# dsh-mnemosyne [English](./README.md) | 简体中文 > [Mnemosyne](https://github.com/mnemosyne-oss/mnemosyne) 记忆层在 [DeepSeek Harness](https://github.com/deepseek-ai) 中的插件 — 本地优先、SQLite 支持的跨会话记忆。 ![dsh-mnemosyne 项目介绍 Banner](./assets/mnemosyne-banner.png) > 面向 DSH 的本地优先记忆:跨会话记住、召回并整理上下文。 ## 关于 Mnemosyne [Mnemosyne](https://github.com/mnemosyne-oss/mnemosyne) 是一个零云依赖、SQLite 支持的本地优先 AI 记忆系统。一个 `pip install`,一个 SQLite 文件,无需外部服务。它采用 **BEAM**(Bilevel Episodic-Associative Memory)架构: - **工作记忆**(Working Memory)— 热上下文层,自动注入 LLM 调用前,基于 TTL 淘汰 - **情景记忆**(Episodic Memory)— 长期存储,sqlite-vec + FTS5 混合检索(50% 向量相似度 + 30% FTS5 排序 + 20% 重要性) - **知识三元组**(TripleStore)— 带版本链的时序知识图谱 Mnemosyne 支持 MCP、Python SDK 及多种 agent 框架(Claude Code、Cursor、Codex、OpenWebUI、Pi 等)。本插件是其在 DSH 中的集成。 ## 关于 Pi-mnemosyne 本插件移植自 [`@mnemosyne-oss/pi-mnemosyne`](https://github.com/mnemosyne-oss/pi-mnemosyne) — Mnemosyne 官方的 [Pi coding agent](https://pi.dev/) 扩展。所有记忆逻辑都在 `mnemosyne` CLI(`pip install mnemosyne-memory`)里,插件保持 CLI 优先:常规共享记忆操作通过子进程调用 CLI。移植到 DSH 时增加了设置面板、CLI 自动安装、配置管理和会话收尾自动整合;并超出原版"无状态代理"的边界,增加了几个不重复实现记忆逻辑的薄桥:经 CLI venv 解释器运行的会话级 Python helper、直连 SQLite 的 scope 迁移,以及写过滤器(`ignore_patterns` / `write_classifier`)的 env 桥接。 ## 功能 - **六个原生工具**:`mnemosyne_remember` / `mnemosyne_recall` / `mnemosyne_forget` / `mnemosyne_stats` / `mnemosyne_sleep` / `mnemosyne_bind` - **按筛选结果批量管理记忆**:在记忆浏览器中先用筛选条件定位记录,再单独勾选或选择当前列表,最后通过筛选工具栏中的操作面板批量修改可信度、有效期、重要性、生命周期状态或 scope;工作区绑定仅作为批量移动的目标,不覆盖记忆内容。 - **内嵌技能**:`mnemosyne` 技能随插件自动注册,指导 agent 何时存储/检索记忆 - **设置面板**:DSH Settings 左侧独立 "Mnemosyne" 入口,含 CLI 状态、记忆统计、一键安装/测试、配置表单 - **记忆面板**:通过可选的 Better Sidebar 集成从 Mnemosyne 设置面板打开,展示当前 Bank 的总览、记忆浏览、筛选批量管理、三元组、整合记录、搜索和详情视图;管理操作均需明确确认。 - **自动安装 CLI**:面板 Setup 按钮用 `uv tool install mnemosyne-memory` 自动装好,并补齐 `config.yaml` 默认值 - **数据隔离**:SQLite 库与 `config.yaml` 存于 `~/.dsh/mnemosyne`,不碰 `~/.hermes` - **配置同步**:面板从扁平的 `config.yaml` 读取 mnemosyne 实际配置,空值字段显示默认值 placeholder;保存后自动执行 `mnemosyne config reload` - **默认值恢复**:面板底部支持将面板管理的配置恢复为 mnemosyne 默认值 - **自动整理**:后台按 session 串行处理同步;每 10 个 durable turn 检查工作记忆数量,达到阈值时自动执行当前会话的 `mnemosyne sleep`。清空的 `sleep_threshold` 回退到上游默认 50(绝不会被当成 0 而每轮必睡);`session/disposed` 只在该会话确实写入过自动记忆时才执行收尾整合——空闲会话不会触发可能调用 LLM 的 sleep - **自动记忆(默认启用)**:对齐 Mnemosyne 当前 Hermes 集成;可在设置中分别关闭自动记忆能力,显式设置为 `false` 的旧配置保持不变: - **Prompt 声明段** — 在 system prompt 注入 `# Mnemosyne Memory` 头部,让模型知道记忆工具可用 - **自动存储对话** — 每轮对话后自动将**真实 user 消息**(不含 assistant 输出)存入 Mnemosyne,无需模型主动调用 `mnemosyne_remember`;注入型上下文消息永不入库——`plugin`(如本插件自己的 prefetch 注入)、`agent-instructions`(workspace 指令)、`skill-catalog`(可用技能目录提醒)。兼容 Hermes 的长度上限默认是 user 500 字、assistant 800 字;对应上限设为 `0` 时完整保存,不做截断 - **自动召回注入** — 每个模型步骤前自动 recall 相关记忆并注入对话流,模型无需调用 `mnemosyne_recall` 即可看到先验上下文 - **会话隔离** — 按 DSH 会话分区记忆(引擎 `session_id` 列):每个会话只召回自己的记录 + `global` 作用域的行。子代理与其根会话共享记忆。会话 id 由持久化的 session header(`createdAt`)派生,恢复的会话跨 DSH 重启记忆不丢。`global` 行对所有会话**可读可写**(任何会话也能删除)。记忆面板管理区提供历史 `default` 会话迁移到 `global`、session 合并回 `default` 以及工作区迁移入口;工作区迁移先预览并在执行前创建备份。上游 `cross_session` 召回开关不受支持 ## 安装 ```bash # 将已发布的插件安装到 web profile dsh plugin --profile web add dsh-mnemosyne # 重启 profile 后,打开 Settings > Mnemosyne,点 Setup 自动安装 CLI # 或手动:uv tool install mnemosyne-memory ```
从 GitHub 安装(不通过 npm) ```bash git clone https://github.com/rebron1900/dsh-mnemosyne.git dsh plugin --profile web add ./dsh-mnemosyne ```
> Setup 按钮需要 PATH 上有 `uv`。如果尚未安装 uv: > ```bash > curl -LsSf https://astral.sh/uv/install.sh | sh > ``` ## 配置 配置有两个来源:插件自身的 DSH settings(`~/.dsh/settings.yaml` 的 `mnemosyne:` 命名空间)以及 mnemosyne 的扁平 `~/.dsh/mnemosyne/config.yaml`。面板优先显示 config.yaml 中的实际值;缺少值时显示默认值 placeholder。 | 分组 | 字段 | 配置来源 | |------|------|----------| | 插件 | `cli` / `defaultTopK` / `timeoutMs` / `dataDir` | DSH settings / `cordis.patch.yml` | | Embedding | `noEmbeddings` / `embeddingModel` / `embeddingDim` / `embeddingApiUrl` / `embeddingApiKey` | config.yaml `no_embeddings` / `embedding_*` | | LLM | `llmEnabled` / `llmBaseUrl` / `llmApiKey` / `llmModel` / `llmTimeout` | config.yaml `llm_*` | | 召回 | `polyphonicRecall` | config.yaml `polyphonic_recall` | | 工作记忆 | `wmMaxItems` / `wmTtlHours` | config.yaml `wm_*` | | 工作记忆 | `autoSleep` / `sleepThreshold` / `ignorePatterns` / `syncRoles` | config.yaml `auto_sleep_enabled` / `sleep_threshold` / `ignore_patterns` / `sync_roles` | | 自动记忆 | `promptSection` / `autoSync` / `syncTurnUserLimit` / `syncTurnAssistantLimit` / `autoPrefetch` / `recallMode` / `autoWriteScope` / `prefetchTopK` / `prefetchMinQueryLen` | DSH settings / `cordis.patch.yml` | > **注意**:自动记忆字段是 DSH 侧配置(通过设置面板保存,不写入 `config.yaml`)。它们通过设置监听器在运行时生效,无需重启 DSH。 > **作用域兼容说明**:存量安装默认保留原有 `sessionScope` 行为;已有记忆位于历史 `default` 会话时,会话级召回暂时不可见。工作区共享需显式设置 `recallMode=workspace` 与 `autoWriteScope=workspace`;升级后请打开记忆面板管理区,先确认再迁移数据。反向操作会有意把 `dsh_*` 行合并进共享历史命名空间,并丢失原会话归属。`global` 行对所有会话可见**且可删除**;插件会强制关闭上游 `cross_session` 召回逃生开关。workspace 模式使用显式 `.mnemosyne-id` 标记,绝不会静默回落到其他命名空间。config 面板只返回它管理的字段(允许列表),密钥类值一律掩码(`***`),真实值不会回传给浏览器。 面板保存会写入对应配置文件,并执行 `mnemosyne config reload`。底部"恢复默认配置"会将面板管理的配置恢复为 mnemosyne 默认值;更多未展示的配置可以直接编辑 `~/.dsh/mnemosyne/config.yaml`。除 `vec_type` 等启动时确定的配置外,大部分配置支持热加载。 面板的 `ignorePatterns`(工作记忆组)是写入过滤器:每行一个正则(Python re 语法),匹配的内容在 `remember()` 时被静默丢弃(如 `^git status`、`^pip install`、`^Traceback`)。插件会把它桥接到 `MNEMOSYNE_IGNORE_PATTERNS` 环境变量(上游写入过滤器只读 env),每次 CLI 调用都生效。在 config.yaml 中加 `write_classifier: strict` 可额外启用内置的噪音/密钥/结构启发式过滤。 ## 架构 ``` ┌──────────────────────────────────────┐ │ DSH Agent Session │ │ (tools + skill + session/event + │ │ agent/pre-step + systemPrompt) │ └──────────────┬───────────────────────┘ │ execFile (no shell) ┌──────────────▼───────────────────────┐ │ mnemosyne CLI │ │ store / recall / delete / │ │ stats / sleep / config │ └──────────────┬───────────────────────┘ │ ┌──────────────▼───────────────────────┐ │ ~/.dsh/mnemosyne/ │ │ ├── mnemosyne.db (SQLite) │ │ │ ├── Working Memory (hot tier) │ │ │ ├── Episodic Memory (long-term) │ │ │ └── TripleStore (temporal KG) │ │ └── config.yaml (flat key: value) │ └──────────────────────────────────────┘ ``` 插件保持 CLI 优先:共享记忆操作调用 `mnemosyne` CLI,会话级操作则通过 CLI venv 解释器运行小型 Python helper。Node 侧不重复实现记忆逻辑。但它已不再是**纯**无状态代理,因为迁移路由会直连 SQLite 写入 scope 元数据,写过滤器 env 桥接每次调用都会读 `config.yaml`。 ## 设计与实现方案 见 [docs/design.md](docs/design.md)。 ## 开发 ```bash pnpm install pnpm test # node --test(124 例:103 单元 + 17 集成 + 4 client) ``` ## License MIT