jipika/dsh-memory ↗★ 0

@jipika/dsh-memory

Two-layer long-term memory (global + per-project) injected into the system prompt on every assembly, with a Settings panel to switch each layer off. Live re-read, zero extra LLM cost. 适合需要让AI记住特定背景设定,且不希望增加额外调用成本的用户。

패키지
@jipika/dsh-memory
호환성
미검증
버전
0.2.1
라이선스
MIT
최근 업데이트
2026. 9. 23.

설치

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:jipika/dsh-memory

dsh-memory

Two-layer long-term memory for DeepSeek Harness (DSH) — global + per-project, plain markdown, zero extra LLM cost, effective the moment you write.

给 DeepSeek Harness 的两层长期记忆:全局层 + 项目层,纯 markdown、明文可编辑、 不产生任何额外 LLM 调用,写完即生效。

npm license DSH 1024Store


它解决什么

Agent 每次会话都是失忆的。让记忆活下来通常只有两条路:

做法代价
把记忆塞进系统提示词需要"谁来写、写到哪、怎么注入"的一整套机制
用 LLM 从会话里提炼事实每轮会话都在后台烧钱,且内容进了别人的向量库

本插件的取舍是:记忆就是几个 markdown 文件,注入走 DSH 原生的提示词 seam,写入由当前会话的 agent 顺手完成 —— 于是它既不花钱,也不出本机,还能被 git 跟踪、被人手编辑。

