fix(anthropic): strip content from assistant messages with tool call for bedrock#1599
fix(anthropic): strip content from assistant messages with tool call for bedrock#1599Pnkcaht wants to merge 3 commits intodocker:mainfrom
Conversation
… for Bedrock Signed-off-by: pnkcaht <samzoovsk19@gmail.com>
|
/review |
There was a problem hiding this comment.
Review Summary
Found 1 potential issue in the changed code related to tool call handling that could cause message sequencing problems.
Key Finding:
The new validation logic skips tool calls with missing IDs but still appends the message, which could cause mismatches between tool_use and tool_result blocks.
Note: The JSON unmarshal fallback behavior exists in both old and new code - the PR only adds logging, so that's not a new issue.
I'm not sure we should do this, maybe it'd be better to split it out into its own message before the tool calls |
Do you want me to do it? I'll do it without a problem, it needs to be perfect :) |
… in convertMessages (docker#1593) Signed-off-by: pnkcaht <samzoovsk19@gmail.com>
… improve logging (docker#1593) Signed-off-by: pnkcaht <samzoovsk19@gmail.com>
|
@krissetto Done! I implemented the split: if there's content + tool calls, I send the message first with just the text/reasoning (preserving the logic) and then only with the use of the tool. Full history, Bedrock protocol ok. Suggestion made by the AI also resolved in the other commit. |
What I Did
pkg/model/provider/anthropic/client.go, updated theconvertMessagesfunction to strictly separatecontent(text) andtool_useblocks in assistant messages.msg.ToolCallsexists, we now ignore anymsg.Content(text) to comply with Anthropic / AWS Bedrock strict protocol (no mixing allowed).ValidationExceptionon Bedrock when usingtransfer_taskin multi-agent setups.Releated Issue
Closes #1593
Before & After
Before
Before (caused ValidationException on Bedrock):
{ "role": "assistant", "content": "Let me proceed with analyzing the issue...", "tool_calls": [ { "id": "tooluse_ABC123", "type": "function", "function": { "name": "transfer_task", "arguments": "{\"agent\": \"scout\", \"task\": \"Retrieve data from source A\", \"expected_output\": \"Summary of findings\"}" } }, { "id": "tooluse_XYZ789", "type": "function", "function": { "name": "transfer_task", "arguments": "{\"agent\": \"coder\", \"task\": \"Analyze the implementation\", \"expected_output\": \"Technical analysis\"}" } } ] }After
After (now compliant with Anthropic/Bedrock protocol):
{ "role": "assistant", "tool_calls": [ { "id": "tooluse_ABC123", "type": "function", "function": { "name": "transfer_task", "arguments": "{\"agent\": \"scout\", \"task\": \"Retrieve data from source A\", \"expected_output\": \"Summary of findings\"}" } }, { "id": "tooluse_XYZ789", "type": "function", "function": { "name": "transfer_task", "arguments": "{\"agent\": \"coder\", \"task\": \"Analyze the implementation\", \"expected_output\": \"Technical analysis\"}" } } ] }Diagram
sequenceDiagram participant Coordinator as Coordinator Agent participant LLM as Anthropic/Bedrock participant Subagents as Subagents (scout, coder) Note over Coordinator,Subagents: Before (broken) Coordinator->>LLM: Send message with text + transfer_task calls LLM-->>Coordinator: Returns assistant msg with content + tool_calls Coordinator->>Bedrock: Send conversation history Bedrock-->>Coordinator: ValidationException (mixing forbidden) Note over Coordinator,Subagents: After (fixed) Coordinator->>LLM: Send prompt (no text + tool calls) LLM-->>Coordinator: Returns assistant msg with only tool_use blocks Coordinator->>Subagents: Execute transfer_task Subagents-->>Coordinator: Return tool results Coordinator->>LLM: Send next turn with tool_results LLM-->>Coordinator: Final analysis (only content, no tool_calls) Coordinator->>User: Response