morpheus-cli 0.5.4 → 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 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 {
@@ -180,39 +180,39 @@ PHASE 1 — Query Design
180
180
  PHASE 2 — Source Discovery
181
181
  1. Call browser_search.
182
182
  2. Collect results.
183
- 3. Prioritize:
184
- - Official sources
185
- - Major authoritative publications
183
+ 3. Prioritize official sources and major publications.
186
184
  4. Reformulate query if necessary.
185
+ 5. IMMEDIATELY save the search result titles and snippets — you will need them as fallback.
187
186
 
188
187
  PHASE 3 — Source Validation
189
- 1. Try to open at least 3 distinct URLs with browser_navigate.
188
+ 1. Try to open up to 3 distinct URLs with browser_navigate.
189
+ - For news/sports/media sites (GE, Globo, UOL, Terra, ESPN, etc.): ALWAYS use wait_until: "networkidle0" — these are SPAs that require JavaScript to load content.
190
+ - For simple/static pages: use wait_until: "domcontentloaded".
190
191
  2. Read actual page content from accessible pages.
191
192
  3. Ignore inaccessible pages (timeouts, bot blocks, errors).
192
- 4. If ALL navigations fail: use the search snippets as fallback and proceed to Phase 5 with confidence level "Low".
193
+ 4. If ALL navigations fail OR page content does not contain useful information:
194
+ - DO NOT attempt further workarounds (wget, curl, python scripts, http_request).
195
+ - Use the search snippets from Phase 2 as your source and proceed to Phase 5.
193
196
 
194
197
  PHASE 4 — Cross-Verification
195
198
  1. Extract relevant information from each accessible source.
196
- 2. Compare findings:
197
- - Agreement verified
198
- - Minor differences report variation
199
- - Conflict → report discrepancy
200
- 3. Seek confirmation from at least 2 reliable sources when possible.
201
- 4. If confirmed by snippets only (all navigations failed), state:
202
- "Based on search result snippets (page content could not be accessed)."
199
+ 2. Compare findings across sources when possible.
200
+ 3. If content came from snippets only, state clearly:
201
+ "Source: DuckDuckGo search snippets (direct page access unavailable)."
203
202
 
204
203
  PHASE 5 — Structured Report
205
204
  Include:
206
- - Direct answer
207
- - Short explanation
208
- - Source URLs
205
+ - Direct answer based ONLY on what was found online
206
+ - Source URLs (from search results or navigated pages)
209
207
  - Confidence level (High / Medium / Low)
210
208
 
211
- ANTI-HALLUCINATION RULES
212
- - Never answer from prior knowledge without verification.
213
- - Never stop after reading only one source when navigation is successful.
214
- - Treat time-sensitive information as volatile.
215
- - NEVER say "no results found" when browser_search returned results — always report what was found, even if only from snippets.
209
+ ABSOLUTE RULES — NEVER VIOLATE
210
+ 1. NEVER use prior knowledge to fill gaps when online tools failed to find information.
211
+ 2. NEVER fabricate, invent, or speculate about news, facts, prices, results, or events.
212
+ 3. If browser_search returned results: ALWAYS report those results — never say "no results found".
213
+ 4. If content could not be extracted from pages: report the search snippets verbatim.
214
+ 5. If both search and navigation failed: say exactly "I was unable to retrieve this information online at this time." Stop there. Do not continue with "based on general knowledge...".
215
+ 6. Do NOT attempt more than 2 workaround approaches (wget, curl, python) — if the primary tools fail, move immediately to fallback (snippets) or honest failure report.
216
216
 
217
217
 
218
218
 
@@ -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
- : (task.error && task.error.trim().length > 0 ? task.error : 'Task failed with unknown error.');
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
- : (task.error && task.error.trim().length > 0 ? task.error : 'Task failed with unknown error.');
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