fix(databricks): charge the input rate for cache tokens on models with no cache pricing

The shared cost calculator treats a missing cache rate as free, so routing
Databricks through it billed cached tokens at zero on the 14 entries that
publish no cache pricing. On a 10,000 token prompt with 8,000 cache reads
that is $0.0010000 against the correct $0.0050001, a fivefold undercharge.

Those entries now declare cache rates equal to their input rate, which is
what a model with no caching discount should charge, and a test pins every
priced Databricks entry to declaring cache rates so no future entry can
regress into it.

Also repoints the provider-neutral generalization test off an id the new
Opus 5 entry now shadows, adds backup-to-main parity tests for the five new
entries, pins that Databricks Claude is never auto-injected with cache
control despite reporting caching support, and trims the Sonnet 5 pricing
note, which is served on an unauthenticated route.
This commit is contained in:
mateo-berri 2026-08-22 15:37:37 -07:00
parent 6c23f5ffba
commit da3dcb139d
5 changed files with 119 additions and 3 deletions

View file

@ -14551,6 +14551,8 @@
]
},
"databricks/databricks-bge-large-en": {
"cache_creation_input_token_cost": 1.0003e-07,
"cache_read_input_token_cost": 1.0003e-07,
"input_cost_per_token": 1.0003e-07,
"input_dbu_cost_per_token": 1.429e-06,
"litellm_provider": "databricks",
@ -14904,7 +14906,7 @@
"max_output_tokens": 128000,
"max_tokens": 128000,
"metadata": {
"notes": "Input/output cost per token is dbu cost * $0.070. Number provided for reference, '*_dbu_cost_per_token' used in actual calculation. Anthropic's introductory launch rates (28.571 input / 142.857 output DBU) run through 2026-08-31. The standard rates listed here, equal to Sonnet 4.5 / 4.6, are used instead because pricing carries no expiry date, and undercharging past the window would let spend outrun enforced budgets."
"notes": "Input/output cost per token is dbu cost * $0.070. Number provided for reference, '*_dbu_cost_per_token' used in actual calculation. Introductory launch rates of 28.571 input / 142.857 output DBU run through 2026-08-31; the standard rates are listed here because entries carry no expiry date."
},
"mode": "chat",
"output_cost_per_token": 1.5000020000000002e-05,
@ -15042,6 +15044,8 @@
"supports_tool_choice": true
},
"databricks/databricks-gemma-3-12b": {
"cache_creation_input_token_cost": 1.5000999999999998e-07,
"cache_read_input_token_cost": 1.5000999999999998e-07,
"input_cost_per_token": 1.5000999999999998e-07,
"input_dbu_cost_per_token": 2.1429999999999996e-06,
"litellm_provider": "databricks",
@ -15273,6 +15277,8 @@
"supports_prompt_caching": true
},
"databricks/databricks-gpt-oss-120b": {
"cache_creation_input_token_cost": 1.5000999999999998e-07,
"cache_read_input_token_cost": 1.5000999999999998e-07,
"input_cost_per_token": 1.5000999999999998e-07,
"input_dbu_cost_per_token": 2.1429999999999996e-06,
"litellm_provider": "databricks",
@ -15288,6 +15294,8 @@
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
},
"databricks/databricks-gpt-oss-20b": {
"cache_creation_input_token_cost": 7e-08,
"cache_read_input_token_cost": 7e-08,
"input_cost_per_token": 7e-08,
"input_dbu_cost_per_token": 1e-06,
"litellm_provider": "databricks",
@ -15303,6 +15311,8 @@
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
},
"databricks/databricks-gte-large-en": {
"cache_creation_input_token_cost": 1.2999000000000001e-07,
"cache_read_input_token_cost": 1.2999000000000001e-07,
"input_cost_per_token": 1.2999000000000001e-07,
"input_dbu_cost_per_token": 1.857e-06,
"litellm_provider": "databricks",
@ -15318,6 +15328,8 @@
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
},
"databricks/databricks-llama-2-70b-chat": {
"cache_creation_input_token_cost": 5.0001e-07,
"cache_read_input_token_cost": 5.0001e-07,
"input_cost_per_token": 5.0001e-07,
"input_dbu_cost_per_token": 7.143e-06,
"litellm_provider": "databricks",
@ -15334,6 +15346,8 @@
"supports_tool_choice": true
},
"databricks/databricks-llama-4-maverick": {
"cache_creation_input_token_cost": 5.0001e-07,
"cache_read_input_token_cost": 5.0001e-07,
"input_cost_per_token": 5.0001e-07,
"input_dbu_cost_per_token": 7.143e-06,
"litellm_provider": "databricks",
@ -15350,6 +15364,8 @@
"supports_tool_choice": true
},
"databricks/databricks-meta-llama-3-1-405b-instruct": {
"cache_creation_input_token_cost": 5.00003e-06,
"cache_read_input_token_cost": 5.00003e-06,
"input_cost_per_token": 5.00003e-06,
"input_dbu_cost_per_token": 7.1429e-05,
"litellm_provider": "databricks",
@ -15366,6 +15382,8 @@
"supports_tool_choice": true
},
"databricks/databricks-meta-llama-3-1-8b-instruct": {
"cache_creation_input_token_cost": 1.5000999999999998e-07,
"cache_read_input_token_cost": 1.5000999999999998e-07,
"input_cost_per_token": 1.5000999999999998e-07,
"input_dbu_cost_per_token": 2.1429999999999996e-06,
"litellm_provider": "databricks",
@ -15381,6 +15399,8 @@
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
},
"databricks/databricks-meta-llama-3-3-70b-instruct": {
"cache_creation_input_token_cost": 5.0001e-07,
"cache_read_input_token_cost": 5.0001e-07,
"input_cost_per_token": 5.0001e-07,
"input_dbu_cost_per_token": 7.143e-06,
"litellm_provider": "databricks",
@ -15397,6 +15417,8 @@
"supports_tool_choice": true
},
"databricks/databricks-meta-llama-3-70b-instruct": {
"cache_creation_input_token_cost": 1.00002e-06,
"cache_read_input_token_cost": 1.00002e-06,
"input_cost_per_token": 1.00002e-06,
"input_dbu_cost_per_token": 1.4286e-05,
"litellm_provider": "databricks",
@ -15413,6 +15435,8 @@
"supports_tool_choice": true
},
"databricks/databricks-mixtral-8x7b-instruct": {
"cache_creation_input_token_cost": 5.0001e-07,
"cache_read_input_token_cost": 5.0001e-07,
"input_cost_per_token": 5.0001e-07,
"input_dbu_cost_per_token": 7.143e-06,
"litellm_provider": "databricks",
@ -15429,6 +15453,8 @@
"supports_tool_choice": true
},
"databricks/databricks-mpt-30b-instruct": {
"cache_creation_input_token_cost": 1.00002e-06,
"cache_read_input_token_cost": 1.00002e-06,
"input_cost_per_token": 1.00002e-06,
"input_dbu_cost_per_token": 1.4286e-05,
"litellm_provider": "databricks",
@ -15445,6 +15471,8 @@
"supports_tool_choice": true
},
"databricks/databricks-mpt-7b-instruct": {
"cache_creation_input_token_cost": 5.0001e-07,
"cache_read_input_token_cost": 5.0001e-07,
"input_cost_per_token": 5.0001e-07,
"input_dbu_cost_per_token": 7.143e-06,
"litellm_provider": "databricks",

View file

@ -14551,6 +14551,8 @@
]
},
"databricks/databricks-bge-large-en": {
"cache_creation_input_token_cost": 1.0003e-07,
"cache_read_input_token_cost": 1.0003e-07,
"input_cost_per_token": 1.0003e-07,
"input_dbu_cost_per_token": 1.429e-06,
"litellm_provider": "databricks",
@ -14904,7 +14906,7 @@
"max_output_tokens": 128000,
"max_tokens": 128000,
"metadata": {
"notes": "Input/output cost per token is dbu cost * $0.070. Number provided for reference, '*_dbu_cost_per_token' used in actual calculation. Anthropic's introductory launch rates (28.571 input / 142.857 output DBU) run through 2026-08-31. The standard rates listed here, equal to Sonnet 4.5 / 4.6, are used instead because pricing carries no expiry date, and undercharging past the window would let spend outrun enforced budgets."
"notes": "Input/output cost per token is dbu cost * $0.070. Number provided for reference, '*_dbu_cost_per_token' used in actual calculation. Introductory launch rates of 28.571 input / 142.857 output DBU run through 2026-08-31; the standard rates are listed here because entries carry no expiry date."
},
"mode": "chat",
"output_cost_per_token": 1.5000020000000002e-05,
@ -15042,6 +15044,8 @@
"supports_tool_choice": true
},
"databricks/databricks-gemma-3-12b": {
"cache_creation_input_token_cost": 1.5000999999999998e-07,
"cache_read_input_token_cost": 1.5000999999999998e-07,
"input_cost_per_token": 1.5000999999999998e-07,
"input_dbu_cost_per_token": 2.1429999999999996e-06,
"litellm_provider": "databricks",
@ -15273,6 +15277,8 @@
"supports_prompt_caching": true
},
"databricks/databricks-gpt-oss-120b": {
"cache_creation_input_token_cost": 1.5000999999999998e-07,
"cache_read_input_token_cost": 1.5000999999999998e-07,
"input_cost_per_token": 1.5000999999999998e-07,
"input_dbu_cost_per_token": 2.1429999999999996e-06,
"litellm_provider": "databricks",
@ -15288,6 +15294,8 @@
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
},
"databricks/databricks-gpt-oss-20b": {
"cache_creation_input_token_cost": 7e-08,
"cache_read_input_token_cost": 7e-08,
"input_cost_per_token": 7e-08,
"input_dbu_cost_per_token": 1e-06,
"litellm_provider": "databricks",
@ -15303,6 +15311,8 @@
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
},
"databricks/databricks-gte-large-en": {
"cache_creation_input_token_cost": 1.2999000000000001e-07,
"cache_read_input_token_cost": 1.2999000000000001e-07,
"input_cost_per_token": 1.2999000000000001e-07,
"input_dbu_cost_per_token": 1.857e-06,
"litellm_provider": "databricks",
@ -15318,6 +15328,8 @@
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
},
"databricks/databricks-llama-2-70b-chat": {
"cache_creation_input_token_cost": 5.0001e-07,
"cache_read_input_token_cost": 5.0001e-07,
"input_cost_per_token": 5.0001e-07,
"input_dbu_cost_per_token": 7.143e-06,
"litellm_provider": "databricks",
@ -15334,6 +15346,8 @@
"supports_tool_choice": true
},
"databricks/databricks-llama-4-maverick": {
"cache_creation_input_token_cost": 5.0001e-07,
"cache_read_input_token_cost": 5.0001e-07,
"input_cost_per_token": 5.0001e-07,
"input_dbu_cost_per_token": 7.143e-06,
"litellm_provider": "databricks",
@ -15350,6 +15364,8 @@
"supports_tool_choice": true
},
"databricks/databricks-meta-llama-3-1-405b-instruct": {
"cache_creation_input_token_cost": 5.00003e-06,
"cache_read_input_token_cost": 5.00003e-06,
"input_cost_per_token": 5.00003e-06,
"input_dbu_cost_per_token": 7.1429e-05,
"litellm_provider": "databricks",
@ -15366,6 +15382,8 @@
"supports_tool_choice": true
},
"databricks/databricks-meta-llama-3-1-8b-instruct": {
"cache_creation_input_token_cost": 1.5000999999999998e-07,
"cache_read_input_token_cost": 1.5000999999999998e-07,
"input_cost_per_token": 1.5000999999999998e-07,
"input_dbu_cost_per_token": 2.1429999999999996e-06,
"litellm_provider": "databricks",
@ -15381,6 +15399,8 @@
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
},
"databricks/databricks-meta-llama-3-3-70b-instruct": {
"cache_creation_input_token_cost": 5.0001e-07,
"cache_read_input_token_cost": 5.0001e-07,
"input_cost_per_token": 5.0001e-07,
"input_dbu_cost_per_token": 7.143e-06,
"litellm_provider": "databricks",
@ -15397,6 +15417,8 @@
"supports_tool_choice": true
},
"databricks/databricks-meta-llama-3-70b-instruct": {
"cache_creation_input_token_cost": 1.00002e-06,
"cache_read_input_token_cost": 1.00002e-06,
"input_cost_per_token": 1.00002e-06,
"input_dbu_cost_per_token": 1.4286e-05,
"litellm_provider": "databricks",
@ -15413,6 +15435,8 @@
"supports_tool_choice": true
},
"databricks/databricks-mixtral-8x7b-instruct": {
"cache_creation_input_token_cost": 5.0001e-07,
"cache_read_input_token_cost": 5.0001e-07,
"input_cost_per_token": 5.0001e-07,
"input_dbu_cost_per_token": 7.143e-06,
"litellm_provider": "databricks",
@ -15429,6 +15453,8 @@
"supports_tool_choice": true
},
"databricks/databricks-mpt-30b-instruct": {
"cache_creation_input_token_cost": 1.00002e-06,
"cache_read_input_token_cost": 1.00002e-06,
"input_cost_per_token": 1.00002e-06,
"input_dbu_cost_per_token": 1.4286e-05,
"litellm_provider": "databricks",
@ -15445,6 +15471,8 @@
"supports_tool_choice": true
},
"databricks/databricks-mpt-7b-instruct": {
"cache_creation_input_token_cost": 5.0001e-07,
"cache_read_input_token_cost": 5.0001e-07,
"input_cost_per_token": 5.0001e-07,
"input_dbu_cost_per_token": 7.143e-06,
"litellm_provider": "databricks",

View file

@ -1599,6 +1599,14 @@ class TestEnableAnthropicPromptCaching:
assert supports_prompt_caching(model=model, custom_llm_provider=provider) is True
assert self._points(model=model, provider=provider) == []
def test_databricks_claude_not_injected_despite_caching_support(self, monkeypatch):
from litellm.utils import supports_prompt_caching
monkeypatch.setattr(litellm, "enable_anthropic_prompt_caching", True)
model = "databricks/databricks-claude-sonnet-4-5"
assert supports_prompt_caching(model=model, custom_llm_provider="databricks") is True
assert self._points(model=model, provider="databricks") == []
def test_model_without_caching_support_not_injected(self, monkeypatch):
monkeypatch.setattr(litellm, "enable_anthropic_prompt_caching", True)
assert self._points(model="anthropic.claude-3-5-sonnet-20240620-v1:0", provider="bedrock") == []

View file

@ -378,7 +378,7 @@ def test_shipped_rules_flag_unmapped_fable_as_always_on_thinking(shipped_cost_ma
"model,provider",
[
("claude-opus-4-9@20260101", "vertex_ai"),
("databricks-claude-opus-5-1", "databricks"),
("databricks-claude-haiku-5-1", "databricks"),
],
)
def test_shipped_rules_are_provider_neutral_for_unmapped_ids(shipped_cost_map, model, provider):
@ -388,6 +388,8 @@ def test_shipped_rules_are_provider_neutral_for_unmapped_ids(shipped_cost_map, m
assert info["supports_adaptive_thinking"] is True
assert info["supports_mid_conversation_system"] is True
assert info["supports_function_calling"] is True
assert not info.get("input_cost_per_token")
assert not info.get("output_cost_per_token")
@pytest.mark.parametrize(

View file

@ -1,4 +1,6 @@
import json
from collections.abc import Iterator
from pathlib import Path
from typing import Final
import pytest
@ -7,6 +9,17 @@ import litellm
from litellm.llms.databricks.cost_calculator import cost_per_token
from litellm.types.utils import ModelInfo, Usage
REPO_ROOT: Final = Path(__file__).parents[4]
MAIN_PRICES: Final = REPO_ROOT / "model_prices_and_context_window.json"
BACKUP_PRICES: Final = REPO_ROOT / "litellm" / "model_prices_and_context_window_backup.json"
NEW_MODELS: Final = (
"databricks/databricks-claude-opus-4-7",
"databricks/databricks-claude-opus-4-8",
"databricks/databricks-claude-opus-5",
"databricks/databricks-claude-sonnet-5",
"databricks/databricks-claude-fable-5",
)
@pytest.fixture
def local_model_cost_map(monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
@ -91,6 +104,43 @@ def test_new_models_carry_cache_pricing(local_model_cost_map: None, model: str)
assert info["supports_prompt_caching"] is True
def test_every_priced_databricks_model_declares_cache_rates(local_model_cost_map: None) -> None:
undeclared: Final = [
model
for model, info in litellm.model_cost.items()
if model.startswith("databricks/")
and info.get("input_cost_per_token") is not None
and info.get("cache_read_input_token_cost") is None
]
assert undeclared == []
def test_models_without_a_cache_discount_bill_cache_tokens_at_the_input_rate(
local_model_cost_map: None,
) -> None:
model: Final = "databricks/databricks-meta-llama-3-3-70b-instruct"
info: Final = _model_info(model)
usage: Final = Usage(
prompt_tokens=10000,
completion_tokens=100,
total_tokens=10100,
cache_read_input_tokens=8000,
)
prompt_cost, _ = cost_per_token(model=model, usage=usage)
assert prompt_cost == pytest.approx(10000 * info["input_cost_per_token"])
@pytest.mark.parametrize("model", NEW_MODELS)
def test_backup_price_map_matches_main(model: str) -> None:
main_cost: Final = json.loads(MAIN_PRICES.read_text())
backup_cost: Final = json.loads(BACKUP_PRICES.read_text())
assert backup_cost.get(model) == main_cost.get(model)
def test_sonnet_5_ships_standard_rates_not_introductory(local_model_cost_map: None) -> None:
sonnet_5: Final = _model_info("databricks/databricks-claude-sonnet-5")
sonnet_4_6: Final = _model_info("databricks/databricks-claude-sonnet-4-6")