adaptive-context-memory 1.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.
Files changed (70) hide show
  1. package/README.md +104 -0
  2. package/dist/core/llmClient.d.ts +14 -0
  3. package/dist/core/llmClient.d.ts.map +1 -0
  4. package/dist/core/llmClient.js +68 -0
  5. package/dist/core/llmClient.js.map +1 -0
  6. package/dist/core/retry.d.ts +21 -0
  7. package/dist/core/retry.d.ts.map +1 -0
  8. package/dist/core/retry.js +68 -0
  9. package/dist/core/retry.js.map +1 -0
  10. package/dist/core/settings.d.ts +46 -0
  11. package/dist/core/settings.d.ts.map +1 -0
  12. package/dist/core/settings.js +133 -0
  13. package/dist/core/settings.js.map +1 -0
  14. package/dist/db/database.d.ts +50 -0
  15. package/dist/db/database.d.ts.map +1 -0
  16. package/dist/db/database.js +157 -0
  17. package/dist/db/database.js.map +1 -0
  18. package/dist/demo.d.ts +16 -0
  19. package/dist/demo.d.ts.map +1 -0
  20. package/dist/demo.js +305 -0
  21. package/dist/demo.js.map +1 -0
  22. package/dist/index.d.ts +16 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +33 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/memory/add/extractionPhase.d.ts +17 -0
  27. package/dist/memory/add/extractionPhase.d.ts.map +1 -0
  28. package/dist/memory/add/extractionPhase.js +48 -0
  29. package/dist/memory/add/extractionPhase.js.map +1 -0
  30. package/dist/memory/add/updatePhase.d.ts +11 -0
  31. package/dist/memory/add/updatePhase.d.ts.map +1 -0
  32. package/dist/memory/add/updatePhase.js +133 -0
  33. package/dist/memory/add/updatePhase.js.map +1 -0
  34. package/dist/memory/bubbleCreator.d.ts +10 -0
  35. package/dist/memory/bubbleCreator.d.ts.map +1 -0
  36. package/dist/memory/bubbleCreator.js +46 -0
  37. package/dist/memory/bubbleCreator.js.map +1 -0
  38. package/dist/memory/connectionFinder.d.ts +14 -0
  39. package/dist/memory/connectionFinder.d.ts.map +1 -0
  40. package/dist/memory/connectionFinder.js +56 -0
  41. package/dist/memory/connectionFinder.js.map +1 -0
  42. package/dist/memory/embeddings.d.ts +27 -0
  43. package/dist/memory/embeddings.d.ts.map +1 -0
  44. package/dist/memory/embeddings.js +145 -0
  45. package/dist/memory/embeddings.js.map +1 -0
  46. package/dist/memory/extractor.d.ts +20 -0
  47. package/dist/memory/extractor.d.ts.map +1 -0
  48. package/dist/memory/extractor.js +60 -0
  49. package/dist/memory/extractor.js.map +1 -0
  50. package/dist/memory/memory.d.ts +80 -0
  51. package/dist/memory/memory.d.ts.map +1 -0
  52. package/dist/memory/memory.js +342 -0
  53. package/dist/memory/memory.js.map +1 -0
  54. package/dist/memory/toolClassifier.d.ts +13 -0
  55. package/dist/memory/toolClassifier.d.ts.map +1 -0
  56. package/dist/memory/toolClassifier.js +53 -0
  57. package/dist/memory/toolClassifier.js.map +1 -0
  58. package/dist/memory/vectorStore.d.ts +40 -0
  59. package/dist/memory/vectorStore.d.ts.map +1 -0
  60. package/dist/memory/vectorStore.js +168 -0
  61. package/dist/memory/vectorStore.js.map +1 -0
  62. package/dist/summary/summaryGenerator.d.ts +14 -0
  63. package/dist/summary/summaryGenerator.d.ts.map +1 -0
  64. package/dist/summary/summaryGenerator.js +66 -0
  65. package/dist/summary/summaryGenerator.js.map +1 -0
  66. package/dist/utils/prompts.d.ts +7 -0
  67. package/dist/utils/prompts.d.ts.map +1 -0
  68. package/dist/utils/prompts.js +133 -0
  69. package/dist/utils/prompts.js.map +1 -0
  70. package/package.json +42 -0
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ /**
3
+ * SQLite Database — TypeScript port using better-sqlite3 + Drizzle ORM schema.
4
+ *
5
+ * Tables:
6
+ * conversations — one row per conversation
7
+ * messages — chat turns (user / assistant)
8
+ * conversation_summary — rolling LLM-generated summary
9
+ * memories — semantic & episodic memory facts
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.getDb = getDb;
49
+ exports.resetDb = resetDb;
50
+ exports.createTables = createTables;
51
+ exports.parseEmbedding = parseEmbedding;
52
+ exports.parseMeta = parseMeta;
53
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
54
+ const path = __importStar(require("path"));
55
+ const fs = __importStar(require("fs"));
56
+ const settings_js_1 = require("../core/settings.js");
57
+ // ─── Singleton DB handle ────────────────────────────────────────────────────
58
+ let _db = null;
59
+ function getDb() {
60
+ if (!_db) {
61
+ const s = (0, settings_js_1.getSettings)();
62
+ const dbPath = s.getDatabaseUrl(); // returns an absolute file path
63
+ const dir = path.dirname(dbPath);
64
+ fs.mkdirSync(dir, { recursive: true });
65
+ _db = new better_sqlite3_1.default(dbPath);
66
+ _db.pragma("journal_mode = WAL");
67
+ _db.pragma("foreign_keys = ON");
68
+ if (s.debug)
69
+ console.log(`[ContextMemory] DB connected: ${dbPath}`);
70
+ }
71
+ return _db;
72
+ }
73
+ /** Close and reset the DB connection (useful for testing) */
74
+ function resetDb() {
75
+ if (_db) {
76
+ _db.close();
77
+ _db = null;
78
+ }
79
+ }
80
+ // ─── Schema bootstrap ───────────────────────────────────────────────────────
81
+ function createTables() {
82
+ const db = getDb();
83
+ db.exec(`
84
+ CREATE TABLE IF NOT EXISTS conversations (
85
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
86
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
87
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
88
+ );
89
+
90
+ CREATE TABLE IF NOT EXISTS messages (
91
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
92
+ conversation_id INTEGER NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
93
+ sender TEXT NOT NULL CHECK(sender IN ('user', 'assistant')),
94
+ message_text TEXT NOT NULL,
95
+ timestamp TEXT NOT NULL DEFAULT (datetime('now'))
96
+ );
97
+
98
+ CREATE TABLE IF NOT EXISTS conversation_summary (
99
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
100
+ conversation_id INTEGER NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
101
+ summary_text TEXT,
102
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
103
+ );
104
+
105
+ CREATE TABLE IF NOT EXISTS memories (
106
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
107
+ conversation_id INTEGER NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
108
+ memory_text TEXT NOT NULL,
109
+ category TEXT,
110
+ embedding TEXT,
111
+ memory_metadata TEXT DEFAULT '{}',
112
+ is_episodic INTEGER NOT NULL DEFAULT 0,
113
+ occurred_at TEXT,
114
+ session_id INTEGER,
115
+ importance REAL NOT NULL DEFAULT 0.5,
116
+ is_active INTEGER NOT NULL DEFAULT 1,
117
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
118
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
119
+ );
120
+
121
+ CREATE INDEX IF NOT EXISTS idx_memories_conv ON memories(conversation_id);
122
+ CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(category);
123
+ CREATE INDEX IF NOT EXISTS idx_memories_active ON memories(is_active);
124
+ CREATE INDEX IF NOT EXISTS idx_messages_conv ON messages(conversation_id);
125
+ `);
126
+ // Migration: add category column to existing DBs that don't have it
127
+ try {
128
+ db.exec(`ALTER TABLE memories ADD COLUMN category TEXT`);
129
+ }
130
+ catch {
131
+ // Column already exists — ignore
132
+ }
133
+ if ((0, settings_js_1.getSettings)().debug)
134
+ console.log("[ContextMemory] Tables ready.");
135
+ }
136
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
137
+ function parseEmbedding(row) {
138
+ if (!row.embedding)
139
+ return null;
140
+ try {
141
+ return JSON.parse(row.embedding);
142
+ }
143
+ catch {
144
+ return null;
145
+ }
146
+ }
147
+ function parseMeta(row) {
148
+ if (!row.memory_metadata)
149
+ return {};
150
+ try {
151
+ return JSON.parse(row.memory_metadata);
152
+ }
153
+ catch {
154
+ return {};
155
+ }
156
+ }
157
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWH,sBAYC;AAGD,0BAKC;AAGD,oCAuDC;AAyCD,wCAGC;AAED,8BAGC;AAxID,oEAAsC;AACtC,2CAA6B;AAC7B,uCAAyB;AAEzB,qDAAkD;AAElD,+EAA+E;AAC/E,IAAI,GAAG,GAA6B,IAAI,CAAC;AAEzC,SAAgB,KAAK;IACnB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,CAAC,GAAG,IAAA,yBAAW,GAAE,CAAC;QACxB,MAAM,MAAM,GAAG,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,gCAAgC;QACnE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACjC,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,GAAG,GAAG,IAAI,wBAAQ,CAAC,MAAM,CAAC,CAAC;QAC3B,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACjC,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAChC,IAAI,CAAC,CAAC,KAAK;YAAE,OAAO,CAAC,GAAG,CAAC,iCAAiC,MAAM,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6DAA6D;AAC7D,SAAgB,OAAO;IACrB,IAAI,GAAG,EAAE,CAAC;QACR,GAAG,CAAC,KAAK,EAAE,CAAC;QACZ,GAAG,GAAG,IAAI,CAAC;IACb,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,SAAgB,YAAY;IAC1B,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IAEnB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CP,CAAC,CAAC;IAEH,oEAAoE;IACpE,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,iCAAiC;IACnC,CAAC;IAED,IAAI,IAAA,yBAAW,GAAE,CAAC,KAAK;QAAE,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;AACxE,CAAC;AAwCD,gFAAgF;AAChF,SAAgB,cAAc,CAAC,GAAc;IAC3C,IAAI,CAAC,GAAG,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QAAC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAa,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AAC9E,CAAC;AAED,SAAgB,SAAS,CAAC,GAAc;IACtC,IAAI,CAAC,GAAG,CAAC,eAAe;QAAE,OAAO,EAAE,CAAC;IACpC,IAAI,CAAC;QAAC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAA4B,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACjG,CAAC"}
package/dist/demo.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * ContextMemory TypeScript Demo
3
+ * ═══════════════════════════════════════════════════════════════
4
+ *
5
+ * Interactive CLI demo showing all ContextMemory features:
6
+ * - add() → extracts semantic facts + episodic bubbles
7
+ * - search() → cosine similarity + recency/importance scoring
8
+ * - getAll() → list all stored memories
9
+ * - update() → re-embed and update a memory
10
+ * - delete() → soft-delete from DB + vector store
11
+ *
12
+ * Run: npx ts-node src/demo.ts
13
+ * ═══════════════════════════════════════════════════════════════
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=demo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../src/demo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
package/dist/demo.js ADDED
@@ -0,0 +1,305 @@
1
+ "use strict";
2
+ /**
3
+ * ContextMemory TypeScript Demo
4
+ * ═══════════════════════════════════════════════════════════════
5
+ *
6
+ * Interactive CLI demo showing all ContextMemory features:
7
+ * - add() → extracts semantic facts + episodic bubbles
8
+ * - search() → cosine similarity + recency/importance scoring
9
+ * - getAll() → list all stored memories
10
+ * - update() → re-embed and update a memory
11
+ * - delete() → soft-delete from DB + vector store
12
+ *
13
+ * Run: npx ts-node src/demo.ts
14
+ * ═══════════════════════════════════════════════════════════════
15
+ */
16
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ var desc = Object.getOwnPropertyDescriptor(m, k);
19
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
+ desc = { enumerable: true, get: function() { return m[k]; } };
21
+ }
22
+ Object.defineProperty(o, k2, desc);
23
+ }) : (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ o[k2] = m[k];
26
+ }));
27
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29
+ }) : function(o, v) {
30
+ o["default"] = v;
31
+ });
32
+ var __importStar = (this && this.__importStar) || (function () {
33
+ var ownKeys = function(o) {
34
+ ownKeys = Object.getOwnPropertyNames || function (o) {
35
+ var ar = [];
36
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
37
+ return ar;
38
+ };
39
+ return ownKeys(o);
40
+ };
41
+ return function (mod) {
42
+ if (mod && mod.__esModule) return mod;
43
+ var result = {};
44
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
45
+ __setModuleDefault(result, mod);
46
+ return result;
47
+ };
48
+ })();
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ const readline = __importStar(require("readline"));
51
+ const index_js_1 = require("./index.js");
52
+ // ─── Config ─────────────────────────────────────────────────────────────────
53
+ (0, index_js_1.configure)({
54
+ openrouterApiKey: process.env.OPENROUTER_API_KEY,
55
+ openaiApiKey: process.env.OPENAI_API_KEY,
56
+ llmProvider: process.env.OPENROUTER_API_KEY ? "openrouter" : "openai",
57
+ llmModel: process.env.LLM_MODEL ?? "openai/gpt-4o-mini",
58
+ embeddingModel: process.env.EMBEDDING_MODEL ?? "text-embedding-3-small",
59
+ debug: process.env.DEBUG === "true",
60
+ });
61
+ (0, index_js_1.createTables)();
62
+ const db = (0, index_js_1.getDb)();
63
+ const mem = new index_js_1.ContextMemory(db);
64
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
65
+ const CYAN = "\x1b[36m";
66
+ const GREEN = "\x1b[32m";
67
+ const YELLOW = "\x1b[33m";
68
+ const DIM = "\x1b[2m";
69
+ const RESET = "\x1b[0m";
70
+ const BOLD = "\x1b[1m";
71
+ const RED = "\x1b[31m";
72
+ function log(msg) {
73
+ console.log(msg);
74
+ }
75
+ function hr(char = "─") {
76
+ log(DIM + char.repeat(60) + RESET);
77
+ }
78
+ function header(title) {
79
+ hr("═");
80
+ log(BOLD + CYAN + ` ${title}` + RESET);
81
+ hr("═");
82
+ }
83
+ /** Ensure a conversation row exists and return its ID */
84
+ function ensureConversation(id) {
85
+ if (id != null) {
86
+ const exists = db.prepare("SELECT id FROM conversations WHERE id = ?").get(id);
87
+ if (exists)
88
+ return id;
89
+ }
90
+ const res = db.prepare("INSERT INTO conversations DEFAULT VALUES").run();
91
+ const newId = res.lastInsertRowid;
92
+ log(`${GREEN}✓ New conversation created — ID ${newId}${RESET}`);
93
+ return newId;
94
+ }
95
+ // ─── Demo conversation state ─────────────────────────────────────────────────
96
+ let conversationId = ensureConversation();
97
+ let chatHistory = [];
98
+ let lastAssistantReply = "";
99
+ // ─── Simulate a chat turn ────────────────────────────────────────────────────
100
+ async function simulateChatTurn(userInput) {
101
+ // Build a minimal assistant reply for demo purposes
102
+ const assistantReply = `[Assistant] Got it: "${userInput}"`;
103
+ lastAssistantReply = assistantReply;
104
+ chatHistory.push({ role: "user", content: userInput });
105
+ chatHistory.push({ role: "assistant", content: assistantReply });
106
+ log(`\n${YELLOW}📥 Processing conversation turn...${RESET}`);
107
+ const result = await mem.add(chatHistory, conversationId);
108
+ log(GREEN + "✓ Memory extraction complete:" + RESET);
109
+ if (result.semantic.length > 0) {
110
+ log(` ${CYAN}Semantic facts (${result.semantic.length}):${RESET}`);
111
+ result.semantic.forEach((f) => log(` • ${f}`));
112
+ }
113
+ if (result.bubbles.length > 0) {
114
+ log(` ${YELLOW}Episodic bubbles (${result.bubbles.length}):${RESET}`);
115
+ result.bubbles.forEach((b) => log(` ◉ ${b}`));
116
+ }
117
+ if (result.semantic.length === 0 && result.bubbles.length === 0) {
118
+ log(` ${DIM}(Nothing extractable in this turn)${RESET}`);
119
+ }
120
+ }
121
+ // ─── Commands ────────────────────────────────────────────────────────────────
122
+ async function handleSearch(query) {
123
+ log(`\n${YELLOW}🔍 Searching for: "${query}"...${RESET}`);
124
+ const res = await mem.search(query, conversationId, { limit: 10, mmrLambda: 0.6 });
125
+ log(`${GREEN}Found ${res.total} result(s) [MMR-ranked]:${RESET}`);
126
+ if (res.results.length === 0) {
127
+ log(` ${DIM}(no results)${RESET}`);
128
+ return;
129
+ }
130
+ for (const r of res.results) {
131
+ const typeColor = r.type === "semantic" ? CYAN : r.type === "bubble" ? YELLOW : DIM;
132
+ log(` ${typeColor}[${r.type}]${RESET} ${BOLD}${r.memory}${RESET}`);
133
+ log(` ID: ${r.memoryId} | score: ${r.score.toFixed(4)} | category: ${r.category ?? "—"}${r.occurredAt ? ` | at: ${r.occurredAt}` : ""}`);
134
+ }
135
+ }
136
+ function handleList() {
137
+ const memories = mem.getAll(conversationId);
138
+ log(`\n${GREEN}All memories for conversation ${conversationId} (${memories.length} total):${RESET}`);
139
+ if (memories.length === 0) {
140
+ log(` ${DIM}(none yet)${RESET}`);
141
+ return;
142
+ }
143
+ for (const m of memories) {
144
+ const typeColor = m.is_episodic ? YELLOW : CYAN;
145
+ const typeLabel = m.is_episodic ? "bubble" : "semantic";
146
+ log(` ${typeColor}[${typeLabel}]${RESET} ${BOLD}ID ${m.id}${RESET} [${m.category ?? "?"}]: ${m.memory_text}`);
147
+ }
148
+ }
149
+ async function handleUpdate(memoryId, newText) {
150
+ log(`\n${YELLOW}✏️ Updating memory ${memoryId}...${RESET}`);
151
+ await mem.update(memoryId, newText);
152
+ log(`${GREEN}✓ Memory ${memoryId} updated.${RESET}`);
153
+ }
154
+ function handleStats() {
155
+ const stats = mem.getStats(conversationId);
156
+ log(`\n${GREEN}Memory stats for conversation ${conversationId}:${RESET}`);
157
+ log(` Total: ${BOLD}${stats.total}${RESET} | Semantic: ${CYAN}${stats.semantic}${RESET} | Bubbles: ${YELLOW}${stats.bubbles}${RESET}`);
158
+ if (Object.keys(stats.byCategory).length > 0) {
159
+ log(` By category:`);
160
+ for (const [cat, count] of Object.entries(stats.byCategory)) {
161
+ log(` ${CYAN}${cat}${RESET}: ${count}`);
162
+ }
163
+ }
164
+ const cacheStats = (0, index_js_1.getEmbeddingCacheStats)();
165
+ log(` Embedding cache: ${cacheStats.size} entries | Hit rate: ${cacheStats.hitRate}`);
166
+ }
167
+ async function handleConsolidate() {
168
+ log(`\n${YELLOW}🔧 Consolidating near-duplicate memories...${RESET}`);
169
+ const count = await mem.consolidate(conversationId);
170
+ if (count > 0)
171
+ log(`${GREEN}✓ Merged ${count} redundant memories.${RESET}`);
172
+ else
173
+ log(`${DIM}(nothing to consolidate)${RESET}`);
174
+ }
175
+ function handlePurge(days) {
176
+ const count = mem.purgeOldBubbles(conversationId, days);
177
+ log(`${GREEN}✓ Purged ${count} bubble(s) older than ${days} days.${RESET}`);
178
+ }
179
+ function handleDelete(memoryId) {
180
+ log(`\n${RED}🗑 Deleting memory ${memoryId}...${RESET}`);
181
+ mem.delete(memoryId);
182
+ log(`${GREEN}✓ Memory ${memoryId} deleted.${RESET}`);
183
+ }
184
+ function handleNewConversation() {
185
+ conversationId = ensureConversation();
186
+ chatHistory = [];
187
+ log(`${GREEN}✓ Switched to conversation ${conversationId}${RESET}`);
188
+ }
189
+ function printHelp() {
190
+ header("ContextMemory TypeScript v2 — Interactive Demo");
191
+ log(`${CYAN}Commands:${RESET}`);
192
+ log(` ${BOLD}chat <message>${RESET} — Extract memories from a user message`);
193
+ log(` ${BOLD}search <query>${RESET} — MMR-ranked semantic search`);
194
+ log(` ${BOLD}list${RESET} — List all memories (with categories)`);
195
+ log(` ${BOLD}stats${RESET} — Show memory counts + cache hit rate`);
196
+ log(` ${BOLD}update <id> <text>${RESET} — Update a memory by ID`);
197
+ log(` ${BOLD}delete <id>${RESET} — Delete a memory by ID`);
198
+ log(` ${BOLD}consolidate${RESET} — Merge near-duplicate memories via LLM`);
199
+ log(` ${BOLD}purge [days]${RESET} — Purge episodic bubbles older than N days (default 30)`);
200
+ log(` ${BOLD}newconv${RESET} — Start a new conversation`);
201
+ log(` ${BOLD}help${RESET} — Show this help`);
202
+ log(` ${BOLD}exit${RESET} — Quit`);
203
+ hr();
204
+ log(`${DIM}Conversation ID: ${conversationId} | DB: ${(0, index_js_1.getDb)().name}${RESET}`);
205
+ hr();
206
+ }
207
+ // ─── REPL ─────────────────────────────────────────────────────────────────────
208
+ async function main() {
209
+ printHelp();
210
+ const rl = readline.createInterface({
211
+ input: process.stdin,
212
+ output: process.stdout,
213
+ prompt: `${BOLD}${CYAN}context-memory>${RESET} `,
214
+ });
215
+ rl.prompt();
216
+ rl.on("line", async (line) => {
217
+ rl.pause();
218
+ const trimmed = line.trim();
219
+ if (!trimmed) {
220
+ rl.resume();
221
+ rl.prompt();
222
+ return;
223
+ }
224
+ const [cmd, ...rest] = trimmed.split(" ");
225
+ const arg = rest.join(" ").trim();
226
+ try {
227
+ switch (cmd.toLowerCase()) {
228
+ case "chat":
229
+ if (!arg) {
230
+ log(`${RED}Usage: chat <message>${RESET}`);
231
+ break;
232
+ }
233
+ await simulateChatTurn(arg);
234
+ break;
235
+ case "search":
236
+ if (!arg) {
237
+ log(`${RED}Usage: search <query>${RESET}`);
238
+ break;
239
+ }
240
+ await handleSearch(arg);
241
+ break;
242
+ case "list":
243
+ handleList();
244
+ break;
245
+ case "update": {
246
+ const parts = arg.split(" ");
247
+ const id = parseInt(parts[0], 10);
248
+ const newText = parts.slice(1).join(" ");
249
+ if (isNaN(id) || !newText) {
250
+ log(`${RED}Usage: update <id> <new text>${RESET}`);
251
+ break;
252
+ }
253
+ await handleUpdate(id, newText);
254
+ break;
255
+ }
256
+ case "delete": {
257
+ const id = parseInt(arg, 10);
258
+ if (isNaN(id)) {
259
+ log(`${RED}Usage: delete <id>${RESET}`);
260
+ break;
261
+ }
262
+ handleDelete(id);
263
+ break;
264
+ }
265
+ case "stats":
266
+ handleStats();
267
+ break;
268
+ case "consolidate":
269
+ await handleConsolidate();
270
+ break;
271
+ case "purge": {
272
+ const days = arg ? parseInt(arg, 10) : 30;
273
+ handlePurge(isNaN(days) ? 30 : days);
274
+ break;
275
+ }
276
+ case "newconv":
277
+ handleNewConversation();
278
+ break;
279
+ case "help":
280
+ printHelp();
281
+ break;
282
+ case "exit":
283
+ case "quit":
284
+ log(GREEN + "Bye! 👋" + RESET);
285
+ rl.close();
286
+ process.exit(0);
287
+ break;
288
+ default:
289
+ log(`${RED}Unknown command: ${cmd}. Type 'help' for available commands.${RESET}`);
290
+ }
291
+ }
292
+ catch (err) {
293
+ log(`${RED}Error: ${err.message}${RESET}`);
294
+ }
295
+ finally {
296
+ rl.resume();
297
+ rl.prompt();
298
+ }
299
+ });
300
+ }
301
+ main().catch((err) => {
302
+ console.error("Fatal:", err);
303
+ process.exit(1);
304
+ });
305
+ //# sourceMappingURL=demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.js","sourceRoot":"","sources":["../src/demo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * context-memory v2 — Public API
3
+ */
4
+ export { configure, getSettings, resetSettings } from "./core/settings.js";
5
+ export type { ContextMemoryConfig, LLMProvider } from "./core/settings.js";
6
+ export { getDb, createTables, resetDb } from "./db/database.js";
7
+ export type { MemoryRow, MessageRow, ConversationRow, SummaryRow } from "./db/database.js";
8
+ export { ContextMemory } from "./memory/memory.js";
9
+ export type { AddResponse, SearchResponse, SearchOptions, MemoryResult, MemoryStats, } from "./memory/memory.js";
10
+ export { embedText, batchEmbedTexts, getEmbeddingCacheStats } from "./memory/embeddings.js";
11
+ export { getVectorStore, saveVectorStore, rebuildIndexFromDb } from "./memory/vectorStore.js";
12
+ export type { SearchResult } from "./memory/vectorStore.js";
13
+ export { generateConversationSummary } from "./summary/summaryGenerator.js";
14
+ export { withRetry } from "./core/retry.js";
15
+ export type { RetryOptions } from "./core/retry.js";
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC3E,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAG3E,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG3F,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACb,YAAY,EACZ,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC9F,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ /**
3
+ * context-memory v2 — Public API
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.withRetry = exports.generateConversationSummary = exports.rebuildIndexFromDb = exports.saveVectorStore = exports.getVectorStore = exports.getEmbeddingCacheStats = exports.batchEmbedTexts = exports.embedText = exports.ContextMemory = exports.resetDb = exports.createTables = exports.getDb = exports.resetSettings = exports.getSettings = exports.configure = void 0;
7
+ // Core config
8
+ var settings_js_1 = require("./core/settings.js");
9
+ Object.defineProperty(exports, "configure", { enumerable: true, get: function () { return settings_js_1.configure; } });
10
+ Object.defineProperty(exports, "getSettings", { enumerable: true, get: function () { return settings_js_1.getSettings; } });
11
+ Object.defineProperty(exports, "resetSettings", { enumerable: true, get: function () { return settings_js_1.resetSettings; } });
12
+ // Database
13
+ var database_js_1 = require("./db/database.js");
14
+ Object.defineProperty(exports, "getDb", { enumerable: true, get: function () { return database_js_1.getDb; } });
15
+ Object.defineProperty(exports, "createTables", { enumerable: true, get: function () { return database_js_1.createTables; } });
16
+ Object.defineProperty(exports, "resetDb", { enumerable: true, get: function () { return database_js_1.resetDb; } });
17
+ // Main class + types
18
+ var memory_js_1 = require("./memory/memory.js");
19
+ Object.defineProperty(exports, "ContextMemory", { enumerable: true, get: function () { return memory_js_1.ContextMemory; } });
20
+ // Lower-level utilities
21
+ var embeddings_js_1 = require("./memory/embeddings.js");
22
+ Object.defineProperty(exports, "embedText", { enumerable: true, get: function () { return embeddings_js_1.embedText; } });
23
+ Object.defineProperty(exports, "batchEmbedTexts", { enumerable: true, get: function () { return embeddings_js_1.batchEmbedTexts; } });
24
+ Object.defineProperty(exports, "getEmbeddingCacheStats", { enumerable: true, get: function () { return embeddings_js_1.getEmbeddingCacheStats; } });
25
+ var vectorStore_js_1 = require("./memory/vectorStore.js");
26
+ Object.defineProperty(exports, "getVectorStore", { enumerable: true, get: function () { return vectorStore_js_1.getVectorStore; } });
27
+ Object.defineProperty(exports, "saveVectorStore", { enumerable: true, get: function () { return vectorStore_js_1.saveVectorStore; } });
28
+ Object.defineProperty(exports, "rebuildIndexFromDb", { enumerable: true, get: function () { return vectorStore_js_1.rebuildIndexFromDb; } });
29
+ var summaryGenerator_js_1 = require("./summary/summaryGenerator.js");
30
+ Object.defineProperty(exports, "generateConversationSummary", { enumerable: true, get: function () { return summaryGenerator_js_1.generateConversationSummary; } });
31
+ var retry_js_1 = require("./core/retry.js");
32
+ Object.defineProperty(exports, "withRetry", { enumerable: true, get: function () { return retry_js_1.withRetry; } });
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,cAAc;AACd,kDAA2E;AAAlE,wGAAA,SAAS,OAAA;AAAE,0GAAA,WAAW,OAAA;AAAE,4GAAA,aAAa,OAAA;AAG9C,WAAW;AACX,gDAAgE;AAAvD,oGAAA,KAAK,OAAA;AAAE,2GAAA,YAAY,OAAA;AAAE,sGAAA,OAAO,OAAA;AAGrC,qBAAqB;AACrB,gDAAmD;AAA1C,0GAAA,aAAa,OAAA;AAStB,wBAAwB;AACxB,wDAA4F;AAAnF,0GAAA,SAAS,OAAA;AAAE,gHAAA,eAAe,OAAA;AAAE,uHAAA,sBAAsB,OAAA;AAC3D,0DAA8F;AAArF,gHAAA,cAAc,OAAA;AAAE,iHAAA,eAAe,OAAA;AAAE,oHAAA,kBAAkB,OAAA;AAE5D,qEAA4E;AAAnE,kIAAA,2BAA2B,OAAA;AACpC,4CAA4C;AAAnC,qGAAA,SAAS,OAAA"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Extraction Phase — TypeScript port of Python add_extraction_phase.py
3
+ *
4
+ * Step 1 of add():
5
+ * - Gets the latest 10 messages + rolling summary from DB
6
+ * - Calls extractMemories() to get semantic facts + episodic bubbles
7
+ * - Persists the new message pair
8
+ * - Triggers summary generation if needed
9
+ */
10
+ import type Database from "better-sqlite3";
11
+ import { type ExtractionResult } from "../extractor.js";
12
+ export interface ChatMessage {
13
+ role: "user" | "assistant";
14
+ content: string;
15
+ }
16
+ export declare function extractionPhase(db: Database.Database, messages: ChatMessage[], conversationId: number): Promise<ExtractionResult>;
17
+ //# sourceMappingURL=extractionPhase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractionPhase.d.ts","sourceRoot":"","sources":["../../../src/memory/add/extractionPhase.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIzE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,WAAW,EAAE,EACvB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAgD3B"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /**
3
+ * Extraction Phase — TypeScript port of Python add_extraction_phase.py
4
+ *
5
+ * Step 1 of add():
6
+ * - Gets the latest 10 messages + rolling summary from DB
7
+ * - Calls extractMemories() to get semantic facts + episodic bubbles
8
+ * - Persists the new message pair
9
+ * - Triggers summary generation if needed
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.extractionPhase = extractionPhase;
13
+ const extractor_js_1 = require("../extractor.js");
14
+ const summaryGenerator_js_1 = require("../../summary/summaryGenerator.js");
15
+ async function extractionPhase(db, messages, conversationId) {
16
+ if (messages.length < 2)
17
+ return { semantic: [], bubbles: [] };
18
+ const userMsg = messages[messages.length - 2];
19
+ const assistantMsg = messages[messages.length - 1];
20
+ // Format latest pair as "ROLE: content"
21
+ const latestPair = [
22
+ `${userMsg.role.toUpperCase()}: ${userMsg.content}`,
23
+ `${assistantMsg.role.toUpperCase()}: ${assistantMsg.content}`,
24
+ ];
25
+ // Get current rolling summary
26
+ const summaryRow = db
27
+ .prepare("SELECT * FROM conversation_summary WHERE conversation_id = ?")
28
+ .get(conversationId);
29
+ const summaryText = summaryRow?.summary_text ?? "";
30
+ // Get last 10 messages for context
31
+ const recentRows = db
32
+ .prepare(`SELECT * FROM messages WHERE conversation_id = ?
33
+ ORDER BY timestamp DESC LIMIT 10`)
34
+ .all(conversationId);
35
+ const recentMessages = recentRows
36
+ .reverse()
37
+ .map((r) => `${r.sender.toUpperCase()}: ${r.message_text}`);
38
+ // Extract facts via LLM
39
+ const result = await (0, extractor_js_1.extractMemories)(latestPair, summaryText, recentMessages);
40
+ // Persist the message pair
41
+ const now = new Date().toISOString();
42
+ db.prepare("INSERT INTO messages (conversation_id, sender, message_text, timestamp) VALUES (?, ?, ?, ?)").run(conversationId, "user", userMsg.content, now);
43
+ db.prepare("INSERT INTO messages (conversation_id, sender, message_text, timestamp) VALUES (?, ?, ?, ?)").run(conversationId, "assistant", assistantMsg.content, now);
44
+ // Possibly update rolling summary
45
+ await (0, summaryGenerator_js_1.generateConversationSummary)(db, conversationId);
46
+ return result;
47
+ }
48
+ //# sourceMappingURL=extractionPhase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractionPhase.js","sourceRoot":"","sources":["../../../src/memory/add/extractionPhase.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAYH,0CAoDC;AA7DD,kDAAyE;AACzE,2EAAgF;AAQzE,KAAK,UAAU,eAAe,CACnC,EAAqB,EACrB,QAAuB,EACvB,cAAsB;IAEtB,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAE9D,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEnD,wCAAwC;IACxC,MAAM,UAAU,GAAG;QACjB,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,OAAO,EAAE;QACnD,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,OAAO,EAAE;KAC9D,CAAC;IAEF,8BAA8B;IAC9B,MAAM,UAAU,GAAG,EAAE;SAClB,OAAO,CACN,8DAA8D,CAC/D;SACA,GAAG,CAAC,cAAc,CAA2B,CAAC;IACjD,MAAM,WAAW,GAAG,UAAU,EAAE,YAAY,IAAI,EAAE,CAAC;IAEnD,mCAAmC;IACnC,MAAM,UAAU,GAAG,EAAE;SAClB,OAAO,CACN;wCACkC,CACnC;SACA,GAAG,CAAC,cAAc,CAAiB,CAAC;IAEvC,MAAM,cAAc,GAAG,UAAU;SAC9B,OAAO,EAAE;SACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;IAE9D,wBAAwB;IACxB,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAe,EAAC,UAAU,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;IAE9E,2BAA2B;IAC3B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,EAAE,CAAC,OAAO,CACR,6FAA6F,CAC9F,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACpD,EAAE,CAAC,OAAO,CACR,6FAA6F,CAC9F,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,EAAE,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAE9D,kCAAkC;IAClC,MAAM,IAAA,iDAA2B,EAAC,EAAE,EAAE,cAAc,CAAC,CAAC;IAEtD,OAAO,MAAM,CAAC;AAChB,CAAC"}