mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-12 01:49:38 -05:00
chat: add "Don't show again" to Autopilot and Bypass Approvals warning dialogs (#311262)
* Add 'Don't show again' to autopilot/bypass approvals warning dialogs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add developer command to reset chat permission warning dialogs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Always show AutoApprove warning independently of Autopilot Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Extract permission storage keys to shared constants module Move AUTOPILOT_DONT_SHOW_AGAIN_KEY and AUTO_APPROVE_DONT_SHOW_AGAIN_KEY to chat/common/chatPermissionStorageKeys.ts so both chatDeveloperActions and permissionPickerActionItem import from a lightweight shared module. This avoids chatDeveloperActions pulling in heavy widget/UI dependencies at startup via the permissionPickerActionItem import. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
197f33eb36
commit
2212cb295d
@@ -17,6 +17,8 @@ import { ChatContextKeys } from '../../common/actions/chatContextKeys.js';
|
||||
import { IChatService } from '../../common/chatService/chatService.js';
|
||||
import { ILanguageModelsService } from '../../common/languageModels.js';
|
||||
import { IChatWidgetService } from '../chat.js';
|
||||
import { IStorageService, StorageScope } from '../../../../../platform/storage/common/storage.js';
|
||||
import { AUTOPILOT_DONT_SHOW_AGAIN_KEY, AUTO_APPROVE_DONT_SHOW_AGAIN_KEY } from '../../common/chatPermissionStorageKeys.js';
|
||||
|
||||
function uriReplacer(_key: string, value: unknown): unknown {
|
||||
if (URI.isUri(value)) {
|
||||
@@ -37,6 +39,7 @@ export function registerChatDeveloperActions() {
|
||||
registerAction2(InspectChatModelAction);
|
||||
registerAction2(InspectChatModelReferencesAction);
|
||||
registerAction2(ClearRecentlyUsedLanguageModelsAction);
|
||||
registerAction2(ResetChatPermissionWarningDialogsAction);
|
||||
}
|
||||
|
||||
function formatChatModelReferenceInspection(accessor: ServicesAccessor): string {
|
||||
@@ -233,3 +236,23 @@ class ClearRecentlyUsedLanguageModelsAction extends Action2 {
|
||||
accessor.get(ILanguageModelsService).clearRecentlyUsedList();
|
||||
}
|
||||
}
|
||||
|
||||
class ResetChatPermissionWarningDialogsAction extends Action2 {
|
||||
static readonly ID = 'workbench.action.chat.resetPermissionWarningDialogs';
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: ResetChatPermissionWarningDialogsAction.ID,
|
||||
title: localize2('workbench.action.chat.resetPermissionWarningDialogs.label', "Reset Permission Warning Dialogs (Autopilot, Bypass Approvals)"),
|
||||
category: Categories.Developer,
|
||||
f1: true,
|
||||
precondition: ChatContextKeys.enabled
|
||||
});
|
||||
}
|
||||
|
||||
override run(accessor: ServicesAccessor): void {
|
||||
const storageService = accessor.get(IStorageService);
|
||||
storageService.remove(AUTOPILOT_DONT_SHOW_AGAIN_KEY, StorageScope.PROFILE);
|
||||
storageService.remove(AUTO_APPROVE_DONT_SHOW_AGAIN_KEY, StorageScope.PROFILE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,17 +24,29 @@ import { MarkdownString } from '../../../../../../base/common/htmlContent.js';
|
||||
import { ChatInputPickerActionViewItem, IChatInputPickerOptions } from './chatInputPickerActionItem.js';
|
||||
import { IOpenerService } from '../../../../../../platform/opener/common/opener.js';
|
||||
import { URI } from '../../../../../../base/common/uri.js';
|
||||
import { IStorageService, StorageScope, StorageTarget } from '../../../../../../platform/storage/common/storage.js';
|
||||
|
||||
// Track whether warnings have been shown this VS Code session
|
||||
const shownWarnings = new Set<ChatPermissionLevel>();
|
||||
|
||||
function hasShownElevatedWarning(level: ChatPermissionLevel): boolean {
|
||||
import { AUTOPILOT_DONT_SHOW_AGAIN_KEY, AUTO_APPROVE_DONT_SHOW_AGAIN_KEY } from '../../../common/chatPermissionStorageKeys.js';
|
||||
|
||||
function dontShowAgainKey(level: ChatPermissionLevel): string | undefined {
|
||||
if (level === ChatPermissionLevel.Autopilot) {
|
||||
return AUTOPILOT_DONT_SHOW_AGAIN_KEY;
|
||||
}
|
||||
if (level === ChatPermissionLevel.AutoApprove) {
|
||||
return AUTO_APPROVE_DONT_SHOW_AGAIN_KEY;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function hasShownElevatedWarning(level: ChatPermissionLevel, storageService: IStorageService): boolean {
|
||||
if (shownWarnings.has(level)) {
|
||||
return true;
|
||||
}
|
||||
// Autopilot is stricter than AutoApprove, so confirming Autopilot
|
||||
// implies the user already accepted the AutoApprove risks.
|
||||
if (level === ChatPermissionLevel.AutoApprove && shownWarnings.has(ChatPermissionLevel.Autopilot)) {
|
||||
const key = dontShowAgainKey(level);
|
||||
if (key && storageService.getBoolean(key, StorageScope.PROFILE, false)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -57,6 +69,7 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IDialogService private readonly dialogService: IDialogService,
|
||||
@IOpenerService openerService: IOpenerService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
) {
|
||||
const isAutoApprovePolicyRestricted = () => configurationService.inspect<boolean>(ChatConfiguration.GlobalAutoApprove).policyValue === false;
|
||||
const isAutopilotEnabled = () => configurationService.getValue<boolean>(ChatConfiguration.AutopilotEnabled) !== false;
|
||||
@@ -98,7 +111,7 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
|
||||
: localize('permissions.autoApprove.description', "Auto-approve all tool calls and retry on errors"),
|
||||
},
|
||||
run: async () => {
|
||||
if (!hasShownElevatedWarning(ChatPermissionLevel.AutoApprove)) {
|
||||
if (!hasShownElevatedWarning(ChatPermissionLevel.AutoApprove, storageService)) {
|
||||
const result = await this.dialogService.prompt({
|
||||
type: Severity.Warning,
|
||||
message: localize('permissions.autoApprove.warning.title', "Enable Bypass Approvals?"),
|
||||
@@ -112,6 +125,10 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
|
||||
run: () => false
|
||||
},
|
||||
],
|
||||
checkbox: {
|
||||
label: localize('permissions.warning.dontShowAgain', "Don't show again"),
|
||||
checked: false,
|
||||
},
|
||||
custom: {
|
||||
icon: Codicon.warning,
|
||||
markdownDetails: [{
|
||||
@@ -122,6 +139,9 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
|
||||
if (result.result !== true) {
|
||||
return;
|
||||
}
|
||||
if (result.checkboxChecked) {
|
||||
storageService.store(AUTO_APPROVE_DONT_SHOW_AGAIN_KEY, true, StorageScope.PROFILE, StorageTarget.USER);
|
||||
}
|
||||
shownWarnings.add(ChatPermissionLevel.AutoApprove);
|
||||
}
|
||||
delegate.setPermissionLevel(ChatPermissionLevel.AutoApprove);
|
||||
@@ -147,7 +167,7 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
|
||||
: localize('permissions.autopilot.description', "Auto-approve all tool calls and continue until the task is done"),
|
||||
},
|
||||
run: async () => {
|
||||
if (!hasShownElevatedWarning(ChatPermissionLevel.Autopilot)) {
|
||||
if (!hasShownElevatedWarning(ChatPermissionLevel.Autopilot, storageService)) {
|
||||
const result = await this.dialogService.prompt({
|
||||
type: Severity.Warning,
|
||||
message: localize('permissions.autopilot.warning.title', "Enable Autopilot?"),
|
||||
@@ -161,6 +181,10 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
|
||||
run: () => false
|
||||
},
|
||||
],
|
||||
checkbox: {
|
||||
label: localize('permissions.warning.dontShowAgain', "Don't show again"),
|
||||
checked: false,
|
||||
},
|
||||
custom: {
|
||||
icon: Codicon.rocket,
|
||||
markdownDetails: [{
|
||||
@@ -171,6 +195,9 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
|
||||
if (result.result !== true) {
|
||||
return;
|
||||
}
|
||||
if (result.checkboxChecked) {
|
||||
storageService.store(AUTOPILOT_DONT_SHOW_AGAIN_KEY, true, StorageScope.PROFILE, StorageTarget.USER);
|
||||
}
|
||||
shownWarnings.add(ChatPermissionLevel.Autopilot);
|
||||
}
|
||||
delegate.setPermissionLevel(ChatPermissionLevel.Autopilot);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// Storage keys for persisting the user's choice to skip the warning dialog
|
||||
// across sessions when "Don't show again" is checked.
|
||||
export const AUTOPILOT_DONT_SHOW_AGAIN_KEY = 'chat.permissions.autopilot.dontShowWarningAgain';
|
||||
export const AUTO_APPROVE_DONT_SHOW_AGAIN_KEY = 'chat.permissions.autoApprove.dontShowWarningAgain';
|
||||
Reference in New Issue
Block a user