From a5b18431f7779a5b934c0283177d5f9743de3d65 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 29 Sep 2026 03:11:00 +0000 Subject: [PATCH] fix(health): filter wildcard health probes to ids matching the literal prefix Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../health_check_helpers.py | 20 +++++++++---------- .../test_wildcard_partial_prefix_expansion.py | 4 +++- .../test_health_check_helpers.py | 14 +++++++++++-- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/litellm/litellm_core_utils/health_check_helpers.py b/litellm/litellm_core_utils/health_check_helpers.py index 30e9b020245..692435b3910 100644 --- a/litellm/litellm_core_utils/health_check_helpers.py +++ b/litellm/litellm_core_utils/health_check_helpers.py @@ -45,19 +45,17 @@ def _strip_known_provider_prefix(model: str, known_providers: frozenset[str]) -> def _wildcard_health_check_models( - wildcard_suffix: str, custom_llm_provider: str, cheapest_models: Sequence[str] + wildcard_suffix: str, custom_llm_provider: str, candidate_models: Sequence[str] ) -> tuple[str, ...]: if wildcard_suffix == "*": - return tuple(cheapest_models) + return tuple(candidate_models[:3]) known_providers: Final = frozenset(provider.value for provider in LlmProviders) literal_prefix: Final = wildcard_suffix.replace("*", "") - stripped_ids: Final = tuple(_strip_known_provider_prefix(model, known_providers) for model in cheapest_models) - return tuple( - f"{custom_llm_provider}/{stripped}" - if stripped.startswith(literal_prefix) - else f"{custom_llm_provider}/{wildcard_suffix.replace('*', stripped, 1)}" - for stripped in stripped_ids - ) + stripped_ids: Final = tuple(_strip_known_provider_prefix(model, known_providers) for model in candidate_models) + matching: Final = [stripped for stripped in stripped_ids if stripped.startswith(literal_prefix)] + if matching: + return tuple(f"{custom_llm_provider}/{stripped}" for stripped in matching[:3]) + return tuple(f"{custom_llm_provider}/{wildcard_suffix.replace('*', stripped, 1)}" for stripped in stripped_ids[:3]) class HealthCheckHelpers: @@ -74,13 +72,13 @@ class HealthCheckHelpers: ) # this is a wildcard model, we need to pick a random model from the provider - cheapest_models = pick_cheapest_chat_models_from_llm_provider(custom_llm_provider=custom_llm_provider, n=3) + cheapest_models = pick_cheapest_chat_models_from_llm_provider(custom_llm_provider=custom_llm_provider, n=10_000) if len(cheapest_models) == 0: raise Exception( f"Unable to health check wildcard model for provider {custom_llm_provider}. Add a model on your config.yaml or contribute here - https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json" ) candidates: Final = _wildcard_health_check_models( - wildcard_suffix=model, custom_llm_provider=custom_llm_provider, cheapest_models=cheapest_models + wildcard_suffix=model, custom_llm_provider=custom_llm_provider, candidate_models=cheapest_models ) fallback_models: Final = list(candidates[1:]) or None model_params["model"] = candidates[0] diff --git a/tests/e2e/test_wildcard_partial_prefix_expansion.py b/tests/e2e/test_wildcard_partial_prefix_expansion.py index dbe85028e10..1281e9d921b 100644 --- a/tests/e2e/test_wildcard_partial_prefix_expansion.py +++ b/tests/e2e/test_wildcard_partial_prefix_expansion.py @@ -146,5 +146,7 @@ def test_model_info_keeps_provider_model_for_expanded_deployments(wildcard_proxy ) ) - bad = [row.model_name for row in info.data if "system.ai.databricks/" in row.litellm_params.model] + expanded = [row for row in info.data if row.model_name.startswith("databricks/system.ai.")] + assert expanded, "model/info returned no expanded rows for databricks/system.ai.*" + bad = [row.model_name for row in expanded if "system.ai.databricks/" in row.litellm_params.model] assert not bad, f"litellm_params.model carries the corrupted expanded name: {bad}" diff --git a/tests/unit/litellm_core_utils/test_health_check_helpers.py b/tests/unit/litellm_core_utils/test_health_check_helpers.py index 1087d8be3ff..e5bd43369ec 100644 --- a/tests/unit/litellm_core_utils/test_health_check_helpers.py +++ b/tests/unit/litellm_core_utils/test_health_check_helpers.py @@ -564,14 +564,24 @@ def test_wildcard_health_check_models_partial_prefix_substitutes_stripped_id(): def test_wildcard_health_check_models_star_wildcard_unchanged(): - candidates: Final = ("databricks/databricks-gpt-5",) - assert _wildcard_health_check_models("*", "databricks", candidates) == candidates + candidates: Final = ("databricks/a", "databricks/b", "databricks/c", "databricks/d") + assert _wildcard_health_check_models("*", "databricks", candidates) == ( + "databricks/a", + "databricks/b", + "databricks/c", + ) def test_wildcard_health_check_models_partial_prefix_matching_literal_keeps_stripped_id(): assert _wildcard_health_check_models("gpt-4*", "openai", ["gpt-4o-mini"]) == ("openai/gpt-4o-mini",) +def test_wildcard_health_check_models_partial_prefix_filters_candidates_to_literal_prefix(): + assert _wildcard_health_check_models( + "gpt-4*", "openai", ["gpt-5-nano", "gpt-4o-mini", "gpt-4.1-mini", "gpt-4o"] + ) == ("openai/gpt-4o-mini", "openai/gpt-4.1-mini", "openai/gpt-4o") + + def test_wildcard_health_check_models_partial_prefix_splices_suffix_around_star(): assert _wildcard_health_check_models("ft:*", "openai", ["gpt-4o-mini"]) == ("openai/ft:gpt-4o-mini",)