Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
77d916ff
Commit
77d916ff
authored
Mar 05, 2026
by
程序猿MT
Browse files
feat(openai-handler): support codex remote compact outcome logging
parent
9d70c385
Changes
1
Hide whitespace changes
Inline
Side-by-side
backend/internal/handler/openai_gateway_handler.go
View file @
77d916ff
...
...
@@ -33,6 +33,7 @@ type OpenAIGatewayHandler struct {
errorPassthroughService
*
service
.
ErrorPassthroughService
concurrencyHelper
*
ConcurrencyHelper
maxAccountSwitches
int
cfg
*
config
.
Config
}
// NewOpenAIGatewayHandler creates a new OpenAIGatewayHandler
...
...
@@ -61,6 +62,7 @@ func NewOpenAIGatewayHandler(
errorPassthroughService
:
errorPassthroughService
,
concurrencyHelper
:
NewConcurrencyHelper
(
concurrencyService
,
SSEPingFormatComment
,
pingInterval
),
maxAccountSwitches
:
maxAccountSwitches
,
cfg
:
cfg
,
}
}
...
...
@@ -70,6 +72,8 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) {
// 局部兜底:确保该 handler 内部任何 panic 都不会击穿到进程级。
streamStarted
:=
false
defer
h
.
recoverResponsesPanic
(
c
,
&
streamStarted
)
compactStartedAt
:=
time
.
Now
()
defer
h
.
logOpenAIRemoteCompactOutcome
(
c
,
compactStartedAt
)
setOpenAIClientTransportHTTP
(
c
)
requestStart
:=
time
.
Now
()
...
...
@@ -340,6 +344,86 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) {
}
}
func
isOpenAIRemoteCompactPath
(
c
*
gin
.
Context
)
bool
{
if
c
==
nil
||
c
.
Request
==
nil
||
c
.
Request
.
URL
==
nil
{
return
false
}
normalizedPath
:=
strings
.
TrimRight
(
strings
.
TrimSpace
(
c
.
Request
.
URL
.
Path
),
"/"
)
return
strings
.
HasSuffix
(
normalizedPath
,
"/responses/compact"
)
}
func
(
h
*
OpenAIGatewayHandler
)
logOpenAIRemoteCompactOutcome
(
c
*
gin
.
Context
,
startedAt
time
.
Time
)
{
if
!
isOpenAIRemoteCompactPath
(
c
)
{
return
}
var
(
ctx
context
.
Context
=
context
.
Background
()
path
string
status
int
)
if
c
!=
nil
{
if
c
.
Request
!=
nil
{
ctx
=
c
.
Request
.
Context
()
if
c
.
Request
.
URL
!=
nil
{
path
=
strings
.
TrimSpace
(
c
.
Request
.
URL
.
Path
)
}
}
if
c
.
Writer
!=
nil
{
status
=
c
.
Writer
.
Status
()
}
}
outcome
:=
"failed"
if
status
>=
200
&&
status
<
300
{
outcome
=
"succeeded"
}
latencyMs
:=
time
.
Since
(
startedAt
)
.
Milliseconds
()
if
latencyMs
<
0
{
latencyMs
=
0
}
fields
:=
[]
zap
.
Field
{
zap
.
String
(
"component"
,
"handler.openai_gateway.responses"
),
zap
.
Bool
(
"remote_compact"
,
true
),
zap
.
String
(
"compact_outcome"
,
outcome
),
zap
.
Int
(
"status_code"
,
status
),
zap
.
Int64
(
"latency_ms"
,
latencyMs
),
zap
.
String
(
"path"
,
path
),
zap
.
Bool
(
"force_codex_cli"
,
h
!=
nil
&&
h
.
cfg
!=
nil
&&
h
.
cfg
.
Gateway
.
ForceCodexCLI
),
}
if
c
!=
nil
{
if
userAgent
:=
strings
.
TrimSpace
(
c
.
GetHeader
(
"User-Agent"
));
userAgent
!=
""
{
fields
=
append
(
fields
,
zap
.
String
(
"request_user_agent"
,
userAgent
))
}
if
v
,
ok
:=
c
.
Get
(
opsModelKey
);
ok
{
if
model
,
ok
:=
v
.
(
string
);
ok
&&
strings
.
TrimSpace
(
model
)
!=
""
{
fields
=
append
(
fields
,
zap
.
String
(
"request_model"
,
strings
.
TrimSpace
(
model
)))
}
}
if
v
,
ok
:=
c
.
Get
(
opsAccountIDKey
);
ok
{
if
accountID
,
ok
:=
v
.
(
int64
);
ok
&&
accountID
>
0
{
fields
=
append
(
fields
,
zap
.
Int64
(
"account_id"
,
accountID
))
}
}
if
c
.
Writer
!=
nil
{
if
upstreamRequestID
:=
strings
.
TrimSpace
(
c
.
Writer
.
Header
()
.
Get
(
"x-request-id"
));
upstreamRequestID
!=
""
{
fields
=
append
(
fields
,
zap
.
String
(
"upstream_request_id"
,
upstreamRequestID
))
}
else
if
upstreamRequestID
:=
strings
.
TrimSpace
(
c
.
Writer
.
Header
()
.
Get
(
"X-Request-Id"
));
upstreamRequestID
!=
""
{
fields
=
append
(
fields
,
zap
.
String
(
"upstream_request_id"
,
upstreamRequestID
))
}
}
}
log
:=
logger
.
FromContext
(
ctx
)
.
With
(
fields
...
)
if
outcome
==
"succeeded"
{
log
.
Info
(
"codex.remote_compact.succeeded"
)
return
}
log
.
Warn
(
"codex.remote_compact.failed"
)
}
func
(
h
*
OpenAIGatewayHandler
)
validateFunctionCallOutputRequest
(
c
*
gin
.
Context
,
body
[]
byte
,
reqLog
*
zap
.
Logger
)
bool
{
if
!
gjson
.
GetBytes
(
body
,
`input.#(type=="function_call_output")`
)
.
Exists
()
{
return
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