@pixelbyte-software/pixcode 1.53.7 → 1.53.9

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.
@@ -9,11 +9,14 @@ const TERMINAL_RUN_STATES = new Set(['completed', 'failed', 'canceled']);
9
9
  const CALLBACK_TTL_MS = 10 * 60 * 1000;
10
10
  const MAX_CALLBACK_ACTIONS = 1000;
11
11
  const MAX_TELEGRAM_TEXT = 3600;
12
+ const MAX_ACTIVITY_OUTPUT_CHARS = 48_000;
13
+ const MAX_SSE_BUFFER_CHARS = 256_000;
12
14
  const ACTIVITY_EDIT_THROTTLE_MS = 1200;
13
15
  const ACTIVITY_HEARTBEAT_MS = 8000;
14
16
  const INTENT_ROUTER_TIMEOUT_MS = 45_000;
15
17
  const callbackActions = new Map();
16
18
  const runMonitors = new Map();
19
+ const activeLongTasks = new Map();
17
20
  const MODEL_FALLBACKS = Object.fromEntries(PROVIDERS.map((provider) => [provider, getStaticProviderModels(provider)]));
18
21
  const AUTH_HELP = {
19
22
  claude: '`claude login`',
@@ -59,6 +62,15 @@ function truncate(text, max = MAX_TELEGRAM_TEXT) {
59
62
  const value = String(text || '').trim();
60
63
  return value.length > max ? `${value.slice(0, max - 20)}\n\n…truncated…` : value;
61
64
  }
65
+ function appendBoundedText(current, chunk, maxChars = MAX_ACTIVITY_OUTPUT_CHARS) {
66
+ const nextChunk = String(chunk || '');
67
+ if (!nextChunk)
68
+ return { text: current || '', truncated: false };
69
+ const combined = `${current || ''}${nextChunk}`;
70
+ if (combined.length <= maxChars)
71
+ return { text: combined, truncated: false };
72
+ return { text: combined.slice(-maxChars), truncated: true };
73
+ }
62
74
  function languageFor(link) {
63
75
  return SUPPORTED_LANGUAGES.includes(link?.language) ? link.language : 'en';
64
76
  }
@@ -278,6 +290,9 @@ async function localAgentStream(userId, body, onEvent) {
278
290
  if (done)
279
291
  break;
280
292
  buffer += decoder.decode(value, { stream: true });
293
+ if (buffer.length > MAX_SSE_BUFFER_CHARS) {
294
+ buffer = buffer.slice(-MAX_SSE_BUFFER_CHARS);
295
+ }
281
296
  let boundary = buffer.indexOf('\n\n');
282
297
  while (boundary !== -1) {
283
298
  const block = buffer.slice(0, boundary);
@@ -322,6 +337,7 @@ function createActivityState({ lang, type = 'agent', provider, project, prompt,
322
337
  workflowId: null,
323
338
  events: [],
324
339
  output: '',
340
+ outputTruncated: false,
325
341
  error: null,
326
342
  };
327
343
  }
@@ -350,11 +366,20 @@ function trimTelegramOutput(text, max, suffix = '') {
350
366
  const room = Math.max(300, max - ending.length - 4);
351
367
  return `${value.slice(0, room).trim()}\n\n${ending}`;
352
368
  }
369
+ function appendActivityOutput(activity, chunk) {
370
+ if (!activity)
371
+ return;
372
+ const next = appendBoundedText(activity.output, chunk);
373
+ activity.output = next.text;
374
+ activity.outputTruncated = Boolean(activity.outputTruncated || next.truncated);
375
+ }
353
376
  function renderActivity(activity, { finalText = null } = {}) {
354
377
  const output = finalText || activity.output;
355
378
  if (activity.type === 'agent' && output && !activity.error) {
356
379
  if (activity.status === 'done') {
357
- return trimTelegramOutput(output, 3400, t(activity.lang, 'control.activity.outputTooLong'));
380
+ return trimTelegramOutput(output, 3400, activity.outputTruncated
381
+ ? t(activity.lang, 'control.activity.outputHistoryTrimmed')
382
+ : t(activity.lang, 'control.activity.outputTooLong'));
358
383
  }
359
384
  const footer = `⏳ ${t(activity.lang, 'control.activity.liveFooter', { elapsed: formatElapsed(activity.startedAt) })}`;
360
385
  const body = trimTelegramOutput(output, 3200, t(activity.lang, 'control.activity.outputShortened'));
@@ -760,13 +785,13 @@ function applyAgentStreamEvent(activity, event) {
760
785
  if (event.kind === 'stream_delta' || event.kind === 'text') {
761
786
  activity.status = 'running';
762
787
  activity.phase = t(activity.lang, 'control.activity.responding');
763
- activity.output = `${activity.output}${extractTextFromEvent(event)}`;
788
+ appendActivityOutput(activity, extractTextFromEvent(event));
764
789
  return;
765
790
  }
766
791
  if (event.type === 'claude-response' && event.data?.type === 'assistant') {
767
792
  activity.status = 'running';
768
793
  activity.phase = t(activity.lang, 'control.activity.responding');
769
- activity.output = `${activity.output}${extractTextFromEvent(event)}`;
794
+ appendActivityOutput(activity, extractTextFromEvent(event));
770
795
  return;
771
796
  }
772
797
  if (event.kind === 'tool_use') {
@@ -891,6 +916,43 @@ async function runAgent({ bot, chatId, link, prompt, activity = null }) {
891
916
  active.output = t(lang, 'control.noAssistantText');
892
917
  await editTelegramActivity({ bot, chatId, activity: active, force: true });
893
918
  }
919
+ function longTaskKey(chatId) {
920
+ return String(chatId);
921
+ }
922
+ async function launchLongTelegramTask({ bot, chatId, link, kind, activity = null, task }) {
923
+ const key = longTaskKey(chatId);
924
+ const existing = activeLongTasks.get(key);
925
+ const lang = languageFor(link);
926
+ if (existing) {
927
+ await send(bot, chatId, t(lang, 'control.longTaskRunning', {
928
+ kind: existing.kind,
929
+ elapsed: formatElapsed(existing.startedAt),
930
+ }), {
931
+ editMessageId: activity?.messageId,
932
+ parse_mode: undefined,
933
+ });
934
+ return true;
935
+ }
936
+ const record = {
937
+ kind,
938
+ startedAt: Date.now(),
939
+ };
940
+ activeLongTasks.set(key, record);
941
+ Promise.resolve()
942
+ .then(task)
943
+ .catch(async (error) => {
944
+ console.error('[telegram-control] long task failed:', error);
945
+ await send(bot, chatId, t(lang, 'control.longTaskFailed'), {
946
+ editMessageId: activity?.messageId,
947
+ parse_mode: undefined,
948
+ }).catch(() => { });
949
+ })
950
+ .finally(() => {
951
+ if (activeLongTasks.get(key) === record)
952
+ activeLongTasks.delete(key);
953
+ });
954
+ return true;
955
+ }
894
956
  export async function runWorkflow({ bot, chatId, link, input, activity = null }) {
895
957
  const lang = languageFor(link);
896
958
  const state = getState(link.user_id);
@@ -1097,8 +1159,14 @@ async function handleRoutedIntent({ bot, chatId, link, text, activity }) {
1097
1159
  const intent = await resolveTelegramAiIntent({ bot, chatId, link, text, activity });
1098
1160
  const editMessageId = activity?.messageId;
1099
1161
  if (intent.action === 'agent_prompt') {
1100
- await runAgent({ bot, chatId, link, prompt: intent.prompt || text, activity });
1101
- return true;
1162
+ return launchLongTelegramTask({
1163
+ bot,
1164
+ chatId,
1165
+ link,
1166
+ kind: 'agent',
1167
+ activity,
1168
+ task: () => runAgent({ bot, chatId, link, prompt: intent.prompt || text, activity }),
1169
+ });
1102
1170
  }
1103
1171
  if (intent.action === 'show_menu') {
1104
1172
  await showMainMenu({ bot, chatId, link, editMessageId });
@@ -1175,8 +1243,14 @@ async function handleRoutedIntent({ bot, chatId, link, text, activity }) {
1175
1243
  return true;
1176
1244
  }
1177
1245
  if (intent.action === 'run_workflow') {
1178
- await runWorkflow({ bot, chatId, link, input: intent.workflowInput || text, activity });
1179
- return true;
1246
+ return launchLongTelegramTask({
1247
+ bot,
1248
+ chatId,
1249
+ link,
1250
+ kind: 'workflow',
1251
+ activity,
1252
+ task: () => runWorkflow({ bot, chatId, link, input: intent.workflowInput || text, activity }),
1253
+ });
1180
1254
  }
1181
1255
  if (intent.action === 'show_sessions') {
1182
1256
  await showSessions({ bot, chatId, link, editMessageId });
@@ -1186,8 +1260,14 @@ async function handleRoutedIntent({ bot, chatId, link, text, activity }) {
1186
1260
  await startNewChat({ bot, chatId, link, editMessageId });
1187
1261
  return true;
1188
1262
  }
1189
- await runAgent({ bot, chatId, link, prompt: text, activity });
1190
- return true;
1263
+ return launchLongTelegramTask({
1264
+ bot,
1265
+ chatId,
1266
+ link,
1267
+ kind: 'agent',
1268
+ activity,
1269
+ task: () => runAgent({ bot, chatId, link, prompt: text, activity }),
1270
+ });
1191
1271
  }
1192
1272
  async function fetchRun(userId, runId) {
1193
1273
  return localApi(userId, `/api/orchestration/workflows/runs/${runId}`);
@@ -1393,12 +1473,22 @@ async function handleAwaitingInput({ bot, chatId, link, text }) {
1393
1473
  return false;
1394
1474
  updateTelegramControlState(link.user_id, { awaiting: null });
1395
1475
  if (awaiting.type === 'agent_prompt') {
1396
- await runAgent({ bot, chatId, link, prompt: text });
1397
- return true;
1476
+ return launchLongTelegramTask({
1477
+ bot,
1478
+ chatId,
1479
+ link,
1480
+ kind: 'agent',
1481
+ task: () => runAgent({ bot, chatId, link, prompt: text }),
1482
+ });
1398
1483
  }
1399
1484
  if (awaiting.type === 'workflow_prompt') {
1400
- await runWorkflow({ bot, chatId, link, input: text });
1401
- return true;
1485
+ return launchLongTelegramTask({
1486
+ bot,
1487
+ chatId,
1488
+ link,
1489
+ kind: 'workflow',
1490
+ task: () => runWorkflow({ bot, chatId, link, input: text }),
1491
+ });
1402
1492
  }
1403
1493
  return false;
1404
1494
  }
@@ -1494,8 +1584,13 @@ async function handleCommand({ bot, chatId, link, text }) {
1494
1584
  await send(bot, chatId, t(lang, 'control.sendAgentPrompt'));
1495
1585
  return true;
1496
1586
  }
1497
- await runAgent({ bot, chatId, link, prompt: argText });
1498
- return true;
1587
+ return launchLongTelegramTask({
1588
+ bot,
1589
+ chatId,
1590
+ link,
1591
+ kind: 'agent',
1592
+ task: () => runAgent({ bot, chatId, link, prompt: argText }),
1593
+ });
1499
1594
  }
1500
1595
  if (command === '/workflow' || command === '/orchestrate') {
1501
1596
  if (!argText) {
@@ -1503,8 +1598,13 @@ async function handleCommand({ bot, chatId, link, text }) {
1503
1598
  await send(bot, chatId, t(lang, 'control.sendWorkflowPrompt'));
1504
1599
  return true;
1505
1600
  }
1506
- await runWorkflow({ bot, chatId, link, input: argText });
1507
- return true;
1601
+ return launchLongTelegramTask({
1602
+ bot,
1603
+ chatId,
1604
+ link,
1605
+ kind: 'workflow',
1606
+ task: () => runWorkflow({ bot, chatId, link, input: argText }),
1607
+ });
1508
1608
  }
1509
1609
  if (command === '/cancel') {
1510
1610
  if (!argText) {
@@ -1563,6 +1663,10 @@ export async function handleTelegramControlMessage(args) {
1563
1663
  await send(args.bot, chatId, t(languageFor(args.link), 'error.generic')).catch(() => { });
1564
1664
  return true;
1565
1665
  }
1666
+ }).catch(async (error) => {
1667
+ console.error('[telegram-control] message job failed:', error);
1668
+ await send(args.bot, chatId, t(languageFor(args.link), 'error.generic')).catch(() => { });
1669
+ return true;
1566
1670
  });
1567
1671
  }
1568
1672
  async function showRunDetail({ bot, chatId, link, runId, editMessageId }) {
@@ -1769,6 +1873,11 @@ export async function handleTelegramControlCallback(args) {
1769
1873
  await args.bot?.answerCallbackQuery(args.query?.id, { text: t(lang, 'error.generic') }).catch(() => { });
1770
1874
  await send(args.bot, chatId, t(lang, 'error.generic')).catch(() => { });
1771
1875
  }
1876
+ }).catch(async (error) => {
1877
+ console.error('[telegram-control] callback job failed:', error);
1878
+ const lang = languageFor(args.link);
1879
+ await args.bot?.answerCallbackQuery(args.query?.id, { text: t(lang, 'error.generic') }).catch(() => { });
1880
+ await send(args.bot, chatId, t(lang, 'error.generic')).catch(() => { });
1772
1881
  });
1773
1882
  }
1774
1883
  //# sourceMappingURL=control-center.js.map