@codingame/monaco-vscode-chat-service-override 5.3.0 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/chat.js +5 -7
- package/package.json +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.js +160 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.js +17 -11
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.js +15 -13
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.js +215 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCopyActions.js +1 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatFileTreeActions.js +6 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.js +15 -93
- package/vscode/src/vs/workbench/contrib/chat/browser/chat.contribution.js +27 -106
- package/vscode/src/vs/workbench/contrib/chat/browser/chatAccessibilityService.js +5 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditor.js +6 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chatParticipantContributions.js +95 -51
- package/vscode/src/vs/workbench/contrib/chat/browser/chatQuick.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/chatResponseAccessibleView.js +94 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatVariables.js +64 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/chatViewPane.js +2 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatContextAttachments.js +50 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputCompletions.js +370 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.js +19 -366
- package/vscode/src/vs/workbench/contrib/chat/common/chatServiceImpl.js +122 -63
- package/vscode/src/vs/workbench/contrib/chat/common/chatWidgetHistoryService.js +12 -5
- package/vscode/src/vs/workbench/contrib/chat/common/languageModelStats.js +6 -5
- package/vscode/src/vs/workbench/contrib/chat/common/{voiceChat.js → voiceChatService.js} +58 -21
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.js +15 -14
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.js +33 -32
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSavingServiceImpl.js +6 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatHistoryVariables.js +0 -26
- package/vscode/src/vs/workbench/contrib/chat/common/languageModels.js +0 -50
- package/vscode/src/vs/workbench/contrib/inlineChat/common/inlineChatServiceImpl.js +0 -33
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
|
|
2
2
|
import { isNonEmptyArray } from 'vscode/vscode/vs/base/common/arrays';
|
|
3
|
+
import { AmbiguousCharacters, InvisibleCharacters } from 'vscode/vscode/vs/base/common/strings';
|
|
3
4
|
import { Codicon } from 'vscode/vscode/vs/base/common/codicons';
|
|
4
|
-
import { DisposableStore, DisposableMap, toDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
|
|
5
|
+
import { DisposableStore, DisposableMap, Disposable, toDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
|
|
5
6
|
import { localizeWithPath, localize2WithPath } from 'vscode/vscode/vs/nls';
|
|
6
7
|
import { ContextKeyExpr } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
|
|
7
8
|
import { IContextKeyService } from 'vscode/vscode/vs/platform/contextkey/common/contextkey.service';
|
|
@@ -10,13 +11,18 @@ import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service';
|
|
|
10
11
|
import { IProductService } from 'vscode/vscode/vs/platform/product/common/productService.service';
|
|
11
12
|
import { Registry } from 'vscode/vscode/vs/platform/registry/common/platform';
|
|
12
13
|
import { ViewPaneContainer } from 'vscode/vscode/vs/workbench/browser/parts/views/viewPaneContainer';
|
|
13
|
-
import { Extensions } from 'vscode/vscode/vs/workbench/common/views';
|
|
14
|
+
import { Extensions, ViewContainerLocation } from 'vscode/vscode/vs/workbench/common/views';
|
|
14
15
|
import { CHAT_VIEW_ID } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chat';
|
|
15
16
|
import { ChatViewPane, CHAT_SIDEBAR_PANEL_ID } from './chatViewPane.js';
|
|
16
17
|
import { ChatAgentLocation } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents';
|
|
17
18
|
import { IChatAgentService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents.service';
|
|
18
19
|
import { isProposedApiEnabled } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions';
|
|
19
20
|
import { ExtensionsRegistry } from 'vscode/vscode/vs/workbench/services/extensions/common/extensionsRegistry';
|
|
21
|
+
import 'vscode/vscode/vs/platform/notification/common/notification';
|
|
22
|
+
import { INotificationService } from 'vscode/vscode/vs/platform/notification/common/notification.service';
|
|
23
|
+
import { Action } from 'vscode/vscode/vs/base/common/actions';
|
|
24
|
+
import { ICommandService } from 'vscode/vscode/vs/platform/commands/common/commands.service';
|
|
25
|
+
import Severity$1 from 'vscode/vscode/vs/base/common/severity';
|
|
20
26
|
|
|
21
27
|
const _moduleId = "vs/workbench/contrib/chat/browser/chatParticipantContributions";
|
|
22
28
|
const chatParticipantExtensionPoint = ExtensionsRegistry.registerExtensionPoint({
|
|
@@ -38,21 +44,23 @@ const chatParticipantExtensionPoint = ExtensionsRegistry.registerExtensionPoint(
|
|
|
38
44
|
description: ( localizeWithPath(
|
|
39
45
|
_moduleId,
|
|
40
46
|
2,
|
|
41
|
-
"User-facing
|
|
47
|
+
"User-facing name for this chat participant. The user will use '@' with this name to invoke the participant. Name must not contain whitespace."
|
|
42
48
|
)),
|
|
43
|
-
type: 'string'
|
|
49
|
+
type: 'string',
|
|
50
|
+
pattern: '^[\\w0-9_-]+$'
|
|
44
51
|
},
|
|
45
|
-
|
|
46
|
-
description: ( localizeWithPath(_moduleId, 3, "A description of this chat participant, shown in the UI.")),
|
|
47
|
-
type: 'string'
|
|
48
|
-
},
|
|
49
|
-
isDefault: {
|
|
52
|
+
fullName: {
|
|
50
53
|
markdownDescription: ( localizeWithPath(
|
|
51
54
|
_moduleId,
|
|
52
|
-
|
|
53
|
-
"
|
|
55
|
+
3,
|
|
56
|
+
"The full name of this chat participant, which is shown as the label for responses coming from this participant. If not provided, {0} is used.",
|
|
57
|
+
'`name`'
|
|
54
58
|
)),
|
|
55
|
-
type: '
|
|
59
|
+
type: 'string'
|
|
60
|
+
},
|
|
61
|
+
description: {
|
|
62
|
+
description: ( localizeWithPath(_moduleId, 4, "A description of this chat participant, shown in the UI.")),
|
|
63
|
+
type: 'string'
|
|
56
64
|
},
|
|
57
65
|
isSticky: {
|
|
58
66
|
description: ( localizeWithPath(
|
|
@@ -62,17 +70,18 @@ const chatParticipantExtensionPoint = ExtensionsRegistry.registerExtensionPoint(
|
|
|
62
70
|
)),
|
|
63
71
|
type: 'boolean'
|
|
64
72
|
},
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
sampleRequest: {
|
|
74
|
+
description: ( localizeWithPath(
|
|
75
|
+
_moduleId,
|
|
76
|
+
6,
|
|
77
|
+
"When the user clicks this participant in `/help`, this text will be submitted to the participant."
|
|
78
|
+
)),
|
|
79
|
+
type: 'string'
|
|
71
80
|
},
|
|
72
81
|
commands: {
|
|
73
82
|
markdownDescription: ( localizeWithPath(
|
|
74
83
|
_moduleId,
|
|
75
|
-
|
|
84
|
+
7,
|
|
76
85
|
"Commands available for this chat participant, which the user can invoke with a `/`."
|
|
77
86
|
)),
|
|
78
87
|
type: 'array',
|
|
@@ -85,24 +94,24 @@ const chatParticipantExtensionPoint = ExtensionsRegistry.registerExtensionPoint(
|
|
|
85
94
|
name: {
|
|
86
95
|
description: ( localizeWithPath(
|
|
87
96
|
_moduleId,
|
|
88
|
-
|
|
97
|
+
8,
|
|
89
98
|
"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."
|
|
90
99
|
)),
|
|
91
100
|
type: 'string'
|
|
92
101
|
},
|
|
93
102
|
description: {
|
|
94
|
-
description: ( localizeWithPath(_moduleId,
|
|
103
|
+
description: ( localizeWithPath(_moduleId, 9, "A description of this command.")),
|
|
95
104
|
type: 'string'
|
|
96
105
|
},
|
|
97
106
|
when: {
|
|
98
|
-
description: ( localizeWithPath(_moduleId,
|
|
107
|
+
description: ( localizeWithPath(_moduleId, 10, "A condition which must be true to enable this command.")),
|
|
99
108
|
type: 'string'
|
|
100
109
|
},
|
|
101
110
|
sampleRequest: {
|
|
102
111
|
description: ( localizeWithPath(
|
|
103
112
|
_moduleId,
|
|
104
|
-
|
|
105
|
-
"When the user clicks this command in `/help`, this text will be submitted to
|
|
113
|
+
11,
|
|
114
|
+
"When the user clicks this command in `/help`, this text will be submitted to the participant."
|
|
106
115
|
)),
|
|
107
116
|
type: 'string'
|
|
108
117
|
},
|
|
@@ -114,29 +123,9 @@ const chatParticipantExtensionPoint = ExtensionsRegistry.registerExtensionPoint(
|
|
|
114
123
|
)),
|
|
115
124
|
type: 'boolean'
|
|
116
125
|
},
|
|
117
|
-
defaultImplicitVariables: {
|
|
118
|
-
markdownDescription: ( localizeWithPath(
|
|
119
|
-
_moduleId,
|
|
120
|
-
11,
|
|
121
|
-
"**Only** allowed for extensions that have the `chatParticipantAdditions` proposal. The names of the variables that are invoked by default"
|
|
122
|
-
)),
|
|
123
|
-
type: 'array',
|
|
124
|
-
items: {
|
|
125
|
-
type: 'string'
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
126
|
}
|
|
129
127
|
}
|
|
130
128
|
},
|
|
131
|
-
locations: {
|
|
132
|
-
markdownDescription: ( localizeWithPath(_moduleId, 12, "Locations in which this chat participant is available.")),
|
|
133
|
-
type: 'array',
|
|
134
|
-
default: ['panel'],
|
|
135
|
-
items: {
|
|
136
|
-
type: 'string',
|
|
137
|
-
enum: ['panel', 'terminal', 'notebook']
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
129
|
}
|
|
141
130
|
}
|
|
142
131
|
},
|
|
@@ -148,13 +137,16 @@ const chatParticipantExtensionPoint = ExtensionsRegistry.registerExtensionPoint(
|
|
|
148
137
|
});
|
|
149
138
|
let ChatExtensionPointHandler = class ChatExtensionPointHandler {
|
|
150
139
|
static { this.ID = 'workbench.contrib.chatExtensionPointHandler'; }
|
|
151
|
-
constructor(_chatAgentService, productService, contextService, logService) {
|
|
140
|
+
constructor(_chatAgentService, productService, contextService, logService, notificationService, commandService) {
|
|
152
141
|
this._chatAgentService = _chatAgentService;
|
|
153
142
|
this.productService = productService;
|
|
154
143
|
this.contextService = contextService;
|
|
155
144
|
this.logService = logService;
|
|
145
|
+
this.notificationService = notificationService;
|
|
146
|
+
this.commandService = commandService;
|
|
156
147
|
this.disposables = ( (new DisposableStore()));
|
|
157
148
|
this._participantRegistrationDisposables = ( (new DisposableMap()));
|
|
149
|
+
this.hasRegisteredDefaultParticipantView = false;
|
|
158
150
|
this._viewContainer = this.registerViewContainer();
|
|
159
151
|
this.registerListeners();
|
|
160
152
|
this.handleAndRegisterChatExtensions();
|
|
@@ -193,12 +185,48 @@ let ChatExtensionPointHandler = class ChatExtensionPointHandler {
|
|
|
193
185
|
handleAndRegisterChatExtensions() {
|
|
194
186
|
chatParticipantExtensionPoint.setHandler((extensions, delta) => {
|
|
195
187
|
for (const extension of delta.added) {
|
|
188
|
+
if (( (extension.value.some(
|
|
189
|
+
participant => participant.id === 'github.copilot.default' && !participant.fullName
|
|
190
|
+
)))) {
|
|
191
|
+
this.notificationService.notify({
|
|
192
|
+
severity: Severity$1.Error,
|
|
193
|
+
message: ( localizeWithPath(
|
|
194
|
+
_moduleId,
|
|
195
|
+
12,
|
|
196
|
+
"Chat failed to load. Please ensure that the GitHub Copilot Chat extension is up to date."
|
|
197
|
+
)),
|
|
198
|
+
actions: {
|
|
199
|
+
primary: [
|
|
200
|
+
( (new Action('showExtension', ( localizeWithPath(_moduleId, 13, "Show Extension")), undefined, true, () => {
|
|
201
|
+
return this.commandService.executeCommand('workbench.extensions.action.showExtensionsWithIds', ['GitHub.copilot-chat']);
|
|
202
|
+
})))
|
|
203
|
+
]
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
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
|
+
}
|
|
196
212
|
for (const providerDescriptor of extension.value) {
|
|
213
|
+
if (!providerDescriptor.name.match(/^[\w0-9_-]+$/)) {
|
|
214
|
+
this.logService.error(`Extension '${extension.description.identifier.value}' CANNOT register participant with invalid name: ${providerDescriptor.name}. Name must match /^[\\w0-9_-]+$/.`);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (providerDescriptor.fullName && AmbiguousCharacters.getInstance(( (new Set()))).containsAmbiguousCharacter(providerDescriptor.fullName)) {
|
|
218
|
+
this.logService.error(`Extension '${extension.description.identifier.value}' CANNOT register participant with fullName that contains ambiguous characters: ${providerDescriptor.fullName}.`);
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (providerDescriptor.fullName && InvisibleCharacters.containsInvisibleCharacter(providerDescriptor.fullName.replace(/ /g, ''))) {
|
|
222
|
+
this.logService.error(`Extension '${extension.description.identifier.value}' CANNOT register participant with fullName that contains invisible characters: ${providerDescriptor.fullName}.`);
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
197
225
|
if (providerDescriptor.isDefault && !isProposedApiEnabled(extension.description, 'defaultChatParticipant')) {
|
|
198
226
|
this.logService.error(`Extension '${extension.description.identifier.value}' CANNOT use API proposal: defaultChatParticipant.`);
|
|
199
227
|
continue;
|
|
200
228
|
}
|
|
201
|
-
if (providerDescriptor.defaultImplicitVariables && !isProposedApiEnabled(extension.description, 'chatParticipantAdditions')) {
|
|
229
|
+
if ((providerDescriptor.defaultImplicitVariables || providerDescriptor.locations) && !isProposedApiEnabled(extension.description, 'chatParticipantAdditions')) {
|
|
202
230
|
this.logService.error(`Extension '${extension.description.identifier.value}' CANNOT use API proposal: chatParticipantAdditions.`);
|
|
203
231
|
continue;
|
|
204
232
|
}
|
|
@@ -210,17 +238,24 @@ let ChatExtensionPointHandler = class ChatExtensionPointHandler {
|
|
|
210
238
|
if (providerDescriptor.isDefault && (!providerDescriptor.locations || providerDescriptor.locations?.includes(ChatAgentLocation.Panel))) {
|
|
211
239
|
store.add(this.registerDefaultParticipantView(providerDescriptor));
|
|
212
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
|
+
}
|
|
213
245
|
store.add(this._chatAgentService.registerAgent(providerDescriptor.id, {
|
|
214
246
|
extensionId: extension.description.identifier,
|
|
215
|
-
|
|
247
|
+
publisherDisplayName: extension.description.publisherDisplayName ?? extension.description.publisher,
|
|
216
248
|
extensionPublisherId: extension.description.publisher,
|
|
217
249
|
extensionDisplayName: extension.description.displayName ?? extension.description.name,
|
|
218
250
|
id: providerDescriptor.id,
|
|
219
251
|
description: providerDescriptor.description,
|
|
252
|
+
when: providerDescriptor.when,
|
|
220
253
|
metadata: {
|
|
221
254
|
isSticky: providerDescriptor.isSticky,
|
|
255
|
+
sampleRequest: providerDescriptor.sampleRequest,
|
|
222
256
|
},
|
|
223
257
|
name: providerDescriptor.name,
|
|
258
|
+
fullName: providerDescriptor.fullName,
|
|
224
259
|
isDefault: providerDescriptor.isDefault,
|
|
225
260
|
defaultImplicitVariables: providerDescriptor.defaultImplicitVariables,
|
|
226
261
|
locations: isNonEmptyArray(providerDescriptor.locations) ?
|
|
@@ -239,7 +274,7 @@ let ChatExtensionPointHandler = class ChatExtensionPointHandler {
|
|
|
239
274
|
});
|
|
240
275
|
}
|
|
241
276
|
registerViewContainer() {
|
|
242
|
-
const title = ( localize2WithPath(_moduleId,
|
|
277
|
+
const title = ( localize2WithPath(_moduleId, 14, "Chat"));
|
|
243
278
|
const icon = Codicon.commentDiscussion;
|
|
244
279
|
const viewContainerId = CHAT_SIDEBAR_PANEL_ID;
|
|
245
280
|
const viewContainer = ( (Registry.as(Extensions.ViewContainersRegistry))).registerViewContainer({
|
|
@@ -253,22 +288,29 @@ let ChatExtensionPointHandler = class ChatExtensionPointHandler {
|
|
|
253
288
|
storageId: viewContainerId,
|
|
254
289
|
hideIfEmpty: true,
|
|
255
290
|
order: 100,
|
|
256
|
-
},
|
|
291
|
+
}, ViewContainerLocation.Sidebar);
|
|
257
292
|
return viewContainer;
|
|
258
293
|
}
|
|
259
294
|
registerDefaultParticipantView(defaultParticipantDescriptor) {
|
|
295
|
+
if (this.hasRegisteredDefaultParticipantView) {
|
|
296
|
+
this.logService.warn(`Tried to register a second default chat participant view for "${defaultParticipantDescriptor.id}"`);
|
|
297
|
+
return Disposable.None;
|
|
298
|
+
}
|
|
299
|
+
const name = defaultParticipantDescriptor.fullName ?? defaultParticipantDescriptor.name;
|
|
260
300
|
const viewDescriptor = [{
|
|
261
301
|
id: CHAT_VIEW_ID,
|
|
262
302
|
containerIcon: this._viewContainer.icon,
|
|
263
303
|
containerTitle: this._viewContainer.title.value,
|
|
264
304
|
singleViewPaneContainerTitle: this._viewContainer.title.value,
|
|
265
|
-
name: { value:
|
|
305
|
+
name: { value: name, original: name },
|
|
266
306
|
canToggleVisibility: false,
|
|
267
307
|
canMoveView: true,
|
|
268
308
|
ctorDescriptor: ( (new SyncDescriptor(ChatViewPane))),
|
|
269
309
|
}];
|
|
310
|
+
this.hasRegisteredDefaultParticipantView = true;
|
|
270
311
|
( (Registry.as(Extensions.ViewsRegistry))).registerViews(viewDescriptor, this._viewContainer);
|
|
271
312
|
return toDisposable(() => {
|
|
313
|
+
this.hasRegisteredDefaultParticipantView = false;
|
|
272
314
|
( (Registry.as(Extensions.ViewsRegistry))).deregisterViews(viewDescriptor, this._viewContainer);
|
|
273
315
|
});
|
|
274
316
|
}
|
|
@@ -277,7 +319,9 @@ ChatExtensionPointHandler = ( (__decorate([
|
|
|
277
319
|
( (__param(0, IChatAgentService))),
|
|
278
320
|
( (__param(1, IProductService))),
|
|
279
321
|
( (__param(2, IContextKeyService))),
|
|
280
|
-
( (__param(3, ILogService)))
|
|
322
|
+
( (__param(3, ILogService))),
|
|
323
|
+
( (__param(4, INotificationService))),
|
|
324
|
+
( (__param(5, ICommandService)))
|
|
281
325
|
], ChatExtensionPointHandler)));
|
|
282
326
|
function getParticipantKey(extensionId, participantName) {
|
|
283
327
|
return `${extensionId.value}_${participantName}`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
|
|
2
2
|
import { isAncestorOfActiveElement, $ } from 'vscode/vscode/vs/base/browser/dom';
|
|
3
|
-
import { Sash } from 'vscode/vscode/vs/base/browser/ui/sash/sash';
|
|
3
|
+
import { Sash, Orientation } from 'vscode/vscode/vs/base/browser/ui/sash/sash';
|
|
4
4
|
import { disposableTimeout } from 'vscode/vscode/vs/base/common/async';
|
|
5
5
|
import { CancellationToken } from 'vscode/vscode/vs/base/common/cancellation';
|
|
6
6
|
import { Emitter, Event } from 'vscode/vscode/vs/base/common/event';
|
|
@@ -174,10 +174,10 @@ let QuickChat = class QuickChat extends Disposable {
|
|
|
174
174
|
if (this.widget) {
|
|
175
175
|
throw ( new Error('Cannot render quick chat twice'));
|
|
176
176
|
}
|
|
177
|
-
const scopedInstantiationService = this.instantiationService.createChild(( new ServiceCollection([
|
|
177
|
+
const scopedInstantiationService = this._register(this.instantiationService.createChild(( new ServiceCollection([
|
|
178
178
|
IContextKeyService,
|
|
179
179
|
this._register(this.contextKeyService.createScoped(parent))
|
|
180
|
-
])));
|
|
180
|
+
]))));
|
|
181
181
|
this.widget = this._register(scopedInstantiationService.createInstance(ChatWidget, ChatAgentLocation.Panel, { resource: true }, { renderInputOnTop: true, renderStyle: 'compact', menus: { inputSideToolbar: MenuId.ChatInputSide } }, {
|
|
182
182
|
listForeground: quickInputForeground,
|
|
183
183
|
listBackground: quickInputBackground,
|
|
@@ -191,7 +191,7 @@ let QuickChat = class QuickChat extends Disposable {
|
|
|
191
191
|
this.sash = this._register(( new Sash(
|
|
192
192
|
parent,
|
|
193
193
|
{ getHorizontalSashTop: () => parent.offsetHeight },
|
|
194
|
-
{ orientation:
|
|
194
|
+
{ orientation: Orientation.HORIZONTAL }
|
|
195
195
|
)));
|
|
196
196
|
this.registerListeners(parent);
|
|
197
197
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { renderMarkdownAsPlaintext } from 'vscode/vscode/vs/base/browser/markdownRenderer';
|
|
2
|
+
import { MarkdownString } from 'vscode/vscode/vs/base/common/htmlContent';
|
|
3
|
+
import { ICodeEditorService } from 'vscode/vscode/vs/editor/browser/services/codeEditorService';
|
|
4
|
+
import { AccessibleViewType, AccessibleViewProviderId } from 'vscode/vscode/vs/platform/accessibility/browser/accessibleView';
|
|
5
|
+
import { alertAccessibleViewFocusChange } from 'vscode/vscode/vs/platform/accessibility/browser/accessibleViewRegistry';
|
|
6
|
+
import { AccessibilityVerbositySettingId } from 'vscode/vscode/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
|
|
7
|
+
import { IChatWidgetService } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chat.service';
|
|
8
|
+
import { CONTEXT_IN_CHAT_SESSION } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatContextKeys';
|
|
9
|
+
import { ChatWelcomeMessageModel } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatModel';
|
|
10
|
+
import { isResponseVM } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatViewModel';
|
|
11
|
+
|
|
12
|
+
class ChatResponseAccessibleView {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.priority = 100;
|
|
15
|
+
this.name = 'panelChat';
|
|
16
|
+
this.type = AccessibleViewType.View;
|
|
17
|
+
this.when = CONTEXT_IN_CHAT_SESSION;
|
|
18
|
+
}
|
|
19
|
+
getProvider(accessor) {
|
|
20
|
+
const widgetService = accessor.get(IChatWidgetService);
|
|
21
|
+
const codeEditorService = accessor.get(ICodeEditorService);
|
|
22
|
+
return resolveProvider(widgetService, codeEditorService, true);
|
|
23
|
+
function resolveProvider(widgetService, codeEditorService, initialRender) {
|
|
24
|
+
const widget = widgetService.lastFocusedWidget;
|
|
25
|
+
if (!widget) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const chatInputFocused = initialRender && !!codeEditorService.getFocusedCodeEditor();
|
|
29
|
+
if (initialRender && chatInputFocused) {
|
|
30
|
+
widget.focusLastMessage();
|
|
31
|
+
}
|
|
32
|
+
if (!widget) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const verifiedWidget = widget;
|
|
36
|
+
const focusedItem = verifiedWidget.getFocus();
|
|
37
|
+
if (!focusedItem) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
widget.focus(focusedItem);
|
|
41
|
+
const isWelcome = focusedItem instanceof ChatWelcomeMessageModel;
|
|
42
|
+
let responseContent = isResponseVM(focusedItem) ? focusedItem.response.asString() : undefined;
|
|
43
|
+
if (isWelcome) {
|
|
44
|
+
const welcomeReplyContents = [];
|
|
45
|
+
for (const content of focusedItem.content) {
|
|
46
|
+
if (Array.isArray(content)) {
|
|
47
|
+
welcomeReplyContents.push(...( content.map(m => m.message)));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
welcomeReplyContents.push(content.value);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
responseContent = welcomeReplyContents.join('\n');
|
|
54
|
+
}
|
|
55
|
+
if (!responseContent && 'errorDetails' in focusedItem && focusedItem.errorDetails) {
|
|
56
|
+
responseContent = focusedItem.errorDetails.message;
|
|
57
|
+
}
|
|
58
|
+
if (!responseContent) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const responses = verifiedWidget.viewModel?.getItems().filter(i => isResponseVM(i));
|
|
62
|
+
const length = responses?.length;
|
|
63
|
+
const responseIndex = responses?.findIndex(i => i === focusedItem);
|
|
64
|
+
return {
|
|
65
|
+
id: AccessibleViewProviderId.Chat,
|
|
66
|
+
verbositySettingKey: AccessibilityVerbositySettingId.Chat,
|
|
67
|
+
provideContent() { return renderMarkdownAsPlaintext(( new MarkdownString(responseContent)), true); },
|
|
68
|
+
onClose() {
|
|
69
|
+
verifiedWidget.reveal(focusedItem);
|
|
70
|
+
if (chatInputFocused) {
|
|
71
|
+
verifiedWidget.focusInput();
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
verifiedWidget.focus(focusedItem);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
next() {
|
|
78
|
+
verifiedWidget.moveFocus(focusedItem, 'next');
|
|
79
|
+
alertAccessibleViewFocusChange(responseIndex, length, 'next');
|
|
80
|
+
resolveProvider(widgetService, codeEditorService);
|
|
81
|
+
},
|
|
82
|
+
previous() {
|
|
83
|
+
verifiedWidget.moveFocus(focusedItem, 'previous');
|
|
84
|
+
alertAccessibleViewFocusChange(responseIndex, length, 'previous');
|
|
85
|
+
resolveProvider(widgetService, codeEditorService);
|
|
86
|
+
},
|
|
87
|
+
options: { type: AccessibleViewType.View }
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
dispose() { }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { ChatResponseAccessibleView };
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
|
|
2
|
+
import { basename } from 'vscode/vscode/vs/base/common/path';
|
|
2
3
|
import { coalesce } from 'vscode/vscode/vs/base/common/arrays';
|
|
3
4
|
import { onUnexpectedExternalError } from 'vscode/vscode/vs/base/common/errors';
|
|
4
5
|
import { Iterable } from 'vscode/vscode/vs/base/common/iterator';
|
|
5
6
|
import { toDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
|
|
7
|
+
import { URI } from 'vscode/vscode/vs/base/common/uri';
|
|
8
|
+
import { showChatView } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chat';
|
|
6
9
|
import { IChatWidgetService } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chat.service';
|
|
7
10
|
import { ChatDynamicVariableModel } from 'vscode/vscode/vs/workbench/contrib/chat/browser/contrib/chatDynamicVariables';
|
|
11
|
+
import { ChatAgentLocation } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents';
|
|
8
12
|
import { ChatRequestVariablePart, ChatRequestDynamicVariablePart } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatParserTypes';
|
|
13
|
+
import { ChatContextAttachments } from './contrib/chatContextAttachments.js';
|
|
14
|
+
import { IViewsService } from 'vscode/vscode/vs/workbench/services/views/common/viewsService.service';
|
|
9
15
|
|
|
10
16
|
let ChatVariablesService = class ChatVariablesService {
|
|
11
|
-
constructor(chatWidgetService) {
|
|
17
|
+
constructor(chatWidgetService, viewsService) {
|
|
12
18
|
this.chatWidgetService = chatWidgetService;
|
|
19
|
+
this.viewsService = viewsService;
|
|
13
20
|
this._resolver = ( new Map());
|
|
14
21
|
}
|
|
15
|
-
async resolveVariables(prompt, model, progress, token) {
|
|
22
|
+
async resolveVariables(prompt, attachedContextVariables, model, progress, token) {
|
|
16
23
|
let resolvedVariables = [];
|
|
17
24
|
const jobs = [];
|
|
18
25
|
prompt.parts
|
|
@@ -28,18 +35,44 @@ let ChatVariablesService = class ChatVariablesService {
|
|
|
28
35
|
}
|
|
29
36
|
progress(item);
|
|
30
37
|
};
|
|
31
|
-
jobs.push(data.resolver(prompt.text, part.variableArg, model, variableProgressCallback, token).then(
|
|
32
|
-
|
|
38
|
+
jobs.push(data.resolver(prompt.text, part.variableArg, model, variableProgressCallback, token).then(value => {
|
|
39
|
+
if (value) {
|
|
40
|
+
resolvedVariables[i] = { id: data.data.id, modelDescription: data.data.modelDescription, name: part.variableName, range: part.range, value, references };
|
|
41
|
+
}
|
|
33
42
|
}).catch(onUnexpectedExternalError));
|
|
34
43
|
}
|
|
35
44
|
}
|
|
36
45
|
else if (part instanceof ChatRequestDynamicVariablePart) {
|
|
37
|
-
resolvedVariables[i] = { name: part.referenceText, range: part.range,
|
|
46
|
+
resolvedVariables[i] = { id: part.id, name: part.referenceText, range: part.range, value: part.data };
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
const resolvedAttachedContext = [];
|
|
50
|
+
attachedContextVariables
|
|
51
|
+
?.forEach((attachment, i) => {
|
|
52
|
+
const data = this._resolver.get(attachment.name?.toLowerCase());
|
|
53
|
+
if (data) {
|
|
54
|
+
const references = [];
|
|
55
|
+
const variableProgressCallback = (item) => {
|
|
56
|
+
if (item.kind === 'reference') {
|
|
57
|
+
references.push(item);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
progress(item);
|
|
61
|
+
};
|
|
62
|
+
jobs.push(data.resolver(prompt.text, '', model, variableProgressCallback, token).then(value => {
|
|
63
|
+
if (value) {
|
|
64
|
+
resolvedAttachedContext[i] = { id: data.data.id, modelDescription: data.data.modelDescription, name: attachment.name, range: attachment.range, value, references };
|
|
65
|
+
}
|
|
66
|
+
}).catch(onUnexpectedExternalError));
|
|
67
|
+
}
|
|
68
|
+
else if (attachment.isDynamic) {
|
|
69
|
+
resolvedAttachedContext[i] = { id: attachment.id, name: attachment.name, value: attachment.value };
|
|
38
70
|
}
|
|
39
71
|
});
|
|
40
72
|
await Promise.allSettled(jobs);
|
|
41
73
|
resolvedVariables = coalesce(resolvedVariables);
|
|
42
74
|
resolvedVariables.sort((a, b) => b.range.start - a.range.start);
|
|
75
|
+
resolvedVariables.push(...resolvedAttachedContext);
|
|
43
76
|
return {
|
|
44
77
|
variables: resolvedVariables,
|
|
45
78
|
};
|
|
@@ -47,9 +80,9 @@ let ChatVariablesService = class ChatVariablesService {
|
|
|
47
80
|
async resolveVariable(variableName, promptText, model, progress, token) {
|
|
48
81
|
const data = this._resolver.get(variableName.toLowerCase());
|
|
49
82
|
if (!data) {
|
|
50
|
-
return
|
|
83
|
+
return undefined;
|
|
51
84
|
}
|
|
52
|
-
return (await data.resolver(promptText, undefined, model, progress, token))
|
|
85
|
+
return (await data.resolver(promptText, undefined, model, progress, token));
|
|
53
86
|
}
|
|
54
87
|
hasVariable(name) {
|
|
55
88
|
return ( this._resolver.has(name.toLowerCase()));
|
|
@@ -82,9 +115,32 @@ let ChatVariablesService = class ChatVariablesService {
|
|
|
82
115
|
this._resolver.delete(key);
|
|
83
116
|
});
|
|
84
117
|
}
|
|
118
|
+
async attachContext(name, value, location) {
|
|
119
|
+
if (location !== ChatAgentLocation.Panel) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
await showChatView(this.viewsService);
|
|
123
|
+
const widget = this.chatWidgetService.lastFocusedWidget;
|
|
124
|
+
if (!widget || !widget.viewModel) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const key = name.toLowerCase();
|
|
128
|
+
if (key === 'file' && typeof value !== 'string') {
|
|
129
|
+
const uri = URI.isUri(value) ? value : value.uri;
|
|
130
|
+
const range = 'range' in value ? value.range : undefined;
|
|
131
|
+
widget.getContrib(ChatContextAttachments.ID)?.setContext(false, { value, id: ( uri.toString()) + (range?.toString() ?? ''), name: basename(uri.path), isFile: true, isDynamic: true });
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const resolved = this._resolver.get(key);
|
|
135
|
+
if (!resolved) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
widget.getContrib(ChatContextAttachments.ID)?.setContext(false, { ...resolved.data, value });
|
|
139
|
+
}
|
|
85
140
|
};
|
|
86
141
|
ChatVariablesService = ( __decorate([
|
|
87
|
-
( __param(0, IChatWidgetService))
|
|
142
|
+
( __param(0, IChatWidgetService)),
|
|
143
|
+
( __param(1, IViewsService))
|
|
88
144
|
], ChatVariablesService));
|
|
89
145
|
|
|
90
146
|
export { ChatVariablesService };
|
|
@@ -10,6 +10,7 @@ import { ServiceCollection } from 'vscode/vscode/vs/platform/instantiation/commo
|
|
|
10
10
|
import { IKeybindingService } from 'vscode/vscode/vs/platform/keybinding/common/keybinding.service';
|
|
11
11
|
import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service';
|
|
12
12
|
import { IOpenerService } from 'vscode/vscode/vs/platform/opener/common/opener.service';
|
|
13
|
+
import { StorageScope, StorageTarget } from 'vscode/vscode/vs/platform/storage/common/storage';
|
|
13
14
|
import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage.service';
|
|
14
15
|
import { ITelemetryService } from 'vscode/vscode/vs/platform/telemetry/common/telemetry.service';
|
|
15
16
|
import 'vscode/vscode/vs/platform/theme/common/colorUtils';
|
|
@@ -48,7 +49,7 @@ let ChatViewPane = class ChatViewPane extends ViewPane {
|
|
|
48
49
|
this.didProviderRegistrationFail = false;
|
|
49
50
|
this.didUnregisterProvider = false;
|
|
50
51
|
this.memento = ( new Memento('interactive-session-view-' + CHAT_PROVIDER_ID, this.storageService));
|
|
51
|
-
this.viewState = this.memento.getMemento(
|
|
52
|
+
this.viewState = this.memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
|
|
52
53
|
this._register(this.chatAgentService.onDidChangeAgents(() => {
|
|
53
54
|
if (this.chatAgentService.getDefaultAgent(ChatAgentLocation.Panel)) {
|
|
54
55
|
if (!this._widget?.viewModel) {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Disposable } from 'vscode/vscode/vs/base/common/lifecycle';
|
|
2
|
+
import { ChatWidget } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chatWidget';
|
|
3
|
+
|
|
4
|
+
class ChatContextAttachments extends Disposable {
|
|
5
|
+
static { this.ID = 'chatContextAttachments'; }
|
|
6
|
+
get id() {
|
|
7
|
+
return ChatContextAttachments.ID;
|
|
8
|
+
}
|
|
9
|
+
constructor(widget) {
|
|
10
|
+
super();
|
|
11
|
+
this.widget = widget;
|
|
12
|
+
this._attachedContext = ( new Set());
|
|
13
|
+
this._register(this.widget.onDidDeleteContext((e) => {
|
|
14
|
+
this._removeContext(e);
|
|
15
|
+
}));
|
|
16
|
+
this._register(this.widget.onDidSubmitAgent(() => {
|
|
17
|
+
this._clearAttachedContext();
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
getInputState() {
|
|
21
|
+
return [...( this._attachedContext.values())];
|
|
22
|
+
}
|
|
23
|
+
setInputState(s) {
|
|
24
|
+
if (!Array.isArray(s)) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
this.widget.setContext(true, ...s);
|
|
28
|
+
}
|
|
29
|
+
getContext() {
|
|
30
|
+
return ( new Set(( [...( this._attachedContext.values())].map((v) => v.id))));
|
|
31
|
+
}
|
|
32
|
+
setContext(overwrite, ...attachments) {
|
|
33
|
+
if (overwrite) {
|
|
34
|
+
this._attachedContext.clear();
|
|
35
|
+
}
|
|
36
|
+
for (const attachment of attachments) {
|
|
37
|
+
this._attachedContext.add(attachment);
|
|
38
|
+
}
|
|
39
|
+
this.widget.setContext(overwrite, ...attachments);
|
|
40
|
+
}
|
|
41
|
+
_removeContext(attachment) {
|
|
42
|
+
this._attachedContext.delete(attachment);
|
|
43
|
+
}
|
|
44
|
+
_clearAttachedContext() {
|
|
45
|
+
this._attachedContext.clear();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
ChatWidget.CONTRIBS.push(ChatContextAttachments);
|
|
49
|
+
|
|
50
|
+
export { ChatContextAttachments };
|