fix(databricks): enable vision on fable-5 and pin every cache rate to published DBU

databricks-claude-fable-5 was the only fable-5 entry in the registry
declaring supports_vision false, and the only one of the five new
entries to do so.

Only the five new models were pinned against the published DBU table,
so the 26 cache literals added to pre-existing entries were checked by
nothing independent. Extend the table to all 33 entries carrying cache
rates and assert both cache fields against it for the 31 that take the
published rates, leaving the two older-vintage gemini-2-5 entries to
their existing guard.

Also widen the cache-declaration guard to both cache fields, and
replace the single-model equals-input assertion with one that covers
all 14 entries publishing no cache rates.
This commit is contained in:
mateo-berri 2026-08-22 17:30:10 -07:00
parent 0a869b7226
commit 112224a7fe
3 changed files with 68 additions and 16 deletions

View file

@ -14614,7 +14614,7 @@
"supports_reasoning": true,
"supports_sampling_params": false,
"supports_tool_choice": true,
"supports_vision": false,
"supports_vision": true,
"thinking_always_on": true
},
"databricks/databricks-claude-haiku-4-5": {

View file

@ -14614,7 +14614,7 @@
"supports_reasoning": true,
"supports_sampling_params": false,
"supports_tool_choice": true,
"supports_vision": false,
"supports_vision": true,
"thinking_always_on": true
},
"databricks/databricks-claude-haiku-4-5": {

View file

@ -28,12 +28,45 @@ PRICE_FIELDS: Final = (
"cache_read_input_token_cost",
)
PUBLISHED_DBU_PER_MILLION: Final = {
"databricks/databricks-claude-opus-4-7": ("71.429", "357.143", "89.286", "7.143"),
"databricks/databricks-claude-opus-4-8": ("71.429", "357.143", "89.286", "7.143"),
"databricks/databricks-claude-opus-5": ("71.429", "357.143", "89.286", "7.143"),
"databricks/databricks-claude-sonnet-5": ("42.857", "214.286", "53.571", "4.286"),
"databricks/databricks-claude-fable-5": ("142.858", "714.286", "178.572", "14.286"),
"databricks/databricks-claude-opus-5": ("71.429", "357.143", "89.286", "7.143"),
"databricks/databricks-claude-opus-4-8": ("71.429", "357.143", "89.286", "7.143"),
"databricks/databricks-claude-opus-4-7": ("71.429", "357.143", "89.286", "7.143"),
"databricks/databricks-claude-opus-4-6": ("71.429", "357.143", "89.286", "7.143"),
"databricks/databricks-claude-opus-4-5": ("71.429", "357.143", "89.286", "7.143"),
"databricks/databricks-claude-opus-4-1": ("214.286", "1071.429", "267.857", "21.429"),
"databricks/databricks-claude-opus-4": ("214.286", "1071.429", "267.857", "21.429"),
"databricks/databricks-claude-sonnet-5": ("42.857", "214.286", "53.571", "4.286"),
"databricks/databricks-claude-sonnet-4-6": ("42.857", "214.286", "53.571", "4.286"),
"databricks/databricks-claude-sonnet-4-5": ("42.857", "214.286", "53.571", "4.286"),
"databricks/databricks-claude-sonnet-4-1": ("42.857", "214.286", "53.571", "4.286"),
"databricks/databricks-claude-sonnet-4": ("42.857", "214.286", "53.571", "4.286"),
"databricks/databricks-claude-3-7-sonnet": ("42.857", "214.286", "53.571", "4.286"),
"databricks/databricks-claude-haiku-4-5": ("14.286", "71.429", "17.857", "1.429"),
"databricks/databricks-gpt-5": ("17.857", "142.857", "17.857", "1.786"),
"databricks/databricks-gpt-5-1": ("17.857", "142.857", "17.857", "1.786"),
"databricks/databricks-gpt-5-1-codex-max": ("17.857", "142.857", "17.857", "1.786"),
"databricks/databricks-gpt-5-1-codex-mini": ("3.571", "28.571", "3.571", "0.357"),
"databricks/databricks-gpt-5-mini": ("3.571", "28.571", "3.571", "0.357"),
"databricks/databricks-gpt-5-nano": ("0.714", "5.714", "0.714", "0.071"),
"databricks/databricks-gpt-5-2": ("25.000", "200.000", "25.000", "2.500"),
"databricks/databricks-gpt-5-2-codex": ("25.000", "200.000", "25.000", "2.500"),
"databricks/databricks-gpt-5-3-codex": ("25.000", "200.000", "25.000", "2.500"),
"databricks/databricks-gpt-5-4": ("35.714", "214.286", "35.714", "3.571"),
"databricks/databricks-gpt-5-4-mini": ("10.714", "64.286", "10.714", "1.071"),
"databricks/databricks-gpt-5-4-nano": ("2.857", "17.857", "2.857", "0.286"),
"databricks/databricks-gemini-3-1-pro": ("35.714", "214.286", "35.714", "3.571"),
"databricks/databricks-gemini-3-pro": ("35.714", "214.286", "35.714", "3.571"),
"databricks/databricks-gemini-3-flash": ("8.929", "53.571", "8.929", "0.893"),
"databricks/databricks-gemini-3-1-flash-lite": ("4.464", "26.786", "4.464", "0.446"),
"databricks/databricks-gemini-2-5-pro": ("22.321", "178.571", "22.321", "2.232"),
"databricks/databricks-gemini-2-5-flash": ("5.357", "44.643", "5.357", "0.536"),
}
OLDER_VINTAGE_MODELS: Final = (
"databricks/databricks-gemini-2-5-pro",
"databricks/databricks-gemini-2-5-flash",
)
CACHE_FIELDS: Final = ("cache_creation_input_token_cost", "cache_read_input_token_cost")
def _model_info(model: str) -> ModelInfo:
@ -102,6 +135,15 @@ def test_new_models_price_at_published_dbu_rates(local_model_cost_map: None, mod
assert info[field] == _dollars_per_token(dbu_per_million), field
@pytest.mark.parametrize("model", sorted(set(PUBLISHED_DBU_PER_MILLION) - set(OLDER_VINTAGE_MODELS)))
def test_cache_rates_derive_from_published_cache_dbu(local_model_cost_map: None, model: str) -> None:
info: Final = _model_info(model)
cache_dbu_per_million: Final = PUBLISHED_DBU_PER_MILLION[model][2:]
for field, dbu_per_million in zip(CACHE_FIELDS, cache_dbu_per_million):
assert info[field] == _dollars_per_token(dbu_per_million), field
@pytest.mark.parametrize("model", NEW_MODELS)
def test_new_models_carry_cache_pricing(local_model_cost_map: None, model: str) -> None:
info: Final = _model_info(model)
@ -119,7 +161,7 @@ def test_every_priced_databricks_model_declares_cache_rates(local_model_cost_map
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
and any(info.get(field) is None for field in CACHE_FIELDS)
]
assert undeclared == []
@ -139,12 +181,28 @@ def test_models_without_a_cache_discount_bill_cache_tokens_at_the_input_rate(
prompt_cost, _ = cost_per_token(model=model, usage=usage)
assert info["cache_read_input_token_cost"] == info["input_cost_per_token"]
assert info["cache_creation_input_token_cost"] == info["input_cost_per_token"]
assert prompt_cost == pytest.approx(10000 * info["input_cost_per_token"])
assert prompt_cost > 8000 * info["input_cost_per_token"]
def test_every_model_without_published_cache_dbu_bills_cache_at_its_own_input_rate(
local_model_cost_map: None,
) -> None:
without_published_rates: Final = [
model
for model, info in litellm.model_cost.items()
if model.startswith("databricks/")
and info.get("input_cost_per_token")
and model not in PUBLISHED_DBU_PER_MILLION
]
assert len(without_published_rates) == 14
for model in without_published_rates:
info = _model_info(model)
for field in CACHE_FIELDS:
assert info[field] == pytest.approx(info["input_cost_per_token"]), (model, field)
@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())
@ -163,13 +221,7 @@ def test_sonnet_5_ships_standard_rates_not_introductory(local_model_cost_map: No
assert sonnet_5[field] == pytest.approx(sonnet_4_6[field]), field
@pytest.mark.parametrize(
"model",
[
"databricks/databricks-gemini-2-5-pro",
"databricks/databricks-gemini-2-5-flash",
],
)
@pytest.mark.parametrize("model", OLDER_VINTAGE_MODELS)
def test_entries_priced_at_an_older_vintage_keep_cache_rates_tied_to_their_own_input(
local_model_cost_map: None,
model: str,