@remnic/core 9.3.612 → 9.3.614

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 (374) hide show
  1. package/dist/access-cli.js +58 -57
  2. package/dist/access-cli.js.map +1 -1
  3. package/dist/access-http.d.ts +4 -2
  4. package/dist/access-http.js +22 -22
  5. package/dist/access-mcp.d.ts +9 -2
  6. package/dist/access-mcp.js +19 -19
  7. package/dist/access-schema.d.ts +12 -12
  8. package/dist/access-schema.js +3 -3
  9. package/dist/{access-service-D2J9dh_9.d.ts → access-service-DGG_2xPK.d.ts} +1 -1
  10. package/dist/access-service.d.ts +2 -2
  11. package/dist/access-service.js +16 -16
  12. package/dist/active-recall.js +20 -3
  13. package/dist/active-recall.js.map +1 -1
  14. package/dist/adapters/index.js +4 -4
  15. package/dist/adapters/registry.js +2 -2
  16. package/dist/behavior-learner.js +2 -3
  17. package/dist/behavior-learner.js.map +1 -1
  18. package/dist/bootstrap.d.ts +1 -1
  19. package/dist/briefing.js +3 -3
  20. package/dist/buffer.d.ts +1 -1
  21. package/dist/buffer.js +1 -1
  22. package/dist/calibration.d.ts +5 -2
  23. package/dist/calibration.js +7 -5
  24. package/dist/calibration.js.map +1 -1
  25. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
  26. package/dist/causal-consolidation.d.ts +8 -2
  27. package/dist/causal-consolidation.js +13 -11
  28. package/dist/causal-consolidation.js.map +1 -1
  29. package/dist/{chunk-3BP57I6J.js → chunk-2F6NP3NT.js} +2 -1
  30. package/dist/{chunk-3BP57I6J.js.map → chunk-2F6NP3NT.js.map} +1 -1
  31. package/dist/{chunk-AU7Q3LSC.js → chunk-2QSZNTDO.js} +4 -4
  32. package/dist/{chunk-HSVJGWYS.js → chunk-2ROPI5OE.js} +2 -2
  33. package/dist/{chunk-C4SQJZAF.js → chunk-2SGJY2UY.js} +6 -3
  34. package/dist/chunk-2SGJY2UY.js.map +1 -0
  35. package/dist/{chunk-ZDTVJXIP.js → chunk-3MAONBX3.js} +13 -5
  36. package/dist/chunk-3MAONBX3.js.map +1 -0
  37. package/dist/{chunk-G3Z3QEF5.js → chunk-3PY7VHV7.js} +2 -2
  38. package/dist/chunk-3PY7VHV7.js.map +1 -0
  39. package/dist/{chunk-CF3ZF2YU.js → chunk-3QSU4NFF.js} +3 -3
  40. package/dist/{chunk-AJA46VX5.js → chunk-3T74IZB3.js} +11 -2
  41. package/dist/chunk-3T74IZB3.js.map +1 -0
  42. package/dist/{chunk-KVEVLBKC.js → chunk-4HFJQCJZ.js} +13 -8
  43. package/dist/chunk-4HFJQCJZ.js.map +1 -0
  44. package/dist/{chunk-KGK2QKWL.js → chunk-4R4KTDIE.js} +1 -1
  45. package/dist/chunk-4R4KTDIE.js.map +1 -0
  46. package/dist/{chunk-OI27U2HT.js → chunk-5BTCT236.js} +2 -2
  47. package/dist/{chunk-CO7ZO4TU.js → chunk-5VDJMYTF.js} +2 -2
  48. package/dist/{chunk-BFBF3XEF.js → chunk-6BDVBBBY.js} +33 -25
  49. package/dist/{chunk-BFBF3XEF.js.map → chunk-6BDVBBBY.js.map} +1 -1
  50. package/dist/{chunk-EAZGEEG2.js → chunk-6L46YAEZ.js} +45 -9
  51. package/dist/chunk-6L46YAEZ.js.map +1 -0
  52. package/dist/{chunk-YFS5OEKO.js → chunk-7MLB4NCL.js} +2 -2
  53. package/dist/{chunk-IOTENEVL.js → chunk-7YQFWOF7.js} +57 -50
  54. package/dist/chunk-7YQFWOF7.js.map +1 -0
  55. package/dist/{chunk-2QANQKSQ.js → chunk-ADNZVFXG.js} +15 -15
  56. package/dist/{chunk-LZ3VEOU5.js → chunk-AL4RAJL5.js} +22 -5
  57. package/dist/chunk-AL4RAJL5.js.map +1 -0
  58. package/dist/{chunk-557IAFPD.js → chunk-APRRL26Q.js} +2 -2
  59. package/dist/{chunk-QDDHYAKV.js → chunk-AZDOWD2L.js} +2 -2
  60. package/dist/{chunk-TH67Q46T.js → chunk-B6FDZPCF.js} +17 -9
  61. package/dist/chunk-B6FDZPCF.js.map +1 -0
  62. package/dist/{chunk-MLT75J5S.js → chunk-B6SU7YSE.js} +3 -3
  63. package/dist/{chunk-FXKPZ3H6.js → chunk-BPSGLMQ4.js} +2 -2
  64. package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
  65. package/dist/{chunk-NOMEVTUD.js → chunk-C6C7XVKG.js} +5 -4
  66. package/dist/chunk-C6C7XVKG.js.map +1 -0
  67. package/dist/{chunk-XKIQZXUB.js → chunk-CI7RKSRE.js} +7 -1
  68. package/dist/chunk-CI7RKSRE.js.map +1 -0
  69. package/dist/{chunk-IK34DVAC.js → chunk-CIOMS6DI.js} +2 -2
  70. package/dist/{chunk-2I5JGH3M.js → chunk-CYEPCZN5.js} +2 -2
  71. package/dist/{chunk-2I5JGH3M.js.map → chunk-CYEPCZN5.js.map} +1 -1
  72. package/dist/{chunk-JHMFYY7L.js → chunk-DCGT4FPP.js} +13 -5
  73. package/dist/chunk-DCGT4FPP.js.map +1 -0
  74. package/dist/{chunk-7DZRO2DC.js → chunk-DEPRLVLK.js} +2 -2
  75. package/dist/{chunk-CSKLPDN6.js → chunk-DEVUWMME.js} +52 -19
  76. package/dist/chunk-DEVUWMME.js.map +1 -0
  77. package/dist/{chunk-DHGSZ3UD.js → chunk-DGNQRNLL.js} +2 -2
  78. package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
  79. package/dist/chunk-FAV25DUZ.js +12 -0
  80. package/dist/chunk-FAV25DUZ.js.map +1 -0
  81. package/dist/{chunk-ETUPBUHB.js → chunk-GDASG7NC.js} +2 -2
  82. package/dist/{chunk-L227SKTB.js → chunk-GDB4J2H3.js} +17 -1
  83. package/dist/chunk-GDB4J2H3.js.map +1 -0
  84. package/dist/{chunk-IP73YCZP.js → chunk-GLPBYIXN.js} +4 -2
  85. package/dist/chunk-GLPBYIXN.js.map +1 -0
  86. package/dist/{chunk-4HP7HIE3.js → chunk-HP5FMB6L.js} +2 -2
  87. package/dist/{chunk-EVZFIAPG.js → chunk-IBTZEBUD.js} +23 -10
  88. package/dist/chunk-IBTZEBUD.js.map +1 -0
  89. package/dist/{chunk-DOX2CG6Y.js → chunk-IEUU7O4F.js} +2 -2
  90. package/dist/{chunk-JNANKJLN.js → chunk-JOASJWQR.js} +2 -2
  91. package/dist/chunk-JOASJWQR.js.map +1 -0
  92. package/dist/{chunk-WSGF57U2.js → chunk-JQDZQ4TB.js} +2 -2
  93. package/dist/{chunk-HINSGUA7.js → chunk-KBL3JJR6.js} +9 -13
  94. package/dist/chunk-KBL3JJR6.js.map +1 -0
  95. package/dist/{chunk-W7L6HXUC.js → chunk-LXOM6IQU.js} +2 -2
  96. package/dist/{chunk-G6R5UD3Q.js → chunk-MGN7VHWQ.js} +42 -1
  97. package/dist/{chunk-G6R5UD3Q.js.map → chunk-MGN7VHWQ.js.map} +1 -1
  98. package/dist/{chunk-DLJ4IR6M.js → chunk-MHQC2WU2.js} +2 -2
  99. package/dist/chunk-MHQC2WU2.js.map +1 -0
  100. package/dist/{chunk-6JGNHWCI.js → chunk-OBIRVF36.js} +3 -3
  101. package/dist/{chunk-CHCA44C3.js → chunk-ODPLEWB6.js} +3 -3
  102. package/dist/chunk-ODPLEWB6.js.map +1 -0
  103. package/dist/{chunk-HENLZHIT.js → chunk-OIF36KGD.js} +7 -4
  104. package/dist/chunk-OIF36KGD.js.map +1 -0
  105. package/dist/{chunk-GUPISBV2.js → chunk-PP2JH3GP.js} +2 -2
  106. package/dist/{chunk-OXJBNGBK.js → chunk-PSUB67YB.js} +2 -2
  107. package/dist/{chunk-UWY7GIVS.js → chunk-PYIFUBRK.js} +45 -13
  108. package/dist/chunk-PYIFUBRK.js.map +1 -0
  109. package/dist/{chunk-KIB7SDIJ.js → chunk-Q6YIJGXJ.js} +2 -2
  110. package/dist/{chunk-PPPZY2EU.js → chunk-QEMCQFDW.js} +2 -2
  111. package/dist/{chunk-ZT3EGNLR.js → chunk-QPD426WT.js} +2 -2
  112. package/dist/{chunk-RLV3PQGH.js → chunk-QVO4YOB7.js} +6 -6
  113. package/dist/{chunk-GMAG2HS4.js → chunk-RG3LBSGH.js} +46 -9
  114. package/dist/chunk-RG3LBSGH.js.map +1 -0
  115. package/dist/{chunk-XSWKORGM.js → chunk-S53OYO3F.js} +3 -1
  116. package/dist/chunk-S53OYO3F.js.map +1 -0
  117. package/dist/{chunk-YCN4BVDK.js → chunk-SCPFRKIT.js} +4 -2
  118. package/dist/chunk-SCPFRKIT.js.map +1 -0
  119. package/dist/{chunk-HJNQQICM.js → chunk-T5XWMMU2.js} +107 -50
  120. package/dist/chunk-T5XWMMU2.js.map +1 -0
  121. package/dist/{chunk-NZPF2SYV.js → chunk-T7N6KQGS.js} +138 -5
  122. package/dist/chunk-T7N6KQGS.js.map +1 -0
  123. package/dist/{chunk-VJXSUAO7.js → chunk-TNOWU6RP.js} +13 -10
  124. package/dist/chunk-TNOWU6RP.js.map +1 -0
  125. package/dist/{chunk-PCI747N2.js → chunk-TZVQQTG4.js} +48 -19
  126. package/dist/chunk-TZVQQTG4.js.map +1 -0
  127. package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
  128. package/dist/{chunk-IK7DCC5H.js → chunk-VMGLYN42.js} +2 -2
  129. package/dist/{chunk-5RPTH6AU.js → chunk-VPGUMLBA.js} +8 -7
  130. package/dist/chunk-VPGUMLBA.js.map +1 -0
  131. package/dist/{chunk-KM2A35EO.js → chunk-WB3LYXC5.js} +11 -7
  132. package/dist/chunk-WB3LYXC5.js.map +1 -0
  133. package/dist/{chunk-NSKYFGDL.js → chunk-X4QQB7O6.js} +2 -2
  134. package/dist/{chunk-HPWVAEET.js → chunk-X6IRLNOO.js} +3 -7
  135. package/dist/chunk-X6IRLNOO.js.map +1 -0
  136. package/dist/{chunk-46GJIW5M.js → chunk-XAZOWLW4.js} +5 -5
  137. package/dist/{chunk-46GJIW5M.js.map → chunk-XAZOWLW4.js.map} +1 -1
  138. package/dist/{chunk-XPSVGJYA.js → chunk-YRMKDTKF.js} +12 -9
  139. package/dist/chunk-YRMKDTKF.js.map +1 -0
  140. package/dist/{chunk-6ZZP4EJF.js → chunk-ZJR7VG5L.js} +3 -3
  141. package/dist/{chunk-6ZZP4EJF.js.map → chunk-ZJR7VG5L.js.map} +1 -1
  142. package/dist/{cli-OrfKXNU4.d.ts → cli-DWeu7eTY.d.ts} +6 -2
  143. package/dist/cli.d.ts +3 -3
  144. package/dist/cli.js +60 -59
  145. package/dist/compounding/engine.js +3 -3
  146. package/dist/compounding/preference-consolidator.js +39 -11
  147. package/dist/compounding/preference-consolidator.js.map +1 -1
  148. package/dist/config.js +1 -1
  149. package/dist/connectors/codex-materialize-runner.js +3 -3
  150. package/dist/connectors/index.js +3 -3
  151. package/dist/consolidation-provenance-check.js +1 -1
  152. package/dist/contradiction/index.js +4 -4
  153. package/dist/conversation-index/backend.js +2 -2
  154. package/dist/conversation-index/indexer.js +1 -1
  155. package/dist/cross-namespace-budget.js +1 -1
  156. package/dist/enrichment/index.js +1 -1
  157. package/dist/entity-retrieval.js +3 -3
  158. package/dist/evals.js +1 -1
  159. package/dist/explicit-capture.d.ts +1 -1
  160. package/dist/extraction-judge.js +8 -1
  161. package/dist/extraction.js +2 -2
  162. package/dist/fallback-llm.d.ts +23 -6
  163. package/dist/fallback-llm.js +5 -3
  164. package/dist/{first-start-migration-GYJWIH36.js → first-start-migration-FF7YFGRP.js} +6 -6
  165. package/dist/index.d.ts +3 -3
  166. package/dist/index.js +94 -93
  167. package/dist/index.js.map +1 -1
  168. package/dist/lcm/archive.js +2 -2
  169. package/dist/lcm/engine.js +5 -5
  170. package/dist/lcm/index.js +7 -7
  171. package/dist/lcm/summarizer.js +3 -3
  172. package/dist/maintenance/memory-governance-cron.d.ts +6 -4
  173. package/dist/maintenance/memory-governance-cron.js +1 -1
  174. package/dist/maintenance/memory-governance.js +3 -3
  175. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  176. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  177. package/dist/mcp-memory-inspector-app.d.ts +2 -2
  178. package/dist/mcp-memory-inspector-app.js +1 -1
  179. package/dist/migrate/from-engram.js +1 -1
  180. package/dist/namespaces/migrate.js +16 -15
  181. package/dist/namespaces/search.js +12 -11
  182. package/dist/namespaces/storage.js +3 -3
  183. package/dist/network/webdav.d.ts +2 -0
  184. package/dist/network/webdav.js +1 -1
  185. package/dist/objective-state-writers.js +2 -2
  186. package/dist/operator-toolkit.d.ts +3 -1
  187. package/dist/operator-toolkit.js +21 -20
  188. package/dist/{orchestrator-DTRQG75J.d.ts → orchestrator-CqWOjfgl.d.ts} +46 -3
  189. package/dist/orchestrator.d.ts +1 -1
  190. package/dist/orchestrator.js +47 -44
  191. package/dist/patterns-cli.js +1 -1
  192. package/dist/qmd-recall-cache.d.ts +2 -0
  193. package/dist/qmd-recall-cache.js +1 -1
  194. package/dist/qmd.d.ts +37 -2
  195. package/dist/qmd.js +4 -1
  196. package/dist/recall-explain-renderer.js +3 -3
  197. package/dist/recall-planner-llm.d.ts +57 -0
  198. package/dist/recall-planner-llm.js +167 -0
  199. package/dist/recall-planner-llm.js.map +1 -0
  200. package/dist/recall-xray-cli.js +4 -4
  201. package/dist/recall-xray-renderer.js +3 -3
  202. package/dist/recall-xray.js +2 -2
  203. package/dist/resume-bundles.js +2 -2
  204. package/dist/retrieval-agents.js +2 -2
  205. package/dist/routing/store.js +1 -1
  206. package/dist/search/factory.js +11 -10
  207. package/dist/search/index.js +11 -10
  208. package/dist/search/lancedb-backend.d.ts +1 -1
  209. package/dist/search/lancedb-backend.js +3 -2
  210. package/dist/search/meilisearch-backend.d.ts +1 -1
  211. package/dist/search/meilisearch-backend.js +3 -2
  212. package/dist/search/noop-backend.d.ts +1 -1
  213. package/dist/search/noop-backend.js +1 -1
  214. package/dist/search/orama-backend.d.ts +1 -1
  215. package/dist/search/orama-backend.js +3 -2
  216. package/dist/search/port.d.ts +6 -1
  217. package/dist/search/port.js +7 -0
  218. package/dist/search/remote-backend.d.ts +1 -1
  219. package/dist/search/remote-backend.js +1 -1
  220. package/dist/semantic-consolidation.js +4 -4
  221. package/dist/semantic-rule-promotion.js +3 -3
  222. package/dist/semantic-rule-verifier.js +3 -3
  223. package/dist/session-observer-state.js +1 -1
  224. package/dist/storage.js +2 -2
  225. package/dist/summarizer.js +2 -2
  226. package/dist/temporal-index.js +1 -1
  227. package/dist/{tier-stats-SKML2OSF.js → tier-stats-3LYQ3VV5.js} +3 -3
  228. package/dist/transfer/backup.js +2 -2
  229. package/dist/transfer/capsule-export.js +2 -2
  230. package/dist/transfer/capsule-import.js +2 -2
  231. package/dist/transfer/export-sqlite.js +1 -1
  232. package/dist/types.d.ts +32 -0
  233. package/dist/types.js +1 -1
  234. package/dist/utility-learner.js +1 -1
  235. package/dist/utility-runtime.js +2 -2
  236. package/dist/verified-recall.js +3 -3
  237. package/dist/work/board.js +2 -2
  238. package/dist/work/storage.d.ts +2 -0
  239. package/dist/work/storage.js +1 -1
  240. package/package.json +1 -1
  241. package/src/access-http.ts +3 -0
  242. package/src/access-mcp.test.ts +51 -0
  243. package/src/access-mcp.ts +26 -5
  244. package/src/active-recall.test.ts +40 -0
  245. package/src/active-recall.ts +19 -2
  246. package/src/behavior-learner.ts +5 -3
  247. package/src/buffer-session.test.ts +58 -0
  248. package/src/buffer-surprise-trigger.test.ts +4 -18
  249. package/src/buffer.ts +39 -11
  250. package/src/calibration.ts +10 -4
  251. package/src/causal-consolidation.test.ts +47 -2
  252. package/src/causal-consolidation.ts +13 -9
  253. package/src/cli.ts +19 -4
  254. package/src/compounding/engine.ts +2 -0
  255. package/src/compounding/preference-consolidator.test.ts +292 -0
  256. package/src/compounding/preference-consolidator.ts +55 -19
  257. package/src/config.test.ts +213 -0
  258. package/src/config.ts +175 -4
  259. package/src/connectors/codex-materialize-runner.ts +7 -4
  260. package/src/consolidation-provenance-check.ts +24 -5
  261. package/src/conversation-index/indexer.test.ts +22 -0
  262. package/src/conversation-index/indexer.ts +7 -3
  263. package/src/cross-namespace-budget.test.ts +44 -21
  264. package/src/cross-namespace-budget.ts +2 -2
  265. package/src/enrichment/pipeline.ts +11 -16
  266. package/src/evals.ts +1 -1
  267. package/src/extraction-judge-chain.test.ts +55 -0
  268. package/src/extraction-judge.ts +7 -9
  269. package/src/extraction.ts +16 -5
  270. package/src/fallback-llm.test.ts +600 -1
  271. package/src/fallback-llm.ts +91 -22
  272. package/src/maintenance/memory-governance-cron.ts +39 -29
  273. package/src/mcp-memory-inspector-app.ts +54 -12
  274. package/src/message-parts/index.ts +6 -0
  275. package/src/message-parts/message-parts.test.ts +30 -0
  276. package/src/migrate/from-engram.ts +19 -5
  277. package/src/namespaces/search.test.ts +15 -2
  278. package/src/namespaces/search.ts +1 -1
  279. package/src/network/webdav.ts +61 -21
  280. package/src/operator-toolkit.ts +6 -2
  281. package/src/orchestrator.ts +173 -20
  282. package/src/qmd-client.test.ts +85 -0
  283. package/src/qmd-recall-cache.test.ts +16 -0
  284. package/src/qmd-recall-cache.ts +7 -0
  285. package/src/qmd.test.ts +54 -0
  286. package/src/qmd.ts +119 -19
  287. package/src/recall-planner-llm.test.ts +224 -0
  288. package/src/recall-planner-llm.ts +289 -0
  289. package/src/routing/store.ts +4 -8
  290. package/src/search/factory.ts +3 -0
  291. package/src/search/lancedb-backend.ts +15 -3
  292. package/src/search/meilisearch-backend.ts +70 -7
  293. package/src/search/noop-backend.ts +5 -1
  294. package/src/search/orama-backend.ts +15 -3
  295. package/src/search/port.ts +15 -0
  296. package/src/search/remote-backend.ts +5 -1
  297. package/src/session-observer-state.ts +1 -1
  298. package/src/summarizer.ts +3 -3
  299. package/src/temporal-index.test.ts +18 -0
  300. package/src/temporal-index.ts +45 -0
  301. package/src/training-export/cli-date-validation.test.ts +36 -0
  302. package/src/training-export/date-parse.ts +21 -2
  303. package/src/transfer/export-sqlite.ts +3 -0
  304. package/src/types.ts +35 -0
  305. package/src/utility-learner.ts +1 -0
  306. package/src/work/storage.ts +23 -0
  307. package/dist/chunk-5RPTH6AU.js.map +0 -1
  308. package/dist/chunk-AJA46VX5.js.map +0 -1
  309. package/dist/chunk-C4SQJZAF.js.map +0 -1
  310. package/dist/chunk-CHCA44C3.js.map +0 -1
  311. package/dist/chunk-CSKLPDN6.js.map +0 -1
  312. package/dist/chunk-DLJ4IR6M.js.map +0 -1
  313. package/dist/chunk-EAZGEEG2.js.map +0 -1
  314. package/dist/chunk-EVZFIAPG.js.map +0 -1
  315. package/dist/chunk-G3Z3QEF5.js.map +0 -1
  316. package/dist/chunk-GMAG2HS4.js.map +0 -1
  317. package/dist/chunk-HENLZHIT.js.map +0 -1
  318. package/dist/chunk-HINSGUA7.js.map +0 -1
  319. package/dist/chunk-HJNQQICM.js.map +0 -1
  320. package/dist/chunk-HPWVAEET.js.map +0 -1
  321. package/dist/chunk-IOTENEVL.js.map +0 -1
  322. package/dist/chunk-IP73YCZP.js.map +0 -1
  323. package/dist/chunk-JHMFYY7L.js.map +0 -1
  324. package/dist/chunk-JNANKJLN.js.map +0 -1
  325. package/dist/chunk-KGK2QKWL.js.map +0 -1
  326. package/dist/chunk-KM2A35EO.js.map +0 -1
  327. package/dist/chunk-KVEVLBKC.js.map +0 -1
  328. package/dist/chunk-L227SKTB.js.map +0 -1
  329. package/dist/chunk-LZ3VEOU5.js.map +0 -1
  330. package/dist/chunk-NOMEVTUD.js.map +0 -1
  331. package/dist/chunk-NZPF2SYV.js.map +0 -1
  332. package/dist/chunk-PCI747N2.js.map +0 -1
  333. package/dist/chunk-TH67Q46T.js.map +0 -1
  334. package/dist/chunk-UWY7GIVS.js.map +0 -1
  335. package/dist/chunk-VJXSUAO7.js.map +0 -1
  336. package/dist/chunk-XKIQZXUB.js.map +0 -1
  337. package/dist/chunk-XPSVGJYA.js.map +0 -1
  338. package/dist/chunk-XSWKORGM.js.map +0 -1
  339. package/dist/chunk-YCN4BVDK.js.map +0 -1
  340. package/dist/chunk-ZDTVJXIP.js.map +0 -1
  341. /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
  342. /package/dist/{chunk-AU7Q3LSC.js.map → chunk-2QSZNTDO.js.map} +0 -0
  343. /package/dist/{chunk-HSVJGWYS.js.map → chunk-2ROPI5OE.js.map} +0 -0
  344. /package/dist/{chunk-CF3ZF2YU.js.map → chunk-3QSU4NFF.js.map} +0 -0
  345. /package/dist/{chunk-OI27U2HT.js.map → chunk-5BTCT236.js.map} +0 -0
  346. /package/dist/{chunk-CO7ZO4TU.js.map → chunk-5VDJMYTF.js.map} +0 -0
  347. /package/dist/{chunk-YFS5OEKO.js.map → chunk-7MLB4NCL.js.map} +0 -0
  348. /package/dist/{chunk-2QANQKSQ.js.map → chunk-ADNZVFXG.js.map} +0 -0
  349. /package/dist/{chunk-557IAFPD.js.map → chunk-APRRL26Q.js.map} +0 -0
  350. /package/dist/{chunk-QDDHYAKV.js.map → chunk-AZDOWD2L.js.map} +0 -0
  351. /package/dist/{chunk-MLT75J5S.js.map → chunk-B6SU7YSE.js.map} +0 -0
  352. /package/dist/{chunk-FXKPZ3H6.js.map → chunk-BPSGLMQ4.js.map} +0 -0
  353. /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
  354. /package/dist/{chunk-IK34DVAC.js.map → chunk-CIOMS6DI.js.map} +0 -0
  355. /package/dist/{chunk-7DZRO2DC.js.map → chunk-DEPRLVLK.js.map} +0 -0
  356. /package/dist/{chunk-DHGSZ3UD.js.map → chunk-DGNQRNLL.js.map} +0 -0
  357. /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
  358. /package/dist/{chunk-ETUPBUHB.js.map → chunk-GDASG7NC.js.map} +0 -0
  359. /package/dist/{chunk-4HP7HIE3.js.map → chunk-HP5FMB6L.js.map} +0 -0
  360. /package/dist/{chunk-DOX2CG6Y.js.map → chunk-IEUU7O4F.js.map} +0 -0
  361. /package/dist/{chunk-WSGF57U2.js.map → chunk-JQDZQ4TB.js.map} +0 -0
  362. /package/dist/{chunk-W7L6HXUC.js.map → chunk-LXOM6IQU.js.map} +0 -0
  363. /package/dist/{chunk-6JGNHWCI.js.map → chunk-OBIRVF36.js.map} +0 -0
  364. /package/dist/{chunk-GUPISBV2.js.map → chunk-PP2JH3GP.js.map} +0 -0
  365. /package/dist/{chunk-OXJBNGBK.js.map → chunk-PSUB67YB.js.map} +0 -0
  366. /package/dist/{chunk-KIB7SDIJ.js.map → chunk-Q6YIJGXJ.js.map} +0 -0
  367. /package/dist/{chunk-PPPZY2EU.js.map → chunk-QEMCQFDW.js.map} +0 -0
  368. /package/dist/{chunk-ZT3EGNLR.js.map → chunk-QPD426WT.js.map} +0 -0
  369. /package/dist/{chunk-RLV3PQGH.js.map → chunk-QVO4YOB7.js.map} +0 -0
  370. /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
  371. /package/dist/{chunk-IK7DCC5H.js.map → chunk-VMGLYN42.js.map} +0 -0
  372. /package/dist/{chunk-NSKYFGDL.js.map → chunk-X4QQB7O6.js.map} +0 -0
  373. /package/dist/{first-start-migration-GYJWIH36.js.map → first-start-migration-FF7YFGRP.js.map} +0 -0
  374. /package/dist/{tier-stats-SKML2OSF.js.map → tier-stats-3LYQ3VV5.js.map} +0 -0
