@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.
- package/README.md +685 -691
- package/dist/auth/login.d.ts +107 -68
- package/dist/auth/login.js +227 -216
- package/dist/auth/login.js.map +1 -1
- package/dist/cli.js +41 -41
- package/dist/consolidator.js +519 -519
- package/dist/context-pressure.js +91 -91
- package/dist/governance.js +6 -6
- package/dist/handoff.d.ts +11 -6
- package/dist/handoff.js +32 -10
- package/dist/handoff.js.map +1 -1
- package/dist/migrate.js +5 -5
- package/dist/server.js +1101 -927
- package/dist/server.js.map +1 -1
- package/dist/source-dedup.d.ts +86 -86
- package/dist/source-dedup.js +147 -147
- package/dist/storage-postgres.js +61 -61
- package/dist/update-metadata.d.ts +29 -29
- package/dist/update-metadata.js +51 -51
- package/dist/wal.d.ts +95 -95
- package/dist/wal.js +295 -295
- package/migrations/postgres/001_init.sql +70 -70
- package/migrations/postgres/002_indexes.sql +45 -45
- package/package.json +69 -69
package/dist/context-pressure.js
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CONTEXT PRESSURE — self-nudge helper.
|
|
3
|
-
*
|
|
4
|
-
* Engram can't actually read the agent's token budget, but it can return a
|
|
5
|
-
* structured checklist that reminds the agent *what* to do when context is
|
|
6
|
-
* getting heavy. The agent calls this periodically (or after big tool outputs)
|
|
7
|
-
* and gets back a deterministic prompt-injection telling it to write a
|
|
8
|
-
* handoff note and invoke /compact.
|
|
9
|
-
*
|
|
10
|
-
* This exists because self-pacing compaction is a discipline problem — the
|
|
11
|
-
* agent knows it should do it, but needs a loud, structured reminder.
|
|
12
|
-
*/
|
|
13
|
-
const PLAN_OK = [
|
|
14
|
-
'No action required. Continue working.',
|
|
15
|
-
'Save any new facts, preferences, or decisions to
|
|
16
|
-
];
|
|
17
|
-
const PLAN_WARM = [
|
|
18
|
-
'Save any unsaved facts/preferences/decisions to
|
|
19
|
-
'Update session state with current task/decisions via
|
|
20
|
-
'Continue working but keep tool outputs lean.',
|
|
21
|
-
];
|
|
22
|
-
const PLAN_HOT = [
|
|
23
|
-
'IMMEDIATELY call
|
|
24
|
-
'Save unsaved facts to
|
|
25
|
-
'After the handoff is written, invoke /compact yourself — do not wait for the system.',
|
|
26
|
-
];
|
|
27
|
-
const PLAN_CRITICAL = [
|
|
28
|
-
'STOP all other work.',
|
|
29
|
-
'Call
|
|
30
|
-
'Save any unsaved facts to
|
|
31
|
-
'Tell the user the context is near-full and ask permission to /compact or end the session. If no response, compact anyway — losing the handoff is worse than a surprise compact.',
|
|
32
|
-
];
|
|
33
|
-
// When the agent reports a natural phase boundary (task done, pivoting focus,
|
|
34
|
-
// finishing a subsystem), eat the cache miss now. The pivot will thrash the
|
|
35
|
-
// cache anyway — better to compact with fresh memories and a handoff in hand
|
|
36
|
-
// than ride a bloated window into the next phase.
|
|
37
|
-
const PLAN_PHASE_BOUNDARY = [
|
|
38
|
-
'Natural phase boundary detected. This is the right moment to compact — pivots thrash the cache anyway.',
|
|
39
|
-
'Call
|
|
40
|
-
'Save any unsaved facts from the completed phase via
|
|
41
|
-
'Invoke /compact yourself before starting the next phase. Do not carry verbose tool outputs from the finished work into the new one.',
|
|
42
|
-
];
|
|
43
|
-
export function assessPressure(level, reason = '', phaseBoundary = false) {
|
|
44
|
-
// Phase boundary overrides ok/warm — compact proactively regardless of level.
|
|
45
|
-
// At hot/critical the phase boundary adds urgency but the existing plan is already strict.
|
|
46
|
-
if (phaseBoundary && (level === 'ok' || level === 'warm')) {
|
|
47
|
-
return {
|
|
48
|
-
level,
|
|
49
|
-
phaseBoundary: true,
|
|
50
|
-
reason,
|
|
51
|
-
actionPlan: PLAN_PHASE_BOUNDARY,
|
|
52
|
-
reminder: 'Phase boundary. Write handoff, save memories, /compact before pivoting.',
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
switch (level) {
|
|
56
|
-
case 'ok':
|
|
57
|
-
return {
|
|
58
|
-
level,
|
|
59
|
-
phaseBoundary,
|
|
60
|
-
reason,
|
|
61
|
-
actionPlan: PLAN_OK,
|
|
62
|
-
reminder: 'Context healthy. Keep persisting memories as they emerge.',
|
|
63
|
-
};
|
|
64
|
-
case 'warm':
|
|
65
|
-
return {
|
|
66
|
-
level,
|
|
67
|
-
phaseBoundary,
|
|
68
|
-
reason,
|
|
69
|
-
actionPlan: PLAN_WARM,
|
|
70
|
-
reminder: 'Context warming. Persist memories now; keep outputs lean.',
|
|
71
|
-
};
|
|
72
|
-
case 'hot':
|
|
73
|
-
return {
|
|
74
|
-
level,
|
|
75
|
-
phaseBoundary,
|
|
76
|
-
reason,
|
|
77
|
-
actionPlan: phaseBoundary
|
|
78
|
-
? [...PLAN_PHASE_BOUNDARY, ...PLAN_HOT]
|
|
79
|
-
: PLAN_HOT,
|
|
80
|
-
reminder: 'Context HOT. Write handoff note, then /compact. Do not wait.',
|
|
81
|
-
};
|
|
82
|
-
case 'critical':
|
|
83
|
-
return {
|
|
84
|
-
level,
|
|
85
|
-
phaseBoundary,
|
|
86
|
-
reason,
|
|
87
|
-
actionPlan: PLAN_CRITICAL,
|
|
88
|
-
reminder: 'CRITICAL: window near full. Write handoff NOW or lose state.',
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* CONTEXT PRESSURE — self-nudge helper.
|
|
3
|
+
*
|
|
4
|
+
* Engram can't actually read the agent's token budget, but it can return a
|
|
5
|
+
* structured checklist that reminds the agent *what* to do when context is
|
|
6
|
+
* getting heavy. The agent calls this periodically (or after big tool outputs)
|
|
7
|
+
* and gets back a deterministic prompt-injection telling it to write a
|
|
8
|
+
* handoff note and invoke /compact.
|
|
9
|
+
*
|
|
10
|
+
* This exists because self-pacing compaction is a discipline problem — the
|
|
11
|
+
* agent knows it should do it, but needs a loud, structured reminder.
|
|
12
|
+
*/
|
|
13
|
+
const PLAN_OK = [
|
|
14
|
+
'No action required. Continue working.',
|
|
15
|
+
'Save any new facts, preferences, or decisions to engram-ingest as they emerge.',
|
|
16
|
+
];
|
|
17
|
+
const PLAN_WARM = [
|
|
18
|
+
'Save any unsaved facts/preferences/decisions to engram-ingest now — do not batch.',
|
|
19
|
+
'Update session state with current task/decisions via engram-session.',
|
|
20
|
+
'Continue working but keep tool outputs lean.',
|
|
21
|
+
];
|
|
22
|
+
const PLAN_HOT = [
|
|
23
|
+
'IMMEDIATELY call engram-handoff-write with a full "where we left off" snapshot.',
|
|
24
|
+
'Save unsaved facts to engram-ingest.',
|
|
25
|
+
'After the handoff is written, invoke /compact yourself — do not wait for the system.',
|
|
26
|
+
];
|
|
27
|
+
const PLAN_CRITICAL = [
|
|
28
|
+
'STOP all other work.',
|
|
29
|
+
'Call engram-handoff-write RIGHT NOW — reason: "context-pressure". Include currentTask, nextSteps, fileRefs, openQuestions.',
|
|
30
|
+
'Save any unsaved facts to engram-ingest.',
|
|
31
|
+
'Tell the user the context is near-full and ask permission to /compact or end the session. If no response, compact anyway — losing the handoff is worse than a surprise compact.',
|
|
32
|
+
];
|
|
33
|
+
// When the agent reports a natural phase boundary (task done, pivoting focus,
|
|
34
|
+
// finishing a subsystem), eat the cache miss now. The pivot will thrash the
|
|
35
|
+
// cache anyway — better to compact with fresh memories and a handoff in hand
|
|
36
|
+
// than ride a bloated window into the next phase.
|
|
37
|
+
const PLAN_PHASE_BOUNDARY = [
|
|
38
|
+
'Natural phase boundary detected. This is the right moment to compact — pivots thrash the cache anyway.',
|
|
39
|
+
'Call engram-handoff-write with reason="compact". Include currentTask (the phase just finished), completed, nextSteps (the phase about to start), fileRefs, decisions.',
|
|
40
|
+
'Save any unsaved facts from the completed phase via engram-ingest.',
|
|
41
|
+
'Invoke /compact yourself before starting the next phase. Do not carry verbose tool outputs from the finished work into the new one.',
|
|
42
|
+
];
|
|
43
|
+
export function assessPressure(level, reason = '', phaseBoundary = false) {
|
|
44
|
+
// Phase boundary overrides ok/warm — compact proactively regardless of level.
|
|
45
|
+
// At hot/critical the phase boundary adds urgency but the existing plan is already strict.
|
|
46
|
+
if (phaseBoundary && (level === 'ok' || level === 'warm')) {
|
|
47
|
+
return {
|
|
48
|
+
level,
|
|
49
|
+
phaseBoundary: true,
|
|
50
|
+
reason,
|
|
51
|
+
actionPlan: PLAN_PHASE_BOUNDARY,
|
|
52
|
+
reminder: 'Phase boundary. Write handoff, save memories, /compact before pivoting.',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
switch (level) {
|
|
56
|
+
case 'ok':
|
|
57
|
+
return {
|
|
58
|
+
level,
|
|
59
|
+
phaseBoundary,
|
|
60
|
+
reason,
|
|
61
|
+
actionPlan: PLAN_OK,
|
|
62
|
+
reminder: 'Context healthy. Keep persisting memories as they emerge.',
|
|
63
|
+
};
|
|
64
|
+
case 'warm':
|
|
65
|
+
return {
|
|
66
|
+
level,
|
|
67
|
+
phaseBoundary,
|
|
68
|
+
reason,
|
|
69
|
+
actionPlan: PLAN_WARM,
|
|
70
|
+
reminder: 'Context warming. Persist memories now; keep outputs lean.',
|
|
71
|
+
};
|
|
72
|
+
case 'hot':
|
|
73
|
+
return {
|
|
74
|
+
level,
|
|
75
|
+
phaseBoundary,
|
|
76
|
+
reason,
|
|
77
|
+
actionPlan: phaseBoundary
|
|
78
|
+
? [...PLAN_PHASE_BOUNDARY, ...PLAN_HOT]
|
|
79
|
+
: PLAN_HOT,
|
|
80
|
+
reminder: 'Context HOT. Write handoff note, then /compact. Do not wait.',
|
|
81
|
+
};
|
|
82
|
+
case 'critical':
|
|
83
|
+
return {
|
|
84
|
+
level,
|
|
85
|
+
phaseBoundary,
|
|
86
|
+
reason,
|
|
87
|
+
actionPlan: PLAN_CRITICAL,
|
|
88
|
+
reminder: 'CRITICAL: window near full. Write handoff NOW or lose state.',
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
92
|
//# sourceMappingURL=context-pressure.js.map
|
package/dist/governance.js
CHANGED
|
@@ -160,12 +160,12 @@ async function llmContradictionCheck(config, newContent, candidates) {
|
|
|
160
160
|
const existingList = candidates
|
|
161
161
|
.map((c, i) => `${i}. [${c.id}] ${c.content.slice(0, 200)}`)
|
|
162
162
|
.join('\n');
|
|
163
|
-
const response = await llmComplete(config, `You detect contradictions between a new memory and existing memories.
|
|
164
|
-
A contradiction exists when two statements cannot both be true.
|
|
165
|
-
NOT a contradiction: additional details, updates, or elaborations.
|
|
166
|
-
IS a contradiction: opposite claims, negated facts, mutually exclusive preferences.
|
|
167
|
-
|
|
168
|
-
Return JSON: [{"index": number, "type": "direct"|"semantic"|"temporal", "confidence": 0.0-1.0}]
|
|
163
|
+
const response = await llmComplete(config, `You detect contradictions between a new memory and existing memories.
|
|
164
|
+
A contradiction exists when two statements cannot both be true.
|
|
165
|
+
NOT a contradiction: additional details, updates, or elaborations.
|
|
166
|
+
IS a contradiction: opposite claims, negated facts, mutually exclusive preferences.
|
|
167
|
+
|
|
168
|
+
Return JSON: [{"index": number, "type": "direct"|"semantic"|"temporal", "confidence": 0.0-1.0}]
|
|
169
169
|
Return [] if no contradictions found. Return ONLY valid JSON.`, `NEW MEMORY:\n${newContent}\n\nEXISTING MEMORIES:\n${existingList}`, { maxTokens: 300, temperature: 0 });
|
|
170
170
|
const result = { found: false, contradictions: [] };
|
|
171
171
|
try {
|
package/dist/handoff.d.ts
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
export interface HandoffNote {
|
|
14
14
|
/** ISO timestamp of when this handoff was written */
|
|
15
15
|
timestamp: string;
|
|
16
|
+
/** Optional human-friendly checkpoint name (e.g. "engram-named-checkpoints"). Allows list-and-pick resume across many saved sessions. */
|
|
17
|
+
name?: string;
|
|
16
18
|
/** Session or conversation identifier */
|
|
17
19
|
sessionId: string | null;
|
|
18
20
|
/** Why the handoff was written: compact, session-end, manual, context-pressure */
|
|
@@ -36,13 +38,16 @@ export interface HandoffNote {
|
|
|
36
38
|
* Write a handoff note. Persists BOTH JSON (machine-readable) and markdown (human-readable).
|
|
37
39
|
*/
|
|
38
40
|
export declare function writeHandoff(dataDir: string, note: Omit<HandoffNote, 'timestamp'>): HandoffNote;
|
|
39
|
-
export declare function readHandoff(dataDir: string,
|
|
40
|
-
|
|
41
|
-
* List handoff stamps, newest first.
|
|
42
|
-
*/
|
|
43
|
-
export declare function listHandoffs(dataDir: string, limit?: number): Array<{
|
|
41
|
+
export declare function readHandoff(dataDir: string, identifier?: string): HandoffNote | null;
|
|
42
|
+
export interface HandoffListEntry {
|
|
44
43
|
stamp: string;
|
|
45
44
|
timestamp: string;
|
|
46
45
|
reason: string;
|
|
47
46
|
currentTask: string;
|
|
48
|
-
|
|
47
|
+
name?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* List handoff checkpoints, newest first. Includes the optional `name` so a
|
|
51
|
+
* caller can present a list-and-pick UI keyed on either stamp or name.
|
|
52
|
+
*/
|
|
53
|
+
export declare function listHandoffs(dataDir: string, limit?: number): HandoffListEntry[];
|
package/dist/handoff.js
CHANGED
|
@@ -39,29 +39,47 @@ export function writeHandoff(dataDir, note) {
|
|
|
39
39
|
return full;
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
|
-
* Read the most recent handoff, or a specific one by stamp.
|
|
42
|
+
* Read the most recent handoff, or a specific one by stamp or name.
|
|
43
|
+
*
|
|
44
|
+
* Identifier resolution order:
|
|
45
|
+
* 1. No identifier → latest timestamped handoff
|
|
46
|
+
* 2. Identifier matches stamp regex → load by stamp
|
|
47
|
+
* 3. Otherwise → scan handoff JSONs for `name` field match (newest match wins)
|
|
43
48
|
*/
|
|
44
49
|
// Timestamped handoff filenames look like "2026-04-22_14-32-05-123Z" (what
|
|
45
50
|
// stampFilename() produces). The rolling `session-checkpoint.json` written
|
|
46
51
|
// by engram_stop_hook.sh does NOT match this shape, so it won't shadow real
|
|
47
52
|
// handoffs when readHandoff() picks the latest.
|
|
48
53
|
const STAMP_RE = /^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}/;
|
|
49
|
-
export function readHandoff(dataDir,
|
|
54
|
+
export function readHandoff(dataDir, identifier) {
|
|
50
55
|
const dir = handoffDir(dataDir);
|
|
51
56
|
if (!existsSync(dir))
|
|
52
57
|
return null;
|
|
53
|
-
|
|
54
|
-
if (!targetStamp) {
|
|
58
|
+
if (!identifier) {
|
|
55
59
|
const allJson = readdirSync(dir).filter(f => f.endsWith('.json'));
|
|
56
60
|
const timestamped = allJson.filter(f => STAMP_RE.test(f)).sort().reverse();
|
|
57
|
-
// Prefer an explicitly-written, timestamped handoff; fall back to any
|
|
58
|
-
// other .json (e.g. the rolling session checkpoint) only if none exist.
|
|
59
61
|
const pick = timestamped[0] ?? allJson.sort().reverse()[0];
|
|
60
62
|
if (!pick)
|
|
61
63
|
return null;
|
|
62
|
-
|
|
64
|
+
return loadHandoffFile(handoffJsonPath(dataDir, pick.replace(/\.json$/, '')));
|
|
63
65
|
}
|
|
64
|
-
|
|
66
|
+
if (STAMP_RE.test(identifier)) {
|
|
67
|
+
return loadHandoffFile(handoffJsonPath(dataDir, identifier));
|
|
68
|
+
}
|
|
69
|
+
// Name lookup — scan newest first, return first hit.
|
|
70
|
+
const stamps = readdirSync(dir)
|
|
71
|
+
.filter(f => f.endsWith('.json'))
|
|
72
|
+
.map(f => f.replace(/\.json$/, ''))
|
|
73
|
+
.sort()
|
|
74
|
+
.reverse();
|
|
75
|
+
for (const stamp of stamps) {
|
|
76
|
+
const note = loadHandoffFile(handoffJsonPath(dataDir, stamp));
|
|
77
|
+
if (note?.name === identifier)
|
|
78
|
+
return note;
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
function loadHandoffFile(path) {
|
|
65
83
|
if (!existsSync(path))
|
|
66
84
|
return null;
|
|
67
85
|
try {
|
|
@@ -72,7 +90,8 @@ export function readHandoff(dataDir, stamp) {
|
|
|
72
90
|
}
|
|
73
91
|
}
|
|
74
92
|
/**
|
|
75
|
-
* List handoff
|
|
93
|
+
* List handoff checkpoints, newest first. Includes the optional `name` so a
|
|
94
|
+
* caller can present a list-and-pick UI keyed on either stamp or name.
|
|
76
95
|
*/
|
|
77
96
|
export function listHandoffs(dataDir, limit = 10) {
|
|
78
97
|
const dir = handoffDir(dataDir);
|
|
@@ -93,6 +112,7 @@ export function listHandoffs(dataDir, limit = 10) {
|
|
|
93
112
|
timestamp: note.timestamp,
|
|
94
113
|
reason: note.reason,
|
|
95
114
|
currentTask: note.currentTask,
|
|
115
|
+
...(note.name ? { name: note.name } : {}),
|
|
96
116
|
});
|
|
97
117
|
}
|
|
98
118
|
catch {
|
|
@@ -103,9 +123,11 @@ export function listHandoffs(dataDir, limit = 10) {
|
|
|
103
123
|
}
|
|
104
124
|
function formatHandoffMarkdown(note) {
|
|
105
125
|
const lines = [
|
|
106
|
-
`# Handoff — ${note.timestamp}`,
|
|
126
|
+
`# Handoff — ${note.name ?? note.timestamp}`,
|
|
107
127
|
'',
|
|
128
|
+
note.name ? `**Name:** ${note.name}` : '',
|
|
108
129
|
`**Reason:** ${note.reason}`,
|
|
130
|
+
`**Timestamp:** ${note.timestamp}`,
|
|
109
131
|
note.sessionId ? `**Session:** ${note.sessionId}` : '',
|
|
110
132
|
'',
|
|
111
133
|
'## Current Task',
|
package/dist/handoff.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handoff.js","sourceRoot":"","sources":["../src/handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtG,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"handoff.js","sourceRoot":"","sources":["../src/handoff.ts"],"names":[],"mappings":"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"}
|
package/dist/migrate.js
CHANGED
|
@@ -51,11 +51,11 @@ async function main() {
|
|
|
51
51
|
await client.connect();
|
|
52
52
|
try {
|
|
53
53
|
// Bootstrap the bookkeeping table itself.
|
|
54
|
-
await client.query(`
|
|
55
|
-
CREATE TABLE IF NOT EXISTS _migrations (
|
|
56
|
-
filename text PRIMARY KEY,
|
|
57
|
-
applied_at timestamptz NOT NULL DEFAULT NOW()
|
|
58
|
-
)
|
|
54
|
+
await client.query(`
|
|
55
|
+
CREATE TABLE IF NOT EXISTS _migrations (
|
|
56
|
+
filename text PRIMARY KEY,
|
|
57
|
+
applied_at timestamptz NOT NULL DEFAULT NOW()
|
|
58
|
+
)
|
|
59
59
|
`);
|
|
60
60
|
const { rows: appliedRows } = await client.query(`SELECT filename FROM _migrations`);
|
|
61
61
|
const applied = new Set(appliedRows.map((r) => r.filename));
|