DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

AngleNaris /

AngleNaris/slumberpavilion

Verified

沉眠阁 — 把已归档的 DSH 会话搬出加载路径,并提供归档/读取/还原/删除工具

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@ac1d73ca

沉眠阁 · slumberpavilion

把 DSH 里「已归档」的会话真正搬出加载路径,并内置读取归档内容的能力。

它为什么需要存在

DSH 的「归档」只是一个标签,写进 storages/workspace.json 的 archivedSessionIds。 官方 archived-session-gate 的原话是:

an archived Session ... must not run a model step until it is restored.

它拦的是能不能跑,不是占不占地方。归档之后:

  • 会话日志仍留在 .dsh/sessions/<工作区>/<会话id>/
  • 投影记录仍留在 .dsh/storages/session_projcache/sessions/<id>.json

而 session_projcache 用的是 JSON 存储后端,官方注释写明「读写共享存储域内一致的内存状态」—— 全部记录常驻内存。实测:2395 条记录 / 169.5 MB JSON,其中 126 条已归档的占 40.8 MB(24.1%), 而它们只占条目数的 5%。归档的大多是长篇会话,正是最占地方的那批。

本插件做三件事:

  1. 每隔一段时间检查 archivedSessionIds,发现新归档的会话
  2. 把它的日志目录与投影记录移动到 ~/DSH-Archive(不是删除)
  3. manifest.json 记下来源与去向,随时可还原

安装

npm install slumberpavilion

然后在 profile 的 package.json 里把包装进 bundles:

"dependencies": {
  "slumberpavilion": "^0.1.0"
},
"dsh": {
  "profile": {
    "bundles": [
      "...",
      "slumberpavilion"
    ]
  }
}

重启 DSH。本地开发时可以用 file: 依赖 + 一条符号链接代替 npm 安装:

ln -s ../plugins/slumberpavilion ~/.dsh/profiles/desktop/node_modules/slumberpavilion

配置

在 cordis.patch.yml 里,全部字段都是 volatile(改完热生效):

字段 默认 含义
enabled true 总开关
archiveRoot '' 归档根目录,留空 = ~/DSH-Archive
checkIntervalMs 20000 检查间隔(毫秒)
moveLogs true 是否移动 sessions 下的日志目录
moveProjections true 是否移动 session_projcache 记录(内存收益主要来自这里)

读取归档

方式一:命令行(不依赖 DSH,随时可用)

node lib/cli.js list 20
node lib/cli.js read f8ab825e 上下文压缩 50
node lib/cli.js info f8ab825e

方式二:Agent 工具

注册五个工具,对话里可直接调用:

工具 作用
archive_list 列出归档会话(按体积降序)
archive_read 读一个归档会话;keyword 过滤、compact 只留对话轮次、maxChars 逐条截断
archive_session 执行归档:标记 + 立刻搬走,不用等后台扫描;先 dryRun=true 看清目标
archive_restore 还原归档:搬回 .dsh、撤销归档标记、清清单;同样支持 dryRun
archive_delete 永久删除一个归档会话;先 dryRun=true 看清目标再动手

archive_session 走的是宿主的 ctx.workspaceRegistry.archiveSession(),所以归档状态 是 DSH 自己写进 workspace.json 的,不靠手改文件;标记落盘后插件立刻 sweep() 一轮, 把日志与投影搬进归档区,返回里会报出最终目录。

  • 只认唯一命中:ID 或片段模糊命中多条时拒绝执行并列出候选,免得搬错会话。
  • 活跃会话默认拒绝(WorkspaceActiveSessionError);确认要归档正在跑的会话,加 stopActivity=true,宿主会先请求停掉它的工作再归档。
  • 拒绝归档「正在执行这条工具的那个会话」,不然等于自断。

archive_restore 是它的逆操作,顺序是「搬文件 → unarchiveSession() → 清清单」:

  • 目标位置已有同名目录时拒绝,让你先确认是不是重复还原。
  • 清单里记着原始的 from,还原优先搬回原位;没有记录时退回 .dsh/sessions/<工作区>/<会话 ID>。
  • 投影记录(projcache)跟着一起搬回;目标已存在的不覆盖。
  • 撤销标记失败时仍然搬文件,并在返回里明确警告「它仍算已归档,请在界面取消归档」。

这层曾经整个是哑的,原因是三个叠在一起的问题,现在都修了:

  1. 没有声明 inject。Cordis 里不 export const inject = ["tools"] 就读不了 ctx.tools,一读抛 cannot get property "tools" without inject;原来的代码把这句 写在 try 里,异常被吞掉,只剩一条 warn,工具永远静默缺席。
  2. await import("@deepseek-ai/dsh-tools") 解析不到。这个包只随宿主打包在 app.asar 里,profile 的 node_modules 没有它,Node 的 ESM 解析器又不认 asar。 改用 createRequire(import.meta.url)(Electron 主进程认得 asar 路径),同步取。
  3. 工具定义形状不对。defineTool 收的是「属性表」,必填用 required: true 标在 属性上;output.render(args, value) 必须返回 ContentBlock[]。原来传的是完整 JSON Schema、render 直接返回字符串。

取不到 defineTool 时还有一层本地兜底:normalizeToolDefinition() 自己把属性表 展开成完整 JSON Schema,所以换机器/换宿主也不会两头空。

排障:插件往 %TEMP%\slumber-pavilion-diag.log 记一行 apply、一行 defineTool 是否取到、每个工具是否注册成功。改了代码重载插件后先看这个文件。

还原

两种方式,效果一样:

  • 对话里 archive_restore(推荐):搬文件、撤销标记、清清单一次做完,先跑 dryRun 看目标。
  • 手动:manifest.json 里每个条目都记着 from(原路径)与 to(归档路径),把 to 移回 from,再去界面里取消归档、从清单删掉那一条。

已知边界

  • 扫描只处理「已归档」的会话。归档标记由 DSH 写;archive_session 只是替你把这个 标记写进去,然后立刻搬文件。
  • 移动后 workspace.json 里的 archivedSessionIds 不会清理,指向一个不存在的会话。 实测这不影响启动(列表按投影记录渲染,记录没了就不显示)。
  • 若会话日志已被 DSH 重新折叠出新的投影记录,下次扫描会再搬一次。
  • 「已搬过」的判据覆盖顶层与各批次目录的 manifest.json。早先只读顶层那份,老批次 条目会被当成没搬过、每轮空转一次;现在不会了。
  • archive_session 只认磁盘上还在 .dsh/sessions 里的会话;只剩归档副本的请用 archive_list / archive_read。

为什么解压要手写

DSH 的 session.v4.jsonl.zstd 是多帧 zstd(边写边追加,每追加一次一个独立帧)。 Node 的 zstdDecompressSync 和 createZstdDecompress 都只解第一帧就收工—— 实测 1.1 MB 只解出 285 字节,恰好是会话头。

所以 reader.js 按帧魔数 28 B5 2F FD 切开逐个解,切错就往后找下一个魔数重试。 实测那个 60.6 MB 的会话:31,528 帧,56,701 行,零失败,压缩比约 ×3.8。

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit ac1d73ca7262

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout