Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/common/chatSessionsService.ts
5272 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { CancellationToken } from '../../../../base/common/cancellation.js';
7
import { Event, IWaitUntil } from '../../../../base/common/event.js';
8
import { IMarkdownString } from '../../../../base/common/htmlContent.js';
9
import { IDisposable } from '../../../../base/common/lifecycle.js';
10
import { IObservable } from '../../../../base/common/observable.js';
11
import { ThemeIcon } from '../../../../base/common/themables.js';
12
import { URI } from '../../../../base/common/uri.js';
13
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
14
import { IChatAgentAttachmentCapabilities, IChatAgentRequest } from './participants/chatAgents.js';
15
import { IChatEditingSession } from './editing/chatEditingService.js';
16
import { IChatModel, IChatRequestVariableData, ISerializableChatModelInputState } from './model/chatModel.js';
17
import { IChatProgress, IChatService, IChatSessionTiming } from './chatService/chatService.js';
18
import { Target } from './promptSyntax/service/promptsService.js';
19
20
export const enum ChatSessionStatus {
21
Failed = 0,
22
Completed = 1,
23
InProgress = 2,
24
NeedsInput = 3
25
}
26
27
export interface IChatSessionCommandContribution {
28
name: string;
29
description: string;
30
when?: string;
31
}
32
33
export interface IChatSessionProviderOptionItem {
34
id: string;
35
name: string;
36
description?: string;
37
locked?: boolean;
38
icon?: ThemeIcon;
39
default?: boolean;
40
// [key: string]: any;
41
}
42
43
export interface IChatSessionProviderOptionGroupCommand {
44
command: string;
45
title: string;
46
tooltip?: string;
47
arguments?: unknown[];
48
}
49
50
export interface IChatSessionProviderOptionGroup {
51
id: string;
52
name: string;
53
description?: string;
54
items: IChatSessionProviderOptionItem[];
55
searchable?: boolean;
56
onSearch?: (query: string, token: CancellationToken) => Thenable<IChatSessionProviderOptionItem[]>;
57
/**
58
* A context key expression that controls visibility of this option group picker.
59
* When specified, the picker is only visible when the expression evaluates to true.
60
* The expression can reference other option group values via `chatSessionOption.<groupId>`.
61
* Example: `"chatSessionOption.models == 'gpt-4'"`
62
*/
63
when?: string;
64
icon?: ThemeIcon;
65
/**
66
* Custom commands to show in the option group's picker UI.
67
* These will be shown in a separate section at the end of the picker.
68
*/
69
commands?: IChatSessionProviderOptionGroupCommand[];
70
}
71
72
export interface IChatSessionsExtensionPoint {
73
readonly type: string;
74
readonly name: string;
75
readonly displayName: string;
76
readonly description: string;
77
readonly when?: string;
78
readonly icon?: string | { light: string; dark: string };
79
readonly order?: number;
80
readonly alternativeIds?: string[];
81
readonly welcomeTitle?: string;
82
readonly welcomeMessage?: string;
83
readonly welcomeTips?: string;
84
readonly inputPlaceholder?: string;
85
readonly capabilities?: IChatAgentAttachmentCapabilities;
86
readonly commands?: IChatSessionCommandContribution[];
87
readonly canDelegate?: boolean;
88
readonly isReadOnly?: boolean;
89
/**
90
* When set, the chat session will show a filtered mode picker with custom agents
91
* that have a matching `target` property. This enables contributed chat sessions
92
* to reuse the standard agent/mode dropdown with filtered custom agents.
93
* Custom agents without a `target` property are also shown in all filtered lists
94
*/
95
readonly customAgentTarget?: Target;
96
}
97
98
export interface IChatSessionItem {
99
resource: URI;
100
label: string;
101
iconPath?: ThemeIcon;
102
badge?: string | IMarkdownString;
103
description?: string | IMarkdownString;
104
status?: ChatSessionStatus;
105
tooltip?: string | IMarkdownString;
106
timing: IChatSessionTiming;
107
changes?: {
108
files: number;
109
insertions: number;
110
deletions: number;
111
} | readonly IChatSessionFileChange[] | readonly IChatSessionFileChange2[];
112
archived?: boolean;
113
metadata?: { readonly [key: string]: unknown };
114
}
115
116
export interface IChatSessionFileChange {
117
modifiedUri: URI;
118
originalUri?: URI;
119
insertions: number;
120
deletions: number;
121
}
122
123
export interface IChatSessionFileChange2 {
124
readonly uri: URI;
125
readonly originalUri?: URI;
126
readonly modifiedUri?: URI;
127
readonly insertions: number;
128
readonly deletions: number;
129
}
130
131
export type IChatSessionHistoryItem = {
132
id?: string;
133
type: 'request';
134
prompt: string;
135
participant: string;
136
command?: string;
137
variableData?: IChatRequestVariableData;
138
} | {
139
type: 'response';
140
parts: IChatProgress[];
141
participant: string;
142
};
143
144
/**
145
* The session type used for local agent chat sessions.
146
*/
147
export const localChatSessionType = 'local';
148
149
/**
150
* The option ID used for selecting the agent in chat sessions.
151
*/
152
export const agentOptionId = 'agent';
153
154
export interface IChatSession extends IDisposable {
155
readonly onWillDispose: Event<void>;
156
157
readonly sessionResource: URI;
158
159
readonly history: readonly IChatSessionHistoryItem[];
160
161
/**
162
* Session options as key-value pairs. Keys correspond to option group IDs (e.g., 'models', 'subagents')
163
* and values are either the selected option item IDs (string) or full option items (for locked state).
164
*/
165
readonly options?: Record<string, string | IChatSessionProviderOptionItem>;
166
167
readonly progressObs?: IObservable<IChatProgress[]>;
168
readonly isCompleteObs?: IObservable<boolean>;
169
readonly interruptActiveResponseCallback?: () => Promise<boolean>;
170
171
/**
172
* Editing session transferred from a previously-untitled chat session in `onDidCommitChatSessionItem`.
173
*/
174
transferredState?: {
175
editingSession: IChatEditingSession | undefined;
176
inputState: ISerializableChatModelInputState | undefined;
177
};
178
179
requestHandler?: (
180
request: IChatAgentRequest,
181
progress: (progress: IChatProgress[]) => void,
182
// eslint-disable-next-line @typescript-eslint/no-explicit-any
183
history: any[], // TODO: Nail down types
184
token: CancellationToken
185
) => Promise<void>;
186
}
187
188
export interface IChatSessionContentProvider {
189
provideChatSessionContent(sessionResource: URI, token: CancellationToken): Promise<IChatSession>;
190
}
191
192
export interface IChatSessionItemController {
193
194
readonly onDidChangeChatSessionItems: Event<void>;
195
196
get items(): readonly IChatSessionItem[];
197
198
refresh(token: CancellationToken): Promise<void>;
199
}
200
201
/**
202
* Event fired when session options need to be sent to the extension.
203
* Extends IWaitUntil to allow listeners to register async work that will be awaited.
204
*/
205
export interface IChatSessionOptionsWillNotifyExtensionEvent extends IWaitUntil {
206
readonly sessionResource: URI;
207
readonly updates: ReadonlyArray<{ optionId: string; value: string | IChatSessionProviderOptionItem }>;
208
}
209
210
export interface IChatSessionsService {
211
readonly _serviceBrand: undefined;
212
213
// #region Chat session item provider support
214
readonly onDidChangeItemsProviders: Event<{ readonly chatSessionType: string }>;
215
readonly onDidChangeSessionItems: Event<{ readonly chatSessionType: string }>;
216
217
readonly onDidChangeAvailability: Event<void>;
218
readonly onDidChangeInProgress: Event<void>;
219
220
getChatSessionContribution(chatSessionType: string): IChatSessionsExtensionPoint | undefined;
221
222
registerChatSessionItemController(chatSessionType: string, controller: IChatSessionItemController): IDisposable;
223
activateChatSessionItemProvider(chatSessionType: string): Promise<void>;
224
225
getAllChatSessionContributions(): IChatSessionsExtensionPoint[];
226
getIconForSessionType(chatSessionType: string): ThemeIcon | URI | undefined;
227
getWelcomeTitleForSessionType(chatSessionType: string): string | undefined;
228
getWelcomeMessageForSessionType(chatSessionType: string): string | undefined;
229
getInputPlaceholderForSessionType(chatSessionType: string): string | undefined;
230
231
/**
232
* Get the list of current chat session items grouped by session type.
233
* @param providerTypeFilter If specified, only returns items from the given providers. If undefined, returns items from all providers.
234
*/
235
getChatSessionItems(providerTypeFilter: readonly string[] | undefined, token: CancellationToken): Promise<Array<{ readonly chatSessionType: string; readonly items: readonly IChatSessionItem[] }>>;
236
237
/**
238
* Forces the controllers to refresh their session items, optionally filtered by provider type.
239
*/
240
refreshChatSessionItems(providerTypeFilter: readonly string[] | undefined, token: CancellationToken): Promise<void>;
241
242
reportInProgress(chatSessionType: string, count: number): void;
243
getInProgress(): { displayName: string; count: number }[];
244
245
// #endregion
246
247
// #region Content provider support
248
readonly onDidChangeContentProviderSchemes: Event<{ readonly added: string[]; readonly removed: string[] }>;
249
250
getContentProviderSchemes(): string[];
251
252
registerChatSessionContentProvider(scheme: string, provider: IChatSessionContentProvider): IDisposable;
253
canResolveChatSession(sessionResource: URI): Promise<boolean>;
254
getOrCreateChatSession(sessionResource: URI, token: CancellationToken): Promise<IChatSession>;
255
256
hasAnySessionOptions(sessionResource: URI): boolean;
257
getSessionOption(sessionResource: URI, optionId: string): string | IChatSessionProviderOptionItem | undefined;
258
setSessionOption(sessionResource: URI, optionId: string, value: string | IChatSessionProviderOptionItem): boolean;
259
260
/**
261
* Fired when options for a chat session change.
262
*/
263
onDidChangeSessionOptions: Event<URI>;
264
265
/**
266
* Get the capabilities for a specific session type
267
*/
268
getCapabilitiesForSessionType(chatSessionType: string): IChatAgentAttachmentCapabilities | undefined;
269
270
/**
271
* Get the customAgentTarget for a specific session type.
272
* When the Target is not `Target.Undefined`, the mode picker should show filtered custom agents matching this target.
273
*/
274
getCustomAgentTargetForSessionType(chatSessionType: string): Target;
275
276
onDidChangeOptionGroups: Event<string>;
277
278
getOptionGroupsForSessionType(chatSessionType: string): IChatSessionProviderOptionGroup[] | undefined;
279
setOptionGroupsForSessionType(chatSessionType: string, handle: number, optionGroups?: IChatSessionProviderOptionGroup[]): void;
280
/**
281
* Event fired when session options change and need to be sent to the extension.
282
* MainThreadChatSessions subscribes to this to forward changes to the extension host.
283
* Uses IWaitUntil pattern to allow listeners to register async work.
284
*/
285
readonly onRequestNotifyExtension: Event<IChatSessionOptionsWillNotifyExtensionEvent>;
286
notifySessionOptionsChange(sessionResource: URI, updates: ReadonlyArray<{ optionId: string; value: string | IChatSessionProviderOptionItem }>): Promise<void>;
287
288
registerChatModelChangeListeners(chatService: IChatService, chatSessionType: string, onChange: () => void): IDisposable;
289
getInProgressSessionDescription(chatModel: IChatModel): string | undefined;
290
}
291
292
export function isSessionInProgressStatus(state: ChatSessionStatus): boolean {
293
return state === ChatSessionStatus.InProgress || state === ChatSessionStatus.NeedsInput;
294
}
295
296
export function isIChatSessionFileChange2(obj: unknown): obj is IChatSessionFileChange2 {
297
const candidate = obj as IChatSessionFileChange2;
298
return candidate && candidate.uri instanceof URI && typeof candidate.insertions === 'number' && typeof candidate.deletions === 'number';
299
}
300
301
export const IChatSessionsService = createDecorator<IChatSessionsService>('chatSessionsService');
302
303