fix(webhook): re-read PR labels at review start so a late AI-USAGE counts #10

Merged
gitea_admin merged 3 commits from fix/ai-usage-label-reread into main 2026-08-20 23:42:37 +00:00
Owner

Labelling a PR is two webhook events. The review claims on the AI-REVIEW event and starts; the AI-USAGE event that follows is dropped by the in-flight dedupe, so report_usage stayed False and the review posted without its usage block (observed on #9).

This re-reads the labels from the API at review start and upgrades the flag. Best-effort: any failure logs and leaves the payload verdict intact.

Opened to exercise the freshly deployed fixes from #9 end to end — inline-comment anchoring against the raw diff, and this label re-read.

Labelling a PR is two webhook events. The review claims on the AI-REVIEW event and starts; the AI-USAGE event that follows is dropped by the in-flight dedupe, so `report_usage` stayed False and the review posted without its usage block (observed on #9). This re-reads the labels from the API at review start and upgrades the flag. Best-effort: any failure logs and leaves the payload verdict intact. Opened to exercise the freshly deployed fixes from #9 end to end — inline-comment anchoring against the raw diff, and this label re-read.
gitea_admin added 1 commit 2026-08-20 23:27:42 +00:00
Labelling a PR is two webhook events. AI-REVIEW arrives first, the review
claims (repo, index, sha) and starts; the AI-USAGE event that follows a
moment later hits the in-flight dedupe and is dropped. `report_usage` was
snapshotted from the first payload, which had not seen AI-USAGE yet, so the
review posted without its usage block even though the label was on the PR by
the time it finished — observed on gitea_admin/pragent#9 (`usage=False` in
the pod log, no <details> section in the posted review).

Re-read the labels from the API at review start and upgrade the flag. The
read is best-effort: any failure logs and returns [], leaving the payload's
verdict intact, because a usage section is not worth failing a review over.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B11e8TZZxJyzHW7jj7KWUN
pragent-bot bot added the AI-REVIEWAI-USAGE labels 2026-08-20 23:28:03 +00:00
pragent-bot bot reviewed 2026-08-20 23:29:02 +00:00
pragent-bot bot left a comment

🤖 AI Review · pragent pilot · glm-5.2:cloud · 4ef62f28

Summary of Changes

  • pilot/webhook_server.py: add _fetch_current_labels() which GETs the PR's labels from the Gitea API with the bot token, returning [] on any failure
  • pilot/webhook_server.py: in _run_review, when report_usage is False, re-read current labels and upgrade the flag if AI-USAGE is now present (best-effort, logged)
  • tests/pilot/test_webhook_server.py: add three tests for the re-read — late AI-USAGE recovered, absence keeps it off, and API failure is non-fatal

Key Risks & Concerns

None identified.

🤖 **AI Review** · pragent pilot · glm-5.2:cloud · `4ef62f28` ### Summary of Changes - pilot/webhook_server.py: add _fetch_current_labels() which GETs the PR's labels from the Gitea API with the bot token, returning [] on any failure - pilot/webhook_server.py: in _run_review, when report_usage is False, re-read current labels and upgrade the flag if AI-USAGE is now present (best-effort, logged) - tests/pilot/test_webhook_server.py: add three tests for the re-read — late AI-USAGE recovered, absence keeps it off, and API failure is non-fatal ### Key Risks & Concerns _None identified._ <!-- pragent:sha=4ef62f28bbb5d05575829f7e3e65a96b95ec74c3 -->
gitea_admin added 1 commit 2026-08-20 23:29:22 +00:00
GITEA_API is the host with no version prefix — ai_review._get / _post append
/api/v1 per call. The re-read helper didn't, so it 404'd on every review and
silently fell back to the payload's verdict: "could not re-read labels for
gitea_admin/pragent#10: HTTP Error 404" in the pod log, usage block still
missing. Caught by labelling PR #10 AI-REVIEW then AI-USAGE, which is the
exact sequence the fix exists to handle.

Test asserts the composed URL, since a wrong path here fails silently by
design (the helper swallows errors so a review is never lost over a usage
section).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B11e8TZZxJyzHW7jj7KWUN
pragent-bot bot reviewed 2026-08-20 23:30:35 +00:00
pragent-bot bot left a comment

🤖 AI Review · pragent pilot · glm-5.2:cloud · aedea973

Summary of Changes

  • Add _fetch_current_labels(repo, index) which GETs the Gitea labels API with the bot token and returns [] on any failure.
  • In _run_review, when report_usage is False, re-read current labels and upgrade the flag if AI-USAGE is now present (best-effort, logged).
  • Add tests for late AI-USAGE recovery, absent-label no-op, versioned API URL path, and non-fatal failure.

Key Risks & Concerns

  • Every review without AI-USAGE now makes an extra synchronous GET to Gitea before slot acquisition; bounded by a 15s timeout and negligible beside the LLM call, but adds a new dependency on API availability for the opt-in upgrade path.
  • repo and index are interpolated into the URL path without explicit URL-encoding; fail-safe (malformed values raise and return []) and input is HMAC-verified, but a defensive urllib.parse.quote on the path segments would be cleaner.
🔋 AI Usage & Run Details
  • Model / Engine: glm-5.2:cloud · opencode · 7 steps · 69.2s
  • Total Tokens: 128373 in / 3579 out (0 reasoning, cache 0 read / 0 write, 131952 total)
  • Est. cost on Claude Sonnet 5: $0.2925
  • Actual: $0.00 (headroom glm-5.2:cloud — free tier)
  • Scope: Whole-repo checkout at head sha (agent can read any file + run linters, not just the diff) — input tokens include files read beyond the diff. Per-comment output is attributed (one model pass produces all findings; output split by each finding's body weight).
🤖 **AI Review** · pragent pilot · glm-5.2:cloud · `aedea973` ### Summary of Changes - Add `_fetch_current_labels(repo, index)` which GETs the Gitea labels API with the bot token and returns [] on any failure. - In `_run_review`, when `report_usage` is False, re-read current labels and upgrade the flag if AI-USAGE is now present (best-effort, logged). - Add tests for late AI-USAGE recovery, absent-label no-op, versioned API URL path, and non-fatal failure. ### Key Risks & Concerns - Every review without AI-USAGE now makes an extra synchronous GET to Gitea before slot acquisition; bounded by a 15s timeout and negligible beside the LLM call, but adds a new dependency on API availability for the opt-in upgrade path. - `repo` and `index` are interpolated into the URL path without explicit URL-encoding; fail-safe (malformed values raise and return []) and input is HMAC-verified, but a defensive `urllib.parse.quote` on the path segments would be cleaner. <details> <summary>🔋 AI Usage & Run Details</summary> - **Model / Engine**: `glm-5.2:cloud` · opencode · 7 steps · 69.2s - **Total Tokens**: 128373 in / 3579 out (0 reasoning, cache 0 read / 0 write, 131952 total) - **Est. cost on Claude Sonnet 5**: $0.2925 - **Actual**: $0.00 (headroom glm-5.2:cloud — free tier) - **Scope**: Whole-repo checkout at head sha (agent can read any file + run linters, not just the diff) — input tokens include files read beyond the diff. Per-comment output is *attributed* (one model pass produces all findings; output split by each finding's body weight). </details> <!-- pragent:sha=aedea973abcbc1bf3a237ad4a5b1ade084891088 -->
gitea_admin added 1 commit 2026-08-20 23:35:14 +00:00
The previous two commits put the label re-read in the webhook, at review
start. That is too early to help: the review claims on the AI-REVIEW event
and the re-read runs milliseconds later, while the reviewer's second click
(AI-USAGE) is still a second or two away. It would have kept 404ing quietly
if the path fix hadn't landed, and even fixed it caught nothing.

Move the check to where the decision is actually used — just before the
usage block is rendered, after the model has run. That is a minute or more
after the trigger, by which time the label is there. Attribution is computed
in the same branch, so a late opt-in still gets its per-comment token lines.

`pr_has_label` goes through the existing gitea_get helper, which owns the
/api/v1 prefix, so the path can't drift again. Any failure returns False and
the payload's verdict stands: a review is never lost over a usage section.

Reverts the webhook-side re-read from 4ef62f2 and aedea97.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B11e8TZZxJyzHW7jj7KWUN
pragent-bot bot reviewed 2026-08-20 23:38:49 +00:00
pragent-bot bot left a comment

🤖 AI Review · pragent pilot · glm-5.2:cloud · c58c0018

Summary of Changes

No summary provided.

Key Risks & Concerns

None identified.

⚠️ The reviewer did not emit a parseable findings block, so there are no inline comments. Its raw notes are below — treat them as unverified: line numbers were not validated against the diff.

The diff touches gitea_get (network egress / API token handling) and the review render path, so this is at least full tier per the attention-tiering rules. Let me inspect the surrounding code and run linters.

🔋 AI Usage & Run Details
  • Model / Engine: glm-5.2:cloud · opencode · 7 steps · 77.1s
  • Total Tokens: 138727 in / 862 out (0 reasoning, cache 0 read / 0 write, 139589 total)
  • Est. cost on Claude Sonnet 5: $0.2861
  • Actual: $0.00 (headroom glm-5.2:cloud — free tier)
  • Scope: Whole-repo checkout at head sha (agent can read any file + run linters, not just the diff) — input tokens include files read beyond the diff. Per-comment output is attributed (one model pass produces all findings; output split by each finding's body weight).
🤖 **AI Review** · pragent pilot · glm-5.2:cloud · `c58c0018` ### Summary of Changes _No summary provided._ ### Key Risks & Concerns _None identified._ ⚠️ _The reviewer did not emit a parseable findings block, so there are no inline comments. Its raw notes are below — treat them as unverified: line numbers were not validated against the diff._ The diff touches `gitea_get` (network egress / API token handling) and the review render path, so this is at least `full` tier per the attention-tiering rules. Let me inspect the surrounding code and run linters. <details> <summary>🔋 AI Usage & Run Details</summary> - **Model / Engine**: `glm-5.2:cloud` · opencode · 7 steps · 77.1s - **Total Tokens**: 138727 in / 862 out (0 reasoning, cache 0 read / 0 write, 139589 total) - **Est. cost on Claude Sonnet 5**: $0.2861 - **Actual**: $0.00 (headroom glm-5.2:cloud — free tier) - **Scope**: Whole-repo checkout at head sha (agent can read any file + run linters, not just the diff) — input tokens include files read beyond the diff. Per-comment output is *attributed* (one model pass produces all findings; output split by each finding's body weight). </details> <!-- pragent:sha=c58c00181e822e1373a114e207167f961f6223d4 -->
gitea_admin merged commit cdf116ece9 into main 2026-08-20 23:42:37 +00:00
gitea_admin deleted branch fix/ai-usage-label-reread 2026-08-20 23:42:37 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gitea_admin/pragent#10