@dafantong01/dsh-memory-palace

memorytested: passnpmMIT

Local long-term memory for DSH sessions: archives older turns under context pressure, with four tiered hot-memory boards, project documents, memory families with editable family names and root transfer that preserves project hot memory, summary keyword locator with segment-level candidates and pagin

下载量 / Downloads
3,337
依赖体积 / node_modules
1.24 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add @dafantong01/dsh-memory-palace

Sandbox test results

StageResult
1 install✓
2 list✓
3 mount✓
4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

README

记忆回廊(dsh-memory-palace)

把会话原文按「一轮对话」为单位、分类归档到当前工作区的 memory-palace/ 目录。

目的:在 DSH 自动压缩之前,先把较早的完整原文落到磁盘,压缩后还能查回原话。

0.3.7 发布版:本地长期记忆。归档较早的整轮原文,提供四板块分级注入、项目档案与项目热记忆、记忆家族与根转移、摘要关键词定位与候选翻页、手动注入、20K 分段、tag 关联检索、归档触发快路径与压缩恢复;数据都在当前工作区。
0.1.x 的归档基础说明仍适用。

功能总览

  • 热记忆四板块:identity(角色自我)、user 板块(用户画像)、rules(规则铁律)、memories(关键记忆)。
  • 分级注入:mind-seal 每轮;important 每 5 轮 / 10k 输出 token;normal 每 12 轮 / 30k;minor 压缩后一次。共享计数器,受总预算约束。
  • 项目档案:会话级 Markdown 文档,支持新建/编辑/启用/停用/归档/取消归档/软删除;启用档案进入小型注入清单,停用档案可按需读取,归档档案模型只得到错误;正文按 20K 分段加载。
  • 项目热记忆:按 projectLabel 绑定项目档案,可挂任意板块;项目启用才注入,停用/归档不注入、不占预算;每个会话独立存储,同名项目可并存,支持显式跨读。
  • 记忆家族:母归属/子会话/脱离/让位/解散/根转移;母归属可单独修改家族显示名,不改文件夹与成员;子会话的全局热记忆只读,但可以拥有自己的项目热记忆;长记忆互读;文件锁、journal、选举、根转移与旧根只读。
  • 自动捕获:严格命令式只负责识别,由模型按语义写入对应板块;非命令式由模型自行判断;规则只进候选。
  • 手动注入:页签条目可「立即注入」;下一轮注入带【手动注入】段。
  • 检索关联:项目档案检索命中后,按同项目或共享 tag 自动补最多 3 条相关文档。
  • 归档快路径:压力超阈值时只用 tokenMeter 触发,检测不再全量解码日志;真正归档时才解码校验。
  • 摘要定位:palace_summary(keyword=...) 先扫月度摘要,返回年月/类别/轮次;本会话未命中时可按配置回退家族、全库搜、询问用户,或仅停在候选摘要。候选按段取:每月最多 1–6 段(默认 3),用本地词法打分排序,整段摘要返回;每页最多 3 个月,月数上限 = 保底月数 + 增量(0–18),用返回的 candidateCursor 翻页。
  • 彻底压缩时的归档:勾选「归档后彻底压缩」并手动归档时,除最后 archiveTailTurns(默认 2)轮外全部归档;不勾选仍按原保留窗口。
  • 缓存自检:只统计缓存实际追加/重建,每 20 次写入做一次全量解码校准(可调 10–100);重建后自动清理 manifest 未引用的旧 chunk。
  • 检查/安装更新:页签检查更新;安装更新需用户确认,失败可回退。
  • 本地优先:归档、热记忆、项目档案、家族状态都在当前工作区 memory-palace/;不依赖外部记忆服务。

安装

dsh plugin --profile <profile> add @dafantong01/dsh-memory-palace

安装后重启 DSH,在会话页签打开「记忆宫殿」,给会话命名后才会归档。

