fix(desktop): rebind sessions after websocket reconnect (salvage of #41740) (#43004)

* fix(desktop): rebind sessions after websocket reconnect

* docs(desktop): explain the reconnect-resume guard in use-route-resume

The reconnect fix turns on two subtle conditions with no inline rationale:
`seenGatewayStateRef` suppresses a spurious "became open" on the first effect
run (so a session mounting with the gateway already open doesn't double-resume),
and the `gatewayBecameOpen ||` arm forces a re-resume even when the route looks
`alreadyActive` because the cached runtime id can be stale after the gateway
rebinds/reaps the session. Comment both so the next reader doesn't "simplify"
them back into the original bug. No behavior change.

---------

Co-authored-by: Josh Dow <josh.dow@prepad.io>
This commit is contained in:
brooklyn!
2026-06-09 19:01:00 +00:00
committed by GitHub
co-authored by Josh Dow
parent 46fedef07f
commit 8d71c38919
5 changed files with 126 additions and 3 deletions
+38
View File
@@ -613,6 +613,44 @@ def test_session_resume_live_payload_uses_current_history_with_ancestors(server,
]
def test_session_activate_rebinds_orphaned_ws_session_to_current_transport(server, monkeypatch):
"""Reconnect + activate must reattach a parked live session before orphan reap."""
class _Transport:
def write(self, _obj):
return True
sid = "runtime01"
old_transport = server._stdio_transport
new_transport = _Transport()
server._sessions[sid] = {
"agent": types.SimpleNamespace(model="test/model"),
"created_at": 123.0,
"history": [],
"history_lock": threading.RLock(),
"last_active": 123.0,
"running": False,
"session_key": "20260409_010101_abc123",
"transport": old_transport,
}
monkeypatch.setattr(server, "current_transport", lambda: new_transport)
monkeypatch.setattr(server, "_get_db", lambda: None)
monkeypatch.setattr(
server,
"_session_info",
lambda _agent, _session=None: {"model": "test/model"},
)
resp = server.handle_request(
{"id": "activate", "method": "session.activate", "params": {"session_id": sid}}
)
assert "error" not in resp
assert resp["result"]["session_id"] == sid
assert server._sessions[sid]["transport"] is new_transport
assert not server._ws_session_is_orphaned(server._sessions[sid])
def test_session_branch_persists_branched_from_marker(server, monkeypatch):
"""TUI /branch must persist a _branched_from marker so the branch stays
visible in /resume and /sessions.