mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-16 02:56:37 +01:00
Support sticky agents (#204910)
* Allow sticky chat agents Agents can be sticky and customize the repopulated placeholder. And normalize the API for sub commands See #199908 * Move code around to fix race condition and simplify * Fix build * Agents are sticky by default. Command sticky 'placeholder' is moved to chat agent additions * Rename repopulate to 'isSticky' * Rename
This commit is contained in:
@@ -407,13 +407,19 @@ class ExtHostChatAgent {
|
||||
return [];
|
||||
}
|
||||
return result
|
||||
.map(c => ({
|
||||
name: c.name,
|
||||
description: c.description,
|
||||
followupPlaceholder: c.followupPlaceholder,
|
||||
shouldRepopulate: c.shouldRepopulate,
|
||||
sampleRequest: c.sampleRequest
|
||||
}));
|
||||
.map(c => {
|
||||
if ('repopulate2' in c) {
|
||||
checkProposedApiEnabled(this.extension, 'chatAgents2Additions');
|
||||
}
|
||||
|
||||
return {
|
||||
name: c.name,
|
||||
description: c.description,
|
||||
followupPlaceholder: c.isSticky2?.placeholder,
|
||||
shouldRepopulate: c.isSticky2?.isSticky ?? c.isSticky,
|
||||
sampleRequest: c.sampleRequest
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async provideFollowups(result: vscode.ChatAgentResult2, token: CancellationToken): Promise<vscode.ChatAgentFollowup[]> {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IChatWidgetContrib } from 'vs/workbench/contrib/chat/browser/chatWidget';
|
||||
import { IChatAgentCommand, IChatAgentData } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { IParsedChatRequest } from 'vs/workbench/contrib/chat/common/chatParserTypes';
|
||||
import { IChatRequestViewModel, IChatResponseViewModel, IChatViewModel, IChatWelcomeMessageViewModel } from 'vs/workbench/contrib/chat/common/chatViewModel';
|
||||
|
||||
@@ -101,6 +102,7 @@ export type IChatWidgetViewContext = IChatViewViewContext | IChatResourceViewCon
|
||||
export interface IChatWidget {
|
||||
readonly onDidChangeViewModel: Event<void>;
|
||||
readonly onDidAcceptInput: Event<void>;
|
||||
readonly onDidSubmitAgent: Event<{ agent: IChatAgentData; slashCommand?: IChatAgentCommand }>;
|
||||
readonly viewContext: IChatWidgetViewContext;
|
||||
readonly viewModel: IChatViewModel | undefined;
|
||||
readonly inputEditor: ICodeEditor;
|
||||
|
||||
@@ -35,7 +35,7 @@ import { ChatViewModel, IChatResponseViewModel, isRequestVM, isResponseVM, isWel
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IParsedChatRequest, chatAgentLeader, chatSubcommandLeader } from 'vs/workbench/contrib/chat/common/chatParserTypes';
|
||||
import { ChatRequestParser } from 'vs/workbench/contrib/chat/common/chatRequestParser';
|
||||
import { IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { IChatAgentCommand, IChatAgentData, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@@ -73,6 +73,9 @@ export interface IChatWidgetContrib extends IDisposable {
|
||||
export class ChatWidget extends Disposable implements IChatWidget {
|
||||
public static readonly CONTRIBS: { new(...args: [IChatWidget, ...any]): IChatWidgetContrib }[] = [];
|
||||
|
||||
private readonly _onDidSubmitAgent = this._register(new Emitter<{ agent: IChatAgentData; slashCommand?: IChatAgentCommand }>());
|
||||
public readonly onDidSubmitAgent = this._onDidSubmitAgent.event;
|
||||
|
||||
private _onDidFocus = this._register(new Emitter<void>());
|
||||
readonly onDidFocus = this._onDidFocus.event;
|
||||
|
||||
@@ -586,6 +589,7 @@ export class ChatWidget extends Disposable implements IChatWidget {
|
||||
if (result) {
|
||||
const inputState = this.collectInputState();
|
||||
this.inputPart.acceptInput(isUserQuery ? input : undefined, isUserQuery ? inputState : undefined);
|
||||
this._onDidSubmitAgent.fire({ agent: result.agent, slashCommand: result.slashCommand });
|
||||
result.responseCompletePromise.then(async () => {
|
||||
const responses = this.viewModel?.getItems().filter(isResponseVM);
|
||||
const lastResponse = responses?.[responses.length - 1];
|
||||
|
||||
@@ -29,7 +29,6 @@ import { IChatAgentCommand, IChatAgentData, IChatAgentService } from 'vs/workben
|
||||
import { chatSlashCommandBackground, chatSlashCommandForeground } from 'vs/workbench/contrib/chat/common/chatColors';
|
||||
import { ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashCommandPart, ChatRequestTextPart, ChatRequestVariablePart, IParsedChatRequestPart, chatAgentLeader, chatSubcommandLeader, chatVariableLeader } from 'vs/workbench/contrib/chat/common/chatParserTypes';
|
||||
import { ChatRequestParser } from 'vs/workbench/contrib/chat/common/chatRequestParser';
|
||||
import { IChatService } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatSlashCommandService } from 'vs/workbench/contrib/chat/common/chatSlashCommands';
|
||||
import { IChatVariablesService } from 'vs/workbench/contrib/chat/common/chatVariables';
|
||||
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
@@ -39,8 +38,8 @@ const placeholderDecorationType = 'chat-session-detail';
|
||||
const slashCommandTextDecorationType = 'chat-session-text';
|
||||
const variableTextDecorationType = 'chat-variable-text';
|
||||
|
||||
function agentAndCommandToKey(agent: string, subcommand: string): string {
|
||||
return `${agent}__${subcommand}`;
|
||||
function agentAndCommandToKey(agent: string, subcommand: string | undefined): string {
|
||||
return subcommand ? `${agent}__${subcommand}` : agent;
|
||||
}
|
||||
|
||||
class InputEditorDecorations extends Disposable {
|
||||
@@ -55,7 +54,6 @@ class InputEditorDecorations extends Disposable {
|
||||
private readonly widget: IChatWidget,
|
||||
@ICodeEditorService private readonly codeEditorService: ICodeEditorService,
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
@IChatService private readonly chatService: IChatService,
|
||||
@IChatAgentService private readonly chatAgentService: IChatAgentService,
|
||||
) {
|
||||
super();
|
||||
@@ -72,10 +70,8 @@ class InputEditorDecorations extends Disposable {
|
||||
this.previouslyUsedAgents.clear();
|
||||
this.updateInputEditorDecorations();
|
||||
}));
|
||||
this._register(this.chatService.onDidSubmitAgent((e) => {
|
||||
if (e.sessionId === this.widget.viewModel?.sessionId) {
|
||||
this.previouslyUsedAgents.add(agentAndCommandToKey(e.agent.id, e.slashCommand.name));
|
||||
}
|
||||
this._register(this.widget.onDidSubmitAgent((e) => {
|
||||
this.previouslyUsedAgents.add(agentAndCommandToKey(e.agent.id, e.slashCommand?.name));
|
||||
}));
|
||||
this._register(this.chatAgentService.onDidChangeAgents(() => this.updateInputEditorDecorations()));
|
||||
|
||||
@@ -168,20 +164,24 @@ class InputEditorDecorations extends Disposable {
|
||||
return nextPart && nextPart instanceof ChatRequestTextPart && nextPart.text === ' ';
|
||||
};
|
||||
|
||||
const getRangeForPlaceholder = (part: IParsedChatRequestPart) => ({
|
||||
startLineNumber: part.editorRange.startLineNumber,
|
||||
endLineNumber: part.editorRange.endLineNumber,
|
||||
startColumn: part.editorRange.endColumn + 1,
|
||||
endColumn: 1000
|
||||
});
|
||||
|
||||
const onlyAgentAndWhitespace = agentPart && parsedRequest.every(p => p instanceof ChatRequestTextPart && !p.text.trim().length || p instanceof ChatRequestAgentPart);
|
||||
if (onlyAgentAndWhitespace) {
|
||||
// Agent reference with no other text - show the placeholder
|
||||
const isFollowupSlashCommand = this.previouslyUsedAgents.has(agentAndCommandToKey(agentPart.agent.id, undefined));
|
||||
const shouldRenderFollowupPlaceholder = isFollowupSlashCommand && agentPart.agent.metadata.followupPlaceholder;
|
||||
if (agentPart.agent.metadata.description && exactlyOneSpaceAfterPart(agentPart)) {
|
||||
placeholderDecoration = [{
|
||||
range: {
|
||||
startLineNumber: agentPart.editorRange.startLineNumber,
|
||||
endLineNumber: agentPart.editorRange.endLineNumber,
|
||||
startColumn: agentPart.editorRange.endColumn + 1,
|
||||
endColumn: 1000
|
||||
},
|
||||
range: getRangeForPlaceholder(agentPart),
|
||||
renderOptions: {
|
||||
after: {
|
||||
contentText: agentPart.agent.metadata.description,
|
||||
contentText: shouldRenderFollowupPlaceholder ? agentPart.agent.metadata.followupPlaceholder : agentPart.agent.metadata.description,
|
||||
color: this.getPlaceholderColor(),
|
||||
}
|
||||
}
|
||||
@@ -196,12 +196,7 @@ class InputEditorDecorations extends Disposable {
|
||||
const shouldRenderFollowupPlaceholder = isFollowupSlashCommand && agentSubcommandPart.command.followupPlaceholder;
|
||||
if (agentSubcommandPart?.command.description && exactlyOneSpaceAfterPart(agentSubcommandPart)) {
|
||||
placeholderDecoration = [{
|
||||
range: {
|
||||
startLineNumber: agentSubcommandPart.editorRange.startLineNumber,
|
||||
endLineNumber: agentSubcommandPart.editorRange.endLineNumber,
|
||||
startColumn: agentSubcommandPart.editorRange.endColumn + 1,
|
||||
endColumn: 1000
|
||||
},
|
||||
range: getRangeForPlaceholder(agentSubcommandPart),
|
||||
renderOptions: {
|
||||
after: {
|
||||
contentText: shouldRenderFollowupPlaceholder ? agentSubcommandPart.command.followupPlaceholder : agentSubcommandPart.command.description,
|
||||
@@ -212,27 +207,6 @@ class InputEditorDecorations extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
const onlySlashCommandAndWhitespace = slashCommandPart && parsedRequest.every(p => p instanceof ChatRequestTextPart && !p.text.trim().length || p instanceof ChatRequestSlashCommandPart);
|
||||
if (onlySlashCommandAndWhitespace) {
|
||||
// Command reference with no other text - show the placeholder
|
||||
if (slashCommandPart.slashCommand.detail && exactlyOneSpaceAfterPart(slashCommandPart)) {
|
||||
placeholderDecoration = [{
|
||||
range: {
|
||||
startLineNumber: slashCommandPart.editorRange.startLineNumber,
|
||||
endLineNumber: slashCommandPart.editorRange.endLineNumber,
|
||||
startColumn: slashCommandPart.editorRange.endColumn + 1,
|
||||
endColumn: 1000
|
||||
},
|
||||
renderOptions: {
|
||||
after: {
|
||||
contentText: slashCommandPart.slashCommand.detail,
|
||||
color: this.getPlaceholderColor(),
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
this.widget.inputEditor.setDecorationsByType(decorationDescription, placeholderDecorationType, placeholderDecoration ?? []);
|
||||
|
||||
const textDecorations: IDecorationOptions[] | undefined = [];
|
||||
@@ -264,21 +238,23 @@ class InputEditorSlashCommandMode extends Disposable {
|
||||
|
||||
constructor(
|
||||
private readonly widget: IChatWidget,
|
||||
@IChatService private readonly chatService: IChatService
|
||||
) {
|
||||
super();
|
||||
this._register(this.chatService.onDidSubmitAgent(e => {
|
||||
if (this.widget.viewModel?.sessionId !== e.sessionId) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._register(this.widget.onDidSubmitAgent(e => {
|
||||
this.repopulateAgentCommand(e.agent, e.slashCommand);
|
||||
}));
|
||||
}
|
||||
|
||||
private async repopulateAgentCommand(agent: IChatAgentData, slashCommand: IChatAgentCommand) {
|
||||
if (slashCommand.shouldRepopulate) {
|
||||
const value = `${chatAgentLeader}${agent.id} ${chatSubcommandLeader}${slashCommand.name} `;
|
||||
private async repopulateAgentCommand(agent: IChatAgentData, slashCommand: IChatAgentCommand | undefined) {
|
||||
let value: string | undefined;
|
||||
if (slashCommand && slashCommand.shouldRepopulate) {
|
||||
value = `${chatAgentLeader}${agent.id} ${chatSubcommandLeader}${slashCommand.name} `;
|
||||
} else {
|
||||
// Agents always repopulate, and slash commands fall back to the agent if they don't repopulate
|
||||
value = `${chatAgentLeader}${agent.id} `;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
this.widget.inputEditor.setValue(value);
|
||||
this.widget.inputEditor.setPosition({ lineNumber: 1, column: value.length + 1 });
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ export interface IChatAgentMetadata {
|
||||
themeIcon?: ThemeIcon;
|
||||
sampleRequest?: string;
|
||||
supportIssueReporting?: boolean;
|
||||
followupPlaceholder?: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -262,13 +262,18 @@ export interface IChatTransferredSessionData {
|
||||
inputValue: string;
|
||||
}
|
||||
|
||||
export interface IChatSendRequestData {
|
||||
responseCompletePromise: Promise<void>;
|
||||
agent: IChatAgentData;
|
||||
slashCommand?: IChatAgentCommand;
|
||||
}
|
||||
|
||||
export const IChatService = createDecorator<IChatService>('IChatService');
|
||||
|
||||
export interface IChatService {
|
||||
_serviceBrand: undefined;
|
||||
transferredSessionData: IChatTransferredSessionData | undefined;
|
||||
|
||||
onDidSubmitAgent: Event<{ agent: IChatAgentData; slashCommand: IChatAgentCommand; sessionId: string }>;
|
||||
onDidRegisterProvider: Event<{ providerId: string }>;
|
||||
onDidUnregisterProvider: Event<{ providerId: string }>;
|
||||
registerProvider(provider: IChatProvider): IDisposable;
|
||||
@@ -283,7 +288,7 @@ export interface IChatService {
|
||||
/**
|
||||
* Returns whether the request was accepted.
|
||||
*/
|
||||
sendRequest(sessionId: string, message: string): Promise<{ responseCompletePromise: Promise<void> } | undefined>;
|
||||
sendRequest(sessionId: string, message: string): Promise<IChatSendRequestData | undefined>;
|
||||
removeRequest(sessionid: string, requestId: string): Promise<void>;
|
||||
cancelCurrentRequestForSession(sessionId: string): void;
|
||||
clearSession(sessionId: string): void;
|
||||
|
||||
@@ -20,13 +20,13 @@ import { Progress } from 'vs/platform/progress/common/progress';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IChatAgentCommand, IChatAgentData, IChatAgentHistoryEntry, IChatAgentRequest, IChatAgentResult, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { IChatAgentHistoryEntry, IChatAgentRequest, IChatAgentResult, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { CONTEXT_PROVIDER_EXISTS } from 'vs/workbench/contrib/chat/common/chatContextKeys';
|
||||
import { ChatModel, ChatModelInitState, ChatRequestModel, ChatWelcomeMessageModel, IChatModel, IChatRequestVariableData, IChatRequestVariableData2, ISerializableChatData, ISerializableChatsData } from 'vs/workbench/contrib/chat/common/chatModel';
|
||||
import { ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashCommandPart, ChatRequestVariablePart, IParsedChatRequest, getPromptText } from 'vs/workbench/contrib/chat/common/chatParserTypes';
|
||||
import { ChatMessageRole, IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider';
|
||||
import { ChatRequestParser } from 'vs/workbench/contrib/chat/common/chatRequestParser';
|
||||
import { ChatAgentCopyKind, IChat, IChatCompleteResponse, IChatDetail, IChatDynamicRequest, IChatFollowup, IChatProgress, IChatProvider, IChatProviderInfo, IChatService, IChatTransferredSessionData, IChatUserActionEvent, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { ChatAgentCopyKind, IChat, IChatCompleteResponse, IChatDetail, IChatDynamicRequest, IChatFollowup, IChatProgress, IChatProvider, IChatProviderInfo, IChatSendRequestData, IChatService, IChatTransferredSessionData, IChatUserActionEvent, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatSlashCommandService } from 'vs/workbench/contrib/chat/common/chatSlashCommands';
|
||||
import { IChatVariablesService } from 'vs/workbench/contrib/chat/common/chatVariables';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
@@ -146,9 +146,6 @@ export class ChatService extends Disposable implements IChatService {
|
||||
private readonly _onDidPerformUserAction = this._register(new Emitter<IChatUserActionEvent>());
|
||||
public readonly onDidPerformUserAction: Event<IChatUserActionEvent> = this._onDidPerformUserAction.event;
|
||||
|
||||
private readonly _onDidSubmitAgent = this._register(new Emitter<{ agent: IChatAgentData; slashCommand: IChatAgentCommand; sessionId: string }>());
|
||||
public readonly onDidSubmitAgent = this._onDidSubmitAgent.event;
|
||||
|
||||
private readonly _onDidDisposeSession = this._register(new Emitter<{ sessionId: string; providerId: string; reason: 'initializationFailed' | 'cleared' }>());
|
||||
public readonly onDidDisposeSession = this._onDidDisposeSession.event;
|
||||
|
||||
@@ -438,7 +435,7 @@ export class ChatService extends Disposable implements IChatService {
|
||||
return this._startSession(data.providerId, data, CancellationToken.None);
|
||||
}
|
||||
|
||||
async sendRequest(sessionId: string, request: string): Promise<{ responseCompletePromise: Promise<void> } | undefined> {
|
||||
async sendRequest(sessionId: string, request: string): Promise<IChatSendRequestData | undefined> {
|
||||
this.trace('sendRequest', `sessionId: ${sessionId}, message: ${request.substring(0, 20)}${request.length > 20 ? '[...]' : ''}}`);
|
||||
if (!request.trim()) {
|
||||
this.trace('sendRequest', 'Rejected empty message');
|
||||
@@ -461,8 +458,16 @@ export class ChatService extends Disposable implements IChatService {
|
||||
return;
|
||||
}
|
||||
|
||||
const parsedRequest = this.instantiationService.createInstance(ChatRequestParser).parseChatRequest(sessionId, request);
|
||||
const agent = parsedRequest.parts.find((r): r is ChatRequestAgentPart => r instanceof ChatRequestAgentPart)?.agent ?? this.chatAgentService.getDefaultAgent()!;
|
||||
const agentSlashCommandPart = parsedRequest.parts.find((r): r is ChatRequestAgentSubcommandPart => r instanceof ChatRequestAgentSubcommandPart);
|
||||
|
||||
// This method is only returning whether the request was accepted - don't block on the actual request
|
||||
return { responseCompletePromise: this._sendRequestAsync(model, sessionId, provider, request) };
|
||||
return {
|
||||
responseCompletePromise: this._sendRequestAsync(model, sessionId, provider, parsedRequest),
|
||||
agent,
|
||||
slashCommand: agentSlashCommandPart?.command,
|
||||
};
|
||||
}
|
||||
|
||||
private refreshFollowupsCancellationToken(sessionId: string): CancellationToken {
|
||||
@@ -473,10 +478,8 @@ export class ChatService extends Disposable implements IChatService {
|
||||
return newTokenSource.token;
|
||||
}
|
||||
|
||||
private async _sendRequestAsync(model: ChatModel, sessionId: string, provider: IChatProvider, message: string): Promise<void> {
|
||||
private async _sendRequestAsync(model: ChatModel, sessionId: string, provider: IChatProvider, parsedRequest: IParsedChatRequest): Promise<void> {
|
||||
const followupsCancelToken = this.refreshFollowupsCancellationToken(sessionId);
|
||||
const parsedRequest = this.instantiationService.createInstance(ChatRequestParser).parseChatRequest(sessionId, message);
|
||||
|
||||
let request: ChatRequestModel;
|
||||
const agentPart = 'kind' in parsedRequest ? undefined : parsedRequest.parts.find((r): r is ChatRequestAgentPart => r instanceof ChatRequestAgentPart);
|
||||
const agentSlashCommandPart = 'kind' in parsedRequest ? undefined : parsedRequest.parts.find((r): r is ChatRequestAgentSubcommandPart => r instanceof ChatRequestAgentSubcommandPart);
|
||||
@@ -523,10 +526,6 @@ export class ChatService extends Disposable implements IChatService {
|
||||
});
|
||||
|
||||
try {
|
||||
if (agentPart && agentSlashCommandPart?.command) {
|
||||
this._onDidSubmitAgent.fire({ agent: agentPart.agent, slashCommand: agentSlashCommandPart.command, sessionId: model.sessionId });
|
||||
}
|
||||
|
||||
let rawResult: IChatAgentResult | null | undefined;
|
||||
let agentOrCommandFollowups: Promise<IChatFollowup[] | undefined> | undefined = undefined;
|
||||
|
||||
@@ -570,7 +569,7 @@ export class ChatService extends Disposable implements IChatService {
|
||||
rawResult = agentResult;
|
||||
agentOrCommandFollowups = this.chatAgentService.getFollowups(agent.id, requestProps, agentResult, followupsCancelToken);
|
||||
} else if (commandPart && this.chatSlashCommandService.hasCommand(commandPart.slashCommand.command)) {
|
||||
request = model.addRequest(parsedRequest, { message, variables: {} });
|
||||
request = model.addRequest(parsedRequest, { message: parsedRequest.text, variables: {} });
|
||||
// contributed slash commands
|
||||
// TODO: spell this out in the UI
|
||||
const history: IChatMessage[] = [];
|
||||
@@ -581,6 +580,7 @@ export class ChatService extends Disposable implements IChatService {
|
||||
history.push({ role: ChatMessageRole.User, content: request.message.text });
|
||||
history.push({ role: ChatMessageRole.Assistant, content: request.response.response.asString() });
|
||||
}
|
||||
const message = parsedRequest.text;
|
||||
const commandResult = await this.chatSlashCommandService.executeCommand(commandPart.slashCommand.command, message.substring(commandPart.slashCommand.command.length + 1).trimStart(), new Progress<IChatProgress>(p => {
|
||||
progressCallback(p);
|
||||
}), history, token);
|
||||
|
||||
+4
-13
@@ -180,19 +180,10 @@ declare module 'vscode' {
|
||||
readonly sampleRequest?: string;
|
||||
|
||||
/**
|
||||
* Whether executing the command puts the
|
||||
* chat into a persistent mode, where the
|
||||
* command is prepended to the chat input.
|
||||
* Whether executing the command puts the chat into a persistent mode, where the command is automatically added to the chat input for the next message.
|
||||
* If this is not set, the chat input will fall back to the agent after submitting this command.
|
||||
*/
|
||||
readonly shouldRepopulate?: boolean;
|
||||
|
||||
/**
|
||||
* Placeholder text to render in the chat input
|
||||
* when the command has been repopulated.
|
||||
* Has no effect if `shouldRepopulate` is `false`.
|
||||
*/
|
||||
// TODO@API merge this with shouldRepopulate? so that invalid state cannot be represented?
|
||||
readonly followupPlaceholder?: string;
|
||||
readonly isSticky?: boolean;
|
||||
}
|
||||
|
||||
export interface ChatAgentCommandProvider {
|
||||
@@ -221,7 +212,7 @@ declare module 'vscode' {
|
||||
prompt: string;
|
||||
|
||||
/**
|
||||
* By default, the followup goes to the same agent/subCommand. But these properties can be set to override that.
|
||||
* By default, the followup goes to the same agent/command. But these properties can be set to override that.
|
||||
*/
|
||||
agentId?: string;
|
||||
|
||||
|
||||
@@ -230,4 +230,18 @@ declare module 'vscode' {
|
||||
*/
|
||||
kind?: string;
|
||||
}
|
||||
|
||||
export interface ChatAgentCommand {
|
||||
readonly isSticky2?: {
|
||||
/**
|
||||
* Indicates that the command should be automatically repopulated.
|
||||
*/
|
||||
isSticky: true;
|
||||
|
||||
/**
|
||||
* This can be set to a string to use a different placeholder message in the input box when the command has been repopulated.
|
||||
*/
|
||||
placeholder?: string;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user