mirror of
https://github.com/tiennm99/litellm.git
synced 2026-06-17 10:47:56 +00:00
refactor(anthropic): drive adaptive-thinking gate via supports_adaptive_thinking flag
Three of greptile's open comments on #27074 (P2 converse:512, P1 databricks:361, and the underlying capability-flag policy rule) flagged the same pattern: _is_claude_4_6_model(...) or _is_claude_4_7_model(...) used inline as a runtime 'is this an adaptive-thinking model?' check. That requires a code release each time a new adaptive Claude lands. Consolidate the inline gating to AnthropicModelInfo._is_adaptive_thinking_model, and switch the helper itself to read a new supports_adaptive_thinking flag from `model_prices_and_context_window.json` via `_supports_factory`, falling back to the family pattern only when the model-map entry doesn't carry the flag (preserves OpenRouter / Vercel / Bedrock-prefixed variants that route through the same code path with non-canonical ids). Adds `supports_adaptive_thinking: true` to the four 4.6/4.7 anthropic entries (opus-4-6 + dated, opus-4-7 + dated, sonnet-4-6). Bedrock-prefixed and Vertex-prefixed entries don't need the flag because both fall back through the family pattern (the helper short-circuits early on True from either path) and the bedrock/vertex Claude IDs all match the existing opus-4-{6,7} / sonnet-4-{6,7} pattern. Affected call sites: - `bedrock/chat/converse_transformation.py:_handle_reasoning_effort_parameter` - `anthropic/chat/transformation.py:_map_reasoning_effort` - `anthropic/chat/transformation.py:map_openai_params` (output_config branch) - `databricks/chat/transformation.py:map_openai_params` (output_config branch) The remaining `_is_claude_4_6_model` / `_is_claude_4_7_model` references in `AnthropicConfig._validate_effort_for_model` and `AnthropicConfig.get_supported_openai_params` are intentionally retained: they're per-model gating fallbacks for variants whose model-map entries don't yet carry the `supports_max_reasoning_effort` / `supports_reasoning` flag. Those are documented in-place. Tests: 537 anthropic/bedrock/databricks/vertex/messages tests pass. Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com>
This commit is contained in:
@@ -920,9 +920,7 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
||||
"""
|
||||
if reasoning_effort is None or reasoning_effort == "none":
|
||||
return None
|
||||
if AnthropicConfig._is_claude_4_6_model(
|
||||
model
|
||||
) or AnthropicConfig._is_claude_4_7_model(model):
|
||||
if AnthropicConfig._is_adaptive_thinking_model(model):
|
||||
return AnthropicThinkingParam(
|
||||
type="adaptive",
|
||||
)
|
||||
@@ -1262,11 +1260,12 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
||||
optional_params.pop("output_config", None)
|
||||
else:
|
||||
optional_params["thinking"] = mapped_thinking
|
||||
# For Claude 4.6+ models, effort is controlled via output_config,
|
||||
# not thinking budget_tokens. Map reasoning_effort to output_config.
|
||||
if AnthropicConfig._is_claude_4_6_model(
|
||||
model
|
||||
) or AnthropicConfig._is_claude_4_7_model(model):
|
||||
# For Claude 4.6+ adaptive-thinking models, effort is
|
||||
# controlled via ``output_config``, not
|
||||
# ``thinking.budget_tokens``. Driven by
|
||||
# ``supports_adaptive_thinking`` in the model map so
|
||||
# adding a new adaptive Claude is a model-map-only change.
|
||||
if AnthropicConfig._is_adaptive_thinking_model(model):
|
||||
# ``_map_reasoning_effort`` returns ``type=adaptive``
|
||||
# for any string on adaptive models without checking
|
||||
# the value, so reject unmapped efforts here (matching
|
||||
|
||||
@@ -273,7 +273,26 @@ class AnthropicModelInfo(BaseLLMModelInfo):
|
||||
|
||||
@staticmethod
|
||||
def _is_adaptive_thinking_model(model: str) -> bool:
|
||||
"""Claude 4.6+ models use adaptive thinking with output_config effort."""
|
||||
"""Claude 4.6+ models use adaptive thinking with ``output_config.effort``.
|
||||
|
||||
Driven by the ``supports_adaptive_thinking`` flag in
|
||||
``model_prices_and_context_window.json`` so that adding a new
|
||||
adaptive-thinking model is a pure model-map change. Falls back to
|
||||
the family-pattern check for OpenRouter / Vercel / Bedrock /
|
||||
provider-prefixed variants whose model-map entries don't (yet)
|
||||
carry the flag.
|
||||
"""
|
||||
from litellm.utils import _supports_factory
|
||||
|
||||
try:
|
||||
if _supports_factory(
|
||||
model=model,
|
||||
custom_llm_provider=None,
|
||||
key="supports_adaptive_thinking",
|
||||
):
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
return AnthropicModelInfo._is_claude_4_6_model(
|
||||
model
|
||||
) or AnthropicModelInfo._is_claude_4_7_model(model)
|
||||
|
||||
@@ -478,14 +478,15 @@ class AmazonConverseConfig(BaseConfig):
|
||||
optional_params.pop("output_config", None)
|
||||
else:
|
||||
optional_params["thinking"] = mapped_thinking
|
||||
# Adaptive-thinking models (Claude 4.6 / 4.7) take the tier
|
||||
# via output_config.effort. Mirror the mapping used by
|
||||
# AnthropicConfig.map_openai_params and apply the same
|
||||
# validation rules so unmapped/garbage efforts surface as a
|
||||
# 400 instead of being silently flattened on the wire.
|
||||
if AnthropicConfig._is_claude_4_6_model(
|
||||
model
|
||||
) or AnthropicConfig._is_claude_4_7_model(model):
|
||||
# Adaptive-thinking models (Claude 4.6 / 4.7+) take the
|
||||
# tier via ``output_config.effort``. Mirror the mapping
|
||||
# used by ``AnthropicConfig.map_openai_params`` and apply
|
||||
# the same validation rules so unmapped/garbage efforts
|
||||
# surface as a 400 instead of being silently flattened on
|
||||
# the wire. Driven by ``supports_adaptive_thinking`` in
|
||||
# ``model_prices_and_context_window.json`` so a future
|
||||
# adaptive Claude release lands as a model-map change.
|
||||
if AnthropicConfig._is_adaptive_thinking_model(model):
|
||||
# Use ``.get()`` without a fallback so unmapped efforts
|
||||
# (e.g. ``"disabled"``) surface as a clean 400 here
|
||||
# rather than leaking the raw garbage string through to
|
||||
|
||||
@@ -350,15 +350,17 @@ class DatabricksConfig(DatabricksBase, OpenAILikeChatConfig, AnthropicConfig):
|
||||
optional_params.pop("output_config", None)
|
||||
else:
|
||||
optional_params["thinking"] = mapped_thinking
|
||||
# For Claude 4.6/4.7 adaptive models, ``_map_reasoning_effort``
|
||||
# For Claude 4.6+ adaptive models, ``_map_reasoning_effort``
|
||||
# returns ``type=adaptive`` for ANY non-None / non-"none"
|
||||
# string without validating the value, so reject unmapped
|
||||
# efforts here and set ``output_config.effort`` (matching the
|
||||
# Anthropic native / Bedrock Converse / Bedrock Invoke /
|
||||
# /v1/messages paths).
|
||||
if AnthropicConfig._is_claude_4_6_model(
|
||||
model
|
||||
) or AnthropicConfig._is_claude_4_7_model(model):
|
||||
# /v1/messages paths). Driven by ``supports_adaptive_thinking``
|
||||
# in the model map so future adaptive Claudes land via a
|
||||
# model-map update rather than a code release — the
|
||||
# Anthropic-native and Bedrock routes already use the same
|
||||
# helper, so all three paths stay in lock-step.
|
||||
if AnthropicConfig._is_adaptive_thinking_model(model):
|
||||
# ``reasoning_effort_value`` comes from ``non_default_params``
|
||||
# so its static type is ``Any | None``. Narrow to ``str`` for
|
||||
# the mapping lookup; non-strings fall through to the
|
||||
|
||||
@@ -9228,6 +9228,7 @@
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_adaptive_thinking": true,
|
||||
"supports_assistant_prefill": true,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
@@ -9421,6 +9422,7 @@
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_adaptive_thinking": true,
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
@@ -9454,6 +9456,7 @@
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_adaptive_thinking": true,
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
@@ -9487,6 +9490,7 @@
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_adaptive_thinking": true,
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
@@ -9521,6 +9525,7 @@
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_adaptive_thinking": true,
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
|
||||
Reference in New Issue
Block a user