fix(agent-runtime): preserve non-text content blocks in MessageConverter#426
Conversation
MessageConverter.toContentBlocks() was filtering out all non-text content blocks (tool_use, tool_result, etc.), causing lossy message conversion when execRun is implemented with @anthropic-ai/claude-agent-sdk. Changes: - Widen ContentBlockType to include ToolUse and ToolResult - Add ToolUseContentBlock, ToolResultContentBlock, GenericContentBlock types - Add corresponding input types (TextInputContentPart, etc.) - Fix toContentBlocks(): .filter().map() → .map() with text wrapping and non-text passthrough - Fix toInputMessageObjects(): same treatment for input messages - Add isTextBlock/isToolUseBlock/isToolResultBlock type guard helpers - Update InputMessage.content type to use InputContentPart[] - Add comprehensive test coverage for non-text content preservation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe changes expand message content handling to support tool-related blocks (tool_use, tool_result, generic) alongside text blocks. Type guards are added to discriminate content variants. Conversion logic in MessageConverter is updated to preserve non-text blocks instead of filtering them, and new content-part interfaces are introduced for input/output typing. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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 tool-related content blocks (tool_use, tool_result) and generic blocks within the agent runtime. It includes new type definitions, type guards, and updates to the MessageConverter to ensure these blocks are preserved during message processing. Comprehensive tests have been added to verify the handling of mixed content types. A review comment identifies an opportunity to reduce code duplication in MessageConverter.ts by reusing the toContentBlocks method.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/types/agent-runtime/AgentMessage.ts`:
- Around line 76-78: The InputMessage.content type change breaks existing
callers and the MessageConverter which assumes non-string content is an array;
update the InputMessage interface to accept string | InputContentPart |
InputContentPart[] (restore single-object support) and then normalize inside the
MessageConverter method that maps content (the mapping call around
MessageConverter.ts:148) by treating a single InputContentPart as [part] before
calling .map(); ensure the converter branches handle string, single object, and
array uniformly so tests and examples continue to work.
🪄 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: d8cfd482-70d7-4340-b704-3b69475a85d9
📒 Files selected for processing (5)
core/agent-runtime/src/MessageConverter.tscore/agent-runtime/test/AgentRuntime.test.tscore/agent-runtime/test/MessageConverter.test.tscore/tegg/agent.tscore/types/agent-runtime/AgentMessage.ts
Summary
MessageConverter.toContentBlocks()有损转换问题:原实现通过.filter(part => part.type === 'text')过滤掉了所有非 text 类型的 content block(如tool_use、tool_result),导致基于@anthropic-ai/claude-agent-sdk实现execRun时,工具调用信息在转换后丢失MessageConverter.toInputMessageObjects()同样的有损问题:原实现将所有 content part 当作 text 处理,非 text 块的.text为 undefinedContentBlockType中新增ToolUse、ToolResult,新增对应的输入/输出类型接口,并增加GenericContentBlock兜底未来新类型isTextBlock()、isToolUseBlock()、isToolResultBlock()方便业务代码做类型收窄Affected areas
Test plan
toContentBlocks保留 tool_use content partstoContentBlocks保留 tool_result content parts(含 is_error 标记)toContentBlocks保留未知类型 content parts(generic 兜底)toContentBlocks保持混合类型的顺序toMessageObject保留 tool_use blocksextractFromStreamMessages正确提取包含 tool_use 的消息toInputMessageObjects保留 tool_use / tool_result blocks🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Improvements