Repository navigation
feat: add per-agent reviewer summaries to the review comment - #89
Conversation
🤖 AI code reviewDecision: Ready for human review Overall PR risk: Medium. This change modifies existing behavior by adding per-agent summaries to the reviewer output schema and rendering paths. The affected surfaces include renderMarkdown, renderAggregateMarkdown, CoordinatorOutput state, and the terminal reporter — the change touches every rendered review comment. Model text now reaches the visible comment through plainModelLine escaping, and the size fallback re-renders without summaries; summaries never reach the decision path, and old state parses safely because the field is optional.
No findings. This review is advisory — it never blocks a merge and never auto-approves. |
Each reviewer pass may return a short `summary` of what it reviewed and concluded. The engine keeps one row per roster agent (its summary, or why it did not run: `paths` or the router) in an engine-owned `agentSummaries` field, and the comment lists them in a collapsed section under the overall summary. Summaries are model text, so the reporter flattens them to one line, escapes HTML, and breaks `@` mentions.
4566846 to
ece3ec4
Compare
…hen the comment is too big - plainModelLine let `_@login_` (rendered as `<em>@login</em>`) and character references (`@login`, `@login`, `@octocat`) through, and GitHub decodes references before it looks for mentions. Escape every reference's `&`, and break each `@` that doesn't follow an ASCII letter or digit, which keeps email addresses whole. - Only the aggregate comment checked MAX_COMMENT_CHARS. Escaping and the base64 state copy make summaries several times their byte budget, and a single comment over GitHub's limit failed to post, so the finished review was replaced by the failure notice. Over the limit, leave the summaries out with the same note the aggregate uses. - Summary parts lived in a plain object, so an agent named `constructor` or `toString` crashed the whole run; they are now a Map. Parts are kept in diff order rather than pass-completion order, and a `cross-cutting` agent is listed once. - Clipping no longer leaves half an emoji, and an unknown "not run" reason from an old or newer engine's state reads "not run". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Escaping every reference made model text like `<T>` or `&` show up literally. Only a reference that decodes to `@` itself can start a mention: one after the `@` spells a login character, but that `@` is broken like any other. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Resolved so the one filter, breakMentions, carries #89's rules (`@` character references escaped, every `@` not after a letter or digit broken) for both the summary rows and the multi-line model text #90 added. humanReviewReasons and buildMentions take a Map, like the summary parts, so an agent named `constructor` can't read an inherited property. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Review notes from a multi-model review (Codex, Grok and Claude, each finding then re-checked against the code). Fixes are in cd22aec and 58eff53, pushed to this branch. 1. Mentions get past
2. No size check on the single comment (holds, reproduced). The 8 KB budget is on raw JSON, but escaping and the base64 state copy multiply it: 40
3. An agent named
4. Low (fixed): parts are now picked in diff order, not pass-completion order, so the same PR gives the same summary; clipping no longer leaves half an emoji; an unknown Not changed: summaries left out for size stay gone on Checks: typecheck, |
The capture in `(^|[^A-Za-z0-9])@` consumed the first `@` of `@@login`, so the second never matched and `@@login` still notified. A lookbehind breaks each one. Found by the repo's own AI review. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Follow-up: the AI review here is right. My broader |
Why
The AI review summary comment shows only the coordinator's overall summary. Each reviewer agent's own view of the change is lost, and the comment doesn't say which agents ran or why one didn't.
Change
summary(one or two sentences). The parser fails soft like the trace: it flattens the value to one line, cuts it at 280 characters, and drops a malformed value but keeps the findings.buildAgentSummariesmakes one row per roster agent. Agents that ran come first, in run order with the cross-cutting pass last. Agents that didn't run follow, markedpaths(the paths filter skipped them) orrouter(the router didn't select them).renderAggregateMarkdownfirst leaves out every scope's summaries, from the visible rows and the state, with a one-line note in each scope. Only then does it trim findings, so summaries never cost a finding.attachAgentSummariesattaches the list as an engine-ownedagentSummariesfield after the decision and strips any coordinator-written value, the same way asreviewTrace./dismissre-renders keep the section.plainModelLinestrips formatting tags, escapes every<, collapses whitespace, and puts a zero-width space after every@that could start a mention. That includes an@after a backtick, since a backtick can close a code span or have no partner. A local review run by this repo's own reviewer setup found that backtick case in an earlier version, and it's now fixed and tested.<inside a code span shows as<, the same as the existing short rationale excerpt. The escape stays because a code span could otherwise carry a forged state marker.shared.mdnow ask for thesummaryfield. README, LLP 0002 and LLP 0005 document it.Test Plan
bun test(803 pass), typecheck, lint,fmt:checkandllp:checkall pass, and so doecr ref-checkandecr verify-configon this repo's own setup.The new tests fail before the change and pass after. They cover:
summaryfield and its fail-soft behaviorpathsI also ran
ecr reviewlocally on this branch with the repo's own reviewers (consistency, correctness and security on Claude Opus 5.5). All three returned a summary, and the rendered comment shows the section as designed.