Skip to content

Commit 5e3a912

Browse files
authored
Move welcome message to chat agent (microsoft#204163)
* Move welcome message provider to default agent * Remove welcome message/sample questions from interactive provider * Remove provider display name and icon * Add default agent for tests * And proposal
1 parent c535f3d commit 5e3a912

File tree

16 files changed

+120
-105
lines changed

16 files changed

+120
-105
lines changed

extensions/vscode-api-tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"enabledApiProposals": [
88
"authSession",
99
"chatAgents2",
10+
"defaultChatAgent",
1011
"contribViewsRemote",
1112
"contribStatusBarItems",
1213
"createFileSystemWatcher",

extensions/vscode-api-tests/src/singlefolder-tests/chat.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ suite('chat', () => {
3636
deferred.complete(request);
3737
return null;
3838
});
39+
agent.isDefault = true;
3940
agent.subCommandProvider = {
4041
provideSubCommands: (_token) => {
4142
return [{ name: 'hello', description: 'Hello' }];

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

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ export class MainThreadChat extends Disposable implements MainThreadChatShape {
4949

5050
const unreg = this._chatService.registerProvider({
5151
id,
52-
displayName: registration.label,
5352
prepareSession: async (token) => {
5453
const session = await this._proxy.$prepareChat(handle, token);
5554
if (!session) {
@@ -75,12 +74,6 @@ export class MainThreadChat extends Disposable implements MainThreadChatShape {
7574
}
7675
};
7776
},
78-
provideWelcomeMessage: (token) => {
79-
return this._proxy.$provideWelcomeMessage(handle, token);
80-
},
81-
provideSampleQuestions: (token) => {
82-
return this._proxy.$provideSampleQuestions(handle, token);
83-
},
8477
});
8578

8679
this._providerRegistrations.set(handle, unreg);

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ export class MainThreadChatAgents2 extends Disposable implements MainThreadChatA
103103
}
104104
lastSlashCommands = await this._proxy.$provideSlashCommands(handle, token);
105105
return lastSlashCommands;
106+
},
107+
provideWelcomeMessage: (token: CancellationToken) => {
108+
return this._proxy.$provideWelcomeMessage(handle, token);
109+
},
110+
provideSampleQuestions: (token: CancellationToken) => {
111+
return this._proxy.$provideSampleQuestions(handle, token);
106112
}
107113
});
108114
this._agents.set(handle, {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,8 @@ export interface ExtHostChatAgentsShape2 {
12221222
$acceptFeedback(handle: number, sessionId: string, requestId: string, vote: InteractiveSessionVoteDirection, reportIssue?: boolean): void;
12231223
$acceptAction(handle: number, sessionId: string, requestId: string, action: IChatUserActionEvent): void;
12241224
$invokeCompletionProvider(handle: number, query: string, token: CancellationToken): Promise<IChatAgentCompletionItem[]>;
1225+
$provideWelcomeMessage(handle: number, token: CancellationToken): Promise<(string | IMarkdownString)[] | undefined>;
1226+
$provideSampleQuestions(handle: number, token: CancellationToken): Promise<IChatReplyFollowup[] | undefined>;
12251227
$releaseSession(sessionId: string): void;
12261228
}
12271229

@@ -1305,8 +1307,6 @@ export interface MainThreadChatShape extends IDisposable {
13051307

13061308
export interface ExtHostChatShape {
13071309
$prepareChat(handle: number, token: CancellationToken): Promise<IChatDto | undefined>;
1308-
$provideWelcomeMessage(handle: number, token: CancellationToken): Promise<(string | IMarkdownString | IChatReplyFollowup[])[] | undefined>;
1309-
$provideSampleQuestions(handle: number, token: CancellationToken): Promise<IChatReplyFollowup[] | undefined>;
13101310
$releaseSession(sessionId: number): void;
13111311
}
13121312

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

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { CancellationToken } from 'vs/base/common/cancellation';
7-
import { IMarkdownString } from 'vs/base/common/htmlContent';
87
import { Iterable } from 'vs/base/common/iterator';
98
import { toDisposable } from 'vs/base/common/lifecycle';
109
import { IRelaxedExtensionDescription } from 'vs/platform/extensions/common/extensions';
1110
import { ExtHostChatShape, IChatDto, IMainContext, MainContext, MainThreadChatShape } from 'vs/workbench/api/common/extHost.protocol';
12-
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
13-
import { IChatReplyFollowup } from 'vs/workbench/contrib/chat/common/chatService';
1411
import type * as vscode from 'vscode';
1512

1613
class ChatProviderWrapper<T> {
@@ -89,49 +86,6 @@ export class ExtHostChat implements ExtHostChatShape {
8986
};
9087
}
9188

92-
async $provideWelcomeMessage(handle: number, token: CancellationToken): Promise<(string | IMarkdownString | IChatReplyFollowup[])[] | undefined> {
93-
const entry = this._chatProvider.get(handle);
94-
if (!entry) {
95-
return undefined;
96-
}
97-
98-
if (!entry.provider.provideWelcomeMessage) {
99-
return undefined;
100-
}
101-
102-
const content = await entry.provider.provideWelcomeMessage(token);
103-
if (!content) {
104-
return undefined;
105-
}
106-
return content.map(item => {
107-
if (typeof item === 'string') {
108-
return item;
109-
} else if (Array.isArray(item)) {
110-
return item.map(f => typeConvert.ChatReplyFollowup.from(f));
111-
} else {
112-
return typeConvert.MarkdownString.from(item);
113-
}
114-
});
115-
}
116-
117-
async $provideSampleQuestions(handle: number, token: CancellationToken): Promise<IChatReplyFollowup[] | undefined> {
118-
const entry = this._chatProvider.get(handle);
119-
if (!entry) {
120-
return undefined;
121-
}
122-
123-
if (!entry.provider.provideSampleQuestions) {
124-
return undefined;
125-
}
126-
127-
const rawFollowups = await entry.provider.provideSampleQuestions(token);
128-
if (!rawFollowups) {
129-
return undefined;
130-
}
131-
132-
return rawFollowups?.map(f => typeConvert.ChatReplyFollowup.from(f));
133-
}
134-
13589
$releaseSession(sessionId: number) {
13690
this._chatSessions.delete(sessionId);
13791
}

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

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { DeferredPromise, raceCancellation } from 'vs/base/common/async';
88
import { CancellationToken } from 'vs/base/common/cancellation';
99
import { toErrorMessage } from 'vs/base/common/errorMessage';
1010
import { Emitter } from 'vs/base/common/event';
11+
import { IMarkdownString } from 'vs/base/common/htmlContent';
1112
import { StopWatch } from 'vs/base/common/stopwatch';
1213
import { URI } from 'vs/base/common/uri';
1314
import { localize } from 'vs/nls';
@@ -19,7 +20,7 @@ import { ExtHostChatProvider } from 'vs/workbench/api/common/extHostChatProvider
1920
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
2021
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
2122
import { IChatAgentCommand, IChatAgentRequest, IChatAgentResult } from 'vs/workbench/contrib/chat/common/chatAgents';
22-
import { IChatFollowup, IChatUserActionEvent, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
23+
import { IChatFollowup, IChatReplyFollowup, IChatUserActionEvent, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
2324
import { checkProposedApiEnabled, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
2425
import type * as vscode from 'vscode';
2526

@@ -218,12 +219,30 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
218219
const items = await agent.invokeCompletionProvider(query, token);
219220
return items.map(typeConvert.ChatAgentCompletionItem.from);
220221
}
222+
223+
async $provideWelcomeMessage(handle: number, token: CancellationToken): Promise<(string | IMarkdownString)[] | undefined> {
224+
const agent = this._agents.get(handle);
225+
if (!agent) {
226+
return;
227+
}
228+
229+
return await agent.provideWelcomeMessage(token);
230+
}
231+
232+
async $provideSampleQuestions(handle: number, token: CancellationToken): Promise<IChatReplyFollowup[] | undefined> {
233+
const agent = this._agents.get(handle);
234+
if (!agent) {
235+
return;
236+
}
237+
238+
return await agent.provideSampleQuestions(token);
239+
}
221240
}
222241

223242
class ExtHostChatAgent<TResult extends vscode.ChatAgentResult2> {
224243

225244
private _subCommandProvider: vscode.ChatAgentSubCommandProvider | undefined;
226-
private _followupProvider: vscode.FollowupProvider<TResult> | undefined;
245+
private _followupProvider: vscode.ChatAgentFollowupProvider<TResult> | undefined;
227246
private _description: string | undefined;
228247
private _fullName: string | undefined;
229248
private _iconPath: vscode.Uri | { light: vscode.Uri; dark: vscode.Uri } | vscode.ThemeIcon | undefined;
@@ -236,6 +255,7 @@ class ExtHostChatAgent<TResult extends vscode.ChatAgentResult2> {
236255
private _onDidPerformAction = new Emitter<vscode.ChatAgentUserActionEvent>();
237256
private _supportIssueReporting: boolean | undefined;
238257
private _agentVariableProvider?: { provider: vscode.ChatAgentCompletionItemProvider; triggerCharacters: string[] };
258+
private _welcomeMessageProvider?: vscode.ChatAgentWelcomeMessageProvider | undefined;
239259

240260
constructor(
241261
public readonly extension: IExtensionDescription,
@@ -290,6 +310,35 @@ class ExtHostChatAgent<TResult extends vscode.ChatAgentResult2> {
290310
return followups.map(f => typeConvert.ChatFollowup.from(f));
291311
}
292312

313+
async provideWelcomeMessage(token: CancellationToken): Promise<(string | IMarkdownString)[] | undefined> {
314+
if (!this._welcomeMessageProvider) {
315+
return [];
316+
}
317+
const content = await this._welcomeMessageProvider.provideWelcomeMessage(token);
318+
if (!content) {
319+
return [];
320+
}
321+
return content.map(item => {
322+
if (typeof item === 'string') {
323+
return item;
324+
} else {
325+
return typeConvert.MarkdownString.from(item);
326+
}
327+
});
328+
}
329+
330+
async provideSampleQuestions(token: CancellationToken): Promise<IChatReplyFollowup[]> {
331+
if (!this._welcomeMessageProvider || !this._welcomeMessageProvider.provideSampleQuestions) {
332+
return [];
333+
}
334+
const content = await this._welcomeMessageProvider.provideSampleQuestions(token);
335+
if (!content) {
336+
return [];
337+
}
338+
339+
return content?.map(f => typeConvert.ChatReplyFollowup.from(f));
340+
}
341+
293342
get apiAgent(): vscode.ChatAgent2<TResult> {
294343
let disposed = false;
295344
let updateScheduled = false;
@@ -444,6 +493,13 @@ class ExtHostChatAgent<TResult extends vscode.ChatAgentResult2> {
444493
get agentVariableProvider() {
445494
return that._agentVariableProvider;
446495
},
496+
set welcomeMessageProvider(v) {
497+
that._welcomeMessageProvider = v;
498+
updateMetadataSoon();
499+
},
500+
get welcomeMessageProvider() {
501+
return that._welcomeMessageProvider;
502+
},
447503
onDidPerformAction: !isProposedApiEnabled(this.extension, 'chatAgents2Additions')
448504
? undefined!
449505
: this._onDidPerformAction.event

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import { Iterable } from 'vs/base/common/iterator';
1010
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
1111
import { ThemeIcon } from 'vs/base/common/themables';
1212
import { URI } from 'vs/base/common/uri';
13+
import { ProviderResult } from 'vs/editor/common/languages';
1314
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
1415
import { IChatProgressResponseContent } from 'vs/workbench/contrib/chat/common/chatModel';
15-
import { IChatFollowup, IChatProgress, IChatResponseErrorDetails } from 'vs/workbench/contrib/chat/common/chatService';
16+
import { IChatFollowup, IChatProgress, IChatReplyFollowup, IChatResponseErrorDetails } from 'vs/workbench/contrib/chat/common/chatService';
1617
import { IChatRequestVariableValue } from 'vs/workbench/contrib/chat/common/chatVariables';
1718

1819
//#region agent service, commands etc
@@ -33,6 +34,8 @@ export interface IChatAgent extends IChatAgentData {
3334
provideFollowups?(sessionId: string, token: CancellationToken): Promise<IChatFollowup[]>;
3435
lastSlashCommands?: IChatAgentCommand[];
3536
provideSlashCommands(token: CancellationToken): Promise<IChatAgentCommand[]>;
37+
provideWelcomeMessage?(token: CancellationToken): ProviderResult<(string | IMarkdownString)[] | undefined>;
38+
provideSampleQuestions?(token: CancellationToken): ProviderResult<IChatReplyFollowup[] | undefined>;
3639
}
3740

3841
export interface IChatAgentCommand {

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

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

6-
import { URI } from 'vs/base/common/uri';
76
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
87

98
export interface IChatProviderContribution {
109
id: string;
11-
label: string;
12-
extensionIcon?: URI;
1310
when?: string;
1411
}
1512

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,7 @@ export type IChatProgress =
156156

157157
export interface IChatProvider {
158158
readonly id: string;
159-
readonly displayName: string;
160-
readonly iconUrl?: string;
161159
prepareSession(token: CancellationToken): ProviderResult<IChat | undefined>;
162-
provideWelcomeMessage?(token: CancellationToken): ProviderResult<(string | IMarkdownString | IChatReplyFollowup[])[] | undefined>;
163-
provideSampleQuestions?(token: CancellationToken): ProviderResult<IChatReplyFollowup[] | undefined>;
164160
}
165161

166162
export interface IChatReplyFollowup {
@@ -269,7 +265,6 @@ export interface IChatDetail {
269265

270266
export interface IChatProviderInfo {
271267
id: string;
272-
displayName: string;
273268
}
274269

275270
export interface IChatTransferredSessionData {

0 commit comments

Comments
 (0)