[eric] WS resilience: per-session seq + ring buffer + resume protocol so agent runs survive transient disconnects (wifi flap, sleep, NAT

drop) instead of flipping to completed. Adds heartbeat (25s ping/10s pong), reconnect with infinite jittered backoff, outbound queue gated
   on resume_ack, gap_detected fallback for long offlines, on-disk persistence of terminal events for post-restart recovery, and a
  reconnecting connection state decoupled from session.status. 1089 backend tests covering 500 randomized disconnect scenarios + concurrent
  broadcast races. Backend/WS handler does not cancel agent task on disconnect
This commit is contained in:
ciregenz
2026-04-28 23:47:59 -04:00
parent 5d69215739
commit 9be2d87f73
7 changed files with 1215 additions and 27 deletions
+20
View File
@@ -83,6 +83,12 @@ export interface AgentSession {
mcp_suggestions_is_vague?: boolean;
active_outputs?: string[];
compacted_through_msg_id?: string | null;
// Transient frontend-only WS connection state. Independent of
// `status` (which describes the agent run itself). When the WS
// drops we set this to 'reconnecting' so the UI can render a
// subtle indicator without faking a terminal status. Cleared back
// to 'live' on resume_ack. Never persisted to the backend.
connection_state?: 'live' | 'reconnecting';
}
export interface AgentConfig {
@@ -602,6 +608,19 @@ const agentsSlice = createSlice({
}
},
setSessionConnState(
state,
action: PayloadAction<{ sessionId: string; state: 'live' | 'reconnecting' }>
) {
// Transient WS-layer indicator. Decoupled from session.status
// so a network blip never masquerades as a run terminating —
// status keeps reflecting the agent's actual lifecycle.
const session = state.sessions[action.payload.sessionId];
if (session) {
session.connection_state = action.payload.state;
}
},
addMessage(state, action: PayloadAction<{ sessionId: string; message: AgentMessage }>) {
const session = state.sessions[action.payload.sessionId];
if (session) {
@@ -1129,6 +1148,7 @@ export const {
setDraftSystemPrompt,
updateSession,
updateSessionStatus,
setSessionConnState,
addMessage,
streamStart,
streamDelta,