Merge branch 'litellm_block_unpriced_models' of https://github.com/BerriAI/litellm into litellm_block_unpriced_models

# Conflicts:
#	litellm/proxy/auth/auth_checks.py
#	tests/test_litellm/proxy/auth/test_auth_checks.py
This commit is contained in:
mateo-berri 2026-08-20 14:36:58 -07:00
commit 7f539e388c
2 changed files with 15 additions and 21 deletions

View file

@ -445,9 +445,7 @@ def _has_ptu_flat_cost(model: str, llm_router: "Router") -> bool:
def _is_cost_explicitly_configured(model: str, llm_router: "Router") -> bool:
"""
Check if any deployment in the model group has cost fields explicitly
set in its litellm_params or its litellm.model_cost entry, on any billed
metric. An explicit zero counts: pricing a model at 0 is a deliberate
admin choice, distinct from a model missing from the cost map.
set in its litellm.model_cost entry.
When Router._create_deployment() registers a model not in the global
cost map, it creates a sparse entry like {"id": "<hash>"} with no cost
@ -457,8 +455,6 @@ def _is_cost_explicitly_configured(model: str, llm_router: "Router") -> bool:
for deployment in llm_router.model_list:
if deployment.get("model_name") != model:
continue
if _entry_has_explicit_cost_key(deployment.get("litellm_params") or _EMPTY_COST_ENTRY):
return True
model_id = deployment.get("model_info", {}).get("id")
if model_id is None:
continue
@ -475,13 +471,6 @@ def _is_positive_cost(value: object) -> bool:
return isinstance(value, (int, float)) and not isinstance(value, bool) and value > 0
def _entry_has_explicit_cost_key(entry: Mapping[str, object]) -> bool:
return any(
"cost_per" in key and isinstance(value, (int, float)) and not isinstance(value, bool)
for key, value in entry.items()
)
def _entry_has_priced_metric(entry: Mapping[str, object]) -> bool:
for key, value in entry.items():
if "cost_per" not in key:
@ -493,15 +482,20 @@ def _entry_has_priced_metric(entry: Mapping[str, object]) -> bool:
return False
def _entry_declares_price(entry: Mapping[str, object]) -> bool:
return any("cost_per" in key for key in entry)
def _model_group_has_pricing(model: str, llm_router: "Router") -> bool:
"""
Check every deployment behind a model group for a positive price on any billed
metric (tokens, characters, seconds, pages, images, queries, ...), so models that
are billed by a non-token metric are not treated as unpriced.
A model group counts as priced when a deployment overrides any *cost_per* field in its
litellm_params, even at zero, or when its resolved model info carries a positive price on
any billed metric (tokens, characters, seconds, pages, images, queries, ...), so models
billed by a non-token metric are not treated as unpriced.
"""
for deployment in llm_router.get_model_list(model_name=model) or ():
litellm_params = deployment.get("litellm_params") or _EMPTY_COST_ENTRY
if _entry_has_priced_metric(litellm_params):
if _entry_declares_price(litellm_params):
return True
model_id = (deployment.get("model_info") or _EMPTY_COST_ENTRY).get("id")

View file

@ -6635,7 +6635,7 @@ def test_model_has_no_cost_mapping_non_token_price_from_litellm_params_is_false(
{
"model_name": "custom-tts",
"litellm_params": {
"model": UNPRICED_UNDERLYING_MODEL,
"model": f"{UNPRICED_UNDERLYING_MODEL}-per-second",
"api_key": "sk-test",
"input_cost_per_second": 0.0001,
},
@ -6646,8 +6646,8 @@ def test_model_has_no_cost_mapping_non_token_price_from_litellm_params_is_false(
assert model_has_no_cost_mapping(model="custom-tts", llm_router=router) is False
@pytest.mark.parametrize("zero_cost_key", ["input_cost_per_second", "input_cost_per_token"])
def test_model_has_no_cost_mapping_explicit_zero_price_is_false(zero_cost_key):
@pytest.mark.parametrize("cost_field", ["input_cost_per_second", "input_cost_per_token"])
def test_model_has_no_cost_mapping_explicit_zero_price_is_false(cost_field):
from litellm.proxy.auth.auth_checks import model_has_no_cost_mapping
from litellm.router import Router
@ -6656,9 +6656,9 @@ def test_model_has_no_cost_mapping_explicit_zero_price_is_false(zero_cost_key):
{
"model_name": "free-group",
"litellm_params": {
"model": UNPRICED_UNDERLYING_MODEL,
"model": f"{UNPRICED_UNDERLYING_MODEL}-{cost_field}",
"api_key": "sk-test",
zero_cost_key: 0.0,
cost_field: 0,
},
}
]