feat(pricing): add Bedrock rows for Opus 4.8/4.7, correct Opus 4.6 to $5/$25

Adds current-gen Claude Opus pricing rows on Bedrock keyed to Anthropic's
published list price, which commercial Bedrock on-demand mirrors. Also
corrects the existing Opus 4.6 row: it carried Claude-3-era Opus pricing
($15/$75); Opus 4.5+ list at $5/$25 with cache write 1.25x / read 0.1x.

The AWS Price List API had not published these SKUs machine-readably as
of 2026-07, so these are commercial-list snapshots pending an
authoritative machine source.

Reapplied from PR #62327 (commit authored under a placeholder identity,
so cherry-pick was not usable; sonnet-5 row from that PR already landed
via #67932).

Co-authored-by: pgregg88 <4943027+pgregg88@users.noreply.github.com>
This commit is contained in:
Teknium 2026-07-20 02:51:17 -07:00
parent e101bbaebb
commit 3441b80f4f
2 changed files with 72 additions and 5 deletions

View file

@ -545,17 +545,47 @@ _OFFICIAL_DOCS_PRICING: Dict[tuple[str, str], PricingEntry] = {
# Bedrock charges the same per-token rates as the model provider but
# through AWS billing. These are the on-demand prices (no commitment).
# Source: https://aws.amazon.com/bedrock/pricing/
# Current-gen Claude Opus on Bedrock. Commercial Bedrock on-demand
# mirrors Anthropic's published list price for the Claude line
# ($5/$25 for Opus 4.6/4.7/4.8; cache write = 1.25x input at the
# 5-minute TTL, cache read = 0.1x input). NOTE: the AWS Price List API
# had not published these SKUs machine-readably as of 2026-07 — these
# are commercial-list snapshots pending an authoritative machine source.
(
"bedrock",
"anthropic.claude-opus-4-8",
): PricingEntry(
input_cost_per_million=Decimal("5.00"),
output_cost_per_million=Decimal("25.00"),
cache_read_cost_per_million=Decimal("0.50"),
cache_write_cost_per_million=Decimal("6.25"),
source="official_docs_snapshot",
source_url="https://aws.amazon.com/bedrock/pricing/",
pricing_version="anthropic-list-2026-07",
),
(
"bedrock",
"anthropic.claude-opus-4-7",
): PricingEntry(
input_cost_per_million=Decimal("5.00"),
output_cost_per_million=Decimal("25.00"),
cache_read_cost_per_million=Decimal("0.50"),
cache_write_cost_per_million=Decimal("6.25"),
source="official_docs_snapshot",
source_url="https://aws.amazon.com/bedrock/pricing/",
pricing_version="anthropic-list-2026-07",
),
(
"bedrock",
"anthropic.claude-opus-4-6",
): PricingEntry(
input_cost_per_million=Decimal("15.00"),
output_cost_per_million=Decimal("75.00"),
cache_read_cost_per_million=Decimal("1.50"),
cache_write_cost_per_million=Decimal("18.75"),
input_cost_per_million=Decimal("5.00"),
output_cost_per_million=Decimal("25.00"),
cache_read_cost_per_million=Decimal("0.50"),
cache_write_cost_per_million=Decimal("6.25"),
source="official_docs_snapshot",
source_url="https://aws.amazon.com/bedrock/pricing/",
pricing_version="bedrock-pricing-2026-04",
pricing_version="anthropic-list-2026-07",
),
(
"bedrock",

View file

@ -348,6 +348,43 @@ def test_bedrock_claude_rows_all_carry_cache_pricing():
assert entry.cache_write_cost_per_million > entry.input_cost_per_million, key
def test_bedrock_current_gen_claude_rows_resolve():
"""Current-gen Claude models (Opus 4.8/4.7, Sonnet 5) must have Bedrock
pricing rows so cached sessions report a dollar cost, not ``unknown``.
Assert each resolves via the bare id and a cross-region inference profile
(us./global. prefix), that every id for a given model resolves to the same
entry, and that the row carries the cache fields a Bedrock Claude session
needs.
(Version-suffixed IDs like ``...-v1:0`` are covered separately by the
normalizer test in the suffix-strip change; this test intentionally sticks
to id shapes that resolve on ``main`` so it is independent of that PR.)
"""
url = "https://bedrock-runtime.us-east-1.amazonaws.com"
for bare in (
"anthropic.claude-opus-4-8",
"anthropic.claude-opus-4-7",
"anthropic.claude-sonnet-5",
):
ref = get_pricing_entry(bare, provider="bedrock", base_url=url)
assert ref is not None, bare
assert ref.input_cost_per_million is not None, bare
assert ref.output_cost_per_million is not None, bare
# Output costs more than input across the Claude line; sanity-check the
# row isn't malformed (input < output).
assert ref.output_cost_per_million > ref.input_cost_per_million, bare
# Cache fields present so cached sessions price correctly (the #50295
# symptom was unknown cost on cached Bedrock Claude sessions).
assert ref.cache_read_cost_per_million is not None, bare
assert ref.cache_write_cost_per_million is not None, bare
# Cross-region inference profiles resolve to the same entry.
for mid in (f"us.{bare}", f"global.{bare}"):
entry = get_pricing_entry(mid, provider="bedrock", base_url=url)
assert entry is not None, mid
assert entry.input_cost_per_million == ref.input_cost_per_million, mid
assert entry.output_cost_per_million == ref.output_cost_per_million, mid
def test_bedrock_cross_region_profile_prefix_resolves_to_pricing():
"""Cross-region inference profiles (us./global./eu. prefixes) must resolve
to the same pricing entry as the bare foundation-model id. Without prefix