From 053f53fa89f9914f80fe4be07aaf382b5ff0e3b7 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Sat, 2 May 2026 08:02:19 -0700 Subject: [PATCH] feat: map reasoning_effort=xhigh/max to budget_tokens on pre-4.6 Anthropic models Adds DEFAULT_REASONING_EFFORT_XHIGH_THINKING_BUDGET=8192 and DEFAULT_REASONING_EFFORT_MAX_THINKING_BUDGET=16384 (env-overridable) and extends AnthropicConfig._map_reasoning_effort so reasoning_effort='xhigh' and 'max' produce thinking={type:'enabled', budget_tokens:N} on pre-4.6 models. 4.6/4.7 behavior is unchanged: those still short-circuit to adaptive thinking and have output_config.effort applied separately by _apply_output_config (with per-model gating). --- litellm/constants.py | 6 ++++++ litellm/llms/anthropic/chat/transformation.py | 12 ++++++++++++ .../chat/test_anthropic_chat_transformation.py | 2 ++ 3 files changed, 20 insertions(+) diff --git a/litellm/constants.py b/litellm/constants.py index 334ef8d48a4..6e0d3f6d0e5 100644 --- a/litellm/constants.py +++ b/litellm/constants.py @@ -202,6 +202,12 @@ DEFAULT_REASONING_EFFORT_MEDIUM_THINKING_BUDGET = int( DEFAULT_REASONING_EFFORT_HIGH_THINKING_BUDGET = int( os.getenv("DEFAULT_REASONING_EFFORT_HIGH_THINKING_BUDGET", 4096) ) +DEFAULT_REASONING_EFFORT_XHIGH_THINKING_BUDGET = int( + os.getenv("DEFAULT_REASONING_EFFORT_XHIGH_THINKING_BUDGET", 8192) +) +DEFAULT_REASONING_EFFORT_MAX_THINKING_BUDGET = int( + os.getenv("DEFAULT_REASONING_EFFORT_MAX_THINKING_BUDGET", 16384) +) MAX_TOKEN_TRIMMING_ATTEMPTS = int( os.getenv("MAX_TOKEN_TRIMMING_ATTEMPTS", 10) ) # Maximum number of attempts to trim the message diff --git a/litellm/llms/anthropic/chat/transformation.py b/litellm/llms/anthropic/chat/transformation.py index 35624c93b37..2feb9d771d2 100644 --- a/litellm/llms/anthropic/chat/transformation.py +++ b/litellm/llms/anthropic/chat/transformation.py @@ -11,8 +11,10 @@ from litellm.constants import ( DEFAULT_ANTHROPIC_CHAT_MAX_TOKENS, DEFAULT_REASONING_EFFORT_HIGH_THINKING_BUDGET, DEFAULT_REASONING_EFFORT_LOW_THINKING_BUDGET, + DEFAULT_REASONING_EFFORT_MAX_THINKING_BUDGET, DEFAULT_REASONING_EFFORT_MEDIUM_THINKING_BUDGET, DEFAULT_REASONING_EFFORT_MINIMAL_THINKING_BUDGET, + DEFAULT_REASONING_EFFORT_XHIGH_THINKING_BUDGET, RESPONSE_FORMAT_TOOL_NAME, ) from litellm.litellm_core_utils.core_helpers import map_finish_reason @@ -823,6 +825,16 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): type="enabled", budget_tokens=DEFAULT_REASONING_EFFORT_MINIMAL_THINKING_BUDGET, ) + elif reasoning_effort == "xhigh": + return AnthropicThinkingParam( + type="enabled", + budget_tokens=DEFAULT_REASONING_EFFORT_XHIGH_THINKING_BUDGET, + ) + elif reasoning_effort == "max": + return AnthropicThinkingParam( + type="enabled", + budget_tokens=DEFAULT_REASONING_EFFORT_MAX_THINKING_BUDGET, + ) else: raise ValueError(f"Unmapped reasoning effort: {reasoning_effort}") 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 cbb9b21d620..b8f5ded1cd2 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 @@ -2159,6 +2159,8 @@ def test_reasoning_effort_maps_to_budget_thinking_for_non_opus_4_6(): ("medium", 2048), # DEFAULT_REASONING_EFFORT_MEDIUM_THINKING_BUDGET ("high", 4096), # DEFAULT_REASONING_EFFORT_HIGH_THINKING_BUDGET ("minimal", 128), # DEFAULT_REASONING_EFFORT_MINIMAL_THINKING_BUDGET + ("xhigh", 8192), # DEFAULT_REASONING_EFFORT_XHIGH_THINKING_BUDGET + ("max", 16384), # DEFAULT_REASONING_EFFORT_MAX_THINKING_BUDGET ] for effort, expected_budget in test_cases: