From 75ffda0ef148a73f9a55ae0e7e2c43f488d31afb Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Sat, 14 Feb 2026 12:54:12 -0600 Subject: [PATCH] fix: ensure vercel variants pass amazon models under bedrock key --- packages/opencode/src/provider/transform.ts | 14 +++++++-- .../opencode/test/provider/transform.test.ts | 30 +++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index b4eb14a2ffa7..1c92f528ee74 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -802,15 +802,22 @@ export namespace ProviderTransform { return {} } + // Maps model ID prefix to provider slug used in providerOptions. + // Example: "amazon/nova-2-lite" → "bedrock" + const SLUG_OVERRIDES: Record = { + amazon: "bedrock", + } + export function providerOptions(model: Provider.Model, options: { [x: string]: any }) { if (model.api.npm === "@ai-sdk/gateway") { // Gateway providerOptions are split across two namespaces: - // - `gateway`: gateway-native routing/caching controls + // - `gateway`: gateway-native routing/caching controls (order, only, byok, etc.) // - ``: provider-specific model options (anthropic/openai/...) // We keep `gateway` as-is and route every other top-level option under the - // model-derived upstream slug so variants/options can stay flat internally. + // model-derived upstream slug. const i = model.api.id.indexOf("/") - const slug = i > 0 ? model.api.id.slice(0, i) : undefined + const rawSlug = i > 0 ? model.api.id.slice(0, i) : undefined + const slug = rawSlug ? (SLUG_OVERRIDES[rawSlug] ?? rawSlug) : undefined const gateway = options.gateway const rest = Object.fromEntries(Object.entries(options).filter(([k]) => k !== "gateway")) const has = Object.keys(rest).length > 0 @@ -820,6 +827,7 @@ export namespace ProviderTransform { if (has) { if (slug) { + // Route model-specific options under the provider slug result[slug] = rest } else if (gateway && typeof gateway === "object" && !Array.isArray(gateway)) { result.gateway = { ...gateway, ...rest } diff --git a/packages/opencode/test/provider/transform.test.ts b/packages/opencode/test/provider/transform.test.ts index 99acfcc81763..3494cb56fdd0 100644 --- a/packages/opencode/test/provider/transform.test.ts +++ b/packages/opencode/test/provider/transform.test.ts @@ -341,6 +341,36 @@ describe("ProviderTransform.providerOptions", () => { gateway: { reasoningEffort: "high" }, }) }) + + test("maps amazon slug to bedrock for provider options", () => { + const model = createModel({ + providerID: "vercel", + api: { + id: "amazon/nova-2-lite", + url: "https://ai-gateway.vercel.sh/v3/ai", + npm: "@ai-sdk/gateway", + }, + }) + + expect(ProviderTransform.providerOptions(model, { reasoningConfig: { type: "enabled" } })).toEqual({ + bedrock: { reasoningConfig: { type: "enabled" } }, + }) + }) + + test("uses groq slug for groq models", () => { + const model = createModel({ + providerID: "vercel", + api: { + id: "groq/llama-3.3-70b-versatile", + url: "https://ai-gateway.vercel.sh/v3/ai", + npm: "@ai-sdk/gateway", + }, + }) + + expect(ProviderTransform.providerOptions(model, { reasoningFormat: "parsed" })).toEqual({ + groq: { reasoningFormat: "parsed" }, + }) + }) }) describe("ProviderTransform.schema - gemini array items", () => {