mirror of
https://github.com/Microsoft/vscode
synced 2024-09-19 18:48:00 +00:00
Make vscode own /help, add API for agents to customize it (#197964)
* Make vscode own /help, add API for agents to customize it Towards #197081 * Fix build error
This commit is contained in:
parent
55c1e8473c
commit
ca8981c284
|
@ -217,6 +217,9 @@ class ExtHostChatAgent {
|
|||
private _fullName: string | undefined;
|
||||
private _iconPath: vscode.Uri | { light: vscode.Uri; dark: vscode.Uri } | vscode.ThemeIcon | undefined;
|
||||
private _isDefault: boolean | undefined;
|
||||
private _helpTextPrefix: string | vscode.MarkdownString | undefined;
|
||||
private _helpTextPostfix: string | vscode.MarkdownString | undefined;
|
||||
private _sampleRequest?: string;
|
||||
private _isSecondary: boolean | undefined;
|
||||
private _onDidReceiveFeedback = new Emitter<vscode.ChatAgentResult2Feedback>();
|
||||
private _onDidPerformAction = new Emitter<vscode.ChatAgentUserActionEvent>();
|
||||
|
@ -259,7 +262,14 @@ class ExtHostChatAgent {
|
|||
return [];
|
||||
}
|
||||
this._lastSlashCommands = result;
|
||||
return result.map(c => ({ name: c.name, description: c.description, followupPlaceholder: c.followupPlaceholder, shouldRepopulate: c.shouldRepopulate }));
|
||||
return result
|
||||
.map(c => ({
|
||||
name: c.name,
|
||||
description: c.description,
|
||||
followupPlaceholder: c.followupPlaceholder,
|
||||
shouldRepopulate: c.shouldRepopulate,
|
||||
sampleRequest: c.sampleRequest
|
||||
}));
|
||||
}
|
||||
|
||||
async provideFollowups(result: vscode.ChatAgentResult2, token: CancellationToken): Promise<IChatFollowup[]> {
|
||||
|
@ -300,6 +310,9 @@ class ExtHostChatAgent {
|
|||
hasFollowup: this._followupProvider !== undefined,
|
||||
isDefault: this._isDefault,
|
||||
isSecondary: this._isSecondary,
|
||||
helpTextPrefix: (!this._helpTextPrefix || typeof this._helpTextPrefix === 'string') ? this._helpTextPrefix : typeConvert.MarkdownString.from(this._helpTextPrefix),
|
||||
helpTextPostfix: (!this._helpTextPostfix || typeof this._helpTextPostfix === 'string') ? this._helpTextPostfix : typeConvert.MarkdownString.from(this._helpTextPostfix),
|
||||
sampleRequest: this._sampleRequest,
|
||||
});
|
||||
updateScheduled = false;
|
||||
});
|
||||
|
@ -354,6 +367,32 @@ class ExtHostChatAgent {
|
|||
that._isDefault = v;
|
||||
updateMetadataSoon();
|
||||
},
|
||||
get helpTextPrefix() {
|
||||
checkProposedApiEnabled(that.extension, 'defaultChatAgent');
|
||||
return that._helpTextPrefix;
|
||||
},
|
||||
set helpTextPrefix(v) {
|
||||
checkProposedApiEnabled(that.extension, 'defaultChatAgent');
|
||||
if (!that._isDefault) {
|
||||
throw new Error('helpTextPrefix is only available on the default chat agent');
|
||||
}
|
||||
|
||||
that._helpTextPrefix = v;
|
||||
updateMetadataSoon();
|
||||
},
|
||||
get helpTextPostfix() {
|
||||
checkProposedApiEnabled(that.extension, 'defaultChatAgent');
|
||||
return that._helpTextPostfix;
|
||||
},
|
||||
set helpTextPostfix(v) {
|
||||
checkProposedApiEnabled(that.extension, 'defaultChatAgent');
|
||||
if (!that._isDefault) {
|
||||
throw new Error('helpTextPostfix is only available on the default chat agent');
|
||||
}
|
||||
|
||||
that._helpTextPostfix = v;
|
||||
updateMetadataSoon();
|
||||
},
|
||||
get isSecondary() {
|
||||
checkProposedApiEnabled(that.extension, 'defaultChatAgent');
|
||||
return that._isSecondary;
|
||||
|
@ -363,6 +402,13 @@ class ExtHostChatAgent {
|
|||
that._isSecondary = v;
|
||||
updateMetadataSoon();
|
||||
},
|
||||
get sampleRequest() {
|
||||
return that._sampleRequest;
|
||||
},
|
||||
set sampleRequest(v) {
|
||||
that._sampleRequest = v;
|
||||
updateMetadataSoon();
|
||||
},
|
||||
get onDidReceiveFeedback() {
|
||||
return that._onDidReceiveFeedback.event;
|
||||
},
|
||||
|
|
|
@ -8,19 +8,15 @@ import { ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
|||
import { localize } from 'vs/nls';
|
||||
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
|
||||
import { CHAT_CATEGORY } from 'vs/workbench/contrib/chat/browser/actions/chatActions';
|
||||
import { IChatWidget } from 'vs/workbench/contrib/chat/browser/chat';
|
||||
import { IChatWidget, IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat';
|
||||
import { CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_CHAT_REQUEST_IN_PROGRESS } from 'vs/workbench/contrib/chat/common/chatContextKeys';
|
||||
import { IChatService } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
|
||||
export interface IChatExecuteActionContext {
|
||||
widget: IChatWidget;
|
||||
widget?: IChatWidget;
|
||||
inputValue?: string;
|
||||
}
|
||||
|
||||
export function isExecuteActionContext(thing: unknown): thing is IChatExecuteActionContext {
|
||||
return typeof thing === 'object' && thing !== null && 'widget' in thing;
|
||||
}
|
||||
|
||||
export class SubmitAction extends Action2 {
|
||||
static readonly ID = 'workbench.action.chat.submit';
|
||||
|
||||
|
@ -44,12 +40,11 @@ export class SubmitAction extends Action2 {
|
|||
}
|
||||
|
||||
run(accessor: ServicesAccessor, ...args: any[]) {
|
||||
const context = args[0];
|
||||
if (!isExecuteActionContext(context)) {
|
||||
return;
|
||||
}
|
||||
const context: IChatExecuteActionContext = args[0];
|
||||
|
||||
context.widget.acceptInput(context.inputValue);
|
||||
const widgetService = accessor.get(IChatWidgetService);
|
||||
const widget = context.widget ?? widgetService.lastFocusedWidget;
|
||||
widget?.acceptInput(context.inputValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,8 +71,8 @@ export function registerChatExecuteActions() {
|
|||
}
|
||||
|
||||
run(accessor: ServicesAccessor, ...args: any[]) {
|
||||
const context = args[0];
|
||||
if (!isExecuteActionContext(context)) {
|
||||
const context: IChatExecuteActionContext = args[0];
|
||||
if (!context.widget) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ import { EditorExtensions, IEditorFactoryRegistry } from 'vs/workbench/common/ed
|
|||
import { registerChatActions } from 'vs/workbench/contrib/chat/browser/actions/chatActions';
|
||||
import { registerChatCodeBlockActions } from 'vs/workbench/contrib/chat/browser/actions/chatCodeblockActions';
|
||||
import { registerChatCopyActions } from 'vs/workbench/contrib/chat/browser/actions/chatCopyActions';
|
||||
import { registerChatExecuteActions } from 'vs/workbench/contrib/chat/browser/actions/chatExecuteActions';
|
||||
import { IChatExecuteActionContext, SubmitAction, registerChatExecuteActions } from 'vs/workbench/contrib/chat/browser/actions/chatExecuteActions';
|
||||
import { registerQuickChatActions } from 'vs/workbench/contrib/chat/browser/actions/chatQuickInputActions';
|
||||
import { registerChatTitleActions } from 'vs/workbench/contrib/chat/browser/actions/chatTitleActions';
|
||||
import { registerChatExportActions } from 'vs/workbench/contrib/chat/browser/actions/chatImportExport';
|
||||
|
@ -45,7 +45,7 @@ import { ChatAccessibilityService } from 'vs/workbench/contrib/chat/browser/chat
|
|||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { AccessibilityVerbositySettingId, AccessibleViewProviderId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
|
||||
import { ChatWelcomeMessageModel } from 'vs/workbench/contrib/chat/common/chatModel';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { ChatProviderService, IChatProviderService } from 'vs/workbench/contrib/chat/common/chatProvider';
|
||||
import { ChatSlashCommandService, IChatSlashCommandService } from 'vs/workbench/contrib/chat/common/chatSlashCommands';
|
||||
import { alertFocusChange } from 'vs/workbench/contrib/accessibility/browser/accessibilityContributions';
|
||||
|
@ -56,6 +56,8 @@ import { registerChatFileTreeActions } from 'vs/workbench/contrib/chat/browser/a
|
|||
import { QuickChatService } from 'vs/workbench/contrib/chat/browser/chatQuick';
|
||||
import { ChatAgentService, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { ChatVariablesService } from 'vs/workbench/contrib/chat/browser/chatVariables';
|
||||
import { chatAgentLeader, chatSubcommandLeader } from 'vs/workbench/contrib/chat/common/chatParserTypes';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
// Register configuration
|
||||
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
|
||||
|
@ -221,16 +223,52 @@ class ChatSlashStaticSlashCommandsContribution extends Disposable {
|
|||
constructor(
|
||||
@IChatSlashCommandService slashCommandService: IChatSlashCommandService,
|
||||
@ICommandService commandService: ICommandService,
|
||||
@IChatAgentService chatAgentService: IChatAgentService,
|
||||
) {
|
||||
super();
|
||||
this._store.add(slashCommandService.registerSlashCommand({
|
||||
command: 'clear',
|
||||
detail: nls.localize('clear', "Clear the session"),
|
||||
sortText: 'z_clear',
|
||||
sortText: 'z2_clear',
|
||||
executeImmediately: true
|
||||
}, async () => {
|
||||
commandService.executeCommand(ACTION_ID_CLEAR_CHAT);
|
||||
}));
|
||||
this._store.add(slashCommandService.registerSlashCommand({
|
||||
command: 'help',
|
||||
detail: '',
|
||||
sortText: 'z1_help',
|
||||
executeImmediately: true
|
||||
}, async (prompt, progress) => {
|
||||
const defaultAgent = chatAgentService.getDefaultAgent();
|
||||
const agents = chatAgentService.getAgents();
|
||||
if (defaultAgent?.metadata.helpTextPrefix) {
|
||||
progress.report({ content: defaultAgent.metadata.helpTextPrefix });
|
||||
progress.report({ content: '\n\n' });
|
||||
}
|
||||
|
||||
const agentText = (await Promise.all(agents
|
||||
.filter(a => a.id !== defaultAgent?.id)
|
||||
.map(async a => {
|
||||
const agentWithLeader = `${chatAgentLeader}${a.id}`;
|
||||
const actionArg: IChatExecuteActionContext = { inputValue: `${agentWithLeader} ${a.metadata.sampleRequest}` };
|
||||
const urlSafeArg = encodeURIComponent(JSON.stringify(actionArg));
|
||||
const agentLine = `* [\`${agentWithLeader}\`](command:${SubmitAction.ID}?${urlSafeArg}) - ${a.metadata.description}`;
|
||||
const commands = await a.provideSlashCommands(CancellationToken.None);
|
||||
const commandText = commands.map(c => {
|
||||
const actionArg: IChatExecuteActionContext = { inputValue: `${agentWithLeader} ${chatSubcommandLeader}${c.name} ${c.sampleRequest ?? ''}` };
|
||||
const urlSafeArg = encodeURIComponent(JSON.stringify(actionArg));
|
||||
return `\t* [\`${chatSubcommandLeader}${c.name}\`](command:${SubmitAction.ID}?${urlSafeArg}) - ${c.description}`;
|
||||
}).join('\n');
|
||||
|
||||
return agentLine + '\n' + commandText;
|
||||
}))).join('\n');
|
||||
progress.report({ content: new MarkdownString(agentText, { isTrusted: { enabledCommands: [SubmitAction.ID] } }) });
|
||||
if (defaultAgent?.metadata.helpTextPostfix) {
|
||||
progress.report({ content: '\n\n' });
|
||||
progress.report({ content: defaultAgent.metadata.helpTextPostfix });
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ThemeIcon } from 'vs/base/common/themables';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider';
|
||||
import { IChatFollowup, IChatProgress, IChatResponseErrorDetails, IChatResponseProgressFileTreeData } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatFollowup, IChatProgress, IChatResponseErrorDetails } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatRequestVariableValue } from 'vs/workbench/contrib/chat/common/chatVariables';
|
||||
|
||||
//#region agent service, commands etc
|
||||
|
@ -27,40 +28,44 @@ export interface IChatAgent extends IChatAgentData {
|
|||
provideSlashCommands(token: CancellationToken): Promise<IChatAgentCommand[]>;
|
||||
}
|
||||
|
||||
export interface IChatAgentFragment {
|
||||
content: string | { treeData: IChatResponseProgressFileTreeData };
|
||||
}
|
||||
|
||||
export interface IChatAgentCommand {
|
||||
name: string;
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* Whether the command should execute as soon
|
||||
* as it is entered. Defaults to `false`.
|
||||
*/
|
||||
executeImmediately?: boolean;
|
||||
|
||||
/**
|
||||
* Whether executing the command puts the
|
||||
* chat into a persistent mode, where the
|
||||
* slash command is prepended to the chat input.
|
||||
*/
|
||||
shouldRepopulate?: boolean;
|
||||
|
||||
/**
|
||||
* Placeholder text to render in the chat input
|
||||
* when the slash command has been repopulated.
|
||||
* Has no effect if `shouldRepopulate` is `false`.
|
||||
*/
|
||||
followupPlaceholder?: string;
|
||||
|
||||
sampleRequest?: string;
|
||||
}
|
||||
|
||||
export interface IChatAgentMetadata {
|
||||
description?: string;
|
||||
isDefault?: boolean; // The agent invoked when no agent is specified
|
||||
helpTextPrefix?: string | IMarkdownString;
|
||||
helpTextPostfix?: string | IMarkdownString;
|
||||
isSecondary?: boolean; // Invoked by ctrl/cmd+enter
|
||||
fullName?: string;
|
||||
icon?: URI;
|
||||
iconDark?: URI;
|
||||
themeIcon?: ThemeIcon;
|
||||
sampleRequest?: string;
|
||||
}
|
||||
|
||||
export interface IChatAgentRequest {
|
||||
|
|
|
@ -169,7 +169,11 @@ export class Response implements IResponse {
|
|||
} else if (lastResponsePart) {
|
||||
// Combine this part with the last, non-resolving string part
|
||||
if (isMarkdownString(responsePart)) {
|
||||
this._responseParts[responsePartLength] = { string: new MarkdownString(lastResponsePart.string.value + responsePart.value, responsePart) };
|
||||
// Merge all enabled commands
|
||||
const lastPartEnabledCommands = typeof lastResponsePart.string.isTrusted === 'object' ? lastResponsePart.string.isTrusted.enabledCommands : [];
|
||||
const thisPartEnabledCommands = typeof responsePart.isTrusted === 'object' ? responsePart.isTrusted.enabledCommands : [];
|
||||
const enabledCommands = [...lastPartEnabledCommands, ...thisPartEnabledCommands];
|
||||
this._responseParts[responsePartLength] = { string: new MarkdownString(lastResponsePart.string.value + responsePart.value, { isTrusted: { enabledCommands } }) };
|
||||
} else {
|
||||
this._responseParts[responsePartLength] = { string: new MarkdownString(lastResponsePart.string.value + responsePart, lastResponsePart.string) };
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import { ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashC
|
|||
import { ChatMessageRole, IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider';
|
||||
import { ChatRequestParser } from 'vs/workbench/contrib/chat/common/chatRequestParser';
|
||||
import { IChat, IChatCompleteResponse, IChatDetail, IChatDynamicRequest, IChatFollowup, IChatProgress, IChatProvider, IChatProviderInfo, IChatRequest, IChatResponse, IChatService, IChatTransferredSessionData, IChatUserActionEvent, ISlashCommand, InteractiveSessionCopyKind, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatSlashCommandService, IChatSlashFragment } from 'vs/workbench/contrib/chat/common/chatSlashCommands';
|
||||
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';
|
||||
|
||||
|
@ -567,10 +567,8 @@ 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 commandResult = await this.chatSlashCommandService.executeCommand(commandPart.slashCommand.command, message.substring(commandPart.slashCommand.command.length + 1).trimStart(), new Progress<IChatSlashFragment>(p => {
|
||||
const { content } = p;
|
||||
const data = isCompleteInteractiveProgressTreeData(content) ? content : { content };
|
||||
progressCallback(data);
|
||||
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);
|
||||
agentOrCommandFollowups = Promise.resolve(commandResult?.followUp);
|
||||
rawResponse = { session: model.session! };
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, IDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IProgress } from 'vs/platform/progress/common/progress';
|
||||
import { IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider';
|
||||
import { IChatFollowup, IChatResponseProgressFileTreeData } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatFollowup, IChatProgress, IChatResponseProgressFileTreeData } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
||||
//#region slash service, commands etc
|
||||
|
@ -29,21 +29,18 @@ export interface IChatSlashData {
|
|||
export interface IChatSlashFragment {
|
||||
content: string | { treeData: IChatResponseProgressFileTreeData };
|
||||
}
|
||||
|
||||
export type IChatSlashCallback = { (prompt: string, progress: IProgress<IChatSlashFragment>, history: IChatMessage[], token: CancellationToken): Promise<{ followUp: IChatFollowup[] } | void> };
|
||||
export type IChatSlashCallback = { (prompt: string, progress: IProgress<IChatProgress>, history: IChatMessage[], token: CancellationToken): Promise<{ followUp: IChatFollowup[] } | void> };
|
||||
|
||||
export const IChatSlashCommandService = createDecorator<IChatSlashCommandService>('chatSlashCommandService');
|
||||
|
||||
/**
|
||||
* This currently only exists to drive /clear. Delete this when the agent service can handle that scenario
|
||||
* This currently only exists to drive /clear and /help
|
||||
*/
|
||||
export interface IChatSlashCommandService {
|
||||
_serviceBrand: undefined;
|
||||
readonly onDidChangeCommands: Event<void>;
|
||||
registerSlashData(data: IChatSlashData): IDisposable;
|
||||
registerSlashCallback(id: string, command: IChatSlashCallback): IDisposable;
|
||||
registerSlashCommand(data: IChatSlashData, command: IChatSlashCallback): IDisposable;
|
||||
executeCommand(id: string, prompt: string, progress: IProgress<IChatSlashFragment>, history: IChatMessage[], token: CancellationToken): Promise<{ followUp: IChatFollowup[] } | void>;
|
||||
executeCommand(id: string, prompt: string, progress: IProgress<IChatProgress>, history: IChatMessage[], token: CancellationToken): Promise<{ followUp: IChatFollowup[] } | void>;
|
||||
getCommands(): Array<IChatSlashData>;
|
||||
hasCommand(id: string): boolean;
|
||||
}
|
||||
|
@ -68,11 +65,12 @@ export class ChatSlashCommandService extends Disposable implements IChatSlashCom
|
|||
this._commands.clear();
|
||||
}
|
||||
|
||||
registerSlashData(data: IChatSlashData): IDisposable {
|
||||
registerSlashCommand(data: IChatSlashData, command: IChatSlashCallback): IDisposable {
|
||||
if (this._commands.has(data.command)) {
|
||||
throw new Error(`Already registered a command with id ${data.command}}`);
|
||||
}
|
||||
this._commands.set(data.command, { data });
|
||||
|
||||
this._commands.set(data.command, { data, command });
|
||||
this._onDidChangeCommands.fire();
|
||||
|
||||
return toDisposable(() => {
|
||||
|
@ -82,22 +80,6 @@ export class ChatSlashCommandService extends Disposable implements IChatSlashCom
|
|||
});
|
||||
}
|
||||
|
||||
registerSlashCallback(id: string, command: IChatSlashCallback): IDisposable {
|
||||
const data = this._commands.get(id);
|
||||
if (!data) {
|
||||
throw new Error(`No command with id ${id} registered`);
|
||||
}
|
||||
data.command = command;
|
||||
return toDisposable(() => data.command = undefined);
|
||||
}
|
||||
|
||||
registerSlashCommand(data: IChatSlashData, command: IChatSlashCallback): IDisposable {
|
||||
return combinedDisposable(
|
||||
this.registerSlashData(data),
|
||||
this.registerSlashCallback(data.command, command)
|
||||
);
|
||||
}
|
||||
|
||||
getCommands(): Array<IChatSlashData> {
|
||||
return Array.from(this._commands.values(), v => v.data);
|
||||
}
|
||||
|
@ -106,7 +88,7 @@ export class ChatSlashCommandService extends Disposable implements IChatSlashCom
|
|||
return this._commands.has(id);
|
||||
}
|
||||
|
||||
async executeCommand(id: string, prompt: string, progress: IProgress<IChatSlashFragment>, history: IChatMessage[], token: CancellationToken): Promise<{ followUp: IChatFollowup[] } | void> {
|
||||
async executeCommand(id: string, prompt: string, progress: IProgress<IChatProgress>, history: IChatMessage[], token: CancellationToken): Promise<{ followUp: IChatFollowup[] } | void> {
|
||||
const data = this._commands.get(id);
|
||||
if (!data) {
|
||||
throw new Error('No command with id ${id} NOT registered');
|
||||
|
|
|
@ -29,7 +29,6 @@ import { IViewsService } from 'vs/workbench/common/views';
|
|||
import { IChatContributionService } from 'vs/workbench/contrib/chat/common/chatContributionService';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { isExecuteActionContext } from 'vs/workbench/contrib/chat/browser/actions/chatExecuteActions';
|
||||
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { HasSpeechProvider, ISpeechService, SpeechToTextStatus } from 'vs/workbench/contrib/speech/common/speechService';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
|
@ -41,6 +40,7 @@ import { contrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegis
|
|||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { isNumber } from 'vs/base/common/types';
|
||||
import { AccessibilityVoiceSettingId, SpeechTimeoutDefault } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
|
||||
import { IChatExecuteActionContext } from 'vs/workbench/contrib/chat/browser/actions/chatExecuteActions';
|
||||
|
||||
const CONTEXT_VOICE_CHAT_GETTING_READY = new RawContextKey<boolean>('voiceChatGettingReady', false, { type: 'boolean', description: localize('voiceChatGettingReady', "True when getting ready for receiving voice input from the microphone for voice chat.") });
|
||||
const CONTEXT_VOICE_CHAT_IN_PROGRESS = new RawContextKey<boolean>('voiceChatInProgress', false, { type: 'boolean', description: localize('voiceChatInProgress', "True when voice recording from microphone is in progress for voice chat.") });
|
||||
|
@ -486,7 +486,8 @@ export class StartVoiceChatAction extends Action2 {
|
|||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const commandService = accessor.get(ICommandService);
|
||||
|
||||
if (isExecuteActionContext(context)) {
|
||||
const widget = (context as IChatExecuteActionContext)?.widget;
|
||||
if (widget) {
|
||||
// if we already get a context when the action is executed
|
||||
// from a toolbar within the chat widget, then make sure
|
||||
// to move focus into the input field so that the controller
|
||||
|
@ -494,7 +495,7 @@ export class StartVoiceChatAction extends Action2 {
|
|||
// TODO@bpasero this will actually not work if the button
|
||||
// is clicked from the inline editor while focus is in a
|
||||
// chat input field in a view or picker
|
||||
context.widget.focusInput();
|
||||
widget.focusInput();
|
||||
}
|
||||
|
||||
const controller = await VoiceChatSessionControllerFactory.create(accessor, 'focused');
|
||||
|
|
10
src/vscode-dts/vscode.proposed.chatAgents2.d.ts
vendored
10
src/vscode-dts/vscode.proposed.chatAgents2.d.ts
vendored
|
@ -91,6 +91,11 @@ declare module 'vscode' {
|
|||
*/
|
||||
readonly description: string;
|
||||
|
||||
/**
|
||||
* When the user clicks this slash command in `/help`, this text will be submitted to this slash command
|
||||
*/
|
||||
readonly sampleRequest?: string;
|
||||
|
||||
/**
|
||||
* Whether executing the command puts the
|
||||
* chat into a persistent mode, where the
|
||||
|
@ -204,6 +209,11 @@ declare module 'vscode' {
|
|||
*/
|
||||
followupProvider?: FollowupProvider;
|
||||
|
||||
/**
|
||||
* When the user clicks this agent in `/help`, this text will be submitted to this slash command
|
||||
*/
|
||||
sampleRequest?: string;
|
||||
|
||||
/**
|
||||
* An event that fires whenever feedback for a result is received, e.g. when a user up- or down-votes
|
||||
* a result.
|
||||
|
|
|
@ -16,5 +16,15 @@ declare module 'vscode' {
|
|||
* TODO@API name
|
||||
*/
|
||||
isSecondary?: boolean;
|
||||
|
||||
/**
|
||||
* A string that will be added before the listing of chat agents in `/help`.
|
||||
*/
|
||||
helpTextPrefix?: string | MarkdownString;
|
||||
|
||||
/**
|
||||
* A string that will be appended after the listing of chat agents in `/help`.
|
||||
*/
|
||||
helpTextPostfix?: string | MarkdownString;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue