@atomicmemory/core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (589) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +201 -0
  3. package/README.md +314 -0
  4. package/dist/app/bind-ephemeral.d.ts +18 -0
  5. package/dist/app/bind-ephemeral.js +22 -0
  6. package/dist/app/cors-headers.d.ts +12 -0
  7. package/dist/app/cors-headers.js +18 -0
  8. package/dist/app/create-app.d.ts +25 -0
  9. package/dist/app/create-app.js +156 -0
  10. package/dist/app/runtime-config-route-snapshot.d.ts +27 -0
  11. package/dist/app/runtime-config-route-snapshot.js +27 -0
  12. package/dist/app/runtime-container.d.ts +281 -0
  13. package/dist/app/runtime-container.js +297 -0
  14. package/dist/app/startup-checks.d.ts +28 -0
  15. package/dist/app/startup-checks.js +45 -0
  16. package/dist/bin.d.ts +17 -0
  17. package/dist/bin.js +128 -0
  18. package/dist/config.d.ts +680 -0
  19. package/dist/config.js +808 -0
  20. package/dist/db/agent-trust-repository.d.ts +49 -0
  21. package/dist/db/agent-trust-repository.js +66 -0
  22. package/dist/db/belief-edges-repository.d.ts +68 -0
  23. package/dist/db/belief-edges-repository.js +124 -0
  24. package/dist/db/claim-repository.d.ts +6 -0
  25. package/dist/db/claim-repository.js +4 -0
  26. package/dist/db/contradictions-repository.d.ts +56 -0
  27. package/dist/db/contradictions-repository.js +88 -0
  28. package/dist/db/document-chunk-repository.d.ts +48 -0
  29. package/dist/db/document-chunk-repository.js +145 -0
  30. package/dist/db/document-chunk-types.d.ts +35 -0
  31. package/dist/db/document-chunk-types.js +9 -0
  32. package/dist/db/document-list-cursor.d.ts +45 -0
  33. package/dist/db/document-list-cursor.js +111 -0
  34. package/dist/db/document-list-repository.d.ts +103 -0
  35. package/dist/db/document-list-repository.js +204 -0
  36. package/dist/db/entity-cards-repository.d.ts +37 -0
  37. package/dist/db/entity-cards-repository.js +46 -0
  38. package/dist/db/entity-values-repository.d.ts +26 -0
  39. package/dist/db/entity-values-repository.js +57 -0
  40. package/dist/db/link-repository.d.ts +30 -0
  41. package/dist/db/link-repository.js +54 -0
  42. package/dist/db/memory-repository.d.ts +163 -0
  43. package/dist/db/memory-repository.js +232 -0
  44. package/dist/db/migrate.d.ts +6 -0
  45. package/dist/db/migrate.js +36 -0
  46. package/dist/db/mmr.d.ts +14 -0
  47. package/dist/db/mmr.js +57 -0
  48. package/dist/db/passport-feed-repository.d.ts +91 -0
  49. package/dist/db/passport-feed-repository.js +198 -0
  50. package/dist/db/pg-episode-store.d.ts +19 -0
  51. package/dist/db/pg-episode-store.js +17 -0
  52. package/dist/db/pg-link-store.d.ts +17 -0
  53. package/dist/db/pg-link-store.js +14 -0
  54. package/dist/db/pg-memory-store.d.ts +68 -0
  55. package/dist/db/pg-memory-store.js +53 -0
  56. package/dist/db/pg-recap-store.d.ts +13 -0
  57. package/dist/db/pg-recap-store.js +19 -0
  58. package/dist/db/pg-representation-store.d.ts +17 -0
  59. package/dist/db/pg-representation-store.js +17 -0
  60. package/dist/db/pg-search-store.d.ts +29 -0
  61. package/dist/db/pg-search-store.js +47 -0
  62. package/dist/db/pool.d.ts +5 -0
  63. package/dist/db/pool.js +21 -0
  64. package/dist/db/ppr.d.ts +56 -0
  65. package/dist/db/ppr.js +178 -0
  66. package/dist/db/query-helpers.d.ts +44 -0
  67. package/dist/db/query-helpers.js +60 -0
  68. package/dist/db/raw-doc-artifact-sync.d.ts +128 -0
  69. package/dist/db/raw-doc-artifact-sync.js +259 -0
  70. package/dist/db/raw-document-blob-repository.d.ts +148 -0
  71. package/dist/db/raw-document-blob-repository.js +300 -0
  72. package/dist/db/raw-document-repository.d.ts +104 -0
  73. package/dist/db/raw-document-repository.js +410 -0
  74. package/dist/db/raw-document-status-repository.d.ts +122 -0
  75. package/dist/db/raw-document-status-repository.js +183 -0
  76. package/dist/db/raw-document-types.d.ts +236 -0
  77. package/dist/db/raw-document-types.js +10 -0
  78. package/dist/db/raw-storage-reconciliation-repository.d.ts +110 -0
  79. package/dist/db/raw-storage-reconciliation-repository.js +200 -0
  80. package/dist/db/reflection-jobs-repository.d.ts +33 -0
  81. package/dist/db/reflection-jobs-repository.js +48 -0
  82. package/dist/db/reflections-repository.d.ts +41 -0
  83. package/dist/db/reflections-repository.js +83 -0
  84. package/dist/db/repository-claims.d.ts +141 -0
  85. package/dist/db/repository-claims.js +376 -0
  86. package/dist/db/repository-deferred-audn.d.ts +33 -0
  87. package/dist/db/repository-deferred-audn.js +69 -0
  88. package/dist/db/repository-document-delete.d.ts +53 -0
  89. package/dist/db/repository-document-delete.js +156 -0
  90. package/dist/db/repository-entities.d.ts +114 -0
  91. package/dist/db/repository-entities.js +317 -0
  92. package/dist/db/repository-entity-attributes.d.ts +41 -0
  93. package/dist/db/repository-entity-attributes.js +65 -0
  94. package/dist/db/repository-entity-graph.d.ts +32 -0
  95. package/dist/db/repository-entity-graph.js +87 -0
  96. package/dist/db/repository-first-mentions.d.ts +41 -0
  97. package/dist/db/repository-first-mentions.js +79 -0
  98. package/dist/db/repository-lessons.d.ts +51 -0
  99. package/dist/db/repository-lessons.js +90 -0
  100. package/dist/db/repository-links.d.ts +26 -0
  101. package/dist/db/repository-links.js +105 -0
  102. package/dist/db/repository-observation.d.ts +26 -0
  103. package/dist/db/repository-observation.js +51 -0
  104. package/dist/db/repository-read.d.ts +56 -0
  105. package/dist/db/repository-read.js +271 -0
  106. package/dist/db/repository-recaps.d.ts +59 -0
  107. package/dist/db/repository-recaps.js +158 -0
  108. package/dist/db/repository-representations.d.ts +48 -0
  109. package/dist/db/repository-representations.js +162 -0
  110. package/dist/db/repository-temporal-state.d.ts +35 -0
  111. package/dist/db/repository-temporal-state.js +46 -0
  112. package/dist/db/repository-tll.d.ts +88 -0
  113. package/dist/db/repository-tll.js +179 -0
  114. package/dist/db/repository-types.d.ts +313 -0
  115. package/dist/db/repository-types.js +142 -0
  116. package/dist/db/repository-user-profiles.d.ts +17 -0
  117. package/dist/db/repository-user-profiles.js +28 -0
  118. package/dist/db/repository-vector-search.d.ts +33 -0
  119. package/dist/db/repository-vector-search.js +373 -0
  120. package/dist/db/repository-wipe.d.ts +34 -0
  121. package/dist/db/repository-wipe.js +94 -0
  122. package/dist/db/repository-write.d.ts +61 -0
  123. package/dist/db/repository-write.js +279 -0
  124. package/dist/db/schema.sql +1355 -0
  125. package/dist/db/storage-artifact-delete-tx.d.ts +56 -0
  126. package/dist/db/storage-artifact-delete-tx.js +123 -0
  127. package/dist/db/storage-artifact-providers.d.ts +21 -0
  128. package/dist/db/storage-artifact-providers.js +21 -0
  129. package/dist/db/storage-artifact-recovery-repository.d.ts +66 -0
  130. package/dist/db/storage-artifact-recovery-repository.js +58 -0
  131. package/dist/db/storage-artifact-repository.d.ts +329 -0
  132. package/dist/db/storage-artifact-repository.js +497 -0
  133. package/dist/db/stores.d.ts +220 -0
  134. package/dist/db/stores.js +12 -0
  135. package/dist/db/summaries-repository.d.ts +74 -0
  136. package/dist/db/summaries-repository.js +125 -0
  137. package/dist/eval/beam-10m-loader.d.ts +98 -0
  138. package/dist/eval/beam-10m-loader.js +128 -0
  139. package/dist/index.d.ts +18 -0
  140. package/dist/index.js +17 -0
  141. package/dist/middleware/require-bearer.d.ts +27 -0
  142. package/dist/middleware/require-bearer.js +60 -0
  143. package/dist/middleware/validate-response.d.ts +33 -0
  144. package/dist/middleware/validate-response.js +55 -0
  145. package/dist/middleware/validate.d.ts +43 -0
  146. package/dist/middleware/validate.js +85 -0
  147. package/dist/routes/agents.d.ts +13 -0
  148. package/dist/routes/agents.js +89 -0
  149. package/dist/routes/document-response-formatters.d.ts +98 -0
  150. package/dist/routes/document-response-formatters.js +243 -0
  151. package/dist/routes/documents.d.ts +74 -0
  152. package/dist/routes/documents.js +425 -0
  153. package/dist/routes/memories.d.ts +29 -0
  154. package/dist/routes/memories.js +725 -0
  155. package/dist/routes/memory-response-formatters.d.ts +179 -0
  156. package/dist/routes/memory-response-formatters.js +210 -0
  157. package/dist/routes/public-raw-storage-metadata.d.ts +54 -0
  158. package/dist/routes/public-raw-storage-metadata.js +56 -0
  159. package/dist/routes/reflect.d.ts +14 -0
  160. package/dist/routes/reflect.js +19 -0
  161. package/dist/routes/response-schema-map.d.ts +14 -0
  162. package/dist/routes/response-schema-map.js +69 -0
  163. package/dist/routes/route-errors.d.ts +12 -0
  164. package/dist/routes/route-errors.js +30 -0
  165. package/dist/routes/storage-error-handlers.d.ts +34 -0
  166. package/dist/routes/storage-error-handlers.js +185 -0
  167. package/dist/routes/storage-response-formatters.d.ts +44 -0
  168. package/dist/routes/storage-response-formatters.js +155 -0
  169. package/dist/routes/storage.d.ts +38 -0
  170. package/dist/routes/storage.js +369 -0
  171. package/dist/routes/upstream-provider-errors.d.ts +19 -0
  172. package/dist/routes/upstream-provider-errors.js +95 -0
  173. package/dist/schemas/agents.d.ts +79 -0
  174. package/dist/schemas/agents.js +126 -0
  175. package/dist/schemas/common.d.ts +110 -0
  176. package/dist/schemas/common.js +190 -0
  177. package/dist/schemas/document-list-responses.d.ts +102 -0
  178. package/dist/schemas/document-list-responses.js +87 -0
  179. package/dist/schemas/document-list-schemas.d.ts +123 -0
  180. package/dist/schemas/document-list-schemas.js +174 -0
  181. package/dist/schemas/document-response-schemas.d.ts +610 -0
  182. package/dist/schemas/document-response-schemas.js +264 -0
  183. package/dist/schemas/document-status-envelope.d.ts +48 -0
  184. package/dist/schemas/document-status-envelope.js +54 -0
  185. package/dist/schemas/documents.d.ts +292 -0
  186. package/dist/schemas/documents.js +449 -0
  187. package/dist/schemas/errors.d.ts +75 -0
  188. package/dist/schemas/errors.js +105 -0
  189. package/dist/schemas/memories.d.ts +378 -0
  190. package/dist/schemas/memories.js +542 -0
  191. package/dist/schemas/openapi.d.ts +24 -0
  192. package/dist/schemas/openapi.js +1038 -0
  193. package/dist/schemas/response-scalars.d.ts +10 -0
  194. package/dist/schemas/response-scalars.js +10 -0
  195. package/dist/schemas/responses.d.ts +536 -0
  196. package/dist/schemas/responses.js +350 -0
  197. package/dist/schemas/search-response-parts.d.ts +97 -0
  198. package/dist/schemas/search-response-parts.js +103 -0
  199. package/dist/schemas/storage-schemas.d.ts +175 -0
  200. package/dist/schemas/storage-schemas.js +277 -0
  201. package/dist/schemas/zod-setup.d.ts +15 -0
  202. package/dist/schemas/zod-setup.js +17 -0
  203. package/dist/server.d.ts +13 -0
  204. package/dist/server.js +57 -0
  205. package/dist/services/abstract-query-policy.d.ts +13 -0
  206. package/dist/services/abstract-query-policy.js +50 -0
  207. package/dist/services/affinity-clustering.d.ts +66 -0
  208. package/dist/services/affinity-clustering.js +125 -0
  209. package/dist/services/agentic-retrieval.d.ts +38 -0
  210. package/dist/services/agentic-retrieval.js +126 -0
  211. package/dist/services/answer-format.d.ts +56 -0
  212. package/dist/services/answer-format.js +118 -0
  213. package/dist/services/answer-rescue.d.ts +72 -0
  214. package/dist/services/answer-rescue.js +177 -0
  215. package/dist/services/answer-verifier.d.ts +24 -0
  216. package/dist/services/answer-verifier.js +73 -0
  217. package/dist/services/api-retry.d.ts +6 -0
  218. package/dist/services/api-retry.js +41 -0
  219. package/dist/services/assistant-turn-filter.d.ts +20 -0
  220. package/dist/services/assistant-turn-filter.js +69 -0
  221. package/dist/services/atomicmem-uri.d.ts +33 -0
  222. package/dist/services/atomicmem-uri.js +86 -0
  223. package/dist/services/audit-events.d.ts +54 -0
  224. package/dist/services/audit-events.js +56 -0
  225. package/dist/services/chunked-extraction.d.ts +21 -0
  226. package/dist/services/chunked-extraction.js +108 -0
  227. package/dist/services/claim-slotting.d.ts +27 -0
  228. package/dist/services/claim-slotting.js +38 -0
  229. package/dist/services/claude-code-llm.d.ts +19 -0
  230. package/dist/services/claude-code-llm.js +96 -0
  231. package/dist/services/composite-dedup.d.ts +50 -0
  232. package/dist/services/composite-dedup.js +153 -0
  233. package/dist/services/composite-grouping.d.ts +41 -0
  234. package/dist/services/composite-grouping.js +111 -0
  235. package/dist/services/composite-staleness.d.ts +20 -0
  236. package/dist/services/composite-staleness.js +50 -0
  237. package/dist/services/conciseness-preference.d.ts +14 -0
  238. package/dist/services/conciseness-preference.js +42 -0
  239. package/dist/services/conflict-policy.d.ts +20 -0
  240. package/dist/services/conflict-policy.js +335 -0
  241. package/dist/services/consensus-extraction.d.ts +39 -0
  242. package/dist/services/consensus-extraction.js +147 -0
  243. package/dist/services/consensus-validation.d.ts +52 -0
  244. package/dist/services/consensus-validation.js +206 -0
  245. package/dist/services/consolidation-service.d.ts +60 -0
  246. package/dist/services/consolidation-service.js +171 -0
  247. package/dist/services/content-detection.d.ts +18 -0
  248. package/dist/services/content-detection.js +25 -0
  249. package/dist/services/contradiction-surfacing.d.ts +62 -0
  250. package/dist/services/contradiction-surfacing.js +111 -0
  251. package/dist/services/cost-telemetry.d.ts +39 -0
  252. package/dist/services/cost-telemetry.js +58 -0
  253. package/dist/services/counter-evidence.d.ts +34 -0
  254. package/dist/services/counter-evidence.js +92 -0
  255. package/dist/services/current-state-ranking.d.ts +21 -0
  256. package/dist/services/current-state-ranking.js +152 -0
  257. package/dist/services/deferred-audn.d.ts +47 -0
  258. package/dist/services/deferred-audn.js +162 -0
  259. package/dist/services/document-chunker.d.ts +50 -0
  260. package/dist/services/document-chunker.js +153 -0
  261. package/dist/services/document-failure-markers.d.ts +91 -0
  262. package/dist/services/document-failure-markers.js +305 -0
  263. package/dist/services/document-indexer.d.ts +122 -0
  264. package/dist/services/document-indexer.js +405 -0
  265. package/dist/services/document-service.d.ts +245 -0
  266. package/dist/services/document-service.js +325 -0
  267. package/dist/services/document-upload-artifact-sync.d.ts +80 -0
  268. package/dist/services/document-upload-artifact-sync.js +162 -0
  269. package/dist/services/document-upload-beta2-recovery.d.ts +72 -0
  270. package/dist/services/document-upload-beta2-recovery.js +94 -0
  271. package/dist/services/document-upload.d.ts +44 -0
  272. package/dist/services/document-upload.js +353 -0
  273. package/dist/services/embedding.d.ts +57 -0
  274. package/dist/services/embedding.js +416 -0
  275. package/dist/services/entity-attribute-extractor.d.ts +34 -0
  276. package/dist/services/entity-attribute-extractor.js +117 -0
  277. package/dist/services/entity-card-synthesis.d.ts +54 -0
  278. package/dist/services/entity-card-synthesis.js +92 -0
  279. package/dist/services/entity-dedup.d.ts +9 -0
  280. package/dist/services/entity-dedup.js +14 -0
  281. package/dist/services/entity-graph.d.ts +17 -0
  282. package/dist/services/entity-graph.js +135 -0
  283. package/dist/services/entropy-gate.d.ts +52 -0
  284. package/dist/services/entropy-gate.js +56 -0
  285. package/dist/services/episode-fetcher.d.ts +47 -0
  286. package/dist/services/episode-fetcher.js +128 -0
  287. package/dist/services/event-anchor-facts.d.ts +8 -0
  288. package/dist/services/event-anchor-facts.js +205 -0
  289. package/dist/services/event-chain-detector.d.ts +52 -0
  290. package/dist/services/event-chain-detector.js +83 -0
  291. package/dist/services/extraction-cache.d.ts +9 -0
  292. package/dist/services/extraction-cache.js +54 -0
  293. package/dist/services/extraction-enrichment.d.ts +9 -0
  294. package/dist/services/extraction-enrichment.js +223 -0
  295. package/dist/services/extraction.d.ts +69 -0
  296. package/dist/services/extraction.js +596 -0
  297. package/dist/services/fact-normalization.d.ts +12 -0
  298. package/dist/services/fact-normalization.js +248 -0
  299. package/dist/services/filecoin-observability.d.ts +127 -0
  300. package/dist/services/filecoin-observability.js +200 -0
  301. package/dist/services/first-mention-service.d.ts +76 -0
  302. package/dist/services/first-mention-service.js +186 -0
  303. package/dist/services/hierarchical-retrieval.d.ts +49 -0
  304. package/dist/services/hierarchical-retrieval.js +50 -0
  305. package/dist/services/ingest-fact-pipeline.d.ts +32 -0
  306. package/dist/services/ingest-fact-pipeline.js +212 -0
  307. package/dist/services/ingest-post-write.d.ts +50 -0
  308. package/dist/services/ingest-post-write.js +117 -0
  309. package/dist/services/ingest-trace.d.ts +32 -0
  310. package/dist/services/ingest-trace.js +60 -0
  311. package/dist/services/input-sanitizer.d.ts +41 -0
  312. package/dist/services/input-sanitizer.js +135 -0
  313. package/dist/services/iterative-retrieval.d.ts +26 -0
  314. package/dist/services/iterative-retrieval.js +139 -0
  315. package/dist/services/keyword-expansion.d.ts +10 -0
  316. package/dist/services/keyword-expansion.js +26 -0
  317. package/dist/services/lesson-service.d.ts +68 -0
  318. package/dist/services/lesson-service.js +178 -0
  319. package/dist/services/literal-extractor.d.ts +16 -0
  320. package/dist/services/literal-extractor.js +74 -0
  321. package/dist/services/literal-list-protection.d.ts +17 -0
  322. package/dist/services/literal-list-protection.js +134 -0
  323. package/dist/services/literal-query-expansion.d.ts +20 -0
  324. package/dist/services/literal-query-expansion.js +181 -0
  325. package/dist/services/llm.d.ts +61 -0
  326. package/dist/services/llm.js +265 -0
  327. package/dist/services/memcell-projection.d.ts +17 -0
  328. package/dist/services/memcell-projection.js +41 -0
  329. package/dist/services/memory-audn.d.ts +43 -0
  330. package/dist/services/memory-audn.js +419 -0
  331. package/dist/services/memory-crud.d.ts +93 -0
  332. package/dist/services/memory-crud.js +255 -0
  333. package/dist/services/memory-ingest.d.ts +21 -0
  334. package/dist/services/memory-ingest.js +249 -0
  335. package/dist/services/memory-lifecycle.d.ts +75 -0
  336. package/dist/services/memory-lifecycle.js +108 -0
  337. package/dist/services/memory-lineage.d.ts +181 -0
  338. package/dist/services/memory-lineage.js +232 -0
  339. package/dist/services/memory-network.d.ts +40 -0
  340. package/dist/services/memory-network.js +75 -0
  341. package/dist/services/memory-search-types.d.ts +25 -0
  342. package/dist/services/memory-search-types.js +10 -0
  343. package/dist/services/memory-search.d.ts +48 -0
  344. package/dist/services/memory-search.js +505 -0
  345. package/dist/services/memory-service-types.d.ts +371 -0
  346. package/dist/services/memory-service-types.js +8 -0
  347. package/dist/services/memory-service.d.ts +152 -0
  348. package/dist/services/memory-service.js +225 -0
  349. package/dist/services/memory-storage.d.ts +33 -0
  350. package/dist/services/memory-storage.js +328 -0
  351. package/dist/services/msr-aggregator.d.ts +38 -0
  352. package/dist/services/msr-aggregator.js +97 -0
  353. package/dist/services/msr-detector.d.ts +35 -0
  354. package/dist/services/msr-detector.js +65 -0
  355. package/dist/services/namespace-retrieval.d.ts +60 -0
  356. package/dist/services/namespace-retrieval.js +180 -0
  357. package/dist/services/observation-date-extraction.d.ts +12 -0
  358. package/dist/services/observation-date-extraction.js +50 -0
  359. package/dist/services/observation-service.d.ts +27 -0
  360. package/dist/services/observation-service.js +84 -0
  361. package/dist/services/packaging-observability.d.ts +29 -0
  362. package/dist/services/packaging-observability.js +146 -0
  363. package/dist/services/query-expansion.d.ts +83 -0
  364. package/dist/services/query-expansion.js +242 -0
  365. package/dist/services/query-keyword-matches.d.ts +6 -0
  366. package/dist/services/query-keyword-matches.js +56 -0
  367. package/dist/services/query-term-visibility.d.ts +28 -0
  368. package/dist/services/query-term-visibility.js +100 -0
  369. package/dist/services/quick-extraction.d.ts +25 -0
  370. package/dist/services/quick-extraction.js +431 -0
  371. package/dist/services/quoted-entity-extraction.d.ts +10 -0
  372. package/dist/services/quoted-entity-extraction.js +161 -0
  373. package/dist/services/raw-storage-reconciler-backoff.d.ts +8 -0
  374. package/dist/services/raw-storage-reconciler-backoff.js +14 -0
  375. package/dist/services/raw-storage-reconciler-scheduler.d.ts +29 -0
  376. package/dist/services/raw-storage-reconciler-scheduler.js +43 -0
  377. package/dist/services/raw-storage-reconciler.d.ts +71 -0
  378. package/dist/services/raw-storage-reconciler.js +278 -0
  379. package/dist/services/recap-builder.d.ts +49 -0
  380. package/dist/services/recap-builder.js +157 -0
  381. package/dist/services/reflect-jobs.d.ts +23 -0
  382. package/dist/services/reflect-jobs.js +36 -0
  383. package/dist/services/reflect-prompts.d.ts +71 -0
  384. package/dist/services/reflect-prompts.js +99 -0
  385. package/dist/services/reflect-retrieval.d.ts +33 -0
  386. package/dist/services/reflect-retrieval.js +30 -0
  387. package/dist/services/reflect.d.ts +49 -0
  388. package/dist/services/reflect.js +84 -0
  389. package/dist/services/relative-temporal.d.ts +14 -0
  390. package/dist/services/relative-temporal.js +163 -0
  391. package/dist/services/relevance-policy.d.ts +37 -0
  392. package/dist/services/relevance-policy.js +109 -0
  393. package/dist/services/rerank.d.ts +32 -0
  394. package/dist/services/rerank.js +118 -0
  395. package/dist/services/reranker.d.ts +20 -0
  396. package/dist/services/reranker.js +99 -0
  397. package/dist/services/retrieval-channel-rules.d.ts +34 -0
  398. package/dist/services/retrieval-channel-rules.js +41 -0
  399. package/dist/services/retrieval-config-overlay.d.ts +36 -0
  400. package/dist/services/retrieval-config-overlay.js +44 -0
  401. package/dist/services/retrieval-format.d.ts +119 -0
  402. package/dist/services/retrieval-format.js +559 -0
  403. package/dist/services/retrieval-policy.d.ts +69 -0
  404. package/dist/services/retrieval-policy.js +275 -0
  405. package/dist/services/retrieval-profiles.d.ts +37 -0
  406. package/dist/services/retrieval-profiles.js +90 -0
  407. package/dist/services/retrieval-side-effects.d.ts +14 -0
  408. package/dist/services/retrieval-side-effects.js +26 -0
  409. package/dist/services/retrieval-trace.d.ts +108 -0
  410. package/dist/services/retrieval-trace.js +147 -0
  411. package/dist/services/rrf-fusion.d.ts +18 -0
  412. package/dist/services/rrf-fusion.js +34 -0
  413. package/dist/services/search-pipeline.d.ts +71 -0
  414. package/dist/services/search-pipeline.js +788 -0
  415. package/dist/services/session-date.d.ts +20 -0
  416. package/dist/services/session-date.js +61 -0
  417. package/dist/services/session-packaging.d.ts +53 -0
  418. package/dist/services/session-packaging.js +182 -0
  419. package/dist/services/session-summary-generator.d.ts +53 -0
  420. package/dist/services/session-summary-generator.js +134 -0
  421. package/dist/services/specialists/cr-specialist.d.ts +52 -0
  422. package/dist/services/specialists/cr-specialist.js +121 -0
  423. package/dist/services/specialists/dispatch.d.ts +53 -0
  424. package/dist/services/specialists/dispatch.js +102 -0
  425. package/dist/services/specialists/ie-ku-specialist.d.ts +37 -0
  426. package/dist/services/specialists/ie-ku-specialist.js +63 -0
  427. package/dist/services/specialists/msr-specialist.d.ts +61 -0
  428. package/dist/services/specialists/msr-specialist.js +162 -0
  429. package/dist/services/specialists/tr-specialist.d.ts +37 -0
  430. package/dist/services/specialists/tr-specialist.js +146 -0
  431. package/dist/services/storage-key-prefix.d.ts +42 -0
  432. package/dist/services/storage-key-prefix.js +45 -0
  433. package/dist/services/storage-put-recovery.d.ts +71 -0
  434. package/dist/services/storage-put-recovery.js +269 -0
  435. package/dist/services/storage-service-errors.d.ts +124 -0
  436. package/dist/services/storage-service-errors.js +189 -0
  437. package/dist/services/storage-service.d.ts +176 -0
  438. package/dist/services/storage-service.js +423 -0
  439. package/dist/services/subject-aware-ranking.d.ts +19 -0
  440. package/dist/services/subject-aware-ranking.js +161 -0
  441. package/dist/services/supplemental-extraction.d.ts +7 -0
  442. package/dist/services/supplemental-extraction.js +116 -0
  443. package/dist/services/tbc-execution.d.ts +49 -0
  444. package/dist/services/tbc-execution.js +284 -0
  445. package/dist/services/temporal-classifier.d.ts +56 -0
  446. package/dist/services/temporal-classifier.js +94 -0
  447. package/dist/services/temporal-endpoint-evidence.d.ts +12 -0
  448. package/dist/services/temporal-endpoint-evidence.js +313 -0
  449. package/dist/services/temporal-fingerprint.d.ts +6 -0
  450. package/dist/services/temporal-fingerprint.js +12 -0
  451. package/dist/services/temporal-format.d.ts +9 -0
  452. package/dist/services/temporal-format.js +21 -0
  453. package/dist/services/temporal-intent.d.ts +39 -0
  454. package/dist/services/temporal-intent.js +78 -0
  455. package/dist/services/temporal-query-constraints.d.ts +16 -0
  456. package/dist/services/temporal-query-constraints.js +107 -0
  457. package/dist/services/temporal-query-expansion.d.ts +14 -0
  458. package/dist/services/temporal-query-expansion.js +131 -0
  459. package/dist/services/temporal-rerank.d.ts +22 -0
  460. package/dist/services/temporal-rerank.js +47 -0
  461. package/dist/services/temporal-result-protection.d.ts +7 -0
  462. package/dist/services/temporal-result-protection.js +60 -0
  463. package/dist/services/temporal-state-write.d.ts +57 -0
  464. package/dist/services/temporal-state-write.js +45 -0
  465. package/dist/services/tiered-context.d.ts +87 -0
  466. package/dist/services/tiered-context.js +214 -0
  467. package/dist/services/tiered-loading.d.ts +88 -0
  468. package/dist/services/tiered-loading.js +263 -0
  469. package/dist/services/timeline-pack.d.ts +36 -0
  470. package/dist/services/timeline-pack.js +50 -0
  471. package/dist/services/timing.d.ts +13 -0
  472. package/dist/services/timing.js +72 -0
  473. package/dist/services/tll-augmentation.d.ts +20 -0
  474. package/dist/services/tll-augmentation.js +125 -0
  475. package/dist/services/tll-retrieval.d.ts +55 -0
  476. package/dist/services/tll-retrieval.js +101 -0
  477. package/dist/services/topic-abstraction.d.ts +36 -0
  478. package/dist/services/topic-abstraction.js +105 -0
  479. package/dist/services/trust-scoring.d.ts +43 -0
  480. package/dist/services/trust-scoring.js +89 -0
  481. package/dist/services/typed-belief-calculus.d.ts +126 -0
  482. package/dist/services/typed-belief-calculus.js +204 -0
  483. package/dist/services/upload-config.d.ts +34 -0
  484. package/dist/services/upload-config.js +23 -0
  485. package/dist/services/upload-decision.d.ts +65 -0
  486. package/dist/services/upload-decision.js +98 -0
  487. package/dist/services/upload-helpers.d.ts +107 -0
  488. package/dist/services/upload-helpers.js +148 -0
  489. package/dist/services/user-profile-builder.d.ts +22 -0
  490. package/dist/services/user-profile-builder.js +109 -0
  491. package/dist/services/voyage-embedding.d.ts +22 -0
  492. package/dist/services/voyage-embedding.js +77 -0
  493. package/dist/services/write-security.d.ts +31 -0
  494. package/dist/services/write-security.js +64 -0
  495. package/dist/storage/artifact-public-redaction.d.ts +34 -0
  496. package/dist/storage/artifact-public-redaction.js +83 -0
  497. package/dist/storage/cleanup.d.ts +103 -0
  498. package/dist/storage/cleanup.js +138 -0
  499. package/dist/storage/codec-factory.d.ts +17 -0
  500. package/dist/storage/codec-factory.js +33 -0
  501. package/dist/storage/codecs/aes-gcm-codec.d.ts +44 -0
  502. package/dist/storage/codecs/aes-gcm-codec.js +108 -0
  503. package/dist/storage/codecs/noop-codec.d.ts +16 -0
  504. package/dist/storage/codecs/noop-codec.js +23 -0
  505. package/dist/storage/factory.d.ts +44 -0
  506. package/dist/storage/factory.js +99 -0
  507. package/dist/storage/filecoin-cid-validation.d.ts +82 -0
  508. package/dist/storage/filecoin-cid-validation.js +122 -0
  509. package/dist/storage/filecoin-public-metadata.d.ts +73 -0
  510. package/dist/storage/filecoin-public-metadata.js +110 -0
  511. package/dist/storage/local-fs-store.d.ts +39 -0
  512. package/dist/storage/local-fs-store.js +145 -0
  513. package/dist/storage/pointer-uri-allowlist.d.ts +38 -0
  514. package/dist/storage/pointer-uri-allowlist.js +70 -0
  515. package/dist/storage/provider-metadata-projection.d.ts +27 -0
  516. package/dist/storage/provider-metadata-projection.js +68 -0
  517. package/dist/storage/providers/filecoin/backend.d.ts +42 -0
  518. package/dist/storage/providers/filecoin/backend.js +250 -0
  519. package/dist/storage/providers/filecoin/config.d.ts +70 -0
  520. package/dist/storage/providers/filecoin/config.js +275 -0
  521. package/dist/storage/providers/filecoin/errors.d.ts +45 -0
  522. package/dist/storage/providers/filecoin/errors.js +56 -0
  523. package/dist/storage/providers/filecoin/filecoin-pin-car.d.ts +78 -0
  524. package/dist/storage/providers/filecoin/filecoin-pin-car.js +155 -0
  525. package/dist/storage/providers/filecoin/filecoin-pin-client.d.ts +92 -0
  526. package/dist/storage/providers/filecoin/filecoin-pin-client.js +199 -0
  527. package/dist/storage/providers/filecoin/filecoin-pin-mapping.d.ts +58 -0
  528. package/dist/storage/providers/filecoin/filecoin-pin-mapping.js +103 -0
  529. package/dist/storage/providers/filecoin/filecoin-pin-timeout.d.ts +30 -0
  530. package/dist/storage/providers/filecoin/filecoin-pin-timeout.js +53 -0
  531. package/dist/storage/providers/filecoin/filecoin-pin-vendor.d.ts +111 -0
  532. package/dist/storage/providers/filecoin/filecoin-pin-vendor.js +87 -0
  533. package/dist/storage/providers/filecoin/hints.d.ts +71 -0
  534. package/dist/storage/providers/filecoin/hints.js +123 -0
  535. package/dist/storage/providers/filecoin/index.d.ts +51 -0
  536. package/dist/storage/providers/filecoin/index.js +103 -0
  537. package/dist/storage/providers/filecoin/ipfs-cid.d.ts +50 -0
  538. package/dist/storage/providers/filecoin/ipfs-cid.js +64 -0
  539. package/dist/storage/providers/filecoin/metadata.d.ts +72 -0
  540. package/dist/storage/providers/filecoin/metadata.js +137 -0
  541. package/dist/storage/providers/filecoin/piece-cid.d.ts +48 -0
  542. package/dist/storage/providers/filecoin/piece-cid.js +57 -0
  543. package/dist/storage/providers/filecoin/provider-client.d.ts +234 -0
  544. package/dist/storage/providers/filecoin/provider-client.js +27 -0
  545. package/dist/storage/providers/filecoin/readiness.d.ts +62 -0
  546. package/dist/storage/providers/filecoin/readiness.js +85 -0
  547. package/dist/storage/providers/filecoin/retriever.d.ts +82 -0
  548. package/dist/storage/providers/filecoin/retriever.js +63 -0
  549. package/dist/storage/providers/filecoin/skeleton-client.d.ts +36 -0
  550. package/dist/storage/providers/filecoin/skeleton-client.js +55 -0
  551. package/dist/storage/providers/filecoin/synapse-client.d.ts +169 -0
  552. package/dist/storage/providers/filecoin/synapse-client.js +343 -0
  553. package/dist/storage/providers/filecoin/synapse-construction.d.ts +26 -0
  554. package/dist/storage/providers/filecoin/synapse-construction.js +47 -0
  555. package/dist/storage/providers/filecoin/synapse-error-mapping.d.ts +23 -0
  556. package/dist/storage/providers/filecoin/synapse-error-mapping.js +49 -0
  557. package/dist/storage/providers/filecoin/synapse-readiness.d.ts +37 -0
  558. package/dist/storage/providers/filecoin/synapse-readiness.js +231 -0
  559. package/dist/storage/providers/filecoin/uri.d.ts +49 -0
  560. package/dist/storage/providers/filecoin/uri.js +84 -0
  561. package/dist/storage/providers/filecoin/verified-fetch-lifecycle.d.ts +77 -0
  562. package/dist/storage/providers/filecoin/verified-fetch-lifecycle.js +196 -0
  563. package/dist/storage/providers/filecoin/verified-fetch-retriever.d.ts +54 -0
  564. package/dist/storage/providers/filecoin/verified-fetch-retriever.js +81 -0
  565. package/dist/storage/providers/filecoin/verified-fetch-vendor.d.ts +71 -0
  566. package/dist/storage/providers/filecoin/verified-fetch-vendor.js +94 -0
  567. package/dist/storage/raw-content-codec.d.ts +89 -0
  568. package/dist/storage/raw-content-codec.js +47 -0
  569. package/dist/storage/raw-content-store-backend-adapter.d.ts +28 -0
  570. package/dist/storage/raw-content-store-backend-adapter.js +67 -0
  571. package/dist/storage/raw-content-store.d.ts +228 -0
  572. package/dist/storage/raw-content-store.js +27 -0
  573. package/dist/storage/s3-store.d.ts +42 -0
  574. package/dist/storage/s3-store.js +181 -0
  575. package/dist/storage/storage-backend-registry.d.ts +58 -0
  576. package/dist/storage/storage-backend-registry.js +56 -0
  577. package/dist/storage/storage-backend.d.ts +82 -0
  578. package/dist/storage/storage-backend.js +14 -0
  579. package/dist/storage/storage-capabilities.d.ts +56 -0
  580. package/dist/storage/storage-capabilities.js +170 -0
  581. package/dist/storage/store-registry.d.ts +67 -0
  582. package/dist/storage/store-registry.js +77 -0
  583. package/dist/vector-math.d.ts +15 -0
  584. package/dist/vector-math.js +31 -0
  585. package/dist/xml-escape.d.ts +5 -0
  586. package/dist/xml-escape.js +7 -0
  587. package/openapi.json +15395 -0
  588. package/openapi.yaml +10794 -0
  589. package/package.json +119 -0
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Shared parser for transcript-level session dates.
3
+ *
4
+ * Benchmark and SDK callers can include a first-line header:
5
+ * - `[Session date: ...]` — preferred explicit form
6
+ * - `[<time_anchor> | Turn N]` or `[<time_anchor>]` — BEAM transcript form
7
+ * where `<time_anchor>` is `Month-Day-Year` or any Date-parseable string
8
+ *
9
+ * Core uses this date as the logical observation timestamp for extraction,
10
+ * storage backdating, and context packaging.
11
+ *
12
+ * IMPORTANT: BEAM transcripts also produce bare turn markers like `[Turn 43]`
13
+ * when the loader splits a session mid-stream. The captured `Turn 43` would
14
+ * pass `Date.parse()` (which interprets the trailing number as a year — e.g.
15
+ * 2043). To prevent year corruption we require the captured anchor to look
16
+ * dated (contains a month name OR a 4-digit year) before passing to Date.parse.
17
+ */
18
+ export declare function extractSessionTimestamp(conversationText: string): string | null;
19
+ export declare function parseSessionDate(conversationText: string): Date | null;
20
+ export declare function resolveSessionDate(explicitTimestamp: Date | undefined, conversationText: string): Date | undefined;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Shared parser for transcript-level session dates.
3
+ *
4
+ * Benchmark and SDK callers can include a first-line header:
5
+ * - `[Session date: ...]` — preferred explicit form
6
+ * - `[<time_anchor> | Turn N]` or `[<time_anchor>]` — BEAM transcript form
7
+ * where `<time_anchor>` is `Month-Day-Year` or any Date-parseable string
8
+ *
9
+ * Core uses this date as the logical observation timestamp for extraction,
10
+ * storage backdating, and context packaging.
11
+ *
12
+ * IMPORTANT: BEAM transcripts also produce bare turn markers like `[Turn 43]`
13
+ * when the loader splits a session mid-stream. The captured `Turn 43` would
14
+ * pass `Date.parse()` (which interprets the trailing number as a year — e.g.
15
+ * 2043). To prevent year corruption we require the captured anchor to look
16
+ * dated (contains a month name OR a 4-digit year) before passing to Date.parse.
17
+ */
18
+ const SESSION_DATE_PATTERN = /^\[Session date:\s*([^\]]+)\]/i;
19
+ const BEAM_ANCHOR_PATTERN = /^\[([^|\]]+?)(?:\s*\|\s*Turn\s+\d+)?\]\s/i;
20
+ // Lookahead validators for what counts as a real date string. Together they
21
+ // reject `Turn 43`, `Turn 134`, `code block`, etc.
22
+ const HAS_YEAR_4 = /\b\d{4}\b/;
23
+ const HAS_MONTH_NAME = /\b(jan(uary)?|feb(ruary)?|mar(ch)?|apr(il)?|may|jun(e)?|jul(y)?|aug(ust)?|sep(t|tember)?|oct(ober)?|nov(ember)?|dec(ember)?)\b/i;
24
+ const STARTS_WITH_TURN = /^\s*turn\b/i;
25
+ export function extractSessionTimestamp(conversationText) {
26
+ const firstLine = conversationText.split('\n', 1)[0] ?? '';
27
+ const explicit = firstLine.match(SESSION_DATE_PATTERN);
28
+ if (explicit?.[1])
29
+ return explicit[1].trim();
30
+ const beam = firstLine.match(BEAM_ANCHOR_PATTERN);
31
+ if (!beam?.[1])
32
+ return null;
33
+ const candidate = beam[1].trim();
34
+ // Reject bare turn markers and other non-date captures.
35
+ if (STARTS_WITH_TURN.test(candidate))
36
+ return null;
37
+ if (!HAS_YEAR_4.test(candidate) && !HAS_MONTH_NAME.test(candidate))
38
+ return null;
39
+ return normalizeAnchor(candidate);
40
+ }
41
+ /**
42
+ * BEAM anchors look like `March-15-2024`. JS Date.parse() accepts
43
+ * `March 15 2024` (spaces) but rejects the hyphenated form. Replace
44
+ * inner hyphens with spaces so Date.parse() succeeds. Other formats
45
+ * (ISO, RFC) pass through unchanged.
46
+ */
47
+ function normalizeAnchor(anchor) {
48
+ if (/^[A-Za-z]+-\d{1,2}-\d{4}$/.test(anchor))
49
+ return anchor.replace(/-/g, ' ');
50
+ return anchor;
51
+ }
52
+ export function parseSessionDate(conversationText) {
53
+ const timestamp = extractSessionTimestamp(conversationText);
54
+ if (!timestamp)
55
+ return null;
56
+ const parsed = new Date(timestamp);
57
+ return Number.isNaN(parsed.getTime()) ? null : parsed;
58
+ }
59
+ export function resolveSessionDate(explicitTimestamp, conversationText) {
60
+ return explicitTimestamp ?? parseSessionDate(conversationText) ?? undefined;
61
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Multi-session answer-bearing packaging policy.
3
+ *
4
+ * Groups retrieved memories by source session (episode_id) and promotes
5
+ * answer-bearing atoms — those containing currencies, durations/dates,
6
+ * past-attendance language, or named participants — above generic
7
+ * advisory/recommendation content within each session group.
8
+ *
9
+ * Session groups are ordered chronologically by earliest memory.
10
+ * When all memories share one session (or have no episode_id),
11
+ * falls back to pure chronological sort to avoid unnecessary churn.
12
+ */
13
+ import type { SearchResult } from '../db/repository-types.js';
14
+ /**
15
+ * Detect whether a memory's content is answer-bearing: contains specific
16
+ * retrievable facts (currencies, durations, attendance, named participants)
17
+ * rather than generic advisory prose.
18
+ */
19
+ export declare function isAnswerBearing(content: string): boolean;
20
+ /**
21
+ * Detect whether a memory is advisory-only: matches generic advisory patterns
22
+ * AND does NOT match any answer-bearing pattern. Answer-bearing always wins.
23
+ */
24
+ export declare function isAdvisoryOnly(content: string): boolean;
25
+ /**
26
+ * Budget-aware trim that drops advisory atoms first.
27
+ * Answer-bearing memories always occupy first slots; advisory fills remainder.
28
+ */
29
+ export declare function trimToAnswerBearingBudget(memories: SearchResult[], maxResults: number): SearchResult[];
30
+ /**
31
+ * Three-tier within-session priority for a single memory.
32
+ *
33
+ * Tier 1 — Direct answer: amounts, dates, counts, outcomes, scored results.
34
+ * These are the facts most likely to directly answer a question.
35
+ * Tier 2 — Supporting facts: participants, locations, state transitions,
36
+ * attendance. Provide context for tier-1 facts.
37
+ * Tier 3 — Advisory/context: everything else (recommendations, planning,
38
+ * meta-conversation, or neutral prose).
39
+ *
40
+ * Chronological order is preserved within each tier.
41
+ */
42
+ export declare function withinSessionTier(content: string): 1 | 2 | 3;
43
+ /**
44
+ * Sort memories with session-aware answer-bearing promotion.
45
+ *
46
+ * When memories span multiple sessions (distinct episode_ids):
47
+ * 1. Group by episode_id
48
+ * 2. Promote answer-bearing atoms within each group
49
+ * 3. Order groups chronologically by earliest memory
50
+ *
51
+ * When all memories share one session, falls back to chronological sort.
52
+ */
53
+ export declare function sortBySessionPriority(memories: SearchResult[]): SearchResult[];
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Multi-session answer-bearing packaging policy.
3
+ *
4
+ * Groups retrieved memories by source session (episode_id) and promotes
5
+ * answer-bearing atoms — those containing currencies, durations/dates,
6
+ * past-attendance language, or named participants — above generic
7
+ * advisory/recommendation content within each session group.
8
+ *
9
+ * Session groups are ordered chronologically by earliest memory.
10
+ * When all memories share one session (or have no episode_id),
11
+ * falls back to pure chronological sort to avoid unnecessary churn.
12
+ */
13
+ /** Currency amounts: $500, €200, 1000 dollars */
14
+ const CURRENCY_PATTERN = /(?:\$|€|£|¥)\s*[\d,]+(?:\.\d+)?|\b\d[\d,]*(?:\.\d+)?\s*(?:dollars?|euros?|pounds?|USD|EUR|GBP|yen|yuan)\b/i;
15
+ /** Durations: "3 months", "2 weeks"; named dates: "January 15" */
16
+ const DURATION_DATE_PATTERN = /\b\d+\s*(?:hours?|days?|weeks?|months?|years?|minutes?|seconds?)\b|\b(?:January|February|March|April|May|June|July|August|September|October|November|December)\s+\d{1,2}\b/i;
17
+ /** Past-attendance verbs indicating the user did something. */
18
+ const ATTENDANCE_PATTERN = /\b(?:attended|visited|went\s+to|traveled\s+to|participated\s+in|joined|enrolled|signed\s+up|registered|completed|graduated|moved\s+to|flew\s+to|arrived)\b/i;
19
+ /** Multi-word proper nouns: "Dr. Smith", "John Carter", "Miss Bee Providore" */
20
+ const NAMED_PARTICIPANT_PATTERN = /\b(?:Dr\.?\s+[A-Z][a-z]+|[A-Z][a-z]+(?:\s+[A-Z][a-z]+)+)\b/;
21
+ /** Explicit year references: "in 2023", "since 2019" */
22
+ const YEAR_REFERENCE_PATTERN = /\b(?:in|since|from|until|before|after|around)\s+\d{4}\b/i;
23
+ /** Specific people counts: "15 participants", "200 employees" */
24
+ const QUANTITY_PATTERN = /\b\d+\s*(?:people|participants|attendees|members|students|employees|guests|speakers|teams?)\b/i;
25
+ /** Explicit counts: "3 times", "5 occasions" */
26
+ const EXPLICIT_COUNT_PATTERN = /\b\d+\s*(?:times|occasions|instances|sessions)\b/i;
27
+ /** Location with proper noun: "at Stanford", "in Berlin" */
28
+ const LOCATION_SPECIFICITY_PATTERN = /\b(?:at|in|near|from)\s+[A-Z][a-z]+(?:\s+[A-Z][a-z]+)*\b/;
29
+ /** State transitions: "switched from X to Y" */
30
+ const STATE_TRANSITION_PATTERN = /\b(?:switched|changed|moved|migrated|upgraded|transitioned)\s+(?:from|to)\b/i;
31
+ /** Scored/measured results: "scored 170", "rated 4.5" */
32
+ const COMPARATIVE_RESULT_PATTERN = /\b(?:scored|rated|ranked|received|earned|achieved)\s+\d/i;
33
+ /** Concrete event outcomes: accepted, completed, won, passed, etc. */
34
+ const EVENT_OUTCOME_PATTERN = /\b(?:accepted|completed|finished|passed|failed|won|lost|received|submitted|launched|published|hired|fired|promoted|resigned|retired|delivered|shipped)\b/i;
35
+ /** Generic advisory prose from the assistant. */
36
+ const ADVISORY_RECOMMENDATION_PATTERN = /\b(?:(?:assistant|AI)\s+(?:recommended|suggested|advised))\b/i;
37
+ /** Vague planning without anchoring specifics. */
38
+ const VAGUE_PLANNING_PATTERN = /\b(?:plans?\s+to|wants?\s+to|considering|thinking\s+about)\b/i;
39
+ /** Meta-conversation summaries. */
40
+ const META_CONVERSATION_PATTERN = /\b(?:discussed|talked\s+about|conversation\s+about)\b/i;
41
+ /**
42
+ * Detect whether a memory's content is answer-bearing: contains specific
43
+ * retrievable facts (currencies, durations, attendance, named participants)
44
+ * rather than generic advisory prose.
45
+ */
46
+ export function isAnswerBearing(content) {
47
+ return (CURRENCY_PATTERN.test(content) ||
48
+ DURATION_DATE_PATTERN.test(content) ||
49
+ ATTENDANCE_PATTERN.test(content) ||
50
+ NAMED_PARTICIPANT_PATTERN.test(content) ||
51
+ YEAR_REFERENCE_PATTERN.test(content) ||
52
+ QUANTITY_PATTERN.test(content) ||
53
+ EXPLICIT_COUNT_PATTERN.test(content) ||
54
+ LOCATION_SPECIFICITY_PATTERN.test(content) ||
55
+ STATE_TRANSITION_PATTERN.test(content) ||
56
+ COMPARATIVE_RESULT_PATTERN.test(content) ||
57
+ EVENT_OUTCOME_PATTERN.test(content));
58
+ }
59
+ /**
60
+ * Detect whether a memory is advisory-only: matches generic advisory patterns
61
+ * AND does NOT match any answer-bearing pattern. Answer-bearing always wins.
62
+ */
63
+ export function isAdvisoryOnly(content) {
64
+ if (isAnswerBearing(content))
65
+ return false;
66
+ return (ADVISORY_RECOMMENDATION_PATTERN.test(content) ||
67
+ VAGUE_PLANNING_PATTERN.test(content) ||
68
+ META_CONVERSATION_PATTERN.test(content));
69
+ }
70
+ /**
71
+ * Budget-aware trim that drops advisory atoms first.
72
+ * Answer-bearing memories always occupy first slots; advisory fills remainder.
73
+ */
74
+ export function trimToAnswerBearingBudget(memories, maxResults) {
75
+ if (memories.length <= maxResults)
76
+ return sortBySessionPriority(memories);
77
+ const answerBearingPool = [];
78
+ const advisoryPool = [];
79
+ for (const m of memories) {
80
+ if (isAnswerBearing(m.content)) {
81
+ answerBearingPool.push(m);
82
+ }
83
+ else {
84
+ advisoryPool.push(m);
85
+ }
86
+ }
87
+ const byScore = (a, b) => b.score - a.score;
88
+ answerBearingPool.sort(byScore);
89
+ advisoryPool.sort(byScore);
90
+ const selected = answerBearingPool.slice(0, maxResults);
91
+ const remaining = maxResults - selected.length;
92
+ if (remaining > 0) {
93
+ selected.push(...advisoryPool.slice(0, remaining));
94
+ }
95
+ return sortBySessionPriority(selected);
96
+ }
97
+ /** Chronological sort by created_at ascending. */
98
+ function sortChronologically(memories) {
99
+ return [...memories].sort((a, b) => a.created_at.getTime() - b.created_at.getTime());
100
+ }
101
+ /**
102
+ * Three-tier within-session priority for a single memory.
103
+ *
104
+ * Tier 1 — Direct answer: amounts, dates, counts, outcomes, scored results.
105
+ * These are the facts most likely to directly answer a question.
106
+ * Tier 2 — Supporting facts: participants, locations, state transitions,
107
+ * attendance. Provide context for tier-1 facts.
108
+ * Tier 3 — Advisory/context: everything else (recommendations, planning,
109
+ * meta-conversation, or neutral prose).
110
+ *
111
+ * Chronological order is preserved within each tier.
112
+ */
113
+ export function withinSessionTier(content) {
114
+ if (CURRENCY_PATTERN.test(content) ||
115
+ DURATION_DATE_PATTERN.test(content) ||
116
+ EXPLICIT_COUNT_PATTERN.test(content) ||
117
+ QUANTITY_PATTERN.test(content) ||
118
+ COMPARATIVE_RESULT_PATTERN.test(content) ||
119
+ YEAR_REFERENCE_PATTERN.test(content) ||
120
+ EVENT_OUTCOME_PATTERN.test(content)) {
121
+ return 1;
122
+ }
123
+ if (ATTENDANCE_PATTERN.test(content) ||
124
+ NAMED_PARTICIPANT_PATTERN.test(content) ||
125
+ LOCATION_SPECIFICITY_PATTERN.test(content) ||
126
+ STATE_TRANSITION_PATTERN.test(content)) {
127
+ return 2;
128
+ }
129
+ return 3;
130
+ }
131
+ /**
132
+ * Within a single session group, promote answer-bearing atoms above
133
+ * advisory atoms using a three-tier ordering. Chronological order is
134
+ * preserved within each tier.
135
+ */
136
+ function promoteAnswerBearing(memories) {
137
+ const tier1 = [];
138
+ const tier2 = [];
139
+ const tier3 = [];
140
+ for (const m of memories) {
141
+ const tier = withinSessionTier(m.content);
142
+ if (tier === 1)
143
+ tier1.push(m);
144
+ else if (tier === 2)
145
+ tier2.push(m);
146
+ else
147
+ tier3.push(m);
148
+ }
149
+ return [
150
+ ...sortChronologically(tier1),
151
+ ...sortChronologically(tier2),
152
+ ...sortChronologically(tier3),
153
+ ];
154
+ }
155
+ /**
156
+ * Sort memories with session-aware answer-bearing promotion.
157
+ *
158
+ * When memories span multiple sessions (distinct episode_ids):
159
+ * 1. Group by episode_id
160
+ * 2. Promote answer-bearing atoms within each group
161
+ * 3. Order groups chronologically by earliest memory
162
+ *
163
+ * When all memories share one session, falls back to chronological sort.
164
+ */
165
+ export function sortBySessionPriority(memories) {
166
+ if (memories.length <= 1)
167
+ return [...memories];
168
+ const episodes = new Set(memories.map((m) => m.episode_id));
169
+ if (episodes.size <= 1)
170
+ return sortChronologically(memories);
171
+ const groups = new Map();
172
+ for (const m of memories) {
173
+ const key = m.episode_id ?? 'no-session';
174
+ if (!groups.has(key))
175
+ groups.set(key, []);
176
+ groups.get(key).push(m);
177
+ }
178
+ const sortedGroups = [...groups.values()]
179
+ .map(promoteAnswerBearing)
180
+ .sort((a, b) => a[0].created_at.getTime() - b[0].created_at.getTime());
181
+ return sortedGroups.flat();
182
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Session + conversation summary generation for hierarchical retrieval (T2.2).
3
+ *
4
+ * Called at end-of-session ingest (session summary) and end-of-conversation
5
+ * ingest (conversation summary). Output is persisted to `session_summaries`
6
+ * and `conv_summaries` tables; embeddings are computed by the caller using
7
+ * the existing `embedText` pipeline.
8
+ *
9
+ * Cost-aware: small sessions (< MIN_FACTS_FOR_LLM facts) skip the LLM call
10
+ * and return a deterministic concat. Saves cost on tiny conversational
11
+ * fragments and keeps unit-test cost at zero.
12
+ *
13
+ * No new LLM provider — reuses the shared LLMProvider interface from llm.ts.
14
+ * Activated by `hierarchicalRetrievalEnabled=true` in IngestRuntimeConfig.
15
+ */
16
+ import type { LLMProvider } from './llm.js';
17
+ export interface SessionSummary {
18
+ summary: string;
19
+ topics: string[];
20
+ /** True when the LLM was invoked; false when the deterministic-skip path fired. */
21
+ llmInvoked: boolean;
22
+ }
23
+ export interface ConvSummary {
24
+ summary: string;
25
+ llmInvoked: boolean;
26
+ }
27
+ export interface SummaryGenerationOptions {
28
+ /** Random seed forwarded to the LLM provider when supported (for determinism). */
29
+ seed?: number;
30
+ /** Optional override for the small-session deterministic-skip threshold. */
31
+ minFactsForLlm?: number;
32
+ }
33
+ /**
34
+ * Generate a topical summary for one session.
35
+ *
36
+ * Returns `{summary, topics}`:
37
+ * - summary : ~100-token natural-language sketch ("kickoff: API design, auth choices")
38
+ * - topics : up to MAX_TOPICS short noun-phrase tags ("api design", "auth", "kickoff")
39
+ *
40
+ * For sessions with fewer than `minFactsForLlm` facts, returns a deterministic
41
+ * concat of the first 3 facts plus their first-noun-phrase as topics — this
42
+ * keeps unit tests free of LLM mocks and is empirically as good as a tiny LLM
43
+ * summary on short sessions.
44
+ */
45
+ export declare function generateSessionSummary(sessionFacts: string[], llm: LLMProvider, opts?: SummaryGenerationOptions): Promise<SessionSummary>;
46
+ /**
47
+ * Generate a conversation-level summary by rolling up session summaries.
48
+ *
49
+ * `sessionSummaries` are passed in chronological order. Output is ~200-token
50
+ * natural-language overview ("project kickoff through API redesign;
51
+ * decisions on Postgres + JWT auth; outstanding question on rate-limit").
52
+ */
53
+ export declare function generateConvSummary(sessionSummaries: string[], llm: LLMProvider, opts?: SummaryGenerationOptions): Promise<ConvSummary>;
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Session + conversation summary generation for hierarchical retrieval (T2.2).
3
+ *
4
+ * Called at end-of-session ingest (session summary) and end-of-conversation
5
+ * ingest (conversation summary). Output is persisted to `session_summaries`
6
+ * and `conv_summaries` tables; embeddings are computed by the caller using
7
+ * the existing `embedText` pipeline.
8
+ *
9
+ * Cost-aware: small sessions (< MIN_FACTS_FOR_LLM facts) skip the LLM call
10
+ * and return a deterministic concat. Saves cost on tiny conversational
11
+ * fragments and keeps unit-test cost at zero.
12
+ *
13
+ * No new LLM provider — reuses the shared LLMProvider interface from llm.ts.
14
+ * Activated by `hierarchicalRetrievalEnabled=true` in IngestRuntimeConfig.
15
+ */
16
+ const MIN_FACTS_FOR_LLM = 5;
17
+ const SESSION_SUMMARY_MAX_TOKENS = 150;
18
+ const CONV_SUMMARY_MAX_TOKENS = 280;
19
+ const MAX_TOPICS = 8;
20
+ /**
21
+ * Generate a topical summary for one session.
22
+ *
23
+ * Returns `{summary, topics}`:
24
+ * - summary : ~100-token natural-language sketch ("kickoff: API design, auth choices")
25
+ * - topics : up to MAX_TOPICS short noun-phrase tags ("api design", "auth", "kickoff")
26
+ *
27
+ * For sessions with fewer than `minFactsForLlm` facts, returns a deterministic
28
+ * concat of the first 3 facts plus their first-noun-phrase as topics — this
29
+ * keeps unit tests free of LLM mocks and is empirically as good as a tiny LLM
30
+ * summary on short sessions.
31
+ */
32
+ export async function generateSessionSummary(sessionFacts, llm, opts = {}) {
33
+ const minFacts = opts.minFactsForLlm ?? MIN_FACTS_FOR_LLM;
34
+ if (sessionFacts.length < minFacts) {
35
+ return deterministicSessionSummary(sessionFacts);
36
+ }
37
+ const userMsg = buildSessionPrompt(sessionFacts);
38
+ const raw = await llm.chat([
39
+ { role: 'system', content: SESSION_SYSTEM_PROMPT },
40
+ { role: 'user', content: userMsg },
41
+ ], { maxTokens: SESSION_SUMMARY_MAX_TOKENS, jsonMode: true, seed: opts.seed });
42
+ return parseSessionResponse(raw, sessionFacts);
43
+ }
44
+ /**
45
+ * Generate a conversation-level summary by rolling up session summaries.
46
+ *
47
+ * `sessionSummaries` are passed in chronological order. Output is ~200-token
48
+ * natural-language overview ("project kickoff through API redesign;
49
+ * decisions on Postgres + JWT auth; outstanding question on rate-limit").
50
+ */
51
+ export async function generateConvSummary(sessionSummaries, llm, opts = {}) {
52
+ const minFacts = opts.minFactsForLlm ?? MIN_FACTS_FOR_LLM;
53
+ if (sessionSummaries.length < minFacts) {
54
+ return {
55
+ summary: sessionSummaries.join(' / ').slice(0, 600),
56
+ llmInvoked: false,
57
+ };
58
+ }
59
+ const userMsg = buildConvPrompt(sessionSummaries);
60
+ const raw = await llm.chat([
61
+ { role: 'system', content: CONV_SYSTEM_PROMPT },
62
+ { role: 'user', content: userMsg },
63
+ ], { maxTokens: CONV_SUMMARY_MAX_TOKENS, jsonMode: true, seed: opts.seed });
64
+ return { summary: parseConvResponse(raw), llmInvoked: true };
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // Prompts
68
+ // ---------------------------------------------------------------------------
69
+ const SESSION_SYSTEM_PROMPT = 'You produce a structured summary of one conversation session. ' +
70
+ 'Output ONLY valid JSON of the form {"summary": "...", "topics": ["...", "..."]}. ' +
71
+ 'The "summary" field is one to two sentences (≤ 100 tokens) describing what was ' +
72
+ 'discussed and any decisions reached. The "topics" field is up to 8 short noun-phrase ' +
73
+ 'tags. No prose outside the JSON.';
74
+ const CONV_SYSTEM_PROMPT = 'You produce a structured summary of an entire conversation by rolling up its session ' +
75
+ 'summaries. Output ONLY valid JSON of the form {"summary": "..."}. The "summary" field ' +
76
+ 'is two to four sentences (≤ 200 tokens) covering the conversation arc. No prose ' +
77
+ 'outside the JSON.';
78
+ function buildSessionPrompt(facts) {
79
+ const enumerated = facts.slice(0, 50).map((f, i) => `${i + 1}. ${f}`).join('\n');
80
+ return `Session facts:\n${enumerated}\n\nReturn JSON {summary, topics}.`;
81
+ }
82
+ function buildConvPrompt(summaries) {
83
+ const enumerated = summaries.map((s, i) => `Session ${i + 1}: ${s}`).join('\n');
84
+ return `Session summaries (chronological):\n${enumerated}\n\nReturn JSON {summary}.`;
85
+ }
86
+ // ---------------------------------------------------------------------------
87
+ // Deterministic-skip path
88
+ // ---------------------------------------------------------------------------
89
+ function deterministicSessionSummary(facts) {
90
+ const lead = facts.slice(0, 3).join(' / ').slice(0, 400);
91
+ const topics = extractDeterministicTopics(facts);
92
+ return { summary: lead, topics, llmInvoked: false };
93
+ }
94
+ function extractDeterministicTopics(facts) {
95
+ const tokens = facts
96
+ .flatMap((f) => f.toLowerCase().split(/\W+/))
97
+ .filter((t) => t.length >= 4);
98
+ const counts = new Map();
99
+ for (const t of tokens)
100
+ counts.set(t, (counts.get(t) ?? 0) + 1);
101
+ return Array.from(counts.entries())
102
+ .sort((a, b) => b[1] - a[1])
103
+ .slice(0, MAX_TOPICS)
104
+ .map(([word]) => word);
105
+ }
106
+ function parseSessionResponse(raw, fallbackFacts) {
107
+ const parsed = tryParseJson(raw);
108
+ if (!parsed || typeof parsed.summary !== 'string') {
109
+ return { ...deterministicSessionSummary(fallbackFacts), llmInvoked: true };
110
+ }
111
+ const topics = Array.isArray(parsed.topics)
112
+ ? parsed.topics.filter((t) => typeof t === 'string').slice(0, MAX_TOPICS)
113
+ : [];
114
+ return { summary: parsed.summary, topics, llmInvoked: true };
115
+ }
116
+ function parseConvResponse(raw) {
117
+ const parsed = tryParseJson(raw);
118
+ if (parsed && typeof parsed.summary === 'string')
119
+ return parsed.summary;
120
+ // Fail-safe: return raw text trimmed
121
+ return raw.trim().slice(0, 600);
122
+ }
123
+ function tryParseJson(raw) {
124
+ const trimmed = raw.trim();
125
+ // Tolerate ```json fenced blocks
126
+ const fence = trimmed.match(/^```(?:json)?\s*([\s\S]*?)```$/);
127
+ const body = fence ? fence[1].trim() : trimmed;
128
+ try {
129
+ return JSON.parse(body);
130
+ }
131
+ catch {
132
+ return null;
133
+ }
134
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * CR (Contradiction Resolution) specialist.
3
+ *
4
+ * Replaces the deleted Layer 3 counter-edge-surface module which was
5
+ * broken (the [CONTRADICTS] marker confused Haiku into picking the wrong
6
+ * side). The new approach: explicit FACT A / FACT B framing via tool-use
7
+ * so the LLM produces BEAM's canonical "you said X but also Y" answer.
8
+ *
9
+ * Flow:
10
+ * 1) Pattern-match the query (e.g. "have I ever", "did I ever")
11
+ * 2) Query belief_edges for COUNTER edges among the retrieved top-K
12
+ * 3) Fetch BOTH sides of each edge
13
+ * 4) Call Haiku with explicit fact_a/fact_b framing via tool-use
14
+ * 5) Return the LLM's answer (which should follow the BEAM canonical shape)
15
+ */
16
+ import type { BeliefEdgesRepository } from '../../db/belief-edges-repository.js';
17
+ import type { MemoryRepository } from '../../db/memory-repository.js';
18
+ /** Pattern check: should the CR specialist handle this query? */
19
+ export declare function shouldInvokeCrSpecialist(query: string): boolean;
20
+ export interface CrMemoryInput {
21
+ id: string;
22
+ text: string;
23
+ }
24
+ export interface CrSpecialistDeps {
25
+ /** Top-K retrieved memories from the shared search spine. */
26
+ memories: ReadonlyArray<CrMemoryInput>;
27
+ /** Original user query. */
28
+ query: string;
29
+ /** User ID scoping all DB lookups. */
30
+ userId: string;
31
+ /** Anthropic model ID (e.g. 'claude-haiku-4-5'). */
32
+ model: string;
33
+ /** BeliefEdgesRepository — null when TBC is disabled. */
34
+ beliefEdges: BeliefEdgesRepository | null;
35
+ /** MemoryRepository for fetching sides not present in top-K. */
36
+ memoryRepo: MemoryRepository;
37
+ }
38
+ export interface CrSpecialistResult {
39
+ /** The LLM answer in canonical "You said X but also Y" shape. */
40
+ answer: string;
41
+ /** Whether the specialist handled the query (false = fall through to spine). */
42
+ handled: boolean;
43
+ /** Number of bilateral contradiction pairs found. */
44
+ contradictionsFound: number;
45
+ }
46
+ /**
47
+ * Run the CR specialist.
48
+ *
49
+ * Returns handled=false when the query doesn't match the CR pattern,
50
+ * so callers can fall through to the standard search spine.
51
+ */
52
+ export declare function runCrSpecialist(deps: CrSpecialistDeps): Promise<CrSpecialistResult>;
@@ -0,0 +1,121 @@
1
+ /**
2
+ * CR (Contradiction Resolution) specialist.
3
+ *
4
+ * Replaces the deleted Layer 3 counter-edge-surface module which was
5
+ * broken (the [CONTRADICTS] marker confused Haiku into picking the wrong
6
+ * side). The new approach: explicit FACT A / FACT B framing via tool-use
7
+ * so the LLM produces BEAM's canonical "you said X but also Y" answer.
8
+ *
9
+ * Flow:
10
+ * 1) Pattern-match the query (e.g. "have I ever", "did I ever")
11
+ * 2) Query belief_edges for COUNTER edges among the retrieved top-K
12
+ * 3) Fetch BOTH sides of each edge
13
+ * 4) Call Haiku with explicit fact_a/fact_b framing via tool-use
14
+ * 5) Return the LLM's answer (which should follow the BEAM canonical shape)
15
+ */
16
+ import { callAnthropicTool } from '../llm.js';
17
+ /** Pattern check: should the CR specialist handle this query? */
18
+ export function shouldInvokeCrSpecialist(query) {
19
+ // BEAM CR phrasings: "have I ever / did I ever / am I / do I / conflicting / contradict"
20
+ return /\b(have I (ever|already|previously)|did I (ever|already|previously)|am I (currently|now)|conflicting|contradict)\b/i.test(query);
21
+ }
22
+ const CR_TOOL_SCHEMA = {
23
+ name: 'answer_contradiction',
24
+ description: 'Answer a contradiction-resolution question by surfacing both conflicting facts.',
25
+ input_schema: {
26
+ type: 'object',
27
+ properties: {
28
+ both_sides_present: { type: 'boolean' },
29
+ answer_text: {
30
+ type: 'string',
31
+ description: 'BEAM canonical shape: "You said X but also Y. Could you clarify which is correct?"',
32
+ },
33
+ },
34
+ required: ['both_sides_present', 'answer_text'],
35
+ },
36
+ };
37
+ /** Resolve the text for a single memory side (top-K cache first, then DB). */
38
+ async function resolveMemoryText(userId, id, topK, memoryRepo) {
39
+ const cached = topK.find(m => m.id === id);
40
+ if (cached)
41
+ return cached.text;
42
+ const row = await memoryRepo.getMemory(id, userId);
43
+ return row?.content ?? '';
44
+ }
45
+ /** Query COUNTER edges and resolve both sides into ContradictionPair[]. */
46
+ async function fetchContradictions(deps) {
47
+ if (!deps.beliefEdges)
48
+ return [];
49
+ const topIds = deps.memories.map(m => m.id);
50
+ if (topIds.length === 0)
51
+ return [];
52
+ const edges = await deps.beliefEdges.findCounterEdgesForMemories(deps.userId, topIds);
53
+ if (edges.length === 0)
54
+ return [];
55
+ const pairs = [];
56
+ const seen = new Set();
57
+ for (const e of edges) {
58
+ const key = [e.sourceId, e.targetId].sort().join('|');
59
+ if (seen.has(key))
60
+ continue;
61
+ seen.add(key);
62
+ const [factA, factB] = await Promise.all([
63
+ resolveMemoryText(deps.userId, e.sourceId, deps.memories, deps.memoryRepo),
64
+ resolveMemoryText(deps.userId, e.targetId, deps.memories, deps.memoryRepo),
65
+ ]);
66
+ if (factA && factB) {
67
+ pairs.push({ factA, factB });
68
+ }
69
+ }
70
+ return pairs;
71
+ }
72
+ /** Build system prompt for CR tool-use call. */
73
+ function buildSystemPrompt() {
74
+ return [
75
+ 'You are answering a contradiction-resolution question.',
76
+ 'The user\'s memory contains two conflicting facts about the same topic.',
77
+ 'Surface both sides explicitly using this canonical shape:',
78
+ '',
79
+ '"You said X but also Y. Could you clarify which is correct?"',
80
+ '',
81
+ 'Where X and Y are the two contradicting claims.',
82
+ 'Call the answer_contradiction tool. Do NOT free-text.',
83
+ ].join('\n');
84
+ }
85
+ /** Build user message listing contradicting fact pairs. */
86
+ function buildUserMessage(query, pairs) {
87
+ const lines = [
88
+ `User question: ${query}`,
89
+ '',
90
+ 'Contradicting facts:',
91
+ ...pairs.flatMap((p, i) => [
92
+ `Pair ${i + 1}:`,
93
+ ` FACT A: ${p.factA}`,
94
+ ` FACT B (contradicts A): ${p.factB}`,
95
+ ]),
96
+ ];
97
+ return lines.join('\n');
98
+ }
99
+ /**
100
+ * Run the CR specialist.
101
+ *
102
+ * Returns handled=false when the query doesn't match the CR pattern,
103
+ * so callers can fall through to the standard search spine.
104
+ */
105
+ export async function runCrSpecialist(deps) {
106
+ if (!shouldInvokeCrSpecialist(deps.query)) {
107
+ return { answer: '', handled: false, contradictionsFound: 0 };
108
+ }
109
+ const pairs = await fetchContradictions(deps);
110
+ if (pairs.length === 0) {
111
+ return { answer: '', handled: true, contradictionsFound: 0 };
112
+ }
113
+ const system = buildSystemPrompt();
114
+ const userText = buildUserMessage(deps.query, pairs);
115
+ const tool = await callAnthropicTool(deps.model, system, userText, CR_TOOL_SCHEMA);
116
+ return {
117
+ answer: tool.answer_text,
118
+ handled: true,
119
+ contradictionsFound: pairs.length,
120
+ };
121
+ }