This commit is contained in:
devin-ai-integration[bot] 2026-08-26 19:23:32 +00:00 committed by GitHub
commit 8702ff0559
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 5108 additions and 356 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -59,17 +59,17 @@ class GptProfile(NamedTuple):
GPT_5_6_PROFILES = [
GptProfile(
model_id="us.openai.gpt-5.6-sol",
input_cost=5.5e-06, input_cost_above_272k=1.1e-05,
cache_write=6.875e-06, cache_write_above_272k=1.375e-05,
cache_read=5.5e-07, cache_read_above_272k=1.1e-06,
output_cost=3.3e-05, output_cost_above_272k=4.95e-05,
input_cost=4.4e-06, input_cost_above_272k=8.8e-06,
cache_write=5.5e-06, cache_write_above_272k=1.1e-05,
cache_read=4.4e-07, cache_read_above_272k=8.8e-07,
output_cost=2.2e-05, output_cost_above_272k=3.3e-05,
),
GptProfile(
model_id="global.openai.gpt-5.6-sol",
input_cost=5e-06, input_cost_above_272k=1e-05,
cache_write=6.25e-06, cache_write_above_272k=1.25e-05,
cache_read=5e-07, cache_read_above_272k=1e-06,
output_cost=3e-05, output_cost_above_272k=4.5e-05,
input_cost=4e-06, input_cost_above_272k=8e-06,
cache_write=5e-06, cache_write_above_272k=1e-05,
cache_read=4e-07, cache_read_above_272k=8e-07,
output_cost=2e-05, output_cost_above_272k=3e-05,
),
GptProfile(
model_id="us.openai.gpt-5.6-terra",
@ -221,7 +221,7 @@ def test_bedrock_gpt_5_6_above_272k_tier_applies_to_cost(local_model_cost_map):
custom_llm_provider="bedrock",
)
assert cost == pytest.approx((300000 * 1.1e-05) + (1000 * 4.95e-05), rel=1e-9)
assert cost == pytest.approx((300000 * 8.8e-06) + (1000 * 3.3e-05), rel=1e-9)
def test_bedrock_gpt_5_6_bills_cache_read_tokens(local_model_cost_map):
@ -241,10 +241,10 @@ def test_bedrock_gpt_5_6_bills_cache_read_tokens(local_model_cost_map):
custom_llm_provider="bedrock",
)
expected = (2 * 5.5e-06) + (15609 * 5.5e-07) + (5 * 3.3e-05)
expected = (2 * 4.4e-06) + (15609 * 4.4e-07) + (5 * 2.2e-05)
assert cost == pytest.approx(expected, rel=1e-9)
# Without cache_read_input_token_cost the cached prefix bills at zero.
assert cost > (15611 * 5.5e-06) * 0.1
assert cost > (15611 * 4.4e-06) * 0.1
def test_bedrock_gpt_5_6_bills_cache_write_tokens(local_model_cost_map):
@ -263,7 +263,7 @@ def test_bedrock_gpt_5_6_bills_cache_write_tokens(local_model_cost_map):
custom_llm_provider="bedrock",
)
expected = (2 * 5.5e-06) + (15609 * 6.875e-06) + (5 * 3.3e-05)
expected = (2 * 4.4e-06) + (15609 * 5.5e-06) + (5 * 2.2e-05)
assert cost == pytest.approx(expected, rel=1e-9)

View file

