← 返回列表
未验证
为你的 agent 已经生成的图像提供内联预览——在消息流中,支持任意格式。
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/8 · 已提供中文文档
综合分
28.6
GitHub 分
28.6
用户评分
—
★ Stars
0
周下载量
—
兼容 / 相关生态插件(非 dsh 原生,请按其对应运行时安装)
git clone https://github.com/tianxia--/Dsh-ImageProview.git信任档位:已验证本站已于 0 天前真实安装成功
- 是什么
- 生态应用(桌面端 / Web 外壳,不以 dsh plugin add 安装)
- 装得上吗
- 本站已真实安装成功(非静态推断)
- 安全吗
- 本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
- 还在维护吗
- 活跃:最近一次提交在 17 天前
档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →
🟢实装验证通过· 2026/9/25
由本站实装验证器在真实 dsh 环境安装成功,非静态推断。
数据截至 2026/9/21(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
由 DeepSeek 最新模型翻译生成dsh-image-preview
npm
license
为你的 agent 已经生成的图像提供内联预览——在消息流中,支持任意格式。
问题所在
agent 读取的图像永远不会到达 Chat 流程。read_image(包括通过 run_code 调用)将其结果作为合成的 user/message 传递,其 source.kind 不是 "user",而 @deepseek-ai/dsh-client-ui-chat 会将每一条此类消息归类为 context 节点:
if (event.data.source.kind !== "user") return { kind: "context", ... }
ContextInjectionRow 没有图像位置,因此图像块被丢弃,只留下其描述符文本:
/tmp/shot.pngimageimage/png image, 840x2289 px, 972428 bytes
你自己粘贴的图像没有问题(source.kind === "user" → UserMessageNodeView → 缩略图 + 灯箱)。只有 agent 的图像会丢失。而且由于 read_image 仅接受 PNG/JPEG/WebP/GIF,HEIC、TIFF、PSD、SVG、ICO、TGA 或 Netpbm 文件根本不会成为附件——它只能以路径的形式出现。
本插件的作用
| 情况 | 位置 | 字节 |
|---|---|---|
| Agent 图像附件(read_image) | 新的 agent-image chat 节点 | 已在持久化附件存储中;无额外 I/O |
| 仅提及图像文件的消息 | 新的 agent-image-path chat 节点 | 宿主路由 /image-preview/meta + /image-preview/file |
两者都通过 renderMessageImages 渲染——即 ChatView 传递给每一个带键节点渲染器的位置——因此缩略图尺寸、加载/重试状态以及全尺寸灯箱都使用官方的 ui-attachment 实现。没有重新实现任何图像 UI,也没有覆盖任何官方组件:conversation Definitions 不是排他的,因此这些行是添加在现有文本行旁边的。
刷新页面,过去的会话也会亮起来:投影会从会话日志中重建。
截图
所有格式,一个宿主路由——下面的每个缩略图都是在浏览器中渲染的真实 /image-preview/file 响应(原生格式逐字节一致,其余转码为 PNG):
formats
同一次往返的像素保真度,解码后与源文件对比(参见实测保真度):
pixel fidelity
格式
逐字节提供(浏览器直接渲染):PNG · JPEG · GIF · WebP · AVIF · BMP · ICO/CUR · SVG
在宿主上转码为 PNG:HEIC/HEIF · TIFF · PSD · JP2/J2K · TGA · Netpbm (PBM/PGM/PPM/PAM) · EXR · DDS · JXL
工具链是 sips(macOS,始终存在)→ magick → convert → ffmpeg,外加内置的零依赖 TGA 和 Netpbm 解码器,这样即使机器上这些工具一个都没有,这两种格式也仍能正常工作。结果缓存在 $DSH_HOME/plugins-cache/image-preview 下,以路径 + mtime + 大小作为键,最多保留 240 条。没有可用转码器的格式会返回 no-transcoder 并且什么都不渲染,而不是渲染出一个损坏的帧。
实测保真度
test/visual.test.mjs 构造一个源图案(纯 R/G/B/Y 色带、一条对角线、一个棋盘格),将其转换为每一种格式,通过 HTTP 走真实路由取回,解码所返回的载荷并与源图比较。每通道平均绝对误差(0 = 完全一致),来自本机:
| 格式 | 以何形式返回 | MAE | |
|---|---|---|---|
| PNG · GIF · BMP | 原生 | 0 | 无损 |
| TIFF · PSD · TGA · Netpbm | PNG | 0 | 无损转码 |
| EXR | PNG | 0.08 | HDR 往返 |
| JP2 | PNG | 3.32 | 有损编解码器 |
| JPEG | 原生 | 7.30 | 有损编解码器 |
| HEIC | PNG | 7.55 | 有损编解码器 |
每一种格式还会与源图的垂直翻转副本以及红/蓝通道互换副本进行比较;在每种情况下,直接比较都以 15–40 倍的优势胜出,这正是用来排除手写解码器实际会犯的那两种错误的手段。内置的 TGA 解码器(左下角原点以及 BGR 顺序)和 Netpbm 解码器单独测得 MAE 为 0,因为在 macOS 上工具链总是先到达 sips,否则会把它们掩盖掉。
此处未验证:DDS(这个 macOS 构建版本的 sips 会写出零字节文件,因此无法生成测试夹具——测试套件将其报告为已跳过)和 JXL(sips --formats 将其列为可读但不可写)。PDF 已在 0.2.0 中移除:文档的光栅化 DPI 是一种选择,而非一种属性,而且实测往返的 MAE 高达 34。
安全模型
浏览器无法读取本地磁盘;此路由可以,因此它默认拒绝:
- 解析后的 realpath 必须位于允许的根目录之下——主机所知的每一个工作区(ctx.workspaceRegistry)、操作系统临时目录、$DSH_HOME,以及你配置的任何 allowRoots。符号链接会在检查之前被解析,因此指向工作区之外的链接无法逃逸出去。
- 扩展名必须在允许列表中,并且开头的字节必须嗅探为真实图像——一个命名为 .png 的 shell 脚本会被拒绝(not-an-image)。
- 只有当客户端提供会话 cwd 时,相对路径才会被解析。
- maxBytes(默认 128 MiB)限制源文件大小;响应会携带 x-content-type-options: nosniff 和 content-disposition: inline。
- 跨站请求会被拒绝。 插件路由挂载在 dsh web 的 cookie 门禁之外——@liustack/modlens 的粘贴路由也会响应未认证的请求——因此本路由并不依赖它。服务器绑定到回环地址,这就只剩下一个可触及的攻击者:你浏览器中某个网页把 指向该路由。它无法读取像素(画布被污染),但加载/错误时序会让它探测出哪些文件存在,因此被 Fetch Metadata 标记为跨站的请求会被拒绝。不发送 Fetch Metadata 的调用方(curl、本地脚本)则会被正常服务:它们本来就能直接读取那些文件。
安装
从本仓库安装
dsh plugin --profile web add github:tianxia--/Dsh-ImageProview
或从 npm 安装(发布后)
dsh plugin --profile web add dsh-image-preview
或从本地检出安装
dsh plugin --profile web add link:/path/to/Dsh-ImageProview
或者手动接入:
~/.dsh/profiles/web/cordis.patch.yml
- insert:
- id: image-preview
name: dsh-image-preview
config:
maxBytes: 134217728 # 可选,默认 128 MiB
allowRoots: [] # 可选的额外根目录
transcode: true # false = 仅原生格式
宿主端挂载路由;浏览器端(lib/client.js)按惰性 CJS 客户端插件协议手写——无需构建步骤,无依赖。
验证
npm test # 164 项检查:50 项宿主路由、15 项真实 HTTP、46 项客户端 bundle、53 项像素保真
宿主测试套件生成 13 个测试夹具(在可用时通过 sips),并用伪造的 req/res 对驱动真实处理器;客户端测试套件用打桩的模块加载器加载真实 bundle,并用从持久会话日志中复制出来的事件形状驱动两个 Definition。
已知限制
- 文本行会保留。 图片行是添加在原始 上下文行旁边,而不是替换它:覆盖官方 context 键意味着要重新实现 ContextInjectionRow(来源标签、折叠状态),却没有任何视觉收益。
- 工具结果不会被扫描。 工具结果中由 bash 打印的路径不会被预览;只有用户/助手消息文本和附件会被扫描。
- 灯箱是官方的那一个——适配视口,无缩放或平移。如果你想要一个带自己围栏语法的可缩放查看器,img-preview 覆盖了那块领域,两者可以共存。
- 转码取决于宿主机。 没有 sips/ImageMagick/ffmpeg 时,就只剩下内置的 TGA 和 Netpbm 解码器。
许可证
MIT