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:
+52
-9
@@ -17,13 +17,25 @@ Service pragent-webhook.pragent.svc.cluster.local (ClusterIP, ns pragent)
|
||||
│ AND pull_request.labels ∋ AI-REVIEW
|
||||
▼
|
||||
ai_review.review_pr() (same core the CI-step uses)
|
||||
1. fetch PR diff → GET gitea-http.gitea.svc:3000/api/v1/repos/{o}/{r}/pulls/{i}.diff
|
||||
2. review prompt → POST http://100.74.17.70:8789/v1/messages (glm-5.2:cloud)
|
||||
3. post review → POST .../pulls/{i}/reviews (event: COMMENT) as pragent-bot
|
||||
1. fetch existing reviews → dedupe: skip if a review already carries
|
||||
<!-- pragent:sha=<this sha> --> (no duplicate on label-toggle / re-fire)
|
||||
2. fetch PR diff → GET .../pulls/{i}.diff
|
||||
3. fetch .pr-review.json @ head ref (optional repo-local focus/config)
|
||||
4. prior review bodies → fed as "already said" context (light §6.1)
|
||||
5. review prompt → POST http://100.74.17.70:8789/v1/messages (glm-5.2:cloud)
|
||||
model emits JSON: {findings:[{severity,path,line,problem,fix,suggestion}]}
|
||||
6. parse diff hunks → valid (path, new_line) anchors (RIGHT side)
|
||||
7. post review → POST .../pulls/{i}/reviews (event: COMMENT) as pragent-bot
|
||||
- anchored findings → inline line comments, body wraps `suggestion` in a
|
||||
```suggestion fence (Gitea renders an apply-button)
|
||||
- unanchored findings → summary-body bullets
|
||||
- summary body carries the <!-- pragent:sha=... --> marker for dedupe
|
||||
```
|
||||
|
||||
Fail-open, comment-only, re-posts on every qualifying trigger (no prior-comment
|
||||
synthesis yet — framework §6.1). Reviews are tagged with the head SHA.
|
||||
Fail-open. No duplicate per commit (dedupe). Inline comments + apply-able
|
||||
suggestions where the line anchors cleanly. Repo-local focus via
|
||||
`.pr-review.json`. Prior reviews fed as context so re-pushes synthesize instead
|
||||
of repeating (light version of framework §6.1).
|
||||
|
||||
## What "onboarding a repo" means now
|
||||
|
||||
@@ -37,6 +49,31 @@ No workflow file, no repo secret, no act-runner needed. (The owner must already
|
||||
be covered by a user-level webhook — see below. If not, do the one-time
|
||||
per-owner setup first.)
|
||||
|
||||
## Repo-local focus: `.pr-review.json` (optional)
|
||||
|
||||
Drop a `.pr-review.json` at the repo root (committed on the PR's branch, or on
|
||||
the default branch) to steer the review for that repo. All fields optional;
|
||||
absent file = defaults. JSON (stdlib, no YAML dependency).
|
||||
|
||||
```json
|
||||
{
|
||||
"focus": ["security", "supply-chain", "sql-injection"],
|
||||
"exclude_paths": ["vendor/**", "**/*.generated.ts"],
|
||||
"languages": ["typescript", "go"],
|
||||
"instructions": "We use Result<T,E> for error handling. Flag any bare throw. Flag eval()/exec() on user input as critical."
|
||||
}
|
||||
```
|
||||
|
||||
- `focus` — weight these review areas higher (does not blind the reviewer to
|
||||
critical issues outside them).
|
||||
- `exclude_paths` — tell the model to ignore these paths.
|
||||
- `languages` — hint the primary languages.
|
||||
- `instructions` — free-form house conventions / compliance language.
|
||||
|
||||
Fetched at review time from the PR head ref
|
||||
(`GET /repos/{o}/{r}/contents/.pr-review.json?ref=<head sha>`). Bad/missing file
|
||||
fails open to defaults. The bot's `read:repository` scope reads it.
|
||||
|
||||
## One-time per-owner setup: register a user-level webhook
|
||||
|
||||
Gitea **system webhooks** (one webhook for the whole instance — the ideal) are
|
||||
@@ -129,11 +166,17 @@ that file once the owner has a user-level webhook — otherwise a labeled PR get
|
||||
reviewed twice. `gitea_admin/pragent`'s own self-CI workflow was retired when the
|
||||
webhook service went live.
|
||||
|
||||
## Known limitations (pilot, same as CI-step)
|
||||
## Known limitations (pilot)
|
||||
|
||||
- Re-posts on every qualifying trigger; no prior-comment synthesis (framework §6.1).
|
||||
- No inline line comments, no status checks, no fail-close.
|
||||
- `glm-5.2:cloud` only; no tiering, no analyzer fan-out.
|
||||
- One model (`glm-5.2:cloud`); no tiering, no analyzer fan-out, no shared-prefix
|
||||
caching. Those are framework features.
|
||||
- No status checks, no fail-close (review never blocks a PR).
|
||||
- Dedupe is per-commit: a re-push (new SHA) always re-reviews (by design — the
|
||||
diff changed). Prior-review context is fed to the model so it doesn't repeat,
|
||||
but the bot does not delete or resolve its own old reviews.
|
||||
- Inline comments only anchor to post-change lines present in the diff (context +
|
||||
added). A finding whose `line` the model places on a removed line or outside
|
||||
the diff is folded into the summary as a bullet instead of misplaced.
|
||||
- Gitea 1.26.1: system webhooks broken (see above) → user-level webhooks instead;
|
||||
hook delivery-history API (`.../hooks/{id}/tasks`) returns 404, so delivery is
|
||||
observed via the pragent-webhook pod logs (`kubectl -n pragent logs -f deploy/pragent-webhook`).
|
||||
|
||||
Reference in New Issue
Block a user