Skip to content

fix(server): detach a closed TUI tab's runtime - #4931

Open
PerryLink wants to merge 1 commit into
docker:mainfrom
PerryLink:fix/detach-closed-tui-tab-runtime
Open

PerryLink wants to merge 1 commit into
docker:mainfrom
PerryLink:fix/detach-closed-tui-tab-runtime

Conversation

@PerryLink

Copy link
Copy Markdown
Contributor

In --listen mode every TUI tab attaches its runtime to the serving session manager (AttachRuntime), but closing a tab only cancels the supervisor's session context: the session manager drops entries only on session deletion (DeleteSession → finishSessionDeletion), so per closed tab the runtime, the session, the attach context (context.WithCancel(context.WithoutCancel(ctx))), the follow-up injector closure and the recall handler all stay reachable for the process lifetime (#4909).

Fix

  • SessionManager.DetachRuntime(sessionID), symmetric with AttachRuntime: removes the runtime entry, cancels the attach context, clears the runtime's recall handler and drops the follow-up injector, key cache and the session's event log. The persisted session is untouched, and — unlike DeleteSession — the event log is not marked permanently deleted, so the session can be attached again (a reopened tab).
  • The TUI spawner's cleanup, which Supervisor.CloseSession already runs off the lock, now calls it, so closing a tab releases its runtime. recallCoordinatorOpt returns the detach function alongside the app option.

Tests

pkg/server/session_detach_test.go:

  • TestDetachRuntime_CleansUpAttachedState — after attach + injector + event source: the runtime entry is gone, the attach context is cancelled, the recall handler is cleared, the injector and event log are dropped; the stored session survives, and re-attaching works (the event log is not blacklisted the way deletion blacklists it).
  • TestDetachRuntime_UnknownSessionIsNoop.

go test ./pkg/server/ ./pkg/tui/service/supervisor/ ./cmd/root/ passes, and go vet ./pkg/server/ ./cmd/root/ is clean.

Closes #4909

Every TUI tab attaches its runtime and session to the session manager
(AttachRuntime), but closing a tab only cancelled the supervisor context:
the manager cleans up on session deletion, so in --listen mode each closed
tab leaked its runtime, session, attach context, follow-up injector and
recall handler for the process lifetime.

Add SessionManager.DetachRuntime, symmetric with AttachRuntime: remove the
entry, cancel the attach context, clear the recall handler and drop the
injector and event log, leaving the persisted session alone and attachable
again. The TUI spawner's cleanup, run by Supervisor.CloseSession, calls it.

Signed-off-by: PerryLink <novelnexusai@outlook.com>
@PerryLink
PerryLink requested a review from a team as a code owner November 14, 2026 01:54
@aheritier aheritier added area/runtime Runtime engine, agent loop execution, tool dispatch, loop detection kind/fix PR fixes a bug (maps to fix:). Use on PRs only. labels Nov 14, 2026

This branch has not been deployed

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

Labels

area/runtime Runtime engine, agent loop execution, tool dispatch, loop detection kind/fix PR fixes a bug (maps to fix:). Use on PRs only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Closing a TUI tab leaks its runtime, session and context in --listen mode

2 participants