@fgv/ts-agent-memory 5.1.0-47 → 5.1.0-49

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 (376) hide show
  1. package/dist/packlets/ingest/orchestrator.js +11 -1
  2. package/dist/packlets/ingest/orchestrator.js.map +1 -1
  3. package/dist/packlets/observe/memoryObservationStore.js +6 -0
  4. package/dist/packlets/observe/memoryObservationStore.js.map +1 -1
  5. package/dist/packlets/observe/observer.js.map +1 -1
  6. package/dist/packlets/retrieve/linkTraversalRetriever.js +1 -1
  7. package/dist/packlets/retrieve/linkTraversalRetriever.js.map +1 -1
  8. package/dist/packlets/retrieve/recencyRetriever.js +1 -1
  9. package/dist/packlets/retrieve/recencyRetriever.js.map +1 -1
  10. package/dist/packlets/retrieve/retriever.js +11 -5
  11. package/dist/packlets/retrieve/retriever.js.map +1 -1
  12. package/dist/packlets/retrieve/structuredFilterRetriever.js +27 -5
  13. package/dist/packlets/retrieve/structuredFilterRetriever.js.map +1 -1
  14. package/dist/packlets/retrieve/tagRetriever.js +1 -1
  15. package/dist/packlets/retrieve/tagRetriever.js.map +1 -1
  16. package/dist/packlets/retrieve/temporalRetrievers.js +1 -1
  17. package/dist/packlets/retrieve/temporalRetrievers.js.map +1 -1
  18. package/dist/packlets/store/fileTreeMemoryStore.js +152 -132
  19. package/dist/packlets/store/fileTreeMemoryStore.js.map +1 -1
  20. package/dist/packlets/store/vectorMaintenance.js +251 -0
  21. package/dist/packlets/store/vectorMaintenance.js.map +1 -0
  22. package/dist/packlets/types/envelope.js.map +1 -1
  23. package/dist/packlets/vector/inMemoryCosineIndex.js +81 -18
  24. package/dist/packlets/vector/inMemoryCosineIndex.js.map +1 -1
  25. package/dist/packlets/vector/inMemoryFragmentCosineIndex.js +7 -0
  26. package/dist/packlets/vector/inMemoryFragmentCosineIndex.js.map +1 -1
  27. package/dist/packlets/vector/vectorIndex.js.map +1 -1
  28. package/dist/ts-agent-memory.d.ts +431 -79
  29. package/lib/packlets/ingest/orchestrator.d.ts.map +1 -1
  30. package/lib/packlets/ingest/orchestrator.js +11 -1
  31. package/lib/packlets/ingest/orchestrator.js.map +1 -1
  32. package/lib/packlets/observe/memoryObservationStore.d.ts.map +1 -1
  33. package/lib/packlets/observe/memoryObservationStore.js +6 -0
  34. package/lib/packlets/observe/memoryObservationStore.js.map +1 -1
  35. package/lib/packlets/observe/observer.d.ts +61 -0
  36. package/lib/packlets/observe/observer.d.ts.map +1 -1
  37. package/lib/packlets/observe/observer.js.map +1 -1
  38. package/lib/packlets/retrieve/linkTraversalRetriever.d.ts +1 -1
  39. package/lib/packlets/retrieve/linkTraversalRetriever.js +1 -1
  40. package/lib/packlets/retrieve/linkTraversalRetriever.js.map +1 -1
  41. package/lib/packlets/retrieve/recencyRetriever.d.ts +1 -1
  42. package/lib/packlets/retrieve/recencyRetriever.js +1 -1
  43. package/lib/packlets/retrieve/recencyRetriever.js.map +1 -1
  44. package/lib/packlets/retrieve/retriever.d.ts +26 -7
  45. package/lib/packlets/retrieve/retriever.d.ts.map +1 -1
  46. package/lib/packlets/retrieve/retriever.js +11 -5
  47. package/lib/packlets/retrieve/retriever.js.map +1 -1
  48. package/lib/packlets/retrieve/structuredFilterRetriever.d.ts +26 -4
  49. package/lib/packlets/retrieve/structuredFilterRetriever.d.ts.map +1 -1
  50. package/lib/packlets/retrieve/structuredFilterRetriever.js +27 -5
  51. package/lib/packlets/retrieve/structuredFilterRetriever.js.map +1 -1
  52. package/lib/packlets/retrieve/tagRetriever.d.ts +1 -1
  53. package/lib/packlets/retrieve/tagRetriever.js +1 -1
  54. package/lib/packlets/retrieve/tagRetriever.js.map +1 -1
  55. package/lib/packlets/retrieve/temporalRetrievers.js +1 -1
  56. package/lib/packlets/retrieve/temporalRetrievers.js.map +1 -1
  57. package/lib/packlets/store/fileTreeMemoryStore.d.ts +135 -59
  58. package/lib/packlets/store/fileTreeMemoryStore.d.ts.map +1 -1
  59. package/lib/packlets/store/fileTreeMemoryStore.js +151 -131
  60. package/lib/packlets/store/fileTreeMemoryStore.js.map +1 -1
  61. package/lib/packlets/store/vectorMaintenance.d.ts +149 -0
  62. package/lib/packlets/store/vectorMaintenance.d.ts.map +1 -0
  63. package/lib/packlets/store/vectorMaintenance.js +255 -0
  64. package/lib/packlets/store/vectorMaintenance.js.map +1 -0
  65. package/lib/packlets/types/envelope.d.ts +11 -0
  66. package/lib/packlets/types/envelope.d.ts.map +1 -1
  67. package/lib/packlets/types/envelope.js.map +1 -1
  68. package/lib/packlets/vector/inMemoryCosineIndex.d.ts +30 -7
  69. package/lib/packlets/vector/inMemoryCosineIndex.d.ts.map +1 -1
  70. package/lib/packlets/vector/inMemoryCosineIndex.js +80 -17
  71. package/lib/packlets/vector/inMemoryCosineIndex.js.map +1 -1
  72. package/lib/packlets/vector/inMemoryFragmentCosineIndex.d.ts +7 -0
  73. package/lib/packlets/vector/inMemoryFragmentCosineIndex.d.ts.map +1 -1
  74. package/lib/packlets/vector/inMemoryFragmentCosineIndex.js +7 -0
  75. package/lib/packlets/vector/inMemoryFragmentCosineIndex.js.map +1 -1
  76. package/lib/packlets/vector/vectorIndex.d.ts +129 -1
  77. package/lib/packlets/vector/vectorIndex.d.ts.map +1 -1
  78. package/lib/packlets/vector/vectorIndex.js.map +1 -1
  79. package/package.json +17 -7
  80. package/.rush/temp/5667e36f1c0cc503a5c20a3ebff76e7b9a702d41.tar.log +0 -468
  81. package/.rush/temp/chunked-rush-logs/ts-agent-memory.build.chunks.jsonl +0 -9
  82. package/.rush/temp/operation/build/all.log +0 -9
  83. package/.rush/temp/operation/build/log-chunks.jsonl +0 -9
  84. package/.rush/temp/operation/build/state.json +0 -3
  85. package/.rush/temp/shrinkwrap-deps.json +0 -689
  86. package/config/api-extractor.json +0 -343
  87. package/config/jest.config.json +0 -14
  88. package/config/rig.json +0 -4
  89. package/dist/test/unit/converters/antagonistRoundTrip.test.js +0 -95
  90. package/dist/test/unit/converters/antagonistRoundTrip.test.js.map +0 -1
  91. package/dist/test/unit/converters/bodyConverterRegistry.test.js +0 -72
  92. package/dist/test/unit/converters/bodyConverterRegistry.test.js.map +0 -1
  93. package/dist/test/unit/converters/envelopeConverter.test.js +0 -313
  94. package/dist/test/unit/converters/envelopeConverter.test.js.map +0 -1
  95. package/dist/test/unit/index/memoryIndex.test.js +0 -214
  96. package/dist/test/unit/index/memoryIndex.test.js.map +0 -1
  97. package/dist/test/unit/ingest/antagonistCycleAndParity.test.js +0 -277
  98. package/dist/test/unit/ingest/antagonistCycleAndParity.test.js.map +0 -1
  99. package/dist/test/unit/ingest/cycleGuard.test.js +0 -81
  100. package/dist/test/unit/ingest/cycleGuard.test.js.map +0 -1
  101. package/dist/test/unit/ingest/dedupScope.test.js +0 -434
  102. package/dist/test/unit/ingest/dedupScope.test.js.map +0 -1
  103. package/dist/test/unit/ingest/orchestrator.test.js +0 -1058
  104. package/dist/test/unit/ingest/orchestrator.test.js.map +0 -1
  105. package/dist/test/unit/observe/memoryObservationStore.test.js +0 -118
  106. package/dist/test/unit/observe/memoryObservationStore.test.js.map +0 -1
  107. package/dist/test/unit/retrieve/fragmentSemanticRetriever.test.js +0 -116
  108. package/dist/test/unit/retrieve/fragmentSemanticRetriever.test.js.map +0 -1
  109. package/dist/test/unit/retrieve/linkTraversalRetriever.test.js +0 -257
  110. package/dist/test/unit/retrieve/linkTraversalRetriever.test.js.map +0 -1
  111. package/dist/test/unit/retrieve/retrievers.test.js +0 -768
  112. package/dist/test/unit/retrieve/retrievers.test.js.map +0 -1
  113. package/dist/test/unit/retrieve/temporalRetrievers.test.js +0 -182
  114. package/dist/test/unit/retrieve/temporalRetrievers.test.js.map +0 -1
  115. package/dist/test/unit/store/antagonistTemporalBoundary.test.js +0 -120
  116. package/dist/test/unit/store/antagonistTemporalBoundary.test.js.map +0 -1
  117. package/dist/test/unit/store/embedOnWrite.test.js +0 -317
  118. package/dist/test/unit/store/embedOnWrite.test.js.map +0 -1
  119. package/dist/test/unit/store/fileTreeMemoryStore.test.js +0 -778
  120. package/dist/test/unit/store/fileTreeMemoryStore.test.js.map +0 -1
  121. package/dist/test/unit/store/fragmentEmbedOnWrite.test.js +0 -255
  122. package/dist/test/unit/store/fragmentEmbedOnWrite.test.js.map +0 -1
  123. package/dist/test/unit/store/indexInjection.test.js +0 -432
  124. package/dist/test/unit/store/indexInjection.test.js.map +0 -1
  125. package/dist/test/unit/store/lenientOpen.test.js +0 -248
  126. package/dist/test/unit/store/lenientOpen.test.js.map +0 -1
  127. package/dist/test/unit/store/listScoped.test.js +0 -109
  128. package/dist/test/unit/store/listScoped.test.js.map +0 -1
  129. package/dist/test/unit/store/observations.test.js +0 -239
  130. package/dist/test/unit/store/observations.test.js.map +0 -1
  131. package/dist/test/unit/store/rankAxis.test.js +0 -254
  132. package/dist/test/unit/store/rankAxis.test.js.map +0 -1
  133. package/dist/test/unit/store/scopeEncoding.test.js +0 -24
  134. package/dist/test/unit/store/scopeEncoding.test.js.map +0 -1
  135. package/dist/test/unit/store/temporalStore.test.js +0 -398
  136. package/dist/test/unit/store/temporalStore.test.js.map +0 -1
  137. package/dist/test/unit/tools/memoryTools.test.js +0 -842
  138. package/dist/test/unit/tools/memoryTools.test.js.map +0 -1
  139. package/dist/test/unit/types/identityCodec.test.js +0 -187
  140. package/dist/test/unit/types/identityCodec.test.js.map +0 -1
  141. package/dist/test/unit/types/ids.test.js +0 -84
  142. package/dist/test/unit/types/ids.test.js.map +0 -1
  143. package/dist/test/unit/types/temporalCodec.test.js +0 -203
  144. package/dist/test/unit/types/temporalCodec.test.js.map +0 -1
  145. package/dist/test/unit/types/temporalPolicy.test.js +0 -83
  146. package/dist/test/unit/types/temporalPolicy.test.js.map +0 -1
  147. package/dist/test/unit/types/writePolicy.test.js +0 -331
  148. package/dist/test/unit/types/writePolicy.test.js.map +0 -1
  149. package/dist/test/unit/vector/fragmentConverters.test.js +0 -58
  150. package/dist/test/unit/vector/fragmentConverters.test.js.map +0 -1
  151. package/dist/test/unit/vector/inMemoryCosineIndex.test.js +0 -252
  152. package/dist/test/unit/vector/inMemoryCosineIndex.test.js.map +0 -1
  153. package/dist/test/unit/vector/inMemoryFragmentCosineIndex.test.js +0 -362
  154. package/dist/test/unit/vector/inMemoryFragmentCosineIndex.test.js.map +0 -1
  155. package/dist/test/unit/vector/vectorIndex.test.js +0 -51
  156. package/dist/test/unit/vector/vectorIndex.test.js.map +0 -1
  157. package/eslint.config.js +0 -15
  158. package/etc/ts-agent-memory.api.md +0 -940
  159. package/lib/test/unit/converters/antagonistRoundTrip.test.d.ts +0 -10
  160. package/lib/test/unit/converters/antagonistRoundTrip.test.d.ts.map +0 -1
  161. package/lib/test/unit/converters/antagonistRoundTrip.test.js +0 -97
  162. package/lib/test/unit/converters/antagonistRoundTrip.test.js.map +0 -1
  163. package/lib/test/unit/converters/bodyConverterRegistry.test.d.ts +0 -2
  164. package/lib/test/unit/converters/bodyConverterRegistry.test.d.ts.map +0 -1
  165. package/lib/test/unit/converters/bodyConverterRegistry.test.js +0 -74
  166. package/lib/test/unit/converters/bodyConverterRegistry.test.js.map +0 -1
  167. package/lib/test/unit/converters/envelopeConverter.test.d.ts +0 -2
  168. package/lib/test/unit/converters/envelopeConverter.test.d.ts.map +0 -1
  169. package/lib/test/unit/converters/envelopeConverter.test.js +0 -315
  170. package/lib/test/unit/converters/envelopeConverter.test.js.map +0 -1
  171. package/lib/test/unit/index/memoryIndex.test.d.ts +0 -2
  172. package/lib/test/unit/index/memoryIndex.test.d.ts.map +0 -1
  173. package/lib/test/unit/index/memoryIndex.test.js +0 -216
  174. package/lib/test/unit/index/memoryIndex.test.js.map +0 -1
  175. package/lib/test/unit/ingest/antagonistCycleAndParity.test.d.ts +0 -9
  176. package/lib/test/unit/ingest/antagonistCycleAndParity.test.d.ts.map +0 -1
  177. package/lib/test/unit/ingest/antagonistCycleAndParity.test.js +0 -279
  178. package/lib/test/unit/ingest/antagonistCycleAndParity.test.js.map +0 -1
  179. package/lib/test/unit/ingest/cycleGuard.test.d.ts +0 -2
  180. package/lib/test/unit/ingest/cycleGuard.test.d.ts.map +0 -1
  181. package/lib/test/unit/ingest/cycleGuard.test.js +0 -83
  182. package/lib/test/unit/ingest/cycleGuard.test.js.map +0 -1
  183. package/lib/test/unit/ingest/dedupScope.test.d.ts +0 -2
  184. package/lib/test/unit/ingest/dedupScope.test.d.ts.map +0 -1
  185. package/lib/test/unit/ingest/dedupScope.test.js +0 -436
  186. package/lib/test/unit/ingest/dedupScope.test.js.map +0 -1
  187. package/lib/test/unit/ingest/orchestrator.test.d.ts +0 -2
  188. package/lib/test/unit/ingest/orchestrator.test.d.ts.map +0 -1
  189. package/lib/test/unit/ingest/orchestrator.test.js +0 -1060
  190. package/lib/test/unit/ingest/orchestrator.test.js.map +0 -1
  191. package/lib/test/unit/observe/memoryObservationStore.test.d.ts +0 -2
  192. package/lib/test/unit/observe/memoryObservationStore.test.d.ts.map +0 -1
  193. package/lib/test/unit/observe/memoryObservationStore.test.js +0 -120
  194. package/lib/test/unit/observe/memoryObservationStore.test.js.map +0 -1
  195. package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.d.ts +0 -2
  196. package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.d.ts.map +0 -1
  197. package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.js +0 -118
  198. package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.js.map +0 -1
  199. package/lib/test/unit/retrieve/linkTraversalRetriever.test.d.ts +0 -2
  200. package/lib/test/unit/retrieve/linkTraversalRetriever.test.d.ts.map +0 -1
  201. package/lib/test/unit/retrieve/linkTraversalRetriever.test.js +0 -259
  202. package/lib/test/unit/retrieve/linkTraversalRetriever.test.js.map +0 -1
  203. package/lib/test/unit/retrieve/retrievers.test.d.ts +0 -2
  204. package/lib/test/unit/retrieve/retrievers.test.d.ts.map +0 -1
  205. package/lib/test/unit/retrieve/retrievers.test.js +0 -770
  206. package/lib/test/unit/retrieve/retrievers.test.js.map +0 -1
  207. package/lib/test/unit/retrieve/temporalRetrievers.test.d.ts +0 -2
  208. package/lib/test/unit/retrieve/temporalRetrievers.test.d.ts.map +0 -1
  209. package/lib/test/unit/retrieve/temporalRetrievers.test.js +0 -184
  210. package/lib/test/unit/retrieve/temporalRetrievers.test.js.map +0 -1
  211. package/lib/test/unit/store/antagonistTemporalBoundary.test.d.ts +0 -9
  212. package/lib/test/unit/store/antagonistTemporalBoundary.test.d.ts.map +0 -1
  213. package/lib/test/unit/store/antagonistTemporalBoundary.test.js +0 -122
  214. package/lib/test/unit/store/antagonistTemporalBoundary.test.js.map +0 -1
  215. package/lib/test/unit/store/embedOnWrite.test.d.ts +0 -2
  216. package/lib/test/unit/store/embedOnWrite.test.d.ts.map +0 -1
  217. package/lib/test/unit/store/embedOnWrite.test.js +0 -319
  218. package/lib/test/unit/store/embedOnWrite.test.js.map +0 -1
  219. package/lib/test/unit/store/fileTreeMemoryStore.test.d.ts +0 -2
  220. package/lib/test/unit/store/fileTreeMemoryStore.test.d.ts.map +0 -1
  221. package/lib/test/unit/store/fileTreeMemoryStore.test.js +0 -780
  222. package/lib/test/unit/store/fileTreeMemoryStore.test.js.map +0 -1
  223. package/lib/test/unit/store/fragmentEmbedOnWrite.test.d.ts +0 -2
  224. package/lib/test/unit/store/fragmentEmbedOnWrite.test.d.ts.map +0 -1
  225. package/lib/test/unit/store/fragmentEmbedOnWrite.test.js +0 -257
  226. package/lib/test/unit/store/fragmentEmbedOnWrite.test.js.map +0 -1
  227. package/lib/test/unit/store/indexInjection.test.d.ts +0 -2
  228. package/lib/test/unit/store/indexInjection.test.d.ts.map +0 -1
  229. package/lib/test/unit/store/indexInjection.test.js +0 -434
  230. package/lib/test/unit/store/indexInjection.test.js.map +0 -1
  231. package/lib/test/unit/store/lenientOpen.test.d.ts +0 -2
  232. package/lib/test/unit/store/lenientOpen.test.d.ts.map +0 -1
  233. package/lib/test/unit/store/lenientOpen.test.js +0 -250
  234. package/lib/test/unit/store/lenientOpen.test.js.map +0 -1
  235. package/lib/test/unit/store/listScoped.test.d.ts +0 -2
  236. package/lib/test/unit/store/listScoped.test.d.ts.map +0 -1
  237. package/lib/test/unit/store/listScoped.test.js +0 -111
  238. package/lib/test/unit/store/listScoped.test.js.map +0 -1
  239. package/lib/test/unit/store/observations.test.d.ts +0 -2
  240. package/lib/test/unit/store/observations.test.d.ts.map +0 -1
  241. package/lib/test/unit/store/observations.test.js +0 -241
  242. package/lib/test/unit/store/observations.test.js.map +0 -1
  243. package/lib/test/unit/store/rankAxis.test.d.ts +0 -2
  244. package/lib/test/unit/store/rankAxis.test.d.ts.map +0 -1
  245. package/lib/test/unit/store/rankAxis.test.js +0 -256
  246. package/lib/test/unit/store/rankAxis.test.js.map +0 -1
  247. package/lib/test/unit/store/scopeEncoding.test.d.ts +0 -2
  248. package/lib/test/unit/store/scopeEncoding.test.d.ts.map +0 -1
  249. package/lib/test/unit/store/scopeEncoding.test.js +0 -26
  250. package/lib/test/unit/store/scopeEncoding.test.js.map +0 -1
  251. package/lib/test/unit/store/temporalStore.test.d.ts +0 -2
  252. package/lib/test/unit/store/temporalStore.test.d.ts.map +0 -1
  253. package/lib/test/unit/store/temporalStore.test.js +0 -400
  254. package/lib/test/unit/store/temporalStore.test.js.map +0 -1
  255. package/lib/test/unit/tools/memoryTools.test.d.ts +0 -2
  256. package/lib/test/unit/tools/memoryTools.test.d.ts.map +0 -1
  257. package/lib/test/unit/tools/memoryTools.test.js +0 -844
  258. package/lib/test/unit/tools/memoryTools.test.js.map +0 -1
  259. package/lib/test/unit/types/identityCodec.test.d.ts +0 -2
  260. package/lib/test/unit/types/identityCodec.test.d.ts.map +0 -1
  261. package/lib/test/unit/types/identityCodec.test.js +0 -189
  262. package/lib/test/unit/types/identityCodec.test.js.map +0 -1
  263. package/lib/test/unit/types/ids.test.d.ts +0 -2
  264. package/lib/test/unit/types/ids.test.d.ts.map +0 -1
  265. package/lib/test/unit/types/ids.test.js +0 -86
  266. package/lib/test/unit/types/ids.test.js.map +0 -1
  267. package/lib/test/unit/types/temporalCodec.test.d.ts +0 -2
  268. package/lib/test/unit/types/temporalCodec.test.d.ts.map +0 -1
  269. package/lib/test/unit/types/temporalCodec.test.js +0 -205
  270. package/lib/test/unit/types/temporalCodec.test.js.map +0 -1
  271. package/lib/test/unit/types/temporalPolicy.test.d.ts +0 -2
  272. package/lib/test/unit/types/temporalPolicy.test.d.ts.map +0 -1
  273. package/lib/test/unit/types/temporalPolicy.test.js +0 -85
  274. package/lib/test/unit/types/temporalPolicy.test.js.map +0 -1
  275. package/lib/test/unit/types/writePolicy.test.d.ts +0 -2
  276. package/lib/test/unit/types/writePolicy.test.d.ts.map +0 -1
  277. package/lib/test/unit/types/writePolicy.test.js +0 -333
  278. package/lib/test/unit/types/writePolicy.test.js.map +0 -1
  279. package/lib/test/unit/vector/fragmentConverters.test.d.ts +0 -2
  280. package/lib/test/unit/vector/fragmentConverters.test.d.ts.map +0 -1
  281. package/lib/test/unit/vector/fragmentConverters.test.js +0 -60
  282. package/lib/test/unit/vector/fragmentConverters.test.js.map +0 -1
  283. package/lib/test/unit/vector/inMemoryCosineIndex.test.d.ts +0 -2
  284. package/lib/test/unit/vector/inMemoryCosineIndex.test.d.ts.map +0 -1
  285. package/lib/test/unit/vector/inMemoryCosineIndex.test.js +0 -254
  286. package/lib/test/unit/vector/inMemoryCosineIndex.test.js.map +0 -1
  287. package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.d.ts +0 -2
  288. package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.d.ts.map +0 -1
  289. package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.js +0 -364
  290. package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.js.map +0 -1
  291. package/lib/test/unit/vector/vectorIndex.test.d.ts +0 -2
  292. package/lib/test/unit/vector/vectorIndex.test.d.ts.map +0 -1
  293. package/lib/test/unit/vector/vectorIndex.test.js +0 -53
  294. package/lib/test/unit/vector/vectorIndex.test.js.map +0 -1
  295. package/rush-logs/ts-agent-memory.build.cache.log +0 -3
  296. package/rush-logs/ts-agent-memory.build.log +0 -9
  297. package/src/index.ts +0 -14
  298. package/src/packlets/converters/bodyConverterRegistry.ts +0 -105
  299. package/src/packlets/converters/envelopeConverter.ts +0 -233
  300. package/src/packlets/converters/index.ts +0 -7
  301. package/src/packlets/index/index.ts +0 -6
  302. package/src/packlets/index/memoryIndex.ts +0 -332
  303. package/src/packlets/ingest/cycleGuard.ts +0 -153
  304. package/src/packlets/ingest/hostStages.ts +0 -111
  305. package/src/packlets/ingest/index.ts +0 -9
  306. package/src/packlets/ingest/model.ts +0 -195
  307. package/src/packlets/ingest/orchestrator.ts +0 -968
  308. package/src/packlets/observe/index.ts +0 -7
  309. package/src/packlets/observe/memoryObservationStore.ts +0 -153
  310. package/src/packlets/observe/observer.ts +0 -119
  311. package/src/packlets/retrieve/fragmentSemanticRetriever.ts +0 -138
  312. package/src/packlets/retrieve/hybridRetriever.ts +0 -194
  313. package/src/packlets/retrieve/index.ts +0 -14
  314. package/src/packlets/retrieve/linkTraversalRetriever.ts +0 -158
  315. package/src/packlets/retrieve/recencyRetriever.ts +0 -54
  316. package/src/packlets/retrieve/retriever.ts +0 -291
  317. package/src/packlets/retrieve/semanticRetriever.ts +0 -152
  318. package/src/packlets/retrieve/structuredFilterRetriever.ts +0 -58
  319. package/src/packlets/retrieve/tagRetriever.ts +0 -58
  320. package/src/packlets/retrieve/temporalRetrievers.ts +0 -210
  321. package/src/packlets/store/fileTreeMemoryStore.ts +0 -1872
  322. package/src/packlets/store/index.ts +0 -7
  323. package/src/packlets/store/scopeEncoding.ts +0 -36
  324. package/src/packlets/tools/index.ts +0 -6
  325. package/src/packlets/tools/memoryTools.ts +0 -706
  326. package/src/packlets/types/envelope.ts +0 -196
  327. package/src/packlets/types/filenameSafety.ts +0 -57
  328. package/src/packlets/types/identityCodec.ts +0 -447
  329. package/src/packlets/types/ids.ts +0 -124
  330. package/src/packlets/types/index.ts +0 -11
  331. package/src/packlets/types/temporal.ts +0 -96
  332. package/src/packlets/types/writePolicy.ts +0 -612
  333. package/src/packlets/vector/fragmentConverters.ts +0 -55
  334. package/src/packlets/vector/inMemoryCosineIndex.ts +0 -196
  335. package/src/packlets/vector/inMemoryFragmentCosineIndex.ts +0 -289
  336. package/src/packlets/vector/index.ts +0 -9
  337. package/src/packlets/vector/vectorIndex.ts +0 -273
  338. package/src/test/unit/converters/antagonistRoundTrip.test.ts +0 -110
  339. package/src/test/unit/converters/bodyConverterRegistry.test.ts +0 -89
  340. package/src/test/unit/converters/envelopeConverter.test.ts +0 -418
  341. package/src/test/unit/index/memoryIndex.test.ts +0 -272
  342. package/src/test/unit/ingest/antagonistCycleAndParity.test.ts +0 -367
  343. package/src/test/unit/ingest/cycleGuard.test.ts +0 -110
  344. package/src/test/unit/ingest/dedupScope.test.ts +0 -542
  345. package/src/test/unit/ingest/orchestrator.test.ts +0 -1355
  346. package/src/test/unit/observe/memoryObservationStore.test.ts +0 -158
  347. package/src/test/unit/retrieve/fragmentSemanticRetriever.test.ts +0 -163
  348. package/src/test/unit/retrieve/linkTraversalRetriever.test.ts +0 -329
  349. package/src/test/unit/retrieve/retrievers.test.ts +0 -1018
  350. package/src/test/unit/retrieve/temporalRetrievers.test.ts +0 -226
  351. package/src/test/unit/store/antagonistTemporalBoundary.test.ts +0 -158
  352. package/src/test/unit/store/embedOnWrite.test.ts +0 -418
  353. package/src/test/unit/store/fileTreeMemoryStore.test.ts +0 -1041
  354. package/src/test/unit/store/fragmentEmbedOnWrite.test.ts +0 -349
  355. package/src/test/unit/store/indexInjection.test.ts +0 -550
  356. package/src/test/unit/store/lenientOpen.test.ts +0 -292
  357. package/src/test/unit/store/listScoped.test.ts +0 -138
  358. package/src/test/unit/store/observations.test.ts +0 -290
  359. package/src/test/unit/store/rankAxis.test.ts +0 -349
  360. package/src/test/unit/store/scopeEncoding.test.ts +0 -37
  361. package/src/test/unit/store/temporalStore.test.ts +0 -469
  362. package/src/test/unit/tools/memoryTools.test.ts +0 -1121
  363. package/src/test/unit/types/identityCodec.test.ts +0 -266
  364. package/src/test/unit/types/ids.test.ts +0 -94
  365. package/src/test/unit/types/temporalCodec.test.ts +0 -259
  366. package/src/test/unit/types/temporalPolicy.test.ts +0 -124
  367. package/src/test/unit/types/writePolicy.test.ts +0 -446
  368. package/src/test/unit/vector/fragmentConverters.test.ts +0 -80
  369. package/src/test/unit/vector/inMemoryCosineIndex.test.ts +0 -318
  370. package/src/test/unit/vector/inMemoryFragmentCosineIndex.test.ts +0 -477
  371. package/src/test/unit/vector/vectorIndex.test.ts +0 -64
  372. package/temp/build/lint/_eslint-5eVG3S6w.json +0 -306
  373. package/temp/build/typescript/ts_8nwakTlr.json +0 -1
  374. package/temp/ts-agent-memory.api.json +0 -21030
  375. package/temp/ts-agent-memory.api.md +0 -940
  376. package/tsconfig.json +0 -8
@@ -1,7 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Erik Fortune
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- export * from './observer';
7
- export * from './memoryObservationStore';
@@ -1,153 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Erik Fortune
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- import { Collections, Result, fail, succeed } from '@fgv/ts-utils';
7
- import { IMemoryObservationQuery, IMemoryObservationRecord, IMemoryObserver } from './observer';
8
-
9
- /**
10
- * Construction options for {@link MemoryObservationStore.create}.
11
- * @public
12
- */
13
- export interface IMemoryObservationStoreCreateParams {
14
- /**
15
- * Maximum number of observation records retained before the oldest is
16
- * overwritten. Defaults to `1000`. Must be a positive integer if supplied.
17
- */
18
- readonly maxRecords?: number;
19
- }
20
-
21
- /**
22
- * The default in-memory observation store: an {@link IMemoryObserver} that
23
- * retains the records it observes in a bounded ring and answers schema-aware
24
- * {@link MemoryObservationStore.query | queries} over them.
25
- *
26
- * @remarks
27
- * **Privacy posture — this store is most-permissive by design.** It retains
28
- * every field of every record verbatim, including any `provenance` and
29
- * `querySnapshot`. The library bakes in **no** redaction, retention, or
30
- * field-stripping policy — that is deployment policy, not library policy. A
31
- * deployment that must redact wraps this store with its own
32
- * {@link IMemoryObserver} that transforms records before forwarding, or
33
- * substitutes a different observer entirely. Size is the only bounded
34
- * dimension, via `maxRecords`.
35
- *
36
- * The store composes `RetainingRingBuffer` from `@fgv/ts-utils` (it does not
37
- * hand-roll a ring) and implements {@link IMemoryObserver} directly — `observe`
38
- * (the hook) and `query` (the read surface) live on the same class. Wire it via
39
- * {@link IFileTreeMemoryStoreCreateParams.observers}. `seq` and `timestamp` are
40
- * assigned by the firing authority (the store) before `observe`, so this store
41
- * never mints them.
42
- * @public
43
- */
44
- export class MemoryObservationStore implements IMemoryObserver {
45
- /**
46
- * The bounded ring of observed records. The firing authority assigns each
47
- * record's `seq`, so the ring's monotonic-`seq` cursor contract is satisfied
48
- * by that authority's per-instance counter.
49
- * @internal
50
- */
51
- private readonly _buffer: Collections.RetainingRingBuffer<IMemoryObservationRecord>;
52
-
53
- /**
54
- * @param buffer - The pre-constructed backing ring buffer.
55
- * @internal
56
- */
57
- private constructor(buffer: Collections.RetainingRingBuffer<IMemoryObservationRecord>) {
58
- this._buffer = buffer;
59
- }
60
-
61
- /**
62
- * The highest `seq` observed so far. Hold this value and pass it as
63
- * `sinceSeq` to {@link MemoryObservationStore.query | query} to page only
64
- * records observed afterward. Stable across ring eviction and
65
- * {@link MemoryObservationStore.clear | clear}.
66
- */
67
- public get lastSeq(): number {
68
- return this._buffer.lastSeq;
69
- }
70
-
71
- /**
72
- * The number of records currently retained.
73
- */
74
- public get size(): number {
75
- return this._buffer.size;
76
- }
77
-
78
- /**
79
- * Family-convention factory.
80
- * @param params - {@link IMemoryObservationStoreCreateParams | Construction options}.
81
- * @returns On success, a new store. Fails if `maxRecords` is supplied and is
82
- * not a positive integer.
83
- */
84
- public static create(params?: IMemoryObservationStoreCreateParams): Result<MemoryObservationStore> {
85
- const maxRecords: number | undefined = params?.maxRecords;
86
- if (maxRecords !== undefined && (!Number.isInteger(maxRecords) || maxRecords < 1)) {
87
- return fail(`MemoryObservationStore: maxRecords must be a positive integer (got ${maxRecords})`);
88
- }
89
- return succeed(
90
- new MemoryObservationStore(
91
- new Collections.RetainingRingBuffer<IMemoryObservationRecord>({ maxRecords })
92
- )
93
- );
94
- }
95
-
96
- /**
97
- * {@inheritDoc IMemoryObserver.observe}
98
- */
99
- public observe(record: IMemoryObservationRecord): Promise<Result<unknown>> {
100
- this._buffer.push(record);
101
- return Promise.resolve(succeed(record));
102
- }
103
-
104
- /**
105
- * Returns retained records, oldest-first, narrowed by the supplied criteria.
106
- * @param criteria - {@link IMemoryObservationQuery | AND-combined filter criteria}.
107
- * @returns The matching records, oldest-first.
108
- */
109
- public query(criteria?: IMemoryObservationQuery): ReadonlyArray<IMemoryObservationRecord> {
110
- return this._buffer.query({
111
- sinceSeq: criteria?.sinceSeq,
112
- limit: criteria?.limit,
113
- filter:
114
- criteria === undefined ? undefined : (record) => MemoryObservationStore._matches(record, criteria)
115
- });
116
- }
117
-
118
- /**
119
- * Clears all retained records. Does NOT reset
120
- * {@link MemoryObservationStore.lastSeq | lastSeq}, so a held `sinceSeq`
121
- * cursor never re-sees a sequence number.
122
- */
123
- public clear(): void {
124
- this._buffer.clear();
125
- }
126
-
127
- /**
128
- * Tests a record against the non-`seq`/`limit` criteria (those are applied by
129
- * the ring buffer itself).
130
- * @internal
131
- */
132
- private static _matches(record: IMemoryObservationRecord, criteria: IMemoryObservationQuery): boolean {
133
- if (criteria.since !== undefined && record.timestamp < criteria.since) {
134
- return false;
135
- }
136
- if (criteria.until !== undefined && record.timestamp > criteria.until) {
137
- return false;
138
- }
139
- if (criteria.scope !== undefined && record.scope !== criteria.scope) {
140
- return false;
141
- }
142
- if (criteria.kind !== undefined && record.kind !== criteria.kind) {
143
- return false;
144
- }
145
- if (criteria.phase !== undefined && record.phase !== criteria.phase) {
146
- return false;
147
- }
148
- if (criteria.outcome !== undefined && record.outcome !== criteria.outcome) {
149
- return false;
150
- }
151
- return true;
152
- }
153
- }
@@ -1,119 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Erik Fortune
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- import { Result } from '@fgv/ts-utils';
7
- import { IProvenance, Kind, MemoryId, MemoryScopeKey } from '../types';
8
-
9
- /**
10
- * The store/retriever operation an observation record describes.
11
- *
12
- * @remarks
13
- * `'read'` / `'write'` / `'delete'` are fired post-op by
14
- * {@link FileTreeMemoryStore} (on `get` / `put` / `delete` respectively) when
15
- * observers are wired. `'retrieve'` is reserved for retriever-fired
16
- * observations; no B2 retriever fires one (a single seq authority per
17
- * observation store is the supported topology), so it never appears in B2 but
18
- * is part of the vocabulary so a future retriever-firing hook is additive.
19
- * @public
20
- */
21
- export type MemoryObservationPhase = 'read' | 'write' | 'delete' | 'retrieve';
22
-
23
- /**
24
- * The outcome of the observed operation.
25
- * @public
26
- */
27
- export type MemoryObservationOutcome = 'success' | 'failure';
28
-
29
- /**
30
- * A single audit record produced by an observed store (or retriever) operation.
31
- *
32
- * @remarks
33
- * `seq` and `timestamp` are assigned by the firing authority (the store) before
34
- * fan-out, so the same record carries the same `seq` across every observer it
35
- * lands in. `seq` is strictly increasing per authority, satisfying the
36
- * `RetainingRingBuffer` cursor contract that {@link MemoryObservationStore}
37
- * relies on.
38
- * @public
39
- */
40
- export interface IMemoryObservationRecord {
41
- /**
42
- * Monotonic 1-based sequence number assigned by the firing authority, stable
43
- * across a store's ring eviction. The ordering / paging key.
44
- */
45
- readonly seq: number;
46
- /** Milliseconds since epoch when the firing authority produced the record. */
47
- readonly timestamp: number;
48
- /** Which operation this record describes. */
49
- readonly phase: MemoryObservationPhase;
50
- /** The scope the operation touched, when resolvable. */
51
- readonly scope?: MemoryScopeKey;
52
- /** The record id the operation touched, when resolvable. */
53
- readonly id?: MemoryId;
54
- /** The kind the operation targeted, when known. */
55
- readonly kind?: Kind;
56
- /** Whether the operation succeeded. */
57
- readonly outcome: MemoryObservationOutcome;
58
- /** Present on failure: the failure `Result`'s message. */
59
- readonly error?: string;
60
- /** Structured provenance of the write, when the operation carried one. */
61
- readonly provenance?: IProvenance;
62
- /**
63
- * For `'retrieve'` observations: an opaque snapshot of the query that drove
64
- * the retrieval. Carried verbatim; never interpreted by the store.
65
- */
66
- readonly querySnapshot?: Readonly<Record<string, unknown>>;
67
- }
68
-
69
- /**
70
- * Single-method async observer hook. The store fires `observe` once per public
71
- * `get` / `put` / `delete` call when observers are wired.
72
- *
73
- * @remarks
74
- * Observer errors never affect the store operation — the store swallows a
75
- * failed `Result` or a thrown / rejected `observe`, logging it to the injected
76
- * diagnostic logger at `warn`.
77
- * @public
78
- */
79
- export interface IMemoryObserver {
80
- /**
81
- * When `true`, the store dispatches `observe` without awaiting it, so a slow
82
- * remote observer (SIEM, network sink) does not extend the store operation's
83
- * latency. Defaults to `false` (awaited), which is correct for the cheap
84
- * in-memory default {@link MemoryObservationStore}. Errors are swallowed
85
- * either way.
86
- */
87
- readonly fireAndForget?: boolean;
88
- /**
89
- * Receives a fully-formed observation record.
90
- * @param record - The observation record.
91
- * @returns A `Result` whose failure is swallowed (logged to the store's
92
- * diagnostic logger). A rejected promise is likewise swallowed.
93
- */
94
- observe(record: IMemoryObservationRecord): Promise<Result<unknown>>;
95
- }
96
-
97
- /**
98
- * Query criteria for {@link MemoryObservationStore.query}. All supplied criteria
99
- * are AND-combined.
100
- * @public
101
- */
102
- export interface IMemoryObservationQuery {
103
- /** Only records with `seq > sinceSeq` (incremental paging cursor). */
104
- readonly sinceSeq?: number;
105
- /** Return at most this many records — the most-recent N, still oldest-first. */
106
- readonly limit?: number;
107
- /** Only records with `timestamp >= since`. */
108
- readonly since?: number;
109
- /** Only records with `timestamp <= until`. */
110
- readonly until?: number;
111
- /** Only records that touched this scope. */
112
- readonly scope?: MemoryScopeKey;
113
- /** Only records that targeted this kind. */
114
- readonly kind?: Kind;
115
- /** Only records of this phase. */
116
- readonly phase?: MemoryObservationPhase;
117
- /** Only records with this outcome. */
118
- readonly outcome?: MemoryObservationOutcome;
119
- }
@@ -1,138 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Erik Fortune
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- import { Result, fail, succeed } from '@fgv/ts-utils';
7
- import { IFragmentVectorIndex, IVectorQueryHit } from '../vector';
8
- import { QueryEmbedder } from './semanticRetriever';
9
-
10
- /**
11
- * The loud-degradation message a {@link FragmentSemanticRetriever} returns when a
12
- * fragment query is issued but no {@link IFragmentSemanticBackend | backend} is
13
- * wired — the discovery surface NEVER answers a fragment query with a silent empty.
14
- * @public
15
- */
16
- export const FRAGMENT_SEMANTIC_UNWIRED_MESSAGE: string =
17
- 'fragment recall: no fragment index is wired; wire an IFragmentSemanticBackend to enable sub-document search';
18
-
19
- /**
20
- * The fragment backend wired into a {@link FragmentSemanticRetriever}: the fragment
21
- * index to query and the embedder that turns the query text into a vector. Both are
22
- * required together — a fragment index is useless without a way to embed the query.
23
- * @public
24
- */
25
- export interface IFragmentSemanticBackend {
26
- /** The fragment-granular vector index to query. */
27
- readonly fragmentIndex: IFragmentVectorIndex;
28
- /** Turns the query text into a vector. */
29
- readonly embedQuery: QueryEmbedder;
30
- }
31
-
32
- /**
33
- * A sub-document semantic-search request: the natural-language `semantic` text to
34
- * match, an optional `topK` result cap (default 10), and an optional
35
- * `maxPerRecord` cap that keeps one long document from monopolizing the result.
36
- * @public
37
- */
38
- export interface IFragmentQuery {
39
- /** The natural-language text to embed and match against stored fragments. */
40
- readonly semantic: string;
41
- /** Maximum number of fragment hits to return. Defaults to 10. */
42
- readonly topK?: number;
43
- /**
44
- * Maximum number of fragments any single record may contribute to the result.
45
- * Applied during selection (before the `topK` cut). Omit for uncapped.
46
- */
47
- readonly maxPerRecord?: number;
48
- }
49
-
50
- /**
51
- * What a {@link FragmentSemanticRetriever} can do given its wiring.
52
- * @public
53
- */
54
- export interface IFragmentRetrieverCapabilities {
55
- /** `true` when a fragment backend is wired and fragment recall is operational. */
56
- readonly supportsFragmentRecall: boolean;
57
- }
58
-
59
- /**
60
- * The sub-document semantic-search retriever — the "discovery" half of a
61
- * search-then-read contract. It embeds a fragment query, queries the
62
- * {@link IFragmentVectorIndex}, and returns the raw per-fragment
63
- * {@link IVectorQueryHit | hits} (each carrying a record `target` AND whichever of
64
- * `locator` / `fragmentId` the stored fragment was indexed with), NOT resolved
65
- * records: the consumer re-reads each record and resolves the fragment on its own
66
- * read side. Note the `locator` span is advisory — see {@link IFragmentLocator}; it
67
- * is not a slice guaranteed to reproduce the fragment's text.
68
- *
69
- * @remarks
70
- * Deliberately NOT an {@link IMemoryRetriever}: memory recall is record-granular and
71
- * returns records; fragment discovery is fragment-granular and returns fragment
72
- * identities. Keeping it a distinct surface matches the consumer contract (memory
73
- * stays record-granular; sub-document knowledge uses a separate fragment index) and
74
- * avoids overloading the record retriever's return type with identity fields that
75
- * only make sense here.
76
- *
77
- * When no backend is wired, `supportsFragmentRecall` is `false` and any fragment
78
- * query degrades loudly ({@link FRAGMENT_SEMANTIC_UNWIRED_MESSAGE}) — it NEVER
79
- * returns a silent empty. A consumer-supplied backend that rejects (throws) is
80
- * normalized into a `Failure`.
81
- * @public
82
- */
83
- export class FragmentSemanticRetriever {
84
- private readonly _backend: IFragmentSemanticBackend | undefined;
85
-
86
- private constructor(backend: IFragmentSemanticBackend | undefined) {
87
- this._backend = backend;
88
- }
89
-
90
- /** What this retriever can do given its wiring. */
91
- public get capabilities(): IFragmentRetrieverCapabilities {
92
- return { supportsFragmentRecall: this._backend !== undefined };
93
- }
94
-
95
- /** Family-convention factory. */
96
- public static create(params: {
97
- readonly backend?: IFragmentSemanticBackend;
98
- }): Result<FragmentSemanticRetriever> {
99
- return succeed(new FragmentSemanticRetriever(params.backend));
100
- }
101
-
102
- /**
103
- * Embed `query.semantic`, query the fragment index, and return the per-fragment
104
- * hits in descending score order. Fails loudly when no backend is wired.
105
- */
106
- public async retrieve(query: IFragmentQuery): Promise<Result<ReadonlyArray<IVectorQueryHit>>> {
107
- if (this._backend === undefined) {
108
- return fail(FRAGMENT_SEMANTIC_UNWIRED_MESSAGE);
109
- }
110
- const backend: IFragmentSemanticBackend = this._backend;
111
- // Consumer-supplied hooks may throw; normalize both a returned `fail` and a
112
- // rejection into a single `fragment recall: <label> failed` Failure so
113
- // `retrieve` always honors its `Promise<Result<...>>` contract.
114
- const embedded: Result<Float32Array> = await FragmentSemanticRetriever._callBackend(
115
- 'query embedding',
116
- () => backend.embedQuery(query.semantic)
117
- );
118
- if (embedded.isFailure()) {
119
- return fail(embedded.message);
120
- }
121
- return FragmentSemanticRetriever._callBackend('fragment query', () =>
122
- backend.fragmentIndex.query(embedded.value, query.topK ?? 10, query.maxPerRecord)
123
- );
124
- }
125
-
126
- /**
127
- * Invoke a consumer-supplied backend hook, normalizing both a returned `fail`
128
- * and a thrown/rejected promise into a single `fragment recall: <label> failed`
129
- * `Failure`.
130
- */
131
- private static async _callBackend<T>(label: string, op: () => Promise<Result<T>>): Promise<Result<T>> {
132
- try {
133
- return (await op()).withErrorFormat((msg) => `fragment recall: ${label} failed: ${msg}`);
134
- } catch (err) {
135
- return fail(`fragment recall: ${label} failed: ${String(err)}`);
136
- }
137
- }
138
- }
@@ -1,194 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Erik Fortune
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- import { Result, fail, mapResults, succeed } from '@fgv/ts-utils';
7
- import { IMemoryRecord, MemoryId } from '../types';
8
- import {
9
- IMemoryQuery,
10
- IMemoryRetriever,
11
- IMemoryRetrieverCapabilities,
12
- guardRetrieverCapabilities,
13
- limitRecords,
14
- rankCompare,
15
- recencyCompare
16
- } from './retriever';
17
-
18
- /**
19
- * Strategy for combining the result sets of the retrievers a
20
- * {@link HybridRetriever} composes. Injectable so a consumer can weight,
21
- * re-rank, or intersect instead of the default union.
22
- * @public
23
- */
24
- export interface IMergeStrategy {
25
- /**
26
- * Merge the per-retriever result sets into a single ordered result.
27
- * @param resultSets - One entry per composed retriever, in composition order.
28
- */
29
- merge(
30
- resultSets: ReadonlyArray<ReadonlyArray<IMemoryRecord<unknown>>>
31
- ): Result<ReadonlyArray<IMemoryRecord<unknown>>>;
32
- }
33
-
34
- /**
35
- * The reference {@link IMergeStrategy}: a score-union. Every record is scored by
36
- * the number of composed result sets it appears in (deduplicated by
37
- * {@link IMemoryEnvelope.id | id}); the merged result is ordered by descending
38
- * score, then by recency. Records surfaced by more retrievers rank higher.
39
- *
40
- * @remarks
41
- * Dedup is by `id` alone, which is unambiguous for the flat (one-file-per-entity)
42
- * kinds B2 ships. Phase-C versioned kinds that reuse a stem across scopes will
43
- * extend the dedup key — additive, no API change.
44
- * @public
45
- */
46
- export class ScoreUnionMergeStrategy implements IMergeStrategy {
47
- private constructor() {}
48
-
49
- /** Family-convention factory. */
50
- public static create(): Result<ScoreUnionMergeStrategy> {
51
- return succeed(new ScoreUnionMergeStrategy());
52
- }
53
-
54
- /** {@inheritDoc IMergeStrategy.merge} */
55
- public merge(
56
- resultSets: ReadonlyArray<ReadonlyArray<IMemoryRecord<unknown>>>
57
- ): Result<ReadonlyArray<IMemoryRecord<unknown>>> {
58
- const scored: Map<MemoryId, { readonly record: IMemoryRecord<unknown>; score: number }> = new Map();
59
- for (const set of resultSets) {
60
- // Count each id at most once per result set, so the score is "how many
61
- // retrievers surfaced this record" rather than "how many copies total".
62
- const seenInSet: Set<MemoryId> = new Set<MemoryId>();
63
- for (const record of set) {
64
- const id: MemoryId = record.envelope.id;
65
- if (seenInSet.has(id)) {
66
- continue;
67
- }
68
- seenInSet.add(id);
69
- const existing = scored.get(id);
70
- if (existing === undefined) {
71
- scored.set(id, { record, score: 1 });
72
- } else {
73
- existing.score += 1;
74
- }
75
- }
76
- }
77
- const merged: IMemoryRecord<unknown>[] = Array.from(scored.values())
78
- .sort((a, b) => (b.score !== a.score ? b.score - a.score : recencyCompare(a.record, b.record)))
79
- .map((entry) => entry.record);
80
- return succeed(merged);
81
- }
82
- }
83
-
84
- /**
85
- * Composes several retrievers, dispatches a query to each, and merges their
86
- * results via an injectable {@link IMergeStrategy}. Its capabilities are the
87
- * union of the composed retrievers' capabilities.
88
- *
89
- * @remarks
90
- * The hybrid enforces the loud-degradation contract against its OWN (union)
91
- * capabilities, then projects the query for each child: a child that does not
92
- * support the `semantic` (or `asOf`) axis is handed a query with that axis
93
- * stripped, so it returns its normal results instead of loud-failing on a field
94
- * a sibling handles. A child that genuinely fails (e.g. a wired semantic backend
95
- * erroring) propagates — the hybrid never silently drops a failure.
96
- * @public
97
- */
98
- export class HybridRetriever implements IMemoryRetriever {
99
- private readonly _retrievers: ReadonlyArray<IMemoryRetriever>;
100
- private readonly _mergeStrategy: IMergeStrategy;
101
- private readonly _capabilities: IMemoryRetrieverCapabilities;
102
-
103
- private constructor(
104
- retrievers: ReadonlyArray<IMemoryRetriever>,
105
- mergeStrategy: IMergeStrategy,
106
- capabilities: IMemoryRetrieverCapabilities
107
- ) {
108
- this._retrievers = retrievers;
109
- this._mergeStrategy = mergeStrategy;
110
- this._capabilities = capabilities;
111
- }
112
-
113
- /** {@inheritDoc IMemoryRetriever.capabilities} */
114
- public get capabilities(): IMemoryRetrieverCapabilities {
115
- return this._capabilities;
116
- }
117
-
118
- /**
119
- * Family-convention factory.
120
- * @param retrievers - The retrievers to compose (at least one).
121
- * @param mergeStrategy - How to combine their results.
122
- */
123
- public static create(
124
- retrievers: ReadonlyArray<IMemoryRetriever>,
125
- mergeStrategy: IMergeStrategy
126
- ): Result<HybridRetriever> {
127
- if (retrievers.length === 0) {
128
- return fail('HybridRetriever: at least one retriever is required');
129
- }
130
- // Snapshot the caller's array so a later mutation cannot make `retrieve()`
131
- // and the cached `capabilities` disagree.
132
- const stableRetrievers: ReadonlyArray<IMemoryRetriever> = [...retrievers];
133
- const capabilities: IMemoryRetrieverCapabilities = {
134
- supportsSemanticRecall: stableRetrievers.some((r) => r.capabilities.supportsSemanticRecall),
135
- supportsTemporalQuery: stableRetrievers.some((r) => r.capabilities.supportsTemporalQuery),
136
- supportsLinkTraversal: stableRetrievers.some((r) => r.capabilities.supportsLinkTraversal)
137
- };
138
- return succeed(new HybridRetriever(stableRetrievers, mergeStrategy, capabilities));
139
- }
140
-
141
- /** {@inheritDoc IMemoryRetriever.retrieve} */
142
- public async retrieve(query: IMemoryQuery): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>> {
143
- return guardRetrieverCapabilities(query, this._capabilities).thenOnSuccess(async () => {
144
- const perRetriever: Result<ReadonlyArray<IMemoryRecord<unknown>>>[] = await Promise.all(
145
- this._retrievers.map((retriever) => retriever.retrieve(this._projectQuery(query, retriever)))
146
- );
147
- return mapResults(perRetriever)
148
- .onSuccess((resultSets) => this._mergeStrategy.merge(resultSets))
149
- .onSuccess((merged) => {
150
- // `orderBy: 'rank'` re-orders the merged set by rank (descending, absent
151
- // last) before the page window, so a rank-ordered hybrid query yields a
152
- // rank-ordered page. Absent / `'recency'` preserves the merge strategy's
153
- // own ordering (byte-identical to the pre-`orderBy` behavior).
154
- const ordered: ReadonlyArray<IMemoryRecord<unknown>> =
155
- query.orderBy === 'rank' ? [...merged].sort(rankCompare) : merged;
156
- return succeed(limitRecords(ordered, query.limit, query.offset));
157
- });
158
- });
159
- }
160
-
161
- /**
162
- * Project the query for one child retriever. Two adjustments:
163
- *
164
- * - Strip axes the child does not support (`semantic` / `topK` for a
165
- * non-semantic child, `asOf` for a non-temporal child, the link axes for a
166
- * non-link child) so it returns its normal results rather than loud-failing
167
- * on a field a sibling handles.
168
- * - Strip `limit` unconditionally: limit is a post-merge concern. A child that
169
- * pre-truncated its result set would starve the merge strategy of candidates
170
- * it needs to score correctly (a record both children would surface must
171
- * reach the merge to score 2). The hybrid applies `limit` once, after merge.
172
- */
173
- private _projectQuery(query: IMemoryQuery, retriever: IMemoryRetriever): IMemoryQuery {
174
- const projected: { -readonly [K in keyof IMemoryQuery]: IMemoryQuery[K] } = { ...query };
175
- delete projected.limit;
176
- // Offset, like limit, is a post-merge concern: a child that pre-skipped its
177
- // own ordered set would drop candidates the merge needs to score correctly.
178
- // The hybrid applies the `{ offset, limit }` window once, after merge.
179
- delete projected.offset;
180
- if (!retriever.capabilities.supportsSemanticRecall) {
181
- delete projected.semantic;
182
- delete projected.topK;
183
- }
184
- if (!retriever.capabilities.supportsTemporalQuery) {
185
- delete projected.asOf;
186
- }
187
- if (!retriever.capabilities.supportsLinkTraversal) {
188
- delete projected.linkedFrom;
189
- delete projected.linkedTo;
190
- delete projected.hops;
191
- }
192
- return projected;
193
- }
194
- }
@@ -1,14 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Erik Fortune
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- export * from './retriever';
7
- export * from './recencyRetriever';
8
- export * from './linkTraversalRetriever';
9
- export * from './tagRetriever';
10
- export * from './structuredFilterRetriever';
11
- export * from './semanticRetriever';
12
- export * from './fragmentSemanticRetriever';
13
- export * from './temporalRetrievers';
14
- export * from './hybridRetriever';