Skip to content

feat(ai): add OpenAI Responses API (/v1/responses) support#13186

Merged
nic-6443 merged 3 commits into
apache:masterfrom
nic-6443:feat/openai-responses-api
Apr 10, 2026
Merged

feat(ai): add OpenAI Responses API (/v1/responses) support#13186
nic-6443 merged 3 commits into
apache:masterfrom
nic-6443:feat/openai-responses-api

Conversation

@nic-6443

@nic-6443 nic-6443 commented Apr 9, 2026

Copy link
Copy Markdown
Member

Description

Add protocol adapter for OpenAI Responses API, enabling ai-proxy and related AI plugins to handle /v1/responses endpoints with both streaming (SSE named events) and non-streaming modes.

Production changes

  • New protocol: ai-protocols/openai-responses.lua (315 lines)
    • matches() detects Response API by URI + body.input
    • parse_sse_event() handles named SSE events (response.output_text.delta, response.completed, response.failed)
    • extract_usage() maps input_tokens/output_tokens
    • build_deny_response() generates Response API format errors
    • get_messages() returns instructions + input for content checking
  • Protocol registry: Register openai-responses in ai-protocols/init.lua detection order (before openai-chat, since both check body but responses also checks URI)
  • Provider capabilities: Add openai-responses capability with /v1/responses path to openai and openai-compatible providers
  • Prompt guard fix: Skip get_content_to_check for Response API in ai-prompt-guard.lua (instructions + input are parallel fields, not conversation history)

Test coverage (5 test files updated)

Test file Coverage
ai-proxy.t Basic routing, non-streaming passthrough with usage extraction, streaming SSE passthrough
ai-prompt-guard.t Deny/allow patterns for string input, instructions, array input; match_all_roles true/false behavior
ai-prompt-decorator.t Prepend sets instructions, append modifies input (string and array), combined prepend+append
ai-rag.t RAG result injection appended to Response API input
ai-aliyun-content-moderation.t Content moderation for violent input, Response API format deny response, streaming SSE deny format, input_tokens usage format, nil-schema fix for non-openai providers

Technical notes

  • Response API is implemented as passthrough (no protocol conversion needed), just SSE event model adaptation
  • Protocol detection order matters: openai-responses must come before openai-chat (both check body, but responses also checks URI)
  • SSE transport layer already supports named events, no modification needed
  • All test files include BEGIN { $ENV{TEST_ENABLE_CONTROL_API_V1} = "0"; } to prevent /v1/responses route conflict with control API

Add protocol adapter for OpenAI Responses API, enabling ai-proxy and
related AI plugins to handle /v1/responses endpoints with both streaming
(SSE named events) and non-streaming modes.

Changes:
- New protocol: ai-protocols/openai-responses.lua (315 lines)
  - matches() detects Response API by URI + body.input
  - parse_sse_event() handles named events (response.output_text.delta,
    response.completed, response.failed)
  - extract_usage() maps input_tokens/output_tokens
  - build_deny_response() generates Response API format errors
  - get_messages() returns instructions + input for content checking
- Register openai-responses in ai-protocols/init.lua detection order
  (before openai-chat, since both check body but responses also checks URI)
- Add openai-responses capability to openai and openai-compatible providers
- Fix ai-prompt-guard to skip get_content_to_check for Response API
  (instructions + input are parallel fields, not conversation history)

Test coverage across 5 test files:
- ai-proxy.t: basic routing, non-streaming passthrough with usage
  extraction, streaming SSE passthrough
- ai-prompt-guard.t: deny/allow patterns for string input, instructions,
  array input; match_all_roles=true/false behavior
- ai-prompt-decorator.t: prepend sets instructions, append modifies input
  (string and array), combined prepend+append
- ai-rag.t: RAG result injection appended to Response API input
- ai-aliyun-content-moderation.t: content moderation for violent input,
  Response API format deny response, streaming SSE deny format,
  input_tokens usage format, nil-schema fix for non-openai providers
@dosubot dosubot Bot added size:XXL This PR changes 1000+ lines, ignoring generated files. enhancement New feature or request labels Apr 9, 2026
@nic-6443
nic-6443 requested a review from Copilot April 9, 2026 07:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a new OpenAI Responses API protocol adapter so AI proxy/plugins can handle /v1/responses requests (streaming SSE named events + non-streaming), and updates providers + plugin logic/tests accordingly.

Changes:

  • Added openai-responses protocol with SSE named-event parsing and usage extraction.
  • Registered protocol detection before openai-chat, and added /v1/responses capability to OpenAI(-compatible) providers.
  • Updated prompt-guard behavior and expanded integration tests across proxy/guard/decorator/RAG/moderation.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
t/plugin/ai-rag.t Adds Responses API route + verifies RAG injection appends to input.
t/plugin/ai-proxy.t Adds mock /v1/responses upstream + routing and SSE passthrough tests.
t/plugin/ai-prompt-guard.t Adds allow/deny coverage for Responses API input/instructions formats.
t/plugin/ai-prompt-decorator.t Verifies prepend/append behavior maps to instructions and input for Responses API.
t/plugin/ai-aliyun-content-moderation.t Adds moderation cases + deny-response format checks for Responses API (streaming + non-streaming).
t/lib/server.lua Adds a /v1/responses echo handler alias for tests.
apisix/plugins/ai-providers/openai.lua Registers openai-responses capability path.
apisix/plugins/ai-providers/openai-compatible.lua Adds explicit capability paths, incl. openai-responses.
apisix/plugins/ai-protocols/openai-responses.lua New protocol adapter (matching, SSE parsing, usage extraction, deny response builder, message extraction).
apisix/plugins/ai-protocols/init.lua Registers openai-responses and updates detection order + comments.
apisix/plugins/ai-prompt-guard.lua Skips “last message only” filtering for Responses API by protocol name.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apisix/plugins/ai-protocols/openai-responses.lua
Comment thread apisix/plugins/ai-protocols/openai-responses.lua
Comment thread apisix/plugins/ai-protocols/openai-responses.lua
Comment thread apisix/plugins/ai-protocols/init.lua Outdated
Comment thread apisix/plugins/ai-protocols/openai-responses.lua
nic-6443 added 2 commits April 9, 2026 16:07
Address review feedback: the @return doc comment for detect() was
missing openai-embeddings from the list of possible return values.
@nic-6443
nic-6443 merged commit 3512255 into apache:master Apr 10, 2026
19 checks passed
@nic-6443
nic-6443 deleted the feat/openai-responses-api branch April 10, 2026 02:48
wistefan pushed a commit to wistefan/apisix that referenced this pull request Jun 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants