Skip to content

emrg: switching sessions is not refused while a stream runs - #2641

Closed
pm25coder wants to merge 1 commit into
masterfrom
fix/gui-switch-any-time
Closed

pm25coder wants to merge 1 commit into
masterfrom
fix/gui-switch-any-time

Conversation

@pm25coder

Copy link
Copy Markdown
Collaborator

Closes #2637

The GUI's emrg:switchSession refused to switch while the session being left still had a
turn streaming: the handler threw stream in progress — cannot switch whenever
connManager.get(currentSessionId).ownStream was set. Nothing switched, and the turn kept
running anyway — the refusal cost the navigation and saved nothing.

That check dates from when switching a session closed the old connection: ConnManager.close()
cancels a busy connection before dropping its socket, so letting a switch through would have
killed the running turn. Switching no longer closes anything — it opens or reuses the target
session's own connection and leaves the previous one alone (main.js:625); closing is
emrg:closeSession's job. Each session has its own websocket and transcript bucket, so the
guard had nothing left to protect.

What changed

  • emrg/gui/main.js — the ownStream refusal is gone from the switch handler. The other
    refusals on that path (invalid session_id, invalid agent path, the 20-open-session cap) are
    untouched, and the G65 lock itself stays: conn.sendTask still marks it (:430) and releases
    it on failure (:434), and close()/cancel still use it.
  • emrg/gui/renderer/src/components/Shell.tsx — selectProjectSession (the sidebar path)
    had no catch, so every refusal on this path — the cap, an invalid id — became an unhandled
    promise rejection: no visible change at all, and setActiveSid never ran. It now reports the
    failure the way the task panel already does and leaves the view where it is. The task panel's
    own catch is unchanged.
  • emrg/gui/test/boot-contract.test.js — one regression test holding both halves: the
    switch handler no longer consults ownStream, and its other two refusals still stand.
  • Agent.md — the GUI totals move 168 → 169, with boot-contract 11 → 12 in the breakdown.

How it was verified

  • The test is red before the fix and green after — added first, run against the unchanged
    handler: # tests 12 / # pass 11 / # fail 1, failing on the new test and nothing else.
  • Mutant arm: with the refusal put back as a one-line mutant, the same test is the one that
    fails (not ok 12), then passes again once removed — so it catches the real thing rather than
    a shape near it.
  • The predicate is pinned in both directions, because the new comment in main.js names the
    lock: a comment mentioning ownStream must stay silent, a real read of it must be caught.
    Without that arm the assertion would have been red on its own explanatory comment.
  • cd emrg/gui && npm test — 170 tests, 161 pass, 0 fail, 9 skipped (169 before this change).
  • cd emrg/gui/renderer && npm run typecheck && npm test — typecheck clean, 740 tests passing.
  • uv run pytest tests/ -q — 5510 passed, 518 skipped.
  • uv run --no-sync python3 scripts/check-node-test-count.py — OK, 740 renderer + 169 GUI, both
    runners agree; tests/test_doc_counts.py — 82 passed.

CI is pending on this head; nothing here is reported as green.

@pm25coder

Copy link
Copy Markdown
Collaborator Author

Superseded by #2640 — folded into it rather than left competing.

Both PRs remove the same refusal from emrg:switchSession, for the same reason: the guard
came from a design in which switching closed the previous connection, and switching no longer
closes anything. #2640 is the better answer to the half this one got wrong. The issue asks that
a refusal be visible where the user acted; this PR answered that by writing the message into
the current session's transcript — the very defect the issue describes for the task panel, where
the user is looking at the task list and never sees it. #2640 puts a role="alert" banner on the
panel the user is standing on, covers both callers, pins the fact that the switch must not close
the connection it leaves, and carries renderer tests for the visibility path.

It also opened first (#2640 at 08:57Z, this one at 09:05Z), so there is no first-come argument for
keeping mine either.

One issue is finished by one PR, and #2637 now reads as a duplicate while both are open. Nothing
here is being re-opened as a third attempt.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

emrg: the GUI refuses to switch sessions while the current one is streaming

1 participant