dsh-layered-memory 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +186 -0
  3. package/assets/readme/hero.svg +58 -0
  4. package/cordis.patch.yml +16 -0
  5. package/dist/client.js +1066 -0
  6. package/dist/config.d.ts +263 -0
  7. package/dist/config.js +65 -0
  8. package/dist/hooks/capture.d.ts +16 -0
  9. package/dist/hooks/capture.js +160 -0
  10. package/dist/hooks/recall.d.ts +31 -0
  11. package/dist/hooks/recall.js +201 -0
  12. package/dist/index.d.ts +190 -0
  13. package/dist/index.js +234 -0
  14. package/dist/llm.d.ts +32 -0
  15. package/dist/llm.js +128 -0
  16. package/dist/pipeline/l1.d.ts +19 -0
  17. package/dist/pipeline/l1.js +226 -0
  18. package/dist/pipeline/l2.d.ts +13 -0
  19. package/dist/pipeline/l2.js +77 -0
  20. package/dist/pipeline/l3.d.ts +15 -0
  21. package/dist/pipeline/l3.js +72 -0
  22. package/dist/pipeline/runner.d.ts +44 -0
  23. package/dist/pipeline/runner.js +132 -0
  24. package/dist/prompts/l1-dedup.d.ts +20 -0
  25. package/dist/prompts/l1-dedup.js +244 -0
  26. package/dist/prompts/l1-extraction.d.ts +18 -0
  27. package/dist/prompts/l1-extraction.js +434 -0
  28. package/dist/prompts/persona.d.ts +23 -0
  29. package/dist/prompts/persona.js +234 -0
  30. package/dist/prompts/scene.d.ts +33 -0
  31. package/dist/prompts/scene.js +408 -0
  32. package/dist/settings.d.ts +27 -0
  33. package/dist/settings.js +73 -0
  34. package/dist/stats.d.ts +46 -0
  35. package/dist/stats.js +234 -0
  36. package/dist/store/bm25.d.ts +19 -0
  37. package/dist/store/bm25.js +62 -0
  38. package/dist/store/embedding.d.ts +68 -0
  39. package/dist/store/embedding.js +133 -0
  40. package/dist/store/io.d.ts +13 -0
  41. package/dist/store/io.js +75 -0
  42. package/dist/store/l0.d.ts +28 -0
  43. package/dist/store/l0.js +148 -0
  44. package/dist/store/l1.d.ts +70 -0
  45. package/dist/store/l1.js +239 -0
  46. package/dist/store/persona.d.ts +15 -0
  47. package/dist/store/persona.js +60 -0
  48. package/dist/store/scenes.d.ts +23 -0
  49. package/dist/store/scenes.js +150 -0
  50. package/dist/store/search-utils.d.ts +22 -0
  51. package/dist/store/search-utils.js +71 -0
  52. package/dist/store/session-modes.d.ts +24 -0
  53. package/dist/store/session-modes.js +102 -0
  54. package/dist/store/sqlite.d.ts +121 -0
  55. package/dist/store/sqlite.js +922 -0
  56. package/dist/store/state.d.ts +35 -0
  57. package/dist/store/state.js +62 -0
  58. package/dist/tools/index.d.ts +21 -0
  59. package/dist/tools/index.js +169 -0
  60. package/dist/types.d.ts +86 -0
  61. package/dist/types.js +7 -0
  62. package/dist/util/filelog.d.ts +4 -0
  63. package/dist/util/filelog.js +43 -0
  64. package/dist/util/sanitize.d.ts +10 -0
  65. package/dist/util/sanitize.js +66 -0
  66. package/dist/util/text.d.ts +11 -0
  67. package/dist/util/text.js +43 -0
  68. package/package.json +80 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 JunNanLYS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,186 @@
1
+ <p align="center">
2
+ <img src="./assets/readme/hero.svg" width="100%"
3
+ alt="dsh-layered-memory:对话自动分层蒸馏成记忆,模型每步前自动召回注入(L0 原始对话 → L1 原子记忆 → L2 场景块 → L3 核心画像)">
4
+ </p>
5
+
6
+ # dsh-layered-memory
7
+
8
+ DeepSeek Harness 的**分层蒸馏记忆插件**(持久组合插件):对话在后台自动完成
9
+ L0 捕获 → L1 原子记忆 → L2 场景整合 → L3 画像蒸馏,模型每一步前自动把相关记忆
10
+ 注入上下文——用户与模型都不需要做任何操作。移植自
11
+ [MemoryCore](https://github.com/TencentDB-Agent-Memory)(TencentDB Agent Memory)的
12
+ 管线设计:Prompt 原样保留,仅把"LLM 操作文件"的 L2/L3 流程适配为"LLM 输出、工程侧执行"。
13
+
14
+ ## 核心能力
15
+
16
+ ### 分层记忆(L0–L3)
17
+
18
+ | 层 | 内容 | 存储 |
19
+ | --- | --- | --- |
20
+ | L0 | 每轮 user/assistant 消息(清洗去噪、剥离代码块与注入标签) | `conversations/YYYY-MM-DD.jsonl` + SQLite |
21
+ | L1 | 情境切分 + 记忆提取(chat: persona/episodic/instruction;work: work_fact/work_task/work_method/work_artifact)+ 冲突检测去重合并,每条带族标签 | `records/YYYY-MM-DD.jsonl` + SQLite(FTS5 + 可选向量,family 列) |
22
+ | L2 | 把新记忆整合为 Markdown 场景文档(META 块、热度管理、合并上限),按族各自整合 | `scenes/chat/*.md`、`scenes/work/*.md` |
23
+ | L3 | 从变化场景蒸馏画像(chat: 用户画像 ≤2000 字;work: Team Operating Doctrine ≤1200 字),每族一份 | `persona-chat.md`、`persona-work.md` |
24
+
25
+ 管线原则:所有蒸馏调用复用 DSH 自身的 `ctx.llm`;任何阶段失败只记日志、绝不阻塞
26
+ Agent 循环;召回注入用标签包裹、捕获侧自动剥离,防止反馈循环。
27
+
28
+ ### 会话级记忆档位
29
+
30
+ 每个会话可独立选择记忆档位,**写入与召回同档**:
31
+
32
+ | 档位 | 蒸馏(写入) | 召回(注入) |
33
+ | --- | --- | --- |
34
+ | `自动`(默认) | 合并词表 prompt 单次抽取,个人三类 + 工作四类全开,按 type 前缀落族标签 | 两族全召回;画像/场景导航按类别归组、`<domain>` 分域结构化注入 |
35
+ | `chat` | 窄 prompt 只提个人三类,只入 chat 族 | 只查 chat 记忆 + chat 画像/场景导航 |
36
+ | `work` | 窄 prompt 只提工作四类,只入 work 族 | 只查 work 记忆 + work 画像/场景导航 |
37
+ | `关闭` | 不写 L0、不蒸馏 | 不召回;三个记忆工具返回"已隐身"提示 |
38
+
39
+ - **控件**:输入栏内、模式选择器右侧的 pill(`记忆·自动`),点击在上方浮出 macOS 风格
40
+ 滑动选择器——拖拽松手吸附最近档位;
41
+ - **默认档** = 配置 `family`(`auto|chat|work`,默认 `auto`);每会话的选择按 sessionId
42
+ 持久化到 `session-modes.json`,重启/恢复会话不丢;中途切档下一轮生效,已提取记忆留在原族;
43
+ - 与全局开关叠加(全局是总闸);L2/L3 完全分族,间族内容不渗透。
44
+
45
+ ### 记忆浏览器(设置页 → 记忆)
46
+
47
+ 多 Tab 页面,两族混合视图:**概览**(各层计数 + 记忆模式开关面板,5 秒自动刷新)、
48
+ **记忆**(L1 卡片列表,关键词/类型/情境筛选)、**场景**(L2 全文)、**画像**(L3 全文)、
49
+ **日志**(`memory.log` 尾部 200 行)。开关走官方 settings 服务(命名空间 `dsh-memory`,
50
+ 实时生效、重启保留);生效规则 = **静态 config(部署上限)AND 运行时开关**,
51
+ 数据通道为 loopback RPC(`dsh-memory/*`)。
52
+
53
+ ## 快速开始
54
+
55
+ 需要 Node ≥ 22.16 与已安装的 dsh CLI(dsh 是 pnpm 转发器,未装 pnpm 时先 `npm i -g pnpm`)。
56
+
57
+ ```bash
58
+ # 从 npm 安装(推荐;可 pin 版本,如 @0.5.3)
59
+ dsh plugin --profile web add dsh-layered-memory
60
+
61
+ # 或从 GitHub 仓库安装
62
+ dsh plugin --profile web add https://github.com/JunNanLYS/dsh-layered-memory
63
+
64
+ # 或从本地路径安装(开发/调试,link: 指向仓库,npm run build + 重启 dsh 即生效)
65
+ dsh plugin --profile web add /path/to/dsh-layered-memory
66
+ ```
67
+
68
+ 本包声明了 `dsh.bundle` 组合包层(`cordis.patch.yml`),安装后会**自动挂载插件行**——
69
+ 不需要再手改 `$DSH_HOME/profiles/web/cordis.patch.yml`。然后重启 DeepSeek Harness,
70
+ 验证:`~/.dsh/memory/` 下出现 `conversations/ records/ scenes/` 目录和 `memory.db`
71
+ 即插件 apply 成功;设置页出现"记忆"页面、输入栏出现档位 pill 即 client 半边就绪。
72
+
73
+ > ⚠️ **安全提示**:安装插件 = 以你的权限运行第三方代码。本插件会读取会话内容、
74
+ > 在数据目录写文件、调用你配置的 LLM/embedding 服务;介意请先审查源码(`src/`)。
75
+
76
+ **卸载**:`dsh plugin --profile web remove dsh-layered-memory` + 重启。数据保留在
77
+ `~/.dsh/memory/`,不需要时手动删除整个目录即可。
78
+
79
+ ### 从源码开发
80
+
81
+ ```bash
82
+ git clone https://github.com/JunNanLYS/dsh-layered-memory
83
+ cd dsh-layered-memory
84
+ npm install && npm run build
85
+ dsh plugin --profile web add . # link: 安装,改代码后 npm run build + 重启 dsh 即生效
86
+ npm run smoke # 冒烟测试(先重编:见下方命令)
87
+ npx tsc src/smoke.ts --outDir dist-smoke --module nodenext --moduleResolution nodenext --target es2022 --strict --skipLibCheck --esModuleInterop
88
+ ```
89
+
90
+ ## 配置
91
+
92
+ 覆盖配置写在 profile 自己的 `cordis.patch.yml`,用**顶层裸 patch 条目**(直接 `id:`,
93
+ 不要包在 `insert:` 里——insert 与 bundle 层同 id 追加会导致 `duplicate loader entry id`
94
+ 启动失败):
95
+
96
+ ```yaml
97
+ - id: dsh-memory
98
+ name: dsh-layered-memory
99
+ config: # 键按行整体替换(不深合并),按需写全要保留的键
100
+ family: auto # 新会话默认档:auto | chat | work
101
+ llm: # 蒸馏模型路由(不写则跟随当前默认模型)
102
+ provider: ''
103
+ model: ''
104
+ ```
105
+
106
+ | 字段 | 默认 | 说明 |
107
+ | --- | --- | --- |
108
+ | `family` | `auto` | 新会话默认记忆档位:`auto`(双族自动)\| `chat`(个人)\| `work`(工作);会话内可用输入栏控件临时切换 |
109
+ | `dataDir` | `$DSH_HOME/memory` | 数据目录 |
110
+ | `capture.enabled` | `true` | L0 捕获 |
111
+ | `capture.stripCodeBlocks` | `true` | 助手消息剥离代码块 |
112
+ | `capture.maxMessageChars` | `4000` | 单条消息最大字符数 |
113
+ | `extract.enabled` | `true` | L1 抽取 |
114
+ | `extract.minMessages` | `1` | 攒够 N 条新消息跑一次 L1 抽取 |
115
+ | `extract.backgroundMessages` | `10` | 抽取时附带的背景消息条数 |
116
+ | `extract.candidatePool` | `5` | 去重候选池大小 |
117
+ | `l2.enabled` | `true` | L2 场景整合 |
118
+ | `l2.minNewMemories` | `5` | 距上次 L2 整合的新记忆阈值 |
119
+ | `l2.maxScenes` | `12` | 场景块数量上限 |
120
+ | `l2.sceneContextLimit` | `3` | L2 prompt 附带的相似场景全文上限 |
121
+ | `l3.enabled` | `true` | L3 画像蒸馏 |
122
+ | `l3.interval` | `20` | L3 蒸馏间隔(新记忆条数) |
123
+ | `recall.enabled` | `true` | 自动召回 |
124
+ | `recall.maxResults` | `5` | 每步召回注入的 L1 条数 |
125
+ | `recall.strategy` | `hybrid` | 检索策略:`keyword` / `embedding` / `hybrid` |
126
+ | `recall.scoreThreshold` | `0.3` | 召回分数阈值(低于不注入;仅 keyword/embedding 策略生效,hybrid 融合前不过滤;工具路径不过滤) |
127
+ | `embedding.enabled` | `false` | 向量检索开关;关闭即纯 FTS 运行 |
128
+ | `embedding.baseUrl` | 空 | OpenAI 兼容 /embeddings 地址(如 `https://api.siliconflow.cn/v1`) |
129
+ | `embedding.apiKey` | 空 | API Key |
130
+ | `embedding.model` | 空 | embedding 模型名 |
131
+ | `embedding.dimensions` | `0` | 向量维度(启用时必填,须与模型输出一致) |
132
+ | `llm.provider/model` | 空 | 蒸馏模型覆盖(默认用当前默认选择) |
133
+ | `llm.maxTokens` | `20000` | 单次蒸馏输出 token 上限(全阶段统一;推理模型的 reasoning 与正文共享该预算,过低会被思考吃光导致正文 0 字符) |
134
+ | `llm.temperature` | `0.3` | 蒸馏温度 |
135
+ | `llm.maxInputChars` | `700000` | 单次蒸馏输入字符预算(超限的 L1 输入自动分块抽取) |
136
+ | `tools` | `true` | 是否注册模型可调用的记忆工具 |
137
+
138
+ ## 存储布局
139
+
140
+ 对齐 MemoryCore 官方双写架构:JSONL 追加文件(`conversations/`、`records/` 按天分片)是
141
+ 备份/恢复的事实源,**只增不改**;`memory.db`(node:sqlite + WAL + FTS5 BM25 + sqlite-vec
142
+ 余弦向量)是主检索引擎,去重合并的更新/删除只动检索库。
143
+
144
+ - **检索三策略**(`recall.strategy`):`keyword`(FTS5 BM25)/ `embedding`(vec0 余弦 KNN)/
145
+ `hybrid`(双路并行 + RRF k=60 融合,默认);`conversation_search`(L0)同款融合;
146
+ - **向量能力可选**:默认关闭(纯 FTS)。DSH 的 `ctx.llm` 无 embeddings 端点,启用需自备
147
+ 任意 OpenAI 兼容 `/embeddings` 服务(配置 `embedding.*`);配置变化自动 drop 向量表并
148
+ 后台全量重嵌入;
149
+ - **降级链**:sqlite-vec 加载失败 → 纯 FTS;embedding 调用失败 → 该次降级 FTS 并告警一次;
150
+ 检索库初始化失败 → 记忆功能整体停用但 dsh 本体照常启动;
151
+ - **替换缝**:`L1Store.search()` 是唯一检索入口。
152
+
153
+ ```
154
+ memory/
155
+ ├── memory.db # SQLite 检索库(L0/L1 元数据 + FTS5 + 可选向量;L1 带 family 列)
156
+ ├── conversations/2026-01-01.jsonl # L0 原始对话事实源(每天一个文件,追加;不分族)
157
+ ├── records/2026-01-01.jsonl # L1 原子记忆事实源(每天一个文件,追加;含 family 字段)
158
+ ├── scenes/chat/*.md # L2 场景块(chat 族)
159
+ ├── scenes/work/*.md # L2 场景块(work 族)
160
+ ├── persona-chat.md # L3 画像(chat 族:用户画像)
161
+ ├── persona-work.md # L3 画像(work 族:Team Operating Doctrine)
162
+ ├── state.json # 管线 checkpoint(v2 分族:families.chat / families.work)
163
+ ├── session-modes.json # 会话档位映射(sessionId → 档位,>90 天自动清理)
164
+ └── memory.log # 诊断日志(info+,超 2MB 轮转为 memory.log.1)
165
+ ```
166
+
167
+ ## 日志与排查
168
+
169
+ dsh 宿主把插件日志打到控制台,插件将 info 及以上镜像到数据目录 `memory.log`。一轮对话的
170
+ 典型日志路径:`L0 捕获 turn=N …条` → `L0 落盘 N 条` → `蒸馏管线开始(…待重试 M 条)` →
171
+ `LLM 调用 provider/model:输入 x → 输出 y 字符(z s)` → `L1 抽取完成(…新增 Y 条)` →
172
+ `蒸馏管线结束`;下一轮有 `召回命中 N 条 L1`。LLM 空输出会带完整诊断(finish 原因 /
173
+ token 计数 / reasoning 摘录);JSON 解析失败附带模型原始输出前 400 字符;所有失败 warn
174
+ 携带错误堆栈首帧。
175
+
176
+ ## 与 MemoryCore 的差异
177
+
178
+ - 内嵌完整管线(不依赖外部 Gateway),蒸馏复用 DSH 自己的 LLM;
179
+ - L2/L3 由"LLM 操作文件工具"改为"LLM 输出操作 JSON / 完整文档,工程侧执行";
180
+ - 召回注入点在 `agent/pre-step` + agent 作用域 `systemPrompt.context`(DSH 原生事件/服务);
181
+ - 存储/检索即官方 sqlite 后端的单机裁剪版(裁掉多租户隔离列、TCVDB 云后端、审计表;
182
+ 分词用自带 CJK 二元组替代 jieba,保持零原生依赖——仅 sqlite-vec 一个原生扩展,加载失败自动降级)。
183
+
184
+ ## License
185
+
186
+ [MIT](LICENSE)
@@ -0,0 +1,58 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg"
2
+ width="1200" height="400" viewBox="0 0 1200 400"
3
+ role="img" aria-labelledby="title desc">
4
+ <title id="title">dsh-layered-memory</title>
5
+ <desc id="desc">DeepSeek Harness 分层蒸馏记忆插件:对话经 L0 捕获、L1 原子记忆、L2 场景整合、L3 画像蒸馏四层提炼,宽度递减表示数据精炼;模型每一步前自动召回注入。</desc>
6
+
7
+ <rect width="1200" height="400" rx="26" fill="#0B0E14"/>
8
+
9
+ <!-- ── 标题区 ── -->
10
+ <g id="title-block" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">
11
+ <text x="64" y="88" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
12
+ font-size="22" letter-spacing="2" fill="#8B93A7">DEEPSEEK HARNESS · PERSISTENT PLUGIN</text>
13
+ <text x="64" y="152" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
14
+ font-size="48" font-weight="700" fill="#F2F3F5">dsh-layered-memory</text>
15
+ <text x="64" y="198" font-size="34" fill="#C9CFDB">对话自动分层蒸馏成记忆,</text>
16
+ <text x="64" y="244" font-size="34" fill="#C9CFDB">模型每步前自动召回注入。</text>
17
+ <text x="64" y="288" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
18
+ font-size="18" fill="#6B7484">MIT LICENSE · v0.5.0 · SESSION-LEVEL MODES</text>
19
+ </g>
20
+
21
+ <!-- ── 分层管线(宽度递减 = 数据精炼) ── -->
22
+ <g id="distill-pipeline">
23
+ <!-- L0 -->
24
+ <rect x="704" y="96" width="436" height="46" rx="12" fill="#11161F" stroke="#232A38" stroke-width="1.5"/>
25
+ <circle cx="732" cy="119" r="6" fill="#2DD4BF"/>
26
+ <text x="760" y="126" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="20" fill="#2DD4BF">L0</text>
27
+ <text x="800" y="126" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif" font-size="20" fill="#F2F3F5">原始对话</text>
28
+ <text x="1120" y="126" text-anchor="end" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="16" fill="#6B7484">conversations/</text>
29
+ <!-- L1 -->
30
+ <rect x="704" y="158" width="396" height="46" rx="12" fill="#11161F" stroke="#232A38" stroke-width="1.5"/>
31
+ <circle cx="732" cy="181" r="6" fill="#2DD4BF"/>
32
+ <text x="760" y="188" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="20" fill="#2DD4BF">L1</text>
33
+ <text x="800" y="188" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif" font-size="20" fill="#F2F3F5">原子记忆</text>
34
+ <text x="1080" y="188" text-anchor="end" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="16" fill="#6B7484">records/</text>
35
+ <!-- L2 -->
36
+ <rect x="704" y="220" width="356" height="46" rx="12" fill="#11161F" stroke="#232A38" stroke-width="1.5"/>
37
+ <circle cx="732" cy="243" r="6" fill="#2DD4BF"/>
38
+ <text x="760" y="250" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="20" fill="#2DD4BF">L2</text>
39
+ <text x="800" y="250" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif" font-size="20" fill="#F2F3F5">场景块</text>
40
+ <text x="1040" y="250" text-anchor="end" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="16" fill="#6B7484">scenes/</text>
41
+ <!-- L3 -->
42
+ <rect x="704" y="282" width="316" height="46" rx="12" fill="#11161F" stroke="#232A38" stroke-width="1.5"/>
43
+ <circle cx="732" cy="305" r="6" fill="#2DD4BF"/>
44
+ <text x="760" y="312" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="20" fill="#2DD4BF">L3</text>
45
+ <text x="800" y="312" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif" font-size="20" fill="#F2F3F5">核心画像</text>
46
+ <text x="1010" y="312" text-anchor="end" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="16" fill="#6B7484">persona-*.md</text>
47
+
48
+ <!-- 层间蒸馏箭头(左侧圆点列) -->
49
+ <path d="M732 142 v10 l-5 -5 M732 152 l5 -5" stroke="#2DD4BF" stroke-width="2" fill="none"/>
50
+ <path d="M732 204 v10 l-5 -5 M732 214 l5 -5" stroke="#2DD4BF" stroke-width="2" fill="none"/>
51
+ <path d="M732 266 v10 l-5 -5 M732 276 l5 -5" stroke="#2DD4BF" stroke-width="2" fill="none"/>
52
+
53
+ <!-- 召回回路说明 -->
54
+ <circle cx="716" cy="352" r="5" fill="#F5A623"/>
55
+ <text x="734" y="357" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
56
+ font-size="18" fill="#8B93A7">pre-step 自动召回注入 · 与写入同档</text>
57
+ </g>
58
+ </svg>
@@ -0,0 +1,16 @@
1
+ # dsh-layered-memory 组合包层:安装(dsh plugin --profile <name> add dsh-layered-memory)
2
+ # 后自动挂载插件行,无需再手改 profile 的 cordis.patch.yml。
3
+ # 覆盖配置请在 profile 自己的 cordis.patch.yml 里写顶层裸 patch(直接 id:,不要包 insert:,
4
+ # 同 id 再 insert 会报 duplicate loader entry id 启动失败):
5
+ # - id: dsh-memory
6
+ # name: dsh-layered-memory
7
+ # config: { family: auto } # 键按行整体替换,不深合并
8
+ - insert:
9
+ - id: dsh-memory
10
+ name: dsh-layered-memory
11
+ # config: # 全部字段有默认值,按需覆盖:
12
+ # family: auto # 新会话默认档:auto | chat | work
13
+ # dataDir: '' # 默认 $DSH_HOME/memory
14
+ # llm:
15
+ # provider: '' # 蒸馏模型路由(默认跟随当前默认模型)
16
+ # model: ''