@pyxmate/memory 1.19.8 → 1.20.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/dist/{chunk-VORP6NHJ.mjs → chunk-BUKDWHTY.mjs} +111 -0
- package/dist/{chunk-LWFCE4OS.mjs → chunk-HVJZDJGH.mjs} +2 -4
- package/dist/{chunk-KVYCISUI.mjs → chunk-KZKGRND2.mjs} +3 -49
- package/dist/{chunk-FIRMGTFX.mjs → chunk-QWLTZIIK.mjs} +1 -1
- package/dist/cli/pyx-mem.mjs +3 -3
- package/dist/dashboard.mjs +4 -4
- package/dist/{data-plane-contract-CmosA5XV.d.ts → data-plane-contract-webbeMs5.d.ts} +6 -0
- package/dist/data-plane-contract.d.ts +1 -1
- package/dist/data-plane-contract.mjs +1 -1
- package/dist/index.d.ts +1339 -1300
- package/dist/index.mjs +14 -10
- package/dist/react.mjs +4 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,1435 +1,1472 @@
|
|
|
1
1
|
import { StoreInput as StoreInput$1, MemoryEntry as MemoryEntry$1, MemorySearchParams as MemorySearchParams$1, MemorySearchResult as MemorySearchResult$1, MemoryType as MemoryType$1, PrincipalContext as PrincipalContext$1, SensitivityLevel as SensitivityLevel$1, MemoryStats as MemoryStats$1, MemoryInsights as MemoryInsights$1, LineageParams as LineageParams$1, LineageResult as LineageResult$1, ReinforceParams as ReinforceParams$1, ReinforceResult as ReinforceResult$1, WikiLintReport as WikiLintReport$1, GraphRepairResult as GraphRepairResult$1, ExtractedImageMeta as ExtractedImageMeta$1, IngestEntity as IngestEntity$1, IngestRelationship as IngestRelationship$1, EntityExtractionResult as EntityExtractionResult$1, Topology as Topology$1, IngestEvent as IngestEvent$1, GraphEnrichEvent as GraphEnrichEvent$1, GraphNode as GraphNode$1, GraphTraversalResult as GraphTraversalResult$1, CorrectionRecord as CorrectionRecord$1 } from '@pyx-memory/shared';
|
|
2
2
|
export { documentContentSource, documentGraphSource, documentImageSource } from '@pyx-memory/shared';
|
|
3
|
-
export { e as encodeListCursorToken, p as parseListCursorToken } from './data-plane-contract-
|
|
3
|
+
export { e as encodeListCursorToken, p as parseListCursorToken } from './data-plane-contract-webbeMs5.js';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
/** ISO 8601 timestamp string */
|
|
6
|
+
type Timestamp = string;
|
|
7
|
+
/** Unique agent identifier */
|
|
8
|
+
type AgentId = string;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Caller identity for ReBAC authorization.
|
|
12
|
+
*
|
|
13
|
+
* The canonical "subject" in Zanzibar terms — passed alongside requests so the
|
|
14
|
+
* memory layer can compute an AuthzPlan (visible namespaces + entry overrides)
|
|
15
|
+
* before any retrieval source fans out.
|
|
16
|
+
*
|
|
17
|
+
* Identity comes from authenticated request context (X-Tenant-Id / auth token
|
|
18
|
+
* claims), never from request bodies or multipart form fields. The legacy
|
|
19
|
+
* `userId` / `teamId` / `agentId` columns on MemoryEntry remain for audit and
|
|
20
|
+
* legacy filters but MUST NOT drive authorization decisions — they are
|
|
21
|
+
* collision-prone aliases (a service principal sharing an ID with a human
|
|
22
|
+
* user has no protection against confused-deputy attacks).
|
|
23
|
+
*
|
|
24
|
+
* Sensitivity / clearance is intentionally NOT on this object. It is a
|
|
25
|
+
* MAC-style classification, orthogonal to RBAC, and continues to be carried
|
|
26
|
+
* via the `X-Caller-Access-Level` header → `MemorySearchParams.maxSensitivity`.
|
|
27
|
+
* Conflating the two couples future changes (e.g. per-namespace classification
|
|
28
|
+
* rules) to identity propagation.
|
|
29
|
+
*/
|
|
30
|
+
interface PrincipalContext {
|
|
20
31
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
32
|
+
* Hard isolation boundary. Required even in single-tenant deployments —
|
|
33
|
+
* single-mode passes a stable sentinel (`SINGLE_TENANT_ID`) so authz code
|
|
34
|
+
* paths look identical regardless of mode.
|
|
23
35
|
*/
|
|
24
|
-
|
|
25
|
-
/** Filter by memory type. */
|
|
26
|
-
type?: MemoryType$1;
|
|
27
|
-
/** Filter by agent ID. */
|
|
28
|
-
agentId?: string;
|
|
29
|
-
/** Filter by tenant ID for multi-tenant isolation. */
|
|
30
|
-
tenantId?: string;
|
|
31
|
-
/** Exact namespace scope. Excludes legacy tenant-root entries. */
|
|
32
|
-
namespaceId?: string;
|
|
36
|
+
tenantId: string;
|
|
33
37
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
+
* Stable subject ID (within the tenant). For humans this is the userId;
|
|
39
|
+
* for AI runtimes it is the agentId; for system actors it is a service
|
|
40
|
+
* identifier. Combined with `kind`, forms the Zanzibar subject coordinate
|
|
41
|
+
* `<kind>:<principalId>`.
|
|
38
42
|
*/
|
|
39
|
-
|
|
40
|
-
/** Maximum sensitivity level to include. Omitted preserves legacy behavior. */
|
|
41
|
-
maxSensitivity?: SensitivityLevel$1;
|
|
43
|
+
principalId: string;
|
|
42
44
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* `
|
|
45
|
+
* Subject namespace. Distinguishes humans from AI agents from internal
|
|
46
|
+
* services so a userId/agentId/serviceId collision cannot grant
|
|
47
|
+
* unintended access.
|
|
48
|
+
* - `user`: human end user
|
|
49
|
+
* - `agent`: AI runtime acting on a user's behalf or autonomously
|
|
50
|
+
* - `service`: non-AI internal system (cron, ETL, admin tooling)
|
|
49
51
|
*/
|
|
50
|
-
|
|
52
|
+
kind: 'user' | 'agent' | 'service';
|
|
51
53
|
}
|
|
52
|
-
/**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
/** Sentinel tenant ID used in single-tenant deployments. */
|
|
55
|
+
declare const SINGLE_TENANT_ID = "_single";
|
|
56
|
+
|
|
57
|
+
declare const MemoryType: {
|
|
58
|
+
readonly SHORT_TERM: "short-term";
|
|
59
|
+
readonly LONG_TERM: "long-term";
|
|
60
|
+
readonly WORKING: "working";
|
|
61
|
+
readonly EPISODIC: "episodic";
|
|
62
|
+
readonly SUMMARY: "summary";
|
|
63
|
+
};
|
|
64
|
+
type MemoryType = (typeof MemoryType)[keyof typeof MemoryType];
|
|
65
|
+
declare const SensitivityLevel: {
|
|
66
|
+
readonly PUBLIC: "public";
|
|
67
|
+
readonly INTERNAL: "internal";
|
|
68
|
+
readonly SECRET: "secret";
|
|
69
|
+
};
|
|
70
|
+
type SensitivityLevel = (typeof SensitivityLevel)[keyof typeof SensitivityLevel];
|
|
71
|
+
declare const RAGStrategy: {
|
|
72
|
+
readonly NAIVE: "naive";
|
|
73
|
+
readonly GRAPH: "graph";
|
|
74
|
+
readonly HYBRID: "hybrid";
|
|
75
|
+
};
|
|
76
|
+
type RAGStrategy = (typeof RAGStrategy)[keyof typeof RAGStrategy];
|
|
77
|
+
/**
|
|
78
|
+
* Strategy identifiers that were public in earlier versions and have been
|
|
79
|
+
* removed. Server/SDK reject requests using these with a stable
|
|
80
|
+
* `strategy.deprecated:<name>` error code (not the generic "invalid
|
|
81
|
+
* strategy" message) so callers and dashboards can detect the removal
|
|
82
|
+
* cleanly across a version bump.
|
|
83
|
+
*
|
|
84
|
+
* v0.26: `agentic` removed (Codex pair: silent-catch in agentic.ts
|
|
85
|
+
* violated Production-ready; behavior subsumed by HybridRAGEngine).
|
|
86
|
+
*/
|
|
87
|
+
declare const DEPRECATED_RAG_STRATEGIES: ReadonlyMap<string, string>;
|
|
88
|
+
declare const VectorProvider: {
|
|
89
|
+
readonly LANCEDB: "lancedb";
|
|
90
|
+
};
|
|
91
|
+
type VectorProvider = (typeof VectorProvider)[keyof typeof VectorProvider];
|
|
92
|
+
declare const EmbeddingProviderName: {
|
|
93
|
+
readonly STUB: "stub";
|
|
94
|
+
/** @deprecated Vestigial — pyx-memory uses internal EmbeddingGemma embeddings. */
|
|
95
|
+
readonly ANTHROPIC: "anthropic";
|
|
96
|
+
/** @deprecated Vestigial — pyx-memory uses internal EmbeddingGemma embeddings. */
|
|
97
|
+
readonly OPENAI: "openai";
|
|
98
|
+
/** In-process ONNX model (default: EmbeddingGemma-300M). */
|
|
99
|
+
readonly LOCAL: "local";
|
|
100
|
+
/** Remote OpenAI-compatible embedding service (pyx-cloud shared, custom, etc.). */
|
|
101
|
+
readonly HTTP: "http";
|
|
102
|
+
};
|
|
103
|
+
type EmbeddingProviderName = (typeof EmbeddingProviderName)[keyof typeof EmbeddingProviderName];
|
|
104
|
+
type GraphEnrichmentStatus = 'caller-provided' | 'extracted' | 'merged' | 'opted-out' | 'skipped-duplicate' | 'skipped-sensitive' | 'skipped-unprovisioned' | 'extracted-empty' | 'failed-graph-write' | 'failed-best-effort';
|
|
105
|
+
interface GraphEnrichment {
|
|
106
|
+
status: GraphEnrichmentStatus;
|
|
107
|
+
provider?: 'http' | 'local' | 'none';
|
|
108
|
+
reason?: string;
|
|
109
|
+
action?: string;
|
|
61
110
|
}
|
|
62
|
-
/**
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
111
|
+
/**
|
|
112
|
+
* A caller-supplied relationship whose source or target name did not resolve to
|
|
113
|
+
* any entity in the same store call (after name normalization), so the edge was
|
|
114
|
+
* not written. Surfaced on the store response so the agent — not just the server
|
|
115
|
+
* log — can see which edges to re-send.
|
|
116
|
+
*/
|
|
117
|
+
interface DroppedGraphRelationship {
|
|
118
|
+
source: string;
|
|
119
|
+
target: string;
|
|
120
|
+
type: string;
|
|
121
|
+
}
|
|
122
|
+
type VectorStatus = 'pending' | 'stored' | 'skipped';
|
|
123
|
+
/**
|
|
124
|
+
* Upper bound of a caller-declared `sessionOrdinal`: `n + 2` stays an exact
|
|
125
|
+
* integer, so the ±2 neighbor operator needs no runtime arithmetic guard.
|
|
126
|
+
*/
|
|
127
|
+
declare const SESSION_ORDINAL_MAX: number;
|
|
128
|
+
declare function isSessionOrdinal(value: unknown): value is number;
|
|
129
|
+
interface MemoryEntry {
|
|
130
|
+
id: string;
|
|
131
|
+
content: string;
|
|
132
|
+
type: MemoryType;
|
|
133
|
+
agentId?: AgentId;
|
|
134
|
+
sessionId?: string;
|
|
73
135
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
136
|
+
* Caller-declared turn coordinate inside `sessionId` (0 ≤ n ≤ SESSION_ORDINAL_MAX).
|
|
137
|
+
* Never inferred from timestamps or insertion order; unique per
|
|
138
|
+
* (tenant, namespace, session) while declared.
|
|
77
139
|
*/
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
140
|
+
sessionOrdinal?: number;
|
|
141
|
+
metadata: Record<string, unknown>;
|
|
142
|
+
/** @deprecated Vestigial — embeddings are managed internally by the vector store. */
|
|
143
|
+
embedding?: number[];
|
|
144
|
+
createdAt: Timestamp;
|
|
145
|
+
/** SHA-256 hash of content for deduplication. */
|
|
146
|
+
contentHash?: string;
|
|
147
|
+
/** Importance score (1-10). */
|
|
148
|
+
importance?: number;
|
|
149
|
+
/** Number of times this entry has been accessed via search. */
|
|
150
|
+
accessCount?: number;
|
|
151
|
+
/** ISO timestamp of last access via search. */
|
|
152
|
+
lastAccessed?: string;
|
|
153
|
+
/** Parent entry ID for hierarchical storage (e.g., doc → section → chunk). */
|
|
154
|
+
parentId?: string;
|
|
155
|
+
/** Source identifier (e.g., filename, URL, session). */
|
|
90
156
|
source?: string;
|
|
91
|
-
/**
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
157
|
+
/** When the event described by this memory occurred. */
|
|
158
|
+
eventTime?: string;
|
|
159
|
+
/** When this entry was ingested into the system. */
|
|
160
|
+
ingestTime?: string;
|
|
161
|
+
/** Sensitivity classification based on content analysis. */
|
|
162
|
+
sensitivity?: SensitivityLevel;
|
|
163
|
+
/** Whether the content field is encrypted at rest. */
|
|
164
|
+
encrypted?: boolean;
|
|
165
|
+
/** Number of graph entities written by this store call. Present on store responses. */
|
|
166
|
+
graphEntitiesWritten?: number;
|
|
167
|
+
/** Number of graph relationships written by this store call. Present on store responses. */
|
|
168
|
+
graphRelationshipsWritten?: number;
|
|
169
|
+
/** Count of caller relationships dropped because an endpoint name did not match any entity in the call. Present (and >0) only when edges were dropped. */
|
|
170
|
+
graphRelationshipsDropped?: number;
|
|
171
|
+
/** Up to 20 of the dropped relationships (source/target/type), so the agent can re-send them. Present only when edges were dropped. */
|
|
172
|
+
graphRelationshipsDroppedDetail?: DroppedGraphRelationship[];
|
|
173
|
+
/** Graph extraction/enrichment outcome for this store call. Present on graph-targeted store responses. */
|
|
174
|
+
graphEnrichment?: GraphEnrichment;
|
|
175
|
+
/** Store response vector outcome. Pending means SQLite is durable and vector indexing is eventually consistent. */
|
|
176
|
+
vectorStatus?: VectorStatus;
|
|
177
|
+
/** Tenant ID for multi-tenant isolation. */
|
|
96
178
|
tenantId?: string;
|
|
97
|
-
/**
|
|
179
|
+
/** User ID within the tenant. */
|
|
180
|
+
userId?: string;
|
|
181
|
+
/** Team/group ID within the tenant. */
|
|
182
|
+
teamId?: string;
|
|
183
|
+
/**
|
|
184
|
+
* Namespace ID — the primary protected resource for ReBAC authorization.
|
|
185
|
+
* `undefined` (NULL on the row) means the entry lives in the legacy
|
|
186
|
+
* "tenant-root" bucket and is visible to anyone with tenant access (the
|
|
187
|
+
* pre-ReBAC posture). Setting `namespaceId` opts the entry into AuthzPlan-
|
|
188
|
+
* based filtering, where visibility is computed from `authz_tuples` for
|
|
189
|
+
* the calling principal.
|
|
190
|
+
*/
|
|
98
191
|
namespaceId?: string;
|
|
99
192
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
193
|
+
* When true, consolidation leaves this entry alone — it is never archived by
|
|
194
|
+
* decay and never merged (nor merged-into) by semantic deduplication. Use for
|
|
195
|
+
* stable anchor entries whose ID is referenced by external systems (e.g. a
|
|
196
|
+
* file-catalog row pointed at by another service's foreign key).
|
|
102
197
|
*/
|
|
103
|
-
|
|
198
|
+
pinned?: boolean;
|
|
104
199
|
/**
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
200
|
+
* Lifecycle status (H8). Optional on write (absent means `'active'`), but
|
|
201
|
+
* every entry READ back from the store carries it explicitly — a caller can
|
|
202
|
+
* compare `entry.status === 'active'` without special-casing an absent field.
|
|
203
|
+
* `'active'` is a normal retrievable entry. `'superseded'` means a newer near-duplicate
|
|
204
|
+
* UPDATE replaced this one during consolidation. `'archived'` (1b) means decay
|
|
205
|
+
* retired it (no successor) — kept, strength 0, `deep`-tier only. All three
|
|
206
|
+
* are kept (history / lineage / deep recall) but `superseded`/`archived` are
|
|
207
|
+
* excluded from default/quick/medium search. Only `forget()` and exact-byte-
|
|
208
|
+
* duplicate collapse hard-delete. See `docs/H8-MEMORY-MODEL-DESIGN.md`.
|
|
110
209
|
*/
|
|
111
|
-
|
|
112
|
-
/** Maximum sensitivity level to include. Omitted preserves legacy behavior. */
|
|
113
|
-
maxSensitivity?: SensitivityLevel$1;
|
|
114
|
-
}
|
|
115
|
-
/** Abstract interface for memory systems (local or remote). */
|
|
116
|
-
interface MemoryInterface {
|
|
117
|
-
initialize(): Promise<void>;
|
|
118
|
-
store(entry: StoreInput$1): Promise<MemoryEntry$1>;
|
|
119
|
-
search(params: MemorySearchParams$1): Promise<MemorySearchResult$1>;
|
|
120
|
-
/** List entries with SQL LIMIT/OFFSET pagination. */
|
|
121
|
-
list(params?: MemoryListParams): Promise<MemoryListResult>;
|
|
122
|
-
get(id: string, options?: TenantScopeOptions): Promise<MemoryEntry$1 | null>;
|
|
123
|
-
delete(id: string, options?: TenantScopeOptions): Promise<boolean>;
|
|
124
|
-
clearSession(sessionId: string, options?: TenantScopeOptions): Promise<number>;
|
|
125
|
-
stats(options?: TenantScopeOptions): Promise<MemoryStats$1>;
|
|
126
|
-
insights(options?: TenantScopeOptions): Promise<MemoryInsights$1>;
|
|
127
|
-
/** Query entries as they existed at a point in time (by ingest time). */
|
|
128
|
-
queryAsOf(asOfDate: string, filters?: TemporalQueryFilters, options?: TenantScopeOptions): Promise<MemoryEntry$1[]>;
|
|
129
|
-
/** Read the time-ordered lineage of a graph fact or superseded entry chain. */
|
|
130
|
-
lineage(params: LineageParams$1): Promise<LineageResult$1>;
|
|
131
|
-
/** Reinforce memories that were actually used by the caller. */
|
|
132
|
-
reinforce(params: ReinforceParams$1): Promise<ReinforceResult$1>;
|
|
133
|
-
/** Query entries by event time range (when things actually happened). */
|
|
134
|
-
queryByEventTime(startTime: string, endTime: string, filters?: TemporalQueryFilters): Promise<MemoryEntry$1[]>;
|
|
135
|
-
shutdown(): Promise<void>;
|
|
136
|
-
}
|
|
137
|
-
/** Consolidation run result. */
|
|
138
|
-
interface ConsolidationRunResult {
|
|
139
|
-
entriesProcessed: number;
|
|
140
|
-
entriesMerged: number;
|
|
141
|
-
entriesArchived: number;
|
|
142
|
-
durationMs: number;
|
|
143
|
-
}
|
|
144
|
-
/** Extended interface with lifecycle operations. Non-breaking for existing consumers. */
|
|
145
|
-
interface ExtendedMemoryInterface extends MemoryInterface {
|
|
146
|
-
/** Run consolidation: score, dedup, decay, and summarize memories. */
|
|
147
|
-
consolidate(): Promise<ConsolidationRunResult>;
|
|
148
|
-
/** Soft-delete a memory with a reason (marks as archived). */
|
|
149
|
-
forget(id: string, reason?: string): Promise<boolean>;
|
|
150
|
-
/** Summarize a session's memories into a long-term entry. */
|
|
151
|
-
summarizeSession(sessionId: string): Promise<MemoryEntry$1 | null>;
|
|
210
|
+
status?: 'active' | 'superseded' | 'archived';
|
|
152
211
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
212
|
+
* When `status==='superseded'`, the id of the newer entry that replaced this
|
|
213
|
+
* one — the backward link used by `Memory.lineage()` chain traversal. Cleared
|
|
214
|
+
* to NULL (never resurrected to active) if the successor is later forgotten.
|
|
156
215
|
*/
|
|
157
|
-
|
|
158
|
-
limit?: number;
|
|
159
|
-
}): Promise<WikiLintReport$1>;
|
|
160
|
-
/** Run decay on all entries, archiving those below threshold. */
|
|
161
|
-
runDecay(): Promise<number>;
|
|
162
|
-
/** Reindex the FTS5 full-text search index. */
|
|
163
|
-
reindex(): Promise<void>;
|
|
164
|
-
/** Delete all entries matching a source, cleaning up all stores. */
|
|
165
|
-
deleteBySource(source: string, options?: TenantScopeOptions): Promise<number>;
|
|
166
|
-
/** Repair stale graph references left by older delete paths or crashed cleanup. */
|
|
167
|
-
repairGraph(): Promise<GraphRepairResult$1>;
|
|
216
|
+
supersededByEntryId?: string;
|
|
168
217
|
/**
|
|
169
|
-
*
|
|
170
|
-
*
|
|
218
|
+
* @internal Hosted data-plane only. SHA-256 of the canonical caller store
|
|
219
|
+
* payload (server-stamped timestamps excluded), persisted for caller-id
|
|
220
|
+
* stores so a re-send of the same `metadata.dbRef.revision` can be
|
|
221
|
+
* classified as an idempotent no-op (digest match) or a
|
|
222
|
+
* `revision_reuse_conflict` (digest mismatch). Graph entities/relationships
|
|
223
|
+
* are part of the payload but not of the row, so the digest cannot be
|
|
224
|
+
* recomputed from stored state.
|
|
171
225
|
*/
|
|
172
|
-
|
|
226
|
+
payloadDigest?: string;
|
|
227
|
+
}
|
|
228
|
+
interface MemorySearchParams {
|
|
229
|
+
query: string;
|
|
230
|
+
type?: MemoryType;
|
|
231
|
+
agentId?: AgentId;
|
|
232
|
+
/** Optional caller session identifier used for in-process hygiene telemetry. */
|
|
233
|
+
sessionId?: string;
|
|
234
|
+
limit?: number;
|
|
235
|
+
strategy?: RAGStrategy;
|
|
236
|
+
/** Filter results to entries whose eventTime falls within [start, end] (ISO 8601). */
|
|
237
|
+
eventTimeRange?: [string, string];
|
|
238
|
+
/** Filter results to entries ingested before this cutoff (ISO 8601). Falls back to createdAt when ingestTime is null. */
|
|
239
|
+
asOf?: string;
|
|
173
240
|
/**
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
241
|
+
* Soft recency ANCHOR (ISO 8601) — never a filter. Candidates are ranked by
|
|
242
|
+
* proximity to this time instead of now, and conflicting assertions
|
|
243
|
+
* re-order around it. Resolving relative-time expressions ("two months
|
|
244
|
+
* ago", "3년 전") to an absolute timestamp is the CALLER's side of the
|
|
245
|
+
* agentic contract — language understanding never enters the engine. Wins
|
|
246
|
+
* over the query-text year parse (hybrid strategy).
|
|
178
247
|
*/
|
|
179
|
-
|
|
248
|
+
anchorTime?: string;
|
|
180
249
|
/**
|
|
181
|
-
*
|
|
182
|
-
*
|
|
250
|
+
* The category the user is asking to count/list (e.g. "fitness classes",
|
|
251
|
+
* "운동 수업", any language). Presence signals enumeration intent and supplies
|
|
252
|
+
* the category for graph resolution; the caller (which understands the user's
|
|
253
|
+
* language) sets it. When omitted, pyx falls back to a deterministic EN/KO
|
|
254
|
+
* marker detector.
|
|
183
255
|
*/
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* No-op {@link MemoryInterface} for hosts that run without a memory backend
|
|
189
|
-
* (e.g. `MEMORY_URL` is unset). Every method returns a safe default, so the
|
|
190
|
-
* rest of the system functions without branching on `memory == null`.
|
|
191
|
-
*
|
|
192
|
-
* Canonical single source: this lives in the SAME package as `MemoryInterface`,
|
|
193
|
-
* so any method added to the interface fails THIS class's compile in the same
|
|
194
|
-
* build. The null-object can never silently drift behind the contract — the
|
|
195
|
-
* failure mode that left hand-rolled copies in downstream repos missing
|
|
196
|
-
* `lineage`/`reinforce` after the interface grew them.
|
|
197
|
-
*
|
|
198
|
-
* `initialize()` emits a single `console.warn`; pass nothing else — it is a
|
|
199
|
-
* pure null-object. Hosts wanting structured logging should log at the wiring
|
|
200
|
-
* site where they choose `DisabledMemory` over a real client.
|
|
201
|
-
*/
|
|
202
|
-
declare class DisabledMemory implements MemoryInterface {
|
|
203
|
-
initialize(): Promise<void>;
|
|
204
|
-
store(entry: StoreInput$1): Promise<MemoryEntry$1>;
|
|
205
|
-
search(): Promise<MemorySearchResult$1>;
|
|
206
|
-
list(params?: MemoryListParams): Promise<MemoryListResult>;
|
|
207
|
-
get(): Promise<MemoryEntry$1 | null>;
|
|
208
|
-
delete(): Promise<boolean>;
|
|
209
|
-
clearSession(): Promise<number>;
|
|
210
|
-
stats(): Promise<MemoryStats$1>;
|
|
211
|
-
insights(): Promise<MemoryInsights$1>;
|
|
212
|
-
queryAsOf(): Promise<MemoryEntry$1[]>;
|
|
213
|
-
lineage(): Promise<LineageResult$1>;
|
|
214
|
-
reinforce(): Promise<ReinforceResult$1>;
|
|
215
|
-
queryByEventTime(): Promise<MemoryEntry$1[]>;
|
|
216
|
-
shutdown(): Promise<void>;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Callbacks for two-phase file enrichment. All callbacks are optional:
|
|
221
|
-
* - Image-rich PDF + describeImage only → describes images, no entity extraction
|
|
222
|
-
* - Image-rich PDF + describeImage + extractEntitiesV2 → describes + extracts
|
|
223
|
-
* - Text-only file + extractEntitiesV2 only → extracts from textWindows
|
|
224
|
-
* - Mixed file + both → describes images + extracts from both sources
|
|
225
|
-
*
|
|
226
|
-
* Without any callback, the ingest stream emits the server result with no
|
|
227
|
-
* SDK-side enrichment. Server-side text/entity extraction may still run when
|
|
228
|
-
* configured; image understanding still requires caller-provided
|
|
229
|
-
* descriptions/hooks.
|
|
230
|
-
*/
|
|
231
|
-
interface EnrichmentCallbacks {
|
|
256
|
+
enumerationConcept?: string;
|
|
257
|
+
/** Confidence threshold below which the system recommends abstention (0.0–1.0). Default: 0.3. */
|
|
258
|
+
abstentionThreshold?: number;
|
|
232
259
|
/**
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
260
|
+
* Rerank with the cross-encoder before final truncation (hybrid strategy
|
|
261
|
+
* only). The pipeline retrieves and dedups a deeper candidate pool (≥50),
|
|
262
|
+
* scores it through the cross-encoder, then truncates to `limit` —
|
|
263
|
+
* reranking after truncation cannot change top-`limit` set membership.
|
|
264
|
+
* Forwarded by `MemoryClient.search` and the HTTP route; core enforces
|
|
265
|
+
* hybrid-only usage.
|
|
236
266
|
*/
|
|
237
|
-
|
|
267
|
+
enableRerank?: boolean;
|
|
238
268
|
/**
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
269
|
+
* Iterative multi-hop candidate generation (hybrid strategy only). After the
|
|
270
|
+
* first retrieval pass, non-oracle bridge entities are mined from the top
|
|
271
|
+
* seed passages, a second dense+lexical pass is seeded by those bridges, and
|
|
272
|
+
* both passes' ranked lists are fused into a single RRF before scoring and
|
|
273
|
+
* (optional) rerank-then-truncate. Grows the candidate pool to surface
|
|
274
|
+
* later-hop passages the single-pass query misses. Deterministic: no
|
|
275
|
+
* query-time LLM, fixed bridge order. Default off keeps the pipeline
|
|
276
|
+
* byte-identical. EMBEDDED ONLY: `MemoryClient.search` rejects it (the HTTP
|
|
277
|
+
* API does not forward it).
|
|
243
278
|
*/
|
|
244
|
-
|
|
245
|
-
textWindows: string[];
|
|
246
|
-
imageDescriptions: string[];
|
|
247
|
-
mimeType: string;
|
|
248
|
-
filename: string;
|
|
249
|
-
}) => Promise<{
|
|
250
|
-
entities: IngestEntity$1[];
|
|
251
|
-
relationships: IngestRelationship$1[];
|
|
252
|
-
}>;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Options for {@link MemoryClient.ingestFileEvents}. `signal` lets
|
|
256
|
-
* long-running ingests (LLM enrichment + graph writes) be cancelled cleanly.
|
|
257
|
-
*
|
|
258
|
-
* `namespaceId` opts the upload into ReBAC AuthzPlan visibility — the server
|
|
259
|
-
* thread the namespace through parsing → enrichment → store calls so the
|
|
260
|
-
* resulting catalog row and chunk entries land in the named namespace
|
|
261
|
-
* (server v0.17.4+; required when `requireNamespaceForTenantWrites=true`).
|
|
262
|
-
*/
|
|
263
|
-
interface IngestFileOptions {
|
|
264
|
-
description?: string;
|
|
265
|
-
enrichment?: EnrichmentCallbacks;
|
|
266
|
-
signal?: AbortSignal;
|
|
267
|
-
namespaceId?: string;
|
|
279
|
+
enableMultiHop?: boolean;
|
|
268
280
|
/**
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
281
|
+
* Explicit bridge entities for the second multi-hop pass, bypassing mining.
|
|
282
|
+
* EVAL ONLY — used by the benchmark oracle-ceiling probe to isolate fusion
|
|
283
|
+
* capacity from mining quality; never set on a production path. Ignored
|
|
284
|
+
* unless `enableMultiHop` is also set.
|
|
272
285
|
*/
|
|
273
|
-
|
|
286
|
+
multiHopBridges?: string[];
|
|
274
287
|
/**
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
288
|
+
* Set false for a read-only search that does NOT bump access counts /
|
|
289
|
+
* lastAccessed on returned entries. Access feeds ranking (WEIGHT_ACCESS and
|
|
290
|
+
* the no-eventTime recency fallback), so a measurement that searches the
|
|
291
|
+
* store mutates what it measures — repeated benchmark runs over a persisted
|
|
292
|
+
* index drift. Default true (access tracking is the product's usage signal).
|
|
280
293
|
*/
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Options for {@link MemoryClient.graphEnrichFileEvents}. `documentKey` is the
|
|
285
|
-
* caller's stable logical identity for the document whose graph is being
|
|
286
|
-
* rebuilt — the server derives the graph anchor id from
|
|
287
|
-
* (tenant, namespace, documentKey), so repeating the same key replaces the
|
|
288
|
-
* document's graph references instead of multiplying them.
|
|
289
|
-
*
|
|
290
|
-
* `enrichment.extractEntitiesV2` is required: graph-only re-enrichment is
|
|
291
|
-
* caller-extraction by definition (there is no server-side fallback).
|
|
292
|
-
*/
|
|
293
|
-
interface GraphEnrichFileOptions {
|
|
294
|
-
documentKey: string;
|
|
294
|
+
trackAccess?: boolean;
|
|
295
295
|
/**
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
signal?: AbortSignal;
|
|
304
|
-
enrichment: EnrichmentCallbacks;
|
|
305
|
-
}
|
|
306
|
-
interface FileDownloadOptions {
|
|
307
|
-
/** Stable logical document identity used by documentKey-aware ingest. */
|
|
308
|
-
documentKey?: string;
|
|
309
|
-
/** Exact namespace containing the uploaded document. */
|
|
310
|
-
namespaceId?: string;
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Caller-supplied enrichment for the per-call store path. Mirrors
|
|
314
|
-
* {@link EnrichmentCallbacks} for file ingest. When supplied, the SDK invokes
|
|
315
|
-
* the callback and merges the result into the payload before POSTing. Without
|
|
316
|
-
* a callback, server-side text/entity extraction can run only when the server
|
|
317
|
-
* has an extraction brain configured; otherwise callers must pass graph data
|
|
318
|
-
* or use caller-side hooks. Images always require caller-provided
|
|
319
|
-
* descriptions/hooks.
|
|
320
|
-
*/
|
|
321
|
-
interface StoreEnrichmentCallbacks {
|
|
322
|
-
/**
|
|
323
|
-
* Extract entities + relationships from `content`. The caller's LLM does
|
|
324
|
-
* the work; the SDK passes the result through {@link mergeExtractedEntities}
|
|
325
|
-
* (caller-wins, case-insensitive) before sending to the server.
|
|
326
|
-
*
|
|
327
|
-
* Skipped when `entry.extractEntities === false`. When
|
|
328
|
-
* `entry.extractEntities === true` but this callback is not supplied,
|
|
329
|
-
* `MemoryClient.store()` forwards the hint so the server-side extraction
|
|
330
|
-
* brain can run and loud-fail if it is not configured.
|
|
331
|
-
*/
|
|
332
|
-
extractEntities?: (input: {
|
|
333
|
-
content: string;
|
|
334
|
-
metadata?: Record<string, unknown>;
|
|
335
|
-
signal?: AbortSignal;
|
|
336
|
-
}) => Promise<EntityExtractionResult$1>;
|
|
337
|
-
}
|
|
338
|
-
/** Options accepted by {@link MemoryClient.store}. */
|
|
339
|
-
interface StoreOptions {
|
|
340
|
-
enrichment?: StoreEnrichmentCallbacks;
|
|
341
|
-
/** Propagated into the `extractEntities` callback and the underlying fetch. */
|
|
342
|
-
signal?: AbortSignal;
|
|
343
|
-
/** Stable logical request key. Reuse this exact value after a lost response. */
|
|
344
|
-
idempotencyKey?: string;
|
|
345
|
-
}
|
|
346
|
-
interface RequestAuthorityOptions {
|
|
347
|
-
/** Stable logical request key. Reuse this exact value after a lost response. */
|
|
348
|
-
idempotencyKey?: string;
|
|
349
|
-
}
|
|
350
|
-
/** Error thrown by MemoryClient when the server returns a non-success response. */
|
|
351
|
-
declare class MemoryServerError extends Error {
|
|
352
|
-
readonly status: number;
|
|
353
|
-
/** Stable machine-readable discriminator returned by the memory server. */
|
|
354
|
-
readonly code?: string;
|
|
355
|
-
/** Exact HTTP Retry-After value returned by the memory server. */
|
|
356
|
-
readonly retryAfter?: string;
|
|
357
|
-
/** Retry delay normalized to seconds when Retry-After is parseable. */
|
|
358
|
-
readonly retryAfterSeconds?: number;
|
|
359
|
-
constructor(message: string, status: number, code?: string, retryAfter?: string);
|
|
360
|
-
/** True when the server returned HTTP 404 (not found). */
|
|
361
|
-
get isNotFound(): boolean;
|
|
362
|
-
}
|
|
363
|
-
interface MemoryClientOptions {
|
|
364
|
-
/** API key for authentication. */
|
|
365
|
-
apiKey?: string;
|
|
366
|
-
/** Additional headers to send with every request (e.g., X-Caller-Access-Level). */
|
|
367
|
-
defaultHeaders?: Record<string, string>;
|
|
368
|
-
/**
|
|
369
|
-
* Default per-request timeout in milliseconds. Without this, a wedged
|
|
370
|
-
* memory server (e.g. event-loop blocked by inference) makes every
|
|
371
|
-
* caller hang forever — that was the Korens demo wedge in 2026-04 where
|
|
372
|
-
* a 161-second pyx-memory stall propagated through the runtime to the
|
|
373
|
-
* browser. Defaults to 30 s, which is high enough that normal
|
|
374
|
-
* `/search` and `/stats` requests never hit it but low enough that a
|
|
375
|
-
* stuck server fails loudly.
|
|
376
|
-
*
|
|
377
|
-
* Only applied when the caller does NOT pass their own `signal` via
|
|
378
|
-
* RequestInit. Long-running operations (large `consolidate`, `reindex`,
|
|
379
|
-
* file ingest with enrichment) should pass their own AbortSignal —
|
|
380
|
-
* that signal fully replaces the default ceiling.
|
|
381
|
-
*/
|
|
382
|
-
requestTimeoutMs?: number;
|
|
383
|
-
}
|
|
384
|
-
declare class MemoryClient implements ExtendedMemoryInterface {
|
|
385
|
-
protected baseUrl: string;
|
|
386
|
-
private readonly _authHeaders;
|
|
387
|
-
private readonly _requestTimeoutMs;
|
|
388
|
-
constructor(memoryUrl: string, apiKeyOrOptions?: string | MemoryClientOptions);
|
|
389
|
-
/** Encode a path segment to prevent URL injection */
|
|
390
|
-
private encodePathSegment;
|
|
391
|
-
private authorityHeaders;
|
|
392
|
-
private exactReadAuthority;
|
|
393
|
-
initialize(): Promise<void>;
|
|
394
|
-
store(entry: StoreInput$1, options?: StoreOptions): Promise<MemoryEntry$1>;
|
|
395
|
-
search(params: MemorySearchParams$1, authority?: RequestAuthorityOptions & Pick<TenantScopeOptions, 'tenantId' | 'namespaceId'>): Promise<MemorySearchResult$1>;
|
|
396
|
-
get(id: string, authority?: TenantScopeOptions & RequestAuthorityOptions): Promise<MemoryEntry$1 | null>;
|
|
397
|
-
delete(id: string, authority?: TenantScopeOptions & RequestAuthorityOptions): Promise<boolean>;
|
|
398
|
-
clearSession(sessionId: string): Promise<number>;
|
|
399
|
-
stats(options?: TenantScopeOptions): Promise<MemoryStats$1>;
|
|
400
|
-
insights(options?: TenantScopeOptions & RequestAuthorityOptions): Promise<MemoryInsights$1>;
|
|
401
|
-
/**
|
|
402
|
-
* Fetch the running server's topology snapshot (build variant, declared
|
|
403
|
-
* role, embedding location, active model profile). Round-trips the
|
|
404
|
-
* server's `GET /status` envelope through {@link fetchApi}, surfacing any
|
|
405
|
-
* non-success response as {@link MemoryServerError}. Auth-header
|
|
406
|
-
* forwarding is unchanged from other client methods even though `/status`
|
|
407
|
-
* is server-side public — the server simply ignores credentials on that
|
|
408
|
-
* route.
|
|
409
|
-
*/
|
|
410
|
-
status(): Promise<Topology$1>;
|
|
411
|
-
shutdown(): Promise<void>;
|
|
412
|
-
list(params?: MemoryListParams, authority?: RequestAuthorityOptions & Pick<TenantScopeOptions, 'tenantId' | 'namespaceId'>): Promise<MemoryListResult>;
|
|
413
|
-
/**
|
|
414
|
-
* Native streaming file ingest. Yields typed {@link IngestEvent}s as the
|
|
415
|
-
* server (parsing/storing) and the SDK (enrichment/result) make progress.
|
|
416
|
-
*
|
|
417
|
-
* Wire contract: SDK POSTs with `Accept: application/x-ndjson`; the server
|
|
418
|
-
* MUST respond with NDJSON. There is no JSON fallback — older servers
|
|
419
|
-
* that emit `application/json` for this endpoint are not supported, and
|
|
420
|
-
* the SDK yields a terminal `error` event in that case.
|
|
421
|
-
*
|
|
422
|
-
* After the server's terminal `result`, the SDK runs its own enrichment
|
|
423
|
-
* phase (image-describe → entity-extract → `/enrich` POST), emitting
|
|
424
|
-
* progress + heartbeat events around each step, then yields the single
|
|
425
|
-
* terminal `result` event with the merged SDK + server result.
|
|
426
|
-
*
|
|
427
|
-
* Promise-shaped consumers should iterate the returned AsyncIterable and
|
|
428
|
-
* collect the terminal event; there is no separate `ingestFile()` Promise
|
|
429
|
-
* method by design (one wire format, one SDK method).
|
|
430
|
-
*/
|
|
431
|
-
ingestFileEvents(file: File, options?: IngestFileOptions): AsyncIterable<IngestEvent$1>;
|
|
432
|
-
/**
|
|
433
|
-
* Graph-only re-enrichment for a document whose chunks are already stored
|
|
434
|
-
* and searchable but whose graph build failed. Uploads the original to
|
|
435
|
-
* `/api/memory/graph/enrich/file` (prepare-only — the server performs zero
|
|
436
|
-
* store/delete before the final graph write), runs the SAME enrichment
|
|
437
|
-
* callback engine as {@link ingestFileEvents}, then finalizes into one
|
|
438
|
-
* stable graph anchor keyed by `documentKey`. Repeating the same key
|
|
439
|
-
* replaces the document's graph references idempotently.
|
|
440
|
-
*
|
|
441
|
-
* The terminal `result` is a {@link GraphEnrichResult} event carrying the
|
|
442
|
-
* ACTUAL persisted graph counts; abort and failures yield a terminal
|
|
443
|
-
* `error` event instead (the server retains the pending session for retry).
|
|
444
|
-
*/
|
|
445
|
-
graphEnrichFileEvents(file: File, options: GraphEnrichFileOptions): AsyncIterable<GraphEnrichEvent$1>;
|
|
446
|
-
/**
|
|
447
|
-
* POST a multipart body to an NDJSON streaming endpoint and relay its
|
|
448
|
-
* progress/heartbeat events. Returns the raw terminal `result` record, or
|
|
449
|
-
* null after yielding a terminal error (transport failure, server error
|
|
450
|
-
* event, non-NDJSON response, stream ending without a result). One
|
|
451
|
-
* implementation for both streaming surfaces so the wire protocol cannot
|
|
452
|
-
* fork.
|
|
296
|
+
* Retrieval EFFORT tier (H8 slice 1b) — admits candidates by activation
|
|
297
|
+
* strength BEFORE RRF fusion (like LLM thinking-mode depth): `quick` = the
|
|
298
|
+
* strongest (sharpest top), `medium` = strong+mid, `deep` = everything
|
|
299
|
+
* including cold + superseded + archived rows. **Omitted ⇒ byte-identical to
|
|
300
|
+
* pre-1b behavior** (no activation lookup; all rows admitted, superseded/
|
|
301
|
+
* archived hidden as in 1a). Strength rises only via `Memory.reinforce` (recall
|
|
302
|
+
* reinforces); idle alone never revives. See `docs/H8-MEMORY-MODEL-DESIGN.md`.
|
|
453
303
|
*/
|
|
454
|
-
|
|
304
|
+
effort?: 'quick' | 'medium' | 'deep';
|
|
305
|
+
/** Maximum sensitivity level to include in results. Entries above this level are excluded. */
|
|
306
|
+
maxSensitivity?: SensitivityLevel;
|
|
307
|
+
/** Tenant ID for multi-tenant isolation. */
|
|
308
|
+
tenantId?: string;
|
|
309
|
+
/** User ID within the tenant. */
|
|
310
|
+
userId?: string;
|
|
311
|
+
/** Team/group ID within the tenant. */
|
|
312
|
+
teamId?: string;
|
|
455
313
|
/**
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
* callbacks. The callback work itself lives in
|
|
460
|
-
* {@link runEnrichmentCallbacks} — shared with the graph-only surface.
|
|
314
|
+
* Exact namespace requested by a trusted transport boundary. `Memory.search`
|
|
315
|
+
* validates it against the calling principal's AuthzPlan and compiles it to
|
|
316
|
+
* a singleton prefilter. Exact scope excludes legacy NULL rows.
|
|
461
317
|
*/
|
|
462
|
-
|
|
318
|
+
namespaceId?: string;
|
|
463
319
|
/**
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
*
|
|
469
|
-
* purpose-specific wrappers translate that into their terminal error.
|
|
320
|
+
* AuthzPlan-derived visibility list. Populated internally by `Memory.search`
|
|
321
|
+
* after computing the plan from the calling principal — callers should
|
|
322
|
+
* NOT set this directly. Empty array means "no granted namespaces" (only
|
|
323
|
+
* legacy NULL-namespace entries are visible). `undefined` skips the
|
|
324
|
+
* filter (single-tenant / pre-ReBAC compat).
|
|
470
325
|
*
|
|
471
|
-
*
|
|
472
|
-
* documentKey-aware full ingest may replace a prior graph only from a
|
|
473
|
-
* complete input set (no truncated text windows or undescribed images). A
|
|
474
|
-
* complete extractor result containing zero entities remains a valid clear.
|
|
475
|
-
*/
|
|
476
|
-
private runEnrichmentCallbacks;
|
|
477
|
-
/**
|
|
478
|
-
* Race a Promise against a periodic heartbeat tick. Yields a heartbeat
|
|
479
|
-
* IngestEvent every {@link INGEST_EVENT_HEARTBEAT_MS} until the promise
|
|
480
|
-
* settles, then returns the resolved value (or rethrows). Lets callers
|
|
481
|
-
* keep upstream sockets alive through long LLM/HTTP work without
|
|
482
|
-
* coupling the heartbeat cadence to the work itself.
|
|
326
|
+
* Callers must not set this directly; use `namespaceId` for exact scope.
|
|
483
327
|
*/
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
private ingestErrorEvent;
|
|
328
|
+
namespaceIds?: string[];
|
|
329
|
+
/** Strict namespace equality compiled internally from `namespaceId`. */
|
|
330
|
+
exactNamespaceId?: string;
|
|
488
331
|
/**
|
|
489
|
-
*
|
|
490
|
-
*
|
|
332
|
+
* AuthzPlan-derived list of strict-mode namespaces in the caller's
|
|
333
|
+
* tenant the principal CANNOT see (v0.17.0). Graph traversal MUST
|
|
334
|
+
* drop edges whose `namespace_id` matches the supplied set even when
|
|
335
|
+
* the surrounding KG node is otherwise reachable. Populated
|
|
336
|
+
* internally by `Memory.search` from `AuthzPlan.forbiddenStrict
|
|
337
|
+
* NamespaceIds` — callers should NOT set this directly.
|
|
491
338
|
*/
|
|
492
|
-
|
|
339
|
+
forbiddenStrictNamespaceIds?: string[];
|
|
340
|
+
}
|
|
341
|
+
interface MemorySearchResult {
|
|
342
|
+
entries: MemoryEntry[];
|
|
343
|
+
totalCount: number;
|
|
344
|
+
strategy: RAGStrategy;
|
|
345
|
+
/** Visible graph slice that supported the returned entries, when graph traversal contributed. */
|
|
346
|
+
graph?: GraphTraversalResult;
|
|
493
347
|
/**
|
|
494
|
-
*
|
|
495
|
-
*
|
|
348
|
+
* Optional scored entries for ranked results. `score` is the fused RANK score
|
|
349
|
+
* (RRF + recency/importance/access priors) — good for ordering, NOT a relevance
|
|
350
|
+
* magnitude. `vectorSimilarity` is the raw dense query-similarity (LanceDB
|
|
351
|
+
* transformed-L2, 1/(1+distance)); null when the entry has no dense signal
|
|
352
|
+
* (FTS/graph-only). Surface vectorSimilarity, not score, as a "% match".
|
|
496
353
|
*/
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
limit?: number;
|
|
502
|
-
}): Promise<MemoryEntry$1[]>;
|
|
503
|
-
graphNodes(): Promise<GraphNode$1[]>;
|
|
504
|
-
graphEdges(): Promise<{
|
|
505
|
-
stats: {
|
|
506
|
-
nodeCount: number;
|
|
507
|
-
edgeCount: number;
|
|
508
|
-
rawNodeCount?: number;
|
|
509
|
-
rawEdgeCount?: number;
|
|
510
|
-
};
|
|
354
|
+
scoredEntries?: Array<{
|
|
355
|
+
entry: MemoryEntry;
|
|
356
|
+
score: number;
|
|
357
|
+
vectorSimilarity?: number | null;
|
|
511
358
|
}>;
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
dryRun?: boolean;
|
|
529
|
-
}): Promise<{
|
|
530
|
-
from: string;
|
|
531
|
-
to: string;
|
|
532
|
-
updated: number;
|
|
533
|
-
dryRun: boolean;
|
|
534
|
-
}>;
|
|
535
|
-
queryAsOf(asOfDate: string, filters?: TemporalQueryFilters, authority?: TenantScopeOptions): Promise<MemoryEntry$1[]>;
|
|
536
|
-
lineage(params: LineageParams$1, authority?: RequestAuthorityOptions): Promise<LineageResult$1>;
|
|
537
|
-
reinforce(params: ReinforceParams$1, authority?: RequestAuthorityOptions): Promise<ReinforceResult$1>;
|
|
538
|
-
log(filters?: MemoryLogFilters): Promise<MemoryEntry$1[]>;
|
|
539
|
-
queryByEventTime(startTime: string, endTime: string, filters?: TemporalQueryFilters): Promise<MemoryEntry$1[]>;
|
|
540
|
-
summarizeEntity(name: string): Promise<MemoryEntry$1>;
|
|
541
|
-
getEntitySynthesis(name: string): Promise<MemoryEntry$1 | null>;
|
|
542
|
-
/**
|
|
543
|
-
* v0.26 user-profile snapshot — upsert. The server derives `userId`
|
|
544
|
-
* from `X-User-Id` (caller wires it via `defaultHeaders` on the
|
|
545
|
-
* client constructor or per-request middleware); the body cannot
|
|
546
|
-
* override it. See spec §Requirements 10.
|
|
547
|
-
*/
|
|
548
|
-
upsertUserProfile(input: {
|
|
549
|
-
namespaceId: string;
|
|
550
|
-
content: string;
|
|
551
|
-
}): Promise<{
|
|
552
|
-
updatedAt: string;
|
|
553
|
-
contentSize: number;
|
|
554
|
-
}>;
|
|
555
|
-
/**
|
|
556
|
-
* v0.26 user-profile snapshot — fetch by namespace. Returns `null` on
|
|
557
|
-
* HTTP 404 (`isNotFound`), rethrows any other non-2xx as
|
|
558
|
-
* `MemoryServerError`. Mirrors `get()`'s 404-to-null pattern so callers
|
|
559
|
-
* can branch on "no profile yet" without inspecting status codes.
|
|
560
|
-
*/
|
|
561
|
-
getUserProfile(namespaceId: string): Promise<{
|
|
562
|
-
content: string;
|
|
563
|
-
updatedAt: string;
|
|
564
|
-
contentSize: number;
|
|
565
|
-
} | null>;
|
|
566
|
-
/**
|
|
567
|
-
* v0.28 correction-memory — record an explicit correction. POSTs to
|
|
568
|
-
* `/api/memory/corrections`; tenant is header-derived (server-side), so
|
|
569
|
-
* the body carries only the correction fields. Returns `{ id, createdAt }`.
|
|
570
|
-
*/
|
|
571
|
-
recordCorrection(input: {
|
|
572
|
-
/** Omit in single-tenant deployments — corrections are stored namespace-free. */
|
|
573
|
-
namespaceId?: string;
|
|
574
|
-
whatWasWrong: string;
|
|
575
|
-
whatToDoInstead: string;
|
|
576
|
-
appliesWhen: string;
|
|
577
|
-
project?: string;
|
|
578
|
-
taskShape?: string;
|
|
579
|
-
}): Promise<{
|
|
580
|
-
id: string;
|
|
581
|
-
createdAt: string;
|
|
582
|
-
}>;
|
|
583
|
-
/**
|
|
584
|
-
* v0.28 correction-memory — fetch the corrections applicable to a task
|
|
585
|
-
* shape. GETs `/api/memory/corrections`; returns `[]` when none have
|
|
586
|
-
* positive overlap. pyx never auto-prepends — the agent owns inclusion.
|
|
587
|
-
*/
|
|
588
|
-
fetchApplicableCorrections(input: {
|
|
589
|
-
/** Omit in single-tenant deployments — reads the namespace-free scope. */
|
|
590
|
-
namespaceId?: string;
|
|
591
|
-
taskShape: string;
|
|
592
|
-
project?: string;
|
|
593
|
-
limit?: number;
|
|
594
|
-
}): Promise<CorrectionRecord$1[]>;
|
|
595
|
-
/**
|
|
596
|
-
* H26 B-d — deterministic prospective due-scan: entries with
|
|
597
|
-
* `eventTime ∈ [from, from+windowDays]` (inclusive), eventTime ascending,
|
|
598
|
-
* no relevance ranking. `GET /api/memory/due`.
|
|
599
|
-
*/
|
|
600
|
-
dueScan(input: {
|
|
601
|
-
windowDays: number;
|
|
602
|
-
from?: string;
|
|
603
|
-
/** Omit in single-tenant deployments. */
|
|
604
|
-
namespaceId?: string;
|
|
605
|
-
limit?: number;
|
|
606
|
-
}): Promise<MemoryEntry$1[]>;
|
|
607
|
-
protected fetchApi<T>(path: string, options?: RequestInit): Promise<T>;
|
|
608
|
-
/**
|
|
609
|
-
* Map fetch-layer rejections into a typed `MemoryServerError` so callers
|
|
610
|
-
* can react uniformly. AbortSignal.timeout fires a `TimeoutError`; the
|
|
611
|
-
* caller's signal generally fires an `AbortError`. Anything else (DNS,
|
|
612
|
-
* TCP reset, TLS) becomes a wrapped error with status 0.
|
|
613
|
-
*/
|
|
614
|
-
private translateFetchError;
|
|
615
|
-
/** Parse and validate a JSON API response, throwing MemoryServerError on any failure. */
|
|
616
|
-
private parseApiResponse;
|
|
359
|
+
/** Confidence assessment for abstention. Present when search produces scored entries. */
|
|
360
|
+
confidence?: {
|
|
361
|
+
/** Overall confidence 0.0–1.0. */
|
|
362
|
+
confidence: number;
|
|
363
|
+
/** Whether the system recommends abstaining (confidence below threshold). */
|
|
364
|
+
shouldAbstain: boolean;
|
|
365
|
+
/** Raw signals used to compute confidence. */
|
|
366
|
+
signals: {
|
|
367
|
+
topScore: number;
|
|
368
|
+
scoreGap: number;
|
|
369
|
+
scoreStdDev: number;
|
|
370
|
+
resultCount: number;
|
|
371
|
+
aboveThresholdRatio: number;
|
|
372
|
+
scoreSeparation: number;
|
|
373
|
+
};
|
|
374
|
+
};
|
|
617
375
|
}
|
|
618
|
-
|
|
619
|
-
interface
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
376
|
+
/** One version in a fact's history, as returned by {@link LineageResult}. */
|
|
377
|
+
interface LineageVersion {
|
|
378
|
+
entryId: string;
|
|
379
|
+
/** The entry content carrying this version's value. */
|
|
380
|
+
value: string;
|
|
381
|
+
eventTime?: string;
|
|
382
|
+
ingestTime?: string;
|
|
383
|
+
status: 'active' | 'superseded' | 'archived';
|
|
384
|
+
/** Set when this version was superseded by a newer entry. */
|
|
385
|
+
supersededByEntryId?: string;
|
|
625
386
|
}
|
|
626
|
-
|
|
627
|
-
declare const DEFAULTS: {
|
|
628
|
-
readonly DATA_DIR: "./data";
|
|
629
|
-
readonly VECTOR_PROVIDER: "lancedb";
|
|
630
|
-
readonly MEMORY_SERVER_PORT: 7822;
|
|
631
|
-
};
|
|
632
|
-
declare const TAXONOMY_MAX_CATEGORIES = 10;
|
|
633
|
-
declare const TAXONOMY_MAX_TOP_ENTITIES = 15;
|
|
634
|
-
declare const TAXONOMY_MAX_SAMPLE_TOPICS = 8;
|
|
635
|
-
declare const TAXONOMY_MAX_PROJECTS = 8;
|
|
636
|
-
declare const MEMORY_PROJECT_LABEL_MAX_CHARS = 80;
|
|
637
|
-
|
|
638
|
-
/** ISO 8601 timestamp string */
|
|
639
|
-
type Timestamp = string;
|
|
640
|
-
/** Unique agent identifier */
|
|
641
|
-
type AgentId = string;
|
|
642
|
-
|
|
643
387
|
/**
|
|
644
|
-
*
|
|
645
|
-
*
|
|
646
|
-
*
|
|
647
|
-
*
|
|
648
|
-
* before any retrieval source fans out.
|
|
649
|
-
*
|
|
650
|
-
* Identity comes from authenticated request context (X-Tenant-Id / auth token
|
|
651
|
-
* claims), never from request bodies or multipart form fields. The legacy
|
|
652
|
-
* `userId` / `teamId` / `agentId` columns on MemoryEntry remain for audit and
|
|
653
|
-
* legacy filters but MUST NOT drive authorization decisions — they are
|
|
654
|
-
* collision-prone aliases (a service principal sharing an ID with a human
|
|
655
|
-
* user has no protection against confused-deputy attacks).
|
|
656
|
-
*
|
|
657
|
-
* Sensitivity / clearance is intentionally NOT on this object. It is a
|
|
658
|
-
* MAC-style classification, orthogonal to RBAC, and continues to be carried
|
|
659
|
-
* via the `X-Caller-Access-Level` header → `MemorySearchParams.maxSensitivity`.
|
|
660
|
-
* Conflating the two couples future changes (e.g. per-namespace classification
|
|
661
|
-
* rules) to identity propagation.
|
|
388
|
+
* Query for the evolution of a fact (H8 `Memory.lineage`). Provide either a
|
|
389
|
+
* `subject` (+ optional `relation`) for graph-backed subject/relation lineage,
|
|
390
|
+
* OR an `entryId` to walk the `supersededBy` chain (the only mode available
|
|
391
|
+
* without a graph store).
|
|
662
392
|
*/
|
|
663
|
-
interface
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
/**
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
* - `user`: human end user
|
|
682
|
-
* - `agent`: AI runtime acting on a user's behalf or autonomously
|
|
683
|
-
* - `service`: non-AI internal system (cron, ETL, admin tooling)
|
|
684
|
-
*/
|
|
685
|
-
kind: 'user' | 'agent' | 'service';
|
|
393
|
+
interface LineageParams {
|
|
394
|
+
subject?: string;
|
|
395
|
+
relation?: string;
|
|
396
|
+
entryId?: string;
|
|
397
|
+
/** Current version as of this time (newest version with eventTime ≤ asOf). */
|
|
398
|
+
asOf?: string;
|
|
399
|
+
eventTimeRange?: [string, string];
|
|
400
|
+
/** Return only versions strictly older than the version holding this value. */
|
|
401
|
+
beforeValue?: string;
|
|
402
|
+
limit?: number;
|
|
403
|
+
}
|
|
404
|
+
interface LineageResult {
|
|
405
|
+
subject?: string;
|
|
406
|
+
relation?: string;
|
|
407
|
+
/** Event-time ascending (oldest → newest). */
|
|
408
|
+
versions: LineageVersion[];
|
|
409
|
+
/** Which path answered — honest provenance (graph conflict-group vs supersededBy chain). */
|
|
410
|
+
source: 'graph' | 'chain';
|
|
686
411
|
}
|
|
687
|
-
/** Sentinel tenant ID used in single-tenant deployments. */
|
|
688
|
-
declare const SINGLE_TENANT_ID = "_single";
|
|
689
|
-
|
|
690
|
-
declare const MemoryType: {
|
|
691
|
-
readonly SHORT_TERM: "short-term";
|
|
692
|
-
readonly LONG_TERM: "long-term";
|
|
693
|
-
readonly WORKING: "working";
|
|
694
|
-
readonly EPISODIC: "episodic";
|
|
695
|
-
readonly SUMMARY: "summary";
|
|
696
|
-
};
|
|
697
|
-
type MemoryType = (typeof MemoryType)[keyof typeof MemoryType];
|
|
698
|
-
declare const SensitivityLevel: {
|
|
699
|
-
readonly PUBLIC: "public";
|
|
700
|
-
readonly INTERNAL: "internal";
|
|
701
|
-
readonly SECRET: "secret";
|
|
702
|
-
};
|
|
703
|
-
type SensitivityLevel = (typeof SensitivityLevel)[keyof typeof SensitivityLevel];
|
|
704
|
-
declare const RAGStrategy: {
|
|
705
|
-
readonly NAIVE: "naive";
|
|
706
|
-
readonly GRAPH: "graph";
|
|
707
|
-
readonly HYBRID: "hybrid";
|
|
708
|
-
};
|
|
709
|
-
type RAGStrategy = (typeof RAGStrategy)[keyof typeof RAGStrategy];
|
|
710
412
|
/**
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
714
|
-
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
717
|
-
* v0.26: `agentic` removed (Codex pair: silent-catch in agentic.ts
|
|
718
|
-
* violated Production-ready; behavior subsumed by HybridRAGEngine).
|
|
413
|
+
* Explicit recall-usefulness signal for {@link MemorySearchParams} `reinforce`.
|
|
414
|
+
* `context_included` = surfaced into the working context (small η); `cited` =
|
|
415
|
+
* the agent actually used it in its answer (medium η); `explicit_positive` =
|
|
416
|
+
* user/agent marked it useful (large η). Mere top-k return is NOT a signal
|
|
417
|
+
* (determinism + "returned ≠ used") — only an explicit `reinforce()` call moves
|
|
418
|
+
* strength.
|
|
719
419
|
*/
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
420
|
+
type ReinforceSignal = 'context_included' | 'cited' | 'explicit_positive';
|
|
421
|
+
interface ReinforceParams {
|
|
422
|
+
entryIds: string[];
|
|
423
|
+
signal: ReinforceSignal;
|
|
424
|
+
/** When the recall happened — epoch-ms, or full ISO-8601 WITH timezone. Date-only / tz-free is rejected. Defaults to the activation clock. */
|
|
425
|
+
at?: string | number;
|
|
426
|
+
}
|
|
427
|
+
interface ReinforceResult {
|
|
428
|
+
/** Per-entry post-reinforce activation. Entries absent from the store are omitted. */
|
|
429
|
+
updated: Array<{
|
|
430
|
+
entryId: string;
|
|
431
|
+
strength: number;
|
|
432
|
+
tier: 'quick' | 'medium' | 'deep';
|
|
433
|
+
}>;
|
|
434
|
+
}
|
|
435
|
+
interface SourceEvidence {
|
|
436
|
+
/** Memory entry that produced this graph fact. */
|
|
437
|
+
memoryEntryId: string;
|
|
438
|
+
/** Data tenant of the source entry. `null` = single-tenant / legacy data. */
|
|
439
|
+
tenantId?: string | null;
|
|
440
|
+
/** Namespace of the source memory entry. `null` = legacy / tenant-root. */
|
|
441
|
+
namespaceId?: string | null;
|
|
442
|
+
/** Optional source identifier copied from the memory entry or caller. */
|
|
443
|
+
source?: string;
|
|
444
|
+
/** Optional content hash copied from the memory entry or caller. */
|
|
445
|
+
contentHash?: string;
|
|
446
|
+
/** Optional short text evidence for the graph fact. */
|
|
447
|
+
snippet?: string;
|
|
448
|
+
/** When this evidence was recorded. */
|
|
449
|
+
createdAt?: Timestamp;
|
|
743
450
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
451
|
+
declare const StoreTarget: {
|
|
452
|
+
readonly SQLITE: "sqlite";
|
|
453
|
+
readonly VECTOR: "vector";
|
|
454
|
+
readonly GRAPH: "graph";
|
|
455
|
+
};
|
|
456
|
+
type StoreTarget = (typeof StoreTarget)[keyof typeof StoreTarget];
|
|
457
|
+
/** Agent-provided entity for graph storage. */
|
|
458
|
+
interface IngestEntity {
|
|
459
|
+
/** Entity name (e.g., "Alice", "TypeScript"). */
|
|
460
|
+
name: string;
|
|
461
|
+
/** Entity type — freeform, agent decides (e.g., "PERSON", "TOOL"). */
|
|
462
|
+
type: string;
|
|
463
|
+
/** Stable canonical identifier. Defaults to a deterministic name+type id. */
|
|
464
|
+
canonicalId?: string;
|
|
465
|
+
/** Source evidence for this graph node. Defaults to the containing memory entry. */
|
|
466
|
+
sourceEvidence?: SourceEvidence[];
|
|
467
|
+
/** Optional properties to attach to the graph node. */
|
|
468
|
+
properties?: Record<string, unknown>;
|
|
469
|
+
}
|
|
470
|
+
/** Agent-provided relationship for graph storage. */
|
|
471
|
+
interface IngestRelationship {
|
|
472
|
+
/** Source entity name (must match an entity in the entities array). */
|
|
751
473
|
source: string;
|
|
474
|
+
/** Target entity name (must match an entity in the entities array). */
|
|
752
475
|
target: string;
|
|
476
|
+
/** Relationship type — freeform, agent decides (e.g., "WORKS_AT", "USES"). */
|
|
753
477
|
type: string;
|
|
478
|
+
/** Source evidence for this graph edge. Defaults to the containing memory entry. */
|
|
479
|
+
sourceEvidence?: SourceEvidence[];
|
|
480
|
+
/** Optional properties to attach to the graph edge. */
|
|
481
|
+
properties?: Record<string, unknown>;
|
|
754
482
|
}
|
|
755
|
-
|
|
756
|
-
|
|
483
|
+
/**
|
|
484
|
+
* How `Memory.store()` should react when the graph write fails.
|
|
485
|
+
* - `throw` (default, since v0.13.0): propagate the failure so the caller
|
|
486
|
+
* knows the graph is incomplete. Honest contract: a graph write either
|
|
487
|
+
* commits or fails loudly. Silent partial-loss was the v0.12.2 bug that
|
|
488
|
+
* masked 91/92 dropped entities.
|
|
489
|
+
* - `best-effort`: swallow the error and log a warning; the entry is still
|
|
490
|
+
* considered ingested in SQLite/vector. Use only when you genuinely don't
|
|
491
|
+
* need the graph slice and a transient neo4j blip shouldn't fail ingest.
|
|
492
|
+
*/
|
|
493
|
+
type GraphFailureMode = 'throw' | 'best-effort';
|
|
494
|
+
/** Store input: what the agent sends to Memory.store(). */
|
|
495
|
+
type StoreInput = Omit<MemoryEntry, 'id' | 'createdAt'> & {
|
|
496
|
+
id?: string;
|
|
497
|
+
createdAt?: string;
|
|
498
|
+
/** Storage targets. Default: ["sqlite", "vector"]. */
|
|
499
|
+
targets?: StoreTarget[];
|
|
500
|
+
/** Agent-provided entities for graph storage. */
|
|
501
|
+
entities?: IngestEntity[];
|
|
502
|
+
/** Agent-provided relationships for graph storage. */
|
|
503
|
+
relationships?: IngestRelationship[];
|
|
504
|
+
/** Override graph entity extraction for this store call. */
|
|
505
|
+
extractEntities?: boolean;
|
|
506
|
+
/** Graph-failure handling. Default: "throw" (loud) — see GraphFailureMode. */
|
|
507
|
+
graphFailureMode?: GraphFailureMode;
|
|
508
|
+
};
|
|
509
|
+
/**
|
|
510
|
+
* `Memory.expand()` input (eng-pull FD2): `baseEntryIds` is the caller's
|
|
511
|
+
* declared context in ITS order (dedupe set only; ids need not resolve);
|
|
512
|
+
* `anchorEntryIds` ⊆ base, in the caller's priority order.
|
|
513
|
+
*/
|
|
514
|
+
type ExpandParams = {
|
|
515
|
+
baseEntryIds: string[];
|
|
516
|
+
anchorEntryIds: string[];
|
|
517
|
+
};
|
|
518
|
+
type ExpandAnchorStatus = {
|
|
757
519
|
id: string;
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
520
|
+
status: 'expanded';
|
|
521
|
+
sessionId: string;
|
|
522
|
+
sessionOrdinal: number;
|
|
523
|
+
} | {
|
|
524
|
+
id: string;
|
|
525
|
+
status: 'not_expandable';
|
|
526
|
+
reason: 'not_found' | 'not_active' | 'no_ordinal';
|
|
527
|
+
};
|
|
528
|
+
/** `added` = full entries in admission order (±1 then ±2 per anchor, anchors in request order). */
|
|
529
|
+
interface ExpandResult {
|
|
530
|
+
added: MemoryEntry[];
|
|
531
|
+
anchors: ExpandAnchorStatus[];
|
|
532
|
+
}
|
|
533
|
+
interface MemoryIngestRequest {
|
|
534
|
+
content?: string;
|
|
535
|
+
type?: MemoryType;
|
|
536
|
+
metadata?: Record<string, unknown>;
|
|
537
|
+
agentId?: string;
|
|
761
538
|
sessionId?: string;
|
|
762
|
-
|
|
763
|
-
/**
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
539
|
+
sessionOrdinal?: number;
|
|
540
|
+
/** Storage targets. Default: ["sqlite", "vector"]. */
|
|
541
|
+
targets?: StoreTarget[];
|
|
542
|
+
/** Agent-provided entities for graph storage. */
|
|
543
|
+
entities?: IngestEntity[];
|
|
544
|
+
/** Agent-provided relationships for graph storage. */
|
|
545
|
+
relationships?: IngestRelationship[];
|
|
546
|
+
/** Override graph entity extraction for this ingest request. */
|
|
547
|
+
extractEntities?: boolean;
|
|
548
|
+
/** Graph-failure handling. Default: "throw" (loud) — see GraphFailureMode. */
|
|
549
|
+
graphFailureMode?: GraphFailureMode;
|
|
768
550
|
/** Importance score (1-10). */
|
|
769
551
|
importance?: number;
|
|
770
|
-
/**
|
|
771
|
-
accessCount?: number;
|
|
772
|
-
/** ISO timestamp of last access via search. */
|
|
773
|
-
lastAccessed?: string;
|
|
774
|
-
/** Parent entry ID for hierarchical storage (e.g., doc → section → chunk). */
|
|
775
|
-
parentId?: string;
|
|
776
|
-
/** Source identifier (e.g., filename, URL, session). */
|
|
552
|
+
/** Source identifier (e.g., filename, URL). */
|
|
777
553
|
source?: string;
|
|
778
|
-
/** When the event
|
|
554
|
+
/** When the event occurred (ISO timestamp). */
|
|
779
555
|
eventTime?: string;
|
|
780
|
-
/**
|
|
781
|
-
|
|
782
|
-
/**
|
|
783
|
-
|
|
784
|
-
/**
|
|
785
|
-
|
|
786
|
-
/** Number of graph entities written by this store call. Present on store responses. */
|
|
787
|
-
graphEntitiesWritten?: number;
|
|
788
|
-
/** Number of graph relationships written by this store call. Present on store responses. */
|
|
789
|
-
graphRelationshipsWritten?: number;
|
|
790
|
-
/** Count of caller relationships dropped because an endpoint name did not match any entity in the call. Present (and >0) only when edges were dropped. */
|
|
791
|
-
graphRelationshipsDropped?: number;
|
|
792
|
-
/** Up to 20 of the dropped relationships (source/target/type), so the agent can re-send them. Present only when edges were dropped. */
|
|
793
|
-
graphRelationshipsDroppedDetail?: DroppedGraphRelationship[];
|
|
794
|
-
/** Graph extraction/enrichment outcome for this store call. Present on graph-targeted store responses. */
|
|
795
|
-
graphEnrichment?: GraphEnrichment;
|
|
796
|
-
/** Store response vector outcome. Pending means SQLite is durable and vector indexing is eventually consistent. */
|
|
797
|
-
vectorStatus?: VectorStatus;
|
|
798
|
-
/** Tenant ID for multi-tenant isolation. */
|
|
799
|
-
tenantId?: string;
|
|
800
|
-
/** User ID within the tenant. */
|
|
801
|
-
userId?: string;
|
|
802
|
-
/** Team/group ID within the tenant. */
|
|
803
|
-
teamId?: string;
|
|
804
|
-
/**
|
|
805
|
-
* Namespace ID — the primary protected resource for ReBAC authorization.
|
|
806
|
-
* `undefined` (NULL on the row) means the entry lives in the legacy
|
|
807
|
-
* "tenant-root" bucket and is visible to anyone with tenant access (the
|
|
808
|
-
* pre-ReBAC posture). Setting `namespaceId` opts the entry into AuthzPlan-
|
|
809
|
-
* based filtering, where visibility is computed from `authz_tuples` for
|
|
810
|
-
* the calling principal.
|
|
811
|
-
*/
|
|
812
|
-
namespaceId?: string;
|
|
813
|
-
/**
|
|
814
|
-
* When true, consolidation leaves this entry alone — it is never archived by
|
|
815
|
-
* decay and never merged (nor merged-into) by semantic deduplication. Use for
|
|
816
|
-
* stable anchor entries whose ID is referenced by external systems (e.g. a
|
|
817
|
-
* file-catalog row pointed at by another service's foreign key).
|
|
818
|
-
*/
|
|
819
|
-
pinned?: boolean;
|
|
820
|
-
/**
|
|
821
|
-
* Lifecycle status (H8). Optional on write (absent means `'active'`), but
|
|
822
|
-
* every entry READ back from the store carries it explicitly — a caller can
|
|
823
|
-
* compare `entry.status === 'active'` without special-casing an absent field.
|
|
824
|
-
* `'active'` is a normal retrievable entry. `'superseded'` means a newer near-duplicate
|
|
825
|
-
* UPDATE replaced this one during consolidation. `'archived'` (1b) means decay
|
|
826
|
-
* retired it (no successor) — kept, strength 0, `deep`-tier only. All three
|
|
827
|
-
* are kept (history / lineage / deep recall) but `superseded`/`archived` are
|
|
828
|
-
* excluded from default/quick/medium search. Only `forget()` and exact-byte-
|
|
829
|
-
* duplicate collapse hard-delete. See `docs/H8-MEMORY-MODEL-DESIGN.md`.
|
|
830
|
-
*/
|
|
831
|
-
status?: 'active' | 'superseded' | 'archived';
|
|
832
|
-
/**
|
|
833
|
-
* When `status==='superseded'`, the id of the newer entry that replaced this
|
|
834
|
-
* one — the backward link used by `Memory.lineage()` chain traversal. Cleared
|
|
835
|
-
* to NULL (never resurrected to active) if the successor is later forgotten.
|
|
836
|
-
*/
|
|
837
|
-
supersededByEntryId?: string;
|
|
838
|
-
/**
|
|
839
|
-
* @internal Hosted data-plane only. SHA-256 of the canonical caller store
|
|
840
|
-
* payload (server-stamped timestamps excluded), persisted for caller-id
|
|
841
|
-
* stores so a re-send of the same `metadata.dbRef.revision` can be
|
|
842
|
-
* classified as an idempotent no-op (digest match) or a
|
|
843
|
-
* `revision_reuse_conflict` (digest mismatch). Graph entities/relationships
|
|
844
|
-
* are part of the payload but not of the row, so the digest cannot be
|
|
845
|
-
* recomputed from stored state.
|
|
846
|
-
*/
|
|
847
|
-
payloadDigest?: string;
|
|
848
|
-
}
|
|
849
|
-
interface MemorySearchParams {
|
|
850
|
-
query: string;
|
|
851
|
-
type?: MemoryType;
|
|
852
|
-
agentId?: AgentId;
|
|
853
|
-
/** Optional caller session identifier used for in-process hygiene telemetry. */
|
|
854
|
-
sessionId?: string;
|
|
855
|
-
limit?: number;
|
|
856
|
-
strategy?: RAGStrategy;
|
|
857
|
-
/** Filter results to entries whose eventTime falls within [start, end] (ISO 8601). */
|
|
858
|
-
eventTimeRange?: [string, string];
|
|
859
|
-
/** Filter results to entries ingested before this cutoff (ISO 8601). Falls back to createdAt when ingestTime is null. */
|
|
860
|
-
asOf?: string;
|
|
861
|
-
/**
|
|
862
|
-
* Soft recency ANCHOR (ISO 8601) — never a filter. Candidates are ranked by
|
|
863
|
-
* proximity to this time instead of now, and conflicting assertions
|
|
864
|
-
* re-order around it. Resolving relative-time expressions ("two months
|
|
865
|
-
* ago", "3년 전") to an absolute timestamp is the CALLER's side of the
|
|
866
|
-
* agentic contract — language understanding never enters the engine. Wins
|
|
867
|
-
* over the query-text year parse (hybrid strategy).
|
|
868
|
-
*/
|
|
869
|
-
anchorTime?: string;
|
|
870
|
-
/**
|
|
871
|
-
* The category the user is asking to count/list (e.g. "fitness classes",
|
|
872
|
-
* "운동 수업", any language). Presence signals enumeration intent and supplies
|
|
873
|
-
* the category for graph resolution; the caller (which understands the user's
|
|
874
|
-
* language) sets it. When omitted, pyx falls back to a deterministic EN/KO
|
|
875
|
-
* marker detector.
|
|
876
|
-
*/
|
|
877
|
-
enumerationConcept?: string;
|
|
878
|
-
/** Confidence threshold below which the system recommends abstention (0.0–1.0). Default: 0.3. */
|
|
879
|
-
abstentionThreshold?: number;
|
|
880
|
-
/**
|
|
881
|
-
* Rerank with the cross-encoder before final truncation (hybrid strategy
|
|
882
|
-
* only). The pipeline retrieves and dedups a deeper candidate pool (≥50),
|
|
883
|
-
* scores it through the cross-encoder, then truncates to `limit` —
|
|
884
|
-
* reranking after truncation cannot change top-`limit` set membership.
|
|
885
|
-
* Forwarded by `MemoryClient.search` and the HTTP route; core enforces
|
|
886
|
-
* hybrid-only usage.
|
|
887
|
-
*/
|
|
888
|
-
enableRerank?: boolean;
|
|
889
|
-
/**
|
|
890
|
-
* Iterative multi-hop candidate generation (hybrid strategy only). After the
|
|
891
|
-
* first retrieval pass, non-oracle bridge entities are mined from the top
|
|
892
|
-
* seed passages, a second dense+lexical pass is seeded by those bridges, and
|
|
893
|
-
* both passes' ranked lists are fused into a single RRF before scoring and
|
|
894
|
-
* (optional) rerank-then-truncate. Grows the candidate pool to surface
|
|
895
|
-
* later-hop passages the single-pass query misses. Deterministic: no
|
|
896
|
-
* query-time LLM, fixed bridge order. Default off keeps the pipeline
|
|
897
|
-
* byte-identical. EMBEDDED ONLY: `MemoryClient.search` rejects it (the HTTP
|
|
898
|
-
* API does not forward it).
|
|
899
|
-
*/
|
|
900
|
-
enableMultiHop?: boolean;
|
|
901
|
-
/**
|
|
902
|
-
* Explicit bridge entities for the second multi-hop pass, bypassing mining.
|
|
903
|
-
* EVAL ONLY — used by the benchmark oracle-ceiling probe to isolate fusion
|
|
904
|
-
* capacity from mining quality; never set on a production path. Ignored
|
|
905
|
-
* unless `enableMultiHop` is also set.
|
|
906
|
-
*/
|
|
907
|
-
multiHopBridges?: string[];
|
|
908
|
-
/**
|
|
909
|
-
* Set false for a read-only search that does NOT bump access counts /
|
|
910
|
-
* lastAccessed on returned entries. Access feeds ranking (WEIGHT_ACCESS and
|
|
911
|
-
* the no-eventTime recency fallback), so a measurement that searches the
|
|
912
|
-
* store mutates what it measures — repeated benchmark runs over a persisted
|
|
913
|
-
* index drift. Default true (access tracking is the product's usage signal).
|
|
914
|
-
*/
|
|
915
|
-
trackAccess?: boolean;
|
|
916
|
-
/**
|
|
917
|
-
* Retrieval EFFORT tier (H8 slice 1b) — admits candidates by activation
|
|
918
|
-
* strength BEFORE RRF fusion (like LLM thinking-mode depth): `quick` = the
|
|
919
|
-
* strongest (sharpest top), `medium` = strong+mid, `deep` = everything
|
|
920
|
-
* including cold + superseded + archived rows. **Omitted ⇒ byte-identical to
|
|
921
|
-
* pre-1b behavior** (no activation lookup; all rows admitted, superseded/
|
|
922
|
-
* archived hidden as in 1a). Strength rises only via `Memory.reinforce` (recall
|
|
923
|
-
* reinforces); idle alone never revives. See `docs/H8-MEMORY-MODEL-DESIGN.md`.
|
|
924
|
-
*/
|
|
925
|
-
effort?: 'quick' | 'medium' | 'deep';
|
|
926
|
-
/** Maximum sensitivity level to include in results. Entries above this level are excluded. */
|
|
927
|
-
maxSensitivity?: SensitivityLevel;
|
|
556
|
+
/** Optional deterministic ID for the entry (agent-provided). */
|
|
557
|
+
id?: string;
|
|
558
|
+
/** Parent entry ID for hierarchical storage (e.g., doc → section → chunk). */
|
|
559
|
+
parentId?: string;
|
|
560
|
+
/** When this entry was ingested (ISO timestamp). Default: now. */
|
|
561
|
+
ingestTime?: string;
|
|
928
562
|
/** Tenant ID for multi-tenant isolation. */
|
|
929
563
|
tenantId?: string;
|
|
930
564
|
/** User ID within the tenant. */
|
|
931
565
|
userId?: string;
|
|
932
566
|
/** Team/group ID within the tenant. */
|
|
933
567
|
teamId?: string;
|
|
934
|
-
/**
|
|
935
|
-
* Exact namespace requested by a trusted transport boundary. `Memory.search`
|
|
936
|
-
* validates it against the calling principal's AuthzPlan and compiles it to
|
|
937
|
-
* a singleton prefilter. Exact scope excludes legacy NULL rows.
|
|
938
|
-
*/
|
|
568
|
+
/** Namespace ID — see `MemoryEntry.namespaceId`. */
|
|
939
569
|
namespaceId?: string;
|
|
940
570
|
/**
|
|
941
|
-
*
|
|
942
|
-
*
|
|
943
|
-
* NOT set this directly. Empty array means "no granted namespaces" (only
|
|
944
|
-
* legacy NULL-namespace entries are visible). `undefined` skips the
|
|
945
|
-
* filter (single-tenant / pre-ReBAC compat).
|
|
946
|
-
*
|
|
947
|
-
* Callers must not set this directly; use `namespaceId` for exact scope.
|
|
571
|
+
* Exclude this entry from consolidation (decay-archive and semantic dedup).
|
|
572
|
+
* See `MemoryEntry.pinned` for full semantics.
|
|
948
573
|
*/
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
574
|
+
pinned?: boolean;
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Agent-recorded explicit correction ("you did X wrong; do Y instead").
|
|
578
|
+
* `Memory.recordCorrection` writes one pinned, sqlite-only entry; pyx does
|
|
579
|
+
* pure structural retrieval with zero LLM / embedding on this path. Scope is
|
|
580
|
+
* `(tenantId, namespaceId)` + optional `project` — NOT per-user, because a
|
|
581
|
+
* correction about how to do X in this project is namespace-shared. No
|
|
582
|
+
* `confidence` field by design: ranking is overlap-then-recency only.
|
|
583
|
+
*/
|
|
584
|
+
interface CorrectionInput {
|
|
585
|
+
tenantId: string;
|
|
952
586
|
/**
|
|
953
|
-
*
|
|
954
|
-
*
|
|
955
|
-
*
|
|
956
|
-
* the surrounding KG node is otherwise reachable. Populated
|
|
957
|
-
* internally by `Memory.search` from `AuthzPlan.forbiddenStrict
|
|
958
|
-
* NamespaceIds` — callers should NOT set this directly.
|
|
587
|
+
* Namespace partition. Required in multi-tenant mode (the isolation
|
|
588
|
+
* boundary). Optional in single-tenant mode, where corrections are stored
|
|
589
|
+
* namespace-free (`namespace_id IS NULL`) exactly like ordinary writes.
|
|
959
590
|
*/
|
|
960
|
-
|
|
591
|
+
namespaceId?: string;
|
|
592
|
+
/** What the agent did wrong (required free text). */
|
|
593
|
+
whatWasWrong: string;
|
|
594
|
+
/** The corrective instruction (required free text) — stored as `entry.content`. */
|
|
595
|
+
whatToDoInstead: string;
|
|
596
|
+
/** Applicability context the matcher scores task shapes against (required free text). */
|
|
597
|
+
appliesWhen: string;
|
|
598
|
+
/** Optional project scope — when set, the correction applies only to that project. */
|
|
599
|
+
project?: string;
|
|
600
|
+
/** Optional task-shape hint, stored for provenance; matching uses `appliesWhen`. */
|
|
601
|
+
taskShape?: string;
|
|
602
|
+
/** Optional agent id; defaults to the Memory instance's `agentId`. */
|
|
603
|
+
agentId?: string;
|
|
961
604
|
}
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
605
|
+
/** Input to `Memory.fetchApplicableCorrections`. */
|
|
606
|
+
interface FetchCorrectionsInput {
|
|
607
|
+
tenantId: string;
|
|
608
|
+
/** Namespace partition; omit to read the namespace-free scope (single-tenant mode). */
|
|
609
|
+
namespaceId?: string;
|
|
610
|
+
/** Shape of the task about to run — scored against each correction's `appliesWhen`. */
|
|
611
|
+
taskShape: string;
|
|
612
|
+
/** Optional project filter — keeps only project-matching or project-absent rows. */
|
|
613
|
+
project?: string;
|
|
614
|
+
/** Max corrections to return. Default 5, hard cap 5. */
|
|
615
|
+
limit?: number;
|
|
616
|
+
/** Optional sensitivity cap for hosted/HTTP callers. Omitted preserves trusted in-process behavior. */
|
|
617
|
+
maxSensitivity?: SensitivityLevel;
|
|
618
|
+
}
|
|
619
|
+
/** Input to `Memory.dueScan` (H26 B-d — the one deterministic prospective primitive). */
|
|
620
|
+
interface DueScanInput {
|
|
968
621
|
/**
|
|
969
|
-
*
|
|
970
|
-
*
|
|
971
|
-
* magnitude. `vectorSimilarity` is the raw dense query-similarity (LanceDB
|
|
972
|
-
* transformed-L2, 1/(1+distance)); null when the entry has no dense signal
|
|
973
|
-
* (FTS/graph-only). Surface vectorSimilarity, not score, as a "% match".
|
|
622
|
+
* Window start, ISO-8601. Defaults to the server's injected clock ("now").
|
|
623
|
+
* Benches and reproducible callers pass it explicitly.
|
|
974
624
|
*/
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
/**
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
topScore: number;
|
|
989
|
-
scoreGap: number;
|
|
990
|
-
scoreStdDev: number;
|
|
991
|
-
resultCount: number;
|
|
992
|
-
aboveThresholdRatio: number;
|
|
993
|
-
scoreSeparation: number;
|
|
994
|
-
};
|
|
995
|
-
};
|
|
625
|
+
from?: string;
|
|
626
|
+
/** Window length in fixed 24-hour periods, endpoints inclusive. Integer 1..370 — out-of-range is a loud error, never a clamp. */
|
|
627
|
+
windowDays: number;
|
|
628
|
+
/** Max entries returned. Default 20, hard cap 100. */
|
|
629
|
+
limit?: number;
|
|
630
|
+
/** Tenant scope; defaults to the Memory instance's tenant. */
|
|
631
|
+
tenantId?: string;
|
|
632
|
+
/** Explicit namespace scope (tenant-root rows stay visible). Overrides principal-derived visibility. */
|
|
633
|
+
namespaceId?: string;
|
|
634
|
+
/** Optional principal for namespace visibility (AuthzPlan), like search. */
|
|
635
|
+
principal?: PrincipalContext;
|
|
636
|
+
/** Optional sensitivity cap for hosted/HTTP callers; filtered in SQL before LIMIT. */
|
|
637
|
+
maxSensitivity?: SensitivityLevel;
|
|
996
638
|
}
|
|
997
|
-
/** One
|
|
998
|
-
interface
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
supersededByEntryId?: string;
|
|
639
|
+
/** One applicable correction returned by `fetchApplicableCorrections`. */
|
|
640
|
+
interface CorrectionRecord {
|
|
641
|
+
id: string;
|
|
642
|
+
whatWasWrong: string;
|
|
643
|
+
whatToDoInstead: string;
|
|
644
|
+
appliesWhen: string;
|
|
645
|
+
createdAt: string;
|
|
646
|
+
/** Overlap-coefficient score between the query `taskShape` and this row's `appliesWhen`. */
|
|
647
|
+
score: number;
|
|
1007
648
|
}
|
|
1008
649
|
/**
|
|
1009
|
-
*
|
|
1010
|
-
*
|
|
1011
|
-
*
|
|
1012
|
-
* without a graph store).
|
|
650
|
+
* Rolling graph-traversal telemetry (in-process, since boot). Watches the
|
|
651
|
+
* engine re-review triggers: depth-2 getNeighbors p95 latency / result size
|
|
652
|
+
* (hub explosion) and getAllEdges job duration.
|
|
1013
653
|
*/
|
|
1014
|
-
interface
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
/**
|
|
1022
|
-
|
|
1023
|
-
limit?: number;
|
|
1024
|
-
}
|
|
1025
|
-
interface LineageResult {
|
|
1026
|
-
subject?: string;
|
|
1027
|
-
relation?: string;
|
|
1028
|
-
/** Event-time ascending (oldest → newest). */
|
|
1029
|
-
versions: LineageVersion[];
|
|
1030
|
-
/** Which path answered — honest provenance (graph conflict-group vs supersededBy chain). */
|
|
1031
|
-
source: 'graph' | 'chain';
|
|
654
|
+
interface GraphTelemetrySnapshot {
|
|
655
|
+
/** p95 latency (ms) of getNeighbors calls with depth >= 2; null until sampled. */
|
|
656
|
+
neighborsDepth2P95Ms: number | null;
|
|
657
|
+
/** p95 result node count of getNeighbors calls with depth >= 2; null until sampled. */
|
|
658
|
+
neighborsDepth2ResultP95: number | null;
|
|
659
|
+
/** Depth >= 2 samples in the rolling window (confidence for the p95s). */
|
|
660
|
+
neighborsDepth2SampleCount: number;
|
|
661
|
+
/** Duration (ms) of the most recent getAllEdges call; null until one ran. */
|
|
662
|
+
allEdgesLastMs: number | null;
|
|
1032
663
|
}
|
|
1033
664
|
/**
|
|
1034
|
-
*
|
|
1035
|
-
*
|
|
1036
|
-
*
|
|
1037
|
-
* user/agent marked it useful (large η). Mere top-k return is NOT a signal
|
|
1038
|
-
* (determinism + "returned ≠ used") — only an explicit `reinforce()` call moves
|
|
1039
|
-
* strength.
|
|
665
|
+
* Since-boot usage-hygiene telemetry (in-process, serializable). Tracks whether
|
|
666
|
+
* callers provide event-time/graph context on store, whether searches miss, how
|
|
667
|
+
* reinforce is used, and whether sessions search before their first store.
|
|
1040
668
|
*/
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
669
|
+
interface UsageHygieneSnapshot {
|
|
670
|
+
/** Total Memory.store calls observed since boot. */
|
|
671
|
+
storesTotal: number;
|
|
672
|
+
/** Store calls whose input carried eventTime. */
|
|
673
|
+
storesWithEventTime: number;
|
|
674
|
+
/** Store calls whose input carried caller-supplied entities or relationships. */
|
|
675
|
+
storesWithGraph: number;
|
|
676
|
+
/** Store calls by input type; missing type is counted as "long-term". */
|
|
677
|
+
storesByType: Record<string, number>;
|
|
678
|
+
/** Total Memory.search calls observed since boot. */
|
|
679
|
+
searchesTotal: number;
|
|
680
|
+
/** Completed searches that returned zero entries. */
|
|
681
|
+
searchesZeroResults: number;
|
|
682
|
+
/** Total Memory.reinforce calls observed since boot. */
|
|
683
|
+
reinforceTotal: number;
|
|
684
|
+
/** Total get_taxonomy_state (Memory.getTaxonomyState) calls observed since boot. */
|
|
685
|
+
taxonomyStateReadsTotal: number;
|
|
686
|
+
/** Total name_cluster (Memory.nameCluster) calls observed since boot. */
|
|
687
|
+
nameClusterCallsTotal: number;
|
|
688
|
+
/** Reinforce calls by signal value. */
|
|
689
|
+
reinforceBySignal: Record<string, number>;
|
|
690
|
+
/** Sessions where at least one search happened before the first store. */
|
|
691
|
+
searchBeforeFirstStoreSessions: number;
|
|
692
|
+
/** Sessions whose first observed hygiene event was a store. */
|
|
693
|
+
storeFirstSessions: number;
|
|
1047
694
|
}
|
|
1048
|
-
interface
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
695
|
+
interface MemoryStats {
|
|
696
|
+
totalEntries: number;
|
|
697
|
+
storageUsedBytes: number;
|
|
698
|
+
vectorCount: number;
|
|
699
|
+
recentAccessCount: number;
|
|
700
|
+
graphNodeCount?: number;
|
|
701
|
+
graphEdgeCount?: number;
|
|
702
|
+
/** Raw graph node count before tenant/ReBAC visibility filtering (raw stats mode only). */
|
|
703
|
+
graphRawNodeCount?: number;
|
|
704
|
+
/** Raw graph edge count before tenant/ReBAC visibility filtering (raw stats mode only). */
|
|
705
|
+
graphRawEdgeCount?: number;
|
|
706
|
+
/** Name of the active graph store ('neo4j', 'sqlite', or undefined if none). */
|
|
707
|
+
graphStore?: string;
|
|
708
|
+
/** Graph traversal telemetry; undefined when no graph store is active. */
|
|
709
|
+
graphTelemetry?: GraphTelemetrySnapshot;
|
|
710
|
+
/** Usage-hygiene telemetry since process boot. */
|
|
711
|
+
usageHygiene?: UsageHygieneSnapshot;
|
|
712
|
+
/** Whether the memory service is connected. False when using DisabledMemory. */
|
|
713
|
+
connected?: boolean;
|
|
714
|
+
/**
|
|
715
|
+
* Deferred-embed queue depth. The in-process core always reports it (0 when
|
|
716
|
+
* idle); absent means unknown (older server or disabled client), never 0.
|
|
717
|
+
*/
|
|
718
|
+
pendingEmbeddings?: number;
|
|
719
|
+
}
|
|
720
|
+
interface MemoryInsightMetrics {
|
|
721
|
+
activeEntries: number;
|
|
722
|
+
retainedAdditions7d: number;
|
|
723
|
+
appliedRecalls: number;
|
|
724
|
+
reinforcedEntries: number;
|
|
725
|
+
retrievedEntries: number;
|
|
726
|
+
retrievals: number;
|
|
727
|
+
lastAppliedAt: string | null;
|
|
728
|
+
lastRetrievedAt: string | null;
|
|
729
|
+
}
|
|
730
|
+
interface MemoryProjectInsight extends MemoryInsightMetrics {
|
|
731
|
+
label: string;
|
|
732
|
+
}
|
|
733
|
+
/** Body-free, caller-visible aggregate for product status surfaces. */
|
|
734
|
+
interface MemoryInsights {
|
|
735
|
+
generatedAt: string;
|
|
736
|
+
scope: 'connected_memory';
|
|
737
|
+
coverage: {
|
|
738
|
+
retainedAdditions: {
|
|
739
|
+
state: 'measured' | 'partial';
|
|
740
|
+
trackingSince: string | null;
|
|
741
|
+
trackedEntries: number;
|
|
742
|
+
totalEntries: number;
|
|
743
|
+
reason: string | null;
|
|
744
|
+
};
|
|
745
|
+
projectLabels: {
|
|
746
|
+
state: 'measured';
|
|
747
|
+
};
|
|
748
|
+
retrievalUsage: {
|
|
749
|
+
state: 'partial';
|
|
750
|
+
reason: string;
|
|
751
|
+
};
|
|
752
|
+
tokenEfficiency: {
|
|
753
|
+
state: 'not_instrumented';
|
|
754
|
+
reason: string;
|
|
755
|
+
};
|
|
756
|
+
contextAccuracy: {
|
|
757
|
+
state: 'not_instrumented';
|
|
758
|
+
reason: string;
|
|
759
|
+
};
|
|
760
|
+
};
|
|
761
|
+
summary: {
|
|
762
|
+
activeEntries: number;
|
|
763
|
+
observedProjectLabels: number;
|
|
764
|
+
retainedAdditions7d: number | null;
|
|
765
|
+
trackedEntries: number;
|
|
766
|
+
appliedRecalls: number;
|
|
767
|
+
reinforcedEntries: number;
|
|
768
|
+
retrievedEntries: number;
|
|
769
|
+
retrievals: number;
|
|
770
|
+
};
|
|
771
|
+
projects: MemoryProjectInsight[];
|
|
772
|
+
other: MemoryInsightMetrics | null;
|
|
773
|
+
/** Most recently reinforced visible entries (≤5), labels only, never bodies. */
|
|
774
|
+
recentApplied?: Array<{
|
|
775
|
+
topic: string | null;
|
|
776
|
+
project: string | null;
|
|
777
|
+
at: string;
|
|
1054
778
|
}>;
|
|
1055
779
|
}
|
|
1056
|
-
interface
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
tenantId?: string | null;
|
|
1061
|
-
/** Namespace of the source memory entry. `null` = legacy / tenant-root. */
|
|
1062
|
-
namespaceId?: string | null;
|
|
1063
|
-
/** Optional source identifier copied from the memory entry or caller. */
|
|
1064
|
-
source?: string;
|
|
1065
|
-
/** Optional content hash copied from the memory entry or caller. */
|
|
1066
|
-
contentHash?: string;
|
|
1067
|
-
/** Optional short text evidence for the graph fact. */
|
|
1068
|
-
snippet?: string;
|
|
1069
|
-
/** When this evidence was recorded. */
|
|
1070
|
-
createdAt?: Timestamp;
|
|
780
|
+
interface GraphRepairResult {
|
|
781
|
+
staleEdgesDeleted: number;
|
|
782
|
+
staleNodeRefsRemoved: number;
|
|
783
|
+
orphanNodesDeleted: number;
|
|
1071
784
|
}
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
readonly VECTOR: "vector";
|
|
1075
|
-
readonly GRAPH: "graph";
|
|
1076
|
-
};
|
|
1077
|
-
type StoreTarget = (typeof StoreTarget)[keyof typeof StoreTarget];
|
|
1078
|
-
/** Agent-provided entity for graph storage. */
|
|
1079
|
-
interface IngestEntity {
|
|
1080
|
-
/** Entity name (e.g., "Alice", "TypeScript"). */
|
|
785
|
+
interface GraphNode {
|
|
786
|
+
id: string;
|
|
1081
787
|
name: string;
|
|
1082
|
-
/** Entity type — freeform, agent decides (e.g., "PERSON", "TOOL"). */
|
|
1083
788
|
type: string;
|
|
1084
|
-
/** Stable canonical identifier. Defaults to a deterministic name+type id. */
|
|
1085
789
|
canonicalId?: string;
|
|
1086
|
-
/** Source evidence for this graph node. Defaults to the containing memory entry. */
|
|
1087
790
|
sourceEvidence?: SourceEvidence[];
|
|
1088
|
-
|
|
1089
|
-
|
|
791
|
+
properties: Record<string, unknown>;
|
|
792
|
+
memoryEntryIds: string[];
|
|
1090
793
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
/** Target entity name (must match an entity in the entities array). */
|
|
1096
|
-
target: string;
|
|
1097
|
-
/** Relationship type — freeform, agent decides (e.g., "WORKS_AT", "USES"). */
|
|
794
|
+
interface GraphRelationship {
|
|
795
|
+
id: string;
|
|
796
|
+
sourceId: string;
|
|
797
|
+
targetId: string;
|
|
1098
798
|
type: string;
|
|
1099
|
-
/** Source evidence for this graph edge. Defaults to the containing memory entry. */
|
|
1100
799
|
sourceEvidence?: SourceEvidence[];
|
|
1101
|
-
|
|
1102
|
-
|
|
800
|
+
properties: Record<string, unknown>;
|
|
801
|
+
memoryEntryId?: string;
|
|
802
|
+
/**
|
|
803
|
+
* Namespace_id provenance carried from the originating MemoryEntry.
|
|
804
|
+
* `null` (or absent) = legacy / tenant-root bucket. Foundation for the
|
|
805
|
+
* v0.17.0 strict traversal filter (the AuthzPlan compares this value
|
|
806
|
+
* edge-by-edge so KG dedupe at the node level can stay intact).
|
|
807
|
+
*/
|
|
808
|
+
namespaceId?: string | null;
|
|
809
|
+
}
|
|
810
|
+
interface GraphTraversalResult {
|
|
811
|
+
nodes: GraphNode[];
|
|
812
|
+
relationships: GraphRelationship[];
|
|
813
|
+
paths: Array<{
|
|
814
|
+
nodeIds: string[];
|
|
815
|
+
relationshipIds: string[];
|
|
816
|
+
}>;
|
|
1103
817
|
}
|
|
1104
818
|
/**
|
|
1105
|
-
*
|
|
1106
|
-
* -
|
|
1107
|
-
*
|
|
1108
|
-
*
|
|
1109
|
-
* masked 91/92 dropped entities.
|
|
1110
|
-
* - `best-effort`: swallow the error and log a warning; the entry is still
|
|
1111
|
-
* considered ingested in SQLite/vector. Use only when you genuinely don't
|
|
1112
|
-
* need the graph slice and a transient neo4j blip shouldn't fail ingest.
|
|
819
|
+
* Memory.lint() report shape — Karpathy-wiki Item B (v0.18.0).
|
|
820
|
+
* Read-only projection composed from signals every owning module
|
|
821
|
+
* already exposes. Lives in shared so the HTTP client can hold the
|
|
822
|
+
* same type as core without re-declaring it.
|
|
1113
823
|
*/
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
824
|
+
interface WikiLintReport {
|
|
825
|
+
orphans: GraphNode[];
|
|
826
|
+
decayCandidates: MemoryEntry[];
|
|
827
|
+
staleSyntheses: Array<{
|
|
828
|
+
entry: MemoryEntry;
|
|
829
|
+
reason: string;
|
|
830
|
+
}>;
|
|
831
|
+
dedupCandidates: Array<{
|
|
832
|
+
hash: string;
|
|
833
|
+
entryIds: string[];
|
|
834
|
+
}>;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/** Parameters for paginated entry listing. */
|
|
838
|
+
interface MemoryListParams {
|
|
839
|
+
/** 1-based page number. Default: 1 */
|
|
840
|
+
page?: number;
|
|
841
|
+
/** Entries per page (1–100). Default: 20 */
|
|
842
|
+
limit?: number;
|
|
843
|
+
/**
|
|
844
|
+
* Opaque keyset-pagination token from a previous result's `nextCursor`.
|
|
845
|
+
* Guarantees exactly-once traversal even while strictly-newer entries
|
|
846
|
+
* are being written (offset/page pagination can repeat or skip there).
|
|
847
|
+
* A cursor is only valid for the same filter set that produced it.
|
|
848
|
+
* Mutually exclusive with `page` — supplying both is an error. Not a
|
|
849
|
+
* snapshot: rows backdated behind the cursor position can still appear.
|
|
850
|
+
*/
|
|
851
|
+
cursor?: string;
|
|
852
|
+
/**
|
|
853
|
+
* Opt-in lifecycle-status filter. Omitted preserves today's behavior:
|
|
854
|
+
* active, superseded, and archived entries are all returned.
|
|
855
|
+
*/
|
|
856
|
+
status?: 'active' | 'superseded' | 'archived';
|
|
857
|
+
/** Filter by memory type. */
|
|
858
|
+
type?: MemoryType$1;
|
|
859
|
+
/** Filter by agent ID. */
|
|
860
|
+
agentId?: string;
|
|
861
|
+
/** Filter by tenant ID for multi-tenant isolation. */
|
|
862
|
+
tenantId?: string;
|
|
863
|
+
/** Exact namespace scope. Excludes legacy tenant-root entries. */
|
|
864
|
+
namespaceId?: string;
|
|
865
|
+
/**
|
|
866
|
+
* Calling principal. When supplied, list applies the AuthzPlan
|
|
867
|
+
* visibility filter so entries in forbidden namespaces never reach
|
|
868
|
+
* the response. Single-tenant / library-direct callers may omit it
|
|
869
|
+
* and get the legacy tenant-only scope.
|
|
870
|
+
*/
|
|
871
|
+
principal?: PrincipalContext$1;
|
|
872
|
+
/** Maximum sensitivity level to include. Omitted preserves legacy behavior. */
|
|
873
|
+
maxSensitivity?: SensitivityLevel$1;
|
|
874
|
+
/**
|
|
875
|
+
* R1/R2 — opt-in list of `metadata._kind` values to include in the
|
|
876
|
+
* response. When omitted or empty, the default-set returns only entries
|
|
877
|
+
* with NO `_kind` system metadata (e.g. `_kind:'entity-summary'` rows
|
|
878
|
+
* are hidden). When supplied, the listed kinds are returned IN ADDITION
|
|
879
|
+
* to the default-set (additive, not replacement). See
|
|
880
|
+
* `docs/specs/topic-org-v025-f1-include-kinds/spec.md`.
|
|
881
|
+
*/
|
|
882
|
+
includeKinds?: string[];
|
|
883
|
+
}
|
|
884
|
+
/** Result of a paginated entry listing. */
|
|
885
|
+
interface MemoryListResult {
|
|
886
|
+
entries: MemoryEntry$1[];
|
|
887
|
+
totalCount: number;
|
|
888
|
+
/** Present in page/offset mode only — a keyset traversal has no page number. */
|
|
889
|
+
page?: number;
|
|
890
|
+
limit: number;
|
|
891
|
+
/** Keyset token for the next page; null when this page is the last. */
|
|
892
|
+
nextCursor: string | null;
|
|
893
|
+
}
|
|
894
|
+
/** Filters for temporal queries (queryAsOf, queryByEventTime). */
|
|
895
|
+
interface TemporalQueryFilters {
|
|
896
|
+
type?: MemoryType$1;
|
|
1134
897
|
agentId?: string;
|
|
1135
|
-
sessionId?: string;
|
|
1136
|
-
/** Storage targets. Default: ["sqlite", "vector"]. */
|
|
1137
|
-
targets?: StoreTarget[];
|
|
1138
|
-
/** Agent-provided entities for graph storage. */
|
|
1139
|
-
entities?: IngestEntity[];
|
|
1140
|
-
/** Agent-provided relationships for graph storage. */
|
|
1141
|
-
relationships?: IngestRelationship[];
|
|
1142
|
-
/** Override graph entity extraction for this ingest request. */
|
|
1143
|
-
extractEntities?: boolean;
|
|
1144
|
-
/** Graph-failure handling. Default: "throw" (loud) — see GraphFailureMode. */
|
|
1145
|
-
graphFailureMode?: GraphFailureMode;
|
|
1146
|
-
/** Importance score (1-10). */
|
|
1147
|
-
importance?: number;
|
|
1148
|
-
/** Source identifier (e.g., filename, URL). */
|
|
1149
898
|
source?: string;
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
/**
|
|
1157
|
-
|
|
1158
|
-
|
|
899
|
+
limit?: number;
|
|
900
|
+
/**
|
|
901
|
+
* Number of matching rows to skip. Offset pages can shift under concurrent
|
|
902
|
+
* deletion; use cursor for a deletion-stable queryAsOf walk.
|
|
903
|
+
*/
|
|
904
|
+
offset?: number;
|
|
905
|
+
/**
|
|
906
|
+
* Opaque keyset token for a deletion-stable queryAsOf walk. Derive it from
|
|
907
|
+
* the last returned entry with `encodeListCursorToken`; mutually exclusive
|
|
908
|
+
* with offset.
|
|
909
|
+
*/
|
|
910
|
+
cursor?: string;
|
|
911
|
+
/** Maximum sensitivity level to include. Omitted preserves legacy behavior. */
|
|
912
|
+
maxSensitivity?: SensitivityLevel$1;
|
|
913
|
+
}
|
|
914
|
+
/** Filters for the chronological feed (`log`, Karpathy `log.md` primitive). */
|
|
915
|
+
interface MemoryLogFilters {
|
|
916
|
+
/** Inclusive lower bound on `created_at` (ISO 8601). Cursor for "what's new since X". */
|
|
917
|
+
since?: string;
|
|
918
|
+
/** Maximum entries to return. The HTTP layer clamps to [1, 100]. */
|
|
919
|
+
limit?: number;
|
|
920
|
+
type?: MemoryType$1;
|
|
921
|
+
agentId?: string;
|
|
922
|
+
source?: string;
|
|
923
|
+
/** Maximum sensitivity level to include. Omitted preserves legacy behavior. */
|
|
924
|
+
maxSensitivity?: SensitivityLevel$1;
|
|
925
|
+
}
|
|
926
|
+
/** Options for scoping operations to a specific tenant. */
|
|
927
|
+
interface TenantScopeOptions {
|
|
1159
928
|
tenantId?: string;
|
|
1160
|
-
/**
|
|
1161
|
-
userId?: string;
|
|
1162
|
-
/** Team/group ID within the tenant. */
|
|
1163
|
-
teamId?: string;
|
|
1164
|
-
/** Namespace ID — see `MemoryEntry.namespaceId`. */
|
|
929
|
+
/** Optional strict namespace coordinate for exact get/delete operations. */
|
|
1165
930
|
namespaceId?: string;
|
|
1166
931
|
/**
|
|
1167
|
-
*
|
|
1168
|
-
*
|
|
932
|
+
* Graph count mode for stats(). Use raw on admin-health paths
|
|
933
|
+
* that should avoid the visible graph projection.
|
|
1169
934
|
*/
|
|
1170
|
-
|
|
935
|
+
graphVisibility?: 'visible' | 'raw';
|
|
936
|
+
/**
|
|
937
|
+
* Calling principal. When supplied alongside or instead of tenantId,
|
|
938
|
+
* the operation applies the AuthzPlan visibility filter — get/delete
|
|
939
|
+
* will treat entries in forbidden namespaces as if they did not exist.
|
|
940
|
+
* Single-tenant / library-direct callers may omit it and get the
|
|
941
|
+
* legacy tenant-only scope.
|
|
942
|
+
*/
|
|
943
|
+
principal?: PrincipalContext$1;
|
|
944
|
+
/** Maximum sensitivity level to include. Omitted preserves legacy behavior. */
|
|
945
|
+
maxSensitivity?: SensitivityLevel$1;
|
|
946
|
+
}
|
|
947
|
+
/** Abstract interface for memory systems (local or remote). */
|
|
948
|
+
interface MemoryInterface {
|
|
949
|
+
initialize(): Promise<void>;
|
|
950
|
+
store(entry: StoreInput$1): Promise<MemoryEntry$1>;
|
|
951
|
+
search(params: MemorySearchParams$1): Promise<MemorySearchResult$1>;
|
|
952
|
+
/** List entries with SQL LIMIT/OFFSET pagination. */
|
|
953
|
+
list(params?: MemoryListParams): Promise<MemoryListResult>;
|
|
954
|
+
get(id: string, options?: TenantScopeOptions): Promise<MemoryEntry$1 | null>;
|
|
955
|
+
delete(id: string, options?: TenantScopeOptions): Promise<boolean>;
|
|
956
|
+
clearSession(sessionId: string, options?: TenantScopeOptions): Promise<number>;
|
|
957
|
+
stats(options?: TenantScopeOptions): Promise<MemoryStats$1>;
|
|
958
|
+
insights(options?: TenantScopeOptions): Promise<MemoryInsights$1>;
|
|
959
|
+
/** Query entries as they existed at a point in time (by ingest time). */
|
|
960
|
+
queryAsOf(asOfDate: string, filters?: TemporalQueryFilters, options?: TenantScopeOptions): Promise<MemoryEntry$1[]>;
|
|
961
|
+
/** Read the time-ordered lineage of a graph fact or superseded entry chain. */
|
|
962
|
+
lineage(params: LineageParams$1): Promise<LineageResult$1>;
|
|
963
|
+
/** Reinforce memories that were actually used by the caller. */
|
|
964
|
+
reinforce(params: ReinforceParams$1): Promise<ReinforceResult$1>;
|
|
965
|
+
/** Query entries by event time range (when things actually happened). */
|
|
966
|
+
queryByEventTime(startTime: string, endTime: string, filters?: TemporalQueryFilters): Promise<MemoryEntry$1[]>;
|
|
967
|
+
shutdown(): Promise<void>;
|
|
968
|
+
}
|
|
969
|
+
/** Consolidation run result. */
|
|
970
|
+
interface ConsolidationRunResult {
|
|
971
|
+
entriesProcessed: number;
|
|
972
|
+
entriesMerged: number;
|
|
973
|
+
entriesArchived: number;
|
|
974
|
+
durationMs: number;
|
|
975
|
+
}
|
|
976
|
+
/** Extended interface with lifecycle operations. Non-breaking for existing consumers. */
|
|
977
|
+
interface ExtendedMemoryInterface extends MemoryInterface {
|
|
978
|
+
/** Run consolidation: score, dedup, decay, and summarize memories. */
|
|
979
|
+
consolidate(): Promise<ConsolidationRunResult>;
|
|
980
|
+
/** Soft-delete a memory with a reason (marks as archived). */
|
|
981
|
+
forget(id: string, reason?: string): Promise<boolean>;
|
|
982
|
+
/** Summarize a session's memories into a long-term entry. */
|
|
983
|
+
summarizeSession(sessionId: string): Promise<MemoryEntry$1 | null>;
|
|
984
|
+
/**
|
|
985
|
+
* Read-only memory-wide lint report (v0.18.0 Karpathy-wiki Item B):
|
|
986
|
+
* orphans, decay candidates, stale entries, dedup candidates. Pure
|
|
987
|
+
* projection — no writes.
|
|
988
|
+
*/
|
|
989
|
+
lint(options?: {
|
|
990
|
+
limit?: number;
|
|
991
|
+
}): Promise<WikiLintReport$1>;
|
|
992
|
+
/** Run decay on all entries, archiving those below threshold. */
|
|
993
|
+
runDecay(): Promise<number>;
|
|
994
|
+
/** Reindex the FTS5 full-text search index. */
|
|
995
|
+
reindex(): Promise<void>;
|
|
996
|
+
/** Delete all entries matching a source, cleaning up all stores. */
|
|
997
|
+
deleteBySource(source: string, options?: TenantScopeOptions): Promise<number>;
|
|
998
|
+
/** Repair stale graph references left by older delete paths or crashed cleanup. */
|
|
999
|
+
repairGraph(): Promise<GraphRepairResult$1>;
|
|
1000
|
+
/**
|
|
1001
|
+
* Chronological feed of memory entries (Karpathy `log.md` primitive).
|
|
1002
|
+
* Cursor-based via `since` (created_at lower bound). No totalCount.
|
|
1003
|
+
*/
|
|
1004
|
+
log(filters?: MemoryLogFilters): Promise<MemoryEntry$1[]>;
|
|
1005
|
+
/**
|
|
1006
|
+
* Synthesize a per-entity profile (Karpathy-wiki "wiki page" primitive).
|
|
1007
|
+
* LLM-driven, caller-triggered. Stores a pinned `_kind:'entity-summary'`
|
|
1008
|
+
* entry with `_search_visibility:'on-demand'` so it never enters the
|
|
1009
|
+
* default retrieval pool. Re-running replaces the prior synthesis.
|
|
1010
|
+
*/
|
|
1011
|
+
summarizeEntity(name: string): Promise<MemoryEntry$1>;
|
|
1012
|
+
/**
|
|
1013
|
+
* Fetch a previously-synthesized entity profile. Returns `null` when no
|
|
1014
|
+
* synthesis exists yet. O(1) — the read side of the amortized pattern.
|
|
1015
|
+
*/
|
|
1016
|
+
getEntitySynthesis(name: string): Promise<MemoryEntry$1 | null>;
|
|
1171
1017
|
}
|
|
1018
|
+
|
|
1172
1019
|
/**
|
|
1173
|
-
*
|
|
1174
|
-
*
|
|
1175
|
-
*
|
|
1176
|
-
*
|
|
1177
|
-
*
|
|
1178
|
-
*
|
|
1020
|
+
* No-op {@link MemoryInterface} for hosts that run without a memory backend
|
|
1021
|
+
* (e.g. `MEMORY_URL` is unset). Every method returns a safe default, so the
|
|
1022
|
+
* rest of the system functions without branching on `memory == null`.
|
|
1023
|
+
*
|
|
1024
|
+
* Canonical single source: this lives in the SAME package as `MemoryInterface`,
|
|
1025
|
+
* so any method added to the interface fails THIS class's compile in the same
|
|
1026
|
+
* build. The null-object can never silently drift behind the contract — the
|
|
1027
|
+
* failure mode that left hand-rolled copies in downstream repos missing
|
|
1028
|
+
* `lineage`/`reinforce` after the interface grew them.
|
|
1029
|
+
*
|
|
1030
|
+
* `initialize()` emits a single `console.warn`; pass nothing else — it is a
|
|
1031
|
+
* pure null-object. Hosts wanting structured logging should log at the wiring
|
|
1032
|
+
* site where they choose `DisabledMemory` over a real client.
|
|
1179
1033
|
*/
|
|
1180
|
-
|
|
1181
|
-
|
|
1034
|
+
declare class DisabledMemory implements MemoryInterface {
|
|
1035
|
+
initialize(): Promise<void>;
|
|
1036
|
+
store(entry: StoreInput$1): Promise<MemoryEntry$1>;
|
|
1037
|
+
search(): Promise<MemorySearchResult$1>;
|
|
1038
|
+
list(params?: MemoryListParams): Promise<MemoryListResult>;
|
|
1039
|
+
get(): Promise<MemoryEntry$1 | null>;
|
|
1040
|
+
delete(): Promise<boolean>;
|
|
1041
|
+
clearSession(): Promise<number>;
|
|
1042
|
+
stats(): Promise<MemoryStats$1>;
|
|
1043
|
+
insights(): Promise<MemoryInsights$1>;
|
|
1044
|
+
queryAsOf(): Promise<MemoryEntry$1[]>;
|
|
1045
|
+
lineage(): Promise<LineageResult$1>;
|
|
1046
|
+
reinforce(): Promise<ReinforceResult$1>;
|
|
1047
|
+
queryByEventTime(): Promise<MemoryEntry$1[]>;
|
|
1048
|
+
shutdown(): Promise<void>;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
/**
|
|
1052
|
+
* Callbacks for two-phase file enrichment. All callbacks are optional:
|
|
1053
|
+
* - Image-rich PDF + describeImage only → describes images, no entity extraction
|
|
1054
|
+
* - Image-rich PDF + describeImage + extractEntitiesV2 → describes + extracts
|
|
1055
|
+
* - Text-only file + extractEntitiesV2 only → extracts from textWindows
|
|
1056
|
+
* - Mixed file + both → describes images + extracts from both sources
|
|
1057
|
+
*
|
|
1058
|
+
* Without any callback, the ingest stream emits the server result with no
|
|
1059
|
+
* SDK-side enrichment. Server-side text/entity extraction may still run when
|
|
1060
|
+
* configured; image understanding still requires caller-provided
|
|
1061
|
+
* descriptions/hooks.
|
|
1062
|
+
*/
|
|
1063
|
+
interface EnrichmentCallbacks {
|
|
1182
1064
|
/**
|
|
1183
|
-
*
|
|
1184
|
-
*
|
|
1185
|
-
*
|
|
1065
|
+
* Describe an image using LLM vision. Receives the raw image buffer and
|
|
1066
|
+
* metadata. Required for image-bearing files; safe to omit for text-only
|
|
1067
|
+
* uploads where the server emits zero images.
|
|
1186
1068
|
*/
|
|
1187
|
-
|
|
1188
|
-
/**
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1069
|
+
describeImage?: (imageBuffer: ArrayBuffer, meta: ExtractedImageMeta$1) => Promise<string>;
|
|
1070
|
+
/**
|
|
1071
|
+
* Entity-extraction callback. Receives text windows and image descriptions
|
|
1072
|
+
* separately so callers can apply different prompts per source. Triggers
|
|
1073
|
+
* the `X-Pyx-Enrichment-Capabilities: text_windows_v1` negotiation header
|
|
1074
|
+
* on ingest.
|
|
1075
|
+
*/
|
|
1076
|
+
extractEntitiesV2?: (input: {
|
|
1077
|
+
textWindows: string[];
|
|
1078
|
+
imageDescriptions: string[];
|
|
1079
|
+
mimeType: string;
|
|
1080
|
+
filename: string;
|
|
1081
|
+
}) => Promise<{
|
|
1082
|
+
entities: IngestEntity$1[];
|
|
1083
|
+
relationships: IngestRelationship$1[];
|
|
1084
|
+
}>;
|
|
1200
1085
|
}
|
|
1201
|
-
/**
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1086
|
+
/**
|
|
1087
|
+
* Options for {@link MemoryClient.ingestFileEvents}. `signal` lets
|
|
1088
|
+
* long-running ingests (LLM enrichment + graph writes) be cancelled cleanly.
|
|
1089
|
+
*
|
|
1090
|
+
* `namespaceId` opts the upload into ReBAC AuthzPlan visibility — the server
|
|
1091
|
+
* thread the namespace through parsing → enrichment → store calls so the
|
|
1092
|
+
* resulting catalog row and chunk entries land in the named namespace
|
|
1093
|
+
* (server v0.17.4+; required when `requireNamespaceForTenantWrites=true`).
|
|
1094
|
+
*/
|
|
1095
|
+
interface IngestFileOptions {
|
|
1096
|
+
description?: string;
|
|
1097
|
+
enrichment?: EnrichmentCallbacks;
|
|
1098
|
+
signal?: AbortSignal;
|
|
1205
1099
|
namespaceId?: string;
|
|
1206
|
-
/** Shape of the task about to run — scored against each correction's `appliesWhen`. */
|
|
1207
|
-
taskShape: string;
|
|
1208
|
-
/** Optional project filter — keeps only project-matching or project-absent rows. */
|
|
1209
|
-
project?: string;
|
|
1210
|
-
/** Max corrections to return. Default 5, hard cap 5. */
|
|
1211
|
-
limit?: number;
|
|
1212
|
-
/** Optional sensitivity cap for hosted/HTTP callers. Omitted preserves trusted in-process behavior. */
|
|
1213
|
-
maxSensitivity?: SensitivityLevel;
|
|
1214
|
-
}
|
|
1215
|
-
/** Input to `Memory.dueScan` (H26 B-d — the one deterministic prospective primitive). */
|
|
1216
|
-
interface DueScanInput {
|
|
1217
1100
|
/**
|
|
1218
|
-
*
|
|
1219
|
-
*
|
|
1101
|
+
* Stable logical document identity used for replaceable content, image,
|
|
1102
|
+
* and graph projections. Requires `enrichment.extractEntitiesV2` so the
|
|
1103
|
+
* client can negotiate text windows and complete the stable replacement.
|
|
1220
1104
|
*/
|
|
1221
|
-
|
|
1222
|
-
/**
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
/** Optional principal for namespace visibility (AuthzPlan), like search. */
|
|
1231
|
-
principal?: PrincipalContext;
|
|
1232
|
-
/** Optional sensitivity cap for hosted/HTTP callers; filtered in SQL before LIMIT. */
|
|
1233
|
-
maxSensitivity?: SensitivityLevel;
|
|
1234
|
-
}
|
|
1235
|
-
/** One applicable correction returned by `fetchApplicableCorrections`. */
|
|
1236
|
-
interface CorrectionRecord {
|
|
1237
|
-
id: string;
|
|
1238
|
-
whatWasWrong: string;
|
|
1239
|
-
whatToDoInstead: string;
|
|
1240
|
-
appliesWhen: string;
|
|
1241
|
-
createdAt: string;
|
|
1242
|
-
/** Overlap-coefficient score between the query `taskShape` and this row's `appliesWhen`. */
|
|
1243
|
-
score: number;
|
|
1105
|
+
documentKey?: string;
|
|
1106
|
+
/**
|
|
1107
|
+
* Migration-only pinned file-ingestion catalog for this document's first
|
|
1108
|
+
* stable replacement. The server validates its exact scope and uses its
|
|
1109
|
+
* bounded provenance to detach legacy graph references. Omit this after the
|
|
1110
|
+
* stable anchor is established: the first pass may retire catalog-owned
|
|
1111
|
+
* projections, so later revisions should use `documentKey` alone.
|
|
1112
|
+
*/
|
|
1113
|
+
catalogEntryId?: string;
|
|
1244
1114
|
}
|
|
1245
1115
|
/**
|
|
1246
|
-
*
|
|
1247
|
-
*
|
|
1248
|
-
*
|
|
1116
|
+
* Options for {@link MemoryClient.graphEnrichFileEvents}. `documentKey` is the
|
|
1117
|
+
* caller's stable logical identity for the document whose graph is being
|
|
1118
|
+
* rebuilt — the server derives the graph anchor id from
|
|
1119
|
+
* (tenant, namespace, documentKey), so repeating the same key replaces the
|
|
1120
|
+
* document's graph references instead of multiplying them.
|
|
1121
|
+
*
|
|
1122
|
+
* `enrichment.extractEntitiesV2` is required: graph-only re-enrichment is
|
|
1123
|
+
* caller-extraction by definition (there is no server-side fallback).
|
|
1249
1124
|
*/
|
|
1250
|
-
interface
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1125
|
+
interface GraphEnrichFileOptions {
|
|
1126
|
+
documentKey: string;
|
|
1127
|
+
/**
|
|
1128
|
+
* Migration-only pinned file-ingestion catalog for the first stable graph
|
|
1129
|
+
* replacement. The server resolves it in the current tenant/namespace and
|
|
1130
|
+
* detaches its bounded graph references. Omit it on later revisions once
|
|
1131
|
+
* the `documentKey` anchor exists.
|
|
1132
|
+
*/
|
|
1133
|
+
catalogEntryId?: string;
|
|
1134
|
+
namespaceId?: string;
|
|
1135
|
+
signal?: AbortSignal;
|
|
1136
|
+
enrichment: EnrichmentCallbacks;
|
|
1137
|
+
}
|
|
1138
|
+
interface FileDownloadOptions {
|
|
1139
|
+
/** Stable logical document identity used by documentKey-aware ingest. */
|
|
1140
|
+
documentKey?: string;
|
|
1141
|
+
/** Exact namespace containing the uploaded document. */
|
|
1142
|
+
namespaceId?: string;
|
|
1259
1143
|
}
|
|
1260
1144
|
/**
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1263
|
-
*
|
|
1145
|
+
* Caller-supplied enrichment for the per-call store path. Mirrors
|
|
1146
|
+
* {@link EnrichmentCallbacks} for file ingest. When supplied, the SDK invokes
|
|
1147
|
+
* the callback and merges the result into the payload before POSTing. Without
|
|
1148
|
+
* a callback, server-side text/entity extraction can run only when the server
|
|
1149
|
+
* has an extraction brain configured; otherwise callers must pass graph data
|
|
1150
|
+
* or use caller-side hooks. Images always require caller-provided
|
|
1151
|
+
* descriptions/hooks.
|
|
1264
1152
|
*/
|
|
1265
|
-
interface
|
|
1266
|
-
/**
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
taxonomyStateReadsTotal: number;
|
|
1282
|
-
/** Total name_cluster (Memory.nameCluster) calls observed since boot. */
|
|
1283
|
-
nameClusterCallsTotal: number;
|
|
1284
|
-
/** Reinforce calls by signal value. */
|
|
1285
|
-
reinforceBySignal: Record<string, number>;
|
|
1286
|
-
/** Sessions where at least one search happened before the first store. */
|
|
1287
|
-
searchBeforeFirstStoreSessions: number;
|
|
1288
|
-
/** Sessions whose first observed hygiene event was a store. */
|
|
1289
|
-
storeFirstSessions: number;
|
|
1153
|
+
interface StoreEnrichmentCallbacks {
|
|
1154
|
+
/**
|
|
1155
|
+
* Extract entities + relationships from `content`. The caller's LLM does
|
|
1156
|
+
* the work; the SDK passes the result through {@link mergeExtractedEntities}
|
|
1157
|
+
* (caller-wins, case-insensitive) before sending to the server.
|
|
1158
|
+
*
|
|
1159
|
+
* Skipped when `entry.extractEntities === false`. When
|
|
1160
|
+
* `entry.extractEntities === true` but this callback is not supplied,
|
|
1161
|
+
* `MemoryClient.store()` forwards the hint so the server-side extraction
|
|
1162
|
+
* brain can run and loud-fail if it is not configured.
|
|
1163
|
+
*/
|
|
1164
|
+
extractEntities?: (input: {
|
|
1165
|
+
content: string;
|
|
1166
|
+
metadata?: Record<string, unknown>;
|
|
1167
|
+
signal?: AbortSignal;
|
|
1168
|
+
}) => Promise<EntityExtractionResult$1>;
|
|
1290
1169
|
}
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
/**
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
/**
|
|
1307
|
-
|
|
1308
|
-
/**
|
|
1309
|
-
|
|
1170
|
+
/** Options accepted by {@link MemoryClient.store}. */
|
|
1171
|
+
interface StoreOptions {
|
|
1172
|
+
enrichment?: StoreEnrichmentCallbacks;
|
|
1173
|
+
/** Propagated into the `extractEntities` callback and the underlying fetch. */
|
|
1174
|
+
signal?: AbortSignal;
|
|
1175
|
+
/** Stable logical request key. Reuse this exact value after a lost response. */
|
|
1176
|
+
idempotencyKey?: string;
|
|
1177
|
+
}
|
|
1178
|
+
interface RequestAuthorityOptions {
|
|
1179
|
+
/** Stable logical request key. Reuse this exact value after a lost response. */
|
|
1180
|
+
idempotencyKey?: string;
|
|
1181
|
+
}
|
|
1182
|
+
/** Error thrown by MemoryClient when the server returns a non-success response. */
|
|
1183
|
+
declare class MemoryServerError extends Error {
|
|
1184
|
+
readonly status: number;
|
|
1185
|
+
/** Stable machine-readable discriminator returned by the memory server. */
|
|
1186
|
+
readonly code?: string;
|
|
1187
|
+
/** Exact HTTP Retry-After value returned by the memory server. */
|
|
1188
|
+
readonly retryAfter?: string;
|
|
1189
|
+
/** Retry delay normalized to seconds when Retry-After is parseable. */
|
|
1190
|
+
readonly retryAfterSeconds?: number;
|
|
1191
|
+
constructor(message: string, status: number, code?: string, retryAfter?: string);
|
|
1192
|
+
/** True when the server returned HTTP 404 (not found). */
|
|
1193
|
+
get isNotFound(): boolean;
|
|
1194
|
+
}
|
|
1195
|
+
interface MemoryClientOptions {
|
|
1196
|
+
/** API key for authentication. */
|
|
1197
|
+
apiKey?: string;
|
|
1198
|
+
/** Additional headers to send with every request (e.g., X-Caller-Access-Level). */
|
|
1199
|
+
defaultHeaders?: Record<string, string>;
|
|
1200
|
+
/**
|
|
1201
|
+
* Default per-request timeout in milliseconds. Without this, a wedged
|
|
1202
|
+
* memory server (e.g. event-loop blocked by inference) makes every
|
|
1203
|
+
* caller hang forever — that was the Korens demo wedge in 2026-04 where
|
|
1204
|
+
* a 161-second pyx-memory stall propagated through the runtime to the
|
|
1205
|
+
* browser. Defaults to 30 s, which is high enough that normal
|
|
1206
|
+
* `/search` and `/stats` requests never hit it but low enough that a
|
|
1207
|
+
* stuck server fails loudly.
|
|
1208
|
+
*
|
|
1209
|
+
* Only applied when the caller does NOT pass their own `signal` via
|
|
1210
|
+
* RequestInit. Long-running operations (large `consolidate`, `reindex`,
|
|
1211
|
+
* file ingest with enrichment) should pass their own AbortSignal —
|
|
1212
|
+
* that signal fully replaces the default ceiling.
|
|
1213
|
+
*/
|
|
1214
|
+
requestTimeoutMs?: number;
|
|
1215
|
+
}
|
|
1216
|
+
declare class MemoryClient implements ExtendedMemoryInterface {
|
|
1217
|
+
protected baseUrl: string;
|
|
1218
|
+
private readonly _authHeaders;
|
|
1219
|
+
private readonly _requestTimeoutMs;
|
|
1220
|
+
constructor(memoryUrl: string, apiKeyOrOptions?: string | MemoryClientOptions);
|
|
1221
|
+
/** Encode a path segment to prevent URL injection */
|
|
1222
|
+
private encodePathSegment;
|
|
1223
|
+
private authorityHeaders;
|
|
1224
|
+
private exactReadAuthority;
|
|
1225
|
+
initialize(): Promise<void>;
|
|
1226
|
+
store(entry: StoreInput$1, options?: StoreOptions): Promise<MemoryEntry$1>;
|
|
1227
|
+
search(params: MemorySearchParams$1, authority?: RequestAuthorityOptions & Pick<TenantScopeOptions, 'tenantId' | 'namespaceId'>): Promise<MemorySearchResult$1>;
|
|
1228
|
+
get(id: string, authority?: TenantScopeOptions & RequestAuthorityOptions): Promise<MemoryEntry$1 | null>;
|
|
1229
|
+
delete(id: string, authority?: TenantScopeOptions & RequestAuthorityOptions): Promise<boolean>;
|
|
1230
|
+
clearSession(sessionId: string): Promise<number>;
|
|
1231
|
+
stats(options?: TenantScopeOptions): Promise<MemoryStats$1>;
|
|
1232
|
+
insights(options?: TenantScopeOptions & RequestAuthorityOptions): Promise<MemoryInsights$1>;
|
|
1233
|
+
/**
|
|
1234
|
+
* Fetch the running server's topology snapshot (build variant, declared
|
|
1235
|
+
* role, embedding location, active model profile). Round-trips the
|
|
1236
|
+
* server's `GET /status` envelope through {@link fetchApi}, surfacing any
|
|
1237
|
+
* non-success response as {@link MemoryServerError}. Auth-header
|
|
1238
|
+
* forwarding is unchanged from other client methods even though `/status`
|
|
1239
|
+
* is server-side public — the server simply ignores credentials on that
|
|
1240
|
+
* route.
|
|
1241
|
+
*/
|
|
1242
|
+
status(): Promise<Topology$1>;
|
|
1243
|
+
shutdown(): Promise<void>;
|
|
1244
|
+
list(params?: MemoryListParams, authority?: RequestAuthorityOptions & Pick<TenantScopeOptions, 'tenantId' | 'namespaceId'>): Promise<MemoryListResult>;
|
|
1245
|
+
/**
|
|
1246
|
+
* Native streaming file ingest. Yields typed {@link IngestEvent}s as the
|
|
1247
|
+
* server (parsing/storing) and the SDK (enrichment/result) make progress.
|
|
1248
|
+
*
|
|
1249
|
+
* Wire contract: SDK POSTs with `Accept: application/x-ndjson`; the server
|
|
1250
|
+
* MUST respond with NDJSON. There is no JSON fallback — older servers
|
|
1251
|
+
* that emit `application/json` for this endpoint are not supported, and
|
|
1252
|
+
* the SDK yields a terminal `error` event in that case.
|
|
1253
|
+
*
|
|
1254
|
+
* After the server's terminal `result`, the SDK runs its own enrichment
|
|
1255
|
+
* phase (image-describe → entity-extract → `/enrich` POST), emitting
|
|
1256
|
+
* progress + heartbeat events around each step, then yields the single
|
|
1257
|
+
* terminal `result` event with the merged SDK + server result.
|
|
1258
|
+
*
|
|
1259
|
+
* Promise-shaped consumers should iterate the returned AsyncIterable and
|
|
1260
|
+
* collect the terminal event; there is no separate `ingestFile()` Promise
|
|
1261
|
+
* method by design (one wire format, one SDK method).
|
|
1262
|
+
*/
|
|
1263
|
+
ingestFileEvents(file: File, options?: IngestFileOptions): AsyncIterable<IngestEvent$1>;
|
|
1264
|
+
/**
|
|
1265
|
+
* Graph-only re-enrichment for a document whose chunks are already stored
|
|
1266
|
+
* and searchable but whose graph build failed. Uploads the original to
|
|
1267
|
+
* `/api/memory/graph/enrich/file` (prepare-only — the server performs zero
|
|
1268
|
+
* store/delete before the final graph write), runs the SAME enrichment
|
|
1269
|
+
* callback engine as {@link ingestFileEvents}, then finalizes into one
|
|
1270
|
+
* stable graph anchor keyed by `documentKey`. Repeating the same key
|
|
1271
|
+
* replaces the document's graph references idempotently.
|
|
1272
|
+
*
|
|
1273
|
+
* The terminal `result` is a {@link GraphEnrichResult} event carrying the
|
|
1274
|
+
* ACTUAL persisted graph counts; abort and failures yield a terminal
|
|
1275
|
+
* `error` event instead (the server retains the pending session for retry).
|
|
1276
|
+
*/
|
|
1277
|
+
graphEnrichFileEvents(file: File, options: GraphEnrichFileOptions): AsyncIterable<GraphEnrichEvent$1>;
|
|
1278
|
+
/**
|
|
1279
|
+
* POST a multipart body to an NDJSON streaming endpoint and relay its
|
|
1280
|
+
* progress/heartbeat events. Returns the raw terminal `result` record, or
|
|
1281
|
+
* null after yielding a terminal error (transport failure, server error
|
|
1282
|
+
* event, non-NDJSON response, stream ending without a result). One
|
|
1283
|
+
* implementation for both streaming surfaces so the wire protocol cannot
|
|
1284
|
+
* fork.
|
|
1285
|
+
*/
|
|
1286
|
+
private streamNdjsonUpload;
|
|
1287
|
+
/**
|
|
1288
|
+
* Run the SDK-side enrichment phase for an ingest result and yield the
|
|
1289
|
+
* single terminal {@link IngestResultEvent} at the end. Skips work cleanly
|
|
1290
|
+
* when the server emitted no enrichment block or the caller wired no
|
|
1291
|
+
* callbacks. The callback work itself lives in
|
|
1292
|
+
* {@link runEnrichmentCallbacks} — shared with the graph-only surface.
|
|
1293
|
+
*/
|
|
1294
|
+
private completeIngestFileEvents;
|
|
1295
|
+
/**
|
|
1296
|
+
* The ONE enrichment callback engine, shared by {@link ingestFileEvents}
|
|
1297
|
+
* and {@link graphEnrichFileEvents}: fetches extracted images, invokes
|
|
1298
|
+
* `describeImage` with bounded concurrency, invokes `extractEntitiesV2`
|
|
1299
|
+
* exactly once, and POSTs `/files/{fileId}/enrich` — emitting progress and
|
|
1300
|
+
* heartbeat events around each slow step. Throws on any failure; the
|
|
1301
|
+
* purpose-specific wrappers translate that into their terminal error.
|
|
1302
|
+
*
|
|
1303
|
+
* Legacy ingest keeps its existing partial add-on behavior. Graph-only and
|
|
1304
|
+
* documentKey-aware full ingest may replace a prior graph only from a
|
|
1305
|
+
* complete input set (no truncated text windows or undescribed images). A
|
|
1306
|
+
* complete extractor result containing zero entities remains a valid clear.
|
|
1307
|
+
*/
|
|
1308
|
+
private runEnrichmentCallbacks;
|
|
1309
|
+
/**
|
|
1310
|
+
* Race a Promise against a periodic heartbeat tick. Yields a heartbeat
|
|
1311
|
+
* IngestEvent every {@link INGEST_EVENT_HEARTBEAT_MS} until the promise
|
|
1312
|
+
* settles, then returns the resolved value (or rethrows). Lets callers
|
|
1313
|
+
* keep upstream sockets alive through long LLM/HTTP work without
|
|
1314
|
+
* coupling the heartbeat cadence to the work itself.
|
|
1315
|
+
*/
|
|
1316
|
+
private withSdkHeartbeats;
|
|
1317
|
+
private normalizeActiveIngestStage;
|
|
1318
|
+
private fileIngestResultFromEvent;
|
|
1319
|
+
private ingestErrorEvent;
|
|
1310
1320
|
/**
|
|
1311
|
-
*
|
|
1312
|
-
*
|
|
1321
|
+
* Get the download URL for an uploaded file.
|
|
1322
|
+
* Returns a URL that serves the original file binary with proper Content-Type.
|
|
1313
1323
|
*/
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
scope: 'connected_memory';
|
|
1333
|
-
coverage: {
|
|
1334
|
-
retainedAdditions: {
|
|
1335
|
-
state: 'measured' | 'partial';
|
|
1336
|
-
trackingSince: string | null;
|
|
1337
|
-
trackedEntries: number;
|
|
1338
|
-
totalEntries: number;
|
|
1339
|
-
reason: string | null;
|
|
1340
|
-
};
|
|
1341
|
-
projectLabels: {
|
|
1342
|
-
state: 'measured';
|
|
1343
|
-
};
|
|
1344
|
-
retrievalUsage: {
|
|
1345
|
-
state: 'partial';
|
|
1346
|
-
reason: string;
|
|
1347
|
-
};
|
|
1348
|
-
tokenEfficiency: {
|
|
1349
|
-
state: 'not_instrumented';
|
|
1350
|
-
reason: string;
|
|
1351
|
-
};
|
|
1352
|
-
contextAccuracy: {
|
|
1353
|
-
state: 'not_instrumented';
|
|
1354
|
-
reason: string;
|
|
1324
|
+
getFileDownloadUrl(filename: string, options?: FileDownloadOptions): string;
|
|
1325
|
+
/**
|
|
1326
|
+
* Download an uploaded file by filename.
|
|
1327
|
+
* Returns the raw Response (caller handles the body — arrayBuffer, blob, stream, etc.).
|
|
1328
|
+
*/
|
|
1329
|
+
downloadFile(filename: string, options?: FileDownloadOptions): Promise<Response>;
|
|
1330
|
+
/** @deprecated Use {@link list} instead. Kept for backwards compatibility. */
|
|
1331
|
+
listEntries(params?: {
|
|
1332
|
+
page?: number;
|
|
1333
|
+
limit?: number;
|
|
1334
|
+
}): Promise<MemoryEntry$1[]>;
|
|
1335
|
+
graphNodes(): Promise<GraphNode$1[]>;
|
|
1336
|
+
graphEdges(): Promise<{
|
|
1337
|
+
stats: {
|
|
1338
|
+
nodeCount: number;
|
|
1339
|
+
edgeCount: number;
|
|
1340
|
+
rawNodeCount?: number;
|
|
1341
|
+
rawEdgeCount?: number;
|
|
1355
1342
|
};
|
|
1356
|
-
};
|
|
1357
|
-
summary: {
|
|
1358
|
-
activeEntries: number;
|
|
1359
|
-
observedProjectLabels: number;
|
|
1360
|
-
retainedAdditions7d: number | null;
|
|
1361
|
-
trackedEntries: number;
|
|
1362
|
-
appliedRecalls: number;
|
|
1363
|
-
reinforcedEntries: number;
|
|
1364
|
-
retrievedEntries: number;
|
|
1365
|
-
retrievals: number;
|
|
1366
|
-
};
|
|
1367
|
-
projects: MemoryProjectInsight[];
|
|
1368
|
-
other: MemoryInsightMetrics | null;
|
|
1369
|
-
/** Most recently reinforced visible entries (≤5), labels only, never bodies. */
|
|
1370
|
-
recentApplied?: Array<{
|
|
1371
|
-
topic: string | null;
|
|
1372
|
-
project: string | null;
|
|
1373
|
-
at: string;
|
|
1374
1343
|
}>;
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1344
|
+
graphQuery(query: {
|
|
1345
|
+
nodeId: string;
|
|
1346
|
+
depth?: number;
|
|
1347
|
+
}): Promise<GraphTraversalResult$1>;
|
|
1348
|
+
consolidate(): Promise<ConsolidationRunResult>;
|
|
1349
|
+
forget(id: string, reason?: string): Promise<boolean>;
|
|
1350
|
+
summarizeSession(sessionId: string): Promise<MemoryEntry$1 | null>;
|
|
1351
|
+
lint(options?: {
|
|
1352
|
+
limit?: number;
|
|
1353
|
+
}): Promise<WikiLintReport$1>;
|
|
1354
|
+
runDecay(): Promise<number>;
|
|
1355
|
+
reindex(): Promise<void>;
|
|
1356
|
+
clearGraph(): Promise<number>;
|
|
1357
|
+
repairGraph(): Promise<GraphRepairResult$1>;
|
|
1358
|
+
deleteBySource(source: string, authority?: TenantScopeOptions): Promise<number>;
|
|
1359
|
+
setFolder(from: string, to: string, options?: {
|
|
1360
|
+
dryRun?: boolean;
|
|
1361
|
+
}): Promise<{
|
|
1362
|
+
from: string;
|
|
1363
|
+
to: string;
|
|
1364
|
+
updated: number;
|
|
1365
|
+
dryRun: boolean;
|
|
1366
|
+
}>;
|
|
1367
|
+
queryAsOf(asOfDate: string, filters?: TemporalQueryFilters, authority?: TenantScopeOptions): Promise<MemoryEntry$1[]>;
|
|
1368
|
+
lineage(params: LineageParams$1, authority?: RequestAuthorityOptions): Promise<LineageResult$1>;
|
|
1369
|
+
reinforce(params: ReinforceParams$1, authority?: RequestAuthorityOptions): Promise<ReinforceResult$1>;
|
|
1370
|
+
log(filters?: MemoryLogFilters): Promise<MemoryEntry$1[]>;
|
|
1371
|
+
queryByEventTime(startTime: string, endTime: string, filters?: TemporalQueryFilters): Promise<MemoryEntry$1[]>;
|
|
1372
|
+
summarizeEntity(name: string): Promise<MemoryEntry$1>;
|
|
1373
|
+
getEntitySynthesis(name: string): Promise<MemoryEntry$1 | null>;
|
|
1398
1374
|
/**
|
|
1399
|
-
*
|
|
1400
|
-
* `
|
|
1401
|
-
*
|
|
1402
|
-
*
|
|
1375
|
+
* v0.26 user-profile snapshot — upsert. The server derives `userId`
|
|
1376
|
+
* from `X-User-Id` (caller wires it via `defaultHeaders` on the
|
|
1377
|
+
* client constructor or per-request middleware); the body cannot
|
|
1378
|
+
* override it. See spec §Requirements 10.
|
|
1403
1379
|
*/
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
nodeIds: string[];
|
|
1411
|
-
relationshipIds: string[];
|
|
1412
|
-
}>;
|
|
1413
|
-
}
|
|
1414
|
-
/**
|
|
1415
|
-
* Memory.lint() report shape — Karpathy-wiki Item B (v0.18.0).
|
|
1416
|
-
* Read-only projection composed from signals every owning module
|
|
1417
|
-
* already exposes. Lives in shared so the HTTP client can hold the
|
|
1418
|
-
* same type as core without re-declaring it.
|
|
1419
|
-
*/
|
|
1420
|
-
interface WikiLintReport {
|
|
1421
|
-
orphans: GraphNode[];
|
|
1422
|
-
decayCandidates: MemoryEntry[];
|
|
1423
|
-
staleSyntheses: Array<{
|
|
1424
|
-
entry: MemoryEntry;
|
|
1425
|
-
reason: string;
|
|
1380
|
+
upsertUserProfile(input: {
|
|
1381
|
+
namespaceId: string;
|
|
1382
|
+
content: string;
|
|
1383
|
+
}): Promise<{
|
|
1384
|
+
updatedAt: string;
|
|
1385
|
+
contentSize: number;
|
|
1426
1386
|
}>;
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1387
|
+
/**
|
|
1388
|
+
* v0.26 user-profile snapshot — fetch by namespace. Returns `null` on
|
|
1389
|
+
* HTTP 404 (`isNotFound`), rethrows any other non-2xx as
|
|
1390
|
+
* `MemoryServerError`. Mirrors `get()`'s 404-to-null pattern so callers
|
|
1391
|
+
* can branch on "no profile yet" without inspecting status codes.
|
|
1392
|
+
*/
|
|
1393
|
+
getUserProfile(namespaceId: string): Promise<{
|
|
1394
|
+
content: string;
|
|
1395
|
+
updatedAt: string;
|
|
1396
|
+
contentSize: number;
|
|
1397
|
+
} | null>;
|
|
1398
|
+
/**
|
|
1399
|
+
* v0.28 correction-memory — record an explicit correction. POSTs to
|
|
1400
|
+
* `/api/memory/corrections`; tenant is header-derived (server-side), so
|
|
1401
|
+
* the body carries only the correction fields. Returns `{ id, createdAt }`.
|
|
1402
|
+
*/
|
|
1403
|
+
recordCorrection(input: {
|
|
1404
|
+
/** Omit in single-tenant deployments — corrections are stored namespace-free. */
|
|
1405
|
+
namespaceId?: string;
|
|
1406
|
+
whatWasWrong: string;
|
|
1407
|
+
whatToDoInstead: string;
|
|
1408
|
+
appliesWhen: string;
|
|
1409
|
+
project?: string;
|
|
1410
|
+
taskShape?: string;
|
|
1411
|
+
}): Promise<{
|
|
1412
|
+
id: string;
|
|
1413
|
+
createdAt: string;
|
|
1430
1414
|
}>;
|
|
1415
|
+
/**
|
|
1416
|
+
* v0.28 correction-memory — fetch the corrections applicable to a task
|
|
1417
|
+
* shape. GETs `/api/memory/corrections`; returns `[]` when none have
|
|
1418
|
+
* positive overlap. pyx never auto-prepends — the agent owns inclusion.
|
|
1419
|
+
*/
|
|
1420
|
+
fetchApplicableCorrections(input: {
|
|
1421
|
+
/** Omit in single-tenant deployments — reads the namespace-free scope. */
|
|
1422
|
+
namespaceId?: string;
|
|
1423
|
+
taskShape: string;
|
|
1424
|
+
project?: string;
|
|
1425
|
+
limit?: number;
|
|
1426
|
+
}): Promise<CorrectionRecord$1[]>;
|
|
1427
|
+
/**
|
|
1428
|
+
* H26 B-d — deterministic prospective due-scan: entries with
|
|
1429
|
+
* `eventTime ∈ [from, from+windowDays]` (inclusive), eventTime ascending,
|
|
1430
|
+
* no relevance ranking. `GET /api/memory/due`.
|
|
1431
|
+
*/
|
|
1432
|
+
dueScan(input: {
|
|
1433
|
+
windowDays: number;
|
|
1434
|
+
from?: string;
|
|
1435
|
+
/** Omit in single-tenant deployments. */
|
|
1436
|
+
namespaceId?: string;
|
|
1437
|
+
limit?: number;
|
|
1438
|
+
}): Promise<MemoryEntry$1[]>;
|
|
1439
|
+
protected fetchApi<T>(path: string, options?: RequestInit): Promise<T>;
|
|
1440
|
+
/**
|
|
1441
|
+
* Map fetch-layer rejections into a typed `MemoryServerError` so callers
|
|
1442
|
+
* can react uniformly. AbortSignal.timeout fires a `TimeoutError`; the
|
|
1443
|
+
* caller's signal generally fires an `AbortError`. Anything else (DNS,
|
|
1444
|
+
* TCP reset, TLS) becomes a wrapped error with status 0.
|
|
1445
|
+
*/
|
|
1446
|
+
private translateFetchError;
|
|
1447
|
+
/** Parse and validate a JSON API response, throwing MemoryServerError on any failure. */
|
|
1448
|
+
private parseApiResponse;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
interface IngestionResult {
|
|
1452
|
+
filename: string;
|
|
1453
|
+
fileType: string;
|
|
1454
|
+
chunks: number;
|
|
1455
|
+
entryIds: string[];
|
|
1456
|
+
totalCharacters: number;
|
|
1431
1457
|
}
|
|
1432
1458
|
|
|
1459
|
+
declare const DEFAULTS: {
|
|
1460
|
+
readonly DATA_DIR: "./data";
|
|
1461
|
+
readonly VECTOR_PROVIDER: "lancedb";
|
|
1462
|
+
readonly MEMORY_SERVER_PORT: 7822;
|
|
1463
|
+
};
|
|
1464
|
+
declare const TAXONOMY_MAX_CATEGORIES = 10;
|
|
1465
|
+
declare const TAXONOMY_MAX_TOP_ENTITIES = 15;
|
|
1466
|
+
declare const TAXONOMY_MAX_SAMPLE_TOPICS = 8;
|
|
1467
|
+
declare const TAXONOMY_MAX_PROJECTS = 8;
|
|
1468
|
+
declare const MEMORY_PROJECT_LABEL_MAX_CHARS = 80;
|
|
1469
|
+
|
|
1433
1470
|
/**
|
|
1434
1471
|
* Result shape returned by an LLM entity extractor — entities + relations.
|
|
1435
1472
|
*
|
|
@@ -1866,6 +1903,8 @@ declare const MoveFailureReason: {
|
|
|
1866
1903
|
readonly GRAPH_UPDATE_FAILED: "graph_update_failed";
|
|
1867
1904
|
/** Compensation itself failed — manual intervention required. */
|
|
1868
1905
|
readonly COMPENSATION_FAILED: "compensation_failed";
|
|
1906
|
+
/** Target namespace already holds the entry's (session, ordinal) coordinate; nothing moved. */
|
|
1907
|
+
readonly SESSION_ORDINAL_CONFLICT: "session_ordinal_conflict";
|
|
1869
1908
|
};
|
|
1870
1909
|
type MoveFailureReason = (typeof MoveFailureReason)[keyof typeof MoveFailureReason];
|
|
1871
1910
|
/**
|
|
@@ -1893,4 +1932,4 @@ interface CreatePyxMemoryOptions {
|
|
|
1893
1932
|
}
|
|
1894
1933
|
declare function createPyxMemory(opts?: CreatePyxMemoryOptions): MemoryClient;
|
|
1895
1934
|
|
|
1896
|
-
export { type AgentId, type ApiResponse, type ConsolidationRunResult, type CorrectionInput, type CorrectionRecord, type CreatePyxMemoryOptions, DEFAULTS, DEPRECATED_RAG_STRATEGIES, DisabledMemory, type DroppedGraphRelationship, type DueScanInput, EmbeddingProviderName, type EnrichmentCallbacks, type EnrichmentPurpose, type EntityExtractionResult, type ExtendedMemoryInterface, type FetchCorrectionsInput, type FileDownloadOptions, type GraphEnrichEvent, type GraphEnrichFileOptions, type GraphEnrichPreparedEvent, type GraphEnrichResult, type GraphEnrichResultEvent, type GraphEnrichment, type GraphEnrichmentStatus, type GraphExtractionPayload, type GraphFailureMode, type GraphNode, type GraphRelationship, type GraphRepairResult, type GraphTelemetrySnapshot, type GraphTraversalResult, type IngestEntity, type IngestErrorEvent, type IngestEvent, type IngestFileOptions, type IngestHeartbeatEvent, type IngestProgressEvent, type IngestRelationship, type IngestResultEvent, type IngestStage, type IngestionResult, type LineageParams, type LineageResult, type LineageVersion, MEMORY_PROJECT_LABEL_MAX_CHARS, MemoryClient, type MemoryClientOptions, type MemoryEntry, type MemoryIngestRequest, type MemoryInsightMetrics, type MemoryInsights, type MemoryInterface, type MemoryListParams, type MemoryListResult, type MemoryLogFilters, type MemoryProjectInsight, type MemorySearchParams, type MemorySearchResult, MemoryServerError, type MemoryStats, MemoryType, type MoveEntriesFilter, MoveFailureReason, type MoveResult, type MoveTarget, NamespaceIsolation, type PrincipalContext, RAGStrategy, type ReinforceParams, type ReinforceResult, type ReinforceSignal, SINGLE_TENANT_ID, type SecretElevationAggregate, type SecretElevationNotice, SensitivityLevel, type SourceEvidence, type StoreInput, StoreTarget, TAXONOMY_MAX_CATEGORIES, TAXONOMY_MAX_PROJECTS, TAXONOMY_MAX_SAMPLE_TOPICS, TAXONOMY_MAX_TOP_ENTITIES, type TemporalQueryFilters, type TenantScopeOptions, type Timestamp, type Topology, type TopologyExtractionProvider, type TopologyServiceVariant, type UsageHygieneSnapshot, VectorProvider, type VectorStatus, type WikiLintReport, assertGraphExtractionPayload, createPyxMemory, mergeExtractedEntities, normalizeGraphLabel, normalizeNameKey, projectSearchResponseForMcp, secretElevationAggregate, secretElevationNoticeFor, withSecretElevationNotice };
|
|
1935
|
+
export { type AgentId, type ApiResponse, type ConsolidationRunResult, type CorrectionInput, type CorrectionRecord, type CreatePyxMemoryOptions, DEFAULTS, DEPRECATED_RAG_STRATEGIES, DisabledMemory, type DroppedGraphRelationship, type DueScanInput, EmbeddingProviderName, type EnrichmentCallbacks, type EnrichmentPurpose, type EntityExtractionResult, type ExpandAnchorStatus, type ExpandParams, type ExpandResult, type ExtendedMemoryInterface, type FetchCorrectionsInput, type FileDownloadOptions, type GraphEnrichEvent, type GraphEnrichFileOptions, type GraphEnrichPreparedEvent, type GraphEnrichResult, type GraphEnrichResultEvent, type GraphEnrichment, type GraphEnrichmentStatus, type GraphExtractionPayload, type GraphFailureMode, type GraphNode, type GraphRelationship, type GraphRepairResult, type GraphTelemetrySnapshot, type GraphTraversalResult, type IngestEntity, type IngestErrorEvent, type IngestEvent, type IngestFileOptions, type IngestHeartbeatEvent, type IngestProgressEvent, type IngestRelationship, type IngestResultEvent, type IngestStage, type IngestionResult, type LineageParams, type LineageResult, type LineageVersion, MEMORY_PROJECT_LABEL_MAX_CHARS, MemoryClient, type MemoryClientOptions, type MemoryEntry, type MemoryIngestRequest, type MemoryInsightMetrics, type MemoryInsights, type MemoryInterface, type MemoryListParams, type MemoryListResult, type MemoryLogFilters, type MemoryProjectInsight, type MemorySearchParams, type MemorySearchResult, MemoryServerError, type MemoryStats, MemoryType, type MoveEntriesFilter, MoveFailureReason, type MoveResult, type MoveTarget, NamespaceIsolation, type PrincipalContext, RAGStrategy, type ReinforceParams, type ReinforceResult, type ReinforceSignal, SESSION_ORDINAL_MAX, SINGLE_TENANT_ID, type SecretElevationAggregate, type SecretElevationNotice, SensitivityLevel, type SourceEvidence, type StoreInput, StoreTarget, TAXONOMY_MAX_CATEGORIES, TAXONOMY_MAX_PROJECTS, TAXONOMY_MAX_SAMPLE_TOPICS, TAXONOMY_MAX_TOP_ENTITIES, type TemporalQueryFilters, type TenantScopeOptions, type Timestamp, type Topology, type TopologyExtractionProvider, type TopologyServiceVariant, type UsageHygieneSnapshot, VectorProvider, type VectorStatus, type WikiLintReport, assertGraphExtractionPayload, createPyxMemory, isSessionOrdinal, mergeExtractedEntities, normalizeGraphLabel, normalizeNameKey, projectSearchResponseForMcp, secretElevationAggregate, secretElevationNoticeFor, withSecretElevationNotice };
|