@gakr-gakr/discord 0.1.0

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 (353) hide show
  1. package/account-inspect-api.ts +6 -0
  2. package/action-runtime-api.ts +1 -0
  3. package/api.ts +130 -0
  4. package/autobot.plugin.json +15 -0
  5. package/channel-config-api.ts +1 -0
  6. package/channel-plugin-api.ts +3 -0
  7. package/config-api.ts +4 -0
  8. package/configured-state.ts +6 -0
  9. package/contract-api.ts +21 -0
  10. package/directory-contract-api.ts +4 -0
  11. package/doctor-contract-api.ts +1 -0
  12. package/index.ts +24 -0
  13. package/package.json +79 -0
  14. package/runtime-api.actions.ts +15 -0
  15. package/runtime-api.lookup.ts +22 -0
  16. package/runtime-api.monitor.ts +50 -0
  17. package/runtime-api.send.ts +79 -0
  18. package/runtime-api.threads.ts +31 -0
  19. package/runtime-api.ts +181 -0
  20. package/runtime-setter-api.ts +3 -0
  21. package/secret-contract-api.ts +4 -0
  22. package/security-audit-contract-api.ts +1 -0
  23. package/security-contract-api.ts +4 -0
  24. package/session-key-api.ts +1 -0
  25. package/setup-entry.ts +9 -0
  26. package/setup-plugin-api.ts +3 -0
  27. package/src/account-inspect.ts +131 -0
  28. package/src/accounts.ts +205 -0
  29. package/src/actions/handle-action.guild-admin.ts +421 -0
  30. package/src/actions/handle-action.ts +402 -0
  31. package/src/actions/runtime.guild.ts +446 -0
  32. package/src/actions/runtime.messaging.messages.ts +226 -0
  33. package/src/actions/runtime.messaging.reactions.ts +67 -0
  34. package/src/actions/runtime.messaging.runtime.ts +73 -0
  35. package/src/actions/runtime.messaging.send.ts +336 -0
  36. package/src/actions/runtime.messaging.shared.ts +97 -0
  37. package/src/actions/runtime.messaging.ts +37 -0
  38. package/src/actions/runtime.moderation-shared.ts +48 -0
  39. package/src/actions/runtime.moderation.ts +116 -0
  40. package/src/actions/runtime.presence.ts +117 -0
  41. package/src/actions/runtime.shared.ts +86 -0
  42. package/src/actions/runtime.ts +87 -0
  43. package/src/api.ts +219 -0
  44. package/src/approval-handler.runtime.ts +636 -0
  45. package/src/approval-native.ts +219 -0
  46. package/src/approval-runtime.ts +14 -0
  47. package/src/approval-shared.ts +56 -0
  48. package/src/audit-core.ts +178 -0
  49. package/src/audit.ts +32 -0
  50. package/src/channel-actions.runtime.ts +1 -0
  51. package/src/channel-actions.ts +254 -0
  52. package/src/channel-api.ts +29 -0
  53. package/src/channel.conversation.ts +159 -0
  54. package/src/channel.loaders.ts +50 -0
  55. package/src/channel.runtime.ts +1 -0
  56. package/src/channel.setup.ts +12 -0
  57. package/src/channel.ts +728 -0
  58. package/src/chunk.ts +321 -0
  59. package/src/client.ts +143 -0
  60. package/src/component-custom-id.ts +72 -0
  61. package/src/components-registry.ts +356 -0
  62. package/src/components.builders.ts +410 -0
  63. package/src/components.modal.ts +124 -0
  64. package/src/components.parse.ts +407 -0
  65. package/src/components.ts +54 -0
  66. package/src/components.types.ts +187 -0
  67. package/src/config-schema.ts +6 -0
  68. package/src/config-ui-hints.ts +354 -0
  69. package/src/conversation-identity.ts +58 -0
  70. package/src/delivery-retry.ts +56 -0
  71. package/src/directory-cache.ts +116 -0
  72. package/src/directory-config.ts +58 -0
  73. package/src/directory-live.ts +135 -0
  74. package/src/doctor-contract.ts +477 -0
  75. package/src/doctor-shared.ts +5 -0
  76. package/src/doctor.ts +340 -0
  77. package/src/draft-chunking.ts +43 -0
  78. package/src/draft-stream.ts +162 -0
  79. package/src/error-body.ts +38 -0
  80. package/src/exec-approvals.ts +110 -0
  81. package/src/gateway-logging.ts +67 -0
  82. package/src/group-policy.ts +113 -0
  83. package/src/guilds.ts +29 -0
  84. package/src/inbound-event-delivery.ts +135 -0
  85. package/src/interactive-dispatch.ts +104 -0
  86. package/src/internal/api.commands.ts +51 -0
  87. package/src/internal/api.guild.ts +164 -0
  88. package/src/internal/api.interactions.ts +53 -0
  89. package/src/internal/api.messages.ts +113 -0
  90. package/src/internal/api.reactions.ts +38 -0
  91. package/src/internal/api.ts +61 -0
  92. package/src/internal/api.users.ts +19 -0
  93. package/src/internal/api.webhooks.ts +13 -0
  94. package/src/internal/client.ts +310 -0
  95. package/src/internal/command-deploy.ts +352 -0
  96. package/src/internal/commands.ts +188 -0
  97. package/src/internal/components.base.ts +65 -0
  98. package/src/internal/components.message.ts +279 -0
  99. package/src/internal/components.modal.ts +95 -0
  100. package/src/internal/components.ts +31 -0
  101. package/src/internal/discord.ts +11 -0
  102. package/src/internal/embeds.ts +35 -0
  103. package/src/internal/entity-cache.ts +98 -0
  104. package/src/internal/event-queue.ts +185 -0
  105. package/src/internal/gateway-close-codes.ts +25 -0
  106. package/src/internal/gateway-dispatch.ts +96 -0
  107. package/src/internal/gateway-identify-limiter.ts +26 -0
  108. package/src/internal/gateway-lifecycle.ts +75 -0
  109. package/src/internal/gateway-rate-limit.ts +104 -0
  110. package/src/internal/gateway.ts +479 -0
  111. package/src/internal/interaction-dispatch.ts +162 -0
  112. package/src/internal/interaction-options.ts +98 -0
  113. package/src/internal/interaction-response.ts +53 -0
  114. package/src/internal/interactions.ts +378 -0
  115. package/src/internal/listeners.ts +91 -0
  116. package/src/internal/modal-fields.ts +95 -0
  117. package/src/internal/payload.ts +69 -0
  118. package/src/internal/rest-body.ts +115 -0
  119. package/src/internal/rest-errors.ts +88 -0
  120. package/src/internal/rest-routes.ts +50 -0
  121. package/src/internal/rest-scheduler.ts +557 -0
  122. package/src/internal/rest.ts +322 -0
  123. package/src/internal/schemas.ts +36 -0
  124. package/src/internal/structures.ts +280 -0
  125. package/src/internal/test-builders.test-support.ts +167 -0
  126. package/src/internal/voice.ts +49 -0
  127. package/src/media-detection.ts +28 -0
  128. package/src/mentions.ts +147 -0
  129. package/src/monitor/ack-reactions.ts +70 -0
  130. package/src/monitor/agent-components-auth.ts +7 -0
  131. package/src/monitor/agent-components-context.ts +154 -0
  132. package/src/monitor/agent-components-data.ts +224 -0
  133. package/src/monitor/agent-components-dm-auth.ts +177 -0
  134. package/src/monitor/agent-components-guild-auth.ts +322 -0
  135. package/src/monitor/agent-components-helpers.runtime.ts +3 -0
  136. package/src/monitor/agent-components-helpers.ts +34 -0
  137. package/src/monitor/agent-components-reply.ts +10 -0
  138. package/src/monitor/agent-components.deps.runtime.ts +2 -0
  139. package/src/monitor/agent-components.dispatch.ts +359 -0
  140. package/src/monitor/agent-components.handlers.ts +303 -0
  141. package/src/monitor/agent-components.modal.ts +160 -0
  142. package/src/monitor/agent-components.plugin-interactive.ts +187 -0
  143. package/src/monitor/agent-components.runtime.ts +14 -0
  144. package/src/monitor/agent-components.system-controls.ts +215 -0
  145. package/src/monitor/agent-components.ts +70 -0
  146. package/src/monitor/agent-components.types.ts +58 -0
  147. package/src/monitor/agent-components.wildcard-controls.ts +171 -0
  148. package/src/monitor/allow-list.ts +631 -0
  149. package/src/monitor/auto-presence.ts +356 -0
  150. package/src/monitor/channel-access.ts +102 -0
  151. package/src/monitor/commands.ts +9 -0
  152. package/src/monitor/dm-command-auth.ts +259 -0
  153. package/src/monitor/dm-command-decision.ts +49 -0
  154. package/src/monitor/exec-approvals.ts +161 -0
  155. package/src/monitor/format.ts +45 -0
  156. package/src/monitor/gateway-handle.ts +34 -0
  157. package/src/monitor/gateway-metadata.ts +298 -0
  158. package/src/monitor/gateway-plugin.ts +302 -0
  159. package/src/monitor/gateway-registry.ts +37 -0
  160. package/src/monitor/gateway-supervisor.ts +206 -0
  161. package/src/monitor/inbound-context.ts +95 -0
  162. package/src/monitor/inbound-dedupe.ts +79 -0
  163. package/src/monitor/inbound-job.ts +118 -0
  164. package/src/monitor/listeners.queue.ts +91 -0
  165. package/src/monitor/listeners.reactions.ts +594 -0
  166. package/src/monitor/listeners.ts +150 -0
  167. package/src/monitor/message-channel-info.ts +96 -0
  168. package/src/monitor/message-forwarded.ts +114 -0
  169. package/src/monitor/message-handler.batch-gate.ts +19 -0
  170. package/src/monitor/message-handler.context.ts +492 -0
  171. package/src/monitor/message-handler.dm-preflight.ts +119 -0
  172. package/src/monitor/message-handler.draft-preview.ts +436 -0
  173. package/src/monitor/message-handler.hydration.ts +198 -0
  174. package/src/monitor/message-handler.module-test-helpers.ts +31 -0
  175. package/src/monitor/message-handler.preflight-channel-access.ts +86 -0
  176. package/src/monitor/message-handler.preflight-channel-context.ts +58 -0
  177. package/src/monitor/message-handler.preflight-context.ts +54 -0
  178. package/src/monitor/message-handler.preflight-helpers.ts +164 -0
  179. package/src/monitor/message-handler.preflight-history.ts +23 -0
  180. package/src/monitor/message-handler.preflight-logging.ts +36 -0
  181. package/src/monitor/message-handler.preflight-pluralkit.ts +28 -0
  182. package/src/monitor/message-handler.preflight-runtime.ts +28 -0
  183. package/src/monitor/message-handler.preflight-thread.ts +49 -0
  184. package/src/monitor/message-handler.preflight.ts +822 -0
  185. package/src/monitor/message-handler.preflight.types.ts +115 -0
  186. package/src/monitor/message-handler.process.ts +1033 -0
  187. package/src/monitor/message-handler.routing-preflight.ts +112 -0
  188. package/src/monitor/message-handler.ts +309 -0
  189. package/src/monitor/message-media.ts +536 -0
  190. package/src/monitor/message-run-queue.ts +101 -0
  191. package/src/monitor/message-text.ts +171 -0
  192. package/src/monitor/message-utils.ts +34 -0
  193. package/src/monitor/model-picker-preferences.ts +184 -0
  194. package/src/monitor/model-picker.state.ts +364 -0
  195. package/src/monitor/model-picker.test-utils.ts +26 -0
  196. package/src/monitor/model-picker.ts +38 -0
  197. package/src/monitor/model-picker.view.ts +722 -0
  198. package/src/monitor/native-command-agent-reply.ts +125 -0
  199. package/src/monitor/native-command-arg-ui.ts +233 -0
  200. package/src/monitor/native-command-auth.ts +309 -0
  201. package/src/monitor/native-command-bypass.ts +13 -0
  202. package/src/monitor/native-command-context.ts +109 -0
  203. package/src/monitor/native-command-dispatch.ts +35 -0
  204. package/src/monitor/native-command-model-picker-apply.ts +209 -0
  205. package/src/monitor/native-command-model-picker-interaction.ts +516 -0
  206. package/src/monitor/native-command-model-picker-ui.ts +357 -0
  207. package/src/monitor/native-command-reply.ts +185 -0
  208. package/src/monitor/native-command-route.ts +91 -0
  209. package/src/monitor/native-command-status.ts +76 -0
  210. package/src/monitor/native-command-ui.ts +26 -0
  211. package/src/monitor/native-command-ui.types.ts +20 -0
  212. package/src/monitor/native-command.args.ts +45 -0
  213. package/src/monitor/native-command.options.ts +153 -0
  214. package/src/monitor/native-command.runtime.ts +51 -0
  215. package/src/monitor/native-command.ts +747 -0
  216. package/src/monitor/native-command.types.ts +9 -0
  217. package/src/monitor/native-interaction-channel-context.ts +50 -0
  218. package/src/monitor/preflight-audio.runtime.ts +9 -0
  219. package/src/monitor/preflight-audio.ts +130 -0
  220. package/src/monitor/presence-cache.ts +61 -0
  221. package/src/monitor/presence.ts +50 -0
  222. package/src/monitor/provider-session.runtime.ts +12 -0
  223. package/src/monitor/provider.acp.ts +89 -0
  224. package/src/monitor/provider.allowlist.ts +398 -0
  225. package/src/monitor/provider.cleanup.ts +41 -0
  226. package/src/monitor/provider.commands.ts +129 -0
  227. package/src/monitor/provider.config-log.ts +45 -0
  228. package/src/monitor/provider.deploy-errors.ts +362 -0
  229. package/src/monitor/provider.deploy.ts +221 -0
  230. package/src/monitor/provider.interactions.ts +160 -0
  231. package/src/monitor/provider.lifecycle.ts +562 -0
  232. package/src/monitor/provider.runtime.ts +1 -0
  233. package/src/monitor/provider.startup-log.ts +32 -0
  234. package/src/monitor/provider.startup.ts +323 -0
  235. package/src/monitor/provider.ts +688 -0
  236. package/src/monitor/reply-context.ts +64 -0
  237. package/src/monitor/reply-delivery.ts +216 -0
  238. package/src/monitor/reply-safety.ts +96 -0
  239. package/src/monitor/rest-fetch.ts +97 -0
  240. package/src/monitor/route-resolution.ts +140 -0
  241. package/src/monitor/sender-identity.ts +81 -0
  242. package/src/monitor/startup-status.ts +10 -0
  243. package/src/monitor/status.ts +22 -0
  244. package/src/monitor/system-events.ts +55 -0
  245. package/src/monitor/thread-bindings.config.ts +35 -0
  246. package/src/monitor/thread-bindings.discord-api.ts +310 -0
  247. package/src/monitor/thread-bindings.lifecycle.ts +354 -0
  248. package/src/monitor/thread-bindings.manager.ts +554 -0
  249. package/src/monitor/thread-bindings.messages.ts +6 -0
  250. package/src/monitor/thread-bindings.persona.ts +25 -0
  251. package/src/monitor/thread-bindings.session-adapter.ts +229 -0
  252. package/src/monitor/thread-bindings.session-shared.ts +59 -0
  253. package/src/monitor/thread-bindings.session-updates.ts +35 -0
  254. package/src/monitor/thread-bindings.state.ts +540 -0
  255. package/src/monitor/thread-bindings.ts +48 -0
  256. package/src/monitor/thread-bindings.types.ts +83 -0
  257. package/src/monitor/thread-channel-context.ts +112 -0
  258. package/src/monitor/thread-session-close.ts +63 -0
  259. package/src/monitor/thread-title.ts +181 -0
  260. package/src/monitor/threading.auto-thread.ts +287 -0
  261. package/src/monitor/threading.cache.ts +45 -0
  262. package/src/monitor/threading.starter.ts +288 -0
  263. package/src/monitor/threading.ts +20 -0
  264. package/src/monitor/threading.types.ts +102 -0
  265. package/src/monitor/timeouts.ts +84 -0
  266. package/src/monitor/typing.ts +17 -0
  267. package/src/monitor.gateway.ts +75 -0
  268. package/src/monitor.ts +28 -0
  269. package/src/network-config.ts +79 -0
  270. package/src/normalize.ts +86 -0
  271. package/src/outbound-adapter.ts +327 -0
  272. package/src/outbound-approval.ts +29 -0
  273. package/src/outbound-components.ts +86 -0
  274. package/src/outbound-payload.ts +208 -0
  275. package/src/outbound-send-context.ts +92 -0
  276. package/src/outbound-session-route.ts +72 -0
  277. package/src/pluralkit.ts +58 -0
  278. package/src/preview-streaming.ts +18 -0
  279. package/src/probe.runtime.ts +1 -0
  280. package/src/probe.ts +237 -0
  281. package/src/proxy-fetch.ts +92 -0
  282. package/src/proxy-request-client.ts +21 -0
  283. package/src/recipient-resolution.ts +39 -0
  284. package/src/resolve-allowlist-common.ts +39 -0
  285. package/src/resolve-channels.ts +369 -0
  286. package/src/resolve-users.ts +184 -0
  287. package/src/retry.ts +98 -0
  288. package/src/runtime-api.ts +64 -0
  289. package/src/runtime-config.ts +16 -0
  290. package/src/runtime.ts +23 -0
  291. package/src/secret-config-contract.ts +140 -0
  292. package/src/security-audit.runtime.ts +1 -0
  293. package/src/security-audit.ts +208 -0
  294. package/src/security-contract.ts +47 -0
  295. package/src/security-doctor.ts +20 -0
  296. package/src/security.ts +60 -0
  297. package/src/send-target-parsing.ts +14 -0
  298. package/src/send.channels.ts +139 -0
  299. package/src/send.components.ts +391 -0
  300. package/src/send.emojis-stickers.ts +57 -0
  301. package/src/send.guild.ts +170 -0
  302. package/src/send.message-request.ts +112 -0
  303. package/src/send.messages.ts +229 -0
  304. package/src/send.outbound.ts +459 -0
  305. package/src/send.permissions.ts +283 -0
  306. package/src/send.reactions.ts +155 -0
  307. package/src/send.receipt.ts +69 -0
  308. package/src/send.shared.ts +469 -0
  309. package/src/send.ts +82 -0
  310. package/src/send.types.ts +191 -0
  311. package/src/send.typing.ts +9 -0
  312. package/src/send.voice.ts +140 -0
  313. package/src/send.webhook.ts +137 -0
  314. package/src/session-contract.ts +3 -0
  315. package/src/session-key-normalization.ts +47 -0
  316. package/src/setup-account-state.ts +144 -0
  317. package/src/setup-adapter.ts +14 -0
  318. package/src/setup-core.ts +215 -0
  319. package/src/setup-runtime-helpers.ts +10 -0
  320. package/src/setup-surface.ts +132 -0
  321. package/src/shared-interactive.ts +167 -0
  322. package/src/shared.ts +197 -0
  323. package/src/status-issues.ts +201 -0
  324. package/src/subagent-hooks.ts +232 -0
  325. package/src/target-parsing.ts +70 -0
  326. package/src/target-resolver.ts +129 -0
  327. package/src/targets.ts +12 -0
  328. package/src/token.ts +107 -0
  329. package/src/ui-colors.ts +27 -0
  330. package/src/ui.ts +20 -0
  331. package/src/voice/access.ts +126 -0
  332. package/src/voice/audio.ts +249 -0
  333. package/src/voice/capture-state.ts +120 -0
  334. package/src/voice/command.ts +284 -0
  335. package/src/voice/config.ts +8 -0
  336. package/src/voice/ingress.ts +164 -0
  337. package/src/voice/manager.runtime.ts +14 -0
  338. package/src/voice/manager.ts +1155 -0
  339. package/src/voice/prompt.ts +22 -0
  340. package/src/voice/realtime.ts +1370 -0
  341. package/src/voice/receive-recovery.ts +159 -0
  342. package/src/voice/sanitize.ts +29 -0
  343. package/src/voice/sdk-runtime.ts +14 -0
  344. package/src/voice/segment.ts +160 -0
  345. package/src/voice/session.ts +81 -0
  346. package/src/voice/speaker-context.ts +127 -0
  347. package/src/voice/tts.ts +151 -0
  348. package/src/voice-message.ts +474 -0
  349. package/subagent-hooks-api.ts +27 -0
  350. package/test-api.ts +4 -0
  351. package/thread-binding-api.ts +1 -0
  352. package/timeouts.ts +6 -0
  353. package/tsconfig.json +16 -0
