CLIProxyAPI audit
Responses WebSocket → vendor support matrix
This matrix maps what happens when a client connects to the OpenAI Responses websocket handler and requests a model backed by each provider. It distinguishes direct translator support from transport support and calls out where the path is merely conditional or untested.
13providers look supported through direct translators plus streaming executors
2providers are partial because their backend API is specialized or the path lacks focused tests
1provider is conditional on a connected websocket relay client
1registered provider is not supported because no direct Responses translator exists
Key rule: the translator registry performs a direct lookup only. If
openai-response → target-format is not registered, the request body falls back mostly unchanged rather than chaining through openai. That is why OpenAI-compatible executors work, while a distinct format like kiro does not automatically work.
| Vendor / provider | Executor target | Responses translator | Upstream transport | WS client support | Evidence and caveats |
|---|---|---|---|---|---|
| Codex | codex |
openai-response → codex |
Native Responses websocket when auth has websockets:true; otherwise HTTP POST /responses SSE. |
supported | CodexAutoExecutor switches to websocket only for websocket-capable auth; otherwise uses HTTP SSE. The websocket handler disables incremental previous_response_id replay for non-websocket auths. |
| OpenAI-compatible / default | openai |
openai-response → openai |
HTTP POST /chat/completions SSE. |
supported | Works for providers that implement streaming Chat Completions. Plain non-stream POST-only providers are not adapted into websocket events. |
| GitHub Copilot | openai-response for Responses source; otherwise openai |
Native Responses path for this source. | HTTP POST to Copilot /responses when source is openai-response. |
supported | useGitHubCopilotResponsesEndpoint returns true for openai-response, avoiding chat-completions translation. |
| Gemini API | gemini |
openai-response → gemini |
HTTP POST streamGenerateContent?alt=sse. |
supported | Direct request and stream response translators exist for Gemini. |
| Gemini Vertex | gemini |
openai-response → gemini |
HTTP streaming Vertex Gemini endpoint. | supported | Shares the Gemini translator target and stream translation path. |
| Gemini CLI | gemini-cli |
openai-response → gemini-cli |
HTTP POST CodeAssist streamGenerateContent?alt=sse. |
supported | Direct translator registration exists for the Gemini CLI format. |
| AI Studio | gemini |
openai-response → gemini |
Proxy-to-provider wsrelay tunnel carrying HTTP-style request and streaming chunks. |
conditional | Requires a connected /v1/ws AI Studio relay client. It is not direct arbitrary upstream websocket support. |
| Claude / Anthropic | claude |
openai-response → claude |
HTTP POST /v1/messages?beta=true SSE. |
supported | Direct Responses-to-Claude translator plus Claude SSE executor path. |
| Antigravity | antigravity |
openai-response → antigravity |
HTTP streaming with Antigravity endpoint fallback. | supported | Direct translator registration exists; executor has streaming fallback logic. |
| Kimi | openai for Responses source |
openai-response → openai |
HTTP POST /v1/chat/completions SSE. |
supported | For non-Claude sources, Kimi uses the OpenAI Chat target and stream translator. |
| xAI | codex |
openai-response → codex |
HTTP POST /responses SSE. |
supported | xAI normalizes Responses bodies through the Codex-style target format. |
| Kilo | openai |
openai-response → openai |
HTTP POST OpenRouter-style /chat/completions SSE. |
supported | OpenAI-compatible stream path and response synthesis should work for text/tool-compatible chat requests. |
| CodeBuddy | openai |
openai-response → openai |
HTTP streaming Chat Completions style. | supported | Uses OpenAI-compatible request and stream translation. |
| CommandCode | openai |
openai-response → openai |
HTTP POST with Accept: text/event-stream. |
supported | Uses OpenAI-compatible request and stream translation. |
| Cursor | openai |
openai-response → openai |
Cursor HTTP/2 Connect protobuf stream; executor synthesizes OpenAI Chat Completion chunks, then translates back to Responses events. | likely, caveated | No distinct Cursor translator is needed. The path should work for basic text and MCP tool calls, but there is no focused test for Responses WS → Cursor, and Cursor conversation IDs do not use the websocket execution session id. |
| GitLab Duo | openai or native gateway |
openai-response → openai |
Specialized GitLab chat/code-suggestions APIs; can synthesize OpenAI-style stream fallback. | partial | Text requests can flow through, but GitLab prompt construction is specialized and does not make this a general Responses-compatible vendor. |
| Kiro | kiro |
No direct openai-response → kiro registration. |
HTTP streaming Kiro endpoints. | not supported | The registry does not chain openai-response → openai → kiro. Missing direct translator means raw Responses JSON is likely passed into Kiro-specific request building. |
| iFlow | openai |
openai-response → openai |
HTTP POST with Accept: text/event-stream. |
executor-only | The executor exists and should work like other OpenAI-compatible paths, but no service registration case was found in ensureExecutorsForAuthWithMode. |
Cursor-specific reading
Cursor is not an arbitrary vendor format. It accepts OpenAI-shaped input inside the executor, then converts it into Cursor's private HTTP/2 Connect protobuf protocol.
ExecuteStreamtranslatesopenai-responsetoopenai.- Cursor emits synthetic OpenAI Chat Completion chunks.
- The OpenAI-to-Responses stream translator turns those chunks into
response.*SSE events, and the websocket handler sends JSON payloads to the client.
Main gaps
The project has a strong direct translator/executor pattern, but no universal adapter layer for arbitrary formats and transports.
- No generic POST-only-to-Responses-websocket event synthesizer.
- No translator chaining for missing direct conversions.
- No focused Cursor test that exercises the full websocket ingress path.