dsh-layered-memory 0.6.0 → 0.7.0

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 (52) hide show
  1. package/README.en.md +101 -81
  2. package/README.md +91 -71
  3. package/assets/img/Hero.png +0 -0
  4. package/assets/img/Layers.png +0 -0
  5. package/assets/img/Modes.png +0 -0
  6. package/assets/img/ui-dark.jpg +0 -0
  7. package/assets/img/ui-light.jpg +0 -0
  8. package/assets/readme/flow.svg +189 -0
  9. package/assets/readme/storage.svg +115 -0
  10. package/dist/client.js +1242 -325
  11. package/dist/config.d.ts +12 -0
  12. package/dist/config.js +20 -17
  13. package/dist/hooks/capture.d.ts +17 -1
  14. package/dist/hooks/capture.js +45 -11
  15. package/dist/hooks/recall.d.ts +7 -0
  16. package/dist/hooks/recall.js +20 -4
  17. package/dist/index.d.ts +8 -0
  18. package/dist/index.js +112 -44
  19. package/dist/pipeline/rebuild.d.ts +80 -0
  20. package/dist/pipeline/rebuild.js +307 -0
  21. package/dist/pipeline/runner.d.ts +42 -4
  22. package/dist/pipeline/runner.js +125 -21
  23. package/dist/settings.js +79 -20
  24. package/dist/stats.d.ts +8 -1
  25. package/dist/stats.js +156 -14
  26. package/dist/store/download-queue.d.ts +71 -0
  27. package/dist/store/download-queue.js +313 -0
  28. package/dist/store/embedding-source.d.ts +160 -0
  29. package/dist/store/embedding-source.js +421 -0
  30. package/dist/store/embedding.d.ts +3 -1
  31. package/dist/store/embedding.js +5 -0
  32. package/dist/store/l0.d.ts +13 -5
  33. package/dist/store/l0.js +33 -6
  34. package/dist/store/l1.d.ts +15 -5
  35. package/dist/store/l1.js +40 -15
  36. package/dist/store/local-embedding.d.ts +64 -0
  37. package/dist/store/local-embedding.js +120 -0
  38. package/dist/store/model-catalog.d.ts +45 -0
  39. package/dist/store/model-catalog.js +78 -0
  40. package/dist/store/pending.d.ts +15 -0
  41. package/dist/store/pending.js +56 -0
  42. package/dist/store/runtime-installer.d.ts +60 -0
  43. package/dist/store/runtime-installer.js +181 -0
  44. package/dist/store/sqlite.d.ts +68 -7
  45. package/dist/store/sqlite.js +414 -71
  46. package/dist/store/state.d.ts +6 -0
  47. package/dist/store/state.js +11 -0
  48. package/dist/tools/index.js +6 -4
  49. package/dist/util/filelog.d.ts +2 -0
  50. package/dist/util/filelog.js +20 -3
  51. package/package.json +1 -1
  52. package/assets/readme/hero.svg +0 -58
