@seanhogg/builderforce-memory 2026.9.34 → 2026.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/errors/SSMError.d.ts +1 -1
- package/dist/errors/SSMError.d.ts.map +1 -1
- package/dist/errors/SSMError.js.map +1 -1
- package/dist/handoff/index.d.ts +5 -5
- package/dist/handoff/index.js +5 -5
- package/dist/handoff/note.d.ts +1 -1
- package/dist/handoff/note.js +1 -1
- package/dist/handoff/pack.d.ts +13 -4
- package/dist/handoff/pack.d.ts.map +1 -1
- package/dist/handoff/pack.js +31 -10
- package/dist/handoff/pack.js.map +1 -1
- package/dist/memory/MemoryStore.d.ts +120 -181
- package/dist/memory/MemoryStore.d.ts.map +1 -1
- package/dist/memory/MemoryStore.js +201 -389
- package/dist/memory/MemoryStore.js.map +1 -1
- package/dist/memory/SemanticRecall.d.ts +64 -0
- package/dist/memory/SemanticRecall.d.ts.map +1 -0
- package/dist/memory/SemanticRecall.js +188 -0
- package/dist/memory/SemanticRecall.js.map +1 -0
- package/dist/memory/records.d.ts +26 -0
- package/dist/memory/records.d.ts.map +1 -0
- package/dist/memory/records.js +71 -0
- package/dist/memory/records.js.map +1 -0
- package/dist/memory/ttlSweeper.d.ts +12 -0
- package/dist/memory/ttlSweeper.d.ts.map +1 -0
- package/dist/memory/ttlSweeper.js +28 -0
- package/dist/memory/ttlSweeper.js.map +1 -0
- package/dist/memory/types.d.ts +142 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +6 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/storage/ScopedFactRepository.d.ts +156 -0
- package/dist/storage/ScopedFactRepository.d.ts.map +1 -0
- package/dist/storage/ScopedFactRepository.js +278 -0
- package/dist/storage/ScopedFactRepository.js.map +1 -0
- package/dist/storage/factImport.d.ts +21 -0
- package/dist/storage/factImport.d.ts.map +1 -0
- package/dist/storage/factImport.js +61 -0
- package/dist/storage/factImport.js.map +1 -0
- package/dist/storage/factMutations.d.ts +46 -0
- package/dist/storage/factMutations.d.ts.map +1 -0
- package/dist/storage/factMutations.js +73 -0
- package/dist/storage/factMutations.js.map +1 -0
- package/dist/storage/factQueries.d.ts +16 -0
- package/dist/storage/factQueries.d.ts.map +1 -0
- package/dist/storage/factQueries.js +36 -0
- package/dist/storage/factQueries.js.map +1 -0
- package/dist/storage/factRetention.d.ts +30 -0
- package/dist/storage/factRetention.d.ts.map +1 -0
- package/dist/storage/factRetention.js +65 -0
- package/dist/storage/factRetention.js.map +1 -0
- package/dist/storage/fileLock.d.ts +56 -0
- package/dist/storage/fileLock.d.ts.map +1 -0
- package/dist/storage/fileLock.js +138 -0
- package/dist/storage/fileLock.js.map +1 -0
- package/dist/storage/fileTransaction.d.ts +33 -0
- package/dist/storage/fileTransaction.d.ts.map +1 -0
- package/dist/storage/fileTransaction.js +108 -0
- package/dist/storage/fileTransaction.js.map +1 -0
- package/dist/storage/idbAdapter.d.ts +95 -0
- package/dist/storage/idbAdapter.d.ts.map +1 -0
- package/dist/storage/idbAdapter.js +311 -0
- package/dist/storage/idbAdapter.js.map +1 -0
- package/dist/storage/nodeFileAdapter.d.ts +127 -0
- package/dist/storage/nodeFileAdapter.d.ts.map +1 -0
- package/dist/storage/nodeFileAdapter.js +275 -0
- package/dist/storage/nodeFileAdapter.js.map +1 -0
- package/dist/storage/syncJournal.d.ts +19 -0
- package/dist/storage/syncJournal.d.ts.map +1 -0
- package/dist/storage/syncJournal.js +46 -0
- package/dist/storage/syncJournal.js.map +1 -0
- package/dist/storage/types.d.ts +207 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +90 -0
- package/dist/storage/types.js.map +1 -0
- package/package.json +3 -3
- package/src/errors/SSMError.ts +1 -0
- package/src/handoff/handoff.test.ts +52 -2
- package/src/handoff/index.ts +5 -5
- package/src/handoff/note.ts +1 -1
- package/src/handoff/pack.ts +32 -9
- package/src/memory/MemoryStore.ts +245 -525
- package/src/memory/SemanticRecall.ts +204 -0
- package/src/memory/records.ts +79 -0
- package/src/memory/ttlSweeper.ts +29 -0
- package/src/memory/types.ts +149 -0
- package/src/storage/ScopedFactRepository.ts +373 -0
- package/src/storage/factImport.ts +73 -0
- package/src/storage/factMutations.ts +106 -0
- package/src/storage/factQueries.ts +41 -0
- package/src/storage/factRetention.ts +82 -0
- package/src/storage/fileLock.ts +162 -0
- package/src/storage/fileTransaction.ts +116 -0
- package/src/storage/idbAdapter.ts +373 -0
- package/src/storage/nodeFileAdapter.ts +331 -0
- package/src/storage/syncJournal.ts +47 -0
- package/src/storage/types.ts +262 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Runtime-level failures (bridge, distillation, memory) throw SSMError.
|
|
6
6
|
* Both carry a typed `code` discriminant for programmatic handling.
|
|
7
7
|
*/
|
|
8
|
-
export type SSMErrorCode = 'RUNTIME_DESTROYED' | 'BRIDGE_REQUEST_FAILED' | 'BRIDGE_RESPONSE_INVALID' | 'MEMORY_UNAVAILABLE' | 'DISTILL_FAILED' | 'UNKNOWN';
|
|
8
|
+
export type SSMErrorCode = 'RUNTIME_DESTROYED' | 'BRIDGE_REQUEST_FAILED' | 'BRIDGE_RESPONSE_INVALID' | 'MEMORY_UNAVAILABLE' | 'MEMORY_CONFLICT' | 'DISTILL_FAILED' | 'UNKNOWN';
|
|
9
9
|
export declare class SSMError extends Error {
|
|
10
10
|
readonly code: SSMErrorCode;
|
|
11
11
|
readonly cause?: unknown | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SSMError.d.ts","sourceRoot":"","sources":["../../src/errors/SSMError.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,YAAY,GAClB,mBAAmB,GACnB,uBAAuB,GACvB,yBAAyB,GACzB,oBAAoB,GACpB,gBAAgB,GAChB,SAAS,CAAC;AAEhB,qBAAa,QAAS,SAAQ,KAAK;aAEX,IAAI,EAAE,YAAY;aAElB,KAAK,CAAC,EAAE,OAAO;gBAFf,IAAI,EAAE,YAAY,EAClC,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,OAAO,YAAA;CAKtC"}
|
|
1
|
+
{"version":3,"file":"SSMError.d.ts","sourceRoot":"","sources":["../../src/errors/SSMError.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,YAAY,GAClB,mBAAmB,GACnB,uBAAuB,GACvB,yBAAyB,GACzB,oBAAoB,GACpB,iBAAiB,GACjB,gBAAgB,GAChB,SAAS,CAAC;AAEhB,qBAAa,QAAS,SAAQ,KAAK;aAEX,IAAI,EAAE,YAAY;aAElB,KAAK,CAAC,EAAE,OAAO;gBAFf,IAAI,EAAE,YAAY,EAClC,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,OAAO,YAAA;CAKtC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SSMError.js","sourceRoot":"","sources":["../../src/errors/SSMError.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"SSMError.js","sourceRoot":"","sources":["../../src/errors/SSMError.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,MAAM,OAAO,QAAS,SAAQ,KAAK;IAEX;IAEA;IAHpB,YACoB,IAAkB,EAClC,OAAe,EACC,KAAe;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAc;QAElB,UAAK,GAAL,KAAK,CAAU;QAG/B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IAC3B,CAAC;CACJ"}
|
package/dist/handoff/index.d.ts
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Model hand-off packing — the `@seanhogg/builderforce-memory/handoff` subpath (PRD 34 §3.3).
|
|
3
3
|
*
|
|
4
4
|
* When a conversation moves to another model (a local one with a small window, say),
|
|
5
|
-
* {@link packHandoff} fits the transcript into that model's budget: the system
|
|
6
|
-
* stay, the latest user directive stays verbatim, tool calls are never
|
|
7
|
-
* results, the verbatim tail takes what the budget allows, and the
|
|
8
|
-
* ONE
|
|
9
|
-
* note when the models differ).
|
|
5
|
+
* {@link packHandoff} fits the transcript into that model's budget: the leading system
|
|
6
|
+
* message(s) stay first, the latest user directive stays verbatim, tool calls are never
|
|
7
|
+
* split from their results, the verbatim tail takes what the budget allows, and the
|
|
8
|
+
* dropped middle becomes ONE note (summary → memory recall → elision marker, with a
|
|
9
|
+
* one-line hand-off note when the models differ) whose role keeps turns alternating.
|
|
10
10
|
*
|
|
11
11
|
* Pure: no WebGPU, no IndexedDB, no `node:*` — runs in a Cloudflare Worker, a browser
|
|
12
12
|
* page and Node alike.
|
package/dist/handoff/index.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Model hand-off packing — the `@seanhogg/builderforce-memory/handoff` subpath (PRD 34 §3.3).
|
|
3
3
|
*
|
|
4
4
|
* When a conversation moves to another model (a local one with a small window, say),
|
|
5
|
-
* {@link packHandoff} fits the transcript into that model's budget: the system
|
|
6
|
-
* stay, the latest user directive stays verbatim, tool calls are never
|
|
7
|
-
* results, the verbatim tail takes what the budget allows, and the
|
|
8
|
-
* ONE
|
|
9
|
-
* note when the models differ).
|
|
5
|
+
* {@link packHandoff} fits the transcript into that model's budget: the leading system
|
|
6
|
+
* message(s) stay first, the latest user directive stays verbatim, tool calls are never
|
|
7
|
+
* split from their results, the verbatim tail takes what the budget allows, and the
|
|
8
|
+
* dropped middle becomes ONE note (summary → memory recall → elision marker, with a
|
|
9
|
+
* one-line hand-off note when the models differ) whose role keeps turns alternating.
|
|
10
10
|
*
|
|
11
11
|
* Pure: no WebGPU, no IndexedDB, no `node:*` — runs in a Cloudflare Worker, a browser
|
|
12
12
|
* page and Node alike.
|
package/dist/handoff/note.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The ONE
|
|
2
|
+
* The ONE note that stands in for the dropped middle of a handed-off
|
|
3
3
|
* transcript: an optional one-line hand-off note, then the first body source that
|
|
4
4
|
* succeeds — the `summarize` result, else the `recall` memory block for the latest
|
|
5
5
|
* directive, else an elision marker. A failing, timing-out or empty source falls through
|
package/dist/handoff/note.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The ONE
|
|
2
|
+
* The ONE note that stands in for the dropped middle of a handed-off
|
|
3
3
|
* transcript: an optional one-line hand-off note, then the first body source that
|
|
4
4
|
* succeeds — the `summarize` result, else the `recall` memory block for the latest
|
|
5
5
|
* directive, else an elision marker. A failing, timing-out or empty source falls through
|
package/dist/handoff/pack.d.ts
CHANGED
|
@@ -4,13 +4,22 @@
|
|
|
4
4
|
* Shape of the result, mirroring Builderforce's `assembleCompacted`
|
|
5
5
|
* (brain-embedded/src/workingTranscript.ts):
|
|
6
6
|
*
|
|
7
|
-
* system message(s) · ONE
|
|
7
|
+
* leading system message(s) · ONE note for the dropped middle · the latest user
|
|
8
8
|
* directive re-injected verbatim (only when it fell in the middle) · the verbatim tail
|
|
9
9
|
*
|
|
10
|
+
* Only the LEADING run of system messages is the fixed prefix. A system message later in
|
|
11
|
+
* the conversation stays where it was: in the tail when the tail reaches it, else in the
|
|
12
|
+
* dropped middle — never hoisted to the front, where it would read as if it governed the
|
|
13
|
+
* whole conversation.
|
|
14
|
+
*
|
|
15
|
+
* The note's role keeps turns alternating: it is an `assistant` note when a user turn (the
|
|
16
|
+
* re-injected directive, or a tail that starts with one) follows it, and a `user` note
|
|
17
|
+
* when an assistant turn follows or nothing does — never two assistant turns in a row.
|
|
18
|
+
*
|
|
10
19
|
* The tail is the longest run of whole units (see `segments.ts`) from the end that fits
|
|
11
|
-
* what is left after the
|
|
12
|
-
*
|
|
13
|
-
*
|
|
20
|
+
* what is left after the prefix, the directive and room for an elision marker. Whatever
|
|
21
|
+
* room the tail leaves is the note's: summary, else recall, else the marker. The result
|
|
22
|
+
* never exceeds the budget unless the prefix + directive alone do.
|
|
14
23
|
*/
|
|
15
24
|
import type { HandoffPack, HandoffPackInput } from './types.js';
|
|
16
25
|
export declare function packHandoff(input: HandoffPackInput): Promise<HandoffPack>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../src/handoff/pack.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../src/handoff/pack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAAkB,WAAW,EAAE,gBAAgB,EAAkB,MAAM,YAAY,CAAC;AAyEhG,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAuD/E"}
|
package/dist/handoff/pack.js
CHANGED
|
@@ -4,17 +4,37 @@
|
|
|
4
4
|
* Shape of the result, mirroring Builderforce's `assembleCompacted`
|
|
5
5
|
* (brain-embedded/src/workingTranscript.ts):
|
|
6
6
|
*
|
|
7
|
-
* system message(s) · ONE
|
|
7
|
+
* leading system message(s) · ONE note for the dropped middle · the latest user
|
|
8
8
|
* directive re-injected verbatim (only when it fell in the middle) · the verbatim tail
|
|
9
9
|
*
|
|
10
|
+
* Only the LEADING run of system messages is the fixed prefix. A system message later in
|
|
11
|
+
* the conversation stays where it was: in the tail when the tail reaches it, else in the
|
|
12
|
+
* dropped middle — never hoisted to the front, where it would read as if it governed the
|
|
13
|
+
* whole conversation.
|
|
14
|
+
*
|
|
15
|
+
* The note's role keeps turns alternating: it is an `assistant` note when a user turn (the
|
|
16
|
+
* re-injected directive, or a tail that starts with one) follows it, and a `user` note
|
|
17
|
+
* when an assistant turn follows or nothing does — never two assistant turns in a row.
|
|
18
|
+
*
|
|
10
19
|
* The tail is the longest run of whole units (see `segments.ts`) from the end that fits
|
|
11
|
-
* what is left after the
|
|
12
|
-
*
|
|
13
|
-
*
|
|
20
|
+
* what is left after the prefix, the directive and room for an elision marker. Whatever
|
|
21
|
+
* room the tail leaves is the note's: summary, else recall, else the marker. The result
|
|
22
|
+
* never exceeds the budget unless the prefix + directive alone do.
|
|
14
23
|
*/
|
|
15
24
|
import { defaultEstimateTokens, handoffBudget, messageTokens, tokensOf } from './budget.js';
|
|
16
25
|
import { buildNote, composeNote, elisionMarker, handoffLine, noteTokens } from './note.js';
|
|
17
26
|
import { segmentTranscript } from './segments.js';
|
|
27
|
+
/** Length of the leading run of `system` messages. */
|
|
28
|
+
function leadingSystemCount(all) {
|
|
29
|
+
let n = 0;
|
|
30
|
+
while (n < all.length && all[n].role === 'system')
|
|
31
|
+
n += 1;
|
|
32
|
+
return n;
|
|
33
|
+
}
|
|
34
|
+
/** The note's role: `user` before an assistant turn (or at the end), else `assistant`. */
|
|
35
|
+
function noteRole(next) {
|
|
36
|
+
return next === undefined || next.role === 'assistant' ? 'user' : 'assistant';
|
|
37
|
+
}
|
|
18
38
|
/** Index of the last `user` message, or -1. */
|
|
19
39
|
function latestDirectiveIndex(convo) {
|
|
20
40
|
for (let i = convo.length - 1; i >= 0; i--)
|
|
@@ -64,8 +84,9 @@ export async function packHandoff(input) {
|
|
|
64
84
|
// Under budget: hand the transcript over untouched.
|
|
65
85
|
if (tokensOf(all, estimate) <= budget)
|
|
66
86
|
return result(all.slice(), 0, estimate);
|
|
67
|
-
const
|
|
68
|
-
const
|
|
87
|
+
const prefixLen = leadingSystemCount(all);
|
|
88
|
+
const system = all.slice(0, prefixLen);
|
|
89
|
+
const convo = all.slice(prefixLen);
|
|
69
90
|
const systemTokens = tokensOf(system, estimate);
|
|
70
91
|
const directiveIdx = latestDirectiveIndex(convo);
|
|
71
92
|
const directive = directiveIdx >= 0 ? convo[directiveIdx] : undefined;
|
|
@@ -96,12 +117,12 @@ export async function packHandoff(input) {
|
|
|
96
117
|
timeoutMs: input.timeoutMs,
|
|
97
118
|
})
|
|
98
119
|
: null;
|
|
120
|
+
const after = reinject && directive ? [directive] : [];
|
|
121
|
+
after.push(...convo.slice(tail.start));
|
|
99
122
|
const messages = [...system];
|
|
100
123
|
if (note)
|
|
101
|
-
messages.push({ role:
|
|
102
|
-
|
|
103
|
-
messages.push(directive);
|
|
104
|
-
messages.push(...convo.slice(tail.start));
|
|
124
|
+
messages.push({ role: noteRole(after[0]), content: note.text });
|
|
125
|
+
messages.push(...after);
|
|
105
126
|
return result(messages, droppedMsgs.length, estimate, {
|
|
106
127
|
summarized: note?.summarized ?? false,
|
|
107
128
|
recalled: note?.recalled ?? false,
|
package/dist/handoff/pack.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack.js","sourceRoot":"","sources":["../../src/handoff/pack.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"pack.js","sourceRoot":"","sources":["../../src/handoff/pack.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,149 +1,104 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MemoryStore – persistent key-value fact store and weight checkpoint helper.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
4
|
+
* Persistence is delegated to a narrow {@link FactStoragePort} (M01) fronted by
|
|
5
|
+
* a {@link ScopedFactRepository} unit-of-work layer (M02–M06):
|
|
6
|
+
* - Browser default: IndexedDB via {@link IdbStorageAdapter}; every write
|
|
7
|
+
* resolves only after the transaction commits (M02).
|
|
8
|
+
* - Node.js: pass `storage: await NodeFileStorageAdapter.open(path)` for real
|
|
9
|
+
* durable storage. fake-indexeddb via `idbFactory` remains supported for
|
|
10
|
+
* TESTS, but is never durable and is not presented as such.
|
|
11
|
+
* - Facts live in an explicit {@link MemoryScope} partition (default: the
|
|
12
|
+
* unbound, never-connected scope) with durable revisions, operation
|
|
13
|
+
* identity, provenance and — when `sync: true` — a journaled tombstone
|
|
14
|
+
* trail that caps/TTL will not sacrifice (M03/M04/M06).
|
|
15
|
+
*
|
|
16
|
+
* Recall ranking and its derived embedding/index caches live in
|
|
17
|
+
* {@link SemanticRecall}; the public shapes in `./types.ts`.
|
|
7
18
|
*
|
|
8
19
|
* Weight save/load is delegated to the SSMRuntime passed to saveWeights/loadWeights.
|
|
9
20
|
*/
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* answered.
|
|
38
|
-
*/
|
|
39
|
-
export type RecallMethod = 'embedding' | 'lexical';
|
|
40
|
-
/** A recalled entry with its relevance score (higher = closer). */
|
|
41
|
-
export interface ScoredMemory {
|
|
42
|
-
entry: MemoryEntry;
|
|
43
|
-
score: number;
|
|
44
|
-
}
|
|
45
|
-
/** A ranked recall: the hits plus the ranker that ordered them. */
|
|
46
|
-
export interface RankedRecall {
|
|
47
|
-
hits: ScoredMemory[];
|
|
48
|
-
method: RecallMethod;
|
|
49
|
-
}
|
|
50
|
-
export interface RememberOptions {
|
|
51
|
-
/** Override the store-level defaultTtlMs for this entry. */
|
|
52
|
-
ttlMs?: number;
|
|
53
|
-
type?: FactType;
|
|
54
|
-
tags?: string[];
|
|
55
|
-
importance?: number;
|
|
56
|
-
}
|
|
57
|
-
export interface MemoryStoreOptions {
|
|
58
|
-
/** IndexedDB database name. Default: 'ssmjs'. */
|
|
59
|
-
dbName?: string;
|
|
60
|
-
/** Key used for weight storage within the 'weights' object store. Default: 'ssmjs-weights'. */
|
|
61
|
-
weightsKey?: string;
|
|
62
|
-
/**
|
|
63
|
-
* IDBFactory to use instead of the global `indexedDB`.
|
|
64
|
-
* Use this in Node.js environments with fake-indexeddb:
|
|
65
|
-
* import { IDBFactory } from 'fake-indexeddb';
|
|
66
|
-
* const idbFactory = new IDBFactory();
|
|
67
|
-
*/
|
|
68
|
-
idbFactory?: IDBFactory;
|
|
69
|
-
/**
|
|
70
|
-
* Default TTL applied to new entries when no per-entry ttlMs is provided.
|
|
71
|
-
* Entries with an expired TTL are filtered from recallAll() and related methods.
|
|
72
|
-
*/
|
|
73
|
-
defaultTtlMs?: number;
|
|
21
|
+
import type { HybridRetrieveOptions } from '../retrieval/index.js';
|
|
22
|
+
import { IdbStorageAdapter } from '../storage/idbAdapter.js';
|
|
23
|
+
import { ScopedFactRepository } from '../storage/ScopedFactRepository.js';
|
|
24
|
+
import { MemoryStorageError, type ConsistencyNote, type FactProvenance, type FactStoragePort, type MemoryScope, type StoredFactRecord, type TombstoneRecord, type JournalEntry } from '../storage/types.js';
|
|
25
|
+
import type { MemoryEntry, MemoryStoreOptions, RankedRecall, RememberOptions, SaveLoadRuntime, ScoredMemory, SSMRuntimeRef } from './types.js';
|
|
26
|
+
export type { FactType, MemoryEntry, MemoryStoreOptions, RankedRecall, RecallMethod, RememberOptions, ScoredMemory, } from './types.js';
|
|
27
|
+
export declare class MemoryStore {
|
|
28
|
+
private readonly _weightsKey;
|
|
29
|
+
private readonly _defaultTtl;
|
|
30
|
+
private readonly _maxEntries;
|
|
31
|
+
private readonly _scope;
|
|
32
|
+
/** The unit-of-work layer every durable operation flows through. */
|
|
33
|
+
readonly repository: ScopedFactRepository;
|
|
34
|
+
private readonly _storage;
|
|
35
|
+
/** Cross-context subscription, opened on the first operation (see `_ready`). */
|
|
36
|
+
private _unsubscribe;
|
|
37
|
+
private _subscribed;
|
|
38
|
+
private readonly _sweeper;
|
|
39
|
+
/** Ranking + its embedding / dense-index caches (EVM-1, EVM-1b, EVM-8). */
|
|
40
|
+
private readonly _recall;
|
|
41
|
+
/**
|
|
42
|
+
* Last store generation observed from a FOREIGN context (another tab,
|
|
43
|
+
* window or process). Monotonic, in-memory only; lets readers notice
|
|
44
|
+
* cross-context writes without a storage round-trip per recall (M05).
|
|
45
|
+
*/
|
|
46
|
+
private _foreignRevision;
|
|
47
|
+
constructor(opts?: MemoryStoreOptions);
|
|
74
48
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
49
|
+
* Cross-context invalidation (M05): a sibling tab/window/process that
|
|
50
|
+
* commits against the same storage invalidates this instance's derived
|
|
51
|
+
* caches. Subscribed lazily on the first operation: before it there are no
|
|
52
|
+
* caches to invalidate, and an eager subscription opened a global
|
|
53
|
+
* BroadcastChannel in the constructor that kept Node processes alive.
|
|
78
54
|
*/
|
|
79
|
-
|
|
55
|
+
private _ready;
|
|
56
|
+
/** The scope partition this store is bound to (never widened implicitly). */
|
|
57
|
+
get scope(): MemoryScope;
|
|
58
|
+
/** The durable storage backend kind in use ('indexedDB' | 'node-file'). */
|
|
59
|
+
get storageKind(): FactStoragePort['kind'];
|
|
80
60
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
61
|
+
* Best-effort in-memory token that changes when another context writes to
|
|
62
|
+
* this store's database. Readers (e.g. EvermindCognition's recall cache)
|
|
63
|
+
* can fold it into their cache key so cross-context writes invalidate
|
|
64
|
+
* without a storage hit per recall.
|
|
84
65
|
*/
|
|
85
|
-
|
|
66
|
+
get foreignRevision(): number;
|
|
67
|
+
private _onForeignChange;
|
|
86
68
|
/**
|
|
87
|
-
*
|
|
88
|
-
* (
|
|
69
|
+
* Stores or overwrites a fact. Resolves only after the underlying
|
|
70
|
+
* transaction commits durably (M02); the fact, its provenance and its sync
|
|
71
|
+
* journal entry commit atomically.
|
|
89
72
|
*/
|
|
90
|
-
embedCacheMax?: number;
|
|
91
|
-
}
|
|
92
|
-
interface SaveLoadRuntime {
|
|
93
|
-
save(opts?: {
|
|
94
|
-
storage: 'indexedDB';
|
|
95
|
-
key: string;
|
|
96
|
-
}): Promise<void>;
|
|
97
|
-
load(opts?: {
|
|
98
|
-
key: string;
|
|
99
|
-
}): Promise<boolean>;
|
|
100
|
-
}
|
|
101
|
-
type SSMRuntimeRef = any;
|
|
102
|
-
export declare class MemoryStore {
|
|
103
|
-
private readonly _dbName;
|
|
104
|
-
private readonly _weightsKey;
|
|
105
|
-
private readonly _idb;
|
|
106
|
-
private readonly _defaultTtl;
|
|
107
|
-
private readonly _annThreshold;
|
|
108
|
-
private readonly _maxEntries;
|
|
109
|
-
private readonly _embedCacheMax;
|
|
110
|
-
private _db;
|
|
111
|
-
private _sweepTimer;
|
|
112
|
-
/** Content → L2-normalised embedding cache, used by recallSimilar. */
|
|
113
|
-
private readonly _embedCache;
|
|
114
|
-
/** Runtime whose embeddings populate `_embedCache`; a change invalidates it. */
|
|
115
|
-
private _embedRuntime;
|
|
116
|
-
private readonly _denseVectors;
|
|
117
|
-
private _denseIndex;
|
|
118
|
-
/** Signature of the fact set the current index was built from. */
|
|
119
|
-
private _denseSig;
|
|
120
|
-
/** Identity of the runtime whose embeddings populated the vectors. */
|
|
121
|
-
private _denseRuntime;
|
|
122
|
-
constructor(opts?: MemoryStoreOptions);
|
|
123
|
-
private _open;
|
|
124
|
-
private _isExpired;
|
|
125
|
-
/** Stores or overwrites a fact. */
|
|
126
73
|
remember(key: string, content: string, opts?: RememberOptions): Promise<void>;
|
|
127
74
|
/**
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
75
|
+
* Compare-and-set write (M04/M05): commits only if the record's current
|
|
76
|
+
* revision equals `expectedRevision` (`null` asserts the key is absent).
|
|
77
|
+
* Throws a MemoryStorageError otherwise (`code` 'MEMORY_CONFLICT',
|
|
78
|
+
* `storageCode` 'STORAGE_CONFLICT'; see `isStorageConflict`) — callers reconcile
|
|
79
|
+
* (re-read, re-evaluate evidence) instead of blindly overwriting a
|
|
80
|
+
* concurrent writer. Returns the committed entry.
|
|
131
81
|
*/
|
|
132
|
-
|
|
82
|
+
rememberCas(key: string, content: string, expectedRevision: number | null, opts?: RememberOptions): Promise<MemoryEntry>;
|
|
83
|
+
/** Fetches an entry WITH its durable revision, for CAS-based reconciliation. */
|
|
84
|
+
recallVersioned(key: string): Promise<MemoryEntry | undefined>;
|
|
133
85
|
/**
|
|
134
|
-
* Starts a background timer that periodically
|
|
86
|
+
* Starts a background timer that periodically deletes expired entries —
|
|
135
87
|
* TTL is otherwise only evaluated lazily on read, so an idle store would keep
|
|
136
88
|
* dead entries forever. Idempotent; pair with {@link stopTtlSweeper}. (EVM-7)
|
|
89
|
+
*
|
|
90
|
+
* With sync enabled each expiry is a scoped deletion (tombstone + journal),
|
|
91
|
+
* not a silent drop (M06).
|
|
137
92
|
*/
|
|
138
93
|
startTtlSweeper(intervalMs: number): void;
|
|
139
94
|
/** Stops the background TTL sweeper started by {@link startTtlSweeper}. */
|
|
140
95
|
stopTtlSweeper(): void;
|
|
141
96
|
/**
|
|
142
|
-
* Retrieves a fact by key.
|
|
97
|
+
* Retrieves a fact by key from this store's scope partition.
|
|
143
98
|
* Returns `undefined` if the key does not exist or the entry has expired.
|
|
144
99
|
*/
|
|
145
100
|
recall(key: string): Promise<MemoryEntry | undefined>;
|
|
146
|
-
/** Returns all non-expired stored facts, newest first. */
|
|
101
|
+
/** Returns all non-expired stored facts in this store's scope, newest first. */
|
|
147
102
|
recallAll(): Promise<MemoryEntry[]>;
|
|
148
103
|
/**
|
|
149
104
|
* Returns the N most recently updated non-expired facts.
|
|
@@ -152,19 +107,15 @@ export declare class MemoryStore {
|
|
|
152
107
|
recallRecent(n: number): Promise<MemoryEntry[]>;
|
|
153
108
|
/**
|
|
154
109
|
* Returns all non-expired entries that contain the given tag.
|
|
110
|
+
* Looks the tag up on the facts `byTag` index when the storage adapter has
|
|
111
|
+
* one; a full scan is used only when that index is missing.
|
|
155
112
|
*/
|
|
156
113
|
recallByTag(tag: string): Promise<MemoryEntry[]>;
|
|
157
114
|
/**
|
|
158
|
-
* Finds the top-K semantically similar entries to `query
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
* memory layer uses the very model it is attached to, and recall quality
|
|
163
|
-
* improves automatically as that model is adapted/distilled. Embeddings are
|
|
164
|
-
* cached per content string to avoid recomputing across calls.
|
|
165
|
-
*
|
|
166
|
-
* If no embedding-capable runtime is provided, or embedding fails for any
|
|
167
|
-
* reason, it transparently falls back to Jaccard word-overlap similarity.
|
|
115
|
+
* Finds the top-K semantically similar entries to `query`: cosine over the
|
|
116
|
+
* attached SSM runtime's embeddings (so recall improves as that model is
|
|
117
|
+
* adapted), or Jaccard word overlap when no runtime can embed. See
|
|
118
|
+
* {@link SemanticRecall}.
|
|
168
119
|
*/
|
|
169
120
|
recallSimilar(query: string, topK: number, runtime?: SSMRuntimeRef): Promise<MemoryEntry[]>;
|
|
170
121
|
/**
|
|
@@ -173,80 +124,67 @@ export declare class MemoryStore {
|
|
|
173
124
|
* so callers can rank/threshold by TRUE similarity instead of list position.
|
|
174
125
|
* {@link recallSimilar} is the score-dropping convenience wrapper over this.
|
|
175
126
|
*/
|
|
176
|
-
recallSimilarScored(query: string, topK: number, runtime?: SSMRuntimeRef): Promise<
|
|
177
|
-
entry: MemoryEntry;
|
|
178
|
-
score: number;
|
|
179
|
-
}>>;
|
|
127
|
+
recallSimilarScored(query: string, topK: number, runtime?: SSMRuntimeRef): Promise<ScoredMemory[]>;
|
|
180
128
|
/**
|
|
181
|
-
* Hybrid recall:
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
* (embeddings) and exact-token matches (BM25 — identifiers, codes, rare names)
|
|
186
|
-
* that cosine-only `recallSimilar` misses, and avoids returning near-duplicate
|
|
187
|
-
* facts. Degrades to BM25-only when no embedding-capable runtime is available,
|
|
188
|
-
* so it is always strictly at least as good as the lexical fallback.
|
|
129
|
+
* Hybrid recall: dense (SSM-embedding cosine) and sparse (BM25) rankings
|
|
130
|
+
* fused by Reciprocal Rank Fusion, then an MMR diversity rerank — catches
|
|
131
|
+
* exact-token matches cosine misses, and degrades to BM25 alone without a
|
|
132
|
+
* runtime. The production RAG path.
|
|
189
133
|
*/
|
|
190
134
|
recallHybrid(query: string, topK: number, runtime?: SSMRuntimeRef, opts?: HybridRetrieveOptions): Promise<MemoryEntry[]>;
|
|
191
135
|
/**
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
* there is exactly one implementation of the blend — and it is the shared
|
|
197
|
-
* `hybridRetrieve` → `reciprocalRankFusion` primitive, never a second hand-
|
|
198
|
-
* rolled mix of cosine and word overlap.
|
|
199
|
-
*
|
|
200
|
-
* `method` is honest rather than aspirational: `'embedding'` means the query
|
|
201
|
-
* really did embed and the dense ranking really did participate in the fusion;
|
|
202
|
-
* `'lexical'` means no model was available (or embedding failed) and the
|
|
203
|
-
* ordering is BM25 alone. Callers surface it so a user can tell semantic
|
|
204
|
-
* recall from the fallback instead of guessing.
|
|
136
|
+
* {@link recallHybrid} with its evidence: each hit's fused score, and WHICH
|
|
137
|
+
* ranker produced the ordering — `'embedding'` only when the query and the
|
|
138
|
+
* candidates really embedded, `'lexical'` when the ordering is BM25 alone.
|
|
139
|
+
* One blend implementation: the shared `hybridRetrieve` primitive.
|
|
205
140
|
*/
|
|
206
141
|
recallRanked(query: string, topK: number, runtime?: SSMRuntimeRef, opts?: HybridRetrieveOptions): Promise<RankedRecall>;
|
|
207
142
|
/**
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
*/
|
|
212
|
-
private _embedWithCache;
|
|
213
|
-
/**
|
|
214
|
-
* Synchronise the persistent dense vector store + HNSW index to `all` (EVM-1b).
|
|
215
|
-
* Embeds ONLY new/changed facts (keyed by `key@seq`), prunes removed ones, and
|
|
216
|
-
* rebuilds the index only when the fact set actually changed — so a read-heavy
|
|
217
|
-
* workload reuses both the embeddings and the index across recalls. Returns
|
|
218
|
-
* `null` (caller falls back to lexical) if any embedding is unavailable, or
|
|
219
|
-
* resets everything when the runtime identity changes (embeddings are
|
|
220
|
-
* model-specific).
|
|
221
|
-
*/
|
|
222
|
-
private _syncDense;
|
|
223
|
-
/**
|
|
224
|
-
* Hard-deletes all entries whose TTL has expired.
|
|
143
|
+
* Deletes all entries whose TTL has expired. With sync enabled each expiry
|
|
144
|
+
* commits a tombstone + journal entry in the same transaction, so expiries
|
|
145
|
+
* propagate instead of resurrecting from a replica (M06).
|
|
225
146
|
* @returns The number of entries deleted.
|
|
226
147
|
*/
|
|
227
148
|
purgeExpired(): Promise<number>;
|
|
228
|
-
/**
|
|
149
|
+
/**
|
|
150
|
+
* Deletes a single fact. No-op if key does not exist. With sync enabled the
|
|
151
|
+
* delete is a durable tombstone + journal entry committed atomically (M04).
|
|
152
|
+
*/
|
|
229
153
|
forget(key: string): Promise<void>;
|
|
230
|
-
/** Deletes all facts. Does not affect saved weights. */
|
|
154
|
+
/** Deletes all facts in this store's scope. Does not affect saved weights. */
|
|
231
155
|
clear(): Promise<void>;
|
|
156
|
+
/** Operations not yet acknowledged by sync — the pending knowledge set. */
|
|
157
|
+
pendingOps(): Promise<JournalEntry[]>;
|
|
158
|
+
/** Delete tombstones in this store's scope (or all scopes when omitted). */
|
|
159
|
+
tombstones(scope?: MemoryScope): Promise<TombstoneRecord[]>;
|
|
160
|
+
/**
|
|
161
|
+
* Acknowledges that the given operations reached the sync target. Their
|
|
162
|
+
* facts/tombstones stop being `pendingSync`, so retention may touch them
|
|
163
|
+
* again. Retention NEVER touches unacknowledged knowledge (M06).
|
|
164
|
+
*/
|
|
165
|
+
markSynced(opIds: string[]): Promise<void>;
|
|
166
|
+
/** The current durable store generation. */
|
|
167
|
+
revision(): Promise<number>;
|
|
168
|
+
/** Releases cross-context subscriptions and the underlying connection. */
|
|
169
|
+
close(): void;
|
|
232
170
|
/**
|
|
233
171
|
* Returns all non-expired facts as a plain array for export.
|
|
234
|
-
*
|
|
172
|
+
* Scope, revision and provenance travel with each entry (M03).
|
|
235
173
|
*/
|
|
236
174
|
exportAll(): Promise<MemoryEntry[]>;
|
|
237
175
|
/**
|
|
238
|
-
* Imports entries from an external array.
|
|
176
|
+
* Imports entries from an external array INTO this store's scope partition.
|
|
177
|
+
* Source timestamps, sequences, tags, importance, TTL and provenance are
|
|
178
|
+
* preserved — import never rewrites source time (M06).
|
|
239
179
|
*
|
|
240
180
|
* - `'merge'` : only writes an entry if no existing entry with the same
|
|
241
181
|
* key exists, or if the incoming entry has a newer timestamp.
|
|
242
182
|
* - `'overwrite'` : writes all entries unconditionally.
|
|
243
183
|
*/
|
|
244
|
-
importAll(entries: MemoryEntry[], strategy: 'merge' | 'overwrite'): Promise<void>;
|
|
245
|
-
/** Writes a raw MemoryEntry directly (preserves original timestamp / metadata). */
|
|
246
|
-
private _putRaw;
|
|
184
|
+
importAll(entries: MemoryEntry[], strategy: 'merge' | 'overwrite', importedFrom?: string): Promise<void>;
|
|
247
185
|
/**
|
|
248
186
|
* Saves SSM weights via `runtime.save()`.
|
|
249
|
-
* The weights are stored under `weightsKey` in
|
|
187
|
+
* The weights are stored under `weightsKey` in the session's IndexedDB,
|
|
250
188
|
* separate from MambaSession's own key.
|
|
251
189
|
*/
|
|
252
190
|
saveWeights(runtime: SaveLoadRuntime): Promise<void>;
|
|
@@ -256,5 +194,6 @@ export declare class MemoryStore {
|
|
|
256
194
|
*/
|
|
257
195
|
loadWeights(runtime: SaveLoadRuntime): Promise<boolean>;
|
|
258
196
|
}
|
|
259
|
-
export {};
|
|
197
|
+
export { IdbStorageAdapter, ScopedFactRepository, MemoryStorageError, };
|
|
198
|
+
export type { ConsistencyNote, FactProvenance, FactStoragePort, JournalEntry, MemoryScope, StoredFactRecord, TombstoneRecord, };
|
|
260
199
|
//# sourceMappingURL=MemoryStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoryStore.d.ts","sourceRoot":"","sources":["../../src/memory/MemoryStore.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"MemoryStore.d.ts","sourceRoot":"","sources":["../../src/memory/MemoryStore.ts"],"names":[],"mappings":"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"}
|