Skip to content

Commit 16c5a9a

Browse files
authored
Merge pull request microsoft#257160 from microsoft/dev/mjbvz/chat-session-info-api
Reshape chat session api
2 parents 07120a1 + b44c9f2 commit 16c5a9a

File tree

7 files changed

+75
-84
lines changed

7 files changed

+75
-84
lines changed

src/vs/workbench/api/browser/mainThreadChatSessions.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { CancellationToken } from '../../../base/common/cancellation.js';
77
import { Disposable, DisposableMap } from '../../../base/common/lifecycle.js';
88
import { URI, UriComponents } from '../../../base/common/uri.js';
99
import { ILogService } from '../../../platform/log/common/log.js';
10-
import { IChatSessionContent, IChatSessionsProvider, IChatSessionsService } from '../../contrib/chat/common/chatSessionsService.js';
10+
import { IChatSessionItem, IChatSessionItemProvider, IChatSessionsService } from '../../contrib/chat/common/chatSessionsService.js';
1111
import { extHostNamedCustomer, IExtHostContext } from '../../services/extensions/common/extHostCustomers.js';
1212
import { ExtHostContext, MainContext, MainThreadChatSessionsShape } from '../common/extHost.protocol.js';
1313

@@ -23,24 +23,24 @@ export class MainThreadChatSessions extends Disposable implements MainThreadChat
2323
super();
2424
}
2525

