fix(relay/codex): force stream=true on /v1/responses - #5819
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
Walkthrough
ChangesCodex Streaming Enforcement
Estimated code review effort🎯 2 (Simple) | ⏱️ ~5 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@relay/channel/codex/adaptor.go`:
- Around line 103-110: The Codex adaptor is forcing the upstream request to
stream correctly, but it also overwrites the caller’s stream preference by
setting info.IsStream to true. Update the adaptor logic around request.Stream
and info.IsStream so the request is always sent as streaming to Codex while
preserving the original info.IsStream value, and add a non-stream buffered
fallback in DoResponse/OaiResponsesStreamHandler for callers that requested
stream=false so they still receive a JSON response instead of SSE.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 4be7d10d-d839-4da5-ba80-363f8986394d
📒 Files selected for processing (1)
relay/channel/codex/adaptor.go
| // 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 | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Inspect how IsStream is initially derived and whether the stream handler
# accounts for a client that requested non-streaming.
rg -nP --type=go 'func OaiResponsesStreamHandler' -A 40
echo '--- where IsStream is initialized ---'
rg -nP --type=go '\.IsStream\s*=' -C2Repository: QuantumNous/new-api
Length of output: 157
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file list =="
git ls-files | rg '^(relay/channel/codex/adaptor\.go|.*openai.*\.go|.*responses.*\.go|.*stream.*\.go)$' || true
echo
echo "== locate DoResponse / OaiResponsesStreamHandler / IsStream assignments =="
rg -n --hidden --glob '*.go' 'DoResponse|OaiResponsesStreamHandler|IsStream|StreamHandler' relay . || trueRepository: QuantumNous/new-api
Length of output: 50375
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== relay/channel/codex/adaptor.go (lines 90-170) =="
sed -n '90,170p' relay/channel/codex/adaptor.go | cat -n
echo
echo "== relay/channel/openai/relay_responses.go (lines 1-220) =="
sed -n '1,220p' relay/channel/openai/relay_responses.go | cat -n
echo
echo "== relay/channel/openai/chat_via_responses.go (lines 1-240) =="
sed -n '1,240p' relay/channel/openai/chat_via_responses.go | cat -n
echo
echo "== relay/common/relay_info.go (lines 430-500) =="
sed -n '430,500p' relay/common/relay_info.go | cat -n
echo
echo "== relay/chat_completions_via_responses.go (lines 130-175) =="
sed -n '130,175p' relay/chat_completions_via_responses.go | cat -nRepository: QuantumNous/new-api
Length of output: 25086
Preserve the caller's stream preference here
Force request.Stream = true for Codex, but keep info.IsStream unchanged. DoResponse routes through OaiResponsesStreamHandler, which always emits SSE; overwriting info.IsStream makes stream: false callers receive a streamed body instead of the JSON response they asked for. Add a buffered non-stream fallback for those callers.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@relay/channel/codex/adaptor.go` around lines 103 - 110, The Codex adaptor is
forcing the upstream request to stream correctly, but it also overwrites the
caller’s stream preference by setting info.IsStream to true. Update the adaptor
logic around request.Stream and info.IsStream so the request is always sent as
streaming to Codex while preserving the original info.IsStream value, and add a
non-stream buffered fallback in DoResponse/OaiResponsesStreamHandler for callers
that requested stream=false so they still receive a JSON response instead of
SSE.
59eddfd to
c324e13
Compare
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 <noreply@anthropic.com>
c324e13 to
2c2dfb0
Compare
|
codex渠道类型在配置时已有说明,仅能在codex cli中使用,不存在此类使用场景,不会考虑对其进行修改。 |
Important
📝 变更描述 / Description
Codex 渠道(
ChannelTypeCodex=57)走chatgpt.com/backend-api/codex/responses,上游只接受流式请求,缺少"stream": true会返回 HTTP 400Stream must be set to true。#4325已经让"批量自动测试"路径强制使用 stream,但手动测试按钮路径漏了:前端测试弹窗默认Stream Mode开关关闭时,streamquery 参数未发送,后端strconv.ParseBool解析为空→false,buildTestRequest拼出Stream: lo.ToPtr(false),导致手动测试必然 400。把强制
stream=true的逻辑下沉到 codex 适配器(relay/channel/codex/adaptor.go:103-110),让所有调用路径(手动测试、批量测试、playground、第三方客户端)都符合上游契约。同时把info.IsStream同步置true,避免DoResponse把 SSE 响应按非流式 JSON 解析。/v1/responses/compact端点不在此约束范围内,因此保留原有行为。🚀 变更类型 / Type of change
🔗 关联任务 / Related Issue
fix: use stream for codex auto test)400 Stream must be set to true✅ 提交前检查项 / Checklist
info.IsStream避免响应解析错误。relay/channel/codex/adaptor.go一个文件、9 行新增。go test;改动面小且正交,参考 fix: use stream for codex auto test #4325 同一文件同类改动可由维护者快速复核。codex_key.json等本地调试文件未入库。📸 运行证明 / Proof of Work
调用路径推导(
controller/channel-test.go:75-152→controller/channel-test.go:695-756→relay/responses_handler.go:81-86→relay/channel/codex/adaptor.go:56-117):Stream Mode=off→isStream=false→request.Stream=*bool{false}→ 上游 400request.Stream=lo.ToPtr(true)由 codex 适配器无条件覆盖 → 上游接受🤖 AI 协助说明 / AI Assistance Disclosure
本次改动由 Claude(Anthropic)协助完成:
Summary by CodeRabbit