智能交互界面 dreamfarer-space/deepseek-harness-intelligent-ui
DeepSeek Harnessv0.2.11演示 · 快速开始 · 如何选择 · 组件 · 沙箱组件 · 扩展 · 安全 · 配置 · 质量 · 开发
43.6/100
综合分
22
GitHub 星标
931
npm 周下载
—/5
用户评分
数据截至 2026/11/4 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add deepseek-harness-intelligent-uinpm 源 · deepseek-harness-intelligent-ui 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · ui
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 1 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包deepseek-harness-intelligent-ui @ 0.2.11
✓Node 引擎要求 >=22.13.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖要求 >=0.1.7-rc.1 <0.3.0-0 || >=0.2.0-0 <0.2.0 || >=0.2.1-0 <0.2.1 || >=0.2.2-0 <0.2.2 · 最新 0.2.1-rc.2 兼容
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/29 01:43:12
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件写入剪贴板(不计风险)
查看扫描证据(共 7 处,展示前 7 条)
- 写入剪贴板client/client.js:286
`);return t[t.length-1]===""&&t.pop(),t}function mu(e,t){let n=ca(e),r=ca(t),i=am(n,r),a=[],o=0,s=0;if(!i)return n.forEach((c,d)=>a.push({op:"-",text: - 写入剪贴板client/client.js:321
`)}function Sx(e){let{block:t,env:n}=e,r=typeof t.html=="string"?t.html:"",i=e.settled&&r!=="";return r===""&&typeof t.css!="string"?(0,Ce.jsx)(yn,{me - 写入剪贴板renderer/renderer.js:651
`);return t[t.length-1]===""&&t.pop(),t}function Zv(e,t){let n=Gp(e),i=Gp(t),r=qE(n,i),a=[],l=0,o=0;if(!r)return n.forEach((c,d)=>a.push({op:"-",text: - 读取本地文件bin/cli.mjs:18
const pkg = JSON.parse(readFileSync(fileURLToPath(new URL('../package.json', import.meta.url)), 'utf8')) - 读取本地文件bin/cli.mjs:98
const manifest = JSON.parse(readFileSync(path.join(dir, 'package.json'), 'utf8')) - 执行外部命令来自配置/变量bin/cli.mjs:111
const r = spawnSync(win ? shellLine(cmd, args) : cmd, win ? [] : args, { - 读取本地文件bin/cli.mjs:159
if (!existsSync(dir)) warn(`profile "${opts.profile}" does not exist yet at ${dir}`, 'it is created on first install')
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh@deepseek-ai/dsh-llm给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
为 DeepSeek Harness(DSH)提供生成式交互界面:声明式组件和沙箱实时小组件在聊天中流式呈现。
最近更新
在 GitHub 查看全部 →v0.2.112026-10-28
· 变更
· 支持 DeepSeek Harness 0.2.1-rc.3、0.2.1-rc.4(next)和 0.2.2-alpha.2(alpha)。@deepseek-ai/dsh 和 @deepseek-ai/dsh-llm 的 peer 范围现在列出 0.2.2 预发布版,@deepseek-ai/cordis 的 peer 范围列出 4.0.6 预发布版,这样普通 npm 共同安装的结果与 DSH 自身的兼容性检查一致。安装冒烟测试、完整的浏览器 E2E(43 项检查)和 DSH 扩展 E2E 在三个版本上全部通过,无需改动运行时。
v0.2.102026-10-27
· 变更
· 小组件策略设置(cdnAllowlist、allowNetwork、maxWidgetHeight、maxWidgetBytes、sendPromptMaxChars、openLinkAllowedOrigins)现在是实时生效的设置:可以直接在官方设置表单里修改,DeepSeek Harness Remote 客户端也支持,改完下次工具调用就生效,不用重新加载插件。
· 设置说明支持简体中文。
· 安全
· 在沙箱审计中把弹窗、顶部导航、表单和下载这四类探测拆开了。表单检查现在要求出现真实的 CSP 违规且没有请求;下载检查用浏览器事件,并带一个阳性对照。跨源下载链接即使保存响应被拦截,仍可能发起自导航请求。
· 小组件沙箱边界审计(#19),实测矩阵见 docs/widget-csp-audit.md,回归套件在 npm run e2e:security 里,覆盖所有资源类型和请求通道。
· 宿主消息走一条绑定文档的 MessageChannel,由 bootstrap 在生成代码之前建立。被导航过的文档收不到宿主 RPC 结果、HTML 或主题更新,哪怕它无限期推迟 load 事件。重建会轮换凭据并重置生命周期;过期的异步回复到不了新通道。自导航本身以及初始 URL 里的数据仍然可行。
· allowNetwork=false 会挡住脚本可见的网络访问,但发往白名单源的资源元素请求仍然可行。cdnAllowlist 为空会挡住外部资源请求,但挡不住自导航。
完整变更日志:
v0.2.92026-10-22
· 变更内容
· fix(release):等待注册表传播,最长 10 分钟
· docs:新增 CONTRIBUTING 指南
· test(eval):新增成对的展示路由用例(F 组)
· fix(eval):在替代仓库改动的 widget 上评判 F3b
· fix(render):说明 root 为必填项以及如何添加
· docs:记录展示路由研究并保留当前指引
· docs:声明 storefront 截图
· chore(release):0.2.9
完整变更日志:
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。
README
由 DeepSeek 最新模型翻译生成English · 中文
演示 · 快速开始 · 如何选择 · 组件 · 沙箱组件 · 扩展 · 安全 · 配置 · 质量 · 开发
为 DeepSeek Harness(DSH)提供生成式、可交互的 UI。用户用自然语言提问,Agent 自行决定怎样作答:
- 普通文本:用文字最清楚的时候;
- 原生组件:看板、数据表格、图表、散点图与热力图、时间线、带滑块的函数图像、KaTeX 公式、Mermaid 流程图、代码差异、文件树、JSON 树、表单和选择题卡片;
- 完全自定义的沙箱实时组件:Three.js 三维场景、Canvas 模拟、小应用。
界面随回答流式、渐进地出现。排序、筛选、滑块、旋转、缩放、切换标签页都在浏览器内即时响应,只有显式操作(按钮、表单、选择题、Bridge.sendPrompt)才会回到 Agent,可以在当前会话中继续,也可以新开会话。
本插件把 CopilotKit OpenIntelligentUI 的思路(Open Generative UI + A2UI 风格声明式组件)移植到 DSH 自带的扩展点上,不依赖 CopilotKit、LangGraph 或外部路由服务。
✨ 亮点
🧠 自主决策
无需任何命令。每一轮由 Agent 依据系统提示,自行选择文本、原生组件或实时组件。
展开完整文档(README 剩余 1 节)
English · 中文
演示 · 快速开始 · 如何选择 · 组件 · 沙箱组件 · 扩展 · 安全 · 配置 · 质量 · 开发
为 DeepSeek Harness(DSH)提供生成式、可交互的 UI。用户用自然语言提问,Agent 自行决定怎样作答:
- 普通文本:用文字最清楚的时候;
- 原生组件:看板、数据表格、图表、散点图与热力图、时间线、带滑块的函数图像、KaTeX 公式、Mermaid 流程图、代码差异、文件树、JSON 树、表单和选择题卡片;
- 完全自定义的沙箱实时组件:Three.js 三维场景、Canvas 模拟、小应用。
界面随回答流式、渐进地出现。排序、筛选、滑块、旋转、缩放、切换标签页都在浏览器内即时响应,只有显式操作(按钮、表单、选择题、Bridge.sendPrompt)才会回到 Agent,可以在当前会话中继续,也可以新开会话。
本插件把 CopilotKit OpenIntelligentUI 的思路(Open Generative UI + A2UI 风格声明式组件)移植到 DSH 自带的扩展点上,不依赖 CopilotKit、LangGraph 或外部路由服务。
✨ 亮点
🧠 自主决策
无需任何命令。每一轮由 Agent 依据系统提示,自行选择文本、原生组件或实时组件。
⚡ 流式渐进
JSON 还在生成,组件就已出现。实时组件在同一个 iframe 中 morph 并原地定稿,不重建、不闪烁。
🖱️ 本地优先
排序、搜索、筛选、分页、导出、悬停、滑块、旋转、标签页都在浏览器内完成,不调用模型。
🧩 26 种组件
从卡片、标签页到数据表格、Scatter、Heatmap、Plot、Math、Mermaid、CodeDiff 和 Choice,渲染前先校验。
🔒 默认沙箱隔离
不透明源 iframe、严格 CSP、带 token 的消息校验、限流的 Bridge,全部在真实浏览器中实测。
💾 状态不丢失
标签页、排序、筛选、表单值、滑块和 UI.state 在回合折叠、原位修改、页面刷新、中途停止后都能恢复。
🎬 演示
真实 DeepSeek 模型,端到端
https://github.com/user-attachments/assets/e4eb0adc-659e-4c80-b473-449aa42ca00f
质量基线的全部 11 个浏览器用例,由 deepseek-flash 在 DSH Web 0.2.0-rc.1 中现场生成(2026-10-16):纯文本、图表、数据表、表单回传、Plot、Three.js 与「让模型修复」、停止 → 重新生成、两轮原位修改、Fast 3G、CDN 不可达、手机宽度。失败原样保留并标为 ✗。由 DeepSeek 鲸鱼娘解说(见致谢)。完整视频:docs/assets/real-model/demo.mp4(2 分 27 秒)。
🖼️ 结果一览(各用例截图)
| 多系列柱状图:✗(调用中途被截断) | ui_patch 两轮原位修改:✓ |
| 图表 | 原位修改 |
| 图表内容正确,但卡片显示「生成已中断」 | 「改成折线图」→「加上小程序 30/45/60/80」:同一张卡片,第 3 版 |
| 提交表单 → 模型使用提交的值:✓ | 阻尼振动 Plot,滑块实时重绘:✓ |
| 表单回传 | Plot |
| Three.js:✗,再由「让模型修复」修好 | 中途停止 → 重新生成:✓ |
| Three.js 修复后 | 重新生成 |
| Fast 3G、禁用缓存:✓ | CDN 不可达:✓(按设计降级) |
| 弱网络 | 无网络 |
| 手机宽度(390 px):✓ | 可排序数据表:✗(Agent 去查资料了) |
| 移动端 | 数据表 |
无法播放视频的页面(如 npm)可以看 GIF 版:demo.gif。
功能一览
以下视频都是在 DeepSeek Harness 桌面版中通过 magpie 调用真实 DeepSeek 模型现场录制的,没有脚本化回答。镜头跟随鼠标,放大到正在操作的区域;等待模型回答的部分做了快进(右上角显示倍速)。
Choice:选一个方案,在当前会话中继续或新开会话 · DeepSeek-V4.1-Flash
https://github.com/user-attachments/assets/1317993c-17b1-4fca-9356-c365afcc6101
Table 数据表格:按类型排序、搜索、按列筛选、分页、导出 CSV · DeepSeek-V4.1-Flash
https://github.com/user-attachments/assets/be9c74e4-2ed3-402c-bd08-d57ea8516eec
Scatter 与 Heatmap:悬停、点按、键盘查看;缺失值用斜线标出,不显示为 0 · DeepSeek-Flash
https://github.com/user-attachments/assets/cb575946-bab5-4551-9621-489dee55df07
CodeDiff、FileTree 与 JsonView:代码按文本显示、上下文可折叠、复制 JSONPath · DeepSeek-Flash
https://github.com/user-attachments/assets/75900041-3880-4e21-97f8-21bfd41872ad
🚀 快速开始
需要 DeepSeek Harness 0.1.7 – 0.2.x(>=0.1.7-rc.1 <0.3.0)和 Node.js ≥ 22.13,Windows、Linux、macOS 均可。安装不需要编译:npm 包自带预构建的浏览器端 bundle,没有任何安装脚本。
dsh plugin --profile web add deepseek-harness-intelligent-ui
重启 DSH Web(dsh web),试着提一个需要可视化的问题,例如 “按渠道对比 Q1–Q4 营收” 或 “让我在 3D 里探索 x²+y²+z²=2Rz”。桌面版在 Plugins → Add plugin 中输入同一个包名即可。
引导式安装器会先检查 Node、dsh 版本、pnpm 和 profile,再执行同样的 dsh plugin add:
npx deepseek-harness-intelligent-ui install # 可选 --profile <名称>、--dsh <路径>、--dry-run
npx deepseek-harness-intelligent-ui doctor # 只诊断,不做修改
| 操作 | 命令 |
| 升级 | dsh plugin --profile web add deepseek-harness-intelligent-ui@latest |
| 试用预发布版(存在 next 标签时) | dsh plugin --profile web add deepseek-harness-intelligent-ui@next |
| 固定版本 | dsh plugin --profile web add deepseek-harness-intelligent-ui@0.2.7 |
| 卸载 | dsh plugin --profile web remove deepseek-harness-intelligent-ui(或 npx deepseek-harness-intelligent-ui uninstall) |
| 从源码目录安装 | dsh plugin --profile web add file:/path/to/deepseek-harness-intelligent-ui |
🩺 常见问题
- 提示 pnpm was not found:DSH 用 pnpm 安装插件。运行 corepack enable(Node 自带)或 npm i -g pnpm。
- 提示 … is incompatible with dsh X:当前 DSH 版本不在支持范围内。升级 DSH(npm i -g @deepseek-ai/dsh@latest),或在兼容性文档里找支持该版本的插件发行版。
- 从 0.1.x 升级(以前用 file: 安装的 dsh-intelligent-ui):先运行 dsh plugin --profile web remove dsh-intelligent-ui。新旧两个包会插入同一个 intelligent-ui 行,doctor 能检测到这种冲突。
- 界面没有出现:安装后要重启 DSH Web,并确认启动的是安装插件时指定的 profile。
兼容性。 CI 在每次推送和每晚定时任务中,用 Windows、Linux、macOS 对 DSH 0.1.7-rc.2、0.2.0-rc.1、latest、next、alpha 安装打包后的插件并运行完整的浏览器 E2E,DSH 一发新版就能发现问题。详情和本地验证记录见 docs/compatibility.md。
🧠 Agent 如何选择呈现方式
插件注入一段系统提示(src/guidance.js),让模型每一轮自行选择:
- 普通文本:寒暄、简短事实、解释说明、要复制的代码、工作区内的编程任务。
- ui_render:结构化内容,例如对比、要探索的数据、看板、流程、公式、函数、代码评审、在几个方案中做选择、收集输入。
- ui_render_widget:组件目录画不出的东西,例如三维、模拟、动画、游戏、自定义工具。
- 本地优先:凡是能在浏览器里算出来的,都必须即时更新,不调用模型。
这些规则为什么在与重写版决策顺序做真实模型 A/B 后被保留,以及路由如何评测,见 docs/presentation-routing.md。
/ui <需求> 可强制以 UI 作答。
| 工具 | 适用场景 | 渲染方式 |
| ui_render | 结构化回答 | 固定目录中的原生 React 组件,随 JSON 流式渐进渲染 |
| ui_patch | 修改之前显示的界面 | 组件级操作,未改动的组件保留交互状态(详情) |
| ui_render_widget | 自定义可视化、三维、模拟、小应用 | 不透明源沙箱 iframe 中的 HTML/CSS/JS:先 CSS,再实时 morph HTML,最后执行 JS,全程一个 iframe |
🧩 组件目录(ui_render)
| 类别 | 组件 |
| 布局 | Card、Stack、Grid、Tabs(支持键盘操作) |
| 文本与提示 | Text(markdown 子集)、Code、Alert、Badge、Divider |
| 数据 | Stat、Progress、List、Timeline;Table 数据表格:按类型排序(数值、ISO 日期、布尔)、搜索、按列筛选、分页、CSV/Markdown 导出 |
| 图表 | Chart(柱状、折线、面积、饼图;可堆叠,图例显隐,悬停/点按/键盘提示,数据导出)、Scatter(连续坐标散点图)、Heatmap(顺序或发散色标,缺失值单独标识) |
| 地图 | Map(地点标记、路线、分组;拖动/键盘平移缩放;内置离线世界轮廓,或使用你配置的瓦片底图) |
| 媒体 | Image 与 Gallery(https 图片,懒加载且不发送 Referer,说明文字与可点击署名,模态大图查看器支持方向键;加载失败时显示图片描述);Video(YouTube / Bilibili / Vimeo 链接用官方播放器,用户点击播放后才加载;或 https 直链 .mp4/.webm 原生播放;始终附原视频链接) |
| 数学与图示 | Plot(y = f(x),拖动滑块即时重绘;安全表达式编译器,不用 eval)、Math(KaTeX)、Mermaid |
| 代码与结构 | CodeDiff(多文件新旧对比或 unified patch)、FileTree(状态徽标)、JsonView(JSONPath、复制) |
| 交互 | Button、Choice(选择题卡片)、Form(文本、数字、范围滑块、下拉、勾选、日期、多行文本) |
- 先校验再渲染。 DSH 的工具 schema 不支持递归,所以界面以扁平节点列表加 id 引用传输。Host 会拒绝未知类型或属性、悬空或重复的 id、环、形状不一致(图表系列、热力图行列)、非有限数值、无法编译的 Plot 表达式、越界的地图坐标和超限数据,返回 ok:false 并附出错路径,模型据此修正后重试。
- 只渲染文本。 单元格、代码、JSON 和标签都作为 React 文本渲染,不作为 HTML。CSV 导出遵循 RFC 4180,带 UTF-8 BOM,并防止表格公式注入。
- 可访问、自适应。 图表可获得焦点并用键盘查看,树形组件使用 role=tree,触屏上控件更大;图表按卡片实际宽度布局,手机上坐标轴文字依然清晰。
- Math 与 Mermaid 在与组件相同的沙箱中从 CDN 白名单加载,CDN 不可达时显示静态降级;使用离线资源包可完全离线。
选择题与新开会话
Choice 显示一个问题、若干选项卡片和两个按钮。在当前会话中继续会把选中项的 prompt 作为下一条消息发送;新开会话会在同一工作区创建新会话、提交该 prompt 并跳转过去。新会话不会复制当前对话历史,所以每个选项的 prompt 都是自包含的。Button 设置 sessionTarget: "new" 也能做到同样的事。启动过程是幂等的:双击、失败后重试或刷新页面都不会把任务启动两次。
后续组件(Map、Calendar)的路线图与设计说明:docs/component-roadmap.md。
🔁 原位增量更新(ui_patch)
用户要求修改之前显示的界面时(例如“把柱状图换成折线图,其余不变”),Agent 按组件 id 打补丁,不必重新发送整棵组件树。
- 标识: 每次 ui_render 的结果都会给出界面的 uiId 和版本号 1;每个被接受的补丁都会给出新版本号和组件的 id:类型 概览。
- 操作: setProps(合并,unset 删除)、replaceNode、insertChild、removeNode,按顺序执行,要么全部生效,要么全部不生效;新版本还要通过与全新 ui_render 相同的校验。
- 并发: baseVersion 为必填;基于旧版本的补丁会被拒绝并告知当前版本,补丁不会并行执行。
- 作用范围: Host 不保存状态,而是重放本会话自己的历史来重建当前版本,所以补丁只能作用于同一会话中的界面。
- 交互状态: 组件 id 在各版本间不变,未被替换的组件保留排序、筛选、标签页、表单输入、提交锁定和滑块位置;被替换的组件状态重置。
- 显示: 补丁流式生成时,上一版本保持可用;成功后新版本显示在回复下方,旧副本收起为“已更新为第 N 版”。被拒绝、失败或中断的补丁不改动任何内容。
- 沙箱组件会被重新渲染而不是打补丁,UI.state 依然保留。
🪟 沙箱组件(ui_render_widget)
字段遵循 OpenIntelligentUI 的流式协议,顺序固定:title、initialHeight、placeholderMessages、css、html、jsFunctions、jsExpressions。css 完成前显示占位文字;随后打开预览 iframe,把部分 HTML 实时 morph 进去(idiomorph);参数完整后,在同一个 iframe 内原地定稿并执行代码。
| 运行时辅助(全局 UI) | 作用 |
| UI.three(el, opts) | renderer、场景、灯光和 OrbitControls(拖动旋转,滚轮或双指缩放),按需渲染并自适应尺寸 |
| UI.canvas(el, draw) | 高清 2D 画布,尺寸或主题变化时自动重绘 |
| UI.state / UI.setState() | 持久化状态;带 id 的输入控件自动保存并恢复 |
| UI.color('accent') / UI.css() | 不透明主题色(可用于 three.js 和 Canvas)/ 原始 CSS 值 |
| UI.onTheme(cb)、UI.scheme、UI.reducedMotion | 响应主题变化与减少动效偏好 |
| .ui-row、.ui-control、.ui-card、.ui-stage | 辅助样式类 |
- Bridge: Bridge.sendPrompt({ text }) 在宿主应答前禁用触发它的控件;Bridge.openLink({ url }) 打开链接;Websandbox.connection.remote.* 为兼容 OpenIntelligentUI 而保留。
- 依赖库: 通过 importmap 从 esm.sh 引入 three、three/addons/…、d3、chart.js/auto、gsap、canvas-confetti。
- 错误恢复: 出现脚本错误时显示错误数量,并提供“重新加载”和“让模型修复”(把错误发给 Agent)。
显示位置与状态保持
- 回合进行中,UI 在工具调用处内联显示;从准备、执行到结果始终是同一个组件实例。
- 回合结束后,DSH 会把工具调用折叠进“过程”区域,插件把 UI 重新显示在回复下方,内联处改为一行提示。
- 交互状态按界面保存在内存和 localStorage 中(有上限),移到回复下方或刷新页面后都会恢复;UI 本身从持久化的会话日志重建。
- 中途停止时保留已完成的部分(组件的静态预览或已生成的组件),并提供提示和“重新生成”;即使 DSH 丢弃了仍在流式输出的调用也是如此。
🔌 扩展
| 第三方组件 | 可信伴随插件可注册带版本和命名空间的组件,Host 与浏览器共用 props 校验,支持 React 渲染与禁用、卸载。模型输出不能注册或加载代码。扩展接口与 GitDiffViewer 模板 |
| 受控数据与动作 | Table 与 Chart 可共享按会话隔离的只读 dataRef,在本地搜索、筛选、排序和分页。可信宿主可注册经 Schema 校验的动作,只有用户原生点击才会执行,并有权限检查、写操作确认和幂等回执。接入文档 |
| 便携渲染器 | renderer/renderer.js 可在 DSH Web 之外渲染已接受的 ui_render、ui_patch 和沙箱组件,例如在移动端 WebView 中。远程客户端约定 |
| 离线资源 | 可选资源包内置锁定版本的 KaTeX/字体、Mermaid、Three.js、D3、Chart.js 和 canvas-confetti,公式、流程图和标准 3D 场景无需 CDN。离线资源包 |
🔒 安全模型
- 隔离: 配合 srcdoc,不加 allow-same-origin。E2E 在浏览器中实测:parent.document、localStorage、document.cookie 均抛出 SecurityError,fetch 被拦截,window.origin 为 "null"。
- CSP: default-src 'none';脚本、样式、字体、图片只能来自 cdnAllowlist;未开启 allowNetwork 时 connect-src 'none';form-action 'none'、base-uri 'none'。逐通道实测矩阵见 docs/widget-csp-audit.md,并可运行 npm run e2e:security。
- allowNetwork=false 能挡与不能挡什么: 它能拦截 fetch、XHR、WebSocket、EventSource、sendBeacon 和 ;但不能阻止 、、、@font-face、 向允许名单内的来源发起请求,而本实现将 cdnAllowlist 转为仅含来源的 CSP 条目,不限制资源路径——允许名单内的 CDN 仍可能在资源 URL 中看到组件数据。要阻止外部资源请求,请设 cdnAllowlist: [](离线包已如此);它仍不能阻止组件自身导航,以及在首次导航 URL 中携带数据。
- 导航: 绑定原文档的 MessageChannel 可阻止替换文档接收宿主数据。后续 iframe load 会移除外部页面;未完成的响应可延迟这一步界面移除。首次自身导航请求仍可能发生。iframe sandbox 已阻止顶层导航、window.open 和文件下载。跨来源下载链接仍可能先触发自身导航请求,再由浏览器阻止保存响应。
- 消息校验: 首次握手校验 iframe 来源与每个文档的新 token,再接收其转移的端口。后续消息仅走该端口并校验 token/格式;窗口 RPC 与旧端口均被拒绝(E2E 实测)。
- sendPrompt 限制: 挂载后 1 秒内拒绝,2 秒内最多一次,长度受 sendPromptMaxChars 限制,以普通用户消息排队发送。
- openLink: 只允许 https,可用 openLinkAllowedOrigins 进一步限制。
- 组件目录: 文本作为 React 元素渲染,不作为 HTML;Plot 表达式只能调用固定的数学函数,无法使用 eval、Function 或访问属性;新开会话和宿主动作都要求用户原生点击。
⚙️ 配置
安装后 bundle patch 会自动插入 intelligent-ui 这一行。要修改配置,在 profile 的 cordis.patch.yml 中添加:
- id: intelligent-ui
config:
allowNetwork: true
cdnAllowlist: [https://esm.sh, https://cdn.jsdelivr.net]
| 配置项 | 默认值 | 含义 |
| enableCatalog | true | 注册 ui_render 和 ui_patch |
| enableWidget | true | 注册 ui_render_widget |
| injectGuidance | true | 注入“何时使用 UI”的系统提示 |
| cdnAllowlist | esm.sh、jsdelivr、unpkg | 组件(以及 Math/Mermaid)可加载资源的来源 |
| allowNetwork | false | 允许组件对上述来源发起 fetch 和 WebSocket。关闭时资源类元素仍可访问这些来源;要阻止外部资源请求(仍可发生自身导航)请把 cdnAllowlist 设为空 |
| maxWidgetHeight | 2400 | iframe 最大高度(px) |
| maxWidgetBytes | 400000 | 超过此大小的组件会被拒绝 |
| sendPromptMaxChars | 4000 | 组件、按钮、表单、选择题单条消息的最大长度 |
| openLinkAllowedOrigins | [] | 非空时,openLink 只能打开这些来源 |
| mapTileUrl | '' | Map 的栅格瓦片模板,例如 https://tile.openstreetmap.org/{z}/{x}/{y}.png(https,含 {z}/{x}/{y})。留空则显示离线轮廓。请遵守瓦片服务商的使用政策 |
| mapTileAttribution | '' | 瓦片地图上始终显示的署名,例如 © OpenStreetMap contributors |
| mapTileMaxZoom | 19 | 瓦片服务商提供的最大缩放级别 |
| mediaAllowedOrigins | [] | 非空时,Image/Gallery/Video 只从这些 https 来源加载(平台视频按播放器来源,如 https://www.youtube-nocookie.com、https://player.bilibili.com),其他来源显示占位提示。留空:允许任意 https 来源 |
📊 真实模型质量基线
工具调用的参数能解析,不等于用户真正拿到了可用的界面。npm run eval:real 把三层结果分开统计,任何一层通过都不能代替另一层。
| 层 | 证明什么 | 最新 · 2026-10-16 · deepseek-flash |
| Mock E2E | 渲染、流式、交互、持久化与隔离(回答是脚本化的) | 30 / 30 |
| 真实模型 · API | 选对工具、首次就给出合法参数、渲染出的界面包含所要求的组件和数据 | 30 / 32(94%) |
| 真实模型 · 浏览器 | 模型生成的界面在真实 DSH Web + Chrome 中可用:能渲染、能交互、经得起停止/恢复和弱网,控制台无错误 | 自动化 9 / 11人工复核后 8 / 11 |
| 耗时(真实模型) | p50 | p95 |
| 首次出现可见预览 | 7.6 s | 70.2 s |
| 界面生成完成 | 11.8 s | 73.4 s |
| 流结束后的浏览器端执行 | 26 ms | 2.9 s |
长尾来自体积较大的 Three.js 组件(预览开始前要先写出 10–20 KB 代码)。失败都是模型与 Agent 的真实行为:调用中途被截断、Agent 去上网查资料而没有出界面、Three.js 作用域错误经「让模型修复」修好、首次参数无效后重试改对。各用例、检查项与完整结论见 docs/real-model-eval.md。
▶️ 如何运行
密钥只从环境变量读取;如果报告里仍含有密钥,运行会拒绝写出报告。
export DEEPSEEK_API_KEY='<your-key>' # PowerShell:$env:DEEPSEEK_API_KEY = '<your-key>'
npm run eval:real # Mock E2E + API + 浏览器;任何失败都以退出码 1 结束
npm run eval:real -- --repeat 3 # 单用例成功率与 p50/p95
npm run eval:real -- --record && npm run eval:demo # 录制并剪辑演示视频
| 选项 | 作用 |
| --stage mock,api,browser | 只运行部分层(默认 all);A–F 选择 API 类别(F:成对的呈现方式决策用例,#58) |
| --only B3,R-chart | 只运行这些用例 |
| --keep-other-layers | 保留本次没有运行的层或用例,各自保留原来的日期 |
| --append | 配合 --only:把重跑结果作为额外样本加入,绝不用一次侥幸成功覆盖失败 |
| --rescore | 用当前断言、基于已保存的对话记录重新判定上一次 API 运行,不调用模型 |
| --report <file.json> | 把报告写到其他文件,例如每个提示词版本一份,用来对比基线与候选提示词 |
| DEEPSEEK_EVAL_MODEL | 模型 id(默认 deepseek-flash) |
GitHub 上的 Real-model eval 工作流可按需手动触发,使用仓库密钥 DEEPSEEK_API_KEY 运行同一条命令;用 deepseek-flash 完整跑一遍约花费 ¥1.5。
🔬 每个用例检查什么
API 阶段(scripts/eval/api-stage.mjs,16 个用例,断言 v3;每条要求单独成为一项检查):
- 纯文本(A1–A4): 不调用界面工具,给出有内容的回答。
- 图表与数据表(B1–B3、B5): 按含义识别的指标卡;包含全部五列的可排序表格;含 Q1–Q4、同时有线上与线下两个系列的柱状图;至少 4 个里程碑的时间线。
- 表单(B4、D1): 滑块、复选框和下拉选择;D1 按浏览器方式提交,并要求后续回答使用提交的值。
- 数学 Plot(C2): 三个滑块且都出现在表达式中,函数形状为 exp(…)·sin/cos(…)。
- Three.js 与组件(C1、C3、C4): 使用 UI.three() 或 import("three"),有动画、光照、启动/暂停和参数控件。
- 多轮修改(D2、D3): 新增一列且每个值都正确、旧值保留;柱状 → 折线,再按准确数值加入第三个系列。
- 呈现方式决策(F,尚未进入已记录的运行): 21 个成对用例,主题不变、只改变任务(解释 vs. 拖动参数、解释 Three.js vs. 对话内可旋转场景、可复制代码 vs. 修改仓库、Markdown 表格 vs. 用户数据的可搜索表格、写公式 vs. 推导中插入曲线、结尾 Choice vs. 每节一张图),另有必须保持已筛选表格不变的 patch、3D 回合之后的纯文本限制,以及没有数据源的实时数据请求。no-ui 失败表示不必要的 UI,needs-ui 失败表示漏掉了 UI。详见 #58。
浏览器阶段(scripts/eval/browser-stage.mjs,11 个用例,每个都在新会话中):纯文本不创建卡片;图表有图例、Q1–Q4 和本地悬停;数据表重新排序不调用模型;用真实鼠标键盘填写并提交表单;Plot 滑块重绘;Three.js 画布确有内容(像素统计)且可拖动,失败时尝试「让模型修复」;停止 → 预览 → 重新生成;两轮原位修改;Fast 3G;屏蔽 CDN;390 px 手机宽度。每个用例都记录控制台错误,每张截图都经过人工复核。
🛠 开发与验证
npm install
npm run build # client-src/ → client/client.js 与 renderer/renderer.js
npm test # 单元与组件测试(vitest)
npm run typecheck
npm run e2e:all # 构建 → 安装到临时 DSH 目录 → 脚本化模型 + 真实 DSH Web → 浏览器检查
npm run e2e:controlled # 受控数据与动作(真实 Chromium)
npm run e2e:extensions # 第三方组件模板(真实 Chromium)
npm run e2e:offline # 断网环境下的离线资源包
npm run smoke -- --spec ./deepseek-harness-intelligent-ui-<版本>.tgz # 对打包结果做安装冒烟测试
npm run demo:features # 在 DSH 桌面版中重新录制功能演示视频
npm run docs:art # 重新生成 README 插图
- 目录结构: src/ 是 Host 端(纯 ESM,无需构建);client-src/ 是浏览器端(TSX,用 esbuild 打包)。client/client.js 与 renderer/renderer.js 提交到仓库并随包发布,npm、file: 和 git 安装都不需要构建;产物过期时 CI 会失败。不要添加 prepare/postinstall 脚本,DSH 的 pnpm 会拦截插件构建脚本。
- E2E 需要 Chrome(可用 CHROME_PATH 指定)和 PATH 中的 dsh(可用 DSH_BIN 指定),可在 Windows、Linux、macOS 上运行。--spec <tgz> 测试打包结果,--record 重新录制脚本化演示,E2E_DATA_ONLY=1 / E2E_SESSION_ONLY=1 只运行其中一组。
- 功能演示视频: 以 --remote-debugging-port=9333 启动桌面版并选好模型,然后运行 npm run demo:features(见 scripts/demo/)。
✅ 浏览器 E2E 检查什么(scripts/e2e/browser.mjs)
- 普通问答保持纯文本;看板流式渐进出现。
- 图表悬停、表格排序、标签页都在本地完成;表单回传后得到新界面。
- ui_patch 把图表从柱状改为折线:无效的首次尝试被拒绝,旧副本收起,状态保留(刷新后也保留)。
- 组件预览在同一个 iframe 中定稿;Three.js 场景能渲染、旋转、缩放;R 滑块在本地生效;Bridge.sendPrompt 能往返。
- KaTeX 与 Mermaid 能渲染;Plot 滑块在本地生效;早先的界面保留状态。
- 停止 → 静态预览 → 重新生成;深色主题;手机宽度无溢出;刷新后恢复所有界面与状态。
- 沙箱隔离,伪造消息被忽略。
- 数据组件: 搜索加范围与日期筛选、CSV 内容与防公式注入、散点图悬停、热力图键盘操作区分 0 与缺失值、CodeDiff 不执行 HTML,以上都不调用模型。
- 新开会话: 原生按钮只启动一个独立会话,不复制历史。
- 控制台没有插件错误。
📦 发布流程(维护者)
1. 开一个 chore: prepare x.y.z release PR:在 CHANGELOG.md 中新增 ## [x.y.z] 小节,运行 npm version x.y.z --no-git-tag-version 和 npm run build,更新 README 中的固定版本示例,并用 npm run release:check 检查。
2. CI 通过后合并。
3. 在合并提交上打 vx.y.z tag 并推送。Release 工作流会运行 CI 矩阵,通过 Trusted Publishing 带 provenance 发布到 npm(预发布版使用 next 标签),在三个系统上对已发布的包做冒烟测试,并用 CHANGELOG 的对应小节创建 GitHub Release。
OIDC 与仓库设置见 docs/releasing.md。
📚 文档
| 文档 | 内容 |
| compatibility.md | 支持的 DSH、Node 与操作系统版本;CI 测试范围 |
| component-roadmap.md | #17 交付的组件;Map 与 Calendar 设计提案 |
| component-extensions.md | 第三方组件接口与模板 |
| controlled-data-actions.md | 宿主数据绑定与 Schema 校验的动作 |
| portable-renderer.md | 在 DSH Web 之外渲染 |
| offline-resources.md | 离线 KaTeX/Mermaid/Three.js 资源包 |
| real-model-eval.md | 真实模型评测:用例、检查项与结论 |
| releasing.md | 发布完整性与 npm Trusted Publishing |
| CHANGELOG.md | 各版本变更 |
已知限制
- 默认在线包的公式、Mermaid 与组件导入库依赖可达的 CDN。离线资源包支持公式、Mermaid 和标准 Three.js 场景;其他 Three.js 插件、GSAP、外部媒体不包含在内。资源加载失败时会显示明确的降级提示或脚本错误。
- 交互状态保存在当前浏览器的 localStorage 中,不跨设备同步。
- 流式中途被丢弃的调用按回合起止时间归属;如果远程 DSH 主机与浏览器的时钟偏差较大,这张卡片可能不显示。
致谢
概念、流式组件协议和部分提示词来自 CopilotKit/OpenIntelligentUI(MIT),见 THIRD_PARTY_NOTICES.md。
担任端到端演示解说的 DeepSeek 鲸鱼娘(共 26 个姿态)来自 Sutera-Diffusus/dsh-whale-musume(MIT © Sutera-Diffusus,立绘作者 @SuteraWu)。原始文件及许可证见 scripts/eval/demo/assets/whale/,不包含在 npm 包中。
本项目采用 MIT 许可。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
dreamfarer-space/deepseek-harness-intelligent-ui
演示 · 快速开始 · 如何选择 · 组件 · 沙箱组件 · 扩展 · 安全 · 配置 · 质量 · 开发
相关插件 · UI / 主题
破甲增强版JeffKeeping/dsh-purge-plus
dsh-purge 的非官方分支fork:适配 DeepSeek Harness 0.2.1-rc.2、破甲内核…
★ 387已汉化DeepSeek 客户端
71.9
无代码业务系统平台nocobase/nocobase
NocoBase 是什么
★ 24,804已汉化DSH
71.8
1Panel 服务器面板1Panel-dev/1Panel
全球 250 万+ 自托管用户共同喜爱。
★ 37,344已汉化DSH
71.5
终端编码代理esengine/DeepSeek-Reasonix
· 指南 · ACP · 扩展开发 · 规格 · 官方网站 · Discord · QQ
★ 36,045已汉化DSH
71.2
工作状态行动态ccch1mneyyy/working-activity
作者:chimney@ccch1mneyyy。社区项目,非 DeepSeek 官方项目。
★ 664已汉化DSH
71.2
多模型配置管家farion1231/cc-switch
跨平台桌面一体化助手,支持 Claude Code、Codex、OpenCode、DeepSeek Harness 等工具,唯一官网 ccswitch.io
★ 151,202已汉化DSH
71.1
这是你的仓库?认领条目