Merge pull request #41483 from BerriAI/litellm_v1_models_alias_metadata

fix(proxy): resolve model_group_alias to its target for /v1/models metadata
This commit is contained in:
Yassin Kortam 2026-09-18 15:22:02 -07:00 committed by GitHub
commit 5f83d97669
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 4 deletions

View file

@ -195,6 +195,7 @@ from litellm.repositories.user_repository import UserRepository
from litellm.repositories.verification_token_repository import (
VerificationTokenRepository,
)
from litellm.router_utils.common_utils import resolve_model_group_alias
from litellm.secret_managers.main import str_to_bool
from litellm.types.integrations.slack_alerting import DEFAULT_ALERT_TYPES
from litellm.types.llms.openai import ResponsesAPIResponse
@ -8206,18 +8207,23 @@ def create_model_info_response(
"owned_by": provider,
}
listing_info: Final = llm_router.get_model_listing_info(model_id) if llm_router is not None else None
alias_target: Final = (
resolve_model_group_alias(llm_router.model_group_alias, model_id) if llm_router is not None else None
)
lookup_model: Final = alias_target if alias_target is not None else model_id
listing_info: Final = llm_router.get_model_listing_info(lookup_model) if llm_router is not None else None
# One entry per distinct model behind the listed name; (None,) when the router knows
# nothing about it, so the listed name is resolved on its own as before.
deployment_models: Final[tuple[str | None, ...]] = (
listing_info.cost_map_keys if listing_info is not None and listing_info.cost_map_keys else (None,)
)
listed_info: Final = _safe_get_model_info(model_id, get_model_info)
listed_info: Final = _safe_get_model_info(lookup_model, get_model_info)
candidate_sets: Final = tuple(
_resolve_listing_model_info(
deployment_model=deployment_model,
listed_model=model_id,
listed_model=lookup_model,
listed_info=listed_info,
get_model_info=get_model_info,
)
@ -8248,7 +8254,7 @@ def create_model_info_response(
max_output_tokens = listing_info.max_output_tokens
if llm_router is not None:
configured_mode: Final = llm_router.get_configured_mode(model_id)
configured_mode: Final = llm_router.get_configured_mode(lookup_model)
if isinstance(configured_mode, str):
base["mode"] = configured_mode

View file

@ -2177,6 +2177,41 @@ def test_create_model_info_response_resolves_mode_through_deployment_model():
assert response["mode"] == "embedding"
@pytest.mark.parametrize(
"model_group_alias",
[
{"team-embeddings": "my-embeddings"},
{"team-embeddings": {"model": "my-embeddings", "hidden": False}},
],
)
def test_create_model_info_response_resolves_model_group_alias_to_target(model_group_alias, local_model_cost_map):
"""A `model_group_alias` row must report the metadata of the group it points at,
not the cost-map generalization or nothing that the alias name resolves to."""
from litellm import Router
router = Router(
model_list=[
{
"model_name": "my-embeddings",
"litellm_params": {"model": "openai/text-embedding-3-small"},
}
],
model_group_alias=model_group_alias,
)
alias_response = create_model_info_response(
model_id="team-embeddings", provider="openai", llm_router=router
)
target_response = create_model_info_response(
model_id="my-embeddings", provider="openai", llm_router=router
)
assert alias_response["id"] == "team-embeddings"
for field in ("mode", "max_input_tokens", "max_output_tokens"):
assert alias_response.get(field) == target_response.get(field)
assert alias_response["mode"] == "embedding"
@pytest.mark.parametrize(
"key_metadata, team_metadata, expected_to_run",
[