用 Chat Output Renderer API 在 VS Code 聊天界面渲染自定义组件——chat-output-renderer-sample 深度解析

发布时间:2026/9/24 17:21:40

用 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),仅供参考
延伸阅读

更多相关文章

2026/9/24 17:21:40

进销存软件排行榜:2026年10款主流软件横评与选型

摘要:进销存软件用得对不对,直接影响开单、库存和对账效率。本文按开单顺不顺、库存准不准、对账清不清、价格合不合理四件事,横评10款主流产品,并给出不同业态的选型建议和上手四步。一、进销存排行榜是怎么排的?先看…

2026/9/24 18:21:44

Spring Boot后端项目部署实战:从解压到联调的全流程指南

简介:期刊出版数字化要求后端系统高效组织数据与业务逻辑。这份资源正是一套面向初中级开发者的期刊管理后端实现,适合用来学习API设计、数据库建模与权限控制。资源围绕期刊、文章、作者、审稿人等核心实体,以Python提供app入口、rpc远程调用…

2026/9/24 18:21:44

AI创业公司云平台选型指南:算力、成本与防锁定策略

这两年我经常被VC朋友问同一个问题:手上投了十几家AI公司,每家都在问云平台怎么选,能不能直接给个清单?说实话,这个问题没有标准答案,但问的人多了,我发现大家踩过的坑高度重合。今天这篇就从技…

2026/9/24 18:21:44

Win11网线直连传大文件:“输入网络凭据”问题全解析

1. 为什么网线直连才是最稳的文件传输方式先说个场景:两台电脑都需要互传大量文件,一个大活儿是几十 GB 的设计稿、视频素材或者虚拟机镜像。用 U 盘倒腾来回拔插累得够呛,走微信、网盘传大文件要么限速要么压缩画质,内网 WiFi 传…

2026/9/24 18:21:44

从COCO到YOLO:雨雪路面数据集训练全流程与避坑指南

简介:雨雪天气路面状况识别是自动驾驶与智能交通中的常见难点,这份数据集专门面向结冰路面、雪地、下雨湿滑、干燥路面四类场景,图片均为原始拍摄图像,并使用COCO格式进行目标标记,可直接用于目标检测、语义分割等模型…

2026/9/24 18:16:44

Java火车票系统实战:解决超卖、事务隔离与订单唯一性

简介:这是一套面向Java初学者与数据库课程实践者的火车票售票系统完整源码,基于Java Swing界面与Access数据库(.mdb文件)实现,解决小型票务场景下的车次管理、余票查询、在线售票与退票等核心业务需求。资源共89个文件…

2026/9/23 12:07:00

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/24 0:00:21

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

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

2026/9/24 0:00:21

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

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

2026/9/24 0:00:21

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

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

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码