Skip to content

Commit cd476de

Browse files
committed
Add simple test impl
1 parent 487f330 commit cd476de

File tree

6 files changed

+105
-2
lines changed

6 files changed

+105
-2
lines changed

extensions/markdown-language-features/package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
"categories": [
1616
"Programming Languages"
1717
],
18+
"enabledApiProposals": [
19+
"chatParticipantAdditions",
20+
"chatParticipantPrivate",
21+
"chatOutputRenderer"
22+
],
1823
"activationEvents": [
1924
"onLanguage:markdown",
2025
"onLanguage:prompt",
@@ -35,6 +40,13 @@
3540
}
3641
},
3742
"contributes": {
43+
"languageModelTools": [
44+
{
45+
"name": "test-renderer",
46+
"displayName": "Test renderer",
47+
"modelDescription": "Renders test data to the output"
48+
}
49+
],
3850
"notebookRenderer": [
3951
{
4052
"id": "vscode.markdown-it-renderer",

extensions/markdown-language-features/src/extension.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export async function activate(context: vscode.ExtensionContext) {
2424
const client = await startServer(context, engine);
2525
context.subscriptions.push(client);
2626
activateShared(context, client, engine, logger, contributions);
27+
28+
registerTestOutputRenderer(context);
2729
}
2830

2931
function startServer(context: vscode.ExtensionContext, parser: IMdParser): Promise<MdLanguageClient> {
@@ -54,3 +56,40 @@ function startServer(context: vscode.ExtensionContext, parser: IMdParser): Promi
5456
return new LanguageClient(id, name, serverOptions, clientOptions);
5557
}, parser);
5658
}
59+
60+
61+
function registerTestOutputRenderer(context: vscode.ExtensionContext) {
62+
vscode.lm.registerTool('test-renderer', {
63+
invoke: (options, token) => {
64+
const result = new vscode.ExtendedLanguageModelToolResult([]);
65+
66+
(result as vscode.ExtendedLanguageModelToolResult2).toolResultDetails2 = {
67+
mime: 'application/vnd.test-output',
68+
value: new Uint8Array(Buffer.from('This is a test <b>output</b> rendered by the test renderer.'))
69+
};
70+
71+
return result;
72+
},
73+
});
74+
75+
vscode.chat.registerChatOutputRenderer('application/vnd.test-output', {
76+
async renderChatOutput(data, webview, _token) {
77+
const decodedData = new TextDecoder().decode(data);
78+
79+
webview.html = `<!DOCTYPE html>
80+
<html lang="en">
81+
<head>
82+
<meta charset="UTF-8">
83+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
84+
<title>Document</title>
85+
</head>
86+
<body>
87+
${decodedData}
88+
</body>
89+
</html>`;
90+
91+
92+
},
93+
});
94+
}
95+

extensions/markdown-language-features/tsconfig.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
},
66
"include": [
77
"src/**/*",
8-
"../../src/vscode-dts/vscode.d.ts"
8+
"../../src/vscode-dts/vscode.d.ts",
9+
"../../src/vscode-dts/vscode.proposed.chatOutputRenderer.d.ts",
10+
"../../src/vscode-dts/vscode.proposed.chatParticipantPrivate.d.ts"
911
]
1012
}

src/vs/workbench/contrib/chat/browser/chatContentParts/toolInvocationParts/chatToolInvocationPart.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { IInstantiationService } from '../../../../../../platform/instantiation/
1111
import { IChatToolInvocation, IChatToolInvocationSerialized } from '../../../common/chatService.js';
1212
import { IChatRendererContent } from '../../../common/chatViewModel.js';
1313
import { CodeBlockModelCollection } from '../../../common/codeBlockModelCollection.js';
14-
import { isToolResultInputOutputDetails } from '../../../common/languageModelToolsService.js';
14+
import { isToolResultInputOutputDetails, isToolResultOutputDetails } from '../../../common/languageModelToolsService.js';
1515
import { ChatTreeItem, IChatCodeBlockInfo } from '../../chat.js';
1616
import { IChatContentPart, IChatContentPartRenderContext } from '../chatContentParts.js';
1717
import { EditorPool } from '../chatMarkdownContentPart.js';
@@ -23,6 +23,7 @@ import { ChatTerminalMarkdownProgressPart } from './chatTerminalMarkdownProgress
2323
import { TerminalConfirmationWidgetSubPart } from './chatTerminalToolSubPart.js';
2424
import { ToolConfirmationSubPart } from './chatToolConfirmationSubPart.js';
2525
import { BaseChatToolInvocationSubPart } from './chatToolInvocationSubPart.js';
26+
import { ChatToolOutputSubPart } from './chatToolOutputPart.js';
2627
import { ChatToolProgressSubPart } from './chatToolProgressPart.js';
2728

2829
export class ChatToolInvocationPart extends Disposable implements IChatContentPart {
@@ -132,6 +133,10 @@ export class ChatToolInvocationPart extends Disposable implements IChatContentPa
132133
);
133134
}
134135

136+
if (isToolResultOutputDetails(this.toolInvocation.resultDetails)) {
137+
return this.instantiationService.createInstance(ChatToolOutputSubPart, this.toolInvocation, this.toolInvocation.resultDetails, this.context);
138+
}
139+
135140
return this.instantiationService.createInstance(ChatToolProgressSubPart, this.toolInvocation, this.context, this.renderer);
136141
}
137142

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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 * as dom from '../../../../../../base/browser/dom.js';
7+
import { CancellationToken } from '../../../../../../base/common/cancellation.js';
8+
import { IChatToolInvocation, IChatToolInvocationSerialized } from '../../../common/chatService.js';
9+
import { IToolResultOutputDetails } from '../../../common/languageModelToolsService.js';
10+
import { IChatCodeBlockInfo } from '../../chat.js';
11+
import { IChatOutputRendererService } from '../../chatOutputItemRenderer.js';
12+
import { IChatContentPartRenderContext } from '../chatContentParts.js';
13+
import { BaseChatToolInvocationSubPart } from './chatToolInvocationSubPart.js';
14+
15+
export class ChatToolOutputSubPart extends BaseChatToolInvocationSubPart {
16+
public readonly domNode: HTMLElement;
17+
18+
public override readonly codeblocks: IChatCodeBlockInfo[] = [];
19+
20+
constructor(
21+
toolInvocation: IChatToolInvocation | IChatToolInvocationSerialized,
22+
output: IToolResultOutputDetails,
23+
_context: IChatContentPartRenderContext,
24+
@IChatOutputRendererService private readonly chatOutputItemRendererService: IChatOutputRendererService,
25+
) {
26+
super(toolInvocation);
27+
28+
this.domNode = this.createOutputPart(output);
29+
}
30+
31+
private createOutputPart(detauls: IToolResultOutputDetails): HTMLElement {
32+
const parent = dom.$('div.webview-output');
33+
parent.style.maxHeight = '80vh';
34+
35+
this.chatOutputItemRendererService.renderOutputPart(detauls.output.mimeType, detauls.output.value.buffer, parent, CancellationToken.None).then((disposable) => {
36+
this._register(disposable);
37+
this._onDidChangeHeight.fire();
38+
});
39+
return parent;
40+
}
41+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ export function isToolResultInputOutputDetails(obj: any): obj is IToolResultInpu
156156
return typeof obj === 'object' && typeof obj?.input === 'string' && (typeof obj?.output === 'string' || Array.isArray(obj?.output));
157157
}
158158

159+
export function isToolResultOutputDetails(obj: any): obj is IToolResultOutputDetails {
160+
return typeof obj === 'object' && (typeof obj?.output === 'object');
161+
}
162+
159163
export interface IToolResult {
160164
content: (IToolResultPromptTsxPart | IToolResultTextPart | IToolResultDataPart)[];
161165
toolResultMessage?: string | IMarkdownString;

0 commit comments

Comments
 (0)