26-
$registerChatSessionsProvider(handle: number, chatSessionType: string): void {
26+
$registerChatSessionItemProvider(handle: number, chatSessionType: string): void {
2727
// Register the provider handle - this tracks that a provider exists
28-
const provider: IChatSessionsProvider = {
28+
const provider: IChatSessionItemProvider = {
2929
chatSessionType,
30-
provideChatSessions: (token) => this._provideChatSessionsInformation(handle, token)
30+
provideChatSessionItems: (token) => this._provideChatSessionItems(handle, token)
3131
};
32-
this._registrations.set(handle, this._chatSessionsService.registerChatSessionsProvider(handle, provider));
32+
this._registrations.set(handle, this._chatSessionsService.registerChatSessionItemProvider(handle, provider));
3333
}
3434

35-
private async _provideChatSessionsInformation(handle: number, token: CancellationToken): Promise<IChatSessionContent[]> {
35+
private async _provideChatSessionItems(handle: number, token: CancellationToken): Promise<IChatSessionItem[]> {
3636
const proxy = this._extHostContext.getProxy(ExtHostContext.ExtHostChatSessions);
3737

3838
try {
3939
// Get all results as an array from the RPC call
40-
const sessions = await proxy.$provideChatSessions(handle, token);
40+
const sessions = await proxy.$provideChatSessionItems(handle, token);
4141
return sessions.map(session => ({
4242
...session,
43-
uri: URI.revive(session.uri),
43+
id: session.id,
4444
iconPath: session.iconPath ? this._reviveIconPath(session.iconPath) : undefined
4545
}));
4646
} catch (error) {
@@ -49,14 +49,14 @@ export class MainThreadChatSessions extends Disposable implements MainThreadChat
4949
return [];
5050
}
5151

52-
$unregisterChatSessionsProvider(handle: number): void {
52+
$unregisterChatSessionItemProvider(handle: number): void {
5353
this._registrations.deleteAndDispose(handle);
5454
}
5555

5656

5757
private _reviveIconPath(
5858
iconPath: UriComponents | { light: UriComponents; dark: UriComponents } | { id: string; color?: { id: string } | undefined })
59-
: IChatSessionContent['iconPath'] {
59+
: IChatSessionItem['iconPath'] {
6060
if (!iconPath) {
6161
return undefined;
6262
}

src/vs/workbench/api/common/extHost.api.impl.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,9 +1505,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
15051505
checkProposedApiEnabled(extension, 'chatParticipantPrivate');
15061506
return _asExtensionEvent(extHostChatAgents2.onDidDisposeChatSession)(listeners, thisArgs, disposables);
15071507
},
1508-
registerChatSessionsProvider(provider: vscode.ChatSessionsProvider) {
1508+
registerChatSessionItemProvider(chatSessionType: string, provider: vscode.ChatSessionItemProvider) {
15091509
checkProposedApiEnabled(extension, 'chatSessionsProvider');
1510-
return extHostChatSessions.registerChatSessionsProvider(provider);
1510+
return extHostChatSessions.registerChatSessionItemProvider(chatSessionType, provider);
15111511
},
15121512
};
15131513

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import { ICodeMapperRequest, ICodeMapperResult } from '../../contrib/chat/common
5858
import { IChatRelatedFile, IChatRelatedFileProviderMetadata as IChatRelatedFilesProviderMetadata, IChatRequestDraft } from '../../contrib/chat/common/chatEditingService.js';
5959
import { IChatProgressHistoryResponseContent } from '../../contrib/chat/common/chatModel.js';
6060
import { IChatContentInlineReference, IChatFollowup, IChatNotebookEdit, IChatProgress, IChatTask, IChatTaskDto, IChatUserActionEvent, IChatVoteAction } from '../../contrib/chat/common/chatService.js';
61-
import { IChatSessionContent } from '../../contrib/chat/common/chatSessionsService.js';
61+
import { IChatSessionItem } from '../../contrib/chat/common/chatSessionsService.js';
6262
import { IChatRequestVariableValue } from '../../contrib/chat/common/chatVariables.js';
6363
import { ChatAgentLocation } from '../../contrib/chat/common/constants.js';
6464
import { IChatMessage, IChatResponseFragment, ILanguageModelChatMetadataAndIdentifier, ILanguageModelChatSelector } from '../../contrib/chat/common/languageModels.js';
@@ -3102,12 +3102,12 @@ export interface MainThreadChatStatusShape {
31023102
}
31033103

31043104
export interface MainThreadChatSessionsShape extends IDisposable {
3105-
$registerChatSessionsProvider(handle: number, chatSessionType: string): void;
3106-
$unregisterChatSessionsProvider(handle: number): void;
3105+
$registerChatSessionItemProvider(handle: number, chatSessionType: string): void;
3106+
$unregisterChatSessionItemProvider(handle: number): void;
31073107
}
31083108

31093109
export interface ExtHostChatSessionsShape {
3110-
$provideChatSessions(handle: number, token: CancellationToken): Promise<IChatSessionContent[]>;
3110+
$provideChatSessionItems(handle: number, token: CancellationToken): Promise<IChatSessionItem[]>;
31113111
}
31123112

31133113
// --- proxy identifiers

src/vs/workbench/api/common/extHostChatSessions.ts

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,22 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { Disposable, DisposableStore } from '../../../base/common/lifecycle.js';
7-
import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';
8-
import { IExtHostRpcService } from './extHostRpcService.js';
9-
import { ExtHostChatSessionsShape, MainContext, MainThreadChatSessionsShape } from './extHost.protocol.js';
106
import type * as vscode from 'vscode';
7+
import { Disposable, DisposableStore } from '../../../base/common/lifecycle.js';
8+
import { MarshalledId } from '../../../base/common/marshallingIds.js';
119
import { ILogService } from '../../../platform/log/common/log.js';
1210
import { Proxied } from '../../services/extensions/common/proxyIdentifier.js';
11+
import { ExtHostChatSessionsShape, MainContext, MainThreadChatSessionsShape } from './extHost.protocol.js';
1312
import { ExtHostCommands } from './extHostCommands.js';
14-
import { MarshalledId } from '../../../base/common/marshallingIds.js';
15-
import { URI } from '../../../base/common/uri.js';
16-
17-
export interface IExtHostChatSessions extends ExtHostChatSessionsShape {
18-
registerChatSessionsProvider(provider: vscode.ChatSessionsProvider): vscode.Disposable;
19-
$provideChatSessions(handle: number, token: vscode.CancellationToken): Promise<vscode.ChatSessionContent[]>;
20-
}
21-
export const IExtHostChatSessions = createDecorator<IExtHostChatSessions>('IExtHostChatSessions');
13+
import { IExtHostRpcService } from './extHostRpcService.js';
14+
import { IChatSessionItem } from '../../contrib/chat/common/chatSessionsService.js';
2215

23-
export class ExtHostChatSessions extends Disposable implements IExtHostChatSessions {
24-
declare _serviceBrand: undefined;
16+
export class ExtHostChatSessions extends Disposable implements ExtHostChatSessionsShape {
2517

2618
private readonly _proxy: Proxied<MainThreadChatSessionsShape>;
27-
private readonly _statusProviders = new Map<number, { provider: vscode.ChatSessionsProvider; disposable: DisposableStore }>();
19+
private readonly _statusProviders = new Map<number, { provider: vscode.ChatSessionItemProvider; disposable: DisposableStore }>();
2820
private _nextHandle = 0;
29-
private _sessionMap: Map<string, vscode.ChatSessionContent> = new Map();
21+
private _sessionMap: Map<string, vscode.ChatSessionItem> = new Map();
3022

3123
constructor(
3224
commands: ExtHostCommands,
@@ -39,12 +31,12 @@ export class ExtHostChatSessions extends Disposable implements IExtHostChatSessi
3931
commands.registerArgumentProcessor({
4032
processArgument: (arg) => {
4133
if (arg && arg.$mid === MarshalledId.ChatSessionContext) {
42-
const id = this.uriToId(arg.uri);
34+
const id = arg.id;
4335
const sessionContent = this._sessionMap.get(id);
4436
if (sessionContent) {
4537
return sessionContent;
4638
} else {
47-
this._logService.warn(`No chat session found for URI: ${id}`);
39+
this._logService.warn(`No chat session found for ID: ${id}`);
4840
return arg;
4941
}
5042
}
@@ -54,49 +46,48 @@ export class ExtHostChatSessions extends Disposable implements IExtHostChatSessi
5446
});
5547
}
5648

57-
registerChatSessionsProvider(provider: vscode.ChatSessionsProvider): vscode.Disposable {
49+
registerChatSessionItemProvider(chatSessionType: string, provider: vscode.ChatSessionItemProvider): vscode.Disposable {
5850
const handle = this._nextHandle++;
5951
const disposables = new DisposableStore();
6052

6153
this._statusProviders.set(handle, { provider, disposable: disposables });
62-
this._proxy.$registerChatSessionsProvider(handle, provider.chatSessionType);
54+
this._proxy.$registerChatSessionItemProvider(handle, chatSessionType);
6355

6456
return {
6557
dispose: () => {
6658
this._statusProviders.delete(handle);
6759
disposables.dispose();
68-
provider.dispose();
69-
this._proxy.$unregisterChatSessionsProvider(handle);
60+
this._proxy.$unregisterChatSessionItemProvider(handle);
7061
}
7162
};
7263
}
7364

74-
async $provideChatSessions(handle: number, token: vscode.CancellationToken): Promise<vscode.ChatSessionContent[]> {
65+
async $provideChatSessionItems(handle: number, token: vscode.CancellationToken): Promise<IChatSessionItem[]> {
7566
const entry = this._statusProviders.get(handle);
7667
if (!entry) {
7768
this._logService.error(`No provider registered for handle ${handle}`);
7869
return [];
7970
}
8071

81-
const sessions = await entry.provider.provideChatSessions(token);
82-
const response: vscode.ChatSessionContent[] = [];
72+
const sessions = await entry.provider.provideChatSessionItems(token);
73+
if (!sessions) {
74+
return [];
75+
}
76+
77+
const response: IChatSessionItem[] = [];
8378
for (const sessionContent of sessions) {
84-
if (sessionContent.uri) {
79+
if (sessionContent.id) {
8580
this._sessionMap.set(
86-
this.uriToId(sessionContent.uri),
81+
sessionContent.id,
8782
sessionContent
8883
);
8984
response.push({
90-
uri: sessionContent.uri,
85+
id: sessionContent.id,
9186
label: sessionContent.label,
9287
iconPath: sessionContent.iconPath
9388
});
9489
}
9590
}
9691
return response;
9792
}
98-
99-
private uriToId(uri: URI): string {
100-
return `${uri.scheme}+${uri.authority}+${uri.path}`;
101-
}
10293
}

src/vs/workbench/contrib/chat/browser/actions/chatActions.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ export function registerChatActions() {
565565
const cancellationToken = new CancellationTokenSource();
566566

567567
try {
568-
const sessions = await chatSessionsService.provideChatSessions(cancellationToken.token);
568+
const sessions = await chatSessionsService.provideChatSessionItems(cancellationToken.token);
569569

570570
for (const session of sessions) {
571571
const sessionContent = session.session;
@@ -588,17 +588,17 @@ export function registerChatActions() {
588588
label: sessionContent.label,
589589
description: '',
590590
chat: {
591-
sessionId: sessionContent.uri.toString(),
591+
sessionId: sessionContent.id,
592592
title: sessionContent.label,
593593
isActive: false,
594594
lastMessageDate: 0,
595595
},
596596
buttons,
597-
uri: sessionContent.uri
597+
id: sessionContent.id
598598
};
599599

600600
// Check if this agent already exists (update existing or add new)
601-
const existingIndex = agentPicks.findIndex(pick => pick.chat.sessionId === sessionContent.uri.path);
601+
const existingIndex = agentPicks.findIndex(pick => pick.chat.sessionId === sessionContent.id);
602602
if (existingIndex >= 0) {
603603
agentPicks[existingIndex] = agentPick;
604604
} else {
@@ -746,7 +746,7 @@ export function registerChatActions() {
746746
if (buttonItem.id) {
747747
const contextItem = context.item as ICodingAgentPickerItem;
748748
commandService.executeCommand(buttonItem.id, {
749-
uri: contextItem.uri,
749+
id: contextItem.id,
750750
$mid: MarshalledId.ChatSessionContext
751751
});
752752
}
@@ -790,13 +790,13 @@ export function registerChatActions() {
790790
true
791791
);
792792
return;
793-
} else if ((item as ICodingAgentPickerItem).uri !== undefined) {
793+
} else if ((item as ICodingAgentPickerItem).id !== undefined) {
794794
// TODO: This is a temporary change that will be replaced by opening a new chat instance
795795
if (item.buttons && item.buttons.length > 0) {
796796
const pickedItem = (item.buttons[0] as ICodingAgentPickerItem);
797797
if (pickedItem.id) {
798798
commandService.executeCommand(pickedItem.id, {
799-
uri: (item as ICodingAgentPickerItem).uri,
799+
id: (item as ICodingAgentPickerItem).id,
800800
$mid: MarshalledId.ChatSessionContext
801801
});
802802
}
@@ -845,7 +845,7 @@ export function registerChatActions() {
845845
}
846846

847847
const showAgentSessionsMenuConfig = configurationService.getValue<string>(ChatConfiguration.AgentSessionsViewLocation);
848-
if (showAgentSessionsMenuConfig === 'showChatsMenu' && chatSessionsService.hasChatSessionsProviders) {
848+
if (showAgentSessionsMenuConfig === 'showChatsMenu' && chatSessionsService.hasChatSessionItemProviders) {
849849
await this.showIntegratedPicker(
850850
chatService,
851851
quickInputService,

src/vs/workbench/contrib/chat/common/chatSessionsService.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,47 +11,47 @@ import { InstantiationType, registerSingleton } from '../../../../platform/insta
1111
import { URI } from '../../../../base/common/uri.js';
1212
import { ThemeIcon } from '../../../../base/common/themables.js';
1313

14-
export interface IChatSessionContent {
15-
uri: URI;
14+
export interface IChatSessionItem {
15+
id: string;
1616
label: string;
1717
iconPath?: URI | {
1818
light: URI;
1919
dark: URI;
2020
} | ThemeIcon;
2121
}
2222

23-
export interface IChatSessionsProvider {
23+
export interface IChatSessionItemProvider {
2424
readonly chatSessionType: string;
25-
provideChatSessions(token: CancellationToken): Promise<IChatSessionContent[]>;
25+
provideChatSessionItems(token: CancellationToken): Promise<IChatSessionItem[]>;
2626
}
2727

2828
export interface IChatSessionsService {
2929
readonly _serviceBrand: undefined;
30-
registerChatSessionsProvider(handle: number, provider: IChatSessionsProvider): IDisposable;
31-
hasChatSessionsProviders: boolean;
32-
provideChatSessions(token: CancellationToken): Promise<{ provider: IChatSessionsProvider; session: IChatSessionContent }[]>;
30+
registerChatSessionItemProvider(handle: number, provider: IChatSessionItemProvider): IDisposable;
31+
hasChatSessionItemProviders: boolean;
32+
provideChatSessionItems(token: CancellationToken): Promise<{ provider: IChatSessionItemProvider; session: IChatSessionItem }[]>;
3333
}
3434

3535
export const IChatSessionsService = createDecorator<IChatSessionsService>('chatSessionsService');
3636

3737
export class ChatSessionsService extends Disposable implements IChatSessionsService {
3838
readonly _serviceBrand: undefined;
39-
private _providers: Map<number, IChatSessionsProvider> = new Map();
39+
private _providers: Map<number, IChatSessionItemProvider> = new Map();
4040

4141
constructor(
4242
@ILogService private readonly _logService: ILogService,
4343
) {
4444
super();
4545
}
4646

47-
public async provideChatSessions(token: CancellationToken): Promise<{ provider: IChatSessionsProvider; session: IChatSessionContent }[]> {
48-
const results: { provider: IChatSessionsProvider; session: IChatSessionContent }[] = [];
47+
public async provideChatSessionItems(token: CancellationToken): Promise<{ provider: IChatSessionItemProvider; session: IChatSessionItem }[]> {
48+
const results: { provider: IChatSessionItemProvider; session: IChatSessionItem }[] = [];
4949

5050
// Iterate through all registered providers and collect their results
5151
for (const [handle, provider] of this._providers) {
5252
try {
53-
if (provider.provideChatSessions) {
54-
const sessions = await provider.provideChatSessions(token);
53+
if (provider.provideChatSessionItems) {
54+
const sessions = await provider.provideChatSessionItems(token);
5555
results.push(...sessions.map(session => ({ provider, session })));
5656
}
5757
} catch (error) {
@@ -65,7 +65,7 @@ export class ChatSessionsService extends Disposable implements IChatSessionsServ
6565
return results;
6666
}
6767

68-
public registerChatSessionsProvider(handle: number, provider: IChatSessionsProvider): IDisposable {
68+
public registerChatSessionItemProvider(handle: number, provider: IChatSessionItemProvider): IDisposable {
6969
this._providers.set(handle, provider);
7070
return {
7171
dispose: () => {
@@ -74,7 +74,7 @@ export class ChatSessionsService extends Disposable implements IChatSessionsServ
7474
};
7575
}
7676

77-
public get hasChatSessionsProviders(): boolean {
77+
public get hasChatSessionItemProviders(): boolean {
7878
return this._providers.size > 0;
7979
}
8080
}

0 commit comments

Comments
 (0)