@zooique/memora 2.0.0 → 3.0.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 (588) hide show
  1. package/CHANGELOG.md +1028 -0
  2. package/README.en.md +305 -0
  3. package/README.md +303 -148
  4. package/config.example.json +43 -0
  5. package/dist/agent/agent.d.ts +438 -295
  6. package/dist/agent/agent.d.ts.map +1 -1
  7. package/dist/agent/agent.js +1368 -836
  8. package/dist/agent/agent.js.map +1 -1
  9. package/dist/agent/assembler.d.ts +117 -39
  10. package/dist/agent/assembler.d.ts.map +1 -1
  11. package/dist/agent/assembler.js +574 -71
  12. package/dist/agent/assembler.js.map +1 -1
  13. package/dist/agent/budget.d.ts +131 -0
  14. package/dist/agent/budget.d.ts.map +1 -0
  15. package/dist/agent/budget.js +128 -0
  16. package/dist/agent/budget.js.map +1 -0
  17. package/dist/agent/builtinToolHandlers.d.ts +229 -17
  18. package/dist/agent/builtinToolHandlers.d.ts.map +1 -1
  19. package/dist/agent/builtinToolHandlers.js +758 -70
  20. package/dist/agent/builtinToolHandlers.js.map +1 -1
  21. package/dist/agent/builtinTools.d.ts +198 -7
  22. package/dist/agent/builtinTools.d.ts.map +1 -1
  23. package/dist/agent/builtinTools.js +646 -14
  24. package/dist/agent/builtinTools.js.map +1 -1
  25. package/dist/agent/compaction.d.ts +93 -0
  26. package/dist/agent/compaction.d.ts.map +1 -0
  27. package/dist/agent/compaction.js +192 -0
  28. package/dist/agent/compaction.js.map +1 -0
  29. package/dist/agent/constants.d.ts +139 -18
  30. package/dist/agent/constants.d.ts.map +1 -1
  31. package/dist/agent/constants.js +154 -18
  32. package/dist/agent/constants.js.map +1 -1
  33. package/dist/agent/contextManager.d.ts +126 -76
  34. package/dist/agent/contextManager.d.ts.map +1 -1
  35. package/dist/agent/contextManager.js +197 -135
  36. package/dist/agent/contextManager.js.map +1 -1
  37. package/dist/agent/contextPreparer.d.ts +78 -0
  38. package/dist/agent/contextPreparer.d.ts.map +1 -0
  39. package/dist/agent/contextPreparer.js +128 -0
  40. package/dist/agent/contextPreparer.js.map +1 -0
  41. package/dist/agent/duplicateInterceptor.d.ts +67 -0
  42. package/dist/agent/duplicateInterceptor.d.ts.map +1 -0
  43. package/dist/agent/duplicateInterceptor.js +82 -0
  44. package/dist/agent/duplicateInterceptor.js.map +1 -0
  45. package/dist/agent/guardRail.d.ts +166 -0
  46. package/dist/agent/guardRail.d.ts.map +1 -0
  47. package/dist/agent/guardRail.js +333 -0
  48. package/dist/agent/guardRail.js.map +1 -0
  49. package/dist/agent/loop.d.ts +718 -253
  50. package/dist/agent/loop.d.ts.map +1 -1
  51. package/dist/agent/loop.js +2215 -648
  52. package/dist/agent/loop.js.map +1 -1
  53. package/dist/agent/managers/archiveCoordinator.d.ts +21 -74
  54. package/dist/agent/managers/archiveCoordinator.d.ts.map +1 -1
  55. package/dist/agent/managers/archiveCoordinator.js +32 -105
  56. package/dist/agent/managers/archiveCoordinator.js.map +1 -1
  57. package/dist/agent/managers/chatLockManager.d.ts +20 -88
  58. package/dist/agent/managers/chatLockManager.d.ts.map +1 -1
  59. package/dist/agent/managers/chatLockManager.js +31 -103
  60. package/dist/agent/managers/chatLockManager.js.map +1 -1
  61. package/dist/agent/managers/dedupManager.d.ts +85 -0
  62. package/dist/agent/managers/dedupManager.d.ts.map +1 -0
  63. package/dist/agent/managers/dedupManager.js +248 -0
  64. package/dist/agent/managers/dedupManager.js.map +1 -0
  65. package/dist/agent/managers/goalConsistencyChecker.d.ts +42 -0
  66. package/dist/agent/managers/goalConsistencyChecker.d.ts.map +1 -0
  67. package/dist/agent/managers/goalConsistencyChecker.js +178 -0
  68. package/dist/agent/managers/goalConsistencyChecker.js.map +1 -0
  69. package/dist/agent/managers/llmCaller.d.ts +124 -0
  70. package/dist/agent/managers/llmCaller.d.ts.map +1 -0
  71. package/dist/agent/managers/llmCaller.js +417 -0
  72. package/dist/agent/managers/llmCaller.js.map +1 -0
  73. package/dist/agent/managers/llmJudgeHelper.d.ts +21 -0
  74. package/dist/agent/managers/llmJudgeHelper.d.ts.map +1 -0
  75. package/dist/agent/managers/llmJudgeHelper.js +32 -0
  76. package/dist/agent/managers/llmJudgeHelper.js.map +1 -0
  77. package/dist/agent/managers/loopMetrics.d.ts +58 -0
  78. package/dist/agent/managers/loopMetrics.d.ts.map +1 -0
  79. package/dist/agent/managers/loopMetrics.js +68 -0
  80. package/dist/agent/managers/loopMetrics.js.map +1 -0
  81. package/dist/agent/managers/memoryAdvisor.d.ts +27 -120
  82. package/dist/agent/managers/memoryAdvisor.d.ts.map +1 -1
  83. package/dist/agent/managers/memoryAdvisor.js +56 -192
  84. package/dist/agent/managers/memoryAdvisor.js.map +1 -1
  85. package/dist/agent/managers/memoryGovernance.d.ts +24 -0
  86. package/dist/agent/managers/memoryGovernance.d.ts.map +1 -0
  87. package/dist/agent/managers/memoryGovernance.js +46 -0
  88. package/dist/agent/managers/memoryGovernance.js.map +1 -0
  89. package/dist/agent/managers/memoryInspector.d.ts +59 -393
  90. package/dist/agent/managers/memoryInspector.d.ts.map +1 -1
  91. package/dist/agent/managers/memoryInspector.js +92 -736
  92. package/dist/agent/managers/memoryInspector.js.map +1 -1
  93. package/dist/agent/managers/roundSummaryGenerator.d.ts +56 -0
  94. package/dist/agent/managers/roundSummaryGenerator.d.ts.map +1 -0
  95. package/dist/agent/managers/roundSummaryGenerator.js +201 -0
  96. package/dist/agent/managers/roundSummaryGenerator.js.map +1 -0
  97. package/dist/agent/managers/sessionArchiver.d.ts +19 -63
  98. package/dist/agent/managers/sessionArchiver.d.ts.map +1 -1
  99. package/dist/agent/managers/sessionArchiver.js +83 -157
  100. package/dist/agent/managers/sessionArchiver.js.map +1 -1
  101. package/dist/agent/managers/sessionManager.d.ts +286 -57
  102. package/dist/agent/managers/sessionManager.d.ts.map +1 -1
  103. package/dist/agent/managers/sessionManager.js +846 -85
  104. package/dist/agent/managers/sessionManager.js.map +1 -1
  105. package/dist/agent/managers/sessionNamer.d.ts +35 -0
  106. package/dist/agent/managers/sessionNamer.d.ts.map +1 -0
  107. package/dist/agent/managers/sessionNamer.js +104 -0
  108. package/dist/agent/managers/sessionNamer.js.map +1 -0
  109. package/dist/agent/managers/streamAccumulator.d.ts +20 -0
  110. package/dist/agent/managers/streamAccumulator.d.ts.map +1 -0
  111. package/dist/agent/managers/streamAccumulator.js +15 -0
  112. package/dist/agent/managers/streamAccumulator.js.map +1 -0
  113. package/dist/agent/managers/textPolishManager.d.ts +8 -44
  114. package/dist/agent/managers/textPolishManager.d.ts.map +1 -1
  115. package/dist/agent/managers/textPolishManager.js +12 -47
  116. package/dist/agent/managers/textPolishManager.js.map +1 -1
  117. package/dist/agent/managers/toolCallHelpers.d.ts +105 -0
  118. package/dist/agent/managers/toolCallHelpers.d.ts.map +1 -0
  119. package/dist/agent/managers/toolCallHelpers.js +161 -0
  120. package/dist/agent/managers/toolCallHelpers.js.map +1 -0
  121. package/dist/agent/managers/workProjection.d.ts +57 -87
  122. package/dist/agent/managers/workProjection.d.ts.map +1 -1
  123. package/dist/agent/managers/workProjection.js +166 -246
  124. package/dist/agent/managers/workProjection.js.map +1 -1
  125. package/dist/agent/messageHistory.d.ts +134 -84
  126. package/dist/agent/messageHistory.d.ts.map +1 -1
  127. package/dist/agent/messageHistory.js +419 -133
  128. package/dist/agent/messageHistory.js.map +1 -1
  129. package/dist/agent/needsPlanning.d.ts +28 -0
  130. package/dist/agent/needsPlanning.d.ts.map +1 -0
  131. package/dist/agent/needsPlanning.js +68 -0
  132. package/dist/agent/needsPlanning.js.map +1 -0
  133. package/dist/agent/seed/index.d.ts +11 -0
  134. package/dist/agent/seed/index.d.ts.map +1 -0
  135. package/dist/agent/seed/index.js +10 -0
  136. package/dist/agent/seed/index.js.map +1 -0
  137. package/dist/agent/seed/orchestrator.d.ts +83 -0
  138. package/dist/agent/seed/orchestrator.d.ts.map +1 -0
  139. package/dist/agent/seed/orchestrator.js +260 -0
  140. package/dist/agent/seed/orchestrator.js.map +1 -0
  141. package/dist/agent/seed/prepare.d.ts +49 -0
  142. package/dist/agent/seed/prepare.d.ts.map +1 -0
  143. package/dist/agent/seed/prepare.js +107 -0
  144. package/dist/agent/seed/prepare.js.map +1 -0
  145. package/dist/agent/seed/types.d.ts +115 -0
  146. package/dist/agent/seed/types.d.ts.map +1 -0
  147. package/dist/agent/seed/types.js +15 -0
  148. package/dist/agent/seed/types.js.map +1 -0
  149. package/dist/agent/sessionStateMachine.d.ts +78 -0
  150. package/dist/agent/sessionStateMachine.d.ts.map +1 -0
  151. package/dist/agent/sessionStateMachine.js +182 -0
  152. package/dist/agent/sessionStateMachine.js.map +1 -0
  153. package/dist/agent/taskTableRenderer.d.ts +51 -0
  154. package/dist/agent/taskTableRenderer.d.ts.map +1 -0
  155. package/dist/agent/taskTableRenderer.js +115 -0
  156. package/dist/agent/taskTableRenderer.js.map +1 -0
  157. package/dist/agent/toolExecutor.d.ts +255 -9
  158. package/dist/agent/toolExecutor.d.ts.map +1 -1
  159. package/dist/agent/toolExecutor.js +956 -20
  160. package/dist/agent/toolExecutor.js.map +1 -1
  161. package/dist/agent/toolLedger.d.ts +120 -0
  162. package/dist/agent/toolLedger.d.ts.map +1 -0
  163. package/dist/agent/toolLedger.js +149 -0
  164. package/dist/agent/toolLedger.js.map +1 -0
  165. package/dist/agent/toolResultCache.d.ts +134 -0
  166. package/dist/agent/toolResultCache.d.ts.map +1 -0
  167. package/dist/agent/toolResultCache.js +243 -0
  168. package/dist/agent/toolResultCache.js.map +1 -0
  169. package/dist/agent/toolResultOffload.d.ts +59 -0
  170. package/dist/agent/toolResultOffload.d.ts.map +1 -0
  171. package/dist/agent/toolResultOffload.js +70 -0
  172. package/dist/agent/toolResultOffload.js.map +1 -0
  173. package/dist/agent/toolRunner.d.ts +59 -0
  174. package/dist/agent/toolRunner.d.ts.map +1 -0
  175. package/dist/agent/toolRunner.js +147 -0
  176. package/dist/agent/toolRunner.js.map +1 -0
  177. package/dist/agent/tracer.d.ts +99 -107
  178. package/dist/agent/tracer.d.ts.map +1 -1
  179. package/dist/agent/tracer.js +24 -69
  180. package/dist/agent/tracer.js.map +1 -1
  181. package/dist/agent/types.d.ts +512 -162
  182. package/dist/agent/types.d.ts.map +1 -1
  183. package/dist/agent/types.js +2 -51
  184. package/dist/agent/types.js.map +1 -1
  185. package/dist/code-exec/codeExecutionProvider.d.ts +16 -0
  186. package/dist/code-exec/codeExecutionProvider.d.ts.map +1 -0
  187. package/dist/code-exec/codeExecutionProvider.js +57 -0
  188. package/dist/code-exec/codeExecutionProvider.js.map +1 -0
  189. package/dist/code-exec/types.d.ts +37 -0
  190. package/dist/code-exec/types.d.ts.map +1 -0
  191. package/dist/code-exec/types.js +12 -0
  192. package/dist/code-exec/types.js.map +1 -0
  193. package/dist/config/expandEnvVars.d.ts +22 -0
  194. package/dist/config/expandEnvVars.d.ts.map +1 -0
  195. package/dist/config/expandEnvVars.js +38 -0
  196. package/dist/config/expandEnvVars.js.map +1 -0
  197. package/dist/config/loader.d.ts +59 -242
  198. package/dist/config/loader.d.ts.map +1 -1
  199. package/dist/config/loader.js +237 -194
  200. package/dist/config/loader.js.map +1 -1
  201. package/dist/index.d.ts +69 -74
  202. package/dist/index.d.ts.map +1 -1
  203. package/dist/index.js +93 -63
  204. package/dist/index.js.map +1 -1
  205. package/dist/llm/abortSignal.d.ts +2 -3
  206. package/dist/llm/abortSignal.d.ts.map +1 -1
  207. package/dist/llm/abortSignal.js +2 -3
  208. package/dist/llm/abortSignal.js.map +1 -1
  209. package/dist/llm/factory.d.ts +29 -25
  210. package/dist/llm/factory.d.ts.map +1 -1
  211. package/dist/llm/factory.js +34 -69
  212. package/dist/llm/factory.js.map +1 -1
  213. package/dist/llm/openaiCompatible.d.ts +25 -40
  214. package/dist/llm/openaiCompatible.d.ts.map +1 -1
  215. package/dist/llm/openaiCompatible.js +181 -129
  216. package/dist/llm/openaiCompatible.js.map +1 -1
  217. package/dist/llm/provider.d.ts +29 -42
  218. package/dist/llm/provider.d.ts.map +1 -1
  219. package/dist/llm/provider.js +11 -10
  220. package/dist/llm/provider.js.map +1 -1
  221. package/dist/llm/types.d.ts +54 -11
  222. package/dist/llm/types.d.ts.map +1 -1
  223. package/dist/llm/types.js +0 -5
  224. package/dist/llm/types.js.map +1 -1
  225. package/dist/logging/logger.d.ts +8 -29
  226. package/dist/logging/logger.d.ts.map +1 -1
  227. package/dist/logging/logger.js +43 -233
  228. package/dist/logging/logger.js.map +1 -1
  229. package/dist/logging/loggerInterface.d.ts +9 -8
  230. package/dist/logging/loggerInterface.d.ts.map +1 -1
  231. package/dist/memory/gcService.d.ts +164 -0
  232. package/dist/memory/gcService.d.ts.map +1 -0
  233. package/dist/memory/gcService.js +215 -0
  234. package/dist/memory/gcService.js.map +1 -0
  235. package/dist/memory/governance.d.ts +17 -0
  236. package/dist/memory/governance.d.ts.map +1 -0
  237. package/dist/memory/governance.js +17 -0
  238. package/dist/memory/governance.js.map +1 -0
  239. package/dist/memory/inMemoryRoundStore.d.ts +124 -0
  240. package/dist/memory/inMemoryRoundStore.d.ts.map +1 -0
  241. package/dist/memory/inMemoryRoundStore.js +216 -0
  242. package/dist/memory/inMemoryRoundStore.js.map +1 -0
  243. package/dist/memory/inMemorySessionStore.d.ts +92 -0
  244. package/dist/memory/inMemorySessionStore.d.ts.map +1 -0
  245. package/dist/memory/inMemorySessionStore.js +219 -0
  246. package/dist/memory/inMemorySessionStore.js.map +1 -0
  247. package/dist/memory/inMemorySessionViewLoader.d.ts +89 -0
  248. package/dist/memory/inMemorySessionViewLoader.d.ts.map +1 -0
  249. package/dist/memory/inMemorySessionViewLoader.js +183 -0
  250. package/dist/memory/inMemorySessionViewLoader.js.map +1 -0
  251. package/dist/memory/inMemoryStorage.d.ts +26 -141
  252. package/dist/memory/inMemoryStorage.d.ts.map +1 -1
  253. package/dist/memory/inMemoryStorage.js +48 -187
  254. package/dist/memory/inMemoryStorage.js.map +1 -1
  255. package/dist/memory/keywordsTouch.d.ts +20 -0
  256. package/dist/memory/keywordsTouch.d.ts.map +1 -0
  257. package/dist/memory/keywordsTouch.js +25 -0
  258. package/dist/memory/keywordsTouch.js.map +1 -0
  259. package/dist/memory/lockManager.d.ts +7 -2
  260. package/dist/memory/lockManager.d.ts.map +1 -1
  261. package/dist/memory/lockManager.js +35 -11
  262. package/dist/memory/lockManager.js.map +1 -1
  263. package/dist/memory/projectManager.d.ts +30 -128
  264. package/dist/memory/projectManager.d.ts.map +1 -1
  265. package/dist/memory/projectManager.js +39 -171
  266. package/dist/memory/projectManager.js.map +1 -1
  267. package/dist/memory/projectRegistry.d.ts +22 -37
  268. package/dist/memory/projectRegistry.d.ts.map +1 -1
  269. package/dist/memory/projectRegistry.js +78 -85
  270. package/dist/memory/projectRegistry.js.map +1 -1
  271. package/dist/memory/roundStore.d.ts +629 -0
  272. package/dist/memory/roundStore.d.ts.map +1 -0
  273. package/dist/memory/roundStore.js +116 -0
  274. package/dist/memory/roundStore.js.map +1 -0
  275. package/dist/memory/sessionStore.d.ts +70 -61
  276. package/dist/memory/sessionStore.d.ts.map +1 -1
  277. package/dist/memory/sessionStore.js +23 -1
  278. package/dist/memory/sessionStore.js.map +1 -1
  279. package/dist/memory/sessionViewLoader.d.ts +141 -0
  280. package/dist/memory/sessionViewLoader.d.ts.map +1 -0
  281. package/dist/memory/sessionViewLoader.js +65 -0
  282. package/dist/memory/sessionViewLoader.js.map +1 -0
  283. package/dist/memory/sourceValidation.d.ts +18 -9
  284. package/dist/memory/sourceValidation.d.ts.map +1 -1
  285. package/dist/memory/sourceValidation.js +35 -29
  286. package/dist/memory/sourceValidation.js.map +1 -1
  287. package/dist/memory/storageInterface.d.ts +45 -126
  288. package/dist/memory/storageInterface.d.ts.map +1 -1
  289. package/dist/memory/types.d.ts +82 -168
  290. package/dist/memory/types.d.ts.map +1 -1
  291. package/dist/memory/types.js +116 -79
  292. package/dist/memory/types.js.map +1 -1
  293. package/dist/project-search/projectSearchProvider.d.ts +29 -0
  294. package/dist/project-search/projectSearchProvider.d.ts.map +1 -0
  295. package/dist/project-search/projectSearchProvider.js +57 -0
  296. package/dist/project-search/projectSearchProvider.js.map +1 -0
  297. package/dist/project-search/terms.d.ts +14 -0
  298. package/dist/project-search/terms.d.ts.map +1 -0
  299. package/dist/project-search/terms.js +68 -0
  300. package/dist/project-search/terms.js.map +1 -0
  301. package/dist/project-search/types.d.ts +139 -0
  302. package/dist/project-search/types.d.ts.map +1 -0
  303. package/dist/project-search/types.js +8 -0
  304. package/dist/project-search/types.js.map +1 -0
  305. package/dist/role-pack/capabilityMap.d.ts +28 -0
  306. package/dist/role-pack/capabilityMap.d.ts.map +1 -0
  307. package/dist/role-pack/capabilityMap.js +56 -0
  308. package/dist/role-pack/capabilityMap.js.map +1 -0
  309. package/dist/role-pack/constants.d.ts +21 -0
  310. package/dist/role-pack/constants.d.ts.map +1 -0
  311. package/dist/role-pack/constants.js +21 -0
  312. package/dist/role-pack/constants.js.map +1 -0
  313. package/dist/role-pack/rolePackManager.d.ts +269 -0
  314. package/dist/role-pack/rolePackManager.d.ts.map +1 -0
  315. package/dist/role-pack/rolePackManager.js +1082 -0
  316. package/dist/role-pack/rolePackManager.js.map +1 -0
  317. package/dist/role-pack/strategyKeys.d.ts +100 -0
  318. package/dist/role-pack/strategyKeys.d.ts.map +1 -0
  319. package/dist/role-pack/strategyKeys.js +184 -0
  320. package/dist/role-pack/strategyKeys.js.map +1 -0
  321. package/dist/role-pack/strategyResolver.d.ts +109 -0
  322. package/dist/role-pack/strategyResolver.d.ts.map +1 -0
  323. package/dist/role-pack/strategyResolver.js +304 -0
  324. package/dist/role-pack/strategyResolver.js.map +1 -0
  325. package/dist/role-pack/types.d.ts +237 -0
  326. package/dist/role-pack/types.d.ts.map +1 -0
  327. package/dist/role-pack/types.js +8 -0
  328. package/dist/role-pack/types.js.map +1 -0
  329. package/dist/role-pack/validator.d.ts +38 -0
  330. package/dist/role-pack/validator.d.ts.map +1 -0
  331. package/dist/role-pack/validator.js +436 -0
  332. package/dist/role-pack/validator.js.map +1 -0
  333. package/dist/security/pathGuard.d.ts +69 -72
  334. package/dist/security/pathGuard.d.ts.map +1 -1
  335. package/dist/security/pathGuard.js +151 -131
  336. package/dist/security/pathGuard.js.map +1 -1
  337. package/dist/skill/skillLayer3.d.ts +91 -0
  338. package/dist/skill/skillLayer3.d.ts.map +1 -0
  339. package/dist/skill/skillLayer3.js +104 -0
  340. package/dist/skill/skillLayer3.js.map +1 -0
  341. package/dist/skill/skillManager.d.ts +127 -56
  342. package/dist/skill/skillManager.d.ts.map +1 -1
  343. package/dist/skill/skillManager.js +318 -163
  344. package/dist/skill/skillManager.js.map +1 -1
  345. package/dist/skill/skillScriptRunner.d.ts +97 -0
  346. package/dist/skill/skillScriptRunner.d.ts.map +1 -0
  347. package/dist/skill/skillScriptRunner.js +271 -0
  348. package/dist/skill/skillScriptRunner.js.map +1 -0
  349. package/dist/skill/types.d.ts +73 -17
  350. package/dist/skill/types.d.ts.map +1 -1
  351. package/dist/skill/types.js +5 -1
  352. package/dist/skill/types.js.map +1 -1
  353. package/dist/utils/array.d.ts +5 -6
  354. package/dist/utils/array.d.ts.map +1 -1
  355. package/dist/utils/array.js +6 -6
  356. package/dist/utils/array.js.map +1 -1
  357. package/dist/utils/atomicWrite.d.ts +8 -0
  358. package/dist/utils/atomicWrite.d.ts.map +1 -0
  359. package/dist/utils/atomicWrite.js +31 -0
  360. package/dist/utils/atomicWrite.js.map +1 -0
  361. package/dist/utils/backgroundTask.d.ts +38 -0
  362. package/dist/utils/backgroundTask.d.ts.map +1 -0
  363. package/dist/utils/backgroundTask.js +117 -0
  364. package/dist/utils/backgroundTask.js.map +1 -0
  365. package/dist/utils/configResourceManager.d.ts +79 -0
  366. package/dist/utils/configResourceManager.d.ts.map +1 -0
  367. package/dist/utils/configResourceManager.js +150 -0
  368. package/dist/utils/configResourceManager.js.map +1 -0
  369. package/dist/utils/errors.d.ts +48 -56
  370. package/dist/utils/errors.d.ts.map +1 -1
  371. package/dist/utils/errors.js +60 -58
  372. package/dist/utils/errors.js.map +1 -1
  373. package/dist/utils/eventEmitter.d.ts +141 -63
  374. package/dist/utils/eventEmitter.d.ts.map +1 -1
  375. package/dist/utils/eventEmitter.js +50 -35
  376. package/dist/utils/eventEmitter.js.map +1 -1
  377. package/dist/utils/fileSafe.d.ts +20 -0
  378. package/dist/utils/fileSafe.d.ts.map +1 -0
  379. package/dist/utils/fileSafe.js +56 -0
  380. package/dist/utils/fileSafe.js.map +1 -0
  381. package/dist/utils/frontmatter.d.ts +2 -3
  382. package/dist/utils/frontmatter.d.ts.map +1 -1
  383. package/dist/utils/frontmatter.js +6 -5
  384. package/dist/utils/frontmatter.js.map +1 -1
  385. package/dist/utils/hash.d.ts +12 -0
  386. package/dist/utils/hash.d.ts.map +1 -0
  387. package/dist/utils/hash.js +27 -0
  388. package/dist/utils/hash.js.map +1 -0
  389. package/dist/utils/http.d.ts +17 -0
  390. package/dist/utils/http.d.ts.map +1 -0
  391. package/dist/utils/http.js +29 -0
  392. package/dist/utils/http.js.map +1 -0
  393. package/dist/utils/json.d.ts +1 -1
  394. package/dist/utils/json.js +1 -1
  395. package/dist/utils/math.d.ts +34 -1
  396. package/dist/utils/math.d.ts.map +1 -1
  397. package/dist/utils/math.js +47 -14
  398. package/dist/utils/math.js.map +1 -1
  399. package/dist/utils/objects.d.ts +2 -3
  400. package/dist/utils/objects.d.ts.map +1 -1
  401. package/dist/utils/objects.js +2 -3
  402. package/dist/utils/objects.js.map +1 -1
  403. package/dist/utils/recallDefaults.d.ts +16 -0
  404. package/dist/utils/recallDefaults.d.ts.map +1 -0
  405. package/dist/utils/recallDefaults.js +16 -0
  406. package/dist/utils/recallDefaults.js.map +1 -0
  407. package/dist/utils/safeTimer.d.ts +8 -36
  408. package/dist/utils/safeTimer.d.ts.map +1 -1
  409. package/dist/utils/safeTimer.js +9 -37
  410. package/dist/utils/safeTimer.js.map +1 -1
  411. package/dist/utils/scanner.d.ts +97 -17
  412. package/dist/utils/scanner.d.ts.map +1 -1
  413. package/dist/utils/scanner.js +269 -47
  414. package/dist/utils/scanner.js.map +1 -1
  415. package/dist/utils/segmenter.d.ts +20 -29
  416. package/dist/utils/segmenter.d.ts.map +1 -1
  417. package/dist/utils/segmenter.js +230 -88
  418. package/dist/utils/segmenter.js.map +1 -1
  419. package/dist/utils/strings.d.ts +15 -32
  420. package/dist/utils/strings.d.ts.map +1 -1
  421. package/dist/utils/strings.js +25 -44
  422. package/dist/utils/strings.js.map +1 -1
  423. package/dist/utils/time.d.ts +37 -0
  424. package/dist/utils/time.d.ts.map +1 -1
  425. package/dist/utils/time.js +56 -0
  426. package/dist/utils/time.js.map +1 -1
  427. package/dist/utils/toError.d.ts +13 -1
  428. package/dist/utils/toError.d.ts.map +1 -1
  429. package/dist/utils/toError.js +18 -1
  430. package/dist/utils/toError.js.map +1 -1
  431. package/dist/web-fetch/fetchWebFetchProvider.d.ts +14 -0
  432. package/dist/web-fetch/fetchWebFetchProvider.d.ts.map +1 -0
  433. package/dist/web-fetch/fetchWebFetchProvider.js +69 -0
  434. package/dist/web-fetch/fetchWebFetchProvider.js.map +1 -0
  435. package/dist/web-fetch/types.d.ts +30 -0
  436. package/dist/web-fetch/types.d.ts.map +1 -0
  437. package/dist/web-fetch/types.js +7 -0
  438. package/dist/web-fetch/types.js.map +1 -0
  439. package/dist/web-fetch/webFetchProvider.d.ts +10 -0
  440. package/dist/web-fetch/webFetchProvider.d.ts.map +1 -0
  441. package/dist/web-fetch/webFetchProvider.js +28 -0
  442. package/dist/web-fetch/webFetchProvider.js.map +1 -0
  443. package/dist/web-search/fetchWebSearchProvider.d.ts +27 -0
  444. package/dist/web-search/fetchWebSearchProvider.d.ts.map +1 -0
  445. package/dist/web-search/fetchWebSearchProvider.js +199 -0
  446. package/dist/web-search/fetchWebSearchProvider.js.map +1 -0
  447. package/dist/web-search/types.d.ts +46 -0
  448. package/dist/web-search/types.d.ts.map +1 -0
  449. package/dist/web-search/types.js +2 -0
  450. package/dist/{persona → web-search}/types.js.map +1 -1
  451. package/dist/web-search/webSearchProvider.d.ts +10 -0
  452. package/dist/web-search/webSearchProvider.d.ts.map +1 -0
  453. package/dist/web-search/webSearchProvider.js +30 -0
  454. package/dist/web-search/webSearchProvider.js.map +1 -0
  455. package/docs/architecture/role-pack-authoring-guide.md +243 -0
  456. package/docs/architecture/role-pack-spec.md +767 -0
  457. package/docs/memora-api-reference.md +1175 -0
  458. package/docs/memora-/346/216/245/345/205/245/346/214/207/345/215/227.md +843 -0
  459. package/docs/role-pack-/345/274/200/346/224/276/351/224/256/346/214/207/345/215/227.md +148 -0
  460. package/package.json +105 -83
  461. package/role-packs/README.md +41 -0
  462. package/role-packs/memora/345/212/251/346/211/213/manifest.json +12 -0
  463. package/role-packs/memora/345/212/251/346/211/213/persona.md +12 -0
  464. package/role-packs/memora/345/212/251/346/211/213/rules.md +4 -0
  465. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/manifest.json +44 -0
  466. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/persona.md +46 -0
  467. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/rules.md +15 -0
  468. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/character-sheet.md +34 -0
  469. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/core-extractor.md +37 -0
  470. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/craft-review.md +69 -0
  471. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/dialogue-craft.md +45 -0
  472. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/emotion-wave.md +46 -0
  473. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/empathy-craft.md +79 -0
  474. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/foreshadow.md +29 -0
  475. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/hotspot-mapping.md +121 -0
  476. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/idea-lever.md +42 -0
  477. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/logline-craft.md +47 -0
  478. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/longform-guard.md +64 -0
  479. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/need-finder.md +40 -0
  480. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/outline-expand.md +46 -0
  481. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/pacing-hook.md +34 -0
  482. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/polish-method.md +113 -0
  483. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/pov-discipline.md +79 -0
  484. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/project-init/SKILL.md +112 -0
  485. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/project-init/scripts/init-novel-project.mjs +441 -0
  486. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/relationship-web.md +47 -0
  487. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/scene-craft.md +46 -0
  488. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/story-bible.md +60 -0
  489. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/story-structure.md +36 -0
  490. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/style-weaver.md +109 -0
  491. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/three-layer-check.md +27 -0
  492. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/world-builder.md +41 -0
  493. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/manifest.json +48 -0
  494. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/persona.md +73 -0
  495. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/rules.md +19 -0
  496. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/api-doc-writer.md +40 -0
  497. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/doc-planner.md +42 -0
  498. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/nutrient-search.md +28 -0
  499. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/seed-finder.md +28 -0
  500. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/ssot-audit.md +34 -0
  501. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/style-guide.md +40 -0
  502. package/dist/agent/guardrail.d.ts +0 -47
  503. package/dist/agent/guardrail.d.ts.map +0 -1
  504. package/dist/agent/guardrail.js +0 -51
  505. package/dist/agent/guardrail.js.map +0 -1
  506. package/dist/agent/managers/autoConfigRefiner.d.ts +0 -39
  507. package/dist/agent/managers/autoConfigRefiner.d.ts.map +0 -1
  508. package/dist/agent/managers/autoConfigRefiner.js +0 -150
  509. package/dist/agent/managers/autoConfigRefiner.js.map +0 -1
  510. package/dist/agent/managers/configManager.d.ts +0 -125
  511. package/dist/agent/managers/configManager.d.ts.map +0 -1
  512. package/dist/agent/managers/configManager.js +0 -194
  513. package/dist/agent/managers/configManager.js.map +0 -1
  514. package/dist/agent/managers/insightExtractor.d.ts +0 -139
  515. package/dist/agent/managers/insightExtractor.d.ts.map +0 -1
  516. package/dist/agent/managers/insightExtractor.js +0 -401
  517. package/dist/agent/managers/insightExtractor.js.map +0 -1
  518. package/dist/agent/managers/memoryDecayScheduler.d.ts +0 -198
  519. package/dist/agent/managers/memoryDecayScheduler.d.ts.map +0 -1
  520. package/dist/agent/managers/memoryDecayScheduler.js +0 -349
  521. package/dist/agent/managers/memoryDecayScheduler.js.map +0 -1
  522. package/dist/agent/managers/relationBuilder.d.ts +0 -131
  523. package/dist/agent/managers/relationBuilder.d.ts.map +0 -1
  524. package/dist/agent/managers/relationBuilder.js +0 -192
  525. package/dist/agent/managers/relationBuilder.js.map +0 -1
  526. package/dist/agent/personaMatcher.d.ts +0 -29
  527. package/dist/agent/personaMatcher.d.ts.map +0 -1
  528. package/dist/agent/personaMatcher.js +0 -60
  529. package/dist/agent/personaMatcher.js.map +0 -1
  530. package/dist/agent/userFactExtractor.d.ts +0 -25
  531. package/dist/agent/userFactExtractor.d.ts.map +0 -1
  532. package/dist/agent/userFactExtractor.js +0 -81
  533. package/dist/agent/userFactExtractor.js.map +0 -1
  534. package/dist/eval/evalRunner.d.ts +0 -94
  535. package/dist/eval/evalRunner.d.ts.map +0 -1
  536. package/dist/eval/evalRunner.js +0 -141
  537. package/dist/eval/evalRunner.js.map +0 -1
  538. package/dist/eval/evalTypes.d.ts +0 -148
  539. package/dist/eval/evalTypes.d.ts.map +0 -1
  540. package/dist/eval/evalTypes.js +0 -118
  541. package/dist/eval/evalTypes.js.map +0 -1
  542. package/dist/eval/scenarios.d.ts +0 -33
  543. package/dist/eval/scenarios.d.ts.map +0 -1
  544. package/dist/eval/scenarios.js +0 -109
  545. package/dist/eval/scenarios.js.map +0 -1
  546. package/dist/llm/embedding.d.ts +0 -67
  547. package/dist/llm/embedding.d.ts.map +0 -1
  548. package/dist/llm/embedding.js +0 -184
  549. package/dist/llm/embedding.js.map +0 -1
  550. package/dist/memory/hybridMerge.d.ts +0 -54
  551. package/dist/memory/hybridMerge.d.ts.map +0 -1
  552. package/dist/memory/hybridMerge.js +0 -36
  553. package/dist/memory/hybridMerge.js.map +0 -1
  554. package/dist/memory/inMemoryRelationStore.d.ts +0 -51
  555. package/dist/memory/inMemoryRelationStore.d.ts.map +0 -1
  556. package/dist/memory/inMemoryRelationStore.js +0 -65
  557. package/dist/memory/inMemoryRelationStore.js.map +0 -1
  558. package/dist/memory/loader.d.ts +0 -49
  559. package/dist/memory/loader.d.ts.map +0 -1
  560. package/dist/memory/loader.js +0 -93
  561. package/dist/memory/loader.js.map +0 -1
  562. package/dist/memory/recall.d.ts +0 -66
  563. package/dist/memory/recall.d.ts.map +0 -1
  564. package/dist/memory/recall.js +0 -142
  565. package/dist/memory/recall.js.map +0 -1
  566. package/dist/memory/relationStore.d.ts +0 -78
  567. package/dist/memory/relationStore.d.ts.map +0 -1
  568. package/dist/memory/relationStore.js +0 -2
  569. package/dist/memory/relationStore.js.map +0 -1
  570. package/dist/memory/store.d.ts +0 -50
  571. package/dist/memory/store.d.ts.map +0 -1
  572. package/dist/memory/store.js +0 -161
  573. package/dist/memory/store.js.map +0 -1
  574. package/dist/memory/userProfile.d.ts +0 -156
  575. package/dist/memory/userProfile.d.ts.map +0 -1
  576. package/dist/memory/userProfile.js +0 -320
  577. package/dist/memory/userProfile.js.map +0 -1
  578. package/dist/memory/vectorStore.d.ts +0 -185
  579. package/dist/memory/vectorStore.d.ts.map +0 -1
  580. package/dist/memory/vectorStore.js +0 -257
  581. package/dist/memory/vectorStore.js.map +0 -1
  582. package/dist/persona/personaManager.d.ts +0 -160
  583. package/dist/persona/personaManager.d.ts.map +0 -1
  584. package/dist/persona/personaManager.js +0 -414
  585. package/dist/persona/personaManager.js.map +0 -1
  586. package/dist/persona/types.d.ts +0 -32
  587. package/dist/persona/types.d.ts.map +0 -1
  588. package/dist/persona/types.js +0 -5
@@ -1,16 +1,6 @@
1
1
  import { SOURCE_LABELS } from '../../memory/types.js';
2
- import { byScoreDesc } from '../../utils/array.js';
3
2
  import { configError } from '../../utils/errors.js';
4
- import { nowIso } from '../../utils/time.js';
5
3
  import { truncate } from '../../utils/strings.js';
6
- import { logger } from '../../logging/logger.js';
7
- // 双通道融合排序算法 + 常量从 hybridMerge 导入(不再绕道 recall.ts)
8
- // 消除"agent 模块依赖 memory/recall.ts 内部常量"的分层违规
9
- import { hybridMerge, RECALL_LIMIT_MULTIPLIER, } from '../../memory/hybridMerge.js';
10
- // parseLlmJson 用于解析 LLM 去重判断结果(与 SessionArchiver 同模式)
11
- import { parseLlmJson } from '../../utils/json.js';
12
- // levenshtein 用于名称相似度计算(复用 sourceValidation 中的实现,避免重复造轮子)
13
- import { levenshtein } from '../../memory/sourceValidation.js';
14
4
  // ─── 常量 ────────────────────────────────────────────────
15
5
  /** 工作记忆预览条数(最近 N 条) */
16
6
  const WORKING_PREVIEW = 5;
@@ -18,143 +8,57 @@ const WORKING_PREVIEW = 5;
18
8
  const CONTENT_PREVIEW_LEN = 80;