package/src/cli.ts CHANGED
@@ -792,6 +792,7 @@ export interface AccessHttpServeCliCommandOptions {
792
792
  trustPrincipalHeader?: boolean;
793
793
  citationsEnabled?: boolean;
794
794
  citationsAutoDetect?: boolean;
795
+ emitLegacyTools?: boolean;
795
796
  createServer?: (options: {
796
797
  service: EngramAccessService;
797
798
  host?: string;
@@ -802,6 +803,7 @@ export interface AccessHttpServeCliCommandOptions {
802
803
  trustPrincipalHeader?: boolean;
803
804
  citationsEnabled?: boolean;
804
805
  citationsAutoDetect?: boolean;
806
+ emitLegacyTools?: boolean;
805
807
  }) => AccessHttpServerLike;
806
808
  }
807
809
 
@@ -2732,6 +2734,7 @@ export async function runAccessHttpServeCliCommand(
2732
2734
  trustPrincipalHeader: input.trustPrincipalHeader,
2733
2735
  citationsEnabled: input.citationsEnabled,
2734
2736
  citationsAutoDetect: input.citationsAutoDetect,
2737
+ emitLegacyTools: input.emitLegacyTools,
2735
2738
  }));
2736
2739
 
2737
2740
  const server = createServer(options);
