@codingame/monaco-vscode-chat-service-override 4.1.0 → 4.1.2
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 +9 -9
- package/external/tslib/tslib.es6.js +11 -0
- package/external/vscode-marked/lib/marked.esm.js +2200 -0
- package/override/vs/platform/dialogs/common/dialogs.js +10 -0
- package/package.json +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClear.js +17 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.js +115 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.js +503 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCopyActions.js +82 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatFileTreeActions.js +77 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatImportExport.js +110 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatMoveActions.js +171 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.js +271 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chat.contribution.js +317 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatAccessibilityService.js +60 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatContributionServiceImpl.js +423 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditor.js +98 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatQuick.js +285 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatVariables.js +90 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatViewPane.js +185 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatHistoryVariables.js +26 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.js +618 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatServiceImpl.js +600 -0
- package/vscode/src/vs/workbench/contrib/chat/common/voiceChat.js +141 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.js +40 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.js +41 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatNotebook.js +72 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSavingServiceImpl.js +236 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/common/inlineChatServiceImpl.js +33 -0
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
import { __decorate, __param } from '../../../../../../../../external/tslib/tslib.es6.js';
|
|
2
|
+
import { MarkdownString } from 'vscode/vscode/vs/base/common/htmlContent';
|
|
3
|
+
import { Disposable, MutableDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
|
|
4
|
+
import { ICodeEditorService } from 'vscode/vscode/vs/editor/browser/services/codeEditorService';
|
|
5
|
+
import { Range } from 'vscode/vscode/vs/editor/common/core/range';
|
|
6
|
+
import { getWordAtText } from 'vscode/vscode/vs/editor/common/core/wordHelper';
|
|
7
|
+
import { ILanguageFeaturesService } from 'vscode/vscode/vs/editor/common/services/languageFeatures';
|
|
8
|
+
import { localizeWithPath } from 'vscode/vscode/vs/nls';
|
|
9
|
+
import { Action2, registerAction2 } from 'vscode/vscode/vs/platform/actions/common/actions';
|
|
10
|
+
import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
|
|
11
|
+
import { Registry } from 'vscode/vscode/vs/platform/registry/common/platform';
|
|
12
|
+
import 'vscode/vscode/vs/platform/theme/common/colorUtils';
|
|
13
|
+
import 'vscode/vscode/vs/platform/theme/common/colors/baseColors';
|
|
14
|
+
import 'vscode/vscode/vs/platform/theme/common/colors/chartsColors';
|
|
15
|
+
import 'vscode/vscode/vs/platform/theme/common/colors/editorColors';
|
|
16
|
+
import { inputPlaceholderForeground } from 'vscode/vscode/vs/platform/theme/common/colors/inputColors';
|
|
17
|
+
import 'vscode/vscode/vs/platform/theme/common/colors/listColors';
|
|
18
|
+
import 'vscode/vscode/vs/platform/theme/common/colors/menuColors';
|
|
19
|
+
import 'vscode/vscode/vs/platform/theme/common/colors/minimapColors';
|
|
20
|
+
import 'vscode/vscode/vs/platform/theme/common/colors/miscColors';
|
|
21
|
+
import 'vscode/vscode/vs/platform/theme/common/colors/quickpickColors';
|
|
22
|
+
import 'vscode/vscode/vs/platform/theme/common/colors/searchColors';
|
|
23
|
+
import { IThemeService } from 'vscode/vscode/vs/platform/theme/common/themeService';
|
|
24
|
+
import { Extensions } from 'vscode/vscode/vs/workbench/common/contributions';
|
|
25
|
+
import { SubmitAction } from 'vscode/vscode/vs/workbench/contrib/chat/browser/actions/chatExecuteActions';
|
|
26
|
+
import { IChatWidgetService } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chat';
|
|
27
|
+
import { ChatInputPart } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chatInputPart';
|
|
28
|
+
import { ChatWidget } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chatWidget';
|
|
29
|
+
import { SelectAndInsertFileAction, dynamicVariableDecorationType } from 'vscode/vscode/vs/workbench/contrib/chat/browser/contrib/chatDynamicVariables';
|
|
30
|
+
import { ChatAgentLocation, IChatAgentService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents';
|
|
31
|
+
import { chatSlashCommandForeground, chatSlashCommandBackground } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatColors';
|
|
32
|
+
import { chatVariableLeader, ChatRequestVariablePart, ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashCommandPart, ChatRequestTextPart, chatAgentLeader, chatSubcommandLeader } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatParserTypes';
|
|
33
|
+
import { ChatRequestParser } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatRequestParser';
|
|
34
|
+
import { IChatSlashCommandService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatSlashCommands';
|
|
35
|
+
import { IChatVariablesService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatVariables';
|
|
36
|
+
|
|
37
|
+
var BuiltinDynamicCompletions_1, VariableCompletions_1;
|
|
38
|
+
const decorationDescription = 'chat';
|
|
39
|
+
const placeholderDecorationType = 'chat-session-detail';
|
|
40
|
+
const slashCommandTextDecorationType = 'chat-session-text';
|
|
41
|
+
const variableTextDecorationType = 'chat-variable-text';
|
|
42
|
+
function agentAndCommandToKey(agent, subcommand) {
|
|
43
|
+
return subcommand ? `${agent.id}__${subcommand}` : agent.id;
|
|
44
|
+
}
|
|
45
|
+
let InputEditorDecorations = class InputEditorDecorations extends Disposable {
|
|
46
|
+
constructor(widget, codeEditorService, themeService, chatAgentService) {
|
|
47
|
+
super();
|
|
48
|
+
this.widget = widget;
|
|
49
|
+
this.codeEditorService = codeEditorService;
|
|
50
|
+
this.themeService = themeService;
|
|
51
|
+
this.chatAgentService = chatAgentService;
|
|
52
|
+
this.id = 'inputEditorDecorations';
|
|
53
|
+
this.previouslyUsedAgents = ( new Set());
|
|
54
|
+
this.viewModelDisposables = this._register(( new MutableDisposable()));
|
|
55
|
+
this.codeEditorService.registerDecorationType(decorationDescription, placeholderDecorationType, {});
|
|
56
|
+
this._register(this.themeService.onDidColorThemeChange(() => this.updateRegisteredDecorationTypes()));
|
|
57
|
+
this.updateRegisteredDecorationTypes();
|
|
58
|
+
this.updateInputEditorDecorations();
|
|
59
|
+
this._register(this.widget.inputEditor.onDidChangeModelContent(() => this.updateInputEditorDecorations()));
|
|
60
|
+
this._register(this.widget.onDidChangeParsedInput(() => this.updateInputEditorDecorations()));
|
|
61
|
+
this._register(this.widget.onDidChangeViewModel(() => {
|
|
62
|
+
this.registerViewModelListeners();
|
|
63
|
+
this.previouslyUsedAgents.clear();
|
|
64
|
+
this.updateInputEditorDecorations();
|
|
65
|
+
}));
|
|
66
|
+
this._register(this.widget.onDidSubmitAgent((e) => {
|
|
67
|
+
this.previouslyUsedAgents.add(agentAndCommandToKey(e.agent, e.slashCommand?.name));
|
|
68
|
+
}));
|
|
69
|
+
this._register(this.chatAgentService.onDidChangeAgents(() => this.updateInputEditorDecorations()));
|
|
70
|
+
this.registerViewModelListeners();
|
|
71
|
+
}
|
|
72
|
+
registerViewModelListeners() {
|
|
73
|
+
this.viewModelDisposables.value = this.widget.viewModel?.onDidChange(e => {
|
|
74
|
+
if (e?.kind === 'changePlaceholder' || e?.kind === 'initialize') {
|
|
75
|
+
this.updateInputEditorDecorations();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
updateRegisteredDecorationTypes() {
|
|
80
|
+
this.codeEditorService.removeDecorationType(variableTextDecorationType);
|
|
81
|
+
this.codeEditorService.removeDecorationType(dynamicVariableDecorationType);
|
|
82
|
+
this.codeEditorService.removeDecorationType(slashCommandTextDecorationType);
|
|
83
|
+
const theme = this.themeService.getColorTheme();
|
|
84
|
+
this.codeEditorService.registerDecorationType(decorationDescription, slashCommandTextDecorationType, {
|
|
85
|
+
color: theme.getColor(chatSlashCommandForeground)?.toString(),
|
|
86
|
+
backgroundColor: theme.getColor(chatSlashCommandBackground)?.toString(),
|
|
87
|
+
borderRadius: '3px'
|
|
88
|
+
});
|
|
89
|
+
this.codeEditorService.registerDecorationType(decorationDescription, variableTextDecorationType, {
|
|
90
|
+
color: theme.getColor(chatSlashCommandForeground)?.toString(),
|
|
91
|
+
backgroundColor: theme.getColor(chatSlashCommandBackground)?.toString(),
|
|
92
|
+
borderRadius: '3px'
|
|
93
|
+
});
|
|
94
|
+
this.codeEditorService.registerDecorationType(decorationDescription, dynamicVariableDecorationType, {
|
|
95
|
+
color: theme.getColor(chatSlashCommandForeground)?.toString(),
|
|
96
|
+
backgroundColor: theme.getColor(chatSlashCommandBackground)?.toString(),
|
|
97
|
+
borderRadius: '3px'
|
|
98
|
+
});
|
|
99
|
+
this.updateInputEditorDecorations();
|
|
100
|
+
}
|
|
101
|
+
getPlaceholderColor() {
|
|
102
|
+
const theme = this.themeService.getColorTheme();
|
|
103
|
+
const transparentForeground = theme.getColor(inputPlaceholderForeground);
|
|
104
|
+
return transparentForeground?.toString();
|
|
105
|
+
}
|
|
106
|
+
async updateInputEditorDecorations() {
|
|
107
|
+
const inputValue = this.widget.inputEditor.getValue();
|
|
108
|
+
const viewModel = this.widget.viewModel;
|
|
109
|
+
if (!viewModel) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (!inputValue) {
|
|
113
|
+
const defaultAgent = this.chatAgentService.getDefaultAgent(this.widget.location);
|
|
114
|
+
const decoration = [
|
|
115
|
+
{
|
|
116
|
+
range: {
|
|
117
|
+
startLineNumber: 1,
|
|
118
|
+
endLineNumber: 1,
|
|
119
|
+
startColumn: 1,
|
|
120
|
+
endColumn: 1000
|
|
121
|
+
},
|
|
122
|
+
renderOptions: {
|
|
123
|
+
after: {
|
|
124
|
+
contentText: viewModel.inputPlaceholder ?? defaultAgent?.description ?? '',
|
|
125
|
+
color: this.getPlaceholderColor()
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
];
|
|
130
|
+
this.widget.inputEditor.setDecorationsByType(decorationDescription, placeholderDecorationType, decoration);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const parsedRequest = this.widget.parsedInput.parts;
|
|
134
|
+
let placeholderDecoration;
|
|
135
|
+
const agentPart = parsedRequest.find((p) => p instanceof ChatRequestAgentPart);
|
|
136
|
+
const agentSubcommandPart = parsedRequest.find((p) => p instanceof ChatRequestAgentSubcommandPart);
|
|
137
|
+
const slashCommandPart = parsedRequest.find((p) => p instanceof ChatRequestSlashCommandPart);
|
|
138
|
+
const exactlyOneSpaceAfterPart = (part) => {
|
|
139
|
+
const partIdx = parsedRequest.indexOf(part);
|
|
140
|
+
if (parsedRequest.length > partIdx + 2) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
const nextPart = parsedRequest[partIdx + 1];
|
|
144
|
+
return nextPart && nextPart instanceof ChatRequestTextPart && nextPart.text === ' ';
|
|
145
|
+
};
|
|
146
|
+
const getRangeForPlaceholder = (part) => ({
|
|
147
|
+
startLineNumber: part.editorRange.startLineNumber,
|
|
148
|
+
endLineNumber: part.editorRange.endLineNumber,
|
|
149
|
+
startColumn: part.editorRange.endColumn + 1,
|
|
150
|
+
endColumn: 1000
|
|
151
|
+
});
|
|
152
|
+
const onlyAgentAndWhitespace = agentPart && parsedRequest.every(p => p instanceof ChatRequestTextPart && !p.text.trim().length || p instanceof ChatRequestAgentPart);
|
|
153
|
+
if (onlyAgentAndWhitespace) {
|
|
154
|
+
const isFollowupSlashCommand = ( this.previouslyUsedAgents.has(agentAndCommandToKey(agentPart.agent, undefined)));
|
|
155
|
+
const shouldRenderFollowupPlaceholder = isFollowupSlashCommand && agentPart.agent.metadata.followupPlaceholder;
|
|
156
|
+
if (agentPart.agent.description && exactlyOneSpaceAfterPart(agentPart)) {
|
|
157
|
+
placeholderDecoration = [{
|
|
158
|
+
range: getRangeForPlaceholder(agentPart),
|
|
159
|
+
renderOptions: {
|
|
160
|
+
after: {
|
|
161
|
+
contentText: shouldRenderFollowupPlaceholder ? agentPart.agent.metadata.followupPlaceholder : agentPart.agent.description,
|
|
162
|
+
color: this.getPlaceholderColor(),
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}];
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const onlyAgentCommandAndWhitespace = agentPart && agentSubcommandPart && parsedRequest.every(p => p instanceof ChatRequestTextPart && !p.text.trim().length || p instanceof ChatRequestAgentPart || p instanceof ChatRequestAgentSubcommandPart);
|
|
169
|
+
if (onlyAgentCommandAndWhitespace) {
|
|
170
|
+
const isFollowupSlashCommand = ( this.previouslyUsedAgents.has(agentAndCommandToKey(agentPart.agent, agentSubcommandPart.command.name)));
|
|
171
|
+
const shouldRenderFollowupPlaceholder = isFollowupSlashCommand && agentSubcommandPart.command.followupPlaceholder;
|
|
172
|
+
if (agentSubcommandPart?.command.description && exactlyOneSpaceAfterPart(agentSubcommandPart)) {
|
|
173
|
+
placeholderDecoration = [{
|
|
174
|
+
range: getRangeForPlaceholder(agentSubcommandPart),
|
|
175
|
+
renderOptions: {
|
|
176
|
+
after: {
|
|
177
|
+
contentText: shouldRenderFollowupPlaceholder ? agentSubcommandPart.command.followupPlaceholder : agentSubcommandPart.command.description,
|
|
178
|
+
color: this.getPlaceholderColor(),
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}];
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
this.widget.inputEditor.setDecorationsByType(decorationDescription, placeholderDecorationType, placeholderDecoration ?? []);
|
|
185
|
+
const textDecorations = [];
|
|
186
|
+
if (agentPart) {
|
|
187
|
+
const isDupe = !!this.chatAgentService.getAgents().find(other => other.name === agentPart.agent.name && other.id !== agentPart.agent.id);
|
|
188
|
+
const id = isDupe ? `(${agentPart.agent.id}) ` : '';
|
|
189
|
+
const agentHover = `${id}${agentPart.agent.description}`;
|
|
190
|
+
textDecorations.push({ range: agentPart.editorRange, hoverMessage: ( new MarkdownString(agentHover)) });
|
|
191
|
+
if (agentSubcommandPart) {
|
|
192
|
+
textDecorations.push({ range: agentSubcommandPart.editorRange, hoverMessage: ( new MarkdownString(agentSubcommandPart.command.description)) });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (slashCommandPart) {
|
|
196
|
+
textDecorations.push({ range: slashCommandPart.editorRange });
|
|
197
|
+
}
|
|
198
|
+
this.widget.inputEditor.setDecorationsByType(decorationDescription, slashCommandTextDecorationType, textDecorations);
|
|
199
|
+
const varDecorations = [];
|
|
200
|
+
const variableParts = parsedRequest.filter((p) => p instanceof ChatRequestVariablePart);
|
|
201
|
+
for (const variable of variableParts) {
|
|
202
|
+
varDecorations.push({ range: variable.editorRange });
|
|
203
|
+
}
|
|
204
|
+
this.widget.inputEditor.setDecorationsByType(decorationDescription, variableTextDecorationType, varDecorations);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
InputEditorDecorations = ( __decorate([
|
|
208
|
+
( __param(1, ICodeEditorService)),
|
|
209
|
+
( __param(2, IThemeService)),
|
|
210
|
+
( __param(3, IChatAgentService))
|
|
211
|
+
], InputEditorDecorations));
|
|
212
|
+
class InputEditorSlashCommandMode extends Disposable {
|
|
213
|
+
constructor(widget) {
|
|
214
|
+
super();
|
|
215
|
+
this.widget = widget;
|
|
216
|
+
this.id = 'InputEditorSlashCommandMode';
|
|
217
|
+
this._register(this.widget.onDidSubmitAgent(e => {
|
|
218
|
+
this.repopulateAgentCommand(e.agent, e.slashCommand);
|
|
219
|
+
}));
|
|
220
|
+
}
|
|
221
|
+
async repopulateAgentCommand(agent, slashCommand) {
|
|
222
|
+
let value;
|
|
223
|
+
if (slashCommand && slashCommand.isSticky) {
|
|
224
|
+
value = `${chatAgentLeader}${agent.name} ${chatSubcommandLeader}${slashCommand.name} `;
|
|
225
|
+
}
|
|
226
|
+
else if (agent.metadata.isSticky) {
|
|
227
|
+
value = `${chatAgentLeader}${agent.name} `;
|
|
228
|
+
}
|
|
229
|
+
if (value) {
|
|
230
|
+
this.widget.inputEditor.setValue(value);
|
|
231
|
+
this.widget.inputEditor.setPosition({ lineNumber: 1, column: value.length + 1 });
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
ChatWidget.CONTRIBS.push(InputEditorDecorations, InputEditorSlashCommandMode);
|
|
236
|
+
let SlashCommandCompletions = class SlashCommandCompletions extends Disposable {
|
|
237
|
+
constructor(languageFeaturesService, chatWidgetService, chatSlashCommandService) {
|
|
238
|
+
super();
|
|
239
|
+
this.languageFeaturesService = languageFeaturesService;
|
|
240
|
+
this.chatWidgetService = chatWidgetService;
|
|
241
|
+
this.chatSlashCommandService = chatSlashCommandService;
|
|
242
|
+
this._register(this.languageFeaturesService.completionProvider.register({ scheme: ChatInputPart.INPUT_SCHEME, hasAccessToAllModels: true }, {
|
|
243
|
+
_debugDisplayName: 'globalSlashCommands',
|
|
244
|
+
triggerCharacters: ['/'],
|
|
245
|
+
provideCompletionItems: async (model, position, _context, _token) => {
|
|
246
|
+
const widget = this.chatWidgetService.getWidgetByInputUri(model.uri);
|
|
247
|
+
if (!widget || !widget.viewModel || widget.location !== ChatAgentLocation.Panel ) {
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
const range = computeCompletionRanges(model, position, /\/\w*/g);
|
|
251
|
+
if (!range) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
const parsedRequest = widget.parsedInput.parts;
|
|
255
|
+
const usedAgent = parsedRequest.find(p => p instanceof ChatRequestAgentPart);
|
|
256
|
+
if (usedAgent) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
const slashCommands = this.chatSlashCommandService.getCommands();
|
|
260
|
+
if (!slashCommands) {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
suggestions: ( slashCommands.map((c, i) => {
|
|
265
|
+
const withSlash = `/${c.command}`;
|
|
266
|
+
return {
|
|
267
|
+
label: withSlash,
|
|
268
|
+
insertText: c.executeImmediately ? '' : `${withSlash} `,
|
|
269
|
+
detail: c.detail,
|
|
270
|
+
range: ( new Range(1, 1, 1, 1)),
|
|
271
|
+
sortText: c.sortText ?? 'a'.repeat(i + 1),
|
|
272
|
+
kind: 18 ,
|
|
273
|
+
command: c.executeImmediately ? { id: SubmitAction.ID, title: withSlash, arguments: [{ widget, inputValue: `${withSlash} ` }] } : undefined,
|
|
274
|
+
};
|
|
275
|
+
}))
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}));
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
SlashCommandCompletions = ( __decorate([
|
|
282
|
+
( __param(0, ILanguageFeaturesService)),
|
|
283
|
+
( __param(1, IChatWidgetService)),
|
|
284
|
+
( __param(2, IChatSlashCommandService))
|
|
285
|
+
], SlashCommandCompletions));
|
|
286
|
+
( Registry.as(Extensions.Workbench)).registerWorkbenchContribution(SlashCommandCompletions, 4 );
|
|
287
|
+
let AgentCompletions = class AgentCompletions extends Disposable {
|
|
288
|
+
constructor(languageFeaturesService, chatWidgetService, chatAgentService) {
|
|
289
|
+
super();
|
|
290
|
+
this.languageFeaturesService = languageFeaturesService;
|
|
291
|
+
this.chatWidgetService = chatWidgetService;
|
|
292
|
+
this.chatAgentService = chatAgentService;
|
|
293
|
+
this._register(this.languageFeaturesService.completionProvider.register({ scheme: ChatInputPart.INPUT_SCHEME, hasAccessToAllModels: true }, {
|
|
294
|
+
_debugDisplayName: 'chatAgent',
|
|
295
|
+
triggerCharacters: ['@'],
|
|
296
|
+
provideCompletionItems: async (model, position, _context, _token) => {
|
|
297
|
+
const widget = this.chatWidgetService.getWidgetByInputUri(model.uri);
|
|
298
|
+
if (!widget || !widget.viewModel || widget.location !== ChatAgentLocation.Panel ) {
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
const parsedRequest = widget.parsedInput.parts;
|
|
302
|
+
const usedAgent = parsedRequest.find(p => p instanceof ChatRequestAgentPart);
|
|
303
|
+
if (usedAgent && !Range.containsPosition(usedAgent.editorRange, position)) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
const range = computeCompletionRanges(model, position, /@\w*/g);
|
|
307
|
+
if (!range) {
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
const agents = this.chatAgentService.getAgents()
|
|
311
|
+
.filter(a => !a.isDefault)
|
|
312
|
+
.filter(a => a.locations.includes(widget.location));
|
|
313
|
+
return {
|
|
314
|
+
suggestions: ( agents.map((a, i) => {
|
|
315
|
+
const withAt = `@${a.name}`;
|
|
316
|
+
const isDupe = !!agents.find(other => other.name === a.name && other.id !== a.id);
|
|
317
|
+
return {
|
|
318
|
+
label: isDupe ?
|
|
319
|
+
{ label: withAt, description: a.description, detail: ` (${a.id})` } :
|
|
320
|
+
withAt,
|
|
321
|
+
insertText: `${withAt} `,
|
|
322
|
+
detail: a.description,
|
|
323
|
+
range: ( new Range(1, 1, 1, 1)),
|
|
324
|
+
command: { id: AssignSelectedAgentAction.ID, title: AssignSelectedAgentAction.ID, arguments: [{ agent: a, widget }] },
|
|
325
|
+
kind: 18 ,
|
|
326
|
+
};
|
|
327
|
+
}))
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
}));
|
|
331
|
+
this._register(this.languageFeaturesService.completionProvider.register({ scheme: ChatInputPart.INPUT_SCHEME, hasAccessToAllModels: true }, {
|
|
332
|
+
_debugDisplayName: 'chatAgentSubcommand',
|
|
333
|
+
triggerCharacters: ['/'],
|
|
334
|
+
provideCompletionItems: async (model, position, _context, token) => {
|
|
335
|
+
const widget = this.chatWidgetService.getWidgetByInputUri(model.uri);
|
|
336
|
+
if (!widget || !widget.viewModel || widget.location !== ChatAgentLocation.Panel ) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const range = computeCompletionRanges(model, position, /\/\w*/g);
|
|
340
|
+
if (!range) {
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
const parsedRequest = widget.parsedInput.parts;
|
|
344
|
+
const usedAgentIdx = parsedRequest.findIndex((p) => p instanceof ChatRequestAgentPart);
|
|
345
|
+
if (usedAgentIdx < 0) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const usedSubcommand = parsedRequest.find(p => p instanceof ChatRequestAgentSubcommandPart);
|
|
349
|
+
if (usedSubcommand) {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
for (const partAfterAgent of parsedRequest.slice(usedAgentIdx + 1)) {
|
|
353
|
+
if (!(partAfterAgent instanceof ChatRequestTextPart) || !partAfterAgent.text.trim().match(/^(\/\w*)?$/)) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
const usedAgent = parsedRequest[usedAgentIdx];
|
|
358
|
+
return {
|
|
359
|
+
suggestions: ( usedAgent.agent.slashCommands.map((c, i) => {
|
|
360
|
+
const withSlash = `/${c.name}`;
|
|
361
|
+
return {
|
|
362
|
+
label: withSlash,
|
|
363
|
+
insertText: `${withSlash} `,
|
|
364
|
+
detail: c.description,
|
|
365
|
+
range,
|
|
366
|
+
kind: 18 ,
|
|
367
|
+
};
|
|
368
|
+
}))
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
}));
|
|
372
|
+
this._register(this.languageFeaturesService.completionProvider.register({ scheme: ChatInputPart.INPUT_SCHEME, hasAccessToAllModels: true }, {
|
|
373
|
+
_debugDisplayName: 'chatAgentAndSubcommand',
|
|
374
|
+
triggerCharacters: ['/'],
|
|
375
|
+
provideCompletionItems: async (model, position, _context, token) => {
|
|
376
|
+
const widget = this.chatWidgetService.getWidgetByInputUri(model.uri);
|
|
377
|
+
const viewModel = widget?.viewModel;
|
|
378
|
+
if (!widget || !viewModel || widget.location !== ChatAgentLocation.Panel ) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const range = computeCompletionRanges(model, position, /\/\w*/g);
|
|
382
|
+
if (!range) {
|
|
383
|
+
return null;
|
|
384
|
+
}
|
|
385
|
+
const agents = this.chatAgentService.getAgents()
|
|
386
|
+
.filter(a => a.locations.includes(widget.location));
|
|
387
|
+
const justAgents = ( agents
|
|
388
|
+
.filter(a => !a.isDefault)
|
|
389
|
+
.map(agent => {
|
|
390
|
+
const isDupe = !!agents.find(other => other.name === agent.name && other.id !== agent.id);
|
|
391
|
+
const detail = agent.description;
|
|
392
|
+
const agentLabel = `${chatAgentLeader}${agent.name}`;
|
|
393
|
+
return {
|
|
394
|
+
label: isDupe ?
|
|
395
|
+
{ label: agentLabel, description: agent.description, detail: ` (${agent.id})` } :
|
|
396
|
+
agentLabel,
|
|
397
|
+
detail,
|
|
398
|
+
filterText: `${chatSubcommandLeader}${agent.name}`,
|
|
399
|
+
insertText: `${agentLabel} `,
|
|
400
|
+
range: ( new Range(1, 1, 1, 1)),
|
|
401
|
+
kind: 18 ,
|
|
402
|
+
sortText: `${chatSubcommandLeader}${agent.id}`,
|
|
403
|
+
command: { id: AssignSelectedAgentAction.ID, title: AssignSelectedAgentAction.ID, arguments: [{ agent, widget }] },
|
|
404
|
+
};
|
|
405
|
+
}));
|
|
406
|
+
return {
|
|
407
|
+
suggestions: justAgents.concat(agents.flatMap(agent => ( agent.slashCommands.map((c, i) => {
|
|
408
|
+
const agentLabel = `${chatAgentLeader}${agent.name}`;
|
|
409
|
+
const withSlash = `${chatSubcommandLeader}${c.name}`;
|
|
410
|
+
return {
|
|
411
|
+
label: { label: withSlash, description: agentLabel },
|
|
412
|
+
filterText: `${chatSubcommandLeader}${agent.name}${c.name}`,
|
|
413
|
+
commitCharacters: [' '],
|
|
414
|
+
insertText: `${agentLabel} ${withSlash} `,
|
|
415
|
+
detail: `(${agentLabel}) ${c.description ?? ''}`,
|
|
416
|
+
range: ( new Range(1, 1, 1, 1)),
|
|
417
|
+
kind: 18 ,
|
|
418
|
+
sortText: `${chatSubcommandLeader}${agent.id}${c.name}`,
|
|
419
|
+
command: { id: AssignSelectedAgentAction.ID, title: AssignSelectedAgentAction.ID, arguments: [{ agent, widget }] },
|
|
420
|
+
};
|
|
421
|
+
}))))
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
}));
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
AgentCompletions = ( __decorate([
|
|
428
|
+
( __param(0, ILanguageFeaturesService)),
|
|
429
|
+
( __param(1, IChatWidgetService)),
|
|
430
|
+
( __param(2, IChatAgentService))
|
|
431
|
+
], AgentCompletions));
|
|
432
|
+
( Registry.as(Extensions.Workbench)).registerWorkbenchContribution(AgentCompletions, 4 );
|
|
433
|
+
class AssignSelectedAgentAction extends Action2 {
|
|
434
|
+
static { this.ID = 'workbench.action.chat.assignSelectedAgent'; }
|
|
435
|
+
constructor() {
|
|
436
|
+
super({
|
|
437
|
+
id: AssignSelectedAgentAction.ID,
|
|
438
|
+
title: ''
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
async run(accessor, ...args) {
|
|
442
|
+
const arg = args[0];
|
|
443
|
+
if (!arg || !arg.widget || !arg.agent) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
arg.widget.lastSelectedAgent = arg.agent;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
registerAction2(AssignSelectedAgentAction);
|
|
450
|
+
let BuiltinDynamicCompletions = class BuiltinDynamicCompletions extends Disposable {
|
|
451
|
+
static { BuiltinDynamicCompletions_1 = this; }
|
|
452
|
+
static { this.VariableNameDef = ( new RegExp(`${chatVariableLeader}\\w*`, 'g')); }
|
|
453
|
+
constructor(languageFeaturesService, chatWidgetService) {
|
|
454
|
+
super();
|
|
455
|
+
this.languageFeaturesService = languageFeaturesService;
|
|
456
|
+
this.chatWidgetService = chatWidgetService;
|
|
457
|
+
this._register(this.languageFeaturesService.completionProvider.register({ scheme: ChatInputPart.INPUT_SCHEME, hasAccessToAllModels: true }, {
|
|
458
|
+
_debugDisplayName: 'chatDynamicCompletions',
|
|
459
|
+
triggerCharacters: [chatVariableLeader],
|
|
460
|
+
provideCompletionItems: async (model, position, _context, _token) => {
|
|
461
|
+
const widget = this.chatWidgetService.getWidgetByInputUri(model.uri);
|
|
462
|
+
if (!widget || !widget.supportsFileReferences || widget.location !== ChatAgentLocation.Panel ) {
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
const range = computeCompletionRanges(model, position, BuiltinDynamicCompletions_1.VariableNameDef);
|
|
466
|
+
if (!range) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
const afterRange = ( new Range(
|
|
470
|
+
position.lineNumber,
|
|
471
|
+
range.replace.startColumn,
|
|
472
|
+
position.lineNumber,
|
|
473
|
+
range.replace.startColumn + '#file:'.length
|
|
474
|
+
));
|
|
475
|
+
return {
|
|
476
|
+
suggestions: [
|
|
477
|
+
{
|
|
478
|
+
label: `${chatVariableLeader}file`,
|
|
479
|
+
insertText: `${chatVariableLeader}file:`,
|
|
480
|
+
detail: ( localizeWithPath(
|
|
481
|
+
'vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib',
|
|
482
|
+
'pickFileLabel',
|
|
483
|
+
"Pick a file"
|
|
484
|
+
)),
|
|
485
|
+
range,
|
|
486
|
+
kind: 18 ,
|
|
487
|
+
command: { id: SelectAndInsertFileAction.ID, title: SelectAndInsertFileAction.ID, arguments: [{ widget, range: afterRange }] },
|
|
488
|
+
sortText: 'z'
|
|
489
|
+
}
|
|
490
|
+
]
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
}));
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
BuiltinDynamicCompletions = BuiltinDynamicCompletions_1 = ( __decorate([
|
|
497
|
+
( __param(0, ILanguageFeaturesService)),
|
|
498
|
+
( __param(1, IChatWidgetService))
|
|
499
|
+
], BuiltinDynamicCompletions));
|
|
500
|
+
( Registry.as(Extensions.Workbench)).registerWorkbenchContribution(BuiltinDynamicCompletions, 4 );
|
|
501
|
+
function computeCompletionRanges(model, position, reg) {
|
|
502
|
+
const varWord = getWordAtText(position.column, reg, model.getLineContent(position.lineNumber), 0);
|
|
503
|
+
if (!varWord && model.getWordUntilPosition(position).word) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
let insert;
|
|
507
|
+
let replace;
|
|
508
|
+
if (!varWord) {
|
|
509
|
+
insert = replace = Range.fromPositions(position);
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
insert = ( new Range(
|
|
513
|
+
position.lineNumber,
|
|
514
|
+
varWord.startColumn,
|
|
515
|
+
position.lineNumber,
|
|
516
|
+
position.column
|
|
517
|
+
));
|
|
518
|
+
replace = ( new Range(
|
|
519
|
+
position.lineNumber,
|
|
520
|
+
varWord.startColumn,
|
|
521
|
+
position.lineNumber,
|
|
522
|
+
varWord.endColumn
|
|
523
|
+
));
|
|
524
|
+
}
|
|
525
|
+
return { insert, replace, varWord };
|
|
526
|
+
}
|
|
527
|
+
let VariableCompletions = class VariableCompletions extends Disposable {
|
|
528
|
+
static { VariableCompletions_1 = this; }
|
|
529
|
+
static { this.VariableNameDef = ( new RegExp(`${chatVariableLeader}\\w*`, 'g')); }
|
|
530
|
+
constructor(languageFeaturesService, chatWidgetService, chatVariablesService) {
|
|
531
|
+
super();
|
|
532
|
+
this.languageFeaturesService = languageFeaturesService;
|
|
533
|
+
this.chatWidgetService = chatWidgetService;
|
|
534
|
+
this.chatVariablesService = chatVariablesService;
|
|
535
|
+
this._register(this.languageFeaturesService.completionProvider.register({ scheme: ChatInputPart.INPUT_SCHEME, hasAccessToAllModels: true }, {
|
|
536
|
+
_debugDisplayName: 'chatVariables',
|
|
537
|
+
triggerCharacters: [chatVariableLeader],
|
|
538
|
+
provideCompletionItems: async (model, position, _context, _token) => {
|
|
539
|
+
const widget = this.chatWidgetService.getWidgetByInputUri(model.uri);
|
|
540
|
+
if (!widget || widget.location !== ChatAgentLocation.Panel ) {
|
|
541
|
+
return null;
|
|
542
|
+
}
|
|
543
|
+
const range = computeCompletionRanges(model, position, VariableCompletions_1.VariableNameDef);
|
|
544
|
+
if (!range) {
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
const usedVariables = widget.parsedInput.parts.filter((p) => p instanceof ChatRequestVariablePart);
|
|
548
|
+
const variableItems = ( Array.from(this.chatVariablesService.getVariables())
|
|
549
|
+
.filter(v => !( usedVariables.some(usedVar => usedVar.variableName === v.name)))
|
|
550
|
+
.map(v => {
|
|
551
|
+
const withLeader = `${chatVariableLeader}${v.name}`;
|
|
552
|
+
return {
|
|
553
|
+
label: withLeader,
|
|
554
|
+
range,
|
|
555
|
+
insertText: withLeader + ' ',
|
|
556
|
+
detail: v.description,
|
|
557
|
+
kind: 18 ,
|
|
558
|
+
sortText: 'z'
|
|
559
|
+
};
|
|
560
|
+
}));
|
|
561
|
+
return {
|
|
562
|
+
suggestions: variableItems
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
}));
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
VariableCompletions = VariableCompletions_1 = ( __decorate([
|
|
569
|
+
( __param(0, ILanguageFeaturesService)),
|
|
570
|
+
( __param(1, IChatWidgetService)),
|
|
571
|
+
( __param(2, IChatVariablesService))
|
|
572
|
+
], VariableCompletions));
|
|
573
|
+
( Registry.as(Extensions.Workbench)).registerWorkbenchContribution(VariableCompletions, 4 );
|
|
574
|
+
let ChatTokenDeleter = class ChatTokenDeleter extends Disposable {
|
|
575
|
+
constructor(widget, instantiationService) {
|
|
576
|
+
super();
|
|
577
|
+
this.widget = widget;
|
|
578
|
+
this.instantiationService = instantiationService;
|
|
579
|
+
this.id = 'chatTokenDeleter';
|
|
580
|
+
const parser = this.instantiationService.createInstance(ChatRequestParser);
|
|
581
|
+
const inputValue = this.widget.inputEditor.getValue();
|
|
582
|
+
let previousInputValue;
|
|
583
|
+
let previousSelectedAgent;
|
|
584
|
+
this._register(this.widget.inputEditor.onDidChangeModelContent(e => {
|
|
585
|
+
if (!previousInputValue) {
|
|
586
|
+
previousInputValue = inputValue;
|
|
587
|
+
previousSelectedAgent = this.widget.lastSelectedAgent;
|
|
588
|
+
}
|
|
589
|
+
const change = e.changes[0];
|
|
590
|
+
if (!change.text && this.widget.viewModel) {
|
|
591
|
+
const previousParsedValue = parser.parseChatRequest(this.widget.viewModel.sessionId, previousInputValue, ChatAgentLocation.Panel, { selectedAgent: previousSelectedAgent });
|
|
592
|
+
const deletableTokens = previousParsedValue.parts.filter(p => p instanceof ChatRequestAgentPart || p instanceof ChatRequestAgentSubcommandPart || p instanceof ChatRequestSlashCommandPart || p instanceof ChatRequestVariablePart);
|
|
593
|
+
deletableTokens.forEach(token => {
|
|
594
|
+
const deletedRangeOfToken = Range.intersectRanges(token.editorRange, change.range);
|
|
595
|
+
if (deletedRangeOfToken && Range.compareRangesUsingStarts(token.editorRange, change.range) < 0) {
|
|
596
|
+
const length = deletedRangeOfToken.endColumn - deletedRangeOfToken.startColumn;
|
|
597
|
+
const rangeToDelete = ( new Range(
|
|
598
|
+
token.editorRange.startLineNumber,
|
|
599
|
+
token.editorRange.startColumn,
|
|
600
|
+
token.editorRange.endLineNumber,
|
|
601
|
+
token.editorRange.endColumn - length
|
|
602
|
+
));
|
|
603
|
+
this.widget.inputEditor.executeEdits(this.id, [{
|
|
604
|
+
range: rangeToDelete,
|
|
605
|
+
text: '',
|
|
606
|
+
}]);
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
previousInputValue = this.widget.inputEditor.getValue();
|
|
611
|
+
previousSelectedAgent = this.widget.lastSelectedAgent;
|
|
612
|
+
}));
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
ChatTokenDeleter = ( __decorate([
|
|
616
|
+
( __param(1, IInstantiationService))
|
|
617
|
+
], ChatTokenDeleter));
|
|
618
|
+
ChatWidget.CONTRIBS.push(ChatTokenDeleter);
|