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