Просмотр исходного кода

fix: ensure vercel variants pass amazon models under bedrock key (#13631)

Aiden Cline 1 месяц назад
Родитель
Сommit
933a491ade

+ 11 - 3
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<string, string> = {
+    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.)
       // - `<upstream slug>`: 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 }

+ 30 - 0
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", () => {