fix(pricing): restrict Bedrock profile normalization

This commit is contained in:
Osraka 2026-07-15 11:52:41 +03:00 committed by Teknium
parent 54418a888e
commit e101bbaebb
2 changed files with 30 additions and 19 deletions

View file

@ -917,7 +917,8 @@ def _normalize_bedrock_model_name(model: str) -> str:
e.g. ``us.anthropic.claude-opus-4-7``. The pricing table is keyed on the
bare ``anthropic.claude-*`` id, so the prefix must be stripped before the
lookup or every cross-region session prices as unknown. Also normalizes
dot-notation version numbers (``4.7`` ``4-7``).
dot-notation version numbers (``4.7`` ``4-7``) and the documented
trailing date, revision, and profile components (``-20250514-v1:0``).
"""
name = model.lower().strip()
for prefix in (
@ -936,6 +937,12 @@ def _normalize_bedrock_model_name(model: str) -> str:
name = name[len(prefix):]
break
name = re.sub(r"(\d+)\.(\d+)", r"\1-\2", name)
# Bedrock inference profile IDs append these documented components to the
# foundation model ID. Strip only the trailing forms, not arbitrary model
# name continuations that could be a distinct SKU.
name = re.sub(r":\d+$", "", name)
name = re.sub(r"-v\d+$", "", name)
name = re.sub(r"-\d{8}$", "", name)
return name
@ -977,20 +984,6 @@ def _lookup_official_docs_pricing(route: BillingRoute) -> Optional[PricingEntry]
entry = _OFFICIAL_DOCS_PRICING.get((route.provider, normalized))
if entry:
return entry
bedrock_entries = (
(known_model, known_entry)
for (provider, known_model), known_entry in _OFFICIAL_DOCS_PRICING.items()
if provider == route.provider
)
for known_model, known_entry in sorted(
bedrock_entries,
key=lambda item: len(item[0]),
reverse=True,
):
if normalized == known_model or normalized.startswith(
(f"{known_model}-", f"{known_model}:")
):
return known_entry
return None

View file

@ -394,16 +394,34 @@ def test_bedrock_pricing_supports_less_common_inference_profile_prefixes():
"""AWS also exposes profile scopes beyond us./global./eu.; those should
not silently fall through to unknown pricing.
"""
bare = get_pricing_entry("anthropic.claude-haiku-4-5", provider="bedrock")
entry = get_pricing_entry(
"apac.anthropic.claude-haiku-4-5-20251001-v1:0",
provider="bedrock",
)
assert bare is not None
assert entry is not None
assert float(entry.input_cost_per_million) == 0.8
assert float(entry.output_cost_per_million) == 4.0
assert float(entry.cache_read_cost_per_million) == 0.08
assert float(entry.cache_write_cost_per_million) == 1.0
for field in (
"input_cost_per_million",
"output_cost_per_million",
"cache_read_cost_per_million",
"cache_write_cost_per_million",
):
assert getattr(entry, field) == getattr(bare, field)
def test_bedrock_unknown_model_continuation_does_not_use_base_pricing():
"""Unrecognized Bedrock SKUs must remain unknown rather than inheriting a
similarly named model family's price.
"""
assert (
get_pricing_entry(
"anthropic.claude-sonnet-4-6-experimental",
provider="bedrock",
)
is None
)
def test_bedrock_claude_cached_session_estimates_cost_not_unknown():