Skip to content

Commit 7e899bf

Browse files
authored
feat: support dynamic variable sublists (microsoft#210473)
1 parent c132d06 commit 7e899bf

File tree

7 files changed

+48
-8
lines changed

7 files changed

+48
-8
lines changed

src/vs/workbench/api/browser/mainThreadChatAgents2.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ export class MainThreadChatAgents2 extends Disposable implements MainThreadChatA
210210
kind: CompletionItemKind.Text,
211211
detail: v.detail,
212212
documentation: v.documentation,
213-
command: { id: AddDynamicVariableAction.ID, title: '', arguments: [{ widget, range: rangeAfterInsert, variableData: revive(v.values) } satisfies IAddDynamicVariableContext] }
213+
command: { id: AddDynamicVariableAction.ID, title: '', arguments: [{ widget, range: rangeAfterInsert, variableData: revive(v.values), command: v.command } satisfies IAddDynamicVariableContext] }
214214
} satisfies CompletionItem;
215215
});
216216

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,7 @@ export interface IChatAgentCompletionItem {
12321232
values: IChatRequestVariableValueDto[];
12331233
detail?: string;
12341234
documentation?: string | IMarkdownString;
1235+
command?: ICommandDto;
12351236
}
12361237

12371238
export type IChatContentProgressDto =

src/vs/workbench/api/common/extHostChatAgents2.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { toErrorMessage } from 'vs/base/common/errorMessage';
1010
import { Emitter } from 'vs/base/common/event';
1111
import { IMarkdownString } from 'vs/base/common/htmlContent';
1212
import { Iterable } from 'vs/base/common/iterator';
13-
import { DisposableMap, DisposableStore } from 'vs/base/common/lifecycle';
13+
import { Disposable, DisposableMap, DisposableStore } from 'vs/base/common/lifecycle';
1414
import { StopWatch } from 'vs/base/common/stopwatch';
1515
import { assertType } from 'vs/base/common/types';
1616
import { URI } from 'vs/base/common/uri';
@@ -198,20 +198,22 @@ class ChatAgentResponseStream {
198198
}
199199
}
200200

201-
export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
201+
export class ExtHostChatAgents2 extends Disposable implements ExtHostChatAgentsShape2 {
202202

203203
private static _idPool = 0;
204204

205205
private readonly _agents = new Map<number, ExtHostChatAgent>();
206206
private readonly _proxy: MainThreadChatAgentsShape2;
207207

208-
private readonly _sessionDisposables: DisposableMap<string, DisposableStore> = new DisposableMap();
208+
private readonly _sessionDisposables: DisposableMap<string, DisposableStore> = this._register(new DisposableMap());
209+
private readonly _completionDisposables = this._register(new DisposableStore());
209210

210211
constructor(
211212
mainContext: IMainContext,
212213
private readonly _logService: ILogService,
213214
private readonly commands: ExtHostCommands,
214215
) {
216+
super();
215217
this._proxy = mainContext.getProxy(MainContext.MainThreadChatAgents2);
216218
}
217219

@@ -373,7 +375,8 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
373375
}
374376

375377
const items = await agent.invokeCompletionProvider(query, token);
376-
return items.map(typeConvert.ChatAgentCompletionItem.from);
378+
379+
return items.map((i) => typeConvert.ChatAgentCompletionItem.from(i, this.commands.converter, this._completionDisposables));
377380
}
378381

