From e0d02325cd111586bb693f98a190d57d56974300 Mon Sep 17 00:00:00 2001 From: Bhavya U Date: Sat, 14 Feb 2026 22:59:30 -0800 Subject: [PATCH] add event for focused chat session changes in chat widget service (#295407) * fix: handle active chat session based on local agent session provider * add event for focused chat session changes in chat widget service --- .../api/browser/mainThreadChatAgents2.ts | 16 +++++++++++++--- src/vs/workbench/contrib/chat/browser/chat.ts | 6 ++++++ .../chat/browser/widget/chatWidgetService.ts | 8 ++++++++ .../chat/test/browser/widget/mockChatWidget.ts | 1 + .../test/browser/workbenchTestServices.ts | 1 + 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadChatAgents2.ts b/src/vs/workbench/api/browser/mainThreadChatAgents2.ts index 06341d03c02..130f387072c 100644 --- a/src/vs/workbench/api/browser/mainThreadChatAgents2.ts +++ b/src/vs/workbench/api/browser/mainThreadChatAgents2.ts @@ -23,7 +23,8 @@ import { ExtensionIdentifier } from '../../../platform/extensions/common/extensi import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js'; import { ILogService } from '../../../platform/log/common/log.js'; import { IUriIdentityService } from '../../../platform/uriIdentity/common/uriIdentity.js'; -import { IChatWidgetService } from '../../contrib/chat/browser/chat.js'; +import { IChatWidget, IChatWidgetService } from '../../contrib/chat/browser/chat.js'; +import { AgentSessionProviders, getAgentSessionProvider } from '../../contrib/chat/browser/agentSessions/agentSessions.js'; import { AddDynamicVariableAction, IAddDynamicVariableContext } from '../../contrib/chat/browser/attachments/chatDynamicVariables.js'; import { IChatAgentHistoryEntry, IChatAgentImplementation, IChatAgentRequest, IChatAgentService } from '../../contrib/chat/common/participants/chatAgents.js'; import { IPromptFileContext, IPromptsService } from '../../contrib/chat/common/promptSyntax/service/promptsService.js'; @@ -145,9 +146,18 @@ export class MainThreadChatAgents2 extends Disposable implements MainThreadChatA this._register(this._chatService.onDidReceiveQuestionCarouselAnswer(e => { this._proxy.$handleQuestionCarouselAnswer(e.requestId, e.resolveId, e.answers); })); - this._register(this._chatWidgetService.onDidChangeFocusedWidget(widget => { - this._proxy.$acceptActiveChatSession(widget?.viewModel?.sessionResource); + this._register(this._chatWidgetService.onDidChangeFocusedSession(() => { + this._acceptActiveChatSession(this._chatWidgetService.lastFocusedWidget); })); + + // Push the initial active session if there is already a focused widget + this._acceptActiveChatSession(this._chatWidgetService.lastFocusedWidget); + } + + private _acceptActiveChatSession(widget: IChatWidget | undefined): void { + const sessionResource = widget?.viewModel?.sessionResource; + const isLocal = sessionResource && getAgentSessionProvider(sessionResource) === AgentSessionProviders.Local; + this._proxy.$acceptActiveChatSession(isLocal ? sessionResource : undefined); } $unregisterAgent(handle: number): void { diff --git a/src/vs/workbench/contrib/chat/browser/chat.ts b/src/vs/workbench/contrib/chat/browser/chat.ts index 1cace4dc134..e58d1fe7fba 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.ts @@ -126,6 +126,12 @@ export interface IChatWidgetService { */ readonly onDidChangeFocusedWidget: Event; + /** + * Fires when the focused chat session changes, either because the focused widget + * changed or because the focused widget loaded a different session. + */ + readonly onDidChangeFocusedSession: Event; + /** * Reveals the widget, focusing its input unless `preserveFocus` is true. */ diff --git a/src/vs/workbench/contrib/chat/browser/widget/chatWidgetService.ts b/src/vs/workbench/contrib/chat/browser/widget/chatWidgetService.ts index 9e5ce02f368..136fe05787f 100644 --- a/src/vs/workbench/contrib/chat/browser/widget/chatWidgetService.ts +++ b/src/vs/workbench/contrib/chat/browser/widget/chatWidgetService.ts @@ -36,6 +36,9 @@ export class ChatWidgetService extends Disposable implements IChatWidgetService private readonly _onDidChangeFocusedWidget = this._register(new Emitter()); readonly onDidChangeFocusedWidget = this._onDidChangeFocusedWidget.event; + private readonly _onDidChangeFocusedSession = this._register(new Emitter()); + readonly onDidChangeFocusedSession = this._onDidChangeFocusedSession.event; + constructor( @IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService, @IViewsService private readonly viewsService: IViewsService, @@ -222,6 +225,7 @@ export class ChatWidgetService extends Disposable implements IChatWidgetService this._lastFocusedWidget = widget; this._onDidChangeFocusedWidget.fire(widget); + this._onDidChangeFocusedSession.fire(); } register(newWidget: IChatWidget): IDisposable { @@ -239,6 +243,10 @@ export class ChatWidgetService extends Disposable implements IChatWidgetService return combinedDisposable( newWidget.onDidFocus(() => this.setLastFocusedWidget(newWidget)), newWidget.onDidChangeViewModel(({ previousSessionResource, currentSessionResource }) => { + if (this._lastFocusedWidget === newWidget && !isEqual(previousSessionResource, currentSessionResource)) { + this._onDidChangeFocusedSession.fire(); + } + if (!previousSessionResource || (currentSessionResource && isEqual(previousSessionResource, currentSessionResource))) { return; } diff --git a/src/vs/workbench/contrib/chat/test/browser/widget/mockChatWidget.ts b/src/vs/workbench/contrib/chat/test/browser/widget/mockChatWidget.ts index 7e7d3336a17..edd6275ee86 100644 --- a/src/vs/workbench/contrib/chat/test/browser/widget/mockChatWidget.ts +++ b/src/vs/workbench/contrib/chat/test/browser/widget/mockChatWidget.ts @@ -13,6 +13,7 @@ export class MockChatWidgetService implements IChatWidgetService { readonly onDidAddWidget: Event = Event.None; readonly onDidBackgroundSession: Event = Event.None; readonly onDidChangeFocusedWidget: Event = Event.None; + readonly onDidChangeFocusedSession: Event = Event.None; readonly _serviceBrand: undefined; diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index a911112cb4a..529c27d720d 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -2143,6 +2143,7 @@ export class TestChatWidgetService implements IChatWidgetService { onDidAddWidget = Event.None; onDidBackgroundSession = Event.None; onDidChangeFocusedWidget = Event.None; + onDidChangeFocusedSession = Event.None; async reveal(widget: IChatWidget, preserveFocus?: boolean): Promise { return false; } async revealWidget(preserveFocus?: boolean): Promise { return undefined; }