Repository navigation
[feat] Close other session tabs, or the ones to the right [AGE-4188] - #6330
ashrafchowdury merged 3 commits into
Conversation
The tab strip had one close affordance: the × on a single tab. Clearing a strip that had grown long meant clicking × over and over. A tab's context menu now carries Chrome's bulk closes — Close, Close other tabs, Close tabs to the right — each disabled when it would do nothing. Pinned tabs survive "close other tabs", as they do in a browser. Since pins lead the strip they are never to the right of anything, so the carve-out only shows up in that one verb. The strip computes the ids because "to the right" means the RENDERED order, which is pin-sorted and only the strip knows. `closeSessionsAtomFamily` then applies the whole set in one write, with the same rules a single close has: sessions stay in history and stay reopenable, never-run husks are discarded, and the active tab moves to the nearest survivor. Closing a running tab still cancels its run.
…connect Reopening a long session was slow, and got slow again every time you came back to the tab. The watch relay emits `ready` on every connect, and the relay connects on each tab activation and each return to a foreground window. `ready` was wired to the same handler as `records-changed`, so each of those invalidated the records query and re-read the entire log — a ~200KB fetch at `priority: "low"`, a full remap, and a `setMessages` that replaces the transcript and re-renders every row. On reopen that ran right beside the mount's own revalidation, so the log was read twice within a second. `ready` now has its own handler that skips a read the mount is already doing, or one that finished within the relay's own coalescing window. The skip is safe because of what `ready` is for. A change can land after the response headers flush but before the Redis subscribe completes, reaching neither the stream nor a revalidation driven by `onopen` — `ready` closes that window. A read of the log newer than the connection cannot have missed such a change, so repeating it buys nothing. A change after the subscribe arrives as `records-changed`, which is never skipped; that is why the two events needed separating rather than sharing a deduped handler. Every full read now reports itself, so "nobody has read this" and "a read is running right now" are distinguishable — the second is the reopen case, where the mount's revalidation is still in flight when `ready` lands.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Only conflict was the mobile TurnRow import block: release added CollapsibleMessageBody to the @agenta/chat/components import while this branch added the @agenta/chat/hooks import beside it. Kept both. Merged rather than rebased because four PRs (#6328, #6329, #6330, #6331) are stacked on this branch, so rewriting its history would break their bases.
[fix] Stop re-reading a session's record log on every connect [AGE-4189]
14ae06f
into
fix/session-tab-close-cancels-run
Railway Preview Environment
|
Context
The tab strip has one close affordance, the X on a single tab. Clearing a long strip means clicking X over and over.
Changes
A tab's context menu now carries the same bulk closes a browser has: Close, Close other tabs, Close tabs to the right. Each one is disabled when it would do nothing.
Pinned tabs survive "Close other tabs", the way they survive it in Chrome. Pins lead the strip, so they are never to the right of anything, and the carve-out only shows up in that one verb.
The strip computes the ids because "to the right" means the rendered order, which is pin-sorted and only the strip knows.
closeSessionsAtomFamilythen applies the whole set in one write, with the same rules a single close has. Sessions stay in history and stay reopenable, never-run blanks are discarded, and the active tab moves to the nearest survivor. Closing a running tab still cancels its run.Tests
sessions.bulkClose.test.tscovers the one-write close, history retention, the active tab surviving, the active tab moving right and then falling back left, empty and unknown id sets, and blank-session cleanup.tsc --noEmitand eslint clean on@agenta/oss.Demo
Outstanding. This adds a visible menu, so it needs a capture from the real app running this branch. I have not run the stack, and a mock-up would not show the real menu, theme, or spacing.
What to QA
Notes for the reviewer
closeSessionsAtomFamilyis a new close path. #5862 requires every close path to remove the id fromopenIdsByAppAtombefore React runs the cleanup, and this one does, since that write comes first. If #5862 lands before this, the new atom also needs itsdropSessionRuntime(set, id)call, otherwise a bulk close leaks one chat instance and one stale status dot per tab. It merges clean without it, so nothing will flag it.