diff --git a/tests/test_litellm/llms/anthropic/experimental_pass_through/adapters/test_anthropic_experimental_pass_through_adapters_transformation.py b/tests/test_litellm/llms/anthropic/experimental_pass_through/adapters/test_anthropic_experimental_pass_through_adapters_transformation.py index 74e1e17e6d7..f0f57606f74 100644 --- a/tests/test_litellm/llms/anthropic/experimental_pass_through/adapters/test_anthropic_experimental_pass_through_adapters_transformation.py +++ b/tests/test_litellm/llms/anthropic/experimental_pass_through/adapters/test_anthropic_experimental_pass_through_adapters_transformation.py @@ -2641,3 +2641,62 @@ def test_translate_openai_response_to_anthropic_with_polyfill_both_compaction_an cm = result.get("context_management") assert cm is not None assert cm["applied_edits"][0]["type"] == "compact_20260112" + + +class TestTranslateToolsDropsToolChoice: + """Test that tool_choice is dropped when only web_search tools remain.""" + + def setup_method(self): + self.adapter = LiteLLMAnthropicMessagesAdapter() + + def test_tool_choice_removed_when_only_web_search_tools(self): + """When all tools are web_search-type, tool_choice should be popped.""" + new_kwargs: dict = {"tool_choice": "auto", "model": "gpt-4o"} + anthropic_request = { + "model": "claude-sonnet-4-20250514", + "max_tokens": 1024, + "messages": [{"role": "user", "content": "search the web"}], + "tools": [ + {"type": "web_search_20260209", "name": "web_search"}, + ], + "tool_choice": {"type": "auto"}, + } + + self.adapter._translate_tools_to_openai( + anthropic_message_request=anthropic_request, + new_kwargs=new_kwargs, + ) + + assert "tool_choice" not in new_kwargs + assert new_kwargs.get("web_search_options") == {} + + def test_tool_choice_preserved_when_regular_tools_exist(self): + """When regular tools exist alongside web_search, tool_choice stays.""" + new_kwargs: dict = {"tool_choice": "auto", "model": "gpt-4o"} + anthropic_request = { + "model": "claude-sonnet-4-20250514", + "max_tokens": 1024, + "messages": [{"role": "user", "content": "search and compute"}], + "tools": [ + {"type": "web_search_20260209", "name": "web_search"}, + { + "type": "custom", + "name": "get_weather", + "description": "Get weather", + "input_schema": { + "type": "object", + "properties": {"location": {"type": "string"}}, + }, + }, + ], + "tool_choice": {"type": "auto"}, + } + + self.adapter._translate_tools_to_openai( + anthropic_message_request=anthropic_request, + new_kwargs=new_kwargs, + ) + + assert "tool_choice" in new_kwargs + assert new_kwargs.get("web_search_options") == {} + assert "tools" in new_kwargs