mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(utils): stop model registration from shadowing capability rules
Router writes every configured deployment into litellm.model_cost, and a deployment that declares no model_info lands there as an empty entry. An exact entry ends the model-info lookup ladder before the fallback generalizations are consulted, so that empty entry made the rules inert for the model: configuring one on a proxy stripped the capabilities the same model resolves to off-proxy. Seed a new registration from the capability rules its key matches. The caller's own model_info still wins field by field, so an explicit supports_reasoning: false on the deployment keeps overriding the rule. Claude-Session: https://claude.ai/code/session_01A6SkwJdfZUmkzfUkrEkqX8
This commit is contained in:
parent
033f2e5e2a
commit
7a1178a859
2 changed files with 50 additions and 1 deletions
|
|
@ -3108,7 +3108,10 @@ def register_model(
|
|||
existing_model = cast(dict, builtin_model_info)
|
||||
model_cost_key = existing_model["key"]
|
||||
else:
|
||||
existing_model = {}
|
||||
# An exact entry ends the lookup ladder before the capability rules are
|
||||
# consulted, so seed from them: otherwise registering an unmapped model
|
||||
# shadows the very defaults it would have resolved to unregistered.
|
||||
existing_model = dict(match_capability_generalizations(_key_str) or {}) # mutable-ok: merge target
|
||||
model_cost_key = key
|
||||
builtin_entry = _resolve_builtin_model_cost_entry(key=_key_str, provider=provider)
|
||||
if builtin_entry is not None:
|
||||
|
|
|
|||
|
|
@ -631,3 +631,49 @@ def test_shipped_wandb_rule_keeps_reasoning_effort_on_an_unmapped_model(shipped_
|
|||
drop_params=False,
|
||||
)
|
||||
assert optional_params["reasoning_effort"] == "medium"
|
||||
|
||||
|
||||
def test_router_registration_does_not_shadow_shipped_rules(shipped_cost_map):
|
||||
"""Regression: Router writes every configured deployment into ``litellm.model_cost``,
|
||||
and an exact entry ends the lookup ladder before the rules are consulted. Registering
|
||||
an unmapped model has to carry the rule defaults forward, or configuring a model on a
|
||||
proxy silently strips the capabilities the same model resolves to off-proxy."""
|
||||
from litellm import Router
|
||||
|
||||
unmapped_wandb = "wandb/zai-org/GLM-6-Turbo"
|
||||
unmapped_claude = "anthropic/claude-opus-9"
|
||||
assert unmapped_wandb not in litellm.model_cost
|
||||
assert unmapped_claude not in litellm.model_cost
|
||||
|
||||
Router(
|
||||
model_list=[
|
||||
{"model_name": name, "litellm_params": {"model": name, "api_key": "fake"}}
|
||||
for name in (unmapped_wandb, unmapped_claude)
|
||||
]
|
||||
)
|
||||
|
||||
assert unmapped_wandb in litellm.model_cost
|
||||
assert unmapped_claude in litellm.model_cost
|
||||
assert litellm.supports_reasoning(model="zai-org/GLM-6-Turbo", custom_llm_provider="wandb") is True
|
||||
assert litellm.supports_reasoning(model="claude-opus-9", custom_llm_provider="anthropic") is True
|
||||
|
||||
|
||||
def test_deployment_model_info_beats_the_seeded_rule_defaults(shipped_cost_map):
|
||||
"""Seeding a registration from the rules is a floor, not an override: an explicit
|
||||
model_info on the deployment still wins, so a non-reasoning model can be configured
|
||||
under a reasoning-first namespace."""
|
||||
from litellm import Router
|
||||
|
||||
model = "wandb/some-org/NoThink-1"
|
||||
Router(
|
||||
model_list=[
|
||||
{
|
||||
"model_name": model,
|
||||
"litellm_params": {"model": model, "api_key": "fake"},
|
||||
"model_info": {"supports_reasoning": False},
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
assert litellm.model_cost[model]["supports_reasoning"] is False
|
||||
assert litellm.supports_reasoning(model="some-org/NoThink-1", custom_llm_provider="wandb") is False
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue