diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index 471da03cb..407c26878 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -657,9 +657,21 @@ export namespace ProviderTransform { // https://v5.ai-sdk.dev/providers/ai-sdk-providers/perplexity return {} - case "@mymediset/sap-ai-provider": case "@jerome-benoit/sap-ai-provider-v2": if (model.api.id.includes("anthropic")) { + if (isAnthropicAdaptive) { + return Object.fromEntries( + adaptiveEfforts.map((effort) => [ + effort, + { + thinking: { + type: "adaptive", + }, + effort, + }, + ]), + ) + } return { high: { thinking: { @@ -675,7 +687,26 @@ export namespace ProviderTransform { }, } } - return Object.fromEntries(WIDELY_SUPPORTED_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }])) + if (model.api.id.includes("gemini") && id.includes("2.5")) { + return { + high: { + thinkingConfig: { + includeThoughts: true, + thinkingBudget: 16000, + }, + }, + max: { + thinkingConfig: { + includeThoughts: true, + thinkingBudget: 24576, + }, + }, + } + } + if (model.api.id.includes("gpt") || /\bo[1-9]/.test(model.api.id)) { + return Object.fromEntries(WIDELY_SUPPORTED_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }])) + } + return {} } return {} } diff --git a/packages/opencode/test/provider/transform.test.ts b/packages/opencode/test/provider/transform.test.ts index 512819a65..b6d3afc2d 100644 --- a/packages/opencode/test/provider/transform.test.ts +++ b/packages/opencode/test/provider/transform.test.ts @@ -2479,4 +2479,145 @@ describe("ProviderTransform.variants", () => { expect(result).toEqual({}) }) }) + + describe("@jerome-benoit/sap-ai-provider-v2", () => { + test("anthropic models return thinking variants", () => { + const model = createMockModel({ + id: "sap-ai-core/anthropic--claude-sonnet-4", + providerID: "sap-ai-core", + api: { + id: "anthropic--claude-sonnet-4", + url: "https://api.ai.sap", + npm: "@jerome-benoit/sap-ai-provider-v2", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["high", "max"]) + expect(result.high).toEqual({ + thinking: { + type: "enabled", + budgetTokens: 16000, + }, + }) + expect(result.max).toEqual({ + thinking: { + type: "enabled", + budgetTokens: 31999, + }, + }) + }) + + test("anthropic 4.6 models return adaptive thinking variants", () => { + const model = createMockModel({ + id: "sap-ai-core/anthropic--claude-sonnet-4-6", + providerID: "sap-ai-core", + api: { + id: "anthropic--claude-sonnet-4-6", + url: "https://api.ai.sap", + npm: "@jerome-benoit/sap-ai-provider-v2", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high", "max"]) + expect(result.low).toEqual({ + thinking: { + type: "adaptive", + }, + effort: "low", + }) + expect(result.max).toEqual({ + thinking: { + type: "adaptive", + }, + effort: "max", + }) + }) + + test("gemini 2.5 models return thinkingConfig variants", () => { + const model = createMockModel({ + id: "sap-ai-core/gcp--gemini-2.5-pro", + providerID: "sap-ai-core", + api: { + id: "gcp--gemini-2.5-pro", + url: "https://api.ai.sap", + npm: "@jerome-benoit/sap-ai-provider-v2", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["high", "max"]) + expect(result.high).toEqual({ + thinkingConfig: { + includeThoughts: true, + thinkingBudget: 16000, + }, + }) + expect(result.max).toEqual({ + thinkingConfig: { + includeThoughts: true, + thinkingBudget: 24576, + }, + }) + }) + + test("gpt models return reasoningEffort variants", () => { + const model = createMockModel({ + id: "sap-ai-core/azure-openai--gpt-4o", + providerID: "sap-ai-core", + api: { + id: "azure-openai--gpt-4o", + url: "https://api.ai.sap", + npm: "@jerome-benoit/sap-ai-provider-v2", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high"]) + expect(result.low).toEqual({ reasoningEffort: "low" }) + expect(result.high).toEqual({ reasoningEffort: "high" }) + }) + + test("o-series models return reasoningEffort variants", () => { + const model = createMockModel({ + id: "sap-ai-core/azure-openai--o3-mini", + providerID: "sap-ai-core", + api: { + id: "azure-openai--o3-mini", + url: "https://api.ai.sap", + npm: "@jerome-benoit/sap-ai-provider-v2", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "medium", "high"]) + expect(result.low).toEqual({ reasoningEffort: "low" }) + expect(result.high).toEqual({ reasoningEffort: "high" }) + }) + + + test("sonar models return empty object", () => { + const model = createMockModel({ + id: "sap-ai-core/perplexity--sonar-pro", + providerID: "sap-ai-core", + api: { + id: "perplexity--sonar-pro", + url: "https://api.ai.sap", + npm: "@jerome-benoit/sap-ai-provider-v2", + }, + }) + const result = ProviderTransform.variants(model) + expect(result).toEqual({}) + }) + + test("mistral models return empty object", () => { + const model = createMockModel({ + id: "sap-ai-core/mistral--mistral-large", + providerID: "sap-ai-core", + api: { + id: "mistral--mistral-large", + url: "https://api.ai.sap", + npm: "@jerome-benoit/sap-ai-provider-v2", + }, + }) + const result = ProviderTransform.variants(model) + expect(result).toEqual({}) + }) + }) })