@openacp/cli 0.6.9 → 2026.326.2

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 (258) hide show
  1. package/README.md +100 -154
  2. package/dist/{action-detect-P7ZE4NEM.js → action-detect-QPA775HB.js} +2 -2
  3. package/dist/adapter-6ANPBSVU.js +16 -0
  4. package/dist/{discord-7IVQKB2H.js → adapter-77ZCVABT.js} +659 -348
  5. package/dist/adapter-77ZCVABT.js.map +1 -0
  6. package/dist/{adapter-LNEGLMOE.js → adapter-PQGHVG4K.js} +300 -93
  7. package/dist/adapter-PQGHVG4K.js.map +1 -0
  8. package/dist/{admin-6SYB6XCZ.js → admin-GBPZFFAU.js} +3 -3
  9. package/dist/agent-catalog-YHBFERYO.js +11 -0
  10. package/dist/{agent-dependencies-4OWBMZWZ.js → agent-dependencies-WS7Z2DFW.js} +2 -2
  11. package/dist/agent-registry-5LZT7CUB.js +9 -0
  12. package/dist/agent-store-VSHNY5GT.js +9 -0
  13. package/dist/{agents-QO7DKARJ.js → agents-BWU4MRRD.js} +3 -3
  14. package/dist/{api-client-CFQT5U7D.js → api-client-AQPNKXI2.js} +2 -2
  15. package/dist/api-server-3PYLRBCN.js +8 -0
  16. package/dist/api-server-CHVSUDBX.js +11 -0
  17. package/dist/{autostart-X33OGMX6.js → autostart-6JS565RY.js} +3 -3
  18. package/dist/chunk-2CX4IEEC.js +124 -0
  19. package/dist/chunk-2CX4IEEC.js.map +1 -0
  20. package/dist/{chunk-O7CPGUAI.js → chunk-4KGLKKQK.js} +4 -4
  21. package/dist/chunk-4KGLKKQK.js.map +1 -0
  22. package/dist/{chunk-W3EYKZNQ.js → chunk-4WXALZA3.js} +2 -2
  23. package/dist/chunk-4WXALZA3.js.map +1 -0
  24. package/dist/chunk-5OCGO27U.js +125 -0
  25. package/dist/chunk-5OCGO27U.js.map +1 -0
  26. package/dist/{chunk-JUYDFUSN.js → chunk-5ZOFBTOR.js} +117 -237
  27. package/dist/chunk-5ZOFBTOR.js.map +1 -0
  28. package/dist/chunk-6RXVEXF3.js +23 -0
  29. package/dist/chunk-6RXVEXF3.js.map +1 -0
  30. package/dist/{chunk-34M4OS5P.js → chunk-A6Y4GZM3.js} +3 -3
  31. package/dist/chunk-A6Y4GZM3.js.map +1 -0
  32. package/dist/chunk-AD3X6DGK.js +166 -0
  33. package/dist/chunk-AD3X6DGK.js.map +1 -0
  34. package/dist/{chunk-7QJS2XBD.js → chunk-AFKX424Q.js} +2 -2
  35. package/dist/chunk-AFKX424Q.js.map +1 -0
  36. package/dist/chunk-APS6UEFU.js +259 -0
  37. package/dist/chunk-APS6UEFU.js.map +1 -0
  38. package/dist/chunk-BLQUXO7S.js +113 -0
  39. package/dist/chunk-BLQUXO7S.js.map +1 -0
  40. package/dist/{chunk-WTZDAYZX.js → chunk-BQ6FR32N.js} +3 -3
  41. package/dist/chunk-BQ6FR32N.js.map +1 -0
  42. package/dist/chunk-FNRSWA2K.js +1 -0
  43. package/dist/chunk-FQEBWOZR.js +3557 -0
  44. package/dist/chunk-FQEBWOZR.js.map +1 -0
  45. package/dist/{chunk-4CTX774K.js → chunk-GJOY37U7.js} +4 -4
  46. package/dist/chunk-GJOY37U7.js.map +1 -0
  47. package/dist/{chunk-I7WC6E5S.js → chunk-HVBNCPAY.js} +2 -2
  48. package/dist/chunk-HVBNCPAY.js.map +1 -0
  49. package/dist/{chunk-2HMQOC7N.js → chunk-I3CGU5W7.js} +4 -4
  50. package/dist/chunk-I3CGU5W7.js.map +1 -0
  51. package/dist/{chunk-NVPG6JCL.js → chunk-L7YNNBI5.js} +3 -3
  52. package/dist/chunk-L7YNNBI5.js.map +1 -0
  53. package/dist/chunk-LGFWH3AE.js +26 -0
  54. package/dist/chunk-LGFWH3AE.js.map +1 -0
  55. package/dist/chunk-MLF4W5R6.js +101 -0
  56. package/dist/chunk-MLF4W5R6.js.map +1 -0
  57. package/dist/{chunk-KIRH7TUJ.js → chunk-MTSDOSXS.js} +3 -3
  58. package/dist/chunk-MTSDOSXS.js.map +1 -0
  59. package/dist/{chunk-J4SJTKIK.js → chunk-NAM4ERUW.js} +3 -3
  60. package/dist/chunk-NAM4ERUW.js.map +1 -0
  61. package/dist/{chunk-BN3X7UXB.js → chunk-NBFIBGAT.js} +39 -25
  62. package/dist/chunk-NBFIBGAT.js.map +1 -0
  63. package/dist/{chunk-BNLGTZ34.js → chunk-O5RG4YZY.js} +3 -3
  64. package/dist/chunk-O5RG4YZY.js.map +1 -0
  65. package/dist/{chunk-JHYXKVV2.js → chunk-ODUM3D6X.js} +2 -2
  66. package/dist/chunk-ODUM3D6X.js.map +1 -0
  67. package/dist/chunk-OYSAN7UX.js +15 -0
  68. package/dist/chunk-OYSAN7UX.js.map +1 -0
  69. package/dist/chunk-P4SNGQNI.js +158 -0
  70. package/dist/chunk-P4SNGQNI.js.map +1 -0
  71. package/dist/{chunk-2CJ46J3C.js → chunk-PPSMUECX.js} +3 -3
  72. package/dist/chunk-PPSMUECX.js.map +1 -0
  73. package/dist/chunk-Q6ZXJTZB.js +56 -0
  74. package/dist/chunk-Q6ZXJTZB.js.map +1 -0
  75. package/dist/{chunk-XANPHG7W.js → chunk-QSDZDHNS.js} +7 -7
  76. package/dist/chunk-QSDZDHNS.js.map +1 -0
  77. package/dist/{chunk-33RP6K2O.js → chunk-QVMEF6FB.js} +6 -6
  78. package/dist/chunk-QVMEF6FB.js.map +1 -0
  79. package/dist/chunk-QWP76EBW.js +536 -0
  80. package/dist/chunk-QWP76EBW.js.map +1 -0
  81. package/dist/{chunk-V5GZQEIY.js → chunk-RBYBSSGO.js} +4 -4
  82. package/dist/chunk-RBYBSSGO.js.map +1 -0
  83. package/dist/{chunk-H5P2C6H4.js → chunk-RKB2ZK6S.js} +628 -408
  84. package/dist/chunk-RKB2ZK6S.js.map +1 -0
  85. package/dist/{chunk-UKT3G5IA.js → chunk-SHTGQGAU.js} +7 -7
  86. package/dist/chunk-SHTGQGAU.js.map +1 -0
  87. package/dist/chunk-SNPYTMPR.js +51 -0
  88. package/dist/chunk-SNPYTMPR.js.map +1 -0
  89. package/dist/chunk-UB2QB6DE.js +124 -0
  90. package/dist/chunk-UB2QB6DE.js.map +1 -0
  91. package/dist/chunk-UNJUWWQO.js +1108 -0
  92. package/dist/chunk-UNJUWWQO.js.map +1 -0
  93. package/dist/chunk-V2M243KZ.js +445 -0
  94. package/dist/chunk-V2M243KZ.js.map +1 -0
  95. package/dist/chunk-V5JT5TPD.js +97 -0
  96. package/dist/chunk-V5JT5TPD.js.map +1 -0
  97. package/dist/chunk-W26AUH5B.js +61 -0
  98. package/dist/chunk-W26AUH5B.js.map +1 -0
  99. package/dist/chunk-WAAD23KY.js +222 -0
  100. package/dist/chunk-WAAD23KY.js.map +1 -0
  101. package/dist/chunk-WIIZNPCR.js +150 -0
  102. package/dist/chunk-WIIZNPCR.js.map +1 -0
  103. package/dist/chunk-WQCJTU2C.js +84 -0
  104. package/dist/chunk-WQCJTU2C.js.map +1 -0
  105. package/dist/chunk-WVLDNYOJ.js +150 -0
  106. package/dist/chunk-WVLDNYOJ.js.map +1 -0
  107. package/dist/chunk-WXVT3AOY.js +22 -0
  108. package/dist/chunk-WXVT3AOY.js.map +1 -0
  109. package/dist/{chunk-GAK6PIBW.js → chunk-XMMAGAT4.js} +2 -2
  110. package/dist/chunk-XMMAGAT4.js.map +1 -0
  111. package/dist/chunk-Y64XWMJ4.js +212 -0
  112. package/dist/chunk-Y64XWMJ4.js.map +1 -0
  113. package/dist/chunk-YEULD3SG.js +62 -0
  114. package/dist/chunk-YEULD3SG.js.map +1 -0
  115. package/dist/chunk-ZHGPZBS4.js +49 -0
  116. package/dist/chunk-ZHGPZBS4.js.map +1 -0
  117. package/dist/{chunk-JKBFUAJK.js → chunk-ZSLHHQPQ.js} +2 -2
  118. package/dist/chunk-ZSLHHQPQ.js.map +1 -0
  119. package/dist/cli.js +501 -150
  120. package/dist/cli.js.map +1 -1
  121. package/dist/{config-6S355X75.js → config-I4FMCJGZ.js} +3 -3
  122. package/dist/config-editor-HNEKXRLQ.js +11 -0
  123. package/dist/{config-registry-AHYI4MYL.js → config-registry-CUMNXFGK.js} +2 -2
  124. package/dist/context-XM6E22LM.js +10 -0
  125. package/dist/core-plugins-VEUNFTMB.js +27 -0
  126. package/dist/{daemon-4CS6HMB5.js → daemon-PXO5QPCR.js} +4 -4
  127. package/dist/dev-loader-RDC5E2CW.js +50 -0
  128. package/dist/dev-loader-RDC5E2CW.js.map +1 -0
  129. package/dist/discord-NOJQ5PZO.js +8 -0
  130. package/dist/doctor-H72BZOPA.js +10 -0
  131. package/dist/{doctor-OLYBO3V3.js → doctor-RF6BHMCC.js} +5 -5
  132. package/dist/file-service-EUODJAIT.js +9 -0
  133. package/dist/file-service-EUODJAIT.js.map +1 -0
  134. package/dist/index.d.ts +1293 -188
  135. package/dist/index.js +387 -48
  136. package/dist/index.js.map +1 -1
  137. package/dist/{install-cloudflared-Z7VCGOVG.js → install-cloudflared-AN24L4DP.js} +5 -5
  138. package/dist/install-cloudflared-AN24L4DP.js.map +1 -0
  139. package/dist/install-context-XPWTFT3J.js +78 -0
  140. package/dist/install-context-XPWTFT3J.js.map +1 -0
  141. package/dist/{install-jq-HUYSQWKR.js → install-jq-CRVDJGF3.js} +5 -5
  142. package/dist/install-jq-CRVDJGF3.js.map +1 -0
  143. package/dist/{integrate-PNEHRY2I.js → integrate-5C6KSU6D.js} +2 -2
  144. package/dist/integrate-5C6KSU6D.js.map +1 -0
  145. package/dist/{log-NXABYJTT.js → log-LZ7FTRKG.js} +2 -2
  146. package/dist/log-LZ7FTRKG.js.map +1 -0
  147. package/dist/main-T5WVCCFN.js +715 -0
  148. package/dist/main-T5WVCCFN.js.map +1 -0
  149. package/dist/{menu-YY5MKHEK.js → menu-YDQ2LWAR.js} +2 -2
  150. package/dist/menu-YDQ2LWAR.js.map +1 -0
  151. package/dist/{new-session-FEO4J4VU.js → new-session-AVQCNXRG.js} +5 -5
  152. package/dist/new-session-AVQCNXRG.js.map +1 -0
  153. package/dist/notifications-D5BRDNSU.js +9 -0
  154. package/dist/notifications-D5BRDNSU.js.map +1 -0
  155. package/dist/plugin-create-JVCVUG6V.js +331 -0
  156. package/dist/plugin-create-JVCVUG6V.js.map +1 -0
  157. package/dist/plugin-registry-WB3DR67H.js +8 -0
  158. package/dist/plugin-registry-WB3DR67H.js.map +1 -0
  159. package/dist/{post-upgrade-CJG5I7M2.js → post-upgrade-XLHZ6ZB7.js} +8 -8
  160. package/dist/post-upgrade-XLHZ6ZB7.js.map +1 -0
  161. package/dist/read-text-file-IRZM3QLM.js +8 -0
  162. package/dist/read-text-file-IRZM3QLM.js.map +1 -0
  163. package/dist/security-YNRBW6S7.js +9 -0
  164. package/dist/security-YNRBW6S7.js.map +1 -0
  165. package/dist/{session-IUSI7P5S.js → session-KZFA6Z26.js} +4 -4
  166. package/dist/session-KZFA6Z26.js.map +1 -0
  167. package/dist/{settings-RQPAM4KC.js → settings-MFYM7CZO.js} +4 -4
  168. package/dist/settings-MFYM7CZO.js.map +1 -0
  169. package/dist/settings-manager-MD2U4ZV2.js +8 -0
  170. package/dist/settings-manager-MD2U4ZV2.js.map +1 -0
  171. package/dist/setup-BAI2F24H.js +747 -0
  172. package/dist/setup-BAI2F24H.js.map +1 -0
  173. package/dist/slack-KH7E3VBS.js +8 -0
  174. package/dist/slack-KH7E3VBS.js.map +1 -0
  175. package/dist/speech-2GHQNRIO.js +9 -0
  176. package/dist/speech-2GHQNRIO.js.map +1 -0
  177. package/dist/telegram-ZDC3JQF2.js +8 -0
  178. package/dist/telegram-ZDC3JQF2.js.map +1 -0
  179. package/dist/tunnel-M47I7H4B.js +8 -0
  180. package/dist/tunnel-M47I7H4B.js.map +1 -0
  181. package/dist/{tunnel-service-CJLUH6SZ.js → tunnel-service-WADYHREX.js} +17 -17
  182. package/dist/tunnel-service-WADYHREX.js.map +1 -0
  183. package/dist/usage-WYNK6ZC5.js +10 -0
  184. package/dist/usage-WYNK6ZC5.js.map +1 -0
  185. package/dist/validators-6CLEZUBD.js +8 -0
  186. package/dist/validators-6CLEZUBD.js.map +1 -0
  187. package/dist/validators-WSTBNKRW.js +12 -0
  188. package/dist/validators-WSTBNKRW.js.map +1 -0
  189. package/package.json +1 -1
  190. package/dist/adapter-LNEGLMOE.js.map +0 -1
  191. package/dist/agent-catalog-FC3HGDEQ.js +0 -11
  192. package/dist/agent-registry-WT4NXPYG.js +0 -9
  193. package/dist/agent-store-VZLFPTZU.js +0 -9
  194. package/dist/chunk-2CJ46J3C.js.map +0 -1
  195. package/dist/chunk-2HMQOC7N.js.map +0 -1
  196. package/dist/chunk-33RP6K2O.js.map +0 -1
  197. package/dist/chunk-34M4OS5P.js.map +0 -1
  198. package/dist/chunk-4CTX774K.js.map +0 -1
  199. package/dist/chunk-7QJS2XBD.js.map +0 -1
  200. package/dist/chunk-BDYVCIBH.js +0 -735
  201. package/dist/chunk-BDYVCIBH.js.map +0 -1
  202. package/dist/chunk-BN3X7UXB.js.map +0 -1
  203. package/dist/chunk-BNLGTZ34.js.map +0 -1
  204. package/dist/chunk-GAK6PIBW.js.map +0 -1
  205. package/dist/chunk-H5P2C6H4.js.map +0 -1
  206. package/dist/chunk-I7WC6E5S.js.map +0 -1
  207. package/dist/chunk-J4SJTKIK.js.map +0 -1
  208. package/dist/chunk-JHYXKVV2.js.map +0 -1
  209. package/dist/chunk-JKBFUAJK.js.map +0 -1
  210. package/dist/chunk-JUYDFUSN.js.map +0 -1
  211. package/dist/chunk-KIRH7TUJ.js.map +0 -1
  212. package/dist/chunk-LBIKITQT.js +0 -22
  213. package/dist/chunk-LBIKITQT.js.map +0 -1
  214. package/dist/chunk-LGP2YGRL.js +0 -4880
  215. package/dist/chunk-LGP2YGRL.js.map +0 -1
  216. package/dist/chunk-NAMYZIS5.js +0 -1
  217. package/dist/chunk-NVPG6JCL.js.map +0 -1
  218. package/dist/chunk-O7CPGUAI.js.map +0 -1
  219. package/dist/chunk-UKT3G5IA.js.map +0 -1
  220. package/dist/chunk-V5GZQEIY.js.map +0 -1
  221. package/dist/chunk-VOIJ6OY4.js +0 -63
  222. package/dist/chunk-VOIJ6OY4.js.map +0 -1
  223. package/dist/chunk-W3EYKZNQ.js.map +0 -1
  224. package/dist/chunk-WTZDAYZX.js.map +0 -1
  225. package/dist/chunk-XANPHG7W.js.map +0 -1
  226. package/dist/config-editor-RVLWZLVB.js +0 -13
  227. package/dist/discord-7IVQKB2H.js.map +0 -1
  228. package/dist/doctor-HZZ5BSHB.js +0 -10
  229. package/dist/install-cloudflared-Z7VCGOVG.js.map +0 -1
  230. package/dist/install-jq-HUYSQWKR.js.map +0 -1
  231. package/dist/integrate-PNEHRY2I.js.map +0 -1
  232. package/dist/main-ZK4MPMBG.js +0 -238
  233. package/dist/main-ZK4MPMBG.js.map +0 -1
  234. package/dist/post-upgrade-CJG5I7M2.js.map +0 -1
  235. package/dist/setup-3GQSYBE4.js +0 -35
  236. package/dist/tunnel-service-CJLUH6SZ.js.map +0 -1
  237. /package/dist/{action-detect-P7ZE4NEM.js.map → action-detect-QPA775HB.js.map} +0 -0
  238. /package/dist/{admin-6SYB6XCZ.js.map → adapter-6ANPBSVU.js.map} +0 -0
  239. /package/dist/{agent-catalog-FC3HGDEQ.js.map → admin-GBPZFFAU.js.map} +0 -0
  240. /package/dist/{agent-dependencies-4OWBMZWZ.js.map → agent-catalog-YHBFERYO.js.map} +0 -0
  241. /package/dist/{agent-registry-WT4NXPYG.js.map → agent-dependencies-WS7Z2DFW.js.map} +0 -0
  242. /package/dist/{agent-store-VZLFPTZU.js.map → agent-registry-5LZT7CUB.js.map} +0 -0
  243. /package/dist/{agents-QO7DKARJ.js.map → agent-store-VSHNY5GT.js.map} +0 -0
  244. /package/dist/{api-client-CFQT5U7D.js.map → agents-BWU4MRRD.js.map} +0 -0
  245. /package/dist/{autostart-X33OGMX6.js.map → api-client-AQPNKXI2.js.map} +0 -0
  246. /package/dist/{chunk-NAMYZIS5.js.map → api-server-3PYLRBCN.js.map} +0 -0
  247. /package/dist/{config-6S355X75.js.map → api-server-CHVSUDBX.js.map} +0 -0
  248. /package/dist/{config-editor-RVLWZLVB.js.map → autostart-6JS565RY.js.map} +0 -0
  249. /package/dist/{config-registry-AHYI4MYL.js.map → chunk-FNRSWA2K.js.map} +0 -0
  250. /package/dist/{daemon-4CS6HMB5.js.map → config-I4FMCJGZ.js.map} +0 -0
  251. /package/dist/{doctor-HZZ5BSHB.js.map → config-editor-HNEKXRLQ.js.map} +0 -0
  252. /package/dist/{doctor-OLYBO3V3.js.map → config-registry-CUMNXFGK.js.map} +0 -0
  253. /package/dist/{log-NXABYJTT.js.map → context-XM6E22LM.js.map} +0 -0
  254. /package/dist/{menu-YY5MKHEK.js.map → core-plugins-VEUNFTMB.js.map} +0 -0
  255. /package/dist/{new-session-FEO4J4VU.js.map → daemon-PXO5QPCR.js.map} +0 -0
  256. /package/dist/{session-IUSI7P5S.js.map → discord-NOJQ5PZO.js.map} +0 -0
  257. /package/dist/{settings-RQPAM4KC.js.map → doctor-H72BZOPA.js.map} +0 -0
  258. /package/dist/{setup-3GQSYBE4.js.map → doctor-RF6BHMCC.js.map} +0 -0
@@ -1,48 +1,49 @@
1
1
  import {
2
2
  PRODUCT_GUIDE,
3
- STATUS_ICONS,
4
- dispatchMessage,
5
- evaluateNoise,
3
+ SendQueue,
4
+ ToolCallTracker
5
+ } from "./chunk-5ZOFBTOR.js";
6
+ import {
7
+ BaseRenderer,
8
+ MessagingAdapter,
6
9
  extractContentText,
7
10
  formatTokens,
8
11
  formatToolSummary,
9
12
  formatToolTitle,
10
13
  progressBar,
14
+ resolveToolIcon,
11
15
  splitMessage,
12
16
  stripCodeFences,
13
17
  truncateContent
14
- } from "./chunk-JUYDFUSN.js";
15
- import {
16
- CheckpointReader,
17
- DEFAULT_MAX_TOKENS
18
- } from "./chunk-LGP2YGRL.js";
19
- import {
20
- ChannelAdapter
21
- } from "./chunk-LBIKITQT.js";
22
- import {
23
- DoctorEngine
24
- } from "./chunk-NVPG6JCL.js";
18
+ } from "./chunk-V2M243KZ.js";
25
19
  import {
26
20
  buildMenuKeyboard,
27
21
  buildSkillMessages,
28
22
  handleClear,
29
23
  handleHelp,
30
24
  handleMenu
31
- } from "./chunk-7QJS2XBD.js";
25
+ } from "./chunk-AFKX424Q.js";
26
+ import {
27
+ DoctorEngine
28
+ } from "./chunk-L7YNNBI5.js";
29
+ import {
30
+ CheckpointReader,
31
+ DEFAULT_MAX_TOKENS
32
+ } from "./chunk-APS6UEFU.js";
32
33
  import {
33
34
  getConfigValue,
34
35
  getSafeFields,
35
36
  isHotReloadable,
36
37
  resolveOptions
37
- } from "./chunk-JHYXKVV2.js";
38
+ } from "./chunk-ODUM3D6X.js";
38
39
  import {
39
40
  createChildLogger
40
- } from "./chunk-GAK6PIBW.js";
41
+ } from "./chunk-XMMAGAT4.js";
41
42
 
