MCPcopy Index your code
hub / github.com/coder/coder / GuessSessionID

Function GuessSessionID

aibridge/session.go:20–87  ·  view source on GitHub ↗

Legacy format: save compilation on each call. GuessSessionID attempts to retrieve a session ID which may have been sent by the client. We only attempt to retrieve sessions using methods recognized for the given client.

(client Client, r *http.Request)

Source from the content-addressed store, hash-verified

18// the client. We only attempt to retrieve sessions using methods recognized for
19// the given client.
20func GuessSessionID(client Client, r *http.Request) *string {
21 switch client {
22 case ClientClaudeCode:
23 // Prefer the dedicated header (added in Claude Code v2.1.86+).
24 if sid := cleanRef(r.Header.Get("X-Claude-Code-Session-Id")); sid != nil {
25 return sid
26 }
27
28 // Fall back to extracting from the metadata.user_id field in the JSON body.
29 // Newer format: JSON-encoded object with a "session_id" field.
30 // Legacy format: "user_{sha256}_account_{id}_session_{uuid}"
31 payload, err := io.ReadAll(r.Body)
32 if err != nil {
33 return nil
34 }
35 _ = r.Body.Close()
36
37 // Restore the request body.
38 r.Body = io.NopCloser(bytes.NewReader(payload))
39 userID := gjson.GetBytes(payload, "metadata.user_id")
40 if userID.Type != gjson.String {
41 return nil
42 }
43
44 raw := userID.String()
45
46 // Newer body format: user_id is a JSON-encoded object with a session_id field.
47 if sessionID := gjson.Get(raw, "session_id"); sessionID.Exists() {
48 return cleanRef(sessionID.String())
49 }
50
51 // Legacy body format: "user_{sha256}_account_{id}_session_{uuid}"
52 matches := claudeCodePattern.FindStringSubmatch(raw)
53 if len(matches) < 2 {
54 return nil
55 }
56 return cleanRef(matches[1])
57 case ClientCodex:
58 return cleanRef(r.Header.Get("session_id"))
59 case ClientMux:
60 return cleanRef(r.Header.Get("X-Mux-Workspace-Id"))
61 case ClientZed:
62 return nil // Zed does not send a session ID from Zed Agent or Text Thread.
63 case ClientCopilotVSC:
64 // This does not map precisely to what we consider a session, but it's close enough.
65 // Most other providers' equivalent of this would persist for the duration of a
66 // conversation; it does seem to persist across an agentic loop though, which is
67 // all we really need.
68 //
69 // There's also `vscode-sessionid` but that's persistent for the duration of the
70 // VS Code window.
71 return cleanRef(r.Header.Get("x-interaction-id"))
72 case ClientCopilotCLI:
73 return cleanRef(r.Header.Get("X-Client-Session-Id"))
74 case ClientKilo:
75 return cleanRef(r.Header.Get("X-KILOCODE-TASKID"))
76 case ClientCoderAgents:
77 return cleanRef(r.Header.Get("X-Coder-Chat-Id"))

Callers 3

TestGuessSessionIDFunction · 0.92
TestUnreadableBodyFunction · 0.92
newInterceptionProcessorFunction · 0.85

Calls 6

cleanRefFunction · 0.85
GetMethod · 0.65
CloseMethod · 0.65
ReadAllMethod · 0.45
StringMethod · 0.45
ExistsMethod · 0.45

Tested by 2

TestGuessSessionIDFunction · 0.74
TestUnreadableBodyFunction · 0.74