@openclaw/discord 2026.6.11 → 2026.6.34

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 (152) hide show
  1. package/dist/action-runtime-api.js +1 -1
  2. package/dist/{api-4GFMoWu0.js → api-CjnGBhM3.js} +4 -1
  3. package/dist/api.js +14 -14
  4. package/dist/{approval-handler.runtime-SsFtZQA6.js → approval-handler.runtime-BWPQrzpP.js} +9 -4
  5. package/dist/{audit-CAnmyf2A.js → audit-BwJ_2OjL.js} +3 -3
  6. package/dist/{channel-YA7AbYP3.js → channel-DU4jnQgl.js} +15 -15
  7. package/dist/{channel-actions-BJ3n5Z1l.js → channel-actions-CwmIqnYN.js} +2 -2
  8. package/dist/{channel-actions.runtime-D2QTRgZ9.js → channel-actions.runtime-DvpTfaJ4.js} +5 -5
  9. package/dist/channel-plugin-api.js +1 -1
  10. package/dist/{channel.setup-B1zDEAR7.js → channel.setup-glZ5Y98a.js} +2 -2
  11. package/dist/{components-Dm4c_ce6.js → components-j6lTZBsT.js} +1 -1
  12. package/dist/{conversation-identity-DZ0BD7xO.js → conversation-identity-36FFBwm5.js} +2 -2
  13. package/dist/{directory-config-BK1OhHa3.js → directory-config-BYMFzL29.js} +1 -1
  14. package/dist/directory-contract-api.js +1 -1
  15. package/dist/{directory-live-DP3CmwGf.js → directory-live-9JtJCiu8.js} +2 -2
  16. package/dist/{handle-action.guild-admin-B2cOoU2D.js → handle-action.guild-admin-xxGYrp-I.js} +2 -2
  17. package/dist/index.js +1 -1
  18. package/dist/{manager.runtime-CPHxr9B3.js → manager.runtime-NxCd-PVt.js} +3 -3
  19. package/dist/{message-handler-CKaTgBIV.js → message-handler-cizxbaDc.js} +7 -6
  20. package/dist/{message-handler.preflight--eAiaewz.js → message-handler.preflight-CbD0u7U7.js} +10 -10
  21. package/dist/{message-handler.process-PhKAmrEd.js → message-handler.process-Do4EM591.js} +10 -10
  22. package/dist/{message-utils-O1vK3kPu.js → message-utils-CJeAoISH.js} +1 -1
  23. package/dist/{outbound-adapter-fO_7hbTh.js → outbound-adapter-Dxs6iKEq.js} +62 -131
  24. package/dist/{pluralkit-B3MzPaPU.js → pluralkit-DI6RYaVj.js} +1 -1
  25. package/dist/presence-cache-z1N8MbJ3.js +45 -0
  26. package/dist/{probe-CxnDikWm.js → probe-esE_Oqdm.js} +1 -1
  27. package/dist/{probe.runtime-DLFkSDVB.js → probe.runtime-C3Atgpvr.js} +1 -1
  28. package/dist/{provider-BJaJ20MY.js → provider-B-s93q9s.js} +76 -26
  29. package/dist/{provider-session.runtime-D6xc-60s.js → provider-session.runtime-BKMOqHpd.js} +3 -3
  30. package/dist/provider.runtime-CaTJrpnl.js +2 -0
  31. package/dist/{resolve-allowlist-common-BDpBb8dF.js → resolve-allowlist-common-3gB2Gpmm.js} +1 -1
  32. package/dist/{resolve-channels-iJIjYfRw.js → resolve-channels-B3gQf8QL.js} +3 -3
  33. package/dist/{resolve-users-_fv1mm1f.js → resolve-users-BO10y5fJ.js} +3 -3
  34. package/dist/{runtime-ywXByivr.js → runtime-CFlR3L9X.js} +8 -8
  35. package/dist/runtime-api.actions.js +2 -2
  36. package/dist/runtime-api.js +20 -20
  37. package/dist/runtime-api.lookup.js +5 -5
  38. package/dist/runtime-api.monitor-CRiBIQEI.js +6 -0
  39. package/dist/runtime-api.monitor.js +6 -5
  40. package/dist/runtime-api.send.js +5 -5
  41. package/dist/runtime-api.threads.js +3 -3
  42. package/dist/{send-Dc5uQX5H.js → send-JHxfT4Pk.js} +6 -4
  43. package/dist/{send.components-D4bl20xr.js → send.components-CN35E2Ck.js} +11 -6
  44. package/dist/{send.outbound-5axvwLkl.js → send.outbound-B-cA1Esv.js} +15 -8
  45. package/dist/{send.receipt-B21MspvT.js → send.receipt-CGecJDin.js} +10 -1
  46. package/dist/{send.shared-9082A2sO.js → send.shared-vcbfThdy.js} +107 -16
  47. package/dist/session-binding-contract-api.js +1 -1
  48. package/dist/setup-plugin-api.js +1 -1
  49. package/dist/{subagent-hooks-NTv6B4up.js → subagent-hooks-20wXhVzZ.js} +2 -2
  50. package/dist/subagent-hooks-api.js +1 -1
  51. package/dist/{system-events-BzaI1WpN.js → system-events-DR27TE7p.js} +1 -1
  52. package/dist/{target-resolver-agnOrtOU.js → target-resolver-CDi1gI90.js} +2 -2
  53. package/dist/targets-C6yd3y8R.js +3 -0
  54. package/dist/{thread-bindings-DNitaHVh.js → thread-bindings-DU4T6nDo.js} +4 -4
  55. package/dist/{thread-bindings.discord-api-CjYNuvZa.js → thread-bindings.discord-api-CYkr-3Gj.js} +4 -4
  56. package/dist/{thread-bindings.manager-PZvJ4TJx.js → thread-bindings.manager-BqWs1UE2.js} +3 -3
  57. package/dist/{transcripts-source-Bi8N6h5X.js → transcripts-source-D-lBI5ZD.js} +1 -1
  58. package/dist/transcripts-source-api.js +1 -1
  59. package/dist/{typing-BdRqXUN3.js → typing-xr05bL-r.js} +1 -1
  60. package/node_modules/undici/README.md +8 -2
  61. package/node_modules/undici/docs/docs/api/Agent.md +248 -44
  62. package/node_modules/undici/docs/docs/api/BalancedPool.md +246 -48
  63. package/node_modules/undici/docs/docs/api/CacheStorage.md +171 -13
  64. package/node_modules/undici/docs/docs/api/CacheStore.md +294 -98
  65. package/node_modules/undici/docs/docs/api/Client.md +369 -179
  66. package/node_modules/undici/docs/docs/api/ClientStats.md +80 -14
  67. package/node_modules/undici/docs/docs/api/Connector.md +118 -36
  68. package/node_modules/undici/docs/docs/api/ContentType.md +65 -25
  69. package/node_modules/undici/docs/docs/api/Cookies.md +122 -71
  70. package/node_modules/undici/docs/docs/api/Debug.md +34 -18
  71. package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +364 -164
  72. package/node_modules/undici/docs/docs/api/Dispatcher.md +485 -1102
  73. package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +101 -87
  74. package/node_modules/undici/docs/docs/api/Errors.md +503 -40
  75. package/node_modules/undici/docs/docs/api/EventSource.md +294 -32
  76. package/node_modules/undici/docs/docs/api/Fetch.md +680 -31
  77. package/node_modules/undici/docs/docs/api/GlobalInstallation.md +78 -98
  78. package/node_modules/undici/docs/docs/api/H2CClient.md +298 -176
  79. package/node_modules/undici/docs/docs/api/Interceptors.md +414 -0
  80. package/node_modules/undici/docs/docs/api/MockAgent.md +333 -314
  81. package/node_modules/undici/docs/docs/api/MockCallHistory.md +272 -98
  82. package/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +189 -26
  83. package/node_modules/undici/docs/docs/api/MockClient.md +151 -33
  84. package/node_modules/undici/docs/docs/api/MockErrors.md +56 -5
  85. package/node_modules/undici/docs/docs/api/MockPool.md +321 -258
  86. package/node_modules/undici/docs/docs/api/Pool.md +235 -43
  87. package/node_modules/undici/docs/docs/api/PoolStats.md +119 -13
  88. package/node_modules/undici/docs/docs/api/ProxyAgent.md +179 -160
  89. package/node_modules/undici/docs/docs/api/RedirectHandler.md +238 -63
  90. package/node_modules/undici/docs/docs/api/RetryAgent.md +113 -26
  91. package/node_modules/undici/docs/docs/api/RetryHandler.md +161 -77
  92. package/node_modules/undici/docs/docs/api/RoundRobinPool.md +166 -72
  93. package/node_modules/undici/docs/docs/api/SnapshotAgent.md +264 -542
  94. package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +162 -187
  95. package/node_modules/undici/docs/docs/api/Util.md +68 -11
  96. package/node_modules/undici/docs/docs/api/WebSocket.md +475 -80
  97. package/node_modules/undici/docs/docs/api/api-lifecycle.md +100 -32
  98. package/node_modules/undici/docs/docs/best-practices/client-certificate.md +2 -0
  99. package/node_modules/undici/docs/docs/best-practices/crawling.md +3 -1
  100. package/node_modules/undici/docs/docs/best-practices/migrating-from-v7-to-v8.md +6 -4
  101. package/node_modules/undici/docs/docs/best-practices/mocking-request.md +9 -7
  102. package/node_modules/undici/docs/docs/best-practices/proxy.md +3 -1
  103. package/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +10 -8
  104. package/node_modules/undici/docs/docs/best-practices/writing-tests.md +2 -0
  105. package/node_modules/undici/docs/docs/{GettingStarted.md → getting-started.md} +22 -19
  106. package/node_modules/undici/docs/docs/index.md +784 -0
  107. package/node_modules/undici/docs/docs/site.json +125 -0
  108. package/node_modules/undici/docs/docs/type-map.json +79 -0
  109. package/node_modules/undici/lib/api/api-request.js +7 -1
  110. package/node_modules/undici/lib/api/readable.js +47 -2
  111. package/node_modules/undici/lib/cache/memory-cache-store.js +54 -9
  112. package/node_modules/undici/lib/cache/sqlite-cache-store.js +7 -1
  113. package/node_modules/undici/lib/core/errors.js +20 -0
  114. package/node_modules/undici/lib/core/request.js +14 -3
  115. package/node_modules/undici/lib/core/util.js +30 -2
  116. package/node_modules/undici/lib/dispatcher/agent.js +3 -3
  117. package/node_modules/undici/lib/dispatcher/client-h1.js +65 -8
  118. package/node_modules/undici/lib/dispatcher/client-h2.js +265 -142
  119. package/node_modules/undici/lib/dispatcher/proxy-agent.js +40 -6
  120. package/node_modules/undici/lib/global.js +36 -16
  121. package/node_modules/undici/lib/handler/cache-handler.js +269 -61
  122. package/node_modules/undici/lib/handler/cache-revalidation-handler.js +13 -3
  123. package/node_modules/undici/lib/handler/redirect-handler.js +6 -2
  124. package/node_modules/undici/lib/handler/retry-handler.js +87 -23
  125. package/node_modules/undici/lib/interceptor/cache.js +159 -52
  126. package/node_modules/undici/lib/interceptor/decompress.js +9 -2
  127. package/node_modules/undici/lib/mock/mock-interceptor.js +25 -7
  128. package/node_modules/undici/lib/mock/mock-utils.js +39 -10
  129. package/node_modules/undici/lib/util/cache.js +372 -68
  130. package/node_modules/undici/lib/util/date.js +23 -6
  131. package/node_modules/undici/lib/web/cookies/parse.js +3 -2
  132. package/node_modules/undici/lib/web/cookies/util.js +79 -9
  133. package/node_modules/undici/lib/web/eventsource/util.js +1 -1
  134. package/node_modules/undici/lib/web/fetch/body.js +2 -1
  135. package/node_modules/undici/lib/web/fetch/constants.js +1 -1
  136. package/node_modules/undici/lib/web/fetch/index.js +11 -2
  137. package/node_modules/undici/lib/web/fetch/response.js +1 -3
  138. package/node_modules/undici/lib/web/fetch/util.js +4 -1
  139. package/node_modules/undici/package.json +2 -2
  140. package/node_modules/undici/types/client.d.ts +3 -3
  141. package/node_modules/undici/types/cookies.d.ts +1 -1
  142. package/node_modules/undici/types/dispatcher.d.ts +3 -3
  143. package/node_modules/undici/types/errors.d.ts +10 -0
  144. package/node_modules/undici/types/handlers.d.ts +2 -0
  145. package/node_modules/undici/types/mock-interceptor.d.ts +5 -1
  146. package/node_modules/undici/types/proxy-agent.d.ts +7 -0
  147. package/npm-shrinkwrap.json +7 -7
  148. package/package.json +5 -5
  149. package/dist/gateway-registry-DPxmW0Db.js +0 -74
  150. package/dist/provider.runtime-jNlHxUSW.js +0 -2
  151. package/dist/runtime-api.monitor-Bb5AaRzg.js +0 -6
  152. package/dist/targets-ClUPljCU.js +0 -3
@@ -1,46 +1,10 @@
1
- import { o as normalizeDiscordOutboundTarget, s as chunkDiscordTextWithMode, t as createDiscordSendReceipt, x as DiscordError } from "./send.receipt-B21MspvT.js";
2
- import { s as resolveDiscordAccount } from "./accounts-P19jm1lf.js";
3
- import { d as readDiscordComponentSpec } from "./components-Dm4c_ce6.js";
4
- import { t as parseDiscordRetryAfterBodySeconds } from "./retry-after-D5_VmM-_.js";
1
+ import { o as normalizeDiscordOutboundTarget, s as chunkDiscordTextWithMode, t as createDiscordSendReceipt } from "./send.receipt-CGecJDin.js";
2
+ import { d as readDiscordComponentSpec } from "./components-j6lTZBsT.js";
5
3
  import { n as notifyDiscordInboundEventOutboundPayloadSuccess } from "./inbound-event-delivery-CEPlt2uz.js";
6
4
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
7
5
  import { resolvePayloadMediaUrls, sendPayloadMediaSequenceOrFallback, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
8
- import { resolveRetryConfig, retryAsync } from "openclaw/plugin-sdk/retry-runtime";
9
6
  import { createReplyToFanout, resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-outbound";
10
7
  import { attachChannelToResult, createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
11
- //#region extensions/discord/src/delivery-retry.ts
12
- const DISCORD_DELIVERY_RETRY_DEFAULTS = {
13
- attempts: 3,
14
- minDelayMs: 1e3,
15
- maxDelayMs: 3e4,
16
- jitter: 0
17
- };
18
- function isRetryableDiscordDeliveryError(err) {
19
- if (err instanceof DiscordError) return false;
20
- const status = err.status ?? err.statusCode;
21
- return status === 429 || status !== void 0 && status >= 500;
22
- }
23
- function getDiscordDeliveryRetryAfterMs(err) {
24
- if (!err || typeof err !== "object") return;
25
- const retryAfterSeconds = "retryAfter" in err ? parseDiscordRetryAfterBodySeconds(err.retryAfter) : void 0;
26
- if (retryAfterSeconds !== void 0) return retryAfterSeconds * 1e3;
27
- const retryAfterRaw = err.headers?.["retry-after"];
28
- if (!retryAfterRaw) return;
29
- const headerSeconds = parseDiscordRetryAfterBodySeconds(retryAfterRaw);
30
- return headerSeconds === void 0 ? void 0 : headerSeconds * 1e3;
31
- }
32
- async function withDiscordDeliveryRetry(params) {
33
- const retryConfig = resolveRetryConfig(DISCORD_DELIVERY_RETRY_DEFAULTS, resolveDiscordAccount({
34
- cfg: params.cfg,
35
- accountId: params.accountId
36
- }).config.retry);
37
- return await retryAsync(params.fn, {
38
- ...retryConfig,
39
- shouldRetry: (err) => isRetryableDiscordDeliveryError(err),
40
- retryAfterMs: getDiscordDeliveryRetryAfterMs
41
- });
42
- }
43
- //#endregion
44
8
  //#region extensions/discord/src/media-detection.ts
45
9
  const DISCORD_VIDEO_MEDIA_EXTENSIONS = new Set([
46
10
  ".avi",
@@ -86,11 +50,11 @@ function normalizeDiscordApprovalPayload(payload) {
86
50
  let discordComponentSendPromise;
87
51
  let discordSharedInteractivePromise;
88
52
  async function sendDiscordComponentMessageLazy(...args) {
89
- discordComponentSendPromise ??= import("./send.components-D4bl20xr.js").then((n) => n.i).then((module) => module.sendDiscordComponentMessage);
53
+ discordComponentSendPromise ??= import("./send.components-CN35E2Ck.js").then((n) => n.i).then((module) => module.sendDiscordComponentMessage);
90
54
  return await (await discordComponentSendPromise)(...args);
91
55
  }
92
56
  function loadDiscordSharedInteractive() {
93
- discordSharedInteractivePromise ??= import("./components-Dm4c_ce6.js").then((n) => n.a);
57
+ discordSharedInteractivePromise ??= import("./components-j6lTZBsT.js").then((n) => n.a);
94
58
  return discordSharedInteractivePromise;
95
59
  }
96
60
  function addPayloadTextFallback(spec, payload) {
@@ -125,7 +89,7 @@ async function resolveDiscordComponentSpec(payload) {
125
89
  //#region extensions/discord/src/outbound-send-context.ts
126
90
  let discordSendRuntimePromise;
127
91
  async function loadDiscordSendRuntime() {
128
- discordSendRuntimePromise ??= import("./send-Dc5uQX5H.js").then((n) => n.t);
92
+ discordSendRuntimePromise ??= import("./send-JHxfT4Pk.js").then((n) => n.t);
129
93
  return await discordSendRuntimePromise;
130
94
  }
131
95
  function resolveDiscordOutboundTarget(params) {
@@ -157,12 +121,7 @@ async function createDiscordPayloadSendContext(ctx) {
157
121
  replyToMode: ctx.replyToMode
158
122
  }),
159
123
  send: resolveOutboundSendDep(ctx.deps, "discord") ?? runtime.sendMessageDiscord,
160
- sendVoice: resolveOutboundSendDep(ctx.deps, "discordVoice") ?? runtime.sendVoiceMessageDiscord,
161
- withRetry: async (fn) => await withDiscordDeliveryRetry({
162
- cfg: ctx.cfg,
163
- accountId: ctx.accountId,
164
- fn
165
- })
124
+ sendVoice: resolveOutboundSendDep(ctx.deps, "discordVoice") ?? runtime.sendVoiceMessageDiscord
166
125
  };
167
126
  }
168
127
  //#endregion
@@ -210,15 +169,15 @@ async function sendDiscordOutboundPayload(params) {
210
169
  const mediaUrls = resolvePayloadMediaUrls(payload);
211
170
  const sendContext = await createDiscordPayloadSendContext(ctx);
212
171
  if (payload.audioAsVoice && mediaUrls.length > 0) {
213
- let lastResult = await sendContext.withRetry(async () => await sendContext.sendVoice(sendContext.target, mediaUrls[0], resolveDiscordDeliveryOptions(ctx, sendContext)));
214
- if (payload.text?.trim()) lastResult = await sendContext.withRetry(async () => await sendContext.send(sendContext.target, payload.text, {
172
+ let lastResult = await sendContext.sendVoice(sendContext.target, mediaUrls[0], resolveDiscordDeliveryOptions(ctx, sendContext));
173
+ if (payload.text?.trim()) lastResult = await sendContext.send(sendContext.target, payload.text, {
215
174
  verbose: false,
216
175
  ...resolveDiscordFormattedDeliveryOptions(ctx, sendContext)
217
- }));
218
- for (const mediaUrl of mediaUrls.slice(1)) lastResult = await sendContext.withRetry(async () => await sendContext.send(sendContext.target, "", {
176
+ });
177
+ for (const mediaUrl of mediaUrls.slice(1)) lastResult = await sendContext.send(sendContext.target, "", {
219
178
  verbose: false,
220
179
  ...resolveDiscordMediaDeliveryOptions(ctx, sendContext, mediaUrl)
221
- }));
180
+ });
222
181
  return attachChannelToResult("discord", lastResult);
223
182
  }
224
183
  const componentSpec = await resolveDiscordComponentSpec(payload);
@@ -231,20 +190,20 @@ async function sendDiscordOutboundPayload(params) {
231
190
  text: payload.text ?? "",
232
191
  mediaUrls,
233
192
  fallbackResult: createDiscordUnknownPayloadResult(sendContext.target),
234
- sendNoMedia: async () => await sendContext.withRetry(async () => await sendContext.send(sendContext.target, payload.text ?? "", {
193
+ sendNoMedia: async () => await sendContext.send(sendContext.target, payload.text ?? "", {
235
194
  verbose: false,
236
195
  components: nativeComponents,
237
196
  embeds,
238
197
  filename,
239
198
  ...resolveDiscordFormattedDeliveryOptions(ctx, sendContext)
240
- })),
241
- send: async ({ text, mediaUrl, isFirst }) => await sendContext.withRetry(async () => await sendContext.send(sendContext.target, text, {
199
+ }),
200
+ send: async ({ text, mediaUrl, isFirst }) => await sendContext.send(sendContext.target, text, {
242
201
  verbose: false,
243
202
  ...resolveDiscordMediaDeliveryOptions(ctx, sendContext, mediaUrl),
244
203
  components: isFirst ? nativeComponents : void 0,
245
204
  embeds: isFirst ? embeds : void 0,
246
205
  filename: isFirst ? filename : void 0
247
- }))
206
+ })
248
207
  }));
249
208
  return await sendTextMediaPayload({
250
209
  channel: "discord",
@@ -259,13 +218,13 @@ async function sendDiscordOutboundPayload(params) {
259
218
  text: payload.text ?? "",
260
219
  mediaUrls,
261
220
  fallbackResult: createDiscordUnknownPayloadResult(sendContext.target),
262
- sendNoMedia: async () => await sendContext.withRetry(async () => await sendDiscordComponentMessageLazy(sendContext.target, componentSpec, { ...resolveDiscordFormattedDeliveryOptions(ctx, sendContext) })),
221
+ sendNoMedia: async () => await sendDiscordComponentMessageLazy(sendContext.target, componentSpec, { ...resolveDiscordFormattedDeliveryOptions(ctx, sendContext) }),
263
222
  send: async ({ text, mediaUrl, isFirst }) => {
264
- if (isFirst) return await sendContext.withRetry(async () => await sendDiscordComponentMessageLazy(sendContext.target, componentSpec, { ...resolveDiscordMediaDeliveryOptions(ctx, sendContext, mediaUrl) }));
265
- return await sendContext.withRetry(async () => await sendContext.send(sendContext.target, text, {
223
+ if (isFirst) return await sendDiscordComponentMessageLazy(sendContext.target, componentSpec, { ...resolveDiscordMediaDeliveryOptions(ctx, sendContext, mediaUrl) });
224
+ return await sendContext.send(sendContext.target, text, {
266
225
  verbose: false,
267
226
  ...resolveDiscordMediaDeliveryOptions(ctx, sendContext, mediaUrl)
268
- }));
227
+ });
269
228
  }
270
229
  }));
271
230
  }
@@ -280,7 +239,7 @@ function stripDiscordInternalRuntimeScaffolding(text) {
280
239
  }
281
240
  let discordThreadBindingsPromise;
282
241
  function loadDiscordThreadBindings() {
283
- discordThreadBindingsPromise ??= import("./thread-bindings-DNitaHVh.js").then((n) => n.t);
242
+ discordThreadBindingsPromise ??= import("./thread-bindings-DU4T6nDo.js").then((n) => n.t);
284
243
  return discordThreadBindingsPromise;
285
244
  }
286
245
  function resolveDiscordWebhookIdentity(params) {
@@ -387,21 +346,16 @@ const discordOutbound = {
387
346
  }).catch(() => null);
388
347
  if (webhookResult) return webhookResult;
389
348
  }
390
- const send = resolveOutboundSendDep(deps, "discord") ?? (await loadDiscordSendRuntime()).sendMessageDiscord;
391
- return await withDiscordDeliveryRetry({
349
+ return await (resolveOutboundSendDep(deps, "discord") ?? (await loadDiscordSendRuntime()).sendMessageDiscord)(resolveDiscordOutboundTarget({
350
+ to,
351
+ threadId
352
+ }), text, {
353
+ verbose: false,
354
+ replyTo: replyToId ?? void 0,
355
+ accountId: accountId ?? void 0,
356
+ silent: silent ?? void 0,
392
357
  cfg,
393
- accountId,
394
- fn: async () => await send(resolveDiscordOutboundTarget({
395
- to,
396
- threadId
397
- }), text, {
398
- verbose: false,
399
- replyTo: replyToId ?? void 0,
400
- accountId: accountId ?? void 0,
401
- silent: silent ?? void 0,
402
- cfg,
403
- ...resolveDiscordFormattingOptions({ formatting })
404
- })
358
+ ...resolveDiscordFormattingOptions({ formatting })
405
359
  });
406
360
  },
407
361
  sendMedia: async ({ cfg, to, text, mediaUrl, audioAsVoice, mediaAccess, mediaLocalRoots, mediaReadFile, accountId, deps, replyToId, threadId, silent, formatting }) => {
@@ -411,76 +365,53 @@ const discordOutbound = {
411
365
  threadId
412
366
  });
413
367
  const formattingOptions = resolveDiscordFormattingOptions({ formatting });
414
- if (audioAsVoice && mediaUrl) {
415
- const sendVoice = resolveOutboundSendDep(deps, "discordVoice") ?? (await loadDiscordSendRuntime()).sendVoiceMessageDiscord;
416
- return await withDiscordDeliveryRetry({
417
- cfg,
418
- accountId,
419
- fn: async () => await sendVoice(target, mediaUrl, {
420
- cfg,
421
- replyTo: replyToId ?? void 0,
422
- accountId: accountId ?? void 0,
423
- silent: silent ?? void 0
424
- })
425
- });
426
- }
368
+ if (audioAsVoice && mediaUrl) return await (resolveOutboundSendDep(deps, "discordVoice") ?? (await loadDiscordSendRuntime()).sendVoiceMessageDiscord)(target, mediaUrl, {
369
+ cfg,
370
+ replyTo: replyToId ?? void 0,
371
+ accountId: accountId ?? void 0,
372
+ silent: silent ?? void 0
373
+ });
427
374
  if (text.trim() && mediaUrl && isLikelyDiscordVideoMedia(mediaUrl)) {
428
- await withDiscordDeliveryRetry({
429
- cfg,
430
- accountId,
431
- fn: async () => await send(target, text, {
432
- verbose: false,
433
- replyTo: replyToId ?? void 0,
434
- accountId: accountId ?? void 0,
435
- silent: silent ?? void 0,
436
- cfg,
437
- ...formattingOptions
438
- })
439
- });
440
- return await withDiscordDeliveryRetry({
375
+ await send(target, text, {
376
+ verbose: false,
377
+ replyTo: replyToId ?? void 0,
378
+ accountId: accountId ?? void 0,
379
+ silent: silent ?? void 0,
441
380
  cfg,
442
- accountId,
443
- fn: async () => await send(target, "", {
444
- verbose: false,
445
- mediaUrl,
446
- mediaAccess,
447
- mediaLocalRoots,
448
- mediaReadFile,
449
- accountId: accountId ?? void 0,
450
- silent: silent ?? void 0,
451
- cfg,
452
- ...formattingOptions
453
- })
381
+ ...formattingOptions
454
382
  });
455
- }
456
- return await withDiscordDeliveryRetry({
457
- cfg,
458
- accountId,
459
- fn: async () => await send(target, text, {
383
+ return await send(target, "", {
460
384
  verbose: false,
461
385
  mediaUrl,
462
386
  mediaAccess,
463
387
  mediaLocalRoots,
464
388
  mediaReadFile,
465
- replyTo: replyToId ?? void 0,
466
389
  accountId: accountId ?? void 0,
467
390
  silent: silent ?? void 0,
468
391
  cfg,
469
392
  ...formattingOptions
470
- })
471
- });
472
- },
473
- sendPoll: async ({ cfg, to, poll, accountId, threadId, silent }) => await withDiscordDeliveryRetry({
474
- cfg,
475
- accountId,
476
- fn: async () => await (await loadDiscordSendRuntime()).sendPollDiscord(resolveDiscordOutboundTarget({
477
- to,
478
- threadId
479
- }), poll, {
393
+ });
394
+ }
395
+ return await send(target, text, {
396
+ verbose: false,
397
+ mediaUrl,
398
+ mediaAccess,
399
+ mediaLocalRoots,
400
+ mediaReadFile,
401
+ replyTo: replyToId ?? void 0,
480
402
  accountId: accountId ?? void 0,
481
403
  silent: silent ?? void 0,
482
- cfg
483
- })
404
+ cfg,
405
+ ...formattingOptions
406
+ });
407
+ },
408
+ sendPoll: async ({ cfg, to, poll, accountId, threadId, silent }) => await (await loadDiscordSendRuntime()).sendPollDiscord(resolveDiscordOutboundTarget({
409
+ to,
410
+ threadId
411
+ }), poll, {
412
+ accountId: accountId ?? void 0,
413
+ silent: silent ?? void 0,
414
+ cfg
484
415
  })
485
416
  }),
486
417
  afterDeliverPayload: async ({ target, payload }) => {
@@ -1,4 +1,4 @@
1
- import { Wt as __exportAll } from "./send.receipt-B21MspvT.js";
1
+ import { Wt as __exportAll } from "./send.receipt-CGecJDin.js";
2
2
  import { resolveFetch } from "openclaw/plugin-sdk/fetch-runtime";
3
3
  import { readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
4
4
  //#region extensions/discord/src/pluralkit.ts
@@ -0,0 +1,45 @@
1
+ //#region extensions/discord/src/monitor/presence-cache.ts
2
+ /**
3
+ * In-memory cache of Discord user presence data.
4
+ * Populated by PRESENCE_UPDATE gateway events when the GuildPresences intent is enabled.
5
+ * Per-account maps are capped to prevent unbounded growth (#4948).
6
+ */
7
+ const MAX_PRESENCE_PER_ACCOUNT = 5e3;
8
+ const presenceCache = /* @__PURE__ */ new Map();
9
+ function resolveAccountKey(accountId) {
10
+ return accountId ?? "default";
11
+ }
12
+ /** Update cached presence for a user. */
13
+ function setPresence(accountId, userId, data) {
14
+ const accountKey = resolveAccountKey(accountId);
15
+ let accountCache = presenceCache.get(accountKey);
16
+ if (!accountCache) {
17
+ accountCache = /* @__PURE__ */ new Map();
18
+ presenceCache.set(accountKey, accountCache);
19
+ }
20
+ accountCache.set(userId, data);
21
+ if (accountCache.size > MAX_PRESENCE_PER_ACCOUNT) {
22
+ const oldest = accountCache.keys().next().value;
23
+ if (oldest !== void 0) accountCache.delete(oldest);
24
+ }
25
+ }
26
+ /** Get cached presence for a user. Returns undefined if not cached. */
27
+ function getPresence(accountId, userId) {
28
+ return presenceCache.get(resolveAccountKey(accountId))?.get(userId);
29
+ }
30
+ /** Clear cached presence data. */
31
+ function clearPresences(accountId) {
32
+ if (accountId) {
33
+ presenceCache.delete(resolveAccountKey(accountId));
34
+ return;
35
+ }
36
+ presenceCache.clear();
37
+ }
38
+ /** Get the number of cached presence entries. */
39
+ function presenceCacheSize() {
40
+ let total = 0;
41
+ for (const accountCache of presenceCache.values()) total += accountCache.size;
42
+ return total;
43
+ }
44
+ //#endregion
45
+ export { setPresence as i, getPresence as n, presenceCacheSize as r, clearPresences as t };
@@ -1,5 +1,5 @@
1
1
  import { p as normalizeDiscordToken } from "./accounts-P19jm1lf.js";
2
- import { n as fetchDiscord, t as DiscordApiError } from "./api-4GFMoWu0.js";
2
+ import { n as fetchDiscord, t as DiscordApiError } from "./api-CjnGBhM3.js";
3
3
  import { resolveFetch } from "openclaw/plugin-sdk/fetch-runtime";
4
4
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
5
5
  import { fetchWithTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
@@ -1,2 +1,2 @@
1
- import { a as resolveDiscordPrivilegedIntentsFromFlags, i as probeDiscord, n as fetchDiscordApplicationSummary, r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-CxnDikWm.js";
1
+ import { a as resolveDiscordPrivilegedIntentsFromFlags, i as probeDiscord, n as fetchDiscordApplicationSummary, r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-esE_Oqdm.js";
2
2
  export { fetchDiscordApplicationId, fetchDiscordApplicationSummary, parseApplicationIdFromToken, probeDiscord, resolveDiscordPrivilegedIntentsFromFlags };
@@ -1,23 +1,23 @@
1
- import { $ as BaseMessageInteractiveComponent, A as User, B as Container, D as CommandWithSubcommands, E as Command, F as Modal, J as Separator, K as Row, O as Guild, R as Button, S as RateLimitError, Wt as __exportAll, X as TextDisplay, Y as StringSelectMenu, c as discord_exports, ct as createThread, d as MessageReactionAddListener, dt as editChannel, f as MessageReactionRemoveListener, g as ThreadUpdateListener, k as Message, l as InteractionCreateListener, m as ReadyListener, mt as getChannelMessage, p as PresenceUpdateListener, s as chunkDiscordTextWithMode, u as MessageCreateListener, v as Client, y as Plugin } from "./send.receipt-B21MspvT.js";
1
+ import { $ as BaseMessageInteractiveComponent, A as User, B as Container, D as CommandWithSubcommands, E as Command, F as Modal, J as Separator, K as Row, O as Guild, R as Button, S as RateLimitError, Wt as __exportAll, X as TextDisplay, Y as StringSelectMenu, c as discord_exports, ct as createThread, d as MessageReactionAddListener, dt as editChannel, f as MessageReactionRemoveListener, g as ThreadUpdateListener, k as Message, l as InteractionCreateListener, m as ReadyListener, mt as getChannelMessage, p as PresenceUpdateListener, s as chunkDiscordTextWithMode, u as MessageCreateListener, v as Client, y as Plugin } from "./send.receipt-CGecJDin.js";
2
2
  import { c as resolveDiscordAccountAllowFrom, d as resolveDiscordAccountDmPolicy, f as resolveDiscordMaxLinesPerMessage, p as normalizeDiscordToken, s as resolveDiscordAccount } from "./accounts-P19jm1lf.js";
3
- import { _ as parseDiscordComponentCustomId, b as parseDiscordModalCustomIdForInteraction, v as parseDiscordComponentCustomIdForInteraction, y as parseDiscordModalCustomId } from "./components-Dm4c_ce6.js";
4
- import { a as resolveDiscordComponentEntryWithPersistence, o as resolveDiscordModalEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-D4bl20xr.js";
5
- import { c as setPresence, i as unregisterGateway, r as registerGateway } from "./gateway-registry-DPxmW0Db.js";
6
- import { B as DISCORD_REST_TIMEOUT_MS, D as canViewDiscordGuildChannel, H as withValidatedDiscordProxy, I as createDiscordRestClient, V as validateDiscordProxyUrl } from "./send.shared-9082A2sO.js";
7
- import { a as summarizeDiscordResponseBody, i as isDiscordRateLimitResponseBody } from "./api-4GFMoWu0.js";
3
+ import { _ as parseDiscordComponentCustomId, b as parseDiscordModalCustomIdForInteraction, v as parseDiscordComponentCustomIdForInteraction, y as parseDiscordModalCustomId } from "./components-j6lTZBsT.js";
4
+ import { a as resolveDiscordComponentEntryWithPersistence, o as resolveDiscordModalEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-CN35E2Ck.js";
5
+ import { i as setPresence } from "./presence-cache-z1N8MbJ3.js";
6
+ import { H as validateDiscordProxyUrl, K as registerGateway, L as createDiscordRestClient, O as canViewDiscordGuildChannel, U as withValidatedDiscordProxy, V as DISCORD_REST_TIMEOUT_MS, q as unregisterGateway } from "./send.shared-vcbfThdy.js";
7
+ import { a as summarizeDiscordResponseBody, i as isDiscordRateLimitResponseBody } from "./api-CjnGBhM3.js";
8
8
  import { S as resolveTimestampMs, _ as resolveGroupDmAllow, a as normalizeDiscordSlug, b as formatDiscordUserTag, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordGuildEntry, f as resolveDiscordMemberAccessState, h as resolveDiscordOwnerAllowFrom, i as normalizeDiscordDisplaySlug, l as resolveDiscordChannelPolicyCommandAuthorizer, m as resolveDiscordOwnerAccess, n as isDiscordGroupAllowedByPolicy, o as resolveDiscordAllowListMatch, p as resolveDiscordMemberAllowed, r as normalizeDiscordAllowList, v as shouldEmitDiscordReactionNotification, y as formatDiscordReactionEmoji } from "./allow-list-C-MqM-B_.js";
9
- import { s as sendVoiceMessageDiscord } from "./send-Dc5uQX5H.js";
10
- import { o as formatMention, t as sendMessageDiscord } from "./send.outbound-5axvwLkl.js";
9
+ import { s as sendVoiceMessageDiscord } from "./send-JHxfT4Pk.js";
10
+ import { o as formatMention, t as sendMessageDiscord } from "./send.outbound-B-cA1Esv.js";
11
11
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
12
- import { a as getDiscordExecApprovalApprovers, s as isDiscordExecApprovalClientEnabled, t as resolveDiscordConversationIdentity } from "./conversation-identity-DZ0BD7xO.js";
12
+ import { a as getDiscordExecApprovalApprovers, s as isDiscordExecApprovalClientEnabled, t as resolveDiscordConversationIdentity } from "./conversation-identity-36FFBwm5.js";
13
13
  import { d as withAbortTimeout, l as raceWithTimeout } from "./timeouts-C5TBc_9x.js";
14
- import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-iJIjYfRw.js";
15
- import { t as resolveDiscordUserAllowlist } from "./resolve-users-_fv1mm1f.js";
16
- import { _ as formatThreadBindingDurationLabel, a as isThreadArchived, d as resolveDiscordChannelNameSafe, f as resolveDiscordChannelParentIdSafe, l as resolveDiscordChannelIdSafe, m as resolveDiscordChannelTopicSafe, p as resolveDiscordChannelParentSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-CjYNuvZa.js";
17
- import { r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-CxnDikWm.js";
18
- import { d as resolveDiscordMessageChannelId, n as resolveDiscordForwardedMessagesTextFromSnapshots, t as resolveDiscordEmbedText, u as resolveDiscordChannelInfo } from "./message-utils-O1vK3kPu.js";
14
+ import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-B3gQf8QL.js";
15
+ import { t as resolveDiscordUserAllowlist } from "./resolve-users-BO10y5fJ.js";
16
+ import { _ as formatThreadBindingDurationLabel, a as isThreadArchived, d as resolveDiscordChannelNameSafe, f as resolveDiscordChannelParentIdSafe, l as resolveDiscordChannelIdSafe, m as resolveDiscordChannelTopicSafe, p as resolveDiscordChannelParentSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-CYkr-3Gj.js";
17
+ import { r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-esE_Oqdm.js";
18
+ import { d as resolveDiscordMessageChannelId, n as resolveDiscordForwardedMessagesTextFromSnapshots, t as resolveDiscordEmbedText, u as resolveDiscordChannelInfo } from "./message-utils-CJeAoISH.js";
19
19
  import { t as resolveDiscordSenderIdentity } from "./sender-identity-CEsfDF0L.js";
20
- import "./approval-handler.runtime-SsFtZQA6.js";
20
+ import "./approval-handler.runtime-BWPQrzpP.js";
21
21
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
22
22
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, normalizeStringEntries, normalizeStringEntriesLower, summarizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
23
23
  import { buildAgentSessionKey, deriveLastRoutePolicy, isAcpSessionKey, isSubagentSessionKey, parseAgentSessionKey, resolveAgentIdFromSessionKey, resolveAgentRoute } from "openclaw/plugin-sdk/routing";
@@ -30,6 +30,7 @@ import { resolvePinnedMainDmOwnerFromAllowlist as resolvePinnedMainDmOwnerFromAl
30
30
  import { Type } from "typebox";
31
31
  import { Check, Errors } from "typebox/value";
32
32
  import { inspect } from "node:util";
33
+ import { readResponseWithLimit } from "openclaw/plugin-sdk/response-limit-runtime";
33
34
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
34
35
  import { resolveSendableOutboundReplyParts, resolveTextChunksWithFallback } from "openclaw/plugin-sdk/reply-payload";
35
36
  import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
@@ -4919,19 +4920,38 @@ var GatewayReconnectTimer = class {
4919
4920
  //#region extensions/discord/src/internal/gateway-rate-limit.ts
4920
4921
  const GATEWAY_SEND_LIMIT = 120;
4921
4922
  const GATEWAY_SEND_WINDOW_MS = 6e4;
4923
+ const GATEWAY_SEND_QUEUE_LIMIT = GATEWAY_SEND_LIMIT;
4922
4924
  var GatewaySendLimiter = class {
4923
- constructor(sendNow, emitError) {
4925
+ constructor(sendNow, emitError, emitOverflowWarning) {
4924
4926
  this.sendNow = sendNow;
4925
4927
  this.emitError = emitError;
4928
+ this.emitOverflowWarning = emitOverflowWarning;
4926
4929
  this.outboundSendTimestamps = [];
4927
4930
  this.outboundQueue = [];
4931
+ this.droppedEvents = 0;
4932
+ this.overflowWarningEmitted = false;
4928
4933
  }
4929
4934
  send(serialized, options) {
4930
4935
  if (options?.critical || this.canSend(Date.now())) {
4931
4936
  this.sendSerialized(serialized);
4932
4937
  return;
4933
4938
  }
4939
+ let shouldEmitOverflowWarning = false;
4940
+ if (this.outboundQueue.length >= GATEWAY_SEND_QUEUE_LIMIT) {
4941
+ this.outboundQueue.shift();
4942
+ this.droppedEvents += 1;
4943
+ if (!this.overflowWarningEmitted) {
4944
+ this.overflowWarningEmitted = true;
4945
+ shouldEmitOverflowWarning = true;
4946
+ }
4947
+ }
4934
4948
  this.outboundQueue.push({ payload: serialized });
4949
+ if (shouldEmitOverflowWarning) this.emitOverflowWarning({
4950
+ droppedEvents: this.droppedEvents,
4951
+ maxQueuedEvents: GATEWAY_SEND_QUEUE_LIMIT,
4952
+ policy: "drop-oldest",
4953
+ queuedEvents: this.outboundQueue.length
4954
+ });
4935
4955
  this.scheduleFlush();
4936
4956
  }
4937
4957
  clear() {
@@ -4940,6 +4960,8 @@ var GatewaySendLimiter = class {
4940
4960
  this.outboundFlushTimer = void 0;
4941
4961
  }
4942
4962
  this.outboundQueue = [];
4963
+ this.droppedEvents = 0;
4964
+ this.overflowWarningEmitted = false;
4943
4965
  }
4944
4966
  getStatus() {
4945
4967
  const now = Date.now();
@@ -4949,7 +4971,8 @@ var GatewaySendLimiter = class {
4949
4971
  remainingEvents: Math.max(0, GATEWAY_SEND_LIMIT - this.outboundSendTimestamps.length),
4950
4972
  resetTime: this.outboundSendTimestamps.length > 0 ? oldest + GATEWAY_SEND_WINDOW_MS : now + GATEWAY_SEND_WINDOW_MS,
4951
4973
  currentEventCount: this.outboundSendTimestamps.length,
4952
- queuedEvents: this.outboundQueue.length
4974
+ queuedEvents: this.outboundQueue.length,
4975
+ droppedEvents: this.droppedEvents
4953
4976
  };
4954
4977
  }
4955
4978
  pruneWindow(now) {
@@ -4988,6 +5011,7 @@ var GatewaySendLimiter = class {
4988
5011
  return;
4989
5012
  }
4990
5013
  }
5014
+ if (this.outboundQueue.length < GATEWAY_SEND_QUEUE_LIMIT) this.overflowWarningEmitted = false;
4991
5015
  this.scheduleFlush();
4992
5016
  }
4993
5017
  };
@@ -5029,7 +5053,7 @@ var GatewayPlugin = class extends Plugin {
5029
5053
  this.isConnecting = false;
5030
5054
  this.heartbeatTimers = new GatewayHeartbeatTimers();
5031
5055
  this.reconnectTimer = new GatewayReconnectTimer();
5032
- this.outboundLimiter = new GatewaySendLimiter((payload) => this.sendSerializedGatewayEvent(payload), (error) => this.emitter.emit("error", error));
5056
+ this.outboundLimiter = new GatewaySendLimiter((payload) => this.sendSerializedGatewayEvent(payload), (error) => this.emitter.emit("error", error), (warning) => this.emitter.emit("warning", `Gateway outbound queue overflow policy=${warning.policy} droppedEvents=${warning.droppedEvents} queuedEvents=${warning.queuedEvents} maxQueuedEvents=${warning.maxQueuedEvents}`));
5033
5057
  this.options = {
5034
5058
  ...options,
5035
5059
  reconnect: {
@@ -5602,6 +5626,7 @@ const DEFAULT_DISCORD_GATEWAY_URL = "wss://gateway.discord.gg/";
5602
5626
  const DEFAULT_DISCORD_GATEWAY_INFO_TIMEOUT_MS = 3e4;
5603
5627
  const MAX_DISCORD_GATEWAY_INFO_TIMEOUT_MS = 12e4;
5604
5628
  const DISCORD_GATEWAY_INFO_TIMEOUT_ENV = "OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS";
5629
+ const DISCORD_GATEWAY_METADATA_MAX_BYTES = 4 * 1024 * 1024;
5605
5630
  const DISCORD_GATEWAY_METADATA_FALLBACK_LOG_INTERVAL_MS = 6e4;
5606
5631
  const discordGatewayBotInfoSchema = Type.Object({
5607
5632
  url: Type.String({ minLength: 1 }),
@@ -5620,7 +5645,7 @@ function resolveFetchInputUrl(input) {
5620
5645
  return input.url;
5621
5646
  }
5622
5647
  async function materializeGuardedResponse(response) {
5623
- const body = await response.arrayBuffer();
5648
+ const body = new Uint8Array(await readResponseWithLimit(response, DISCORD_GATEWAY_METADATA_MAX_BYTES, { onOverflow: ({ size, maxBytes }) => /* @__PURE__ */ new Error(`Discord gateway metadata response body too large: ${size} bytes (limit: ${maxBytes} bytes)`) }));
5624
5649
  return new Response(body, {
5625
5650
  status: response.status,
5626
5651
  statusText: response.statusText,
@@ -6044,6 +6069,26 @@ var DiscordGatewayLifecycleError = class extends Error {
6044
6069
  function getDiscordGatewayEmitter(gateway) {
6045
6070
  return gateway?.emitter;
6046
6071
  }
6072
+ const discordGatewayLog = createSubsystemLogger("discord/gateway");
6073
+ const discordGatewayLateErrorGuards = /* @__PURE__ */ new WeakMap();
6074
+ function removeDiscordGatewayLateErrorGuard(emitter) {
6075
+ const guard = discordGatewayLateErrorGuards.get(emitter);
6076
+ if (!guard) return;
6077
+ emitter.off("error", guard);
6078
+ discordGatewayLateErrorGuards.delete(emitter);
6079
+ }
6080
+ function ensureDiscordGatewayLateErrorGuard(emitter) {
6081
+ if (emitter.listenerCount("error") > 0) return;
6082
+ const seenMessages = /* @__PURE__ */ new Set();
6083
+ const guard = (err) => {
6084
+ const message = formatDiscordGatewayErrorMessage(err);
6085
+ if (seenMessages.has(message)) return;
6086
+ seenMessages.add(message);
6087
+ discordGatewayLog.error(`suppressed late gateway error after dispose: ${message}`);
6088
+ };
6089
+ discordGatewayLateErrorGuards.set(emitter, guard);
6090
+ emitter.on("error", guard);
6091
+ }
6047
6092
  function readFirstStackFrame(err) {
6048
6093
  const stack = err.stack;
6049
6094
  if (!stack) return;
@@ -6125,6 +6170,7 @@ function createDiscordGatewaySupervisor(params) {
6125
6170
  case "buffering": pending.push(event);
6126
6171
  }
6127
6172
  };
6173
+ removeDiscordGatewayLateErrorGuard(emitter);
6128
6174
  emitter.on("error", onGatewayError);
6129
6175
  return {
6130
6176
  emitter,
@@ -6145,6 +6191,8 @@ function createDiscordGatewaySupervisor(params) {
6145
6191
  },
6146
6192
  dispose: () => {
6147
6193
  if (phase === "disposed") return;
6194
+ emitter.off("error", onGatewayError);
6195
+ ensureDiscordGatewayLateErrorGuard(emitter);
6148
6196
  lifecycleHandler = void 0;
6149
6197
  phase = "disposed";
6150
6198
  pending.length = 0;
@@ -7953,7 +8001,7 @@ async function loadConversationRuntime$1() {
7953
8001
  return await conversationRuntimePromise$1;
7954
8002
  }
7955
8003
  async function loadTypingRuntime() {
7956
- typingRuntimePromise ??= import("./typing-BdRqXUN3.js").then((n) => n.n);
8004
+ typingRuntimePromise ??= import("./typing-xr05bL-r.js").then((n) => n.n);
7957
8005
  return await typingRuntimePromise;
7958
8006
  }
7959
8007
  function buildDiscordComponentConversationLabel(params) {
@@ -8374,7 +8422,7 @@ async function dispatchPluginDiscordInteractiveEvent(params) {
8374
8422
  //#region extensions/discord/src/monitor/agent-components.handlers.ts
8375
8423
  let componentsRuntimePromise;
8376
8424
  async function loadComponentsRuntime() {
8377
- componentsRuntimePromise ??= import("./components-Dm4c_ce6.js").then((n) => n.t);
8425
+ componentsRuntimePromise ??= import("./components-j6lTZBsT.js").then((n) => n.t);
8378
8426
  return await componentsRuntimePromise;
8379
8427
  }
8380
8428
  async function handleDiscordComponentEvent(params) {
@@ -9157,7 +9205,9 @@ function attachDiscordGatewayLogging(params) {
9157
9205
  if (shouldPromoteGatewayDebug(message)) runtime.log?.(`discord gateway: ${message}`);
9158
9206
  };
9159
9207
  const onGatewayWarning = (warning) => {
9160
- logVerbose(`discord gateway warning: ${String(warning)}`);
9208
+ const message = `discord gateway warning: ${String(warning)}`;
9209
+ logVerbose(message);
9210
+ runtime.log?.(warn(message));
9161
9211
  };
9162
9212
  const onGatewayMetrics = (metrics) => {
9163
9213
  logVerbose(`discord gateway metrics: ${formatGatewayMetrics(metrics)}`);
@@ -9592,7 +9642,7 @@ async function runDiscordGatewayLifecycle(params) {
9592
9642
  gatewayEmitter?.removeListener(DISCORD_GATEWAY_TRANSPORT_ACTIVITY_EVENT, onGatewayTransportActivity);
9593
9643
  if (params.voiceManager) {
9594
9644
  await params.voiceManager.destroy();
9595
- const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-Bi8N6h5X.js").then((n) => n.n);
9645
+ const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-D-lBI5ZD.js").then((n) => n.n);
9596
9646
  setDiscordTranscriptsVoiceManager({
9597
9647
  accountId: params.accountId,
9598
9648
  manager: null
@@ -9870,7 +9920,7 @@ function logDiscordStartupPhase(params) {
9870
9920
  });
9871
9921
  }
9872
9922
  async function loadDiscordVoiceRuntime() {
9873
- const promise = discordVoiceRuntimePromise ?? import("./manager.runtime-CPHxr9B3.js");
9923
+ const promise = discordVoiceRuntimePromise ?? import("./manager.runtime-NxCd-PVt.js");
9874
9924
  discordVoiceRuntimePromise = promise;
9875
9925
  try {
9876
9926
  return await promise;
@@ -9880,7 +9930,7 @@ async function loadDiscordVoiceRuntime() {
9880
9930
  }
9881
9931
  }
9882
9932
  async function loadDiscordProviderSessionRuntime() {
9883
- const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-D6xc-60s.js");
9933
+ const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-BKMOqHpd.js");
9884
9934
  discordProviderSessionRuntimePromise = promise;
9885
9935
  try {
9886
9936
  return await promise;
@@ -10151,7 +10201,7 @@ async function monitorDiscordProvider(opts = {}) {
10151
10201
  runtime,
10152
10202
  botUserId
10153
10203
  });
10154
- const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-Bi8N6h5X.js").then((n) => n.n);
10204
+ const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-D-lBI5ZD.js").then((n) => n.n);
10155
10205
  setDiscordTranscriptsVoiceManager({
10156
10206
  accountId: account.accountId,
10157
10207
  manager: voiceManager
@@ -1,6 +1,6 @@
1
- import { a as reconcileAcpThreadBindingsOnStartup } from "./thread-bindings-DNitaHVh.js";
2
- import { n as createThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-PZvJ4TJx.js";
3
- import { t as createDiscordMessageHandler } from "./message-handler-CKaTgBIV.js";
1
+ import { a as reconcileAcpThreadBindingsOnStartup } from "./thread-bindings-DU4T6nDo.js";
2
+ import { n as createThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-BqWs1UE2.js";
3
+ import { t as createDiscordMessageHandler } from "./message-handler-cizxbaDc.js";
4
4
  import { resolveThreadBindingIdleTimeoutMs, resolveThreadBindingMaxAgeMs, resolveThreadBindingsEnabled } from "openclaw/plugin-sdk/conversation-runtime";
5
5
  import { getAcpSessionManager, isAcpRuntimeError } from "openclaw/plugin-sdk/acp-runtime";
6
6
  export { createDiscordMessageHandler, createNoopThreadBindingManager, createThreadBindingManager, getAcpSessionManager, isAcpRuntimeError, reconcileAcpThreadBindingsOnStartup, resolveThreadBindingIdleTimeoutMs, resolveThreadBindingMaxAgeMs, resolveThreadBindingsEnabled };
@@ -0,0 +1,2 @@
1
+ import { t as monitorDiscordProvider } from "./provider-B-s93q9s.js";
2
+ export { monitorDiscordProvider };
@@ -1,5 +1,5 @@
1
1
  import { p as normalizeDiscordToken } from "./accounts-P19jm1lf.js";
2
- import { n as fetchDiscord } from "./api-4GFMoWu0.js";
2
+ import { n as fetchDiscord } from "./api-CjnGBhM3.js";
3
3
  import { a as normalizeDiscordSlug } from "./allow-list-C-MqM-B_.js";
4
4
  //#region extensions/discord/src/guilds.ts
5
5
  async function listGuilds(token, fetcher) {
@@ -1,7 +1,7 @@
1
- import { Wt as __exportAll } from "./send.receipt-B21MspvT.js";
2
- import { n as fetchDiscord, t as DiscordApiError } from "./api-4GFMoWu0.js";
1
+ import { Wt as __exportAll } from "./send.receipt-CGecJDin.js";
2
+ import { n as fetchDiscord, t as DiscordApiError } from "./api-CjnGBhM3.js";
3
3
  import { a as normalizeDiscordSlug } from "./allow-list-C-MqM-B_.js";
4
- import { i as listGuilds, n as filterDiscordGuilds, r as resolveDiscordAllowlistToken, t as buildDiscordUnresolvedResults } from "./resolve-allowlist-common-BDpBb8dF.js";
4
+ import { i as listGuilds, n as filterDiscordGuilds, r as resolveDiscordAllowlistToken, t as buildDiscordUnresolvedResults } from "./resolve-allowlist-common-3gB2Gpmm.js";
5
5
  //#region extensions/discord/src/resolve-channels.ts
6
6
  var resolve_channels_exports = /* @__PURE__ */ __exportAll({ resolveDiscordChannelAllowlist: () => resolveDiscordChannelAllowlist });
7
7
  function parseDiscordChannelInput(raw) {