feat(claw-server): close finished-agent tabs via reconciliation sweep - #2085
Merged
Conversation
Ending a session released its tab-ownership ledger but never closed the Chrome tabs the agent opened, so agent tabs accumulated. Only the tab group was ever closed by the server, and only after the long retention window and only when the tabs were grouped, so ungrouped tabs, popup children, crashes, and CDP disconnects all leaked tabs. Add a periodic reconciliation sweep that closes any tab which was agent-owned but now has no live owner, once a short configurable grace has elapsed. The predicate is derived from the durable ledger (a tab with history and no open row), so it cannot touch a user tab or a tab a live session still owns, and it catches popup children by construction. The sweep intersects with the browser's open tabs, so it only ever acts on tabs that still exist and is safe to run repeatedly, surviving crashes and disconnects. The foreground tab is spared and closed on a later pass once the user moves off it. Grace defaults to three minutes and is tunable via CLAW_TAB_CLEANUP_GRACE_MS.
Contributor
Greptile SummaryThe PR adds durable-ledger-based reconciliation that periodically closes released agent-owned tabs after a configurable grace period.
Confidence Score: 4/5The PR should not merge until the cleanup revalidates live ownership and foreground state immediately before closing each tab. The new destructive reconciliation acts on ownership and active-tab snapshots that can change during awaited work, allowing it to close a newly claimed agent tab or the tab a user has just activated. Files Needing Attention: packages/browseros-agent/apps/claw-server-rust/src/services/tab_cleanup.rs Important Files Changed
Sequence DiagramsequenceDiagram
participant Agent
participant Ledger
participant Sweep as Cleanup sweep
participant Browser
participant User
Sweep->>Ledger: Query released orphan tab IDs
Ledger-->>Sweep: Orphan snapshot
Agent->>Ledger: Enqueue a new live claim
Sweep->>Browser: List pages and active state
User->>Browser: Activate a candidate tab
Sweep->>Browser: Close page from stale snapshots
Note over Sweep,Browser: Ownership and active state are not revalidated
Prompt To Fix All With AI### Issue 1
packages/browseros-agent/apps/claw-server-rust/src/services/tab_cleanup.rs:72-76
**Stale ownership closes claimed tabs**
When a live session claims an orphaned tab after the ledger query but before the close, the sweep acts on the stale orphan snapshot and closes the newly owned tab, interrupting the running agent session.
### Issue 2
packages/browseros-agent/apps/claw-server-rust/src/services/tab_cleanup.rs:72-76
**Stale foreground state closes active tab**
When the user activates an orphaned tab after the page listing reports it inactive but before the close command, the sweep uses the stale active-state snapshot and closes the tab the user is viewing.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "feat(claw-server): close finished-agent ..." | Re-trigger Greptile |
Contributor
✅ Tests passed — 2543/2547
|
The cleanup sweep decided on an orphan snapshot and a page listing, then closed later, so between them a live session could reclaim a tab or the user could bring one to the foreground and the sweep would still close it. Re-check both the instant before each close: skip a tab that now has an open owner and skip the current foreground tab (read fresh via get_active). This shrinks the window to a negligible residual; CDP offers no atomic close-if-unowned-and-inactive, so a tiny irreducible gap remains by nature.
…n env var Drop CLAW_TAB_CLEANUP_GRACE_MS and the tab_cleanup_grace config field; the grace is a single sensible default (3 minutes) defined next to the sweep that uses it. One fewer knob to reason about, and the value lives where the behavior does.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Closes the browser tabs an agent opened once its session finishes. Ending a session already released the durable tab-ownership ledger, but nothing closed the actual Chrome tabs, so agent tabs accumulated over time. The only server-driven close was at the tab-group level, gated on the long retention window and on the tabs having been grouped, so ungrouped tabs, popup children, crashes, and CDP disconnects all leaked tabs.
How
A periodic reconciliation sweep closes any tab that was agent-owned but now has no live owner, once a short grace has elapsed.
CLAW_TAB_CLEANUP_GRACE_MS.Tests
tab_cleanup -> browserservice edge, with a guarding test.Notes
Legacy target-scoped claims (pre-tab-id ownership) are out of scope; the sweep operates on the current tab-id ownership model. On-reconnect cleanup is covered by the next periodic tick.