Path: blob/main/src/vs/workbench/contrib/chat/browser/chatContentParts/chatElicitationContentPart.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Emitter } from '../../../../../base/common/event.js';6import { IMarkdownString, isMarkdownString, MarkdownString } from '../../../../../base/common/htmlContent.js';7import { Disposable, IDisposable } from '../../../../../base/common/lifecycle.js';8import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';9import { IChatProgressRenderableResponseContent } from '../../common/chatModel.js';10import { IChatElicitationRequest } from '../../common/chatService.js';11import { IChatAccessibilityService } from '../chat.js';12import { ChatConfirmationWidget } from './chatConfirmationWidget.js';13import { IChatContentPart, IChatContentPartRenderContext } from './chatContentParts.js';14import { IAction } from '../../../../../base/common/actions.js';1516export class ChatElicitationContentPart extends Disposable implements IChatContentPart {17public readonly domNode: HTMLElement;1819private readonly _onDidChangeHeight = this._register(new Emitter<void>());20public readonly onDidChangeHeight = this._onDidChangeHeight.event;2122constructor(23elicitation: IChatElicitationRequest,24context: IChatContentPartRenderContext,25@IInstantiationService private readonly instantiationService: IInstantiationService,26@IChatAccessibilityService private readonly chatAccessibilityService: IChatAccessibilityService27) {28super();2930const buttons = [31{32label: elicitation.acceptButtonLabel,33data: true,34moreActions: elicitation.moreActions?.map((action: IAction) => ({35label: action.label,36data: action,37run: action.run38}))39},40{ label: elicitation.rejectButtonLabel, data: false, isSecondary: true },41];42const confirmationWidget = this._register(this.instantiationService.createInstance(ChatConfirmationWidget, context.container, {43title: elicitation.title,44subtitle: elicitation.subtitle,45buttons,46message: this.getMessageToRender(elicitation),47toolbarData: { partType: 'elicitation', partSource: elicitation.source?.type, arg: elicitation }48}));49confirmationWidget.setShowButtons(elicitation.state === 'pending');5051if (elicitation.onDidRequestHide) {52this._register(elicitation.onDidRequestHide(() => this.domNode.remove()));53}5455this._register(confirmationWidget.onDidChangeHeight(() => this._onDidChangeHeight.fire()));5657this._register(confirmationWidget.onDidClick(async e => {58let result: boolean | IAction | undefined;59if (typeof e.data === 'boolean' && e.data === true) {60result = e.data;61} else if (e.data && typeof e.data === 'object' && 'run' in e.data && 'label' in e.data) {62result = e.data as IAction;63} else {64result = undefined;65}66if (result !== undefined) {67await elicitation.accept(result);68} else {69await elicitation.reject();70}7172confirmationWidget.setShowButtons(false);73confirmationWidget.updateMessage(this.getMessageToRender(elicitation));7475this._onDidChangeHeight.fire();76}));7778this.chatAccessibilityService.acceptElicitation(elicitation);79this.domNode = confirmationWidget.domNode;80this.domNode.tabIndex = 0;81const messageToRender = this.getMessageToRender(elicitation);82this.domNode.ariaLabel = elicitation.title + ' ' + (typeof messageToRender === 'string' ? messageToRender : messageToRender.value || '');83}8485private getMessageToRender(elicitation: IChatElicitationRequest): IMarkdownString | string {86if (!elicitation.acceptedResult) {87return elicitation.message;88}8990const messageMd = isMarkdownString(elicitation.message) ? MarkdownString.lift(elicitation.message) : new MarkdownString(elicitation.message);91messageMd.appendCodeblock('json', JSON.stringify(elicitation.acceptedResult, null, 2));92return messageMd;93}9495hasSameContent(other: IChatProgressRenderableResponseContent): boolean {96// No other change allowed for this content type97return other.kind === 'elicitation';98}99100addDisposable(disposable: IDisposable): void {101this._register(disposable);102}103}104105106