fix: resume sessions across client restarts instead of orphaning them#427
Merged
Conversation
When an AI agent (OpenCode, etc.) restarts, it regenerates its session header value (e.g. x-session-affinity nanoid). Previously, the gateway's Tier 1 identification treated this as a brand-new session, orphaning all prior distillations, gradient calibration, and cache warming state. Four coordinated fixes: 1. OpenCode plugin injects stable x-lore-session-id using OpenCode's persistent DB session ID (survives restarts). 2. Reorder KNOWN_SESSION_HEADERS so x-lore-session-id (always stable) is checked before volatile headers like x-session-affinity. 3. Add Tier 1a cross-header migration: when a new higher-priority header appears (plugin upgrade), check lower-priority headers for an existing session and re-index under the new header. 4. Add Tier 1b rotation detection in the gateway: when a known header name is present but its value is unrecognized, scan for exactly one recent non-subagent predecessor session with the same header name. If found, resume it instead of creating a new session. Also fixes: - Remove sessions.has() gate in Tier 1 so DB-only sessions (after gateway restart) are found without requiring in-memory hydration. - Treat lastTurnAt=0 as 'recently active' (gradient never ran yet) instead of infinitely stale in rotation candidate evaluation.
66a760b to
8574178
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When an AI agent (OpenCode, etc.) restarts, it regenerates its session header value (e.g.
x-session-affinitynanoid). The gateway's Tier 1 identification treated this as a brand-new session, orphaning all prior distillations, gradient calibration, and cache warming state. This caused cold starts, wasted tokens, and fragmented conversation logs.Changes
packages/opencode/src/index.ts): Injects stablex-lore-session-idusing OpenCode's persistent DB session ID (input.sessionID) which survives restartspackages/gateway/src/session.ts): ReordersKNOWN_SESSION_HEADERSsox-lore-session-id(always stable, deterministic) is checked before volatile headers likex-session-affinitypackages/gateway/src/pipeline.ts): When a new higher-priority header appears (e.g. plugin upgrade starts sendingx-lore-session-id), checks lower-priority headers for an existing session and re-indexes under the new header — prevents session orphaning on upgradepackages/gateway/src/pipeline.ts,session.ts): When a known header name is present but its value is unrecognized, scans for exactly one recent non-subagent predecessor session with the same header name. If found, resumes it. Extracted as a purefindRotationPredecessor()function for testabilitysessions.has()gate: DB-only sessions (after gateway restart) are now found via the header index without requiring in-memory hydration firstlastTurnAt=0false staleness: Sessions where gradient never ran are treated as recently active, not infinitely stalepackages/gateway/test/session.test.ts): Header priority, rotation happy path, concurrent sessions, sub-agent exclusion, stale session exclusion, boundary conditionsSafety Guards (Tier 1b)