diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 73f08242a76..4e8dab3e724 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1694,7 +1694,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I ChatResponseProgressPart: extHostTypes.ChatResponseProgressPart, ChatResponseReferencePart: extHostTypes.ChatResponseReferencePart, ChatResponseTextEditPart: extHostTypes.ChatResponseTextEditPart, + ChatResponseMarkdownWithVulnerabilitiesPart: extHostTypes.ChatResponseMarkdownWithVulnerabilitiesPart, ChatResponseCommandButtonPart: extHostTypes.ChatResponseCommandButtonPart, + ChatResponseDetectedParticipantPart: extHostTypes.ChatResponseDetectedParticipantPart, ChatRequestTurn: extHostTypes.ChatRequestTurn, ChatResponseTurn: extHostTypes.ChatResponseTurn, ChatLocation: extHostTypes.ChatLocation, diff --git a/src/vs/workbench/api/common/extHostChatAgents2.ts b/src/vs/workbench/api/common/extHostChatAgents2.ts index ad88ee8f96f..09496a9a738 100644 --- a/src/vs/workbench/api/common/extHostChatAgents2.ts +++ b/src/vs/workbench/api/common/extHostChatAgents2.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Location } from 'vs/editor/common/languages'; import { coalesce } from 'vs/base/common/arrays'; import { raceCancellation } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; @@ -15,6 +14,7 @@ import { DisposableMap, DisposableStore } from 'vs/base/common/lifecycle'; import { StopWatch } from 'vs/base/common/stopwatch'; import { assertType } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; +import { Location } from 'vs/editor/common/languages'; import { localize } from 'vs/nls'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { ILogService } from 'vs/platform/log/common/log'; @@ -33,13 +33,12 @@ class ChatAgentResponseStream { private _stopWatch = StopWatch.create(false); private _isClosed: boolean = false; private _firstProgress: number | undefined; - private _apiObject: vscode.ChatExtendedResponseStream | undefined; + private _apiObject: vscode.ChatResponseStream | undefined; constructor( private readonly _extension: IExtensionDescription, private readonly _request: IChatAgentRequest, private readonly _proxy: MainThreadChatAgentsShape2, - private readonly _logService: ILogService, private readonly _commandsConverter: CommandsConverter, private readonly _sessionDisposables: DisposableStore ) { } @@ -86,6 +85,17 @@ class ChatAgentResponseStream { _report(dto); return this; }, + markdownWithVulnerabilities(value, vulnerabilities) { + throwIfDone(this.markdown); + if (vulnerabilities) { + checkProposedApiEnabled(that._extension, 'chatParticipantAdditions'); + } + + const part = new extHostTypes.ChatResponseMarkdownWithVulnerabilitiesPart(value, vulnerabilities); + const dto = typeConvert.ChatResponseMarkdownWithVulnerabilitiesPart.from(part); + _report(dto); + return this; + }, filetree(value, baseUri) { throwIfDone(this.filetree); const part = new extHostTypes.ChatResponseFileTreePart(value, baseUri); @@ -156,10 +166,19 @@ class ChatAgentResponseStream { _report(dto); return this; }, + detectedParticipant(participant, command) { + throwIfDone(this.detectedParticipant); + checkProposedApiEnabled(that._extension, 'chatParticipantAdditions'); + + const part = new extHostTypes.ChatResponseDetectedParticipantPart(participant, command); + const dto = typeConvert.ChatResponseDetectedParticipantPart.from(part); + _report(dto); + return this; + }, push(part) { throwIfDone(this.push); - if (part instanceof extHostTypes.ChatResponseTextEditPart) { + if (part instanceof extHostTypes.ChatResponseTextEditPart || part instanceof extHostTypes.ChatResponseMarkdownWithVulnerabilitiesPart || part instanceof extHostTypes.ChatResponseDetectedParticipantPart) { checkProposedApiEnabled(that._extension, 'chatParticipantAdditions'); } @@ -173,22 +192,6 @@ class ChatAgentResponseStream { return this; }, - report(progress) { - throwIfDone(this.report); - if ('placeholder' in progress && 'resolvedContent' in progress) { - // Ignore for now, this is the deleted Task type - return; - } - - const value = typeConvert.ChatResponseProgress.from(that._extension, progress); - if (!value) { - that._logService.error('Unknown progress type: ' + JSON.stringify(progress)); - return; - } - - _report(value); - return this; - } }; } @@ -248,7 +251,7 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 { this._sessionDisposables.set(request.sessionId, sessionDisposables); } - const stream = new ChatAgentResponseStream(agent.extension, request, this._proxy, this._logService, this.commands.converter, sessionDisposables); + const stream = new ChatAgentResponseStream(agent.extension, request, this._proxy, this.commands.converter, sessionDisposables); try { const convertedHistory = await this.prepareHistoryTurns(request.agentId, context); const task = agent.invoke( @@ -662,7 +665,7 @@ class ExtHostChatAgent { } satisfies vscode.ChatParticipant; } - invoke(request: vscode.ChatRequest, context: vscode.ChatContext, response: vscode.ChatExtendedResponseStream, token: CancellationToken): vscode.ProviderResult { + invoke(request: vscode.ChatRequest, context: vscode.ChatContext, response: vscode.ChatResponseStream, token: CancellationToken): vscode.ProviderResult { return this._requestHandler(request, context, response, token); } } diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index c10fd138685..53d48952916 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 { 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 } 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'; @@ -51,7 +51,6 @@ import { TestId } from 'vs/workbench/contrib/testing/common/testId'; import { CoverageDetails, DetailType, ICoverageCount, IFileCoverage, ISerializedTestResults, ITestErrorMessage, ITestItem, ITestTag, TestMessageType, TestResultItem, denamespaceTestTag, namespaceTestTag } from 'vs/workbench/contrib/testing/common/testTypes'; import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn'; import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; -import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; import { Dto } from 'vs/workbench/services/extensions/common/proxyIdentifier'; import type * as vscode from 'vscode'; import * as types from './extHostTypes'; @@ -2361,6 +2360,32 @@ export namespace ChatResponseMarkdownPart { } } +export namespace ChatResponseMarkdownWithVulnerabilitiesPart { + export function from(part: vscode.ChatResponseMarkdownWithVulnerabilitiesPart): Dto { + return { + kind: 'markdownVuln', + content: MarkdownString.from(part.value), + vulnerabilities: part.vulnerabilities, + }; + } + export function to(part: Dto): vscode.ChatResponseMarkdownWithVulnerabilitiesPart { + return new types.ChatResponseMarkdownWithVulnerabilitiesPart(MarkdownString.to(part.content), part.vulnerabilities); + } +} + +export namespace ChatResponseDetectedParticipantPart { + export function from(part: vscode.ChatResponseDetectedParticipantPart): Dto { + return { + kind: 'agentDetection', + agentId: part.participant, + command: part.command, + }; + } + export function to(part: Dto): vscode.ChatResponseDetectedParticipantPart { + return new types.ChatResponseDetectedParticipantPart(part.agentId, part.command); + } +} + export namespace ChatResponseFilesPart { export function from(part: vscode.ChatResponseFileTreePart): IChatTreeData { const { value, baseUri } = part; @@ -2499,7 +2524,7 @@ export namespace ChatResponseReferencePart { export namespace ChatResponsePart { - export function from(part: vscode.ChatResponsePart | vscode.ChatResponseTextEditPart, commandsConverter: CommandsConverter, commandDisposables: DisposableStore): extHostProtocol.IChatProgressDto { + export function from(part: vscode.ChatResponsePart | vscode.ChatResponseTextEditPart | vscode.ChatResponseMarkdownWithVulnerabilitiesPart | vscode.ChatResponseDetectedParticipantPart, commandsConverter: CommandsConverter, commandDisposables: DisposableStore): extHostProtocol.IChatProgressDto { if (part instanceof types.ChatResponseMarkdownPart) { return ChatResponseMarkdownPart.from(part); } else if (part instanceof types.ChatResponseAnchorPart) { @@ -2514,12 +2539,16 @@ export namespace ChatResponsePart { return ChatResponseCommandButtonPart.from(part, commandsConverter, commandDisposables); } else if (part instanceof types.ChatResponseTextEditPart) { return ChatResponseTextEditPart.from(part); + } else if (part instanceof types.ChatResponseMarkdownWithVulnerabilitiesPart) { + return ChatResponseMarkdownWithVulnerabilitiesPart.from(part); + } else if (part instanceof types.ChatResponseDetectedParticipantPart) { + return ChatResponseDetectedParticipantPart.from(part); } - return { - kind: 'content', - content: '' - }; + return { + kind: 'markdownContent', + content: MarkdownString.from('') + }; } export function to(part: extHostProtocol.IChatProgressDto, commandsConverter: CommandsConverter): vscode.ChatResponsePart | undefined { @@ -2548,86 +2577,6 @@ export namespace ChatResponsePart { } } -export namespace ChatResponseProgress { - export function from(extension: IExtensionDescription, progress: vscode.ChatExtendedProgress): extHostProtocol.IChatProgressDto | undefined { - if ('markdownContent' in progress) { - checkProposedApiEnabled(extension, 'chatParticipantAdditions'); - return { content: MarkdownString.from(progress.markdownContent), kind: 'markdownContent' }; - } else if ('content' in progress) { - if ('vulnerabilities' in progress && progress.vulnerabilities) { - checkProposedApiEnabled(extension, 'chatParticipantAdditions'); - return { content: progress.content, vulnerabilities: progress.vulnerabilities, kind: 'vulnerability' }; - } - - if (typeof progress.content === 'string') { - return { content: progress.content, kind: 'content' }; - } - - checkProposedApiEnabled(extension, 'chatParticipantAdditions'); - return { content: MarkdownString.from(progress.content), kind: 'markdownContent' }; - } else if ('documents' in progress) { - return { - documents: progress.documents.map(d => ({ - uri: d.uri, - version: d.version, - ranges: d.ranges.map(r => Range.from(r)) - })), - kind: 'usedContext' - }; - } else if ('reference' in progress) { - return { - reference: 'uri' in progress.reference ? - { - uri: progress.reference.uri, - range: Range.from(progress.reference.range) - } : progress.reference, - kind: 'reference' - }; - } else if ('inlineReference' in progress) { - return { - inlineReference: 'uri' in progress.inlineReference ? - { - uri: progress.inlineReference.uri, - range: Range.from(progress.inlineReference.range) - } : progress.inlineReference, - name: progress.title, - kind: 'inlineReference' - }; - } else if ('participant' in progress) { - checkProposedApiEnabled(extension, 'chatParticipantAdditions'); - return { agentId: progress.participant, command: progress.command, kind: 'agentDetection' }; - } else if ('message' in progress) { - return { content: MarkdownString.from(progress.message), kind: 'progressMessage' }; - } else { - return undefined; - } - } - - export function toProgressContent(progress: extHostProtocol.IChatContentProgressDto, commandsConverter: Command.ICommandsConverter): vscode.ChatContentProgress | undefined { - switch (progress.kind) { - case 'markdownContent': - // For simplicity, don't sent back the 'extended' types, so downgrade markdown to just some text - return { content: progress.content.value }; - case 'inlineReference': - return { - inlineReference: - isUriComponents(progress.inlineReference) ? - URI.revive(progress.inlineReference) : - Location.to(progress.inlineReference), - title: progress.name - }; - case 'command': - // If the command isn't in the converter, then this session may have been restored, and the command args don't exist anymore - return { - command: commandsConverter.fromInternal(progress.command) ?? { command: progress.command.id, title: progress.command.title }, - }; - default: - // Unknown type, eg something in history that was removed? Ignore - return undefined; - } - } -} - export namespace ChatAgentRequest { export function to(request: IChatAgentRequest): vscode.ChatRequest { return { @@ -2692,7 +2641,11 @@ export namespace ChatAgentUserActionEvent { const ehResult = ChatAgentResult.to(result); if (event.action.kind === 'command') { - const commandAction: vscode.ChatCommandAction = { kind: 'command', commandButton: ChatResponseProgress.toProgressContent(event.action.commandButton, commandsConverter) as vscode.ChatCommandButton }; + const command = event.action.commandButton.command; + const commandButton = { + command: commandsConverter.fromInternal(command) ?? { command: command.id, title: command.title }, + }; + const commandAction: vscode.ChatCommandAction = { kind: 'command', commandButton }; return { action: commandAction, result: ehResult }; } else if (event.action.kind === 'followUp') { const followupAction: vscode.ChatFollowupAction = { kind: 'followUp', followup: ChatFollowup.to(event.action.followup) }; diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index d82ecb98502..dd2b2076b22 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -4276,6 +4276,29 @@ export class ChatResponseMarkdownPart { } } +/** + * TODO if 'vulnerabilities' is finalized, this should be merged with the base ChatResponseMarkdownPart. I just don't see how to do that while keeping + * vulnerabilities in a seperate API proposal in a clean way. + */ +export class ChatResponseMarkdownWithVulnerabilitiesPart { + value: vscode.MarkdownString; + vulnerabilities: vscode.ChatVulnerability[]; + constructor(value: string | vscode.MarkdownString, vulnerabilities: vscode.ChatVulnerability[]) { + this.value = typeof value === 'string' ? new MarkdownString(value) : value; + this.vulnerabilities = vulnerabilities; + } +} + +export class ChatResponseDetectedParticipantPart { + participant: string; + // TODO@API validate this against statically-declared slash commands? + command?: vscode.ChatCommand; + constructor(participant: string, command?: vscode.ChatCommand) { + this.participant = participant; + this.command = command; + } +} + export class ChatResponseFileTreePart { value: vscode.ChatResponseFileTree[]; baseUri: vscode.Uri; diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index 02cc120a46a..211e74c208c 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -257,9 +257,9 @@ class ChatSlashStaticSlashCommandsContribution extends Disposable { if (isMarkdownString(defaultAgent.metadata.helpTextPrefix)) { progress.report({ content: defaultAgent.metadata.helpTextPrefix, kind: 'markdownContent' }); } else { - progress.report({ content: defaultAgent.metadata.helpTextPrefix, kind: 'content' }); + progress.report({ content: new MarkdownString(defaultAgent.metadata.helpTextPrefix), kind: 'markdownContent' }); } - progress.report({ content: '\n\n', kind: 'content' }); + progress.report({ content: new MarkdownString('\n\n'), kind: 'markdownContent' }); } // Report agent list @@ -282,11 +282,11 @@ class ChatSlashStaticSlashCommandsContribution extends Disposable { // Report variables if (defaultAgent?.metadata.helpTextVariablesPrefix) { - progress.report({ content: '\n\n', kind: 'content' }); + progress.report({ content: new MarkdownString('\n\n'), kind: 'markdownContent' }); if (isMarkdownString(defaultAgent.metadata.helpTextVariablesPrefix)) { progress.report({ content: defaultAgent.metadata.helpTextVariablesPrefix, kind: 'markdownContent' }); } else { - progress.report({ content: defaultAgent.metadata.helpTextVariablesPrefix, kind: 'content' }); + progress.report({ content: new MarkdownString(defaultAgent.metadata.helpTextVariablesPrefix), kind: 'markdownContent' }); } const variables = [ @@ -296,16 +296,16 @@ class ChatSlashStaticSlashCommandsContribution extends Disposable { const variableText = variables .map(v => `* \`${chatVariableLeader}${v.name}\` - ${v.description}`) .join('\n'); - progress.report({ content: '\n' + variableText, kind: 'content' }); + progress.report({ content: new MarkdownString('\n' + variableText), kind: 'markdownContent' }); } // Report help text ending if (defaultAgent?.metadata.helpTextPostfix) { - progress.report({ content: '\n\n', kind: 'content' }); + progress.report({ content: new MarkdownString('\n\n'), kind: 'markdownContent' }); if (isMarkdownString(defaultAgent.metadata.helpTextPostfix)) { progress.report({ content: defaultAgent.metadata.helpTextPostfix, kind: 'markdownContent' }); } else { - progress.report({ content: defaultAgent.metadata.helpTextPostfix, kind: 'content' }); + progress.report({ content: new MarkdownString(defaultAgent.metadata.helpTextPostfix), kind: 'markdownContent' }); } } })); diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index 92b5e688d2f..832c8f0e45b 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -957,7 +957,8 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer('interactiveSessionCommand', { @@ -483,8 +484,8 @@ export class ChatService extends Disposable implements IChatService { gotProgress = true; - if (progress.kind === 'content' || progress.kind === 'markdownContent') { - this.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${typeof progress.content === 'string' ? progress.content.length : progress.content.value.length} chars`); + if (progress.kind === 'markdownContent') { + this.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${progress.content.value.length} chars`); } else { this.trace('sendRequest', `Provider returned progress: ${JSON.stringify(progress)}`); } @@ -639,7 +640,8 @@ export class ChatService extends Disposable implements IChatService { message; const request = model.addRequest(parsedRequest, variableData || { variables: [] }, attempt ?? 0); if (typeof response.message === 'string') { - model.acceptResponseProgress(request, { content: response.message, kind: 'content' }); + // TODO is this possible? + model.acceptResponseProgress(request, { content: new MarkdownString(response.message), kind: 'markdownContent' }); } else { for (const part of response.message) { model.acceptResponseProgress(request, part, true); diff --git a/src/vs/workbench/contrib/chat/test/common/__snapshots__/Response_markdown__markdown.0.snap b/src/vs/workbench/contrib/chat/test/common/__snapshots__/Response_markdown__markdown.0.snap new file mode 100644 index 00000000000..a7cb1f9bd3a --- /dev/null +++ b/src/vs/workbench/contrib/chat/test/common/__snapshots__/Response_markdown__markdown.0.snap @@ -0,0 +1,11 @@ +[ + { + content: { + value: "markdown1markdown2", + isTrusted: { enabledCommands: [ ] }, + supportThemeIcons: false, + supportHtml: false + }, + kind: "markdownContent" + } +] \ No newline at end of file diff --git a/src/vs/workbench/contrib/chat/test/common/chatModel.test.ts b/src/vs/workbench/contrib/chat/test/common/chatModel.test.ts index c43c5dfedad..6edca7ea268 100644 --- a/src/vs/workbench/contrib/chat/test/common/chatModel.test.ts +++ b/src/vs/workbench/contrib/chat/test/common/chatModel.test.ts @@ -126,27 +126,20 @@ suite('ChatModel', () => { suite('Response', () => { ensureNoDisposablesAreLeakedInTestSuite(); - test('content, markdown', async () => { + test('markdown, markdown', async () => { const response = new Response([]); - response.updateContent({ content: 'text', kind: 'content' }); - response.updateContent({ content: new MarkdownString('markdown'), kind: 'markdownContent' }); + response.updateContent({ content: new MarkdownString('markdown1'), kind: 'markdownContent' }); + response.updateContent({ content: new MarkdownString('markdown2'), kind: 'markdownContent' }); await assertSnapshot(response.value); - assert.strictEqual(response.asString(), 'textmarkdown'); - }); - - test('markdown, content', async () => { - const response = new Response([]); - response.updateContent({ content: new MarkdownString('markdown'), kind: 'markdownContent' }); - response.updateContent({ content: 'text', kind: 'content' }); - await assertSnapshot(response.value); + assert.strictEqual(response.asString(), 'markdown1markdown2'); }); test('inline reference', async () => { const response = new Response([]); - response.updateContent({ content: 'text before', kind: 'content' }); + response.updateContent({ content: new MarkdownString('text before'), kind: 'markdownContent' }); response.updateContent({ inlineReference: URI.parse('https://microsoft.com'), kind: 'inlineReference' }); - response.updateContent({ content: 'text after', kind: 'content' }); + response.updateContent({ content: new MarkdownString('text after'), kind: 'markdownContent' }); await assertSnapshot(response.value); }); }); diff --git a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatController.ts b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatController.ts index 155e251dcc8..0b0d3e60208 100644 --- a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatController.ts +++ b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatController.ts @@ -272,9 +272,7 @@ export class TerminalChatController extends Disposable implements ITerminalContr return; } - if (progress.kind === 'content') { - responseContent += progress.content; - } else if (progress.kind === 'markdownContent') { + if (progress.kind === 'markdownContent') { responseContent += progress.content.value; } if (this._currentRequest) { diff --git a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts index eba515e2998..4b5b0f2c133 100644 --- a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts @@ -179,7 +179,7 @@ export class TerminalChatWidget extends Disposable { } updateProgress(progress?: IChatProgress): void { - this._inlineChatWidget.updateProgress(progress?.kind === 'content' || progress?.kind === 'markdownContent'); + this._inlineChatWidget.updateProgress(progress?.kind === 'markdownContent'); } public get focusTracker(): IFocusTracker { return this._focusTracker; diff --git a/src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts b/src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts index b877acbc72e..c41cc244101 100644 --- a/src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts @@ -56,11 +56,6 @@ declare module 'vscode' { responseIsRedacted?: boolean; } - /** @deprecated */ - export interface ChatMarkdownContent { - markdownContent: MarkdownString; - } - /** * Now only used for the "intent detection" API below */ @@ -69,46 +64,25 @@ declare module 'vscode' { readonly description: string; } - // TODO@API fit this into the stream - export interface ChatDetectedParticipant { + export class ChatResponseDetectedParticipantPart { participant: string; // TODO@API validate this against statically-declared slash commands? command?: ChatCommand; + constructor(participant: string, command?: ChatCommand); } - // TODO@API fit this into the stream export interface ChatVulnerability { title: string; description: string; // id: string; // Later we will need to be able to link these across multiple content chunks. } - // TODO@API fit this into the stream - export interface ChatContent { - vulnerabilities?: ChatVulnerability[]; + export class ChatResponseMarkdownWithVulnerabilitiesPart { + value: MarkdownString; + vulnerabilities: ChatVulnerability[]; + constructor(value: string | MarkdownString, vulnerabilities: ChatVulnerability[]); } - /** - * @deprecated use ChatResponseStream instead - */ - export type ChatContentProgress = - | ChatContent - | ChatInlineContentReference - | ChatCommandButton; - - /** - * @deprecated use ChatResponseStream instead - */ - export type ChatMetadataProgress = - | ChatUsedContext - | ChatContentReference - | ChatProgressMessage; - - /** - * @deprecated use ChatResponseStream instead - */ - export type ChatProgress = ChatContentProgress | ChatMetadataProgress; - /** @deprecated */ export interface ChatProgressMessage { message: string; @@ -123,21 +97,6 @@ declare module 'vscode' { reference: Uri | Location; } - /** - * A reference to a piece of content that will be rendered inline with the markdown content. - */ - export interface ChatInlineContentReference { - /** - * The resource being referenced. - */ - inlineReference: Uri | Location; - - /** - * An alternate title for the resource. - */ - title?: string; - } - /** * Displays a {@link Command command} as a button in the chat response. */ @@ -145,16 +104,6 @@ declare module 'vscode' { command: Command; } - /** - * A piece of the chat response's content. Will be merged with other progress pieces as needed, and rendered as markdown. - */ - export interface ChatContent { - /** - * The content as a string of markdown source. - */ - content: string; - } - export interface ChatDocumentContext { uri: Uri; version: number; @@ -169,8 +118,9 @@ declare module 'vscode' { export interface ChatResponseStream { textEdit(target: Uri, edits: TextEdit | TextEdit[]): ChatResponseStream; - - push(part: ChatResponsePart | ChatResponseTextEditPart): ChatResponseStream; + markdownWithVulnerabilities(value: string | MarkdownString, vulnerabilities: ChatVulnerability[]): ChatResponseStream; + detectedParticipant(participant: string, command?: ChatCommand): ChatResponseStream; + push(part: ChatResponsePart | ChatResponseTextEditPart | ChatResponseDetectedParticipantPart): ChatResponseStream; } // TODO@API fit this into the stream @@ -178,25 +128,6 @@ declare module 'vscode' { documents: ChatDocumentContext[]; } - export interface ChatResponseStream { - /** - * @deprecated use above methods instread - */ - report(value: ChatProgress): void; - } - - /** @deprecated */ - export type ChatExtendedProgress = ChatProgress - | ChatMarkdownContent - | ChatDetectedParticipant; - - export type ChatExtendedResponseStream = ChatResponseStream & { - /** - * @deprecated - */ - report(value: ChatExtendedProgress): void; - }; - export interface ChatParticipant { /** * Provide a set of variables that can only be used with this participant. @@ -218,7 +149,7 @@ declare module 'vscode' { constructor(label: string | CompletionItemLabel, values: ChatVariableValue[]); } - export type ChatExtendedRequestHandler = (request: ChatRequest, context: ChatContext, response: ChatExtendedResponseStream, token: CancellationToken) => ProviderResult; + export type ChatExtendedRequestHandler = (request: ChatRequest, context: ChatContext, response: ChatResponseStream, token: CancellationToken) => ProviderResult; export namespace chat { /**