Merge pull request #209080 from microsoft/merogge/first-code

add run/insert first code block actions when there are multiple
This commit is contained in:
Megan Rogge 2024-03-29 05:35:08 -07:00 committed by GitHub
commit 7955ac4224
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 83 additions and 7 deletions

View file

@ -19,7 +19,9 @@ export const enum TerminalChatCommandId {
FeedbackUnhelpful = 'workbench.action.terminal.chat.feedbackUnhelpful',
FeedbackReportIssue = 'workbench.action.terminal.chat.feedbackReportIssue',
RunCommand = 'workbench.action.terminal.chat.runCommand',
RunFirstCommand = 'workbench.action.terminal.chat.runFirstCommand',
InsertCommand = 'workbench.action.terminal.chat.insertCommand',
InsertFirstCommand = 'workbench.action.terminal.chat.insertFirstCommand',
ViewInChat = 'workbench.action.terminal.chat.viewInChat',
PreviousFromHistory = 'workbench.action.terminal.chat.previousFromHistory',
NextFromHistory = 'workbench.action.terminal.chat.nextFromHistory',
@ -39,6 +41,7 @@ export const enum TerminalChatContextKeyStrings {
ChatAgentRegistered = 'terminalChatAgentRegistered',
ChatResponseEditorFocused = 'terminalChatResponseEditorFocused',
ChatResponseContainsCodeBlock = 'terminalChatResponseContainsCodeBlock',
ChatResponseContainsMultipleCodeBlocks = 'terminalChatResponseContainsMultipleCodeBlocks',
ChatResponseSupportsIssueReporting = 'terminalChatResponseSupportsIssueReporting',
ChatSessionResponseVote = 'terminalChatSessionResponseVote',
}
@ -61,9 +64,12 @@ export namespace TerminalChatContextKeys {
/** Whether the terminal chat agent has been registered */
export const agentRegistered = new RawContextKey<boolean>(TerminalChatContextKeyStrings.ChatAgentRegistered, false, localize('chatAgentRegisteredContextKey', "Whether the terminal chat agent has been registered."));
/** The type of chat response, if any */
/** The chat response contains at least one code block */
export const responseContainsCodeBlock = new RawContextKey<boolean>(TerminalChatContextKeyStrings.ChatResponseContainsCodeBlock, false, localize('chatResponseContainsCodeBlockContextKey', "Whether the chat response contains a code block."));
/** The chat response contains multiple code blocks */
export const responseContainsMultipleCodeBlocks = new RawContextKey<boolean>(TerminalChatContextKeyStrings.ChatResponseContainsMultipleCodeBlocks, false, localize('chatResponseContainsMultipleCodeBlocksContextKey', "Whether the chat response contains multiple code blocks."));
/** Whether the response supports issue reporting */
export const responseSupportsIssueReporting = new RawContextKey<boolean>(TerminalChatContextKeyStrings.ChatResponseSupportsIssueReporting, false, localize('chatResponseSupportsIssueReportingContextKey', "Whether the response supports issue reporting"));

View file

@ -156,7 +156,8 @@ registerActiveXtermAction({
ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
TerminalChatContextKeys.requestActive.negate(),
TerminalChatContextKeys.agentRegistered,
TerminalChatContextKeys.responseContainsCodeBlock
TerminalChatContextKeys.responseContainsCodeBlock,
TerminalChatContextKeys.responseContainsMultipleCodeBlocks.negate()
),
icon: Codicon.play,
keybinding: {
@ -168,7 +169,39 @@ registerActiveXtermAction({
id: MENU_TERMINAL_CHAT_WIDGET_STATUS,
group: '0_main',
order: 0,
when: ContextKeyExpr.and(TerminalChatContextKeys.responseContainsCodeBlock, TerminalChatContextKeys.requestActive.negate())
when: ContextKeyExpr.and(TerminalChatContextKeys.responseContainsCodeBlock, TerminalChatContextKeys.responseContainsMultipleCodeBlocks.negate(), TerminalChatContextKeys.requestActive.negate())
},
run: (_xterm, _accessor, activeInstance) => {
if (isDetachedTerminalInstance(activeInstance)) {
return;
}
const contr = TerminalChatController.activeChatWidget || TerminalChatController.get(activeInstance);
contr?.acceptCommand(true);
}
});
registerActiveXtermAction({
id: TerminalChatCommandId.RunFirstCommand,
title: localize2('runFirstCommand', 'Run First Chat Command'),
shortTitle: localize2('runFirst', 'Run First'),
precondition: ContextKeyExpr.and(
ContextKeyExpr.has(`config.${TerminalSettingId.ExperimentalInlineChat}`),
ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
TerminalChatContextKeys.requestActive.negate(),
TerminalChatContextKeys.agentRegistered,
TerminalChatContextKeys.responseContainsMultipleCodeBlocks
),
icon: Codicon.play,
keybinding: {
when: TerminalChatContextKeys.requestActive.negate(),
weight: KeybindingWeight.WorkbenchContrib,
primary: KeyMod.CtrlCmd | KeyCode.Enter,
},
menu: {
id: MENU_TERMINAL_CHAT_WIDGET_STATUS,
group: '0_main',
order: 0,
when: ContextKeyExpr.and(TerminalChatContextKeys.responseContainsMultipleCodeBlocks, TerminalChatContextKeys.requestActive.negate())
},
run: (_xterm, _accessor, activeInstance) => {
if (isDetachedTerminalInstance(activeInstance)) {
@ -188,7 +221,8 @@ registerActiveXtermAction({
ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
TerminalChatContextKeys.requestActive.negate(),
TerminalChatContextKeys.agentRegistered,
TerminalChatContextKeys.responseContainsCodeBlock
TerminalChatContextKeys.responseContainsCodeBlock,
TerminalChatContextKeys.responseContainsMultipleCodeBlocks.negate()
),
keybinding: {
when: TerminalChatContextKeys.requestActive.negate(),
@ -199,7 +233,38 @@ registerActiveXtermAction({
id: MENU_TERMINAL_CHAT_WIDGET_STATUS,
group: '0_main',
order: 1,
when: ContextKeyExpr.and(TerminalChatContextKeys.responseContainsCodeBlock, TerminalChatContextKeys.requestActive.negate())
when: ContextKeyExpr.and(TerminalChatContextKeys.responseContainsCodeBlock, TerminalChatContextKeys.responseContainsMultipleCodeBlocks.negate(), TerminalChatContextKeys.requestActive.negate())
},
run: (_xterm, _accessor, activeInstance) => {
if (isDetachedTerminalInstance(activeInstance)) {
return;
}
const contr = TerminalChatController.activeChatWidget || TerminalChatController.get(activeInstance);
contr?.acceptCommand(false);
}
});
registerActiveXtermAction({
id: TerminalChatCommandId.InsertFirstCommand,
title: localize2('insertFirstCommand', 'Insert First Chat Command'),
shortTitle: localize2('insertFirst', 'Insert First'),
precondition: ContextKeyExpr.and(
ContextKeyExpr.has(`config.${TerminalSettingId.ExperimentalInlineChat}`),
ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
TerminalChatContextKeys.requestActive.negate(),
TerminalChatContextKeys.agentRegistered,
TerminalChatContextKeys.responseContainsMultipleCodeBlocks
),
keybinding: {
when: TerminalChatContextKeys.requestActive.negate(),
weight: KeybindingWeight.WorkbenchContrib,
primary: KeyMod.Alt | KeyCode.Enter,
},
menu: {
id: MENU_TERMINAL_CHAT_WIDGET_STATUS,
group: '0_main',
order: 1,
when: ContextKeyExpr.and(TerminalChatContextKeys.responseContainsMultipleCodeBlocks, TerminalChatContextKeys.requestActive.negate())
},
run: (_xterm, _accessor, activeInstance) => {
if (isDetachedTerminalInstance(activeInstance)) {

View file

@ -63,6 +63,7 @@ export class TerminalChatController extends Disposable implements ITerminalContr
private readonly _requestActiveContextKey: IContextKey<boolean>;
private readonly _terminalAgentRegisteredContextKey: IContextKey<boolean>;
private readonly _responseContainsCodeBlockContextKey: IContextKey<boolean>;
private readonly _responseContainsMulitpleCodeBlocksContextKey: IContextKey<boolean>;
private readonly _responseSupportsIssueReportingContextKey: IContextKey<boolean>;
private readonly _sessionResponseVoteContextKey: IContextKey<string | undefined>;
@ -103,6 +104,7 @@ export class TerminalChatController extends Disposable implements ITerminalContr
this._requestActiveContextKey = TerminalChatContextKeys.requestActive.bindTo(this._contextKeyService);
this._terminalAgentRegisteredContextKey = TerminalChatContextKeys.agentRegistered.bindTo(this._contextKeyService);
this._responseContainsCodeBlockContextKey = TerminalChatContextKeys.responseContainsCodeBlock.bindTo(this._contextKeyService);
this._responseContainsMulitpleCodeBlocksContextKey = TerminalChatContextKeys.responseContainsMultipleCodeBlocks.bindTo(this._contextKeyService);
this._responseSupportsIssueReportingContextKey = TerminalChatContextKeys.responseSupportsIssueReporting.bindTo(this._contextKeyService);
this._sessionResponseVoteContextKey = TerminalChatContextKeys.sessionResponseVote.bindTo(this._contextKeyService);
@ -327,7 +329,10 @@ export class TerminalChatController extends Disposable implements ITerminalContr
this._chatAccessibilityService.acceptResponse(responseContent, accessibilityRequestId);
const containsCode = responseContent.includes('```');
this._chatWidget?.value.inlineChatWidget.updateChatMessage({ message: new MarkdownString(responseContent), requestId: this._currentRequest.id, providerId: 'terminal' }, false, containsCode);
this._responseContainsCodeBlockContextKey.set(containsCode);
const firstCodeBlock = await this.chatWidget?.inlineChatWidget.getCodeBlockInfo(0);
const secondCodeBlock = await this.chatWidget?.inlineChatWidget.getCodeBlockInfo(1);
this._responseContainsCodeBlockContextKey.set(!!firstCodeBlock);
this._responseContainsMulitpleCodeBlocksContextKey.set(!!secondCodeBlock);
this._chatWidget?.value.inlineChatWidget.updateToolbar(true);
}
const supportIssueReporting = this._currentRequest?.response?.agent?.metadata?.supportIssueReporting;

View file

@ -57,7 +57,7 @@ export class TerminalChatWidget extends Disposable {
menu: MENU_TERMINAL_CHAT_WIDGET_STATUS,
options: {
buttonConfigProvider: action => {
if (action.id === TerminalChatCommandId.ViewInChat || action.id === TerminalChatCommandId.RunCommand) {
if (action.id === TerminalChatCommandId.ViewInChat || action.id === TerminalChatCommandId.RunCommand || action.id === TerminalChatCommandId.RunFirstCommand) {
return { isSecondary: false };
} else {
return { isSecondary: true };