Repository navigation
v0.4.2
0.4.2 — 修正 v4 会话格式下的标记来源(旧写法会卡死整个会话)
⚠️ 如果你在用 0.4.1,请升级。 0.4.1 写的回退标记会让被回退过的那个会话彻底无法继续——每一轮都报「本轮运行失败」,且与所选模型无关(切模型、切回deepseek-v4-flash都无效)。
根因
回退标记是一条 user/message,source 盖的是 { kind: 'plugin', plugin: 'rollback' }。DSH 0.2.0(会话格式 v4)在编码该事件时拒绝 kind === 'plugin':
format v4 message requires a producer-owned source kind
关键在于这次拒绝发生在持久化 drain 里,不在 append 的调用栈上:append 已经返回成功,失败批次却被留在写队列头部,此后该会话每一次写入都重新编码同一批次并抛同一个错。
改动
- 写入端改为 v4 要求的产生者所属 kind:
{ kind: 'plugin:rollback' }。这正是 DSH 自身 v3→v4 迁移给未登记插件分配的拼写(producerKind()→plugin:<name>,并丢掉plugin字段)。 - 新增
src/core/marker-source.ts:标记来源的唯一出处——写入常量、kind 常量与读取判定isRollbackMarkerSource()。 - 读取端同时接受三种拼写:
{ plugin: 'rollback' }、{ kind: 'plugin', plugin: 'rollback' }、{ kind: 'plugin:rollback' }。日志是 append-only 的,而 v4 迁移是把旧标记重写而非丢弃,所以同一个文件里两种拼写并存;只认新拼写会让升级过会话的已回退区段重新可见(幻影轮次,以及「曾创建的文件」误删你后来重建的文件)。 - 不会误判别的插件:
{ kind: 'plugin', plugin: 'compaction' }这类来源不匹配。 - 兼容范围未改:
dsh.engines.dsh仍为>=0.1.5-rc.2。v3 的来源 kind 白名单只作用于 v2→v3 迁移路径,v3 原生准入从不约束user/message的source.kind。
验证
- 单元测试 280 通过 / 0 失败;产物自检 27/27;
lib/*.js重建后哈希逐字节一致(构建可复现)。 - 用宿主自己的 v4 编解码代码(从运行中的 app.asar 原样抽出的
@deepseek-ai/dsh-session-format-v3-to-v4)跑真实计划产物:新拼写在assertV4RowAdmission与encodeEvent两个入口都通过;0.4.1 的旧拼写在两处都被拒,且报文正是上面那条 —— 完整复现了那次故障。
安装
dsh plugin --profile web add -w @nianchu/dsh-rollback装完必须重启 DSH:profile 的 bundle 列表只在启动时组装。
npm 那条路:@nianchu/dsh-rollback@0.4.2(若用国内镜像装不上,.npmrc加@nianchu:registry=https://registry.npmjs.org/)。