diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index cc1514f48a8..ddd66510da5 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -333,6 +333,8 @@ export namespace ProviderTransform { 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"] if ( id.includes("deepseek") || id.includes("minimax") || @@ -366,6 +368,19 @@ export namespace ProviderTransform { case "@ai-sdk/gateway": if (model.id.includes("anthropic")) { + if (isAnthropicAdaptive) { + return Object.fromEntries( + adaptiveEfforts.map((effort) => [ + effort, + { + thinking: { + type: "adaptive", + }, + effort, + }, + ]), + ) + } return { high: { thinking: { @@ -502,10 +517,9 @@ export namespace ProviderTransform { case "@ai-sdk/google-vertex/anthropic": // https://v5.ai-sdk.dev/providers/ai-sdk-providers/google-vertex#anthropic-provider - if (model.api.id.includes("opus-4-6") || model.api.id.includes("opus-4.6")) { - const efforts = ["low", "medium", "high", "max"] + if (isAnthropicAdaptive) { return Object.fromEntries( - efforts.map((effort) => [ + adaptiveEfforts.map((effort) => [ effort, { thinking: { @@ -534,10 +548,9 @@ export namespace ProviderTransform { case "@ai-sdk/amazon-bedrock": // https://v5.ai-sdk.dev/providers/ai-sdk-providers/amazon-bedrock - if (model.api.id.includes("opus-4-6") || model.api.id.includes("opus-4.6")) { - const efforts = ["low", "medium", "high", "max"] + if (isAnthropicAdaptive) { return Object.fromEntries( - efforts.map((effort) => [ + adaptiveEfforts.map((effort) => [ effort, { reasoningConfig: { diff --git a/packages/opencode/test/provider/transform.test.ts b/packages/opencode/test/provider/transform.test.ts index 57131d76a98..189bdfd32b4 100644 --- a/packages/opencode/test/provider/transform.test.ts +++ b/packages/opencode/test/provider/transform.test.ts @@ -1705,6 +1705,66 @@ describe("ProviderTransform.variants", () => { }) describe("@ai-sdk/gateway", () => { + test("anthropic sonnet 4.6 models return adaptive thinking options", () => { + const model = createMockModel({ + id: "anthropic/claude-sonnet-4-6", + providerID: "gateway", + api: { + id: "anthropic/claude-sonnet-4-6", + url: "https://gateway.ai", + npm: "@ai-sdk/gateway", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high", "max"]) + expect(result.medium).toEqual({ + thinking: { + type: "adaptive", + }, + effort: "medium", + }) + }) + + test("anthropic sonnet 4.6 dot-format models return adaptive thinking options", () => { + const model = createMockModel({ + id: "anthropic/claude-sonnet-4-6", + providerID: "gateway", + api: { + id: "anthropic/claude-sonnet-4.6", + url: "https://gateway.ai", + npm: "@ai-sdk/gateway", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high", "max"]) + expect(result.medium).toEqual({ + thinking: { + type: "adaptive", + }, + effort: "medium", + }) + }) + + test("anthropic opus 4.6 dot-format models return adaptive thinking options", () => { + const model = createMockModel({ + id: "anthropic/claude-opus-4-6", + providerID: "gateway", + api: { + id: "anthropic/claude-opus-4.6", + url: "https://gateway.ai", + npm: "@ai-sdk/gateway", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high", "max"]) + expect(result.high).toEqual({ + thinking: { + type: "adaptive", + }, + effort: "high", + }) + }) + test("anthropic models return anthropic thinking options", () => { const model = createMockModel({ id: "anthropic/claude-sonnet-4", @@ -2064,6 +2124,26 @@ describe("ProviderTransform.variants", () => { }) describe("@ai-sdk/anthropic", () => { + test("sonnet 4.6 returns adaptive thinking options", () => { + const model = createMockModel({ + id: "anthropic/claude-sonnet-4-6", + providerID: "anthropic", + api: { + id: "claude-sonnet-4-6", + url: "https://api.anthropic.com", + npm: "@ai-sdk/anthropic", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high", "max"]) + expect(result.high).toEqual({ + thinking: { + type: "adaptive", + }, + effort: "high", + }) + }) + test("returns high and max with thinking config", () => { const model = createMockModel({ id: "anthropic/claude-4", @@ -2092,6 +2172,26 @@ describe("ProviderTransform.variants", () => { }) describe("@ai-sdk/amazon-bedrock", () => { + test("anthropic sonnet 4.6 returns adaptive reasoning options", () => { + const model = createMockModel({ + id: "bedrock/anthropic-claude-sonnet-4-6", + providerID: "bedrock", + api: { + id: "anthropic.claude-sonnet-4-6", + url: "https://bedrock.amazonaws.com", + npm: "@ai-sdk/amazon-bedrock", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high", "max"]) + expect(result.max).toEqual({ + reasoningConfig: { + type: "adaptive", + maxReasoningEffort: "max", + }, + }) + }) + test("returns WIDELY_SUPPORTED_EFFORTS with reasoningConfig", () => { const model = createMockModel({ id: "bedrock/llama-4",