特性

  • 两层:~/.dsh/memory.md(全局:用户偏好 / 环境事实 / 通用坑)+ 按工作区分级的项目层, 切换项目自动切换内容。
  • 零 LLM 成本:插件本身不调用任何模型,只读文件;写记忆用的是会话已经在跑的那个模型。
  • 写完即生效:注册的是函数式 text,每次提示词组装都重读文件 —— 不需要重启、不需要刷新。 (对比:cordis.patch.yml 里 personaPrefix 的 !!js 只在 boot 求值一次。)
  • 索引注入,不炸上下文:项目记忆只注入 MEMORY.md(一个 - [标题](https://github.com/jipika/dsh-memory/blob/87c1f1f09ca933c371e10424d79e2a6e9dcbed82/%E6%96%87%E4%BB%B6.md) — 摘要 的索引), 主题正文按需读。上千行的记忆库也只占固定的索引体积。
  • 设置面板:DSH 设置里多一个「记忆」分栏 —— 每层一个开关,点标题即可展开看正文。
  • 明文、可移植:就是 markdown。可以 git、可以 diff、可以手改;删掉文件即停用(段渲染为空串, 被 renderPrompt() 过滤,零残留)。

安装

从 npm(推荐)

已发布为 @jipika/dsh-memory,也收录在 DSH 1024Store 目录里:

dsh plugin --profile web add @jipika/dsh-memory

本插件自带 cordis.patch.yml(package.json 里声明了 dsh.bundle.patch),安装时 DSH 会自动把它 挂进 profile 的组合树,不需要手工编辑任何 profile 文件。

从源码(想改代码时)

git clone https://github.com/jipika/dsh-memory.git ~/.dsh/local-plugins/dsh-memory

然后以 link: 方式挂进 profile(以 desktop 为例):

# 1) 依赖(~/.dsh/profiles/desktop/package.json)
#    "@jipika/dsh-memory": "link:../../local-plugins/dsh-memory"

# 2) 挂载(~/.dsh/profiles/desktop/cordis.patch.yml 末尾追加)
#    - insert:
#        - id: dsh-memory
#          name: '@jipika/dsh-memory'

cd ~/.dsh/profiles/desktop && pnpm install

装完后若是 link: 方式,pnpm install 会重建 node_modules 链接并把 HMR 的基线路径换掉 —— 建议 重启一次 DSH(host 半在 boot 时加载)。之后改记忆、翻开关都不再需要重启。

记忆文件布局

~/.dsh/memory.md                                  ← 全局层(整个文件注入)
~/.dsh/memory/projects/
  ├── --Users-me-code-repo--/                     ← 项目层:目录形式
  │   ├── MEMORY.md                               ← 注入这一份(索引)
  │   ├── some-topic.md                           ← 主题正文,按需读
  │   └── another-topic.md
  └── --Users-me-other-repo--.md                  ← 项目层:单文件形式(同样支持)

项目层目录名由会话的 cwd 推出,规则与 DSH 自己的会话目录一致——路径里的 / 换成 -, 两端各加 --:

/Users/me/code/repo   →   --Users-me-code-repo--

所以 ~/.dsh/sessions/--Users-me-code-repo--/ 与 ~/.dsh/memory/projects/--Users-me-code-repo--/ 是同一个项目的两份数据,一眼能对上。

记忆怎么写

由 agent 顺手写(这也是"零 LLM 成本"的来源:写入搭的是本来就跑着的会话)。建议在 ~/.dsh/AGENTS.md 里放几条纪律,例如:

Memory upkeep (long-term memory):
- TWO layers, both injected on every assembly (no restart needed):
  · GLOBAL  `~/.dsh/memory.md` — facts that would bite in ANY repo.
  · PROJECT `~/.dsh/memory/projects/----.md` — facts
    that only hold in this workspace.
- Append one line `- [YYYY-MM-DD] fact` under the matching section, in the SAME
  turn you learn it. Do not batch for "later".
- Do NOT log narration or anything re-derivable from the repo.
- NEVER put secrets in it — both layers ride every request to the model provider.
- Record what IS true, never a removal: "X was uninstalled" is stale the moment
  it is written and taxes every future session.

设置面板

设置里会出现一个「记忆」分栏:

  • 全局层一个开关;项目层每个项目一个开关(项目列表由 host 扫描记忆目录自动维护)。
  • 点任意一行的标题即可就地展开该层的正文(由 host 的只读路由 /dsh-memory/content 提供)。
  • 关掉的那一层不再注入;再次开启立即重新读取文件。
  • 开关状态存在 ~/.dsh/settings.yaml 的 dsh-memory 节:
dsh-memory:
  globalEnabled: true
  projectEnabled:
    --Users-me-code-repo--: false   # 关掉这个项目的记忆
  knownProjects:                     # host 自动维护,供面板列出
    - --Users-me-code-repo--

工作原理

ctx.systemPrompt.section({
  name: "dsh-memory:long-term",
  order: 1,              // 紧跟 DEPLOYMENT_PERSONA_PREFIX(order 0),先于工具规范
  text: compose,         // ← 函数:每次 assemble() 重新求值
});

compose() 按当前 cwd 决定注入哪些层,并遵守开关;任一层不可用(文件缺失 / 开关关闭)就返回空串, 而空段会被 dsh-system-prompt 的 renderPrompt() 过滤掉。

插件同时注册:

  • 一个 settings namespace(dsh-memory)承载开关与自动维护的项目清单; host 半用手写 schema —— 插件装在 node_modules 之外,解析不到 schemastery。
  • 一条只读 HTTP 路由 GET /dsh-memory/content?target=global|(target 走白名单校验, 拒绝 .. 与路径分隔符,无法越出记忆目录)。

验证

node tests/probe.mjs

28 项断言,全部在临时 HOME 里跑(自造记忆文件,不碰你的真实数据),覆盖:两层注入、 cwd→slug 推导、无 agent 时只注入全局、两个开关的开/关/重开、内容路由(含路径穿越被拒)、 以及面板渲染与行点击展开。

兼容性

依赖 DSH 的以下既有 seam:systemPrompt.section()(函数式 text)、settings.register()、 webServer.register()、client 的 settings.section 槽位与 settingsScope.bind()。 在 DSH Desktop 2.0.13 / dsh core 0.1.5-rc.2 上验证通过。

License

MIT