42
- // src/adapters/telegram/adapter.ts
43
+ // src/plugins/telegram/adapter.ts
43
44
  import { Bot, InputFile } from "grammy";
44
45
 
45
- // src/adapters/telegram/topics.ts
46
+ // src/plugins/telegram/topics.ts
46
47
  async function ensureTopics(bot, chatId, config, saveConfig) {
47
48
  let notificationTopicId = config.notificationTopicId;
48
49
  let assistantTopicId = config.assistantTopicId;
@@ -79,10 +80,10 @@ function buildDeepLink(chatId, threadId, messageId) {
79
80
  return `https://t.me/c/${cleanId}/${threadId}`;
80
81
  }
81
82
 
82
- // src/adapters/telegram/commands/new-session.ts
83
+ // src/plugins/telegram/commands/new-session.ts
83
84
  import { InlineKeyboard as InlineKeyboard2 } from "grammy";
84
85
 
85
- // src/adapters/telegram/formatting.ts
86
+ // src/plugins/telegram/formatting.ts
86
87
  function escapeHtml(text) {
87
88
  if (!text) return "";
88
89
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -118,33 +119,43 @@ function markdownToTelegramHtml(md) {
118
119
  return text;
119
120
  }
120
121
  function formatToolCall(tool, verbosity = "medium") {
121
- const si = STATUS_ICONS[tool.status || ""] || "\u{1F527}";
122
+ const si = resolveToolIcon(tool);
122
123
  const name = tool.name || "Tool";
123
- const label = verbosity === "low" ? formatToolTitle(name, tool.rawInput) : formatToolSummary(name, tool.rawInput);
124
+ const label = verbosity === "low" ? formatToolTitle(name, tool.rawInput, tool.displayTitle) : formatToolSummary(name, tool.rawInput, tool.displaySummary);
124
125
  let text = `${si} <b>${escapeHtml(label)}</b>`;
125
126
  text += formatViewerLinks(tool.viewerLinks, tool.viewerFilePath);
126
- if (verbosity === "high" || verbosity === "medium" && !tool.viewerLinks) {
127
- const details = stripCodeFences(extractContentText(tool.content));
128
- if (details) {
129
- text += `
130
- <pre>${escapeHtml(truncateContent(details, 3800))}</pre>`;
131
- }
127
+ if (verbosity === "high") {
128
+ text += formatHighDetails(tool.rawInput, tool.content, 3800);
132
129
  }
133
130
  return text;
134
131
  }
135
132
  function formatToolUpdate(update, verbosity = "medium") {
136
- const si = STATUS_ICONS[update.status] || "\u{1F527}";
133
+ const si = resolveToolIcon(update);
137
134
  const name = update.name || "Tool";
138
- const label = verbosity === "low" ? formatToolTitle(name, update.rawInput) : formatToolSummary(name, update.rawInput);
135
+ const label = verbosity === "low" ? formatToolTitle(name, update.rawInput, update.displayTitle) : formatToolSummary(name, update.rawInput, update.displaySummary);
139
136
  let text = `${si} <b>${escapeHtml(label)}</b>`;
140
137
  text += formatViewerLinks(update.viewerLinks, update.viewerFilePath);
141
- if (verbosity === "high" || verbosity === "medium" && !update.viewerLinks) {
142
- const details = stripCodeFences(extractContentText(update.content));
143
- if (details) {
138
+ if (verbosity === "high") {
139
+ text += formatHighDetails(update.rawInput, update.content, 3800);
140
+ }
141
+ return text;
142
+ }
143
+ function formatHighDetails(rawInput, content, maxLen) {
144
+ let text = "";
145
+ if (rawInput) {
146
+ const inputStr = typeof rawInput === "string" ? rawInput : JSON.stringify(rawInput, null, 2);
147
+ if (inputStr && inputStr !== "{}") {
144
148
  text += `
145
- <pre>${escapeHtml(truncateContent(details, 3800))}</pre>`;
149
+ <b>Input:</b>
150
+ <pre>${escapeHtml(truncateContent(inputStr, maxLen))}</pre>`;
146
151
  }
147
152
  }
153
+ const details = stripCodeFences(extractContentText(content));
154
+ if (details) {
155
+ text += `
156
+ <b>Output:</b>
157
+ <pre>${escapeHtml(truncateContent(details, maxLen))}</pre>`;
158
+ }
148
159
  return text;
149
160
  }
150
161
  function formatViewerLinks(links, filePath) {
@@ -159,16 +170,40 @@ function formatViewerLinks(links, filePath) {
159
170
  \u{1F4DD} <a href="${escapeHtml(links.diff)}">View diff${fileName ? ` \u2014 ${escapeHtml(fileName)}` : ""}</a>`;
160
171
  return text;
161
172
  }
162
- function formatUsage(usage) {
163
- const { tokensUsed, contextSize } = usage;
173
+ function formatPlan(plan, verbosity = "medium") {
174
+ const { entries } = plan;
175
+ if (verbosity === "medium") {
176
+ const done = entries.filter((e) => e.status === "completed").length;
177
+ return `\u{1F4CB} <b>Plan:</b> ${done}/${entries.length} steps completed`;
178
+ }
179
+ const statusIcon = {
180
+ pending: "\u2B1C",
181
+ in_progress: "\u{1F504}",
182
+ completed: "\u2705"
183
+ };
184
+ const lines = entries.map(
185
+ (e, i) => `${statusIcon[e.status] || "\u2B1C"} ${i + 1}. ${escapeHtml(e.content)}`
186
+ );
187
+ return `<b>Plan:</b>
188
+ ${lines.join("\n")}`;
189
+ }
190
+ function formatUsage(usage, verbosity = "medium") {
191
+ const { tokensUsed, contextSize, cost } = usage;
164
192
  if (tokensUsed == null) return "\u{1F4CA} Usage data unavailable";
193
+ if (verbosity === "medium") {
194
+ const costStr = cost != null ? ` \xB7 $${cost.toFixed(2)}` : "";
195
+ return `\u{1F4CA} ${formatTokens(tokensUsed)} tokens${costStr}`;
196
+ }
165
197
  if (contextSize == null) return `\u{1F4CA} ${formatTokens(tokensUsed)} tokens`;
166
198
  const ratio = tokensUsed / contextSize;
167
199
  const pct = Math.round(ratio * 100);
168
200
  const bar = progressBar(ratio);
169
201
  const emoji = pct >= 85 ? "\u26A0\uFE0F" : "\u{1F4CA}";
170
- return `${emoji} ${formatTokens(tokensUsed)} / ${formatTokens(contextSize)} tokens
202
+ let text = `${emoji} ${formatTokens(tokensUsed)} / ${formatTokens(contextSize)} tokens
171
203
  ${bar} ${pct}%`;
204
+ if (cost != null) text += `
205
+ \u{1F4B0} $${cost.toFixed(2)}`;
206
+ return text;
172
207
  }
173
208
  var PERIOD_LABEL = {
174
209
  today: "Today",
@@ -211,7 +246,7 @@ function splitMessage2(text, maxLength = 3800) {
211
246
  return splitMessage(text, maxLength);
212
247
  }
213
248
 
214
- // src/adapters/telegram/commands/admin.ts
249
+ // src/plugins/telegram/commands/admin.ts
215
250
  import { InlineKeyboard } from "grammy";
216
251
  var log = createChildLogger({ module: "telegram-cmd-admin" });
217
252
  function setupDangerousModeCallbacks(bot, core) {
@@ -569,7 +604,7 @@ async function handleRestart(ctx, core) {
569
604
  await core.requestRestart();
570
605
  }
571
606
 
572
- // src/adapters/telegram/commands/new-session.ts
607
+ // src/plugins/telegram/commands/new-session.ts
573
608
  var log2 = createChildLogger({ module: "telegram-cmd-new-session" });
574
609
  var pendingNewSessions = /* @__PURE__ */ new Map();
575
610
  var PENDING_TIMEOUT_MS = 5 * 60 * 1e3;
@@ -957,7 +992,7 @@ Or just the folder name like <code>my-project</code> (will use ${core.configMana
957
992
  });
958
993
  }
959
994
 
960
- // src/adapters/telegram/commands/session.ts
995
+ // src/plugins/telegram/commands/session.ts
961
996
  import { InlineKeyboard as InlineKeyboard3 } from "grammy";
962
997
  var log3 = createChildLogger({ module: "telegram-cmd-session" });
963
998
  async function handleCancel(ctx, core, assistant) {
@@ -1382,7 +1417,7 @@ async function handleSummaryCallback(ctx, core, chatId) {
1382
1417
  }
1383
1418
  }
1384
1419
 
1385
- // src/adapters/telegram/commands/agents.ts
1420
+ // src/plugins/telegram/commands/agents.ts
1386
1421
  import { InlineKeyboard as InlineKeyboard4 } from "grammy";
1387
1422
  var AGENTS_PER_PAGE = 6;
1388
1423
  async function handleAgents(ctx, core, page = 0) {
@@ -1581,10 +1616,10 @@ Downloading... ${bar} ${percent}%`, { parse_mode: "HTML" });
1581
1616
  };
1582
1617
  const result = await catalog.install(nameOrId, progress);
1583
1618
  if (result.ok) {
1584
- const { getAgentCapabilities } = await import("./agent-dependencies-4OWBMZWZ.js");
1619
+ const { getAgentCapabilities } = await import("./agent-dependencies-WS7Z2DFW.js");
1585
1620
  const caps = getAgentCapabilities(result.agentKey);
1586
1621
  if (caps.integration) {
1587
- const { installIntegration } = await import("./integrate-PNEHRY2I.js");
1622
+ const { installIntegration } = await import("./integrate-5C6KSU6D.js");
1588
1623
  const intResult = await installIntegration(result.agentKey, caps.integration);
1589
1624
  if (intResult.success) {
1590
1625
  try {
@@ -1651,10 +1686,10 @@ function buildProgressBar(percent) {
1651
1686
  return "\u2588".repeat(filled) + "\u2591".repeat(empty);
1652
1687
  }
1653
1688
 
1654
- // src/adapters/telegram/commands/integrate.ts
1689
+ // src/plugins/telegram/commands/integrate.ts
1655
1690
  import { InlineKeyboard as InlineKeyboard5 } from "grammy";
1656
1691
  async function handleIntegrate(ctx, _core) {
1657
- const { listIntegrations } = await import("./integrate-PNEHRY2I.js");
1692
+ const { listIntegrations } = await import("./integrate-5C6KSU6D.js");
1658
1693
  const agents = listIntegrations();
1659
1694
  const keyboard = new InlineKeyboard5();
1660
1695
  for (const agent of agents) {
@@ -1687,7 +1722,7 @@ function setupIntegrateCallbacks(bot, core) {
1687
1722
  } catch {
1688
1723
  }
1689
1724
  if (data === "i:back") {
1690
- const { listIntegrations } = await import("./integrate-PNEHRY2I.js");
1725
+ const { listIntegrations } = await import("./integrate-5C6KSU6D.js");
1691
1726
  const agents = listIntegrations();
1692
1727
  const keyboard2 = new InlineKeyboard5();
1693
1728
  for (const agent of agents) {
@@ -1707,7 +1742,7 @@ Select an agent to manage its integrations.`,
1707
1742
  const agentMatch = data.match(/^i:agent:(.+)$/);
1708
1743
  if (agentMatch) {
1709
1744
  const agentName2 = agentMatch[1];
1710
- const { getIntegration: getIntegration2 } = await import("./integrate-PNEHRY2I.js");
1745
+ const { getIntegration: getIntegration2 } = await import("./integrate-5C6KSU6D.js");
1711
1746
  const integration2 = getIntegration2(agentName2);
1712
1747
  if (!integration2) {
1713
1748
  await ctx.reply(`\u274C No integration available for '${escapeHtml(agentName2)}'.`, { parse_mode: "HTML" });
@@ -1734,7 +1769,7 @@ ${integration2.items.map((i) => `\u2022 <b>${escapeHtml(i.name)}</b> \u2014 ${es
1734
1769
  const action = actionMatch[1];
1735
1770
  const agentName = actionMatch[2];
1736
1771
  const itemId = actionMatch[3];
1737
- const { getIntegration } = await import("./integrate-PNEHRY2I.js");
1772
+ const { getIntegration } = await import("./integrate-5C6KSU6D.js");
1738
1773
  const integration = getIntegration(agentName);
1739
1774
  if (!integration) return;
1740
1775
  const item = integration.items.find((i) => i.id === itemId);
@@ -1769,7 +1804,7 @@ ${resultText}`,
1769
1804
  });
1770
1805
  }
1771
1806
 
1772
- // src/adapters/telegram/commands/resume.ts
1807
+ // src/plugins/telegram/commands/resume.ts
1773
1808
  import * as fs from "fs";
1774
1809
  import * as path from "path";
1775
1810
  import * as os from "os";
@@ -2046,7 +2081,7 @@ Or just the folder name (will use workspace baseDir)`,
2046
2081
  });
2047
2082
  }
2048
2083
 
2049
- // src/adapters/telegram/commands/settings.ts
2084
+ // src/plugins/telegram/commands/settings.ts
2050
2085
  import { InlineKeyboard as InlineKeyboard7 } from "grammy";
2051
2086
  var log5 = createChildLogger({ module: "telegram-settings" });
2052
2087
  function buildSettingsKeyboard(core) {
@@ -2218,7 +2253,7 @@ Tap to change:`, {
2218
2253
  await ctx.answerCallbackQuery();
2219
2254
  } catch {
2220
2255
  }
2221
- const { buildMenuKeyboard: buildMenuKeyboard3 } = await import("./menu-YY5MKHEK.js");
2256
+ const { buildMenuKeyboard: buildMenuKeyboard3 } = await import("./menu-YDQ2LWAR.js");
2222
2257
  try {
2223
2258
  await ctx.editMessageText(`<b>OpenACP Menu</b>
2224
2259
  Choose an action:`, {
@@ -2255,7 +2290,7 @@ function buildNestedUpdate(dotPath, value) {
2255
2290
  return result;
2256
2291
  }
2257
2292
 
2258
- // src/adapters/telegram/commands/doctor.ts
2293
+ // src/plugins/telegram/commands/doctor.ts
2259
2294
  import { InlineKeyboard as InlineKeyboard8 } from "grammy";
2260
2295
  var log6 = createChildLogger({ module: "telegram-cmd-doctor" });
2261
2296
  var pendingFixesStore = /* @__PURE__ */ new Map();
@@ -2361,7 +2396,7 @@ function setupDoctorCallbacks(bot) {
2361
2396
  });
2362
2397
  }
2363
2398
 
2364
- // src/adapters/telegram/commands/tunnel.ts
2399
+ // src/plugins/telegram/commands/tunnel.ts
2365
2400
  import { InlineKeyboard as InlineKeyboard9 } from "grammy";
2366
2401
  var log7 = createChildLogger({ module: "telegram-cmd-tunnel" });
2367
2402
  async function handleTunnel(ctx, core) {
@@ -2517,7 +2552,7 @@ function setupTunnelCallbacks(bot, core) {
2517
2552
  });
2518
2553
  }
2519
2554
 
2520
- // src/adapters/telegram/commands/index.ts
2555
+ // src/plugins/telegram/commands/index.ts
2521
2556
  function setupCommands(bot, core, chatId, assistant) {
2522
2557
  bot.command("new", (ctx) => handleNew(ctx, core, chatId, assistant));
2523
2558
  bot.command("newchat", (ctx) => handleNewChat(ctx, core, chatId));
@@ -2636,7 +2671,7 @@ var STATIC_COMMANDS = [
2636
2671
  { command: "resume", description: "Resume with conversation history from Entire checkpoints" }
2637
2672
  ];
2638
2673
 
2639
- // src/adapters/telegram/permissions.ts
2674
+ // src/plugins/telegram/permissions.ts
2640
2675
  import { InlineKeyboard as InlineKeyboard10 } from "grammy";
2641
2676
  import { nanoid } from "nanoid";
2642
2677
  var log8 = createChildLogger({ module: "telegram-permissions" });
@@ -2716,7 +2751,7 @@ ${escapeHtml(request.description)}`,
2716
2751
  }
2717
2752
  };
2718
2753
 
2719
- // src/adapters/telegram/assistant.ts
2754
+ // src/plugins/telegram/assistant.ts
2720
2755
  var log9 = createChildLogger({ module: "telegram-assistant" });
2721
2756
  async function spawnAssistant(core, adapter, assistantTopicId) {
2722
2757
  const config = core.configManager.get();
@@ -2917,7 +2952,7 @@ function redirectToAssistant(chatId, assistantTopicId) {
2917
2952
  return `\u{1F4AC} Please use the <a href="${link}">\u{1F916} Assistant</a> topic to chat with OpenACP.`;
2918
2953
  }
2919
2954
 
2920
- // src/adapters/telegram/activity.ts
2955
+ // src/plugins/telegram/activity.ts
2921
2956
  var log10 = createChildLogger({ module: "telegram:activity" });
2922
2957
  var THINKING_REFRESH_MS = 15e3;
2923
2958
  var THINKING_MAX_MS = 3 * 60 * 1e3;
@@ -2975,11 +3010,15 @@ var ThinkingIndicator = class {
2975
3010
  const elapsed = Math.round((Date.now() - this.showTime) / 1e3);
2976
3011
  this.sendQueue.enqueue(() => {
2977
3012
  if (this.dismissed) return Promise.resolve(void 0);
2978
- return this.api.sendMessage(this.chatId, `\u{1F4AD} <i>Still thinking... (${elapsed}s)</i>`, {
2979
- message_thread_id: this.threadId,
2980
- parse_mode: "HTML",
2981
- disable_notification: true
2982
- });
3013
+ return this.api.sendMessage(
3014
+ this.chatId,
3015
+ `\u{1F4AD} <i>Still thinking... (${elapsed}s)</i>`,
3016
+ {
3017
+ message_thread_id: this.threadId,
3018
+ parse_mode: "HTML",
3019
+ disable_notification: true
3020
+ }
3021
+ );
2983
3022
  }).then((result) => {
2984
3023
  if (result && !this.dismissed) {
2985
3024
  this.msgId = result.message_id;
@@ -3003,8 +3042,8 @@ var UsageMessage = class {
3003
3042
  this.sendQueue = sendQueue;
3004
3043
  }
3005
3044
  msgId;
3006
- async send(usage) {
3007
- const text = formatUsage(usage);
3045
+ async send(usage, verbosity = "medium") {
3046
+ const text = formatUsage(usage, verbosity);
3008
3047
  try {
3009
3048
  if (this.msgId) {
3010
3049
  await this.sendQueue.enqueue(
@@ -3034,13 +3073,19 @@ var UsageMessage = class {
3034
3073
  const id = this.msgId;
3035
3074
  this.msgId = void 0;
3036
3075
  try {
3037
- await this.sendQueue.enqueue(() => this.api.deleteMessage(this.chatId, id));
3076
+ await this.sendQueue.enqueue(
3077
+ () => this.api.deleteMessage(this.chatId, id)
3078
+ );
3038
3079
  } catch (err) {
3039
3080
  log10.warn({ err }, "UsageMessage.delete() failed");
3040
3081
  }
3041
3082
  }
3042
3083
  };
3043
- function formatPlanCard(entries) {
3084
+ function formatPlanCard(entries, verbosity = "medium") {
3085
+ if (verbosity === "medium") {
3086
+ const done2 = entries.filter((e) => e.status === "completed").length;
3087
+ return `\u{1F4CB} <b>Plan:</b> ${done2}/${entries.length} steps completed`;
3088
+ }
3044
3089
  const statusIcon = {
3045
3090
  completed: "\u2705",
3046
3091
  in_progress: "\u{1F504}",
@@ -3073,6 +3118,10 @@ var PlanCard = class {
3073
3118
  latestEntries;
3074
3119
  lastSentText;
3075
3120
  flushTimer;
3121
+ verbosity = "medium";
3122
+ setVerbosity(v) {
3123
+ this.verbosity = v;
3124
+ }
3076
3125
  update(entries) {
3077
3126
  this.latestEntries = entries;
3078
3127
  if (this.flushTimer) clearTimeout(this.flushTimer);
@@ -3101,7 +3150,7 @@ var PlanCard = class {
3101
3150
  }
3102
3151
  async _flush() {
3103
3152
  if (!this.latestEntries) return;
3104
- const text = formatPlanCard(this.latestEntries);
3153
+ const text = formatPlanCard(this.latestEntries, this.verbosity);
3105
3154
  if (this.msgId && text === this.lastSentText) return;
3106
3155
  this.lastSentText = text;
3107
3156
  try {
@@ -3151,10 +3200,11 @@ var ActivityTracker = class {
3151
3200
  await this._firstEventGuard();
3152
3201
  await this.thinking.show();
3153
3202
  }
3154
- async onPlan(entries) {
3203
+ async onPlan(entries, verbosity) {
3155
3204
  await this._firstEventGuard();
3156
3205
  this.thinking.dismiss();
3157
3206
  this.hasPlanCard = true;
3207
+ if (verbosity) this.planCard.setVerbosity(verbosity);
3158
3208
  this.planCard.update(entries);
3159
3209
  }
3160
3210
  async onToolCall() {
@@ -3166,8 +3216,8 @@ var ActivityTracker = class {
3166
3216
  await this._firstEventGuard();
3167
3217
  this.thinking.dismiss();
3168
3218
  }
3169
- async sendUsage(data) {
3170
- await this.usage.send(data);
3219
+ async sendUsage(data, verbosity = "medium") {
3220
+ await this.usage.send(data, verbosity);
3171
3221
  }
3172
3222
  getUsageMsgId() {
3173
3223
  return this.usage.getMsgId();
@@ -3200,73 +3250,7 @@ var ActivityTracker = class {
3200
3250
  }
3201
3251
  };
3202
3252
 
3203
- // src/adapters/telegram/send-queue.ts
3204
- var TelegramSendQueue = class {
3205
- items = [];
3206
- processing = false;
3207
- lastExec = 0;
3208
- minInterval;
3209
- constructor(minInterval = 3e3) {
3210
- this.minInterval = minInterval;
3211
- }
3212
- enqueue(fn, opts) {
3213
- const type = opts?.type ?? "other";
3214
- const key = opts?.key;
3215
- return new Promise((resolve, reject) => {
3216
- if (type === "text" && key) {
3217
- const idx = this.items.findIndex(
3218
- (item) => item.type === "text" && item.key === key
3219
- );
3220
- if (idx !== -1) {
3221
- this.items[idx].resolve(void 0);
3222
- this.items[idx] = { fn, type, key, resolve, reject };
3223
- this.scheduleProcess();
3224
- return;
3225
- }
3226
- }
3227
- this.items.push({ fn, type, key, resolve, reject });
3228
- this.scheduleProcess();
3229
- });
3230
- }
3231
- onRateLimited() {
3232
- const remaining = [];
3233
- for (const item of this.items) {
3234
- if (item.type === "text") {
3235
- item.resolve(void 0);
3236
- } else {
3237
- remaining.push(item);
3238
- }
3239
- }
3240
- this.items = remaining;
3241
- }
3242
- scheduleProcess() {
3243
- if (this.processing) return;
3244
- if (this.items.length === 0) return;
3245
- const elapsed = Date.now() - this.lastExec;
3246
- const delay = Math.max(0, this.minInterval - elapsed);
3247
- this.processing = true;
3248
- setTimeout(() => void this.processNext(), delay);
3249
- }
3250
- async processNext() {
3251
- const item = this.items.shift();
3252
- if (!item) {
3253
- this.processing = false;
3254
- return;
3255
- }
3256
- try {
3257
- const result = await item.fn();
3258
- item.resolve(result);
3259
- } catch (err) {
3260
- item.reject(err);
3261
- } finally {
3262
- this.lastExec = Date.now();
3263
- this.processing = false;
3264
- this.scheduleProcess();
3265
- }
3266
- }
3267
- };
3268
-
3269
- // src/adapters/telegram/action-detect.ts
3253
+ // src/plugins/telegram/action-detect.ts
3270
3254
  import { nanoid as nanoid2 } from "nanoid";
3271
3255
  import { InlineKeyboard as InlineKeyboard11 } from "grammy";
3272
3256
  var CMD_NEW_RE = /\/new(?:\s+([^\s\u0080-\uFFFF]+)(?:\s+([^\s\u0080-\uFFFF]+))?)?/;
@@ -3423,32 +3407,25 @@ function setupActionCallbacks(bot, core, chatId, getAssistantSessionId) {
3423
3407
  });
3424
3408
  }
3425
3409
 
3426
- // src/adapters/telegram/tool-call-tracker.ts
3410
+ // src/plugins/telegram/tool-call-tracker.ts
3427
3411
  var log11 = createChildLogger({ module: "tool-call-tracker" });
3428
- var ToolCallTracker = class {
3412
+ var TelegramToolCallTracker = class {
3429
3413
  constructor(bot, chatId, sendQueue) {
3430
3414
  this.bot = bot;
3431
3415
  this.chatId = chatId;
3432
3416
  this.sendQueue = sendQueue;
3433
3417
  }
3434
- sessions = /* @__PURE__ */ new Map();
3418
+ tracker = new ToolCallTracker();
3419
+ /** Platform-specific ready-promise per tool call, keyed by `${sessionId}:${toolId}`. */
3420
+ readyMap = /* @__PURE__ */ new Map();
3435
3421
  async trackNewCall(sessionId, threadId, meta, verbosity = "medium") {
3436
- if (!this.sessions.has(sessionId)) {
3437
- this.sessions.set(sessionId, /* @__PURE__ */ new Map());
3438
- }
3439
3422
  let resolveReady;
3440
3423
  const ready = new Promise((r) => {
3441
3424
  resolveReady = r;
3442
3425
  });
3443
- this.sessions.get(sessionId).set(meta.id, {
3444
- msgId: 0,
3445
- name: meta.name,
3446
- kind: meta.kind,
3447
- rawInput: meta.rawInput,
3448
- viewerLinks: meta.viewerLinks,
3449
- viewerFilePath: meta.viewerFilePath,
3450
- ready
3451
- });
3426
+ const key = `${sessionId}:${meta.id}`;
3427
+ this.readyMap.set(key, { ready });
3428
+ this.tracker.track(sessionId, meta, "0");
3452
3429
  try {
3453
3430
  const msg = await this.sendQueue.enqueue(
3454
3431
  () => this.bot.api.sendMessage(this.chatId, formatToolCall(meta, verbosity), {
@@ -3457,53 +3434,60 @@ var ToolCallTracker = class {
3457
3434
  disable_notification: true
3458
3435
  })
3459
3436
  );
3460
- const toolEntry = this.sessions.get(sessionId).get(meta.id);
3461
- toolEntry.msgId = msg.message_id;
3437
+ const tracked = this.tracker.update(sessionId, meta.id, meta.status ?? "running");
3438
+ if (tracked) {
3439
+ tracked.messageId = String(msg.message_id);
3440
+ }
3462
3441
  } finally {
3463
3442
  resolveReady();
3464
3443
  }
3465
3444
  }
3466
3445
  async updateCall(sessionId, meta, verbosity = "medium") {
3467
- const toolState = this.sessions.get(sessionId)?.get(meta.id);
3468
- if (!toolState) return;
3469
- if (meta.viewerLinks) {
3470
- toolState.viewerLinks = meta.viewerLinks;
3471
- log11.debug(
3472
- { toolId: meta.id, viewerLinks: meta.viewerLinks },
3473
- "Accumulated viewerLinks"
3474
- );
3475
- }
3476
- if (meta.viewerFilePath) toolState.viewerFilePath = meta.viewerFilePath;
3477
- if (meta.name) toolState.name = meta.name;
3478
- if (meta.kind) toolState.kind = meta.kind;
3446
+ const key = `${sessionId}:${meta.id}`;
3447
+ const readyState = this.readyMap.get(key);
3448
+ const tracked = this.tracker.update(sessionId, meta.id, meta.status, {
3449
+ viewerLinks: meta.viewerLinks,
3450
+ viewerFilePath: meta.viewerFilePath,
3451
+ name: meta.name,
3452
+ kind: meta.kind
3453
+ });
3454
+ if (!tracked) return;
3479
3455
  const isTerminal = meta.status === "completed" || meta.status === "failed";
3480
3456
  if (!isTerminal) return;
3481
- await toolState.ready;
3457
+ if (readyState) {
3458
+ await readyState.ready;
3459
+ }
3460
+ const msgId = Number(tracked.messageId);
3482
3461
  log11.debug(
3483
3462
  {
3484
3463
  toolId: meta.id,
3485
3464
  status: meta.status,
3486
- hasViewerLinks: !!toolState.viewerLinks,
3487
- viewerLinks: toolState.viewerLinks,
3488
- name: toolState.name,
3489
- msgId: toolState.msgId
3465
+ hasViewerLinks: !!tracked.viewerLinks,
3466
+ viewerLinks: tracked.viewerLinks,
3467
+ name: tracked.name,
3468
+ msgId
3490
3469
  },
3491
3470
  "Tool completed, preparing edit"
3492
3471
  );
3493
3472
  const merged = {
3494
- ...meta,
3495
- name: toolState.name,
3496
- kind: toolState.kind,
3497
- rawInput: toolState.rawInput,
3498
- viewerLinks: toolState.viewerLinks,
3499
- viewerFilePath: toolState.viewerFilePath
3473
+ id: meta.id,
3474
+ name: tracked.name,
3475
+ kind: tracked.kind,
3476
+ rawInput: tracked.rawInput,
3477
+ viewerLinks: tracked.viewerLinks,
3478
+ viewerFilePath: tracked.viewerFilePath,
3479
+ displaySummary: tracked.displaySummary,
3480
+ displayTitle: tracked.displayTitle,
3481
+ displayKind: tracked.displayKind,
3482
+ status: meta.status,
3483
+ content: meta.content
3500
3484
  };
3501
3485
  const formattedText = formatToolUpdate(merged, verbosity);
3502
3486
  try {
3503
3487
  await this.sendQueue.enqueue(
3504
3488
  () => this.bot.api.editMessageText(
3505
3489
  this.chatId,
3506
- toolState.msgId,
3490
+ msgId,
3507
3491
  formattedText,
3508
3492
  { parse_mode: "HTML" }
3509
3493
  )
@@ -3512,7 +3496,7 @@ var ToolCallTracker = class {
3512
3496
  log11.warn(
3513
3497
  {
3514
3498
  err,
3515
- msgId: toolState.msgId,
3499
+ msgId,
3516
3500
  textLen: formattedText.length,
3517
3501
  hasViewerLinks: !!merged.viewerLinks
3518
3502
  },
@@ -3521,11 +3505,15 @@ var ToolCallTracker = class {
3521
3505
  }
3522
3506
  }
3523
3507
  cleanup(sessionId) {
3524
- this.sessions.delete(sessionId);
3508
+ const active = this.tracker.getActive(sessionId);
3509
+ for (const tool of active) {
3510
+ this.readyMap.delete(`${sessionId}:${tool.id}`);
3511
+ }
3512
+ this.tracker.clear(sessionId);
3525
3513
  }
3526
3514
  };
3527
3515
 
3528
- // src/adapters/telegram/streaming.ts
3516
+ // src/plugins/telegram/streaming.ts
3529
3517
  var FLUSH_INTERVAL = 5e3;
3530
3518
  var MessageDraft = class {
3531
3519
  constructor(bot, chatId, threadId, sendQueue, sessionId) {
@@ -3707,7 +3695,7 @@ var MessageDraft = class {
3707
3695
  }
3708
3696
  };
3709
3697
 
3710
- // src/adapters/telegram/draft-manager.ts
3698
+ // src/plugins/telegram/draft-manager.ts
3711
3699
  var DraftManager = class {
3712
3700
  constructor(bot, chatId, sendQueue) {
3713
3701
  this.bot = bot;
@@ -3779,7 +3767,7 @@ var DraftManager = class {
3779
3767
  }
3780
3768
  };
3781
3769
 
3782
- // src/adapters/telegram/skill-command-manager.ts
3770
+ // src/plugins/telegram/skill-command-manager.ts
3783
3771
  var log12 = createChildLogger({ module: "skill-commands" });
3784
3772
  var SkillCommandManager = class {
3785
3773
  // sessionId → pinned msgId
@@ -3874,7 +3862,57 @@ var SkillCommandManager = class {
3874
3862
  }
3875
3863
  };
3876
3864
 
3877
- // src/adapters/telegram/adapter.ts
3865
+ // src/plugins/telegram/renderer.ts
3866
+ var TelegramRenderer = class extends BaseRenderer {
3867
+ renderToolCall(content, verbosity) {
3868
+ const meta = content.metadata ?? {};
3869
+ return { body: formatToolCall(meta, verbosity), format: "html" };
3870
+ }
3871
+ renderToolUpdate(content, verbosity) {
3872
+ const meta = content.metadata ?? {};
3873
+ return { body: formatToolUpdate(meta, verbosity), format: "html" };
3874
+ }
3875
+ renderPlan(content, verbosity) {
3876
+ const meta = content.metadata;
3877
+ return { body: formatPlan({ entries: meta?.entries ?? [] }, verbosity), format: "html" };
3878
+ }
3879
+ renderUsage(content, verbosity) {
3880
+ const meta = content.metadata;
3881
+ return { body: formatUsage(meta ?? {}, verbosity), format: "html" };
3882
+ }
3883
+ renderError(content) {
3884
+ return { body: `\u274C <b>Error:</b> ${escapeHtml(content.text)}`, format: "html" };
3885
+ }
3886
+ renderNotification(notification) {
3887
+ const emoji = {
3888
+ completed: "\u2705",
3889
+ error: "\u274C",
3890
+ permission: "\u{1F510}",
3891
+ input_required: "\u{1F4AC}",
3892
+ budget_warning: "\u26A0\uFE0F"
3893
+ };
3894
+ let text = `${emoji[notification.type] || "\u2139\uFE0F"} <b>${escapeHtml(notification.sessionName || "Session")}</b>
3895
+ `;
3896
+ text += escapeHtml(notification.summary);
3897
+ return { body: text, format: "html" };
3898
+ }
3899
+ renderSystemMessage(content) {
3900
+ return { body: escapeHtml(content.text), format: "html" };
3901
+ }
3902
+ renderModeChange(content) {
3903
+ const modeId = content.metadata?.modeId ?? "";
3904
+ return { body: `\u{1F504} <b>Mode:</b> ${escapeHtml(String(modeId))}`, format: "html" };
3905
+ }
3906
+ renderConfigUpdate() {
3907
+ return { body: "\u2699\uFE0F <b>Config updated</b>", format: "html" };
3908
+ }
3909
+ renderModelUpdate(content) {
3910
+ const modelId = content.metadata?.modelId ?? "";
3911
+ return { body: `\u{1F916} <b>Model:</b> ${escapeHtml(String(modelId))}`, format: "html" };
3912
+ }
3913
+ };
3914
+
3915
+ // src/plugins/telegram/adapter.ts
3878
3916
  var log13 = createChildLogger({ module: "telegram" });
3879
3917
  function patchedFetch(input, init) {
3880
3918
  if (init?.signal && !(init.signal instanceof AbortSignal)) {
@@ -3889,7 +3927,18 @@ function patchedFetch(input, init) {
3889
3927
  }
3890
3928
  return fetch(input, init);
3891
3929
  }
3892
- var TelegramAdapter = class extends ChannelAdapter {
3930
+ var TelegramAdapter = class extends MessagingAdapter {
3931
+ name = "telegram";
3932
+ renderer = new TelegramRenderer();
3933
+ capabilities = {
3934
+ streaming: true,
3935
+ richFormatting: true,
3936
+ threads: true,
3937
+ reactions: true,
3938
+ fileUpload: true,
3939
+ voice: true
3940
+ };
3941
+ core;
3893
3942
  bot;
3894
3943
  telegramConfig;
3895
3944
  permissionHandler;
@@ -3897,18 +3946,22 @@ var TelegramAdapter = class extends ChannelAdapter {
3897
3946
  assistantInitializing = false;
3898
3947
  notificationTopicId;
3899
3948
  assistantTopicId;
3900
- sendQueue = new TelegramSendQueue(3e3);
3949
+ sendQueue = new SendQueue({ minInterval: 3e3 });
3950
+ _sessionThreadIds = /* @__PURE__ */ new Map();
3901
3951
  // Extracted managers
3902
3952
  toolTracker;
3903
3953
  draftManager;
3904
3954
  skillManager;
3905
3955
  fileService;
3906
3956
  sessionTrackers = /* @__PURE__ */ new Map();
3907
- get verbosity() {
3908
- const live = this.core.configManager.get().channels?.telegram;
3909
- const v = live?.displayVerbosity ?? this.telegramConfig.displayVerbosity;
3910
- if (v === "low" || v === "high") return v;
3911
- return "medium";
3957
+ callbackCache = /* @__PURE__ */ new Map();
3958
+ callbackCounter = 0;
3959
+ getThreadId(sessionId) {
3960
+ const threadId = this._sessionThreadIds.get(sessionId);
3961
+ if (threadId === void 0) {
3962
+ throw new Error(`No threadId stored for session ${sessionId}`);
3963
+ }
3964
+ return threadId;
3912
3965
  }
3913
3966
  getOrCreateTracker(sessionId, threadId) {
3914
3967
  let tracker = this.sessionTrackers.get(sessionId);
@@ -3924,7 +3977,11 @@ var TelegramAdapter = class extends ChannelAdapter {
3924
3977
  return tracker;
3925
3978
  }
3926
3979
  constructor(core, config) {
3927
- super(core, config);
3980
+ super(
3981
+ { configManager: core.configManager },
3982
+ { ...config, maxMessageLength: 4096, enabled: config.enabled ?? true }
3983
+ );
3984
+ this.core = core;
3928
3985
  this.telegramConfig = config;
3929
3986
  }
3930
3987
  async start() {
@@ -3935,7 +3992,7 @@ var TelegramAdapter = class extends ChannelAdapter {
3935
3992
  }
3936
3993
  });
3937
3994
  this.fileService = this.core.fileService;
3938
- this.toolTracker = new ToolCallTracker(
3995
+ this.toolTracker = new TelegramToolCallTracker(
3939
3996
  this.bot,
3940
3997
  this.telegramConfig.chatId,
3941
3998
  this.sendQueue
@@ -4015,6 +4072,67 @@ var TelegramAdapter = class extends ChannelAdapter {
4015
4072
  (sessionId) => this.core.sessionManager.getSession(sessionId),
4016
4073
  (notification) => this.sendNotification(notification)
4017
4074
  );
4075
+ this.bot.on("message:text", async (ctx, next) => {
4076
+ const text = ctx.message?.text;
4077
+ if (!text?.startsWith("/")) return next();
4078
+ const registry = this.core.lifecycleManager?.serviceRegistry?.get("command-registry");
4079
+ if (!registry) return next();
4080
+ const commandName = text.split(" ")[0].slice(1).split("@")[0];
4081
+ const def = registry.get(commandName);
4082
+ if (!def) return next();
4083
+ const chatId = ctx.chat.id;
4084
+ const topicId = ctx.message.message_thread_id;
4085
+ try {
4086
+ const sessionId = topicId != null ? this.core.sessionManager.getSessionByThread("telegram", String(topicId))?.id ?? null : null;
4087
+ const response = await registry.execute(text, {
4088
+ raw: "",
4089
+ sessionId,
4090
+ channelId: "telegram",
4091
+ userId: String(ctx.from?.id),
4092
+ reply: async (content) => {
4093
+ if (typeof content === "string") {
4094
+ await ctx.reply(content);
4095
+ } else if (typeof content === "object" && content !== null && "type" in content) {
4096
+ await this.renderCommandResponse(content, chatId, topicId);
4097
+ }
4098
+ }
4099
+ });
4100
+ if (response.type !== "silent") {
4101
+ await this.renderCommandResponse(response, chatId, topicId);
4102
+ }
4103
+ } catch (err) {
4104
+ await ctx.reply(`\u26A0\uFE0F Command failed: ${String(err)}`);
4105
+ }
4106
+ });
4107
+ this.bot.callbackQuery(/^c\//, async (ctx) => {
4108
+ const data = ctx.callbackQuery.data;
4109
+ const command = this.fromCallbackData(data);
4110
+ const registry = this.core.lifecycleManager?.serviceRegistry?.get("command-registry");
4111
+ if (!registry) return;
4112
+ const chatId = ctx.chat.id;
4113
+ const topicId = ctx.callbackQuery.message?.message_thread_id;
4114
+ try {
4115
+ const sessionId = topicId != null ? this.core.sessionManager.getSessionByThread("telegram", String(topicId))?.id ?? null : null;
4116
+ const response = await registry.execute(command, {
4117
+ raw: "",
4118
+ sessionId,
4119
+ channelId: "telegram",
4120
+ userId: String(ctx.from?.id),
4121
+ reply: async (content) => {
4122
+ if (typeof content === "string") {
4123
+ await ctx.editMessageText(content).catch(() => {
4124
+ });
4125
+ }
4126
+ }
4127
+ });
4128
+ await ctx.answerCallbackQuery();
4129
+ if (response.type !== "silent") {
4130
+ await this.renderCommandResponse(response, chatId, topicId);
4131
+ }
4132
+ } catch {
4133
+ await ctx.answerCallbackQuery({ text: "Command failed" });
4134
+ }
4135
+ });
4018
4136
  setupDangerousModeCallbacks(this.bot, this.core);
4019
4137
  setupTTSCallbacks(this.bot, this.core);
4020
4138
  setupVerbosityCallbacks(this.bot, this.core);
@@ -4092,7 +4210,7 @@ var TelegramAdapter = class extends ChannelAdapter {
4092
4210
  });
4093
4211
  return;
4094
4212
  }
4095
- const { getAgentCapabilities } = await import("./agent-registry-WT4NXPYG.js");
4213
+ const { getAgentCapabilities } = await import("./agent-registry-5LZT7CUB.js");
4096
4214
  const caps = getAgentCapabilities(agentName);
4097
4215
  if (!caps.supportsResume || !caps.resumeCommand) {
4098
4216
  await ctx.reply("This agent does not support session transfer.", {
@@ -4179,6 +4297,87 @@ var TelegramAdapter = class extends ChannelAdapter {
4179
4297
  await this.bot.stop();
4180
4298
  log13.info("Telegram bot stopped");
4181
4299
  }
4300
+ // --- CommandRegistry response rendering ---
4301
+ async renderCommandResponse(response, chatId, topicId) {
4302
+ switch (response.type) {
4303
+ case "text":
4304
+ await this.bot.api.sendMessage(chatId, response.text, {
4305
+ message_thread_id: topicId
4306
+ });
4307
+ break;
4308
+ case "error":
4309
+ await this.bot.api.sendMessage(
4310
+ chatId,
4311
+ `\u26A0\uFE0F ${response.message}`,
4312
+ { message_thread_id: topicId }
4313
+ );
4314
+ break;
4315
+ case "menu": {
4316
+ const keyboard = response.options.map((opt) => [
4317
+ {
4318
+ text: `${opt.label}${opt.hint ? ` \u2014 ${opt.hint}` : ""}`,
4319
+ callback_data: this.toCallbackData(opt.command)
4320
+ }
4321
+ ]);
4322
+ await this.bot.api.sendMessage(chatId, response.title, {
4323
+ message_thread_id: topicId,
4324
+ reply_markup: { inline_keyboard: keyboard }
4325
+ });
4326
+ break;
4327
+ }
4328
+ case "list": {
4329
+ const lines = response.items.map(
4330
+ (i) => `\u2022 ${i.label}${i.detail ? ` \u2014 ${i.detail}` : ""}`
4331
+ );
4332
+ const text = `${response.title}
4333
+ ${lines.join("\n")}`;
4334
+ await this.bot.api.sendMessage(chatId, text, {
4335
+ message_thread_id: topicId
4336
+ });
4337
+ break;
4338
+ }
4339
+ case "confirm": {
4340
+ const buttons = [
4341
+ [
4342
+ {
4343
+ text: "\u2705 Yes",
4344
+ callback_data: this.toCallbackData(response.onYes)
4345
+ }
4346
+ ]
4347
+ ];
4348
+ if (response.onNo) {
4349
+ buttons[0].push({
4350
+ text: "\u274C No",
4351
+ callback_data: this.toCallbackData(response.onNo)
4352
+ });
4353
+ }
4354
+ await this.bot.api.sendMessage(chatId, response.question, {
4355
+ message_thread_id: topicId,
4356
+ reply_markup: { inline_keyboard: buttons }
4357
+ });
4358
+ break;
4359
+ }
4360
+ case "silent":
4361
+ break;
4362
+ }
4363
+ }
4364
+ toCallbackData(command) {
4365
+ const data = `c/${command}`;
4366
+ if (data.length <= 64) return data;
4367
+ const id = String(++this.callbackCounter);
4368
+ this.callbackCache.set(id, command);
4369
+ if (this.callbackCache.size > 1e3) {
4370
+ const first = this.callbackCache.keys().next().value;
4371
+ if (first) this.callbackCache.delete(first);
4372
+ }
4373
+ return `c/#${id}`;
4374
+ }
4375
+ fromCallbackData(data) {
4376
+ if (data.startsWith("c/#")) {
4377
+ return this.callbackCache.get(data.slice(3)) ?? data.slice(2);
4378
+ }
4379
+ return data.slice(2);
4380
+ }
4182
4381
  setupRoutes() {
4183
4382
  this.bot.on("message:text", async (ctx) => {
4184
4383
  const threadId = ctx.message.message_thread_id;
@@ -4315,243 +4514,255 @@ var TelegramAdapter = class extends ChannelAdapter {
4315
4514
  );
4316
4515
  });
4317
4516
  }
4318
- // --- MessageHandlers for dispatchMessage ---
4319
- messageHandlers = {
4320
- onThought: async (ctx, _content) => {
4321
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.threadId);
4322
- await tracker.onThought();
4323
- },
4324
- onText: async (ctx, content) => {
4325
- if (!this.draftManager.hasDraft(ctx.sessionId)) {
4326
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.threadId);
4327
- tracker.onTextStart().catch(() => {
4328
- });
4329
- }
4330
- const draft = this.draftManager.getOrCreate(ctx.sessionId, ctx.threadId);
4331
- draft.append(content.text);
4332
- this.draftManager.appendText(ctx.sessionId, content.text);
4333
- },
4334
- onToolCall: async (ctx, content) => {
4335
- const meta = content.metadata ?? {};
4336
- const toolName = meta.name ?? content.text ?? "Tool";
4337
- const toolKind = String(meta.kind ?? "other");
4338
- const noiseAction = evaluateNoise(toolName, toolKind, meta.rawInput);
4339
- if (noiseAction === "hide" && this.verbosity !== "high") return;
4340
- if (noiseAction === "collapse" && this.verbosity === "low") return;
4341
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.threadId);
4342
- await tracker.onToolCall();
4343
- await this.draftManager.finalize(
4344
- ctx.sessionId,
4345
- this.assistantSession?.id
4346
- );
4347
- await this.toolTracker.trackNewCall(
4348
- ctx.sessionId,
4349
- ctx.threadId,
4350
- {
4351
- id: meta.id ?? "",
4352
- name: meta.name ?? content.text ?? "Tool",
4353
- kind: meta.kind,
4354
- status: meta.status,
4355
- content: meta.content,
4356
- rawInput: meta.rawInput,
4357
- viewerLinks: meta.viewerLinks,
4358
- viewerFilePath: meta.viewerFilePath
4359
- },
4360
- this.verbosity
4517
+ // --- MessagingAdapter overrides ---
4518
+ async sendMessage(sessionId, content) {
4519
+ if (this.assistantInitializing && sessionId === this.assistantSession?.id)
4520
+ return;
4521
+ const session = this.core.sessionManager.getSession(sessionId);
4522
+ if (!session) return;
4523
+ if (session.archiving) return;
4524
+ const threadId = Number(session.threadId);
4525
+ if (!threadId || isNaN(threadId)) {
4526
+ log13.warn(
4527
+ { sessionId, threadId: session.threadId },
4528
+ "Session has no valid threadId, skipping message"
4361
4529
  );
4362
- },
4363
- onToolUpdate: async (ctx, content) => {
4364
- const meta = content.metadata ?? {};
4365
- await this.toolTracker.updateCall(
4366
- ctx.sessionId,
4530
+ return;
4531
+ }
4532
+ this._sessionThreadIds.set(sessionId, threadId);
4533
+ try {
4534
+ await super.sendMessage(sessionId, content);
4535
+ } finally {
4536
+ this._sessionThreadIds.delete(sessionId);
4537
+ }
4538
+ }
4539
+ async handleThought(sessionId, _content, _verbosity) {
4540
+ const threadId = this.getThreadId(sessionId);
4541
+ const tracker = this.getOrCreateTracker(sessionId, threadId);
4542
+ await tracker.onThought();
4543
+ }
4544
+ async handleText(sessionId, content) {
4545
+ const threadId = this.getThreadId(sessionId);
4546
+ if (!this.draftManager.hasDraft(sessionId)) {
4547
+ const tracker = this.getOrCreateTracker(sessionId, threadId);
4548
+ tracker.onTextStart().catch(() => {
4549
+ });
4550
+ }
4551
+ const draft = this.draftManager.getOrCreate(sessionId, threadId);
4552
+ draft.append(content.text);
4553
+ this.draftManager.appendText(sessionId, content.text);
4554
+ }
4555
+ async handleToolCall(sessionId, content, verbosity) {
4556
+ const threadId = this.getThreadId(sessionId);
4557
+ const meta = content.metadata ?? {};
4558
+ const tracker = this.getOrCreateTracker(sessionId, threadId);
4559
+ await tracker.onToolCall();
4560
+ await this.draftManager.finalize(
4561
+ sessionId,
4562
+ this.assistantSession?.id
4563
+ );
4564
+ await this.toolTracker.trackNewCall(
4565
+ sessionId,
4566
+ threadId,
4567
+ {
4568
+ id: meta.id ?? "",
4569
+ name: meta.name ?? content.text ?? "Tool",
4570
+ kind: meta.kind,
4571
+ status: meta.status,
4572
+ content: meta.content,
4573
+ rawInput: meta.rawInput,
4574
+ viewerLinks: meta.viewerLinks,
4575
+ viewerFilePath: meta.viewerFilePath,
4576
+ displaySummary: meta.displaySummary,
4577
+ displayTitle: meta.displayTitle,
4578
+ displayKind: meta.displayKind
4579
+ },
4580
+ verbosity
4581
+ );
4582
+ }
4583
+ async handleToolUpdate(sessionId, content, verbosity) {
4584
+ const meta = content.metadata ?? {};
4585
+ await this.toolTracker.updateCall(
4586
+ sessionId,
4587
+ {
4588
+ id: meta.id ?? "",
4589
+ name: meta.name ?? content.text ?? "",
4590
+ kind: meta.kind,
4591
+ status: meta.status ?? "completed",
4592
+ content: meta.content,
4593
+ rawInput: meta.rawInput,
4594
+ viewerLinks: meta.viewerLinks,
4595
+ viewerFilePath: meta.viewerFilePath,
4596
+ displaySummary: meta.displaySummary,
4597
+ displayTitle: meta.displayTitle,
4598
+ displayKind: meta.displayKind
4599
+ },
4600
+ verbosity
4601
+ );
4602
+ }
4603
+ async handlePlan(sessionId, content, verbosity) {
4604
+ const threadId = this.getThreadId(sessionId);
4605
+ const meta = content.metadata ?? {};
4606
+ const entries = meta.entries ?? [];
4607
+ const tracker = this.getOrCreateTracker(sessionId, threadId);
4608
+ await tracker.onPlan(
4609
+ entries.map((e) => ({
4610
+ content: e.content,
4611
+ status: e.status,
4612
+ priority: e.priority ?? "medium"
4613
+ })),
4614
+ verbosity
4615
+ );
4616
+ }
4617
+ async handleUsage(sessionId, content, verbosity) {
4618
+ const threadId = this.getThreadId(sessionId);
4619
+ const meta = content.metadata;
4620
+ await this.draftManager.finalize(
4621
+ sessionId,
4622
+ this.assistantSession?.id
4623
+ );
4624
+ const tracker = this.getOrCreateTracker(sessionId, threadId);
4625
+ await tracker.sendUsage(meta ?? {}, verbosity);
4626
+ if (this.notificationTopicId && sessionId !== this.assistantSession?.id) {
4627
+ const sess = this.core.sessionManager.getSession(sessionId);
4628
+ const sessionName = sess?.name || "Session";
4629
+ const chatIdStr = String(this.telegramConfig.chatId);
4630
+ const numericId = chatIdStr.startsWith("-100") ? chatIdStr.slice(4) : chatIdStr.replace("-", "");
4631
+ const usageMsgId = tracker.getUsageMsgId();
4632
+ const deepLink = usageMsgId ? `https://t.me/c/${numericId}/${threadId}/${usageMsgId}` : `https://t.me/c/${numericId}/${threadId}`;
4633
+ const text = `\u2705 <b>${escapeHtml(sessionName)}</b>
4634
+ Task completed.
4635
+
4636
+ <a href="${deepLink}">\u2192 Go to topic</a>`;
4637
+ this.sendQueue.enqueue(
4638
+ () => this.bot.api.sendMessage(this.telegramConfig.chatId, text, {
4639
+ message_thread_id: this.notificationTopicId,
4640
+ parse_mode: "HTML",
4641
+ disable_notification: false
4642
+ })
4643
+ ).catch(() => {
4644
+ });
4645
+ }
4646
+ }
4647
+ async handleAttachment(sessionId, content) {
4648
+ const threadId = this.getThreadId(sessionId);
4649
+ if (!content.attachment) return;
4650
+ const { attachment } = content;
4651
+ if (attachment.size > 50 * 1024 * 1024) {
4652
+ log13.warn(
4367
4653
  {
4368
- id: meta.id ?? "",
4369
- name: meta.name ?? content.text ?? "",
4370
- kind: meta.kind,
4371
- status: meta.status ?? "completed",
4372
- content: meta.content,
4373
- rawInput: meta.rawInput,
4374
- viewerLinks: meta.viewerLinks,
4375
- viewerFilePath: meta.viewerFilePath
4654
+ sessionId,
4655
+ fileName: attachment.fileName,
4656
+ size: attachment.size
4376
4657
  },
4377
- this.verbosity
4378
- );
4379
- },
4380
- onPlan: async (ctx, content) => {
4381
- const meta = content.metadata ?? {};
4382
- const entries = meta.entries ?? [];
4383
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.threadId);
4384
- await tracker.onPlan(
4385
- entries.map((e) => ({
4386
- content: e.content,
4387
- status: e.status,
4388
- priority: e.priority ?? "medium"
4389
- }))
4658
+ "File too large for Telegram (>50MB)"
4390
4659
  );
4391
- },
4392
- onUsage: async (ctx, content) => {
4393
- const meta = content.metadata;
4394
- await this.draftManager.finalize(
4395
- ctx.sessionId,
4396
- this.assistantSession?.id
4660
+ await this.sendQueue.enqueue(
4661
+ () => this.bot.api.sendMessage(
4662
+ this.telegramConfig.chatId,
4663
+ `\u26A0\uFE0F File too large to send (${Math.round(attachment.size / 1024 / 1024)}MB): ${escapeHtml(attachment.fileName)}`,
4664
+ { message_thread_id: threadId, parse_mode: "HTML" }
4665
+ )
4397
4666
  );
4398
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.threadId);
4399
- await tracker.sendUsage(meta ?? {});
4400
- if (this.notificationTopicId && ctx.sessionId !== this.assistantSession?.id) {
4401
- const sess = this.core.sessionManager.getSession(ctx.sessionId);
4402
- const sessionName = sess?.name || "Session";
4403
- const chatIdStr = String(this.telegramConfig.chatId);
4404
- const numericId = chatIdStr.startsWith("-100") ? chatIdStr.slice(4) : chatIdStr.replace("-", "");
4405
- const usageMsgId = tracker.getUsageMsgId();
4406
- const deepLink = usageMsgId ? `https://t.me/c/${numericId}/${ctx.threadId}/${usageMsgId}` : `https://t.me/c/${numericId}/${ctx.threadId}`;
4407
- const text = `\u2705 <b>${escapeHtml(sessionName)}</b>
4408
- Task completed.
4409
-
4410
- <a href="${deepLink}">\u2192 Go to topic</a>`;
4411
- this.sendQueue.enqueue(
4412
- () => this.bot.api.sendMessage(this.telegramConfig.chatId, text, {
4413
- message_thread_id: this.notificationTopicId,
4414
- parse_mode: "HTML",
4415
- disable_notification: false
4667
+ return;
4668
+ }
4669
+ try {
4670
+ const inputFile = new InputFile(attachment.filePath);
4671
+ if (attachment.type === "image") {
4672
+ await this.sendQueue.enqueue(
4673
+ () => this.bot.api.sendPhoto(this.telegramConfig.chatId, inputFile, {
4674
+ message_thread_id: threadId
4416
4675
  })
4417
- ).catch(() => {
4418
- });
4419
- }
4420
- },
4421
- onAttachment: async (ctx, content) => {
4422
- if (!content.attachment) return;
4423
- const { attachment } = content;
4424
- if (attachment.size > 50 * 1024 * 1024) {
4425
- log13.warn(
4426
- {
4427
- sessionId: ctx.sessionId,
4428
- fileName: attachment.fileName,
4429
- size: attachment.size
4430
- },
4431
- "File too large for Telegram (>50MB)"
4432
4676
  );
4677
+ } else if (attachment.type === "audio") {
4433
4678
  await this.sendQueue.enqueue(
4434
- () => this.bot.api.sendMessage(
4435
- this.telegramConfig.chatId,
4436
- `\u26A0\uFE0F File too large to send (${Math.round(attachment.size / 1024 / 1024)}MB): ${escapeHtml(attachment.fileName)}`,
4437
- { message_thread_id: ctx.threadId, parse_mode: "HTML" }
4438
- )
4679
+ () => this.bot.api.sendVoice(this.telegramConfig.chatId, inputFile, {
4680
+ message_thread_id: threadId
4681
+ })
4439
4682
  );
4440
- return;
4441
- }
4442
- try {
4443
- const inputFile = new InputFile(attachment.filePath);
4444
- if (attachment.type === "image") {
4445
- await this.sendQueue.enqueue(
4446
- () => this.bot.api.sendPhoto(this.telegramConfig.chatId, inputFile, {
4447
- message_thread_id: ctx.threadId
4448
- })
4449
- );
4450
- } else if (attachment.type === "audio") {
4451
- await this.sendQueue.enqueue(
4452
- () => this.bot.api.sendVoice(this.telegramConfig.chatId, inputFile, {
4453
- message_thread_id: ctx.threadId
4454
- })
4455
- );
4456
- const draft = this.draftManager.getDraft(ctx.sessionId);
4457
- if (draft) {
4458
- draft.stripPattern(/\[TTS\][\s\S]*?\[\/TTS\]/g).catch(() => {
4459
- });
4460
- }
4461
- } else {
4462
- await this.sendQueue.enqueue(
4463
- () => this.bot.api.sendDocument(this.telegramConfig.chatId, inputFile, {
4464
- message_thread_id: ctx.threadId
4465
- })
4466
- );
4683
+ const draft = this.draftManager.getDraft(sessionId);
4684
+ if (draft) {
4685
+ draft.stripPattern(/\[TTS\][\s\S]*?\[\/TTS\]/g).catch(() => {
4686
+ });
4467
4687
  }
4468
- } catch (err) {
4469
- log13.error(
4470
- { err, sessionId: ctx.sessionId, fileName: attachment.fileName },
4471
- "Failed to send attachment"
4472
- );
4473
- }
4474
- },
4475
- onSessionEnd: async (ctx, _content) => {
4476
- await this.draftManager.finalize(
4477
- ctx.sessionId,
4478
- this.assistantSession?.id
4479
- );
4480
- this.draftManager.cleanup(ctx.sessionId);
4481
- this.toolTracker.cleanup(ctx.sessionId);
4482
- await this.skillManager.cleanup(ctx.sessionId);
4483
- const tracker = this.sessionTrackers.get(ctx.sessionId);
4484
- if (tracker) {
4485
- await tracker.onComplete();
4486
- tracker.destroy();
4487
- this.sessionTrackers.delete(ctx.sessionId);
4488
4688
  } else {
4489
4689
  await this.sendQueue.enqueue(
4490
- () => this.bot.api.sendMessage(
4491
- this.telegramConfig.chatId,
4492
- `\u2705 <b>Done</b>`,
4493
- {
4494
- message_thread_id: ctx.threadId,
4495
- parse_mode: "HTML",
4496
- disable_notification: true
4497
- }
4498
- )
4690
+ () => this.bot.api.sendDocument(this.telegramConfig.chatId, inputFile, {
4691
+ message_thread_id: threadId
4692
+ })
4499
4693
  );
4500
4694
  }
4501
- },
4502
- onError: async (ctx, content) => {
4503
- await this.draftManager.finalize(
4504
- ctx.sessionId,
4505
- this.assistantSession?.id
4506
- );
4507
- const tracker = this.sessionTrackers.get(ctx.sessionId);
4508
- if (tracker) {
4509
- tracker.destroy();
4510
- this.sessionTrackers.delete(ctx.sessionId);
4511
- }
4512
- await this.sendQueue.enqueue(
4513
- () => this.bot.api.sendMessage(
4514
- this.telegramConfig.chatId,
4515
- `\u274C <b>Error:</b> ${escapeHtml(content.text)}`,
4516
- {
4517
- message_thread_id: ctx.threadId,
4518
- parse_mode: "HTML",
4519
- disable_notification: true
4520
- }
4521
- )
4695
+ } catch (err) {
4696
+ log13.error(
4697
+ { err, sessionId, fileName: attachment.fileName },
4698
+ "Failed to send attachment"
4522
4699
  );
4523
- },
4524
- onSystemMessage: async (ctx, content) => {
4700
+ }
4701
+ }
4702
+ async handleSessionEnd(sessionId, _content) {
4703
+ const threadId = this.getThreadId(sessionId);
4704
+ await this.draftManager.finalize(
4705
+ sessionId,
4706
+ this.assistantSession?.id
4707
+ );
4708
+ this.draftManager.cleanup(sessionId);
4709
+ this.toolTracker.cleanup(sessionId);
4710
+ await this.skillManager.cleanup(sessionId);
4711
+ const tracker = this.sessionTrackers.get(sessionId);
4712
+ if (tracker) {
4713
+ await tracker.onComplete();
4714
+ tracker.destroy();
4715
+ this.sessionTrackers.delete(sessionId);
4716
+ } else {
4525
4717
  await this.sendQueue.enqueue(
4526
4718
  () => this.bot.api.sendMessage(
4527
4719
  this.telegramConfig.chatId,
4528
- escapeHtml(content.text),
4720
+ `\u2705 <b>Done</b>`,
4529
4721
  {
4530
- message_thread_id: ctx.threadId,
4722
+ message_thread_id: threadId,
4531
4723
  parse_mode: "HTML",
4532
4724
  disable_notification: true
4533
4725
  }
4534
4726
  )
4535
4727
  );
4536
4728
  }
4537
- };
4538
- // --- ChannelAdapter implementations ---
4539
- async sendMessage(sessionId, content) {
4540
- if (this.assistantInitializing && sessionId === this.assistantSession?.id)
4541
- return;
4542
- const session = this.core.sessionManager.getSession(sessionId);
4543
- if (!session) return;
4544
- if (session.archiving) return;
4545
- const threadId = Number(session.threadId);
4546
- if (!threadId || isNaN(threadId)) {
4547
- log13.warn(
4548
- { sessionId, threadId: session.threadId },
4549
- "Session has no valid threadId, skipping message"
4550
- );
4551
- return;
4729
+ }
4730
+ async handleError(sessionId, content) {
4731
+ const threadId = this.getThreadId(sessionId);
4732
+ await this.draftManager.finalize(
4733
+ sessionId,
4734
+ this.assistantSession?.id
4735
+ );
4736
+ const tracker = this.sessionTrackers.get(sessionId);
4737
+ if (tracker) {
4738
+ tracker.destroy();
4739
+ this.sessionTrackers.delete(sessionId);
4552
4740
  }
4553
- const ctx = { sessionId, threadId };
4554
- await dispatchMessage(this.messageHandlers, ctx, content, this.verbosity);
4741
+ await this.sendQueue.enqueue(
4742
+ () => this.bot.api.sendMessage(
4743
+ this.telegramConfig.chatId,
4744
+ `\u274C <b>Error:</b> ${escapeHtml(content.text)}`,
4745
+ {
4746
+ message_thread_id: threadId,
4747
+ parse_mode: "HTML",
4748
+ disable_notification: true
4749
+ }
4750
+ )
4751
+ );
4752
+ }
4753
+ async handleSystem(sessionId, content) {
4754
+ const threadId = this.getThreadId(sessionId);
4755
+ await this.sendQueue.enqueue(
4756
+ () => this.bot.api.sendMessage(
4757
+ this.telegramConfig.chatId,
4758
+ escapeHtml(content.text),
4759
+ {
4760
+ message_thread_id: threadId,
4761
+ parse_mode: "HTML",
4762
+ disable_notification: true
4763
+ }
4764
+ )
4765
+ );
4555
4766
  }
4556
4767
  async sendPermissionRequest(sessionId, request) {
4557
4768
  log13.info({ sessionId, requestId: request.id }, "Permission request sent");
@@ -4592,7 +4803,16 @@ Task completed.
4592
4803
 
4593
4804
  <a href="${deepLink}">\u2192 Go to topic</a>`;
4594
4805
  }
4595
- const replyMarkup = notification.type === "completed" ? { inline_keyboard: [[{ text: "\u{1F4CB} Summary", callback_data: `sm:summary:${notification.sessionId}` }]] } : void 0;
4806
+ const replyMarkup = notification.type === "completed" ? {
4807
+ inline_keyboard: [
4808
+ [
4809
+ {
4810
+ text: "\u{1F4CB} Summary",
4811
+ callback_data: `sm:summary:${notification.sessionId}`
4812
+ }
4813
+ ]
4814
+ ]
4815
+ } : void 0;
4596
4816
  await this.sendQueue.enqueue(
4597
4817
  () => this.bot.api.sendMessage(this.telegramConfig.chatId, text, {
4598
4818
  message_thread_id: this.notificationTopicId,
@@ -4737,4 +4957,4 @@ Task completed.
4737
4957
  export {
4738
4958
  TelegramAdapter
4739
4959
  };
4740
- //# sourceMappingURL=chunk-H5P2C6H4.js.map
4960
+ //# sourceMappingURL=chunk-RKB2ZK6S.js.map