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
This commit is contained in:
Bhavya U
2026-02-14 22:59:30 -08:00
committed by GitHub
parent dfd7335658
commit e0d02325cd
5 changed files with 29 additions and 3 deletions

View File

@@ -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 {

View File

@@ -126,6 +126,12 @@ export interface IChatWidgetService {
*/
readonly onDidChangeFocusedWidget: Event<IChatWidget | undefined>;
/**
* 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<void>;
/**
* Reveals the widget, focusing its input unless `preserveFocus` is true.
*/

View File

@@ -36,6 +36,9 @@ export class ChatWidgetService extends Disposable implements IChatWidgetService
private readonly _onDidChangeFocusedWidget = this._register(new Emitter<IChatWidget | undefined>());
readonly onDidChangeFocusedWidget = this._onDidChangeFocusedWidget.event;
private readonly _onDidChangeFocusedSession = this._register(new Emitter<void>());
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;
}

View File

@@ -13,6 +13,7 @@ export class MockChatWidgetService implements IChatWidgetService {
readonly onDidAddWidget: Event<IChatWidget> = Event.None;
readonly onDidBackgroundSession: Event<URI> = Event.None;
readonly onDidChangeFocusedWidget: Event<IChatWidget | undefined> = Event.None;
readonly onDidChangeFocusedSession: Event<void> = Event.None;
readonly _serviceBrand: undefined;

View File

@@ -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<boolean> { return false; }
async revealWidget(preserveFocus?: boolean): Promise<IChatWidget | undefined> { return undefined; }