agentHostChangesetService.ts ×25

Frontier kind: Joint frontier

unlabeled · c_967cc1ccf651

1 test · 52220 LOC · 304 files · introduces 1 test · 109 LOC · 2 files

Introduces — evidence that enters the hierarchy at this concept

Code
26 ranges109 lines · 2 files
Tests
1 test

Contains — complete concept membership

All code (extent)
5589 ranges52220 lines · 304 files · Browse complete extent
All tests (intent)
1 testBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

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 native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

1 test introduced at this concept.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

2 files ranked by introduced lines: 109 introduced LOC across 26 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/agentHostChangesetService.ts 107 introduced LOC · 25 ranges

Open complete file

333 return;
334 }
335 > this._scheduleStaticRecompute(session, 'session', undefined, this._markStaticChangesetComputing(session, 'session')); agentHostChangesetService.ts
336 }
337
759 return;
760 }
761 > this._stateManager.registerChangeset(changesetUri); agentHostChangesetService.ts
762 > try {
763 > let diffs = await this._tryComputeGitDiffs(session, ref.object, kind);
764 > if (!diffs) {
765 > if (kind === 'branch') {
766 > // Branch changeset answers a different question than the
767 > // edit-tracker aggregator — do not fall back. Preserve
768 > // whatever cached state is already there.
769 > this._logService.debug(`[AgentHostChangesetService] Branch git diff unavailable for ${session}; preserving cached changeset. previousStatus=${statusBeforeCompute ?? 'unknown'} cachedFiles=${this._stateManager.getChangesetState(changesetUri)?.files.length ?? 0}`);
770 > this._restoreStaticChangesetStatus(changesetUri, statusBeforeCompute);
771 > return;
772 > }
773 > // `session` kind: working-tree git is unavailable (no
774 > // working dir or not a git work tree). Fall back to the
775 > // edit-tracker aggregator — for the session changeset the
776 > // SDK-tracked edits are the best available approximation.
777 > //
778 > // In multi-chat sessions each peer chat records its file
779 > // edits into its OWN database (the chat URI is used as the
780 > // session URI for that chat's edit tracker). Union the
781 > // session DB with every peer chat DB so peer-chat edits roll
782 > // up into the session-level changes.
783 > const peerSources = this._openPeerChatSources(session);
784 > try {
785 > if (peerSources.length > 0) {
786 const sources: ISessionDiffSource[] = [
787 { sessionUri: session, db: ref.object },
794 // and the tracking issue.
795 diffs = await computeUnionedDiffs(sources, this._diffComputeService);
797 > let incremental: IIncrementalDiffOptions | undefined;
798 > if (changedTurnId) {
799 const previousDiffs = this._readPreviousChangesetDiffs(changesetUri);
800 if (previousDiffs) {
802 }
803 }
804 > diffs = await computeSessionDiffs(session, ref.object, this._diffComputeService, incremental); agentHostChangesetService.ts
805 > }
806 > } finally {
807 > for (const peer of peerSources) {
808 peer.ref.dispose();
809 }
811 > }
812 >
813 > const reviewed = kind === ChangesetKind.Branch
814 ? await this._computeReviewedInfo(session, ref.object)
815 > : undefined; agentHostChangesetService.ts
816 this._publishChangesetDiffs(session, changesetUri, diffs, reviewed);
817
845 error: { errorType: 'computeFailed', message: err instanceof Error ? err.message : String(err) },
846 });
847 > } finally { agentHostChangesetService.ts
848 > this._activeStaticComputes.delete(changesetUri);
849 > this._stateManager.onChangesetLivenessChanged();
850 > ref.dispose();
851 > }
852 }
853
939 */
940 private _openPeerChatSources(session: ProtocolURI): { sessionUri: ProtocolURI; ref: ReturnType<ISessionDataService['openDatabase']> }[] {
941 > const chats = this._stateManager.getSessionState(session)?.chats ?? []; agentHostChangesetService.ts
942 > const sources: { sessionUri: ProtocolURI; ref: ReturnType<ISessionDataService['openDatabase']> }[] = [];
943 > for (const chat of chats) {
944 > if (isDefaultChatUri(chat.resource)) {
945 > continue;
946 > }
947 try {
948 const ref = this._sessionDataService.openDatabase(URI.parse(chat.resource));
951 this._logService.warn(`[AgentHostChangesetService] Failed to open peer chat database for session changes: ${chat.resource}`, err);
952 }
954 > return sources;
955 > }
956
957 /**
964 */
965 private _latestTurnIdAcrossChats(session: ProtocolURI): string | undefined {
966 > const sessionState = this._stateManager.getSessionState(session); agentHostChangesetService.ts
967 > if (!sessionState) {
968 return undefined;
969 }
971 > const chats = sessionState.chats ?? [];
972 > if (chats.length <= 1) {
973 > return sessionState.turns.at(-1)?.id;
974 > }
975
976 let bestTurnId: string | undefined;
1003 */
1004 private async _tryComputeGitDiffs(session: ProtocolURI, db: ISessionDatabase, kind: StaticChangesetKind): Promise<readonly ISessionFileDiff[] | undefined> {
1005 > const workingDirectory = this._stateManager.getSessionState(session)?.workingDirectories?.[0]; agentHostChangesetService.ts
1006 > if (!workingDirectory) {
1007 return undefined;
1008 }
1010 > let workingDirectoryUri: URI;
1011 > try {
1012 > workingDirectoryUri = URI.parse(workingDirectory);
1013 > } catch {
1014 return undefined;
1015 }
1017 > // Session
1018 > if (kind === 'session') {
1019 > // Get session checkpoints. In multi-chat sessions the working tree
1020 > // is shared and each chat's turn checkpoints are stored under the
1021 > // session URI keyed by their turn id, so the most-recently-modified
1022 > // chat's last turn captures the full working-tree delta.
1023 > const latestTurnId = this._latestTurnIdAcrossChats(session);
1024 > if (!latestTurnId) {
1025 > return undefined;
1026 > }
1027
1028 const sessionUri = URI.parse(session);
1031 this._checkpointService.getTurnCheckpointPair(sessionUri, latestTurnId),
1032 ]);
1033 > if (!baseline || !pair) { agentHostChangesetService.ts
1034 return undefined;
1035 }
1045 return undefined;
1046 }
1048 >
1049 > // Branch
1050 > const baseBranch = await this._resolveBranchBaseBranch(session, db);
1051 >
1052 > try {
1053 > return await this._gitService.computeSessionFileDiffs(workingDirectoryUri, {
1054 > sessionUri: session,
1055 > baseBranch
1056 > });
1057 > } catch (err) {
1058 this._logService.warn(`[AgentHostChangesetService] git-driven ${kind} diff computation failed; falling back to edit-tracker`, err);
1059 return undefined;
1060 }
1062
1063 /**
1066 */
1067 private async _resolveBranchBaseBranch(session: ProtocolURI, db: ISessionDatabase): Promise<string | undefined> {
1068 > const persistedBaseBranch = await db.getMetadata(META_DIFF_BASE_BRANCH); agentHostChangesetService.ts
1069 > const gitStateBaseBranch = readSessionGitState(this._stateManager.getSessionState(session)?._meta)?.baseBranchName;
1070 > if (!persistedBaseBranch && gitStateBaseBranch) {
1071 this._logService.debug(`[AgentHostChangesetService] Using _meta.git base branch fallback for Branch Changes in ${session}: ${gitStateBaseBranch}`);
1072 }
1073 > return resolveDiffBaseBranchName(persistedBaseBranch, gitStateBaseBranch); agentHostChangesetService.ts
1074 > }
1075
1076 /**
1113 */
1114 private _persistSessionFlag(session: ProtocolURI, key: string, value: string): void {
1115 > const ref = this._sessionDataService.openDatabase(URI.parse(session)); agentHostChangesetService.ts
1116 > ref.object.setMetadata(key, value).catch(err => {
1117 this._logService.warn(`[AgentHostChangesetService] Failed to persist ${key}`, err);
1118 > }).finally(() => { agentHostChangesetService.ts
1119 > ref.dispose();
1120 > });
1121 > }
1122 }
src/vs/platform/agentHost/node/agentHostChangesetOperationService.ts 2 introduced LOC · 1 range

Open complete file