From 1ccc3382d9c6c0233845949c196239cc192a5014 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Fri, 10 Jul 2026 21:00:33 -0700 Subject: [PATCH] feat(fallback-generalizations): widen adaptive-thinking gate to any claude family at major 5+ --- ...odel_prices_and_context_window_backup.json | 4 +-- model_prices_and_context_window.json | 4 +-- .../test_fallback_generalizations.py | 29 ++++++++++++++++--- .../anthropic/test_anthropic_common_utils.py | 23 ++++++++------- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index c483b3288e2..868ba5c43e3 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -45088,8 +45088,8 @@ }, { "name": "claude-adaptive-thinking", - "pattern": "(?:opus|sonnet|haiku)[-._](?:4[-._](?:[6-9]|[1-9]\\d)(?!\\d)|(?:[5-9]|[1-9]\\d{1,})[-._]\\d{1,2}(?!\\d))", - "description": "Claude opus/sonnet/haiku at version 4.6 or higher: 4.6 through 4.99, then any 5.x, 6.x or later major. The minor is capped at two digits so an 8-digit date suffix such as claude-opus-4-20250514 is never read as a >= 4.6 minor. Turns on adaptive thinking for new versions with no code change.", + "pattern": "(?:opus|sonnet|haiku)[-._](?:4[-._](?:[6-9]|[1-9]\\d)(?!\\d)|(?:[5-9]|[1-9]\\d{1,})[-._]\\d{1,2}(?!\\d))|claude-[a-z]+-(?:[5-9]|[1-9]\\d)(?!\\d)(?:[-._]\\d{1,2}(?!\\d))?", + "description": "Claude opus/sonnet/haiku at version 4.6 or higher (4.6 through 4.99, then any later major-minor), plus any claude-- id at major version 5 or higher, bare major or major-minor, so a new family shaped like claude-fable-5 is covered by the same gate as the core families. 4.x coverage stays limited to opus/sonnet/haiku. The minor is capped at two digits so an 8-digit date suffix such as claude-opus-4-20250514 is never read as a >= 4.6 minor. Turns on adaptive thinking for new versions and new families with no code change.", "model_info": { "supports_adaptive_thinking": true } diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index ee0b1193990..37ce3d270c8 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -45321,8 +45321,8 @@ }, { "name": "claude-adaptive-thinking", - "pattern": "(?:opus|sonnet|haiku)[-._](?:4[-._](?:[6-9]|[1-9]\\d)(?!\\d)|(?:[5-9]|[1-9]\\d{1,})[-._]\\d{1,2}(?!\\d))", - "description": "Claude opus/sonnet/haiku at version 4.6 or higher: 4.6 through 4.99, then any 5.x, 6.x or later major. The minor is capped at two digits so an 8-digit date suffix such as claude-opus-4-20250514 is never read as a >= 4.6 minor. Turns on adaptive thinking for new versions with no code change.", + "pattern": "(?:opus|sonnet|haiku)[-._](?:4[-._](?:[6-9]|[1-9]\\d)(?!\\d)|(?:[5-9]|[1-9]\\d{1,})[-._]\\d{1,2}(?!\\d))|claude-[a-z]+-(?:[5-9]|[1-9]\\d)(?!\\d)(?:[-._]\\d{1,2}(?!\\d))?", + "description": "Claude opus/sonnet/haiku at version 4.6 or higher (4.6 through 4.99, then any later major-minor), plus any claude-- id at major version 5 or higher, bare major or major-minor, so a new family shaped like claude-fable-5 is covered by the same gate as the core families. 4.x coverage stays limited to opus/sonnet/haiku. The minor is capped at two digits so an 8-digit date suffix such as claude-opus-4-20250514 is never read as a >= 4.6 minor. Turns on adaptive thinking for new versions and new families with no code change.", "model_info": { "supports_adaptive_thinking": true } diff --git a/tests/test_litellm/litellm_core_utils/test_fallback_generalizations.py b/tests/test_litellm/litellm_core_utils/test_fallback_generalizations.py index b911a46443c..e4407b547cc 100644 --- a/tests/test_litellm/litellm_core_utils/test_fallback_generalizations.py +++ b/tests/test_litellm/litellm_core_utils/test_fallback_generalizations.py @@ -343,14 +343,35 @@ def test_shipped_version_boundaries(shipped_cost_map, model, provider, adaptive, assert info.get("supports_mid_conversation_system") is mid_conversation, model -def test_shipped_mid_conversation_rule_covers_new_families_like_fable(shipped_cost_map): - """The 4.8+ mid-conversation gate accepts bare 5+ majors, so a new family shaped - like claude-fable-5 is covered. The adaptive rule keeps its opus/sonnet/haiku - family list, so a fable-shaped id gets no adaptive flag from the rules.""" +def test_shipped_rules_cover_new_families_like_fable_at_5_plus(shipped_cost_map): + """Both version gates accept any claude-- id at major 5 or higher, bare + major or major-minor, so a new family shaped like claude-fable-5 gets adaptive + thinking and mid-conversation system support without a cost-map entry.""" model = "claude-fable-5-1" assert model not in litellm.model_cost info = litellm.get_model_info(model, custom_llm_provider="anthropic") assert info["supports_mid_conversation_system"] is True + assert info["supports_adaptive_thinking"] is True + assert info["supports_function_calling"] is True + + +def test_shipped_rules_flag_bare_5_plus_majors_of_any_family(shipped_cost_map): + """A bare 5+ major with no minor gets both flags at the rule level; the mapped + claude-fable-5 entry itself still resolves from the cost map, so this pins the + pattern via the capability union rather than get_model_info.""" + matched = match_capability_generalizations("claude-fable-5") + assert matched is not None + assert matched["supports_adaptive_thinking"] is True + assert matched["supports_mid_conversation_system"] is True + + +def test_shipped_adaptive_rule_keeps_4x_coverage_to_core_families(shipped_cost_map): + """The family-agnostic adaptive branch starts at major 5; a non-core family at + 4.x gets the 4.8+ mid-conversation flag and baseline caps but never adaptive.""" + model = "claude-newfam-4-9" + assert model not in litellm.model_cost + info = litellm.get_model_info(model, custom_llm_provider="anthropic") + assert info["supports_mid_conversation_system"] is True assert info.get("supports_adaptive_thinking") is None assert info["supports_function_calling"] is True diff --git a/tests/test_litellm/llms/anthropic/test_anthropic_common_utils.py b/tests/test_litellm/llms/anthropic/test_anthropic_common_utils.py index f7a234c8ae8..316f0d6ddf7 100644 --- a/tests/test_litellm/llms/anthropic/test_anthropic_common_utils.py +++ b/tests/test_litellm/llms/anthropic/test_anthropic_common_utils.py @@ -1649,17 +1649,18 @@ class TestClaudeOpus48AdaptiveThinking: @pytest.mark.parametrize( "model", [ - "us.anthropic.claude-fable-5-preview", - "claude-fable-5-preview", + "us.anthropic.claude-fable-preview", + "claude-fable-preview", ], ) def test_unmapped_aliases_without_parseable_version_stay_non_adaptive( self, local_model_cost_map, model ): """An alias absent from the map, not matched by any ``fallback_generalizations`` - rule, and without a parseable opus/sonnet/haiku >= 4.6 family version stays - non-adaptive. ``fable`` is outside the version-rule family set, so neither the - cost map nor the declarative rule marks it adaptive.""" + rule, and without any parseable family version stays non-adaptive. ``fable`` + without a major version matches neither the core-family 4.6+ gate nor the + family-agnostic 5+ gate, so neither the cost map nor the declarative rule marks + it adaptive.""" import litellm from litellm.llms.anthropic.common_utils import AnthropicModelInfo @@ -1676,16 +1677,18 @@ class TestClaudeOpus48AdaptiveThinking: "claude-opus-5-0", "claude-opus-4-10", "claude-opus-4-8-some-future-suffix", + "claude-fable-5-preview", + "us.anthropic.claude-fable-5-preview", ], ) def test_adaptive_thinking_version_fallback_for_unmapped_high_versions( self, local_model_cost_map, model ): - """Provider-prefixed or suffixed Claude names that resolve to no mapped entry and - are not matched by the anchored ``anthropic-claude`` pricing rule still resolve to - adaptive when their opus/sonnet/haiku family version is >= 4.6. The version gate is - the declarative ``anthropic-claude-adaptive-thinking`` rule, so 5.x, 6.x and any - later family are covered with no code change.""" + """Provider-prefixed or suffixed Claude names that resolve to no mapped entry + still resolve to adaptive when their opus/sonnet/haiku family version is >= 4.6 + or any family's major version is >= 5. The version gate is the declarative + ``claude-adaptive-thinking`` rule, so 5.x, 6.x and any later family are covered + with no code change.""" import litellm from litellm.llms.anthropic.common_utils import AnthropicModelInfo