diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 2b49b0f59d6..a1591ae8ad3 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1706,6 +1706,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I ChatResponseAnchorPart: extHostTypes.ChatResponseAnchorPart, ChatResponseProgressPart: extHostTypes.ChatResponseProgressPart, ChatResponseReferencePart: extHostTypes.ChatResponseReferencePart, + ChatResponseWarningPart: extHostTypes.ChatResponseWarningPart, ChatResponseTextEditPart: extHostTypes.ChatResponseTextEditPart, ChatResponseMarkdownWithVulnerabilitiesPart: extHostTypes.ChatResponseMarkdownWithVulnerabilitiesPart, ChatResponseCommandButtonPart: extHostTypes.ChatResponseCommandButtonPart, diff --git a/src/vs/workbench/api/common/extHostChatAgents2.ts b/src/vs/workbench/api/common/extHostChatAgents2.ts index 82a25240fe4..165da541365 100644 --- a/src/vs/workbench/api/common/extHostChatAgents2.ts +++ b/src/vs/workbench/api/common/extHostChatAgents2.ts @@ -123,6 +123,13 @@ class ChatAgentResponseStream { _report(dto); return this; }, + warning(value) { + throwIfDone(this.progress); + const part = new extHostTypes.ChatResponseWarningPart(value); + const dto = typeConvert.ChatResponseWarningPart.from(part); + _report(dto); + return this; + }, reference(value, iconPath) { throwIfDone(this.reference); diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index bb32ca47812..70e3a4c5167 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -39,7 +39,7 @@ import { DEFAULT_EDITOR_ASSOCIATION, SaveReason } from 'vs/workbench/common/edit import { IViewBadge } from 'vs/workbench/common/views'; import { ChatAgentLocation, IChatAgentRequest, IChatAgentResult } from 'vs/workbench/contrib/chat/common/chatAgents'; import { IChatRequestVariableEntry } from 'vs/workbench/contrib/chat/common/chatModel'; -import { IChatAgentDetection, IChatAgentMarkdownContentWithVulnerability, IChatCommandButton, IChatContentInlineReference, IChatContentReference, IChatFollowup, IChatMarkdownContent, IChatProgressMessage, IChatTextEdit, IChatTreeData, IChatUserActionEvent } from 'vs/workbench/contrib/chat/common/chatService'; +import { IChatAgentDetection, IChatAgentMarkdownContentWithVulnerability, IChatCommandButton, IChatContentInlineReference, IChatContentReference, IChatFollowup, IChatMarkdownContent, IChatProgressMessage, IChatTextEdit, IChatTreeData, IChatUserActionEvent, IChatWarningMessage } from 'vs/workbench/contrib/chat/common/chatService'; import { IChatRequestVariableValue } from 'vs/workbench/contrib/chat/common/chatVariables'; import * as chatProvider from 'vs/workbench/contrib/chat/common/languageModels'; import { DebugTreeItemCollapsibleState, IDebugVisualizationTreeItem } from 'vs/workbench/contrib/debug/common/debug'; @@ -2463,6 +2463,18 @@ export namespace ChatResponseProgressPart { } } +export namespace ChatResponseWarningPart { + export function from(part: vscode.ChatResponseWarningPart): Dto { + return { + kind: 'warning', + content: MarkdownString.from(part.value) + }; + } + export function to(part: Dto): vscode.ChatResponseWarningPart { + return new types.ChatResponseWarningPart(part.content.value); + } +} + export namespace ChatResponseCommandButtonPart { export function from(part: vscode.ChatResponseCommandButtonPart, commandsConverter: CommandsConverter, commandDisposables: DisposableStore): Dto { // If the command isn't in the converter, then this session may have been restored, and the command args don't exist anymore diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 362ae439933..1175df5453c 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -4362,6 +4362,17 @@ export class ChatResponseProgressPart { } } +export class ChatResponseWarningPart { + value: vscode.MarkdownString; + constructor(value: string | vscode.MarkdownString) { + if (typeof value !== 'string' && value.isTrusted === true) { + throw new Error('The boolean form of MarkdownString.isTrusted is NOT supported for chat participants.'); + } + + this.value = typeof value === 'string' ? new MarkdownString(value) : value; + } +} + export class ChatResponseCommandButtonPart { value: vscode.Command; constructor(value: vscode.Command) { diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index ed6193be46a..0c1a447222a 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -67,7 +67,7 @@ import { ChatAgentLocation, IChatAgentMetadata, IChatAgentNameService } from 'vs import { CONTEXT_CHAT_RESPONSE_SUPPORT_ISSUE_REPORTING, CONTEXT_REQUEST, CONTEXT_RESPONSE, CONTEXT_RESPONSE_DETECTED_AGENT_COMMAND, CONTEXT_RESPONSE_FILTERED, CONTEXT_RESPONSE_VOTE } from 'vs/workbench/contrib/chat/common/chatContextKeys'; import { IChatProgressRenderableResponseContent, IChatTextEditGroup } from 'vs/workbench/contrib/chat/common/chatModel'; import { chatAgentLeader, chatSubcommandLeader } from 'vs/workbench/contrib/chat/common/chatParserTypes'; -import { IChatCommandButton, IChatContentReference, IChatFollowup, IChatProgressMessage, IChatResponseProgressFileTreeData, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService'; +import { IChatCommandButton, IChatContentReference, IChatFollowup, IChatProgressMessage, IChatResponseProgressFileTreeData, IChatWarningMessage, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService'; import { IChatVariablesService } from 'vs/workbench/contrib/chat/common/chatVariables'; import { IChatProgressMessageRenderData, IChatRenderData, IChatResponseMarkdownRenderData, IChatResponseViewModel, IChatWelcomeMessageViewModel, isRequestVM, isResponseVM, isWelcomeVM } from 'vs/workbench/contrib/chat/common/chatViewModel'; import { IWordCountResult, getNWords } from 'vs/workbench/contrib/chat/common/chatWordCounter'; @@ -511,7 +511,9 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer; @@ -229,6 +230,8 @@ export class Response implements IResponse { return ''; } else if (part.kind === 'progressMessage') { return ''; + } else if (part.kind === 'warning') { + return ''; } else { return part.content.value; } @@ -762,7 +765,7 @@ export class ChatModel extends Disposable implements IChatModel { throw new Error('acceptResponseProgress: Adding progress to a completed response'); } - if (progress.kind === 'markdownContent' || progress.kind === 'treeData' || progress.kind === 'inlineReference' || progress.kind === 'markdownVuln' || progress.kind === 'progressMessage' || progress.kind === 'command' || progress.kind === 'textEdit') { + if (progress.kind === 'markdownContent' || progress.kind === 'treeData' || progress.kind === 'inlineReference' || progress.kind === 'markdownVuln' || progress.kind === 'progressMessage' || progress.kind === 'command' || progress.kind === 'textEdit' || progress.kind === 'warning') { request.response.updateContent(progress, quiet); } else if (progress.kind === 'usedContext' || progress.kind === 'reference') { request.response.applyReference(progress); diff --git a/src/vs/workbench/contrib/chat/common/chatService.ts b/src/vs/workbench/contrib/chat/common/chatService.ts index 45b36d23700..1ea2e62094b 100644 --- a/src/vs/workbench/contrib/chat/common/chatService.ts +++ b/src/vs/workbench/contrib/chat/common/chatService.ts @@ -106,6 +106,11 @@ export interface IChatProgressMessage { kind: 'progressMessage'; } +export interface IChatWarningMessage { + content: IMarkdownString; + kind: 'warning'; +} + export interface IChatAgentVulnerabilityDetails { title: string; description: string; @@ -138,6 +143,7 @@ export type IChatProgress = | IChatAgentDetection | IChatProgressMessage | IChatCommandButton + | IChatWarningMessage | IChatTextEdit; export interface IChatFollowup { diff --git a/src/vscode-dts/vscode.proposed.chatParticipant.d.ts b/src/vscode-dts/vscode.proposed.chatParticipant.d.ts index be004ff4a91..6f7c51fef2a 100644 --- a/src/vscode-dts/vscode.proposed.chatParticipant.d.ts +++ b/src/vscode-dts/vscode.proposed.chatParticipant.d.ts @@ -351,6 +351,15 @@ declare module 'vscode' { */ reference(value: Uri | Location | { variableName: string; value?: Uri | Location }, iconPath?: ThemeIcon): ChatResponseStream; + /** + * Push a warning to this stream. Short-hand for + * `push(new ChatResponseWarningPart(message))`. + * + * @param message A warning message + * @returns This stream. + */ + warning(message: string | MarkdownString): ChatResponseStream; + /** * Pushes a part to this stream. * @@ -401,11 +410,16 @@ declare module 'vscode' { constructor(value: Command); } + export class ChatResponseWarningPart { + value: MarkdownString; + constructor(value: string | MarkdownString); + } + /** * Represents the different chat response types. */ export type ChatResponsePart = ChatResponseMarkdownPart | ChatResponseFileTreePart | ChatResponseAnchorPart - | ChatResponseProgressPart | ChatResponseReferencePart | ChatResponseCommandButtonPart; + | ChatResponseProgressPart | ChatResponseReferencePart | ChatResponseCommandButtonPart | ChatResponseWarningPart; export namespace chat {