Repository navigation
fix(bedrock): return JSON for Claude Opus 5.5 response_format when tool_choice can't be forced - #42718
fix(bedrock): return JSON for Claude Opus 5.5 response_format when tool_choice can't be forced#42718kimnamu wants to merge 6 commits into
Conversation
…ol_choice can't be forced Opus 5.5 and Fable 5.1 reject a forced tool_choice on Bedrock, and litellm also skips the forced tool_choice whenever thinking is on, so the synthetic json_tool_call tool goes out unforced on those requests. With the default description the model often skips the tool and answers in plain text. When thinking is on or the model rejects forced tool use, give the tool a directive description, with the same condition in the Converse and Invoke routes. Other requests are unchanged
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…ting into it Greptile flagged the Invoke directive for mutating tool dicts in place. Anthropic-format tools reach map_openai_params as the caller's own dicts, so a caller tool that reused the reserved json_tool_call name would have carried the directive back into its later requests, and AGENTS.md rules out in-place mutation. Build a new dict for the json_tool_call tool and store the rebuilt list on optional_params, the way _add_tools_to_optional_params already does. Request bodies are unchanged.
|
Thanks for the quick review pass on this PR; the no-mutation point was worth acting on. Pushed 6bd579c so the Invoke path rebuilds the
Why the commit: at ChecksCaller-owned dict, before and after (Opus 5.5, Invoke, basedpyright on the changed file: 128 errors at |
…onse_format # Conflicts: # tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py
Thanks for the Fable 5.1 backstop in #39184 and the Opus 5.5 cost map entries in #42588. This picks up the unforced path #42644 left as "its own feature"
Size: 28 source lines, 94 test lines
TLDR
Problem this solves:
response_formatin plain textjson_tool_calltool gets skippedHow it solves it:
59db39626f)79eef9aa8d)/v1/chat/completions, ConverseParis.)/v1/chat/completions, Invoke/v1/responses/v1/messages,bedrock/converse/deployment"stream": true, 3 runsParis.)tool_choiceauto, required or named, both routesget_weather,tool_choiceauto, Opus 5 Converse and Invoke, Opus 5.5get_weather3/3 each/v1/messageson the default Invoke route (schema inlined, no tool)outputConfig)User Flow
Before: Opus 5.5 answers JSON requests in prose
opus-5-5, json_schemaresponse_format"Paris.",json.loadsfailsAfter: the same request returns JSON
{"name": "Paris", "country": "France"}Details
converse_transformation.py:1242-1249skips the forced choice when thinking is on or the model rejects it, and the description falls back to the tool name (factory.py:5132-5135)anthropic_claude3_transformation.py:118-126) and when thinking is on, and the tool has no descriptiontoolSpec.strictandoutputConfig.textFormaton Opus 5.5References: https://www.anthropic.com/news/claude-opus-5-5 , https://platform.claude.com/docs/en/models/opus-5-5/migration-guide , https://platform.claude.com/docs/en/about-claude/models/overview
59db39626f)79eef9aa8d)reasoning_effort="low", Conversereasoning_effort="low", Invokereasoning_effort="low", Converse, 3 runsreasoning_effort="low", Converse, 3 runsOffline body capture (7 Claude models on Converse and Invoke, 6 others on Converse, 5 variants each): 28 of 100 rows change, all thinking-on or forced-tool-rejected; tip bodies identical to
036cfb951bThe 4 cases that also pass on main are the forced-tool and caller-tool rows. They fail if the directive leaks into requests where the tool can be forced
59db39626f79eef9aa8dtests/test_litellm/llms/bedrocktests/unit/llms/bedrocktests/test_litellm/llms/anthropic/chatlitellm/files (CI scope), ruff strict, type discipline, test quality gatesRelevant issues
Fixes #42717
Affected release
Linear ticket
Pre-Submission checklist
Screenshots / Proof of Fix
Live Bedrock calls through a local proxy
Before (59db396)
Converse
Invoke
Responses
Messages
Streaming
Control
Caller tool
After (79eef9a)
Converse
Invoke
Responses
Messages
Streaming
Control
Caller tool
Type
🐛 Bug Fix
Caveats (if any)
Medium
tool_choiceto Opus 5.5 withresponse_format(Bedrock 400)Low
us.profiles onlyFinal Attestation