src/vs/platform/agentHost/common/agentHostCheckpointService.ts

114 LOC · 112 covered · 2 uncovered · 2 ranges · 1462 concepts · 1 introducers · 677 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- agentHostCheckpointService.ts ×2
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { URI } from '../../../base/common/uri.js';
7 > import { createDecorator } from '../../instantiation/common/instantiation.js';
8 >
9 > export const IAgentHostCheckpointService = createDecorator<IAgentHostCheckpointService>('agentHostCheckpointService');
10 >
11 > /**
12 > * `session_metadata` key under which the per-session baseline (turn/0)
13 > * checkpoint ref is stored.
14 > */
15 > export const META_CHECKPOINT_BASE_REF = 'checkpoint.baseRef';
16 >
17 > /**
18 > * Returns the canonical name for a per-turn checkpoint ref.
19 > * Distinct from the chat extension's `refs/sessions/...` so the two can
20 > * coexist safely in the same repository.
21 > */
22 > export function buildCheckpointRefName(sanitizedSessionId: string, turnNumber: number): string {
23 return `refs/agents/${sanitizedSessionId}/checkpoints/turn/${turnNumber}`;
24 }
26 > /**
27 > * Captures per-turn git **checkpoint refs** for Agent Host sessions so
28 > * end-of-turn diffs reflect the entire working-tree delta (including
29 > * terminal-tool edits that are invisible to the FileEditTracker pipeline).
30 > *
31 > * Each checkpoint is a parentless or parent-chained commit (commit-tree)
32 > * pointing at a tree captured via the temp-index trick, anchored under
33 > * `refs/agents/<sid>/checkpoints/turn/<N>`. The session-private ref
34 > * namespace means the commits stay reachable for the lifetime of the
35 > * session and survive process restarts (refs live on disk in
36 > * `<repo>/.git/refs/`), while never appearing as branches/tags to the
37 > * user. Cleanup is driven by `ISessionDataService.onWillDeleteSessionData`
38 > * — the service deletes every ref it created for the destroyed session
39 > * before the data directory is removed.
40 > */
41 > export interface IAgentHostCheckpointService {
42 > readonly _serviceBrand: undefined;
43 >
44 > /**
45 > * Captures the session's baseline (turn/0) checkpoint. Idempotent: if
46 > * a baseline already exists for the session, returns the existing ref.
47 > * Returns `undefined` when the working directory is not a git work tree
48 > * (folder-isolation against a non-git folder) or when checkpoint
49 > * capture fails.
50 > *
51 > * Called once per session, immediately after the session's working
52 > * directory has been resolved and any worktree metadata has been
53 > * persisted (e.g. `CopilotAgent._materializeProvisional`).
54 > */
55 > captureBaseline(sessionUri: URI, workingDirectory: URI | undefined): Promise<string | undefined>;
56 >
57 > /**
58 > * Captures an end-of-turn checkpoint, chained to the previous turn's
59 > * checkpoint (or the baseline for turn 1). Persists the ref against
60 > * the turn via `ISessionDatabase.setTurnCheckpointRef`. Returns
61 > * `undefined` when the session is not git-backed, the baseline is
62 > * missing, or capture fails.
63 > *
64 > * If the captured tree OID matches the parent's tree OID (no-op turn)
65 > * the parent ref is recorded against the turn rather than creating a
66 > * redundant commit / new ref.
67 > *
68 > * Called from `AgentSideEffects` when a `ChatTurnComplete` action
69 > * fires, BEFORE the changeset service's `onTurnComplete` hook so the
70 > * per-turn changeset compute can pick up the new refs.
71 > */
72 > captureTurnCheckpoint(sessionUri: URI, turnId: string): Promise<string | undefined>;
73 >
74 > /**
75 > * Returns the `{ parent, current }` checkpoint refs for a turn, or
76 > * `undefined` when either is missing. Used by the changeset service
77 > * to decide whether to take the git-diff fast path for per-turn diffs.
78 > */
79 > getTurnCheckpointPair(sessionUri: URI, turnId: string): Promise<{ parent: string; current: string } | undefined>;
80 >
81 > /**
82 > * Returns the session's baseline checkpoint ref, or `undefined` when
83 > * the baseline was never captured (non-git-backed session, or capture
84 > * failed). Used by the changeset service to resolve compare-turns
85 > * URIs whose `originalTurnId` is the `BASELINE_TURN_ID` sentinel.
86 > */
87 > getBaselineCheckpointRef(sessionUri: URI): Promise<string | undefined>;
88 >
89 > /**
90 > * Deletes every checkpoint ref this service created for the session
91 > * (baseline + all turn refs), reading the precise list from the
92 > * session database. Tolerates missing refs.
93 > *
94 > * Called from a subscriber to `ISessionDataService.onWillDeleteSessionData`
95 > * before the session's data directory is removed.
96 > */
97 > disposeSessionData(sessionUri: URI): Promise<void>;
98 > }
99 >
100 > /**
101 > * A no-op implementation of {@link IAgentHostCheckpointService} used as a
102 > * fallback in test fixtures that don't exercise checkpoint capture, and
103 > * as the default value for the optional `_checkpointService` parameter
104 > * on `AgentService` so existing test callsites keep compiling without
105 > * forced fixture updates.
106 > */
107 > export const NULL_CHECKPOINT_SERVICE: IAgentHostCheckpointService = {
108 > _serviceBrand: undefined,
109 > captureBaseline: async () => undefined,
110 > captureTurnCheckpoint: async () => undefined,
111 > getTurnCheckpointPair: async () => undefined,
112 > getBaselineCheckpointRef: async () => undefined,
113 > disposeSessionData: async () => { },
114 > };