morpheus-cli 0.5.5 → 0.5.6
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/dist/http/api.js +12 -0
- package/dist/runtime/tasks/dispatcher.js +8 -4
- package/dist/runtime/tasks/repository.js +17 -4
- package/dist/ui/assets/{index-DP2V4kRd.js → index-BC40Mg99.js} +21 -21
- package/dist/ui/assets/index-Dgdart9S.css +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/ui/sw.js +1 -1
- package/package.json +1 -1
- package/dist/ui/assets/index-mglRG5Zw.css +0 -1
package/dist/http/api.js
CHANGED
|
@@ -248,6 +248,18 @@ export function createApiRouter(oracle) {
|
|
|
248
248
|
res.status(500).json({ error: err.message });
|
|
249
249
|
}
|
|
250
250
|
});
|
|
251
|
+
router.post('/tasks/:id/cancel', (req, res) => {
|
|
252
|
+
try {
|
|
253
|
+
const ok = taskRepository.cancelTask(req.params.id);
|
|
254
|
+
if (!ok) {
|
|
255
|
+
return res.status(404).json({ error: 'Active task not found for cancellation' });
|
|
256
|
+
}
|
|
257
|
+
res.json({ success: true });
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
res.status(500).json({ error: err.message });
|
|
261
|
+
}
|
|
262
|
+
});
|
|
251
263
|
// Legacy /session/reset (keep for backward compat or redirect to POST /sessions)
|
|
252
264
|
router.post('/session/reset', async (req, res) => {
|
|
253
265
|
try {
|
|
@@ -43,10 +43,12 @@ export class TaskDispatcher {
|
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
if (task.origin_channel === 'ui') {
|
|
46
|
-
const statusIcon = task.status === 'completed' ? '✅' : '❌';
|
|
46
|
+
const statusIcon = task.status === 'completed' ? '✅' : task.status === 'cancelled' ? '🚫' : '❌';
|
|
47
47
|
const body = task.status === 'completed'
|
|
48
48
|
? (task.output && task.output.trim().length > 0 ? task.output : 'Task completed without output.')
|
|
49
|
-
:
|
|
49
|
+
: task.status === 'cancelled'
|
|
50
|
+
? 'Task was cancelled.'
|
|
51
|
+
: (task.error && task.error.trim().length > 0 ? task.error : 'Task failed with unknown error.');
|
|
50
52
|
const content = `${statusIcon}\ Task \`${task.id.toUpperCase()}\`\n` +
|
|
51
53
|
`Agent: \`${task.agent.toUpperCase()}\`\n` +
|
|
52
54
|
`Status: \`${task.status.toUpperCase()}\`\n\n${body}`;
|
|
@@ -70,10 +72,12 @@ export class TaskDispatcher {
|
|
|
70
72
|
if (!adapter) {
|
|
71
73
|
throw new Error('Telegram adapter not connected');
|
|
72
74
|
}
|
|
73
|
-
const statusIcon = task.status === 'completed' ? '✅' : '❌';
|
|
75
|
+
const statusIcon = task.status === 'completed' ? '✅' : task.status === 'cancelled' ? '🚫' : '❌';
|
|
74
76
|
const body = task.status === 'completed'
|
|
75
77
|
? (task.output && task.output.trim().length > 0 ? task.output : 'Task completed without output.')
|
|
76
|
-
:
|
|
78
|
+
: task.status === 'cancelled'
|
|
79
|
+
? 'Task was cancelled.'
|
|
80
|
+
: (task.error && task.error.trim().length > 0 ? task.error : 'Task failed with unknown error.');
|
|
77
81
|
const header = `${statusIcon}\ Task \`${task.id.toUpperCase()}\`\n` +
|
|
78
82
|
`Agent: \`${task.agent.toUpperCase()}\`\n` +
|
|
79
83
|
`Status: \`${task.status.toUpperCase()}\``;
|
|
@@ -240,7 +240,7 @@ export class TaskRepository {
|
|
|
240
240
|
notify_status = 'pending',
|
|
241
241
|
notify_last_error = NULL,
|
|
242
242
|
notified_at = NULL
|
|
243
|
-
WHERE id = ?
|
|
243
|
+
WHERE id = ? AND status != 'cancelled'
|
|
244
244
|
`).run(normalizedOutput.length > 0 ? normalizedOutput : 'Task completed without output.', now, now, id);
|
|
245
245
|
}
|
|
246
246
|
markFailed(id, error) {
|
|
@@ -253,9 +253,22 @@ export class TaskRepository {
|
|
|
253
253
|
updated_at = ?,
|
|
254
254
|
notify_status = 'pending',
|
|
255
255
|
notified_at = NULL
|
|
256
|
-
WHERE id = ?
|
|
256
|
+
WHERE id = ? AND status != 'cancelled'
|
|
257
257
|
`).run(error, now, now, id);
|
|
258
258
|
}
|
|
259
|
+
cancelTask(id) {
|
|
260
|
+
const now = Date.now();
|
|
261
|
+
const result = this.db.prepare(`
|
|
262
|
+
UPDATE tasks
|
|
263
|
+
SET status = 'cancelled',
|
|
264
|
+
finished_at = ?,
|
|
265
|
+
updated_at = ?,
|
|
266
|
+
notify_status = 'pending',
|
|
267
|
+
notified_at = NULL
|
|
268
|
+
WHERE id = ? AND status IN ('pending', 'running')
|
|
269
|
+
`).run(now, now, id);
|
|
270
|
+
return result.changes > 0;
|
|
271
|
+
}
|
|
259
272
|
retryTask(id) {
|
|
260
273
|
const now = Date.now();
|
|
261
274
|
const result = this.db.prepare(`
|
|
@@ -306,7 +319,7 @@ export class TaskRepository {
|
|
|
306
319
|
const row = this.db.prepare(`
|
|
307
320
|
SELECT id
|
|
308
321
|
FROM tasks
|
|
309
|
-
WHERE status IN ('completed', 'failed')
|
|
322
|
+
WHERE status IN ('completed', 'failed', 'cancelled')
|
|
310
323
|
AND notify_status = 'pending'
|
|
311
324
|
AND finished_at IS NOT NULL
|
|
312
325
|
AND finished_at <= ?
|
|
@@ -338,7 +351,7 @@ export class TaskRepository {
|
|
|
338
351
|
SET notify_status = 'pending',
|
|
339
352
|
notify_last_error = COALESCE(notify_last_error, 'Recovered notification queue state'),
|
|
340
353
|
updated_at = ?
|
|
341
|
-
WHERE status IN ('completed', 'failed')
|
|
354
|
+
WHERE status IN ('completed', 'failed', 'cancelled')
|
|
342
355
|
AND (
|
|
343
356
|
(notify_status = 'sending' AND updated_at <= ?)
|
|
344
357
|
OR
|