用 Chat Output Renderer API 在 VS Code 聊天界面渲染自定义组件——chat-output-renderer-sample 深度解析
示例工程【免费下载链接】vscode-extension-samplesSample code illustrating the VS Code extension API.项目地址https://gitcode.com/gh_mirrors/vs/vscode-extension-samples点击查看免费下载本指南围绕 vscode-extension-samples 仓库中的 chat-output-renderer-sample 展开讲解 VS Code 官方提出的proposedChat Output Renderer API 的完整使用方式让扩展向 VS Code 的聊天界面贡献自定义渲染组件由语言模型通过工具tool调用生成这些组件并借助 Webview API 完成渲染。读完本文你将掌握从package.json贡献点声明、工具注册、渲染器注册到 Webview 安全渲染与「模型自修复 Mermaid 标记」完整闭环的实战实现并能在自己的扩展中复用这套模式。一、示例概述Chat Output Renderer API 解决什么问题VS Code 默认的聊天界面只能以文本或少量固定形式展示模型输出。Chat Output Renderer APIproposed API允许扩展为聊天输出贡献自定义渲染组件custom rendered widgets其核心工作链路是语言模型在对话中调用扩展注册的工具Language Model Tool工具返回带自定义 MIME 类型的结构化数据VS Code 依据 MIME 类型匹配扩展注册的输出渲染器渲染器基于 Webview API 将数据渲染成富交互组件本示例为 Mermaid 图表。该 API 还能在渲染历史聊天记录中的旧组件时被再次调用源码注释It can also be invoked when rendering old Mermaid diagrams in the chat history见 src/extension.ts因此聊天记录回放时图表依然可正常显示。本示例选择 Mermaid.js 作为渲染目标直观展示从「模型生成图源码」到「聊天面板内渲染成图」的全过程。二、环境要求与运行方式2.1 环境前置条件按 README.md 的说明运行本示例需要满足VS Code 1.109 或更新版本该版本才开始包含 Chat Output Renderer 相关 API 支持。这一点与 package.json 中的engines: { vscode: ^1.109.0 }相互印证。Node.js 与 npm用于安装依赖和编译 TypeScript。2.2 安装与启动步骤# 1. 进入示例目录 cd chat-output-renderer-sample # 2. 安装依赖 npm install这里有一个容易被忽略的细节npm install触发 package.json 中的postinstall钩子npm run download-api其内部依次执行dts dev下载包含 proposed API 的类型定义和postdownload-api→dts main下载主 API 类型。由于chatOutputRenderer是 proposed API没有这一步骤TypeScript 编译将因缺少类型定义而失败依赖vscode/dts^0.4.0负责完成这项工作。安装完成后在 VS Code 中按F5或点击调试视图中的Run Extension目标即可运行。该调试配置来自 .vscode/launch.jsonpreLaunchTask: npm: watch会先启动编译任务任务定义在 .vscode/tasks.json 中对应tsc -watch -p ./并使用$tsc-watchproblem matcher 捕获编译错误、以isBackground: true作为后台任务运行随后扩展会在一个新的 VS Code 窗口中启动type: extensionHost--extensionDevelopmentPath${workspaceFolder}。三、工程配置声明工具与输出渲染器本示例的扩展清单文件 package.json 展示了两个关键的贡献点这是整个功能「能被 VS Code 识别」的基础。3.1 启用 proposed APIenabledApiProposals: [ chatOutputRenderer ]必须显式声明chatOutputRenderer代码中才能使用vscode.chat.registerChatOutputRenderer以及ExtendedLanguageModelToolResult2.toolResultDetails2等 proposed 类型。3.2 contributes.languageModelTools声明模型可调用的工具示例声明了两个工具package.json字段工具一Mermaid Renderer工具二Mermaid Creatorname/toolReferenceNameextSample_renderMermaidDiagramextSample_createMermaidDiagramdisplayNameMermaid RendererMermaid CreatormodelDescriptionRenders a Mermaid diagram from Mermaid.js markup.Creates a Mermaid diagram from a description and renders for the user.userDescriptionRender a Mermaid.js diagrams from markup.Creates and renders Mermaid.js diagrams.canBeReferencedInPrompttruetrueinputSchema{ markup: string }{ description: string }modelDescription与userDescription分别面向语言模型和用户展示用于决定模型「何时、如何」调用工具inputSchema则是工具的 JSON Schema 参数定义模型会依据它生成调用参数。3.3 contributes.chatOutputRenderers声明自定义输出渲染器chatOutputRenderers: [ { viewType: vscode-samples.mermaid, mimeTypes: [ application/vnd.chat-output-renderer.mermaid ] } ]viewType是渲染器的唯一标识与代码中registerChatOutputRenderer的第一个参数一一对应mimeTypes声明该渲染器处理哪些 MIME 类型的数据当工具结果携带匹配的 MIME 时VS Code 会调用此渲染器。这两组常量在 src/extension.ts 中有明确对应const viewType vscode-samples.mermaid; const mime application/vnd.chat-output-renderer.mermaid;3.4 依赖与编译运行期依赖package.jsonmermaid ^11.12.0图表渲染引擎、jsdom ^26.1.0为 mermaid 在 Node 侧解析提供 DOM 环境、dompurify ^3.3.1HTML 消毒编译配置tsconfig.jsonmodule: commonjs、target: ES2024、strict: true、outDir: out、rootDir: src编译产物输出到out/与package.json的main: ./out/extension.js对应。四、核心实现工具 渲染器的完整闭环示例入口 src/extension.ts 在activate中完成全部注册整体结构清晰注册两个工具 → 注册一个渲染器。4.1 工具一渲染已有的 Mermaid 标记context.subscriptions.push( vscode.lm.registerTool{ markup: string }(extSample_renderMermaidDiagram, { invoke: async (options, token) { let sourceCode options.input.markup; sourceCode await runMermaidMarkupFixLoop(sourceCode, token); return writeMermaidToolOutput(sourceCode); }, }) );该工具接收模型给出的markup字符串先经过「Mermaid 标记修复循环」保证语法尽量合法再调用writeMermaidToolOutput打包输出。工具定义见 src/extension.ts。4.2 工具二根据描述生成 Mermaid 图表context.subscriptions.push( vscode.lm.registerTool{ description: string }(extSample_createMermaidDiagram, { invoke: async (options, token) { const description options.input.description; let sourceCode await generateMermaidDiagram(description, token); if (!sourceCode) { throw new Error(Failed to generate Mermaid diagram from description); } sourceCode await runMermaidMarkupFixLoop(sourceCode, token); return writeMermaidToolOutput(sourceCode); }, }) );该工具接收自然语言描述先让语言模型生成 Mermaid 源码再做修复循环最后输出。两个工具共用同一套「生成 → 校验 → 修复 → 输出」管线体现复用的设计思路。工具定义见 src/extension.ts。4.3 渲染器将二进制数据渲染为 Webviewcontext.subscriptions.push( vscode.chat.registerChatOutputRenderer(viewType, { async renderChatOutput({ value }, chatOutputWebview, _ctx, _token) { const mermaidSource new TextDecoder().decode(value); const mermaidDist vscode.Uri.joinPath(context.extensionUri, node_modules, mermaid, dist); chatOutputWebview.webview.options { enableScripts: true, localResourceRoots: [mermaidDist], }; // ... 拼接 HTML 并注入 mermaid.esm.mjs }, }));关键点逐一拆解实现见 src/extension.tsvalue是二进制数据渲染器收到的value是Uint8Array需要用TextDecoder().decode(value)还原为 Mermaid 源码字符串Webview 资源定位vscode.Uri.joinPath(context.extensionUri, node_modules, mermaid, dist)指向扩展安装目录内 mermaid 的 ESM 产物目录并设置localResourceRoots限定 Webview 可加载的本地资源范围开启脚本enableScripts: true是 Webview 内执行 JavaScript 的前提HTML 内容以pre classmermaid承载源码通过script typemodule以asWebviewUri转换后的 URI 动态importmermaid 的mermaid.esm.mjs并调用mermaid.initialize({ startOnLoad: true })让页面加载完成后自动渲染。4.4 输出打包自定义 MIME 与二进制数据writeMermaidToolOutputsrc/extension.ts是打通「工具 → 渲染器」的关键桥梁function writeMermaidToolOutput(sourceCode: string): vscode.LanguageModelToolResult { const result new vscode.LanguageModelToolResult([ new vscode.LanguageModelTextPart(sourceCode) ]); (result as vscode.ExtendedLanguageModelToolResult2).toolResultDetails2 { mime, value: new TextEncoder().encode(sourceCode), }; return result; }工具结果主体仍是文本供语言模型继续阅读/引用同时通过 proposed 的toolResultDetails2附加mime与二进制value——VS Code 据此将结果路由到对应 MIME 的渲染器。mime常量与package.json中chatOutputRenderers.mimeTypes必须保持一致路由才能命中。五、Mermaid 标记的「自修复循环」让模型输出更可靠语言模型生成的 Mermaid 代码常有语法错误。示例实现了一个最大3 次maxFixAttempts 3见 src/extension.ts的修复循环保证渲染成功率validatemermaid.parse 校验 ├─ 成功 → 直接返回 └─ 失败 → 将源码 错误信息交给语言模型修复 → 重新校验最多 3 轮 最终无论结果如何返回「尽力而为」的源码核心逻辑runMermaidMarkupFixLoopsrc/extension.ts在每一轮都检查token.isCancellationRequested支持用户随时中断。5.1 语法校验在 Node 侧解析 MermaidvalidateMermaidMarkupsrc/extension.ts调用mermaid.parse(sourceCode)判断语法是否合法。由于 mermaid 需要浏览器 DOM 环境示例采用懒加载 JSDOM 打补丁的方式getMermaidInstance见 src/extension.tsconst createMermaidInstance async () { const { window } new JSDOM(); (global as any).window window; (global as any).DOMPurify DOMPurify(window); return import(mermaid); };即用jsdom构造一个空的window挂到global上同时用DOMPurify(window)提供 mermaid 依赖的消毒实现然后动态import(mermaid)。cached ??保证实例只创建一次。5.2 调用语言模型修复语法tryFixingUpMermaidMarkupsrc/extension.ts构造一组对话消息发给语言模型Assistant 消息声明任务根据错误信息修复 Mermaid 源码并要求「在 mermaid 围栏代码块内返回完整源码不加任何注释或解释」User 消息粘贴待修复源码和错误信息原文。随后parseMermaidMarkupFromChatResponsesrc/extension.ts流式收集模型响应校验首行以开头、末行以结尾剥离围栏后返回中间的源码若格式不符则返回undefined调用方回退使用原源码避免模型答非所问破坏已有内容。5.3 从描述生成图表generateMermaidDiagramsrc/extension.ts使用同样的提示词模式要求返回围栏代码块把用户描述转成 Mermaid 源码失败时抛出明确错误。六、语言模型选择策略getPreferredLmsrc/extension.ts按优先级选择可用的聊天模型return (await vscode.lm.selectChatModels({ family: gpt-4o-mini })).at(0) ?? (await vscode.lm.selectChatModels({ family: gpt-4o })).at(0) ?? (await vscode.lm.selectChatModels({})).at(0);即优先gpt-4o-mini成本低、速度快适合修复/生成这类轻量任务退而求其次选gpt-4o最后退回任意可用模型。需要说明该选择策略依赖用户 VS Code 环境中实际可用的语言模型供应商与模型系列不同环境下可用模型会有差异属于示例的合理默认而非硬性约束。若找不到可用模型修复流程会打印警告并返回原源码生成流程则直接抛错。七、安全与健壮性Webview 渲染的底线在聊天界面执行第三方代码模型生成的 Mermaid 源码存在注入风险示例在多处做了防护HTML 实体转义escapeHtmlTextsrc/extension.ts对 逐一转义防止 Mermaid 源码被当作 HTML 解析注入脚本块转义escapeForScriptBlocksrc/extension.ts对反斜杠、引号、回车换行及/script进行转义防止源码闭合 script 标签逃逸CSP 策略Webview HTML 中显式声明default-src none; script-src ${cspSource} nonce-${nonce}; style-src self unsafe-inline——只允许来自cspSource且带 nonce 的脚本杜绝未知来源脚本执行nonce 随机数getNoncesrc/extension.ts生成 64 位随机字符串脚本标签通过nonce${nonce}与 CSP 配合形成一次性执行许可localResourceRoots 白名单Webview 只能访问扩展内node_modules/mermaid/dist下的资源缩小了本地文件暴露面。健壮性方面所有涉及模型请求的异步流程都贯穿CancellationToken检查token.isCancellationRequested一旦用户中断立即抛出Operation cancelled避免悬挂请求。八、把这套模式迁移到自己的扩展以本示例为模板接入自定义聊天组件只需四步改常量替换 src/extension.ts 中的viewType与mime为你的命名空间如my-ext.chart/application/vnd.my-ext.chart改声明在 package.json 的contributes.chatOutputRenderers同步viewType/mimeTypes并按需补充languageModelTools中的工具定义与inputSchema改渲染逻辑在renderChatOutput中解码value、配置webview.options、注入你的前端资源可参考localResourceRoots与asWebviewUri的用法保安全底线保留 CSP nonce HTML 转义三板斧尤其是渲染模型生成的用户内容时。九、总结chat-output-renderer-sample 完整展示了 VS Code Chat Output Renderer API 从声明、注册到渲染的整条链路package.json贡献点声明 MIME 与 viewTypevscode.lm.registerTool提供模型可调用的工具toolResultDetails2携带自定义 MIME 的二进制数据完成路由vscode.chat.registerChatOutputRenderer基于 Webview 完成最终渲染。示例在工程细节上同样值得借鉴——JSDOM 打补丁实现 Node 侧 Mermaid 解析、基于语言模型的三次自修复循环、CSPnonce转义的安全防线以及贯穿始终的取消令牌处理。结合 chat-output-renderer-sample/src/extension.ts 与 chat-output-renderer-sample/package.json 对照阅读即可在自己的扩展中落地同样能力为 VS Code 聊天界面定制任意类型的富交互组件。赞分享示例工程【免费下载链接】vscode-extension-samplesSample code illustrating the VS Code extension API.项目地址https://gitcode.com/gh_mirrors/vs/vscode-extension-samples点击查看免费下载相关推荐Panasonic S5 RAW偏色darktable加载相机配置文件一步还原Panasonic S5 RAW偏色darktable加载相机配置文件一步还原 周日晚上把S5拍的一卷片子导入电脑缩略图一排看过去肤色泛绿、天空发灰相机屏示例工程CopilotKit Headless Chat 完整演示深度解析手写 React 聊天界面与全量渲染 Hook 面CopilotKit Headless Chat 完整演示深度解析手写 React 聊天界面与全量渲染 Hook 面 导读 headless complete人工智能AI AgentAgent 框架前端后端A2UI Lit Renderer 深度指南基于 Lit Web Components 的 Agent 声明式界面渲染架构与自定义组件实践A2UI Lit Renderer 深度指南基于 Lit Web Components 的 Agent 声明式界面渲染架构与自定义组件实践 本篇指南围绕 A2人工智能AI AgentAI 应用前端UI组件上一篇Vant Rate 评分组件完全指南从基础用法到源码级交互原理下一篇Cilium 实战用 cilium-dbg fqdn cache list 检视 FQDN 代理 DNS 缓存创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Boto3(AWS SDK for Python)IAM Policy 管理实战:创建、查询、附加与分离托管策略

Boto3(AWS SDK for Python)IAM Policy 管理实战:创建、查询、附加与分离托管策略

后端云原生 【免费下载链接】boto3 AWS SDK for Python (Boto3) 项目地址: https://gitcode.com/gh_mirrors/bo/boto3 点击查看 免费下载 本文是基于 AWS SDK for Python(Boto3)的 IAM 策略管理实战指南,围绕 IAM 托管策略的完整…

2026/9/24 17:20:26 阅读更多 →
Beekeeper Studio 语言切换指南:3 分钟配好中文界面与区域设置

Beekeeper Studio 语言切换指南:3 分钟配好中文界面与区域设置

Beekeeper Studio 语言切换指南:3 分钟配好中文界面与区域设置 【免费下载链接】beekeeper-studio Modern and easy to use SQL client for MySQL, Postgres, SQLite, SQL Server, and more. Linux, MacOS, and Windows. 项目地址: https://gitcode.com/GitHub_Tr…

2026/9/24 17:20:25 阅读更多 →
以 180° 翻转的英文 “en-Qabs“ 语言包解析 HMCL 的“倒置英语“彩蛋:从 README_en_Qabs.md 到运行时翻译器

以 180° 翻转的英文 “en-Qabs“ 语言包解析 HMCL 的“倒置英语“彩蛋:从 README_en_Qabs.md 到运行时翻译器

桌面应用游戏开发 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL 点击查看 免费下载 HMCL(Hello Minecraft! Launcher)的文档目录中…

2026/9/24 17:20:25 阅读更多 →

最新新闻

卡车倾倒建筑垃圾检测数据集:从视频流到行为识别的落地拆解

卡车倾倒建筑垃圾检测数据集:从视频流到行为识别的落地拆解

简介:这是一份面向计算机视觉与深度学习方向的目标检测数据集,聚焦卡车倾倒建筑垃圾这一特定行为识别任务,适合训练和评估YOLOv7等实时检测模型,可服务于城市监控、建筑工地管理与环保监测等场景。压缩包共1023个文件,…

2026/9/24 19:32:03 阅读更多 →
心脏病预测机器学习实战:11个脚本从数据清洗到XGBoost调参

心脏病预测机器学习实战:11个脚本从数据清洗到XGBoost调参

简介:这份资源面向机器学习入门与进阶学习者,提供一套完整的心脏病数据集分析与预测实战案例,帮助读者掌握从数据清洗、特征工程到多模型对比的完整流程。包内共14个文件,以11个Python源代码为主,另含2个CSV数据集和1个…

2026/9/24 19:32:03 阅读更多 →
基于销量可视化的手机价位段智能选型平台

基于销量可视化的手机价位段智能选型平台

