feat(executor): refine session and conversation header handling for Codex

- Updated session handling to replace `Session_id` and `Conversation_id` headers with new logic ensuring consistent use of `Cache.ID` and prompt keys.
- Restored `Session_id` as a priority extraction source for `ExtractSessionID`.
- Added tests to validate case-sensitive and case-insensitive headers, canonical account header usage, and session key preservation.
- Removed legacy support for deprecated `Conversation_id` header to clean up API.
This commit is contained in:
Luis Pater
2026-06-01 11:27:10 +08:00
parent fb4f39d300
commit 05b972479a
9 changed files with 129 additions and 61 deletions
+20 -9
View File
@@ -931,6 +931,9 @@ func (e *CodexExecutor) cacheHelper(ctx context.Context, from sdktranslator.Form
if err != nil {
return nil, nil, codexIdentityConfuseState{}, err
}
if cache.ID != "" {
httpReq.Header.Set("Session_id", cache.ID)
}
return httpReq, rawJSON, identityState, nil
}
@@ -964,7 +967,6 @@ func applyCodexIdentityConfuseHeaders(headers http.Header, state *codexIdentityC
if headers == nil {
return
}
defer deleteDeprecatedCodexConversationHeader(headers)
if state == nil || !state.enabled {
return
}
@@ -977,6 +979,12 @@ func applyCodexIdentityConfuseHeaders(headers http.Header, state *codexIdentityC
}
setHeaderCasePreserved(headers, "Session-Id", state.promptCacheKey)
if headerValueCaseInsensitive(headers, "session_id") != "" {
setHeaderCasePreserved(headers, "session_id", state.promptCacheKey)
}
if headerValueCaseInsensitive(headers, "Conversation_id") != "" {
setHeaderCasePreserved(headers, "Conversation_id", state.promptCacheKey)
}
headers.Set("X-Client-Request-Id", state.promptCacheKey)
headers.Set("Thread-Id", state.promptCacheKey)
headers.Set("X-Codex-Window-Id", state.promptCacheKey+":0")
@@ -1072,6 +1080,10 @@ func applyCodexHeaders(r *http.Request, auth *cliproxyauth.Auth, token string, s
cfgUserAgent, _ := codexHeaderDefaults(cfg, auth)
ensureHeaderWithConfigPrecedence(r.Header, ginHeaders, "User-Agent", cfgUserAgent, codexUserAgent)
if strings.Contains(r.Header.Get("User-Agent"), "Mac OS") {
misc.EnsureHeader(r.Header, ginHeaders, "Session_id", uuid.NewString())
}
if stream {
r.Header.Set("Accept", "text/event-stream")
} else {
@@ -1090,19 +1102,18 @@ func applyCodexHeaders(r *http.Request, auth *cliproxyauth.Auth, token string, s
} else if !isAPIKey {
r.Header.Set("Originator", codexOriginator)
}
// if !isAPIKey {
// if auth != nil && auth.Metadata != nil {
// if accountID, ok := auth.Metadata["account_id"].(string); ok {
// r.Header.Set("Chatgpt-Account-Id", accountID)
// }
// }
// }
if !isAPIKey {
if auth != nil && auth.Metadata != nil {
if accountID, ok := auth.Metadata["account_id"].(string); ok {
r.Header.Set("Chatgpt-Account-Id", accountID)
}
}
}
var attrs map[string]string
if auth != nil {
attrs = auth.Attributes
}
util.ApplyCustomHeadersFromAttrs(r, attrs)
deleteDeprecatedCodexConversationHeader(r.Header)
}
func newCodexStatusErr(statusCode int, body []byte) statusErr {