mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-06 08:16:43 +00:00
fix(model_checks): drop wildcard routes like bedrock/* from /v1/models (#31731)
* fix: remove wildcard routes from /v1/models response Wildcard routes like bedrock/* were leaking into the /v1/models response because _get_wildcard_models only removed them from unique_models in the fallback branches (no router or no deployment), but not when the router had a matching deployment. Now wildcards are always removed from the base list; they are only re-added to the result when return_wildcard_routes=True is explicitly passed. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(model_checks): collapse wildcard expansion branches and tighten regression tests Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Krrish Dholakia <krrishdholakia@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: yassin <yassin@berri.ai>
This commit is contained in:
parent
4e18c0f63a
commit
7ae352e5cf
2 changed files with 88 additions and 21 deletions
|
|
@ -387,33 +387,22 @@ def _get_wildcard_models(
|
|||
all_wildcard_models: Final = []
|
||||
for model in unique_models:
|
||||
if _check_wildcard_routing(model=model):
|
||||
if return_wildcard_routes: # will add the wildcard route to the list eg: anthropic/*.
|
||||
if return_wildcard_routes:
|
||||
all_wildcard_models.append(model)
|
||||
|
||||
## get litellm params from model
|
||||
if llm_router is not None:
|
||||
model_list = llm_router.get_model_list(model_name=model, team_id=team_id)
|
||||
if model_list:
|
||||
for router_model in model_list:
|
||||
wildcard_models = get_known_models_from_wildcard(
|
||||
models_to_remove.add(model)
|
||||
|
||||
model_list = llm_router.get_model_list(model_name=model, team_id=team_id) if llm_router else None
|
||||
if model_list:
|
||||
for router_model in model_list:
|
||||
all_wildcard_models.extend(
|
||||
get_known_models_from_wildcard(
|
||||
wildcard_model=model,
|
||||
litellm_params=LiteLLM_Params(**router_model["litellm_params"]),
|
||||
)
|
||||
all_wildcard_models.extend(wildcard_models)
|
||||
else:
|
||||
# Router has no deployment for this wildcard (e.g., BYOK team models)
|
||||
# Fall back to expanding from known provider models
|
||||
wildcard_models = get_known_models_from_wildcard(wildcard_model=model, litellm_params=None)
|
||||
if wildcard_models:
|
||||
models_to_remove.add(model)
|
||||
all_wildcard_models.extend(wildcard_models)
|
||||
)
|
||||
else:
|
||||
# get all known provider models
|
||||
wildcard_models = get_known_models_from_wildcard(wildcard_model=model, litellm_params=None)
|
||||
|
||||
if wildcard_models:
|
||||
models_to_remove.add(model)
|
||||
all_wildcard_models.extend(wildcard_models)
|
||||
all_wildcard_models.extend(get_known_models_from_wildcard(wildcard_model=model, litellm_params=None))
|
||||
|
||||
for model in models_to_remove:
|
||||
unique_models.remove(model)
|
||||
|
|
|
|||
|
|
@ -754,6 +754,84 @@ def test_expand_wildcard_invalid_litellm_params_passthrough():
|
|||
assert result == [deployment]
|
||||
|
||||
|
||||
def test_get_complete_model_list_excludes_wildcard_routes_by_default():
|
||||
"""Regression (LIT-4108): a wildcard with a matching router deployment leaked into /v1/models."""
|
||||
from litellm import Router
|
||||
from litellm.proxy.auth.model_checks import get_complete_model_list
|
||||
|
||||
router = Router(
|
||||
model_list=[
|
||||
{
|
||||
"model_name": "bedrock/*",
|
||||
"litellm_params": {"model": "bedrock/*"},
|
||||
},
|
||||
{
|
||||
"model_name": "gpt-4",
|
||||
"litellm_params": {"model": "openai/gpt-4"},
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
result = get_complete_model_list(
|
||||
key_models=[],
|
||||
team_models=[],
|
||||
proxy_model_list=["bedrock/*", "gpt-4"],
|
||||
user_model=None,
|
||||
infer_model_from_keys=False,
|
||||
return_wildcard_routes=False,
|
||||
llm_router=router,
|
||||
)
|
||||
|
||||
assert "bedrock/*" not in result
|
||||
assert "gpt-4" in result
|
||||
assert any(m.startswith("bedrock/") for m in result)
|
||||
|
||||
|
||||
def test_get_complete_model_list_excludes_wildcard_routes_without_router():
|
||||
from litellm.proxy.auth.model_checks import get_complete_model_list
|
||||
|
||||
result = get_complete_model_list(
|
||||
key_models=[],
|
||||
team_models=[],
|
||||
proxy_model_list=["bedrock/*", "gpt-4"],
|
||||
user_model=None,
|
||||
infer_model_from_keys=False,
|
||||
return_wildcard_routes=False,
|
||||
llm_router=None,
|
||||
)
|
||||
|
||||
assert "bedrock/*" not in result
|
||||
assert "gpt-4" in result
|
||||
assert any(m.startswith("bedrock/") for m in result)
|
||||
|
||||
|
||||
def test_get_complete_model_list_includes_wildcard_routes_when_requested():
|
||||
from litellm import Router
|
||||
from litellm.proxy.auth.model_checks import get_complete_model_list
|
||||
|
||||
router = Router(
|
||||
model_list=[
|
||||
{
|
||||
"model_name": "bedrock/*",
|
||||
"litellm_params": {"model": "bedrock/*"},
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
result = get_complete_model_list(
|
||||
key_models=[],
|
||||
team_models=[],
|
||||
proxy_model_list=["bedrock/*"],
|
||||
user_model=None,
|
||||
infer_model_from_keys=False,
|
||||
return_wildcard_routes=True,
|
||||
llm_router=router,
|
||||
)
|
||||
|
||||
assert result.count("bedrock/*") == 1
|
||||
assert any(m.startswith("bedrock/") and m != "bedrock/*" for m in result)
|
||||
|
||||
|
||||
def test_add_known_models_refreshes_models_by_provider_for_wildcard_expansion():
|
||||
"""models_by_provider was a frozen import-time snapshot of set unions, so cost map
|
||||
reloads (which call add_known_models) never reached wildcard expansion until a
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue