From 5d729b20e219caeeb10430a6e229559317d94b09 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Mon, 8 Jun 2026 14:38:09 +0000 Subject: [PATCH] fix(aibridge): check x-session-affinity header for OpenCode sessions X-OpenCode-Session is only set by the OpenCode "Zen" provider. Other providers use x-session-affinity instead. Fall back to x-session-affinity when X-OpenCode-Session is not present. --- aibridge/session.go | 7 ++++++- aibridge/session_test.go | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/aibridge/session.go b/aibridge/session.go index 759a2e69f1ecd..9882029ea396a 100644 --- a/aibridge/session.go +++ b/aibridge/session.go @@ -76,7 +76,12 @@ func GuessSessionID(client Client, r *http.Request) *string { case ClientCoderAgents: return cleanRef(r.Header.Get("X-Coder-Chat-Id")) case ClientOpenCode: - return cleanRef(r.Header.Get("X-OpenCode-Session")) + // Prefer X-OpenCode-Session (set by the OpenCode "Zen" provider). + if sid := cleanRef(r.Header.Get("X-OpenCode-Session")); sid != nil { + return sid + } + // Fall back to x-session-affinity (set by other providers). + return cleanRef(r.Header.Get("x-session-affinity")) case ClientCrush: return nil // Crush does not send a session ID header. case ClientRoo: diff --git a/aibridge/session_test.go b/aibridge/session_test.go index f1fb7614f4cb4..24d72d57a39ea 100644 --- a/aibridge/session_test.go +++ b/aibridge/session_test.go @@ -195,6 +195,18 @@ func TestGuessSessionID(t *testing.T) { headers: map[string]string{"X-OpenCode-Session": " ses_15a48edefffe7oY0YcIHRv29dD "}, sessionID: utils.PtrTo("ses_15a48edefffe7oY0YcIHRv29dD"), }, + { + name: "opencode_zen_header_takes_precedence_over_session_affinity", + client: aibridge.ClientOpenCode, + headers: map[string]string{"X-OpenCode-Session": "zen-session", "x-session-affinity": "other-session"}, + sessionID: utils.PtrTo("zen-session"), + }, + { + name: "opencode_session_affinity_fallback", + client: aibridge.ClientOpenCode, + headers: map[string]string{"x-session-affinity": "affinity-session-123"}, + sessionID: utils.PtrTo("affinity-session-123"), + }, { name: "opencode_without_session_header", client: aibridge.ClientOpenCode,