Skip to content

Add new chat items to inProgressItem instead of the controller#309965

Merged
TylerLeonhardt merged 1 commit intomainfrom
tyler/legitimate-duck
Apr 14, 2026
Merged

Add new chat items to inProgressItem instead of the controller#309965
TylerLeonhardt merged 1 commit intomainfrom
tyler/legitimate-duck

Conversation

@TylerLeonhardt
Copy link
Copy Markdown
Member

Since they have not yet been created on disk, we should keep these in the inProgress map so they're maintained across refreshes.

Since they have not yet been created on disk, we should keep these in the inProgress map so they're maintained across refreshes.
Copilot AI review requested due to automatic review settings April 14, 2026 20:25
@TylerLeonhardt TylerLeonhardt enabled auto-merge (squash) April 14, 2026 20:25
@TylerLeonhardt TylerLeonhardt self-assigned this Apr 14, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR changes how newly created (not yet persisted) chat session items are tracked so they survive refreshes by storing them in the in-progress map rather than immediately adding them to the controller’s main items collection.

Changes:

  • Store newly created chat items in _inProgressItems keyed by newSessionId instead of adding them to this._controller.items.
Show a summary per file
File Description
extensions/copilot/src/extension/chatSessions/vscode-node/claudeChatSessionContentProvider.ts Routes newly created (not-yet-on-disk) chat items into the in-progress tracking map to persist across refreshes.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 2

cwd: folder,
};
this._controller.items.add(item);
this._inProgressItems.set(newSessionId, item);
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By no longer adding the item to this._controller.items, any logic that relies on the controller’s main item collection (e.g., UI listing, disposal, or persistence transitions) may not see this item until it’s written to disk. To avoid stale entries and potential memory/resource leaks, ensure there is a guaranteed transition path that (a) moves the item from _inProgressItems into this._controller.items once it’s persisted, and (b) removes it from _inProgressItems on completion, cancellation, or failure (ideally in a finally/cleanup path).

See below for a potential fix:

		const cleanupInProgressItem = (sessionId: string, removeTransientControllerItem = false) => {
			const inProgressItem = this._inProgressItems.get(sessionId);
			if (!inProgressItem) {
				return;
			}

			this._inProgressItems.delete(sessionId);

			if (removeTransientControllerItem) {
				const sessionUri = ClaudeSessionUri.forSessionId(sessionId);
				if (this._controller.items.get(sessionUri) === inProgressItem) {
					this._controller.items.delete(sessionUri);
				}
			}
		};

		const reconcileInProgressItems = () => {
			for (const [sessionId, inProgressItem] of this._inProgressItems) {
				const sessionUri = ClaudeSessionUri.forSessionId(sessionId);
				const currentItem = this._controller.items.get(sessionUri);

				if (currentItem && currentItem !== inProgressItem) {
					this._inProgressItems.delete(sessionId);
				}
			}
		};

		this._controller = this._register(vscode.chat.createChatSessionItemController(
			ClaudeSessionUri.scheme,
			async () => {
				try {
					await this._refreshItems(CancellationToken.None);
				} finally {
					reconcileInProgressItems();
				}
			}
		));

		this._controller.newChatSessionItemHandler = async (context, token) => {
			const newSessionId = generateUuid();

			try {
				const item = this._controller.createChatSessionItem(
					ClaudeSessionUri.forSessionId(newSessionId),
					context.request.prompt,
				);
				item.iconPath = new vscode.ThemeIcon('claude');
				item.timing = { created: Date.now() };
				const permissionModeOptionValue = context.sessionOptions?.find(o => o.optionId === PERMISSION_MODE_OPTION_ID)?.value;
				const permissionMode = typeof permissionModeOptionValue === 'string' ? permissionModeOptionValue : permissionModeOptionValue?.id;
				const folderOptionValue = context.sessionOptions?.find(o => o.optionId === FOLDER_OPTION_ID)?.value;
				const folder = typeof folderOptionValue === 'string'
					? URI.file(folderOptionValue)
					: folderOptionValue?.id
						? URI.file(folderOptionValue.id)
						: undefined;
				item.metadata = {
					permissionMode,
					cwd: folder,
				};

				this._controller.items.add(item);
				this._inProgressItems.set(newSessionId, item);
				token.onCancellationRequested(() => cleanupInProgressItem(newSessionId, true));

				return item;
			} catch (error) {
				cleanupInProgressItem(newSessionId, true);
				throw error;
			}

Copilot uses AI. Check for mistakes.
@@ -438,7 +438,7 @@ export class ClaudeChatSessionItemController extends Disposable {
permissionMode,
cwd: folder,
};
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change encodes an important lifecycle rule ("items not yet created on disk must live in _inProgressItems"). Consider adding a short inline comment here (or a brief doc comment on _inProgressItems) describing when entries are added/removed and when they are promoted into the controller’s main items collection. This will help future changes avoid accidentally double-tracking or orphaning items.

Suggested change
};
};
// Newly created items live here until the backing session exists on disk; once persisted,
// they are removed from `_inProgressItems` and promoted into `this._controller.items`.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

Screenshot Changes

Base: 6a3da5ff Current: 516412e5

Changed (2)

chat/aiCustomizations/aiCustomizationManagementEditor/PromptsTabScrolled/Dark
Before After
before after
editor/inlineCompletions/other/JumpToHint/Dark
Before After
before after

@TylerLeonhardt TylerLeonhardt merged commit 5023d59 into main Apr 14, 2026
30 checks passed
@TylerLeonhardt TylerLeonhardt deleted the tyler/legitimate-duck branch April 14, 2026 21:22
@vs-code-engineering vs-code-engineering bot added this to the 1.117.0 milestone Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants