mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-15 09:12:18 +00:00
Merge 114b140118 into 527d882508
This commit is contained in:
commit
523c05af9a
12 changed files with 207 additions and 9 deletions
|
|
@ -2433,7 +2433,7 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
# Anthropic errors with: "When thinking is disabled, an assistant message cannot contain thinking"
|
||||
# Related issue: https://github.com/BerriAI/litellm/issues/18926
|
||||
if (
|
||||
optional_params.get("thinking") is not None
|
||||
optional_params.get("thinking") not in (None, {"type": "disabled"})
|
||||
and last_assistant_with_tool_calls_has_no_thinking_blocks(capped_messages)
|
||||
and not any_assistant_message_has_thinking_blocks(capped_messages)
|
||||
):
|
||||
|
|
|
|||
|
|
@ -84,6 +84,11 @@ DROP_DISABLED_THINKING_WARNING: Final = (
|
|||
"disabled (the alternative is a provider 400). The model will still think adaptively, its response can contain "
|
||||
"thinking blocks, and those thinking tokens are billed as output tokens."
|
||||
)
|
||||
REMAP_DISABLED_TO_BETWEEN_TOOLS_WARNING: Final = (
|
||||
"Replacing `thinking={'type': 'disabled'}` with `thinking={'type': 'between_tools'}` for model=%s: this model "
|
||||
"400s on `disabled`, and `between_tools` is its lowest thinking setting. The model will not think before "
|
||||
"responding; progress notes it writes between tool calls still come back as `thinking` blocks."
|
||||
)
|
||||
|
||||
# Anthropic error `type` (both the JSON error body and SSE `event: error`
|
||||
# payloads use this field) mapped to the HTTP status code it corresponds to.
|
||||
|
|
@ -1141,6 +1146,28 @@ class AnthropicModelInfo(BaseLLMModelInfo):
|
|||
"""
|
||||
return AnthropicModelInfo._supports_model_capability(model, "thinking_always_on", custom_llm_provider)
|
||||
|
||||
@staticmethod
|
||||
def _supports_between_tools_thinking(model: str, custom_llm_provider: str) -> bool:
|
||||
"""Whether ``model`` accepts ``thinking.type=between_tools`` as its off-equivalent
|
||||
setting for an always-on-thinking model. The model cost map is authoritative: an
|
||||
explicit ``supports_between_tools_thinking`` entry resolved under
|
||||
``custom_llm_provider``. Sonnet 5.5 is the only family with this entry today;
|
||||
other always-on-thinking families fall back to the drop-and-warn path in
|
||||
``maybe_drop_disabled_thinking`` until their own off-equivalent is confirmed.
|
||||
"""
|
||||
return AnthropicModelInfo._supports_model_capability(
|
||||
model, "supports_between_tools_thinking", custom_llm_provider
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _effort_rejects_between_tools(optional_params: Mapping[str, object]) -> bool:
|
||||
"""``thinking.type=between_tools`` 400s at ``xhigh``/``max`` effort; those levels
|
||||
keep adaptive thinking as their only valid off-equivalent."""
|
||||
output_config: Final = optional_params.get("output_config")
|
||||
if not isinstance(output_config, dict):
|
||||
return False
|
||||
return "effort" in output_config and output_config["effort"] in ("xhigh", "max")
|
||||
|
||||
@staticmethod
|
||||
def _supports_legacy_thinking(model: str, custom_llm_provider: str) -> bool:
|
||||
"""Whether ``model`` is an adaptive-thinking model that still accepts legacy
|
||||
|
|
@ -1157,14 +1184,24 @@ class AnthropicModelInfo(BaseLLMModelInfo):
|
|||
optional_params: MutableMapping[str, object], # mutable-ok: in-place out-param, as in _maybe_drop_speed_param
|
||||
custom_llm_provider: str,
|
||||
) -> None:
|
||||
"""Omit ``thinking={'type': 'disabled'}`` for always-on-thinking models
|
||||
(Fable 5 / Mythos 5), which 400 on it; omission is the API-documented
|
||||
remedy and yields the model's default adaptive thinking."""
|
||||
"""Replace ``thinking={'type': 'disabled'}`` for always-on-thinking models
|
||||
(Fable 5 / Mythos 5, Sonnet 5.5, Opus 5.5), which 400 on it. Sonnet 5.5 has a
|
||||
real off-equivalent, ``between_tools``, valid at `low`/`medium`/`high` effort;
|
||||
remap to that instead of silently leaving thinking on at whatever effort the
|
||||
caller set. Every other always-on-thinking family falls back to omitting
|
||||
``thinking``, the API-documented remedy, which yields the model's default
|
||||
adaptive thinking."""
|
||||
thinking: Final = optional_params.get("thinking")
|
||||
if not isinstance(thinking, dict) or thinking.get("type") != "disabled":
|
||||
return
|
||||
if not AnthropicModelInfo._is_always_on_thinking_model(model, custom_llm_provider):
|
||||
return
|
||||
if AnthropicModelInfo._supports_between_tools_thinking(
|
||||
model, custom_llm_provider
|
||||
) and not AnthropicModelInfo._effort_rejects_between_tools(optional_params):
|
||||
litellm.verbose_logger.warning(REMAP_DISABLED_TO_BETWEEN_TOOLS_WARNING, model)
|
||||
optional_params["thinking"] = {"type": "between_tools"} # rebind-ok: in-place out-param, see signature
|
||||
return
|
||||
litellm.verbose_logger.warning(
|
||||
DROP_DISABLED_THINKING_WARNING,
|
||||
model,
|
||||
|
|
|
|||
|
|
@ -2133,7 +2133,7 @@ class AmazonConverseConfig(BaseConfig):
|
|||
# If any message has thinking_blocks, we must keep thinking enabled, otherwise
|
||||
# Related issues: https://github.com/BerriAI/litellm/issues/14194
|
||||
if (
|
||||
optional_params.get("thinking") is not None
|
||||
optional_params.get("thinking") not in (None, {"type": "disabled"})
|
||||
and messages is not None
|
||||
and last_assistant_with_tool_calls_has_no_thinking_blocks(messages)
|
||||
and not any_assistant_message_has_thinking_blocks(messages)
|
||||
|
|
|
|||
|
|
@ -16516,6 +16516,7 @@
|
|||
"supports_output_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://platform.claude.com/docs/en/about-claude/pricing",
|
||||
"supports_web_search": true
|
||||
|
|
@ -61897,6 +61898,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -69801,6 +69803,7 @@
|
|||
"output_cost_per_token": 1.2e-05,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"supports_adaptive_thinking": true,
|
||||
"supports_assistant_prefill": false,
|
||||
|
|
@ -75371,6 +75374,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75402,6 +75406,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"cache_creation_input_token_cost_above_1hr": 4.4e-06,
|
||||
"cache_creation_input_token_cost": 2.75e-06,
|
||||
|
|
@ -75453,6 +75458,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75488,6 +75494,7 @@
|
|||
"supports_max_reasoning_effort": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://management.azure.com/subscriptions/c873328e-b572-4770-8dff-aaeb6f1f0e79/providers/Microsoft.CognitiveServices/locations/eastus2/models?api-version=2024-10-01"
|
||||
},
|
||||
|
|
@ -75506,6 +75513,7 @@
|
|||
"output_cost_per_token": 1.2e-05,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json",
|
||||
"supports_adaptive_thinking": true,
|
||||
|
|
@ -75542,6 +75550,7 @@
|
|||
"output_cost_per_token": 1.2e-05,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json",
|
||||
"supports_adaptive_thinking": true,
|
||||
|
|
@ -75606,6 +75615,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75652,6 +75662,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75693,6 +75704,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75803,6 +75815,7 @@
|
|||
"output_cost_per_token": 1.2e-05,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json",
|
||||
"supports_adaptive_thinking": true,
|
||||
|
|
@ -75872,6 +75885,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75911,6 +75925,7 @@
|
|||
"supports_max_reasoning_effort": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://cloud.google.com/gemini-enterprise-agent-platform/generative-ai/pricing"
|
||||
},
|
||||
|
|
@ -75950,6 +75965,7 @@
|
|||
"supports_max_reasoning_effort": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://cloud.google.com/gemini-enterprise-agent-platform/generative-ai/pricing"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -814,7 +814,7 @@ class AnthropicThinkingBlockBinding(TypedDict, total=False):
|
|||
|
||||
|
||||
class AnthropicThinkingParam(TypedDict, total=False):
|
||||
type: ReadOnly[Literal["enabled", "adaptive", "disabled"]]
|
||||
type: ReadOnly[Literal["enabled", "adaptive", "disabled", "between_tools"]]
|
||||
budget_tokens: int
|
||||
display: ReadOnly[Literal["summarized", "omitted", "updates"]]
|
||||
block_binding: ReadOnly[AnthropicThinkingBlockBinding]
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ class ProviderSpecificModelInfo(TypedDict, total=False):
|
|||
supports_adaptive_thinking: bool | None
|
||||
supports_legacy_thinking: ReadOnly[bool | None]
|
||||
thinking_always_on: ReadOnly[bool | None]
|
||||
supports_between_tools_thinking: ReadOnly[bool | None]
|
||||
supports_tool_search: bool | None
|
||||
supports_mid_conversation_system: bool | None
|
||||
supports_url_context: bool | None
|
||||
|
|
|
|||
|
|
@ -16516,6 +16516,7 @@
|
|||
"supports_output_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://platform.claude.com/docs/en/about-claude/pricing",
|
||||
"supports_web_search": true
|
||||
|
|
@ -61897,6 +61898,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -69801,6 +69803,7 @@
|
|||
"output_cost_per_token": 1.2e-05,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"supports_adaptive_thinking": true,
|
||||
"supports_assistant_prefill": false,
|
||||
|
|
@ -75371,6 +75374,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75402,6 +75406,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"cache_creation_input_token_cost_above_1hr": 4.4e-06,
|
||||
"cache_creation_input_token_cost": 2.75e-06,
|
||||
|
|
@ -75453,6 +75458,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75488,6 +75494,7 @@
|
|||
"supports_max_reasoning_effort": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://management.azure.com/subscriptions/c873328e-b572-4770-8dff-aaeb6f1f0e79/providers/Microsoft.CognitiveServices/locations/eastus2/models?api-version=2024-10-01"
|
||||
},
|
||||
|
|
@ -75506,6 +75513,7 @@
|
|||
"output_cost_per_token": 1.2e-05,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json",
|
||||
"supports_adaptive_thinking": true,
|
||||
|
|
@ -75542,6 +75550,7 @@
|
|||
"output_cost_per_token": 1.2e-05,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json",
|
||||
"supports_adaptive_thinking": true,
|
||||
|
|
@ -75606,6 +75615,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75652,6 +75662,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75693,6 +75704,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75803,6 +75815,7 @@
|
|||
"output_cost_per_token": 1.2e-05,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json",
|
||||
"supports_adaptive_thinking": true,
|
||||
|
|
@ -75872,6 +75885,7 @@
|
|||
"supports_parallel_tool_use_config": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrockFoundationModels/current/index.json"
|
||||
},
|
||||
|
|
@ -75911,6 +75925,7 @@
|
|||
"supports_max_reasoning_effort": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://cloud.google.com/gemini-enterprise-agent-platform/generative-ai/pricing"
|
||||
},
|
||||
|
|
@ -75950,6 +75965,7 @@
|
|||
"supports_max_reasoning_effort": true,
|
||||
"supports_forced_tool_use": false,
|
||||
"thinking_always_on": true,
|
||||
"supports_between_tools_thinking": true,
|
||||
"prompt_cache_min_tokens": 512,
|
||||
"source": "https://cloud.google.com/gemini-enterprise-agent-platform/generative-ai/pricing"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7487,6 +7487,32 @@ def test_chat_dummy_tool_result_for_an_orphaned_tool_call_replays_a_byte_identic
|
|||
assert requests[0]["messages"][2]["content"][0]["type"] == "tool_result"
|
||||
|
||||
|
||||
def test_disabled_thinking_on_sonnet_5_5_tool_result_turn_remaps_to_between_tools(local_model_cost_map, monkeypatch):
|
||||
monkeypatch.setattr(litellm, "modify_params", True)
|
||||
messages: Final = [
|
||||
{"role": "user", "content": "Look it up"},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": None,
|
||||
"tool_calls": [{"id": "call_1", "type": "function", "function": {"name": "lookup", "arguments": "{}"}}],
|
||||
},
|
||||
{"role": "tool", "tool_call_id": "call_1", "content": "found"},
|
||||
]
|
||||
tools: Final = [
|
||||
{"name": "lookup", "description": "Look something up", "input_schema": {"type": "object", "properties": {}}}
|
||||
]
|
||||
|
||||
request: Final = AnthropicConfig().transform_request(
|
||||
model="claude-sonnet-5-5",
|
||||
messages=messages,
|
||||
optional_params={"tools": tools, "thinking": {"type": "disabled"}},
|
||||
litellm_params={},
|
||||
headers={},
|
||||
)
|
||||
|
||||
assert request["thinking"] == {"type": "between_tools"}
|
||||
|
||||
|
||||
anthropic_chunk_list: Final = [
|
||||
{
|
||||
"type": "content_block_start",
|
||||
|
|
|
|||
|
|
@ -4540,6 +4540,59 @@ def test_tool_changes_beta_requires_system_tool_reference(role: str, content: ob
|
|||
assert ANTHROPIC_MID_CONVERSATION_TOOL_CHANGES_BETA_HEADER not in headers.get("anthropic-beta", "").split(",")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("effort", (None, "low", "medium", "high"))
|
||||
def test_maybe_drop_disabled_thinking_remaps_sonnet_5_5_to_between_tools(
|
||||
local_model_cost_map: None, effort: str | None
|
||||
) -> None:
|
||||
from litellm.llms.anthropic.common_utils import AnthropicModelInfo
|
||||
|
||||
optional_params: Final[dict[str, object]] = {"thinking": {"type": "disabled"}}
|
||||
if effort is not None:
|
||||
optional_params["output_config"] = {"effort": effort}
|
||||
|
||||
AnthropicModelInfo.maybe_drop_disabled_thinking(
|
||||
model="claude-sonnet-5-5",
|
||||
optional_params=optional_params,
|
||||
custom_llm_provider="anthropic",
|
||||
)
|
||||
|
||||
assert optional_params["thinking"] == {"type": "between_tools"}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("effort", ("xhigh", "max"))
|
||||
def test_maybe_drop_disabled_thinking_drops_for_sonnet_5_5_at_rejecting_effort(
|
||||
local_model_cost_map: None, effort: str
|
||||
) -> None:
|
||||
from litellm.llms.anthropic.common_utils import AnthropicModelInfo
|
||||
|
||||
optional_params: Final[dict[str, object]] = {
|
||||
"thinking": {"type": "disabled"},
|
||||
"output_config": {"effort": effort},
|
||||
}
|
||||
|
||||
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_maybe_drop_disabled_thinking_still_drops_for_opus_5_5(local_model_cost_map: None) -> None:
|
||||
from litellm.llms.anthropic.common_utils import AnthropicModelInfo
|
||||
|
||||
optional_params: Final[dict[str, object]] = {"thinking": {"type": "disabled"}}
|
||||
|
||||
AnthropicModelInfo.maybe_drop_disabled_thinking(
|
||||
model="claude-opus-5-5",
|
||||
optional_params=optional_params,
|
||||
custom_llm_provider="anthropic",
|
||||
)
|
||||
|
||||
assert "thinking" not in optional_params
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("tool_call_id", "provider_specific_fields", "rebuilt"),
|
||||
(
|
||||
|
|
|
|||
|
|
@ -8619,6 +8619,32 @@ def test_disabled_thinking_omitted_for_always_on_models_converse(local_model_cos
|
|||
assert additional.get("thinking") == {"type": "disabled"}
|
||||
|
||||
|
||||
def test_disabled_thinking_on_sonnet_5_5_tool_result_turn_remaps_to_between_tools_converse(
|
||||
local_model_cost_map, monkeypatch
|
||||
):
|
||||
monkeypatch.setattr(litellm, "modify_params", True)
|
||||
messages: Final = [
|
||||
{"role": "user", "content": "Look it up"},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": None,
|
||||
"tool_calls": [{"id": "call_1", "type": "function", "function": {"name": "lookup", "arguments": "{}"}}],
|
||||
},
|
||||
{"role": "tool", "tool_call_id": "call_1", "content": "found"},
|
||||
]
|
||||
tools: Final = [{"type": "function", "function": {"name": "lookup", "parameters": {"type": "object"}}}]
|
||||
|
||||
result: Final = AmazonConverseConfig()._transform_request(
|
||||
model="us.anthropic.claude-sonnet-5-5",
|
||||
messages=messages,
|
||||
optional_params={"maxTokens": 64, "tools": tools, "thinking": {"type": "disabled"}},
|
||||
litellm_params={},
|
||||
headers={},
|
||||
)
|
||||
|
||||
assert result.get("additionalModelRequestFields", {}).get("thinking") == {"type": "between_tools"}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"model",
|
||||
["anthropic.claude-fable-5-1", "us.anthropic.claude-fable-5-1"],
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@ populate ``litellm.anthropic_models`` at import, which is what lets a bare
|
|||
``anthropic/*`` wildcard deployment).
|
||||
|
||||
Sonnet 5.5 (``claude-sonnet-5-5``) is covered here too. It carries the same
|
||||
gen-5 profile but thinking cannot be turned off and forced tool use is not
|
||||
supported, same as Opus 5.5
|
||||
gen-5 profile, and forced tool use is not supported, same as Opus 5.5. Thinking
|
||||
cannot be turned off via ``thinking.type=disabled``, the Sonnet 5 shape; the
|
||||
off-equivalent is ``thinking.type=between_tools``, which ``maybe_drop_disabled_thinking``
|
||||
remaps a caller's ``disabled`` request to.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
|
@ -78,9 +80,29 @@ def test_sonnet_5_5_present_in_bundled_backup(model_name):
|
|||
)
|
||||
def test_sonnet_5_5_thinking_profile(local_model_cost_map, model, provider):
|
||||
"""Sonnet 5.5 has thinking always on with the adaptive thinking surface, and
|
||||
no forced tool use, same as Opus 5.5."""
|
||||
no forced tool use, same as Opus 5.5. Unlike the rest of that family, it also
|
||||
has a real off-equivalent for thinking: between_tools."""
|
||||
from litellm.llms.anthropic.common_utils import AnthropicModelInfo
|
||||
|
||||
assert AnthropicModelInfo.is_adaptive_thinking_model(model, provider) is True
|
||||
assert AnthropicModelInfo._is_always_on_thinking_model(model, provider) is True
|
||||
assert AnthropicModelInfo._supports_between_tools_thinking(model, provider) is True
|
||||
assert AnthropicModelInfo.forced_tool_use_unsupported(model.removeprefix("anthropic/")) is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("model", "provider"),
|
||||
[
|
||||
("claude-opus-5-5", "anthropic"),
|
||||
("claude-fable-5", "anthropic"),
|
||||
("claude-mythos-5", "anthropic"),
|
||||
],
|
||||
)
|
||||
def test_other_always_on_thinking_models_lack_between_tools(local_model_cost_map, model, provider):
|
||||
"""Sonnet 5.5 is the only always-on-thinking family with a confirmed
|
||||
between_tools off-equivalent today; the rest must keep falling back to the
|
||||
drop-and-warn path in maybe_drop_disabled_thinking."""
|
||||
from litellm.llms.anthropic.common_utils import AnthropicModelInfo
|
||||
|
||||
assert AnthropicModelInfo._is_always_on_thinking_model(model, provider) is True
|
||||
assert AnthropicModelInfo._supports_between_tools_thinking(model, provider) is False
|
||||
|
|
|
|||
|
|
@ -1243,6 +1243,7 @@ _COST_MAP_ROW_SCHEMA: Final = {
|
|||
"supports_anthropic_thinking_payload": {"type": "boolean"},
|
||||
"supports_legacy_thinking": {"type": "boolean"},
|
||||
"thinking_always_on": {"type": "boolean"},
|
||||
"supports_between_tools_thinking": {"type": "boolean"},
|
||||
"supports_mid_conversation_system": {"type": "boolean"},
|
||||
"supports_sampling_params": {"type": "boolean"},
|
||||
"supports_output_config": {"type": "boolean"},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue