Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 67885be

Browse files
committed
Add new mode picker in aide agent input
1 parent f7816b3 commit 67885be

File tree

4 files changed

+115
-9
lines changed

4 files changed

+115
-9
lines changed

src/vs/workbench/contrib/aideAgent/browser/actions/aideAgentExecuteActions.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { localize2 } from '../../../../../nls.js';
1010
import { Action2, MenuId, MenuRegistry, registerAction2 } from '../../../../../platform/actions/common/actions.js';
1111
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
1212
import { KeybindingWeight } from '../../../../../platform/keybinding/common/keybindingsRegistry.js';
13-
import { CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_CHAT_LOCATION, CONTEXT_CHAT_REQUEST_IN_PROGRESS, CONTEXT_IN_CHAT_INPUT, CONTEXT_LANGUAGE_MODELS_ARE_USER_SELECTABLE, CONTEXT_PARTICIPANT_SUPPORTS_MODEL_PICKER } from '../../common/aideAgentContextKeys.js';
13+
import { CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_CHAT_LOCATION, CONTEXT_CHAT_REQUEST_IN_PROGRESS, CONTEXT_IN_CHAT_INPUT } from '../../common/aideAgentContextKeys.js';
1414
import { IAideAgentService } from '../../common/aideAgentService.js';
1515
import { IAideAgentWidgetService, IChatWidget } from '../aideAgent.js';
1616
import { CHAT_CATEGORY } from './aideAgentActions.js';
@@ -65,15 +65,15 @@ export class SubmitAction extends Action2 {
6565
}
6666
}
6767

