Render peer agent messages as teammate cards instead of steering (#309) - #328
Render peer agent messages as teammate cards instead of steering (#309)#328cboos wants to merge 5 commits into
Conversation
Specification only, no implementation. Peer agent messages arrive as a `queued_command` attachment whose `origin` object the attachment factory never reads, so they render as "User (steering)" with the `<agent-message from=…>` wrapper visible in the card body. The brief records the data shape, a structural census of `origin.kind` (human 2554, no-origin 2431, peer 29), the 29/29 resolution of `origin.senderTaskId` to the sender's subagent transcript, why `channel` is out of scope, the delicate parts of the steering path, and the test and cache obligations. Based on the Agent-spawn linking branch: the two share no code, but the cross-link from a peer card to its sender's transcript only resolves once subagent transcripts are linked at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…#309) Peer agent messages arrive as a `type: "attachment"` entry with `attachment.type: "queued_command"` carrying an `origin` object with `kind: "peer"`. Previously, `_create_queued_command_message` ignored `origin` and converted all queued commands into `UserSteeringMessage` using the raw `prompt`, causing two defects: 1. Misattribution: rendered as "User (steering)" (attributed to the human). 2. Leaked markup: the raw `<agent-message from="...">` wrapper rendered literally in the card body. Reuse `TeammateMessage` and `TeammateMessageBlock` for peer agent messages: - Add optional `sender_task_id` on `TeammateMessageBlock` to preserve `origin.senderTaskId` (for future subagent transcript linking). - In `attachment_factory._create_queued_command_message`, promote `origin.kind == "peer"` attachments to `TeammateMessage` with clean prose from `origin.body` (falling back to stripping the wrapper tags via `ATTR_RUN` from `teammate_factory` to safely handle attributes containing `>`). - Set `is_system=(sender == SYSTEM_ID)` on the teammate block. - Common human steering (`origin.kind == "human"`) and legacy origin-less entries remain untouched. Covered with synthetic HTML/Markdown test cases and mutation checks. Co-Authored-By: Antigravity (Gemini 3.8 Flash) <antigravity@google.com>
- F4: 'teammate-system' appears in inlined CSS stylesheets, so asserting 'teammate-system' in html passed even when the element lacked the class. Anchor the assertion to the element's class attribute (class="teammate-message teammate-system"), which genuinely discriminates. - F5: Drop redundant _ATTR_RUN and _SYSTEM_ID aliases in teammate_factory.py. Co-Authored-By: Antigravity (Gemini 3.8 Flash) <antigravity@google.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review. 📝 WalkthroughWalkthroughQueued-command attachments now distinguish peer origins from human or absent origins. Peer messages render as attributed teammate cards, preserve sender task IDs, identify system senders, and strip outer ChangesPeer message rendering
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant QueuedCommand
participant AttachmentFactory
participant TeammateMessage
participant Renderer
QueuedCommand->>AttachmentFactory: provide peer origin and prompt text
AttachmentFactory->>AttachmentFactory: strip outer agent-message wrapper
AttachmentFactory->>TeammateMessage: create sender-attributed message
TeammateMessage->>Renderer: provide sender, task ID, status, and body
Renderer-->>QueuedCommand: render teammate card
Merge Risk: ⚪ Minimal · up to This increment has no reviewer findings to act on and no supplied change details indicating new risk, so there is no merge-blocking concern identified at this time. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Replace private session identifier and entry UUID in work/agent-message-origin.md with descriptive references to the issue's screenshot and local session shape. Co-Authored-By: Antigravity (Gemini 3.8 Flash) <antigravity@google.com>
Clean up duplicated descriptions and remove stale '#316 has merged' clause in work/agent-message-origin.md. Co-Authored-By: Antigravity (Gemini 3.8 Flash) <antigravity@google.com>
Summary
Closes #309.
Issue #309 shows a peer agent message arriving as a
queued_commandattachment withorigin.kind == "peer"being rendered as "User (steering)" with the outer<agent-message>XML wrapper tags leaked into the card body (the issue screenshot displays the exact fixture uuid covered by our test case).This change:
TeammateMessageandTeammateMessageBlockfor peerqueued_commandattachments.teammate_idfromorigin.fromororigin.name, and preservessender_task_id(origin.senderTaskId) onTeammateMessageBlockfor subagent transcript correlation.origin.body, with fallback to unwrapping outer<agent-message>tags viaATTR_RUNfromteammate_factory(ensuring attribute values containing>do not truncate the opening tag).is_systeminvariant when the peer sender issystem.UserSteeringMessagehandling for human steering (origin.kind == "human") and legacy origin-less attachments.Validation
test/test_steering_queued_command.pycovering HTML and Markdown rendering, attribute parsing with>,is_systemclass rendering, and human/absent origin retention.is_systemlogic causes targeted tests to fail.just ci).Summary by CodeRabbit
New Features
Bug Fixes
Documentation