feat: a Snapshots page, and a checkpoint listing that pages, searches and sorts - #2798
Draft
Charlesthebird wants to merge 1 commit into
Draft
feat: a Snapshots page, and a checkpoint listing that pages, searches and sorts#2798Charlesthebird wants to merge 1 commit into
Charlesthebird wants to merge 1 commit into
Conversation
… and sorts Closes #2783. A checkpoint pins a copy of the conversation's runtime in the substrate. They were reachable only from inside the conversation they belong to and could not be removed at all, while duplicating a chat takes one every time — so a cluster accumulated snapshots nobody had asked for and nobody could find. The page lists them, searches them, and deletes them singly or in a batch. A batch is one request each, sequential, under one `toast.promise`; a failure does not stop the run, each is logged, and the toast says how it went. `ListCheckpoints` does the narrowing: it takes a filter, a sort column and an offset, answers with the count the filter matched, and `agent_instance_id` became optional so one request spans a caller's conversations. Reading everything into the browser and filtering there reports "no matches" about rows it never fetched. Rows are named, searched and sorted by the conversation's name as recorded when the snapshot was taken — the only name a query can reach, since the current one lives inside an encoded payload. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Nicholas Bucher <behappy54321@gmail.com>
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.
🤖 written by Claude (start)
Stacked on #2775, which adds the chat side. Closes #2783.
A checkpoint pins a copy of the conversation's runtime in the substrate. They were reachable only from inside the conversation they belong to and could not be removed at all, while duplicating a chat takes one every time — so a cluster accumulated snapshots nobody had asked for and nobody could find.
The page
Lists every snapshot the reader holds, searches them, and deletes them singly or in a batch. A batch is one request each, sequential, under one
toast.promise; a failure does not stop the run, each is logged, and the toast says how it went rather than claiming success over a partial one.Deleting can refuse: the controller will not remove a snapshot while a chat forked from it still exists, and reports that as
NotFound. The page states the condition rather than guessing at it per failure.The listing
ListCheckpointstakes a filter, a sort column and an offset, and answers with the count the filter matched.agent_instance_idbecame optional so one request spans a caller's conversations rather than one per conversation. Reading everything into the browser and narrowing it there reports "no matches" about rows it never fetched.Rows are named, searched and sorted by the conversation's name as recorded when the snapshot was taken — the only name a query can reach, since the current one lives inside an encoded payload. A rename leaves earlier rows reading as they did.
In the store that is one statement:
count(*) OVER ()carries the total, and the ordering is passed as parameters rather than concatenated in, so it stays preparable byTestInlineSQLPreparesand there is noORDER BYto inject into.Not here: the index the listing wants,
(user_id, state, id DESC). Migration files are immutable once merged, so it needs its own; without it a listing is a sequential scan. Tracked in #2783.Testing
ENABLE_MOCK_UI=true yarn dev, open a conversation and press Checkpoint beside Send a couple of times.Reels against a real cluster are in the comments.
🤖 written by Claude (end)