@onenomad/engram-mcp 1.0.0 → 2.0.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.
@@ -1,52 +1,52 @@
1
- /**
2
- * Pure helper: build the storage patch for a memory_update_metadata
3
- * call. Separated from server.ts so importing it (e.g. from tests)
4
- * doesn't pull in the MCP stdio server bootstrap.
5
- *
6
- * - `merge`: only fields the caller specified land in the patch.
7
- * Untouched fields are absent → Storage.updateChunk leaves them alone.
8
- * - `replace`: every metadata-shape field is set, with caller values
9
- * where present and engram defaults otherwise. Existing untouched
10
- * fields get overwritten with the default. Footgun-y; the tool
11
- * layer logs a warning when this mode fires.
12
- *
13
- * Immutable fields (id, createdAt, embedding, embeddingVersion) are
14
- * never produced by this helper; the tool layer doesn't accept them
15
- * in its input schema either.
16
- */
17
- export function buildUpdateMetadataPatch(metadata, mode) {
18
- const patch = {};
19
- if (mode === 'replace') {
20
- patch.tags = metadata.tags ?? [];
21
- patch.source = metadata.source ?? '';
22
- patch.domain = metadata.domain ?? '';
23
- patch.topic = metadata.topic ?? '';
24
- patch.type = metadata.type ?? 'context';
25
- patch.sentiment = metadata.sentiment ?? 'neutral';
26
- patch.importance = metadata.importance ?? 0.5;
27
- if (metadata.cognitiveLayer !== undefined) {
28
- patch.cognitiveLayer = metadata.cognitiveLayer;
29
- }
30
- }
31
- else {
32
- if (metadata.tags !== undefined)
33
- patch.tags = metadata.tags;
34
- if (metadata.source !== undefined)
35
- patch.source = metadata.source;
36
- if (metadata.domain !== undefined)
37
- patch.domain = metadata.domain;
38
- if (metadata.topic !== undefined)
39
- patch.topic = metadata.topic;
40
- if (metadata.type !== undefined)
41
- patch.type = metadata.type;
42
- if (metadata.sentiment !== undefined)
43
- patch.sentiment = metadata.sentiment;
44
- if (metadata.importance !== undefined)
45
- patch.importance = metadata.importance;
46
- if (metadata.cognitiveLayer !== undefined) {
47
- patch.cognitiveLayer = metadata.cognitiveLayer;
48
- }
49
- }
50
- return patch;
51
- }
1
+ /**
2
+ * Pure helper: build the storage patch for a engram-update-metadata
3
+ * call. Separated from server.ts so importing it (e.g. from tests)
4
+ * doesn't pull in the MCP stdio server bootstrap.
5
+ *
6
+ * - `merge`: only fields the caller specified land in the patch.
7
+ * Untouched fields are absent → Storage.updateChunk leaves them alone.
8
+ * - `replace`: every metadata-shape field is set, with caller values
9
+ * where present and engram defaults otherwise. Existing untouched
10
+ * fields get overwritten with the default. Footgun-y; the tool
11
+ * layer logs a warning when this mode fires.
12
+ *
13
+ * Immutable fields (id, createdAt, embedding, embeddingVersion) are
14
+ * never produced by this helper; the tool layer doesn't accept them
15
+ * in its input schema either.
16
+ */
17
+ export function buildUpdateMetadataPatch(metadata, mode) {
18
+ const patch = {};
19
+ if (mode === 'replace') {
20
+ patch.tags = metadata.tags ?? [];
21
+ patch.source = metadata.source ?? '';
22
+ patch.domain = metadata.domain ?? '';
23
+ patch.topic = metadata.topic ?? '';
24
+ patch.type = metadata.type ?? 'context';
25
+ patch.sentiment = metadata.sentiment ?? 'neutral';
26
+ patch.importance = metadata.importance ?? 0.5;
27
+ if (metadata.cognitiveLayer !== undefined) {
28
+ patch.cognitiveLayer = metadata.cognitiveLayer;
29
+ }
30
+ }
31
+ else {
32
+ if (metadata.tags !== undefined)
33
+ patch.tags = metadata.tags;
34
+ if (metadata.source !== undefined)
35
+ patch.source = metadata.source;
36
+ if (metadata.domain !== undefined)
37
+ patch.domain = metadata.domain;
38
+ if (metadata.topic !== undefined)
39
+ patch.topic = metadata.topic;
40
+ if (metadata.type !== undefined)
41
+ patch.type = metadata.type;
42
+ if (metadata.sentiment !== undefined)
43
+ patch.sentiment = metadata.sentiment;
44
+ if (metadata.importance !== undefined)
45
+ patch.importance = metadata.importance;
46
+ if (metadata.cognitiveLayer !== undefined) {
47
+ patch.cognitiveLayer = metadata.cognitiveLayer;
48
+ }
49
+ }
50
+ return patch;
51
+ }
52
52
  //# sourceMappingURL=update-metadata.js.map
package/dist/wal.d.ts CHANGED
@@ -1,95 +1,95 @@
1
- import type { SmartMemoryConfig, MemoryType, CognitiveLayer, Sentiment, MemoryOrigin, MemoryTier } from './types.js';
2
- import type { StoredChunk } from './storage.js';
3
- import { Storage } from './storage.js';
4
- /**
5
- * Write-Ahead Log (WAL) — real-time memory capture during conversations.
6
- *
7
- * The WAL principle: write state BEFORE responding, not after.
8
- * This ensures no memory is lost if the agent crashes, compacts, or restarts.
9
- *
10
- * Use `ingest` for immediate capture of facts/decisions/preferences
11
- * as they happen, rather than waiting for post-conversation extraction.
12
- */
13
- export interface IngestEntry {
14
- content: string;
15
- type?: MemoryType;
16
- layer?: CognitiveLayer;
17
- importance?: number;
18
- tags?: string[];
19
- source?: string;
20
- domain?: string;
21
- topic?: string;
22
- sentiment?: Sentiment;
23
- emotionalValence?: number;
24
- emotionalArousal?: number;
25
- origin?: MemoryOrigin;
26
- tier?: MemoryTier;
27
- /**
28
- * ISO 8601 timestamp override. Default: ingest time (Date.now()).
29
- *
30
- * Critical when the content represents an event that originally
31
- * happened at a different time — meeting notes from yesterday,
32
- * dated documents, imported chat history, benchmark fixtures.
33
- *
34
- * The createdAt timestamp flows into `buildContextPrefix()` which
35
- * is included in the embedded text. The retrieval pipeline uses
36
- * this as a temporal signal — both via similarity match against
37
- * the prefix in queries, and via downstream temporal-boost logic
38
- * in `search.ts`.
39
- *
40
- * Without an override, every ingested memory shares the ingest-
41
- * time prefix (which is the same for everything ingested in the
42
- * same hour), losing all temporal differentiation.
43
- */
44
- createdAt?: string;
45
- /**
46
- * When true, skip the per-chunk KG triple extraction. The standalone
47
- * locomo bench bypasses this (calls saveChunk directly, never enters
48
- * wal.ts), which is why its wall-clock is ~50× faster than Pyre's
49
- * MCP-boundary bench on the same dataset.
50
- *
51
- * Real users keep KG extraction (it powers memory_dossier,
52
- * memory_kg_query, graph rerank). Benchmark harnesses comparing
53
- * apples-to-apples vs the standalone bench should pass this flag
54
- * so they're measuring the same code path.
55
- */
56
- skipKgExtraction?: boolean;
57
- /**
58
- * When true, skip the post-batch appendDailyEntry write. Same
59
- * rationale as skipKgExtraction — the standalone bench doesn't
60
- * touch the daily-entries store; bench harnesses matching it
61
- * should skip the write to compare on equal footing.
62
- */
63
- skipDailyEntry?: boolean;
64
- /**
65
- * When false, KG extraction + daily-entry append run in the
66
- * BACKGROUND after ingest() returns. The caller gets its chunks
67
- * back as soon as the saveChunk loop finishes; the side effects
68
- * complete on their own pace.
69
- *
70
- * Default true (backwards compatible — caller awaits everything).
71
- * Production callers where the agent doesn't immediately query
72
- * the just-written content (chat WAL, tool-vault bridge) should
73
- * pass false for ~5-30× faster perceived ingest latency.
74
- *
75
- * To wait for background work to drain (tests, shutdown), call
76
- * `flushPendingSideEffects()` from this module.
77
- */
78
- awaitSideEffects?: boolean;
79
- }
80
- /**
81
- * Wait for all in-flight background side-effects (KG extraction +
82
- * daily-entry append fired with `awaitSideEffects: false`) to
83
- * complete. No-op when nothing is pending.
84
- *
85
- * Tests should call this between ingest and assert; shutdown code
86
- * should call before process exit to avoid losing KG writes.
87
- */
88
- export declare function flushPendingSideEffects(): Promise<void>;
89
- /** Pending count — for tests + telemetry. */
90
- export declare function pendingSideEffectCount(): number;
91
- /**
92
- * Immediately persist one or more memory entries.
93
- * Designed to be called mid-conversation, before the agent responds.
94
- */
95
- export declare function ingest(config: SmartMemoryConfig, storage: Storage, entries: IngestEntry[]): Promise<StoredChunk[]>;
1
+ import type { SmartMemoryConfig, MemoryType, CognitiveLayer, Sentiment, MemoryOrigin, MemoryTier } from './types.js';
2
+ import type { StoredChunk } from './storage.js';
3
+ import { Storage } from './storage.js';
4
+ /**
5
+ * Write-Ahead Log (WAL) — real-time memory capture during conversations.
6
+ *
7
+ * The WAL principle: write state BEFORE responding, not after.
8
+ * This ensures no memory is lost if the agent crashes, compacts, or restarts.
9
+ *
10
+ * Use `ingest` for immediate capture of facts/decisions/preferences
11
+ * as they happen, rather than waiting for post-conversation extraction.
12
+ */
13
+ export interface IngestEntry {
14
+ content: string;
15
+ type?: MemoryType;
16
+ layer?: CognitiveLayer;
17
+ importance?: number;
18
+ tags?: string[];
19
+ source?: string;
20
+ domain?: string;
21
+ topic?: string;
22
+ sentiment?: Sentiment;
23
+ emotionalValence?: number;
24
+ emotionalArousal?: number;
25
+ origin?: MemoryOrigin;
26
+ tier?: MemoryTier;
27
+ /**
28
+ * ISO 8601 timestamp override. Default: ingest time (Date.now()).
29
+ *
30
+ * Critical when the content represents an event that originally
31
+ * happened at a different time — meeting notes from yesterday,
32
+ * dated documents, imported chat history, benchmark fixtures.
33
+ *
34
+ * The createdAt timestamp flows into `buildContextPrefix()` which
35
+ * is included in the embedded text. The retrieval pipeline uses
36
+ * this as a temporal signal — both via similarity match against
37
+ * the prefix in queries, and via downstream temporal-boost logic
38
+ * in `search.ts`.
39
+ *
40
+ * Without an override, every ingested memory shares the ingest-
41
+ * time prefix (which is the same for everything ingested in the
42
+ * same hour), losing all temporal differentiation.
43
+ */
44
+ createdAt?: string;
45
+ /**
46
+ * When true, skip the per-chunk KG triple extraction. The standalone
47
+ * locomo bench bypasses this (calls saveChunk directly, never enters
48
+ * wal.ts), which is why its wall-clock is ~50× faster than Pyre's
49
+ * MCP-boundary bench on the same dataset.
50
+ *
51
+ * Real users keep KG extraction (it powers engram-dossier,
52
+ * engram-kg-query, graph rerank). Benchmark harnesses comparing
53
+ * apples-to-apples vs the standalone bench should pass this flag
54
+ * so they're measuring the same code path.
55
+ */
56
+ skipKgExtraction?: boolean;
57
+ /**
58
+ * When true, skip the post-batch appendDailyEntry write. Same
59
+ * rationale as skipKgExtraction — the standalone bench doesn't
60
+ * touch the daily-entries store; bench harnesses matching it
61
+ * should skip the write to compare on equal footing.
62
+ */
63
+ skipDailyEntry?: boolean;
64
+ /**
65
+ * When false, KG extraction + daily-entry append run in the
66
+ * BACKGROUND after ingest() returns. The caller gets its chunks
67
+ * back as soon as the saveChunk loop finishes; the side effects
68
+ * complete on their own pace.
69
+ *
70
+ * Default true (backwards compatible — caller awaits everything).
71
+ * Production callers where the agent doesn't immediately query
72
+ * the just-written content (chat WAL, tool-vault bridge) should
73
+ * pass false for ~5-30× faster perceived ingest latency.
74
+ *
75
+ * To wait for background work to drain (tests, shutdown), call
76
+ * `flushPendingSideEffects()` from this module.
77
+ */
78
+ awaitSideEffects?: boolean;
79
+ }
80
+ /**
81
+ * Wait for all in-flight background side-effects (KG extraction +
82
+ * daily-entry append fired with `awaitSideEffects: false`) to
83
+ * complete. No-op when nothing is pending.
84
+ *
85
+ * Tests should call this between ingest and assert; shutdown code
86
+ * should call before process exit to avoid losing KG writes.
87
+ */
88
+ export declare function flushPendingSideEffects(): Promise<void>;
89
+ /** Pending count — for tests + telemetry. */
90
+ export declare function pendingSideEffectCount(): number;
91
+ /**
92
+ * Immediately persist one or more memory entries.
93
+ * Designed to be called mid-conversation, before the agent responds.
94
+ */
95
+ export declare function ingest(config: SmartMemoryConfig, storage: Storage, entries: IngestEntry[]): Promise<StoredChunk[]>;