diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts index 245f7c37d5c..d70710f9d59 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts @@ -54,6 +54,7 @@ import { ChatMode, validateChatMode } from '../../common/constants.js'; import { CopilotUsageExtensionFeatureId } from '../../common/languageModelStats.js'; import { ILanguageModelToolsService } from '../../common/languageModelToolsService.js'; import { ChatViewId, IChatWidget, IChatWidgetService, showChatView, showCopilotView } from '../chat.js'; +import { ctxHasRequestInProgress, ctxIsGlobalEditingSession } from '../chatEditing/chatEditingEditorContextKeys.js'; import { IChatEditorOptions } from '../chatEditor.js'; import { ChatEditorInput } from '../chatEditorInput.js'; import { ChatViewPane } from '../chatViewPane.js'; @@ -118,11 +119,16 @@ export function registerChatActions() { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KeyI } }, - menu: { + menu: [{ id: MenuId.ChatTitleBarMenu, group: 'a_open', order: 1 - } + }, { + id: MenuId.ChatEditingEditorContent, + when: ContextKeyExpr.and(ctxHasRequestInProgress, ctxIsGlobalEditingSession), + group: 'navigate', + order: 4, + }] }); } diff --git a/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorOverlay.ts b/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorOverlay.ts index 394530bffbc..54e51b8bcef 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorOverlay.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorOverlay.ts @@ -31,11 +31,11 @@ import { IInlineChatSessionService } from '../../../inlineChat/browser/inlineCha import { isEqual } from '../../../../../base/common/resources.js'; import { ObservableEditorSession } from './chatEditingEditorContextKeys.js'; import { rcut } from '../../../../../base/common/strings.js'; +import { CHAT_OPEN_ACTION_ID } from '../actions/chatActions.js'; class ChatEditorOverlayWidget { private readonly _domNode: HTMLElement; - // private readonly _progressNode: HTMLElement; private readonly _toolbar: WorkbenchToolBar; private readonly _showStore = new DisposableStore(); @@ -168,7 +168,7 @@ class ChatEditorOverlayWidget { }; } - if (action.id === 'inlineChat2.reveal' || action.id === 'workbench.action.chat.openEditSession') { + if (action.id === 'inlineChat2.reveal' || action.id === CHAT_OPEN_ACTION_ID) { return new class extends ActionViewItem { private _requestMessage: IObservable<{ message: string; paused?: boolean } | undefined>; @@ -248,10 +248,6 @@ class ChatEditorOverlayWidget { })); } - - protected override getTooltip(): string | undefined { - return this._requestMessage.get()?.message || super.getTooltip(); - } }; } return undefined; diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.ts index c26b4b49211..fbdcc1d5f36 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.ts @@ -30,6 +30,7 @@ registerEditorContribution(InlineChatController.ID, InlineChatController, Editor registerAction2(InlineChatActions.StopSessionAction2); registerAction2(InlineChatActions.RevealWidget); +registerAction2(InlineChatActions.CancelRequestAction); // --- browser diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index dc31d83bea9..e1814505d92 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -12,7 +12,7 @@ import { EmbeddedCodeEditorWidget } from '../../../../editor/browser/widget/code import { EditorContextKeys } from '../../../../editor/common/editorContextKeys.js'; import { InlineChatController, InlineChatController1, InlineChatController2, InlineChatRunOptions } from './inlineChatController.js'; import { ACTION_ACCEPT_CHANGES, CTX_INLINE_CHAT_HAS_AGENT, CTX_INLINE_CHAT_HAS_STASHED_SESSION, CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_VISIBLE, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, CTX_INLINE_CHAT_RESPONSE_TYPE, InlineChatResponseType, ACTION_REGENERATE_RESPONSE, ACTION_VIEW_IN_CHAT, ACTION_TOGGLE_DIFF, CTX_INLINE_CHAT_CHANGE_HAS_DIFF, CTX_INLINE_CHAT_CHANGE_SHOWS_DIFF, MENU_INLINE_CHAT_ZONE, ACTION_DISCARD_CHANGES, CTX_INLINE_CHAT_POSSIBLE, ACTION_START, CTX_INLINE_CHAT_HAS_AGENT2, MENU_INLINE_CHAT_SIDE } from '../common/inlineChat.js'; -import { ctxIsGlobalEditingSession, ctxRequestCount } from '../../chat/browser/chatEditing/chatEditingEditorContextKeys.js'; +import { ctxHasRequestInProgress, ctxIsGlobalEditingSession, ctxRequestCount } from '../../chat/browser/chatEditing/chatEditingEditorContextKeys.js'; import { localize, localize2 } from '../../../../nls.js'; import { Action2, IAction2Options, MenuId } from '../../../../platform/actions/common/actions.js'; import { ContextKeyExpr, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js'; @@ -641,3 +641,36 @@ export class RevealWidget extends AbstractInline2ChatAction { ctrl.markActiveController(); } } + +export class CancelRequestAction extends AbstractInline2ChatAction { + constructor() { + super({ + id: 'inlineChat2.cancelRequest', + title: localize2('cancel', "Cancel Request"), + f1: true, + icon: Codicon.stopCircle, + precondition: ContextKeyExpr.and(ctxIsGlobalEditingSession.negate(), ctxHasRequestInProgress), + toggled: CTX_INLINE_CHAT_VISIBLE, + menu: { + id: MenuId.ChatEditingEditorContent, + when: ContextKeyExpr.and( + ctxHasRequestInProgress, + ctxIsGlobalEditingSession.negate(), + ), + group: 'navigate', + order: 14, + } + }); + } + + runInlineChatCommand(accessor: ServicesAccessor, ctrl: InlineChatController2, _editor: ICodeEditor): void { + const chatService = accessor.get(IChatService); + + const { viewModel } = ctrl.widget.chatWidget; + if (viewModel) { + ctrl.toggleWidgetUntilNextRequest(); + ctrl.markActiveController(); + chatService.cancelCurrentRequestForSession(viewModel.sessionId); + } + } +}