@remnic/core 9.69.23 → 9.69.24

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 (440) hide show
  1. package/dist/abstraction-nodes.js +3 -2
  2. package/dist/access-admin-ops-surface.d.ts +1 -1
  3. package/dist/access-admin-ops-surface.js +53 -53
  4. package/dist/access-authorization-probe.d.ts +1 -1
  5. package/dist/access-authorization-probe.js +54 -54
  6. package/dist/access-boundary.d.ts +1 -1
  7. package/dist/access-boundary.js +53 -53
  8. package/dist/access-citation-namespace.js +3 -3
  9. package/dist/access-cli.js +112 -112
  10. package/dist/access-extraction-force-flush.d.ts +1 -1
  11. package/dist/access-extraction-force-flush.js +53 -53
  12. package/dist/access-http-briefing.d.ts +1 -1
  13. package/dist/access-http-briefing.js +54 -54
  14. package/dist/access-http-lcm-compaction.d.ts +1 -1
  15. package/dist/access-http-lifecycle-flush.d.ts +1 -1
  16. package/dist/access-http-offline-stream.d.ts +1 -1
  17. package/dist/access-http-query.js +55 -55
  18. package/dist/access-http.d.ts +2 -2
  19. package/dist/access-http.js +72 -72
  20. package/dist/access-identity-continuity-surface.js +53 -53
  21. package/dist/access-lcm-surface.d.ts +1 -1
  22. package/dist/access-lcm-surface.js +53 -53
  23. package/dist/access-mcp.d.ts +1 -1
  24. package/dist/access-mcp.js +64 -64
  25. package/dist/access-namespace-preflight.js +53 -53
  26. package/dist/access-observe-write-surface.d.ts +1 -1
  27. package/dist/access-observe-write-surface.js +53 -53
  28. package/dist/access-offline-manifest.js +10 -10
  29. package/dist/access-operations-batch.js +58 -58
  30. package/dist/access-operations.d.ts +6 -6
  31. package/dist/access-operations.js +63 -63
  32. package/dist/access-recall-concurrency.d.ts +1 -1
  33. package/dist/access-recall-concurrency.js +53 -53
  34. package/dist/access-recall-response.d.ts +1 -1
  35. package/dist/access-recall-response.js +53 -53
  36. package/dist/access-recall-surface.d.ts +1 -1
  37. package/dist/access-recall-surface.js +53 -53
  38. package/dist/access-schema.d.ts +91 -91
  39. package/dist/access-schema.js +6 -5
  40. package/dist/access-service-helpers.d.ts +1 -1
  41. package/dist/access-service.d.ts +1 -1
  42. package/dist/access-service.js +53 -53
  43. package/dist/access-surface-catalog.d.ts +1 -1
  44. package/dist/access-surface-catalog.js +55 -55
  45. package/dist/active-recall.js +12 -11
  46. package/dist/active-recall.js.map +1 -1
  47. package/dist/{auto-sync-TTIEWJ5X.js → auto-sync-WNGG2GC2.js} +7 -7
  48. package/dist/briefing.js +20 -20
  49. package/dist/buffer.js +9 -9
  50. package/dist/calibration.js +2 -1
  51. package/dist/calibration.js.map +1 -1
  52. package/dist/{capsule-merge-CU6QJBSV.js → capsule-merge-IPG4IOFP.js} +4 -4
  53. package/dist/causal-behavior.js +4 -3
  54. package/dist/causal-behavior.js.map +1 -1
  55. package/dist/causal-chain.js +4 -3
  56. package/dist/causal-consolidation.js +25 -25
  57. package/dist/causal-retrieval.js +4 -3
  58. package/dist/causal-retrieval.js.map +1 -1
  59. package/dist/causal-trajectory-graph.js +2 -1
  60. package/dist/causal-trajectory-graph.js.map +1 -1
  61. package/dist/causal-trajectory.js +3 -2
  62. package/dist/{chunk-5RWHODVF.js → chunk-27QVNSQ3.js} +2 -2
  63. package/dist/{chunk-2MX7RU7B.js → chunk-2EKJDQZB.js} +2 -2
  64. package/dist/{chunk-XLRM6PPI.js → chunk-2IOHTUP3.js} +4 -4
  65. package/dist/{chunk-ZGQDTD5T.js → chunk-2ITE4C2Z.js} +2 -2
  66. package/dist/{chunk-O5ZR7SXV.js → chunk-2SGLMP2E.js} +2 -2
  67. package/dist/{chunk-FYWLSFFS.js → chunk-2Z4GS5E6.js} +2 -2
  68. package/dist/{chunk-WELP4CG6.js → chunk-37KUQPX4.js} +6 -6
  69. package/dist/{chunk-DDQQY2E3.js → chunk-3BTFBQLO.js} +7 -7
  70. package/dist/chunk-3BTFBQLO.js.map +1 -0
  71. package/dist/{chunk-UR6PBX2J.js → chunk-3K7V3HE6.js} +35 -60
  72. package/dist/chunk-3K7V3HE6.js.map +1 -0
  73. package/dist/{chunk-MRSLR6TB.js → chunk-3QQTXYZ6.js} +2 -2
  74. package/dist/{chunk-DJUKBGAD.js → chunk-46EST7JO.js} +5 -5
  75. package/dist/chunk-46EST7JO.js.map +1 -0
  76. package/dist/{chunk-CI6C33EO.js → chunk-46ZPIGWI.js} +3 -3
  77. package/dist/{chunk-HTIIXNJQ.js → chunk-4FIH6MPS.js} +6 -3
  78. package/dist/chunk-4FIH6MPS.js.map +1 -0
  79. package/dist/{chunk-MCA2X4WH.js → chunk-4IHBN6WU.js} +2 -2
  80. package/dist/{chunk-W7IGLX4G.js → chunk-4O6WRBGE.js} +7 -7
  81. package/dist/chunk-4O6WRBGE.js.map +1 -0
  82. package/dist/{chunk-TOZCM7WN.js → chunk-4TKJGOCJ.js} +2 -2
  83. package/dist/{chunk-3ADRFFRO.js → chunk-54WHLA65.js} +4 -4
  84. package/dist/{chunk-Z2N2AHEM.js → chunk-56Y6EKZN.js} +2 -2
  85. package/dist/{chunk-2H2N5UQW.js → chunk-5ATKSPEQ.js} +2 -2
  86. package/dist/{chunk-MSOXFXCA.js → chunk-5FAGCOZD.js} +5 -5
  87. package/dist/chunk-5FAGCOZD.js.map +1 -0
  88. package/dist/{chunk-ZVZHG7AI.js → chunk-5UBH37SL.js} +3 -3
  89. package/dist/{chunk-YZYZ2BEU.js → chunk-66OJSCI6.js} +2 -2
  90. package/dist/{chunk-HNPE66LB.js → chunk-6CVNSDCZ.js} +4 -4
  91. package/dist/{chunk-ERVJFFTR.js → chunk-6NXSYYGP.js} +2 -2
  92. package/dist/{chunk-2HIJHXB3.js → chunk-6WHJ2EAB.js} +2 -2
  93. package/dist/{chunk-34VTBPNE.js → chunk-6XL73HQ4.js} +4 -4
  94. package/dist/{chunk-YK3UIF7X.js → chunk-AQ7SYDVO.js} +2 -2
  95. package/dist/{chunk-DSCCM66R.js → chunk-B3O3IRZN.js} +2 -2
  96. package/dist/{chunk-P77QX3ID.js → chunk-B6O2YLUR.js} +21 -20
  97. package/dist/chunk-B6O2YLUR.js.map +1 -0
  98. package/dist/{chunk-N37X5RU7.js → chunk-BD7JTBYP.js} +2 -2
  99. package/dist/{chunk-VO43BJ2F.js → chunk-BLJWYCNO.js} +5 -5
  100. package/dist/{chunk-ACPCA4NO.js → chunk-BMWN7B3Y.js} +6 -6
  101. package/dist/chunk-BMWN7B3Y.js.map +1 -0
  102. package/dist/{chunk-HSKSVY3Q.js → chunk-C553ZTLF.js} +15 -15
  103. package/dist/{chunk-GCASGYIO.js → chunk-C7HJ3NEI.js} +2 -2
  104. package/dist/{chunk-WVGXCBOC.js → chunk-D5F7TKMH.js} +2 -2
  105. package/dist/{chunk-UFT2XNBW.js → chunk-DGS34QSY.js} +2 -2
  106. package/dist/{chunk-VAOL3SOT.js → chunk-DZD3WGCD.js} +4 -4
  107. package/dist/{chunk-KHMS2FQS.js → chunk-E2P7TZTF.js} +2 -2
  108. package/dist/{chunk-6FC3IZ26.js → chunk-EBA5DA77.js} +2 -2
  109. package/dist/{chunk-E6EANYLD.js → chunk-EOQ6FSQP.js} +2 -2
  110. package/dist/{chunk-7RPPCA26.js → chunk-FVOP3NT7.js} +2 -2
  111. package/dist/{chunk-NRLELHAY.js → chunk-G7NYVKD6.js} +2 -2
  112. package/dist/{chunk-QY34X2QJ.js → chunk-GHTSNGBZ.js} +2 -2
  113. package/dist/{chunk-SLIOMMPF.js → chunk-H272ZPQ3.js} +5 -5
  114. package/dist/{chunk-ZZBQNQS6.js → chunk-H3TKENU4.js} +2 -2
  115. package/dist/{chunk-5OPNUUBX.js → chunk-H4SEGIZY.js} +2 -2
  116. package/dist/{chunk-F2HMDGLC.js → chunk-H54VWRPS.js} +13 -13
  117. package/dist/{chunk-HTP6XRUI.js → chunk-HM7RHKS4.js} +2 -2
  118. package/dist/{chunk-O7H3P2SJ.js → chunk-HWLIMQE2.js} +2 -2
  119. package/dist/{chunk-62WZDHTW.js → chunk-ICKJ52PE.js} +33 -33
  120. package/dist/chunk-ICKJ52PE.js.map +1 -0
  121. package/dist/{chunk-I3FDDCY3.js → chunk-JEC4DVM3.js} +8 -8
  122. package/dist/chunk-JEC4DVM3.js.map +1 -0
  123. package/dist/{chunk-ET2CNMLD.js → chunk-JN72EPOE.js} +2 -2
  124. package/dist/{chunk-E7UQOS4C.js → chunk-JPKK466T.js} +2 -2
  125. package/dist/{chunk-JCCWJHOP.js → chunk-JYZSRNR7.js} +2 -2
  126. package/dist/{chunk-7IUESBLV.js → chunk-K7724CH2.js} +2 -2
  127. package/dist/{chunk-UK7HXNNJ.js → chunk-KAXCYM66.js} +3 -3
  128. package/dist/{chunk-7XVP4P4O.js → chunk-KB2G2I6Q.js} +3 -3
  129. package/dist/{chunk-K7LTRJZU.js → chunk-KEF46KL2.js} +2 -2
  130. package/dist/{chunk-5UZXUTVO.js → chunk-KNA3BXXL.js} +6 -2
  131. package/dist/chunk-KNA3BXXL.js.map +1 -0
  132. package/dist/{chunk-JYYTWCPU.js → chunk-KTWG7CNY.js} +6 -6
  133. package/dist/{chunk-XTYDEO7M.js → chunk-L7Z57SID.js} +2 -2
  134. package/dist/{chunk-EYMPUXAN.js → chunk-LO4UKPKX.js} +3 -3
  135. package/dist/{chunk-LDWIPYJ6.js → chunk-LS2FHUML.js} +3 -3
  136. package/dist/{chunk-GDB4J2H3.js → chunk-MPC7TYTZ.js} +2 -2
  137. package/dist/{chunk-2GF27PGH.js → chunk-MRPOZBJC.js} +3 -3
  138. package/dist/{chunk-7OLKAQMG.js → chunk-MWN6QEI2.js} +2 -2
  139. package/dist/{chunk-J62HG52Z.js → chunk-MY5EDR46.js} +4 -4
  140. package/dist/{chunk-IZRMWPGS.js → chunk-N3ZOP7KC.js} +2 -2
  141. package/dist/{chunk-N6A2RP5S.js → chunk-NB3LRY4T.js} +3 -3
  142. package/dist/{chunk-4N5BIR2U.js → chunk-ND6IQGSZ.js} +2 -2
  143. package/dist/{chunk-NOB2T2FC.js → chunk-NHLLKEKK.js} +2 -2
  144. package/dist/{chunk-WW6B7NQJ.js → chunk-NLYVH66G.js} +6 -6
  145. package/dist/chunk-NLYVH66G.js.map +1 -0
  146. package/dist/{chunk-M5CQNOQN.js → chunk-O6ZNNVSP.js} +2 -2
  147. package/dist/{chunk-NNBZS3DY.js → chunk-OB3XMWX5.js} +2 -2
  148. package/dist/{chunk-TXJNRGMI.js → chunk-OEYZXDQI.js} +6 -6
  149. package/dist/chunk-OEYZXDQI.js.map +1 -0
  150. package/dist/{chunk-SIBVIP2Y.js → chunk-PAZY2ZKP.js} +2 -2
  151. package/dist/{chunk-LXESHEBP.js → chunk-PX4UMA5Z.js} +2 -2
  152. package/dist/{chunk-4KNRKJXQ.js → chunk-QOOBICJF.js} +5 -5
  153. package/dist/chunk-QOOBICJF.js.map +1 -0
  154. package/dist/{chunk-NNZFPYYX.js → chunk-R7QY5ZVB.js} +2 -2
  155. package/dist/{chunk-WTRTFIIN.js → chunk-R7RTXEYG.js} +2 -2
  156. package/dist/{chunk-XRBJ5R3P.js → chunk-RBCQVOVJ.js} +3 -3
  157. package/dist/{chunk-WFZNT4KB.js → chunk-RC5DXXWC.js} +2 -2
  158. package/dist/{chunk-OH7LZHGJ.js → chunk-RJYJ7KR7.js} +52 -52
  159. package/dist/{chunk-OH7LZHGJ.js.map → chunk-RJYJ7KR7.js.map} +1 -1
  160. package/dist/{chunk-5QZR2RA3.js → chunk-ROBHL3GL.js} +2 -2
  161. package/dist/{chunk-6PST2SFW.js → chunk-SCXURCVT.js} +3 -3
  162. package/dist/{chunk-AYG7ML7O.js → chunk-SJDQ5RSN.js} +3 -3
  163. package/dist/{chunk-3ZBLKIHJ.js → chunk-SMWTZLHE.js} +51 -41
  164. package/dist/{chunk-3ZBLKIHJ.js.map → chunk-SMWTZLHE.js.map} +1 -1
  165. package/dist/{chunk-IQXDSKTL.js → chunk-SVXJLDDC.js} +6 -6
  166. package/dist/{chunk-SEF4IOFE.js → chunk-SWIKABKI.js} +2 -2
  167. package/dist/{chunk-ZJABRLCZ.js → chunk-TBXAY2SS.js} +4 -4
  168. package/dist/{chunk-GIC6BASP.js → chunk-TNSCIPBQ.js} +2 -2
  169. package/dist/{chunk-ZMDMHSV2.js → chunk-TVEONGBU.js} +2 -2
  170. package/dist/{chunk-4FSEZRGK.js → chunk-TWF35IC6.js} +2 -2
  171. package/dist/{chunk-LS2SGMQE.js → chunk-U6N5IBVY.js} +2 -2
  172. package/dist/{chunk-62YW6OYI.js → chunk-UCKYTA2T.js} +3 -3
  173. package/dist/{chunk-YFCHNOGJ.js → chunk-UNNPNBR2.js} +9 -9
  174. package/dist/{chunk-Z2M7F4QM.js → chunk-VVX5PZFS.js} +3 -3
  175. package/dist/{chunk-NTYLZXDX.js → chunk-VYCOJKSX.js} +2 -2
  176. package/dist/{chunk-UICSQESY.js → chunk-W24T5YMW.js} +2 -2
  177. package/dist/{chunk-HDQUQBPW.js → chunk-W3K3HITK.js} +2 -2
  178. package/dist/{chunk-GDASG7NC.js → chunk-W4F3C7N7.js} +2 -2
  179. package/dist/{chunk-YBLZFNIQ.js → chunk-WJHGDE7X.js} +2 -2
  180. package/dist/{chunk-ZBPXG5PJ.js → chunk-WMLEPWMO.js} +9 -9
  181. package/dist/chunk-WMLEPWMO.js.map +1 -0
  182. package/dist/{chunk-4F24PHNX.js → chunk-WQZZDN5M.js} +2 -2
  183. package/dist/{chunk-CDZEUCV7.js → chunk-X5K5TAQZ.js} +4 -4
  184. package/dist/{chunk-5AUODSOQ.js → chunk-XM24CDZX.js} +3 -3
  185. package/dist/{chunk-6VML2LII.js → chunk-XOVKXJEP.js} +3 -3
  186. package/dist/{chunk-OU5TIWDQ.js → chunk-XSGUMQQQ.js} +12 -12
  187. package/dist/{chunk-7CFVBWDC.js → chunk-XUE46UYW.js} +3 -3
  188. package/dist/{chunk-DJORULH3.js → chunk-YRLHEEQT.js} +2 -2
  189. package/dist/{chunk-YRWDPE32.js → chunk-Z3O53WZR.js} +2 -2
  190. package/dist/{chunk-CSY5DA7O.js → chunk-Z6COGHHN.js} +2 -2
  191. package/dist/{chunk-OYR3IPHD.js → chunk-ZIW5JVRM.js} +2 -2
  192. package/dist/{cli-B_YwqoIr.d.ts → cli-DD0P-lu8.d.ts} +1 -1
  193. package/dist/cli.d.ts +2 -2
  194. package/dist/cli.js +94 -94
  195. package/dist/coding/export-okf-codegraph.js +21 -21
  196. package/dist/coding/pre-action-gate.js +4 -3
  197. package/dist/commitment-ledger.js +3 -2
  198. package/dist/compounding/engine.js +21 -21
  199. package/dist/config.js +12 -11
  200. package/dist/connectors/codex-materialize-runner.js +21 -21
  201. package/dist/connectors/codex-materialize.js +3 -3
  202. package/dist/connectors/index.js +21 -21
  203. package/dist/consolidation-provenance-check.js +4 -4
  204. package/dist/consolidation-undo.js +3 -3
  205. package/dist/contradiction/index.js +7 -7
  206. package/dist/convergence-refresh.js +22 -22
  207. package/dist/corpus-watermark.js +22 -22
  208. package/dist/cue-anchors.js +4 -3
  209. package/dist/deep-recall-http-glue.d.ts +1 -1
  210. package/dist/deep-recall-http-glue.js +7 -6
  211. package/dist/deep-recall-mcp-tools.d.ts +1 -1
  212. package/dist/entity-retrieval.js +20 -20
  213. package/dist/eval-trajectory-store.js +4 -3
  214. package/dist/eval-trajectory.js +4 -3
  215. package/dist/evals.js +3 -2
  216. package/dist/explicit-capture.js +8 -8
  217. package/dist/external-wiki-access.d.ts +1 -1
  218. package/dist/external-wiki-access.js +54 -54
  219. package/dist/external-wiki-mcp-tools.d.ts +1 -1
  220. package/dist/extraction.js +25 -25
  221. package/dist/{first-start-migration-KHIMCBIC.js → first-start-migration-RC345GPL.js} +6 -5
  222. package/dist/{first-start-migration-KHIMCBIC.js.map → first-start-migration-RC345GPL.js.map} +1 -1
  223. package/dist/{graph-edge-decay-CJW4OT2X.js → graph-edge-decay-MKIRZ762.js} +5 -4
  224. package/dist/graph-jsonl.js +3 -2
  225. package/dist/graph-snapshot.js +3 -2
  226. package/dist/graph.js +2 -1
  227. package/dist/harmonic-construction.js +5 -4
  228. package/dist/harmonic-retrieval.js +5 -4
  229. package/dist/index.d.ts +693 -681
  230. package/dist/index.js +114 -112
  231. package/dist/json-store.js +2 -1
  232. package/dist/live-connectors-runner.js +3 -2
  233. package/dist/location/index.js +23 -23
  234. package/dist/maintenance/memory-governance.js +20 -20
  235. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +20 -20
  236. package/dist/maintenance/rebuild-memory-projection.js +21 -21
  237. package/dist/mcp-memory-inspector-app.d.ts +1 -1
  238. package/dist/memory-projection-mutations.js +3 -3
  239. package/dist/memory-subject-cli.d.ts +1 -1
  240. package/dist/memory-subject.d.ts +1 -1
  241. package/dist/memory-subject.js +4 -4
  242. package/dist/namespaces/migrate.js +21 -21
  243. package/dist/namespaces/search.js +8 -8
  244. package/dist/namespaces/storage.js +20 -20
  245. package/dist/objective-state-writers.js +4 -3
  246. package/dist/objective-state.js +3 -2
  247. package/dist/offline-sync-file-io.js +4 -3
  248. package/dist/offline-sync-impression-drain.js +5 -5
  249. package/dist/offline-sync.js +5 -4
  250. package/dist/operator-doctor-corpus.js +23 -23
  251. package/dist/operator-toolkit.js +38 -38
  252. package/dist/orchestration/maintenance.js +29 -29
  253. package/dist/orchestrator.js +112 -112
  254. package/dist/page-versioning.js +3 -3
  255. package/dist/{public-http-D6d4W8x-.d.ts → public-http-C4i8Opxc.d.ts} +1 -1
  256. package/dist/{purge-OP6BEDFY.js → purge-TZKRE6ZQ.js} +5 -5
  257. package/dist/purge-TZKRE6ZQ.js.map +1 -0
  258. package/dist/recall-state.js +3 -3
  259. package/dist/reconcile/manifest.js +4 -4
  260. package/dist/{resolution-U5O4QANY.js → resolution-VKATP2HT.js} +8 -8
  261. package/dist/resume-bundles.js +16 -15
  262. package/dist/salvage-envelope.js +6 -6
  263. package/dist/schemas.d.ts +176 -176
  264. package/dist/search/document-scanner.js +3 -3
  265. package/dist/search/factory.js +7 -7
  266. package/dist/search/index.js +7 -7
  267. package/dist/search/lancedb-backend.js +4 -4
  268. package/dist/search/meilisearch-backend.js +4 -4
  269. package/dist/search/orama-backend.js +4 -4
  270. package/dist/secure-store/index.js +3 -3
  271. package/dist/semantic-consolidation.js +22 -22
  272. package/dist/semantic-rule-promotion.js +20 -20
  273. package/dist/semantic-rule-verifier.js +20 -20
  274. package/dist/shared-context/manager.d.ts +6 -6
  275. package/dist/source-agent-qualifier.js +24 -24
  276. package/dist/standup/build.js +20 -20
  277. package/dist/storage.js +19 -19
  278. package/dist/subject-config.js +5 -5
  279. package/dist/support-passport/index.d.ts +4 -4
  280. package/dist/support-passport/index.js +56 -56
  281. package/dist/{tier-stats-2TOW3QNL.js → tier-stats-KA6OZX2C.js} +6 -5
  282. package/dist/{tier-stats-2TOW3QNL.js.map → tier-stats-KA6OZX2C.js.map} +1 -1
  283. package/dist/transfer/capsule-import.js +4 -4
  284. package/dist/transfer/export-okf.js +21 -21
  285. package/dist/transfer/types.d.ts +78 -78
  286. package/dist/trust-zones.js +3 -2
  287. package/dist/utility-learner.js +4 -3
  288. package/dist/utility-runtime.js +5 -4
  289. package/dist/utility-telemetry.js +3 -2
  290. package/dist/verified-recall.js +20 -20
  291. package/dist/who-knows-cli.d.ts +1 -1
  292. package/dist/who-knows-cli.js +21 -21
  293. package/dist/who-knows.d.ts +1 -1
  294. package/dist/who-knows.js +20 -20
  295. package/dist/work/board.js +3 -3
  296. package/dist/work/storage.js +2 -2
  297. package/dist/work-product-ledger.js +3 -2
  298. package/dist/write-envelope.js +5 -5
  299. package/package.json +2 -2
  300. package/src/abstraction-nodes.ts +1 -4
  301. package/src/binary-lifecycle/backend.ts +2 -1
  302. package/src/connectors/live/github.ts +10 -17
  303. package/src/connectors/live/gmail.ts +8 -19
  304. package/src/connectors/live/google-drive.ts +6 -13
  305. package/src/connectors/live/notion.ts +11 -21
  306. package/src/cue-anchors.ts +1 -6
  307. package/src/graph.ts +2 -4
  308. package/src/json-store.ts +17 -20
  309. package/src/live-connectors-runner.ts +2 -1
  310. package/src/location/store.ts +1 -4
  311. package/src/maintenance/purge.ts +2 -5
  312. package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +3 -6
  313. package/src/maintenance/rebuild-memory-projection.ts +2 -5
  314. package/src/namespaces/catalog.ts +1 -9
  315. package/src/offline-sync-file-io.test.ts +39 -0
  316. package/src/offline-sync-file-io.ts +3 -7
  317. package/src/procedural/procedure-miner.ts +1 -9
  318. package/src/search/document-scanner.ts +3 -6
  319. package/src/semantic-rule-promotion.ts +1 -4
  320. package/src/utils/errno.test.ts +31 -0
  321. package/src/utils/errno.ts +5 -0
  322. package/src/wearables/index.ts +1 -0
  323. package/src/wearables/registry.ts +23 -0
  324. package/dist/chunk-4KNRKJXQ.js.map +0 -1
  325. package/dist/chunk-5UZXUTVO.js.map +0 -1
  326. package/dist/chunk-62WZDHTW.js.map +0 -1
  327. package/dist/chunk-ACPCA4NO.js.map +0 -1
  328. package/dist/chunk-DDQQY2E3.js.map +0 -1
  329. package/dist/chunk-DJUKBGAD.js.map +0 -1
  330. package/dist/chunk-HTIIXNJQ.js.map +0 -1
  331. package/dist/chunk-I3FDDCY3.js.map +0 -1
  332. package/dist/chunk-MSOXFXCA.js.map +0 -1
  333. package/dist/chunk-P77QX3ID.js.map +0 -1
  334. package/dist/chunk-TXJNRGMI.js.map +0 -1
  335. package/dist/chunk-UR6PBX2J.js.map +0 -1
  336. package/dist/chunk-W7IGLX4G.js.map +0 -1
  337. package/dist/chunk-WW6B7NQJ.js.map +0 -1
  338. package/dist/chunk-ZBPXG5PJ.js.map +0 -1
  339. package/dist/purge-OP6BEDFY.js.map +0 -1
  340. package/dist/{access-service-Cv8Rizo0.d.ts → access-service-DWdY9Mlk.d.ts} +64 -64
  341. /package/dist/{auto-sync-TTIEWJ5X.js.map → auto-sync-WNGG2GC2.js.map} +0 -0
  342. /package/dist/{capsule-merge-CU6QJBSV.js.map → capsule-merge-IPG4IOFP.js.map} +0 -0
  343. /package/dist/{chunk-5RWHODVF.js.map → chunk-27QVNSQ3.js.map} +0 -0
  344. /package/dist/{chunk-2MX7RU7B.js.map → chunk-2EKJDQZB.js.map} +0 -0
  345. /package/dist/{chunk-XLRM6PPI.js.map → chunk-2IOHTUP3.js.map} +0 -0
  346. /package/dist/{chunk-ZGQDTD5T.js.map → chunk-2ITE4C2Z.js.map} +0 -0
  347. /package/dist/{chunk-O5ZR7SXV.js.map → chunk-2SGLMP2E.js.map} +0 -0
  348. /package/dist/{chunk-FYWLSFFS.js.map → chunk-2Z4GS5E6.js.map} +0 -0
  349. /package/dist/{chunk-WELP4CG6.js.map → chunk-37KUQPX4.js.map} +0 -0
  350. /package/dist/{chunk-MRSLR6TB.js.map → chunk-3QQTXYZ6.js.map} +0 -0
  351. /package/dist/{chunk-CI6C33EO.js.map → chunk-46ZPIGWI.js.map} +0 -0
  352. /package/dist/{chunk-MCA2X4WH.js.map → chunk-4IHBN6WU.js.map} +0 -0
  353. /package/dist/{chunk-TOZCM7WN.js.map → chunk-4TKJGOCJ.js.map} +0 -0
  354. /package/dist/{chunk-3ADRFFRO.js.map → chunk-54WHLA65.js.map} +0 -0
  355. /package/dist/{chunk-Z2N2AHEM.js.map → chunk-56Y6EKZN.js.map} +0 -0
  356. /package/dist/{chunk-2H2N5UQW.js.map → chunk-5ATKSPEQ.js.map} +0 -0
  357. /package/dist/{chunk-ZVZHG7AI.js.map → chunk-5UBH37SL.js.map} +0 -0
  358. /package/dist/{chunk-YZYZ2BEU.js.map → chunk-66OJSCI6.js.map} +0 -0
  359. /package/dist/{chunk-HNPE66LB.js.map → chunk-6CVNSDCZ.js.map} +0 -0
  360. /package/dist/{chunk-ERVJFFTR.js.map → chunk-6NXSYYGP.js.map} +0 -0
  361. /package/dist/{chunk-2HIJHXB3.js.map → chunk-6WHJ2EAB.js.map} +0 -0
  362. /package/dist/{chunk-34VTBPNE.js.map → chunk-6XL73HQ4.js.map} +0 -0
  363. /package/dist/{chunk-YK3UIF7X.js.map → chunk-AQ7SYDVO.js.map} +0 -0
  364. /package/dist/{chunk-DSCCM66R.js.map → chunk-B3O3IRZN.js.map} +0 -0
  365. /package/dist/{chunk-N37X5RU7.js.map → chunk-BD7JTBYP.js.map} +0 -0
  366. /package/dist/{chunk-VO43BJ2F.js.map → chunk-BLJWYCNO.js.map} +0 -0
  367. /package/dist/{chunk-HSKSVY3Q.js.map → chunk-C553ZTLF.js.map} +0 -0
  368. /package/dist/{chunk-GCASGYIO.js.map → chunk-C7HJ3NEI.js.map} +0 -0
  369. /package/dist/{chunk-WVGXCBOC.js.map → chunk-D5F7TKMH.js.map} +0 -0
  370. /package/dist/{chunk-UFT2XNBW.js.map → chunk-DGS34QSY.js.map} +0 -0
  371. /package/dist/{chunk-VAOL3SOT.js.map → chunk-DZD3WGCD.js.map} +0 -0
  372. /package/dist/{chunk-KHMS2FQS.js.map → chunk-E2P7TZTF.js.map} +0 -0
  373. /package/dist/{chunk-6FC3IZ26.js.map → chunk-EBA5DA77.js.map} +0 -0
  374. /package/dist/{chunk-E6EANYLD.js.map → chunk-EOQ6FSQP.js.map} +0 -0
  375. /package/dist/{chunk-7RPPCA26.js.map → chunk-FVOP3NT7.js.map} +0 -0
  376. /package/dist/{chunk-NRLELHAY.js.map → chunk-G7NYVKD6.js.map} +0 -0
  377. /package/dist/{chunk-QY34X2QJ.js.map → chunk-GHTSNGBZ.js.map} +0 -0
  378. /package/dist/{chunk-SLIOMMPF.js.map → chunk-H272ZPQ3.js.map} +0 -0
  379. /package/dist/{chunk-ZZBQNQS6.js.map → chunk-H3TKENU4.js.map} +0 -0
  380. /package/dist/{chunk-5OPNUUBX.js.map → chunk-H4SEGIZY.js.map} +0 -0
  381. /package/dist/{chunk-F2HMDGLC.js.map → chunk-H54VWRPS.js.map} +0 -0
  382. /package/dist/{chunk-HTP6XRUI.js.map → chunk-HM7RHKS4.js.map} +0 -0
  383. /package/dist/{chunk-O7H3P2SJ.js.map → chunk-HWLIMQE2.js.map} +0 -0
  384. /package/dist/{chunk-ET2CNMLD.js.map → chunk-JN72EPOE.js.map} +0 -0
  385. /package/dist/{chunk-E7UQOS4C.js.map → chunk-JPKK466T.js.map} +0 -0
  386. /package/dist/{chunk-JCCWJHOP.js.map → chunk-JYZSRNR7.js.map} +0 -0
  387. /package/dist/{chunk-7IUESBLV.js.map → chunk-K7724CH2.js.map} +0 -0
  388. /package/dist/{chunk-UK7HXNNJ.js.map → chunk-KAXCYM66.js.map} +0 -0
  389. /package/dist/{chunk-7XVP4P4O.js.map → chunk-KB2G2I6Q.js.map} +0 -0
  390. /package/dist/{chunk-K7LTRJZU.js.map → chunk-KEF46KL2.js.map} +0 -0
  391. /package/dist/{chunk-JYYTWCPU.js.map → chunk-KTWG7CNY.js.map} +0 -0
  392. /package/dist/{chunk-XTYDEO7M.js.map → chunk-L7Z57SID.js.map} +0 -0
  393. /package/dist/{chunk-EYMPUXAN.js.map → chunk-LO4UKPKX.js.map} +0 -0
  394. /package/dist/{chunk-LDWIPYJ6.js.map → chunk-LS2FHUML.js.map} +0 -0
  395. /package/dist/{chunk-GDB4J2H3.js.map → chunk-MPC7TYTZ.js.map} +0 -0
  396. /package/dist/{chunk-2GF27PGH.js.map → chunk-MRPOZBJC.js.map} +0 -0
  397. /package/dist/{chunk-7OLKAQMG.js.map → chunk-MWN6QEI2.js.map} +0 -0
  398. /package/dist/{chunk-J62HG52Z.js.map → chunk-MY5EDR46.js.map} +0 -0
  399. /package/dist/{chunk-IZRMWPGS.js.map → chunk-N3ZOP7KC.js.map} +0 -0
  400. /package/dist/{chunk-N6A2RP5S.js.map → chunk-NB3LRY4T.js.map} +0 -0
  401. /package/dist/{chunk-4N5BIR2U.js.map → chunk-ND6IQGSZ.js.map} +0 -0
  402. /package/dist/{chunk-NOB2T2FC.js.map → chunk-NHLLKEKK.js.map} +0 -0
  403. /package/dist/{chunk-M5CQNOQN.js.map → chunk-O6ZNNVSP.js.map} +0 -0
  404. /package/dist/{chunk-NNBZS3DY.js.map → chunk-OB3XMWX5.js.map} +0 -0
  405. /package/dist/{chunk-SIBVIP2Y.js.map → chunk-PAZY2ZKP.js.map} +0 -0
  406. /package/dist/{chunk-LXESHEBP.js.map → chunk-PX4UMA5Z.js.map} +0 -0
  407. /package/dist/{chunk-NNZFPYYX.js.map → chunk-R7QY5ZVB.js.map} +0 -0
  408. /package/dist/{chunk-WTRTFIIN.js.map → chunk-R7RTXEYG.js.map} +0 -0
  409. /package/dist/{chunk-XRBJ5R3P.js.map → chunk-RBCQVOVJ.js.map} +0 -0
  410. /package/dist/{chunk-WFZNT4KB.js.map → chunk-RC5DXXWC.js.map} +0 -0
  411. /package/dist/{chunk-5QZR2RA3.js.map → chunk-ROBHL3GL.js.map} +0 -0
  412. /package/dist/{chunk-6PST2SFW.js.map → chunk-SCXURCVT.js.map} +0 -0
  413. /package/dist/{chunk-AYG7ML7O.js.map → chunk-SJDQ5RSN.js.map} +0 -0
  414. /package/dist/{chunk-IQXDSKTL.js.map → chunk-SVXJLDDC.js.map} +0 -0
  415. /package/dist/{chunk-SEF4IOFE.js.map → chunk-SWIKABKI.js.map} +0 -0
  416. /package/dist/{chunk-ZJABRLCZ.js.map → chunk-TBXAY2SS.js.map} +0 -0
  417. /package/dist/{chunk-GIC6BASP.js.map → chunk-TNSCIPBQ.js.map} +0 -0
  418. /package/dist/{chunk-ZMDMHSV2.js.map → chunk-TVEONGBU.js.map} +0 -0
  419. /package/dist/{chunk-4FSEZRGK.js.map → chunk-TWF35IC6.js.map} +0 -0
  420. /package/dist/{chunk-LS2SGMQE.js.map → chunk-U6N5IBVY.js.map} +0 -0
  421. /package/dist/{chunk-62YW6OYI.js.map → chunk-UCKYTA2T.js.map} +0 -0
  422. /package/dist/{chunk-YFCHNOGJ.js.map → chunk-UNNPNBR2.js.map} +0 -0
  423. /package/dist/{chunk-Z2M7F4QM.js.map → chunk-VVX5PZFS.js.map} +0 -0
  424. /package/dist/{chunk-NTYLZXDX.js.map → chunk-VYCOJKSX.js.map} +0 -0
  425. /package/dist/{chunk-UICSQESY.js.map → chunk-W24T5YMW.js.map} +0 -0
  426. /package/dist/{chunk-HDQUQBPW.js.map → chunk-W3K3HITK.js.map} +0 -0
  427. /package/dist/{chunk-GDASG7NC.js.map → chunk-W4F3C7N7.js.map} +0 -0
  428. /package/dist/{chunk-YBLZFNIQ.js.map → chunk-WJHGDE7X.js.map} +0 -0
  429. /package/dist/{chunk-4F24PHNX.js.map → chunk-WQZZDN5M.js.map} +0 -0
  430. /package/dist/{chunk-CDZEUCV7.js.map → chunk-X5K5TAQZ.js.map} +0 -0
  431. /package/dist/{chunk-5AUODSOQ.js.map → chunk-XM24CDZX.js.map} +0 -0
  432. /package/dist/{chunk-6VML2LII.js.map → chunk-XOVKXJEP.js.map} +0 -0
  433. /package/dist/{chunk-OU5TIWDQ.js.map → chunk-XSGUMQQQ.js.map} +0 -0
  434. /package/dist/{chunk-7CFVBWDC.js.map → chunk-XUE46UYW.js.map} +0 -0
  435. /package/dist/{chunk-DJORULH3.js.map → chunk-YRLHEEQT.js.map} +0 -0
  436. /package/dist/{chunk-YRWDPE32.js.map → chunk-Z3O53WZR.js.map} +0 -0
  437. /package/dist/{chunk-CSY5DA7O.js.map → chunk-Z6COGHHN.js.map} +0 -0
  438. /package/dist/{chunk-OYR3IPHD.js.map → chunk-ZIW5JVRM.js.map} +0 -0
  439. /package/dist/{graph-edge-decay-CJW4OT2X.js.map → graph-edge-decay-MKIRZ762.js.map} +0 -0
  440. /package/dist/{resolution-U5O4QANY.js.map → resolution-VKATP2HT.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/active-recall.ts"],"sourcesContent":["import { appendFile, mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { DEFAULT_REASONING_MODEL } from \"./config.js\";\nimport { collapseWhitespace, truncateCodePointSafe } from \"./whitespace.js\";\nimport type {\n ActiveRecallChatType,\n ActiveRecallModelFallbackPolicy,\n ActiveRecallPromptStyle,\n ActiveRecallQueryMode,\n ActiveRecallThinking,\n} from \"./types.js\";\n\nexport interface ActiveRecallTurn {\n role: \"user\" | \"assistant\";\n content: string;\n}\n\nexport interface ActiveRecallInput {\n sessionKey: string;\n agentId: string;\n chatType: ActiveRecallChatType;\n recentTurns: ActiveRecallTurn[];\n currentMessage: string;\n}\n\nexport interface ActiveRecallConfig {\n enabled: boolean;\n agents: string[] | null;\n allowedChatTypes: ActiveRecallChatType[];\n queryMode: ActiveRecallQueryMode;\n promptStyle: ActiveRecallPromptStyle;\n customInstruction: string | null;\n promptReplacement: string | null;\n promptAppend: string | null;\n maxSummaryChars: number;\n recentUserTurns: number;\n recentAssistantTurns: number;\n recentUserChars: number;\n recentAssistantChars: number;\n thinking: ActiveRecallThinking;\n timeoutMs: number;\n cacheTtlMs: number;\n persistTranscripts: boolean;\n transcriptDir: string;\n entityGraphDepth: number;\n includeCausalTrajectories: boolean;\n includeDaySummary: boolean;\n attachRecallExplain: boolean;\n modelOverride: string | null;\n modelFallbackPolicy: ActiveRecallModelFallbackPolicy;\n}\n\nexport interface ActiveRecallResult {\n summary: string | null;\n citations: Array<{ memoryId: string; relevance: number }>;\n latencyMs: number;\n cacheHit: boolean;\n modelUsed: string;\n transcriptPath: string | null;\n}\n\nexport interface ActiveRecallDependencies {\n recall(query: string, sessionKey: string): Promise<string | null>;\n getLastRecallSnapshot?(sessionKey: string): { memoryIds?: string[] } | null;\n walkEntityGraph?(params: {\n sessionKey: string;\n query: string;\n depth: number;\n }): Promise<string[]>;\n loadCausalTrajectories?(params: {\n sessionKey: string;\n query: string;\n }): Promise<string[]>;\n loadDaySummary?(sessionKey: string): Promise<string | null>;\n explainLastRecall?(sessionKey: string): Promise<string | null>;\n generateSummary?(params: {\n prompt: string;\n sessionKey: string;\n agentId: string;\n model: string;\n timeoutMs: number;\n thinking: ActiveRecallThinking;\n fallbackPolicy: ActiveRecallModelFallbackPolicy;\n }): Promise<{ text: string | null; modelUsed?: string; cacheHit?: boolean }>;\n now?: () => number;\n}\n\ninterface CachedRecallResult {\n expiresAt: number;\n value: ActiveRecallResult;\n}\n\ninterface ActiveRecallTurnWithIndex {\n index: number;\n role: ActiveRecallTurn[\"role\"];\n content: string;\n}\n\nconst ACTIVE_RECALL_CACHE_MAX_ENTRIES = 256;\n\nconst NONE_SET = new Set([\n \"\",\n \"none\",\n \"no_reply\",\n \"nothing useful\",\n \"no relevant memory\",\n \"timeout\",\n \"[]\",\n \"{}\",\n \"null\",\n \"n/a\",\n]);\n\nconst STYLE_INSTRUCTIONS: Record<ActiveRecallPromptStyle, string> = {\n balanced: \"Summarize the most relevant memory context in a compact, neutral way.\",\n strict: \"Only include memory that is directly supported by the retrieved context.\",\n contextual: \"Prefer concise context that helps the next reply stay grounded in recent work.\",\n \"recall-heavy\": \"Bias toward richer recall coverage when multiple retrieved items reinforce each other.\",\n \"precision-heavy\": \"Bias toward precision. Omit anything uncertain or weakly supported.\",\n \"preference-only\": \"Only surface user preference or operating-style memory when present.\",\n};\n\nfunction cloneRecallResult(value: ActiveRecallResult): ActiveRecallResult {\n return {\n ...value,\n citations: [...value.citations],\n };\n}\n\nfunction buildCacheKey(input: ActiveRecallInput, config: ActiveRecallConfig, queryBundle: string): string {\n return JSON.stringify({\n sessionKey: input.sessionKey,\n agentId: input.agentId,\n queryMode: config.queryMode,\n promptStyle: config.promptStyle,\n customInstruction: config.customInstruction,\n promptReplacement: config.promptReplacement,\n promptAppend: config.promptAppend,\n maxSummaryChars: config.maxSummaryChars,\n entityGraphDepth: config.entityGraphDepth,\n includeCausalTrajectories: config.includeCausalTrajectories,\n includeDaySummary: config.includeDaySummary,\n attachRecallExplain: config.attachRecallExplain,\n modelOverride: config.modelOverride,\n modelFallbackPolicy: config.modelFallbackPolicy,\n thinking: config.thinking,\n queryBundle,\n });\n}\n\nfunction pruneExpiredCache(\n cache: Map<string, CachedRecallResult>,\n currentTime: number,\n): void {\n for (const [key, entry] of cache.entries()) {\n if (entry.expiresAt <= currentTime) {\n cache.delete(key);\n }\n }\n}\n\nfunction enforceCacheLimit(cache: Map<string, CachedRecallResult>): void {\n while (cache.size > ACTIVE_RECALL_CACHE_MAX_ENTRIES) {\n const oldestKey = cache.keys().next().value;\n if (typeof oldestKey !== \"string\") {\n break;\n }\n cache.delete(oldestKey);\n }\n}\n\nfunction cropTurns(\n turns: ActiveRecallTurn[],\n role: \"user\" | \"assistant\",\n maxTurns: number,\n maxChars: number,\n): ActiveRecallTurnWithIndex[] {\n if (maxTurns <= 0) {\n return [];\n }\n\n const selected: ActiveRecallTurnWithIndex[] = [];\n for (let index = turns.length - 1; index >= 0 && selected.length < maxTurns; index -= 1) {\n const turn = turns[index];\n if (turn?.role === role) {\n selected.push({\n index,\n role: turn.role,\n content: collapseWhitespace(truncateCodePointSafe(turn.content, maxChars)),\n });\n }\n }\n\n return selected.reverse();\n}\n\nfunction mergeChronologicalTurns(\n userTurns: ActiveRecallTurnWithIndex[],\n assistantTurns: ActiveRecallTurnWithIndex[],\n): ActiveRecallTurnWithIndex[] {\n return [...userTurns, ...assistantTurns]\n .sort((left, right) => left.index - right.index)\n .filter((value) => value.content.length > 0);\n}\n\nexport function buildActiveRecallQueryBundle(\n input: ActiveRecallInput,\n config: ActiveRecallConfig,\n): string {\n if (config.queryMode === \"message\") {\n return collapseWhitespace(input.currentMessage);\n }\n\n const userTurns = cropTurns(\n input.recentTurns,\n \"user\",\n config.recentUserTurns,\n config.recentUserChars,\n );\n const assistantTurns = cropTurns(\n input.recentTurns,\n \"assistant\",\n config.recentAssistantTurns,\n config.recentAssistantChars,\n );\n const mergedTurns = mergeChronologicalTurns(userTurns, assistantTurns);\n\n const parts = [\n ...mergedTurns.map((turn) => `${turn.role}: ${turn.content}`),\n ];\n\n if (config.queryMode === \"full\") {\n return [...parts, `current: ${collapseWhitespace(input.currentMessage)}`]\n .filter((value) => value.trim().length > 0)\n .join(\"\\n\");\n }\n\n return [`current: ${collapseWhitespace(input.currentMessage)}`, ...parts]\n .filter((value) => value.trim().length > 0)\n .join(\"\\n\");\n}\n\nexport function normalizeActiveRecallSummary(value: string | null, maxChars: number): string | null {\n if (value == null) return null;\n const compact = collapseWhitespace(value);\n if (NONE_SET.has(compact.toLowerCase())) return null;\n return truncateCodePointSafe(compact, maxChars);\n}\n\nfunction sanitizeTranscriptPathSegment(value: string): string {\n const normalized = collapseWhitespace(value);\n return encodeURIComponent(normalized.length > 0 ? normalized : \"unknown\").replaceAll(\n \".\",\n \"%2E\",\n );\n}\n\nexport function buildActiveRecallPrompt(params: {\n config: ActiveRecallConfig;\n queryBundle: string;\n recallContext: string | null;\n graphContext: string[];\n causalContext: string[];\n daySummary: string | null;\n recallExplain: string | null;\n}): string {\n const promptReplacement = params.config.promptReplacement?.trim();\n if (promptReplacement) {\n return promptReplacement;\n }\n\n const sections = [\n params.config.customInstruction?.trim() || STYLE_INSTRUCTIONS[params.config.promptStyle],\n `Query bundle:\\n${params.queryBundle}`,\n params.recallContext ? `Retrieved memory:\\n${params.recallContext}` : null,\n params.graphContext.length > 0 ? `Entity graph:\\n${params.graphContext.join(\"\\n\")}` : null,\n params.causalContext.length > 0 ? `Causal trajectories:\\n${params.causalContext.join(\"\\n\")}` : null,\n params.daySummary ? `Day summary:\\n${params.daySummary}` : null,\n params.recallExplain ? `Recall explain:\\n${params.recallExplain}` : null,\n params.config.promptAppend?.trim() || null,\n \"Return either NONE or a compact summary grounded only in the supplied context.\",\n ];\n return sections.filter((value): value is string => !!value && value.trim().length > 0).join(\"\\n\\n\");\n}\n\nasync function appendActiveRecallTranscript(\n transcriptRoot: string,\n input: ActiveRecallInput,\n config: ActiveRecallConfig,\n result: ActiveRecallResult,\n queryBundle: string,\n): Promise<string> {\n const date = new Date().toISOString().slice(0, 10);\n const filePath = path.join(\n transcriptRoot,\n \"agents\",\n sanitizeTranscriptPathSegment(input.agentId),\n date,\n `${sanitizeTranscriptPathSegment(input.sessionKey)}.jsonl`,\n );\n await mkdir(path.dirname(filePath), { recursive: true });\n await appendFile(\n filePath,\n `${JSON.stringify({\n ts: new Date().toISOString(),\n sessionKey: input.sessionKey,\n agentId: input.agentId,\n queryMode: config.queryMode,\n promptStyle: config.promptStyle,\n queryBundle,\n summary: result.summary,\n citations: result.citations,\n latencyMs: result.latencyMs,\n cacheHit: result.cacheHit,\n modelUsed: result.modelUsed,\n })}\\n`,\n \"utf8\",\n );\n return filePath;\n}\n\nexport function createActiveRecallEngine(\n deps: ActiveRecallDependencies,\n config: ActiveRecallConfig,\n) {\n const cache = new Map<string, CachedRecallResult>();\n const now = deps.now ?? (() => Date.now());\n\n return {\n async run(input: ActiveRecallInput): Promise<ActiveRecallResult> {\n if (!config.enabled) {\n return {\n summary: null,\n citations: [],\n latencyMs: 0,\n cacheHit: false,\n modelUsed: config.modelOverride ?? \"disabled\",\n transcriptPath: null,\n };\n }\n if (config.agents && !config.agents.includes(input.agentId)) {\n return {\n summary: null,\n citations: [],\n latencyMs: 0,\n cacheHit: false,\n modelUsed: config.modelOverride ?? \"filtered\",\n transcriptPath: null,\n };\n }\n if (!config.allowedChatTypes.includes(input.chatType)) {\n return {\n summary: null,\n citations: [],\n latencyMs: 0,\n cacheHit: false,\n modelUsed: config.modelOverride ?? \"filtered\",\n transcriptPath: null,\n };\n }\n\n const queryBundle = buildActiveRecallQueryBundle(input, config);\n const cacheKey = buildCacheKey(input, config, queryBundle);\n const currentTime = now();\n const cacheEnabled = config.cacheTtlMs > 0;\n if (cacheEnabled) {\n pruneExpiredCache(cache, currentTime);\n }\n const cached = cache.get(cacheKey);\n if (cacheEnabled && cached) {\n const result: ActiveRecallResult = {\n ...cloneRecallResult(cached.value),\n latencyMs: Math.max(0, now() - currentTime),\n cacheHit: true,\n };\n result.transcriptPath = null;\n if (config.persistTranscripts) {\n try {\n result.transcriptPath = await appendActiveRecallTranscript(\n config.transcriptDir,\n input,\n config,\n result,\n queryBundle,\n );\n } catch {\n result.transcriptPath = null;\n }\n }\n return result;\n }\n\n const start = currentTime;\n const recallContext = await deps.recall(queryBundle, input.sessionKey);\n const graphContext =\n config.entityGraphDepth > 0 && deps.walkEntityGraph\n ? await deps.walkEntityGraph({\n sessionKey: input.sessionKey,\n query: queryBundle,\n depth: config.entityGraphDepth,\n })\n : [];\n const causalContext =\n config.includeCausalTrajectories && deps.loadCausalTrajectories\n ? await deps.loadCausalTrajectories({\n sessionKey: input.sessionKey,\n query: queryBundle,\n })\n : [];\n const daySummary =\n config.includeDaySummary && deps.loadDaySummary\n ? await deps.loadDaySummary(input.sessionKey)\n : null;\n const recallExplain =\n config.attachRecallExplain && deps.explainLastRecall\n ? await deps.explainLastRecall(input.sessionKey)\n : null;\n const prompt = buildActiveRecallPrompt({\n config,\n queryBundle,\n recallContext,\n graphContext,\n causalContext,\n daySummary,\n recallExplain,\n });\n\n const generated = deps.generateSummary\n ? await deps.generateSummary({\n prompt,\n sessionKey: input.sessionKey,\n agentId: input.agentId,\n model: config.modelOverride ?? DEFAULT_REASONING_MODEL,\n timeoutMs: config.timeoutMs,\n thinking: config.thinking,\n fallbackPolicy: config.modelFallbackPolicy,\n })\n : {\n text: recallContext,\n modelUsed: config.modelOverride ?? DEFAULT_REASONING_MODEL,\n cacheHit: false,\n };\n const summary = normalizeActiveRecallSummary(\n generated.text,\n config.maxSummaryChars,\n );\n const snapshot = deps.getLastRecallSnapshot?.(input.sessionKey);\n const citations = (snapshot?.memoryIds ?? []).map((memoryId, index) => ({\n memoryId,\n relevance: Number((1 / (index + 1)).toFixed(3)),\n }));\n const result: ActiveRecallResult = {\n summary,\n citations,\n latencyMs: Math.max(0, now() - start),\n cacheHit: generated.cacheHit === true,\n modelUsed: generated.modelUsed ?? config.modelOverride ?? DEFAULT_REASONING_MODEL,\n transcriptPath: null,\n };\n if (config.persistTranscripts) {\n try {\n result.transcriptPath = await appendActiveRecallTranscript(\n config.transcriptDir,\n input,\n config,\n result,\n queryBundle,\n );\n } catch {\n result.transcriptPath = null;\n }\n }\n\n if (cacheEnabled) {\n const completedAt = now();\n const cachedValue = cloneRecallResult(result);\n cachedValue.transcriptPath = null;\n cache.set(cacheKey, {\n expiresAt: completedAt + config.cacheTtlMs,\n value: cachedValue,\n });\n enforceCacheLimit(cache);\n }\n return result;\n },\n };\n}\n"],"mappings":"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","names":["result"]}
