@codingame/monaco-vscode-chat-service-override 1.85.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/chat.d.ts +5 -0
  2. package/chat.js +39 -0
  3. package/external/rollup-plugin-styles/dist/runtime/inject-css.js +3 -0
  4. package/external/tslib/tslib.es6.js +11 -0
  5. package/index.d.ts +1 -0
  6. package/index.js +1 -0
  7. package/override/vs/platform/dialogs/common/dialogs.js +8 -0
  8. package/package.json +24 -0
  9. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClear.js +17 -0
  10. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.js +115 -0
  11. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.js +509 -0
  12. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCopyActions.js +88 -0
  13. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatFileTreeActions.js +83 -0
  14. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatImportExport.js +110 -0
  15. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatMoveActions.js +223 -0
  16. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.js +283 -0
  17. package/vscode/src/vs/workbench/contrib/chat/browser/chat.contribution.js +283 -0
  18. package/vscode/src/vs/workbench/contrib/chat/browser/chatAccessibilityService.js +61 -0
  19. package/vscode/src/vs/workbench/contrib/chat/browser/chatContributionServiceImpl.js +179 -0
  20. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditor.js +88 -0
  21. package/vscode/src/vs/workbench/contrib/chat/browser/chatQuick.js +271 -0
  22. package/vscode/src/vs/workbench/contrib/chat/browser/chatVariables.js +91 -0
  23. package/vscode/src/vs/workbench/contrib/chat/browser/chatViewPane.js +165 -0
  24. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatHistoryVariables.js +26 -0
  25. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.js +626 -0
  26. package/vscode/src/vs/workbench/contrib/chat/browser/media/chatEditor.css.js +6 -0
  27. package/vscode/src/vs/workbench/contrib/chat/common/chatColors.js +31 -0
  28. package/vscode/src/vs/workbench/contrib/chat/common/chatServiceImpl.js +564 -0
  29. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.js +41 -0
  30. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.js +41 -0
  31. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.js +748 -0
  32. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatDecorations.js +250 -0
  33. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatNotebook.js +62 -0
  34. package/vscode/src/vs/workbench/contrib/inlineChat/common/inlineChatServiceImpl.js +35 -0
