Skip to content

Commit 2212cb2

Browse files
ulugbeknaCopilot
andauthored
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>
1 parent 197f33e commit 2212cb2

3 files changed

Lines changed: 65 additions & 6 deletions

File tree

src/vs/workbench/contrib/chat/browser/actions/chatDeveloperActions.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import { ChatContextKeys } from '../../common/actions/chatContextKeys.js';
1717
import { IChatService } from '../../common/chatService/chatService.js';
1818
import { ILanguageModelsService } from '../../common/languageModels.js';
1919
import { IChatWidgetService } from '../chat.js';
20+
import { IStorageService, StorageScope } from '../../../../../platform/storage/common/storage.js';
21+
import { AUTOPILOT_DONT_SHOW_AGAIN_KEY, AUTO_APPROVE_DONT_SHOW_AGAIN_KEY } from '../../common/chatPermissionStorageKeys.js';
2022

2123
function uriReplacer(_key: string, value: unknown): unknown {
2224
if (URI.isUri(value)) {
@@ -37,6 +39,7 @@ export function registerChatDeveloperActions() {
3739
registerAction2(InspectChatModelAction);
3840
registerAction2(InspectChatModelReferencesAction);
3941
registerAction2(ClearRecentlyUsedLanguageModelsAction);
42+
registerAction2(ResetChatPermissionWarningDialogsAction);
4043
}
4144

4245
function formatChatModelReferenceInspection(accessor: ServicesAccessor): string {
@@ -233,3 +236,23 @@ class ClearRecentlyUsedLanguageModelsAction extends Action2 {
233236
accessor.get(ILanguageModelsService).clearRecentlyUsedList();
234237
}
235238
}
239+
240+
class ResetChatPermissionWarningDialogsAction extends Action2 {
241+
static readonly ID = 'workbench.action.chat.resetPermissionWarningDialogs';
242+
243+
constructor() {
244+
super({
245+
id: ResetChatPermissionWarningDialogsAction.ID,
246+
title: localize2('workbench.action.chat.resetPermissionWarningDialogs.label', "Reset Permission Warning Dialogs (Autopilot, Bypass Approvals)"),
247+
category: Categories.Developer,
248+
f1: true,
249+
precondition: ChatContextKeys.enabled
250+
});
251+
}
252+
253+
override run(accessor: ServicesAccessor): void {
254+
const storageService = accessor.get(IStorageService);
255+
storageService.remove(AUTOPILOT_DONT_SHOW_AGAIN_KEY, StorageScope.PROFILE);
256+
storageService.remove(AUTO_APPROVE_DONT_SHOW_AGAIN_KEY, StorageScope.PROFILE);
257+
}
258+
}

src/vs/workbench/contrib/chat/browser/widget/input/permissionPickerActionItem.ts

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,29 @@ import { MarkdownString } from '../../../../../../base/common/htmlContent.js';
2424
import { ChatInputPickerActionViewItem, IChatInputPickerOptions } from './chatInputPickerActionItem.js';
2525
import { IOpenerService } from '../../../../../../platform/opener/common/opener.js';
2626
import { URI } from '../../../../../../base/common/uri.js';
27+
import { IStorageService, StorageScope, StorageTarget } from '../../../../../../platform/storage/common/storage.js';
2728

2829
// Track whether warnings have been shown this VS Code session
2930
const shownWarnings = new Set<ChatPermissionLevel>();
3031

31-
function hasShownElevatedWarning(level: ChatPermissionLevel): boolean {
32+
import { AUTOPILOT_DONT_SHOW_AGAIN_KEY, AUTO_APPROVE_DONT_SHOW_AGAIN_KEY } from '../../../common/chatPermissionStorageKeys.js';
33+
34+
function dontShowAgainKey(level: ChatPermissionLevel): string | undefined {
35+
if (level === ChatPermissionLevel.Autopilot) {
36+
return AUTOPILOT_DONT_SHOW_AGAIN_KEY;
37+
}
38+
if (level === ChatPermissionLevel.AutoApprove) {
39+
return AUTO_APPROVE_DONT_SHOW_AGAIN_KEY;
40+
}
41+
return undefined;
42+
}
43+
44+
function hasShownElevatedWarning(level: ChatPermissionLevel, storageService: IStorageService): boolean {
3245
if (shownWarnings.has(level)) {
3346
return true;
3447
}
35-
// Autopilot is stricter than AutoApprove, so confirming Autopilot
36-
// implies the user already accepted the AutoApprove risks.
37-
if (level === ChatPermissionLevel.AutoApprove && shownWarnings.has(ChatPermissionLevel.Autopilot)) {
48+
const key = dontShowAgainKey(level);
49+
if (key && storageService.getBoolean(key, StorageScope.PROFILE, false)) {
3850
return true;
3951
}
4052
return false;
@@ -57,6 +69,7 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
5769
@IConfigurationService configurationService: IConfigurationService,
5870
@IDialogService private readonly dialogService: IDialogService,
5971
@IOpenerService openerService: IOpenerService,
72+
@IStorageService storageService: IStorageService,
6073
) {
6174
const isAutoApprovePolicyRestricted = () => configurationService.inspect<boolean>(ChatConfiguration.GlobalAutoApprove).policyValue === false;
6275
const isAutopilotEnabled = () => configurationService.getValue<boolean>(ChatConfiguration.AutopilotEnabled) !== false;
@@ -98,7 +111,7 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
98111
: localize('permissions.autoApprove.description', "Auto-approve all tool calls and retry on errors"),
99112
},
100113
run: async () => {
101-
if (!hasShownElevatedWarning(ChatPermissionLevel.AutoApprove)) {
114+
if (!hasShownElevatedWarning(ChatPermissionLevel.AutoApprove, storageService)) {
102115
const result = await this.dialogService.prompt({
103116
type: Severity.Warning,
104117
message: localize('permissions.autoApprove.warning.title', "Enable Bypass Approvals?"),
@@ -112,6 +125,10 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
112125
run: () => false
113126
},
114127
],
128+
checkbox: {
129+
label: localize('permissions.warning.dontShowAgain', "Don't show again"),
130+
checked: false,
131+
},
115132
custom: {
116133
icon: Codicon.warning,
117134
markdownDetails: [{
@@ -122,6 +139,9 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
122139
if (result.result !== true) {
123140
return;
124141
}
142+
if (result.checkboxChecked) {
143+
storageService.store(AUTO_APPROVE_DONT_SHOW_AGAIN_KEY, true, StorageScope.PROFILE, StorageTarget.USER);
144+
}
125145
shownWarnings.add(ChatPermissionLevel.AutoApprove);
126146
}
127147
delegate.setPermissionLevel(ChatPermissionLevel.AutoApprove);
@@ -147,7 +167,7 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
147167
: localize('permissions.autopilot.description', "Auto-approve all tool calls and continue until the task is done"),
148168
},
149169
run: async () => {
150-
if (!hasShownElevatedWarning(ChatPermissionLevel.Autopilot)) {
170+
if (!hasShownElevatedWarning(ChatPermissionLevel.Autopilot, storageService)) {
151171
const result = await this.dialogService.prompt({
152172
type: Severity.Warning,
153173
message: localize('permissions.autopilot.warning.title', "Enable Autopilot?"),
@@ -161,6 +181,10 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
161181
run: () => false
162182
},
163183
],
184+
checkbox: {
185+
label: localize('permissions.warning.dontShowAgain', "Don't show again"),
186+
checked: false,
187+
},
164188
custom: {
165189
icon: Codicon.rocket,
166190
markdownDetails: [{
@@ -171,6 +195,9 @@ export class PermissionPickerActionItem extends ChatInputPickerActionViewItem {
171195
if (result.result !== true) {
172196
return;
173197
}
198+
if (result.checkboxChecked) {
199+
storageService.store(AUTOPILOT_DONT_SHOW_AGAIN_KEY, true, StorageScope.PROFILE, StorageTarget.USER);
200+
}
174201
shownWarnings.add(ChatPermissionLevel.Autopilot);
175202
}
176203
delegate.setPermissionLevel(ChatPermissionLevel.Autopilot);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
// Storage keys for persisting the user's choice to skip the warning dialog
7+
// across sessions when "Don't show again" is checked.
8+
export const AUTOPILOT_DONT_SHOW_AGAIN_KEY = 'chat.permissions.autopilot.dontShowWarningAgain';
9+
export const AUTO_APPROVE_DONT_SHOW_AGAIN_KEY = 'chat.permissions.autoApprove.dontShowWarningAgain';

0 commit comments

Comments
 (0)