fix(session): read Claude Code session id from its request header
Claude Code carries the session in metadata.user_id, which the Responses API translation drops before the executor resolves a cache session. The request then fell through to the assistant-text hash and the per-connection fallback, so one conversation was split across several prompt_cache_key values and the upstream prefix cache kept missing. Fall back to the x-claude-code-session-id header, which survives every translation. The body stays authoritative when both are present.
This commit is contained in:
@@ -94,6 +94,7 @@ const MAX_CONTINUATION_SESSIONS = 5000;
|
||||
// Client headers/body fields that carry an upstream session id (priority order)
|
||||
const SESSION_HEADER_KEYS = ["x-session-id", "session-id", "session_id", "x-amp-thread-id"];
|
||||
const CLAUDE_CODE_SESSION_RE = /_session_([a-f0-9-]+)$/;
|
||||
const CLAUDE_CODE_SESSION_HEADER = "x-claude-code-session-id";
|
||||
|
||||
function sha16(text) {
|
||||
return crypto.createHash("sha256").update(text).digest("hex").slice(0, 16);
|
||||
@@ -135,7 +136,10 @@ function extractAntigravitySession(body) {
|
||||
}
|
||||
|
||||
function extractClientSessionId(headers, body, scope = "") {
|
||||
const claude = extractClaudeCodeSession(body?.metadata?.user_id);
|
||||
// Claude Code sends the session in a header AND in metadata.user_id; the header
|
||||
// survives translation to formats that drop metadata (e.g. Responses API).
|
||||
const claude = extractClaudeCodeSession(body?.metadata?.user_id)
|
||||
|| headerValue(headers, CLAUDE_CODE_SESSION_HEADER);
|
||||
if (claude) return `claude:${claude}`;
|
||||
const antigravity = extractAntigravitySession(body);
|
||||
if (antigravity) return `antigravity:${antigravity}`;
|
||||
|
||||
Reference in New Issue
Block a user