feat(catalog): add Claude Opus 5 entries for Amazon Bedrock
Changes: - Add Amazon Bedrock catalog entries for Claude Opus 5 - Exclude unsupported jp. inference profiles during generation - Add Bedrock prompt cache compatibility info, AWS model card sources, and regression tests Reason / background: - Incorporate the new model info from models.dev and align with the official AWS spec Scope of impact: - Model catalog generation, Bedrock compatibility info, catalog tests
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Added Claude Opus 5 model entries for Amazon Bedrock: `anthropic.claude-opus-5` plus its `us.`, `eu.`, `au.`, and `global.` regional/geo IDs.
|
||||
|
||||
## [17.1.3] - 2026-07-24
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -52,6 +52,7 @@ import {
|
||||
applyCanonicalLimitFallback,
|
||||
applyGeneratedModelPolicies,
|
||||
CLOUDFLARE_FALLBACK_MODEL,
|
||||
dropUnsupportedBedrockGeoIds,
|
||||
linkOpenAIPromotionTargets,
|
||||
} from "./generated-policies";
|
||||
|
||||
@@ -634,6 +635,7 @@ async function generateModels() {
|
||||
allModels = dropFireworksWireIds(allModels);
|
||||
allModels = dropUnusableZaiContextTierIds(allModels);
|
||||
allModels = dropXiaomiAudioOnlyIds(allModels);
|
||||
allModels = dropUnsupportedBedrockGeoIds(allModels);
|
||||
allModels = normalizeAntigravityEndpoint(allModels);
|
||||
// Normalize display names: gateway author prefixes ("OpenAI: …"), alias
|
||||
// markers ("(latest)"), provider attribution ("(Antigravity)"), and
|
||||
|
||||
@@ -51,6 +51,20 @@ export const CLOUDFLARE_FALLBACK_MODEL: ModelSpec<"anthropic-messages"> = {
|
||||
maxTokens: 64000,
|
||||
};
|
||||
|
||||
/**
|
||||
* `models.dev` currently lists `jp.anthropic.claude-opus-5`, but AWS's own
|
||||
* Bedrock model card documents only `anthropic.claude-opus-5` plus the `us.`,
|
||||
* `eu.`, `au.`, and `global.` Geo/Global inference-profile IDs under
|
||||
* Programmatic Access; Japan regions are marked unsupported for Geo inference
|
||||
* in the same card's regional-availability table. Bedrock rejects an
|
||||
* undocumented inference-profile ID outright, so drop this specific upstream
|
||||
* row rather than ship a selector that 4xxs on first use (PR #6591 review).
|
||||
* https://docs.aws.amazon.com/bedrock/latest/userguide/model-card-anthropic-claude-opus-5.html
|
||||
*/
|
||||
export function dropUnsupportedBedrockGeoIds(models: readonly ModelSpec[]): ModelSpec[] {
|
||||
return models.filter(model => !(model.provider === "amazon-bedrock" && model.id === "jp.anthropic.claude-opus-5"));
|
||||
}
|
||||
|
||||
const CODEX_GPT_5_4_PRIORITY_BY_VARIANT: Partial<Record<OpenAIVariant, number>> = {
|
||||
base: 0,
|
||||
mini: 1,
|
||||
|
||||
@@ -42,6 +42,15 @@ const EXPLICIT_CHECKPOINTS_4096_1H: ResolvedBedrockCompat = {
|
||||
promptCacheMaximumCheckpoints: 4,
|
||||
};
|
||||
|
||||
// AWS モデルカード: 512 トークン、最大 4 個のキャッシュチェックポイント、5 分と 1 時間の TTL。
|
||||
// https://docs.aws.amazon.com/bedrock/latest/userguide/model-card-anthropic-claude-opus-5.html
|
||||
const EXPLICIT_CHECKPOINTS_512_1H: ResolvedBedrockCompat = {
|
||||
promptCacheMode: "explicit",
|
||||
supportsLongPromptCacheRetention: true,
|
||||
promptCacheMinimumTokens: 512,
|
||||
promptCacheMaximumCheckpoints: 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* Explicit Nova cache points complement Bedrock's automatic prefix caching:
|
||||
* AWS recommends them for consistent cache hits and input-cost savings. Keep
|
||||
@@ -82,6 +91,9 @@ function detectedBedrockCompat(modelId: string): ResolvedBedrockCompat {
|
||||
) {
|
||||
return EXPLICIT_CHECKPOINTS_4096_1H;
|
||||
}
|
||||
if (id.includes("anthropic.claude-opus-5")) {
|
||||
return EXPLICIT_CHECKPOINTS_512_1H;
|
||||
}
|
||||
if (id.includes("anthropic.claude-opus-4-6")) {
|
||||
return EXPLICIT_CHECKPOINTS_4096_5M;
|
||||
}
|
||||
|
||||
@@ -7966,6 +7966,36 @@
|
||||
"supportsDisplay": true
|
||||
}
|
||||
},
|
||||
"anthropic.claude-opus-5": {
|
||||
"id": "anthropic.claude-opus-5",
|
||||
"name": "Claude Opus 5",
|
||||
"api": "bedrock-converse-stream",
|
||||
"provider": "amazon-bedrock",
|
||||
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 5,
|
||||
"output": 25,
|
||||
"cacheRead": 0.5,
|
||||
"cacheWrite": 6.25
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 128000,
|
||||
"thinking": {
|
||||
"mode": "anthropic-adaptive",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"max"
|
||||
],
|
||||
"supportsDisplay": true
|
||||
}
|
||||
},
|
||||
"anthropic.claude-sonnet-5": {
|
||||
"id": "anthropic.claude-sonnet-5",
|
||||
"name": "Claude Sonnet 5",
|
||||
@@ -8084,6 +8114,36 @@
|
||||
"supportsDisplay": true
|
||||
}
|
||||
},
|
||||
"au.anthropic.claude-opus-5": {
|
||||
"id": "au.anthropic.claude-opus-5",
|
||||
"name": "Claude Opus 5 (AU)",
|
||||
"api": "bedrock-converse-stream",
|
||||
"provider": "amazon-bedrock",
|
||||
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 5,
|
||||
"output": 25,
|
||||
"cacheRead": 0.5,
|
||||
"cacheWrite": 6.25
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 128000,
|
||||
"thinking": {
|
||||
"mode": "anthropic-adaptive",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"max"
|
||||
],
|
||||
"supportsDisplay": true
|
||||
}
|
||||
},
|
||||
"au.anthropic.claude-sonnet-4-5-20250929-v1:0": {
|
||||
"id": "au.anthropic.claude-sonnet-4-5-20250929-v1:0",
|
||||
"name": "Claude Sonnet 4.5 (AU)",
|
||||
@@ -8669,6 +8729,36 @@
|
||||
"supportsDisplay": true
|
||||
}
|
||||
},
|
||||
"eu.anthropic.claude-opus-5": {
|
||||
"id": "eu.anthropic.claude-opus-5",
|
||||
"name": "Claude Opus 5 (EU)",
|
||||
"api": "bedrock-converse-stream",
|
||||
"provider": "amazon-bedrock",
|
||||
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 5.5,
|
||||
"output": 27.5,
|
||||
"cacheRead": 0.55,
|
||||
"cacheWrite": 6.875
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 128000,
|
||||
"thinking": {
|
||||
"mode": "anthropic-adaptive",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"max"
|
||||
],
|
||||
"supportsDisplay": true
|
||||
}
|
||||
},
|
||||
"eu.anthropic.claude-sonnet-4-20250514-v1:0": {
|
||||
"id": "eu.anthropic.claude-sonnet-4-20250514-v1:0",
|
||||
"name": "Claude Sonnet 4 (EU)",
|
||||
@@ -8992,6 +9082,36 @@
|
||||
"supportsDisplay": true
|
||||
}
|
||||
},
|
||||
"global.anthropic.claude-opus-5": {
|
||||
"id": "global.anthropic.claude-opus-5",
|
||||
"name": "Claude Opus 5 (Global)",
|
||||
"api": "bedrock-converse-stream",
|
||||
"provider": "amazon-bedrock",
|
||||
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 5,
|
||||
"output": 25,
|
||||
"cacheRead": 0.5,
|
||||
"cacheWrite": 6.25
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 128000,
|
||||
"thinking": {
|
||||
"mode": "anthropic-adaptive",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"max"
|
||||
],
|
||||
"supportsDisplay": true
|
||||
}
|
||||
},
|
||||
"global.anthropic.claude-sonnet-4-20250514-v1:0": {
|
||||
"id": "global.anthropic.claude-sonnet-4-20250514-v1:0",
|
||||
"name": "Claude Sonnet 4 (Global)",
|
||||
@@ -10620,6 +10740,36 @@
|
||||
"supportsDisplay": true
|
||||
}
|
||||
},
|
||||
"us.anthropic.claude-opus-5": {
|
||||
"id": "us.anthropic.claude-opus-5",
|
||||
"name": "Claude Opus 5 (US)",
|
||||
"api": "bedrock-converse-stream",
|
||||
"provider": "amazon-bedrock",
|
||||
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 5,
|
||||
"output": 25,
|
||||
"cacheRead": 0.5,
|
||||
"cacheWrite": 6.25
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 128000,
|
||||
"thinking": {
|
||||
"mode": "anthropic-adaptive",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"max"
|
||||
],
|
||||
"supportsDisplay": true
|
||||
}
|
||||
},
|
||||
"us.anthropic.claude-sonnet-4-20250514-v1:0": {
|
||||
"id": "us.anthropic.claude-sonnet-4-20250514-v1:0",
|
||||
"name": "Claude Sonnet 4 (US)",
|
||||
@@ -94800,4 +94950,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { buildBedrockCompat } from "@oh-my-pi/pi-catalog/compat/bedrock";
|
||||
import { getBundledModels } from "@oh-my-pi/pi-catalog/models";
|
||||
import type { ModelSpec } from "@oh-my-pi/pi-catalog/types";
|
||||
import { dropUnsupportedBedrockGeoIds } from "../scripts/generated-policies";
|
||||
|
||||
// AWS's Bedrock model card for Claude Opus 5 lists exactly these Programmatic
|
||||
// Access IDs — the bare model ID plus the us./eu./au. Geo and global.
|
||||
// inference profiles. Japan is explicitly marked unsupported for Geo
|
||||
// inference in the same card's regional-availability table, so no `jp.`
|
||||
// profile exists for this model (unlike several Opus 4.x generations).
|
||||
// https://docs.aws.amazon.com/bedrock/latest/userguide/model-card-anthropic-claude-opus-5.html
|
||||
const AWS_DOCUMENTED_OPUS_5_IDS = [
|
||||
"anthropic.claude-opus-5",
|
||||
"us.anthropic.claude-opus-5",
|
||||
"eu.anthropic.claude-opus-5",
|
||||
"au.anthropic.claude-opus-5",
|
||||
"global.anthropic.claude-opus-5",
|
||||
];
|
||||
|
||||
describe("Amazon Bedrock Claude Opus 5", () => {
|
||||
test("bundles exactly the AWS-documented inference-profile IDs", () => {
|
||||
const bedrockOpus5Ids = getBundledModels("amazon-bedrock")
|
||||
.map(model => model.id)
|
||||
.filter(id => id.endsWith("anthropic.claude-opus-5"));
|
||||
|
||||
expect(new Set(bedrockOpus5Ids)).toEqual(new Set(AWS_DOCUMENTED_OPUS_5_IDS));
|
||||
// `models.dev` currently also lists `jp.anthropic.claude-opus-5`; Bedrock
|
||||
// has no such inference profile for this model and would reject it.
|
||||
expect(bedrockOpus5Ids).not.toContain("jp.anthropic.claude-opus-5");
|
||||
});
|
||||
|
||||
test("dropUnsupportedBedrockGeoIds filters the undocumented jp. profile without touching other providers/ids", () => {
|
||||
const bareSpec = (provider: string, id: string): ModelSpec<"bedrock-converse-stream"> => ({
|
||||
id,
|
||||
name: id,
|
||||
api: "bedrock-converse-stream",
|
||||
provider,
|
||||
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 200000,
|
||||
maxTokens: 64000,
|
||||
});
|
||||
const input = [
|
||||
bareSpec("amazon-bedrock", "jp.anthropic.claude-opus-5"),
|
||||
bareSpec("amazon-bedrock", "us.anthropic.claude-opus-5"),
|
||||
// A `jp.` id on a different Bedrock model, or on a different provider,
|
||||
// must survive — only this exact (provider, id) pair is undocumented.
|
||||
bareSpec("amazon-bedrock", "jp.anthropic.claude-opus-4-8"),
|
||||
bareSpec("some-other-provider", "jp.anthropic.claude-opus-5"),
|
||||
];
|
||||
|
||||
expect(dropUnsupportedBedrockGeoIds(input).map(model => model.id)).toEqual([
|
||||
"us.anthropic.claude-opus-5",
|
||||
"jp.anthropic.claude-opus-4-8",
|
||||
"jp.anthropic.claude-opus-5",
|
||||
]);
|
||||
});
|
||||
|
||||
test("resolves the AWS-documented 512-token/four-checkpoint/1h prompt-cache capability", () => {
|
||||
for (const id of AWS_DOCUMENTED_OPUS_5_IDS) {
|
||||
const spec: ModelSpec<"bedrock-converse-stream"> = {
|
||||
id,
|
||||
name: id,
|
||||
api: "bedrock-converse-stream",
|
||||
provider: "amazon-bedrock",
|
||||
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
|
||||
reasoning: true,
|
||||
input: ["text", "image"],
|
||||
cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
|
||||
contextWindow: 1_000_000,
|
||||
maxTokens: 128_000,
|
||||
};
|
||||
expect(buildBedrockCompat(spec)).toEqual({
|
||||
promptCacheMode: "explicit",
|
||||
supportsLongPromptCacheRetention: true,
|
||||
promptCacheMinimumTokens: 512,
|
||||
promptCacheMaximumCheckpoints: 4,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user