@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,158 +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 { IEdgeTarget, IMemoryRecord, edgeTargetKey } from '../types';
8
- import { IIndexedMemoryRecord, IMemoryIndex } from '../index';
9
- import {
10
- IMemoryQuery,
11
- IMemoryRetriever,
12
- IMemoryRetrieverCapabilities,
13
- guardRetrieverCapabilities,
14
- indexedRecordMatchesQuery,
15
- limitRecords,
16
- orderingCompare
17
- } from './retriever';
18
-
19
- /** The capabilities a link-traversal retriever exposes (link traversal only). */
20
- const LINK_TRAVERSAL_CAPABILITIES: IMemoryRetrieverCapabilities = {
21
- supportsSemanticRecall: false,
22
- supportsTemporalQuery: false,
23
- supportsLinkTraversal: true
24
- };
25
-
26
- /** Default BFS hop count when `query.hops` is not supplied. */
27
- const DEFAULT_HOPS: number = 1;
28
-
29
- /**
30
- * The loud-degradation message returned when a link-traversal query supplies no
31
- * seed (`linkedFrom` / `linkedTo`).
32
- * @public
33
- */
34
- export const LINK_TRAVERSAL_NO_SEED_MESSAGE: string =
35
- 'link traversal requires a seed id (linkedFrom or linkedTo)';
36
-
37
- /**
38
- * Breadth-first link-traversal retriever. From a scope-qualified
39
- * {@link IEdgeTarget} seed it walks the link graph up to `query.hops` levels and
40
- * returns the records reached (excluding the seed), recency-ordered and limited.
41
- *
42
- * @remarks
43
- * - **Direction.** `linkedFrom` walks OUTBOUND edges (each record's
44
- * `envelope.links[].target`); `linkedTo` walks INBOUND edges (the index's
45
- * `backlinks`). Exactly one is the seed; `linkedFrom` wins if both are set.
46
- * - **Scope-qualified nodes.** Every graph node is an {@link IEdgeTarget}
47
- * `(scope, id)` pair, so following an edge to `turn-3` reaches ONLY the record
48
- * in the edge's own scope — never a same-stem record in another scope.
49
- * - **Bound + cycle safety.** Traversal is bounded by `hops` (default `1` — a
50
- * single hop) and a visited-set guard. Nodes are canonicalized to their
51
- * `(scope, id)` string via {@link edgeTargetKey}, so a `Set<string>` visited-set
52
- * is the exact, collision-free cycle key — no structural hashing (e.g.
53
- * `Crc32Normalizer`) is needed. A self-loop or any multi-hop cycle terminates
54
- * because a revisited node is never re-expanded.
55
- * - **Post-filter.** The scope / kind / tag / predicate axes of the query are
56
- * applied to the reached records (the link axes are the traversal itself).
57
- * @public
58
- */
59
- export class LinkTraversalRetriever implements IMemoryRetriever {
60
- private readonly _index: IMemoryIndex;
61
-
62
- private constructor(index: IMemoryIndex) {
63
- this._index = index;
64
- }
65
-
66
- /** Family-convention factory. */
67
- public static create(index: IMemoryIndex): Result<LinkTraversalRetriever> {
68
- return succeed(new LinkTraversalRetriever(index));
69
- }
70
-
71
- /** {@inheritDoc IMemoryRetriever.capabilities} */
72
- public get capabilities(): IMemoryRetrieverCapabilities {
73
- return LINK_TRAVERSAL_CAPABILITIES;
74
- }
75
-
76
- /** {@inheritDoc IMemoryRetriever.retrieve} */
77
- public retrieve(query: IMemoryQuery): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>> {
78
- return Promise.resolve(
79
- guardRetrieverCapabilities(query, this.capabilities).onSuccess(() => this._traverse(query))
80
- );
81
- }
82
-
83
- /** Run the bounded, cycle-safe BFS and post-filter the reached records. */
84
- private _traverse(query: IMemoryQuery): Result<ReadonlyArray<IMemoryRecord<unknown>>> {
85
- const outbound: boolean = query.linkedFrom !== undefined;
86
- const seed: IEdgeTarget | undefined = query.linkedFrom ?? query.linkedTo;
87
- if (seed === undefined) {
88
- return fail(LINK_TRAVERSAL_NO_SEED_MESSAGE);
89
- }
90
- const hops: number = query.hops ?? DEFAULT_HOPS;
91
- const byKey: ReadonlyMap<string, IIndexedMemoryRecord> = this._indexByKey();
92
-
93
- // The visited-set IS the cycle guard: nodes are canonicalized to their
94
- // `(scope, id)` string, so set membership is an exact identity check. The
95
- // seed is pre-marked so it is never re-added.
96
- const visited: Set<string> = new Set<string>([edgeTargetKey(seed)]);
97
- const reached: IEdgeTarget[] = [];
98
- let frontier: IEdgeTarget[] = [seed];
99
- for (let hop = 0; hop < hops && frontier.length > 0; hop++) {
100
- const next: IEdgeTarget[] = [];
101
- for (const node of frontier) {
102
- for (const neighbor of outbound ? this._outbound(node, byKey) : this._inbound(node)) {
103
- const neighborKey: string = edgeTargetKey(neighbor);
104
- if (!visited.has(neighborKey)) {
105
- visited.add(neighborKey);
106
- reached.push(neighbor);
107
- next.push(neighbor);
108
- }
109
- }
110
- }
111
- frontier = next;
112
- }
113
-
114
- const entries: IIndexedMemoryRecord[] = [];
115
- for (const node of reached) {
116
- const match: IIndexedMemoryRecord | undefined = byKey.get(edgeTargetKey(node));
117
- if (match !== undefined) {
118
- entries.push(match);
119
- }
120
- }
121
- const ordered: IMemoryRecord<unknown>[] = entries
122
- .filter((entry) => indexedRecordMatchesQuery(entry, query))
123
- .map((entry) => entry.record)
124
- .sort(orderingCompare(query.orderBy));
125
- return succeed(limitRecords(ordered, query.limit, query.offset));
126
- }
127
-
128
- /**
129
- * Group the index's entries by their scope-qualified {@link edgeTargetKey}
130
- * `(scope, id)` composite. Each composite is the index's primary key, so it maps
131
- * to exactly one entry — two records that reuse a filename stem across scopes
132
- * (e.g. `turn-0` in two conversations) get distinct keys and never collide.
133
- */
134
- private _indexByKey(): ReadonlyMap<string, IIndexedMemoryRecord> {
135
- const byKey: Map<string, IIndexedMemoryRecord> = new Map<string, IIndexedMemoryRecord>();
136
- for (const entry of this._index.entries()) {
137
- byKey.set(edgeTargetKey({ scope: entry.scope, id: entry.record.envelope.id }), entry);
138
- }
139
- return byKey;
140
- }
141
-
142
- /** Outbound neighbors: the scope-qualified targets of every edge on the record at `node`. */
143
- private _outbound(node: IEdgeTarget, byKey: ReadonlyMap<string, IIndexedMemoryRecord>): IEdgeTarget[] {
144
- const targets: IEdgeTarget[] = [];
145
- const match: IIndexedMemoryRecord | undefined = byKey.get(edgeTargetKey(node));
146
- if (match !== undefined) {
147
- for (const edge of match.record.envelope.links) {
148
- targets.push(edge.target);
149
- }
150
- }
151
- return targets;
152
- }
153
-
154
- /** Inbound neighbors: the scope-qualified sources whose edges point AT `node` (the backlinks). */
155
- private _inbound(node: IEdgeTarget): ReadonlyArray<IEdgeTarget> {
156
- return this._index.backlinks(node);
157
- }
158
- }
@@ -1,54 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Erik Fortune
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- import { Result, succeed } from '@fgv/ts-utils';
7
- import { IMemoryRecord } from '../types';
8
- import { IMemoryIndex } from '../index';
9
- import {
10
- IMemoryQuery,
11
- IMemoryRetriever,
12
- IMemoryRetrieverCapabilities,
13
- NON_SEMANTIC_CAPABILITIES,
14
- guardRetrieverCapabilities,
15
- limitRecords,
16
- orderingCompare,
17
- selectByQuery
18
- } from './retriever';
19
-
20
- /**
21
- * Returns records matching the query's scope / kind / tag / predicate filters,
22
- * ordered most-recently-updated first. The universal v1 retriever — an empty
23
- * query returns the whole vault in recency order.
24
- * @public
25
- */
26
- export class RecencyRetriever implements IMemoryRetriever {
27
- private readonly _index: IMemoryIndex;
28
-
29
- private constructor(index: IMemoryIndex) {
30
- this._index = index;
31
- }
32
-
33
- /** {@inheritDoc IMemoryRetriever.capabilities} */
34
- public get capabilities(): IMemoryRetrieverCapabilities {
35
- return NON_SEMANTIC_CAPABILITIES;
36
- }
37
-
38
- /** Family-convention factory. */
39
- public static create(index: IMemoryIndex): Result<RecencyRetriever> {
40
- return succeed(new RecencyRetriever(index));
41
- }
42
-
43
- /** {@inheritDoc IMemoryRetriever.retrieve} */
44
- public retrieve(query: IMemoryQuery): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>> {
45
- return Promise.resolve(
46
- guardRetrieverCapabilities(query, this.capabilities).onSuccess(() => {
47
- const ordered: IMemoryRecord<unknown>[] = selectByQuery(this._index.entries(), query).sort(
48
- orderingCompare(query.orderBy)
49
- );
50
- return succeed(limitRecords(ordered, query.limit, query.offset));
51
- })
52
- );
53
- }
54
- }
@@ -1,291 +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 { IEdgeTarget, IMemoryRecord, Kind, MemoryScopeKey, Tag } from '../types';
8
- import { IIndexedMemoryRecord } from '../index';
9
-
10
- /**
11
- * The capabilities a retriever exposes. A consumer probes these before
12
- * dispatching a query so it never silently gets an empty result for a
13
- * capability the retriever does not implement.
14
- * @public
15
- */
16
- export interface IMemoryRetrieverCapabilities {
17
- /** Semantic / vector recall is operational (an {@link IVectorIndex} is wired). */
18
- readonly supportsSemanticRecall: boolean;
19
- /** Temporal "as-of" queries are operational (a temporal index is wired). */
20
- readonly supportsTemporalQuery: boolean;
21
- /** Link traversal is supported (an in-memory backlink index is present). */
22
- readonly supportsLinkTraversal: boolean;
23
- }
24
-
25
- /**
26
- * A retrieval query. Every field is optional; an empty query is the "recency
27
- * over everything" request. `semantic` and `asOf` are present from day one (the
28
- * no-resignature guarantee): a backend that adds semantic or temporal recall
29
- * sets the matching capability flag, with no interface change.
30
- * @public
31
- */
32
- export interface IMemoryQuery {
33
- /** Restrict to records in this scope. */
34
- readonly scope?: MemoryScopeKey;
35
- /** Restrict to records carrying this tag (exact match). */
36
- readonly tag?: Tag;
37
- /**
38
- * Restrict to records of this kind — the single-kind shorthand for
39
- * {@link IMemoryQuery.kinds | kinds}. When both are set they compose as AND
40
- * (the record's kind must satisfy both), so `kind` must itself be a member of
41
- * `kinds` for anything to match.
42
- */
43
- readonly kind?: Kind;
44
- /**
45
- * Restrict to records in ANY of these kinds — the general (multi-kind) form of
46
- * {@link IMemoryQuery.kind | kind}. Absent → no kind-set constraint (today's
47
- * behavior). An explicit empty array `[]` matches NOTHING (mirroring the
48
- * non-positive-`limit` "explicit empty" convention), never "match all".
49
- */
50
- readonly kinds?: ReadonlyArray<Kind>;
51
- /** Restrict to records linked FROM this scope-qualified seed (outbound). */
52
- readonly linkedFrom?: IEdgeTarget;
53
- /** Restrict to records linked TO this scope-qualified seed (inbound / backlinks). */
54
- readonly linkedTo?: IEdgeTarget;
55
- /** BFS hop count for link traversal. Default: 1. */
56
- readonly hops?: number;
57
- /**
58
- * Text query for semantic / vector recall. If set and the retriever's
59
- * `supportsSemanticRecall` is `false`, the retriever returns a loud
60
- * `Result.fail` ({@link SEMANTIC_UNWIRED_MESSAGE}) — never a silent empty.
61
- */
62
- readonly semantic?: string;
63
- /** Top-K for semantic recall. Default: 10. */
64
- readonly topK?: number;
65
- /**
66
- * As-of epoch ms for temporal "valid at" queries. If set and the retriever's
67
- * `supportsTemporalQuery` is `false`, the retriever returns a loud
68
- * `Result.fail` — never a silent empty.
69
- */
70
- readonly asOf?: number;
71
- /**
72
- * Ordering for the result set. `'recency'` (the default when absent — today's
73
- * exact behavior) orders most-recently-updated first; `'rank'` orders by the
74
- * store-computed {@link IMemoryEnvelope.rank} descending (records with an absent
75
- * `rank` last), with recency as the tiebreak. Combined with `{ limit, offset }`
76
- * this yields a bounded top-M rank-ordered page with no full-vault scan.
77
- *
78
- * @remarks
79
- * `orderBy` governs the ordered non-semantic retrievers (recency / tag /
80
- * structured-filter / link-traversal) and the {@link HybridRetriever}'s
81
- * post-merge ordering. The {@link SemanticRetriever} is the sole exception: it
82
- * preserves its native vector-similarity order regardless of `orderBy` —
83
- * re-sorting semantic hits by `rank` would discard the similarity ranking that
84
- * is the whole point of that path; a consumer that wants rank ordering uses a
85
- * non-semantic query.
86
- */
87
- readonly orderBy?: 'recency' | 'rank';
88
- /** Maximum records to return. Applied after all other filters. */
89
- readonly limit?: number;
90
- /**
91
- * Records to skip after ordering, before `limit` — so `{ offset, limit }` is a
92
- * stable page window over the ordered result set. Default 0. A non-positive or
93
- * absent offset is today's behavior (no skip); an offset past the end yields an
94
- * empty page, never a throw.
95
- */
96
- readonly offset?: number;
97
- /** Arbitrary predicate applied after the scope / kind / tag pre-filter. */
98
- readonly filter?: (record: IMemoryRecord<unknown>) => boolean;
99
- }
100
-
101
- /**
102
- * The retrieval contract. A retriever exposes its {@link
103
- * IMemoryRetrieverCapabilities | capabilities} and answers
104
- * {@link IMemoryRetriever.retrieve | queries}, degrading loudly (never silently
105
- * empty) when a requested capability is not wired.
106
- * @public
107
- */
108
- export interface IMemoryRetriever {
109
- /** The capabilities this retriever exposes. Probe before dispatch. */
110
- readonly capabilities: IMemoryRetrieverCapabilities;
111
- /**
112
- * Retrieve records matching `query`. Returns a `Result.fail` with a
113
- * diagnostic message when the query requests a capability this retriever does
114
- * not support (never an empty success).
115
- */
116
- retrieve(query: IMemoryQuery): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>>;
117
- }
118
-
119
- /**
120
- * The loud-degradation message a retriever returns when `query.semantic` is set
121
- * but no {@link IVectorIndex} is wired.
122
- * @public
123
- */
124
- export const SEMANTIC_UNWIRED_MESSAGE: string = 'semantic recall requires a vector index; none configured';
125
-
126
- /**
127
- * The loud-degradation message a retriever returns when a link-traversal axis
128
- * (`linkedFrom` / `linkedTo` / `hops`) is requested but no backlink index is
129
- * wired.
130
- * @public
131
- */
132
- export const LINK_TRAVERSAL_UNWIRED_MESSAGE: string =
133
- 'link traversal requires a backlink index; none configured';
134
-
135
- /**
136
- * The capabilities every non-semantic, non-temporal, non-link v1 retriever
137
- * exposes (all three flags `false`).
138
- * @public
139
- */
140
- export const NON_SEMANTIC_CAPABILITIES: IMemoryRetrieverCapabilities = {
141
- supportsSemanticRecall: false,
142
- supportsTemporalQuery: false,
143
- supportsLinkTraversal: false
144
- };
145
-
146
- /**
147
- * Build the loud-degradation message a retriever returns when `query.asOf` is
148
- * set but no temporal index is wired.
149
- * @public
150
- */
151
- export function temporalUnwiredMessage(kind?: Kind): string {
152
- return `temporal query requires temporal index; none configured${
153
- kind !== undefined ? ` for kind ${kind}` : ''
154
- }`;
155
- }
156
-
157
- /**
158
- * Enforce the loud-degradation contract for the `semantic` and `asOf` axes
159
- * against a retriever's `capabilities`: a requested capability the retriever
160
- * does not support fails loudly rather than returning a silent empty result.
161
- * @public
162
- */
163
- export function guardRetrieverCapabilities(
164
- query: IMemoryQuery,
165
- capabilities: IMemoryRetrieverCapabilities
166
- ): Result<true> {
167
- if (query.semantic !== undefined && !capabilities.supportsSemanticRecall) {
168
- return fail(SEMANTIC_UNWIRED_MESSAGE);
169
- }
170
- if (query.asOf !== undefined && !capabilities.supportsTemporalQuery) {
171
- return fail(temporalUnwiredMessage(query.kind));
172
- }
173
- const requestsLinkTraversal: boolean =
174
- query.linkedFrom !== undefined || query.linkedTo !== undefined || query.hops !== undefined;
175
- if (requestsLinkTraversal && !capabilities.supportsLinkTraversal) {
176
- return fail(LINK_TRAVERSAL_UNWIRED_MESSAGE);
177
- }
178
- return succeed(true);
179
- }
180
-
181
- /**
182
- * Recency comparator: most-recently-updated first, with a `seq` tiebreak so
183
- * equal-`updated` records sort deterministically. Mirrors the B1 index ordering.
184
- * @public
185
- */
186
- export function recencyCompare(a: IMemoryRecord<unknown>, b: IMemoryRecord<unknown>): number {
187
- const byUpdated: number = b.envelope.updated - a.envelope.updated;
188
- return byUpdated !== 0 ? byUpdated : b.envelope.seq - a.envelope.seq;
189
- }
190
-
191
- /**
192
- * Rank comparator: store-computed {@link IMemoryEnvelope.rank} descending, with
193
- * {@link recencyCompare} as the tiebreak. Records with an absent `rank` sort LAST
194
- * (after every ranked record), then by recency among themselves. Mirrors the
195
- * index's rank-view ordering.
196
- * @public
197
- */
198
- export function rankCompare(a: IMemoryRecord<unknown>, b: IMemoryRecord<unknown>): number {
199
- const ra: number | undefined = a.envelope.rank;
200
- const rb: number | undefined = b.envelope.rank;
201
- if (ra === undefined && rb !== undefined) {
202
- return 1;
203
- }
204
- if (rb === undefined && ra !== undefined) {
205
- return -1;
206
- }
207
- if (ra !== undefined && rb !== undefined && ra !== rb) {
208
- return rb - ra;
209
- }
210
- return recencyCompare(a, b);
211
- }
212
-
213
- /**
214
- * Select the record comparator for a query's {@link IMemoryQuery.orderBy | orderBy}
215
- * axis: {@link rankCompare} for `'rank'`, {@link recencyCompare} otherwise (the
216
- * default, byte-identical to the pre-`orderBy` behavior).
217
- * @public
218
- */
219
- export function orderingCompare(
220
- orderBy?: IMemoryQuery['orderBy']
221
- ): (a: IMemoryRecord<unknown>, b: IMemoryRecord<unknown>) => number {
222
- return orderBy === 'rank' ? rankCompare : recencyCompare;
223
- }
224
-
225
- /**
226
- * Whether an indexed entry satisfies a query's scope / kind / tag / predicate
227
- * pre-filter (the axes shared by every v1 retriever). The `semantic` / `asOf` /
228
- * link axes are NOT applied here — those are each retriever's own concern.
229
- * @public
230
- */
231
- export function indexedRecordMatchesQuery(entry: IIndexedMemoryRecord, query: IMemoryQuery): boolean {
232
- if (query.scope !== undefined && entry.scope !== query.scope) {
233
- return false;
234
- }
235
- if (query.kind !== undefined && entry.record.envelope.kind !== query.kind) {
236
- return false;
237
- }
238
- if (query.kinds !== undefined && !query.kinds.includes(entry.record.envelope.kind)) {
239
- return false;
240
- }
241
- if (query.tag !== undefined && !entry.record.envelope.tags.includes(query.tag)) {
242
- return false;
243
- }
244
- if (query.filter !== undefined && !query.filter(entry.record)) {
245
- return false;
246
- }
247
- return true;
248
- }
249
-
250
- /**
251
- * Apply the shared scope / kind / tag / predicate pre-filter to a set of indexed
252
- * entries, returning the surviving records (unordered, unlimited).
253
- * @public
254
- */
255
- export function selectByQuery(
256
- entries: ReadonlyArray<IIndexedMemoryRecord>,
257
- query: IMemoryQuery
258
- ): IMemoryRecord<unknown>[] {
259
- return entries.filter((entry) => indexedRecordMatchesQuery(entry, query)).map((entry) => entry.record);
260
- }
261
-
262
- /**
263
- * Apply the `{ offset, limit }` page window to an ordered record set. Applied
264
- * last, after ordering, so it always takes a stable window of the ordered
265
- * result. `offset` is applied first (records to skip), then `limit` (top-N of
266
- * the remainder).
267
- *
268
- * @remarks
269
- * Both bounds are public query input and are guarded against non-positive
270
- * values slipping into `slice`:
271
- * - `offset` absent or non-positive → no skip (today's behavior). An offset past
272
- * the end yields an empty page rather than a throw.
273
- * - `limit` absent → no truncation; a non-positive `limit` means "no records"
274
- * and returns an empty array.
275
- * @public
276
- */
277
- export function limitRecords(
278
- records: ReadonlyArray<IMemoryRecord<unknown>>,
279
- limit?: number,
280
- offset?: number
281
- ): ReadonlyArray<IMemoryRecord<unknown>> {
282
- const skip: number = offset !== undefined && offset > 0 ? offset : 0;
283
- const windowed: ReadonlyArray<IMemoryRecord<unknown>> = skip > 0 ? records.slice(skip) : records;
284
- if (limit === undefined) {
285
- return windowed;
286
- }
287
- if (limit <= 0) {
288
- return [];
289
- }
290
- return windowed.length > limit ? windowed.slice(0, limit) : windowed;
291
- }
@@ -1,152 +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 { IMemoryRecord, edgeTargetKey } from '../types';
8
- import { IIndexedMemoryRecord, IMemoryIndex } from '../index';
9
- import { IVectorIndex, IVectorQueryHit } from '../vector';
10
- import {
11
- IMemoryQuery,
12
- IMemoryRetriever,
13
- IMemoryRetrieverCapabilities,
14
- SEMANTIC_UNWIRED_MESSAGE,
15
- indexedRecordMatchesQuery,
16
- limitRecords,
17
- temporalUnwiredMessage
18
- } from './retriever';
19
-
20
- /**
21
- * Embeds a query string into a vector for {@link IVectorIndex.query}. Async and
22
- * `Result`-returning, since a real embedder does a network call.
23
- * @public
24
- */
25
- export type QueryEmbedder = (text: string) => Promise<Result<Float32Array>>;
26
-
27
- /**
28
- * The semantic backend wired into a {@link SemanticRetriever}: the vector index
29
- * to query and the embedder that turns the query text into a vector. Both are
30
- * required together — a vector index is useless without a way to embed the
31
- * query, so {@link SemanticRetriever.create} treats them as one unit.
32
- * @public
33
- */
34
- export interface ISemanticBackend {
35
- /** The vector index to query. */
36
- readonly vectorIndex: IVectorIndex;
37
- /** Turns the query text into a vector. */
38
- readonly embedQuery: QueryEmbedder;
39
- }
40
-
41
- /**
42
- * Construction options for {@link SemanticRetriever.create}.
43
- * @public
44
- */
45
- export interface ISemanticRetrieverCreateParams {
46
- /** The record index, used to resolve vector hits back to full records. */
47
- readonly index: IMemoryIndex;
48
- /**
49
- * The semantic backend. When absent, the retriever reports
50
- * `supportsSemanticRecall: false` and a `query.semantic` request degrades
51
- * loudly ({@link SEMANTIC_UNWIRED_MESSAGE}) rather than returning empty.
52
- */
53
- readonly backend?: ISemanticBackend;
54
- }
55
-
56
- /**
57
- * Vector-recall retriever. When a {@link ISemanticBackend | backend} is wired it
58
- * embeds `query.semantic`, queries the vector index, and resolves the hits back
59
- * to records (preserving vector score order). When no backend is wired,
60
- * `supportsSemanticRecall` is `false` and any `query.semantic` request degrades
61
- * loudly — it NEVER returns a silent empty.
62
- *
63
- * @remarks
64
- * A consumer-supplied backend that rejects (throws) is normalized into a
65
- * `Failure` — `retrieve` always honors its `Promise<Result<...>>` contract.
66
- * @public
67
- */
68
- export class SemanticRetriever implements IMemoryRetriever {
69
- private readonly _index: IMemoryIndex;
70
- private readonly _backend: ISemanticBackend | undefined;
71
-
72
- private constructor(index: IMemoryIndex, backend: ISemanticBackend | undefined) {
73
- this._index = index;
74
- this._backend = backend;
75
- }
76
-
77
- /** {@inheritDoc IMemoryRetriever.capabilities} */
78
- public get capabilities(): IMemoryRetrieverCapabilities {
79
- return {
80
- supportsSemanticRecall: this._backend !== undefined,
81
- supportsTemporalQuery: false,
82
- supportsLinkTraversal: false
83
- };
84
- }
85
-
86
- /** Family-convention factory. */
87
- public static create(params: ISemanticRetrieverCreateParams): Result<SemanticRetriever> {
88
- return succeed(new SemanticRetriever(params.index, params.backend));
89
- }
90
-
91
- /** {@inheritDoc IMemoryRetriever.retrieve} */
92
- public async retrieve(query: IMemoryQuery): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>> {
93
- if (query.asOf !== undefined) {
94
- return fail(temporalUnwiredMessage(query.kind));
95
- }
96
- if (query.semantic === undefined) {
97
- // The semantic term is this retriever's axis; without it there is nothing
98
- // to recall (a no-op contribution to a HybridRetriever, not a failure).
99
- return succeed([]);
100
- }
101
- if (this._backend === undefined) {
102
- return fail(SEMANTIC_UNWIRED_MESSAGE);
103
- }
104
- const backend: ISemanticBackend = this._backend;
105
- // The backend hooks are consumer-supplied; a rejecting (throwing) impl must
106
- // still surface as a `Failure`, never escape `retrieve` as a rejected
107
- // promise. `_callBackend` normalizes both a returned `fail` and a rejection.
108
- const embedded: Result<Float32Array> = await SemanticRetriever._callBackend('query embedding', () =>
109
- backend.embedQuery(query.semantic as string)
110
- );
111
- if (embedded.isFailure()) {
112
- return fail(embedded.message);
113
- }
114
- const hits: Result<ReadonlyArray<IVectorQueryHit>> = await SemanticRetriever._callBackend(
115
- 'vector query',
116
- () => backend.vectorIndex.query(embedded.value, query.topK ?? 10)
117
- );
118
- if (hits.isFailure()) {
119
- return fail(hits.message);
120
- }
121
- // Key by the canonical scope-qualified target so a hit re-resolves to the
122
- // exact record it scored against — a bare id would alias two records that
123
- // share a filename stem across scopes.
124
- const byKey: Map<string, IIndexedMemoryRecord> = new Map(
125
- this._index
126
- .entries()
127
- .map((entry) => [edgeTargetKey({ scope: entry.scope, id: entry.record.envelope.id }), entry])
128
- );
129
- const records: IMemoryRecord<unknown>[] = [];
130
- for (const hit of hits.value) {
131
- const entry: IIndexedMemoryRecord | undefined = byKey.get(edgeTargetKey(hit.target));
132
- if (entry !== undefined && indexedRecordMatchesQuery(entry, query)) {
133
- records.push(entry.record);
134
- }
135
- }
136
- return succeed(limitRecords(records, query.limit, query.offset));
137
- }
138
-
139
- /**
140
- * Invoke a consumer-supplied backend hook, normalizing both a returned `fail`
141
- * and a thrown/rejected promise into a single `semantic recall: <label> failed`
142
- * `Failure`. Keeps `retrieve` within the `Promise<Result<...>>` contract even
143
- * when the injected `embedQuery` / `vectorIndex` misbehaves.
144
- */
145
- private static async _callBackend<T>(label: string, op: () => Promise<Result<T>>): Promise<Result<T>> {
146
- try {
147
- return (await op()).withErrorFormat((msg) => `semantic recall: ${label} failed: ${msg}`);
148
- } catch (err) {
149
- return fail(`semantic recall: ${label} failed: ${String(err)}`);
150
- }
151
- }
152
- }