pilot: dedupe + repo config + inline comments w/ suggestions

- Dedupe: Gitea-as-state. Scan existing reviews for a hidden
  <!-- pragent:sha=... --> marker matching the head sha; skip if present
  (kills duplicate reviews on label-toggle / re-fire). Prior review bodies
  fed back as 'already said' context (light framework §6.1).
- Repo-local focus: optional .pr-review.json at repo root
  ({focus,exclude_paths,languages,instructions}), fetched at head ref.
- Inline comments + apply-able suggestions: model emits JSON findings
  {severity,path,line,problem,fix,suggestion}; diff hunks parsed into valid
  (path,new_line) RIGHT-side anchors; anchored findings become positional
  review comments with a ```suggestion fence (Gitea apply-button);
  unanchored findings fold into the summary body.
- Tests: parse_diff_anchors, parse_findings (tolerant JSON), split_findings,
  inline_comment_body, summary_bullets, parse_repo_config, reviewed_shas,
  prior_review_bodies, sha-marker. 35 pass.
- Bump OLLAMA_MAX_TOKENS default 6000 -> 8000 (suggestions add length).

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Marcos
2026-08-17 19:59:36 +00:00
parent 789fb38bae
commit 90cea84f6f
4 changed files with 734 additions and 45 deletions
+8 -5
View File
@@ -1,12 +1,14 @@
#!/usr/bin/env python3
"""pragent pilot — central webhook receiver.
A stdlib-only HTTP server that Gitea posts system-webhook events to. It gates on
A stdlib-only HTTP server that Gitea posts user-webhook events to. It gates on
the `AI-REVIEW` PR label, then runs the same review core (`ai_review.review_pr`)
the CI-step pilot uses, posting findings back as `pragent-bot`.
Zero per-repo setup: one Gitea **system webhook** fires for every repo on the
instance; this service filters to labeled PRs. Onboarding a repo = label a PR.
Per-owner setup: one Gitea **user-level webhook** per repo-owner fires for every
repo that owner has; this service filters to labeled PRs. (Gitea 1.26.1 system
webhooks are broken — see pilot/README-webhook.md.) Onboarding a repo = add the
bot as a Write collaborator + create the label + label a PR.
Stdlib only — no pip install, runs on python:3-slim with the scripts mounted.
@@ -17,7 +19,8 @@ Endpoints:
Env:
WEBHOOK_SECRET shared secret used to register the Gitea webhook (HMAC)
GITEA_API in-cluster Gitea base URL
PRAGENT_BOT_TOKEN pragent-bot access token (admin so it can read any repo)
PRAGENT_BOT_TOKEN pragent-bot access token (non-admin; must be a Write
collaborator on each reviewed repo)
OLLAMA_URL headroom proxy URL, e.g. http://100.74.17.70:8789
OLLAMA_MODEL model id, e.g. glm-5.2:cloud
OLLAMA_MAX_TOKENS (optional) output cap, default 6000
@@ -46,7 +49,7 @@ GITEA_API = os.environ.get("GITEA_API", "http://gitea-http.gitea.svc.cluster.loc
BOT_TOKEN = os.environ.get("PRAGENT_BOT_TOKEN", "")
OLLAMA_URL = os.environ.get("OLLAMA_URL", "http://100.74.17.70:8789")
OLLAMA_MODEL = os.environ.get("OLLAMA_MODEL", "glm-5.2:cloud")
OLLAMA_MAX_TOKENS = int(os.environ.get("OLLAMA_MAX_TOKENS", "6000"))
OLLAMA_MAX_TOKENS = int(os.environ.get("OLLAMA_MAX_TOKENS", "8000"))
DIFF_MAX_CHARS = int(os.environ.get("DIFF_MAX_CHARS", "150000"))
WEBHOOK_SECRET = os.environ.get("WEBHOOK_SECRET", "").encode()
PORT = int(os.environ.get("WEBHOOK_PORT", "8080"))