Skip to content

fix(dashboard): key keep-alive PTY on resume+profile, not just tab token (#61284) - #61320

Closed
kyssta-exe wants to merge 1 commit into
NousResearch:mainfrom
kyssta-exe:fix/61284-pty-registry-key-session-switch
Closed

fix(dashboard): key keep-alive PTY on resume+profile, not just tab token (#61284)#61320
kyssta-exe wants to merge 1 commit into
NousResearch:mainfrom
kyssta-exe:fix/61284-pty-registry-key-session-switch

Conversation

@kyssta-exe

Copy link
Copy Markdown
Contributor

Summary

Fixes #61284 — Dashboard "Silent WebSocket" on Session Switch.

Root cause

The keep-alive PTY registry (PtySessionRegistry) was keyed only on the per-tab attach_token, which is stable across session switches. When the user selects a different chat session:

  1. The same attach_token is sent
  2. attach_or_spawn() finds the existing PTY running session A and reattaches
  3. The freshly-resolved argv carrying --resume B is never spawned
  4. The dashboard shows the previous session's terminal

The code=1005 / messages=1 log line in the issue is benign teardown of the superseded socket, not the root cause.

Fix

Fold resume (which session to resume) and profile into the registry key using NUL-byte concatenation:

  • Same attach_token + same resume → reattach (browser refresh preserves keep-alive)
  • Same attach_token + different resume → spawn new PTY (session switch)
  • profile is also included for the same latent bug with profile switching
registry_key = "\0".join((attach_token, resume or "", profile or ""))

The detach call is updated to use the same compound key.

Verification

  1. Open dashboard, switch between 3+ chat sessions — each switch should show the correct session's terminal
  2. Refresh the browser while viewing session B — keep-alive reattaches to session B
  3. The old session A's PTY lingers to the reaper TTL, so switching back reattaches to A's live agent
  4. Bounded by the existing max_sessions + reaper

When switching chat sessions in the dashboard, the PTY registry was keyed
only on the per-tab attach_token, which is stable across session switches.
attach_or_spawn() found the existing PTY from session A and reattached
instead of spawning a new PTY for session B.

Fix: fold resume and profile into the registry key so each distinct
session/profile combination gets its own PTY. Keep-alive is preserved:
- Same attach_token + same resume → reattach (browser refresh)
- Same attach_token + different resume → spawn new PTY (session switch)

Fixes NousResearch#61284
@kyssta-exe
kyssta-exe force-pushed the fix/61284-pty-registry-key-session-switch branch from 7a0f48e to 43ebb84 Compare July 9, 2026 06:22
@alt-glitch alt-glitch added type/bug Something isn't working comp/dashboard Web dashboard / control panel UI (dashboard/, landing) comp/cli CLI entry point, hermes_cli/, setup wizard sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state P2 Medium — degraded but workaround exists duplicate This issue or pull request already exists labels Jul 9, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #60745 — both are OPEN, both touch only hermes_cli/web_server.py, and both fix the same wrong-session PTY reattach bug (#61284) via the identical mechanism: fold resume + profile into the PTY registry key as a NUL(\0)-joined string so switching sessions spawns a distinct PTY instead of reusing the old one. This PR: registry_key = "\0".join((attach_token, resume or "", profile or "")); #60745: attach_token = f"{attach_token}\0{profile or ''}\0{resume or ''}". Byte-equivalent apart from cosmetics (variable name, profile/resume order). Canonical = earliest OPEN by createdAt: #60745 (2026-07-08) predates this PR (2026-07-09). Related: #61290 (closed same-mechanism backend twin), #61045/#61107 (frontend twins, ChatPage.tsx), #60515 (merged salvage that introduced the keep-alive regression). Maintainer should pick one backend fix.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused backend fix. The wrong-session premise is present on current main: hermes_cli/web_server.py:15452-15454 calls the registry with only attach_token, and hermes_cli/pty_session.py:151-153 returns an existing live PTY without spawning the newly resolved argv.

Problems

  • The new key derives from resume after the default-chat active-session fallback at hermes_cli/web_server.py:15405-15406. A first default-chat connection can use an empty resume key, while a refresh uses the persisted session ID and creates a second PTY rather than reattaching.
  • The PR adds no regression coverage beyond current main's same-token test in tests/test_pty_keepalive_ws.py:7-52.

Suggested changes

  • Capture the raw query resume before fallback and use that raw value, plus profile, for the registry identity.
  • Add resume-switch, profile-switch, and default-chat-after-fallback regression tests. Open PR #60745 (1a5680ca) already demonstrates that shape and coverage.

Automated hermes-sweeper review.

Comment thread hermes_cli/web_server.py
return

# Keep-alive path: the PTY outlives this socket; reattach by token.
# Key on attach_token + resume + profile so switching to a different

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the raw query resume captured before active-session-file fallback here. On default /chat, that fallback can change resume from empty to the persisted session ID between refreshes, causing this key to change and the live keep-alive PTY to be replaced.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 11, 2026
@kyssta-exe

Copy link
Copy Markdown
Contributor Author

Stale — no merge activity for 4-6 days. Can resubmit if still needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/profiles Multi-profile isolation, HERMES_HOME scoping comp/cli CLI entry point, hermes_cli/, setup wizard comp/dashboard Web dashboard / control panel UI (dashboard/, landing) duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Dashboard chat sessions fail to render due to recent WebSocket regression

3 participants