This commit is contained in:
Samir Hanna Verza 2026-11-05 14:42:01 -03:00 • committed by GitHub
commit c735b24111
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 66 additions and 1 deletions

View file

@ -48,7 +48,18 @@ def resolve_litellm_model(model: str) -> str | None:
if isinstance(model_cost.get(key), dict)
}
if len(matches) == 1 or len(prices) == 1:
return matches[0]
# Every route prices the model the same, so picking one is free; pick
# the first-party listing over an aggregator's re-listing. Aggregators
# (OpenRouter, DeepInfra, ...) re-key a model under a namespaced path
# such as "openrouter/x-ai/grok-4.5", which sorts ahead of the native
# "xai/grok-4.5", so the alphabetically first key would be misleading.
native = [
key
for key in matches
if isinstance(model_cost.get(key), dict)
and key == f"{model_cost[key].get('litellm_provider')}/{name}"
]
return native[0] if len(native) == 1 else matches[0]
return None # noqa: TRY300
except Exception: # noqa: BLE001
return None

View file

@ -253,12 +253,16 @@ def test_resolver_uses_provider_when_bare_entry_has_one() -> None:
def test_resolver_does_not_guess_between_differently_priced_providers() -> None:
original = litellm.model_cost
# Real catalog entries always carry ``litellm_provider``; without it the native
# route could never match and this guard would not exercise the preference.
litellm.model_cost = {
"provider-a/example": {
"litellm_provider": "provider-a",
"input_cost_per_token": 1.0,
"output_cost_per_token": 2.0,
},
"provider-b/example": {
"litellm_provider": "provider-b",
"input_cost_per_token": 3.0,
"output_cost_per_token": 4.0,
},
@ -269,3 +273,53 @@ def test_resolver_does_not_guess_between_differently_priced_providers() -> None:
finally:
litellm.model_cost = original
resolve_litellm_model.cache_clear()
def test_resolver_prefers_native_provider_over_aggregator() -> None:
# The same model re-listed by an aggregator (which sorts first) and by its
# first-party provider at the same price. The resolver must return the
# native listing, not the alphabetically first aggregator key.
original = litellm.model_cost
litellm.model_cost = {
"openrouter/x-ai/grok-4.5": {
"litellm_provider": "openrouter",
"input_cost_per_token": 2e-06,
"output_cost_per_token": 6e-06,
},
"xai/grok-4.5": {
"litellm_provider": "xai",
"input_cost_per_token": 2e-06,
"output_cost_per_token": 6e-06,
},
}
try:
resolve_litellm_model.cache_clear()
assert resolve_litellm_model("grok-4.5") == "xai/grok-4.5"
finally:
litellm.model_cost = original
resolve_litellm_model.cache_clear()
def test_resolver_does_not_guess_when_a_native_route_exists_but_prices_differ() -> None:
# The native preference only breaks ties between routes that price the model the
# same. When an aggregator charges differently, the cost depends on the route and
# the resolver still declines to guess, as it did before the native preference.
original = litellm.model_cost
litellm.model_cost = {
"deepinfra/x/example-model": {
"litellm_provider": "deepinfra",
"input_cost_per_token": 1e-06,
"output_cost_per_token": 2e-06,
},
"example/example-model": {
"litellm_provider": "example",
"input_cost_per_token": 5e-06,
"output_cost_per_token": 9e-06,
},
}
try:
resolve_litellm_model.cache_clear()
assert resolve_litellm_model("example-model") is None
finally:
litellm.model_cost = original
resolve_litellm_model.cache_clear()