@fgv/ts-agent-memory 5.1.0-39 → 5.1.0-41
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/.rush/temp/{b82cf6bdece20481260e6bab946179eeec9d7b46.tar.log → cbbdbe09515171b4eba8f2592be2dace1e4e8142.tar.log} +14 -2
- package/.rush/temp/chunked-rush-logs/ts-agent-memory.build.chunks.jsonl +2 -2
- package/.rush/temp/operation/build/all.log +2 -2
- package/.rush/temp/operation/build/log-chunks.jsonl +2 -2
- package/.rush/temp/operation/build/state.json +1 -1
- package/dist/packlets/converters/envelopeConverter.js +17 -3
- package/dist/packlets/converters/envelopeConverter.js.map +1 -1
- package/dist/packlets/index/memoryIndex.js +58 -10
- package/dist/packlets/index/memoryIndex.js.map +1 -1
- package/dist/packlets/ingest/cycleGuard.js +13 -6
- package/dist/packlets/ingest/cycleGuard.js.map +1 -1
- package/dist/packlets/ingest/hostStages.js.map +1 -1
- package/dist/packlets/ingest/model.js.map +1 -1
- package/dist/packlets/ingest/orchestrator.js +94 -49
- package/dist/packlets/ingest/orchestrator.js.map +1 -1
- package/dist/packlets/retrieve/hybridRetriever.js +13 -2
- package/dist/packlets/retrieve/hybridRetriever.js.map +1 -1
- package/dist/packlets/retrieve/linkTraversalRetriever.js +46 -57
- package/dist/packlets/retrieve/linkTraversalRetriever.js.map +1 -1
- package/dist/packlets/retrieve/recencyRetriever.js +3 -3
- package/dist/packlets/retrieve/recencyRetriever.js.map +1 -1
- package/dist/packlets/retrieve/retriever.js +50 -7
- package/dist/packlets/retrieve/retriever.js.map +1 -1
- package/dist/packlets/retrieve/semanticRetriever.js +9 -3
- package/dist/packlets/retrieve/semanticRetriever.js.map +1 -1
- package/dist/packlets/retrieve/structuredFilterRetriever.js +3 -3
- package/dist/packlets/retrieve/structuredFilterRetriever.js.map +1 -1
- package/dist/packlets/retrieve/tagRetriever.js +3 -3
- package/dist/packlets/retrieve/tagRetriever.js.map +1 -1
- package/dist/packlets/retrieve/temporalRetrievers.js +3 -3
- package/dist/packlets/retrieve/temporalRetrievers.js.map +1 -1
- package/dist/packlets/store/fileTreeMemoryStore.js +72 -16
- package/dist/packlets/store/fileTreeMemoryStore.js.map +1 -1
- package/dist/packlets/tools/memoryTools.js +104 -21
- package/dist/packlets/tools/memoryTools.js.map +1 -1
- package/dist/packlets/types/envelope.js +13 -1
- package/dist/packlets/types/envelope.js.map +1 -1
- package/dist/packlets/vector/inMemoryCosineIndex.js +22 -17
- package/dist/packlets/vector/inMemoryCosineIndex.js.map +1 -1
- package/dist/packlets/vector/vectorIndex.js.map +1 -1
- package/dist/test/unit/converters/antagonistRoundTrip.test.js +3 -3
- package/dist/test/unit/converters/antagonistRoundTrip.test.js.map +1 -1
- package/dist/test/unit/converters/envelopeConverter.test.js +125 -8
- package/dist/test/unit/converters/envelopeConverter.test.js.map +1 -1
- package/dist/test/unit/index/memoryIndex.test.js +87 -25
- package/dist/test/unit/index/memoryIndex.test.js.map +1 -1
- package/dist/test/unit/ingest/antagonistCycleAndParity.test.js +20 -16
- package/dist/test/unit/ingest/antagonistCycleAndParity.test.js.map +1 -1
- package/dist/test/unit/ingest/cycleGuard.test.js +28 -1
- package/dist/test/unit/ingest/cycleGuard.test.js.map +1 -1
- package/dist/test/unit/ingest/orchestrator.test.js +187 -45
- package/dist/test/unit/ingest/orchestrator.test.js.map +1 -1
- package/dist/test/unit/retrieve/linkTraversalRetriever.test.js +106 -31
- package/dist/test/unit/retrieve/linkTraversalRetriever.test.js.map +1 -1
- package/dist/test/unit/retrieve/retrievers.test.js +299 -37
- package/dist/test/unit/retrieve/retrievers.test.js.map +1 -1
- package/dist/test/unit/store/embedOnWrite.test.js +69 -12
- package/dist/test/unit/store/embedOnWrite.test.js.map +1 -1
- package/dist/test/unit/store/listScoped.test.js +109 -0
- package/dist/test/unit/store/listScoped.test.js.map +1 -0
- package/dist/test/unit/store/rankAxis.test.js +254 -0
- package/dist/test/unit/store/rankAxis.test.js.map +1 -0
- package/dist/test/unit/tools/memoryTools.test.js +280 -11
- package/dist/test/unit/tools/memoryTools.test.js.map +1 -1
- package/dist/test/unit/types/writePolicy.test.js +9 -2
- package/dist/test/unit/types/writePolicy.test.js.map +1 -1
- package/dist/test/unit/vector/inMemoryCosineIndex.test.js +95 -35
- package/dist/test/unit/vector/inMemoryCosineIndex.test.js.map +1 -1
- package/dist/test/unit/vector/vectorIndex.test.js +24 -15
- package/dist/test/unit/vector/vectorIndex.test.js.map +1 -1
- package/dist/ts-agent-memory.d.ts +384 -97
- package/etc/ts-agent-memory.api.md +64 -22
- package/lib/packlets/converters/envelopeConverter.d.ts +8 -1
- package/lib/packlets/converters/envelopeConverter.d.ts.map +1 -1
- package/lib/packlets/converters/envelopeConverter.js +18 -4
- package/lib/packlets/converters/envelopeConverter.js.map +1 -1
- package/lib/packlets/index/memoryIndex.d.ts +42 -10
- package/lib/packlets/index/memoryIndex.d.ts.map +1 -1
- package/lib/packlets/index/memoryIndex.js +58 -10
- package/lib/packlets/index/memoryIndex.js.map +1 -1
- package/lib/packlets/ingest/cycleGuard.d.ts +5 -5
- package/lib/packlets/ingest/cycleGuard.d.ts.map +1 -1
- package/lib/packlets/ingest/cycleGuard.js +13 -6
- package/lib/packlets/ingest/cycleGuard.js.map +1 -1
- package/lib/packlets/ingest/hostStages.d.ts +3 -3
- package/lib/packlets/ingest/hostStages.d.ts.map +1 -1
- package/lib/packlets/ingest/hostStages.js.map +1 -1
- package/lib/packlets/ingest/model.d.ts +25 -14
- package/lib/packlets/ingest/model.d.ts.map +1 -1
- package/lib/packlets/ingest/model.js.map +1 -1
- package/lib/packlets/ingest/orchestrator.d.ts +18 -4
- package/lib/packlets/ingest/orchestrator.d.ts.map +1 -1
- package/lib/packlets/ingest/orchestrator.js +93 -48
- package/lib/packlets/ingest/orchestrator.js.map +1 -1
- package/lib/packlets/retrieve/hybridRetriever.d.ts.map +1 -1
- package/lib/packlets/retrieve/hybridRetriever.js +12 -1
- package/lib/packlets/retrieve/hybridRetriever.js.map +1 -1
- package/lib/packlets/retrieve/linkTraversalRetriever.d.ts +18 -23
- package/lib/packlets/retrieve/linkTraversalRetriever.d.ts.map +1 -1
- package/lib/packlets/retrieve/linkTraversalRetriever.js +45 -56
- package/lib/packlets/retrieve/linkTraversalRetriever.js.map +1 -1
- package/lib/packlets/retrieve/recencyRetriever.js +2 -2
- package/lib/packlets/retrieve/recencyRetriever.js.map +1 -1
- package/lib/packlets/retrieve/retriever.d.ts +70 -11
- package/lib/packlets/retrieve/retriever.d.ts.map +1 -1
- package/lib/packlets/retrieve/retriever.js +52 -7
- package/lib/packlets/retrieve/retriever.js.map +1 -1
- package/lib/packlets/retrieve/semanticRetriever.d.ts.map +1 -1
- package/lib/packlets/retrieve/semanticRetriever.js +9 -3
- package/lib/packlets/retrieve/semanticRetriever.js.map +1 -1
- package/lib/packlets/retrieve/structuredFilterRetriever.js +2 -2
- package/lib/packlets/retrieve/structuredFilterRetriever.js.map +1 -1
- package/lib/packlets/retrieve/tagRetriever.js +2 -2
- package/lib/packlets/retrieve/tagRetriever.js.map +1 -1
- package/lib/packlets/retrieve/temporalRetrievers.js +3 -3
- package/lib/packlets/retrieve/temporalRetrievers.js.map +1 -1
- package/lib/packlets/store/fileTreeMemoryStore.d.ts +57 -3
- package/lib/packlets/store/fileTreeMemoryStore.d.ts.map +1 -1
- package/lib/packlets/store/fileTreeMemoryStore.js +72 -16
- package/lib/packlets/store/fileTreeMemoryStore.js.map +1 -1
- package/lib/packlets/tools/memoryTools.d.ts +24 -0
- package/lib/packlets/tools/memoryTools.d.ts.map +1 -1
- package/lib/packlets/tools/memoryTools.js +104 -21
- package/lib/packlets/tools/memoryTools.js.map +1 -1
- package/lib/packlets/types/envelope.d.ts +61 -8
- package/lib/packlets/types/envelope.d.ts.map +1 -1
- package/lib/packlets/types/envelope.js +14 -0
- package/lib/packlets/types/envelope.js.map +1 -1
- package/lib/packlets/vector/inMemoryCosineIndex.d.ts +9 -5
- package/lib/packlets/vector/inMemoryCosineIndex.d.ts.map +1 -1
- package/lib/packlets/vector/inMemoryCosineIndex.js +22 -17
- package/lib/packlets/vector/inMemoryCosineIndex.js.map +1 -1
- package/lib/packlets/vector/vectorIndex.d.ts +46 -20
- package/lib/packlets/vector/vectorIndex.d.ts.map +1 -1
- package/lib/packlets/vector/vectorIndex.js.map +1 -1
- package/lib/test/unit/converters/antagonistRoundTrip.test.js +3 -3
- package/lib/test/unit/converters/antagonistRoundTrip.test.js.map +1 -1
- package/lib/test/unit/converters/envelopeConverter.test.js +124 -7
- package/lib/test/unit/converters/envelopeConverter.test.js.map +1 -1
- package/lib/test/unit/index/memoryIndex.test.js +86 -24
- package/lib/test/unit/index/memoryIndex.test.js.map +1 -1
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.js +20 -16
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.js.map +1 -1
- package/lib/test/unit/ingest/cycleGuard.test.js +28 -1
- package/lib/test/unit/ingest/cycleGuard.test.js.map +1 -1
- package/lib/test/unit/ingest/orchestrator.test.js +186 -44
- package/lib/test/unit/ingest/orchestrator.test.js.map +1 -1
- package/lib/test/unit/retrieve/linkTraversalRetriever.test.js +106 -31
- package/lib/test/unit/retrieve/linkTraversalRetriever.test.js.map +1 -1
- package/lib/test/unit/retrieve/retrievers.test.js +298 -36
- package/lib/test/unit/retrieve/retrievers.test.js.map +1 -1
- package/lib/test/unit/store/embedOnWrite.test.js +68 -11
- package/lib/test/unit/store/embedOnWrite.test.js.map +1 -1
- package/lib/test/unit/store/listScoped.test.d.ts +2 -0
- package/lib/test/unit/store/listScoped.test.d.ts.map +1 -0
- package/lib/test/unit/store/listScoped.test.js +111 -0
- package/lib/test/unit/store/listScoped.test.js.map +1 -0
- package/lib/test/unit/store/rankAxis.test.d.ts +2 -0
- package/lib/test/unit/store/rankAxis.test.d.ts.map +1 -0
- package/lib/test/unit/store/rankAxis.test.js +256 -0
- package/lib/test/unit/store/rankAxis.test.js.map +1 -0
- package/lib/test/unit/tools/memoryTools.test.js +280 -11
- package/lib/test/unit/tools/memoryTools.test.js.map +1 -1
- package/lib/test/unit/types/writePolicy.test.js +9 -2
- package/lib/test/unit/types/writePolicy.test.js.map +1 -1
- package/lib/test/unit/vector/inMemoryCosineIndex.test.js +95 -35
- package/lib/test/unit/vector/inMemoryCosineIndex.test.js.map +1 -1
- package/lib/test/unit/vector/vectorIndex.test.js +24 -15
- package/lib/test/unit/vector/vectorIndex.test.js.map +1 -1
- package/package.json +7 -7
- package/rush-logs/ts-agent-memory.build.cache.log +1 -1
- package/rush-logs/ts-agent-memory.build.log +2 -2
- package/src/packlets/converters/envelopeConverter.ts +27 -4
- package/src/packlets/index/memoryIndex.ts +86 -22
- package/src/packlets/ingest/cycleGuard.ts +22 -11
- package/src/packlets/ingest/hostStages.ts +3 -3
- package/src/packlets/ingest/model.ts +25 -14
- package/src/packlets/ingest/orchestrator.ts +143 -67
- package/src/packlets/retrieve/hybridRetriever.ts +14 -1
- package/src/packlets/retrieve/linkTraversalRetriever.ts +51 -62
- package/src/packlets/retrieve/recencyRetriever.ts +3 -3
- package/src/packlets/retrieve/retriever.ts +97 -13
- package/src/packlets/retrieve/semanticRetriever.ts +10 -5
- package/src/packlets/retrieve/structuredFilterRetriever.ts +3 -3
- package/src/packlets/retrieve/tagRetriever.ts +3 -3
- package/src/packlets/retrieve/temporalRetrievers.ts +3 -3
- package/src/packlets/store/fileTreeMemoryStore.ts +117 -12
- package/src/packlets/tools/memoryTools.ts +152 -25
- package/src/packlets/types/envelope.ts +66 -8
- package/src/packlets/vector/inMemoryCosineIndex.ts +45 -22
- package/src/packlets/vector/vectorIndex.ts +47 -20
- package/src/test/unit/converters/antagonistRoundTrip.test.ts +3 -3
- package/src/test/unit/converters/envelopeConverter.test.ts +168 -11
- package/src/test/unit/index/memoryIndex.test.ts +99 -14
- package/src/test/unit/ingest/antagonistCycleAndParity.test.ts +23 -18
- package/src/test/unit/ingest/cycleGuard.test.ts +44 -2
- package/src/test/unit/ingest/orchestrator.test.ts +234 -41
- package/src/test/unit/retrieve/linkTraversalRetriever.test.ts +134 -35
- package/src/test/unit/retrieve/retrievers.test.ts +381 -25
- package/src/test/unit/store/embedOnWrite.test.ts +83 -11
- package/src/test/unit/store/listScoped.test.ts +138 -0
- package/src/test/unit/store/rankAxis.test.ts +349 -0
- package/src/test/unit/tools/memoryTools.test.ts +362 -13
- package/src/test/unit/types/writePolicy.test.ts +11 -2
- package/src/test/unit/vector/inMemoryCosineIndex.test.ts +115 -39
- package/src/test/unit/vector/vectorIndex.test.ts +33 -17
- package/temp/build/lint/_eslint-5eVG3S6w.json +41 -33
- package/temp/build/typescript/ts_8nwakTlr.json +1 -1
- package/temp/ts-agent-memory.api.json +1080 -136
- package/temp/ts-agent-memory.api.md +64 -22
|
@@ -251,6 +251,26 @@ export declare function defaultMemoryScopeEncoding(scope: MemoryScopeKey): Resul
|
|
|
251
251
|
*/
|
|
252
252
|
export declare const edgeConverter: Converter<IEdge>;
|
|
253
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Converter for a scope-qualified {@link IEdgeTarget}. Both `scope` and `id`
|
|
256
|
+
* are required — the whole point of the scoped target is that a bare id is
|
|
257
|
+
* ambiguous across scopes.
|
|
258
|
+
* @public
|
|
259
|
+
*/
|
|
260
|
+
export declare const edgeTargetConverter: Converter<IEdgeTarget>;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* The canonical composite-key string for an {@link IEdgeTarget}: scope + id,
|
|
264
|
+
* NUL-separated. NUL is excluded from both components (scope segments are
|
|
265
|
+
* filename-safe; {@link MemoryId} is portable-filename-safe), so it is a
|
|
266
|
+
* collision-proof separator. This is the ONE canonicalization every consumer
|
|
267
|
+
* that keys on a scoped target uses — the backlink index, the cycle guard, and
|
|
268
|
+
* the ingest edge-validation path all route through it so their notions of
|
|
269
|
+
* "same target" cannot drift.
|
|
270
|
+
* @public
|
|
271
|
+
*/
|
|
272
|
+
export declare function edgeTargetKey(target: IEdgeTarget): string;
|
|
273
|
+
|
|
254
274
|
/**
|
|
255
275
|
* Consumer-supplied domain key. The stable entity identity across versions;
|
|
256
276
|
* the package never mints identity. Equals {@link MemoryId} for non-temporal
|
|
@@ -292,6 +312,7 @@ export declare class FileTreeMemoryStore implements IMemoryStore {
|
|
|
292
312
|
private readonly _registry;
|
|
293
313
|
private readonly _writePolicies;
|
|
294
314
|
private readonly _codecs;
|
|
315
|
+
private readonly _rankProjectors;
|
|
295
316
|
private readonly _defaultCodec;
|
|
296
317
|
private readonly _defaultPolicy;
|
|
297
318
|
private readonly _scopeEncoding;
|
|
@@ -334,6 +355,10 @@ export declare class FileTreeMemoryStore implements IMemoryStore {
|
|
|
334
355
|
getById(scope: MemoryScopeKey, id: MemoryId): Promise<Result<IMemoryRecord<unknown> | undefined>>;
|
|
335
356
|
/** {@inheritDoc IMemoryStore.list} */
|
|
336
357
|
list(filter?: IMemoryStoreListFilter): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>>;
|
|
358
|
+
/** {@inheritDoc IMemoryStore.listScoped} */
|
|
359
|
+
listScoped(): Promise<Result<ReadonlyArray<IScopedMemoryRecord>>>;
|
|
360
|
+
/** {@inheritDoc IMemoryStore.asRecordSource} */
|
|
361
|
+
asRecordSource(): IMemoryRecordSource;
|
|
337
362
|
/**
|
|
338
363
|
* Collapse temporal records to the single version valid at `asOf` per entity;
|
|
339
364
|
* non-temporal records are timeless and pass through unchanged (valid-time
|
|
@@ -413,7 +438,12 @@ export declare class FileTreeMemoryStore implements IMemoryStore {
|
|
|
413
438
|
* `accept` / `reject` decisions evict nothing.
|
|
414
439
|
*/
|
|
415
440
|
private _applyEvictions;
|
|
416
|
-
/**
|
|
441
|
+
/**
|
|
442
|
+
* Best-effort vector removal for each evicted record (never fails the put).
|
|
443
|
+
* Every evicted record is in the same `scope` as the incoming write (the
|
|
444
|
+
* cull-oldest cohort is the incoming record's `(scope, kind)` cohort), so that
|
|
445
|
+
* scope qualifies each removal target.
|
|
446
|
+
*/
|
|
417
447
|
private _removeEvictedVectors;
|
|
418
448
|
/**
|
|
419
449
|
* Run a consumer-supplied vector hook, normalizing a thrown/rejected hook into a
|
|
@@ -544,6 +574,19 @@ export declare class FileTreeMemoryStore implements IMemoryStore {
|
|
|
544
574
|
*/
|
|
545
575
|
private _isMutableMetadataUnchanged;
|
|
546
576
|
private _contentHash;
|
|
577
|
+
/**
|
|
578
|
+
* Stamp the store-computed {@link IMemoryEnvelope.rank} onto a fully-built,
|
|
579
|
+
* fully-stamped record by running the kind's registered {@link RankProjector}.
|
|
580
|
+
* Runs on the SAME resolved (post-merge) record whose `contentHash` was just
|
|
581
|
+
* computed, so `rank` is always consistent with the current body — no separate
|
|
582
|
+
* write path and no consumer write-discipline rule. A no-op pass-through
|
|
583
|
+
* (byte-identical record) when the kind has no projector — the additive,
|
|
584
|
+
* zero-overhead-when-unwired default. The projector is a host callback: a throw
|
|
585
|
+
* is logged at `warn` and the record is stamped with NO `rank` (the field is
|
|
586
|
+
* explicitly cleared, so a throw on an update drops a now-stale prior rank rather
|
|
587
|
+
* than preserving it), so a ranking bug never loses an authoritative write.
|
|
588
|
+
*/
|
|
589
|
+
private _stampRank;
|
|
547
590
|
private _codecFor;
|
|
548
591
|
private _policyFor;
|
|
549
592
|
/**
|
|
@@ -720,8 +763,8 @@ export declare interface IBodyConverterRegistry {
|
|
|
720
763
|
* @public
|
|
721
764
|
*/
|
|
722
765
|
export declare interface ICandidateEdge {
|
|
723
|
-
/** The reference
|
|
724
|
-
readonly source:
|
|
766
|
+
/** The scope-qualified reference (codec `(scope, idStem)`) of the candidate the edge originates from. */
|
|
767
|
+
readonly source: IEdgeTarget;
|
|
725
768
|
/** The attributed edge (type / target / optional confidence / provenance). */
|
|
726
769
|
readonly edge: IEdge;
|
|
727
770
|
}
|
|
@@ -792,31 +835,47 @@ export declare interface ICreateMemoryToolsParams {
|
|
|
792
835
|
* {@link MemoryId} is used.
|
|
793
836
|
*/
|
|
794
837
|
readonly handleFor?: (record: IMemoryRecord<unknown>) => string;
|
|
838
|
+
/**
|
|
839
|
+
* Optional host projector mapping a record (and the requested detail tier) to
|
|
840
|
+
* its agent-visible {@link IMemoryToolResultItem}. When supplied, every
|
|
841
|
+
* `memory_search` / `memory_context` / `memory_read` result item is produced by
|
|
842
|
+
* this callback — the host owns how much of the body a `'gist'` vs `'full'`
|
|
843
|
+
* result carries, so it can bound the default (`'gist'`) path.
|
|
844
|
+
*
|
|
845
|
+
* When absent, the built-in default projection is used (full body plus the
|
|
846
|
+
* {@link ICreateMemoryToolsParams.handleFor | handleFor} handle), which ignores
|
|
847
|
+
* the detail tier — behavior is byte-identical to a build with no projector.
|
|
848
|
+
*
|
|
849
|
+
* The callback is guarded exactly like `handleFor`: a throw degrades to the
|
|
850
|
+
* default full-body projection for that item rather than failing the whole
|
|
851
|
+
* search.
|
|
852
|
+
*/
|
|
853
|
+
readonly projectItem?: (record: IMemoryRecord<unknown>, detail: MemoryDetailTier) => IMemoryToolResultItem;
|
|
795
854
|
}
|
|
796
855
|
|
|
797
856
|
/**
|
|
798
|
-
* A directed edge in the link graph the cycle guard reasons over:
|
|
799
|
-
* to `target` under relation `type`.
|
|
857
|
+
* A directed edge in the link graph the cycle guard reasons over: scope-qualified
|
|
858
|
+
* `source` links to scope-qualified `target` under relation `type`.
|
|
800
859
|
* @public
|
|
801
860
|
*/
|
|
802
861
|
export declare interface ICycleGuardEdge {
|
|
803
|
-
readonly source:
|
|
804
|
-
readonly target:
|
|
862
|
+
readonly source: IEdgeTarget;
|
|
863
|
+
readonly target: IEdgeTarget;
|
|
805
864
|
readonly type: LinkType;
|
|
806
865
|
}
|
|
807
866
|
|
|
808
867
|
/**
|
|
809
868
|
* An attributed link between two records. Carries the relation type, the
|
|
810
|
-
* target
|
|
811
|
-
* Replaces bare string references (e.g.
|
|
812
|
-
* `IEdge` with `type: LinkType('mtm-ref')`).
|
|
869
|
+
* scope-qualified {@link IEdgeTarget | target}, and optional confidence /
|
|
870
|
+
* provenance / world-truth validity. Replaces bare string references (e.g.
|
|
871
|
+
* PersonAIlity's `IMtmRef` becomes an `IEdge` with `type: LinkType('mtm-ref')`).
|
|
813
872
|
* @public
|
|
814
873
|
*/
|
|
815
874
|
export declare interface IEdge {
|
|
816
875
|
/** Open-vocabulary relation type. */
|
|
817
876
|
readonly type: LinkType;
|
|
818
|
-
/** The linked-to record. */
|
|
819
|
-
readonly target:
|
|
877
|
+
/** The scope-qualified address of the linked-to record. */
|
|
878
|
+
readonly target: IEdgeTarget;
|
|
820
879
|
/** Optional confidence in `[0, 1]`. */
|
|
821
880
|
readonly confidence?: number;
|
|
822
881
|
/** Optional structured provenance for the link itself. */
|
|
@@ -830,6 +889,23 @@ export declare interface IEdge {
|
|
|
830
889
|
readonly invalid_at?: number | null;
|
|
831
890
|
}
|
|
832
891
|
|
|
892
|
+
/**
|
|
893
|
+
* The physical address of a linked-to record: the `(scope, id)` pair that
|
|
894
|
+
* uniquely identifies it. Both components are required because a bare
|
|
895
|
+
* {@link MemoryId} is NOT unique across scopes — per-scope codecs (e.g. the
|
|
896
|
+
* medium-term codec's `turn-<n>` stems) legally mint the same stem under
|
|
897
|
+
* different scopes, so an edge that carried only the id would be ambiguous.
|
|
898
|
+
* `(scope, id)` matches the store's `getById(scope, id)` addressing and the
|
|
899
|
+
* index's composite primary key.
|
|
900
|
+
* @public
|
|
901
|
+
*/
|
|
902
|
+
export declare interface IEdgeTarget {
|
|
903
|
+
/** The scope the target record lives under. */
|
|
904
|
+
readonly scope: MemoryScopeKey;
|
|
905
|
+
/** The target record's stable file-stem id (unique WITHIN {@link IEdgeTarget.scope}). */
|
|
906
|
+
readonly id: MemoryId;
|
|
907
|
+
}
|
|
908
|
+
|
|
833
909
|
/**
|
|
834
910
|
* A near-duplicate candidate surfaced to the {@link IEntityResolver} by stage-4
|
|
835
911
|
* layer-2 similarity search: an existing record whose embedding is within the
|
|
@@ -837,8 +913,14 @@ export declare interface IEdge {
|
|
|
837
913
|
* @public
|
|
838
914
|
*/
|
|
839
915
|
export declare interface IEntityResolutionCandidate {
|
|
840
|
-
/**
|
|
841
|
-
|
|
916
|
+
/**
|
|
917
|
+
* The existing record's scope-qualified `(scope, id)` address. Scope-qualified
|
|
918
|
+
* (not a bare {@link MemoryId}) because per-scope codecs legally mint the same
|
|
919
|
+
* stem under different scopes — the {@link ResolutionVerdict} target the resolver
|
|
920
|
+
* returns must round-trip this exact address so the write binds the intended
|
|
921
|
+
* record.
|
|
922
|
+
*/
|
|
923
|
+
readonly target: IEdgeTarget;
|
|
842
924
|
/** The existing record. */
|
|
843
925
|
readonly record: IMemoryRecord<unknown>;
|
|
844
926
|
/** The backend similarity score (higher = more similar). */
|
|
@@ -891,6 +973,19 @@ export declare interface IFileTreeMemoryStoreCreateParams {
|
|
|
891
973
|
readonly writePolicies?: ReadonlyMap<Kind, IWritePolicy>;
|
|
892
974
|
/** Per-kind identity codecs. */
|
|
893
975
|
readonly codecs?: ReadonlyMap<Kind, IIdentityCodec>;
|
|
976
|
+
/**
|
|
977
|
+
* Optional per-kind host projector map. When a kind has an entry, the store
|
|
978
|
+
* runs the projector on the fully-resolved (post-merge) record on every put
|
|
979
|
+
* AND every update — in the same pass that recomputes `contentHash` — and
|
|
980
|
+
* stamps the numeric result into {@link IMemoryEnvelope.rank}, which the index's
|
|
981
|
+
* rank view and `orderBy: 'rank'` retrieval sort by (descending, absent last).
|
|
982
|
+
* Absent for a kind → that kind's records carry no `rank`. Purely additive and
|
|
983
|
+
* zero-overhead when unwired: an absent map leaves every write byte-identical.
|
|
984
|
+
* The projector is a host callback — a throw is logged at `warn` and the record
|
|
985
|
+
* is stamped with no `rank`, never failing the write (mirrors the store's other
|
|
986
|
+
* guard-host-callbacks conventions).
|
|
987
|
+
*/
|
|
988
|
+
readonly rankProjectors?: ReadonlyMap<Kind, RankProjector>;
|
|
894
989
|
/** Default codec for kinds without an explicit entry. */
|
|
895
990
|
readonly defaultCodec?: IIdentityCodec;
|
|
896
991
|
/** Scope encoding. Defaults to {@link defaultMemoryScopeEncoding}. */
|
|
@@ -1054,12 +1149,15 @@ export declare interface IIngestItem {
|
|
|
1054
1149
|
*/
|
|
1055
1150
|
readonly content: unknown;
|
|
1056
1151
|
/**
|
|
1057
|
-
* Optional back-link to the memory record this item was derived
|
|
1058
|
-
* MTM turn an extracted fact came from). When present, fgv stamps
|
|
1059
|
-
* {@link IProvenance.derivedFrom | provenance.derivedFrom} on every record
|
|
1060
|
-
* ingested from this item (stage 6) — the cross-kind provenance spine.
|
|
1152
|
+
* Optional scope-qualified back-link to the memory record this item was derived
|
|
1153
|
+
* from (e.g. the MTM turn an extracted fact came from). When present, fgv stamps
|
|
1154
|
+
* it as {@link IProvenance.derivedFrom | provenance.derivedFrom} on every record
|
|
1155
|
+
* ingested from this item (stage 6) — the cross-kind provenance spine. A
|
|
1156
|
+
* scope-qualified {@link IEdgeTarget} (not a bare {@link MemoryId}) because
|
|
1157
|
+
* per-scope codecs legally reuse a stem across scopes, so a bare id would be
|
|
1158
|
+
* ambiguous.
|
|
1061
1159
|
*/
|
|
1062
|
-
readonly sourceId?:
|
|
1160
|
+
readonly sourceId?: IEdgeTarget;
|
|
1063
1161
|
/** Optional opaque metadata carried alongside the item; never interpreted by fgv. */
|
|
1064
1162
|
readonly metadata?: Record<string, unknown>;
|
|
1065
1163
|
}
|
|
@@ -1161,6 +1259,15 @@ export declare interface IMemoryEnvelope {
|
|
|
1161
1259
|
* an exact match is a no-op upsert that returns the existing record.
|
|
1162
1260
|
*/
|
|
1163
1261
|
readonly contentHash: string;
|
|
1262
|
+
/**
|
|
1263
|
+
* Store-computed host-defined ordering value, produced by the kind's
|
|
1264
|
+
* {@link RankProjector} on every put/update and stamped into the envelope in
|
|
1265
|
+
* the same pass that recomputes {@link IMemoryEnvelope.contentHash | contentHash}.
|
|
1266
|
+
* Absent when the kind has no registered projector (or the projector threw on
|
|
1267
|
+
* this record). Ordered retrieval (`orderBy: 'rank'`) and the index's rank view
|
|
1268
|
+
* sort by this value descending, placing records with an absent `rank` last.
|
|
1269
|
+
*/
|
|
1270
|
+
readonly rank?: number;
|
|
1164
1271
|
/** Structured provenance (never a flat enum). */
|
|
1165
1272
|
readonly provenance: IProvenance;
|
|
1166
1273
|
/** Bi-temporal validity. Present only on temporal kinds. */
|
|
@@ -1218,10 +1325,20 @@ export declare interface IMemoryIndex {
|
|
|
1218
1325
|
/** All records in recency order (most-recently-updated first). */
|
|
1219
1326
|
byRecency(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
1220
1327
|
/**
|
|
1221
|
-
*
|
|
1222
|
-
*
|
|
1328
|
+
* All records ordered by store-computed {@link IMemoryEnvelope.rank} descending,
|
|
1329
|
+
* with recency (most-recently-updated, then `seq`) as a tiebreak. Records with
|
|
1330
|
+
* an absent `rank` sort LAST (after every ranked record), then by recency among
|
|
1331
|
+
* themselves. Serves a bounded top-M ({@link IMemoryEnvelope.rank}-ordered) page
|
|
1332
|
+
* from the in-memory index with no full-vault (filesystem) scan.
|
|
1223
1333
|
*/
|
|
1224
|
-
|
|
1334
|
+
byRank(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
1335
|
+
/**
|
|
1336
|
+
* The scope-qualified sources of records whose `links` point AT `target`
|
|
1337
|
+
* (inbound edges), keyed on the target's `(scope, id)` address. The seed map
|
|
1338
|
+
* for B2 link-traversal; results are {@link IEdgeTarget}s so a caller can feed
|
|
1339
|
+
* them straight back in as further traversal seeds.
|
|
1340
|
+
*/
|
|
1341
|
+
backlinks(target: IEdgeTarget): ReadonlyArray<IEdgeTarget>;
|
|
1225
1342
|
}
|
|
1226
1343
|
|
|
1227
1344
|
/**
|
|
@@ -1409,12 +1526,24 @@ export declare interface IMemoryQuery {
|
|
|
1409
1526
|
readonly scope?: MemoryScopeKey;
|
|
1410
1527
|
/** Restrict to records carrying this tag (exact match). */
|
|
1411
1528
|
readonly tag?: Tag;
|
|
1412
|
-
/**
|
|
1529
|
+
/**
|
|
1530
|
+
* Restrict to records of this kind — the single-kind shorthand for
|
|
1531
|
+
* {@link IMemoryQuery.kinds | kinds}. When both are set they compose as AND
|
|
1532
|
+
* (the record's kind must satisfy both), so `kind` must itself be a member of
|
|
1533
|
+
* `kinds` for anything to match.
|
|
1534
|
+
*/
|
|
1413
1535
|
readonly kind?: Kind;
|
|
1414
|
-
/**
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1536
|
+
/**
|
|
1537
|
+
* Restrict to records in ANY of these kinds — the general (multi-kind) form of
|
|
1538
|
+
* {@link IMemoryQuery.kind | kind}. Absent → no kind-set constraint (today's
|
|
1539
|
+
* behavior). An explicit empty array `[]` matches NOTHING (mirroring the
|
|
1540
|
+
* non-positive-`limit` "explicit empty" convention), never "match all".
|
|
1541
|
+
*/
|
|
1542
|
+
readonly kinds?: ReadonlyArray<Kind>;
|
|
1543
|
+
/** Restrict to records linked FROM this scope-qualified seed (outbound). */
|
|
1544
|
+
readonly linkedFrom?: IEdgeTarget;
|
|
1545
|
+
/** Restrict to records linked TO this scope-qualified seed (inbound / backlinks). */
|
|
1546
|
+
readonly linkedTo?: IEdgeTarget;
|
|
1418
1547
|
/** BFS hop count for link traversal. Default: 1. */
|
|
1419
1548
|
readonly hops?: number;
|
|
1420
1549
|
/**
|
|
@@ -1431,8 +1560,32 @@ export declare interface IMemoryQuery {
|
|
|
1431
1560
|
* `Result.fail` — never a silent empty.
|
|
1432
1561
|
*/
|
|
1433
1562
|
readonly asOf?: number;
|
|
1563
|
+
/**
|
|
1564
|
+
* Ordering for the result set. `'recency'` (the default when absent — today's
|
|
1565
|
+
* exact behavior) orders most-recently-updated first; `'rank'` orders by the
|
|
1566
|
+
* store-computed {@link IMemoryEnvelope.rank} descending (records with an absent
|
|
1567
|
+
* `rank` last), with recency as the tiebreak. Combined with `{ limit, offset }`
|
|
1568
|
+
* this yields a bounded top-M rank-ordered page with no full-vault scan.
|
|
1569
|
+
*
|
|
1570
|
+
* @remarks
|
|
1571
|
+
* `orderBy` governs the ordered non-semantic retrievers (recency / tag /
|
|
1572
|
+
* structured-filter / link-traversal) and the {@link HybridRetriever}'s
|
|
1573
|
+
* post-merge ordering. The {@link SemanticRetriever} is the sole exception: it
|
|
1574
|
+
* preserves its native vector-similarity order regardless of `orderBy` —
|
|
1575
|
+
* re-sorting semantic hits by `rank` would discard the similarity ranking that
|
|
1576
|
+
* is the whole point of that path; a consumer that wants rank ordering uses a
|
|
1577
|
+
* non-semantic query.
|
|
1578
|
+
*/
|
|
1579
|
+
readonly orderBy?: 'recency' | 'rank';
|
|
1434
1580
|
/** Maximum records to return. Applied after all other filters. */
|
|
1435
1581
|
readonly limit?: number;
|
|
1582
|
+
/**
|
|
1583
|
+
* Records to skip after ordering, before `limit` — so `{ offset, limit }` is a
|
|
1584
|
+
* stable page window over the ordered result set. Default 0. A non-positive or
|
|
1585
|
+
* absent offset is today's behavior (no skip); an offset past the end yields an
|
|
1586
|
+
* empty page, never a throw.
|
|
1587
|
+
*/
|
|
1588
|
+
readonly offset?: number;
|
|
1436
1589
|
/** Arbitrary predicate applied after the scope / kind / tag pre-filter. */
|
|
1437
1590
|
readonly filter?: (record: IMemoryRecord<unknown>) => boolean;
|
|
1438
1591
|
}
|
|
@@ -1453,16 +1606,17 @@ export declare interface IMemoryRecord<TBody = unknown> {
|
|
|
1453
1606
|
|
|
1454
1607
|
/**
|
|
1455
1608
|
* The minimal record-source surface {@link InMemoryCosineIndex.rebuild} reads to
|
|
1456
|
-
* re-embed an entire vault.
|
|
1457
|
-
*
|
|
1458
|
-
*
|
|
1459
|
-
*
|
|
1460
|
-
* for {@link IVectorIndex}, so the reverse
|
|
1609
|
+
* re-embed an entire vault. Each entry carries the record's scope-qualified
|
|
1610
|
+
* address (see {@link IScopedMemoryRecord}) so the rebuild keys the vector index
|
|
1611
|
+
* exactly as the incremental embed-on-write path does. A consumer backs this with
|
|
1612
|
+
* the store's scoped index — the vector packlet does not import the store packlet
|
|
1613
|
+
* (which depends on the vector packlet for {@link IVectorIndex}, so the reverse
|
|
1614
|
+
* import would be a cycle).
|
|
1461
1615
|
* @public
|
|
1462
1616
|
*/
|
|
1463
1617
|
export declare interface IMemoryRecordSource {
|
|
1464
|
-
/** List every record in the vault. */
|
|
1465
|
-
list(): Promise<Result<ReadonlyArray<
|
|
1618
|
+
/** List every record in the vault, each paired with its scoped address. */
|
|
1619
|
+
list(): Promise<Result<ReadonlyArray<IScopedMemoryRecord>>>;
|
|
1466
1620
|
}
|
|
1467
1621
|
|
|
1468
1622
|
/**
|
|
@@ -1519,6 +1673,24 @@ export declare interface IMemoryStore {
|
|
|
1519
1673
|
* List records, filtered in-memory over the derived index.
|
|
1520
1674
|
*/
|
|
1521
1675
|
list(filter?: IMemoryStoreListFilter): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>>;
|
|
1676
|
+
/**
|
|
1677
|
+
* List EVERY record in the vault, each paired with its scope-qualified
|
|
1678
|
+
* `(scope, id)` address — the projection {@link IMemoryRecordSource} requires.
|
|
1679
|
+
* Unlike {@link IMemoryStore.list | list}, it takes no filter (whole-vault) and
|
|
1680
|
+
* returns {@link IScopedMemoryRecord}s so a re-index keys each entry on the same
|
|
1681
|
+
* scoped target the incremental embed-on-write path uses. Two records that share
|
|
1682
|
+
* a filename stem across scopes appear as distinct entries.
|
|
1683
|
+
*/
|
|
1684
|
+
listScoped(): Promise<Result<ReadonlyArray<IScopedMemoryRecord>>>;
|
|
1685
|
+
/**
|
|
1686
|
+
* Adapt this store to the {@link IMemoryRecordSource} seam so it can drive
|
|
1687
|
+
* {@link IVectorIndex} rebuilds (e.g. `InMemoryCosineIndex.rebuild`). The
|
|
1688
|
+
* returned source's `list()` delegates to {@link IMemoryStore.listScoped}. The
|
|
1689
|
+
* store cannot implement {@link IMemoryRecordSource} directly because its
|
|
1690
|
+
* `list(filter?)` returns bare records (the ergonomic query surface) while the
|
|
1691
|
+
* seam's `list()` returns scope-qualified records.
|
|
1692
|
+
*/
|
|
1693
|
+
asRecordSource(): IMemoryRecordSource;
|
|
1522
1694
|
/**
|
|
1523
1695
|
* Write a record. Validates the body, computes a content hash, deduplicates
|
|
1524
1696
|
* (scope-wide, before policy), applies the kind's {@link IWritePolicy}, stamps
|
|
@@ -1649,6 +1821,11 @@ export declare type IngestDisposition = 'written' | 'deduped' | 'merged';
|
|
|
1649
1821
|
* @public
|
|
1650
1822
|
*/
|
|
1651
1823
|
export declare class InMemoryCosineIndex implements IVectorIndex {
|
|
1824
|
+
/**
|
|
1825
|
+
* Stored embeddings keyed by the canonical {@link edgeTargetKey} of the
|
|
1826
|
+
* record's scope-qualified address, so two records that share a filename stem
|
|
1827
|
+
* across scopes occupy distinct entries and never overwrite each other.
|
|
1828
|
+
*/
|
|
1652
1829
|
private readonly _vectors;
|
|
1653
1830
|
/** The dimension of every stored vector; `undefined` until the first `add`. */
|
|
1654
1831
|
private _dimension;
|
|
@@ -1658,9 +1835,9 @@ export declare class InMemoryCosineIndex implements IVectorIndex {
|
|
|
1658
1835
|
/** Family-convention factory. */
|
|
1659
1836
|
static create(): Result<InMemoryCosineIndex>;
|
|
1660
1837
|
/** {@inheritDoc IVectorIndex.add} */
|
|
1661
|
-
add(
|
|
1838
|
+
add(target: IEdgeTarget, vector: Float32Array): Promise<Result<string>>;
|
|
1662
1839
|
/** {@inheritDoc IVectorIndex.remove} */
|
|
1663
|
-
remove(
|
|
1840
|
+
remove(target: IEdgeTarget): Promise<Result<IEdgeTarget>>;
|
|
1664
1841
|
/** {@inheritDoc IVectorIndex.query} */
|
|
1665
1842
|
query(vector: Float32Array, topK: number): Promise<Result<ReadonlyArray<IVectorQueryHit>>>;
|
|
1666
1843
|
/**
|
|
@@ -1673,8 +1850,7 @@ export declare class InMemoryCosineIndex implements IVectorIndex {
|
|
|
1673
1850
|
* rather than left in a partially-rebuilt state — a caller that retries a query
|
|
1674
1851
|
* after a failed rebuild sees a clean empty index, never a half-populated one.
|
|
1675
1852
|
*
|
|
1676
|
-
* @param source - The record source to re-embed
|
|
1677
|
-
* satisfies this structurally).
|
|
1853
|
+
* @param source - The scope-qualified record source to re-embed.
|
|
1678
1854
|
* @param embed - The embedder applied to each record.
|
|
1679
1855
|
*/
|
|
1680
1856
|
rebuild(source: IMemoryRecordSource, embed: MemoryEmbedder): Promise<Result<number>>;
|
|
@@ -1707,8 +1883,14 @@ export declare interface IProvenance {
|
|
|
1707
1883
|
readonly model?: string;
|
|
1708
1884
|
/** Optional confidence in `[0, 1]`. */
|
|
1709
1885
|
readonly confidence?: number;
|
|
1710
|
-
/**
|
|
1711
|
-
|
|
1886
|
+
/**
|
|
1887
|
+
* Scope-qualified back-link to the source record. Enables the cross-kind
|
|
1888
|
+
* provenance spine. A scope-qualified {@link IEdgeTarget} (not a bare
|
|
1889
|
+
* {@link MemoryId}) because per-scope codecs (e.g. the MTM codec's `turn-<n>`
|
|
1890
|
+
* stems) legally reuse a stem across scopes, so a bare id would be ambiguous —
|
|
1891
|
+
* the same reason {@link IEdge.target} is scope-qualified.
|
|
1892
|
+
*/
|
|
1893
|
+
readonly derivedFrom?: IEdgeTarget;
|
|
1712
1894
|
/** Opaque extension payload — consumer-owned, never interpreted by the store. */
|
|
1713
1895
|
readonly [key: string]: unknown;
|
|
1714
1896
|
}
|
|
@@ -1721,8 +1903,8 @@ export declare interface IProvenance {
|
|
|
1721
1903
|
export declare interface IRelationCandidate {
|
|
1722
1904
|
/** The candidate about to be written. */
|
|
1723
1905
|
readonly candidate: ICandidateRecord;
|
|
1724
|
-
/** Its resolved reference
|
|
1725
|
-
readonly id:
|
|
1906
|
+
/** Its resolved scope-qualified reference (codec `(scope, idStem)` — the stable entity address). */
|
|
1907
|
+
readonly id: IEdgeTarget;
|
|
1726
1908
|
}
|
|
1727
1909
|
|
|
1728
1910
|
/**
|
|
@@ -1755,6 +1937,21 @@ export declare interface IRelationExtractor {
|
|
|
1755
1937
|
relate(context: IRelationContext): Promise<Result<ReadonlyArray<ICandidateEdge>>>;
|
|
1756
1938
|
}
|
|
1757
1939
|
|
|
1940
|
+
/**
|
|
1941
|
+
* A record paired with its scope-qualified {@link IEdgeTarget | address}, as
|
|
1942
|
+
* yielded by {@link IMemoryRecordSource.list}. The address is required because
|
|
1943
|
+
* {@link InMemoryCosineIndex.rebuild} keys each re-embedded entry on the
|
|
1944
|
+
* scope-qualified target, not a bare {@link MemoryId} — two records that share a
|
|
1945
|
+
* filename stem across scopes must not collide when the whole vault is re-indexed.
|
|
1946
|
+
* @public
|
|
1947
|
+
*/
|
|
1948
|
+
export declare interface IScopedMemoryRecord {
|
|
1949
|
+
/** The record's scope-qualified `(scope, id)` address. */
|
|
1950
|
+
readonly target: IEdgeTarget;
|
|
1951
|
+
/** The record itself, passed to the embedder. */
|
|
1952
|
+
readonly record: IMemoryRecord<unknown>;
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1758
1955
|
/**
|
|
1759
1956
|
* The semantic backend wired into a {@link SemanticRetriever}: the vector index
|
|
1760
1957
|
* to query and the embedder that turns the query text into a vector. Both are
|
|
@@ -1884,16 +2081,19 @@ export declare interface ITemporalVersionAddress {
|
|
|
1884
2081
|
*/
|
|
1885
2082
|
export declare interface IVectorIndex {
|
|
1886
2083
|
/**
|
|
1887
|
-
* Add (or replace) the embedding for `
|
|
1888
|
-
* {@link IMemoryEnvelope.embeddingRef | embeddingRef} the store stamps
|
|
1889
|
-
* the envelope so a later read knows the record is embedded.
|
|
2084
|
+
* Add (or replace) the embedding for the scope-qualified `target`. Returns the
|
|
2085
|
+
* opaque {@link IMemoryEnvelope.embeddingRef | embeddingRef} the store stamps
|
|
2086
|
+
* onto the envelope so a later read knows the record is embedded. Keying on the
|
|
2087
|
+
* `(scope, id)` address (not a bare id) is load-bearing: two records that share
|
|
2088
|
+
* a filename stem across scopes must not clobber each other's embedding.
|
|
1890
2089
|
*/
|
|
1891
|
-
add(
|
|
2090
|
+
add(target: IEdgeTarget, vector: Float32Array): Promise<Result<string>>;
|
|
1892
2091
|
/**
|
|
1893
|
-
* Remove the embedding for `
|
|
1894
|
-
*
|
|
2092
|
+
* Remove the embedding for the scope-qualified `target`. Returns the removed
|
|
2093
|
+
* target. Idempotent — removing a target with no embedding still succeeds
|
|
2094
|
+
* (returns the target).
|
|
1895
2095
|
*/
|
|
1896
|
-
remove(
|
|
2096
|
+
remove(target: IEdgeTarget): Promise<Result<IEdgeTarget>>;
|
|
1897
2097
|
/**
|
|
1898
2098
|
* Return the `topK` nearest records to `vector`, in descending score order.
|
|
1899
2099
|
*/
|
|
@@ -1901,14 +2101,22 @@ export declare interface IVectorIndex {
|
|
|
1901
2101
|
}
|
|
1902
2102
|
|
|
1903
2103
|
/**
|
|
1904
|
-
* A single hit returned by {@link IVectorIndex.query}: the matched record
|
|
1905
|
-
*
|
|
1906
|
-
* backend-defined). Hits are
|
|
2104
|
+
* A single hit returned by {@link IVectorIndex.query}: the matched record's
|
|
2105
|
+
* scope-qualified {@link IEdgeTarget | address} and the backend's similarity
|
|
2106
|
+
* score (higher = more similar; the exact scale is backend-defined). Hits are
|
|
2107
|
+
* returned in descending score order.
|
|
2108
|
+
*
|
|
2109
|
+
* @remarks
|
|
2110
|
+
* The address is a `(scope, id)` pair, NOT a bare {@link MemoryId} — per-scope
|
|
2111
|
+
* codecs (e.g. the medium-term codec's `turn-<n>` stems) legally mint the same
|
|
2112
|
+
* stem under different scopes, so a bare id could not disambiguate two records
|
|
2113
|
+
* that share a stem. The caller re-resolves the hit against the record index by
|
|
2114
|
+
* the same scoped address.
|
|
1907
2115
|
* @public
|
|
1908
2116
|
*/
|
|
1909
2117
|
export declare interface IVectorQueryHit {
|
|
1910
|
-
/** The
|
|
1911
|
-
readonly
|
|
2118
|
+
/** The scope-qualified address of the matched record. */
|
|
2119
|
+
readonly target: IEdgeTarget;
|
|
1912
2120
|
/** Backend similarity score; higher is more similar. */
|
|
1913
2121
|
readonly score: number;
|
|
1914
2122
|
}
|
|
@@ -2056,13 +2264,21 @@ export declare class KnowledgeLwwPolicy implements IWritePolicy {
|
|
|
2056
2264
|
}
|
|
2057
2265
|
|
|
2058
2266
|
/**
|
|
2059
|
-
*
|
|
2060
|
-
* last, after ordering, so it always takes
|
|
2061
|
-
*
|
|
2062
|
-
*
|
|
2267
|
+
* Apply the `{ offset, limit }` page window to an ordered record set. Applied
|
|
2268
|
+
* last, after ordering, so it always takes a stable window of the ordered
|
|
2269
|
+
* result. `offset` is applied first (records to skip), then `limit` (top-N of
|
|
2270
|
+
* the remainder).
|
|
2271
|
+
*
|
|
2272
|
+
* @remarks
|
|
2273
|
+
* Both bounds are public query input and are guarded against non-positive
|
|
2274
|
+
* values slipping into `slice`:
|
|
2275
|
+
* - `offset` absent or non-positive → no skip (today's behavior). An offset past
|
|
2276
|
+
* the end yields an empty page rather than a throw.
|
|
2277
|
+
* - `limit` absent → no truncation; a non-positive `limit` means "no records"
|
|
2278
|
+
* and returns an empty array.
|
|
2063
2279
|
* @public
|
|
2064
2280
|
*/
|
|
2065
|
-
export declare function limitRecords(records: ReadonlyArray<IMemoryRecord<unknown>>, limit?: number): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
2281
|
+
export declare function limitRecords(records: ReadonlyArray<IMemoryRecord<unknown>>, limit?: number, offset?: number): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
2066
2282
|
|
|
2067
2283
|
/**
|
|
2068
2284
|
* The loud-degradation message returned when a link-traversal query supplies no
|
|
@@ -2080,20 +2296,23 @@ export declare const LINK_TRAVERSAL_NO_SEED_MESSAGE: string;
|
|
|
2080
2296
|
export declare const LINK_TRAVERSAL_UNWIRED_MESSAGE: string;
|
|
2081
2297
|
|
|
2082
2298
|
/**
|
|
2083
|
-
* Breadth-first link-traversal retriever. From a
|
|
2084
|
-
* the link graph up to `query.hops` levels and
|
|
2085
|
-
* (excluding the seed), recency-ordered and limited.
|
|
2299
|
+
* Breadth-first link-traversal retriever. From a scope-qualified
|
|
2300
|
+
* {@link IEdgeTarget} seed it walks the link graph up to `query.hops` levels and
|
|
2301
|
+
* returns the records reached (excluding the seed), recency-ordered and limited.
|
|
2086
2302
|
*
|
|
2087
2303
|
* @remarks
|
|
2088
2304
|
* - **Direction.** `linkedFrom` walks OUTBOUND edges (each record's
|
|
2089
2305
|
* `envelope.links[].target`); `linkedTo` walks INBOUND edges (the index's
|
|
2090
2306
|
* `backlinks`). Exactly one is the seed; `linkedFrom` wins if both are set.
|
|
2307
|
+
* - **Scope-qualified nodes.** Every graph node is an {@link IEdgeTarget}
|
|
2308
|
+
* `(scope, id)` pair, so following an edge to `turn-3` reaches ONLY the record
|
|
2309
|
+
* in the edge's own scope — never a same-stem record in another scope.
|
|
2091
2310
|
* - **Bound + cycle safety.** Traversal is bounded by `hops` (default `1` — a
|
|
2092
|
-
* single hop) and a visited-set guard.
|
|
2093
|
-
* string {@link
|
|
2094
|
-
* collision-free cycle key — no structural hashing (e.g.
|
|
2095
|
-
* needed. A self-loop or any multi-hop cycle terminates
|
|
2096
|
-
* is never re-expanded.
|
|
2311
|
+
* single hop) and a visited-set guard. Nodes are canonicalized to their
|
|
2312
|
+
* `(scope, id)` string via {@link edgeTargetKey}, so a `Set<string>` visited-set
|
|
2313
|
+
* is the exact, collision-free cycle key — no structural hashing (e.g.
|
|
2314
|
+
* `Crc32Normalizer`) is needed. A self-loop or any multi-hop cycle terminates
|
|
2315
|
+
* because a revisited node is never re-expanded.
|
|
2097
2316
|
* - **Post-filter.** The scope / kind / tag / predicate axes of the query are
|
|
2098
2317
|
* applied to the reached records (the link axes are the traversal itself).
|
|
2099
2318
|
* @public
|
|
@@ -2110,23 +2329,15 @@ export declare class LinkTraversalRetriever implements IMemoryRetriever {
|
|
|
2110
2329
|
/** Run the bounded, cycle-safe BFS and post-filter the reached records. */
|
|
2111
2330
|
private _traverse;
|
|
2112
2331
|
/**
|
|
2113
|
-
* Group the index's entries by
|
|
2114
|
-
*
|
|
2115
|
-
* two
|
|
2116
|
-
*
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
* traversal resolves a target across ALL scopes that hold that id. When two
|
|
2121
|
-
* scopes reuse a stem, following an edge to it reaches every match. This
|
|
2122
|
-
* mirrors the `backlinks` index, which is also keyed by bare id. Scope-
|
|
2123
|
-
* qualified link resolution is intentionally out of scope for Phase C and
|
|
2124
|
-
* would be an additive change here (and to {@link IEdge} / the index).
|
|
2125
|
-
*/
|
|
2126
|
-
private _indexById;
|
|
2127
|
-
/** Outbound neighbors: the targets of every edge on the records with this id. */
|
|
2332
|
+
* Group the index's entries by their scope-qualified {@link edgeTargetKey}
|
|
2333
|
+
* `(scope, id)` composite. Each composite is the index's primary key, so it maps
|
|
2334
|
+
* to exactly one entry — two records that reuse a filename stem across scopes
|
|
2335
|
+
* (e.g. `turn-0` in two conversations) get distinct keys and never collide.
|
|
2336
|
+
*/
|
|
2337
|
+
private _indexByKey;
|
|
2338
|
+
/** Outbound neighbors: the scope-qualified targets of every edge on the record at `node`. */
|
|
2128
2339
|
private _outbound;
|
|
2129
|
-
/** Inbound neighbors: the
|
|
2340
|
+
/** Inbound neighbors: the scope-qualified sources whose edges point AT `node` (the backlinks). */
|
|
2130
2341
|
private _inbound;
|
|
2131
2342
|
}
|
|
2132
2343
|
|
|
@@ -2216,6 +2427,15 @@ export declare class MemoryCapCullPolicy implements IWritePolicy {
|
|
|
2216
2427
|
private _rebuild;
|
|
2217
2428
|
}
|
|
2218
2429
|
|
|
2430
|
+
/**
|
|
2431
|
+
* The detail tier a `memory_search` / `memory_context` result is projected at.
|
|
2432
|
+
* `'gist'` is the default (bounded) path; `'full'` is opt-in. Only meaningful
|
|
2433
|
+
* when a host {@link ICreateMemoryToolsParams.projectItem | projectItem} is
|
|
2434
|
+
* supplied — the built-in default projection returns the full body regardless.
|
|
2435
|
+
* @public
|
|
2436
|
+
*/
|
|
2437
|
+
export declare type MemoryDetailTier = 'gist' | 'full';
|
|
2438
|
+
|
|
2219
2439
|
/**
|
|
2220
2440
|
* Embeds a complete record into a vector for the store's embed-on-write hook.
|
|
2221
2441
|
* Async and `Result`-returning, since a real embedder does a network call (cloud
|
|
@@ -2248,10 +2468,13 @@ export declare class MemoryIndex implements IMemoryIndex {
|
|
|
2248
2468
|
/** tag → set of composite keys. */
|
|
2249
2469
|
private readonly _byTag;
|
|
2250
2470
|
/**
|
|
2251
|
-
*
|
|
2252
|
-
*
|
|
2253
|
-
*
|
|
2254
|
-
*
|
|
2471
|
+
* canonical target key (`edgeTargetKey`) → (source composite key → source
|
|
2472
|
+
* {@link IEdgeTarget}). The OUTER map is keyed on the scope-qualified target's
|
|
2473
|
+
* canonical `(scope, id)` string — NOT the target's bare id — so an edge to
|
|
2474
|
+
* `turn-3` in one conversation is tracked separately from `turn-3` in another.
|
|
2475
|
+
* The INNER map is keyed by the source's `(scope, id)` composite so two distinct
|
|
2476
|
+
* source records that share an id across scopes are tracked independently and
|
|
2477
|
+
* removing one never drops the other's edge.
|
|
2255
2478
|
*/
|
|
2256
2479
|
private readonly _backlinks;
|
|
2257
2480
|
private constructor();
|
|
@@ -2276,19 +2499,38 @@ export declare class MemoryIndex implements IMemoryIndex {
|
|
|
2276
2499
|
byTag(tag: Tag): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
2277
2500
|
/** {@inheritDoc IMemoryIndex.byRecency} */
|
|
2278
2501
|
byRecency(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
2502
|
+
/** {@inheritDoc IMemoryIndex.byRank} */
|
|
2503
|
+
byRank(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
2279
2504
|
/** {@inheritDoc IMemoryIndex.backlinks} */
|
|
2280
|
-
backlinks(target:
|
|
2505
|
+
backlinks(target: IEdgeTarget): ReadonlyArray<IEdgeTarget>;
|
|
2281
2506
|
/**
|
|
2282
2507
|
* Resolve a set of composite keys to their records, ordered
|
|
2283
2508
|
* most-recently-updated first (with a `seq` tiebreak so equal-`updated`
|
|
2284
2509
|
* records sort deterministically).
|
|
2285
2510
|
*/
|
|
2286
2511
|
private _recencyOrdered;
|
|
2512
|
+
/**
|
|
2513
|
+
* Resolve a set of composite keys to their records, ordered by
|
|
2514
|
+
* {@link IMemoryEnvelope.rank} descending with recency (`updated`, then `seq`)
|
|
2515
|
+
* as the tiebreak. Records with an absent `rank` sort LAST, then by recency
|
|
2516
|
+
* among themselves. Computed on call (mirrors {@link MemoryIndex._recencyOrdered}) —
|
|
2517
|
+
* no incremental rank-ordered view is maintained, matching the recency view's
|
|
2518
|
+
* approach; the sort is over the in-memory index, never a filesystem walk.
|
|
2519
|
+
*/
|
|
2520
|
+
private _rankOrdered;
|
|
2521
|
+
/**
|
|
2522
|
+
* Rank-descending comparator with an absent-`rank`-last rule and a recency
|
|
2523
|
+
* (`updated`, then `seq`) tiebreak. Duplicated from the retrieve packlet's
|
|
2524
|
+
* `rankCompare` deliberately: the index must not depend on `retrieve` (that
|
|
2525
|
+
* package depends on the index), mirroring how `_recencyOrdered` inlines the
|
|
2526
|
+
* recency ordering rather than importing `recencyCompare`.
|
|
2527
|
+
*/
|
|
2528
|
+
private static _compareByRank;
|
|
2287
2529
|
/** Insert an entry and register all its derived associations. */
|
|
2288
2530
|
private _add;
|
|
2289
2531
|
/** Remove the entry at `key` (if present) and all its derived associations. */
|
|
2290
2532
|
private _remove;
|
|
2291
|
-
/** Register `
|
|
2533
|
+
/** Register `source` (keyed by its composite `sourceKey`) as linking at `target`. */
|
|
2292
2534
|
private _addBacklink;
|
|
2293
2535
|
/** Drop the backlink from `sourceKey` to `target`, removing the target map when empty. */
|
|
2294
2536
|
private _removeBacklink;
|
|
@@ -2382,7 +2624,8 @@ export declare class MemoryIngestOrchestrator implements IMemoryIngestOrchestrat
|
|
|
2382
2624
|
private _relate;
|
|
2383
2625
|
/**
|
|
2384
2626
|
* Validate stage-5 edges: each `source` must be a candidate being written; each
|
|
2385
|
-
* `target` must resolve to a sibling candidate or an existing store record.
|
|
2627
|
+
* `target` must resolve to a sibling candidate or an existing store record. All
|
|
2628
|
+
* matching is on the canonical scope-qualified address.
|
|
2386
2629
|
*/
|
|
2387
2630
|
private _validateEdges;
|
|
2388
2631
|
/** Stage 6 — stamp provenance + edges, admit through the store, record the outcome. */
|
|
@@ -2397,10 +2640,23 @@ export declare class MemoryIngestOrchestrator implements IMemoryIngestOrchestrat
|
|
|
2397
2640
|
private _resolveAddress;
|
|
2398
2641
|
/** Run a host hook, normalizing a thrown/rejected hook into a Failure (never throws across the seam). */
|
|
2399
2642
|
private _capture;
|
|
2400
|
-
/**
|
|
2401
|
-
|
|
2402
|
-
|
|
2643
|
+
/**
|
|
2644
|
+
* Every existing outbound edge in the snapshot, as cycle-guard edges. The
|
|
2645
|
+
* source is the record's own scope-qualified address (already resolved by
|
|
2646
|
+
* {@link MemoryIngestOrchestrator._scopeRecords}); the target is the edge's
|
|
2647
|
+
* own scoped target. Both ends are scoped so the guard never conflates a stem
|
|
2648
|
+
* shared across scopes into one graph node.
|
|
2649
|
+
*/
|
|
2403
2650
|
private static _existingEdges;
|
|
2651
|
+
/**
|
|
2652
|
+
* Resolve every snapshot record's scope-qualified `(scope, id)` address via its
|
|
2653
|
+
* registered codec. Fails loudly if a record's kind has no resolvable codec —
|
|
2654
|
+
* the edge path cannot place an un-scopeable record in the graph, and a missing
|
|
2655
|
+
* codec for a stored kind is a real misconfiguration, not something to paper over.
|
|
2656
|
+
*/
|
|
2657
|
+
private _scopeRecords;
|
|
2658
|
+
/** Human-readable `scope/id` rendering of a scoped target for edge-validation diagnostics. */
|
|
2659
|
+
private static _formatTarget;
|
|
2404
2660
|
/** A provisional record for embedding a candidate (placeholder txn-time fields). */
|
|
2405
2661
|
private static _provisionalRecord;
|
|
2406
2662
|
/** Require a candidate body to be a string (the store persists only string bodies). */
|
|
@@ -2592,6 +2848,14 @@ export declare class MtmIdentityCodec implements IIdentityCodec {
|
|
|
2592
2848
|
*/
|
|
2593
2849
|
export declare const NON_SEMANTIC_CAPABILITIES: IMemoryRetrieverCapabilities;
|
|
2594
2850
|
|
|
2851
|
+
/**
|
|
2852
|
+
* Select the record comparator for a query's {@link IMemoryQuery.orderBy | orderBy}
|
|
2853
|
+
* axis: {@link rankCompare} for `'rank'`, {@link recencyCompare} otherwise (the
|
|
2854
|
+
* default, byte-identical to the pre-`orderBy` behavior).
|
|
2855
|
+
* @public
|
|
2856
|
+
*/
|
|
2857
|
+
export declare function orderingCompare(orderBy?: IMemoryQuery['orderBy']): (a: IMemoryRecord<unknown>, b: IMemoryRecord<unknown>) => number;
|
|
2858
|
+
|
|
2595
2859
|
/**
|
|
2596
2860
|
* Parse a complete memory file into a typed {@link IMemoryRecord}. Splits the
|
|
2597
2861
|
* frontmatter, validates the envelope, and dispatches the body through the
|
|
@@ -2623,6 +2887,27 @@ export declare type ProvenanceSource = 'agent' | 'host-ingest' | 'human' | (stri
|
|
|
2623
2887
|
*/
|
|
2624
2888
|
export declare type QueryEmbedder = (text: string) => Promise<Result<Float32Array>>;
|
|
2625
2889
|
|
|
2890
|
+
/**
|
|
2891
|
+
* Rank comparator: store-computed {@link IMemoryEnvelope.rank} descending, with
|
|
2892
|
+
* {@link recencyCompare} as the tiebreak. Records with an absent `rank` sort LAST
|
|
2893
|
+
* (after every ranked record), then by recency among themselves. Mirrors the
|
|
2894
|
+
* index's rank-view ordering.
|
|
2895
|
+
* @public
|
|
2896
|
+
*/
|
|
2897
|
+
export declare function rankCompare(a: IMemoryRecord<unknown>, b: IMemoryRecord<unknown>): number;
|
|
2898
|
+
|
|
2899
|
+
/**
|
|
2900
|
+
* A per-kind host projection from a fully-resolved (post-merge) memory record
|
|
2901
|
+
* to a numeric ordering value. Registered per kind at store construction (see
|
|
2902
|
+
* `rankProjectors`); the store runs it on every put/update over the same
|
|
2903
|
+
* resolved record whose `contentHash` it computes, stamping the result into
|
|
2904
|
+
* {@link IMemoryEnvelope.rank}. The store never interprets the body — the host
|
|
2905
|
+
* owns what the number means. A projector that throws is treated as "no rank
|
|
2906
|
+
* for this record" (logged at `warn`), never failing the write.
|
|
2907
|
+
* @public
|
|
2908
|
+
*/
|
|
2909
|
+
export declare type RankProjector = (record: IMemoryRecord<unknown>) => number;
|
|
2910
|
+
|
|
2626
2911
|
/**
|
|
2627
2912
|
* Recency comparator: most-recently-updated first, with a `seq` tiebreak so
|
|
2628
2913
|
* equal-`updated` records sort deterministically. Mirrors the B1 index ordering.
|
|
@@ -2650,20 +2935,22 @@ export declare class RecencyRetriever implements IMemoryRetriever {
|
|
|
2650
2935
|
/**
|
|
2651
2936
|
* The four dedup verdicts a {@link IEntityResolver} (or fgv's exact-match layer)
|
|
2652
2937
|
* returns for a candidate. See the design note §3 for the verdict → write
|
|
2653
|
-
* disposition mapping.
|
|
2938
|
+
* disposition mapping. Each target-bearing arm carries a scope-qualified
|
|
2939
|
+
* {@link IEdgeTarget} (not a bare {@link MemoryId}) so the verdict resolves to a
|
|
2940
|
+
* single record even when a filename stem is reused across scopes.
|
|
2654
2941
|
* @public
|
|
2655
2942
|
*/
|
|
2656
2943
|
export declare type ResolutionVerdict = {
|
|
2657
2944
|
readonly verdict: 'new';
|
|
2658
2945
|
} | {
|
|
2659
2946
|
readonly verdict: 'duplicate-of';
|
|
2660
|
-
readonly target:
|
|
2947
|
+
readonly target: IEdgeTarget;
|
|
2661
2948
|
} | {
|
|
2662
2949
|
readonly verdict: 'supersede';
|
|
2663
|
-
readonly target:
|
|
2950
|
+
readonly target: IEdgeTarget;
|
|
2664
2951
|
} | {
|
|
2665
2952
|
readonly verdict: 'merge-into';
|
|
2666
|
-
readonly target:
|
|
2953
|
+
readonly target: IEdgeTarget;
|
|
2667
2954
|
};
|
|
2668
2955
|
|
|
2669
2956
|
/**
|