fix: use createAzure in validate-model and fix resourceName fallback (fixes #819)

Two related bugs caused Azure OpenAI to pass validation but fail in actual use:

1. validate-model/route.ts used createOpenAI for Azure, while ai-providers.ts
   uses createAzure. These differ in URL construction and authentication headers
   (api-key vs Authorization: Bearer), so validation did not test the real code
   path. Switch to createAzure for consistency.

2. In ai-providers.ts, when a user provided their own API key without a custom
   base URL, resourceName was unconditionally set to undefined. This left
   createAzure with no endpoint information, resulting in resource not found.
   resourceName is an endpoint component, not a credential, so it is safe to
   fall back to AZURE_RESOURCE_NAME from the environment whenever no baseURL is
   available.
This commit is contained in:
octo-patch
2026-04-22 20:07:28 +08:00
parent d4454beb9a
commit d08b28821e
2 changed files with 8 additions and 7 deletions
+4 -3
View File
@@ -4,6 +4,7 @@ import { createDeepSeek, deepseek } from "@ai-sdk/deepseek"
import { createGateway } from "@ai-sdk/gateway"
import { createGoogleGenerativeAI } from "@ai-sdk/google"
import { createVertex } from "@ai-sdk/google-vertex"
import { createAzure } from "@ai-sdk/azure"
import { createOpenAI } from "@ai-sdk/openai"
import { createOpenRouter } from "@openrouter/ai-sdk-provider"
import { generateText } from "ai"
@@ -126,11 +127,11 @@ export async function POST(req: Request) {
}
case "azure": {
const azure = createOpenAI({
const azureClient = createAzure({
apiKey,
baseURL: baseUrl,
...(baseUrl && { baseURL: baseUrl }),
})
model = azure.chat(modelId)
model = azureClient(modelId)
break
}
+4 -4
View File
@@ -913,10 +913,10 @@ export function getAIModel(overrides?: ClientOverrides): ModelConfig {
overrides?.baseUrl,
serverBaseUrl,
)
// Only use server's resourceName if user is NOT providing their own API key
const resourceName = overrides?.apiKey
? undefined
: process.env.AZURE_RESOURCE_NAME
// Only use server's resourceName when no baseURL is available.
// resourceName is an endpoint component (not a credential), so it is
// safe to use as a fallback even when the user brings their own API key.
const resourceName = !baseURL ? process.env.AZURE_RESOURCE_NAME : undefined
// Azure requires either baseURL or resourceName to construct the endpoint
// resourceName constructs: https://{resourceName}.openai.azure.com/openai/v1{path}
if (baseURL || resourceName || overrides?.apiKey) {