19
9
  /** 搜索结果内容预览字符数(比快照层略长,便于用户判断相关性) */
20
10
  const SEARCH_PREVIEW_LEN = 120;
21
- // ─── L2 采纳反哺常量 ────────────────────────────────────
22
- /** 采纳反哺的 score 提升量(与 recall.ts 的 BOOST_INCREMENT 一致,保持"越常用越重要"语义统一) */
23
- const ADOPTION_BOOST_INCREMENT = 0.05;
24
- /** score 上限(与 recall.ts 的 SCORE_CEILING 一致,防止 boost 超过 1.0) */
25
- const SCORE_CEILING = 1.0;
26
- // ─── L1 语义去重常量 ────────────────────────────────────
27
- /** 参与去重扫描的 source 标签(与衰减范围一致,不扫描配置型记忆) */
28
- const DEDUP_SOURCES = [SOURCE_LABELS.INSIGHT, SOURCE_LABELS.PROFILE, SOURCE_LABELS.WORK_PROJECTION];
29
- /** 单次去重扫描的候选记忆条数上限(控制内存和 LLM 调用量) */
30
- const DEDUP_CANDIDATE_LIMIT = 50;
31
- /** 单次 LLM 判断的候选对数上限(每对约 200 tokens,10 对 ≈ 2000 tokens) */
32
- const DEDUP_PAIR_LIMIT = 10;
33
- /** 名称相似度阈值(归一化 Levenshtein 距离 ≤ 此值视为名称高度相似,进入 LLM 判断) */
34
- const DEDUP_NAME_SIMILARITY_THRESHOLD = 0.3;
35
- /** LLM 去重判断超时(ms),与 TextPolishManager 一致 */
36
- const DEDUP_TIMEOUT_MS = 15_000;
37
- /** 被判定为重复的记忆降级到此 score(接近 0 但保留可恢复性,不物理删除) */
38
- const DEDUP_LOW_SCORE = 0.1;
39
- /** 候选记忆内容预览长度(截断后送入 LLM,控制 token 消耗) */
40
- const DEDUP_CONTENT_PREVIEW_LEN = 200;
41
11
  // ─── 类 ──────────────────────────────────────────────────
42
12
  export class MemoryInspector {
43
13
  index;
44
14
  loop;
45
15
  history;
46
- /** 向量存储(可选,提供时 searchHybrid 启用语义搜索) */
47
- vectorStore = null;
48
- /** 关系存储(可选,ADR-014 侧车,未注入时关系方法静默降级) */
49
- relationStore;
50
- /** 记忆顾问(sourceHealth + suggest 委托) */
51
- advisor;
52
- /** 后台 LLM Provider(可选,用于语义去重等异步治理任务,未注入时降级跳过) */
53
- backgroundProvider;
54
16
  /**
55
- * @param index - 记忆存储(用于读写操作)
56
- * @param loop - AgentLoop(用于获取工作记忆)
57
- * @param history - MessageHistory(用于获取当前会话信息)
58
- * @param advisor - 记忆顾问(组合根一致性,由 assembler.ts 显式注入,必填)
59
- * @param relationStore - 关系存储侧车(可选,ADR-014,未注入时关系方法降级返回空/no-op)
60
- * @param backgroundProvider - 后台 LLM Provider(可选,用于语义去重,未注入时降级跳过)
17
+ * 构造记忆管理器。sourceHealth/suggest 由 Agent 门面直连 MemoryAdvisor,本类不持有 advisor(消除 3 层代理)。
61
18
  */
62
- constructor(index, loop, history, advisor, relationStore = null, backgroundProvider = null) {
19
+ constructor(index, loop, history) {
63
20
  this.index = index;
64
21
  this.loop = loop;
65
22
  this.history = history;
66
- // 组合根一致性——advisor 由 assembler.ts 显式注入(必填,不再内部创建)
67
- this.advisor = advisor;
68
- this.relationStore = relationStore;
69
- this.backgroundProvider = backgroundProvider;
70
- }
71
- /**
72
- * 注入向量存储(由 Agent 在初始化后调用,解决构造时序)
73
- */
74
- setVectorStore(vs) {
75
- this.vectorStore = vs;
76
23
  }
77
24
  // ─── 只读查询(IMemoryStorage 透传) ───────────────────
78
- // 写操作以 writeXxx 前缀命名,集中在本类末尾的"写操作"section。
79
- /**
80
- * 列出回收站中的软删除记忆(只读查询)
81
- *
82
- * @param limit 返回数量上限(默认 50)
83
- * @returns 软删除记忆列表(按 deletedAt 降序)
84
- */
85
- listDeleted(limit = 50) {
25
+ /** 列出回收站软删除记忆。limit<=0 或 undefined 表示不设上限,否则返回最近 N 条(默认 undefined=全部)。 */
26
+ listDeleted(limit) {
86
27
  return this.index.listDeleted(limit);
87
28
  }
88
- /**
89
- * 按 ID 获取单条软删除记忆(只读查询)
90
- *
91
- * 用于 restore/purge 操作前的存在性校验,避免 listDeleted 默认 50 上限
92
- * 导致回收站超量时操作失效。
93
- *
94
- * @param id 记忆唯一标识
95
- * @returns 软删除记忆,不存在或未软删除时返回 null
96
- */
29
+ /** 按 ID 获取软删除记忆(用于 restore/purge 前存在性校验,单条精确查询免全量扫描) */
97
30
  getDeletedById(id) {
98
31
  return this.index.getDeletedById(id);
99
32
  }
100
- /**
101
- * 按 ID 获取单条活跃记忆(已软删除的返回 null)
102
- *
103
- * @param id 记忆唯一标识
104
- * @returns 记忆对象,不存在或已软删除时返回 null
105
- */
33
+ /** 按 ID 获取单条活跃记忆(已软删除的返回 null) */
106
34
  getById(id) {
107
35
  return this.index.getById(id);
108
36
  }
109
- /**
110
- * 按来源标签获取记忆列表
111
- *
112
- * @param source 来源标签(如 'persona'、'rule'、'insight')
113
- * @returns 该来源的所有记忆
114
- */
37
+ /** 按来源标签获取记忆列表(如 'persona'、'rule'、'round-summary') */
115
38
  getBySource(source) {
116
39
  return this.index.getBySource(source);
117
40
  }
118
41
  /**
119
- * 列出所有记忆(用于宿主项目的记忆管理面板)
120
- *
121
- * 与 search() 不同,本方法允许空查询,返回按 score 降序排列的记忆列表。
122
- * search() 拒绝空查询是为了防止"静默全量返回"的误用;
123
- * list() 则是显式声明"我要列出所有记忆"的意图。
124
- *
125
- * @param limit 返回数量上限(默认 50)
126
- * @returns 记忆列表(按 score 降序)
42
+ * 列出活跃记忆(供宿主记忆管理面板),按 accessedAt 降序。
43
+ * search() 拒绝空查询防"静默全量返回"误用;list() 是显式声明列举——但**默认仍带 50 条上限**
44
+ * (安全默认,与 listDeleted 的 undefined=全部 语义刻意不同)。需要全量的调用方须
45
+ * 显式传入上限(如 stats().total),否则静默截断。
127
46
  */
128
47
  list(limit = 50) {
129
48
  return this.index.search('', limit);
130
49
  }
131
50
  // ─── 快照 ─────────────────────────────────────────────
132
- /**
133
- * 统一查看记忆快照(3 层)
134
- *
135
- * 简化为 3 层(工作记忆 / Bootstrap / 归档记忆)。
136
- *
137
- * 设计原则:
138
- * - **纯只读**——不动任何组件状态
139
- * - **同步返回**——避免数据不一致(不调 LLM、不调 SQLite)
140
- * - **轻量**——每层只返回前 N 条 + 总数
141
- */
51
+ /** 统一查看记忆快照(3 层):纯只读、同步返回、每层只返回前 N 条 + 总数。 */
142
52
  snapshot() {
143
53
  // 第 1 层:工作记忆(AgentLoop 的 messages 数组)
144
54
  const workingFull = this.loop.getMessages();
145
55
  const workingTotal = workingFull.length;
146
56
  const working = workingFull.slice(-WORKING_PREVIEW);
147
- // 第 2 层:Bootstrap 记忆(永驻 + 领域)
148
- // 直接按 source 查询,避免 search('', 50) 全量扫描
149
- const rules = this.index.getBySource(SOURCE_LABELS.RULE);
150
- const personas = this.index.getBySource(SOURCE_LABELS.PERSONA);
151
- const skills = this.index.getBySource(SOURCE_LABELS.SKILL);
152
- const bootstrap = [...rules, ...personas, ...skills];
153
- // 第 3 层:归档记忆计数(insight + profile + work-projection)
154
- const insightCount = this.index.countBySource(SOURCE_LABELS.INSIGHT);
155
- const profileCount = this.index.countBySource(SOURCE_LABELS.PROFILE);
156
- const workProjectionCount = this.index.countBySource(SOURCE_LABELS.WORK_PROJECTION);
157
- const archiveTotal = insightCount + profileCount + workProjectionCount;
57
+ // 第 2 层 Bootstrap 恒空:设定记忆唯一归角色包,索引不再新增,rolePackPrompt 承载规则注入。
58
+ // 保留空壳形状。宿主治理面走 stats/list/searchByKeyword,不消费本层。
59
+ // 第 3 层:归档记忆计数(round-summary,记忆库唯一对话记忆)
60
+ const roundSummaryCount = this.index.countBySource(SOURCE_LABELS.ROUND_SUMMARY);
61
+ const archiveTotal = roundSummaryCount;
158
62
  return {
159
63
  working: {
160
64
  total: workingTotal,
@@ -165,35 +69,26 @@ export class MemoryInspector {
165
69
  })),
166
70
  },
167
71
  bootstrap: {
168
- total: bootstrap.length,
169
- items: bootstrap.map((m) => ({
170
- id: m.id,
171
- source: m.source,
172
- name: m.name,
173
- contentPreview: m.content.slice(0, CONTENT_PREVIEW_LEN),
174
- score: m.score,
175
- })),
72
+ total: 0,
73
+ items: [],
176
74
  },
177
75
  archive: {
178
76
  archiveCount: archiveTotal,
179
- // ADR-014 关系边总数(relationStore 未注入时为 0)
180
- relationCount: this.countRelations(),
181
77
  currentSession: this.history.session ?? '(none)',
182
78
  currentSessionName: this.history.currentSessionName ?? '(none)',
183
79
  hint: '调 listAllSessions() 获取文件清单',
184
80
  stats: {
185
- insight: insightCount,
186
- profile: profileCount,
187
- 'work-projection': workProjectionCount,
81
+ 'round-summary': roundSummaryCount,
188
82
  },
189
83
  },
190
84
  };
191
85
  }
192
86
  // ─── 搜索 ─────────────────────────────────────────────
193
87
  /**
194
- * 搜索记忆(关键词 + FTS5 索引)
195
- *
196
- * 返回 CLI 友好的扁平结构(已处理内容截断)
88
+ * @deprecated 本同步通道已退役,功能由 `searchByKeyword()` 承担(后者含
89
+ * superseded 过滤 / excludeRoundIds 互斥 / accessedAt + 溯源揭示)。当前无生产/宿主消费方,
90
+ * 勿新增调用。
91
+ * 搜索记忆(关键词 + FTS5 索引),返回 CLI 友好扁平结构(已截断)。
197
92
  */
198
93
  search(query, limit = 10) {
199
94
  // 空 query 会让 search() 退化为"返回所有",对宿主程序是静默误导
@@ -213,26 +108,30 @@ export class MemoryInspector {
213
108
  id: m.id,
214
109
  name: m.name,
215
110
  source: m.source,
216
- score: m.score,
217
111
  // 截断长内容到搜索预览长度
218
112
  contentPreview: truncate(m.content, SEARCH_PREVIEW_LEN),
219
113
  createdAt: m.createdAt,
220
114
  }));
221
115
  }
222
116
  /**
223
- * 混合搜索记忆(语义 + 关键词双通道)
117
+ * 搜索记忆(纯关键词单通道,无向量通道、无融合排序)。
224
118
  *
225
- * 当 VectorStore 可用时,启用语义搜索通道,补强关键词召回的语义缺口。
226
- * 向量搜索失败时静默降级到纯关键词(降级优先原则)。
119
+ * 边界声明(分层分轨):searchByKeyword 是「记忆搜索工具」,不是召回管线——不应用 L1/L2 分层、
120
+ * 不进池策略(preference 无条件进池 / intent 排除)、不做 cap 内分配(capTokens / minSemanticShare)。
121
+ * 分层分轨原属「召回编排」`recall()`;**现行实现中已无任何召回编排**,
122
+ * 搜索工具只暴露过滤后的结果,供宿主/上层按需自取(见 memory-as-summary §4.5 边界标注)。
227
123
  *
228
- * 融合排序算法已提取到 hybridMerge.ts,与 recall() 共享同一实现,
229
- * 避免跨模块常量依赖。
124
+ * 无语义(向量)通道:embedding 写端缺失导致语义通道在生产从未生效,
125
+ * 属于「宣称能力零消费」的僵尸;且主流 agent(Anthropic Memory tool / Claude Code / Librarian Pattern)
126
+ * 已实证「LLM 消费者 + 小语料」下纯关键词足用——LLM 会自主改述重试(工具描述已提示)。向量语义检索
127
+ * 的 cache 形态方案记入探索期文档候选,等真实「关键词搜不到」复现再按缓存重算形态补回。
230
128
  *
231
- * @returns 混合排序后的搜索结果(含相似度分数)
129
+ * @param excludeRoundIds 排除的轮次 ID 集合(可选):这些轮次的 round-summary 已被装配期载入正文,
130
+ * 不重复返回(工具召回与装配期正文互斥,§5.1);缺省不过滤。
232
131
  */
233
- async searchHybrid(query, limit = 10) {
132
+ async searchByKeyword(query, limit = 10, excludeRoundIds) {
234
133
  if (!query || query.trim() === '') {
235
- throw configError('搜索关键词为空', 'searchHybrid() 需要非空 query', [
134
+ throw configError('搜索关键词为空', 'searchByKeyword() 需要非空 query', [
236
135
  '传入非空字符串关键词',
237
136
  ]);
238
137
  }
@@ -241,640 +140,97 @@ export class MemoryInspector {
241
140
  '使用 limit = 10(默认值)',
242
141
  ]);
243
142
  }
244
- const merged = new Map();
245
- // ── 通道 1:语义搜索(VectorStore 可用时) ──
246
- if (this.vectorStore && this.vectorStore.size > 0) {
247
- try {
248
- const vectorResults = await this.vectorStore.search(query, limit * RECALL_LIMIT_MULTIPLIER, 0.3);
249
- for (const vr of vectorResults) {
250
- const memory = this.index.getById(vr.id);
251
- if (memory) {
252
- merged.set(memory.id, { memory, vectorScore: vr.similarity });
253
- }
254
- }
255
- }
256
- catch (err) {
257
- logger.debug({ err }, '语义搜索失败,降级到关键词');
258
- }
259
- }
260
- // ── 通道 2:关键词搜索(补齐语义通道未覆盖的) ──
261
- const keywordResults = this.index.search(query, limit * RECALL_LIMIT_MULTIPLIER);
262
- for (const m of keywordResults) {
263
- if (!merged.has(m.id)) {
264
- merged.set(m.id, { memory: m, vectorScore: 0 });
265
- }
266
- }
267
- // ── 综合排序:委托给 hybridMerge 纯函数(与 recall() 共享) ──
268
- const sorted = hybridMerge(merged.values(), limit);
269
- return sorted.map(({ memory, vectorScore }) => ({
143
+ // 单个通道:纯关键词搜索(无向量通道、无融合排序,FTS 索引已按相关性返回)
144
+ const keywordResults = this.index.search(query, limit);
145
+ // 前置 superseded 过滤:被 supersededBy 取代的摘要不作为当前事实
146
+ // 返回(仍保留可回溯,trace_summary 可精确取原文)。在截断前过滤,避免占据 top-N 槽位挤掉有效命中。
147
+ const active = keywordResults.filter((m) => !m.supersededBy);
148
+ // 工具召回与装配期内容互斥(§5.1):排除「正文或摘要已在眼前」轮次的 round-summary,
149
+ // 避免 LLM 拿回眼前内容的摘要重复(excludeRoundIds 由调用方按 loop.getExclusionRoundIds 精确派生,
150
+ // = 视图内 ∪ 被替换 ∪ 在途,天然不含当轮)。
151
+ // 被排除者不补位(工具语义):返回更聚焦的结果即可,不强制凑满 limit。
152
+ const unexcluded = excludeRoundIds && excludeRoundIds.size > 0
153
+ ? active.filter((m) => !m.roundId || !excludeRoundIds.has(m.roundId))
154
+ : active;
155
+ // 截断到 limit;不引入 accessedAt 时间主序(§5.2 定案)——
156
+ // accessedAt 只作为事实字段揭示(工具命中 touch 刷新),优先级判断归 LLM 结合任务定夺。
157
+ const result = unexcluded.slice(0, limit);
158
+ return result.map((memory) => ({
270
159
  id: memory.id,
271
160
  name: memory.name,
272
161
  source: memory.source,
273
- score: memory.score,
274
- similarity: vectorScore,
275
162
  contentPreview: truncate(memory.content, SEARCH_PREVIEW_LEN),
276
163
  createdAt: memory.createdAt,
164
+ accessedAt: memory.accessedAt,
165
+ // 结构化溯源(§3.3「返回」行):round-summary 命中项显式附 sessionId/roundId,
166
+ // 与 trace_summary 参数直通——LLM 零解析直用,不得隐式编码进 name 字段。
167
+ // 字段值源:round-summary 顶层持久化 sessionName(= YYYY-MM-DD-sessionName,即 trace_summary 的 sessionId)
168
+ // + roundId;metadata 不在存储契约的保证范围内,故不从 metadata 读。
169
+ sessionId: memory.sessionName,
170
+ roundId: memory.roundId,
277
171
  }));
278
172
  }
279
173
  // ─── 统计 ─────────────────────────────────────────────
280
- /**
281
- * 记忆库统计
282
- *
283
- * 返回记忆来源分布、数据库大小等关键指标。
284
- * 优化:使用 getAllSources() 一次查询替代多次 countBySource + 全量 search,
285
- * 复杂度从 O(n*knownSources + n) 降为 O(distinctSources)。
286
- */
174
+ /** 记忆库统计:用 getAllSources() 一次查询来源分布(含宿主自定义标签),避免逐 source 多次 count */
287
175
  stats() {
288
176
  const total = this.index.count();
289
- // 直接使用 getAllSources() 获取所有 source 分布(含宿主自定义标签)
290
177
  const sourceMap = this.index.getAllSources();
291
178
  const bySource = {};
292
179
  for (const [source, count] of sourceMap) {
293
180
  if (count > 0)
294
181
  bySource[source] = count;
295
182
  }
296
- return { bySource, total, relationCount: this.countRelations() };
297
- }
298
- // ─── 关系查询(ADR-014 侧车) ───────────────────────────
299
- /**
300
- * 查询指定记忆的关系边
301
- *
302
- * ADR-014 侧车模型:关系数据独立于 Memory 7 字段基元,存储在 IMemoryRelationStore。
303
- * relationStore 未注入时返回空数组(向后兼容)。
304
- *
305
- * @param memoryId - 记忆 ID
306
- * @param direction - 方向过滤:'outgoing'(出边)/ 'incoming'(入边)/ 'both'(双向,默认)
307
- * @returns 关系边数组,按 createdAt 降序
308
- */
309
- getRelations(memoryId, direction = 'both') {
310
- if (!this.relationStore)
311
- return [];
312
- return this.relationStore.getRelations(memoryId, direction);
313
- }
314
- /**
315
- * 查询全部关系边
316
- *
317
- * 用于宿主 UI 渲染拓扑可视化(阶段 2.4)。
318
- * relationStore 未注入时返回空数组(向后兼容)。
319
- *
320
- * @returns 全部关系边数组
321
- */
322
- getAllRelations() {
323
- if (!this.relationStore)
324
- return [];
325
- return this.relationStore.getAllRelations();
326
- }
327
- // 关系写操作以 writeAddRelation / writeRemoveRelation 命名,见本类末尾"写操作"section。
328
- /**
329
- * 记忆关系路径追溯(ADR-014 扩展,Phase 5.1)
330
- *
331
- * 从指定记忆出发,沿关系边追溯来源或去向,返回完整路径。
332
- * 用于宿主 UI 展示记忆的演化脉络(如 insight-a → refines → insight-b → follows → insight-c)。
333
- *
334
- * 防环设计:使用 visited Set 记录已访问节点,防止环导致无限递归。
335
- * 深度限制:maxDepth 控制最大追溯步数,防止路径过长。
336
- *
337
- * relationStore 未注入时返回仅含起点节点的数组(向后兼容,ADR-014 降级优先)。
338
- *
339
- * @param memoryId - 起点记忆 ID
340
- * @param maxDepth - 最大追溯深度(默认 5,防止路径过长)
341
- * @param direction - 追溯方向:'incoming'(追溯来源,默认)/ 'outgoing'(追溯去向) / 'both'
342
- * @returns 路径节点列表,按 depth 升序(起点在前)
343
- */
344
- getRelationPath(memoryId, maxDepth = 5, direction = 'incoming') {
345
- // 起点节点(无论 relationStore 是否注入都返回)
346
- const startMemory = this.index.getById(memoryId);
347
- const path = [
348
- {
349
- memoryId,
350
- memoryName: startMemory?.name ?? '(unknown)',
351
- memorySource: startMemory?.source ?? '(unknown)',
352
- relationType: null,
353
- relationWeight: null,
354
- depth: 0,
355
- },
356
- ];
357
- // relationStore 未注入时仅返回起点(降级优先,ADR-014)
358
- if (!this.relationStore)
359
- return path;
360
- // BFS 遍历,visited 防环
361
- const visited = new Set([memoryId]);
362
- const queue = [
363
- { id: memoryId, depth: 0, relationType: '', relationWeight: 0 },
364
- ];
365
- while (queue.length > 0) {
366
- const current = queue.shift();
367
- if (current.depth >= maxDepth)
368
- continue;
369
- const relations = this.relationStore.getRelations(current.id, direction);
370
- for (const rel of relations) {
371
- // direction='incoming' 时邻居是 sourceId;'outgoing' 时邻居是 targetId
372
- const neighborId = direction === 'incoming' ? rel.sourceId : rel.targetId;
373
- if (visited.has(neighborId))
374
- continue;
375
- visited.add(neighborId);
376
- const neighborMemory = this.index.getById(neighborId);
377
- path.push({
378
- memoryId: neighborId,
379
- memoryName: neighborMemory?.name ?? '(unknown)',
380
- memorySource: neighborMemory?.source ?? '(unknown)',
381
- relationType: rel.type,
382
- relationWeight: rel.weight,
383
- depth: current.depth + 1,
384
- });
385
- queue.push({
386
- id: neighborId,
387
- depth: current.depth + 1,
388
- relationType: rel.type,
389
- relationWeight: rel.weight,
390
- });
391
- }
392
- }
393
- return path;
394
- }
395
- /**
396
- * 记忆关系邻居查询(ADR-014 扩展,Phase 5.2)
397
- *
398
- * 返回与指定记忆直接关联的记忆列表,含关系类型和方向。
399
- * 用于宿主 UI 展示某记忆的直接关联记忆(如冲突记忆、支持记忆、后续记忆等)。
400
- *
401
- * relationStore 未注入时返回空数组(向后兼容,ADR-014 降级优先)。
402
- *
403
- * @param memoryId - 基准记忆 ID
404
- * @param limit - 返回数量上限(默认 10,防止过多邻居导致 UI 拥挤)
405
- * @returns 邻居记忆列表,含关系类型/权重/方向
406
- */
407
- getRelationNeighbors(memoryId, limit = 10) {
408
- // relationStore 未注入时返回空数组(降级优先,ADR-014)
409
- if (!this.relationStore)
410
- return [];
411
- const neighbors = [];
412
- const seen = new Set(); // 去重(同一邻居可能有多条关系)
413
- // outgoing:memoryId 是 sourceId,邻居是 targetId
414
- const outgoing = this.relationStore.getRelations(memoryId, 'outgoing');
415
- for (const rel of outgoing) {
416
- if (seen.has(rel.targetId))
417
- continue;
418
- seen.add(rel.targetId);
419
- const neighborMemory = this.index.getById(rel.targetId);
420
- neighbors.push({
421
- memoryId: rel.targetId,
422
- memoryName: neighborMemory?.name ?? '(unknown)',
423
- memorySource: neighborMemory?.source ?? '(unknown)',
424
- memoryScore: neighborMemory?.score ?? 0,
425
- relationType: rel.type,
426
- relationWeight: rel.weight,
427
- direction: 'outgoing',
428
- });
429
- }
430
- // incoming:memoryId 是 targetId,邻居是 sourceId
431
- const incoming = this.relationStore.getRelations(memoryId, 'incoming');
432
- for (const rel of incoming) {
433
- if (seen.has(rel.sourceId))
434
- continue;
435
- seen.add(rel.sourceId);
436
- const neighborMemory = this.index.getById(rel.sourceId);
437
- neighbors.push({
438
- memoryId: rel.sourceId,
439
- memoryName: neighborMemory?.name ?? '(unknown)',
440
- memorySource: neighborMemory?.source ?? '(unknown)',
441
- memoryScore: neighborMemory?.score ?? 0,
442
- relationType: rel.type,
443
- relationWeight: rel.weight,
444
- direction: 'incoming',
445
- });
446
- }
447
- return neighbors.slice(0, limit);
448
- }
449
- /**
450
- * 统计关系边总数
451
- *
452
- * 用于 stats() 和 snapshot() 的 relationCount 字段。
453
- * relationStore 未注入时返回 0(向后兼容)。
454
- */
455
- countRelations() {
456
- if (!this.relationStore)
457
- return 0;
458
- return this.relationStore.getAllRelations().length;
459
- }
460
- // ─── 源健康诊断 + 关联推荐(委托给 MemoryAdvisor) ───
461
- /**
462
- * 记忆源健康诊断(委托给 MemoryAdvisor)
463
- *
464
- * 为每个 source 计算健康指标(数量、平均 score、新鲜度、状态)。
465
- * 实现已迁移至 MemoryAdvisor,此处保留委托以维持 API 契约。
466
- */
467
- sourceHealth() {
468
- return this.advisor.sourceHealth();
469
- }
470
- /**
471
- * 关联推荐(委托给 MemoryAdvisor)
472
- *
473
- * 基于 score + 时效性 + source 多样性推荐记忆。
474
- * 实现已迁移至 MemoryAdvisor,此处保留委托以维持 API 契约。
475
- *
476
- * @param query - 可选的搜索关键词(提供时结合搜索结果推荐,省略时基于全局热度推荐)
477
- * @param options - 推荐选项
478
- */
479
- suggest(query, options) {
480
- return this.advisor.suggest(query, options);
481
- }
482
- /**
483
- * L3 冲突检测(委托给 MemoryAdvisor.detectConflicts)
484
- *
485
- * 同 source 内配对,调用 LLM 判断语义冲突,仅检测不修复(需用户决策)。
486
- * backgroundProvider 未注入时由 advisor 内部静默跳过(返回 skippedReason 报告)。
487
- *
488
- * 委托方法存在理由:agent.ts 仅持有 memoryInspector 引用,不直接持有 memoryAdvisor,
489
- * 通过此转发保持"inspector 是读写 + 治理统一入口"语义。
490
- *
491
- * @param signal 可选的 AbortSignal
492
- * @returns 冲突报告(扫描数 / 冲突数 / 冲突详情列表 / 跳过原因)
493
- */
494
- async detectConflicts(signal) {
495
- return this.advisor.detectConflicts(signal);
183
+ return { bySource, total };
496
184
  }
497
- // ─── 写操作(writeXxx 前缀,IMemoryStorage / IMemoryRelationStore 透传) ───
498
- /**
499
- * 插入或更新记忆
500
- *
501
- * @param memory 完整记忆对象
502
- */
185
+ // ─── 写操作(writeXxx 前缀,IMemoryStorage 透传) ───
186
+ /** 插入或更新记忆 */
503
187
  writeUpsert(memory) {
504
188
  this.index.upsert(memory);
505
189
  }
506
- /**
507
- * 提升记忆的 score(L2 采纳反哺内核)
508
- *
509
- * 用户在补全模块采纳某条候选后,通过 IPC 调用此方法反哺到内核 Memory.score。
510
- * 与 recall.ts 的 boostScore 路径语义一致("越常用越重要"),但触发源不同:
511
- * - recall.ts boostScore:召回时触发(被动)
512
- * - writeBoost:用户主动采纳时触发(主动)
513
- *
514
- * 设计原则:
515
- * - 复用现有 upsert 路径,不新增存储层接口
516
- * - score 上限 1.0(与 recall.ts SCORE_CEILING 一致)
517
- * - 同步更新 accessedAt,避免被衰减机制误降级
518
- * - 记忆不存在时静默返回 false(补全候选可能来自对话历史,无对应记忆)
519
- *
520
- * @param id 记忆唯一标识(${source}:${name} 格式)
521
- * @param increment score 提升量(默认 0.05,与 recall.ts BOOST_INCREMENT 一致)
522
- * @returns 是否成功提升(记忆不存在时返回 false)
523
- */
524
- writeBoost(id, increment = ADOPTION_BOOST_INCREMENT) {
525
- const memory = this.index.getById(id);
526
- if (!memory)
527
- return false;
528
- const boosted = {
529
- ...memory,
530
- score: Math.min(SCORE_CEILING, memory.score + increment),
531
- accessedAt: nowIso(),
532
- };
533
- this.index.upsert(boosted);
534
- return true;
535
- }
536
- /**
537
- * 软删除记忆(写入 deletedAt)
538
- *
539
- * @param id 记忆唯一标识(${source}:${name} 格式)
540
- */
190
+ /** 软删除记忆(写入 deletedAt) */
541
191
  writeDelete(id) {
542
192
  this.index.delete(id);
543
193
  }
544
194
  /**
545
- * 恢复软删除的记忆(清除 deletedAt)
195
+ * 随问答闭环删除的摘要记忆软删:Round 引用归 0 被物理删除后联动。
196
+ *
197
+ * 软删即脱钩:命中 roundId 的 round-summary 清空溯源(sessionName/roundId)后再软删——
198
+ * 原会话/轮已不存在(物理回收),溯源悬空无意义;恢复后即为「无需溯源的独立记忆」。
199
+ * metadata 不在存储契约的保证范围内,故不用标记位,直接清顶层溯源字段最简。
200
+ * 治理页单条软删(writeDelete)不清溯源:误删恢复仍保留关联。
546
201
  *
547
- * @param id 记忆唯一标识
202
+ * @param roundIds 被物理删除(引用归 0)的 Round ID 集合
203
+ * @returns 软删的摘要数量(0 = 无可联动记忆)
548
204
  */
205
+ softDeleteRoundSummaries(roundIds) {
206
+ if (roundIds.length === 0)
207
+ return 0;
208
+ const idSet = new Set(roundIds);
209
+ let count = 0;
210
+ for (const memory of this.index.getBySource(SOURCE_LABELS.ROUND_SUMMARY)) {
211
+ if (memory.roundId && idSet.has(memory.roundId)) {
212
+ // 脱钩溯源(覆盖写为无溯源副本,仅清除顶层字段不动内容/权重)→ 软删进回收站
213
+ this.index.upsert({ ...memory, sessionName: undefined, roundId: undefined });
214
+ this.index.delete(memory.id);
215
+ count++;
216
+ }
217
+ }
218
+ return count;
219
+ }
220
+ /** 恢复软删除记忆(清除 deletedAt) */
549
221
  writeRestore(id) {
550
222
  this.index.restore(id);
551
223
  }
552
224
  /**
553
- * 物理删除记忆(不可恢复,用于回收站彻底删除)
554
- *
555
- * @param id 记忆唯一标识
225
+ * 物理删除记忆(不可恢复)。IMemoryStorage.purge 为同步 void(无返回值、无异步弧),
226
+ * 宿主经 IPC 同步消费——无 fire-and-forget/catch 可言,注释按事实陈述。
556
227
  */
557
228
  writePurge(id) {
558
229
  this.index.purge(id);
559
230
  }
560
- /**
561
- * 清理过期的软删除记忆
562
- *
563
- * 物理删除所有 deletedAt 早于 before 的记忆。
564
- * 由宿主项目的定时器调用(默认 30 天保留期)。
565
- *
566
- * @param before 时间阈值,deletedAt 早于此值的记忆将被物理删除
567
- * @returns 被清理的记忆数量
568
- */
231
+ /** 清理 deletedAt 早于 before 的软删除记忆(宿主定时器调用,默认 30 天保留期) */
569
232
  writePurgeExpired(before) {
570
233
  return this.index.purgeExpired(before);
571
234
  }
572
- /**
573
- * 添加记忆关系(透传 relationStore)
574
- *
575
- * 用于宿主 UI 手动创建关系(关系图右键菜单 → 连线 → 创建关系)。
576
- * relationStore 未注入时静默降级(不阻塞)。
577
- *
578
- * @param relation 关系边数据
579
- */
580
- writeAddRelation(relation) {
581
- if (!this.relationStore)
582
- return;
583
- this.relationStore.addRelation(relation);
584
- }
585
- /**
586
- * 删除记忆关系(透传 relationStore)
587
- *
588
- * 用于宿主 UI 手动删除关系(关系图右键菜单 → 编辑关系 → 删除)。
589
- * relationStore 未注入时静默降级(不阻塞)。
590
- *
591
- * @param sourceId 关系起点
592
- * @param targetId 关系终点
593
- * @param type 关系类型
594
- */
595
- writeRemoveRelation(sourceId, targetId, type) {
596
- if (!this.relationStore)
597
- return;
598
- this.relationStore.removeRelation(sourceId, targetId, type);
599
- }
600
- // ─── LLM 记忆治理(异步,backgroundProvider 未注入时静默降级) ───
601
- /**
602
- * 语义去重:扫描名称高度相似的记忆对,调用 LLM 判断语义等价性
603
- *
604
- * 流程:
605
- * 1. 从 insight/profile/work-projection 加载候选记忆(上限 50 条)
606
- * 2. 按名称归一化 Levenshtein 距离筛选相似对(上限 10 对)
607
- * 3. 对每对调用 LLM 判断语义等价性(结构化 JSON 输出)
608
- * 4. 等价则降级低分记忆(score → 0.1,不物理删除,保留可恢复性)
609
- * 5. 返回去重报告
610
- *
611
- * 安全设计:
612
- * - 不物理删除——仅降级 score,用户可通过宿主 UI 手动恢复
613
- * - LLM 失败降级——返回已处理的报告,不阻塞调用方
614
- * - 异步执行——不阻塞主对话热路径(由宿主定时任务或用户手动触发)
615
- * - backgroundProvider 未注入时静默跳过(返回 skippedReason)
616
- *
617
- * @param signal 可选的 AbortSignal(取消正在进行的 LLM 判断)
618
- * @returns 去重报告
619
- */
620
- async deduplicateMemories(signal) {
621
- // backgroundProvider 未注入时静默降级(向后兼容)
622
- if (!this.backgroundProvider) {
623
- return {
624
- scannedCount: 0,
625
- pairCount: 0,
626
- deduplicatedCount: 0,
627
- demotedIds: [],
628
- skippedReason: 'backgroundProvider 未注入',
629
- };
630
- }
631
- // ── 步骤 1:加载候选记忆(按 score 降序,取前 50 条) ──
632
- const candidates = [];
633
- for (const source of DEDUP_SOURCES) {
634
- const memories = this.index.getBySource(source);
635
- candidates.push(...memories);
636
- }
637
- // 按 score 降序排列,优先处理高分记忆(更可能产生重复)
638
- candidates.sort(byScoreDesc);
639
- const limited = candidates.slice(0, DEDUP_CANDIDATE_LIMIT);
640
- // ── 步骤 2:筛选名称高度相似的记忆对 ──
641
- const pairs = this.findNameOverlapPairs(limited);
642
- if (pairs.length === 0) {
643
- return {
644
- scannedCount: limited.length,
645
- pairCount: 0,
646
- deduplicatedCount: 0,
647
- demotedIds: [],
648
- skippedReason: '未发现名称相似的记忆对',
649
- };
650
- }
651
- // ── 步骤 3:逐对调用 LLM 判断语义等价性 ──
652
- const demotedIds = [];
653
- const verdicts = [];
654
- let deduplicatedCount = 0;
655
- for (const pair of pairs) {
656
- try {
657
- const verdict = await this.judgeDuplicate(pair, signal);
658
- if (verdict.isDuplicate) {
659
- // 降级低分记忆(b 的 score ≤ a 的 score,因 candidates 已按 score 降序)
660
- this.demoteMemory(pair.b, verdict.mergedContent);
661
- demotedIds.push(pair.b.id);
662
- // 收集审计详情(供 UI 展示"为什么降级"和"合并后保留了什么")
663
- verdicts.push({
664
- demotedId: pair.b.id,
665
- reason: verdict.reason,
666
- mergedContent: verdict.mergedContent,
667
- });
668
- deduplicatedCount++;
669
- logger.info({ demotedId: pair.b.id, keptId: pair.a.id, reason: verdict.reason }, '语义去重:降级重复记忆');
670
- }
671
- }
672
- catch (err) {
673
- // 单对 LLM 判断失败不阻塞后续对,记录警告继续
674
- logger.warn({ err, pairId: `${pair.a.id}↔${pair.b.id}` }, '语义去重:LLM 判断失败,跳过此对');
675
- }
676
- }
677
- return {
678
- scannedCount: limited.length,
679
- pairCount: pairs.length,
680
- deduplicatedCount,
681
- demotedIds,
682
- verdicts,
683
- };
684
- }
685
- /**
686
- * 筛选名称高度相似的候选记忆对
687
- *
688
- * 判定规则(满足任一即视为名称相似):
689
- * 1. 归一化 Levenshtein 距离 ≤ 0.3(如 "用户偏好" vs "用户偏爱")
690
- * 2. 一个名称包含另一个(如 "用户偏好" vs "用户偏好设置")
691
- *
692
- * 去重设计:
693
- * - 已配对的记忆不再参与后续配对(避免 A-B-C 三元组产生 A-B + A-C + B-C 三对)
694
- * - 候选对按相似度升序排列(越相似越优先),取前 10 对
695
- *
696
- * @param candidates 候选记忆列表(已按 score 降序)
697
- * @returns 名称相似的记忆对列表(a.score ≥ b.score)
698
- */
699
- findNameOverlapPairs(candidates) {
700
- const pairs = [];
701
- const usedIds = new Set();
702
- // 双重循环生成所有可能的对,按相似度排序后贪心选取
703
- const allPairs = [];
704
- for (let i = 0; i < candidates.length; i++) {
705
- for (let j = i + 1; j < candidates.length; j++) {
706
- const a = candidates[i]; // i 循环内,score 较高
707
- const b = candidates[j]; // j > i,score 较低或相等
708
- const similarity = MemoryInspector.computeNameSimilarity(a.name, b.name);
709
- if (similarity <= DEDUP_NAME_SIMILARITY_THRESHOLD) {
710
- allPairs.push({ a, b, nameSimilarity: similarity });
711
- }
712
- }
713
- }
714
- // 按相似度升序排列(越相似越优先处理)
715
- allPairs.sort((x, y) => x.nameSimilarity - y.nameSimilarity);
716
- // 贪心选取:已配对的记忆不再参与后续配对
717
- for (const { a, b, nameSimilarity } of allPairs) {
718
- if (usedIds.has(a.id) || usedIds.has(b.id))
719
- continue;
720
- pairs.push({ a, b, nameSimilarity });
721
- usedIds.add(a.id);
722
- usedIds.add(b.id);
723
- if (pairs.length >= DEDUP_PAIR_LIMIT)
724
- break;
725
- }
726
- return pairs;
727
- }
728
- /**
729
- * 计算两个名称的归一化相似度(0-1,越小越相似)
730
- *
731
- * 综合两种规则取较小值:
732
- * 1. 归一化 Levenshtein 距离 = distance / max(len_a, len_b)
733
- * 2. 包含关系:若一个名称包含另一个,相似度 = 0(完全相似)
734
- *
735
- * @param nameA 名称 A
736
- * @param nameB 名称 B
737
- * @returns 相似度(0=完全相似,1=完全不同)
738
- */
739
- static computeNameSimilarity(nameA, nameB) {
740
- // 规则 2:包含关系(如 "用户偏好" vs "用户偏好设置")
741
- if (nameA.includes(nameB) || nameB.includes(nameA)) {
742
- return 0;
743
- }
744
- // 规则 1:归一化 Levenshtein 距离
745
- const maxLen = Math.max(nameA.length, nameB.length);
746
- if (maxLen === 0)
747
- return 0; // 两个空字符串视为完全相似
748
- const distance = levenshtein(nameA, nameB);
749
- return distance / maxLen;
750
- }
751
- /**
752
- * 调用 LLM 判断单对记忆的语义等价性
753
- *
754
- * 使用结构化 JSON 输出(isDuplicate + mergedContent + reason),
755
- * 参照 SessionArchiver.generateSummary 的 parseLlmJson 模式。
756
- *
757
- * LLM 失败时抛出异常(由 deduplicateMemories 捕获并降级跳过此对)。
758
- *
759
- * @param pair 候选记忆对
760
- * @param signal 可选的 AbortSignal
761
- * @returns LLM 判断结果
762
- */
763
- async judgeDuplicate(pair, signal) {
764
- const messages = buildDedupMessages(pair);
765
- let llmResponse = '';
766
- // 流式累积模式(与 TextPolishManager / SessionArchiver 一致)
767
- for await (const chunk of this.backgroundProvider.chat(messages, {
768
- maxTokens: 300,
769
- temperature: 0,
770
- timeoutMs: DEDUP_TIMEOUT_MS,
771
- signal,
772
- })) {
773
- if (chunk.content)
774
- llmResponse += chunk.content;
775
- }
776
- // 解析 LLM 响应(JSON 格式)
777
- const parsed = parseLlmJson(llmResponse.trim());
778
- if (!parsed) {
779
- throw new Error('LLM 去重判断返回非法 JSON');
780
- }
781
- return {
782
- isDuplicate: parsed.isDuplicate === true,
783
- mergedContent: typeof parsed.mergedContent === 'string' ? parsed.mergedContent : undefined,
784
- reason: typeof parsed.reason === 'string' ? parsed.reason : '(LLM 未提供理由)',
785
- };
786
- }
787
- /**
788
- * 降级重复记忆(score → DEDUP_LOW_SCORE,可选合并内容)
789
- *
790
- * 安全设计:
791
- * - 不物理删除,仅降低 score,保留可恢复性
792
- * - 若提供 mergedContent,更新保留记忆(a)的 content 为合并后内容
793
- * - 通过 upsert 覆盖原记忆(保持 id/source/name/createdAt 不变)
794
- *
795
- * @param memory 待降级的记忆(低分方)
796
- * @param mergedContent 可选的合并后内容(更新到保留方,由调用方负责)
797
- */
798
- demoteMemory(memory, mergedContent) {
799
- const demoted = {
800
- ...memory,
801
- score: DEDUP_LOW_SCORE,
802
- // 更新 accessedAt,标记最近被处理过
803
- accessedAt: nowIso(),
804
- };
805
- this.index.upsert(demoted);
806
- // 若提供合并内容,调用方可通过 writeUpsert 单独更新保留方
807
- // 此处不直接修改保留方,保持职责单一(仅降级低分方)
808
- if (mergedContent) {
809
- logger.debug({ demotedId: memory.id, mergedContentLen: mergedContent.length }, '语义去重:合并内容已生成(需调用方手动更新保留方)');
810
- }
811
- }
812
- }
813
- // ─── L1 语义去重 Prompt 模板(模块级函数,与 TextPolishManager.buildPolishMessages 同模式) ───
814
- /**
815
- * 构建语义去重判断的 LLM 消息
816
- *
817
- * 设计要点:
818
- * - system 消息定义判断规则(语义等价 = 表达同一事实/偏好/洞察)
819
- * - user 消息携带候选对的内容预览(截断到 200 字符)
820
- * - 要求输出结构化 JSON(isDuplicate + mergedContent + reason)
821
- * - few-shot 示例降低 LLM 误判率
822
- *
823
- * @param pair 候选记忆对
824
- * @returns system + user 消息数组
825
- */
826
- function buildDedupMessages(pair) {
827
- const contentA = pair.a.content.length > DEDUP_CONTENT_PREVIEW_LEN
828
- ? truncate(pair.a.content, DEDUP_CONTENT_PREVIEW_LEN, '…[截断]')
829
- : pair.a.content;
830
- const contentB = pair.b.content.length > DEDUP_CONTENT_PREVIEW_LEN
831
- ? truncate(pair.b.content, DEDUP_CONTENT_PREVIEW_LEN, '…[截断]')
832
- : pair.b.content;
833
- return [
834
- {
835
- role: 'system',
836
- content: `你是记忆去重助手。判断给定的两条记忆是否语义等价(表达同一事实/偏好/洞察)。
837
-
838
- 判断规则:
839
- - 语义等价 = 核心信息相同,仅措辞/格式/细节程度不同
840
- - 语义不等价 = 核心信息不同,或一条是另一条的补充/细化(非等价)
841
- - 忽略时间戳、ID 等元数据差异
842
- - 忽略措辞风格差异(如"喜欢"vs"偏爱")
843
-
844
- 输出 JSON 格式:
845
- {
846
- "isDuplicate": true/false,
847
- "mergedContent": "合并后的内容(仅 isDuplicate=true 时提供,保留两条记忆的完整信息)",
848
- "reason": "判断理由(简短说明)"
849
- }
850
-
851
- 示例:
852
- 输入 A: "用户偏好简洁的 UI 设计"
853
- 输入 B: "用户喜欢简洁的界面风格"
854
- 输出: {"isDuplicate": true, "mergedContent": "用户偏好简洁的 UI/界面设计风格", "reason": "核心偏好相同,仅措辞差异"}
855
-
856
- 输入 A: "用户是 TypeScript 开发者"
857
- 输入 B: "用户偏好使用 TypeScript 进行后端开发"
858
- 输出: {"isDuplicate": false, "reason": "B 是 A 的细化(限定后端),非语义等价"}`,
859
- },
860
- {
861
- role: 'user',
862
- content: `请判断以下两条记忆是否语义等价:
863
-
864
- 记忆 A(score: ${pair.a.score},保留候选):
865
- - 名称:${pair.a.name}
866
- - 来源:${pair.a.source}
867
- - 内容:${contentA}
868
-
869
- 记忆 B(score: ${pair.b.score},降级候选):
870
- - 名称:${pair.b.name}
871
- - 来源:${pair.b.source}
872
- - 内容:${contentB}
873
-
874
- 名称相似度:${pair.nameSimilarity.toFixed(2)}(0=完全相同,1=完全不同)
875
-
876
- 请输出 JSON 判断结果。`,
877
- },
878
- ];
879
235
  }
880
236
  //# sourceMappingURL=memoryInspector.js.map