@emqo/claudebridge 0.5.2 → 0.5.3

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.
@@ -242,6 +242,13 @@ export class DiscordAdapter {
242
242
  const res = this.maxParallel > 1
243
243
  ? await this.engine.runParallel(task.user_id, task.description, "discord", task.chat_id)
244
244
  : await this.engine.runStream(task.user_id, task.description, "discord", task.chat_id);
245
+ if (res.timedOut) {
246
+ this.store.markTaskResult(task.id, "failed");
247
+ if (res.text)
248
+ this.store.setTaskResult(task.id, res.text.slice(0, 10000));
249
+ await channel.send(t(this.locale, "auto_failed", { id: task.id, err: "timed out" }));
250
+ return;
251
+ }
245
252
  this.store.markTaskResult(task.id, "done");
246
253
  if (res.text)
247
254
  this.store.setTaskResult(task.id, res.text.slice(0, 10000));
@@ -396,14 +396,28 @@ export class TelegramAdapter {
396
396
  const res = this.maxParallel > 1
397
397
  ? await this.engine.runParallel(task.user_id, task.description, "telegram", task.chat_id)
398
398
  : await this.engine.runStream(task.user_id, task.description, "telegram", task.chat_id);
399
+ if (res.timedOut) {
400
+ this.store.markTaskResult(task.id, "failed");
401
+ if (res.text)
402
+ this.store.setTaskResult(task.id, res.text.slice(0, 10000));
403
+ await this.reply(chatId, t(this.locale, "auto_failed", { id: task.id, err: "timed out" }));
404
+ return;
405
+ }
399
406
  this.store.markTaskResult(task.id, "done");
400
407
  if (res.text)
401
408
  this.store.setTaskResult(task.id, res.text.slice(0, 10000));
402
409
  const maxLen = this.config.chunk_size || 4000;
403
- const chunks = chunkText(res.text || "(no output)", maxLen);
410
+ const rawChunks = chunkText(res.text || "(no output)", maxLen);
411
+ const mdChunks = chunkText(toTelegramMarkdown(res.text || "(no output)"), maxLen);
404
412
  await this.reply(chatId, t(this.locale, "auto_done", { id: task.id, cost: (res.cost || 0).toFixed(4) }));
405
- for (const c of chunks)
406
- await this.reply(chatId, c);
413
+ for (let i = 0; i < mdChunks.length; i++) {
414
+ try {
415
+ await this.call("sendMessage", { chat_id: chatId, text: mdChunks[i], parse_mode: "MarkdownV2" });
416
+ }
417
+ catch {
418
+ await this.reply(chatId, rawChunks[i] || mdChunks[i]);
419
+ }
420
+ }
407
421
  // Chain progress reporting
408
422
  if (task.parent_id) {
409
423
  const progress = this.store.getChainProgress(task.parent_id);
@@ -6,6 +6,7 @@ export interface AgentResponse {
6
6
  text: string;
7
7
  sessionId: string;
8
8
  cost?: number;
9
+ timedOut?: boolean;
9
10
  }
10
11
  export type StreamCallback = (chunk: string, full: string) => void | Promise<void>;
11
12
  export declare class AgentEngine {
@@ -150,7 +150,7 @@ export class AgentEngine {
150
150
  const child = spawn("claude", args, { cwd, env, stdio: ["pipe", "pipe", "pipe"] });
151
151
  child.stdin.end();
152
152
  console.log(`[agent] spawned claude pid=${child.pid} cwd=${cwd} args=${args.join(" ")}`);
153
- const timeoutMs = (this.config.agent.timeout_seconds || 300) * 1000;
153
+ const timeoutMs = (this.config.agent.timeout_seconds || 600) * 1000;
154
154
  const timer = setTimeout(() => { try {
155
155
  child.kill("SIGTERM");
156
156
  }
@@ -205,9 +205,10 @@ export class AgentEngine {
205
205
  clearTimeout(timer);
206
206
  console.log(`[agent] claude exited code=${code} signal=${signal} fullText=${fullText.length}chars stderr=${stderr.slice(0, 200)}`);
207
207
  if (signal === "SIGTERM") {
208
+ console.warn(`[agent] claude timed out after ${timeoutMs / 1000}s`);
208
209
  if (newSessionId)
209
210
  this.store.setSession(userId, newSessionId, platform);
210
- resolve({ text: fullText.trim() || "(timed out)", sessionId: newSessionId, cost });
211
+ resolve({ text: fullText.trim() || "(timed out)", sessionId: newSessionId, cost, timedOut: true });
211
212
  return;
212
213
  }
213
214
  if (code === 0 || fullText.trim()) {
@@ -256,7 +257,7 @@ export class AgentEngine {
256
257
  const child = spawn("claude", args, { cwd, env, stdio: ["pipe", "pipe", "pipe"] });
257
258
  child.stdin.end();
258
259
  console.log(`[agent] spawned claude (parallel) pid=${child.pid} cwd=${cwd}`);
259
- const timeoutMs = (this.config.agent.timeout_seconds || 300) * 1000;
260
+ const timeoutMs = (this.config.agent.timeout_seconds || 600) * 1000;
260
261
  const timer = setTimeout(() => { try {
261
262
  child.kill("SIGTERM");
262
263
  }
@@ -301,8 +302,12 @@ export class AgentEngine {
301
302
  child.on("close", (code, signal) => {
302
303
  clearTimeout(timer);
303
304
  console.log(`[agent] claude (parallel) exited code=${code} signal=${signal} text=${fullText.length}chars`);
304
- if (code === 0 || fullText.trim() || signal === "SIGTERM") {
305
- resolve({ text: fullText.trim() || (signal === "SIGTERM" ? "(timed out)" : "(no response)"), sessionId, cost });
305
+ if (signal === "SIGTERM") {
306
+ console.warn(`[agent] claude (parallel) timed out after ${timeoutMs / 1000}s`);
307
+ resolve({ text: fullText.trim() || "(timed out)", sessionId, cost, timedOut: true });
308
+ }
309
+ else if (code === 0 || fullText.trim()) {
310
+ resolve({ text: fullText.trim() || "(no response)", sessionId, cost });
306
311
  }
307
312
  else {
308
313
  reject(new Error(`claude exited ${code}: ${stderr.slice(0, 500)}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emqo/claudebridge",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Bridge claude CLI to chat platforms (Telegram, Discord) with HITL approval, conditional branching, webhook triggers, parallel execution, and observability",
5
5
  "main": "dist/index.js",
6
6
  "bin": {