1
+ {"version":3,"sources":["../src/active-recall.ts"],"sourcesContent":["import { appendFile, mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { DEFAULT_REASONING_MODEL } from \"./config.js\";\nimport { collapseWhitespace, truncateCodePointSafe } from \"./whitespace.js\";\nimport type {\n ActiveRecallChatType,\n ActiveRecallModelFallbackPolicy,\n ActiveRecallPromptStyle,\n ActiveRecallQueryMode,\n ActiveRecallThinking,\n} from \"./types.js\";\n\nexport interface ActiveRecallTurn {\n role: \"user\" | \"assistant\";\n content: string;\n}\n\nexport interface ActiveRecallInput {\n sessionKey: string;\n agentId: string;\n chatType: ActiveRecallChatType;\n recentTurns: ActiveRecallTurn[];\n currentMessage: string;\n}\n\nexport interface ActiveRecallConfig {\n enabled: boolean;\n agents: string[] | null;\n allowedChatTypes: ActiveRecallChatType[];\n queryMode: ActiveRecallQueryMode;\n promptStyle: ActiveRecallPromptStyle;\n customInstruction: string | null;\n promptReplacement: string | null;\n promptAppend: string | null;\n maxSummaryChars: number;\n recentUserTurns: number;\n recentAssistantTurns: number;\n recentUserChars: number;\n recentAssistantChars: number;\n thinking: ActiveRecallThinking;\n timeoutMs: number;\n cacheTtlMs: number;\n persistTranscripts: boolean;\n transcriptDir: string;\n entityGraphDepth: number;\n includeCausalTrajectories: boolean;\n includeDaySummary: boolean;\n attachRecallExplain: boolean;\n modelOverride: string | null;\n modelFallbackPolicy: ActiveRecallModelFallbackPolicy;\n}\n\nexport interface ActiveRecallResult {\n summary: string | null;\n citations: Array<{ memoryId: string; relevance: number }>;\n latencyMs: number;\n cacheHit: boolean;\n modelUsed: string;\n transcriptPath: string | null;\n}\n\nexport interface ActiveRecallDependencies {\n recall(query: string, sessionKey: string): Promise<string | null>;\n getLastRecallSnapshot?(sessionKey: string): { memoryIds?: string[] } | null;\n walkEntityGraph?(params: {\n sessionKey: string;\n query: string;\n depth: number;\n }): Promise<string[]>;\n loadCausalTrajectories?(params: {\n sessionKey: string;\n query: string;\n }): Promise<string[]>;\n loadDaySummary?(sessionKey: string): Promise<string | null>;\n explainLastRecall?(sessionKey: string): Promise<string | null>;\n generateSummary?(params: {\n prompt: string;\n sessionKey: string;\n agentId: string;\n model: string;\n timeoutMs: number;\n thinking: ActiveRecallThinking;\n fallbackPolicy: ActiveRecallModelFallbackPolicy;\n }): Promise<{ text: string | null; modelUsed?: string; cacheHit?: boolean }>;\n now?: () => number;\n}\n\ninterface CachedRecallResult {\n expiresAt: number;\n value: ActiveRecallResult;\n}\n\ninterface ActiveRecallTurnWithIndex {\n index: number;\n role: ActiveRecallTurn[\"role\"];\n content: string;\n}\n\nconst ACTIVE_RECALL_CACHE_MAX_ENTRIES = 256;\n\nconst NONE_SET = new Set([\n \"\",\n \"none\",\n \"no_reply\",\n \"nothing useful\",\n \"no relevant memory\",\n \"timeout\",\n \"[]\",\n \"{}\",\n \"null\",\n \"n/a\",\n]);\n\nconst STYLE_INSTRUCTIONS: Record<ActiveRecallPromptStyle, string> = {\n balanced: \"Summarize the most relevant memory context in a compact, neutral way.\",\n strict: \"Only include memory that is directly supported by the retrieved context.\",\n contextual: \"Prefer concise context that helps the next reply stay grounded in recent work.\",\n \"recall-heavy\": \"Bias toward richer recall coverage when multiple retrieved items reinforce each other.\",\n \"precision-heavy\": \"Bias toward precision. Omit anything uncertain or weakly supported.\",\n \"preference-only\": \"Only surface user preference or operating-style memory when present.\",\n};\n\nfunction cloneRecallResult(value: ActiveRecallResult): ActiveRecallResult {\n return {\n ...value,\n citations: [...value.citations],\n };\n}\n\nfunction buildCacheKey(input: ActiveRecallInput, config: ActiveRecallConfig, queryBundle: string): string {\n return JSON.stringify({\n sessionKey: input.sessionKey,\n agentId: input.agentId,\n queryMode: config.queryMode,\n promptStyle: config.promptStyle,\n customInstruction: config.customInstruction,\n promptReplacement: config.promptReplacement,\n promptAppend: config.promptAppend,\n maxSummaryChars: config.maxSummaryChars,\n entityGraphDepth: config.entityGraphDepth,\n includeCausalTrajectories: config.includeCausalTrajectories,\n includeDaySummary: config.includeDaySummary,\n attachRecallExplain: config.attachRecallExplain,\n modelOverride: config.modelOverride,\n modelFallbackPolicy: config.modelFallbackPolicy,\n thinking: config.thinking,\n queryBundle,\n });\n}\n\nfunction pruneExpiredCache(\n cache: Map<string, CachedRecallResult>,\n currentTime: number,\n): void {\n for (const [key, entry] of cache.entries()) {\n if (entry.expiresAt <= currentTime) {\n cache.delete(key);\n }\n }\n}\n\nfunction enforceCacheLimit(cache: Map<string, CachedRecallResult>): void {\n while (cache.size > ACTIVE_RECALL_CACHE_MAX_ENTRIES) {\n const oldestKey = cache.keys().next().value;\n if (typeof oldestKey !== \"string\") {\n break;\n }\n cache.delete(oldestKey);\n }\n}\n\nfunction cropTurns(\n turns: ActiveRecallTurn[],\n role: \"user\" | \"assistant\",\n maxTurns: number,\n maxChars: number,\n): ActiveRecallTurnWithIndex[] {\n if (maxTurns <= 0) {\n return [];\n }\n\n const selected: ActiveRecallTurnWithIndex[] = [];\n for (let index = turns.length - 1; index >= 0 && selected.length < maxTurns; index -= 1) {\n const turn = turns[index];\n if (turn?.role === role) {\n selected.push({\n index,\n role: turn.role,\n content: collapseWhitespace(truncateCodePointSafe(turn.content, maxChars)),\n });\n }\n }\n\n return selected.reverse();\n}\n\nfunction mergeChronologicalTurns(\n userTurns: ActiveRecallTurnWithIndex[],\n assistantTurns: ActiveRecallTurnWithIndex[],\n): ActiveRecallTurnWithIndex[] {\n return [...userTurns, ...assistantTurns]\n .sort((left, right) => left.index - right.index)\n .filter((value) => value.content.length > 0);\n}\n\nexport function buildActiveRecallQueryBundle(\n input: ActiveRecallInput,\n config: ActiveRecallConfig,\n): string {\n if (config.queryMode === \"message\") {\n return collapseWhitespace(input.currentMessage);\n }\n\n const userTurns = cropTurns(\n input.recentTurns,\n \"user\",\n config.recentUserTurns,\n config.recentUserChars,\n );\n const assistantTurns = cropTurns(\n input.recentTurns,\n \"assistant\",\n config.recentAssistantTurns,\n config.recentAssistantChars,\n );\n const mergedTurns = mergeChronologicalTurns(userTurns, assistantTurns);\n\n const parts = [\n ...mergedTurns.map((turn) => `${turn.role}: ${turn.content}`),\n ];\n\n if (config.queryMode === \"full\") {\n return [...parts, `current: ${collapseWhitespace(input.currentMessage)}`]\n .filter((value) => value.trim().length > 0)\n .join(\"\\n\");\n }\n\n return [`current: ${collapseWhitespace(input.currentMessage)}`, ...parts]\n .filter((value) => value.trim().length > 0)\n .join(\"\\n\");\n}\n\nexport function normalizeActiveRecallSummary(value: string | null, maxChars: number): string | null {\n if (value == null) return null;\n const compact = collapseWhitespace(value);\n if (NONE_SET.has(compact.toLowerCase())) return null;\n return truncateCodePointSafe(compact, maxChars);\n}\n\nfunction sanitizeTranscriptPathSegment(value: string): string {\n const normalized = collapseWhitespace(value);\n return encodeURIComponent(normalized.length > 0 ? normalized : \"unknown\").replaceAll(\n \".\",\n \"%2E\",\n );\n}\n\nexport function buildActiveRecallPrompt(params: {\n config: ActiveRecallConfig;\n queryBundle: string;\n recallContext: string | null;\n graphContext: string[];\n causalContext: string[];\n daySummary: string | null;\n recallExplain: string | null;\n}): string {\n const promptReplacement = params.config.promptReplacement?.trim();\n if (promptReplacement) {\n return promptReplacement;\n }\n\n const sections = [\n params.config.customInstruction?.trim() || STYLE_INSTRUCTIONS[params.config.promptStyle],\n `Query bundle:\\n${params.queryBundle}`,\n params.recallContext ? `Retrieved memory:\\n${params.recallContext}` : null,\n params.graphContext.length > 0 ? `Entity graph:\\n${params.graphContext.join(\"\\n\")}` : null,\n params.causalContext.length > 0 ? `Causal trajectories:\\n${params.causalContext.join(\"\\n\")}` : null,\n params.daySummary ? `Day summary:\\n${params.daySummary}` : null,\n params.recallExplain ? `Recall explain:\\n${params.recallExplain}` : null,\n params.config.promptAppend?.trim() || null,\n \"Return either NONE or a compact summary grounded only in the supplied context.\",\n ];\n return sections.filter((value): value is string => !!value && value.trim().length > 0).join(\"\\n\\n\");\n}\n\nasync function appendActiveRecallTranscript(\n transcriptRoot: string,\n input: ActiveRecallInput,\n config: ActiveRecallConfig,\n result: ActiveRecallResult,\n queryBundle: string,\n): Promise<string> {\n const date = new Date().toISOString().slice(0, 10);\n const filePath = path.join(\n transcriptRoot,\n \"agents\",\n sanitizeTranscriptPathSegment(input.agentId),\n date,\n `${sanitizeTranscriptPathSegment(input.sessionKey)}.jsonl`,\n );\n await mkdir(path.dirname(filePath), { recursive: true });\n await appendFile(\n filePath,\n `${JSON.stringify({\n ts: new Date().toISOString(),\n sessionKey: input.sessionKey,\n agentId: input.agentId,\n queryMode: config.queryMode,\n promptStyle: config.promptStyle,\n queryBundle,\n summary: result.summary,\n citations: result.citations,\n latencyMs: result.latencyMs,\n cacheHit: result.cacheHit,\n modelUsed: result.modelUsed,\n })}\\n`,\n \"utf8\",\n );\n return filePath;\n}\n\nexport function createActiveRecallEngine(\n deps: ActiveRecallDependencies,\n config: ActiveRecallConfig,\n) {\n const cache = new Map<string, CachedRecallResult>();\n const now = deps.now ?? (() => Date.now());\n\n return {\n async run(input: ActiveRecallInput): Promise<ActiveRecallResult> {\n if (!config.enabled) {\n return {\n summary: null,\n citations: [],\n latencyMs: 0,\n cacheHit: false,\n modelUsed: config.modelOverride ?? \"disabled\",\n transcriptPath: null,\n };\n }\n if (config.agents && !config.agents.includes(input.agentId)) {\n return {\n summary: null,\n citations: [],\n latencyMs: 0,\n cacheHit: false,\n modelUsed: config.modelOverride ?? \"filtered\",\n transcriptPath: null,\n };\n }\n if (!config.allowedChatTypes.includes(input.chatType)) {\n return {\n summary: null,\n citations: [],\n latencyMs: 0,\n cacheHit: false,\n modelUsed: config.modelOverride ?? \"filtered\",\n transcriptPath: null,\n };\n }\n\n const queryBundle = buildActiveRecallQueryBundle(input, config);\n const cacheKey = buildCacheKey(input, config, queryBundle);\n const currentTime = now();\n const cacheEnabled = config.cacheTtlMs > 0;\n if (cacheEnabled) {\n pruneExpiredCache(cache, currentTime);\n }\n const cached = cache.get(cacheKey);\n if (cacheEnabled && cached) {\n const result: ActiveRecallResult = {\n ...cloneRecallResult(cached.value),\n latencyMs: Math.max(0, now() - currentTime),\n cacheHit: true,\n };\n result.transcriptPath = null;\n if (config.persistTranscripts) {\n try {\n result.transcriptPath = await appendActiveRecallTranscript(\n config.transcriptDir,\n input,\n config,\n result,\n queryBundle,\n );\n } catch {\n result.transcriptPath = null;\n }\n }\n return result;\n }\n\n const start = currentTime;\n const recallContext = await deps.recall(queryBundle, input.sessionKey);\n const graphContext =\n config.entityGraphDepth > 0 && deps.walkEntityGraph\n ? await deps.walkEntityGraph({\n sessionKey: input.sessionKey,\n query: queryBundle,\n depth: config.entityGraphDepth,\n })\n : [];\n const causalContext =\n config.includeCausalTrajectories && deps.loadCausalTrajectories\n ? await deps.loadCausalTrajectories({\n sessionKey: input.sessionKey,\n query: queryBundle,\n })\n : [];\n const daySummary =\n config.includeDaySummary && deps.loadDaySummary\n ? await deps.loadDaySummary(input.sessionKey)\n : null;\n const recallExplain =\n config.attachRecallExplain && deps.explainLastRecall\n ? await deps.explainLastRecall(input.sessionKey)\n : null;\n const prompt = buildActiveRecallPrompt({\n config,\n queryBundle,\n recallContext,\n graphContext,\n causalContext,\n daySummary,\n recallExplain,\n });\n\n const generated = deps.generateSummary\n ? await deps.generateSummary({\n prompt,\n sessionKey: input.sessionKey,\n agentId: input.agentId,\n model: config.modelOverride ?? DEFAULT_REASONING_MODEL,\n timeoutMs: config.timeoutMs,\n thinking: config.thinking,\n fallbackPolicy: config.modelFallbackPolicy,\n })\n : {\n text: recallContext,\n modelUsed: config.modelOverride ?? DEFAULT_REASONING_MODEL,\n cacheHit: false,\n };\n const summary = normalizeActiveRecallSummary(\n generated.text,\n config.maxSummaryChars,\n );\n const snapshot = deps.getLastRecallSnapshot?.(input.sessionKey);\n const citations = (snapshot?.memoryIds ?? []).map((memoryId, index) => ({\n memoryId,\n relevance: Number((1 / (index + 1)).toFixed(3)),\n }));\n const result: ActiveRecallResult = {\n summary,\n citations,\n latencyMs: Math.max(0, now() - start),\n cacheHit: generated.cacheHit === true,\n modelUsed: generated.modelUsed ?? config.modelOverride ?? DEFAULT_REASONING_MODEL,\n transcriptPath: null,\n };\n if (config.persistTranscripts) {\n try {\n result.transcriptPath = await appendActiveRecallTranscript(\n config.transcriptDir,\n input,\n config,\n result,\n queryBundle,\n );\n } catch {\n result.transcriptPath = null;\n }\n }\n\n if (cacheEnabled) {\n const completedAt = now();\n const cachedValue = cloneRecallResult(result);\n cachedValue.transcriptPath = null;\n cache.set(cacheKey, {\n expiresAt: completedAt + config.cacheTtlMs,\n value: cachedValue,\n });\n enforceCacheLimit(cache);\n }\n return result;\n },\n };\n}\n"],"mappings":"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","names":["result"]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  dateInTimezone,
3
3
  defaultTimezone
4
- } from "./chunk-SIBVIP2Y.js";
4
+ } from "./chunk-PAZY2ZKP.js";
5
5
  import "./chunk-ODW5GDFE.js";
6
6
  import "./chunk-UOBPK2OS.js";
7
7
  import "./chunk-CIO7GCWE.js";
@@ -12,7 +12,7 @@ import {
12
12
  describeErrorForOperator
13
13
  } from "./chunk-V7IZKJI3.js";
14
14
  import "./chunk-UHVXE24Y.js";
15
- import "./chunk-MRSLR6TB.js";
15
+ import "./chunk-3QQTXYZ6.js";
16
16
  import "./chunk-BT7NVCML.js";
17
17
  import "./chunk-JALOAKSZ.js";
18
18
  import "./chunk-QIEUU4UK.js";
@@ -21,10 +21,10 @@ import "./chunk-45GF7Y3V.js";
21
21
  import "./chunk-RGMVMVMF.js";
22
22
  import "./chunk-N7RWREIQ.js";
23
23
  import "./chunk-QDW3E4RD.js";
24
- import "./chunk-NTYLZXDX.js";
24
+ import "./chunk-VYCOJKSX.js";
25
25
  import "./chunk-YCVB7X56.js";
26
26
  import "./chunk-RL6NEVXT.js";
27
- import "./chunk-N6A2RP5S.js";
27
+ import "./chunk-NB3LRY4T.js";
28
28
  import "./chunk-5FVVY2EB.js";
29
29
  import "./chunk-FFAZ2XFU.js";
30
30
  import "./chunk-JDSVLVCG.js";
@@ -34,10 +34,10 @@ import "./chunk-P7FMDTKL.js";
34
34
  import "./chunk-JUOZ62Y7.js";
35
35
  import "./chunk-EYIEWJNI.js";
36
36
  import "./chunk-JUC24CTX.js";
37
- import "./chunk-ET2CNMLD.js";
37
+ import "./chunk-JN72EPOE.js";
38
38
  import "./chunk-A6XUJE5D.js";
39
39
  import "./chunk-VS2IYZRU.js";
40
- import "./chunk-5UZXUTVO.js";
40
+ import "./chunk-KNA3BXXL.js";
41
41
  import "./chunk-3WCASNQZ.js";
42
42
  import "./chunk-PZ5AY32C.js";
43
43
 
@@ -90,4 +90,4 @@ function startWearablesAutoSync(settings, deps) {
90
90
  export {
91
91
  startWearablesAutoSync
92
92
  };
93
- //# sourceMappingURL=auto-sync-TTIEWJ5X.js.map
93
+ //# sourceMappingURL=auto-sync-WNGG2GC2.js.map
package/dist/briefing.js CHANGED
@@ -18,19 +18,19 @@ import {
18
18
  renderBriefingMarkdown,
19
19
  resolveBriefingSaveDir,
20
20
  validateBriefingFormat
21
- } from "./chunk-YBLZFNIQ.js";
22
- import "./chunk-OU5TIWDQ.js";
21
+ } from "./chunk-WJHGDE7X.js";
22
+ import "./chunk-XSGUMQQQ.js";
23
23
  import "./chunk-UHVXE24Y.js";
24
24
  import "./chunk-46WM6JX2.js";
25
- import "./chunk-WVGXCBOC.js";
26
- import "./chunk-FYWLSFFS.js";
27
- import "./chunk-HNPE66LB.js";
28
- import "./chunk-N37X5RU7.js";
29
- import "./chunk-NNBZS3DY.js";
25
+ import "./chunk-D5F7TKMH.js";
26
+ import "./chunk-2Z4GS5E6.js";
27
+ import "./chunk-6CVNSDCZ.js";
28
+ import "./chunk-BD7JTBYP.js";
29
+ import "./chunk-OB3XMWX5.js";
30
30
  import "./chunk-CYEPCZN5.js";
31
- import "./chunk-GIC6BASP.js";
31
+ import "./chunk-TNSCIPBQ.js";
32
32
  import "./chunk-YQNNHLCG.js";
33
- import "./chunk-W7IGLX4G.js";
33
+ import "./chunk-4O6WRBGE.js";
34
34
  import "./chunk-6KTXE6A3.js";
35
35
  import "./chunk-GUMZC2BO.js";
36
36
  import "./chunk-227UFSEQ.js";
@@ -40,22 +40,22 @@ import "./chunk-A7Q43EUZ.js";
40
40
  import "./chunk-S2V7RUCL.js";
41
41
  import "./chunk-SO7SV523.js";
42
42
  import "./chunk-SCU65EZI.js";
43
- import "./chunk-2GF27PGH.js";
43
+ import "./chunk-MRPOZBJC.js";
44
44
  import "./chunk-S2HLHAZ4.js";
45
45
  import "./chunk-DM2T26WE.js";
46
46
  import "./chunk-LDXUBPMO.js";
47
47
  import "./chunk-XSTNGNJP.js";
48
48
  import "./chunk-AAD2ZS6P.js";
49
- import "./chunk-SLIOMMPF.js";
49
+ import "./chunk-H272ZPQ3.js";
50
50
  import "./chunk-YXZG5TVN.js";
51
51
  import "./chunk-3ONXXHQO.js";
52
52
  import "./chunk-5GINB5LC.js";
53
53
  import "./chunk-3WU7XOFN.js";
54
54
  import "./chunk-G7D6GZ5J.js";
55
- import "./chunk-E7UQOS4C.js";
55
+ import "./chunk-JPKK466T.js";
56
56
  import "./chunk-XCB6QDL6.js";
57
57
  import "./chunk-RBOJCG4T.js";
58
- import "./chunk-NNZFPYYX.js";
58
+ import "./chunk-R7QY5ZVB.js";
59
59
  import "./chunk-5WITETWU.js";
60
60
  import "./chunk-6CIAGZ6X.js";
61
61
  import "./chunk-UBCBDJOB.js";
@@ -63,7 +63,7 @@ import "./chunk-CEH2AFXG.js";
63
63
  import "./chunk-JXN77SGO.js";
64
64
  import "./chunk-IUM3VSHI.js";
65
65
  import "./chunk-ZLQ37WJX.js";
66
- import "./chunk-MRSLR6TB.js";
66
+ import "./chunk-3QQTXYZ6.js";
67
67
  import "./chunk-BT7NVCML.js";
68
68
  import "./chunk-C64XATK7.js";
69
69
  import "./chunk-42JKGUFJ.js";
@@ -75,7 +75,7 @@ import "./chunk-RGMVMVMF.js";
75
75
  import "./chunk-N7RWREIQ.js";
76
76
  import "./chunk-NXH34IPL.js";
77
77
  import "./chunk-ZIKENA2C.js";
78
- import "./chunk-NTYLZXDX.js";
78
+ import "./chunk-VYCOJKSX.js";
79
79
  import "./chunk-6Q3ZTEF6.js";
80
80
  import "./chunk-W5BIQOAJ.js";
81
81
  import "./chunk-Z7L72ZHL.js";
@@ -84,13 +84,13 @@ import "./chunk-YCVB7X56.js";
84
84
  import "./chunk-PQVCH2AE.js";
85
85
  import "./chunk-PJKTFXE2.js";
86
86
  import "./chunk-TG3FAM2S.js";
87
- import "./chunk-ZJABRLCZ.js";
87
+ import "./chunk-TBXAY2SS.js";
88
88
  import "./chunk-ZA53AZND.js";
89
89
  import "./chunk-AL3UYZ5N.js";
90
90
  import "./chunk-RL6NEVXT.js";
91
- import "./chunk-GCASGYIO.js";
91
+ import "./chunk-C7HJ3NEI.js";
92
92
  import "./chunk-7RJUVTVF.js";
93
- import "./chunk-N6A2RP5S.js";
93
+ import "./chunk-NB3LRY4T.js";
94
94
  import "./chunk-5FVVY2EB.js";
95
95
  import "./chunk-FFAZ2XFU.js";
96
96
  import "./chunk-EEOUMG3J.js";
@@ -108,10 +108,10 @@ import "./chunk-EYIEWJNI.js";
108
108
  import "./chunk-JUC24CTX.js";
109
109
  import "./chunk-BTTPKDIL.js";
110
110
  import "./chunk-FF4KLI5W.js";
111
- import "./chunk-ET2CNMLD.js";
111
+ import "./chunk-JN72EPOE.js";
112
112
  import "./chunk-A6XUJE5D.js";
113
113
  import "./chunk-VS2IYZRU.js";
114
- import "./chunk-5UZXUTVO.js";
114
+ import "./chunk-KNA3BXXL.js";
115
115
  import "./chunk-3WCASNQZ.js";
116
116
  import "./chunk-PZ5AY32C.js";
117
117
  export {
package/dist/buffer.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  SmartBuffer
3
- } from "./chunk-CSY5DA7O.js";
3
+ } from "./chunk-Z6COGHHN.js";
4
4
  import "./chunk-2AD5SXO4.js";
5
5
  import "./chunk-H3FZVNRN.js";
6
- import "./chunk-XTYDEO7M.js";
7
- import "./chunk-WW6B7NQJ.js";
6
+ import "./chunk-L7Z57SID.js";
7
+ import "./chunk-NLYVH66G.js";
8
8
  import "./chunk-CSAKJVXW.js";
9
9
  import "./chunk-K2XUWZBM.js";
10
10
  import "./chunk-OD4FM2U7.js";
@@ -12,18 +12,18 @@ import "./chunk-CEH2AFXG.js";
12
12
  import "./chunk-JXN77SGO.js";
13
13
  import "./chunk-IUM3VSHI.js";
14
14
  import "./chunk-ZLQ37WJX.js";
15
- import "./chunk-MRSLR6TB.js";
15
+ import "./chunk-3QQTXYZ6.js";
16
16
  import "./chunk-BT7NVCML.js";
17
17
  import "./chunk-C64XATK7.js";
18
18
  import "./chunk-42JKGUFJ.js";
19
19
  import "./chunk-P6FHFTZ7.js";
20
- import "./chunk-NTYLZXDX.js";
20
+ import "./chunk-VYCOJKSX.js";
21
21
  import "./chunk-6Q3ZTEF6.js";
22
22
  import "./chunk-TBBDFYXW.js";
23
23
  import "./chunk-ESNFSSO4.js";
24
24
  import "./chunk-AW4QUFQF.js";
25
- import "./chunk-GCASGYIO.js";
26
- import "./chunk-N6A2RP5S.js";
25
+ import "./chunk-C7HJ3NEI.js";
26
+ import "./chunk-NB3LRY4T.js";
27
27
  import "./chunk-5FVVY2EB.js";
28
28
  import "./chunk-FFAZ2XFU.js";
29
29
  import "./chunk-JDSVLVCG.js";
@@ -39,10 +39,10 @@ import "./chunk-O75CRYGF.js";
39
39
  import "./chunk-EYIEWJNI.js";
40
40
  import "./chunk-JUC24CTX.js";
41
41
  import "./chunk-BTTPKDIL.js";
42
- import "./chunk-ET2CNMLD.js";
42
+ import "./chunk-JN72EPOE.js";
43
43
  import "./chunk-A6XUJE5D.js";
44
44
  import "./chunk-VS2IYZRU.js";
45
- import "./chunk-5UZXUTVO.js";
45
+ import "./chunk-KNA3BXXL.js";
46
46
  import "./chunk-3WCASNQZ.js";
47
47
  import "./chunk-PZ5AY32C.js";
48
48
  export {
@@ -15,7 +15,8 @@ import "./chunk-EYIEWJNI.js";
15
15
  import "./chunk-JUC24CTX.js";
16
16
  import {
17
17
  listJsonFiles
18
- } from "./chunk-P77QX3ID.js";
18
+ } from "./chunk-B6O2YLUR.js";
19
+ import "./chunk-KNA3BXXL.js";
19
20
  import {
20
21
  log
21
22
  } from "./chunk-3WCASNQZ.js";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/calibration.ts"],"sourcesContent":["/**\n * calibration.ts — Prediction-Error-Driven Model-User Calibration\n *\n * Analyzes patterns in user corrections to identify systematic miscalibration\n * between the model's predictions and the user's actual expectations.\n * During consolidation, replays chains of similar corrections through an LLM\n * to synthesize CalibrationRules that adjust model behavior for this specific user.\n *\n * Inspired by:\n * - Cerebellar motor calibration (prediction errors drive lasting adjustments)\n * - Temporal difference learning (dopamine signals prediction error)\n * - Tesla FSD shadow mode (divergence between prediction and reality = training signal)\n */\n\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { FallbackLlmClient } from \"./fallback-llm.js\";\nimport type { AgentPersonaModelConfig, GatewayConfig, MemoryFile } from \"./types.js\";\nimport { listJsonFiles, readJsonFile } from \"./json-store.js\";\nimport { isRecord } from \"./store-contract.js\";\nimport { log } from \"./logger.js\";\nimport { OUTPUT_LANGUAGE_POLICY } from \"./extraction-prompt.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface CalibrationRule {\n id: string;\n ruleType: \"model_tendency\" | \"user_expectation\" | \"scope_boundary\" | \"verification_required\";\n condition: string;\n modelTendency: string;\n userExpectation: string;\n calibration: string;\n confidence: number;\n evidenceCount: number;\n evidenceCorrectionIds: string[];\n createdAt: string;\n lastReinforcedAt: string;\n}\n\nexport interface CalibrationIndex {\n rules: CalibrationRule[];\n updatedAt: string;\n totalCorrectionsAnalyzed: number;\n}\n\n// ─── Storage ─────────────────────────────────────────────────────────────────\n\nfunction calibrationDir(memoryDir: string): string {\n return path.join(memoryDir, \"state\", \"calibration\");\n}\n\nfunction calibrationIndexPath(memoryDir: string): string {\n return path.join(calibrationDir(memoryDir), \"calibration-index.json\");\n}\n\nexport async function readCalibrationIndex(memoryDir: string): Promise<CalibrationIndex> {\n try {\n const raw = JSON.parse(await readFile(calibrationIndexPath(memoryDir), \"utf8\"));\n return {\n rules: Array.isArray(raw.rules) ? raw.rules : [],\n updatedAt: typeof raw.updatedAt === \"string\" ? raw.updatedAt : new Date().toISOString(),\n totalCorrectionsAnalyzed: typeof raw.totalCorrectionsAnalyzed === \"number\" ? raw.totalCorrectionsAnalyzed : 0,\n };\n } catch {\n return { rules: [], updatedAt: new Date().toISOString(), totalCorrectionsAnalyzed: 0 };\n }\n}\n\nasync function writeCalibrationIndex(memoryDir: string, index: CalibrationIndex): Promise<void> {\n const dir = calibrationDir(memoryDir);\n await mkdir(dir, { recursive: true });\n index.updatedAt = new Date().toISOString();\n await writeFile(calibrationIndexPath(memoryDir), JSON.stringify(index, null, 2), \"utf8\");\n}\n\n// ─── Correction Reading ──────────────────────────────────────────────────────\n\nexport interface CorrectionMemory {\n id: string;\n content: string;\n created: string;\n confidence: number;\n entityRefs: string[];\n tags: string[];\n}\n\nconst CALIBRATION_RULE_TYPES = new Set([\n \"model_tendency\",\n \"user_expectation\",\n \"scope_boundary\",\n \"verification_required\",\n]);\n\nfunction parseConfidence(value: unknown): number | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return undefined;\n return Math.max(0, Math.min(1, value));\n}\n\nfunction parseEvidenceIds(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0);\n}\n\nfunction nonEmptyString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\n/**\n * Exported for entity-contamination R-11 regression coverage (#682\n * PR 2/3 — codex review). Tests can drive the real correction-reading\n * path instead of duplicating the regex inline, so calibration parser\n * regressions surface via the contamination suite.\n */\nexport async function readCalibrationCorrections(memoryDir: string): Promise<CorrectionMemory[]> {\n return readCorrectionsImpl(memoryDir);\n}\n\nasync function readCorrections(memoryDir: string): Promise<CorrectionMemory[]> {\n return readCorrectionsImpl(memoryDir);\n}\n\nasync function readCorrectionsImpl(memoryDir: string): Promise<CorrectionMemory[]> {\n const correctionsDir = path.join(memoryDir, \"corrections\");\n const files = await listJsonFiles(correctionsDir).catch(() => {\n // Corrections might be in facts/ directories too\n return [] as string[];\n });\n\n // Also scan facts directories for correction-category files\n const factsDir = path.join(memoryDir, \"facts\");\n try {\n const { readdir } = await import(\"node:fs/promises\");\n const dayDirs = (await readdir(factsDir)).filter((d: string) => /^\\d{4}-\\d{2}-\\d{2}$/.test(d));\n for (const day of dayDirs) {\n const dayPath = path.join(factsDir, day);\n const dayFiles = (await readdir(dayPath))\n .filter((f: string) => f.startsWith(\"correction-\") && f.endsWith(\".md\"))\n .map((f: string) => path.join(dayPath, f));\n files.push(...dayFiles);\n }\n } catch {\n // facts dir might not exist\n }\n\n // Also check the dedicated corrections directory\n try {\n const { readdir } = await import(\"node:fs/promises\");\n const corrFiles = (await readdir(correctionsDir))\n .filter((f: string) => f.endsWith(\".md\"))\n .map((f: string) => path.join(correctionsDir, f));\n files.push(...corrFiles);\n } catch {\n // corrections dir might not exist\n }\n\n const corrections: CorrectionMemory[] = [];\n const seen = new Set<string>();\n\n for (const filePath of files) {\n try {\n const raw = await readFile(filePath, \"utf8\");\n\n // Parse frontmatter\n const fmMatch = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n if (!fmMatch) continue;\n\n const content = fmMatch[2].trim();\n if (!content || content.length < 10) continue;\n\n // Extract id from frontmatter\n const idMatch = fmMatch[1].match(/^id:\\s*(.+)$/m);\n const id = idMatch?.[1]?.trim() ?? path.basename(filePath, \".md\");\n\n if (seen.has(id)) continue;\n seen.add(id);\n\n const confMatch = fmMatch[1].match(/^confidence:\\s*(.+)$/m);\n const confidence = confMatch ? parseFloat(confMatch[1]) : 0.9;\n\n const entityMatch = fmMatch[1].match(/^entityRef:\\s*(.+)$/m);\n const entityRefs = entityMatch ? [entityMatch[1].trim()] : [];\n\n corrections.push({ id, content, created: \"\", confidence, entityRefs, tags: [] });\n } catch {\n // skip unparseable files\n }\n }\n\n return corrections;\n}\n\n// ─── LLM-Assisted Clustering and Replay ──────────────────────────────────────\n\nexport const CLUSTER_PROMPT = `You are analyzing user corrections to an AI assistant. Each correction represents a moment where the assistant's prediction of what the user wanted was WRONG.\n\nYour job: Group these corrections into clusters where the SAME TYPE of misunderstanding is happening. Then for each cluster, synthesize a CalibrationRule.\n\nA CalibrationRule describes:\n- condition: When does this type of mistake happen?\n- modelTendency: What does the model tend to assume or do wrong?\n- userExpectation: What does the user actually want instead?\n- calibration: How should the model adjust its behavior?\n- ruleType: One of \"model_tendency\", \"user_expectation\", \"scope_boundary\", \"verification_required\"\n\nFocus on PATTERNS, not individual corrections. A cluster needs at least 2 corrections to be worth a rule.\n${OUTPUT_LANGUAGE_POLICY}\n\nOutput valid JSON only:\n{\n \"rules\": [\n {\n \"ruleType\": \"model_tendency\",\n \"condition\": \"When discussing project scope or task boundaries\",\n \"modelTendency\": \"The model tends to assume broader scope than the user intends\",\n \"userExpectation\": \"The user prefers narrow, specific task definitions and wants to be asked before scope expansion\",\n \"calibration\": \"When uncertain about scope, ask for clarification rather than assuming. Default to the narrower interpretation.\",\n \"confidence\": 0.85,\n \"evidenceIds\": [\"correction-id-1\", \"correction-id-2\"]\n }\n ]\n}`;\n\nexport async function synthesizeCalibrationRules(\n corrections: CorrectionMemory[],\n llm: FallbackLlmClient,\n existingRules: CalibrationRule[],\n agentId?: string,\n modelChain?: AgentPersonaModelConfig,\n): Promise<CalibrationRule[]> {\n if (corrections.length < 2) return [];\n\n // Format corrections for the LLM\n const correctionText = corrections\n .slice(0, 50) // limit to avoid huge prompts\n .map((c, i) => `[${c.id}] ${c.content}`)\n .join(\"\\n\\n\");\n\n const existingRulesText = existingRules.length > 0\n ? `\\n\\nExisting calibration rules (avoid duplicating these):\\n${existingRules.map((r) => `- ${r.condition}: ${r.calibration}`).join(\"\\n\")}`\n : \"\";\n\n const response = await llm.chatCompletion(\n [\n { role: \"system\", content: CLUSTER_PROMPT },\n { role: \"user\", content: `Here are ${corrections.length} corrections from this user:\\n\\n${correctionText}${existingRulesText}` },\n ],\n { temperature: 0.3, maxTokens: 3000, agentId, modelChain },\n );\n\n if (!response?.content) return [];\n\n try {\n let jsonStr = response.content.trim();\n const fenceMatch = jsonStr.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/);\n if (fenceMatch) jsonStr = fenceMatch[1];\n\n const parsed = JSON.parse(jsonStr);\n if (!Array.isArray(parsed.rules)) return [];\n\n const now = new Date().toISOString();\n const rawRules: unknown[] = Array.isArray(parsed.rules) ? parsed.rules : [];\n return rawRules\n .map((r: unknown): CalibrationRule | undefined => {\n if (!r || typeof r !== \"object\" || Array.isArray(r)) return undefined;\n const raw = r as Record<string, unknown>;\n const ruleType = nonEmptyString(raw.ruleType);\n const condition = nonEmptyString(raw.condition);\n const modelTendency = nonEmptyString(raw.modelTendency);\n const calibration = nonEmptyString(raw.calibration);\n const confidence = parseConfidence(raw.confidence);\n if (\n !ruleType ||\n !CALIBRATION_RULE_TYPES.has(ruleType) ||\n !condition ||\n !modelTendency ||\n !calibration ||\n confidence === undefined\n ) {\n return undefined;\n }\n const evidenceCorrectionIds = parseEvidenceIds(raw.evidenceIds);\n return {\n id: `cal-${createHash(\"sha256\").update(condition + calibration).digest(\"hex\").slice(0, 12)}`,\n ruleType: ruleType as CalibrationRule[\"ruleType\"],\n condition,\n modelTendency,\n userExpectation: nonEmptyString(raw.userExpectation) ?? \"\",\n calibration,\n confidence,\n evidenceCount: evidenceCorrectionIds.length,\n evidenceCorrectionIds,\n createdAt: now,\n lastReinforcedAt: now,\n };\n })\n .filter((rule): rule is CalibrationRule => !!rule);\n } catch {\n log.warn(\"[calibration] failed to parse LLM response\");\n return [];\n }\n}\n\n// ─── Recall Section ──────────────────────────────────────────────────────────\n\n/**\n * Build a recall section from calibration rules relevant to the current query.\n * Uses the LLM to select which rules apply to the current context.\n */\nexport function buildCalibrationRecallSection(\n rules: CalibrationRule[],\n query: string,\n maxChars: number = 1200,\n): string | null {\n if (rules.length === 0) return null;\n\n // Simple relevance: include all rules (they're already filtered to this user)\n // In production, could use embedding similarity to filter\n const lines: string[] = [\n \"## Model Calibration (learned from past corrections)\",\n \"\",\n \"Adjustments for this specific user, learned from patterns in their corrections:\",\n \"\",\n ];\n\n let totalChars = lines.join(\"\\n\").length;\n\n for (const rule of rules) {\n const line = `- **${rule.condition}**: ${rule.modelTendency} → Instead: ${rule.calibration}`;\n if (totalChars + line.length + 1 > maxChars) break;\n lines.push(line);\n totalChars += line.length + 1;\n }\n\n if (lines.length <= 4) return null;\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Run the full calibration pipeline:\n * 1. Read all corrections\n * 2. Send to LLM for clustering and rule synthesis\n * 3. Merge with existing rules\n * 4. Write updated index\n */\nexport async function runCalibrationConsolidation(options: {\n memoryDir: string;\n gatewayConfig?: GatewayConfig;\n gatewayAgentId?: string;\n modelChain?: AgentPersonaModelConfig;\n workspaceDir?: string;\n}): Promise<CalibrationRule[]> {\n try {\n const llm = new FallbackLlmClient(options.gatewayConfig, {\n workspaceDir: options.workspaceDir,\n });\n if (!llm.isAvailable({ agentId: options.gatewayAgentId, modelChain: options.modelChain })) {\n log.debug(\"[calibration] no LLM available — skipping consolidation\");\n return [];\n }\n\n const corrections = await readCorrections(options.memoryDir);\n if (corrections.length < 3) {\n log.debug(`[calibration] only ${corrections.length} corrections — need at least 3`);\n return [];\n }\n\n const existingIndex = await readCalibrationIndex(options.memoryDir);\n\n const newRules = await synthesizeCalibrationRules(corrections, llm, existingIndex.rules, options.gatewayAgentId, options.modelChain);\n if (newRules.length === 0) {\n log.debug(\"[calibration] no new calibration rules synthesized\");\n return existingIndex.rules;\n }\n\n // Merge: keep existing rules, add new ones (deduplicate by id)\n const ruleMap = new Map(existingIndex.rules.map((r) => [r.id, r]));\n for (const rule of newRules) {\n if (ruleMap.has(rule.id)) {\n // Reinforce existing rule\n const existing = ruleMap.get(rule.id)!;\n existing.lastReinforcedAt = new Date().toISOString();\n existing.evidenceCount += rule.evidenceCount;\n existing.confidence = Math.min(1, existing.confidence + 0.05);\n } else {\n ruleMap.set(rule.id, rule);\n }\n }\n\n const allRules = [...ruleMap.values()];\n await writeCalibrationIndex(options.memoryDir, {\n rules: allRules,\n updatedAt: new Date().toISOString(),\n totalCorrectionsAnalyzed: corrections.length,\n });\n\n log.debug(`[calibration] synthesized ${newRules.length} new rule(s), ${allRules.length} total`);\n return allRules;\n } catch (error) {\n log.warn(`[calibration] consolidation failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);\n return [];\n }\n}\n\n/**\n * Standalone entry point for calibration consolidation that can be called\n * independently of weekly compounding. The compounding engine's\n * `synthesizeWeekly()` is one trigger, but orchestrators or periodic\n * maintenance jobs should call this directly so calibration is not gated\n * on weekly compounding being enabled.\n */\nexport async function runCalibrationIfEnabled(options: {\n memoryDir: string;\n calibrationEnabled: boolean;\n gatewayConfig?: GatewayConfig;\n gatewayAgentId?: string;\n modelChain?: AgentPersonaModelConfig;\n workspaceDir?: string;\n}): Promise<CalibrationRule[]> {\n if (!options.calibrationEnabled) {\n return [];\n }\n return runCalibrationConsolidation({\n memoryDir: options.memoryDir,\n gatewayConfig: options.gatewayConfig,\n gatewayAgentId: options.gatewayAgentId,\n modelChain: options.modelChain,\n workspaceDir: options.workspaceDir,\n });\n}\n\n/**\n * Get calibration rules for recall injection.\n * Reads the pre-computed calibration index.\n */\nexport async function getCalibrationRulesForRecall(\n memoryDir: string,\n): Promise<CalibrationRule[]> {\n const index = await readCalibrationIndex(memoryDir);\n return index.rules;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/calibration.ts"],"sourcesContent":["/**\n * calibration.ts — Prediction-Error-Driven Model-User Calibration\n *\n * Analyzes patterns in user corrections to identify systematic miscalibration\n * between the model's predictions and the user's actual expectations.\n * During consolidation, replays chains of similar corrections through an LLM\n * to synthesize CalibrationRules that adjust model behavior for this specific user.\n *\n * Inspired by:\n * - Cerebellar motor calibration (prediction errors drive lasting adjustments)\n * - Temporal difference learning (dopamine signals prediction error)\n * - Tesla FSD shadow mode (divergence between prediction and reality = training signal)\n */\n\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { FallbackLlmClient } from \"./fallback-llm.js\";\nimport type { AgentPersonaModelConfig, GatewayConfig, MemoryFile } from \"./types.js\";\nimport { listJsonFiles, readJsonFile } from \"./json-store.js\";\nimport { isRecord } from \"./store-contract.js\";\nimport { log } from \"./logger.js\";\nimport { OUTPUT_LANGUAGE_POLICY } from \"./extraction-prompt.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface CalibrationRule {\n id: string;\n ruleType: \"model_tendency\" | \"user_expectation\" | \"scope_boundary\" | \"verification_required\";\n condition: string;\n modelTendency: string;\n userExpectation: string;\n calibration: string;\n confidence: number;\n evidenceCount: number;\n evidenceCorrectionIds: string[];\n createdAt: string;\n lastReinforcedAt: string;\n}\n\nexport interface CalibrationIndex {\n rules: CalibrationRule[];\n updatedAt: string;\n totalCorrectionsAnalyzed: number;\n}\n\n// ─── Storage ─────────────────────────────────────────────────────────────────\n\nfunction calibrationDir(memoryDir: string): string {\n return path.join(memoryDir, \"state\", \"calibration\");\n}\n\nfunction calibrationIndexPath(memoryDir: string): string {\n return path.join(calibrationDir(memoryDir), \"calibration-index.json\");\n}\n\nexport async function readCalibrationIndex(memoryDir: string): Promise<CalibrationIndex> {\n try {\n const raw = JSON.parse(await readFile(calibrationIndexPath(memoryDir), \"utf8\"));\n return {\n rules: Array.isArray(raw.rules) ? raw.rules : [],\n updatedAt: typeof raw.updatedAt === \"string\" ? raw.updatedAt : new Date().toISOString(),\n totalCorrectionsAnalyzed: typeof raw.totalCorrectionsAnalyzed === \"number\" ? raw.totalCorrectionsAnalyzed : 0,\n };\n } catch {\n return { rules: [], updatedAt: new Date().toISOString(), totalCorrectionsAnalyzed: 0 };\n }\n}\n\nasync function writeCalibrationIndex(memoryDir: string, index: CalibrationIndex): Promise<void> {\n const dir = calibrationDir(memoryDir);\n await mkdir(dir, { recursive: true });\n index.updatedAt = new Date().toISOString();\n await writeFile(calibrationIndexPath(memoryDir), JSON.stringify(index, null, 2), \"utf8\");\n}\n\n// ─── Correction Reading ──────────────────────────────────────────────────────\n\nexport interface CorrectionMemory {\n id: string;\n content: string;\n created: string;\n confidence: number;\n entityRefs: string[];\n tags: string[];\n}\n\nconst CALIBRATION_RULE_TYPES = new Set([\n \"model_tendency\",\n \"user_expectation\",\n \"scope_boundary\",\n \"verification_required\",\n]);\n\nfunction parseConfidence(value: unknown): number | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return undefined;\n return Math.max(0, Math.min(1, value));\n}\n\nfunction parseEvidenceIds(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0);\n}\n\nfunction nonEmptyString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\n/**\n * Exported for entity-contamination R-11 regression coverage (#682\n * PR 2/3 — codex review). Tests can drive the real correction-reading\n * path instead of duplicating the regex inline, so calibration parser\n * regressions surface via the contamination suite.\n */\nexport async function readCalibrationCorrections(memoryDir: string): Promise<CorrectionMemory[]> {\n return readCorrectionsImpl(memoryDir);\n}\n\nasync function readCorrections(memoryDir: string): Promise<CorrectionMemory[]> {\n return readCorrectionsImpl(memoryDir);\n}\n\nasync function readCorrectionsImpl(memoryDir: string): Promise<CorrectionMemory[]> {\n const correctionsDir = path.join(memoryDir, \"corrections\");\n const files = await listJsonFiles(correctionsDir).catch(() => {\n // Corrections might be in facts/ directories too\n return [] as string[];\n });\n\n // Also scan facts directories for correction-category files\n const factsDir = path.join(memoryDir, \"facts\");\n try {\n const { readdir } = await import(\"node:fs/promises\");\n const dayDirs = (await readdir(factsDir)).filter((d: string) => /^\\d{4}-\\d{2}-\\d{2}$/.test(d));\n for (const day of dayDirs) {\n const dayPath = path.join(factsDir, day);\n const dayFiles = (await readdir(dayPath))\n .filter((f: string) => f.startsWith(\"correction-\") && f.endsWith(\".md\"))\n .map((f: string) => path.join(dayPath, f));\n files.push(...dayFiles);\n }\n } catch {\n // facts dir might not exist\n }\n\n // Also check the dedicated corrections directory\n try {\n const { readdir } = await import(\"node:fs/promises\");\n const corrFiles = (await readdir(correctionsDir))\n .filter((f: string) => f.endsWith(\".md\"))\n .map((f: string) => path.join(correctionsDir, f));\n files.push(...corrFiles);\n } catch {\n // corrections dir might not exist\n }\n\n const corrections: CorrectionMemory[] = [];\n const seen = new Set<string>();\n\n for (const filePath of files) {\n try {\n const raw = await readFile(filePath, \"utf8\");\n\n // Parse frontmatter\n const fmMatch = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n if (!fmMatch) continue;\n\n const content = fmMatch[2].trim();\n if (!content || content.length < 10) continue;\n\n // Extract id from frontmatter\n const idMatch = fmMatch[1].match(/^id:\\s*(.+)$/m);\n const id = idMatch?.[1]?.trim() ?? path.basename(filePath, \".md\");\n\n if (seen.has(id)) continue;\n seen.add(id);\n\n const confMatch = fmMatch[1].match(/^confidence:\\s*(.+)$/m);\n const confidence = confMatch ? parseFloat(confMatch[1]) : 0.9;\n\n const entityMatch = fmMatch[1].match(/^entityRef:\\s*(.+)$/m);\n const entityRefs = entityMatch ? [entityMatch[1].trim()] : [];\n\n corrections.push({ id, content, created: \"\", confidence, entityRefs, tags: [] });\n } catch {\n // skip unparseable files\n }\n }\n\n return corrections;\n}\n\n// ─── LLM-Assisted Clustering and Replay ──────────────────────────────────────\n\nexport const CLUSTER_PROMPT = `You are analyzing user corrections to an AI assistant. Each correction represents a moment where the assistant's prediction of what the user wanted was WRONG.\n\nYour job: Group these corrections into clusters where the SAME TYPE of misunderstanding is happening. Then for each cluster, synthesize a CalibrationRule.\n\nA CalibrationRule describes:\n- condition: When does this type of mistake happen?\n- modelTendency: What does the model tend to assume or do wrong?\n- userExpectation: What does the user actually want instead?\n- calibration: How should the model adjust its behavior?\n- ruleType: One of \"model_tendency\", \"user_expectation\", \"scope_boundary\", \"verification_required\"\n\nFocus on PATTERNS, not individual corrections. A cluster needs at least 2 corrections to be worth a rule.\n${OUTPUT_LANGUAGE_POLICY}\n\nOutput valid JSON only:\n{\n \"rules\": [\n {\n \"ruleType\": \"model_tendency\",\n \"condition\": \"When discussing project scope or task boundaries\",\n \"modelTendency\": \"The model tends to assume broader scope than the user intends\",\n \"userExpectation\": \"The user prefers narrow, specific task definitions and wants to be asked before scope expansion\",\n \"calibration\": \"When uncertain about scope, ask for clarification rather than assuming. Default to the narrower interpretation.\",\n \"confidence\": 0.85,\n \"evidenceIds\": [\"correction-id-1\", \"correction-id-2\"]\n }\n ]\n}`;\n\nexport async function synthesizeCalibrationRules(\n corrections: CorrectionMemory[],\n llm: FallbackLlmClient,\n existingRules: CalibrationRule[],\n agentId?: string,\n modelChain?: AgentPersonaModelConfig,\n): Promise<CalibrationRule[]> {\n if (corrections.length < 2) return [];\n\n // Format corrections for the LLM\n const correctionText = corrections\n .slice(0, 50) // limit to avoid huge prompts\n .map((c, i) => `[${c.id}] ${c.content}`)\n .join(\"\\n\\n\");\n\n const existingRulesText = existingRules.length > 0\n ? `\\n\\nExisting calibration rules (avoid duplicating these):\\n${existingRules.map((r) => `- ${r.condition}: ${r.calibration}`).join(\"\\n\")}`\n : \"\";\n\n const response = await llm.chatCompletion(\n [\n { role: \"system\", content: CLUSTER_PROMPT },\n { role: \"user\", content: `Here are ${corrections.length} corrections from this user:\\n\\n${correctionText}${existingRulesText}` },\n ],\n { temperature: 0.3, maxTokens: 3000, agentId, modelChain },\n );\n\n if (!response?.content) return [];\n\n try {\n let jsonStr = response.content.trim();\n const fenceMatch = jsonStr.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/);\n if (fenceMatch) jsonStr = fenceMatch[1];\n\n const parsed = JSON.parse(jsonStr);\n if (!Array.isArray(parsed.rules)) return [];\n\n const now = new Date().toISOString();\n const rawRules: unknown[] = Array.isArray(parsed.rules) ? parsed.rules : [];\n return rawRules\n .map((r: unknown): CalibrationRule | undefined => {\n if (!r || typeof r !== \"object\" || Array.isArray(r)) return undefined;\n const raw = r as Record<string, unknown>;\n const ruleType = nonEmptyString(raw.ruleType);\n const condition = nonEmptyString(raw.condition);\n const modelTendency = nonEmptyString(raw.modelTendency);\n const calibration = nonEmptyString(raw.calibration);\n const confidence = parseConfidence(raw.confidence);\n if (\n !ruleType ||\n !CALIBRATION_RULE_TYPES.has(ruleType) ||\n !condition ||\n !modelTendency ||\n !calibration ||\n confidence === undefined\n ) {\n return undefined;\n }\n const evidenceCorrectionIds = parseEvidenceIds(raw.evidenceIds);\n return {\n id: `cal-${createHash(\"sha256\").update(condition + calibration).digest(\"hex\").slice(0, 12)}`,\n ruleType: ruleType as CalibrationRule[\"ruleType\"],\n condition,\n modelTendency,\n userExpectation: nonEmptyString(raw.userExpectation) ?? \"\",\n calibration,\n confidence,\n evidenceCount: evidenceCorrectionIds.length,\n evidenceCorrectionIds,\n createdAt: now,\n lastReinforcedAt: now,\n };\n })\n .filter((rule): rule is CalibrationRule => !!rule);\n } catch {\n log.warn(\"[calibration] failed to parse LLM response\");\n return [];\n }\n}\n\n// ─── Recall Section ──────────────────────────────────────────────────────────\n\n/**\n * Build a recall section from calibration rules relevant to the current query.\n * Uses the LLM to select which rules apply to the current context.\n */\nexport function buildCalibrationRecallSection(\n rules: CalibrationRule[],\n query: string,\n maxChars: number = 1200,\n): string | null {\n if (rules.length === 0) return null;\n\n // Simple relevance: include all rules (they're already filtered to this user)\n // In production, could use embedding similarity to filter\n const lines: string[] = [\n \"## Model Calibration (learned from past corrections)\",\n \"\",\n \"Adjustments for this specific user, learned from patterns in their corrections:\",\n \"\",\n ];\n\n let totalChars = lines.join(\"\\n\").length;\n\n for (const rule of rules) {\n const line = `- **${rule.condition}**: ${rule.modelTendency} → Instead: ${rule.calibration}`;\n if (totalChars + line.length + 1 > maxChars) break;\n lines.push(line);\n totalChars += line.length + 1;\n }\n\n if (lines.length <= 4) return null;\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Run the full calibration pipeline:\n * 1. Read all corrections\n * 2. Send to LLM for clustering and rule synthesis\n * 3. Merge with existing rules\n * 4. Write updated index\n */\nexport async function runCalibrationConsolidation(options: {\n memoryDir: string;\n gatewayConfig?: GatewayConfig;\n gatewayAgentId?: string;\n modelChain?: AgentPersonaModelConfig;\n workspaceDir?: string;\n}): Promise<CalibrationRule[]> {\n try {\n const llm = new FallbackLlmClient(options.gatewayConfig, {\n workspaceDir: options.workspaceDir,\n });\n if (!llm.isAvailable({ agentId: options.gatewayAgentId, modelChain: options.modelChain })) {\n log.debug(\"[calibration] no LLM available — skipping consolidation\");\n return [];\n }\n\n const corrections = await readCorrections(options.memoryDir);\n if (corrections.length < 3) {\n log.debug(`[calibration] only ${corrections.length} corrections — need at least 3`);\n return [];\n }\n\n const existingIndex = await readCalibrationIndex(options.memoryDir);\n\n const newRules = await synthesizeCalibrationRules(corrections, llm, existingIndex.rules, options.gatewayAgentId, options.modelChain);\n if (newRules.length === 0) {\n log.debug(\"[calibration] no new calibration rules synthesized\");\n return existingIndex.rules;\n }\n\n // Merge: keep existing rules, add new ones (deduplicate by id)\n const ruleMap = new Map(existingIndex.rules.map((r) => [r.id, r]));\n for (const rule of newRules) {\n if (ruleMap.has(rule.id)) {\n // Reinforce existing rule\n const existing = ruleMap.get(rule.id)!;\n existing.lastReinforcedAt = new Date().toISOString();\n existing.evidenceCount += rule.evidenceCount;\n existing.confidence = Math.min(1, existing.confidence + 0.05);\n } else {\n ruleMap.set(rule.id, rule);\n }\n }\n\n const allRules = [...ruleMap.values()];\n await writeCalibrationIndex(options.memoryDir, {\n rules: allRules,\n updatedAt: new Date().toISOString(),\n totalCorrectionsAnalyzed: corrections.length,\n });\n\n log.debug(`[calibration] synthesized ${newRules.length} new rule(s), ${allRules.length} total`);\n return allRules;\n } catch (error) {\n log.warn(`[calibration] consolidation failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);\n return [];\n }\n}\n\n/**\n * Standalone entry point for calibration consolidation that can be called\n * independently of weekly compounding. The compounding engine's\n * `synthesizeWeekly()` is one trigger, but orchestrators or periodic\n * maintenance jobs should call this directly so calibration is not gated\n * on weekly compounding being enabled.\n */\nexport async function runCalibrationIfEnabled(options: {\n memoryDir: string;\n calibrationEnabled: boolean;\n gatewayConfig?: GatewayConfig;\n gatewayAgentId?: string;\n modelChain?: AgentPersonaModelConfig;\n workspaceDir?: string;\n}): Promise<CalibrationRule[]> {\n if (!options.calibrationEnabled) {\n return [];\n }\n return runCalibrationConsolidation({\n memoryDir: options.memoryDir,\n gatewayConfig: options.gatewayConfig,\n gatewayAgentId: options.gatewayAgentId,\n modelChain: options.modelChain,\n workspaceDir: options.workspaceDir,\n });\n}\n\n/**\n * Get calibration rules for recall injection.\n * Reads the pre-computed calibration index.\n */\nexport async function getCalibrationRulesForRecall(\n memoryDir: string,\n): Promise<CalibrationRule[]> {\n const index = await readCalibrationIndex(memoryDir);\n return index.rules;\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createVersion
3
- } from "./chunk-E7UQOS4C.js";
3
+ } from "./chunk-JPKK466T.js";
4
4
  import {
5
5
  bumpMemoryCorpusVersionForDir
6
6
  } from "./chunk-XCB6QDL6.js";
@@ -13,7 +13,7 @@ import {
13
13
  repairContentAfterJournalMove,
14
14
  requestEntityCanonicalIdReconcile,
15
15
  withRawEntityPageMutation
16
- } from "./chunk-NNZFPYYX.js";
16
+ } from "./chunk-R7QY5ZVB.js";
17
17
  import "./chunk-5WITETWU.js";
18
18
  import "./chunk-6CIAGZ6X.js";
19
19
  import "./chunk-C64XATK7.js";
@@ -30,7 +30,7 @@ import {
30
30
  sha256String
31
31
  } from "./chunk-GCGJW34D.js";
32
32
  import "./chunk-VS2IYZRU.js";
33
- import "./chunk-5UZXUTVO.js";
33
+ import "./chunk-KNA3BXXL.js";
34
34
  import "./chunk-3WCASNQZ.js";
35
35
  import "./chunk-PZ5AY32C.js";
36
36
 
@@ -277,4 +277,4 @@ async function readLocalFile(absPath) {
277
277
  export {
278
278
  mergeCapsule
279
279
  };
280
- //# sourceMappingURL=capsule-merge-CU6QJBSV.js.map
280
+ //# sourceMappingURL=capsule-merge-IPG4IOFP.js.map
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  readChainIndex,
3
3
  resolveChainsDir
4
- } from "./chunk-EYMPUXAN.js";
4
+ } from "./chunk-LO4UKPKX.js";
5
5
  import "./chunk-B7RWBZXW.js";
6
6
  import {
7
7
  resolveCausalTrajectoryStoreDir
8
- } from "./chunk-DSCCM66R.js";
8
+ } from "./chunk-B3O3IRZN.js";
9
9
  import {
10
10
  normalizeRecallTokens
11
11
  } from "./chunk-YCVB7X56.js";
@@ -15,7 +15,8 @@ import {
15
15
  import {
16
16
  listJsonFiles,
17
17
  readJsonFile
18
- } from "./chunk-P77QX3ID.js";
18
+ } from "./chunk-B6O2YLUR.js";
19
+ import "./chunk-KNA3BXXL.js";
19
20
  import {
20
21
  log
21
22
  } from "./chunk-3WCASNQZ.js";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/causal-behavior.ts"],"sourcesContent":["/**\n * causal-behavior.ts — CMC Phase 4: Implicit Behavioral Preference Learning\n *\n * Extracts behavioral signals from causal chain analysis. Unlike explicit\n * preference extraction (which reads text), this derives preferences from\n * patterns of action: what goals recur, what actions succeed repeatedly,\n * what outcomes are consistently pursued.\n *\n * Key insight: \"Preferences are recurring causal pathways.\"\n */\n\nimport { resolveCausalTrajectoryStoreDir, type CausalTrajectoryRecord } from \"./causal-trajectory.js\";\nimport type { CausalChainIndex } from \"./causal-chain.js\";\nimport { readChainIndex, resolveChainsDir } from \"./causal-chain.js\";\nimport { normalizeRecallTokens } from \"./recall-tokenization.js\";\nimport { topicOverlapScore } from \"./boxes.js\";\nimport { listJsonFiles, readJsonFile } from \"./json-store.js\";\nimport { isRecord } from \"./store-contract.js\";\nimport type { ConsolidatedPreference } from \"./compounding/preference-consolidator.js\";\nimport path from \"node:path\";\nimport { log } from \"./logger.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type CausalBehaviorSignalType =\n | \"topic_revisitation\"\n | \"action_pattern\"\n | \"outcome_preference\"\n | \"phrasing_style\";\n\nexport interface CausalBehaviorSignal {\n signalType: CausalBehaviorSignalType;\n pattern: string;\n frequency: number;\n sessionCount: number;\n confidence: number;\n trajectoryIds: string[];\n}\n\nexport interface BehaviorConfig {\n minFrequency: number;\n minSessions: number;\n confidenceThreshold: number;\n}\n\n// ─── Signal Extraction ───────────────────────────────────────────────────────\n\n/**\n * Detect topic revisitation: same goal fingerprint appearing in 3+ sessions.\n */\nfunction detectTopicRevisitation(\n trajectories: CausalTrajectoryRecord[],\n config: BehaviorConfig,\n): CausalBehaviorSignal[] {\n const goalGroups = new Map<string, { sessions: Set<string>; trajectoryIds: string[]; goal: string }>();\n\n for (const t of trajectories) {\n const tokens = normalizeRecallTokens(t.goal, []).sort().join(\" \");\n if (!tokens) continue;\n const group = goalGroups.get(tokens) ?? { sessions: new Set(), trajectoryIds: [], goal: t.goal };\n group.sessions.add(t.sessionKey);\n group.trajectoryIds.push(t.trajectoryId);\n goalGroups.set(tokens, group);\n }\n\n const signals: CausalBehaviorSignal[] = [];\n for (const [_key, group] of goalGroups) {\n if (group.trajectoryIds.length < config.minFrequency) continue;\n if (group.sessions.size < config.minSessions) continue;\n\n signals.push({\n signalType: \"topic_revisitation\",\n pattern: group.goal,\n frequency: group.trajectoryIds.length,\n sessionCount: group.sessions.size,\n confidence: Math.min(1, 0.5 + (group.sessions.size / 10)),\n trajectoryIds: group.trajectoryIds.slice(0, 10),\n });\n }\n\n return signals;\n}\n\n/**\n * Detect action patterns: same action with >= 80% success rate, 4+ occurrences.\n */\nfunction detectActionPatterns(\n trajectories: CausalTrajectoryRecord[],\n config: BehaviorConfig,\n): CausalBehaviorSignal[] {\n const actionGroups = new Map<string, {\n sessions: Set<string>;\n trajectoryIds: string[];\n action: string;\n successCount: number;\n totalCount: number;\n }>();\n\n for (const t of trajectories) {\n const tokens = normalizeRecallTokens(t.actionSummary, []).sort().join(\" \");\n if (!tokens) continue;\n const group = actionGroups.get(tokens) ?? {\n sessions: new Set(),\n trajectoryIds: [],\n action: t.actionSummary,\n successCount: 0,\n totalCount: 0,\n };\n group.sessions.add(t.sessionKey);\n group.trajectoryIds.push(t.trajectoryId);\n group.totalCount++;\n if (t.outcomeKind === \"success\") group.successCount++;\n actionGroups.set(tokens, group);\n }\n\n const signals: CausalBehaviorSignal[] = [];\n for (const [_key, group] of actionGroups) {\n if (group.totalCount < Math.max(config.minFrequency, 4)) continue;\n if (group.sessions.size < config.minSessions) continue;\n const successRate = group.successCount / group.totalCount;\n if (successRate < 0.8) continue;\n\n signals.push({\n signalType: \"action_pattern\",\n pattern: group.action,\n frequency: group.totalCount,\n sessionCount: group.sessions.size,\n confidence: Math.min(1, 0.6 + (successRate * 0.3)),\n trajectoryIds: group.trajectoryIds.slice(0, 10),\n });\n }\n\n return signals;\n}\n\n/**\n * Detect outcome preferences: consistent retry patterns leading to success.\n * When a trajectory fails and is retried (via chain edges) successfully,\n * it indicates a strong preference for that outcome.\n */\nfunction detectOutcomePreferences(\n trajectories: CausalTrajectoryRecord[],\n chainIndex: CausalChainIndex,\n config: BehaviorConfig,\n): CausalBehaviorSignal[] {\n const retrySuccesses = new Map<string, {\n sessions: Set<string>;\n trajectoryIds: string[];\n goal: string;\n count: number;\n }>();\n\n const trajectoryMap = new Map(trajectories.map((t) => [t.trajectoryId, t]));\n\n for (const [edgeId, edge] of Object.entries(chainIndex.edges)) {\n if (edge.edgeType !== \"retry\") continue;\n\n const from = trajectoryMap.get(edge.fromTrajectoryId);\n const to = trajectoryMap.get(edge.toTrajectoryId);\n if (!from || !to) continue;\n if (from.outcomeKind !== \"failure\" || to.outcomeKind !== \"success\") continue;\n\n const goalTokens = normalizeRecallTokens(from.goal, []).sort().join(\" \");\n const group = retrySuccesses.get(goalTokens) ?? {\n sessions: new Set(),\n trajectoryIds: [],\n goal: from.goal,\n count: 0,\n };\n group.sessions.add(from.sessionKey);\n group.sessions.add(to.sessionKey);\n group.trajectoryIds.push(from.trajectoryId, to.trajectoryId);\n group.count++;\n retrySuccesses.set(goalTokens, group);\n }\n\n const signals: CausalBehaviorSignal[] = [];\n for (const [_key, group] of retrySuccesses) {\n if (group.count < config.minFrequency) continue;\n if (group.sessions.size < config.minSessions) continue;\n\n signals.push({\n signalType: \"outcome_preference\",\n pattern: group.goal,\n frequency: group.count,\n sessionCount: group.sessions.size,\n confidence: Math.min(1, 0.7 + (group.count / 20)),\n trajectoryIds: [...new Set(group.trajectoryIds)].slice(0, 10),\n });\n }\n\n return signals;\n}\n\n// ─── Preference Synthesis ────────────────────────────────────────────────────\n\n/**\n * Convert behavioral signals into ConsolidatedPreference entries\n * that can be merged with existing IRC preference output.\n */\nexport function synthesizeCausalPreferences(\n signals: CausalBehaviorSignal[],\n confidenceThreshold: number,\n): ConsolidatedPreference[] {\n const preferences: ConsolidatedPreference[] = [];\n\n for (const signal of signals) {\n if (signal.confidence < confidenceThreshold) continue;\n\n let statement: string;\n switch (signal.signalType) {\n case \"topic_revisitation\":\n statement = `The user frequently works on: ${signal.pattern}. This topic has been revisited across ${signal.sessionCount} sessions.`;\n break;\n case \"action_pattern\":\n statement = `The user prefers this approach: ${signal.pattern}. This action pattern has been successful ${signal.frequency} times.`;\n break;\n case \"outcome_preference\":\n statement = `The user persistently pursues: ${signal.pattern}. They retry until successful, indicating strong preference.`;\n break;\n case \"phrasing_style\":\n statement = `The user's phrasing pattern: ${signal.pattern}`;\n break;\n }\n\n preferences.push({\n statement,\n sourceIds: signal.trajectoryIds.slice(0, 5),\n category: \"preference\",\n confidence: signal.confidence,\n keywords: normalizeRecallTokens(signal.pattern, []).slice(0, 10),\n });\n }\n\n return preferences;\n}\n\n// ─── Causal Impact Score ─────────────────────────────────────────────────────\n\n/**\n * Compute the causal impact score for a memory based on its\n * presence in causal chains. Used in lifecycle heat/decay.\n *\n * Formula: 0.1 * incomingEdges + 0.15 * outgoingEdges, clamped to [0, 0.3]\n */\nexport function computeCausalImpactScore(\n memoryId: string,\n chainIndex: CausalChainIndex,\n): number {\n // Memory IDs don't directly map to trajectory IDs, but trajectory-based\n // memories may reference their source trajectory ID. For now, check\n // if the memoryId appears as a trajectory ID in the chain index.\n const incoming = chainIndex.incoming[memoryId]?.length ?? 0;\n const outgoing = chainIndex.outgoing[memoryId]?.length ?? 0;\n const raw = 0.1 * incoming + 0.15 * outgoing;\n return Math.min(0.3, Math.max(0, raw));\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Extract all behavioral signals from causal trajectories and chain analysis.\n */\nexport async function extractCausalBehaviorSignals(options: {\n memoryDir: string;\n causalTrajectoryStoreDir?: string;\n config: BehaviorConfig;\n}): Promise<CausalBehaviorSignal[]> {\n try {\n const { memoryDir, causalTrajectoryStoreDir, config: behaviorConfig } = options;\n\n // Read all trajectories\n const root = resolveCausalTrajectoryStoreDir(memoryDir, causalTrajectoryStoreDir);\n const trajectoriesDir = path.join(root, \"trajectories\");\n const files = await listJsonFiles(trajectoriesDir).catch(() => [] as string[]);\n\n const trajectories: CausalTrajectoryRecord[] = [];\n for (const filePath of files) {\n try {\n const raw = await readJsonFile(filePath);\n if (isRecord(raw) && typeof raw.trajectoryId === \"string\") {\n trajectories.push(raw as unknown as CausalTrajectoryRecord);\n }\n } catch {\n // skip\n }\n }\n\n if (trajectories.length === 0) return [];\n\n // Read chain index\n const chainsDir = resolveChainsDir(memoryDir, causalTrajectoryStoreDir);\n const chainIndex = await readChainIndex(chainsDir);\n\n // Extract all signal types\n const signals: CausalBehaviorSignal[] = [\n ...detectTopicRevisitation(trajectories, behaviorConfig),\n ...detectActionPatterns(trajectories, behaviorConfig),\n ...detectOutcomePreferences(trajectories, chainIndex, behaviorConfig),\n ];\n\n log.debug(`[cmc] extracted ${signals.length} behavioral signal(s) from ${trajectories.length} trajectories`);\n return signals;\n } catch (error) {\n log.warn(`[cmc] behavioral signal extraction failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);\n return [];\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/causal-behavior.ts"],"sourcesContent":["/**\n * causal-behavior.ts — CMC Phase 4: Implicit Behavioral Preference Learning\n *\n * Extracts behavioral signals from causal chain analysis. Unlike explicit\n * preference extraction (which reads text), this derives preferences from\n * patterns of action: what goals recur, what actions succeed repeatedly,\n * what outcomes are consistently pursued.\n *\n * Key insight: \"Preferences are recurring causal pathways.\"\n */\n\nimport { resolveCausalTrajectoryStoreDir, type CausalTrajectoryRecord } from \"./causal-trajectory.js\";\nimport type { CausalChainIndex } from \"./causal-chain.js\";\nimport { readChainIndex, resolveChainsDir } from \"./causal-chain.js\";\nimport { normalizeRecallTokens } from \"./recall-tokenization.js\";\nimport { topicOverlapScore } from \"./boxes.js\";\nimport { listJsonFiles, readJsonFile } from \"./json-store.js\";\nimport { isRecord } from \"./store-contract.js\";\nimport type { ConsolidatedPreference } from \"./compounding/preference-consolidator.js\";\nimport path from \"node:path\";\nimport { log } from \"./logger.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type CausalBehaviorSignalType =\n | \"topic_revisitation\"\n | \"action_pattern\"\n | \"outcome_preference\"\n | \"phrasing_style\";\n\nexport interface CausalBehaviorSignal {\n signalType: CausalBehaviorSignalType;\n pattern: string;\n frequency: number;\n sessionCount: number;\n confidence: number;\n trajectoryIds: string[];\n}\n\nexport interface BehaviorConfig {\n minFrequency: number;\n minSessions: number;\n confidenceThreshold: number;\n}\n\n// ─── Signal Extraction ───────────────────────────────────────────────────────\n\n/**\n * Detect topic revisitation: same goal fingerprint appearing in 3+ sessions.\n */\nfunction detectTopicRevisitation(\n trajectories: CausalTrajectoryRecord[],\n config: BehaviorConfig,\n): CausalBehaviorSignal[] {\n const goalGroups = new Map<string, { sessions: Set<string>; trajectoryIds: string[]; goal: string }>();\n\n for (const t of trajectories) {\n const tokens = normalizeRecallTokens(t.goal, []).sort().join(\" \");\n if (!tokens) continue;\n const group = goalGroups.get(tokens) ?? { sessions: new Set(), trajectoryIds: [], goal: t.goal };\n group.sessions.add(t.sessionKey);\n group.trajectoryIds.push(t.trajectoryId);\n goalGroups.set(tokens, group);\n }\n\n const signals: CausalBehaviorSignal[] = [];\n for (const [_key, group] of goalGroups) {\n if (group.trajectoryIds.length < config.minFrequency) continue;\n if (group.sessions.size < config.minSessions) continue;\n\n signals.push({\n signalType: \"topic_revisitation\",\n pattern: group.goal,\n frequency: group.trajectoryIds.length,\n sessionCount: group.sessions.size,\n confidence: Math.min(1, 0.5 + (group.sessions.size / 10)),\n trajectoryIds: group.trajectoryIds.slice(0, 10),\n });\n }\n\n return signals;\n}\n\n/**\n * Detect action patterns: same action with >= 80% success rate, 4+ occurrences.\n */\nfunction detectActionPatterns(\n trajectories: CausalTrajectoryRecord[],\n config: BehaviorConfig,\n): CausalBehaviorSignal[] {\n const actionGroups = new Map<string, {\n sessions: Set<string>;\n trajectoryIds: string[];\n action: string;\n successCount: number;\n totalCount: number;\n }>();\n\n for (const t of trajectories) {\n const tokens = normalizeRecallTokens(t.actionSummary, []).sort().join(\" \");\n if (!tokens) continue;\n const group = actionGroups.get(tokens) ?? {\n sessions: new Set(),\n trajectoryIds: [],\n action: t.actionSummary,\n successCount: 0,\n totalCount: 0,\n };\n group.sessions.add(t.sessionKey);\n group.trajectoryIds.push(t.trajectoryId);\n group.totalCount++;\n if (t.outcomeKind === \"success\") group.successCount++;\n actionGroups.set(tokens, group);\n }\n\n const signals: CausalBehaviorSignal[] = [];\n for (const [_key, group] of actionGroups) {\n if (group.totalCount < Math.max(config.minFrequency, 4)) continue;\n if (group.sessions.size < config.minSessions) continue;\n const successRate = group.successCount / group.totalCount;\n if (successRate < 0.8) continue;\n\n signals.push({\n signalType: \"action_pattern\",\n pattern: group.action,\n frequency: group.totalCount,\n sessionCount: group.sessions.size,\n confidence: Math.min(1, 0.6 + (successRate * 0.3)),\n trajectoryIds: group.trajectoryIds.slice(0, 10),\n });\n }\n\n return signals;\n}\n\n/**\n * Detect outcome preferences: consistent retry patterns leading to success.\n * When a trajectory fails and is retried (via chain edges) successfully,\n * it indicates a strong preference for that outcome.\n */\nfunction detectOutcomePreferences(\n trajectories: CausalTrajectoryRecord[],\n chainIndex: CausalChainIndex,\n config: BehaviorConfig,\n): CausalBehaviorSignal[] {\n const retrySuccesses = new Map<string, {\n sessions: Set<string>;\n trajectoryIds: string[];\n goal: string;\n count: number;\n }>();\n\n const trajectoryMap = new Map(trajectories.map((t) => [t.trajectoryId, t]));\n\n for (const [edgeId, edge] of Object.entries(chainIndex.edges)) {\n if (edge.edgeType !== \"retry\") continue;\n\n const from = trajectoryMap.get(edge.fromTrajectoryId);\n const to = trajectoryMap.get(edge.toTrajectoryId);\n if (!from || !to) continue;\n if (from.outcomeKind !== \"failure\" || to.outcomeKind !== \"success\") continue;\n\n const goalTokens = normalizeRecallTokens(from.goal, []).sort().join(\" \");\n const group = retrySuccesses.get(goalTokens) ?? {\n sessions: new Set(),\n trajectoryIds: [],\n goal: from.goal,\n count: 0,\n };\n group.sessions.add(from.sessionKey);\n group.sessions.add(to.sessionKey);\n group.trajectoryIds.push(from.trajectoryId, to.trajectoryId);\n group.count++;\n retrySuccesses.set(goalTokens, group);\n }\n\n const signals: CausalBehaviorSignal[] = [];\n for (const [_key, group] of retrySuccesses) {\n if (group.count < config.minFrequency) continue;\n if (group.sessions.size < config.minSessions) continue;\n\n signals.push({\n signalType: \"outcome_preference\",\n pattern: group.goal,\n frequency: group.count,\n sessionCount: group.sessions.size,\n confidence: Math.min(1, 0.7 + (group.count / 20)),\n trajectoryIds: [...new Set(group.trajectoryIds)].slice(0, 10),\n });\n }\n\n return signals;\n}\n\n// ─── Preference Synthesis ────────────────────────────────────────────────────\n\n/**\n * Convert behavioral signals into ConsolidatedPreference entries\n * that can be merged with existing IRC preference output.\n */\nexport function synthesizeCausalPreferences(\n signals: CausalBehaviorSignal[],\n confidenceThreshold: number,\n): ConsolidatedPreference[] {\n const preferences: ConsolidatedPreference[] = [];\n\n for (const signal of signals) {\n if (signal.confidence < confidenceThreshold) continue;\n\n let statement: string;\n switch (signal.signalType) {\n case \"topic_revisitation\":\n statement = `The user frequently works on: ${signal.pattern}. This topic has been revisited across ${signal.sessionCount} sessions.`;\n break;\n case \"action_pattern\":\n statement = `The user prefers this approach: ${signal.pattern}. This action pattern has been successful ${signal.frequency} times.`;\n break;\n case \"outcome_preference\":\n statement = `The user persistently pursues: ${signal.pattern}. They retry until successful, indicating strong preference.`;\n break;\n case \"phrasing_style\":\n statement = `The user's phrasing pattern: ${signal.pattern}`;\n break;\n }\n\n preferences.push({\n statement,\n sourceIds: signal.trajectoryIds.slice(0, 5),\n category: \"preference\",\n confidence: signal.confidence,\n keywords: normalizeRecallTokens(signal.pattern, []).slice(0, 10),\n });\n }\n\n return preferences;\n}\n\n// ─── Causal Impact Score ─────────────────────────────────────────────────────\n\n/**\n * Compute the causal impact score for a memory based on its\n * presence in causal chains. Used in lifecycle heat/decay.\n *\n * Formula: 0.1 * incomingEdges + 0.15 * outgoingEdges, clamped to [0, 0.3]\n */\nexport function computeCausalImpactScore(\n memoryId: string,\n chainIndex: CausalChainIndex,\n): number {\n // Memory IDs don't directly map to trajectory IDs, but trajectory-based\n // memories may reference their source trajectory ID. For now, check\n // if the memoryId appears as a trajectory ID in the chain index.\n const incoming = chainIndex.incoming[memoryId]?.length ?? 0;\n const outgoing = chainIndex.outgoing[memoryId]?.length ?? 0;\n const raw = 0.1 * incoming + 0.15 * outgoing;\n return Math.min(0.3, Math.max(0, raw));\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Extract all behavioral signals from causal trajectories and chain analysis.\n */\nexport async function extractCausalBehaviorSignals(options: {\n memoryDir: string;\n causalTrajectoryStoreDir?: string;\n config: BehaviorConfig;\n}): Promise<CausalBehaviorSignal[]> {\n try {\n const { memoryDir, causalTrajectoryStoreDir, config: behaviorConfig } = options;\n\n // Read all trajectories\n const root = resolveCausalTrajectoryStoreDir(memoryDir, causalTrajectoryStoreDir);\n const trajectoriesDir = path.join(root, \"trajectories\");\n const files = await listJsonFiles(trajectoriesDir).catch(() => [] as string[]);\n\n const trajectories: CausalTrajectoryRecord[] = [];\n for (const filePath of files) {\n try {\n const raw = await readJsonFile(filePath);\n if (isRecord(raw) && typeof raw.trajectoryId === \"string\") {\n trajectories.push(raw as unknown as CausalTrajectoryRecord);\n }\n } catch {\n // skip\n }\n }\n\n if (trajectories.length === 0) return [];\n\n // Read chain index\n const chainsDir = resolveChainsDir(memoryDir, causalTrajectoryStoreDir);\n const chainIndex = await readChainIndex(chainsDir);\n\n // Extract all signal types\n const signals: CausalBehaviorSignal[] = [\n ...detectTopicRevisitation(trajectories, behaviorConfig),\n ...detectActionPatterns(trajectories, behaviorConfig),\n ...detectOutcomePreferences(trajectories, chainIndex, behaviorConfig),\n ];\n\n log.debug(`[cmc] extracted ${signals.length} behavioral signal(s) from ${trajectories.length} trajectories`);\n return signals;\n } catch (error) {\n log.warn(`[cmc] behavioral signal extraction failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);\n return [];\n }\n}\n"],"mappings":"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","names":[]}
@@ -6,12 +6,13 @@ import {
6
6
  stitchCausalChain,
7
7
  validateCausalEdge,
8
8
  writeChainIndex
9
- } from "./chunk-EYMPUXAN.js";
9
+ } from "./chunk-LO4UKPKX.js";
10
10
  import "./chunk-B7RWBZXW.js";
11
- import "./chunk-DSCCM66R.js";
11
+ import "./chunk-B3O3IRZN.js";
12
12
  import "./chunk-YCVB7X56.js";
13
13
  import "./chunk-A2IYSXDQ.js";
14
- import "./chunk-P77QX3ID.js";
14
+ import "./chunk-B6O2YLUR.js";
15
+ import "./chunk-KNA3BXXL.js";
15
16
  import "./chunk-3WCASNQZ.js";
16
17
  import "./chunk-PZ5AY32C.js";
17
18
  export {