Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions packages/opencode/src/provider/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 }
Expand Down
30 changes: 30 additions & 0 deletions packages/opencode/test/provider/transform.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down
Loading