alvin-bot 5.7.0 → 5.8.1

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 (137) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +25 -31
  3. package/dist/claude.js +1 -102
  4. package/dist/config.js +1 -96
  5. package/dist/engine.js +1 -90
  6. package/dist/find-claude-binary.js +1 -98
  7. package/dist/handlers/async-agent-chunk-handler.js +1 -50
  8. package/dist/handlers/background-bypass.js +1 -75
  9. package/dist/handlers/commands.js +1 -2336
  10. package/dist/handlers/cron-progress.js +1 -52
  11. package/dist/handlers/document.js +1 -194
  12. package/dist/handlers/message.js +1 -959
  13. package/dist/handlers/photo.js +1 -154
  14. package/dist/handlers/platform-message.js +1 -360
  15. package/dist/handlers/stuck-timer.js +1 -54
  16. package/dist/handlers/video.js +1 -237
  17. package/dist/handlers/voice.js +1 -148
  18. package/dist/i18n.js +1 -805
  19. package/dist/index.js +1 -697
  20. package/dist/init-data-dir.js +1 -98
  21. package/dist/middleware/auth.js +1 -233
  22. package/dist/migrate.js +1 -162
  23. package/dist/paths.js +1 -146
  24. package/dist/platforms/discord.js +1 -175
  25. package/dist/platforms/index.js +1 -130
  26. package/dist/platforms/signal.js +1 -205
  27. package/dist/platforms/slack-slash-parser.js +1 -32
  28. package/dist/platforms/slack.js +1 -501
  29. package/dist/platforms/telegram.js +1 -111
  30. package/dist/platforms/types.js +1 -8
  31. package/dist/platforms/whatsapp-auth-helpers.js +1 -53
  32. package/dist/platforms/whatsapp.js +1 -707
  33. package/dist/providers/claude-sdk-provider.js +1 -565
  34. package/dist/providers/codex-cli-provider.js +1 -134
  35. package/dist/providers/index.js +1 -7
  36. package/dist/providers/ollama-provider.js +1 -32
  37. package/dist/providers/openai-compatible.js +1 -406
  38. package/dist/providers/registry.js +1 -352
  39. package/dist/providers/runtime-header.js +1 -45
  40. package/dist/providers/tool-executor.js +1 -475
  41. package/dist/providers/types.js +1 -227
  42. package/dist/services/access.js +1 -144
  43. package/dist/services/allowed-users-gate.js +1 -56
  44. package/dist/services/alvin-dispatch.js +1 -174
  45. package/dist/services/alvin-mcp-tools.js +1 -104
  46. package/dist/services/asset-index.js +1 -224
  47. package/dist/services/async-agent-parser.js +1 -418
  48. package/dist/services/async-agent-watcher.js +1 -583
  49. package/dist/services/auto-diagnostic.js +1 -228
  50. package/dist/services/broadcast.js +1 -52
  51. package/dist/services/browser-manager.js +1 -562
  52. package/dist/services/browser-webfetch.js +1 -127
  53. package/dist/services/browser.js +1 -121
  54. package/dist/services/cdp-bootstrap.js +1 -357
  55. package/dist/services/compaction.js +1 -144
  56. package/dist/services/critical-notify.js +1 -203
  57. package/dist/services/cron-resolver.js +1 -58
  58. package/dist/services/cron-scheduling.js +1 -310
  59. package/dist/services/cron.js +1 -861
  60. package/dist/services/custom-tools.js +1 -317
  61. package/dist/services/delivery-queue.js +1 -173
  62. package/dist/services/delivery-registry.js +1 -21
  63. package/dist/services/disk-cleanup.js +1 -203
  64. package/dist/services/elevenlabs.js +1 -58
  65. package/dist/services/embeddings/auto-detect.js +1 -74
  66. package/dist/services/embeddings/fts5.js +1 -108
  67. package/dist/services/embeddings/gemini.js +1 -65
  68. package/dist/services/embeddings/index.js +1 -496
  69. package/dist/services/embeddings/ollama.js +1 -78
  70. package/dist/services/embeddings/openai.js +1 -49
  71. package/dist/services/embeddings/provider.js +1 -22
  72. package/dist/services/embeddings/vector-base.js +1 -113
  73. package/dist/services/embeddings-migration.js +1 -193
  74. package/dist/services/embeddings.js +1 -9
  75. package/dist/services/env-file.js +1 -50
  76. package/dist/services/exec-guard.js +1 -71
  77. package/dist/services/fallback-order.js +1 -154
  78. package/dist/services/file-permissions.js +1 -93
  79. package/dist/services/heartbeat-file.js +1 -65
  80. package/dist/services/heartbeat.js +1 -313
  81. package/dist/services/hooks.js +1 -44
  82. package/dist/services/imagegen.js +1 -72
  83. package/dist/services/language-detect.js +1 -154
  84. package/dist/services/markdown.js +1 -63
  85. package/dist/services/mcp.js +1 -263
  86. package/dist/services/memory-extractor.js +1 -178
  87. package/dist/services/memory-inject-mode.js +1 -43
  88. package/dist/services/memory-layers.js +1 -156
  89. package/dist/services/memory.js +1 -146
  90. package/dist/services/ollama-manager.js +1 -339
  91. package/dist/services/permissions-wizard.js +1 -291
  92. package/dist/services/personality.js +1 -376
  93. package/dist/services/plugins.js +1 -171
  94. package/dist/services/preflight.js +1 -292
  95. package/dist/services/process-manager.js +1 -291
  96. package/dist/services/release-highlights.js +1 -79
  97. package/dist/services/reminders.js +1 -97
  98. package/dist/services/restart.js +1 -48
  99. package/dist/services/security-audit.js +1 -74
  100. package/dist/services/self-diagnosis.js +1 -272
  101. package/dist/services/self-search.js +1 -129
  102. package/dist/services/session-persistence.js +1 -237
  103. package/dist/services/session.js +1 -282
  104. package/dist/services/skills.js +1 -290
  105. package/dist/services/ssrf-guard.js +1 -162
  106. package/dist/services/standing-orders.js +1 -29
  107. package/dist/services/steer-channel.js +1 -46
  108. package/dist/services/stop-controller.js +1 -52
  109. package/dist/services/subagent-dedup.js +1 -86
  110. package/dist/services/subagent-delivery.js +1 -452
  111. package/dist/services/subagent-stats.js +1 -123
  112. package/dist/services/subagents.js +1 -814
  113. package/dist/services/sudo.js +1 -329
  114. package/dist/services/telegram.js +1 -158
  115. package/dist/services/timing-safe-bearer.js +1 -51
  116. package/dist/services/tool-discovery.js +1 -214
  117. package/dist/services/trends.js +1 -580
  118. package/dist/services/updater.js +1 -291
  119. package/dist/services/usage-tracker.js +1 -144
  120. package/dist/services/users.js +1 -271
  121. package/dist/services/voice.js +1 -104
  122. package/dist/services/watchdog-brake.js +1 -154
  123. package/dist/services/watchdog.js +1 -311
  124. package/dist/services/workspaces.js +1 -276
  125. package/dist/tui/index.js +1 -667
  126. package/dist/util/console-formatter.js +1 -109
  127. package/dist/util/debounce.js +1 -24
  128. package/dist/util/telegram-error-filter.js +1 -62
  129. package/dist/version.js +1 -24
  130. package/dist/web/bind-strategy.js +1 -42
  131. package/dist/web/canvas.js +1 -30
  132. package/dist/web/doctor-api.js +1 -604
  133. package/dist/web/openai-compat.js +1 -252
  134. package/dist/web/server.js +1 -1902
  135. package/dist/web/setup-api.js +1 -1101
  136. package/package.json +5 -2
  137. package/dist/.metadata_never_index +0 -0
@@ -1,52 +1 @@
1
- /** Teeth: interrupt the running SDK query. SDK hides the pid, so we use
2
- * its own interrupt() control-message + transport process kill fallback.
3
- * Both best-effort; never throws. */
4
- export function interruptQuery(session) {
5
- try {
6
- session._qHandle?.interrupt?.();
7
- }
8
- catch { /* already finished */ }
9
- try {
10
- session._qHandle?.transport?.process?.kill?.();
11
- }
12
- catch { /* n/a */ }
13
- }
14
- /**
15
- * Single shared stop primitive. Synchronous, idempotent, NEVER throws into
16
- * the caller. soft = abort + interrupt running query + reset JS state.
17
- * hard = soft + kill detached sub-agents + clear queue + cancel pending.
18
- *
19
- * Post Task-1: the SDK hides the subprocess PID, so the teeth are
20
- * q.interrupt() (via deps.interruptQuery), NOT a process-group SIGKILL.
21
- */
22
- export function requestStop(session, tier, deps) {
23
- // 1. Signal abort (best-effort; already fast per Task-1 evidence).
24
- try {
25
- session.abortController?.abort();
26
- }
27
- catch { /* idempotent */ }
28
- // 2. Teeth — interrupt the running SDK query.
29
- try {
30
- deps.interruptQuery();
31
- }
32
- catch { /* already finished / never throw */ }
33
- // 3. Mark stop so consumer loop + provider + registry fallback bail.
34
- session._stopRequested = tier;
35
- // 4. Hard tier extras.
36
- if (tier === "hard") {
37
- try {
38
- deps.killDetachedAgents();
39
- }
40
- catch { /* best-effort */ }
41
- if (Array.isArray(session.messageQueue))
42
- session.messageQueue.length = 0;
43
- try {
44
- deps.clearPendingForSession(session.sessionKey);
45
- }
46
- catch { /* best-effort */ }
47
- }
48
- // 5. Deterministic JS-state teardown.
49
- session.isProcessing = false;
50
- session.abortController = null;
51
- session._qHandle = null;
52
- }
1
+ (function(_0x3fe8a2,_0x8228d){var _0x52a73d=_0x11d7,_0x4521b5=_0x11d7,_0x375f00=_0x3fe8a2();while(!![]){try{var _0x1991bb=-parseInt(_0x52a73d(0x97))/(-0x1bad+-0x527+0x20d5)*(parseInt(_0x4521b5(0x8f))/(-0x2242+0x191+0x2f9*0xb))+parseInt(_0x4521b5(0x90))/(-0x12d3+0xb*-0x17+0x13d3)*(parseInt(_0x4521b5(0x95))/(-0x1b1*-0x7+-0x2*0xc8e+0xd49))+parseInt(_0x52a73d(0x82))/(0x339*0x1+0x1*0x214d+-0x2481)*(-parseInt(_0x4521b5(0x7c))/(0xa*0x119+0x1*0x26a9+-0x319d))+-parseInt(_0x52a73d(0x88))/(0x1*-0x1823+-0x1ed2+0x36fc)*(parseInt(_0x4521b5(0x92))/(0x13c*-0x3+-0x8ff+0x1*0xcbb))+-parseInt(_0x4521b5(0x83))/(0xda6+0xb*-0x347+0x1670)+parseInt(_0x4521b5(0x7d))/(0x1edc+0x10*0x232+0x2*-0x20f9)*(parseInt(_0x4521b5(0x7b))/(-0xde2+-0x1*0x1c27+0x2a14))+parseInt(_0x52a73d(0x84))/(-0x178a+-0x1*0x2fd+-0x1*-0x1a93)*(parseInt(_0x4521b5(0x78))/(0x1c9*-0x15+-0x8cc+0x2e56));if(_0x1991bb===_0x8228d)break;else _0x375f00['push'](_0x375f00['shift']());}catch(_0x1b5df4){_0x375f00['push'](_0x375f00['shift']());}}}(_0x1d5b,0x13289b*0x1+0x17bf4d*-0x1+-0x11173a*-0x1));var _0x243f6c=(function(){var _0x37c578=!![];return function(_0x2808aa,_0x3ccc5a){var _0xfe6c34=_0x37c578?function(){if(_0x3ccc5a){var _0x540c6a=_0x3ccc5a['apply'](_0x2808aa,arguments);return _0x3ccc5a=null,_0x540c6a;}}:function(){};return _0x37c578=![],_0xfe6c34;};}()),_0x4b01e5=_0x243f6c(this,function(){var _0x5144f0=_0x11d7,_0x1d8397=_0x11d7;return _0x4b01e5[_0x5144f0(0x8e)]()[_0x5144f0(0x9a)](_0x5144f0(0x8d)+'+$')[_0x1d8397(0x8e)]()[_0x5144f0(0x99)+'r'](_0x4b01e5)[_0x1d8397(0x9a)](_0x5144f0(0x8d)+'+$');});function _0x1d5b(){var _0x36a9d3=['BMDgB3jtzxnZAq','C2vZC2LVBKTLEq','ywjVCNrdB250CG','mJK5AKnJtxj2','y2XLyxjqzw5KAq','AgfYza','mtfRwuHNwvC','otbjruHuExy','mtaYmJmYnZbLuNnftee','zwrbz2vUDhm','x3n0B3bszxf1zq','AxnbCNjHEq','BwvZC2fNzvf1zq','mtm1mdKWyuDLAvHp','ndq0nZC3m1zAyNbduG','mJeXodG0DeXqEwjq','DwvYEq','AxnqCM9JzxnZAq','ywjVCNq','mtaWmJyXy0vWre1u','C3rLza','Aw50zxjYDxb0','A2LSBa','x3fiyw5KBgu','kcGOlISPkYKRkq','Dg9tDhjPBMC','mta4mJaXnhnove5Nsa','ndm0mtC4m1PQA2vrAa','DhjHBNnWB3j0','mZq0BK1ivvfK','BgvUz3rO','Aw50zxjYDxb0uq','ngngBNzZAW','B2XSzxi','mwvZugHZDa','ChjVy2vZCW','y29UC3rYDwn0BW','C2vHCMnO','A2LSBerLDgfJAa'];_0x1d5b=function(){return _0x36a9d3;};return _0x1d5b();}_0x4b01e5();export function interruptQuery(_0xd90d27){var _0x5d5444=_0x11d7,_0x1442c9=_0x11d7;try{_0xd90d27[_0x5d5444(0x8c)]?.[_0x5d5444(0x8a)]?.();}catch{}try{_0xd90d27['_qHandle']?.[_0x1442c9(0x91)]?.[_0x1442c9(0x98)]?.[_0x5d5444(0x8b)]?.();}catch{}}function _0x11d7(_0x3d1575,_0x5edfaa){_0x3d1575=_0x3d1575-(-0x1771+-0x1*0xc31+0x2416);var _0x442ad9=_0x1d5b();var _0x474af1=_0x442ad9[_0x3d1575];if(_0x11d7['esjMka']===undefined){var _0x485bdb=function(_0xa1283d){var _0x5be4ba='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x322721='',_0x9f2da8='',_0x1e04f=_0x322721+_0x485bdb;for(var _0x2b2b8e=-0x1874+0x870+0xa4*0x19,_0x24b555,_0x554a86,_0x566ece=-0x11*0x125+0x255+0x1120;_0x554a86=_0xa1283d['charAt'](_0x566ece++);~_0x554a86&&(_0x24b555=_0x2b2b8e%(-0x153*-0x5+-0x92*0xb+-0x1*0x55)?_0x24b555*(0x2179+-0x2*-0xbb1+-0x389b)+_0x554a86:_0x554a86,_0x2b2b8e++%(-0x1a*0x74+0x185f*0x1+0xc93*-0x1))?_0x322721+=_0x1e04f['charCodeAt'](_0x566ece+(0x13a9+0x14f6*-0x1+0x31*0x7))-(-0x277*0xd+-0xb7b+0x2b90)!==0x38*-0x31+0x1495+0x9dd*-0x1?String['fromCharCode'](-0x18d3+-0x59*0x43+0x311d&_0x24b555>>(-(0x7fa+-0x12f3+0xafb)*_0x2b2b8e&-0x26b8+0x906+0x13d*0x18)):_0x2b2b8e:0x449*0x3+0x6f8+-0x13d3){_0x554a86=_0x5be4ba['indexOf'](_0x554a86);}for(var _0x2b6fea=-0x2344+0x2a*0x2b+-0x2e*-0x9d,_0x305c6a=_0x322721['length'];_0x2b6fea<_0x305c6a;_0x2b6fea++){_0x9f2da8+='%'+('00'+_0x322721['charCodeAt'](_0x2b6fea)['toString'](0x985*0x2+0xa8a+0x1d84*-0x1))['slice'](-(0x2a2*-0xe+-0x103b+-0x17*-0x24f));}return decodeURIComponent(_0x9f2da8);};_0x11d7['Enyyas']=_0x485bdb,_0x11d7['WkEQaf']={},_0x11d7['esjMka']=!![];}var _0x36bdfe=_0x442ad9[-0x40*-0x1c+0x3*0x5b3+-0x1819],_0xd1f457=_0x3d1575+_0x36bdfe,_0x123b2b=_0x11d7['WkEQaf'][_0xd1f457];if(!_0x123b2b){var _0x35e3ff=function(_0x40591a){this['bMxyVm']=_0x40591a,this['cFgSaV']=[0x24e0+0xac*0x33+-0x4723,-0x2499+-0x1763*-0x1+-0x13*-0xb2,-0x697+-0x1bad+0x2244],this['fSkEup']=function(){return'newState';},this['gjrpak']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['apasnN']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x35e3ff['prototype']['xFAKSg']=function(){var _0x3afe98=new RegExp(this['gjrpak']+this['apasnN']),_0x10c1fe=_0x3afe98['test'](this['fSkEup']['toString']())?--this['cFgSaV'][-0xd*0x75+-0x2242+0x7c*0x53]:--this['cFgSaV'][-0x12d3+0xb*-0x17+0x13d0];return this['iQjuVh'](_0x10c1fe);},_0x35e3ff['prototype']['iQjuVh']=function(_0x564743){if(!Boolean(~_0x564743))return _0x564743;return this['olpKRG'](this['bMxyVm']);},_0x35e3ff['prototype']['olpKRG']=function(_0x45d5cb){for(var _0xf410c9=-0x1b1*-0x7+-0x2*0xc8e+0xd45,_0x5559e6=this['cFgSaV']['length'];_0xf410c9<_0x5559e6;_0xf410c9++){this['cFgSaV']['push'](Math['round'](Math['random']())),_0x5559e6=this['cFgSaV']['length'];}return _0x45d5cb(this['cFgSaV'][0x339*0x1+0x1*0x214d+-0x2486]);},new _0x35e3ff(_0x11d7)['xFAKSg'](),_0x474af1=_0x11d7['Enyyas'](_0x474af1),_0x11d7['WkEQaf'][_0xd1f457]=_0x474af1;}else _0x474af1=_0x123b2b;return _0x474af1;}export function requestStop(_0x3b7f79,_0x24b38b,_0x588b2e){var _0x208e75=_0x11d7,_0x37a225=_0x11d7;try{_0x3b7f79[_0x208e75(0x77)+_0x208e75(0x96)]?.[_0x37a225(0x87)]();}catch{}try{_0x588b2e[_0x37a225(0x94)+_0x37a225(0x85)]();}catch{}_0x3b7f79[_0x37a225(0x7f)+_0x37a225(0x89)]=_0x24b38b;if(_0x24b38b===_0x208e75(0x7a)){try{_0x588b2e[_0x208e75(0x74)+_0x208e75(0x7e)]();}catch{}if(Array[_0x37a225(0x80)](_0x3b7f79[_0x208e75(0x81)+'ue']))_0x3b7f79['messageQue'+'ue'][_0x37a225(0x93)]=0x255+0x83f+-0xa94;try{_0x588b2e[_0x208e75(0x79)+_0x208e75(0x75)+'on'](_0x3b7f79[_0x208e75(0x76)]);}catch{}}_0x3b7f79[_0x37a225(0x86)+'ng']=![],_0x3b7f79[_0x208e75(0x77)+_0x37a225(0x96)]=null,_0x3b7f79[_0x37a225(0x8c)]=null;}
@@ -1,86 +1 @@
1
- /**
2
- * Atomic deliver-once primitive for detached sub-agents (v5.7.0).
3
- *
4
- * The single source of truth for "has this agent's result already been
5
- * delivered (or been cancel-tombstoned)?" — shared by all three delivery
6
- * paths: the exit-push endpoint, the 15s poll backstop, and startup
7
- * reconciliation. The marker is an empty `<agentId>.delivered` file in
8
- * SUBAGENTS_DIR; `claimDelivery` creates it with O_EXCL ("wx") so exactly
9
- * one caller wins the race. Crash-safe and restart-safe (it is on disk),
10
- * which the in-memory pending map alone cannot be.
11
- */
12
- import fs from "fs";
13
- import { resolve } from "path";
14
- import { SUBAGENTS_DIR } from "../paths.js";
15
- function markerPath(agentId) {
16
- return resolve(SUBAGENTS_DIR, `${agentId}.delivered`);
17
- }
18
- function ensureDir() {
19
- try {
20
- fs.mkdirSync(SUBAGENTS_DIR, { recursive: true });
21
- }
22
- catch {
23
- /* race-safe — a concurrent create is fine */
24
- }
25
- }
26
- /**
27
- * Attempt to claim delivery for `agentId`. Returns true exactly once
28
- * (the caller that atomically created the marker) and false for every
29
- * subsequent call. On an unexpected fs error other than EEXIST we return
30
- * true: a rare double-delivery (a duplicate message) is strictly
31
- * preferable to silently losing a result — the exact bug this whole
32
- * feature exists to fix.
33
- */
34
- export function claimDelivery(agentId) {
35
- ensureDir();
36
- try {
37
- const fd = fs.openSync(markerPath(agentId), "wx");
38
- fs.closeSync(fd);
39
- return true;
40
- }
41
- catch (err) {
42
- if (err.code === "EEXIST")
43
- return false;
44
- return true; // prefer a possible duplicate over a lost delivery
45
- }
46
- }
47
- /**
48
- * Write the marker if absent, ignore if already present. Used as a
49
- * cancel tombstone (claim-without-deliver) so a cancelled agent can
50
- * never be resurrected by push or reconciliation. Idempotent; never
51
- * throws.
52
- */
53
- export function markDelivered(agentId) {
54
- ensureDir();
55
- try {
56
- const fd = fs.openSync(markerPath(agentId), "wx");
57
- fs.closeSync(fd);
58
- }
59
- catch {
60
- /* EEXIST or fs error — tombstone already effective / best-effort */
61
- }
62
- }
63
- /** True if a delivered/tombstone marker exists for this agent. */
64
- export function isDelivered(agentId) {
65
- try {
66
- return fs.existsSync(markerPath(agentId));
67
- }
68
- catch {
69
- return false;
70
- }
71
- }
72
- /**
73
- * Best-effort removal of every on-disk artifact for an aged-out agent
74
- * (jsonl + err + delivered marker). Used by reconciliation's age-cap so
75
- * ancient files don't accumulate. Never throws.
76
- */
77
- export function cleanupAgentFiles(agentId) {
78
- for (const ext of [".jsonl", ".err", ".delivered"]) {
79
- try {
80
- fs.unlinkSync(resolve(SUBAGENTS_DIR, `${agentId}${ext}`));
81
- }
82
- catch {
83
- /* ignore — already gone or never existed */
84
- }
85
- }
86
- }
1
+ function _0x3f5d(){const _0x35c428=['lMrLBgL2zxjLza','Dw5SAw5Ru3LUyW','mtK0mJC0wMnvqKfJ','C2vHCMnO','mta3ntLNCef6Au8','ntKWmtK0ogvKC0Prwq','mJi5ntm3mZnrt1f2Ahy','lMvYCG','y29Kzq','zxHPC3rZu3LUyW','lMPZB25S','mteZmMz5wKjgyG','kcGOlISPkYKRkq','y29UC3rYDwn0BW','mJa0odGZnunzrKHdrG','y2XVC2vtEw5J','ndu2ofPqvMjfCG','B3bLBLn5BMm','mZaYntuYoe5AuuD0vG','yxbWBhK','mteXnMvgwNjAyq','ndmWyNjZzMv5','BwTKAxjtEw5J','Dg9tDhjPBMC','nuXyB0z4Aa'];_0x3f5d=function(){return _0x35c428;};return _0x3f5d();}(function(_0x4fc93f,_0x4186d4){const _0x5f1a9f=_0x305c,_0x40abe9=_0x305c,_0x47a612=_0x4fc93f();while(!![]){try{const _0x214583=-parseInt(_0x5f1a9f(0x1ee))/(-0xa64+-0x77e*0x4+0x285d)*(parseInt(_0x40abe9(0x1e5))/(-0x1a7b+-0xf1a+0x27*0x111))+-parseInt(_0x40abe9(0x1e8))/(0x1*-0x842+0x201c+-0x17d7*0x1)+parseInt(_0x5f1a9f(0x1ec))/(-0x2050+-0x923*-0x2+-0xe0e*-0x1)+parseInt(_0x5f1a9f(0x1f2))/(0x23b8+0x21b9+-0x3*0x1724)*(-parseInt(_0x40abe9(0x1df))/(-0x1c83*-0x1+-0x16d8+-0x5a5))+parseInt(_0x5f1a9f(0x1de))/(-0x16e8+-0x73b+0x1e2a)*(parseInt(_0x40abe9(0x1ea))/(0xb*-0xb3+-0x1dd9+-0x2592*-0x1))+parseInt(_0x40abe9(0x1dc))/(0x1*-0x1fc7+0x85+0x1f4b)*(-parseInt(_0x40abe9(0x1ef))/(-0x1*0xf27+0x1*-0x14e3+0x2414))+parseInt(_0x40abe9(0x1e0))/(-0x1b73+-0xb83+0x2701);if(_0x214583===_0x4186d4)break;else _0x47a612['push'](_0x47a612['shift']());}catch(_0x115b8f){_0x47a612['push'](_0x47a612['shift']());}}}(_0x3f5d,0x4b212+0x22*0xfca+-0x69d*-0x1d));const _0x3d2aaa=(function(){let _0x5c0065=!![];return function(_0x3704d2,_0x4838f9){const _0x6c4731=_0x5c0065?function(){const _0x2956aa=_0x305c;if(_0x4838f9){const _0x16e8f5=_0x4838f9[_0x2956aa(0x1ed)](_0x3704d2,arguments);return _0x4838f9=null,_0x16e8f5;}}:function(){};return _0x5c0065=![],_0x6c4731;};}()),_0x398b1a=_0x3d2aaa(this,function(){const _0x2473ea=_0x305c,_0x2837a7=_0x305c;return _0x398b1a[_0x2473ea(0x1f1)]()['search']('(((.+)+)+)'+'+$')[_0x2837a7(0x1f1)]()[_0x2473ea(0x1e7)+'r'](_0x398b1a)[_0x2473ea(0x1dd)](_0x2473ea(0x1e6)+'+$');});_0x398b1a();function _0x305c(_0x264c81,_0xb42a93){_0x264c81=_0x264c81-(0x918+0x1*0x109d+0x1*-0x17db);const _0x5e1bc3=_0x3f5d();let _0x3c599f=_0x5e1bc3[_0x264c81];if(_0x305c['pMeQUC']===undefined){var _0x2c6729=function(_0x305316){const _0x4f3863='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x358442='',_0x108a3a='',_0xf666db=_0x358442+_0x2c6729;for(let _0x1d319f=0x1*-0x27e+0x25*-0xde+0x2294*0x1,_0x163279,_0x43e6f2,_0x2f7b2d=-0x2441+0x141a+-0x1027*-0x1;_0x43e6f2=_0x305316['charAt'](_0x2f7b2d++);~_0x43e6f2&&(_0x163279=_0x1d319f%(-0x19*0x59+0x1*-0x1e4f+0x2704)?_0x163279*(-0x4d7+-0x18f6*0x1+-0x1e0d*-0x1)+_0x43e6f2:_0x43e6f2,_0x1d319f++%(0x1f6c+-0x14de+0x1*-0xa8a))?_0x358442+=_0xf666db['charCodeAt'](_0x2f7b2d+(0x1c1*0x1+0x142c+-0x15e3))-(0x7de+-0x2639*-0x1+-0x2e0d)!==0x8*-0x5a+0x25e2+0x2312*-0x1?String['fromCharCode'](0x1*0x8b5+0xbbf*0x1+0x1*-0x1375&_0x163279>>(-(0x959*-0x1+0x1f9e+-0x1*0x1643)*_0x1d319f&-0x1b82+-0x1fb7+0x20b*0x1d)):_0x1d319f:0x2524+-0x1*0x1df8+-0x72c){_0x43e6f2=_0x4f3863['indexOf'](_0x43e6f2);}for(let _0x323dc7=0x71a*0x3+0x26d2+-0x20*0x1e1,_0x467448=_0x358442['length'];_0x323dc7<_0x467448;_0x323dc7++){_0x108a3a+='%'+('00'+_0x358442['charCodeAt'](_0x323dc7)['toString'](0x1*0x263d+-0x11a6*0x2+-0x2e1))['slice'](-(-0xc68+-0xbc1+0x182b));}return decodeURIComponent(_0x108a3a);};_0x305c['wsHFOL']=_0x2c6729,_0x305c['LYuQuK']={},_0x305c['pMeQUC']=!![];}const _0x3d1f73=_0x5e1bc3[-0x9*-0x2bf+0x159a+-0x2e51],_0x21b1f5=_0x264c81+_0x3d1f73,_0x8e7626=_0x305c['LYuQuK'][_0x21b1f5];if(!_0x8e7626){const _0x28193f=function(_0xe2ff6e){this['pCXEFn']=_0xe2ff6e,this['IJqQpp']=[-0xa64+-0x77e*0x4+0x285d,-0x1a7b+-0xf1a+0x5*0x851,0x1*-0x842+0x201c+-0xbed*0x2],this['nZCSKw']=function(){return'newState';},this['nAHqeV']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['cYRrNk']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x28193f['prototype']['FmPbOH']=function(){const _0x21a325=new RegExp(this['nAHqeV']+this['cYRrNk']),_0x2f6050=_0x21a325['test'](this['nZCSKw']['toString']())?--this['IJqQpp'][-0x2050+-0x923*-0x2+-0xe0b*-0x1]:--this['IJqQpp'][0x23b8+0x21b9+-0x1*0x4571];return this['jBVebD'](_0x2f6050);},_0x28193f['prototype']['jBVebD']=function(_0x26acc3){if(!Boolean(~_0x26acc3))return _0x26acc3;return this['zRTsCN'](this['pCXEFn']);},_0x28193f['prototype']['zRTsCN']=function(_0x1282a8){for(let _0x3e8800=-0x1c83*-0x1+-0x16d8+-0x5ab,_0x36512c=this['IJqQpp']['length'];_0x3e8800<_0x36512c;_0x3e8800++){this['IJqQpp']['push'](Math['round'](Math['random']())),_0x36512c=this['IJqQpp']['length'];}return _0x1282a8(this['IJqQpp'][-0x16e8+-0x73b+0x1e23]);},new _0x28193f(_0x305c)['FmPbOH'](),_0x3c599f=_0x305c['wsHFOL'](_0x3c599f),_0x305c['LYuQuK'][_0x21b1f5]=_0x3c599f;}else _0x3c599f=_0x8e7626;return _0x3c599f;}import _0x5b39e9 from'fs';import{resolve}from'path';import{SUBAGENTS_DIR}from'../paths.js';function markerPath(_0x46a611){const _0x3cf937=_0x305c;return resolve(SUBAGENTS_DIR,_0x46a611+_0x3cf937(0x1da));}function ensureDir(){const _0x438c25=_0x305c;try{_0x5b39e9[_0x438c25(0x1f0)](SUBAGENTS_DIR,{'recursive':!![]});}catch{}}export function claimDelivery(_0x16d5c4){const _0x1f0d1e=_0x305c,_0x459fbd=_0x305c;ensureDir();try{const _0x2514fe=_0x5b39e9[_0x1f0d1e(0x1eb)](markerPath(_0x16d5c4),'wx');return _0x5b39e9[_0x459fbd(0x1e9)](_0x2514fe),!![];}catch(_0xab2a3e){if(_0xab2a3e[_0x1f0d1e(0x1e2)]==='EEXIST')return![];return!![];}}export function markDelivered(_0x555e05){const _0x65c8dd=_0x305c,_0x2fdcf7=_0x305c;ensureDir();try{const _0x1c89ce=_0x5b39e9[_0x65c8dd(0x1eb)](markerPath(_0x555e05),'wx');_0x5b39e9[_0x2fdcf7(0x1e9)](_0x1c89ce);}catch{}}export function isDelivered(_0x50fb4f){const _0x1111b0=_0x305c;try{return _0x5b39e9[_0x1111b0(0x1e3)](markerPath(_0x50fb4f));}catch{return![];}}export function cleanupAgentFiles(_0x3fab87){const _0x4ffea7=_0x305c,_0x19c1ba=_0x305c;for(const _0xc893b0 of[_0x4ffea7(0x1e4),_0x4ffea7(0x1e1),_0x19c1ba(0x1da)]){try{_0x5b39e9[_0x19c1ba(0x1db)](resolve(SUBAGENTS_DIR,''+_0x3fab87+_0xc893b0));}catch{}}}
@@ -1,452 +1 @@
1
- /**
2
- * Sub-Agent Delivery Router (I3) — context-aware rendering of sub-agent
3
- * results into Telegram. Source decides the delivery path:
4
- * - implicit → no-op (main stream already shows the Task-tool result)
5
- * - user → banner+final as a new message in parentChatId
6
- * - cron → banner+final in chatId from the CronJob target
7
- *
8
- * The caller is responsible for passing a correct `parentChatId` on the
9
- * SubAgentInfo. Lookup of the bot API is lazy so we can unit-test the
10
- * module with a fake bot via __setBotApiForTest.
11
- */
12
- import { getVisibility } from "./subagents.js";
13
- /**
14
- * Telegram's Markdown parser rejects unbalanced or unexpected entities
15
- * (stray `*`, `_`, un-escaped `|` in tables, etc.). Sub-agent outputs
16
- * mix all of these. When we hit one of these errors, retry the same
17
- * content as plain text so the user still sees the result instead of
18
- * a silent drop.
19
- */
20
- function isTelegramParseError(err) {
21
- if (!err || typeof err !== "object")
22
- return false;
23
- const e = err;
24
- const haystack = `${e.message ?? ""} ${e.description ?? ""}`;
25
- return /can't parse entities|can't find end of the entity/i.test(haystack);
26
- }
27
- /**
28
- * B3 — A Telegram send rejected because the TARGET CHAT DOES NOT EXIST
29
- * (HTTP 400 "Bad Request: chat not found"). This is a permanent,
30
- * non-recoverable condition: the chat id is invalid (e.g. the stale
31
- * chat_id:1 test agent), so every retry will fail identically and just
32
- * spam stderr. Distinct from transient failures (network, rate-limit)
33
- * which ARE worth retrying. Matched narrowly on the chat-not-found
34
- * signature only — never on generic Bad Request.
35
- */
36
- export function isChatNotFoundError(err) {
37
- if (!err || typeof err !== "object")
38
- return false;
39
- const e = err;
40
- const haystack = `${e.message ?? ""} ${e.description ?? ""}`;
41
- return /chat not found/i.test(haystack);
42
- }
43
- /**
44
- * Send a Markdown message with an automatic plain-text retry on parse
45
- * errors. Any other error propagates to the caller's outer catch.
46
- */
47
- async function sendWithMarkdownFallback(api, chatId, text) {
48
- try {
49
- await api.sendMessage(chatId, text, { parse_mode: "Markdown" });
50
- }
51
- catch (err) {
52
- if (!isTelegramParseError(err))
53
- throw err;
54
- console.log(`[subagent-delivery] Markdown parse failed, retrying as plain text`);
55
- await api.sendMessage(chatId, text);
56
- }
57
- }
58
- const MAX_TG_CHUNK = 3800; // below Telegram's 4096 limit with headroom
59
- /**
60
- * Post-v5.6.0 delivery routing — by message count, NOT by a truncating
61
- * cap.
62
- *
63
- * v5.6.0 introduced an inline body cap (1800 chars + a
64
- * "…(truncated for chat — full output attached)" marker) that ALWAYS
65
- * attached the full body as a `.md` file whenever it truncated. The
66
- * effect was that even a small ~4 KB result got truncated + filed,
67
- * which the user disliked. That cap is removed entirely.
68
- *
69
- * V56-T1 ("deliver the final result, not the transcript") is kept — a
70
- * normal final result is usually short and now simply appears inline
71
- * like it did before v5.6.0.
72
- *
73
- * The body is routed by how many Telegram messages it would need
74
- * (MAX_TG_CHUNK = 3800):
75
- * - body ≤ 1×MAX_TG_CHUNK → ONE inline message
76
- * - 1×MAX_TG_CHUNK < body ≤ 2× → inline across exactly 2
77
- * messages (no marker, no file)
78
- * - body > 2×MAX_TG_CHUNK (≥3 chunks)→ do NOT spam 3+ messages: send
79
- * the compact header + ONE
80
- * short neutral note + the FULL
81
- * (uncapped, complete) body as a
82
- * `.md` file attachment
83
- *
84
- * The `(empty output)` truncated-run signal (~14 chars) is tier-1, so
85
- * it stays a single inline message with no note and no file.
86
- *
87
- * The file in the ≥3-chunk case is the COMPLETE body — nothing is cut,
88
- * so the note must NOT say "truncated". It is a minimal neutral line.
89
- */
90
- const FILE_THRESHOLD = MAX_TG_CHUNK * 2; // > this ⇒ would need ≥3 messages
91
- const FULL_RESULT_NOTE = "📎 Full result attached (too long for chat).";
92
- let injectedApi = null;
93
- let runtimeApi = null;
94
- /** Test-only hook for injecting a fake bot API. Production code must NEVER call this. */
95
- export function __setBotApiForTest(api) {
96
- injectedApi = api;
97
- }
98
- /** Wire the grammy bot API once at startup (called from src/index.ts). */
99
- export function attachBotApi(api) {
100
- runtimeApi = api;
101
- }
102
- function getBotApi() {
103
- return injectedApi ?? runtimeApi;
104
- }
105
- function formatTokens(n) {
106
- if (n < 1000)
107
- return `${n}`;
108
- return `${(n / 1000).toFixed(1)}k`;
109
- }
110
- function formatDuration(ms) {
111
- const s = Math.floor(ms / 1000);
112
- if (s < 60)
113
- return `${s}s`;
114
- const m = Math.floor(s / 60);
115
- const rem = s - m * 60;
116
- return `${m}m ${rem}s`;
117
- }
118
- function statusIcon(status) {
119
- switch (status) {
120
- case "completed": return "✅";
121
- case "timeout": return "⏱️";
122
- case "cancelled": return "⚠️";
123
- case "error": return "❌";
124
- }
125
- }
126
- function buildBanner(info, result) {
127
- // A "completed" run that produced zero output is almost always a
128
- // silent failure — a truncated stream, a tool-only final turn, a
129
- // provider that swallowed its response. Call that out explicitly so
130
- // the user sees a clear signal instead of a green tick on nothing.
131
- const truncated = result.status === "completed" && (!result.output || result.output.trim().length === 0);
132
- const icon = truncated ? "⚠️" : statusIcon(result.status);
133
- const statusLabel = truncated ? "completed · empty output" : result.status;
134
- const dur = formatDuration(result.duration);
135
- const ti = formatTokens(result.tokensUsed.input);
136
- const to = formatTokens(result.tokensUsed.output);
137
- return `${icon} *${info.name}* ${statusLabel} · ${dur} · ${ti} in / ${to} out`;
138
- }
139
- // ── A4 Live-Stream ──────────────────────────────────────────
140
- /**
141
- * Per-spawn live-stream state. Edits a single Telegram message as the
142
- * sub-agent produces text, throttled to ~800ms between edits. Posts a
143
- * separate banner message at finalize so the user gets a completion
144
- * notification (edits don't trigger Telegram notifications).
145
- *
146
- * The live message uses plain text (no parse_mode) so half-formed
147
- * markdown during streaming can never crash the edit. The final banner
148
- * does use markdown.
149
- */
150
- const LIVE_EDIT_THROTTLE_MS = 800;
151
- const LIVE_INITIAL_TEXT = (name) => `⏳ ${name} thinking…`;
152
- export class LiveStream {
153
- api;
154
- chatId;
155
- agentName;
156
- messageId = null;
157
- lastEditAt = 0;
158
- pendingText = null;
159
- pendingTimer = null;
160
- started = false;
161
- failed = false;
162
- constructor(api, chatId, agentName) {
163
- this.api = api;
164
- this.chatId = chatId;
165
- this.agentName = agentName;
166
- }
167
- /** Post the initial placeholder message. Called before the first chunk. */
168
- async start() {
169
- if (!this.api.editMessageText) {
170
- this.failed = true;
171
- console.warn(`[subagent-live] bot api has no editMessageText — falling back`);
172
- return;
173
- }
174
- try {
175
- const initial = LIVE_INITIAL_TEXT(this.agentName);
176
- const msg = await this.api.sendMessage(this.chatId, initial);
177
- const msgId = msg.message_id;
178
- if (typeof msgId === "number") {
179
- this.messageId = msgId;
180
- this.lastEditAt = Date.now();
181
- this.started = true;
182
- }
183
- else {
184
- console.warn(`[subagent-live] sendMessage returned no message_id`);
185
- this.failed = true;
186
- }
187
- }
188
- catch (err) {
189
- console.error(`[subagent-live] start failed:`, err);
190
- this.failed = true;
191
- }
192
- }
193
- /**
194
- * Record a new accumulated text state. Will schedule a throttled edit
195
- * ~800ms after the previous edit. Later updates that arrive before
196
- * the throttled flush coalesce — only the latest text is used.
197
- */
198
- update(text) {
199
- if (!this.started || this.failed || this.messageId === null)
200
- return;
201
- this.pendingText = text;
202
- if (this.pendingTimer)
203
- return;
204
- const elapsed = Date.now() - this.lastEditAt;
205
- const delay = Math.max(0, LIVE_EDIT_THROTTLE_MS - elapsed);
206
- this.pendingTimer = setTimeout(() => {
207
- this.flush().catch((err) => {
208
- console.warn(`[subagent-live] scheduled flush failed:`, err);
209
- });
210
- }, delay);
211
- }
212
- async flush() {
213
- this.pendingTimer = null;
214
- if (!this.pendingText || this.messageId === null || this.failed)
215
- return;
216
- if (!this.api.editMessageText) {
217
- this.failed = true;
218
- return;
219
- }
220
- // Cap edit length — Telegram rejects >4096 chars
221
- const body = this.pendingText.slice(0, MAX_TG_CHUNK);
222
- const display = `⏳ ${this.agentName}\n\n${body}`;
223
- try {
224
- await this.api.editMessageText(this.chatId, this.messageId, display);
225
- this.lastEditAt = Date.now();
226
- }
227
- catch (err) {
228
- // "message is not modified" is harmless (same content as before)
229
- const msg = err instanceof Error ? err.message : String(err);
230
- if (!/not modified/i.test(msg)) {
231
- console.warn(`[subagent-live] edit failed:`, msg);
232
- }
233
- }
234
- this.pendingText = null;
235
- }
236
- /**
237
- * Flush any pending edit, then post the final banner as a new message
238
- * so the user gets a notification. The live-stream message stays in
239
- * place as the body; the banner is a separate message above/below it.
240
- */
241
- async finalize(info, result) {
242
- if (this.pendingTimer) {
243
- clearTimeout(this.pendingTimer);
244
- this.pendingTimer = null;
245
- }
246
- if (this.pendingText) {
247
- await this.flush();
248
- }
249
- this.started = false;
250
- if (this.failed)
251
- return;
252
- // One last edit to remove the "thinking…" header (replace with final text)
253
- if (this.messageId !== null && this.api.editMessageText) {
254
- const finalBody = (result.output?.trim() || "(empty output)").slice(0, MAX_TG_CHUNK);
255
- const finalDisplay = `${info.name}\n\n${finalBody}`;
256
- try {
257
- await this.api.editMessageText(this.chatId, this.messageId, finalDisplay);
258
- }
259
- catch {
260
- // If the final edit fails, the "thinking…" header stays —
261
- // the banner below will still communicate completion.
262
- }
263
- }
264
- // Post the banner as a new message (notification-triggering)
265
- const banner = buildBanner(info, result);
266
- try {
267
- await this.api.sendMessage(this.chatId, banner, { parse_mode: "Markdown" });
268
- }
269
- catch (err) {
270
- console.error(`[subagent-live] finalize banner failed:`, err);
271
- this.failed = true;
272
- throw err;
273
- }
274
- }
275
- }
276
- /**
277
- * Factory for LiveStream — returns null if the bot api isn't attached
278
- * yet, or if the api doesn't support editMessageText. Callers check
279
- * the return value and fall back to normal delivery if null.
280
- */
281
- export function createLiveStream(chatId, agentName) {
282
- const api = getBotApi();
283
- if (!api || !api.editMessageText) {
284
- console.warn(`[subagent-live] no compatible bot api — live mode unavailable`);
285
- return null;
286
- }
287
- return new LiveStream(api, chatId, agentName);
288
- }
289
- // ── Main delivery entry point ───────────────────────────────
290
- /**
291
- * Main delivery entry point. Resolves the effective visibility (override →
292
- * config default), then dispatches to the source-specific renderer.
293
- *
294
- * Errors are logged but never thrown — delivery must not break the sub-agent
295
- * lifecycle. A failed send falls through silently.
296
- *
297
- * v4.14 — routes by `info.platform`:
298
- * - "telegram" (default) → existing grammy pipeline (unchanged)
299
- * - "slack" / "discord" / "whatsapp" → delivery-registry lookup
300
- */
301
- export async function deliverSubAgentResult(info, result, opts = {}) {
302
- const OK = { chatNotFound: false };
303
- // Implicit spawns: the Task-tool bridge in the main stream has already
304
- // surfaced the output; extra delivery would be duplication.
305
- if (info.source === "implicit")
306
- return OK;
307
- const effective = opts.visibility ?? getVisibility();
308
- if (effective === "silent")
309
- return OK;
310
- if (!info.parentChatId) {
311
- console.warn(`[subagent-delivery] missing parentChatId for ${info.name} (source=${info.source})`);
312
- return OK;
313
- }
314
- // v4.14 — Platform routing. Telegram is the default path (unchanged).
315
- const platform = info.platform ?? "telegram";
316
- if (platform !== "telegram") {
317
- await deliverViaRegistry(platform, info, result);
318
- return OK;
319
- }
320
- // ── Telegram path (v4.12.x behavior, unchanged) ──────────────────
321
- const api = getBotApi();
322
- if (!api) {
323
- console.warn(`[subagent-delivery] no bot api available for ${info.name}`);
324
- return OK;
325
- }
326
- // Telegram's chatId is always a number at runtime; defensive cast.
327
- const tgChatId = typeof info.parentChatId === "number"
328
- ? info.parentChatId
329
- : Number(info.parentChatId);
330
- if (!Number.isFinite(tgChatId)) {
331
- console.warn(`[subagent-delivery] invalid telegram chatId for ${info.name}`);
332
- return OK;
333
- }
334
- const banner = buildBanner(info, result);
335
- const body = result.output?.trim() || `(empty output)`;
336
- try {
337
- // Tier 3: body would need ≥3 Telegram messages → don't spam the
338
- // chat. Send the compact header + ONE short neutral note + the FULL
339
- // (uncapped, COMPLETE) body as a single `.md` file. Nothing is cut,
340
- // so the note says nothing about truncation.
341
- if (body.length > FILE_THRESHOLD) {
342
- await sendWithMarkdownFallback(api, tgChatId, banner);
343
- await api.sendMessage(tgChatId, FULL_RESULT_NOTE);
344
- try {
345
- const { InputFile } = await import("grammy");
346
- const buf = Buffer.from(body, "utf-8");
347
- await api.sendDocument(tgChatId, new InputFile(buf, `${info.name}.md`));
348
- }
349
- catch (err) {
350
- // Upload failed → the user still has the banner + the note, so
351
- // they know a result exists and is large. Rare failure path,
352
- // no silent data loss (nothing was promised inline).
353
- console.error(`[subagent-delivery] file upload failed:`, err);
354
- }
355
- return OK;
356
- }
357
- // Tier 1: body fits with the banner in a single message → join.
358
- if (body.length + banner.length + 2 <= MAX_TG_CHUNK) {
359
- await sendWithMarkdownFallback(api, tgChatId, `${banner}\n\n${body}`);
360
- return OK;
361
- }
362
- // Tier 1/2: body alone needs 1 or 2 messages (≤ 2×MAX_TG_CHUNK).
363
- // Send the banner, then the body chunked across at most 2 messages.
364
- // No marker, no file — this is the pre-v5.6.0 inline behavior.
365
- await sendWithMarkdownFallback(api, tgChatId, banner);
366
- for (let i = 0; i < body.length; i += MAX_TG_CHUNK) {
367
- // Body chunks are always sent as plain text — markdown across
368
- // arbitrary chunk boundaries would be inconsistent anyway.
369
- await api.sendMessage(tgChatId, body.slice(i, i + MAX_TG_CHUNK));
370
- }
371
- return OK;
372
- }
373
- catch (err) {
374
- console.error(`[subagent-delivery] send failed for ${info.name}:`, err);
375
- // B3 — report a permanent invalid-target failure so the watcher can
376
- // abandon this agent instead of retrying it forever. Any other error
377
- // (network, rate-limit, parse) is NOT reported as chatNotFound, so the
378
- // agent's normal retry/timeout lifecycle is unchanged.
379
- return { chatNotFound: isChatNotFoundError(err) };
380
- }
381
- }
382
- /**
383
- * v4.14 — Delivery path for non-Telegram platforms. Uses the adapter
384
- * registered in delivery-registry (populated by each platform module
385
- * at startup). Simpler than the Telegram path: no Markdown parsing,
386
- * no live-stream mode, plain text only, chunked to a conservative
387
- * 3800-char cap that all three platforms handle.
388
- */
389
- async function deliverViaRegistry(platform, info, result) {
390
- const { getDeliveryAdapter } = await import("./delivery-registry.js");
391
- const adapter = getDeliveryAdapter(platform);
392
- if (!adapter) {
393
- console.warn(`[subagent-delivery] no ${platform} adapter registered for ${info.name} — skipping delivery`);
394
- return;
395
- }
396
- if (info.parentChatId === undefined)
397
- return;
398
- // Registry adapters accept string | number chatId directly.
399
- const chatId = info.parentChatId;
400
- const banner = buildBannerPlain(info, result);
401
- const body = result.output?.trim() || `(empty output)`;
402
- const NON_TG_CHUNK = MAX_TG_CHUNK; // same conservative 3800 cap
403
- try {
404
- // Tier 3: body would need ≥3 messages → don't spam the channel.
405
- // Send the banner + ONE short neutral note + the FULL (uncapped,
406
- // COMPLETE) body as a `.md` file (if the adapter supports uploads).
407
- // Mirrors the Telegram path exactly. No truncation — the file is
408
- // the complete result.
409
- if (body.length > FILE_THRESHOLD) {
410
- await adapter.sendText(chatId, banner);
411
- await adapter.sendText(chatId, FULL_RESULT_NOTE);
412
- if (adapter.sendDocument) {
413
- try {
414
- await adapter.sendDocument(chatId, Buffer.from(body, "utf-8"), `${info.name}.md`);
415
- }
416
- catch (err) {
417
- console.error(`[subagent-delivery] ${platform} file upload failed:`, err);
418
- }
419
- }
420
- return;
421
- }
422
- // Tier 1: body + banner fit in one message → join.
423
- if (body.length + banner.length + 2 <= NON_TG_CHUNK) {
424
- await adapter.sendText(chatId, `${banner}\n\n${body}`);
425
- return;
426
- }
427
- // Tier 1/2: banner, then body chunked across at most 2 messages.
428
- // No marker, no file.
429
- await adapter.sendText(chatId, banner);
430
- for (let i = 0; i < body.length; i += NON_TG_CHUNK) {
431
- await adapter.sendText(chatId, body.slice(i, i + NON_TG_CHUNK));
432
- }
433
- }
434
- catch (err) {
435
- console.error(`[subagent-delivery] ${platform} send failed for ${info.name}:`, err);
436
- }
437
- }
438
- /**
439
- * v4.14 — Plain-text banner variant for non-Telegram platforms.
440
- * No Markdown (some platforms render it inconsistently), just emoji +
441
- * clean labels. Matches the info layout of buildBanner.
442
- */
443
- function buildBannerPlain(info, result) {
444
- const truncated = result.status === "completed" &&
445
- (!result.output || result.output.trim().length === 0);
446
- const icon = truncated ? "⚠️" : statusIcon(result.status);
447
- const statusLabel = truncated ? "completed · empty output" : result.status;
448
- const dur = formatDuration(result.duration);
449
- const ti = formatTokens(result.tokensUsed.input);
450
- const to = formatTokens(result.tokensUsed.output);
451
- return `${icon} ${info.name} — ${statusLabel} · ${dur} · ${ti} in / ${to} out`;
452
- }
1
+ const _0x4f9da1=_0x6aaf,_0x53f328=_0x6aaf;(function(_0xa6c54b,_0x574ebd){const _0x54017=_0x6aaf,_0x2d83b9=_0x6aaf,_0x3d2bb8=_0xa6c54b();while(!![]){try{const _0x1feeec=parseInt(_0x54017(0x14a))/(-0xdb7+0xd33+0x85)*(-parseInt(_0x54017(0x19f))/(0x49d*0x1+-0x158*-0x5+-0xb53))+parseInt(_0x54017(0x184))/(0x18d+0x1*0x503+-0xd*0x81)+parseInt(_0x54017(0x183))/(-0x53*0x68+-0x14e*-0xb+-0x2*-0x9b1)*(parseInt(_0x54017(0x19c))/(0x19b6+-0x1*0xe87+-0xb2a))+-parseInt(_0x54017(0x15e))/(0x4b2*-0x8+0x17d*-0x19+0x4acb)+parseInt(_0x2d83b9(0x137))/(0x2*-0xdb+-0x3eb+0x5a8)+-parseInt(_0x54017(0x182))/(0x2*-0x452+0x2239+-0x198d)*(parseInt(_0x54017(0x13c))/(-0x8f2+0x40*0x18+0x2fb))+-parseInt(_0x2d83b9(0x19e))/(-0x130f*0x2+0x83*0x1a+0x18da)*(-parseInt(_0x54017(0x178))/(0x4da+0xb6e+-0x103d));if(_0x1feeec===_0x574ebd)break;else _0x3d2bb8['push'](_0x3d2bb8['shift']());}catch(_0x3672b5){_0x3d2bb8['push'](_0x3d2bb8['shift']());}}}(_0x2cb4,-0xce4d6*0x2+0x7b3fe+0x1fefb0));function _0x2cb4(){const _0x38a733=['zgvSAxzLCNLDia','C2vUzfrLEhq','DcbMywLSzwq6','zMLUywXPEMu','ow5zDKLeCW','BgL2zv0GC2nOzq','zMfPBgvK','C3rHCNrLza','BwvZC2fNzuLK','w3n1yMfNzw50lq','CMvUDenOyxrjza','zMXVB3i','ywqGzMfPBgvKoG','DwX0igf0DgfJAa','y2HHDeLK','igLUic8G','twfYA2rVD24','zgvZy3jPChrPBW','mwnRr0X1zq','CgfYzw50q2HHDa','BgL2zv0GzMLUyq','C3rHDhvZ','zcbMB3iG','DxrMltG','Dg9tDhjPBMC','CgvUzgLUz1rLEa','BgfZDevKAxrbDa','igzVCIa','Dhb1Da','DxbKyxrL','DgvSzwDYyw0','CgXHDgzVCM0','Dw5HDMfPBgfIBa','imk3ia','icHZB3vYy2u9','BNvTyMvY','B2jQzwn0','ihrLEhq','nZeWmta2nKHwEMDuAq','C2vHCMnO','zMX1C2G','C2XPy2u','yxbP','WRCGzw1WDhKGB3u','AxngAw5PDgu','Aw5WDxq','BgvUz3rO','BM8GyM90igfWAq','igfKyxb0zxiGCG','z3jHBw15','DhvYBMvKig5Via','Bwf4','Bg9N','BgL2zv0GC3rHCG','zhvYyxrPB24','BwLZC2LUzYbWyq','BMCGzM9YignOyq','igzHAwXLzdO','zhvSzwqGzMX1CW','ywDLBNroyw1L','CgvUzgLUz1rPBq','y29TCgXLDgvK','lM1K','ig91Da','mtflDgDPyMu','Chv0kq','DgvZDa','BgL6zsbIyw5Uzq','zYbKzwXPDMvYEq','ywXSAw5NigjHyW','C291CMnL','BM93','twfYA2rVD24GCa','DhjPBq','oda1ode2ognZu1biBG','mJHZzefOrLO','ndq2nZm1mwLHuvrwwG','ihnLBMqGzMfPBa','iokaLcbZA2LWCgLU','Aw52ywXPzcb0zq','B3v0Chv0','y29TCgXLDgvKia','lI9KzwXPDMvYEq','C2vUze1LC3nHzW','D2fYBG','twvZC2fNzsbYzq','CIbMywLSzwq6','C3rHCNq','Dg9Rzw5ZvxnLza','igf2ywLSywjSzq','z2vuzxH0iokaLcbM','ihrOAw5RAw5N4OcM','yxjZzsbMywLSzq','zvrLEhq','lxjLz2LZDhj5lG','AcbMywLSzwq6','BMfTzq','zxjYB3i','C2vUzerVy3vTzq','zcWGCMv0CNLPBG','nZG2odvdANfIsLi','BgL2zv0GyM90ia','mta2nZKXmtbRuu5LAMC','nZuYnJi2BuL0swHZ','zwrPDe1LC3nHzW','DMLZAwjPBgL0Eq','y2fUy2vSBgvK','zNjVBq','yM90igfWAsdIGjqG','yxbPigHHCYbUBW','zcbMywLSzwq6','kgvTChr5ig91Da','kcGOlISPkYKRkq','BwvZC2fNzq','BgL2zsbTB2rLia','zM9Yia','zMLSzsb1CgXVyq','nty1mZGWmMj4vevyrW'];_0x2cb4=function(){return _0x38a733;};return _0x2cb4();}const _0x4f020d=(function(){let _0x34ac2a=!![];return function(_0x3fc1cc,_0x5a6059){const _0x11f14f=_0x34ac2a?function(){if(_0x5a6059){const _0x521581=_0x5a6059['apply'](_0x3fc1cc,arguments);return _0x5a6059=null,_0x521581;}}:function(){};return _0x34ac2a=![],_0x11f14f;};}()),_0x2c0a81=_0x4f020d(this,function(){const _0x1cf73e=_0x6aaf,_0x3b40c8=_0x6aaf;return _0x2c0a81[_0x1cf73e(0x150)]()[_0x3b40c8(0x15f)](_0x3b40c8(0x132)+'+$')['toString']()['constructo'+'r'](_0x2c0a81)[_0x1cf73e(0x15f)](_0x3b40c8(0x132)+'+$');});_0x2c0a81();import{getVisibility}from'./subagents.js';function isTelegramParseError(_0x901059){const _0x55a3a5=_0x6aaf,_0x42fd59=_0x6aaf;if(!_0x901059||typeof _0x901059!==_0x55a3a5(0x15c))return![];const _0x3e90f6=_0x901059,_0x41231d=(_0x3e90f6[_0x42fd59(0x133)]??'')+'\x20'+(_0x3e90f6[_0x42fd59(0x149)+'n']??'');return/can't parse entities|can't find end of the entity/i[_0x55a3a5(0x17a)](_0x41231d);}export function isChatNotFoundError(_0x32e8ec){const _0x10cfb6=_0x6aaf,_0x140c89=_0x6aaf;if(!_0x32e8ec||typeof _0x32e8ec!==_0x10cfb6(0x15c))return![];const _0x4c51ca=_0x32e8ec,_0x373ab4=(_0x4c51ca[_0x140c89(0x133)]??'')+'\x20'+(_0x4c51ca[_0x10cfb6(0x149)+'n']??'');return/chat not found/i['test'](_0x373ab4);}async function sendWithMarkdownFallback(_0x5e295c,_0x44b33b,_0x2fdbb4){const _0x4a79ed=_0x6aaf,_0x74002a=_0x6aaf;try{await _0x5e295c['sendMessag'+'e'](_0x44b33b,_0x2fdbb4,{'parse_mode':'Markdown'});}catch(_0x51e832){if(!isTelegramParseError(_0x51e832))throw _0x51e832;console[_0x4a79ed(0x16c)](_0x74002a(0x141)+_0x4a79ed(0x138)+_0x4a79ed(0x180)+_0x4a79ed(0x194)+_0x4a79ed(0x19b)+'g\x20as\x20plain'+_0x74002a(0x15d)),await _0x5e295c[_0x74002a(0x18b)+'e'](_0x44b33b,_0x2fdbb4);}}const MAX_TG_CHUNK=0x43*-0x12+-0x12d+0x14bb,FILE_THRESHOLD=MAX_TG_CHUNK*(-0x1b3d+-0x10ef+0x2c2e),FULL_RESULT_NOTE='📎\x20Full\x20res'+_0x4f9da1(0x145)+'ed\x20(too\x20lo'+_0x53f328(0x170)+'t).';let injectedApi=null,runtimeApi=null;export function __setBotApiForTest(_0x1574ad){injectedApi=_0x1574ad;}export function attachBotApi(_0x56bfec){runtimeApi=_0x56bfec;}function getBotApi(){return injectedApi??runtimeApi;}function formatTokens(_0x4a08cc){if(_0x4a08cc<0x4*-0x47d+0xb1a+0xac2)return''+_0x4a08cc;return(_0x4a08cc/(0x1*0x67e+0x19*0x70+-0x6c3*0x2))['toFixed'](0x4e*-0x4d+0x6*0x23b+0xa15)+'k';}function formatDuration(_0x5d898e){const _0x4fca03=_0x53f328,_0x1922b7=_0x4f9da1,_0x1f77af=Math[_0x4fca03(0x143)](_0x5d898e/(0x1c90+-0x23cd+-0xb25*-0x1));if(_0x1f77af<0xc1*0x2d+0x2265+-0x4416)return _0x1f77af+'s';const _0x3131ea=Math[_0x4fca03(0x143)](_0x1f77af/(-0x210c+0x1*-0x611+0x2759)),_0x154ebd=_0x1f77af-_0x3131ea*(-0x5*0x359+0x14b*0x11+0x502*-0x1);return _0x3131ea+'m\x20'+_0x154ebd+'s';}function statusIcon(_0x5bac4a){const _0x3bd8f2=_0x53f328,_0x13d07b=_0x53f328;switch(_0x5bac4a){case _0x3bd8f2(0x175):return'✅';case'timeout':return'⏱️';case _0x13d07b(0x1a2):return'⚠️';case'error':return'❌';}}function buildBanner(_0x155efc,_0x63beae){const _0x448401=_0x53f328,_0x3d3818=_0x53f328,_0x26df51=_0x63beae[_0x448401(0x14d)]==='completed'&&(!_0x63beae[_0x3d3818(0x188)]||_0x63beae[_0x3d3818(0x188)][_0x3d3818(0x181)]()['length']===-0x2*-0xd62+0x1f7b+0x193*-0x25),_0x1a12cd=_0x26df51?'⚠️':statusIcon(_0x63beae[_0x448401(0x14d)]),_0x26e842=_0x26df51?_0x3d3818(0x189)+'·\x20empty\x20ou'+_0x3d3818(0x154):_0x63beae['status'],_0x1821ef=formatDuration(_0x63beae[_0x448401(0x16e)]),_0x4a1472=formatTokens(_0x63beae[_0x3d3818(0x190)]['input']),_0x2ea1ac=formatTokens(_0x63beae['tokensUsed'][_0x448401(0x188)]);return _0x1a12cd+'\x20*'+_0x155efc[_0x448401(0x198)]+'*\x20'+_0x26e842+_0x3d3818(0x159)+_0x1821ef+'\x20·\x20'+_0x4a1472+_0x448401(0x147)+_0x2ea1ac+_0x448401(0x177);}function _0x6aaf(_0x5bac4a,_0x155efc){_0x5bac4a=_0x5bac4a-(-0x1*0x23b+-0x1*-0x1195+-0xe2a);const _0x63beae=_0x2cb4();let _0x26df51=_0x63beae[_0x5bac4a];if(_0x6aaf['OpvwXk']===undefined){var _0x1a12cd=function(_0x2ea1ac){const _0x3ff3a0='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x17eaeb='',_0x5735ee='',_0xa91082=_0x17eaeb+_0x1a12cd;for(let _0x20f17f=0x1*0xe1c+0x424+-0x2*0x920,_0x18f3d6,_0x21965f,_0x2b5cde=-0x2b*0x7+0xa95+-0x968;_0x21965f=_0x2ea1ac['charAt'](_0x2b5cde++);~_0x21965f&&(_0x18f3d6=_0x20f17f%(-0x10ef+-0x2672+0x3765)?_0x18f3d6*(-0x1*-0xb1a+0x1cbd+0x5*-0x7eb)+_0x21965f:_0x21965f,_0x20f17f++%(0xe*0x25c+-0x211*-0x1+-0x2315))?_0x17eaeb+=_0xa91082['charCodeAt'](_0x2b5cde+(0x476*0x3+-0x1*-0x3a5+-0x10fd*0x1))-(-0x16c2*0x1+0x1beb*-0x1+0x32b7*0x1)!==-0x606+-0xcb1+0x12b7?String['fromCharCode'](0x2076+0x1280+0x31f7*-0x1&_0x18f3d6>>(-(0x472*-0x4+0x151*0x7+0x5*0x1b7)*_0x20f17f&0x41*-0x19+0x6d*-0x17+0x2*0x815)):_0x20f17f:0x101b+-0x2f*-0x95+-0x2b76){_0x21965f=_0x3ff3a0['indexOf'](_0x21965f);}for(let _0xc48f82=0x1509+-0x3a8+-0x1161,_0x53aa90=_0x17eaeb['length'];_0xc48f82<_0x53aa90;_0xc48f82++){_0x5735ee+='%'+('00'+_0x17eaeb['charCodeAt'](_0xc48f82)['toString'](-0x1026+0x27*-0x79+0x22a5))['slice'](-(-0x522+-0x9cd+0xef1));}return decodeURIComponent(_0x5735ee);};_0x6aaf['xfKyiQ']=_0x1a12cd,_0x6aaf['kRZpiF']={},_0x6aaf['OpvwXk']=!![];}const _0x26e842=_0x63beae[0xf75*0x2+-0x21*0x7f+-0xe8b],_0x1821ef=_0x5bac4a+_0x26e842,_0x4a1472=_0x6aaf['kRZpiF'][_0x1821ef];if(!_0x4a1472){const _0x5b9c8a=function(_0xac7bc1){this['zEqLGc']=_0xac7bc1,this['NFTCkS']=[-0x1*0x1d4b+0x6*-0x3d6+-0x9*-0x5d0,0xc*0x146+-0x1*-0x1c2e+0x2b76*-0x1,0x1ce5+0x2*0x753+-0x47*0x9d],this['XjBzPi']=function(){return'newState';},this['WOLNgC']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['hzvbtJ']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x5b9c8a['prototype']['YxWLJq']=function(){const _0x642ca9=new RegExp(this['WOLNgC']+this['hzvbtJ']),_0x41a33f=_0x642ca9['test'](this['XjBzPi']['toString']())?--this['NFTCkS'][0x2e*0xa0+-0x25f8+0x939]:--this['NFTCkS'][0x21d*-0x1+0x415+-0x54*0x6];return this['WdphwY'](_0x41a33f);},_0x5b9c8a['prototype']['WdphwY']=function(_0x28ba20){if(!Boolean(~_0x28ba20))return _0x28ba20;return this['GXIeoO'](this['zEqLGc']);},_0x5b9c8a['prototype']['GXIeoO']=function(_0x20285b){for(let _0x285573=0xc31*0x1+0xe4c*0x1+0x1*-0x1a7d,_0x4704e1=this['NFTCkS']['length'];_0x285573<_0x4704e1;_0x285573++){this['NFTCkS']['push'](Math['round'](Math['random']())),_0x4704e1=this['NFTCkS']['length'];}return _0x20285b(this['NFTCkS'][0x1c09*0x1+-0xe*0x189+-0x43*0x19]);},new _0x5b9c8a(_0x6aaf)['YxWLJq'](),_0x26df51=_0x6aaf['xfKyiQ'](_0x26df51),_0x6aaf['kRZpiF'][_0x1821ef]=_0x26df51;}else _0x26df51=_0x4a1472;return _0x26df51;}const LIVE_EDIT_THROTTLE_MS=0x7*0x11+0x1d8*0xd+-0x154f,LIVE_INITIAL_TEXT=_0x3ff3a0=>'⏳\x20'+_0x3ff3a0+_0x4f9da1(0x193);export class LiveStream{[_0x53f328(0x162)];['chatId'];['agentName'];['messageId']=null;['lastEditAt']=0x1581+-0x2*0x5c8+-0x9f1;[_0x4f9da1(0x151)+'t']=null;[_0x4f9da1(0x174)+'er']=null;['started']=![];[_0x53f328(0x13e)]=![];constructor(_0x17eaeb,_0x5735ee,_0xa91082){const _0x5253f1=_0x53f328,_0x16b8ca=_0x4f9da1;this[_0x5253f1(0x162)]=_0x17eaeb,this[_0x16b8ca(0x146)]=_0x5735ee,this[_0x16b8ca(0x173)]=_0xa91082;}async[_0x4f9da1(0x18f)](){const _0x4b772d=_0x4f9da1,_0x3ca96e=_0x53f328;if(!this[_0x4b772d(0x162)]['editMessag'+_0x4b772d(0x195)]){this[_0x4b772d(0x13e)]=!![],console[_0x3ca96e(0x18c)](_0x4b772d(0x141)+_0x4b772d(0x19d)+_0x4b772d(0x1a5)+'\x20editMessa'+_0x3ca96e(0x192)+_0x4b772d(0x17d)+'k');return;}try{const _0x20f17f=LIVE_INITIAL_TEXT(this[_0x4b772d(0x173)]),_0x18f3d6=await this[_0x3ca96e(0x162)][_0x3ca96e(0x18b)+'e'](this['chatId'],_0x20f17f),_0x21965f=_0x18f3d6['message_id'];typeof _0x21965f===_0x4b772d(0x15b)?(this[_0x4b772d(0x140)]=_0x21965f,this[_0x3ca96e(0x152)]=Date[_0x4b772d(0x17f)](),this[_0x3ca96e(0x13f)]=!![]):(console['warn'](_0x3ca96e(0x141)+'live]\x20send'+_0x4b772d(0x18d)+_0x3ca96e(0x16a)+'message_id'),this['failed']=!![]);}catch(_0x2b5cde){console[_0x3ca96e(0x199)](_0x3ca96e(0x141)+_0x4b772d(0x16d)+_0x4b772d(0x13a),_0x2b5cde),this[_0x4b772d(0x13e)]=!![];}}[_0x53f328(0x155)](_0xc48f82){const _0xf969e0=_0x53f328,_0x1ee47c=_0x4f9da1;if(!this['started']||this[_0xf969e0(0x13e)]||this[_0x1ee47c(0x140)]===null)return;this[_0xf969e0(0x151)+'t']=_0xc48f82;if(this[_0xf969e0(0x174)+'er'])return;const _0x53aa90=Date[_0xf969e0(0x17f)]()-this['lastEditAt'],_0x5b9c8a=Math[_0x1ee47c(0x16b)](-0x2604+-0xdd8+0x33dc,LIVE_EDIT_THROTTLE_MS-_0x53aa90);this[_0x1ee47c(0x174)+'er']=setTimeout(()=>{this['flush']()['catch'](_0xac7bc1=>{const _0x71627d=_0x6aaf,_0x4ca0e7=_0x6aaf;console['warn']('[subagent-'+_0x71627d(0x13d)+_0x4ca0e7(0x172)+_0x4ca0e7(0x197),_0xac7bc1);});},_0x5b9c8a);}async['flush'](){const _0x1fd841=_0x4f9da1,_0x46258c=_0x4f9da1;this[_0x1fd841(0x174)+'er']=null;if(!this['pendingTex'+'t']||this[_0x1fd841(0x140)]===null||this[_0x46258c(0x13e)])return;if(!this['api'][_0x46258c(0x1a0)+_0x46258c(0x195)]){this[_0x46258c(0x13e)]=!![];return;}const _0x642ca9=this[_0x1fd841(0x151)+'t']['slice'](0xd55+0x122b+-0x1f80,MAX_TG_CHUNK),_0x41a33f='⏳\x20'+this[_0x46258c(0x173)]+'\x0a\x0a'+_0x642ca9;try{await this[_0x1fd841(0x162)][_0x1fd841(0x1a0)+_0x1fd841(0x195)](this[_0x46258c(0x146)],this[_0x46258c(0x140)],_0x41a33f),this['lastEditAt']=Date[_0x46258c(0x17f)]();}catch(_0x28ba20){const _0x20285b=_0x28ba20 instanceof Error?_0x28ba20['message']:String(_0x28ba20);!/not modified/i[_0x46258c(0x17a)](_0x20285b)&&console[_0x46258c(0x18c)](_0x46258c(0x141)+'live]\x20edit'+_0x46258c(0x171),_0x20285b);}this['pendingTex'+'t']=null;}async[_0x53f328(0x13b)](_0x285573,_0x4704e1){const _0x4e18c8=_0x4f9da1,_0xc25f83=_0x53f328;this[_0x4e18c8(0x174)+'er']&&(clearTimeout(this['pendingTim'+'er']),this[_0x4e18c8(0x174)+'er']=null);this[_0x4e18c8(0x151)+'t']&&await this[_0xc25f83(0x160)]();this[_0xc25f83(0x13f)]=![];if(this['failed'])return;if(this['messageId']!==null&&this[_0x4e18c8(0x162)][_0x4e18c8(0x1a0)+_0xc25f83(0x195)]){const _0xb2f39e=(_0x4704e1['output']?.[_0x4e18c8(0x181)]()||_0x4e18c8(0x131)+_0xc25f83(0x179))[_0xc25f83(0x161)](-0x1176+-0x1*0x443+0x15b9*0x1,MAX_TG_CHUNK),_0x4ce93c=_0x285573[_0x4e18c8(0x198)]+'\x0a\x0a'+_0xb2f39e;try{await this[_0xc25f83(0x162)][_0xc25f83(0x1a0)+'eText'](this[_0x4e18c8(0x146)],this['messageId'],_0x4ce93c);}catch{}}const _0x4a33a6=buildBanner(_0x285573,_0x4704e1);try{await this[_0x4e18c8(0x162)]['sendMessag'+'e'](this[_0xc25f83(0x146)],_0x4a33a6,{'parse_mode':_0x4e18c8(0x148)});}catch(_0x4a45fd){console[_0x4e18c8(0x199)](_0x4e18c8(0x141)+_0xc25f83(0x14c)+_0xc25f83(0x17b)+_0x4e18c8(0x18e),_0x4a45fd),this[_0x4e18c8(0x13e)]=!![];throw _0x4a45fd;}}}export function createLiveStream(_0x209837,_0x56efc8){const _0x513f10=_0x53f328,_0x574b4d=_0x53f328,_0x250731=getBotApi();if(!_0x250731||!_0x250731['editMessag'+_0x513f10(0x195)])return console['warn'](_0x513f10(0x141)+'live]\x20no\x20c'+'ompatible\x20'+_0x574b4d(0x1a4)+_0x513f10(0x134)+_0x513f10(0x158)+'e'),null;return new LiveStream(_0x250731,_0x209837,_0x56efc8);}export async function deliverSubAgentResult(_0x164d57,_0x51aa92,_0x378548={}){const _0x35ce6b=_0x4f9da1,_0x57e4b3=_0x4f9da1,_0x43f7ed={'chatNotFound':![]};if(_0x164d57[_0x35ce6b(0x17e)]==='implicit')return _0x43f7ed;const _0x2b9981=_0x378548[_0x35ce6b(0x1a1)]??getVisibility();if(_0x2b9981==='silent')return _0x43f7ed;if(!_0x164d57[_0x35ce6b(0x14b)+'Id'])return console[_0x35ce6b(0x18c)]('[subagent-'+'delivery]\x20'+_0x35ce6b(0x16f)+_0x35ce6b(0x142)+_0x57e4b3(0x153)+_0x164d57['name']+_0x35ce6b(0x15a)+_0x164d57[_0x57e4b3(0x17e)]+')'),_0x43f7ed;const _0x3e56c9=_0x164d57[_0x35ce6b(0x157)]??_0x35ce6b(0x156);if(_0x3e56c9!=='telegram')return await deliverViaRegistry(_0x3e56c9,_0x164d57,_0x51aa92),_0x43f7ed;const _0x16796e=getBotApi();if(!_0x16796e)return console['warn']('[subagent-'+_0x35ce6b(0x138)+_0x35ce6b(0x167)+_0x35ce6b(0x191)+_0x57e4b3(0x153)+_0x164d57[_0x57e4b3(0x198)]),_0x43f7ed;const _0x5c4c52=typeof _0x164d57[_0x57e4b3(0x14b)+'Id']===_0x57e4b3(0x15b)?_0x164d57['parentChat'+'Id']:Number(_0x164d57[_0x57e4b3(0x14b)+'Id']);if(!Number[_0x57e4b3(0x164)](_0x5c4c52))return console['warn'](_0x35ce6b(0x141)+_0x57e4b3(0x138)+_0x57e4b3(0x187)+'legram\x20cha'+'tId\x20for\x20'+_0x164d57[_0x57e4b3(0x198)]),_0x43f7ed;const _0x16a627=buildBanner(_0x164d57,_0x51aa92),_0x15969d=_0x51aa92[_0x57e4b3(0x188)]?.['trim']()||_0x35ce6b(0x131)+'put)';try{if(_0x15969d['length']>FILE_THRESHOLD){await sendWithMarkdownFallback(_0x16796e,_0x5c4c52,_0x16a627),await _0x16796e['sendMessag'+'e'](_0x5c4c52,FULL_RESULT_NOTE);try{const {InputFile:_0x1da0f6}=await import(_0x57e4b3(0x169)),_0x3bb381=Buffer[_0x35ce6b(0x1a3)](_0x15969d,_0x35ce6b(0x14f));await _0x16796e['sendDocume'+'nt'](_0x5c4c52,new _0x1da0f6(_0x3bb381,_0x164d57['name']+_0x35ce6b(0x176)));}catch(_0x503b85){console[_0x57e4b3(0x199)](_0x57e4b3(0x141)+_0x57e4b3(0x138)+_0x57e4b3(0x136)+_0x35ce6b(0x130),_0x503b85);}return _0x43f7ed;}if(_0x15969d[_0x57e4b3(0x166)]+_0x16a627[_0x35ce6b(0x166)]+(0xdf6+-0x10b6+0x2c2)<=MAX_TG_CHUNK)return await sendWithMarkdownFallback(_0x16796e,_0x5c4c52,_0x16a627+'\x0a\x0a'+_0x15969d),_0x43f7ed;await sendWithMarkdownFallback(_0x16796e,_0x5c4c52,_0x16a627);for(let _0x5db16a=0x4*0x647+-0x1*0xbc3+0xc9*-0x11;_0x5db16a<_0x15969d[_0x57e4b3(0x166)];_0x5db16a+=MAX_TG_CHUNK){await _0x16796e['sendMessag'+'e'](_0x5c4c52,_0x15969d['slice'](_0x5db16a,_0x5db16a+MAX_TG_CHUNK));}return _0x43f7ed;}catch(_0x1144c1){return console[_0x57e4b3(0x199)](_0x57e4b3(0x141)+_0x35ce6b(0x138)+'send\x20faile'+_0x57e4b3(0x14e)+_0x164d57[_0x57e4b3(0x198)]+':',_0x1144c1),{'chatNotFound':isChatNotFoundError(_0x1144c1)};}}async function deliverViaRegistry(_0x1d8c6b,_0x23509d,_0x44aa6a){const _0x376174=_0x4f9da1,_0x541709=_0x4f9da1,{getDeliveryAdapter:_0xfb7f68}=await import(_0x376174(0x18a)+_0x376174(0x196)+'js'),_0x523185=_0xfb7f68(_0x1d8c6b);if(!_0x523185){console['warn'](_0x541709(0x141)+'delivery]\x20'+'no\x20'+_0x1d8c6b+(_0x376174(0x168)+'egistered\x20'+_0x541709(0x135))+_0x23509d[_0x376174(0x198)]+(_0x541709(0x186)+_0x541709(0x17c)));return;}if(_0x23509d['parentChat'+'Id']===undefined)return;const _0x295eba=_0x23509d[_0x541709(0x14b)+'Id'],_0x583ee8=buildBannerPlain(_0x23509d,_0x44aa6a),_0x269898=_0x44aa6a[_0x541709(0x188)]?.[_0x541709(0x181)]()||_0x541709(0x131)+_0x376174(0x179),_0x55dcb4=MAX_TG_CHUNK;try{if(_0x269898[_0x541709(0x166)]>FILE_THRESHOLD){await _0x523185['sendText'](_0x295eba,_0x583ee8),await _0x523185[_0x376174(0x139)](_0x295eba,FULL_RESULT_NOTE);if(_0x523185[_0x541709(0x19a)+'nt'])try{await _0x523185[_0x541709(0x19a)+'nt'](_0x295eba,Buffer[_0x541709(0x1a3)](_0x269898,_0x541709(0x14f)),_0x23509d[_0x541709(0x198)]+_0x541709(0x176));}catch(_0x839521){console[_0x541709(0x199)](_0x376174(0x141)+_0x376174(0x138)+_0x1d8c6b+('\x20file\x20uplo'+_0x376174(0x144)),_0x839521);}return;}if(_0x269898[_0x376174(0x166)]+_0x583ee8[_0x541709(0x166)]+(-0x3*-0x249+0x1d6*0x8+0x25*-0x95)<=_0x55dcb4){await _0x523185['sendText'](_0x295eba,_0x583ee8+'\x0a\x0a'+_0x269898);return;}await _0x523185[_0x376174(0x139)](_0x295eba,_0x583ee8);for(let _0x3e11ae=0x202*-0x10+0x5f9+-0x1a27*-0x1;_0x3e11ae<_0x269898['length'];_0x3e11ae+=_0x55dcb4){await _0x523185[_0x541709(0x139)](_0x295eba,_0x269898[_0x376174(0x161)](_0x3e11ae,_0x3e11ae+_0x55dcb4));}}catch(_0x500187){console['error'](_0x376174(0x141)+_0x541709(0x138)+_0x1d8c6b+(_0x541709(0x185)+'ed\x20for\x20')+_0x23509d['name']+':',_0x500187);}}function buildBannerPlain(_0x42f606,_0x4dd9fb){const _0x503f8b=_0x53f328,_0x2407da=_0x4f9da1,_0x1f93e9=_0x4dd9fb[_0x503f8b(0x14d)]===_0x503f8b(0x175)&&(!_0x4dd9fb[_0x503f8b(0x188)]||_0x4dd9fb[_0x503f8b(0x188)][_0x503f8b(0x181)]()['length']===0x57a+0xf68+-0x14e2),_0x3fff04=_0x1f93e9?'⚠️':statusIcon(_0x4dd9fb[_0x503f8b(0x14d)]),_0x36acb=_0x1f93e9?'completed\x20'+_0x503f8b(0x163)+'tput':_0x4dd9fb['status'],_0x42433c=formatDuration(_0x4dd9fb[_0x503f8b(0x16e)]),_0x4abd2d=formatTokens(_0x4dd9fb[_0x503f8b(0x190)][_0x503f8b(0x165)]),_0x48585c=formatTokens(_0x4dd9fb['tokensUsed'][_0x2407da(0x188)]);return _0x3fff04+'\x20'+_0x42f606[_0x2407da(0x198)]+'\x20—\x20'+_0x36acb+_0x503f8b(0x159)+_0x42433c+_0x2407da(0x159)+_0x4abd2d+_0x2407da(0x147)+_0x48585c+'\x20out';}