diff --git a/litellm/llms/sap/chat/transformation.py b/litellm/llms/sap/chat/transformation.py index 622c28f3c90..0efb3848a17 100755 --- a/litellm/llms/sap/chat/transformation.py +++ b/litellm/llms/sap/chat/transformation.py @@ -349,7 +349,9 @@ class GenAIHubOrchestrationConfig(OpenAIGPTConfig): if "delimiters" in stream_options: stream_config["delimiters"] = stream_options["delimiters"] - optional_params.pop("tool_choice", None) + # tool_choice is forwarded via model.params for Anthropic and GPT models + if not model.startswith(("anthropic", "gpt")): + optional_params.pop("tool_choice", None) modules: Final = [ self._build_prompt_module( diff --git a/tests/unit/llms/sap/chat/test_sap_transformation.py b/tests/unit/llms/sap/chat/test_sap_transformation.py index 41e75b7bfc7..657d17a9509 100644 --- a/tests/unit/llms/sap/chat/test_sap_transformation.py +++ b/tests/unit/llms/sap/chat/test_sap_transformation.py @@ -641,6 +641,38 @@ class TestSAPTransformationIntegration: == "sap_document_translation" ) + @pytest.mark.parametrize("model", ["anthropic--claude-4.5-sonnet", "gpt-4o"]) + @pytest.mark.parametrize( + "tool_choice", + ["auto", "required", {"type": "function", "function": {"name": "get_pump"}}], + ) + def test_tool_choice_forwarded_in_model_params( + self, mock_config, model, tool_choice + ): + result = mock_config.transform_request( + model=model, + messages=[{"role": "user", "content": "Hello"}], + optional_params={ + "tools": [ + { + "type": "function", + "function": { + "name": "get_pump", + "parameters": {"type": "object", "properties": {}}, + }, + } + ], + "tool_choice": tool_choice, + }, + litellm_params={}, + headers={}, + ) + + model_params = result["config"]["modules"]["prompt_templating"]["model"][ + "params" + ] + assert model_params["tool_choice"] == tool_choice + class TestCacheControl: """Unit tests for cache_control preservation on message content parts."""