fix(aibridge): check x-session-affinity header for OpenCode sessions (#26140)

## Summary

`X-OpenCode-Session` is only set by the OpenCode "Zen" provider. Other
providers use `x-session-affinity` instead. This change falls back to
`x-session-affinity` when `X-OpenCode-Session` is not present, so
sessions are correctly identified regardless of the provider used.

Ref: https://github.com/coder/coder/pull/26128

## Changes

- `aibridge/session.go`: Prefer `X-OpenCode-Session` (Zen), fall back to
`x-session-affinity` (other providers).
- `aibridge/session_test.go`: Add tests for precedence and fallback
behavior.

> Generated with [Coder Agents](https://coder.com) by @dannykopping
This commit is contained in:
Danny Kopping
2026-06-08 17:44:13 +02:00
committed by GitHub
parent 3052089c4d
commit 8b5e1cac08
2 changed files with 18 additions and 1 deletions
+6 -1
View File
@@ -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:
+12
View File
@@ -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,