前言¶
DSH 的定位是「一切皆插件」,对话、工具和界面都可以由插件扩展。但在标准对话里,模型给出的通常是一段文本;当你想让答案包含图表、卡片或可交互组件时,纯文本流并不直接满足需求。
dsh-openui-studio 就是针对这个问题的插件。它由 zouyao-andy 维护,客户端分类,目录页显示 0 星,npm 版本 0.1.2。它的思路是在普通 DSH 对话里加入一个按需触发的 /openui 命令:由当前会话选定的模型生成 OpenUI Lang,经过官方 OpenUI 聊天库校验后,用官方 OpenUI Renderer 渲染在对话里。会话、推理、历史、工具记录和输入框仍由 DSH 负责,插件不另起一套界面。
核心功能¶
下面介绍插件实际提供的能力,均来自仓库 README 与 package.json。
- 按需生成:只有显式出现
/openui请求的那一轮才启用 OpenUI 生成,普通消息仍走 DSH 正常流程。附件受支持,只带附件的/openui请求也会被接受。 - 生成与校验:agent 带着会话上下文调用
openui_generate。结果先经官方 OpenUI 聊天库校验,合法结果作为 DSH 工具结果保存并显示在主对话。首次校验失败时插件做一次修复调用;仍失败则 DSH 显示工具错误,不保存半成品界面。 - 官方渲染:渲染使用官方 OpenUI Renderer 和样式表,插件不添加自己的对话数据库、侧栏、输入框或 DSH 模式。
- 结果复用:已保存的结果在重新打开对话时直接渲染,不需要再触发一次模型调用。
- 失败可重试:模型没有产出可用文本时,工具错误会报出流的结束原因、分块数量和原始文本长度,但不记录模型内容,也不会在本轮
/openui里自动重试。 - 按钮不自动发送:OpenUI 答案里的按钮只把建议问题填入 DSH 输入框并聚焦,不会自动发送消息。
逐层重绘与回放¶
新答案使用 Swarm Rebuild 引擎逐层重建已渲染的 OpenUI DOM:光标画框、输入文字、放置媒体、复制重复元素、调整尺寸,并使用对齐参考线。回放会在对话里滚动经过未完成的工作,再回到实时 OpenUI 答案;视口跟随活动元素,密集段落放慢、稀疏段落加快。交接处等对话到达答案末尾,短暂交叉淡化到实时页面。回放从可读的答案内容开始,没有纯光标开场动画。
已保存的答案会立即打开。点击 OpenUI Studio 旁的 replay 图标,可以在不重新生成的情况下重建一次;点击画布或按 Escape 回到可交互答案。系统请求减少动态效果、或新答案在 DSH 后台完成时,回放会跳过。播放期间切换主题会回到实时答案。
动画只对已渲染的 OpenUI DOM 做快照,不修改 OpenUI Lang 结果,也不向对话追加记录。
渲染配置¶
渲染层通过编辑 render.js 自定义。可以在 DSH 里点击 OpenUI Studio 旁的配置图标打开,也可以直接编辑文件。该文件导出一个 JavaScript 对象,配置项如下:
| 配置项 | 默认值 | 作用 |
|---|---|---|
showEditButton |
true |
显示打开 render.js 的图标。 |
toolbar |
['replay'] |
排序或隐藏 replay、debug、download-log。 |
animation.autoPlay |
true |
自动重绘新生成的答案,手动 replay 仍可用。 |
animation.followScroll |
true |
跟随重建过程向下滚动;设为 false 则立即显示完整答案。 |
css |
内置样式表 | 对 OpenUI 答案做作用域内的 CSS 覆盖。 |
css 字符串里包含 --openui-studio-font、--openui-studio-body-size、--openui-studio-body-leading、--openui-studio-heading-size 等排版变量。自定义选择器要放在 .openui-answer 或 .openui-native 之下,避免影响 DSH 本体。这些设置只改变渲染和控件,不改变 LLM prompt 或已保存的答案。编辑 render.js 后需要完全退出并重新打开 DSH,不需要构建或再次调用模型;无效配置会回退到内置默认值并在答案标题旁报错。
模型调用配置¶
模型调用参数单独放在 cordis.patch.yml,字段为 provider、model、maxTokens、temperature、reasoningEffort、maxQuestionChars、promptSuffix。
把 model 和生成类配置保留为 null,就会沿用当前 DSH 会话的请求设置。会话没有 token 预算时,插件读取所选模型的 defaultMaxTokens;该值不存在时交给 DSH 决定。插件里非 null 的值会覆盖对应的会话设置。maxQuestionChars 限制发送给生成器的问题长度,promptSuffix 把环境相关说明追加到生成的官方 OpenUI prompt 之后。基础 prompt 和校验 schema 仍然来自已安装的 OpenUI 包。修改插件配置后需要重启 DSH。profile 的 cordis.patch.yml 在插件 bundle 之后应用,因此可以在不修改插件源码的情况下覆盖这些字段。界面控件跟随 DSH 语言,答案文本跟随问题语言。
安装与启用¶
官方安装方式是在 DSH 的插件管理界面填写插件标识,步骤如下。
- 装好 DSH,并在 Settings → Models 里选择一个默认模型。
- 在 Settings → Plugins → Add plugin 中填入
dsh-openui-studio;也可以直接从 GitHub 仓库安装。 - 安装或更新后完全退出并重新打开 DSH。
- 在 Standard 或 PTC 对话里输入命令,例如:
/openui Explain KV cache memory usage with a chart and a worked example
动画诊断¶
排查回放问题时,可以开启调试日志。
- 在
render.js里把toolbar设为['replay', 'debug', 'download-log'],然后重启 DSH。 - 点击 OpenUI Studio 旁的虫子图标,回放同时记录 block、cursor、animation、scroll、finish 事件。
- 回放结束后点击下载图标保存 JSON 日志。
日志包含时间和几何信息,不包含答案文本,也不需要 DevTools Console。Debug 和下载按钮默认隐藏。
本地开发¶
本地开发需要 Node.js 20 或更高版本。
git clone https://github.com/zouyao-andy/dsh-openui-studio.git
cd dsh-openui-studio
npm ci
npm run build
然后把这个目录通过 DSH 插件管理器作为本地 bundle 安装。本地 checkout 与 npm 包使用同一个插件 ID,因此添加新安装前要先移除旧的 @local/dsh-openui-studio。
npm test
npm run test:render
npm run build
源码职责:src/host/index.js 处理命令、受门控的工具、模型调用和 OpenUI 校验;src/client/chat-answer.js 把已保存结果放进 DSH 轮次;src/client/native-answer.js 使用官方 Renderer 和样式表;src/client/swarm-reveal.js 把答案接到适配过的 Swarm Rebuild 引擎 src/client/vendor/swarm-rebuild.js。之前的绘制策略文件保留用于对比,但不再使用。scripts/gen.mjs 生成官方 OpenUI prompt 和 schema,scripts/build.mjs 生成 Host index.js 和 Client client.js bundle。修改插件源码后需要重新构建并重启 DSH。
适用场景与注意¶
适合已经在 DSH 里做对话式工具或内容展示、希望答案自带可交互界面的开发者,也适合想把 OpenUI Lang 生成纳入现有会话、而不是另起界面的插件作者。
需要注意几点:插件以当前 DSH 进程的权限运行,安装前应先检查源码和许可证;生成结果依赖当前会话所选模型、输出 token 预算和推理强度;没有显式 /openui 请求时不会改变普通对话流程;官方渲染器版本不支持早期自定义 Stack 答案。许可证是 MIT,绘制引擎改编自 Swarm Rebuild(commit 601f6e2),同样是 MIT。
结尾¶
DSH 把界面渲染也交给插件,而 dsh-openui-studio 在保持会话归 DSH 的前提下,把「生成 OpenUI 答案并按需重绘」放进了一次对话里。目录页是独立站点,与 DeepSeek / 幻方无官方从属关系。
- 目录页:https://www.skillhub.cn/plugins/zouyao-andy/dsh-openui-studio
- 仓库:https://github.com/zouyao-andy/dsh-openui-studio