Skip to content

Commit 20f0091

Browse files
authored
Don't allow taking action on codeblocks in filtered responses (microsoft#191732)
Fix microsoft/vscode-copilot#1148
1 parent 4b82860 commit 20f0091

File tree

4 files changed

+36
-6
lines changed

4 files changed

+36
-6
lines changed

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ import { ServicesAccessor } from 'vs/editor/browser/editorExtensions';
1111
import { IBulkEditService, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService';
1212
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
1313
import { Range } from 'vs/editor/common/core/range';
14+
import { RelatedContextItem, WorkspaceEdit } from 'vs/editor/common/languages';
1415
import { ILanguageService } from 'vs/editor/common/languages/language';
1516
import { ITextModel } from 'vs/editor/common/model';
17+
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
1618
import { CopyAction } from 'vs/editor/contrib/clipboard/browser/clipboard';
1719
import { localize } from 'vs/nls';
1820
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
@@ -31,8 +33,6 @@ import { CellKind, NOTEBOOK_EDITOR_ID } from 'vs/workbench/contrib/notebook/comm
3133
import { ITerminalEditorService, ITerminalGroupService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
3234
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
3335
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
34-
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
35-
import { WorkspaceEdit, RelatedContextItem } from 'vs/editor/common/languages';
3636

3737
export interface IChatCodeBlockActionContext {
3838
code: string;
@@ -92,6 +92,11 @@ export function registerChatCodeBlockActions() {
9292
return;
9393
}
9494

95+
if (context.element.errorDetails?.responseIsFiltered) {
96+
// When run from command palette
97+
return;
98+
}
99+
95100
const clipboardService = accessor.get(IClipboardService);
96101
clipboardService.writeText(context.code);
97102

@@ -183,6 +188,11 @@ export function registerChatCodeBlockActions() {
183188
const editorService = accessor.get(IEditorService);
184189
const textFileService = accessor.get(ITextFileService);
185190

191+
if (context.element.errorDetails?.responseIsFiltered) {
192+
// When run from command palette
193+
return;
194+
}
195+
186196
if (editorService.activeEditorPane?.getId() === NOTEBOOK_EDITOR_ID) {
187197
return this.handleNotebookEditor(accessor, editorService.activeEditorPane.getControl() as INotebookEditor, context);
188198
}
@@ -312,6 +322,11 @@ export function registerChatCodeBlockActions() {
312322
}
313323

314324
override async runWithContext(accessor: ServicesAccessor, context: IChatCodeBlockActionContext) {
325+
if (context.element.errorDetails?.responseIsFiltered) {
326+
// When run from command palette
327+
return;
328+
}
329+
315330
const editorService = accessor.get(IEditorService);
316331
const chatService = accessor.get(IChatService);
317332
editorService.openEditor(<IUntitledTextResourceEditorInput>{ contents: context.code, languageId: context.languageId, resource: undefined });
@@ -358,6 +373,11 @@ export function registerChatCodeBlockActions() {
358373
}
359374

360375
override async runWithContext(accessor: ServicesAccessor, context: IChatCodeBlockActionContext) {
376+
if (context.element.errorDetails?.responseIsFiltered) {
377+
// When run from command palette
378+
return;
379+
}
380+
361381
const chatService = accessor.get(IChatService);
362382
const terminalService = accessor.get(ITerminalService);
363383
const editorService = accessor.get(IEditorService);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis
1515
import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits';
1616
import { CHAT_CATEGORY } from 'vs/workbench/contrib/chat/browser/actions/chatActions';
1717
import { IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat';
18-
import { CONTEXT_IN_CHAT_INPUT, CONTEXT_IN_CHAT_SESSION, CONTEXT_REQUEST, CONTEXT_RESPONSE, CONTEXT_RESPONSE_VOTE } from 'vs/workbench/contrib/chat/common/chatContextKeys';
18+
import { CONTEXT_IN_CHAT_INPUT, CONTEXT_IN_CHAT_SESSION, CONTEXT_REQUEST, CONTEXT_RESPONSE, CONTEXT_RESPONSE_FILTERED, CONTEXT_RESPONSE_VOTE } from 'vs/workbench/contrib/chat/common/chatContextKeys';
1919
import { IChatService, IChatUserActionEvent, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
2020
import { isRequestVM, isResponseVM } from 'vs/workbench/contrib/chat/common/chatViewModel';
2121
import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
@@ -119,7 +119,7 @@ export function registerChatTitleActions() {
119119
id: MenuId.ChatMessageTitle,
120120
group: 'navigation',
121121
isHiddenByDefault: true,
122-
when: ContextKeyExpr.and(NOTEBOOK_IS_ACTIVE_EDITOR, CONTEXT_RESPONSE)
122+
when: ContextKeyExpr.and(NOTEBOOK_IS_ACTIVE_EDITOR, CONTEXT_RESPONSE, CONTEXT_RESPONSE_FILTERED.negate())
123123
}
124124
});
125125
}

src/vs/workbench/contrib/chat/browser/chatListRenderer.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ import { IChatCodeBlockActionContext } from 'vs/workbench/contrib/chat/browser/a
6161
import { ChatTreeItem, IChatCodeBlockInfo, IChatFileTreeInfo } from 'vs/workbench/contrib/chat/browser/chat';
6262
import { ChatFollowups } from 'vs/workbench/contrib/chat/browser/chatFollowups';
6363
import { ChatEditorOptions } from 'vs/workbench/contrib/chat/browser/chatOptions';
64-
import { CONTEXT_REQUEST, CONTEXT_RESPONSE, CONTEXT_RESPONSE_HAS_PROVIDER_ID, CONTEXT_RESPONSE_VOTE } from 'vs/workbench/contrib/chat/common/chatContextKeys';
64+
import { CONTEXT_REQUEST, CONTEXT_RESPONSE, CONTEXT_RESPONSE_FILTERED, CONTEXT_RESPONSE_HAS_PROVIDER_ID, CONTEXT_RESPONSE_VOTE } from 'vs/workbench/contrib/chat/common/chatContextKeys';
6565
import { IChatReplyFollowup, IChatResponseProgressFileTreeData, IChatService, ISlashCommand, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
6666
import { IChatResponseMarkdownRenderData, IChatResponseRenderData, IChatResponseViewModel, IChatWelcomeMessageViewModel, isRequestVM, isResponseVM, isWelcomeVM } from 'vs/workbench/contrib/chat/common/chatViewModel';
6767
import { IWordCountResult, getNWords } from 'vs/workbench/contrib/chat/common/chatWordCounter';
@@ -268,10 +268,13 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
268268

269269
templateData.titleToolbar.context = element;
270270

271+
const isFiltered = !!(isResponseVM(element) && element.errorDetails?.responseIsFiltered);
272+
CONTEXT_RESPONSE_FILTERED.bindTo(templateData.contextKeyService).set(isFiltered);
273+
271274
templateData.rowContainer.classList.toggle('interactive-request', isRequestVM(element));
272275
templateData.rowContainer.classList.toggle('interactive-response', isResponseVM(element));
273276
templateData.rowContainer.classList.toggle('interactive-welcome', isWelcomeVM(element));
274-
templateData.rowContainer.classList.toggle('filtered-response', !!(isResponseVM(element) && element.errorDetails?.responseIsFiltered));
277+
templateData.rowContainer.classList.toggle('filtered-response', isFiltered);
275278
templateData.username.textContent = element.username;
276279

277280
if (element.avatarIconUri) {
@@ -969,6 +972,12 @@ class CodeBlockPart extends Disposable implements IChatResultCodeBlockPart {
969972
element: data.element,
970973
languageId: vscodeLanguageId
971974
};
975+
976+
if (isResponseVM(data.element) && data.element.errorDetails?.responseIsFiltered) {
977+
dom.hide(this.toolbar.getElement());
978+
} else {
979+
dom.show(this.toolbar.getElement());
980+
}
972981
}
973982

974983
private fixCodeText(text: string, languageId: string): string {

src/vs/workbench/contrib/chat/common/chatContextKeys.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
88

99
export const CONTEXT_RESPONSE_HAS_PROVIDER_ID = new RawContextKey<boolean>('chatSessionResponseHasProviderId', false, { type: 'boolean', description: localize('interactiveSessionResponseHasProviderId', "True when the provider has assigned an id to this response.") });
1010
export const CONTEXT_RESPONSE_VOTE = new RawContextKey<string>('chatSessionResponseVote', '', { type: 'string', description: localize('interactiveSessionResponseVote', "When the response has been voted up, is set to 'up'. When voted down, is set to 'down'. Otherwise an empty string.") });
11+
export const CONTEXT_RESPONSE_FILTERED = new RawContextKey<boolean>('chatSessionResponseFiltered', false, { type: 'boolean', description: localize('chatResponseFiltered', "True when the chat response was filtered out by the server.") });
1112
export const CONTEXT_CHAT_REQUEST_IN_PROGRESS = new RawContextKey<boolean>('chatSessionRequestInProgress', false, { type: 'boolean', description: localize('interactiveSessionRequestInProgress', "True when the current request is still in progress.") });
1213

1314
export const CONTEXT_RESPONSE = new RawContextKey<boolean>('chatResponse', false, { type: 'boolean', description: localize('chatResponse', "The chat item is a response.") });

0 commit comments

Comments
 (0)