@@ -2772,14 +2775,24 @@ export async function runAccessMcpServeCliCommand(
2772
2775
  service: EngramAccessService,
2773
2776
  options: {
2774
2777
  principal?: string;
2775
- createServer?: (service: EngramAccessService, options: { principal?: string }) => EngramMcpServerLike;
2778
+ emitLegacyTools?: boolean;
2779
+ createServer?: (
2780
+ service: EngramAccessService,
2781
+ options: { principal?: string; emitLegacyTools?: boolean },
2782
+ ) => EngramMcpServerLike;
2776
2783
  stdin?: Readable;
2777
2784
  stdout?: Writable;
2778
2785
  } = {},
2779
2786
  ): Promise<{ ok: true }> {
2780
- const server = options.createServer?.(service, { principal: options.principal }) ?? new EngramMcpServer(service, {
2781
- principal: options.principal,
2782
- });
2787
+ const server =
2788
+ options.createServer?.(service, {
2789
+ principal: options.principal,
2790
+ emitLegacyTools: options.emitLegacyTools,
2791
+ }) ??
2792
+ new EngramMcpServer(service, {
2793
+ principal: options.principal,
2794
+ emitLegacyTools: options.emitLegacyTools,
2795
+ });
2783
2796
  await server.runStdio(options.stdin ?? process.stdin, options.stdout ?? process.stdout);
2784
2797
  return { ok: true };
2785
2798
  }
@@ -6939,6 +6952,7 @@ export function registerCli(
6939
6952
  trustPrincipalHeader: options.trustPrincipalHeader === true,
6940
6953
  citationsEnabled: orchestrator.config.citationsEnabled,
6941
6954
  citationsAutoDetect: orchestrator.config.citationsAutoDetect,
6955
+ emitLegacyTools: orchestrator.config.emitLegacyTools,
6942
6956
  });
6943
6957
  console.log(JSON.stringify(status, null, 2));
6944
6958
  console.log("OK");
@@ -6977,6 +6991,7 @@ export function registerCli(
6977
6991
  const options = (args[0] ?? {}) as Record<string, unknown>;
6978
6992
  await runAccessMcpServeCliCommand(accessService, {
6979
6993
  principal: resolveAccessPrincipalOverride(options.principal, orchestrator.config.agentAccessHttp.principal),
6994
+ emitLegacyTools: orchestrator.config.emitLegacyTools,
6980
6995
  });
6981
6996
  });
6982
6997
 
@@ -492,6 +492,7 @@ export class CompoundingEngine {
492
492
  causalTrajectoryStoreDir: this.config.causalTrajectoryStoreDir,
493
493
  gatewayConfig: this.config.gatewayConfig,
494
494
  gatewayAgentId: this.config.modelSource === "gateway" ? (this.config.gatewayAgentId || undefined) : undefined,
495
+ modelChain: this.config.modelSource === "gateway" ? this.config.taskModelChain : undefined,
495
496
  workspaceDir: this.config.workspaceDir,
496
497
  pluginConfig: this.config,
497
498
  config: {
@@ -534,6 +535,7 @@ export class CompoundingEngine {
534
535
  memoryDir: this.config.memoryDir,
535
536
  gatewayConfig: this.config.gatewayConfig,
536
537
  gatewayAgentId: this.config.modelSource === "gateway" ? (this.config.gatewayAgentId || undefined) : undefined,
538
+ modelChain: this.config.modelSource === "gateway" ? this.config.taskModelChain : undefined,
537
539
  workspaceDir: this.config.workspaceDir,
538
540
  });
539
541
  log.debug(`[calibration] weekly synthesis produced ${calRules.length} calibration rule(s)`);
@@ -30,6 +30,298 @@ test("consolidatePreferences preserves never-use facts as negative preferences",
30
30
  );
31
31
  });
32
32
 
33
+ test("consolidatePreferences preserves like facts as positive preferences", () => {
34
+ const result = consolidatePreferences([
35
+ memory("The user likes React for dashboards."),
36
+ ]);
37
+
38
+ assert.equal(result.preferences.length, 1);
39
+ assert.equal(
40
+ result.preferences[0]?.statement,
41
+ "The user prefers React for dashboards",
42
+ );
43
+ });
44
+
45
+ test("consolidatePreferences preserves like-to facts as infinitive preferences", () => {
46
+ const result = consolidatePreferences([
47
+ memory("The user would like to use React for dashboards."),
48
+ ]);
49
+
50
+ assert.equal(result.preferences.length, 1);
51
+ assert.equal(
52
+ result.preferences[0]?.statement,
53
+ "The user prefers to use React for dashboards",
54
+ );
55
+ });
56
+
57
+ test("consolidatePreferences does not join separate like-to follow-up sentences", () => {
58
+ const result = consolidatePreferences([
59
+ memory("The user would like to use React. They moved to Svelte."),
60
+ ]);
61
+
62
+ assert.equal(result.preferences.length, 1);
63
+ assert.equal(result.preferences[0]?.statement, "The user prefers to use React");
64
+ });
65
+
66
+ test("consolidatePreferences preserves love facts as positive preferences", () => {
67
+ const result = consolidatePreferences([
68
+ memory("The user loves Svelte for prototypes."),
69
+ ]);
70
+
71
+ assert.equal(result.preferences.length, 1);
72
+ assert.equal(
73
+ result.preferences[0]?.statement,
74
+ "The user prefers Svelte for prototypes",
75
+ );
76
+ });
77
+
78
+ test("consolidatePreferences preserves does-not-love facts as negative preferences", () => {
79
+ const result = consolidatePreferences([
80
+ memory("The user does not love React for dashboards."),
81
+ ]);
82
+
83
+ assert.equal(result.preferences.length, 1);
84
+ assert.equal(
85
+ result.preferences[0]?.statement,
86
+ "The user would not prefer React for dashboards",
87
+ );
88
+ });
89
+
90
+ test("consolidatePreferences preserves did-not-love facts as negative preferences", () => {
91
+ const result = consolidatePreferences([
92
+ memory("The user did not love React for dashboards."),
93
+ ]);
94
+
95
+ assert.equal(result.preferences.length, 1);
96
+ assert.equal(
97
+ result.preferences[0]?.statement,
98
+ "The user would not prefer React for dashboards",
99
+ );
100
+ });
101
+
102
+ test("consolidatePreferences preserves would-not-love facts as negative preferences", () => {
103
+ const result = consolidatePreferences([
104
+ memory("The user would not love React for dashboards."),
105
+ ]);
106
+
107
+ assert.equal(result.preferences.length, 1);
108
+ assert.equal(
109
+ result.preferences[0]?.statement,
110
+ "The user would not prefer React for dashboards",
111
+ );
112
+ });
113
+
114
+ test("consolidatePreferences preserves would-not-like-to facts as negative preferences", () => {
115
+ const result = consolidatePreferences([
116
+ memory("The user would not like to use React for dashboards."),
117
+ ]);
118
+
119
+ assert.equal(result.preferences.length, 1);
120
+ assert.equal(
121
+ result.preferences[0]?.statement,
122
+ "The user would not prefer to use React for dashboards",
123
+ );
124
+ });
125
+
126
+ test("consolidatePreferences preserves no-longer-loves facts as negative preferences", () => {
127
+ const result = consolidatePreferences([
128
+ memory("The user no longer loves React."),
129
+ ]);
130
+
131
+ assert.equal(result.preferences.length, 1);
132
+ assert.equal(result.preferences[0]?.statement, "The user would not prefer React");
133
+ });
134
+
135
+ test("consolidatePreferences preserves disliked facts as negative preferences", () => {
136
+ const result = consolidatePreferences([
137
+ memory("The user disliked React for dashboards."),
138
+ ]);
139
+
140
+ assert.equal(result.preferences.length, 1);
141
+ assert.equal(
142
+ result.preferences[0]?.statement,
143
+ "The user would not prefer React for dashboards",
144
+ );
145
+ });
146
+
147
+ test("consolidatePreferences ignores double-negated dislike facts", () => {
148
+ const result = consolidatePreferences([
149
+ memory("The user does not dislike React."),
150
+ ]);
151
+
152
+ assert.equal(result.preferences.length, 0);
153
+ });
154
+
155
+ test("consolidatePreferences ignores repeated double-negated dislike facts", () => {
156
+ const result = consolidatePreferences([
157
+ memory("The user does not dislike React and does not dislike Svelte."),
158
+ ]);
159
+
160
+ assert.equal(result.preferences.length, 0);
161
+ });
162
+
163
+ test("consolidatePreferences preserves explicit preferences after double-negated aversion", () => {
164
+ const result = consolidatePreferences([
165
+ memory("The user does not dislike React, but prefers Svelte for dashboards."),
166
+ ]);
167
+
168
+ assert.equal(result.preferences.length, 1);
169
+ assert.equal(
170
+ result.preferences[0]?.statement,
171
+ "The user prefers Svelte for dashboards",
172
+ );
173
+ });
174
+
175
+ test("consolidatePreferences preserves replacement love clauses after withdrawn preferences", () => {
176
+ const result = consolidatePreferences([
177
+ memory("The user did not love React but now loves Svelte for dashboards."),
178
+ ]);
179
+
180
+ assert.equal(result.preferences.length, 1);
181
+ assert.equal(
182
+ result.preferences[0]?.statement,
183
+ "The user prefers Svelte for dashboards",
184
+ );
185
+ });
186
+
187
+ test("consolidatePreferences preserves short replacement love clauses after withdrawn preferences", () => {
188
+ const result = consolidatePreferences([
189
+ memory("The user did not love React but now loves Go."),
190
+ ]);
191
+
192
+ assert.equal(result.preferences.length, 1);
193
+ assert.equal(result.preferences[0]?.statement, "The user prefers Go");
194
+ });
195
+
196
+ test("consolidatePreferences preserves and-now replacement clauses after withdrawn preferences", () => {
197
+ const result = consolidatePreferences([
198
+ memory("The user did not love React, and now loves Svelte for dashboards."),
199
+ ]);
200
+
201
+ assert.equal(result.preferences.length, 1);
202
+ assert.equal(
203
+ result.preferences[0]?.statement,
204
+ "The user prefers Svelte for dashboards",
205
+ );
206
+ });
207
+
208
+ test("consolidatePreferences preserves plain-and replacement clauses after withdrawn preferences", () => {
209
+ const result = consolidatePreferences([
210
+ memory("The user did not love React and loves Svelte for dashboards."),
211
+ ]);
212
+
213
+ assert.equal(result.preferences.length, 1);
214
+ assert.equal(
215
+ result.preferences[0]?.statement,
216
+ "The user prefers Svelte for dashboards",
217
+ );
218
+ });
219
+
220
+ test("consolidatePreferences keeps compound negated-use clauses negative", () => {
221
+ const result = consolidatePreferences([
222
+ memory("The user does not use React and uses Svelte for dashboards."),
223
+ ]);
224
+
225
+ assert.equal(result.preferences.length, 1);
226
+ assert.equal(result.preferences[0]?.statement, "The user would not prefer React");
227
+ });
228
+
229
+ test("consolidatePreferences preserves replacement like-to clauses after withdrawn preferences", () => {
230
+ const result = consolidatePreferences([
231
+ memory("The user did not love React but like to use Svelte for dashboards."),
232
+ ]);
233
+
234
+ assert.equal(result.preferences.length, 1);
235
+ assert.equal(
236
+ result.preferences[0]?.statement,
237
+ "The user prefers to use Svelte for dashboards",
238
+ );
239
+ });
240
+
241
+ test("consolidatePreferences preserves replacement enjoying clauses after withdrawn preferences", () => {
242
+ const result = consolidatePreferences([
243
+ memory("The user did not love React but enjoying Svelte dashboard work."),
244
+ ]);
245
+
246
+ assert.equal(result.preferences.length, 1);
247
+ assert.equal(
248
+ result.preferences[0]?.statement,
249
+ "The user prefers: enjoying Svelte dashboard work",
250
+ );
251
+ });
252
+
253
+ test("consolidatePreferences preserves replacement use clauses after withdrawn preferences", () => {
254
+ const result = consolidatePreferences([
255
+ memory("The user did not love React but now uses Svelte for dashboards."),
256
+ ]);
257
+
258
+ assert.equal(result.preferences.length, 1);
259
+ assert.equal(
260
+ result.preferences[0]?.statement,
261
+ "The user prefers to use Svelte for dashboards",
262
+ );
263
+ });
264
+
265
+ test("consolidatePreferences still admits preference stem variants in facts", () => {
266
+ const result = consolidatePreferences([
267
+ memory("The user is enjoying Svelte specialization work."),
268
+ ]);
269
+
270
+ assert.equal(result.preferences.length, 1);
271
+ assert.equal(
272
+ result.preferences[0]?.statement,
273
+ "The user is enjoying Svelte specialization work",
274
+ );
275
+ });
276
+
277
+ test("consolidatePreferences ignores like analogies in facts", () => {
278
+ const result = consolidatePreferences([
279
+ memory("The user said Next.js is like React."),
280
+ ]);
281
+
282
+ assert.equal(result.preferences.length, 0);
283
+ });
284
+
285
+ test("consolidatePreferences ignores stale past-tense liked facts", () => {
286
+ const result = consolidatePreferences([
287
+ memory("The user liked Angular before switching to React."),
288
+ ]);
289
+
290
+ assert.equal(result.preferences.length, 0);
291
+ });
292
+
293
+ test("consolidatePreferences preserves multiline use-for facts", () => {
294
+ const result = consolidatePreferences([
295
+ memory("The user uses React\nfor dashboards."),
296
+ ]);
297
+
298
+ assert.equal(result.preferences.length, 1);
299
+ assert.equal(
300
+ result.preferences[0]?.statement,
301
+ "The user prefers to use React for dashboards",
302
+ );
303
+ });
304
+
305
+ test("consolidatePreferences does not join separate use and movement sentences", () => {
306
+ const result = consolidatePreferences([
307
+ memory("The user uses React.\nThey moved to Svelte."),
308
+ ]);
309
+
310
+ assert.equal(result.preferences.length, 0);
311
+ });
312
+
313
+ test("consolidatePreferences preserves a first use clause before later sentences", () => {
314
+ const result = consolidatePreferences([
315
+ memory("The user uses React for dashboards.\nThey moved to Svelte."),
316
+ ]);
317
+
318
+ assert.equal(result.preferences.length, 1);
319
+ assert.equal(
320
+ result.preferences[0]?.statement,
321
+ "The user prefers to use React for dashboards",
322
+ );
323
+ });
324
+
33
325
  test("consolidatePreferences preserves does-not-use facts as negative preferences", () => {
34
326
  const result = consolidatePreferences([
35
327
  memory("The user does not use React for dashboards."),
@@ -48,15 +48,24 @@ const PREFERENCE_EXTRACTORS: Array<{
48
48
  }> = [
49
49
  // "Avoids X" / negated use/work/code statements → negative preference
50
50
  {
51
- pattern: /(?:avoids?|dislikes?|hates?|does\s+not\s+like|doesn'?t\s+like|never\s+uses?|does\s+not\s+uses?|doesn'?t\s+uses?|does\s+not\s+use|doesn'?t\s+use|never\s+works?\s+(?:with|in)|does\s+not\s+works?\s+(?:with|in)|doesn'?t\s+works?\s+(?:with|in)|never\s+codes?\s+(?:in|with)|does\s+not\s+codes?\s+(?:in|with)|doesn'?t\s+codes?\s+(?:in|with)|refuses\s+to\s+(?:use|work\s+(?:with|in)|code\s+(?:in|with)))\s+(.+?)$/im,
51
+ pattern: /(?:avoids?|avoided|dislikes?|disliked|hates?|hated|does\s+not\s+(?:prefer|like|love|enjoy|favou?r)s?|doesn'?t\s+(?:prefer|like|love|enjoy|favou?r)s?|did\s+not\s+(?:prefer|like|love|enjoy|favou?r)s?|didn'?t\s+(?:prefer|like|love|enjoy|favou?r)s?|would\s+not\s+(?:prefer|like|love|enjoy|favou?r)s?|wouldn'?t\s+(?:prefer|like|love|enjoy|favou?r)s?|won'?t\s+(?:prefer|like|love|enjoy|favou?r)s?|never\s+(?:prefers?|likes?|loves?|enjoys?|favou?rs?)|no\s+longer\s+(?:prefers?|likes?|loves?|enjoys?|favou?rs?)|never\s+uses?|does\s+not\s+uses?|doesn'?t\s+uses?|does\s+not\s+use|doesn'?t\s+use|would\s+not\s+use|wouldn'?t\s+use|won'?t\s+use|never\s+works?\s+(?:with|in)|does\s+not\s+works?\s+(?:with|in)|doesn'?t\s+works?\s+(?:with|in)|would\s+not\s+works?\s+(?:with|in)|wouldn'?t\s+works?\s+(?:with|in)|won'?t\s+works?\s+(?:with|in)|never\s+codes?\s+(?:in|with)|does\s+not\s+codes?\s+(?:in|with)|doesn'?t\s+codes?\s+(?:in|with)|would\s+not\s+codes?\s+(?:in|with)|wouldn'?t\s+codes?\s+(?:in|with)|won'?t\s+codes?\s+(?:in|with)|refuses\s+to\s+(?:use|work\s+(?:with|in)|code\s+(?:in|with)))\s+([^.!?]+?)(?=\s+(?:(?:but|however|though|although|except|instead|rather)\b|and\s+(?:(?:now|currently|instead|rather)\b|(?=(?:prefer\w*|enjoy\w*|likes|like\s+to|loves?|loving|favou?r\w*|uses?|works?\s+(?:with|in)|codes?\s+(?:in|with)|interested\s+in|passionate\s+about|focused\s+on|specializ\w*)\b)))|[.!?]|$)/im,
52
52
  transform: (match) => {
53
53
  const subject = match[1].replace(/\.$/, "").trim();
54
54
  return `The user would not prefer ${subject}`;
55
55
  },
56
56
  },
57
+ // "Would like to X" / "like to X" → preference for doing X
58
+ {
59
+ pattern: /\blikes?\s+to\s+([^.!?]+?)(?:\s+(?:for|when|in|over)\s+([^.!?]+?))?(?=[.!?]|$)/im,
60
+ transform: (match) => {
61
+ const action = match[1].replace(/\.$/, "").trim();
62
+ const context = match[2] ? ` for ${match[2].replace(/\.$/, "").trim()}` : "";
63
+ return `The user prefers to ${action}${context}`;
64
+ },
65
+ },
57
66
  // Direct preference statements
58
67
  {
59
- pattern: /(?:prefers?|enjoys?|likes?|loves?|favou?rs?)\s+(.+?)(?:\s+(?:for|when|in|over)\s+(.+?))?$/im,
68
+ pattern: /\b(?:prefers?|enjoys?|likes|loves?|loving|favou?rs?)\s+(.+?)(?:\s+(?:for|when|in|over)\s+(.+?))?$/im,
60
69
  transform: (match) => {
61
70
  const subject = match[1].replace(/\.$/, "").trim();
62
71
  const context = match[2] ? ` for ${match[2].replace(/\.$/, "").trim()}` : "";
@@ -65,10 +74,12 @@ const PREFERENCE_EXTRACTORS: Array<{
65
74
  },
66
75
  // "Uses X for Y" → preference for X in Y context
67
76
  {
68
- pattern: /(?:uses?|works?\s+(?:with|in)|codes?\s+(?:in|with))\s+(.+?)(?:\s+(?:for|to|when)\s+(.+?))?$/im,
77
+ pattern: /(?:uses?|works?\s+(?:with|in)|codes?\s+(?:in|with))\s+([^.!?]+?)(?:\s+(?:for|to|when)\s+([^.!?]+?))?(?=[.!?]|$)/i,
69
78
  transform: (match) => {
70
- const tool = match[1].replace(/\.$/, "").trim();
71
- const context = match[2] ? ` for ${match[2].replace(/\.$/, "").trim()}` : "";
79
+ const tool = match[1].replace(/\s+/g, " ").replace(/\.$/, "").trim();
80
+ const context = match[2]
81
+ ? ` for ${match[2].replace(/\s+/g, " ").replace(/\.$/, "").trim()}`
82
+ : "";
72
83
  return `The user prefers to use ${tool}${context}`;
73
84
  },
74
85
  },
@@ -91,6 +102,26 @@ const PREFERENCE_EXTRACTORS: Array<{
91
102
  },
92
103
  ];
93
104
 
105
+ const FACT_PREFERENCE_LANGUAGE_PATTERN =
106
+ /\b(?:prefer\w*|enjoy\w*|likes|like\s+to|loves?|loving|favou?r\w*|avoid\w*|dislik\w*|hat(?:e|es|ed|ing)|interested\s+in|passionate\s+about|specializ\w*|go-to)\b/i;
107
+ const FACT_USE_CONTEXT_PATTERN =
108
+ /\b(?:uses?|works?\s+(?:with|in)|codes?\s+(?:in|with))\b[^.!?]+\b(?:for|to|when)\b/i;
109
+ const DOUBLE_NEGATED_AVERSION_PATTERN =
110
+ /\b(?:does\s+not|doesn'?t|did\s+not|didn'?t|never|no\s+longer)\s+(?:avoids?|avoided|dislikes?|disliked|hates?|hated)\b/i;
111
+ const DOUBLE_NEGATED_AVERSION_GLOBAL_PATTERN =
112
+ /\b(?:does\s+not|doesn'?t|did\s+not|didn'?t|never|no\s+longer)\s+(?:avoids?|avoided|dislikes?|disliked|hates?|hated)\b/gi;
113
+ const WITHDRAWN_PREFERENCE_PATTERN =
114
+ /\b(?:avoids?|avoided|dislikes?|disliked|hates?|hated|does\s+not\s+(?:prefer|like|love|enjoy|favou?r)s?|doesn'?t\s+(?:prefer|like|love|enjoy|favou?r)s?|did\s+not\s+(?:prefer|like|love|enjoy|favou?r)s?|didn'?t\s+(?:prefer|like|love|enjoy|favou?r)s?|would\s+not\s+(?:prefer|like|love|enjoy|favou?r)s?|wouldn'?t\s+(?:prefer|like|love|enjoy|favou?r)s?|won'?t\s+(?:prefer|like|love|enjoy|favou?r)s?|never\s+(?:prefers?|likes?|loves?|enjoys?|favou?rs?)|no\s+longer\s+(?:prefers?|likes?|loves?|enjoys?|favou?rs?))\b/i;
115
+ const REPLACEMENT_PREFERENCE_CLAUSE_PATTERN =
116
+ /\b(?:(?:but|however|though|although)\s+(?:now\s+|currently\s+|instead\s+|rather\s+)?|and\s+(?:now\s+|currently\s+|instead\s+|rather\s+)?)(?=(?:prefer\w*|enjoy\w*|likes|like\s+to|loves?|loving|favou?r\w*|uses?|works?\s+(?:with|in)|codes?\s+(?:in|with)|interested\s+in|passionate\s+about|focused\s+on|specializ\w*)\b)/i;
117
+
118
+ function replacementPreferenceClause(content: string): string | null {
119
+ const match = REPLACEMENT_PREFERENCE_CLAUSE_PATTERN.exec(content);
120
+ if (!match) return null;
121
+ const clause = content.slice(match.index + match[0].length).trim();
122
+ return clause.replace(/[.!?]+$/, "").trim().length > 0 ? clause : null;
123
+ }
124
+
94
125
  /**
95
126
  * Fallback: convert any preference/correction memory content into a
96
127
  * "The user prefers..." statement by prepending a suitable prefix.
@@ -184,17 +215,9 @@ export function consolidatePreferences(
184
215
  if (m.frontmatter.category !== "fact") return false;
185
216
  if (m.frontmatter.status && m.frontmatter.status !== "active") return false;
186
217
  if ((m.frontmatter.confidence ?? 0) < minConfidence) return false;
187
- const lower = m.content.toLowerCase();
188
218
  return (
189
- lower.includes("prefer") ||
190
- lower.includes("enjoy") ||
191
- lower.includes("like to") ||
192
- lower.includes("interested in") ||
193
- lower.includes("passionate about") ||
194
- lower.includes("specializ") ||
195
- lower.includes("favourite") ||
196
- lower.includes("favorite") ||
197
- (lower.includes("use") && lower.includes("for"))
219
+ FACT_PREFERENCE_LANGUAGE_PATTERN.test(m.content) ||
220
+ FACT_USE_CONTEXT_PATTERN.test(m.content)
198
221
  );
199
222
  });
200
223
 
@@ -225,24 +248,37 @@ export function consolidatePreferences(
225
248
 
226
249
  for (const mem of deduped.slice(0, maxPreferences * 2)) {
227
250
  const content = mem.content.trim();
251
+ const hasDoubleNegatedAversion = DOUBLE_NEGATED_AVERSION_PATTERN.test(content);
252
+ const hasWithdrawnPreference = WITHDRAWN_PREFERENCE_PATTERN.test(content);
253
+ const strippedContent = hasDoubleNegatedAversion
254
+ ? content.replace(DOUBLE_NEGATED_AVERSION_GLOBAL_PATTERN, " ").trim()
255
+ : content;
256
+ const replacementContent = hasWithdrawnPreference
257
+ ? replacementPreferenceClause(strippedContent)
258
+ : null;
259
+ const extractionContent = replacementContent ?? strippedContent;
228
260
  let statement: string | null = null;
229
261
 
230
262
  // Try pattern-based extraction first
231
263
  for (const extractor of PREFERENCE_EXTRACTORS) {
232
- const match = content.match(extractor.pattern);
264
+ const match = extractionContent.match(extractor.pattern);
233
265
  if (match) {
234
- statement = extractor.transform(match, content);
266
+ statement = extractor.transform(match, extractionContent);
235
267
  break;
236
268
  }
237
269
  }
238
270
 
271
+ if (!statement && hasDoubleNegatedAversion) {
272
+ continue;
273
+ }
274
+
239
275
  // Fallback: generic prefix
240
276
  if (!statement) {
241
- statement = fallbackPreferenceStatement(content, mem.frontmatter.category);
277
+ statement = fallbackPreferenceStatement(replacementContent ?? content, mem.frontmatter.category);
242
278
  }
243
279
 
244
280
  // Skip if statement is too short or too generic
245
- if (statement.length < 20) continue;
281
+ if (statement.length < 20 && !replacementContent) continue;
246
282
 
247
283
  const keywords = extractKeywords(statement);
248
284