feat(agent-runtime): support custom SSE event types in streamRun#427
feat(agent-runtime): support custom SSE event types in streamRun#427jerryliang64 merged 2 commits intomasterfrom
Conversation
When AgentStreamMessage.type is set, consumeStreamMessages forwards it as the SSE event name instead of the default thread.message.delta. Content blocks are still accumulated for storage. This enables upstream executors to emit fine-grained events like assistant.text.delta, tool.started, tool.completed etc., giving consumers a richer streaming protocol while maintaining backward compatibility — messages without type continue to use thread.message.delta. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe stream consumer in Changes
Sequence Diagram(s)sequenceDiagram
participant Executor as Executor
participant Runtime as AgentRuntime
participant Converter as MessageConverter
participant Writer as SSEWriter
Executor->>Runtime: yield AgentStreamMessage (with type & message/usage)
alt msg.type present
Runtime->>Converter: toContentBlocks(msg.message)
Converter-->>Runtime: contentBlocks
Runtime->>Writer: writeEvent(msg.type, { id, content: contentBlocks or undefined })
else msg.type absent
Runtime->>Writer: writeEvent(ThreadMessageDelta, { id, delta: msg.message.delta })
end
Runtime->>Runtime: accumulate token usage / run-completion totals
Runtime->>Writer: writeEvent(ThreadRunCompleted, { id, usage: aggregatedUsage })
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
There was a problem hiding this comment.
Code Review
This pull request introduces support for custom event types in the AgentRuntime, allowing messages with a defined type to be forwarded directly to the event writer while still accumulating content for storage. It also includes new test cases to verify custom event forwarding and fallback behavior. A critical issue was identified in the implementation where the use of a continue statement skips the token usage accumulation logic, which would result in the loss of usage statistics for events that contain both a custom type and usage data.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
core/agent-runtime/test/AgentRuntime.test.ts (1)
451-504: Add coverage forusageon custom typed eventsGreat coverage overall. Please add one typed chunk that also includes
usageand assert final run usage totals, so this path is regression-proof.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@core/agent-runtime/test/AgentRuntime.test.ts` around lines 451 - 504, Add a test case step that includes usage on a custom typed AgentStreamMessage and assert the aggregated run usage totals after streamRun completes: inside the existing test "should forward custom event types from AgentStreamMessage.type" (where executor.execRun yields AgentStreamMessage objects), add one yield with a custom type whose message includes a usage object (e.g., message.usage = { prompt_tokens: X, completion_tokens: Y, total_tokens: Z }), then after await runtime.streamRun(...) locate the final run-completed/framework event (e.g., AgentSSEEvent.ThreadRunCompleted or the stored completed event found via writer.events) and assert that its data contains the expected aggregated usage totals; ensure you update references to writer.events, customEvents, and the completedEvent lookup so the new usage-bearing event is included in accumulation and the final assertion checks totals.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@core/agent-runtime/src/AgentRuntime.ts`:
- Around line 359-373: When msg.type is present the code returns early (the
continue at the end of the custom-event branch) and thereby skips accounting of
any token usage that may be attached to that chunk; update the custom-event
handling (the branch that calls MessageConverter.toContentBlocks and
writer.writeEvent) to also process msg.usage before continuing — e.g.,
merge/apply msg.usage into the run-level usage accumulator (or call the same
usage-adding helper used in the normal flow) so that usage is not dropped for
messages that include both a custom type and a usage field; ensure the same
change is mirrored for the other branch noted (the code around the existing
usage handling at lines corresponding to 387-391).
---
Nitpick comments:
In `@core/agent-runtime/test/AgentRuntime.test.ts`:
- Around line 451-504: Add a test case step that includes usage on a custom
typed AgentStreamMessage and assert the aggregated run usage totals after
streamRun completes: inside the existing test "should forward custom event types
from AgentStreamMessage.type" (where executor.execRun yields AgentStreamMessage
objects), add one yield with a custom type whose message includes a usage object
(e.g., message.usage = { prompt_tokens: X, completion_tokens: Y, total_tokens: Z
}), then after await runtime.streamRun(...) locate the final
run-completed/framework event (e.g., AgentSSEEvent.ThreadRunCompleted or the
stored completed event found via writer.events) and assert that its data
contains the expected aggregated usage totals; ensure you update references to
writer.events, customEvents, and the completedEvent lookup so the new
usage-bearing event is included in accumulation and the final assertion checks
totals.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f8fd13e3-049a-4611-a0fd-f9772443de3f
📒 Files selected for processing (2)
core/agent-runtime/src/AgentRuntime.tscore/agent-runtime/test/AgentRuntime.test.ts
…stom type The `continue` statement in the custom event branch caused `msg.usage` processing to be skipped entirely. Replace with `else if` so usage accumulation always runs regardless of event type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
AgentStreamMessage.typeis set,consumeStreamMessagesuses it as the SSE event name instead of the defaultthread.message.deltatypecontinue to usethread.message.delta(fully backward compatible)This enables upstream executors to emit fine-grained events like:
run.initialized— session readyassistant.turn.started— new assistant turn beginsassistant.text.delta— text streaming chunkassistant.thinking.delta— thinking streaming chunktool.started— tool invocation beginstool.delta— tool input streamingtool.completed— tool result returnedassistant.message.completed— turn finishedTest plan
content: undefined🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests