news 2026/10/21 23:21:52

openvscode-server 内置聊天中的 Mermaid 图表渲染:mermaid-chat-features 扩展深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
openvscode-server 内置聊天中的 Mermaid 图表渲染:mermaid-chat-features 扩展深度解析
  • 开发工具
  • IDE
  • 代码编辑器
  • 后端

【免费下载链接】openvscode-server

Run upstream VS Code on a remote machine with access through a modern web browser from any device, anywhere.

项目地址:https://gitcode.com/gh_mirrors/op/openvscode-server
点击查看免费下载

openvscode-server 继承了 VS Code 的内置扩展体系,其中mermaid-chat-features专门负责为内置聊天(built-in chat)提供基础的 Mermaid.js 图表渲染能力。本文以仓库中 extensions/mermaid-chat-features/README.md 为骨架,结合扩展的package.json、扩展宿主源码与聊天 Webview 前端源码,从配置开关、语言模型工具、输出渲染器、平移缩放交互到安全策略,完整梳理该扩展的工作机制与使用方式。读完本文,你将理解 Mermaid 图表在聊天输出中从"语言模型生成标记"到"Webview 交互式渲染"的完整链路,并掌握mermaid-chat.enabled、renderMermaidDiagram工具及上下文菜单命令的配置与行为。

扩展定位:内置、可禁用、不可卸载

mermaid-chat-features在 VS Code / openvscode-server 中属于随产品捆绑(bundled)的内置扩展。README 开篇即给出明确约束:

This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.

即:该扩展无法被卸载,但可以在扩展面板中禁用。其本地化描述(见 extensions/mermaid-chat-features/package.nls.json)将其功能概括为 "Adds Mermaid diagram support to built-in chats."——为内置聊天添加 Mermaid 图表支持,与 README 中 "Adds basic Mermaid.js diagram rendering to build-in chat" 相互印证。

从 package.json 可以看到它的关键元信息:

  • name/publisher:mermaid-chat-features/vscode
  • engines.vscode:^1.104.0(要求宿主至少为 1.104.0 版本)
  • enabledApiProposals:["chatOutputRenderer"](依赖尚处于提案阶段的 Chat Output Renderer API,对应声明见 src/vscode-dts/vscode.proposed.chatOutputRenderer.d.ts)
  • capabilities:支持virtualWorkspaces,且声明untrustedWorkspaces.supported = true(可在不受信任的工作区中运行)
  • 运行时依赖:mermaid ^11.11.0、dompurify ^3.2.7(前者用于图表解析渲染,后者作为输出净化类依赖声明)

构建层面,扩展同时提供 Node 侧(esbuild.mts输出至dist)与浏览器侧(esbuild.browser.mts输出至dist/browser)两套产物,其聊天 Webview 资源则由 esbuild.webview.mts 以index、index-editor、codicon三个入口打包到chat-webview-out,分别对应聊天内联渲染页和编辑器预览页。

开关配置:mermaid-chat.enabled

扩展通过contributes.configuration暴露唯一一个用户可配置项:

"mermaid-chat.enabled": { "type": "boolean", "default": true, "description": "%config.enabled.description%", "scope": "application" }
  • 类型为布尔值,默认开启(true),本地化描述为 "Enable a tool for Mermaid diagram rendering in chat responses."(在聊天回复中启用 Mermaid 图表渲染工具);
  • scope为application,即该设置作用于应用级而非单个工作区,跨工作区保持一致;
  • 该开关的生效点体现在languageModelTools贡献中的when条件:config.mermaid-chat.enabled,即只有在开关为真时,renderMermaidDiagram语言模型工具才会被暴露给聊天模型使用。

语言模型工具:renderMermaidDiagram

扩展向聊天模型注册了一个名为renderMermaidDiagram(展示名 "Mermaid Renderer")的语言模型工具,声明位于 package.json 的contributes.languageModelTools,并在 src/chatOutputRenderer.ts 中通过vscode.lm.registerTool完成实际注册。

工具的输入 Schema 如下:

{ "type": "object", "properties": { "markup": { "type": "string", "description": "The mermaid diagram markup to render as a Mermaid diagram. This should only be the markup of the diagram. Do not include a wrapping code block." }, "title": { "type": "string", "description": "A short title that describes the diagram." } } }
  • markup:必填,仅允许传入 Mermaid 图表标记本身,不得包含包裹它的代码围栏(wrapping code block);
  • title:可选,一句话概括该图表。

工具被调用后,invoke逻辑(writeMermaidToolOutput)做两件事:

  1. 生成标准的 Markdown Mermaid 代码块:通过getFenceForContent动态计算围栏——统计内容中连续反引号的最大长度,取max(3, 最长连续反引号数 + 1),从而避免图表源码自身含反引号时破坏代码块;随后返回形如```mermaid\n<markup>\n```的LanguageModelTextPart,保证在纯文本环境(如不支持自定义渲染器的客户端)也能降级展示;
  2. 附带自定义渲染数据:将{ source, title }序列化为 JSON,以text/vnd.mermaid为 MIME 类型写入toolResultDetails2(提案 API 中的ToolResultDataOutput,见 vscode.proposed.chatOutputRenderer.d.ts),提示宿主使用自定义输出渲染器来渲染这段内容。

聊天输出渲染器:text/vnd.mermaid与vscode.chat-mermaid-features.chatOutputItem

扩展在contributes.chatOutputRenderers中声明了一个输出渲染器:

{ "viewType": "vscode.chat-mermaid-features.chatOutputItem", "mimeTypes": [ "text/vnd.mermaid" ] }
  • viewType是渲染器的唯一标识,与 src/chatOutputRenderer.ts 中vscode.chat.registerChatOutputRenderer(viewType, renderer)注册时传入的字符串一致;
  • mimeTypes声明该渲染器负责的 MIME 类型。结合源码注释(src/chatOutputRenderer.ts),该渲染器既会被工具生成的数据触发,也会用于渲染聊天历史中遗留的旧 Mermaid 图表——这正是decodeMermaidData兼容性的由来。

renderChatOutput的渲染流程(src/chatOutputRenderer.ts)可拆解为:

  1. 解码数据:decodeMermaidData先把Uint8Array解码为文本,优先尝试按 JSON 解析(新格式,含source与可选title),解析失败则整体当作纯文本(旧格式),保证历史聊天记录仍可渲染;
  2. 注册 Webview:为每次渲染生成唯一webviewId,交给MermaidWebviewManager登记,并把openInEditor消息转发为_mermaid-chat.openInEditor命令;
  3. 装配 Webview:enableScripts: true、localResourceRoots指向chat-webview-out;HTML 中通过escapeHtmlText将 Mermaid 源码插入<pre class="mermaid">(对& < > " '五类字符做实体转义),并加载打包后的index.js与codicon.css;
  4. 设置 CSP:页面采用严格的 Content-Security-Policy——default-src 'none'; script-src 'nonce-…'; style-src <cspSource> 'unsafe-inline'; font-src data:;,脚本仅允许携带随机 nonce 的入口模块执行。

数据流总览:从模型输出到交互式图表

综合以上各环节,一条完整的数据链路是:

聊天模型调用 renderMermaidDiagram(markup, title) │ vscode.lm.registerTool → writeMermaidToolOutput ▼ 返回 Markdown 围栏代码块 + toolResultDetails2(text/vnd.mermaid, JSON) │ registerChatOutputRenderer 按 viewType 匹配 ▼ MermaidChatOutputRenderer.renderChatOutput → decodeMermaidData │ generateUuid + registerWebview(webviewManager 登记为 'chat' 类型) ▼ webview.html 注入(escapeHtmlText + CSP + nonce) → 加载 index.js ▼ mermaidWebview.ts:mermaid.initialize + mermaid.run → SVG 渲染 │ PanZoomHandler 接管平移缩放;MutationObserver 监听主题切换 ▼ 用户交互:悬停"Open in Editor"按钮 / 右键菜单(Reset Pan and Zoom、Copy Diagram Source)

Webview 管理与单图单面板:webviewManager 与 editorManager

MermaidWebviewManager

src/webviewManager.ts 用一个Map<string, MermaidWebviewInfo>统一管理聊天输出与编辑器预览两类 Webview:

  • registerWebview(id, webview, mermaidSource, title, type):登记时若 id 已存在会抛出错误,返回的Disposable在销毁时自动注销并清理"活跃 Webview"标记;
  • activeWebview/setActiveWebview:跟随编辑器面板焦点变化维护当前活跃项,供无参命令(如重置缩放、复制源码)定位目标;
  • resetPanZoom(id?):向目标 Webview 发送{ type: 'resetPanZoom' }消息。

MermaidEditorManager

src/editorManager.ts 管理编辑器预览面板(viewType 为vscode.chat-mermaid-features.preview):

  • 内容哈希去重:getWebviewId对 Mermaid 源码做简单的 32 位哈希并转为十六进制作为面板 ID,保证"同一份图表内容只存在一个预览";再次打开同源图表时调用reveal()直接聚焦既有面板,避免重复创建;
  • 面板创建与恢复:新建面板时设置ThemeIcon('graph')图标、retainContextWhenHidden: false,并注册WebviewPanelSerializer;窗口重开时通过deserializeWebviewPanel按持久化的{ webviewId, mermaidSource }状态恢复,恢复失败则显示错误页而非空白页;
  • 生命周期:预览关闭时从 Webview 管理器注销并从_previews中移除,dispose()会级联销毁所有面板。

前端渲染与交互:平移、缩放与主题联动

聊天与编辑器共用同一套前端渲染逻辑 chat-webview-src/mermaidWebview.ts:

  • 渲染入口:mermaid.initialize({ startOnLoad: false, theme })后调用mermaid.run({ nodes: [diagram] })手动渲染,渲染完成后给元素加上rendered类使其从visibility: hidden变为可见;
  • 主题自适应:getMermaidTheme依据vscode-dark/vscode-high-contrast等 body 类判定深色主题;MutationObserver监听 body class 变化,主题切换时清空data-processed并用新主题重新渲染;
  • PanZoomHandler(mermaidWebview.ts)提供完整的图表浏览交互:
    • 缩放范围限制在0.1x ~ 5x(minScale/maxScale),默认zoomFactor = 0.002;
    • Alt + 鼠标拖拽平移、Alt + 单击放大(×1.25)、Alt + Shift + 单击缩小(×0.8);
    • 触控板**双指捏合(pinch)**缩放(走ctrlKey分支,放大因子 ×5 以补偿较小的 deltaY)、Alt + 双指滚动缩放;
    • 平移/缩放后的{ scale, translateX, translateY }通过vscode.setState持久化,再次打开同一 Webview 时restoreState直接恢复,未交互过则居中显示并在 resize 时重新居中;
    • 收到resetPanZoom消息(来自右键菜单命令)时重置为 1x 并清除持久化状态。
  • 两个入口页面的差异:聊天页 index.ts 额外绑定"Open in Editor"悬浮按钮,点击向扩展宿主发送openInEditor消息;编辑器页 index-editor.ts 则装配右上角放大 / 缩小 / 重置三枚缩放控制按钮。

命令与菜单:面向 Webview 上下文的三个内部命令

package.json 的contributes.commands注册了三个内部命令(_前缀表明是私有命令):

命令标题使用场景
_mermaid-chat.resetPanZoomReset Pan and Zoom重置平移与缩放
_mermaid-chat.openInEditorOpen Diagram in Editor在编辑器预览中打开图表
_mermaid-chat.copySourceCopy Diagram Source复制图表 Mermaid 源码

它们的调度逻辑:

  • commandPalette菜单项全部设置"when": "false",因此不会出现在命令面板,只能通过 Webview 上下文触发;
  • webview/context菜单按webviewId条件投放:resetPanZoom仅出现在聊天输出项(vscode.chat-mermaid-features.chatOutputItem);copySource在聊天输出项与编辑器预览(vscode.chat-mermaid-features.preview)中均可用;
  • 实现上(src/extension.ts),命令接收{ mermaidWebviewId? }上下文参数,优先定位指定 Webview,缺省时回退到activeWebview;copySource直接调用vscode.env.clipboard.writeText写入该 Webview 保存的mermaidSource。

安全设计:CSP、HTML 转义与不受信任工作区

由于聊天输出可能来自模型生成的内容,渲染侧在安全上做了多重防护:

  • 严格的 CSP:聊天与预览页面均声明default-src 'none',仅放行带 nonce 的内联脚本与cspSource样式的 webview(见 chatOutputRenderer.ts 与 editorManager.ts);
  • 输出转义:Mermaid 源码在注入<pre>前经过 src/util/html.ts 的escapeHtmlText(转义& < > " '),阻断 HTML 注入;随后浏览器页面本身先隐藏(visibility: hidden),待mermaid.run完成渲染、内容由 Mermaid 库解析为 SVG 后才显示;
  • 依赖净化库:扩展依赖中声明了dompurify ^3.2.7作为净化类依赖;
  • 工作区策略:capabilities.untrustedWorkspaces.supported = true,表明扩展在不受信任工作区中也被判定为安全可用,与上述内容不直接执行任意页面脚本的设计一致。

使用方式与注意事项

  • 开关控制:在设置中搜索mermaid-chat.enabled即可启用/禁用聊天中的 Mermaid 渲染工具(默认开启,应用级作用域)。禁用后renderMermaidDiagram工具的when条件不满足,聊天模型将不再暴露该工具;
  • 提示词使用:直接请聊天模型"画一个 Mermaid 流程图/时序图/状态图"即可触发该工具;模型会返回markup(仅图表标记)与可选的title;
  • 交互操作:在聊天输出或编辑器预览中,按住 Alt 拖拽平移、Alt+单击缩放、触控板捏合缩放;右键可重置缩放或复制图表源码;聊天输出右上角悬浮按钮可一键把图表打开到编辑器预览;
  • 内置属性限制:该扩展随产品捆绑、不可卸载,只能在扩展管理中禁用;它提供的是"基础(basic)"渲染能力,依赖宿主版本 ≥ 1.104.0 及chatOutputRenderer提案 API。

小结

mermaid-chat-features是 openvscode-server 聊天生态中一个小而完整的内置扩展:它以renderMermaidDiagram语言模型工具为入口、以text/vnd.mermaid自定义 MIME 为传输媒介、以ChatOutputRenderer提案 API 为渲染桥梁,最终在严格 CSP 的 Webview 中交付带平移缩放、主题联动、编辑器预览与源码复制能力的 Mermaid 图表。阅读 README.md、package.json、src/chatOutputRenderer.ts、src/editorManager.ts 与 chat-webview-src/mermaidWebview.ts,可以完整复现这套"模型生成 → 工具输出 → 渲染器分发 → Webview 交互"的扩展开发范式。

  • 开发工具
  • IDE
  • 代码编辑器
  • 后端

【免费下载链接】openvscode-server

Run upstream VS Code on a remote machine with access through a modern web browser from any device, anywhere.

项目地址:https://gitcode.com/gh_mirrors/op/openvscode-server
点击查看免费下载
上一篇:3分钟掌握jQuery折叠插件:打造专业级网页交互体验
下一篇:Android-OCR字符过滤技术详解:黑白名单机制实现精准识别

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 22:19:11

大麦自动抢票:3步跑通这个脚本

大麦自动抢票&#xff1a;3步跑通这个脚本 【免费下载链接】Automatic_ticket_purchase 大麦网抢票脚本 项目地址: https://gitcode.com/GitHub_Trending/au/Automatic_ticket_purchase 开售前 10 秒你还在刷页面&#xff0c;"立即购买"灰得比谁都快。手速再快…

作者头像 李华
网站建设 2026/10/19 6:25:29

OpenStack PortBindingFailed排查:Provider Network实例创建失败全解析

只要手动搭过 OpenStack&#xff0c;多少都见过这个画面&#xff1a;明明 provider network 创建成功&#xff0c;subnet 也都是 ACTIVE&#xff0c;结果 openstack server create 一执行&#xff0c;实例状态直接变成 ERROR&#xff0c;fault 里写着 PortBindingFailed: Bindi…

作者头像 李华
网站建设 2026/10/21 12:11:18

电子信息夏令营选拔的四大隐形能力:建模、工程、协同与拆解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/18 6:32:16

Zero 框架 Python 后端开发实战:用 .py 文件定义 API 端点全指南

后端 【免费下载链接】zero Zero is a web server to simplify web development. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/ze/zero 点击查看 免费下载 导读 本文深入讲解开源 Web 开发框架 Zero 的 Python 支持能力&#xff1a;开发者只需在项目目录中放置一个…

作者头像 李华