Skip to content

feat: add Responses API support for Azure OpenAI provider#5203

Open
devin-ai-integration[bot] wants to merge 3 commits intomainfrom
devin/1775033893-azure-responses-api
Open

feat: add Responses API support for Azure OpenAI provider#5203
devin-ai-integration[bot] wants to merge 3 commits intomainfrom
devin/1775033893-azure-responses-api

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot commented Apr 1, 2026

Summary

Adds support for OpenAI's Responses API when using Azure OpenAI endpoints. When api="responses" is set, AzureCompletion delegates to an OpenAICompletion instance configured with the Azure resource's /openai/v1/?api-version=... base URL, reusing the existing fully-tested OpenAI Responses API code path.

Usage:

llm = LLM(model="azure/gpt-4o", api="responses", api_key=KEY, endpoint=ENDPOINT)

Chat Completions remains the default (api="completions") — no breaking changes.

New fields on AzureCompletion: api, instructions, store, previous_response_id, include, builtin_tools, parse_tool_outputs, auto_chain, auto_chain_reasoning, reasoning_effort, seed, max_completion_tokens

Implementation approach: Delegation to OpenAICompletion rather than duplicating the Responses API logic. The delegate is constructed with base_url pointing to the Azure /openai/v1/ endpoint and api_key set to the Azure key.

Closes #5202

Review & Testing Checklist for Human

  • Verify the base URL format {resource}/openai/v1/?api-version={version} is correct for Azure's Responses API. This is the most critical assumption — the URL construction in _init_responses_delegate strips /openai/deployments/{model} from the endpoint and rebuilds as /openai/v1/. If Azure uses a different path, nothing will work. Consider testing with a real Azure endpoint.
  • Event/telemetry behavior in responses mode: When api="responses", the Azure call() early-returns to the delegate, skipping Azure's _emit_call_started_event and hook invocations. The OpenAI delegate emits its own events with provider="openai" — verify this is acceptable for your telemetry/observability pipeline.
  • _client/_async_client are None in responses mode: Confirm no other code path (e.g., aclose(), context managers, or BaseLLM methods) accesses these when api="responses" in a way that would break.
  • End-to-end test with a real Azure OpenAI resource: The 26 new tests are all unit tests with mocks. Recommend manually verifying with a real Azure deployment that has Responses API enabled (requires a recent api_version like 2025-03-01-preview).

Notes

  • All 83 existing Azure tests continue to pass (0 regressions)
  • 26 new tests added covering: initialization, URL construction, parameter forwarding, delegation, factory routing, config serialization, chain management, streaming, structured output, and edge cases

Link to Devin session: https://app.devin.ai/sessions/660c36a7889243cab62f8af7b5890723


Note

Medium Risk
Adds a new execution path that bypasses the native Azure client/hook/event flow and relies on correct Azure base-URL construction; misconfiguration could break calls in api="responses" mode while leaving the default path intact.

Overview
Adds an optional api="responses" mode to the Azure LLM provider that delegates call()/acall() to OpenAICompletion configured with an Azure /openai/v1/?api-version=... base_url, while keeping Chat Completions as the default path.

Introduces new Responses-API-related fields (e.g., instructions, chaining, built-in tools, max_completion_tokens, reasoning_effort) that are forwarded to the delegate, exposes last_response_id/reset_chain, updates to_config_dict() to persist non-default api/reasoning_effort, and adds extensive unit tests covering URL construction, parameter forwarding, delegation behavior, and ensuring the legacy completions clients remain unaffected.

Written by Cursor Bugbot for commit 2315422. This will update automatically on new commits. Configure here.

When api='responses' is set on an Azure LLM instance, calls are
delegated to the OpenAI Responses API implementation with the Azure
resource's /openai/v1/ base URL, reusing the fully-tested OpenAI
Responses API code path.

New fields on AzureCompletion:
- api: Literal['completions', 'responses'] (default: 'completions')
- instructions, store, previous_response_id, include, builtin_tools
- parse_tool_outputs, auto_chain, auto_chain_reasoning
- reasoning_effort, seed, max_completion_tokens

Usage:
  llm = LLM(model='azure/gpt-4o', api='responses', api_key=KEY, endpoint=ENDPOINT)

Closes #5202

Co-Authored-By: João <joao@crewai.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

Prompt hidden (unlisted session)

@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

import sys
import types
from unittest.mock import patch, MagicMock, Mock
from unittest.mock import patch, MagicMock, Mock, AsyncMock
…delegate

Addresses Bugbot review feedback - these parameters were silently
ignored when using api='responses' mode.

Co-Authored-By: João <joao@crewai.com>
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

resource_url = raw_endpoint.rstrip("/")

api_version = self.api_version or "2024-06-01"
base_url = f"{resource_url}/openai/v1/?api-version={api_version}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Query parameter in base_url produces malformed request URLs

High Severity

The base_url is constructed with a query parameter (?api-version=...) embedded in it. The OpenAI Python SDK uses httpx's raw_path (which includes the query string) for URL joining, so appending API paths like responses produces malformed URLs such as /openai/v1/?api-version=2024-06-01/responses. Microsoft's official documentation shows the correct format is https://RESOURCE.openai.azure.com/openai/v1/ without any query parameter — the v1 API endpoint doesn't require api-version. All tests pass because they mock delegate.call() and never exercise actual HTTP URL construction.

Additional Locations (1)
Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: Add Responses API Support for Azure OpenAI Provider

0 participants