@kindgi/adapter-model-azure-openai
npm install @kindgi/adapter-model-azure-openai · source
Azure OpenAI ModelProvider for @kindgi/capabilities: a registration's models served by your Azure OpenAI deployments, on the v1 API, signed in with the resource's key or with the runtime's own Entra identity.
It covers Azure OpenAI deployments. Other models served by Azure AI Foundry (Llama, Mistral, DeepSeek…) aren't in it.
It's built on @kindgi/adapter-model-shared: the retries, typed errors (ModelProviderError), the reasoning state carried across a pause, usage and cost are the same as every adapter built on it. The requests are sent by the AI SDK's @ai-sdk/azure provider at the provider-spec level, pinned exactly.
A registration
Section titled “A registration”adapter_id: @kindgi/adapter-model-azure-openai, with these adapter_config keys:
| Key | What |
|---|---|
resourceName |
The Azure OpenAI resource, as in <name>.openai.azure.com. |
baseURL |
Instead of resourceName: a custom endpoint, https, with no credentials, query or fragment. On an Azure OpenAI host (another cloud's, say) it ends in /openai/v1; a gateway's is any path, with auth: api-key. |
deployments |
Required. The deployment serving each registered model: "model=deployment,…", e.g. "gpt-6.1-sol=gpt-6-1-sol,gpt-6-luna=luna-prod". Azure deployment names are yours to choose (often the model's own name, as gpt-6.1-sol), so every model in metadata.models needs one. |
api |
responses (default) or chat-completions. Tools with GPT-6 need responses: Azure refuses them on Chat Completions while the model reasons. |
auth |
api-key (default): the resource's key, through secret_ref. entra: the runtime's Azure identity; no secret_ref; an Azure OpenAI host only (below); refused where the deployment doesn't let tenant configuration sign in as the server (serverCredentials: false, KINDGI_TENANT_HOST_ACCESS=isolated). |
{ "adapter_id": "@kindgi/adapter-model-azure-openai", "adapter_config": { "resourceName": "acme-openai", "deployments": "gpt-6.1-sol=gpt-6-1-sol", "auth": "entra" }, "metadata": { "id": "azure-openai", "region": "canadacentral", "models": [ { "name": "gpt-6.1-sol", "contextWindow": 1050000, "sampling": false, "features": ["tool-use", "structured-output"], "cost": { "promptUsdPer1kTokens": 0.002, "completionUsdPer1kTokens": 0.01, "cachedPromptMultiplier": 0.05 } } ] }}checkConfig reports each problem with a registration at the setting at fault, without the network or the secret:
resourceNameandbaseURLtogether, or neither;- a
resourceNamethat isn't one DNS label, or abaseURLthat isn't https; - an unknown
api,authoradapter_configkey; api-keywithoutsecret_ref, orentrawith one;entraon a host that isn't Azure OpenAI's, naming the host;- a
baseURLwith credentials, a query or a fragment, ending in more than one/, or an Azure OpenAI host'sbaseURLwithout/openai/v1; - a malformed
deploymentsentry, a model named twice or not listed, a deployment name Azure wouldn't take, or a model with no deployment.
How it signs in
Section titled “How it signs in”Each of these has a test. It signs in before each attempt, with the call's abort signal, and the attempt's request carries what that sign-in got, so calls running at once never share a credential.
auth: entra: a bearer token from the runtime's Azure identity (AdapterFactoryInput.identities.azure), asked for every attempt (the identity caches and renews it), within 10 seconds; a call stopped meanwhile ends at once, with its own reason. Noapi-keyheader is sent. A runtime with no Azure identity refuses the registration, namingKINDGI_AZURE_CLIENT_ID. The identity needs the Cognitive Services OpenAI User role on the resource.-
Only an Azure OpenAI host gets the token, because whoever receives it could use it against every Azure OpenAI resource the runtime's identity has a role on. Another host is refused at registration (and by the factory), naming it:
Cloud Hosts Scope Azure *.openai.azure.com,*.cognitiveservices.azure.com,*.services.ai.azure.comhttps://cognitiveservices.azure.com/.defaultAzure Government *.openai.azure.us,*.cognitiveservices.azure.ushttps://cognitiveservices.azure.us/.defaultMicrosoft lists each cloud's endpoints on Compare Azure Government and global Azure. Azure Government needs the runtime's identity to be in Azure Government too.
-
auth: api-key: the keysecret_refnames, read for every attempt and sent asapi-key(whitespace around it dropped), so a rotated key takes effect on the next call.- A failed sign-in (the identity gives no token, the key can't be read, even with the secret store down, or is empty or blank) ends the call as an
autherror at once, never retried. - No request follows a redirect (
redirect: 'error'): the credential reaches the endpoint and nothing else. - Never the environment:
AZURE_API_KEYandAZURE_RESOURCE_NAMEare never read. The provider is always given its endpoint and its credential.
What it sends
Section titled “What it sends”- Responses (the default):
POST …/openai/v1/responses?api-version=v1, with the deployment asmodelandstore: false, so Azure keeps no conversation state for it: Kindgi's journal is the record. - Chat Completions:
POST …/openai/v1/chat/completions, with the deployment asmodel. - Whether a model reasons is the registration's to say: one registered with
thinkingorsampling: falsereasons, one withsampling: truedoesn't, whatever its deployment is called. A reasoning model keeps its encrypted reasoning between tool turns on Responses, and getsmax_completion_tokenson Chat Completions. When the registration says neither, the AI SDK decides from the deployment's name, so register one or the other when the name doesn't say. - Every attempt goes through the runtime's
fetch(AdapterFactoryInput.fetch), which refuses the hosts its deployment forbids.
costUsd is tokenCostUsd over the model's registered rates: prompt and completion, cached prompt tokens at cachedPromptMultiplier, and the long-context tier when registered. Azure's prices depend on the deployment type (Global, Data Zone, Regional), so register the rates of yours. Costs are estimates from published prices; Azure's invoice is authoritative.
Exports
Section titled “Exports”azureOpenAIAdapterEntry: theAdapterFactoryEntrya runtime registers, withazureOpenAIAdapterFactoryandazureOpenAICheckConfig.readAzureOpenAIConfig(input): a registration read and checked, or every problem with it.AZURE_OPENAI_CLOUDSandazureCloudOf(hostname): the hosts Entra may go to, by cloud, with each scope.AZURE_OPENAI_ADAPTER_ID,AZURE_OPENAI_APIS,AZURE_OPENAI_AUTHS,AZURE_OPENAI_SCOPE(the public cloud's),IDENTITY_TIMEOUT_MS, and theAzureOpenAIConfig,AzureOpenAIApiandAzureOpenAIAuthtypes.
License
Section titled “License”Apache-2.0