@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,105 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Erik Fortune
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- import { Converter, Converters, Result, fail, succeed } from '@fgv/ts-utils';
7
- import { JsonSchema } from '@fgv/ts-json-base';
8
- import { Kind } from '../types';
9
-
10
- /**
11
- * Registry of per-kind body Converters. Each memory {@link Kind} registers the
12
- * validated shape of its body; the store dispatches an `unknown` body through
13
- * the registered Converter on every write. Type-safe — no `any`.
14
- * @public
15
- */
16
- export interface IBodyConverterRegistry {
17
- /**
18
- * Register a Converter for a kind. Replaces any prior registration for the
19
- * same kind.
20
- */
21
- register<T>(kind: Kind, converter: Converter<T>): void;
22
-
23
- /**
24
- * Register a `JsonSchema` validator (from `@fgv/ts-json-base`) for a kind —
25
- * the schema IS a Validator. Replaces any prior registration for the same
26
- * kind.
27
- */
28
- registerSchema<T>(kind: Kind, schema: JsonSchema.ISchemaValidator<T>): void;
29
-
30
- /** Returns `true` if a converter is registered for the kind. */
31
- has(kind: Kind): boolean;
32
-
33
- /**
34
- * Get the raw converter registered for a kind. Fails if the kind is
35
- * unregistered. Exposed for implementors that need to re-validate a patched
36
- * body (e.g. a temporal-versioned policy's `applyUpdate`).
37
- */
38
- getConverter(kind: Kind): Result<Converter<unknown>>;
39
-
40
- /**
41
- * Convert an `unknown` body value for the given kind. Fails with
42
- * `no converter registered for kind '<k>'` when unregistered.
43
- */
44
- convert(kind: Kind, body: unknown): Result<unknown>;
45
- }
46
-
47
- /**
48
- * Default in-memory {@link IBodyConverterRegistry}.
49
- *
50
- * @remarks
51
- * Both `register` and `registerSchema` adapt the supplied converter/validator
52
- * into a `Converter<unknown>` via `Converters.generic`, so the heterogeneous
53
- * per-kind types are stored uniformly with no cast and no `any`. A
54
- * `Converter<T>` is not structurally a `Converter<unknown>` (the `map` callback
55
- * makes the type invariant), so the `generic` wrapper — whose callback returns
56
- * `Result<T>` (assignable to `Result<unknown>`) — is the type-safe bridge.
57
- * @public
58
- */
59
- export class BodyConverterRegistry implements IBodyConverterRegistry {
60
- private readonly _converters: Map<Kind, Converter<unknown>>;
61
-
62
- private constructor() {
63
- this._converters = new Map<Kind, Converter<unknown>>();
64
- }
65
-
66
- /** Family-convention factory. */
67
- public static create(): Result<BodyConverterRegistry> {
68
- return succeed(new BodyConverterRegistry());
69
- }
70
-
71
- /** {@inheritDoc IBodyConverterRegistry.register} */
72
- public register<T>(kind: Kind, converter: Converter<T>): void {
73
- this._converters.set(
74
- kind,
75
- Converters.generic<unknown>((from: unknown) => converter.convert(from))
76
- );
77
- }
78
-
79
- /** {@inheritDoc IBodyConverterRegistry.registerSchema} */
80
- public registerSchema<T>(kind: Kind, schema: JsonSchema.ISchemaValidator<T>): void {
81
- this._converters.set(
82
- kind,
83
- Converters.generic<unknown>((from: unknown) => schema.convert(from))
84
- );
85
- }
86
-
87
- /** {@inheritDoc IBodyConverterRegistry.has} */
88
- public has(kind: Kind): boolean {
89
- return this._converters.has(kind);
90
- }
91
-
92
- /** {@inheritDoc IBodyConverterRegistry.getConverter} */
93
- public getConverter(kind: Kind): Result<Converter<unknown>> {
94
- const converter: Converter<unknown> | undefined = this._converters.get(kind);
95
- if (converter === undefined) {
96
- return fail(`no converter registered for kind '${kind}'`);
97
- }
98
- return succeed(converter);
99
- }
100
-
101
- /** {@inheritDoc IBodyConverterRegistry.convert} */
102
- public convert(kind: Kind, body: unknown): Result<unknown> {
103
- return this.getConverter(kind).onSuccess((converter) => converter.convert(body));
104
- }
105
- }
@@ -1,233 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Erik Fortune
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- import { Converter, Converters, Result, fail, succeed } from '@fgv/ts-utils';
7
- import { Yaml } from '@fgv/ts-extras';
8
- import {
9
- Convert,
10
- IEdge,
11
- IEdgeTarget,
12
- IMemoryEnvelope,
13
- IMemoryRecord,
14
- IProvenance,
15
- ITemporalBlock
16
- } from '../types';
17
- import { IBodyConverterRegistry } from './bodyConverterRegistry';
18
-
19
- /** Matches exactly the JSON `null` literal. */
20
- // eslint-disable-next-line @rushstack/no-new-null -- the envelope nullable fields (invalid_at, embeddingRef) carry meaningful null; design-lock §2.3-2.5
21
- const nullConverter: Converter<null> = Converters.generic<null>((from: unknown) =>
22
- from === null ? succeed(null) : fail('expected null')
23
- );
24
-
25
- /** A nullable epoch-ms value (`number | null`). */
26
- // eslint-disable-next-line @rushstack/no-new-null -- meaningful null for IEdge/ITemporalBlock.invalid_at; design-lock §2.3-2.4
27
- const numberOrNull: Converter<number | null> = Converters.oneOf<number | null>([
28
- Converters.number,
29
- nullConverter
30
- ]);
31
-
32
- /** A nullable string value (`string | null`). */
33
- // eslint-disable-next-line @rushstack/no-new-null -- meaningful null for IMemoryEnvelope.embeddingRef; design-lock §2.5
34
- const stringOrNull: Converter<string | null> = Converters.oneOf<string | null>([
35
- Converters.string,
36
- nullConverter
37
- ]);
38
-
39
- /**
40
- * Converter for a scope-qualified {@link IEdgeTarget}. Both `scope` and `id`
41
- * are required — the whole point of the scoped target is that a bare id is
42
- * ambiguous across scopes.
43
- * @public
44
- */
45
- export const edgeTargetConverter: Converter<IEdgeTarget> = Converters.object<IEdgeTarget>({
46
- scope: Convert.scopeKey,
47
- id: Convert.memoryId
48
- });
49
-
50
- /**
51
- * Converter for the known {@link IProvenance} fields. The full
52
- * {@link provenanceConverter} layers extension-key preservation on top.
53
- * `derivedFrom` is serialized as the nested `{ scope, id }` object (mirroring
54
- * {@link edgeConverter | edge}'s scope-qualified `target`) so the provenance
55
- * back-reference is unambiguous across scopes.
56
- */
57
- const knownProvenanceConverter: Converter<IProvenance> = Converters.object<IProvenance>(
58
- {
59
- source: Converters.string,
60
- by: Converters.string.optional(),
61
- model: Converters.string.optional(),
62
- confidence: Converters.number.optional(),
63
- derivedFrom: edgeTargetConverter.optional()
64
- },
65
- { optionalFields: ['by', 'model', 'confidence', 'derivedFrom'] }
66
- );
67
-
68
- /**
69
- * Converter for {@link IProvenance}. Validates the known fields and preserves
70
- * any extension keys verbatim (the `[key: string]: unknown` opaque payload),
71
- * so a round-trip never drops consumer-attached data.
72
- * @public
73
- */
74
- export const provenanceConverter: Converter<IProvenance> = Converters.generic<IProvenance>(
75
- (from: unknown): Result<IProvenance> =>
76
- knownProvenanceConverter.convert(from).onSuccess((known) => {
77
- // `from` is guaranteed to be a non-null object here — the known-field
78
- // converter only succeeds on objects. Spread the original keys first,
79
- // then the validated/normalized known fields on top, so extension keys
80
- // survive while the known fields carry their converted values.
81
- const merged: IProvenance = { ...(from as Record<string, unknown>), ...known };
82
- return succeed(merged);
83
- })
84
- );
85
-
86
- /**
87
- * Converter for an attributed {@link IEdge}.
88
- * @public
89
- */
90
- export const edgeConverter: Converter<IEdge> = Converters.object<IEdge>(
91
- {
92
- type: Convert.linkType,
93
- target: edgeTargetConverter,
94
- confidence: Converters.number.optional(),
95
- provenance: provenanceConverter.optional(),
96
- valid_at: Converters.number.optional(),
97
- invalid_at: numberOrNull.optional()
98
- },
99
- { optionalFields: ['confidence', 'provenance', 'valid_at', 'invalid_at'] }
100
- );
101
-
102
- /**
103
- * Converter for the optional {@link ITemporalBlock}.
104
- * @public
105
- */
106
- export const temporalConverter: Converter<ITemporalBlock> = Converters.object<ITemporalBlock>(
107
- {
108
- valid_at: Converters.number.optional(),
109
- invalid_at: numberOrNull.optional()
110
- },
111
- { optionalFields: ['valid_at', 'invalid_at'] }
112
- );
113
-
114
- /**
115
- * Converter for the invariant {@link IMemoryEnvelope}. Validates a plain
116
- * object (e.g. parsed YAML frontmatter) into a typed envelope.
117
- * @public
118
- */
119
- export const envelopeConverter: Converter<IMemoryEnvelope> = Converters.object<IMemoryEnvelope>(
120
- {
121
- id: Convert.memoryId,
122
- entityId: Convert.entityId,
123
- kind: Convert.kind,
124
- tags: Converters.arrayOf(Convert.tag),
125
- links: Converters.arrayOf(edgeConverter),
126
- created: Converters.number,
127
- updated: Converters.number,
128
- seq: Converters.number,
129
- contentHash: Converters.string,
130
- rank: Converters.number.optional(),
131
- provenance: provenanceConverter,
132
- temporal: temporalConverter.optional(),
133
- embeddingRef: stringOrNull.optional()
134
- },
135
- { optionalFields: ['rank', 'temporal', 'embeddingRef'] }
136
- );
137
-
138
- /**
139
- * Converter that parses a YAML frontmatter string into an
140
- * {@link IMemoryEnvelope}.
141
- * @public
142
- */
143
- export const envelopeYamlConverter: Converter<IMemoryEnvelope> = Yaml.yamlConverter(envelopeConverter);
144
-
145
- /** The frontmatter delimiter line. */
146
- const FRONTMATTER_DELIMITER: string = '---';
147
-
148
- /**
149
- * The two parts of a memory file: the YAML frontmatter (between the `---`
150
- * delimiters) and the markdown body (everything after the closing delimiter).
151
- * @public
152
- */
153
- export interface IMemoryFileParts {
154
- /** The raw YAML frontmatter (delimiters stripped). */
155
- readonly frontmatter: string;
156
- /** The raw body text following the closing delimiter. */
157
- readonly body: string;
158
- }
159
-
160
- /**
161
- * Split a `---\n<yaml>\n---\n<body>` memory file into its frontmatter and
162
- * body parts. Pure string handling — no external dependency.
163
- * @public
164
- */
165
- export function splitFrontmatter(raw: string): Result<IMemoryFileParts> {
166
- // Split on '\n' and strip a trailing '\r' per line so CRLF-authored files
167
- // parse identically to LF — otherwise the '\r' would ride along into the
168
- // returned frontmatter (perturbing YAML parsing) and body (corrupting
169
- // round-trip fidelity).
170
- const lines: string[] = raw.split('\n').map((line) => (line.endsWith('\r') ? line.slice(0, -1) : line));
171
- if (lines[0].trim() !== FRONTMATTER_DELIMITER) {
172
- return fail("memory file: missing opening frontmatter delimiter '---'");
173
- }
174
- let closeIndex: number = -1;
175
- for (let i = 1; i < lines.length; i++) {
176
- if (lines[i].trim() === FRONTMATTER_DELIMITER) {
177
- closeIndex = i;
178
- break;
179
- }
180
- }
181
- if (closeIndex === -1) {
182
- return fail("memory file: missing closing frontmatter delimiter '---'");
183
- }
184
- return succeed({
185
- frontmatter: lines.slice(1, closeIndex).join('\n'),
186
- body: lines.slice(closeIndex + 1).join('\n')
187
- });
188
- }
189
-
190
- /**
191
- * Join a YAML frontmatter string and a body into the canonical
192
- * `---\n<yaml>\n---\n<body>` memory-file format.
193
- * @public
194
- */
195
- export function joinFrontmatter(frontmatter: string, body: string): string {
196
- const normalized: string = frontmatter.endsWith('\n') ? frontmatter : `${frontmatter}\n`;
197
- return `${FRONTMATTER_DELIMITER}\n${normalized}${FRONTMATTER_DELIMITER}\n${body}`;
198
- }
199
-
200
- /**
201
- * Parse a complete memory file into a typed {@link IMemoryRecord}. Splits the
202
- * frontmatter, validates the envelope, and dispatches the body through the
203
- * registered Converter for the envelope's kind.
204
- * @public
205
- */
206
- export function parseMemoryFile(
207
- raw: string,
208
- registry: IBodyConverterRegistry
209
- ): Result<IMemoryRecord<unknown>> {
210
- return splitFrontmatter(raw).onSuccess((parts) =>
211
- envelopeYamlConverter
212
- .convert(parts.frontmatter)
213
- .withErrorFormat((msg) => `memory file: invalid envelope: ${msg}`)
214
- .onSuccess((envelope) =>
215
- registry
216
- .convert(envelope.kind, parts.body)
217
- .withErrorFormat((msg) => `memory file '${envelope.id}': invalid body: ${msg}`)
218
- .onSuccess((body) => succeed({ envelope, body }))
219
- )
220
- );
221
- }
222
-
223
- /**
224
- * Serialize an envelope and its rendered body text into a memory file. The
225
- * envelope is emitted as YAML frontmatter; the body is written verbatim after
226
- * the closing delimiter.
227
- * @public
228
- */
229
- export function serializeMemoryFile(envelope: IMemoryEnvelope, body: string): Result<string> {
230
- return Yaml.yamlStringify(envelope)
231
- .withErrorFormat((msg) => `memory file '${envelope.id}': failed to serialize envelope: ${msg}`)
232
- .onSuccess((frontmatter) => succeed(joinFrontmatter(frontmatter, body)));
233
- }
@@ -1,7 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Erik Fortune
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- export * from './bodyConverterRegistry';
7
- export * from './envelopeConverter';
@@ -1,6 +0,0 @@
1
- /*
2
- * Copyright (c) 2026 Erik Fortune
3
- * SPDX-License-Identifier: MIT
4
- */
5
-
6
- export * from './memoryIndex';
@@ -1,332 +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 { IEdgeTarget, IMemoryRecord, Kind, MemoryId, MemoryScopeKey, Tag, edgeTargetKey } from '../types';
8
-
9
- /**
10
- * The mutation a {@link IMemoryIndex.patch | patch} applies: a record was
11
- * written (`'put'`) or removed (`'delete'`).
12
- * @public
13
- */
14
- export type MemoryIndexPatchOp = 'put' | 'delete';
15
-
16
- /** Shared empty key set for `byKind` / `byTag` misses (avoids per-call allocation). */
17
- const EMPTY_KEY_SET: ReadonlySet<string> = new Set<string>();
18
-
19
- /**
20
- * A memory record paired with the {@link MemoryScopeKey | scope} it lives
21
- * under. The scope is not carried on the {@link IMemoryEnvelope} (it is derived
22
- * from the entity id by the codec), so the store threads it alongside the
23
- * record when patching or rebuilding the index. The `(scope, id)` pair is the
24
- * index's primary key, keeping records distinct across scopes that reuse a
25
- * filename stem (e.g. `turn-0` under different conversations in Phase C).
26
- * @public
27
- */
28
- export interface IIndexedMemoryRecord {
29
- /** The scope the record is stored under. */
30
- readonly scope: MemoryScopeKey;
31
- /** The memory record itself. */
32
- readonly record: IMemoryRecord<unknown>;
33
- }
34
-
35
- /**
36
- * The derived, in-memory secondary indexes the store maintains over its
37
- * records. Never the source of truth — the FileTree is. The index is fully
38
- * rebuildable from a walk of the store ({@link IMemoryIndex.rebuild}) and is
39
- * patched incrementally on every write ({@link IMemoryIndex.patch}).
40
- *
41
- * @remarks
42
- * B1 builds the maps; link-traversal BFS over {@link IMemoryIndex.backlinks}
43
- * is B2. The accessors return records (not bare ids) so the B2 retrievers can
44
- * consume them directly.
45
- * @public
46
- */
47
- export interface IMemoryIndex {
48
- /**
49
- * Replace the entire index from a full set of records (a store walk).
50
- * @returns The number of records indexed.
51
- */
52
- rebuild(entries: ReadonlyArray<IIndexedMemoryRecord>): Result<number>;
53
-
54
- /**
55
- * Apply a single incremental change. `'put'` inserts or replaces the entry
56
- * at its `(scope, id)` key (removing any prior associations first); `'delete'`
57
- * removes it.
58
- * @returns The entry that was applied.
59
- */
60
- patch(op: MemoryIndexPatchOp, entry: IIndexedMemoryRecord): Result<IIndexedMemoryRecord>;
61
-
62
- /** Every indexed entry (scope + record). Primary read surface for the store. */
63
- entries(): ReadonlyArray<IIndexedMemoryRecord>;
64
-
65
- /** Records of the given kind, in recency order (most-recently-updated first). */
66
- byKind(kind: Kind): ReadonlyArray<IMemoryRecord<unknown>>;
67
-
68
- /** Records carrying the given tag, in recency order. */
69
- byTag(tag: Tag): ReadonlyArray<IMemoryRecord<unknown>>;
70
-
71
- /** All records in recency order (most-recently-updated first). */
72
- byRecency(): ReadonlyArray<IMemoryRecord<unknown>>;
73
-
74
- /**
75
- * All records ordered by store-computed {@link IMemoryEnvelope.rank} descending,
76
- * with recency (most-recently-updated, then `seq`) as a tiebreak. Records with
77
- * an absent `rank` sort LAST (after every ranked record), then by recency among
78
- * themselves. Serves a bounded top-M ({@link IMemoryEnvelope.rank}-ordered) page
79
- * from the in-memory index with no full-vault (filesystem) scan.
80
- */
81
- byRank(): ReadonlyArray<IMemoryRecord<unknown>>;
82
-
83
- /**
84
- * The scope-qualified sources of records whose `links` point AT `target`
85
- * (inbound edges), keyed on the target's `(scope, id)` address. The seed map
86
- * for B2 link-traversal; results are {@link IEdgeTarget}s so a caller can feed
87
- * them straight back in as further traversal seeds.
88
- */
89
- backlinks(target: IEdgeTarget): ReadonlyArray<IEdgeTarget>;
90
- }
91
-
92
- /**
93
- * Default in-memory {@link IMemoryIndex}. Maintains the derived `byKind` /
94
- * `byTag` / `byRecency` / `backlinks` views incrementally; a `'put'` for an
95
- * already-indexed key first removes the prior entry's associations so a changed
96
- * kind / tag / link set never leaves a stale reference behind.
97
- * @public
98
- */
99
- export class MemoryIndex implements IMemoryIndex {
100
- /** Primary store: `(scope, id)` composite key → indexed entry. */
101
- private readonly _byKey: Map<string, IIndexedMemoryRecord>;
102
- /** kind → set of composite keys. */
103
- private readonly _byKind: Map<Kind, Set<string>>;
104
- /** tag → set of composite keys. */
105
- private readonly _byTag: Map<Tag, Set<string>>;
106
- /**
107
- * canonical target key (`edgeTargetKey`) → (source composite key → source
108
- * {@link IEdgeTarget}). The OUTER map is keyed on the scope-qualified target's
109
- * canonical `(scope, id)` string — NOT the target's bare id — so an edge to
110
- * `turn-3` in one conversation is tracked separately from `turn-3` in another.
111
- * The INNER map is keyed by the source's `(scope, id)` composite so two distinct
112
- * source records that share an id across scopes are tracked independently and
113
- * removing one never drops the other's edge.
114
- */
115
- private readonly _backlinks: Map<string, Map<string, IEdgeTarget>>;
116
-
117
- private constructor() {
118
- this._byKey = new Map<string, IIndexedMemoryRecord>();
119
- this._byKind = new Map<Kind, Set<string>>();
120
- this._byTag = new Map<Tag, Set<string>>();
121
- this._backlinks = new Map<string, Map<string, IEdgeTarget>>();
122
- }
123
-
124
- /** Family-convention factory. */
125
- public static create(): Result<MemoryIndex> {
126
- return succeed(new MemoryIndex());
127
- }
128
-
129
- /**
130
- * The composite primary key for an entry: scope + id, NUL-separated. NUL
131
- * is excluded from both components (scope segments pass
132
- * `assertPortableFilenameStem`; `MemoryId` is portable-filename-safe), so it
133
- * is a collision-proof separator across every scope/id pair the codecs produce.
134
- */
135
- private static _keyOf(scope: MemoryScopeKey, id: MemoryId): string {
136
- return edgeTargetKey({ scope, id });
137
- }
138
-
139
- /** {@inheritDoc IMemoryIndex.rebuild} */
140
- public rebuild(entries: ReadonlyArray<IIndexedMemoryRecord>): Result<number> {
141
- this._byKey.clear();
142
- this._byKind.clear();
143
- this._byTag.clear();
144
- this._backlinks.clear();
145
- for (const entry of entries) {
146
- this._add(entry);
147
- }
148
- return succeed(this._byKey.size);
149
- }
150
-
151
- /** {@inheritDoc IMemoryIndex.patch} */
152
- public patch(op: MemoryIndexPatchOp, entry: IIndexedMemoryRecord): Result<IIndexedMemoryRecord> {
153
- const key: string = MemoryIndex._keyOf(entry.scope, entry.record.envelope.id);
154
- // Always drop any prior associations for this key first, so a 'put' that
155
- // changes kind/tags/links cannot strand a stale reference.
156
- this._remove(key);
157
- if (op === 'put') {
158
- this._add(entry);
159
- }
160
- return succeed(entry);
161
- }
162
-
163
- /** {@inheritDoc IMemoryIndex.entries} */
164
- public entries(): ReadonlyArray<IIndexedMemoryRecord> {
165
- return Array.from(this._byKey.values());
166
- }
167
-
168
- /** {@inheritDoc IMemoryIndex.byKind} */
169
- public byKind(kind: Kind): ReadonlyArray<IMemoryRecord<unknown>> {
170
- return this._recencyOrdered(this._byKind.get(kind) ?? EMPTY_KEY_SET);
171
- }
172
-
173
- /** {@inheritDoc IMemoryIndex.byTag} */
174
- public byTag(tag: Tag): ReadonlyArray<IMemoryRecord<unknown>> {
175
- return this._recencyOrdered(this._byTag.get(tag) ?? EMPTY_KEY_SET);
176
- }
177
-
178
- /** {@inheritDoc IMemoryIndex.byRecency} */
179
- public byRecency(): ReadonlyArray<IMemoryRecord<unknown>> {
180
- return this._recencyOrdered(this._byKey.keys());
181
- }
182
-
183
- /** {@inheritDoc IMemoryIndex.byRank} */
184
- public byRank(): ReadonlyArray<IMemoryRecord<unknown>> {
185
- return this._rankOrdered(this._byKey.keys());
186
- }
187
-
188
- /** {@inheritDoc IMemoryIndex.backlinks} */
189
- public backlinks(target: IEdgeTarget): ReadonlyArray<IEdgeTarget> {
190
- const sources: Map<string, IEdgeTarget> | undefined = this._backlinks.get(edgeTargetKey(target));
191
- return sources === undefined ? [] : Array.from(sources.values());
192
- }
193
-
194
- /**
195
- * Resolve a set of composite keys to their records, ordered
196
- * most-recently-updated first (with a `seq` tiebreak so equal-`updated`
197
- * records sort deterministically).
198
- */
199
- private _recencyOrdered(keys: Iterable<string>): ReadonlyArray<IMemoryRecord<unknown>> {
200
- const records: IMemoryRecord<unknown>[] = [];
201
- for (const key of keys) {
202
- const entry: IIndexedMemoryRecord | undefined = this._byKey.get(key);
203
- if (entry !== undefined) {
204
- records.push(entry.record);
205
- }
206
- }
207
- return records.sort((a, b) => {
208
- const byUpdated: number = b.envelope.updated - a.envelope.updated;
209
- return byUpdated !== 0 ? byUpdated : b.envelope.seq - a.envelope.seq;
210
- });
211
- }
212
-
213
- /**
214
- * Resolve a set of composite keys to their records, ordered by
215
- * {@link IMemoryEnvelope.rank} descending with recency (`updated`, then `seq`)
216
- * as the tiebreak. Records with an absent `rank` sort LAST, then by recency
217
- * among themselves. Computed on call (mirrors {@link MemoryIndex._recencyOrdered}) —
218
- * no incremental rank-ordered view is maintained, matching the recency view's
219
- * approach; the sort is over the in-memory index, never a filesystem walk.
220
- */
221
- private _rankOrdered(keys: Iterable<string>): ReadonlyArray<IMemoryRecord<unknown>> {
222
- const records: IMemoryRecord<unknown>[] = [];
223
- for (const key of keys) {
224
- const entry: IIndexedMemoryRecord | undefined = this._byKey.get(key);
225
- if (entry !== undefined) {
226
- records.push(entry.record);
227
- }
228
- }
229
- return records.sort(MemoryIndex._compareByRank);
230
- }
231
-
232
- /**
233
- * Rank-descending comparator with an absent-`rank`-last rule and a recency
234
- * (`updated`, then `seq`) tiebreak. Duplicated from the retrieve packlet's
235
- * `rankCompare` deliberately: the index must not depend on `retrieve` (that
236
- * package depends on the index), mirroring how `_recencyOrdered` inlines the
237
- * recency ordering rather than importing `recencyCompare`.
238
- */
239
- private static _compareByRank(a: IMemoryRecord<unknown>, b: IMemoryRecord<unknown>): number {
240
- const ra: number | undefined = a.envelope.rank;
241
- const rb: number | undefined = b.envelope.rank;
242
- // Absent rank sorts last; two absent ranks fall through to the recency tiebreak.
243
- if (ra === undefined && rb !== undefined) {
244
- return 1;
245
- }
246
- if (rb === undefined && ra !== undefined) {
247
- return -1;
248
- }
249
- if (ra !== undefined && rb !== undefined && ra !== rb) {
250
- return rb - ra;
251
- }
252
- const byUpdated: number = b.envelope.updated - a.envelope.updated;
253
- return byUpdated !== 0 ? byUpdated : b.envelope.seq - a.envelope.seq;
254
- }
255
-
256
- /** Insert an entry and register all its derived associations. */
257
- private _add(entry: IIndexedMemoryRecord): void {
258
- const key: string = MemoryIndex._keyOf(entry.scope, entry.record.envelope.id);
259
- const envelope: IMemoryRecord<unknown>['envelope'] = entry.record.envelope;
260
- this._byKey.set(key, entry);
261
- this._addToSetMap(this._byKind, envelope.kind, key);
262
- for (const tag of envelope.tags) {
263
- this._addToSetMap(this._byTag, tag, key);
264
- }
265
- for (const edge of envelope.links) {
266
- this._addBacklink(edge.target, key, { scope: entry.scope, id: envelope.id });
267
- }
268
- }
269
-
270
- /** Remove the entry at `key` (if present) and all its derived associations. */
271
- private _remove(key: string): void {
272
- const entry: IIndexedMemoryRecord | undefined = this._byKey.get(key);
273
- if (entry === undefined) {
274
- return;
275
- }
276
- const envelope: IMemoryRecord<unknown>['envelope'] = entry.record.envelope;
277
- this._byKey.delete(key);
278
- this._removeFromSetMap(this._byKind, envelope.kind, key);
279
- for (const tag of envelope.tags) {
280
- this._removeFromSetMap(this._byTag, tag, key);
281
- }
282
- for (const edge of envelope.links) {
283
- this._removeBacklink(edge.target, key);
284
- }
285
- }
286
-
287
- /** Register `source` (keyed by its composite `sourceKey`) as linking at `target`. */
288
- private _addBacklink(target: IEdgeTarget, sourceKey: string, source: IEdgeTarget): void {
289
- const targetKey: string = edgeTargetKey(target);
290
- const existing: Map<string, IEdgeTarget> | undefined = this._backlinks.get(targetKey);
291
- if (existing === undefined) {
292
- this._backlinks.set(targetKey, new Map<string, IEdgeTarget>([[sourceKey, source]]));
293
- } else {
294
- existing.set(sourceKey, source);
295
- }
296
- }
297
-
298
- /** Drop the backlink from `sourceKey` to `target`, removing the target map when empty. */
299
- private _removeBacklink(target: IEdgeTarget, sourceKey: string): void {
300
- const targetKey: string = edgeTargetKey(target);
301
- const existing: Map<string, IEdgeTarget> | undefined = this._backlinks.get(targetKey);
302
- if (existing === undefined) {
303
- return;
304
- }
305
- existing.delete(sourceKey);
306
- if (existing.size === 0) {
307
- this._backlinks.delete(targetKey);
308
- }
309
- }
310
-
311
- /** Add `member` to the set at `mapKey`, creating the set on first use. */
312
- private _addToSetMap<K, M>(map: Map<K, Set<M>>, mapKey: K, member: M): void {
313
- const existing: Set<M> | undefined = map.get(mapKey);
314
- if (existing === undefined) {
315
- map.set(mapKey, new Set<M>([member]));
316
- } else {
317
- existing.add(member);
318
- }
319
- }
320
-
321
- /** Remove `member` from the set at `mapKey`, dropping the set when empty. */
322
- private _removeFromSetMap<K, M>(map: Map<K, Set<M>>, mapKey: K, member: M): void {
323
- const existing: Set<M> | undefined = map.get(mapKey);
324
- if (existing === undefined) {
325
- return;
326
- }
327
- existing.delete(member);
328
- if (existing.size === 0) {
329
- map.delete(mapKey);
330
- }
331
- }
332
- }