fix(web): review comments in question answers reach the agent with their text and diff#28051
Problem
While Claude waits on an AskUserQuestion prompt, a line comment added in the Diff panel puts a review-comment chip into the question's answer. On submit, the agent received only the bare link [notes.md L16](t3-context://v1/review-comment/…), with no comment text or diff, and asked the user to retype the comment. A normal message with the same chip carries the text and diff.
Reproduced on main (50c1c5dc53) in the web dev server on a fresh database, with Claude Opus 5.5:
- Ask Claude to create a file and then ask an
AskUserQuestion. - While the question waits, comment on a line in the Diff panel. The chip appears in the answer.
- Submit. The stored answer is exactly the bare link, and Claude says no comment text or diff came through.
Change
- Send:
onRespondToUserInputnow also reads the records the thread's composer draft holds. The Diff panel stores the review comment there, not on the question's draft.projectPendingUserInputAnswerthen runs the answer through the sharedprojectComposerContextForProvider, the same path a normal send uses, whenever the answer references a chip it can expand (review comment, terminal, preview annotation, environment). - Unchanged answers: thread chips stay readable thread links, as before. Image and file chips in an expanded answer become their plain label; the server still appends their
Attached image "…": <path>lines. Answers with nothing to expand are byte-identical to main. - History: the stored answer is the text the agent got.
getQuestionAnswerText, which web history, mobile history and the collapsed row summary share, now hides a generated<t3_context>block usingstripComposerContextEnvelope, and keeps any attachment-path lines after it. It strips a block only if every entry's id has a matching marker in the text before it, so a block the user typed is left alone.
No contract, server or mobile-submission change.
Scope and approval
Fixes pingdotgg/t3code#28022
Triaged via the automated issue flow.
Verification
Tests:
apps/web/src/pendingUserInput.test.ts: "sends review comment chips with the comment text and diff" fails on main (Received: "See [plan.md L16](t3-context://v1/review-comment/…)") and passes now. Another test covers an image chip next to a review chip: the image keeps its label, gets nounavailableorkind="image"entry, and an image-only answer is unchanged.packages/shared/src/composerContextReferences.test.ts: a generated block is stripped back to its body; a trailingAttached imageline is kept; a user-typed block without matching markers is unchanged; plain text is unchanged.vp run check:changedon the merged head passes: format, lint, knip, typecheck (33 packages), tests (44) and the React compiler check.
Real app (web dev server at localhost, Chromium preview, 1280×800, DPR 1, light theme, Claude Opus 5.5, fresh database, synthetic project and image):
| Row | Before (main 50c1c5dc53) | After (branch) |
|---|---|---|
| Chip in the pending answer | ||
| What the agent received | ||
| History, comment only, collapsed / expanded | n/a (main showed the raw link) | |
| History, comment and image, collapsed / expanded | n/a |
Control, main: the same kind of chip sent as a normal message reached Claude with the text and diff.
Stored runtime-request answers, as written by each build:
| 1 | before (main): "[notes.md L16](t3-context://v1/review-comment/review-comment_file-comment-1793431779302-1)" |
| 2 | after: "[Review comment: after.md L16; ref=review-comment_file-comment-1793432313989-1]\n\n<t3_context version=\"1\">\n<context kind=\"review-comment\" id=\"…\">\nfile: after.md\nrange: +16 (15-15)\nsection: Changes\ncomment:\n PURPLE-OTTER: rename this line to sixteen\ndiff:\n @@ -0,0 +16,1 @@\n +line 16\n</context>\n</t3_context>" |
| 3 | after + image: same shape, followed by "\n\nAttached image \"synthetic.png\": \"…/attachments/….png\"" |
Before and after are separate runs of the same flow, and their text differs by design, so pixel diffs (Diff0/DiffT) would not mean anything here and are omitted. 05 was taken at 7b10c389ea; 07–11 at a608ec67f5, the head before the main merge.
Not checked:
- Mobile history and its collapsed summary. They use the same shared
getQuestionAnswerText, which is unit-tested, but I ran no native client. - Narrow web viewport and dark theme.
- A file attachment, and an inline image or file chip pasted next to a review comment (unit-tested only).
- Multi-question requests.
- Recordings of expand/collapse.
- Providers other than Claude: Codex, Cursor, OpenCode and Grok receive the same answer string.
Lead: Claude Opus 5.5 (Claude Code in T3 Code). Steps: Claude Opus 5.5 (red test, implementation, reviewer B) and GPT-6.1 Sol via Codex (reviewer A, proof audit).
🤖 Generated with Claude Code
Checks
Added 5 commits
- Merge remote-tracking branch 'origin/main' into fix/issue-2802277feb8d
- fix(web): question answers send review comment text and diff7b10c38
- fix(web): keep attachment chips and hide the context envelope in question answers82d4b5b
- fix(web): attachment chips in question answers stay labels, history hides only generated envelopesa608ec6
- test(web): reproduce #28022 review comment chips in question answerse4e7758
Approvability
Verdict: Approved at 77feb8d
Macroscope's review found this PR approvable — Question answers now deliver referenced review comments and diffs to the agent while keeping generated payloads out of work-log previews. The change reuses existing context serialization and limits delivery to references included in the answer.
You can add or adjust custom eligibility rules. Learn more.
Thread transfer impact
✅ Thread transfer remains within every enforced ceiling.
| Provider | Metric | Main baseline | This PR | Impact | PR ceiling | |
|---|---|---|---|---|---|---|
| Codex | Total thread wire | 5.0 KiB | 5.0 KiB | +29 B (+0.6%) | 6.8 KiB | ✅ |
| Codex | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Codex | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | +29 B (+2.3%) | 2.0 KiB | ✅ |
| Codex | Live turn WebSocket decoded | 21.5 KiB | 21.6 KiB | +41 B (+0.2%) | 24.4 KiB | ✅ |
| Codex | Live turn messages | 1 | 2 | +1 (+100.0%) | 8 | ✅ |
| Claude | Total thread wire | 5.0 KiB | 5.0 KiB | 0 B (0.0%) | 6.8 KiB | ✅ |
| Claude | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Claude | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | 0 B (0.0%) | 2.0 KiB | ✅ |
| Claude | Live turn WebSocket decoded | 21.9 KiB | 21.9 KiB | 0 B (0.0%) | 24.4 KiB | ✅ |
| Claude | Live turn messages | 1 | 1 | 0 (0.0%) | 8 | ✅ |
Baseline: b47d71d · PR result: 77feb8d · Source CI: success
Scenario and decoded snapshot size
10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
- Codex decoded thread snapshot: 108.5 KiB
- Claude decoded thread snapshot: 108.8 KiB
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.
No actionable comments were generated in the recent review.
External image Recent review info
-
External image Run configuration
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: fix/issue-28022
- File: .coderabbit.config.ts
- Commit: 77feb8d
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Team
- Run ID:
83512ffe-b66f-4153-b983-e3d7c278c9d4
External image Commits
Reviewing files that changed from the base of the PR and between b47d71da28a4a24f93fff1675722693fe4d9a15d and 77feb8d8cde86ddd9184769ab3ba0289a19b73a4.
External image Files selected for processing: 6
apps/web/src/components/chat/usePendingThreadRequests.tsapps/web/src/pendingUserInput.test.tsapps/web/src/pendingUserInput.tspackages/client-runtime/src/work-log/userInput.tspackages/shared/src/composerContextReferences.test.tspackages/shared/src/composerContextReferences.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.
Walkthrough
Pending-question answers now include composer draft context records during projection. The work-log answer reader strips valid generated context envelopes from string answers. Tests cover review-comment text and diff, image labels, and envelope preservation rules.
Changes: Pending question context
Layer / File(s) Summary Project composer context into answers
apps/web/src/components/chat/usePendingThreadRequests.ts,apps/web/src/pendingUserInput.ts,apps/web/src/pendingUserInput.test.tsPending-question submission combines composer draft records with question thread contexts. Projection includes resolved non-attachment context and retains attachment labels. Tests cover review-comment and image references. Strip generated context envelopes
packages/shared/src/composerContextReferences.ts,packages/client-runtime/src/work-log/userInput.ts,packages/shared/src/composerContextReferences.test.tsA shared helper strips valid generated context envelopes. getQuestionAnswerTextapplies it to string answers. Tests cover envelope boundaries and unchanged text.Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix · Severity of issue fixed: Medium
Suggested labels:
bugfix,size:MSuggested reviewers:
t3dotgg,maria-rcks
Merge Risk: External image Low · up to 77feb
In a narrow case, a prefilled answer may be changed before it reaches the agent. This is non-blocking with owner awareness.
Pre-merge checks: Passed 4
Check name Status Explanation Title check Passed The title names the main change: review comments placed in pending question answers now reach the agent with their text and diff. The changeset matches this. It projects composer context records (revi… Description check Passed The description follows the template's main sections: Problem, Change, Scope and approval, and Verification. The Problem section gives the observed behavior, reproduction steps, and environment. The C… Linked Issues check Passed Issue #28022requires pendingAskUserQuestionanswers with review-comment chips to reach the agent with comment text and diff.usePendingThreadRequestsnow reads records from the thread composer d…Out of Scope Changes check Passed The changed files support the linked fix. They prepare pending answers, project review-comment and attachment references, add regression tests, and remove generated provider envelopes from shared hist… Full details: Title check
Explanation
The title names the main change: review comments placed in pending question answers now reach the agent with their text and diff. The changeset matches this. It projects composer context records (review comments and other expandable chips) into pending user-input answers, and it strips the generated context envelope in history display. The title is a conventional commit with a scope and is specific enough for a teammate scanning history. It is 86 characters, slightly long, but still clear.
Full details: Description check
Explanation
The description follows the template's main sections: Problem, Change, Scope and approval, and Verification. The Problem section gives the observed behavior, reproduction steps, and environment. The Change section explains the send path and history path and why the changes stay within the same fix. Scope and approval links issue
#28022and says it was triaged through the automated issue flow. Verification lists focused tests, a repo check run, and real-app before and after evidence. It also lists what was not checked. The description is mostly complete. The template asks for a maintainer approval link or discussion for scope, and the author cites only an automated triage flow, so that point could be clearer. This gap is minor, so the check passes.
Full details: Linked Issues check
Explanation
Issue
#28022requires pendingAskUserQuestionanswers with review-comment chips to reach the agent with comment text and diff.usePendingThreadRequestsnow reads records from the thread composer draft.projectPendingUserInputAnswerresolves review-comment records throughprojectComposerContextForProvider. The new regression test checks that the projected answer contains the comment text and diff and no baret3-context://link. The history change removes generated envelopes while preserving attachment lines. The linked coding requirements are implemented and tested.
Full details: Out of Scope Changes check
Explanation
The changed files support the linked fix. They prepare pending answers, project review-comment and attachment references, add regression tests, and remove generated provider envelopes from shared history text. The image/file handling preserves existing attachment behavior when the new projection runs. No unrelated feature, server contract, or mobile-submission change is demonstrated.
Finishing Touches
Generate docstrings
- Commit to this branch
- Create a new PR
Generate unit tests (beta)
- Commit to this branch
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts