dsh-mnemos-continuity 0.0.0-stage → 1.5.10

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 (43) hide show
  1. package/INSTALL.md +445 -0
  2. package/LICENSE +22 -0
  3. package/README.md +153 -3
  4. package/VERSION.md +82 -0
  5. package/cordis.patch.yml +8 -0
  6. package/docs/architecture-/346/234/272/345/210/266/346/270/205/345/215/225.docx +0 -0
  7. package/docs//346/236/266/346/236/204/346/200/273/350/247/210.docx +0 -0
  8. package/docs//346/250/241/345/235/227/344/270/216/345/212/237/350/203/275/345/256/236/347/216/260.md +474 -0
  9. package/docs//347/256/200/344/273/213-introduction.docx +0 -0
  10. package/docs//350/256/276/350/256/241/350/200/205/350/247/206/350/247/222.docx +0 -0
  11. package/examples/skills/host-interface-verification.md +15 -0
  12. package/examples/skills/outside-workspace-file-ops.md +16 -0
  13. package/package.json +46 -6
  14. package/scripts/constitution-path.mjs +57 -0
  15. package/scripts/default-constitution.mjs +36 -0
  16. package/scripts/init-constitution.mjs +89 -0
  17. package/scripts/update-constitution.mjs +92 -0
  18. package/src/boot-log.js +154 -0
  19. package/src/compaction-snapshot.js +604 -0
  20. package/src/constitution.js +111 -0
  21. package/src/heartbeat.js +28 -0
  22. package/src/host-message.js +65 -0
  23. package/src/index.js +1885 -0
  24. package/src/learner-loop.js +792 -0
  25. package/src/learning-protocol.js +65 -0
  26. package/src/paths.js +123 -0
  27. package/src/plain-text.js +21 -0
  28. package/src/secret-patterns.js +105 -0
  29. package/src/self-text.js +81 -0
  30. package/src/skill-miss.js +249 -0
  31. package/src/skill-propose-text.js +63 -0
  32. package/src/skill-provider.js +151 -0
  33. package/src/skill-review.js +1222 -0
  34. package/src/skill-source-ref.js +123 -0
  35. package/src/skill-usage.js +123 -0
  36. package/src/store-lock.js +375 -0
  37. package/src/store.js +1351 -0
  38. package/src/stuck-detector.js +245 -0
  39. package/src/system-prompt.js +64 -0
  40. package/src/tool-guidance.js +152 -0
  41. package/src/tool-output.js +339 -0
  42. package/src/tool-results.js +242 -0
  43. package/src/user-signals.js +271 -0
package/INSTALL.md ADDED
@@ -0,0 +1,445 @@
1
+ # 安装与配置 Mnemos
2
+
3
+ > 这份文件只写**你要做的事**:装、配、验证、排错、数据放哪。
4
+ > 它是什么、值不值得用 → `docs/简介`;有什么机制 → `docs/architecture-机制清单`;为什么这样设计 → `docs/设计者视角`。
5
+
6
+ ## 三十秒摘要(省你十分钟)
7
+
8
+ Mnemos 是**装在你机器上的一套「让判断跨会话、跨模型继续可用」的东西** —— 记忆、技能、规则都是普通文件。
9
+ 重点不是存了多少,而是**换模型/换会话之后还能被高效用上**。安装有个特点:**代码目录与数据目录是分开的**。
10
+
11
+ **先确认前提**:本插件跑在 **DeepSeek Harness(DSH)** 里。终端敲 `dsh --version` 出版本号 = 你有了;
12
+ 没有的话,先去获取 DSH(本文件只讲插件)。
13
+
14
+ 由此三条,后面的每一步都在为它们服务:
15
+
16
+ 1. **这个包不含任何运行数据,也不含宪法** —— 覆盖安装不会碰到你的记忆;
17
+ 2. **只有宪法初始化必须你本人做**(要设密码);注册插件就是一条命令(见第 2 节),AI 可以代劳,**宪法不该代劳**;
18
+ 3. **装完要确认的不是"它跑起来了",而是"它找对了数据在哪"** —— 看一眼日志就知道。
19
+
20
+ > **保守起步(推荐第一次就这么做)**:装完先关掉后台维护 —— `heartbeatEnabled: false`(见第 10 节),
21
+ > 只留"写记忆 / 召回 / 任务续接",确认对你真有用再一项项开回来。
22
+ > 空闲学习(learner)本来就是默认关的。这样第一晚不会有任何自动的 AI 调用,也就不会有惊喜账单。
23
+ >
24
+ > **关掉之后还剩什么**(这张表就是"保守起步"的全部代价,先看清再决定):
25
+ >
26
+ > | 仍然可用 | 暂时失效(都在心跳里) |
27
+ > |---|---|
28
+ > | 写记忆 / 检索 / 取详情 · 标记作废 · 暂时无关 · 真删除 · 隔离验证 · 任务图三件套 | 闲置降权 · 按龄归档 · 超量归档 · 验证记录超窗销毁 · 孤儿任务图回收 · "该用未用"判定 · 技能评审 |
29
+ >
30
+ > 也就是说:**记忆会一直往里长,但不会自动整理**。想整理时手动说一句"把这次会话归档"(`mnemos_consolidate`)即可;
31
+ > 其余功能随时可以把 `heartbeatEnabled` 改回 `true` 再开。
32
+
33
+ ---
34
+
35
+ ## 0. 前置
36
+
37
+ - **DSH 已安装**并能正常启动(终端 `dsh --version`);
38
+ - 安装不需要 Node.js:`dsh` 自带运行时。
39
+ - 如果走"本地目录安装"(方式 B),那个目录要放在**稳定位置**、之后别随便搬 —— 它在 profile 里是链接引用。
40
+
41
+ ## 1. 确认装到哪个 profile
42
+
43
+ ```bash
44
+ dsh --help # 看用法
45
+ ls ~/.dsh/profiles # 看有哪些 profile(桌面版一般是 desktop)
46
+ ```
47
+
48
+ 记住目标 profile(下文用 `<profile>` 代指)。
49
+
50
+ ## 2. 安装
51
+
52
+ 本包是标准 **bundle**:`package.json` 里带了 `dsh.bundle.patch` 声明,
53
+ 所以**装上去它自己会登记到组合树里**,你不用手工改 profile 补丁。
54
+
55
+ ### 方式 A(推荐):从包名 / GitHub 装
56
+
57
+ ```bash
58
+ dsh plugin --profile <profile> add dsh-mnemos-continuity # 从 npm(发布后可用)
59
+ dsh plugin --profile <profile> add github:<user>/<repo> # 从 GitHub 直装
60
+ ```
61
+
62
+ ### 方式 B:从本地目录装(还没发布时用这个)
63
+
64
+ ```bash
65
+ # 路径可以带引号;Windows 用正斜杠更稳
66
+ dsh plugin --profile <profile> add "link:<解压后**含 package.json 的那一层**的绝对路径>"
67
+ ```
68
+
69
+ > RAR 解压出来通常多一层(`mnemos/`)—— **必须指到里面有 `package.json` 的那一层**,指到父目录会装错。
70
+ >
71
+ > `dsh plugin` 后面接的是 **pnpm 参数**(`add` / `remove` / `why` …),它会在 profile 目录里执行。
72
+ > 装完可以确认它真的进了组合树:
73
+
74
+ ```bash
75
+ dsh --profile <profile> --dump-config | grep dsh-mnemos-continuity
76
+ # 期望看到: - id: dsh-mnemos / name: dsh-mnemos-continuity
77
+ ```
78
+
79
+ > **所有安装方式都可能看到一条 peer 依赖告警**(`Issues with peer dependencies found`)——
80
+ > 因为 DSH 的 profile 模板设了 `autoInstallPeers: false`,而 `@deepseek-ai/schemastery` 由宿主提供。
81
+ > **这条告警无害**:插件能正常加载(实测),不用处理。
82
+
83
+ <details>
84
+ <summary>如果 <code>dsh plugin</code> 不可用(手工兜底,不推荐)</summary>
85
+
86
+ 1. 编辑 `~/.dsh/profiles/<profile>/cordis.patch.yml`:
87
+
88
+ ```yaml
89
+ - id: dsh-mnemos
90
+ config: {} # 配置项见第 10 节,都可省略
91
+ ```
92
+
93
+ 2. 确保该 profile 的 `package.json` 的 `dependencies` 里有本包(`file:` / `link:` 指向解压目录,或版本号)。
94
+ 3. 完全重启。
95
+ </details>
96
+
97
+ ## 3. 更新到新版本(已经装过,要升级)
98
+
99
+ 好消息:**数据不在这个包里** —— 更新只换代码,不碰你的记忆。
100
+
101
+ ```bash
102
+ # 方式 A(包名/GitHub 装的)
103
+ dsh plugin --profile <profile> add dsh-mnemos-continuity@latest
104
+ dsh plugin --profile <profile> add github:<user>/<repo> # 从 GitHub 装的就重装一次
105
+
106
+ # 方式 B(本地目录装的):解压新包覆盖同一目录即可(链接路径不变),或解压到新目录后重新 add
107
+ ```
108
+
109
+ 然后:
110
+
111
+ 1. **先备份**(稳妥做法):完全退出 DSH,复制三样(`memory.json`、`constitution.json`、`skills/`,位置见第 11 节);
112
+ 2. **完全重启**(同第 4 节);
113
+ 3. 按第 6 节验证,重点看两处:
114
+ - `package.json` 里的 `version` 是不是你要的那一版;
115
+ - `mnemos.log` 里的 `dataFile=` 还是原来那份 —— 若变了,说明路径解析变了(**数据没丢**,把配置指回去即可)。
116
+
117
+ > ⚠ 不要把数据目录放进代码目录 —— 那样覆盖安装时容易被一起替换掉。
118
+
119
+ **回滚**:`dsh plugin --profile <profile> add dsh-mnemos-continuity@<旧版本号>`;本地安装则把旧包换回来 + 重启。
120
+ 发行方也保留了历次版本存档(`mnemos-历史版本\v<版本>\`)。
121
+
122
+ **卸载**:
123
+
124
+ ```bash
125
+ dsh plugin --profile <profile> remove dsh-mnemos-continuity
126
+ ```
127
+
128
+ > 卸载**不会删你的数据**(记忆、宪法、技能都在 profile 的数据目录里,见第 11 节)—— 要清干净得自己删那个目录。
129
+
130
+ > 本版**没有数据格式变更**;将来若有,会在 `VERSION.md` 的版本流水里写明。
131
+
132
+ ## 4. 完全重启(必须)
133
+
134
+ **完全退出 DSH 再启动** —— 不是刷新页面,也不是"重新加载窗口"。
135
+
136
+ ## 5. ★ 初始化宪法(只有你本人能做)
137
+
138
+ **在包根目录下运行**(`scripts/` 就在那儿):
139
+
140
+ ```bash
141
+ # 有 Node(装了 Node.js ≥22):
142
+ node "<插件目录>/scripts/init-constitution.mjs" --file="<启动日志里 constitutionFile= 打印的那个路径>"
143
+
144
+ # 没装 Node:用 DSH 自带的运行时跑同一个脚本(Windows)
145
+ $env:ELECTRON_RUN_AS_NODE = 1
146
+ & "<DSH 安装目录>\DeepSeek Harness.exe" --expose-internals `
147
+ "<插件目录>\scripts\init-constitution.mjs" --file="<启动日志里 constitutionFile= 打印的那个路径>"
148
+ ```
149
+
150
+ - 那个路径从 `mnemos.log` 里抄(见第 6 节)——**别自己猜**,猜错了等于没初始化;
151
+ - 它需要你**亲手设一个密码**,密码不落盘 —— 这是"宪法不被偷偷改"的保证,所以 AI 不能也不该替你做;
152
+ - 只想看默认内容、不写盘:加 `--print`。
153
+
154
+ ⚠ **初始化成功后必须再完全重启一次 DSH**:宪法只在插件启动时装载,不会热加载。
155
+ 不重启的话,会话里仍会看到"宪法 · 未初始化"的警告 —— 那不是失败,是还没生效。
156
+
157
+ **自动化场景(CI / 容器)**:把初始化好的 `constitution.json` 放到目标位置即可(插件只读它)。
158
+
159
+ ## 6. 验证装好了
160
+
161
+ 1. **看日志**:`…/mnemos/mnemos.log` 每次启动追加三行,第三行是解析依据:
162
+
163
+ ```
164
+ mnemos: dataFile=C:\...\profiles\<profile>\mnemos\memory.json
165
+ mnemos: constitutionFile=C:\...\profiles\<profile>\mnemos\constitution.json
166
+ mnemos: 解析依据 profileContext=<profile 目录> / DSH_PROFILE_DIR=(未设) / DSH_HOME=(未设) / cwd=...
167
+
168
+ > **看第一段 `profileContext=` 才是准的**(插件的默认数据目录以它为准)。
169
+ > `DSH_PROFILE_DIR` / `DSH_HOME` 在插件进程里通常是"(未设)"——它们只被注入给 shell 工具,不是插件环境变量。
170
+ ```
171
+
172
+ 路径不对就改第 10 节的 `dataFile` / `constitutionFile`。**宪法没初始化时会给出可见警告**,不会静默变空。
173
+
174
+ 2. **写一条、再查一条**:让它写一条记忆,然后**新开一个对话**检索 —— 能召回就说明链路是通的。
175
+
176
+ 3. **看工具挂上没有**:让它列出 `mnemos_*` 工具(清单见第 7 节)。
177
+
178
+ ## 6b. 续接任务:换个会话接着干(**这招用户最常不知道**)
179
+
180
+ 记忆**不跟会话走、也不跟工作区走**:同一份数据在 profile 目录里。所以——**关掉当前对话、过几天在另一个目录开个新会话,
181
+ 让它先检索,就能接着上次的活干**;不需要"同一个对话窗口"才能保持连续。
182
+
183
+ ### 默认做法:直接说一句"继续之前的 X"
184
+
185
+ 平时写下的结论都在记忆里,新会话里说一句"继续之前的 X",它会把相关结论找回来接着做。
186
+ **不需要记任何编号。**
187
+
188
+ ### 要精确时:让它在原对话里给你一份"续接方案"
189
+
190
+ 如果任务多步、中间状态多、怕接错 —— 回到**原来的对话**,直接说:
191
+
192
+ ```
193
+ 给我一个续接方案:把当前任务的状态整理成一条记忆,带任务号,并告诉我下次怎么用它接上。
194
+ ```
195
+
196
+ 它会把状态记下来(做到哪、下一步、踩过的坑)并给你一个任务号。之后在**任何**新会话里按它给的做即可,例如:
197
+
198
+ ```
199
+ 用 mnemos_recall 带 taskId=<它给的任务号> 取回那份续接状态
200
+ ```
201
+
202
+ 为什么这时候才需要任务号:**检索是关键词 + 标签匹配**,不是语义检索 —— 换个说法可能就召不回;
203
+ 任务号是**最可靠的锚**。所以它不是必须记的编号,而是"要精确时才需要的那把钥匙"。
204
+
205
+ > 边界:**没写下来的就等于没发生**;任务号只保证"取得回",不保证"是最新的" —— 状态变了就再要一份;
206
+ > 不同 profile 之间默认不共享(除非把数据路径指到同一份)。
207
+
208
+ ## 7. 它装好之后提供了什么(工具)
209
+
210
+ | 工具 | 作用 |
211
+ |---|---|
212
+ | `mnemos_remember` | 写记忆(自动盖会话标记;可一次完成"写纠正 + 作废旧条") |
213
+ | `mnemos_recall` / `mnemos_open` | 检索摘要 / 取某条详情 |
214
+ | `mnemos_consolidate` | 把本会话的短时记忆归档为长期 |
215
+ | `mnemos_validate` | 在隔离会话里验证外部信息 |
216
+ | `mnemos_constitution` | 读宪法(只读) |
217
+ | `mnemos_delete` | **真删除**(不可恢复) |
218
+ | `mnemos_deprecate` / `mnemos_dormant` | 标记作废 / 标"本轮暂时无关"(可撤销) |
219
+ | `mnemos_propose_skill` | 提议新建技能(要给反例与正例,且反例能追溯到真实失败) |
220
+ | `mnemos_task_open` / `mnemos_task_update` / `mnemos_task_close` | 任务图:开图 / 填回执 / 收尾 —— 派活用,**自己的复杂活也能用**(判据:跨会话 / 被截断 / 有并行 / 需事后交代,任一为是) |
221
+ | `mnemos_heartbeat` / `mnemos_maintenance_list` / `mnemos_heartbeat_toggle` | 手动跑一次维护 / 看维护清单 / 关心跳 |
222
+ | `mnemos_learner_kick` | 立刻踢一轮空闲学习(诊断用,也可主动触发) |
223
+
224
+ ## 8. 后台维护在做什么(心跳)
225
+
226
+ `decay`(衰减降权)· `archive_due`(按龄归档)· `archive_when_full`(超量归档)·
227
+ `prune_validation`(隔离验证记录超窗销毁,留台账)· `reclaim_tasks`(孤儿任务图超期强制归档)·
228
+ `missed_usage`(该用未用判定,**会调 AI**)· `review_skills`(技能评审,**会调 AI**)
229
+
230
+ **一个定时器跑整张注册表**:`heartbeatIntervalMs` 管的是全部维护任务。
231
+ 运行时开关默认在每轮对话开始时被置回开启;要**持久关闭**,在配置里写 `heartbeatEnabled: false`。
232
+
233
+ ## 9. 空闲学习(可选,默认关)
234
+
235
+ > **这一节可以整段跳过**:它默认是关的,跳过不影响上面任何一步。只有你打算开它时,才需要读下去 ——
236
+ > 下面这些是把它开起来才会遇到的坑(preset、provider 路由、工作目录),不是使用这个插件的前提知识。
237
+
238
+ 到点了,它把"一脚"送进一个**专用会话**,让模型自己安排这一轮:读你留的任务,没任务就自由学点,也可以什么都不做。
239
+ **不占用、不污染你正在用的对话。**
240
+
241
+ ### 两个前提,缺一不可
242
+
243
+ | 前提 | 配置 |
244
+ |---|---|
245
+ | ① 打开开关 | `learnerEnabled: true`(默认 false) |
246
+ | ② 配好外部 API | `learnerProvider` + `learnerModel`(**必须**,缺一即不工作;为什么不能用 DeepSeek 自家路由见下) |
247
+
248
+ ```yaml
249
+ - id: dsh-mnemos
250
+ config:
251
+ learnerEnabled: true
252
+ learnerIntervalMs: 3600000 # 1 小时
253
+ learnerProvider: <provider-id> # 必须:带 key 的第三方路由(见下)
254
+ learnerModel: <model-id>
255
+ learnerAgentPreset: standard # 不设它就没有联网/读文件工具(也可自建精简 preset,见下)
256
+ ```
257
+
258
+ > **默认用什么模型**:没有默认 —— **必须自己填** `learnerProvider` + `learnerModel`(带 key 的第三方路由),留空即不工作。
259
+ > 想让它跑在别的模型上,就显式填 `learnerProvider` + `learnerModel`(必须是带 key 的 provider)。
260
+ > 注意:如果你把模型配错(比如配了一个拿不到凭据的 provider),回执与 `learner.log` 会记下失败原因,不会静默。
261
+
262
+ ### 我们实际用的接法(可以直接照抄)
263
+
264
+ 关键点是:**联网与学习是两套独立的接线,各走各的路由。**
265
+
266
+ | 用途 | 走哪条路由 | 为什么 |
267
+ |---|---|---|
268
+ | **联网**(`web_search` / `web_fetch`) | **DeepSeek 官方**(`web-search-deepseek`,凭据用 `DEEPSEEK_API_KEY`,key 存凭据服务、不写进配置) | 官方端点能真正拿到搜索结果;换第三方 Anthropic 端点会因缺计费头而**拿不到结果**(实测) |
269
+ | **空闲学习的模型** | **必须第三方 api-key 路由**(如阿里云 token-plan 的 `qwen3.8-flash`) | 空闲学习是**插件自己建**的 agent:后台几乎不存在活父会话,也就借不到宿主的派活通道;而自建 agent 走 DeepSeek 自家路由会稳定 `TRANSPORT`,第三方 api-key 一次就通。另外宿主派活的子会话会挂在父会话下面、人不好看见 —— 后台任务应当独立可观测 |
270
+
271
+ 所以一句话:**官方 key 只用在"搜索"上,不用在 learner 的 LLM 上** —— 两者互不影响,也不用为了联网去动学习模型。
272
+
273
+ ```yaml
274
+ - id: dsh-mnemos
275
+ config:
276
+ learnerEnabled: true
277
+ learnerIntervalMs: 21600000 # 6 小时:一轮就约 7 万 token,频率低一点更划算
278
+ learnerProvider: aliyun # ★ 第三方 api-key 路由(必须)
279
+ learnerModel: qwen3.8-flash
280
+ # 留空 = 不工作:后台没有主会话可借,也不会退回 DeepSeek 自家路由
281
+ learnerAgentPreset: standard # 出厂 preset(带联网/读文件);要收窄再自建,见下
282
+ ```
283
+
284
+ > **为什么必须是第三方路由**:空闲学习是**插件自己建**的 agent —— 后台运行时几乎不存在"活着的父会话",
285
+ > 所以借不到宿主的派活通道;而自建 agent 走 DeepSeek 自家路由会稳定 `TRANSPORT`(实测 5 次重试全败),
286
+ > 走第三方 api-key 路由一次就通。另一条理由:宿主派活的子会话挂在**父会话的智能体**下面,人不好看见。
287
+
288
+ ### 工具集由 preset 决定
289
+
290
+ **不设 `learnerAgentPreset` 时,默认就是 `standard`** —— 它带联网与读文件工具,能正常学习。
291
+ 只有当你**想收窄**工具集(比如不想要 shell / 子代理 / 待办这些),才需要自建一个精简 preset。
292
+
293
+ 照抄这一行就够用:
294
+
295
+ ```yaml
296
+ learnerAgentPreset: standard
297
+ ```
298
+
299
+ 想更克制(只留 **联网 + 读文件 + Mnemos 自己的工具**),自己声明一个再引用它 ——
300
+ 把它和 `dsh-mnemos-continuity` 写进**同一份** `cordis.patch.yml`:
301
+
302
+ ```yaml
303
+ - insert:
304
+ - id: preset-mnemos-learner
305
+ name: "@deepseek-ai/dsh-agent-preset"
306
+ config:
307
+ id: mnemos-learner
308
+ plugins:
309
+ - id: persona # ★ 必须:没它连 {{model}} 都没有值,整轮直接报错
310
+ name: "@deepseek-ai/dsh-persona"
311
+ config:
312
+ prefix: 'You are a coding agent powered by the {{model}} model.'
313
+ # ★ 不要写 {{cwd}}:宿主的提示变量只有 provider / model / self_narrative,
314
+ # {{cwd}} 会让子会话**第一轮就整轮失败**(unknown prompt variable)。
315
+ suffix: 'Work inside the configured learner workspace; do not wander outside it.'
316
+ - id: tool-fs # 读文件(同包也带 write/edit,拆不开)
317
+ name: "@deepseek-ai/dsh-tool-fs"
318
+ - id: tool-fs-search # glob / grep
319
+ name: "@deepseek-ai/dsh-tool-fs-search"
320
+ - id: tool-web # web_search / web_fetch
321
+ name: "@deepseek-ai/dsh-tool-web"
322
+ config:
323
+ fetch: true
324
+ ```
325
+
326
+ 然后 `learnerAgentPreset: mnemos-learner`。**两个坑**:
327
+
328
+ 1. preset 里 `persona` 必须带上 —— 没它 `{{model}}` 就没有值、整轮报错。
329
+ **但 persona 里别写 `{{cwd}}`**:宿主只注册了 `provider` / `model` / `self_narrative` 三个提示变量,
330
+ 写 `{{cwd}}` 会让子会话第一轮就失败(这条是实测踩出来的);
331
+ 2. **换 preset 后要先删掉旧的 learner 会话** —— 宿主只在"会话第一轮之前"选 preset,已跑过的会话不会补挂。
332
+
333
+ ### 想立刻看它跑一轮
334
+
335
+ 用 `mnemos_learner_kick`(`force: true` 可忽略间隔)。它会把**每一步的真实结果**回报:到点判定 / 新建还是恢复会话 / 是否选中 preset / 入队是否成功 / 入队后状态。
336
+
337
+ ### 任务文件(你写,它读)
338
+
339
+ 首次开启会自动生成(也可用 `learnerTasksFile` 指定):`<memory.json 同目录>\learner-tasks.md`。
340
+
341
+ - 写**开放学习类**的事("把 X 弄明白"),不用写成工单;
342
+ - **每次到点,文件内容原样送给模型**;文件开头的说明是 HTML 注释,不会当成任务送出去;
343
+ - **这个文件归你管**:想让某件事别再做了,你自己把那段删掉。
344
+ ⚠ 说准一点:它手上确实有写工具,改不动是因为**这个文件在它的工作区之外、越界写会被拒** ——
345
+ 是沙箱挡住的,不是"机制保证它改不了"。
346
+
347
+ ### 两条实测边界(值得先知道)
348
+
349
+ - **自指工具已加闸门**:弱模型会把 `mnemos_learner_kick` 当成"今天的任务",连踢三轮零产出。现在这个工具在**执行处**拒绝 learner 会话自己调用它。
350
+ - **它发来的提权请求可以直接拒绝**:看到 `mnemos-learner` 请求提权,拒绝即可。
351
+
352
+ ### 它靠什么、不靠什么
353
+
354
+ - **结论落记忆,不落会话** —— 专用会话被删也能重建,成果不丢;
355
+ - 同一时刻只用一个会话,残留会被清掉后重建,不会越堆越多;
356
+ - 它**不打断**正在忙的 agent(忙就跳过这一轮);
357
+ - **每一轮都用一个(可能是全新的)会话**:不 resume 旧会话 —— resume 出来的会话补不上工具集
358
+ (实测踩过:`read`/`glob` 全变 `unknown tool`)。回执与日志里可能看到"会话重建"。
359
+ 换会话不影响结论 —— 能留下来的只有写进记忆的东西。
360
+
361
+ ## 10. 配置项(完整清单)
362
+
363
+ 写在 `~/.dsh/profiles/<name>/cordis.patch.yml`:
364
+
365
+ ```yaml
366
+ - id: dsh-mnemos
367
+ config:
368
+ # —— 存储 ——
369
+ dataFile: "" # 记忆文件路径;留空 = 自动解析(见第 11 节)
370
+ constitutionFile: "" # 宪法路径;默认与 dataFile 同目录
371
+ autobiographyBudget: 2000 # 自传体注入的字符预算
372
+ # —— 心跳与归档 ——
373
+ heartbeatIntervalMs: 1800000 # 心跳周期(毫秒),默认 30 分钟;0 = 禁用
374
+ heartbeatEnabled: true # 心跳初值;false = 持久关闭
375
+ archiveMinAgeMs: 86400000 # 归档时间阈值(默认 24 小时)
376
+ archiveMaxShort: 50 # 短时记忆数量阈值
377
+ # —— 空闲学习(默认关) ——
378
+ learnerEnabled: false # ★ 默认关;开它必须同时配 provider + model
379
+ learnerIntervalMs: 3600000 # 间隔(毫秒);0 = 关掉
380
+ learnerSessionId: "mnemos-learner" # 专用会话 id(代码自建)
381
+ learnerAgentPreset: "standard" # ★ 决定有没有联网/读文件工具
382
+ learnerTasksFile: "" # 任务文件;留空 = memory.json 同目录
383
+ learnerWorkspace: "" # 会话工作目录;留空 = DSH 默认工作区
384
+ learnerProvider: "" # 留空 = 不工作(必须配第三方 api-key 路由)
385
+ learnerModel: "" # 留空 = 不工作
386
+ learnerMaxTokens: 0 # 0 = 继承全局 agent 配置
387
+ # —— 隔离验证(mnemos_validate)——
388
+ # 子会话必须有自己的 provider/model;留空 = 复用 learnerProvider/learnerModel(推荐),再不行才用父会话的。
389
+ # ★ 不要指望它跟父会话走 DeepSeek 自家路由:实测那条路对"插件自建 agent"一律 TRANSPORT 失败。
390
+ validateProvider: "" # 留空 = 复用 learnerProvider
391
+ validateModel: "" # 留空 = 复用 learnerModel
392
+ # —— 技能 ——
393
+ createWriteBack: true # 新建技能是否直接入目录
394
+ reviewWriteBack: true # 修改已有技能是否真的改写(false = 只出建议)
395
+ maxSkills: 30 # 技能目录容量上限
396
+ reviewEnabled: true # 是否启用技能评审
397
+ reviewProvider: "deepseek-account" # 必须与当前可用 provider 一致
398
+ reviewModel: "deepseek-flash"
399
+ reviewMaxPerCycle: 3 # 每周期最多评审几个
400
+ reviewFreezeAfterCycles: 3 # 连续几个静默周期后冻结
401
+ ```
402
+
403
+ **一个耦合点**:`reviewProvider` / `reviewModel` 必须与当前可用的 provider 一致,否则技能评审会**静默失败**(技能不会变差,但也不会变好)。
404
+
405
+ ## 11. 数据在哪 · 备份 · 换位置
406
+
407
+ **默认解析顺序**(`dataFile` 留空时):
408
+
409
+ 1. 配置里显式写的 `dataFile` / `constitutionFile`
410
+ 2. 环境变量 `MNEMOS_CONSTITUTION_FILE`(宪法专用)
411
+ 3. **宿主给的 profile 目录**下的 `mnemos/`(默认就是这里;插件用宿主 `profileContext` 取,不靠环境变量)
412
+ 再往下的兜底才是 `$DSH_PROFILE_DIR/mnemos` → `$DSH_HOME/mnemos` → `当前目录/mnemos`(只对脚本/无宿主场景有意义)
413
+ 4. `$DSH_HOME/mnemos/`
414
+ 5. 当前工作目录下的 `mnemos/`
415
+
416
+ 不确定就看 `mnemos.log` —— 每次启动都打印实际解析到的两个路径。
417
+
418
+ **要备份三样**:`memory.json`(记忆)· `constitution.json`(宪法)· `skills/`(技能)。
419
+ 都是普通文件,复制目录即可;建议**完全退出 DSH 后**备份,避免拷到写了一半的文件。
420
+
421
+ **换位置**:把 `dataFile` 与 `constitutionFile` 显式写上,指向新路径,然后完全重启。
422
+ **不要把同一份数据挂给两个正在运行的实例**(同机多进程有写保护,跨机器/网络盘未验证)。
423
+
424
+ **多 profile**:每个 profile 默认各一份数据(数据目录 = 该 profile 目录下的 `mnemos/`)。想让两个 profile 共用,就把两者的 `dataFile` 指到同一路径 —— 但那等于共用记忆与技能。
425
+
426
+ ## 12. 出问题时
427
+
428
+ | 现象 | 原因 / 处理 |
429
+ |---|---|
430
+ | 重启后工具没出现 | 没**完全重启**;或 profile 装错了(回第 1 节) |
431
+ | 装了但行为像旧版 | 还是缓存:完全退出再启动,别用"重新加载窗口" |
432
+ | 出现"宪法 · 未初始化"警告 | 三种原因:① 第 5 节没做;② `constitutionFile` 指错路径;③ **第 5 节做了但没再完全重启一次**(宪法只在启动时装载) |
433
+ | 记忆"空了" | 看日志里的 `dataFile=` —— 大概率是路径指到别处,数据本身没丢 |
434
+ | 检索明显不准 | 召回是**关键词 + 标签**匹配(不是语义检索):换关键词试,并检查标签是否覆盖关键类别 |
435
+ | 技能一直不变好 | `reviewProvider` 不可用 → 评审静默失败;或技能已冻结(见 `skill-review-state.json`) |
436
+ | 子代理说"文件不存在"但明明有 | `glob` 用**绝对 Windows 路径**会静默返回 `No files found`。改用 `pwsh Get-ChildItem -File -Filter *.js` 或相对工作区根的路径。**静默假阴性比报错更危险** |
437
+ | 任务的临时结果在收尾时没了 | 那是设计:临时的默认丢弃,要留请显式标记。交付物别同时标成临时 |
438
+
439
+ ## 13. 这个包**不含**什么(刻意如此)
440
+
441
+ 不含任何运行数据(记忆、技能)、不含宪法、不含你的密钥。
442
+ **所以覆盖安装不会碰到你的记忆**:数据在 profile 目录下,与代码目录分开。
443
+
444
+ > **使用限制与责任**:这套能力在善意使用下是效率工具,恶意使用会放大后果 —— 四类风险与责任划分
445
+ > 见 README 的「**风险与责任**」一节(很短,建议开空闲学习或联网前读一遍)。
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 七月流火 <2151926500@qq.com>
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.
22
+
package/README.md CHANGED
@@ -1,3 +1,153 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
1
+ # Mnemos
2
+
3
+ **装进 DeepSeek Harness 的一个插件:不是给 AI 一个更大的记忆库,而是让记忆在换模型、换会话之后还能被高效用上。**
4
+
5
+ > 存多少不是重点。重点是:**换个模型接着干时,它知道该取哪几条、按什么用、用完怎么留下新的判断** ——
6
+ > 记忆存在你能查的文件里,推理模型只是可以换掉的部件。
7
+
8
+ > 一句话:**它想让"判断"能被人查、被人质疑、也能被推翻 —— 而不是看完就忘、错了也没处追。**
9
+
10
+ > **DeepSeek Harness(下称 DSH)是什么**:一个在**你自己电脑上**跑 AI 助手的环境 —— 负责会话、工具和插件,
11
+ > 有**桌面客户端**也有**命令行**两种用法。Mnemos 是装进它的一个插件,**不是**独立软件,也**不能**用在网页版或手机 App 上。
12
+ >
13
+ > **先确认自己有没有 DSH**(30 秒):打开终端敲 `dsh --version` —— 出版本号就说明你已经有了;
14
+ > 没有的话,去 DeepSeek 官方渠道获取(本页只讲这个插件,不讲怎么装 DSH)。
15
+ > 已经装过 DSH 的,可以直接看 [`INSTALL.md`](INSTALL.md)。
16
+
17
+ > **名字说明**:项目叫 **Mnemos**,npm 包名是 **`dsh-mnemos-continuity`**。
18
+ > DSH 生态里另有一个也叫 `dsh-mnemos` 的项目(别人写的,思路不同、不是同一套东西)——
19
+ > 我们这个名字里的 `continuity` 指的就是本项目的重点:**换会话、换模型之后,判断还能接着用**。
20
+
21
+ ## 它到底能带给你什么
22
+
23
+ **写给已经在用 DSH 的人。** 五件事,都用人话说。**为什么能做到、有哪些机制、代价是什么 → 见《简介》**。
24
+
25
+ ### ① 换个对话继续任务,前面的结论能直接接上
26
+
27
+ 记忆不绑在某个对话窗口上。换一个会话、换一个目录都行:新开个对话说一句"继续之前的 X",
28
+ 它会把之前的重要结论找回来,接着往下做 —— **不需要记任何编号**。
29
+
30
+ **想接得更准**(任务做到一半、怕接错)时,回**原来的对话**里说一句"**给我一个续接方案**" ——
31
+ 它会把这个任务的状态整理成一份记录、并给你一个任务号;下次直接拿它精确接上。
32
+
33
+ **边界**:没写下来的等于没发生;不同 profile(DSH 的配置分组,例如 desktop / web)默认不共享。
34
+
35
+ ### ② 多 agent 协作:交接不靠"把对话贴过去",而是靠记忆精确交接
36
+
37
+ 让几个助手同时干活时,常见做法是把前面的对话、背景整段贴给它们 —— 又长,又容易把过时的东西带过去。
38
+
39
+ 这里的做法是:**任务先写进记忆,子代理按任务编号去读它需要的那部分**;做完把结论交回同一条任务记录上。
40
+ 不需要一大段对话来"交接",交的是一份**精确的任务与结果**。
41
+
42
+ 于是你能得到:
43
+
44
+ - **交接是精确的**:子代理拿到的就是任务本身,不是一段被剪切、可能已过时的对话;
45
+ - **成果不散**:几路的结果归到同一份任务记录上,事后按编号能一次取全;
46
+ - **没做完的不会被当成做完**:哪一路没交回结论,会如实标出来;忘了收尾的任务也不会一直挂着。
47
+
48
+ **不派活也能用**:你自己手上的复杂活(会跨会话、会被上下文截断、或者有并行几条线)也可以用同一张任务图来规划与收尾 ——
49
+ 做完就是一份**说得清"哪几块做完了"**的记录。判据很简单,问三个问题:**会跨会话吗?会被截断吗?有并行分支吗?**
50
+ 任一为是就值得开;**单会话几步就完的小事别开,那只是给自己加仪式**。
51
+
52
+ ### ③ 外面来的东西留下出处,而不是被当真
53
+
54
+ 外部来的内容进来时会**永久留下来源**。以后被查到时,它可以被质疑、可以被推翻 —— **但不会被当成事实**。
55
+
56
+ ### ④ 聊天太长被截断时,东西不会凭空消失
57
+
58
+ 上下文被截掉一段时,被截掉的部分会被收起来,并留一句"东西存在哪"的提示。
59
+ 它保证"原文还在、给你指路",**不保证"结论一定不丢"**。
60
+
61
+ ### ⑤ 关掉对话、换掉模型,它还是同一个它
62
+
63
+ "它是谁、做过哪些决定、为什么这么选"记在文件里,不在模型的权重里。
64
+ **代价**:能留下来的是判断与来由,不是说话的方式 —— 换了模型,风格会变。
65
+
66
+ ### 也说清它不是什么
67
+
68
+ - 不是**记忆插件 / 向量检索系统**:记忆只是入口,检索靠关键词与标签(有意不用语义检索);
69
+ - 不是**会自己长大的 agent**:技能要提议、要独立验证、可回滚;**"不修改"也是有效结论**;
70
+ - 不是**成熟产品**:部件齐备、有会真的失败的回归检查,但只有一个人、一台机器的实证。
71
+
72
+ ## 一次真实的崩溃:会话坏了,但结论没丢
73
+
74
+ 有一次,它把对话弄坏了:**那一轮所有工具调用都成功**,但整轮请求被宿主拒掉 ——
75
+ 那个会话再也接不下去,看起来像"全都坏了"。
76
+
77
+ **价值恰恰在这里显出来了**:
78
+
79
+ 1. **结论没丢**:那轮已经写进记忆的判断都还在。**直接开一个新会话,说一句"继续之前的 X",就能接着做** ——
80
+ 不需要先把坏掉的会话修好,才能继续工作;
81
+ 2. **能查清怎么坏的**:判断、来由、当时的错误都留了记录,所以能一路追到"是哪条消息、少了什么字段",
82
+ 而不是只能重启、祈祷下次别再来;
83
+ 3. **修完让它不可能再犯**:让写这类消息**只剩一个入口**,代码里再出现手写就**测试失败**;
84
+ 坏掉的那几个会话也被就地修好(先备份),再用一个探针会话确认同一条路不再出错。
85
+
86
+ > 这就是它和"一个记性好的助手"的区别:**会话是会坏的,但判断不该跟着坏。**
87
+ > 这个 bug 已在 v1.5.0 修掉,并有回归检查盯着。
88
+
89
+ 留下的判据:**静默失败比报错更危险 —— 工具全成功,整轮却死了。**
90
+
91
+ > 这也是它对待自己错误的方式:先承认是**我们的提醒把用户的会话弄坏了**,再让它**不可能再这么坏**。
92
+
93
+ ## 代价与边界(用前必读)
94
+
95
+ - 记忆是**本地明文文件**:自己备份;不要往里粘密码/密钥。要备份哪几个文件、怎么卸载/回滚 → INSTALL 第 3 / 11 节;
96
+ - **每轮会固定注入一点东西**:纪律提示约 2.6k 字符 + 自传体摘要(默认上限 2000 字符)—— 这部分算在你的输入里。
97
+ 自传体的预算可调;**纪律那段没有开关**(诚实说:它和你在 profile 里的自定义提示会叠加,目前没有冲突检测);
98
+ - 后台维护默认开(约 30 分钟一轮),其中两项**会调用 AI** → 有成本,且会把技能正文、相关记忆、你的原始反馈
99
+ 发给你配置的那个评审模型服务商;**可以整体关掉,也可以只关评审**(见 INSTALL)。**具体金额没有测量过**(已知缺口);
100
+ **想稳妥起步:装完第一件事就把它关掉**(`heartbeatEnabled: false`,见 INSTALL 第 10 节),只留记忆,
101
+ 确认有用了再开回来。**关掉后哪些还能用、哪些会失效,INSTALL 开头有一张对照表**;
102
+ - **空闲学习默认关**;开启后每轮都会调用一次模型(用你单独给它配的路由,**需要外部 API key**)→ 有成本;
103
+ - 检索是**关键词 + 标签**匹配,不是语义检索:**写了但召不回是可能的**;
104
+ - 一部分可靠性**靠纪律而不是机制**:结论有没有写进记忆、要不要召回到位 —— 所以偶尔自己提醒一句"这个记一下"更稳;
105
+ - **尚未测量**:召回质量、规模延迟、单位成本、学习闭环的长期效果、多机共用、经验可迁移性;
106
+ **也没有记录"测过哪些 DSH 版本"**(依赖宿主内部行为的部分,宿主升级后可能先坏)—— 这是已知缺口。
107
+
108
+ ## 风险与责任
109
+
110
+ Mnemos 是通用认知架构:身份、记忆、技能、调度**不预设用途**。但要说清 —— **架构里写进了设计者的取舍**
111
+ (外部信息先隔离、判断要留下来由、危险动作留痕),**这些不是"中立"的,是有立场的**。
112
+
113
+ 必须诚实指出四类能力:**善意使用是效率工具,恶意使用会放大后果**。
114
+
115
+ 1. **身份可被持有者改写**:宪法能用口令改。架构层的指令会与模型的原生对齐**叠加** ——
116
+ 既不能假定它压得住原生对齐,也不能假定原生对齐一定压得住它。
117
+ 2. **记忆跨会话积累**:长期、跨会话、跨模型的记忆,会让错误或恶意经验变成"**可复用的经验**"。
118
+ 3. **可调度别的模型**:主模型能派子代理干活,而**任务的真实意图可以不写在 prompt 里**(靠记忆传递),外部很难看出来。
119
+ 4. **可无人值守运行**:心跳与空闲学习能定时醒、持续跑 —— **你不在场时它也在动**。
120
+
121
+ 还有一条常被低估的:**联网抓来的内容可能自带指令**。所以我们把它关进隔离间 —— 但那只降低风险,不消除风险。
122
+
123
+ **责任**:使用者决定它的用途,**持有者作为监护人,对它的行为负最终责任**。本项目不提供任何担保,
124
+ 也不对滥用行为承担连带责任;**能写进机制的限制我们写了**(只读宪法、隔离验证、删除留痕、心跳可整体关),
125
+ **做不到的是替使用者判断**。
126
+
127
+ **反对**:反对任何违法、侵权、破坏网络安全的用法。
128
+
129
+ ## 开始用
130
+
131
+ 前提再确认一次:你得在用 **DeepSeek Harness(DSH)** —— 只在浏览器或手机上用 AI 助手的话,现在装不了。
132
+ 装之前想知道"装完屏幕上会出现什么、怎么确认它找对了数据" —— INSTALL 第 6 节就是验证步骤。
133
+
134
+ 安装、配置、工具清单、数据位置与备份 → 全部在 [`INSTALL.md`](INSTALL.md)(含验证步骤、续接任务的做法、排错表)。
135
+
136
+ ## 文档地图(对外的七份)
137
+
138
+ | 你想干什么 | 读哪份 |
139
+ |---|---|
140
+ | 判断该不该用 | `docs/简介-introduction.docx`(未打包时读同名 `.md`) |
141
+ | **先看它由什么组成、怎么跑起来** | `docs/架构总览.docx` |
142
+ | 装它 / 查配置 | [`INSTALL.md`](INSTALL.md) |
143
+ | 看它**有哪些机制**、各自保证什么、边界在哪 | `docs/architecture-机制清单.docx` |
144
+ | 知道**为什么**这样设计 | `docs/设计者视角.docx` |
145
+ | **想读代码 / 改代码**:每个模块有哪些功能、具体怎么实现 | `docs/模块与功能实现.md`(**纯 Markdown**,附录含宪法原文与系统提示原文) |
146
+ | 确认这是哪一版 | 发行目录根部的 `VERSION.md` |
147
+
148
+ > `docs/*.docx` 由打包步骤从同名 `.md` 生成;发行包里开 docx,源码仓库里读 `.md`。
149
+ > 分不清哪份是当前版时:**源码仓库看 `对外文档-v1.5/` 下的 `.md`;发行目录看根部 `VERSION.md` 里写的版本号与文件清单。**
150
+
151
+ ## License
152
+
153
+ MIT