附件
一句话版:
ctx.attachments是持久化二进制附件缝:校验并原子提交不可变图片字节,返回可序列化的ImageAttachmentRef。attachment-local是它的本地文件系统实现,ui-attachment是纯 React 附件原子。
未发送的浏览器草稿不在这里;字节只在用户提交 prompt 或 provider 适配器提交结构化模型输出时才进入持久存储。
一、是什么
附件能力解决一件事:把图片字节持久化,让会话日志只保存内容寻址引用 + 校验过的元数据,而不是浏览器路径、object URL、provider URL 或 base64。两个核心包都是产品包。
| 包 | ctx key | 角色 |
|---|---|---|
attachment | ctx.attachments | 不可变附件引用、图片限制、存储服务 |
attachment-local | (注册在 ctx.attachments 上) | DSH_HOME 下的内容寻址私有存储 |
ui-attachment | 无(零 cordis) | 纯 React 附件原子:草稿图轨、历史图库、大图灯箱 |
二、引用与写入 API(attachment)
ctx.attachments 校验并原子提交不可变图片字节,返回可序列化的 ImageAttachmentRef;消费者从不把浏览器路径、object URL、provider URL 或 base64 持久化进会话事件。
validateImage:跑同一套准入策略但不持久化saveImages(rc.7):按序批量提交——先校验全部成员再逐张写;准入失败零写入,存储失败不返回部分引用(已发布的内容寻址对象可能留下,由后续保留策略收集)saveImage:在每个模型可见会话事件发布之前提交每个已接受的图片readImage:按已记录元数据校验内容寻址对象;调用方可取消,实现观察取消并把取消保留为取消(不翻译成存储失败)
未发送的 composer 图片仍是浏览器拥有的临时草稿。
三、本地存储(attachment-local)
attachment-local 是 attachment 的私有本地实现,默认挂载(base 组合)。
- 对象落在
<DSH_HOME>/attachments/v1/objects/<sha256-prefix>/<sha256>,由不透明的sha256:id 寻址 - 每个进程把家目录祖先逐级 sync 到文件系统根,证明家目录只 durable 一次,避免误把"别的进程已创建但还没 sync 的目录"当作安全边界
- 写入用私有暂存目录、owner-only 文件、synced 临时文件、原子排他硬链接发布、发布路径上的目录 sync(POSIX;Windows 依赖文件系统元数据 journaling),保证上报的引用能扛住崩溃
- 写入准入与读取都完整解码 raster 后才接受格式与尺寸
DSH_HOME走共享路径策略:显式配置 →$DSH_HOME→~/.dsh。会话日志只含引用与校验过的元数据,从不含这个宿主路径readImage把可选取消转发进文件系统读,并保留取消而不是包成ATTACHMENT_READ_FAILED
四、浏览器 UI 原子(ui-attachment)
纯 React 附件原子,零 cordis:所有字符串经属主插件自己的 locale 命名空间解析,不读任何应用状态;ui-conversation 是它的当前消费者。
AttachmentRail:草稿图轨,64px 缩略图单行横滚,隐藏滚动条,溢出用圆形边缘箭头翻页(prefers-reduced-motion: reduce下瞬时滚动)MessageImage/ImageGallery:单张历史图(长边限 240px),加载失败给显式重试;点击打开ImageLightboxImageLightbox:文档级模态预览,Escape / 背景点击 / 关闭控件关闭,卸载时焦点还给打开者
模型可见性:无——它在浏览器渲染纯 React 原子,不进任何模型请求。
五、配置
attachment-local 无显式配置项;存储根由 DSH_HOME 解析。挂载行即默认组合里的:
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
六、已知限制
- 第一版只接受 PNG、JPEG、WebP、GIF
- 保留与垃圾回收延后(恢复/派生会话可能共享不可变对象)
- 通用文件、音频、视频、持久化未发送草稿需要独立的生命周期与 provider 契约
七、验证
# 看 attachment-local 是否装载
dsh web --dump-config | grep -iE "attachment"
# 看附件对象目录(owner-only,按 sha256 前缀分桶)
ls -la ~/.dsh/attachments/v1/objects/