fix: convert OpenAI-format tool messages in OAuth path#354
Merged
Conversation
… path The OAuth path bypasses LiteLLM and calls the Anthropic Messages API directly via httpx. Unlike LiteLLM, it was not converting OpenAI-format tool messages (role:"tool", assistant tool_calls) to Anthropic format (role:"user" with tool_result blocks, assistant with tool_use blocks). When an agent's chat history contained tool results from previous turns, the heartbeat would trigger a new chat turn, and the OAuth path would send the raw OpenAI-format messages to Anthropic — which rejects them with HTTP 400: "Unexpected role 'tool'". Changes: - _build_anthropic_body now converts assistant tool_calls to tool_use content blocks and role:"tool" messages to role:"user" with tool_result blocks, merging consecutive tool results - _oauth_chat records failures for connection/timeout and 401 errors (previously silent — health tracker was blind to these) - _oauth_chat_stream records failures for 401 and non-success HTTP responses (previously only caught streaming parse exceptions) - Failover warning log now includes error_type and status_code in the message text (previously only in extra dict, invisible in log output) - Added 529 (Anthropic overloaded) to transient status codes for proper exponential backoff instead of flat 60s default cooldown
…utive user roles _hard_prune drops middle message groups, which can leave the first group (user) adjacent to a kept group that also starts with user — creating consecutive same-role messages. The Anthropic API rejects these with 400. _summarize_compact already handled this with a bridge message; now _hard_prune does the same.
bicced
added a commit
that referenced
this pull request
Mar 6, 2026
PR #354 landed the same OAuth tool message conversion inline. Remove our extracted _convert_messages_to_anthropic() (now dead code) and keep origin/main's tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_oauth_chat/_oauth_chat_stream) bypasses LiteLLM and calls the Anthropic Messages API directly. Unlike LiteLLM,_build_anthropic_bodywas not converting OpenAI-format tool messages (role: "tool", assistanttool_calls) to Anthropic format (role: "user"withtool_resultblocks, assistant withtool_usecontent blocks). When an agent's chat history contained tool results from previous turns, Anthropic rejected them with HTTP 400:Unexpected role "tool".Test plan