mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-05 07:37:50 +00:00
Merge 2b3cde3526 into e32d8a4d03
This commit is contained in:
commit
dbf5ee3734
3 changed files with 80 additions and 3 deletions
|
|
@ -376,6 +376,8 @@ def _build_anthropic_tool_name_maps(
|
|||
return forward, reverse
|
||||
|
||||
|
||||
_CLAUDE_MAJOR_VERSION: Final = re.compile(r"claude-[a-z]+-(\d+)")
|
||||
|
||||
REASONING_EFFORT_TO_OUTPUT_CONFIG_EFFORT: Final[dict[str, str]] = {
|
||||
"low": "low",
|
||||
"minimal": "low",
|
||||
|
|
@ -1565,7 +1567,23 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
llm_provider: str = "anthropic",
|
||||
) -> AnthropicThinkingParam | None:
|
||||
"""Capability probes read the cost map under ``custom_llm_provider``; ``llm_provider`` only tags raised exceptions."""
|
||||
if reasoning_effort is None or reasoning_effort == "none":
|
||||
if reasoning_effort is None:
|
||||
return None
|
||||
if reasoning_effort == "none":
|
||||
# An explicit "none" asks for thinking off. On Claude 5-generation
|
||||
# models that default thinking on (Opus 5, Sonnet 5, Haiku 5.5),
|
||||
# omission leaves the model's default in effect, so translate
|
||||
# "none" to thinking.type="disabled", which those models accept.
|
||||
# Models that default thinking off keep omission, which already
|
||||
# honors "none"; always-on-thinking models reject "disabled" and
|
||||
# are handled downstream by maybe_drop_disabled_thinking.
|
||||
major: Final = _CLAUDE_MAJOR_VERSION.search(model)
|
||||
if (
|
||||
major is not None
|
||||
and int(major.group(1)) >= 5
|
||||
and AnthropicConfig._is_adaptive_thinking_model(model, custom_llm_provider)
|
||||
):
|
||||
return AnthropicThinkingParam(type="disabled")
|
||||
return None
|
||||
if AnthropicConfig._is_adaptive_thinking_model(model, custom_llm_provider):
|
||||
# without display, Anthropic defaults adaptive thinking to
|
||||
|
|
@ -1962,7 +1980,10 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
optional_params.pop("output_config", None)
|
||||
else:
|
||||
optional_params["thinking"] = mapped_thinking
|
||||
if AnthropicConfig._is_adaptive_thinking_model(model, self._resolved_provider):
|
||||
# "none" disables thinking outright; there is no matching output_config effort.
|
||||
if effort_value != "none" and AnthropicConfig._is_adaptive_thinking_model(
|
||||
model, self._resolved_provider
|
||||
):
|
||||
mapped_effort = REASONING_EFFORT_TO_OUTPUT_CONFIG_EFFORT.get(effort_value)
|
||||
if mapped_effort is None:
|
||||
AnthropicConfig._raise_invalid_reasoning_effort(
|
||||
|
|
|
|||
|
|
@ -552,7 +552,8 @@ class AmazonConverseConfig(BaseConfig):
|
|||
optional_params.pop("output_config", None)
|
||||
else:
|
||||
optional_params["thinking"] = mapped_thinking
|
||||
if AnthropicConfig.is_adaptive_thinking_model(model, "bedrock"):
|
||||
# "none" disables thinking outright; there is no matching output_config effort.
|
||||
if reasoning_effort != "none" and AnthropicConfig.is_adaptive_thinking_model(model, "bedrock"):
|
||||
mapped_effort = REASONING_EFFORT_TO_OUTPUT_CONFIG_EFFORT.get(reasoning_effort)
|
||||
if mapped_effort is None:
|
||||
AnthropicConfig.raise_invalid_reasoning_effort(
|
||||
|
|
|
|||
|
|
@ -74,3 +74,58 @@ class TestMapReasoningEffort:
|
|||
reasoning_effort="none", model="claude-4-sonnet-20250514", custom_llm_provider="anthropic"
|
||||
)
|
||||
assert result is None
|
||||
|
||||
def test_none_string_returns_disabled_for_haiku_5_5(self):
|
||||
"""reasoning_effort='none' must explicitly disable thinking on Claude
|
||||
models that default thinking on (Haiku 5.5); omission leaves the
|
||||
model's default in effect."""
|
||||
result = AnthropicConfig.map_reasoning_effort(
|
||||
reasoning_effort="none", model="claude-haiku-5-5", custom_llm_provider="anthropic"
|
||||
)
|
||||
assert result == {"type": "disabled"}
|
||||
|
||||
def test_none_string_returns_disabled_for_opus_5(self):
|
||||
result = AnthropicConfig.map_reasoning_effort(
|
||||
reasoning_effort="none", model="claude-opus-5", custom_llm_provider="anthropic"
|
||||
)
|
||||
assert result == {"type": "disabled"}
|
||||
|
||||
def test_none_string_returns_disabled_for_always_on_model(self):
|
||||
"""Always-on models map to 'disabled' too; transform_request drops it
|
||||
via maybe_drop_disabled_thinking (the API-documented remedy)."""
|
||||
result = AnthropicConfig.map_reasoning_effort(
|
||||
reasoning_effort="none", model="claude-sonnet-5-5", custom_llm_provider="anthropic"
|
||||
)
|
||||
assert result == {"type": "disabled"}
|
||||
|
||||
def test_none_string_map_openai_params_sets_thinking_without_output_config(self):
|
||||
params = AnthropicConfig().map_openai_params(
|
||||
non_default_params={"reasoning_effort": "none"},
|
||||
optional_params={},
|
||||
model="claude-haiku-5-5",
|
||||
drop_params=False,
|
||||
)
|
||||
assert params.get("thinking") == {"type": "disabled"}
|
||||
assert "output_config" not in params
|
||||
|
||||
def test_disabled_thinking_dropped_for_always_on_model(self):
|
||||
from litellm.llms.anthropic.common_utils import AnthropicModelInfo
|
||||
|
||||
optional_params = {"thinking": {"type": "disabled"}}
|
||||
AnthropicModelInfo.maybe_drop_disabled_thinking(
|
||||
model="claude-sonnet-5-5",
|
||||
optional_params=optional_params,
|
||||
custom_llm_provider="anthropic",
|
||||
)
|
||||
assert "thinking" not in optional_params
|
||||
|
||||
def test_disabled_thinking_kept_for_haiku_5_5(self):
|
||||
from litellm.llms.anthropic.common_utils import AnthropicModelInfo
|
||||
|
||||
optional_params = {"thinking": {"type": "disabled"}}
|
||||
AnthropicModelInfo.maybe_drop_disabled_thinking(
|
||||
model="claude-haiku-5-5",
|
||||
optional_params=optional_params,
|
||||
custom_llm_provider="anthropic",
|
||||
)
|
||||
assert optional_params["thinking"] == {"type": "disabled"}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue