@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
|
@@ -96,6 +96,12 @@ export function defaultMemoryScopeEncoding(scope: MemoryScopeKey): Result<string
|
|
|
96
96
|
// @public
|
|
97
97
|
export const edgeConverter: Converter<IEdge>;
|
|
98
98
|
|
|
99
|
+
// @public
|
|
100
|
+
export const edgeTargetConverter: Converter<IEdgeTarget>;
|
|
101
|
+
|
|
102
|
+
// @public
|
|
103
|
+
export function edgeTargetKey(target: IEdgeTarget): string;
|
|
104
|
+
|
|
99
105
|
// @public
|
|
100
106
|
export type EntityId = Brand<string, 'EntityId'>;
|
|
101
107
|
|
|
@@ -107,11 +113,13 @@ export const envelopeYamlConverter: Converter<IMemoryEnvelope>;
|
|
|
107
113
|
|
|
108
114
|
// @public
|
|
109
115
|
export class FileTreeMemoryStore implements IMemoryStore {
|
|
116
|
+
asRecordSource(): IMemoryRecordSource;
|
|
110
117
|
static create(params: IFileTreeMemoryStoreCreateParams): Result<FileTreeMemoryStore>;
|
|
111
118
|
delete(kind: Kind, entityId: EntityId): Promise<Result<MemoryId>>;
|
|
112
119
|
get(kind: Kind, entityId: EntityId): Promise<Result<IMemoryRecord<unknown> | undefined>>;
|
|
113
120
|
getById(scope: MemoryScopeKey, id: MemoryId): Promise<Result<IMemoryRecord<unknown> | undefined>>;
|
|
114
121
|
list(filter?: IMemoryStoreListFilter): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>>;
|
|
122
|
+
listScoped(): Promise<Result<ReadonlyArray<IScopedMemoryRecord>>>;
|
|
115
123
|
put(record: IMemoryRecord<unknown>): Promise<Result<IMemoryRecord<unknown>>>;
|
|
116
124
|
}
|
|
117
125
|
|
|
@@ -147,7 +155,7 @@ export interface IBodyConverterRegistry {
|
|
|
147
155
|
// @public
|
|
148
156
|
export interface ICandidateEdge {
|
|
149
157
|
readonly edge: IEdge;
|
|
150
|
-
readonly source:
|
|
158
|
+
readonly source: IEdgeTarget;
|
|
151
159
|
}
|
|
152
160
|
|
|
153
161
|
// @public
|
|
@@ -162,6 +170,7 @@ export interface ICreateMemoryToolsParams {
|
|
|
162
170
|
readonly defaultCodec?: IIdentityCodec;
|
|
163
171
|
readonly handleFor?: (record: IMemoryRecord<unknown>) => string;
|
|
164
172
|
readonly kinds?: ReadonlyArray<Kind>;
|
|
173
|
+
readonly projectItem?: (record: IMemoryRecord<unknown>, detail: MemoryDetailTier) => IMemoryToolResultItem;
|
|
165
174
|
readonly registry: IBodyConverterRegistry;
|
|
166
175
|
readonly retriever: IMemoryRetriever;
|
|
167
176
|
readonly store: IMemoryStore;
|
|
@@ -171,9 +180,9 @@ export interface ICreateMemoryToolsParams {
|
|
|
171
180
|
// @public
|
|
172
181
|
export interface ICycleGuardEdge {
|
|
173
182
|
// (undocumented)
|
|
174
|
-
readonly source:
|
|
183
|
+
readonly source: IEdgeTarget;
|
|
175
184
|
// (undocumented)
|
|
176
|
-
readonly target:
|
|
185
|
+
readonly target: IEdgeTarget;
|
|
177
186
|
// (undocumented)
|
|
178
187
|
readonly type: LinkType;
|
|
179
188
|
}
|
|
@@ -183,16 +192,22 @@ export interface IEdge {
|
|
|
183
192
|
readonly confidence?: number;
|
|
184
193
|
readonly invalid_at?: number | null;
|
|
185
194
|
readonly provenance?: IProvenance;
|
|
186
|
-
readonly target:
|
|
195
|
+
readonly target: IEdgeTarget;
|
|
187
196
|
readonly type: LinkType;
|
|
188
197
|
readonly valid_at?: number;
|
|
189
198
|
}
|
|
190
199
|
|
|
191
200
|
// @public
|
|
192
|
-
export interface
|
|
201
|
+
export interface IEdgeTarget {
|
|
193
202
|
readonly id: MemoryId;
|
|
203
|
+
readonly scope: MemoryScopeKey;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// @public
|
|
207
|
+
export interface IEntityResolutionCandidate {
|
|
194
208
|
readonly record: IMemoryRecord<unknown>;
|
|
195
209
|
readonly score: number;
|
|
210
|
+
readonly target: IEdgeTarget;
|
|
196
211
|
}
|
|
197
212
|
|
|
198
213
|
// @public
|
|
@@ -213,6 +228,7 @@ export interface IFileTreeMemoryStoreCreateParams {
|
|
|
213
228
|
readonly embed?: MemoryEmbedder;
|
|
214
229
|
readonly logger?: Logging.ILogger;
|
|
215
230
|
readonly observers?: ReadonlyArray<IMemoryObserver>;
|
|
231
|
+
readonly rankProjectors?: ReadonlyMap<Kind, RankProjector>;
|
|
216
232
|
readonly registry: IBodyConverterRegistry;
|
|
217
233
|
readonly root: FileTree.IMutableFileTreeDirectoryItem;
|
|
218
234
|
readonly scopeEncoding?: (scope: MemoryScopeKey) => Result<string>;
|
|
@@ -256,7 +272,7 @@ export interface IIngestItem {
|
|
|
256
272
|
readonly content: unknown;
|
|
257
273
|
readonly id: string;
|
|
258
274
|
readonly metadata?: Record<string, unknown>;
|
|
259
|
-
readonly sourceId?:
|
|
275
|
+
readonly sourceId?: IEdgeTarget;
|
|
260
276
|
}
|
|
261
277
|
|
|
262
278
|
// @public
|
|
@@ -294,6 +310,7 @@ export interface IMemoryEnvelope {
|
|
|
294
310
|
readonly kind: Kind;
|
|
295
311
|
readonly links: ReadonlyArray<IEdge>;
|
|
296
312
|
readonly provenance: IProvenance;
|
|
313
|
+
readonly rank?: number;
|
|
297
314
|
readonly seq: number;
|
|
298
315
|
readonly tags: ReadonlyArray<Tag>;
|
|
299
316
|
readonly temporal?: ITemporalBlock;
|
|
@@ -308,8 +325,9 @@ export interface IMemoryFileParts {
|
|
|
308
325
|
|
|
309
326
|
// @public
|
|
310
327
|
export interface IMemoryIndex {
|
|
311
|
-
backlinks(target:
|
|
328
|
+
backlinks(target: IEdgeTarget): ReadonlyArray<IEdgeTarget>;
|
|
312
329
|
byKind(kind: Kind): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
330
|
+
byRank(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
313
331
|
byRecency(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
314
332
|
byTag(tag: Tag): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
315
333
|
entries(): ReadonlyArray<IIndexedMemoryRecord>;
|
|
@@ -384,9 +402,12 @@ export interface IMemoryQuery {
|
|
|
384
402
|
readonly filter?: (record: IMemoryRecord<unknown>) => boolean;
|
|
385
403
|
readonly hops?: number;
|
|
386
404
|
readonly kind?: Kind;
|
|
405
|
+
readonly kinds?: ReadonlyArray<Kind>;
|
|
387
406
|
readonly limit?: number;
|
|
388
|
-
readonly linkedFrom?:
|
|
389
|
-
readonly linkedTo?:
|
|
407
|
+
readonly linkedFrom?: IEdgeTarget;
|
|
408
|
+
readonly linkedTo?: IEdgeTarget;
|
|
409
|
+
readonly offset?: number;
|
|
410
|
+
readonly orderBy?: 'recency' | 'rank';
|
|
390
411
|
readonly scope?: MemoryScopeKey;
|
|
391
412
|
readonly semantic?: string;
|
|
392
413
|
readonly tag?: Tag;
|
|
@@ -401,7 +422,7 @@ export interface IMemoryRecord<TBody = unknown> {
|
|
|
401
422
|
|
|
402
423
|
// @public
|
|
403
424
|
export interface IMemoryRecordSource {
|
|
404
|
-
list(): Promise<Result<ReadonlyArray<
|
|
425
|
+
list(): Promise<Result<ReadonlyArray<IScopedMemoryRecord>>>;
|
|
405
426
|
}
|
|
406
427
|
|
|
407
428
|
// @public
|
|
@@ -419,10 +440,12 @@ export interface IMemoryRetrieverCapabilities {
|
|
|
419
440
|
|
|
420
441
|
// @public
|
|
421
442
|
export interface IMemoryStore {
|
|
443
|
+
asRecordSource(): IMemoryRecordSource;
|
|
422
444
|
delete(kind: Kind, entityId: EntityId): Promise<Result<MemoryId>>;
|
|
423
445
|
get(kind: Kind, entityId: EntityId): Promise<Result<IMemoryRecord<unknown> | undefined>>;
|
|
424
446
|
getById(scope: MemoryScopeKey, id: MemoryId): Promise<Result<IMemoryRecord<unknown> | undefined>>;
|
|
425
447
|
list(filter?: IMemoryStoreListFilter): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>>;
|
|
448
|
+
listScoped(): Promise<Result<ReadonlyArray<IScopedMemoryRecord>>>;
|
|
426
449
|
put(record: IMemoryRecord<unknown>): Promise<Result<IMemoryRecord<unknown>>>;
|
|
427
450
|
}
|
|
428
451
|
|
|
@@ -464,11 +487,11 @@ export type IngestDisposition = 'written' | 'deduped' | 'merged';
|
|
|
464
487
|
|
|
465
488
|
// @public
|
|
466
489
|
export class InMemoryCosineIndex implements IVectorIndex {
|
|
467
|
-
add(
|
|
490
|
+
add(target: IEdgeTarget, vector: Float32Array): Promise<Result<string>>;
|
|
468
491
|
static create(): Result<InMemoryCosineIndex>;
|
|
469
492
|
query(vector: Float32Array, topK: number): Promise<Result<ReadonlyArray<IVectorQueryHit>>>;
|
|
470
493
|
rebuild(source: IMemoryRecordSource, embed: MemoryEmbedder): Promise<Result<number>>;
|
|
471
|
-
remove(
|
|
494
|
+
remove(target: IEdgeTarget): Promise<Result<IEdgeTarget>>;
|
|
472
495
|
get size(): number;
|
|
473
496
|
}
|
|
474
497
|
|
|
@@ -477,7 +500,7 @@ export interface IProvenance {
|
|
|
477
500
|
readonly [key: string]: unknown;
|
|
478
501
|
readonly by?: string;
|
|
479
502
|
readonly confidence?: number;
|
|
480
|
-
readonly derivedFrom?:
|
|
503
|
+
readonly derivedFrom?: IEdgeTarget;
|
|
481
504
|
readonly model?: string;
|
|
482
505
|
readonly source: ProvenanceSource;
|
|
483
506
|
}
|
|
@@ -485,7 +508,7 @@ export interface IProvenance {
|
|
|
485
508
|
// @public
|
|
486
509
|
export interface IRelationCandidate {
|
|
487
510
|
readonly candidate: ICandidateRecord;
|
|
488
|
-
readonly id:
|
|
511
|
+
readonly id: IEdgeTarget;
|
|
489
512
|
}
|
|
490
513
|
|
|
491
514
|
// @public
|
|
@@ -499,6 +522,12 @@ export interface IRelationExtractor {
|
|
|
499
522
|
relate(context: IRelationContext): Promise<Result<ReadonlyArray<ICandidateEdge>>>;
|
|
500
523
|
}
|
|
501
524
|
|
|
525
|
+
// @public
|
|
526
|
+
export interface IScopedMemoryRecord {
|
|
527
|
+
readonly record: IMemoryRecord<unknown>;
|
|
528
|
+
readonly target: IEdgeTarget;
|
|
529
|
+
}
|
|
530
|
+
|
|
502
531
|
// @public
|
|
503
532
|
export interface ISemanticBackend {
|
|
504
533
|
readonly embedQuery: QueryEmbedder;
|
|
@@ -543,15 +572,15 @@ export interface ITemporalVersionAddress {
|
|
|
543
572
|
|
|
544
573
|
// @public
|
|
545
574
|
export interface IVectorIndex {
|
|
546
|
-
add(
|
|
575
|
+
add(target: IEdgeTarget, vector: Float32Array): Promise<Result<string>>;
|
|
547
576
|
query(vector: Float32Array, topK: number): Promise<Result<ReadonlyArray<IVectorQueryHit>>>;
|
|
548
|
-
remove(
|
|
577
|
+
remove(target: IEdgeTarget): Promise<Result<IEdgeTarget>>;
|
|
549
578
|
}
|
|
550
579
|
|
|
551
580
|
// @public
|
|
552
581
|
export interface IVectorQueryHit {
|
|
553
|
-
readonly id: MemoryId;
|
|
554
582
|
readonly score: number;
|
|
583
|
+
readonly target: IEdgeTarget;
|
|
555
584
|
}
|
|
556
585
|
|
|
557
586
|
// @public
|
|
@@ -586,7 +615,7 @@ export class KnowledgeLwwPolicy implements IWritePolicy {
|
|
|
586
615
|
}
|
|
587
616
|
|
|
588
617
|
// @public
|
|
589
|
-
export function limitRecords(records: ReadonlyArray<IMemoryRecord<unknown>>, limit?: number): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
618
|
+
export function limitRecords(records: ReadonlyArray<IMemoryRecord<unknown>>, limit?: number, offset?: number): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
590
619
|
|
|
591
620
|
// @public
|
|
592
621
|
export const LINK_TRAVERSAL_NO_SEED_MESSAGE: string;
|
|
@@ -621,6 +650,9 @@ export class MemoryCapCullPolicy implements IWritePolicy {
|
|
|
621
650
|
readonly mutableFields: ReadonlyArray<string>;
|
|
622
651
|
}
|
|
623
652
|
|
|
653
|
+
// @public
|
|
654
|
+
export type MemoryDetailTier = 'gist' | 'full';
|
|
655
|
+
|
|
624
656
|
// @public
|
|
625
657
|
export type MemoryEmbedder = (record: IMemoryRecord<unknown>) => Promise<Result<Float32Array>>;
|
|
626
658
|
|
|
@@ -629,8 +661,9 @@ export type MemoryId = Brand<string, 'MemoryId'>;
|
|
|
629
661
|
|
|
630
662
|
// @public
|
|
631
663
|
export class MemoryIndex implements IMemoryIndex {
|
|
632
|
-
backlinks(target:
|
|
664
|
+
backlinks(target: IEdgeTarget): ReadonlyArray<IEdgeTarget>;
|
|
633
665
|
byKind(kind: Kind): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
666
|
+
byRank(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
634
667
|
byRecency(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
635
668
|
byTag(tag: Tag): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
636
669
|
static create(): Result<MemoryIndex>;
|
|
@@ -686,6 +719,9 @@ export class MtmIdentityCodec implements IIdentityCodec {
|
|
|
686
719
|
// @public
|
|
687
720
|
export const NON_SEMANTIC_CAPABILITIES: IMemoryRetrieverCapabilities;
|
|
688
721
|
|
|
722
|
+
// @public
|
|
723
|
+
export function orderingCompare(orderBy?: IMemoryQuery['orderBy']): (a: IMemoryRecord<unknown>, b: IMemoryRecord<unknown>) => number;
|
|
724
|
+
|
|
689
725
|
// @public
|
|
690
726
|
export function parseMemoryFile(raw: string, registry: IBodyConverterRegistry): Result<IMemoryRecord<unknown>>;
|
|
691
727
|
|
|
@@ -698,6 +734,12 @@ export type ProvenanceSource = 'agent' | 'host-ingest' | 'human' | (string & {})
|
|
|
698
734
|
// @public
|
|
699
735
|
export type QueryEmbedder = (text: string) => Promise<Result<Float32Array>>;
|
|
700
736
|
|
|
737
|
+
// @public
|
|
738
|
+
export function rankCompare(a: IMemoryRecord<unknown>, b: IMemoryRecord<unknown>): number;
|
|
739
|
+
|
|
740
|
+
// @public
|
|
741
|
+
export type RankProjector = (record: IMemoryRecord<unknown>) => number;
|
|
742
|
+
|
|
701
743
|
// @public
|
|
702
744
|
export function recencyCompare(a: IMemoryRecord<unknown>, b: IMemoryRecord<unknown>): number;
|
|
703
745
|
|
|
@@ -713,13 +755,13 @@ export type ResolutionVerdict = {
|
|
|
713
755
|
readonly verdict: 'new';
|
|
714
756
|
} | {
|
|
715
757
|
readonly verdict: 'duplicate-of';
|
|
716
|
-
readonly target:
|
|
758
|
+
readonly target: IEdgeTarget;
|
|
717
759
|
} | {
|
|
718
760
|
readonly verdict: 'supersede';
|
|
719
|
-
readonly target:
|
|
761
|
+
readonly target: IEdgeTarget;
|
|
720
762
|
} | {
|
|
721
763
|
readonly verdict: 'merge-into';
|
|
722
|
-
readonly target:
|
|
764
|
+
readonly target: IEdgeTarget;
|
|
723
765
|
};
|
|
724
766
|
|
|
725
767
|
// @public
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { Converter, Result } from '@fgv/ts-utils';
|
|
2
|
-
import { IEdge, IMemoryEnvelope, IMemoryRecord, IProvenance, ITemporalBlock } from '../types';
|
|
2
|
+
import { IEdge, IEdgeTarget, IMemoryEnvelope, IMemoryRecord, IProvenance, ITemporalBlock } from '../types';
|
|
3
3
|
import { IBodyConverterRegistry } from './bodyConverterRegistry';
|
|
4
|
+
/**
|
|
5
|
+
* Converter for a scope-qualified {@link IEdgeTarget}. Both `scope` and `id`
|
|
6
|
+
* are required — the whole point of the scoped target is that a bare id is
|
|
7
|
+
* ambiguous across scopes.
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export declare const edgeTargetConverter: Converter<IEdgeTarget>;
|
|
4
11
|
/**
|
|
5
12
|
* Converter for {@link IProvenance}. Validates the known fields and preserves
|
|
6
13
|
* any extension keys verbatim (the `[key: string]: unknown` opaque payload),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envelopeConverter.d.ts","sourceRoot":"","sources":["../../../src/packlets/converters/envelopeConverter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAc,MAAM,EAAiB,MAAM,eAAe,CAAC;AAE7E,OAAO,
|
|
1
|
+
{"version":3,"file":"envelopeConverter.d.ts","sourceRoot":"","sources":["../../../src/packlets/converters/envelopeConverter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAc,MAAM,EAAiB,MAAM,eAAe,CAAC;AAE7E,OAAO,EAEL,KAAK,EACL,WAAW,EACX,eAAe,EACf,aAAa,EACb,WAAW,EACX,cAAc,EACf,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAsBjE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,WAAW,CAGrD,CAAC;AAoBH;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,WAAW,CAUtD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,KAAK,CAU1C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,CAAC,cAAc,CAMvD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,CAAC,eAAe,CAiBxD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,CAAC,eAAe,CAAyC,CAAC;AAKvG;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAuBtE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGzE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,sBAAsB,GAC/B,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAYhC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAI3F"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: MIT
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.envelopeYamlConverter = exports.envelopeConverter = exports.temporalConverter = exports.edgeConverter = exports.provenanceConverter = void 0;
|
|
7
|
+
exports.envelopeYamlConverter = exports.envelopeConverter = exports.temporalConverter = exports.edgeConverter = exports.provenanceConverter = exports.edgeTargetConverter = void 0;
|
|
8
8
|
exports.splitFrontmatter = splitFrontmatter;
|
|
9
9
|
exports.joinFrontmatter = joinFrontmatter;
|
|
10
10
|
exports.parseMemoryFile = parseMemoryFile;
|
|
@@ -27,16 +27,29 @@ const stringOrNull = ts_utils_1.Converters.oneOf([
|
|
|
27
27
|
ts_utils_1.Converters.string,
|
|
28
28
|
nullConverter
|
|
29
29
|
]);
|
|
30
|
+
/**
|
|
31
|
+
* Converter for a scope-qualified {@link IEdgeTarget}. Both `scope` and `id`
|
|
32
|
+
* are required — the whole point of the scoped target is that a bare id is
|
|
33
|
+
* ambiguous across scopes.
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
exports.edgeTargetConverter = ts_utils_1.Converters.object({
|
|
37
|
+
scope: types_1.Convert.scopeKey,
|
|
38
|
+
id: types_1.Convert.memoryId
|
|
39
|
+
});
|
|
30
40
|
/**
|
|
31
41
|
* Converter for the known {@link IProvenance} fields. The full
|
|
32
42
|
* {@link provenanceConverter} layers extension-key preservation on top.
|
|
43
|
+
* `derivedFrom` is serialized as the nested `{ scope, id }` object (mirroring
|
|
44
|
+
* {@link edgeConverter | edge}'s scope-qualified `target`) so the provenance
|
|
45
|
+
* back-reference is unambiguous across scopes.
|
|
33
46
|
*/
|
|
34
47
|
const knownProvenanceConverter = ts_utils_1.Converters.object({
|
|
35
48
|
source: ts_utils_1.Converters.string,
|
|
36
49
|
by: ts_utils_1.Converters.string.optional(),
|
|
37
50
|
model: ts_utils_1.Converters.string.optional(),
|
|
38
51
|
confidence: ts_utils_1.Converters.number.optional(),
|
|
39
|
-
derivedFrom:
|
|
52
|
+
derivedFrom: exports.edgeTargetConverter.optional()
|
|
40
53
|
}, { optionalFields: ['by', 'model', 'confidence', 'derivedFrom'] });
|
|
41
54
|
/**
|
|
42
55
|
* Converter for {@link IProvenance}. Validates the known fields and preserves
|
|
@@ -58,7 +71,7 @@ exports.provenanceConverter = ts_utils_1.Converters.generic((from) => knownProve
|
|
|
58
71
|
*/
|
|
59
72
|
exports.edgeConverter = ts_utils_1.Converters.object({
|
|
60
73
|
type: types_1.Convert.linkType,
|
|
61
|
-
target:
|
|
74
|
+
target: exports.edgeTargetConverter,
|
|
62
75
|
confidence: ts_utils_1.Converters.number.optional(),
|
|
63
76
|
provenance: exports.provenanceConverter.optional(),
|
|
64
77
|
valid_at: ts_utils_1.Converters.number.optional(),
|
|
@@ -87,10 +100,11 @@ exports.envelopeConverter = ts_utils_1.Converters.object({
|
|
|
87
100
|
updated: ts_utils_1.Converters.number,
|
|
88
101
|
seq: ts_utils_1.Converters.number,
|
|
89
102
|
contentHash: ts_utils_1.Converters.string,
|
|
103
|
+
rank: ts_utils_1.Converters.number.optional(),
|
|
90
104
|
provenance: exports.provenanceConverter,
|
|
91
105
|
temporal: exports.temporalConverter.optional(),
|
|
92
106
|
embeddingRef: stringOrNull.optional()
|
|
93
|
-
}, { optionalFields: ['temporal', 'embeddingRef'] });
|
|
107
|
+
}, { optionalFields: ['rank', 'temporal', 'embeddingRef'] });
|
|
94
108
|
/**
|
|
95
109
|
* Converter that parses a YAML frontmatter string into an
|
|
96
110
|
* {@link IMemoryEnvelope}.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envelopeConverter.js","sourceRoot":"","sources":["../../../src/packlets/converters/envelopeConverter.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA0IH,4CAuBC;AAOD,0CAGC;AAQD,0CAeC;AAQD,kDAIC;AA5MD,4CAA6E;AAC7E,8CAAsC;AACtC,oCAAuG;AAGvG,+CAA+C;AAC/C,yJAAyJ;AACzJ,MAAM,aAAa,GAAoB,qBAAU,CAAC,OAAO,CAAO,CAAC,IAAa,EAAE,EAAE,CAChF,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,eAAe,CAAC,CACtD,CAAC;AAEF,mDAAmD;AACnD,+HAA+H;AAC/H,MAAM,YAAY,GAA6B,qBAAU,CAAC,KAAK,CAAgB;IAC7E,qBAAU,CAAC,MAAM;IACjB,aAAa;CACd,CAAC,CAAC;AAEH,iDAAiD;AACjD,wHAAwH;AACxH,MAAM,YAAY,GAA6B,qBAAU,CAAC,KAAK,CAAgB;IAC7E,qBAAU,CAAC,MAAM;IACjB,aAAa;CACd,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,wBAAwB,GAA2B,qBAAU,CAAC,MAAM,CACxE;IACE,MAAM,EAAE,qBAAU,CAAC,MAAM;IACzB,EAAE,EAAE,qBAAU,CAAC,MAAM,CAAC,QAAQ,EAAE;IAChC,KAAK,EAAE,qBAAU,CAAC,MAAM,CAAC,QAAQ,EAAE;IACnC,UAAU,EAAE,qBAAU,CAAC,MAAM,CAAC,QAAQ,EAAE;IACxC,WAAW,EAAE,eAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE;CACzC,EACD,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,aAAa,CAAC,EAAE,CACjE,CAAC;AAEF;;;;;GAKG;AACU,QAAA,mBAAmB,GAA2B,qBAAU,CAAC,OAAO,CAC3E,CAAC,IAAa,EAAuB,EAAE,CACrC,wBAAwB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;IACzD,sEAAsE;IACtE,sEAAsE;IACtE,uEAAuE;IACvE,+DAA+D;IAC/D,MAAM,MAAM,mCAAsB,IAAgC,GAAK,KAAK,CAAE,CAAC;IAC/E,OAAO,IAAA,kBAAO,EAAC,MAAM,CAAC,CAAC;AACzB,CAAC,CAAC,CACL,CAAC;AAEF;;;GAGG;AACU,QAAA,aAAa,GAAqB,qBAAU,CAAC,MAAM,CAC9D;IACE,IAAI,EAAE,eAAO,CAAC,QAAQ;IACtB,MAAM,EAAE,eAAO,CAAC,QAAQ;IACxB,UAAU,EAAE,qBAAU,CAAC,MAAM,CAAC,QAAQ,EAAE;IACxC,UAAU,EAAE,2BAAmB,CAAC,QAAQ,EAAE;IAC1C,QAAQ,EAAE,qBAAU,CAAC,MAAM,CAAC,QAAQ,EAAE;IACtC,UAAU,EAAE,YAAY,CAAC,QAAQ,EAAE;CACpC,EACD,EAAE,cAAc,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,CAC3E,CAAC;AAEF;;;GAGG;AACU,QAAA,iBAAiB,GAA8B,qBAAU,CAAC,MAAM,CAC3E;IACE,QAAQ,EAAE,qBAAU,CAAC,MAAM,CAAC,QAAQ,EAAE;IACtC,UAAU,EAAE,YAAY,CAAC,QAAQ,EAAE;CACpC,EACD,EAAE,cAAc,EAAE,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,CAC/C,CAAC;AAEF;;;;GAIG;AACU,QAAA,iBAAiB,GAA+B,qBAAU,CAAC,MAAM,CAC5E;IACE,EAAE,EAAE,eAAO,CAAC,QAAQ;IACpB,QAAQ,EAAE,eAAO,CAAC,QAAQ;IAC1B,IAAI,EAAE,eAAO,CAAC,IAAI;IAClB,IAAI,EAAE,qBAAU,CAAC,OAAO,CAAC,eAAO,CAAC,GAAG,CAAC;IACrC,KAAK,EAAE,qBAAU,CAAC,OAAO,CAAC,qBAAa,CAAC;IACxC,OAAO,EAAE,qBAAU,CAAC,MAAM;IAC1B,OAAO,EAAE,qBAAU,CAAC,MAAM;IAC1B,GAAG,EAAE,qBAAU,CAAC,MAAM;IACtB,WAAW,EAAE,qBAAU,CAAC,MAAM;IAC9B,UAAU,EAAE,2BAAmB;IAC/B,QAAQ,EAAE,yBAAiB,CAAC,QAAQ,EAAE;IACtC,YAAY,EAAE,YAAY,CAAC,QAAQ,EAAE;CACtC,EACD,EAAE,cAAc,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC,EAAE,CACjD,CAAC;AAEF;;;;GAIG;AACU,QAAA,qBAAqB,GAA+B,gBAAI,CAAC,aAAa,CAAC,yBAAiB,CAAC,CAAC;AAEvG,sCAAsC;AACtC,MAAM,qBAAqB,GAAW,KAAK,CAAC;AAc5C;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,0EAA0E;IAC1E,yEAAyE;IACzE,sEAAsE;IACtE,wBAAwB;IACxB,MAAM,KAAK,GAAa,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACxG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,qBAAqB,EAAE,CAAC;QAC9C,OAAO,IAAA,eAAI,EAAC,0DAA0D,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,UAAU,GAAW,CAAC,CAAC,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,qBAAqB,EAAE,CAAC;YAC9C,UAAU,GAAG,CAAC,CAAC;YACf,MAAM;QACR,CAAC;IACH,CAAC;IACD,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;QACtB,OAAO,IAAA,eAAI,EAAC,0DAA0D,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,IAAA,kBAAO,EAAC;QACb,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAClD,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;KAC7C,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAAC,WAAmB,EAAE,IAAY;IAC/D,MAAM,UAAU,GAAW,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,CAAC;IACzF,OAAO,GAAG,qBAAqB,KAAK,UAAU,GAAG,qBAAqB,KAAK,IAAI,EAAE,CAAC;AACpF,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAC7B,GAAW,EACX,QAAgC;IAEhC,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAC/C,6BAAqB;SAClB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;SAC1B,eAAe,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kCAAkC,GAAG,EAAE,CAAC;SACjE,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE,CACtB,QAAQ;SACL,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;SAClC,eAAe,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,QAAQ,CAAC,EAAE,oBAAoB,GAAG,EAAE,CAAC;SAC9E,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,kBAAO,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CACpD,CACJ,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,QAAyB,EAAE,IAAY;IACzE,OAAO,gBAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;SAChC,eAAe,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,QAAQ,CAAC,EAAE,oCAAoC,GAAG,EAAE,CAAC;SAC9F,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,IAAA,kBAAO,EAAC,eAAe,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC","sourcesContent":["/*\n * Copyright (c) 2026 Erik Fortune\n * SPDX-License-Identifier: MIT\n */\n\nimport { Converter, Converters, Result, fail, succeed } from '@fgv/ts-utils';\nimport { Yaml } from '@fgv/ts-extras';\nimport { Convert, IEdge, IMemoryEnvelope, IMemoryRecord, IProvenance, ITemporalBlock } from '../types';\nimport { IBodyConverterRegistry } from './bodyConverterRegistry';\n\n/** Matches exactly the JSON `null` literal. */\n// eslint-disable-next-line @rushstack/no-new-null -- the envelope nullable fields (invalid_at, embeddingRef) carry meaningful null; design-lock §2.3-2.5\nconst nullConverter: Converter<null> = Converters.generic<null>((from: unknown) =>\n from === null ? succeed(null) : fail('expected null')\n);\n\n/** A nullable epoch-ms value (`number | null`). */\n// eslint-disable-next-line @rushstack/no-new-null -- meaningful null for IEdge/ITemporalBlock.invalid_at; design-lock §2.3-2.4\nconst numberOrNull: Converter<number | null> = Converters.oneOf<number | null>([\n Converters.number,\n nullConverter\n]);\n\n/** A nullable string value (`string | null`). */\n// eslint-disable-next-line @rushstack/no-new-null -- meaningful null for IMemoryEnvelope.embeddingRef; design-lock §2.5\nconst stringOrNull: Converter<string | null> = Converters.oneOf<string | null>([\n Converters.string,\n nullConverter\n]);\n\n/**\n * Converter for the known {@link IProvenance} fields. The full\n * {@link provenanceConverter} layers extension-key preservation on top.\n */\nconst knownProvenanceConverter: Converter<IProvenance> = Converters.object<IProvenance>(\n {\n source: Converters.string,\n by: Converters.string.optional(),\n model: Converters.string.optional(),\n confidence: Converters.number.optional(),\n derivedFrom: Convert.memoryId.optional()\n },\n { optionalFields: ['by', 'model', 'confidence', 'derivedFrom'] }\n);\n\n/**\n * Converter for {@link IProvenance}. Validates the known fields and preserves\n * any extension keys verbatim (the `[key: string]: unknown` opaque payload),\n * so a round-trip never drops consumer-attached data.\n * @public\n */\nexport const provenanceConverter: Converter<IProvenance> = Converters.generic<IProvenance>(\n (from: unknown): Result<IProvenance> =>\n knownProvenanceConverter.convert(from).onSuccess((known) => {\n // `from` is guaranteed to be a non-null object here — the known-field\n // converter only succeeds on objects. Spread the original keys first,\n // then the validated/normalized known fields on top, so extension keys\n // survive while the known fields carry their converted values.\n const merged: IProvenance = { ...(from as Record<string, unknown>), ...known };\n return succeed(merged);\n })\n);\n\n/**\n * Converter for an attributed {@link IEdge}.\n * @public\n */\nexport const edgeConverter: Converter<IEdge> = Converters.object<IEdge>(\n {\n type: Convert.linkType,\n target: Convert.memoryId,\n confidence: Converters.number.optional(),\n provenance: provenanceConverter.optional(),\n valid_at: Converters.number.optional(),\n invalid_at: numberOrNull.optional()\n },\n { optionalFields: ['confidence', 'provenance', 'valid_at', 'invalid_at'] }\n);\n\n/**\n * Converter for the optional {@link ITemporalBlock}.\n * @public\n */\nexport const temporalConverter: Converter<ITemporalBlock> = Converters.object<ITemporalBlock>(\n {\n valid_at: Converters.number.optional(),\n invalid_at: numberOrNull.optional()\n },\n { optionalFields: ['valid_at', 'invalid_at'] }\n);\n\n/**\n * Converter for the invariant {@link IMemoryEnvelope}. Validates a plain\n * object (e.g. parsed YAML frontmatter) into a typed envelope.\n * @public\n */\nexport const envelopeConverter: Converter<IMemoryEnvelope> = Converters.object<IMemoryEnvelope>(\n {\n id: Convert.memoryId,\n entityId: Convert.entityId,\n kind: Convert.kind,\n tags: Converters.arrayOf(Convert.tag),\n links: Converters.arrayOf(edgeConverter),\n created: Converters.number,\n updated: Converters.number,\n seq: Converters.number,\n contentHash: Converters.string,\n provenance: provenanceConverter,\n temporal: temporalConverter.optional(),\n embeddingRef: stringOrNull.optional()\n },\n { optionalFields: ['temporal', 'embeddingRef'] }\n);\n\n/**\n * Converter that parses a YAML frontmatter string into an\n * {@link IMemoryEnvelope}.\n * @public\n */\nexport const envelopeYamlConverter: Converter<IMemoryEnvelope> = Yaml.yamlConverter(envelopeConverter);\n\n/** The frontmatter delimiter line. */\nconst FRONTMATTER_DELIMITER: string = '---';\n\n/**\n * The two parts of a memory file: the YAML frontmatter (between the `---`\n * delimiters) and the markdown body (everything after the closing delimiter).\n * @public\n */\nexport interface IMemoryFileParts {\n /** The raw YAML frontmatter (delimiters stripped). */\n readonly frontmatter: string;\n /** The raw body text following the closing delimiter. */\n readonly body: string;\n}\n\n/**\n * Split a `---\\n<yaml>\\n---\\n<body>` memory file into its frontmatter and\n * body parts. Pure string handling — no external dependency.\n * @public\n */\nexport function splitFrontmatter(raw: string): Result<IMemoryFileParts> {\n // Split on '\\n' and strip a trailing '\\r' per line so CRLF-authored files\n // parse identically to LF — otherwise the '\\r' would ride along into the\n // returned frontmatter (perturbing YAML parsing) and body (corrupting\n // round-trip fidelity).\n const lines: string[] = raw.split('\\n').map((line) => (line.endsWith('\\r') ? line.slice(0, -1) : line));\n if (lines[0].trim() !== FRONTMATTER_DELIMITER) {\n return fail(\"memory file: missing opening frontmatter delimiter '---'\");\n }\n let closeIndex: number = -1;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i].trim() === FRONTMATTER_DELIMITER) {\n closeIndex = i;\n break;\n }\n }\n if (closeIndex === -1) {\n return fail(\"memory file: missing closing frontmatter delimiter '---'\");\n }\n return succeed({\n frontmatter: lines.slice(1, closeIndex).join('\\n'),\n body: lines.slice(closeIndex + 1).join('\\n')\n });\n}\n\n/**\n * Join a YAML frontmatter string and a body into the canonical\n * `---\\n<yaml>\\n---\\n<body>` memory-file format.\n * @public\n */\nexport function joinFrontmatter(frontmatter: string, body: string): string {\n const normalized: string = frontmatter.endsWith('\\n') ? frontmatter : `${frontmatter}\\n`;\n return `${FRONTMATTER_DELIMITER}\\n${normalized}${FRONTMATTER_DELIMITER}\\n${body}`;\n}\n\n/**\n * Parse a complete memory file into a typed {@link IMemoryRecord}. Splits the\n * frontmatter, validates the envelope, and dispatches the body through the\n * registered Converter for the envelope's kind.\n * @public\n */\nexport function parseMemoryFile(\n raw: string,\n registry: IBodyConverterRegistry\n): Result<IMemoryRecord<unknown>> {\n return splitFrontmatter(raw).onSuccess((parts) =>\n envelopeYamlConverter\n .convert(parts.frontmatter)\n .withErrorFormat((msg) => `memory file: invalid envelope: ${msg}`)\n .onSuccess((envelope) =>\n registry\n .convert(envelope.kind, parts.body)\n .withErrorFormat((msg) => `memory file '${envelope.id}': invalid body: ${msg}`)\n .onSuccess((body) => succeed({ envelope, body }))\n )\n );\n}\n\n/**\n * Serialize an envelope and its rendered body text into a memory file. The\n * envelope is emitted as YAML frontmatter; the body is written verbatim after\n * the closing delimiter.\n * @public\n */\nexport function serializeMemoryFile(envelope: IMemoryEnvelope, body: string): Result<string> {\n return Yaml.yamlStringify(envelope)\n .withErrorFormat((msg) => `memory file '${envelope.id}': failed to serialize envelope: ${msg}`)\n .onSuccess((frontmatter) => succeed(joinFrontmatter(frontmatter, body)));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"envelopeConverter.js","sourceRoot":"","sources":["../../../src/packlets/converters/envelopeConverter.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2026 Erik Fortune\n * SPDX-License-Identifier: MIT\n */\n\nimport { Converter, Converters, Result, fail, succeed } from '@fgv/ts-utils';\nimport { Yaml } from '@fgv/ts-extras';\nimport {\n Convert,\n IEdge,\n IEdgeTarget,\n IMemoryEnvelope,\n IMemoryRecord,\n IProvenance,\n ITemporalBlock\n} from '../types';\nimport { IBodyConverterRegistry } from './bodyConverterRegistry';\n\n/** Matches exactly the JSON `null` literal. */\n// eslint-disable-next-line @rushstack/no-new-null -- the envelope nullable fields (invalid_at, embeddingRef) carry meaningful null; design-lock §2.3-2.5\nconst nullConverter: Converter<null> = Converters.generic<null>((from: unknown) =>\n from === null ? succeed(null) : fail('expected null')\n);\n\n/** A nullable epoch-ms value (`number | null`). */\n// eslint-disable-next-line @rushstack/no-new-null -- meaningful null for IEdge/ITemporalBlock.invalid_at; design-lock §2.3-2.4\nconst numberOrNull: Converter<number | null> = Converters.oneOf<number | null>([\n Converters.number,\n nullConverter\n]);\n\n/** A nullable string value (`string | null`). */\n// eslint-disable-next-line @rushstack/no-new-null -- meaningful null for IMemoryEnvelope.embeddingRef; design-lock §2.5\nconst stringOrNull: Converter<string | null> = Converters.oneOf<string | null>([\n Converters.string,\n nullConverter\n]);\n\n/**\n * Converter for a scope-qualified {@link IEdgeTarget}. Both `scope` and `id`\n * are required — the whole point of the scoped target is that a bare id is\n * ambiguous across scopes.\n * @public\n */\nexport const edgeTargetConverter: Converter<IEdgeTarget> = Converters.object<IEdgeTarget>({\n scope: Convert.scopeKey,\n id: Convert.memoryId\n});\n\n/**\n * Converter for the known {@link IProvenance} fields. The full\n * {@link provenanceConverter} layers extension-key preservation on top.\n * `derivedFrom` is serialized as the nested `{ scope, id }` object (mirroring\n * {@link edgeConverter | edge}'s scope-qualified `target`) so the provenance\n * back-reference is unambiguous across scopes.\n */\nconst knownProvenanceConverter: Converter<IProvenance> = Converters.object<IProvenance>(\n {\n source: Converters.string,\n by: Converters.string.optional(),\n model: Converters.string.optional(),\n confidence: Converters.number.optional(),\n derivedFrom: edgeTargetConverter.optional()\n },\n { optionalFields: ['by', 'model', 'confidence', 'derivedFrom'] }\n);\n\n/**\n * Converter for {@link IProvenance}. Validates the known fields and preserves\n * any extension keys verbatim (the `[key: string]: unknown` opaque payload),\n * so a round-trip never drops consumer-attached data.\n * @public\n */\nexport const provenanceConverter: Converter<IProvenance> = Converters.generic<IProvenance>(\n (from: unknown): Result<IProvenance> =>\n knownProvenanceConverter.convert(from).onSuccess((known) => {\n // `from` is guaranteed to be a non-null object here — the known-field\n // converter only succeeds on objects. Spread the original keys first,\n // then the validated/normalized known fields on top, so extension keys\n // survive while the known fields carry their converted values.\n const merged: IProvenance = { ...(from as Record<string, unknown>), ...known };\n return succeed(merged);\n })\n);\n\n/**\n * Converter for an attributed {@link IEdge}.\n * @public\n */\nexport const edgeConverter: Converter<IEdge> = Converters.object<IEdge>(\n {\n type: Convert.linkType,\n target: edgeTargetConverter,\n confidence: Converters.number.optional(),\n provenance: provenanceConverter.optional(),\n valid_at: Converters.number.optional(),\n invalid_at: numberOrNull.optional()\n },\n { optionalFields: ['confidence', 'provenance', 'valid_at', 'invalid_at'] }\n);\n\n/**\n * Converter for the optional {@link ITemporalBlock}.\n * @public\n */\nexport const temporalConverter: Converter<ITemporalBlock> = Converters.object<ITemporalBlock>(\n {\n valid_at: Converters.number.optional(),\n invalid_at: numberOrNull.optional()\n },\n { optionalFields: ['valid_at', 'invalid_at'] }\n);\n\n/**\n * Converter for the invariant {@link IMemoryEnvelope}. Validates a plain\n * object (e.g. parsed YAML frontmatter) into a typed envelope.\n * @public\n */\nexport const envelopeConverter: Converter<IMemoryEnvelope> = Converters.object<IMemoryEnvelope>(\n {\n id: Convert.memoryId,\n entityId: Convert.entityId,\n kind: Convert.kind,\n tags: Converters.arrayOf(Convert.tag),\n links: Converters.arrayOf(edgeConverter),\n created: Converters.number,\n updated: Converters.number,\n seq: Converters.number,\n contentHash: Converters.string,\n rank: Converters.number.optional(),\n provenance: provenanceConverter,\n temporal: temporalConverter.optional(),\n embeddingRef: stringOrNull.optional()\n },\n { optionalFields: ['rank', 'temporal', 'embeddingRef'] }\n);\n\n/**\n * Converter that parses a YAML frontmatter string into an\n * {@link IMemoryEnvelope}.\n * @public\n */\nexport const envelopeYamlConverter: Converter<IMemoryEnvelope> = Yaml.yamlConverter(envelopeConverter);\n\n/** The frontmatter delimiter line. */\nconst FRONTMATTER_DELIMITER: string = '---';\n\n/**\n * The two parts of a memory file: the YAML frontmatter (between the `---`\n * delimiters) and the markdown body (everything after the closing delimiter).\n * @public\n */\nexport interface IMemoryFileParts {\n /** The raw YAML frontmatter (delimiters stripped). */\n readonly frontmatter: string;\n /** The raw body text following the closing delimiter. */\n readonly body: string;\n}\n\n/**\n * Split a `---\\n<yaml>\\n---\\n<body>` memory file into its frontmatter and\n * body parts. Pure string handling — no external dependency.\n * @public\n */\nexport function splitFrontmatter(raw: string): Result<IMemoryFileParts> {\n // Split on '\\n' and strip a trailing '\\r' per line so CRLF-authored files\n // parse identically to LF — otherwise the '\\r' would ride along into the\n // returned frontmatter (perturbing YAML parsing) and body (corrupting\n // round-trip fidelity).\n const lines: string[] = raw.split('\\n').map((line) => (line.endsWith('\\r') ? line.slice(0, -1) : line));\n if (lines[0].trim() !== FRONTMATTER_DELIMITER) {\n return fail(\"memory file: missing opening frontmatter delimiter '---'\");\n }\n let closeIndex: number = -1;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i].trim() === FRONTMATTER_DELIMITER) {\n closeIndex = i;\n break;\n }\n }\n if (closeIndex === -1) {\n return fail(\"memory file: missing closing frontmatter delimiter '---'\");\n }\n return succeed({\n frontmatter: lines.slice(1, closeIndex).join('\\n'),\n body: lines.slice(closeIndex + 1).join('\\n')\n });\n}\n\n/**\n * Join a YAML frontmatter string and a body into the canonical\n * `---\\n<yaml>\\n---\\n<body>` memory-file format.\n * @public\n */\nexport function joinFrontmatter(frontmatter: string, body: string): string {\n const normalized: string = frontmatter.endsWith('\\n') ? frontmatter : `${frontmatter}\\n`;\n return `${FRONTMATTER_DELIMITER}\\n${normalized}${FRONTMATTER_DELIMITER}\\n${body}`;\n}\n\n/**\n * Parse a complete memory file into a typed {@link IMemoryRecord}. Splits the\n * frontmatter, validates the envelope, and dispatches the body through the\n * registered Converter for the envelope's kind.\n * @public\n */\nexport function parseMemoryFile(\n raw: string,\n registry: IBodyConverterRegistry\n): Result<IMemoryRecord<unknown>> {\n return splitFrontmatter(raw).onSuccess((parts) =>\n envelopeYamlConverter\n .convert(parts.frontmatter)\n .withErrorFormat((msg) => `memory file: invalid envelope: ${msg}`)\n .onSuccess((envelope) =>\n registry\n .convert(envelope.kind, parts.body)\n .withErrorFormat((msg) => `memory file '${envelope.id}': invalid body: ${msg}`)\n .onSuccess((body) => succeed({ envelope, body }))\n )\n );\n}\n\n/**\n * Serialize an envelope and its rendered body text into a memory file. The\n * envelope is emitted as YAML frontmatter; the body is written verbatim after\n * the closing delimiter.\n * @public\n */\nexport function serializeMemoryFile(envelope: IMemoryEnvelope, body: string): Result<string> {\n return Yaml.yamlStringify(envelope)\n .withErrorFormat((msg) => `memory file '${envelope.id}': failed to serialize envelope: ${msg}`)\n .onSuccess((frontmatter) => succeed(joinFrontmatter(frontmatter, body)));\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Result } from '@fgv/ts-utils';
|
|
2
|
-
import { IMemoryRecord, Kind,
|
|
2
|
+
import { IEdgeTarget, IMemoryRecord, Kind, MemoryScopeKey, Tag } from '../types';
|
|
3
3
|
/**
|
|
4
4
|
* The mutation a {@link IMemoryIndex.patch | patch} applies: a record was
|
|
5
5
|
* written (`'put'`) or removed (`'delete'`).
|
|
@@ -55,10 +55,20 @@ export interface IMemoryIndex {
|
|
|
55
55
|
/** All records in recency order (most-recently-updated first). */
|
|
56
56
|
byRecency(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
58
|
+
* All records ordered by store-computed {@link IMemoryEnvelope.rank} descending,
|
|
59
|
+
* with recency (most-recently-updated, then `seq`) as a tiebreak. Records with
|
|
60
|
+
* an absent `rank` sort LAST (after every ranked record), then by recency among
|
|
61
|
+
* themselves. Serves a bounded top-M ({@link IMemoryEnvelope.rank}-ordered) page
|
|
62
|
+
* from the in-memory index with no full-vault (filesystem) scan.
|
|
60
63
|
*/
|
|
61
|
-
|
|
64
|
+
byRank(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
65
|
+
/**
|
|
66
|
+
* The scope-qualified sources of records whose `links` point AT `target`
|
|
67
|
+
* (inbound edges), keyed on the target's `(scope, id)` address. The seed map
|
|
68
|
+
* for B2 link-traversal; results are {@link IEdgeTarget}s so a caller can feed
|
|
69
|
+
* them straight back in as further traversal seeds.
|
|
70
|
+
*/
|
|
71
|
+
backlinks(target: IEdgeTarget): ReadonlyArray<IEdgeTarget>;
|
|
62
72
|
}
|
|
63
73
|
/**
|
|
64
74
|
* Default in-memory {@link IMemoryIndex}. Maintains the derived `byKind` /
|
|
@@ -75,10 +85,13 @@ export declare class MemoryIndex implements IMemoryIndex {
|
|
|
75
85
|
/** tag → set of composite keys. */
|
|
76
86
|
private readonly _byTag;
|
|
77
87
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
88
|
+
* canonical target key (`edgeTargetKey`) → (source composite key → source
|
|
89
|
+
* {@link IEdgeTarget}). The OUTER map is keyed on the scope-qualified target's
|
|
90
|
+
* canonical `(scope, id)` string — NOT the target's bare id — so an edge to
|
|
91
|
+
* `turn-3` in one conversation is tracked separately from `turn-3` in another.
|
|
92
|
+
* The INNER map is keyed by the source's `(scope, id)` composite so two distinct
|
|
93
|
+
* source records that share an id across scopes are tracked independently and
|
|
94
|
+
* removing one never drops the other's edge.
|
|
82
95
|
*/
|
|
83
96
|
private readonly _backlinks;
|
|
84
97
|
private constructor();
|
|
@@ -103,19 +116,38 @@ export declare class MemoryIndex implements IMemoryIndex {
|
|
|
103
116
|
byTag(tag: Tag): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
104
117
|
/** {@inheritDoc IMemoryIndex.byRecency} */
|
|
105
118
|
byRecency(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
119
|
+
/** {@inheritDoc IMemoryIndex.byRank} */
|
|
120
|
+
byRank(): ReadonlyArray<IMemoryRecord<unknown>>;
|
|
106
121
|
/** {@inheritDoc IMemoryIndex.backlinks} */
|
|
107
|
-
backlinks(target:
|
|
122
|
+
backlinks(target: IEdgeTarget): ReadonlyArray<IEdgeTarget>;
|
|
108
123
|
/**
|
|
109
124
|
* Resolve a set of composite keys to their records, ordered
|
|
110
125
|
* most-recently-updated first (with a `seq` tiebreak so equal-`updated`
|
|
111
126
|
* records sort deterministically).
|
|
112
127
|
*/
|
|
113
128
|
private _recencyOrdered;
|
|
129
|
+
/**
|
|
130
|
+
* Resolve a set of composite keys to their records, ordered by
|
|
131
|
+
* {@link IMemoryEnvelope.rank} descending with recency (`updated`, then `seq`)
|
|
132
|
+
* as the tiebreak. Records with an absent `rank` sort LAST, then by recency
|
|
133
|
+
* among themselves. Computed on call (mirrors {@link MemoryIndex._recencyOrdered}) —
|
|
134
|
+
* no incremental rank-ordered view is maintained, matching the recency view's
|
|
135
|
+
* approach; the sort is over the in-memory index, never a filesystem walk.
|
|
136
|
+
*/
|
|
137
|
+
private _rankOrdered;
|
|
138
|
+
/**
|
|
139
|
+
* Rank-descending comparator with an absent-`rank`-last rule and a recency
|
|
140
|
+
* (`updated`, then `seq`) tiebreak. Duplicated from the retrieve packlet's
|
|
141
|
+
* `rankCompare` deliberately: the index must not depend on `retrieve` (that
|
|
142
|
+
* package depends on the index), mirroring how `_recencyOrdered` inlines the
|
|
143
|
+
* recency ordering rather than importing `recencyCompare`.
|
|
144
|
+
*/
|
|
145
|
+
private static _compareByRank;
|
|
114
146
|
/** Insert an entry and register all its derived associations. */
|
|
115
147
|
private _add;
|
|
116
148
|
/** Remove the entry at `key` (if present) and all its derived associations. */
|
|
117
149
|
private _remove;
|
|
118
|
-
/** Register `
|
|
150
|
+
/** Register `source` (keyed by its composite `sourceKey`) as linking at `target`. */
|
|
119
151
|
private _addBacklink;
|
|
120
152
|
/** Drop the backlink from `sourceKey` to `target`, removing the target map when empty. */
|
|
121
153
|
private _removeBacklink;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoryIndex.d.ts","sourceRoot":"","sources":["../../../src/packlets/index/memoryIndex.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAW,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"memoryIndex.d.ts","sourceRoot":"","sources":["../../../src/packlets/index/memoryIndex.ts"],"names":[],"mappings":"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"}
|