@dotsetlabs/dotclaw 1.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 (170) hide show
  1. package/.env.example +54 -0
  2. package/LICENSE +21 -0
  3. package/README.md +111 -0
  4. package/config-examples/groups/global/CLAUDE.md +21 -0
  5. package/config-examples/groups/main/CLAUDE.md +47 -0
  6. package/config-examples/mount-allowlist.json +25 -0
  7. package/config-examples/plugin-http.json +18 -0
  8. package/config-examples/runtime.json +30 -0
  9. package/config-examples/tool-budgets.json +24 -0
  10. package/config-examples/tool-policy.json +51 -0
  11. package/container/.dockerignore +6 -0
  12. package/container/Dockerfile +74 -0
  13. package/container/agent-runner/package-lock.json +92 -0
  14. package/container/agent-runner/package.json +20 -0
  15. package/container/agent-runner/src/agent-config.ts +295 -0
  16. package/container/agent-runner/src/container-protocol.ts +73 -0
  17. package/container/agent-runner/src/daemon.ts +91 -0
  18. package/container/agent-runner/src/index.ts +1428 -0
  19. package/container/agent-runner/src/ipc.ts +321 -0
  20. package/container/agent-runner/src/memory.ts +336 -0
  21. package/container/agent-runner/src/prompt-packs.ts +341 -0
  22. package/container/agent-runner/src/tools.ts +1720 -0
  23. package/container/agent-runner/tsconfig.json +19 -0
  24. package/container/build.sh +23 -0
  25. package/container/skills/agent-browser.md +159 -0
  26. package/dist/admin-commands.d.ts +7 -0
  27. package/dist/admin-commands.d.ts.map +1 -0
  28. package/dist/admin-commands.js +87 -0
  29. package/dist/admin-commands.js.map +1 -0
  30. package/dist/agent-context.d.ts +42 -0
  31. package/dist/agent-context.d.ts.map +1 -0
  32. package/dist/agent-context.js +92 -0
  33. package/dist/agent-context.js.map +1 -0
  34. package/dist/agent-execution.d.ts +68 -0
  35. package/dist/agent-execution.d.ts.map +1 -0
  36. package/dist/agent-execution.js +169 -0
  37. package/dist/agent-execution.js.map +1 -0
  38. package/dist/agent-semaphore.d.ts +2 -0
  39. package/dist/agent-semaphore.d.ts.map +1 -0
  40. package/dist/agent-semaphore.js +52 -0
  41. package/dist/agent-semaphore.js.map +1 -0
  42. package/dist/behavior-config.d.ts +14 -0
  43. package/dist/behavior-config.d.ts.map +1 -0
  44. package/dist/behavior-config.js +52 -0
  45. package/dist/behavior-config.js.map +1 -0
  46. package/dist/cli.d.ts +3 -0
  47. package/dist/cli.d.ts.map +1 -0
  48. package/dist/cli.js +626 -0
  49. package/dist/cli.js.map +1 -0
  50. package/dist/config.d.ts +31 -0
  51. package/dist/config.d.ts.map +1 -0
  52. package/dist/config.js +38 -0
  53. package/dist/config.js.map +1 -0
  54. package/dist/container-protocol.d.ts +72 -0
  55. package/dist/container-protocol.d.ts.map +1 -0
  56. package/dist/container-protocol.js +3 -0
  57. package/dist/container-protocol.js.map +1 -0
  58. package/dist/container-runner.d.ts +59 -0
  59. package/dist/container-runner.d.ts.map +1 -0
  60. package/dist/container-runner.js +813 -0
  61. package/dist/container-runner.js.map +1 -0
  62. package/dist/cost.d.ts +9 -0
  63. package/dist/cost.d.ts.map +1 -0
  64. package/dist/cost.js +11 -0
  65. package/dist/cost.js.map +1 -0
  66. package/dist/dashboard.d.ts +58 -0
  67. package/dist/dashboard.d.ts.map +1 -0
  68. package/dist/dashboard.js +471 -0
  69. package/dist/dashboard.js.map +1 -0
  70. package/dist/db.d.ts +99 -0
  71. package/dist/db.d.ts.map +1 -0
  72. package/dist/db.js +423 -0
  73. package/dist/db.js.map +1 -0
  74. package/dist/error-messages.d.ts +17 -0
  75. package/dist/error-messages.d.ts.map +1 -0
  76. package/dist/error-messages.js +109 -0
  77. package/dist/error-messages.js.map +1 -0
  78. package/dist/index.d.ts +2 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +2072 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/locks.d.ts +2 -0
  83. package/dist/locks.d.ts.map +1 -0
  84. package/dist/locks.js +26 -0
  85. package/dist/locks.js.map +1 -0
  86. package/dist/logger.d.ts +4 -0
  87. package/dist/logger.d.ts.map +1 -0
  88. package/dist/logger.js +15 -0
  89. package/dist/logger.js.map +1 -0
  90. package/dist/maintenance.d.ts +13 -0
  91. package/dist/maintenance.d.ts.map +1 -0
  92. package/dist/maintenance.js +151 -0
  93. package/dist/maintenance.js.map +1 -0
  94. package/dist/memory-embeddings.d.ts +13 -0
  95. package/dist/memory-embeddings.d.ts.map +1 -0
  96. package/dist/memory-embeddings.js +126 -0
  97. package/dist/memory-embeddings.js.map +1 -0
  98. package/dist/memory-recall.d.ts +8 -0
  99. package/dist/memory-recall.d.ts.map +1 -0
  100. package/dist/memory-recall.js +127 -0
  101. package/dist/memory-recall.js.map +1 -0
  102. package/dist/memory-store.d.ts +149 -0
  103. package/dist/memory-store.d.ts.map +1 -0
  104. package/dist/memory-store.js +787 -0
  105. package/dist/memory-store.js.map +1 -0
  106. package/dist/metrics.d.ts +12 -0
  107. package/dist/metrics.d.ts.map +1 -0
  108. package/dist/metrics.js +134 -0
  109. package/dist/metrics.js.map +1 -0
  110. package/dist/model-registry.d.ts +67 -0
  111. package/dist/model-registry.d.ts.map +1 -0
  112. package/dist/model-registry.js +230 -0
  113. package/dist/model-registry.js.map +1 -0
  114. package/dist/mount-security.d.ts +37 -0
  115. package/dist/mount-security.d.ts.map +1 -0
  116. package/dist/mount-security.js +284 -0
  117. package/dist/mount-security.js.map +1 -0
  118. package/dist/paths.d.ts +80 -0
  119. package/dist/paths.d.ts.map +1 -0
  120. package/dist/paths.js +149 -0
  121. package/dist/paths.js.map +1 -0
  122. package/dist/personalization.d.ts +6 -0
  123. package/dist/personalization.d.ts.map +1 -0
  124. package/dist/personalization.js +180 -0
  125. package/dist/personalization.js.map +1 -0
  126. package/dist/progress.d.ts +15 -0
  127. package/dist/progress.d.ts.map +1 -0
  128. package/dist/progress.js +92 -0
  129. package/dist/progress.js.map +1 -0
  130. package/dist/runtime-config.d.ts +227 -0
  131. package/dist/runtime-config.d.ts.map +1 -0
  132. package/dist/runtime-config.js +297 -0
  133. package/dist/runtime-config.js.map +1 -0
  134. package/dist/task-scheduler.d.ts +9 -0
  135. package/dist/task-scheduler.d.ts.map +1 -0
  136. package/dist/task-scheduler.js +195 -0
  137. package/dist/task-scheduler.js.map +1 -0
  138. package/dist/telegram-format.d.ts +3 -0
  139. package/dist/telegram-format.d.ts.map +1 -0
  140. package/dist/telegram-format.js +200 -0
  141. package/dist/telegram-format.js.map +1 -0
  142. package/dist/tool-budgets.d.ts +16 -0
  143. package/dist/tool-budgets.d.ts.map +1 -0
  144. package/dist/tool-budgets.js +83 -0
  145. package/dist/tool-budgets.js.map +1 -0
  146. package/dist/tool-policy.d.ts +18 -0
  147. package/dist/tool-policy.d.ts.map +1 -0
  148. package/dist/tool-policy.js +84 -0
  149. package/dist/tool-policy.js.map +1 -0
  150. package/dist/trace-writer.d.ts +39 -0
  151. package/dist/trace-writer.d.ts.map +1 -0
  152. package/dist/trace-writer.js +27 -0
  153. package/dist/trace-writer.js.map +1 -0
  154. package/dist/types.d.ts +81 -0
  155. package/dist/types.d.ts.map +1 -0
  156. package/dist/types.js +2 -0
  157. package/dist/types.js.map +1 -0
  158. package/dist/utils.d.ts +4 -0
  159. package/dist/utils.d.ts.map +1 -0
  160. package/dist/utils.js +30 -0
  161. package/dist/utils.js.map +1 -0
  162. package/launchd/com.dotclaw.plist +32 -0
  163. package/package.json +89 -0
  164. package/scripts/autotune.js +53 -0
  165. package/scripts/bootstrap.js +348 -0
  166. package/scripts/configure.js +200 -0
  167. package/scripts/doctor.js +164 -0
  168. package/scripts/init.js +209 -0
  169. package/scripts/install.sh +219 -0
  170. package/systemd/dotclaw.service +22 -0
package/dist/db.d.ts ADDED
@@ -0,0 +1,99 @@
1
+ import { NewMessage, ScheduledTask, TaskRunLog } from './types.js';
2
+ export declare function initDatabase(): void;
3
+ /**
4
+ * Store a message with full content (generic version).
5
+ * Works with any messaging platform.
6
+ */
7
+ export declare function storeMessage(msgId: string, chatId: string, senderId: string, senderName: string, content: string, timestamp: string, isFromMe: boolean): void;
8
+ export declare function getMessagesSinceCursor(chatJid: string, sinceTimestamp: string | null, sinceMessageId: string | null): NewMessage[];
9
+ export interface ChatState {
10
+ chat_jid: string;
11
+ last_agent_timestamp: string | null;
12
+ last_agent_message_id: string | null;
13
+ }
14
+ export declare function getChatState(chatJid: string): ChatState | null;
15
+ export declare function updateChatState(chatJid: string, timestamp: string, messageId: string): void;
16
+ export interface GroupSession {
17
+ group_folder: string;
18
+ session_id: string;
19
+ updated_at: string;
20
+ }
21
+ export declare function getAllGroupSessions(): GroupSession[];
22
+ export declare function setGroupSession(groupFolder: string, sessionId: string): void;
23
+ export declare function deleteGroupSession(groupFolder: string): void;
24
+ export declare function pauseTasksForGroup(groupFolder: string): number;
25
+ export declare function createTask(task: Omit<ScheduledTask, 'last_run' | 'last_result'>): void;
26
+ export declare function getTaskById(id: string): ScheduledTask | undefined;
27
+ export declare function getAllTasks(): ScheduledTask[];
28
+ export declare function updateTask(id: string, updates: Partial<Pick<ScheduledTask, 'prompt' | 'schedule_type' | 'schedule_value' | 'next_run' | 'status' | 'state_json' | 'retry_count' | 'last_error' | 'context_mode'>>): void;
29
+ export declare function deleteTask(id: string): void;
30
+ export declare function getDueTasks(): ScheduledTask[];
31
+ export declare function updateTaskAfterRun(id: string, nextRun: string | null, lastResult: string, lastError: string | null, retryCount: number): void;
32
+ export declare function logTaskRun(log: TaskRunLog): void;
33
+ export declare function logToolCalls(params: {
34
+ traceId: string;
35
+ chatJid: string;
36
+ groupFolder: string;
37
+ userId?: string | null;
38
+ toolCalls: Array<{
39
+ name: string;
40
+ ok: boolean;
41
+ duration_ms?: number;
42
+ error?: string;
43
+ output_bytes?: number;
44
+ output_truncated?: boolean;
45
+ }>;
46
+ source: string;
47
+ }): void;
48
+ export declare function getToolUsageCounts(params: {
49
+ groupFolder: string;
50
+ userId?: string | null;
51
+ since: string;
52
+ }): Array<{
53
+ tool_name: string;
54
+ count: number;
55
+ }>;
56
+ export declare function getToolReliability(params: {
57
+ groupFolder: string;
58
+ limit?: number;
59
+ }): Array<{
60
+ tool_name: string;
61
+ total: number;
62
+ ok_count: number;
63
+ avg_duration_ms: number | null;
64
+ }>;
65
+ export interface UserFeedback {
66
+ id: string;
67
+ trace_id: string;
68
+ message_id?: string;
69
+ chat_jid?: string;
70
+ feedback_type: 'positive' | 'negative';
71
+ user_id?: string;
72
+ reason?: string;
73
+ created_at: string;
74
+ }
75
+ /**
76
+ * Link a message to its trace ID for feedback lookup
77
+ */
78
+ export declare function linkMessageToTrace(messageId: string, chatJid: string, traceId: string): void;
79
+ /**
80
+ * Get trace ID for a message
81
+ */
82
+ export declare function getTraceIdForMessage(messageId: string, chatJid: string): string | null;
83
+ /**
84
+ * Record user feedback (thumbs up/down reaction)
85
+ */
86
+ export declare function recordUserFeedback(feedback: Omit<UserFeedback, 'id' | 'created_at'>): string;
87
+ /**
88
+ * Get feedback for a trace
89
+ */
90
+ export declare function getFeedbackForTrace(traceId: string): UserFeedback | null;
91
+ /**
92
+ * Get recent feedback for analytics
93
+ */
94
+ export declare function getRecentFeedback(params: {
95
+ chatJid?: string;
96
+ limit?: number;
97
+ since?: string;
98
+ }): UserFeedback[];
99
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
package/dist/db.js ADDED
@@ -0,0 +1,423 @@
1
+ import Database from 'better-sqlite3';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import { STORE_DIR } from './config.js';
5
+ let db;
6
+ let dbInitialized = false;
7
+ export function initDatabase() {
8
+ if (dbInitialized)
9
+ return;
10
+ const dbPath = path.join(STORE_DIR, 'messages.db');
11
+ fs.mkdirSync(path.dirname(dbPath), { recursive: true });
12
+ db = new Database(dbPath);
13
+ dbInitialized = true;
14
+ db.exec(`
15
+ CREATE TABLE IF NOT EXISTS chats (
16
+ jid TEXT PRIMARY KEY,
17
+ name TEXT,
18
+ last_message_time TEXT
19
+ );
20
+ CREATE TABLE IF NOT EXISTS messages (
21
+ id TEXT,
22
+ chat_jid TEXT,
23
+ sender TEXT,
24
+ sender_name TEXT,
25
+ content TEXT,
26
+ timestamp TEXT,
27
+ is_from_me INTEGER,
28
+ PRIMARY KEY (id, chat_jid),
29
+ FOREIGN KEY (chat_jid) REFERENCES chats(jid)
30
+ );
31
+ CREATE INDEX IF NOT EXISTS idx_timestamp ON messages(timestamp);
32
+
33
+ CREATE TABLE IF NOT EXISTS scheduled_tasks (
34
+ id TEXT PRIMARY KEY,
35
+ group_folder TEXT NOT NULL,
36
+ chat_jid TEXT NOT NULL,
37
+ prompt TEXT NOT NULL,
38
+ schedule_type TEXT NOT NULL,
39
+ schedule_value TEXT NOT NULL,
40
+ next_run TEXT,
41
+ last_run TEXT,
42
+ last_result TEXT,
43
+ state_json TEXT,
44
+ retry_count INTEGER DEFAULT 0,
45
+ last_error TEXT,
46
+ status TEXT DEFAULT 'active',
47
+ created_at TEXT NOT NULL
48
+ );
49
+ CREATE INDEX IF NOT EXISTS idx_next_run ON scheduled_tasks(next_run);
50
+ CREATE INDEX IF NOT EXISTS idx_status ON scheduled_tasks(status);
51
+
52
+ CREATE TABLE IF NOT EXISTS task_run_logs (
53
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
54
+ task_id TEXT NOT NULL,
55
+ run_at TEXT NOT NULL,
56
+ duration_ms INTEGER NOT NULL,
57
+ status TEXT NOT NULL,
58
+ result TEXT,
59
+ error TEXT,
60
+ FOREIGN KEY (task_id) REFERENCES scheduled_tasks(id)
61
+ );
62
+ CREATE INDEX IF NOT EXISTS idx_task_run_logs ON task_run_logs(task_id, run_at);
63
+
64
+ CREATE TABLE IF NOT EXISTS chat_state (
65
+ chat_jid TEXT PRIMARY KEY,
66
+ last_agent_timestamp TEXT,
67
+ last_agent_message_id TEXT
68
+ );
69
+
70
+ CREATE TABLE IF NOT EXISTS group_sessions (
71
+ group_folder TEXT PRIMARY KEY,
72
+ session_id TEXT NOT NULL,
73
+ updated_at TEXT NOT NULL
74
+ );
75
+
76
+ CREATE TABLE IF NOT EXISTS tool_audit (
77
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
78
+ trace_id TEXT,
79
+ chat_jid TEXT,
80
+ group_folder TEXT,
81
+ user_id TEXT,
82
+ tool_name TEXT NOT NULL,
83
+ ok INTEGER NOT NULL,
84
+ duration_ms INTEGER,
85
+ error TEXT,
86
+ created_at TEXT NOT NULL,
87
+ source TEXT
88
+ );
89
+ CREATE INDEX IF NOT EXISTS idx_tool_audit_trace ON tool_audit(trace_id);
90
+ CREATE INDEX IF NOT EXISTS idx_tool_audit_group ON tool_audit(group_folder, created_at);
91
+
92
+ CREATE TABLE IF NOT EXISTS user_feedback (
93
+ id TEXT PRIMARY KEY,
94
+ trace_id TEXT NOT NULL,
95
+ message_id TEXT,
96
+ chat_jid TEXT,
97
+ feedback_type TEXT NOT NULL,
98
+ user_id TEXT,
99
+ reason TEXT,
100
+ created_at TEXT NOT NULL
101
+ );
102
+ CREATE INDEX IF NOT EXISTS idx_feedback_trace ON user_feedback(trace_id);
103
+ CREATE INDEX IF NOT EXISTS idx_feedback_chat ON user_feedback(chat_jid, created_at);
104
+
105
+ CREATE TABLE IF NOT EXISTS message_traces (
106
+ message_id TEXT NOT NULL,
107
+ chat_jid TEXT NOT NULL,
108
+ trace_id TEXT NOT NULL,
109
+ created_at TEXT NOT NULL,
110
+ PRIMARY KEY (message_id, chat_jid)
111
+ );
112
+ CREATE INDEX IF NOT EXISTS idx_message_traces ON message_traces(trace_id);
113
+ `);
114
+ // Add sender_name column if it doesn't exist (migration for existing DBs)
115
+ try {
116
+ db.exec(`ALTER TABLE messages ADD COLUMN sender_name TEXT`);
117
+ }
118
+ catch { /* column already exists */ }
119
+ // Add context_mode column if it doesn't exist (migration for existing DBs)
120
+ try {
121
+ db.exec(`ALTER TABLE scheduled_tasks ADD COLUMN context_mode TEXT DEFAULT 'isolated'`);
122
+ }
123
+ catch { /* column already exists */ }
124
+ try {
125
+ db.exec(`ALTER TABLE scheduled_tasks ADD COLUMN state_json TEXT`);
126
+ }
127
+ catch { /* column already exists */ }
128
+ try {
129
+ db.exec(`ALTER TABLE scheduled_tasks ADD COLUMN retry_count INTEGER DEFAULT 0`);
130
+ }
131
+ catch { /* column already exists */ }
132
+ try {
133
+ db.exec(`ALTER TABLE scheduled_tasks ADD COLUMN last_error TEXT`);
134
+ }
135
+ catch { /* column already exists */ }
136
+ // Add user_id column to tool_audit if it doesn't exist
137
+ try {
138
+ db.exec(`ALTER TABLE tool_audit ADD COLUMN user_id TEXT`);
139
+ }
140
+ catch { /* column already exists */ }
141
+ }
142
+ /**
143
+ * Store a message with full content (generic version).
144
+ * Works with any messaging platform.
145
+ */
146
+ export function storeMessage(msgId, chatId, senderId, senderName, content, timestamp, isFromMe) {
147
+ db.prepare(`INSERT OR REPLACE INTO messages (id, chat_jid, sender, sender_name, content, timestamp, is_from_me) VALUES (?, ?, ?, ?, ?, ?, ?)`)
148
+ .run(msgId, chatId, senderId, senderName, content, timestamp, isFromMe ? 1 : 0);
149
+ }
150
+ export function getMessagesSinceCursor(chatJid, sinceTimestamp, sinceMessageId) {
151
+ const timestamp = sinceTimestamp || '1970-01-01T00:00:00.000Z';
152
+ const messageId = sinceMessageId || '0';
153
+ const sql = `
154
+ SELECT id, chat_jid, sender, sender_name, content, timestamp
155
+ FROM messages
156
+ WHERE chat_jid = ? AND is_from_me = 0 AND (
157
+ timestamp > ? OR (timestamp = ? AND CAST(id AS INTEGER) > CAST(? AS INTEGER))
158
+ )
159
+ ORDER BY timestamp, CAST(id AS INTEGER)
160
+ `;
161
+ return db.prepare(sql).all(chatJid, timestamp, timestamp, messageId);
162
+ }
163
+ export function getChatState(chatJid) {
164
+ const row = db.prepare(`
165
+ SELECT chat_jid, last_agent_timestamp, last_agent_message_id
166
+ FROM chat_state
167
+ WHERE chat_jid = ?
168
+ `).get(chatJid);
169
+ return row || null;
170
+ }
171
+ export function updateChatState(chatJid, timestamp, messageId) {
172
+ db.prepare(`
173
+ INSERT INTO chat_state (chat_jid, last_agent_timestamp, last_agent_message_id)
174
+ VALUES (?, ?, ?)
175
+ ON CONFLICT(chat_jid) DO UPDATE SET
176
+ last_agent_timestamp = excluded.last_agent_timestamp,
177
+ last_agent_message_id = excluded.last_agent_message_id
178
+ `).run(chatJid, timestamp, messageId);
179
+ }
180
+ export function getAllGroupSessions() {
181
+ return db.prepare(`SELECT group_folder, session_id, updated_at FROM group_sessions`).all();
182
+ }
183
+ export function setGroupSession(groupFolder, sessionId) {
184
+ const now = new Date().toISOString();
185
+ db.prepare(`
186
+ INSERT INTO group_sessions (group_folder, session_id, updated_at)
187
+ VALUES (?, ?, ?)
188
+ ON CONFLICT(group_folder) DO UPDATE SET
189
+ session_id = excluded.session_id,
190
+ updated_at = excluded.updated_at
191
+ `).run(groupFolder, sessionId, now);
192
+ }
193
+ export function deleteGroupSession(groupFolder) {
194
+ db.prepare(`DELETE FROM group_sessions WHERE group_folder = ?`).run(groupFolder);
195
+ }
196
+ export function pauseTasksForGroup(groupFolder) {
197
+ const info = db.prepare(`
198
+ UPDATE scheduled_tasks
199
+ SET status = 'paused'
200
+ WHERE group_folder = ? AND status != 'completed'
201
+ `).run(groupFolder);
202
+ return info.changes;
203
+ }
204
+ export function createTask(task) {
205
+ db.prepare(`
206
+ INSERT INTO scheduled_tasks (
207
+ id, group_folder, chat_jid, prompt, schedule_type, schedule_value, context_mode,
208
+ next_run, status, created_at, state_json, retry_count, last_error
209
+ )
210
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
211
+ `).run(task.id, task.group_folder, task.chat_jid, task.prompt, task.schedule_type, task.schedule_value, task.context_mode || 'isolated', task.next_run, task.status, task.created_at, task.state_json ?? null, task.retry_count ?? 0, task.last_error ?? null);
212
+ }
213
+ export function getTaskById(id) {
214
+ return db.prepare('SELECT * FROM scheduled_tasks WHERE id = ?').get(id);
215
+ }
216
+ export function getAllTasks() {
217
+ return db.prepare('SELECT * FROM scheduled_tasks ORDER BY created_at DESC').all();
218
+ }
219
+ export function updateTask(id, updates) {
220
+ const fields = [];
221
+ const values = [];
222
+ if (updates.prompt !== undefined) {
223
+ fields.push('prompt = ?');
224
+ values.push(updates.prompt);
225
+ }
226
+ if (updates.schedule_type !== undefined) {
227
+ fields.push('schedule_type = ?');
228
+ values.push(updates.schedule_type);
229
+ }
230
+ if (updates.schedule_value !== undefined) {
231
+ fields.push('schedule_value = ?');
232
+ values.push(updates.schedule_value);
233
+ }
234
+ if (updates.next_run !== undefined) {
235
+ fields.push('next_run = ?');
236
+ values.push(updates.next_run);
237
+ }
238
+ if (updates.status !== undefined) {
239
+ fields.push('status = ?');
240
+ values.push(updates.status);
241
+ }
242
+ if (updates.context_mode !== undefined) {
243
+ fields.push('context_mode = ?');
244
+ values.push(updates.context_mode);
245
+ }
246
+ if (updates.state_json !== undefined) {
247
+ fields.push('state_json = ?');
248
+ values.push(updates.state_json);
249
+ }
250
+ if (updates.retry_count !== undefined) {
251
+ fields.push('retry_count = ?');
252
+ values.push(updates.retry_count);
253
+ }
254
+ if (updates.last_error !== undefined) {
255
+ fields.push('last_error = ?');
256
+ values.push(updates.last_error);
257
+ }
258
+ if (fields.length === 0)
259
+ return;
260
+ values.push(id);
261
+ db.prepare(`UPDATE scheduled_tasks SET ${fields.join(', ')} WHERE id = ?`).run(...values);
262
+ }
263
+ export function deleteTask(id) {
264
+ // Delete child records first (FK constraint)
265
+ db.prepare('DELETE FROM task_run_logs WHERE task_id = ?').run(id);
266
+ db.prepare('DELETE FROM scheduled_tasks WHERE id = ?').run(id);
267
+ }
268
+ export function getDueTasks() {
269
+ const now = new Date().toISOString();
270
+ return db.prepare(`
271
+ SELECT * FROM scheduled_tasks
272
+ WHERE status = 'active' AND next_run IS NOT NULL AND next_run <= ?
273
+ ORDER BY next_run
274
+ `).all(now);
275
+ }
276
+ export function updateTaskAfterRun(id, nextRun, lastResult, lastError, retryCount) {
277
+ const now = new Date().toISOString();
278
+ db.prepare(`
279
+ UPDATE scheduled_tasks
280
+ SET next_run = ?, last_run = ?, last_result = ?, last_error = ?, retry_count = ?,
281
+ status = CASE WHEN ? IS NULL THEN 'completed' ELSE status END
282
+ WHERE id = ?
283
+ `).run(nextRun, now, lastResult, lastError, retryCount, nextRun, id);
284
+ }
285
+ export function logTaskRun(log) {
286
+ db.prepare(`
287
+ INSERT INTO task_run_logs (task_id, run_at, duration_ms, status, result, error)
288
+ VALUES (?, ?, ?, ?, ?, ?)
289
+ `).run(log.task_id, log.run_at, log.duration_ms, log.status, log.result, log.error);
290
+ }
291
+ export function logToolCalls(params) {
292
+ if (!params.toolCalls || params.toolCalls.length === 0)
293
+ return;
294
+ if (!dbInitialized) {
295
+ initDatabase();
296
+ }
297
+ const now = new Date().toISOString();
298
+ const stmt = db.prepare(`
299
+ INSERT INTO tool_audit (trace_id, chat_jid, group_folder, user_id, tool_name, ok, duration_ms, error, created_at, source)
300
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
301
+ `);
302
+ const transaction = db.transaction((calls) => {
303
+ for (const call of calls) {
304
+ stmt.run(params.traceId, params.chatJid, params.groupFolder, params.userId || null, call.name, call.ok ? 1 : 0, call.duration_ms ?? null, call.error ?? null, now, params.source);
305
+ }
306
+ });
307
+ transaction(params.toolCalls);
308
+ }
309
+ export function getToolUsageCounts(params) {
310
+ if (!dbInitialized) {
311
+ initDatabase();
312
+ }
313
+ const clauses = ['group_folder = ?', 'created_at >= ?'];
314
+ const values = [params.groupFolder, params.since];
315
+ if (params.userId) {
316
+ clauses.push('user_id = ?');
317
+ values.push(params.userId);
318
+ }
319
+ const rows = db.prepare(`
320
+ SELECT tool_name, COUNT(*) as count
321
+ FROM tool_audit
322
+ WHERE ${clauses.join(' AND ')}
323
+ GROUP BY tool_name
324
+ `).all(...values);
325
+ return rows;
326
+ }
327
+ export function getToolReliability(params) {
328
+ const limit = params.limit && params.limit > 0 ? params.limit : 200;
329
+ const rows = db.prepare(`
330
+ SELECT tool_name,
331
+ COUNT(*) as total,
332
+ SUM(ok) as ok_count,
333
+ AVG(duration_ms) as avg_duration_ms
334
+ FROM (
335
+ SELECT tool_name, ok, duration_ms
336
+ FROM tool_audit
337
+ WHERE group_folder = ?
338
+ ORDER BY created_at DESC
339
+ LIMIT ?
340
+ )
341
+ GROUP BY tool_name
342
+ `).all(params.groupFolder, limit);
343
+ return rows;
344
+ }
345
+ /**
346
+ * Link a message to its trace ID for feedback lookup
347
+ */
348
+ export function linkMessageToTrace(messageId, chatJid, traceId) {
349
+ if (!dbInitialized)
350
+ initDatabase();
351
+ const now = new Date().toISOString();
352
+ db.prepare(`
353
+ INSERT OR REPLACE INTO message_traces (message_id, chat_jid, trace_id, created_at)
354
+ VALUES (?, ?, ?, ?)
355
+ `).run(messageId, chatJid, traceId, now);
356
+ }
357
+ /**
358
+ * Get trace ID for a message
359
+ */
360
+ export function getTraceIdForMessage(messageId, chatJid) {
361
+ if (!dbInitialized)
362
+ initDatabase();
363
+ const row = db.prepare(`
364
+ SELECT trace_id FROM message_traces
365
+ WHERE message_id = ? AND chat_jid = ?
366
+ `).get(messageId, chatJid);
367
+ return row?.trace_id ?? null;
368
+ }
369
+ /**
370
+ * Record user feedback (thumbs up/down reaction)
371
+ */
372
+ export function recordUserFeedback(feedback) {
373
+ if (!dbInitialized)
374
+ initDatabase();
375
+ const id = `fb-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
376
+ const now = new Date().toISOString();
377
+ db.prepare(`
378
+ INSERT INTO user_feedback (id, trace_id, message_id, chat_jid, feedback_type, user_id, reason, created_at)
379
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
380
+ `).run(id, feedback.trace_id, feedback.message_id ?? null, feedback.chat_jid ?? null, feedback.feedback_type, feedback.user_id ?? null, feedback.reason ?? null, now);
381
+ return id;
382
+ }
383
+ /**
384
+ * Get feedback for a trace
385
+ */
386
+ export function getFeedbackForTrace(traceId) {
387
+ if (!dbInitialized)
388
+ initDatabase();
389
+ const row = db.prepare(`
390
+ SELECT * FROM user_feedback
391
+ WHERE trace_id = ?
392
+ ORDER BY created_at DESC
393
+ LIMIT 1
394
+ `).get(traceId);
395
+ return row ?? null;
396
+ }
397
+ /**
398
+ * Get recent feedback for analytics
399
+ */
400
+ export function getRecentFeedback(params) {
401
+ if (!dbInitialized)
402
+ initDatabase();
403
+ const limit = params.limit || 100;
404
+ const clauses = [];
405
+ const values = [];
406
+ if (params.chatJid) {
407
+ clauses.push('chat_jid = ?');
408
+ values.push(params.chatJid);
409
+ }
410
+ if (params.since) {
411
+ clauses.push('created_at >= ?');
412
+ values.push(params.since);
413
+ }
414
+ const whereClause = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';
415
+ const sql = `
416
+ SELECT * FROM user_feedback
417
+ ${whereClause}
418
+ ORDER BY created_at DESC
419
+ LIMIT ?
420
+ `;
421
+ return db.prepare(sql).all(...values, limit);
422
+ }
423
+ //# sourceMappingURL=db.js.map
package/dist/db.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * User-friendly error message mapping
3
+ * Converts technical errors to human-readable messages
4
+ */
5
+ /**
6
+ * Convert a technical error to a user-friendly message
7
+ */
8
+ export declare function humanizeError(error: Error | string): string;
9
+ /**
10
+ * Check if an error is likely transient and worth retrying
11
+ */
12
+ export declare function isTransientError(error: Error | string): boolean;
13
+ /**
14
+ * Determine if an error should be logged at error level vs warning
15
+ */
16
+ export declare function getErrorSeverity(error: Error | string): 'error' | 'warn' | 'info';
17
+ //# sourceMappingURL=error-messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-messages.d.ts","sourceRoot":"","sources":["../src/error-messages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkDH;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAe3D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAwB/D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAmBjF"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * User-friendly error message mapping
3
+ * Converts technical errors to human-readable messages
4
+ */
5
+ const ERROR_PATTERNS = [
6
+ // Network errors
7
+ { pattern: 'ECONNREFUSED', message: "I'm having trouble connecting to a service. Please try again in a moment." },
8
+ { pattern: 'ETIMEDOUT', message: "That took too long to complete. Let me try a simpler approach." },
9
+ { pattern: 'ENOTFOUND', message: "I couldn't reach a required service. Please check your internet connection." },
10
+ { pattern: 'ECONNRESET', message: "The connection was interrupted. Please try again." },
11
+ { pattern: 'EAI_AGAIN', message: "There was a temporary network issue. Please try again." },
12
+ // Rate limiting
13
+ { pattern: /rate.?limit/i, message: "I need to slow down a bit. Please try again in a few seconds." },
14
+ { pattern: /too many requests/i, message: "I'm being rate limited. Please wait a moment and try again." },
15
+ { pattern: /429/i, message: "I'm being rate limited. Please wait a moment and try again." },
16
+ // Context/token limits
17
+ { pattern: /context.?length/i, message: "That conversation got too long. Let me summarize and continue." },
18
+ { pattern: /maximum.?context/i, message: "We've hit the context limit. I'll need to start fresh or summarize." },
19
+ { pattern: /token.?limit/i, message: "The response was too long. Let me give you a shorter version." },
20
+ // Authentication
21
+ { pattern: /invalid.?api.?key/i, message: "There's a configuration issue with the API. Please contact the admin." },
22
+ { pattern: /unauthorized/i, message: "There's an authentication issue. Please contact the admin." },
23
+ { pattern: /401/i, message: "There's an authentication issue. Please contact the admin." },
24
+ { pattern: /403/i, message: "I don't have permission to do that. Please contact the admin." },
25
+ // Model errors
26
+ { pattern: /model.?not.?found/i, message: "The AI model isn't available right now. Trying an alternative..." },
27
+ { pattern: /model.?unavailable/i, message: "The AI model is temporarily unavailable. Please try again later." },
28
+ { pattern: /overloaded/i, message: "The AI service is busy right now. Please try again in a moment." },
29
+ // Container errors
30
+ { pattern: /container.?timeout/i, message: "That task took too long to complete. Please try with a smaller request." },
31
+ { pattern: /container.?exited/i, message: "Something went wrong while processing. Let me try again." },
32
+ // Tool errors
33
+ { pattern: /tool.?call.?limit/i, message: "I hit my limit for operations. Please narrow the scope or ask for a specific subtask." },
34
+ { pattern: /bash.?timeout/i, message: "A command took too long to run. Please try a simpler operation." },
35
+ // Generic server errors
36
+ { pattern: /500/i, message: "The server encountered an error. Please try again." },
37
+ { pattern: /502/i, message: "There's a temporary server issue. Please try again in a moment." },
38
+ { pattern: /503/i, message: "The service is temporarily unavailable. Please try again later." },
39
+ { pattern: /504/i, message: "The request timed out. Please try again." },
40
+ // Memory/resource errors
41
+ { pattern: /out of memory/i, message: "That task needed more memory than available. Please try with less data." },
42
+ { pattern: /memory.?limit/i, message: "That task needed more memory than available. Please try with less data." }
43
+ ];
44
+ /**
45
+ * Convert a technical error to a user-friendly message
46
+ */
47
+ export function humanizeError(error) {
48
+ const message = typeof error === 'string' ? error : error.message;
49
+ for (const { pattern, message: friendlyMessage } of ERROR_PATTERNS) {
50
+ if (typeof pattern === 'string') {
51
+ if (message.includes(pattern)) {
52
+ return friendlyMessage;
53
+ }
54
+ }
55
+ else if (pattern.test(message)) {
56
+ return friendlyMessage;
57
+ }
58
+ }
59
+ // Default message
60
+ return "Something went wrong. I'll try to help anyway!";
61
+ }
62
+ /**
63
+ * Check if an error is likely transient and worth retrying
64
+ */
65
+ export function isTransientError(error) {
66
+ const message = typeof error === 'string' ? error : error.message;
67
+ const transientPatterns = [
68
+ 'ECONNREFUSED',
69
+ 'ETIMEDOUT',
70
+ 'ECONNRESET',
71
+ 'EAI_AGAIN',
72
+ /rate.?limit/i,
73
+ /429/i,
74
+ /overloaded/i,
75
+ /502/i,
76
+ /503/i,
77
+ /504/i
78
+ ];
79
+ for (const pattern of transientPatterns) {
80
+ if (typeof pattern === 'string') {
81
+ if (message.includes(pattern))
82
+ return true;
83
+ }
84
+ else if (pattern.test(message)) {
85
+ return true;
86
+ }
87
+ }
88
+ return false;
89
+ }
90
+ /**
91
+ * Determine if an error should be logged at error level vs warning
92
+ */
93
+ export function getErrorSeverity(error) {
94
+ const message = typeof error === 'string' ? error : error.message;
95
+ // Transient errors are warnings
96
+ if (isTransientError(error)) {
97
+ return 'warn';
98
+ }
99
+ // Configuration issues are errors
100
+ if (/invalid.?api.?key/i.test(message) || /unauthorized/i.test(message)) {
101
+ return 'error';
102
+ }
103
+ // User-caused issues (context too long, etc) are info
104
+ if (/context.?length/i.test(message) || /token.?limit/i.test(message)) {
105
+ return 'info';
106
+ }
107
+ return 'error';
108
+ }
109
+ //# sourceMappingURL=error-messages.js.map