mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-13 08:52:02 +00:00
Merge 566210b06e into 5103d8a0ee
This commit is contained in:
commit
bad30d8d16
12 changed files with 207 additions and 9 deletions
|
|
@ -2493,7 +2493,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)
|
||||
):
|
||||
|
|
|
|||
|
|
@ -102,6 +102,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.
|
||||
|
|
@ -1164,6 +1169,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 thinks_by_default(model: str, custom_llm_provider: str) -> bool:
|
||||
return AnthropicModelInfo._is_always_on_thinking_model(
|
||||
|
|
@ -1208,14 +1235,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,
|
||||
|
|
|
|||
|
|
@ -2166,7 +2166,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)
|
||||
|
|
|
|||
|
|
@ -16619,6 +16619,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
|
||||
|
|
@ -62197,6 +62198,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"
|
||||
},
|
||||
|
|
@ -70343,6 +70345,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,
|
||||
|
|
@ -75951,6 +75954,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"
|
||||
},
|
||||
|
|
@ -75982,6 +75986,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,
|
||||
|
|
@ -76033,6 +76038,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"
|
||||
},
|
||||
|
|
@ -76068,6 +76074,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"
|
||||
},
|
||||
|
|
@ -76086,6 +76093,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,
|
||||
|
|
@ -76122,6 +76130,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,
|
||||
|
|
@ -76186,6 +76195,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"
|
||||
},
|
||||
|
|
@ -76232,6 +76242,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"
|
||||
},
|
||||
|
|
@ -76273,6 +76284,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"
|
||||
},
|
||||
|
|
@ -76383,6 +76395,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,
|
||||
|
|
@ -76452,6 +76465,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"
|
||||
},
|
||||
|
|
@ -76491,6 +76505,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"
|
||||
},
|
||||
|
|
@ -76530,6 +76545,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"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -816,7 +816,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]
|
||||
|
|
|
|||
|
|
@ -225,6 +225,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]
|
||||
thinking_on_by_default: ReadOnly[bool | None]
|
||||
supports_tool_search: bool | None
|
||||
supports_per_turn_control: ReadOnly[bool | None]
|
||||
|
|
|
|||
|
|
@ -16619,6 +16619,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
|
||||
|
|
@ -62197,6 +62198,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"
|
||||
},
|
||||
|
|
@ -70343,6 +70345,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,
|
||||
|
|
@ -75951,6 +75954,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"
|
||||
},
|
||||
|
|
@ -75982,6 +75986,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,
|
||||
|
|
@ -76033,6 +76038,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"
|
||||
},
|
||||
|
|
@ -76068,6 +76074,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"
|
||||
},
|
||||
|
|
@ -76086,6 +76093,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,
|
||||
|
|
@ -76122,6 +76130,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,
|
||||
|
|
@ -76186,6 +76195,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"
|
||||
},
|
||||
|
|
@ -76232,6 +76242,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"
|
||||
},
|
||||
|
|
@ -76273,6 +76284,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"
|
||||
},
|
||||
|
|
@ -76383,6 +76395,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,
|
||||
|
|
@ -76452,6 +76465,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"
|
||||
},
|
||||
|
|
@ -76491,6 +76505,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"
|
||||
},
|
||||
|
|
@ -76530,6 +76545,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"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7776,6 +7776,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",
|
||||
|
|
|
|||
|
|
@ -4541,6 +4541,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"),
|
||||
(
|
||||
|
|
|
|||
|
|
@ -8808,6 +8808,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
|
||||
|
|
|
|||
|
|
@ -1246,6 +1246,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"},
|
||||
"thinking_on_by_default": {"type": "boolean"},
|
||||
"supports_mid_conversation_system": {"type": "boolean"},
|
||||
"supports_sampling_params": {"type": "boolean"},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue