Skip to content

@kindgi/adapter-model-azure-openai

View as Markdown

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.

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:

  • resourceName and baseURL together, or neither;
  • a resourceName that isn't one DNS label, or a baseURL that isn't https;
  • an unknown api, auth or adapter_config key;
  • api-key without secret_ref, or entra with one;
  • entra on a host that isn't Azure OpenAI's, naming the host;
  • a baseURL with credentials, a query or a fragment, ending in more than one /, or an Azure OpenAI host's baseURL without /openai/v1;
  • a malformed deployments entry, a model named twice or not listed, a deployment name Azure wouldn't take, or a model with no deployment.

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. No api-key header is sent. A runtime with no Azure identity refuses the registration, naming KINDGI_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.com https://cognitiveservices.azure.com/.default
      Azure Government *.openai.azure.us, *.cognitiveservices.azure.us https://cognitiveservices.azure.us/.default

      Microsoft 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 key secret_ref names, read for every attempt and sent as api-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 auth error at once, never retried.
  • No request follows a redirect (redirect: 'error'): the credential reaches the endpoint and nothing else.
  • Never the environment: AZURE_API_KEY and AZURE_RESOURCE_NAME are never read. The provider is always given its endpoint and its credential.
  • Responses (the default): POST …/openai/v1/responses?api-version=v1, with the deployment as model and store: 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 as model.
  • Whether a model reasons is the registration's to say: one registered with thinking or sampling: false reasons, one with sampling: true doesn't, whatever its deployment is called. A reasoning model keeps its encrypted reasoning between tool turns on Responses, and gets max_completion_tokens on 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.

  • azureOpenAIAdapterEntry: the AdapterFactoryEntry a runtime registers, with azureOpenAIAdapterFactory and azureOpenAICheckConfig.
  • readAzureOpenAIConfig(input): a registration read and checked, or every problem with it.
  • AZURE_OPENAI_CLOUDS and azureCloudOf(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 the AzureOpenAIConfig, AzureOpenAIApi and AzureOpenAIAuth types.

Apache-2.0