From f069da8e0ead97381775a6dce8af3675f43fbe13 Mon Sep 17 00:00:00 2001 From: ryan-crabbe-berri Date: Thu, 5 Nov 2026 12:38:58 -0800 Subject: [PATCH] fix(anthropic): report temperature/top_p as supported only when the model keeps them (#50144) * fix(anthropic): report temperature/top_p as supported only when the model keeps them Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(vertex_ai): accept the generic unsupported-param message for Claude batch rows Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- litellm/llms/anthropic/chat/transformation.py | 4 ++-- .../test_anthropic_chat_transformation.py | 21 +++++++++++++++++++ .../test_vertex_ai_files_transformation.py | 2 +- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/litellm/llms/anthropic/chat/transformation.py b/litellm/llms/anthropic/chat/transformation.py index 4f890ed922f..ac4addb0847 100644 --- a/litellm/llms/anthropic/chat/transformation.py +++ b/litellm/llms/anthropic/chat/transformation.py @@ -827,11 +827,11 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): return cls._raise_invalid_reasoning_effort(model, value, llm_provider) def get_supported_openai_params(self, model: str): + sampling_params: Final = ("temperature", "top_p") if self._supports_sampling_params(model) else () params: Final = [ "stream", "stop", - "temperature", - "top_p", + *sampling_params, "max_tokens", "max_completion_tokens", "tools", diff --git a/tests/unit/llms/anthropic/chat/test_anthropic_chat_transformation.py b/tests/unit/llms/anthropic/chat/test_anthropic_chat_transformation.py index 80845b1f12d..3a4231443dd 100644 --- a/tests/unit/llms/anthropic/chat/test_anthropic_chat_transformation.py +++ b/tests/unit/llms/anthropic/chat/test_anthropic_chat_transformation.py @@ -11047,3 +11047,24 @@ def test_claude_cache_control_cap_does_not_count_a_message_level_hint_that_list_ assert sorted(_cached_texts(body)) == ["system prompt", "turn 1", "turn 2", "turn 3"] assert json.dumps(body).count('"cache_control"') == 4 + + +@pytest.mark.parametrize("model", ["claude-opus-4-7", "claude-haiku-4-5-20251001"]) +def test_get_supported_params_reports_sampling_params_only_when_the_request_keeps_them( + local_model_cost_map, model: str +): + """What get_supported_openai_params says about temperature/top_p must match what + map_openai_params does with them under drop_params, so a caller that pre-flights + from the list is never told a param is fine that the request path then drops.""" + config = AnthropicConfig() + + supported = config.get_supported_openai_params(model=model) + sent = config.map_openai_params( + non_default_params={"temperature": 0.1, "top_p": 0.5}, + optional_params={}, + model=model, + drop_params=True, + ) + + assert ("temperature" in supported) == ("temperature" in sent), (model, supported, sent) + assert ("top_p" in supported) == ("top_p" in sent), (model, supported, sent) diff --git a/tests/unit/llms/vertex_ai/files/test_vertex_ai_files_transformation.py b/tests/unit/llms/vertex_ai/files/test_vertex_ai_files_transformation.py index 98e204dd44e..842500a7b27 100644 --- a/tests/unit/llms/vertex_ai/files/test_vertex_ai_files_transformation.py +++ b/tests/unit/llms/vertex_ai/files/test_vertex_ai_files_transformation.py @@ -2161,7 +2161,7 @@ class TestVertexClaudeBatch: monkeypatch.setattr(litellm, "drop_params", False) entry: Final = _claude_chat_entry("r1", "hi", max_tokens=10, top_p=0.5) - with pytest.raises(VertexAIError, match=r"line 1 .*top_p=0.5.*drop_params") as exc_info: + with pytest.raises(VertexAIError, match=r"line 1 .*top_p.*drop_params") as exc_info: _uploaded_rows(config, {**CLAUDE_DEPLOYMENT, "model": "vertex_ai/claude-zeta-9"}, [entry]) assert exc_info.value.status_code == 400