Merge pull request #41112 from BerriAI/litellm_registry_audit_2026_09_14

fix(models): rolling registry audit: Gemini latest aliases, Nova cache pricing, OpenRouter/Together sync, Mistral GLM 5.3, Azure snapshots, Grok caching
This commit is contained in:
Mateo Wang 2026-09-16 14:31:50 -07:00 committed by GitHub
commit 6edb549dbd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 2105 additions and 372 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -5,12 +5,15 @@ from typing import NamedTuple
import pytest
import litellm
from litellm.cost_calculator import completion_cost
from litellm.llms.bedrock.chat.converse_transformation import AmazonConverseConfig
from litellm.llms.bedrock.common_utils import BedrockModelInfo
from litellm.types.utils import (
Choices,
Message,
ModelResponse,
PromptTokensDetailsWrapper,
Usage,
)
@ -152,3 +155,55 @@ def test_bedrock_gpt_5_6_offers_tools_and_reasoning_effort_but_not_thinking(prof
assert "reasoning_effort" in supported
assert "thinking" not in supported
assert "output_config" not in supported
# Cache-read prices are the `*-cache-read-input-tokens` usagetype rows of the AWS Price List API, us-east-1,
# https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonBedrock/current/us-east-1/index.json on 2026-09-15
@pytest.mark.parametrize(
"model,expected_cache_read",
[
("amazon.nova-lite-v1:0", 1.5e-8),
("us.amazon.nova-lite-v1:0", 1.5e-8),
("amazon.nova-micro-v1:0", 8.75e-9),
("us.amazon.nova-micro-v1:0", 8.75e-9),
("amazon.nova-pro-v1:0", 2e-7),
("us.amazon.nova-pro-v1:0", 2e-7),
("us.amazon.nova-premier-v1:0", 6.25e-7),
],
)
def test_bedrock_nova_cache_read_prices(
model, expected_cache_read, local_model_cost_map
):
model_info = litellm.model_cost[model]
assert model_info["cache_read_input_token_cost"] == expected_cache_read
usage = Usage(
prompt_tokens=1_000,
completion_tokens=100,
total_tokens=1_100,
prompt_tokens_details=PromptTokensDetailsWrapper(cached_tokens=400),
)
response = _bedrock_response(model, usage)
cost = completion_cost(
completion_response=response,
model=model,
custom_llm_provider="bedrock",
)
expected_cost = (
600 * model_info["input_cost_per_token"]
+ 400 * expected_cache_read
+ 100 * model_info["output_cost_per_token"]
)
assert cost == pytest.approx(expected_cost)
uncached_usage = Usage(
prompt_tokens=1_000,
completion_tokens=100,
total_tokens=1_100,
)
uncached_cost = completion_cost(
completion_response=_bedrock_response(model, uncached_usage),
model=model,
custom_llm_provider="bedrock",
)
assert cost < uncached_cost

View file

@ -1,8 +1,7 @@
import os
import pytest
import litellm
from litellm.cost_calculator import completion_cost
from litellm.llms.gemini.cost_calculator import (
cost_per_google_maps_grounding_request,
cost_per_web_search_request,
@ -18,6 +17,7 @@ from litellm.types.utils import (
ImageResponse,
ImageUsage,
ImageUsageInputTokensDetails,
ModelResponse,
PromptTokensDetailsWrapper,
Usage,
)
@ -452,6 +452,42 @@ def test_map_traffic_type_to_service_tier(
)
# Alias targets are the `modelVersion` returned by
# POST https://generativelanguage.googleapis.com/v1beta/models/<alias>:generateContent on 2026-09-15
@pytest.mark.parametrize(
"alias,target",
[
("gemini/gemini-flash-latest", "gemini/gemini-3.8-flash"),
("gemini/gemini-flash-lite-latest", "gemini/gemini-3.5-flash-lite"),
("gemini/gemini-pro-latest", "gemini/gemini-3.1-pro-preview"),
],
)
def test_latest_aliases_cost_the_same_as_their_current_target(
monkeypatch, alias, target
):
monkeypatch.setenv("LITELLM_LOCAL_MODEL_COST_MAP", "True")
monkeypatch.setattr(litellm, "model_cost", litellm.get_model_cost_map(url=""))
usage = Usage(
prompt_tokens=1_000,
completion_tokens=500,
total_tokens=1_500,
prompt_tokens_details=PromptTokensDetailsWrapper(cached_tokens=400),
)
def cost_of(model: str) -> float:
return completion_cost(
completion_response=ModelResponse(model=model, usage=usage),
model=model,
custom_llm_provider="gemini",
)
alias_cost = cost_of(alias)
target_cost = cost_of(target)
assert alias_cost == pytest.approx(target_cost)
assert alias_cost > 0
@pytest.mark.parametrize(
"prefixed,bare",
[

View file

@ -0,0 +1,38 @@
from typing import Final
import pytest
import litellm
from litellm import get_model_info
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
from litellm.utils import supports_prompt_caching
MODEL: Final = "vertex_ai/xai/grok-4.6"
GROK_KEY_PREFIXES: Final = ("vertex_ai/xai/grok-", "azure_ai/grok-", "xai/grok-")
@pytest.mark.usefixtures("local_model_cost_map")
def test_grok_models_with_cache_read_price_advertise_prompt_caching() -> None:
cached_grok_models = tuple(
key
for key, entry in litellm.model_cost.items()
if key.startswith(GROK_KEY_PREFIXES) and entry.get("cache_read_input_token_cost")
)
assert cached_grok_models, "expected at least one grok model with a cache read price"
missing_flag = tuple(key for key in cached_grok_models if supports_prompt_caching(model=key) is not True)
assert missing_flag == (), (
f"grok models with cache_read_input_token_cost fail supports_prompt_caching: {missing_flag}"
)
@pytest.mark.usefixtures("local_model_cost_map")
def test_vertex_ai_grok_4_6_supports_prompt_caching_via_get_model_info() -> None:
routed_model, provider, _, _ = get_llm_provider(model=MODEL)
assert (routed_model, provider) == ("xai/grok-4.6", "vertex_ai")
info = get_model_info(model=routed_model, custom_llm_provider=provider)
assert info["litellm_provider"] == "vertex_ai"
assert info.get("supports_prompt_caching") is True
assert supports_prompt_caching(model=MODEL) is True