diff --git a/litellm/anthropic_beta_headers_config.json b/litellm/anthropic_beta_headers_config.json index 662b62cf205..d02afe37569 100644 --- a/litellm/anthropic_beta_headers_config.json +++ b/litellm/anthropic_beta_headers_config.json @@ -72,7 +72,7 @@ "computer-use-2025-11-24": "computer-use-2025-11-24", "context-1m-2025-08-07": "context-1m-2025-08-07", "context-management-2025-06-27": null, - "effort-2025-11-24": null, + "effort-2025-11-24": "effort-2025-11-24", "fast-mode-2026-02-01": null, "files-api-2025-04-14": null, "fine-grained-tool-streaming-2025-05-14": null, @@ -103,7 +103,7 @@ "computer-use-2025-11-24": "computer-use-2025-11-24", "context-1m-2025-08-07": "context-1m-2025-08-07", "context-management-2025-06-27": null, - "effort-2025-11-24": null, + "effort-2025-11-24": "effort-2025-11-24", "fast-mode-2026-02-01": null, "files-api-2025-04-14": null, "fine-grained-tool-streaming-2025-05-14": null, diff --git a/litellm/constants.py b/litellm/constants.py index 7bf94971a39..7708ba8b69a 100644 --- a/litellm/constants.py +++ b/litellm/constants.py @@ -202,6 +202,23 @@ DEFAULT_REASONING_EFFORT_MEDIUM_THINKING_BUDGET = int( DEFAULT_REASONING_EFFORT_HIGH_THINKING_BUDGET = int( os.getenv("DEFAULT_REASONING_EFFORT_HIGH_THINKING_BUDGET", 4096) ) +# ``xhigh`` / ``max`` budget extrapolation for legacy ``thinking.budget_tokens`` +# models (Claude 4.5 series + haiku). Continues the 2× progression +# 1024 → 2048 → 4096 from the existing low/medium/high tiers. These tiers +# also exist as adaptive ``output_config.effort`` enum values on Claude 4.6+ +# / 4.7; this constant only governs the budget-tokens fallback for models +# that aren't on the adaptive path. Per +# https://platform.claude.com/docs/en/build-with-claude/effort the ``effort`` +# enum is gated by model, but the legacy ``budget_tokens`` knob accepts any +# integer up to the model's max_tokens — adopting #27051's mapping here lets +# ``reasoning_effort=xhigh|max`` Just Work as a unified OpenAI-format knob +# regardless of which Anthropic API surface implements it. +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 21edf01f829..9de89d8ad55 100644 --- a/litellm/llms/anthropic/chat/transformation.py +++ b/litellm/llms/anthropic/chat/transformation.py @@ -21,8 +21,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 @@ -869,7 +871,18 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): def _map_reasoning_effort( reasoning_effort: Optional[Union[REASONING_EFFORT, str]], model: str, + llm_provider: str = "anthropic", ) -> Optional[AnthropicThinkingParam]: + """Map an OpenAI-format ``reasoning_effort`` string to Anthropic's + ``thinking`` payload. + + Raises ``BadRequestError`` (clean 400) instead of ``ValueError`` (500) + on unmapped efforts so every caller — Anthropic native, Bedrock + Invoke/Converse, Databricks, Vertex Anthropic, Azure AI Anthropic, + and the experimental ``/v1/messages`` pass-through — surfaces a + consistent error to the user. Pass ``llm_provider`` so the + ``BadRequestError`` carries the right provider name in logs. + """ if reasoning_effort is None or reasoning_effort == "none": return None if AnthropicConfig._is_claude_4_6_model( @@ -893,6 +906,28 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): type="enabled", budget_tokens=DEFAULT_REASONING_EFFORT_HIGH_THINKING_BUDGET, ) + elif reasoning_effort == "xhigh": + # Continues the 2× progression of low/medium/high (1024/2048/4096). + # On adaptive models (Claude 4.6/4.7) the ``xhigh`` tier is + # already routed via ``output_config.effort=xhigh`` above; this + # branch only applies to budget-mode models (Claude 4.5 series + + # haiku) where the OpenAI-format ``reasoning_effort`` knob would + # otherwise 400 with ``Unmapped reasoning effort``. Keeps the + # cross-model UX uniform — ``reasoning_effort=xhigh`` Just Works + # regardless of which Anthropic API surface implements it. + return AnthropicThinkingParam( + type="enabled", + budget_tokens=DEFAULT_REASONING_EFFORT_XHIGH_THINKING_BUDGET, + ) + elif reasoning_effort == "max": + # Same rationale as ``xhigh`` above — ``max`` is the adaptive + # enum's top tier on Claude 4.6/4.7, but for budget-mode models + # we extend the 2× progression (8192 → 16384) so the OpenAI- + # format alias is usable on every Claude model. + return AnthropicThinkingParam( + type="enabled", + budget_tokens=DEFAULT_REASONING_EFFORT_MAX_THINKING_BUDGET, + ) elif reasoning_effort == "minimal": # Anthropic Messages API rejects ``budget_tokens < 1024`` with a # 400. Floor at the provider minimum so ``minimal`` is a usable @@ -906,7 +941,15 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): ), ) else: - raise ValueError(f"Unmapped reasoning effort: {reasoning_effort}") + raise litellm.exceptions.BadRequestError( + message=( + f"Unmapped reasoning effort: {reasoning_effort!r}. " + f"Must be one of: 'minimal', 'low', 'medium', 'high', " + f"'xhigh', 'max', 'none'." + ), + model=model, + llm_provider=llm_provider, + ) def _extract_json_schema_from_response_format( self, value: Optional[dict] @@ -1170,21 +1213,15 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): elif param == "thinking": optional_params["thinking"] = value elif param == "reasoning_effort" and isinstance(value, str): - # Wrap the ``ValueError`` ``_map_reasoning_effort`` raises on - # unmapped efforts (``disabled`` / ``invalid`` / ``""`` / - # ``xhigh``/``max`` on budget-mode Claude 4.5) into a clean - # 400 ``BadRequestError`` instead of letting it surface as - # 500. - try: - mapped_thinking = AnthropicConfig._map_reasoning_effort( - reasoning_effort=value, model=model - ) - except ValueError as e: - raise litellm.exceptions.BadRequestError( - message=str(e), - model=model, - llm_provider=self.custom_llm_provider or "anthropic", - ) + # ``_map_reasoning_effort`` raises ``BadRequestError`` (400) + # directly on unmapped efforts (``disabled`` / ``invalid`` / + # ``""`` / ``xhigh``/``max`` on budget-mode Claude 4.5) so + # we no longer need to wrap a ``ValueError`` here. + mapped_thinking = AnthropicConfig._map_reasoning_effort( + reasoning_effort=value, + model=model, + llm_provider=self.custom_llm_provider or "anthropic", + ) if mapped_thinking is None: optional_params.pop("thinking", None) optional_params.pop("output_config", None) @@ -1673,15 +1710,18 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): model=model, llm_provider=self.custom_llm_provider or "anthropic", ) - # ``max`` is for Opus 4.6+ output effort (not Sonnet 4.6, not Opus 4.5). - # Accept known Opus 4.6/4.7 id patterns and/or ``supports_max_reasoning_effort`` - # in the model map (same pattern as ``xhigh`` below). The hardcoded - # patterns cover OpenRouter/GitHub Copilot/Vercel variants that don't - # carry the model-map flag yet — keep both checks until those provider - # entries are fully populated. + # ``max`` is supported on Claude 4.6 (Opus + Sonnet) and Claude 4.7 + # adaptive-thinking models (per + # https://platform.claude.com/docs/en/build-with-claude/effort). + # Prefer the data-driven ``supports_max_reasoning_effort`` flag in + # ``model_prices_and_context_window.json`` so new variants only + # require a model-map update. Family-level ``_is_claude_4_6_model`` + # / ``_is_claude_4_7_model`` checks remain as a fallback for + # OpenRouter/GitHub Copilot/Vercel/Bedrock variants whose entries + # don't yet carry the flag. if effort == "max" and not ( - self._is_opus_4_6_model(model) - or self._is_opus_4_7_model(model) + self._is_claude_4_6_model(model) + or self._is_claude_4_7_model(model) or self._supports_effort_level(model, "max") ): raise litellm.exceptions.BadRequestError( diff --git a/litellm/llms/anthropic/experimental_pass_through/messages/transformation.py b/litellm/llms/anthropic/experimental_pass_through/messages/transformation.py index 98004f647ef..f756279877d 100644 --- a/litellm/llms/anthropic/experimental_pass_through/messages/transformation.py +++ b/litellm/llms/anthropic/experimental_pass_through/messages/transformation.py @@ -201,12 +201,18 @@ class AnthropicMessagesConfig(BaseAnthropicMessagesConfig): if not isinstance(reasoning_effort, str): return + # ``_map_reasoning_effort`` raises ``BadRequestError`` (400) directly + # on unmapped efforts. The /v1/messages pass-through surfaces errors + # as ``AnthropicError``; convert here so callers see a provider-shaped + # 400 rather than the LiteLLM-shaped one. + from litellm.exceptions import BadRequestError as _BadRequestError + try: mapped_thinking = AnthropicConfig._map_reasoning_effort( reasoning_effort=reasoning_effort, model=model ) - except ValueError as e: - raise AnthropicError(message=str(e), status_code=400) + except _BadRequestError as e: + raise AnthropicError(message=str(e.message), status_code=400) if mapped_thinking is None: optional_params.pop("thinking", None) @@ -238,9 +244,15 @@ class AnthropicMessagesConfig(BaseAnthropicMessagesConfig): # The chat completion path enforces this via # ``_apply_output_config``; mirror it here so /v1/messages # callers see a clean 400 instead of a provider-side error. + # ``max`` is supported on Claude 4.6 (Opus + Sonnet) and Claude + # 4.7 adaptive-thinking models. Prefer the data-driven + # ``supports_max_reasoning_effort`` flag in + # ``model_prices_and_context_window.json``; family-level checks + # are a fallback for variants whose entries don't yet carry the + # flag. if mapped_effort == "max" and not ( - AnthropicConfig._is_opus_4_6_model(model) - or AnthropicConfig._is_opus_4_7_model(model) + AnthropicConfig._is_claude_4_6_model(model) + or AnthropicConfig._is_claude_4_7_model(model) or AnthropicConfig._supports_effort_level(model, "max") ): raise AnthropicError( diff --git a/litellm/llms/bedrock/chat/converse_transformation.py b/litellm/llms/bedrock/chat/converse_transformation.py index f711e88df6e..14c7c3030c4 100644 --- a/litellm/llms/bedrock/chat/converse_transformation.py +++ b/litellm/llms/bedrock/chat/converse_transformation.py @@ -463,20 +463,16 @@ class AmazonConverseConfig(BaseConfig): optional_params.update(reasoning_config) else: # Anthropic and other models: convert to thinking parameter. - # Wrap the ``ValueError`` ``_map_reasoning_effort`` raises on - # unmapped efforts (``disabled`` / ``invalid`` / ``""`` / - # ``xhigh``/``max`` on budget-mode Claude 4.5) into a clean 400 - # ``BadRequestError`` instead of letting it surface as 500. - try: - mapped_thinking = AnthropicConfig._map_reasoning_effort( - reasoning_effort=reasoning_effort, model=model - ) - except ValueError as e: - raise litellm.exceptions.BadRequestError( - message=str(e), - model=model, - llm_provider="bedrock_converse", - ) + # ``_map_reasoning_effort`` raises ``BadRequestError`` (400) + # directly on unmapped efforts (``disabled`` / ``invalid`` / + # ``""`` / ``xhigh``/``max`` on budget-mode Claude 4.5); pass + # ``llm_provider="bedrock_converse"`` so the error carries the + # right provider name. + mapped_thinking = AnthropicConfig._map_reasoning_effort( + reasoning_effort=reasoning_effort, + model=model, + llm_provider="bedrock_converse", + ) if mapped_thinking is None: optional_params.pop("thinking", None) optional_params.pop("output_config", None) @@ -555,9 +551,15 @@ class AmazonConverseConfig(BaseConfig): model=model, llm_provider="bedrock_converse", ) + # ``max`` is supported on Claude 4.6 (Opus + Sonnet) and Claude 4.7 + # adaptive-thinking models. Prefer the data-driven + # ``supports_max_reasoning_effort`` flag in + # ``model_prices_and_context_window.json`` so new variants only + # require a model-map update; family-level checks remain a fallback + # for Bedrock model ids whose entries don't yet carry the flag. if effort == "max" and not ( - AnthropicConfig._is_opus_4_6_model(model) - or AnthropicConfig._is_opus_4_7_model(model) + AnthropicConfig._is_claude_4_6_model(model) + or AnthropicConfig._is_claude_4_7_model(model) or AmazonConverseConfig._supports_effort_level_on_bedrock(model, "max") ): raise litellm.exceptions.BadRequestError( @@ -1535,9 +1537,29 @@ class AmazonConverseConfig(BaseConfig): # Append pre-formatted tools (systemTool etc.) after transformation bedrock_tools.extend(pre_formatted_tools) + # Auto-attach the effort beta header for non-adaptive Anthropic + # models on Bedrock Converse (i.e. Opus 4.5). Claude 4.6/4.7 accept + # ``output_config.effort`` as a stable, GA feature with no beta + # header; Opus 4.5 still gates it behind ``effort-2025-11-24``. The + # check mirrors ``AnthropicModelInfo.is_effort_used`` (which returns + # False for adaptive models) so we don't double-flag adaptive routes. + base_model = BedrockModelInfo.get_base_model(model) + if base_model.startswith("anthropic"): + output_config = additional_request_params.get("output_config") + if ( + isinstance(output_config, dict) + and output_config.get("effort") is not None + and not AnthropicConfig._is_adaptive_thinking_model(model) + ): + from litellm.types.llms.anthropic import ( + ANTHROPIC_EFFORT_BETA_HEADER, + ) + + if ANTHROPIC_EFFORT_BETA_HEADER not in anthropic_beta_list: + anthropic_beta_list.append(ANTHROPIC_EFFORT_BETA_HEADER) + # Set anthropic_beta in additional_request_params if we have any beta features # ONLY apply to Anthropic/Claude models - other models (e.g., Qwen, Llama) don't support this field - base_model = BedrockModelInfo.get_base_model(model) if anthropic_beta_list and base_model.startswith("anthropic"): additional_request_params["anthropic_beta"] = anthropic_beta_list diff --git a/litellm/llms/databricks/chat/transformation.py b/litellm/llms/databricks/chat/transformation.py index c086d4ad755..8ac438bbf01 100644 --- a/litellm/llms/databricks/chat/transformation.py +++ b/litellm/llms/databricks/chat/transformation.py @@ -330,8 +330,15 @@ class DatabricksConfig(DatabricksBase, OpenAILikeChatConfig, AnthropicConfig): ) # unsupported for claude models - if json_schema -> convert to tool call if "reasoning_effort" in non_default_params and "claude" in model: + # ``_map_reasoning_effort`` raises ``BadRequestError`` (400) + # directly on unmapped efforts; pass ``llm_provider="databricks"`` + # so the surfaced error carries the correct provider name (the + # default is ``"anthropic"``, which would mislead users routing + # via Databricks Foundation Model APIs). optional_params["thinking"] = AnthropicConfig._map_reasoning_effort( - reasoning_effort=non_default_params.get("reasoning_effort"), model=model + reasoning_effort=non_default_params.get("reasoning_effort"), + model=model, + llm_provider="databricks", ) optional_params.pop("reasoning_effort", None) ## handle thinking tokens diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 392fafcfc2c..7946e2dceef 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -984,21 +984,6 @@ "tool_use_system_prompt_tokens": 159, "supports_native_structured_output": true }, - "anthropic.claude-mythos-preview": { - "input_cost_per_token": 0, - "output_cost_per_token": 0, - "litellm_provider": "bedrock", - "max_input_tokens": 1000000, - "max_output_tokens": 128000, - "max_tokens": 128000, - "mode": "chat", - "supports_function_calling": true, - "supports_vision": true, - "supports_prompt_caching": false, - "supports_reasoning": true, - "supports_minimal_reasoning_effort": true, - "supports_tool_choice": true - }, "anthropic.claude-opus-4-6-v1": { "cache_creation_input_token_cost": 6.25e-06, "cache_creation_input_token_cost_above_1hr": 1e-05, @@ -1178,6 +1163,21 @@ "supports_max_reasoning_effort": true, "supports_minimal_reasoning_effort": true }, + "anthropic.claude-mythos-preview": { + "input_cost_per_token": 0, + "output_cost_per_token": 0, + "litellm_provider": "bedrock", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supports_function_calling": true, + "supports_vision": true, + "supports_prompt_caching": false, + "supports_reasoning": true, + "supports_minimal_reasoning_effort": true, + "supports_tool_choice": true + }, "global.anthropic.claude-opus-4-7": { "cache_creation_input_token_cost": 6.25e-06, "cache_creation_input_token_cost_above_1hr": 1e-05, @@ -1323,6 +1323,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -1352,6 +1353,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -1381,6 +1383,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -1409,6 +1412,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -1437,6 +1441,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -2055,6 +2060,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -9229,6 +9235,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -9496,7 +9503,6 @@ "us": 1.1, "fast": 6.0 }, - "supports_max_reasoning_effort": true, "supports_minimal_reasoning_effort": true }, "claude-opus-4-7-20260416": { @@ -9531,7 +9537,6 @@ "us": 1.1, "fast": 6.0 }, - "supports_max_reasoning_effort": true, "supports_minimal_reasoning_effort": true }, "claude-sonnet-4-20250514": { @@ -15568,7 +15573,7 @@ "mode": "embedding", "output_cost_per_token": 0, "output_vector_size": 3072, - "source": "https://cloud.google.com/vertex-ai/generative-ai/pricing", + "source": "https://ai.google.dev/gemini-api/docs/embeddings#multimodal", "supports_multimodal": true, "uses_embed_content": true }, @@ -21164,7 +21169,7 @@ }, "gradient_ai/alibaba-qwen3-32b": { "litellm_provider": "gradient_ai", - "max_tokens": 2048, + "max_tokens": 40960, "mode": "chat", "supported_endpoints": [ "/v1/chat/completions" @@ -21172,7 +21177,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 131072, + "max_output_tokens": 40960 }, "gradient_ai/anthropic-claude-3-opus": { "input_cost_per_token": 1.5e-05, @@ -21186,7 +21193,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 200000, + "max_output_tokens": 1024 }, "gradient_ai/anthropic-claude-3.5-haiku": { "input_cost_per_token": 8e-07, @@ -21200,7 +21209,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 200000, + "max_output_tokens": 1024 }, "gradient_ai/anthropic-claude-3.5-sonnet": { "input_cost_per_token": 3e-06, @@ -21214,7 +21225,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 200000, + "max_output_tokens": 1024 }, "gradient_ai/anthropic-claude-3.7-sonnet": { "input_cost_per_token": 3e-06, @@ -21228,7 +21241,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 200000, + "max_output_tokens": 1024 }, "gradient_ai/deepseek-r1-distill-llama-70b": { "input_cost_per_token": 9.9e-07, @@ -21242,7 +21257,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 32768, + "max_output_tokens": 8000 }, "gradient_ai/llama3-8b-instruct": { "input_cost_per_token": 2e-07, @@ -21256,7 +21273,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 8192, + "max_output_tokens": 512 }, "gradient_ai/llama3.3-70b-instruct": { "input_cost_per_token": 6.5e-07, @@ -21270,7 +21289,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 128000, + "max_output_tokens": 2048 }, "gradient_ai/mistral-nemo-instruct-2407": { "input_cost_per_token": 3e-07, @@ -21284,7 +21305,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 128000, + "max_output_tokens": 512 }, "gradient_ai/openai-gpt-4o": { "litellm_provider": "gradient_ai", @@ -21296,7 +21319,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 128000, + "max_output_tokens": 16384 }, "gradient_ai/openai-gpt-4o-mini": { "litellm_provider": "gradient_ai", @@ -21308,7 +21333,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 128000, + "max_output_tokens": 16384 }, "gradient_ai/openai-o3": { "input_cost_per_token": 2e-06, @@ -21322,7 +21349,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 200000, + "max_output_tokens": 100000 }, "gradient_ai/openai-o3-mini": { "input_cost_per_token": 1.1e-06, @@ -21336,7 +21365,9 @@ "supported_modalities": [ "text" ], - "supports_tool_choice": false + "supports_tool_choice": false, + "max_input_tokens": 200000, + "max_output_tokens": 100000 }, "lemonade/Qwen3-Coder-30B-A3B-Instruct-GGUF": { "input_cost_per_token": 0, @@ -21636,11 +21667,13 @@ }, "heroku/claude-3-5-haiku": { "litellm_provider": "heroku", - "max_tokens": 4096, + "max_tokens": 8192, "mode": "chat", "supports_function_calling": true, "supports_system_messages": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 200000, + "max_output_tokens": 8192 }, "heroku/claude-3-5-sonnet-latest": { "litellm_provider": "heroku", @@ -21648,7 +21681,9 @@ "mode": "chat", "supports_function_calling": true, "supports_system_messages": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 200000, + "max_output_tokens": 8192 }, "heroku/claude-3-7-sonnet": { "litellm_provider": "heroku", @@ -21656,7 +21691,9 @@ "mode": "chat", "supports_function_calling": true, "supports_system_messages": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 200000, + "max_output_tokens": 8192 }, "heroku/claude-4-sonnet": { "litellm_provider": "heroku", @@ -21664,7 +21701,9 @@ "mode": "chat", "supports_function_calling": true, "supports_system_messages": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 200000, + "max_output_tokens": 8192 }, "high/1024-x-1024/gpt-image-1": { "input_cost_per_image": 0.167, @@ -22472,48 +22511,6 @@ "/v1/images/generations" ] }, - "luminous-base": { - "input_cost_per_token": 3e-05, - "litellm_provider": "aleph_alpha", - "max_tokens": 2048, - "mode": "completion", - "output_cost_per_token": 3.3e-05 - }, - "luminous-base-control": { - "input_cost_per_token": 3.75e-05, - "litellm_provider": "aleph_alpha", - "max_tokens": 2048, - "mode": "chat", - "output_cost_per_token": 4.125e-05 - }, - "luminous-extended": { - "input_cost_per_token": 4.5e-05, - "litellm_provider": "aleph_alpha", - "max_tokens": 2048, - "mode": "completion", - "output_cost_per_token": 4.95e-05 - }, - "luminous-extended-control": { - "input_cost_per_token": 5.625e-05, - "litellm_provider": "aleph_alpha", - "max_tokens": 2048, - "mode": "chat", - "output_cost_per_token": 6.1875e-05 - }, - "luminous-supreme": { - "input_cost_per_token": 0.000175, - "litellm_provider": "aleph_alpha", - "max_tokens": 2048, - "mode": "completion", - "output_cost_per_token": 0.0001925 - }, - "luminous-supreme-control": { - "input_cost_per_token": 0.00021875, - "litellm_provider": "aleph_alpha", - "max_tokens": 2048, - "mode": "chat", - "output_cost_per_token": 0.000240625 - }, "max-x-max/50-steps/stability.stable-diffusion-xl-v0": { "litellm_provider": "bedrock", "max_input_tokens": 77, @@ -25985,12 +25982,14 @@ "input_cost_per_image": 0.0004, "input_cost_per_token": 2.5e-07, "litellm_provider": "openrouter", - "max_tokens": 200000, + "max_tokens": 4096, "mode": "chat", "output_cost_per_token": 1.25e-06, "supports_function_calling": true, "supports_tool_choice": true, - "supports_vision": true + "supports_vision": true, + "max_input_tokens": 200000, + "max_output_tokens": 4096 }, "openrouter/anthropic/claude-3.5-sonnet": { "input_cost_per_token": 3e-06, @@ -26109,6 +26108,7 @@ "supports_function_calling": true, "supports_prompt_caching": true, "supports_reasoning": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 159, @@ -26149,6 +26149,7 @@ "supports_function_calling": true, "supports_prompt_caching": true, "supports_reasoning": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -26197,6 +26198,29 @@ "supports_vision": true, "tool_use_system_prompt_tokens": 346 }, + "openrouter/anthropic/claude-opus-4.7": { + "cache_creation_input_token_cost": 6.25e-06, + "cache_read_input_token_cost": 5e-07, + "input_cost_per_token": 5e-06, + "litellm_provider": "openrouter", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 2.5e-05, + "supports_assistant_prefill": false, + "supports_computer_use": true, + "supports_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_max_reasoning_effort": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true, + "tool_use_system_prompt_tokens": 346 + }, "openrouter/bytedance/ui-tars-1.5-7b": { "input_cost_per_token": 1e-07, "litellm_provider": "openrouter", @@ -26562,18 +26586,22 @@ "openrouter/mancer/weaver": { "input_cost_per_token": 5.625e-06, "litellm_provider": "openrouter", - "max_tokens": 8000, + "max_tokens": 2000, "mode": "chat", "output_cost_per_token": 5.625e-06, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 8000, + "max_output_tokens": 2000 }, "openrouter/meta-llama/llama-3-70b-instruct": { "input_cost_per_token": 5.9e-07, "litellm_provider": "openrouter", - "max_tokens": 8192, + "max_tokens": 8000, "mode": "chat", "output_cost_per_token": 7.9e-07, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 8192, + "max_output_tokens": 8000 }, "openrouter/minimax/minimax-m2": { "input_cost_per_token": 2.55e-07, @@ -26661,34 +26689,42 @@ "openrouter/mistralai/mistral-7b-instruct": { "input_cost_per_token": 1.3e-07, "litellm_provider": "openrouter", - "max_tokens": 8192, + "max_tokens": 8191, "mode": "chat", "output_cost_per_token": 1.3e-07, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 32768, + "max_output_tokens": 8191 }, "openrouter/mistralai/mistral-large": { "input_cost_per_token": 8e-06, "litellm_provider": "openrouter", - "max_tokens": 32000, + "max_tokens": 8191, "mode": "chat", "output_cost_per_token": 2.4e-05, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 128000, + "max_output_tokens": 8191 }, "openrouter/mistralai/mistral-small-3.1-24b-instruct": { "input_cost_per_token": 1e-07, "litellm_provider": "openrouter", - "max_tokens": 32000, + "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 3e-07, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 131072, + "max_output_tokens": 131072 }, "openrouter/mistralai/mistral-small-3.2-24b-instruct": { "input_cost_per_token": 1e-07, "litellm_provider": "openrouter", - "max_tokens": 32000, + "max_tokens": 128000, "mode": "chat", "output_cost_per_token": 3e-07, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 128000, + "max_output_tokens": 128000 }, "openrouter/mistralai/mixtral-8x22b-instruct": { "input_cost_per_token": 6.5e-07, @@ -26696,7 +26732,9 @@ "max_tokens": 65536, "mode": "chat", "output_cost_per_token": 6.5e-07, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 65536, + "max_output_tokens": 65536 }, "openrouter/moonshotai/kimi-k2.5": { "cache_read_input_token_cost": 1e-07, @@ -26716,26 +26754,32 @@ "openrouter/openai/gpt-3.5-turbo": { "input_cost_per_token": 1.5e-06, "litellm_provider": "openrouter", - "max_tokens": 4095, + "max_tokens": 4096, "mode": "chat", "output_cost_per_token": 2e-06, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 16385, + "max_output_tokens": 4096 }, "openrouter/openai/gpt-3.5-turbo-16k": { "input_cost_per_token": 3e-06, "litellm_provider": "openrouter", - "max_tokens": 16383, + "max_tokens": 4096, "mode": "chat", "output_cost_per_token": 4e-06, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 16385, + "max_output_tokens": 4096 }, "openrouter/openai/gpt-4": { "input_cost_per_token": 3e-05, "litellm_provider": "openrouter", - "max_tokens": 8192, + "max_tokens": 4096, "mode": "chat", "output_cost_per_token": 6e-05, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 8191, + "max_output_tokens": 4096 }, "openrouter/openai/gpt-4.1": { "cache_read_input_token_cost": 5e-07, @@ -27243,10 +27287,12 @@ "openrouter/undi95/remm-slerp-l2-13b": { "input_cost_per_token": 1.875e-06, "litellm_provider": "openrouter", - "max_tokens": 6144, + "max_tokens": 4096, "mode": "chat", "output_cost_per_token": 1.875e-06, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 6144, + "max_output_tokens": 4096 }, "openrouter/x-ai/grok-4": { "input_cost_per_token": 3e-06, @@ -29868,14 +29914,16 @@ "together_ai/deepseek-ai/DeepSeek-V3.1": { "input_cost_per_token": 6e-07, "litellm_provider": "together_ai", - "max_tokens": 128000, + "max_tokens": 16384, "mode": "chat", "output_cost_per_token": 1.7e-06, "source": "https://www.together.ai/models/deepseek-v3-1", "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_reasoning": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_input_tokens": 128000, + "max_output_tokens": 16384 }, "together_ai/meta-llama/Llama-3.2-3B-Instruct-Turbo": { "litellm_provider": "together_ai", @@ -32552,6 +32600,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -34456,6 +34505,7 @@ "output_cost_per_token": 1.5e-05, "source": "https://x.ai/api#pricing", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_response_schema": false, "supports_tool_choice": true, "supports_web_search": true @@ -34471,6 +34521,7 @@ "output_cost_per_token": 1.5e-05, "source": "https://x.ai/api#pricing", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_response_schema": false, "supports_tool_choice": true, "supports_web_search": true @@ -34486,6 +34537,7 @@ "output_cost_per_token": 2.5e-05, "source": "https://x.ai/api#pricing", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_response_schema": false, "supports_tool_choice": true, "supports_web_search": true @@ -34501,6 +34553,7 @@ "output_cost_per_token": 2.5e-05, "source": "https://x.ai/api#pricing", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_response_schema": false, "supports_tool_choice": true, "supports_web_search": true @@ -34516,6 +34569,7 @@ "output_cost_per_token": 1.5e-05, "source": "https://x.ai/api#pricing", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_response_schema": false, "supports_tool_choice": true, "supports_web_search": true @@ -34532,6 +34586,7 @@ "output_cost_per_token": 5e-07, "source": "https://x.ai/api#pricing", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": false, "supports_tool_choice": true, @@ -34549,6 +34604,7 @@ "output_cost_per_token": 5e-07, "source": "https://x.ai/api#pricing", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": false, "supports_tool_choice": true, @@ -34565,6 +34621,7 @@ "output_cost_per_token": 4e-06, "source": "https://x.ai/api#pricing", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": false, "supports_tool_choice": true, @@ -34581,6 +34638,7 @@ "output_cost_per_token": 4e-06, "source": "https://x.ai/api#pricing", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": false, "supports_tool_choice": true, @@ -34597,6 +34655,7 @@ "output_cost_per_token": 4e-06, "source": "https://x.ai/api#pricing", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": false, "supports_tool_choice": true, @@ -34613,6 +34672,7 @@ "output_cost_per_token": 5e-07, "source": "https://x.ai/api#pricing", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": false, "supports_tool_choice": true, @@ -34628,38 +34688,41 @@ "output_cost_per_token": 1.5e-05, "source": "https://docs.x.ai/docs/models", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_tool_choice": true, "supports_web_search": true }, "xai/grok-4-fast-reasoning": { + "cache_read_input_token_cost": 5e-08, + "input_cost_per_token": 2e-07, + "input_cost_per_token_above_128k_tokens": 4e-07, "litellm_provider": "xai", "max_input_tokens": 2000000.0, "max_output_tokens": 2000000.0, "max_tokens": 2000000.0, "mode": "chat", - "input_cost_per_token": 2e-07, - "input_cost_per_token_above_128k_tokens": 4e-07, "output_cost_per_token": 5e-07, "output_cost_per_token_above_128k_tokens": 1e-06, - "cache_read_input_token_cost": 5e-08, "source": "https://docs.x.ai/docs/models", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_tool_choice": true, "supports_web_search": true }, "xai/grok-4-fast-non-reasoning": { + "cache_read_input_token_cost": 5e-08, + "input_cost_per_token": 2e-07, + "input_cost_per_token_above_128k_tokens": 4e-07, "litellm_provider": "xai", "max_input_tokens": 2000000.0, "max_output_tokens": 2000000.0, - "cache_read_input_token_cost": 5e-08, "max_tokens": 2000000.0, "mode": "chat", - "input_cost_per_token": 2e-07, - "input_cost_per_token_above_128k_tokens": 4e-07, "output_cost_per_token": 5e-07, "output_cost_per_token_above_128k_tokens": 1e-06, "source": "https://docs.x.ai/docs/models", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_tool_choice": true, "supports_web_search": true }, @@ -34675,6 +34738,7 @@ "output_cost_per_token_above_128k_tokens": 3e-05, "source": "https://docs.x.ai/docs/models", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_tool_choice": true, "supports_web_search": true }, @@ -34690,6 +34754,7 @@ "output_cost_per_token_above_128k_tokens": 3e-05, "source": "https://docs.x.ai/docs/models", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_tool_choice": true, "supports_web_search": true }, @@ -34707,6 +34772,7 @@ "source": "https://docs.x.ai/docs/models/grok-4-1-fast-reasoning", "supports_audio_input": true, "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, "supports_tool_choice": true, @@ -34727,6 +34793,7 @@ "source": "https://docs.x.ai/docs/models/grok-4-1-fast-reasoning", "supports_audio_input": true, "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, "supports_tool_choice": true, @@ -34747,6 +34814,7 @@ "source": "https://docs.x.ai/docs/models/grok-4-1-fast-reasoning", "supports_audio_input": true, "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, "supports_tool_choice": true, @@ -34767,6 +34835,7 @@ "source": "https://docs.x.ai/docs/models/grok-4-1-fast-non-reasoning", "supports_audio_input": true, "supports_function_calling": true, + "supports_prompt_caching": true, "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, @@ -34786,6 +34855,7 @@ "source": "https://docs.x.ai/docs/models/grok-4-1-fast-non-reasoning", "supports_audio_input": true, "supports_function_calling": true, + "supports_prompt_caching": true, "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, @@ -34802,6 +34872,7 @@ "output_cost_per_token": 6e-06, "source": "https://docs.x.ai/docs/models", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true, @@ -34818,6 +34889,7 @@ "output_cost_per_token": 6e-06, "source": "https://docs.x.ai/docs/models", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true, @@ -34850,6 +34922,7 @@ "output_cost_per_token": 6e-06, "source": "https://docs.x.ai/docs/models", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_tool_choice": true, "supports_vision": true, "supports_web_search": true @@ -34878,6 +34951,7 @@ "output_cost_per_token": 1.5e-06, "source": "https://docs.x.ai/docs/models", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_tool_choice": true }, @@ -34892,6 +34966,7 @@ "output_cost_per_token": 1.5e-06, "source": "https://docs.x.ai/docs/models", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_tool_choice": true }, @@ -34906,6 +34981,7 @@ "output_cost_per_token": 1.5e-06, "source": "https://docs.x.ai/docs/models", "supports_function_calling": true, + "supports_prompt_caching": true, "supports_reasoning": true, "supports_tool_choice": true }, @@ -34937,6 +35013,20 @@ "supports_tool_choice": true, "source": "https://aws.amazon.com/bedrock/pricing/" }, + "zai.glm-5": { + "input_cost_per_token": 1e-06, + "litellm_provider": "bedrock_converse", + "max_input_tokens": 200000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 3.2e-06, + "supports_function_calling": true, + "supports_reasoning": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "source": "https://aws.amazon.com/bedrock/pricing/" + }, "zai.glm-4.7-flash": { "input_cost_per_token": 7e-08, "litellm_provider": "bedrock_converse", @@ -39522,6 +39612,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -39746,6 +39837,87 @@ } ] }, + "zai.glm-5": { + "input_cost_per_token": 1e-06, + "output_cost_per_token": 3.2e-06, + "litellm_provider": "bedrock_converse", + "max_input_tokens": 200000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "source": "https://aws.amazon.com/bedrock/pricing/" + }, + "bedrock/us-east-1/zai.glm-5": { + "input_cost_per_token": 1e-06, + "output_cost_per_token": 3.2e-06, + "litellm_provider": "bedrock", + "max_input_tokens": 200000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "source": "https://aws.amazon.com/bedrock/pricing/" + }, + "bedrock/us-west-2/zai.glm-5": { + "input_cost_per_token": 1e-06, + "output_cost_per_token": 3.2e-06, + "litellm_provider": "bedrock", + "max_input_tokens": 200000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "source": "https://aws.amazon.com/bedrock/pricing/" + }, + "minimax.minimax-m2.5": { + "input_cost_per_token": 3e-07, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "bedrock_converse", + "max_input_tokens": 1000000, + "max_output_tokens": 8192, + "max_tokens": 8192, + "mode": "chat", + "supports_function_calling": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "source": "https://aws.amazon.com/bedrock/pricing/" + }, + "bedrock/us-east-1/minimax.minimax-m2.5": { + "input_cost_per_token": 3e-07, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "bedrock", + "max_input_tokens": 1000000, + "max_output_tokens": 8192, + "max_tokens": 8192, + "mode": "chat", + "supports_function_calling": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "source": "https://aws.amazon.com/bedrock/pricing/" + }, + "bedrock/us-west-2/minimax.minimax-m2.5": { + "input_cost_per_token": 3e-07, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "bedrock", + "max_input_tokens": 1000000, + "max_output_tokens": 8192, + "max_tokens": 8192, + "mode": "chat", + "supports_function_calling": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "source": "https://aws.amazon.com/bedrock/pricing/" + }, "bedrock/us-gov-east-1/anthropic.claude-haiku-4-5-20251001-v1:0": { "cache_creation_input_token_cost": 1.5e-06, "cache_read_input_token_cost": 1.2e-07, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 03b13d743f6..7946e2dceef 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -1323,6 +1323,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -1352,6 +1353,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -1381,6 +1383,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -1409,6 +1412,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -1437,6 +1441,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -2055,6 +2060,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -9229,6 +9235,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -26101,6 +26108,7 @@ "supports_function_calling": true, "supports_prompt_caching": true, "supports_reasoning": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 159, @@ -26141,6 +26149,7 @@ "supports_function_calling": true, "supports_prompt_caching": true, "supports_reasoning": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -26206,6 +26215,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true, @@ -32590,6 +32600,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, @@ -39601,6 +39612,7 @@ "supports_prompt_caching": true, "supports_reasoning": true, "supports_response_schema": true, + "supports_max_reasoning_effort": true, "supports_tool_choice": true, "supports_vision": true, "tool_use_system_prompt_tokens": 346, 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 c496df429e8..1aa664f6574 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 @@ -2078,13 +2078,17 @@ def test_get_config_does_not_leak_module_constants(): ("claude-opus-4-7", "xhigh", True), ("claude-opus-4-6", "max", True), ("claude-opus-4-6", "xhigh", False), - ("claude-sonnet-4-6", "max", False), + # ``max`` is documented as supported on Sonnet 4.6 (Claude 4.6 family). + # The model-map JSON now carries ``supports_max_reasoning_effort: true`` + # for every Sonnet 4.6 entry; ``_supports_effort_level`` should report + # ``True`` on every route prefix (anthropic, bedrock, vertex, azure). + ("claude-sonnet-4-6", "max", True), ("claude-sonnet-4-6", "xhigh", False), ("bedrock/invoke/us.anthropic.claude-opus-4-7", "max", True), ("bedrock/invoke/us.anthropic.claude-opus-4-7", "xhigh", True), ("bedrock/invoke/us.anthropic.claude-opus-4-6-v1", "max", True), ("bedrock/invoke/us.anthropic.claude-opus-4-6-v1", "xhigh", False), - ("bedrock/invoke/us.anthropic.claude-sonnet-4-6", "max", False), + ("bedrock/invoke/us.anthropic.claude-sonnet-4-6", "max", True), ("vertex_ai/claude-opus-4-7", "xhigh", True), ("azure_ai/claude-opus-4-7", "xhigh", True), ], @@ -2393,25 +2397,40 @@ def test_reasoning_effort_does_not_set_output_config_for_older_models(): ), f"output_config should not be set for {model}" -def test_max_effort_rejected_for_sonnet_46(): - """Test that effort='max' is rejected for Sonnet 4.6 (Opus-only effort level). +@pytest.mark.parametrize( + "model", + [ + "claude-sonnet-4-6", + "claude-sonnet-4-6-20260219", + "us.anthropic.claude-sonnet-4-6", + "bedrock/converse/us.anthropic.claude-sonnet-4-6", + "vertex_ai/claude-sonnet-4-6", + "openrouter/anthropic/claude-sonnet-4.6", + ], +) +def test_max_effort_accepted_for_sonnet_46_variants(model): + """``effort='max'`` is documented as supported on Claude 4.6 (Opus + Sonnet) + and Claude 4.7 (https://platform.claude.com/docs/en/build-with-claude/effort). - Surfaces as a clean 400 BadRequestError, not a 500 ValueError. + Earlier versions of this test asserted a 400 for Sonnet 4.6, mirroring an + Opus-only allow-list in ``_apply_output_config``. That gate has since been + widened to ``_is_claude_4_6_model`` (Opus + Sonnet) and the + ``supports_max_reasoning_effort`` JSON flag, matching Anthropic's published + matrix. Verify the param actually flows through every Sonnet 4.6 id + variant our routing layer might see. """ config = AnthropicConfig() messages = [{"role": "user", "content": "Test"}] - with pytest.raises( - litellm.exceptions.BadRequestError, - match="effort='max' is not supported by this model", - ): - config.transform_request( - model="claude-sonnet-4-6-20260219", - messages=messages, - optional_params={"output_config": {"effort": "max"}}, - litellm_params={}, - headers={}, - ) + result = config.transform_request( + model=model, + messages=messages, + optional_params={"output_config": {"effort": "max"}}, + litellm_params={}, + headers={}, + ) + + assert result["output_config"]["effort"] == "max" def test_max_effort_accepted_for_opus_46(): @@ -2510,24 +2529,37 @@ def test_reasoning_effort_garbage_raises_bad_request(effort): @pytest.mark.parametrize( - "effort", - ["xhigh", "max"], + "effort,expected_budget", + [("xhigh", 8192), ("max", 16384)], ) -def test_reasoning_effort_unsupported_tier_on_budget_model_raises_bad_request( - effort, +def test_reasoning_effort_xhigh_max_maps_to_budget_on_budget_model( + effort, expected_budget ): - """``xhigh`` / ``max`` aren't defined for budget-mode (4.5) Claude models; - surface as a clean 400 instead of 500. + """``xhigh`` / ``max`` extend the legacy ``thinking.budget_tokens`` + progression (low=1024 / medium=2048 / high=4096 → xhigh=8192 / max=16384) + on budget-mode Claude models (haiku / 4.5 series). + + Adopted from #27051. Keeps the OpenAI-format ``reasoning_effort`` knob + usable across the full Claude lineup — adaptive models (4.6/4.7) route + these tiers via ``output_config.effort``; budget-mode models use the + extended budget. Anthropic's "max only on Mythos / Opus 4.7 / Opus 4.6 / + Sonnet 4.6" gating applies to the *adaptive enum*, not to the legacy + ``budget_tokens`` knob, which accepts any integer up to ``max_tokens``. """ config = AnthropicConfig() - with pytest.raises(litellm.exceptions.BadRequestError): - config.map_openai_params( - non_default_params={"reasoning_effort": effort}, - optional_params={}, - model="claude-sonnet-4-5-20250929", - drop_params=False, - ) + result = config.map_openai_params( + non_default_params={"reasoning_effort": effort}, + optional_params={}, + model="claude-sonnet-4-5-20250929", + drop_params=False, + ) + + assert result["thinking"]["type"] == "enabled" + assert result["thinking"]["budget_tokens"] == expected_budget + # Budget-mode models must NOT carry an ``output_config`` payload — that + # path is exclusively for adaptive (4.6+) models. + assert "output_config" not in result def test_output_config_effort_empty_string_raises_bad_request(): diff --git a/tests/test_litellm/llms/anthropic/experimental_pass_through/messages/test_reasoning_effort_translation.py b/tests/test_litellm/llms/anthropic/experimental_pass_through/messages/test_reasoning_effort_translation.py index 900bb15545a..20b5f958396 100644 --- a/tests/test_litellm/llms/anthropic/experimental_pass_through/messages/test_reasoning_effort_translation.py +++ b/tests/test_litellm/llms/anthropic/experimental_pass_through/messages/test_reasoning_effort_translation.py @@ -132,11 +132,11 @@ def test_invalid_reasoning_effort_raises_400(bad_effort): @pytest.mark.parametrize( "model,bad_effort", [ + # ``xhigh`` is Opus-4.7-only on the public Anthropic effort matrix, + # so Opus 4.6 / Sonnet 4.6 must still 400 on it. ("claude-opus-4-6", "xhigh"), ("bedrock/invoke/us.anthropic.claude-opus-4-6-v1", "xhigh"), ("claude-sonnet-4-6", "xhigh"), - ("claude-sonnet-4-6", "max"), - ("bedrock/invoke/us.anthropic.claude-sonnet-4-6", "max"), ], ) def test_reasoning_effort_unsupported_tier_raises_400_messages(model, bad_effort): @@ -160,6 +160,32 @@ def test_reasoning_effort_unsupported_tier_raises_400_messages(model, bad_effort assert "not supported by this model" in str(exc_info.value) +@pytest.mark.parametrize( + "model", + [ + # ``max`` is documented as supported on Claude 4.6 (Opus + Sonnet) + # and Claude 4.7. Verify the /v1/messages route accepts it for + # Sonnet 4.6 variants instead of 400-ing client-side. + "claude-sonnet-4-6", + "bedrock/invoke/us.anthropic.claude-sonnet-4-6", + ], +) +def test_reasoning_effort_max_accepted_on_sonnet_46_messages(model): + config = AnthropicMessagesConfig() + optional_params = {"max_tokens": 1024, "reasoning_effort": "max"} + + result = config.transform_anthropic_messages_request( + model=model, + messages=[{"role": "user", "content": "Hello"}], + anthropic_messages_optional_request_params=optional_params, + litellm_params={}, + headers={}, + ) + + output_config = result.get("output_config") + assert isinstance(output_config, dict) and output_config.get("effort") == "max" + + def test_explicit_output_config_wins_over_reasoning_effort(): """ Explicit native ``output_config.effort`` is never overridden by the diff --git a/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py b/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py index 9da7a046044..271498887f4 100644 --- a/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py +++ b/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py @@ -395,24 +395,39 @@ def test_reasoning_effort_garbage_raises_bad_request_converse(effort): ) -def test_output_config_effort_unsupported_max_on_sonnet_46_raises_bad_request(): - """``effort='max'`` is Opus-only. On Sonnet 4.6 the explicit-output_config - path must surface a 400 (matching the chat-completion validation), not - silently forward an unsupported tier to Bedrock.""" +@pytest.mark.parametrize( + "model", + [ + "bedrock/converse/us.anthropic.claude-sonnet-4-6", + "bedrock/converse/global.anthropic.claude-sonnet-4-6", + "bedrock/converse/eu.anthropic.claude-sonnet-4-6", + "bedrock/converse/au.anthropic.claude-sonnet-4-6", + ], +) +def test_output_config_effort_max_passes_through_on_sonnet_46_variants(model): + """``effort='max'`` is supported on Claude 4.6 (Opus + Sonnet) per + https://platform.claude.com/docs/en/build-with-claude/effort. The earlier + Opus-only allow-list in ``_validate_anthropic_adaptive_effort`` has been + widened to ``_is_claude_4_6_model`` (Opus + Sonnet) plus the + ``supports_max_reasoning_effort`` JSON flag. Verify the param actually + flows through to ``additionalModelRequestFields.output_config.effort`` + for every Bedrock Converse Sonnet 4.6 id variant.""" config = AmazonConverseConfig() messages = [{"role": "user", "content": "hi"}] - with pytest.raises(litellm.exceptions.BadRequestError): - config._transform_request( - model="bedrock/converse/us.anthropic.claude-sonnet-4-6", - messages=messages, - optional_params={ - "maxTokens": 256, - "output_config": {"effort": "max"}, - }, - litellm_params={}, - headers={}, - ) + result = config._transform_request( + model=model, + messages=messages, + optional_params={ + "maxTokens": 256, + "output_config": {"effort": "max"}, + }, + litellm_params={}, + headers={}, + ) + + additional = result.get("additionalModelRequestFields", {}) + assert additional.get("output_config") == {"effort": "max"} def test_get_supported_openai_params():