@remnic/core 9.69.44 → 9.69.46

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 (533) hide show
  1. package/dist/access-admin-ops-surface.d.ts +14 -14
  2. package/dist/access-admin-ops-surface.js +36 -36
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-authorization-probe.d.ts +14 -14
  5. package/dist/access-authorization-probe.js +37 -37
  6. package/dist/access-boundary.d.ts +14 -14
  7. package/dist/access-boundary.js +36 -36
  8. package/dist/access-cli.js +90 -87
  9. package/dist/access-cli.js.map +1 -1
  10. package/dist/access-coding-context-resolution.d.ts +1 -1
  11. package/dist/access-extraction-force-flush.d.ts +14 -14
  12. package/dist/access-extraction-force-flush.js +36 -36
  13. package/dist/access-health-types.d.ts +1 -1
  14. package/dist/access-http-briefing.d.ts +14 -14
  15. package/dist/access-http-briefing.js +37 -37
  16. package/dist/access-http-lcm-compaction.d.ts +14 -14
  17. package/dist/access-http-lifecycle-flush.d.ts +14 -14
  18. package/dist/access-http-offline-stream.d.ts +14 -14
  19. package/dist/access-http-query.d.ts +2 -2
  20. package/dist/access-http-query.js +38 -38
  21. package/dist/access-http.d.ts +15 -15
  22. package/dist/access-http.js +52 -52
  23. package/dist/access-identity-continuity-surface.d.ts +11 -11
  24. package/dist/access-identity-continuity-surface.js +36 -36
  25. package/dist/access-lcm-surface.d.ts +14 -14
  26. package/dist/access-lcm-surface.js +36 -36
  27. package/dist/access-mcp-shared-context-tools.d.ts +14 -14
  28. package/dist/access-mcp.d.ts +14 -14
  29. package/dist/access-mcp.js +44 -44
  30. package/dist/access-memory-search-fanout.d.ts +2 -2
  31. package/dist/{access-namespace-preflight-CE-RrXKu.d.ts → access-namespace-preflight-DDnsN22V.d.ts} +1 -1
  32. package/dist/access-namespace-preflight.d.ts +3 -3
  33. package/dist/access-namespace-preflight.js +36 -36
  34. package/dist/access-observe-transcript.d.ts +11 -11
  35. package/dist/access-observe-write-category.d.ts +3 -3
  36. package/dist/access-observe-write-category.js +4 -4
  37. package/dist/access-observe-write-surface.d.ts +14 -14
  38. package/dist/access-observe-write-surface.js +36 -36
  39. package/dist/access-offline-manifest.d.ts +11 -11
  40. package/dist/access-offline-manifest.js +3 -3
  41. package/dist/access-operations-batch.js +37 -37
  42. package/dist/access-operations.d.ts +14 -14
  43. package/dist/access-operations.js +43 -43
  44. package/dist/access-recall-concurrency.d.ts +14 -14
  45. package/dist/access-recall-concurrency.js +36 -36
  46. package/dist/access-recall-response.d.ts +14 -14
  47. package/dist/access-recall-response.js +36 -36
  48. package/dist/access-recall-surface.d.ts +14 -14
  49. package/dist/access-recall-surface.js +36 -36
  50. package/dist/access-schema.d.ts +114 -114
  51. package/dist/access-schema.js +3 -3
  52. package/dist/{access-service-Cww3xAAy.d.ts → access-service-DGynYlbE.d.ts} +73 -73
  53. package/dist/access-service-helpers.d.ts +14 -14
  54. package/dist/access-service.d.ts +14 -14
  55. package/dist/access-service.js +36 -36
  56. package/dist/access-surface-catalog.d.ts +14 -14
  57. package/dist/access-surface-catalog.js +38 -38
  58. package/dist/access-wearables-meetings-surface.d.ts +4 -4
  59. package/dist/action-confidence.d.ts +1 -1
  60. package/dist/active-memory-bridge.d.ts +1 -1
  61. package/dist/active-recall.d.ts +1 -1
  62. package/dist/activity/digest.d.ts +1 -1
  63. package/dist/ambient-provenance.d.ts +1 -1
  64. package/dist/artifact-search.d.ts +1 -1
  65. package/dist/{auto-sync-QZD4RD6H.js → auto-sync-DG5KEOF5.js} +5 -5
  66. package/dist/background-generation.d.ts +1 -1
  67. package/dist/behavior-learner.d.ts +1 -1
  68. package/dist/behavior-signals.d.ts +1 -1
  69. package/dist/bootstrap.d.ts +11 -11
  70. package/dist/briefing-window.d.ts +2 -2
  71. package/dist/briefing.d.ts +2 -2
  72. package/dist/briefing.js +12 -12
  73. package/dist/buffer-surprise-report.d.ts +1 -1
  74. package/dist/buffer-turn-helpers.d.ts +1 -1
  75. package/dist/buffer.d.ts +2 -2
  76. package/dist/buffer.js +3 -3
  77. package/dist/bulk-import/index.d.ts +3 -3
  78. package/dist/calibration.d.ts +1 -1
  79. package/dist/calibration.js +2 -2
  80. package/dist/capabilities.d.ts +1 -1
  81. package/dist/{catalog-Ya3DDn_T.d.ts → catalog-Dl2hYqpS.d.ts} +1 -1
  82. package/dist/causal-behavior.d.ts +1 -1
  83. package/dist/causal-consolidation.d.ts +1 -1
  84. package/dist/causal-consolidation.js +13 -13
  85. package/dist/causal-trajectory-graph.d.ts +1 -1
  86. package/dist/{chunk-MOL7JK4F.js → chunk-3NYM6JA4.js} +2 -2
  87. package/dist/{chunk-WNMVUWI7.js → chunk-3UQIS2GC.js} +2 -2
  88. package/dist/{chunk-JDL5BYYF.js → chunk-47C6DF43.js} +3 -3
  89. package/dist/{chunk-ZBSP4BSN.js → chunk-4ECS33D4.js} +2 -2
  90. package/dist/{chunk-6EGIQEKC.js → chunk-4HTQ76O4.js} +2 -2
  91. package/dist/{chunk-7L54ARML.js → chunk-4XTSKGLX.js} +2 -2
  92. package/dist/{chunk-SUS64JER.js → chunk-5EHPB6RL.js} +2 -2
  93. package/dist/{chunk-J2MGTGKC.js → chunk-5ZXGH2ZL.js} +20 -3
  94. package/dist/chunk-5ZXGH2ZL.js.map +1 -0
  95. package/dist/{chunk-VDLNQVYW.js → chunk-62NYUFNH.js} +7 -7
  96. package/dist/{chunk-Y77UTH7F.js → chunk-66QOUYNS.js} +83 -64
  97. package/dist/chunk-66QOUYNS.js.map +1 -0
  98. package/dist/{chunk-SZV2L2IG.js → chunk-7BNB7KHB.js} +4 -4
  99. package/dist/chunk-AAQA6ZUP.js +41 -0
  100. package/dist/chunk-AAQA6ZUP.js.map +1 -0
  101. package/dist/{chunk-RJ7Z7YXK.js → chunk-AG6PANBG.js} +14 -20
  102. package/dist/chunk-AG6PANBG.js.map +1 -0
  103. package/dist/{chunk-IAGEEVQL.js → chunk-AN2O4KZY.js} +2 -2
  104. package/dist/{chunk-JUOJGZPV.js → chunk-AYP2FZFA.js} +2 -2
  105. package/dist/{chunk-XK76RJBN.js → chunk-AYZHHMTK.js} +2 -2
  106. package/dist/{chunk-LQVXSRAJ.js → chunk-B4EGAHHS.js} +2 -2
  107. package/dist/{chunk-HKQAI6XI.js → chunk-CFIHVWYZ.js} +2 -2
  108. package/dist/{chunk-DABSYX7V.js → chunk-CWMMKFO7.js} +3 -3
  109. package/dist/{chunk-WLHPCAVD.js → chunk-D5DTZBTV.js} +6 -6
  110. package/dist/{chunk-2HDLDBJW.js → chunk-DDBLZJRV.js} +2 -2
  111. package/dist/{chunk-F2FJTOV6.js → chunk-DO6R3LIE.js} +2 -2
  112. package/dist/{chunk-SHEHQBCG.js → chunk-DUJYRVUD.js} +638 -45
  113. package/dist/chunk-DUJYRVUD.js.map +1 -0
  114. package/dist/{chunk-LD22AAJI.js → chunk-EAZ3YZKN.js} +2 -2
  115. package/dist/{chunk-46FVFU7S.js → chunk-EC5SVM6H.js} +2 -2
  116. package/dist/{chunk-GKKLI23D.js → chunk-EEHQY7ER.js} +2 -2
  117. package/dist/{chunk-UHSOPTNB.js → chunk-EP6BA7VV.js} +50 -15
  118. package/dist/chunk-EP6BA7VV.js.map +1 -0
  119. package/dist/{chunk-BPXJINHW.js → chunk-EUP4AXIW.js} +2 -2
  120. package/dist/{chunk-2WMXZYMS.js → chunk-F5V7KRQS.js} +2 -2
  121. package/dist/{chunk-4AX5OYKC.js → chunk-FDDCZDBI.js} +2 -2
  122. package/dist/{chunk-XLPZN3A5.js → chunk-FMEP2RB5.js} +2 -2
  123. package/dist/{chunk-D7UUB33A.js → chunk-FSH6KRKO.js} +2 -2
  124. package/dist/{chunk-3254BYQV.js → chunk-GGY7WKMB.js} +1 -1
  125. package/dist/{chunk-ROXDOKLM.js → chunk-GYYLZOSO.js} +4 -4
  126. package/dist/{chunk-3K64PLY3.js → chunk-HXDXR2FH.js} +23 -23
  127. package/dist/{chunk-XOCGC3FJ.js → chunk-HYWPUYLO.js} +2 -2
  128. package/dist/{chunk-KQAFEZQX.js → chunk-IPLYGWQF.js} +5 -5
  129. package/dist/{chunk-M6FKXOYV.js → chunk-IXMWTNNY.js} +2 -2
  130. package/dist/{chunk-ZYSOT6HD.js → chunk-J3IWHCMF.js} +2 -2
  131. package/dist/{chunk-3YQ7VLP3.js → chunk-J5OXWG66.js} +2 -2
  132. package/dist/{chunk-H2N6SLTR.js → chunk-JIWZVOQM.js} +2 -2
  133. package/dist/{chunk-C3YEB7CR.js → chunk-JOP7W24J.js} +4 -4
  134. package/dist/{chunk-F6PTJLEM.js → chunk-K4KE5MYE.js} +1 -1
  135. package/dist/{chunk-IOTYIECA.js → chunk-KF57IQFX.js} +13 -13
  136. package/dist/{chunk-JL4TQYM5.js → chunk-L272A5QW.js} +33 -2
  137. package/dist/{chunk-JL4TQYM5.js.map → chunk-L272A5QW.js.map} +1 -1
  138. package/dist/chunk-M4DB6ZNN.js +87 -0
  139. package/dist/chunk-M4DB6ZNN.js.map +1 -0
  140. package/dist/{chunk-ZVQ5HF77.js → chunk-N46SNYMC.js} +2 -2
  141. package/dist/{chunk-YR5QT4SR.js → chunk-NAFPHFDM.js} +2 -2
  142. package/dist/{chunk-VHANUT45.js → chunk-ORQ7AZMU.js} +7 -7
  143. package/dist/{chunk-EOXCOZ6L.js → chunk-OV7GJ4KW.js} +2 -2
  144. package/dist/{chunk-VJXMFBVR.js → chunk-P7S7BVBJ.js} +2 -2
  145. package/dist/{chunk-GMU7MAHS.js → chunk-QUFJ3NJE.js} +260 -796
  146. package/dist/chunk-QUFJ3NJE.js.map +1 -0
  147. package/dist/{chunk-7F47R4H4.js → chunk-S3SND7SO.js} +2 -2
  148. package/dist/{chunk-5AJZ7EUW.js → chunk-S7KDHFF2.js} +2 -2
  149. package/dist/{chunk-4WMGRLTV.js → chunk-SRRZZHA5.js} +2 -2
  150. package/dist/{chunk-KDLOKVX7.js → chunk-SW42MMAH.js} +2 -2
  151. package/dist/{chunk-2YIUUXNK.js → chunk-T5NI5K46.js} +2 -2
  152. package/dist/{chunk-QCTXQ2HW.js → chunk-TE6B2UU6.js} +2 -2
  153. package/dist/{chunk-JDOBQPJY.js → chunk-TNQR7N52.js} +2 -2
  154. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  155. package/dist/{chunk-T3F2HWIG.js → chunk-TZ44E732.js} +2 -2
  156. package/dist/{chunk-PF7LQ22G.js → chunk-U4ESGVZ2.js} +3 -3
  157. package/dist/{chunk-WJPR2XUN.js → chunk-UEJY6ZTQ.js} +2 -2
  158. package/dist/{chunk-K3IVJ5ML.js → chunk-UGGOQKO6.js} +26 -26
  159. package/dist/{chunk-OCX7OWOC.js → chunk-UOREPQ3C.js} +2 -2
  160. package/dist/{chunk-R3H2AXO2.js → chunk-VGRVJ6Z6.js} +2 -2
  161. package/dist/{chunk-IWHNT35B.js → chunk-WOBMSMUK.js} +3 -3
  162. package/dist/{chunk-DDGQDNQW.js → chunk-XLZZLUWL.js} +2 -2
  163. package/dist/{chunk-KORQWGUA.js → chunk-Y3XHIWVP.js} +2 -2
  164. package/dist/{chunk-BZDK5EOD.js → chunk-YFVIA5A6.js} +2 -2
  165. package/dist/{chunk-GR76OKET.js → chunk-YSBYNCCN.js} +2 -2
  166. package/dist/{chunk-OGAKUA7I.js → chunk-YUQPUK6H.js} +2 -2
  167. package/dist/{chunk-TRTLWUDD.js → chunk-ZTHGFTMW.js} +2 -2
  168. package/dist/{cli-Cl7bKIWJ.d.ts → cli-Cik3H7q1.d.ts} +5 -5
  169. package/dist/cli.d.ts +16 -16
  170. package/dist/cli.js +67 -67
  171. package/dist/coding/export-okf-codegraph.d.ts +1 -1
  172. package/dist/coding/export-okf-codegraph.js +11 -11
  173. package/dist/coding/pre-action-gate.d.ts +1 -1
  174. package/dist/compounding/engine.d.ts +2 -2
  175. package/dist/compounding/engine.js +12 -12
  176. package/dist/compounding/preference-consolidator.d.ts +1 -1
  177. package/dist/compression-optimizer.d.ts +1 -1
  178. package/dist/config.d.ts +1 -1
  179. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  180. package/dist/connectors/codex-materialize-runner.js +12 -12
  181. package/dist/connectors/codex-materialize.d.ts +1 -1
  182. package/dist/connectors/index.d.ts +1 -1
  183. package/dist/connectors/index.js +12 -12
  184. package/dist/consolidation-provenance-check.d.ts +2 -2
  185. package/dist/consolidation-undo.d.ts +2 -2
  186. package/dist/contradiction/index.d.ts +4 -4
  187. package/dist/converge-config.d.ts +1 -1
  188. package/dist/convergence-refresh.d.ts +2 -2
  189. package/dist/convergence-refresh.js +14 -14
  190. package/dist/conversation-index/backend.d.ts +1 -1
  191. package/dist/conversation-index/chunker.d.ts +1 -1
  192. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  193. package/dist/conversation-index/indexer.d.ts +1 -1
  194. package/dist/conversation-index/search.d.ts +1 -1
  195. package/dist/corpus-watermark.d.ts +1 -1
  196. package/dist/corpus-watermark.js +14 -14
  197. package/dist/cross-lingual-recall.d.ts +1 -1
  198. package/dist/day-summary.d.ts +1 -1
  199. package/dist/deep-recall-http-glue.d.ts +14 -14
  200. package/dist/deep-recall-http-glue.js +4 -4
  201. package/dist/deep-recall-mcp-tools.d.ts +14 -14
  202. package/dist/deep-recall-policy-llm.d.ts +2 -2
  203. package/dist/deep-recall-policy-llm.js +3 -3
  204. package/dist/deep-recall-seeds.d.ts +1 -1
  205. package/dist/delinearize.d.ts +1 -1
  206. package/dist/dependency-propagation-config.d.ts +1 -1
  207. package/dist/{dependency-propagation-delivery-CggS9BFT.d.ts → dependency-propagation-delivery-BXaUoVUf.d.ts} +1 -1
  208. package/dist/direct-answer-wiring.d.ts +1 -1
  209. package/dist/direct-answer.d.ts +1 -1
  210. package/dist/embedding-fallback.d.ts +1 -1
  211. package/dist/enrichment/index.d.ts +1 -1
  212. package/dist/entity-origin-fields.d.ts +1 -1
  213. package/dist/entity-retrieval.d.ts +2 -2
  214. package/dist/entity-retrieval.js +12 -12
  215. package/dist/entity-schema.d.ts +1 -1
  216. package/dist/episodic-context.d.ts +1 -1
  217. package/dist/eval-trajectory-contracts.d.ts +1 -1
  218. package/dist/eval-trajectory-store.d.ts +1 -1
  219. package/dist/eval-trajectory.d.ts +1 -1
  220. package/dist/explicit-capture.d.ts +11 -11
  221. package/dist/explicit-capture.js +2 -2
  222. package/dist/external-wiki-access.d.ts +14 -14
  223. package/dist/external-wiki-access.js +37 -37
  224. package/dist/external-wiki-collection-registration.d.ts +1 -1
  225. package/dist/external-wiki-collection.d.ts +1 -1
  226. package/dist/external-wiki-mcp-tools.d.ts +14 -14
  227. package/dist/extraction-error-classification.d.ts +1 -1
  228. package/dist/extraction-faithfulness.d.ts +2 -2
  229. package/dist/extraction-faithfulness.js +3 -3
  230. package/dist/extraction-judge-telemetry.d.ts +2 -2
  231. package/dist/extraction-judge-training.d.ts +2 -2
  232. package/dist/extraction-judge.d.ts +2 -2
  233. package/dist/extraction-judge.js +3 -3
  234. package/dist/extraction-liveness.d.ts +1 -1
  235. package/dist/extraction-normalization.d.ts +1 -1
  236. package/dist/extraction-prompt.d.ts +1 -1
  237. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  238. package/dist/extraction-source-grounding.d.ts +1 -1
  239. package/dist/extraction-span-config.d.ts +1 -1
  240. package/dist/extraction-span-materialize.d.ts +1 -1
  241. package/dist/extraction-span-wire.d.ts +23 -4
  242. package/dist/extraction-span-wire.js +7 -8
  243. package/dist/extraction-span-wire.js.map +1 -1
  244. package/dist/extraction.d.ts +2 -2
  245. package/dist/extraction.js +19 -17
  246. package/dist/fallback-llm-codex-subscription.d.ts +1 -1
  247. package/dist/fallback-llm-codex-subscription.js +1 -1
  248. package/dist/fallback-llm.d.ts +1 -1
  249. package/dist/fallback-llm.js +2 -2
  250. package/dist/{generic-recall-paths-CoXPSnCw.d.ts → generic-recall-paths-BkVVEoeO.d.ts} +1 -1
  251. package/dist/graph-append-error.d.ts +1 -1
  252. package/dist/graph-dashboard-diff.d.ts +1 -1
  253. package/dist/graph-dashboard-key.d.ts +1 -1
  254. package/dist/graph-dashboard-parser.d.ts +1 -1
  255. package/dist/graph-edge-reinforcement.d.ts +1 -1
  256. package/dist/graph-jsonl.d.ts +1 -1
  257. package/dist/graph-path-reconstruction.d.ts +1 -1
  258. package/dist/graph-path-scoring.d.ts +1 -1
  259. package/dist/graph-snapshot.d.ts +1 -1
  260. package/dist/graph.d.ts +1 -1
  261. package/dist/harmonic-retrieval.js +1 -1
  262. package/dist/importance.d.ts +1 -1
  263. package/dist/importers/index.d.ts +1 -1
  264. package/dist/importers/test-utils.d.ts +1 -1
  265. package/dist/in-flight-reads.d.ts +1 -1
  266. package/dist/{index-fdw_oK5a.d.ts → index-Zb6SUV4R.d.ts} +3 -3
  267. package/dist/index.d.ts +703 -703
  268. package/dist/index.js +90 -87
  269. package/dist/intent.d.ts +1 -1
  270. package/dist/lcm/engine.d.ts +1 -1
  271. package/dist/lcm/index.d.ts +1 -1
  272. package/dist/lcm/index.js +3 -3
  273. package/dist/lcm/tools.d.ts +1 -1
  274. package/dist/lifecycle.d.ts +1 -1
  275. package/dist/live-connectors-runner.d.ts +1 -1
  276. package/dist/{local-llm-3-jtw52a.d.ts → local-llm-DdrhmecM.d.ts} +1 -1
  277. package/dist/local-llm-helpers.d.ts +2 -2
  278. package/dist/local-llm.d.ts +2 -2
  279. package/dist/local-model-endpoint.d.ts +1 -1
  280. package/dist/location/index.d.ts +5 -5
  281. package/dist/location/index.js +14 -14
  282. package/dist/maintenance/memory-governance.d.ts +1 -1
  283. package/dist/maintenance/memory-governance.js +12 -12
  284. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  285. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +12 -12
  286. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  287. package/dist/maintenance/rebuild-memory-projection.js +13 -13
  288. package/dist/{maintenance-DgeeH0a1.d.ts → maintenance-Du_VRvVg.d.ts} +3 -3
  289. package/dist/mcp-memory-inspector-app.d.ts +14 -14
  290. package/dist/memory-action-policy.d.ts +1 -1
  291. package/dist/memory-age.d.ts +100 -0
  292. package/dist/memory-age.js +22 -0
  293. package/dist/memory-age.js.map +1 -0
  294. package/dist/memory-cache.d.ts +1 -1
  295. package/dist/memory-controller.d.ts +1 -1
  296. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  297. package/dist/memory-projection-store.d.ts +1 -1
  298. package/dist/memory-provenance.d.ts +1 -1
  299. package/dist/memory-snapshot.d.ts +1 -1
  300. package/dist/memory-subject-cli.d.ts +14 -14
  301. package/dist/memory-subject.d.ts +14 -14
  302. package/dist/memory-worth-outcomes.d.ts +2 -2
  303. package/dist/models-json.d.ts +1 -1
  304. package/dist/namespaces/migrate.d.ts +3 -3
  305. package/dist/namespaces/migrate.js +13 -13
  306. package/dist/namespaces/principal.d.ts +1 -1
  307. package/dist/namespaces/search.d.ts +1 -1
  308. package/dist/namespaces/search.js +3 -3
  309. package/dist/namespaces/storage.d.ts +3 -3
  310. package/dist/namespaces/storage.js +12 -12
  311. package/dist/native-knowledge.d.ts +1 -1
  312. package/dist/offline-sync-impression-drain.d.ts +1 -1
  313. package/dist/operator-doctor-corpus.d.ts +1 -1
  314. package/dist/operator-doctor-corpus.js +15 -15
  315. package/dist/operator-doctor-replica.d.ts +1 -1
  316. package/dist/operator-toolkit.d.ts +3 -3
  317. package/dist/operator-toolkit.js +20 -20
  318. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  319. package/dist/orchestration/maintenance.d.ts +4 -4
  320. package/dist/orchestration/maintenance.js +20 -20
  321. package/dist/{orchestrator-VXWKdatm.d.ts → orchestrator-D9U3Zgjp.d.ts} +10 -10
  322. package/dist/orchestrator.d.ts +11 -11
  323. package/dist/orchestrator.js +90 -87
  324. package/dist/patterns-cli.d.ts +1 -1
  325. package/dist/{pipeline-CwXZBKR5.d.ts → pipeline-4lqKJZ_0.d.ts} +1 -1
  326. package/dist/policy-runtime.d.ts +1 -1
  327. package/dist/proactive-contention.d.ts +2 -2
  328. package/dist/provenance.d.ts +1 -1
  329. package/dist/{public-http-DdmM4scJ.d.ts → public-http-AabioFLh.d.ts} +1 -1
  330. package/dist/{qmd-DOLTPIQg.d.ts → qmd-DnoWaXKb.d.ts} +1 -1
  331. package/dist/qmd-preflight.d.ts +2 -2
  332. package/dist/qmd-recall-cache.d.ts +1 -1
  333. package/dist/qmd.d.ts +2 -2
  334. package/dist/recall-concurrency-config.d.ts +1 -1
  335. package/dist/recall-disclosure-escalation.d.ts +1 -1
  336. package/dist/recall-explain-renderer.d.ts +1 -1
  337. package/dist/recall-memory-map.d.ts +1 -1
  338. package/dist/recall-navigate-access.d.ts +1 -1
  339. package/dist/recall-navigate-disclosure.d.ts +1 -1
  340. package/dist/recall-navigate.d.ts +1 -1
  341. package/dist/recall-navigation-http-glue.d.ts +14 -14
  342. package/dist/recall-navigation-mcp-tools.d.ts +14 -14
  343. package/dist/recall-navigation-operations.js +37 -37
  344. package/dist/recall-navigation-renderer.d.ts +1 -1
  345. package/dist/recall-navigation.d.ts +1 -1
  346. package/dist/recall-navigation.js +36 -36
  347. package/dist/recall-planner-llm.d.ts +1 -1
  348. package/dist/recall-planner-llm.js +2 -2
  349. package/dist/recall-state-view-admission.d.ts +2 -2
  350. package/dist/recall-state-view-admission.js +3 -3
  351. package/dist/recall-state-view-anchors.d.ts +1 -1
  352. package/dist/recall-state.d.ts +1 -1
  353. package/dist/recall-tag-filter.d.ts +1 -1
  354. package/dist/recall-timings.d.ts +1 -1
  355. package/dist/recall-xray-cli.d.ts +1 -1
  356. package/dist/recall-xray-renderer.d.ts +1 -1
  357. package/dist/recall-xray.d.ts +1 -1
  358. package/dist/reconcile/cursor.d.ts +1 -1
  359. package/dist/reconcile/manifest.d.ts +1 -1
  360. package/dist/reconcile/manifest.js +2 -2
  361. package/dist/reconcile/plan.d.ts +1 -1
  362. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  363. package/dist/replay/normalizers/claude.d.ts +1 -1
  364. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  365. package/dist/replay/normalizers/shared.d.ts +1 -1
  366. package/dist/replay/runner.d.ts +1 -1
  367. package/dist/replay/types.d.ts +1 -1
  368. package/dist/replica-divergence.d.ts +1 -1
  369. package/dist/replica-peers-config.d.ts +1 -1
  370. package/dist/resolve-auth-token.d.ts +1 -1
  371. package/dist/retrieval-agents.d.ts +2 -2
  372. package/dist/retrieval-tiers.d.ts +1 -1
  373. package/dist/routing/engine.d.ts +1 -1
  374. package/dist/routing/store.d.ts +1 -1
  375. package/dist/salvage-envelope.d.ts +1 -1
  376. package/dist/schemas.d.ts +160 -160
  377. package/dist/{scope-profiles-C564-hrv.d.ts → scope-profiles-crazXegZ.d.ts} +1 -1
  378. package/dist/search/embed-helper.d.ts +1 -1
  379. package/dist/search/factory.d.ts +1 -1
  380. package/dist/search/factory.js +2 -2
  381. package/dist/search/index.d.ts +1 -1
  382. package/dist/search/index.js +4 -4
  383. package/dist/search/lancedb-backend.d.ts +1 -1
  384. package/dist/search/meilisearch-backend.d.ts +1 -1
  385. package/dist/search/noop-backend.d.ts +1 -1
  386. package/dist/search/orama-backend.d.ts +1 -1
  387. package/dist/search/port.d.ts +1 -1
  388. package/dist/search/remote-backend.d.ts +1 -1
  389. package/dist/{semantic-consolidation-g6x-ShY8.d.ts → semantic-consolidation-B09JI9WM.d.ts} +1 -1
  390. package/dist/semantic-consolidation.d.ts +2 -2
  391. package/dist/semantic-consolidation.js +13 -13
  392. package/dist/semantic-rule-promotion.js +12 -12
  393. package/dist/semantic-rule-verifier.d.ts +1 -1
  394. package/dist/semantic-rule-verifier.js +12 -12
  395. package/dist/{service-CaCOk0rd.d.ts → service-ByjbCuj7.d.ts} +2 -2
  396. package/dist/session-observer-bands.d.ts +1 -1
  397. package/dist/session-observer-state.d.ts +1 -1
  398. package/dist/shared-context/manager.d.ts +7 -7
  399. package/dist/signal.d.ts +1 -1
  400. package/dist/source-agent-qualifier.d.ts +1 -1
  401. package/dist/source-agent-qualifier.js +15 -15
  402. package/dist/source-attribution.d.ts +7 -4
  403. package/dist/source-attribution.js +1 -1
  404. package/dist/standup/build.js +12 -12
  405. package/dist/{storage-C9nsZX5Q.d.ts → storage-CbdF077z.d.ts} +17 -3
  406. package/dist/storage.d.ts +2 -2
  407. package/dist/storage.js +11 -11
  408. package/dist/subject-config.d.ts +1 -1
  409. package/dist/summarizer.d.ts +1 -1
  410. package/dist/summarizer.js +3 -3
  411. package/dist/summary-snapshot.d.ts +1 -1
  412. package/dist/support-passport/index.d.ts +17 -17
  413. package/dist/support-passport/index.js +39 -39
  414. package/dist/{tagging-BA4RFdH3.d.ts → tagging-CF7DNV7_.d.ts} +2 -2
  415. package/dist/temporal-supersession.d.ts +2 -2
  416. package/dist/temporal-timeline-recall.d.ts +1 -1
  417. package/dist/temporal-validity.d.ts +1 -1
  418. package/dist/threading.d.ts +1 -1
  419. package/dist/tier-migration.d.ts +2 -2
  420. package/dist/tier-routing.d.ts +1 -1
  421. package/dist/topics.d.ts +1 -1
  422. package/dist/transcript.d.ts +1 -1
  423. package/dist/transfer/autodetect.js +1 -1
  424. package/dist/transfer/backup.js +1 -1
  425. package/dist/transfer/capsule-export.js +2 -2
  426. package/dist/transfer/export-okf.d.ts +1 -1
  427. package/dist/transfer/export-okf.js +12 -12
  428. package/dist/transfer/types.d.ts +78 -78
  429. package/dist/trust-score-stage.d.ts +1 -1
  430. package/dist/trust-score.d.ts +1 -1
  431. package/dist/{types-Sps-lg5I.d.ts → types-nmhnJpxx.d.ts} +1 -1
  432. package/dist/types.d.ts +1 -1
  433. package/dist/utility-runtime.d.ts +1 -1
  434. package/dist/verified-recall.js +12 -12
  435. package/dist/who-knows-cli.d.ts +14 -14
  436. package/dist/who-knows-cli.js +13 -13
  437. package/dist/who-knows.d.ts +14 -14
  438. package/dist/who-knows.js +12 -12
  439. package/dist/write-envelope.d.ts +1 -1
  440. package/package.json +2 -2
  441. package/src/background-generation.test.ts +77 -0
  442. package/src/dedup/merge.test.ts +185 -8
  443. package/src/extraction-span-wire.test.ts +17 -1
  444. package/src/extraction-span-wire.ts +46 -3
  445. package/src/extraction.ts +2 -11
  446. package/src/memory-age.test.ts +106 -0
  447. package/src/memory-age.ts +196 -0
  448. package/src/orchestration/recall-search-pipeline.test.ts +207 -1
  449. package/src/orchestration/recall-search-pipeline.ts +13 -9
  450. package/src/orchestration/semantic-merge-commit-effects.ts +31 -9
  451. package/src/orchestration/semantic-merge-persist.ts +16 -5
  452. package/src/providers/codex-subscription.test.ts +109 -3
  453. package/src/providers/codex-subscription.ts +57 -17
  454. package/src/source-attribution.test.ts +27 -0
  455. package/src/source-attribution.ts +41 -5
  456. package/src/storage/cas-revision-host.ts +22 -0
  457. package/src/storage/cas-revision-store.test.ts +44 -1
  458. package/src/storage/cas-revision-store.ts +23 -0
  459. package/src/storage/tombstone-blocked-capture-sync.ts +26 -1
  460. package/src/storage-frontmatter-cas.test.ts +49 -1
  461. package/src/storage.ts +1 -1
  462. package/src/summarizer.ts +18 -0
  463. package/dist/chunk-GMU7MAHS.js.map +0 -1
  464. package/dist/chunk-J2MGTGKC.js.map +0 -1
  465. package/dist/chunk-RJ7Z7YXK.js.map +0 -1
  466. package/dist/chunk-SHEHQBCG.js.map +0 -1
  467. package/dist/chunk-UHSOPTNB.js.map +0 -1
  468. package/dist/chunk-Y77UTH7F.js.map +0 -1
  469. /package/dist/{auto-sync-QZD4RD6H.js.map → auto-sync-DG5KEOF5.js.map} +0 -0
  470. /package/dist/{chunk-MOL7JK4F.js.map → chunk-3NYM6JA4.js.map} +0 -0
  471. /package/dist/{chunk-WNMVUWI7.js.map → chunk-3UQIS2GC.js.map} +0 -0
  472. /package/dist/{chunk-JDL5BYYF.js.map → chunk-47C6DF43.js.map} +0 -0
  473. /package/dist/{chunk-ZBSP4BSN.js.map → chunk-4ECS33D4.js.map} +0 -0
  474. /package/dist/{chunk-6EGIQEKC.js.map → chunk-4HTQ76O4.js.map} +0 -0
  475. /package/dist/{chunk-7L54ARML.js.map → chunk-4XTSKGLX.js.map} +0 -0
  476. /package/dist/{chunk-SUS64JER.js.map → chunk-5EHPB6RL.js.map} +0 -0
  477. /package/dist/{chunk-VDLNQVYW.js.map → chunk-62NYUFNH.js.map} +0 -0
  478. /package/dist/{chunk-SZV2L2IG.js.map → chunk-7BNB7KHB.js.map} +0 -0
  479. /package/dist/{chunk-IAGEEVQL.js.map → chunk-AN2O4KZY.js.map} +0 -0
  480. /package/dist/{chunk-JUOJGZPV.js.map → chunk-AYP2FZFA.js.map} +0 -0
  481. /package/dist/{chunk-XK76RJBN.js.map → chunk-AYZHHMTK.js.map} +0 -0
  482. /package/dist/{chunk-LQVXSRAJ.js.map → chunk-B4EGAHHS.js.map} +0 -0
  483. /package/dist/{chunk-HKQAI6XI.js.map → chunk-CFIHVWYZ.js.map} +0 -0
  484. /package/dist/{chunk-DABSYX7V.js.map → chunk-CWMMKFO7.js.map} +0 -0
  485. /package/dist/{chunk-WLHPCAVD.js.map → chunk-D5DTZBTV.js.map} +0 -0
  486. /package/dist/{chunk-2HDLDBJW.js.map → chunk-DDBLZJRV.js.map} +0 -0
  487. /package/dist/{chunk-F2FJTOV6.js.map → chunk-DO6R3LIE.js.map} +0 -0
  488. /package/dist/{chunk-LD22AAJI.js.map → chunk-EAZ3YZKN.js.map} +0 -0
  489. /package/dist/{chunk-46FVFU7S.js.map → chunk-EC5SVM6H.js.map} +0 -0
  490. /package/dist/{chunk-GKKLI23D.js.map → chunk-EEHQY7ER.js.map} +0 -0
  491. /package/dist/{chunk-BPXJINHW.js.map → chunk-EUP4AXIW.js.map} +0 -0
  492. /package/dist/{chunk-2WMXZYMS.js.map → chunk-F5V7KRQS.js.map} +0 -0
  493. /package/dist/{chunk-4AX5OYKC.js.map → chunk-FDDCZDBI.js.map} +0 -0
  494. /package/dist/{chunk-XLPZN3A5.js.map → chunk-FMEP2RB5.js.map} +0 -0
  495. /package/dist/{chunk-D7UUB33A.js.map → chunk-FSH6KRKO.js.map} +0 -0
  496. /package/dist/{chunk-3254BYQV.js.map → chunk-GGY7WKMB.js.map} +0 -0
  497. /package/dist/{chunk-ROXDOKLM.js.map → chunk-GYYLZOSO.js.map} +0 -0
  498. /package/dist/{chunk-3K64PLY3.js.map → chunk-HXDXR2FH.js.map} +0 -0
  499. /package/dist/{chunk-XOCGC3FJ.js.map → chunk-HYWPUYLO.js.map} +0 -0
  500. /package/dist/{chunk-KQAFEZQX.js.map → chunk-IPLYGWQF.js.map} +0 -0
  501. /package/dist/{chunk-M6FKXOYV.js.map → chunk-IXMWTNNY.js.map} +0 -0
  502. /package/dist/{chunk-ZYSOT6HD.js.map → chunk-J3IWHCMF.js.map} +0 -0
  503. /package/dist/{chunk-3YQ7VLP3.js.map → chunk-J5OXWG66.js.map} +0 -0
  504. /package/dist/{chunk-H2N6SLTR.js.map → chunk-JIWZVOQM.js.map} +0 -0
  505. /package/dist/{chunk-C3YEB7CR.js.map → chunk-JOP7W24J.js.map} +0 -0
  506. /package/dist/{chunk-F6PTJLEM.js.map → chunk-K4KE5MYE.js.map} +0 -0
  507. /package/dist/{chunk-IOTYIECA.js.map → chunk-KF57IQFX.js.map} +0 -0
  508. /package/dist/{chunk-ZVQ5HF77.js.map → chunk-N46SNYMC.js.map} +0 -0
  509. /package/dist/{chunk-YR5QT4SR.js.map → chunk-NAFPHFDM.js.map} +0 -0
  510. /package/dist/{chunk-VHANUT45.js.map → chunk-ORQ7AZMU.js.map} +0 -0
  511. /package/dist/{chunk-EOXCOZ6L.js.map → chunk-OV7GJ4KW.js.map} +0 -0
  512. /package/dist/{chunk-VJXMFBVR.js.map → chunk-P7S7BVBJ.js.map} +0 -0
  513. /package/dist/{chunk-7F47R4H4.js.map → chunk-S3SND7SO.js.map} +0 -0
  514. /package/dist/{chunk-5AJZ7EUW.js.map → chunk-S7KDHFF2.js.map} +0 -0
  515. /package/dist/{chunk-4WMGRLTV.js.map → chunk-SRRZZHA5.js.map} +0 -0
  516. /package/dist/{chunk-KDLOKVX7.js.map → chunk-SW42MMAH.js.map} +0 -0
  517. /package/dist/{chunk-2YIUUXNK.js.map → chunk-T5NI5K46.js.map} +0 -0
  518. /package/dist/{chunk-QCTXQ2HW.js.map → chunk-TE6B2UU6.js.map} +0 -0
  519. /package/dist/{chunk-JDOBQPJY.js.map → chunk-TNQR7N52.js.map} +0 -0
  520. /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
  521. /package/dist/{chunk-T3F2HWIG.js.map → chunk-TZ44E732.js.map} +0 -0
  522. /package/dist/{chunk-PF7LQ22G.js.map → chunk-U4ESGVZ2.js.map} +0 -0
  523. /package/dist/{chunk-WJPR2XUN.js.map → chunk-UEJY6ZTQ.js.map} +0 -0
  524. /package/dist/{chunk-K3IVJ5ML.js.map → chunk-UGGOQKO6.js.map} +0 -0
  525. /package/dist/{chunk-OCX7OWOC.js.map → chunk-UOREPQ3C.js.map} +0 -0
  526. /package/dist/{chunk-R3H2AXO2.js.map → chunk-VGRVJ6Z6.js.map} +0 -0
  527. /package/dist/{chunk-IWHNT35B.js.map → chunk-WOBMSMUK.js.map} +0 -0
  528. /package/dist/{chunk-DDGQDNQW.js.map → chunk-XLZZLUWL.js.map} +0 -0
  529. /package/dist/{chunk-KORQWGUA.js.map → chunk-Y3XHIWVP.js.map} +0 -0
  530. /package/dist/{chunk-BZDK5EOD.js.map → chunk-YFVIA5A6.js.map} +0 -0
  531. /package/dist/{chunk-GR76OKET.js.map → chunk-YSBYNCCN.js.map} +0 -0
  532. /package/dist/{chunk-OGAKUA7I.js.map → chunk-YUQPUK6H.js.map} +0 -0
  533. /package/dist/{chunk-TRTLWUDD.js.map → chunk-ZTHGFTMW.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/summarizer.ts"],"sourcesContent":["import { mkdir, readFile, writeFile, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { log } from \"./logger.js\";\nimport { LocalLlmClient } from \"./local-llm.js\";\nimport { FallbackLlmClient, fallbackLlmRuntimeContextFromConfig, gatewayTaskChainOptions } from \"./fallback-llm.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { extractJsonCandidates } from \"./json-extract.js\";\nimport {\n completeBackgroundGeneration,\n parseBackgroundGenerationJson,\n} from \"./background-generation.js\";\nimport type { HourlySummary, TranscriptEntry, PluginConfig, GatewayConfig } from \"./types.js\";\nimport type { TranscriptManager } from \"./transcript.js\";\nimport { readSummarySnapshot, upsertSummarySnapshot, writeSummarySnapshot } from \"./summary-snapshot.js\";\nimport { encodeStoragePathSegment, resolveSafeStoragePath } from \"./storage-paths.js\";\nimport { sessionStoragePaths } from \"./session-identity.js\";\nimport { resolveLocalLlmCapabilities } from \"./capabilities.js\";\nimport { resolvePipelineProcessingCapabilities } from \"./capabilities.js\";\n\n// Schema for LLM summary output\nconst HourlySummarySchema = z.object({\n bullets: z.array(z.string().trim().min(1)).min(1).describe(\"3-5 bullet points summarizing the hour's activity\"),\n});\n\ntype HourlySummaryResult = z.infer<typeof HourlySummarySchema>;\n\nconst HourlySummaryExtendedSchema = z.object({\n topics: z.array(z.string()).default([]),\n decisions: z.array(z.string()).default([]),\n actionItems: z.array(z.string()).default([]),\n rejected: z.array(z.string()).default([]),\n});\n\ntype HourlySummaryExtendedResult = z.infer<typeof HourlySummaryExtendedSchema>;\n\ntype HourlySummaryExtendedMeta = {\n userTurns: number;\n assistantTurns: number;\n toolCalls: number;\n toolCounts: Record<string, number>;\n};\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Outcome stats of one `runHourly` pass (issue #2783). The summarizer must\n * not report success on empty work: an empty or stale transcript store is\n * the delegate-mode starvation signature, and callers surface these counts\n * and the staleness flag as a distinct warning instead of a bare ok.\n */\nexport interface HourlySummarizerRunStats {\n sessionsConsidered: number;\n sessionsWithEntries: number;\n summariesWritten: number;\n /** True when the newest transcript entry across the store is older than STALE_STORE_MS. */\n staleStore: boolean;\n /** ISO timestamp of the newest transcript entry seen by the scan, when any exist. */\n newestEntryTimestamp: string | null;\n /** True when the transcript scan itself FAILED (unreadable store) — distinct from an empty store. */\n scanFailed: boolean;\n}\n\n/** A store whose newest entry is older than this is considered stale (starvation signal, issue #2783). */\nconst STALE_STORE_MS = 2 * 60 * 60 * 1000;\n\n/**\n * Interpret one {@link HourlySummarizerRunStats} into the operator-facing\n * message/warning (issue #2783). Every degraded shape — failed scan, empty\n * store, backend-down, stale store — is DISTINCT from success; monitoring\n * alerts on `warning`, never on `ok` (ok only means \"the run completed\").\n */\nexport function summarizeHourlyStatus(stats: HourlySummarizerRunStats): {\n message: string;\n warning?: string;\n} {\n if (stats.scanFailed) {\n return {\n message:\n \"Hourly summarization completed, but the transcript store scan FAILED (unreadable directory or I/O error). Investigate the daemon's memoryDir.\",\n warning: \"transcript store scan failed\",\n };\n }\n if (stats.sessionsConsidered === 0) {\n return {\n message:\n \"Hourly summarization completed, but the transcript store is empty — no sessions found. If turns are ingested via observe, transcript persistence may be disabled or failing.\",\n warning: \"transcript store is empty\",\n };\n }\n if (stats.sessionsWithEntries > 0 && stats.summariesWritten === 0) {\n return {\n message: `Hourly summarization found ${stats.sessionsWithEntries} session(s) with transcript entries but wrote no summaries — the summarizer backend may be down.`,\n warning: \"sessions with entries produced no summaries\",\n };\n }\n if (stats.sessionsWithEntries === 0 && stats.staleStore) {\n return {\n message: `Hourly summarization completed with no transcript entries for the target hour, and the store looks stale (newest entry ${stats.newestEntryTimestamp ?? \"unknown\"}).`,\n warning: \"no transcript entries for the target hour and no new entries recently\",\n };\n }\n return {\n message: `Hourly summarization completed: ${stats.summariesWritten} summar${stats.summariesWritten === 1 ? \"y\" : \"ies\"} written across ${stats.sessionsWithEntries} session${stats.sessionsWithEntries === 1 ? \"\" : \"s\"} with transcript entries.`,\n };\n}\n\nexport class HourlySummarizer {\n private summariesDir: string;\n private config: PluginConfig;\n private localLlm: LocalLlmClient;\n private fallbackLlm: FallbackLlmClient;\n private modelRegistry: ModelRegistry;\n private transcript?: TranscriptManager;\n\n constructor(\n config: PluginConfig,\n gatewayConfig?: GatewayConfig,\n modelRegistry?: ModelRegistry,\n transcript?: TranscriptManager\n ) {\n this.config = config;\n this.summariesDir = path.join(config.memoryDir, \"summaries\", \"hourly\");\n this.modelRegistry = modelRegistry ?? new ModelRegistry(config.memoryDir);\n this.transcript = transcript;\n\n // Initialize local LLM client with shared model registry\n this.localLlm = new LocalLlmClient(config, this.modelRegistry);\n\n // Initialize fallback client with gateway config\n this.fallbackLlm = new FallbackLlmClient(gatewayConfig, fallbackLlmRuntimeContextFromConfig(config));\n\n if (\n !gatewayConfig?.agents?.defaults?.model?.primary &&\n !resolveLocalLlmCapabilities(config).localLlm &&\n config.modelSource !== \"gateway\"\n ) {\n log.warn(\"no gateway default AI and local LLM disabled — hourly summarization disabled\");\n }\n }\n\n private get useGatewayModelSource(): boolean {\n return this.config.modelSource === \"gateway\";\n }\n\n private get shouldUseLocalLlm(): boolean {\n return resolveLocalLlmCapabilities(this.config).localLlm && !this.useGatewayModelSource;\n }\n\n private withGatewayAgent(\n options: import(\"./fallback-llm.js\").FallbackLlmOptions\n ): import(\"./fallback-llm.js\").FallbackLlmOptions {\n if (!this.useGatewayModelSource) return options;\n // Shared resolution (taskModelChain > gatewayAgentId) — gotcha #22. Issue #1365.\n return { ...options, ...gatewayTaskChainOptions(this.config) };\n }\n\n async initialize(): Promise<void> {\n await mkdir(this.summariesDir, { recursive: true });\n log.info(\"hourly summarizer initialized\");\n }\n\n private async summarySessionDir(sessionKey: string): Promise<string> {\n return resolveSafeStoragePath(this.summariesDir, encodeStoragePathSegment(sessionKey, \"session\"));\n }\n\n private async legacySummarySessionDir(sessionKey: string): Promise<string | null> {\n if (sessionKey.includes(\"\\0\")) return null;\n try {\n return await resolveSafeStoragePath(this.summariesDir, sessionKey);\n } catch {\n return null;\n }\n }\n\n private summaryDateString(hour: string): string {\n const dateStr = hour.slice(0, 10);\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(dateStr)) {\n throw new Error(`invalid hourly summary timestamp: ${hour}`);\n }\n return dateStr;\n }\n\n // Generate summary for a specific hour and session\n async generateSummary(\n sessionKey: string,\n hourStart: Date,\n entries: TranscriptEntry[]\n ): Promise<HourlySummary | null> {\n if (entries.length === 0) return null;\n\n // Format entries for the LLM\n const conversation = entries.map((e) => `[${e.role}] ${e.content}`).join(\"\\n\\n\");\n\n if (resolvePipelineProcessingCapabilities(this.config).hourlySummariesExtended) {\n const extended = await this.generateExtended(sessionKey, hourStart, conversation, entries);\n if (!extended) return null;\n const meta: HourlySummaryExtendedMeta = {\n userTurns: entries.filter((e) => e.role === \"user\").length,\n assistantTurns: entries.filter((e) => e.role === \"assistant\").length,\n toolCalls: extended._meta.toolCalls,\n toolCounts: extended._meta.toolCounts,\n };\n // Keep HourlySummary surface stable; encode \"topics\" as bullets for recall injection.\n const base: HourlySummary = {\n hour: hourStart.toISOString(),\n sessionKey,\n bullets: extended.topics.length > 0 ? extended.topics.slice(0, 5) : [\"(summary generated)\"],\n turnCount: entries.length,\n generatedAt: new Date().toISOString(),\n };\n const withExtras = base as any;\n withExtras._extended = extended;\n withExtras._extendedMeta = meta;\n return base;\n }\n\n const hourIso = hourStart.toISOString();\n const startTime = Date.now();\n\n if (this.config.backgroundGeneration) {\n try {\n const text = await completeBackgroundGeneration(this.config, [\n {\n role: \"system\",\n content:\n \"You are a conversation summarization system. Summarize the following conversation transcript into 3-5 concise bullet points.\\n\\nGuidelines:\\n- Focus on what was accomplished, decided, or discussed\\n- Include specific topics, projects, or entities mentioned\\n- Note any significant user requests or agent actions\\n- Keep bullets brief but informative (1-2 sentences each)\\n- Skip trivial greetings or meta-conversation\\n- Use present tense for ongoing work, past for completed items\\n\\nRespond with valid JSON only, matching this schema:\\n{\\\"bullets\\\": [\\\"bullet 1\\\", \\\"bullet 2\\\", \\\"bullet 3\\\"]}\",\n },\n { role: \"user\", content: `Summarize this conversation:\\n\\n${conversation}` },\n ]);\n const parsed = parseBackgroundGenerationJson(text, (value) => HourlySummarySchema.parse(value));\n if (parsed) {\n return {\n hour: hourIso,\n sessionKey,\n bullets: parsed.bullets,\n turnCount: entries.length,\n generatedAt: new Date().toISOString(),\n };\n }\n } catch {\n log.info(\"summary generation: background generation unavailable, continuing\");\n }\n }\n\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n try {\n const localResult = await this.generateWithLocalLlm(conversation);\n if (localResult) {\n const durationMs = Date.now() - startTime;\n log.debug(`generated hourly summary for ${sessionKey} at ${hourIso} in ${durationMs}ms using local LLM`);\n return {\n hour: hourIso,\n sessionKey,\n bullets: localResult.bullets,\n turnCount: entries.length,\n generatedAt: new Date().toISOString(),\n };\n }\n // Local failed, fall back if allowed\n if (!this.config.localLlmFallback) {\n log.warn(\"summary generation: local LLM failed and fallback disabled\");\n return null;\n }\n log.info(\"summary generation: local LLM unavailable, falling back to gateway default AI\");\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(\"summary generation: local LLM error and fallback disabled:\", err);\n return null;\n }\n log.info(\"summary generation: local LLM error, falling back to gateway default AI:\", err);\n }\n }\n\n // Fall back to gateway's default AI\n log.info(\"summary generation: falling back to gateway default AI\");\n\n try {\n const messages = [\n {\n role: \"system\" as const,\n content: `You are a conversation summarization system. Summarize the following conversation transcript into 3-5 concise bullet points.\n\nGuidelines:\n- Focus on what was accomplished, decided, or discussed\n- Include specific topics, projects, or entities mentioned\n- Note any significant user requests or agent actions\n- Keep bullets brief but informative (1-2 sentences each)\n- Skip trivial greetings or meta-conversation\n- Use present tense for ongoing work, past for completed items\n\nRespond with valid JSON matching this schema:\n{\n \"bullets\": [\"bullet 1\", \"bullet 2\", \"bullet 3\"]\n}`,\n },\n { role: \"user\" as const, content: `Summarize this conversation:\\n\\n${conversation}` },\n ];\n\n const result = await this.fallbackLlm.parseWithSchema(\n messages,\n HourlySummarySchema,\n this.withGatewayAgent({ temperature: 0.3, maxTokens: 8192 })\n );\n\n const durationMs = Date.now() - startTime;\n\n if (result) {\n log.debug(`generated hourly summary for ${sessionKey} at ${hourIso} in ${durationMs}ms via fallback`);\n return {\n hour: hourIso,\n sessionKey,\n bullets: result.bullets,\n turnCount: entries.length,\n generatedAt: new Date().toISOString(),\n };\n }\n\n log.warn(\"summary generation fallback returned no parsed output\");\n return null;\n } catch (err) {\n log.error(\"summary generation fallback failed\", err);\n return null;\n }\n }\n\n private async generateExtended(\n sessionKey: string,\n hourStart: Date,\n conversation: string,\n entries: TranscriptEntry[]\n ): Promise<(HourlySummaryExtendedResult & { _meta: HourlySummaryExtendedMeta }) | null> {\n const hourIso = hourStart.toISOString();\n const startTime = Date.now();\n\n const hourEnd = new Date(hourStart.getTime() + 60 * 60 * 1000);\n let toolCounts: Record<string, number> = {};\n if (this.config.hourlySummariesIncludeToolStats && this.transcript) {\n const uses = await this.transcript.readToolUse(sessionKey, hourStart, hourEnd);\n for (const u of uses) toolCounts[u.tool] = (toolCounts[u.tool] ?? 0) + 1;\n }\n\n const sys = `You are a conversation summarization system.\\n\\nSummarize the hour into structured sections.\\n\\nReturn valid JSON matching:\\n{\\n \\\"topics\\\": [\\\"...\\\"],\\n \\\"decisions\\\": [\\\"...\\\"],\\n \\\"actionItems\\\": [\\\"...\\\"],\\n \\\"rejected\\\": [\\\"...\\\"]\\n}\\n\\nGuidelines:\\n- Prefer concrete topics and decisions.\\n- Action items should be imperative.\\n- Rejected ideas are things that were explicitly discarded or reversed.\\n- If there are none for a section, return an empty array.\\n`;\n\n const toolStatsLine =\n Object.keys(toolCounts).length > 0\n ? `Tools used (counts): ${Object.entries(toolCounts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([k, v]) => `${k}=${v}`)\n .join(\", \")}\\n\\n`\n : \"\";\n const userTurns = entries.filter((e) => e.role === \"user\").length;\n const assistantTurns = entries.filter((e) => e.role === \"assistant\").length;\n const toolCalls = Object.values(toolCounts).reduce((a, b) => a + b, 0);\n const statsLine = `Stats: userTurns=${userTurns}, assistantTurns=${assistantTurns}, toolCalls=${toolCalls}\\n\\n`;\n\n const user = `Hour: ${hourIso}\\nSession: ${sessionKey}\\n\\n${statsLine}${toolStatsLine}Conversation:\\n${conversation}\\n`;\n\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n try {\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n const truncated =\n user.length > contextSizes.maxInputChars\n ? user.slice(0, contextSizes.maxInputChars) + \"\\n\\n[truncated]\"\n : user;\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"Output valid JSON only.\" },\n { role: \"user\", content: sys + \"\\n\\n\" + truncated },\n ],\n {\n temperature: 0.2,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"hourly_summary_extended\",\n priority: \"background\",\n }\n );\n if (response?.content) {\n const content = response.content.trim();\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n const result = HourlySummaryExtendedSchema.parse(parsed);\n log.debug(\n `generated extended hourly summary for ${sessionKey} at ${hourIso} in ${Date.now() - startTime}ms (local)`\n );\n return { ...result, _meta: { userTurns, assistantTurns, toolCalls, toolCounts } };\n } catch {\n // keep trying candidates\n }\n }\n }\n } catch (err) {\n if (!this.config.localLlmFallback) return null;\n log.info(\"extended summary: local failed, falling back:\", err);\n }\n }\n\n try {\n const result = await this.fallbackLlm.parseWithSchema(\n [\n { role: \"system\" as const, content: sys },\n { role: \"user\" as const, content: user },\n ],\n HourlySummaryExtendedSchema,\n this.withGatewayAgent({ temperature: 0.2, maxTokens: 2048 })\n );\n if (result) {\n log.debug(\n `generated extended hourly summary for ${sessionKey} at ${hourIso} in ${Date.now() - startTime}ms (fallback)`\n );\n return { ...result, _meta: { userTurns, assistantTurns, toolCalls, toolCounts } };\n }\n return null;\n } catch (err) {\n log.error(\"extended summary generation failed\", err);\n return null;\n }\n }\n\n /**\n * Generate summary using local LLM with JSON mode.\n * Uses dynamic context sizing based on model capabilities.\n */\n private async generateWithLocalLlm(conversation: string): Promise<HourlySummaryResult | null> {\n // Get dynamic context sizes based on model capabilities\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n log.debug(`Summarizer model context: ${contextSizes.description}`);\n\n const maxConversationChars = contextSizes.maxInputChars;\n const truncatedConversation =\n conversation.length > maxConversationChars\n ? conversation.slice(0, maxConversationChars) + \"\\n\\n[truncated]\"\n : conversation;\n\n const instructions = `You are a conversation summarization system. Summarize the following conversation transcript into 3-5 concise bullet points.\n\nGuidelines:\n- Focus on what was accomplished, decided, or discussed\n- Include specific topics, projects, or entities mentioned\n- Note any significant user requests or agent actions\n- Keep bullets brief but informative (1-2 sentences each)\n- Skip trivial greetings or meta-conversation\n- Use present tense for ongoing work, past for completed items\n\nRespond with valid JSON matching this schema:\n{\n \"bullets\": [\"bullet 1\", \"bullet 2\", \"bullet 3\"]\n}`;\n\n const fullPrompt = `${instructions}\\n\\nConversation to summarize:\\n${truncatedConversation}`;\n\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"You are a conversation summarization system. Output valid JSON only.\" },\n { role: \"user\", content: fullPrompt },\n ],\n {\n temperature: 0.3,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"hourly_summary\",\n priority: \"background\",\n }\n );\n\n if (!response?.content) {\n return null;\n }\n\n try {\n // Parse JSON response\n const content = response.content.trim();\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n return HourlySummarySchema.parse(parsed);\n } catch {\n // keep trying candidates\n }\n }\n return null;\n } catch (err) {\n log.warn(\"local LLM summary: failed to parse JSON response:\", err);\n return null;\n }\n }\n\n // Save summary to file\n async saveSummary(summary: HourlySummary): Promise<void> {\n const sessionDir = await this.summarySessionDir(summary.sessionKey);\n await mkdir(sessionDir, { recursive: true });\n\n // Format date as YYYY-MM-DD for the filename\n const dateStr = this.summaryDateString(summary.hour);\n const filePath = await resolveSafeStoragePath(sessionDir, `${dateStr}.md`);\n\n // Format hour as HH:00 for display\n const hourStr = summary.hour.slice(11, 13);\n\n // Build markdown content\n const lines: string[] = [];\n\n // Check if file exists to append or create\n let existingContent = \"\";\n try {\n existingContent = await readFile(filePath, \"utf-8\");\n } catch {\n // File doesn't exist yet, will create new\n }\n\n // Check if this hour already exists (idempotent)\n const hourHeader = `## ${hourStr}:00`;\n if (existingContent.includes(hourHeader)) {\n // Replace existing hour section\n const headerMatch = new RegExp(`(^|\\\\n)${escapeRegExp(hourHeader)}\\\\n`).exec(existingContent);\n const sectionStart = headerMatch\n ? headerMatch.index + headerMatch[1].length\n : existingContent.indexOf(hourHeader);\n const nextHeaderPattern = /\\n## \\d{2}:00\\n/g;\n nextHeaderPattern.lastIndex = sectionStart + hourHeader.length;\n const nextHeader = nextHeaderPattern.exec(existingContent);\n const beforeHour = existingContent.slice(0, sectionStart);\n const afterHour = nextHeader ? existingContent.slice(nextHeader.index + 1) : \"\";\n const newSection = this.formatHourSection(summary, hourHeader);\n existingContent = beforeHour + newSection.trimEnd() + (afterHour ? \"\\n\\n\" + afterHour : \"\\n\");\n\n await writeFile(filePath, existingContent, \"utf-8\");\n log.debug(`updated hourly summary for ${summary.sessionKey} at ${hourStr}:00`);\n } else {\n // Append new hour section\n const newSection = this.formatHourSection(summary, hourHeader);\n\n if (existingContent) {\n // Add to existing file\n await writeFile(filePath, existingContent.trimEnd() + \"\\n\\n\" + newSection, \"utf-8\");\n } else {\n // Create new file with header\n const header = `# Hourly Summaries — ${dateStr}\\n\\n*Session: ${summary.sessionKey}*\\n`;\n await writeFile(filePath, header + \"\\n\" + newSection, \"utf-8\");\n }\n log.debug(`saved hourly summary for ${summary.sessionKey} at ${hourStr}:00`);\n }\n try {\n await upsertSummarySnapshot(this.config.memoryDir, summary);\n } catch (error) {\n log.warn(\n `hourly summarizer: failed to update summary snapshot for ${summary.sessionKey} (fail-open): ${String(error)}`\n );\n }\n }\n\n private formatHourSection(summary: HourlySummary, hourHeader: string): string {\n const ext = (summary as any)._extended as\n | (HourlySummaryExtendedResult & { _meta?: HourlySummaryExtendedMeta })\n | undefined;\n const meta = (summary as any)._extendedMeta as HourlySummaryExtendedMeta | undefined;\n const lines: string[] = [hourHeader, \"\"];\n\n if (resolvePipelineProcessingCapabilities(this.config).hourlySummariesExtended && ext) {\n lines.push(\"### Topics Discussed\");\n for (const t of ext.topics) lines.push(`- ${t}`);\n lines.push(\"\");\n lines.push(\"### Decisions Made\");\n for (const d of ext.decisions) lines.push(`- ${d}`);\n lines.push(\"\");\n lines.push(\"### Action Items\");\n for (const a of ext.actionItems) lines.push(`- ${a}`);\n lines.push(\"\");\n lines.push(\"### Rejected Ideas / Reversals\");\n for (const r of ext.rejected) lines.push(`- ${r}`);\n lines.push(\"\");\n if (meta && Object.keys(meta.toolCounts).length > 0) {\n lines.push(\"### Tools Used\");\n const top = Object.entries(meta.toolCounts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 12);\n for (const [name, count] of top) lines.push(`- ${name}: ${count}`);\n lines.push(\"\");\n }\n lines.push(\"### Stats\");\n lines.push(`- Turns: ${summary.turnCount}`);\n if (meta) {\n lines.push(`- User turns: ${meta.userTurns}`);\n lines.push(`- Assistant turns: ${meta.assistantTurns}`);\n lines.push(`- Tool calls: ${meta.toolCalls}`);\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n }\n\n for (const bullet of summary.bullets) lines.push(`- ${bullet}`);\n lines.push(` *(${summary.turnCount} turns)*`);\n lines.push(\"\");\n return lines.join(\"\\n\");\n }\n\n // Read recent summaries for recall injection\n async readRecent(sessionKey: string, hours: number): Promise<HourlySummary[]> {\n try {\n const cutoffTime = Date.now() - hours * 60 * 60 * 1000;\n\n const snapshot = await readSummarySnapshot(this.config.memoryDir, sessionKey);\n if (snapshot) {\n return snapshot\n .filter((s) => new Date(s.hour).getTime() >= cutoffTime)\n .sort((a, b) => new Date(b.hour).getTime() - new Date(a.hour).getTime());\n }\n\n const summaries: HourlySummary[] = [];\n const encodedDir = await this.summarySessionDir(sessionKey);\n const legacyDir = await this.legacySummarySessionDir(sessionKey);\n const seenDirs = new Set<string>();\n\n for (const sessionDir of [encodedDir, legacyDir]) {\n if (!sessionDir || seenDirs.has(sessionDir)) continue;\n seenDirs.add(sessionDir);\n const parsed = await this.readSummaryDir(sessionDir, sessionKey);\n summaries.push(...parsed);\n }\n\n const byHour = new Map<string, HourlySummary>();\n for (const summary of summaries) {\n if (!byHour.has(summary.hour)) byHour.set(summary.hour, summary);\n }\n\n const sortedSummaries = Array.from(byHour.values()).sort(\n (a, b) => new Date(b.hour).getTime() - new Date(a.hour).getTime()\n );\n\n // Filter to recent hours while materializing the full parsed history.\n const recent = sortedSummaries.filter((s) => new Date(s.hour).getTime() >= cutoffTime);\n\n if (sortedSummaries.length > 0) {\n try {\n await writeSummarySnapshot(this.config.memoryDir, sessionKey, sortedSummaries);\n } catch (error) {\n log.warn(\n `hourly summarizer: failed to materialize summary snapshot for ${sessionKey} (fail-open): ${String(error)}`\n );\n }\n }\n\n return recent;\n } catch {\n // Directory doesn't exist or error reading\n return [];\n }\n }\n\n private async readSummaryDir(sessionDir: string, sessionKey: string): Promise<HourlySummary[]> {\n let files: string[];\n try {\n files = await readdir(sessionDir);\n } catch {\n return [];\n }\n\n const summaries: HourlySummary[] = [];\n const mdFiles = files.filter((f) => f.endsWith(\".md\"));\n for (const file of mdFiles) {\n const filePath = await resolveSafeStoragePath(sessionDir, file).catch(() => null);\n if (filePath === null) continue;\n\n try {\n const content = await readFile(filePath, \"utf-8\");\n summaries.push(...this.parseSummaryFile(content, sessionKey, file));\n } catch {\n // Skip unreadable summary files.\n }\n }\n\n return summaries;\n }\n\n private parseSummaryFile(content: string, sessionKey: string, filename: string): HourlySummary[] {\n const summaries: HourlySummary[] = [];\n\n // Extract date from filename (YYYY-MM-DD.md)\n const dateMatch = filename.match(/^(\\d{4}-\\d{2}-\\d{2})\\.md$/);\n if (!dateMatch) return summaries;\n const dateStr = dateMatch[1];\n\n // Split by hour sections\n const hourSections = content.split(/\\n## (\\d{2}):00\\n/);\n\n // First element is the header, skip it\n for (let i = 1; i < hourSections.length; i += 2) {\n const hourStr = hourSections[i];\n const sectionContent = hourSections[i + 1] || \"\";\n\n // Parse bullets\n const bullets: string[] = [];\n const lines = sectionContent.split(\"\\n\");\n let turnCount = 0;\n\n let inTopics = false;\n let sawExtendedTopicsHeader = false;\n for (const line of lines) {\n if (line.startsWith(\"### Topics\")) {\n inTopics = true;\n sawExtendedTopicsHeader = true;\n continue;\n }\n if (line.startsWith(\"### \") && !line.startsWith(\"### Topics\")) {\n inTopics = false;\n }\n const bulletMatch = line.match(/^- (.+)$/);\n if (bulletMatch) {\n // For extended format, only treat topic bullets as recall bullets.\n if (!sawExtendedTopicsHeader || inTopics) bullets.push(bulletMatch[1]);\n }\n const turnMatch = line.match(/\\((\\d+) turns?\\)/);\n if (turnMatch) turnCount = parseInt(turnMatch[1], 10);\n }\n\n if (bullets.length > 0) {\n summaries.push({\n hour: `${dateStr}T${hourStr}:00:00.000Z`,\n sessionKey,\n bullets,\n turnCount,\n generatedAt: \"\", // Not stored in file, not needed for recall\n });\n }\n }\n\n return summaries;\n }\n\n // Format summaries for recall injection\n formatForRecall(summaries: HourlySummary[], maxCount: number): string {\n if (summaries.length === 0) return \"\";\n\n const limited = summaries.slice(0, maxCount);\n const lines: string[] = [`## Recent Activity (last ${limited.length} hours)`];\n\n for (const summary of limited) {\n const hourStr = summary.hour.slice(11, 16); // HH:MM\n for (const bullet of summary.bullets) {\n lines.push(`- ${hourStr}: ${bullet}`);\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n // Main entry point for cron job\n async runHourly(): Promise<HourlySummarizerRunStats> {\n log.debug(\"running hourly summary generation\");\n\n // Get active sessions from transcript. The scan outcome is kept LOCAL to\n // this invocation (review round 2): shared instance state would let two\n // concurrent runHourly calls cross-report each other's timestamps.\n const scan = await this.getActiveSessions();\n const sessions = scan.sessionKeys;\n let sessionsWithEntries = 0;\n let summariesWritten = 0;\n\n for (const sessionKey of sessions) {\n // Calculate the hour we want to summarize (previous hour)\n const now = new Date();\n const hourStart = new Date(now.getTime() - 60 * 60 * 1000);\n hourStart.setMinutes(0, 0, 0);\n const hourEnd = new Date(hourStart.getTime() + 60 * 60 * 1000);\n\n // Get entries for this session in the target hour\n const entries = await this.getTranscriptEntries(sessionKey, hourStart, hourEnd);\n\n if (entries.length === 0) {\n log.debug(`no transcript entries for ${sessionKey} at ${hourStart.toISOString()}`);\n continue;\n }\n sessionsWithEntries += 1;\n\n // Generate and save summary\n const summary = await this.generateSummary(sessionKey, hourStart, entries);\n if (summary) {\n await this.saveSummary(summary);\n summariesWritten += 1;\n log.info(`generated hourly summary for ${sessionKey} (${entries.length} turns)`);\n }\n }\n\n return {\n sessionsConsidered: sessions.length,\n sessionsWithEntries,\n summariesWritten,\n // Staleness signal (issue #2783): newest entry across the whole\n // store, from the same scan getActiveSessions already performs.\n staleStore:\n scan.newestEntryTimestamp !== null &&\n Date.now() - new Date(scan.newestEntryTimestamp).getTime() > STALE_STORE_MS,\n newestEntryTimestamp: scan.newestEntryTimestamp,\n scanFailed: scan.scanFailed,\n };\n }\n\n // Get list of active sessions from the transcript directory, plus the\n // scan bookkeeping runHourly reports: newest entry timestamp (staleness\n // signal) and whether the scan itself FAILED. A failed scan must not be\n // reported as an empty store — those are different incidents (review\n // round 2).\n private async getActiveSessions(): Promise<{\n sessionKeys: string[];\n newestEntryTimestamp: string | null;\n scanFailed: boolean;\n }> {\n const transcriptDir = await resolveSafeStoragePath(this.config.memoryDir, \"transcripts\").catch(() => null);\n if (transcriptDir === null) {\n return { sessionKeys: [], newestEntryTimestamp: null, scanFailed: false };\n }\n\n const sessionKeys = new Set<string>();\n let newestEntryTimestamp: string | null = null;\n let newestEntryTimeMs = Number.NaN;\n let fileReadFailed = false;\n const collect = async (transcriptPath: string): Promise<void> => {\n try {\n const raw = await readFile(transcriptPath, \"utf-8\");\n for (const line of raw.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line) as TranscriptEntry;\n if (typeof entry.sessionKey === \"string\" && entry.sessionKey.length > 0) {\n sessionKeys.add(entry.sessionKey);\n }\n // Compare parsed epoch values, never strings: a malformed\n // timestamp in a hand-edited file must not poison the staleness\n // signal with a lexically-maximal garbage value (review).\n if (typeof entry.timestamp === \"string\") {\n const timeMs = new Date(entry.timestamp).getTime();\n if (Number.isFinite(timeMs) && (Number.isNaN(newestEntryTimeMs) || timeMs > newestEntryTimeMs)) {\n newestEntryTimeMs = timeMs;\n newestEntryTimestamp = entry.timestamp;\n }\n }\n } catch {\n // ignore malformed transcript lines\n }\n }\n } catch (err) {\n // ENOENT is a concurrently-deleted file — ignore. Any other read\n // failure (permissions, I/O) means the store is partially UNREADABLE:\n // mark the scan failed so the caller warns instead of reporting an\n // empty store (review round 3).\n if ((err as NodeJS.ErrnoException)?.code !== \"ENOENT\") {\n fileReadFailed = true;\n }\n }\n };\n\n try {\n const typeEntries = await readdir(transcriptDir, { withFileTypes: true });\n for (const typeEnt of typeEntries) {\n if (!typeEnt.isDirectory()) continue;\n const typeDir = await resolveSafeStoragePath(transcriptDir, typeEnt.name).catch(() => null);\n if (typeDir === null) continue;\n const idEntries = await readdir(typeDir, { withFileTypes: true });\n for (const idEnt of idEntries) {\n if (!idEnt.isDirectory()) continue;\n const chanDir = await resolveSafeStoragePath(typeDir, idEnt.name).catch(() => null);\n if (chanDir === null) continue;\n const files = (await readdir(chanDir)).filter((f) => f.endsWith(\".jsonl\")).sort();\n for (const file of files) {\n const transcriptPath = await resolveSafeStoragePath(chanDir, file).catch(() => null);\n if (transcriptPath === null) continue;\n await collect(transcriptPath);\n }\n }\n }\n return {\n sessionKeys: Array.from(sessionKeys),\n newestEntryTimestamp,\n scanFailed: fileReadFailed,\n };\n } catch (err) {\n // ENOENT on the root is a never-written store — an EMPTY store, not a\n // scan failure (those are different incidents).\n const code = (err as NodeJS.ErrnoException)?.code;\n if (code === \"ENOENT\") {\n return { sessionKeys: [], newestEntryTimestamp: null, scanFailed: false };\n }\n log.warn(`transcript scan failed: ${err}`);\n return { sessionKeys: [], newestEntryTimestamp: null, scanFailed: true };\n }\n }\n\n // Get transcript entries for a session within a time range\n private async getTranscriptEntries(sessionKey: string, startTime: Date, endTime: Date): Promise<TranscriptEntry[]> {\n // Shared session-identity layer (issue #1496, rule #22). Arbitrary keys\n // route to `session/<hash>`; legacy `agent:<id>:...` keep their paths. The\n // shared helper also supplies the read-back-only candidate dirs (mirrors\n // TranscriptManager) so legacy `other/default` AND old `parts.length >= 3`\n // data stays discoverable here too.\n const paths = sessionStoragePaths(sessionKey);\n\n try {\n const transcriptRoot = path.join(this.config.memoryDir, \"transcripts\");\n const candidateDirs = new Set(\n [paths.dir, paths.alternateDir, paths.legacyDir, ...paths.readbackDirs].filter(\n (dir): dir is string => typeof dir === \"string\" && dir.length > 0\n )\n );\n const entries: TranscriptEntry[] = [];\n // Dedup identical raw rows that a partially-applied migration may have\n // left in both the primary dir and a read-back dir (issue #1496, cursor\n // review). Exact raw JSONL line is the stable identity.\n const seenRawLines = new Set<string>();\n\n // Read all daily transcript files in the directory\n for (const candidateDir of candidateDirs) {\n const transcriptDir = await resolveSafeStoragePath(transcriptRoot, candidateDir).catch(() => null);\n if (transcriptDir === null) continue;\n\n const files = await readdir(transcriptDir).catch(() => []);\n for (const file of files) {\n if (!file.endsWith(\".jsonl\")) continue;\n\n const transcriptPath = await resolveSafeStoragePath(transcriptDir, file).catch(() => null);\n if (transcriptPath === null) continue;\n\n try {\n const content = await readFile(transcriptPath, \"utf-8\");\n const lines = content.trim().split(\"\\n\");\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line) as TranscriptEntry;\n const entryTime = new Date(entry.timestamp).getTime();\n\n if (\n entry.sessionKey === sessionKey &&\n entryTime >= startTime.getTime() &&\n entryTime < endTime.getTime() &&\n !seenRawLines.has(line)\n ) {\n seenRawLines.add(line);\n entries.push(entry);\n }\n } catch {\n // Skip malformed lines\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return entries;\n } catch {\n return [];\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/extraction.ts","../src/orchestration/dependency-revalidation.ts"],"sourcesContent":["import OpenAI from \"openai\";\nimport { isAbortError } from \"./abort-error.js\";\nimport { log } from \"./logger.js\";\nimport { delinearize } from \"./delinearize.js\";\nimport { LocalLlmClient } from \"./local-llm.js\";\nimport { shouldRunProactivePass } from \"./proactive-contention.js\";\nimport { FallbackLlmClient, fallbackLlmRuntimeContextFromConfig, gatewayTaskChainOptions } from \"./fallback-llm.js\";\nimport { revalidateDependentsViaLlm, type RevalidationFastChatCompletion } from \"./orchestration/dependency-revalidation.js\";\nimport {\n ExtractionProviderOutputSchema,\n ExtractionResultSchema,\n ConsolidationResultSchema,\n IdentityConsolidationResultSchema,\n buildProfileConsolidationResultSchema,\n ProactiveExtractionResultSchema,\n ProactiveQuestionsResultSchema,\n type ContradictionVerificationResult,\n type SuggestedLinks,\n type MemorySummaryResult,\n type ProactiveQuestionsResultParsed,\n DaySummaryResultSchema,\n} from \"./schemas.js\";\nimport type { BufferTurn, ExtractionResult, ConsolidationResult, MemoryFile, PluginConfig, LlmTraceEvent, GatewayConfig, MemoryCategory, DaySummaryResult as DaySummaryResultShape, ExtractionFailureClass } from \"./types.js\";\nimport type { ExtractedFactSpanRef } from \"./extraction-span-config.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { extractJsonCandidates } from \"./json-extract.js\";\nimport { sanitizeMemoryContent } from \"./sanitize.js\";\nimport { applyWorkExtractionBoundary } from \"./work/boundary.js\";\nimport { buildChatCompletionTokenLimit, shouldAssumeOpenAiChatCompletions } from \"./openai-chat-compat.js\";\nimport { formatDaySummaryMemories, loadDaySummaryPrompt, buildExtensionsFooterForSummary } from \"./day-summary.js\";\nimport { ProfilingCollector } from \"./profiling.js\";\nimport { normalizeProcedureSteps } from \"./procedural/procedure-types.js\";\nimport { normalizeReasoningTrace } from \"./reasoning-trace-types.js\";\nimport { looksLikeMechanicalTelemetryTranscript } from \"./telemetry-transcript.js\";\nimport {\n attachExtractionProvenance,\n type ExtractionGroundingRoleSources,\n} from \"./extraction-source-grounding.js\";\nimport { applyGroundingWithConnector, headerConnector, renderExtractionConversation, resolveSourceConnector, type ExtractionGroundingContext } from \"./source-agent-qualifier.js\";\nimport { isMemoryCategory } from \"./write-envelope.js\";\nexport { classifyExtractionThrownError, classifyFallbackParseFailure, formatExtractionParseFailureLog } from \"./extraction-error-classification.js\";\nimport { classifyExtractionThrownError, classifyFallbackParseFailure, formatExtractionParseFailureLog } from \"./extraction-error-classification.js\";\nimport { AMBIENT_CAPTURE_PROMPT_SECTION_COMPACT, clampAmbientCaptureConfidence } from \"./ambient-provenance.js\";\nimport {\n CONSOLIDATION_RESPONSE_SCHEMA,\n CUE_ANCHOR_PROMPT_INSTRUCTION,\n extractionResponseShape,\n OUTPUT_LANGUAGE_POLICY,\n PROFILE_CONSOLIDATION_RESPONSE_SCHEMA,\n buildConsolidationSystemPrompt,\n buildExtractionInstructions,\n buildProfileConsolidationSystemPrompt,\n eventTimePromptInstruction,\n spanModePromptSection,\n} from \"./extraction-prompt.js\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport { containsExtractionPlaceholder, extractionAttributes, extractionCueAnchors, extractionText, isPlainRecord } from \"./extraction-normalization.js\";\nimport { applyExtractionSpanMaterialization, bindLocalExtractionPrompt, buildSpanMaterializeTurns, stripUntrustedFactSpans, truncateLocalExtractionConversation, type SpanMaterializeTurn } from \"./extraction-span-materialize.js\";\nimport { resolveLocalLlmCapabilities, resolveMemoryLifecycleCapabilities, resolvePipelineProcessingCapabilities, resolveRecallAuxiliaryCapabilities } from \"./capabilities.js\";\ntype ExtractionQuestion = ExtractionResult[\"questions\"][number];\ntype ExtractedFactResult = ExtractionResult[\"facts\"][number];\ntype ExtractedEntityResult = ExtractionResult[\"entities\"][number];\ntype ExtractedRelationshipResult = NonNullable<ExtractionResult[\"relationships\"]>[number];\n\nconst PROACTIVE_MIN_CONFIDENCE = 0.8;\n\nconst EXTRACTION_PROVIDER_JSON_SCHEMA = zodToJsonSchema(\n ExtractionProviderOutputSchema,\n {\n $refStrategy: \"none\",\n effectStrategy: \"input\",\n },\n) as Record<string, unknown>;\n\nfunction extractionEntityType(value: unknown): ExtractedEntityResult[\"type\"] | undefined {\n const type = extractionText(value);\n if (\n type === \"person\" ||\n type === \"project\" ||\n type === \"tool\" ||\n type === \"company\" ||\n type === \"place\" ||\n type === \"other\"\n ) {\n return type;\n }\n return undefined;\n}\n\nfunction normalizeQuestion(question: ExtractionQuestion): ExtractionQuestion {\n const priority = Number.isFinite(question.priority)\n ? Math.max(0, Math.min(1, question.priority))\n : 0.5;\n return {\n question: typeof question.question === \"string\" ? question.question.trim() : \"\",\n context: typeof question.context === \"string\" ? question.context.trim() : \"\",\n priority,\n };\n}\n\nfunction normalizeExtractedSpanRef(value: unknown): ExtractedFactSpanRef | undefined {\n if (!isPlainRecord(value)) return undefined;\n const { sourceMessageIndex, charStart, charEnd, frame, sourceHash, sourceLength } = value;\n if (\n typeof sourceMessageIndex !== \"number\" ||\n typeof charStart !== \"number\" ||\n typeof charEnd !== \"number\" ||\n typeof frame !== \"string\"\n ) {\n return undefined;\n }\n return {\n sourceMessageIndex,\n charStart,\n charEnd,\n frame,\n ...(typeof sourceHash === \"string\" && typeof sourceLength === \"number\"\n ? { sourceHash, sourceLength }\n : {}),\n };\n}\n\nfunction normalizeFactKey(fact: Pick<ExtractedFactResult, \"category\" | \"content\">): string {\n return `${fact.category}:${fact.content.trim().toLowerCase()}`;\n}\n\nfunction normalizeEntityKey(entity: Pick<ExtractedEntityResult, \"name\" | \"type\">): string {\n return `${entity.type}:${entity.name.trim().toLowerCase()}`;\n}\n\nfunction normalizeRelationshipKey(\n relationship: Pick<ExtractedRelationshipResult, \"source\" | \"target\" | \"label\">,\n): string {\n return `${relationship.source.trim().toLowerCase()}=>${relationship.target.trim().toLowerCase()}:${relationship.label.trim().toLowerCase()}`;\n}\n\nfunction normalizeProfileUpdateKey(update: string): string {\n return update.trim().toLowerCase();\n}\n\nexport function shouldEnableLocalExtractionThinking(\n config: Pick<PluginConfig, \"localLlmDisableThinking\" | \"localLlmThinkingThresholdChars\">,\n conversationChars: number,\n): boolean {\n return config.localLlmDisableThinking &&\n config.localLlmThinkingThresholdChars > 0 &&\n conversationChars < config.localLlmThinkingThresholdChars;\n}\n\nfunction throwIfExtractionAborted(signal?: AbortSignal): void {\n if (!signal?.aborted) return;\n const reason = signal.reason;\n throw reason instanceof Error ? reason : new Error(\"extraction aborted\");\n}\n\nexport class ExtractionEngine {\n private client: OpenAI | null;\n private localLlm: LocalLlmClient;\n private fallbackLlm: FallbackLlmClient;\n private modelRegistry: ModelRegistry;\n private profiler: ProfilingCollector;\n\n constructor(\n private readonly config: PluginConfig,\n profilerArg?: ProfilingCollector,\n localLlm?: LocalLlmClient,\n gatewayConfig?: GatewayConfig,\n modelRegistry?: ModelRegistry,\n private readonly fastChatCompletion?: RevalidationFastChatCompletion,\n ) {\n this.profiler = profilerArg ?? new ProfilingCollector({ enabled: false, storageDir: \"/tmp/engram-profiler-disabled\", maxTraces: 0 });\n if (config.openaiApiKey) {\n this.client = new OpenAI({\n apiKey: config.openaiApiKey,\n ...(config.openaiBaseUrl ? { baseURL: config.openaiBaseUrl } : {}),\n });\n } else {\n this.client = null;\n log.warn(\"no OpenAI API key — direct OpenAI client disabled; local and gateway fallback paths remain available\");\n }\n this.localLlm = localLlm ?? new LocalLlmClient(config, modelRegistry);\n this.fallbackLlm = new FallbackLlmClient(\n gatewayConfig,\n fallbackLlmRuntimeContextFromConfig(config),\n );\n this.modelRegistry = modelRegistry ?? new ModelRegistry(config.memoryDir);\n if (config.modelSource === \"gateway\") {\n log.debug(\n `extraction engine: gateway model source active; extraction uses the gateway chain as its primary path` +\n (config.taskModelChain ? \" (taskModelChain)\" :\n config.gatewayAgentId ? ` (agent: ${config.gatewayAgentId})` : \" (defaults)\"),\n );\n } else if (config.taskModelChain) {\n // taskModelChain resolves through gateway providers, so it only applies\n // under modelSource: \"gateway\". Warn rather than silently ignore it so a\n // misconfigured plugin-mode setup is visible. Issue #1365 / PR #1370.\n log.warn(\n `taskModelChain is set but modelSource is \"${config.modelSource}\"; the chain is ignored. ` +\n `Set modelSource: \"gateway\" to use it for extraction/consolidation/summarization.`,\n );\n }\n }\n\n private get useGatewayModelSource(): boolean {\n return this.config.modelSource === \"gateway\";\n }\n\n private get shouldUseLocalLlm(): boolean {\n return resolveLocalLlmCapabilities(this.config).localLlm && !this.useGatewayModelSource;\n }\n\n private get shouldUseDirectClient(): boolean {\n return !this.useGatewayModelSource && this.client !== null;\n }\n\n /**\n * Span-mode materialization (issue #2333 Phase B): sibling module, called\n * after parse and before sanitize/grounding so downstream sees one content\n * form. Offsets index the exact prompt turn texts and die at materialization.\n */\n private applySpanMaterialization(\n result: ExtractionResult,\n spanTurns: readonly SpanMaterializeTurn[],\n ): ExtractionResult {\n return applyExtractionSpanMaterialization(\n result,\n spanTurns,\n this.config.extraction?.spanMode ?? \"off\",\n );\n }\n\n /**\n * Build FallbackLlmOptions with the configured gateway agent ID injected.\n */\n private withGatewayAgent(options: import(\"./fallback-llm.js\").FallbackLlmOptions): import(\"./fallback-llm.js\").FallbackLlmOptions {\n if (!this.useGatewayModelSource) return options;\n // Shared resolution (taskModelChain > gatewayAgentId) so every background\n // task routes identically (gotcha #22). Issue #1365.\n return { ...options, ...gatewayTaskChainOptions(this.config) };\n }\n\n private emit(event: LlmTraceEvent): void {\n try {\n const cb = (globalThis as any).__openclawEngramTrace;\n if (typeof cb === \"function\") cb(event);\n } catch {\n // Never throw — broken subscriber must not crash extraction\n }\n }\n\n private directClientUsesOpenAiTokenSemantics(): boolean {\n return shouldAssumeOpenAiChatCompletions(this.config.openaiBaseUrl);\n }\n\n private sanitizeExtractionResult(result: ExtractionResult, messageTimestamp?: Date): ExtractionResult {\n const proceduralOn = this.config.procedural?.enabled === true;\n const ts = messageTimestamp ?? new Date();\n const facts = result.facts\n .filter((fact) => proceduralOn || fact.category !== \"procedure\")\n .map((fact) => {\n const sanitized = sanitizeMemoryContent(fact.content);\n if (!sanitized.clean) {\n log.warn(`extraction fact sanitized; violations=${sanitized.violations.join(\", \")}`);\n }\n let content = sanitized.text;\n // De-linearize: resolve coreferences + anchor temporal expressions\n if (resolvePipelineProcessingCapabilities(this.config).delinearize) {\n content = delinearize(content, result.entities, ts);\n }\n return {\n ...fact,\n content,\n cueAnchors: extractionCueAnchors(fact.cueAnchors),\n };\n });\n return { ...result, facts, episodeTitle: extractionText(result.episodeTitle) };\n }\n\n private hasExtractionOutputs(result: ExtractionResult): boolean {\n return result.facts.length > 0\n || result.entities.length > 0\n || result.questions.length > 0\n || result.profileUpdates.length > 0\n || (result.relationships?.length ?? 0) > 0;\n }\n\n private looksLikeExtractionResultPayload(parsed: any): boolean {\n return !!parsed &&\n typeof parsed === \"object\" &&\n !Array.isArray(parsed) &&\n (\n \"facts\" in parsed ||\n \"entities\" in parsed ||\n \"profileUpdates\" in parsed ||\n \"questions\" in parsed ||\n \"relationships\" in parsed ||\n \"identityReflection\" in parsed\n );\n }\n\n private normalizeExtractionResultPayload(parsed: any): ExtractionResult {\n const entities: ExtractedEntityResult[] = Array.isArray(parsed?.entities)\n ? parsed.entities\n .map((candidate: unknown): ExtractedEntityResult | undefined => this.normalizeEntityUpdate(candidate))\n .filter((entity: ExtractedEntityResult | undefined): entity is ExtractedEntityResult => (\n entity !== undefined && entity.name.length > 0\n ))\n : [];\n\n const facts = Array.isArray(parsed?.facts)\n ? parsed.facts\n .map((candidate: unknown) => {\n const f = isPlainRecord(candidate) ? candidate : {};\n const category = typeof f.category === \"string\" ? f.category.trim() : \"fact\";\n const reasoningTraceInput = isPlainRecord(f.reasoningTrace)\n ? f.reasoningTrace\n : isPlainRecord(f?.reasoning_trace)\n ? f.reasoning_trace\n : undefined;\n if (!isMemoryCategory(category)) return undefined;\n const procedureSteps = Array.isArray(f.procedureSteps)\n ? normalizeProcedureSteps(f.procedureSteps)\n : undefined;\n const reasoningTrace = reasoningTraceInput\n ? normalizeReasoningTrace(reasoningTraceInput) ?? undefined\n : undefined;\n if (\n containsExtractionPlaceholder(procedureSteps) ||\n containsExtractionPlaceholder(reasoningTrace)\n ) {\n return undefined;\n }\n return {\n category,\n content: extractionText(f.content) ?? extractionText(f.text) ?? \"\",\n confidence: typeof f.confidence === \"number\" ? f.confidence : 0.7,\n tags: Array.isArray(f.tags)\n ? f.tags.flatMap((tag: unknown) => {\n const text = extractionText(tag);\n return text === undefined ? [] : [text];\n })\n : [],\n entityRef: extractionText(f.entityRef),\n cueAnchors: extractionCueAnchors(f.cueAnchors),\n promptedByQuestion: extractionText(f.promptedByQuestion),\n scope:\n f.scope === \"global\" || f.scope === \"project\" ? f.scope : undefined,\n subject:\n f.subject === \"user\" || f.subject === \"agent\" ? f.subject : undefined,\n structuredAttributes: extractionAttributes(f.structuredAttributes),\n procedureSteps,\n reasoningTrace,\n quote: extractionText(f.quote),\n span: normalizeExtractedSpanRef(f.span),\n eventTime: extractionText(f.eventTime) ?? extractionText(f.event_time),\n };\n })\n .filter((fact: ExtractedFactResult | undefined): fact is ExtractedFactResult => (\n fact !== undefined && fact.content.length > 0\n ))\n : [];\n\n const questions: ExtractionQuestion[] = Array.isArray(parsed?.questions)\n ? parsed.questions.flatMap((candidate: unknown) => {\n const record = isPlainRecord(candidate) ? candidate : undefined;\n const question =\n extractionText(record?.question) ??\n extractionText(record?.text) ??\n extractionText(candidate);\n if (question === undefined) return [];\n return [{\n question,\n context: extractionText(record?.context) ?? \"\",\n priority: typeof record?.priority === \"number\" ? record.priority : 0.5,\n }];\n })\n : [];\n\n const profileUpdates = Array.isArray(parsed?.profileUpdates)\n ? parsed.profileUpdates.flatMap((candidate: unknown) => {\n const update = extractionText(candidate);\n return update === undefined ? [] : [update];\n })\n : [];\n\n const relationships: ExtractedRelationshipResult[] | undefined = Array.isArray(parsed?.relationships)\n ? parsed.relationships.flatMap((candidate: unknown) => {\n const relationship = isPlainRecord(candidate) ? candidate : undefined;\n const source = extractionText(relationship?.source);\n const target = extractionText(relationship?.target);\n const label = extractionText(relationship?.label);\n if (source === undefined || target === undefined || label === undefined) return [];\n return [{\n source,\n target,\n label,\n promptedByQuestion: extractionText(relationship?.promptedByQuestion),\n }];\n })\n : undefined;\n\n return {\n facts,\n entities,\n profileUpdates,\n questions,\n identityReflection: extractionText(parsed?.identityReflection),\n episodeTitle: extractionText(parsed?.episodeTitle),\n relationships,\n };\n }\n\n private normalizeEntityUpdate(entity: unknown): ExtractedEntityResult | undefined {\n const record = isPlainRecord(entity) ? entity : {};\n const rawUpdates = isPlainRecord(record.updates) ? record.updates : undefined;\n const normalizedTexts = (value: unknown): string[] =>\n Array.isArray(value)\n ? value.flatMap((candidate: unknown) => {\n const text = extractionText(candidate);\n return text === undefined ? [] : [text];\n })\n : [];\n const directFacts = normalizedTexts(record.facts);\n const updateFacts = normalizedTexts(rawUpdates?.facts);\n const scalarUpdateFacts = rawUpdates\n ? Object.entries(rawUpdates)\n .sort(([left], [right]) => left.localeCompare(right))\n .flatMap(([key, value]) => {\n if ([\"facts\", \"name\", \"promptedByQuestion\", \"structuredSections\", \"type\"].includes(key)) {\n return [];\n }\n const normalizedKey = extractionText(key);\n if (normalizedKey === undefined) return [];\n const normalizedValue = extractionText(value);\n if (normalizedValue !== undefined) return [`${normalizedKey}: ${normalizedValue}`];\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return [`${normalizedKey}: ${String(value)}`];\n }\n return [];\n })\n : [];\n const structuredSectionsSource = Array.isArray(record.structuredSections)\n ? record.structuredSections\n : Array.isArray(rawUpdates?.structuredSections)\n ? rawUpdates.structuredSections\n : [];\n const structuredSections = structuredSectionsSource.flatMap((candidate: unknown) => {\n const section = isPlainRecord(candidate) ? candidate : {};\n const key = extractionText(section.key);\n const title = extractionText(section.title);\n const facts = normalizedTexts(section.facts);\n if (key === undefined || title === undefined || facts.length === 0) return [];\n return [{ key, title, facts }];\n });\n\n const rawType = record.type ?? rawUpdates?.type;\n const type = rawType === undefined ? \"other\" : extractionEntityType(rawType);\n if (type === undefined) return undefined;\n return {\n name:\n extractionText(record.name) ??\n extractionText(record.entityId) ??\n extractionText(rawUpdates?.name) ??\n \"\",\n type,\n facts: [...directFacts, ...updateFacts, ...scalarUpdateFacts],\n structuredSections: structuredSections.length > 0 ? structuredSections : undefined,\n promptedByQuestion: extractionText(record.promptedByQuestion) ?? extractionText(rawUpdates?.promptedByQuestion),\n };\n }\n\n private parseJsonObject(content?: string | null): any | null {\n const trimmed = content?.trim();\n if (!trimmed) return null;\n\n for (const candidate of extractJsonCandidates(trimmed)) {\n try {\n return JSON.parse(candidate);\n } catch {\n // keep trying candidates\n }\n }\n\n return null;\n }\n\n private normalizeContradictionVerificationResult(parsed: any): ContradictionVerificationResult | null {\n if (!parsed || typeof parsed.isContradiction !== \"boolean\") return null;\n\n const rawWhich = parsed.whichIsNewer ?? parsed.winner;\n const normalizedWhich =\n rawWhich === \"first\" || rawWhich === \"existing\"\n ? \"first\"\n : rawWhich === \"second\" || rawWhich === \"new\"\n ? \"second\"\n : \"unclear\";\n\n return {\n isContradiction: Boolean(parsed.isContradiction),\n confidence: typeof parsed.confidence === \"number\" ? parsed.confidence : 0.5,\n reasoning:\n typeof parsed.reasoning === \"string\"\n ? parsed.reasoning\n : typeof parsed.explanation === \"string\"\n ? parsed.explanation\n : \"\",\n whichIsNewer: normalizedWhich,\n };\n }\n\n private normalizeSuggestedLinksResult(parsed: any): SuggestedLinks | null {\n if (!parsed || !Array.isArray(parsed.links)) {\n return null;\n }\n\n const normalizedLinks = parsed.links\n .map((link: any) => {\n const rawLinkType = link?.linkType ?? link?.type;\n return {\n targetId: typeof link?.targetId === \"string\" ? link.targetId : \"\",\n linkType:\n rawLinkType === \"follows\" ||\n rawLinkType === \"references\" ||\n rawLinkType === \"contradicts\" ||\n rawLinkType === \"supports\" ||\n rawLinkType === \"related\"\n ? rawLinkType\n : \"related\",\n strength: typeof link?.strength === \"number\" ? Math.max(0, Math.min(1, link.strength)) : 0.5,\n reason: typeof link?.reason === \"string\" ? link.reason : undefined,\n };\n })\n .filter((link: any) => link.targetId.length > 0);\n\n return { links: normalizedLinks };\n }\n\n private normalizeMemorySummaryResult(parsed: any): MemorySummaryResult | null {\n if (!parsed) return null;\n\n const normalized: MemorySummaryResult = {\n summaryText:\n typeof parsed.summaryText === \"string\"\n ? parsed.summaryText\n : typeof parsed.summary === \"string\"\n ? parsed.summary\n : \"\",\n keyFacts: Array.isArray(parsed.keyFacts) ? parsed.keyFacts.filter((f: unknown) => typeof f === \"string\") : [],\n keyEntities: Array.isArray(parsed.keyEntities)\n ? parsed.keyEntities.filter((e: unknown) => typeof e === \"string\")\n : Array.isArray(parsed.entities)\n ? parsed.entities.filter((e: unknown) => typeof e === \"string\")\n : [],\n };\n\n return normalized.summaryText.length > 0 ? normalized : null;\n }\n\n private normalizeDaySummaryResult(parsed: any): DaySummaryResultShape | null {\n if (!parsed) return null;\n\n const normalized: DaySummaryResultShape = {\n summary: typeof parsed.summary === \"string\" ? parsed.summary.trim() : \"\",\n bullets: Array.isArray(parsed.bullets)\n ? parsed.bullets.filter((item: unknown) => typeof item === \"string\").map((item: string) => item.trim()).filter(Boolean)\n : [],\n next_actions: Array.isArray(parsed.next_actions)\n ? parsed.next_actions.filter((item: unknown) => typeof item === \"string\").map((item: string) => item.trim()).filter(Boolean)\n : [],\n risks_or_open_loops: Array.isArray(parsed.risks_or_open_loops)\n ? parsed.risks_or_open_loops.filter((item: unknown) => typeof item === \"string\").map((item: string) => item.trim()).filter(Boolean)\n : [],\n };\n\n return normalized.summary.length > 0 ? normalized : null;\n }\n\n private sanitizeConsolidationResult(result: {\n items?: unknown[];\n profileUpdates?: unknown[];\n entityUpdates?: unknown[];\n }): ConsolidationResult {\n const items: ConsolidationResult[\"items\"] = [];\n for (const item of Array.isArray(result.items) ? result.items : []) {\n const rawAction = typeof (item as any)?.action === \"string\" ? (item as any).action.toUpperCase() : \"SKIP\";\n const action =\n rawAction === \"ADD\" ||\n rawAction === \"MERGE\" ||\n rawAction === \"UPDATE\" ||\n rawAction === \"INVALIDATE\" ||\n rawAction === \"SKIP\"\n ? rawAction\n : \"SKIP\";\n const existingId =\n typeof (item as any)?.existingId === \"string\"\n ? (item as any).existingId.trim()\n : typeof (item as any)?.newMemoryId === \"string\"\n ? (item as any).newMemoryId.trim()\n : typeof (item as any)?.memoryId === \"string\"\n ? (item as any).memoryId.trim()\n : \"\";\n if (!existingId) continue;\n const mergeWith = typeof (item as any)?.mergeWith === \"string\" ? (item as any).mergeWith : undefined;\n const reason = typeof (item as any)?.reason === \"string\" ? (item as any).reason : \"\";\n const rawUpdatedContent = typeof (item as any)?.updatedContent === \"string\" ? (item as any).updatedContent : undefined;\n if (!rawUpdatedContent) {\n items.push({ existingId, action, mergeWith, updatedContent: undefined, reason });\n continue;\n }\n const sanitized = sanitizeMemoryContent(rawUpdatedContent);\n if (!sanitized.clean) {\n log.warn(`consolidation item sanitized (${existingId}); violations=${sanitized.violations.join(\", \")}`);\n }\n items.push({\n existingId,\n action,\n mergeWith,\n updatedContent: sanitized.text,\n reason,\n });\n }\n const profileUpdates = (Array.isArray(result.profileUpdates) ? result.profileUpdates : [])\n .map((update: any) =>\n typeof update === \"string\"\n ? update.trim()\n : typeof update?.content === \"string\"\n ? update.content.trim()\n : \"\",\n )\n .filter((update) => update.length > 0);\n const entityUpdates = (Array.isArray(result.entityUpdates) ? result.entityUpdates : [])\n .map((entity: unknown): ExtractedEntityResult | undefined => this.normalizeEntityUpdate(entity))\n .filter((entity: ExtractedEntityResult | undefined): entity is ExtractedEntityResult => (\n entity !== undefined && entity.name.length > 0\n ));\n return { items, profileUpdates, entityUpdates };\n }\n\n private async applyProactiveQuestionPass(\n conversation: string,\n base: ExtractionResult,\n ctx: ExtractionGroundingContext,\n signal?: AbortSignal,\n ): Promise<ExtractionResult> {\n if (!resolvePipelineProcessingCapabilities(this.config).proactiveExtraction) return base;\n const maxAdditional = Math.max(0, Math.floor(this.config.maxProactiveQuestionsPerExtraction));\n if (!shouldRunProactivePass(this.config, maxAdditional, this.shouldUseLocalLlm, this.localLlm)) return base;\n\n try {\n const proactive = await this.generateProactiveQuestions(conversation, base, maxAdditional, ctx.ambientCapture === true, signal);\n if (proactive.length === 0) return base;\n const ambient = ctx.ambientCapture === true;\n const proactiveAdditions = await this.answerProactiveQuestions(\n conversation, base, proactive, maxAdditional, ctx.sourceConnector, ambient, signal);\n const sanitizedAdditions = this.sanitizeExtractionResult({ ...proactiveAdditions, facts: stripUntrustedFactSpans(proactiveAdditions.facts) }, ctx.messageTimestamp);\n const groundedAdditions = applyGroundingWithConnector(this.config, sanitizedAdditions, ctx);\n if (!this.hasExtractionOutputs(groundedAdditions)) return base;\n return this.mergeProactiveExtractionPass(base, groundedAdditions, maxAdditional);\n } catch (err) {\n if (signal?.aborted) throw err;\n log.debug(`proactive extraction question pass failed (ignored): ${err}`);\n return base;\n }\n }\n\n private parseProactiveQuestionsFromText(\n content: string,\n existingQuestionKeys: Set<string>,\n ): ExtractionQuestion[] {\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate) as Partial<ProactiveQuestionsResultParsed>;\n if (!Array.isArray(parsed.questions)) continue;\n return parsed.questions\n .map((q) => normalizeQuestion(q as ExtractionQuestion))\n .filter((q) => q.question.length > 0)\n .filter((q) => !existingQuestionKeys.has(q.question.toLowerCase()));\n } catch {\n // Continue to next candidate.\n }\n }\n return [];\n }\n\n private parseProactiveExtractionResultFromText(content: string): ExtractionResult | null {\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = ProactiveExtractionResultSchema.parse(JSON.parse(candidate));\n return this.normalizeExtractionResultPayload({\n ...parsed,\n questions: [],\n });\n } catch {\n // Continue to next candidate.\n }\n }\n return null;\n }\n\n private async generateProactiveQuestions(\n conversation: string,\n base: ExtractionResult,\n maxAdditional: number,\n ambientCapture: boolean,\n signal?: AbortSignal,\n ): Promise<ExtractionQuestion[]> {\n const existingQuestionKeys = new Set(\n (base.questions ?? [])\n .map((q) => q.question.trim().toLowerCase())\n .filter((q) => q.length > 0),\n );\n const factsPreview = base.facts\n .slice(0, 8)\n .map((f) => `- (${f.category}) ${f.content}`)\n .join(\"\\n\");\n const existingQuestionsPreview = (base.questions ?? [])\n .slice(0, 8)\n .map((q) => `- ${q.question}`)\n .join(\"\\n\");\n\n const prompt = [\n \"You are doing a proactive second-pass memory extraction.\",\n `Generate up to ${maxAdditional} additional high-value follow-up questions not already covered.${ambientCapture ? AMBIENT_CAPTURE_PROMPT_SECTION_COMPACT : \"\"}`,\n OUTPUT_LANGUAGE_POLICY,\n \"Return only valid JSON with this shape:\",\n '{\"questions\":[{\"question\":\"...\",\"context\":\"...\",\"priority\":0.0}]}',\n \"\",\n \"Current extracted facts:\",\n factsPreview || \"(none)\",\n \"\",\n \"Questions already extracted (do not repeat):\",\n existingQuestionsPreview || \"(none)\",\n \"\",\n \"Conversation:\",\n conversation,\n ].join(\"\\n\");\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n {\n role: \"system\",\n content: \"You are a proactive memory extraction assistant. Output valid JSON only.\",\n },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.2,\n maxTokens: this.config.proactiveExtractionMaxTokens,\n timeoutMs: this.config.proactiveExtractionTimeoutMs,\n operation: \"proactive_extraction\",\n priority: \"background\",\n signal,\n },\n );\n throwIfExtractionAborted(signal);\n if (localResponse?.content) {\n const localParsed = this.parseProactiveQuestionsFromText(\n localResponse.content.trim(),\n existingQuestionKeys,\n );\n if (localParsed.length > 0) {\n return localParsed.slice(0, maxAdditional);\n }\n }\n if (!this.config.localLlmFallback) {\n return [];\n }\n } catch (err) {\n if (signal?.aborted || !this.config.localLlmFallback) {\n throw err;\n }\n }\n }\n\n const fallbackResult = await this.fallbackLlm.parseWithSchema(\n [\n {\n role: \"system\",\n content: \"Generate additional proactive memory follow-up questions. Return valid JSON only.\",\n },\n { role: \"user\", content: prompt },\n ],\n ProactiveQuestionsResultSchema,\n this.withGatewayAgent({\n temperature: 0.2,\n maxTokens: this.config.proactiveExtractionMaxTokens,\n timeoutMs: this.config.proactiveExtractionTimeoutMs,\n signal,\n }),\n );\n if (!fallbackResult?.questions) return [];\n return fallbackResult.questions\n .map((q) => normalizeQuestion(q as ExtractionQuestion))\n .filter((q) => q.question.length > 0)\n .filter((q) => !existingQuestionKeys.has(q.question.toLowerCase()))\n .slice(0, maxAdditional);\n }\n\n private async answerProactiveQuestions(\n conversation: string,\n base: ExtractionResult,\n proactiveQuestions: ExtractionQuestion[],\n maxAdditional: number,\n sourceConnector: string | undefined,\n ambientCapture: boolean,\n signal?: AbortSignal,\n ): Promise<ExtractionResult> {\n const factsPreview = base.facts\n .slice(0, 8)\n .map((f) => `- (${f.category}) ${f.content}`)\n .join(\"\\n\");\n const entitiesPreview = base.entities\n .slice(0, 8)\n .map((entity) => `- (${entity.type}) ${entity.name}: ${entity.facts.join(\"; \") || \"(no facts)\"}`)\n .join(\"\\n\");\n const proactivePreview = proactiveQuestions\n .slice(0, maxAdditional)\n .map((question, index) => `${index + 1}. ${question.question}${question.context ? `\\n context: ${question.context}` : \"\"}`)\n .join(\"\\n\");\n\n const prompt = [\n \"You are answering proactive memory follow-up questions using only the provided buffered conversation.\",\n `Return at most ${maxAdditional} additional high-confidence memory candidates that were omitted from the base extraction.`,\n `Only include information directly supported by the conversation. Do not speculate. Do not repeat the base extraction.${ambientCapture ? AMBIENT_CAPTURE_PROMPT_SECTION_COMPACT : \"\"}`,\n OUTPUT_LANGUAGE_POLICY,\n \"Return only valid JSON with this shape:\",\n '{\"facts\":[{\"category\":\"fact\",\"content\":\"...\",\"confidence\":0.0,\"tags\":[\"...\"],\"entityRef\":\"optional\",\"promptedByQuestion\":\"optional\",\"quote\":\"optional verbatim span from a single turn\"}],\"profileUpdates\":[\"...\"],\"entities\":[{\"name\":\"...\",\"type\":\"person\",\"facts\":[\"...\"],\"structuredSections\":[{\"key\":\"beliefs\",\"title\":\"Beliefs\",\"facts\":[\"...\"]}],\"promptedByQuestion\":\"optional\"}],\"relationships\":[{\"source\":\"...\",\"target\":\"...\",\"label\":\"...\",\"promptedByQuestion\":\"optional\"}]}',\n this.config.provenance?.enabled\n ? '- Source quotes: For each fact, include a \"quote\" field with the EXACT verbatim words from the conversation that support the fact (a contiguous span from a single turn, not a paraphrase). Cap at ~300 chars.'\n : \"\",\n // #1578: emit the same event-time guidance as the primary extraction\n // paths so proactive-recovered facts also carry an optional eventTime\n // (chatgpt-codex thread on extraction.ts:1607). Returns \"\" when the\n // bi-temporal gate is off, keeping the prompt unchanged by default.\n eventTimePromptInstruction(this.config),\n headerConnector(sourceConnector) !== undefined && resolveMemoryLifecycleCapabilities(this.config).extractionScopeClassification\n ? `Tool, command, or CLI-flag instructions tied to the ${sourceConnector} agent are \"project\" scope; when you recover one, begin the fact with a leading \"In ${sourceConnector}, \" clause naming that agent (e.g. \"In ${sourceConnector}, use the search tool with a repository path.\").`\n : \"\",\n \"\",\n \"Base extracted facts (do not repeat):\",\n factsPreview || \"(none)\",\n \"\",\n \"Base extracted entities (do not repeat):\",\n entitiesPreview || \"(none)\",\n \"\",\n \"Answer these follow-up questions from the same conversation only:\",\n proactivePreview || \"(none)\",\n \"\",\n \"Conversation:\",\n conversation,\n ].join(\"\\n\");\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n {\n role: \"system\",\n content: \"You are a proactive memory extraction assistant. Output valid JSON only.\",\n },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.2,\n maxTokens: this.config.proactiveExtractionMaxTokens,\n timeoutMs: this.config.proactiveExtractionTimeoutMs,\n operation: \"proactive_extraction\",\n priority: \"background\",\n signal,\n },\n );\n throwIfExtractionAborted(signal);\n if (localResponse?.content) {\n const parsed = this.parseProactiveExtractionResultFromText(localResponse.content.trim());\n if (parsed) {\n return parsed;\n }\n }\n if (!this.config.localLlmFallback) {\n return { facts: [], profileUpdates: [], entities: [], questions: [] };\n }\n } catch (err) {\n if (signal?.aborted || !this.config.localLlmFallback) {\n throw err;\n }\n }\n }\n\n const fallbackResult = await this.fallbackLlm.parseWithSchema(\n [\n {\n role: \"system\",\n content: \"Answer proactive memory follow-up questions from the provided conversation only. Return valid JSON only.\",\n },\n { role: \"user\", content: prompt },\n ],\n ProactiveExtractionResultSchema,\n this.withGatewayAgent({\n temperature: 0.2,\n maxTokens: this.config.proactiveExtractionMaxTokens,\n timeoutMs: this.config.proactiveExtractionTimeoutMs,\n signal,\n }),\n );\n if (!fallbackResult) {\n return { facts: [], profileUpdates: [], entities: [], questions: [] };\n }\n return this.normalizeExtractionResultPayload({\n ...fallbackResult,\n questions: [],\n });\n }\n\n private mergeProactiveExtractionPass(\n base: ExtractionResult,\n proactive: ExtractionResult,\n maxAdditional: number,\n ): ExtractionResult {\n const allowlist = this.config.proactiveExtractionCategoryAllowlist;\n let remainingBudget = Math.max(0, Math.floor(maxAdditional));\n const mergedFacts = [...base.facts];\n const seenFacts = new Set(base.facts.map((fact) => normalizeFactKey(fact)));\n for (const fact of proactive.facts) {\n if (remainingBudget <= 0) break;\n if (fact.confidence < PROACTIVE_MIN_CONFIDENCE) continue;\n if (allowlist && !allowlist.includes(fact.category as MemoryCategory)) continue;\n const key = normalizeFactKey(fact);\n if (seenFacts.has(key)) continue;\n seenFacts.add(key);\n mergedFacts.push({ ...fact, source: \"proactive\" });\n remainingBudget -= 1;\n }\n\n const mergedEntities = base.entities.map((entity) => ({\n ...entity,\n facts: [...entity.facts],\n structuredSections: entity.structuredSections\n ? entity.structuredSections.map((section) => ({\n ...section,\n facts: [...section.facts],\n }))\n : undefined,\n }));\n const entityIndex = new Map(mergedEntities.map((entity, index) => [normalizeEntityKey(entity), index]));\n for (const entity of proactive.entities) {\n if (remainingBudget <= 0) break;\n const key = normalizeEntityKey(entity);\n const existingIndex = entityIndex.get(key);\n if (typeof existingIndex === \"number\") {\n const existing = mergedEntities[existingIndex]!;\n const nextFacts = new Set(existing.facts.map((fact) => fact.trim()));\n const nextSections = new Map(\n (existing.structuredSections ?? []).map((section) => [section.key, {\n ...section,\n facts: [...section.facts],\n }]),\n );\n let changed = false;\n for (const fact of entity.facts) {\n const trimmed = fact.trim();\n if (!trimmed || nextFacts.has(trimmed)) continue;\n nextFacts.add(trimmed);\n changed = true;\n }\n for (const section of entity.structuredSections ?? []) {\n const existingSection = nextSections.get(section.key);\n if (!existingSection) {\n nextSections.set(section.key, {\n key: section.key,\n title: section.title,\n facts: [...section.facts],\n });\n changed = true;\n continue;\n }\n const nextSectionFacts = new Set(existingSection.facts.map((fact) => fact.trim()));\n for (const fact of section.facts) {\n const trimmed = fact.trim();\n if (!trimmed || nextSectionFacts.has(trimmed)) continue;\n nextSectionFacts.add(trimmed);\n changed = true;\n }\n existingSection.facts = Array.from(nextSectionFacts);\n }\n if (changed) {\n mergedEntities[existingIndex] = {\n ...existing,\n facts: Array.from(nextFacts),\n structuredSections: Array.from(nextSections.values()),\n source: \"proactive\",\n promptedByQuestion: existing.promptedByQuestion ?? entity.promptedByQuestion,\n };\n remainingBudget -= 1;\n }\n continue;\n }\n mergedEntities.push({\n ...entity,\n source: \"proactive\",\n structuredSections: entity.structuredSections\n ? entity.structuredSections.map((section) => ({\n ...section,\n facts: [...section.facts],\n }))\n : undefined,\n });\n entityIndex.set(key, mergedEntities.length - 1);\n remainingBudget -= 1;\n }\n\n const mergedProfileUpdates = [...base.profileUpdates];\n const seenProfileUpdates = new Set(base.profileUpdates.map((update) => normalizeProfileUpdateKey(update)));\n for (const update of proactive.profileUpdates) {\n if (remainingBudget <= 0) break;\n const key = normalizeProfileUpdateKey(update);\n if (!key || seenProfileUpdates.has(key)) continue;\n seenProfileUpdates.add(key);\n mergedProfileUpdates.push(update.trim());\n remainingBudget -= 1;\n }\n\n const mergedRelationships = [...(base.relationships ?? [])];\n const seenRelationships = new Set(mergedRelationships.map((relationship) => normalizeRelationshipKey(relationship)));\n for (const relationship of proactive.relationships ?? []) {\n if (remainingBudget <= 0) break;\n const key = normalizeRelationshipKey(relationship);\n if (seenRelationships.has(key)) continue;\n seenRelationships.add(key);\n mergedRelationships.push({ ...relationship, extractionSource: \"proactive\" });\n remainingBudget -= 1;\n }\n\n return {\n ...base,\n facts: mergedFacts,\n entities: mergedEntities,\n profileUpdates: mergedProfileUpdates,\n relationships: mergedRelationships,\n };\n }\n\n private async parseWithGatewayFallback<T>(\n traceId: string,\n operation: LlmTraceEvent[\"operation\"],\n startedAtMs: number,\n schema: { parse: (data: unknown) => T },\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: { temperature?: number; maxTokens?: number } = {},\n ): Promise<T | null> {\n const detailed = await this.fallbackLlm.parseWithSchemaDetailed(messages, schema, this.withGatewayAgent(options));\n if (\"modelUsed\" in detailed) {\n const durationMs = Date.now() - startedAtMs;\n this.emit({\n kind: \"llm_end\",\n traceId,\n model: detailed.modelUsed,\n operation,\n durationMs,\n output: JSON.stringify(detailed.result).slice(0, 2000),\n });\n return detailed.result;\n }\n return null;\n }\n\n /**\n * The one funnel every successful extraction path returns through — local\n * LLM, direct client, and gateway fallback alike. The ambient clamp lives\n * here so a new path cannot bypass it (issue #2294).\n */\n private finalizeExtractionResult(\n result: ExtractionResult,\n turns: ReadonlyArray<{\n content: string;\n sessionKey?: string;\n logicalSessionKey?: string;\n timestamp: string;\n turnFingerprint?: string;\n }>,\n sourceConnector?: string,\n ambientCapture = false,\n ): ExtractionResult {\n const clamped = ambientCapture ? clampAmbientCaptureConfidence(result) : result;\n const provenanced = attachExtractionProvenance(clamped, turns, this.config.provenance);\n return sourceConnector === undefined ? provenanced : { ...provenanced, sourceConnector };\n }\n\n async extract(\n turns: BufferTurn[],\n existingEntities?: string[],\n signal?: AbortSignal,\n ): Promise<ExtractionResult> {\n const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);\n\n // Guard: skip if buffer is empty or all turns are whitespace-only\n const substantiveTurns = turns.filter((t) => t.content.trim().length > 0);\n if (substantiveTurns.length === 0) {\n log.debug(\"extraction skipped — no substantive turns in buffer\");\n return { facts: [], profileUpdates: [], entities: [], questions: [] };\n }\n\n const boundedTurns = substantiveTurns\n .map((turn) => ({\n ...turn,\n content: turn.role === \"assistant\"\n ? applyWorkExtractionBoundary(turn.content)\n : turn.content,\n }))\n .filter((turn) => turn.content.trim().length > 0);\n // One derivation, over the turns the model actually sees (boundedTurns) —\n // the same set the qualifier, grounding source, and telemetry filter\n // operate on. result.sourceConnector carries it to persistence so the\n // orchestrator does not recompute over a different turn set (#2183).\n const resolvedConnector = resolveSourceConnector(boundedTurns);\n // Ambient-capture provenance (issue #2294): true when any contributing turn\n // came from an always-on recorder, so the prompt warns about media audio\n // and the finalize chokepoint clamps high-impact personal facts.\n const ambientCapture = boundedTurns.some(\n (turn) => turn.ambientCapture === true && turn.extractionContextOnly !== true,\n );\n // The header and qualifier strip/restore are gated on the scope-classification\n // capability; persistence records resolvedConnector regardless (trusted metadata).\n const sourceConnector = lifecycleCaps.extractionScopeClassification\n ? resolvedConnector\n : undefined;\n const { conversation, renderedConversation } = renderExtractionConversation(boundedTurns, headerConnector(sourceConnector));\n const spanTurns = buildSpanMaterializeTurns(boundedTurns.map((turn) => turn.content));\n\n const groundingSource = boundedTurns\n .map((turn) => turn.content)\n .join(\"\\n\\n\");\n const assertionSource = boundedTurns\n .filter((turn) => turn.extractionContextOnly !== true)\n .map((turn) => turn.content)\n .join(\"\\n\\n\");\n const roleAssertionSources: ExtractionGroundingRoleSources = {\n profile: boundedTurns\n .filter((turn) => turn.role === \"user\" && turn.extractionContextOnly !== true)\n .map((turn) => turn.content)\n .join(\"\\n\\n\"),\n identity: boundedTurns\n .filter((turn) => turn.role === \"assistant\" && turn.extractionContextOnly !== true)\n .map((turn) => turn.content)\n .join(\"\\n\\n\"),\n };\n if (renderedConversation.trim().length === 0) {\n log.debug(\"extraction skipped — conversation only contained non-memory work-layer context\");\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionSkippedReason: \"conversation_only_non_memory\",\n };\n }\n if (\n lifecycleCaps.extractionTelemetryPrefilter &&\n looksLikeMechanicalTelemetryTranscript(renderedConversation)\n ) {\n log.debug(\"extraction skipped — mechanical action/state telemetry without durable-memory cues\");\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionSkippedReason: \"mechanical_telemetry\",\n };\n }\n\n // Use the last turn's timestamp for temporal anchoring (more accurate than wall-clock)\n const lastTurnTs = boundedTurns.length > 0 ? new Date(boundedTurns[boundedTurns.length - 1].timestamp) : undefined;\n const messageTimestamp = lastTurnTs && !isNaN(lastTurnTs.getTime()) ? lastTurnTs : undefined;\n const groundingContext: ExtractionGroundingContext = {\n groundingSource,\n assertionSource,\n roleAssertionSources,\n messageTimestamp,\n sourceConnector,\n ambientCapture,\n scopeClassificationEnabled: lifecycleCaps.extractionScopeClassification,\n };\n\n const traceId = crypto.randomUUID();\n // Only emit llm_start for the direct path when a client or local LLM is configured.\n // Fallback-only deployments skip this to avoid fake spans in Opik.\n const emittedDirectStart = !!(this.shouldUseDirectClient || this.shouldUseLocalLlm);\n if (emittedDirectStart) {\n this.emit({ kind: \"llm_start\", traceId, model: this.config.model, operation: \"extraction\", input: conversation });\n }\n let closedDirectTrace = false;\n const startTime = Date.now();\n\n // --- profiling instrumentation ---\n const extractionTraceId = this.profiler.startTrace(\"extraction\", undefined, {\n model: this.config.model,\n localLlm: resolveLocalLlmCapabilities(this.config).localLlm,\n });\n this.profiler.startSpan(\"total\", extractionTraceId);\n // True when a local or direct extractor was attempted before the gateway\n // fallback, so a gateway \"no models\" result doesn't re-classify a real\n // primary failure as auth_config (codex review: preserve direct/local failures).\n let primaryExtractorAttempted = false;\n\n try {\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n this.profiler.startSpan(\"local-llm\", extractionTraceId);\n primaryExtractorAttempted = true;\n try {\n const localResult = await this.extractWithLocalLlm(conversation, existingEntities, signal, ambientCapture);\n throwIfExtractionAborted(signal);\n if (localResult) {\n const durationMs = Date.now() - startTime;\n this.profiler.endSpan(\"local-llm\", extractionTraceId);\n this.emit({ kind: \"llm_end\", traceId, model: this.config.localLlmModel, operation: \"extraction\", durationMs });\n log.debug(`extraction: used local LLM — ${localResult.facts.length} facts, ${localResult.entities.length} entities`);\n const localSpanTurns = bindLocalExtractionPrompt(\n conversation,\n boundedTurns,\n this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext,\n ).maxInputChars,\n renderedConversation,\n ).spanTurns;\n const sanitized = this.sanitizeExtractionResult(this.applySpanMaterialization(localResult, localSpanTurns), messageTimestamp);\n const grounded = applyGroundingWithConnector(this.config, sanitized, groundingContext);\n const finalResult = await this.applyProactiveQuestionPass(conversation, grounded, groundingContext, signal);\n return this.finalizeExtractionResult(finalResult, boundedTurns, resolvedConnector, ambientCapture);\n }\n // Local failed, fall back if allowed\n if (!this.config.localLlmFallback) {\n log.warn(\"extraction: local LLM failed and fallback disabled\");\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionFailure: \"local_llm_unavailable\",\n extractionFailureClass: \"provider_retryable\",\n };\n }\n log.info(\"extraction: local LLM unavailable, falling back to gateway default AI\");\n } catch (err) {\n if (signal?.aborted) throw err;\n if (!this.config.localLlmFallback) {\n log.warn(\"extraction: local LLM error and fallback disabled:\", err);\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionFailure: \"local_llm_error\",\n extractionFailureClass: \"provider_retryable\",\n };\n }\n log.info(\"extraction: local LLM error, falling back to gateway default AI:\", err);\n } finally {\n // End local-llm span if it wasn't ended on the success path\n try { this.profiler.endSpan(\"local-llm\", extractionTraceId); } catch { /* span may already be closed */ }\n }\n }\n\n // Try direct OpenAI-compatible client (Scryr, OpenRouter, etc.)\n if (this.shouldUseDirectClient) {\n this.profiler.startSpan(\"direct-client\", extractionTraceId);\n primaryExtractorAttempted = true;\n try {\n const directResult = await this.extractWithDirectClient(conversation, existingEntities, signal, ambientCapture);\n if (directResult) {\n const durationMs = Date.now() - startTime;\n this.profiler.endSpan(\"direct-client\", extractionTraceId);\n this.emit({ kind: \"llm_end\", traceId, model: this.config.model, operation: \"extraction\", durationMs });\n log.debug(`extraction: used direct client (${this.config.model}) — ${directResult.facts.length} facts, ${directResult.entities.length} entities`);\n const sanitized = this.sanitizeExtractionResult(this.applySpanMaterialization(directResult, spanTurns), messageTimestamp);\n const grounded = applyGroundingWithConnector(this.config, sanitized, groundingContext);\n const finalResult = await this.applyProactiveQuestionPass(conversation, grounded, groundingContext, signal);\n return this.finalizeExtractionResult(finalResult, boundedTurns, resolvedConnector, ambientCapture);\n }\n // Emit error event so Opik sees the direct client failure before fallback.\n // Wrapped in try/catch so a subscriber error doesn't break the fallback path.\n try {\n this.emit({\n kind: \"llm_error\", traceId, model: this.config.model, operation: \"extraction\",\n durationMs: Date.now() - startTime, error: \"direct client returned no result\",\n });\n } catch { /* trace emit must not block fallback */ }\n closedDirectTrace = true;\n log.info(\"extraction: direct client returned no result, falling back to gateway AI\");\n } catch (err) {\n if (signal?.aborted) throw err;\n try {\n this.emit({\n kind: \"llm_error\", traceId, model: this.config.model, operation: \"extraction\",\n durationMs: Date.now() - startTime, error: String(err),\n });\n } catch { /* trace emit must not block fallback */ }\n closedDirectTrace = true;\n log.info(\"extraction: direct client failed, falling back to gateway AI:\", err);\n } finally {\n try { this.profiler.endSpan(\"direct-client\", extractionTraceId); } catch { /* span may already be closed */ }\n }\n }\n\n // Close any orphaned direct-path llm_start (e.g., local LLM failed, no direct client)\n if (emittedDirectStart && !closedDirectTrace) {\n try {\n this.emit({\n kind: \"llm_error\", traceId, model: this.config.model, operation: \"extraction\",\n durationMs: Date.now() - startTime, error: \"local LLM failed, handing off to gateway fallback\",\n });\n } catch { /* trace emit must not block fallback */ }\n }\n\n // In gateway mode this is the primary extraction path. In plugin mode it is the\n // final fallback after local/direct attempts fail. Emit a fresh llm_start so the\n // gateway-backed call gets its own trace rather than being orphaned under the\n // direct-client traceId.\n const fallbackTraceId = crypto.randomUUID();\n const fallbackStartTime = Date.now();\n if (this.useGatewayModelSource) {\n log.debug(\n `extraction: using gateway model chain as primary path` +\n (this.config.taskModelChain ? \" (taskModelChain)\" :\n this.config.gatewayAgentId ? ` (agent: ${this.config.gatewayAgentId})` : \" (defaults)\"),\n );\n } else {\n log.info(\"extraction: falling back to gateway default AI\");\n }\n\n this.profiler.startSpan(\"gateway-fallback\", extractionTraceId);\n try {\n const messages = [\n {\n role: \"system\" as const,\n content:\n buildExtractionInstructions(this.config, existingEntities, ambientCapture) +\n `\\n\\nReturn only valid JSON matching this shape. Placeholder text describes field shape only and is never source evidence:\\n${extractionResponseShape(this.config.extraction?.spanMode ?? \"off\")}`,\n },\n { role: \"user\" as const, content: conversation },\n ];\n\n this.emit({ kind: \"llm_start\", traceId: fallbackTraceId, model: \"fallback\", operation: \"extraction\", input: conversation });\n\n const detailed = await this.fallbackLlm.parseWithSchemaDetailed(\n messages,\n ExtractionResultSchema,\n this.withGatewayAgent({\n temperature: 0.3,\n maxTokens: this.config.extractionMaxOutputTokens,\n timeoutMs: this.config.taskLlmTimeoutMs ?? this.config.localLlmTimeoutMs,\n jsonSchema: {\n name: \"extraction_result\",\n schema: EXTRACTION_PROVIDER_JSON_SCHEMA,\n strict: false,\n },\n signal,\n }),\n );\n\n const fallbackDurationMs = Date.now() - fallbackStartTime;\n\n if (\"modelUsed\" in detailed && Array.isArray(detailed.result.facts)) {\n const result = detailed.result;\n this.emit({\n kind: \"llm_end\", traceId: fallbackTraceId, model: detailed.modelUsed, operation: \"extraction\",\n durationMs: fallbackDurationMs, output: JSON.stringify(result).slice(0, 2000),\n });\n log.debug(\n `extracted ${result.facts.length} facts, ${result.entities.length} entities, ${(result.questions ?? []).length} questions via fallback (${detailed.modelUsed})`,\n );\n const normalized = this.normalizeExtractionResultPayload(result);\n const sanitized = this.sanitizeExtractionResult(this.applySpanMaterialization(normalized, spanTurns), messageTimestamp);\n const grounded = applyGroundingWithConnector(this.config, sanitized, groundingContext);\n const finalResult = await this.applyProactiveQuestionPass(conversation, grounded, groundingContext, signal);\n return this.finalizeExtractionResult(finalResult, boundedTurns, resolvedConnector, ambientCapture);\n }\n\n const parseFailure =\n detailed.result === null\n ? detailed\n : { failureReason: \"empty\" as const, attemptedModel: undefined, httpStatus: undefined, errorClass: \"empty\" };\n const failureLog = formatExtractionParseFailureLog({\n failureReason: parseFailure.failureReason,\n attemptedModel: parseFailure.attemptedModel,\n httpStatus: parseFailure.httpStatus,\n errorClass: parseFailure.errorClass,\n traceId: fallbackTraceId,\n });\n this.emit({\n kind: \"llm_error\",\n traceId: fallbackTraceId,\n model: parseFailure.attemptedModel ?? \"fallback\",\n operation: \"extraction\",\n durationMs: fallbackDurationMs,\n error: failureLog,\n });\n log.warn(failureLog);\n const fallbackParseFailureClass: ExtractionFailureClass =\n detailed.result === null\n ? detailed.failureReason === \"no_models\" && primaryExtractorAttempted\n ? // Gateway had no models, but a local/direct extractor already failed —\n // the root cause is the primary (transient), not gateway auth/config.\n \"provider_retryable\"\n : classifyFallbackParseFailure(detailed.failureReason)\n : \"parse_empty\";\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionFailure: \"fallback_no_parsed_output\",\n extractionFailureClass: fallbackParseFailureClass,\n };\n } catch (err) {\n if (signal?.aborted) throw err;\n this.emit({\n kind: \"llm_error\", traceId: fallbackTraceId, model: \"fallback\", operation: \"extraction\",\n durationMs: Date.now() - fallbackStartTime, error: String(err),\n });\n log.error(\"extraction fallback failed\", err);\n return {\n facts: [],\n profileUpdates: [],\n entities: [],\n questions: [],\n extractionFailure: \"fallback_failed\",\n extractionFailureClass: classifyExtractionThrownError(err),\n };\n } finally {\n try { this.profiler.endSpan(\"gateway-fallback\", extractionTraceId); } catch { /* span may already be closed */ }\n }\n\n } finally {\n // --- profiling: close the total span and trace ---\n this.profiler.endSpan(\"total\", extractionTraceId);\n this.profiler.endTrace(extractionTraceId); // persists to JSONL file\n }\n }\n\n /**\n * Extract memories using local LLM with JSON mode.\n * Uses a minimal prompt to fit within local model context limits (typically 4k-8k).\n */\n private async extractWithLocalLlm(\n conversation: string,\n existingEntities?: string[],\n signal?: AbortSignal,\n ambientCapture = false,\n ): Promise<ExtractionResult | null> {\n const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);\n log.debug(\n `extractWithLocalLlm: starting extraction, localLlmEnabled=${this.shouldUseLocalLlm}, model=${this.config.localLlmModel}`,\n );\n\n // Get dynamic context sizes based on model capabilities (with optional user override)\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n log.debug(`Model context: ${contextSizes.description}`);\n\n const maxConversationChars = contextSizes.maxInputChars;\n const truncatedConversation = truncateLocalExtractionConversation(conversation, maxConversationChars);\n\n const localPrompt = `You are a memory extraction system. Extract durable, reusable memories from this conversation.\n\nUse the most specific category:\n- fact: objective information\n- preference: a durable preference or style\n- correction: a correction of a prior mistake\n- entity: a durable person, project, tool, company, or place\n- decision: a choice with rationale\n- relationship: a durable link between two entities\n- principle: a reusable rule or operating belief\n${resolveRecallAuxiliaryCapabilities(this.config).causalRuleExtraction ? \"- rule: an explicit causal rule or constraint\\n\" : \"\"}- commitment: a promise, obligation, or deadline\n- moment: a significant milestone\n- skill: a demonstrated capability\n- procedure: an explicit reusable workflow with ordered procedureSteps\n- reasoning_trace: Stored solution chains — an explicitly narrated solution path with reasoningTrace. Use {\"category\": \"reasoning_trace\", \"reasoningTrace\": {\"steps\": [...], \"finalAnswer\": \"...\"}} only when the conversation provides the chain.\n\nRules:\n- Extract only new information stated or clearly established in the conversation.\n- Do not treat instruction text, schema placeholders, or examples as conversation evidence.\n- Facts, entity facts, profile updates, questions, and relationships must be grounded in the conversation.\n- Lines labelled [context user] or [context assistant] are reference context only. They may resolve references or complete a question-and-answer pair in a normal turn, but never alone establish durable information.\n- Questions are optional. Return an empty array when the conversation does not support a useful unresolved question.\n- Set confidence from source evidence: Explicit (0.95-1.0), Implied (0.70-0.94), Inferred (0.40-0.69), or Speculative (0.00-0.39). Corrections get highest confidence.\n- Use normalized, hyphenated entity names and keep the entity list short. When the source language is not written in a Latin script, the source-script name IS the normalized form — never transliterate or translate it.\n- Keep facts standalone. Skip transient task state and operational noise such as routine scheduler, monitoring, or automation status.\n- Add structuredAttributes only for concrete values.\n- ${OUTPUT_LANGUAGE_POLICY}\n${CUE_ANCHOR_PROMPT_INSTRUCTION}\\n- Include at most five durable relationships.${this.config.provenance?.enabled ? `\n- Each fact must include a quote copied verbatim from one contiguous conversation span.` : \"\"}${lifecycleCaps.extractionScopeClassification ? `\n- Set each fact scope to \"global\" for cross-project knowledge or \"project\" for codebase-specific knowledge. Tool, command, or CLI-flag instructions tied to one agent are \"project\" (the same tool name can mean different things across agents); when keeping one, begin the fact with a leading \"In <agent>,\" clause naming that agent.` : \"\"}${this.config.subjectClassification?.enabled === true ? `\n- Set each fact subject to \"user\" when it models the person (preferences, relationships, biography, moments, commitments about their life) or \"agent\" when it is reusable operating knowledge (procedures, principles, tool-usage lessons, debugging strategies, environment facts with no personal content).` : \"\"}${ambientCapture ? AMBIENT_CAPTURE_PROMPT_SECTION_COMPACT : \"\"}\n${eventTimePromptInstruction(this.config)}${spanModePromptSection(this.config.extraction?.spanMode ?? \"off\")}\nReturn only valid JSON matching this shape. Placeholder text describes field shape only and is never source evidence:\n${extractionResponseShape(this.config.extraction?.spanMode ?? \"off\")}\n\nConversation:\n${truncatedConversation}`;\n\n log.debug(\n `extractWithLocalLlm: calling localLlm.chatCompletion with prompt length ${localPrompt.length}...`,\n );\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"You are a memory extraction system. Output valid JSON only.\" },\n { role: \"user\", content: localPrompt },\n ],\n {\n temperature: 0.1,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"extraction\",\n disableThinking: shouldEnableLocalExtractionThinking(this.config, conversation.length)\n ? false\n : undefined,\n priority: \"background\",\n signal,\n },\n );\n\n if (!response?.content) {\n log.debug(\"extractWithLocalLlm: chatCompletion returned null or empty content\");\n return null;\n }\n\n const content = response.content.trim();\n // Avoid logging model output content by default (may contain user data).\n log.debug(`extractWithLocalLlm: got response content, length=${content.length}`);\n\n for (const candidate of extractJsonCandidates(content)) {\n try {\n log.debug(`extractWithLocalLlm: attempting JSON parse, candidate length=${candidate.length}`);\n const parsed = JSON.parse(candidate);\n if (!this.looksLikeExtractionResultPayload(parsed)) {\n continue;\n }\n\n const result: ExtractionResult = this.normalizeExtractionResultPayload(parsed);\n\n log.debug(\n `extractWithLocalLlm: successfully parsed response, facts=${result.facts.length}, entities=${result.entities.length}, profileUpdates=${result.profileUpdates.length}, questions=${result.questions.length}`,\n );\n return result;\n } catch {\n // keep trying candidates\n }\n }\n\n // Try to extract partial facts from truncated JSON after all complete JSON\n // candidates fail to parse.\n log.debug(\"extractWithLocalLlm: JSON parse failed, attempting partial extraction...\");\n const partial = this.extractPartialFacts(content);\n if (partial.facts.length > 0 || partial.entities.length > 0) {\n log.debug(\n `extractWithLocalLlm: extracted ${partial.facts.length} partial facts from truncated JSON`,\n );\n return partial;\n }\n return null;\n }\n\n /**\n * Extract memories using direct OpenAI-compatible client (Chat Completions API).\n * Works with Scryr, OpenRouter, and other OpenAI-compatible endpoints.\n */\n private async extractWithDirectClient(\n conversation: string,\n existingEntities?: string[],\n signal?: AbortSignal,\n ambientCapture = false,\n ): Promise<ExtractionResult | null> {\n if (!this.client) return null;\n\n const tokenParams = buildChatCompletionTokenLimit(this.config.model, this.config.extractionMaxOutputTokens, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n });\n log.debug(`extractWithDirectClient: calling model=${this.config.model} tokenParams=${JSON.stringify(tokenParams)}`);\n\n const response = await this.client.chat.completions.create(\n {\n model: this.config.model,\n messages: [\n {\n role: \"system\",\n content:\n buildExtractionInstructions(this.config, existingEntities, ambientCapture) +\n `\\n\\nReturn only valid JSON matching this shape. Placeholder text describes field shape only and is never source evidence:\\n${extractionResponseShape(this.config.extraction?.spanMode ?? \"off\")}`,\n },\n { role: \"user\", content: conversation },\n ],\n ...tokenParams,\n },\n signal ? { signal } : undefined,\n );\n\n const content = response.choices?.[0]?.message?.content?.trim();\n if (!content) {\n log.info(`extractWithDirectClient: empty response — choices=${JSON.stringify(response.choices?.length ?? 0)} finishReason=${response.choices?.[0]?.finish_reason ?? \"n/a\"}`);\n return null;\n }\n\n log.info(\n `extractWithDirectClient: got response, length=${content.length}`,\n );\n\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n\n return this.normalizeExtractionResultPayload(parsed);\n } catch {\n // keep trying candidates\n }\n }\n\n log.info(`extractWithDirectClient: failed to parse JSON from response (first 200 chars: ${content.slice(0, 200)})`);\n return null;\n }\n\n /**\n * Extract partial facts from truncated JSON responses.\n * Local LLMs sometimes hit token limits mid-JSON. This tries to salvage valid facts.\n */\n private extractPartialFacts(jsonStr: string): ExtractionResult {\n\n const facts: ExtractionResult[\"facts\"] = [];\n const entities: ExtractionResult[\"entities\"] = [];\n\n try {\n // Find all complete fact objects (ones with all required fields)\n const factRegex = /\\{\\s*\"category\"\\s*:\\s*\"([^\"]+)\"\\s*,\\s*\"content\"\\s*:\\s*\"([^\"]+)\"\\s*,\\s*\"confidence\"\\s*:\\s*([0-9.]+)/g;\n let match;\n while ((match = factRegex.exec(jsonStr)) !== null) {\n const category = match[1]?.trim() ?? \"\";\n if (!isMemoryCategory(category)) continue;\n facts.push({\n category,\n content: match[2].replace(/\\\\n/g, '\\n').replace(/\\\\\"/g, '\"'),\n confidence: parseFloat(match[3]),\n tags: [],\n });\n }\n\n // Find all complete entity objects\n const entityRegex = /\\{\\s*\"name\"\\s*:\\s*\"([^\"]+)\"\\s*,\\s*\"type\"\\s*:\\s*\"([^\"]+)\"/g;\n while ((match = entityRegex.exec(jsonStr)) !== null) {\n const type = extractionEntityType(match[2]);\n if (type === undefined) continue;\n entities.push({\n name: match[1],\n type,\n facts: [],\n });\n }\n } catch {\n // Ignore regex errors\n }\n\n return this.normalizeExtractionResultPayload({ facts, entities, profileUpdates: [], questions: [] });\n }\n\n async consolidate(\n newMemories: MemoryFile[],\n existingMemories: MemoryFile[],\n currentProfile: string,\n ): Promise<ConsolidationResult> {\n const newList = newMemories\n .map(\n (m) =>\n `[${m.frontmatter.id}] (${m.frontmatter.category}) ${m.content}`,\n )\n .join(\"\\n\");\n\n const existingList = existingMemories\n .slice(-50) // Only consolidate against recent memories\n .map(\n (m) =>\n `[${m.frontmatter.id}] (${m.frontmatter.category}) ${m.content}`,\n )\n .join(\"\\n\");\n\n const cTraceId = crypto.randomUUID();\n this.emit({ kind: \"llm_start\", traceId: cTraceId, model: this.config.model, operation: \"consolidation\", input: newList });\n const cStartTime = Date.now();\n\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n try {\n const localResult = await this.consolidateWithLocalLlm(newList, existingList, currentProfile);\n if (localResult) {\n const durationMs = Date.now() - cStartTime;\n this.emit({ kind: \"llm_end\", traceId: cTraceId, model: this.config.localLlmModel, operation: \"consolidation\", durationMs });\n log.debug(`consolidation: used local LLM — ${localResult.items.length} decisions`);\n return this.sanitizeConsolidationResult(localResult);\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"consolidation: local LLM failed and fallback disabled\");\n return { items: [], profileUpdates: [], entityUpdates: [] };\n }\n log.info(\"consolidation: local LLM unavailable, falling back to gateway AI\");\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(\"consolidation: local LLM error and fallback disabled:\", err);\n return { items: [], profileUpdates: [], entityUpdates: [] };\n }\n log.info(\"consolidation: local LLM error, falling back to gateway AI:\", err);\n }\n }\n\n const fallbackResult = await this.parseWithGatewayFallback(\n cTraceId,\n \"consolidation\",\n cStartTime,\n ConsolidationResultSchema,\n [\n {\n role: \"system\",\n content: buildConsolidationSystemPrompt(this.config),\n },\n {\n role: \"user\",\n content: `Current behavioral profile:\n${currentProfile || \"(empty)\"}\n\nExisting memories:\n${existingList || \"(none)\"}\n\nNew memories to consolidate:\n${newList}\n\nConsolidate the new memories against existing ones.`,\n },\n ],\n { temperature: 0.3, maxTokens: 4096 },\n );\n if (fallbackResult) {\n log.debug(`consolidation: ${fallbackResult.items.length} decisions via fallback`);\n return this.sanitizeConsolidationResult({\n items: fallbackResult.items,\n profileUpdates: fallbackResult.profileUpdates,\n entityUpdates: fallbackResult.entityUpdates,\n });\n }\n\n // Fall back to OpenAI API\n if (!this.client) {\n log.warn(\"consolidation skipped — no OpenAI API key and local LLM failed/disabled\");\n return { items: [], profileUpdates: [], entityUpdates: [] };\n }\n\n try {\n const instructionText = `${buildConsolidationSystemPrompt(this.config)}\n\nCurrent behavioral profile:\n${currentProfile || \"(empty)\"}\n\nExisting memories:\n${existingList || \"(none)\"}\n\nNew memories to consolidate:\n${newList}\n\nRespond with valid JSON only, matching this schema:\n${CONSOLIDATION_RESPONSE_SCHEMA}`;\n\n const response = await this.client.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: \"Consolidate the new memories against existing ones.\" },\n ],\n ...(this.config.reasoningEffort !== \"none\" ? { reasoning_effort: this.config.reasoningEffort } : {}),\n ...buildChatCompletionTokenLimit(this.config.model, 4096, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const rawContent = response.choices?.[0]?.message?.content?.trim();\n const cDurationMs = Date.now() - cStartTime;\n const cUsage = (response as any).usage;\n\n let parsed: any = null;\n if (rawContent) {\n for (const candidate of extractJsonCandidates(rawContent)) {\n try {\n parsed = JSON.parse(candidate);\n break;\n } catch {\n // keep trying candidates\n }\n }\n }\n\n this.emit({\n kind: \"llm_end\", traceId: cTraceId, model: this.config.model, operation: \"consolidation\", durationMs: cDurationMs,\n output: parsed ? JSON.stringify(parsed).slice(0, 2000) : undefined,\n tokenUsage: cUsage ? { input: cUsage.prompt_tokens, output: cUsage.completion_tokens, total: cUsage.total_tokens } : undefined,\n });\n\n if (parsed && Array.isArray(parsed.items)) {\n log.debug(\n `consolidation: ${parsed.items.length} decisions`,\n );\n return this.sanitizeConsolidationResult({\n items: parsed.items,\n profileUpdates: Array.isArray(parsed.profileUpdates) ? parsed.profileUpdates : [],\n entityUpdates: Array.isArray(parsed.entityUpdates) ? parsed.entityUpdates : [],\n });\n }\n\n log.warn(\"consolidation returned no parsed output\");\n return { items: [], profileUpdates: [], entityUpdates: [] };\n } catch (err) {\n this.emit({\n kind: \"llm_error\", traceId: cTraceId, model: this.config.model, operation: \"consolidation\",\n durationMs: Date.now() - cStartTime, error: String(err),\n });\n log.error(\"consolidation failed\", err);\n return { items: [], profileUpdates: [], entityUpdates: [] };\n }\n }\n\n /**\n * Consolidate memories using local LLM.\n */\n private async consolidateWithLocalLlm(\n newList: string,\n existingList: string,\n currentProfile: string,\n ): Promise<ConsolidationResult | null> {\n // Get dynamic context sizes\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n log.debug(`Consolidation model context: ${contextSizes.description}`);\n\n const prompt = `${buildConsolidationSystemPrompt(this.config)}\n\nCurrent behavioral profile:\n${currentProfile || \"(empty)\"}\n\nExisting memories:\n${existingList || \"(none)\"}\n\nNew memories to consolidate:\n${newList}\n\nRespond with valid JSON matching this schema:\n${CONSOLIDATION_RESPONSE_SCHEMA}`;\n\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"You are a memory consolidation system. Output valid JSON only.\" },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.3,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"consolidation\",\n priority: \"background\",\n },\n );\n\n if (!response?.content) {\n return null;\n }\n\n try {\n const content = response.content.trim();\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n return {\n items: Array.isArray((parsed as any).items) ? (parsed as any).items : [],\n profileUpdates: Array.isArray((parsed as any).profileUpdates)\n ? (parsed as any).profileUpdates\n : [],\n entityUpdates: Array.isArray((parsed as any).entityUpdates)\n ? (parsed as any).entityUpdates\n : [],\n } as ConsolidationResult;\n } catch {\n // keep trying candidates\n }\n }\n return null;\n } catch (err) {\n log.warn(\"local LLM consolidation: failed to parse JSON response:\", err);\n return null;\n }\n }\n\n /**\n * Consolidate a bloated profile.md into a compact version.\n * The LLM merges duplicates, removes stale info, and preserves section structure.\n * Returns the consolidated markdown or null on failure.\n */\n async consolidateProfile(\n fullProfileContent: string,\n targetLines: number = 50,\n ): Promise<{ consolidatedProfile: string; removedCount: number; summary: string } | null> {\n const pTraceId = crypto.randomUUID();\n this.emit({ kind: \"llm_start\", traceId: pTraceId, model: this.config.model, operation: \"profile_consolidation\", input: fullProfileContent.slice(0, 2000) });\n const pStartTime = Date.now();\n\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n try {\n const localResult = await this.consolidateProfileWithLocalLlm(fullProfileContent, targetLines);\n if (localResult) {\n const durationMs = Date.now() - pStartTime;\n this.emit({ kind: \"llm_end\", traceId: pTraceId, model: this.config.localLlmModel, operation: \"profile_consolidation\", durationMs });\n log.debug(`profile consolidation: used local LLM — removed ${localResult.removedCount} items`);\n return localResult;\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"profile consolidation: local LLM failed and fallback disabled\");\n return null;\n }\n log.info(\"profile consolidation: local LLM unavailable, falling back to gateway AI\");\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(\"profile consolidation: local LLM error and fallback disabled:\", err);\n return null;\n }\n log.info(\"profile consolidation: local LLM error, falling back to gateway AI:\", err);\n }\n }\n\n const profileFallback = await this.parseWithGatewayFallback(\n pTraceId,\n \"profile_consolidation\",\n pStartTime,\n buildProfileConsolidationResultSchema(targetLines),\n [\n {\n role: \"system\",\n content: buildProfileConsolidationSystemPrompt(targetLines),\n },\n { role: \"user\", content: fullProfileContent },\n ],\n { temperature: 0.3, maxTokens: 4096 },\n );\n if (profileFallback) {\n log.debug(\n `profile consolidation: removed ${profileFallback.removedCount} items — ${profileFallback.summary} (fallback)`,\n );\n return profileFallback;\n }\n\n // Fall back to OpenAI API\n if (!this.client) {\n log.warn(\"profile consolidation skipped — no OpenAI API key and local LLM failed/disabled\");\n return null;\n }\n\n try {\n const instructionText = `${buildProfileConsolidationSystemPrompt(targetLines)}\n\nRespond with valid JSON matching this schema:\n${PROFILE_CONSOLIDATION_RESPONSE_SCHEMA}`;\n\n const response = await this.client.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: fullProfileContent },\n ],\n ...(this.config.reasoningEffort !== \"none\" ? { reasoning_effort: this.config.reasoningEffort } : {}),\n ...buildChatCompletionTokenLimit(this.config.model, 4096, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const rawContent = response.choices?.[0]?.message?.content?.trim();\n const pDurationMs = Date.now() - pStartTime;\n const pUsage = (response as any).usage;\n\n let parsed: any = null;\n if (rawContent) {\n for (const candidate of extractJsonCandidates(rawContent)) {\n try {\n parsed = JSON.parse(candidate);\n break;\n } catch {\n // keep trying candidates\n }\n }\n }\n\n this.emit({\n kind: \"llm_end\", traceId: pTraceId, model: this.config.model, operation: \"profile_consolidation\", durationMs: pDurationMs,\n output: parsed ? parsed.summary : undefined,\n tokenUsage: pUsage ? { input: pUsage.prompt_tokens, output: pUsage.completion_tokens, total: pUsage.total_tokens } : undefined,\n });\n\n if (parsed && typeof parsed.consolidatedProfile === \"string\") {\n log.debug(\n `profile consolidation: removed ${parsed.removedCount ?? 0} items — ${parsed.summary ?? \"\"}`,\n );\n return {\n consolidatedProfile: parsed.consolidatedProfile,\n removedCount: Number(parsed.removedCount || 0),\n summary: String(parsed.summary || \"\"),\n };\n }\n\n log.warn(\"profile consolidation returned no parsed output\");\n return null;\n } catch (err) {\n this.emit({\n kind: \"llm_error\", traceId: pTraceId, model: this.config.model, operation: \"profile_consolidation\",\n durationMs: Date.now() - pStartTime, error: String(err),\n });\n log.error(\"profile consolidation failed\", err);\n return null;\n }\n }\n\n /**\n * Consolidate profile using local LLM.\n */\n private async consolidateProfileWithLocalLlm(\n fullProfileContent: string,\n targetLines: number = 50,\n ): Promise<{ consolidatedProfile: string; removedCount: number; summary: string } | null> {\n // Get dynamic context sizes\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n log.debug(`Profile consolidation model context: ${contextSizes.description}`);\n\n const prompt = `${buildProfileConsolidationSystemPrompt(targetLines)}\n\nProfile to consolidate:\n${fullProfileContent}\n\nRespond with valid JSON matching this schema:\n${PROFILE_CONSOLIDATION_RESPONSE_SCHEMA}`;\n\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"You are a profile consolidation system. Output valid JSON only.\" },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.3,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"profile_consolidation\",\n priority: \"background\",\n },\n );\n\n if (!response?.content) {\n return null;\n }\n\n try {\n const content = response.content.trim();\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n return {\n consolidatedProfile: String((parsed as any).consolidatedProfile || \"\"),\n removedCount: Number((parsed as any).removedCount || 0),\n summary: String((parsed as any).summary || \"\"),\n };\n } catch {\n // keep trying candidates\n }\n }\n return null;\n } catch (err) {\n log.warn(\"local LLM profile consolidation: failed to parse JSON response:\", err);\n return null;\n }\n }\n\n /**\n * Consolidate IDENTITY.md reflections into a concise \"Learned Patterns\" section.\n * Returns the new content for the IDENTITY.md file (everything below the static header).\n */\n async consolidateIdentity(\n fullIdentityContent: string,\n staticHeaderEndMarker: string,\n ): Promise<{ learnedPatterns: string[]; summary: string } | null> {\n const iTraceId = crypto.randomUUID();\n this.emit({ kind: \"llm_start\", traceId: iTraceId, model: this.config.model, operation: \"identity_consolidation\", input: fullIdentityContent.slice(0, 2000) });\n const iStartTime = Date.now();\n\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n try {\n const localResult = await this.consolidateIdentityWithLocalLlm(fullIdentityContent);\n if (localResult) {\n const durationMs = Date.now() - iStartTime;\n this.emit({ kind: \"llm_end\", traceId: iTraceId, model: this.config.localLlmModel, operation: \"identity_consolidation\", durationMs });\n log.debug(`identity consolidation: used local LLM — ${localResult.learnedPatterns.length} patterns`);\n return localResult;\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"identity consolidation: local LLM failed and fallback disabled\");\n return null;\n }\n log.info(\"identity consolidation: local LLM unavailable, falling back to gateway AI\");\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(\"identity consolidation: local LLM error and fallback disabled:\", err);\n return null;\n }\n log.info(\"identity consolidation: local LLM error, falling back to gateway AI:\", err);\n }\n }\n\n const identityFallback = await this.parseWithGatewayFallback(\n iTraceId,\n \"identity_consolidation\",\n iStartTime,\n IdentityConsolidationResultSchema,\n [\n {\n role: \"system\",\n content: `You are an identity consolidation system. You are given the full contents of an IDENTITY.md file that contains many individual reflection entries. Your job is to:\n\n1. Read all the reflection entries (sections starting with \"## Reflection\")\n2. Extract the most important, durable behavioral patterns and lessons learned\n3. Consolidate them into concise, standalone statements (aim for 10-25 key patterns)\n4. Remove redundancy — if multiple reflections say the same thing, merge into one clear statement\n5. Prioritize patterns that are actionable and recurring over one-off observations\n6. Write a brief summary paragraph\n\nThe goal is to reduce a bloated file to a compact, high-signal set of learned patterns while preserving all genuinely useful self-knowledge.`,\n },\n { role: \"user\", content: fullIdentityContent },\n ],\n { temperature: 0.3, maxTokens: 4096 },\n );\n if (identityFallback) {\n log.debug(\n `identity consolidation: ${identityFallback.learnedPatterns.length} patterns (fallback)`,\n );\n return identityFallback;\n }\n\n // Fall back to OpenAI API\n if (!this.client) {\n log.warn(\"identity consolidation skipped — no OpenAI API key and local LLM failed/disabled\");\n return null;\n }\n\n try {\n const instructionText = `You are an identity consolidation system. You are given the full contents of an IDENTITY.md file that contains many individual reflection entries. Your job is to:\n\n1. Read all the reflection entries (sections starting with \"## Reflection\")\n2. Extract the most important, durable behavioral patterns and lessons learned\n3. Consolidate them into concise, standalone statements (aim for 10-25 key patterns)\n4. Remove redundancy — if multiple reflections say the same thing, merge into one clear statement\n5. Prioritize patterns that are actionable and recurring over one-off observations\n6. Write a brief summary paragraph\n\nThe goal is to reduce a bloated file to a compact, high-signal set of learned patterns while preserving all genuinely useful self-knowledge.\n\nRespond with valid JSON matching this schema:\n{\n \"learnedPatterns\": [\"pattern 1\", \"pattern 2\", \"pattern 3\"],\n \"summary\": \"brief summary of consolidation\"\n}`;\n\n const response = await this.client.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: fullIdentityContent },\n ],\n ...(this.config.reasoningEffort !== \"none\" ? { reasoning_effort: this.config.reasoningEffort } : {}),\n ...buildChatCompletionTokenLimit(this.config.model, 4096, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const rawContent = response.choices?.[0]?.message?.content?.trim();\n const iDurationMs = Date.now() - iStartTime;\n const iUsage = (response as any).usage;\n\n let parsed: any = null;\n if (rawContent) {\n for (const candidate of extractJsonCandidates(rawContent)) {\n try {\n parsed = JSON.parse(candidate);\n break;\n } catch {\n // keep trying candidates\n }\n }\n }\n\n this.emit({\n kind: \"llm_end\", traceId: iTraceId, model: this.config.model, operation: \"identity_consolidation\", durationMs: iDurationMs,\n output: parsed ? parsed.summary : undefined,\n tokenUsage: iUsage ? { input: iUsage.prompt_tokens, output: iUsage.completion_tokens, total: iUsage.total_tokens } : undefined,\n });\n\n if (parsed && Array.isArray(parsed.learnedPatterns)) {\n const learnedPatterns = parsed.learnedPatterns\n .filter((pattern: unknown) => typeof pattern === \"string\")\n .map((pattern: string) => pattern.trim())\n .filter((pattern: string) => pattern.length > 0);\n log.debug(\n `identity consolidation: ${learnedPatterns.length} patterns`,\n );\n return {\n learnedPatterns,\n summary: String(parsed.summary || \"\"),\n };\n }\n\n log.warn(\"identity consolidation returned no parsed output\");\n return null;\n } catch (err) {\n this.emit({\n kind: \"llm_error\", traceId: iTraceId, model: this.config.model, operation: \"identity_consolidation\",\n durationMs: Date.now() - iStartTime, error: String(err),\n });\n log.error(\"identity consolidation failed\", err);\n return null;\n }\n }\n\n /**\n * Consolidate identity using local LLM.\n */\n private async consolidateIdentityWithLocalLlm(\n fullIdentityContent: string,\n ): Promise<{ learnedPatterns: string[]; summary: string } | null> {\n // Get dynamic context sizes\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n log.debug(`Identity consolidation model context: ${contextSizes.description}`);\n\n const prompt = `You are an identity consolidation system. You are given the full contents of an IDENTITY.md file that contains many individual reflection entries. Your job is to:\n\n1. Read all the reflection entries (sections starting with \"## Reflection\")\n2. Extract the most important, durable behavioral patterns and lessons learned\n3. Consolidate them into concise, standalone statements (aim for 10-25 key patterns)\n4. Remove redundancy — if multiple reflections say the same thing, merge into one clear statement\n5. Prioritize patterns that are actionable and recurring over one-off observations\n6. Write a brief summary paragraph\n\nThe goal is to reduce a bloated file to a compact, high-signal set of learned patterns while preserving all genuinely useful self-knowledge.\n\nIDENTITY.md content:\n${fullIdentityContent}\n\nRespond with valid JSON matching this schema:\n{\n \"learnedPatterns\": [\"pattern 1\", \"pattern 2\", \"pattern 3\"],\n \"summary\": \"brief summary of consolidation\"\n}`;\n\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"You are an identity consolidation system. Output valid JSON only.\" },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.3,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"identity_consolidation\",\n priority: \"background\",\n },\n );\n\n if (!response?.content) {\n return null;\n }\n\n try {\n const content = response.content.trim();\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n return {\n learnedPatterns: Array.isArray((parsed as any).learnedPatterns)\n ? (parsed as any).learnedPatterns\n : [],\n summary: String((parsed as any).summary || \"\"),\n };\n } catch {\n // keep trying candidates\n }\n }\n return null;\n } catch (err) {\n log.warn(\"local LLM identity consolidation: failed to parse JSON response:\", err);\n return null;\n }\n }\n\n /**\n * Verify if two memories contradict each other using LLM.\n * Called when QMD finds semantically similar memories (Phase 2B).\n */\n async verifyContradiction(\n newMemory: { content: string; category: string },\n existingMemory: { id: string; content: string; category: string; created: string },\n ): Promise<ContradictionVerificationResult | null> {\n const input = `Memory 1 (existing, created ${existingMemory.created}):\nCategory: ${existingMemory.category}\nContent: ${existingMemory.content}\n\nMemory 2 (new):\nCategory: ${newMemory.category}\nContent: ${newMemory.content}`;\n\n try {\n const instructionText = `You are a contradiction detection system. Analyze whether two memories contradict each other.\n\nIMPORTANT: Not all similar memories are contradictions!\n- \"User likes TypeScript\" and \"User likes Python\" are NOT contradictions (preferences can coexist)\n- \"User prefers dark mode\" and \"User prefers light mode\" ARE contradictions (mutually exclusive)\n- \"User's email is a@b.com\" and \"User's email is c@d.com\" ARE contradictions (only one email)\n- \"User works at Acme\" and \"User used to work at Acme\" might be a contradiction (temporal change)\n\nOnly mark as contradiction if the two statements CANNOT both be true at the same time.\n\nIf they ARE contradictory, determine which represents the more recent/current state based on:\n- Explicit time references (\"now\", \"currently\", \"used to\", \"no longer\")\n- The fact that newer corrections often start with \"actually\" or \"correction\"\n- Context clues about change over time\n\nRespond with valid JSON matching this schema:\n{\n \"isContradiction\": true,\n \"confidence\": 0.95,\n \"reasoning\": \"why they contradict or don't\",\n \"whichIsNewer\": \"first\"\n}`;\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n {\n temperature: 0.3,\n maxTokens: 2048,\n operation: \"contradiction_verification\",\n priority: \"background\",\n },\n );\n const normalized = this.normalizeContradictionVerificationResult(\n this.parseJsonObject(localResponse?.content),\n );\n if (normalized) {\n log.debug(\n `contradiction check via local LLM: ${normalized.isContradiction ? \"YES\" : \"NO\"} (confidence: ${normalized.confidence})`,\n );\n return normalized;\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"contradiction verification skipped — local LLM returned invalid JSON and cloud fallback is disabled\");\n return null;\n }\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(`contradiction verification skipped — local LLM failed and cloud fallback is disabled: ${err}`);\n return null;\n }\n }\n }\n\n if (!this.shouldUseDirectClient) {\n const fallbackResponse = await this.fallbackLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n this.withGatewayAgent({ temperature: 0.3, maxTokens: 2048 }),\n );\n const normalized = this.normalizeContradictionVerificationResult(\n this.parseJsonObject(fallbackResponse?.content),\n );\n if (normalized) {\n log.debug(\n `contradiction check via fallback: ${normalized.isContradiction ? \"YES\" : \"NO\"} (confidence: ${normalized.confidence})`,\n );\n return normalized;\n }\n log.warn(\"contradiction verification skipped — no OpenAI API key and fallback unavailable\");\n return null;\n }\n\n const response = await this.client!.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n ...buildChatCompletionTokenLimit(this.config.model, 2048, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const normalized = this.normalizeContradictionVerificationResult(\n this.parseJsonObject(response.choices?.[0]?.message?.content),\n );\n if (normalized) {\n log.debug(\n `contradiction check: ${normalized.isContradiction ? \"YES\" : \"NO\"} (confidence: ${normalized.confidence})`,\n );\n return normalized;\n }\n\n return null;\n } catch (err) {\n log.error(\"contradiction verification failed\", err);\n return null;\n }\n }\n async revalidateDependents(\n superseded: { id: string; content: string },\n replacement: { id: string; content: string } | null,\n dependents: Array<{ id: string; category: string; content: string }>,\n signal?: AbortSignal,\n ): Promise<{\n verdicts: Array<{\n memoryId: string;\n verdict: \"still_valid\" | \"invalidated\" | \"uncertain\";\n reason?: string;\n }>;\n }> {\n const complete: RevalidationFastChatCompletion = async (messages, options) => {\n try {\n const fast = await this.fastChatCompletion?.(messages, options);\n if (fast) return fast;\n } catch (error) {\n if (isAbortError(error) || options.signal?.aborted) throw error;\n log.warn(`dependency revalidation fast route failed: ${error}`);\n }\n if (this.shouldUseLocalLlm) {\n try {\n const local = await this.localLlm.chatCompletion(messages, options);\n if (local || !this.config.localLlmFallback) return local;\n } catch (error) {\n if (!this.config.localLlmFallback) throw error;\n }\n }\n if (!this.shouldUseDirectClient) {\n return this.fallbackLlm.chatCompletion(messages, this.withGatewayAgent(options));\n }\n const client = this.client;\n if (!client) return null;\n if (!shouldAssumeOpenAiChatCompletions(client.baseURL ?? this.config.openaiBaseUrl)) {\n const response = await client.chat.completions.create(\n {\n model: this.config.model,\n messages,\n max_tokens: options.maxTokens,\n },\n { signal: options.signal },\n );\n const content = response.choices[0]?.message?.content;\n return typeof content === \"string\" ? { content } : null;\n }\n const response = await client.responses.create({\n model: this.config.model,\n instructions: messages.find((message) => message.role === \"system\")?.content,\n input: messages.filter((message) => message.role !== \"system\").map((message) => message.content).join(\"\\n\\n\"),\n max_output_tokens: options.maxTokens,\n }, { signal: options.signal });\n return typeof response.output_text === \"string\" ? { content: response.output_text } : null;\n };\n return revalidateDependentsViaLlm(\n { fastChatCompletion: complete, parseJsonObject: this.parseJsonObject },\n superseded,\n replacement,\n dependents,\n { signal, timeoutMs: this.config.dependencyPropagation.timeoutMs },\n );\n }\n async suggestLinks(\n newMemory: { content: string; category: string },\n candidateMemories: Array<{ id: string; content: string; category: string }>,\n ): Promise<SuggestedLinks | null> {\n if (candidateMemories.length === 0) {\n return { links: [] };\n }\n\n const candidateList = candidateMemories\n .map((m, i) => `[${i + 1}] ID: ${m.id}\\nCategory: ${m.category}\\nContent: ${m.content}`)\n .join(\"\\n\\n\");\n\n const input = `New memory:\nCategory: ${newMemory.category}\nContent: ${newMemory.content}\n\nCandidate memories to link to:\n${candidateList}`;\n\n try {\n const instructionText = `You are a memory linking system. Analyze the new memory and suggest relationships to existing memories.\n\nLink types:\n- follows: This memory is a continuation or next step (e.g., decision follows discussion)\n- references: This memory mentions or refers to the other (e.g., fact references entity)\n- contradicts: This memory conflicts with the other (use sparingly, only for true contradictions)\n- supports: This memory provides evidence or reinforcement (e.g., example supports principle)\n- related: General topical relationship\n\nRules:\n- Only suggest links with strength > 0.5\n- Quality over quantity — 0-3 links is typical\n- Prefer specific link types over generic \"related\"\n- Consider entity references, topics, and causal relationships\n\nRespond with valid JSON matching this schema:\n{\n \"links\": [{\"targetId\": \"memory-id\", \"linkType\": \"follows|references|contradicts|supports|related\", \"strength\": 0.8, \"reason\": \"why\"}]\n}`;\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n {\n temperature: 0.3,\n maxTokens: 2048,\n operation: \"link_suggestion\",\n priority: \"background\",\n },\n );\n const normalized = this.normalizeSuggestedLinksResult(this.parseJsonObject(localResponse?.content));\n if (normalized) {\n log.debug(`suggested ${normalized.links.length} links via local LLM`);\n return normalized;\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"link suggestion skipped — local LLM returned invalid JSON and cloud fallback is disabled\");\n return null;\n }\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(`link suggestion skipped — local LLM failed and cloud fallback is disabled: ${err}`);\n return null;\n }\n }\n }\n\n if (!this.shouldUseDirectClient) {\n const fallbackResponse = await this.fallbackLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n this.withGatewayAgent({ temperature: 0.3, maxTokens: 2048 }),\n );\n const normalized = this.normalizeSuggestedLinksResult(this.parseJsonObject(fallbackResponse?.content));\n if (normalized) {\n log.debug(`suggested ${normalized.links.length} links via fallback`);\n return normalized;\n }\n log.warn(\"link suggestion skipped — no OpenAI API key and fallback unavailable\");\n return null;\n }\n\n const response = await this.client!.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n ...buildChatCompletionTokenLimit(this.config.model, 2048, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const normalized = this.normalizeSuggestedLinksResult(\n this.parseJsonObject(response.choices?.[0]?.message?.content),\n );\n if (normalized) {\n log.debug(`suggested ${normalized.links.length} links`);\n return normalized;\n }\n\n return null;\n } catch (err) {\n log.error(\"link suggestion failed\", err);\n return null;\n }\n }\n\n async generateDaySummary(memories: string | MemoryFile[]): Promise<DaySummaryResultShape | null> {\n if (!resolveRecallAuxiliaryCapabilities(this.config).daySummary) {\n log.warn(\"day summary skipped — disabled by config\");\n return null;\n }\n\n const memoryContext = formatDaySummaryMemories(memories);\n if (memoryContext.length === 0) return null;\n\n const instructionText = await loadDaySummaryPrompt();\n\n // Append extension footer when extensions are active (#382)\n let extensionsFooter = \"\";\n try {\n extensionsFooter = await buildExtensionsFooterForSummary(this.config);\n } catch {\n // Non-fatal: skip extension footer if discovery fails\n }\n\n const userPrompt = `Generate an end-of-day summary from this Remnic memory context:\n\n${memoryContext}${extensionsFooter.length > 0 ? `\\n\\n${extensionsFooter}` : \"\"}`;\n const traceId = crypto.randomUUID();\n const startedAt = Date.now();\n this.emit({ kind: \"llm_start\", traceId, model: this.config.model, operation: \"day_summary\", input: memoryContext.slice(0, 4000) });\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: `${instructionText}\n\nReturn valid JSON only.` },\n { role: \"user\", content: userPrompt },\n ],\n {\n temperature: 0.2,\n maxTokens: 2048,\n operation: \"day_summary\",\n priority: \"background\",\n },\n );\n const normalized = this.normalizeDaySummaryResult(this.parseJsonObject(localResponse?.content));\n if (normalized) {\n this.emit({ kind: \"llm_end\", traceId, model: this.config.localLlmModel, operation: \"day_summary\", durationMs: Date.now() - startedAt, output: JSON.stringify(normalized).slice(0, 2000) });\n log.debug(`generated day summary via local LLM (${normalized.bullets.length} bullets)`);\n return normalized;\n }\n if (!this.config.localLlmFallback) {\n this.emit({ kind: \"llm_error\", traceId, model: this.config.localLlmModel, operation: \"day_summary\", durationMs: Date.now() - startedAt, error: \"local LLM returned invalid JSON and fallback disabled\" });\n log.warn(\"day summary skipped — local LLM returned invalid JSON and fallback disabled\");\n return null;\n }\n } catch (err) {\n if (!this.config.localLlmFallback) {\n this.emit({ kind: \"llm_error\", traceId, model: this.config.localLlmModel, operation: \"day_summary\", durationMs: Date.now() - startedAt, error: String(err) });\n log.warn(`day summary skipped — local LLM failed and fallback disabled: ${err}`);\n return null;\n }\n }\n }\n\n const fallbackResult = await this.parseWithGatewayFallback(\n traceId,\n \"day_summary\",\n startedAt,\n DaySummaryResultSchema,\n [\n { role: \"system\", content: `${instructionText}\n\nReturn valid JSON only.` },\n { role: \"user\", content: userPrompt },\n ],\n { temperature: 0.2, maxTokens: 2048 },\n );\n if (fallbackResult) {\n const normalized = this.normalizeDaySummaryResult(fallbackResult);\n if (normalized) {\n log.debug(`generated day summary via fallback (${normalized.bullets.length} bullets)`);\n return normalized;\n }\n }\n\n // Direct Responses API fallback (AGENTS.md-compliant: never Chat Completions)\n if (this.shouldUseDirectClient) {\n try {\n const response = await (this.client as any).responses.create({\n model: this.config.model,\n instructions: `${instructionText}\\n\\nReturn valid JSON only.`,\n input: userPrompt,\n max_output_tokens: 2048,\n });\n const rawText = typeof response.output_text === \"string\" ? response.output_text : JSON.stringify(response.output_text ?? \"\");\n const normalized = this.normalizeDaySummaryResult(this.parseJsonObject(rawText));\n if (normalized) {\n this.emit({ kind: \"llm_end\", traceId, model: this.config.model, operation: \"day_summary\", durationMs: Date.now() - startedAt, output: JSON.stringify(normalized).slice(0, 2000) });\n log.debug(`generated day summary via Responses API (${normalized.bullets.length} bullets)`);\n return normalized;\n }\n this.emit({ kind: \"llm_error\", traceId, model: this.config.model, operation: \"day_summary\", durationMs: Date.now() - startedAt, error: \"Responses API returned unparseable output\" });\n } catch (err) {\n this.emit({ kind: \"llm_error\", traceId, model: this.config.model, operation: \"day_summary\", durationMs: Date.now() - startedAt, error: `Responses API failed: ${err}` });\n }\n }\n\n this.emit({ kind: \"llm_error\", traceId, model: this.config.model, operation: \"day_summary\", durationMs: Date.now() - startedAt, error: \"all generation paths exhausted (local LLM + gateway + Responses API)\" });\n log.warn(\"day summary skipped — all generation paths exhausted\");\n return null;\n }\n\n\n /**\n * Summarize a batch of old memories into a compact summary (Phase 4A).\n */\n async summarizeMemories(\n memories: Array<{ id: string; content: string; category: string; created: string }>,\n ): Promise<MemorySummaryResult | null> {\n if (memories.length === 0) return null;\n\n const memoryList = memories\n .map((m) => `[${m.id}] (${m.category}, ${m.created.slice(0, 10)})\\n${m.content}`)\n .join(\"\\n\\n\");\n\n try {\n const instructionText = `You are a memory summarization system. You are given a batch of old memories that need to be compressed into a summary.\n\nYour task:\n1. Write a concise summary paragraph (2-4 sentences) capturing the essence of these memories\n2. Extract the 5-10 most important facts that should be preserved\n3. List the key entities mentioned\n\nGuidelines:\n- Preserve specific, actionable information\n- Merge redundant details into single statements\n- Focus on durable insights, not transient details\n- Maintain any preferences, decisions, or corrections as key facts\n\nRespond with valid JSON matching this schema:\n{\n \"summaryText\": \"concise summary paragraph\",\n \"keyFacts\": [\"fact 1\", \"fact 2\"],\n \"keyEntities\": [\"entity-1\", \"entity-2\"]\n}`;\n\n if (this.shouldUseLocalLlm) {\n try {\n const localResponse = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: `Summarize these ${memories.length} memories:\\n\\n${memoryList}` },\n ],\n {\n temperature: 0.3,\n maxTokens: 4096,\n operation: \"memory_summarization\",\n priority: \"background\",\n },\n );\n const normalized = this.normalizeMemorySummaryResult(this.parseJsonObject(localResponse?.content));\n if (normalized) {\n log.debug(\n `summarized ${memories.length} memories into ${normalized.keyFacts.length} key facts via local LLM`,\n );\n return normalized;\n }\n if (!this.config.localLlmFallback) {\n log.warn(\"summarization skipped — local LLM returned invalid JSON and cloud fallback is disabled\");\n return null;\n }\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(`summarization skipped — local LLM failed and cloud fallback is disabled: ${err}`);\n return null;\n }\n }\n }\n\n if (!this.shouldUseDirectClient) {\n const fallbackResponse = await this.fallbackLlm.chatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: `Summarize these ${memories.length} memories:\\n\\n${memoryList}` },\n ],\n this.withGatewayAgent({ temperature: 0.3, maxTokens: 4096 }),\n );\n const normalized = this.normalizeMemorySummaryResult(this.parseJsonObject(fallbackResponse?.content));\n if (normalized) {\n log.debug(`summarized ${memories.length} memories into ${normalized.keyFacts.length} key facts via fallback`);\n return normalized;\n }\n log.warn(\"summarization skipped — no OpenAI API key and fallback unavailable\");\n return null;\n }\n\n const response = await this.client!.chat.completions.create({\n model: this.config.model,\n messages: [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: `Summarize these ${memories.length} memories:\\n\\n${memoryList}` },\n ],\n ...buildChatCompletionTokenLimit(this.config.model, 4096, {\n assumeOpenAI: this.directClientUsesOpenAiTokenSemantics(),\n }),\n });\n\n const normalized = this.normalizeMemorySummaryResult(\n this.parseJsonObject(response.choices?.[0]?.message?.content),\n );\n if (normalized) {\n log.debug(`summarized ${memories.length} memories into ${normalized.keyFacts.length} key facts`);\n return normalized;\n }\n\n return null;\n } catch (err) {\n log.error(\"memory summarization failed\", err);\n return null;\n }\n }\n}\n","/**\n * LLM revalidation of dependent memories after a support link breaks.\n *\n * Extracted from ExtractionEngine to keep extraction.ts under its ratchet\n * ceiling. The ExtractionEngine.revalidateDependents method delegates here.\n */\n\nexport interface RevalidationVerdict {\n memoryId: string;\n verdict: \"still_valid\" | \"invalidated\" | \"uncertain\";\n reason?: string;\n}\n\nexport type RevalidationFastChatCompletion = (\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: {\n temperature?: number;\n maxTokens?: number;\n timeoutMs?: number;\n operation?: string;\n priority?: \"background\" | \"recall-critical\";\n signal?: AbortSignal;\n },\n) => Promise<{ content: string } | null>;\n\nexport interface RevalidationDeps {\n fastChatCompletion: RevalidationFastChatCompletion;\n parseJsonObject: (raw: string | null) => unknown;\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction buildPrompt(\n superseded: { id: string; content: string },\n replacement: { id: string; content: string } | null,\n dependents: Array<{ id: string; category: string; content: string }>,\n): { input: string; instructionText: string } {\n const dependentPrompt = dependents\n .map(\n (memory, index) =>\n `[${index + 1}] id: ${memory.id} | category: ${memory.category}\\n${memory.content}`,\n )\n .join(\"\\n\\n\");\n const input = `SUPERSEDED MEMORY (id: ${superseded.id}):\n${superseded.content}\n\nREPLACEMENT (id: ${replacement?.id ?? \"none\"}):\n${replacement?.content ?? \"none — the memory was removed without replacement\"}\n\nDEPENDENTS TO REVALIDATE (return exactly one verdict per id):\n${dependentPrompt}`;\n const instructionText = `You revalidate dependent memory claims after a supporting memory changes.\nFor each requested memory, decide whether its claim still holds.\nReturn valid JSON only:\n{\"verdicts\":[{\"memoryId\":\"id\",\"verdict\":\"still_valid|invalidated|uncertain\",\"reason\":\"brief reason\"}]}\nNever invent memory IDs. Use \"uncertain\" when the evidence is insufficient.`;\n return { input, instructionText };\n}\n\nfunction normalizeVerdicts(\n parsed: unknown,\n dependents: Array<{ id: string }>,\n): RevalidationVerdict[] {\n const raw: unknown[] = isPlainRecord(parsed) && Array.isArray(parsed.verdicts) ? parsed.verdicts : [];\n const requested = new Set(dependents.map((memory) => memory.id));\n const seen = new Set<string>();\n const normalized: RevalidationVerdict[] = [];\n for (const candidate of raw) {\n if (!isPlainRecord(candidate)) continue;\n const memoryId = typeof candidate.memoryId === \"string\" ? candidate.memoryId.trim() : \"\";\n if (!requested.has(memoryId) || seen.has(memoryId)) continue;\n seen.add(memoryId);\n const verdict =\n candidate.verdict === \"still_valid\" ||\n candidate.verdict === \"invalidated\" ||\n candidate.verdict === \"uncertain\"\n ? candidate.verdict\n : \"uncertain\";\n normalized.push({\n memoryId,\n verdict,\n ...(typeof candidate.reason === \"string\" ? { reason: candidate.reason } : {}),\n });\n }\n return dependents.map((memory) => {\n const verdict = normalized.find((candidate) => candidate.memoryId === memory.id);\n return verdict ?? { memoryId: memory.id, verdict: \"uncertain\" as const };\n });\n}\n\nexport async function revalidateDependentsViaLlm(\n deps: RevalidationDeps,\n superseded: { id: string; content: string },\n replacement: { id: string; content: string } | null,\n dependents: Array<{ id: string; category: string; content: string }>,\n options: { signal?: AbortSignal; timeoutMs?: number } = {},\n): Promise<{ verdicts: RevalidationVerdict[] }> {\n const { input, instructionText } = buildPrompt(superseded, replacement, dependents);\n const maxTokens = Math.max(1024, dependents.length * 256);\n const response = await deps.fastChatCompletion(\n [\n { role: \"system\", content: instructionText },\n { role: \"user\", content: input },\n ],\n {\n temperature: 0.2,\n maxTokens,\n operation: \"dependency_revalidation\",\n priority: \"background\",\n timeoutMs: options.timeoutMs,\n signal: options.signal,\n },\n );\n const rawContent = response?.content ?? null;\n if (!rawContent?.trim()) {\n throw new Error(\"fast completion returned no dependency revalidation output\");\n }\n\n return { verdicts: normalizeVerdicts(deps.parseJsonObject(rawContent), dependents) };\n}\n"],"mappings":"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","names":["isPlainRecord","normalized","response"]}