Repository navigation
v2026.10.09.1 — dsh 适配 DSH Desktop 0.2.0-rc.2:会话格式 v4(原生发布)+ Workspace 分组重建
客户端发布:
CLIENT_VERSION2026.10.06.1 → 2026.10.09.1(mcp/updater.py、server/client_update.py),各端经/api/client/manifest自动更新、重启 Agent 后生效。服务端侧只有分发用的版本号变更(client_update.py),无 schema 变更。已部署 236(代码提交2ef7dbe,3 个文件 LF 归一化预检 / 回读 / 编译全通过,11 项线上核对全 PASS;线上真包解出后就地跑test_dsh.py40 项 OK)。
背景:同步下来的会话在新版 DSH Desktop 里打不开
DSH Desktop 0.2.0-rc.2 的会话格式已是 v4(挂载 @deepseek-ai/dsh-session-format-v3-to-v4),而适配器仍宣称「当前世代 = v3」并按 v3 形态发布。dsh 读器对 v3 产物跑 v3→v4 迁移,其目标校验要求 session/title 在 source.kind='user' 时 messageSeqs 必须为空,适配器却给用户标题写了 messageSeqs: [<首个 user/message 的 seq>]。结果是每个带标题的同步会话在桌面打开时都报
「历史加载失败:… session/title messageSeqs must be empty exactly for a user title; source v3 artifact remains unchanged」。
同一版本还修掉两个独立问题:同步进来的会话全部堆在侧栏「未分组」(Workspace 索引只在首启扫描),以及超长路径下的会话被静默丢失。
Fixed(v3 日志过不了 v4 校验 —— 打开即「历史加载失败」)
- 定位用 dsh 自己的读器(非自证):把桌面
app.asar里的dsh/node_modules解出,用其中的dsh-session-format-catalog/dsh-session-query对真实 store 跑listSessions+readSession—— 410 个日志 6 通过 / 404 失败,错误全是上面的标题规则;把单个日志的标题事件改成messageSeqs: []后同法复跑即通过。改掉标题后又暴露出两处 v4 原生接纳(不再经迁移)的问题:连续 user 行会让上一回合悬空(turn/start does not open the expected turn)、首行即 assistant 的会话缺少受保护的首个 system head(system/message requires a protected first surface head)。 - 修复(
mcp/adapters/dsh.py):_CURRENT_LOG_GENERATION3 → 4:按 v4 原生形态发布,不再依赖迁移链;旧世代日志即使没有新消息也升级(legacy判定改用当前世代),前代逐字节冻结、后继写成session.v4.*。- 用户标题事件写
messageSeqs: [](v4 目标规则)。 - 每轮注入的
system/message来源由 v3 的{kind:'plugin', plugin:'@deepseek-ai/dsh-system-prompt'}改为 v4 要求的{kind:'system-prompt'}。 - 回合骨架修正:开新回合前关闭上一个回合(该回合有模型回复 →
turn/end.reason.kind='completed',否则'interrupted');首行即模型回复的会话也先开回合并写入 system head,保证整份日志的第一个表层事件是受保护的 system 消息。
Fixed(同步的会话全堆在「未分组」—— Workspace 索引只在首启扫描)
- 根因:DSH Desktop 侧栏按 Workspace 分组,成员来自
workspace存储域(<home>/storages/workspace.json)每条记录的sessionIds;dsh 只在首次初始化(initialized尚为 false 时)按会话头 bootstrap 一次,之后永不重扫。适配器此前刻意不写该域(旧版合成行会破坏其不变式),于是所有同步进来的会话都留在「未分组」—— 实测 414 个会话里 383 个本可归属,域里却只有 1 个。 - 修复(
mcp/adapters/dsh.py::_refresh_workspace_index,每次写入后运行):镜像 dsh 自己的 header bootstrap 加性重建归属 —— 按fs.realpath(cwd)分组,把本机会话挂到路径相同的记录、缺失目录时新建记录(标题取末段、时间取组内最新会话)。既有记录、标题与展示顺序全部保留(新记录按 dshcreate的约定前置);CJK/超长路径、大小写漂移、junction 都经同一规范。只动已初始化且结构自洽的 unit:文件缺失、外来 unit(name/version 不符)、initialized: false、workspaceIds与表键不一致或存在pendingMutation时一律不碰(交给 dsh);cwd 不存在或没有 cwd(_no-cwd)的会话不分组 —— 与 dsh 自身一致。
Fixed(顺带:长路径会话被静默丢失)
_log_file/_session_files/_find_any_log/_log_meta/status/ 投影缓存写入此前用裸Path.iterdir()/read_bytes(),store 根一深(path ≥MAX_PATH)就抛OSError被吞,会话既不读也不写(_session_files少返、_log_file返回None)。现统一走_lp()扩展长度形式(新增_isdir/_scan/_mtime纯辅助)。实测副本根把某些会话目录顶到 267 字符时,修复前 404/413、修复后 414/414。
测试与验证
- 端到端(dsh 自己的读器,非自证):把真实 store 的 409 个会话经修复后的适配器全量写入空 store(
imported: 409 / new_messages: 26066),再用dsh-session-query对写入结果逐个readSession—— 409/409 全通过(含 1018 事件的长会话、CJK/超长路径会话、_no-cwd会话)。对真实 store 的副本跑一次升级写(updated: 413、new_messages: 0):前代 v3 逐字节冻结、每会话新增session.v4.jsonl.zstd后继,414/414 后继readSession通过(修复前 404/413)。桌面实机:重启后打开同步会话正常渲染历史(不再报历史加载失败)。 - Workspace(dsh 真实域 + 桌面实机):真实 store 副本上先跑一遍:记录 33 → 45、成员 1 → 383,三条不变式(唯一所有者 / 一目录一记录 / 顺序 == 表键)断言通过、二次运行幂等;对真实 store 应用后重启桌面实测:侧栏出现
service / client / diagramon / OpenCode / work / Desktop / D:\ …等新分组,agentctxsync(69)、中医健康(16)、hermes-sync-foreign(121) 等各归其位,「未分组」只剩 cwd 在本机不存在的会话(本次快照 24 个)。 - 单测:
mcp/tests/test_dsh.py—— 当前世代落盘为 v4、用户标题messageSeqs为空、system/message为system-prompt来源、当前世代就地重写、v3 前代升级为 v4 且前代逐字节不变、连续 user 行以interrupted收口、模型先行会话以 system head 打头、超MAX_PATH的会话目录仍能被_log_file读到;WorkspaceIndexTest7 例。mcp套件 223 项 OK。 - 236 部署核对(11/11 PASS):manifest(
agent=dsh与agent=omp,v=2026.10.06.1)均返回 2026.10.09.1 且update_available=true;包内manifest.json版本一致;包内mcp/adapters/dsh.py含_CURRENT_LOG_GENERATION = 4、{"kind": "system-prompt"}、_refresh_workspace_index、_lp(;包内mcp/updater.py为新版本号;包内 dsh.py 与清单 sha256 及提交2ef7dbe三者逐字节相符。另把线上agent=dsh归档解出,就地对其mcp/adapters/dsh.py跑test_dsh.py—— 40 项 OK。
Docs
docs/SUPPORTED_AGENTS.md(DSH 行)与docs/ARCHITECTURE.md(dsh 小节):当前世代 v3 → v4,补上用户标题messageSeqs为空、system-prompt来源、v3→v4 边与 v4 原生接纳的拒绝规则;workspace 域由「外部不写」改为「按会话头加性重建归属」并写明其不变式与延迟可见(需重启桌面)。
兼容性
- 已装客户端会在下一次更新检查(每小时一次,或 Agent 重启后 60 秒)自动拉取 2026.10.09.1,重启 Agent 后新逻辑生效;升级后的客户端会把本机既有的 v3 日志在下一次同步时升级为 v4(前代逐字节保留)。
- 未更新的客户端仍按 v3 发布,在 0.2.0-rc.2 桌面里仍会「历史加载失败」——请更新客户端(或重启 Agent 触发自动更新)。
- 服务端无 schema/接口变更,旧客户端行为不变。
生产状态:236 已部署(代码提交 2ef7dbe,记录提交 f68b9f6,tag v2026.10.09.1)。