@@ -0,0 +1,688 @@
1
+ import type { ChannelRuntimeSurface } from "autobot/plugin-sdk/channel-contract";
2
+ import {
3
+ listNativeCommandSpecsForConfig,
4
+ listSkillCommandsForAgents,
5
+ } from "autobot/plugin-sdk/command-auth-native";
6
+ import type { AutoBotConfig, ReplyToMode } from "autobot/plugin-sdk/config-contracts";
7
+ import { createConnectedChannelStatusPatch } from "autobot/plugin-sdk/gateway-runtime";
8
+ import {
9
+ resolveNativeCommandsEnabled,
10
+ resolveNativeSkillsEnabled,
11
+ } from "autobot/plugin-sdk/native-command-config-runtime";
12
+ import { resolveTextChunkLimit } from "autobot/plugin-sdk/reply-chunking";
13
+ import { getRuntimeConfig } from "autobot/plugin-sdk/runtime-config-snapshot";
14
+ import { isVerbose, logVerbose, shouldLogVerbose, warn } from "autobot/plugin-sdk/runtime-env";
15
+ import { createSubsystemLogger } from "autobot/plugin-sdk/runtime-env";
16
+ import { createNonExitingRuntime, type RuntimeEnv } from "autobot/plugin-sdk/runtime-env";
17
+ import {
18
+ GROUP_POLICY_BLOCKED_LABEL,
19
+ resolveOpenProviderRuntimeGroupPolicy,
20
+ resolveDefaultGroupPolicy,
21
+ warnMissingProviderGroupPolicyFallbackOnce,
22
+ } from "autobot/plugin-sdk/runtime-group-policy";
23
+ import { formatErrorMessage } from "autobot/plugin-sdk/ssrf-runtime";
24
+ import {
25
+ resolveDiscordAccount,
26
+ resolveDiscordAccountAllowFrom,
27
+ resolveDiscordAccountDmPolicy,
28
+ } from "../accounts.js";
29
+ import { Client } from "../internal/discord.js";
30
+ import { GatewayCloseCodes } from "../internal/gateway.js";
31
+ import { fetchDiscordApplicationId, parseApplicationIdFromToken } from "../probe.js";
32
+ import { normalizeDiscordToken } from "../token.js";
33
+ import { resolveDiscordVoiceEnabled } from "../voice/config.js";
34
+ import { createDiscordAutoPresenceController } from "./auto-presence.js";
35
+ import { resolveDiscordSlashCommandConfig } from "./commands.js";
36
+ import type { MutableDiscordGateway } from "./gateway-handle.js";
37
+ import { createDiscordGatewayPlugin } from "./gateway-plugin.js";
38
+ import { createDiscordGatewaySupervisor } from "./gateway-supervisor.js";
39
+ import { registerDiscordListener } from "./listeners.js";
40
+ import { createDiscordNativeCommand } from "./native-command.js";
41
+ import { probeDiscordAcpBindingHealth } from "./provider.acp.js";
42
+ import { resolveDiscordAllowlistConfig } from "./provider.allowlist.js";
43
+ import { cleanupDiscordProviderStartup } from "./provider.cleanup.js";
44
+ import {
45
+ resolveDiscordProviderCommandSpecs,
46
+ type GetPluginCommandSpecs,
47
+ } from "./provider.commands.js";
48
+ import { logDiscordResolvedConfig } from "./provider.config-log.js";
49
+ import {
50
+ formatDiscordDeployErrorDetails,
51
+ formatDiscordDeployErrorMessage,
52
+ } from "./provider.deploy-errors.js";
53
+ import { runDiscordCommandDeployInBackground } from "./provider.deploy.js";
54
+ import { createDiscordProviderInteractionSurface } from "./provider.interactions.js";
55
+ import { runDiscordGatewayLifecycle } from "./provider.lifecycle.js";
56
+ import { logDiscordStartupPhase as logDiscordStartupPhaseBase } from "./provider.startup-log.js";
57
+ import {
58
+ createDiscordMonitorClient,
59
+ fetchDiscordBotIdentity,
60
+ registerDiscordMonitorListeners,
61
+ } from "./provider.startup.js";
62
+ import { resolveDiscordRestFetch } from "./rest-fetch.js";
63
+ import { formatDiscordStartupStatusMessage } from "./startup-status.js";
64
+ import type { DiscordMonitorStatusSink } from "./status.js";
65
+
66
+ export type MonitorDiscordOpts = {
67
+ token?: string;
68
+ accountId?: string;
69
+ config?: AutoBotConfig;
70
+ runtime?: RuntimeEnv;
71
+ channelRuntime?: ChannelRuntimeSurface;
72
+ abortSignal?: AbortSignal;
73
+ mediaMaxMb?: number;
74
+ historyLimit?: number;
75
+ replyToMode?: ReplyToMode;
76
+ setStatus?: DiscordMonitorStatusSink;
77
+ };
78
+
79
+ const DEFAULT_DISCORD_MEDIA_MAX_MB = 100;
80
+
81
+ type DiscordVoiceManager = import("../voice/manager.js").DiscordVoiceManager;
82
+
83
+ type DiscordVoiceRuntimeModule = typeof import("../voice/manager.runtime.js");
84
+ type DiscordProviderSessionRuntimeModule = typeof import("./provider-session.runtime.js");
85
+
86
+ let discordVoiceRuntimePromise: Promise<DiscordVoiceRuntimeModule> | undefined;
87
+ let discordProviderSessionRuntimePromise: Promise<DiscordProviderSessionRuntimeModule> | undefined;
88
+
89
+ let fetchDiscordApplicationIdForTesting: typeof fetchDiscordApplicationId | undefined;
90
+ let createDiscordNativeCommandForTesting: typeof createDiscordNativeCommand | undefined;
91
+ let runDiscordGatewayLifecycleForTesting: typeof runDiscordGatewayLifecycle | undefined;
92
+ let createDiscordGatewayPluginForTesting: typeof createDiscordGatewayPlugin | undefined;
93
+ let createDiscordGatewaySupervisorForTesting: typeof createDiscordGatewaySupervisor | undefined;
94
+ let loadDiscordVoiceRuntimeForTesting: (() => Promise<DiscordVoiceRuntimeModule>) | undefined;
95
+ let loadDiscordProviderSessionRuntimeForTesting:
96
+ | (() => Promise<DiscordProviderSessionRuntimeModule>)
97
+ | undefined;
98
+ let createClientForTesting:
99
+ | ((
100
+ options: ConstructorParameters<typeof Client>[0],
101
+ handlers: ConstructorParameters<typeof Client>[1],
102
+ plugins: ConstructorParameters<typeof Client>[2],
103
+ ) => Client)
104
+ | undefined;
105
+ let getPluginCommandSpecsForTesting: GetPluginCommandSpecs | undefined;
106
+ let resolveDiscordAccountForTesting: typeof resolveDiscordAccount | undefined;
107
+ let resolveNativeCommandsEnabledForTesting: typeof resolveNativeCommandsEnabled | undefined;
108
+ let resolveNativeSkillsEnabledForTesting: typeof resolveNativeSkillsEnabled | undefined;
109
+ let listNativeCommandSpecsForConfigForTesting: typeof listNativeCommandSpecsForConfig | undefined;
110
+ let listSkillCommandsForAgentsForTesting: typeof listSkillCommandsForAgents | undefined;
111
+ let isVerboseForTesting: typeof isVerbose | undefined;
112
+ let shouldLogVerboseForTesting: typeof shouldLogVerbose | undefined;
113
+
114
+ function logDiscordStartupPhase(
115
+ params: Omit<Parameters<typeof logDiscordStartupPhaseBase>[0], "isVerbose">,
116
+ ) {
117
+ logDiscordStartupPhaseBase({
118
+ ...params,
119
+ isVerbose: isVerboseForTesting ?? isVerbose,
120
+ });
121
+ }
122
+
123
+ async function loadDiscordVoiceRuntime(): Promise<DiscordVoiceRuntimeModule> {
124
+ if (loadDiscordVoiceRuntimeForTesting) {
125
+ return await loadDiscordVoiceRuntimeForTesting();
126
+ }
127
+ const promise = discordVoiceRuntimePromise ?? import("../voice/manager.runtime.js");
128
+ discordVoiceRuntimePromise = promise;
129
+ try {
130
+ return await promise;
131
+ } catch (error) {
132
+ if (discordVoiceRuntimePromise === promise) {
133
+ discordVoiceRuntimePromise = undefined;
134
+ }
135
+ throw error;
136
+ }
137
+ }
138
+
139
+ async function loadDiscordProviderSessionRuntime(): Promise<DiscordProviderSessionRuntimeModule> {
140
+ if (loadDiscordProviderSessionRuntimeForTesting) {
141
+ return await loadDiscordProviderSessionRuntimeForTesting();
142
+ }
143
+ const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime.js");
144
+ discordProviderSessionRuntimePromise = promise;
145
+ try {
146
+ return await promise;
147
+ } catch (error) {
148
+ if (discordProviderSessionRuntimePromise === promise) {
149
+ discordProviderSessionRuntimePromise = undefined;
150
+ }
151
+ throw error;
152
+ }
153
+ }
154
+
155
+ function normalizeBooleanForTesting(value: unknown): boolean | undefined {
156
+ if (typeof value === "boolean") {
157
+ return value;
158
+ }
159
+ return undefined;
160
+ }
161
+
162
+ function resolveThreadBindingsEnabledForTesting(params: {
163
+ channelEnabledRaw: unknown;
164
+ sessionEnabledRaw: unknown;
165
+ }): boolean {
166
+ return (
167
+ normalizeBooleanForTesting(params.channelEnabledRaw) ??
168
+ normalizeBooleanForTesting(params.sessionEnabledRaw) ??
169
+ true
170
+ );
171
+ }
172
+
173
+ const DISCORD_DISALLOWED_INTENTS_CODE = GatewayCloseCodes.DisallowedIntents;
174
+
175
+ function isDiscordDisallowedIntentsError(err: unknown): boolean {
176
+ if (!err) {
177
+ return false;
178
+ }
179
+ const message = formatErrorMessage(err);
180
+ return message.includes(String(DISCORD_DISALLOWED_INTENTS_CODE));
181
+ }
182
+
183
+ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
184
+ const startupStartedAt = Date.now();
185
+ const cfg = opts.config ?? getRuntimeConfig();
186
+ const account = (resolveDiscordAccountForTesting ?? resolveDiscordAccount)({
187
+ cfg,
188
+ accountId: opts.accountId,
189
+ });
190
+ const token =
191
+ normalizeDiscordToken(opts.token ?? undefined, "channels.discord.token") ?? account.token;
192
+ if (!token) {
193
+ throw new Error(
194
+ `Discord bot token missing for account "${account.accountId}" (set discord.accounts.${account.accountId}.token or DISCORD_BOT_TOKEN for default).`,
195
+ );
196
+ }
197
+
198
+ const runtime: RuntimeEnv = opts.runtime ?? createNonExitingRuntime();
199
+
200
+ const rawDiscordCfg = account.config;
201
+ const discordRootThreadBindings = cfg.channels?.discord?.threadBindings;
202
+ const discordAccountThreadBindings =
203
+ cfg.channels?.discord?.accounts?.[account.accountId]?.threadBindings;
204
+ const discordRestFetch = resolveDiscordRestFetch(rawDiscordCfg.proxy, runtime);
205
+ const dmConfig = rawDiscordCfg.dm;
206
+ const configuredDmAllowFrom = resolveDiscordAccountAllowFrom({
207
+ cfg,
208
+ accountId: account.accountId,
209
+ });
210
+ let guildEntries = rawDiscordCfg.guilds;
211
+ const defaultGroupPolicy = resolveDefaultGroupPolicy(cfg);
212
+ const providerConfigPresent = cfg.channels?.discord !== undefined;
213
+ const { groupPolicy, providerMissingFallbackApplied } = resolveOpenProviderRuntimeGroupPolicy({
214
+ providerConfigPresent,
215
+ groupPolicy: rawDiscordCfg.groupPolicy,
216
+ defaultGroupPolicy,
217
+ });
218
+ const discordCfg =
219
+ rawDiscordCfg.groupPolicy === groupPolicy ? rawDiscordCfg : { ...rawDiscordCfg, groupPolicy };
220
+ warnMissingProviderGroupPolicyFallbackOnce({
221
+ providerMissingFallbackApplied,
222
+ providerKey: "discord",
223
+ accountId: account.accountId,
224
+ blockedLabel: GROUP_POLICY_BLOCKED_LABEL.guild,
225
+ log: (message) => runtime.log?.(warn(message)),
226
+ });
227
+ let allowFrom = configuredDmAllowFrom ?? [];
228
+ const mediaMaxBytes =
229
+ (opts.mediaMaxMb ?? discordCfg.mediaMaxMb ?? DEFAULT_DISCORD_MEDIA_MAX_MB) * 1024 * 1024;
230
+ const textLimit = resolveTextChunkLimit(cfg, "discord", account.accountId, {
231
+ fallbackLimit: 2000,
232
+ });
233
+ const historyLimit = Math.max(
234
+ 0,
235
+ opts.historyLimit ?? discordCfg.historyLimit ?? cfg.messages?.groupChat?.historyLimit ?? 20,
236
+ );
237
+ const replyToMode = opts.replyToMode ?? discordCfg.replyToMode ?? "off";
238
+ const dmEnabled = dmConfig?.enabled ?? true;
239
+ const dmPolicy =
240
+ resolveDiscordAccountDmPolicy({
241
+ cfg,
242
+ accountId: account.accountId,
243
+ }) ?? "pairing";
244
+ const discordProviderSessionRuntime = await loadDiscordProviderSessionRuntime();
245
+ const threadBindingIdleTimeoutMs =
246
+ discordProviderSessionRuntime.resolveThreadBindingIdleTimeoutMs({
247
+ channelIdleHoursRaw:
248
+ discordAccountThreadBindings?.idleHours ?? discordRootThreadBindings?.idleHours,
249
+ sessionIdleHoursRaw: cfg.session?.threadBindings?.idleHours,
250
+ });
251
+ const threadBindingMaxAgeMs = discordProviderSessionRuntime.resolveThreadBindingMaxAgeMs({
252
+ channelMaxAgeHoursRaw:
253
+ discordAccountThreadBindings?.maxAgeHours ?? discordRootThreadBindings?.maxAgeHours,
254
+ sessionMaxAgeHoursRaw: cfg.session?.threadBindings?.maxAgeHours,
255
+ });
256
+ const threadBindingsEnabled = discordProviderSessionRuntime.resolveThreadBindingsEnabled({
257
+ channelEnabledRaw: discordAccountThreadBindings?.enabled ?? discordRootThreadBindings?.enabled,
258
+ sessionEnabledRaw: cfg.session?.threadBindings?.enabled,
259
+ });
260
+ const groupDmEnabled = dmConfig?.groupEnabled ?? false;
261
+ const groupDmChannels = dmConfig?.groupChannels;
262
+ const nativeEnabled = (resolveNativeCommandsEnabledForTesting ?? resolveNativeCommandsEnabled)({
263
+ providerId: "discord",
264
+ providerSetting: discordCfg.commands?.native,
265
+ globalSetting: cfg.commands?.native,
266
+ });
267
+ const nativeSkillsEnabled = (resolveNativeSkillsEnabledForTesting ?? resolveNativeSkillsEnabled)({
268
+ providerId: "discord",
269
+ providerSetting: discordCfg.commands?.nativeSkills,
270
+ globalSetting: cfg.commands?.nativeSkills,
271
+ });
272
+ const useAccessGroups = cfg.commands?.useAccessGroups !== false;
273
+ const slashCommand = resolveDiscordSlashCommandConfig(discordCfg.slashCommand);
274
+ const sessionPrefix = "discord:slash";
275
+ const ephemeralDefault = slashCommand.ephemeral;
276
+ const voiceEnabled = resolveDiscordVoiceEnabled(discordCfg.voice);
277
+
278
+ const allowlistResolved = await resolveDiscordAllowlistConfig({
279
+ token,
280
+ guildEntries,
281
+ allowFrom,
282
+ discordConfig: discordCfg,
283
+ fetcher: discordRestFetch,
284
+ runtime,
285
+ });
286
+ guildEntries = allowlistResolved.guildEntries;
287
+ allowFrom = allowlistResolved.allowFrom ?? [];
288
+
289
+ if ((shouldLogVerboseForTesting ?? shouldLogVerbose)()) {
290
+ logDiscordResolvedConfig({
291
+ dmEnabled,
292
+ dmPolicy,
293
+ allowFrom,
294
+ groupDmEnabled,
295
+ groupDmChannels,
296
+ groupPolicy,
297
+ guildEntries,
298
+ historyLimit,
299
+ mediaMaxBytes,
300
+ nativeEnabled,
301
+ nativeSkillsEnabled,
302
+ useAccessGroups,
303
+ threadBindingsEnabled,
304
+ threadBindingIdleTimeoutMs,
305
+ threadBindingMaxAgeMs,
306
+ });
307
+ }
308
+
309
+ logDiscordStartupPhase({
310
+ runtime,
311
+ accountId: account.accountId,
312
+ phase: "fetch-application-id:start",
313
+ startAt: startupStartedAt,
314
+ });
315
+ const configuredApplicationId =
316
+ typeof discordCfg.applicationId === "string" && discordCfg.applicationId.trim()
317
+ ? discordCfg.applicationId.trim()
318
+ : undefined;
319
+ const parsedApplicationId = configuredApplicationId ?? parseApplicationIdFromToken(token);
320
+ const applicationId =
321
+ parsedApplicationId ??
322
+ (await (fetchDiscordApplicationIdForTesting ?? fetchDiscordApplicationId)(
323
+ token,
324
+ 4000,
325
+ discordRestFetch,
326
+ ));
327
+ if (!applicationId) {
328
+ throw new Error("Failed to resolve Discord application id");
329
+ }
330
+ logDiscordStartupPhase({
331
+ runtime,
332
+ accountId: account.accountId,
333
+ phase: "fetch-application-id:done",
334
+ startAt: startupStartedAt,
335
+ details: `applicationId=${applicationId}`,
336
+ });
337
+
338
+ const { commandSpecs } = await resolveDiscordProviderCommandSpecs({
339
+ cfg,
340
+ runtime,
341
+ nativeEnabled,
342
+ nativeSkillsEnabled,
343
+ listSkillCommandsForAgents: listSkillCommandsForAgentsForTesting ?? listSkillCommandsForAgents,
344
+ listNativeCommandSpecsForConfig:
345
+ listNativeCommandSpecsForConfigForTesting ?? listNativeCommandSpecsForConfig,
346
+ getPluginCommandSpecs: getPluginCommandSpecsForTesting,
347
+ });
348
+ const voiceManagerRef: { current: DiscordVoiceManager | null } = { current: null };
349
+ const threadBindings = threadBindingsEnabled
350
+ ? discordProviderSessionRuntime.createThreadBindingManager({
351
+ accountId: account.accountId,
352
+ token,
353
+ cfg,
354
+ idleTimeoutMs: threadBindingIdleTimeoutMs,
355
+ maxAgeMs: threadBindingMaxAgeMs,
356
+ })
357
+ : discordProviderSessionRuntime.createNoopThreadBindingManager(account.accountId);
358
+ if (threadBindingsEnabled) {
359
+ const uncertainProbeKeys = new Set<string>();
360
+ const reconciliation = await discordProviderSessionRuntime.reconcileAcpThreadBindingsOnStartup({
361
+ cfg,
362
+ accountId: account.accountId,
363
+ sendFarewell: false,
364
+ healthProbe: async ({ sessionKey, session }) => {
365
+ const probe = await probeDiscordAcpBindingHealth({
366
+ cfg,
367
+ sessionKey,
368
+ storedState: session.acp?.state,
369
+ lastActivityAt: session.acp?.lastActivityAt,
370
+ providerSessionRuntime: discordProviderSessionRuntime,
371
+ });
372
+ if (probe.status === "uncertain") {
373
+ uncertainProbeKeys.add(`${sessionKey}${probe.reason ? ` (${probe.reason})` : ""}`);
374
+ }
375
+ return probe;
376
+ },
377
+ });
378
+ if (reconciliation.removed > 0) {
379
+ logVerbose(
380
+ `discord: removed ${reconciliation.removed}/${reconciliation.checked} stale ACP thread bindings on startup for account ${account.accountId}: ${reconciliation.staleSessionKeys.join(", ")}`,
381
+ );
382
+ }
383
+ if (uncertainProbeKeys.size > 0) {
384
+ logVerbose(
385
+ `discord: ACP thread-binding health probe uncertain for account ${account.accountId}: ${[...uncertainProbeKeys].join(", ")}`,
386
+ );
387
+ }
388
+ }
389
+ let lifecycleStarted = false;
390
+ let gatewaySupervisor: ReturnType<typeof createDiscordGatewaySupervisor> | undefined;
391
+ let deactivateMessageHandler: (() => void) | undefined;
392
+ let autoPresenceController: Awaited<
393
+ ReturnType<typeof createDiscordMonitorClient>
394
+ >["autoPresenceController"] = null;
395
+ let lifecycleGateway: MutableDiscordGateway | undefined;
396
+ let earlyGatewayEmitter = gatewaySupervisor?.emitter;
397
+ let onEarlyGatewayDebug: ((msg: unknown) => void) | undefined;
398
+ try {
399
+ const { commands, components, modals } = createDiscordProviderInteractionSurface({
400
+ cfg,
401
+ discordConfig: discordCfg,
402
+ accountId: account.accountId,
403
+ token,
404
+ commandSpecs,
405
+ nativeEnabled,
406
+ voiceEnabled,
407
+ groupPolicy,
408
+ useAccessGroups,
409
+ sessionPrefix,
410
+ ephemeralDefault,
411
+ threadBindings,
412
+ voiceManagerRef,
413
+ guildEntries,
414
+ allowFrom,
415
+ dmPolicy,
416
+ runtime,
417
+ channelRuntime: opts.channelRuntime,
418
+ abortSignal: opts.abortSignal,
419
+ createNativeCommand: createDiscordNativeCommandForTesting ?? createDiscordNativeCommand,
420
+ });
421
+
422
+ const {
423
+ client,
424
+ gateway,
425
+ gatewaySupervisor: createdGatewaySupervisor,
426
+ autoPresenceController: createdAutoPresenceController,
427
+ } = await createDiscordMonitorClient({
428
+ accountId: account.accountId,
429
+ applicationId,
430
+ token,
431
+ restFetch: discordRestFetch,
432
+ commands,
433
+ components,
434
+ modals,
435
+ voiceEnabled,
436
+ discordConfig: discordCfg,
437
+ runtime,
438
+ createClient: createClientForTesting ?? ((...args) => new Client(...args)),
439
+ createGatewayPlugin: createDiscordGatewayPluginForTesting ?? createDiscordGatewayPlugin,
440
+ createGatewaySupervisor:
441
+ createDiscordGatewaySupervisorForTesting ?? createDiscordGatewaySupervisor,
442
+ createAutoPresenceController: createDiscordAutoPresenceController,
443
+ isDisallowedIntentsError: isDiscordDisallowedIntentsError,
444
+ });
445
+ lifecycleGateway = gateway;
446
+ gatewaySupervisor = createdGatewaySupervisor;
447
+ autoPresenceController = createdAutoPresenceController;
448
+
449
+ earlyGatewayEmitter = gatewaySupervisor.emitter;
450
+ onEarlyGatewayDebug = (msg: unknown) => {
451
+ if (!(isVerboseForTesting ?? isVerbose)()) {
452
+ return;
453
+ }
454
+ runtime.log?.(
455
+ `discord startup [${account.accountId}] gateway-debug ${Math.max(0, Date.now() - startupStartedAt)}ms ${String(msg)}`,
456
+ );
457
+ };
458
+ earlyGatewayEmitter?.on("debug", onEarlyGatewayDebug);
459
+
460
+ logDiscordStartupPhase({
461
+ runtime,
462
+ accountId: account.accountId,
463
+ phase: "deploy-commands:schedule",
464
+ startAt: startupStartedAt,
465
+ gateway: lifecycleGateway,
466
+ details: `native=${nativeEnabled ? "on" : "off"} reconcile=on commandCount=${commands.length}`,
467
+ });
468
+ runDiscordCommandDeployInBackground({
469
+ client,
470
+ runtime,
471
+ enabled: nativeEnabled,
472
+ accountId: account.accountId,
473
+ startupStartedAt,
474
+ shouldLogVerbose: shouldLogVerboseForTesting ?? shouldLogVerbose,
475
+ isVerbose: isVerboseForTesting ?? isVerbose,
476
+ });
477
+
478
+ const logger = createSubsystemLogger("discord/monitor");
479
+ const guildHistories = new Map<
480
+ string,
481
+ import("autobot/plugin-sdk/reply-history").HistoryEntry[]
482
+ >();
483
+ let { botUserId, botUserName } = await fetchDiscordBotIdentity({
484
+ client,
485
+ token,
486
+ runtime,
487
+ logStartupPhase: (phase, details) =>
488
+ logDiscordStartupPhase({
489
+ runtime,
490
+ accountId: account.accountId,
491
+ phase,
492
+ startAt: startupStartedAt,
493
+ gateway: lifecycleGateway,
494
+ details,
495
+ }),
496
+ });
497
+ let voiceManager: DiscordVoiceManager | null = null;
498
+
499
+ if (voiceEnabled) {
500
+ const {
501
+ DiscordVoiceManager,
502
+ DiscordVoiceReadyListener,
503
+ DiscordVoiceResumedListener,
504
+ DiscordVoiceStateUpdateListener,
505
+ } = await loadDiscordVoiceRuntime();
506
+ voiceManager = new DiscordVoiceManager({
507
+ client,
508
+ cfg,
509
+ discordConfig: discordCfg,
510
+ accountId: account.accountId,
511
+ runtime,
512
+ botUserId,
513
+ });
514
+ voiceManagerRef.current = voiceManager;
515
+ registerDiscordListener(client.listeners, new DiscordVoiceReadyListener(voiceManager));
516
+ registerDiscordListener(client.listeners, new DiscordVoiceResumedListener(voiceManager));
517
+ registerDiscordListener(client.listeners, new DiscordVoiceStateUpdateListener(voiceManager));
518
+ }
519
+
520
+ const messageHandler = discordProviderSessionRuntime.createDiscordMessageHandler({
521
+ cfg,
522
+ discordConfig: discordCfg,
523
+ accountId: account.accountId,
524
+ token,
525
+ runtime,
526
+ setStatus: opts.setStatus,
527
+ abortSignal: opts.abortSignal,
528
+ botUserId,
529
+ guildHistories,
530
+ historyLimit,
531
+ mediaMaxBytes,
532
+ textLimit,
533
+ replyToMode,
534
+ dmEnabled,
535
+ dmPolicy,
536
+ groupDmEnabled,
537
+ groupDmChannels,
538
+ allowFrom,
539
+ guildEntries,
540
+ threadBindings,
541
+ discordRestFetch,
542
+ });
543
+ deactivateMessageHandler = messageHandler.deactivate;
544
+ const trackInboundEvent = opts.setStatus
545
+ ? () => {
546
+ const at = Date.now();
547
+ // Gateway heartbeat ACKs are transport-level; Discord app events stay app-level only.
548
+ opts.setStatus?.({ lastEventAt: at, lastInboundAt: at });
549
+ }
550
+ : undefined;
551
+ registerDiscordMonitorListeners({
552
+ cfg,
553
+ client,
554
+ accountId: account.accountId,
555
+ discordConfig: discordCfg,
556
+ runtime,
557
+ botUserId,
558
+ dmEnabled,
559
+ groupDmEnabled,
560
+ groupDmChannels,
561
+ dmPolicy,
562
+ allowFrom,
563
+ groupPolicy,
564
+ guildEntries,
565
+ logger,
566
+ messageHandler,
567
+ trackInboundEvent,
568
+ });
569
+
570
+ logDiscordStartupPhase({
571
+ runtime,
572
+ accountId: account.accountId,
573
+ phase: "client-start",
574
+ startAt: startupStartedAt,
575
+ gateway: lifecycleGateway,
576
+ });
577
+
578
+ const botIdentity =
579
+ botUserId && botUserName ? `${botUserId} (${botUserName})` : (botUserId ?? botUserName ?? "");
580
+ runtime.log?.(
581
+ formatDiscordStartupStatusMessage({
582
+ gatewayReady: lifecycleGateway?.isConnected === true,
583
+ botIdentity: botIdentity || undefined,
584
+ }),
585
+ );
586
+ if (lifecycleGateway?.isConnected) {
587
+ opts.setStatus?.(createConnectedChannelStatusPatch());
588
+ }
589
+
590
+ lifecycleStarted = true;
591
+ earlyGatewayEmitter?.removeListener("debug", onEarlyGatewayDebug);
592
+ onEarlyGatewayDebug = undefined;
593
+ await (runDiscordGatewayLifecycleForTesting ?? runDiscordGatewayLifecycle)({
594
+ accountId: account.accountId,
595
+ gateway: lifecycleGateway,
596
+ runtime,
597
+ abortSignal: opts.abortSignal,
598
+ statusSink: opts.setStatus,
599
+ isDisallowedIntentsError: isDiscordDisallowedIntentsError,
600
+ voiceManager,
601
+ voiceManagerRef,
602
+ threadBindings,
603
+ gatewaySupervisor,
604
+ gatewayReadyTimeoutMs: account.config.gatewayReadyTimeoutMs,
605
+ gatewayRuntimeReadyTimeoutMs: account.config.gatewayRuntimeReadyTimeoutMs,
606
+ });
607
+ } finally {
608
+ cleanupDiscordProviderStartup({
609
+ deactivateMessageHandler,
610
+ autoPresenceController,
611
+ setStatus: opts.setStatus,
612
+ onEarlyGatewayDebug,
613
+ earlyGatewayEmitter,
614
+ lifecycleStarted,
615
+ lifecycleGateway,
616
+ gatewaySupervisor,
617
+ threadBindings,
618
+ runtime,
619
+ });
620
+ }
621
+ }
622
+
623
+ export const testing = {
624
+ createDiscordGatewayPlugin,
625
+ resolveDiscordRuntimeGroupPolicy: resolveOpenProviderRuntimeGroupPolicy,
626
+ resolveDefaultGroupPolicy,
627
+ resolveDiscordRestFetch,
628
+ resolveThreadBindingsEnabled: resolveThreadBindingsEnabledForTesting,
629
+ formatDiscordDeployErrorDetails,
630
+ formatDiscordDeployErrorMessage,
631
+ setFetchDiscordApplicationId(mock?: typeof fetchDiscordApplicationId) {
632
+ fetchDiscordApplicationIdForTesting = mock;
633
+ },
634
+ setCreateDiscordNativeCommand(mock?: typeof createDiscordNativeCommand) {
635
+ createDiscordNativeCommandForTesting = mock;
636
+ },
637
+ setRunDiscordGatewayLifecycle(mock?: typeof runDiscordGatewayLifecycle) {
638
+ runDiscordGatewayLifecycleForTesting = mock;
639
+ },
640
+ setCreateDiscordGatewayPlugin(mock?: typeof createDiscordGatewayPlugin) {
641
+ createDiscordGatewayPluginForTesting = mock;
642
+ },
643
+ setCreateDiscordGatewaySupervisor(mock?: typeof createDiscordGatewaySupervisor) {
644
+ createDiscordGatewaySupervisorForTesting = mock;
645
+ },
646
+ setLoadDiscordVoiceRuntime(mock?: () => Promise<DiscordVoiceRuntimeModule>) {
647
+ loadDiscordVoiceRuntimeForTesting = mock;
648
+ },
649
+ setLoadDiscordProviderSessionRuntime(mock?: () => Promise<DiscordProviderSessionRuntimeModule>) {
650
+ loadDiscordProviderSessionRuntimeForTesting = mock;
651
+ },
652
+ setCreateClient(
653
+ mock?: (
654
+ options: ConstructorParameters<typeof Client>[0],
655
+ handlers: ConstructorParameters<typeof Client>[1],
656
+ plugins: ConstructorParameters<typeof Client>[2],
657
+ ) => Client,
658
+ ) {
659
+ createClientForTesting = mock;
660
+ },
661
+ setGetPluginCommandSpecs(mock?: GetPluginCommandSpecs) {
662
+ getPluginCommandSpecsForTesting = mock;
663
+ },
664
+ setResolveDiscordAccount(mock?: typeof resolveDiscordAccount) {
665
+ resolveDiscordAccountForTesting = mock;
666
+ },
667
+ setResolveNativeCommandsEnabled(mock?: typeof resolveNativeCommandsEnabled) {
668
+ resolveNativeCommandsEnabledForTesting = mock;
669
+ },
670
+ setResolveNativeSkillsEnabled(mock?: typeof resolveNativeSkillsEnabled) {
671
+ resolveNativeSkillsEnabledForTesting = mock;
672
+ },
673
+ setListNativeCommandSpecsForConfig(mock?: typeof listNativeCommandSpecsForConfig) {
674
+ listNativeCommandSpecsForConfigForTesting = mock;
675
+ },
676
+ setListSkillCommandsForAgents(mock?: typeof listSkillCommandsForAgents) {
677
+ listSkillCommandsForAgentsForTesting = mock;
678
+ },
679
+ setIsVerbose(mock?: typeof isVerbose) {
680
+ isVerboseForTesting = mock;
681
+ },
682
+ setShouldLogVerbose(mock?: typeof shouldLogVerbose) {
683
+ shouldLogVerboseForTesting = mock;
684
+ },
685
+ };
686
+
687
+ export const resolveDiscordRuntimeGroupPolicy = resolveOpenProviderRuntimeGroupPolicy;
688
+ export { testing as __testing };