diff --git a/litellm/llms/bedrock_mantle/responses/transformation.py b/litellm/llms/bedrock_mantle/responses/transformation.py index 2ea355fd369..d911a6c01be 100644 --- a/litellm/llms/bedrock_mantle/responses/transformation.py +++ b/litellm/llms/bedrock_mantle/responses/transformation.py @@ -48,7 +48,9 @@ _BASE_SUFFIXES_TO_STRIP: Final = ( ) # Per Bedrock Mantle Responses API validation errors. -_BEDROCK_MANTLE_SUPPORTED_RESPONSE_TOOL_TYPES = frozenset({"function", "mcp", "custom", "namespace", "tool_search"}) +_BEDROCK_MANTLE_SUPPORTED_RESPONSE_TOOL_TYPES: Final = frozenset( + {"function", "mcp", "custom", "namespace", "tool_search"} +) _BEDROCK_MANTLE_SUPPORTED_SERVICE_TIERS: Final = frozenset({"auto", "default"}) @@ -141,7 +143,9 @@ class BedrockMantleResponsesAPIConfig(BedrockMantleAuthMixin, OpenAIResponsesAPI kept.append(tool) continue tool_type = tool.get("type") - if tool_type in _BEDROCK_MANTLE_SUPPORTED_RESPONSE_TOOL_TYPES: + if tool_type in _BEDROCK_MANTLE_SUPPORTED_RESPONSE_TOOL_TYPES or ( + isinstance(tool_type, str) and tool_type.startswith("web_search") + ): kept.append(tool) else: dropped_types.append(str(tool_type)) diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 9ca8d9e1bac..7926dd5145f 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -49381,6 +49381,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_web_search": true, "supports_tool_choice": true, "supports_vision": true }, @@ -49414,6 +49415,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_web_search": true, "supports_tool_choice": true, "supports_vision": true }, @@ -49447,6 +49449,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_web_search": true, "supports_tool_choice": true, "supports_vision": true }, @@ -49624,6 +49627,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_web_search": true, "supports_tool_choice": true, "supports_vision": true }, @@ -49651,6 +49655,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_web_search": true, "supports_tool_choice": true, "supports_vision": true }, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 9ca8d9e1bac..7926dd5145f 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -49381,6 +49381,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_web_search": true, "supports_tool_choice": true, "supports_vision": true }, @@ -49414,6 +49415,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_web_search": true, "supports_tool_choice": true, "supports_vision": true }, @@ -49447,6 +49449,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_web_search": true, "supports_tool_choice": true, "supports_vision": true }, @@ -49624,6 +49627,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_web_search": true, "supports_tool_choice": true, "supports_vision": true }, @@ -49651,6 +49655,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_web_search": true, "supports_tool_choice": true, "supports_vision": true }, diff --git a/tests/test_litellm/llms/bedrock_mantle/test_bedrock_mantle_responses_transformation.py b/tests/test_litellm/llms/bedrock_mantle/test_bedrock_mantle_responses_transformation.py index 00a319f99f0..850b78aa108 100644 --- a/tests/test_litellm/llms/bedrock_mantle/test_bedrock_mantle_responses_transformation.py +++ b/tests/test_litellm/llms/bedrock_mantle/test_bedrock_mantle_responses_transformation.py @@ -327,12 +327,44 @@ class TestBedrockMantleResponsesRequestBody: class TestBedrockMantleResponsesTools: + @pytest.mark.parametrize( + "tool_type", ["web_search", "web_search_preview", "web_search_2025_08_26"] + ) + def test_web_search_tool_family_survives_map_openai_params(self, tool_type): + tool = {"type": tool_type, "filters": {"domains": ["example.com"]}} + cfg = BedrockMantleResponsesAPIConfig() + + params = cfg.map_openai_params( + response_api_optional_params={"tools": [tool]}, + model="openai.gpt-5.5", + drop_params=False, + ) + + assert params["tools"] == [tool] + + @pytest.mark.parametrize( + "tool_type", ["web_search", "web_search_preview", "web_search_2025_08_26"] + ) + def test_web_search_tool_family_survives_transform_responses_api_request(self, tool_type): + tool = {"type": tool_type, "filters": {"domains": ["example.com"]}} + cfg = BedrockMantleResponsesAPIConfig() + + body = cfg.transform_responses_api_request( + model="openai.gpt-5.5", + input="hello", + response_api_optional_request_params={"tools": [tool]}, + litellm_params=GenericLiteLLMParams(), + headers={}, + ) + + assert body["tools"] == [tool] + def test_map_openai_params_drops_unsupported_tools(self): cfg = BedrockMantleResponsesAPIConfig() params = cfg.map_openai_params( response_api_optional_params={ "tools": [ - {"type": "web_search"}, + {"type": "file_search"}, {"type": "function", "name": "exec_command"}, ] }, @@ -341,10 +373,13 @@ class TestBedrockMantleResponsesTools: ) assert params["tools"] == [{"type": "function", "name": "exec_command"}] - def test_map_openai_params_removes_tools_when_all_unsupported(self): + @pytest.mark.parametrize( + "tool_type", ["file_search", "image_generation", "code_interpreter"] + ) + def test_map_openai_params_removes_tools_when_all_unsupported(self, tool_type): cfg = BedrockMantleResponsesAPIConfig() params = cfg.map_openai_params( - response_api_optional_params={"tools": [{"type": "web_search"}]}, + response_api_optional_params={"tools": [{"type": tool_type}]}, model="openai.gpt-5.5", drop_params=False, ) @@ -358,12 +393,12 @@ class TestBedrockMantleResponsesTools: "litellm.llms.bedrock_mantle.responses.transformation.verbose_logger.warning" ) as mock_warning: cfg.map_openai_params( - response_api_optional_params={"tools": [{"type": "web_search"}]}, + response_api_optional_params={"tools": [{"type": "file_search"}]}, model="openai.gpt-5.5", drop_params=False, ) assert mock_warning.call_count == 1 - assert "web_search" in str(mock_warning.call_args) + assert "file_search" in str(mock_warning.call_args) def _codex_exec_tool(): @@ -544,14 +579,17 @@ class TestBedrockMantleCodexAdditionalTools: ) assert body["tools"] == [existing_tool, *self._CODEX_TOOLS] - def test_unsupported_hoisted_tool_types_are_dropped(self): + @pytest.mark.parametrize( + "tool_type", ["file_search", "image_generation", "code_interpreter"] + ) + def test_unsupported_hoisted_tool_types_are_dropped(self, tool_type): body = self._transform( input=[ { "type": "additional_tools", "role": "developer", "tools": [ - {"type": "web_search"}, + {"type": tool_type}, {"type": "function", "name": "wait"}, ], }, @@ -563,7 +601,7 @@ class TestBedrockMantleCodexAdditionalTools: def test_item_stripped_even_when_no_hoisted_tool_survives(self): body = self._transform( input=[ - {"type": "additional_tools", "role": "developer", "tools": [{"type": "web_search"}]}, + {"type": "additional_tools", "role": "developer", "tools": [{"type": "file_search"}]}, self._USER_MESSAGE, ] )