fix: reconcile session state after desktop reconnect - #71475
Conversation
9d43c23 to
e1f27d7
Compare
Related: #58109 also addresses Desktop reconnects, but it reconciles stale busy state across sessions; this patch reliably re-activates the selected routed session after a batched reconnect. The mechanisms are complementary, not duplicates. |
|
Thanks for isolating the reconnect path and covering the batched-state case. Problems
Suggested changes
Automated hermes-sweeper review. |
|
The still-relevant connection-epoch and dead-worker recovery behavior from this PR has been salvaged onto current main in #83166. Javier SM's original commits are preserved as authored; the superseded readiness-auth commit is intentionally excluded. This cross-link does not close or rewrite this PR. |
Superseded by #83166, which salvages this PR's still-relevant connection-epoch and dead-worker recovery behavior onto current main while preserving the original authorship. |
Superseded by the active salvage #83166, which carries this PR's still-relevant reconnect recovery work. |
Summary
session.activatepath to rebind the replacement transport and refresh authoritative messages/running staterunning/inflight_turnprojection when its prompt worker has already exitedRoot cause
If the WebSocket disconnected during a turn, the backend could finish and persist the assistant final while its transport was detached. A fast
closed -> connecting -> opencycle could be batched so the route hook rendered only the finalopenvalue and never ran selected-session reconciliation. Desktop could therefore keep showingThinkinguntil the user sent another message.The affected live session also exposed a dead prompt worker with
running=true, so an authoritative activation still reproduced the stale busy projection. The gateway now reconciles that impossible state before returning a live payload, while leaving live workers and the brief pre-registration window untouched.During live installation, current Desktop
mainalso found the deployed 0.18.2 remote throughTest remotebut failed bootstrap with401 no_cookie: readiness probing used the public/token fetch path instead of the authenticated Electron session. OAuth-gated readiness now uses that session for both/api/healthand the legacy/api/statusfallback.Tests
npm run test:ui -- src/app/session/hooks/use-route-resume.test.tsx src/app/session/hooks/use-session-actions.test.tsx(49 passed)npm run test:desktop:platforms -- electron/backend-health.test.ts(7 passed)scripts/run_tests.sh tests/test_tui_gateway_server.py -q -k session_activate(4 passed)ruff check tui_gateway/server.py tests/test_tui_gateway_server.pynpm run typechecknpm run lint -- --quietnpm run buildLive proof
Installed a clean local macOS build from
19656e12c5f4, started a harmless 10-second response, quit Desktop while it was running, waited for the detached backend to finish, and relaunched. Desktop displayedHERMES_RECONNECT_RECOVERY_OKand returned to an idle composer without a rescue message or stale Stop control.