@agentplugged/claw 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 (149) hide show
  1. package/dist/cli.d.ts +11 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +111 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/config.d.ts +29 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +94 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/index.d.ts +17 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +54 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/memory/capture.d.ts +13 -0
  14. package/dist/memory/capture.d.ts.map +1 -0
  15. package/dist/memory/capture.js +102 -0
  16. package/dist/memory/capture.js.map +1 -0
  17. package/dist/memory/db.d.ts +56 -0
  18. package/dist/memory/db.d.ts.map +1 -0
  19. package/dist/memory/db.js +206 -0
  20. package/dist/memory/db.js.map +1 -0
  21. package/dist/memory/index.d.ts +8 -0
  22. package/dist/memory/index.d.ts.map +1 -0
  23. package/dist/memory/index.js +42 -0
  24. package/dist/memory/index.js.map +1 -0
  25. package/dist/memory/llm-extract.d.ts +13 -0
  26. package/dist/memory/llm-extract.d.ts.map +1 -0
  27. package/dist/memory/llm-extract.js +135 -0
  28. package/dist/memory/llm-extract.js.map +1 -0
  29. package/dist/memory/recall.d.ts +16 -0
  30. package/dist/memory/recall.d.ts.map +1 -0
  31. package/dist/memory/recall.js +131 -0
  32. package/dist/memory/recall.js.map +1 -0
  33. package/dist/observability/collector.d.ts +40 -0
  34. package/dist/observability/collector.d.ts.map +1 -0
  35. package/dist/observability/collector.js +119 -0
  36. package/dist/observability/collector.js.map +1 -0
  37. package/dist/observability/db.d.ts +60 -0
  38. package/dist/observability/db.d.ts.map +1 -0
  39. package/dist/observability/db.js +189 -0
  40. package/dist/observability/db.js.map +1 -0
  41. package/dist/observability/index.d.ts +7 -0
  42. package/dist/observability/index.d.ts.map +1 -0
  43. package/dist/observability/index.js +35 -0
  44. package/dist/observability/index.js.map +1 -0
  45. package/dist/observability/queries.d.ts +54 -0
  46. package/dist/observability/queries.d.ts.map +1 -0
  47. package/dist/observability/queries.js +181 -0
  48. package/dist/observability/queries.js.map +1 -0
  49. package/dist/router/classifier.d.ts +8 -0
  50. package/dist/router/classifier.d.ts.map +1 -0
  51. package/dist/router/classifier.js +90 -0
  52. package/dist/router/classifier.js.map +1 -0
  53. package/dist/router/fallback.d.ts +18 -0
  54. package/dist/router/fallback.d.ts.map +1 -0
  55. package/dist/router/fallback.js +102 -0
  56. package/dist/router/fallback.js.map +1 -0
  57. package/dist/router/index.d.ts +5 -0
  58. package/dist/router/index.d.ts.map +1 -0
  59. package/dist/router/index.js +214 -0
  60. package/dist/router/index.js.map +1 -0
  61. package/dist/router/leak-detector.d.ts +33 -0
  62. package/dist/router/leak-detector.d.ts.map +1 -0
  63. package/dist/router/leak-detector.js +320 -0
  64. package/dist/router/leak-detector.js.map +1 -0
  65. package/dist/router/logger.d.ts +18 -0
  66. package/dist/router/logger.d.ts.map +1 -0
  67. package/dist/router/logger.js +130 -0
  68. package/dist/router/logger.js.map +1 -0
  69. package/dist/router/models.d.ts +5 -0
  70. package/dist/router/models.d.ts.map +1 -0
  71. package/dist/router/models.js +96 -0
  72. package/dist/router/models.js.map +1 -0
  73. package/dist/router/providers.d.ts +4 -0
  74. package/dist/router/providers.d.ts.map +1 -0
  75. package/dist/router/providers.js +323 -0
  76. package/dist/router/providers.js.map +1 -0
  77. package/dist/router/strategy.d.ts +29 -0
  78. package/dist/router/strategy.d.ts.map +1 -0
  79. package/dist/router/strategy.js +169 -0
  80. package/dist/router/strategy.js.map +1 -0
  81. package/dist/router/types.d.ts +63 -0
  82. package/dist/router/types.d.ts.map +1 -0
  83. package/dist/router/types.js +3 -0
  84. package/dist/router/types.js.map +1 -0
  85. package/dist/sidecar/auth.d.ts +7 -0
  86. package/dist/sidecar/auth.d.ts.map +1 -0
  87. package/dist/sidecar/auth.js +36 -0
  88. package/dist/sidecar/auth.js.map +1 -0
  89. package/dist/sidecar/index.d.ts +2 -0
  90. package/dist/sidecar/index.d.ts.map +1 -0
  91. package/dist/sidecar/index.js +336 -0
  92. package/dist/sidecar/index.js.map +1 -0
  93. package/dist/sidecar/routes/addons.d.ts +6 -0
  94. package/dist/sidecar/routes/addons.d.ts.map +1 -0
  95. package/dist/sidecar/routes/addons.js +332 -0
  96. package/dist/sidecar/routes/addons.js.map +1 -0
  97. package/dist/sidecar/routes/backup.d.ts +7 -0
  98. package/dist/sidecar/routes/backup.d.ts.map +1 -0
  99. package/dist/sidecar/routes/backup.js +204 -0
  100. package/dist/sidecar/routes/backup.js.map +1 -0
  101. package/dist/sidecar/routes/channels.d.ts +4 -0
  102. package/dist/sidecar/routes/channels.d.ts.map +1 -0
  103. package/dist/sidecar/routes/channels.js +120 -0
  104. package/dist/sidecar/routes/channels.js.map +1 -0
  105. package/dist/sidecar/routes/health.d.ts +5 -0
  106. package/dist/sidecar/routes/health.d.ts.map +1 -0
  107. package/dist/sidecar/routes/health.js +28 -0
  108. package/dist/sidecar/routes/health.js.map +1 -0
  109. package/dist/sidecar/routes/memory.d.ts +7 -0
  110. package/dist/sidecar/routes/memory.d.ts.map +1 -0
  111. package/dist/sidecar/routes/memory.js +234 -0
  112. package/dist/sidecar/routes/memory.js.map +1 -0
  113. package/dist/sidecar/routes/metrics.d.ts +5 -0
  114. package/dist/sidecar/routes/metrics.d.ts.map +1 -0
  115. package/dist/sidecar/routes/metrics.js +273 -0
  116. package/dist/sidecar/routes/metrics.js.map +1 -0
  117. package/dist/sidecar/routes/restart.d.ts +4 -0
  118. package/dist/sidecar/routes/restart.d.ts.map +1 -0
  119. package/dist/sidecar/routes/restart.js +81 -0
  120. package/dist/sidecar/routes/restart.js.map +1 -0
  121. package/dist/sidecar/routes/router-config.d.ts +5 -0
  122. package/dist/sidecar/routes/router-config.d.ts.map +1 -0
  123. package/dist/sidecar/routes/router-config.js +150 -0
  124. package/dist/sidecar/routes/router-config.js.map +1 -0
  125. package/dist/sidecar/routes/security.d.ts +8 -0
  126. package/dist/sidecar/routes/security.d.ts.map +1 -0
  127. package/dist/sidecar/routes/security.js +308 -0
  128. package/dist/sidecar/routes/security.js.map +1 -0
  129. package/dist/sidecar/routes/skills.d.ts +5 -0
  130. package/dist/sidecar/routes/skills.d.ts.map +1 -0
  131. package/dist/sidecar/routes/skills.js +146 -0
  132. package/dist/sidecar/routes/skills.js.map +1 -0
  133. package/dist/sidecar/routes/soul.d.ts +4 -0
  134. package/dist/sidecar/routes/soul.d.ts.map +1 -0
  135. package/dist/sidecar/routes/soul.js +115 -0
  136. package/dist/sidecar/routes/soul.js.map +1 -0
  137. package/dist/sidecar/routes/team.d.ts +4 -0
  138. package/dist/sidecar/routes/team.d.ts.map +1 -0
  139. package/dist/sidecar/routes/team.js +139 -0
  140. package/dist/sidecar/routes/team.js.map +1 -0
  141. package/dist/sidecar/routes/update.d.ts +4 -0
  142. package/dist/sidecar/routes/update.d.ts.map +1 -0
  143. package/dist/sidecar/routes/update.js +96 -0
  144. package/dist/sidecar/routes/update.js.map +1 -0
  145. package/dist/sidecar/utils.d.ts +9 -0
  146. package/dist/sidecar/utils.d.ts.map +1 -0
  147. package/dist/sidecar/utils.js +57 -0
  148. package/dist/sidecar/utils.js.map +1 -0
  149. package/package.json +45 -0
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.openMemoryDatabase = openMemoryDatabase;
40
+ exports.insertMemory = insertMemory;
41
+ exports.searchMemories = searchMemories;
42
+ exports.getAllMemories = getAllMemories;
43
+ exports.deleteMemory = deleteMemory;
44
+ exports.trackAccess = trackAccess;
45
+ exports.logMemoryAction = logMemoryAction;
46
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
47
+ const fs = __importStar(require("fs"));
48
+ const path = __importStar(require("path"));
49
+ // ─── Schema ──────────────────────────────────────────────────────────────────
50
+ const SCHEMA_SQL = `
51
+ CREATE TABLE IF NOT EXISTS memories (
52
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
53
+ type TEXT NOT NULL DEFAULT 'fact',
54
+ content TEXT NOT NULL,
55
+ source TEXT,
56
+ confidence REAL NOT NULL DEFAULT 1.0,
57
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
58
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
59
+ accessed_at TEXT,
60
+ access_count INTEGER NOT NULL DEFAULT 0
61
+ );
62
+
63
+ CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
64
+ CREATE INDEX IF NOT EXISTS idx_memories_created ON memories(created_at);
65
+
66
+ CREATE TABLE IF NOT EXISTS memory_log (
67
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
68
+ action TEXT NOT NULL,
69
+ memory_id INTEGER,
70
+ timestamp TEXT NOT NULL DEFAULT (datetime('now'))
71
+ );
72
+ `;
73
+ // ─── Functions ────────────────────────────────────────────────────────────────
74
+ /**
75
+ * Opens (or creates) the memory SQLite database.
76
+ * Stored at <dataDir>/memory/memory.db.
77
+ * WAL mode is enabled for concurrent reads.
78
+ */
79
+ function openMemoryDatabase(dataDir) {
80
+ const memoryDir = path.join(dataDir, "memory");
81
+ if (!fs.existsSync(memoryDir)) {
82
+ fs.mkdirSync(memoryDir, { recursive: true });
83
+ }
84
+ const dbPath = path.join(memoryDir, "memory.db");
85
+ const db = new better_sqlite3_1.default(dbPath);
86
+ db.pragma("journal_mode = WAL");
87
+ db.exec(SCHEMA_SQL);
88
+ return db;
89
+ }
90
+ /**
91
+ * Inserts a new memory record and returns its auto-incremented id.
92
+ */
93
+ function insertMemory(db, memory) {
94
+ const stmt = db.prepare(`
95
+ INSERT INTO memories (type, content, source, confidence)
96
+ VALUES (@type, @content, @source, @confidence)
97
+ `);
98
+ const result = stmt.run({
99
+ type: memory.type,
100
+ content: memory.content,
101
+ source: memory.source ?? null,
102
+ confidence: memory.confidence ?? 1.0,
103
+ });
104
+ return result.lastInsertRowid;
105
+ }
106
+ /**
107
+ * Searches memories using SQLite LIKE across the content field.
108
+ * Splits the query into keywords and OR-combines them.
109
+ */
110
+ function searchMemories(db, query, limit = 20) {
111
+ const keywords = query
112
+ .trim()
113
+ .split(/\s+/)
114
+ .filter((k) => k.length > 1);
115
+ if (keywords.length === 0) {
116
+ return getAllMemories(db, { limit }).memories;
117
+ }
118
+ // Build: content LIKE '%kw1%' OR content LIKE '%kw2%'
119
+ const conditions = keywords.map(() => "content LIKE ?").join(" OR ");
120
+ const params = keywords.map((k) => `%${k}%`);
121
+ params.push(limit);
122
+ const sql = `
123
+ SELECT * FROM memories
124
+ WHERE ${conditions}
125
+ ORDER BY confidence DESC, created_at DESC
126
+ LIMIT ?
127
+ `;
128
+ const rows = db.prepare(sql).all(...params);
129
+ // Update access tracking for recalled memories
130
+ if (rows.length > 0) {
131
+ const ids = rows.map((r) => r.id);
132
+ const placeholders = ids.map(() => "?").join(",");
133
+ db.prepare(`
134
+ UPDATE memories
135
+ SET accessed_at = datetime('now'),
136
+ access_count = access_count + 1
137
+ WHERE id IN (${placeholders})
138
+ `).run(...ids);
139
+ }
140
+ return rows;
141
+ }
142
+ /**
143
+ * Returns all memories with optional type filter and pagination.
144
+ */
145
+ function getAllMemories(db, opts = {}) {
146
+ const limit = opts.limit ?? 50;
147
+ const offset = opts.offset ?? 0;
148
+ let whereClause = "";
149
+ const params = [];
150
+ if (opts.type) {
151
+ whereClause = "WHERE type = ?";
152
+ params.push(opts.type);
153
+ }
154
+ const countSql = `SELECT COUNT(*) as total FROM memories ${whereClause}`;
155
+ const countRow = db.prepare(countSql).get(...params);
156
+ const total = countRow?.total ?? 0;
157
+ const dataSql = `
158
+ SELECT * FROM memories
159
+ ${whereClause}
160
+ ORDER BY confidence DESC, created_at DESC
161
+ LIMIT ? OFFSET ?
162
+ `;
163
+ const memories = db
164
+ .prepare(dataSql)
165
+ .all(...params, limit, offset);
166
+ return { memories, total };
167
+ }
168
+ /**
169
+ * Deletes a memory by id. Returns true if a row was deleted.
170
+ */
171
+ function deleteMemory(db, id) {
172
+ const result = db.prepare("DELETE FROM memories WHERE id = ?").run(id);
173
+ return result.changes > 0;
174
+ }
175
+ /**
176
+ * Tracks access to a memory: increments access_count and updates accessed_at.
177
+ */
178
+ function trackAccess(db, memoryId) {
179
+ try {
180
+ db.prepare(`
181
+ UPDATE memories
182
+ SET access_count = access_count + 1,
183
+ accessed_at = datetime('now')
184
+ WHERE id = ?
185
+ `).run(memoryId);
186
+ }
187
+ catch (err) {
188
+ // Access tracking must never crash the caller
189
+ console.error("[memory/db] Failed to track access:", err);
190
+ }
191
+ }
192
+ /**
193
+ * Logs a memory action (capture, recall, forget) to the memory_log table.
194
+ */
195
+ function logMemoryAction(db, action, memoryId) {
196
+ try {
197
+ db.prepare(`
198
+ INSERT INTO memory_log (action, memory_id) VALUES (@action, @memoryId)
199
+ `).run({ action, memoryId: memoryId ?? null });
200
+ }
201
+ catch (err) {
202
+ // Logging must never crash the caller
203
+ console.error("[memory/db] Failed to log memory action:", err);
204
+ }
205
+ }
206
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/memory/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export { openMemoryDatabase, insertMemory, searchMemories, getAllMemories, deleteMemory, logMemoryAction, trackAccess, } from "./db";
2
+ export type { Memory } from "./db";
3
+ export { extractMemories } from "./capture";
4
+ export type { CapturedMemory } from "./capture";
5
+ export { extractMemoriesLLM, mergeExtractions } from "./llm-extract";
6
+ export { buildMemoryContext } from "./recall";
7
+ export declare const MEMORY_SKILL_MD = "---\nname: agentplugged-memory\ndescription: Persistent memory system for AgentPlugged\nalways: true\nhidden: true\n---\n\n# Memory System\n\nYou have access to a persistent memory system. Key facts, preferences, and decisions from conversations are automatically remembered.\n\n## Available Commands\n\nUsers can use these commands:\n- /remember <text> \u2014 manually save something to memory\n- /recall \u2014 show all stored memories\n- /forget <text> \u2014 remove a specific memory\n- /memories \u2014 list all memories with details\n\n## Automatic Behavior\n\nAfter each conversation, relevant information is automatically extracted and stored. Before each response, relevant memories are injected into your context.\n";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,YAAY,EACZ,eAAe,EACf,WAAW,GACZ,MAAM,MAAM,CAAC;AACd,YAAY,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAErE,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE9C,eAAO,MAAM,eAAe,0tBAsB3B,CAAC"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MEMORY_SKILL_MD = exports.buildMemoryContext = exports.mergeExtractions = exports.extractMemoriesLLM = exports.extractMemories = exports.trackAccess = exports.logMemoryAction = exports.deleteMemory = exports.getAllMemories = exports.searchMemories = exports.insertMemory = exports.openMemoryDatabase = void 0;
4
+ var db_1 = require("./db");
5
+ Object.defineProperty(exports, "openMemoryDatabase", { enumerable: true, get: function () { return db_1.openMemoryDatabase; } });
6
+ Object.defineProperty(exports, "insertMemory", { enumerable: true, get: function () { return db_1.insertMemory; } });
7
+ Object.defineProperty(exports, "searchMemories", { enumerable: true, get: function () { return db_1.searchMemories; } });
8
+ Object.defineProperty(exports, "getAllMemories", { enumerable: true, get: function () { return db_1.getAllMemories; } });
9
+ Object.defineProperty(exports, "deleteMemory", { enumerable: true, get: function () { return db_1.deleteMemory; } });
10
+ Object.defineProperty(exports, "logMemoryAction", { enumerable: true, get: function () { return db_1.logMemoryAction; } });
11
+ Object.defineProperty(exports, "trackAccess", { enumerable: true, get: function () { return db_1.trackAccess; } });
12
+ var capture_1 = require("./capture");
13
+ Object.defineProperty(exports, "extractMemories", { enumerable: true, get: function () { return capture_1.extractMemories; } });
14
+ var llm_extract_1 = require("./llm-extract");
15
+ Object.defineProperty(exports, "extractMemoriesLLM", { enumerable: true, get: function () { return llm_extract_1.extractMemoriesLLM; } });
16
+ Object.defineProperty(exports, "mergeExtractions", { enumerable: true, get: function () { return llm_extract_1.mergeExtractions; } });
17
+ var recall_1 = require("./recall");
18
+ Object.defineProperty(exports, "buildMemoryContext", { enumerable: true, get: function () { return recall_1.buildMemoryContext; } });
19
+ exports.MEMORY_SKILL_MD = `---
20
+ name: agentplugged-memory
21
+ description: Persistent memory system for AgentPlugged
22
+ always: true
23
+ hidden: true
24
+ ---
25
+
26
+ # Memory System
27
+
28
+ You have access to a persistent memory system. Key facts, preferences, and decisions from conversations are automatically remembered.
29
+
30
+ ## Available Commands
31
+
32
+ Users can use these commands:
33
+ - /remember <text> — manually save something to memory
34
+ - /recall — show all stored memories
35
+ - /forget <text> — remove a specific memory
36
+ - /memories — list all memories with details
37
+
38
+ ## Automatic Behavior
39
+
40
+ After each conversation, relevant information is automatically extracted and stored. Before each response, relevant memories are injected into your context.
41
+ `;
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":";;;AAAA,2BAQc;AAPZ,wGAAA,kBAAkB,OAAA;AAClB,kGAAA,YAAY,OAAA;AACZ,oGAAA,cAAc,OAAA;AACd,oGAAA,cAAc,OAAA;AACd,kGAAA,YAAY,OAAA;AACZ,qGAAA,eAAe,OAAA;AACf,iGAAA,WAAW,OAAA;AAIb,qCAA4C;AAAnC,0GAAA,eAAe,OAAA;AAGxB,6CAAqE;AAA5D,iHAAA,kBAAkB,OAAA;AAAE,+GAAA,gBAAgB,OAAA;AAE7C,mCAA8C;AAArC,4GAAA,kBAAkB,OAAA;AAEd,QAAA,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsB9B,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { CapturedMemory } from "./capture";
2
+ /**
3
+ * Calls Claude Haiku to extract structured memories from a user+assistant exchange.
4
+ * Falls back to an empty array on any error (network, parsing, etc.).
5
+ */
6
+ export declare function extractMemoriesLLM(userMessage: string, assistantResponse: string, apiKey: string): Promise<CapturedMemory[]>;
7
+ /**
8
+ * Merges regex-based and LLM-based memory extractions.
9
+ * Deduplicates by normalized content. When duplicates are found,
10
+ * keeps the one with higher confidence.
11
+ */
12
+ export declare function mergeExtractions(regex: CapturedMemory[], llm: CapturedMemory[]): CapturedMemory[];
13
+ //# sourceMappingURL=llm-extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-extract.d.ts","sourceRoot":"","sources":["../../src/memory/llm-extract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AA4BhD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,EAAE,CAAC,CA4C3B;AA0DD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EAAE,EACvB,GAAG,EAAE,cAAc,EAAE,GACpB,cAAc,EAAE,CAoBlB"}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractMemoriesLLM = extractMemoriesLLM;
4
+ exports.mergeExtractions = mergeExtractions;
5
+ // ─── Constants ────────────────────────────────────────────────────────────────
6
+ const ANTHROPIC_API_URL = "https://api.anthropic.com/v1/messages";
7
+ const MODEL = "claude-haiku-4-20250414";
8
+ const MAX_TOKENS = 1024;
9
+ const EXTRACTION_SYSTEM_PROMPT = `You are a memory extraction assistant. Your job is to identify important, persistent information from a conversation exchange that would be useful to remember for future interactions.
10
+
11
+ Extract memorable information from this conversation.
12
+ Return a JSON array with objects: { "type": "preference"|"decision"|"fact"|"context", "content": string, "confidence": number (0-1) }
13
+
14
+ Guidelines:
15
+ - "preference": User likes, dislikes, habits, preferred tools/approaches
16
+ - "decision": Choices made, directions chosen, commitments
17
+ - "fact": Personal info (name, role, company), technical facts, project details
18
+ - "context": Current project state, goals, constraints, environment details
19
+
20
+ Rules:
21
+ - Only extract truly important/persistent information. Skip trivial or ephemeral details.
22
+ - Each content string should be self-contained and understandable without the original conversation.
23
+ - Confidence should reflect how certain and persistent the information is (0.5 = uncertain, 0.9+ = very certain).
24
+ - Return an empty array [] if nothing is worth remembering.
25
+ - Return ONLY the JSON array, no markdown fences, no explanation.`;
26
+ // ─── LLM Extraction ─────────────────────────────────────────────────────────
27
+ /**
28
+ * Calls Claude Haiku to extract structured memories from a user+assistant exchange.
29
+ * Falls back to an empty array on any error (network, parsing, etc.).
30
+ */
31
+ async function extractMemoriesLLM(userMessage, assistantResponse, apiKey) {
32
+ if (!apiKey || !userMessage || !assistantResponse) {
33
+ return [];
34
+ }
35
+ try {
36
+ const response = await fetch(ANTHROPIC_API_URL, {
37
+ method: "POST",
38
+ headers: {
39
+ "Content-Type": "application/json",
40
+ "x-api-key": apiKey,
41
+ "anthropic-version": "2023-06-01",
42
+ },
43
+ body: JSON.stringify({
44
+ model: MODEL,
45
+ max_tokens: MAX_TOKENS,
46
+ system: EXTRACTION_SYSTEM_PROMPT,
47
+ messages: [
48
+ {
49
+ role: "user",
50
+ content: `User message:\n${userMessage}\n\nAssistant response:\n${assistantResponse}`,
51
+ },
52
+ ],
53
+ }),
54
+ });
55
+ if (!response.ok) {
56
+ return [];
57
+ }
58
+ const data = (await response.json());
59
+ const text = data.content?.[0]?.text;
60
+ if (!text) {
61
+ return [];
62
+ }
63
+ return parseExtractionResponse(text);
64
+ }
65
+ catch {
66
+ // Silent fallback -- LLM extraction is best-effort
67
+ return [];
68
+ }
69
+ }
70
+ // ─── Response parsing ────────────────────────────────────────────────────────
71
+ const VALID_TYPES = new Set(["preference", "decision", "fact", "context"]);
72
+ function parseExtractionResponse(text) {
73
+ try {
74
+ // Strip potential markdown fences
75
+ const cleaned = text
76
+ .replace(/^```(?:json)?\s*/m, "")
77
+ .replace(/\s*```\s*$/m, "")
78
+ .trim();
79
+ const parsed = JSON.parse(cleaned);
80
+ if (!Array.isArray(parsed)) {
81
+ return [];
82
+ }
83
+ const memories = [];
84
+ for (const item of parsed) {
85
+ if (item &&
86
+ typeof item === "object" &&
87
+ typeof item.type === "string" &&
88
+ typeof item.content === "string" &&
89
+ typeof item.confidence === "number") {
90
+ const type = item.type;
91
+ const content = item.content.trim();
92
+ const confidence = item.confidence;
93
+ if (VALID_TYPES.has(type) &&
94
+ content.length >= 5 &&
95
+ content.length <= 500 &&
96
+ confidence >= 0 &&
97
+ confidence <= 1) {
98
+ memories.push({
99
+ type: type,
100
+ content,
101
+ confidence,
102
+ });
103
+ }
104
+ }
105
+ }
106
+ return memories;
107
+ }
108
+ catch {
109
+ return [];
110
+ }
111
+ }
112
+ // ─── Merge ───────────────────────────────────────────────────────────────────
113
+ /**
114
+ * Merges regex-based and LLM-based memory extractions.
115
+ * Deduplicates by normalized content. When duplicates are found,
116
+ * keeps the one with higher confidence.
117
+ */
118
+ function mergeExtractions(regex, llm) {
119
+ const map = new Map();
120
+ // Add regex results first
121
+ for (const mem of regex) {
122
+ const key = mem.content.trim().toLowerCase();
123
+ map.set(key, mem);
124
+ }
125
+ // Add LLM results, keeping higher confidence on conflict
126
+ for (const mem of llm) {
127
+ const key = mem.content.trim().toLowerCase();
128
+ const existing = map.get(key);
129
+ if (!existing || mem.confidence > existing.confidence) {
130
+ map.set(key, mem);
131
+ }
132
+ }
133
+ return Array.from(map.values());
134
+ }
135
+ //# sourceMappingURL=llm-extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-extract.js","sourceRoot":"","sources":["../../src/memory/llm-extract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import Database from "better-sqlite3";
2
+ /**
3
+ * Builds a memory context block to inject before an LLM response.
4
+ *
5
+ * Strategy:
6
+ * 1. Extract keywords from the latest user message(s)
7
+ * 2. Search memories relevant to those keywords
8
+ * 3. Append the most recent memories
9
+ * 4. Append high-confidence memories
10
+ * 5. Deduplicate and truncate to MAX_MEMORY_CHARS
11
+ * 6. Format as a <memory>...</memory> XML block
12
+ *
13
+ * Returns an empty string if no memories exist.
14
+ */
15
+ export declare function buildMemoryContext(db: Database.Database, currentMessages: string[]): string;
16
+ //# sourceMappingURL=recall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recall.d.ts","sourceRoot":"","sources":["../../src/memory/recall.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAoEtC;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,eAAe,EAAE,MAAM,EAAE,GACxB,MAAM,CAoER"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildMemoryContext = buildMemoryContext;
4
+ const db_1 = require("./db");
5
+ // ─── Constants ────────────────────────────────────────────────────────────────
6
+ const MAX_MEMORY_CHARS = 2000; // ~500 tokens at ~4 chars/token
7
+ const RECENT_MEMORIES_LIMIT = 10;
8
+ const SEARCH_RESULTS_LIMIT = 10;
9
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
10
+ /**
11
+ * Extracts meaningful keywords from a list of message strings.
12
+ * Strips stop words and short tokens.
13
+ */
14
+ function extractKeywords(messages) {
15
+ const STOP_WORDS = new Set([
16
+ "the", "a", "an", "is", "are", "was", "were", "be", "been", "being",
17
+ "have", "has", "had", "do", "does", "did", "will", "would", "could",
18
+ "should", "may", "might", "shall", "can", "to", "of", "in", "on",
19
+ "at", "for", "with", "about", "by", "from", "as", "it", "its",
20
+ "this", "that", "these", "those", "i", "you", "he", "she", "we",
21
+ "they", "me", "him", "her", "us", "them", "my", "your", "his", "our",
22
+ "what", "how", "when", "where", "why", "who", "which", "and", "or",
23
+ "but", "not", "no", "so", "if", "then", "also", "just", "like",
24
+ ]);
25
+ const words = messages
26
+ .join(" ")
27
+ .toLowerCase()
28
+ .replace(/[^a-z0-9\s]/g, " ")
29
+ .split(/\s+/)
30
+ .filter((w) => w.length > 2 && !STOP_WORDS.has(w));
31
+ // Deduplicate, keep most frequent first (simple frequency sort)
32
+ const freq = new Map();
33
+ for (const word of words) {
34
+ freq.set(word, (freq.get(word) ?? 0) + 1);
35
+ }
36
+ return Array.from(freq.entries())
37
+ .sort((a, b) => b[1] - a[1])
38
+ .slice(0, 10)
39
+ .map(([w]) => w);
40
+ }
41
+ /**
42
+ * Deduplicates memories by content (case-insensitive).
43
+ */
44
+ function deduplicateMemories(memories) {
45
+ const seen = new Set();
46
+ return memories.filter((m) => {
47
+ const key = m.content.trim().toLowerCase();
48
+ if (seen.has(key))
49
+ return false;
50
+ seen.add(key);
51
+ return true;
52
+ });
53
+ }
54
+ /**
55
+ * Formats a memory type label for display.
56
+ */
57
+ function formatType(type) {
58
+ return type.toLowerCase();
59
+ }
60
+ // ─── Main export ──────────────────────────────────────────────────────────────
61
+ /**
62
+ * Builds a memory context block to inject before an LLM response.
63
+ *
64
+ * Strategy:
65
+ * 1. Extract keywords from the latest user message(s)
66
+ * 2. Search memories relevant to those keywords
67
+ * 3. Append the most recent memories
68
+ * 4. Append high-confidence memories
69
+ * 5. Deduplicate and truncate to MAX_MEMORY_CHARS
70
+ * 6. Format as a <memory>...</memory> XML block
71
+ *
72
+ * Returns an empty string if no memories exist.
73
+ */
74
+ function buildMemoryContext(db, currentMessages) {
75
+ // 1. Extract keywords from the conversation
76
+ const keywords = extractKeywords(currentMessages);
77
+ const allCandidates = [];
78
+ // 2. Keyword-based search
79
+ if (keywords.length > 0) {
80
+ const query = keywords.slice(0, 5).join(" ");
81
+ const relevant = (0, db_1.searchMemories)(db, query, SEARCH_RESULTS_LIMIT);
82
+ allCandidates.push(...relevant);
83
+ }
84
+ // 3. Most recent memories
85
+ const { memories: recent } = (0, db_1.getAllMemories)(db, { limit: RECENT_MEMORIES_LIMIT });
86
+ allCandidates.push(...recent);
87
+ // 4. High-confidence memories (confidence >= 0.9)
88
+ const { memories: allMemories } = (0, db_1.getAllMemories)(db, { limit: 50 });
89
+ const highConfidence = allMemories.filter((m) => m.confidence >= 0.9);
90
+ allCandidates.push(...highConfidence);
91
+ // 5. Deduplicate
92
+ const unique = deduplicateMemories(allCandidates);
93
+ if (unique.length === 0) {
94
+ return "";
95
+ }
96
+ // 5b. Score and sort: combine confidence with access frequency boost
97
+ // Access boost is logarithmic so frequently accessed memories are favoured
98
+ // but new memories (access_count = 0) are not buried.
99
+ const scored = unique
100
+ .map((m) => ({
101
+ memory: m,
102
+ score: m.confidence + Math.log1p(m.access_count) * 0.1,
103
+ }))
104
+ .sort((a, b) => b.score - a.score)
105
+ .map((s) => s.memory);
106
+ // 5c. Track access for every memory that will be included in context
107
+ for (const memory of scored) {
108
+ (0, db_1.trackAccess)(db, memory.id);
109
+ }
110
+ // 6. Build the text block, respecting the character budget
111
+ const lines = [];
112
+ let totalChars = 0;
113
+ for (const memory of scored) {
114
+ const line = `- [${formatType(memory.type)}] ${memory.content}`;
115
+ if (totalChars + line.length > MAX_MEMORY_CHARS) {
116
+ break;
117
+ }
118
+ lines.push(line);
119
+ totalChars += line.length + 1; // +1 for newline
120
+ }
121
+ if (lines.length === 0) {
122
+ return "";
123
+ }
124
+ return [
125
+ "<memory>",
126
+ "Here is what I remember about this user:",
127
+ ...lines,
128
+ "</memory>",
129
+ ].join("\n");
130
+ }
131
+ //# sourceMappingURL=recall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recall.js","sourceRoot":"","sources":["../../src/memory/recall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import Database from "better-sqlite3";
2
+ /**
3
+ * ObservabilityCollector hooks into OpenClaw and the router to track
4
+ * every interaction for the dashboard.
5
+ *
6
+ * All methods are synchronous (SQLite writes are fast enough) so they
7
+ * can be called from lifecycle hooks without async overhead.
8
+ */
9
+ export declare class ObservabilityCollector {
10
+ private readonly db;
11
+ private dailyAccumulator;
12
+ constructor(db: Database.Database);
13
+ /**
14
+ * Called when a new conversation starts (before_agent_start hook).
15
+ */
16
+ startSession(sessionId: string, channel?: string): void;
17
+ /**
18
+ * Called when the conversation ends (agent_end hook).
19
+ */
20
+ endSession(sessionId: string): void;
21
+ /**
22
+ * Called for each message sent or received.
23
+ */
24
+ trackMessage(sessionId: string, role: "user" | "assistant", tokens: number): void;
25
+ /**
26
+ * Called for each tool invocation.
27
+ */
28
+ trackToolCall(sessionId: string, toolName: string, duration: number, success: boolean): void;
29
+ /**
30
+ * Called when an LLM request completes (from router logs).
31
+ */
32
+ trackLLMCall(sessionId: string, model: string, inputTokens: number, outputTokens: number, cost: number, latencyMs: number): void;
33
+ /**
34
+ * Flushes accumulated daily stats to the database.
35
+ * Should be called periodically (e.g. every minute) or at session end.
36
+ */
37
+ flushDailyStats(): void;
38
+ private accumulateDaily;
39
+ }
40
+ //# sourceMappingURL=collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/observability/collector.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAiBtC;;;;;;GAMG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IAGvC,OAAO,CAAC,gBAAgB,CAAkC;gBAE9C,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAMjC;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAUvD;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAOnC;;OAEG;IACH,YAAY,CACV,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GAAG,WAAW,EAC1B,MAAM,EAAE,MAAM,GACb,IAAI;IAYP;;OAEG;IACH,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,GACf,IAAI;IAgBP;;OAEG;IACH,YAAY,CACV,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,IAAI;IA0BP;;;OAGG;IACH,eAAe,IAAI,IAAI;IAcvB,OAAO,CAAC,eAAe;CAIxB"}