前言¶
如果你用 DeepSeek Harness(dsh)做过智能体开发,大概率遇到过这类场景:模型在会话中生成了一张图、导出了一份 CSV,然后告诉你「文件在 output/ 目录下」,或者贴出一个 file:///... 链接。文件确实交付了,但用户要看内容,还得自己去宿主机上翻目录、开本地预览。
dsh-rich-artifacts 解决的就是这一步。它是 Inkotake 维护的一个 DSH 插件,把工作区文件包装成「聊天 Artifact」:光栅图片直接在会话里内联渲染,其他文件变成带下载按钮的文件卡片。模型创建面向用户的交付文件时,调用 publish_artifact 工具即可完成发布。
这是什么¶
一句话定位:一个将工作区文件发布为聊天 Artifact 的 DSH 双端插件(dual-face plugin),带内联图片预览和下载卡片。
几个基本信息:
- 插件名:
dsh-rich-artifacts,作者 Inkotake,版本 0.1.0 - 许可证:MIT
- 仓库:https://github.com/Inkotake/dsh-rich-artifacts
- 目录页:https://www.skillhub.cn/plugins/Inkotake/dsh-rich-artifacts
DSH 的理念是「一切皆插件」,这个插件走的就是标准插件路径:宿主侧注册工具和会话事件,浏览器侧注入 UI。需要说明的是,skillhub.cn 是独立的社区插件目录,与 DeepSeek、幻方没有官方从属关系。
核心功能¶
publish_artifact 工具¶
插件向模型暴露一个 publish_artifact 工具,参数有三个:
path(必填):要发布的工作区文件路径title(可选):显示标题display:auto(默认)/inline/download
auto 模式下,PNG/JPEG/WebP/GIF 会内联渲染,其他文件生成下载卡片;也可以通过 inline 或 download 显式指定呈现方式。
ArtifactStore:内容寻址存储¶
发布的文件进入 ArtifactStore,采用 SHA-256 内容寻址的 blob 存储,元数据单独存放在 ~/.dsh/artifacts/v1/ 下。存储根目录、各类大小上限都可通过配置调整,后面会讲到。
持久会话事件¶
插件注册了一个持久会话事件 artifact/published。设计上只有 artifact 元数据进入会话日志,blob 本体不进日志。这样做的好处是历史会话在 reload / fork 之后,artifact 仍然能正常显示。
有一个实现细节值得注意:artifact/published 是 log-only 事件,而当前 harness 没有提供仓库外会话事件类型的注册入口,所以宿主在启动时会把该事件加入 KNOWN_SESSION_EVENT_TYPES,保证插件安装期间已持久化的会话仍可加载。
HTTP 端点¶
插件提供两个端点:
GET /api/artifacts/:id/content— inline-safe 预览GET /api/artifacts/:id/download— 附件下载
Web UI 呈现¶
浏览器端在每轮对话的尾部(turn-tail)渲染一个画廊:PNG/JPEG/WebP/GIF 内联显示,其他文件显示为带下载按钮的文件卡片。
安全机制¶
发布文件涉及文件系统访问和网络暴露,插件做了几层限制:
- 工作区限制:通过
fs.resolve+fs.contains保证只能发布工作区内的文件 - 末段符号链接拒绝
- 魔数 MIME 嗅探:MIME 类型优先由文件内容决定,扩展名只是次要提示。一个伪装成
.png的 HTML 文件不会被内联 - V0.1 中 SVG/HTML 仅支持下载,不内联
- 文件大小、图像大小、图像像素限制
安装与启用¶
官方安装命令:
dsh plugin --profile web add github:Inkotake/dsh-rich-artifacts
如果需要锁定到某个 commit、做可复现的源码安装:
dsh plugin --profile web add github:Inkotake/dsh-rich-artifacts#<commit>
安装后重启 dsh web(或你安装所用的 profile)即可生效。
仓库中 lib/index.js 是 ESM 宿主插件,lib/client.js 是浏览器 bundle,两者都已提交,所以源码安装不需要额外的构建步骤。如果要自己构建,仓库里有 pnpm install && pnpm run build 的流程,测试可以跑 node tests/artifact-store.test.mjs。
典型用法¶
插件会注册一个 system-prompt section,模型在创建交付文件时会自行调用工具。你也可以直接在对话里要求:
Create a training-loss chart, export it to CSV, and publish both files as artifacts.
模型随后会执行:
publish_artifact({ "path": "output/loss.png", "display": "auto" })
publish_artifact({ "path": "output/loss.csv" })
执行完这一轮后,对话尾部会内联显示 loss 曲线图,并附一个 CSV 的下载卡片。两种类型的交付一次看全,不需要用户去文件系统里找。
配置¶
插件配置写在 profile 的 cordis.patch.yml 里:
- id: dsh-rich-artifacts
name: dsh-rich-artifacts
config:
root: ~/.dsh/artifacts
maxFileBytes: 104857600
maxTurnBytes: 524288000
maxImageBytes: 20971520
maxImagePixels: 40000000
inline:
png: true
jpeg: true
webp: true
gif: true
svg: false
各字段含义与默认值:
| 字段 | 默认值 | 含义 |
|---|---|---|
root |
~/.dsh/artifacts |
Artifact 存储根目录 |
maxFileBytes |
104857600 |
单文件大小上限 |
maxTurnBytes |
524288000 |
每轮上限(V0.1 尚未强制执行,为预留项) |
maxImageBytes |
20971520 |
内联图像大小上限 |
maxImagePixels |
40000000 |
内联图像像素上限(best-effort 解析) |
inline.* |
png/jpeg/webp/gif: true,svg: false |
哪些图像类型可以内联渲染 |
适用场景与注意¶
适合的场景:智能体需要向用户交付可视化产物(训练曲线、图表、截图)或数据文件(CSV、JSON)的工作流。凡是「模型产出文件、用户要看内容」的场合,这个插件都能把交付环节收进聊天界面。
使用前有几点要注意:
- 插件以当前 dsh 进程的权限运行,能访问该进程可访问的文件系统资源。安装前建议先检查源码和许可证,确认符合自己的安全要求。许可证为 MIT。
maxTurnBytes在 V0.1 中是预留配置,尚未强制执行,不要依赖它做每轮体积控制。- SVG 和 HTML 在 V0.1 中只提供下载,不会内联渲染;这是有意为之的设计,涉及 HTML/SVG 的交付场景需要知悉。
- MIME 判定以魔数优先,扩展名只是次要提示,文件扩展名与实际内容不一致时以内联安全策略为准。
结尾¶
dsh-rich-artifacts 做的事情不复杂:把「文件在工作区里」变成「文件在对话里」。存储用内容寻址保证可追溯,会话事件只存元数据保证历史会话可回放,配合工作区限制和魔数嗅探把发布路径的口子收住。如果你的 DSH 工作流经常产出图表和数据文件,值得装上试一试。
- 目录页:https://www.skillhub.cn/plugins/Inkotake/dsh-rich-artifacts
- GitHub:https://github.com/Inkotake/dsh-rich-artifacts