feat(ai): add OpenAI Responses API (/v1/responses) support#13186
Merged
Conversation
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
There was a problem hiding this comment.
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-responsesprotocol with SSE named-event parsing and usage extraction. - Registered protocol detection before
openai-chat, and added/v1/responsescapability 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.
Address review feedback: the @return doc comment for detect() was missing openai-embeddings from the list of possible return values.
nic-6443
requested review from
AlinsRan,
Baoyuantop,
membphis,
moonming and
shreemaan-abhishek
April 9, 2026 10:46
moonming
approved these changes
Apr 9, 2026
Baoyuantop
approved these changes
Apr 10, 2026
AlinsRan
approved these changes
Apr 10, 2026
wistefan
pushed a commit
to wistefan/apisix
that referenced
this pull request
Jun 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Add protocol adapter for OpenAI Responses API, enabling ai-proxy and related AI plugins to handle
/v1/responsesendpoints with both streaming (SSE named events) and non-streaming modes.Production changes
ai-protocols/openai-responses.lua(315 lines)matches()detects Response API by URI +body.inputparse_sse_event()handles named SSE events (response.output_text.delta,response.completed,response.failed)extract_usage()mapsinput_tokens/output_tokensbuild_deny_response()generates Response API format errorsget_messages()returns instructions + input for content checkingopenai-responsesinai-protocols/init.luadetection order (beforeopenai-chat, since both check body but responses also checks URI)openai-responsescapability with/v1/responsespath toopenaiandopenai-compatibleprovidersget_content_to_checkfor Response API inai-prompt-guard.lua(instructions + input are parallel fields, not conversation history)Test coverage (5 test files updated)
ai-proxy.tai-prompt-guard.tmatch_all_rolestrue/false behaviorai-prompt-decorator.tai-rag.tai-aliyun-content-moderation.tinput_tokensusage format, nil-schema fix for non-openai providersTechnical notes
openai-responsesmust come beforeopenai-chat(both check body, but responses also checks URI)BEGIN { $ENV{TEST_ENABLE_CONTROL_API_V1} = "0"; }to prevent/v1/responsesroute conflict with control API