@ -1683,10 +1683,19 @@ class TestBedrockMantleResponsesPricing:
assert info["cache_read_input_token_cost"] == pytest.approx(2.75e-07)
assert info["max_input_tokens"] == 1050000
def test_gpt_5_6_cyber_pricing_and_mode(self, local_cost_map):
info = litellm.get_model_info("bedrock_mantle/openai.gpt-5.6-cyber")
assert info["mode"] == "responses"
assert info["input_cost_per_token"] == pytest.approx(1.375e-05)
assert info["cache_creation_input_token_cost"] == pytest.approx(1.71875e-05)
assert info["cache_read_input_token_cost"] == pytest.approx(1.375e-06)
assert info["output_cost_per_token"] == pytest.approx(8.25e-05)
assert info["max_input_tokens"] == 272000
@pytest.mark.parametrize(
"model, input_cost, cache_creation_cost, cache_read_cost, output_cost",
[
("openai.gpt-5.6-sol", 5.5e-06, 6.875e-06, 5.5e-07, 3.3e-05),
("openai.gpt-5.6-sol", 4.4e-06, 5.5e-06, 4.4e-07, 2.2e-05),
("openai.gpt-5.6-terra", 2.2e-06, 2.75e-06, 2.2e-07, 1.32e-05),
("openai.gpt-5.6-luna", 2.2e-07, 2.75e-07, 2.2e-08, 1.32e-06),
],
@ -1709,7 +1718,7 @@ class TestBedrockMantleResponsesPricing:
@pytest.mark.parametrize(
"model, input_cost, output_cost",
[
("openai.gpt-5.6-sol", 5.5e-06, 3.3e-05),
("openai.gpt-5.6-sol", 4.4e-06, 2.2e-05),
("openai.gpt-5.6-terra", 2.2e-06, 1.32e-05),
("openai.gpt-5.6-luna", 2.2e-07, 1.32e-06),
],

View file

@ -87,3 +87,56 @@ def test_anthropic_sonnet_1hr_cache_write_pricing(
), f"{model_key}: long-context 1hr/5min ratio is {ratio_lc}, expected 1.6"
else:
assert "cache_creation_input_token_cost_above_1hr_above_200k_tokens" not in info
CLAUDE_3_EXPECTED = [
("claude-3-haiku-20240307", 5e-07),
("claude-3-opus-20240229", 3e-05),
]
@pytest.mark.parametrize("model_key, expected_1hr", CLAUDE_3_EXPECTED)
def test_claude_3_1hr_cache_write_pricing(model_data, model_key, expected_1hr):
"""Haiku 3 and Opus 3 both carried Sonnet's 6e-06 1hr rate, overbilling Haiku 3
1-hour cache writes 12x and underbilling Opus 3 5x."""
info = model_data[model_key]
assert info["cache_creation_input_token_cost_above_1hr"] == expected_1hr
@pytest.mark.parametrize("model_key, expected_1hr", CLAUDE_3_EXPECTED)
def test_backup_matches_main_for_claude_3_1hr_cache_write(model_key, expected_1hr):
json_path = os.path.join(
os.path.dirname(__file__),
"../../litellm/model_prices_and_context_window_backup.json",
)
with open(json_path) as f:
backup = json.load(f)
assert (
backup[model_key]["cache_creation_input_token_cost_above_1hr"] == expected_1hr
)
def test_first_party_anthropic_1hr_cache_writes_are_2x_base_input(model_data):
"""Anthropic charges 1-hour cache writes at 2x base input for every first-party
model, so any entry that drifts off that multiple is a copy-paste error."""
offenders = tuple(
(
model_key,
info["input_cost_per_token"],
info["cache_creation_input_token_cost_above_1hr"],
)
for model_key, info in model_data.items()
if isinstance(info, dict)
and info.get("litellm_provider") == "anthropic"
and info.get("input_cost_per_token")
and info.get("cache_creation_input_token_cost_above_1hr")
and abs(
info["cache_creation_input_token_cost_above_1hr"]
- 2 * info["input_cost_per_token"]
)
> 1e-12
)
assert offenders == (), f"1hr cache write is not 2x base input for: {offenders}"

View file

@ -0,0 +1,86 @@
"""
Validate the Fireworks AI Serverless entry added for #37274 exists in
`model_prices_and_context_window.json` and that the bare Fireworks model ID
resolves through `get_model_info`.
Pricing as published at https://docs.fireworks.ai/serverless/pricing
(USD per 1M tokens, uncached input / cached input / output):
accounts/fireworks/models/deepseek-v4-pro-0813 -> $1.32 / $0.044 / $3.96
"""
import json
import os
import pytest
import litellm
from litellm.utils import get_model_info
@pytest.fixture(scope="module", autouse=True)
def _local_model_cost_map():
"""
Point litellm at the bundled cost map for the duration of this module
only. ``mp.undo()`` restores both the environment variable and
``litellm.model_cost`` so nothing leaks into later tests.
"""
mp = pytest.MonkeyPatch()
mp.setenv("LITELLM_LOCAL_MODEL_COST_MAP", "True")
mp.setattr(litellm, "model_cost", litellm.get_model_cost_map(url=""))
get_model_info.cache_clear()
yield
mp.undo()
get_model_info.cache_clear()
NEW_ENTRIES = {
"fireworks_ai/accounts/fireworks/models/deepseek-v4-pro-0813": {
"input_cost_per_token": 1.32e-06,
"cache_read_input_token_cost": 4.4e-08,
"output_cost_per_token": 3.96e-06,
"max_input_tokens": 1048576,
"max_output_tokens": 131072,
},
}
@pytest.fixture(scope="module")
def model_data():
json_path = os.path.join(
os.path.dirname(__file__), "../../model_prices_and_context_window.json"
)
with open(json_path) as f:
return json.load(f)
def test_fireworks_serverless_entries_exist(model_data):
"""The new prefixed entry carries the pricing and metadata from #37274."""
for key, expected in NEW_ENTRIES.items():
assert key in model_data, f"{key} is missing from model_prices_and_context_window.json"
entry = model_data[key]
for field, value in expected.items():
assert entry[field] == pytest.approx(value), f"{key}.{field}"
assert entry["litellm_provider"] == "fireworks_ai"
assert entry["mode"] == "chat"
assert entry["supports_function_calling"] is True
assert entry["supports_vision"] is False
def test_bare_fireworks_ids_resolve_through_prefixed_entries():
"""Bare IDs from #37274 resolve via the provider-prefix lookup path."""
for bare_id, prefixed_key in [
(
"accounts/fireworks/models/deepseek-v4-pro-0813",
"fireworks_ai/accounts/fireworks/models/deepseek-v4-pro-0813",
),
]:
info = get_model_info(model=bare_id, custom_llm_provider="fireworks_ai")
expected = NEW_ENTRIES[prefixed_key]
assert info.get("key") == prefixed_key
assert info["litellm_provider"] == "fireworks_ai"
assert info["input_cost_per_token"] == pytest.approx(expected["input_cost_per_token"])
assert info["cache_read_input_token_cost"] == pytest.approx(expected["cache_read_input_token_cost"])
assert info["output_cost_per_token"] == pytest.approx(expected["output_cost_per_token"])
assert info["max_input_tokens"] == expected["max_input_tokens"]
assert info["max_output_tokens"] == expected["max_output_tokens"]

View file

@ -31,16 +31,16 @@ SERVERLESS_CHAT_MODELS: Final = (
"together_ai/meta-models/Muse-Glimmer-30B",
"together_ai/google/gemma-4-31B-it",
"together_ai/pearl-ai/gemma-4-31b-it",
"together_ai/google/gemma-3n-E4B-it",
"together_ai/arize-ai/qwen-2-1.5b-instruct",
"together_ai/Prism-ML/Ternary-Bonsai-27B",
"together_ai/meta-llama/Llama-Guard-4-12B",
"together_ai/openai/gpt-oss-120b",
"together_ai/openai/gpt-oss-20b",
"together_ai/meta-llama/Llama-3.3-70B-Instruct-Turbo",
)
DEPRECATED_MODELS: Final = {
"together_ai/google/gemma-3n-E4B-it": "2026-08-25",
"together_ai/meta-llama/Llama-Guard-4-12B": "2026-08-25",
"together_ai/Qwen/Qwen3-235B-A22B-Instruct-2507-tput": "2026-07-10",
"together_ai/Qwen/Qwen3.5-397B-A17B": "2026-06-29",
"together_ai/Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8": "2026-06-04",