68-
export const ChatModelPickerActionId = 'workbench.action.aideAgent.pickModel';
69-
MenuRegistry.appendMenuItem(MenuId.AideAgentExecute, {
68+
export const AgentModePickerActionId = 'workbench.action.aideAgent.setMode';
69+
MenuRegistry.appendMenuItem(MenuId.AideAgentInput, {
7070
command: {
71-
id: ChatModelPickerActionId,
72-
title: localize2('chat.pickModel.label', "Pick Model"),
71+
id: AgentModePickerActionId,
72+
title: localize2('aideAgent.setMode.label', "Set Mode"),
7373
},
7474
order: 1,
7575
group: 'navigation',
76-
when: ContextKeyExpr.and(CONTEXT_LANGUAGE_MODELS_ARE_USER_SELECTABLE, CONTEXT_PARTICIPANT_SUPPORTS_MODEL_PICKER, ContextKeyExpr.equals(CONTEXT_CHAT_LOCATION.key, 'panel')),
76+
when: ContextKeyExpr.equals(CONTEXT_CHAT_LOCATION.key, 'panel'),
7777
});
7878

7979
export class CancelAction extends Action2 {

src/vs/workbench/contrib/aideAgent/browser/aideAgentInputPart.ts

+92-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import { IHistoryNavigationWidget } from '../../../../base/browser/history.js';
99
import { StandardKeyboardEvent } from '../../../../base/browser/keyboardEvent.js';
1010
import * as aria from '../../../../base/browser/ui/aria/aria.js';
1111
import { Button } from '../../../../base/browser/ui/button/button.js';
12+
import { renderLabelWithIcons } from '../../../../base/browser/ui/iconLabel/iconLabels.js';
13+
import { IAction } from '../../../../base/common/actions.js';
1214
import { Codicon } from '../../../../base/common/codicons.js';
13-
import { Emitter } from '../../../../base/common/event.js';
15+
import { Emitter, Event } from '../../../../base/common/event.js';
1416
import { HistoryNavigator2 } from '../../../../base/common/history.js';
1517
import { KeyCode } from '../../../../base/common/keyCodes.js';
1618
import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
@@ -35,24 +37,27 @@ import { HiddenItemStrategy, MenuWorkbenchToolBar } from '../../../../platform/a
3537
import { MenuId, MenuItemAction } from '../../../../platform/actions/common/actions.js';
3638
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
3739
import { IContextKey, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
40+
import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js';
3841
import { FileKind } from '../../../../platform/files/common/files.js';
3942
import { registerAndCreateHistoryNavigationContext } from '../../../../platform/history/browser/contextScopedHistoryWidget.js';
4043
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
4144
import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js';
4245
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';
4346
import { ILogService } from '../../../../platform/log/common/log.js';
47+
import { INotificationService } from '../../../../platform/notification/common/notification.js';
48+
import { IThemeService } from '../../../../platform/theme/common/themeService.js';
4449
import { ResourceLabels } from '../../../browser/labels.js';
4550
import { AccessibilityVerbositySettingId } from '../../accessibility/browser/accessibilityConfiguration.js';
4651
import { AccessibilityCommandId } from '../../accessibility/common/accessibilityCommands.js';
4752
import { getSimpleCodeEditorWidgetOptions, getSimpleEditorOptions, setupSimpleEditorSelectionStyling } from '../../codeEditor/browser/simpleEditorOptions.js';
4853
import { ChatAgentLocation } from '../common/aideAgentAgents.js';
4954
import { CONTEXT_CHAT_INPUT_CURSOR_AT_TOP, CONTEXT_CHAT_INPUT_HAS_FOCUS, CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_IN_CHAT_INPUT } from '../common/aideAgentContextKeys.js';
50-
import { IChatRequestVariableEntry } from '../common/aideAgentModel.js';
55+
import { AgentMode, IChatRequestVariableEntry } from '../common/aideAgentModel.js';
5156
import { IChatFollowup } from '../common/aideAgentService.js';
5257
import { IChatResponseViewModel } from '../common/aideAgentViewModel.js';
5358
import { IAideAgentWidgetHistoryService, IChatHistoryEntry } from '../common/aideAgentWidgetHistoryService.js';
5459
import { IAideAgentLMService } from '../common/languageModels.js';
55-
import { CancelAction, IChatExecuteActionContext, SubmitAction } from './actions/aideAgentExecuteActions.js';
60+
import { AgentModePickerActionId, CancelAction, IChatExecuteActionContext, SubmitAction } from './actions/aideAgentExecuteActions.js';
5661
import { IChatWidget } from './aideAgent.js';
5762
import { ChatFollowups } from './aideAgentFollowups.js';
5863

@@ -146,6 +151,12 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
146151
return metadataId;
147152
}
148153

154+
private _onDidChangeCurrentAgentMode = new Emitter<string>();
155+
private _currentAgentMode: AgentMode = AgentMode.Edit;
156+
get currentAgentMode() {
157+
return this._currentAgentMode;
158+
}
159+
149160
private cachedDimensions: dom.Dimension | undefined;
150161
private cachedExecuteToolbarWidth: number | undefined;
151162
private cachedInputToolbarWidth: number | undefined;
@@ -484,6 +495,16 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
484495
menuOptions: { shouldForwardArgs: true },
485496
hiddenItemStrategy: HiddenItemStrategy.Ignore,
486497
actionViewItemProvider: (action, options) => {
498+
if (action.id === AgentModePickerActionId && action instanceof MenuItemAction) {
499+
const itemDelegate: AgentModeSetterDelegate = {
500+
onDidChangeMode: this._onDidChangeCurrentAgentMode.event,
501+
setMode: (modeId: string) => {
502+
this._currentAgentMode = modeId as AgentMode;
503+
}
504+
};
505+
return this.instantiationService.createInstance(AgentModeActionViewItem, action, this._currentAgentMode, itemDelegate);
506+
}
507+
487508
if (action instanceof MenuItemAction) {
488509
return this.instantiationService.createInstance(MenuEntryActionViewItem, action, undefined);
489510
}
@@ -717,5 +738,73 @@ function getLastPosition(model: ITextModel): IPosition {
717738
return { lineNumber: model.getLineCount(), column: model.getLineLength(model.getLineCount()) + 1 };
718739
}
719740

741+
interface AgentModeSetterDelegate {
742+
onDidChangeMode: Event<string>;
743+
setMode(selectedModeId: string): void;
744+
}
745+
746+
class AgentModeActionViewItem extends MenuEntryActionViewItem {
747+
constructor(
748+
action: MenuItemAction,
749+
private currentAgentMode: AgentMode,
750+
private delegate: AgentModeSetterDelegate,
751+
@IKeybindingService keybindingService: IKeybindingService,
752+
@INotificationService notificationService: INotificationService,
753+
@IContextKeyService contextKeyService: IContextKeyService,
754+
@IThemeService themeService: IThemeService,
755+
@IContextMenuService contextMenuService: IContextMenuService,
756+
@IAccessibilityService _accessibilityService: IAccessibilityService
757+
) {
758+
super(action, undefined, keybindingService, notificationService, contextKeyService, themeService, contextMenuService, _accessibilityService);
759+
760+
this._register(delegate.onDidChangeMode(modeId => {
761+
this.currentAgentMode = modeId as AgentMode;
762+
this.updateLabel();
763+
}));
764+
}
765+
766+
override async onClick(): Promise<void> {
767+
this._openContextMenu();
768+
}
769+
770+
override render(container: HTMLElement): void {
771+
super.render(container);
772+
container.classList.add('agentmode-picker-item');
773+
}
774+
775+
protected override updateLabel(): void {
776+
if (this.label) {
777+
this.label.textContent = this.currentAgentMode;
778+
dom.reset(this.label, ...renderLabelWithIcons(`${this.currentAgentMode}$(chevron-down)`));
779+
}
780+
}
781+
782+
private _openContextMenu() {
783+
const setAgentModeAction = (mode: string): IAction => {
784+
return {
785+
id: mode,
786+
label: mode,
787+
tooltip: '',
788+
class: undefined,
789+
enabled: true,
790+
checked: mode === this.currentAgentMode,
791+
run: () => {
792+
this.currentAgentMode = mode as AgentMode;
793+
this.delegate.setMode(mode);
794+
this.updateLabel();
795+
}
796+
};
797+
};
798+
799+
this._contextMenuService.showContextMenu({
800+
getAnchor: () => this.element!,
801+
getActions: () => [
802+
setAgentModeAction('Edit'),
803+
setAgentModeAction('Chat'),
804+
]
805+
});
806+
}
807+
}
808+
720809
const chatInputEditorContainerSelector = '.interactive-input-editor';
721810
setupSimpleEditorSelectionStyling(chatInputEditorContainerSelector);

src/vs/workbench/contrib/aideAgent/browser/media/aideAgent.css

+12
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,18 @@ have to be updated for changes to the rules above, or to support more deeply nes
509509
margin-right: auto;
510510
}
511511

512+
.interactive-session .chat-input-toolbars .agentmode-picker-item .action-label {
513+
height: 16px;
514+
padding: 3px 0px 3px 6px;
515+
display: flex;
516+
align-items: center;
517+
}
518+
519+
.interactive-session .chat-input-toolbars .agentmode-picker-item .action-label .codicon-chevron-down {
520+
font-size: 12px;
521+
margin-left: 2px;
522+
}
523+
512524
.interactive-session .chat-input-toolbars .monaco-action-bar .actions-container {
513525
display: flex;
514526
gap: 4px;

src/vs/workbench/contrib/aideAgent/common/aideAgentModel.ts

+5
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,11 @@ export enum ChatModelInitState {
748748
Initialized
749749
}
750750

751+
export enum AgentMode {
752+
Chat = 'Chat',
753+
Edit = 'Edit'
754+
}
755+
751756
export class ChatModel extends Disposable implements IChatModel {
752757
static getDefaultTitle(requests: (ISerializableChatRequestData | IChatExchangeModel)[]): string {
753758
const firstRequestMessage = requests.find(r => isRequestModel(r));

0 commit comments

Comments
 (0)