mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-26 01:12:21 +00:00
fix(router): use .get() for 'hidden' and 'model' keys in dict-style model_group_alias entries
RouterModelGroupAliasItem is a TypedDict with required fields 'model'
and 'hidden', but TypedDict is a type-hint only — Python does not
validate or inject keys at runtime. Any user whose config omits the
'hidden' key (natural, since it is only needed to hide a group) gets a
plain dict without it:
model_group_alias:
'gpt-4-alias': {model: gpt-3.5-turbo} # no hidden key
This caused a KeyError on every request because:
- get_model_group_info() is called by set_response_headers on every
router completion (confirmed by source comment)
- get_model_list_from_model_alias() is called during Router.__init__
via set_model_list -> get_model_names
Both call sites used item['hidden'] and item['model'] directly.
Fix: switch to item.get('hidden') and item.get('model', '') in both
locations. item.get('hidden') returns None when the key is absent,
and None is not True, so the visibility logic is preserved correctly.
Adds regression test covering three cases:
- dict alias without 'hidden' key (no KeyError, returns info)
- dict alias with hidden=True (returns None)
- dict alias with hidden=False (returns info)
This commit is contained in:
parent
cf9b5e4fa7
commit
ee71d69db0
2 changed files with 54 additions and 4 deletions
|
|
@ -8697,10 +8697,10 @@ class Router:
|
|||
if isinstance(item, str):
|
||||
_router_model_group = item
|
||||
elif isinstance(item, dict):
|
||||
if item["hidden"] is True:
|
||||
if item.get("hidden") is True:
|
||||
return None
|
||||
else:
|
||||
_router_model_group = item["model"]
|
||||
_router_model_group = item.get("model", "")
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
@ -9299,10 +9299,10 @@ class Router:
|
|||
_router_model_name: str = model_value
|
||||
elif isinstance(model_value, dict):
|
||||
_model_value = RouterModelGroupAliasItem(**model_value) # type: ignore
|
||||
if _model_value["hidden"] is True:
|
||||
if _model_value.get("hidden") is True:
|
||||
continue
|
||||
else:
|
||||
_router_model_name = _model_value["model"]
|
||||
_router_model_name = _model_value.get("model", "")
|
||||
else:
|
||||
continue
|
||||
|
||||
|
|
|
|||
|
|
@ -977,6 +977,56 @@ def test_update_settings(model_list):
|
|||
assert router.allowed_fails == 20
|
||||
|
||||
|
||||
def test_get_model_group_info_alias_dict_without_hidden_key(model_list):
|
||||
"""Regression test: get_model_group_info must not raise KeyError when a
|
||||
dict-style model_group_alias entry omits the 'hidden' key.
|
||||
|
||||
RouterModelGroupAliasItem declares 'hidden: bool' as a TypedDict field, but
|
||||
TypedDict is a type-hint only — Python does NOT inject default values at
|
||||
runtime. Any user who writes:
|
||||
|
||||
model_group_alias:
|
||||
"gpt-4-alias": {"model": "gpt-3.5-turbo"}
|
||||
|
||||
gets a plain dict without 'hidden', causing item["hidden"] to raise
|
||||
KeyError on every request (via set_response_headers -> get_model_group_info).
|
||||
"""
|
||||
alias_model_list = list(model_list) + [
|
||||
{
|
||||
"model_name": "gpt-3.5-turbo",
|
||||
"litellm_params": {"model": "openai/gpt-3.5-turbo", "api_key": "sk-fake"},
|
||||
}
|
||||
]
|
||||
router = Router(
|
||||
model_list=alias_model_list,
|
||||
model_group_alias={
|
||||
"gpt-4-alias": {"model": "gpt-3.5-turbo"},
|
||||
},
|
||||
)
|
||||
|
||||
# Must not raise KeyError — 'hidden' key is absent from the alias dict
|
||||
result = router.get_model_group_info(model_group="gpt-4-alias")
|
||||
assert result is not None
|
||||
|
||||
# Alias with hidden=True must still return None
|
||||
router2 = Router(
|
||||
model_list=alias_model_list,
|
||||
model_group_alias={
|
||||
"secret-alias": {"model": "gpt-3.5-turbo", "hidden": True},
|
||||
},
|
||||
)
|
||||
assert router2.get_model_group_info(model_group="secret-alias") is None
|
||||
|
||||
# Alias with hidden=False (explicit) must return info
|
||||
router3 = Router(
|
||||
model_list=alias_model_list,
|
||||
model_group_alias={
|
||||
"visible-alias": {"model": "gpt-3.5-turbo", "hidden": False},
|
||||
},
|
||||
)
|
||||
assert router3.get_model_group_info(model_group="visible-alias") is not None
|
||||
|
||||
|
||||
def test_common_checks_available_deployment(model_list):
|
||||
"""Test if the 'common_checks_available_deployment' function is working correctly"""
|
||||
router = Router(model_list=model_list)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue