@codingame/monaco-vscode-chat-service-override 10.1.3 → 11.0.0

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 (50) hide show
  1. package/chat.js +6 -3
  2. package/package.json +6 -2
  3. package/vscode/src/vs/editor/common/diff/documentDiffProvider.js +8 -0
  4. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.js +84 -38
  5. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.js +265 -20
  6. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.js +20 -39
  7. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.js +373 -216
  8. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCopyActions.js +4 -5
  9. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatDeveloperActions.js +1 -1
  10. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatFileTreeActions.js +4 -5
  11. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatGettingStarted.js +54 -0
  12. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatImportExport.js +6 -7
  13. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatMoveActions.js +12 -11
  14. package/vscode/src/vs/workbench/contrib/chat/browser/actions/codeBlockOperations.js +14 -42
  15. package/vscode/src/vs/workbench/contrib/chat/browser/chat.contribution.js +82 -50
  16. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedFileEntry.js +326 -0
  17. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingService.js +448 -0
  18. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.js +507 -0
  19. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingTextModelContentProviders.js +76 -0
  20. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditor.js +4 -4
  21. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditorActions.js +109 -0
  22. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditorController.js +284 -0
  23. package/vscode/src/vs/workbench/contrib/chat/browser/chatParticipantContributions.js +116 -77
  24. package/vscode/src/vs/workbench/contrib/chat/browser/chatPasteProviders.js +100 -9
  25. package/vscode/src/vs/workbench/contrib/chat/browser/chatQuick.js +3 -3
  26. package/vscode/src/vs/workbench/contrib/chat/browser/chatResponseAccessibleView.js +1 -1
  27. package/vscode/src/vs/workbench/contrib/chat/browser/chatVariables.js +7 -9
  28. package/vscode/src/vs/workbench/contrib/chat/browser/chatViewPane.js +61 -42
  29. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.js +5 -5
  30. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorHover.js +3 -3
  31. package/vscode/src/vs/workbench/contrib/chat/{common → browser}/languageModelToolsService.js +28 -31
  32. package/vscode/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcomeContributions.js +75 -0
  33. package/vscode/src/vs/workbench/contrib/chat/common/chatCodeMapperService.js +120 -1
  34. package/vscode/src/vs/workbench/contrib/chat/common/chatProgressTypes/chatToolInvocation.js +10 -8
  35. package/vscode/src/vs/workbench/contrib/chat/common/chatServiceImpl.js +33 -18
  36. package/vscode/src/vs/workbench/contrib/chat/common/chatWidgetHistoryService.js +1 -1
  37. package/vscode/src/vs/workbench/contrib/chat/common/ignoredFiles.js +21 -0
  38. package/vscode/src/vs/workbench/contrib/chat/common/languageModelStats.js +2 -2
  39. package/vscode/src/vs/workbench/contrib/chat/common/languageModels.js +6 -6
  40. package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsContribution.js +68 -47
  41. package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsParametersSchema.js +250 -0
  42. package/vscode/src/vs/workbench/contrib/chat/common/voiceChatService.js +2 -2
  43. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.js +7 -8
  44. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibilityHelp.js +1 -1
  45. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.js +1 -1
  46. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatCurrentLine.js +3 -3
  47. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatNotebook.js +2 -2
  48. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSavingServiceImpl.js +65 -128
  49. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.js +0 -170
  50. package/vscode/src/vs/workbench/contrib/chat/browser/chatGettingStarted.js +0 -131
@@ -30,29 +30,33 @@ import { SIDE_BAR_FOREGROUND } from 'vscode/vscode/vs/workbench/common/theme';
30
30
  import { IViewDescriptorService } from 'vscode/vscode/vs/workbench/common/views.service';
31
31
  import { ChatAgentLocation } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents';
