diff --git a/litellm/llms/anthropic/chat/transformation.py b/litellm/llms/anthropic/chat/transformation.py index 2b3647d944c..ded1babcb6b 100644 --- a/litellm/llms/anthropic/chat/transformation.py +++ b/litellm/llms/anthropic/chat/transformation.py @@ -1534,19 +1534,16 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): f"Invalid effort value: {effort}. Must be one of: " f"'high', 'medium', 'low', 'xhigh', 'max'" ) - # ``max`` is supported by Claude Opus 4.6 and Opus 4.7 (not Sonnet 4.6, - # not Opus 4.5). The upstream Anthropic API accepts effort=max on both - # Opus 4.6 and 4.7, so we keep both substring checks here for - # date-variant tolerance (e.g. claude-opus-4-7-20260408). See #25957. - if effort == "max" and not ( - self._is_opus_4_6_model(model) or self._is_opus_4_7_model(model) - ): + # Both ``max`` and ``xhigh`` are data-driven via + # ``supports_{level}_reasoning_effort`` in the model map, mirroring the + # pattern used in ``openai/chat/gpt_5_transformation.py``. Enabling a + # new model for either level is therefore a pure model-map change. + # Per Anthropic's effort docs, ``max`` is currently accepted on Claude + # Opus 4.6, Opus 4.7, and Sonnet 4.6. See #25957 / #25958. + if effort == "max" and not self._supports_effort_level(model, "max"): raise ValueError( - f"effort='max' is only supported by Claude Opus 4.6 and 4.7. " - f"Got model: {model}" + f"effort='max' is not supported by this model. Got model: {model}" ) - # ``xhigh`` is data-driven via ``supports_xhigh_reasoning_effort`` so - # enabling it for a new model is a pure model-map change. if effort == "xhigh" and not self._supports_effort_level(model, "xhigh"): raise ValueError( f"effort='xhigh' is not supported by this model. Got model: {model}" diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 04b68b8f4ec..e7791e6f740 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -1145,6 +1145,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "supports_native_structured_output": true }, @@ -1173,6 +1174,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "supports_native_structured_output": true }, @@ -1201,6 +1203,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "supports_native_structured_output": true }, @@ -1229,6 +1232,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "supports_native_structured_output": true }, @@ -1257,6 +1261,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "supports_native_structured_output": true }, @@ -1285,7 +1290,8 @@ "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true }, "global.anthropic.claude-sonnet-4-6": { "cache_creation_input_token_cost": 3.75e-06, @@ -1312,7 +1318,8 @@ "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true }, "us.anthropic.claude-sonnet-4-6": { "cache_creation_input_token_cost": 4.125e-06, @@ -1339,7 +1346,8 @@ "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true }, "eu.anthropic.claude-sonnet-4-6": { "cache_creation_input_token_cost": 4.125e-06, @@ -1366,7 +1374,8 @@ "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true }, "au.anthropic.claude-sonnet-4-6": { "cache_creation_input_token_cost": 4.125e-06, @@ -1393,7 +1402,8 @@ "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true }, "anthropic.claude-sonnet-4-20250514-v1:0": { "cache_creation_input_token_cost": 3.75e-06, @@ -1939,6 +1949,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 159 }, "azure_ai/claude-opus-4-1": { @@ -2003,7 +2014,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "tool_use_system_prompt_tokens": 346 + "tool_use_system_prompt_tokens": 346, + "supports_max_reasoning_effort": true }, "azure/computer-use-preview": { "input_cost_per_token": 3e-06, @@ -8909,7 +8921,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "tool_use_system_prompt_tokens": 346 + "tool_use_system_prompt_tokens": 346, + "supports_max_reasoning_effort": true }, "claude-sonnet-4-5-20250929-v1:0": { "cache_creation_input_token_cost": 3.75e-06, @@ -9163,6 +9176,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "provider_specific_entry": { "us": 1.1, @@ -9195,6 +9209,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "provider_specific_entry": { "us": 1.1, @@ -31399,6 +31414,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346 }, "vertex_ai/claude-opus-4-7@default": { @@ -31426,6 +31442,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346 }, "vertex_ai/claude-sonnet-4-5": { @@ -31478,7 +31495,8 @@ "search_context_size_high": 0.01, "search_context_size_low": 0.01, "search_context_size_medium": 0.01 - } + }, + "supports_max_reasoning_effort": true }, "vertex_ai/claude-sonnet-4-5@20250929": { "cache_creation_input_token_cost": 3.75e-06, @@ -38345,7 +38363,8 @@ "search_context_size_high": 0.01, "search_context_size_low": 0.01, "search_context_size_medium": 0.01 - } + }, + "supports_max_reasoning_effort": true }, "duckduckgo/search": { "litellm_provider": "duckduckgo", diff --git a/litellm/types/utils.py b/litellm/types/utils.py index d0bc9b78941..ae37c51466f 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -140,6 +140,7 @@ class ProviderSpecificModelInfo(TypedDict, total=False): supports_url_context: Optional[bool] supports_none_reasoning_effort: Optional[bool] supports_xhigh_reasoning_effort: Optional[bool] + supports_max_reasoning_effort: Optional[bool] class SearchContextCostPerQuery(TypedDict, total=False): diff --git a/litellm/utils.py b/litellm/utils.py index 2125875ee1d..4087b2bb9f1 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -5896,6 +5896,9 @@ def _get_model_info_helper( # noqa: PLR0915 supports_xhigh_reasoning_effort=_model_info.get( "supports_xhigh_reasoning_effort", None ), + supports_max_reasoning_effort=_model_info.get( + "supports_max_reasoning_effort", None + ), supports_computer_use=_model_info.get("supports_computer_use", None), search_context_cost_per_query=_model_info.get( "search_context_cost_per_query", None diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 04b68b8f4ec..e7791e6f740 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -1145,6 +1145,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "supports_native_structured_output": true }, @@ -1173,6 +1174,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "supports_native_structured_output": true }, @@ -1201,6 +1203,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "supports_native_structured_output": true }, @@ -1229,6 +1232,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "supports_native_structured_output": true }, @@ -1257,6 +1261,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "supports_native_structured_output": true }, @@ -1285,7 +1290,8 @@ "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true }, "global.anthropic.claude-sonnet-4-6": { "cache_creation_input_token_cost": 3.75e-06, @@ -1312,7 +1318,8 @@ "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true }, "us.anthropic.claude-sonnet-4-6": { "cache_creation_input_token_cost": 4.125e-06, @@ -1339,7 +1346,8 @@ "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true }, "eu.anthropic.claude-sonnet-4-6": { "cache_creation_input_token_cost": 4.125e-06, @@ -1366,7 +1374,8 @@ "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true }, "au.anthropic.claude-sonnet-4-6": { "cache_creation_input_token_cost": 4.125e-06, @@ -1393,7 +1402,8 @@ "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true }, "anthropic.claude-sonnet-4-20250514-v1:0": { "cache_creation_input_token_cost": 3.75e-06, @@ -1939,6 +1949,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 159 }, "azure_ai/claude-opus-4-1": { @@ -2003,7 +2014,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "tool_use_system_prompt_tokens": 346 + "tool_use_system_prompt_tokens": 346, + "supports_max_reasoning_effort": true }, "azure/computer-use-preview": { "input_cost_per_token": 3e-06, @@ -8909,7 +8921,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "tool_use_system_prompt_tokens": 346 + "tool_use_system_prompt_tokens": 346, + "supports_max_reasoning_effort": true }, "claude-sonnet-4-5-20250929-v1:0": { "cache_creation_input_token_cost": 3.75e-06, @@ -9163,6 +9176,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "provider_specific_entry": { "us": 1.1, @@ -9195,6 +9209,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346, "provider_specific_entry": { "us": 1.1, @@ -31399,6 +31414,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346 }, "vertex_ai/claude-opus-4-7@default": { @@ -31426,6 +31442,7 @@ "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, "tool_use_system_prompt_tokens": 346 }, "vertex_ai/claude-sonnet-4-5": { @@ -31478,7 +31495,8 @@ "search_context_size_high": 0.01, "search_context_size_low": 0.01, "search_context_size_medium": 0.01 - } + }, + "supports_max_reasoning_effort": true }, "vertex_ai/claude-sonnet-4-5@20250929": { "cache_creation_input_token_cost": 3.75e-06, @@ -38345,7 +38363,8 @@ "search_context_size_high": 0.01, "search_context_size_low": 0.01, "search_context_size_medium": 0.01 - } + }, + "supports_max_reasoning_effort": true }, "duckduckgo/search": { "litellm_provider": "duckduckgo", diff --git a/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py b/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py index e44c4791726..1707447cd83 100644 --- a/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py +++ b/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py @@ -1654,7 +1654,7 @@ def test_max_effort_rejected_for_opus_45(): messages = [{"role": "user", "content": "Test"}] with pytest.raises( - ValueError, match="effort='max' is only supported by Claude Opus 4.6 and 4.7" + ValueError, match="effort='max' is not supported by this model" ): optional_params = {"output_config": {"effort": "max"}} config.transform_request( @@ -2212,21 +2212,25 @@ def test_reasoning_effort_does_not_set_output_config_for_older_models(): ), f"output_config should not be set for {model}" -def test_max_effort_rejected_for_sonnet_46(): - """Test that effort='max' is rejected for Sonnet 4.6 (Sonnet 4.6 doesn't support max).""" +def test_max_effort_accepted_for_sonnet_46(): + """Per Anthropic's effort docs, ``max`` is supported by Sonnet 4.6. + + Source: https://platform.claude.com/docs/en/build-with-claude/effort + > The ``max`` effort level is available on Claude Mythos Preview, + > Claude Opus 4.7, Claude Opus 4.6, and Claude Sonnet 4.6. + """ config = AnthropicConfig() messages = [{"role": "user", "content": "Test"}] - with pytest.raises( - ValueError, match="effort='max' is only supported by Claude Opus 4.6 and 4.7" - ): - config.transform_request( - model="claude-sonnet-4-6-20260219", - messages=messages, - optional_params={"output_config": {"effort": "max"}}, - litellm_params={}, - headers={}, - ) + result = config.transform_request( + model="claude-sonnet-4-6", + messages=messages, + optional_params={"output_config": {"effort": "max"}}, + litellm_params={}, + headers={}, + ) + + assert result["output_config"]["effort"] == "max" def test_max_effort_accepted_for_opus_46(): @@ -2235,7 +2239,7 @@ def test_max_effort_accepted_for_opus_46(): messages = [{"role": "user", "content": "Test"}] result = config.transform_request( - model="claude-opus-4-6-20250514", + model="claude-opus-4-6-20260205", messages=messages, optional_params={"output_config": {"effort": "max"}}, litellm_params={},