Skip to content

v2026.09.21.1

Choose a tag to compare

@westsource westsource released this 21 Sep 11:45
· 17 commits to main since this release

v2026.09.21.1 — 按会话暂停 / 恢复同步(Web 多选 · 服务端冻结 · 客户端补推)

服务端 + 客户端发布:CLIENT_VERSION 2026.09.13.4 → 2026.09.21.1(mcp/updater.py 与 server/client_update.py 同步),各端经 /api/client/manifest 自动更新、Agent 重启后生效。schema 变更:sessions 新增 sync_paused / sync_paused_at 两列,由启动时的 init_db() 幂等 ALTER TABLE ... ADD COLUMN IF NOT EXISTS 创建,无需人工迁移。

Added(Web 端可多选:暂停 / 恢复会话同步)

  • 选定会话暂停 / 恢复同步:工作空间详情页与「全部会话」页每行带勾选框,批量栏一次暂停或恢复所选会话;每行另有单行按钮,会话查看器页也有同一按钮。暂停的会话在列表里带「已暂停同步」徽标。
  • 语义是服务端冻结上行,不是把会话从共享池里摘掉:
    • /push(以及 Web 导入)对这些会话零写入 —— 会话元数据、消息、rev/field_rev、last_synced_at 全部不动。闸门放在 push_sync 最前面,所以配额闸门、消息去重快照与 rev 记账都看不到被暂停的会话:整会话冻结,不是部分合并。
    • /pull 照旧下发冻结版本。否则其它设备会认为"服务端没有这个会话",触发「本地删除不是删除信号」的补回逻辑,或让用户以为会话被删。暂停只断上行。
  • /push 新增响应字段 paused_ids:本次被冻结跳过的会话 id。客户端据此不记录 push 指纹 —— 指纹的含义是"服务端已持有这份内容",记了它,暂停期间的内容在恢复后将永远补不上去(本地无变化 → 指纹命中 → 跳过)。不记指纹 = 每轮重发,恢复后下一轮自动补齐。
  • 路由:POST /web/sync/pause / POST /web/sync/resume,表单字段 sel 可重复,值 "<ws_id>:<session_id>"(会话 id 自身可含冒号,只按第一个冒号切分);只更新调用者自己的 workspace(workspaces.user_id 校验),返回路径 next 限同源。行内已有各自的删除表单,所以每行勾选框用 form="sync-bulk" 关联到行外表单(HTML 不允许嵌套 form),两个提交按钮用 formaction 区分。
  • Web 导入(/web/workspace/{id}/import)跳过暂停会话并在 flash 中报数(与 /push 同规则,不静默丢弃)。

Changed(客户端与文档)

  • mcp/server.py::push_sessions 识别 paused_ids:不计入 processed、不写指纹,日志与返回体给出 paused / paused_ids 计数(多 chunk 合并计数)。
  • 新增词条 sync_pause_* / sync_bulk_* / ws_import_paused(zh-CN + en);_macros.html 新增 sync_paused_chip()。
  • 文档:docs/ARCHITECTURE.md 新增「暂停/恢复同步」决策记录(含混合版本窗口与回归防线)、sessions 表两列、路由表、pull 过滤段说明;docs/server-deployment.md 路由表 / /push 响应字段 / sessions 列表同步;docs/OPERATIONS.md 数据保留章节补条目;README(中英)功能要点同步。

混合版本窗口(实测确认)

  • 未更新的客户端照常自动同步:旧客户端(2026.09.13.4)对新服务端实测 —— 普通会话推送行为一字未变;推送被暂停会话时返回计数 0、无 error,同步循环不中断,同批次其它会话照常入库。
  • 代价:旧客户端会把那次"被跳过"的推送当作成功并写入指纹,于是暂停期间的内容要等该会话本地内容再变化一次、或清一次指纹 sidecar(<mcp目录>/.hermes-sync-field-meta-push-fingerprint.json)才会补上。实测清掉 sidecar 后下一轮即补齐。客户端自动更新后该窗口自然消失。

测试与验证

  • 单元测试:server/tests/test_sync.py(PushTest 新增 sync pause 用例:冻结零写入、同批次其它会话照常落库、响应带 paused_ids、暂停会话不再进入配额闸门)、server/tests/test_sync_pause_ui.py(sel 解析含冒号 id、端点、多选、属主校验、空选择提示、next 同源校验、导入跳过并计数、zh/en 词条齐备)、mcp/tests/test_push_pause.py(不写指纹、下一轮重发、混合版本窗口、多 chunk 合并计数)。全量:server + mcp 477 passed / 2 skipped。
  • 线上(236)20 项检查全 PASS:两列由 init_db() 建出;匿名 POST /web/sync/pause → 307 /web/login;Web 暂停后 /push 返回 paused_ids 且该会话标题/消息数原封不动、/pull 仍下发冻结版本;列表页渲染徽标与批量栏;恢复后同一次推送补齐暂停期间的 2 条消息;/api/client/manifest?agent=hermes&v=2026.09.13.4 返回 version 2026.09.21.1 + update_available=true,下载包内 manifest.json 版本一致、mcp/server.py 的 sha256 与清单相符且含 paused_ids。

生产状态:236 已部署(提交 9531474)—— 11 个文件(6 个 .py + 4 个模板 + mcp/ 客户端 2 个)对上次部署提交 cab5a8a 逐文件 LF 归一化 sha256 预检通过、上传后回读一致、py_compile 通过,重启后 systemctl is-active = active、journal 无 error;check_drift_236.py / check_drift_mcp_236.py 复核 server/ 50 个文件、mcp/ 15 个文件 drift=0。线上 /api/client/manifest 已服务 2026.09.21.1。

仓库说明:v2026.09.19.2 的历史重写(清除部署细节 + 提交身份统一为 noreply)保持不变;本次发布起,新提交与 tag 使用维护者身份 道荣 <westsource@126.com>。