Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
dad57a6b
authored
Jul 11, 2026
by
Seefs
Committed by
GitHub
Jul 11, 2026
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: sync codex field (#6018)
parent
00f1cbb6
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
162 additions
and
14 deletions
+162
-14
dto/openai_request.go
+7
-2
dto/openai_responses_compaction_request.go
+9
-0
relay/channel/codex/constants.go
+1
-1
relay/helper/stream_scanner.go
+20
-0
relay/responses_handler.go
+2
-0
setting/operation_setting/channel_affinity_setting.go
+36
-1
web/classic/src/constants/channel-affinity-template.constants.js
+30
-4
web/default/src/features/channels/components/dialogs/param-override-editor-dialog.tsx
+27
-3
web/default/src/features/system-settings/general/channel-affinity/constants.ts
+30
-3
No files found.
dto/openai_request.go
View file @
dad57a6b
...
...
@@ -874,6 +874,9 @@ type OpenAIResponsesRequest struct {
User
json
.
RawMessage
`json:"user,omitempty"`
MaxToolCalls
*
uint
`json:"max_tool_calls,omitempty"`
Prompt
json
.
RawMessage
`json:"prompt,omitempty"`
// Codex Responses metadata/client_metadata:
// https://github.com/openai/codex/commit/14df0e8833aad0d6d78287954b61ffac67af936c
ClientMetadata
json
.
RawMessage
`json:"client_metadata,omitempty"`
// qwen
EnableThinking
json
.
RawMessage
`json:"enable_thinking,omitempty"`
// perplexity
...
...
@@ -958,8 +961,10 @@ func (r *OpenAIResponsesRequest) GetToolsMap() []map[string]any {
}
type
Reasoning
struct
{
Effort
string
`json:"effort,omitempty"`
Summary
string
`json:"summary,omitempty"`
Effort
string
`json:"effort,omitempty"`
Summary
string
`json:"summary,omitempty"`
Mode
json
.
RawMessage
`json:"mode,omitempty"`
Context
json
.
RawMessage
`json:"context,omitempty"`
}
type
Input
struct
{
...
...
dto/openai_responses_compaction_request.go
View file @
dad57a6b
...
...
@@ -14,6 +14,15 @@ type OpenAIResponsesCompactionRequest struct {
Input
json
.
RawMessage
`json:"input,omitempty"`
Instructions
json
.
RawMessage
`json:"instructions,omitempty"`
PreviousResponseID
string
`json:"previous_response_id,omitempty"`
// Codex compact request parity:
// https://github.com/openai/codex/commit/53d59722268dde82fb93c1f37964ce196c2a86d7
// https://github.com/openai/codex/commit/5d6f23a27bf9c90709af527a7108c1c2eadf5123
Tools
json
.
RawMessage
`json:"tools,omitempty"`
ParallelToolCalls
json
.
RawMessage
`json:"parallel_tool_calls,omitempty"`
Reasoning
*
Reasoning
`json:"reasoning,omitempty"`
ServiceTier
string
`json:"service_tier,omitempty"`
PromptCacheKey
json
.
RawMessage
`json:"prompt_cache_key,omitempty"`
Text
json
.
RawMessage
`json:"text,omitempty"`
}
func
(
r
*
OpenAIResponsesCompactionRequest
)
GetTokenCountMeta
()
*
types
.
TokenCountMeta
{
...
...
relay/channel/codex/constants.go
View file @
dad57a6b
...
...
@@ -9,7 +9,7 @@ var baseModelList = []string{
"gpt-5"
,
"gpt-5-codex"
,
"gpt-5-codex-mini"
,
"gpt-5.1"
,
"gpt-5.1-codex"
,
"gpt-5.1-codex-max"
,
"gpt-5.1-codex-mini"
,
"gpt-5.2"
,
"gpt-5.2-codex"
,
"gpt-5.3-codex"
,
"gpt-5.3-codex-spark"
,
"gpt-5.4"
,
"gpt-5.4"
,
"gpt-5.6-sol"
,
"gpt-5.6-terra"
,
"gpt-5.6-luna"
,
}
var
ModelList
=
withCompactModelSuffix
(
baseModelList
)
...
...
relay/helper/stream_scanner.go
View file @
dad57a6b
...
...
@@ -14,6 +14,7 @@ import (
"github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/logger"
relaycommon
"github.com/QuantumNous/new-api/relay/common"
"github.com/QuantumNous/new-api/service"
"github.com/QuantumNous/new-api/setting/operation_setting"
"github.com/bytedance/gopkg/util/gopool"
...
...
@@ -45,6 +46,24 @@ func NewStreamScanner(reader io.Reader) *bufio.Scanner {
return
scanner
}
func
copyCodexSSEHeaders
(
c
*
gin
.
Context
,
resp
*
http
.
Response
)
{
if
c
==
nil
||
c
.
Writer
==
nil
||
resp
==
nil
{
return
}
// codex
for
_
,
name
:=
range
[]
string
{
"X-Reasoning-Included"
,
"X-Codex-Turn-State"
}
{
values
:=
resp
.
Header
.
Values
(
name
)
if
!
service
.
ShouldCopyUpstreamHeader
(
c
,
name
,
values
)
{
continue
}
for
_
,
value
:=
range
values
{
if
value
!=
""
{
c
.
Writer
.
Header
()
.
Add
(
name
,
value
)
}
}
}
}
// ExtendWriteDeadline pushes the connection write deadline forward before each
// stream write. Best-effort: writers that don't support deadlines (e.g.
// httptest recorders) are silently ignored.
...
...
@@ -122,6 +141,7 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon
defer
cleanup
()
scanner
.
Split
(
bufio
.
ScanLines
)
copyCodexSSEHeaders
(
c
,
resp
)
SetEventStreamHeaders
(
c
)
ctx
=
context
.
WithValue
(
ctx
,
"stop_chan"
,
stopChan
)
...
...
relay/responses_handler.go
View file @
dad57a6b
...
...
@@ -45,6 +45,8 @@ func ResponsesHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *
Input
:
req
.
Input
,
Instructions
:
req
.
Instructions
,
PreviousResponseID
:
req
.
PreviousResponseID
,
ParallelToolCalls
:
req
.
ParallelToolCalls
,
ServiceTier
:
req
.
ServiceTier
,
}
default
:
return
types
.
NewErrorWithStatusCode
(
...
...
setting/operation_setting/channel_affinity_setting.go
View file @
dad57a6b
...
...
@@ -36,12 +36,33 @@ type ChannelAffinitySetting struct {
Rules
[]
ChannelAffinityRule
`json:"rules"`
}
// Keep Codex CLI passthrough aligned with upstream. Codex uses lower-case
// header names, while HTTP matching here is case-insensitive.
// Request session/thread headers:
// https://github.com/openai/codex/commit/7c7b4861d88960f7e3bd5b7f30f8351be666dd84
// Responses metadata headers/client_metadata:
// https://github.com/openai/codex/commit/14df0e8833aad0d6d78287954b61ffac67af936c
// x-codex-turn-state response/request round trip:
// https://github.com/openai/codex/commit/ebdd8795e924a8149b616e46ca2ed7848c207a4b
var
codexCliPassThroughHeaders
=
[]
string
{
"Originator"
,
"Session_id"
,
"Thread_id"
,
"Session-Id"
,
"Thread-Id"
,
"X-Client-Request-Id"
,
"User-Agent"
,
"X-Codex-Beta-Features"
,
"X-Codex-Turn-State"
,
"X-Codex-Turn-Metadata"
,
"X-Codex-Window-Id"
,
"X-Codex-Parent-Thread-Id"
,
//"X-Codex-Installation-Id",
"X-OpenAI-Subagent"
,
"X-OpenAI-Memgen-Request"
,
//"X-OAI-Attestation",
"X-ResponsesAPI-Include-Timing-Metrics"
,
"X-OpenAI-Internal-Codex-Responses-Lite"
,
}
var
claudeCliPassThroughHeaders
=
[]
string
{
...
...
@@ -74,6 +95,20 @@ func buildPassHeaderTemplate(headers []string) map[string]interface{} {
}
}
func
buildCodexPassHeaderTemplate
()
map
[
string
]
interface
{}
{
requestHeaders
:=
make
([]
string
,
0
,
len
(
codexCliPassThroughHeaders
))
requestHeaders
=
append
(
requestHeaders
,
codexCliPassThroughHeaders
...
)
return
map
[
string
]
interface
{}{
"operations"
:
[]
map
[
string
]
interface
{}{
{
"mode"
:
"pass_headers"
,
"value"
:
requestHeaders
,
"keep_origin"
:
true
,
},
},
}
}
var
channelAffinitySetting
=
ChannelAffinitySetting
{
Enabled
:
true
,
SwitchOnSuccess
:
true
,
...
...
@@ -90,7 +125,7 @@ var channelAffinitySetting = ChannelAffinitySetting{
},
ValueRegex
:
""
,
TTLSeconds
:
0
,
ParamOverrideTemplate
:
build
PassHeaderTemplate
(
codexCliPassThroughHeaders
),
ParamOverrideTemplate
:
build
CodexPassHeaderTemplate
(
),
SkipRetryOnFailure
:
true
,
IncludeUsingGroup
:
true
,
IncludeRuleName
:
true
,
...
...
web/classic/src/constants/channel-affinity-template.constants.js
View file @
dad57a6b
...
...
@@ -27,12 +27,39 @@ const buildPassHeadersTemplate = (headers) => ({
],
});
const
buildCodexPassHeadersTemplate
=
()
=>
({
operations
:
[
{
mode
:
'pass_headers'
,
value
:
[...
CODEX_CLI_HEADER_PASSTHROUGH_HEADERS
],
keep_origin
:
true
,
},
],
});
// Keep in sync with upstream Codex request headers:
// https://github.com/openai/codex/commit/7c7b4861d88960f7e3bd5b7f30f8351be666dd84
// https://github.com/openai/codex/commit/14df0e8833aad0d6d78287954b61ffac67af936c
// https://github.com/openai/codex/commit/ebdd8795e924a8149b616e46ca2ed7848c207a4b
export
const
CODEX_CLI_HEADER_PASSTHROUGH_HEADERS
=
[
'Originator'
,
'Session_id'
,
'Thread_id'
,
'Session-Id'
,
'Thread-Id'
,
'X-Client-Request-Id'
,
'User-Agent'
,
'X-Codex-Beta-Features'
,
'X-Codex-Turn-State'
,
'X-Codex-Turn-Metadata'
,
'X-Codex-Window-Id'
,
'X-Codex-Parent-Thread-Id'
,
// 'X-Codex-Installation-Id',
'X-OpenAI-Subagent'
,
'X-OpenAI-Memgen-Request'
,
// 'X-OAI-Attestation',
'X-ResponsesAPI-Include-Timing-Metrics'
,
'X-OpenAI-Internal-Codex-Responses-Lite'
,
];
export
const
CLAUDE_CLI_HEADER_PASSTHROUGH_HEADERS
=
[
...
...
@@ -51,9 +78,8 @@ export const CLAUDE_CLI_HEADER_PASSTHROUGH_HEADERS = [
'Anthropic-Version'
,
];
export
const
CODEX_CLI_HEADER_PASSTHROUGH_TEMPLATE
=
buildPassHeadersTemplate
(
CODEX_CLI_HEADER_PASSTHROUGH_HEADERS
,
);
export
const
CODEX_CLI_HEADER_PASSTHROUGH_TEMPLATE
=
buildCodexPassHeadersTemplate
();
export
const
CLAUDE_CLI_HEADER_PASSTHROUGH_TEMPLATE
=
buildPassHeadersTemplate
(
CLAUDE_CLI_HEADER_PASSTHROUGH_HEADERS
,
...
...
@@ -65,7 +91,7 @@ export const CHANNEL_AFFINITY_RULE_TEMPLATES = {
model_regex
:
[
'^gpt-.*$'
],
path_regex
:
[
'/v1/responses'
],
key_sources
:
[{
type
:
'gjson'
,
path
:
'prompt_cache_key'
}],
param_override_template
:
CODEX_CLI_HEADER_PASSTHROUGH_TEMPLATE
,
param_override_template
:
buildCodexPassHeadersTemplate
()
,
value_regex
:
''
,
ttl_seconds
:
0
,
skip_retry_on_failure
:
true
,
...
...
web/default/src/features/channels/components/dialogs/param-override-editor-dialog.tsx
View file @
dad57a6b
...
...
@@ -291,12 +291,29 @@ const GEMINI_IMAGE_4K_TEMPLATE = {
],
}
// Keep in sync with upstream Codex request headers:
// https://github.com/openai/codex/commit/7c7b4861d88960f7e3bd5b7f30f8351be666dd84
// https://github.com/openai/codex/commit/14df0e8833aad0d6d78287954b61ffac67af936c
// https://github.com/openai/codex/commit/ebdd8795e924a8149b616e46ca2ed7848c207a4b
const
CODEX_CLI_HEADER_PASSTHROUGH_HEADERS
=
[
'Originator'
,
'Session_id'
,
'Thread_id'
,
'Session-Id'
,
'Thread-Id'
,
'X-Client-Request-Id'
,
'User-Agent'
,
'X-Codex-Beta-Features'
,
'X-Codex-Turn-State'
,
'X-Codex-Turn-Metadata'
,
'X-Codex-Window-Id'
,
'X-Codex-Parent-Thread-Id'
,
// 'X-Codex-Installation-Id',
'X-OpenAI-Subagent'
,
'X-OpenAI-Memgen-Request'
,
// 'X-OAI-Attestation',
'X-ResponsesAPI-Include-Timing-Metrics'
,
'X-OpenAI-Internal-Codex-Responses-Lite'
,
]
const
CLAUDE_CLI_HEADER_PASSTHROUGH_HEADERS
=
[
...
...
@@ -321,9 +338,15 @@ const buildPassHeadersTemplate = (headers: string[]) => ({
],
})
const
CODEX_CLI_HEADER_PASSTHROUGH_TEMPLATE
=
buildPassHeadersTemplate
(
CODEX_CLI_HEADER_PASSTHROUGH_HEADERS
)
const
CODEX_CLI_HEADER_PASSTHROUGH_TEMPLATE
=
{
operations
:
[
{
mode
:
'pass_headers'
,
value
:
[...
CODEX_CLI_HEADER_PASSTHROUGH_HEADERS
],
keep_origin
:
true
,
},
],
}
const
CLAUDE_CLI_HEADER_PASSTHROUGH_TEMPLATE
=
buildPassHeadersTemplate
(
CLAUDE_CLI_HEADER_PASSTHROUGH_HEADERS
)
...
...
@@ -941,6 +964,7 @@ const validateOperations = (
if
(
headers
.
length
===
0
)
return
t
(
'Rule {{line}} pass_headers format is invalid'
,
{
line
})
}
}
return
''
}
...
...
web/default/src/features/system-settings/general/channel-affinity/constants.ts
View file @
dad57a6b
...
...
@@ -18,12 +18,29 @@ For commercial licensing, please contact support@quantumnous.com
*/
import
type
{
AffinityRule
}
from
'./types'
// Keep in sync with upstream Codex request headers:
// https://github.com/openai/codex/commit/7c7b4861d88960f7e3bd5b7f30f8351be666dd84
// https://github.com/openai/codex/commit/14df0e8833aad0d6d78287954b61ffac67af936c
// https://github.com/openai/codex/commit/ebdd8795e924a8149b616e46ca2ed7848c207a4b
const
CODEX_CLI_HEADER_PASSTHROUGH_HEADERS
=
[
'Originator'
,
'Session_id'
,
'Thread_id'
,
'Session-Id'
,
'Thread-Id'
,
'X-Client-Request-Id'
,
'User-Agent'
,
'X-Codex-Beta-Features'
,
'X-Codex-Turn-State'
,
'X-Codex-Turn-Metadata'
,
'X-Codex-Window-Id'
,
'X-Codex-Parent-Thread-Id'
,
// 'X-Codex-Installation-Id',
'X-OpenAI-Subagent'
,
'X-OpenAI-Memgen-Request'
,
// 'X-OAI-Attestation',
'X-ResponsesAPI-Include-Timing-Metrics'
,
'X-OpenAI-Internal-Codex-Responses-Lite'
,
]
const
CLAUDE_CLI_HEADER_PASSTHROUGH_HEADERS
=
[
...
...
@@ -54,6 +71,18 @@ function buildPassHeadersTemplate(headers: string[]) {
}
}
function
buildCodexPassHeadersTemplate
()
{
return
{
operations
:
[
{
mode
:
'pass_headers'
,
value
:
[...
CODEX_CLI_HEADER_PASSTHROUGH_HEADERS
],
keep_origin
:
true
,
},
],
}
}
export
type
RuleTemplate
=
Omit
<
AffinityRule
,
'id'
>
export
const
RULE_TEMPLATES
:
Record
<
string
,
RuleTemplate
>
=
{
...
...
@@ -62,9 +91,7 @@ export const RULE_TEMPLATES: Record<string, RuleTemplate> = {
model_regex
:
[
'^gpt-.*$'
],
path_regex
:
[
'/v1/responses'
],
key_sources
:
[{
type
:
'gjson'
,
path
:
'prompt_cache_key'
}],
param_override_template
:
buildPassHeadersTemplate
(
CODEX_CLI_HEADER_PASSTHROUGH_HEADERS
),
param_override_template
:
buildCodexPassHeadersTemplate
(),
value_regex
:
''
,
ttl_seconds
:
0
,
skip_retry_on_failure
:
true
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment