Skip to content

Commit eac82dc

Browse files
committed
fix: respect useCompletionUrls for custom @ai-sdk/azure providers
When a custom provider uses npm: "@ai-sdk/azure", the getLanguage function was falling back to sdk.languageModel() which bypasses the useCompletionUrls option check. This caused the Azure provider to use the /responses endpoint instead of /chat/completions even when useCompletionUrls was set to true. The fix adds a check in getLanguage to apply Azure-specific logic for any model using @ai-sdk/azure, ensuring useCompletionUrls is respected for both built-in and custom Azure providers. Fixes anomalyco#20287
1 parent 3ea7b6a commit eac82dc

2 files changed

Lines changed: 56 additions & 5 deletions

File tree

‎packages/opencode/src/provider/provider.ts‎

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,12 +1416,21 @@ export namespace Provider {
14161416
const sdk = await resolveSDK(model, s)
14171417

14181418
try {
1419+
const mergedOptions = { ...provider.options, ...model.options }
14191420
const language = s.modelLoaders[model.providerID]
1420-
? await s.modelLoaders[model.providerID](sdk, model.api.id, {
1421-
...provider.options,
1422-
...model.options,
1423-
})
1424-
: sdk.languageModel(model.api.id)
1421+
? await s.modelLoaders[model.providerID](sdk, model.api.id, mergedOptions)
1422+
: (() => {
1423+
// For custom providers using @ai-sdk/azure, apply azure-specific logic
1424+
if (model.api.npm === "@ai-sdk/azure") {
1425+
if (useLanguageModel(sdk)) return sdk.languageModel(model.api.id)
1426+
if (mergedOptions["useCompletionUrls"]) {
1427+
return sdk.chat(model.api.id)
1428+
} else {
1429+
return sdk.responses(model.api.id)
1430+
}
1431+
}
1432+
return sdk.languageModel(model.api.id)
1433+
})()
14251434
s.models.set(key, language)
14261435
return language
14271436
} catch (e) {

‎packages/opencode/test/provider/provider.test.ts‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,3 +2282,45 @@ test("cloudflare-ai-gateway forwards config metadata options", async () => {
22822282
},
22832283
})
22842284
})
2285+
2286+
test("custom provider using @ai-sdk/azure respects useCompletionUrls option", async () => {
2287+
await using tmp = await tmpdir({
2288+
init: async (dir) => {
2289+
await Bun.write(
2290+
path.join(dir, "opencode.json"),
2291+
JSON.stringify({
2292+
$schema: "https://opencode.ai/config.json",
2293+
provider: {
2294+
foundary: {
2295+
npm: "@ai-sdk/azure",
2296+
options: {
2297+
baseURL: "https://custom-domain/openai",
2298+
apiKey: "test-key",
2299+
apiVersion: "2025-04-01-preview",
2300+
useDeploymentBasedUrls: true,
2301+
useCompletionUrls: true,
2302+
},
2303+
models: {
2304+
"gpt-5.4": {
2305+
name: "GPT-5.4",
2306+
},
2307+
},
2308+
},
2309+
},
2310+
}),
2311+
)
2312+
},
2313+
})
2314+
await Instance.provide({
2315+
directory: tmp.path,
2316+
fn: async () => {
2317+
const providers = await Provider.list()
2318+
expect(providers[ProviderID.make("foundary")]).toBeDefined()
2319+
expect(providers[ProviderID.make("foundary")].options.useCompletionUrls).toBe(true)
2320+
const model = await Provider.getModel(ProviderID.make("foundary"), ModelID.make("gpt-5.4"))
2321+
expect(model).toBeDefined()
2322+
// Verify the model has the correct npm package
2323+
expect(model.api.npm).toBe("@ai-sdk/azure")
2324+
},
2325+
})
2326+
})

0 commit comments

Comments
 (0)