fix(bedrock): inject dummy tool when tool calls present without requiring modify_params

This commit is contained in:
Ayush Arora 2026-09-12 00:25:31 +05:30
parent 6882f057b4
commit 41801617cc
2 changed files with 51 additions and 8 deletions

View file

@ -1614,14 +1614,7 @@ class AmazonConverseConfig(BaseConfig):
Bedrock doesn't support tool calling without `tools=` param specified.
"""
if "tools" not in optional_params and messages is not None and has_tool_call_blocks(messages):
if litellm.modify_params:
optional_params["tools"] = add_dummy_tool(custom_llm_provider="bedrock_converse")
else:
raise litellm.UnsupportedParamsError(
message="Bedrock doesn't support tool calling without `tools=` param specified. Pass `tools=` param OR set `litellm.modify_params = True` // `litellm_settings::modify_params: True` to add dummy tool to the request.",
model="",
llm_provider="bedrock",
)
optional_params["tools"] = add_dummy_tool(custom_llm_provider="bedrock_converse")
# Drop thinking param if thinking is enabled but thinking_blocks are missing
# This prevents the error: "Expected thinking or redacted_thinking, but found tool_use"

View file

@ -6953,3 +6953,53 @@ def test_transform_response_honors_json_mode_kwarg_when_optional_params_lack_it(
)
assert result.choices[0].message.tool_calls is None
assert json.loads(result.choices[0].message.content) == {"city": "Paris", "population": 2100000}
def test_transform_request_injects_dummy_tool_without_tools_param():
"""
Bedrock Converse rejects requests with tool turns when toolConfig is omitted.
LiteLLM must inject a dummy tool without requiring litellm.modify_params.
"""
from litellm.llms.bedrock.chat.converse_transformation import AmazonConverseConfig
config = AmazonConverseConfig()
prev_modify_params = litellm.modify_params
litellm.modify_params = False
try:
messages = [
{"role": "user", "content": "Hello"},
{
"role": "assistant",
"content": "Calling tool",
"tool_calls": [
{
"id": "tooluse_test_dummy",
"type": "function",
"function": {"name": "get_x", "arguments": "{}"},
}
],
},
{
"role": "tool",
"tool_call_id": "tooluse_test_dummy",
"content": "{}",
},
]
result = config.transform_request(
model="anthropic.claude-3-5-sonnet-20240620-v1:0",
messages=messages,
optional_params={},
litellm_params={},
headers={},
)
finally:
litellm.modify_params = prev_modify_params
assert "toolConfig" in result
tools = result["toolConfig"].get("tools", [])
tool_names = [
t.get("toolSpec", {}).get("name")
for t in tools
if isinstance(t, dict) and "toolSpec" in t
]
assert "dummy_tool" in tool_names