Replies: 6 comments 1 reply
|
你这四类报错我在 0.1.5-rc.1 的源码里都定位到了. 它们不是同一条规则, 但属于同一类问题: 迁移器把「released v0 写入器当年允许写」当成了「今天必须能读」的硬条件.
最后一行值得单独看一眼: 报错原文就是 机制的完整说明(以及「该不该放宽、放宽后诊断落在哪」)我写在 #6144 里了, 它和你是同一个问题, 只是触发字段不同. 这里不重复. 关于你自己救这些会话, 路径本身可行, 三个注意点:
范围说明: 以上都是在 0.1.5-rc.1 源码上静态定位的结果, 我没有在你这类混合语料的会话库上实跑迁移. |
|
我的直接没法开新对话了,工作区也选不了 |
|
四类里的三类我们已经跟进并修了(dsh-session-surgeon,commit
工具只在本机 runtime 自己会跑 v0→v1 迁移(format ≥ 1)时才改文件;四类形状都用官方 0.1.5-rc.1 的 没装插件的话: npx --yes github:xiaoshenming/dsh-session-surgeon repair <会话id> # 先看会改什么
npx --yes github:xiaoshenming/dsh-session-surgeon repair <会话id> --apply # 确认后再写回 |
|
补一个读取侧修复的思路,和楼里已有的"改写会话数据"方案互补。 楼里目前的方向都是改用户文件( 两处都在
关于第 2 点,补充一处精确化:楼上说"两个版本字段一致",更准确的是—— 也就是说 v2 描述符恰好等于省略该字段的 v3 描述符。因此升版本号是严格无损的, 我按上面三处改了 0.1.5-rc.2 的构建产物,用真实生产读取路径 复现脚本(不需要任何受影响的会话数据,干净 mkdir repro && cd repro && npm init -y
npm i @deepseek-ai/dsh-session-format-catalog@0.1.5-rc.2
node repro.mjsimport { sessionFormatCatalog } from "@deepseek-ai/dsh-session-format-catalog";
const HEADER = {
type: "session", version: 0,
id: "session-00000000-0000-0000-0000-000000000000",
createdAt: 1789000000000, delegationDepth: 0,
};
function restore(rows) {
const session = sessionFormatCatalog.createRestore(rows[0], {
recovery: "strict", validation: "current",
});
for (let i = 1; i < rows.length; i += 1) session.decodeRow(rows[i]);
return session.finish();
}
const CASES = {
"1. permission/preset carrying `origin`": [
HEADER,
{ type: "permission/preset", seq: 0, time: 1789000000000,
data: { preset: "workspace-write", origin: "default" } },
],
"2. subagent/descriptor at version 2": [
HEADER,
{ type: "subagent/descriptor", seq: 0, time: 1789000000000,
data: { version: 2, mode: "continuable", provider: "spawn", label: "repro",
agentProvider: "deepseek-official", agentModel: "deepseek-v4-pro" } },
],
"3. control: permission/preset without `origin`": [
HEADER,
{ type: "permission/preset", seq: 0, time: 1789000000000,
data: { preset: "workspace-write" } },
],
};
for (const [name, rows] of Object.entries(CASES)) {
try { const a = restore(rows); console.log(`PASS ${name} -> v${a.header.version}`); }
catch (e) { console.log(`FAIL ${name}\n ${e.constructor.name}: ${e.message}`); }
}0.1.5-rc.2 上的实测输出: 顺带确认一下: 本地补丁(仅为验证用,不是让官方照抄这个文件)补在 - "permission/preset": disposition(["preset"]),
+ "permission/preset": disposition(["preset"], ["origin"]), case "permission/preset":
nonEmptyString(data["preset"], `${label} preset`);
+ if (data["origin"] !== void 0) literalValue(data["origin"], [
+ "default", "inferred", "selection"
+ ], `${label} origin`);
return;+function normalizeLegacySubagentDescriptor(event) {
+ if (event.type !== "subagent/descriptor" || event.data?.["version"] !== 2) return event;
+ return { ...event, data: { ...event.data, version: 3 } };
+}
+
function normalizeReleasedV0Event(event, sessionId, state) {
- const message = normalizeLegacyMessage(normalizeLegacyCompaction(
+ const message = normalizeLegacySubagentDescriptor(normalizeLegacyMessage(normalizeLegacyCompaction(
...
- ), sessionId, state.messageIds);
+ ), sessionId, state.messageIds));该包被整条迁移链共享( |


Uh oh!
There was an error while loading. Please reload this page.
一直在用dsh,很喜欢。遇到一个问题想反馈一下。
问题
从 0.1.1 升级到 0.1.5 之后,一些以前的会话打不开了。网页上提示
failed to observe session ... refuses this format v0 Session,意思是不认这个旧格式。我这边 35 个会话里有 15 个打不开。原因
看起来是新版把老会话升级成新格式的时候检查得太严了——只要是老版本当时写进去、现在不再用的字段,整份会话就直接不给加载。
而且它一次只报一个错,改掉一个又冒出下一个,我一共碰上四种:
origin字段,新版不认,报错。(新版其实已经不用这个字段了,直接忽略掉就行)version: 2,新版只认 3,报错。(这两种格式的字段其实是一样的,当成 3 应该就行)instruction-hint、at-file-mention),新版不认,报错。session/imported标记,新版不认。建议
老版本自己写进去的数据,希望新版能兼容一下:能忽略的就忽略,能直接升级的就升级,不要因为一个字段就让整个会话打不开。
或者至少给个修复的命令,不然这些老会话就永远看不了了。
环境:dsh 0.1.5-rc.1,Windows 11,Node v24.4.1。
再次感谢!
All reactions