From 2c2dfb0d0f2a77b9944cddd49b94b1de4ff948eb Mon Sep 17 00:00:00 2001 From: Ericcc <55902434+Ericcc-Ma@users.noreply.github.com> Date: Wed, 1 Jul 2026 09:27:04 +0800 Subject: [PATCH] fix(relay/codex): force stream=true on /v1/responses Codex upstream (chatgpt.com/backend-api/codex/responses) rejects requests without "stream": true with HTTP 400 "Stream must be set to true". The manual channel test button previously sent stream=false unless the user explicitly toggled the Stream Mode switch in the test dialog, since the manual test path passes the stream query parameter straight through buildTestRequest without honoring shouldUseStreamForAutomaticChannelTest. Force stream=true inside the codex adapter so every call path (manual test, batch test, playground, third-party clients) honors the upstream contract. Also set info.IsStream=true so DoResponse routes the SSE response through OaiResponsesStreamHandler instead of trying to parse it as a non-stream JSON body. The /v1/responses/compact endpoint is left untouched since compact requests do not share the same upstream constraint. Co-Authored-By: Claude --- relay/channel/codex/adaptor.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/relay/channel/codex/adaptor.go b/relay/channel/codex/adaptor.go index ef4d4fa04125..250eeb9098dd 100644 --- a/relay/channel/codex/adaptor.go +++ b/relay/channel/codex/adaptor.go @@ -14,6 +14,7 @@ import ( relaycommon "github.com/QuantumNous/new-api/relay/common" relayconstant "github.com/QuantumNous/new-api/relay/constant" "github.com/QuantumNous/new-api/types" + "github.com/samber/lo" "github.com/gin-gonic/gin" ) @@ -99,6 +100,14 @@ func (a *Adaptor) ConvertOpenAIResponsesRequest(c *gin.Context, info *relaycommo if isCompact { return request, nil } + // Codex upstream (chatgpt.com/backend-api/codex/responses) only accepts + // streaming requests and rejects with 400 "Stream must be set to true" + // otherwise. Force it here so every call path (manual test, batch test, + // playground, third-party clients) honors the upstream contract. + request.Stream = lo.ToPtr(true) + if info != nil { + info.IsStream = true + } // codex: store must be false request.Store = json.RawMessage("false") // rm max_output_tokens