修复 Codex(OpenAI OAuth) 渠道 endpoint 找不到问题 - #2871
Conversation
WalkthroughCodex channel handling is modified to constrain endpoint selection to responses endpoints based on model suffix, force streaming mode in request conversion, and simplify test request construction by short-circuiting for Codex channels. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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
🤖 Fix all issues with AI agents
In `@relay/channel/codex/adaptor.go`:
- Around line 99-105: The adaptor currently forces streaming unconditionally
(setting request.Stream = true and info.IsStream = true), which breaks the
compact path; update the logic in the Codex adaptor so streaming is only forced
when the request is not a compact request: check the existing isCompact
condition (the same flag used to pick OaiResponsesCompactionHandler) before
mutating request.Stream/info.IsStream and only set them when isCompact is false;
alternatively, if the compact endpoint truly needs SSE, update
OaiResponsesCompactionHandler to parse SSE instead of using
io.ReadAll+Unmarshal—reference symbols: request.Stream, info.IsStream,
isCompact, SetupRequestHeader, OaiResponsesCompactionHandler, and the
/backend-api/codex/responses/compact handler.
🧹 Nitpick comments (1)
controller/channel-test.go (1)
574-580: Use the existingtestResponsesInputvariable instead of a duplicate literal.
testResponsesInputis already defined at Line 486 with the same JSON value. Reuse it for consistency and to avoid drift if the test payload changes.♻️ Proposed fix
// Codex channel only supports responses endpoints. if channel != nil && channel.Type == constant.ChannelTypeCodex { return &dto.OpenAIResponsesRequest{ Model: model, - Input: json.RawMessage(`[{"role":"user","content":"hi"}]`), + Input: testResponsesInput, } }Note:
testResponsesInputis a local variable inbuildTestRequest, so it's already in scope.
| // Codex backend requires streaming; force stream when unset. | ||
| if !request.Stream { | ||
| request.Stream = true | ||
| if info != nil { | ||
| info.IsStream = true | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, let's look at the full adaptor.go file to understand the flow
wc -l relay/channel/codex/adaptor.goRepository: QuantumNous/new-api
Length of output: 97
🏁 Script executed:
#!/bin/bash
# Get the relevant sections of adaptor.go around the lines mentioned
cat -n relay/channel/codex/adaptor.go | sed -n '95,135p'Repository: QuantumNous/new-api
Length of output: 1607
🏁 Script executed:
#!/bin/bash
# Find the OaiResponsesCompactionHandler function
ast-grep --pattern $'func OaiResponsesCompactionHandler($_, $_) {
$$$
}'Repository: QuantumNous/new-api
Length of output: 45
🏁 Script executed:
#!/bin/bash
# Also try a simpler search for the handler
rg -A 20 "func OaiResponsesCompactionHandler" relay/channel/codex/Repository: QuantumNous/new-api
Length of output: 45
🏁 Script executed:
#!/bin/bash
# Look for SetupRequestHeader method in the same file
rg -n -B 3 -A 10 "SetupRequestHeader" relay/channel/codex/adaptor.goRepository: QuantumNous/new-api
Length of output: 572
🏁 Script executed:
#!/bin/bash
# Get more of SetupRequestHeader to see the Accept header logic
cat -n relay/channel/codex/adaptor.go | sed -n '156,200p'Repository: QuantumNous/new-api
Length of output: 1721
🏁 Script executed:
#!/bin/bash
# Find OaiResponsesCompactionHandler in the openai package
rg -A 30 "func OaiResponsesCompactionHandler" relay/channel/openai/Repository: QuantumNous/new-api
Length of output: 2668
🏁 Script executed:
#!/bin/bash
# Search for where OaiResponsesCompactionHandler is defined
fd -t f "\.go$" relay/channel/openai/ | xargs rg -l "OaiResponsesCompactionHandler"Repository: QuantumNous/new-api
Length of output: 142
🏁 Script executed:
#!/bin/bash
# Check if there's any streaming handling in the compact handler
cat -n relay/channel/openai/relay_responses_compact.goRepository: QuantumNous/new-api
Length of output: 1773
🏁 Script executed:
#!/bin/bash
# Look for any comments or documentation about Codex compact endpoint streaming behavior
rg -B 5 -A 5 "compact" relay/channel/codex/ -iRepository: QuantumNous/new-api
Length of output: 5055
🏁 Script executed:
#!/bin/bash
# Check if there's any special streaming handling in OpenAI package for compact
rg -B 5 -A 15 "func OaiResponsesStreamHandler" relay/channel/openai/relay_responses.go | head -40Repository: QuantumNous/new-api
Length of output: 786
🏁 Script executed:
#!/bin/bash
# Look for any recent changes or PR context about compact streaming
git log --oneline relay/channel/codex/adaptor.go | head -20Repository: QuantumNous/new-api
Length of output: 112
🏁 Script executed:
#!/bin/bash
# Check if StreamScannerHandler expects server-sent event format
rg -B 3 -A 20 "func StreamScannerHandler" relay/Repository: QuantumNous/new-api
Length of output: 1429
🏁 Script executed:
#!/bin/bash
# Look at the complete GetRequestURL to understand both endpoints
cat -n relay/channel/codex/adaptor.go | sed -n '146,155p'Repository: QuantumNous/new-api
Length of output: 600
🏁 Script executed:
#!/bin/bash
# Check what the compact endpoint is supposed to return - look for test files or docs
fd -t f "compact" relay/channel/codex/ relay/channel/openai/ | head -20Repository: QuantumNous/new-api
Length of output: 110
🏁 Script executed:
#!/bin/bash
# See if there are any tests for the compact handler that show expected response format
find relay -name "*.go" -type f | xargs rg -l "OaiResponsesCompactionHandler" | xargs grep -l "test\|Test"Repository: QuantumNous/new-api
Length of output: 47
🏁 Script executed:
#!/bin/bash
# Check if there are any comments or documentation about whether both Codex endpoints require streaming
rg -B 10 -A 10 "Codex backend requires streaming" relay/channel/codex/Repository: QuantumNous/new-api
Length of output: 1168
🏁 Script executed:
#!/bin/bash
# Check the git history for this change to understand the intent
git show HEAD:relay/channel/codex/adaptor.go | grep -A 20 "Codex backend requires streaming"Repository: QuantumNous/new-api
Length of output: 606
🏁 Script executed:
#!/bin/bash
# Let me check if there's any conditional logic about when streaming is actually sent vs expected
# Look at the exact request body to understand what's being sent
rg -B 5 -A 15 "SetupRequestHeader" relay/channel/openai/relay-openai.go | head -50Repository: QuantumNous/new-api
Length of output: 45
🏁 Script executed:
#!/bin/bash
# Check if the backend behavior differs based on Accept header vs stream parameter
# Look at how stream parameter affects responses in test or doc files
find relay -name "*.md" -o -name "*.txt" | xargs rg -l "codex" -i 2>/dev/null || echo "No docs found"Repository: QuantumNous/new-api
Length of output: 1181
🏁 Script executed:
#!/bin/bash
# Final check: see if compact requests ever worked or if there are any error handling comments
rg -B 5 -A 10 "OpenAIResponsesCompactionResponse" relay/channel/Repository: QuantumNous/new-api
Length of output: 1470
Forced streaming creates incompatibility with the compact response handler.
Streaming is forced unconditionally at lines 99-105 (before the isCompact check at line 107), which causes:
-
Compact requests receive conflicting handlers:
request.Stream = truecauses the SetupRequestHeader to setAccept: text/event-stream(line 194), so the Codex backend responds in server-sent events format. However, the compact handler at line 128 (OaiResponsesCompactionHandler) callsio.ReadAll()followed byUnmarshal()expecting a single JSON object, not streaming format—this will fail. -
SetupRequestHeader else branch is dead code: The condition at lines 195-196 can never execute in the Codex adaptor since
info.IsStreamis alwaystrue.
If the Codex backend's /backend-api/codex/responses/compact endpoint requires streaming, the compact handler needs to parse SSE format. If it doesn't require streaming, the forced streaming should not apply to compact requests.
🤖 Prompt for AI Agents
In `@relay/channel/codex/adaptor.go` around lines 99 - 105, The adaptor currently
forces streaming unconditionally (setting request.Stream = true and
info.IsStream = true), which breaks the compact path; update the logic in the
Codex adaptor so streaming is only forced when the request is not a compact
request: check the existing isCompact condition (the same flag used to pick
OaiResponsesCompactionHandler) before mutating request.Stream/info.IsStream and
only set them when isCompact is false; alternatively, if the compact endpoint
truly needs SSE, update OaiResponsesCompactionHandler to parse SSE instead of
using io.ReadAll+Unmarshal—reference symbols: request.Stream, info.IsStream,
isCompact, SetupRequestHeader, OaiResponsesCompactionHandler, and the
/backend-api/codex/responses/compact handler.
|
这个测试本来就是非流的,强制改成stream不是很妥当,结果都是对不上的。 |
|
确实强制改 stream 不太合适,这个修改发起的最初目的是如果我在创建 Codex (OpenAI OAuth) 渠道时使用 /v1/chat/completions 进行验证会不通过,所以让AI修复这个问题。但是刚刚我又检查了一下代码,其实对 codex 后缀的模型是有判断的。这里或许可以有个友好的提示,或者增加更多条件修改 requestPath。我将会在 PR #2873 重新创建一个 |
你这个直接给写成带gpt名字的模型给切到responses了,这就更不合适了。 |
|
codex现在这一版的肯定明显有bug。不知道最新版修好未 |
在使用 Codex (OpenAI OAuth) 登陆时如果上游不支持 chat complations API 会导致报错找不到 endpoint,但是 Codex 上游是一定支持 responses api 的,所以把用于验证的借口换成 responses api
Summary by CodeRabbit