@codingame/monaco-vscode-chat-service-override 6.0.3 → 7.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 (19) hide show
  1. package/chat.js +4 -1
  2. package/package.json +2 -2
  3. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.js +61 -11
  4. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.js +62 -4
  5. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatDeveloperActions.js +28 -0
  6. package/vscode/src/vs/workbench/contrib/chat/browser/chat.contribution.js +25 -4
  7. package/vscode/src/vs/workbench/contrib/chat/browser/chatParticipantContributions.js +12 -16
  8. package/vscode/src/vs/workbench/contrib/chat/browser/chatVariables.js +1 -1
  9. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatContextAttachments.js +10 -1
  10. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputCompletions.js +23 -14
  11. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.js +1 -4
  12. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorHover.js +87 -0
  13. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/editorHoverWrapper.js +31 -0
  14. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/media/editorHoverWrapper.css.js +6 -0
  15. package/vscode/src/vs/workbench/contrib/chat/common/chatServiceImpl.js +6 -6
  16. package/vscode/src/vs/workbench/contrib/chat/common/languageModelToolsService.js +60 -0
  17. package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsContribution.js +93 -0
  18. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.js +74 -6
  19. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.js +3 -1
package/chat.js CHANGED
@@ -24,6 +24,8 @@ import { InlineChatSessionServiceImpl } from 'vscode/vscode/vs/workbench/contrib
24
24
  import { LanguageModelStatsService } from './vscode/src/vs/workbench/contrib/chat/common/languageModelStats.js';
25
25
  import './vscode/src/vs/workbench/contrib/chat/browser/chat.contribution.js';
26
26
  import './vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.js';
27
+ import { ILanguageModelToolsService } from 'vscode/vscode/vs/workbench/contrib/chat/common/languageModelToolsService.service';
28
+ import { LanguageModelToolsService } from './vscode/src/vs/workbench/contrib/chat/common/languageModelToolsService.js';
27
29
 
28
30
  function getServiceOverride() {
29
31
  return {
@@ -40,7 +42,8 @@ function getServiceOverride() {
40
42
  [( IInlineChatSavingService.toString())]: new SyncDescriptor(InlineChatSavingServiceImpl, [], true),
41
43
  [( IChatCodeBlockContextProviderService.toString())]: new SyncDescriptor(ChatCodeBlockContextProviderService, [], true),
42
44
  [( ILanguageModelStatsService.toString())]: new SyncDescriptor(LanguageModelStatsService, [], true),
43
- [( IChatAgentNameService.toString())]: new SyncDescriptor(ChatAgentNameService, [], true)
45
+ [( IChatAgentNameService.toString())]: new SyncDescriptor(ChatAgentNameService, [], true),
46
+ [( ILanguageModelToolsService.toString())]: new SyncDescriptor(LanguageModelToolsService, [], true)
44
47
  };
45
48
  }
46
49
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codingame/monaco-vscode-chat-service-override",
3
- "version": "6.0.3",
3
+ "version": "7.0.0",
4
4
  "keywords": [],
5
5
  "author": {
6
6
  "name": "CodinGame",
@@ -26,6 +26,6 @@
26
26
  }
27
27
  },
28
28
  "dependencies": {
29
- "vscode": "npm:@codingame/monaco-vscode-api@6.0.3"
29
+ "vscode": "npm:@codingame/monaco-vscode-api@7.0.0"
30
30
  }
31
31
  }
@@ -9,12 +9,16 @@ import { EditorContextKeys } from 'vscode/vscode/vs/editor/common/editorContextK
9
9
  import { ILanguageService } from 'vscode/vscode/vs/editor/common/languages/language';
10
10
  import { ILanguageFeaturesService } from 'vscode/vscode/vs/editor/common/services/languageFeatures';
11
11
  import { CopyAction } from 'vscode/vscode/vs/editor/contrib/clipboard/browser/clipboard';
12
- import { localize2WithPath } from 'vscode/vscode/vs/nls';
12
+ import { localize2WithPath, localizeWithPath } from 'vscode/vscode/vs/nls';
13
13
  import { Action2, registerAction2, MenuId } from 'vscode/vscode/vs/platform/actions/common/actions';
14
14
  import { IClipboardService } from 'vscode/vscode/vs/platform/clipboard/common/clipboardService.service';
15
15
  import { ContextKeyExpr } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
16
16
  import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
17
17
  import { KeybindingWeight } from 'vscode/vscode/vs/platform/keybinding/common/keybindingsRegistry';
18
+ import 'vscode/vscode/vs/platform/notification/common/notification';
19
+ import { INotificationService } from 'vscode/vscode/vs/platform/notification/common/notification.service';
20
+ import { ProgressLocation } from 'vscode/vscode/vs/platform/progress/common/progress';
21
+ import { IProgressService } from 'vscode/vscode/vs/platform/progress/common/progress.service';
18
22
  import { TerminalLocation } from 'vscode/vscode/vs/platform/terminal/common/terminal';
19
23
  import { accessibleViewInCodeBlock } from 'vscode/vscode/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
20
24
  import { CHAT_CATEGORY } from 'vscode/vscode/vs/workbench/contrib/chat/browser/actions/chatActions';
@@ -29,6 +33,7 @@ import { NOTEBOOK_EDITOR_ID, CellKind } from 'vscode/vscode/vs/workbench/contrib
29
33
  import { ITerminalService, ITerminalEditorService, ITerminalGroupService } from 'vscode/vscode/vs/workbench/contrib/terminal/browser/terminal.service';
30
34
  import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/common/editorService.service';
31
35
  import { ITextFileService } from 'vscode/vscode/vs/workbench/services/textfile/common/textfiles.service';
36
+ import Severity$1 from 'vscode/vscode/vs/base/common/severity';
32
37
 
33
38
  const _moduleId = "vs/workbench/contrib/chat/browser/actions/chatCodeblockActions";
