Skip to content

Commit 64fc5fc

Browse files
author
Zeph Gillen
committed
feat(anthropic+openrouter): add Opus 4.8 with adaptive-thinking effort
Adds claude-opus-4-8 to the static Anthropic catalog and wires it through the provider switch + OpenRouter passthrough. Opus 4.8 facts (from platform.claude.com): - 1M context, 128k max output, $5/$25 per MTok (same as 4.7) - Adaptive thinking only; manual budget_tokens returns a 400 error - Effort values: low / medium / high / xhigh / max - Default effort: high (Anthropic explicitly recommends as best balance -- yields token-spend similar to Opus 4.7's xhigh default but with better performance) For OpenRouter, the dynamic fetcher reports supportsReasoningEffort as a boolean which collapses the UI to the legacy [low/medium/high] fallback (same gap we fixed for gpt-5.5). Mirror the static capability array onto anthropic/claude-opus-4.7 AND anthropic/claude-opus-4.8 so xhigh and max are reachable in both. Disable supportsReasoningBudget since both reject budget_tokens. Parametrized fetcher test covers both ids.
1 parent e674e4f commit 64fc5fc

4 files changed

Lines changed: 70 additions & 0 deletions

File tree

packages/types/src/providers/anthropic.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,30 @@ export const anthropicModels = {
111111
supportsTemperature: false,
112112
supportsReasoningDisplay: true,
113113
},
114+
"claude-opus-4-8": {
115+
maxTokens: 128_000,
116+
// Native 1M-token context window; flat pricing (200k on Microsoft Foundry only).
117+
// Source: https://platform.claude.com/docs/en/about-claude/models/overview
118+
contextWindow: 1_000_000,
119+
supportsImages: true,
120+
supportsPromptCache: true,
121+
inputPrice: 5.0,
122+
outputPrice: 25.0,
123+
cacheWritesPrice: 6.25,
124+
cacheReadsPrice: 0.5,
125+
// Opus 4.8 uses adaptive thinking only; manual `thinking: {type: "enabled", budget_tokens}`
126+
// returns a 400 error. Effort controls thinking depth.
127+
// Per https://platform.claude.com/docs/en/build-with-claude/effort:
128+
// - Effort defaults to `high` on the API and Claude Code; Anthropic explicitly states
129+
// this is "the best overall balance of quality and user experience" and yields
130+
// similar token usage to Opus 4.7's xhigh default but with better performance.
131+
// - `xhigh` is recommended for difficult tasks and long-running async workflows.
132+
supportsReasoningEffort: ["low", "medium", "high", "xhigh", "max"],
133+
requiredReasoningEffort: true,
134+
reasoningEffort: "high",
135+
supportsTemperature: false,
136+
supportsReasoningDisplay: true,
137+
},
114138
"claude-opus-4-5-20251101": {
115139
maxTokens: 32_000, // Overridden to 8k if `enableReasoningEffort` is false.
116140
contextWindow: 200_000,

src/api/providers/anthropic.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
9090
case "claude-sonnet-4-20250514":
9191
case "claude-opus-4-6":
9292
case "claude-opus-4-7":
93+
case "claude-opus-4-8":
9394
case "claude-opus-4-5-20251101":
9495
case "claude-opus-4-1-20250805":
9596
case "claude-opus-4-20250514":
@@ -159,6 +160,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
159160
case "claude-sonnet-4-20250514":
160161
case "claude-opus-4-6":
161162
case "claude-opus-4-7":
163+
case "claude-opus-4-8":
162164
case "claude-opus-4-5-20251101":
163165
case "claude-opus-4-1-20250805":
164166
case "claude-opus-4-20250514":

src/api/providers/fetchers/__tests__/openrouter.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,34 @@ describe("OpenRouter API", () => {
266266
})
267267

268268
describe("parseOpenRouterModel", () => {
269+
it.each([["anthropic/claude-opus-4.7"], ["anthropic/claude-opus-4.8"]])(
270+
"mirrors static capability for %s on OpenRouter",
271+
(id) => {
272+
const mockModel = {
273+
name: id,
274+
description: "Test model",
275+
context_length: 1_000_000,
276+
max_completion_tokens: 128000,
277+
pricing: { prompt: "0.000005", completion: "0.000025", input_cache_read: "0.0000005" },
278+
}
279+
280+
const result = parseOpenRouterModel({
281+
id,
282+
model: mockModel,
283+
inputModality: ["text", "image"],
284+
outputModality: ["text"],
285+
maxTokens: 128000,
286+
supportedParameters: ["reasoning", "tools"],
287+
})
288+
289+
expect(result.maxTokens).toBe(128000)
290+
expect(result.supportsReasoningEffort).toEqual(["low", "medium", "high", "xhigh", "max"])
291+
expect(result.requiredReasoningEffort).toBe(true)
292+
expect(result.supportsReasoningBudget).toBe(false)
293+
expect(result.supportsTemperature).toBe(false)
294+
},
295+
)
296+
269297
it("sets claude-sonnet-4.6 model to Anthropic max tokens", () => {
270298
const mockModel = {
271299
name: "Claude Sonnet 4.6",

src/api/providers/fetchers/openrouter.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,22 @@ export const parseOpenRouterModel = ({
279279
modelInfo.maxTokens = anthropicModels["claude-opus-4-6"].maxTokens
280280
}
281281

282+
// Opus 4.7 and 4.8 via OpenRouter: mirror static capability arrays so the UI
283+
// surfaces xhigh / max effort levels (boolean true would collapse to the
284+
// legacy low/medium/high fallback). Both models use adaptive thinking only
285+
// and reject budget_tokens, so disable supportsReasoningBudget.
286+
if (id === "anthropic/claude-opus-4.7" || id === "anthropic/claude-opus-4.8") {
287+
const staticId = id === "anthropic/claude-opus-4.7" ? "claude-opus-4-7" : "claude-opus-4-8"
288+
const staticDef = anthropicModels[staticId]
289+
modelInfo.maxTokens = staticDef.maxTokens
290+
modelInfo.supportsReasoningEffort = staticDef.supportsReasoningEffort
291+
modelInfo.reasoningEffort = staticDef.reasoningEffort
292+
modelInfo.requiredReasoningEffort = staticDef.requiredReasoningEffort
293+
modelInfo.supportsReasoningBudget = false
294+
modelInfo.supportsReasoningDisplay = staticDef.supportsReasoningDisplay
295+
modelInfo.supportsTemperature = staticDef.supportsTemperature
296+
}
297+
282298
// Ensure correct reasoning handling for Claude Haiku 4.5 on OpenRouter
283299
// Use budget control and disable effort-based reasoning fallback
284300
if (id === "anthropic/claude-haiku-4.5") {

0 commit comments

Comments
 (0)