Skip to content

v0.1.3 — 删除现在真的落盘(v4 source-kind 修复)

Choose a tag to compare

@kyle123740 kyle123740 released this 27 Sep 02:53
· 16 commits to main since this release

修复:删除现在真的会落盘(0.1.3)

症状:在任意会话(包括全新会话)里删除消息 —— 行立刻消失、占位行出现 —— 重启桌面版后内容在界面和模型上下文里都回来了。

根因(先解码磁盘日志、再把墓碑送进真实持久化后端往返,两步定位):

// dsh-session-format-v3-to-v4
if (typeof value["kind"] !== "string" || value["kind"].length === 0 || value["kind"] === "plugin")
    throw new SessionFormatError("format v4 message requires a producer-owned source kind");

墓碑原先写成 source: { kind: "plugin", plugin: "message-recall", … }。Session.append 不校验这一项,所以事件能进内存日志、客户端拿到它并把占位行画出来;但 flush 时持久化编码器对整批抛错,一条都没写进磁盘。重启从磁盘重建,删除就蒸发了。compaction 的替换不受影响,是因为它声明的是已注册的 compact-checkpoint —— 这也是我一开始误判「机制没问题」的原因。

修法:墓碑改声明 kind: "user"(它本来就是 user 角色的空消息;v4 里 user/message 不要求处于开启的 turn/step 内,所以追加在 turn/end 之后合法),插件身份放到 producer: "message-recall"。客户端两种形状都认,页面上残留的旧墓碑不会失效。

本次改动

  • 新增 scripts/verify-persistence.mjs:把墓碑写进真实 @deepseek-ai/dsh-session-persistence-jsonl 后端的临时目录 → flush → 从磁盘读回,断言「事件全数往返 / 墓碑在盘上 / replace 语义保留 / 重放 surface 与实时一致 / 重开会话不再派生被删文本」,外加一条负向断言把 kind: "plugin" 会被拒绝这件事钉死。npm test 现在三套一起跑。
  • 只读 inspect 动作:不需要活着的 Agent,同时报告「内存日志」与「磁盘日志」(事件数、maxSeq、所有 replace 事件及其 source、按 seq 的类型流水)。这次就是靠它把范围收窄的。
  • 中英 README:写清 v4 的 source-kind 约束、它为什么制造出「重启前正常」的假象,以及这个诊断接口。
  • 移除 profile 侧的热更新行:两个模块实例同时注册 /dsh-message-recall 会被 webserver 以 duplicate exact route 拒绝,导致整条目激活失败。现在只保留插件自带的包名行,Host 改动一律靠重启生效。

升级

dsh plugin --profile desktop add github:kyle123740/dsh-message-recall#v0.1.3

必须重启一次桌面版(Host 半边的模块在进程内缓存,改动不会热加载),然后刷新界面。重启后之前那些「删了又回来」的消息需要重新删一次 —— 旧墓碑从未落盘,磁盘上没有可迁移的东西。