mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-03 07:23:33 +00:00
fix: keep reasoning_effort xhigh on Gemini and suffixed Claude ids
Gemini has no thinking level above high, so xhigh was a 400. Claude ids with an effort suffix such as claude-sonnet-5-5-high now inherit the base model's xhigh flag.
This commit is contained in:
parent
d346d769f0
commit
ece58bbc2f
4 changed files with 31 additions and 3 deletions
|
|
@ -108,6 +108,7 @@ def anthropic_error_frame_exception(error_type: str, message: str, status_code:
|
|||
_BEDROCK_VERSION_SUFFIX_RE: Final = re.compile(r"-v\d+(?::\d+)?$")
|
||||
_INFERENCE_PROFILE_MINOR_RE: Final = re.compile(r":\d+$")
|
||||
_DATED_RELEASE_SUFFIX_RE: Final = re.compile(r"-\d{8}$")
|
||||
_EFFORT_ALIAS_SUFFIX_RE: Final = re.compile(r"-(?:minimal|low|medium|high|xhigh|max)$")
|
||||
_DOTTED_VERSION_RE: Final = re.compile(r"(\d)\.(\d)")
|
||||
_CLAUDE_CODE_BILLING_HEADER_PREFIX: Final = "x-anthropic-billing-header:"
|
||||
OBJECT_MAPPING_ADAPTER: Final = TypeAdapter(dict[object, object])
|
||||
|
|
@ -743,7 +744,9 @@ class AnthropicModelInfo(BaseLLMModelInfo):
|
|||
(``4.6`` -> ``4-6``). Lets any reasonable alias (e.g.
|
||||
``bedrock/invoke/global.anthropic.claude-opus-4-7-v1:0``,
|
||||
``claude-sonnet-4-6-20260219`` or ``claude-sonnet-4.6``) resolve to its base
|
||||
cost-map entry so the capability flag on that entry stays authoritative."""
|
||||
cost-map entry so the capability flag on that entry stays authoritative.
|
||||
A trailing effort alias (``-high``, ``-xhigh``) is tried the same way, so
|
||||
``claude-sonnet-5-5-high`` keeps the xhigh flag from ``claude-sonnet-5-5``."""
|
||||
prefixes: Final = (
|
||||
"bedrock/converse/",
|
||||
"bedrock/invoke/",
|
||||
|
|
@ -766,6 +769,7 @@ class AnthropicModelInfo(BaseLLMModelInfo):
|
|||
_BEDROCK_VERSION_SUFFIX_RE.sub("", cand),
|
||||
_INFERENCE_PROFILE_MINOR_RE.sub("", cand),
|
||||
_DATED_RELEASE_SUFFIX_RE.sub("", cand),
|
||||
_EFFORT_ALIAS_SUFFIX_RE.sub("", cand),
|
||||
_DOTTED_VERSION_RE.sub(r"\1-\2", cand),
|
||||
_strip_bedrock_id_suffixes(cand),
|
||||
AnthropicModelInfo._strip_version_suffix(cand),
|
||||
|
|
|
|||
|
|
@ -985,7 +985,8 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
|||
"thinkingBudget": DEFAULT_REASONING_EFFORT_MEDIUM_THINKING_BUDGET,
|
||||
"includeThoughts": sends_thoughts,
|
||||
}
|
||||
elif reasoning_effort == "high":
|
||||
elif reasoning_effort in ("high", "xhigh"):
|
||||
# Gemini has no thinking budget above high. OpenAI clients send xhigh.
|
||||
return {
|
||||
"thinkingBudget": DEFAULT_REASONING_EFFORT_HIGH_THINKING_BUDGET,
|
||||
"includeThoughts": sends_thoughts,
|
||||
|
|
@ -1037,7 +1038,8 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
|||
return {"thinkingLevel": "low", "includeThoughts": sends_thoughts}
|
||||
elif reasoning_effort == "medium":
|
||||
return {"thinkingLevel": "medium", "includeThoughts": sends_thoughts}
|
||||
elif reasoning_effort == "high":
|
||||
elif reasoning_effort in ("high", "xhigh"):
|
||||
# Gemini 3+ thinkingLevel tops out at high. Keep xhigh instead of 400.
|
||||
return {"thinkingLevel": "high", "includeThoughts": sends_thoughts}
|
||||
elif reasoning_effort in ("disable", "none"):
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -2640,6 +2640,12 @@ def test_supports_effort_level_handles_provider_prefixes(model, level, expected)
|
|||
assert AnthropicConfig._supports_effort_level(model, level, "anthropic") is expected
|
||||
|
||||
|
||||
def test_effort_alias_suffix_inherits_base_model_xhigh():
|
||||
"""``claude-sonnet-5-5-high`` is the same model as ``claude-sonnet-5-5``."""
|
||||
assert AnthropicConfig._supports_effort_level("claude-sonnet-5-5-high", "xhigh", "anthropic") is True
|
||||
assert AnthropicConfig.validate_effort_for_model("claude-sonnet-5-5-high", "xhigh", "anthropic") is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"model,effort,expect_error",
|
||||
[
|
||||
|
|
|
|||
|
|
@ -3285,6 +3285,22 @@ def test_reasoning_effort_maps_to_thinking_level_gemini_3():
|
|||
assert result["thinkingConfig"]["thinkingLevel"] == "high"
|
||||
assert result["thinkingConfig"]["includeThoughts"] is True
|
||||
|
||||
# xhigh has no Gemini thinkingLevel above high, so it uses that ceiling.
|
||||
optional_params = {}
|
||||
non_default_params = {"reasoning_effort": "xhigh"}
|
||||
result = v.map_openai_params(
|
||||
non_default_params=non_default_params,
|
||||
optional_params=optional_params,
|
||||
model=model,
|
||||
drop_params=False,
|
||||
)
|
||||
assert result["thinkingConfig"]["thinkingLevel"] == "high"
|
||||
assert result["thinkingConfig"]["includeThoughts"] is True
|
||||
assert (
|
||||
VertexGeminiConfig._map_reasoning_effort_to_thinking_budget("xhigh", "gemini-2.5-pro")
|
||||
== VertexGeminiConfig._map_reasoning_effort_to_thinking_budget("high", "gemini-2.5-pro")
|
||||
)
|
||||
|
||||
# Test disable -> low + includeThoughts=False (cannot fully disable in Gemini 3)
|
||||
optional_params = {}
|
||||
non_default_params = {"reasoning_effort": "disable"}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue