engram-sdk 0.1.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.
Files changed (69) hide show
  1. package/CONTRIBUTING.md +65 -0
  2. package/Dockerfile +21 -0
  3. package/EVAL-FRAMEWORK.md +70 -0
  4. package/EVAL.md +127 -0
  5. package/LICENSE +17 -0
  6. package/README.md +309 -0
  7. package/ROADMAP.md +113 -0
  8. package/deploy/fly.toml +26 -0
  9. package/dist/auto-ingest.d.ts +3 -0
  10. package/dist/auto-ingest.d.ts.map +1 -0
  11. package/dist/auto-ingest.js +334 -0
  12. package/dist/auto-ingest.js.map +1 -0
  13. package/dist/brief.d.ts +45 -0
  14. package/dist/brief.d.ts.map +1 -0
  15. package/dist/brief.js +183 -0
  16. package/dist/brief.js.map +1 -0
  17. package/dist/claude-watcher.d.ts +3 -0
  18. package/dist/claude-watcher.d.ts.map +1 -0
  19. package/dist/claude-watcher.js +385 -0
  20. package/dist/claude-watcher.js.map +1 -0
  21. package/dist/cli.d.ts +3 -0
  22. package/dist/cli.d.ts.map +1 -0
  23. package/dist/cli.js +764 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/embeddings.d.ts +42 -0
  26. package/dist/embeddings.d.ts.map +1 -0
  27. package/dist/embeddings.js +145 -0
  28. package/dist/embeddings.js.map +1 -0
  29. package/dist/eval.d.ts +2 -0
  30. package/dist/eval.d.ts.map +1 -0
  31. package/dist/eval.js +281 -0
  32. package/dist/eval.js.map +1 -0
  33. package/dist/extract.d.ts +11 -0
  34. package/dist/extract.d.ts.map +1 -0
  35. package/dist/extract.js +139 -0
  36. package/dist/extract.js.map +1 -0
  37. package/dist/hosted.d.ts +3 -0
  38. package/dist/hosted.d.ts.map +1 -0
  39. package/dist/hosted.js +144 -0
  40. package/dist/hosted.js.map +1 -0
  41. package/dist/index.d.ts +11 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +7 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/ingest.d.ts +28 -0
  46. package/dist/ingest.d.ts.map +1 -0
  47. package/dist/ingest.js +192 -0
  48. package/dist/ingest.js.map +1 -0
  49. package/dist/mcp.d.ts +3 -0
  50. package/dist/mcp.d.ts.map +1 -0
  51. package/dist/mcp.js +349 -0
  52. package/dist/mcp.js.map +1 -0
  53. package/dist/server.d.ts +17 -0
  54. package/dist/server.d.ts.map +1 -0
  55. package/dist/server.js +515 -0
  56. package/dist/server.js.map +1 -0
  57. package/dist/store.d.ts +87 -0
  58. package/dist/store.d.ts.map +1 -0
  59. package/dist/store.js +548 -0
  60. package/dist/store.js.map +1 -0
  61. package/dist/types.d.ts +204 -0
  62. package/dist/types.d.ts.map +1 -0
  63. package/dist/types.js +77 -0
  64. package/dist/types.js.map +1 -0
  65. package/dist/vault.d.ts +116 -0
  66. package/dist/vault.d.ts.map +1 -0
  67. package/dist/vault.js +1234 -0
  68. package/dist/vault.js.map +1 -0
  69. package/package.json +61 -0
package/ROADMAP.md ADDED
@@ -0,0 +1,113 @@
1
+ # Engram Roadmap
2
+
3
+ *Last updated: 2026-02-17*
4
+
5
+ ## Phase 1 — Foundation ✅ Current
6
+
7
+ **What:** The core memory engine — SDK, REST API, auto-extraction, consolidation, and vector search.
8
+
9
+ **Why it matters:** This is the proof that structured memory is fundamentally better than flat files and vector-only search. Everything else builds on this foundation.
10
+
11
+ ### Done
12
+ - [x] Memory types: episodic, semantic, procedural
13
+ - [x] Vault API: remember(), recall(), forget(), connect(), consolidate()
14
+ - [x] SQLite storage with sqlite-vec vector search
15
+ - [x] Memory graph with typed edges (supports, contradicts, elaborates, supersedes, etc.)
16
+ - [x] Entity tracking across memories
17
+ - [x] Memory decay with configurable half-life
18
+ - [x] LLM-powered consolidation (Anthropic, OpenAI)
19
+ - [x] Rule-based consolidation (no LLM fallback)
20
+ - [x] REST API server — all Vault operations exposed, CORS, health endpoint
21
+ - [x] Auto-extraction: rule-based entities, topics, salience estimation
22
+ - [x] POST /v1/ingest endpoint for raw text
23
+ - [x] CLI with REPL mode
24
+ - [x] Conversation ingest pipeline (LLM-powered)
25
+ - [x] Session briefing generation
26
+ - [x] Spreading activation recall
27
+ - [x] Proactive memory surfacing
28
+ - [x] Marketing site deployed (engram-site.vercel.app)
29
+ - [x] 86+ tests passing across 5 test files
30
+
31
+ ### Next
32
+ - [ ] Domain resolution (engram.ai or fallback)
33
+ - [ ] Public repo launch
34
+ - [ ] Launch announcements (HN, Product Hunt, X, r/LocalLLaMA)
35
+
36
+ ---
37
+
38
+ ## Phase 2 — Hosted Service
39
+
40
+ **What:** Multi-tenant hosted API at api.engram.ai — the primary product.
41
+
42
+ **Why it matters:** Most developers don't want to run infrastructure. A hosted API with a generous free tier removes all friction. This is the business.
43
+
44
+ ### To Build
45
+ - [ ] Multi-tenant architecture — isolated vaults per API key
46
+ - [ ] Auth system — API key generation, scoping, rotation
47
+ - [ ] Usage metering — track memories stored, recalls, consolidations
48
+ - [ ] Rate limiting — per-key limits, burst handling
49
+ - [ ] Billing integration — usage-based pricing, Stripe
50
+ - [ ] Dashboard — API key management, usage graphs, vault inspector
51
+ - [ ] Managed consolidation — scheduled sleep cycles, no user infra needed
52
+ - [ ] Free tier: 1 vault, 10K memories, 1K recalls/day
53
+ - [ ] Pro tier: unlimited vaults, priority consolidation, higher limits
54
+ - [ ] Enterprise: dedicated infrastructure, SSO, SLAs
55
+
56
+ ### Why Usage-Based
57
+ Memory is sensitive data. Charging by usage (not seats) means individuals and small teams can use the full API for free or near-free, while heavy users pay proportionally. No artificial feature gates.
58
+
59
+ ---
60
+
61
+ ## Phase 3 — Intelligence
62
+
63
+ **What:** Upgrade the brain — LLM-powered extraction, smarter consolidation, proactive context, contradiction detection.
64
+
65
+ **Why it matters:** Rule-based extraction works but misses nuance. LLM-powered intelligence makes Engram dramatically better at understanding what matters and surfacing it at the right time.
66
+
67
+ ### To Build
68
+ - [ ] LLM-powered entity extraction (upgrade from regex/rules)
69
+ - [ ] Smart consolidation — cross-session pattern detection, temporal reasoning
70
+ - [ ] Proactive context surfacing — push relevant memories before the agent asks
71
+ - [ ] Contradiction detection — flag conflicting memories automatically
72
+ - [ ] Salience learning — adapt importance scoring based on access patterns
73
+ - [ ] Memory summarization — compress old episodes without losing key facts
74
+ - [ ] Confidence calibration — track how often recalled memories are actually useful
75
+
76
+ ### Why This Comes After Hosted
77
+ Intelligence features consume LLM tokens. Running them in the hosted service means users don't need their own LLM API keys. The hosted tier absorbs the cost and passes it through in usage pricing.
78
+
79
+ ---
80
+
81
+ ## Phase 4 — Ecosystem
82
+
83
+ **What:** Official integrations, protocol specification, developer ecosystem.
84
+
85
+ **Why it matters:** Engram's value multiplies when every agent framework can plug into it. An open protocol means the memory layer isn't locked to one vendor.
86
+
87
+ ### To Build
88
+ - [ ] OpenClaw integration — replace flat-file memory with structured Engram
89
+ - [ ] LangChain memory adapter
90
+ - [ ] CrewAI memory adapter
91
+ - [ ] Python SDK (thin client over REST)
92
+ - [ ] Protocol specification — open standard for agent memory interop
93
+ - [ ] Developer documentation site
94
+ - [ ] Multi-agent vault sharing (agents share memories with permissions)
95
+ - [ ] Cross-agent conflict resolution
96
+ - [ ] Webhook notifications on memory events
97
+ - [ ] Import/export adapters for other memory systems
98
+
99
+ ### The Protocol Vision
100
+ Agent memory shouldn't be locked to any framework or vendor. The Engram protocol spec defines a standard way for agents to store, recall, connect, and consolidate memories — regardless of implementation. Any tool can implement it, any agent can use it.
101
+
102
+ ---
103
+
104
+ ## Metrics
105
+
106
+ - Waitlist signups
107
+ - API keys issued
108
+ - Memories stored (hosted)
109
+ - Monthly active vaults
110
+ - Recall latency p50/p95
111
+ - Consolidation quality (manual eval)
112
+ - GitHub stars / npm downloads
113
+ - Integration adoption
@@ -0,0 +1,26 @@
1
+ app = "engram-api"
2
+ primary_region = "sjc"
3
+
4
+ [build]
5
+ dockerfile = "../Dockerfile"
6
+
7
+ [env]
8
+ NODE_ENV = "production"
9
+ ENGRAM_HOST = "0.0.0.0"
10
+ ENGRAM_PORT = "3800"
11
+ ENGRAM_CORS_ORIGIN = "*"
12
+
13
+ [http_service]
14
+ internal_port = 3800
15
+ force_https = true
16
+ auto_stop_machines = "stop"
17
+ auto_start_machines = true
18
+ min_machines_running = 1
19
+
20
+ [mounts]
21
+ source = "engram_data"
22
+ destination = "/data"
23
+
24
+ [[vm]]
25
+ size = "shared-cpu-1x"
26
+ memory = "512mb"
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env npx tsx
2
+ export {};
3
+ //# sourceMappingURL=auto-ingest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-ingest.d.ts","sourceRoot":"","sources":["../src/auto-ingest.ts"],"names":[],"mappings":""}
@@ -0,0 +1,334 @@
1
+ #!/usr/bin/env npx tsx
2
+ // ============================================================
3
+ // Auto-Ingest — Watch OpenClaw transcripts and extract memories
4
+ // ============================================================
5
+ //
6
+ // Reads the active session transcript, finds new messages since
7
+ // last run, chunks them, and sends to the Engram ingest pipeline.
8
+ //
9
+ // Usage:
10
+ // npx tsx src/auto-ingest.ts # One-shot
11
+ // npx tsx src/auto-ingest.ts --watch # Watch mode
12
+ // ENGRAM_API=http://localhost:3800 npx tsx src/auto-ingest.ts
13
+ //
14
+ // State tracked in: ~/.config/engram/ingest-state.json
15
+ import { readFileSync, writeFileSync, existsSync, readdirSync, statSync } from 'fs';
16
+ import { join } from 'path';
17
+ import { homedir } from 'os';
18
+ // ============================================================
19
+ // Config
20
+ // ============================================================
21
+ const ENGRAM_API = process.env.ENGRAM_API ?? 'http://127.0.0.1:3800/v1';
22
+ const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
23
+ const STATE_PATH = join(homedir(), '.config', 'engram', 'ingest-state.json');
24
+ const SESSIONS_DIR = join(homedir(), '.openclaw', 'agents', 'main', 'sessions');
25
+ // Minimum conversation chunk size worth ingesting (characters)
26
+ const MIN_CHUNK_SIZE = 200;
27
+ // Maximum chunk size to send to LLM at once
28
+ const MAX_CHUNK_SIZE = 4000;
29
+ // Skip messages shorter than this (trivial)
30
+ const MIN_MESSAGE_LENGTH = 20;
31
+ function loadState() {
32
+ if (existsSync(STATE_PATH)) {
33
+ return JSON.parse(readFileSync(STATE_PATH, 'utf-8'));
34
+ }
35
+ return {
36
+ lastIngestedLine: {},
37
+ lastRunAt: new Date(0).toISOString(),
38
+ totalMemoriesCreated: 0,
39
+ totalRunCount: 0,
40
+ };
41
+ }
42
+ function saveState(state) {
43
+ writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
44
+ }
45
+ function findActiveTranscript() {
46
+ if (!existsSync(SESSIONS_DIR))
47
+ return null;
48
+ const files = readdirSync(SESSIONS_DIR)
49
+ .filter(f => f.endsWith('.jsonl') && !f.includes('deleted'))
50
+ .map(f => ({
51
+ name: f,
52
+ path: join(SESSIONS_DIR, f),
53
+ mtime: statSync(join(SESSIONS_DIR, f)).mtimeMs,
54
+ }))
55
+ .sort((a, b) => b.mtime - a.mtime);
56
+ if (files.length === 0)
57
+ return null;
58
+ const latest = files[0];
59
+ const sessionId = latest.name.replace('.jsonl', '');
60
+ return { path: latest.path, sessionId };
61
+ }
62
+ function parseTranscript(filePath, startLine = 0) {
63
+ const content = readFileSync(filePath, 'utf-8');
64
+ const lines = content.split('\n').filter(l => l.trim());
65
+ const turns = [];
66
+ for (let i = startLine; i < lines.length; i++) {
67
+ try {
68
+ const entry = JSON.parse(lines[i]);
69
+ if (entry.type !== 'message' || !entry.message)
70
+ continue;
71
+ const role = entry.message.role;
72
+ if (role !== 'user' && role !== 'assistant')
73
+ continue;
74
+ // Extract text content (skip thinking, tool calls)
75
+ const textParts = (entry.message.content ?? [])
76
+ .filter((c) => c.type === 'text')
77
+ .map((c) => c.text)
78
+ .join('\n')
79
+ .trim();
80
+ if (!textParts || textParts.length < MIN_MESSAGE_LENGTH)
81
+ continue;
82
+ // Skip system messages and metadata
83
+ if (textParts.startsWith('System:') && !textParts.includes('MST]'))
84
+ continue;
85
+ // Clean up: remove system prefixes from user messages
86
+ let cleanText = textParts;
87
+ // Extract the actual human message from user turns (after the timestamp)
88
+ const humanMatch = cleanText.match(/\[.*?MST\]\s*(.*)/s);
89
+ if (role === 'user' && humanMatch) {
90
+ cleanText = humanMatch[1].trim();
91
+ }
92
+ // Skip if it's just system noise
93
+ if (cleanText.startsWith('System:') && cleanText.length < 100)
94
+ continue;
95
+ // Skip heartbeat acks
96
+ if (cleanText === 'HEARTBEAT_OK' || cleanText === 'NO_REPLY')
97
+ continue;
98
+ if (cleanText.length >= MIN_MESSAGE_LENGTH) {
99
+ turns.push({
100
+ role,
101
+ text: cleanText,
102
+ timestamp: entry.timestamp ?? new Date().toISOString(),
103
+ lineNumber: i,
104
+ });
105
+ }
106
+ }
107
+ catch {
108
+ // Skip malformed lines
109
+ }
110
+ }
111
+ return turns;
112
+ }
113
+ // ============================================================
114
+ // Chunking — group turns into conversation segments
115
+ // ============================================================
116
+ function chunkConversation(turns) {
117
+ const chunks = [];
118
+ let currentChunk = '';
119
+ for (const turn of turns) {
120
+ const prefix = turn.role === 'user' ? 'Human' : 'Agent';
121
+ const line = `${prefix}: ${turn.text}\n\n`;
122
+ if (currentChunk.length + line.length > MAX_CHUNK_SIZE && currentChunk.length >= MIN_CHUNK_SIZE) {
123
+ chunks.push(currentChunk.trim());
124
+ currentChunk = '';
125
+ }
126
+ currentChunk += line;
127
+ }
128
+ if (currentChunk.length >= MIN_CHUNK_SIZE) {
129
+ chunks.push(currentChunk.trim());
130
+ }
131
+ return chunks;
132
+ }
133
+ async function ingestChunk(chunk) {
134
+ // Use the LLM-powered ingest if available, otherwise fall back to simple remember
135
+ if (GEMINI_API_KEY) {
136
+ return await llmIngest(chunk);
137
+ }
138
+ else {
139
+ // Simple mode: store the chunk as a single episodic memory
140
+ const res = await fetch(`${ENGRAM_API}/ingest`, {
141
+ method: 'POST',
142
+ headers: { 'Content-Type': 'application/json' },
143
+ body: JSON.stringify({ text: chunk }),
144
+ });
145
+ return res.ok ? 1 : 0;
146
+ }
147
+ }
148
+ async function llmIngest(chunk) {
149
+ const prompt = `You are a memory extraction engine for an AI agent. Analyze this conversation segment and extract structured memories worth keeping long-term.
150
+
151
+ CONVERSATION:
152
+ ${chunk}
153
+
154
+ Extract memories that would be valuable to recall days or weeks from now. For each, provide:
155
+ - content: A clear, standalone statement (should make sense without the conversation)
156
+ - type: "episodic" (specific events/decisions), "semantic" (facts/preferences/patterns), or "procedural" (how-to/lessons)
157
+ - entities: People, projects, tools, places mentioned
158
+ - topics: Relevant topic tags
159
+ - salience: 0.0-1.0 (how important for future recall?)
160
+ - status: "active" (default), "pending" (if it's a commitment/plan not yet done)
161
+
162
+ Be SELECTIVE. Extract only what matters. Skip small talk, acknowledgments, and trivial exchanges.
163
+
164
+ Respond as JSON:
165
+ {"memories": [{"content": "...", "type": "...", "entities": ["..."], "topics": ["..."], "salience": 0.0-1.0, "status": "active|pending"}]}
166
+
167
+ If nothing worth remembering, respond: {"memories": []}`;
168
+ try {
169
+ const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${GEMINI_API_KEY}`, {
170
+ method: 'POST',
171
+ headers: { 'Content-Type': 'application/json' },
172
+ body: JSON.stringify({
173
+ contents: [{ parts: [{ text: prompt }] }],
174
+ generationConfig: { responseMimeType: 'application/json', maxOutputTokens: 2048 },
175
+ }),
176
+ });
177
+ if (!response.ok) {
178
+ if (response.status === 429) {
179
+ // Rate limited — back off and retry once
180
+ console.warn(`Gemini rate limited, waiting 15s and retrying...`);
181
+ await new Promise(resolve => setTimeout(resolve, 15000));
182
+ const retry = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${GEMINI_API_KEY}`, {
183
+ method: 'POST',
184
+ headers: { 'Content-Type': 'application/json' },
185
+ body: JSON.stringify({
186
+ contents: [{ parts: [{ text: prompt }] }],
187
+ generationConfig: { responseMimeType: 'application/json', maxOutputTokens: 2048 },
188
+ }),
189
+ });
190
+ if (!retry.ok) {
191
+ console.error(`Gemini API error after retry: ${retry.status}`);
192
+ return 0;
193
+ }
194
+ const retryData = await retry.json();
195
+ const retryText = retryData.candidates?.[0]?.content?.parts?.[0]?.text ?? '{}';
196
+ const retryParsed = JSON.parse(retryText);
197
+ // Process retry results below
198
+ let created = 0;
199
+ for (const mem of retryParsed.memories ?? []) {
200
+ if (mem.salience < 0.2)
201
+ continue;
202
+ if (/(?:sk-|api[_-]?key|password|token|secret)[:\s=]+\S{10,}/i.test(mem.content))
203
+ continue;
204
+ if (/AIza[a-zA-Z0-9_-]{30,}/.test(mem.content))
205
+ continue;
206
+ const res = await fetch(`${ENGRAM_API}/memories`, {
207
+ method: 'POST',
208
+ headers: { 'Content-Type': 'application/json' },
209
+ body: JSON.stringify({
210
+ content: mem.content,
211
+ type: mem.type ?? 'episodic',
212
+ entities: mem.entities ?? [],
213
+ topics: [...(mem.topics ?? []), 'auto-ingested'],
214
+ salience: mem.salience ?? 0.5,
215
+ status: mem.status ?? 'active',
216
+ source: { type: 'conversation' },
217
+ }),
218
+ });
219
+ if (res.ok)
220
+ created++;
221
+ }
222
+ return created;
223
+ }
224
+ console.error(`Gemini API error: ${response.status}`);
225
+ return 0;
226
+ }
227
+ const data = await response.json();
228
+ const text = data.candidates?.[0]?.content?.parts?.[0]?.text ?? '{}';
229
+ const parsed = JSON.parse(text);
230
+ let created = 0;
231
+ for (const mem of parsed.memories ?? []) {
232
+ if (mem.salience < 0.2)
233
+ continue; // Skip trivial
234
+ // Security: never store secrets
235
+ if (/(?:sk-|api[_-]?key|password|token|secret)[:\s=]+\S{10,}/i.test(mem.content))
236
+ continue;
237
+ if (/AIza[a-zA-Z0-9_-]{30,}/.test(mem.content))
238
+ continue; // Google API keys
239
+ const res = await fetch(`${ENGRAM_API}/memories`, {
240
+ method: 'POST',
241
+ headers: { 'Content-Type': 'application/json' },
242
+ body: JSON.stringify({
243
+ content: mem.content,
244
+ type: mem.type ?? 'episodic',
245
+ entities: mem.entities ?? [],
246
+ topics: [...(mem.topics ?? []), 'auto-ingested'],
247
+ salience: mem.salience ?? 0.5,
248
+ status: mem.status ?? 'active',
249
+ source: { type: 'conversation' },
250
+ }),
251
+ });
252
+ if (res.ok)
253
+ created++;
254
+ }
255
+ return created;
256
+ }
257
+ catch (err) {
258
+ console.error('LLM ingest error:', err);
259
+ return 0;
260
+ }
261
+ }
262
+ async function ingestNewMessages() {
263
+ const state = loadState();
264
+ const transcript = findActiveTranscript();
265
+ if (!transcript) {
266
+ console.log('No active transcript found.');
267
+ return { memoriesCreated: 0, chunks: 0 };
268
+ }
269
+ const startLine = state.lastIngestedLine[transcript.sessionId] ?? 0;
270
+ console.log(`Reading transcript ${transcript.sessionId} from line ${startLine}...`);
271
+ const turns = parseTranscript(transcript.path, startLine);
272
+ if (turns.length === 0) {
273
+ console.log('No new messages to ingest.');
274
+ return { memoriesCreated: 0, chunks: 0 };
275
+ }
276
+ console.log(`Found ${turns.length} new turns. Chunking...`);
277
+ const chunks = chunkConversation(turns);
278
+ console.log(`${chunks.length} chunks to process.`);
279
+ let totalCreated = 0;
280
+ for (let i = 0; i < chunks.length; i++) {
281
+ console.log(`Processing chunk ${i + 1}/${chunks.length}...`);
282
+ const created = await ingestChunk(chunks[i]);
283
+ totalCreated += created;
284
+ console.log(` → ${created} memories extracted`);
285
+ // Rate limit: wait between chunks to avoid 429s
286
+ if (i < chunks.length - 1) {
287
+ await new Promise(r => setTimeout(r, 5000));
288
+ }
289
+ }
290
+ // Update state
291
+ const lastLine = turns[turns.length - 1].lineNumber + 1;
292
+ state.lastIngestedLine[transcript.sessionId] = lastLine;
293
+ state.lastRunAt = new Date().toISOString();
294
+ state.totalMemoriesCreated += totalCreated;
295
+ state.totalRunCount++;
296
+ saveState(state);
297
+ console.log(`\nDone. ${totalCreated} memories created from ${chunks.length} chunks.`);
298
+ console.log(`Total across all runs: ${state.totalMemoriesCreated} memories in ${state.totalRunCount} runs.`);
299
+ return { memoriesCreated: totalCreated, chunks: chunks.length };
300
+ }
301
+ // ============================================================
302
+ // Main
303
+ // ============================================================
304
+ const isWatch = process.argv.includes('--watch');
305
+ // Interval in ms — default 5 min, configurable via ENGRAM_INGEST_INTERVAL_MS
306
+ const intervalMs = parseInt(process.env.ENGRAM_INGEST_INTERVAL_MS ?? '300000', 10);
307
+ if (isWatch) {
308
+ const mins = Math.round(intervalMs / 60000);
309
+ console.log(`🧠 Engram auto-ingest running in watch mode (every ${mins} min)...`);
310
+ let running = false;
311
+ const run = async () => {
312
+ if (running)
313
+ return; // skip if previous run still going
314
+ running = true;
315
+ try {
316
+ const result = await ingestNewMessages();
317
+ if (result && result.memoriesCreated > 0) {
318
+ console.log(` ✓ ${result.memoriesCreated} memories from ${result.chunks} chunks at ${new Date().toLocaleTimeString()}`);
319
+ }
320
+ }
321
+ catch (err) {
322
+ console.error('Ingest error:', err);
323
+ }
324
+ finally {
325
+ running = false;
326
+ }
327
+ };
328
+ run();
329
+ setInterval(run, intervalMs);
330
+ }
331
+ else {
332
+ ingestNewMessages().catch(console.error);
333
+ }
334
+ //# sourceMappingURL=auto-ingest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-ingest.js","sourceRoot":"","sources":["../src/auto-ingest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { Vault } from './vault.js';
2
+ import type { Memory } from './types.js';
3
+ export interface BriefOptions {
4
+ /** Who is the agent talking to? Boosts memories about this person. */
5
+ who?: string;
6
+ /** Current time (defaults to now). Affects temporal relevance. */
7
+ when?: Date;
8
+ /** Recent topic hints (from conversation opener, etc.) */
9
+ recentTopics?: string[];
10
+ /** Recent entity hints */
11
+ recentEntities?: string[];
12
+ /** Max memories to include in briefing */
13
+ maxMemories?: number;
14
+ /** Include behavioral patterns? (requires semantic memories from consolidation) */
15
+ includePatterns?: boolean;
16
+ }
17
+ export interface Briefing {
18
+ /** Structured summary suitable for agent context injection */
19
+ summary: string;
20
+ /** Key facts about the person we're talking to */
21
+ personContext: Memory[];
22
+ /** Active projects and recent work */
23
+ activeProjects: Memory[];
24
+ /** Recent interactions (last 2-3 sessions) */
25
+ recentInteractions: Memory[];
26
+ /** Behavioral patterns and preferences */
27
+ patterns: Memory[];
28
+ /** Unresolved commitments or pending items */
29
+ pendingItems: Memory[];
30
+ /** Procedural memories (how to handle things) */
31
+ procedures: Memory[];
32
+ /** All memories included, for debugging */
33
+ allMemories: Memory[];
34
+ /** Generation timestamp */
35
+ generatedAt: string;
36
+ }
37
+ /**
38
+ * Generate a context-aware session briefing.
39
+ *
40
+ * This replaces "read all the markdown files" with intelligent,
41
+ * targeted memory retrieval that gives the agent exactly what
42
+ * it needs for the current interaction.
43
+ */
44
+ export declare function brief(vault: Vault, options?: BriefOptions): Promise<Briefing>;
45
+ //# sourceMappingURL=brief.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brief.d.ts","sourceRoot":"","sources":["../src/brief.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,EAAuB,MAAM,YAAY,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,0BAA0B;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mFAAmF;IACnF,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,QAAQ;IACvB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,sCAAsC;IACtC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,8CAA8C;IAC9C,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,iDAAiD;IACjD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,2CAA2C;IAC3C,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAsB,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA4KvF"}