@emqo/claudebridge 0.6.3 → 0.7.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.
@@ -247,6 +247,14 @@ export class DiscordAdapter {
247
247
  if (res.text)
248
248
  this.store.setTaskResult(task.id, res.text.slice(0, 10000));
249
249
  await channel.send(t(this.locale, "auto_failed", { id: task.id, err: "timed out" }));
250
+ const retryMatch = task.description.match(/\[retry (\d+)\/3\]/);
251
+ const retryCount = retryMatch ? parseInt(retryMatch[1]) : 0;
252
+ if (retryCount < 3) {
253
+ const retryDesc = retryCount === 0
254
+ ? `[retry 1/3] Previous attempt of task #${task.id} timed out. Continue from where it left off: ${task.description}`
255
+ : task.description.replace(`[retry ${retryCount}/3]`, `[retry ${retryCount + 1}/3]`);
256
+ this.store.addTask(task.user_id, "discord", task.chat_id, retryDesc, undefined, true, task.parent_id || task.id, Date.now() + 120000);
257
+ }
250
258
  return;
251
259
  }
252
260
  this.store.markTaskResult(task.id, "done");
@@ -267,6 +275,15 @@ export class DiscordAdapter {
267
275
  catch (err) {
268
276
  this.store.markTaskResult(task.id, "failed");
269
277
  console.error(`[discord] auto-task #${task.id} failed:`, err);
278
+ // Self-healing: auto-retry failed tasks (max 3 retries)
279
+ const retryMatch = task.description.match(/\[retry (\d+)\/3\]/);
280
+ const retryCount = retryMatch ? parseInt(retryMatch[1]) : 0;
281
+ if (retryCount < 3) {
282
+ const retryDesc = retryCount === 0
283
+ ? `[retry 1/3] Previous attempt of task #${task.id} failed (${(err.message || "unknown").slice(0, 100)}). Analyze the failure, fix the issue, then: ${task.description}`
284
+ : task.description.replace(`[retry ${retryCount}/3]`, `[retry ${retryCount + 1}/3]`);
285
+ this.store.addTask(task.user_id, "discord", task.chat_id, retryDesc, undefined, true, task.parent_id || task.id, Date.now() + 120000);
286
+ }
270
287
  try {
271
288
  const ch = await this.client.channels.fetch(task.chat_id);
272
289
  if (ch?.isTextBased() && "send" in ch) {
@@ -401,6 +401,16 @@ export class TelegramAdapter {
401
401
  if (res.text)
402
402
  this.store.setTaskResult(task.id, res.text.slice(0, 10000));
403
403
  await this.reply(chatId, t(this.locale, "auto_failed", { id: task.id, err: "timed out" }));
404
+ // Self-healing: auto-retry timed out tasks
405
+ const retryMatch = task.description.match(/\[retry (\d+)\/3\]/);
406
+ const retryCount = retryMatch ? parseInt(retryMatch[1]) : 0;
407
+ if (retryCount < 3) {
408
+ const retryDesc = retryCount === 0
409
+ ? `[retry 1/3] Previous attempt of task #${task.id} timed out. Continue from where it left off: ${task.description}`
410
+ : task.description.replace(`[retry ${retryCount}/3]`, `[retry ${retryCount + 1}/3]`);
411
+ const retryId = this.store.addTask(task.user_id, "telegram", task.chat_id, retryDesc, undefined, true, task.parent_id || task.id, Date.now() + 120000);
412
+ await this.reply(chatId, t(this.locale, "auto_retry", { id: retryId, attempt: retryCount + 1, parent: task.id }));
413
+ }
404
414
  return;
405
415
  }
406
416
  this.store.markTaskResult(task.id, "done");
@@ -428,6 +438,16 @@ export class TelegramAdapter {
428
438
  catch (err) {
429
439
  this.store.markTaskResult(task.id, "failed");
430
440
  await this.reply(chatId, t(this.locale, "auto_failed", { id: task.id, err: err.message || "unknown" }));
441
+ // Self-healing: auto-retry failed tasks (max 3 retries)
442
+ const retryMatch = task.description.match(/\[retry (\d+)\/3\]/);
443
+ const retryCount = retryMatch ? parseInt(retryMatch[1]) : 0;
444
+ if (retryCount < 3) {
445
+ const retryDesc = retryCount === 0
446
+ ? `[retry 1/3] Previous attempt of task #${task.id} failed (${(err.message || "unknown").slice(0, 100)}). Analyze the failure, fix the issue, then: ${task.description}`
447
+ : task.description.replace(`[retry ${retryCount}/3]`, `[retry ${retryCount + 1}/3]`);
448
+ const retryId = this.store.addTask(task.user_id, "telegram", task.chat_id, retryDesc, undefined, true, task.parent_id || task.id, Date.now() + 120000);
449
+ await this.reply(chatId, t(this.locale, "auto_retry", { id: retryId, attempt: retryCount + 1, parent: task.id }));
450
+ }
431
451
  }
432
452
  }
433
453
  async checkApprovals() {
package/dist/core/i18n.js CHANGED
@@ -14,6 +14,7 @@ const messages = {
14
14
  auto_scheduled: "Auto task #{id} scheduled (executes in {minutes} min):\n{desc}",
15
15
  auto_done: "Auto task #{id} done (cost: ${cost}):",
16
16
  auto_failed: "Auto task #{id} failed: {err}",
17
+ auto_retry: "Self-healing: auto task #{parent} failed, retry #{attempt}/3 queued as task #{id} (in 2min)",
17
18
  page_expired: "Page expired. Please resend your question.",
18
19
  approval_request: "Approval needed for auto task #{id}:\n{desc}",
19
20
  approval_approved: "Auto task #{id} approved -- queued for execution.",
@@ -38,6 +39,7 @@ const messages = {
38
39
  auto_scheduled: "自动任务 #{id} 已排程({minutes} 分钟后执行):\n{desc}",
39
40
  auto_done: "自动任务 #{id} 完成(花费:${cost}):",
40
41
  auto_failed: "自动任务 #{id} 失败:{err}",
42
+ auto_retry: "自愈机制:自动任务 #{parent} 失败,重试 #{attempt}/3 已排队为任务 #{id}(2分钟后执行)",
41
43
  page_expired: "页面已过期,请重新发送问题。",
42
44
  approval_request: "自动任务 #{id} 需要审批:\n{desc}",
43
45
  approval_approved: "自动任务 #{id} 已批准 -- 已加入执行队列。",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emqo/claudebridge",
3
- "version": "0.6.3",
3
+ "version": "0.7.0",
4
4
  "description": "Bridge claude CLI to chat platforms (Telegram, Discord) with scheduled auto-tasks, autonomous project management, HITL approval, conditional branching, webhook triggers, parallel execution, and observability",
5
5
  "main": "dist/index.js",
6
6
  "bin": {