diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index c940b31c8c..92862b0ca6 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -389,12 +389,21 @@ export function topK(model: Provider.Model) { const WIDELY_SUPPORTED_EFFORTS = ["low", "medium", "high"] const OPENAI_EFFORTS = ["none", "minimal", ...WIDELY_SUPPORTED_EFFORTS, "xhigh"] +function anthropicAdaptiveEfforts(apiId: string): string[] | null { + if (["opus-4-7", "opus-4.7"].some((v) => apiId.includes(v))) { + return ["low", "medium", "high", "xhigh", "max"] + } + if (["opus-4-6", "opus-4.6", "sonnet-4-6", "sonnet-4.6"].some((v) => apiId.includes(v))) { + return ["low", "medium", "high", "max"] + } + return null +} + export function variants(model: Provider.Model): Record> { if (!model.capabilities.reasoning) return {} const id = model.id.toLowerCase() - const isAnthropicAdaptive = ["opus-4-6", "opus-4.6", "sonnet-4-6", "sonnet-4.6"].some((v) => model.api.id.includes(v)) - const adaptiveEfforts = ["low", "medium", "high", "max"] + const adaptiveEfforts = anthropicAdaptiveEfforts(model.api.id) if ( id.includes("deepseek") || id.includes("minimax") || @@ -429,7 +438,7 @@ export function variants(model: Provider.Model): Record [ effort, @@ -578,7 +587,7 @@ export function variants(model: Provider.Model): Record [ effort, @@ -609,7 +618,7 @@ export function variants(model: Provider.Model): Record [ effort, @@ -716,7 +725,7 @@ export function variants(model: Provider.Model): Record [ effort, diff --git a/packages/opencode/test/provider/transform.test.ts b/packages/opencode/test/provider/transform.test.ts index 0666d0f641..d53ce38b16 100644 --- a/packages/opencode/test/provider/transform.test.ts +++ b/packages/opencode/test/provider/transform.test.ts @@ -2246,6 +2246,46 @@ describe("ProviderTransform.variants", () => { }) }) + test("anthropic opus 4.7 models return adaptive thinking options with xhigh", () => { + const model = createMockModel({ + id: "anthropic/claude-opus-4-7", + providerID: "gateway", + api: { + id: "anthropic/claude-opus-4-7", + url: "https://gateway.ai", + npm: "@ai-sdk/gateway", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high", "xhigh", "max"]) + expect(result.xhigh).toEqual({ + thinking: { + type: "adaptive", + }, + effort: "xhigh", + }) + expect(result.max).toEqual({ + thinking: { + type: "adaptive", + }, + effort: "max", + }) + }) + + test("anthropic opus 4.7 dot-format models return adaptive thinking options with xhigh", () => { + const model = createMockModel({ + id: "anthropic/claude-opus-4-7", + providerID: "gateway", + api: { + id: "anthropic/claude-opus-4.7", + url: "https://gateway.ai", + npm: "@ai-sdk/gateway", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high", "xhigh", "max"]) + }) + test("anthropic models return anthropic thinking options", () => { const model = createMockModel({ id: "anthropic/claude-sonnet-4", @@ -2654,6 +2694,32 @@ describe("ProviderTransform.variants", () => { }) }) + test("opus 4.7 returns adaptive thinking options with xhigh", () => { + const model = createMockModel({ + id: "anthropic/claude-opus-4-7", + providerID: "anthropic", + api: { + id: "claude-opus-4-7", + url: "https://api.anthropic.com", + npm: "@ai-sdk/anthropic", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high", "xhigh", "max"]) + expect(result.xhigh).toEqual({ + thinking: { + type: "adaptive", + }, + effort: "xhigh", + }) + expect(result.max).toEqual({ + thinking: { + type: "adaptive", + }, + effort: "max", + }) + }) + test("returns high and max with thinking config", () => { const model = createMockModel({ id: "anthropic/claude-4", @@ -2702,6 +2768,32 @@ describe("ProviderTransform.variants", () => { }) }) + test("anthropic opus 4.7 returns adaptive reasoning options with xhigh", () => { + const model = createMockModel({ + id: "bedrock/anthropic-claude-opus-4-7", + providerID: "bedrock", + api: { + id: "anthropic.claude-opus-4-7", + url: "https://bedrock.amazonaws.com", + npm: "@ai-sdk/amazon-bedrock", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high", "xhigh", "max"]) + expect(result.xhigh).toEqual({ + reasoningConfig: { + type: "adaptive", + maxReasoningEffort: "xhigh", + }, + }) + expect(result.max).toEqual({ + reasoningConfig: { + type: "adaptive", + maxReasoningEffort: "max", + }, + }) + }) + test("returns WIDELY_SUPPORTED_EFFORTS with reasoningConfig", () => { const model = createMockModel({ id: "bedrock/llama-4",