32
32
  import { IChatAgentService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents.service';
33
- import { ChatModelInitState } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatModel';
34
- import { CHAT_PROVIDER_ID } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatParticipantContribTypes';
33
+ import { ChatModelInitState } from '@codingame/monaco-vscode-chat-extensions-interactive-notebook-quickaccess-search-terminal-common/vscode/vs/workbench/contrib/chat/common/chatModel';
34
+ import { CHAT_PROVIDER_ID } from '@codingame/monaco-vscode-chat-extensions-interactive-notebook-quickaccess-search-terminal-common/vscode/vs/workbench/contrib/chat/common/chatParticipantContribTypes';
35
35
  import { IChatService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatService.service';
36
- import { ChatWidget } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chatWidget';
36
+ import { ChatWidget } from '@codingame/monaco-vscode-chat-extensions-notebook-common/vscode/vs/workbench/contrib/chat/browser/chatWidget';
37
+ import { ChatViewWelcomeController } from '@codingame/monaco-vscode-chat-extensions-notebook-common/vscode/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewWelcomeController';
37
38
 
38
- const CHAT_SIDEBAR_PANEL_ID = 'workbench.panel.chatSidebar';
39
+ const CHAT_SIDEBAR_PANEL_ID = 'workbench.panel.chat';
40
+ const CHAT_EDITING_SIDEBAR_PANEL_ID = 'workbench.panel.chatEditing';
39
41
  let ChatViewPane = class ChatViewPane extends ViewPane {
40
42
  get widget() { return this._widget; }
41
- constructor(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, hoverService, storageService, chatService, chatAgentService, logService) {
43
+ constructor(chatOptions, options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, hoverService, storageService, chatService, chatAgentService, logService) {
42
44
  super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, hoverService);
45
+ this.chatOptions = chatOptions;
43
46
  this.storageService = storageService;
44
47
  this.chatService = chatService;
45
48
  this.chatAgentService = chatAgentService;
46
49
  this.logService = logService;
47
50
  this.modelDisposables = this._register(( new DisposableStore()));
48
- this.didProviderRegistrationFail = false;
51
+ this.defaultParticipantRegistrationFailed = false;
49
52
  this.didUnregisterProvider = false;
50
- this.isInitialized = false;
51
- this.memento = ( new Memento('interactive-session-view-' + CHAT_PROVIDER_ID, this.storageService));
53
+ this.memento = ( new Memento(
54
+ 'interactive-session-view-' + CHAT_PROVIDER_ID + (this.chatOptions.location === ChatAgentLocation.EditingSession ? `-edits` : ''),
55
+ this.storageService
56
+ ));
52
57
  this.viewState = this.memento.getMemento(1 , 1 );
53
58
  this._register(this.chatAgentService.onDidChangeAgents(() => {
54
- this.isInitialized = true;
55
- if (this.chatAgentService.getDefaultAgent(ChatAgentLocation.Panel)) {
59
+ if (this.chatAgentService.getDefaultAgent(this.chatOptions?.location)) {
56
60
  if (!this._widget?.viewModel) {
57
61
  const sessionId = this.getSessionId();
58
62
  const model = sessionId ? this.chatService.getOrRestoreSession(sessionId) : undefined;
@@ -60,7 +64,7 @@ let ChatViewPane = class ChatViewPane extends ViewPane {
60
64
  try {
61
65
  this._widget.setVisible(false);
62
66
  this.updateModel(model);
63
- this.didProviderRegistrationFail = false;
67
+ this.defaultParticipantRegistrationFailed = false;
64
68
  this.didUnregisterProvider = false;
65
69
  this._onDidChangeViewWelcomeState.fire();
66
70
  }
@@ -76,15 +80,16 @@ let ChatViewPane = class ChatViewPane extends ViewPane {
76
80
  }));
77
81
  }
78
82
  getActionsContext() {
79
- return {
80
- chatView: this
81
- };
83
+ return this.widget?.viewModel ? {
84
+ sessionId: this.widget.viewModel.sessionId,
85
+ $mid: 19
86
+ } : undefined;
82
87
  }
83
88
  updateModel(model, viewState) {
84
89
  this.modelDisposables.clear();
85
90
  model = model ?? (this.chatService.transferredSessionData?.sessionId
86
91
  ? this.chatService.getOrRestoreSession(this.chatService.transferredSessionData.sessionId)
87
- : this.chatService.startSession(ChatAgentLocation.Panel, CancellationToken.None));
92
+ : this.chatService.startSession(this.chatOptions.location, CancellationToken.None));
88
93
  if (!model) {
89
94
  throw ( new Error('Could not start chat session'));
90
95
  }
@@ -93,13 +98,13 @@ let ChatViewPane = class ChatViewPane extends ViewPane {
93
98
  }
94
99
  this.viewState.sessionId = model.sessionId;
95
100
  this._widget.setModel(model, { ...this.viewState });
101
+ this.updateActions();
96
102
  }
97
103
  shouldShowWelcome() {
98
- if (!this.chatAgentService.getContributedDefaultAgent(ChatAgentLocation.Panel)) {
99
- return true;
100
- }
101
104
  const noPersistedSessions = !this.chatService.hasSessions();
102
- return this.didUnregisterProvider || !this._widget?.viewModel && (noPersistedSessions || this.didProviderRegistrationFail) || !this.isInitialized;
105
+ const shouldShow = this.didUnregisterProvider || !this._widget?.viewModel && noPersistedSessions || this.defaultParticipantRegistrationFailed;
106
+ this.logService.trace(`ChatViewPane#shouldShowWelcome(${this.chatOptions.location}) = ${shouldShow}: didUnregister=${this.didUnregisterProvider} || noViewModel:${!this._widget?.viewModel} && noPersistedSessions=${noPersistedSessions} || defaultParticipantRegistrationFailed=${this.defaultParticipantRegistrationFailed}`);
107
+ return shouldShow;
103
108
  }
104
109
  getSessionId() {
105
110
  let sessionId;
@@ -115,14 +120,27 @@ let ChatViewPane = class ChatViewPane extends ViewPane {
115
120
  renderBody(parent) {
116
121
  try {
117
122
  super.renderBody(parent);
123
+ this._register(this.instantiationService.createInstance(ChatViewWelcomeController, parent, this, this.chatOptions.location));
118
124
  const scopedInstantiationService = this._register(this.instantiationService.createChild(( new ServiceCollection([IContextKeyService, this.scopedContextKeyService]))));
119
125
  const locationBasedColors = this.getLocationBasedColors();
120
- this._widget = this._register(scopedInstantiationService.createInstance(ChatWidget, ChatAgentLocation.Panel, { viewId: this.id }, { supportsFileReferences: true }, {
126
+ this._widget = this._register(scopedInstantiationService.createInstance(ChatWidget, this.chatOptions.location, { viewId: this.id }, {
127
+ autoScroll: this.chatOptions.location === ChatAgentLocation.EditingSession,
128
+ renderFollowups: this.chatOptions.location === ChatAgentLocation.Panel,
129
+ supportsFileReferences: true,
130
+ supportsAdditionalParticipants: this.chatOptions.location === ChatAgentLocation.Panel,
131
+ rendererOptions: {
132
+ renderCodeBlockPills: this.chatOptions.location === ChatAgentLocation.EditingSession,
133
+ renderTextEditsAsSummary: (uri) => {
134
+ return this.chatOptions.location === ChatAgentLocation.EditingSession;
135
+ },
136
+ },
137
+ enableImplicitContext: this.chatOptions.location === ChatAgentLocation.Panel
138
+ }, {
121
139
  listForeground: SIDE_BAR_FOREGROUND,
122
140
  listBackground: locationBasedColors.background,
123
141
  overlayBackground: locationBasedColors.overlayBackground,
124
142
  inputEditorBackground: locationBasedColors.background,
125
- resultEditorBackground: editorBackground
143
+ resultEditorBackground: editorBackground,
126
144
  }));
127
145
  this._register(this.onDidChangeBodyVisibility(visible => {
128
146
  this._widget.setVisible(visible);
@@ -130,13 +148,13 @@ let ChatViewPane = class ChatViewPane extends ViewPane {
130
148
  this._register(this._widget.onDidClear(() => this.clear()));
131
149
  this._widget.render(parent);
132
150
  const sessionId = this.getSessionId();
133
- const disposeListener = sessionId ? this._register(this.chatService.onDidDisposeSession((e) => {
151
+ const disposeListener = this._register(this.chatService.onDidDisposeSession((e) => {
134
152
  if (e.reason === 'initializationFailed') {
135
- this.didProviderRegistrationFail = true;
153
+ this.defaultParticipantRegistrationFailed = true;
136
154
  disposeListener?.dispose();
137
155
  this._onDidChangeViewWelcomeState.fire();
138
156
  }
139
- })) : undefined;
157
+ }));
140
158
  const model = sessionId ? this.chatService.getOrRestoreSession(sessionId) : undefined;
141
159
  this.updateModel(model);
142
160
  }
@@ -154,6 +172,7 @@ let ChatViewPane = class ChatViewPane extends ViewPane {
154
172
  }
155
173
  this.updateViewState();
156
174
  this.updateModel(undefined);
175
+ this.updateActions();
157
176
  }
158
177
  loadSession(sessionId, viewState) {
159
178
  if (this.widget.viewModel) {
@@ -183,26 +202,26 @@ let ChatViewPane = class ChatViewPane extends ViewPane {
183
202
  }
184
203
  updateViewState(viewState) {
185
204
  const newViewState = viewState ?? this._widget.getViewState();
186
- this.viewState.inputValue = newViewState.inputValue;
187
- this.viewState.inputState = newViewState.inputState;
188
- this.viewState.selectedLanguageModelId = newViewState.selectedLanguageModelId;
205
+ for (const [key, value] of Object.entries(newViewState)) {
206
+ this.viewState[key] = value;
207
+ }
189
208
  }
190
209
  };
191
210
  ChatViewPane = ( __decorate([
192
- ( __param(1, IKeybindingService)),
193
- ( __param(2, IContextMenuService)),
194
- ( __param(3, IConfigurationService)),
195
- ( __param(4, IContextKeyService)),
196
- ( __param(5, IViewDescriptorService)),
197
- ( __param(6, IInstantiationService)),
198
- ( __param(7, IOpenerService)),
199
- ( __param(8, IThemeService)),
200
- ( __param(9, ITelemetryService)),
201
- ( __param(10, IHoverService)),
202
- ( __param(11, IStorageService)),
203
- ( __param(12, IChatService)),
204
- ( __param(13, IChatAgentService)),
205
- ( __param(14, ILogService))
211
+ ( __param(2, IKeybindingService)),
212
+ ( __param(3, IContextMenuService)),
213
+ ( __param(4, IConfigurationService)),
214
+ ( __param(5, IContextKeyService)),
215
+ ( __param(6, IViewDescriptorService)),
216
+ ( __param(7, IInstantiationService)),
217
+ ( __param(8, IOpenerService)),
218
+ ( __param(9, IThemeService)),
219
+ ( __param(10, ITelemetryService)),
220
+ ( __param(11, IHoverService)),
221
+ ( __param(12, IStorageService)),
222
+ ( __param(13, IChatService)),
223
+ ( __param(14, IChatAgentService)),
224
+ ( __param(15, ILogService))
206
225
  ], ChatViewPane));
207
226
 
208
- export { CHAT_SIDEBAR_PANEL_ID, ChatViewPane };
227
+ export { CHAT_EDITING_SIDEBAR_PANEL_ID, CHAT_SIDEBAR_PANEL_ID, ChatViewPane };
@@ -16,12 +16,12 @@ import 'vscode/vscode/vs/platform/theme/common/colors/miscColors';
16
16
  import 'vscode/vscode/vs/platform/theme/common/colors/quickpickColors';
17
17
  import 'vscode/vscode/vs/platform/theme/common/colors/searchColors';
18
18
  import { IThemeService } from 'vscode/vscode/vs/platform/theme/common/themeService.service';
19
- import { ChatWidget } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chatWidget';
20
- import { dynamicVariableDecorationType } from 'vscode/vscode/vs/workbench/contrib/chat/browser/contrib/chatDynamicVariables';
19
+ import { ChatWidget } from '@codingame/monaco-vscode-chat-extensions-notebook-common/vscode/vs/workbench/contrib/chat/browser/chatWidget';
20
+ import { dynamicVariableDecorationType } from '@codingame/monaco-vscode-chat-extensions-notebook-common/vscode/vs/workbench/contrib/chat/browser/contrib/chatDynamicVariables';
21
21
  import { IChatAgentService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents.service';
22
- import { chatSlashCommandForeground, chatSlashCommandBackground } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatColors';
23
- import { ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashCommandPart, ChatRequestTextPart, ChatRequestVariablePart, ChatRequestToolPart, chatAgentLeader, chatSubcommandLeader } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatParserTypes';
24
- import { ChatRequestParser } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatRequestParser';
22
+ import { chatSlashCommandForeground, chatSlashCommandBackground } from '@codingame/monaco-vscode-chat-extensions-interactive-notebook-quickaccess-search-terminal-common/vscode/vs/workbench/contrib/chat/common/chatColors';
23
+ import { ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashCommandPart, ChatRequestTextPart, ChatRequestVariablePart, ChatRequestToolPart, chatAgentLeader, chatSubcommandLeader } from '@codingame/monaco-vscode-chat-extensions-interactive-notebook-quickaccess-search-terminal-common/vscode/vs/workbench/contrib/chat/common/chatParserTypes';
24
+ import { ChatRequestParser } from '@codingame/monaco-vscode-chat-extensions-notebook-common/vscode/vs/workbench/contrib/chat/common/chatRequestParser';
25
25
 
26
26
  const decorationDescription = 'chat';
27
27
  const placeholderDecorationType = 'chat-session-detail';
@@ -5,9 +5,9 @@ import { RenderedHoverParts, HoverParticipantRegistry } from 'vscode/vscode/vs/e
5
5
  import { ICommandService } from 'vscode/vscode/vs/platform/commands/common/commands.service';
6
6
  import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
7
7
  import { IChatWidgetService } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chat.service';
8
- import { ChatAgentHover, getChatAgentHoverOptions } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chatAgentHover';
8
+ import { ChatAgentHover, getChatAgentHoverOptions } from '@codingame/monaco-vscode-chat-extensions-interactive-notebook-quickaccess-search-terminal-common/vscode/vs/workbench/contrib/chat/browser/chatAgentHover';
9
9
  import { ChatEditorHoverWrapper } from './editorHoverWrapper.js';
10
- import { extractAgentAndCommand } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatParserTypes';
10
+ import { extractAgentAndCommand } from '@codingame/monaco-vscode-chat-extensions-interactive-notebook-quickaccess-search-terminal-common/vscode/vs/workbench/contrib/chat/common/chatParserTypes';
11
11
  import { localize } from 'vscode/vscode/vs/nls';
12
12
 
13
13
  let ChatAgentHoverParticipant = class ChatAgentHoverParticipant {
@@ -61,7 +61,7 @@ let ChatAgentHoverParticipant = class ChatAgentHoverParticipant {
61
61
  );
62
62
  }
63
63
  getAccessibleContent(hoverPart) {
64
- return ( localize(7381, 'There is a chat agent hover part here.'));
64
+ return ( localize(7638, 'There is a chat agent hover part here.'));
65
65
  }
66
66
  };
67
67
  ChatAgentHoverParticipant = ( (__decorate([
@@ -1,4 +1,5 @@
1
1
  import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
2
+ import { renderStringAsPlaintext } from 'vscode/vscode/vs/base/browser/markdownRenderer';
2
3
  import { RunOnceScheduler } from 'vscode/vscode/vs/base/common/async';
3
4
  import { CancellationError } from 'vscode/vscode/vs/base/common/errors';
4
5
  import { Emitter } from 'vscode/vscode/vs/base/common/event';
@@ -6,16 +7,18 @@ import { Iterable } from 'vscode/vscode/vs/base/common/iterator';
6
7
  import { Disposable, toDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
7
8
  import { localize } from 'vscode/vscode/vs/nls';
8
9
  import { IContextKeyService } from 'vscode/vscode/vs/platform/contextkey/common/contextkey.service';
10
+ import { IDialogService } from 'vscode/vscode/vs/platform/dialogs/common/dialogs.service';
9
11
  import { IExtensionService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions.service';
10
- import { ChatToolInvocation } from './chatProgressTypes/chatToolInvocation.js';
12
+ import { ChatToolInvocation } from '../common/chatProgressTypes/chatToolInvocation.js';
11
13
  import { IChatService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatService.service';
12
14
 
13
15
  let LanguageModelToolsService = class LanguageModelToolsService extends Disposable {
14
- constructor(_extensionService, _contextKeyService, _chatService) {
16
+ constructor(_extensionService, _contextKeyService, _chatService, _dialogService) {
15
17
  super();
16
18
  this._extensionService = _extensionService;
17
19
  this._contextKeyService = _contextKeyService;
18
20
  this._chatService = _chatService;
21
+ this._dialogService = _dialogService;
19
22
  this._onDidChangeTools = ( (new Emitter()));
20
23
  this.onDidChangeTools = this._onDidChangeTools.event;
21
24
  this._onDidChangeToolsScheduler = ( (new RunOnceScheduler(() => this._onDidChangeTools.fire(), 750)));
@@ -31,9 +34,6 @@ let LanguageModelToolsService = class LanguageModelToolsService extends Disposab
31
34
  if (( (this._tools.has(toolData.id)))) {
32
35
  throw ( (new Error(`Tool "${toolData.id}" is already registered.`)));
33
36
  }
34
- if (!toolData.supportedContentTypes.includes('text/plain')) {
35
- toolData.supportedContentTypes.push('text/plain');
36
- }
37
37
  this._tools.set(toolData.id, { data: toolData });
38
38
  this._onDidChangeToolsScheduler.schedule();
39
39
  toolData.when?.keys().forEach(key => this._toolContextKeys.add(key));
@@ -80,7 +80,7 @@ let LanguageModelToolsService = class LanguageModelToolsService extends Disposab
80
80
  }
81
81
  getToolByName(name) {
82
82
  for (const toolData of this.getTools()) {
83
- if (toolData.name === name) {
83
+ if (toolData.toolReferenceName === name) {
84
84
  return toolData;
85
85
  }
86
86
  }
@@ -102,50 +102,47 @@ let LanguageModelToolsService = class LanguageModelToolsService extends Disposab
102
102
  if (dto.context) {
103
103
  const model = this._chatService.getSession(dto.context?.sessionId);
104
104
  const request = model.getRequests().at(-1);
105
- const participantName = request.response?.agent?.fullName ?? '';
106
- const getConfirmationMessages = async () => {
107
- if (!tool.data.requiresConfirmation) {
108
- return undefined;
109
- }
110
- return (await tool.impl.provideToolConfirmationMessages(participantName, dto.parameters, token)) ?? {
111
- title: ( localize(3185, "Use {0}?", `"${tool.data.displayName ?? tool.data.id}"`)),
112
- message: ( localize(
113
- 3186,
114
- "{0} will use {1}.",
115
- participantName,
116
- `"${tool.data.displayName ?? tool.data.id}"`
117
- )),
118
- };
119
- };
120
- const [invocationMessage, confirmationMessages] = await Promise.all([
121
- tool.impl.provideToolInvocationMessage(dto.parameters, token),
122
- getConfirmationMessages()
123
- ]);
124
- const defaultMessage = ( localize(3187, "Using {0}", `"${tool.data.displayName ?? tool.data.id}"`));
125
- toolInvocation = ( (new ChatToolInvocation(invocationMessage ?? defaultMessage, confirmationMessages)));
105
+ const prepared = tool.impl.prepareToolInvocation ?
106
+ await tool.impl.prepareToolInvocation(dto.parameters, token)
107
+ : undefined;
108
+ const defaultMessage = ( localize(2733, "Using {0}", `"${tool.data.displayName}"`));
109
+ const invocationMessage = prepared?.invocationMessage ?? defaultMessage;
110
+ toolInvocation = ( (new ChatToolInvocation(invocationMessage, prepared?.confirmationMessages)));
126
111
  token.onCancellationRequested(() => {
127
112
  toolInvocation.confirmed.complete(false);
128
113
  });
129
114
  model.acceptResponseProgress(request, toolInvocation);
130
- if (tool.data.requiresConfirmation) {
115
+ if (prepared?.confirmationMessages) {
131
116
  const userConfirmed = await toolInvocation.confirmed.p;
132
117
  if (!userConfirmed) {
133
118
  throw ( (new CancellationError()));
134
119
  }
135
120
  }
136
121
  }
122
+ else {
123
+ const prepared = tool.impl.prepareToolInvocation ?
124
+ await tool.impl.prepareToolInvocation(dto.parameters, token)
125
+ : undefined;
126
+ if (prepared?.confirmationMessages) {
127
+ const result = await this._dialogService.confirm({ message: prepared.confirmationMessages.title, detail: renderStringAsPlaintext(prepared.confirmationMessages.message) });
128
+ if (!result.confirmed) {
129
+ throw ( (new CancellationError()));
130
+ }
131
+ }
132
+ }
137
133
  try {
138
- return tool.impl.invoke(dto, countTokens, token);
134
+ return await tool.impl.invoke(dto, countTokens, token);
139
135
  }
140
136
  finally {
141
- toolInvocation?.complete();
137
+ toolInvocation?.isCompleteDeferred.complete();
142
138
  }
143
139
  }
144
140
  };
145
141
  LanguageModelToolsService = ( (__decorate([
146
142
  ( (__param(0, IExtensionService))),
147
143
  ( (__param(1, IContextKeyService))),
148
- ( (__param(2, IChatService)))
144
+ ( (__param(2, IChatService))),
145
+ ( (__param(3, IDialogService)))
149
146
  ], LanguageModelToolsService)));
150
147
 
151
148
  export { LanguageModelToolsService };
@@ -0,0 +1,75 @@
1
+ import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
2
+ import { MarkdownString } from 'vscode/vscode/vs/base/common/htmlContent';
3
+ import { ThemeIcon } from 'vscode/vscode/vs/base/common/themables';
4
+ import { localize } from 'vscode/vscode/vs/nls';
5
+ import { ContextKeyExpr } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
6
+ import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service';
7
+ import { Registry } from 'vscode/vscode/vs/platform/registry/common/platform';
8
+ import { checkProposedApiEnabled } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions';
9
+ import { ExtensionsRegistry } from 'vscode/vscode/vs/workbench/services/extensions/common/extensionsRegistry';
10
+
11
+ const chatViewsWelcomeExtensionPoint = ExtensionsRegistry.registerExtensionPoint({
12
+ extensionPoint: 'chatViewsWelcome',
13
+ jsonSchema: {
14
+ description: ( localize(7639, 'Contributes a welcome message to a chat view')),
15
+ type: 'array',
16
+ items: {
17
+ additionalProperties: false,
18
+ type: 'object',
19
+ properties: {
20
+ icon: {
21
+ type: 'string',
22
+ description: ( localize(7640, 'The icon for the welcome message.')),
23
+ },
24
+ title: {
25
+ type: 'string',
26
+ description: ( localize(7641, 'The title of the welcome message.')),
27
+ },
28
+ content: {
29
+ type: 'string',
30
+ description: ( localize(
31
+ 7642,
32
+ 'The content of the welcome message. The first command link will be rendered as a button.'
33
+ )),
34
+ },
35
+ when: {
36
+ type: 'string',
37
+ description: ( localize(7643, 'Condition when the welcome message is shown.')),
38
+ }
39
+ }
40
+ },
41
+ required: ['icon', 'title', 'contents', 'when'],
42
+ }
43
+ });
44
+ let ChatViewsWelcomeHandler = class ChatViewsWelcomeHandler {
45
+ static { this.ID = 'workbench.contrib.chatViewsWelcomeHandler'; }
46
+ constructor(logService) {
47
+ this.logService = logService;
48
+ chatViewsWelcomeExtensionPoint.setHandler((extensions, delta) => {
49
+ for (const extension of delta.added) {
50
+ for (const providerDescriptor of extension.value) {
51
+ checkProposedApiEnabled(extension.description, 'chatParticipantPrivate');
52
+ const when = ContextKeyExpr.deserialize(providerDescriptor.when);
53
+ if (!when) {
54
+ this.logService.error(`Could not deserialize 'when' clause for chatViewsWelcome contribution: ${providerDescriptor.when}`);
55
+ continue;
56
+ }
57
+ const descriptor = {
58
+ ...providerDescriptor,
59
+ when,
60
+ icon: ThemeIcon.fromString(providerDescriptor.icon),
61
+ content: ( (new MarkdownString(providerDescriptor.content, { isTrusted: true }))),
62
+ };
63
+ ( (Registry.as(
64
+ "workbench.registry.chat.viewsWelcome"
65
+ ))).register(descriptor);
66
+ }
67
+ }
68
+ });
69
+ }
70
+ };
71
+ ChatViewsWelcomeHandler = ( (__decorate([
72
+ ( (__param(0, ILogService)))
73
+ ], ChatViewsWelcomeHandler)));
74
+
75
+ export { ChatViewsWelcomeHandler };
@@ -1,3 +1,9 @@
1
+ import { ResourceMap } from 'vscode/vscode/vs/base/common/map';
2
+ import { splitLinesIncludeSeparators } from 'vscode/vscode/vs/base/common/strings';
3
+ import { isString } from 'vscode/vscode/vs/base/common/types';
4
+ import { URI } from 'vscode/vscode/vs/base/common/uri';
5
+ import { isLocation } from 'vscode/vscode/vs/editor/common/languages';
6
+
1
7
  class CodeMapperService {
2
8
  constructor() {
3
9
  this.providers = [];
@@ -22,6 +28,119 @@ class CodeMapperService {
22
28
  }
23
29
  return undefined;
24
30
  }
31
+ async mapCodeFromResponse(responseModel, response, token) {
32
+ const fenceLanguageRegex = /^`{3,}/;
33
+ const codeBlocks = [];
34
+ const currentBlock = [];
35
+ const markdownBeforeBlock = [];
36
+ let currentBlockUri = undefined;
37
+ let fence = undefined;
38
+ for (const lineOrUri of iterateLinesOrUris(responseModel)) {
39
+ if (isString(lineOrUri)) {
40
+ const fenceLanguageIdMatch = lineOrUri.match(fenceLanguageRegex);
41
+ if (fenceLanguageIdMatch) {
42
+ if (fence !== undefined && fenceLanguageIdMatch[0] === fence) {
43
+ fence = undefined;
44
+ if (currentBlockUri) {
45
+ codeBlocks.push({ code: currentBlock.join(''), resource: currentBlockUri, markdownBeforeBlock: markdownBeforeBlock.join('') });
46
+ currentBlock.length = 0;
47
+ markdownBeforeBlock.length = 0;
48
+ currentBlockUri = undefined;
49
+ }
50
+ }
51
+ else {
52
+ fence = fenceLanguageIdMatch[0];
53
+ }
54
+ }
55
+ else {
56
+ if (fence !== undefined) {
57
+ currentBlock.push(lineOrUri);
58
+ }
59
+ else {
60
+ markdownBeforeBlock.push(lineOrUri);
61
+ }
62
+ }
63
+ }
64
+ else {
65
+ currentBlockUri = lineOrUri;
66
+ }
67
+ }
68
+ const conversation = [];
69
+ for (const request of responseModel.session.getRequests()) {
70
+ const response = request.response;
71
+ if (!response || response === responseModel) {
72
+ break;
73
+ }
74
+ conversation.push({
75
+ type: 'request',
76
+ message: request.message.text
77
+ });
78
+ conversation.push({
79
+ type: 'response',
80
+ message: response.response.getMarkdown(),
81
+ result: response.result,
82
+ references: getReferencesAsDocumentContext(response.contentReferences)
83
+ });
84
+ }
85
+ return this.mapCode({ codeBlocks, conversation }, response, token);
86
+ }
87
+ }
88
+ function iterateLinesOrUris(responseModel) {
89
+ return {
90
+ *[Symbol.iterator]() {
91
+ let lastIncompleteLine = undefined;
92
+ for (const part of responseModel.response.value) {
93
+ if (part.kind === 'markdownContent' || part.kind === 'markdownVuln') {
94
+ const lines = splitLinesIncludeSeparators(part.content.value);
95
+ if (lines.length > 0) {
96
+ if (lastIncompleteLine !== undefined) {
97
+ lines[0] = lastIncompleteLine + lines[0];
98
+ }
99
+ lastIncompleteLine = isLineIncomplete(lines[lines.length - 1]) ? lines.pop() : undefined;
100
+ for (const line of lines) {
101
+ yield line;
102
+ }
103
+ }
104
+ }
105
+ else if (part.kind === 'codeblockUri') {
106
+ yield part.uri;
107
+ }
108
+ }
109
+ if (lastIncompleteLine !== undefined) {
110
+ yield lastIncompleteLine;
111
+ }
112
+ }
113
+ };
114
+ }
115
+ function isLineIncomplete(line) {
116
+ const lastChar = line.charCodeAt(line.length - 1);
117
+ return lastChar !== 10 && lastChar !== 13 ;
118
+ }
119
+ function getReferencesAsDocumentContext(res) {
120
+ const map = ( new ResourceMap());
121
+ for (const r of res) {
122
+ let uri;
123
+ let range;
124
+ if (URI.isUri(r.reference)) {
125
+ uri = r.reference;
126
+ }
127
+ else if (isLocation(r.reference)) {
128
+ uri = r.reference.uri;
129
+ range = r.reference.range;
130
+ }
131
+ if (uri) {
132
+ const item = map.get(uri);
133
+ if (item) {
134
+ if (range) {
135
+ item.ranges.push(range);
136
+ }
137
+ }
138
+ else {
139
+ map.set(uri, { uri, version: -1, ranges: range ? [range] : [] });
140
+ }
141
+ }
142
+ }
143
+ return [...( map.values())];
25
144
  }
26
145
 
27
- export { CodeMapperService };
146
+ export { CodeMapperService, getReferencesAsDocumentContext };
@@ -4,6 +4,9 @@ class ChatToolInvocation {
4
4
  get isComplete() {
5
5
  return this._isComplete;
6
6
  }
7
+ get isCompleteDeferred() {
8
+ return this._isCompleteDeferred;
9
+ }
7
10
  get isCanceled() {
8
11
  return this._isCanceled;
9
12
  }
@@ -18,6 +21,7 @@ class ChatToolInvocation {
18
21
  this._confirmationMessages = _confirmationMessages;
19
22
  this.kind = 'toolInvocation';
20
23
  this._isComplete = false;
24
+ this._isCompleteDeferred = ( new DeferredPromise());
21
25
  this._confirmDeferred = ( new DeferredPromise());
22
26
  if (!_confirmationMessages) {
23
27
  this._isConfirmed = true;
@@ -27,15 +31,12 @@ class ChatToolInvocation {
27
31
  this._isConfirmed = confirmed;
28
32
  this._confirmationMessages = undefined;
29
33
  if (!confirmed) {
30
- this.complete();
34
+ this._isCompleteDeferred.complete();
31
35
  }
32
36
  });
33
- }
34
- complete() {
35
- if (this._isComplete) {
36
- throw ( new Error('Invocation is already complete.'));
37
- }
38
- this._isComplete = true;
37
+ this._isCompleteDeferred.p.then(() => {
38
+ this._isComplete = true;
39
+ });
39
40
  }
40
41
  get confirmationMessages() {
41
42
  return this._confirmationMessages;
@@ -44,7 +45,8 @@ class ChatToolInvocation {
44
45
  return {
45
46
  kind: 'toolInvocationSerialized',
46
47
  invocationMessage: this.invocationMessage,
47
- isConfirmed: this._isConfirmed ?? false
48
+ isConfirmed: this._isConfirmed ?? false,
49
+ isComplete: this._isComplete,
48
50
  };
49
51
  }
50
52
  }