dsh-visual:在 DSH 对话里阻塞式交互视觉卡片

前言

DeepSeek Harness(DSH)里,模型常用纯文本或 Markdown 向用户确认选项、收集表单。用户点选后,结果往往还要靠下一轮对话描述,智能体在同一轮里很难拿到结构化、可编程的反馈。若需要「发一张可点的卡、等用户交还再继续」,就要在宿主侧提供工具与客户端渲染能力。dsh-visual 是面向 DSH 的客户端插件:模型调用 visual 工具发布自包含 HTML 或可拖拽流程图,工具在用户提交前保持 pending,点击、表单、注释与卡片状态一并作为 tool result 返回。

这是什么

dsh-visual(npm 包名 dsh-visual,仓库 MjxUpUp/dsh-visual)由维护者 MjxUpUp 发布,在 SkillHub 目录中归类为客户端插件。它在消息流中渲染真实卡片,而不是助手旁白、聊天预览或 artifact 预览页;卡片内联 <script> 通过 dshVisual 桥接读写状态,与用户操作合并成 JSON 答案。

核心功能

下面介绍 README 中已说明、且与实现描述一致的能力。

阻塞式交互,而非 fire-and-forget。 visual 在用户提交前一直处于 pending,答案作为 tool result 回到同一轮,智能体可据此继续推理。

可脚本化的 HTML 卡片。 样式作用域隔离;脚本以 new Function('dshVisual', source)(bridge) 按卡片编译,并行多张卡互不泄漏。桥接提供 dshVisual.root、dshVisual.setState,以及可选初始 dshVisual.data。

结构化答案。 按钮使用 data-visual-action,输入使用 data-visual-field;页脚另有中性 交还(action: "done"),不隐含批准,审核类场景需自备 approve/revise 等 action。

带锚点的注释。 在卡片内元素上右键可留注释,答案中的 comments 含 selector、label、text,便于模型对应到具体 DOM。

流程编辑器。 传入 flow({nodes, edges})时渲染可编辑画布:拖拽节点、双击改名、连线与删除,编辑后的图随提交返回。

并行与安全边界。 同一轮多张卡各自独立 bridge 与 state。

可取消与超时。 timeoutMs(默认 10 分钟,最长 1 小时)到期返回 action: "timeout";停止本轮返回 action: "cancelled",卡片只读并说明原因。

环境与安装

要求(来自 README):

  • DeepSeek Harness 0.1.0-rc.1 及以上,且低于 0.3(含 prerelease)
  • Node.js 20 及以上

安装与启用:

先执行官方安装命令,再重启 DSH 一次以便加载宿主侧;之后若只改 lib/client.js,刷新页面(README 写 ⌘R)即可。

dsh plugin --profile desktop add dsh-visual

本地开发可链接目录:

dsh plugin --profile desktop add /path/to/dsh-visual
dsh plugin --profile desktop remove dsh-visual   # 卸载

插件以当前 DSH 进程权限运行;安装前请自行查看仓库源码与 MIT 许可证。DSH 生态强调「一切皆插件」;SkillHub 目录页 为社区站点,与 DeepSeek / 幻方无官方从属关系。

典型用法

用自然语言向模型说明即可,例如:

用 visual 发一张发布确认卡,让我选版本并留一句备注

模型侧工具调用大致如下(参数见下一节):

{
  "title": "发布确认",
  "height": 360,
  "html": "<h3>发 0.1.1 到 npm?</h3><textarea data-visual-field=\"note\"></textarea><button data-visual-action=\"approve\">发</button><button data-visual-action=\"hold\">先别发</button>",
  "actions": [{ "id": "approve", "label": "发" }, { "id": "hold", "label": "先别发" }],
  "timeoutMs": 600000
}

用户点击后,工具返回单一答案对象,例如:

{
  "action": "approve",
  "payload": { "fields": { "note": "记得打 tag" } },
  "state": { "checks": ["install"] },
  "comments": [{ "selector": "h3", "label": "h3", "text": "标题再短一点" }]
}

卡片内用脚本维护状态并写回 answer.state 时,可参照 README 中的模式:

<script>
(function (dshVisual) {
  var state = Object.assign({ on: false }, dshVisual.data || {})
  dshVisual.root.querySelector('.toggle').addEventListener('click', function () {
    state.on = !state.on
    this.textContent = state.on ? '开' : '关'
    dshVisual.setState(state)
  })
})(dshVisual)
</script>

工具参数

参数 类型 说明
title string 卡片标题
html string 完整自包含 HTML;样式 scoped,脚本按卡运行
flow object 流程图 {nodes, edges},与 HTML 二选一
data object 初始数据,暴露为 dshVisual.data
height number 初始高度 px,160–900,卡片可自 resize
actions array {id, label},供页脚 chip 与按钮文案
timeoutMs number 等待提交的时长

除 html 与 flow 必须二选一外,其余字段均可选。

适用场景与注意

适合需要在 DSH 桌面会话中做发布确认、带备注的审核、可编辑流程图 handed back 给模型等场景。不适合期望「只展示、不阻塞」或完全脱离 tool 协议的 UI。

注意 DSH 版本须落在 README 声明区间内;超时与取消后卡片只读,模型应处理 timeout / cancelled action。客户端为手写 module-loader bundle,发布包当前版本见 npm(资料中 package.json 为 0.1.1)。

结尾

dsh-visual 把「模型发 UI、用户交结构化结果、同一轮继续」收成一条 tool 链路。目录与源码:

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