teleton 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.
- package/README.md +395 -0
- package/bin/teleton.js +2 -0
- package/dist/chunk-7NJ46ZIX.js +74 -0
- package/dist/chunk-UR2LQEKR.js +319 -0
- package/dist/chunk-WDUHRPGA.js +1930 -0
- package/dist/chunk-WXVHT6CI.js +18938 -0
- package/dist/chunk-XBGUNXF2.js +176 -0
- package/dist/cli/index.js +1055 -0
- package/dist/get-my-gifts-YKUHPRGS.js +8 -0
- package/dist/index.js +12 -0
- package/dist/memory-O5NYYWF3.js +60 -0
- package/dist/migrate-25RH22HJ.js +59 -0
- package/dist/paths-STCOKEXS.js +14 -0
- package/dist/scraper-DW5Z2AP5.js +377 -0
- package/dist/task-dependency-resolver-5I62EU67.js +133 -0
- package/dist/task-executor-ZMXWLMI7.js +144 -0
- package/dist/tasks-NUFMZNV5.js +8 -0
- package/package.json +85 -0
- package/src/templates/BOOTSTRAP.md +48 -0
- package/src/templates/IDENTITY.md +33 -0
- package/src/templates/MEMORY.md +34 -0
- package/src/templates/SOUL.md +43 -0
- package/src/templates/USER.md +36 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
// src/memory/agent/tasks.ts
|
|
2
|
+
import { randomUUID } from "crypto";
|
|
3
|
+
var TaskStore = class {
|
|
4
|
+
constructor(db) {
|
|
5
|
+
this.db = db;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Create a new task
|
|
9
|
+
*/
|
|
10
|
+
createTask(task) {
|
|
11
|
+
const id = randomUUID();
|
|
12
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
13
|
+
this.db.prepare(
|
|
14
|
+
`
|
|
15
|
+
INSERT INTO tasks (id, description, status, priority, created_by, created_at, scheduled_for, payload, reason, scheduled_message_id)
|
|
16
|
+
VALUES (?, ?, 'pending', ?, ?, ?, ?, ?, ?, ?)
|
|
17
|
+
`
|
|
18
|
+
).run(
|
|
19
|
+
id,
|
|
20
|
+
task.description,
|
|
21
|
+
task.priority ?? 0,
|
|
22
|
+
task.createdBy ?? null,
|
|
23
|
+
now,
|
|
24
|
+
task.scheduledFor ? Math.floor(task.scheduledFor.getTime() / 1e3) : null,
|
|
25
|
+
task.payload ?? null,
|
|
26
|
+
task.reason ?? null,
|
|
27
|
+
task.scheduledMessageId ?? null
|
|
28
|
+
);
|
|
29
|
+
if (task.dependsOn && task.dependsOn.length > 0) {
|
|
30
|
+
for (const parentId of task.dependsOn) {
|
|
31
|
+
this.addDependency(id, parentId);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
id,
|
|
36
|
+
description: task.description,
|
|
37
|
+
status: "pending",
|
|
38
|
+
priority: task.priority ?? 0,
|
|
39
|
+
createdBy: task.createdBy,
|
|
40
|
+
createdAt: new Date(now * 1e3),
|
|
41
|
+
scheduledFor: task.scheduledFor,
|
|
42
|
+
payload: task.payload,
|
|
43
|
+
reason: task.reason,
|
|
44
|
+
scheduledMessageId: task.scheduledMessageId
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Update a task
|
|
49
|
+
*/
|
|
50
|
+
updateTask(taskId, updates) {
|
|
51
|
+
const task = this.getTask(taskId);
|
|
52
|
+
if (!task) return void 0;
|
|
53
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
54
|
+
const updateFields = [];
|
|
55
|
+
const updateValues = [];
|
|
56
|
+
if (updates.description !== void 0) {
|
|
57
|
+
updateFields.push("description = ?");
|
|
58
|
+
updateValues.push(updates.description);
|
|
59
|
+
}
|
|
60
|
+
if (updates.status !== void 0) {
|
|
61
|
+
updateFields.push("status = ?");
|
|
62
|
+
updateValues.push(updates.status);
|
|
63
|
+
if (updates.status === "in_progress" && !task.startedAt) {
|
|
64
|
+
updateFields.push("started_at = ?");
|
|
65
|
+
updateValues.push(now);
|
|
66
|
+
}
|
|
67
|
+
if ((updates.status === "done" || updates.status === "failed" || updates.status === "cancelled") && !task.completedAt) {
|
|
68
|
+
updateFields.push("completed_at = ?");
|
|
69
|
+
updateValues.push(now);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (updates.priority !== void 0) {
|
|
73
|
+
updateFields.push("priority = ?");
|
|
74
|
+
updateValues.push(updates.priority);
|
|
75
|
+
}
|
|
76
|
+
if (updates.result !== void 0) {
|
|
77
|
+
updateFields.push("result = ?");
|
|
78
|
+
updateValues.push(updates.result);
|
|
79
|
+
}
|
|
80
|
+
if (updates.error !== void 0) {
|
|
81
|
+
updateFields.push("error = ?");
|
|
82
|
+
updateValues.push(updates.error);
|
|
83
|
+
}
|
|
84
|
+
if (updateFields.length === 0) return task;
|
|
85
|
+
updateValues.push(taskId);
|
|
86
|
+
this.db.prepare(
|
|
87
|
+
`
|
|
88
|
+
UPDATE tasks
|
|
89
|
+
SET ${updateFields.join(", ")}
|
|
90
|
+
WHERE id = ?
|
|
91
|
+
`
|
|
92
|
+
).run(...updateValues);
|
|
93
|
+
return this.getTask(taskId);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get a task by ID
|
|
97
|
+
*/
|
|
98
|
+
getTask(id) {
|
|
99
|
+
const row = this.db.prepare(`SELECT * FROM tasks WHERE id = ?`).get(id);
|
|
100
|
+
if (!row) return void 0;
|
|
101
|
+
return {
|
|
102
|
+
id: row.id,
|
|
103
|
+
description: row.description,
|
|
104
|
+
status: row.status,
|
|
105
|
+
priority: row.priority,
|
|
106
|
+
createdBy: row.created_by,
|
|
107
|
+
createdAt: new Date(row.created_at * 1e3),
|
|
108
|
+
startedAt: row.started_at ? new Date(row.started_at * 1e3) : void 0,
|
|
109
|
+
completedAt: row.completed_at ? new Date(row.completed_at * 1e3) : void 0,
|
|
110
|
+
result: row.result,
|
|
111
|
+
error: row.error,
|
|
112
|
+
scheduledFor: row.scheduled_for ? new Date(row.scheduled_for * 1e3) : void 0,
|
|
113
|
+
payload: row.payload,
|
|
114
|
+
reason: row.reason,
|
|
115
|
+
scheduledMessageId: row.scheduled_message_id
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* List tasks with optional filters
|
|
120
|
+
*/
|
|
121
|
+
listTasks(filter) {
|
|
122
|
+
let sql = `SELECT * FROM tasks WHERE 1=1`;
|
|
123
|
+
const params = [];
|
|
124
|
+
if (filter?.status) {
|
|
125
|
+
sql += ` AND status = ?`;
|
|
126
|
+
params.push(filter.status);
|
|
127
|
+
}
|
|
128
|
+
if (filter?.createdBy) {
|
|
129
|
+
sql += ` AND created_by = ?`;
|
|
130
|
+
params.push(filter.createdBy);
|
|
131
|
+
}
|
|
132
|
+
sql += ` ORDER BY priority DESC, created_at ASC`;
|
|
133
|
+
const rows = this.db.prepare(sql).all(...params);
|
|
134
|
+
return rows.map((row) => ({
|
|
135
|
+
id: row.id,
|
|
136
|
+
description: row.description,
|
|
137
|
+
status: row.status,
|
|
138
|
+
priority: row.priority,
|
|
139
|
+
createdBy: row.created_by,
|
|
140
|
+
createdAt: new Date(row.created_at * 1e3),
|
|
141
|
+
startedAt: row.started_at ? new Date(row.started_at * 1e3) : void 0,
|
|
142
|
+
completedAt: row.completed_at ? new Date(row.completed_at * 1e3) : void 0,
|
|
143
|
+
result: row.result,
|
|
144
|
+
error: row.error,
|
|
145
|
+
scheduledFor: row.scheduled_for ? new Date(row.scheduled_for * 1e3) : void 0,
|
|
146
|
+
payload: row.payload,
|
|
147
|
+
reason: row.reason,
|
|
148
|
+
scheduledMessageId: row.scheduled_message_id
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get active (pending or in_progress) tasks
|
|
153
|
+
*/
|
|
154
|
+
getActiveTasks() {
|
|
155
|
+
const rows = this.db.prepare(
|
|
156
|
+
`
|
|
157
|
+
SELECT * FROM tasks
|
|
158
|
+
WHERE status IN ('pending', 'in_progress')
|
|
159
|
+
ORDER BY priority DESC, created_at ASC
|
|
160
|
+
`
|
|
161
|
+
).all();
|
|
162
|
+
return rows.map((row) => ({
|
|
163
|
+
id: row.id,
|
|
164
|
+
description: row.description,
|
|
165
|
+
status: row.status,
|
|
166
|
+
priority: row.priority,
|
|
167
|
+
createdBy: row.created_by,
|
|
168
|
+
createdAt: new Date(row.created_at * 1e3),
|
|
169
|
+
startedAt: row.started_at ? new Date(row.started_at * 1e3) : void 0,
|
|
170
|
+
completedAt: row.completed_at ? new Date(row.completed_at * 1e3) : void 0,
|
|
171
|
+
result: row.result,
|
|
172
|
+
error: row.error,
|
|
173
|
+
scheduledFor: row.scheduled_for ? new Date(row.scheduled_for * 1e3) : void 0,
|
|
174
|
+
payload: row.payload,
|
|
175
|
+
reason: row.reason,
|
|
176
|
+
scheduledMessageId: row.scheduled_message_id
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Delete a task
|
|
181
|
+
*/
|
|
182
|
+
deleteTask(taskId) {
|
|
183
|
+
const result = this.db.prepare(`DELETE FROM tasks WHERE id = ?`).run(taskId);
|
|
184
|
+
return result.changes > 0;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Mark task as done
|
|
188
|
+
*/
|
|
189
|
+
completeTask(taskId, result) {
|
|
190
|
+
return this.updateTask(taskId, { status: "done", result });
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Mark task as failed
|
|
194
|
+
*/
|
|
195
|
+
failTask(taskId, error) {
|
|
196
|
+
return this.updateTask(taskId, { status: "failed", error });
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Start a task
|
|
200
|
+
*/
|
|
201
|
+
startTask(taskId) {
|
|
202
|
+
return this.updateTask(taskId, { status: "in_progress" });
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Cancel a task
|
|
206
|
+
*/
|
|
207
|
+
cancelTask(taskId) {
|
|
208
|
+
return this.updateTask(taskId, { status: "cancelled" });
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Check if adding a dependency would create a cycle
|
|
212
|
+
* Uses BFS to traverse dependency graph
|
|
213
|
+
*/
|
|
214
|
+
wouldCreateCycle(taskId, newParentId) {
|
|
215
|
+
if (taskId === newParentId) {
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
const visited = /* @__PURE__ */ new Set();
|
|
219
|
+
const queue = [newParentId];
|
|
220
|
+
while (queue.length > 0) {
|
|
221
|
+
const current = queue.shift();
|
|
222
|
+
if (current === taskId) {
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
if (visited.has(current)) {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
visited.add(current);
|
|
229
|
+
const deps = this.getDependencies(current);
|
|
230
|
+
queue.push(...deps);
|
|
231
|
+
}
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Add a dependency (taskId depends on parentTaskId)
|
|
236
|
+
* Throws error if would create circular dependency
|
|
237
|
+
*/
|
|
238
|
+
addDependency(taskId, parentTaskId) {
|
|
239
|
+
if (this.wouldCreateCycle(taskId, parentTaskId)) {
|
|
240
|
+
throw new Error(
|
|
241
|
+
`Cannot add dependency: would create circular dependency (${taskId} \u2192 ${parentTaskId})`
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
this.db.prepare(`INSERT OR IGNORE INTO task_dependencies (task_id, depends_on_task_id) VALUES (?, ?)`).run(taskId, parentTaskId);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Get all tasks that this task depends on
|
|
248
|
+
*/
|
|
249
|
+
getDependencies(taskId) {
|
|
250
|
+
const rows = this.db.prepare(`SELECT depends_on_task_id FROM task_dependencies WHERE task_id = ?`).all(taskId);
|
|
251
|
+
return rows.map((r) => r.depends_on_task_id);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Get all tasks that depend on this task
|
|
255
|
+
*/
|
|
256
|
+
getDependents(taskId) {
|
|
257
|
+
const rows = this.db.prepare(`SELECT task_id FROM task_dependencies WHERE depends_on_task_id = ?`).all(taskId);
|
|
258
|
+
return rows.map((r) => r.task_id);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Check if a task can execute (all dependencies are done)
|
|
262
|
+
* Optimized: Single query with JOIN instead of N+1 queries
|
|
263
|
+
*/
|
|
264
|
+
canExecute(taskId) {
|
|
265
|
+
const result = this.db.prepare(
|
|
266
|
+
`
|
|
267
|
+
SELECT COUNT(*) as pending_count
|
|
268
|
+
FROM task_dependencies td
|
|
269
|
+
LEFT JOIN tasks t ON td.depends_on_task_id = t.id
|
|
270
|
+
WHERE td.task_id = ?
|
|
271
|
+
AND (t.id IS NULL OR t.status != 'done')
|
|
272
|
+
`
|
|
273
|
+
).get(taskId);
|
|
274
|
+
return result.pending_count === 0;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Get all parent task results for a dependent task
|
|
278
|
+
* Optimized: Single query with JOIN instead of N+1 queries
|
|
279
|
+
*/
|
|
280
|
+
getParentResults(taskId) {
|
|
281
|
+
const rows = this.db.prepare(
|
|
282
|
+
`
|
|
283
|
+
SELECT t.id, t.description, t.result
|
|
284
|
+
FROM task_dependencies td
|
|
285
|
+
JOIN tasks t ON td.depends_on_task_id = t.id
|
|
286
|
+
WHERE td.task_id = ?
|
|
287
|
+
AND t.status = 'done'
|
|
288
|
+
AND t.result IS NOT NULL
|
|
289
|
+
`
|
|
290
|
+
).all(taskId);
|
|
291
|
+
return rows.map((row) => {
|
|
292
|
+
let parsedResult;
|
|
293
|
+
try {
|
|
294
|
+
parsedResult = JSON.parse(row.result);
|
|
295
|
+
} catch (e) {
|
|
296
|
+
parsedResult = row.result;
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
taskId: row.id,
|
|
300
|
+
description: row.description,
|
|
301
|
+
result: parsedResult
|
|
302
|
+
};
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
var instances = /* @__PURE__ */ new WeakMap();
|
|
307
|
+
function getTaskStore(db) {
|
|
308
|
+
let store = instances.get(db);
|
|
309
|
+
if (!store) {
|
|
310
|
+
store = new TaskStore(db);
|
|
311
|
+
instances.set(db, store);
|
|
312
|
+
}
|
|
313
|
+
return store;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export {
|
|
317
|
+
TaskStore,
|
|
318
|
+
getTaskStore
|
|
319
|
+
};
|