fix(proxy): preserve dynamic valid models in /v1/models filtering

This commit is contained in:
omarsherif0 2026-04-13 21:24:52 +00:00
parent 832210de09
commit 976b12d05e
No known key found for this signature in database
GPG key ID: 9E7B298437B5995B
2 changed files with 57 additions and 19 deletions

View file

@ -4,12 +4,11 @@ from typing import Dict, List, Optional, Set
import litellm
from litellm._logging import verbose_proxy_logger
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
from litellm.proxy._types import SpecialModelNames, UserAPIKeyAuth
from litellm.router import Router
from litellm.router_utils.fallback_event_handlers import get_fallback_model_group
from litellm.types.router import LiteLLM_Params
from litellm.types.utils import LlmProvidersSet
from litellm.utils import get_valid_models
@ -66,25 +65,23 @@ def _get_models_from_access_groups(
return all_models
def _is_known_provider_qualified_model(model: str) -> bool:
def _is_resolvable_dynamic_model(model: str) -> bool:
"""
Return True for provider-qualified model identifiers such as:
- openai/gpt-4o-mini
- bedrock/us.amazon.nova-micro-v1:0
- openrouter/auto
Return True for model identifiers that LiteLLM can still resolve even when
they are not present in the static model list.
This intentionally allows provider-prefixed models even when the exact
model name is not yet in LiteLLM's static model list, since those routes
may still be valid for pass-through / BYOK flows.
This covers:
- provider-qualified routes such as `bedrock/us.amazon.nova-micro-v1:0`
or JSON-registry providers such as `publicai/some-new-model`
- dynamic model identifiers such as OpenAI fine-tunes
(`ft:gpt-4o:my-org:custom:id`)
"""
if "/" not in model:
try:
get_llm_provider(model=model)
return True
except Exception:
return False
provider_prefix = model.split("/", 1)[0]
return provider_prefix in LlmProvidersSet or JSONProviderRegistry.exists(
provider_prefix
)
def _should_include_model_in_complete_list(
model: str,
@ -99,11 +96,12 @@ def _should_include_model_in_complete_list(
- configured proxy model groups
- configured access group names
- known base model IDs (e.g. gpt-4o-mini)
- known provider-qualified routes (e.g. openai/gpt-4o-mini, bedrock/*)
- provider-qualified or other dynamically resolvable model IDs
(e.g. openai/gpt-4o-mini, publicai/foo, ft:gpt-4o:org:suffix:id)
Drop:
- arbitrary strings that don't resolve to a proxy model, access group, or
a recognized LiteLLM/provider model route.
a recognized LiteLLM model route.
"""
if model in (
SpecialModelNames.all_proxy_models.value,
@ -120,7 +118,7 @@ def _should_include_model_in_complete_list(
if model == "*":
return True
if _is_known_provider_qualified_model(model):
if _is_resolvable_dynamic_model(model):
return True
return False

View file

@ -312,3 +312,43 @@ def test_get_complete_model_list_keeps_provider_qualified_models():
)
assert result == ["bedrock/very_new_model"]
def test_get_complete_model_list_keeps_json_registry_provider_models():
"""
JSON-registry-only providers should also survive filtering even when the
exact model name is not present in LiteLLM's static model list.
"""
from litellm.proxy.auth.model_checks import get_complete_model_list
result = get_complete_model_list(
key_models=["publicai/some-new-model"],
team_models=[],
proxy_model_list=[],
user_model=None,
infer_model_from_keys=False,
model_access_groups={},
)
assert result == ["publicai/some-new-model"]
def test_get_complete_model_list_keeps_openai_finetune_model_ids():
"""
OpenAI fine-tuned model IDs are dynamic valid models and should remain in
the final list even though they are not in LiteLLM's static model list.
"""
from litellm.proxy.auth.model_checks import get_complete_model_list
finetuned_model = "ft:gpt-4o:my-org:custom-suffix:model-id"
result = get_complete_model_list(
key_models=[finetuned_model],
team_models=[],
proxy_model_list=[],
user_model=None,
infer_model_from_keys=False,
model_access_groups={},
)
assert result == [finetuned_model]