@graphorin/memory 0.6.0 → 0.7.0
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/CHANGELOG.md +83 -0
- package/README.md +24 -7
- package/dist/conflict/index.js +0 -1
- package/dist/conflict/pipeline.js +0 -1
- package/dist/conflict/pipeline.js.map +1 -1
- package/dist/conflict/stages/stage3-heuristic-regex.js +0 -1
- package/dist/conflict/stages/stage3-heuristic-regex.js.map +1 -1
- package/dist/conflict/types.d.ts +1 -1
- package/dist/conflict/types.js.map +1 -1
- package/dist/consolidator/index.js +2 -0
- package/dist/consolidator/index.js.map +1 -1
- package/dist/consolidator/lock.js +7 -1
- package/dist/consolidator/lock.js.map +1 -1
- package/dist/consolidator/phases/deep.js +19 -12
- package/dist/consolidator/phases/deep.js.map +1 -1
- package/dist/consolidator/phases/induce.d.ts.map +1 -1
- package/dist/consolidator/phases/induce.js +2 -3
- package/dist/consolidator/phases/induce.js.map +1 -1
- package/dist/consolidator/phases/reflect.js +35 -8
- package/dist/consolidator/phases/reflect.js.map +1 -1
- package/dist/consolidator/phases/standard.js +199 -28
- package/dist/consolidator/phases/standard.js.map +1 -1
- package/dist/consolidator/reconcile.js +16 -15
- package/dist/consolidator/reconcile.js.map +1 -1
- package/dist/consolidator/runtime.d.ts.map +1 -1
- package/dist/consolidator/runtime.js +129 -47
- package/dist/consolidator/runtime.js.map +1 -1
- package/dist/consolidator/scheduler.d.ts +17 -3
- package/dist/consolidator/scheduler.d.ts.map +1 -1
- package/dist/consolidator/scheduler.js.map +1 -1
- package/dist/consolidator/types.d.ts +30 -1
- package/dist/consolidator/types.d.ts.map +1 -1
- package/dist/consolidator/types.js +10 -0
- package/dist/consolidator/types.js.map +1 -1
- package/dist/context-engine/compaction/clear-tool-results.d.ts +1 -1
- package/dist/context-engine/compaction/clear-tool-results.js +1 -1
- package/dist/context-engine/compaction/clear-tool-results.js.map +1 -1
- package/dist/context-engine/compaction/compactor.d.ts +1 -0
- package/dist/context-engine/compaction/compactor.d.ts.map +1 -1
- package/dist/context-engine/compaction/compactor.js +32 -8
- package/dist/context-engine/compaction/compactor.js.map +1 -1
- package/dist/context-engine/compaction/hooks/types.d.ts +1 -1
- package/dist/context-engine/compaction/index.d.ts +1 -0
- package/dist/context-engine/compaction/templates/marker.d.ts +33 -0
- package/dist/context-engine/compaction/templates/marker.d.ts.map +1 -0
- package/dist/context-engine/compaction/templates/marker.js +34 -0
- package/dist/context-engine/compaction/templates/marker.js.map +1 -0
- package/dist/context-engine/compaction/templates/summary-9-section.d.ts +1 -1
- package/dist/context-engine/compaction/templates/summary-9-section.d.ts.map +1 -1
- package/dist/context-engine/compaction/templates/summary-9-section.js +4 -3
- package/dist/context-engine/compaction/templates/summary-9-section.js.map +1 -1
- package/dist/context-engine/engine.d.ts +7 -176
- package/dist/context-engine/engine.d.ts.map +1 -1
- package/dist/context-engine/engine.js +0 -2
- package/dist/context-engine/engine.js.map +1 -1
- package/dist/context-engine/index.d.ts +8 -49
- package/dist/context-engine/io-types.d.ts +144 -0
- package/dist/context-engine/io-types.d.ts.map +1 -0
- package/dist/context-engine/locale-packs/types.d.ts +1 -1
- package/dist/context-engine/locale-packs/types.js.map +1 -1
- package/dist/context-engine/privacy-filter.d.ts +1 -2
- package/dist/context-engine/privacy-filter.d.ts.map +1 -1
- package/dist/context-engine/privacy-filter.js +1 -2
- package/dist/context-engine/privacy-filter.js.map +1 -1
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.js +2 -2
- package/dist/errors/index.js.map +1 -1
- package/dist/facade.d.ts +43 -52
- package/dist/facade.d.ts.map +1 -1
- package/dist/facade.js +5 -3
- package/dist/facade.js.map +1 -1
- package/dist/graph/entity-resolver.js +1 -1
- package/dist/graph/entity-resolver.js.map +1 -1
- package/dist/index.d.ts +17 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -7
- package/dist/index.js.map +1 -1
- package/dist/internal/envelope.js +57 -0
- package/dist/internal/envelope.js.map +1 -0
- package/dist/internal/injection-heuristics.js +0 -0
- package/dist/internal/injection-heuristics.js.map +1 -1
- package/dist/internal/llm-json.js +40 -0
- package/dist/internal/llm-json.js.map +1 -0
- package/dist/internal/storage-adapter.d.ts +23 -10
- package/dist/internal/storage-adapter.d.ts.map +1 -1
- package/dist/memory-interface.d.ts +131 -0
- package/dist/memory-interface.d.ts.map +1 -0
- package/dist/package.js +6 -0
- package/dist/package.js.map +1 -0
- package/dist/search/iterative.d.ts.map +1 -1
- package/dist/search/iterative.js +2 -3
- package/dist/search/iterative.js.map +1 -1
- package/dist/search/query-transform.d.ts.map +1 -1
- package/dist/search/query-transform.js +2 -3
- package/dist/search/query-transform.js.map +1 -1
- package/dist/tiers/episodic-memory.js +3 -3
- package/dist/tiers/episodic-memory.js.map +1 -1
- package/dist/tiers/index.d.ts +2 -2
- package/dist/tiers/insight-memory.js +1 -1
- package/dist/tiers/insight-memory.js.map +1 -1
- package/dist/tiers/procedural-memory.d.ts +1 -1
- package/dist/tiers/procedural-memory.js +2 -2
- package/dist/tiers/procedural-memory.js.map +1 -1
- package/dist/tiers/semantic-memory.d.ts +58 -4
- package/dist/tiers/semantic-memory.d.ts.map +1 -1
- package/dist/tiers/semantic-memory.js +103 -20
- package/dist/tiers/semantic-memory.js.map +1 -1
- package/dist/tools/block-tools.d.ts +19 -57
- package/dist/tools/block-tools.d.ts.map +1 -1
- package/dist/tools/block-tools.js.map +1 -1
- package/dist/tools/fact-tools.d.ts +53 -214
- package/dist/tools/fact-tools.d.ts.map +1 -1
- package/dist/tools/fact-tools.js +3 -2
- package/dist/tools/fact-tools.js.map +1 -1
- package/dist/tools/recall-tools.d.ts +34 -175
- package/dist/tools/recall-tools.d.ts.map +1 -1
- package/dist/tools/recall-tools.js +5 -4
- package/dist/tools/recall-tools.js.map +1 -1
- package/dist/tools/runbook-tools.d.ts +15 -58
- package/dist/tools/runbook-tools.d.ts.map +1 -1
- package/dist/tools/runbook-tools.js.map +1 -1
- package/dist/tools/types.d.ts +1 -1
- package/package.json +18 -17
- package/src/conflict/index.ts +29 -0
- package/src/conflict/locale-packs/en.ts +142 -0
- package/src/conflict/locale-packs/index.ts +17 -0
- package/src/conflict/locale-packs/types.ts +138 -0
- package/src/conflict/pipeline.ts +371 -0
- package/src/conflict/stages/helpers.ts +65 -0
- package/src/conflict/stages/stage1-exact-dedup.ts +40 -0
- package/src/conflict/stages/stage2-embedding-three-zone.ts +54 -0
- package/src/conflict/stages/stage3-heuristic-regex.ts +51 -0
- package/src/conflict/stages/stage4-subject-predicate.ts +46 -0
- package/src/conflict/stages/stage5-defer-to-deep.ts +34 -0
- package/src/conflict/types.ts +263 -0
- package/src/consolidator/budget.ts +312 -0
- package/src/consolidator/decay.ts +246 -0
- package/src/consolidator/dlq.ts +61 -0
- package/src/consolidator/errors.ts +87 -0
- package/src/consolidator/idempotency.ts +27 -0
- package/src/consolidator/index.ts +269 -0
- package/src/consolidator/lock.ts +141 -0
- package/src/consolidator/noise-filter.ts +235 -0
- package/src/consolidator/phases/deep.ts +308 -0
- package/src/consolidator/phases/induce.ts +423 -0
- package/src/consolidator/phases/learned-context.ts +233 -0
- package/src/consolidator/phases/light.ts +166 -0
- package/src/consolidator/phases/reflect.ts +504 -0
- package/src/consolidator/phases/standard.ts +1002 -0
- package/src/consolidator/reconcile.ts +273 -0
- package/src/consolidator/runtime.ts +1049 -0
- package/src/consolidator/scheduler.ts +182 -0
- package/src/consolidator/triggers.ts +134 -0
- package/src/consolidator/types.ts +622 -0
- package/src/context-engine/annotations.ts +161 -0
- package/src/context-engine/auto-recall.ts +92 -0
- package/src/context-engine/compaction/clear-tool-results.ts +232 -0
- package/src/context-engine/compaction/compactor.ts +403 -0
- package/src/context-engine/compaction/hooks/reanchor-persona-block.ts +55 -0
- package/src/context-engine/compaction/hooks/reanchor-pinned-facts.ts +66 -0
- package/src/context-engine/compaction/hooks/reanchor-project-rules.ts +57 -0
- package/src/context-engine/compaction/hooks/reanchor-recent-results.ts +116 -0
- package/src/context-engine/compaction/hooks/types.ts +68 -0
- package/src/context-engine/compaction/index.ts +60 -0
- package/src/context-engine/compaction/templates/marker.ts +33 -0
- package/src/context-engine/compaction/templates/summary-9-section.ts +223 -0
- package/src/context-engine/compaction/thresholds.ts +107 -0
- package/src/context-engine/compaction/types.ts +255 -0
- package/src/context-engine/engine.ts +970 -0
- package/src/context-engine/index.ts +118 -0
- package/src/context-engine/io-types.ts +162 -0
- package/src/context-engine/locale-packs/en.ts +107 -0
- package/src/context-engine/locale-packs/index.ts +19 -0
- package/src/context-engine/locale-packs/resolver.ts +197 -0
- package/src/context-engine/locale-packs/types.ts +177 -0
- package/src/context-engine/metadata.ts +114 -0
- package/src/context-engine/preambles/inbound-en.ts +19 -0
- package/src/context-engine/privacy-filter.ts +190 -0
- package/src/context-engine/templates/base-en.ts +19 -0
- package/src/context-engine/templates/composer.ts +91 -0
- package/src/context-engine/token-budget.ts +319 -0
- package/src/context-engine/token-counter.ts +157 -0
- package/src/errors/index.ts +273 -0
- package/src/facade.ts +750 -0
- package/src/graph/entity-resolver.ts +364 -0
- package/src/graph/index.ts +24 -0
- package/src/index.ts +259 -0
- package/src/internal/contextualize.ts +173 -0
- package/src/internal/embedder-binding.ts +53 -0
- package/src/internal/envelope.ts +70 -0
- package/src/internal/id.ts +23 -0
- package/src/internal/injection-heuristics.ts +0 -0
- package/src/internal/llm-json.ts +38 -0
- package/src/internal/spans.ts +35 -0
- package/src/internal/storage-adapter.ts +963 -0
- package/src/memory-interface.ts +158 -0
- package/src/migration/embedder-migration.ts +237 -0
- package/src/migration/index.ts +13 -0
- package/src/search/explain.ts +123 -0
- package/src/search/fit-weights.ts +109 -0
- package/src/search/graph-ppr.ts +38 -0
- package/src/search/index.ts +55 -0
- package/src/search/iterative.ts +658 -0
- package/src/search/query-transform.ts +285 -0
- package/src/search/rrf.ts +225 -0
- package/src/search/trust.ts +55 -0
- package/src/search/types.ts +50 -0
- package/src/tiers/episodic-memory.ts +463 -0
- package/src/tiers/index.ts +50 -0
- package/src/tiers/insight-memory.ts +208 -0
- package/src/tiers/procedural-memory.ts +482 -0
- package/src/tiers/semantic-memory.ts +1729 -0
- package/src/tiers/session-memory.ts +271 -0
- package/src/tiers/shared-memory.ts +62 -0
- package/src/tiers/working-memory.ts +368 -0
- package/src/tools/block-tools.ts +172 -0
- package/src/tools/fact-tools.ts +473 -0
- package/src/tools/index.ts +109 -0
- package/src/tools/recall-tools.ts +303 -0
- package/src/tools/runbook-tools.ts +107 -0
- package/src/tools/taint.ts +39 -0
- package/src/tools/types.ts +37 -0
- package/dist/conflict/locale-packs/index.js +0 -4
- package/dist/context-engine/compaction/index.js +0 -10
- package/dist/context-engine/index.d.ts.map +0 -1
- package/dist/context-engine/index.js +0 -25
- package/dist/context-engine/locale-packs/index.js +0 -4
|
@@ -0,0 +1,963 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
EmbedderProvider,
|
|
3
|
+
EntityRole,
|
|
4
|
+
Episode,
|
|
5
|
+
EpisodicMemoryStore,
|
|
6
|
+
Fact,
|
|
7
|
+
GraphEntity,
|
|
8
|
+
Insight,
|
|
9
|
+
MemoryHit,
|
|
10
|
+
MemoryOwner,
|
|
11
|
+
MemoryStatus,
|
|
12
|
+
MemoryStore,
|
|
13
|
+
Message,
|
|
14
|
+
MessageRef,
|
|
15
|
+
ProceduralMemoryStore,
|
|
16
|
+
Rule,
|
|
17
|
+
SemanticMemoryStore,
|
|
18
|
+
SessionListOptions,
|
|
19
|
+
SessionMemoryStore,
|
|
20
|
+
SessionScope,
|
|
21
|
+
SharedMemoryStore,
|
|
22
|
+
WorkingMemoryStore,
|
|
23
|
+
} from '@graphorin/core';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Shape of the embedding payload threaded through the optional
|
|
27
|
+
* embedded write helpers exposed by adapters such as
|
|
28
|
+
* `@graphorin/store-sqlite`. Matches the storage adapter's
|
|
29
|
+
* `SqliteMemoryWriteOptions` byte-for-byte but is declared
|
|
30
|
+
* structurally here so `@graphorin/memory` does not import the
|
|
31
|
+
* storage package directly.
|
|
32
|
+
*
|
|
33
|
+
* @stable
|
|
34
|
+
*/
|
|
35
|
+
export interface EmbeddedWriteOptions {
|
|
36
|
+
readonly embedding?: {
|
|
37
|
+
readonly embedderId: string;
|
|
38
|
+
readonly vector: Float32Array;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Contextual-retrieval index text (P1-3). When supplied, the adapter
|
|
42
|
+
* indexes its lexical (FTS) surface against this context-prepended
|
|
43
|
+
* text while persisting the canonical `text` unchanged. Absent ⇒ the
|
|
44
|
+
* canonical text is indexed (pre-P1-3 behaviour).
|
|
45
|
+
*/
|
|
46
|
+
readonly indexText?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Extension of the typed `EpisodicMemoryStore` with optional
|
|
51
|
+
* embedding-aware helpers + lifecycle helpers that storage adapters
|
|
52
|
+
* may expose.
|
|
53
|
+
*
|
|
54
|
+
* @stable
|
|
55
|
+
*/
|
|
56
|
+
export interface EpisodicMemoryStoreExt extends EpisodicMemoryStore {
|
|
57
|
+
putWithEmbedding?(episode: Episode, options: EmbeddedWriteOptions): Promise<void>;
|
|
58
|
+
searchVector?(
|
|
59
|
+
scope: SessionScope,
|
|
60
|
+
embedding: Float32Array,
|
|
61
|
+
embedderId: string,
|
|
62
|
+
topK: number,
|
|
63
|
+
/** Point-in-time filter (`started_at <= asOf`, ISO-8601). P0-2. */
|
|
64
|
+
asOf?: string,
|
|
65
|
+
/** Include quarantined episodes (validation/inspector path). P1-4. */
|
|
66
|
+
includeQuarantined?: boolean,
|
|
67
|
+
): Promise<ReadonlyArray<MemoryHit<Episode>>>;
|
|
68
|
+
/**
|
|
69
|
+
* Mark an episode archived. Soft-archive - the row stays for replay.
|
|
70
|
+
* W-154: with `scope`, adapters no-op unless the row belongs to it.
|
|
71
|
+
*/
|
|
72
|
+
archive?(id: string, reason?: string, scope?: SessionScope): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Most-recent episodes by end time (newest first), with no FTS / vector
|
|
75
|
+
* query - recency, not relevance (MCON-1). Powers `EpisodicMemory.recent()`
|
|
76
|
+
* and the deep-phase reflection gate. The default `@graphorin/store-sqlite`
|
|
77
|
+
* adapter implements it.
|
|
78
|
+
*/
|
|
79
|
+
listRecent?(
|
|
80
|
+
scope: SessionScope,
|
|
81
|
+
limit: number,
|
|
82
|
+
options?: { includeQuarantined?: boolean },
|
|
83
|
+
): Promise<ReadonlyArray<Episode>>;
|
|
84
|
+
/**
|
|
85
|
+
* Set an episode's retrieval-trust `status` (MCON-2) - promote a quarantined
|
|
86
|
+
* (auto-formed) episode into default recall or re-quarantine an active one,
|
|
87
|
+
* with a `memory_history` audit row. Powers {@link EpisodicMemory.validate}.
|
|
88
|
+
*/
|
|
89
|
+
setStatus?(
|
|
90
|
+
id: string,
|
|
91
|
+
status: MemoryStatus,
|
|
92
|
+
reason?: string,
|
|
93
|
+
scope?: SessionScope,
|
|
94
|
+
): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Count the recall-eligible episodes for the scope (CE-5) - a `COUNT(*)`,
|
|
97
|
+
* never materialising rows. Powers honest `metadata()` counts.
|
|
98
|
+
*/
|
|
99
|
+
count?(scope: SessionScope): Promise<number>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Extension of the typed `SemanticMemoryStore` with optional
|
|
104
|
+
* embedding-aware helpers + lifecycle helpers that storage adapters
|
|
105
|
+
* may expose.
|
|
106
|
+
*
|
|
107
|
+
* @stable
|
|
108
|
+
*/
|
|
109
|
+
export interface SemanticMemoryStoreExt extends SemanticMemoryStore {
|
|
110
|
+
rememberWithEmbedding?(fact: Fact, options: EmbeddedWriteOptions): Promise<void>;
|
|
111
|
+
searchVector?(
|
|
112
|
+
scope: SessionScope,
|
|
113
|
+
embedding: Float32Array,
|
|
114
|
+
embedderId: string,
|
|
115
|
+
topK: number,
|
|
116
|
+
/**
|
|
117
|
+
* Point-in-time filter applied after KNN: only facts whose
|
|
118
|
+
* validity interval contains `asOf` (ISO-8601) survive. P0-2.
|
|
119
|
+
*/
|
|
120
|
+
asOf?: string,
|
|
121
|
+
/**
|
|
122
|
+
* Include quarantined facts in the KNN result (validation /
|
|
123
|
+
* inspector path). Default reads exclude them. P1-4.
|
|
124
|
+
*/
|
|
125
|
+
includeQuarantined?: boolean,
|
|
126
|
+
/**
|
|
127
|
+
* Include superseded / validity-expired facts. Default reads
|
|
128
|
+
* evaluate validity at NOW (memory-retrieval-01).
|
|
129
|
+
*/
|
|
130
|
+
includeSuperseded?: boolean,
|
|
131
|
+
/**
|
|
132
|
+
* Retrieval-time principal filter (D3). Rows with no stored owner
|
|
133
|
+
* are treated as `'user'`. Absent ⇒ no owner filter.
|
|
134
|
+
*/
|
|
135
|
+
owner?: MemoryOwner | ReadonlyArray<MemoryOwner>,
|
|
136
|
+
): Promise<ReadonlyArray<MemoryHit<Fact>>>;
|
|
137
|
+
/** Lookup a single fact by id (returns `null` when absent or soft-deleted). */
|
|
138
|
+
get?(id: string): Promise<Fact | null>;
|
|
139
|
+
/**
|
|
140
|
+
* Set a fact's retrieval-trust `status` and write a `memory_history`
|
|
141
|
+
* audit row (P1-4). Promotes a quarantined fact to `active` (the
|
|
142
|
+
* validation path) or re-quarantines an active one. Never touches
|
|
143
|
+
* content / embedding / tombstone - quarantine is a retrieval gate.
|
|
144
|
+
* Powers {@link SemanticMemory.validate}; the default
|
|
145
|
+
* `@graphorin/store-sqlite` adapter implements it.
|
|
146
|
+
*/
|
|
147
|
+
setStatus?(
|
|
148
|
+
factId: string,
|
|
149
|
+
status: MemoryStatus,
|
|
150
|
+
reason?: string,
|
|
151
|
+
scope?: SessionScope,
|
|
152
|
+
): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Count the recall-eligible facts for the scope (CE-5) - a `COUNT(*)` with
|
|
155
|
+
* the default recall filters (live, non-archived, non-quarantined), never
|
|
156
|
+
* materialising rows. Powers honest `metadata()` counts.
|
|
157
|
+
*/
|
|
158
|
+
count?(scope: SessionScope): Promise<number>;
|
|
159
|
+
/**
|
|
160
|
+
* Hard-delete a fact (GDPR path). The audit log row is preserved
|
|
161
|
+
* but the row itself + every per-embedder vec0 entry is removed.
|
|
162
|
+
* Distinct from {@link SemanticMemoryStore.forget} (soft-delete).
|
|
163
|
+
*/
|
|
164
|
+
purge?(id: string, reason?: string, scope?: SessionScope): Promise<void>;
|
|
165
|
+
/**
|
|
166
|
+
* W-019: record a PENDING supersede link - set `newId.supersedes =
|
|
167
|
+
* oldId` WITHOUT closing the old fact's validity interval. Used when
|
|
168
|
+
* a supersede's successor lands quarantined: the old fact must stay
|
|
169
|
+
* in default recall until the successor is validated, at which point
|
|
170
|
+
* {@link SemanticMemory.validate} completes the closure via
|
|
171
|
+
* {@link SemanticMemoryStore.supersede}. No schema change - the
|
|
172
|
+
* `supersedes` column already exists.
|
|
173
|
+
*/
|
|
174
|
+
linkPendingSupersede?(newId: string, oldId: string): Promise<void>;
|
|
175
|
+
/**
|
|
176
|
+
* Walk the bi-temporal supersede chain that `factId` belongs to and
|
|
177
|
+
* return every fact in it, oldest → newest (by `validFrom`),
|
|
178
|
+
* including superseded / soft-deleted rows so callers can answer
|
|
179
|
+
* "how did this fact change over time". Scope-guarded and
|
|
180
|
+
* cycle-safe; returns `[]` for an unknown id. Powers
|
|
181
|
+
* {@link SemanticMemory.history} (P0-2). The default
|
|
182
|
+
* `@graphorin/store-sqlite` adapter implements it.
|
|
183
|
+
*/
|
|
184
|
+
historyOf?(scope: SessionScope, factId: string): Promise<ReadonlyArray<Fact>>;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Single message tuple returned by
|
|
189
|
+
* {@link SessionMemoryStoreExt.listMessagesSince}. The optional
|
|
190
|
+
* `tokenCount` field is the value cached in the storage layer
|
|
191
|
+
* (DEC-131); `null` indicates the cache is empty.
|
|
192
|
+
*
|
|
193
|
+
* @stable
|
|
194
|
+
*/
|
|
195
|
+
export interface SessionMessageRecord {
|
|
196
|
+
readonly id: string;
|
|
197
|
+
readonly sequence: number;
|
|
198
|
+
readonly createdAt: string;
|
|
199
|
+
readonly tokenCount: number | null;
|
|
200
|
+
readonly message: Message;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Extension of the typed `SessionMemoryStore` with optional
|
|
205
|
+
* token-cache + vector-search + cursor-aware reader helpers that
|
|
206
|
+
* storage adapters may expose.
|
|
207
|
+
*
|
|
208
|
+
* @stable
|
|
209
|
+
*/
|
|
210
|
+
export interface SessionMemoryStoreExt extends SessionMemoryStore {
|
|
211
|
+
searchVector?(
|
|
212
|
+
scope: SessionScope,
|
|
213
|
+
embedding: Float32Array,
|
|
214
|
+
embedderId: string,
|
|
215
|
+
topK: number,
|
|
216
|
+
): Promise<ReadonlyArray<MemoryHit>>;
|
|
217
|
+
/**
|
|
218
|
+
* Sum of `session_messages.token_count` for the supplied scope.
|
|
219
|
+
* Returns `null` when the cache is empty / partially populated so
|
|
220
|
+
* callers can fall back to a heuristic. Surfaced per DEC-131.
|
|
221
|
+
*/
|
|
222
|
+
totalCachedTokens?(scope: SessionScope): Promise<number | null>;
|
|
223
|
+
/**
|
|
224
|
+
* List messages for the supplied scope past the optional
|
|
225
|
+
* `lastMessageId` cursor, oldest-first, capped at `limit`. Used by
|
|
226
|
+
* the consolidator's standard phase to advance the per-scope
|
|
227
|
+
* idempotency cursor without rereading already-processed turns.
|
|
228
|
+
*/
|
|
229
|
+
listMessagesSince?(
|
|
230
|
+
scope: SessionScope,
|
|
231
|
+
lastMessageId: string | null,
|
|
232
|
+
limit: number,
|
|
233
|
+
): Promise<ReadonlyArray<SessionMessageRecord>>;
|
|
234
|
+
/**
|
|
235
|
+
* Count the live messages in the scoped session (CE-5) - a `COUNT(*)`, never
|
|
236
|
+
* materialising rows; `0` for a user-only scope. Powers honest `metadata()`
|
|
237
|
+
* counts instead of `list(...)`-materialising up to 1000 rows.
|
|
238
|
+
*/
|
|
239
|
+
count?(scope: SessionScope): Promise<number>;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Optional extension surface for storage adapters' embedder registry.
|
|
244
|
+
* The interface is structural so any adapter that matches the shape
|
|
245
|
+
* works.
|
|
246
|
+
*
|
|
247
|
+
* @stable
|
|
248
|
+
*/
|
|
249
|
+
export interface EmbeddingMetaRegistryLike {
|
|
250
|
+
registerOrReturn(input: {
|
|
251
|
+
readonly id: string;
|
|
252
|
+
readonly embedderKind: string;
|
|
253
|
+
readonly model: string;
|
|
254
|
+
readonly dim: number;
|
|
255
|
+
readonly distanceMetric?: 'cosine' | 'dot' | 'euclidean';
|
|
256
|
+
readonly configHash: string;
|
|
257
|
+
readonly notes?: string | null;
|
|
258
|
+
}): { readonly id: string };
|
|
259
|
+
get(id: string): unknown | null;
|
|
260
|
+
assertKnown(id: string): void;
|
|
261
|
+
retire(id: string, retiredAt?: number): void;
|
|
262
|
+
listAll(): ReadonlyArray<{ readonly id: string; readonly retiredAt: number | null }>;
|
|
263
|
+
listActive(): ReadonlyArray<{ readonly id: string; readonly retiredAt: number | null }>;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Stable lowercase identifier for the pipeline stage that produced a
|
|
268
|
+
* conflict decision. Mirrored byte-for-byte by
|
|
269
|
+
* `@graphorin/store-sqlite`'s `ConflictPipelineStage`.
|
|
270
|
+
*
|
|
271
|
+
* @stable
|
|
272
|
+
*/
|
|
273
|
+
export type ConflictAuditStage =
|
|
274
|
+
| 'exact-dedup'
|
|
275
|
+
| 'embedding-three-zone'
|
|
276
|
+
| 'heuristic-regex'
|
|
277
|
+
| 'subject-predicate'
|
|
278
|
+
| 'defer-to-deep';
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Final pipeline outcome recorded against the candidate fact. Matches
|
|
282
|
+
* the storage adapter's `ConflictPipelineDecision` exactly.
|
|
283
|
+
* `'judge-unparseable'` closes a pending row whose deep-phase judge
|
|
284
|
+
* call repeatedly failed (MCON-9) so it stops being re-billed forever.
|
|
285
|
+
*
|
|
286
|
+
* @stable
|
|
287
|
+
*/
|
|
288
|
+
export type ConflictAuditDecision =
|
|
289
|
+
| 'admit'
|
|
290
|
+
| 'dedup'
|
|
291
|
+
| 'supersede'
|
|
292
|
+
| 'pending'
|
|
293
|
+
| 'judge-unparseable';
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Single audit row written by `runConflictPipeline(...)`. The optional
|
|
297
|
+
* `ConflictMemoryStoreExt.recordDecision` accepts this shape; the
|
|
298
|
+
* default `@graphorin/store-sqlite` implementation persists it into
|
|
299
|
+
* the `fact_conflicts` table introduced by Phase 10b.
|
|
300
|
+
*
|
|
301
|
+
* @stable
|
|
302
|
+
*/
|
|
303
|
+
export interface ConflictAuditInputLike {
|
|
304
|
+
readonly scope: SessionScope;
|
|
305
|
+
readonly candidateId: string;
|
|
306
|
+
readonly existingId?: string;
|
|
307
|
+
readonly decision: ConflictAuditDecision;
|
|
308
|
+
readonly stage: ConflictAuditStage;
|
|
309
|
+
readonly detectionZone?: string;
|
|
310
|
+
readonly similarity?: number;
|
|
311
|
+
readonly reason?: string;
|
|
312
|
+
readonly detectedBy?: string;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Pending-queue payload - Stage 5 (defer-to-deep) hands the row over
|
|
317
|
+
* to the deep-phase LLM judge (Phase 10c).
|
|
318
|
+
*
|
|
319
|
+
* @stable
|
|
320
|
+
*/
|
|
321
|
+
export interface PendingConflictInputLike {
|
|
322
|
+
readonly scope: SessionScope;
|
|
323
|
+
readonly factId: string;
|
|
324
|
+
readonly candidateText: string;
|
|
325
|
+
readonly stage: ConflictAuditStage;
|
|
326
|
+
readonly reason?: string;
|
|
327
|
+
/** Top-K conflicting existing fact ids surfaced by Stage 2. */
|
|
328
|
+
readonly conflictingIds?: ReadonlyArray<string>;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Read-back shape returned by `listPending(...)`.
|
|
333
|
+
*
|
|
334
|
+
* @stable
|
|
335
|
+
*/
|
|
336
|
+
export interface PendingConflictRowLike {
|
|
337
|
+
readonly id: number;
|
|
338
|
+
readonly scopeUserId: string;
|
|
339
|
+
readonly factId: string;
|
|
340
|
+
readonly candidateText: string;
|
|
341
|
+
readonly stage: string;
|
|
342
|
+
readonly reason: string | null;
|
|
343
|
+
readonly enqueuedAt: number;
|
|
344
|
+
readonly attemptedAt: number | null;
|
|
345
|
+
readonly resolvedAt: number | null;
|
|
346
|
+
readonly decision: string | null;
|
|
347
|
+
/** Top-K conflicting existing fact ids; empty when omitted at enqueue. */
|
|
348
|
+
readonly conflictingIds: ReadonlyArray<string>;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Optional storage extension surfacing the audit + pending queue
|
|
353
|
+
* tables Phase 10b owns. Adapters that opt out leave the property
|
|
354
|
+
* undefined; the conflict pipeline degrades gracefully (no audit, no
|
|
355
|
+
* deferred queue, but every other stage still functions).
|
|
356
|
+
*
|
|
357
|
+
* @stable
|
|
358
|
+
*/
|
|
359
|
+
export interface ConflictMemoryStoreExt {
|
|
360
|
+
recordDecision(input: ConflictAuditInputLike): Promise<{
|
|
361
|
+
readonly id: number;
|
|
362
|
+
readonly detectedAt: number;
|
|
363
|
+
}>;
|
|
364
|
+
enqueuePending(input: PendingConflictInputLike): Promise<{ readonly id: number }>;
|
|
365
|
+
listPending(scope: SessionScope, limit?: number): Promise<ReadonlyArray<PendingConflictRowLike>>;
|
|
366
|
+
markResolved(id: number, decision: ConflictAuditDecision): Promise<void>;
|
|
367
|
+
/**
|
|
368
|
+
* Stamp `attemptedAt` on a pending row whose judge call failed
|
|
369
|
+
* (MCON-9). The deep phase closes the row as `'judge-unparseable'`
|
|
370
|
+
* on the NEXT failure, so a poisoned row is billed at most twice.
|
|
371
|
+
* Optional - without it the deep phase falls back to skip-and-retry.
|
|
372
|
+
*/
|
|
373
|
+
markAttempted?(id: number, attemptedAt?: number): Promise<void>;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Persisted per-scope consolidator state row mirrored byte-for-byte
|
|
378
|
+
* by `@graphorin/store-sqlite`'s `consolidator_state` table. The lock
|
|
379
|
+
* fields (`activeLockHeldBy` / `activeLockAcquiredAt`) are populated
|
|
380
|
+
* while a phase is running and cleared when it finishes; the cursor
|
|
381
|
+
* fields advance as the standard phase processes a batch of
|
|
382
|
+
* messages.
|
|
383
|
+
*
|
|
384
|
+
* @stable
|
|
385
|
+
*/
|
|
386
|
+
export interface ConsolidatorStateRow {
|
|
387
|
+
readonly scope: SessionScope;
|
|
388
|
+
readonly lastProcessedMessageId: string | null;
|
|
389
|
+
readonly lastPhase: 'light' | 'standard' | 'deep' | null;
|
|
390
|
+
readonly lastCompletedAt: number | null;
|
|
391
|
+
readonly nextEligibleAt: number | null;
|
|
392
|
+
readonly activeLockHeldBy: string | null;
|
|
393
|
+
readonly activeLockAcquiredAt: number | null;
|
|
394
|
+
/**
|
|
395
|
+
* `ended_at` (epoch ms) of the newest episode the deep-phase reflection
|
|
396
|
+
* pass has already reflected on (MCON-13). A later pass accumulates
|
|
397
|
+
* importance only from strictly-newer episodes; `null` ⇒ nothing reflected
|
|
398
|
+
* yet.
|
|
399
|
+
*/
|
|
400
|
+
readonly reflectionWatermark: number | null;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Patch shape accepted by
|
|
405
|
+
* {@link ConsolidatorMemoryStoreExt.upsertState}. Every field is
|
|
406
|
+
* optional so callers may advance the cursor and the run stamp
|
|
407
|
+
* independently. `null` clears a column; `undefined` leaves it
|
|
408
|
+
* untouched.
|
|
409
|
+
*
|
|
410
|
+
* @stable
|
|
411
|
+
*/
|
|
412
|
+
export interface ConsolidatorStatePatch {
|
|
413
|
+
readonly lastProcessedMessageId?: string | null;
|
|
414
|
+
readonly lastPhase?: 'light' | 'standard' | 'deep' | null;
|
|
415
|
+
readonly lastCompletedAt?: number | null;
|
|
416
|
+
readonly nextEligibleAt?: number | null;
|
|
417
|
+
readonly activeLockHeldBy?: string | null;
|
|
418
|
+
readonly activeLockAcquiredAt?: number | null;
|
|
419
|
+
readonly reflectionWatermark?: number | null;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Phase invocation audit row written to `consolidator_runs`. The
|
|
424
|
+
* accompanying `id` is generated by the caller so a partial / failed
|
|
425
|
+
* run can be reconciled by replay.
|
|
426
|
+
*
|
|
427
|
+
* @stable
|
|
428
|
+
*/
|
|
429
|
+
export interface ConsolidatorRunInput {
|
|
430
|
+
readonly id: string;
|
|
431
|
+
readonly scope: SessionScope;
|
|
432
|
+
readonly triggerKind: 'turn' | 'idle' | 'cron' | 'event' | 'budget' | 'manual';
|
|
433
|
+
readonly phase: 'light' | 'standard' | 'deep';
|
|
434
|
+
readonly startedAt: number;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/** @stable */
|
|
438
|
+
export interface ConsolidatorRunFinish {
|
|
439
|
+
readonly id: string;
|
|
440
|
+
readonly finishedAt: number;
|
|
441
|
+
readonly status: 'completed' | 'failed' | 'deferred' | 'partial';
|
|
442
|
+
readonly llmTokensUsed?: number;
|
|
443
|
+
readonly llmCostUsd?: number | null;
|
|
444
|
+
readonly factsCreated?: number;
|
|
445
|
+
readonly factsUpdated?: number;
|
|
446
|
+
readonly conflictsResolved?: number;
|
|
447
|
+
readonly noiseFilteredCount?: number;
|
|
448
|
+
readonly emptyExtractions?: number;
|
|
449
|
+
/** Episodes auto-formed by the run (P1-2 / MCON-17). */
|
|
450
|
+
readonly episodesFormed?: number;
|
|
451
|
+
/** Insights synthesized by the run's reflection pass (P1-1 / MCON-17). */
|
|
452
|
+
readonly insightsCreated?: number;
|
|
453
|
+
readonly errorMessage?: string | null;
|
|
454
|
+
readonly retryCount?: number;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/** @stable */
|
|
458
|
+
export interface DlqBatchInput {
|
|
459
|
+
readonly id: string;
|
|
460
|
+
readonly consolidatorRunId: string | null;
|
|
461
|
+
readonly scope: SessionScope;
|
|
462
|
+
readonly messageIds: ReadonlyArray<string>;
|
|
463
|
+
readonly errorKind: string;
|
|
464
|
+
readonly errorMessage: string;
|
|
465
|
+
readonly failedAt: number;
|
|
466
|
+
readonly nextRetryAt: number;
|
|
467
|
+
readonly retryCount: number;
|
|
468
|
+
/**
|
|
469
|
+
* Phase that failed (MCON-10) so `drainDlq` replays the SAME phase
|
|
470
|
+
* instead of inferring (the old inference hard-coded `'standard'`).
|
|
471
|
+
* Absent / `null` ⇒ legacy row, replayed as `'standard'`.
|
|
472
|
+
*/
|
|
473
|
+
readonly phase?: 'light' | 'standard' | 'deep' | null;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/** @stable */
|
|
477
|
+
export interface DlqBatchRow {
|
|
478
|
+
readonly id: string;
|
|
479
|
+
readonly consolidatorRunId: string | null;
|
|
480
|
+
readonly scope: SessionScope;
|
|
481
|
+
readonly messageIds: ReadonlyArray<string>;
|
|
482
|
+
readonly errorKind: string;
|
|
483
|
+
readonly errorMessage: string;
|
|
484
|
+
readonly failedAt: number;
|
|
485
|
+
readonly nextRetryAt: number | null;
|
|
486
|
+
readonly retryCount: number;
|
|
487
|
+
/** Phase that failed (MCON-10); `null`/absent ⇒ legacy row. */
|
|
488
|
+
readonly phase?: 'light' | 'standard' | 'deep' | null;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Optional consolidator-state surface every storage adapter exposes
|
|
493
|
+
* for Phase 10c. Mirrors the `consolidator_state`,
|
|
494
|
+
* `consolidator_runs`, and `consolidator_failed_batches` tables
|
|
495
|
+
* shipped in Phase 05's migration 009. Adapters that do not
|
|
496
|
+
* implement the surface degrade gracefully - the consolidator runs
|
|
497
|
+
* in stateless mode (no DLQ, no cursor persistence) and emits a
|
|
498
|
+
* one-shot WARN.
|
|
499
|
+
*
|
|
500
|
+
* @stable
|
|
501
|
+
*/
|
|
502
|
+
export interface ConsolidatorMemoryStoreExt {
|
|
503
|
+
getState(scope: SessionScope): Promise<ConsolidatorStateRow | null>;
|
|
504
|
+
upsertState(scope: SessionScope, patch: ConsolidatorStatePatch): Promise<ConsolidatorStateRow>;
|
|
505
|
+
/**
|
|
506
|
+
* Atomically claim the per-scope lock. Returns `true` when the
|
|
507
|
+
* row was either unlocked, owned by `runId`, or stale (the held
|
|
508
|
+
* timestamp is older than `maxAgeMs`); `false` otherwise. The
|
|
509
|
+
* `now` argument allows the lock manager to inject a deterministic
|
|
510
|
+
* clock during tests.
|
|
511
|
+
*/
|
|
512
|
+
acquireLock(scope: SessionScope, runId: string, now: number, maxAgeMs: number): Promise<boolean>;
|
|
513
|
+
releaseLock(scope: SessionScope, runId: string): Promise<void>;
|
|
514
|
+
|
|
515
|
+
recordRunStart(input: ConsolidatorRunInput): Promise<void>;
|
|
516
|
+
recordRunFinish(finish: ConsolidatorRunFinish): Promise<void>;
|
|
517
|
+
listRecentRuns(
|
|
518
|
+
scope: SessionScope,
|
|
519
|
+
limit?: number,
|
|
520
|
+
): Promise<
|
|
521
|
+
ReadonlyArray<{
|
|
522
|
+
readonly id: string;
|
|
523
|
+
readonly phase: 'light' | 'standard' | 'deep';
|
|
524
|
+
readonly status: string;
|
|
525
|
+
readonly startedAt: number;
|
|
526
|
+
readonly finishedAt: number | null;
|
|
527
|
+
readonly llmCostUsd: number | null;
|
|
528
|
+
readonly llmTokensUsed: number;
|
|
529
|
+
readonly factsCreated: number;
|
|
530
|
+
readonly factsUpdated: number;
|
|
531
|
+
}>
|
|
532
|
+
>;
|
|
533
|
+
|
|
534
|
+
enqueueFailedBatch(input: DlqBatchInput): Promise<void>;
|
|
535
|
+
/**
|
|
536
|
+
* Claim every DLQ row whose `nextRetryAt` is at or before `now`,
|
|
537
|
+
* up to `limit`. Returns the rows in failed-at order so the
|
|
538
|
+
* oldest backlog drains first.
|
|
539
|
+
*/
|
|
540
|
+
claimReadyBatches(
|
|
541
|
+
scope: SessionScope,
|
|
542
|
+
now: number,
|
|
543
|
+
limit?: number,
|
|
544
|
+
): Promise<ReadonlyArray<DlqBatchRow>>;
|
|
545
|
+
/** Mark the row succeeded - removes it from the DLQ. */
|
|
546
|
+
markBatchSucceeded(id: string): Promise<void>;
|
|
547
|
+
/**
|
|
548
|
+
* Schedule the next retry attempt. The caller computes
|
|
549
|
+
* `nextRetryAt` so the backoff schedule is centralized in the
|
|
550
|
+
* consolidator.
|
|
551
|
+
*/
|
|
552
|
+
rescheduleBatch(id: string, retryCount: number, nextRetryAt: number): Promise<void>;
|
|
553
|
+
/**
|
|
554
|
+
* Mark the row exhausted (`retryCount` exceeded the configured
|
|
555
|
+
* cap). The row stays in the DLQ for operator inspection.
|
|
556
|
+
* Implementations MUST clear `nextRetryAt` so the row is no
|
|
557
|
+
* longer eligible for `claimReadyBatches`. The optional
|
|
558
|
+
* `retryCount` argument is recorded against the row so the
|
|
559
|
+
* persisted count reflects the final attempt that triggered the
|
|
560
|
+
* exhaustion.
|
|
561
|
+
*/
|
|
562
|
+
markBatchExhausted(id: string, errorMessage: string, retryCount?: number): Promise<void>;
|
|
563
|
+
listFailedBatches(scope: SessionScope, limit?: number): Promise<ReadonlyArray<DlqBatchRow>>;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Decay-aware extension of the typed `SemanticMemoryStore`. Phase
|
|
568
|
+
* 10c's light phase reads the strength + last-accessed columns and
|
|
569
|
+
* archives facts whose retention curve falls below the configured
|
|
570
|
+
* threshold. Adapters that do not maintain decay columns may omit
|
|
571
|
+
* the surface entirely - the light phase skips the archive step
|
|
572
|
+
* with an INFO log.
|
|
573
|
+
*
|
|
574
|
+
* @stable
|
|
575
|
+
*/
|
|
576
|
+
export interface DecayMemoryStoreExt {
|
|
577
|
+
/**
|
|
578
|
+
* List facts for the scope ordered by `lastAccessedAt` ASC so the
|
|
579
|
+
* caller can apply Ebbinghaus retention without scanning the
|
|
580
|
+
* whole table. `limit` defaults to `1000`.
|
|
581
|
+
*
|
|
582
|
+
* Archived rows are EXCLUDED by default (MCON-6) - they never receive
|
|
583
|
+
* access bumps, so they would pin the LRU head and saturate the decay
|
|
584
|
+
* window, structurally stopping threshold-archiving and capacity
|
|
585
|
+
* eviction for live facts. Inspection paths pass
|
|
586
|
+
* `{ includeArchived: true }`.
|
|
587
|
+
*
|
|
588
|
+
* `importance` / `status` / `provenance` (X-1) feed the multi-signal
|
|
589
|
+
* salience score that orders capacity-bounded eviction.
|
|
590
|
+
*/
|
|
591
|
+
listForDecay(
|
|
592
|
+
scope: SessionScope,
|
|
593
|
+
limit?: number,
|
|
594
|
+
opts?: { readonly includeArchived?: boolean },
|
|
595
|
+
): Promise<
|
|
596
|
+
ReadonlyArray<{
|
|
597
|
+
readonly id: string;
|
|
598
|
+
readonly text: string;
|
|
599
|
+
readonly strength: number;
|
|
600
|
+
readonly lastAccessedAt: number | null;
|
|
601
|
+
readonly createdAt: number;
|
|
602
|
+
readonly archived: boolean;
|
|
603
|
+
/** Importance hint in `[0, 1]`; `null` when unscored (X-1). */
|
|
604
|
+
readonly importance: number | null;
|
|
605
|
+
/** Retrieval-trust state (P1-4): `'active'` | `'quarantined'`. */
|
|
606
|
+
readonly status: string;
|
|
607
|
+
/** Trust-provenance tag (P1-4); `null` for first-party rows. */
|
|
608
|
+
readonly provenance: string | null;
|
|
609
|
+
/**
|
|
610
|
+
* Monotonic retrieval-access counter (D3, migration 027). Feeds
|
|
611
|
+
* the opt-in `accessReinforcement` salience weight. Optional -
|
|
612
|
+
* adapters without the column omit it (treated as `0`).
|
|
613
|
+
*/
|
|
614
|
+
readonly accessCount?: number;
|
|
615
|
+
}>
|
|
616
|
+
>;
|
|
617
|
+
/**
|
|
618
|
+
* Soft-archive a fact (sets `archived = 1`). The audit row in
|
|
619
|
+
* `memory_history` records the archive event.
|
|
620
|
+
*/
|
|
621
|
+
archiveFact(id: string, reason?: string, scope?: SessionScope): Promise<void>;
|
|
622
|
+
/**
|
|
623
|
+
* Record a retrieval access for the given facts (MRET-7): stamp
|
|
624
|
+
* `lastAccessedAt` and reinforce `strength` (implementation-capped).
|
|
625
|
+
* Optional - adapters without decay columns may omit it; callers
|
|
626
|
+
* MUST treat failures as non-fatal (the read path never breaks on a
|
|
627
|
+
* bookkeeping write).
|
|
628
|
+
*/
|
|
629
|
+
markAccessed?(
|
|
630
|
+
ids: ReadonlyArray<string>,
|
|
631
|
+
accessedAt?: number,
|
|
632
|
+
scope?: SessionScope,
|
|
633
|
+
): Promise<void>;
|
|
634
|
+
/**
|
|
635
|
+
* Narrow decay-column read for exactly the given fact ids (MRET-8) -
|
|
636
|
+
* powers per-search decay re-ranking without the old O(scope)
|
|
637
|
+
* 1000-row window read. Optional; absent ⇒ the tier falls back to
|
|
638
|
+
* `listForDecay`.
|
|
639
|
+
*/
|
|
640
|
+
listDecaySignals?(ids: ReadonlyArray<string>): Promise<
|
|
641
|
+
ReadonlyArray<{
|
|
642
|
+
readonly id: string;
|
|
643
|
+
readonly strength: number;
|
|
644
|
+
readonly lastAccessedAt: number | null;
|
|
645
|
+
readonly createdAt: number;
|
|
646
|
+
}>
|
|
647
|
+
>;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/** Options accepted by {@link InsightMemoryStoreExt.list}. */
|
|
651
|
+
export interface InsightListOptions {
|
|
652
|
+
readonly limit?: number;
|
|
653
|
+
/** Include quarantined insights (validation / inspector path). */
|
|
654
|
+
readonly includeQuarantined?: boolean;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/** Options accepted by {@link InsightMemoryStoreExt.search}. */
|
|
658
|
+
export interface InsightSearchStoreOptions {
|
|
659
|
+
readonly topK?: number;
|
|
660
|
+
/** Include quarantined insights (validation / inspector path). */
|
|
661
|
+
readonly includeQuarantined?: boolean;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Optional storage extension for the reflection `insights` table
|
|
666
|
+
* (P1-1). The consolidator's reflection pass inserts quarantined,
|
|
667
|
+
* cited insights here; the thin `InsightMemory` read surface lists /
|
|
668
|
+
* searches them; the ExpeL salience loop bumps + prunes them. Search is
|
|
669
|
+
* FTS-only by design - insights are a soft, rank-capped inspector
|
|
670
|
+
* surface, not primary recall.
|
|
671
|
+
*
|
|
672
|
+
* Adapters that opt out leave the property undefined; reflection then
|
|
673
|
+
* degrades to a no-op (it never writes) and `InsightMemory`
|
|
674
|
+
* search/list return empty. The default `@graphorin/store-sqlite`
|
|
675
|
+
* adapter implements it.
|
|
676
|
+
*
|
|
677
|
+
* @stable
|
|
678
|
+
*/
|
|
679
|
+
export interface InsightMemoryStoreExt {
|
|
680
|
+
/** Persist a synthesized insight (idempotent on `id`). */
|
|
681
|
+
insert(insight: Insight): Promise<void>;
|
|
682
|
+
/** Most-recent insights for the scope (newest first). */
|
|
683
|
+
list(scope: SessionScope, opts?: InsightListOptions): Promise<ReadonlyArray<Insight>>;
|
|
684
|
+
/** FTS keyword search over insight text. */
|
|
685
|
+
search(
|
|
686
|
+
scope: SessionScope,
|
|
687
|
+
query: string,
|
|
688
|
+
opts?: InsightSearchStoreOptions,
|
|
689
|
+
): Promise<ReadonlyArray<MemoryHit<Insight>>>;
|
|
690
|
+
/** Lookup a single insight by id (`null` when absent / pruned). */
|
|
691
|
+
get?(id: string): Promise<Insight | null>;
|
|
692
|
+
/**
|
|
693
|
+
* Set an insight's retrieval-trust `status` (MCON-2) - promote a quarantined
|
|
694
|
+
* (reflection) insight or re-quarantine an active one, with a
|
|
695
|
+
* `memory_history` audit row. Powers {@link InsightMemory.validate}.
|
|
696
|
+
*/
|
|
697
|
+
setStatus?(
|
|
698
|
+
id: string,
|
|
699
|
+
status: MemoryStatus,
|
|
700
|
+
reason?: string,
|
|
701
|
+
scope?: SessionScope,
|
|
702
|
+
): Promise<void>;
|
|
703
|
+
/**
|
|
704
|
+
* Adjust an insight's ExpeL salience by `delta`, clamped at 0. The
|
|
705
|
+
* floor is the value at which {@link prune} removes it.
|
|
706
|
+
*/
|
|
707
|
+
bumpSalience(id: string, delta: number, reason?: string): Promise<void>;
|
|
708
|
+
/**
|
|
709
|
+
* Soft-delete every salience-0 insight for the scope (the ExpeL
|
|
710
|
+
* forgetting step). Returns the number pruned. Tombstone only -
|
|
711
|
+
* pruned insights stay auditable.
|
|
712
|
+
*/
|
|
713
|
+
prune(scope: SessionScope): Promise<number>;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Extension of the typed `ProceduralMemoryStore` with the optional
|
|
718
|
+
* promotion helper that storage adapters may expose (MCON-2).
|
|
719
|
+
*
|
|
720
|
+
* @stable
|
|
721
|
+
*/
|
|
722
|
+
export interface ProceduralMemoryStoreExt extends ProceduralMemoryStore {
|
|
723
|
+
/**
|
|
724
|
+
* Set a rule's retrieval-trust `status` - promote a quarantined (induced)
|
|
725
|
+
* procedure into `activate()` or re-quarantine an active one, with a
|
|
726
|
+
* `memory_history` audit row. Powers {@link ProceduralMemory.validate}.
|
|
727
|
+
*/
|
|
728
|
+
setStatus?(
|
|
729
|
+
id: string,
|
|
730
|
+
status: MemoryStatus,
|
|
731
|
+
reason?: string,
|
|
732
|
+
scope?: SessionScope,
|
|
733
|
+
): Promise<void>;
|
|
734
|
+
/**
|
|
735
|
+
* Lexical runbook search over rule text (D3, migration 028) - content
|
|
736
|
+
* recall for "find the procedure for this task", as opposed to
|
|
737
|
+
* predicate activation. Quarantined (unvalidated induced) procedures
|
|
738
|
+
* are excluded unless the inspector opts in. Optional - adapters
|
|
739
|
+
* without the index omit it and {@link ProceduralMemory.search} falls
|
|
740
|
+
* back to an in-memory lexical scan over `list(...)`.
|
|
741
|
+
*/
|
|
742
|
+
search?(
|
|
743
|
+
scope: SessionScope,
|
|
744
|
+
query: string,
|
|
745
|
+
opts?: { readonly topK?: number; readonly includeQuarantined?: boolean },
|
|
746
|
+
): Promise<ReadonlyArray<MemoryHit<Rule>>>;
|
|
747
|
+
/**
|
|
748
|
+
* Record one demonstrated successful reuse of a rule and return the
|
|
749
|
+
* new counter value (MCON-2 part 4). Powers
|
|
750
|
+
* promotion-by-demonstrated-success via
|
|
751
|
+
* {@link ProceduralMemory.recordOutcome}. Optional - adapters without
|
|
752
|
+
* the counter simply never auto-promote.
|
|
753
|
+
*/
|
|
754
|
+
recordSuccess?(id: string): Promise<number>;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/** Find-or-create payload for {@link GraphMemoryStoreExt.upsertEntity}. */
|
|
758
|
+
export interface EntityUpsertInput {
|
|
759
|
+
/** Display name as first observed. */
|
|
760
|
+
readonly name: string;
|
|
761
|
+
/** Folded key for lexical dedup + the canonical unique index. */
|
|
762
|
+
readonly normalizedName: string;
|
|
763
|
+
/** Optional name embedding (back-filled on a hit that lacked one). */
|
|
764
|
+
readonly vector?: Float32Array;
|
|
765
|
+
/** Embedder that produced {@link EntityUpsertInput.vector}. */
|
|
766
|
+
readonly embedderId?: string;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* A canonical {@link GraphEntity} returned with its name embedding so the
|
|
771
|
+
* resolver can run cosine dedup in-process (entity counts are small).
|
|
772
|
+
*/
|
|
773
|
+
export interface EntityWithEmbedding extends GraphEntity {
|
|
774
|
+
readonly vector: Float32Array | null;
|
|
775
|
+
readonly embedderId: string | null;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/** One row of the append-only merge / unmerge audit ledger (P2-1). */
|
|
779
|
+
export interface EntityMergeRecord {
|
|
780
|
+
readonly id: string;
|
|
781
|
+
readonly userId: string;
|
|
782
|
+
readonly kind: 'merge' | 'unmerge';
|
|
783
|
+
readonly fromEntityId: string;
|
|
784
|
+
readonly intoEntityId: string | null;
|
|
785
|
+
readonly reason?: string;
|
|
786
|
+
readonly createdAt: string;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/** Options for {@link GraphMemoryStoreExt.expandOneHop}. */
|
|
790
|
+
export interface ExpandHopsStoreOptions {
|
|
791
|
+
/** Traversal depth (default `1`). */
|
|
792
|
+
readonly maxHops?: number;
|
|
793
|
+
/** Max neighbours to return (default `60`). */
|
|
794
|
+
readonly limit?: number;
|
|
795
|
+
/** Include quarantined neighbours (validation / inspector path). */
|
|
796
|
+
readonly includeQuarantined?: boolean;
|
|
797
|
+
/** Point-in-time filter, ISO-8601 (same semantics as fact search). */
|
|
798
|
+
readonly asOf?: string;
|
|
799
|
+
/**
|
|
800
|
+
* Include superseded / validity-expired neighbours. Default reads
|
|
801
|
+
* evaluate validity at NOW (memory-retrieval-01).
|
|
802
|
+
*/
|
|
803
|
+
readonly includeSuperseded?: boolean;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* Optional storage extension for the lightweight in-SQLite relation
|
|
808
|
+
* graph (P2-1). Owns the canonical `entities` table, the `fact_entities`
|
|
809
|
+
* mapping, and the append-only `entity_merges` ledger. The entity
|
|
810
|
+
* *resolution policy* (lexical + embedding dedup, optional LLM
|
|
811
|
+
* adjudication) lives in `@graphorin/memory`; this surface is the pure
|
|
812
|
+
* persistence + the recursive-CTE traversal.
|
|
813
|
+
*
|
|
814
|
+
* Adapters that opt out leave the property undefined; entity resolution
|
|
815
|
+
* on write degrades to a no-op and `search({ expandHops })` skips
|
|
816
|
+
* expansion. The default `@graphorin/store-sqlite` adapter implements it.
|
|
817
|
+
*
|
|
818
|
+
* @stable
|
|
819
|
+
*/
|
|
820
|
+
export interface GraphMemoryStoreExt {
|
|
821
|
+
/** Find-or-create the canonical (root) entity for the normalized name. */
|
|
822
|
+
upsertEntity(scope: SessionScope, input: EntityUpsertInput): Promise<string>;
|
|
823
|
+
/** Link a fact's subject / object to a canonical entity (idempotent). */
|
|
824
|
+
linkFactEntity(factId: string, entityId: string, role: EntityRole): Promise<void>;
|
|
825
|
+
/** Candidate entities for the resolver (roots only unless `includeMerged`). */
|
|
826
|
+
listEntities(
|
|
827
|
+
scope: SessionScope,
|
|
828
|
+
opts?: { readonly includeMerged?: boolean; readonly limit?: number },
|
|
829
|
+
): Promise<ReadonlyArray<EntityWithEmbedding>>;
|
|
830
|
+
/**
|
|
831
|
+
* Uncapped indexed lookup of the canonical root for an exact normalized
|
|
832
|
+
* name. Lets the resolver dedup an exact alias of an arbitrarily-old
|
|
833
|
+
* entity without scanning (and deserializing) the bounded
|
|
834
|
+
* {@link listEntities} candidate window (CS-11). Optional: stores without
|
|
835
|
+
* it fall back to the capped lexical scan inside `resolveEntityDecision`.
|
|
836
|
+
*/
|
|
837
|
+
findEntityByNormalizedName?(
|
|
838
|
+
scope: SessionScope,
|
|
839
|
+
normalizedName: string,
|
|
840
|
+
): Promise<EntityWithEmbedding | null>;
|
|
841
|
+
/** Lookup one entity by id (any merge state). */
|
|
842
|
+
getEntity(scope: SessionScope, id: string): Promise<GraphEntity | null>;
|
|
843
|
+
/** Follow `mergedInto` to the canonical root id. */
|
|
844
|
+
resolveCanonical(scope: SessionScope, id: string): Promise<string>;
|
|
845
|
+
/** Merge `fromId` into `intoId`'s root; auditable + reversible. */
|
|
846
|
+
mergeEntities(
|
|
847
|
+
scope: SessionScope,
|
|
848
|
+
fromId: string,
|
|
849
|
+
intoId: string,
|
|
850
|
+
reason?: string,
|
|
851
|
+
): Promise<void>;
|
|
852
|
+
/** Reverse a merge: make `id` a root again + record an audit row. */
|
|
853
|
+
unmergeEntity(scope: SessionScope, id: string, reason?: string): Promise<void>;
|
|
854
|
+
/** The append-only merge / unmerge ledger, newest first. */
|
|
855
|
+
listMerges(
|
|
856
|
+
scope: SessionScope,
|
|
857
|
+
opts?: { readonly limit?: number },
|
|
858
|
+
): Promise<ReadonlyArray<EntityMergeRecord>>;
|
|
859
|
+
/** Expand seed facts to neighbours sharing a canonical entity (one-hop CTE). */
|
|
860
|
+
expandOneHop(
|
|
861
|
+
scope: SessionScope,
|
|
862
|
+
seedFactIds: ReadonlyArray<string>,
|
|
863
|
+
opts?: ExpandHopsStoreOptions,
|
|
864
|
+
): Promise<ReadonlyArray<Fact>>;
|
|
865
|
+
/**
|
|
866
|
+
* PPR-lite graded expansion (D5): like {@link expandOneHop} but returns
|
|
867
|
+
* each neighbour with its minimum hop `depth` from the seeds, so the
|
|
868
|
+
* tier can weight it by damped spreading activation. Optional - stores
|
|
869
|
+
* without it fall back to flat one-hop expansion.
|
|
870
|
+
*/
|
|
871
|
+
expandActivation?(
|
|
872
|
+
scope: SessionScope,
|
|
873
|
+
seedFactIds: ReadonlyArray<string>,
|
|
874
|
+
opts?: ExpandHopsStoreOptions,
|
|
875
|
+
): Promise<ReadonlyArray<{ readonly fact: Fact; readonly depth: number }>>;
|
|
876
|
+
/**
|
|
877
|
+
* Exact entity-match retriever (D5): facts linked to the canonical
|
|
878
|
+
* entity for `normalizedName`. Optional. Powers a precise
|
|
879
|
+
* "facts about <entity>" candidate leg.
|
|
880
|
+
*/
|
|
881
|
+
factsForEntityName?(
|
|
882
|
+
scope: SessionScope,
|
|
883
|
+
normalizedName: string,
|
|
884
|
+
opts?: ExpandHopsStoreOptions,
|
|
885
|
+
): Promise<ReadonlyArray<Fact>>;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* Composite shape every `@graphorin/memory` consumer must supply at
|
|
890
|
+
* construction time. Mirrors the typed `MemoryStore` from
|
|
891
|
+
* `@graphorin/core` but widens the per-tier sub-store types with the
|
|
892
|
+
* optional embedding-aware extension methods.
|
|
893
|
+
*
|
|
894
|
+
* Concrete adapters (most notably `@graphorin/store-sqlite`)
|
|
895
|
+
* implement every member by construction; in-memory test doubles
|
|
896
|
+
* implement the minimum and leave the optional members undefined.
|
|
897
|
+
*
|
|
898
|
+
* @stable
|
|
899
|
+
*/
|
|
900
|
+
export interface MemoryStoreAdapter
|
|
901
|
+
extends Omit<MemoryStore, 'session' | 'episodic' | 'semantic' | 'procedural'> {
|
|
902
|
+
readonly session: SessionMemoryStoreExt;
|
|
903
|
+
readonly episodic: EpisodicMemoryStoreExt;
|
|
904
|
+
readonly semantic: SemanticMemoryStoreExt & Partial<DecayMemoryStoreExt>;
|
|
905
|
+
readonly procedural: ProceduralMemoryStoreExt;
|
|
906
|
+
/**
|
|
907
|
+
* Optional conflict audit + pending queue surface. Defined on the
|
|
908
|
+
* default `@graphorin/store-sqlite` adapter, omitted on the
|
|
909
|
+
* minimal in-memory test doubles.
|
|
910
|
+
*
|
|
911
|
+
* @stable
|
|
912
|
+
*/
|
|
913
|
+
readonly conflicts?: ConflictMemoryStoreExt;
|
|
914
|
+
/**
|
|
915
|
+
* Optional consolidator state + runs + DLQ surface. Defined on
|
|
916
|
+
* the default `@graphorin/store-sqlite` adapter; in-memory test
|
|
917
|
+
* doubles may opt in via the fixture.
|
|
918
|
+
*
|
|
919
|
+
* @stable
|
|
920
|
+
*/
|
|
921
|
+
readonly consolidator?: ConsolidatorMemoryStoreExt;
|
|
922
|
+
/**
|
|
923
|
+
* Optional reflection insight surface (P1-1). Defined on the default
|
|
924
|
+
* `@graphorin/store-sqlite` adapter; omitted ⇒ reflection is a no-op
|
|
925
|
+
* and `InsightMemory` reads return empty.
|
|
926
|
+
*
|
|
927
|
+
* @stable
|
|
928
|
+
*/
|
|
929
|
+
readonly insights?: InsightMemoryStoreExt;
|
|
930
|
+
/**
|
|
931
|
+
* Optional relation-graph surface (P2-1). Defined on the default
|
|
932
|
+
* `@graphorin/store-sqlite` adapter; omitted ⇒ entity resolution on
|
|
933
|
+
* write is a no-op and `search({ expandHops })` skips expansion.
|
|
934
|
+
*
|
|
935
|
+
* @stable
|
|
936
|
+
*/
|
|
937
|
+
readonly graph?: GraphMemoryStoreExt;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* Re-export of session memory shape we use locally for narrower
|
|
942
|
+
* types inside the facade.
|
|
943
|
+
*
|
|
944
|
+
* @internal
|
|
945
|
+
*/
|
|
946
|
+
export type SessionListResult = ReadonlyArray<Message>;
|
|
947
|
+
|
|
948
|
+
export type {
|
|
949
|
+
EmbedderProvider,
|
|
950
|
+
Episode,
|
|
951
|
+
EpisodicMemoryStore,
|
|
952
|
+
Fact,
|
|
953
|
+
Insight,
|
|
954
|
+
Message,
|
|
955
|
+
MessageRef,
|
|
956
|
+
ProceduralMemoryStore,
|
|
957
|
+
SemanticMemoryStore,
|
|
958
|
+
SessionListOptions,
|
|
959
|
+
SessionMemoryStore,
|
|
960
|
+
SessionScope,
|
|
961
|
+
SharedMemoryStore,
|
|
962
|
+
WorkingMemoryStore,
|
|
963
|
+
};
|