fix(auth): resolve model_group_alias before the zero-cost budget bypass check

This commit is contained in:
devin-ai-integration[bot] 2026-07-31 15:12:18 +00:00
parent 3c2264cfac
commit 901cfbd4bf
2 changed files with 60 additions and 2 deletions

View file

@ -187,7 +187,8 @@ def _is_model_cost_zero(model: Optional[Union[str, List[str]]], llm_router: Opti
continue
try:
# Use router's get_model_group_info method directly for better reliability
model_group_info = llm_router.get_model_group_info(model_group=model_name)
resolved_name = _resolve_model_group_alias(model_name, llm_router)
model_group_info = llm_router.get_model_group_info(model_group=resolved_name)
if model_group_info is None:
# Model not found or no pricing info available
@ -224,7 +225,7 @@ def _is_model_cost_zero(model: Optional[Union[str, List[str]]], llm_router: Opti
# not from defaulted sparse auto-registration entries.
# See: https://github.com/BerriAI/litellm/issues/24770
safe_name = str(model_name).replace("\n", "").replace("\r", "")
if not _is_cost_explicitly_configured(model_name, llm_router):
if not _is_cost_explicitly_configured(resolved_name, llm_router):
verbose_proxy_logger.debug(
"Model %s has zero cost but no explicit cost "
"configuration in model_cost entry — treating as unknown "
@ -253,6 +254,20 @@ def _is_model_cost_zero(model: Optional[Union[str, List[str]]], llm_router: Opti
return True
def _resolve_model_group_alias(model: str, llm_router: "Router") -> str:
"""
Map a user-facing ``model_group_alias`` name onto the model group it points at.
Returns ``model`` unchanged when it isn't an alias.
"""
item = llm_router.model_group_alias.get(model)
if isinstance(item, str):
return item
if isinstance(item, dict):
return item.get("model", model)
return model
def _is_cost_explicitly_configured(model: str, llm_router: "Router") -> bool:
"""
Check if any deployment in the model group has cost fields explicitly

View file

@ -162,6 +162,49 @@ class TestUnmappedModelBudgetEnforcement:
# Subsequent call sees the new pricing and enforces budget.
assert _is_model_cost_zero(model="ramping-model", llm_router=router) is False
def test_free_model_behind_model_group_alias_bypasses_budget(self):
"""
Regression test for https://github.com/BerriAI/litellm/issues/35369:
an alias pointing at an explicitly free model group must bypass budget
checks exactly like the underlying model group does.
"""
router = Router(
model_list=[
{
"model_name": "free-model",
"litellm_params": {
"model": "openai/nonexistent-but-free-model",
"api_key": "sk-fake",
"input_cost_per_token": 0.0,
"output_cost_per_token": 0.0,
},
},
],
model_group_alias={
"free-alias": "free-model",
"free-alias-hidden": {"model": "free-model", "hidden": True},
},
)
assert _is_model_cost_zero(model="free-model", llm_router=router) is True
assert _is_model_cost_zero(model="free-alias", llm_router=router) is True
assert _is_model_cost_zero(model="free-alias-hidden", llm_router=router) is True
def test_paid_model_behind_model_group_alias_enforces_budget(self):
"""An alias pointing at a paid model group must still enforce budget."""
router = Router(
model_list=[
{
"model_name": "paid-model",
"litellm_params": {
"model": "openai/gpt-4o-mini",
"api_key": "sk-fake",
},
},
],
model_group_alias={"paid-alias": "paid-model"},
)
assert _is_model_cost_zero(model="paid-alias", llm_router=router) is False
def test_handles_router_without_zero_cost_cache_attribute(self):
"""Tolerate router-like objects (e.g. ``MagicMock`` stand-ins) that
do not expose ``_zero_cost_cache`` the auth check must still