- name
- azure-openai-to-responses
- license
- MIT
- description
- Shift Python apps dem from Azure OpenAI Chat Completions go Responses API. E cover AzureOpenAI/AsyncAzureOpenAI client shift go v1 endpoint, streaming, tools, structured output, multi-turn, EntraID auth, plus model compatibility checks. Na Python-focused, Azure OpenAI-specific. USE FOR: shift go responses API, change from chat completions, openai responses, upgrade openai SDK, responses API migration, move from completions go responses, gpt-5 migration, azure openai python migration, chat completions go responses, AzureOpenAI go OpenAI client, python azure openai upgrade. DO NOT USE FOR: build new apps from scratch (start with responses directly), Node/TypeScript/C#/Java/Go migrations (dis skill na Python-only), Azure infrastructure setup (use azure-prepare), deploy models (use microsoft-foundry).
# Migrate Python Apps from Azure OpenAI Chat Completions to Responses API
> **AUTHORITATIVE GUIDANCE — FOLLOW EXACTLY**
>
> Dis skill dey migrate Python code wey dey use Azure OpenAI Chat Completions
> come use di unified Responses API. Abeg follow dis instructions sharply.
> No try do your own mapping of parameters or create new API shapes.
---
## Triggers
Activate dis skill wen user want:
- Migrate a Python app from Azure OpenAI Chat Completions to Responses API
- Upgrade Python OpenAI SDK usage to di latest API shape for Azure OpenAI
- Prepare Python code for GPT-5 or newer models wey need Responses on Azure
- Switch from `AzureOpenAI`/`AsyncAzureOpenAI` go standard `OpenAI`/`AsyncOpenAI` client with di v1 endpoint
- Fix deprecation warnings wey concern `AzureOpenAI` constructors or `api_version`
---
## ⚠️ Model Compatibility — CHECK FIRST
> **Before you migrate, make sure say your Azure OpenAI deployment support Responses API.**
### 1. Smoke-test your deployment (fastest)
```python
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AZURE_OPENAI_API_KEY"],
base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/",
)
try:
resp = client.responses.create(
model=os.environ["AZURE_OPENAI_DEPLOYMENT"],
input="ping",
max_output_tokens=50,
store=False,
)
print(f"✅ Deployment supports Responses API: {resp.output_text}")
except Exception as e:
print(f"❌ Deployment does NOT support Responses API: {e}")
```
> **Note**: `max_output_tokens` get **minimum 16** for Azure OpenAI. If value less than 16, e go return 400 error. Use 50+ for smoke tests.
If e return 404, e mean say di deployment model no de support Responses yet — check di reference down or redeploy with correct model.
### 2. Check models wey dey your region (recommended)
Run di built-in model compatibility tool to see wetin dey available with Responses API support for your region:
```bash
python migrate.py models --subscription YOUR_SUB_ID --location YOUR_REGION
```
Dis one dey query Azure ARM live and show compatibility matrix — which models dey support Responses, structured output, tools, etc. Use `--filter gpt-5.1,gpt-5.2` to narrow results or `--json` for scripting.
### 3. Full model support reference
- **Live query**: `python migrate.py models` (see am above — region-specific, always updated)
- **Browse availability**: [Model summary table and region availability](https://learn.microsoft.com/en-us/azure/foundry/foundry-models/concepts/models-sold-directly-by-azure?tabs=global-standard-aoai%2Cglobal-standard&pivots=azure-openai#model-summary-table-and-region-availability)
- **Quickstart & guidance**: **https://aka.ms/openai/start**
### ⚠️ Older model limitations
> **WARNING**: Older models (before `gpt-4.1`) fit no fit support all Responses API features fully.
>
> Known limitations with older models:
> - **`reasoning` parameter**: No support for many non-reasoning models. Only migrate `reasoning` if e already dey for original code.
> - **`seed` parameter**: No dey support at all for Responses API — remove from all requests.
> - **Structured output via `text.format`**: Older models no sure to enforce `strict: true` JSON schemas well.
> - **Tool orchestration**: GPT-5+ dey manage tool calls as part of internal reasoning. Older models for Responses still dey work but dem no get dis deep integration.
> - **Temperature constraints**: Wen you dey migrate to `gpt-5`, temperature gats be blank or set to `1`. Older models no get dis kind limit.
### O-series reasoning models (o1, o3-mini, o3, o4-mini)
O-series models get them own special parameter limits. If your app dey target o-series models during migration:
- **`temperature`**: Gats be `1` (or no include am). O-series no fit take other values.
- **`max_completion_tokens` → `max_output_tokens`**: Apps wey dey use Azure-specific `max_completion_tokens` must switch go `max_output_tokens`. Set am high (4096+) because reasoning tokens dey count against limit.
- **`reasoning_effort`**: If app dey use `reasoning_effort` (low/medium/high), keep am — Responses API support this for o-series models.
- **Streaming behavior**: O-series models fit hold output till reasoning finish before e dey send text delta events. Streaming still work, but first `response.output_text.delta` fit show late than GPT models.
- **`top_p`**: No support for o-series — remove if e dey.
- **Tool use**: O-series models support tools via Responses API same as GPT, but tool call orchestration quality depend on model.
**Action — proactive model advisory**: During scan, check which model app dey target (deployment names, env vars, config). If model before `gpt-4.1` (no be gpt-4.1+), tell user beforehand:
- Migration go work for basic text, chat, streaming, and tools for their current model.
- Newer models (`gpt-5.1`, `gpt-5.2`) get better tool orchestration, structured output enforcement, reasoning, and cross-region availability.
- Dem suppose think about upgrading deployment when dem ready — e no go block migration.
No block or refuse migrate based on model version. Dis advisory be just info.
### GitHub Models no support Responses API
> **GitHub Models (`models.github.ai`, `models.inference.ai.azure.com`) no support Responses API.**
If codebase get GitHub Models path (look for `base_url` wey point to `models.github.ai` or `models.inference.ai.azure.com`), **remove am completely** during migration. Responses API need Azure OpenAI, OpenAI, or compatible local endpoint (e.g., Ollama with Responses support).
Action during scan:
- Flag any GitHub Models code paths for removal.
---
## Framework Migration
Plenty apps dey use higher-level frameworks on top of OpenAI. When you dey migrate dem, the framework own API go change — no be only the underlying OpenAI calls.
### Microsoft Agent Framework (MAF)
**Check your MAF version first** — migration depends on whether you dey on MAF 1.0.0+ or before 1.0.0 beta/rc.
#### MAF 1.0.0+ (agent-framework-openai >= 1.0.0)
`OpenAIChatClient` **dey use Responses API already** — no migration needed. If codebase dey use old `OpenAIChatCompletionClient` (we dey use `chat.completions.create`), switch am to `OpenAIChatClient`.
| Before | After |
|--------|-------|
| `from agent_framework.openai import OpenAIChatCompletionClient` | `from agent_framework.openai import OpenAIChatClient` |
| `OpenAIChatCompletionClient(...)` | `OpenAIChatClient(...)` |
To check your version: `python -c "import agent_framework_openai; print(agent_framework_openai.__version__)"`
#### MAF pre-1.0.0 (beta/rc releases)
For pre-1.0.0 MAF, `OpenAIChatClient` dey use Chat Completions. Upgrade to `agent-framework-openai>=1.0.0` so that `OpenAIChatClient` go use Responses API by default.
No other changes dey needed — `Agent` and tools API still the same.
### LangChain (`langchain-openai`)
Add `use_responses_api=True` to `ChatOpenAI()`. Change response access from `.content` to `.text`.
| Before | After |
|--------|-------|
| `ChatOpenAI(model=..., base_url=..., api_key=...)` | `ChatOpenAI(model=..., base_url=..., api_key=..., use_responses_api=True)` |
| `result['messages'][-1].content` | `result['messages'][-1].text` |
For complete before/after code examples, see [cheat-sheet.md](./references/cheat-sheet.md).
---
## Frontend Migration Guidance
> **Responses API na server-side matter.** Migrate your Python backend; frontend HTTP contract suppose no change unless your backend na thin pass-through — if na so, consider use Responses request shape to drop translation layer. If frontend dey call OpenAI directly with client-side key, make dem move those calls to backend first.
### `@microsoft/ai-chat-protocol` deprecation
The `@microsoft/ai-chat-protocol` npm package don deprecate, make you replace am with [`ndjson-readablestream`](https://www.npmjs.com/package/ndjson-readablestream). If you see am for frontend:
1. Replace di CDN script tag:
```html
<!-- Before -->
<script src="https://cdn.jsdelivr.net/npm/@microsoft/ai-chat-protocol@.../dist/iife/index.js"></script>
<!-- After -->
<script src="https://cdn.jsdelivr.net/npm/ndjson-readablestream@1.0.7/dist/ndjson-readablestream.umd.js"></script>
```
2. Remove `AIChatProtocolClient` instantiation (`new ChatProtocol.AIChatProtocolClient("/chat")`).
3. Replace `client.getStreamedCompletion(messages)` with direct `fetch()` call to backend streaming endpoint.
4. Replace `for await (const response of result)` with `for await (const chunk of readNDJSONStream(response.body))`.
5. Change property access from `response.delta.content` / `response.error` to `chunk.delta.content` / `chunk.error`.
---
## Goals
- List all Python call sites wey dey use Chat Completions or old Completions for Azure OpenAI.
- Propose migration plan and sequence for Python codebase.
- Apply safe, small edits to switch to Responses API.
- Update callers to use Responses output schema; no backcompat wrappers.
- Run tests/lints; fix small breaks introduced by migration.
- Prepare small, reviewable change sets and give final summary with diffs (no commit).
---
## Guardrails
- Only change files inside git workspace. No write outside.
- No preserve backward-compatibility shims; migrate code to new API shape.
- No leave tombstone/transition comments or backup files.
- Keep streaming semantics if e dey before; otherwise use non-streaming.
- Ask approval before run commands or network calls if approval mode dey.
- No run `git add`/`git commit`/`git push`; only produce working-tree edits.
---
## Step 0: Azure OpenAI Client Migration (Prerequisite)
If your codebase dey use `AzureOpenAI` or `AsyncAzureOpenAI` constructors, migrate to standard `OpenAI` / `AsyncOpenAI` constructors first. Azure-specific constructors don deprecate for `openai>=1.108.1`.
### Why the v1 API path?
The new `/openai/v1` endpoint dey use standard `OpenAI()` client instead of `AzureOpenAI()`, no need `api_version` parameter, and e dey work the same for OpenAI and Azure OpenAI. Di same client code dey future-proof — no version management needed.
### Key changes
| Before | After |
|--------|-------|
| `AzureOpenAI` | `OpenAI` |
| `AsyncAzureOpenAI` | `AsyncOpenAI` |
| `azure_endpoint` | `base_url` |
| `azure_ad_token_provider` | `api_key` |
| `api_version=...` | Remove completely |
### Cleanup checklist
- Remove `api_version` argument from client construction.
- Remove `AZURE_OPENAI_VERSION` / `AZURE_OPENAI_API_VERSION` environment variables from `.env`, app settings, and Bicep/infra files.
- Rename `AZURE_OPENAI_CLIENT_ID` → `AZURE_CLIENT_ID` for `.env`, app settings, Bicep/infra, and test fixtures (standard Azure Identity SDK convention).
- Ensure `openai>=1.108.1` in `requirements.txt` or `pyproject.toml`.
### Environment variable migration
| Old env var | Action | Notes |
|-------------|--------|-------|
| `AZURE_OPENAI_VERSION` | **Remove** | No need `api_version` with v1 endpoint |
| `AZURE_OPENAI_API_VERSION` | **Remove** | Same as above |
| `AZURE_OPENAI_CLIENT_ID` | **Rename** → `AZURE_CLIENT_ID` | Standard Azure Identity SDK convention for `ManagedIdentityCredential(client_id=...)` |
| `AZURE_OPENAI_ENDPOINT` | **Keep** | Still need for `base_url` construction |
| `AZURE_OPENAI_CHAT_DEPLOYMENT` | **Keep** | Use as `model` param in `responses.create` |
| `AZURE_OPENAI_API_KEY` | **Keep** | Use as `api_key` for key-based auth |
For client setup code examples (sync, async, EntraID, API key, multi-tenant), see [cheat-sheet.md](./references/cheat-sheet.md).
---
## Step 1: Detect Legacy Call Sites
Run the [detect_legacy.py](../../../../../.agents/skills/azure-openai-to-responses/scripts/detect_legacy.py) script to find all call sites wey need migration:
```bash
python skills/azure-openai-to-responses/scripts/detect_legacy.py .
```
Or run these searches manually — every match be migration target:
```bash
# Ol API calls (gats rewrite)
rg "chat\.completions\.create"
rg "ChatCompletion\.create"
rg "Completion\.create"
# Old Azure client constructors (gats change)
rg "AzureOpenAI\("
rg "AsyncAzureOpenAI\("
# How responses path dem dey access (gats update)
rg "choices\[0\]\.message\.content"
rg "choices\[0\]\.delta\.content"
rg "choices\[0\]\.message\.function_call"
rg "choices\[0\]\.message\.tool_calls"
# Tool definitions wey dey old inside nested form (gats flatten)
rg '"function":\s*{\s*"name"'
rg "pydantic_function_tool"
# Tool results for old form (gats change to function_call_output)
rg '"role":\s*"tool"'
rg '"tool_call_id"'
# Old parameters (gats remove or change name)
rg "response_format"
rg "max_tokens\b" # change name to max_output_tokens
rg "['\"]seed['\"]" # remove entirely
# Old environment variables (gats clean)
rg "AZURE_OPENAI_API_VERSION|AZURE_OPENAI_VERSION"
rg "AZURE_OPENAI_CLIENT_ID" # e suppose be AZURE_CLIENT_ID
# GitHub Models endpoints (gats remove — Responses API no dey support)
rg "models\.github\.ai|models\.inference\.ai\.azure"
# Framework level old patterns (gats update)
rg "OpenAIChatCompletionClient" # MAF 1.0.0+: change to OpenAIChatClient
rg "ChatOpenAI\(" | grep -v "use_responses_api" # LangChain: need use_responses_api=True
# Test setup (gats update)
rg "ChatCompletionChunk|AsyncCompletions\.create" tests/
rg "_azure_ad_token_provider" tests/
Auf GitHub ansehen