agent host: hydrate snapshot controller for Restore Checkpoint#319051
Merged
Conversation
Currently the AgentHostSnapshotController never has any checkpoints to restore to when "Restore Checkpoint" is invoked, so the removed request stays visible in the chat UI. This fix wires up hydration end-to-end and simplifies the controller's bookkeeping along the way. - Seed a request-level checkpoint for every historical turn on session open, not only turns with file edits. Without this, restoreSnapshot for any turn that lacked tool calls fell through with "No checkpoint found" and _setDisabledRequests was never called. - Always populate _pendingHistoryTurns from the protocol state (previously gated on hasTurnsWithEdits), and stop using Event.once on onDidCreateModel to wait for the chat model — the once subscription was being consumed by an unrelated model created first, leaving the controller un-hydrated. Now we synchronously hydrate when the model already exists, otherwise listen until the matching session arrives. - Make ensureRequestCheckpoint advance _currentCheckpointIndex to the new checkpoint. Previously the cursor stayed put, so requestDisablement marked the in-flight request as disabled (the new checkpoint sat "forward" of the cursor) and the next call would splice it away. - Simplify to one checkpoint per request. Multiple tool calls in the same request now fold their edits into a single checkpoint via a seenToolCallIds Set, and restoreSnapshot/getSnapshotUri/ getSnapshotContents ignore the stopId parameter. canUndo/canRedo derive purely from cursor position — undo/redo is request-level, available whenever any checkpoint exists. - Add tests covering: in-flight request isn't disabled, restore of a no-edit request marks it disabled, stale forward branch is spliced on new request after restore-to-start, and multi-tool-call edits undo together. Fixes #318251 (Commit message generated by Copilot)
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes “Restore Checkpoint” for agent-host chat sessions by ensuring snapshot state is properly hydrated from protocol history and by simplifying checkpoint tracking to request-level undo/redo, so restored (removed) requests are correctly hidden in the UI.
Changes:
- Seed request-level checkpoints for all historical turns (including no-edit turns) and hydrate them when the chat model becomes available.
- Simplify snapshot bookkeeping to one checkpoint per request and fold tool-call edits into that checkpoint.
- Add/extend tests for no-edit restore behavior, forward-branch splicing, and multi-tool-call undo.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/chat/test/browser/agentHost/agentHostSnapshotController.test.ts | Adds coverage for request-level checkpoint semantics, no-edit restores, branch splicing, and multi-tool-call undo. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSnapshotController.ts | Switches to one checkpoint per request, adjusts disablement/undo semantics, and updates snapshot URI/content behavior. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionHandler.ts | Stores all historical turns for hydration and fixes eager snapshot-controller creation so hydration reliably occurs for the correct session. |
Copilot's findings
- Files reviewed: 3/3 changed files
- Comments generated: 3
roblourens
previously approved these changes
May 29, 2026
- Fold multiple tool-call edits to the same file in one request into a single net before/after pair (mergeFileEdit). Without this, _writeCheckpointContent applied duplicate writes in parallel and raced. - Refresh stale 'sentinel' wording in session handler comments. (Commit message generated by Copilot)
Yoyokrazy
approved these changes
May 29, 2026
eleanorjboyd
approved these changes
May 29, 2026
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.
agent host: hydrate snapshot controller for Restore CheckpointCurrently the AgentHostSnapshotController never has any checkpoints torestore to when "Restore Checkpoint" is invoked, so the removed requeststays visible in the chat UI. This fix wires up hydration end-to-end andsimplifies the controller's bookkeeping along the way.- Seed a request-level checkpoint for every historical turn on session open, not only turns with file edits. Without this, restoreSnapshot for any turn that lacked tool calls fell through with "No checkpoint found" and _setDisabledRequests was never called.- Always populate _pendingHistoryTurns from the protocol state (previously gated on hasTurnsWithEdits), and stop using Event.once on onDidCreateModel to wait for the chat model ΓÇö the once subscription was being consumed by an unrelated model created first, leaving the controller un-hydrated. Now we synchronously hydrate when the model already exists, otherwise listen until the matching session arrives.- Make ensureRequestCheckpoint advance _currentCheckpointIndex to the new checkpoint. Previously the cursor stayed put, so requestDisablement marked the in-flight request as disabled (the new checkpoint sat "forward" of the cursor) and the next call would splice it away.- Simplify to one checkpoint per request. Multiple tool calls in the same request now fold their edits into a single checkpoint via a seenToolCallIds Set, and restoreSnapshot/getSnapshotUri/ getSnapshotContents ignore the stopId parameter. canUndo/canRedo derive purely from cursor position ΓÇö undo/redo is request-level, available whenever any checkpoint exists.- Add tests covering: in-flight request isn't disabled, restore of a no-edit request marks it disabled, stale forward branch is spliced on new request after restore-to-start, and multi-tool-call edits undo together.Fixes #318251 message generated by Copilot)