feat(agent-runtime): add normalizeContentBlocks for Anthropic SDK stream events#429
Conversation
…DK stream events mergeContentBlocks now auto-normalizes raw Anthropic streaming event blocks (content_block_start, content_block_delta, content_block_stop, etc.) into standard content blocks before merging. This allows upstream code to transparently pass through SDK events without manual format conversion. Normalization rules: - content_block_start[tool_use] → ToolUseContentBlock - content_block_delta[input_json_delta] → TextContentBlock (merged into tool_use.input) - content_block_delta[text_delta] → TextContentBlock - content_block_delta[thinking_delta] → discarded - content_block_stop / message_stop / message_delta → discarded - Standard blocks (text, tool_use, tool_result) → kept as-is Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdded a new static method Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 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 a normalizeContentBlocks method to the MessageConverter class to handle raw SDK streaming events, such as those from Anthropic. The method converts events like content_block_start and content_block_delta into standard MessageContentBlock types while discarding non-essential events like thinking_delta and message_stop. Comprehensive tests were added to verify the normalization logic and its integration into the existing mergeContentBlocks workflow. Review feedback suggests simplifying redundant string assignments and conditional checks within the new method.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/MessageConverter.ts`:
- Around line 121-126: The normalizeContentBlocks method currently types its
input as MessageContentBlock[] but actually accepts raw SDK event shapes; define
a new union type RawSdkStreamingEvent that lists the supported raw packet shapes
(e.g., content_block_start, content_block_delta with subtypes
input_json_delta/text_delta/thinking_delta, message_delta, message_stop), then
update the signatures of normalizeContentBlocks and mergeContentBlocks to accept
(blocks: (MessageContentBlock | RawSdkStreamingEvent)[]): MessageContentBlock[]
so callers can pass raw events without casting; ensure all internal
pattern-matching within normalizeContentBlocks and mergeContentBlocks uses the
new union type guards to discriminate event kinds.
- Around line 129-161: In MessageConverter.normalizeContentBlocks, add a branch
to detect and skip blocks where b.type === 'content_block_start' and
b.content_block?.type === ContentBlockType.Text so these streaming
"content_block_start[text]" events are discarded before falling through to the
generic result.push; update mergeContentBlocks-related tests to include a
streaming event sequence with content_block_start[text] to assert it is ignored
in the final normalized/merged message (reference symbols: MessageConverter,
normalizeContentBlocks, mergeContentBlocks, ContentBlockType.Text).
🪄 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: d2f976de-2041-4627-973b-2611455c4033
📒 Files selected for processing (2)
core/agent-runtime/src/MessageConverter.tscore/agent-runtime/test/MessageConverter.test.ts
Summary
mergeContentBlocksnow auto-normalizes raw Anthropic streaming event blocks before mergingnormalizeContentBlocksmethod converts SDK events (content_block_start,content_block_delta,content_block_stop, etc.) into standard content blocksNormalization rules
content_block_start[tool_use]ToolUseContentBlockcontent_block_delta[input_json_delta]TextContentBlock(merged intotool_use.input)content_block_delta[text_delta]TextContentBlockcontent_block_delta[thinking_delta]content_block_stop/message_stop/message_deltaTest plan
normalizeContentBlockscovering each event typemergeContentBlockswith raw Anthropic SDK stream events🤖 Generated with Claude Code
Summary by CodeRabbit
Refactor
Tests