Merge pull request #38327 from BerriAI/litellm_tiered_pricing_rate_fallbacks

test(cost-calc): pin the rate fallbacks inside a tiered-pricing tier
This commit is contained in:
ryan-crabbe-berri 2026-08-26 09:20:56 -07:00 • committed by GitHub
commit 597b4bb239
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -716,6 +716,136 @@ def test_generic_cost_per_token_tier_without_an_output_rate_bills_the_model_rate
litellm.model_cost.pop(model, None)
def test_generic_cost_per_token_tier_without_cache_rates_bills_cache_at_the_tier_input_rate():
model = "litellm-test-tiered-no-cache-rates"
custom_llm_provider = "openrouter"
litellm.register_model(
{
model: {
"litellm_provider": custom_llm_provider,
"mode": "chat",
"cache_read_input_token_cost": 9e-09,
"cache_creation_input_token_cost": 9e-06,
"tiered_pricing": [
{
"range": [0, 32000],
"input_cost_per_token": 4.6e-07,
"output_cost_per_token": 2.3e-06,
},
{
"range": [32000, 128000],
"input_cost_per_token": 7e-07,
"output_cost_per_token": 3.5e-06,
},
],
}
}
)
try:
uncached = Usage(prompt_tokens=40000, completion_tokens=100, total_tokens=40100)
cached = Usage(
prompt_tokens=40000,
completion_tokens=100,
total_tokens=40100,
prompt_tokens_details=PromptTokensDetailsWrapper(
cached_tokens=5000, cache_creation_tokens=15000
),
)
uncached_prompt_cost, _ = generic_cost_per_token(
model=model,
usage=uncached,
custom_llm_provider=custom_llm_provider,
)
cached_prompt_cost, cached_completion_cost = generic_cost_per_token(
model=model,
usage=cached,
custom_llm_provider=custom_llm_provider,
)
tier_input_rate = 7e-07
assert round(cached_prompt_cost, 12) == round(40000 * tier_input_rate, 12)
assert round(cached_prompt_cost, 12) == round(uncached_prompt_cost, 12)
assert round(cached_completion_cost, 12) == round(100 * 3.5e-06, 12)
finally:
litellm.model_cost.pop(model, None)
def test_generic_cost_per_token_tier_without_a_1hr_cache_rate_bills_the_tier_cache_creation_rate():
model = "litellm-test-tiered-no-1hr-cache-rate"
custom_llm_provider = "openrouter"
litellm.register_model(
{
model: {
"litellm_provider": custom_llm_provider,
"mode": "chat",
"cache_creation_input_token_cost_above_1hr": 9e-05,
"tiered_pricing": [
{
"range": [0, 128000],
"input_cost_per_token": 7e-07,
"output_cost_per_token": 3.5e-06,
"cache_creation_input_token_cost": 8.75e-07,
}
],
}
}
)
try:
usage = Usage(
prompt_tokens=1000,
completion_tokens=10,
total_tokens=1010,
prompt_tokens_details=PromptTokensDetailsWrapper(
cache_creation_tokens=800,
cache_creation_token_details=CacheCreationTokenDetails(
ephemeral_5m_input_tokens=300, ephemeral_1h_input_tokens=500
),
),
)
prompt_cost, completion_cost = generic_cost_per_token(
model=model,
usage=usage,
custom_llm_provider=custom_llm_provider,
)
tier_cache_creation_rate = 8.75e-07
expected_prompt = (200 * 7e-07) + (800 * tier_cache_creation_rate)
assert round(prompt_cost, 12) == round(expected_prompt, 12)
assert round(completion_cost, 12) == round(10 * 3.5e-06, 12)
finally:
litellm.model_cost.pop(model, None)
def test_generic_cost_per_token_tier_without_an_input_rate_is_not_a_priced_tier():
model = "litellm-test-tiered-no-input-rate"
custom_llm_provider = "openrouter"
litellm.register_model(
{
model: {
"litellm_provider": custom_llm_provider,
"mode": "chat",
"input_cost_per_token": 1e-06,
"output_cost_per_token": 2e-06,
"tiered_pricing": [{"range": [0, 128000], "output_cost_per_token": 3.5e-06}],
}
}
)
try:
usage = Usage(prompt_tokens=1000, completion_tokens=100, total_tokens=1100)
prompt_cost, completion_cost = generic_cost_per_token(
model=model,
usage=usage,
custom_llm_provider=custom_llm_provider,
)
assert round(prompt_cost, 12) == round(1000 * 1e-06, 12)
assert round(completion_cost, 12) == round(100 * 2e-06, 12)
finally:
litellm.model_cost.pop(model, None)
def test_router_deployment_with_input_only_tiers_bills_completions_at_the_backend_rate():
"""Regression: the router registers a deployment's custom pricing as a standalone
model_cost entry holding only the supplied fields, so an input-only tier table left