feat(runtime): render agent event stream live during execution - #3186
Conversation
|
🤖 Review · |
Site previewPreview: https://5f3fdfee-site.fullsend-ai.workers.dev Commit: |
|
/fs-review |
PR Summary by Qodofeat(runtime): improve agent event stream rendering
AI Description
Diagram
High-Level Assessment
Files changed (11)
|
|
🤖 Review · |
Code Review by Qodo
1.
|
|
🤖 Finished Review · ✅ Success · Started 9:59 PM UTC · Completed 10:10 PM UTC |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
ReviewPrior findings status
Changes since prior reviewCommit
All changes are clean and correct. No new issues introduced. FindingsLow
Previous runReviewPrior findings status
FindingsLow
Previous run (2)ReviewThis is a re-review following commit Prior findings status
FindingsMedium
Low
Previous run (3)ReviewVerdict: Comment This is a re-review following a force push that rewrote the branch history from SHA Force push impactThe prior review approved at SHA
Several fixes from prior commits ( Prior findings status
Medium-severity findings1. TextEvent/ThinkingEvent bypass All other event types correctly sanitize their string fields: Remediation: Apply 2. Remediation: At minimum, restore the Low-severity findings
Labels: Previous run (4)ReviewVerdict: Approve This is a re-review following commit The overall PR — normalized Changes since prior reviewCommit
Prior findings status
Remaining low-severity findingMissing Labels: Previous run (5)ReviewVerdict: Approve This is a re-review following commit The overall PR — normalized Changes since prior reviewCommit
Prior findings status
Remaining low-severity findingMissing Labels: Previous run (6)ReviewVerdict: Approve This is a re-review following commit Changes since prior reviewCommit
Prior findings status
Remaining low-severity findingMissing Labels: Previous run (7)ReviewVerdict: Approve This is a re-review following commit Changes since prior reviewCommit
Prior findings status
Remaining low-severity findingsDesign spec stale references — The spec at Missing
Labels: Previous run (8)ReviewVerdict: Comment This is a re-review following commit Changes since prior reviewThe author's response commit ( Prior findings status
Remaining findingsDesign spec inaccurately describes
Duplicated metrics handler logic — The Missing test coverage for Previous run (9)ReviewVerdict: Comment This is a re-review following the author's response commit ( Changes since prior reviewThe author's response commit addresses the prior review directly:
Remaining findings
Design spec not updated to reflect Stale Previous run (10)ReviewVerdict: Request changes This PR implements a well-structured event stream rendering architecture for High-severity findings
Medium-severity findings
Low-severity findings
Previous run (11)ReviewVerdict: Comment This is a re-review following commit Changes since prior reviewThe author's response commit ( Prior findings status
Remaining findingsDesign spec inaccurately describes
Duplicated metrics handler logic — The Missing test coverage for Labels: Previous run (12)ReviewVerdict: Comment This is a re-review following the author's response commit ( Changes since prior reviewThe author's response commit addresses the prior review directly:
Remaining findings
Design spec not updated to reflect Stale Labels: ReviewVerdict: Request changes This PR implements a well-structured event stream rendering architecture for High-severity findings
Medium-severity findings
Low-severity findings
Labels: PR modifies internal/runtime event streaming and internal/ui printer Previous run (13)ReviewVerdict: Comment This is a re-review following the author's response commit ( Changes since prior reviewThe author's response commit addresses the prior review directly:
Remaining findings
Design spec not updated to reflect Stale Labels: Previous run (14)ReviewVerdict: Request changes This PR implements a well-structured event stream rendering architecture for High-severity findings
Medium-severity findings
Low-severity findings
Labels: PR modifies internal/runtime event streaming and internal/ui printer |
|
🤖 Finished Review · ✅ Success · Started 4:25 PM UTC · Completed 4:34 PM UTC |
|
🤖 Finished Review · ✅ Success · Started 5:20 PM UTC · Completed 5:30 PM UTC |
|
🤖 Finished Review · ✅ Success · Started 7:47 PM UTC · Completed 7:59 PM UTC |
rh-hemartin
left a comment
There was a problem hiding this comment.
LGTM but not sure if this will be too verbose. Also you are submitting plans and specs. Remove those. As per the verbosity, we can always go back to a less verbose thing.
waynesun09
left a comment
There was a problem hiding this comment.
Security-focused review. Three unique medium-and-above findings inline, all stemming from the switch to live-rendering the untrusted agent stream:
- HIGH — text/thinking deltas rendered without
sanitizeOutput→ ANSI terminal-escape injection and GitHub Actions::command::injection. - MEDIUM — full Bash command (and Agent prompts) now displayed instead of the binary name, leaking secrets into terminal and persisted CI logs.
- MEDIUM —
allowedToolsallowlist removed andevent.godoc comments left claiming masking/"safe for display" that no longer holds.
The common fix is to treat every rendered string from the stream as untrusted: sanitize text/thinking/model/subtype (newline-preserving variant), and restore the binary-name/allowlist disclosure controls the pre-PR code and this PR's own design spec require. Lower-severity notes (unsanitized model/version/subtype headers, unbounded toolInputJSON accumulation) not posted inline.
…tool context ThinkingEvent, TextEvent, InitEvent (Model/Version), and ResultEvent (Subtype) were rendered without sanitization, allowing ANSI escape injection and GHA workflow command injection from untrusted model output. Add sanitizeStreamText — a newline-preserving variant of sanitizeOutput — and apply it to text/thinking deltas. Apply sanitizeOutput to Model, Version, and Subtype fields. Replace the ad-hoc env var prefix redaction in collapseCommand with SecretRedactor from internal/security, which covers API keys, tokens, auth headers, private keys, and credential patterns. This reuses the same scrubbing logic used for transcript post-processing. Update ToolUseEvent doc comments to reflect that Name carries the raw tool name (the pre-PR allowlist was removed). Signed-off-by: Ralph Bean <rbean@redhat.com> Assisted-by: Claude claude-opus-4-6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
|
🤖 Finished Review · ✅ Success · Started 2:43 PM UTC · Completed 2:57 PM UTC |
waynesun09
left a comment
There was a problem hiding this comment.
Review Squad — #3186
Agents: 5 dispatched (2x Claude coder, 1x Claude researcher, 1x Codex; Gemini timed out)
Models: Claude, Codex
4 unique findings after dedup, verification, and filtering out intentional design decisions (allowedTools removal, collapseCommand, sanitization — all addressed in prior fix commits).
- 2 HIGH — OnEvent bypasses metrics population; totalOutput not reset on message_start
- 2 MEDIUM — dead
startparameter / lost elapsed time; unbounded toolInputJSON growth
Assisted-by: Claude (review), Codex (review)
…unds - Always wrap OnEvent handler to capture metrics (Model, ResultEvent fields, ToolCalls) regardless of whether a custom handler is provided. EventRenderer is now a pure rendering concern with no metrics field. - Reset totalOutput on message_start to prevent stale token counts from carrying across turns. - Remove unused start parameter from NewEventRenderer and progressParser. - Cap toolInputJSON accumulation at 1MB to bound memory growth from malicious or buggy input_json_delta streams. - Update design spec to reflect new signatures. Signed-off-by: Ralph Bean <rbean@redhat.com> Assisted-by: Claude claude-opus-4-6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
|
🤖 Finished Review · ✅ Success · Started 3:30 PM UTC · Completed 3:43 PM UTC |
waynesun09
left a comment
There was a problem hiding this comment.
All 4 review findings from the prior round are addressed in 07869001:
- OnEvent metrics wrapping — handler always wrapped to capture
InitEvent.Model,ResultEventfields, andToolUseEventcount regardless of custom/default path.EventRendereris now pure rendering. totalOutputreset — reset to 0 onmessage_start.- Dead
startparameter — removed fromNewEventRendererandprogressParsersignatures. toolInputJSONunbounded growth — capped at 1MB (maxToolInputSize).
Metrics logic is correctly duplicated in both claude.go:Run and progressParser. Tests updated to match new signatures. No new issues introduced.
Assisted-by: Claude (review), Codex (review)
|
🤖 Finished Retro · ✅ Success · Started 6:16 PM UTC · Completed 6:27 PM UTC |
|
PR #3186 added live event stream rendering to Proposals filed
|
Summary
Renders the agent's event stream live during
fullsend run, replacing the old progress output that only showed periodic heartbeats and tool names.AgentEventtypes (InitEvent,ThinkingEvent,TextEvent,ToolUseEvent,TokensEvent,ResultEvent,ErrorEvent,RetryEvent) that bridge runtime-specific NDJSON parsing and runtime-agnostic renderingOnEventcallback toRunParamsfor custom event handlingEventRendererthat renders structured terminal output: thinking (🧠 italic/muted), text (💬), tool calls (⚙ blue), heartbeats (⏳ muted), token usage, errors, retries, and result summariesClaudeRuntime.RunCloses #3170.
Test plan
🤖 Generated with Claude Code