summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGraham Campbell <[email protected]>2026-04-16 16:57:36 +0100
committerGitHub <[email protected]>2026-04-16 10:57:36 -0500
commit378c05f202b0fda6561451a93639712a11400972 (patch)
treef76ae0e2f416e375be3e7919b25229c7bc2ddebf
parentcc7acd90ab2fda54f06ff687a46d7364e479dc32 (diff)
downloadopencode-378c05f202b0fda6561451a93639712a11400972.tar.gz
opencode-378c05f202b0fda6561451a93639712a11400972.zip
feat: Add support for claude opus 4.7 xhigh adaptive reasoning effort (#22833)
Co-authored-by: Aiden Cline <[email protected]>
-rw-r--r--packages/opencode/src/provider/transform.ts21
-rw-r--r--packages/opencode/test/provider/transform.test.ts92
2 files changed, 107 insertions, 6 deletions
diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts
index c940b31c8..92862b0ca 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<string, Record<string, any>> {
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<string, Record<string, a
case "@ai-sdk/gateway":
if (model.id.includes("anthropic")) {
- if (isAnthropicAdaptive) {
+ if (adaptiveEfforts) {
return Object.fromEntries(
adaptiveEfforts.map((effort) => [
effort,
@@ -578,7 +587,7 @@ export function variants(model: Provider.Model): Record<string, Record<string, a
case "@ai-sdk/google-vertex/anthropic":
// https://v5.ai-sdk.dev/providers/ai-sdk-providers/google-vertex#anthropic-provider
- if (isAnthropicAdaptive) {
+ if (adaptiveEfforts) {
return Object.fromEntries(
adaptiveEfforts.map((effort) => [
effort,
@@ -609,7 +618,7 @@ export function variants(model: Provider.Model): Record<string, Record<string, a
case "@ai-sdk/amazon-bedrock":
// https://v5.ai-sdk.dev/providers/ai-sdk-providers/amazon-bedrock
- if (isAnthropicAdaptive) {
+ if (adaptiveEfforts) {
return Object.fromEntries(
adaptiveEfforts.map((effort) => [
effort,
@@ -716,7 +725,7 @@ export function variants(model: Provider.Model): Record<string, Record<string, a
case "@jerome-benoit/sap-ai-provider-v2":
if (model.api.id.includes("anthropic")) {
- if (isAnthropicAdaptive) {
+ if (adaptiveEfforts) {
return Object.fromEntries(
adaptiveEfforts.map((effort) => [
effort,
diff --git a/packages/opencode/test/provider/transform.test.ts b/packages/opencode/test/provider/transform.test.ts
index 0666d0f64..d53ce38b1 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",