Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions controller/channel-test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ func testChannel(channel *model.Channel, testModel string, endpointType string)
if strings.HasSuffix(testModel, ratio_setting.CompactModelSuffix) {
requestPath = "/v1/responses/compact"
}

// Codex channel only supports responses endpoints.
if channel.Type == constant.ChannelTypeCodex {
if strings.HasSuffix(testModel, ratio_setting.CompactModelSuffix) {
requestPath = "/v1/responses/compact"
} else {
requestPath = "/v1/responses"
}
}
}
if strings.HasPrefix(requestPath, "/v1/responses/compact") {
testModel = ratio_setting.WithCompactModelSuffix(testModel)
Expand Down Expand Up @@ -562,6 +571,14 @@ func buildTestRequest(model string, endpointType string, channel *model.Channel)
}
}

// 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"}]`),
}
}

// Responses-only models (e.g. codex series)
if strings.Contains(strings.ToLower(model), "codex") {
return &dto.OpenAIResponsesRequest{
Expand Down
8 changes: 8 additions & 0 deletions relay/channel/codex/adaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ func (a *Adaptor) ConvertOpenAIResponsesRequest(c *gin.Context, info *relaycommo
request.Instructions = json.RawMessage(`""`)
}

// Codex backend requires streaming; force stream when unset.
if !request.Stream {
request.Stream = true
if info != nil {
info.IsStream = true
}
}
Comment on lines +99 to +105

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 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.go

Repository: 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.go

Repository: 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.go

Repository: 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/ -i

Repository: 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 -40

Repository: 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 -20

Repository: 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 -20

Repository: 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 -50

Repository: 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:

  1. Compact requests receive conflicting handlers: request.Stream = true causes the SetupRequestHeader to set Accept: text/event-stream (line 194), so the Codex backend responds in server-sent events format. However, the compact handler at line 128 (OaiResponsesCompactionHandler) calls io.ReadAll() followed by Unmarshal() expecting a single JSON object, not streaming format—this will fail.

  2. SetupRequestHeader else branch is dead code: The condition at lines 195-196 can never execute in the Codex adaptor since info.IsStream is always true.

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.


if isCompact {
return request, nil
}
Expand Down