Skip to content

Expands session affinity ID extraction sources#2899

Open
can1357 wants to merge 1 commit intorouter-for-me:devfrom
can1357:dev
Open

Expands session affinity ID extraction sources#2899
can1357 wants to merge 1 commit intorouter-for-me:devfrom
can1357:dev

Conversation

@can1357
Copy link
Copy Markdown
Contributor

@can1357 can1357 commented Apr 19, 2026

Broadens the set of identifiers used to maintain session affinity, improving compatibility with a wider range of clients (e.g., OpenAI Codex).

  • Checks additional headers (X-Client-Request-Id, Session-Id, Conversation-Id) alongside X-Session-ID when extracting a session identifier
  • Adds support for the prompt_cache_key body field as a session source, which Codex stamps with a session ID

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6229351321

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if headers != nil {
if sid := headers.Get("X-Session-ID"); sid != "" {
return "header:" + sid, ""
for _, h := range []string{"X-Session-ID", "X-Client-Request-Id", "Session-Id", "Conversation-Id"} {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle Session_id header for session affinity

extractSessionIDs now looks for Session-Id/Conversation-Id, but other Codex-facing code in this repo uses underscore-style headers (for example Session_id in sdk/api/handlers/openai/openai_responses_websocket_toolcall_repair.go:150). In Go, header lookup is case-insensitive but does not normalize _ to -, so requests carrying Session_id will still miss this new header path and fall back to body/hash extraction, which can break sticky auth selection for requests without stable body session fields.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request expands the session ID extraction logic to support additional headers (X-Client-Request-Id, Session-Id, Conversation-Id) and the prompt_cache_key body field. Feedback was provided to align documentation comments with the actual kebab-case header names and to unroll the header check loop to prevent unnecessary allocations in high-traffic request paths.

// Priority for session ID extraction:
// 1. metadata.user_id (Claude Code format) - highest priority
// 2. X-Session-ID header
// 2. X-Session-ID / X-Client-Request-Id / session_id / conversation_id headers
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.

medium

The comment uses snake_case for session_id and conversation_id, but the implementation (and standard HTTP header naming) uses kebab-case (Session-Id, Conversation-Id). This can be misleading for developers trying to understand which headers are actually supported.

Suggested change
// 2. X-Session-ID / X-Client-Request-Id / session_id / conversation_id headers
// 2. X-Session-ID / X-Client-Request-Id / Session-Id / Conversation-Id headers

// Priority order:
// 1. metadata.user_id (Claude Code format with _session_{uuid}) - highest priority for Claude Code clients
// 2. X-Session-ID header
// 2. X-Session-ID / X-Client-Request-Id / session_id / conversation_id headers
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.

medium

The comment uses snake_case for session_id and conversation_id, but the implementation uses kebab-case. Updating this to match the actual header keys improves clarity.

Suggested change
// 2. X-Session-ID / X-Client-Request-Id / session_id / conversation_id headers
// 2. X-Session-ID / X-Client-Request-Id / Session-Id / Conversation-Id headers

Comment on lines +604 to 611
// 2. X-Session-ID / X-Client-Request-ID / session_id / conversation_id headers
if headers != nil {
if sid := headers.Get("X-Session-ID"); sid != "" {
return "header:" + sid, ""
for _, h := range []string{"X-Session-ID", "X-Client-Request-Id", "Session-Id", "Conversation-Id"} {
if sid := headers.Get(h); sid != "" {
return "header:" + sid, ""
}
}
}
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.

medium

Creating a new slice of strings on every call to extractSessionIDs causes unnecessary allocations in a high-traffic request path. Unrolling the header checks is more efficient and avoids these allocations. Additionally, the comment has been updated to match the kebab-case naming used in the code.

Suggested change
// 2. X-Session-ID / X-Client-Request-ID / session_id / conversation_id headers
if headers != nil {
if sid := headers.Get("X-Session-ID"); sid != "" {
return "header:" + sid, ""
for _, h := range []string{"X-Session-ID", "X-Client-Request-Id", "Session-Id", "Conversation-Id"} {
if sid := headers.Get(h); sid != "" {
return "header:" + sid, ""
}
}
}
// 2. X-Session-ID / X-Client-Request-Id / Session-Id / Conversation-Id headers
if headers != nil {
if sid := headers.Get("X-Session-ID"); sid != "" {
return "header:" + sid, ""
}
if sid := headers.Get("X-Client-Request-Id"); sid != "" {
return "header:" + sid, ""
}
if sid := headers.Get("Session-Id"); sid != "" {
return "header:" + sid, ""
}
if sid := headers.Get("Conversation-Id"); sid != "" {
return "header:" + sid, ""
}
}

- Updated session ID extraction to consider additional request headers, including X-Client-Request-Id, Session-Id, and Conversation-Id.
- Added fallback parsing for the prompt_cache_key body field as a conversation/session identifier source.
- Adjusted the in-code priority comments to reflect the expanded header and body-based identifier sources.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d78530a402

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if headers != nil {
if sid := headers.Get("X-Session-ID"); sid != "" {
return "header:" + sid, ""
for _, h := range []string{"X-Session-ID", "X-Client-Request-Id", "Session-Id", "Conversation-Id"} {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle Conversation_id header alias

The new header extraction list includes Conversation-Id but not Conversation_id, while the Codex websocket path sets Conversation_id (internal/runtime/executor/codex_websockets_executor.go:805). In Go, _ and - are not interchangeable for header lookup, so these requests will still miss the intended header-based affinity path and fall back to body/hash IDs, which keeps session stickiness inconsistent for this flow.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant