@ai-sdk/azure 4.0.54 → 4.0.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +25 -6
- package/dist/index.js.map +1 -1
- package/docs/04-azure.mdx +23 -1
- package/package.json +1 -1
- package/src/azure-openai-provider.ts +39 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @ai-sdk/azure
|
|
2
2
|
|
|
3
|
+
## 4.0.55
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 993e900: Construct OpenAI v1 URLs for Azure AI Foundry (`*.services.ai.azure.com`) and Cognitive Services (`*.cognitiveservices.azure.com`) hostnames while preserving complete v1 and Foundry project base URLs.
|
|
8
|
+
|
|
3
9
|
## 4.0.54
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -82,7 +82,8 @@ interface AzureOpenAIProviderSettings {
|
|
|
82
82
|
* Use a different URL prefix for API calls, e.g. to use proxy servers. Either this or `resourceName` can be used.
|
|
83
83
|
* When a baseURL is provided, the resourceName is ignored.
|
|
84
84
|
*
|
|
85
|
-
* With an Azure OpenAI baseURL, the resolved URL is `{baseURL}/v1{path}`.
|
|
85
|
+
* With an unversioned Azure OpenAI baseURL, the resolved URL is `{baseURL}/v1{path}`.
|
|
86
|
+
* Azure OpenAI base URLs that already end in `/openai/v1` are used as-is.
|
|
86
87
|
* With a non-Azure custom gateway baseURL, the resolved URL is `{baseURL}{path}`.
|
|
87
88
|
*/
|
|
88
89
|
baseURL?: string;
|
|
@@ -106,7 +107,8 @@ interface AzureOpenAIProviderSettings {
|
|
|
106
107
|
*/
|
|
107
108
|
fetch?: FetchFunction;
|
|
108
109
|
/**
|
|
109
|
-
* Custom api version to use. Defaults to `
|
|
110
|
+
* Custom api version to use. Defaults to `v1`.
|
|
111
|
+
* Complete v1 base URLs are used as-is.
|
|
110
112
|
*/
|
|
111
113
|
apiVersion?: string;
|
|
112
114
|
/**
|
package/dist/index.js
CHANGED
|
@@ -37,11 +37,26 @@ var azureOpenaiTools = {
|
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
// src/version.ts
|
|
40
|
-
var VERSION = true ? "4.0.
|
|
40
|
+
var VERSION = true ? "4.0.55" : "0.0.0-test";
|
|
41
41
|
|
|
42
42
|
// src/azure-openai-provider.ts
|
|
43
|
-
function
|
|
44
|
-
|
|
43
|
+
function getAzureOpenAIBaseURLInfo(baseURL) {
|
|
44
|
+
if (baseURL == null) {
|
|
45
|
+
return {
|
|
46
|
+
isAzureOpenAI: true,
|
|
47
|
+
isFoundryProject: false,
|
|
48
|
+
isVersioned: false
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const url = new URL(baseURL);
|
|
52
|
+
const hostname = url.hostname;
|
|
53
|
+
const isAzureOpenAI = hostname.endsWith(".openai.azure.com") || hostname.endsWith(".services.ai.azure.com") || hostname.endsWith(".cognitiveservices.azure.com");
|
|
54
|
+
const pathname = url.pathname.replace(/\/+$/, "");
|
|
55
|
+
return {
|
|
56
|
+
isAzureOpenAI,
|
|
57
|
+
isFoundryProject: hostname.endsWith(".services.ai.azure.com") && pathname.startsWith("/api/projects/"),
|
|
58
|
+
isVersioned: isAzureOpenAI && pathname.toLowerCase().endsWith("/openai/v1")
|
|
59
|
+
};
|
|
45
60
|
}
|
|
46
61
|
function createAzure(options = {}) {
|
|
47
62
|
var _a;
|
|
@@ -86,7 +101,11 @@ function createAzure(options = {}) {
|
|
|
86
101
|
description: "Azure OpenAI resource name"
|
|
87
102
|
});
|
|
88
103
|
const apiVersion = (_a = options.apiVersion) != null ? _a : "v1";
|
|
89
|
-
const
|
|
104
|
+
const {
|
|
105
|
+
isAzureOpenAI,
|
|
106
|
+
isFoundryProject,
|
|
107
|
+
isVersioned: isAzureOpenAIVersioned
|
|
108
|
+
} = getAzureOpenAIBaseURLInfo(options.baseURL);
|
|
90
109
|
const url = ({ path, modelId }) => {
|
|
91
110
|
var _a2;
|
|
92
111
|
const baseUrlPrefix = withoutTrailingSlash(
|
|
@@ -95,12 +114,12 @@ function createAzure(options = {}) {
|
|
|
95
114
|
let fullUrl;
|
|
96
115
|
if (options.useDeploymentBasedUrls) {
|
|
97
116
|
fullUrl = new URL(`${baseUrlPrefix}/deployments/${modelId}${path}`);
|
|
98
|
-
} else if (!
|
|
117
|
+
} else if (!isAzureOpenAI || isAzureOpenAIVersioned) {
|
|
99
118
|
fullUrl = new URL(`${baseUrlPrefix}${path}`);
|
|
100
119
|
} else {
|
|
101
120
|
fullUrl = new URL(`${baseUrlPrefix}/v1${path}`);
|
|
102
121
|
}
|
|
103
|
-
if (
|
|
122
|
+
if (options.useDeploymentBasedUrls || isAzureOpenAI && !isAzureOpenAIVersioned && !isFoundryProject) {
|
|
104
123
|
fullUrl.searchParams.set("api-version", apiVersion);
|
|
105
124
|
}
|
|
106
125
|
return fullUrl.toString();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/azure-openai-provider.ts","../src/azure-openai-tools.ts","../src/version.ts"],"sourcesContent":["import {\n OpenAIChatLanguageModel,\n OpenAICompletionLanguageModel,\n OpenAIEmbeddingModel,\n OpenAIImageModel,\n OpenAIResponsesLanguageModel,\n OpenAISpeechModel,\n OpenAITranscriptionModel,\n} from '@ai-sdk/openai/internal';\nimport { DeepSeekChatLanguageModel } from '@ai-sdk/deepseek/internal';\nimport {\n InvalidArgumentError,\n type EmbeddingModelV4,\n type LanguageModelV4,\n type ProviderV4,\n type ImageModelV4,\n type SpeechModelV4,\n type TranscriptionModelV4,\n} from '@ai-sdk/provider';\nimport {\n loadApiKey,\n loadSetting,\n normalizeHeaders,\n withoutTrailingSlash,\n withUserAgentSuffix,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { azureOpenaiTools } from './azure-openai-tools';\nimport { VERSION } from './version';\n\nexport interface AzureOpenAIProvider extends ProviderV4 {\n (deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure OpenAI responses API model for text generation.\n */\n languageModel(deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure OpenAI chat model for text generation.\n */\n chat(deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure-hosted DeepSeek chat model for text generation.\n */\n deepseek(deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure OpenAI responses API model for text generation.\n */\n responses(deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure OpenAI completion model for text generation.\n */\n completion(deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure OpenAI model for text embeddings.\n */\n embedding(deploymentId: string): EmbeddingModelV4;\n\n /**\n * Creates an Azure OpenAI model for text embeddings.\n */\n embeddingModel(deploymentId: string): EmbeddingModelV4;\n\n /**\n * @deprecated Use `embedding` instead.\n */\n textEmbedding(deploymentId: string): EmbeddingModelV4;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(deploymentId: string): EmbeddingModelV4;\n\n /**\n * Creates an Azure OpenAI DALL-E model for image generation.\n */\n image(deploymentId: string): ImageModelV4;\n\n /**\n * Creates an Azure OpenAI DALL-E model for image generation.\n */\n imageModel(deploymentId: string): ImageModelV4;\n\n /**\n * Creates an Azure OpenAI model for audio transcription.\n */\n transcription(deploymentId: string): TranscriptionModelV4;\n\n /**\n * Creates an Azure OpenAI model for speech generation.\n */\n speech(deploymentId: string): SpeechModelV4;\n\n /**\n * AzureOpenAI-specific tools.\n */\n tools: typeof azureOpenaiTools;\n}\n\nexport interface AzureOpenAIProviderSettings {\n /**\n * Name of the Azure OpenAI resource. Either this or `baseURL` can be used.\n *\n * The resource name is used in the assembled URL: `https://{resourceName}.openai.azure.com/openai/v1{path}`.\n */\n resourceName?: string;\n\n /**\n * Use a different URL prefix for API calls, e.g. to use proxy servers. Either this or `resourceName` can be used.\n * When a baseURL is provided, the resourceName is ignored.\n *\n * With an Azure OpenAI baseURL, the resolved URL is `{baseURL}/v1{path}`.\n * With a non-Azure custom gateway baseURL, the resolved URL is `{baseURL}{path}`.\n */\n baseURL?: string;\n\n /**\n * API key for authenticating requests.\n */\n apiKey?: string;\n\n /**\n * A function that returns an access token for Microsoft Entra\n * (formerly known as Azure Active Directory), which will be invoked\n * on every request.\n */\n tokenProvider?: (() => Promise<string>) | undefined;\n\n /**\n * Custom headers to include in the requests.\n */\n headers?: Record<string, string>;\n\n /**\n * Custom fetch implementation. You can use it as a middleware to intercept requests,\n * or to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n\n /**\n * Custom api version to use. Defaults to `preview`.\n */\n apiVersion?: string;\n\n /**\n * Use deployment-based URLs for specific model types. Set to true to use legacy deployment format:\n * `{baseURL}/deployments/{deploymentId}{path}?api-version={apiVersion}` instead of\n * `{baseURL}/v1{path}?api-version={apiVersion}`.\n */\n useDeploymentBasedUrls?: boolean;\n}\n\nfunction isAzureOpenAIBaseURL(baseURL: string | undefined) {\n return (\n baseURL == null || new URL(baseURL).hostname.endsWith('.openai.azure.com')\n );\n}\n\n/**\n * Create an Azure OpenAI provider instance.\n */\nexport function createAzure(\n options: AzureOpenAIProviderSettings = {},\n): AzureOpenAIProvider {\n const tokenProvider = options.tokenProvider;\n\n if (options.apiKey && tokenProvider) {\n throw new InvalidArgumentError({\n argument: 'apiKey/tokenProvider',\n message:\n 'Both apiKey and tokenProvider were provided. Please use only one authentication method.',\n });\n }\n\n const getHeaders = () => {\n const authHeaders = tokenProvider\n ? {}\n : {\n 'api-key': loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'AZURE_API_KEY',\n description: 'Azure OpenAI',\n }),\n };\n\n return withUserAgentSuffix(\n {\n ...authHeaders,\n ...options.headers,\n },\n `ai-sdk/azure/${VERSION}`,\n );\n };\n\n const fetch: FetchFunction | undefined = tokenProvider\n ? async (input, init) => {\n const headers = normalizeHeaders(init?.headers);\n\n if (headers.authorization == null) {\n headers.authorization = `Bearer ${await tokenProvider()}`;\n }\n\n return (options.fetch ?? globalThis.fetch)(input, {\n ...init,\n headers,\n });\n }\n : options.fetch;\n\n const getResourceName = () =>\n loadSetting({\n settingValue: options.resourceName,\n settingName: 'resourceName',\n environmentVariableName: 'AZURE_RESOURCE_NAME',\n description: 'Azure OpenAI resource name',\n });\n\n const apiVersion = options.apiVersion ?? 'v1';\n const useAzureOpenAIEndpoint = isAzureOpenAIBaseURL(options.baseURL);\n\n const url = ({ path, modelId }: { path: string; modelId: string }) => {\n const baseUrlPrefix = withoutTrailingSlash(\n options.baseURL ?? `https://${getResourceName()}.openai.azure.com/openai`,\n );\n\n let fullUrl: URL;\n if (options.useDeploymentBasedUrls) {\n // Use deployment-based format for compatibility with certain Azure OpenAI models\n fullUrl = new URL(`${baseUrlPrefix}/deployments/${modelId}${path}`);\n } else if (!useAzureOpenAIEndpoint) {\n // Custom gateways can own Azure routing and versioning themselves.\n fullUrl = new URL(`${baseUrlPrefix}${path}`);\n } else {\n // Use v1 API format - no deployment ID in URL\n fullUrl = new URL(`${baseUrlPrefix}/v1${path}`);\n }\n\n if (useAzureOpenAIEndpoint || options.useDeploymentBasedUrls) {\n fullUrl.searchParams.set('api-version', apiVersion);\n }\n\n return fullUrl.toString();\n };\n\n const createChatModel = (deploymentName: string) =>\n new OpenAIChatLanguageModel(deploymentName, {\n provider: 'azure.chat',\n url,\n headers: getHeaders,\n fetch,\n });\n\n const createDeepSeekModel = (deploymentName: string) =>\n new DeepSeekChatLanguageModel(deploymentName, {\n provider: 'azure.deepseek',\n url,\n headers: getHeaders,\n fetch,\n supportsPenaltySampling: true,\n supportsThinking: false,\n // json_object with thinking enabled makes Azure return the JSON in reasoning_content with empty content\n supportsStructuredOutputs: true,\n });\n\n const createCompletionModel = (modelId: string) =>\n new OpenAICompletionLanguageModel(modelId, {\n provider: 'azure.completion',\n url,\n headers: getHeaders,\n fetch,\n });\n\n const createEmbeddingModel = (modelId: string) =>\n new OpenAIEmbeddingModel(modelId, {\n provider: 'azure.embeddings',\n headers: getHeaders,\n url,\n fetch,\n });\n\n const createResponsesModel = (modelId: string) =>\n new OpenAIResponsesLanguageModel(modelId, {\n provider: 'azure.responses',\n url,\n headers: getHeaders,\n fetch,\n // Soft-deprecated. TODO: remove in v8\n fileIdPrefixes: ['assistant-'],\n });\n\n const createImageModel = (modelId: string) =>\n new OpenAIImageModel(modelId, {\n provider: 'azure.image',\n url,\n headers: getHeaders,\n fetch,\n });\n\n const createTranscriptionModel = (modelId: string) =>\n new OpenAITranscriptionModel(modelId, {\n provider: 'azure.transcription',\n url,\n headers: getHeaders,\n fetch,\n });\n\n const createSpeechModel = (modelId: string) =>\n new OpenAISpeechModel(modelId, {\n provider: 'azure.speech',\n url,\n headers: getHeaders,\n fetch,\n });\n\n const provider = function (deploymentId: string) {\n if (new.target) {\n throw new Error(\n 'The Azure OpenAI model function cannot be called with the new keyword.',\n );\n }\n\n return createResponsesModel(deploymentId);\n };\n\n provider.specificationVersion = 'v4' as const;\n provider.languageModel = createResponsesModel;\n provider.chat = createChatModel;\n provider.deepseek = createDeepSeekModel;\n provider.completion = createCompletionModel;\n provider.embedding = createEmbeddingModel;\n provider.embeddingModel = createEmbeddingModel;\n provider.textEmbedding = createEmbeddingModel;\n provider.textEmbeddingModel = createEmbeddingModel;\n provider.image = createImageModel;\n provider.imageModel = createImageModel;\n provider.responses = createResponsesModel;\n provider.transcription = createTranscriptionModel;\n provider.speech = createSpeechModel;\n provider.tools = azureOpenaiTools;\n return provider;\n}\n\n/**\n * Default Azure OpenAI provider instance.\n */\nexport const azure = createAzure();\n","import {\n codeInterpreter,\n fileSearch,\n imageGeneration,\n webSearch,\n webSearchPreview,\n} from '@ai-sdk/openai/internal';\n\nexport const azureOpenaiTools: {\n codeInterpreter: typeof codeInterpreter;\n fileSearch: typeof fileSearch;\n imageGeneration: typeof imageGeneration;\n webSearch: typeof webSearch;\n webSearchPreview: typeof webSearchPreview;\n} = {\n codeInterpreter,\n fileSearch,\n imageGeneration,\n webSearch,\n webSearchPreview,\n};\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n"],"mappings":"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","names":["_a"]}
|
|
1
|
+
{"version":3,"sources":["../src/azure-openai-provider.ts","../src/azure-openai-tools.ts","../src/version.ts"],"sourcesContent":["import {\n OpenAIChatLanguageModel,\n OpenAICompletionLanguageModel,\n OpenAIEmbeddingModel,\n OpenAIImageModel,\n OpenAIResponsesLanguageModel,\n OpenAISpeechModel,\n OpenAITranscriptionModel,\n} from '@ai-sdk/openai/internal';\nimport { DeepSeekChatLanguageModel } from '@ai-sdk/deepseek/internal';\nimport {\n InvalidArgumentError,\n type EmbeddingModelV4,\n type LanguageModelV4,\n type ProviderV4,\n type ImageModelV4,\n type SpeechModelV4,\n type TranscriptionModelV4,\n} from '@ai-sdk/provider';\nimport {\n loadApiKey,\n loadSetting,\n normalizeHeaders,\n withoutTrailingSlash,\n withUserAgentSuffix,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { azureOpenaiTools } from './azure-openai-tools';\nimport { VERSION } from './version';\n\nexport interface AzureOpenAIProvider extends ProviderV4 {\n (deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure OpenAI responses API model for text generation.\n */\n languageModel(deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure OpenAI chat model for text generation.\n */\n chat(deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure-hosted DeepSeek chat model for text generation.\n */\n deepseek(deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure OpenAI responses API model for text generation.\n */\n responses(deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure OpenAI completion model for text generation.\n */\n completion(deploymentId: string): LanguageModelV4;\n\n /**\n * Creates an Azure OpenAI model for text embeddings.\n */\n embedding(deploymentId: string): EmbeddingModelV4;\n\n /**\n * Creates an Azure OpenAI model for text embeddings.\n */\n embeddingModel(deploymentId: string): EmbeddingModelV4;\n\n /**\n * @deprecated Use `embedding` instead.\n */\n textEmbedding(deploymentId: string): EmbeddingModelV4;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(deploymentId: string): EmbeddingModelV4;\n\n /**\n * Creates an Azure OpenAI DALL-E model for image generation.\n */\n image(deploymentId: string): ImageModelV4;\n\n /**\n * Creates an Azure OpenAI DALL-E model for image generation.\n */\n imageModel(deploymentId: string): ImageModelV4;\n\n /**\n * Creates an Azure OpenAI model for audio transcription.\n */\n transcription(deploymentId: string): TranscriptionModelV4;\n\n /**\n * Creates an Azure OpenAI model for speech generation.\n */\n speech(deploymentId: string): SpeechModelV4;\n\n /**\n * AzureOpenAI-specific tools.\n */\n tools: typeof azureOpenaiTools;\n}\n\nexport interface AzureOpenAIProviderSettings {\n /**\n * Name of the Azure OpenAI resource. Either this or `baseURL` can be used.\n *\n * The resource name is used in the assembled URL: `https://{resourceName}.openai.azure.com/openai/v1{path}`.\n */\n resourceName?: string;\n\n /**\n * Use a different URL prefix for API calls, e.g. to use proxy servers. Either this or `resourceName` can be used.\n * When a baseURL is provided, the resourceName is ignored.\n *\n * With an unversioned Azure OpenAI baseURL, the resolved URL is `{baseURL}/v1{path}`.\n * Azure OpenAI base URLs that already end in `/openai/v1` are used as-is.\n * With a non-Azure custom gateway baseURL, the resolved URL is `{baseURL}{path}`.\n */\n baseURL?: string;\n\n /**\n * API key for authenticating requests.\n */\n apiKey?: string;\n\n /**\n * A function that returns an access token for Microsoft Entra\n * (formerly known as Azure Active Directory), which will be invoked\n * on every request.\n */\n tokenProvider?: (() => Promise<string>) | undefined;\n\n /**\n * Custom headers to include in the requests.\n */\n headers?: Record<string, string>;\n\n /**\n * Custom fetch implementation. You can use it as a middleware to intercept requests,\n * or to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n\n /**\n * Custom api version to use. Defaults to `v1`.\n * Complete v1 base URLs are used as-is.\n */\n apiVersion?: string;\n\n /**\n * Use deployment-based URLs for specific model types. Set to true to use legacy deployment format:\n * `{baseURL}/deployments/{deploymentId}{path}?api-version={apiVersion}` instead of\n * `{baseURL}/v1{path}?api-version={apiVersion}`.\n */\n useDeploymentBasedUrls?: boolean;\n}\n\nfunction getAzureOpenAIBaseURLInfo(baseURL: string | undefined) {\n if (baseURL == null) {\n return {\n isAzureOpenAI: true,\n isFoundryProject: false,\n isVersioned: false,\n };\n }\n\n const url = new URL(baseURL);\n const hostname = url.hostname;\n const isAzureOpenAI =\n hostname.endsWith('.openai.azure.com') ||\n hostname.endsWith('.services.ai.azure.com') ||\n hostname.endsWith('.cognitiveservices.azure.com');\n const pathname = url.pathname.replace(/\\/+$/, '');\n\n return {\n isAzureOpenAI,\n isFoundryProject:\n hostname.endsWith('.services.ai.azure.com') &&\n pathname.startsWith('/api/projects/'),\n isVersioned: isAzureOpenAI && pathname.toLowerCase().endsWith('/openai/v1'),\n };\n}\n\n/**\n * Create an Azure OpenAI provider instance.\n */\nexport function createAzure(\n options: AzureOpenAIProviderSettings = {},\n): AzureOpenAIProvider {\n const tokenProvider = options.tokenProvider;\n\n if (options.apiKey && tokenProvider) {\n throw new InvalidArgumentError({\n argument: 'apiKey/tokenProvider',\n message:\n 'Both apiKey and tokenProvider were provided. Please use only one authentication method.',\n });\n }\n\n const getHeaders = () => {\n const authHeaders = tokenProvider\n ? {}\n : {\n 'api-key': loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'AZURE_API_KEY',\n description: 'Azure OpenAI',\n }),\n };\n\n return withUserAgentSuffix(\n {\n ...authHeaders,\n ...options.headers,\n },\n `ai-sdk/azure/${VERSION}`,\n );\n };\n\n const fetch: FetchFunction | undefined = tokenProvider\n ? async (input, init) => {\n const headers = normalizeHeaders(init?.headers);\n\n if (headers.authorization == null) {\n headers.authorization = `Bearer ${await tokenProvider()}`;\n }\n\n return (options.fetch ?? globalThis.fetch)(input, {\n ...init,\n headers,\n });\n }\n : options.fetch;\n\n const getResourceName = () =>\n loadSetting({\n settingValue: options.resourceName,\n settingName: 'resourceName',\n environmentVariableName: 'AZURE_RESOURCE_NAME',\n description: 'Azure OpenAI resource name',\n });\n\n const apiVersion = options.apiVersion ?? 'v1';\n const {\n isAzureOpenAI,\n isFoundryProject,\n isVersioned: isAzureOpenAIVersioned,\n } = getAzureOpenAIBaseURLInfo(options.baseURL);\n\n const url = ({ path, modelId }: { path: string; modelId: string }) => {\n const baseUrlPrefix = withoutTrailingSlash(\n options.baseURL ?? `https://${getResourceName()}.openai.azure.com/openai`,\n );\n\n let fullUrl: URL;\n if (options.useDeploymentBasedUrls) {\n // Use deployment-based format for compatibility with certain Azure OpenAI models\n fullUrl = new URL(`${baseUrlPrefix}/deployments/${modelId}${path}`);\n } else if (!isAzureOpenAI || isAzureOpenAIVersioned) {\n // Custom gateways can own Azure routing and versioning themselves.\n // Complete Azure OpenAI v1 URLs also own their versioning.\n fullUrl = new URL(`${baseUrlPrefix}${path}`);\n } else {\n // Use v1 API format - no deployment ID in URL\n fullUrl = new URL(`${baseUrlPrefix}/v1${path}`);\n }\n\n if (\n options.useDeploymentBasedUrls ||\n (isAzureOpenAI && !isAzureOpenAIVersioned && !isFoundryProject)\n ) {\n fullUrl.searchParams.set('api-version', apiVersion);\n }\n\n return fullUrl.toString();\n };\n\n const createChatModel = (deploymentName: string) =>\n new OpenAIChatLanguageModel(deploymentName, {\n provider: 'azure.chat',\n url,\n headers: getHeaders,\n fetch,\n });\n\n const createDeepSeekModel = (deploymentName: string) =>\n new DeepSeekChatLanguageModel(deploymentName, {\n provider: 'azure.deepseek',\n url,\n headers: getHeaders,\n fetch,\n supportsPenaltySampling: true,\n supportsThinking: false,\n // json_object with thinking enabled makes Azure return the JSON in reasoning_content with empty content\n supportsStructuredOutputs: true,\n });\n\n const createCompletionModel = (modelId: string) =>\n new OpenAICompletionLanguageModel(modelId, {\n provider: 'azure.completion',\n url,\n headers: getHeaders,\n fetch,\n });\n\n const createEmbeddingModel = (modelId: string) =>\n new OpenAIEmbeddingModel(modelId, {\n provider: 'azure.embeddings',\n headers: getHeaders,\n url,\n fetch,\n });\n\n const createResponsesModel = (modelId: string) =>\n new OpenAIResponsesLanguageModel(modelId, {\n provider: 'azure.responses',\n url,\n headers: getHeaders,\n fetch,\n // Soft-deprecated. TODO: remove in v8\n fileIdPrefixes: ['assistant-'],\n });\n\n const createImageModel = (modelId: string) =>\n new OpenAIImageModel(modelId, {\n provider: 'azure.image',\n url,\n headers: getHeaders,\n fetch,\n });\n\n const createTranscriptionModel = (modelId: string) =>\n new OpenAITranscriptionModel(modelId, {\n provider: 'azure.transcription',\n url,\n headers: getHeaders,\n fetch,\n });\n\n const createSpeechModel = (modelId: string) =>\n new OpenAISpeechModel(modelId, {\n provider: 'azure.speech',\n url,\n headers: getHeaders,\n fetch,\n });\n\n const provider = function (deploymentId: string) {\n if (new.target) {\n throw new Error(\n 'The Azure OpenAI model function cannot be called with the new keyword.',\n );\n }\n\n return createResponsesModel(deploymentId);\n };\n\n provider.specificationVersion = 'v4' as const;\n provider.languageModel = createResponsesModel;\n provider.chat = createChatModel;\n provider.deepseek = createDeepSeekModel;\n provider.completion = createCompletionModel;\n provider.embedding = createEmbeddingModel;\n provider.embeddingModel = createEmbeddingModel;\n provider.textEmbedding = createEmbeddingModel;\n provider.textEmbeddingModel = createEmbeddingModel;\n provider.image = createImageModel;\n provider.imageModel = createImageModel;\n provider.responses = createResponsesModel;\n provider.transcription = createTranscriptionModel;\n provider.speech = createSpeechModel;\n provider.tools = azureOpenaiTools;\n return provider;\n}\n\n/**\n * Default Azure OpenAI provider instance.\n */\nexport const azure = createAzure();\n","import {\n codeInterpreter,\n fileSearch,\n imageGeneration,\n webSearch,\n webSearchPreview,\n} from '@ai-sdk/openai/internal';\n\nexport const azureOpenaiTools: {\n codeInterpreter: typeof codeInterpreter;\n fileSearch: typeof fileSearch;\n imageGeneration: typeof imageGeneration;\n webSearch: typeof webSearch;\n webSearchPreview: typeof webSearchPreview;\n} = {\n codeInterpreter,\n fileSearch,\n imageGeneration,\n webSearch,\n webSearchPreview,\n};\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n"],"mappings":"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","names":["_a"]}
|
package/docs/04-azure.mdx
CHANGED
|
@@ -32,6 +32,15 @@ const azure = createAzure({
|
|
|
32
32
|
});
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
You can also use a complete [Microsoft Foundry OpenAI v1 base URL](https://learn.microsoft.com/en-us/azure/foundry/openai/api-version-lifecycle#model-support):
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
const azure = createAzure({
|
|
39
|
+
baseURL: 'https://your-resource.services.ai.azure.com/openai/v1',
|
|
40
|
+
apiKey: 'your-api-key',
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
35
44
|
For Microsoft Entra ID authentication, you can provide a token provider.
|
|
36
45
|
Install `@azure/identity` separately if you want to use its credential helpers:
|
|
37
46
|
|
|
@@ -76,6 +85,8 @@ You can use the following optional settings to customize the OpenAI provider ins
|
|
|
76
85
|
|
|
77
86
|
Sets a custom [api version](https://learn.microsoft.com/en-us/azure/ai-services/openai/api-version-deprecation).
|
|
78
87
|
Defaults to `v1`.
|
|
88
|
+
This setting is applied when the provider constructs the v1 path or uses
|
|
89
|
+
deployment-based URLs. Complete v1 base URLs are used as-is.
|
|
79
90
|
|
|
80
91
|
- **baseURL** _string_
|
|
81
92
|
|
|
@@ -84,7 +95,18 @@ You can use the following optional settings to customize the OpenAI provider ins
|
|
|
84
95
|
Either this or `resourceName` can be used.
|
|
85
96
|
When a baseURL is provided, the resourceName is ignored.
|
|
86
97
|
|
|
87
|
-
|
|
98
|
+
For Azure-hosted URLs ending in `.openai.azure.com`,
|
|
99
|
+
`.services.ai.azure.com`, or `.cognitiveservices.azure.com`, you can pass
|
|
100
|
+
either an unversioned OpenAI prefix such as `https://your-resource.services.ai.azure.com/openai`
|
|
101
|
+
or a complete v1 base URL such as `https://your-resource.services.ai.azure.com/openai/v1`.
|
|
102
|
+
The provider appends `/v1` and the configured `api-version` to unversioned
|
|
103
|
+
resource URLs. Complete v1 URLs are used as-is.
|
|
104
|
+
|
|
105
|
+
Complete Microsoft Foundry project v1 URLs, such as
|
|
106
|
+
`https://your-resource.services.ai.azure.com/api/projects/your-project/openai/v1`,
|
|
107
|
+
are also used as-is. If `/v1` is omitted from a Foundry project URL, the
|
|
108
|
+
provider appends it without adding an `api-version` query parameter.
|
|
109
|
+
|
|
88
110
|
With a non-Azure custom gateway baseURL, the resolved URL is `{baseURL}{path}`;
|
|
89
111
|
the SDK does not append `/v1` or an `api-version` query parameter in this mode.
|
|
90
112
|
|
package/package.json
CHANGED
|
@@ -114,7 +114,8 @@ export interface AzureOpenAIProviderSettings {
|
|
|
114
114
|
* Use a different URL prefix for API calls, e.g. to use proxy servers. Either this or `resourceName` can be used.
|
|
115
115
|
* When a baseURL is provided, the resourceName is ignored.
|
|
116
116
|
*
|
|
117
|
-
* With an Azure OpenAI baseURL, the resolved URL is `{baseURL}/v1{path}`.
|
|
117
|
+
* With an unversioned Azure OpenAI baseURL, the resolved URL is `{baseURL}/v1{path}`.
|
|
118
|
+
* Azure OpenAI base URLs that already end in `/openai/v1` are used as-is.
|
|
118
119
|
* With a non-Azure custom gateway baseURL, the resolved URL is `{baseURL}{path}`.
|
|
119
120
|
*/
|
|
120
121
|
baseURL?: string;
|
|
@@ -143,7 +144,8 @@ export interface AzureOpenAIProviderSettings {
|
|
|
143
144
|
fetch?: FetchFunction;
|
|
144
145
|
|
|
145
146
|
/**
|
|
146
|
-
* Custom api version to use. Defaults to `
|
|
147
|
+
* Custom api version to use. Defaults to `v1`.
|
|
148
|
+
* Complete v1 base URLs are used as-is.
|
|
147
149
|
*/
|
|
148
150
|
apiVersion?: string;
|
|
149
151
|
|
|
@@ -155,10 +157,30 @@ export interface AzureOpenAIProviderSettings {
|
|
|
155
157
|
useDeploymentBasedUrls?: boolean;
|
|
156
158
|
}
|
|
157
159
|
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
function getAzureOpenAIBaseURLInfo(baseURL: string | undefined) {
|
|
161
|
+
if (baseURL == null) {
|
|
162
|
+
return {
|
|
163
|
+
isAzureOpenAI: true,
|
|
164
|
+
isFoundryProject: false,
|
|
165
|
+
isVersioned: false,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const url = new URL(baseURL);
|
|
170
|
+
const hostname = url.hostname;
|
|
171
|
+
const isAzureOpenAI =
|
|
172
|
+
hostname.endsWith('.openai.azure.com') ||
|
|
173
|
+
hostname.endsWith('.services.ai.azure.com') ||
|
|
174
|
+
hostname.endsWith('.cognitiveservices.azure.com');
|
|
175
|
+
const pathname = url.pathname.replace(/\/+$/, '');
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
isAzureOpenAI,
|
|
179
|
+
isFoundryProject:
|
|
180
|
+
hostname.endsWith('.services.ai.azure.com') &&
|
|
181
|
+
pathname.startsWith('/api/projects/'),
|
|
182
|
+
isVersioned: isAzureOpenAI && pathname.toLowerCase().endsWith('/openai/v1'),
|
|
183
|
+
};
|
|
162
184
|
}
|
|
163
185
|
|
|
164
186
|
/**
|
|
@@ -221,7 +243,11 @@ export function createAzure(
|
|
|
221
243
|
});
|
|
222
244
|
|
|
223
245
|
const apiVersion = options.apiVersion ?? 'v1';
|
|
224
|
-
const
|
|
246
|
+
const {
|
|
247
|
+
isAzureOpenAI,
|
|
248
|
+
isFoundryProject,
|
|
249
|
+
isVersioned: isAzureOpenAIVersioned,
|
|
250
|
+
} = getAzureOpenAIBaseURLInfo(options.baseURL);
|
|
225
251
|
|
|
226
252
|
const url = ({ path, modelId }: { path: string; modelId: string }) => {
|
|
227
253
|
const baseUrlPrefix = withoutTrailingSlash(
|
|
@@ -232,15 +258,19 @@ export function createAzure(
|
|
|
232
258
|
if (options.useDeploymentBasedUrls) {
|
|
233
259
|
// Use deployment-based format for compatibility with certain Azure OpenAI models
|
|
234
260
|
fullUrl = new URL(`${baseUrlPrefix}/deployments/${modelId}${path}`);
|
|
235
|
-
} else if (!
|
|
261
|
+
} else if (!isAzureOpenAI || isAzureOpenAIVersioned) {
|
|
236
262
|
// Custom gateways can own Azure routing and versioning themselves.
|
|
263
|
+
// Complete Azure OpenAI v1 URLs also own their versioning.
|
|
237
264
|
fullUrl = new URL(`${baseUrlPrefix}${path}`);
|
|
238
265
|
} else {
|
|
239
266
|
// Use v1 API format - no deployment ID in URL
|
|
240
267
|
fullUrl = new URL(`${baseUrlPrefix}/v1${path}`);
|
|
241
268
|
}
|
|
242
269
|
|
|
243
|
-
if (
|
|
270
|
+
if (
|
|
271
|
+
options.useDeploymentBasedUrls ||
|
|
272
|
+
(isAzureOpenAI && !isAzureOpenAIVersioned && !isFoundryProject)
|
|
273
|
+
) {
|
|
244
274
|
fullUrl.searchParams.set('api-version', apiVersion);
|
|
245
275
|
}
|
|
246
276
|
|