diff --git a/open-sse/config/providerRegistry.ts b/open-sse/config/providerRegistry.ts index 6e8c696e23..fb304d7964 100644 --- a/open-sse/config/providerRegistry.ts +++ b/open-sse/config/providerRegistry.ts @@ -1066,6 +1066,12 @@ const _REGISTRY_EAGER: Record = { }, models: [ { id: "auto-kiro", name: "Auto (Kiro picks best model)" }, + { + id: "claude-opus-4.8", + name: "Claude Opus 4.8", + contextLength: 1000000, + maxOutputTokens: 128000, + }, { id: "claude-opus-4.7", name: "Claude Opus 4.7", diff --git a/src/shared/constants/pricing.ts b/src/shared/constants/pricing.ts index e91703b036..b5c29cf8d1 100644 --- a/src/shared/constants/pricing.ts +++ b/src/shared/constants/pricing.ts @@ -1304,6 +1304,20 @@ export const DEFAULT_PRICING = { reasoning: 15.0, cache_creation: 3.0, }, + "claude-opus-4.8": { + input: 15.0, + output: 75.0, + cached: 7.5, + reasoning: 75.0, + cache_creation: 15.0, + }, + "claude-opus-4.7": { + input: 15.0, + output: 75.0, + cached: 7.5, + reasoning: 75.0, + cache_creation: 15.0, + }, "claude-opus-4.6": { input: 15.0, output: 75.0, diff --git a/tests/unit/catalog-updates-v3x.test.ts b/tests/unit/catalog-updates-v3x.test.ts index c93bedff3b..4b97773344 100644 --- a/tests/unit/catalog-updates-v3x.test.ts +++ b/tests/unit/catalog-updates-v3x.test.ts @@ -3,6 +3,7 @@ import assert from "node:assert/strict"; import { getModelsByProviderId } from "../../open-sse/config/providerModels.ts"; import { resolveCanonicalProviderModel } from "../../open-sse/services/model.ts"; +import { DEFAULT_PRICING } from "../../src/shared/constants/pricing.ts"; test("Pollinations catalog mirrors the current public text model lineup", () => { const models = getModelsByProviderId("pollinations"); @@ -45,3 +46,19 @@ test("NVIDIA catalog includes the verified 2026 additions and GPT OSS 20B alias model: "openai/gpt-oss-20b", }); }); + +test("Kiro catalog exposes Claude Opus 4.8 alongside 4.7 with matching pricing", () => { + const models = getModelsByProviderId("kiro"); + const ids = new Set(models.map((model) => model.id)); + + assert.ok(ids.has("claude-opus-4.8"), "kiro must expose claude-opus-4.8"); + assert.ok(ids.has("claude-opus-4.7"), "kiro must still expose claude-opus-4.7"); + + const opus48 = models.find((model) => model.id === "claude-opus-4.8"); + assert.equal(opus48?.contextLength, 1000000); + assert.equal(opus48?.maxOutputTokens, 128000); + + // Pricing for the Kiro channel must cover the new model so usage cost is non-zero. + const kiroPricing = (DEFAULT_PRICING as Record>).kiro; + assert.ok(kiroPricing["claude-opus-4.8"], "kiro pricing must include claude-opus-4.8"); +});