379382
async $provideWelcomeMessage(handle: number, location: ChatAgentLocation, token: CancellationToken): Promise<(string | IMarkdownString)[] | undefined> {

src/vs/workbench/api/common/extHostTypeConverters.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2612,13 +2612,14 @@ export namespace ChatAgentResolvedVariable {
26122612
}
26132613

26142614
export namespace ChatAgentCompletionItem {
2615-
export function from(item: vscode.ChatCompletionItem): extHostProtocol.IChatAgentCompletionItem {
2615+
export function from(item: vscode.ChatCompletionItem, commandsConverter: CommandsConverter, disposables: DisposableStore): extHostProtocol.IChatAgentCompletionItem {
26162616
return {
26172617
label: item.label,
26182618
values: item.values.map(ChatVariable.from),
26192619
insertText: item.insertText,
26202620
detail: item.detail,
26212621
documentation: item.documentation,
2622+
command: commandsConverter.toInternal(item.command, disposables),
26222623
};
26232624
}
26242625
}

src/vs/workbench/api/common/extHostTypes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4245,6 +4245,7 @@ export class ChatCompletionItem implements vscode.ChatCompletionItem {
42454245
values: vscode.ChatVariableValue[];
42464246
detail?: string;
42474247
documentation?: string | MarkdownString;
4248+
command?: vscode.Command;
42484249

42494250
constructor(label: string | CompletionItemLabel, values: vscode.ChatVariableValue[]) {
42504251
this.label = label;

src/vs/workbench/contrib/chat/browser/contrib/chatDynamicVariables.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ import { basename } from 'vs/base/common/resources';
1010
import { URI } from 'vs/base/common/uri';
1111
import { IRange, Range } from 'vs/editor/common/core/range';
1212
import { IDecorationOptions } from 'vs/editor/common/editorCommon';
13+
import { Command } from 'vs/editor/common/languages';
1314
import { ITextModelService } from 'vs/editor/common/services/resolverService';
1415
import { localize } from 'vs/nls';
1516
import { Action2, registerAction2 } from 'vs/platform/actions/common/actions';
17+
import { ICommandService } from 'vs/platform/commands/common/commands';
1618
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
1719
import { ILabelService } from 'vs/platform/label/common/label';
1820
import { ILogService } from 'vs/platform/log/common/log';
@@ -217,6 +219,7 @@ export interface IAddDynamicVariableContext {
217219
widget: IChatWidget;
218220
range: IRange;
219221
variableData: IChatRequestVariableValue[];
222+
command?: Command;
220223
}
221224

222225
function isAddDynamicVariableContext(context: any): context is IAddDynamicVariableContext {
@@ -241,9 +244,39 @@ export class AddDynamicVariableAction extends Action2 {
241244
return;
242245
}
243246

247+
let range = context.range;
248+
const variableData = context.variableData;
249+
250+
const doCleanup = () => {
251+
// Failed, remove the dangling variable prefix
252+
context.widget.inputEditor.executeEdits('chatInsertDynamicVariableWithArguments', [{ range: context.range, text: `` }]);
253+
};
254+
255+
// If this completion item has no command, return it directly
256+
if (context.command) {
257+
// Invoke the command on this completion item along with its args and return the result
258+
const commandService = accessor.get(ICommandService);
259+
const selection: string | undefined = await commandService.executeCommand(context.command.id, ...(context.command.arguments ?? []));
260+
if (!selection) {
261+
doCleanup();
262+
return;
263+
}
264+
265+
// Compute new range and variableData
266+
const insertText = ':' + selection;
267+
const insertRange = new Range(range.startLineNumber, range.endColumn, range.endLineNumber, range.endColumn + insertText.length);
268+
range = new Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn + insertText.length);
269+
const editor = context.widget.inputEditor;
270+
const success = editor.executeEdits('chatInsertDynamicVariableWithArguments', [{ range: insertRange, text: insertText + ' ' }]);
271+
if (!success) {
272+
doCleanup();
273+
return;
274+
}
275+
}
276+
244277
context.widget.getContrib<ChatDynamicVariableModel>(ChatDynamicVariableModel.ID)?.addReference({
245-
range: context.range,
246-
data: context.variableData
278+
range: range,
279+
data: variableData
247280
});
248281
}
249282
}

src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ declare module 'vscode' {
131131
insertText?: string;
132132
detail?: string;
133133
documentation?: string | MarkdownString;
134+
command?: Command;
134135

135136
constructor(label: string | CompletionItemLabel, values: ChatVariableValue[]);
136137
}

0 commit comments

Comments
 (0)