@@ -0,0 +1,564 @@
1
+ import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
+ import { CancellationToken, CancellationTokenSource } from 'monaco-editor/esm/vs/base/common/cancellation.js';
3
+ import { Emitter } from 'monaco-editor/esm/vs/base/common/event.js';
4
+ import { MarkdownString } from 'monaco-editor/esm/vs/base/common/htmlContent.js';
5
+ import { Iterable } from 'monaco-editor/esm/vs/base/common/iterator.js';
6
+ import { Disposable, DisposableMap, toDisposable } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
7
+ import { revive } from 'monaco-editor/esm/vs/base/common/marshalling.js';
8
+ import { StopWatch } from 'monaco-editor/esm/vs/base/common/stopwatch.js';
9
+ import { URI } from 'monaco-editor/esm/vs/base/common/uri.js';
10
+ import { localizeWithPath } from 'monaco-editor/esm/vs/nls.js';
11
+ import { CommandsRegistry } from 'monaco-editor/esm/vs/platform/commands/common/commands.js';
12
+ import { IContextKeyService } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey.js';
13
+ import { IInstantiationService } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation.js';
14
+ import { ILogService } from 'monaco-editor/esm/vs/platform/log/common/log.js';
15
+ import { Progress } from 'monaco-editor/esm/vs/platform/progress/common/progress.js';
16
+ import { IStorageService } from 'monaco-editor/esm/vs/platform/storage/common/storage.js';
17
+ import { ITelemetryService } from 'monaco-editor/esm/vs/platform/telemetry/common/telemetry.js';
18
+ import { IWorkspaceContextService } from 'monaco-editor/esm/vs/platform/workspace/common/workspace.js';
19
+ import { IChatAgentService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents';
20
+ import { CONTEXT_PROVIDER_EXISTS } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatContextKeys';
21
+ import { ChatModel, ChatWelcomeMessageModel, ChatModelInitState } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatModel';
22
+ import { ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashCommandPart } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatParserTypes';
23
+ import { ChatRequestParser } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatRequestParser';
24
+ import { InteractiveSessionVoteDirection, InteractiveSessionCopyKind } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatService';
25
+ import { IChatSlashCommandService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatSlashCommands';
26
+ import { IChatVariablesService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatVariables';
27
+ import { IExtensionService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions';
28
+
29
+ const serializedChatKey = 'interactive.sessions';
30
+ const globalChatKey = 'chat.workspaceTransfer';
31
+ const SESSION_TRANSFER_EXPIRATION_IN_MILLISECONDS = 1000 * 60;
32
+ const maxPersistedSessions = 25;
33
+ let ChatService = class ChatService extends Disposable {
34
+ get transferredSessionData() {
35
+ return this._transferredSessionData;
36
+ }
37
+ constructor(storageService, logService, extensionService, instantiationService, telemetryService, contextKeyService, workspaceContextService, chatSlashCommandService, chatVariablesService, chatAgentService) {
38
+ super();
39
+ this.storageService = storageService;
40
+ this.logService = logService;
41
+ this.extensionService = extensionService;
42
+ this.instantiationService = instantiationService;
43
+ this.telemetryService = telemetryService;
44
+ this.contextKeyService = contextKeyService;
45
+ this.workspaceContextService = workspaceContextService;
46
+ this.chatSlashCommandService = chatSlashCommandService;
47
+ this.chatVariablesService = chatVariablesService;
48
+ this.chatAgentService = chatAgentService;
49
+ this._providers = ( new Map());
50
+ this._sessionModels = this._register(( new DisposableMap()));
51
+ this._pendingRequests = this._register(( new DisposableMap()));
52
+ this._onDidPerformUserAction = this._register(( new Emitter()));
53
+ this.onDidPerformUserAction = this._onDidPerformUserAction.event;
54
+ this._onDidSubmitAgent = this._register(( new Emitter()));
55
+ this.onDidSubmitAgent = this._onDidSubmitAgent.event;
56
+ this._onDidDisposeSession = this._register(( new Emitter()));
57
+ this.onDidDisposeSession = this._onDidDisposeSession.event;
58
+ this._onDidRegisterProvider = this._register(( new Emitter()));
59
+ this.onDidRegisterProvider = this._onDidRegisterProvider.event;
60
+ this._hasProvider = CONTEXT_PROVIDER_EXISTS.bindTo(this.contextKeyService);
61
+ const sessionData = storageService.get(serializedChatKey, 1 , '');
62
+ if (sessionData) {
63
+ this._persistedSessions = this.deserializeChats(sessionData);
64
+ const countsForLog = ( Object.keys(this._persistedSessions)).length;
65
+ if (countsForLog > 0) {
66
+ this.trace('constructor', `Restored ${countsForLog} persisted sessions`);
67
+ }
68
+ }
69
+ else {
70
+ this._persistedSessions = {};
71
+ }
72
+ const transferredData = this.getTransferredSessionData();
73
+ const transferredChat = transferredData?.chat;
74
+ if (transferredChat) {
75
+ this.trace('constructor', `Transferred session ${transferredChat.sessionId}`);
76
+ this._persistedSessions[transferredChat.sessionId] = transferredChat;
77
+ this._transferredSessionData = { sessionId: transferredChat.sessionId, inputValue: transferredData.inputValue };
78
+ }
79
+ this._register(storageService.onWillSaveState(() => this.saveState()));
80
+ }
81
+ saveState() {
82
+ let allSessions = Array.from(( this._sessionModels.values()))
83
+ .filter(session => session.getRequests().length > 0);
84
+ allSessions = allSessions.concat(( Object.values(this._persistedSessions))
85
+ .filter(session => !( this._sessionModels.has(session.sessionId)))
86
+ .filter(session => session.requests.length));
87
+ allSessions.sort((a, b) => (b.creationDate ?? 0) - (a.creationDate ?? 0));
88
+ allSessions = allSessions.slice(0, maxPersistedSessions);
89
+ if (allSessions.length) {
90
+ this.trace('onWillSaveState', `Persisting ${allSessions.length} sessions`);
91
+ }
92
+ const serialized = JSON.stringify(allSessions);
93
+ if (allSessions.length) {
94
+ this.trace('onWillSaveState', `Persisting ${serialized.length} chars`);
95
+ }
96
+ this.storageService.store(serializedChatKey, serialized, 1 , 1 );
97
+ }
98
+ notifyUserAction(action) {
99
+ if (action.action.kind === 'vote') {
100
+ this.telemetryService.publicLog2('interactiveSessionVote', {
101
+ providerId: action.providerId,
102
+ direction: action.action.direction === InteractiveSessionVoteDirection.Up ? 'up' : 'down'
103
+ });
104
+ }
105
+ else if (action.action.kind === 'copy') {
106
+ this.telemetryService.publicLog2('interactiveSessionCopy', {
107
+ providerId: action.providerId,
108
+ copyKind: action.action.copyType === InteractiveSessionCopyKind.Action ? 'action' : 'toolbar'
109
+ });
110
+ }
111
+ else if (action.action.kind === 'insert') {
112
+ this.telemetryService.publicLog2('interactiveSessionInsert', {
113
+ providerId: action.providerId,
114
+ newFile: !!action.action.newFile
115
+ });
116
+ }
117
+ else if (action.action.kind === 'command') {
118
+ const command = CommandsRegistry.getCommand(action.action.command.commandId);
119
+ const commandId = command ? action.action.command.commandId : 'INVALID';
120
+ this.telemetryService.publicLog2('interactiveSessionCommand', {
121
+ providerId: action.providerId,
122
+ commandId
123
+ });
124
+ }
125
+ else if (action.action.kind === 'runInTerminal') {
126
+ this.telemetryService.publicLog2('interactiveSessionRunInTerminal', {
127
+ providerId: action.providerId,
128
+ languageId: action.action.languageId ?? ''
129
+ });
130
+ }
131
+ this._onDidPerformUserAction.fire(action);
132
+ }
133
+ trace(method, message) {
134
+ this.logService.trace(`ChatService#${method}: ${message}`);
135
+ }
136
+ error(method, message) {
137
+ this.logService.error(`ChatService#${method} ${message}`);
138
+ }
139
+ deserializeChats(sessionData) {
140
+ try {
141
+ const arrayOfSessions = revive(JSON.parse(sessionData));
142
+ if (!Array.isArray(arrayOfSessions)) {
143
+ throw new Error('Expected array');
144
+ }
145
+ const sessions = arrayOfSessions.reduce((acc, session) => {
146
+ for (const request of session.requests) {
147
+ if (Array.isArray(request.response)) {
148
+ request.response = ( request.response.map((response) => {
149
+ if (typeof response === 'string') {
150
+ return ( new MarkdownString(response));
151
+ }
152
+ return response;
153
+ }));
154
+ }
155
+ else if (typeof request.response === 'string') {
156
+ request.response = [( new MarkdownString(request.response))];
157
+ }
158
+ }
159
+ acc[session.sessionId] = session;
160
+ return acc;
161
+ }, {});
162
+ return sessions;
163
+ }
164
+ catch (err) {
165
+ this.error('deserializeChats', `Malformed session data: ${err}. [${sessionData.substring(0, 20)}${sessionData.length > 20 ? '...' : ''}]`);
166
+ return {};
167
+ }
168
+ }
169
+ getTransferredSessionData() {
170
+ const data = this.storageService.getObject(globalChatKey, 0 , []);
171
+ const workspaceUri = this.workspaceContextService.getWorkspace().folders[0]?.uri;
172
+ if (!workspaceUri) {
173
+ return;
174
+ }
175
+ const thisWorkspace = ( workspaceUri.toString());
176
+ const currentTime = Date.now();
177
+ const transferred = data.find(item => ( URI.revive(item.toWorkspace).toString()) === thisWorkspace && (currentTime - item.timestampInMilliseconds < SESSION_TRANSFER_EXPIRATION_IN_MILLISECONDS));
178
+ const filtered = data.filter(item => ( URI.revive(item.toWorkspace).toString()) !== thisWorkspace && (currentTime - item.timestampInMilliseconds < SESSION_TRANSFER_EXPIRATION_IN_MILLISECONDS));
179
+ this.storageService.store(globalChatKey, JSON.stringify(filtered), 0 , 1 );
180
+ return transferred;
181
+ }
182
+ getHistory() {
183
+ const sessions = ( Object.values(this._persistedSessions))
184
+ .filter(session => session.requests.length > 0);
185
+ sessions.sort((a, b) => (b.creationDate ?? 0) - (a.creationDate ?? 0));
186
+ return ( sessions
187
+ .filter(session => !( this._sessionModels.has(session.sessionId)))
188
+ .filter(session => !session.isImported)
189
+ .map(item => {
190
+ const firstRequestMessage = item.requests[0]?.message;
191
+ return {
192
+ sessionId: item.sessionId,
193
+ title: (typeof firstRequestMessage === 'string' ? firstRequestMessage :
194
+ firstRequestMessage?.text) ?? '',
195
+ };
196
+ }));
197
+ }
198
+ removeHistoryEntry(sessionId) {
199
+ delete this._persistedSessions[sessionId];
200
+ }
201
+ startSession(providerId, token) {
202
+ this.trace('startSession', `providerId=${providerId}`);
203
+ return this._startSession(providerId, undefined, token);
204
+ }
205
+ _startSession(providerId, someSessionHistory, token) {
206
+ this.trace('_startSession', `providerId=${providerId}`);
207
+ const model = this.instantiationService.createInstance(ChatModel, providerId, someSessionHistory);
208
+ this._sessionModels.set(model.sessionId, model);
209
+ this.initializeSession(model, token);
210
+ return model;
211
+ }
212
+ reinitializeModel(model) {
213
+ this.trace('reinitializeModel', `Start reinit`);
214
+ this.initializeSession(model, CancellationToken.None);
215
+ }
216
+ async initializeSession(model, token) {
217
+ try {
218
+ this.trace('initializeSession', `Initialize session ${model.sessionId}`);
219
+ model.startInitialize();
220
+ await this.extensionService.activateByEvent(`onInteractiveSession:${model.providerId}`);
221
+ const provider = this._providers.get(model.providerId);
222
+ if (!provider) {
223
+ throw new Error(`Unknown provider: ${model.providerId}`);
224
+ }
225
+ let session;
226
+ try {
227
+ session = (await provider.prepareSession(token)) ?? undefined;
228
+ }
229
+ catch (err) {
230
+ this.trace('initializeSession', `Provider initializeSession threw: ${err}`);
231
+ }
232
+ if (!session) {
233
+ throw new Error('Provider returned no session');
234
+ }
235
+ this.trace('startSession', `Provider returned session`);
236
+ const welcomeMessage = model.welcomeMessage ? undefined : (await provider.provideWelcomeMessage?.(token)) ?? undefined;
237
+ const welcomeModel = welcomeMessage && ( new ChatWelcomeMessageModel(model, ( welcomeMessage.map(item => typeof item === 'string' ? ( new MarkdownString(item)) : item)), (await provider.provideSampleQuestions?.(token)) ?? []));
238
+ model.initialize(session, welcomeModel);
239
+ }
240
+ catch (err) {
241
+ this.trace('startSession', `initializeSession failed: ${err}`);
242
+ model.setInitializationError(err);
243
+ this._sessionModels.deleteAndDispose(model.sessionId);
244
+ this._onDidDisposeSession.fire({ sessionId: model.sessionId, providerId: model.providerId, reason: 'initializationFailed' });
245
+ }
246
+ }
247
+ getSession(sessionId) {
248
+ return this._sessionModels.get(sessionId);
249
+ }
250
+ getSessionId(sessionProviderId) {
251
+ return Iterable.find(( this._sessionModels.values()), model => model.session?.id === sessionProviderId)?.sessionId;
252
+ }
253
+ getOrRestoreSession(sessionId) {
254
+ this.trace('getOrRestoreSession', `sessionId: ${sessionId}`);
255
+ const model = this._sessionModels.get(sessionId);
256
+ if (model) {
257
+ return model;
258
+ }
259
+ const sessionData = this._persistedSessions[sessionId];
260
+ if (!sessionData) {
261
+ return undefined;
262
+ }
263
+ if (sessionId === this.transferredSessionData?.sessionId) {
264
+ this._transferredSessionData = undefined;
265
+ }
266
+ return this._startSession(sessionData.providerId, sessionData, CancellationToken.None);
267
+ }
268
+ loadSessionFromContent(data) {
269
+ return this._startSession(data.providerId, data, CancellationToken.None);
270
+ }
271
+ async sendRequest(sessionId, request) {
272
+ this.trace('sendRequest', `sessionId: ${sessionId}, message: ${request.substring(0, 20)}${request.length > 20 ? '[...]' : ''}}`);
273
+ if (!request.trim()) {
274
+ this.trace('sendRequest', 'Rejected empty message');
275
+ return;
276
+ }
277
+ const model = this._sessionModels.get(sessionId);
278
+ if (!model) {
279
+ throw new Error(`Unknown session: ${sessionId}`);
280
+ }
281
+ await model.waitForInitialization();
282
+ const provider = this._providers.get(model.providerId);
283
+ if (!provider) {
284
+ throw new Error(`Unknown provider: ${model.providerId}`);
285
+ }
286
+ if (( this._pendingRequests.has(sessionId))) {
287
+ this.trace('sendRequest', `Session ${sessionId} already has a pending request`);
288
+ return;
289
+ }
290
+ return { responseCompletePromise: this._sendRequestAsync(model, sessionId, provider, request) };
291
+ }
292
+ async _sendRequestAsync(model, sessionId, provider, message) {
293
+ const parsedRequest = await this.instantiationService.createInstance(ChatRequestParser).parseChatRequest(sessionId, message);
294
+ let request;
295
+ const agentPart = 'kind' in parsedRequest ? undefined : parsedRequest.parts.find((r) => r instanceof ChatRequestAgentPart);
296
+ const agentSlashCommandPart = 'kind' in parsedRequest ? undefined : parsedRequest.parts.find((r) => r instanceof ChatRequestAgentSubcommandPart);
297
+ const commandPart = 'kind' in parsedRequest ? undefined : parsedRequest.parts.find((r) => r instanceof ChatRequestSlashCommandPart);
298
+ let gotProgress = false;
299
+ const requestType = commandPart ? 'slashCommand' : 'string';
300
+ const source = ( new CancellationTokenSource());
301
+ const token = source.token;
302
+ const sendRequestInternal = async () => {
303
+ const progressCallback = (progress) => {
304
+ if (token.isCancellationRequested) {
305
+ return;
306
+ }
307
+ gotProgress = true;
308
+ if (progress.kind === 'content' || progress.kind === 'markdownContent') {
309
+ this.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${typeof progress.content === 'string' ? progress.content.length : progress.content.value.length} chars`);
310
+ }
311
+ else {
312
+ this.trace('sendRequest', `Provider returned progress: ${JSON.stringify(progress)}`);
313
+ }
314
+ model.acceptResponseProgress(request, progress);
315
+ };
316
+ const stopWatch = ( new StopWatch(false));
317
+ const listener = token.onCancellationRequested(() => {
318
+ this.trace('sendRequest', `Request for session ${model.sessionId} was cancelled`);
319
+ this.telemetryService.publicLog2('interactiveSessionProviderInvoked', {
320
+ providerId: provider.id,
321
+ timeToFirstProgress: undefined,
322
+ totalTime: stopWatch.elapsed(),
323
+ result: 'cancelled',
324
+ requestType,
325
+ agent: agentPart?.agent.id ?? '',
326
+ slashCommand: agentSlashCommandPart ? agentSlashCommandPart.command.name : commandPart?.slashCommand.command,
327
+ chatSessionId: model.sessionId
328
+ });
329
+ model.cancelRequest(request);
330
+ });
331
+ try {
332
+ if (agentPart && agentSlashCommandPart?.command) {
333
+ this._onDidSubmitAgent.fire({ agent: agentPart.agent, slashCommand: agentSlashCommandPart.command, sessionId: model.sessionId });
334
+ }
335
+ let rawResponse;
336
+ let agentOrCommandFollowups = undefined;
337
+ const defaultAgent = this.chatAgentService.getDefaultAgent();
338
+ if (agentPart || (defaultAgent && !commandPart)) {
339
+ const agent = (agentPart?.agent ?? defaultAgent);
340
+ const history = [];
341
+ for (const request of model.getRequests()) {
342
+ if (!request.response) {
343
+ continue;
344
+ }
345
+ history.push({ role: 1 , content: request.message.text });
346
+ history.push({ role: 2 , content: request.response.response.asString() });
347
+ }
348
+ request = model.addRequest(parsedRequest, agent);
349
+ const requestProps = {
350
+ sessionId,
351
+ requestId: request.id,
352
+ message,
353
+ variables: {},
354
+ command: agentSlashCommandPart?.command.name ?? '',
355
+ };
356
+ if ('parts' in parsedRequest) {
357
+ const varResult = await this.chatVariablesService.resolveVariables(parsedRequest, model, token);
358
+ requestProps.variables = varResult.variables;
359
+ requestProps.message = varResult.prompt;
360
+ }
361
+ const agentResult = await this.chatAgentService.invokeAgent(agent.id, requestProps, progressCallback, history, token);
362
+ rawResponse = {
363
+ session: model.session,
364
+ errorDetails: agentResult.errorDetails,
365
+ timings: agentResult.timings
366
+ };
367
+ agentOrCommandFollowups = agentResult?.followUp ? Promise.resolve(agentResult.followUp) :
368
+ this.chatAgentService.getFollowups(agent.id, sessionId, CancellationToken.None);
369
+ }
370
+ else if (commandPart && this.chatSlashCommandService.hasCommand(commandPart.slashCommand.command)) {
371
+ request = model.addRequest(parsedRequest);
372
+ const history = [];
373
+ for (const request of model.getRequests()) {
374
+ if (!request.response) {
375
+ continue;
376
+ }
377
+ history.push({ role: 1 , content: request.message.text });
378
+ history.push({ role: 2 , content: request.response.response.asString() });
379
+ }
380
+ const commandResult = await this.chatSlashCommandService.executeCommand(commandPart.slashCommand.command, message.substring(commandPart.slashCommand.command.length + 1).trimStart(), ( new Progress(p => {
381
+ progressCallback(p);
382
+ })), history, token);
383
+ agentOrCommandFollowups = Promise.resolve(commandResult?.followUp);
384
+ rawResponse = { session: model.session };
385
+ }
386
+ else {
387
+ throw new Error(`Cannot handle request`);
388
+ }
389
+ if (token.isCancellationRequested) {
390
+ return;
391
+ }
392
+ else {
393
+ if (!rawResponse) {
394
+ this.trace('sendRequest', `Provider returned no response for session ${model.sessionId}`);
395
+ rawResponse = { session: model.session, errorDetails: { message: ( localizeWithPath(
396
+ 'vs/workbench/contrib/chat/common/chatServiceImpl',
397
+ 'emptyResponse',
398
+ "Provider returned null response"
399
+ )) } };
400
+ }
401
+ const result = rawResponse.errorDetails?.responseIsFiltered ? 'filtered' :
402
+ rawResponse.errorDetails && gotProgress ? 'errorWithOutput' :
403
+ rawResponse.errorDetails ? 'error' :
404
+ 'success';
405
+ this.telemetryService.publicLog2('interactiveSessionProviderInvoked', {
406
+ providerId: provider.id,
407
+ timeToFirstProgress: rawResponse.timings?.firstProgress,
408
+ totalTime: rawResponse.timings?.totalElapsed,
409
+ result,
410
+ requestType,
411
+ agent: agentPart?.agent.id ?? '',
412
+ slashCommand: agentSlashCommandPart ? agentSlashCommandPart.command.name : commandPart?.slashCommand.command,
413
+ chatSessionId: model.sessionId
414
+ });
415
+ model.setResponse(request, rawResponse);
416
+ this.trace('sendRequest', `Provider returned response for session ${model.sessionId}`);
417
+ if (agentOrCommandFollowups) {
418
+ agentOrCommandFollowups.then(followups => {
419
+ model.setFollowups(request, followups);
420
+ model.completeResponse(request, rawResponse?.errorDetails);
421
+ });
422
+ }
423
+ else {
424
+ model.completeResponse(request, rawResponse?.errorDetails);
425
+ }
426
+ }
427
+ }
428
+ finally {
429
+ listener.dispose();
430
+ }
431
+ };
432
+ const rawResponsePromise = sendRequestInternal();
433
+ this._pendingRequests.set(model.sessionId, source);
434
+ rawResponsePromise.finally(() => {
435
+ this._pendingRequests.deleteAndDispose(model.sessionId);
436
+ });
437
+ return rawResponsePromise;
438
+ }
439
+ async removeRequest(sessionId, requestId) {
440
+ const model = this._sessionModels.get(sessionId);
441
+ if (!model) {
442
+ throw new Error(`Unknown session: ${sessionId}`);
443
+ }
444
+ await model.waitForInitialization();
445
+ const provider = this._providers.get(model.providerId);
446
+ if (!provider) {
447
+ throw new Error(`Unknown provider: ${model.providerId}`);
448
+ }
449
+ model.removeRequest(requestId);
450
+ }
451
+ async sendRequestToProvider(sessionId, message) {
452
+ this.trace('sendRequestToProvider', `sessionId: ${sessionId}`);
453
+ return await this.sendRequest(sessionId, message.message);
454
+ }
455
+ getProviders() {
456
+ return Array.from(( this._providers.keys()));
457
+ }
458
+ async addCompleteRequest(sessionId, message, response) {
459
+ this.trace('addCompleteRequest', `message: ${message}`);
460
+ const model = this._sessionModels.get(sessionId);
461
+ if (!model) {
462
+ throw new Error(`Unknown session: ${sessionId}`);
463
+ }
464
+ await model.waitForInitialization();
465
+ const parsedRequest = typeof message === 'string' ?
466
+ await this.instantiationService.createInstance(ChatRequestParser).parseChatRequest(sessionId, message) :
467
+ message;
468
+ const request = model.addRequest(parsedRequest);
469
+ if (typeof response.message === 'string') {
470
+ model.acceptResponseProgress(request, { content: response.message, kind: 'content' });
471
+ }
472
+ else {
473
+ for (const part of response.message) {
474
+ model.acceptResponseProgress(request, part, true);
475
+ }
476
+ }
477
+ model.setResponse(request, {
478
+ session: model.session,
479
+ errorDetails: response.errorDetails,
480
+ });
481
+ if (response.followups !== undefined) {
482
+ model.setFollowups(request, response.followups);
483
+ }
484
+ model.completeResponse(request, response.errorDetails);
485
+ }
486
+ cancelCurrentRequestForSession(sessionId) {
487
+ this.trace('cancelCurrentRequestForSession', `sessionId: ${sessionId}`);
488
+ this._pendingRequests.get(sessionId)?.cancel();
489
+ this._pendingRequests.deleteAndDispose(sessionId);
490
+ }
491
+ clearSession(sessionId) {
492
+ this.trace('clearSession', `sessionId: ${sessionId}`);
493
+ const model = this._sessionModels.get(sessionId);
494
+ if (!model) {
495
+ throw new Error(`Unknown session: ${sessionId}`);
496
+ }
497
+ this._persistedSessions[sessionId] = model.toJSON();
498
+ this._sessionModels.deleteAndDispose(sessionId);
499
+ this._pendingRequests.get(sessionId)?.cancel();
500
+ this._pendingRequests.deleteAndDispose(sessionId);
501
+ this._onDidDisposeSession.fire({ sessionId, providerId: model.providerId, reason: 'cleared' });
502
+ }
503
+ registerProvider(provider) {
504
+ this.trace('registerProvider', `Adding new chat provider`);
505
+ if (( this._providers.has(provider.id))) {
506
+ throw new Error(`Provider ${provider.id} already registered`);
507
+ }
508
+ this._providers.set(provider.id, provider);
509
+ this._hasProvider.set(true);
510
+ this._onDidRegisterProvider.fire({ providerId: provider.id });
511
+ Array.from(( this._sessionModels.values()))
512
+ .filter(model => model.providerId === provider.id)
513
+ .filter(model => model.initState === ChatModelInitState.Created)
514
+ .forEach(model => this.reinitializeModel(model));
515
+ return toDisposable(() => {
516
+ this.trace('registerProvider', `Disposing chat provider`);
517
+ this._providers.delete(provider.id);
518
+ this._hasProvider.set(this._providers.size > 0);
519
+ Array.from(( this._sessionModels.values()))
520
+ .filter(model => model.providerId === provider.id)
521
+ .forEach(model => model.deinitialize());
522
+ });
523
+ }
524
+ hasSessions(providerId) {
525
+ return !!( Object.values(this._persistedSessions)).find((session) => session.providerId === providerId);
526
+ }
527
+ getProviderInfos() {
528
+ return ( Array.from(( this._providers.values())).map(provider => {
529
+ return {
530
+ id: provider.id,
531
+ displayName: provider.displayName
532
+ };
533
+ }));
534
+ }
535
+ transferChatSession(transferredSessionData, toWorkspace) {
536
+ const model = Iterable.find(( this._sessionModels.values()), model => model.sessionId === transferredSessionData.sessionId);
537
+ if (!model) {
538
+ throw new Error(`Failed to transfer session. Unknown session ID: ${transferredSessionData.sessionId}`);
539
+ }
540
+ const existingRaw = this.storageService.getObject(globalChatKey, 0 , []);
541
+ existingRaw.push({
542
+ chat: model.toJSON(),
543
+ timestampInMilliseconds: Date.now(),
544
+ toWorkspace: toWorkspace,
545
+ inputValue: transferredSessionData.inputValue,
546
+ });
547
+ this.storageService.store(globalChatKey, JSON.stringify(existingRaw), 0 , 1 );
548
+ this.trace('transferChatSession', `Transferred session ${model.sessionId} to workspace ${( toWorkspace.toString())}`);
549
+ }
550
+ };
551
+ ChatService = ( __decorate([
552
+ ( __param(0, IStorageService)),
553
+ ( __param(1, ILogService)),
554
+ ( __param(2, IExtensionService)),
555
+ ( __param(3, IInstantiationService)),
556
+ ( __param(4, ITelemetryService)),
557
+ ( __param(5, IContextKeyService)),
558
+ ( __param(6, IWorkspaceContextService)),
559
+ ( __param(7, IChatSlashCommandService)),
560
+ ( __param(8, IChatVariablesService)),
561
+ ( __param(9, IChatAgentService))
562
+ ], ChatService));
563
+
564
+ export { ChatService };
@@ -0,0 +1,41 @@
1
+ import { registerAction2 } from 'monaco-editor/esm/vs/platform/actions/common/actions.js';
2
+ import { registerEditorContribution } from 'monaco-editor/esm/vs/editor/browser/editorExtensions.js';
3
+ import { InlineChatController } from 'vscode/vscode/vs/workbench/contrib/inlineChat/browser/inlineChatController';
4
+ import { InlineAccessibilityHelpContribution, StartSessionAction, UnstashSessionAction, MakeRequestAction, StopRequestAction, ReRunRequestAction, DiscardAction, DiscardToClipboardAction, DiscardUndoToNewFileAction, CancelSessionAction, ArrowOutUpAction, ArrowOutDownAction, FocusInlineChat, PreviousFromHistory, NextFromHistory, ViewInChatAction, ExpandMessageAction, ContractMessageAction, ToggleInlineDiff, ToggleDiffForChange, FeebackHelpfulCommand, FeebackUnhelpfulCommand, ReportIssueForBugCommand, ApplyPreviewEdits, CopyRecordings } from './inlineChatActions.js';
5
+ import { INLINE_CHAT_ID, INTERACTIVE_EDITOR_ACCESSIBILITY_HELP_ID, INLINE_CHAT_DECORATIONS_ID } from 'vscode/vscode/vs/workbench/contrib/inlineChat/common/inlineChat';
6
+ import { Registry } from 'monaco-editor/esm/vs/platform/registry/common/platform.js';
7
+ import { InlineChatNotebookContribution } from './inlineChatNotebook.js';
8
+ import { Extensions } from 'vscode/vscode/vs/workbench/common/contributions';
9
+ import { InlineChatAccessibleViewContribution } from './inlineChatAccessibleView.js';
10
+ import { InlineChatDecorationsContribution } from './inlineChatDecorations.js';
11
+
12
+ registerEditorContribution(INLINE_CHAT_ID, InlineChatController, 0 );
13
+ registerEditorContribution(INTERACTIVE_EDITOR_ACCESSIBILITY_HELP_ID, InlineAccessibilityHelpContribution, 3 );
14
+ registerEditorContribution(INLINE_CHAT_DECORATIONS_ID, InlineChatDecorationsContribution, 1 );
15
+ registerAction2(StartSessionAction);
16
+ registerAction2(UnstashSessionAction);
17
+ registerAction2(MakeRequestAction);
18
+ registerAction2(StopRequestAction);
19
+ registerAction2(ReRunRequestAction);
20
+ registerAction2(DiscardAction);
21
+ registerAction2(DiscardToClipboardAction);
22
+ registerAction2(DiscardUndoToNewFileAction);
23
+ registerAction2(CancelSessionAction);
24
+ registerAction2(ArrowOutUpAction);
25
+ registerAction2(ArrowOutDownAction);
26
+ registerAction2(FocusInlineChat);
27
+ registerAction2(PreviousFromHistory);
28
+ registerAction2(NextFromHistory);
29
+ registerAction2(ViewInChatAction);
30
+ registerAction2(ExpandMessageAction);
31
+ registerAction2(ContractMessageAction);
32
+ registerAction2(ToggleInlineDiff);
33
+ registerAction2(ToggleDiffForChange);
34
+ registerAction2(FeebackHelpfulCommand);
35
+ registerAction2(FeebackUnhelpfulCommand);
36
+ registerAction2(ReportIssueForBugCommand);
37
+ registerAction2(ApplyPreviewEdits);
38
+ registerAction2(CopyRecordings);
39
+ const workbenchContributionsRegistry = ( Registry.as(Extensions.Workbench));
40
+ workbenchContributionsRegistry.registerWorkbenchContribution(InlineChatNotebookContribution, 3 );
41
+ workbenchContributionsRegistry.registerWorkbenchContribution(InlineChatAccessibleViewContribution, 4 );
@@ -0,0 +1,41 @@
1
+ import { InlineChatController } from 'vscode/vscode/vs/workbench/contrib/inlineChat/browser/inlineChatController';
2
+ import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_RESPONSE_FOCUSED } from 'vscode/vscode/vs/workbench/contrib/inlineChat/common/inlineChat';
3
+ import { IAccessibleViewService } from 'vscode/vscode/vs/workbench/contrib/accessibility/browser/accessibleView';
4
+ import { Disposable } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
5
+ import { ICodeEditorService } from 'monaco-editor/esm/vs/editor/browser/services/codeEditorService.js';
6
+ import { ContextKeyExpr } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey.js';
7
+ import { AccessibleViewAction } from 'vscode/vscode/vs/workbench/contrib/accessibility/browser/accessibleViewActions';
8
+
9
+ class InlineChatAccessibleViewContribution extends Disposable {
10
+ constructor() {
11
+ super();
12
+ this._register(AccessibleViewAction.addImplementation(100, 'inlineChat', accessor => {
13
+ const accessibleViewService = accessor.get(IAccessibleViewService);
14
+ const codeEditorService = accessor.get(ICodeEditorService);
15
+ const editor = (codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor());
16
+ if (!editor) {
17
+ return false;
18
+ }
19
+ const controller = InlineChatController.get(editor);
20
+ if (!controller) {
21
+ return false;
22
+ }
23
+ const responseContent = controller?.getMessage();
24
+ if (!responseContent) {
25
+ return false;
26
+ }
27
+ accessibleViewService.show({
28
+ id: "inlineChat" ,
29
+ verbositySettingKey: "accessibility.verbosity.inlineChat" ,
30
+ provideContent() { return responseContent; },
31
+ onClose() {
32
+ controller.focus();
33
+ },
34
+ options: { type: "view" }
35
+ });
36
+ return true;
37
+ }, ( ContextKeyExpr.or(CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_RESPONSE_FOCUSED))));
38
+ }
39
+ }
40
+
41
+ export { InlineChatAccessibleViewContribution };