@@ -0,0 +1,189 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg"
2
+ xmlns:xlink="http://www.w3.org/1999/xlink"
3
+ width="1200" height="600" viewBox="0 0 1200 600"
4
+ role="img" aria-labelledby="flowTitle flowDesc">
5
+ <title id="flowTitle">dsh-layered-memory 运行时数据流</title>
6
+ <desc id="flowDesc">左侧 User 与 Assistant 的会话事件(session/event)流入中间的 dsh-layered-memory 插件:L0 捕获、L1–L3 蒸馏、检索召回与记忆工具;插件在 agent/pre-step 把相关记忆注入右侧 DeepSeek Harness 核心,蒸馏调用复用核心的 ctx.llm;数据双写 ~/.dsh/memory/。</desc>
7
+
8
+ <defs>
9
+ <marker id="arr-teal" markerWidth="9" markerHeight="9" refX="7" refY="4" orient="auto">
10
+ <path d="M0 0 L8 4 L0 8 Z" fill="#2DD4BF"/>
11
+ </marker>
12
+ <marker id="arr-orange" markerWidth="9" markerHeight="9" refX="7" refY="4" orient="auto">
13
+ <path d="M0 0 L8 4 L0 8 Z" fill="#F5A623"/>
14
+ </marker>
15
+ </defs>
16
+
17
+ <rect width="1200" height="600" rx="26" fill="#0B0E14"/>
18
+
19
+ <g font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">
20
+
21
+ <!-- ── 图例 ── -->
22
+ <circle cx="72" cy="58" r="5" fill="#2DD4BF"/>
23
+ <text x="86" y="64" font-size="18" fill="#C9CFDB">捕获 / 写入</text>
24
+ <circle cx="250" cy="58" r="5" fill="#F5A623"/>
25
+ <text x="264" y="64" font-size="18" fill="#C9CFDB">召回 / 注入</text>
26
+
27
+ <!-- ── 左列:User ── -->
28
+ <g id="node-user">
29
+ <rect x="64" y="120" width="190" height="92" rx="16" fill="#11161F" stroke="#232A38" stroke-width="1.5"/>
30
+ <circle cx="102" cy="152" r="9" fill="none" stroke="#8B93A7" stroke-width="2"/>
31
+ <path d="M86 182 a16 16 0 0 1 32 0" fill="none" stroke="#8B93A7" stroke-width="2"/>
32
+ <text x="126" y="162" font-size="20" font-weight="700" fill="#F2F3F5">User</text>
33
+ <text x="126" y="188" font-size="18" fill="#8B93A7">用户消息</text>
34
+ </g>
35
+
36
+ <!-- ── 左列:Assistant ── -->
37
+ <g id="node-assistant">
38
+ <rect x="64" y="348" width="190" height="92" rx="16" fill="#11161F" stroke="#232A38" stroke-width="1.5"/>
39
+ <path d="M102 376 L106 390 L120 394 L106 398 L102 412 L98 398 L84 394 L98 390 Z" fill="#8B93A7"/>
40
+ <text x="126" y="392" font-size="20" font-weight="700" fill="#F2F3F5">Assistant</text>
41
+ <text x="126" y="418" font-size="18" fill="#8B93A7">助手回复</text>
42
+ </g>
43
+
44
+ <!-- ── 中列:插件 ── -->
45
+ <g id="node-plugin">
46
+ <rect x="430" y="96" width="290" height="356" rx="18" fill="#11161F" stroke="#2DD4BF" stroke-opacity="0.55" stroke-width="1.5"/>
47
+ <text x="575" y="138" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
48
+ font-size="22" font-weight="700" fill="#F2F3F5">dsh-layered-memory</text>
49
+ <text x="575" y="166" text-anchor="middle" font-size="18" fill="#8B93A7">分层蒸馏记忆插件</text>
50
+
51
+ <g id="plugin-modules">
52
+ <rect x="452" y="188" width="246" height="46" rx="10" fill="#0D1119" stroke="#232A38"/>
53
+ <circle cx="470" cy="211" r="4" fill="#2DD4BF"/>
54
+ <text x="486" y="218" font-size="19" fill="#F2F3F5">L0 捕获 capture</text>
55
+
56
+ <rect x="452" y="244" width="246" height="46" rx="10" fill="#0D1119" stroke="#232A38"/>
57
+ <circle cx="470" cy="267" r="4" fill="#2DD4BF"/>
58
+ <text x="486" y="274" font-size="19" fill="#F2F3F5">L1–L3 蒸馏 distill</text>
59
+
60
+ <rect x="452" y="300" width="246" height="46" rx="10" fill="#0D1119" stroke="#232A38"/>
61
+ <circle cx="470" cy="323" r="4" fill="#2DD4BF"/>
62
+ <text x="486" y="330" font-size="19" fill="#F2F3F5">检索召回 · 三策略</text>
63
+
64
+ <rect x="452" y="356" width="246" height="46" rx="10" fill="#0D1119" stroke="#232A38"/>
65
+ <circle cx="470" cy="379" r="4" fill="#2DD4BF"/>
66
+ <text x="486" y="386" font-size="19" fill="#F2F3F5">记忆工具 ×3</text>
67
+ </g>
68
+ </g>
69
+
70
+ <!-- ── 存储条 ── -->
71
+ <g id="node-storage">
72
+ <path id="sto-write" d="M545 456 V482" stroke="#2DD4BF" stroke-width="2.5" fill="none" marker-end="url(#arr-teal)"/>
73
+ <path id="sto-read" d="M605 482 V456" stroke="#F5A623" stroke-width="2.5" fill="none" marker-end="url(#arr-orange)"/>
74
+ <text x="531" y="472" text-anchor="end" font-size="16" fill="#2DD4BF">写</text>
75
+ <text x="619" y="472" font-size="16" fill="#F5A623">读</text>
76
+ <circle r="3.5" fill="#2DD4BF" cx="545" cy="470">
77
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
78
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
79
+ <animateMotion dur="1.6s" begin="0s" repeatCount="indefinite"><mpath href="#sto-write" xlink:href="#sto-write"/></animateMotion>
80
+ </circle>
81
+ <circle r="3.5" fill="#F5A623" cx="605" cy="468">
82
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
83
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
84
+ <animateMotion dur="1.6s" begin="-0.8s" repeatCount="indefinite"><mpath href="#sto-read" xlink:href="#sto-read"/></animateMotion>
85
+ </circle>
86
+
87
+ <rect x="430" y="486" width="290" height="54" rx="12" fill="#0D1119" stroke="#232A38" stroke-dasharray="6 4"/>
88
+ <text x="575" y="509" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
89
+ font-size="18" fill="#2DD4BF">~/.dsh/memory/</text>
90
+ <text x="575" y="531" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
91
+ font-size="16" fill="#6B7484">memory.db · JSONL · Markdown</text>
92
+ </g>
93
+
94
+ <!-- ── 右列:DSH 核心 ── -->
95
+ <g id="node-core">
96
+ <rect x="920" y="96" width="216" height="356" rx="18" fill="#11161F" stroke="#232A38" stroke-width="1.5"/>
97
+ <text x="1028" y="138" text-anchor="middle" font-size="22" font-weight="700" fill="#F2F3F5">DSH 核心</text>
98
+ <text x="1028" y="166" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
99
+ font-size="18" fill="#8B93A7">DeepSeek Harness</text>
100
+
101
+ <g id="core-modules">
102
+ <rect x="936" y="188" width="184" height="46" rx="10" fill="#0D1119" stroke="#232A38"/>
103
+ <circle cx="954" cy="211" r="4" fill="#F5A623"/>
104
+ <text x="970" y="218" font-size="19" fill="#F2F3F5">agent 循环</text>
105
+
106
+ <rect x="936" y="244" width="184" height="46" rx="10" fill="#0D1119" stroke="#232A38"/>
107
+ <circle cx="954" cy="267" r="4" fill="#F5A623"/>
108
+ <text x="970" y="274" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="19" fill="#F2F3F5">ctx.llm</text>
109
+
110
+ <rect x="936" y="300" width="184" height="46" rx="10" fill="#0D1119" stroke="#232A38"/>
111
+ <circle cx="954" cy="323" r="4" fill="#F5A623"/>
112
+ <text x="970" y="330" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="19" fill="#F2F3F5">systemPrompt</text>
113
+
114
+ <rect x="936" y="356" width="184" height="46" rx="10" fill="#0D1119" stroke="#232A38"/>
115
+ <circle cx="954" cy="379" r="4" fill="#F5A623"/>
116
+ <text x="970" y="386" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="19" fill="#F2F3F5">tools·settings</text>
117
+ </g>
118
+ </g>
119
+
120
+ <!-- ── 连接 1:User → 插件(捕获) ── -->
121
+ <path id="cap-user" d="M254 166 H430" stroke="#2DD4BF" stroke-width="2.5" fill="none" marker-end="url(#arr-teal)"/>
122
+ <text x="342" y="142" text-anchor="middle" font-size="18" fill="#C9CFDB">对话输入</text>
123
+ <circle r="4" fill="#2DD4BF" cx="320" cy="166">
124
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
125
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
126
+ <animateMotion dur="2.4s" begin="0s" repeatCount="indefinite"><mpath href="#cap-user" xlink:href="#cap-user"/></animateMotion>
127
+ </circle>
128
+ <circle r="4" fill="#2DD4BF" opacity="0.7" cx="368" cy="166">
129
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
130
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
131
+ <animateMotion dur="2.4s" begin="-1.2s" repeatCount="indefinite"><mpath href="#cap-user" xlink:href="#cap-user"/></animateMotion>
132
+ </circle>
133
+
134
+ <!-- ── 连接 2:Assistant → 插件(捕获) ── -->
135
+ <path id="cap-asst" d="M254 394 H430" stroke="#2DD4BF" stroke-width="2.5" fill="none" marker-end="url(#arr-teal)"/>
136
+ <text x="342" y="370" text-anchor="middle" font-size="18" fill="#C9CFDB">回复捕获</text>
137
+ <circle r="4" fill="#2DD4BF" cx="320" cy="394">
138
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
139
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
140
+ <animateMotion dur="2.4s" begin="-0.6s" repeatCount="indefinite"><mpath href="#cap-asst" xlink:href="#cap-asst"/></animateMotion>
141
+ </circle>
142
+ <circle r="4" fill="#2DD4BF" opacity="0.7" cx="368" cy="394">
143
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
144
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
145
+ <animateMotion dur="2.4s" begin="-1.8s" repeatCount="indefinite"><mpath href="#cap-asst" xlink:href="#cap-asst"/></animateMotion>
146
+ </circle>
147
+
148
+ <!-- ── 连接 3:插件 → 核心(召回注入) ── -->
149
+ <path id="flow-recall" d="M720 192 L920 214" stroke="#F5A623" stroke-width="2.5" fill="none" marker-end="url(#arr-orange)"/>
150
+ <text x="820" y="166" text-anchor="middle" font-size="18" fill="#F5A623">召回注入 pre-step</text>
151
+ <circle r="3.5" fill="#F5A623" cx="770" cy="198">
152
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
153
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
154
+ <animateMotion dur="2.4s" begin="0s" repeatCount="indefinite"><mpath href="#flow-recall" xlink:href="#flow-recall"/></animateMotion>
155
+ </circle>
156
+ <circle r="3.5" fill="#F5A623" cx="815" cy="202.5">
157
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
158
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
159
+ <animateMotion dur="2.4s" begin="-0.8s" repeatCount="indefinite"><mpath href="#flow-recall" xlink:href="#flow-recall"/></animateMotion>
160
+ </circle>
161
+ <circle r="3.5" fill="#F5A623" cx="860" cy="207">
162
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
163
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
164
+ <animateMotion dur="2.4s" begin="-1.6s" repeatCount="indefinite"><mpath href="#flow-recall" xlink:href="#flow-recall"/></animateMotion>
165
+ </circle>
166
+
167
+ <!-- ── 连接 4:核心 → 插件(蒸馏复用 LLM) ── -->
168
+ <path id="flow-distill" d="M920 320 L720 342" stroke="#2DD4BF" stroke-width="2.5" fill="none" marker-end="url(#arr-teal)"/>
169
+ <text x="820" y="374" text-anchor="middle" font-size="18" fill="#2DD4BF">蒸馏复用 ctx.llm</text>
170
+ <circle r="3.5" fill="#2DD4BF" cx="865" cy="327">
171
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
172
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
173
+ <animateMotion dur="2.4s" begin="-0.4s" repeatCount="indefinite"><mpath href="#flow-distill" xlink:href="#flow-distill"/></animateMotion>
174
+ </circle>
175
+ <circle r="3.5" fill="#2DD4BF" cx="820" cy="331">
176
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
177
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
178
+ <animateMotion dur="2.4s" begin="-1.2s" repeatCount="indefinite"><mpath href="#flow-distill" xlink:href="#flow-distill"/></animateMotion>
179
+ </circle>
180
+ <circle r="3.5" fill="#2DD4BF" cx="775" cy="335">
181
+ <animate attributeName="cx" to="0" dur="1ms" fill="freeze"/>
182
+ <animate attributeName="cy" to="0" dur="1ms" fill="freeze"/>
183
+ <animateMotion dur="2.4s" begin="-2s" repeatCount="indefinite"><mpath href="#flow-distill" xlink:href="#flow-distill"/></animateMotion>
184
+ </circle>
185
+
186
+ <!-- ── 底注 ── -->
187
+ <text x="600" y="576" text-anchor="middle" font-size="18" fill="#8B93A7">事件缝 session/event · 注入缝 agent/pre-step + systemPrompt.context · 全程无感,用户与模型零操作</text>
188
+ </g>
189
+ </svg>
@@ -0,0 +1,115 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg"
2
+ width="1200" height="800" viewBox="0 0 1200 800"
3
+ role="img" aria-labelledby="storageTitle storageDesc">
4
+ <title id="storageTitle">存储布局与检索</title>
5
+ <desc id="storageDesc">双写架构:JSONL 按天追加只增不改(事实源),memory.db 为主检索引擎。文件形态含 conversations、records、scenes、persona、state、pending、session-modes、embedding-source、models、runtime、日志与重建归档;检索三策略 keyword/embedding/hybrid(RRF k=60 融合);嵌入源三态 off/remote/local(生效 = 部署上限 AND 运行时选择);降级链保证永不阻塞宿主,唯一检索缝为 L1Store.search()。</desc>
6
+
7
+ <rect width="1200" height="800" rx="26" fill="#0B0E14"/>
8
+
9
+ <g font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">
10
+
11
+ <!-- ── 双写架构 ── -->
12
+ <rect x="64" y="56" width="1072" height="56" rx="14" fill="#11161F" stroke="#232A38" stroke-width="1.5"/>
13
+ <text x="600" y="91" text-anchor="middle" font-size="20" fill="#F2F3F5">双写架构:JSONL 按天追加、只增不改(备份 / 恢复事实源)· memory.db 主检索引擎(去重合并只动检索库)</text>
14
+
15
+ <!-- ── 左:文件形态 ── -->
16
+ <g id="files">
17
+ <rect x="64" y="140" width="560" height="610" rx="16" fill="#0D1119" stroke="#232A38" stroke-width="1.5"/>
18
+ <text x="92" y="176" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
19
+ font-size="18" fill="#2DD4BF">文件形态 · ~/.dsh/memory/</text>
20
+
21
+ <g font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="18">
22
+ <text x="92" y="210" fill="#F2F3F5">memory.db</text>
23
+ <text x="352" y="210" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">SQLite 检索库 · FTS5+向量</text>
24
+
25
+ <text x="92" y="252" fill="#F2F3F5">conversations/*.jsonl</text>
26
+ <text x="352" y="252" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">L0 事实源 · 只增不改</text>
27
+
28
+ <text x="92" y="294" fill="#F2F3F5">records/*.jsonl</text>
29
+ <text x="352" y="294" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">L1 事实源 · 含 family</text>
30
+
31
+ <text x="92" y="336" fill="#F2F3F5">scenes/&lt;family&gt;/*.md</text>
32
+ <text x="352" y="336" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">L2 场景块 · 按族</text>
33
+
34
+ <text x="92" y="378" fill="#F2F3F5">persona-&lt;family&gt;.md</text>
35
+ <text x="352" y="378" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">L3 画像 · 每族一份</text>
36
+
37
+ <text x="92" y="420" fill="#F2F3F5">state.json</text>
38
+ <text x="352" y="420" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">checkpoint · v2 分族</text>
39
+
40
+ <text x="92" y="462" fill="#F2F3F5">pending.json</text>
41
+ <text x="352" y="462" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">未蒸馏缓冲 · 重启恢复</text>
42
+
43
+ <text x="92" y="504" fill="#F2F3F5">session-modes.json</text>
44
+ <text x="352" y="504" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">会话档位 · 90 天清理</text>
45
+
46
+ <text x="92" y="546" fill="#F2F3F5">embedding-source.json</text>
47
+ <text x="352" y="546" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">嵌入源三态 · 运行时切换</text>
48
+
49
+ <text x="92" y="588" fill="#F2F3F5">models/&lt;id&gt;/</text>
50
+ <text x="352" y="588" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">本地嵌入模型 · sha256 校验</text>
51
+
52
+ <text x="92" y="630" fill="#F2F3F5">runtime/</text>
53
+ <text x="352" y="630" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">推理运行时 · 按需安装</text>
54
+
55
+ <text x="92" y="672" fill="#F2F3F5">*.bak.&lt;ts&gt;/</text>
56
+ <text x="352" y="672" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">重建归档(改名保留)</text>
57
+
58
+ <text x="92" y="714" fill="#F2F3F5">memory.log</text>
59
+ <text x="352" y="714" fill="#8B93A7" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif">诊断日志 · 2MB 轮转</text>
60
+ </g>
61
+ </g>
62
+
63
+ <!-- ── 右上:检索三策略 ── -->
64
+ <g id="retrieval">
65
+ <rect x="656" y="140" width="480" height="210" rx="16" fill="#0D1119" stroke="#232A38" stroke-width="1.5"/>
66
+ <text x="684" y="174" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
67
+ font-size="18" fill="#F5A623">检索三策略 · recall.strategy</text>
68
+
69
+ <text x="684" y="210" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="18" fill="#F2F3F5">keyword</text>
70
+ <text x="800" y="210" font-size="18" fill="#8B93A7">FTS5 BM25</text>
71
+
72
+ <text x="684" y="244" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="18" fill="#F2F3F5">embedding</text>
73
+ <text x="800" y="244" font-size="18" fill="#8B93A7">vec0 余弦 KNN</text>
74
+
75
+ <text x="684" y="278" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="18" fill="#F2F3F5">hybrid</text>
76
+ <rect x="798" y="262" width="48" height="24" rx="12" fill="#2DD4BF"/>
77
+ <text x="822" y="279" text-anchor="middle" font-size="15" font-weight="700" fill="#0B0E14">默认</text>
78
+ <text x="860" y="278" font-size="18" fill="#8B93A7">双路并行 + RRF k=60</text>
79
+
80
+ <text x="684" y="322" font-size="18" fill="#6B7484">conversation_search(L0)同款融合</text>
81
+ </g>
82
+
83
+ <!-- ── 右中:嵌入源三态 ── -->
84
+ <g id="embedding-source">
85
+ <rect x="656" y="370" width="480" height="184" rx="16" fill="#0D1119" stroke="#232A38" stroke-width="1.5"/>
86
+ <text x="684" y="404" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
87
+ font-size="18" fill="#93A8FF">嵌入源三态 · 运行时切换</text>
88
+
89
+ <text x="684" y="438" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="18" fill="#F2F3F5">off</text>
90
+ <text x="800" y="438" font-size="18" fill="#8B93A7">纯 FTS(默认)</text>
91
+
92
+ <text x="684" y="471" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="18" fill="#F2F3F5">remote</text>
93
+ <text x="800" y="471" font-size="18" fill="#8B93A7">OpenAI 兼容 /embeddings</text>
94
+
95
+ <text x="684" y="504" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="18" fill="#F2F3F5">local</text>
96
+ <text x="800" y="504" font-size="18" fill="#8B93A7">内置目录 · CPU 推理</text>
97
+
98
+ <text x="684" y="536" font-size="16" fill="#6B7484">生效 = 部署上限 AND 运行时选择 · 本地模型免 API Key</text>
99
+ </g>
100
+
101
+ <!-- ── 右下:降级链 ── -->
102
+ <g id="degradation">
103
+ <rect x="656" y="574" width="480" height="176" rx="16" fill="#0D1119" stroke="#232A38" stroke-width="1.5"/>
104
+ <text x="684" y="608" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
105
+ font-size="18" fill="#8B93A7">降级链 · 永不阻塞宿主</text>
106
+
107
+ <text x="684" y="642" font-size="18" fill="#C9CFDB">sqlite-vec 加载失败 → 纯 FTS</text>
108
+ <text x="684" y="675" font-size="18" fill="#C9CFDB">embedding 调用失败 → 该次降级 FTS</text>
109
+ <text x="684" y="708" font-size="18" fill="#C9CFDB">初始化失败 → 记忆停用 · dsh 照常启动</text>
110
+
111
+ <text x="684" y="740" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
112
+ font-size="18" fill="#2DD4BF">唯一检索缝:L1Store.search()</text>
113
+ </g>
114
+ </g>
115
+ </svg>