feat(runtime): render agent event stream live during execution#3186
feat(runtime): render agent event stream live during execution#3186ralphbean wants to merge 15 commits into
Conversation
|
🤖 Review · |
Site previewPreview: https://c25e80c4-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! |
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 runReviewVerdict: Approve This is a re-review following commit Changes since prior reviewCommit
Prior findings status
Remaining low-severity findingMissing Labels: Previous run (2)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 (3)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 (4)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 (5)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 (6)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 (7)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 (8)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 (9)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 |
|
🤖 Finished Review · ✅ Success · Started 8:02 PM UTC · Completed 8:09 PM UTC |
|
I don't see any runs on the triage agent for the issue linked (appdumpster/test-repo#25), could you provide the run URL directly? |
Ah, yes. All my local testing was done with edit: here it is: appdumpster/test-repo#25 (comment) |
Design for #3170. Defines normalized AgentEvent types, a callback-based integration via RunParams.OnEvent, and an EventRenderer that produces structured terminal output (thinking, text, tool summaries, tokens, errors) during fullsend run execution. The Claude stream parser is refactored to emit normalized events; the renderer is runtime-agnostic so opencode can plug in with its own parser later. Assisted-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
Six-task plan covering event types, OnEvent callback, EventRenderer, Claude parser refactor, ClaudeRuntime.Run wiring, and final verification. TDD throughout with complete code blocks. Part of #3170. Assisted-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
Define the AgentEvent interface and concrete event structs (InitEvent, ThinkingEvent, TextEvent, ToolUseEvent, TokensEvent, ResultEvent, ErrorEvent, RetryEvent) that bridge runtime-specific NDJSON parsing and runtime-agnostic rendering. Part of #3170. Assisted-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
Add an optional OnEvent func(AgentEvent) field to RunParams. When set, the runtime calls it with normalized events during execution. When nil, events are silently discarded (or the runtime uses a default renderer). Part of #3170. Assisted-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
EventRenderer consumes normalized AgentEvent values and renders structured terminal output: thinking text (italic/dim), assistant text, tool summaries with elapsed time and count, token usage (throttled), result summaries, errors, and retry warnings. Tracks block state for clean transitions between event types. Part of #3170. Assisted-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
Refactor the Claude Code NDJSON parser to emit normalized AgentEvent values via a callback instead of calling printer.Heartbeat directly. The new parseClaudeStream function processes stream_event deltas (thinking, text, tool input JSON), system events (init, api_retry), result events, and errors. The old progressParser is kept as a thin wrapper that creates an EventRenderer. Supports assistant message fallback for older Claude Code versions that don't emit stream_event deltas. Part of #3170. Assisted-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
Wire the OnEvent callback in ClaudeRuntime.Run. When OnEvent is nil (the default), creates an EventRenderer that renders thinking, text, tool summaries, token usage, errors, and result summaries to the terminal in real time. When OnEvent is set, the caller receives normalized AgentEvent values for custom handling. Closes #3170. Assisted-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
…token throttle Fix ResultEvent construction to include the error message from the result event's "result" field. Remove duplicate token throttling from EventRenderer (throttling belongs only in the parser). Add tests for error result rendering. Part of #3170. Assisted-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
- Suppress duplicate InitEvent headers (only show first with version) - Render text and thinking content from assistant messages in the fallback (non-streaming) path, which were previously silently dropped - Differentiate tool calls (⚙ blue) from heartbeat timer (⏳ muted) with distinct emoji and color via new ToolProgress printer method - Show full Bash commands instead of just the binary name, truncated at 120 characters and collapsed to a single line - Remove allowedTools blocklist — tool names are not sensitive and the trajectory is public; extractSafeContext already returns empty for tools it doesn't know how to summarize - Add context extraction for Skill (skill_name) and Agent (prompt) tools Assisted-by: Claude claude-opus-4-6 <noreply@anthropic.com> 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>
- Sanitize ThinkingEvent, TextEvent, and InitEvent fields through sanitizeOutput before rendering, preventing ANSI escape injection and GHA workflow command marker injection in CI logs - Redact leading KEY=VALUE env var assignments in collapseCommand to prevent secrets from leaking into progress output and CI annotations - Extract metrics population from EventRenderer into a dedicated metricsHandler wrapper in ClaudeRuntime.Run, ensuring RunMetrics is always populated regardless of whether a custom OnEvent callback is provided - Simplify EventRenderer to be purely a rendering concern (no metrics field, no start time) - Add unit tests for sanitization, ToolProgress, and Heartbeat Assisted-by: Claude claude-opus-4-6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
The allowlist was removed but the doc comment still referenced it. Assisted-by: Claude claude-opus-4-6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
…lback - Extract metrics population into RunMetrics.Update method, eliminating duplicate logic between ClaudeRuntime.Run and progressParser - Add server_tool_use to assistant fallback path for consistency with the stream_event path Assisted-by: Claude claude-opus-4-6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
…rences - Apply sanitizeOutput to e.Subtype in renderer result label - Update design spec: replace extractBinaryName/allowedTools references with collapseCommand and current behavior Assisted-by: Claude claude-opus-4-6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
0141bbe to
c5d9f4d
Compare
Plan files are no longer kept in the repo. Assisted-by: Claude claude-opus-4-6 <noreply@anthropic.com> Signed-off-by: Ralph Bean <rbean@redhat.com>
|
🤖 Review · |
|
🤖 Finished Review · ✅ Success · Started 7:30 PM UTC · Completed 7:38 PM UTC |
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