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/dist/server.js ADDED
@@ -0,0 +1,515 @@
1
+ #!/usr/bin/env node
2
+ import { Vault } from './vault.js';
3
+ import { OpenAIEmbeddings, GeminiEmbeddings } from './embeddings.js';
4
+ import { createServer } from 'node:http';
5
+ // Active vault instances
6
+ const vaultCache = new Map();
7
+ function getOrCreateVault(config) {
8
+ const key = `${config.owner}:${config.dbPath ?? 'default'}`;
9
+ let vault = vaultCache.get(key);
10
+ if (!vault) {
11
+ let embedder;
12
+ if (config.llm) {
13
+ if (config.llm.provider === 'gemini') {
14
+ embedder = new GeminiEmbeddings(config.llm.apiKey, config.llm.embeddingModel ?? 'gemini-embedding-001');
15
+ }
16
+ else {
17
+ embedder = new OpenAIEmbeddings(config.llm.apiKey, config.llm.embeddingModel ?? 'text-embedding-3-small');
18
+ }
19
+ }
20
+ vault = new Vault(config, embedder);
21
+ vaultCache.set(key, vault);
22
+ }
23
+ return vault;
24
+ }
25
+ // ============================================================
26
+ // Request parsing helpers
27
+ // ============================================================
28
+ async function readBody(req) {
29
+ const chunks = [];
30
+ for await (const chunk of req) {
31
+ chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
32
+ }
33
+ return Buffer.concat(chunks).toString('utf-8');
34
+ }
35
+ function json(res, status, data) {
36
+ res.writeHead(status, { 'Content-Type': 'application/json' });
37
+ res.end(JSON.stringify(data));
38
+ }
39
+ function error(res, status, message) {
40
+ json(res, status, { error: message });
41
+ }
42
+ const routes = [];
43
+ function route(method, path, handler) {
44
+ // Convert /v1/memories/:id to a regex with named groups
45
+ const paramNames = [];
46
+ const regexStr = path.replace(/:(\w+)/g, (_, name) => {
47
+ paramNames.push(name);
48
+ return '([^/]+)';
49
+ });
50
+ routes.push({ method, pattern: new RegExp(`^${regexStr}$`), paramNames, handler });
51
+ }
52
+ // ============================================================
53
+ // API Routes
54
+ // ============================================================
55
+ // POST /v1/memories — remember()
56
+ route('POST', '/v1/memories', async (req, res, vault) => {
57
+ const body = JSON.parse(await readBody(req));
58
+ const memory = vault.remember(body);
59
+ json(res, 201, memory);
60
+ });
61
+ // GET /v1/memories/recall?context=...&entities=...&topics=...&types=...&limit=...&spread=...
62
+ route('GET', '/v1/memories/recall', async (req, res, vault) => {
63
+ const url = new URL(req.url, `http://${req.headers.host}`);
64
+ const context = url.searchParams.get('context');
65
+ if (!context) {
66
+ error(res, 400, 'context query parameter is required');
67
+ return;
68
+ }
69
+ const input = { context };
70
+ const entities = url.searchParams.get('entities');
71
+ if (entities)
72
+ input.entities = entities.split(',');
73
+ const topics = url.searchParams.get('topics');
74
+ if (topics)
75
+ input.topics = topics.split(',');
76
+ const types = url.searchParams.get('types');
77
+ if (types)
78
+ input.types = types.split(',');
79
+ const limit = url.searchParams.get('limit');
80
+ if (limit)
81
+ input.limit = parseInt(limit, 10);
82
+ // Spreading activation params
83
+ const spread = url.searchParams.get('spread');
84
+ if (spread !== null)
85
+ input.spread = spread !== 'false' && spread !== '0';
86
+ const spreadHops = url.searchParams.get('spreadHops');
87
+ if (spreadHops)
88
+ input.spreadHops = parseInt(spreadHops, 10);
89
+ const spreadDecay = url.searchParams.get('spreadDecay');
90
+ if (spreadDecay)
91
+ input.spreadDecay = parseFloat(spreadDecay);
92
+ const spreadEntityHops = url.searchParams.get('spreadEntityHops');
93
+ if (spreadEntityHops !== null)
94
+ input.spreadEntityHops = spreadEntityHops !== 'false' && spreadEntityHops !== '0';
95
+ const memories = await vault.recall(input);
96
+ json(res, 200, { memories, count: memories.length });
97
+ });
98
+ // POST /v1/memories/recall — recall() with body (for complex queries)
99
+ route('POST', '/v1/memories/recall', async (req, res, vault) => {
100
+ const body = JSON.parse(await readBody(req));
101
+ const memories = await vault.recall(body);
102
+ json(res, 200, { memories, count: memories.length });
103
+ });
104
+ // DELETE /v1/memories/:id — forget()
105
+ route('DELETE', '/v1/memories/:id', (req, res, vault, params) => {
106
+ const url = new URL(req.url, `http://${req.headers.host}`);
107
+ const hard = url.searchParams.get('hard') === 'true';
108
+ vault.forget(params.id, hard);
109
+ json(res, 200, { deleted: params.id, hard });
110
+ });
111
+ // GET /v1/memories/:id/neighbors — neighbors()
112
+ route('GET', '/v1/memories/:id/neighbors', (req, res, vault, params) => {
113
+ const url = new URL(req.url, `http://${req.headers.host}`);
114
+ const depth = parseInt(url.searchParams.get('depth') ?? '1', 10);
115
+ const memories = vault.neighbors(params.id, depth);
116
+ json(res, 200, { memories, count: memories.length });
117
+ });
118
+ // POST /v1/connections — connect()
119
+ route('POST', '/v1/connections', async (req, res, vault) => {
120
+ const body = JSON.parse(await readBody(req));
121
+ const { sourceId, targetId, type, strength } = body;
122
+ if (!sourceId || !targetId || !type) {
123
+ error(res, 400, 'sourceId, targetId, and type are required');
124
+ return;
125
+ }
126
+ const edge = vault.connect(sourceId, targetId, type, strength);
127
+ json(res, 201, edge);
128
+ });
129
+ // POST /v1/consolidate — consolidate()
130
+ route('POST', '/v1/consolidate', async (req, res, vault) => {
131
+ const report = await vault.consolidate();
132
+ json(res, 200, report);
133
+ });
134
+ // GET /v1/entities — entities()
135
+ route('GET', '/v1/entities', (req, res, vault) => {
136
+ const entities = vault.entities();
137
+ json(res, 200, { entities, count: entities.length });
138
+ });
139
+ // GET /v1/stats — stats()
140
+ route('GET', '/v1/stats', (req, res, vault) => {
141
+ const stats = vault.stats();
142
+ json(res, 200, stats);
143
+ });
144
+ // POST /v1/export — export()
145
+ route('POST', '/v1/export', (req, res, vault) => {
146
+ const data = vault.export();
147
+ json(res, 200, data);
148
+ });
149
+ // POST /v1/embeddings/backfill — compute embeddings for all memories
150
+ route('POST', '/v1/embeddings/backfill', async (req, res, vault) => {
151
+ const count = await vault.backfillEmbeddings();
152
+ json(res, 200, { backfilled: count });
153
+ });
154
+ // POST /v1/ingest — auto-extract memories from raw conversation text
155
+ route('POST', '/v1/ingest', async (req, res, vault) => {
156
+ const body = JSON.parse(await readBody(req));
157
+ const { text, content, transcript } = body;
158
+ const rawText = text ?? content ?? transcript;
159
+ if (!rawText || typeof rawText !== 'string') {
160
+ error(res, 400, 'text, content, or transcript field is required (string)');
161
+ return;
162
+ }
163
+ // Simple mode: just remember() with auto-extraction (no LLM needed)
164
+ const memory = vault.remember({ content: rawText });
165
+ json(res, 201, memory);
166
+ });
167
+ // POST /v1/surface — proactive memory surfacing (memories pushed, not pulled)
168
+ route('POST', '/v1/surface', async (req, res, vault) => {
169
+ const body = JSON.parse(await readBody(req));
170
+ const { context, activeEntities, activeTopics, seen, minSalience, minHoursSinceAccess, limit, relevanceThreshold } = body;
171
+ if (!context || typeof context !== 'string') {
172
+ error(res, 400, 'context field is required (string)');
173
+ return;
174
+ }
175
+ const results = await vault.surface({
176
+ context,
177
+ activeEntities,
178
+ activeTopics,
179
+ seen,
180
+ minSalience,
181
+ minHoursSinceAccess,
182
+ limit,
183
+ relevanceThreshold,
184
+ });
185
+ json(res, 200, { surfaced: results, count: results.length });
186
+ });
187
+ // POST /v1/briefing — session briefing: structured context summary for session start
188
+ route('POST', '/v1/briefing', async (req, res, vault) => {
189
+ const body = JSON.parse(await readBody(req));
190
+ const context = body.context ?? body.topic ?? '';
191
+ const limit = body.limit ?? 20;
192
+ const briefing = await vault.briefing(context, limit);
193
+ json(res, 200, briefing);
194
+ });
195
+ // GET /v1/briefing — session briefing with optional context
196
+ route('GET', '/v1/briefing', async (req, res, vault) => {
197
+ const url = new URL(req.url, `http://${req.headers.host}`);
198
+ const context = url.searchParams.get('context') ?? '';
199
+ const limit = parseInt(url.searchParams.get('limit') ?? '20', 10);
200
+ const briefing = await vault.briefing(context, limit);
201
+ json(res, 200, briefing);
202
+ });
203
+ // POST /v1/shadow/compare — compare Engram briefing vs a memory file
204
+ // Shadow mode: run Engram alongside existing memory, see what each catches
205
+ route('POST', '/v1/shadow/compare', async (req, res, vault) => {
206
+ const body = JSON.parse(await readBody(req));
207
+ const memoryFileContent = body.memoryFile ?? '';
208
+ const context = body.context ?? '';
209
+ const limit = body.limit ?? 20;
210
+ if (!memoryFileContent) {
211
+ return error(res, 400, 'memoryFile is required (paste your CLAUDE.md / MEMORY.md content)');
212
+ }
213
+ // Get Engram briefing
214
+ const briefing = await vault.briefing(context, limit);
215
+ // Collect all surfaced items from briefing sections
216
+ const surfacedItems = [
217
+ ...briefing.keyFacts.map((f) => f.content),
218
+ ...briefing.activeCommitments.map((c) => c.content),
219
+ ...briefing.recentActivity.map((a) => a.content),
220
+ ];
221
+ // Simple line-level analysis: what does Engram surface that the file doesn't mention?
222
+ const fileLower = memoryFileContent.toLowerCase();
223
+ const engramOnly = [];
224
+ const bothHave = [];
225
+ for (const item of surfacedItems) {
226
+ const keywords = item
227
+ .toLowerCase()
228
+ .split(/\s+/)
229
+ .filter((w) => w.length > 4)
230
+ .slice(0, 5);
231
+ const matchCount = keywords.filter((kw) => fileLower.includes(kw)).length;
232
+ const matchRatio = keywords.length > 0 ? matchCount / keywords.length : 0;
233
+ if (matchRatio < 0.4) {
234
+ engramOnly.push(item.slice(0, 150));
235
+ }
236
+ else {
237
+ bothHave.push(item.slice(0, 150));
238
+ }
239
+ }
240
+ // Check what's in the file but Engram didn't surface
241
+ const fileLines = memoryFileContent
242
+ .split('\n')
243
+ .map((l) => l.replace(/^[\s\-*#>]+/, '').trim())
244
+ .filter((l) => l.length > 20);
245
+ const fileOnly = [];
246
+ const briefingText = surfacedItems.map((s) => s.toLowerCase()).join(' ');
247
+ for (const line of fileLines) {
248
+ const lineKeywords = line.toLowerCase().split(/\s+/).filter((w) => w.length > 4).slice(0, 5);
249
+ const matchCount = lineKeywords.filter((kw) => briefingText.includes(kw)).length;
250
+ const matchRatio = lineKeywords.length > 0 ? matchCount / lineKeywords.length : 0;
251
+ if (matchRatio < 0.3) {
252
+ fileOnly.push(line.slice(0, 150));
253
+ }
254
+ }
255
+ json(res, 200, {
256
+ summary: {
257
+ engramSurfaced: surfacedItems.length,
258
+ engramOnly: engramOnly.length,
259
+ fileOnly: fileOnly.length,
260
+ overlap: bothHave.length,
261
+ },
262
+ engramOnly: engramOnly.slice(0, 20),
263
+ fileOnly: fileOnly.slice(0, 20),
264
+ overlap: bothHave.slice(0, 10),
265
+ briefing: briefing.summary,
266
+ });
267
+ });
268
+ // POST /v1/ingest/realtime — Real-time memory extraction from conversation text
269
+ // Send a message or conversation snippet, get memories extracted and stored instantly
270
+ route('POST', '/v1/ingest/realtime', async (req, res, vault) => {
271
+ const body = JSON.parse(await readBody(req));
272
+ const text = body.text ?? '';
273
+ const geminiKey = process.env.GEMINI_API_KEY ?? process.env.ENGRAM_LLM_API_KEY;
274
+ if (!text) {
275
+ return error(res, 400, 'text is required');
276
+ }
277
+ if (!geminiKey) {
278
+ // Fallback: store as single memory using rule-based extraction
279
+ const { extract } = await import('./extract.js');
280
+ const extracted = extract(text);
281
+ const mem = await vault.remember({
282
+ content: text.slice(0, 500),
283
+ type: 'episodic',
284
+ entities: extracted.entities,
285
+ topics: extracted.topics,
286
+ salience: extracted.suggestedSalience,
287
+ source: { type: 'conversation' },
288
+ });
289
+ return json(res, 200, { created: 1, memories: [{ id: mem.id, content: mem.content }] });
290
+ }
291
+ // LLM-powered extraction
292
+ const prompt = `You are a memory extraction engine for an AI agent. Analyze this conversation segment and extract structured memories worth keeping long-term.
293
+
294
+ CONVERSATION:
295
+ ${text}
296
+
297
+ Extract memories that would be valuable to recall days or weeks from now. For each, provide:
298
+ - content: A clear, standalone statement (should make sense without the conversation)
299
+ - type: "episodic" (specific events), "semantic" (facts/preferences), or "procedural" (how-to/lessons)
300
+ - entities: People, projects, tools, places mentioned
301
+ - topics: Relevant topic tags
302
+ - salience: 0.0-1.0 (how important for future recall?)
303
+ - status: "active" (default), "pending" (if it's a commitment/plan not yet done)
304
+
305
+ Be SELECTIVE. Only extract what matters. Skip small talk and trivial exchanges.
306
+
307
+ Respond as JSON:
308
+ {"memories": [{"content": "...", "type": "...", "entities": ["..."], "topics": ["..."], "salience": 0.0-1.0, "status": "active|pending"}]}`;
309
+ try {
310
+ const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${geminiKey}`, {
311
+ method: 'POST',
312
+ headers: { 'Content-Type': 'application/json' },
313
+ body: JSON.stringify({
314
+ contents: [{ parts: [{ text: prompt }] }],
315
+ generationConfig: { responseMimeType: 'application/json', maxOutputTokens: 2048 },
316
+ }),
317
+ });
318
+ if (!response.ok) {
319
+ return error(res, 502, `LLM extraction failed: ${response.status}`);
320
+ }
321
+ const data = await response.json();
322
+ const llmText = data.candidates?.[0]?.content?.parts?.[0]?.text ?? '{}';
323
+ const parsed = JSON.parse(llmText);
324
+ const created = [];
325
+ for (const mem of parsed.memories ?? []) {
326
+ if (mem.salience < 0.2)
327
+ continue;
328
+ // Security: never store secrets
329
+ if (/(?:sk-|api[_-]?key|password|token|secret)[:\s=]+\S{10,}/i.test(mem.content))
330
+ continue;
331
+ if (/AIza[a-zA-Z0-9_-]{30,}/.test(mem.content))
332
+ continue;
333
+ const stored = await vault.remember({
334
+ content: mem.content,
335
+ type: mem.type ?? 'episodic',
336
+ entities: mem.entities ?? [],
337
+ topics: [...(mem.topics ?? []), 'realtime'],
338
+ salience: mem.salience ?? 0.5,
339
+ status: mem.status ?? 'active',
340
+ source: { type: 'conversation' },
341
+ });
342
+ created.push({ id: stored.id, content: stored.content });
343
+ }
344
+ json(res, 200, { created: created.length, memories: created });
345
+ }
346
+ catch (err) {
347
+ error(res, 500, `Extraction error: ${err.message}`);
348
+ }
349
+ });
350
+ // GET /v1/contradictions — list unresolved contradictions
351
+ route('GET', '/v1/contradictions', (req, res, vault) => {
352
+ const url = new URL(req.url, `http://${req.headers.host}`);
353
+ const limit = parseInt(url.searchParams.get('limit') ?? '50', 10);
354
+ const contradictions = vault.contradictions(limit);
355
+ json(res, 200, { contradictions, count: contradictions.length });
356
+ });
357
+ // GET /health — health check
358
+ route('GET', '/health', (req, res) => {
359
+ json(res, 200, { status: 'ok', version: '0.1.0', timestamp: new Date().toISOString() });
360
+ });
361
+ // ============================================================
362
+ // Server
363
+ // ============================================================
364
+ export function createEngramServer(config) {
365
+ const preferredPort = config.port ?? 3800;
366
+ const host = config.host ?? '127.0.0.1';
367
+ // Optional auth token for single-tenant mode (set ENGRAM_AUTH_TOKEN to enable)
368
+ const authToken = process.env.ENGRAM_AUTH_TOKEN;
369
+ function resolveVault(req) {
370
+ // Single-tenant mode
371
+ if (config.defaultVault) {
372
+ // If auth token is set, enforce it
373
+ if (authToken) {
374
+ const authHeader = req.headers.authorization;
375
+ if (!authHeader?.startsWith('Bearer ') || authHeader.slice(7) !== authToken) {
376
+ return null;
377
+ }
378
+ }
379
+ return getOrCreateVault(config.defaultVault);
380
+ }
381
+ // Multi-tenant: resolve from Authorization header
382
+ const authHeader = req.headers.authorization;
383
+ if (!authHeader?.startsWith('Bearer '))
384
+ return null;
385
+ const apiKey = authHeader.slice(7);
386
+ const vaultConfig = config.vaults[apiKey];
387
+ if (!vaultConfig)
388
+ return null;
389
+ return getOrCreateVault(vaultConfig);
390
+ }
391
+ const server = createServer(async (req, res) => {
392
+ // CORS — restrict to localhost by default, configurable via ENGRAM_CORS_ORIGIN
393
+ const allowedOrigin = process.env.ENGRAM_CORS_ORIGIN ?? 'http://localhost:*';
394
+ const requestOrigin = req.headers.origin ?? '';
395
+ if (allowedOrigin === '*' || requestOrigin.startsWith('http://localhost') || requestOrigin.startsWith('http://127.0.0.1')) {
396
+ res.setHeader('Access-Control-Allow-Origin', requestOrigin || 'http://localhost');
397
+ }
398
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
399
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
400
+ if (req.method === 'OPTIONS') {
401
+ res.writeHead(204);
402
+ res.end();
403
+ return;
404
+ }
405
+ const url = new URL(req.url, `http://${req.headers.host}`);
406
+ const pathname = url.pathname;
407
+ // Match route
408
+ for (const r of routes) {
409
+ if (req.method !== r.method)
410
+ continue;
411
+ const match = pathname.match(r.pattern);
412
+ if (!match)
413
+ continue;
414
+ // Extract params
415
+ const params = {};
416
+ r.paramNames.forEach((name, i) => { params[name] = match[i + 1]; });
417
+ // Health check doesn't need a vault
418
+ if (pathname === '/health') {
419
+ try {
420
+ await r.handler(req, res, null, params);
421
+ }
422
+ catch (err) {
423
+ error(res, 500, err.message ?? 'Internal server error');
424
+ }
425
+ return;
426
+ }
427
+ // Resolve vault
428
+ const vault = resolveVault(req);
429
+ if (!vault) {
430
+ error(res, 401, 'Invalid or missing API key');
431
+ return;
432
+ }
433
+ try {
434
+ await r.handler(req, res, vault, params);
435
+ }
436
+ catch (err) {
437
+ console.error(`Error handling ${req.method} ${pathname}:`, err);
438
+ error(res, 500, err.message ?? 'Internal server error');
439
+ }
440
+ return;
441
+ }
442
+ error(res, 404, `Not found: ${req.method} ${pathname}`);
443
+ });
444
+ return {
445
+ listen: () => new Promise((resolve) => {
446
+ server.listen(preferredPort, host, () => {
447
+ const addr = server.address();
448
+ console.log(`🧠 Engram API server listening on http://${host}:${addr.port}`);
449
+ resolve();
450
+ });
451
+ }),
452
+ close: async () => {
453
+ // Flush and close all vaults (await pending embeddings)
454
+ const closePromises = [...vaultCache.values()].map(v => v.close());
455
+ await Promise.allSettled(closePromises);
456
+ vaultCache.clear();
457
+ await new Promise((resolve) => server.close(() => resolve()));
458
+ },
459
+ server,
460
+ };
461
+ }
462
+ // ============================================================
463
+ // CLI entry point
464
+ // ============================================================
465
+ if (process.argv[1]?.endsWith('server.ts') || process.argv[1]?.endsWith('server.js')) {
466
+ const owner = process.env.ENGRAM_OWNER ?? 'default';
467
+ const dbPath = process.env.ENGRAM_DB_PATH;
468
+ const port = parseInt(process.env.ENGRAM_PORT ?? '0', 10);
469
+ const host = process.env.ENGRAM_HOST ?? '127.0.0.1';
470
+ const llmProvider = process.env.ENGRAM_LLM_PROVIDER;
471
+ const llmApiKey = process.env.ENGRAM_LLM_API_KEY ?? (llmProvider === 'gemini' ? process.env.GEMINI_API_KEY : undefined);
472
+ const llmModel = process.env.ENGRAM_LLM_MODEL;
473
+ const vaultConfig = {
474
+ owner,
475
+ ...(dbPath ? { dbPath } : {}),
476
+ ...(llmProvider && llmApiKey ? {
477
+ llm: { provider: llmProvider, apiKey: llmApiKey, model: llmModel },
478
+ } : {}),
479
+ };
480
+ const srv = createEngramServer({
481
+ port,
482
+ host,
483
+ vaults: {},
484
+ defaultVault: vaultConfig,
485
+ });
486
+ srv.listen().then(() => {
487
+ console.log(`Vault owner: ${owner}`);
488
+ console.log(`Database: ${dbPath ?? `engram-${owner}.db`}`);
489
+ if (llmProvider)
490
+ console.log(`LLM: ${llmProvider} (${llmModel ?? 'default'})`);
491
+ console.log('\nEndpoints:');
492
+ console.log(' POST /v1/memories — Store a memory');
493
+ console.log(' GET /v1/memories/recall — Recall memories');
494
+ console.log(' POST /v1/memories/recall — Recall (complex query)');
495
+ console.log(' DELETE /v1/memories/:id — Forget a memory');
496
+ console.log(' GET /v1/memories/:id/neighbors — Graph traversal');
497
+ console.log(' POST /v1/connections — Connect memories');
498
+ console.log(' POST /v1/consolidate — Run consolidation');
499
+ console.log(' GET /v1/entities — List entities');
500
+ console.log(' GET /v1/stats — Vault statistics');
501
+ console.log(' POST /v1/export — Export vault');
502
+ console.log(' GET /health — Health check');
503
+ });
504
+ // Graceful shutdown
505
+ process.on('SIGINT', async () => {
506
+ console.log('\nShutting down...');
507
+ await srv.close();
508
+ process.exit(0);
509
+ });
510
+ process.on('SIGTERM', async () => {
511
+ await srv.close();
512
+ process.exit(0);
513
+ });
514
+ }
515
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import type { Memory, Edge, Entity, RememberParsed } from './types.js';
2
+ export declare class MemoryStore {
3
+ private db;
4
+ private vecEnabled;
5
+ private embeddingDimensions;
6
+ constructor(dbPath: string, embeddingDimensions?: number);
7
+ private migrate;
8
+ createMemory(input: RememberParsed): Memory;
9
+ getMemory(id: string): Memory | null;
10
+ /** Read a memory without updating access stats (for graph traversal, activation spreading) */
11
+ getMemoryDirect(id: string): Memory | null;
12
+ /** Get all memories by a list of IDs without updating access stats */
13
+ getMemoriesDirect(ids: string[]): Memory[];
14
+ updateMemory(id: string, updates: Partial<Pick<Memory, 'content' | 'summary' | 'salience' | 'confidence' | 'entities' | 'topics'>>): void;
15
+ /** Update a memory's status (active, pending, fulfilled, superseded, archived) */
16
+ updateStatus(id: string, status: string): void;
17
+ deleteMemory(id: string): void;
18
+ /** Get recent memories, ordered by creation time */
19
+ getRecent(limit?: number): Memory[];
20
+ /** Get memories by entity */
21
+ getByEntity(entityName: string, limit?: number): Memory[];
22
+ /** Get memories by topic */
23
+ getByTopic(topic: string, limit?: number): Memory[];
24
+ /** Get memories by status */
25
+ getByStatus(status: string, limit?: number): Memory[];
26
+ /** Get memories by type */
27
+ getByType(type: string, limit?: number): Memory[];
28
+ /** Full-text search on content */
29
+ search(query: string, limit?: number): Memory[];
30
+ /** Get all memories (for consolidation) */
31
+ getEpisodicSince(since: string, limit?: number): Memory[];
32
+ /** Get memories below stability threshold (candidates for archival) */
33
+ getDecayedMemories(threshold?: number): Memory[];
34
+ /** Count memories by type */
35
+ getStats(): {
36
+ total: number;
37
+ episodic: number;
38
+ semantic: number;
39
+ procedural: number;
40
+ entities: number;
41
+ };
42
+ createEdge(sourceId: string, targetId: string, type: Edge['type'] | string, strength?: number): Edge;
43
+ getEdgesFrom(memoryId: string): Edge[];
44
+ getEdgesTo(memoryId: string): Edge[];
45
+ /** Get all edges connected to a memory (both directions) */
46
+ getEdgesBidirectional(memoryId: string): Edge[];
47
+ /** Batch: get all edges for a set of memory IDs (both directions) */
48
+ getEdgesForMemories(memoryIds: string[]): Edge[];
49
+ /** Get memories that share entities with the given memory */
50
+ getCoEntityMemories(memoryId: string, limit?: number): Array<{
51
+ memory: Memory;
52
+ sharedEntities: string[];
53
+ }>;
54
+ getNeighbors(memoryId: string, depth?: number): Memory[];
55
+ upsertEntity(name: string, type?: string): Entity;
56
+ getEntity(name: string): Entity | null;
57
+ getAllEntities(): Entity[];
58
+ /** Store an embedding for a memory */
59
+ storeEmbedding(memoryId: string, embedding: number[]): void;
60
+ /** Find nearest neighbors by embedding vector */
61
+ searchByVector(embedding: number[], limit?: number): Array<{
62
+ memoryId: string;
63
+ distance: number;
64
+ }>;
65
+ /** Check if vector search is available */
66
+ hasVectorSearch(): boolean;
67
+ /** Get the stored embedding for a memory (for dedup checks) */
68
+ getEmbedding(memoryId: string): number[] | null;
69
+ /** Find memories with very high semantic similarity (for dedup) */
70
+ findSimilar(embedding: number[], threshold?: number, limit?: number): Array<{
71
+ memoryId: string;
72
+ distance: number;
73
+ similarity: number;
74
+ }>;
75
+ /** Apply time-based decay to all memories */
76
+ applyDecay(halfLifeHours?: number): number;
77
+ exportAll(): {
78
+ memories: Memory[];
79
+ edges: Edge[];
80
+ entities: Entity[];
81
+ };
82
+ private rowToMemory;
83
+ private rowToEdge;
84
+ private rowToEntity;
85
+ close(): void;
86
+ }
87
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}