mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-29 06:33:28 +00:00
fix(proxy): list alias wildcards as routable ids, not raw catalog ids
An alias whose suffix collides with a catalog sub-prefix (e.g. public "cloudflare/@cf/*" over deployment "cloudflare/*") took the partial-filter branch and listed raw catalog ids. Routing substitutes the captured suffix into the deployment pattern, so those listed ids routed to targets that do not exist. Only use filter semantics when the deployment repeats the wildcard suffix (or no deployment is available); aliases prepend their prefix to provider-stripped catalog ids so every listed id routes back to a real catalog model. Addresses Greptile review on #46390.
This commit is contained in:
parent
ae186a5ba6
commit
fb4bed86bf
2 changed files with 39 additions and 1 deletions
|
|
@ -312,7 +312,13 @@ def get_known_models_from_wildcard(wildcard_model: str, litellm_params: LiteLLM_
|
|||
for wc_model in wildcard_models
|
||||
if wc_model.removeprefix(provider_id_prefix).startswith(model_prefix)
|
||||
]
|
||||
if deployment_repeats_prefix or filtered_wildcard_models:
|
||||
# Filter semantics (list matching catalog ids) only apply when the public name is the
|
||||
# deployment's own pattern. For an alias over a broader deployment (e.g. public
|
||||
# "cloudflare/@cf/*" over "cloudflare/*"), routing substitutes the captured suffix into
|
||||
# the deployment pattern, so catalog ids must be listed with the alias prefix prepended
|
||||
# to their provider-stripped form; listing the raw catalog id would advertise models
|
||||
# whose routed target does not exist.
|
||||
if deployment_repeats_prefix or (litellm_params is None and filtered_wildcard_models):
|
||||
wildcard_models = filtered_wildcard_models
|
||||
else:
|
||||
# add model prefix to wildcard models
|
||||
|
|
|
|||
|
|
@ -1272,3 +1272,35 @@ def test_alias_wildcard_prepends_its_prefix_to_catalog_ids_without_their_provide
|
|||
litellm.model_cost.pop(catalog_id, None)
|
||||
litellm.models_by_provider["cloudflare"].discard(catalog_id)
|
||||
litellm.add_known_models(model_cost_map={})
|
||||
|
||||
|
||||
def test_alias_wildcard_matching_catalog_subprefix_lists_routable_ids() -> None:
|
||||
"""GH#46384: an alias whose suffix collides with a catalog sub-prefix (public
|
||||
"cloudflare/@cf/*" over deployment "cloudflare/*") is an alias, not a filter.
|
||||
Routing substitutes the captured suffix into the deployment pattern, so the
|
||||
listing must prepend the alias prefix to provider-stripped catalog ids; the
|
||||
raw catalog id would route to a target that does not exist."""
|
||||
import litellm
|
||||
from litellm.proxy.auth.model_checks import get_known_models_from_wildcard
|
||||
from litellm.types.router import LiteLLM_Params
|
||||
|
||||
catalog_id: Final = "cloudflare/@cf/partial-alias-org/model-b"
|
||||
try:
|
||||
litellm.register_model(
|
||||
{catalog_id: {"litellm_provider": "cloudflare", "mode": "chat"}}, persist_across_reloads=False
|
||||
)
|
||||
|
||||
listed: Final = get_known_models_from_wildcard("cloudflare/@cf/*", LiteLLM_Params(model="cloudflare/*"))
|
||||
|
||||
# routing captures the segment after "cloudflare/@cf/" and substitutes it into
|
||||
# "cloudflare/*"; every listed id must therefore map back to a catalog id
|
||||
alias_prefix: Final = "cloudflare/@cf/"
|
||||
routed: Final = [
|
||||
f"cloudflare/{model.removeprefix(alias_prefix)}" for model in listed if model.startswith(alias_prefix)
|
||||
]
|
||||
assert catalog_id in routed
|
||||
assert catalog_id not in listed
|
||||
finally:
|
||||
litellm.model_cost.pop(catalog_id, None) # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType] # test cleanup
|
||||
litellm.models_by_provider["cloudflare"].discard(catalog_id) # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType] # test cleanup
|
||||
litellm.add_known_models(model_cost_map={}) # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType] # test cleanup
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue