From cafda08d8f063b0bd2f456cd2333bb348382128d Mon Sep 17 00:00:00 2001 From: Matt Bierner <12821956+mjbvz@users.noreply.github.com> Date: Fri, 20 Mar 2026 15:02:15 -0700 Subject: [PATCH] Try to clean up inProgress handling for chat sessions This api is very strange. Reducing where it's exposed because it really should not exist --- .../chatSessions/chatSessions.contribution.ts | 51 +++++-------------- .../browser/chatStatus/chatStatusDashboard.ts | 26 ++++++++-- .../chat/common/chatSessionsService.ts | 4 +- .../test/common/mockChatSessionsService.ts | 11 ++-- 4 files changed, 38 insertions(+), 54 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessions.contribution.ts b/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessions.contribution.ts index f98c6d170b63..eaa31bb7761e 100644 --- a/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessions.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessions.contribution.ts @@ -47,7 +47,7 @@ import { ChatViewPane } from '../widgetHosts/viewPane/chatViewPane.js'; import { AgentSessionProviders, getAgentSessionProviderName } from '../agentSessions/agentSessions.js'; import { BugIndicatingError, isCancellationError } from '../../../../../base/common/errors.js'; import { IEditorGroupsService } from '../../../../services/editor/common/editorGroupsService.js'; -import { getChatSessionType, isUntitledChatSession, LocalChatSessionUri } from '../../common/model/chatUri.js'; +import { isUntitledChatSession, LocalChatSessionUri } from '../../common/model/chatUri.js'; import { assertNever } from '../../../../../base/common/assert.js'; import { ICommandService } from '../../../../../platform/commands/common/commands.js'; import { Target } from '../../common/promptSyntax/promptTypes.js'; @@ -295,7 +295,7 @@ export class ChatSessionsService extends Disposable implements IChatSessionsServ private readonly _onDidChangeOptionGroups = this._register(new Emitter()); public get onDidChangeOptionGroups() { return this._onDidChangeOptionGroups.event; } - private readonly inProgressMap: Map = new Map(); + private readonly inProgressMap = new Map(); private readonly _sessionTypeOptions = new Map(); private readonly _sessionTypeNewSessionOptions = new Map(); @@ -351,23 +351,6 @@ export class ChatSessionsService extends Disposable implements IChatSessionsServ } })); - this._register(this.onDidChangeSessionItems((delta) => { - const changedChatSessionTypes = new Set(); - for (const session of delta.addedOrUpdated ?? []) { - changedChatSessionTypes.add(getChatSessionType(session.resource)); - } - - for (const resource of delta.removed ?? []) { - changedChatSessionTypes.add(getChatSessionType(resource)); - } - - for (const chatSessionType of changedChatSessionTypes) { - this.updateInProgressStatus(chatSessionType).catch(error => { - this._logService.warn(`Failed to update progress status for '${chatSessionType}':`, error); - }); - } - })); - this._register(this._labelService.registerFormatter({ scheme: Schemas.copilotPr, formatting: { @@ -378,27 +361,17 @@ export class ChatSessionsService extends Disposable implements IChatSessionsServ })); } - public reportInProgress(chatSessionType: string, count: number): void { - let displayName: string | undefined; - - if (chatSessionType === AgentSessionProviders.Local) { - displayName = localize('chat.session.inProgress.local', "Local Agent"); - } else if (chatSessionType === AgentSessionProviders.Background) { - displayName = localize('chat.session.inProgress.background', "Background Agent"); - } else if (chatSessionType === AgentSessionProviders.Cloud) { - displayName = localize('chat.session.inProgress.cloud', "Cloud Agent"); - } else { - displayName = this._contributions.get(chatSessionType)?.contribution.displayName; + private reportInProgress(chatSessionType: string, count: number): void { + if (!this._itemControllers.has(chatSessionType)) { + this._logService.warn(`Attempted to report in-progress status for unknown chat session type '${chatSessionType}'`); } - if (displayName) { - this.inProgressMap.set(displayName, count); - } + this.inProgressMap.set(chatSessionType, count); this._onDidChangeInProgress.fire(); } - public getInProgress(): { displayName: string; count: number }[] { - return Array.from(this.inProgressMap.entries()).map(([displayName, count]) => ({ displayName, count })); + public getInProgress(): { chatSessionType: string; count: number }[] { + return Array.from(this.inProgressMap.entries()).map(([chatSessionType, count]) => ({ chatSessionType, count })); } private async updateInProgressStatus(chatSessionType: string): Promise { @@ -919,12 +892,9 @@ export class ChatSessionsService extends Disposable implements IChatSessionsServ disposables.add(controller.onDidChangeChatSessionItems(e => { this._onDidChangeSessionItems.fire(e); + this.updateInProgressStatus(chatSessionType); })); - this.updateInProgressStatus(chatSessionType).catch(error => { - this._logService.warn(`Failed to update initial progress status for '${chatSessionType}':`, error); - }); - return { dispose: () => { initialRefreshCts.cancel(); @@ -935,6 +905,9 @@ export class ChatSessionsService extends Disposable implements IChatSessionsServ this._itemControllers.delete(chatSessionType); this._onDidChangeItemsProviders.fire({ chatSessionType }); } + + // Remove any in-progress tracking for this provider since it's no longer available + this.updateInProgressStatus(chatSessionType); } }; } diff --git a/src/vs/workbench/contrib/chat/browser/chatStatus/chatStatusDashboard.ts b/src/vs/workbench/contrib/chat/browser/chatStatus/chatStatusDashboard.ts index ad2cb70765e2..61e8e655f158 100644 --- a/src/vs/workbench/contrib/chat/browser/chatStatus/chatStatusDashboard.ts +++ b/src/vs/workbench/contrib/chat/browser/chatStatus/chatStatusDashboard.ts @@ -48,6 +48,7 @@ import { Color } from '../../../../../base/common/color.js'; import { IViewsService } from '../../../../services/views/common/viewsService.js'; import { ChatViewId } from '../chat.js'; import { isCompletionsEnabled } from '../../../../../editor/common/services/completionsEnablement.js'; +import { AgentSessionProviders } from '../agentSessions/agentSessions.js'; const defaultChat = product.defaultChatAgent; @@ -235,12 +236,15 @@ export class ChatStatusDashboard extends DomWidget { } })); - for (const { displayName, count } of inProgress) { + for (const { chatSessionType, count } of inProgress) { if (count > 0) { - const text = localize('inProgressChatSession', "$(loading~spin) {0} in progress", displayName); - const chatSessionsElement = this.element.appendChild($('div.description')); - const parts = renderLabelWithIcons(text); - chatSessionsElement.append(...parts); + const displayName = this.getDisplayNameForChatSessionType(chatSessionType); + if (displayName) { + const text = localize('inProgressChatSession', "$(loading~spin) {0} in progress", displayName); + const chatSessionsElement = this.element.appendChild($('div.description')); + const parts = renderLabelWithIcons(text); + chatSessionsElement.append(...parts); + } } } } @@ -402,6 +406,18 @@ export class ChatStatusDashboard extends DomWidget { } } + private getDisplayNameForChatSessionType(chatSessionType: string): string | undefined { + if (chatSessionType === AgentSessionProviders.Local) { + return localize('chat.session.inProgress.local', "Local Agent"); + } else if (chatSessionType === AgentSessionProviders.Background) { + return localize('chat.session.inProgress.background', "Background Agent"); + } else if (chatSessionType === AgentSessionProviders.Cloud) { + return localize('chat.session.inProgress.cloud', "Cloud Agent"); + } else { + return this.chatSessionsService.getChatSessionContribution(chatSessionType)?.displayName; + } + } + private canUseChat(): boolean { if (!this.chatEntitlementService.sentiment.installed || this.chatEntitlementService.sentiment.disabled || this.chatEntitlementService.sentiment.untrusted) { return false; // chat not installed or not enabled diff --git a/src/vs/workbench/contrib/chat/common/chatSessionsService.ts b/src/vs/workbench/contrib/chat/common/chatSessionsService.ts index f69e3ffb6620..b5e5149cf98f 100644 --- a/src/vs/workbench/contrib/chat/common/chatSessionsService.ts +++ b/src/vs/workbench/contrib/chat/common/chatSessionsService.ts @@ -315,8 +315,8 @@ export interface IChatSessionsService { */ refreshChatSessionItems(providerTypeFilter: readonly string[] | undefined, token: CancellationToken): Promise; - reportInProgress(chatSessionType: string, count: number): void; - getInProgress(): { displayName: string; count: number }[]; + /** @deprecated Use `getChatSessionItems` */ + getInProgress(): { chatSessionType: string; count: number }[]; // #endregion diff --git a/src/vs/workbench/contrib/chat/test/common/mockChatSessionsService.ts b/src/vs/workbench/contrib/chat/test/common/mockChatSessionsService.ts index c2eb2fef88aa..f49d4fbbbd23 100644 --- a/src/vs/workbench/contrib/chat/test/common/mockChatSessionsService.ts +++ b/src/vs/workbench/contrib/chat/test/common/mockChatSessionsService.ts @@ -44,7 +44,7 @@ export class MockChatSessionsService implements IChatSessionsService { private contributions: IChatSessionsExtensionPoint[] = []; private optionGroups = new Map(); private sessionOptions = new ResourceMap(); - private inProgress = new Map(); + private inProgress = new Map(); // For testing: allow triggering events fireDidChangeItemsProviders(event: { chatSessionType: string }): void { @@ -125,13 +125,8 @@ export class MockChatSessionsService implements IChatSessionsService { })); } - reportInProgress(chatSessionType: string, count: number): void { - this.inProgress.set(chatSessionType, count); - this._onDidChangeInProgress.fire(); - } - - getInProgress(): { displayName: string; count: number }[] { - return Array.from(this.inProgress.entries()).map(([displayName, count]) => ({ displayName, count })); + getInProgress(): { chatSessionType: string; count: number }[] { + return Array.from(this.inProgress.entries()).map(([chatSessionType, count]) => ({ chatSessionType, count })); } registerChatSessionContentProvider(chatSessionType: string, provider: IChatSessionContentProvider): IDisposable {