fix(proxy): list catalog models through routing-prefix wildcard deployments

This commit is contained in:
mateo-berri 2026-10-19 10:34:25 -07:00
parent 8dbbdc90c7
commit d14a5aedc0
2 changed files with 38 additions and 3 deletions

View file

@ -1,6 +1,7 @@
# What is this?
## Common checks for /v1/models and `/model/info`
import copy
import itertools
import re
from collections.abc import Sequence
from typing import Final
@ -271,16 +272,33 @@ def _hydrate_litellm_credential_name(
return litellm_params
def _is_routing_segment(segment: str, provider_model_ids: tuple[str, ...]) -> bool:
return "*" not in segment and not any(model_id.startswith(f"{segment}/") for model_id in provider_model_ids)
def _without_routing_segments(model_pattern: str, provider_model_ids: tuple[str, ...]) -> str:
segments: Final = model_pattern.split("/")
routing_segments: Final = tuple(
itertools.takewhile(lambda segment: _is_routing_segment(segment, provider_model_ids), segments[:-1])
)
return "/".join(segments[len(routing_segments) :])
def _ids_routing_to_catalog_models(
name_pattern: str, deployment_pattern: str, provider: str, catalog_ids: Sequence[str]
) -> tuple[str, ...]:
if name_pattern.count("*") != deployment_pattern.count("*"):
return ()
deployment_regex: Final = re.compile(PatternMatchRouter().pattern_to_regex(deployment_pattern))
provider_id_prefix: Final = f"{provider}/"
provider_model_ids: Final = tuple(catalog_id.removeprefix(provider_id_prefix) for catalog_id in catalog_ids)
catalog_pattern: Final = _without_routing_segments(
deployment_pattern.removeprefix(provider_id_prefix), provider_model_ids
)
deployment_regex: Final = re.compile(
PatternMatchRouter().pattern_to_regex(f"{provider_id_prefix}{catalog_pattern}")
)
catalog_matches: Final = (
deployment_regex.fullmatch(f"{provider_id_prefix}{catalog_id.removeprefix(provider_id_prefix)}")
for catalog_id in catalog_ids
deployment_regex.fullmatch(f"{provider_id_prefix}{model_id}") for model_id in provider_model_ids
)
return tuple(
dict.fromkeys(

View file

@ -1267,6 +1267,8 @@ _ROUTE_CF_ID: Final = "cloudflare/@cf/partial-route-org/model-a-instruct"
_ROUTE_CF_SUFFIXED_ID: Final = "cloudflare/@cf/partial-route-org/model-b-instruct-v2"
_ROUTE_HF_ID: Final = "cloudflare/@hf/partial-route-org/model-c"
_ROUTE_GEMINI_ID: Final = "gemini-partial-route-9-flash"
_ROUTE_OPENAI_ID: Final = "gpt-partial-route-9-mini"
_ROUTE_BEDROCK_ID: Final = "anthropic.partial-route-9-v1:0"
_ROUTE_CF_IDS: Final = {_ROUTE_CF_ID, _ROUTE_CF_SUFFIXED_ID}
@ -1297,6 +1299,19 @@ _ROUTE_CF_IDS: Final = {_ROUTE_CF_ID, _ROUTE_CF_SUFFIXED_ID}
pytest.param(
"gemini/*", "gemini/*", "gemini/gemini-partial-route-9*", {_ROUTE_GEMINI_ID}, id="key-filter-over-bare-id"
),
pytest.param(
"openai/*", "openai/responses/*", None, {f"openai/responses/{_ROUTE_OPENAI_ID}"}, id="responses-route"
),
pytest.param(
"openai/*",
"openai/responses/*",
"openai/gpt-partial-route-9*",
{f"openai/responses/{_ROUTE_OPENAI_ID}"},
id="key-filter-over-responses-route",
),
pytest.param(
"bedrock/*", "bedrock/converse/*", None, {f"bedrock/converse/{_ROUTE_BEDROCK_ID}"}, id="converse-route"
),
],
)
def test_every_listed_partial_wildcard_id_routes_to_the_catalog_model_it_names(
@ -1331,6 +1346,8 @@ def test_every_listed_partial_wildcard_id_routes_to_the_catalog_model_it_names(
_ROUTE_CF_SUFFIXED_ID: "cloudflare",
_ROUTE_HF_ID: "cloudflare",
_ROUTE_GEMINI_ID: "gemini",
_ROUTE_OPENAI_ID: "openai",
_ROUTE_BEDROCK_ID: "bedrock",
}
):
v1_models: Final = get_complete_model_list(