mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
Merge pull request #40581 from BerriAI/litellm_registry_audit_2026_09_10
fix(model_prices): registry audit 2026-09-10, absorb open pricing PRs
This commit is contained in:
commit
c1a83fc005
5 changed files with 154 additions and 49 deletions
|
|
@ -157,9 +157,6 @@ class JinaAIRerankConfig(BaseRerankConfig):
|
|||
billed_units: RerankBilledUnits | None = None,
|
||||
model_info: ModelInfo | None = None,
|
||||
) -> tuple[float, float]:
|
||||
"""
|
||||
Jina AI reranker is priced at $0.000000018 per token.
|
||||
"""
|
||||
if (
|
||||
model_info is None
|
||||
or "input_cost_per_token" not in model_info
|
||||
|
|
|
|||
|
|
@ -30295,7 +30295,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": false,
|
||||
"supports_minimal_reasoning_effort": true
|
||||
"supports_minimal_reasoning_effort": false
|
||||
},
|
||||
"gpt-5.1-2025-11-13": {
|
||||
"cache_read_input_token_cost": 1.25e-07,
|
||||
|
|
@ -30340,7 +30340,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": false,
|
||||
"supports_minimal_reasoning_effort": true
|
||||
"supports_minimal_reasoning_effort": false
|
||||
},
|
||||
"gpt-5.1-chat-latest": {
|
||||
"cache_read_input_token_cost": 1.25e-07,
|
||||
|
|
@ -30432,7 +30432,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true
|
||||
"supports_minimal_reasoning_effort": false
|
||||
},
|
||||
"gpt-5.2-2025-12-11": {
|
||||
"cache_read_input_token_cost": 1.75e-07,
|
||||
|
|
@ -30478,7 +30478,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true
|
||||
"supports_minimal_reasoning_effort": false
|
||||
},
|
||||
"gpt-5.2-chat-latest": {
|
||||
"cache_read_input_token_cost": 1.75e-07,
|
||||
|
|
@ -31474,7 +31474,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": false,
|
||||
"input_cost_per_token_above_272k_tokens_flex": 2.5e-06,
|
||||
"output_cost_per_token_above_272k_tokens_flex": 1.125e-05,
|
||||
"cache_read_input_token_cost_above_272k_tokens_flex": 2.5e-07
|
||||
|
|
@ -31526,7 +31526,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": false,
|
||||
"input_cost_per_token_above_272k_tokens_flex": 2.5e-06,
|
||||
"output_cost_per_token_above_272k_tokens_flex": 1.125e-05,
|
||||
"cache_read_input_token_cost_above_272k_tokens_flex": 2.5e-07
|
||||
|
|
@ -31578,7 +31578,7 @@
|
|||
"supports_web_search": true,
|
||||
"supports_none_reasoning_effort": false,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": false,
|
||||
"input_cost_per_token_above_272k_tokens_flex": 3e-05,
|
||||
"output_cost_per_token_above_272k_tokens_flex": 0.000135
|
||||
},
|
||||
|
|
@ -31629,7 +31629,7 @@
|
|||
"supports_web_search": true,
|
||||
"supports_none_reasoning_effort": false,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": false,
|
||||
"input_cost_per_token_above_272k_tokens_flex": 3e-05,
|
||||
"output_cost_per_token_above_272k_tokens_flex": 0.000135
|
||||
},
|
||||
|
|
@ -33709,13 +33709,14 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"jina-reranker-v2-base-multilingual": {
|
||||
"input_cost_per_token": 1.8e-08,
|
||||
"input_cost_per_token": 5e-08,
|
||||
"litellm_provider": "jina_ai",
|
||||
"max_input_tokens": 1024,
|
||||
"max_output_tokens": 1024,
|
||||
"max_tokens": 1024,
|
||||
"mode": "rerank",
|
||||
"output_cost_per_token": 1.8e-08
|
||||
"output_cost_per_token": 0.0,
|
||||
"source": "https://api.jina.ai/v1/models"
|
||||
},
|
||||
"jp.anthropic.claude-sonnet-4-5-20250929-v1:0": {
|
||||
"cache_creation_input_token_cost": 4.125e-06,
|
||||
|
|
@ -39969,6 +39970,45 @@
|
|||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"openrouter/openai/gpt-5.6-sol": {
|
||||
"cache_creation_input_token_cost": 2.5e-06,
|
||||
"cache_creation_input_token_cost_above_272k_tokens": 5e-06,
|
||||
"cache_read_input_token_cost": 2e-07,
|
||||
"cache_read_input_token_cost_above_272k_tokens": 4e-07,
|
||||
"default_reasoning_effort": "medium",
|
||||
"input_cost_per_token": 2e-06,
|
||||
"input_cost_per_token_above_272k_tokens": 4e-06,
|
||||
"litellm_provider": "openrouter",
|
||||
"max_input_tokens": 1050000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1e-05,
|
||||
"output_cost_per_token_above_272k_tokens": 1.5e-05,
|
||||
"reasoning_effort_levels": [
|
||||
"none",
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
],
|
||||
"source": "https://openrouter.ai/openai/gpt-5.6-sol",
|
||||
"supported_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supported_output_modalities": [
|
||||
"text"
|
||||
],
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"openrouter/openai/gpt-oss-120b": {
|
||||
"input_cost_per_token": 3.7e-08,
|
||||
"litellm_provider": "openrouter",
|
||||
|
|
|
|||
|
|
@ -30295,7 +30295,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": false,
|
||||
"supports_minimal_reasoning_effort": true
|
||||
"supports_minimal_reasoning_effort": false
|
||||
},
|
||||
"gpt-5.1-2025-11-13": {
|
||||
"cache_read_input_token_cost": 1.25e-07,
|
||||
|
|
@ -30340,7 +30340,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": false,
|
||||
"supports_minimal_reasoning_effort": true
|
||||
"supports_minimal_reasoning_effort": false
|
||||
},
|
||||
"gpt-5.1-chat-latest": {
|
||||
"cache_read_input_token_cost": 1.25e-07,
|
||||
|
|
@ -30432,7 +30432,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true
|
||||
"supports_minimal_reasoning_effort": false
|
||||
},
|
||||
"gpt-5.2-2025-12-11": {
|
||||
"cache_read_input_token_cost": 1.75e-07,
|
||||
|
|
@ -30478,7 +30478,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true
|
||||
"supports_minimal_reasoning_effort": false
|
||||
},
|
||||
"gpt-5.2-chat-latest": {
|
||||
"cache_read_input_token_cost": 1.75e-07,
|
||||
|
|
@ -31474,7 +31474,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": false,
|
||||
"input_cost_per_token_above_272k_tokens_flex": 2.5e-06,
|
||||
"output_cost_per_token_above_272k_tokens_flex": 1.125e-05,
|
||||
"cache_read_input_token_cost_above_272k_tokens_flex": 2.5e-07
|
||||
|
|
@ -31526,7 +31526,7 @@
|
|||
"supports_none_reasoning_effort": true,
|
||||
"default_reasoning_effort": "none",
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": false,
|
||||
"input_cost_per_token_above_272k_tokens_flex": 2.5e-06,
|
||||
"output_cost_per_token_above_272k_tokens_flex": 1.125e-05,
|
||||
"cache_read_input_token_cost_above_272k_tokens_flex": 2.5e-07
|
||||
|
|
@ -31578,7 +31578,7 @@
|
|||
"supports_web_search": true,
|
||||
"supports_none_reasoning_effort": false,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": false,
|
||||
"input_cost_per_token_above_272k_tokens_flex": 3e-05,
|
||||
"output_cost_per_token_above_272k_tokens_flex": 0.000135
|
||||
},
|
||||
|
|
@ -31629,7 +31629,7 @@
|
|||
"supports_web_search": true,
|
||||
"supports_none_reasoning_effort": false,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": true,
|
||||
"supports_minimal_reasoning_effort": false,
|
||||
"input_cost_per_token_above_272k_tokens_flex": 3e-05,
|
||||
"output_cost_per_token_above_272k_tokens_flex": 0.000135
|
||||
},
|
||||
|
|
@ -33709,13 +33709,14 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"jina-reranker-v2-base-multilingual": {
|
||||
"input_cost_per_token": 1.8e-08,
|
||||
"input_cost_per_token": 5e-08,
|
||||
"litellm_provider": "jina_ai",
|
||||
"max_input_tokens": 1024,
|
||||
"max_output_tokens": 1024,
|
||||
"max_tokens": 1024,
|
||||
"mode": "rerank",
|
||||
"output_cost_per_token": 1.8e-08
|
||||
"output_cost_per_token": 0.0,
|
||||
"source": "https://api.jina.ai/v1/models"
|
||||
},
|
||||
"jp.anthropic.claude-sonnet-4-5-20250929-v1:0": {
|
||||
"cache_creation_input_token_cost": 4.125e-06,
|
||||
|
|
@ -39969,6 +39970,45 @@
|
|||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"openrouter/openai/gpt-5.6-sol": {
|
||||
"cache_creation_input_token_cost": 2.5e-06,
|
||||
"cache_creation_input_token_cost_above_272k_tokens": 5e-06,
|
||||
"cache_read_input_token_cost": 2e-07,
|
||||
"cache_read_input_token_cost_above_272k_tokens": 4e-07,
|
||||
"default_reasoning_effort": "medium",
|
||||
"input_cost_per_token": 2e-06,
|
||||
"input_cost_per_token_above_272k_tokens": 4e-06,
|
||||
"litellm_provider": "openrouter",
|
||||
"max_input_tokens": 1050000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1e-05,
|
||||
"output_cost_per_token_above_272k_tokens": 1.5e-05,
|
||||
"reasoning_effort_levels": [
|
||||
"none",
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
],
|
||||
"source": "https://openrouter.ai/openai/gpt-5.6-sol",
|
||||
"supported_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supported_output_modalities": [
|
||||
"text"
|
||||
],
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"openrouter/openai/gpt-oss-120b": {
|
||||
"input_cost_per_token": 3.7e-08,
|
||||
"litellm_provider": "openrouter",
|
||||
|
|
|
|||
|
|
@ -276,6 +276,17 @@ def test_gpt5_drops_reasoning_effort_xhigh_when_requested(config: OpenAIConfig):
|
|||
assert "reasoning_effort" not in params
|
||||
|
||||
|
||||
def test_gpt5_1_gpt5_2_gpt5_4_drop_minimal_reasoning_effort(config: OpenAIConfig):
|
||||
for model in ("gpt-5.1", "gpt-5.2", "gpt-5.4", "gpt-5.4-pro"):
|
||||
params = config.map_openai_params(
|
||||
non_default_params={"reasoning_effort": "minimal"},
|
||||
optional_params={},
|
||||
model=model,
|
||||
drop_params=True,
|
||||
)
|
||||
assert "reasoning_effort" not in params
|
||||
|
||||
|
||||
# GPT-5.1 temperature handling tests
|
||||
def test_gpt5_1_model_detection(gpt5_config: OpenAIGPT5Config):
|
||||
"""Test that models supporting reasoning_effort='none' are correctly detected via model map."""
|
||||
|
|
@ -388,26 +399,26 @@ def test_gpt5_4_mini_allows_reasoning_effort_none(config: OpenAIConfig):
|
|||
assert params["reasoning_effort"] == "none"
|
||||
|
||||
|
||||
def test_gpt5_4_allows_reasoning_effort_minimal(config: OpenAIConfig):
|
||||
"""gpt-5.4 supports reasoning_effort='minimal'."""
|
||||
params = config.map_openai_params(
|
||||
non_default_params={"reasoning_effort": "minimal"},
|
||||
optional_params={},
|
||||
model="gpt-5.4",
|
||||
drop_params=False,
|
||||
)
|
||||
assert params["reasoning_effort"] == "minimal"
|
||||
def test_gpt5_4_rejects_reasoning_effort_minimal(config: OpenAIConfig):
|
||||
"""gpt-5.4 rejects reasoning_effort='minimal'."""
|
||||
with pytest.raises(litellm.utils.UnsupportedParamsError):
|
||||
config.map_openai_params(
|
||||
non_default_params={"reasoning_effort": "minimal"},
|
||||
optional_params={},
|
||||
model="gpt-5.4",
|
||||
drop_params=False,
|
||||
)
|
||||
|
||||
|
||||
def test_gpt5_4_pro_allows_reasoning_effort_minimal(config: OpenAIConfig):
|
||||
"""gpt-5.4-pro supports reasoning_effort='minimal'."""
|
||||
params = config.map_openai_params(
|
||||
non_default_params={"reasoning_effort": "minimal"},
|
||||
optional_params={},
|
||||
model="gpt-5.4-pro",
|
||||
drop_params=False,
|
||||
)
|
||||
assert params["reasoning_effort"] == "minimal"
|
||||
def test_gpt5_4_pro_rejects_reasoning_effort_minimal(config: OpenAIConfig):
|
||||
"""gpt-5.4-pro rejects reasoning_effort='minimal'."""
|
||||
with pytest.raises(litellm.utils.UnsupportedParamsError):
|
||||
config.map_openai_params(
|
||||
non_default_params={"reasoning_effort": "minimal"},
|
||||
optional_params={},
|
||||
model="gpt-5.4-pro",
|
||||
drop_params=False,
|
||||
)
|
||||
|
||||
|
||||
def test_gpt5_4_mini_rejects_reasoning_effort_minimal(config: OpenAIConfig):
|
||||
|
|
@ -468,13 +479,13 @@ def test_gpt5_minimal_dict_triggers_validation(config: OpenAIConfig):
|
|||
|
||||
|
||||
def test_gpt5_minimal_dict_accepted_for_supported_model(config: OpenAIConfig):
|
||||
"""Dict with effort='minimal' passes through for gpt-5.4+."""
|
||||
"""Dict with effort='minimal' passes through for gpt-5."""
|
||||
params = config.map_openai_params(
|
||||
non_default_params={
|
||||
"reasoning_effort": {"effort": "minimal", "summary": "detailed"}
|
||||
},
|
||||
optional_params={},
|
||||
model="gpt-5.4",
|
||||
model="gpt-5",
|
||||
drop_params=False,
|
||||
)
|
||||
assert params["reasoning_effort"] == "minimal"
|
||||
|
|
@ -482,8 +493,8 @@ def test_gpt5_minimal_dict_accepted_for_supported_model(config: OpenAIConfig):
|
|||
|
||||
def test_gpt5_supports_reasoning_effort_level_minimal(gpt5_config: OpenAIGPT5Config):
|
||||
"""Test that _supports_reasoning_effort_level correctly identifies minimal support."""
|
||||
assert gpt5_config._supports_reasoning_effort_level("gpt-5.4", "minimal")
|
||||
assert gpt5_config._supports_reasoning_effort_level("gpt-5.4-pro", "minimal")
|
||||
assert not gpt5_config._supports_reasoning_effort_level("gpt-5.4", "minimal")
|
||||
assert not gpt5_config._supports_reasoning_effort_level("gpt-5.4-pro", "minimal")
|
||||
assert not gpt5_config._supports_reasoning_effort_level("gpt-5.4-mini", "minimal")
|
||||
assert not gpt5_config._supports_reasoning_effort_level("gpt-5.4-nano", "minimal")
|
||||
|
||||
|
|
@ -504,10 +515,10 @@ def test_gpt5_minimal_explicitly_disabled_check(gpt5_config: OpenAIGPT5Config):
|
|||
assert gpt5_config._is_reasoning_effort_level_explicitly_disabled(
|
||||
"openai/gpt-5.4-mini", "minimal"
|
||||
)
|
||||
assert not gpt5_config._is_reasoning_effort_level_explicitly_disabled(
|
||||
assert gpt5_config._is_reasoning_effort_level_explicitly_disabled(
|
||||
"gpt-5.4", "minimal"
|
||||
)
|
||||
assert not gpt5_config._is_reasoning_effort_level_explicitly_disabled(
|
||||
assert gpt5_config._is_reasoning_effort_level_explicitly_disabled(
|
||||
"gpt-5.4-pro", "minimal"
|
||||
)
|
||||
|
||||
|
|
@ -523,8 +534,8 @@ def test_is_explicitly_disabled_factory_minimal():
|
|||
assert _is_explicitly_disabled_factory("gpt-5.4-mini", None, key)
|
||||
assert _is_explicitly_disabled_factory("gpt-5.4-nano", None, key)
|
||||
assert _is_explicitly_disabled_factory("openai/gpt-5.4-mini", None, key)
|
||||
assert not _is_explicitly_disabled_factory("gpt-5.4", None, key)
|
||||
assert not _is_explicitly_disabled_factory("gpt-5.4-pro", None, key)
|
||||
assert _is_explicitly_disabled_factory("gpt-5.4", None, key)
|
||||
assert _is_explicitly_disabled_factory("gpt-5.4-pro", None, key)
|
||||
assert not _is_explicitly_disabled_factory("gpt-5.4-turbo-preview", None, key)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ from litellm.cost_calculator import (
|
|||
response_cost_calculator,
|
||||
)
|
||||
from litellm.types.llms.openai import OpenAIRealtimeStreamList
|
||||
from litellm.types.rerank import RerankResponse
|
||||
from litellm.types.utils import (
|
||||
CacheCreationTokenDetails,
|
||||
ModelInfo,
|
||||
|
|
@ -128,6 +129,22 @@ def test_completion_cost_uses_response_model_for_dynamic_routing(_local_model_co
|
|||
assert cost > 0, "Cost should be calculated using response model"
|
||||
|
||||
|
||||
def test_jina_rerank_bills_total_tokens_at_input_rate_only(_local_model_cost_map):
|
||||
response: Final = RerankResponse(
|
||||
id="rerank-1",
|
||||
results=[{"index": 0, "relevance_score": 0.9}],
|
||||
meta={"billed_units": {"total_tokens": 1000}},
|
||||
)
|
||||
|
||||
cost: Final = completion_cost(
|
||||
completion_response=response,
|
||||
model="jina_ai/jina-reranker-v2-base-multilingual",
|
||||
call_type="rerank",
|
||||
)
|
||||
|
||||
assert cost == pytest.approx(1000 * 5e-08)
|
||||
|
||||
|
||||
def test_cost_calculator_with_response_cost_in_additional_headers():
|
||||
class MockResponse(BaseModel):
|
||||
_hidden_params = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue