feat: add claude mythos 5.2 to vertex ai cost map (#50940)

* Add Claude Mythos 5.2 to Vertex AI cost map

Copies the vertex_ai/claude-fable-5-2 and @default rows as
vertex_ai/claude-mythos-5-2 and @default. Anthropic's Mythos 5.2 model
page lists Google Cloud as a platform and says it has the same
specifications and pricing as Fable 5.2, and Google publishes no Mythos
row yet, so the new rows cite Anthropic's page as their source.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Bill Mythos 5.2 on Vertex through the cost path in tests

Adds cost_per_token checks with cache reads, 5m and 1h cache writes and
the regional uplift so the Vertex Mythos 5.2 rows are proven to charge
what Fable 5.2 charges, and annotates the new test locals with Final.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Read the regional_endpoint_uplift_multiplier key in the Vertex Mythos uplift test

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Kerry Lu 2026-11-10 09:35:37 -08:00 • committed by GitHub
parent 1035971a05
commit 0b070d25d3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 253 additions and 0 deletions

View file

@ -53236,6 +53236,47 @@
"output_cost_per_token_batches": 2e-05,
"source": "https://cloud.google.com/gemini-enterprise-agent-platform/generative-ai/pricing"
},
"vertex_ai/claude-mythos-5-2": {
"regional_endpoint_uplift_multiplier": 1.1,
"supports_mid_conversation_system": true,
"cache_creation_input_token_cost": 1e-05,
"cache_creation_input_token_cost_above_1hr": 1.6e-05,
"cache_creation_input_token_cost_batches": 5e-06,
"cache_read_input_token_cost": 2e-07,
"cache_read_input_token_cost_batches": 1e-07,
"input_cost_per_token": 8e-06,
"litellm_provider": "vertex_ai-anthropic_models",
"max_input_tokens": 1000000,
"max_output_tokens": 128000,
"mode": "chat",
"output_cost_per_token": 4e-05,
"search_context_cost_per_query": {
"search_context_size_high": 0.01,
"search_context_size_low": 0.01,
"search_context_size_medium": 0.01
},
"supports_adaptive_thinking": true,
"thinking_always_on": true,
"supports_assistant_prefill": false,
"supports_computer_use": true,
"supports_forced_tool_use": false,
"supports_function_calling": true,
"supports_native_structured_output": true,
"supports_pdf_input": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_sampling_params": false,
"supports_tool_choice": true,
"supports_vision": true,
"supports_xhigh_reasoning_effort": true,
"supports_max_reasoning_effort": true,
"prompt_cache_min_tokens": 512,
"deprecation_date": "2027-11-09",
"input_cost_per_token_batches": 4e-06,
"output_cost_per_token_batches": 2e-05,
"source": "https://platform.claude.com/docs/en/models/mythos-5-2/overview"
},
"vertex_ai/claude-fable-latest": {
"alias_of": "vertex_ai/claude-fable-5-2"
},
@ -53360,6 +53401,47 @@
"output_cost_per_token_batches": 2e-05,
"source": "https://cloud.google.com/gemini-enterprise-agent-platform/generative-ai/pricing"
},
"vertex_ai/claude-mythos-5-2@default": {
"regional_endpoint_uplift_multiplier": 1.1,
"supports_mid_conversation_system": true,
"cache_creation_input_token_cost": 1e-05,
"cache_creation_input_token_cost_above_1hr": 1.6e-05,
"cache_creation_input_token_cost_batches": 5e-06,
"cache_read_input_token_cost": 2e-07,
"cache_read_input_token_cost_batches": 1e-07,
"input_cost_per_token": 8e-06,
"litellm_provider": "vertex_ai-anthropic_models",
"max_input_tokens": 1000000,
"max_output_tokens": 128000,
"mode": "chat",
"output_cost_per_token": 4e-05,
"search_context_cost_per_query": {
"search_context_size_high": 0.01,
"search_context_size_low": 0.01,
"search_context_size_medium": 0.01
},
"supports_adaptive_thinking": true,
"thinking_always_on": true,
"supports_assistant_prefill": false,
"supports_computer_use": true,
"supports_forced_tool_use": false,
"supports_function_calling": true,
"supports_native_structured_output": true,
"supports_pdf_input": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_sampling_params": false,
"supports_tool_choice": true,
"supports_vision": true,
"supports_xhigh_reasoning_effort": true,
"supports_max_reasoning_effort": true,
"prompt_cache_min_tokens": 512,
"deprecation_date": "2027-11-09",
"input_cost_per_token_batches": 4e-06,
"output_cost_per_token_batches": 2e-05,
"source": "https://platform.claude.com/docs/en/models/mythos-5-2/overview"
},
"vertex_ai/claude-opus-5": {
"deprecation_date": "2027-01-24",
"regional_endpoint_uplift_multiplier": 1.1,

View file

@ -53236,6 +53236,47 @@
"output_cost_per_token_batches": 2e-05,
"source": "https://cloud.google.com/gemini-enterprise-agent-platform/generative-ai/pricing"
},
"vertex_ai/claude-mythos-5-2": {
"regional_endpoint_uplift_multiplier": 1.1,
"supports_mid_conversation_system": true,
"cache_creation_input_token_cost": 1e-05,
"cache_creation_input_token_cost_above_1hr": 1.6e-05,
"cache_creation_input_token_cost_batches": 5e-06,
"cache_read_input_token_cost": 2e-07,
"cache_read_input_token_cost_batches": 1e-07,
"input_cost_per_token": 8e-06,
"litellm_provider": "vertex_ai-anthropic_models",
"max_input_tokens": 1000000,
"max_output_tokens": 128000,
"mode": "chat",
"output_cost_per_token": 4e-05,
"search_context_cost_per_query": {
"search_context_size_high": 0.01,
"search_context_size_low": 0.01,
"search_context_size_medium": 0.01
},
"supports_adaptive_thinking": true,
"thinking_always_on": true,
"supports_assistant_prefill": false,
"supports_computer_use": true,
"supports_forced_tool_use": false,
"supports_function_calling": true,
"supports_native_structured_output": true,
"supports_pdf_input": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_sampling_params": false,
"supports_tool_choice": true,
"supports_vision": true,
"supports_xhigh_reasoning_effort": true,
"supports_max_reasoning_effort": true,
"prompt_cache_min_tokens": 512,
"deprecation_date": "2027-11-09",
"input_cost_per_token_batches": 4e-06,
"output_cost_per_token_batches": 2e-05,
"source": "https://platform.claude.com/docs/en/models/mythos-5-2/overview"
},
"vertex_ai/claude-fable-latest": {
"alias_of": "vertex_ai/claude-fable-5-2"
},
@ -53360,6 +53401,47 @@
"output_cost_per_token_batches": 2e-05,
"source": "https://cloud.google.com/gemini-enterprise-agent-platform/generative-ai/pricing"
},
"vertex_ai/claude-mythos-5-2@default": {
"regional_endpoint_uplift_multiplier": 1.1,
"supports_mid_conversation_system": true,
"cache_creation_input_token_cost": 1e-05,
"cache_creation_input_token_cost_above_1hr": 1.6e-05,
"cache_creation_input_token_cost_batches": 5e-06,
"cache_read_input_token_cost": 2e-07,
"cache_read_input_token_cost_batches": 1e-07,
"input_cost_per_token": 8e-06,
"litellm_provider": "vertex_ai-anthropic_models",
"max_input_tokens": 1000000,
"max_output_tokens": 128000,
"mode": "chat",
"output_cost_per_token": 4e-05,
"search_context_cost_per_query": {
"search_context_size_high": 0.01,
"search_context_size_low": 0.01,
"search_context_size_medium": 0.01
},
"supports_adaptive_thinking": true,
"thinking_always_on": true,
"supports_assistant_prefill": false,
"supports_computer_use": true,
"supports_forced_tool_use": false,
"supports_function_calling": true,
"supports_native_structured_output": true,
"supports_pdf_input": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_sampling_params": false,
"supports_tool_choice": true,
"supports_vision": true,
"supports_xhigh_reasoning_effort": true,
"supports_max_reasoning_effort": true,
"prompt_cache_min_tokens": 512,
"deprecation_date": "2027-11-09",
"input_cost_per_token_batches": 4e-06,
"output_cost_per_token_batches": 2e-05,
"source": "https://platform.claude.com/docs/en/models/mythos-5-2/overview"
},
"vertex_ai/claude-opus-5": {
"deprecation_date": "2027-01-24",
"regional_endpoint_uplift_multiplier": 1.1,

View file

@ -18,6 +18,7 @@ import pytest
import litellm
from litellm.constants import BEDROCK_CONVERSE_MODELS
from litellm.litellm_core_utils.get_model_cost_map import GetModelCostMap
from litellm.types.utils import CacheCreationTokenDetails, PromptTokensDetailsWrapper, Usage
REPO_ROOT = os.path.join(os.path.dirname(__file__), "../..")
@ -172,3 +173,91 @@ def test_fable_5_2_accepts_the_speed_param_on_the_anthropic_api(local_model_cost
assert AnthropicModelInfo.supports_fast_mode("claude-fable-5-2", "anthropic") is True
assert AnthropicConfig._model_supports_speed_param("claude-fable-5-2", "anthropic") is True
MYTHOS_5_2_VERTEX_ROWS: Final = (
("vertex_ai/claude-mythos-5-2", "vertex_ai/claude-fable-5-2"),
("vertex_ai/claude-mythos-5-2@default", "vertex_ai/claude-fable-5-2@default"),
)
def _without_source(row: dict[str, object]) -> dict[str, object]:
return {k: v for k, v in row.items() if k != "source"}
def test_mythos_5_2_vertex_rows_present_in_bundled_backup() -> None:
backup: Final = GetModelCostMap.load_local_model_cost_map()
root: Final = _load_root_cost_map()
for model_name, _ in MYTHOS_5_2_VERTEX_ROWS:
assert model_name in backup, f"Missing from backup cost map: {model_name}"
assert backup[model_name] == root[model_name], model_name
@pytest.mark.parametrize(("mythos_row", "fable_row"), MYTHOS_5_2_VERTEX_ROWS)
def test_mythos_5_2_vertex_rows_match_fable_5_2(mythos_row: str, fable_row: str) -> None:
"""Anthropic ships Mythos 5.2 as a verified-access twin of Fable 5.2 with "the same
specifications and pricing" (platform.claude.com/docs/en/models/mythos-5-2/overview,
read 2026-11-10), so the Vertex rows must stay identical apart from their source."""
root: Final = _load_root_cost_map()
assert _without_source(root[mythos_row]) == _without_source(root[fable_row])
assert root[mythos_row]["source"] == "https://platform.claude.com/docs/en/models/mythos-5-2/overview"
@pytest.mark.parametrize("model", [row for row, _ in MYTHOS_5_2_VERTEX_ROWS])
def test_adaptive_thinking_detected_for_mythos_5_2_on_vertex(local_model_cost_map, model: str) -> None:
from litellm.llms.anthropic.common_utils import AnthropicModelInfo
assert AnthropicModelInfo.is_adaptive_thinking_model(model, "anthropic") is True
def _vertex_claude_cached_usage() -> Usage:
return Usage(
prompt_tokens=1600,
completion_tokens=50,
prompt_tokens_details=PromptTokensDetailsWrapper(cached_tokens=300, cache_creation_tokens=300),
cache_read_input_tokens=300,
cache_creation_input_tokens=300,
cache_creation_token_details=CacheCreationTokenDetails(
ephemeral_5m_input_tokens=200, ephemeral_1h_input_tokens=100
),
)
@pytest.mark.parametrize(("mythos_row", "fable_row"), MYTHOS_5_2_VERTEX_ROWS)
def test_mythos_5_2_on_vertex_bills_like_fable_5_2(local_model_cost_map, mythos_row: str, fable_row: str) -> None:
"""Billing through the Vertex cost path, with cache reads, 5m and 1h cache writes and the
regional-endpoint uplift, must charge Mythos 5.2 exactly what Fable 5.2 is charged."""
for location in ("global", "us-east5"):
mythos_cost: Final = litellm.cost_per_token(
model=mythos_row,
custom_llm_provider="vertex_ai",
usage_object=_vertex_claude_cached_usage(),
vertex_location=location,
)
fable_cost: Final = litellm.cost_per_token(
model=fable_row,
custom_llm_provider="vertex_ai",
usage_object=_vertex_claude_cached_usage(),
vertex_location=location,
)
assert mythos_cost == fable_cost, location
assert mythos_cost[0] > 0 and mythos_cost[1] > 0, location
@pytest.mark.parametrize("model", [row for row, _ in MYTHOS_5_2_VERTEX_ROWS])
def test_mythos_5_2_on_vertex_applies_regional_uplift(local_model_cost_map, model: str) -> None:
uplift: Final = _load_root_cost_map()[model]["regional_endpoint_uplift_multiplier"]
global_cost: Final = litellm.cost_per_token(
model=model,
custom_llm_provider="vertex_ai",
usage_object=_vertex_claude_cached_usage(),
vertex_location="global",
)
regional_cost: Final = litellm.cost_per_token(
model=model,
custom_llm_provider="vertex_ai",
usage_object=_vertex_claude_cached_usage(),
vertex_location="us-east5",
)
assert regional_cost[0] == pytest.approx(global_cost[0] * uplift)
assert regional_cost[1] == pytest.approx(global_cost[1] * uplift)