已知限制

  • 不做 embedding;检索是关键词/时间召回,口语化或跨义描述可能搜不到。
  • 不自动注入项目档案全文;按需用 memory_doc_search / memory_doc_read。
  • 归档、项目文档、热记忆的写锁以单 DSH 实例为前提;多实例不做强一致保证。
  • 可与其他记忆工具并存;迁移前先备份并人工抽查。
  • UI 的提示位置、原位编辑、保存后排序属于已知低优先级体验项。

工作方式

1. 触发检查:每 checkEveryTurns 轮(默认 5),在回合收尾处检查一次。要同时满足两道门:

  • 压力门:上下文占用 ≥ triggerPressure(默认 60%)× 窗口。

占用取 DSH 自己的计量 ctx.tokenMeter.measure(session).totalTokens——压缩后它会回落;

拿不到计量服务时才退回「日志轮次累加」,并在提示里标注「日志估算」。

  • 批量门:可归档轮数 ≥ minBatchTurns(默认 10)或 可归档文本量 ≥ 无需归档量 × batchByteFraction(默认 50%)

2. 提醒:两道门都过,插件注入一条极短提示,请模型调用归档工具(enableSteer:false 可关掉,关掉就没有自动归档)。

3. 分类(逐轮判断):模型逐轮决定每轮属于哪个类别,用 segments 提交:

[{category, fromTurn, toTurn}, …]。同一类别可以拆成多段,最后合并成一个文件;

每个 turn 只能归一类,区间不许重叠。

4. 保留:无需归档的近期文本量 = 窗口 × retainFraction(默认 12%),比这更新的轮次不动。

取整轮粒度、严格不超过该上限;只有单轮本身就超上限时,至少保留最后 1 轮。

12% 的用意:压得比 DSH 压缩尾部(约 16%)更小,压缩时不会碰到你还没归档的近期内容。

5. 写入:插件从会话日志逐字取出每个类别的轮次,按时间正序写进该类别一个文件(超 maxFileBytes 才分卷)。模型不复述内容,不会截断或改写。

6. 覆盖去重:已归档轮次记在 .state.json 的 archivedRanges;新请求先把已覆盖的轮次剔掉,只写剩下的。

7. 归档后压缩:compactAfterArchive 默认关。compactNow() 不接受范围参数,压多少由 DSH 自己决定,

可能压掉尚未归档的近期轮次(原文仍在会话日志里,可再归档)。默认不动它。

目录与文件名(会话级隔离)

<当前工作区>/
  memory-palace/
    .namespaces.json       # 会话ID → 文件夹名 的映射(插件维护)
    config.json            # 新会话的默认值(旧版遗留,仅作默认)
    <文件夹>/              # 记忆名:英文(大小写均可)+数字/空格/下划线/连字符
      config.json          # 本会话自己的开关/参数/记忆名
      .state.json          # 本会话水位、已归档区间
      index.jsonl          # 本会话的归档索引(路径相对本文件夹)
      <YYYY-MM>/           # 月份容器:归档时按归档年月找/建
        _summary.md        # 该月摘要:只追加,每段对应一次归档里的一个类别
        <category>/
          <前缀>-<category>-<YYYYMMDD-HHmmss>.md
  • 文件夹名 = 页签里填的「记忆命名」:英文(大小写均可)、数字、空格、下划线、连字符,≤32 位;首尾不能有空格,中文与路径分隔符会被拒绝。
  • 没命名时用会话ID,且不产生任何记忆文件(只建 config/state)。
  • 在页签里改名并保存 → 文件夹就地改名,索引里的路径是相对的,不需要跟着改。
  • 文件夹即归属:memory-palace/<你的文件夹>/ 里的文件都属于那个会话;文件名前缀只是历史署名,不代表归属。
  • 摘要每月一份:<YYYY-MM>/_summary.md,只追加;同一次归档里每个类别写一段,段头是「归档时间 · 对话时间范围 · [类别] 轮次范围」。
  • 月份按该批对话首轮的时间归属:10-31 深夜、11-01 才归档的对话仍落进 2026-10/。
  • 文件头注明 turn = 日志事件序号(含系统指令、插件注入、工具调用),不是“第几条消息”。
  • 一次归档调用里,同一类别的所有轮次进同目录下的一个文件(超 maxFileBytes 才按轮分卷 -p1/-p2)。
  • 不同类别 = 不同文件,即使来自同一次调用。
  • 同秒冲突自动加 -2。分类目录强制英文小写。

从旧结构迁移

早期版本用过不同的目录结构。迁移脚本只用于本项目早期数据,不包含在发布包中;新用户从 0.1.0 开始使用无需迁移。

当前采用的结构是 <会话>/<YYYY-MM>/<category>/。

工具

工具 · 作用

palace_archive · 归档轮次。未命名会话会拒绝。用 segments 逐段给类别:[{category, fromTurn, toTurn}, …];并用 summaries=[{category, text}, …] 给每个类别写一段只概述该类别本次轮次的话(逐段追加到当月 _summary.md)。单类别时可用 summary 代替。可传 selfName 作文件名前缀。超出保留边界或已归档的轮次会直接报错(防止模型估错轮次号)

palace_turns · 列轮次清单:turn 号 + 发言者 + 开头 70 字,用于归档前确认每轮内容。turn 是日志事件序号(含系统指令/插件 steer/纯工具轮),不要用“第几条消息”换算

palace_summary · 读月度摘要:不指定 month 时列出最近几个月(摘要末尾预览 + 归档文件数);month=YYYY-MM 返回该月摘要全文;category 只看该月某类段落;append + fromTurn/toTurn 可给还没归档的近况补写一段摘要

palace_search · 检索归档。默认只查本会话;namespace 查别的会话、all:true 扫全部命名空间(结果标来源)、category 只查某类。keyword 支持空格分隔的多关键词(AND,引号包短语)。默认按轮聚合(每轮一条代表命中 + 该轮命中数),limitTurns 控制轮数(默认取 searchTurnLimit=12);groupByTurn=false 回原始命中行(旧 limit 语义)。片段约 220 字符,总输出上限 8K,文件读失败会跳过并注明。只搜归档正文,不搜 _summary.md(摘要里的概述性说法要用 palace_summary 读);但原文 0 命中时会自动回查摘要并标注「摘要不是轮次」,可用 includeSummary:true 强制追加

palace_read · 读归档。fromTurn/toTurn 返完整原文;path 可省略(按轮次自动找文件),也接受 search 的「文件夹/…」路径;可传 namespace。末尾附一行回链(提取 turn 引用/文件名/工具名,自动提取仅供参考)

palace_config · 查看/修改本会话配置(get 会同时返回 effective / 工作区默认 / 本会话配置)

检索四步法(为省 token 设计)

0) 不知道在哪个月:palace_summary(limit=6)
   → 每月摘要末尾预览;找到大致年月
0b) palace_summary(month="2026-10")
   → 该月全部摘要段落(哪次归档、讲了什么)
1) palace_search(keyword="事故教训", limit=3)
   → 约 1 千字符:命中位置 + 轮次 + 行号 + 文件路径
2) palace_read(fromTurn=48, toTurn=48)
   → 该轮完整原文(思考、工具调用、返回都在)
  • 单次读取默认上限 60,000 字符(约一本书的三分之一),硬上限也是 6 万。
  • 单轮超过 6 万字符时,返回前 6 万并提示 用 offset=N 继续,可分段读完整个大轮(实测 12.7 万字符分 3 段读完)。
  • 不给轮次、也不给 path 时只返回文件开头 6 万字符,并提示按轮次精确取。

开关(会话级,fail-closed)

真正生效要同时满足(现在收成一个统一门 gateState(),页签会显示“为什么没生效”):

1. 全局总闸 enabled(默认开,只是允许插件工作)

2. 本会话开关:memory-palace/<文件夹>/config.json 里 enabled: true,新会话缺省为关

3. 已命名:记忆名为空时,即使开了开关也不归档(只建文件夹和配置)

4. 自动提示:injectNotice / enableSteer 任一关掉 → 工具仍可用,

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::25,最后更新 2026-11-05

Links

GitHub · Homepage · npm

Same category