@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,596 @@
1
+ /**
2
+ * Memory extraction and AUDN resolution.
3
+ * Step 1: Extract discrete facts from conversation text.
4
+ * Step 2: For each fact with similar existing memories, LLM decides:
5
+ * Add (new), Update (merge), Delete (outdated), or Noop (skip).
6
+ * Uses the LLM provider abstraction for model-agnostic operation.
7
+ */
8
+ import { llm } from './llm.js';
9
+ import { withCostStage } from './cost-telemetry.js';
10
+ import { timed, timedSync } from './timing.js';
11
+ import { normalizeExtractedFacts } from './fact-normalization.js';
12
+ import { enrichExtractedFacts } from './extraction-enrichment.js';
13
+ import { mergeSupplementalFacts } from './supplemental-extraction.js';
14
+ import { applyObservationDateAnchors, buildExtractionUserMessage, } from './observation-date-extraction.js';
15
+ const EXTRACTION_MAX_TOKENS = 4096;
16
+ const AUDN_MAX_TOKENS = 2048;
17
+ /** Strip markdown code fences (```json ... ```) that some LLMs wrap around JSON output. */
18
+ function stripJsonFences(raw) {
19
+ const trimmed = raw.trim();
20
+ if (trimmed.startsWith('```')) {
21
+ const firstNewline = trimmed.indexOf('\n');
22
+ if (firstNewline < 0)
23
+ return trimmed;
24
+ const lastFence = trimmed.lastIndexOf('```');
25
+ if (lastFence > firstNewline) {
26
+ // Both opening and closing fences present
27
+ return trimmed.slice(firstNewline + 1, lastFence).trim();
28
+ }
29
+ // Opening fence but no closing fence (truncated response) — strip the opening fence
30
+ return trimmed.slice(firstNewline + 1).trim();
31
+ }
32
+ return trimmed;
33
+ }
34
+ /** Return the first complete JSON object, tolerating prose before/after it. */
35
+ export function extractFirstJsonObject(raw) {
36
+ const cleaned = stripJsonFences(raw);
37
+ if (isValidJson(cleaned))
38
+ return cleaned;
39
+ const start = cleaned.indexOf('{');
40
+ if (start < 0)
41
+ return cleaned;
42
+ const end = findBalancedJsonObjectEnd(cleaned, start);
43
+ return end < 0 ? cleaned : cleaned.slice(start, end + 1);
44
+ }
45
+ function isValidJson(value) {
46
+ try {
47
+ JSON.parse(value);
48
+ return true;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ function findBalancedJsonObjectEnd(input, start) {
55
+ const state = { depth: 0, inString: false, escaped: false };
56
+ for (let i = start; i < input.length; i++) {
57
+ if (advanceJsonScanState(state, input[i]))
58
+ return i;
59
+ }
60
+ return -1;
61
+ }
62
+ function advanceJsonScanState(state, char) {
63
+ if (state.escaped) {
64
+ state.escaped = false;
65
+ return false;
66
+ }
67
+ if (char === '\\') {
68
+ state.escaped = state.inString;
69
+ return false;
70
+ }
71
+ if (char === '"') {
72
+ state.inString = !state.inString;
73
+ return false;
74
+ }
75
+ if (state.inString)
76
+ return false;
77
+ return updateJsonDepth(state, char);
78
+ }
79
+ function updateJsonDepth(state, char) {
80
+ if (char === '{')
81
+ state.depth++;
82
+ if (char === '}')
83
+ state.depth--;
84
+ return state.depth === 0;
85
+ }
86
+ /**
87
+ * Attempts to recover a valid JSON object from truncated LLM output.
88
+ * Finds the last complete object boundary, closes unterminated strings/arrays/objects,
89
+ * and wraps in the expected `{"memories": [...]}` structure if needed.
90
+ */
91
+ function repairTruncatedJson(raw) {
92
+ const lastBrace = raw.lastIndexOf('}');
93
+ if (lastBrace <= 0)
94
+ return null;
95
+ const candidate = removeTrailingJsonCommas(raw.slice(0, lastBrace + 1));
96
+ if (isValidJson(candidate))
97
+ return candidate;
98
+ const repaired = closeAtLastCompleteArrayEntry(candidate);
99
+ return repaired && isValidJson(repaired) ? repaired : null;
100
+ }
101
+ function removeTrailingJsonCommas(value) {
102
+ return value.replace(/,\s*\]/, ']').replace(/,\s*\}/, '}');
103
+ }
104
+ function closeAtLastCompleteArrayEntry(candidate) {
105
+ // Walk backwards to find the last complete array entry boundary
106
+ // Look for `},` or `}]` patterns that mark a complete object in the memories array
107
+ const lastCompleteEntry = candidate.lastIndexOf('},');
108
+ const lastArrayClose = candidate.lastIndexOf('}]');
109
+ const cutPoint = Math.max(lastCompleteEntry, lastArrayClose);
110
+ if (cutPoint <= 0)
111
+ return null;
112
+ return closeOpenJsonContainers(candidate.slice(0, cutPoint + 1));
113
+ }
114
+ function closeOpenJsonContainers(value) {
115
+ const openBrackets = Math.max(0, countMatches(value, '[') - countMatches(value, ']'));
116
+ const openBraces = Math.max(0, countMatches(value, '{') - countMatches(value, '}'));
117
+ return value + ']'.repeat(openBrackets) + '}'.repeat(openBraces);
118
+ }
119
+ function countMatches(value, char) {
120
+ return [...value].filter((candidate) => candidate === char).length;
121
+ }
122
+ export const EXTRACTION_PROMPT = `You are a memory extraction system. Extract discrete, self-contained facts from the conversation below. Each fact should be useful if retrieved months later in a completely different conversation.
123
+
124
+ RULES:
125
+ - Each fact must be a single, atomic statement.
126
+ - **AGGRESSIVE TECHNOLOGY SPLITTING**: Every named tool, framework, library, or technology MUST become its own separate fact. Never combine multiple technologies into a single fact.
127
+ WRONG: "User is building a React project with Tailwind CSS and Supabase."
128
+ RIGHT: Three separate facts:
129
+ 1. "As of January 2026, user is building a personal finance tracker using React."
130
+ 2. "As of January 2026, user is using Tailwind CSS for styling in the finance tracker project."
131
+ 3. "As of January 2026, user is using Supabase for the backend and database in the finance tracker project."
132
+ - If a sentence contains multiple independent attributes of the same project or tool, split them into separate facts.
133
+ - If a sentence contains both a technical choice and who recommended it, extract separate facts for the choice and the recommendation.
134
+ - Each technology fact MUST include the project name, the current date (if available), and the specific role of the technology.
135
+ - Include enough context to be understood in isolation.
136
+ - Replace pronouns with specific names/references.
137
+ - Convert relative times to absolute when possible.
138
+ - Always include dates and timestamps in extracted facts when available (e.g. "As of January 2026, user prefers Vite" not just "User prefers Vite").
139
+ - If the conversation has a date/session header, use it to anchor facts temporally.
140
+ - **ENTITY-FOCUSED EXTRACTION**: Every named person, institution, organization, specific number, or score mentioned by the user MUST appear in at least one extracted fact. Scan the conversation for these and create dedicated facts:
141
+ - People: names, roles, relationships (e.g. "Dr. Chen is user's advisor at Microsoft Research")
142
+ - Institutions: universities, companies, labs (e.g. "User got BS in Computer Science from UC Berkeley")
143
+ - Numbers/scores: test scores, percentages, counts (e.g. "User scored 170 on GRE quant")
144
+ - Licenses/certifications: specific names (e.g. "User plans to use MIT license for dotctl")
145
+ - Future plans: specific tools or techniques planned (e.g. "User plans to add ML classification using TensorFlow.js")
146
+ If you find a name, number, or institution in the conversation that is NOT in any extracted fact, you MUST add a fact for it.
147
+ - **CORRECTION/REVISION PRESERVATION**: When the conversation contains an explicit correction, revision, or supersession of a previous statement (e.g. "Correction:", "Actually,", "Changed my mind"), the extracted fact MUST preserve the corrective relationship. Include phrasing like "instead of Y", "replacing Y", "corrected from Y", or "no longer Y" so the system can detect the supersession.
148
+ WRONG: "User wants PostgreSQL for the production backend."
149
+ RIGHT: "User wants PostgreSQL for the production backend, replacing the earlier MongoDB choice."
150
+ - Skip pleasantries, filler, acknowledgments, and meta-conversation.
151
+ - Skip generic assistant chatter (acknowledgments, "sure!", "got it", "as an AI").
152
+ - DO extract specific factual content from assistant responses: named entities, recommendations with proper nouns, schedules, data tables, creative writing with specific details. Prefix these with "Assistant mentioned:" or "Assistant recommended:".
153
+ - SHORT INPUTS: Even a single sentence like "My email is bob@example.com" contains an extractable fact. Do NOT skip short inputs — if the user stated something factual, extract it regardless of length.
154
+ - CONTACT INFO: Email addresses, phone numbers, home addresses, and similar personal details are always extractable facts with importance >= 0.5.
155
+ - Rate importance 0.0-1.0:
156
+ 0.0-0.3 = trivial (greeting style, minor preferences)
157
+ 0.4-0.6 = useful (project details, tools mentioned)
158
+ 0.7-0.9 = important (core preferences, key decisions, recurring patterns)
159
+ 1.0 = critical (explicit instructions for future, strong opinions)
160
+
161
+ CATEGORIES:
162
+ - preference: Likes, dislikes, opinions, style choices
163
+ - project: What the user is building, tools used, architecture decisions
164
+ - knowledge: Patterns learned, problems solved, techniques discovered
165
+ - person: People mentioned, relationships, roles
166
+ - plan: Goals, intentions, scheduled activities, future work
167
+
168
+ KEYWORDS:
169
+ For each fact, extract keywords that a keyword search should match. Include:
170
+ - Proper nouns (people, companies, products, tools): "Jake", "Supabase", "TanStack Virtual"
171
+ - Dates and time references: "January 15 2026", "February 5 2026"
172
+ - Project names and domains: "fintrack.app", "dotctl"
173
+ - Technical terms that might be lost in paraphrasing: "tRPC", "LoRA", "EMNLP"
174
+ - Organization names: "Stanford", "Microsoft Research", "MIT"
175
+ Keywords preserve the original spelling and casing from the conversation.
176
+
177
+ HEADLINE:
178
+ For each fact, write a short headline (max 10 words) that captures the key point.
179
+ The headline is used as a compact preview when listing memories. It should contain
180
+ the most important entity and action from the fact.
181
+ Example: "User prefers Vite over Webpack for all React projects" → "Prefers Vite over Webpack for React"
182
+
183
+ ENTITIES:
184
+ For each fact, extract the named entities mentioned. Each entity has:
185
+ - name: The entity's canonical name (e.g. "Jake", "PostgreSQL", "Dataflow Inc")
186
+ - type: One of: person, tool, project, organization, place, concept
187
+ Entity types:
188
+ - person: Named individuals (e.g. "Jake", "Dr. Chen", "Sarah")
189
+ - tool: Software, libraries, frameworks (e.g. "PostgreSQL", "Vite", "React")
190
+ - project: Named projects or products (e.g. "DataFlow", "MealMate", "dotctl")
191
+ - organization: Companies, universities, teams (e.g. "MIT", "Google", "Dataflow Inc")
192
+ - place: Cities, countries, addresses (e.g. "San Francisco", "Berlin")
193
+ - concept: Abstract concepts, methodologies (e.g. "microservices", "TDD")
194
+ Only extract entities explicitly named in the fact. Do not infer entities not mentioned.
195
+
196
+ RELATIONS:
197
+ For each fact, extract relationships between entities mentioned in that fact.
198
+ Each relation has:
199
+ - source: Name of the source entity (must match an entity name above)
200
+ - target: Name of the target entity (must match an entity name above)
201
+ - type: One of: uses, works_on, works_at, located_in, knows, prefers, created, belongs_to, studies, manages
202
+ Relation types:
203
+ - uses: Person/project uses a tool/technology
204
+ - works_on: Person works on a project
205
+ - works_at: Person works at an organization
206
+ - located_in: Person/organization is located in a place
207
+ - knows: Person knows another person
208
+ - prefers: Person prefers a tool/concept
209
+ - created: Person created a project/tool
210
+ - belongs_to: Entity belongs to an organization/group
211
+ - studies: Person studies a concept/field
212
+ - manages: Person manages a project/team
213
+ Only extract relations between entities explicitly mentioned in the fact. If a fact has fewer than 2 entities, return an empty relations array.
214
+
215
+ OUTPUT FORMAT (JSON):
216
+ {
217
+ "memories": [
218
+ {
219
+ "fact": "User prefers Vite over Webpack for all React projects",
220
+ "headline": "Prefers Vite over Webpack for React",
221
+ "importance": 0.7,
222
+ "type": "preference",
223
+ "keywords": ["Vite", "Webpack", "React"],
224
+ "entities": [
225
+ {"name": "Vite", "type": "tool"},
226
+ {"name": "Webpack", "type": "tool"},
227
+ {"name": "React", "type": "tool"}
228
+ ],
229
+ "relations": [
230
+ {"source": "User", "target": "Vite", "type": "prefers"}
231
+ ]
232
+ }
233
+ ]
234
+ }
235
+
236
+ If no extractable facts exist, return: {"memories": []}`;
237
+ export async function extractFacts(conversationText, options = {}) {
238
+ const content = await timed('ingest.extract.llm', () => withCostStage('extract', () => llm.chat([
239
+ { role: 'system', content: EXTRACTION_PROMPT },
240
+ { role: 'user', content: buildExtractionUserMessage(conversationText, options) },
241
+ ], { temperature: 0, jsonMode: true, maxTokens: EXTRACTION_MAX_TOKENS })));
242
+ if (!content)
243
+ return [];
244
+ const rawFacts = timedSync('ingest.extract.parse', () => parseExtractionResponse(content));
245
+ if (!rawFacts)
246
+ return [];
247
+ return timedSync('ingest.extract.post-process', () => {
248
+ const normalized = rawFacts.map((m) => normalizeRawFact(m));
249
+ const anchoredFacts = applyObservationDateAnchors(normalized, conversationText, options);
250
+ const baseFacts = enrichExtractedFacts(normalizeExtractedFacts(anchoredFacts));
251
+ return mergeSupplementalFacts(baseFacts, conversationText);
252
+ });
253
+ }
254
+ /** Parse and validate LLM extraction response, returning raw facts or null on failure. */
255
+ function parseExtractionResponse(content) {
256
+ const cleanedContent = stripJsonFences(content);
257
+ const parsed = parseJsonWithRepair(cleanedContent);
258
+ if (!parsed)
259
+ return null;
260
+ return resolveFactArray(parsed, content);
261
+ }
262
+ /** Parse JSON, falling back to truncated-JSON repair on failure. */
263
+ function parseJsonWithRepair(cleanedContent) {
264
+ try {
265
+ return JSON.parse(cleanedContent);
266
+ }
267
+ catch (err) {
268
+ console.warn(`[extractFacts] JSON parse failed (${err.message}); attempting repair`);
269
+ }
270
+ const repaired = repairTruncatedJson(cleanedContent);
271
+ if (!repaired) {
272
+ console.warn('[extractFacts] No valid JSON found; returning empty. Raw:', cleanedContent.slice(0, 300));
273
+ return null;
274
+ }
275
+ try {
276
+ return JSON.parse(repaired);
277
+ }
278
+ catch {
279
+ console.warn('[extractFacts] JSON repair failed; returning empty. Raw:', cleanedContent.slice(0, 300));
280
+ return null;
281
+ }
282
+ }
283
+ /** Extract a fact array from parsed JSON, trying standard keys then fallbacks. */
284
+ function resolveFactArray(parsed, rawContent) {
285
+ const standardArray = parsed.memories
286
+ ?? parsed.facts;
287
+ if (Array.isArray(standardArray))
288
+ return standardArray;
289
+ const found = findFactArray(parsed);
290
+ if (found)
291
+ return found;
292
+ const leafFacts = extractLeafFacts(parsed);
293
+ if (leafFacts.length > 0) {
294
+ console.warn(`[extractFacts] Recovered ${leafFacts.length} facts from non-standard JSON structure`);
295
+ return leafFacts;
296
+ }
297
+ console.warn('[extractFacts] LLM returned no memories array; raw:', rawContent.slice(0, 200));
298
+ return null;
299
+ }
300
+ /** Normalize a single raw extracted fact into the canonical ExtractedFact shape. */
301
+ function normalizeRawFact(m) {
302
+ const rawEntry = m;
303
+ const fact = rawEntry.fact ?? rawEntry.statement ?? '';
304
+ const rawImportance = Number(m.importance);
305
+ const importance = Number.isFinite(rawImportance) ? Math.max(0, Math.min(1, rawImportance)) : 0.5;
306
+ const VALID_TYPES = new Set(['preference', 'project', 'knowledge', 'person', 'plan']);
307
+ const rawType = typeof m.type === 'string' ? m.type.toLowerCase() : '';
308
+ return {
309
+ fact,
310
+ importance,
311
+ type: VALID_TYPES.has(rawType) ? rawType : 'knowledge',
312
+ keywords: Array.isArray(m.keywords) ? m.keywords : [],
313
+ headline: typeof m.headline === 'string' && m.headline.trim() ? m.headline.trim() : generateFallbackHeadline(fact),
314
+ entities: normalizeExtractedEntities(m.entities),
315
+ relations: normalizeExtractedRelations(m.relations),
316
+ };
317
+ }
318
+ /**
319
+ * Search parsed JSON for the first array value containing fact-like objects
320
+ * (objects with a 'fact' or 'statement' string field).
321
+ */
322
+ function findFactArray(obj) {
323
+ for (const value of Object.values(obj)) {
324
+ if (Array.isArray(value) && value.length > 0 && typeof value[0] === 'object' && value[0] !== null) {
325
+ const first = value[0];
326
+ if (typeof first.fact === 'string' || typeof first.statement === 'string') {
327
+ return value;
328
+ }
329
+ }
330
+ }
331
+ return null;
332
+ }
333
+ const MIN_LEAF_FACT_LENGTH = 30;
334
+ const MAX_LEAF_FACT_LENGTH = 500;
335
+ function extractLeafFacts(obj, path = []) {
336
+ if (obj === null || obj === undefined)
337
+ return [];
338
+ if (typeof obj === 'string') {
339
+ return extractLeafFromString(obj);
340
+ }
341
+ if (Array.isArray(obj)) {
342
+ return obj.flatMap((item) => extractLeafFacts(item, path));
343
+ }
344
+ if (typeof obj === 'object') {
345
+ return extractLeafFromObject(obj, path);
346
+ }
347
+ return [];
348
+ }
349
+ /** Build a LeafFact with default fields. */
350
+ function makeLeafFact(fact, headline) {
351
+ return { fact, importance: 0.5, headline, type: 'knowledge', keywords: [], entities: [], relations: [] };
352
+ }
353
+ /** Extract a leaf fact from a string if it meets length requirements. */
354
+ function extractLeafFromString(text) {
355
+ if (text.length >= MIN_LEAF_FACT_LENGTH && text.length <= MAX_LEAF_FACT_LENGTH) {
356
+ return [makeLeafFact(text, text.slice(0, 60))];
357
+ }
358
+ return [];
359
+ }
360
+ /** Try to combine an object's string values into a fact, or recurse into children. */
361
+ function extractLeafFromObject(record, path) {
362
+ const combinedFact = tryCombineStringEntries(record, path);
363
+ if (combinedFact)
364
+ return [combinedFact];
365
+ const facts = [];
366
+ for (const [key, value] of Object.entries(record)) {
367
+ if (key === 'error' || key === 'response')
368
+ continue;
369
+ facts.push(...extractLeafFacts(value, [...path, key]));
370
+ }
371
+ return facts;
372
+ }
373
+ /** Combine 2-6 short string entries into a single fact, or return null. */
374
+ function tryCombineStringEntries(record, path) {
375
+ const stringEntries = Object.entries(record).filter(([, v]) => typeof v === 'string' && v.length > 3);
376
+ if (stringEntries.length < 2 || stringEntries.length > 6)
377
+ return null;
378
+ const combined = stringEntries
379
+ .map(([k, v]) => `${k.replace(/_/g, ' ')}: ${v}`)
380
+ .join('. ');
381
+ if (combined.length < MIN_LEAF_FACT_LENGTH || combined.length > MAX_LEAF_FACT_LENGTH)
382
+ return null;
383
+ const headline = path.length > 0 ? path[path.length - 1].replace(/_/g, ' ') : combined.slice(0, 60);
384
+ return makeLeafFact(combined, headline);
385
+ }
386
+ const AUDN_PROMPT = `You manage a memory store. Given a NEW fact extracted from a conversation and EXISTING memories that are semantically similar, decide what to do.
387
+
388
+ ACTIONS:
389
+ - ADD: The new fact contains information not already covered by existing memories. Store it as a new memory. This is the DEFAULT action — when in doubt, ADD.
390
+ - UPDATE: The new fact is a minor correction or clarification of an existing memory (e.g. fixing a typo, adding a small qualifier). The updated_content replaces the existing memory. Use ONLY when the result would be roughly the same length as the original.
391
+ - SUPERSEDE: The new fact explicitly contradicts an existing memory (e.g. user changed preference, switched tools, reversed a decision). The old memory is marked as superseded and the new fact is stored. This is the PREFERRED action for contradictions — do NOT use UPDATE to merge contradictory facts.
392
+ - DELETE: The existing memory is completely wrong or obsolete and should be removed. Use SUPERSEDE instead when the new fact replaces the old one.
393
+ - NOOP: The new fact is EXACTLY the same information as an existing memory, just rephrased. Only use when NO new information would be gained by storing the fact.
394
+ - CLARIFY: The new fact conflicts with an existing memory but the confidence is low, or it's a critical safety conflict that requires user confirmation.
395
+
396
+ RULES:
397
+ - **Prefer ADD over UPDATE.** Two separate facts about the same topic should be stored as two memories, not merged into one. For example, "user uses Go for dotctl" and "user plans to open source dotctl under MIT" are two separate facts even though both are about dotctl.
398
+ - **NEVER MERGE TECHNICAL DETAILS**: If a project uses multiple tools (e.g. Vite, React, Supabase), each MUST be a separate memory. Do NOT update a "project uses React" memory to include "and Vite". Use ADD instead.
399
+ - Only use NOOP when the new fact is truly redundant — it adds zero new information beyond what's already stored.
400
+ - Only use UPDATE for minor corrections (typos, small qualifiers), NOT for combining related facts. If the updated_content would be substantially longer than the original, use ADD instead.
401
+ - Use SUPERSEDE (not UPDATE) when the new fact contradicts or replaces an old one. Never merge contradictory facts into one statement.
402
+ - Use DELETE only for removing clearly wrong or spam content, not for preference changes.
403
+ - Use CLARIFY if you detect a conflict but:
404
+ 1. The user sounds uncertain ('I think...', 'maybe...', 'not sure').
405
+ 2. The existing fact is critical (Importance >= 0.9) and the new input is brief or lacks explanation.
406
+ 3. The conflict is complex and merging them into an 'UPDATE' would lose important nuance.
407
+ - **CRITICAL**: If you are unsure whether to SUPERSEDE or CLARIFY, you MUST choose **CLARIFY**. It is better to ask for confirmation than to store potentially false information.
408
+ - The updated_content for UPDATE should be a single self-contained statement roughly the same length as the original.
409
+
410
+ OUTPUT FORMAT (JSON):
411
+ {
412
+ "action": "ADD" | "UPDATE" | "SUPERSEDE" | "DELETE" | "NOOP" | "CLARIFY",
413
+ "target_memory_id": null | "id of existing memory to update or delete",
414
+ "updated_content": null | "merged content for UPDATE action",
415
+ "clarification_note": null | "description of the conflict for CLARIFY action",
416
+ "contradiction_confidence": null | 0.0-1.0
417
+ }
418
+
419
+ Return only the JSON object. Do not wrap it in markdown fences. Do not explain your reasoning.
420
+ `;
421
+ export async function resolveAUDN(newFact, existingMemories) {
422
+ const memoriesBlock = existingMemories
423
+ .map((m) => `[ID: ${m.id}] (similarity: ${m.similarity.toFixed(2)}) ${m.content}`)
424
+ .join('\n');
425
+ const content = await llm.chat([
426
+ { role: 'system', content: AUDN_PROMPT },
427
+ { role: 'user', content: `NEW FACT: ${newFact}\n\nEXISTING MEMORIES:\n${memoriesBlock}` },
428
+ ], { temperature: 0, jsonMode: true, maxTokens: AUDN_MAX_TOKENS });
429
+ if (!content) {
430
+ return defaultDecision();
431
+ }
432
+ const cleanedAudn = extractFirstJsonObject(content);
433
+ let parsed;
434
+ try {
435
+ parsed = JSON.parse(cleanedAudn);
436
+ }
437
+ catch {
438
+ console.error('AUDN JSON parse failed, defaulting to ADD. Raw:', content.slice(0, 200));
439
+ return defaultDecision();
440
+ }
441
+ return {
442
+ action: normalizeAction(parsed.action),
443
+ targetMemoryId: sanitizeUuid(parsed.target_memory_id),
444
+ updatedContent: parsed.updated_content ?? null,
445
+ clarificationNote: parsed.clarification_note ?? null,
446
+ contradictionConfidence: normalizeConfidence(parsed.contradiction_confidence, parsed.action ?? 'ADD', newFact),
447
+ };
448
+ }
449
+ const QUERY_REWRITE_PROMPT = `You rewrite user messages into better memory retrieval queries. The goal is to find stored facts about the user that are relevant to their current message.
450
+
451
+ RULES:
452
+ - Expand the query to cover related topics the memory store might contain.
453
+ - **DO NOT** introduce new concepts, entities, or requirements not present in the original query.
454
+ - **PRESERVE ALL ENTITIES**: Keep all specific names (Dr. Chen, Stanford, dotctl, etc.) from the original.
455
+ - If the query mentions "backup plan", do not assume it means data backups unless specified.
456
+ - Keep it concise — a single paragraph of search terms and phrases.
457
+ - Do NOT answer the question — only rewrite it for retrieval.
458
+ - If the query is already specific and factual, return it mostly unchanged.
459
+
460
+ OUTPUT: Return ONLY the rewritten query text, nothing else.`;
461
+ /**
462
+ * LRU cache for query rewrites — avoids redundant LLM calls for identical queries.
463
+ * Temperature=0 makes output deterministic, so caching is safe.
464
+ */
465
+ const REWRITE_CACHE_MAX = 128;
466
+ const rewriteCache = new Map();
467
+ export async function rewriteQuery(query) {
468
+ const cached = rewriteCache.get(query);
469
+ if (cached !== undefined) {
470
+ // Move to end (most recently used)
471
+ rewriteCache.delete(query);
472
+ rewriteCache.set(query, cached);
473
+ return cached;
474
+ }
475
+ const content = await llm.chat([
476
+ { role: 'system', content: QUERY_REWRITE_PROMPT },
477
+ { role: 'user', content: query },
478
+ ], { temperature: 0, maxTokens: 200 });
479
+ const rewritten = content.trim() || query;
480
+ if (rewriteCache.size >= REWRITE_CACHE_MAX) {
481
+ const oldest = rewriteCache.keys().next().value;
482
+ if (oldest !== undefined)
483
+ rewriteCache.delete(oldest);
484
+ }
485
+ rewriteCache.set(query, rewritten);
486
+ return rewritten;
487
+ }
488
+ /** Clear the rewrite cache (for testing). */
489
+ export function clearRewriteCache() {
490
+ rewriteCache.clear();
491
+ }
492
+ /** Get rewrite cache size (for testing/monitoring). */
493
+ export function getRewriteCacheSize() {
494
+ return rewriteCache.size;
495
+ }
496
+ const MULTI_QUERY_PROMPT = `You generate alternative search queries for a memory retrieval system. Given a user question, produce exactly 3 alternative phrasings that might match stored facts differently.
497
+
498
+ RULES:
499
+ - Each variant should emphasize different aspects, synonyms, or entity names from the question
500
+ - Keep variants concise (1-2 sentences each)
501
+ - Do NOT answer the question — only rephrase it for retrieval
502
+ - Include entity names, proper nouns, and specific terms likely stored in memory
503
+
504
+ OUTPUT: Return exactly 3 lines, one query variant per line. No numbering, no bullets, no extra text.`;
505
+ async function generateQueryVariants(query) {
506
+ const content = await llm.chat([
507
+ { role: 'system', content: MULTI_QUERY_PROMPT },
508
+ { role: 'user', content: query },
509
+ ], { temperature: 0.3, maxTokens: 300 });
510
+ if (!content)
511
+ return [];
512
+ return content.trim().split('\n').filter((line) => line.trim().length > 0).slice(0, 3);
513
+ }
514
+ const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
515
+ /** Sanitize a UUID string from LLM output: trim whitespace, validate format. */
516
+ function sanitizeUuid(raw) {
517
+ if (!raw)
518
+ return null;
519
+ const trimmed = raw.replace(/\s+/g, '').trim();
520
+ return UUID_REGEX.test(trimmed) ? trimmed : null;
521
+ }
522
+ /** Normalize a raw action string to a valid AUDNAction, defaulting to ADD. */
523
+ export function normalizeAction(raw) {
524
+ if (!raw)
525
+ return 'ADD';
526
+ const upper = raw.toUpperCase().trim();
527
+ if (upper === 'ADD' || upper === 'UPDATE' || upper === 'DELETE' || upper === 'SUPERSEDE' || upper === 'NOOP' || upper === 'CLARIFY') {
528
+ return upper;
529
+ }
530
+ return 'ADD';
531
+ }
532
+ /** Return the default ADD decision (no target, no content). */
533
+ export function defaultDecision() {
534
+ return {
535
+ action: 'ADD',
536
+ targetMemoryId: null,
537
+ updatedContent: null,
538
+ clarificationNote: null,
539
+ contradictionConfidence: null,
540
+ };
541
+ }
542
+ /** Normalize contradiction confidence: clamp to [0,1] or infer from action. */
543
+ export function normalizeConfidence(value, rawAction, newFact) {
544
+ if (typeof value === 'number' && Number.isFinite(value)) {
545
+ return Math.max(0, Math.min(1, value));
546
+ }
547
+ const action = normalizeAction(rawAction);
548
+ if (action === 'CLARIFY')
549
+ return inferConflictConfidence(newFact, true);
550
+ if (action === 'SUPERSEDE' || action === 'DELETE') {
551
+ return inferConflictConfidence(newFact, false);
552
+ }
553
+ return null;
554
+ }
555
+ /** Infer conflict confidence from fact text; forceLow=true returns 0.35. */
556
+ export function inferConflictConfidence(newFact, forceLow) {
557
+ if (forceLow)
558
+ return 0.35;
559
+ const lower = newFact.toLowerCase();
560
+ const uncertainMarkers = ['maybe', 'might', 'not sure', 'i think', 'perhaps', 'guess', 'check'];
561
+ return uncertainMarkers.some((marker) => lower.includes(marker)) ? 0.35 : 0.9;
562
+ }
563
+ const VALID_ENTITY_TYPES = new Set(['person', 'tool', 'project', 'organization', 'place', 'concept']);
564
+ const VALID_RELATION_TYPES = new Set([
565
+ 'uses', 'works_on', 'works_at', 'located_in', 'knows',
566
+ 'prefers', 'created', 'belongs_to', 'studies', 'manages',
567
+ ]);
568
+ /** Normalize and validate extracted entities, filtering out invalid entries. */
569
+ export function normalizeExtractedEntities(raw) {
570
+ if (!Array.isArray(raw))
571
+ return [];
572
+ return raw
573
+ .filter((e) => typeof e === 'object' && e !== null &&
574
+ typeof e.name === 'string' && e.name.trim().length > 0 &&
575
+ typeof e.type === 'string' && VALID_ENTITY_TYPES.has(e.type))
576
+ .map((e) => ({ name: e.name.trim(), type: e.type }));
577
+ }
578
+ /** Normalize and validate extracted relations, filtering out invalid entries. */
579
+ export function normalizeExtractedRelations(raw) {
580
+ if (!Array.isArray(raw))
581
+ return [];
582
+ return raw
583
+ .filter((r) => typeof r === 'object' && r !== null &&
584
+ typeof r.source === 'string' && r.source.trim().length > 0 &&
585
+ typeof r.target === 'string' && r.target.trim().length > 0 &&
586
+ typeof r.type === 'string' && VALID_RELATION_TYPES.has(r.type))
587
+ .map((r) => ({ source: r.source.trim(), target: r.target.trim(), type: r.type }));
588
+ }
589
+ const HEADLINE_MAX_WORDS = 10;
590
+ /** Truncate a fact to its first ~10 words as a fallback headline. */
591
+ export function generateFallbackHeadline(fact) {
592
+ const words = fact.split(/\s+/);
593
+ if (words.length <= HEADLINE_MAX_WORDS)
594
+ return fact;
595
+ return words.slice(0, HEADLINE_MAX_WORDS).join(' ') + '...';
596
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Deterministic post-processing for LLM-extracted facts.
3
+ * Preserves atomic memory coverage by splitting common multi-clause patterns
4
+ * that the extraction prompt still tends to bundle together.
5
+ */
6
+ export interface NormalizedFactInput {
7
+ fact: string;
8
+ importance: number;
9
+ type: string;
10
+ keywords: string[];
11
+ }
12
+ export declare function normalizeExtractedFacts<T extends NormalizedFactInput>(facts: T[]): T[];