Skip to content

Commit 59b58f7

Browse files
authored
Notify changes to Chat Session Options (#2361)
1 parent 5a400f4 commit 59b58f7

File tree

4 files changed

+63
-4
lines changed

4 files changed

+63
-4
lines changed

src/extension/chatSessions/vscode-node/chatSessions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export class ChatSessionsContrib extends Disposable implements IExtensionContrib
119119

120120
const copilotcliChatSessionParticipant = this._register(copilotcliAgentInstaService.createInstance(
121121
CopilotCLIChatSessionParticipant,
122+
copilotcliChatSessionContentProvider,
122123
promptResolver,
123124
copilotcliSessionItemProvider,
124125
cloudSessionProvider,

src/extension/chatSessions/vscode-node/copilotCLIChatSessionsContribution.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,13 +278,21 @@ export class CopilotCLIChatSessionItemProvider extends Disposable implements vsc
278278
}
279279
}
280280

281-
export class CopilotCLIChatSessionContentProvider implements vscode.ChatSessionContentProvider {
281+
export class CopilotCLIChatSessionContentProvider extends Disposable implements vscode.ChatSessionContentProvider {
282+
private readonly _onDidChangeChatSessionOptions = this._register(new Emitter<vscode.ChatSessionOptionChangeEvent>());
283+
readonly onDidChangeChatSessionOptions = this._onDidChangeChatSessionOptions.event;
282284
constructor(
283285
private readonly worktreeManager: CopilotCLIWorktreeManager,
284286
@ICopilotCLIModels private readonly copilotCLIModels: ICopilotCLIModels,
285287
@ICopilotCLIAgents private readonly copilotCLIAgents: ICopilotCLIAgents,
286288
@ICopilotCLISessionService private readonly sessionService: ICopilotCLISessionService,
287-
) { }
289+
) {
290+
super();
291+
}
292+
293+
public notifySessionOptionsChange(resource: vscode.Uri, updates: ReadonlyArray<{ optionId: string; value: string }>): void {
294+
this._onDidChangeChatSessionOptions.fire({ resource, updates });
295+
}
288296

289297
async provideChatSessionContent(resource: Uri, token: vscode.CancellationToken): Promise<vscode.ChatSession> {
290298
const copilotcliSessionId = SessionIdForCLI.parse(resource);
@@ -413,6 +421,7 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
413421
private CLI_CANCEL = vscode.l10n.t('Cancel');
414422

415423
constructor(
424+
private readonly contentProvider: CopilotCLIChatSessionContentProvider,
416425
private readonly promptResolver: CopilotCLIPromptResolver,
417426
private readonly sessionItemProvider: CopilotCLIChatSessionItemProvider,
418427
private readonly cloudSessionProvider: CopilotCloudSessionsProvider | undefined,
@@ -475,6 +484,21 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
475484
this.getModelId(id, request, token),
476485
this.getAgent(id, request, token),
477486
]);
487+
if (isUntitled && (modelId || agent)) {
488+
const promptFile = request ? await this.getPromptInfoFromRequest(request, token) : undefined;
489+
if (promptFile) {
490+
const changes: { optionId: string; value: string }[] = [];
491+
if (agent) {
492+
changes.push({ optionId: AGENTS_OPTION_ID, value: agent.name });
493+
}
494+
if (modelId) {
495+
changes.push({ optionId: MODELS_OPTION_ID, value: modelId });
496+
}
497+
if (changes.length > 0) {
498+
this.contentProvider.notifySessionOptionsChange(resource, changes);
499+
}
500+
}
501+
}
478502
const session = await this.getOrCreateSession(request, chatSessionContext, modelId, agent, stream, disposables, token);
479503
if (!session || token.isCancellationRequested) {
480504
return {};

src/extension/chatSessions/vscode-node/test/copilotCLIChatSessionParticipant.spec.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import { ChatSummarizerProvider } from '../../../prompt/node/summarizer';
3333
import { createExtensionUnitTestingServices } from '../../../test/node/services';
3434
import { MockChatResponseStream, TestChatRequest } from '../../../test/node/testHelpers';
3535
import type { IToolsService } from '../../../tools/common/toolsService';
36-
import { CopilotCLIChatSessionItemProvider, CopilotCLIChatSessionParticipant, CopilotCLIWorktreeManager } from '../copilotCLIChatSessionsContribution';
36+
import { CopilotCLIChatSessionContentProvider, CopilotCLIChatSessionItemProvider, CopilotCLIChatSessionParticipant, CopilotCLIWorktreeManager } from '../copilotCLIChatSessionsContribution';
3737
import { CopilotCloudSessionsProvider } from '../copilotCloudSessionsProvider';
3838

3939
// Mock terminal integration to avoid importing PowerShell asset (.ps1) which Vite cannot parse during tests
@@ -189,8 +189,13 @@ describe('CopilotCLIChatSessionParticipant.handleRequest', () => {
189189
sessionService = disposables.add(new CopilotCLISessionService(logService, sdk, instantiationService, new NullNativeEnvService(), new MockFileSystemService(), mcpHandler, new NullCopilotCLIAgents()));
190190

191191
manager = await sessionService.getSessionManager() as unknown as MockCliSdkSessionManager;
192-
192+
const contentProvider = new class extends mock<CopilotCLIChatSessionContentProvider>() {
193+
override notifySessionOptionsChange(_resource: vscode.Uri, _updates: ReadonlyArray<{ optionId: string; value: string }>): void {
194+
// no-op
195+
}
196+
}();
193197
participant = new CopilotCLIChatSessionParticipant(
198+
contentProvider,
194199
promptResolver,
195200
itemProvider,
196201
cloudProvider,

src/extension/vscode.proposed.chatSessionsProvider.d.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,39 @@ declare module 'vscode' {
179179
readonly requestHandler: ChatRequestHandler | undefined;
180180
}
181181

182+
/**
183+
* Event fired when chat session options change.
184+
*/
185+
export interface ChatSessionOptionChangeEvent {
186+
/**
187+
* Identifier of the chat session being updated.
188+
*/
189+
readonly resource: Uri;
190+
/**
191+
* Collection of option identifiers and their new values. Only the options that changed are included.
192+
*/
193+
readonly updates: ReadonlyArray<{
194+
/**
195+
* Identifier of the option that changed (for example `model`).
196+
*/
197+
readonly optionId: string;
198+
199+
/**
200+
* The new value assigned to the option. When `undefined`, the option is cleared.
201+
*/
202+
readonly value: string;
203+
}>;
204+
}
205+
182206
/**
183207
* Provides the content for a chat session rendered using the native chat UI.
184208
*/
185209
export interface ChatSessionContentProvider {
210+
/**
211+
* Event that the provider can fire to signal that the options for a chat session have changed.
212+
*/
213+
readonly onDidChangeChatSessionOptions?: Event<ChatSessionOptionChangeEvent>;
214+
186215
/**
187216
* Provides the chat session content for a given uri.
188217
*

0 commit comments

Comments
 (0)