From d0e73ff30ce2defd9f0458338ce62fab66967e6b Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Sun, 2 Aug 2026 14:59:15 -0700 Subject: [PATCH] fix(tui_gateway): widen reaper delegate keepalive to durable session_key Unify @null-runner's selector approach with the merged #77019 keepalive: the reapers now match live delegations by origin UI sid AND (when the TUI owns the durable lifecycle, never for gateway-viewer tabs, #60609) by the durable session_key, so a delegation dispatched from an earlier tab of the same resumed session still keeps it alive. has_live_for_session also counts 'stalling' to match the #77019 live-state set. Explicit teardown (_finalize_session) interrupt semantics unchanged. --- tui_gateway/server.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tui_gateway/server.py b/tui_gateway/server.py index 1a3cbd19976cd..d637fb2f3c1fc 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -761,11 +761,18 @@ def _finalize_session(session: dict | None, end_reason: str = "tui_close") -> No try: from tools.async_delegation import interrupt_for_session - _own_sid, _owned_session_key = _session_async_delegation_selectors( - session, sid_hint=str(session.get("_sid") or "") - ) + _own_sid = str(session.get("_sid") or "") + if not _own_sid: + try: + with _sessions_lock: + for _cand_sid, _cand in _sessions.items(): + if _cand is session: + _own_sid = _cand_sid + break + except Exception: + _own_sid = "" interrupt_for_session( - session_key=_owned_session_key, + session_key=str(session_key or "") if _tui_owns_lifecycle else "", origin_ui_session_id=_own_sid, reason=end_reason, )