summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJérôme Benoit <[email protected]>2026-03-10 16:05:45 +0100
committerGitHub <[email protected]>2026-03-10 10:05:45 -0500
commit4dce485854df0719800c51a1182270ee21c075f9 (patch)
treed2fd7f3633319651039e8f2f41658102f62e1100
parent5ec5d1daceaab23c8ffa9ae32b40f53120f4609e (diff)
downloadopencode-4dce485854df0719800c51a1182270ee21c075f9.tar.gz
opencode-4dce485854df0719800c51a1182270ee21c075f9.zip
fix(opencode): add thinking variants support for SAP AI provider (#14958)
Co-authored-by: Test <[email protected]> Co-authored-by: Stephen Collings <[email protected]>
-rw-r--r--packages/opencode/src/provider/transform.ts35
-rw-r--r--packages/opencode/test/provider/transform.test.ts141
2 files changed, 174 insertions, 2 deletions
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({})
+ })
+ })
})