appback-remoteagent 0.14.3 → 0.14.4

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.
Files changed (2) hide show
  1. package/dist/bot.js +66 -18
  2. package/package.json +1 -1
package/dist/bot.js CHANGED
@@ -1087,10 +1087,14 @@ async function runWithPendingAnimation(botToken, chatId, task) {
1087
1087
  const rendered = formatProviderTelegramChunks(progressChunks, parseMode);
1088
1088
  const extra = rendered.parseMode ? { parse_mode: rendered.parseMode } : undefined;
1089
1089
  for (const chunk of rendered.chunks) {
1090
- await sendTelegramMessage(botToken, chatId, chunk, extra);
1090
+ await sendTelegramMessage(botToken, chatId, chunk, extra).catch((error) => {
1091
+ console.warn(`[telegram-progress-delivery] chat=${chatId} dropped progress message: ${formatTelegramDeliveryError(error)}`);
1092
+ });
1091
1093
  }
1092
1094
  if (normalized.documents.length > 0) {
1093
- await sendTelegramDocuments(botToken, chatId, normalized.documents);
1095
+ await sendTelegramDocuments(botToken, chatId, normalized.documents).catch((error) => {
1096
+ console.warn(`[telegram-progress-delivery] chat=${chatId} dropped progress document(s): ${formatTelegramDeliveryError(error)}`);
1097
+ });
1094
1098
  }
1095
1099
  },
1096
1100
  };
@@ -2233,23 +2237,38 @@ async function sendTelegramDocument(botToken, chatId, document) {
2233
2237
  async function sendTelegramMessage(botToken, chatId, text, extra) {
2234
2238
  const startedAt = Date.now();
2235
2239
  try {
2236
- try {
2237
- return await callTelegramApi(botToken, "sendMessage", {
2238
- chat_id: String(chatId),
2239
- text,
2240
- parse_mode: extra?.parse_mode,
2241
- });
2242
- }
2243
- catch (error) {
2244
- if (!extra?.parse_mode || !isTelegramEntityParseError(error)) {
2245
- throw error;
2240
+ let lastError;
2241
+ for (let attempt = 1; attempt <= 3; attempt += 1) {
2242
+ try {
2243
+ try {
2244
+ return await callTelegramApi(botToken, "sendMessage", {
2245
+ chat_id: String(chatId),
2246
+ text,
2247
+ parse_mode: extra?.parse_mode,
2248
+ });
2249
+ }
2250
+ catch (error) {
2251
+ if (!extra?.parse_mode || !isTelegramEntityParseError(error)) {
2252
+ throw error;
2253
+ }
2254
+ console.warn(`[telegram-sendMessage-fallback] chat=${chatId} parseMode=${extra.parse_mode}: ${formatTelegramDeliveryError(error)}`);
2255
+ return await callTelegramApi(botToken, "sendMessage", {
2256
+ chat_id: String(chatId),
2257
+ text: stripTelegramHtml(text),
2258
+ });
2259
+ }
2260
+ }
2261
+ catch (error) {
2262
+ lastError = error;
2263
+ if (attempt >= 3 || !isRetryableTelegramDeliveryError(error)) {
2264
+ throw error;
2265
+ }
2266
+ const delayMs = attempt * 1500;
2267
+ console.warn(`[telegram-sendMessage-retry] chat=${chatId} attempt=${attempt}/3 delayMs=${delayMs}: ${formatTelegramDeliveryError(error)}`);
2268
+ await sleep(delayMs);
2246
2269
  }
2247
- console.warn(`[telegram-sendMessage-fallback] chat=${chatId} parseMode=${extra.parse_mode}: ${error instanceof Error ? error.message : String(error)}`);
2248
- return await callTelegramApi(botToken, "sendMessage", {
2249
- chat_id: String(chatId),
2250
- text: stripTelegramHtml(text),
2251
- });
2252
2270
  }
2271
+ throw lastError instanceof Error ? lastError : new Error(String(lastError));
2253
2272
  }
2254
2273
  finally {
2255
2274
  const elapsedMs = Date.now() - startedAt;
@@ -2289,7 +2308,16 @@ async function callTelegramApi(botToken, method, params) {
2289
2308
  args.push("--data-urlencode", `${key}=${value}`);
2290
2309
  }
2291
2310
  }
2292
- const { stdout, stderr } = await execFileAsync("curl", args);
2311
+ let stdout;
2312
+ let stderr;
2313
+ try {
2314
+ const result = await execFileAsync("curl", args);
2315
+ stdout = result.stdout;
2316
+ stderr = result.stderr;
2317
+ }
2318
+ catch (error) {
2319
+ throw new TelegramApiError(method, summarizeCurlTelegramError(error, method));
2320
+ }
2293
2321
  if (stderr?.trim()) {
2294
2322
  console.error(`curl stderr for ${method}: ${stderr.trim()}`);
2295
2323
  }
@@ -2309,6 +2337,26 @@ class TelegramApiError extends Error {
2309
2337
  this.name = "TelegramApiError";
2310
2338
  }
2311
2339
  }
2340
+ function summarizeCurlTelegramError(error, method) {
2341
+ if (!(error instanceof Error)) {
2342
+ return `Telegram API ${method} failed: ${String(error)}`;
2343
+ }
2344
+ const stderr = typeof error === "object" && error !== null && "stderr" in error
2345
+ ? String(error.stderr ?? "").trim()
2346
+ : "";
2347
+ const code = typeof error === "object" && error !== null && "code" in error
2348
+ ? String(error.code ?? "")
2349
+ : "";
2350
+ const message = stderr || error.message;
2351
+ return [`Telegram API ${method} curl failed`, code ? `code=${code}` : undefined, message].filter(Boolean).join(": ");
2352
+ }
2353
+ function formatTelegramDeliveryError(error) {
2354
+ return error instanceof Error ? error.message : String(error);
2355
+ }
2356
+ function isRetryableTelegramDeliveryError(error) {
2357
+ const message = formatTelegramDeliveryError(error);
2358
+ return /timed out|timeout|Bad Gateway|502|503|504|ECONNRESET|connection reset|EAI_AGAIN|ENOTFOUND/i.test(message);
2359
+ }
2312
2360
  function isTelegramForbiddenError(error) {
2313
2361
  if (error instanceof GrammyError) {
2314
2362
  return error.error_code === 403 || /^Forbidden:/i.test(error.description);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appback-remoteagent",
3
- "version": "0.14.3",
3
+ "version": "0.14.4",
4
4
  "description": "Personal installable session server for continuing local AI work across PC and Telegram",
5
5
  "license": "MIT",
6
6
  "type": "module",