Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/browser/chatContentParts/chatElicitationContentPart.ts
3296 views
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
import { Emitter } from '../../../../../base/common/event.js';
7
import { IMarkdownString, isMarkdownString, MarkdownString } from '../../../../../base/common/htmlContent.js';
8
import { Disposable, IDisposable } from '../../../../../base/common/lifecycle.js';
9
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
10
import { IChatProgressRenderableResponseContent } from '../../common/chatModel.js';
11
import { IChatElicitationRequest } from '../../common/chatService.js';
12
import { IChatAccessibilityService } from '../chat.js';
13
import { ChatConfirmationWidget } from './chatConfirmationWidget.js';
14
import { IChatContentPart, IChatContentPartRenderContext } from './chatContentParts.js';
15
import { IAction } from '../../../../../base/common/actions.js';
16
17
export class ChatElicitationContentPart extends Disposable implements IChatContentPart {
18
public readonly domNode: HTMLElement;
19
20
private readonly _onDidChangeHeight = this._register(new Emitter<void>());
21
public readonly onDidChangeHeight = this._onDidChangeHeight.event;
22
23
constructor(
24
elicitation: IChatElicitationRequest,
25
context: IChatContentPartRenderContext,
26
@IInstantiationService private readonly instantiationService: IInstantiationService,
27
@IChatAccessibilityService private readonly chatAccessibilityService: IChatAccessibilityService
28
) {
29
super();
30
31
const buttons = [
32
{
33
label: elicitation.acceptButtonLabel,
34
data: true,
35
moreActions: elicitation.moreActions?.map((action: IAction) => ({
36
label: action.label,
37
data: action,
38
run: action.run
39
}))
40
},
41
{ label: elicitation.rejectButtonLabel, data: false, isSecondary: true },
42
];
43
const confirmationWidget = this._register(this.instantiationService.createInstance(ChatConfirmationWidget, context.container, {
44
title: elicitation.title,
45
subtitle: elicitation.subtitle,
46
buttons,
47
message: this.getMessageToRender(elicitation),
48
toolbarData: { partType: 'elicitation', partSource: elicitation.source?.type, arg: elicitation }
49
}));
50
confirmationWidget.setShowButtons(elicitation.state === 'pending');
51
52
if (elicitation.onDidRequestHide) {
53
this._register(elicitation.onDidRequestHide(() => this.domNode.remove()));
54
}
55
56
this._register(confirmationWidget.onDidChangeHeight(() => this._onDidChangeHeight.fire()));
57
58
this._register(confirmationWidget.onDidClick(async e => {
59
let result: boolean | IAction | undefined;
60
if (typeof e.data === 'boolean' && e.data === true) {
61
result = e.data;
62
} else if (e.data && typeof e.data === 'object' && 'run' in e.data && 'label' in e.data) {
63
result = e.data as IAction;
64
} else {
65
result = undefined;
66
}
67
if (result !== undefined) {
68
await elicitation.accept(result);
69
} else {
70
await elicitation.reject();
71
}
72
73
confirmationWidget.setShowButtons(false);
74
confirmationWidget.updateMessage(this.getMessageToRender(elicitation));
75
76
this._onDidChangeHeight.fire();
77
}));
78
79
this.chatAccessibilityService.acceptElicitation(elicitation);
80
this.domNode = confirmationWidget.domNode;
81
this.domNode.tabIndex = 0;
82
const messageToRender = this.getMessageToRender(elicitation);
83
this.domNode.ariaLabel = elicitation.title + ' ' + (typeof messageToRender === 'string' ? messageToRender : messageToRender.value || '');
84
}
85
86
private getMessageToRender(elicitation: IChatElicitationRequest): IMarkdownString | string {
87
if (!elicitation.acceptedResult) {
88
return elicitation.message;
89
}
90
91
const messageMd = isMarkdownString(elicitation.message) ? MarkdownString.lift(elicitation.message) : new MarkdownString(elicitation.message);
92
messageMd.appendCodeblock('json', JSON.stringify(elicitation.acceptedResult, null, 2));
93
return messageMd;
94
}
95
96
hasSameContent(other: IChatProgressRenderableResponseContent): boolean {
97
// No other change allowed for this content type
98
return other.kind === 'elicitation';
99
}
100
101
addDisposable(disposable: IDisposable): void {
102
this._register(disposable);
103
}
104
}
105
106