From 0487b80b853cdb2437267aa24b0ba68d7687d155 Mon Sep 17 00:00:00 2001 From: Bradley-Butcher Date: Mon, 17 Nov 2025 09:36:45 +0000 Subject: [PATCH 1/2] support anthropic strict tools --- litellm/types/llms/anthropic.py | 1 + .../test_anthropic_completion.py | 75 +++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/litellm/types/llms/anthropic.py b/litellm/types/llms/anthropic.py index 950437744f7e..94cdb2775b38 100644 --- a/litellm/types/llms/anthropic.py +++ b/litellm/types/llms/anthropic.py @@ -25,6 +25,7 @@ class AnthropicMessagesToolChoice(TypedDict, total=False): "additionalProperties": Optional[bool], "required": Optional[List[str]], "$defs": Optional[Dict], + "strict": Optional[bool], }, total=False, ) diff --git a/tests/llm_translation/test_anthropic_completion.py b/tests/llm_translation/test_anthropic_completion.py index 27841140e5ba..a3c12db9bfe9 100644 --- a/tests/llm_translation/test_anthropic_completion.py +++ b/tests/llm_translation/test_anthropic_completion.py @@ -1691,3 +1691,78 @@ def test_anthropic_via_responses_api(): print(f"✓ All {len(events_seen)} events matched expected structure") print(f"✓ Received {text_delta_count} text delta chunks") + +def test_anthropic_strict_parameter_passthrough(): + """Test that the strict parameter in tool parameters is passed through to Anthropic input_schema""" + args = { + "non_default_params": { + "tools": [ + { + "type": "function", + "function": { + "name": "get_weather", + "description": "Get weather information", + "parameters": { + "type": "object", + "properties": { + "location": {"type": "string"}, + }, + "required": ["location"], + "strict": True, + }, + }, + } + ], + } + } + + mapped_params = litellm.AnthropicConfig().map_openai_params( + non_default_params=args["non_default_params"], + optional_params={}, + model="claude-sonnet-4-5-20250929", + drop_params=False, + ) + + # Verify the strict parameter is in the mapped tool's input_schema + assert "tools" in mapped_params + assert len(mapped_params["tools"]) == 1 + tool = mapped_params["tools"][0] + assert "input_schema" in tool + assert tool["input_schema"]["strict"] is True + +def test_anthropic_strict_not_present(): + """Test that the strict parameter in tool parameters is passed through to Anthropic input_schema""" + args = { + "non_default_params": { + "tools": [ + { + "type": "function", + "function": { + "name": "get_weather", + "description": "Get weather information", + "parameters": { + "type": "object", + "properties": { + "location": {"type": "string"}, + }, + "required": ["location"], + }, + }, + } + ], + } + } + + mapped_params = litellm.AnthropicConfig().map_openai_params( + non_default_params=args["non_default_params"], + optional_params={}, + model="claude-sonnet-4-5-20250929", + drop_params=False, + ) + + # Verify the strict parameter is in the mapped tool's input_schema + assert "tools" in mapped_params + assert len(mapped_params["tools"]) == 1 + tool = mapped_params["tools"][0] + assert "input_schema" in tool + assert "strict" not in tool["input_schema"] From abbe4dbfdd52b7056b9a0d0c10e36fe1fdb33eee Mon Sep 17 00:00:00 2001 From: Bradley-Butcher Date: Mon, 17 Nov 2025 09:56:50 +0000 Subject: [PATCH 2/2] correct comment from copy-paste --- tests/llm_translation/test_anthropic_completion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/llm_translation/test_anthropic_completion.py b/tests/llm_translation/test_anthropic_completion.py index a3c12db9bfe9..accb536afb1a 100644 --- a/tests/llm_translation/test_anthropic_completion.py +++ b/tests/llm_translation/test_anthropic_completion.py @@ -1760,7 +1760,7 @@ def test_anthropic_strict_not_present(): drop_params=False, ) - # Verify the strict parameter is in the mapped tool's input_schema + # Verify the strict parameter does not exist if it is not passed in assert "tools" in mapped_params assert len(mapped_params["tools"]) == 1 tool = mapped_params["tools"][0]