34
39
  function isCodeBlockActionContext(thing) {
@@ -147,7 +152,7 @@ function registerChatCodeBlockActions() {
147
152
  constructor() {
148
153
  super({
149
154
  id: 'workbench.action.chat.insertCodeBlock',
150
- title: ( localize2WithPath(_moduleId, 1, "Insert at Cursor")),
155
+ title: ( localize2WithPath(_moduleId, 1, "Apply in Editor")),
151
156
  precondition: CONTEXT_CHAT_ENABLED,
152
157
  f1: true,
153
158
  category: CHAT_CATEGORY,
@@ -218,10 +223,11 @@ function registerChatCodeBlockActions() {
218
223
  this.notifyUserAction(accessor, codeBlockActionContext);
219
224
  const bulkEditService = accessor.get(IBulkEditService);
220
225
  const codeEditorService = accessor.get(ICodeEditorService);
226
+ const progressService = accessor.get(IProgressService);
227
+ const notificationService = accessor.get(INotificationService);
221
228
  const mappedEditsProviders = accessor.get(ILanguageFeaturesService).mappedEditsProvider.ordered(activeModel);
222
229
  let mappedEdits = null;
223
230
  if (mappedEditsProviders.length > 0) {
224
- const mostRelevantProvider = mappedEditsProviders[0];
225
231
  const docRefs = [];
226
232
  if (codeEditor.hasModel()) {
227
233
  const model = codeEditor.getModel();
@@ -243,9 +249,27 @@ function registerChatCodeBlockActions() {
243
249
  docRefs.push(usedDocuments);
244
250
  }
245
251
  const cancellationTokenSource = ( (new CancellationTokenSource()));
246
- mappedEdits = await mostRelevantProvider.provideMappedEdits(activeModel, [codeBlockActionContext.code], { documents: docRefs }, cancellationTokenSource.token);
252
+ try {
253
+ mappedEdits = await progressService.withProgress({ location: ProgressLocation.Notification, delay: 500, sticky: true, cancellable: true }, async (progress) => {
254
+ progress.report({ message: ( localizeWithPath(_moduleId, 2, "Applying code block...")) });
255
+ for (const provider of mappedEditsProviders) {
256
+ const mappedEdits = await provider.provideMappedEdits(activeModel, [codeBlockActionContext.code], { documents: docRefs }, cancellationTokenSource.token);
257
+ if (mappedEdits) {
258
+ return mappedEdits;
259
+ }
260
+ }
261
+ return null;
262
+ }, () => cancellationTokenSource.cancel());
263
+ }
264
+ catch (e) {
265
+ notificationService.notify({ severity: Severity$1.Error, message: ( localizeWithPath(_moduleId, 3, "Failed to apply code block: {0}", e.message)) });
266
+ }
267
+ finally {
268
+ cancellationTokenSource.dispose();
269
+ }
247
270
  }
248
271
  if (mappedEdits) {
272
+ console.log('Mapped edits:', mappedEdits);
249
273
  await bulkEditService.apply(mappedEdits);
250
274
  }
251
275
  else {
@@ -280,7 +304,7 @@ function registerChatCodeBlockActions() {
280
304
  constructor() {
281
305
  super({
282
306
  id: 'workbench.action.chat.insertIntoNewFile',
283
- title: ( localize2WithPath(_moduleId, 2, "Insert into New File")),
307
+ title: ( localize2WithPath(_moduleId, 4, "Insert into New File")),
284
308
  precondition: CONTEXT_CHAT_ENABLED,
285
309
  f1: true,
286
310
  category: CHAT_CATEGORY,
@@ -328,7 +352,7 @@ function registerChatCodeBlockActions() {
328
352
  constructor() {
329
353
  super({
330
354
  id: 'workbench.action.chat.runInTerminal',
331
- title: ( localize2WithPath(_moduleId, 3, "Insert into Terminal")),
355
+ title: ( localize2WithPath(_moduleId, 5, "Insert into Terminal")),
332
356
  precondition: CONTEXT_CHAT_ENABLED,
333
357
  f1: true,
334
358
  category: CHAT_CATEGORY,
@@ -413,7 +437,7 @@ function registerChatCodeBlockActions() {
413
437
  const currentResponse = curCodeBlockInfo ?
414
438
  curCodeBlockInfo.element :
415
439
  (focusedResponse ?? widget.viewModel?.getItems().reverse().find((item) => isResponseVM(item)));
416
- if (!currentResponse) {
440
+ if (!currentResponse || !isResponseVM(currentResponse)) {
417
441
  return;
418
442
  }
419
443
  widget.reveal(currentResponse);
@@ -427,7 +451,7 @@ function registerChatCodeBlockActions() {
427
451
  constructor() {
428
452
  super({
429
453
  id: 'workbench.action.chat.nextCodeBlock',
430
- title: ( localize2WithPath(_moduleId, 4, "Next Code Block")),
454
+ title: ( localize2WithPath(_moduleId, 6, "Next Code Block")),
431
455
  keybinding: {
432
456
  primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageDown,
433
457
  mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageDown, },
@@ -447,7 +471,7 @@ function registerChatCodeBlockActions() {
447
471
  constructor() {
448
472
  super({
449
473
  id: 'workbench.action.chat.previousCodeBlock',
450
- title: ( localize2WithPath(_moduleId, 5, "Previous Code Block")),
474
+ title: ( localize2WithPath(_moduleId, 7, "Previous Code Block")),
451
475
  keybinding: {
452
476
  primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageUp,
453
477
  mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageUp, },
@@ -503,7 +527,7 @@ function registerChatCodeCompareBlockActions() {
503
527
  constructor() {
504
528
  super({
505
529
  id: 'workbench.action.chat.applyCompareEdits',
506
- title: ( localize2WithPath(_moduleId, 6, "Apply Edits")),
530
+ title: ( localize2WithPath(_moduleId, 8, "Apply Edits")),
507
531
  f1: false,
508
532
  category: CHAT_CATEGORY,
509
533
  icon: Codicon.check,
@@ -513,7 +537,8 @@ function registerChatCodeCompareBlockActions() {
513
537
  ))),
514
538
  menu: {
515
539
  id: MenuId.ChatCompareBlock,
516
- group: 'navigation'
540
+ group: 'navigation',
541
+ order: 1,
517
542
  }
518
543
  });
519
544
  }
@@ -528,6 +553,31 @@ function registerChatCodeCompareBlockActions() {
528
553
  });
529
554
  }
530
555
  });
556
+ registerAction2(class DiscardEditsCompareBlockAction extends ChatCompareCodeBlockAction {
557
+ constructor() {
558
+ super({
559
+ id: 'workbench.action.chat.discardCompareEdits',
560
+ title: ( localize2WithPath(_moduleId, 9, "Discard Edits")),
561
+ f1: false,
562
+ category: CHAT_CATEGORY,
563
+ icon: Codicon.trash,
564
+ precondition: ( (ContextKeyExpr.and(
565
+ EditorContextKeys.hasChanges,
566
+ (CONTEXT_CHAT_EDIT_APPLIED.negate())
567
+ ))),
568
+ menu: {
569
+ id: MenuId.ChatCompareBlock,
570
+ group: 'navigation',
571
+ order: 2,
572
+ }
573
+ });
574
+ }
575
+ async runWithContext(accessor, context) {
576
+ const instaService = accessor.get(IInstantiationService);
577
+ const editor = instaService.createInstance(DefaultChatTextEditor);
578
+ editor.discard(context.element, context.edit);
579
+ }
580
+ });
531
581
  }
532
582
 
533
583
  export { isCodeBlockActionContext, isCodeCompareBlockActionContext, registerChatCodeBlockActions, registerChatCodeCompareBlockActions };
@@ -21,17 +21,64 @@ import { IChatVariablesService } from 'vscode/vscode/vs/workbench/contrib/chat/c
21
21
  import { AnythingQuickAccessProvider } from 'vscode/vscode/vs/workbench/contrib/search/browser/anythingQuickAccess';
22
22
  import { SymbolsQuickAccessProvider } from 'vscode/vscode/vs/workbench/contrib/search/browser/symbolsQuickAccess';
23
23
  import { ContextKeyExpr } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
24
+ import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/common/editorService.service';
25
+ import { EditorType } from 'vscode/vscode/vs/editor/common/editorCommon';
26
+ import { compare } from 'vscode/vscode/vs/base/common/strings';
24
27
 
25
28
  const _moduleId = "vs/workbench/contrib/chat/browser/actions/chatContextActions";
26
29
  function registerChatContextActions() {
27
30
  registerAction2(AttachContextAction);
31
+ registerAction2(AttachFileAction);
32
+ registerAction2(AttachSelectionAction);
33
+ }
34
+ class AttachFileAction extends Action2 {
35
+ static { this.ID = 'workbench.action.chat.attachFile'; }
36
+ constructor() {
37
+ super({
38
+ id: AttachFileAction.ID,
39
+ title: ( localize2WithPath(_moduleId, 0, "Attach File")),
40
+ category: CHAT_CATEGORY,
41
+ f1: false
42
+ });
43
+ }
44
+ async run(accessor, ...args) {
45
+ const variablesService = accessor.get(IChatVariablesService);
46
+ const textEditorService = accessor.get(IEditorService);
47
+ const activeUri = textEditorService.activeEditor?.resource;
48
+ if (textEditorService.activeTextEditorControl?.getEditorType() === EditorType.ICodeEditor && activeUri && [Schemas.file, Schemas.vscodeRemote].includes(activeUri.scheme)) {
49
+ variablesService.attachContext('file', activeUri, ChatAgentLocation.Panel);
50
+ }
51
+ }
52
+ }
53
+ class AttachSelectionAction extends Action2 {
54
+ static { this.ID = 'workbench.action.chat.attachSelection'; }
55
+ constructor() {
56
+ super({
57
+ id: AttachSelectionAction.ID,
58
+ title: ( localize2WithPath(_moduleId, 1, "Add Selection to Chat")),
59
+ category: CHAT_CATEGORY,
60
+ f1: false
61
+ });
62
+ }
63
+ async run(accessor, ...args) {
64
+ const variablesService = accessor.get(IChatVariablesService);
65
+ const textEditorService = accessor.get(IEditorService);
66
+ const activeEditor = textEditorService.activeTextEditorControl;
67
+ const activeUri = textEditorService.activeEditor?.resource;
68
+ if (textEditorService.activeTextEditorControl?.getEditorType() === EditorType.ICodeEditor && activeUri && [Schemas.file, Schemas.vscodeRemote].includes(activeUri.scheme)) {
69
+ const selection = activeEditor?.getSelection();
70
+ if (selection) {
71
+ variablesService.attachContext('file', { uri: activeUri, range: selection }, ChatAgentLocation.Panel);
72
+ }
73
+ }
74
+ }
28
75
  }
29
76
  class AttachContextAction extends Action2 {
30
77
  static { this.ID = 'workbench.action.chat.attachContext'; }
31
78
  constructor() {
32
79
  super({
33
80
  id: AttachContextAction.ID,
34
- title: ( localize2WithPath(_moduleId, 0, "Attach Context")),
81
+ title: ( localize2WithPath(_moduleId, 2, "Attach Context")),
35
82
  icon: Codicon.attach,
36
83
  category: CHAT_CATEGORY,
37
84
  keybinding: {
@@ -166,11 +213,22 @@ class AttachContextAction extends Action2 {
166
213
  }
167
214
  }
168
215
  quickPickItems.push({
169
- label: ( localizeWithPath(_moduleId, 1, '{0} Symbol...', `$(${Codicon.symbolField.id})`)),
216
+ label: ( localizeWithPath(_moduleId, 3, '{0} Symbol...', `$(${Codicon.symbolField.id})`)),
170
217
  icon: ThemeIcon.fromId(Codicon.symbolField.id),
171
218
  prefix: SymbolsQuickAccessProvider.PREFIX
172
219
  });
173
- this._show(quickInputService, commandService, widget, quickPickItems);
220
+ function extractTextFromIconLabel(label) {
221
+ if (!label) {
222
+ return '';
223
+ }
224
+ const match = label.match(/\$\([^\)]+\)\s*(.+)/);
225
+ return match ? match[1] : label;
226
+ }
227
+ this._show(quickInputService, commandService, widget, quickPickItems.sort(function (a, b) {
228
+ const first = extractTextFromIconLabel(a.label).toUpperCase();
229
+ const second = extractTextFromIconLabel(b.label).toUpperCase();
230
+ return compare(first, second);
231
+ }));
174
232
  }
175
233
  _show(quickInputService, commandService, widget, quickPickItems, query = '') {
176
234
  quickInputService.quickAccess.show(query, {
@@ -179,7 +237,7 @@ class AttachContextAction extends Action2 {
179
237
  SymbolsQuickAccessProvider.PREFIX,
180
238
  AbstractGotoSymbolQuickAccessProvider.PREFIX
181
239
  ],
182
- placeholder: ( localizeWithPath(_moduleId, 2, 'Search attachments')),
240
+ placeholder: ( localizeWithPath(_moduleId, 4, 'Search attachments')),
183
241
  providerOptions: {
184
242
  handleAccept: (item) => {
185
243
  if ('prefix' in item) {
@@ -0,0 +1,28 @@
1
+ import { Codicon } from 'vscode/vscode/vs/base/common/codicons';
2
+ import { localize2WithPath } from 'vscode/vscode/vs/nls';
3
+ import { Categories } from 'vscode/vscode/vs/platform/action/common/actionCommonCategories';
4
+ import { registerAction2, Action2 } from 'vscode/vscode/vs/platform/actions/common/actions';
5
+ import { IChatWidgetService } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chat.service';
6
+
7
+ const _moduleId = "vs/workbench/contrib/chat/browser/actions/chatDeveloperActions";
8
+ function registerChatDeveloperActions() {
9
+ registerAction2(LogChatInputHistoryAction);
10
+ }
11
+ class LogChatInputHistoryAction extends Action2 {
12
+ static { this.ID = 'workbench.action.chat.logInputHistory'; }
13
+ constructor() {
14
+ super({
15
+ id: LogChatInputHistoryAction.ID,
16
+ title: ( localize2WithPath(_moduleId, 0, "Log Chat Input History")),
17
+ icon: Codicon.attach,
18
+ category: Categories.Developer,
19
+ f1: true
20
+ });
21
+ }
22
+ async run(accessor, ...args) {
23
+ const chatWidgetService = accessor.get(IChatWidgetService);
24
+ chatWidgetService.lastFocusedWidget?.logInputHistory();
25
+ }
26
+ }
27
+
28
+ export { registerChatDeveloperActions };
@@ -37,10 +37,12 @@ import 'vscode/vscode/vs/workbench/contrib/chat/browser/chatWidget';
37
37
  import './contrib/chatInputEditorContrib.js';
38
38
  import './contrib/chatContextAttachments.js';
39
39
  import './contrib/chatInputCompletions.js';
40
+ import './contrib/chatInputEditorHover.js';
40
41
  import { ChatAgentLocation } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents';
41
42
  import { IChatAgentService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents.service';
42
43
  import { chatVariableLeader } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatParserTypes';
43
44
  import '../common/chatServiceImpl.js';
45
+ import '../common/languageModelToolsService.js';
44
46
  import '../common/chatSlashCommands.js';
45
47
  import { IChatSlashCommandService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatSlashCommands.service';
46
48
  import { IChatVariablesService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatVariables.service';
@@ -53,6 +55,8 @@ import { IEditorResolverService } from 'vscode/vscode/vs/workbench/services/edit
53
55
  import { LifecyclePhase } from 'vscode/vscode/vs/workbench/services/lifecycle/common/lifecycle';
54
56
  import 'vscode/vscode/vs/workbench/contrib/chat/common/chatColors';
55
57
  import { registerChatContextActions } from './actions/chatContextActions.js';
58
+ import { registerChatDeveloperActions } from './actions/chatDeveloperActions.js';
59
+ import { LanguageModelToolsExtensionPointHandler } from '../common/tools/languageModelToolsContribution.js';
56
60
 
57
61
  const _moduleId = "vs/workbench/contrib/chat/browser/chat.contribution";
58
62
  const configurationRegistry = ( (Registry.as(Extensions.Configuration)));
@@ -101,9 +105,24 @@ configurationRegistry.registerConfiguration({
101
105
  deprecated: true,
102
106
  default: false
103
107
  },
108
+ 'chat.experimental.variables.editor': {
109
+ type: 'boolean',
110
+ description: ( localizeWithPath(_moduleId, 7, "Enables variables for editor chat.")),
111
+ default: false
112
+ },
113
+ 'chat.experimental.variables.notebook': {
114
+ type: 'boolean',
115
+ description: ( localizeWithPath(_moduleId, 8, "Enables variables for notebook chat.")),
116
+ default: false
117
+ },
118
+ 'chat.experimental.variables.terminal': {
119
+ type: 'boolean',
120
+ description: ( localizeWithPath(_moduleId, 9, "Enables variables for terminal chat.")),
121
+ default: false
122
+ },
104
123
  }
105
124
  });
106
- ( (Registry.as(EditorExtensions.EditorPane))).registerEditorPane(EditorPaneDescriptor.create(ChatEditor, ChatEditorInput.EditorID, ( localizeWithPath(_moduleId, 7, "Chat"))), [
125
+ ( (Registry.as(EditorExtensions.EditorPane))).registerEditorPane(EditorPaneDescriptor.create(ChatEditor, ChatEditorInput.EditorID, ( localizeWithPath(_moduleId, 10, "Chat"))), [
107
126
  ( (new SyncDescriptor(ChatEditorInput)))
108
127
  ]);
109
128
  let ChatResolverContribution = class ChatResolverContribution extends Disposable {
@@ -112,7 +131,7 @@ let ChatResolverContribution = class ChatResolverContribution extends Disposable
112
131
  super();
113
132
  this._register(editorResolverService.registerEditor(`${Schemas.vscodeChatSesssion}:**/**`, {
114
133
  id: ChatEditorInput.EditorID,
115
- label: ( localizeWithPath(_moduleId, 7, "Chat")),
134
+ label: ( localizeWithPath(_moduleId, 10, "Chat")),
116
135
  priority: RegisteredEditorPriority.builtin
117
136
  }, {
118
137
  singlePerResource: true,
@@ -135,7 +154,7 @@ let ChatSlashStaticSlashCommandsContribution = class ChatSlashStaticSlashCommand
135
154
  super();
136
155
  this._store.add(slashCommandService.registerSlashCommand({
137
156
  command: 'clear',
138
- detail: ( localizeWithPath(_moduleId, 8, "Start a new chat")),
157
+ detail: ( localizeWithPath(_moduleId, 11, "Start a new chat")),
139
158
  sortText: 'z2_clear',
140
159
  executeImmediately: true
141
160
  }, async () => {
@@ -182,7 +201,7 @@ let ChatSlashStaticSlashCommandsContribution = class ChatSlashStaticSlashCommand
182
201
  }
183
202
  const variables = [
184
203
  ...chatVariablesService.getVariables(),
185
- { name: 'file', description: ( localizeWithPath(_moduleId, 9, "Choose a file in the workspace")) }
204
+ { name: 'file', description: ( localizeWithPath(_moduleId, 12, "Choose a file in the workspace")) }
186
205
  ];
187
206
  const variableText = ( (variables
188
207
  .map(v => `* \`${chatVariableLeader}${v.name}\` - ${v.description}`)))
@@ -213,6 +232,7 @@ registerWorkbenchContribution2(ChatResolverContribution.ID, ChatResolverContribu
213
232
  workbenchContributionsRegistry.registerWorkbenchContribution(ChatSlashStaticSlashCommandsContribution, LifecyclePhase.Eventually);
214
233
  ( (Registry.as(EditorExtensions.EditorFactory))).registerEditorSerializer(ChatEditorInput.TypeID, ChatEditorInputSerializer);
215
234
  registerWorkbenchContribution2(ChatExtensionPointHandler.ID, ChatExtensionPointHandler, WorkbenchPhase.BlockStartup);
235
+ registerWorkbenchContribution2(LanguageModelToolsExtensionPointHandler.ID, LanguageModelToolsExtensionPointHandler, WorkbenchPhase.Eventually);
216
236
  registerChatActions();
217
237
  registerChatCopyActions();
218
238
  registerChatCodeBlockActions();
@@ -225,3 +245,4 @@ registerChatExportActions();
225
245
  registerMoveActions();
226
246
  registerNewChatActions();
227
247
  registerChatContextActions();
248
+ registerChatDeveloperActions();
@@ -78,10 +78,14 @@ const chatParticipantExtensionPoint = ExtensionsRegistry.registerExtensionPoint(
78
78
  )),
79
79
  type: 'string'
80
80
  },
81
+ when: {
82
+ description: ( localizeWithPath(_moduleId, 7, "A condition which must be true to enable this participant.")),
83
+ type: 'string'
84
+ },
81
85
  commands: {
82
86
  markdownDescription: ( localizeWithPath(
83
87
  _moduleId,
84
- 7,
88
+ 8,
85
89
  "Commands available for this chat participant, which the user can invoke with a `/`."
86
90
  )),
87
91
  type: 'array',
@@ -94,23 +98,23 @@ const chatParticipantExtensionPoint = ExtensionsRegistry.registerExtensionPoint(
94
98
  name: {
95
99
  description: ( localizeWithPath(
96
100
  _moduleId,
97
- 8,
101
+ 9,
98
102
  "A short name by which this command is referred to in the UI, e.g. `fix` or * `explain` for commands that fix an issue or explain code. The name should be unique among the commands provided by this participant."
99
103
  )),
100
104
  type: 'string'
101
105
  },
102
106
  description: {
103
- description: ( localizeWithPath(_moduleId, 9, "A description of this command.")),
107
+ description: ( localizeWithPath(_moduleId, 10, "A description of this command.")),
104
108
  type: 'string'
105
109
  },
106
110
  when: {
107
- description: ( localizeWithPath(_moduleId, 10, "A condition which must be true to enable this command.")),
111
+ description: ( localizeWithPath(_moduleId, 11, "A condition which must be true to enable this command.")),
108
112
  type: 'string'
109
113
  },
110
114
  sampleRequest: {
111
115
  description: ( localizeWithPath(
112
116
  _moduleId,
113
- 11,
117
+ 12,
114
118
  "When the user clicks this command in `/help`, this text will be submitted to the participant."
115
119
  )),
116
120
  type: 'string'
@@ -192,12 +196,12 @@ let ChatExtensionPointHandler = class ChatExtensionPointHandler {
192
196
  severity: Severity$1.Error,
193
197
  message: ( localizeWithPath(
194
198
  _moduleId,
195
- 12,
199
+ 13,
196
200
  "Chat failed to load. Please ensure that the GitHub Copilot Chat extension is up to date."
197
201
  )),
198
202
  actions: {
199
203
  primary: [
200
- ( (new Action('showExtension', ( localizeWithPath(_moduleId, 13, "Show Extension")), undefined, true, () => {
204
+ ( (new Action('showExtension', ( localizeWithPath(_moduleId, 14, "Show Extension")), undefined, true, () => {
201
205
  return this.commandService.executeCommand('workbench.extensions.action.showExtensionsWithIds', ['GitHub.copilot-chat']);
202
206
  })))
203
207
  ]
@@ -205,10 +209,6 @@ let ChatExtensionPointHandler = class ChatExtensionPointHandler {
205
209
  });
206
210
  continue;
207
211
  }
208
- if (this.productService.quality === 'stable' && !isProposedApiEnabled(extension.description, 'chatParticipantPrivate')) {
209
- this.logService.warn(`Chat participants are not yet enabled in VS Code Stable (${extension.description.identifier.value})`);
210
- continue;
211
- }
212
212
  for (const providerDescriptor of extension.value) {
213
213
  if (!providerDescriptor.name.match(/^[\w0-9_-]+$/)) {
214
214
  this.logService.error(`Extension '${extension.description.identifier.value}' CANNOT register participant with invalid name: ${providerDescriptor.name}. Name must match /^[\\w0-9_-]+$/.`);
@@ -238,10 +238,6 @@ let ChatExtensionPointHandler = class ChatExtensionPointHandler {
238
238
  if (providerDescriptor.isDefault && (!providerDescriptor.locations || providerDescriptor.locations?.includes(ChatAgentLocation.Panel))) {
239
239
  store.add(this.registerDefaultParticipantView(providerDescriptor));
240
240
  }
241
- if (providerDescriptor.when && !isProposedApiEnabled(extension.description, 'chatParticipantAdditions')) {
242
- this.logService.error(`Extension '${extension.description.identifier.value}' CANNOT use API proposal: chatParticipantAdditions.`);
243
- continue;
244
- }
245
241
  store.add(this._chatAgentService.registerAgent(providerDescriptor.id, {
246
242
  extensionId: extension.description.identifier,
247
243
  publisherDisplayName: extension.description.publisherDisplayName ?? extension.description.publisher,
@@ -274,7 +270,7 @@ let ChatExtensionPointHandler = class ChatExtensionPointHandler {
274
270
  });
275
271
  }
276
272
  registerViewContainer() {
277
- const title = ( localize2WithPath(_moduleId, 14, "Chat"));
273
+ const title = ( localize2WithPath(_moduleId, 15, "Chat"));
278
274
  const icon = Codicon.commentDiscussion;
279
275
  const viewContainerId = CHAT_SIDEBAR_PANEL_ID;
280
276
  const viewContainer = ( (Registry.as(Extensions.ViewContainersRegistry))).registerViewContainer({
@@ -72,7 +72,7 @@ let ChatVariablesService = class ChatVariablesService {
72
72
  await Promise.allSettled(jobs);
73
73
  resolvedVariables = coalesce(resolvedVariables);
74
74
  resolvedVariables.sort((a, b) => b.range.start - a.range.start);
75
- resolvedVariables.push(...resolvedAttachedContext);
75
+ resolvedVariables.push(...coalesce(resolvedAttachedContext));
76
76
  return {
77
77
  variables: resolvedVariables,
78
78
  };
@@ -1,3 +1,4 @@
1
+ import { Emitter } from 'vscode/vscode/vs/base/common/event';
1
2
  import { Disposable } from 'vscode/vscode/vs/base/common/lifecycle';
2
3
  import { ChatWidget } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chatWidget';
3
4
 
@@ -10,6 +11,8 @@ class ChatContextAttachments extends Disposable {
10
11
  super();
11
12
  this.widget = widget;
12
13
  this._attachedContext = ( new Set());
14
+ this._onDidChangeInputState = this._register(( new Emitter()));
15
+ this.onDidChangeInputState = this._onDidChangeInputState.event;
13
16
  this._register(this.widget.onDidDeleteContext((e) => {
14
17
  this._removeContext(e);
15
18
  }));
@@ -22,7 +25,11 @@ class ChatContextAttachments extends Disposable {
22
25
  }
23
26
  setInputState(s) {
24
27
  if (!Array.isArray(s)) {
25
- return;
28
+ s = [];
29
+ }
30
+ this._attachedContext.clear();
31
+ for (const attachment of s) {
32
+ this._attachedContext.add(attachment);
26
33
  }
27
34
  this.widget.setContext(true, ...s);
28
35
  }
@@ -37,9 +44,11 @@ class ChatContextAttachments extends Disposable {
37
44
  this._attachedContext.add(attachment);
38
45
  }
39
46
  this.widget.setContext(overwrite, ...attachments);
47
+ this._onDidChangeInputState.fire();
40
48
  }
41
49
  _removeContext(attachment) {
42
50
  this._attachedContext.delete(attachment);
51
+ this._onDidChangeInputState.fire();
43
52
  }
44
53
  _clearAttachedContext() {
45
54
  this._attachedContext.clear();
@@ -6,6 +6,7 @@ import { CompletionItemKind } from 'vscode/vscode/vs/editor/common/languages';
6
6
  import { ILanguageFeaturesService } from 'vscode/vscode/vs/editor/common/services/languageFeatures';
7
7
  import { localizeWithPath } from 'vscode/vscode/vs/nls';
8
8
  import { Action2, registerAction2 } from 'vscode/vscode/vs/platform/actions/common/actions';
9
+ import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration.service';
9
10
  import { Registry } from 'vscode/vscode/vs/platform/registry/common/platform';
10
11
  import { Extensions } from 'vscode/vscode/vs/workbench/common/contributions';
11
12
  import { SubmitAction } from 'vscode/vscode/vs/workbench/contrib/chat/browser/actions/chatExecuteActions';
@@ -14,7 +15,7 @@ import { ChatInputPart } from 'vscode/vscode/vs/workbench/contrib/chat/browser/c
14
15
  import { SelectAndInsertFileAction } from 'vscode/vscode/vs/workbench/contrib/chat/browser/contrib/chatDynamicVariables';
15
16
  import { ChatAgentLocation, getFullyQualifiedId } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents';
16
17
  import { IChatAgentService, IChatAgentNameService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents.service';
17
- import { ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestTextPart, chatSubcommandLeader, chatVariableLeader, ChatRequestVariablePart, chatAgentLeader } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatParserTypes';
18
+ import { ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestTextPart, chatSubcommandLeader, chatAgentLeader, chatVariableLeader, ChatRequestVariablePart } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatParserTypes';
18
19
  import { IChatSlashCommandService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatSlashCommands.service';
19
20
  import { IChatVariablesService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatVariables.service';
20
21
  import { LifecyclePhase } from 'vscode/vscode/vs/workbench/services/lifecycle/common/lifecycle';
@@ -101,7 +102,7 @@ let AgentCompletions = class AgentCompletions extends Disposable {
101
102
  .filter(a => a.locations.includes(widget.location));
102
103
  return {
103
104
  suggestions: ( (agents.map((agent, i) => {
104
- const { label: agentLabel, isDupe } = getAgentCompletionDetails(agent, agents, this.chatAgentNameService);
105
+ const { label: agentLabel, isDupe } = this.getAgentCompletionDetails(agent);
105
106
  return {
106
107
  label: isDupe ?
107
108
  { label: agentLabel, description: agent.description, detail: ` (${agent.publisherDisplayName})` } :
@@ -173,13 +174,13 @@ let AgentCompletions = class AgentCompletions extends Disposable {
173
174
  const agents = this.chatAgentService.getAgents()
174
175
  .filter(a => a.locations.includes(widget.location));
175
176
  const getFilterText = (agent, command) => {
176
- const dummyPrefix = agent.id === 'github.copilot.terminal' ? `0000` : ``;
177
+ const dummyPrefix = agent.id === 'github.copilot.terminalPanel' ? `0000` : ``;
177
178
  return `${chatSubcommandLeader}${dummyPrefix}${agent.name}.${command}`;
178
179
  };
179
180
  const justAgents = ( (agents
180
181
  .filter(a => !a.isDefault)
181
182
  .map(agent => {
182
- const { label: agentLabel, isDupe } = getAgentCompletionDetails(agent, agents, this.chatAgentNameService);
183
+ const { label: agentLabel, isDupe } = this.getAgentCompletionDetails(agent);
183
184
  const detail = agent.description;
184
185
  return {
185
186
  label: isDupe ?
@@ -196,7 +197,7 @@ let AgentCompletions = class AgentCompletions extends Disposable {
196
197
  })));
197
198
  return {
198
199
  suggestions: justAgents.concat(agents.flatMap(agent => ( (agent.slashCommands.map((c, i) => {
199
- const { label: agentLabel, isDupe } = getAgentCompletionDetails(agent, agents, this.chatAgentNameService);
200
+ const { label: agentLabel, isDupe } = this.getAgentCompletionDetails(agent);
200
201
  const withSlash = `${chatSubcommandLeader}${c.name}`;
201
202
  return {
202
203
  label: { label: withSlash, description: agentLabel, detail: isDupe ? ` (${agent.publisherDisplayName})` : undefined },
@@ -214,6 +215,12 @@ let AgentCompletions = class AgentCompletions extends Disposable {
214
215
  }
215
216
  }));
216
217
  }
218
+ getAgentCompletionDetails(agent) {
219
+ const isAllowed = this.chatAgentNameService.getAgentNameRestriction(agent);
220
+ const agentLabel = `${chatAgentLeader}${isAllowed ? agent.name : getFullyQualifiedId(agent)}`;
221
+ const isDupe = isAllowed && this.chatAgentService.agentHasDupeName(agent.id);
222
+ return { label: agentLabel, isDupe };
223
+ }
217
224
  };
218
225
  AgentCompletions = ( (__decorate([
219
226
  ( (__param(0, ILanguageFeaturesService))),
@@ -315,7 +322,7 @@ function computeCompletionRanges(model, position, reg) {
315
322
  let VariableCompletions = class VariableCompletions extends Disposable {
316
323
  static { VariableCompletions_1 = this; }
317
324
  static { this.VariableNameDef = ( (new RegExp(`${chatVariableLeader}\\w*`, 'g'))); }
318
- constructor(languageFeaturesService, chatWidgetService, chatVariablesService) {
325
+ constructor(languageFeaturesService, chatWidgetService, chatVariablesService, configService) {
319
326
  super();
320
327
  this.languageFeaturesService = languageFeaturesService;
321
328
  this.chatWidgetService = chatWidgetService;
@@ -324,8 +331,15 @@ let VariableCompletions = class VariableCompletions extends Disposable {
324
331
  _debugDisplayName: 'chatVariables',
325
332
  triggerCharacters: [chatVariableLeader],
326
333
  provideCompletionItems: async (model, position, _context, _token) => {
334
+ const locations = ( (new Set()));
335
+ locations.add(ChatAgentLocation.Panel);
336
+ for (const value of ( (Object.values(ChatAgentLocation)))) {
337
+ if (typeof value === 'string' && configService.getValue(`chat.experimental.variables.${value}`)) {
338
+ locations.add(value);
339
+ }
340
+ }
327
341
  const widget = this.chatWidgetService.getWidgetByInputUri(model.uri);
328
- if (!widget || widget.location !== ChatAgentLocation.Panel ) {
342
+ if (!widget || !( (locations.has(widget.location)))) {
329
343
  return null;
330
344
  }
331
345
  const range = computeCompletionRanges(model, position, VariableCompletions_1.VariableNameDef);
@@ -359,12 +373,7 @@ let VariableCompletions = class VariableCompletions extends Disposable {
359
373
  VariableCompletions = VariableCompletions_1 = ( (__decorate([
360
374
  ( (__param(0, ILanguageFeaturesService))),
361
375
  ( (__param(1, IChatWidgetService))),
362
- ( (__param(2, IChatVariablesService)))
376
+ ( (__param(2, IChatVariablesService))),
377
+ ( (__param(3, IConfigurationService)))
363
378
  ], VariableCompletions)));
364
379
  ( (Registry.as(Extensions.Workbench))).registerWorkbenchContribution(VariableCompletions, LifecyclePhase.Eventually);
365
- function getAgentCompletionDetails(agent, otherAgents, chatAgentNameService) {
366
- const isAllowed = chatAgentNameService.getAgentNameRestriction(agent);
367
- const agentLabel = `${chatAgentLeader}${isAllowed ? agent.name : getFullyQualifiedId(agent)}`;
368
- const isDupe = isAllowed && !!otherAgents.find(other => other.name === agent.name && other.id !== agent.id);
369
- return { label: agentLabel, isDupe };
370
- }
@@ -173,10 +173,7 @@ let InputEditorDecorations = class InputEditorDecorations extends Disposable {
173
173
  this.widget.inputEditor.setDecorationsByType(decorationDescription, placeholderDecorationType, placeholderDecoration ?? []);
174
174
  const textDecorations = [];
175
175
  if (agentPart) {
176
- const isDupe = !!this.chatAgentService.getAgents().find(other => other.name === agentPart.agent.name && other.id !== agentPart.agent.id);
177
- const publisher = isDupe ? `(${agentPart.agent.publisherDisplayName}) ` : '';
178
- const agentHover = `${publisher}${agentPart.agent.description}`;
179
- textDecorations.push({ range: agentPart.editorRange, hoverMessage: ( new MarkdownString(agentHover)) });
176
+ textDecorations.push({ range: agentPart.editorRange });
180
177
  if (agentSubcommandPart) {
181
178
  textDecorations.push({ range: agentSubcommandPart.editorRange, hoverMessage: ( new MarkdownString(agentSubcommandPart.command.description)) });
182
179
  }
@@ -0,0 +1,87 @@
1
+ import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
2
+ import { DisposableStore } from 'vscode/vscode/vs/base/common/lifecycle';
3
+ import { Range } from 'vscode/vscode/vs/editor/common/core/range';
4
+ import { RenderedHoverParts, HoverAnchorType, HoverParticipantRegistry } from 'vscode/vscode/vs/editor/contrib/hover/browser/hoverTypes';
5
+ import { ICommandService } from 'vscode/vscode/vs/platform/commands/common/commands.service';
6
+ import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
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';
9
+ import { ChatEditorHoverWrapper } from './editorHoverWrapper.js';
10
+ import { extractAgentAndCommand } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatParserTypes';
11
+ import { localizeWithPath } from 'vscode/vscode/vs/nls';
12
+
13
+ const _moduleId = "vs/workbench/contrib/chat/browser/contrib/chatInputEditorHover";
14
+ let ChatAgentHoverParticipant = class ChatAgentHoverParticipant {
15
+ constructor(editor, instantiationService, chatWidgetService, commandService) {
16
+ this.editor = editor;
17
+ this.instantiationService = instantiationService;
18
+ this.chatWidgetService = chatWidgetService;
19
+ this.commandService = commandService;
20
+ this.hoverOrdinal = 1;
21
+ }
22
+ computeSync(anchor, _lineDecorations) {
23
+ if (!this.editor.hasModel()) {
24
+ return [];
25
+ }
26
+ const widget = this.chatWidgetService.getWidgetByInputUri(this.editor.getModel().uri);
27
+ if (!widget) {
28
+ return [];
29
+ }
30
+ const { agentPart } = extractAgentAndCommand(widget.parsedInput);
31
+ if (!agentPart) {
32
+ return [];
33
+ }
34
+ if (Range.containsPosition(agentPart.editorRange, anchor.range.getStartPosition())) {
35
+ return [( (new ChatAgentHoverPart(this, Range.lift(agentPart.editorRange), agentPart.agent)))];
36
+ }
37
+ return [];
38
+ }
39
+ renderHoverParts(context, hoverParts) {
40
+ if (!hoverParts.length) {
41
+ return (
42
+ (new RenderedHoverParts([]))
43
+ );
44
+ }
45
+ const disposables = ( (new DisposableStore()));
46
+ const hover = disposables.add(this.instantiationService.createInstance(ChatAgentHover));
47
+ disposables.add(hover.onDidChangeContents(() => context.onContentsChanged()));
48
+ const hoverPart = hoverParts[0];
49
+ const agent = hoverPart.agent;
50
+ hover.setAgent(agent.id);
51
+ const actions = getChatAgentHoverOptions(() => agent, this.commandService).actions;
52
+ const wrapper = this.instantiationService.createInstance(ChatEditorHoverWrapper, hover.domNode, actions);
53
+ const wrapperNode = wrapper.domNode;
54
+ context.fragment.appendChild(wrapperNode);
55
+ const renderedHoverPart = {
56
+ hoverPart,
57
+ hoverElement: wrapperNode,
58
+ dispose() { disposables.dispose(); }
59
+ };
60
+ return (
61
+ (new RenderedHoverParts([renderedHoverPart]))
62
+ );
63
+ }
64
+ getAccessibleContent(hoverPart) {
65
+ return ( localizeWithPath(_moduleId, 0, 'There is a chat agent hover part here.'));
66
+ }
67
+ };
68
+ ChatAgentHoverParticipant = ( (__decorate([
69
+ ( (__param(1, IInstantiationService))),
70
+ ( (__param(2, IChatWidgetService))),
71
+ ( (__param(3, ICommandService)))
72
+ ], ChatAgentHoverParticipant)));
73
+ class ChatAgentHoverPart {
74
+ constructor(owner, range, agent) {
75
+ this.owner = owner;
76
+ this.range = range;
77
+ this.agent = agent;
78
+ }
79
+ isValidForHoverAnchor(anchor) {
80
+ return (anchor.type === HoverAnchorType.Range
81
+ && this.range.startColumn <= anchor.range.startColumn
82
+ && this.range.endColumn >= anchor.range.endColumn);
83
+ }
84
+ }
85
+ HoverParticipantRegistry.register(ChatAgentHoverParticipant);
86
+
87
+ export { ChatAgentHoverPart, ChatAgentHoverParticipant };
@@ -0,0 +1,31 @@
1
+ import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
2
+ import './media/editorHoverWrapper.css.js';
3
+ import { $ as $$1, h as h$1 } from 'vscode/vscode/vs/base/browser/dom';
4
+ import 'vscode/vscode/vs/base/browser/ui/hover/hoverWidget';
5
+ import { IKeybindingService } from 'vscode/vscode/vs/platform/keybinding/common/keybinding.service';
6
+
7
+ const $ = $$1;
8
+ const h = h$1;
9
+ let ChatEditorHoverWrapper = class ChatEditorHoverWrapper {
10
+ constructor(hoverContentElement, actions, keybindingService) {
11
+ this.keybindingService = keybindingService;
12
+ const hoverElement = h('.chat-editor-hover-wrapper@root', [h('.chat-editor-hover-wrapper-content@content')]);
13
+ this.domNode = hoverElement.root;
14
+ hoverElement.content.appendChild(hoverContentElement);
15
+ if (actions && actions.length > 0) {
16
+ const statusBarElement = $('.hover-row.status-bar');
17
+ const actionsElement = $('.actions');
18
+ actions.forEach(action => {
19
+ const keybinding = this.keybindingService.lookupKeybinding(action.commandId);
20
+ keybinding ? keybinding.getLabel() : null;
21
+ });
22
+ statusBarElement.appendChild(actionsElement);
23
+ this.domNode.appendChild(statusBarElement);
24
+ }
25
+ }
26
+ };
27
+ ChatEditorHoverWrapper = ( __decorate([
28
+ ( __param(2, IKeybindingService))
29
+ ], ChatEditorHoverWrapper));
30
+
31
+ export { ChatEditorHoverWrapper };
@@ -0,0 +1,6 @@
1
+ import n from 'vscode/external/rollup-plugin-styles/dist/runtime/inject-css.js';
2
+
3
+ var css = ".chat-editor-hover-wrapper-content{padding:2px 8px}";
4
+ n(css,{});
5
+
6
+ export { css, css as default };
@@ -437,8 +437,8 @@ let ChatService = class ChatService extends Disposable {
437
437
  if (!request.response) {
438
438
  continue;
439
439
  }
440
- history.push({ role: ChatMessageRole.User, content: request.message.text });
441
- history.push({ role: ChatMessageRole.Assistant, content: request.response.response.asString() });
440
+ history.push({ role: ChatMessageRole.User, content: { type: 'text', value: request.message.text } });
441
+ history.push({ role: ChatMessageRole.Assistant, content: { type: 'text', value: request.response.response.asString() } });
442
442
  }
443
443
  const message = parsedRequest.text;
444
444
  const commandResult = await this.chatSlashCommandService.executeCommand(commandPart.slashCommand.command, message.substring(commandPart.slashCommand.command.length + 1).trimStart(), ( (new Progress(p => {
@@ -495,13 +495,13 @@ let ChatService = class ChatService extends Disposable {
495
495
  chatSessionId: model.sessionId,
496
496
  location
497
497
  });
498
- const rawResult = { errorDetails: { message: err.message } };
498
+ this.logService.error(`Error while handling chat request: ${toErrorMessage(err, true)}`);
499
499
  if (request) {
500
+ const rawResult = { errorDetails: { message: err.message } };
500
501
  model.setResponse(request, rawResult);
502
+ completeResponseCreated();
503
+ model.completeResponse(request);
501
504
  }
502
- completeResponseCreated();
503
- this.logService.error(`Error while handling chat request: ${toErrorMessage(err)}`);
504
- model.completeResponse(request);
505
505
  }
506
506
  finally {
507
507
  listener.dispose();
@@ -0,0 +1,60 @@
1
+ import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
2
+ import { Emitter } from 'vscode/vscode/vs/base/common/event';
3
+ import { toDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
4
+ import { Iterable } from 'vscode/vscode/vs/base/common/iterator';
5
+ import { IExtensionService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions.service';
6
+
7
+ let LanguageModelToolsService = class LanguageModelToolsService {
8
+ constructor(_extensionService) {
9
+ this._extensionService = _extensionService;
10
+ this._onDidChangeTools = ( new Emitter());
11
+ this.onDidChangeTools = this._onDidChangeTools.event;
12
+ this._tools = ( new Map());
13
+ }
14
+ registerToolData(toolData) {
15
+ if (( this._tools.has(toolData.name))) {
16
+ throw ( new Error(`Tool "${toolData.name}" is already registered.`));
17
+ }
18
+ this._tools.set(toolData.name, { data: toolData });
19
+ this._onDidChangeTools.fire({ added: toolData });
20
+ return toDisposable(() => {
21
+ this._tools.delete(toolData.name);
22
+ this._onDidChangeTools.fire({ removed: toolData.name });
23
+ });
24
+ }
25
+ registerToolImplementation(name, tool) {
26
+ const entry = this._tools.get(name);
27
+ if (!entry) {
28
+ throw ( new Error(`Tool "${name}" was not contributed.`));
29
+ }
30
+ if (entry.impl) {
31
+ throw ( new Error(`Tool "${name}" already has an implementation.`));
32
+ }
33
+ entry.impl = tool;
34
+ return toDisposable(() => {
35
+ entry.impl = undefined;
36
+ });
37
+ }
38
+ getTools() {
39
+ return ( Iterable.map(( this._tools.values()), i => i.data));
40
+ }
41
+ async invokeTool(name, parameters, token) {
42
+ let tool = this._tools.get(name);
43
+ if (!tool) {
44
+ throw ( new Error(`Tool ${name} was not contributed`));
45
+ }
46
+ if (!tool.impl) {
47
+ await this._extensionService.activateByEvent(`onLanguageModelTool:${name}`);
48
+ tool = this._tools.get(name);
49
+ if (!tool?.impl) {
50
+ throw ( new Error(`Tool ${name} does not have an implementation registered.`));
51
+ }
52
+ }
53
+ return tool.impl.invoke(parameters, token);
54
+ }
55
+ };
56
+ LanguageModelToolsService = ( __decorate([
57
+ ( __param(0, IExtensionService))
58
+ ], LanguageModelToolsService));
59
+
60
+ export { LanguageModelToolsService };
@@ -0,0 +1,93 @@
1
+ import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
2
+ import { DisposableMap } from 'vscode/vscode/vs/base/common/lifecycle';
3
+ import { localizeWithPath } from 'vscode/vscode/vs/nls';
4
+ import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service';
5
+ import { ILanguageModelToolsService } from 'vscode/vscode/vs/workbench/contrib/chat/common/languageModelToolsService.service';
6
+ import { ExtensionsRegistry } from 'vscode/vscode/vs/workbench/services/extensions/common/extensionsRegistry';
7
+
8
+ const _moduleId = "vs/workbench/contrib/chat/common/tools/languageModelToolsContribution";
9
+ const languageModelToolsExtensionPoint = ExtensionsRegistry.registerExtensionPoint({
10
+ extensionPoint: 'languageModelTools',
11
+ activationEventsGenerator: (contributions, result) => {
12
+ for (const contrib of contributions) {
13
+ result.push(`onLanguageModelTool:${contrib.name}`);
14
+ }
15
+ },
16
+ jsonSchema: {
17
+ description: ( localizeWithPath(
18
+ _moduleId,
19
+ 0,
20
+ 'Contributes a tool that can be invoked by a language model.'
21
+ )),
22
+ type: 'array',
23
+ items: {
24
+ additionalProperties: false,
25
+ type: 'object',
26
+ defaultSnippets: [{ body: { name: '', description: '' } }],
27
+ required: ['name', 'description'],
28
+ properties: {
29
+ name: {
30
+ description: ( localizeWithPath(
31
+ _moduleId,
32
+ 1,
33
+ "A name for this tool which must be unique across all tools."
34
+ )),
35
+ type: 'string'
36
+ },
37
+ description: {
38
+ description: ( localizeWithPath(
39
+ _moduleId,
40
+ 2,
41
+ "A description of this tool that may be passed to a language model."
42
+ )),
43
+ type: 'string'
44
+ },
45
+ displayName: {
46
+ description: ( localizeWithPath(
47
+ _moduleId,
48
+ 3,
49
+ "A human-readable name for this tool that may be used to describe it in the UI."
50
+ )),
51
+ type: 'string'
52
+ },
53
+ parametersSchema: {
54
+ description: ( localizeWithPath(_moduleId, 4, "A JSON schema for the parameters this tool accepts.")),
55
+ type: 'object',
56
+ $ref: 'http://json-schema.org/draft-07/schema#'
57
+ }
58
+ }
59
+ }
60
+ }
61
+ });
62
+ function toToolKey(extensionIdentifier, toolName) {
63
+ return `${extensionIdentifier.value}/${toolName}`;
64
+ }
65
+ let LanguageModelToolsExtensionPointHandler = class LanguageModelToolsExtensionPointHandler {
66
+ static { this.ID = 'workbench.contrib.toolsExtensionPointHandler'; }
67
+ constructor(languageModelToolsService, logService) {
68
+ this._registrationDisposables = ( (new DisposableMap()));
69
+ languageModelToolsExtensionPoint.setHandler((extensions, delta) => {
70
+ for (const extension of delta.added) {
71
+ for (const tool of extension.value) {
72
+ if (!tool.name || !tool.description) {
73
+ logService.warn(`Invalid tool contribution from ${extension.description.identifier.value}: ${JSON.stringify(tool)}`);
74
+ continue;
75
+ }
76
+ const disposable = languageModelToolsService.registerToolData(tool);
77
+ this._registrationDisposables.set(toToolKey(extension.description.identifier, tool.name), disposable);
78
+ }
79
+ }
80
+ for (const extension of delta.removed) {
81
+ for (const tool of extension.value) {
82
+ this._registrationDisposables.deleteAndDispose(toToolKey(extension.description.identifier, tool.name));
83
+ }
84
+ }
85
+ });
86
+ }
87
+ };
88
+ LanguageModelToolsExtensionPointHandler = ( (__decorate([
89
+ ( (__param(0, ILanguageModelToolsService))),
90
+ ( (__param(1, ILogService)))
91
+ ], LanguageModelToolsExtensionPointHandler)));
92
+
93
+ export { LanguageModelToolsExtensionPointHandler };
@@ -1,8 +1,9 @@
1
+ import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
1
2
  import { registerEditorContribution, EditorContributionInstantiation } from 'vscode/vscode/vs/editor/browser/editorExtensions';
2
- import { registerAction2 } from 'vscode/vscode/vs/platform/actions/common/actions';
3
+ import { MenuRegistry, registerAction2, MenuId, isIMenuItem } from 'vscode/vscode/vs/platform/actions/common/actions';
3
4
  import { InlineChatController } from 'vscode/vscode/vs/workbench/contrib/inlineChat/browser/inlineChatController';
4
- import { StartSessionAction, CloseAction, ConfigureInlineChatAction, UnstashSessionAction, DiscardHunkAction, DiscardAction, RerunAction, CancelSessionAction, MoveToNextHunk, MoveToPreviousHunk, ArrowOutUpAction, ArrowOutDownAction, FocusInlineChat, ViewInChatAction, ToggleDiffForChange, AcceptChanges, CopyRecordings } from 'vscode/vscode/vs/workbench/contrib/inlineChat/browser/inlineChatActions';
5
- import { INLINE_CHAT_ID } from 'vscode/vscode/vs/workbench/contrib/inlineChat/common/inlineChat';
5
+ import { StartSessionAction, CloseAction, ConfigureInlineChatAction, UnstashSessionAction, DiscardHunkAction, DiscardAction, RerunAction, MoveToNextHunk, MoveToPreviousHunk, ArrowOutUpAction, ArrowOutDownAction, FocusInlineChat, ViewInChatAction, ToggleDiffForChange, AcceptChanges, CopyRecordings } from 'vscode/vscode/vs/workbench/contrib/inlineChat/browser/inlineChatActions';
6
+ import { INLINE_CHAT_ID, CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, CTX_INLINE_CHAT_CONFIG_TXT_BTNS, MENU_INLINE_CHAT_CONTENT_STATUS, MENU_INLINE_CHAT_WIDGET_STATUS, InlineChatConfigKeys, MENU_INLINE_CHAT_EXECUTE } from 'vscode/vscode/vs/workbench/contrib/inlineChat/common/inlineChat';
6
7
  import 'vscode/vscode/vs/platform/instantiation/common/extensions';
7
8
  import { Registry } from 'vscode/vscode/vs/platform/registry/common/platform';
8
9
  import { LifecyclePhase } from 'vscode/vscode/vs/workbench/services/lifecycle/common/lifecycle';
@@ -13,8 +14,41 @@ import { InlineChatAccessibleView } from './inlineChatAccessibleView.js';
13
14
  import 'vscode/vscode/vs/platform/instantiation/common/instantiation';
14
15
  import { InlineChatEnabler } from 'vscode/vscode/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl';
15
16
  import { AccessibleViewRegistry } from 'vscode/vscode/vs/platform/accessibility/browser/accessibleViewRegistry';
17
+ import { SubmitAction, CancelAction } from 'vscode/vscode/vs/workbench/contrib/chat/browser/actions/chatExecuteActions';
18
+ import { localizeWithPath } from 'vscode/vscode/vs/nls';
19
+ import { CONTEXT_CHAT_INPUT_HAS_TEXT } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatContextKeys';
20
+ import { ContextKeyExpr } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
21
+ import { DisposableStore } from 'vscode/vscode/vs/base/common/lifecycle';
22
+ import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration.service';
16
23
 
24
+ const _moduleId = "vs/workbench/contrib/inlineChat/browser/inlineChat.contribution";
17
25
  registerEditorContribution(INLINE_CHAT_ID, InlineChatController, EditorContributionInstantiation.Eager);
26
+ const sendActionMenuItem = {
27
+ group: '0_main',
28
+ order: 0,
29
+ command: {
30
+ id: SubmitAction.ID,
31
+ title: ( localizeWithPath(_moduleId, 0, "Send")),
32
+ },
33
+ when: ( (ContextKeyExpr.and(
34
+ CONTEXT_CHAT_INPUT_HAS_TEXT,
35
+ (CTX_INLINE_CHAT_REQUEST_IN_PROGRESS.toNegated()),
36
+ CTX_INLINE_CHAT_CONFIG_TXT_BTNS
37
+ ))),
38
+ };
39
+ MenuRegistry.appendMenuItem(MENU_INLINE_CHAT_CONTENT_STATUS, sendActionMenuItem);
40
+ MenuRegistry.appendMenuItem(MENU_INLINE_CHAT_WIDGET_STATUS, sendActionMenuItem);
41
+ const cancelActionMenuItem = {
42
+ group: '0_main',
43
+ order: 0,
44
+ command: {
45
+ id: CancelAction.ID,
46
+ title: ( localizeWithPath(_moduleId, 1, "Stop Request")),
47
+ shortTitle: ( localizeWithPath(_moduleId, 2, "Stop")),
48
+ },
49
+ when: ( (ContextKeyExpr.and(CTX_INLINE_CHAT_REQUEST_IN_PROGRESS))),
50
+ };
51
+ MenuRegistry.appendMenuItem(MENU_INLINE_CHAT_WIDGET_STATUS, cancelActionMenuItem);
18
52
  registerAction2(StartSessionAction);
19
53
  registerAction2(CloseAction);
20
54
  registerAction2(ConfigureInlineChatAction);
@@ -22,7 +56,6 @@ registerAction2(UnstashSessionAction);
22
56
  registerAction2(DiscardHunkAction);
23
57
  registerAction2(DiscardAction);
24
58
  registerAction2(RerunAction);
25
- registerAction2(CancelSessionAction);
26
59
  registerAction2(MoveToNextHunk);
27
60
  registerAction2(MoveToPreviousHunk);
28
61
  registerAction2(ArrowOutUpAction);
@@ -32,7 +65,42 @@ registerAction2(ViewInChatAction);
32
65
  registerAction2(ToggleDiffForChange);
33
66
  registerAction2(AcceptChanges);
34
67
  registerAction2(CopyRecordings);
35
- const workbenchContributionsRegistry = ( Registry.as(Extensions.Workbench));
68
+ const workbenchContributionsRegistry = ( (Registry.as(Extensions.Workbench)));
36
69
  workbenchContributionsRegistry.registerWorkbenchContribution(InlineChatNotebookContribution, LifecyclePhase.Restored);
37
70
  registerWorkbenchContribution2(InlineChatEnabler.Id, InlineChatEnabler, WorkbenchPhase.AfterRestored);
38
- AccessibleViewRegistry.register(( new InlineChatAccessibleView()));
71
+ AccessibleViewRegistry.register(( (new InlineChatAccessibleView())));
72
+ let MenuCopier = class MenuCopier {
73
+ static { this.Id = 'inlineChat.menuCopier'; }
74
+ constructor(configService) {
75
+ const store = ( (new DisposableStore()));
76
+ function updateMenu() {
77
+ store.clear();
78
+ for (const item of MenuRegistry.getMenuItems(MenuId.ChatExecute)) {
79
+ if (configService.getValue(InlineChatConfigKeys.ExpTextButtons) && isIMenuItem(item) && (item.command.id === SubmitAction.ID || item.command.id === CancelAction.ID)) {
80
+ continue;
81
+ }
82
+ store.add(MenuRegistry.appendMenuItem(MENU_INLINE_CHAT_EXECUTE, item));
83
+ }
84
+ }
85
+ updateMenu();
86
+ const listener = MenuRegistry.onDidChangeMenu(e => {
87
+ if (( (e.has(MenuId.ChatExecute)))) {
88
+ updateMenu();
89
+ }
90
+ });
91
+ const listener2 = configService.onDidChangeConfiguration(e => {
92
+ if (e.affectsConfiguration(InlineChatConfigKeys.ExpTextButtons)) {
93
+ updateMenu();
94
+ }
95
+ });
96
+ this.dispose = () => {
97
+ listener.dispose();
98
+ listener2.dispose();
99
+ store.dispose();
100
+ };
101
+ }
102
+ };
103
+ MenuCopier = ( (__decorate([
104
+ ( (__param(0, IConfigurationService)))
105
+ ], MenuCopier)));
106
+ registerWorkbenchContribution2(MenuCopier.Id, MenuCopier, WorkbenchPhase.AfterRestored);
@@ -4,6 +4,8 @@ import { ICodeEditorService } from 'vscode/vscode/vs/editor/browser/services/cod
4
4
  import { ContextKeyExpr } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
5
5
  import { AccessibleViewType, AccessibleViewProviderId } from 'vscode/vscode/vs/platform/accessibility/browser/accessibleView';
6
6
  import { AccessibilityVerbositySettingId } from 'vscode/vscode/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
7
+ import { MarkdownString } from 'vscode/vscode/vs/base/common/htmlContent';
8
+ import { renderMarkdownAsPlaintext } from 'vscode/vscode/vs/base/browser/markdownRenderer';
7
9
 
8
10
  class InlineChatAccessibleView {
9
11
  constructor() {
@@ -29,7 +31,7 @@ class InlineChatAccessibleView {
29
31
  return {
30
32
  id: AccessibleViewProviderId.InlineChat,
31
33
  verbositySettingKey: AccessibilityVerbositySettingId.InlineChat,
32
- provideContent() { return responseContent; },
34
+ provideContent() { return renderMarkdownAsPlaintext(( new MarkdownString(responseContent)), true); },
33
35
  onClose() {
34
36
  controller.focus();
35
37
  },