mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
fix(proxy): treat explicit zero non-token prices as priced
A deployment that overrides any cost_per field, including at zero, now counts as priced so it is not blocked as unpriced Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
074b37b4f9
commit
c551a5c44a
2 changed files with 31 additions and 5 deletions
|
|
@ -300,15 +300,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 {}
|
||||
if _entry_has_priced_metric(litellm_params):
|
||||
if _entry_declares_price(litellm_params):
|
||||
return True
|
||||
|
||||
model_id = (deployment.get("model_info") or {}).get("id")
|
||||
|
|
|
|||
|
|
@ -5246,7 +5246,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,
|
||||
},
|
||||
|
|
@ -5257,6 +5257,27 @@ 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("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
|
||||
|
||||
router = Router(
|
||||
model_list=[
|
||||
{
|
||||
"model_name": "free-group",
|
||||
"litellm_params": {
|
||||
"model": f"{UNPRICED_UNDERLYING_MODEL}-{cost_field}",
|
||||
"api_key": "sk-test",
|
||||
cost_field: 0,
|
||||
},
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
assert model_has_no_cost_mapping(model="free-group", llm_router=router) is False
|
||||
|
||||
|
||||
async def _run_common_checks(
|
||||
model: Optional[str], llm_router: Optional["Router"], route: str = "/chat/completions"
|
||||
) -> bool:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue