@openclaw/discord 2026.8.1-beta.2 → 2026.9.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/dist/{account-inspect-CqzrH14k.js → account-inspect-BDfKyuvL.js} +1 -1
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/{accounts-DJTf1LtA.js → accounts-CfQ-vSyf.js} +34 -1
  4. package/dist/action-runtime-api.js +1 -1
  5. package/dist/{activities-api-DS7vpdtp.js → activities-api-q-9PaaHH.js} +134 -175
  6. package/dist/activities-api.js +1 -1
  7. package/dist/api.js +17 -17
  8. package/dist/{approval-handler.runtime-B6yEV79q.js → approval-handler.runtime-B7qhK3fR.js} +29 -106
  9. package/dist/{audit-Db-rlntl.js → audit-CBEv_ERu.js} +5 -5
  10. package/dist/{channel-CnnbJSt5.js → channel-Dx1tMTfx.js} +72 -50
  11. package/dist/{channel-actions.runtime-CLKrx6tr.js → channel-actions.runtime-CLWWu9nC.js} +28 -43
  12. package/dist/channel-config-api.js +1 -1
  13. package/dist/channel-plugin-api.js +1 -1
  14. package/dist/channel-type-CVLZyGYS.js +7 -0
  15. package/dist/{channel.setup-BFAO-V1P.js → channel.setup-DOzXS2Pk.js} +5 -5
  16. package/dist/{outbound-session-route-DxLkrgKQ.js → components-B9V5o361.js} +8 -70
  17. package/dist/{config-schema-BgEskFAs.js → config-schema-BR13IAx6.js} +33 -7
  18. package/dist/conversation-binding-route-DJYrY2TQ.js +43 -0
  19. package/dist/{directory-config-BVX7Cflc.js → directory-config-BK6eqekJ.js} +2 -2
  20. package/dist/directory-contract-api.js +1 -1
  21. package/dist/{directory-live-DGIGxpIo.js → directory-live-DSAJSrJk.js} +3 -3
  22. package/dist/{doctor-BzC-TLnB.js → doctor-Cm7Y1pJ2.js} +33 -12
  23. package/dist/doctor-contract-api.js +2 -2
  24. package/dist/{handle-action.guild-admin-BNVTUISF.js → handle-action.guild-admin-BdwCRHmm.js} +9 -5
  25. package/dist/index.js +3 -4
  26. package/dist/{message-handler-Unk_f10F.js → message-handler-BXpWZyni.js} +82 -6
  27. package/dist/{message-handler.preflight-C9zecxR9.js → message-handler.preflight-Ba5LAY_X.js} +38 -50
  28. package/dist/{message-handler.process-DWQ6UHHu.js → message-handler.process-3HEzmemS.js} +204 -234
  29. package/dist/{message-utils-BSCPVgy0.js → message-text-aiwO5R2F.js} +41 -40
  30. package/dist/{outbound-adapter-D9nRivT1.js → outbound-adapter-BE4jSq2d.js} +113 -88
  31. package/dist/{outbound-components-cTzwBJ60.js → outbound-components-oLpg8Qzb.js} +3 -3
  32. package/dist/outbound-session-route-Cg15ZFJd.js +625 -0
  33. package/dist/owner-access-UlYi9t0M.js +107 -0
  34. package/dist/{pluralkit-DdiJ9KMK.js → pluralkit-Tiyl70dx.js} +1 -1
  35. package/dist/{probe-Bl-k5_Ku.js → probe-n6ZXxK8V.js} +1 -1
  36. package/dist/{probe.runtime-M9fREKvp.js → probe.runtime-CN4bdPfZ.js} +1 -1
  37. package/dist/{provider-DvSNb-2v.js → provider-B11xwilq.js} +720 -1325
  38. package/dist/{provider-session.runtime-BUEqD0rA.js → provider-session.runtime-B9xe-Qaf.js} +3 -3
  39. package/dist/provider.runtime-DiYaHvOz.js +2 -0
  40. package/dist/{realtime-session.runtime-C7wen-aF.js → realtime-session.runtime-CU8IQUS-.js} +97 -98
  41. package/dist/{resolve-allowlist-common-D04lpEzb.js → resolve-allowlist-common-BLoYaxEG.js} +2 -2
  42. package/dist/{resolve-channels-Dm7jEeg6.js → resolve-channels-C2sT_n67.js} +5 -4
  43. package/dist/{resolve-users-bktrCUUU.js → resolve-users-CzpjLwjy.js} +2 -2
  44. package/dist/{retry-CLpJcXXf.js → retry-Cv4jCU5Z.js} +111 -18
  45. package/dist/{runtime-DGsSyDTS.js → runtime-BHrTlFkf.js} +88 -85
  46. package/dist/{runtime-DoHjckYm.js → runtime-CY4PRMF-.js} +9 -10
  47. package/dist/runtime-api.js +19 -25
  48. package/dist/{sdk-runtime-QpY8PvCh.js → sdk-runtime-4geQHtXc.js} +57 -89
  49. package/dist/{secret-config-contract-B1akrlyY.js → secret-config-contract-B3i6WxV5.js} +53 -25
  50. package/dist/secret-contract-api.js +1 -1
  51. package/dist/security-audit-contract-api.js +1 -1
  52. package/dist/{security-audit.runtime-CPN0xFYz.js → security-audit.runtime-BVKF9VtY.js} +1 -1
  53. package/dist/{send-B7Q6Oc1I.js → send-C49MFF9j.js} +82 -19
  54. package/dist/{send.components-iJyFXw9L.js → send.components-DKKAw5VX.js} +21 -38
  55. package/dist/{send.outbound-DS5tHwfR.js → send.outbound-zam0TrZx.js} +77 -78
  56. package/dist/{send.shared-BmwFjW6T.js → send.shared-JjljcV4O.js} +135 -120
  57. package/dist/{sender-identity-QtalnCYv.js → sender-identity-BJtfyise.js} +1 -1
  58. package/dist/setup-plugin-api.js +1 -1
  59. package/dist/{shared-BIXIX6uJ.js → shared-_5EcP4jW.js} +38 -14
  60. package/dist/subagent-hooks-DQzvOptn.js +49 -0
  61. package/dist/subagent-hooks-api.js +1 -6
  62. package/dist/{system-events-CTqDf6_s.js → system-events-C7yxaHWP.js} +2 -2
  63. package/dist/{target-resolver-maOKSqO0.js → target-resolver-vxIh6O3-.js} +3 -3
  64. package/dist/targets-CtTKvntJ.js +3 -0
  65. package/dist/{thread-bindings-3L8p82GV.js → thread-bindings-DW5F9vat.js} +28 -26
  66. package/dist/{thread-bindings.manager-DCIH6WDC.js → thread-bindings.manager-ByOtwjo_.js} +9 -12
  67. package/dist/{thread-bindings.session-updates-bJ2KQFY6.js → thread-bindings.session-updates-CJb-BpPL.js} +1 -1
  68. package/dist/{thread-bindings.state-aeV8HNgV.js → thread-bindings.state-D8OMdk4O.js} +1 -1
  69. package/dist/threading-agH1T_6s.js +478 -0
  70. package/dist/transcripts-source-BR11iHA4.js +265 -0
  71. package/dist/transcripts-source-api.js +7 -2
  72. package/dist/{typing-CS-nNVoe.js → typing-Dc_YMY2e.js} +1 -1
  73. package/dist/{voice-runtime-BEdqNcST.js → voice-runtime-DIeaa8fJ.js} +230 -148
  74. package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/README.md +19 -19
  75. package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/dist/v1.js +7 -3
  76. package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/dist/v7.js +5 -2
  77. package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/dist-node/v1.js +7 -3
  78. package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/dist-node/v7.js +5 -2
  79. package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/package.json +4 -3
  80. package/node_modules/@discordjs/voice/node_modules/@types/node/README.md +1 -1
  81. package/node_modules/@discordjs/voice/node_modules/@types/node/child_process.d.ts +0 -1
  82. package/node_modules/@discordjs/voice/node_modules/@types/node/crypto.d.ts +6 -6
  83. package/node_modules/@discordjs/voice/node_modules/@types/node/dns/promises.d.ts +5 -5
  84. package/node_modules/@discordjs/voice/node_modules/@types/node/dns.d.ts +5 -5
  85. package/node_modules/@discordjs/voice/node_modules/@types/node/fs.d.ts +7 -0
  86. package/node_modules/@discordjs/voice/node_modules/@types/node/http.d.ts +30 -0
  87. package/node_modules/@discordjs/voice/node_modules/@types/node/http2.d.ts +4 -4
  88. package/node_modules/@discordjs/voice/node_modules/@types/node/os.d.ts +30 -30
  89. package/node_modules/@discordjs/voice/node_modules/@types/node/package.json +2 -2
  90. package/node_modules/@discordjs/voice/node_modules/@types/node/perf_hooks.d.ts +2 -1
  91. package/node_modules/@discordjs/voice/node_modules/@types/node/process.d.ts +42 -43
  92. package/node_modules/@discordjs/voice/node_modules/@types/node/quic.d.ts +1049 -84
  93. package/node_modules/@discordjs/voice/node_modules/@types/node/sqlite.d.ts +14 -1
  94. package/node_modules/@discordjs/voice/node_modules/@types/node/stream/iter.d.ts +3 -2
  95. package/node_modules/@discordjs/voice/node_modules/@types/node/test.d.ts +61 -0
  96. package/node_modules/@discordjs/voice/node_modules/@types/node/v8.d.ts +20 -23
  97. package/node_modules/discord-api-types/CHANGELOG.md +8 -0
  98. package/node_modules/discord-api-types/package.json +4 -4
  99. package/node_modules/discord-api-types/payloads/v10/channel.d.ts +2 -2
  100. package/node_modules/discord-api-types/payloads/v10/channel.d.ts.map +1 -1
  101. package/node_modules/discord-api-types/payloads/v10/gateway.d.ts +4 -0
  102. package/node_modules/discord-api-types/payloads/v10/gateway.d.ts.map +1 -1
  103. package/node_modules/discord-api-types/payloads/v10/gateway.js.map +1 -1
  104. package/node_modules/discord-api-types/payloads/v10/message.d.ts +4 -1
  105. package/node_modules/discord-api-types/payloads/v10/message.d.ts.map +1 -1
  106. package/node_modules/discord-api-types/payloads/v10/message.js +1 -0
  107. package/node_modules/discord-api-types/payloads/v10/message.js.map +1 -1
  108. package/node_modules/discord-api-types/payloads/v9/channel.d.ts +2 -2
  109. package/node_modules/discord-api-types/payloads/v9/channel.d.ts.map +1 -1
  110. package/node_modules/discord-api-types/payloads/v9/gateway.d.ts +4 -0
  111. package/node_modules/discord-api-types/payloads/v9/gateway.d.ts.map +1 -1
  112. package/node_modules/discord-api-types/payloads/v9/gateway.js.map +1 -1
  113. package/node_modules/discord-api-types/payloads/v9/message.d.ts +4 -1
  114. package/node_modules/discord-api-types/payloads/v9/message.d.ts.map +1 -1
  115. package/node_modules/discord-api-types/payloads/v9/message.js +1 -0
  116. package/node_modules/discord-api-types/payloads/v9/message.js.map +1 -1
  117. package/node_modules/typebox/build/format/date.d.mts +1 -1
  118. package/node_modules/typebox/build/format/date.mjs +1 -1
  119. package/node_modules/typebox/build/format/date_time.d.mts +2 -2
  120. package/node_modules/typebox/build/format/date_time.mjs +3 -3
  121. package/node_modules/typebox/build/format/email.d.mts +1 -1
  122. package/node_modules/typebox/build/format/email.mjs +2 -2
  123. package/node_modules/typebox/build/format/hostname.mjs +2 -10
  124. package/node_modules/typebox/build/format/idn_email.d.mts +1 -1
  125. package/node_modules/typebox/build/format/idn_email.mjs +3 -3
  126. package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -0
  127. package/node_modules/typebox/build/format/idn_hostname.mjs +3 -11
  128. package/node_modules/typebox/build/format/idna/format/bidi.d.mts +3 -0
  129. package/node_modules/typebox/build/format/idna/format/bidi.mjs +98 -0
  130. package/node_modules/typebox/build/format/idna/format/puny.d.mts +3 -0
  131. package/node_modules/typebox/build/format/idna/format/puny.mjs +144 -0
  132. package/node_modules/typebox/build/format/idna/hostname.d.mts +1 -0
  133. package/node_modules/typebox/build/format/idna/hostname.mjs +16 -0
  134. package/node_modules/typebox/build/format/idna/idn-hostname.d.mts +1 -0
  135. package/node_modules/typebox/build/format/idna/idn-hostname.mjs +23 -0
  136. package/node_modules/typebox/build/format/idna/index.d.mts +2 -0
  137. package/node_modules/typebox/build/format/idna/index.mjs +2 -0
  138. package/node_modules/typebox/build/format/idna/label/ascii.d.mts +1 -0
  139. package/node_modules/typebox/build/format/idna/label/ascii.mjs +9 -0
  140. package/node_modules/typebox/build/format/idna/label/puny.d.mts +1 -0
  141. package/node_modules/typebox/build/format/idna/label/puny.mjs +28 -0
  142. package/node_modules/typebox/build/format/idna/label/unicode.d.mts +1 -0
  143. package/node_modules/typebox/build/format/idna/label/unicode.mjs +106 -0
  144. package/node_modules/typebox/build/format/idna/pattern/pattern.d.mts +30 -0
  145. package/node_modules/typebox/build/format/idna/pattern/pattern.mjs +70 -0
  146. package/node_modules/typebox/build/format/ipv4.d.mts +0 -1
  147. package/node_modules/typebox/build/format/ipv4.mjs +2 -32
  148. package/node_modules/typebox/build/format/ipv6.mjs +2 -61
  149. package/node_modules/typebox/build/format/iri.d.mts +2 -2
  150. package/node_modules/typebox/build/format/iri.mjs +26 -8
  151. package/node_modules/typebox/build/format/iri_reference.d.mts +2 -2
  152. package/node_modules/typebox/build/format/iri_reference.mjs +9 -55
  153. package/node_modules/typebox/build/format/regex.d.mts +1 -2
  154. package/node_modules/typebox/build/format/regex.mjs +2 -6
  155. package/node_modules/typebox/build/format/time.d.mts +2 -2
  156. package/node_modules/typebox/build/format/time.mjs +19 -14
  157. package/node_modules/typebox/build/format/uri.d.mts +1 -1
  158. package/node_modules/typebox/build/format/uri.mjs +3 -130
  159. package/node_modules/typebox/build/format/uri_reference.d.mts +1 -1
  160. package/node_modules/typebox/build/format/uri_reference.mjs +2 -3
  161. package/node_modules/typebox/build/format/uri_template.d.mts +2 -3
  162. package/node_modules/typebox/build/format/uri_template.mjs +4 -5
  163. package/node_modules/typebox/build/format/url.d.mts +3 -3
  164. package/node_modules/typebox/build/format/url.mjs +4 -5
  165. package/node_modules/typebox/build/guard/emit.d.mts +3 -1
  166. package/node_modules/typebox/build/guard/emit.mjs +12 -5
  167. package/node_modules/typebox/build/guard/guard.d.mts +8 -2
  168. package/node_modules/typebox/build/guard/guard.mjs +25 -4
  169. package/node_modules/typebox/build/guard/string.d.mts +2 -2
  170. package/node_modules/typebox/build/guard/string.mjs +7 -7
  171. package/node_modules/typebox/build/schema/engine/_context.mjs +3 -3
  172. package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -2
  173. package/node_modules/typebox/build/schema/engine/_regexp.d.mts +2 -0
  174. package/node_modules/typebox/build/schema/engine/_regexp.mjs +4 -0
  175. package/node_modules/typebox/build/schema/engine/_stack.mjs +12 -13
  176. package/node_modules/typebox/build/schema/engine/additionalItems.mjs +17 -7
  177. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +4 -3
  178. package/node_modules/typebox/build/schema/engine/contains.mjs +18 -6
  179. package/node_modules/typebox/build/schema/engine/enum.mjs +1 -1
  180. package/node_modules/typebox/build/schema/engine/items.mjs +26 -6
  181. package/node_modules/typebox/build/schema/engine/maxContains.mjs +3 -3
  182. package/node_modules/typebox/build/schema/engine/minContains.mjs +14 -4
  183. package/node_modules/typebox/build/schema/engine/not.mjs +4 -2
  184. package/node_modules/typebox/build/schema/engine/oneOf.mjs +7 -6
  185. package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -2
  186. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +4 -3
  187. package/node_modules/typebox/build/schema/engine/ref.mjs +1 -7
  188. package/node_modules/typebox/build/schema/engine/schema.mjs +13 -4
  189. package/node_modules/typebox/build/schema/engine/type.mjs +1 -1
  190. package/node_modules/typebox/build/schema/resolve/resolve.d.mts +4 -1
  191. package/node_modules/typebox/build/schema/resolve/resolve.mjs +202 -1
  192. package/node_modules/typebox/build/schema/static/propertyNames.d.mts +5 -0
  193. package/node_modules/typebox/build/schema/static/propertyNames.mjs +3 -0
  194. package/node_modules/typebox/build/schema/static/schema.d.mts +3 -0
  195. package/node_modules/typebox/build/schema/types/index.d.mts +0 -2
  196. package/node_modules/typebox/build/schema/types/index.mjs +0 -2
  197. package/node_modules/typebox/build/system/memory/clone.mjs +14 -11
  198. package/node_modules/typebox/build/system/memory/discard.mjs +6 -5
  199. package/node_modules/typebox/build/system/settings/settings.d.mts +9 -0
  200. package/node_modules/typebox/build/system/settings/settings.mjs +2 -0
  201. package/node_modules/typebox/build/type/engine/call/distribute_arguments.d.mts +6 -1
  202. package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +16 -3
  203. package/node_modules/typebox/build/type/engine/call/instantiate.mjs +34 -4
  204. package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +5 -5
  205. package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +20 -26
  206. package/node_modules/typebox/build/type/engine/evaluate/compare.d.mts +6 -10
  207. package/node_modules/typebox/build/type/engine/evaluate/compare.mjs +9 -13
  208. package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +7 -4
  209. package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +12 -19
  210. package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +4 -20
  211. package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +8 -20
  212. package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +4 -4
  213. package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +11 -8
  214. package/node_modules/typebox/build/type/engine/evaluate/flatten.d.mts +1 -1
  215. package/node_modules/typebox/build/type/engine/evaluate/flatten.mjs +3 -4
  216. package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +17 -2
  217. package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +26 -6
  218. package/node_modules/typebox/build/type/engine/exclude/operation.mjs +3 -4
  219. package/node_modules/typebox/build/type/engine/extract/operation.d.mts +1 -1
  220. package/node_modules/typebox/build/type/engine/extract/operation.mjs +3 -4
  221. package/node_modules/typebox/build/type/engine/priority/priority.d.mts +2 -2
  222. package/node_modules/typebox/build/type/engine/priority/priority.mjs +3 -4
  223. package/node_modules/typebox/build/type/script/mapping.d.mts +32 -29
  224. package/node_modules/typebox/build/type/script/mapping.mjs +18 -25
  225. package/node_modules/typebox/build/type/script/parser.d.mts +19 -25
  226. package/node_modules/typebox/build/type/script/parser.mjs +27 -23
  227. package/node_modules/typebox/build/value/errors/errors.d.mts +2 -2
  228. package/node_modules/typebox/build/value/errors/errors.mjs +1 -1
  229. package/node_modules/typebox/package.json +27 -27
  230. package/node_modules/typebox/readme.md +79 -82
  231. package/node_modules/undici/docs/docs/api/Client.md +21 -8
  232. package/node_modules/undici/lib/api/readable.js +33 -43
  233. package/node_modules/undici/lib/core/connect.js +16 -2
  234. package/node_modules/undici/lib/core/symbols.js +1 -0
  235. package/node_modules/undici/lib/dispatcher/client-h1.js +3 -3
  236. package/node_modules/undici/lib/dispatcher/client-h2.js +179 -10
  237. package/node_modules/undici/lib/dispatcher/client.js +74 -29
  238. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +28 -6
  239. package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +15 -1
  240. package/node_modules/undici/lib/handler/retry-handler.js +7 -2
  241. package/node_modules/undici/lib/interceptor/cache.js +5 -2
  242. package/node_modules/undici/lib/interceptor/deduplicate.js +1 -1
  243. package/node_modules/undici/lib/mock/mock-utils.js +213 -24
  244. package/node_modules/undici/lib/util/cache.js +2 -4
  245. package/node_modules/undici/lib/web/websocket/websocket.js +22 -0
  246. package/node_modules/undici/package.json +1 -1
  247. package/node_modules/undici/types/client.d.ts +40 -0
  248. package/node_modules/ws/lib/permessage-deflate.js +3 -1
  249. package/node_modules/ws/package.json +1 -1
  250. package/openclaw.plugin.json +12 -6
  251. package/package.json +8 -10
  252. package/dist/approval-message-safety-AcIxvrf3.js +0 -140
  253. package/dist/audit-core-xwjIczO0.js +0 -105
  254. package/dist/channel-actions-5s_hjYKd.js +0 -208
  255. package/dist/channel-api-CAJ0wMoV.js +0 -21
  256. package/dist/inbound-event-delivery-De2qxTrP.js +0 -39
  257. package/dist/provider.runtime-C9PnJZbZ.js +0 -2
  258. package/dist/runtime-api.actions.js +0 -3
  259. package/dist/runtime-api.lookup.js +0 -7
  260. package/dist/runtime-api.monitor-CHxrFPnW.js +0 -5
  261. package/dist/runtime-api.monitor.js +0 -8
  262. package/dist/runtime-api.send.js +0 -7
  263. package/dist/runtime-api.threads.js +0 -5
  264. package/dist/send.reactions-BAn0iiVQ.js +0 -78
  265. package/dist/send.receipt-IPI1p-SP.js +0 -66
  266. package/dist/subagent-hooks-CTt5KCJr.js +0 -120
  267. package/dist/subagent-progress-DhaE_h8a.js +0 -109
  268. package/dist/targets-yUFTHoAx.js +0 -3
  269. package/dist/transcripts-source-CfFMexGt.js +0 -123
  270. package/node_modules/p-map/index.d.ts +0 -155
  271. package/node_modules/p-map/index.js +0 -285
  272. package/node_modules/p-map/license +0 -9
  273. package/node_modules/p-map/package.json +0 -57
  274. package/node_modules/p-map/readme.md +0 -190
  275. package/node_modules/typebox/build/format/_idna.d.mts +0 -2
  276. package/node_modules/typebox/build/format/_idna.mjs +0 -246
  277. package/node_modules/typebox/build/format/_puny.d.mts +0 -1
  278. package/node_modules/typebox/build/format/_puny.mjs +0 -77
  279. package/node_modules/typebox/build/schema/resolve/ref.d.mts +0 -3
  280. package/node_modules/typebox/build/schema/resolve/ref.mjs +0 -146
  281. package/node_modules/typebox/build/schema/types/contentEncoding.d.mts +0 -9
  282. package/node_modules/typebox/build/schema/types/contentEncoding.mjs +0 -13
  283. package/node_modules/typebox/build/schema/types/contentMediaType.d.mts +0 -9
  284. package/node_modules/typebox/build/schema/types/contentMediaType.mjs +0 -13
  285. package/dist/{allow-list-DnxIlPP2.js → allow-list-BDMimASD.js} +1 -1
  286. package/dist/{doctor-contract-DLa-BTiU.js → doctor-contract-DsWvKIXF.js} +1 -1
  287. package/dist/{security-audit-jGnJF__m.js → security-audit-BfJhAXZp.js} +1 -1
@@ -1,39 +1,42 @@
1
- import { B as Message, C as ReadyListener, Ct as editChannel, E as ThreadUpdateListener, Et as getChannelMessage, K as Modal, L as Command, M as RateLimitError, O as Client, R as CommandWithSubcommands, S as PresenceUpdateListener, T as ThreadDeleteListener, V as User, Y as Button, Z as Container, _ as GuildDeleteListener, a as chunkDiscordTextWithMode, at as Separator, b as MessageReactionAddListener, bt as createThread, g as GuildCreateListener, h as discord_exports, k as Plugin, ot as StringSelectMenu, rt as Row, st as TextDisplay, tn as __exportAll, ut as BaseMessageInteractiveComponent, v as InteractionCreateListener, x as MessageReactionRemoveListener, y as MessageCreateListener, z as Guild } from "./retry-CLpJcXXf.js";
2
- import { c as resolveDiscordAccountAllowFrom, d as resolveDiscordAccountDmPolicy, f as resolveDiscordMaxLinesPerMessage, p as normalizeDiscordToken, s as resolveDiscordAccount } from "./accounts-DJTf1LtA.js";
3
- import { n as getDiscordActivitiesRuntime } from "./runtime-DoHjckYm.js";
4
- import { C as parseDiscordActivityCustomIdForInteraction, D as parseDiscordModalCustomIdForInteraction, E as parseDiscordModalCustomId, O as decodeCustomIdComponent, T as parseDiscordComponentCustomIdForInteraction, k as encodeCustomIdComponent, l as parseExecApprovalData, s as parseDiscordQuestionData, w as parseDiscordComponentCustomId, y as buildDiscordActivityCustomId } from "./outbound-session-route-DxLkrgKQ.js";
5
- import { D as canViewDiscordGuildChannel, F as createDiscordRestClient, H as registerGateway, K as validateDiscordProxyUrl, U as unregisterGateway, q as withValidatedDiscordProxy, z as DISCORD_REST_TIMEOUT_MS } from "./send.shared-BmwFjW6T.js";
6
- import { _ as resolveDiscordModalEntryWithPersistence, g as resolveDiscordComponentEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-iJyFXw9L.js";
1
+ import { A as ThreadUpdateListener, C as MessageCreateListener, D as ReadyListener, E as PresenceUpdateListener, G as User, H as CommandWithSubcommands, I as RateLimitError, K as hasDiscordV2Components, M as Client, N as Plugin, S as InteractionCreateListener, T as MessageReactionRemoveListener, U as Guild, V as Command, W as Message, Z as Modal, a as chunkDiscordTextWithMode, b as GuildCreateListener, ct as Row, dt as StringSelectMenu, et as Button, ft as TextDisplay, ht as BaseMessageInteractiveComponent, k as ThreadDeleteListener, nt as Container, ut as Separator, w as MessageReactionAddListener, x as GuildDeleteListener, y as discord_exports } from "./retry-Cv4jCU5Z.js";
2
+ import { C as parseDiscordComponentCustomId, D as decodeCustomIdComponent, E as parseDiscordModalCustomIdForInteraction, O as encodeCustomIdComponent, S as parseDiscordActivityCustomIdForInteraction, T as parseDiscordModalCustomId, c as parseExecApprovalData, o as parseDiscordQuestionData, v as buildDiscordActivityCustomId, w as parseDiscordComponentCustomIdForInteraction } from "./components-B9V5o361.js";
3
+ import { c as resolveDiscordAccount, f as resolveDiscordAccountDmPolicy, l as resolveDiscordAccountAllowFrom, m as normalizeDiscordToken, p as resolveDiscordMaxLinesPerMessage } from "./accounts-CfQ-vSyf.js";
4
+ import { a as resolveDiscordComponentEntryWithPersistence, o as resolveDiscordModalEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-DKKAw5VX.js";
7
5
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
8
6
  import { a as isDiscordRateLimitResponseBody, o as summarizeDiscordResponseBody } from "./api-DNVbJyEy.js";
9
- import { C as resolveTimestampMs, a as normalizeDiscordSlug, b as formatDiscordReactionEmoji, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordCommandOwnerAllowFrom, f as resolveDiscordGuildEntry, g as resolveDiscordOwnerAllowFrom, h as resolveDiscordOwnerAccess, i as normalizeDiscordDisplaySlug, l as resolveDiscordChannelPolicyCommandAuthorizer, m as resolveDiscordMemberAllowed, n as isDiscordGroupAllowedByPolicy, o as resolveDiscordAllowListMatch, p as resolveDiscordMemberAccessState, r as normalizeDiscordAllowList, t as allowListMatches, v as resolveGroupDmAllow, x as formatDiscordUserTag, y as shouldEmitDiscordReactionNotification } from "./allow-list-DnxIlPP2.js";
10
- import { a as formatMention, t as sendMessageDiscord } from "./send.outbound-DS5tHwfR.js";
7
+ import { C as resolveTimestampMs, a as normalizeDiscordSlug, b as formatDiscordReactionEmoji, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordCommandOwnerAllowFrom, f as resolveDiscordGuildEntry, g as resolveDiscordOwnerAllowFrom, h as resolveDiscordOwnerAccess, i as normalizeDiscordDisplaySlug, l as resolveDiscordChannelPolicyCommandAuthorizer, m as resolveDiscordMemberAllowed, n as isDiscordGroupAllowedByPolicy, o as resolveDiscordAllowListMatch, p as resolveDiscordMemberAccessState, r as normalizeDiscordAllowList, v as resolveGroupDmAllow, x as formatDiscordUserTag, y as shouldEmitDiscordReactionNotification } from "./allow-list-BDMimASD.js";
8
+ import { B as validateDiscordProxyUrl, G as unregisterGateway, P as createDiscordRestClient, R as DISCORD_REST_TIMEOUT_MS, V as withValidatedDiscordProxy, W as registerGateway, b as canViewDiscordGuildChannel } from "./send.shared-JjljcV4O.js";
9
+ import { a as formatMention, t as sendMessageDiscord } from "./send.outbound-zam0TrZx.js";
10
+ import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
11
+ import { n as getDiscordActivitiesRuntime } from "./runtime-CY4PRMF-.js";
12
+ import { n as resolveDiscordVoiceEnabled, r as authorizeDiscordVoiceIngress, t as resolveDiscordVoiceAccess } from "./owner-access-UlYi9t0M.js";
11
13
  import { i as setPresence, t as clearPresences } from "./presence-cache-z1N8MbJ3.js";
12
- import { r as sendVoiceMessageDiscord } from "./send-B7Q6Oc1I.js";
14
+ import { s as sendVoiceMessageDiscord } from "./send-C49MFF9j.js";
13
15
  import { c as raceWithTimeout, u as withAbortTimeout } from "./timeouts-B9cy6RvQ.js";
14
- import { a as getDiscordExecApprovalApprovers, n as formatDiscordApprovalDisplayValue, r as resolveDiscordConversationIdentity, s as isDiscordExecApprovalClientEnabled, t as DISCORD_APPROVAL_ALLOWED_MENTIONS } from "./approval-message-safety-AcIxvrf3.js";
15
- import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-Dm7jEeg6.js";
16
- import { t as resolveDiscordUserAllowlist } from "./resolve-users-bktrCUUU.js";
17
- import { a as isThreadArchived, c as resolveDiscordChannelInfoSafe, d as resolveDiscordChannelParentSafe, f as resolveDiscordChannelTopicSafe, h as formatThreadBindingDurationLabel, l as resolveDiscordChannelNameSafe, r as getThreadBindingManager, s as resolveDiscordChannelIdSafe, u as resolveDiscordChannelParentIdSafe } from "./thread-bindings.manager-DCIH6WDC.js";
18
- import { a as probeDiscordApplicationId, r as parseApplicationIdFromToken } from "./probe-Bl-k5_Ku.js";
16
+ import { S as isDiscordExecApprovalClientEnabled, b as getDiscordExecApprovalApprovers, c as resolveDiscordEffectiveRoute, i as buildDiscordConversationRouteContext, n as DISCORD_APPROVAL_ALLOWED_MENTIONS, o as resolveDiscordBoundConversationRoute, r as formatDiscordApprovalDisplayValue, u as resolveDiscordConversationIdentity } from "./outbound-session-route-Cg15ZFJd.js";
17
+ import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-C2sT_n67.js";
18
+ import { t as resolveDiscordUserAllowlist } from "./resolve-users-CzpjLwjy.js";
19
+ import { a as isThreadArchived, c as resolveDiscordChannelInfoSafe, f as resolveDiscordChannelTopicSafe, h as formatThreadBindingDurationLabel, l as resolveDiscordChannelNameSafe, r as getThreadBindingManager, s as resolveDiscordChannelIdSafe, u as resolveDiscordChannelParentIdSafe } from "./thread-bindings.manager-ByOtwjo_.js";
20
+ import { a as probeDiscordApplicationId, r as parseApplicationIdFromToken } from "./probe-n6ZXxK8V.js";
19
21
  import { i as sanitizeRecentModels, n as normalizeModelRef, r as preferenceTimestampMs, t as buildPreferenceModelKey } from "./model-picker-preference-primitives-BHT1LkR_.js";
20
- import { a as formatDiscordMediaText, d as resolveDiscordChannelInfo, f as resolveDiscordMessageChannelId, n as resolveDiscordForwardedMessagesTextFromSnapshots, t as resolveDiscordEmbedText } from "./message-utils-BSCPVgy0.js";
21
- import { t as resolveDiscordSenderIdentity } from "./sender-identity-QtalnCYv.js";
22
- import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
23
- import { buildAgentSessionKey, deriveLastRoutePolicy, isAcpSessionKey, isSubagentSessionKey, parseAgentSessionKey, resolveAgentIdFromSessionKey, resolveAgentRoute } from "openclaw/plugin-sdk/routing";
24
- import { asFiniteNumber, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, normalizeStringEntries, parseFiniteNumber, parseStrictNonNegativeInteger, summarizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
25
- import { getRuntimeConfig, getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
22
+ import { f as resolveDiscordChannelInfo, u as resolveDiscordMessageStickers } from "./message-text-aiwO5R2F.js";
23
+ import { i as resolveDiscordThreadParentInfo } from "./threading-agH1T_6s.js";
24
+ import { t as resolveDiscordSenderIdentity } from "./sender-identity-BJtfyise.js";
26
25
  import { logDebug, logError } from "openclaw/plugin-sdk/logging-core";
27
26
  import { ApplicationCommandOptionType, ButtonStyle, ChannelType, ComponentType, GatewayCloseCodes, GatewayCloseCodes as GatewayCloseCodes$1, GatewayDispatchEvents, GatewayIntentBits, GatewayOpcodes } from "discord-api-types/v10";
28
- import { createHash, randomUUID } from "node:crypto";
29
- import { MAX_DATE_TIMESTAMP_MS, asDateTimestampMs, parseFiniteNumber as parseFiniteNumber$1, parseStrictInteger, parseStrictPositiveInteger, resolveDateTimestampMs, resolveTimestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
30
- import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
31
27
  import { Type } from "typebox";
32
28
  import { Check, Errors } from "typebox/value";
29
+ import { createHash, randomUUID } from "node:crypto";
30
+ import { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, asDateTimestampMs, asSafeIntegerInRange, parseFiniteNumber, parseStrictInteger, parseStrictPositiveInteger, resolveDateTimestampMs, resolveTimestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
31
+ import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
33
32
  import { inspect } from "node:util";
34
33
  import { readResponseWithLimit } from "openclaw/plugin-sdk/response-limit-runtime";
35
34
  import { PlatformMessageNotDispatchedError, formatErrorMessage, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
36
35
  import { fetchWithSsrFGuard, formatErrorMessage as formatErrorMessage$1 } from "openclaw/plugin-sdk/ssrf-runtime";
36
+ import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
37
+ import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
38
+ import { asFiniteNumber, asOptionalRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, parseFiniteNumber as parseFiniteNumber$1, parseStrictNonNegativeInteger as parseStrictNonNegativeInteger$1, summarizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
39
+ import { getRuntimeConfig, getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
37
40
  import { createHttp1EnvHttpProxyAgent, createHttp1ProxyAgent, createNodeProxyAgent, resolveEnvHttpProxyAgentOptions, wrapFetchWithAbortSignal } from "openclaw/plugin-sdk/fetch-runtime";
38
41
  import { createNonExitingRuntime, createSubsystemLogger, danger, formatDurationSeconds, isVerbose, logVerbose, shouldLogVerbose, sleepWithAbort, warn } from "openclaw/plugin-sdk/runtime-env";
39
42
  import { sliceUtf16Safe, truncateUtf16Safe, withTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
@@ -41,33 +44,31 @@ import { addAllowlistUserEntriesFromConfigEntry, buildAllowlistResolutionSummary
41
44
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
42
45
  import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
43
46
  import { chunkItems, findCodeRegions, sanitizeAssistantVisibleText, sanitizeAssistantVisibleTextWithProfile } from "openclaw/plugin-sdk/text-chunking";
44
- import { createReplyReferencePlanner } from "openclaw/plugin-sdk/reply-reference";
45
47
  import { buildOutboundSessionContext, listMessageReceiptPlatformIds, resolveChannelStreamingBlockEnabled, sendDurableMessageBatch } from "openclaw/plugin-sdk/channel-outbound";
46
48
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
47
49
  import { resolveSendableOutboundReplyParts, resolveTextChunksWithFallback } from "openclaw/plugin-sdk/reply-payload";
48
50
  import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
49
51
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
50
- import { resolvePinnedMainDmOwnerFromAllowlist as resolvePinnedMainDmOwnerFromAllowlist$1 } from "openclaw/plugin-sdk/security-runtime";
52
+ import { buildCommandTextFromArgs, findCommandByNativeName, formatCommandArgMenuTitle, listChatCommands, listNativeCommandSpecsForConfig, listSkillCommandsForAgents, resolveCommandAuthorizedFromAuthorizers, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverride, serializeCommandArgs } from "openclaw/plugin-sdk/command-auth-native";
51
53
  import { GROUP_POLICY_BLOCKED_LABEL, resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
54
+ import { resolvePinnedMainDmOwnerFromAllowlist as resolvePinnedMainDmOwnerFromAllowlist$1 } from "openclaw/plugin-sdk/security-runtime";
52
55
  import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
53
56
  import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
54
- import { questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
55
57
  import { buildPairingReply, upsertChannelPairingRequest, upsertChannelPairingRequest as upsertChannelPairingRequest$1 } from "openclaw/plugin-sdk/conversation-runtime";
58
+ import * as conversationRuntime from "openclaw/plugin-sdk/conversation-binding-runtime";
59
+ import { questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
56
60
  import { clearExpiredCooldowns, ensureAuthProfileStore, formatReasoningMessage, getPreparedModelCatalogSnapshot, isProfileInCooldown, listAgentIds, loadPreparedModelCatalog, resolveAgentAvatar, resolveAgentDir, resolveDefaultModelForAgent, resolveHumanDelayConfig, resolveProfilesUnavailableReason } from "openclaw/plugin-sdk/agent-runtime";
57
61
  import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
58
62
  import { resolveNativeCommandsEnabled, resolveNativeSkillsEnabled } from "openclaw/plugin-sdk/native-command-config-runtime";
59
63
  import { requestHeartbeat } from "openclaw/plugin-sdk/heartbeat-runtime";
60
64
  import { enqueueRoutedSystemEvent, enqueueRoutedSystemEvent as enqueueRoutedSystemEvent$1 } from "openclaw/plugin-sdk/system-event-runtime";
65
+ import { deleteSessionEntry, getSessionEntry, listSessionEntries, readSessionUpdatedAt as readSessionUpdatedAt$1, resolveStorePath, resolveStorePath as resolveStorePath$1 } from "openclaw/plugin-sdk/session-store-runtime";
61
66
  import { createChannelIngressResolver, defineStableChannelIngressIdentity, readChannelIngressStoreAllowFromForDmPolicy } from "openclaw/plugin-sdk/channel-ingress-runtime";
67
+ import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-dispatch-runtime";
62
68
  import { createChannelPartialDeliveryError, dispatchChannelInboundTurn, formatInboundEnvelope, hasVisibleInboundReplyDispatch, isChannelPartialDeliveryError, resolveEnvelopeFormatOptions, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent } from "openclaw/plugin-sdk/channel-inbound";
63
- import { resolveChannelModelOverride } from "openclaw/plugin-sdk/model-session-runtime";
64
- import { finalizeInboundContext, generateConversationLabel } from "openclaw/plugin-sdk/reply-dispatch-runtime";
65
- import { deleteSessionEntry, getSessionEntry, listSessionEntries, readSessionUpdatedAt as readSessionUpdatedAt$1, resolveStorePath, resolveStorePath as resolveStorePath$1 } from "openclaw/plugin-sdk/session-store-runtime";
66
- import { buildCommandTextFromArgs, findCommandByNativeName, formatCommandArgMenuTitle, listChatCommands, listNativeCommandSpecsForConfig, listSkillCommandsForAgents, resolveCommandAuthorizedFromAuthorizers, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverride, serializeCommandArgs } from "openclaw/plugin-sdk/command-auth-native";
67
69
  import { buildCommandTextFromArgs as buildCommandTextFromArgs$1, findCommandByNativeName as findCommandByNativeName$1, mergeNativeCommandSpecs, parseCommandArgs, resolveCommandArgChoices, resolveCommandArgMenu, serializeCommandArgs as serializeCommandArgs$1 } from "openclaw/plugin-sdk/native-command-registry";
68
70
  import { PLUGIN_COMMAND_DISPATCH } from "openclaw/plugin-sdk/plugin-command-runtime";
69
71
  import { resolveDirectStatusReplyForSession } from "openclaw/plugin-sdk/command-status-runtime";
70
- import * as conversationRuntime from "openclaw/plugin-sdk/conversation-binding-runtime";
71
72
  import { normalizeProviderId } from "openclaw/plugin-sdk/provider-model-shared";
72
73
  import { EventEmitter } from "node:events";
73
74
  import * as ws from "ws";
@@ -140,6 +141,205 @@ async function runDiscordListenerWithSlowLog(params) {
140
141
  }
141
142
  }
142
143
  //#endregion
144
+ //#region extensions/discord/src/monitor/presence-events.ts
145
+ const DISCORD_PRESENCE_GREETING_COOLDOWN_MS = 480 * 60 * 1e3;
146
+ function isDiscordOnlineStatus(status) {
147
+ return status === "online" || status === "idle" || status === "dnd";
148
+ }
149
+ function isDiscordOfflineStatus(status) {
150
+ return status === "offline";
151
+ }
152
+ function resolveDiscordOnlinePresenceEvent(params) {
153
+ const config = params.config;
154
+ const userId = params.data.user?.id?.trim();
155
+ if (!config || config.enabled === false || !userId || userId === params.botUserId || params.data.user.bot === true || !isDiscordOnlineStatus(params.data.status) || !params.availabilityKind) return null;
156
+ if (config.users !== void 0 && !config.users.includes(userId)) return null;
157
+ if (params.lastEmittedAtMs !== void 0 && params.nowMs - params.lastEmittedAtMs < 288e5) return null;
158
+ const lines = [
159
+ "Discord online-presence event:",
160
+ params.availabilityKind === "observed-offline" ? `A human member became available online after being observed offline in guild_id=${JSON.stringify(params.data.guild_id)} user_id=${JSON.stringify(userId)} status=${JSON.stringify(params.data.status)}.` : `A human member became newly visible online since the current guild snapshot in guild_id=${JSON.stringify(params.data.guild_id)} user_id=${JSON.stringify(userId)} status=${JSON.stringify(params.data.status)}. They may have come online or joined after the snapshot; do not claim an exact prior status.`,
161
+ `The authorized greeting target is channel_id=${JSON.stringify(config.channelId)}.`,
162
+ "Before greeting, retrieve relevant memory and wiki context for this immutable user_id, including a known timezone when available. Use their local time for the greeting; if their timezone is unknown, do not guess.",
163
+ "Send at most one short, natural greeting to the target channel. Do not reveal private memory. If no greeting is appropriate, stay silent."
164
+ ];
165
+ return {
166
+ channelId: config.channelId,
167
+ userId,
168
+ text: lines.join("\n")
169
+ };
170
+ }
171
+ //#endregion
172
+ //#region extensions/discord/src/monitor/presence-cooldown-store.ts
173
+ const DISCORD_PRESENCE_COOLDOWN_MAX_ENTRIES = 25e3;
174
+ function openDiscordPresenceCooldownStore() {
175
+ return getDiscordRuntime().state.openSyncKeyedStore({
176
+ namespace: "presence-greeting-cooldowns",
177
+ maxEntries: DISCORD_PRESENCE_COOLDOWN_MAX_ENTRIES,
178
+ overflowPolicy: "reject-new",
179
+ defaultTtlMs: DISCORD_PRESENCE_GREETING_COOLDOWN_MS
180
+ });
181
+ }
182
+ //#endregion
183
+ //#region extensions/discord/src/monitor/presence-emission-gate.ts
184
+ const DISCORD_PRESENCE_RECONNECT_SUPPRESS_MS = 300 * 1e3;
185
+ const DISCORD_PRESENCE_BURST_LIMIT = 8;
186
+ const DISCORD_PRESENCE_BURST_WINDOW_MS = 60 * 1e3;
187
+ function resolveDiscordPresenceGateOptions(config) {
188
+ return {
189
+ reconnectSuppressMs: config?.reconnectSuppressSeconds !== void 0 ? config.reconnectSuppressSeconds * 1e3 : DISCORD_PRESENCE_RECONNECT_SUPPRESS_MS,
190
+ burstLimit: config?.burstLimit ?? DISCORD_PRESENCE_BURST_LIMIT,
191
+ burstWindowMs: config?.burstWindowSeconds !== void 0 ? config.burstWindowSeconds * 1e3 : DISCORD_PRESENCE_BURST_WINDOW_MS
192
+ };
193
+ }
194
+ /**
195
+ * Per-account lifecycle gate for online-presence events. Reconnect state belongs to the Gateway
196
+ * session, while burst state follows the guild-owned configuration that supplies its limits.
197
+ */
198
+ var DiscordPresenceEmissionGate = class {
199
+ constructor() {
200
+ this.reconnectLogged = false;
201
+ this.burstByGuild = /* @__PURE__ */ new Map();
202
+ this.nextReservationId = 0;
203
+ }
204
+ noteGatewaySessionReset(nowMs) {
205
+ this.lastSessionResetAtMs = nowMs;
206
+ this.reconnectLogged = false;
207
+ }
208
+ evaluateReconnectWindow(nowMs, options) {
209
+ if (this.lastSessionResetAtMs !== void 0 && options.reconnectSuppressMs > 0 && nowMs - this.lastSessionResetAtMs < options.reconnectSuppressMs) {
210
+ const shouldLog = !this.reconnectLogged;
211
+ this.reconnectLogged = true;
212
+ return {
213
+ allowed: false,
214
+ reason: "reconnect-window",
215
+ shouldLog
216
+ };
217
+ }
218
+ return { allowed: true };
219
+ }
220
+ reserveBurst(guildId, nowMs, options) {
221
+ const state = this.burstByGuild.get(guildId) ?? {
222
+ reservations: [],
223
+ logged: false
224
+ };
225
+ state.reservations = state.reservations.filter((reservation) => !reservation.committed || nowMs - reservation.atMs < options.burstWindowMs);
226
+ this.burstByGuild.set(guildId, state);
227
+ if (state.reservations.length >= options.burstLimit) {
228
+ const shouldLog = !state.logged;
229
+ state.logged = true;
230
+ return {
231
+ allowed: false,
232
+ reason: state.reservations.some((reservation) => !reservation.committed) ? "burst-pending" : "burst",
233
+ shouldLog
234
+ };
235
+ }
236
+ state.logged = false;
237
+ const reservation = {
238
+ id: this.nextReservationId++,
239
+ atMs: nowMs,
240
+ committed: false
241
+ };
242
+ state.reservations.push(reservation);
243
+ return {
244
+ allowed: true,
245
+ reservation: reservation.id
246
+ };
247
+ }
248
+ commitBurst(guildId, reservation, nowMs) {
249
+ const entry = this.burstByGuild.get(guildId)?.reservations.find((candidate) => candidate.id === reservation);
250
+ if (!entry) return;
251
+ entry.atMs = nowMs;
252
+ entry.committed = true;
253
+ }
254
+ releaseBurst(guildId, reservation) {
255
+ const state = this.burstByGuild.get(guildId);
256
+ if (!state) return;
257
+ state.reservations = state.reservations.filter((candidate) => candidate.id !== reservation);
258
+ if (state.reservations.length === 0 && !state.logged) this.burstByGuild.delete(guildId);
259
+ }
260
+ };
261
+ //#endregion
262
+ //#region extensions/discord/src/monitor/presence-transition-cache.ts
263
+ const DEFAULT_PRESENCE_BASELINE_MAX_ENTRIES = 75e3;
264
+ var DiscordPresenceBaselineCache = class {
265
+ constructor(maxEntries = DEFAULT_PRESENCE_BASELINE_MAX_ENTRIES) {
266
+ this.maxEntries = maxEntries;
267
+ this.offlineByKey = /* @__PURE__ */ new Map();
268
+ this.onlineByKey = /* @__PURE__ */ new Map();
269
+ }
270
+ clear() {
271
+ this.offlineByKey.clear();
272
+ this.onlineByKey.clear();
273
+ }
274
+ clearScope(scope) {
275
+ for (const markers of [this.offlineByKey, this.onlineByKey]) for (const [key, markerScope] of markers) if (markerScope === scope) markers.delete(key);
276
+ }
277
+ isOffline(scope, key) {
278
+ return this.offlineByKey.get(key) === scope;
279
+ }
280
+ isOnline(scope, key) {
281
+ return this.onlineByKey.get(key) === scope;
282
+ }
283
+ observeOffline(scope, key) {
284
+ this.deleteMarker(this.onlineByKey, scope, key);
285
+ return this.observe(this.offlineByKey, scope, key);
286
+ }
287
+ observeOnline(scope, key) {
288
+ this.deleteMarker(this.offlineByKey, scope, key);
289
+ return this.observe(this.onlineByKey, scope, key);
290
+ }
291
+ deleteMarker(markers, scope, key) {
292
+ if (markers.get(key) === scope) markers.delete(key);
293
+ }
294
+ observe(markers, scope, key) {
295
+ markers.delete(key);
296
+ markers.set(key, scope);
297
+ let evictedScope;
298
+ while (markers.size > this.maxEntries) {
299
+ const oldestKey = markers.keys().next().value;
300
+ if (oldestKey === void 0) break;
301
+ evictedScope = markers.get(oldestKey);
302
+ markers.delete(oldestKey);
303
+ }
304
+ return evictedScope;
305
+ }
306
+ };
307
+ //#endregion
308
+ //#region extensions/discord/src/monitor/thread-session-close.ts
309
+ /**
310
+ * Closes every session entry in the store whose key contains {@link threadId}.
311
+ * The explicit lifecycle deletion archives the old transcript and guarantees
312
+ * that a later inbound message starts a fresh session in every reset mode.
313
+ */
314
+ async function closeDiscordThreadSessions(params) {
315
+ const { cfg, threadId } = params;
316
+ const normalizedThreadId = normalizeOptionalLowercaseString(threadId) ?? "";
317
+ if (!normalizedThreadId) return 0;
318
+ const segmentRe = new RegExp(`:${normalizedThreadId}(?::|$)`, "i");
319
+ function sessionKeyContainsThreadId(key) {
320
+ return segmentRe.test(key);
321
+ }
322
+ let resetCount = 0;
323
+ for (const agentId of listAgentIds(cfg)) {
324
+ const storePath = resolveStorePath(cfg.session?.store, { agentId });
325
+ for (const { sessionKey, entry } of listSessionEntries({
326
+ agentId,
327
+ storePath,
328
+ readOnly: true
329
+ })) {
330
+ if (!sessionKeyContainsThreadId(sessionKey)) continue;
331
+ if (await deleteSessionEntry({
332
+ archiveTranscript: true,
333
+ expectedSessionId: entry.sessionId ?? null,
334
+ expectedUpdatedAt: entry.updatedAt,
335
+ sessionKey,
336
+ storePath
337
+ })) resetCount += 1;
338
+ }
339
+ }
340
+ return resetCount;
341
+ }
342
+ //#endregion
143
343
  //#region extensions/discord/src/monitor/dm-command-auth.ts
144
344
  const DISCORD_ALLOW_LIST_PREFIXES = [
145
345
  "discord:",
@@ -305,474 +505,16 @@ async function resolveDiscordTextCommandAccess(params) {
305
505
  });
306
506
  }
307
507
  //#endregion
308
- //#region extensions/discord/src/monitor/thread-title.ts
309
- const DEFAULT_THREAD_TITLE_TIMEOUT_MS = 6e4;
310
- const MAX_THREAD_TITLE_SOURCE_CHARS = 600;
311
- const MAX_THREAD_TITLE_CHANNEL_NAME_CHARS = 120;
312
- const MAX_THREAD_TITLE_CHANNEL_DESCRIPTION_CHARS = 320;
313
- const DISCORD_THREAD_TITLE_SYSTEM_PROMPT = "Generate a concise Discord thread title (3-6 words). Return only the title. Use channel context when provided and avoid redundant channel-name words unless needed for clarity.";
314
- async function generateThreadTitle(params) {
315
- const sourceText = params.messageText.trim();
316
- if (!sourceText) return null;
317
- try {
318
- const userMessage = buildThreadTitleCompletionUserMessage({
319
- sourceText,
320
- channelName: params.channelName,
321
- channelDescription: params.channelDescription
322
- });
323
- const timeoutMs = resolveThreadTitleTimeoutMs(params.timeoutMs);
324
- const generated = await generateConversationLabel({
325
- cfg: params.cfg,
326
- agentId: params.agentId,
327
- userMessage,
328
- prompt: DISCORD_THREAD_TITLE_SYSTEM_PROMPT,
329
- ...params.modelRef ? { modelRef: params.modelRef } : {},
330
- timeoutMs,
331
- maxLength: MAX_THREAD_TITLE_SOURCE_CHARS
332
- });
333
- return generated ? normalizeGeneratedThreadTitle(generated) : null;
334
- } catch (err) {
335
- logVerbose(`thread-title: title generation failed for agent ${params.agentId}: ${String(err)}`);
336
- return null;
337
- }
338
- }
339
- function buildThreadTitleCompletionUserMessage(params) {
340
- const sourceText = truncateThreadTitleSourceText(params.sourceText);
341
- const channelName = normalizeTitleContextField(params.channelName, MAX_THREAD_TITLE_CHANNEL_NAME_CHARS);
342
- const channelDescription = normalizeTitleContextField(params.channelDescription, MAX_THREAD_TITLE_CHANNEL_DESCRIPTION_CHARS);
343
- const messageLines = [];
344
- if (channelName) messageLines.push(`Channel: ${channelName}`);
345
- if (channelDescription) messageLines.push(`Channel description: ${channelDescription}`);
346
- messageLines.push(`Message:\n${sourceText}`);
347
- return messageLines.join("\n\n");
348
- }
349
- function truncateThreadTitleSourceText(sourceText) {
350
- if (sourceText.length <= MAX_THREAD_TITLE_SOURCE_CHARS) return sourceText;
351
- return `${truncateUtf16Safe(sourceText, MAX_THREAD_TITLE_SOURCE_CHARS)}...`;
352
- }
353
- function resolveThreadTitleTimeoutMs(timeoutMs) {
354
- return Math.max(100, Math.floor(timeoutMs ?? DEFAULT_THREAD_TITLE_TIMEOUT_MS));
355
- }
356
- function normalizeGeneratedThreadTitle(raw) {
357
- const lines = raw.replace(/\r/g, "").split("\n");
358
- let firstLine = "";
359
- for (const line of lines) {
360
- const trimmed = line.trim();
361
- if (!trimmed) continue;
362
- if (!firstLine && trimmed.startsWith("```")) continue;
363
- firstLine = trimmed;
364
- break;
365
- }
366
- return stripThreadTitleWrappers(firstLine);
367
- }
368
- function stripThreadTitleWrappers(raw) {
369
- let current = raw.trim();
370
- let previous = "";
371
- while (current && current !== previous) {
372
- previous = current;
373
- current = current.replace(/^["'`]+|["'`]+$/g, "").trim();
374
- current = stripBalancedWrapper(current, "**");
375
- current = stripBalancedWrapper(current, "__");
376
- current = stripBalancedWrapper(current, "*");
377
- current = stripBalancedWrapper(current, "_");
378
- current = stripBalancedWrapper(current, "~~");
379
- }
380
- return current;
381
- }
382
- function stripBalancedWrapper(text, marker) {
383
- if (text.length < marker.length * 2 + 1) return text;
384
- if (!text.startsWith(marker) || !text.endsWith(marker)) return text;
385
- const inner = text.slice(marker.length, text.length - marker.length);
386
- if (!inner || inner.includes(marker)) return text;
387
- return inner;
388
- }
389
- function normalizeTitleContextField(raw, maxChars) {
390
- const value = raw?.trim();
391
- if (!value) return;
392
- const singleLine = value.replace(/\s+/g, " ");
393
- if (singleLine.length <= maxChars) return singleLine;
394
- return `${truncateUtf16Safe(singleLine, maxChars)}...`;
395
- }
396
- //#endregion
397
- //#region extensions/discord/src/monitor/threading.cache.ts
398
- const DISCORD_THREAD_STARTER_CACHE_TTL_MS = 300 * 1e3;
399
- const DISCORD_THREAD_STARTER_CACHE_MAX = 500;
400
- const DISCORD_THREAD_STARTER_CACHE = /* @__PURE__ */ new Map();
401
- function resetDiscordThreadStarterCacheForTest() {
402
- DISCORD_THREAD_STARTER_CACHE.clear();
403
- }
404
- function getCachedThreadStarter(key, now) {
405
- const entry = DISCORD_THREAD_STARTER_CACHE.get(key);
406
- if (!entry) return;
407
- if (now - entry.updatedAt > DISCORD_THREAD_STARTER_CACHE_TTL_MS) {
408
- DISCORD_THREAD_STARTER_CACHE.delete(key);
409
- return;
410
- }
411
- DISCORD_THREAD_STARTER_CACHE.delete(key);
412
- DISCORD_THREAD_STARTER_CACHE.set(key, {
413
- ...entry,
414
- updatedAt: now
415
- });
416
- return entry.value;
417
- }
418
- function setCachedThreadStarter(key, value, now) {
419
- DISCORD_THREAD_STARTER_CACHE.delete(key);
420
- DISCORD_THREAD_STARTER_CACHE.set(key, {
421
- value,
422
- updatedAt: now
423
- });
424
- while (DISCORD_THREAD_STARTER_CACHE.size > DISCORD_THREAD_STARTER_CACHE_MAX) {
425
- const iter = DISCORD_THREAD_STARTER_CACHE.keys().next();
426
- if (iter.done) break;
427
- DISCORD_THREAD_STARTER_CACHE.delete(iter.value);
428
- }
429
- }
430
- //#endregion
431
- //#region extensions/discord/src/monitor/threading.starter.ts
432
- function isDiscordThreadType(type) {
433
- return type === discord_exports.ChannelType.PublicThread || type === discord_exports.ChannelType.PrivateThread || type === discord_exports.ChannelType.AnnouncementThread;
434
- }
435
- function isDiscordForumParentType(parentType) {
436
- return parentType === discord_exports.ChannelType.GuildForum || parentType === discord_exports.ChannelType.GuildMedia;
437
- }
438
- function resolveDiscordThreadChannel(params) {
439
- if (!params.isGuildMessage) return null;
440
- const { message, channelInfo } = params;
441
- const channel = "channel" in message ? message.channel : void 0;
442
- if (channel && typeof channel === "object" && "isThread" in channel && typeof channel.isThread === "function" && channel.isThread()) return channel;
443
- if (!isDiscordThreadType(channelInfo?.type)) return null;
444
- const messageChannelId = params.messageChannelId || resolveDiscordMessageChannelId({ message });
445
- if (!messageChannelId) return null;
446
- return {
447
- id: messageChannelId,
448
- name: channelInfo?.name ?? void 0,
449
- parentId: channelInfo?.parentId ?? void 0,
450
- parent: void 0,
451
- ownerId: channelInfo?.ownerId ?? void 0
452
- };
453
- }
454
- async function resolveDiscordThreadParentInfo(params) {
455
- const { threadChannel, channelInfo, client } = params;
456
- const parent = resolveDiscordChannelParentSafe(threadChannel);
457
- let parentId = resolveDiscordChannelParentIdSafe(threadChannel) ?? resolveDiscordChannelIdSafe(parent) ?? channelInfo?.parentId ?? void 0;
458
- if (!parentId && threadChannel.id) parentId = (await resolveDiscordChannelInfo(client, threadChannel.id))?.parentId ?? void 0;
459
- if (!parentId) return {};
460
- let parentName = resolveDiscordChannelNameSafe(parent);
461
- const parentInfo = await resolveDiscordChannelInfo(client, parentId);
462
- parentName = parentName ?? parentInfo?.name;
463
- const parentType = parentInfo?.type;
508
+ //#region extensions/discord/src/monitor/thread-channel-context.ts
509
+ function buildFetchedChannelInfo(channel) {
510
+ const channelInfo = resolveDiscordChannelInfoSafe(channel);
511
+ if (channelInfo.type === void 0) return null;
464
512
  return {
465
- id: parentId,
466
- name: parentName,
467
- type: parentType
468
- };
469
- }
470
- async function resolveDiscordThreadStarter(params) {
471
- const cacheKey = params.channel.id;
472
- const cached = getCachedThreadStarter(cacheKey, Date.now());
473
- if (cached) return cached;
474
- try {
475
- const messageChannelId = resolveDiscordThreadStarterMessageChannelId(params);
476
- if (!messageChannelId) return null;
477
- const starter = await fetchDiscordThreadStarterMessage({
478
- client: params.client,
479
- messageChannelId,
480
- threadId: params.channel.id
481
- });
482
- if (!starter) return null;
483
- const payload = buildDiscordThreadStarterPayload({
484
- starter,
485
- resolveTimestampMs: params.resolveTimestampMs
486
- });
487
- if (!payload) return null;
488
- setCachedThreadStarter(cacheKey, payload, Date.now());
489
- return payload;
490
- } catch {
491
- return null;
492
- }
493
- }
494
- function resolveDiscordThreadStarterMessageChannelId(params) {
495
- return isDiscordForumParentType(params.parentType) ? params.channel.id : params.parentId;
496
- }
497
- async function fetchDiscordThreadStarterMessage(params) {
498
- const starter = await getChannelMessage(params.client.rest, params.messageChannelId, params.threadId);
499
- return starter ? starter : null;
500
- }
501
- function buildDiscordThreadStarterPayload(params) {
502
- const text = resolveDiscordThreadStarterText(params.starter);
503
- if (!text) return null;
504
- return {
505
- text,
506
- ...resolveDiscordThreadStarterIdentity(params.starter),
507
- timestamp: params.resolveTimestampMs(params.starter.timestamp) ?? void 0
508
- };
509
- }
510
- function resolveDiscordThreadStarterText(starter) {
511
- const content = normalizeOptionalString(starter.content) ?? "";
512
- const embedText = resolveDiscordEmbedText(starter.embeds?.[0]);
513
- const forwardedText = resolveDiscordForwardedMessagesTextFromSnapshots(starter.message_snapshots);
514
- return [content || embedText || forwardedText, formatDiscordMediaText({
515
- attachments: starter.attachments ?? void 0,
516
- stickers: starter.sticker_items ?? void 0
517
- })].filter(Boolean).join("\n");
518
- }
519
- function resolveDiscordThreadStarterIdentity(starter) {
520
- return {
521
- author: resolveDiscordThreadStarterAuthor(starter),
522
- authorId: starter.author?.id ?? void 0,
523
- authorName: starter.author?.username ?? void 0,
524
- authorTag: resolveDiscordThreadStarterAuthorTag(starter.author),
525
- memberRoleIds: resolveDiscordThreadStarterRoleIds(starter.member)
526
- };
527
- }
528
- function resolveDiscordThreadStarterAuthor(starter) {
529
- return starter.member?.nick ?? starter.member?.displayName ?? resolveDiscordThreadStarterAuthorTag(starter.author) ?? starter.author?.username ?? starter.author?.id ?? "Unknown";
530
- }
531
- function resolveDiscordThreadStarterAuthorTag(author) {
532
- if (!author?.username || !author.discriminator) return;
533
- if (author.discriminator !== "0") return `${author.username}#${author.discriminator}`;
534
- return author.username;
535
- }
536
- function resolveDiscordThreadStarterRoleIds(member) {
537
- return Array.isArray(member?.roles) ? member.roles : void 0;
538
- }
539
- function resolveDiscordReplyTarget(opts) {
540
- if (opts.replyToMode === "off") return;
541
- const replyToId = normalizeOptionalString(opts.replyToId);
542
- if (!replyToId) return;
543
- if (opts.replyToMode === "all") return replyToId;
544
- return opts.hasReplied ? void 0 : replyToId;
545
- }
546
- function sanitizeDiscordThreadName(rawName, fallbackId) {
547
- return truncateUtf16Safe(truncateUtf16Safe(rawName.replace(/<@!?\d+>/g, "").replace(/<@&\d+>/g, "").replace(/<#\d+>/g, "").replace(/\s+/g, " ").trim() || `Thread ${fallbackId}`, 80), 100) || `Thread ${fallbackId}`;
548
- }
549
- function resolveDiscordReplyDeliveryPlan(params) {
550
- const originalReplyTarget = params.replyTarget;
551
- let deliverTarget = originalReplyTarget;
552
- let replyTarget = originalReplyTarget;
553
- if (params.createdThreadId) {
554
- deliverTarget = `channel:${params.createdThreadId}`;
555
- replyTarget = deliverTarget;
556
- }
557
- const allowReference = deliverTarget === originalReplyTarget;
558
- const replyReference = createReplyReferencePlanner({
559
- replyToMode: allowReference ? params.replyToMode : "off",
560
- existingId: params.threadChannel ? params.messageId : void 0,
561
- startId: params.messageId,
562
- allowReference
563
- });
564
- return {
565
- deliverTarget,
566
- replyTarget,
567
- replyReference
568
- };
569
- }
570
- //#endregion
571
- //#region extensions/discord/src/monitor/threading.auto-thread.ts
572
- function resolveTrimmedDiscordMessageChannelId(params) {
573
- return (params.messageChannelId || resolveDiscordMessageChannelId({ message: params.message })).trim();
574
- }
575
- function resolveDiscordAutoThreadContext(params) {
576
- const createdThreadId = normalizeOptionalStringifiedId(params.createdThreadId) ?? "";
577
- if (!createdThreadId) return null;
578
- const messageChannelId = normalizeOptionalString(params.messageChannelId) ?? "";
579
- if (!messageChannelId) return null;
580
- const threadSessionKey = buildAgentSessionKey({
581
- agentId: params.agentId,
582
- channel: params.channel,
583
- peer: {
584
- kind: "channel",
585
- id: createdThreadId
586
- }
587
- });
588
- const parentSessionKey = buildAgentSessionKey({
589
- agentId: params.agentId,
590
- channel: params.channel,
591
- peer: {
592
- kind: "channel",
593
- id: messageChannelId
594
- }
595
- });
596
- return {
597
- createdThreadId,
598
- From: `${params.channel}:channel:${createdThreadId}`,
599
- To: `channel:${createdThreadId}`,
600
- OriginatingTo: `channel:${createdThreadId}`,
601
- SessionKey: threadSessionKey,
602
- ModelParentSessionKey: parentSessionKey,
603
- ...params.parentInheritanceEnabled === true ? { ParentSessionKey: parentSessionKey } : {}
604
- };
605
- }
606
- async function resolveDiscordAutoThreadReplyPlan(params) {
607
- const messageChannelId = resolveTrimmedDiscordMessageChannelId(params);
608
- const originalReplyTarget = `channel:${params.threadChannel?.id ?? (messageChannelId || "unknown")}`;
609
- const createdThreadId = await maybeCreateDiscordAutoThread({
610
- client: params.client,
611
- message: params.message,
612
- messageChannelId: messageChannelId || void 0,
613
- channel: params.channel,
614
- isGuildMessage: params.isGuildMessage,
615
- channelConfig: params.channelConfig,
616
- threadChannel: params.threadChannel,
617
- channelType: params.channelType,
618
- channelName: params.channelName,
619
- channelDescription: params.channelDescription,
620
- baseText: params.baseText,
621
- combinedBody: params.combinedBody,
622
- cfg: params.cfg,
623
- agentId: params.agentId
624
- });
625
- const deliveryPlan = resolveDiscordReplyDeliveryPlan({
626
- replyTarget: originalReplyTarget,
627
- replyToMode: params.replyToMode,
628
- messageId: params.message.id,
629
- threadChannel: params.threadChannel,
630
- createdThreadId
631
- });
632
- const autoThreadContext = params.isGuildMessage ? resolveDiscordAutoThreadContext({
633
- agentId: params.agentId,
634
- channel: params.channel,
635
- messageChannelId,
636
- createdThreadId,
637
- parentInheritanceEnabled: params.threadParentInheritanceEnabled
638
- }) : null;
639
- return {
640
- ...deliveryPlan,
641
- createdThreadId,
642
- autoThreadContext
643
- };
644
- }
645
- async function maybeCreateDiscordAutoThread(params) {
646
- if (!params.isGuildMessage) return;
647
- if (!params.channelConfig?.autoThread) return;
648
- if (params.threadChannel) return;
649
- if (params.channelType === discord_exports.ChannelType.GuildForum || params.channelType === discord_exports.ChannelType.GuildMedia || params.channelType === discord_exports.ChannelType.GuildVoice || params.channelType === discord_exports.ChannelType.GuildStageVoice) return;
650
- const messageChannelId = resolveTrimmedDiscordMessageChannelId(params);
651
- if (!messageChannelId) return;
652
- try {
653
- try {
654
- const existingThreadId = (await getChannelMessage(params.client.rest, messageChannelId, params.message.id))?.thread?.id;
655
- if (existingThreadId) {
656
- logVerbose(`discord: autoThread reusing existing thread ${existingThreadId} on ${messageChannelId}/${params.message.id}`);
657
- return existingThreadId;
658
- }
659
- } catch {}
660
- if (params.message.author?.bot) {
661
- logVerbose(`discord: autoThread skipped for bot-authored message ${messageChannelId}/${params.message.id}`);
662
- return;
663
- }
664
- const rawThreadSource = params.baseText || params.combinedBody || "Thread";
665
- const threadName = sanitizeDiscordThreadName(rawThreadSource, params.message.id);
666
- const archiveDuration = params.channelConfig?.autoArchiveDuration ? Number(params.channelConfig.autoArchiveDuration) : 60;
667
- const createdId = (await createThread(params.client.rest, messageChannelId, { body: {
668
- name: threadName,
669
- auto_archive_duration: archiveDuration
670
- } }, params.message.id))?.id || "";
671
- if (createdId && params.channelConfig?.autoThreadName === "generated" && params.cfg && params.agentId) {
672
- const modelRef = resolveDiscordThreadTitleModelRef({
673
- cfg: params.cfg,
674
- channel: params.channel,
675
- agentId: params.agentId,
676
- threadId: createdId,
677
- messageChannelId,
678
- channelName: params.channelName
679
- });
680
- maybeRenameDiscordAutoThread({
681
- client: params.client,
682
- threadId: createdId,
683
- currentName: threadName,
684
- fallbackId: params.message.id,
685
- sourceText: rawThreadSource,
686
- modelRef,
687
- channelName: params.channelName,
688
- channelDescription: params.channelDescription,
689
- cfg: params.cfg,
690
- agentId: params.agentId
691
- });
692
- }
693
- return createdId || void 0;
694
- } catch (err) {
695
- logVerbose(`discord: autoThread creation failed for ${messageChannelId}/${params.message.id}: ${String(err)}`);
696
- try {
697
- const existingThreadId = (await getChannelMessage(params.client.rest, messageChannelId, params.message.id))?.thread?.id || "";
698
- if (existingThreadId) {
699
- logVerbose(`discord: autoThread reusing existing thread ${existingThreadId} on ${messageChannelId}/${params.message.id}`);
700
- return existingThreadId;
701
- }
702
- } catch {}
703
- return;
704
- }
705
- }
706
- function resolveDiscordThreadTitleModelRef(params) {
707
- const channel = params.channel?.trim();
708
- if (!channel) return;
709
- const parentSessionKey = buildAgentSessionKey({
710
- agentId: params.agentId,
711
- channel,
712
- peer: {
713
- kind: "channel",
714
- id: params.messageChannelId
715
- }
716
- });
717
- const channelLabel = params.channelName?.trim();
718
- const groupChannel = channelLabel ? `#${channelLabel}` : void 0;
719
- return resolveChannelModelOverride({
720
- cfg: params.cfg,
721
- channel,
722
- groupId: params.threadId,
723
- groupChatType: "channel",
724
- groupChannel,
725
- groupSubject: groupChannel,
726
- parentSessionKey
727
- })?.model;
728
- }
729
- async function maybeRenameDiscordAutoThread(params) {
730
- try {
731
- const fallbackName = sanitizeDiscordThreadName("", params.fallbackId);
732
- const generated = await generateThreadTitle({
733
- cfg: params.cfg,
734
- agentId: params.agentId,
735
- messageText: params.sourceText,
736
- modelRef: params.modelRef,
737
- channelName: params.channelName,
738
- channelDescription: params.channelDescription
739
- });
740
- if (!generated) return;
741
- const nextName = sanitizeDiscordThreadName(generated, params.fallbackId);
742
- if (!nextName || nextName === params.currentName || nextName === fallbackName) return;
743
- await editChannel(params.client.rest, params.threadId, { body: { name: nextName } });
744
- } catch (err) {
745
- logVerbose(`discord: autoThread rename failed for ${params.threadId}: ${String(err)}`);
746
- }
747
- }
748
- //#endregion
749
- //#region extensions/discord/src/monitor/threading.ts
750
- var threading_exports = /* @__PURE__ */ __exportAll({
751
- maybeCreateDiscordAutoThread: () => maybeCreateDiscordAutoThread,
752
- resetDiscordThreadStarterCacheForTest: () => resetDiscordThreadStarterCacheForTest,
753
- resolveDiscordAutoThreadContext: () => resolveDiscordAutoThreadContext,
754
- resolveDiscordAutoThreadReplyPlan: () => resolveDiscordAutoThreadReplyPlan,
755
- resolveDiscordReplyDeliveryPlan: () => resolveDiscordReplyDeliveryPlan,
756
- resolveDiscordReplyTarget: () => resolveDiscordReplyTarget,
757
- resolveDiscordThreadChannel: () => resolveDiscordThreadChannel,
758
- resolveDiscordThreadParentInfo: () => resolveDiscordThreadParentInfo,
759
- resolveDiscordThreadStarter: () => resolveDiscordThreadStarter,
760
- sanitizeDiscordThreadName: () => sanitizeDiscordThreadName
761
- });
762
- //#endregion
763
- //#region extensions/discord/src/monitor/thread-channel-context.ts
764
- function isDiscordThreadChannelType(type) {
765
- return type === discord_exports.ChannelType.PublicThread || type === discord_exports.ChannelType.PrivateThread || type === discord_exports.ChannelType.AnnouncementThread;
766
- }
767
- function buildFetchedChannelInfo(channel) {
768
- const channelInfo = resolveDiscordChannelInfoSafe(channel);
769
- if (channelInfo.type === void 0) return null;
770
- return {
771
- type: channelInfo.type,
772
- name: channelInfo.name,
773
- topic: channelInfo.topic,
774
- parentId: channelInfo.parentId,
775
- ownerId: channelInfo.ownerId
513
+ type: channelInfo.type,
514
+ name: channelInfo.name,
515
+ topic: channelInfo.topic,
516
+ parentId: channelInfo.parentId,
517
+ ownerId: channelInfo.ownerId
776
518
  };
777
519
  }
778
520
  async function resolveDiscordThreadLikeChannelContext(params) {
@@ -1090,8 +832,8 @@ async function handleDiscordReactionEvent(params) {
1090
832
  const guildSlug = guildInfo?.slug || (data.guild?.name ? normalizeDiscordSlug(data.guild.name) : data.guild_id ?? (isGroupDm ? "group-dm" : "dm"));
1091
833
  const channelLabel = channelSlug ? `#${channelSlug}` : channelName ? `#${normalizeDiscordSlug(channelName)}` : `#${data.channel_id}`;
1092
834
  reactionBase = {
1093
- baseText: `Discord reaction ${action}: ${emojiLabel} by ${actorLabel} on ${guildSlug} ${channelLabel} msg ${data.message_id}`,
1094
- contextKey: `discord:reaction:${action}:${data.message_id}:${user.id}:${emojiLabel}`
835
+ baseText: `Discord ${data.burst ? "super " : ""}reaction ${action}: ${emojiLabel} by ${actorLabel} on ${guildSlug} ${channelLabel} msg ${data.message_id}`,
836
+ contextKey: `discord:reaction:${action}:${data.message_id}:${user.id}:${emojiLabel}${data.burst ? ":burst" : ""}`
1095
837
  };
1096
838
  return reactionBase;
1097
839
  };
@@ -1101,294 +843,95 @@ async function handleDiscordReactionEvent(params) {
1101
843
  cfg: params.cfg,
1102
844
  channel: "discord",
1103
845
  accountId: params.accountId,
1104
- guildId: data.guild_id ?? void 0,
1105
- memberRoleIds,
1106
- peer: {
1107
- kind: isDirectMessage ? "direct" : isGroupDm ? "group" : "channel",
1108
- id: isDirectMessage ? user.id : data.channel_id
1109
- },
1110
- parentPeer: parentPeerId ? {
1111
- kind: "channel",
1112
- id: parentPeerId
1113
- } : void 0
1114
- }), { contextKey });
1115
- };
1116
- const shouldNotifyReaction = (options) => shouldEmitDiscordReactionNotification({
1117
- mode: options.mode,
1118
- botId: botUserId,
1119
- messageAuthorId: options.messageAuthorId,
1120
- userId: user.id,
1121
- userName: user.username,
1122
- userTag: formatDiscordUserTag(user),
1123
- channelConfig: options.channelConfig,
1124
- guildInfo,
1125
- memberRoleIds,
1126
- allowNameMatching: params.allowNameMatching
1127
- });
1128
- const emitReactionWithAuthor = (message) => {
1129
- const { baseText } = resolveReactionBase();
1130
- const authorLabel = message?.author ? formatDiscordUserTag(message.author) : void 0;
1131
- const text = authorLabel ? `${baseText} from ${authorLabel}` : baseText;
1132
- emitReaction(text, parentId);
1133
- };
1134
- const resolveThreadChannelConfig = () => resolveDiscordChannelConfigWithFallback({
1135
- guildInfo,
1136
- channelId: data.channel_id,
1137
- channelName,
1138
- channelSlug,
1139
- parentId,
1140
- parentName,
1141
- parentSlug,
1142
- scope: "thread"
1143
- });
1144
- const authorizeReactionIngressForChannel = async (channelConfig) => await authorizeDiscordReactionIngress({
1145
- ...reactionIngressBase,
1146
- channelConfig
1147
- });
1148
- const resolveThreadChannelAccess = async () => {
1149
- const channelConfig = resolveThreadChannelConfig();
1150
- return {
1151
- access: await authorizeReactionIngressForChannel(channelConfig),
1152
- channelConfig
1153
- };
1154
- };
1155
- if (isThreadChannel) {
1156
- await handleDiscordThreadReactionNotification({
1157
- reactionMode,
1158
- message: data.message,
1159
- parentId,
1160
- resolveThreadChannelAccess,
1161
- shouldNotifyReaction,
1162
- resolveReactionBase,
1163
- emitReaction,
1164
- emitReactionWithAuthor
1165
- });
1166
- return;
1167
- }
1168
- const channelConfig = resolveDiscordChannelConfigWithFallback({
1169
- guildInfo,
1170
- channelId: data.channel_id,
1171
- channelName,
1172
- channelSlug,
1173
- parentId,
1174
- parentName,
1175
- parentSlug,
1176
- scope: "channel"
1177
- });
1178
- await handleDiscordChannelReactionNotification({
1179
- isGuildMessage,
1180
- reactionMode,
1181
- message: data.message,
1182
- channelConfig,
1183
- parentId,
1184
- authorizeReactionIngressForChannel,
1185
- shouldNotifyReaction,
1186
- resolveReactionBase,
1187
- emitReaction,
1188
- emitReactionWithAuthor
1189
- });
1190
- } catch (err) {
1191
- params.logger.error(danger(`discord reaction handler failed: ${String(err)}`));
1192
- }
1193
- }
1194
- //#endregion
1195
- //#region extensions/discord/src/monitor/presence-events.ts
1196
- const DISCORD_PRESENCE_GREETING_COOLDOWN_MS = 480 * 60 * 1e3;
1197
- function isDiscordOnlineStatus(status) {
1198
- return status === "online" || status === "idle" || status === "dnd";
1199
- }
1200
- function isDiscordOfflineStatus(status) {
1201
- return status === "offline";
1202
- }
1203
- function resolveDiscordOnlinePresenceEvent(params) {
1204
- const config = params.config;
1205
- const userId = params.data.user?.id?.trim();
1206
- if (!config || config.enabled === false || !userId || userId === params.botUserId || params.data.user.bot === true || !isDiscordOnlineStatus(params.data.status) || !params.availabilityKind) return null;
1207
- if (config.users !== void 0 && !config.users.includes(userId)) return null;
1208
- if (params.lastEmittedAtMs !== void 0 && params.nowMs - params.lastEmittedAtMs < 288e5) return null;
1209
- const lines = [
1210
- "Discord online-presence event:",
1211
- params.availabilityKind === "observed-offline" ? `A human member became available online after being observed offline in guild_id=${JSON.stringify(params.data.guild_id)} user_id=${JSON.stringify(userId)} status=${JSON.stringify(params.data.status)}.` : `A human member became newly visible online since the current guild snapshot in guild_id=${JSON.stringify(params.data.guild_id)} user_id=${JSON.stringify(userId)} status=${JSON.stringify(params.data.status)}. They may have come online or joined after the snapshot; do not claim an exact prior status.`,
1212
- `The authorized greeting target is channel_id=${JSON.stringify(config.channelId)}.`,
1213
- "Before greeting, retrieve relevant memory and wiki context for this immutable user_id, including a known timezone when available. Use their local time for the greeting; if their timezone is unknown, do not guess.",
1214
- "Send at most one short, natural greeting to the target channel. Do not reveal private memory. If no greeting is appropriate, stay silent."
1215
- ];
1216
- return {
1217
- channelId: config.channelId,
1218
- userId,
1219
- text: lines.join("\n")
1220
- };
1221
- }
1222
- //#endregion
1223
- //#region extensions/discord/src/monitor/presence-cooldown-store.ts
1224
- const DISCORD_PRESENCE_COOLDOWN_MAX_ENTRIES = 25e3;
1225
- function openDiscordPresenceCooldownStore() {
1226
- return getDiscordRuntime().state.openSyncKeyedStore({
1227
- namespace: "presence-greeting-cooldowns",
1228
- maxEntries: DISCORD_PRESENCE_COOLDOWN_MAX_ENTRIES,
1229
- overflowPolicy: "reject-new",
1230
- defaultTtlMs: DISCORD_PRESENCE_GREETING_COOLDOWN_MS
1231
- });
1232
- }
1233
- //#endregion
1234
- //#region extensions/discord/src/monitor/presence-emission-gate.ts
1235
- const DISCORD_PRESENCE_RECONNECT_SUPPRESS_MS = 300 * 1e3;
1236
- const DISCORD_PRESENCE_BURST_LIMIT = 8;
1237
- const DISCORD_PRESENCE_BURST_WINDOW_MS = 60 * 1e3;
1238
- function resolveDiscordPresenceGateOptions(config) {
1239
- return {
1240
- reconnectSuppressMs: config?.reconnectSuppressSeconds !== void 0 ? config.reconnectSuppressSeconds * 1e3 : DISCORD_PRESENCE_RECONNECT_SUPPRESS_MS,
1241
- burstLimit: config?.burstLimit ?? DISCORD_PRESENCE_BURST_LIMIT,
1242
- burstWindowMs: config?.burstWindowSeconds !== void 0 ? config.burstWindowSeconds * 1e3 : DISCORD_PRESENCE_BURST_WINDOW_MS
1243
- };
1244
- }
1245
- /**
1246
- * Per-account lifecycle gate for online-presence events. Reconnect state belongs to the Gateway
1247
- * session, while burst state follows the guild-owned configuration that supplies its limits.
1248
- */
1249
- var DiscordPresenceEmissionGate = class {
1250
- constructor() {
1251
- this.reconnectLogged = false;
1252
- this.burstByGuild = /* @__PURE__ */ new Map();
1253
- this.nextReservationId = 0;
1254
- }
1255
- noteGatewaySessionReset(nowMs) {
1256
- this.lastSessionResetAtMs = nowMs;
1257
- this.reconnectLogged = false;
1258
- }
1259
- evaluateReconnectWindow(nowMs, options) {
1260
- if (this.lastSessionResetAtMs !== void 0 && options.reconnectSuppressMs > 0 && nowMs - this.lastSessionResetAtMs < options.reconnectSuppressMs) {
1261
- const shouldLog = !this.reconnectLogged;
1262
- this.reconnectLogged = true;
1263
- return {
1264
- allowed: false,
1265
- reason: "reconnect-window",
1266
- shouldLog
1267
- };
1268
- }
1269
- return { allowed: true };
1270
- }
1271
- reserveBurst(guildId, nowMs, options) {
1272
- const state = this.burstByGuild.get(guildId) ?? {
1273
- reservations: [],
1274
- logged: false
1275
- };
1276
- state.reservations = state.reservations.filter((reservation) => !reservation.committed || nowMs - reservation.atMs < options.burstWindowMs);
1277
- this.burstByGuild.set(guildId, state);
1278
- if (state.reservations.length >= options.burstLimit) {
1279
- const shouldLog = !state.logged;
1280
- state.logged = true;
1281
- return {
1282
- allowed: false,
1283
- reason: state.reservations.some((reservation) => !reservation.committed) ? "burst-pending" : "burst",
1284
- shouldLog
1285
- };
1286
- }
1287
- state.logged = false;
1288
- const reservation = {
1289
- id: this.nextReservationId++,
1290
- atMs: nowMs,
1291
- committed: false
1292
- };
1293
- state.reservations.push(reservation);
1294
- return {
1295
- allowed: true,
1296
- reservation: reservation.id
1297
- };
1298
- }
1299
- commitBurst(guildId, reservation, nowMs) {
1300
- const entry = this.burstByGuild.get(guildId)?.reservations.find((candidate) => candidate.id === reservation);
1301
- if (!entry) return;
1302
- entry.atMs = nowMs;
1303
- entry.committed = true;
1304
- }
1305
- releaseBurst(guildId, reservation) {
1306
- const state = this.burstByGuild.get(guildId);
1307
- if (!state) return;
1308
- state.reservations = state.reservations.filter((candidate) => candidate.id !== reservation);
1309
- if (state.reservations.length === 0 && !state.logged) this.burstByGuild.delete(guildId);
1310
- }
1311
- };
1312
- //#endregion
1313
- //#region extensions/discord/src/monitor/presence-transition-cache.ts
1314
- const DEFAULT_PRESENCE_BASELINE_MAX_ENTRIES = 75e3;
1315
- var DiscordPresenceBaselineCache = class {
1316
- constructor(maxEntries = DEFAULT_PRESENCE_BASELINE_MAX_ENTRIES) {
1317
- this.maxEntries = maxEntries;
1318
- this.offlineByKey = /* @__PURE__ */ new Map();
1319
- this.onlineByKey = /* @__PURE__ */ new Map();
1320
- }
1321
- clear() {
1322
- this.offlineByKey.clear();
1323
- this.onlineByKey.clear();
1324
- }
1325
- clearScope(scope) {
1326
- for (const markers of [this.offlineByKey, this.onlineByKey]) for (const [key, markerScope] of markers) if (markerScope === scope) markers.delete(key);
1327
- }
1328
- isOffline(scope, key) {
1329
- return this.offlineByKey.get(key) === scope;
1330
- }
1331
- isOnline(scope, key) {
1332
- return this.onlineByKey.get(key) === scope;
1333
- }
1334
- observeOffline(scope, key) {
1335
- this.deleteMarker(this.onlineByKey, scope, key);
1336
- return this.observe(this.offlineByKey, scope, key);
1337
- }
1338
- observeOnline(scope, key) {
1339
- this.deleteMarker(this.offlineByKey, scope, key);
1340
- return this.observe(this.onlineByKey, scope, key);
1341
- }
1342
- deleteMarker(markers, scope, key) {
1343
- if (markers.get(key) === scope) markers.delete(key);
1344
- }
1345
- observe(markers, scope, key) {
1346
- markers.delete(key);
1347
- markers.set(key, scope);
1348
- let evictedScope;
1349
- while (markers.size > this.maxEntries) {
1350
- const oldestKey = markers.keys().next().value;
1351
- if (oldestKey === void 0) break;
1352
- evictedScope = markers.get(oldestKey);
1353
- markers.delete(oldestKey);
1354
- }
1355
- return evictedScope;
1356
- }
1357
- };
1358
- //#endregion
1359
- //#region extensions/discord/src/monitor/thread-session-close.ts
1360
- /**
1361
- * Closes every session entry in the store whose key contains {@link threadId}.
1362
- * The explicit lifecycle deletion archives the old transcript and guarantees
1363
- * that a later inbound message starts a fresh session in every reset mode.
1364
- */
1365
- async function closeDiscordThreadSessions(params) {
1366
- const { cfg, threadId } = params;
1367
- const normalizedThreadId = normalizeOptionalLowercaseString(threadId) ?? "";
1368
- if (!normalizedThreadId) return 0;
1369
- const segmentRe = new RegExp(`:${normalizedThreadId}(?::|$)`, "i");
1370
- function sessionKeyContainsThreadId(key) {
1371
- return segmentRe.test(key);
1372
- }
1373
- let resetCount = 0;
1374
- for (const agentId of listAgentIds(cfg)) {
1375
- const storePath = resolveStorePath(cfg.session?.store, { agentId });
1376
- for (const { sessionKey, entry } of listSessionEntries({
1377
- agentId,
1378
- storePath,
1379
- readOnly: true
1380
- })) {
1381
- if (!sessionKeyContainsThreadId(sessionKey)) continue;
1382
- if (await deleteSessionEntry({
1383
- archiveTranscript: true,
1384
- expectedSessionId: entry.sessionId ?? null,
1385
- expectedUpdatedAt: entry.updatedAt,
1386
- sessionKey,
1387
- storePath
1388
- })) resetCount += 1;
846
+ guildId: data.guild_id ?? void 0,
847
+ memberRoleIds,
848
+ peer: {
849
+ kind: isDirectMessage ? "direct" : isGroupDm ? "group" : "channel",
850
+ id: isDirectMessage ? user.id : data.channel_id
851
+ },
852
+ parentPeer: parentPeerId ? {
853
+ kind: "channel",
854
+ id: parentPeerId
855
+ } : void 0
856
+ }), { contextKey });
857
+ };
858
+ const shouldNotifyReaction = (options) => shouldEmitDiscordReactionNotification({
859
+ mode: options.mode,
860
+ botId: botUserId,
861
+ messageAuthorId: options.messageAuthorId,
862
+ userId: user.id,
863
+ userName: user.username,
864
+ userTag: formatDiscordUserTag(user),
865
+ channelConfig: options.channelConfig,
866
+ guildInfo,
867
+ memberRoleIds,
868
+ allowNameMatching: params.allowNameMatching
869
+ });
870
+ const emitReactionWithAuthor = (message) => {
871
+ const { baseText } = resolveReactionBase();
872
+ const authorLabel = message?.author ? formatDiscordUserTag(message.author) : void 0;
873
+ const text = authorLabel ? `${baseText} from ${authorLabel}` : baseText;
874
+ emitReaction(text, parentId);
875
+ };
876
+ const resolveThreadChannelConfig = () => resolveDiscordChannelConfigWithFallback({
877
+ guildInfo,
878
+ channelId: data.channel_id,
879
+ channelName,
880
+ channelSlug,
881
+ parentId,
882
+ parentName,
883
+ parentSlug,
884
+ scope: "thread"
885
+ });
886
+ const authorizeReactionIngressForChannel = async (channelConfig) => await authorizeDiscordReactionIngress({
887
+ ...reactionIngressBase,
888
+ channelConfig
889
+ });
890
+ const resolveThreadChannelAccess = async () => {
891
+ const channelConfig = resolveThreadChannelConfig();
892
+ return {
893
+ access: await authorizeReactionIngressForChannel(channelConfig),
894
+ channelConfig
895
+ };
896
+ };
897
+ if (isThreadChannel) {
898
+ await handleDiscordThreadReactionNotification({
899
+ reactionMode,
900
+ message: data.message,
901
+ parentId,
902
+ resolveThreadChannelAccess,
903
+ shouldNotifyReaction,
904
+ resolveReactionBase,
905
+ emitReaction,
906
+ emitReactionWithAuthor
907
+ });
908
+ return;
1389
909
  }
910
+ const channelConfig = resolveDiscordChannelConfigWithFallback({
911
+ guildInfo,
912
+ channelId: data.channel_id,
913
+ channelName,
914
+ channelSlug,
915
+ parentId,
916
+ parentName,
917
+ parentSlug,
918
+ scope: "channel"
919
+ });
920
+ await handleDiscordChannelReactionNotification({
921
+ isGuildMessage,
922
+ reactionMode,
923
+ message: data.message,
924
+ channelConfig,
925
+ parentId,
926
+ authorizeReactionIngressForChannel,
927
+ shouldNotifyReaction,
928
+ resolveReactionBase,
929
+ emitReaction,
930
+ emitReactionWithAuthor
931
+ });
932
+ } catch (err) {
933
+ params.logger.error(danger(`discord reaction handler failed: ${String(err)}`));
1390
934
  }
1391
- return resetCount;
1392
935
  }
1393
936
  //#endregion
1394
937
  //#region extensions/discord/src/monitor/listeners.ts
@@ -1815,11 +1358,16 @@ function isDiscordUnknownInteraction(error) {
1815
1358
  if (/Unknown interaction/i.test(err.rawBody?.message ?? "")) return true;
1816
1359
  return false;
1817
1360
  }
1361
+ function resolveDiscordInteractionMessageParts(payload) {
1362
+ const { components, embeds } = payload.channelData?.discord ?? {};
1363
+ return {
1364
+ components: Array.isArray(components) && components.length > 0 ? components : void 0,
1365
+ embeds: Array.isArray(embeds) && embeds.length > 0 ? embeds : void 0
1366
+ };
1367
+ }
1818
1368
  function hasRenderableReplyPayload(payload) {
1819
- if (resolveSendableOutboundReplyParts(payload).hasContent) return true;
1820
- const discordData = payload.channelData?.discord;
1821
- if (Array.isArray(discordData?.components) && discordData.components.length > 0) return true;
1822
- return false;
1369
+ const { components, embeds } = resolveDiscordInteractionMessageParts(payload);
1370
+ return resolveSendableOutboundReplyParts(payload).hasContent || Boolean(components || embeds);
1823
1371
  }
1824
1372
  async function safeDiscordInteractionCall(label, fn) {
1825
1373
  try {
@@ -1839,33 +1387,25 @@ async function settleDiscordInteractionWithoutVisibleReply(interaction) {
1839
1387
  async function deliverDiscordInteractionReply(params) {
1840
1388
  const { interaction, payload, textLimit, maxLinesPerMessage, preferFollowUp, chunkMode } = params;
1841
1389
  const reply = resolveSendableOutboundReplyParts(payload);
1842
- const discordData = payload.channelData?.discord;
1843
- let firstMessageComponents = Array.isArray(discordData?.components) && discordData.components.length > 0 ? discordData.components : void 0;
1390
+ let { components: firstMessageComponents, embeds: firstMessageEmbeds } = resolveDiscordInteractionMessageParts(payload);
1844
1391
  let payloadDelivered = false;
1845
- const sendMessage = async (content, files, components) => {
1846
- const contentPayload = content ? { content } : {};
1847
- const payloadLocal = files && files.length > 0 ? {
1848
- ...contentPayload,
1392
+ const sendMessage = async (content, files, components, embeds) => {
1393
+ const hasV2 = hasDiscordV2Components(components);
1394
+ const payloadLocal = {
1395
+ ...content && !hasV2 ? { content } : {},
1849
1396
  ...components ? { components } : {},
1397
+ ...embeds && !hasV2 ? { embeds } : {},
1850
1398
  ...params.responseEphemeral !== void 0 ? { ephemeral: params.responseEphemeral } : {},
1851
- files
1852
- } : {
1853
- ...contentPayload,
1854
- ...components ? { components } : {},
1855
- ...params.responseEphemeral !== void 0 ? { ephemeral: params.responseEphemeral } : {}
1399
+ ...files?.length ? { files } : {}
1856
1400
  };
1857
1401
  let result;
1858
1402
  try {
1859
1403
  result = await safeDiscordInteractionCall("interaction send", async () => {
1860
- if (!preferFollowUp && !payloadDelivered) {
1861
- await interaction.reply(payloadLocal);
1862
- payloadDelivered = true;
1863
- firstMessageComponents = void 0;
1864
- return;
1865
- }
1866
- await interaction.followUp(payloadLocal);
1404
+ if (!preferFollowUp && !payloadDelivered) await interaction.reply(payloadLocal);
1405
+ else await interaction.followUp(payloadLocal);
1867
1406
  payloadDelivered = true;
1868
1407
  firstMessageComponents = void 0;
1408
+ firstMessageEmbeds = void 0;
1869
1409
  });
1870
1410
  } catch (error) {
1871
1411
  if (!payloadDelivered) throw error;
@@ -1890,99 +1430,27 @@ async function deliverDiscordInteractionReply(params) {
1890
1430
  maxLines: maxLinesPerMessage,
1891
1431
  chunkMode
1892
1432
  }));
1893
- await sendMessage(chunks[0] ?? "", media, firstMessageComponents);
1433
+ await sendMessage(chunks[0] ?? "", media, firstMessageComponents, firstMessageEmbeds);
1894
1434
  for (const chunk of chunks.slice(1)) {
1895
1435
  if (!chunk.trim()) continue;
1896
1436
  await sendMessage(chunk);
1897
1437
  }
1898
1438
  return payloadDelivered;
1899
1439
  }
1900
- if (!reply.hasText && !firstMessageComponents) return false;
1901
- let chunks = reply.text || firstMessageComponents ? resolveTextChunksWithFallback(reply.text, chunkDiscordTextWithMode(reply.text, {
1440
+ if (!reply.hasText && !firstMessageComponents && !firstMessageEmbeds) return false;
1441
+ const chunks = resolveTextChunksWithFallback(reply.text, chunkDiscordTextWithMode(reply.text, {
1902
1442
  maxChars: textLimit,
1903
1443
  maxLines: maxLinesPerMessage,
1904
1444
  chunkMode
1905
- })) : [];
1906
- if (chunks.length === 0 && firstMessageComponents) chunks = [""];
1445
+ }));
1446
+ if (chunks.length === 0) chunks.push("");
1907
1447
  for (const chunk of chunks) {
1908
- if (!chunk.trim() && !firstMessageComponents) continue;
1909
- await sendMessage(chunk, void 0, firstMessageComponents);
1448
+ if (!chunk.trim() && !firstMessageComponents && !firstMessageEmbeds) continue;
1449
+ await sendMessage(chunk, void 0, firstMessageComponents, firstMessageEmbeds);
1910
1450
  }
1911
1451
  return payloadDelivered;
1912
1452
  }
1913
1453
  //#endregion
1914
- //#region extensions/discord/src/monitor/route-resolution.ts
1915
- function buildDiscordRoutePeer(params) {
1916
- return {
1917
- kind: params.isDirectMessage ? "direct" : params.isGroupDm ? "group" : "channel",
1918
- id: params.isDirectMessage ? params.directUserId?.trim() || params.conversationId : params.conversationId
1919
- };
1920
- }
1921
- function resolveDiscordConversationRoute(params) {
1922
- return resolveAgentRoute({
1923
- cfg: params.cfg,
1924
- channel: "discord",
1925
- accountId: params.accountId,
1926
- guildId: params.guildId ?? void 0,
1927
- memberRoleIds: params.memberRoleIds,
1928
- peer: params.peer,
1929
- parentPeer: params.parentConversationId ? {
1930
- kind: "channel",
1931
- id: params.parentConversationId
1932
- } : void 0
1933
- });
1934
- }
1935
- function resolveDiscordBoundConversationRoute(params) {
1936
- return resolveDiscordEffectiveRoute({
1937
- route: resolveDiscordConversationRoute({
1938
- cfg: params.cfg,
1939
- accountId: params.accountId,
1940
- guildId: params.guildId,
1941
- memberRoleIds: params.memberRoleIds,
1942
- peer: buildDiscordRoutePeer({
1943
- isDirectMessage: params.isDirectMessage,
1944
- isGroupDm: params.isGroupDm,
1945
- directUserId: params.directUserId,
1946
- conversationId: params.conversationId
1947
- }),
1948
- parentConversationId: params.parentConversationId
1949
- }),
1950
- boundSessionKey: params.boundSessionKey,
1951
- configuredRoute: params.configuredRoute,
1952
- matchedBy: params.matchedBy
1953
- });
1954
- }
1955
- function resolveDiscordEffectiveRoute(params) {
1956
- const boundSessionKey = params.boundSessionKey?.trim();
1957
- if (!boundSessionKey) return params.configuredRoute?.route ?? params.route;
1958
- return {
1959
- ...params.route,
1960
- sessionKey: boundSessionKey,
1961
- agentId: resolveAgentIdFromSessionKey(boundSessionKey),
1962
- lastRoutePolicy: deriveLastRoutePolicy({
1963
- sessionKey: boundSessionKey,
1964
- mainSessionKey: params.route.mainSessionKey
1965
- }),
1966
- ...params.matchedBy ? { matchedBy: params.matchedBy } : {}
1967
- };
1968
- }
1969
- function hasExplicitRuntimeBindingIntent(record) {
1970
- if (record.targetKind === "subagent") return true;
1971
- if (isAcpSessionKey(record.targetSessionKey) || isSubagentSessionKey(record.targetSessionKey)) return true;
1972
- const metadata = record.metadata;
1973
- if (!metadata || typeof metadata !== "object") return false;
1974
- return typeof metadata.boundBy === "string" || typeof metadata.label === "string" || typeof metadata.threadName === "string" || metadata.pluginBindingOwner === "plugin";
1975
- }
1976
- function shouldIgnoreStaleDiscordRouteBinding(params) {
1977
- const bindingRecord = params.bindingRecord;
1978
- const boundSessionKey = bindingRecord?.targetSessionKey?.trim();
1979
- if (!bindingRecord || !boundSessionKey || hasExplicitRuntimeBindingIntent(bindingRecord)) return false;
1980
- const bound = parseAgentSessionKey(boundSessionKey);
1981
- const routed = parseAgentSessionKey(params.route.sessionKey);
1982
- if (!bound || !routed || bound.rest !== routed.rest) return false;
1983
- return bound.agentId !== params.route.agentId;
1984
- }
1985
- //#endregion
1986
1454
  //#region extensions/discord/src/monitor/native-command-route.ts
1987
1455
  async function resolveDiscordNativeInteractionRouteState(params) {
1988
1456
  const route = resolveDiscordBoundConversationRoute({
@@ -2050,6 +1518,7 @@ async function dispatchDiscordNativeAgentReply(params) {
2050
1518
  sessionKey: params.ctxPayload.SessionKey ?? params.effectiveRoute.sessionKey
2051
1519
  },
2052
1520
  ctxPayload: params.ctxPayload,
1521
+ dispatchReplyFromConfig: params.dispatchReplyFromConfig,
2053
1522
  delivery: {
2054
1523
  deliver: async (payload) => {
2055
1524
  if (params.suppressReplies) return {
@@ -2099,28 +1568,171 @@ async function dispatchDiscordNativeAgentReply(params) {
2099
1568
  disableBlockStreaming: typeof blockStreamingEnabled === "boolean" ? !blockStreamingEnabled : void 0
2100
1569
  }
2101
1570
  });
2102
- const deliberateSilentTerminalReply = turnResult.dispatched && turnResult.dispatchResult.deliberateSilentTerminalReply === true;
2103
- const dispatchResult = {
2104
- dispatched: turnResult.dispatched,
2105
- ...hiddenFinalReply ? { hiddenFinalReply } : {}
1571
+ const deliberateSilentTerminalReply = turnResult.dispatched && turnResult.dispatchResult.deliberateSilentTerminalReply === true;
1572
+ const dispatchResult = {
1573
+ dispatched: turnResult.dispatched,
1574
+ ...hiddenFinalReply ? { hiddenFinalReply } : {}
1575
+ };
1576
+ if (!didReply && (params.suppressReplies || finalReplyOutcome === "suppressed" || deliberateSilentTerminalReply)) {
1577
+ await settleDiscordInteractionWithoutVisibleReply(params.interaction);
1578
+ return dispatchResult;
1579
+ }
1580
+ if (didReply || turnResult.dispatched && hasVisibleInboundReplyDispatch(turnResult.dispatchResult)) return dispatchResult;
1581
+ await safeDiscordInteractionCall("interaction empty fallback", async () => {
1582
+ const payload = {
1583
+ content: DISCORD_EMPTY_VISIBLE_REPLY_WARNING,
1584
+ ephemeral: true
1585
+ };
1586
+ if (params.preferFollowUp) {
1587
+ await params.interaction.followUp(payload);
1588
+ return;
1589
+ }
1590
+ await params.interaction.reply(payload);
1591
+ });
1592
+ return dispatchResult;
1593
+ }
1594
+ //#endregion
1595
+ //#region extensions/discord/src/monitor/commands.ts
1596
+ function resolveDiscordSlashCommandConfig(raw) {
1597
+ return { ephemeral: raw?.ephemeral !== false };
1598
+ }
1599
+ //#endregion
1600
+ //#region extensions/discord/src/monitor/native-command-arg-ui.ts
1601
+ const DISCORD_COMMAND_ARG_CUSTOM_ID_KEY = "cmdarg";
1602
+ function createCommandArgsWithValue(params) {
1603
+ return { values: { [params.argName]: params.value } };
1604
+ }
1605
+ function buildDiscordCommandArgCustomId(params) {
1606
+ return [
1607
+ `${DISCORD_COMMAND_ARG_CUSTOM_ID_KEY}:command=${encodeCustomIdComponent(params.command)}`,
1608
+ `arg=${encodeCustomIdComponent(params.arg)}`,
1609
+ `value=${encodeCustomIdComponent(params.value)}`,
1610
+ `user=${encodeCustomIdComponent(params.userId)}`
1611
+ ].join(";");
1612
+ }
1613
+ function parseDiscordCommandArgData(data) {
1614
+ if (!data || typeof data !== "object") return null;
1615
+ const coerce = (value) => typeof value === "string" || typeof value === "number" ? String(value) : "";
1616
+ const rawCommand = coerce(data.command);
1617
+ const rawArg = coerce(data.arg);
1618
+ const rawValue = coerce(data.value);
1619
+ const rawUser = coerce(data.user);
1620
+ if (!rawCommand || !rawArg || !rawValue || !rawUser) return null;
1621
+ return {
1622
+ command: decodeCustomIdComponent(rawCommand),
1623
+ arg: decodeCustomIdComponent(rawArg),
1624
+ value: decodeCustomIdComponent(rawValue),
1625
+ userId: decodeCustomIdComponent(rawUser)
1626
+ };
1627
+ }
1628
+ async function handleDiscordCommandArgInteraction(params) {
1629
+ const { interaction, data, ctx } = params;
1630
+ const clearWithMessage = async (content) => await params.safeInteractionCall("command arg update", () => interaction.update({
1631
+ content,
1632
+ components: []
1633
+ }));
1634
+ const parsed = parseDiscordCommandArgData(data);
1635
+ if (!parsed) {
1636
+ await clearWithMessage("Sorry, that selection is no longer available.");
1637
+ return;
1638
+ }
1639
+ if (interaction.user?.id && interaction.user.id !== parsed.userId) {
1640
+ await params.safeInteractionCall("command arg ack", () => interaction.acknowledge());
1641
+ return;
1642
+ }
1643
+ const commandDefinition = findCommandByNativeName(parsed.command, "discord") ?? listChatCommands().find((entry) => entry.key === parsed.command);
1644
+ if (!commandDefinition) {
1645
+ await clearWithMessage("Sorry, that command is no longer available.");
1646
+ return;
1647
+ }
1648
+ if (await clearWithMessage(`⏳ Applying ${parsed.value}...`) === null) return;
1649
+ const commandArgs = createCommandArgsWithValue({
1650
+ argName: parsed.arg,
1651
+ value: parsed.value
1652
+ });
1653
+ const commandArgsWithRaw = {
1654
+ ...commandArgs,
1655
+ raw: serializeCommandArgs(commandDefinition, commandArgs)
1656
+ };
1657
+ const prompt = buildCommandTextFromArgs(commandDefinition, commandArgsWithRaw);
1658
+ await params.dispatchCommandInteraction({
1659
+ interaction,
1660
+ prompt,
1661
+ command: commandDefinition,
1662
+ commandArgs: commandArgsWithRaw,
1663
+ cfg: ctx.cfg,
1664
+ discordConfig: ctx.discordConfig,
1665
+ accountId: ctx.accountId,
1666
+ sessionPrefix: ctx.sessionPrefix,
1667
+ preferFollowUp: true,
1668
+ threadBindings: ctx.threadBindings,
1669
+ responseEphemeral: resolveDiscordSlashCommandConfig(ctx.discordConfig?.slashCommand).ephemeral,
1670
+ dispatchReplyFromConfig: ctx.dispatchReplyFromConfig,
1671
+ pluginCommandDispatch: { kind: "non-plugin" }
1672
+ });
1673
+ }
1674
+ async function runDiscordCommandArgButton(params) {
1675
+ await handleDiscordCommandArgInteraction(params);
1676
+ }
1677
+ var DiscordCommandArgButton = class extends Button {
1678
+ constructor(params) {
1679
+ super();
1680
+ this.style = ButtonStyle.Secondary;
1681
+ this.label = params.label;
1682
+ this.customId = params.customId;
1683
+ this.params = params;
1684
+ }
1685
+ async run(interaction, data) {
1686
+ await runDiscordCommandArgButton({
1687
+ ...this.params,
1688
+ interaction,
1689
+ data
1690
+ });
1691
+ }
1692
+ };
1693
+ function buildDiscordCommandArgMenu(params) {
1694
+ const { command, menu, interaction } = params;
1695
+ const commandLabel = command.nativeName ?? command.key;
1696
+ const userId = interaction.user?.id ?? "";
1697
+ const rows = chunkItems(menu.choices, 4).map((choices) => {
1698
+ return new Row(choices.map((choice) => new DiscordCommandArgButton({
1699
+ label: choice.label,
1700
+ customId: buildDiscordCommandArgCustomId({
1701
+ command: commandLabel,
1702
+ arg: menu.arg.name,
1703
+ value: choice.value,
1704
+ userId
1705
+ }),
1706
+ ctx: params.ctx,
1707
+ safeInteractionCall: params.safeInteractionCall,
1708
+ dispatchCommandInteraction: params.dispatchCommandInteraction
1709
+ })));
1710
+ });
1711
+ return {
1712
+ content: formatCommandArgMenuTitle({
1713
+ command,
1714
+ menu
1715
+ }),
1716
+ components: rows
2106
1717
  };
2107
- if (!didReply && (params.suppressReplies || finalReplyOutcome === "suppressed" || deliberateSilentTerminalReply)) {
2108
- await settleDiscordInteractionWithoutVisibleReply(params.interaction);
2109
- return dispatchResult;
1718
+ }
1719
+ var DiscordCommandArgFallbackButton = class extends Button {
1720
+ constructor(params) {
1721
+ super();
1722
+ this.params = params;
1723
+ this.label = "cmdarg";
1724
+ this.customId = "cmdarg:seed=1";
2110
1725
  }
2111
- if (didReply || turnResult.dispatched && hasVisibleInboundReplyDispatch(turnResult.dispatchResult)) return dispatchResult;
2112
- await safeDiscordInteractionCall("interaction empty fallback", async () => {
2113
- const payload = {
2114
- content: DISCORD_EMPTY_VISIBLE_REPLY_WARNING,
2115
- ephemeral: true
2116
- };
2117
- if (params.preferFollowUp) {
2118
- await params.interaction.followUp(payload);
2119
- return;
2120
- }
2121
- await params.interaction.reply(payload);
2122
- });
2123
- return dispatchResult;
1726
+ async run(interaction, data) {
1727
+ await runDiscordCommandArgButton({
1728
+ ...this.params,
1729
+ interaction,
1730
+ data
1731
+ });
1732
+ }
1733
+ };
1734
+ function createDiscordCommandArgFallbackButton$1(params) {
1735
+ return new DiscordCommandArgFallbackButton(params);
2124
1736
  }
2125
1737
  //#endregion
2126
1738
  //#region extensions/discord/src/monitor/native-interaction-channel-context.ts
@@ -2398,11 +2010,11 @@ async function resolveDiscordNativeAutocompleteAuthorized(params) {
2398
2010
  //#endregion
2399
2011
  //#region extensions/discord/src/monitor/native-command-bypass.ts
2400
2012
  function shouldBypassConfiguredAcpEnsure(commandName) {
2401
- return normalizeLowercaseStringOrEmpty(commandName) === "acp";
2013
+ return commandName.trim().toLowerCase() === "acp";
2402
2014
  }
2403
2015
  function shouldBypassConfiguredAcpGuildGuards(commandName) {
2404
- const normalized = normalizeLowercaseStringOrEmpty(commandName);
2405
- return normalized === "new" || normalized === "reset";
2016
+ const command = commandName.trim().toLowerCase();
2017
+ return command === "new" || command === "reset";
2406
2018
  }
2407
2019
  //#endregion
2408
2020
  //#region extensions/discord/src/monitor/inbound-context.ts
@@ -2423,279 +2035,103 @@ function createDiscordSupplementalContextAccessChecker(params) {
2423
2035
  userName: sender.name,
2424
2036
  userTag: sender.tag,
2425
2037
  allowNameMatching: params.allowNameMatching
2426
- })
2427
- });
2428
- };
2429
- }
2430
- function buildDiscordGroupSystemPrompt(channelConfig) {
2431
- const systemPromptParts = [channelConfig?.systemPrompt?.trim() || null].filter((entry) => Boolean(entry));
2432
- return systemPromptParts.length > 0 ? systemPromptParts.join("\n\n") : void 0;
2433
- }
2434
- function buildDiscordChannelStructuredContext(params) {
2435
- if (!params.isGuild) return;
2436
- const entries = [];
2437
- if (typeof params.channelTopic === "string" && params.channelTopic.trim().length > 0) entries.push({
2438
- label: "Discord channel metadata",
2439
- source: "discord",
2440
- type: "channel_metadata",
2441
- payload: { topic: params.channelTopic.trim() }
2442
- });
2443
- return entries.length > 0 ? entries : void 0;
2444
- }
2445
- function buildDiscordInboundAccessContext(params) {
2446
- return {
2447
- groupSystemPrompt: params.isGuild ? buildDiscordGroupSystemPrompt(params.channelConfig) : void 0,
2448
- channelStructuredContext: buildDiscordChannelStructuredContext({
2449
- isGuild: params.isGuild,
2450
- channelTopic: params.channelTopic
2451
- }),
2452
- ownerAllowFrom: resolveDiscordOwnerAllowFrom({
2453
- channelConfig: params.channelConfig,
2454
- guildInfo: params.guildInfo,
2455
- sender: params.sender,
2456
- allowNameMatching: params.allowNameMatching
2457
- })
2458
- };
2459
- }
2460
- //#endregion
2461
- //#region extensions/discord/src/monitor/native-command-context.ts
2462
- function buildDiscordNativeCommandContext(params) {
2463
- const conversationLabel = params.isDirectMessage ? params.user.globalName ?? params.user.username : params.channelId;
2464
- const { groupSystemPrompt, ownerAllowFrom, channelStructuredContext } = buildDiscordInboundAccessContext({
2465
- channelConfig: params.channelConfig,
2466
- guildInfo: params.guildInfo,
2467
- sender: params.sender,
2468
- allowNameMatching: params.allowNameMatching,
2469
- isGuild: params.isGuild,
2470
- channelTopic: params.channelTopic
2471
- });
2472
- return finalizeInboundContext({
2473
- Body: params.prompt,
2474
- BodyForAgent: params.prompt,
2475
- RawBody: params.prompt,
2476
- CommandBody: params.prompt,
2477
- CommandArgs: params.commandArgs,
2478
- From: params.isDirectMessage ? `discord:${params.user.id}` : params.isGroupDm ? `discord:group:${params.channelId}` : `discord:channel:${params.channelId}`,
2479
- To: `slash:${params.user.id}`,
2480
- SessionKey: params.sessionKey,
2481
- CommandTargetSessionKey: params.commandTargetSessionKey,
2482
- AccountId: params.accountId ?? void 0,
2483
- ChatType: params.isDirectMessage ? "direct" : params.isGroupDm ? "group" : "channel",
2484
- ConversationLabel: conversationLabel,
2485
- GroupSubject: params.isGuild ? params.guildName : void 0,
2486
- GroupSpace: params.isGuild ? params.guildInfo?.id ?? params.guildInfo?.slug ?? params.guildId : void 0,
2487
- MemberRoleIds: params.memberRoleIds,
2488
- GroupSystemPrompt: groupSystemPrompt,
2489
- ChannelStructuredContext: channelStructuredContext,
2490
- OwnerAllowFrom: ownerAllowFrom,
2491
- SenderName: params.user.globalName ?? params.user.username,
2492
- SenderId: params.user.id,
2493
- SenderUsername: params.user.username,
2494
- SenderTag: params.sender.tag,
2495
- Provider: "discord",
2496
- Surface: "discord",
2497
- WasMentioned: true,
2498
- MessageSid: params.interactionId,
2499
- MessageThreadId: params.isThreadChannel ? params.channelId : void 0,
2500
- Timestamp: params.timestampMs ?? Date.now(),
2501
- CommandAuthorized: params.commandAuthorized,
2502
- CommandTurn: {
2503
- kind: "native",
2504
- source: "native",
2505
- authorized: params.commandAuthorized,
2506
- body: params.prompt
2507
- },
2508
- CommandSource: "native",
2509
- OriginatingChannel: "discord",
2510
- OriginatingTo: resolveDiscordConversationIdentity({
2511
- isDirectMessage: params.isDirectMessage,
2512
- userId: params.user.id,
2513
- channelId: params.channelId
2514
- }) ?? (params.isDirectMessage ? `user:${params.user.id}` : `channel:${params.channelId}`),
2515
- ThreadParentId: params.isThreadChannel ? params.threadParentId : void 0
2516
- });
2517
- }
2518
- //#endregion
2519
- //#region extensions/discord/src/monitor/native-command-status.ts
2520
- async function maybeDeliverDiscordDirectStatus(params) {
2521
- if (params.suppressReplies || params.commandName !== "status") return null;
2522
- const statusReply = await params.resolveDirectStatusReplyForSession({
2523
- cfg: params.cfg,
2524
- sessionKey: params.commandTargetSessionKey?.trim() || params.sessionKey,
2525
- channel: params.channel,
2526
- senderId: params.senderId,
2527
- senderIsOwner: params.senderIsOwner,
2528
- isAuthorizedSender: params.isAuthorizedSender,
2529
- isGroup: params.isGroup,
2530
- defaultGroupActivation: params.defaultGroupActivation
2531
- });
2532
- if (statusReply && hasRenderableReplyPayload(statusReply)) {
2533
- await deliverDiscordInteractionReply({
2534
- interaction: params.interaction,
2535
- payload: statusReply,
2536
- mediaLocalRoots: params.mediaLocalRoots,
2537
- textLimit: resolveTextChunkLimit(params.cfg, "discord", params.accountId, { fallbackLimit: 2e3 }),
2538
- maxLinesPerMessage: resolveDiscordMaxLinesPerMessage({
2539
- cfg: params.cfg,
2540
- discordConfig: params.discordConfig,
2541
- accountId: params.accountId
2542
- }),
2543
- preferFollowUp: params.preferFollowUp,
2544
- responseEphemeral: params.responseEphemeral,
2545
- chunkMode: resolveChunkMode(params.cfg, "discord", params.accountId)
2546
- });
2547
- return {
2548
- accepted: true,
2549
- effectiveRoute: params.effectiveRoute
2550
- };
2551
- }
2552
- await params.respond("Status unavailable.");
2553
- return {
2554
- accepted: true,
2555
- effectiveRoute: params.effectiveRoute
2556
- };
2557
- }
2558
- //#endregion
2559
- //#region extensions/discord/src/monitor/commands.ts
2560
- function resolveDiscordSlashCommandConfig(raw) {
2561
- return { ephemeral: raw?.ephemeral !== false };
2562
- }
2563
- //#endregion
2564
- //#region extensions/discord/src/monitor/native-command-arg-ui.ts
2565
- const DISCORD_COMMAND_ARG_CUSTOM_ID_KEY = "cmdarg";
2566
- function createCommandArgsWithValue(params) {
2567
- return { values: { [params.argName]: params.value } };
2568
- }
2569
- function buildDiscordCommandArgCustomId(params) {
2570
- return [
2571
- `${DISCORD_COMMAND_ARG_CUSTOM_ID_KEY}:command=${encodeCustomIdComponent(params.command)}`,
2572
- `arg=${encodeCustomIdComponent(params.arg)}`,
2573
- `value=${encodeCustomIdComponent(params.value)}`,
2574
- `user=${encodeCustomIdComponent(params.userId)}`
2575
- ].join(";");
2576
- }
2577
- function parseDiscordCommandArgData(data) {
2578
- if (!data || typeof data !== "object") return null;
2579
- const coerce = (value) => typeof value === "string" || typeof value === "number" ? String(value) : "";
2580
- const rawCommand = coerce(data.command);
2581
- const rawArg = coerce(data.arg);
2582
- const rawValue = coerce(data.value);
2583
- const rawUser = coerce(data.user);
2584
- if (!rawCommand || !rawArg || !rawValue || !rawUser) return null;
2585
- return {
2586
- command: decodeCustomIdComponent(rawCommand),
2587
- arg: decodeCustomIdComponent(rawArg),
2588
- value: decodeCustomIdComponent(rawValue),
2589
- userId: decodeCustomIdComponent(rawUser)
2590
- };
2591
- }
2592
- async function handleDiscordCommandArgInteraction(params) {
2593
- const { interaction, data, ctx } = params;
2594
- const clearWithMessage = async (content) => await params.safeInteractionCall("command arg update", () => interaction.update({
2595
- content,
2596
- components: []
2597
- }));
2598
- const parsed = parseDiscordCommandArgData(data);
2599
- if (!parsed) {
2600
- await clearWithMessage("Sorry, that selection is no longer available.");
2601
- return;
2602
- }
2603
- if (interaction.user?.id && interaction.user.id !== parsed.userId) {
2604
- await params.safeInteractionCall("command arg ack", () => interaction.acknowledge());
2605
- return;
2606
- }
2607
- const commandDefinition = findCommandByNativeName(parsed.command, "discord") ?? listChatCommands().find((entry) => entry.key === parsed.command);
2608
- if (!commandDefinition) {
2609
- await clearWithMessage("Sorry, that command is no longer available.");
2610
- return;
2611
- }
2612
- if (await clearWithMessage(`⏳ Applying ${parsed.value}...`) === null) return;
2613
- const commandArgs = createCommandArgsWithValue({
2614
- argName: parsed.arg,
2615
- value: parsed.value
2616
- });
2617
- const commandArgsWithRaw = {
2618
- ...commandArgs,
2619
- raw: serializeCommandArgs(commandDefinition, commandArgs)
2620
- };
2621
- const prompt = buildCommandTextFromArgs(commandDefinition, commandArgsWithRaw);
2622
- await params.dispatchCommandInteraction({
2623
- interaction,
2624
- prompt,
2625
- command: commandDefinition,
2626
- commandArgs: commandArgsWithRaw,
2627
- cfg: ctx.cfg,
2628
- discordConfig: ctx.discordConfig,
2629
- accountId: ctx.accountId,
2630
- sessionPrefix: ctx.sessionPrefix,
2631
- preferFollowUp: true,
2632
- threadBindings: ctx.threadBindings,
2633
- responseEphemeral: resolveDiscordSlashCommandConfig(ctx.discordConfig?.slashCommand).ephemeral,
2634
- pluginCommandDispatch: { kind: "non-plugin" }
2635
- });
2038
+ })
2039
+ });
2040
+ };
2636
2041
  }
2637
- async function runDiscordCommandArgButton(params) {
2638
- await handleDiscordCommandArgInteraction(params);
2042
+ function buildDiscordGroupSystemPrompt(channelConfig) {
2043
+ const systemPromptParts = [channelConfig?.systemPrompt?.trim() || null].filter((entry) => Boolean(entry));
2044
+ return systemPromptParts.length > 0 ? systemPromptParts.join("\n\n") : void 0;
2639
2045
  }
2640
- var DiscordCommandArgButton = class extends Button {
2641
- constructor(params) {
2642
- super();
2643
- this.style = ButtonStyle.Secondary;
2644
- this.label = params.label;
2645
- this.customId = params.customId;
2646
- this.params = params;
2647
- }
2648
- async run(interaction, data) {
2649
- await runDiscordCommandArgButton({
2650
- ...this.params,
2651
- interaction,
2652
- data
2653
- });
2654
- }
2655
- };
2656
- function buildDiscordCommandArgMenu(params) {
2657
- const { command, menu, interaction } = params;
2658
- const commandLabel = command.nativeName ?? command.key;
2659
- const userId = interaction.user?.id ?? "";
2660
- const rows = chunkItems(menu.choices, 4).map((choices) => {
2661
- return new Row(choices.map((choice) => new DiscordCommandArgButton({
2662
- label: choice.label,
2663
- customId: buildDiscordCommandArgCustomId({
2664
- command: commandLabel,
2665
- arg: menu.arg.name,
2666
- value: choice.value,
2667
- userId
2668
- }),
2669
- ctx: params.ctx,
2670
- safeInteractionCall: params.safeInteractionCall,
2671
- dispatchCommandInteraction: params.dispatchCommandInteraction
2672
- })));
2046
+ function buildDiscordChannelStructuredContext(params) {
2047
+ if (!params.isGuild) return;
2048
+ const entries = [];
2049
+ if (typeof params.channelTopic === "string" && params.channelTopic.trim().length > 0) entries.push({
2050
+ label: "Discord channel metadata",
2051
+ source: "discord",
2052
+ type: "channel_metadata",
2053
+ payload: { topic: params.channelTopic.trim() }
2673
2054
  });
2055
+ return entries.length > 0 ? entries : void 0;
2056
+ }
2057
+ function buildDiscordInboundAccessContext(params) {
2674
2058
  return {
2675
- content: formatCommandArgMenuTitle({
2676
- command,
2677
- menu
2059
+ groupSystemPrompt: params.isGuild ? buildDiscordGroupSystemPrompt(params.channelConfig) : void 0,
2060
+ channelStructuredContext: buildDiscordChannelStructuredContext({
2061
+ isGuild: params.isGuild,
2062
+ channelTopic: params.channelTopic
2678
2063
  }),
2679
- components: rows
2064
+ ownerAllowFrom: resolveDiscordOwnerAllowFrom({
2065
+ channelConfig: params.channelConfig,
2066
+ guildInfo: params.guildInfo,
2067
+ sender: params.sender,
2068
+ allowNameMatching: params.allowNameMatching
2069
+ })
2680
2070
  };
2681
2071
  }
2682
- var DiscordCommandArgFallbackButton = class extends Button {
2683
- constructor(params) {
2684
- super();
2685
- this.params = params;
2686
- this.label = "cmdarg";
2687
- this.customId = "cmdarg:seed=1";
2688
- }
2689
- async run(interaction, data) {
2690
- await runDiscordCommandArgButton({
2691
- ...this.params,
2692
- interaction,
2693
- data
2694
- });
2695
- }
2696
- };
2697
- function createDiscordCommandArgFallbackButton$1(params) {
2698
- return new DiscordCommandArgFallbackButton(params);
2072
+ //#endregion
2073
+ //#region extensions/discord/src/monitor/native-command-context.ts
2074
+ function buildDiscordNativeCommandContext(params) {
2075
+ const conversationLabel = params.isDirectMessage ? params.user.globalName ?? params.user.username : params.channelId;
2076
+ const { groupSystemPrompt, ownerAllowFrom, channelStructuredContext } = buildDiscordInboundAccessContext({
2077
+ channelConfig: params.channelConfig,
2078
+ guildInfo: params.guildInfo,
2079
+ sender: params.sender,
2080
+ allowNameMatching: params.allowNameMatching,
2081
+ isGuild: params.isGuild,
2082
+ channelTopic: params.channelTopic
2083
+ });
2084
+ return finalizeInboundContext({
2085
+ Body: params.prompt,
2086
+ BodyForAgent: params.prompt,
2087
+ RawBody: params.prompt,
2088
+ CommandBody: params.prompt,
2089
+ CommandArgs: params.commandArgs,
2090
+ From: params.isDirectMessage ? `discord:${params.user.id}` : params.isGroupDm ? `discord:group:${params.channelId}` : `discord:channel:${params.channelId}`,
2091
+ To: `slash:${params.user.id}`,
2092
+ SessionKey: params.sessionKey,
2093
+ CommandTargetSessionKey: params.commandTargetSessionKey,
2094
+ AccountId: params.accountId ?? void 0,
2095
+ ChatType: params.isDirectMessage ? "direct" : params.isGroupDm ? "group" : "channel",
2096
+ ...buildDiscordConversationRouteContext({
2097
+ isDirectMessage: params.isDirectMessage,
2098
+ isGroupDm: params.isGroupDm,
2099
+ directUserId: params.user.id,
2100
+ conversationId: params.channelId,
2101
+ isThread: params.isThreadChannel,
2102
+ parentConversationId: params.threadParentId
2103
+ }),
2104
+ ConversationLabel: conversationLabel,
2105
+ GroupSubject: params.isGuild ? params.guildName : void 0,
2106
+ GroupSpace: params.isGuild ? params.guildInfo?.id ?? params.guildInfo?.slug ?? params.guildId : void 0,
2107
+ MemberRoleIds: params.memberRoleIds,
2108
+ GroupSystemPrompt: groupSystemPrompt,
2109
+ ChannelStructuredContext: channelStructuredContext,
2110
+ OwnerAllowFrom: ownerAllowFrom,
2111
+ SenderName: params.user.globalName ?? params.user.username,
2112
+ SenderId: params.user.id,
2113
+ SenderUsername: params.user.username,
2114
+ SenderTag: params.sender.tag,
2115
+ Provider: "discord",
2116
+ Surface: "discord",
2117
+ WasMentioned: true,
2118
+ MessageSid: params.interactionId,
2119
+ Timestamp: params.timestampMs ?? Date.now(),
2120
+ CommandAuthorized: params.commandAuthorized,
2121
+ CommandTurn: {
2122
+ kind: "native",
2123
+ source: "native",
2124
+ authorized: params.commandAuthorized,
2125
+ body: params.prompt
2126
+ },
2127
+ CommandSource: "native",
2128
+ OriginatingChannel: "discord",
2129
+ OriginatingTo: resolveDiscordConversationIdentity({
2130
+ isDirectMessage: params.isDirectMessage,
2131
+ userId: params.user.id,
2132
+ channelId: params.channelId
2133
+ }) ?? (params.isDirectMessage ? `user:${params.user.id}` : `channel:${params.channelId}`)
2134
+ });
2699
2135
  }
2700
2136
  //#endregion
2701
2137
  //#region extensions/discord/src/monitor/model-picker-preferences.ts
@@ -3694,6 +3130,7 @@ async function applyDiscordModelPickerSelection(params) {
3694
3130
  preferFollowUp: true,
3695
3131
  threadBindings: params.threadBindings,
3696
3132
  suppressReplies: true,
3133
+ dispatchReplyFromConfig: params.dispatchReplyFromConfig,
3697
3134
  pluginCommandDispatch: { kind: "non-plugin" }
3698
3135
  }), 12e3);
3699
3136
  if (!dispatchResult.accepted) return {
@@ -4351,6 +3788,7 @@ async function handleDiscordModelPickerInteraction(params) {
4351
3788
  accountId: ctx.accountId,
4352
3789
  sessionPrefix: ctx.sessionPrefix,
4353
3790
  threadBindings: ctx.threadBindings,
3791
+ dispatchReplyFromConfig: ctx.dispatchReplyFromConfig,
4354
3792
  route,
4355
3793
  resolvedModelRef,
4356
3794
  selectedRuntime,
@@ -4414,6 +3852,46 @@ function createDiscordModelPickerFallbackSelect$1(params) {
4414
3852
  return new DiscordModelPickerFallbackSelect(params);
4415
3853
  }
4416
3854
  //#endregion
3855
+ //#region extensions/discord/src/monitor/native-command-status.ts
3856
+ async function maybeDeliverDiscordDirectStatus(params) {
3857
+ if (params.suppressReplies || params.commandName !== "status") return null;
3858
+ const statusReply = await params.resolveDirectStatusReplyForSession({
3859
+ cfg: params.cfg,
3860
+ sessionKey: params.commandTargetSessionKey?.trim() || params.sessionKey,
3861
+ channel: params.channel,
3862
+ senderId: params.senderId,
3863
+ senderIsOwner: params.senderIsOwner,
3864
+ isAuthorizedSender: params.isAuthorizedSender,
3865
+ isGroup: params.isGroup,
3866
+ defaultGroupActivation: params.defaultGroupActivation
3867
+ });
3868
+ if (statusReply && hasRenderableReplyPayload(statusReply)) {
3869
+ await deliverDiscordInteractionReply({
3870
+ interaction: params.interaction,
3871
+ payload: statusReply,
3872
+ mediaLocalRoots: params.mediaLocalRoots,
3873
+ textLimit: resolveTextChunkLimit(params.cfg, "discord", params.accountId, { fallbackLimit: 2e3 }),
3874
+ maxLinesPerMessage: resolveDiscordMaxLinesPerMessage({
3875
+ cfg: params.cfg,
3876
+ discordConfig: params.discordConfig,
3877
+ accountId: params.accountId
3878
+ }),
3879
+ preferFollowUp: params.preferFollowUp,
3880
+ responseEphemeral: params.responseEphemeral,
3881
+ chunkMode: resolveChunkMode(params.cfg, "discord", params.accountId)
3882
+ });
3883
+ return {
3884
+ accepted: true,
3885
+ effectiveRoute: params.effectiveRoute
3886
+ };
3887
+ }
3888
+ await params.respond("Status unavailable.");
3889
+ return {
3890
+ accepted: true,
3891
+ effectiveRoute: params.effectiveRoute
3892
+ };
3893
+ }
3894
+ //#endregion
4417
3895
  //#region extensions/discord/src/monitor/native-command.args.ts
4418
3896
  function readDiscordCommandArgs(interaction, definitions) {
4419
3897
  if (!definitions || definitions.length === 0) return;
@@ -4446,7 +3924,7 @@ const DISCORD_COMMAND_DESCRIPTION_MAX = 100;
4446
3924
  function truncateDiscordCommandDescription(params) {
4447
3925
  const { value, label } = params;
4448
3926
  if (value.length <= DISCORD_COMMAND_DESCRIPTION_MAX) return value;
4449
- log$1.warn(`discord: truncating native command description (${label}) from ${value.length} to ${DISCORD_COMMAND_DESCRIPTION_MAX}: ${JSON.stringify(value)}`);
3927
+ log$1.debug(`discord: truncating native command description (${label}) from ${value.length} to ${DISCORD_COMMAND_DESCRIPTION_MAX}: ${JSON.stringify(value)}`);
4450
3928
  return truncateUtf16Safe(value, DISCORD_COMMAND_DESCRIPTION_MAX);
4451
3929
  }
4452
3930
  function truncateDiscordCommandDescriptionLocalizations(params) {
@@ -4543,7 +4021,7 @@ function buildDiscordCommandOptions(params) {
4543
4021
  const log = createSubsystemLogger("discord/native-command");
4544
4022
  const NON_PLUGIN_COMMAND_DISPATCH = Object.freeze({ kind: "non-plugin" });
4545
4023
  function createDiscordNativeCommand(params) {
4546
- const { command, cfg, discordConfig, accountId, sessionPrefix, ephemeralDefault, threadBindings } = params;
4024
+ const { command, cfg, discordConfig, accountId, sessionPrefix, ephemeralDefault, threadBindings, dispatchReplyFromConfig } = params;
4547
4025
  const fallbackCommandDefinition = createNativeCommandDefinition(command);
4548
4026
  const pluginCommandCandidate = "prepareDispatch" in command ? command : void 0;
4549
4027
  const commandDefinition = pluginCommandCandidate ? fallbackCommandDefinition : findCommandByNativeName$1(command.name, "discord", { includeBundledChannelFallback: false }) ?? fallbackCommandDefinition;
@@ -4610,13 +4088,14 @@ function createDiscordNativeCommand(params) {
4610
4088
  preferFollowUp: true,
4611
4089
  threadBindings,
4612
4090
  responseEphemeral: ephemeralDefault,
4091
+ dispatchReplyFromConfig,
4613
4092
  pluginCommandDispatch: preparedPluginCommand ?? NON_PLUGIN_COMMAND_DISPATCH
4614
4093
  });
4615
4094
  }
4616
4095
  }();
4617
4096
  }
4618
4097
  async function dispatchDiscordCommandInteraction(params) {
4619
- const { interaction, prompt, command, commandArgs, cfg: inputConfig, discordConfig, accountId, sessionPrefix, preferFollowUp, threadBindings, responseEphemeral, suppressReplies } = params;
4098
+ const { interaction, prompt, command, commandArgs, cfg: inputConfig, discordConfig, accountId, sessionPrefix, preferFollowUp, threadBindings, responseEphemeral, suppressReplies, dispatchReplyFromConfig } = params;
4620
4099
  const cfg = getRuntimeConfigSnapshot() ?? inputConfig;
4621
4100
  const commandName = command.nativeName ?? command.key;
4622
4101
  const respond = async (content, options) => {
@@ -4854,7 +4333,8 @@ async function dispatchDiscordCommandInteraction(params) {
4854
4333
  discordConfig,
4855
4334
  accountId,
4856
4335
  sessionPrefix,
4857
- threadBindings
4336
+ threadBindings,
4337
+ dispatchReplyFromConfig
4858
4338
  },
4859
4339
  safeInteractionCall: safeDiscordInteractionCall,
4860
4340
  dispatchCommandInteraction: dispatchDiscordCommandInteraction
@@ -5041,6 +4521,7 @@ async function dispatchDiscordCommandInteraction(params) {
5041
4521
  preferFollowUp,
5042
4522
  responseEphemeral,
5043
4523
  suppressReplies,
4524
+ dispatchReplyFromConfig,
5044
4525
  log,
5045
4526
  pluginCommandDispatch: params.pluginCommandDispatch
5046
4527
  });
@@ -5097,7 +4578,7 @@ function canResumeAfterGatewayClose(code) {
5097
4578
  //#region extensions/discord/src/internal/gateway-identify-limiter.ts
5098
4579
  const IDENTIFY_WINDOW_MS = 5e3;
5099
4580
  function normalizeMaxConcurrency(value) {
5100
- const parsed = parseFiniteNumber$1(value);
4581
+ const parsed = parseFiniteNumber(value);
5101
4582
  return parsed === void 0 ? 1 : Math.max(1, Math.floor(parsed));
5102
4583
  }
5103
4584
  var GatewayIdentifyLimiter = class {
@@ -5305,7 +4786,7 @@ var DiscordGatewayVoiceStateCache = class {
5305
4786
  }
5306
4787
  listVoiceChannelStates(guildId, channelId) {
5307
4788
  const states = this.statesByGuild.get(guildId);
5308
- if (!states) return [];
4789
+ if (!states) return null;
5309
4790
  const result = [];
5310
4791
  for (const state of states.values()) if (state.channel_id === channelId) result.push({ ...state });
5311
4792
  return result;
@@ -5415,6 +4896,9 @@ var GatewayPlugin = class extends Plugin {
5415
4896
  listVoiceChannelStates(guildId, channelId) {
5416
4897
  return this.voiceStateCache.listVoiceChannelStates(guildId, channelId);
5417
4898
  }
4899
+ async fetchGuildEmojis(guildId, fetcher) {
4900
+ return this.client ? await this.client.fetchGuildEmojis(guildId, fetcher) : await fetcher();
4901
+ }
5418
4902
  takeVoiceStateTransition(state) {
5419
4903
  return this.voiceStateCache.takeTransition(state);
5420
4904
  }
@@ -5518,7 +5002,10 @@ var GatewayPlugin = class extends Plugin {
5518
5002
  if (payload.s !== null && payload.s !== void 0) this.sequence = payload.s;
5519
5003
  switch (payload.op) {
5520
5004
  case GatewayOpcodes.Hello: {
5521
- this.startHeartbeat(payload.d.heartbeat_interval ?? 45e3);
5005
+ this.startHeartbeat(asSafeIntegerInRange(asOptionalRecord(payload.d)?.heartbeat_interval, {
5006
+ min: 1,
5007
+ max: MAX_TIMER_TIMEOUT_MS
5008
+ }) ?? 45e3);
5522
5009
  const resumeState = resume ? this.getResumeState() : null;
5523
5010
  if (resumeState) this.send({
5524
5011
  op: GatewayOpcodes.Resume,
@@ -5721,12 +5208,6 @@ var GatewayPlugin = class extends Plugin {
5721
5208
  }
5722
5209
  };
5723
5210
  //#endregion
5724
- //#region extensions/discord/src/voice/config.ts
5725
- function resolveDiscordVoiceEnabled(voice) {
5726
- if (voice?.enabled !== void 0) return voice.enabled;
5727
- return voice !== void 0;
5728
- }
5729
- //#endregion
5730
5211
  //#region extensions/discord/src/monitor/presence.ts
5731
5212
  const DEFAULT_CUSTOM_ACTIVITY_TYPE$1 = 4;
5732
5213
  const CUSTOM_STATUS_NAME$1 = "Custom Status";
@@ -6268,7 +5749,7 @@ function resolveDiscordGatewayIntents(params) {
6268
5749
  const intentsConfig = params?.intentsConfig;
6269
5750
  const voiceEnabled = params?.voiceEnabled;
6270
5751
  const voiceStatesEnabled = intentsConfig?.voiceStates ?? voiceEnabled ?? false;
6271
- let intents = GatewayIntents.Guilds | GatewayIntents.GuildMessages | GatewayIntents.DirectMessages | GatewayIntents.GuildMessageReactions | GatewayIntents.DirectMessageReactions;
5752
+ let intents = GatewayIntents.Guilds | GatewayIntents.GuildExpressions | GatewayIntents.GuildMessages | GatewayIntents.DirectMessages | GatewayIntents.GuildMessageReactions | GatewayIntents.DirectMessageReactions;
6272
5753
  if (intentsConfig?.messageContent !== false) intents |= GatewayIntents.MessageContent;
6273
5754
  if (voiceStatesEnabled) intents |= GatewayIntents.GuildVoiceStates;
6274
5755
  if (intentsConfig?.presence) intents |= GatewayIntents.GuildPresences;
@@ -7045,7 +6526,7 @@ async function runDiscordGatewayLifecycle(params) {
7045
6526
  gatewayEmitter?.removeListener(DISCORD_GATEWAY_TRANSPORT_ACTIVITY_EVENT, onGatewayTransportActivity);
7046
6527
  if (params.voiceManager) {
7047
6528
  await params.voiceManager.destroy();
7048
- const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-CfFMexGt.js").then((n) => n.n);
6529
+ const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-BR11iHA4.js").then((n) => n.n);
7049
6530
  setDiscordTranscriptsVoiceManager({
7050
6531
  accountId: params.accountId,
7051
6532
  manager: null
@@ -7060,7 +6541,7 @@ async function runDiscordGatewayLifecycle(params) {
7060
6541
  let discordVoiceRuntimePromise;
7061
6542
  let discordProviderSessionRuntimePromise;
7062
6543
  async function loadDiscordVoiceRuntime() {
7063
- const promise = discordVoiceRuntimePromise ?? import("./voice-runtime-BEdqNcST.js");
6544
+ const promise = discordVoiceRuntimePromise ?? import("./voice-runtime-DIeaa8fJ.js");
7064
6545
  discordVoiceRuntimePromise = promise;
7065
6546
  try {
7066
6547
  return await promise;
@@ -7070,7 +6551,7 @@ async function loadDiscordVoiceRuntime() {
7070
6551
  }
7071
6552
  }
7072
6553
  async function loadDiscordProviderSessionRuntime() {
7073
- const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-BUEqD0rA.js");
6554
+ const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-B9xe-Qaf.js");
7074
6555
  discordProviderSessionRuntimePromise = promise;
7075
6556
  try {
7076
6557
  return await promise;
@@ -7431,102 +6912,6 @@ async function cleanupDiscordProviderStartup(params) {
7431
6912
  if (!params.lifecycleStarted) params.threadBindings.stop();
7432
6913
  }
7433
6914
  //#endregion
7434
- //#region extensions/discord/src/voice/access.ts
7435
- async function authorizeDiscordVoiceIngress(params) {
7436
- const groupPolicy = params.groupPolicy ?? resolveOpenProviderRuntimeGroupPolicy({
7437
- providerConfigPresent: params.cfg.channels?.discord !== void 0,
7438
- groupPolicy: params.discordConfig.groupPolicy,
7439
- defaultGroupPolicy: params.cfg.channels?.defaults?.groupPolicy
7440
- }).groupPolicy;
7441
- const guildInfo = resolveDiscordGuildEntry({
7442
- guild: params.guild ?? {
7443
- id: params.guildId,
7444
- ...params.guildName ? { name: params.guildName } : {}
7445
- },
7446
- guildId: params.guildId,
7447
- guildEntries: params.discordConfig.guilds
7448
- });
7449
- const channelConfig = params.channelId ? resolveDiscordChannelConfigWithFallback({
7450
- guildInfo,
7451
- channelId: params.channelId,
7452
- channelName: params.channelName,
7453
- channelSlug: params.channelSlug,
7454
- parentId: params.parentId,
7455
- parentName: params.parentName,
7456
- parentSlug: params.parentSlug,
7457
- scope: params.scope
7458
- }) : null;
7459
- if (channelConfig?.enabled === false) return {
7460
- ok: false,
7461
- message: "This channel is disabled."
7462
- };
7463
- const channelAllowlistConfigured = Boolean(guildInfo?.channels) && Object.keys(guildInfo?.channels ?? {}).length > 0;
7464
- if (!params.channelId && groupPolicy === "allowlist" && channelAllowlistConfigured) return {
7465
- ok: false,
7466
- message: `${params.channelLabel ?? "This channel"} is not allowlisted for voice commands.`
7467
- };
7468
- const channelAllowed = channelConfig ? channelConfig.allowed : !channelAllowlistConfigured;
7469
- if (!isDiscordGroupAllowedByPolicy({
7470
- groupPolicy,
7471
- guildAllowlisted: Boolean(guildInfo),
7472
- channelAllowlistConfigured,
7473
- channelAllowed
7474
- }) || channelConfig?.allowed === false) return {
7475
- ok: false,
7476
- message: `${params.channelLabel ?? "This channel"} is not allowlisted for voice commands.`
7477
- };
7478
- const { hasAccessRestrictions, memberAllowed } = resolveDiscordMemberAccessState({
7479
- channelConfig,
7480
- guildInfo,
7481
- memberRoleIds: params.memberRoleIds,
7482
- sender: params.sender,
7483
- allowNameMatching: false
7484
- });
7485
- const admissionAllowList = normalizeDiscordAllowList(params.admissionAllowFrom ?? params.discordConfig.allowFrom ?? params.discordConfig.allowFrom, [
7486
- "discord:",
7487
- "user:",
7488
- "pk:"
7489
- ]);
7490
- const admissionAllowed = admissionAllowList ? allowListMatches(admissionAllowList, params.sender, { allowNameMatching: false }) : false;
7491
- const useAccessGroups = params.useAccessGroups ?? true;
7492
- return resolveCommandAuthorizedFromAuthorizers({
7493
- useAccessGroups,
7494
- authorizers: useAccessGroups ? [{
7495
- configured: admissionAllowList != null,
7496
- allowed: admissionAllowed
7497
- }, {
7498
- configured: hasAccessRestrictions,
7499
- allowed: memberAllowed
7500
- }] : [{
7501
- configured: hasAccessRestrictions,
7502
- allowed: memberAllowed
7503
- }],
7504
- modeWhenAccessGroupsOff: "configured"
7505
- }) ? {
7506
- ok: true,
7507
- channelConfig
7508
- } : {
7509
- ok: false,
7510
- message: "You are not authorized to use this command."
7511
- };
7512
- }
7513
- //#endregion
7514
- //#region extensions/discord/src/voice/owner-access.ts
7515
- function resolveDiscordVoiceAccess(params) {
7516
- const commandOwnerAllowFrom = resolveDiscordCommandOwnerAllowFrom(params.cfg);
7517
- if (commandOwnerAllowFrom) return {
7518
- admissionAllowFrom: commandOwnerAllowFrom,
7519
- ownerAllowFrom: commandOwnerAllowFrom
7520
- };
7521
- return {
7522
- admissionAllowFrom: resolveDiscordAccountAllowFrom({
7523
- cfg: params.cfg,
7524
- accountId: params.accountId
7525
- }) ?? params.discordConfig.allowFrom ?? [],
7526
- ownerAllowFrom: []
7527
- };
7528
- }
7529
- //#endregion
7530
6915
  //#region extensions/discord/src/voice/command.ts
7531
6916
  const VOICE_CHANNEL_TYPES = [ChannelType.GuildVoice, ChannelType.GuildStageVoice];
7532
6917
  const DISCORD_VOICE_COMMAND_SPEC = {
@@ -7890,8 +7275,8 @@ function formatDiscordDeployRestOperation(err) {
7890
7275
  function formatDiscordDeployErrorMessage(err) {
7891
7276
  if (!isAbortLikeError(err)) return formatErrorMessage$1(err);
7892
7277
  const deployErr = err && typeof err === "object" ? err : {};
7893
- const requestMs = parseFiniteNumber(deployErr.deployRequestMs);
7894
- const timeoutMs = parseFiniteNumber(deployErr.deployTimeoutMs);
7278
+ const requestMs = parseFiniteNumber$1(deployErr.deployRequestMs);
7279
+ const timeoutMs = parseFiniteNumber$1(deployErr.deployTimeoutMs);
7895
7280
  const operation = formatDiscordDeployRestOperation(deployErr);
7896
7281
  if (!(requestMs !== void 0 || timeoutMs !== void 0 || deployErr.deployRestMethod !== void 0 || deployErr.deployRestPath !== void 0)) return "Discord REST request was aborted";
7897
7282
  const timing = [];
@@ -7904,8 +7289,8 @@ function formatDiscordDeployErrorMessage(err) {
7904
7289
  function resolveDiscordDeployRateLimitDetails(err) {
7905
7290
  if (!err || typeof err !== "object") return;
7906
7291
  const deployErr = err;
7907
- const status = parseStrictNonNegativeInteger(deployErr.status) ?? parseStrictNonNegativeInteger(deployErr.statusCode);
7908
- const retryAfterSeconds = parseFiniteNumber(deployErr.retryAfter) ?? parseFiniteNumber(readDiscordDeployObjectField(deployErr.rawBody, "retry_after"));
7292
+ const status = parseStrictNonNegativeInteger$1(deployErr.status) ?? parseStrictNonNegativeInteger$1(deployErr.statusCode);
7293
+ const retryAfterSeconds = parseFiniteNumber$1(deployErr.retryAfter) ?? parseFiniteNumber$1(readDiscordDeployObjectField(deployErr.rawBody, "retry_after"));
7909
7294
  if (!(err instanceof RateLimitError || status === 429 || retryAfterSeconds !== void 0)) return;
7910
7295
  const rawGlobal = readDiscordDeployObjectField(deployErr.rawBody, "global");
7911
7296
  const scope = typeof deployErr.scope === "string" && deployErr.scope.trim().length > 0 ? deployErr.scope : rawGlobal === true ? "global" : rawGlobal === false ? "route" : void 0;
@@ -7995,8 +7380,8 @@ function formatDiscordDeployErrorDetails(err) {
7995
7380
  function isDiscordDeployDailyCreateLimit(err) {
7996
7381
  if (!err || typeof err !== "object") return false;
7997
7382
  const deployErr = err;
7998
- const discordCode = parseStrictNonNegativeInteger(deployErr.discordCode);
7999
- const rawCode = parseStrictNonNegativeInteger(readDiscordDeployObjectField(deployErr.rawBody, "code"));
7383
+ const discordCode = parseStrictNonNegativeInteger$1(deployErr.discordCode);
7384
+ const rawCode = parseStrictNonNegativeInteger$1(readDiscordDeployObjectField(deployErr.rawBody, "code"));
8000
7385
  return (discordCode === 30034 || rawCode === 30034) && /daily application command creates/i.test(formatErrorMessage$1(err));
8001
7386
  }
8002
7387
  //#endregion
@@ -8214,9 +7599,6 @@ function formatUsername(user) {
8214
7599
  if (user.discriminator && user.discriminator !== "0") return `${user.username}#${user.discriminator}`;
8215
7600
  return user.username;
8216
7601
  }
8217
- function isThreadChannelType(channelType) {
8218
- return channelType === ChannelType.PublicThread || channelType === ChannelType.PrivateThread || channelType === ChannelType.AnnouncementThread;
8219
- }
8220
7602
  function resolveAgentComponentRoute(params) {
8221
7603
  return resolveAgentRoute({
8222
7604
  cfg: params.ctx.cfg,
@@ -8259,7 +7641,7 @@ function resolveDiscordChannelContext(interaction) {
8259
7641
  const channelSlug = channelName ? normalizeDiscordSlug(channelName) : "";
8260
7642
  const displayChannelSlug = channelName ? normalizeDiscordDisplaySlug(channelName) : "";
8261
7643
  const channelType = channelInfo.type;
8262
- const isThread = isThreadChannelType(channelType);
7644
+ const isThread = isDiscordThreadChannelType(channelType);
8263
7645
  let parentId;
8264
7646
  let parentName;
8265
7647
  let parentSlug = "";
@@ -8757,7 +8139,8 @@ function resolveReplyContext(message, resolveDiscordMessageText) {
8757
8139
  const referenced = message.referencedMessage;
8758
8140
  if (!referenced?.author) return null;
8759
8141
  const referencedText = resolveDiscordMessageText(referenced, { includeForwarded: true });
8760
- if (!referencedText) return null;
8142
+ const hasVisibleMedia = referenced.attachments.length > 0 || !referencedText && resolveDiscordMessageStickers(referenced).length > 0;
8143
+ if (!referencedText && !hasVisibleMedia) return null;
8761
8144
  const sender = resolveDiscordSenderIdentity({
8762
8145
  author: referenced.author,
8763
8146
  pluralkitInfo: null
@@ -8773,7 +8156,7 @@ function resolveReplyContext(message, resolveDiscordMessageText) {
8773
8156
  const roles = referenced.member?.roles;
8774
8157
  return Array.isArray(roles) ? roles.map((roleId) => roleId) : void 0;
8775
8158
  })(),
8776
- body: referencedText,
8159
+ ...referencedText ? { body: referencedText } : {},
8777
8160
  timestamp: resolveTimestampMs(referenced.timestamp)
8778
8161
  };
8779
8162
  }
@@ -8933,6 +8316,7 @@ async function deliverDiscordReply(params) {
8933
8316
  formatting: delivery.formatting,
8934
8317
  threadId: delivery.threadId,
8935
8318
  identity: delivery.identity,
8319
+ onPlatformSendDispatch: params.onPlatformSendDispatch,
8936
8320
  deps: createDiscordDeliveryDeps({
8937
8321
  cfg: params.cfg,
8938
8322
  token: params.token,
@@ -8971,7 +8355,7 @@ async function deliverDiscordReply(params) {
8971
8355
  //#endregion
8972
8356
  //#region extensions/discord/src/monitor/agent-components.dispatch.ts
8973
8357
  const loadConversationRuntime$1 = createLazyRuntimeModule(() => import("./agent-components.runtime-CEPrf2SY.js"));
8974
- const loadTypingRuntime = createLazyRuntimeModule(() => import("./typing-CS-nNVoe.js").then((n) => n.n));
8358
+ const loadTypingRuntime = createLazyRuntimeModule(() => import("./typing-Dc_YMY2e.js").then((n) => n.n));
8975
8359
  function buildDiscordComponentConversationLabel(params) {
8976
8360
  if (params.interactionCtx.isDirectMessage) return buildDirectLabel(params.interactionCtx.user);
8977
8361
  if (params.interactionCtx.isGroupDm) return `Group DM #${params.channelCtx.channelName ?? params.interactionCtx.channelId} channel id:${params.interactionCtx.channelId}`;
@@ -9093,6 +8477,14 @@ async function dispatchDiscordComponentEvent(params) {
9093
8477
  SessionKey: sessionKey,
9094
8478
  AccountId: accountId,
9095
8479
  ChatType: chatType,
8480
+ ...buildDiscordConversationRouteContext({
8481
+ isDirectMessage: interactionCtx.isDirectMessage,
8482
+ isGroupDm: interactionCtx.isGroupDm,
8483
+ directUserId: interactionCtx.userId,
8484
+ conversationId: interactionCtx.channelId,
8485
+ isThread: channelCtx.isThread,
8486
+ parentConversationId: channelCtx.parentId
8487
+ }),
9096
8488
  ConversationLabel: fromLabel,
9097
8489
  SenderName: senderName,
9098
8490
  SenderId: interactionCtx.userId,
@@ -9161,6 +8553,7 @@ async function dispatchDiscordComponentEvent(params) {
9161
8553
  sessionKey
9162
8554
  },
9163
8555
  ctxPayload,
8556
+ dispatchReplyFromConfig: ctx.channelRuntime?.reply?.dispatchReplyFromConfig,
9164
8557
  record: {
9165
8558
  updateLastRoute: interactionCtx.isDirectMessage ? {
9166
8559
  sessionKey: inboundLastRouteSessionKey,
@@ -9202,7 +8595,8 @@ async function dispatchDiscordComponentEvent(params) {
9202
8595
  chunkMode: resolveChunkMode(ctx.cfg, "discord", accountId),
9203
8596
  mediaLocalRoots,
9204
8597
  kind: info.kind,
9205
- bindPendingFinalDelivery: info.bindPendingFinalDelivery
8598
+ bindPendingFinalDelivery: info.bindPendingFinalDelivery,
8599
+ onPlatformSendDispatch: info.onPlatformSendDispatch
9206
8600
  });
9207
8601
  if (result.visibleReplySent) replyReference.markSent();
9208
8602
  return result;
@@ -9367,7 +8761,7 @@ async function dispatchPluginDiscordInteractiveEvent(params) {
9367
8761
  }
9368
8762
  //#endregion
9369
8763
  //#region extensions/discord/src/monitor/agent-components.handlers.ts
9370
- const loadComponentsRuntime = createLazyRuntimeModule(() => import("./outbound-session-route-DxLkrgKQ.js").then((n) => n.n));
8764
+ const loadComponentsRuntime = createLazyRuntimeModule(() => import("./components-B9V5o361.js").then((n) => n.t));
9371
8765
  async function handleDiscordComponentEvent(params) {
9372
8766
  const parsed = parseDiscordComponentData(params.data, resolveInteractionCustomId(params.interaction));
9373
8767
  if (!parsed) {
@@ -10013,29 +9407,24 @@ var QuestionButton = class extends Button {
10013
9407
  try {
10014
9408
  await interaction.acknowledge();
10015
9409
  } catch {}
10016
- let result;
9410
+ let content;
10017
9411
  try {
10018
- result = await this.ctx.resolveQuestion({
9412
+ content = (await this.ctx.resolveQuestion({
10019
9413
  cfg: this.ctx.cfg,
10020
9414
  questionId: callback.questionId,
10021
9415
  optionIndex: callback.optionIndex,
10022
9416
  senderId: interaction.userId,
10023
9417
  clientDisplayName: `Discord question (${this.ctx.accountId})`
10024
- });
9418
+ })).status === "answered" ? "Answer submitted." : "This question was already answered.";
10025
9419
  } catch {
10026
- try {
10027
- await interaction.followUp({
10028
- content: "Could not submit this answer.",
10029
- ephemeral: true
10030
- });
10031
- } catch {}
10032
- return;
9420
+ content = "Could not submit this answer.";
10033
9421
  }
10034
9422
  try {
10035
- await interaction.followUp({
10036
- content: result.status === "answered" ? "Answer submitted." : "This question was already answered.",
9423
+ const feedback = {
9424
+ content,
10037
9425
  ephemeral: true
10038
- });
9426
+ };
9427
+ await (interaction.responseState === "unacknowledged" ? interaction.reply(feedback) : interaction.followUp(feedback));
10039
9428
  } catch {}
10040
9429
  }
10041
9430
  };
@@ -10079,7 +9468,8 @@ function createDiscordProviderInteractionSurface(params) {
10079
9468
  accountId: params.accountId,
10080
9469
  sessionPrefix: params.sessionPrefix,
10081
9470
  ephemeralDefault: params.ephemeralDefault,
10082
- threadBindings: params.threadBindings
9471
+ threadBindings: params.threadBindings,
9472
+ dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
10083
9473
  });
10084
9474
  });
10085
9475
  const execApprovalsConfig = params.discordConfig.execApprovals ?? {};
@@ -10124,21 +9514,24 @@ function createDiscordProviderInteractionSurface(params) {
10124
9514
  discordConfig: params.discordConfig,
10125
9515
  accountId: params.accountId,
10126
9516
  sessionPrefix: params.sessionPrefix,
10127
- threadBindings: params.threadBindings
9517
+ threadBindings: params.threadBindings,
9518
+ dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
10128
9519
  }),
10129
9520
  createDiscordModelPickerFallbackButton({
10130
9521
  cfg: params.cfg,
10131
9522
  discordConfig: params.discordConfig,
10132
9523
  accountId: params.accountId,
10133
9524
  sessionPrefix: params.sessionPrefix,
10134
- threadBindings: params.threadBindings
9525
+ threadBindings: params.threadBindings,
9526
+ dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
10135
9527
  }),
10136
9528
  createDiscordModelPickerFallbackSelect({
10137
9529
  cfg: params.cfg,
10138
9530
  discordConfig: params.discordConfig,
10139
9531
  accountId: params.accountId,
10140
9532
  sessionPrefix: params.sessionPrefix,
10141
- threadBindings: params.threadBindings
9533
+ threadBindings: params.threadBindings,
9534
+ dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
10142
9535
  })
10143
9536
  ];
10144
9537
  const activityButton = createDiscordActivityButton({
@@ -10149,6 +9542,7 @@ function createDiscordProviderInteractionSurface(params) {
10149
9542
  allowFrom: params.allowFrom,
10150
9543
  dmPolicy: params.dmPolicy,
10151
9544
  runtime: params.runtime,
9545
+ channelRuntime: params.channelRuntime,
10152
9546
  token: params.token
10153
9547
  }, params.applicationId);
10154
9548
  if (activityButton) components.push(activityButton);
@@ -10641,6 +10035,7 @@ async function monitorDiscordProvider(opts = {}) {
10641
10035
  let earlyGatewayEmitter = gatewaySupervisor?.emitter;
10642
10036
  let onEarlyGatewayDebug;
10643
10037
  try {
10038
+ const pluginChannelRuntime = opts.channelRuntime;
10644
10039
  const { commands, components, modals } = createDiscordProviderInteractionSurface({
10645
10040
  cfg,
10646
10041
  discordConfig: discordCfg,
@@ -10660,7 +10055,7 @@ async function monitorDiscordProvider(opts = {}) {
10660
10055
  allowFrom,
10661
10056
  dmPolicy,
10662
10057
  runtime,
10663
- channelRuntime: opts.channelRuntime,
10058
+ channelRuntime: pluginChannelRuntime,
10664
10059
  abortSignal: opts.abortSignal,
10665
10060
  createNativeCommand: discordProviderRuntime.createDiscordNativeCommand
10666
10061
  });
@@ -10734,7 +10129,7 @@ async function monitorDiscordProvider(opts = {}) {
10734
10129
  runtime,
10735
10130
  botUserId
10736
10131
  });
10737
- const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-CfFMexGt.js").then((n) => n.n);
10132
+ const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-BR11iHA4.js").then((n) => n.n);
10738
10133
  setDiscordTranscriptsVoiceManager({
10739
10134
  accountId: account.accountId,
10740
10135
  manager: voiceManager
@@ -10752,7 +10147,7 @@ async function monitorDiscordProvider(opts = {}) {
10752
10147
  accountId: account.accountId,
10753
10148
  token,
10754
10149
  runtime,
10755
- buildContext: opts.channelRuntime?.inbound.buildContext,
10150
+ buildContext: pluginChannelRuntime?.inbound.buildContext,
10756
10151
  setStatus: opts.setStatus,
10757
10152
  abortSignal: opts.abortSignal,
10758
10153
  botUserId,
@@ -10840,4 +10235,4 @@ async function monitorDiscordProvider(opts = {}) {
10840
10235
  }
10841
10236
  }
10842
10237
  //#endregion
10843
- export { sanitizeDiscordThreadName as A, handleDiscordDmCommandDecision as C, resolveDiscordAutoThreadReplyPlan as D, threading_exports as E, resolveDiscordTextCommandAccess as M, resolveDiscordReplyTarget as O, shouldIgnoreStaleDiscordRouteBinding as S, registerDiscordListener as T, buildDiscordInboundAccessContext as _, sanitizeDiscordFrontChannelReplyPayloads as a, resolveDiscordConversationRoute as b, resolveReplyContext as c, createDiscordGatewayPlugin as d, resolveDiscordGatewayIntents as f, buildDiscordGroupSystemPrompt as g, createDiscordNativeCommand as h, formatDiscordReplySkip as i, resolveDiscordDmCommandAccess as j, resolveDiscordThreadStarter as k, resolveDiscordVoiceAccess as l, resolveDiscordVoiceEnabled as m, deliverDiscordReply as n, buildDirectLabel as o, waitForDiscordGatewayPluginRegistration as p, formatDiscordReplyDeliveryFailure as r, buildGuildLabel as s, monitorDiscordProvider as t, authorizeDiscordVoiceIngress as u, createDiscordSupplementalContextAccessChecker as v, mapGatewayDispatchData as w, resolveDiscordEffectiveRoute as x, buildDiscordRoutePeer as y };
10238
+ export { mapGatewayDispatchData as _, sanitizeDiscordFrontChannelReplyPayloads as a, resolveDiscordDmCommandAccess as b, resolveReplyContext as c, waitForDiscordGatewayPluginRegistration as d, createDiscordNativeCommand as f, handleDiscordDmCommandDecision as g, createDiscordSupplementalContextAccessChecker as h, formatDiscordReplySkip as i, createDiscordGatewayPlugin as l, buildDiscordInboundAccessContext as m, deliverDiscordReply as n, buildDirectLabel as o, buildDiscordGroupSystemPrompt as p, formatDiscordReplyDeliveryFailure as r, buildGuildLabel as s, monitorDiscordProvider as t, resolveDiscordGatewayIntents as u, registerDiscordListener as v, resolveDiscordTextCommandAccess as x, resolveFetchedDiscordThreadLikeChannelContext as y };