开头做手机选品或者门店铺货的朋友,应该都有过这种纠结:同一批预算,到底是多进几台千元机走量,还是押两三部旗舰机赚毛利?以前大家基本靠经验和感觉,但感觉这东西在行情波动面前特别不靠谱。我去年接手了一…

2026/9/24 19:32:03 阅读更多 →
东华OJ刷题复盘:从TLE到AC,避开多组输入与边界陷阱

东华OJ刷题复盘:从TLE到AC,避开多组输入与边界陷阱

连着刷了三个晚上,东华OJ的基础练习终于推进到了第7到第9题。说实话,这三道题单独拎出来都不算难,但它们卡我的时间和心态,比后面那些看起来更复杂的题还要狠。第7题让我第一次在OJ上感受到“Time Limit Exceeded”的分量&#xf…

2026/9/24 19:32:03 阅读更多 →
SAP选择性数据迁移实施商选型:2026年避坑指南

SAP选择性数据迁移实施商选型:2026年避坑指南

2026年,很多SAP老客户心里都装着一件事:ECC到底什么时候迁,怎么迁。而在这个大问题下面,真正让人头疼的其实是另一个更具体的问题——选择性数据迁移,到底该选哪家SAP实施商来干。先别急着谈价格、谈人天,我…

2026/9/24 19:32:03 阅读更多 →
MySQL用户管理与权限设置实战:从GRANT到远程连接排查

MySQL用户管理与权限设置实战:从GRANT到远程连接排查

接手过不少MySQL环境,也帮人排查过很多数据库问题,发现真正让运维和开发头疼的,往往不是SQL写得不好,而是用户管理和权限设置这块没搞清爽。尤其是线上环境,账号多了、权限乱了,要么是开发抱怨连不上库&…

2026/9/24 19:31:02 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →