Skip to content

fix(anthropic): send parallel tool results in one user message - #52

Merged
zhanghanduo merged 1 commit into
mainfrom
fix/anthropic-merge-tool-results
Sep 29, 2026
Merged

zhanghanduo merged 1 commit into
mainfrom
fix/anthropic-merge-tool-results

Conversation

@zhanghanduo

Copy link
Copy Markdown
Collaborator

Problem

_to_anthropic_msg turns each OpenAI tool message into its own user message, so parallel tool calls produce consecutive user messages with one tool_result each. Anthropic merges them, but gateways translating the Messages API to another backend don't: llm-hub → deepseek-flash returned 400 "An assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'" and the ApodexHarness episode ended with llm_error at turn 2 (Forge r-20260929-110952-e081).

Fix

_merge_tool_results folds consecutive tool-result-only user messages into one (Anthropic's documented shape). Transient messages (runtime addendum) are never merged, so the rolling cache breakpoint from #48 still lands on the merged tool-result message.

Tests

  • Two parallel results → one user message with both tool_result blocks, addendum stays separate.
  • Cache breakpoint lands on the merged message, not the addendum.

Full suite 1612 passed; ruff + pyright clean. Fragment added.

🤖 Generated with Claude Code

Each OpenAI `tool` message was converted to its own user message, so a
turn with parallel calls produced consecutive user messages. Anthropic
merges them, but llm-hub translating to deepseek-flash rejects it:
"An assistant message with 'tool_calls' must be followed by tool
messages responding to each 'tool_call_id'" (Forge run
r-20260929-110952-e081, cs_encoded_word, turn 2). Fold consecutive
tool-result-only user messages into one, the documented shape.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@zhanghanduo
zhanghanduo merged commit 9a03a1c into main Sep 29, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant