fix: harden resume and SSE replay
This commit is contained in:
@@ -100,22 +100,29 @@ export function AppShell() {
|
||||
});
|
||||
}
|
||||
async function doResume(id: string) {
|
||||
const s = sessions.find((x) => x.id === id) ?? null;
|
||||
const reconnectSameSession = activeSessionId === id;
|
||||
// Optimistic switch: change to the session view IMMEDIATELY so the click feels
|
||||
// instant (the resume POST spawns a Pi process and can take seconds). The
|
||||
// working spinner shows straight away; the backend calls run after.
|
||||
setPanelSession(null);
|
||||
resetSession();
|
||||
recordLifecycle("Resuming session");
|
||||
setAwaitingQuestion(false);
|
||||
// Optimistic: the resume POST is about to hand the ball to the harness.
|
||||
setAgentActive(true);
|
||||
setActiveSessionId(id);
|
||||
try {
|
||||
await resumeSession(id);
|
||||
if (reconnectSameSession) setStreamGeneration((value) => value + 1);
|
||||
// Optimistic phase paint: colour the re-entry phase before the first gate.
|
||||
const result = await resumeSession(id);
|
||||
setPanelSession(null);
|
||||
setAwaitingQuestion(false);
|
||||
|
||||
// A running/waiting runtime for the currently selected session is already bound to this
|
||||
// store and EventSource. Reopening it would replay state and can lose in-flight delivery.
|
||||
if (result.alreadyActive && reconnectSameSession) return;
|
||||
|
||||
resetSession();
|
||||
if (!result.alreadyActive) {
|
||||
recordLifecycle("Resuming session");
|
||||
setAgentActive(true);
|
||||
}
|
||||
setActiveSessionId(id);
|
||||
// The backend has now completed clear/rebind. Recreate a same-id source with its cursor;
|
||||
// switching ids naturally creates a new source and resets the cursor in the stream hook.
|
||||
if (!result.alreadyActive && reconnectSameSession) {
|
||||
setStreamGeneration((value) => value + 1);
|
||||
}
|
||||
|
||||
// Paint the persisted re-entry phase while the replacement stream starts replaying.
|
||||
// The manifest's `phase` is the 1-based current phase (1..8).
|
||||
try {
|
||||
const m = (await getSession(id)) as { phase?: number };
|
||||
@@ -126,10 +133,6 @@ export function AppShell() {
|
||||
/* non-fatal: the first gate will set the phase */
|
||||
}
|
||||
} catch {
|
||||
// Revert the optimistic switch and restore the panel.
|
||||
resetSession();
|
||||
setActiveSessionId(null);
|
||||
if (s) setPanelSession(s);
|
||||
toast.error("Failed to resume session.");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user