@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,29 +1,15 @@
1
- import {
2
- buildActionKeyboard,
3
- detectAction,
4
- storeAction
5
- } from "./chunk-I7WC6E5S.js";
6
1
  import {
7
2
  handleNew,
8
3
  handleNewChat,
9
4
  handleNewSessionButton
10
- } from "./chunk-XANPHG7W.js";
11
- import {
12
- handleDangerous,
13
- handleDangerousButton,
14
- handleRestart,
15
- handleTTS,
16
- handleTTSButton,
17
- handleUpdate,
18
- handleVerbosity
19
- } from "./chunk-KIRH7TUJ.js";
5
+ } from "./chunk-QSDZDHNS.js";
20
6
  import {
21
7
  handleCancel,
22
8
  handleCleanupButton,
23
9
  handleHandoff,
24
10
  handleSessions,
25
11
  handleStatus
26
- } from "./chunk-4CTX774K.js";
12
+ } from "./chunk-GJOY37U7.js";
27
13
  import {
28
14
  buildDeepLink,
29
15
  createSessionThread,
@@ -31,116 +17,69 @@ import {
31
17
  ensureForums,
32
18
  ensureUnarchived,
33
19
  renameSessionThread
34
- } from "./chunk-BNLGTZ34.js";
20
+ } from "./chunk-O5RG4YZY.js";
35
21
  import {
36
22
  handleAgentButton,
37
23
  handleAgents,
38
24
  handleInstall
39
- } from "./chunk-J4SJTKIK.js";
25
+ } from "./chunk-NAM4ERUW.js";
40
26
  import {
41
27
  handleSettings,
42
28
  handleSettingsButton
43
- } from "./chunk-O7CPGUAI.js";
29
+ } from "./chunk-4KGLKKQK.js";
44
30
  import {
45
31
  handleDoctor,
46
32
  handleDoctorButton
47
- } from "./chunk-2HMQOC7N.js";
33
+ } from "./chunk-I3CGU5W7.js";
34
+ import {
35
+ buildActionKeyboard,
36
+ detectAction,
37
+ storeAction
38
+ } from "./chunk-HVBNCPAY.js";
39
+ import {
40
+ handleDangerous,
41
+ handleDangerousButton,
42
+ handleRestart,
43
+ handleTTS,
44
+ handleTTSButton,
45
+ handleUpdate,
46
+ handleVerbosity
47
+ } from "./chunk-MTSDOSXS.js";
48
48
  import {
49
49
  PRODUCT_GUIDE,
50
- STATUS_ICONS,
51
- dispatchMessage,
52
- evaluateNoise,
50
+ SendQueue,
51
+ ToolCallTracker
52
+ } from "./chunk-5ZOFBTOR.js";
53
+ import {
54
+ BaseRenderer,
55
+ MessagingAdapter,
53
56
  extractContentText,
54
57
  formatTokens,
55
58
  formatToolSummary,
56
59
  formatToolTitle,
57
60
  progressBar,
61
+ resolveToolIcon,
58
62
  splitMessage,
59
63
  stripCodeFences,
60
64
  truncateContent
61
- } from "./chunk-JUYDFUSN.js";
62
- import {
63
- ChannelAdapter
64
- } from "./chunk-LBIKITQT.js";
65
- import "./chunk-NVPG6JCL.js";
66
- import "./chunk-JHYXKVV2.js";
67
- import "./chunk-33RP6K2O.js";
65
+ } from "./chunk-V2M243KZ.js";
66
+ import "./chunk-L7YNNBI5.js";
67
+ import "./chunk-ODUM3D6X.js";
68
+ import "./chunk-QVMEF6FB.js";
68
69
  import {
70
+ createChildLogger,
69
71
  log
70
- } from "./chunk-GAK6PIBW.js";
72
+ } from "./chunk-XMMAGAT4.js";
71
73
  import "./chunk-VUNV25KB.js";
72
74
 
73
- // src/adapters/discord/adapter.ts
74
- import { Client, GatewayIntentBits, MessageFlags } from "discord.js";
75
-
76
- // src/adapters/discord/send-queue.ts
77
- var DiscordSendQueue = class {
78
- items = [];
79
- processing = false;
80
- lastExec = 0;
81
- minInterval;
82
- constructor(minInterval = 1e3) {
83
- this.minInterval = minInterval;
84
- }
85
- enqueue(fn, opts) {
86
- const type = opts.type;
87
- const key = opts.key;
88
- return new Promise((resolve, reject) => {
89
- if (type === "text" && key) {
90
- const idx = this.items.findIndex(
91
- (item) => item.type === "text" && item.key === key
92
- );
93
- if (idx !== -1) {
94
- this.items[idx].resolve(void 0);
95
- this.items[idx] = { fn, type, key, resolve, reject };
96
- this.scheduleProcess();
97
- return;
98
- }
99
- }
100
- this.items.push({ fn, type, key, resolve, reject });
101
- this.scheduleProcess();
102
- });
103
- }
104
- onRateLimited() {
105
- log.warn("[DiscordSendQueue] Rate limited \u2014 dropping queued text items");
106
- const remaining = [];
107
- for (const item of this.items) {
108
- if (item.type === "text") {
109
- item.resolve(void 0);
110
- } else {
111
- remaining.push(item);
112
- }
113
- }
114
- this.items = remaining;
115
- }
116
- scheduleProcess() {
117
- if (this.processing) return;
118
- if (this.items.length === 0) return;
119
- const elapsed = Date.now() - this.lastExec;
120
- const delay = Math.max(0, this.minInterval - elapsed);
121
- this.processing = true;
122
- setTimeout(() => void this.processNext(), delay);
123
- }
124
- async processNext() {
125
- const item = this.items.shift();
126
- if (!item) {
127
- this.processing = false;
128
- return;
129
- }
130
- try {
131
- const result = await item.fn();
132
- item.resolve(result);
133
- } catch (err) {
134
- item.reject(err);
135
- } finally {
136
- this.lastExec = Date.now();
137
- this.processing = false;
138
- this.scheduleProcess();
139
- }
140
- }
141
- };
75
+ // src/plugins/discord/adapter.ts
76
+ import {
77
+ Client,
78
+ GatewayIntentBits,
79
+ MessageFlags
80
+ } from "discord.js";
142
81
 
143
- // src/adapters/discord/formatting.ts
82
+ // src/plugins/discord/formatting.ts
144
83
  function formatViewerLinks(links, filePath) {
145
84
  if (!links) return "";
146
85
  const fileName = filePath ? filePath.split("/").pop() || filePath : "";
@@ -152,27 +91,47 @@ function formatViewerLinks(links, filePath) {
152
91
  [View diff${fileName ? ` \u2014 ${fileName}` : ""}](${links.diff})`;
153
92
  return text;
154
93
  }
155
- function formatToolCall(tool, verbosity = "medium") {
156
- const si = STATUS_ICONS[tool.status || ""] || "\u{1F527}";
157
- const name = tool.name || "Tool";
158
- const label = verbosity === "low" ? formatToolTitle(name, tool.rawInput) : formatToolSummary(name, tool.rawInput);
159
- let text = `${si} **${label}**`;
160
- text += formatViewerLinks(tool.viewerLinks, tool.viewerFilePath);
161
- if (verbosity === "high" || verbosity === "medium" && !tool.viewerLinks) {
162
- const details = stripCodeFences(extractContentText(tool.content));
163
- if (details) {
94
+ function formatHighDetails(rawInput, content, maxLen) {
95
+ let text = "";
96
+ if (rawInput) {
97
+ const inputStr = typeof rawInput === "string" ? rawInput : JSON.stringify(rawInput, null, 2);
98
+ if (inputStr && inputStr !== "{}") {
164
99
  text += `
100
+ **Input:**
165
101
  \`\`\`
166
- ${truncateContent(details, 500)}
102
+ ${truncateContent(inputStr, maxLen)}
167
103
  \`\`\``;
168
104
  }
169
105
  }
106
+ const details = stripCodeFences(extractContentText(content));
107
+ if (details) {
108
+ text += `
109
+ **Output:**
110
+ \`\`\`
111
+ ${truncateContent(details, maxLen)}
112
+ \`\`\``;
113
+ }
114
+ return text;
115
+ }
116
+ function formatToolCall(tool, verbosity = "medium") {
117
+ const si = resolveToolIcon(tool);
118
+ const name = tool.name || "Tool";
119
+ const label = verbosity === "low" ? formatToolTitle(name, tool.rawInput, tool.displayTitle) : formatToolSummary(name, tool.rawInput, tool.displaySummary);
120
+ let text = `${si} **${label}**`;
121
+ text += formatViewerLinks(tool.viewerLinks, tool.viewerFilePath);
122
+ if (verbosity === "high") {
123
+ text += formatHighDetails(tool.rawInput, tool.content, 500);
124
+ }
170
125
  return text;
171
126
  }
172
127
  function formatToolUpdate(update, verbosity = "medium") {
173
128
  return formatToolCall(update, verbosity);
174
129
  }
175
- function formatPlan(entries) {
130
+ function formatPlan(entries, verbosity = "medium") {
131
+ if (verbosity === "medium") {
132
+ const done = entries.filter((e) => e.status === "completed").length;
133
+ return `\u{1F4CB} **Plan:** ${done}/${entries.length} steps completed`;
134
+ }
176
135
  const statusIcon = {
177
136
  pending: "\u23F3",
178
137
  in_progress: "\u{1F504}",
@@ -184,112 +143,186 @@ function formatPlan(entries) {
184
143
  return `**Plan:**
185
144
  ${lines.join("\n")}`;
186
145
  }
187
- function formatUsage(usage) {
188
- const { tokensUsed, contextSize } = usage;
146
+ function formatUsage(usage, verbosity = "medium") {
147
+ const { tokensUsed, contextSize, cost } = usage;
189
148
  if (tokensUsed == null) return "\u{1F4CA} Usage data unavailable";
149
+ if (verbosity === "medium") {
150
+ const costStr = cost != null ? ` \xB7 $${cost.toFixed(2)}` : "";
151
+ return `\u{1F4CA} ${formatTokens(tokensUsed)} tokens${costStr}`;
152
+ }
190
153
  if (contextSize == null) return `\u{1F4CA} ${formatTokens(tokensUsed)} tokens`;
191
154
  const ratio = tokensUsed / contextSize;
192
155
  const pct = Math.round(ratio * 100);
193
156
  const bar = progressBar(ratio);
194
157
  const emoji = pct >= 85 ? "\u26A0\uFE0F" : "\u{1F4CA}";
195
- return `${emoji} ${formatTokens(tokensUsed)} / ${formatTokens(contextSize)} tokens
158
+ let text = `${emoji} ${formatTokens(tokensUsed)} / ${formatTokens(contextSize)} tokens
196
159
  ${bar} ${pct}%`;
160
+ if (cost != null) text += `
161
+ \u{1F4B0} $${cost.toFixed(2)}`;
162
+ return text;
197
163
  }
198
164
  function splitMessage2(text, maxLength = 1800) {
199
165
  return splitMessage(text, maxLength);
200
166
  }
201
167
 
202
- // src/adapters/discord/tool-call-tracker.ts
203
- var ToolCallTracker = class {
168
+ // src/plugins/discord/renderer.ts
169
+ var DiscordRenderer = class extends BaseRenderer {
170
+ renderToolCall(content, verbosity) {
171
+ const meta = content.metadata ?? {};
172
+ return { body: formatToolCall(meta, verbosity), format: "markdown" };
173
+ }
174
+ renderToolUpdate(content, verbosity) {
175
+ const meta = content.metadata ?? {};
176
+ return { body: formatToolUpdate(meta, verbosity), format: "markdown" };
177
+ }
178
+ renderPlan(content, verbosity) {
179
+ const entries = content.metadata?.entries ?? [];
180
+ return { body: formatPlan(entries, verbosity), format: "markdown" };
181
+ }
182
+ renderUsage(content, verbosity) {
183
+ const meta = content.metadata;
184
+ return { body: formatUsage(meta ?? {}, verbosity), format: "markdown" };
185
+ }
186
+ renderError(content) {
187
+ return { body: `\u274C **Error:** ${content.text}`, format: "markdown" };
188
+ }
189
+ renderNotification(notification) {
190
+ const emoji = {
191
+ completed: "\u2705",
192
+ error: "\u274C",
193
+ permission: "\u{1F510}",
194
+ input_required: "\u{1F4AC}",
195
+ budget_warning: "\u26A0\uFE0F"
196
+ };
197
+ const icon = emoji[notification.type] || "\u2139\uFE0F";
198
+ const name = notification.sessionName ? ` **${notification.sessionName}**` : "";
199
+ let text = `${icon}${name}: ${notification.summary}`;
200
+ if (notification.deepLink) {
201
+ text += `
202
+ ${notification.deepLink}`;
203
+ }
204
+ return { body: text, format: "markdown" };
205
+ }
206
+ renderSystemMessage(content) {
207
+ return { body: content.text, format: "markdown" };
208
+ }
209
+ renderSessionEnd(_content) {
210
+ return { body: "\u2705 Done", format: "markdown" };
211
+ }
212
+ renderModeChange(content) {
213
+ const modeId = content.metadata?.modeId ?? "";
214
+ return { body: `\u{1F504} **Mode:** ${modeId}`, format: "markdown" };
215
+ }
216
+ renderConfigUpdate() {
217
+ return { body: "\u2699\uFE0F **Config updated**", format: "markdown" };
218
+ }
219
+ renderModelUpdate(content) {
220
+ const modelId = content.metadata?.modelId ?? "";
221
+ return { body: `\u{1F916} **Model:** ${modelId}`, format: "markdown" };
222
+ }
223
+ };
224
+
225
+ // src/plugins/discord/tool-call-tracker.ts
226
+ var log2 = createChildLogger({ module: "discord-tool-call-tracker" });
227
+ var DiscordToolCallTracker = class {
204
228
  constructor(sendQueue) {
205
229
  this.sendQueue = sendQueue;
206
230
  }
207
- sessions = /* @__PURE__ */ new Map();
231
+ tracker = new ToolCallTracker();
232
+ /** Platform-specific ready-promise + message per tool call, keyed by `${sessionId}:${toolId}`. */
233
+ platformState = /* @__PURE__ */ new Map();
208
234
  async trackNewCall(sessionId, thread, tool, verbosity = "medium") {
209
- if (!this.sessions.has(sessionId)) {
210
- this.sessions.set(sessionId, /* @__PURE__ */ new Map());
211
- }
212
235
  let resolveReady;
213
236
  const ready = new Promise((r) => {
214
237
  resolveReady = r;
215
238
  });
216
- const state = {
217
- message: void 0,
218
- name: tool.name,
219
- kind: tool.kind,
220
- rawInput: tool.rawInput,
221
- viewerLinks: tool.viewerLinks,
222
- viewerFilePath: tool.viewerFilePath,
223
- ready
224
- };
225
- this.sessions.get(sessionId).set(tool.id, state);
239
+ const key = `${sessionId}:${tool.id}`;
240
+ this.platformState.set(key, { message: void 0, ready });
241
+ this.tracker.track(sessionId, tool, "0");
226
242
  const content = formatToolCall(tool, verbosity);
227
243
  try {
228
244
  const msg = await this.sendQueue.enqueue(() => thread.send({ content }), {
229
245
  type: "other"
230
246
  });
231
- if (msg) state.message = msg;
247
+ if (msg) {
248
+ const state = this.platformState.get(key);
249
+ if (state) state.message = msg;
250
+ }
232
251
  } catch (err) {
233
- log.warn(
252
+ log2.warn(
234
253
  { err, toolId: tool.id },
235
- "[ToolCallTracker] trackNewCall() send failed"
254
+ "trackNewCall() send failed"
236
255
  );
237
256
  } finally {
238
257
  resolveReady();
239
258
  }
240
259
  }
241
260
  async updateCall(sessionId, update, verbosity = "medium") {
242
- const toolState = this.sessions.get(sessionId)?.get(update.id);
243
- if (!toolState) return;
244
- if (update.viewerLinks) toolState.viewerLinks = update.viewerLinks;
245
- if (update.viewerFilePath) toolState.viewerFilePath = update.viewerFilePath;
246
- if (update.name) toolState.name = update.name;
247
- if (update.kind) toolState.kind = update.kind;
261
+ const key = `${sessionId}:${update.id}`;
262
+ const state = this.platformState.get(key);
263
+ const tracked = this.tracker.update(sessionId, update.id, update.status, {
264
+ viewerLinks: update.viewerLinks,
265
+ viewerFilePath: update.viewerFilePath,
266
+ name: update.name,
267
+ kind: update.kind
268
+ });
269
+ if (!tracked) return;
248
270
  const isTerminal = update.status === "completed" || update.status === "failed";
249
271
  if (!isTerminal) return;
250
- await toolState.ready;
251
- if (!toolState.message) return;
252
- log.debug(
272
+ if (state) {
273
+ await state.ready;
274
+ }
275
+ if (!state?.message) return;
276
+ log2.debug(
253
277
  {
254
278
  toolId: update.id,
255
279
  status: update.status,
256
- hasViewerLinks: !!toolState.viewerLinks,
257
- name: toolState.name,
258
- msgId: toolState.message.id
280
+ hasViewerLinks: !!tracked.viewerLinks,
281
+ name: tracked.name,
282
+ msgId: state.message.id
259
283
  },
260
- "[ToolCallTracker] Tool completed, preparing edit"
284
+ "Tool completed, preparing edit"
261
285
  );
262
286
  const merged = {
263
- ...update,
264
- name: toolState.name,
265
- kind: toolState.kind,
266
- rawInput: toolState.rawInput,
267
- viewerLinks: toolState.viewerLinks,
268
- viewerFilePath: toolState.viewerFilePath
287
+ id: update.id,
288
+ name: tracked.name,
289
+ kind: tracked.kind,
290
+ rawInput: tracked.rawInput,
291
+ viewerLinks: tracked.viewerLinks,
292
+ viewerFilePath: tracked.viewerFilePath,
293
+ displaySummary: tracked.displaySummary,
294
+ displayTitle: tracked.displayTitle,
295
+ displayKind: tracked.displayKind,
296
+ status: update.status,
297
+ content: update.content
269
298
  };
270
299
  const content = formatToolUpdate(merged, verbosity);
271
300
  try {
272
- await this.sendQueue.enqueue(() => toolState.message.edit({ content }), {
301
+ await this.sendQueue.enqueue(() => state.message.edit({ content }), {
273
302
  type: "other"
274
303
  });
275
304
  } catch (err) {
276
- log.warn(
305
+ log2.warn(
277
306
  {
278
307
  err,
279
- msgId: toolState.message.id,
308
+ msgId: state.message.id,
280
309
  contentLen: content.length,
281
310
  hasViewerLinks: !!merged.viewerLinks
282
311
  },
283
- "[ToolCallTracker] Tool update edit failed"
312
+ "Tool update edit failed"
284
313
  );
285
314
  }
286
315
  }
287
316
  cleanup(sessionId) {
288
- this.sessions.delete(sessionId);
317
+ const active = this.tracker.getActive(sessionId);
318
+ for (const tool of active) {
319
+ this.platformState.delete(`${sessionId}:${tool.id}`);
320
+ }
321
+ this.tracker.clear(sessionId);
289
322
  }
290
323
  };
291
324
 
292
- // src/adapters/discord/streaming.ts
325
+ // src/plugins/discord/streaming.ts
293
326
  var FLUSH_INTERVAL = 5e3;
294
327
  var MAX_DISPLAY_LENGTH = 1900;
295
328
  var MessageDraft = class {
@@ -438,8 +471,8 @@ var MessageDraft = class {
438
471
  }
439
472
  };
440
473
 
441
- // src/adapters/discord/draft-manager.ts
442
- var DraftManager = class {
474
+ // src/plugins/discord/draft-manager.ts
475
+ var DiscordDraftManager = class {
443
476
  constructor(sendQueue) {
444
477
  this.sendQueue = sendQueue;
445
478
  }
@@ -499,7 +532,7 @@ var DraftManager = class {
499
532
  }
500
533
  };
501
534
 
502
- // src/adapters/discord/activity.ts
535
+ // src/plugins/discord/activity.ts
503
536
  import { EmbedBuilder } from "discord.js";
504
537
  var TYPING_REFRESH_MS = 8e3;
505
538
  var ThinkingIndicator = class {
@@ -548,8 +581,8 @@ var UsageMessage = class {
548
581
  this.sendQueue = sendQueue;
549
582
  }
550
583
  message;
551
- async send(usage) {
552
- const text = formatUsage(usage);
584
+ async send(usage, verbosity = "medium") {
585
+ const text = formatUsage(usage, verbosity);
553
586
  const embed = new EmbedBuilder().setDescription(text);
554
587
  try {
555
588
  if (this.message) {
@@ -573,10 +606,7 @@ var UsageMessage = class {
573
606
  const msg = this.message;
574
607
  this.message = void 0;
575
608
  try {
576
- await this.sendQueue.enqueue(
577
- () => msg.delete(),
578
- { type: "other" }
579
- );
609
+ await this.sendQueue.enqueue(() => msg.delete(), { type: "other" });
580
610
  } catch (err) {
581
611
  log.warn({ err }, "[UsageMessage] delete() failed");
582
612
  }
@@ -593,6 +623,10 @@ var PlanCard = class {
593
623
  latestEntries;
594
624
  lastSentText;
595
625
  flushTimer;
626
+ verbosity = "medium";
627
+ setVerbosity(v) {
628
+ this.verbosity = v;
629
+ }
596
630
  update(entries) {
597
631
  this.latestEntries = entries;
598
632
  if (this.flushTimer) clearTimeout(this.flushTimer);
@@ -621,7 +655,7 @@ var PlanCard = class {
621
655
  }
622
656
  async _flush() {
623
657
  if (!this.latestEntries) return;
624
- const text = formatPlan(this.latestEntries);
658
+ const text = formatPlan(this.latestEntries, this.verbosity);
625
659
  if (this.message && text === this.lastSentText) return;
626
660
  this.lastSentText = text;
627
661
  const embed = new EmbedBuilder().setDescription(text);
@@ -675,14 +709,15 @@ var ActivityTracker = class {
675
709
  this.thinking.dismiss();
676
710
  this.thinking.reset();
677
711
  }
678
- async onPlan(entries) {
712
+ async onPlan(entries, verbosity) {
679
713
  await this._firstEventGuard();
680
714
  this.thinking.dismiss();
681
715
  this.hasPlanCard = true;
716
+ if (verbosity) this.planCard.setVerbosity(verbosity);
682
717
  this.planCard.update(entries);
683
718
  }
684
- async sendUsage(usage) {
685
- await this.usage.send(usage);
719
+ async sendUsage(usage, verbosity = "medium") {
720
+ await this.usage.send(usage, verbosity);
686
721
  }
687
722
  async cleanup() {
688
723
  this.thinking.dismiss();
@@ -698,7 +733,7 @@ var ActivityTracker = class {
698
733
  }
699
734
  };
700
735
 
701
- // src/adapters/discord/skill-command-manager.ts
736
+ // src/plugins/discord/skill-command-manager.ts
702
737
  var DISCORD_MSG_LIMIT = 1900;
703
738
  function buildSkillContent(commands) {
704
739
  const sorted = [...commands].sort((a, b) => a.name.localeCompare(b.name));
@@ -792,7 +827,7 @@ var SkillCommandManager = class {
792
827
  }
793
828
  };
794
829
 
795
- // src/adapters/discord/permissions.ts
830
+ // src/plugins/discord/permissions.ts
796
831
  import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
797
832
  import { nanoid } from "nanoid";
798
833
  var PermissionHandler = class {
@@ -879,10 +914,10 @@ ${request.description}`,
879
914
  }
880
915
  };
881
916
 
882
- // src/adapters/discord/commands/index.ts
917
+ // src/plugins/discord/commands/index.ts
883
918
  import { SlashCommandBuilder } from "discord.js";
884
919
 
885
- // src/adapters/discord/commands/menu.ts
920
+ // src/plugins/discord/commands/menu.ts
886
921
  import {
887
922
  ActionRowBuilder as ActionRowBuilder2,
888
923
  ButtonBuilder as ButtonBuilder2,
@@ -973,12 +1008,12 @@ async function handleMenuButton(interaction, adapter) {
973
1008
  try {
974
1009
  switch (customId) {
975
1010
  case "m:new": {
976
- const { handleNew: handleNew2 } = await import("./new-session-FEO4J4VU.js");
1011
+ const { handleNew: handleNew2 } = await import("./new-session-AVQCNXRG.js");
977
1012
  await interaction.followUp({ content: "Use `/new` to create a new session.", ephemeral: true });
978
1013
  break;
979
1014
  }
980
1015
  case "m:sessions": {
981
- const { handleSessions: handleSessions2 } = await import("./session-IUSI7P5S.js");
1016
+ const { handleSessions: handleSessions2 } = await import("./session-KZFA6Z26.js");
982
1017
  await showSessionsList(interaction, adapter);
983
1018
  break;
984
1019
  }
@@ -987,12 +1022,12 @@ async function handleMenuButton(interaction, adapter) {
987
1022
  break;
988
1023
  }
989
1024
  case "m:agents": {
990
- const { showAgentsList } = await import("./agents-QO7DKARJ.js");
1025
+ const { showAgentsList } = await import("./agents-BWU4MRRD.js");
991
1026
  await showAgentsList(interaction, adapter);
992
1027
  break;
993
1028
  }
994
1029
  case "m:settings": {
995
- const { showSettingsInfo } = await import("./settings-RQPAM4KC.js");
1030
+ const { showSettingsInfo } = await import("./settings-MFYM7CZO.js");
996
1031
  await showSettingsInfo(interaction, adapter);
997
1032
  break;
998
1033
  }
@@ -1001,7 +1036,7 @@ async function handleMenuButton(interaction, adapter) {
1001
1036
  break;
1002
1037
  }
1003
1038
  case "m:restart": {
1004
- const { handleRestart: handleRestart2 } = await import("./admin-6SYB6XCZ.js");
1039
+ const { handleRestart: handleRestart2 } = await import("./admin-GBPZFFAU.js");
1005
1040
  if (!adapter.core.requestRestart) {
1006
1041
  await interaction.followUp({ content: "\u26A0\uFE0F Restart not available.", ephemeral: true });
1007
1042
  } else {
@@ -1020,7 +1055,7 @@ async function handleMenuButton(interaction, adapter) {
1020
1055
  break;
1021
1056
  }
1022
1057
  case "m:doctor": {
1023
- const { runDoctorInline } = await import("./doctor-OLYBO3V3.js");
1058
+ const { runDoctorInline } = await import("./doctor-RF6BHMCC.js");
1024
1059
  await runDoctorInline(interaction, adapter);
1025
1060
  break;
1026
1061
  }
@@ -1097,7 +1132,7 @@ ${lines.join("\n")}${truncated}`,
1097
1132
  });
1098
1133
  }
1099
1134
 
1100
- // src/adapters/discord/commands/integrate.ts
1135
+ // src/plugins/discord/commands/integrate.ts
1101
1136
  async function handleIntegrate(interaction, _adapter) {
1102
1137
  await interaction.deferReply({ ephemeral: true });
1103
1138
  await interaction.editReply(
@@ -1115,7 +1150,7 @@ async function handleIntegrateButton(interaction, _adapter) {
1115
1150
  }
1116
1151
  }
1117
1152
 
1118
- // src/adapters/discord/commands/router.ts
1153
+ // src/plugins/discord/commands/router.ts
1119
1154
  async function handleSlashCommand(interaction, adapter) {
1120
1155
  const { commandName } = interaction;
1121
1156
  try {
@@ -1213,7 +1248,7 @@ async function setupButtonCallbacks(interaction, adapter) {
1213
1248
  return;
1214
1249
  }
1215
1250
  if (customId.startsWith("a:")) {
1216
- const { getAction, removeAction } = await import("./action-detect-P7ZE4NEM.js");
1251
+ const { getAction, removeAction } = await import("./action-detect-QPA775HB.js");
1217
1252
  const actionId = customId.slice(2);
1218
1253
  const action = getAction(actionId);
1219
1254
  if (!action) {
@@ -1296,15 +1331,15 @@ async function setupButtonCallbacks(interaction, adapter) {
1296
1331
  }
1297
1332
  }
1298
1333
  async function executeNewSession(interaction, adapter, agentName, workspace) {
1299
- const { executeNewSession: doExecute } = await import("./new-session-FEO4J4VU.js");
1334
+ const { executeNewSession: doExecute } = await import("./new-session-AVQCNXRG.js");
1300
1335
  await doExecute(interaction, adapter, agentName, workspace);
1301
1336
  }
1302
1337
  async function executeCancelSession(interaction, adapter) {
1303
- const { executeCancelSession: doCancel } = await import("./session-IUSI7P5S.js");
1338
+ const { executeCancelSession: doCancel } = await import("./session-KZFA6Z26.js");
1304
1339
  await doCancel(interaction, adapter);
1305
1340
  }
1306
1341
 
1307
- // src/adapters/discord/commands/index.ts
1342
+ // src/plugins/discord/commands/index.ts
1308
1343
  var SLASH_COMMANDS = [
1309
1344
  new SlashCommandBuilder().setName("new").setDescription("Create a new agent session").addStringOption(
1310
1345
  (o) => o.setName("agent").setDescription("Agent to use").setRequired(false)
@@ -1348,7 +1383,7 @@ async function registerSlashCommands(guild) {
1348
1383
  await guild.commands.set(SLASH_COMMANDS.map((cmd) => cmd.toJSON()));
1349
1384
  }
1350
1385
 
1351
- // src/adapters/discord/assistant.ts
1386
+ // src/plugins/discord/assistant.ts
1352
1387
  async function spawnAssistant(core, threadId) {
1353
1388
  const config = core.configManager.get();
1354
1389
  log.info({ agent: config.defaultAgent, threadId }, "[discord-assistant] Creating assistant session...");
@@ -1518,7 +1553,7 @@ openacp api restart # Restart daemon
1518
1553
  ${PRODUCT_GUIDE}`;
1519
1554
  }
1520
1555
 
1521
- // src/adapters/discord/media.ts
1556
+ // src/plugins/discord/media.ts
1522
1557
  var MAX_DOWNLOAD_SIZE = 100 * 1024 * 1024;
1523
1558
  var DISCORD_UPLOAD_LIMIT = 25 * 1024 * 1024;
1524
1559
  function isAttachmentTooLarge(size) {
@@ -1549,8 +1584,19 @@ async function downloadDiscordAttachment(url, fileName) {
1549
1584
  }
1550
1585
  }
1551
1586
 
1552
- // src/adapters/discord/adapter.ts
1553
- var DiscordAdapter = class extends ChannelAdapter {
1587
+ // src/plugins/discord/adapter.ts
1588
+ var DiscordAdapter = class extends MessagingAdapter {
1589
+ name = "discord";
1590
+ renderer = new DiscordRenderer();
1591
+ capabilities = {
1592
+ streaming: true,
1593
+ richFormatting: true,
1594
+ threads: true,
1595
+ reactions: true,
1596
+ fileUpload: true,
1597
+ voice: false
1598
+ };
1599
+ core;
1554
1600
  client;
1555
1601
  discordConfig;
1556
1602
  sendQueue;
@@ -1559,17 +1605,20 @@ var DiscordAdapter = class extends ChannelAdapter {
1559
1605
  skillManager;
1560
1606
  permissionHandler;
1561
1607
  sessionTrackers = /* @__PURE__ */ new Map();
1562
- get verbosity() {
1563
- return this.discordConfig.displayVerbosity ?? "medium";
1564
- }
1565
1608
  guild;
1566
1609
  forumChannel;
1567
1610
  notificationChannel;
1568
1611
  assistantSession = null;
1569
1612
  assistantInitializing = false;
1570
1613
  fileService;
1614
+ // Per-session thread context for concurrency safety in sendMessage handlers
1615
+ _sessionContexts = /* @__PURE__ */ new Map();
1571
1616
  constructor(core, config) {
1572
- super(core, config);
1617
+ super(
1618
+ { configManager: core.configManager },
1619
+ { ...config, maxMessageLength: 2e3, enabled: config.enabled ?? true }
1620
+ );
1621
+ this.core = core;
1573
1622
  this.discordConfig = config;
1574
1623
  this.client = new Client({
1575
1624
  intents: [
@@ -1578,12 +1627,15 @@ var DiscordAdapter = class extends ChannelAdapter {
1578
1627
  GatewayIntentBits.MessageContent
1579
1628
  ]
1580
1629
  });
1581
- this.sendQueue = new DiscordSendQueue();
1582
- this.toolTracker = new ToolCallTracker(this.sendQueue);
1583
- this.draftManager = new DraftManager(this.sendQueue);
1630
+ this.sendQueue = new SendQueue({ minInterval: 1e3 });
1631
+ this.toolTracker = new DiscordToolCallTracker(this.sendQueue);
1632
+ this.draftManager = new DiscordDraftManager(this.sendQueue);
1584
1633
  this.fileService = core.fileService;
1585
1634
  this.client.rest.on("rateLimited", (info) => {
1586
- log.warn({ route: info.route, timeToReset: info.timeToReset }, "[DiscordAdapter] Rate limited");
1635
+ log.warn(
1636
+ { route: info.route, timeToReset: info.timeToReset },
1637
+ "[DiscordAdapter] Rate limited"
1638
+ );
1587
1639
  this.sendQueue.onRateLimited();
1588
1640
  });
1589
1641
  }
@@ -1592,13 +1644,18 @@ var DiscordAdapter = class extends ChannelAdapter {
1592
1644
  return new Promise((resolve, reject) => {
1593
1645
  this.client.once("ready", async () => {
1594
1646
  try {
1595
- log.info({ guildId: this.discordConfig.guildId }, "[DiscordAdapter] Client ready, initializing...");
1647
+ log.info(
1648
+ { guildId: this.discordConfig.guildId },
1649
+ "[DiscordAdapter] Client ready, initializing..."
1650
+ );
1596
1651
  const guild = this.client.guilds.cache.get(this.discordConfig.guildId) ?? await this.client.guilds.fetch(this.discordConfig.guildId).catch(() => null);
1597
1652
  if (!guild) {
1598
1653
  throw new Error(`Guild not found: ${this.discordConfig.guildId}`);
1599
1654
  }
1600
1655
  this.guild = guild;
1601
- const saveConfig = (updates) => this.core.configManager.save(updates);
1656
+ const saveConfig = (updates) => this.core.configManager.save(
1657
+ updates
1658
+ );
1602
1659
  const { forumChannel, notificationChannel } = await ensureForums(
1603
1660
  guild,
1604
1661
  {
@@ -1609,7 +1666,10 @@ var DiscordAdapter = class extends ChannelAdapter {
1609
1666
  );
1610
1667
  this.forumChannel = forumChannel;
1611
1668
  this.notificationChannel = notificationChannel;
1612
- this.skillManager = new SkillCommandManager(this.sendQueue, this.core.sessionManager);
1669
+ this.skillManager = new SkillCommandManager(
1670
+ this.sendQueue,
1671
+ this.core.sessionManager
1672
+ );
1613
1673
  this.permissionHandler = new PermissionHandler(
1614
1674
  guild.id,
1615
1675
  (sessionId) => this.core.sessionManager.getSession(sessionId),
@@ -1622,7 +1682,10 @@ var DiscordAdapter = class extends ChannelAdapter {
1622
1682
  try {
1623
1683
  await this.notificationChannel.send(welcomeMsg);
1624
1684
  } catch (err) {
1625
- log.warn({ err }, "[DiscordAdapter] Failed to send welcome message");
1685
+ log.warn(
1686
+ { err },
1687
+ "[DiscordAdapter] Failed to send welcome message"
1688
+ );
1626
1689
  }
1627
1690
  await this.setupAssistant();
1628
1691
  log.info("[DiscordAdapter] Initialization complete");
@@ -1641,7 +1704,10 @@ var DiscordAdapter = class extends ChannelAdapter {
1641
1704
  try {
1642
1705
  await this.assistantSession.destroy();
1643
1706
  } catch (err) {
1644
- log.warn({ err }, "[DiscordAdapter] Failed to destroy assistant session");
1707
+ log.warn(
1708
+ { err },
1709
+ "[DiscordAdapter] Failed to destroy assistant session"
1710
+ );
1645
1711
  }
1646
1712
  this.assistantSession = null;
1647
1713
  }
@@ -1649,14 +1715,84 @@ var DiscordAdapter = class extends ChannelAdapter {
1649
1715
  log.info("[DiscordAdapter] Stopped");
1650
1716
  }
1651
1717
  // ─── Interaction handler ──────────────────────────────────────────────────
1718
+ getCommandRegistry() {
1719
+ return this.core.lifecycleManager?.serviceRegistry?.get("command-registry");
1720
+ }
1652
1721
  setupInteractionHandler() {
1653
1722
  this.client.on("interactionCreate", async (interaction) => {
1654
1723
  try {
1655
1724
  if (interaction.isChatInputCommand()) {
1725
+ const registry = this.getCommandRegistry();
1726
+ if (registry) {
1727
+ const commandName = interaction.commandName;
1728
+ const def = registry.get(commandName);
1729
+ if (def) {
1730
+ const rawParts = [];
1731
+ for (const opt of interaction.options.data) {
1732
+ rawParts.push(String(opt.value ?? ""));
1733
+ }
1734
+ const channelId = interaction.channelId;
1735
+ const sessionId = this.core.sessionManager.getSessionByThread("discord", channelId)?.id ?? null;
1736
+ const response = await registry.execute(
1737
+ `/${commandName} ${rawParts.join(" ")}`.trim(),
1738
+ {
1739
+ raw: "",
1740
+ sessionId,
1741
+ channelId: "discord",
1742
+ userId: interaction.user.id,
1743
+ options: Object.fromEntries(
1744
+ interaction.options.data.map((o) => [o.name, String(o.value ?? "")])
1745
+ ),
1746
+ reply: async (content) => {
1747
+ if (typeof content === "string") {
1748
+ if (interaction.replied || interaction.deferred) {
1749
+ await interaction.editReply({ content });
1750
+ } else {
1751
+ await interaction.reply({ content });
1752
+ }
1753
+ }
1754
+ }
1755
+ }
1756
+ );
1757
+ if (response.type !== "silent") {
1758
+ await this.renderCommandResponse(response, interaction);
1759
+ } else if (!interaction.replied && !interaction.deferred) {
1760
+ await interaction.deferReply();
1761
+ }
1762
+ return;
1763
+ }
1764
+ }
1656
1765
  await handleSlashCommand(interaction, this);
1657
1766
  return;
1658
1767
  }
1659
1768
  if (interaction.isButton()) {
1769
+ if (interaction.customId.startsWith("c/")) {
1770
+ const registry = this.getCommandRegistry();
1771
+ if (registry) {
1772
+ const command = interaction.customId.slice(2);
1773
+ const channelId = interaction.channelId;
1774
+ const sessionId = this.core.sessionManager.getSessionByThread("discord", channelId)?.id ?? null;
1775
+ const response = await registry.execute(command, {
1776
+ raw: "",
1777
+ sessionId,
1778
+ channelId: "discord",
1779
+ userId: interaction.user.id,
1780
+ reply: async (content) => {
1781
+ if (typeof content === "string") {
1782
+ if (interaction.replied || interaction.deferred) {
1783
+ await interaction.editReply({ content });
1784
+ } else {
1785
+ await interaction.reply({ content, ephemeral: true });
1786
+ }
1787
+ }
1788
+ }
1789
+ });
1790
+ if (response.type !== "silent") {
1791
+ await this.renderCommandResponse(response, interaction);
1792
+ }
1793
+ return;
1794
+ }
1795
+ }
1660
1796
  const handled = await this.permissionHandler.handleButtonInteraction(interaction);
1661
1797
  if (!handled) {
1662
1798
  await setupButtonCallbacks(interaction, this);
@@ -1667,6 +1803,59 @@ var DiscordAdapter = class extends ChannelAdapter {
1667
1803
  }
1668
1804
  });
1669
1805
  }
1806
+ // ─── CommandRegistry response rendering ──────────────────────────────────
1807
+ async renderCommandResponse(response, interaction) {
1808
+ const reply = async (opts) => {
1809
+ if (interaction.replied || interaction.deferred) {
1810
+ await interaction.editReply(opts);
1811
+ } else {
1812
+ await interaction.reply(opts);
1813
+ }
1814
+ };
1815
+ switch (response.type) {
1816
+ case "text":
1817
+ await reply({ content: response.text });
1818
+ break;
1819
+ case "error":
1820
+ await reply({ content: `\u26A0\uFE0F ${response.message}`, ephemeral: true });
1821
+ break;
1822
+ case "menu": {
1823
+ const { ActionRowBuilder: ActionRowBuilder3, ButtonBuilder: ButtonBuilder3, ButtonStyle: ButtonStyle3, EmbedBuilder: EmbedBuilder2 } = await import("discord.js");
1824
+ const embed = new EmbedBuilder2().setTitle(response.title);
1825
+ const rows = [];
1826
+ for (let i = 0; i < response.options.length && rows.length < 5; i += 5) {
1827
+ const row = new ActionRowBuilder3();
1828
+ const slice = response.options.slice(i, i + 5);
1829
+ for (const opt of slice) {
1830
+ row.addComponents(
1831
+ new ButtonBuilder3().setCustomId(`c/${opt.command}`).setLabel(opt.label.slice(0, 80)).setStyle(ButtonStyle3.Secondary)
1832
+ );
1833
+ }
1834
+ rows.push(row);
1835
+ }
1836
+ await reply({ embeds: [embed], components: rows });
1837
+ break;
1838
+ }
1839
+ case "list": {
1840
+ const { EmbedBuilder: EmbedBuilder2 } = await import("discord.js");
1841
+ const desc = response.items.map((i) => `\u2022 **${i.label}**${i.detail ? ` \u2014 ${i.detail}` : ""}`).join("\n");
1842
+ const embed = new EmbedBuilder2().setTitle(response.title).setDescription(desc);
1843
+ await reply({ embeds: [embed] });
1844
+ break;
1845
+ }
1846
+ case "confirm": {
1847
+ const { ActionRowBuilder: ActionRowBuilder3, ButtonBuilder: ButtonBuilder3, ButtonStyle: ButtonStyle3 } = await import("discord.js");
1848
+ const row = new ActionRowBuilder3().addComponents(
1849
+ new ButtonBuilder3().setCustomId(`c/${response.onYes}`).setLabel("Yes").setStyle(ButtonStyle3.Success),
1850
+ new ButtonBuilder3().setCustomId(`c/${response.onNo || "noop"}`).setLabel("No").setStyle(ButtonStyle3.Secondary)
1851
+ );
1852
+ await reply({ content: response.question, components: [row] });
1853
+ break;
1854
+ }
1855
+ case "silent":
1856
+ break;
1857
+ }
1858
+ }
1670
1859
  // ─── Message handler ──────────────────────────────────────────────────────
1671
1860
  setupMessageHandler() {
1672
1861
  this.client.on("messageCreate", async (message) => {
@@ -1679,7 +1868,12 @@ var DiscordAdapter = class extends ChannelAdapter {
1679
1868
  const userId = message.author.id;
1680
1869
  let text = message.content;
1681
1870
  log.debug(
1682
- { threadId, userId, text: text.slice(0, 50), attachmentCount: message.attachments.size },
1871
+ {
1872
+ threadId,
1873
+ userId,
1874
+ text: text.slice(0, 50),
1875
+ attachmentCount: message.attachments.size
1876
+ },
1683
1877
  "[DiscordAdapter] messageCreate received"
1684
1878
  );
1685
1879
  if (!text && message.attachments.size === 0) return;
@@ -1698,7 +1892,10 @@ var DiscordAdapter = class extends ChannelAdapter {
1698
1892
  "[discord-media] Processing incoming attachments"
1699
1893
  );
1700
1894
  }
1701
- const attachments = await this.processIncomingAttachments(message, sessionId);
1895
+ const attachments = await this.processIncomingAttachments(
1896
+ message,
1897
+ sessionId
1898
+ );
1702
1899
  if (!text && attachments.length > 0) {
1703
1900
  text = buildFallbackText(attachments);
1704
1901
  }
@@ -1711,7 +1908,10 @@ var DiscordAdapter = class extends ChannelAdapter {
1711
1908
  }
1712
1909
  if (this.discordConfig.assistantThreadId && threadId === this.discordConfig.assistantThreadId) {
1713
1910
  if (this.assistantSession && text) {
1714
- await this.assistantSession.enqueuePrompt(text, attachments.length > 0 ? attachments : void 0);
1911
+ await this.assistantSession.enqueuePrompt(
1912
+ text,
1913
+ attachments.length > 0 ? attachments : void 0
1914
+ );
1715
1915
  }
1716
1916
  return;
1717
1917
  }
@@ -1734,14 +1934,25 @@ var DiscordAdapter = class extends ChannelAdapter {
1734
1934
  try {
1735
1935
  const existing = this.guild.channels.cache.get(threadId) ?? await this.guild.channels.fetch(threadId);
1736
1936
  if (existing && existing.isThread()) {
1737
- await ensureUnarchived(existing);
1738
- log.info({ threadId }, "[DiscordAdapter] Reusing existing assistant thread");
1937
+ await ensureUnarchived(
1938
+ existing
1939
+ );
1940
+ log.info(
1941
+ { threadId },
1942
+ "[DiscordAdapter] Reusing existing assistant thread"
1943
+ );
1739
1944
  } else {
1740
- log.warn({ threadId }, "[DiscordAdapter] Assistant thread not found, recreating...");
1945
+ log.warn(
1946
+ { threadId },
1947
+ "[DiscordAdapter] Assistant thread not found, recreating..."
1948
+ );
1741
1949
  threadId = null;
1742
1950
  }
1743
1951
  } catch {
1744
- log.warn({ threadId }, "[DiscordAdapter] Assistant thread inaccessible, recreating...");
1952
+ log.warn(
1953
+ { threadId },
1954
+ "[DiscordAdapter] Assistant thread inaccessible, recreating..."
1955
+ );
1745
1956
  threadId = null;
1746
1957
  }
1747
1958
  }
@@ -1795,7 +2006,10 @@ var DiscordAdapter = class extends ChannelAdapter {
1795
2006
  fileName = "voice.wav";
1796
2007
  mimeType = "audio/wav";
1797
2008
  } catch (err) {
1798
- log.warn({ err }, "[discord-media] OGG\u2192WAV conversion failed, saving original");
2009
+ log.warn(
2010
+ { err },
2011
+ "[discord-media] OGG\u2192WAV conversion failed, saving original"
2012
+ );
1799
2013
  }
1800
2014
  }
1801
2015
  return this.fileService.saveFile(sessionId, fileName, data, mimeType);
@@ -1803,10 +2017,18 @@ var DiscordAdapter = class extends ChannelAdapter {
1803
2017
  );
1804
2018
  const rejected = results.filter((r) => r.status === "rejected");
1805
2019
  if (rejected.length > 0) {
1806
- log.warn({ rejected: rejected.map((r) => r.reason) }, "[discord-media] Some attachments failed");
2020
+ log.warn(
2021
+ { rejected: rejected.map((r) => r.reason) },
2022
+ "[discord-media] Some attachments failed"
2023
+ );
1807
2024
  }
1808
- const saved = results.filter((r) => r.status === "fulfilled").map((r) => r.value).filter((att) => att !== null);
1809
- log.info({ count: saved.length, files: saved.map((a) => a.fileName) }, "[discord-media] Attachments processed");
2025
+ const saved = results.filter(
2026
+ (r) => r.status === "fulfilled"
2027
+ ).map((r) => r.value).filter((att) => att !== null);
2028
+ log.info(
2029
+ { count: saved.length, files: saved.map((a) => a.fileName) },
2030
+ "[discord-media] Attachments processed"
2031
+ );
1810
2032
  return saved;
1811
2033
  }
1812
2034
  // ─── Helper: resolve thread ───────────────────────────────────────────────
@@ -1820,181 +2042,270 @@ var DiscordAdapter = class extends ChannelAdapter {
1820
2042
  try {
1821
2043
  const channel = this.guild.channels.cache.get(threadId) ?? await this.guild.channels.fetch(threadId);
1822
2044
  if (channel && channel.isThread()) return channel;
1823
- log.warn({ sessionId, threadId }, "[DiscordAdapter] Channel is not a thread");
2045
+ log.warn(
2046
+ { sessionId, threadId },
2047
+ "[DiscordAdapter] Channel is not a thread"
2048
+ );
1824
2049
  return null;
1825
2050
  } catch (err) {
1826
- log.warn({ err, sessionId, threadId }, "[DiscordAdapter] Failed to fetch thread");
2051
+ log.warn(
2052
+ { err, sessionId, threadId },
2053
+ "[DiscordAdapter] Failed to fetch thread"
2054
+ );
1827
2055
  return null;
1828
2056
  }
1829
2057
  }
1830
2058
  // ─── Helper: get or create activity tracker ──────────────────────────────
1831
2059
  getOrCreateTracker(sessionId, thread) {
1832
2060
  if (!this.sessionTrackers.has(sessionId)) {
1833
- this.sessionTrackers.set(sessionId, new ActivityTracker(thread, this.sendQueue));
2061
+ this.sessionTrackers.set(
2062
+ sessionId,
2063
+ new ActivityTracker(thread, this.sendQueue)
2064
+ );
1834
2065
  }
1835
2066
  return this.sessionTrackers.get(sessionId);
1836
2067
  }
1837
- // --- MessageHandlers for dispatchMessage ---
1838
- messageHandlers = {
1839
- onThought: async (ctx, _content) => {
1840
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1841
- await tracker.onThought();
1842
- },
1843
- onText: async (ctx, content) => {
1844
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1845
- await tracker.onTextStart();
1846
- const draft = this.draftManager.getOrCreate(ctx.sessionId, ctx.thread);
1847
- draft.append(content.text);
1848
- this.draftManager.appendText(ctx.sessionId, content.text);
1849
- },
1850
- onToolCall: async (ctx, content) => {
1851
- const meta = content.metadata ?? {};
1852
- const toolName = String(meta.name ?? content.text ?? "Tool");
1853
- const toolKind = String(meta.kind ?? "other");
1854
- const noiseAction = evaluateNoise(toolName, toolKind, meta.rawInput);
1855
- if (noiseAction === "hide" && this.verbosity !== "high") return;
1856
- if (noiseAction === "collapse" && this.verbosity === "low") return;
1857
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1858
- await tracker.onToolCall();
1859
- await this.draftManager.finalize(ctx.sessionId, ctx.thread, ctx.isAssistant);
1860
- await this.toolTracker.trackNewCall(ctx.sessionId, ctx.thread, {
2068
+ getSessionContext(sessionId) {
2069
+ const ctx = this._sessionContexts.get(sessionId);
2070
+ if (!ctx) {
2071
+ throw new Error(`No thread context stored for session ${sessionId}`);
2072
+ }
2073
+ return ctx;
2074
+ }
2075
+ // ─── sendMessage ──────────────────────────────────────────────────────────
2076
+ async sendMessage(sessionId, content) {
2077
+ if (this.assistantInitializing && this.assistantSession && sessionId === this.assistantSession.id) {
2078
+ return;
2079
+ }
2080
+ const thread = await this.getThread(sessionId);
2081
+ if (!thread) return;
2082
+ await ensureUnarchived(thread);
2083
+ this._sessionContexts.set(sessionId, {
2084
+ thread,
2085
+ isAssistant: this.assistantSession != null && sessionId === this.assistantSession.id
2086
+ });
2087
+ try {
2088
+ await super.sendMessage(sessionId, content);
2089
+ } finally {
2090
+ this._sessionContexts.delete(sessionId);
2091
+ }
2092
+ }
2093
+ // ─── Handler overrides ─────────────────────────────────────────────────────
2094
+ async handleThought(sessionId, _content, _verbosity) {
2095
+ const { thread } = this.getSessionContext(sessionId);
2096
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2097
+ await tracker.onThought();
2098
+ }
2099
+ async handleText(sessionId, content) {
2100
+ const { thread } = this.getSessionContext(sessionId);
2101
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2102
+ await tracker.onTextStart();
2103
+ const draft = this.draftManager.getOrCreate(sessionId, thread);
2104
+ draft.append(content.text);
2105
+ this.draftManager.appendText(sessionId, content.text);
2106
+ }
2107
+ async handleToolCall(sessionId, content, verbosity) {
2108
+ const { thread, isAssistant } = this.getSessionContext(sessionId);
2109
+ const meta = content.metadata ?? {};
2110
+ const toolName = String(meta.name ?? content.text ?? "Tool");
2111
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2112
+ await tracker.onToolCall();
2113
+ await this.draftManager.finalize(
2114
+ sessionId,
2115
+ thread,
2116
+ isAssistant
2117
+ );
2118
+ await this.toolTracker.trackNewCall(
2119
+ sessionId,
2120
+ thread,
2121
+ {
1861
2122
  id: String(meta.id ?? ""),
1862
2123
  name: toolName,
1863
2124
  kind: meta.kind,
1864
2125
  status: String(meta.status ?? "running"),
1865
2126
  content: meta.content,
2127
+ rawInput: meta.rawInput,
1866
2128
  viewerLinks: meta.viewerLinks,
1867
- viewerFilePath: meta.viewerFilePath
1868
- }, this.verbosity);
1869
- },
1870
- onToolUpdate: async (ctx, content) => {
1871
- const meta = content.metadata ?? {};
1872
- await this.toolTracker.updateCall(ctx.sessionId, {
2129
+ viewerFilePath: meta.viewerFilePath,
2130
+ displaySummary: meta.displaySummary,
2131
+ displayTitle: meta.displayTitle,
2132
+ displayKind: meta.displayKind
2133
+ },
2134
+ verbosity
2135
+ );
2136
+ }
2137
+ async handleToolUpdate(sessionId, content, verbosity) {
2138
+ const meta = content.metadata ?? {};
2139
+ await this.toolTracker.updateCall(
2140
+ sessionId,
2141
+ {
1873
2142
  id: String(meta.id ?? ""),
1874
2143
  name: content.text || String(meta.name ?? ""),
1875
2144
  kind: meta.kind,
1876
2145
  status: String(meta.status ?? "completed"),
1877
2146
  content: meta.content,
2147
+ rawInput: meta.rawInput,
1878
2148
  viewerLinks: meta.viewerLinks,
1879
- viewerFilePath: meta.viewerFilePath
1880
- }, this.verbosity);
1881
- },
1882
- onPlan: async (ctx, content) => {
1883
- const entries = content.metadata?.entries ?? [];
1884
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1885
- await tracker.onPlan(entries);
1886
- },
1887
- onUsage: async (ctx, content) => {
1888
- await this.draftManager.finalize(ctx.sessionId, ctx.thread, ctx.isAssistant);
1889
- const meta = content.metadata ?? {};
1890
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1891
- await tracker.sendUsage({
2149
+ viewerFilePath: meta.viewerFilePath,
2150
+ displaySummary: meta.displaySummary,
2151
+ displayTitle: meta.displayTitle,
2152
+ displayKind: meta.displayKind
2153
+ },
2154
+ verbosity
2155
+ );
2156
+ }
2157
+ async handlePlan(sessionId, content, verbosity) {
2158
+ const { thread } = this.getSessionContext(sessionId);
2159
+ const entries = content.metadata?.entries ?? [];
2160
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2161
+ await tracker.onPlan(entries, verbosity);
2162
+ }
2163
+ async handleUsage(sessionId, content, verbosity) {
2164
+ const { thread, isAssistant } = this.getSessionContext(sessionId);
2165
+ await this.draftManager.finalize(
2166
+ sessionId,
2167
+ thread,
2168
+ isAssistant
2169
+ );
2170
+ const meta = content.metadata ?? {};
2171
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2172
+ await tracker.sendUsage(
2173
+ {
1892
2174
  tokensUsed: meta.tokensUsed,
1893
- contextSize: meta.contextSize
2175
+ contextSize: meta.contextSize,
2176
+ cost: meta.cost
2177
+ },
2178
+ verbosity
2179
+ );
2180
+ try {
2181
+ const deepLink = buildDeepLink(this.guild.id, thread.id);
2182
+ await this.sendNotification({
2183
+ sessionId,
2184
+ type: "completed",
2185
+ summary: content.text || "Session completed",
2186
+ deepLink
1894
2187
  });
1895
- try {
1896
- const deepLink = buildDeepLink(this.guild.id, ctx.thread.id);
1897
- await this.sendNotification({
1898
- sessionId: ctx.sessionId,
1899
- type: "completed",
1900
- summary: content.text || "Session completed",
1901
- deepLink
1902
- });
1903
- } catch {
1904
- }
1905
- },
1906
- onSessionEnd: async (ctx, _content) => {
1907
- await this.draftManager.finalize(ctx.sessionId, ctx.thread, ctx.isAssistant);
1908
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1909
- await tracker.cleanup();
1910
- this.toolTracker.cleanup(ctx.sessionId);
1911
- this.sessionTrackers.delete(ctx.sessionId);
1912
- await this.skillManager.cleanup(ctx.sessionId);
1913
- try {
1914
- await this.sendQueue.enqueue(
1915
- () => ctx.thread.send({ content: "\u2705 Done" }),
1916
- { type: "other" }
1917
- );
1918
- } catch {
1919
- }
1920
- },
1921
- onError: async (ctx, content) => {
1922
- await this.draftManager.finalize(ctx.sessionId, ctx.thread, ctx.isAssistant);
1923
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1924
- await tracker.cleanup();
1925
- this.toolTracker.cleanup(ctx.sessionId);
1926
- this.sessionTrackers.delete(ctx.sessionId);
2188
+ } catch {
2189
+ }
2190
+ }
2191
+ async handleSessionEnd(sessionId, _content) {
2192
+ const { thread, isAssistant } = this.getSessionContext(sessionId);
2193
+ await this.draftManager.finalize(
2194
+ sessionId,
2195
+ thread,
2196
+ isAssistant
2197
+ );
2198
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2199
+ await tracker.cleanup();
2200
+ this.toolTracker.cleanup(sessionId);
2201
+ this.sessionTrackers.delete(sessionId);
2202
+ await this.skillManager.cleanup(sessionId);
2203
+ try {
2204
+ await this.sendQueue.enqueue(
2205
+ () => thread.send({ content: "\u2705 Done" }),
2206
+ { type: "other" }
2207
+ );
2208
+ } catch {
2209
+ }
2210
+ }
2211
+ async handleError(sessionId, content) {
2212
+ const { thread, isAssistant } = this.getSessionContext(sessionId);
2213
+ await this.draftManager.finalize(
2214
+ sessionId,
2215
+ thread,
2216
+ isAssistant
2217
+ );
2218
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2219
+ await tracker.cleanup();
2220
+ this.toolTracker.cleanup(sessionId);
2221
+ this.sessionTrackers.delete(sessionId);
2222
+ try {
2223
+ await this.sendQueue.enqueue(
2224
+ () => thread.send({ content: `\u274C Error: ${content.text}` }),
2225
+ { type: "other" }
2226
+ );
2227
+ } catch {
2228
+ }
2229
+ }
2230
+ async handleAttachment(sessionId, content) {
2231
+ if (!content.attachment) return;
2232
+ const { attachment } = content;
2233
+ const { thread, isAssistant } = this.getSessionContext(sessionId);
2234
+ await this.draftManager.finalize(
2235
+ sessionId,
2236
+ thread,
2237
+ isAssistant
2238
+ );
2239
+ if (isAttachmentTooLarge(attachment.size)) {
2240
+ log.warn(
2241
+ {
2242
+ sessionId,
2243
+ fileName: attachment.fileName,
2244
+ size: attachment.size
2245
+ },
2246
+ "[discord-media] File too large (>25MB)"
2247
+ );
1927
2248
  try {
1928
2249
  await this.sendQueue.enqueue(
1929
- () => ctx.thread.send({ content: `\u274C Error: ${content.text}` }),
2250
+ () => thread.send({
2251
+ content: `\u26A0\uFE0F File too large to send (${Math.round(attachment.size / 1024 / 1024)}MB): ${attachment.fileName}`
2252
+ }),
1930
2253
  { type: "other" }
1931
2254
  );
1932
2255
  } catch {
1933
2256
  }
1934
- },
1935
- onAttachment: async (ctx, content) => {
1936
- if (!content.attachment) return;
1937
- const { attachment } = content;
1938
- await this.draftManager.finalize(ctx.sessionId, ctx.thread, ctx.isAssistant);
1939
- if (isAttachmentTooLarge(attachment.size)) {
1940
- log.warn({ sessionId: ctx.sessionId, fileName: attachment.fileName, size: attachment.size }, "[discord-media] File too large (>25MB)");
1941
- try {
1942
- await this.sendQueue.enqueue(
1943
- () => ctx.thread.send({ content: `\u26A0\uFE0F File too large to send (${Math.round(attachment.size / 1024 / 1024)}MB): ${attachment.fileName}` }),
1944
- { type: "other" }
1945
- );
1946
- } catch {
1947
- }
1948
- return;
1949
- }
1950
- try {
1951
- await this.sendQueue.enqueue(
1952
- () => ctx.thread.send({ files: [{ attachment: attachment.filePath, name: attachment.fileName }] }),
1953
- { type: "other" }
1954
- );
1955
- if (attachment.type === "audio") {
1956
- const draft = this.draftManager.getDraft(ctx.sessionId);
1957
- if (draft) {
1958
- draft.stripPattern(/\[TTS\][\s\S]*?\[\/TTS\]/g).catch(() => {
1959
- });
1960
- }
2257
+ return;
2258
+ }
2259
+ try {
2260
+ await this.sendQueue.enqueue(
2261
+ () => thread.send({
2262
+ files: [
2263
+ { attachment: attachment.filePath, name: attachment.fileName }
2264
+ ]
2265
+ }),
2266
+ { type: "other" }
2267
+ );
2268
+ if (attachment.type === "audio") {
2269
+ const draft = this.draftManager.getDraft(sessionId);
2270
+ if (draft) {
2271
+ draft.stripPattern(/\[TTS\][\s\S]*?\[\/TTS\]/g).catch(() => {
2272
+ });
1961
2273
  }
1962
- } catch (err) {
1963
- log.error({ err, sessionId: ctx.sessionId, fileName: attachment.fileName }, "[discord-media] Failed to send attachment");
1964
- }
1965
- },
1966
- onSystemMessage: async (ctx, content) => {
1967
- try {
1968
- await this.sendQueue.enqueue(
1969
- () => ctx.thread.send({ content: content.text }),
1970
- { type: "other" }
1971
- );
1972
- } catch {
1973
2274
  }
2275
+ } catch (err) {
2276
+ log.error(
2277
+ { err, sessionId, fileName: attachment.fileName },
2278
+ "[discord-media] Failed to send attachment"
2279
+ );
1974
2280
  }
1975
- };
1976
- // ─── sendMessage ──────────────────────────────────────────────────────────
1977
- async sendMessage(sessionId, content) {
1978
- if (this.assistantInitializing && this.assistantSession && sessionId === this.assistantSession.id) {
1979
- return;
2281
+ }
2282
+ async handleSystem(sessionId, content) {
2283
+ const { thread } = this.getSessionContext(sessionId);
2284
+ try {
2285
+ await this.sendQueue.enqueue(
2286
+ () => thread.send({ content: content.text }),
2287
+ { type: "other" }
2288
+ );
2289
+ } catch {
1980
2290
  }
1981
- const thread = await this.getThread(sessionId);
1982
- if (!thread) return;
1983
- await ensureUnarchived(thread);
1984
- const isAssistant = this.assistantSession != null && sessionId === this.assistantSession.id;
1985
- const ctx = { sessionId, thread, isAssistant };
1986
- await dispatchMessage(this.messageHandlers, ctx, content, this.verbosity);
1987
2291
  }
1988
2292
  // ─── sendPermissionRequest ────────────────────────────────────────────────
1989
2293
  async sendPermissionRequest(sessionId, request) {
1990
2294
  const session = this.core.sessionManager.getSession(sessionId);
1991
2295
  if (!session) {
1992
- log.warn({ sessionId }, "[DiscordAdapter] sendPermissionRequest: session not found");
2296
+ log.warn(
2297
+ { sessionId },
2298
+ "[DiscordAdapter] sendPermissionRequest: session not found"
2299
+ );
1993
2300
  return;
1994
2301
  }
1995
2302
  const thread = await this.getThread(sessionId);
1996
2303
  if (!thread) return;
1997
- await this.permissionHandler.sendPermissionRequest(session, request, thread);
2304
+ await this.permissionHandler.sendPermissionRequest(
2305
+ session,
2306
+ request,
2307
+ thread
2308
+ );
1998
2309
  }
1999
2310
  // ─── sendNotification ─────────────────────────────────────────────────────
2000
2311
  async sendNotification(notification) {
@@ -2080,4 +2391,4 @@ ${notification.deepLink}`;
2080
2391
  export {
2081
2392
  DiscordAdapter
2082
2393
  };
2083
- //# sourceMappingURL=discord-7IVQKB2H.js.map
2394
+ //# sourceMappingURL=adapter-77ZCVABT.js.map