@openclaw/discord 2026.9.8 → 2026.10.1-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +7 -0
  2. package/dist/.setup/{account-inspect-De8hOUxG.mjs → account-inspect-CjKqkDnH.mjs} +2 -2
  3. package/dist/.setup/{accounts-ChaMcixG.mjs → accounts-DXHCL8Zm.mjs} +9 -32
  4. package/dist/.setup/{active-turn-thread-route-fmHl1HNd.mjs → active-turn-thread-route-C4tp9noA.mjs} +5 -9
  5. package/dist/.setup/{activities-api-tvbsU2e3.mjs → activities-api-BL_hJ0JQ.mjs} +15 -18
  6. package/dist/.setup/{api-DVbJwZVt.mjs → api-_oznjffB.mjs} +1 -1
  7. package/dist/.setup/{approval-handler.runtime-DxCK2Rux.mjs → approval-handler.runtime-BilYSrRF.mjs} +22 -61
  8. package/dist/.setup/{approval-message-updates-BKFqavHZ.mjs → approval-message-updates-CgRwc2_Q.mjs} +2 -2
  9. package/dist/.setup/{audit-CLg9I71N.mjs → audit-DtvzxONM.mjs} +4 -4
  10. package/dist/.setup/{channel-access-C12aDZ0p.mjs → channel-access-BRp3Y-rF.mjs} +4 -17
  11. package/dist/.setup/{channel-type-DRCrEMss.mjs → channel-type-D1_b5UhU.mjs} +12 -16
  12. package/dist/.setup/{channel-DxlUVU9t.mjs → channel-z5lQMS_9.mjs} +79 -75
  13. package/dist/.setup/{channel.setup-CRo1GjV7.mjs → channel.setup-DBJtugJO.mjs} +14 -34
  14. package/dist/.setup/{components-Cq1PvIpN.mjs → components-CzXLR3QH.mjs} +56 -72
  15. package/dist/.setup/{config-schema-oxELUSDx.mjs → config-schema-CsemBDpS.mjs} +6 -17
  16. package/dist/.setup/{conversation-binding-route-Caz_XuFH.mjs → conversation-binding-route-Bi62ApSt.mjs} +1 -1
  17. package/dist/.setup/{directory-config-esqNn0Eo.mjs → directory-config-BH1LA-gi.mjs} +1 -1
  18. package/dist/.setup/{directory-live-DtKRHuGV.mjs → directory-live-C9xz7IPm.mjs} +10 -13
  19. package/dist/.setup/{discord-0xJYfdDD.mjs → discord-J7aRzq2Q.mjs} +101 -381
  20. package/dist/.setup/{doctor-BCl1H5tl.mjs → doctor-DxSAngJq.mjs} +31 -70
  21. package/dist/.setup/doctor-contract-Bg3NPAMw.mjs +137 -0
  22. package/dist/.setup/{handle-action-CUvQWnE7.mjs → handle-action-DlmFX-_G.mjs} +10 -11
  23. package/dist/.setup/{handle-action.guild-admin-Df-8gVle.mjs → handle-action.guild-admin-BnyqTczR.mjs} +67 -129
  24. package/dist/.setup/{live-policy-config-8Pv20CHc.mjs → live-policy-config-emmPNyh4.mjs} +1 -1
  25. package/dist/.setup/{message-handler-B-Jk4oDk.mjs → message-handler-BNToPZrx.mjs} +7 -6
  26. package/dist/.setup/{message-handler.preflight-v-__NSDq.mjs → message-handler.preflight-D0BcCyI7.mjs} +13 -23
  27. package/dist/.setup/{message-handler.preflight-pluralkit-CWLUBVcx.mjs → message-handler.preflight-pluralkit-D1g3eq0B.mjs} +5 -8
  28. package/dist/.setup/{message-handler.process-BNFFuChn.mjs → message-handler.process-CThRmCWK.mjs} +57 -96
  29. package/dist/.setup/{outbound-adapter-BobT-kse.mjs → outbound-adapter-BPq0c2wY.mjs} +11 -17
  30. package/dist/.setup/{outbound-session-route-zVGxxceg.mjs → outbound-session-route-DGPPKA0z.mjs} +21 -46
  31. package/dist/.setup/{presence-cache-Di3H3DIU.mjs → presence-cache-Dg3_dADn.mjs} +2 -4
  32. package/dist/.setup/{probe-LYrIHlBF.mjs → probe-DIRY8vh7.mjs} +17 -27
  33. package/dist/.setup/{provider-B_G5hASF.mjs → provider-D2OKMo0f.mjs} +273 -446
  34. package/dist/.setup/{provider-session.runtime-BYlTBFD2.mjs → provider-session.runtime-BupCTZQv.mjs} +3 -3
  35. package/dist/.setup/provider.runtime-BaW_JnfU.mjs +2 -0
  36. package/dist/.setup/{realtime-session.runtime-oUd9DOcz.mjs → realtime-session.runtime-D5RSC8Mm.mjs} +6 -8
  37. package/dist/.setup/{receive-recovery-CHPOsnLc.mjs → receive-recovery-GqF2PUN_.mjs} +1 -4
  38. package/dist/.setup/{resolve-allowlist-common-DPdRggu5.mjs → resolve-allowlist-common-DUYRrrVB.mjs} +5 -9
  39. package/dist/.setup/{resolve-channels-BFPNRmVv.mjs → resolve-channels--MUatisx.mjs} +3 -3
  40. package/dist/.setup/{resolve-users-0-aBuCy3.mjs → resolve-users-CxLcDmM0.mjs} +6 -9
  41. package/dist/.setup/{retry-pz_cSha2.mjs → retry-BKzO25k4.mjs} +27 -51
  42. package/dist/.setup/{runtime-sUksZ--Q.mjs → runtime-CerRBfaa.mjs} +2 -2
  43. package/dist/.setup/{runtime-FN000lxA.mjs → runtime-CwUA0RLr.mjs} +228 -255
  44. package/dist/.setup/{runtime-doctor-migrations-CshUGl36.mjs → runtime-doctor-migrations-BPV-R4G9.mjs} +6 -0
  45. package/dist/.setup/{security-audit-Cdaegq7C.mjs → security-audit-D42cp5N7.mjs} +21 -48
  46. package/dist/.setup/{send-CrfEI6Bs.mjs → send-2X7m2Zmw.mjs} +45 -58
  47. package/dist/.setup/{send.components-DxQAMfES.mjs → send.components-RqvgmCs3.mjs} +44 -90
  48. package/dist/.setup/{send.outbound-BISKnb-a.mjs → send.outbound-B4QHSEzm.mjs} +60 -98
  49. package/dist/.setup/{send.shared-DGFkbkQR.mjs → send.shared-BQIUh6Vn.mjs} +13 -20
  50. package/dist/.setup/{sender-identity-B9X5Vb9R.mjs → sender-identity-CooeYfAn.mjs} +1 -1
  51. package/dist/.setup/{session-key-normalization-wJgsKPNF.mjs → session-key-normalization-CCHGNSQw.mjs} +3 -9
  52. package/dist/.setup/setup-plugin-api-nn_giXvZ.mjs +3 -0
  53. package/dist/.setup/{shared-B3wZ4hN-.mjs → shared-CIJn6AEC.mjs} +7 -7
  54. package/dist/.setup/{subagent-hooks-nlUE9ow7.mjs → subagent-hooks-BYlVnxzy.mjs} +4 -9
  55. package/dist/.setup/{system-events-CdeZnvPV.mjs → system-events-CQ3if_pS.mjs} +2 -2
  56. package/dist/.setup/{target-resolver-BuLapkhy.mjs → target-resolver-Dzxf80Y3.mjs} +5 -13
  57. package/dist/.setup/targets-Lf8D55w-.mjs +3 -0
  58. package/dist/.setup/{thread-bindings-D7TfgjR_.mjs → thread-bindings-yNNlcUWE.mjs} +5 -6
  59. package/dist/.setup/{thread-bindings.manager-DN-NissX.mjs → thread-bindings.manager-plk0zJAW.mjs} +14 -20
  60. package/dist/.setup/{thread-bindings.session-updates-CshfKghV.mjs → thread-bindings.session-updates-C9aKtVs6.mjs} +295 -5
  61. package/dist/.setup/{timeouts-D86uWLt_.mjs → timeouts-pun7VJ02.mjs} +2 -15
  62. package/dist/.setup/{transcripts-source-p8EV179h.mjs → transcripts-source-CNWswry-.mjs} +31 -79
  63. package/dist/.setup/typing-CNlSKY5S.mjs +11 -0
  64. package/dist/.setup/{voice-runtime-B46rcwrG.mjs → voice-runtime-Bc75quiH.mjs} +62 -110
  65. package/dist/account-inspect-api.js +1 -1
  66. package/dist/action-runtime-api.js +1 -1
  67. package/dist/activities-api.js +1 -1
  68. package/dist/api.js +18 -18
  69. package/dist/channel-config-api.js +1 -1
  70. package/dist/channel-plugin-api.js +1 -1
  71. package/dist/control-ui/2afbdab1d3aa65a789d8a3eba666f4b1ec5df07073538fe30d6cf32093a1fb2d/index.js +1 -0
  72. package/dist/directory-contract-api.js +1 -1
  73. package/dist/doctor-contract-api.js +19 -128
  74. package/dist/index.js +1 -1
  75. package/dist/runtime-api.js +20 -21
  76. package/dist/security-audit-contract-api.js +1 -1
  77. package/dist/session-key-api.js +1 -1
  78. package/dist/setup-entry.js +1 -1
  79. package/dist/setup-plugin-api.js +1 -1
  80. package/dist/src/voice/audio-worker.runtime.js +6 -8
  81. package/dist/subagent-hooks-api.js +1 -1
  82. package/dist/transcripts-source-api.js +1 -1
  83. package/node_modules/libopus-wasm/CHANGELOG.md +8 -0
  84. package/node_modules/libopus-wasm/dist/discordjs.d.ts.map +1 -1
  85. package/node_modules/libopus-wasm/dist/discordjs.js +14 -2
  86. package/node_modules/libopus-wasm/dist/generated/libopus.generated.mjs +0 -0
  87. package/node_modules/libopus-wasm/dist/index.d.ts.map +1 -1
  88. package/node_modules/libopus-wasm/dist/index.js +55 -100
  89. package/node_modules/libopus-wasm/package.json +5 -5
  90. package/node_modules/undici/README.md +10 -1
  91. package/node_modules/undici/docs/docs/api/Agent.md +8 -8
  92. package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +9 -6
  93. package/node_modules/undici/docs/docs/api/Dispatcher.md +9 -0
  94. package/node_modules/undici/docs/docs/api/Errors.md +25 -0
  95. package/node_modules/undici/docs/docs/api/Fetch.md +10 -0
  96. package/node_modules/undici/docs/docs/api/Interceptors.md +4 -3
  97. package/node_modules/undici/docs/docs/api/Pool.md +5 -6
  98. package/node_modules/undici/docs/docs/index.md +10 -1
  99. package/node_modules/undici/lib/api/readable.js +1 -2
  100. package/node_modules/undici/lib/core/request.js +23 -2
  101. package/node_modules/undici/lib/core/util.js +0 -39
  102. package/node_modules/undici/lib/dispatcher/client-h1.js +11 -4
  103. package/node_modules/undici/lib/dispatcher/client-h2.js +52 -8
  104. package/node_modules/undici/lib/dispatcher/client.js +6 -1
  105. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +21 -6
  106. package/node_modules/undici/lib/dispatcher/pool-base.js +63 -2
  107. package/node_modules/undici/lib/dispatcher/pool.js +90 -7
  108. package/node_modules/undici/lib/dispatcher/proxy-agent.js +16 -3
  109. package/node_modules/undici/lib/handler/deduplication-handler.js +24 -11
  110. package/node_modules/undici/lib/handler/redirect-handler.js +5 -0
  111. package/node_modules/undici/lib/handler/retry-handler.js +72 -13
  112. package/node_modules/undici/lib/interceptor/cache.js +4 -1
  113. package/node_modules/undici/lib/interceptor/decompress.js +236 -69
  114. package/node_modules/undici/lib/web/cache/cache.js +17 -8
  115. package/node_modules/undici/lib/web/cache/cachestorage.js +11 -5
  116. package/node_modules/undici/lib/web/cookies/index.js +19 -7
  117. package/node_modules/undici/lib/web/cookies/util.js +3 -1
  118. package/node_modules/undici/lib/web/eventsource/eventsource.js +25 -1
  119. package/node_modules/undici/lib/web/fetch/body.js +22 -15
  120. package/node_modules/undici/lib/web/fetch/data-url.js +6 -6
  121. package/node_modules/undici/lib/web/fetch/formdata.js +30 -36
  122. package/node_modules/undici/lib/web/fetch/headers.js +34 -31
  123. package/node_modules/undici/lib/web/fetch/index.js +46 -25
  124. package/node_modules/undici/lib/web/fetch/request.js +74 -79
  125. package/node_modules/undici/lib/web/fetch/response.js +43 -44
  126. package/node_modules/undici/lib/web/fetch/util.js +7 -7
  127. package/node_modules/undici/lib/web/infra/index.js +16 -1
  128. package/node_modules/undici/lib/web/webidl/index.js +2 -14
  129. package/node_modules/undici/lib/web/websocket/connection.js +33 -12
  130. package/node_modules/undici/lib/web/websocket/events.js +43 -26
  131. package/node_modules/undici/lib/web/websocket/receiver.js +2 -0
  132. package/node_modules/undici/lib/web/websocket/stream/websocketerror.js +13 -10
  133. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +19 -4
  134. package/node_modules/undici/lib/web/websocket/websocket.js +44 -41
  135. package/node_modules/undici/package.json +1 -1
  136. package/node_modules/undici/types/diagnostics-channel.d.ts +2 -1
  137. package/node_modules/undici/types/interceptors.d.ts +1 -1
  138. package/node_modules/undici/types/webidl.d.ts +13 -7
  139. package/openclaw.plugin.json +6 -0
  140. package/package.json +12 -7
  141. package/dist/.setup/doctor-contract-CvvgwrrG.mjs +0 -409
  142. package/dist/.setup/model-picker-preference-primitives-BHT1LkR_.mjs +0 -37
  143. package/dist/.setup/provider.runtime-CUE3UxER.mjs +0 -2
  144. package/dist/.setup/setup-plugin-api-BQUBxbhe.mjs +0 -3
  145. package/dist/.setup/targets-0KUcEIYx.mjs +0 -3
  146. package/dist/.setup/thread-bindings.state-g6v9zAym.mjs +0 -331
  147. package/dist/.setup/typing-BiHCzBRu.mjs +0 -15
@@ -1,14 +1,14 @@
1
- import { C as withDiscordRequestAuthority, ct as createChannelMessage, lt as createThread } from "./discord-0xJYfdDD.mjs";
2
- import { i as normalizeDiscordHandleKey, o as resolveDiscordDirectoryUserId } from "./directory-live-DtKRHuGV.mjs";
3
- import { f as createReusableDiscordReplyReference, l as createDiscordSendReceiptFromResults, u as createDiscordSendResult } from "./retry-pz_cSha2.mjs";
4
- import { A as resolveDiscordSendEmbeds, D as createDiscordMessageNonce, E as buildDiscordMessageRequest, G as parseAndResolveChannelRecipient, M as createDiscordClient, O as resolveDiscordMessageFlags, c as resolveChannelId, d as sendDiscordMedia, f as sendDiscordText, i as normalizeDiscordPollInput, j as resolveDiscordSuppressEmbeds, k as resolveDiscordSendComponents, l as resolveDiscordChannel, n as buildDiscordTextChunks, s as normalizeStickerIds, t as buildDiscordSendError } from "./send.shared-DGFkbkQR.mjs";
5
- import { ChannelType } from "discord-api-types/v10";
6
- import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
7
- import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { C as withDiscordRequestAuthority, ct as createThread } from "./discord-J7aRzq2Q.mjs";
2
+ import { a as normalizeDiscordSnowflake, i as normalizeDiscordHandleKey, s as resolveDiscordDirectoryUserId } from "./directory-live-C9xz7IPm.mjs";
3
+ import { f as createReusableDiscordReplyReference, l as createDiscordSendReceiptFromResults, u as createDiscordSendResult } from "./retry-BKzO25k4.mjs";
4
+ import { A as resolveDiscordSendEmbeds, D as createDiscordMessageNonce, E as buildDiscordMessageRequest, G as parseAndResolveChannelRecipient, M as createDiscordClient, O as resolveDiscordMessageFlags, c as resolveChannelId, d as sendDiscordMedia, f as sendDiscordText, i as normalizeDiscordPollInput, j as resolveDiscordSuppressEmbeds, k as resolveDiscordSendComponents, l as resolveDiscordChannel, n as buildDiscordTextChunks, s as normalizeStickerIds, t as buildDiscordSendError } from "./send.shared-BQIUh6Vn.mjs";
5
+ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
+ import { ChannelType, Routes } from "discord-api-types/v10";
8
7
  import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runtime";
9
8
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
10
9
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
11
10
  import { resolveChunkMode } from "openclaw/plugin-sdk/reply-chunking";
11
+ import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
12
12
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
13
13
  import { fromMarkdown } from "mdast-util-from-markdown";
14
14
  import { convertMarkdownTables } from "openclaw/plugin-sdk/text-chunking";
@@ -17,15 +17,10 @@ const MENTION_CANDIDATE_PATTERN = /(^|[\s([{"'.,;:!?])@([a-z0-9_.-]{2,32}(?:#[0-
17
17
  const DISCORD_RESERVED_MENTIONS = /* @__PURE__ */ new Set(["everyone", "here"]);
18
18
  const DISCORD_DISCRIMINATOR_SUFFIX = /#\d{4}$/;
19
19
  const DISCORD_BROADCAST_MENTION_PATTERN = /@(everyone|here)\b/;
20
- function normalizeSnowflake(value) {
21
- const text = normalizeOptionalStringifiedId(value) ?? "";
22
- if (!/^\d+$/.test(text)) return null;
23
- return text;
24
- }
25
20
  function formatMention(params) {
26
- const userId = params.userId == null ? null : normalizeSnowflake(params.userId);
27
- const roleId = params.roleId == null ? null : normalizeSnowflake(params.roleId);
28
- const channelId = params.channelId == null ? null : normalizeSnowflake(params.channelId);
21
+ const userId = params.userId == null ? null : normalizeDiscordSnowflake(params.userId);
22
+ const roleId = params.roleId == null ? null : normalizeDiscordSnowflake(params.roleId);
23
+ const channelId = params.channelId == null ? null : normalizeDiscordSnowflake(params.channelId);
29
24
  const mentions = [
30
25
  userId ? `<@${userId}>` : null,
31
26
  roleId ? `<@&${roleId}>` : null,
@@ -43,7 +38,7 @@ function resolveConfiguredMentionAlias(handle, mentionAliases) {
43
38
  if (!alias) continue;
44
39
  const aliasWithoutDiscriminator = alias.replace(DISCORD_DISCRIMINATOR_SUFFIX, "");
45
40
  if (alias === key || withoutDiscriminator && withoutDiscriminator !== key && alias === withoutDiscriminator || aliasWithoutDiscriminator && aliasWithoutDiscriminator !== alias && aliasWithoutDiscriminator === key) {
46
- const userId = normalizeSnowflake(rawUserId);
41
+ const userId = normalizeDiscordSnowflake(rawUserId);
47
42
  if (userId) return userId;
48
43
  }
49
44
  }
@@ -392,21 +387,6 @@ function deriveForumThreadName(text) {
392
387
  function isForumLikeChannel(channel) {
393
388
  return channel?.type === ChannelType.GuildForum || channel?.type === ChannelType.GuildMedia;
394
389
  }
395
- async function resolveDiscordSendTarget(to, opts) {
396
- const cfg = requireRuntimeConfig(opts.cfg, "Discord send target resolution");
397
- const { rest, request, account } = createDiscordClient({
398
- ...opts,
399
- cfg
400
- });
401
- const recipient = await parseAndResolveChannelRecipient(to, cfg, account.accountId);
402
- const { channelId } = await resolveChannelId(rest, recipient, request);
403
- return {
404
- rest,
405
- request,
406
- channelId,
407
- account
408
- };
409
- }
410
390
  async function sendMessageDiscord(to, text, opts) {
411
391
  return await withDiscordRequestAuthority(opts.assertPlatformSendAuthorized, () => sendMessageDiscordInternal(to, text, opts));
412
392
  }
@@ -610,78 +590,60 @@ async function sendMessageDiscordInternal(to, text, opts) {
610
590
  };
611
591
  }
612
592
  async function sendStickerDiscord(to, stickerIds, opts) {
613
- return await withDiscordRequestAuthority(opts.assertPlatformSendAuthorized, () => sendStickerDiscordInternal(to, stickerIds, opts));
614
- }
615
- async function sendStickerDiscordInternal(to, stickerIds, opts) {
616
- const context = await resolveDiscordStructuredSendContext(to, opts);
617
- const { rewrittenContent, suppressEmbeds } = context;
618
- const stickers = normalizeStickerIds(stickerIds);
619
- const flags = resolveDiscordMessageFlags({
620
- silent: opts.silent,
621
- suppressEmbeds
622
- });
623
- const body = {
624
- content: rewrittenContent || void 0,
625
- sticker_ids: stickers,
626
- nonce: createDiscordMessageNonce(),
627
- enforce_nonce: true,
628
- ...flags ? { flags } : {}
629
- };
630
- return context.send("sticker", body);
593
+ return sendDiscordStructuredMessage(to, opts, "sticker", () => ({ sticker_ids: normalizeStickerIds(stickerIds) }));
631
594
  }
632
595
  async function sendPollDiscord(to, poll, opts) {
633
- return await withDiscordRequestAuthority(opts.assertPlatformSendAuthorized, () => sendPollDiscordInternal(to, poll, opts));
634
- }
635
- async function sendPollDiscordInternal(to, poll, opts) {
636
- const context = await resolveDiscordStructuredSendContext(to, opts);
637
- const { rewrittenContent, suppressEmbeds } = context;
638
- if (poll.durationSeconds !== void 0) throw new Error("Discord polls do not support durationSeconds; use durationHours");
639
- const payload = normalizeDiscordPollInput(poll);
640
- const flags = resolveDiscordMessageFlags({
641
- silent: opts.silent,
642
- suppressEmbeds
596
+ return sendDiscordStructuredMessage(to, opts, "poll", () => {
597
+ if (poll.durationSeconds !== void 0) throw new Error("Discord polls do not support durationSeconds; use durationHours");
598
+ return { poll: normalizeDiscordPollInput(poll) };
643
599
  });
644
- const body = {
645
- content: rewrittenContent || void 0,
646
- poll: payload,
647
- nonce: createDiscordMessageNonce(),
648
- enforce_nonce: true,
649
- ...flags ? { flags } : {}
650
- };
651
- return context.send("poll", body);
652
600
  }
653
- async function resolveDiscordStructuredSendContext(to, opts) {
654
- requireRuntimeConfig(opts.cfg, "Discord structured send");
655
- const { rest, request, channelId, account: accountInfo } = await resolveDiscordSendTarget(to, opts);
656
- const content = opts.content;
657
- return {
658
- send: async (kind, body) => {
659
- const result = await request(async () => {
660
- await opts.onPlatformSendDispatch?.();
661
- opts.assertPlatformSendAuthorized?.();
662
- return createChannelMessage(rest, channelId, { body });
663
- }, kind, { safety: "nonce-protected-create" });
664
- recordChannelActivity({
665
- channel: "discord",
666
- accountId: accountInfo.accountId,
667
- direction: "outbound"
668
- });
669
- return createDiscordSendResult({
670
- result,
671
- fallbackChannelId: channelId,
672
- kind: kind === "poll" ? "poll" : "card",
673
- threadId: kind === "poll" ? opts.threadId : void 0
674
- });
675
- },
676
- rewrittenContent: content?.trim() ? rewriteDiscordKnownMentions(content, {
677
- accountId: accountInfo.accountId,
678
- mentionAliases: accountInfo.config.mentionAliases
679
- }) : void 0,
680
- suppressEmbeds: resolveDiscordSuppressEmbeds({
681
- configured: accountInfo.config.suppressEmbeds,
601
+ async function sendDiscordStructuredMessage(to, opts, kind, buildPayload) {
602
+ return withDiscordRequestAuthority(opts.assertPlatformSendAuthorized, async () => {
603
+ const cfg = requireRuntimeConfig(opts.cfg, "Discord structured send");
604
+ const { rest, request, account } = createDiscordClient({
605
+ ...opts,
606
+ cfg
607
+ });
608
+ const recipient = await parseAndResolveChannelRecipient(to, cfg, account.accountId);
609
+ const { channelId } = await resolveChannelId(rest, recipient, request);
610
+ const content = opts.content?.trim() ? rewriteDiscordKnownMentions(opts.content, {
611
+ accountId: account.accountId,
612
+ mentionAliases: account.config.mentionAliases
613
+ }) : void 0;
614
+ const suppressEmbeds = resolveDiscordSuppressEmbeds({
615
+ configured: account.config.suppressEmbeds,
682
616
  override: opts.suppressEmbeds
683
- })
684
- };
617
+ });
618
+ const payload = buildPayload();
619
+ const flags = resolveDiscordMessageFlags({
620
+ silent: opts.silent,
621
+ suppressEmbeds
622
+ });
623
+ const body = {
624
+ content: content || void 0,
625
+ ...payload,
626
+ nonce: createDiscordMessageNonce(),
627
+ enforce_nonce: true,
628
+ ...flags ? { flags } : {}
629
+ };
630
+ const result = await request(async () => {
631
+ await opts.onPlatformSendDispatch?.();
632
+ opts.assertPlatformSendAuthorized?.();
633
+ return await rest.post(Routes.channelMessages(channelId), { body });
634
+ }, kind, { safety: "nonce-protected-create" });
635
+ recordChannelActivity({
636
+ channel: "discord",
637
+ accountId: account.accountId,
638
+ direction: "outbound"
639
+ });
640
+ return createDiscordSendResult({
641
+ result,
642
+ fallbackChannelId: channelId,
643
+ kind: kind === "poll" ? "poll" : "card",
644
+ threadId: kind === "poll" ? opts.threadId : void 0
645
+ });
646
+ });
685
647
  }
686
648
  //#endregion
687
649
  export { discordTextHasBroadcastMention as a, prepareDiscordOutboundText as i, sendPollDiscord as n, formatMention as o, sendStickerDiscord as r, sendMessageDiscord as t };
@@ -1,22 +1,21 @@
1
- import { A as serializePayload, Mt as getGuildMember, ct as createChannelMessage, g as RequestClient, gt as getThreadMember, it as getCurrentUser, j as Embed, jt as getGuild, k as hasDiscordV2Components, mt as getChannel, rt as createUserDmChannel } from "./discord-0xJYfdDD.mjs";
2
- import { t as isDiscordThreadChannelType } from "./channel-type-DRCrEMss.mjs";
3
- import { c as resolveDiscordAccount, m as normalizeDiscordToken, o as mergeDiscordAccountConfig } from "./accounts-ChaMcixG.mjs";
4
- import { o as chunkDiscordTextWithMode, p as resolveDiscordReplyMessageId, r as createDiscordRetryRunner } from "./retry-pz_cSha2.mjs";
5
- import { t as parseAndResolveDiscordTarget } from "./target-resolver-BuLapkhy.mjs";
6
- import { ChannelType, MessageFlags, PermissionFlagsBits } from "discord-api-types/v10";
1
+ import { A as serializePayload, _t as getGuildMember, dt as getChannel, g as RequestClient, gt as getGuild, it as getCurrentUser, j as Embed, k as hasDiscordV2Components, pt as getThreadMember, rt as createUserDmChannel } from "./discord-J7aRzq2Q.mjs";
2
+ import { t as isDiscordThreadChannelType } from "./channel-type-D1_b5UhU.mjs";
3
+ import { c as resolveDiscordAccount, m as normalizeDiscordToken, o as mergeDiscordAccountConfig } from "./accounts-DXHCL8Zm.mjs";
4
+ import { o as chunkDiscordTextWithMode, p as resolveDiscordReplyMessageId, r as createDiscordRetryRunner } from "./retry-BKzO25k4.mjs";
5
+ import { t as parseAndResolveDiscordTarget } from "./target-resolver-Dzxf80Y3.mjs";
6
+ import { normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
7
+ import { ChannelType, MessageFlags, PermissionFlagsBits, Routes } from "discord-api-types/v10";
7
8
  import { randomBytes } from "node:crypto";
8
9
  import { makeProxyFetch } from "openclaw/plugin-sdk/fetch-runtime";
9
10
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
10
- import { normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
11
+ import { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/outbound-media";
11
12
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
12
13
  import { resolveTextChunksWithFallback } from "openclaw/plugin-sdk/reply-payload";
13
14
  import { danger } from "openclaw/plugin-sdk/runtime-env";
14
15
  import { PollLayoutType } from "discord-api-types/payloads/v10";
15
- import { buildOutboundMediaLoadOptions, extensionForMime, normalizePollDurationHours, normalizePollInput } from "openclaw/plugin-sdk/media-runtime";
16
- import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
16
+ import { extensionForMime, normalizePollDurationHours, normalizePollInput } from "openclaw/plugin-sdk/media-runtime";
17
17
  //#region extensions/discord/src/recipient-resolution.ts
18
18
  async function parseAndResolveRecipient(raw, cfg, accountId, parseOptions = {}) {
19
- if (!cfg) throw new Error("Discord recipient resolution requires a resolved runtime config. Load and resolve config at the command or gateway boundary, then pass cfg through the runtime path.");
20
19
  const resolvedCfg = requireRuntimeConfig(cfg, "Discord recipient resolution");
21
20
  const accountInfo = resolveDiscordAccount({
22
21
  cfg: resolvedCfg,
@@ -103,13 +102,7 @@ function validateDiscordProxyUrl(proxyUrl) {
103
102
  //#region extensions/discord/src/proxy-request-client.ts
104
103
  const DISCORD_REST_TIMEOUT_MS = 15e3;
105
104
  function createDiscordRequestClient(token, options) {
106
- if (!options?.fetch) return new RequestClient(token, options);
107
- return new RequestClient(token, {
108
- maxQueueSize: 1e3,
109
- timeout: DISCORD_REST_TIMEOUT_MS,
110
- ...options,
111
- fetch: options.fetch
112
- });
105
+ return new RequestClient(token, options);
113
106
  }
114
107
  //#endregion
115
108
  //#region extensions/discord/src/client.ts
@@ -676,7 +669,7 @@ async function sendDiscordChunks(params, upload) {
676
669
  result = await params.request(async () => {
677
670
  await params.onPlatformSendDispatch?.();
678
671
  params.assertPlatformSendAuthorized?.();
679
- return createChannelMessage(params.rest, params.channelId, { body });
672
+ return await params.rest.post(Routes.channelMessages(params.channelId), { body });
680
673
  }, files ? "media" : "text", { safety: "nonce-protected-create" });
681
674
  } catch (error) {
682
675
  if (files && upload) return upload.onRejected(error);
@@ -696,12 +689,12 @@ async function sendDiscordText(params) {
696
689
  return sendDiscordChunks(params);
697
690
  }
698
691
  async function sendDiscordMedia(params) {
699
- const media = await loadWebMedia(params.mediaUrl, buildOutboundMediaLoadOptions({
692
+ const media = await loadOutboundMediaFromUrl(params.mediaUrl, {
700
693
  maxBytes: params.maxBytes,
701
694
  mediaAccess: params.mediaAccess,
702
695
  mediaLocalRoots: params.mediaLocalRoots,
703
696
  mediaReadFile: params.mediaReadFile
704
- }));
697
+ });
705
698
  const resolvedFileName = params.filename?.trim() || media.fileName || (media.contentType ? `upload${extensionForMime(media.contentType) ?? ""}` : "") || "upload";
706
699
  return sendDiscordChunks(params, {
707
700
  files: [{
@@ -1,4 +1,4 @@
1
- import { S as formatDiscordUserTag } from "./channel-type-DRCrEMss.mjs";
1
+ import { C as formatDiscordUserTag } from "./channel-type-D1_b5UhU.mjs";
2
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  //#region extensions/discord/src/monitor/sender-identity.ts
4
4
  function resolveDiscordWebhookId(message) {
@@ -1,16 +1,10 @@
1
1
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
2
2
  //#region extensions/discord/src/session-key-normalization.ts
3
- function normalizeDiscordChatType(raw) {
4
- const normalized = normalizeLowercaseStringOrEmpty(raw);
5
- if (!normalized) return;
6
- if (normalized === "dm") return "direct";
7
- if (normalized === "group" || normalized === "channel" || normalized === "direct") return normalized;
8
- }
9
3
  function normalizeExplicitDiscordSessionKey(sessionKey, ctx) {
10
4
  let normalized = normalizeLowercaseStringOrEmpty(sessionKey);
11
- if (normalizeDiscordChatType(ctx.ChatType) !== "direct") return normalized;
12
- normalized = normalized.replace(/^(discord:)dm:/, "$1direct:");
13
- normalized = normalized.replace(/^(agent:[^:]+:discord:)dm:/, "$1direct:");
5
+ const chatType = normalizeLowercaseStringOrEmpty(ctx.ChatType);
6
+ if (chatType !== "direct" && chatType !== "dm") return normalized;
7
+ normalized = normalized.replace(/^((?:agent:[^:]+:)?discord:)dm:/, "$1direct:");
14
8
  const match = normalized.match(/^((?:agent:[^:]+:)?)discord:channel:([^:]+)$/);
15
9
  if (!match) return normalized;
16
10
  const from = normalizeLowercaseStringOrEmpty(ctx.From);
@@ -0,0 +1,3 @@
1
+ import { t as discordSetupPlugin } from "./channel.setup-DBJtugJO.mjs";
2
+ import "../setup-plugin-api.js";
3
+ export { discordSetupPlugin };
@@ -1,8 +1,8 @@
1
- import { c as resolveDiscordAccount, d as resolveDiscordAccountDisabledReason, f as resolveDiscordAccountDmPolicy, l as resolveDiscordAccountAllowFrom, n as isDiscordAccountEnabledForRuntime, o as mergeDiscordAccountConfig, r as listDiscordAccountIds, s as resolveDefaultDiscordAccountId } from "./accounts-ChaMcixG.mjs";
2
- import { t as inspectDiscordAccount } from "./account-inspect-De8hOUxG.mjs";
3
- import { n as discordIngressIdentity, t as selectDiscordLivePolicyConfig } from "./live-policy-config-8Pv20CHc.mjs";
4
- import { t as DiscordChannelConfigSchema } from "./config-schema-oxELUSDx.mjs";
5
- import { n as normalizeCompatibilityConfig } from "./doctor-contract-CvvgwrrG.mjs";
1
+ import { c as resolveDiscordAccount, d as resolveDiscordAccountDisabledReason, f as resolveDiscordAccountDmPolicy, l as resolveDiscordAccountAllowFrom, n as isDiscordAccountEnabledForRuntime, o as mergeDiscordAccountConfig, r as listDiscordAccountIds, s as resolveDefaultDiscordAccountId } from "./accounts-DXHCL8Zm.mjs";
2
+ import { t as inspectDiscordAccount } from "./account-inspect-CjKqkDnH.mjs";
3
+ import { n as discordIngressIdentity, t as selectDiscordLivePolicyConfig } from "./live-policy-config-emmPNyh4.mjs";
4
+ import { t as DiscordChannelConfigSchema } from "./config-schema-CsemBDpS.mjs";
5
+ import { n as normalizeCompatibilityConfig } from "./doctor-contract-Bg3NPAMw.mjs";
6
6
  import { r as secretTargetRegistryEntries, t as collectRuntimeConfigAssignments } from "./secret-config-contract-uOE2J7yM.mjs";
7
7
  import { n as unsupportedSecretRefSurfacePatterns, t as collectUnsupportedSecretRefConfigCandidates } from "./security-contract-DSHk7I2w.mjs";
8
8
  import { t as deriveLegacySessionChatType } from "./session-contract-BO5tlIdl.mjs";
@@ -57,7 +57,7 @@ const collectDiscordSecurityFindings = createConditionalWarningCollector.finding
57
57
  severity: "warn",
58
58
  title: "Discord security warning"
59
59
  });
60
- const loadDiscordSecurityAuditModule = createLazyRuntimeModule(() => import("./security-audit-Cdaegq7C.mjs").then((n) => n.n));
60
+ const loadDiscordSecurityAuditModule = createLazyRuntimeModule(() => import("./security-audit-D42cp5N7.mjs").then((n) => n.n));
61
61
  const discordSecurityAdapter = {
62
62
  resolveDmPolicy: resolveDiscordDmPolicy,
63
63
  collectWarnings: collectDiscordSecurityFindings,
@@ -101,7 +101,7 @@ const DISCORD_LEGACY_CONFIG_RULES = [];
101
101
  //#region extensions/discord/src/shared.ts
102
102
  const DISCORD_CHANNEL = "discord";
103
103
  const livePolicyConfigPrefixes = Object.keys(selectDiscordLivePolicyConfig({})).flatMap((key) => [`channels.discord.${key}`, `channels.discord.accounts.*.${key}`]);
104
- const loadDiscordDoctorModule = createLazyRuntimeModule(() => import("./doctor-BCl1H5tl.mjs"));
104
+ const loadDiscordDoctorModule = createLazyRuntimeModule(() => import("./doctor-DxSAngJq.mjs"));
105
105
  const discordDoctor = {
106
106
  dmAllowFromMode: "topOnly",
107
107
  groupModel: "route",
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
2
- import { u as ensureBindingsLoadedAsync } from "./thread-bindings.state-g6v9zAym.mjs";
3
- import { o as listThreadBindingsBySessionKey, u as unbindThreadBindingsBySessionKeyAsync } from "./thread-bindings-D7TfgjR_.mjs";
2
+ import { x as ensureBindingsLoadedAsync } from "./thread-bindings.session-updates-C9aKtVs6.mjs";
3
+ import { o as listThreadBindingsBySessionKey, u as unbindThreadBindingsBySessionKeyAsync } from "./thread-bindings-yNNlcUWE.mjs";
4
4
  import { normalizeOptionalLowercaseString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  //#region extensions/discord/src/subagent-hooks.ts
6
6
  var subagent_hooks_exports = /* @__PURE__ */ __exportAll({
@@ -34,19 +34,14 @@ async function handleDiscordSubagentDeliveryTargetAsync(event) {
34
34
  }
35
35
  function resolveDiscordDeliveryTarget(event) {
36
36
  const requesterAccountId = event.requesterOrigin?.accountId?.trim();
37
- const requesterThreadId = event.requesterOrigin?.threadId != null && event.requesterOrigin.threadId !== "" ? normalizeOptionalStringifiedId(event.requesterOrigin.threadId) ?? "" : "";
37
+ const requesterThreadId = normalizeOptionalStringifiedId(event.requesterOrigin?.threadId);
38
38
  const bindings = listThreadBindingsBySessionKey({
39
39
  targetSessionKey: event.childSessionKey,
40
40
  ...requesterAccountId ? { accountId: requesterAccountId } : {},
41
41
  targetKind: "subagent"
42
42
  });
43
- if (bindings.length === 0) return;
44
43
  let binding;
45
- if (requesterThreadId) binding = bindings.find((entry) => {
46
- if (entry.threadId !== requesterThreadId) return false;
47
- if (requesterAccountId && entry.accountId !== requesterAccountId) return false;
48
- return true;
49
- });
44
+ if (requesterThreadId) binding = bindings.find((entry) => entry.threadId === requesterThreadId && (!requesterAccountId || entry.accountId === requesterAccountId));
50
45
  if (!binding && bindings.length === 1) binding = bindings[0];
51
46
  if (!binding) return;
52
47
  return { origin: {
@@ -1,5 +1,5 @@
1
- import { t as discord_exports } from "./discord-0xJYfdDD.mjs";
2
- import { S as formatDiscordUserTag } from "./channel-type-DRCrEMss.mjs";
1
+ import { t as discord_exports } from "./discord-J7aRzq2Q.mjs";
2
+ import { C as formatDiscordUserTag } from "./channel-type-D1_b5UhU.mjs";
3
3
  //#region extensions/discord/src/monitor/system-events.ts
4
4
  const SYSTEM_EVENT_ACTIONS = /* @__PURE__ */ new Map([
5
5
  [discord_exports.MessageType.ChannelPinnedMessage, "pinned a message"],
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
2
- import { c as resolveDiscordAccount, l as resolveDiscordAccountAllowFrom } from "./accounts-ChaMcixG.mjs";
3
- import { a as rememberDiscordDirectoryUser, r as listDiscordDirectoryPeersLive } from "./directory-live-DtKRHuGV.mjs";
4
- import { b as parseDiscordTarget, h as allowFromContainsDiscordUserId } from "./retry-pz_cSha2.mjs";
2
+ import { c as resolveDiscordAccount, l as resolveDiscordAccountAllowFrom } from "./accounts-DXHCL8Zm.mjs";
3
+ import { o as rememberDiscordDirectoryUser, r as listDiscordDirectoryPeersLive } from "./directory-live-C9xz7IPm.mjs";
4
+ import { b as parseDiscordTarget, h as allowFromContainsDiscordUserId } from "./retry-BKzO25k4.mjs";
5
5
  import { buildMessagingTarget } from "openclaw/plugin-sdk/channel-targets";
6
6
  //#region extensions/discord/src/target-resolver.ts
7
7
  var target_resolver_exports = /* @__PURE__ */ __exportAll({
@@ -15,7 +15,7 @@ var target_resolver_exports = /* @__PURE__ */ __exportAll({
15
15
  async function resolveDiscordTarget(raw, options, parseOptions = {}) {
16
16
  const trimmed = raw.trim();
17
17
  if (!trimmed) return;
18
- const likelyUsername = isLikelyUsername(trimmed);
18
+ const likelyUsername = !/^(user:|channel:|discord:|@|<@!?)|[\d]+$/.test(trimmed);
19
19
  const shouldLookup = isExplicitUserLookup(trimmed, parseOptions) || likelyUsername;
20
20
  if (/^\d+$/.test(trimmed) && parseOptions.defaultKind !== "user" && isConfiguredAllowedDiscordDmUser(trimmed, options)) return buildMessagingTarget("user", trimmed, trimmed);
21
21
  const directParse = safeParseDiscordTarget(trimmed, parseOptions);
@@ -67,15 +67,7 @@ function isConfiguredAllowedDiscordDmUser(input, options) {
67
67
  return allowFromContainsDiscordUserId(allowFrom, input);
68
68
  }
69
69
  function isExplicitUserLookup(input, options) {
70
- if (/^<@!?(\d+)>$/.test(input)) return true;
71
- if (/^(user:|discord:)/.test(input)) return true;
72
- if (input.startsWith("@")) return true;
73
- if (/^\d+$/.test(input)) return options.defaultKind === "user";
74
- return false;
75
- }
76
- function isLikelyUsername(input) {
77
- if (/^(user:|channel:|discord:|@|<@!?)|[\d]+$/.test(input)) return false;
78
- return true;
70
+ return /^<@!?(\d+)>$/.test(input) || /^(user:|discord:)/.test(input) || input.startsWith("@") || /^\d+$/.test(input) && options.defaultKind === "user";
79
71
  }
80
72
  //#endregion
81
73
  export { resolveDiscordTarget as n, target_resolver_exports as r, parseAndResolveDiscordTarget as t };
@@ -0,0 +1,3 @@
1
+ import "./retry-BKzO25k4.mjs";
2
+ import "./target-resolver-Dzxf80Y3.mjs";
3
+ export {};
@@ -1,11 +1,10 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
2
- import { b as parseDiscordTarget } from "./retry-pz_cSha2.mjs";
3
- import "./targets-0KUcEIYx.mjs";
4
- import { D as resolveThreadBindingMaxAgeMs$1, E as resolveThreadBindingMaxAgeExpiresAt, T as resolveThreadBindingInactivityExpiresAt, _ as refreshUnboundThreadWebhookIdentity, f as getThreadBindingToken, n as MANAGERS_BY_ACCOUNT_ID, t as BINDINGS_BY_THREAD_ID, w as resolveThreadBindingIdleTimeoutMs$1 } from "./thread-bindings.state-g6v9zAym.mjs";
5
- import { a as mutateBindingsForTargetSession, i as setThreadBindingMaxAgeBySessionKeyAsync, n as setThreadBindingIdleTimeoutBySessionKeyAsync, o as resolveBindingIdsForTargetSession, r as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey, u as removeBindingRecordSync } from "./thread-bindings.session-updates-CshfKghV.mjs";
6
- import { c as resolveThreadBindingPersonaFromRecord, i as createNoopThreadBindingManager, n as getThreadBindingManager, o as resolveChannelIdForBinding, s as resolveThreadBindingPersona, t as createThreadBindingManager } from "./thread-bindings.manager-DN-NissX.mjs";
7
- import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
2
+ import { b as parseDiscordTarget } from "./retry-BKzO25k4.mjs";
3
+ import "./targets-Lf8D55w-.mjs";
4
+ import { C as getThreadBindingToken, E as refreshUnboundThreadWebhookIdentity, F as resolveThreadBindingMaxAgeMs$1, M as resolveThreadBindingIdleTimeoutMs$1, N as resolveThreadBindingInactivityExpiresAt, P as resolveThreadBindingMaxAgeExpiresAt, _ as MANAGERS_BY_ACCOUNT_ID, a as mutateBindingsForTargetSession, g as BINDINGS_BY_THREAD_ID, i as setThreadBindingMaxAgeBySessionKeyAsync, n as setThreadBindingIdleTimeoutBySessionKeyAsync, o as resolveBindingIdsForTargetSession, r as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey, u as removeBindingRecordSync } from "./thread-bindings.session-updates-C9aKtVs6.mjs";
5
+ import { c as resolveThreadBindingPersonaFromRecord, i as createNoopThreadBindingManager, n as getThreadBindingManager, o as resolveChannelIdForBinding, s as resolveThreadBindingPersona, t as createThreadBindingManager } from "./thread-bindings.manager-plk0zJAW.mjs";
8
6
  import { normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
7
+ import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
9
8
  import { formatThreadBindingDurationLabel as formatThreadBindingDurationLabel$1, resolveThreadBindingIdleTimeoutMs, resolveThreadBindingIntroText, resolveThreadBindingIntroText as resolveThreadBindingIntroText$1, resolveThreadBindingMaxAgeMs, resolveThreadBindingThreadName, resolveThreadBindingThreadName as resolveThreadBindingThreadName$1, resolveThreadBindingsEnabled } from "openclaw/plugin-sdk/conversation-runtime";
10
9
  import { readAcpSessionEntry } from "openclaw/plugin-sdk/acp-runtime";
11
10
  import { runTasksWithConcurrency } from "openclaw/plugin-sdk/concurrency-runtime";
@@ -1,16 +1,15 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
2
- import { C as withDiscordRequestAuthority, mt as getChannel, nt as createChannelWebhook } from "./discord-0xJYfdDD.mjs";
3
- import { t as isDiscordThreadChannelType } from "./channel-type-DRCrEMss.mjs";
4
- import { t as canFallbackDiscordWebhookSend, x as resolveDiscordChannelId } from "./retry-pz_cSha2.mjs";
5
- import { N as createDiscordRestClient } from "./send.shared-DGFkbkQR.mjs";
6
- import { t as sendMessageDiscord } from "./send.outbound-BISKnb-a.mjs";
7
- import { n as resolveDiscordChannelInfoSafe, t as resolveDiscordChannelIdSafe } from "./channel-access-C12aDZ0p.mjs";
8
- import { c as sendWebhookMessageDiscord, u as createThreadDiscord } from "./send-CrfEI6Bs.mjs";
9
- import { C as resolvePreparedThreadBindingLifecycle, D as resolveThreadBindingMaxAgeMs$1, M as toReusableWebhookKey, S as resolveBindingRecordKey, _ as refreshUnboundThreadWebhookIdentity, c as THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS, d as forgetThreadBindingToken, f as getThreadBindingToken, h as normalizeThreadBindingDurationMs, i as REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL, j as toBindingRecordKey, k as shouldDefaultPersist, m as normalizeTargetKind, n as MANAGERS_BY_ACCOUNT_ID, r as PERSIST_BY_ACCOUNT_ID, t as BINDINGS_BY_THREAD_ID, u as ensureBindingsLoadedAsync, v as rememberReusableWebhook, w as resolveThreadBindingIdleTimeoutMs$1, x as resolveBindingIdsForSession, y as rememberThreadBindingToken } from "./thread-bindings.state-g6v9zAym.mjs";
10
- import { c as drainThreadBindingAccountOperations, d as runThreadBindingAccountOperation, f as runThreadBindingMutation, h as updateBindingRecordSync, l as drainThreadBindingMutations, m as snapshotThreadBindingJson, p as shouldPersistAnyBindingState, s as commitBindingRecord } from "./thread-bindings.session-updates-CshfKghV.mjs";
11
- import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
12
- import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
2
+ import { C as withDiscordRequestAuthority, dt as getChannel, nt as createChannelWebhook } from "./discord-J7aRzq2Q.mjs";
3
+ import { t as isDiscordThreadChannelType } from "./channel-type-D1_b5UhU.mjs";
4
+ import { t as canFallbackDiscordWebhookSend, x as resolveDiscordChannelId } from "./retry-BKzO25k4.mjs";
5
+ import { N as createDiscordRestClient } from "./send.shared-BQIUh6Vn.mjs";
6
+ import { t as sendMessageDiscord } from "./send.outbound-B4QHSEzm.mjs";
7
+ import { n as resolveDiscordChannelInfoSafe, t as resolveDiscordChannelIdSafe } from "./channel-access-BRp3Y-rF.mjs";
8
+ import { c as sendWebhookMessageDiscord, u as createThreadDiscord } from "./send-2X7m2Zmw.mjs";
9
+ import { A as resolveBindingRecordKey, C as getThreadBindingToken, D as rememberReusableWebhook, E as refreshUnboundThreadWebhookIdentity, F as resolveThreadBindingMaxAgeMs$1, I as shouldDefaultPersist, L as toBindingRecordKey, M as resolveThreadBindingIdleTimeoutMs$1, O as rememberThreadBindingToken, R as toReusableWebhookKey, S as forgetThreadBindingToken, T as normalizeThreadBindingDurationMs, _ as MANAGERS_BY_ACCOUNT_ID, b as THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS, c as drainThreadBindingAccountOperations, d as runThreadBindingAccountOperation, f as runThreadBindingMutation, g as BINDINGS_BY_THREAD_ID, h as updateBindingRecordSync, j as resolvePreparedThreadBindingLifecycle, k as resolveBindingIdsForSession, l as drainThreadBindingMutations, m as snapshotThreadBindingJson, p as shouldPersistAnyBindingState, s as commitBindingRecord, v as PERSIST_BY_ACCOUNT_ID, w as normalizeTargetKind, x as ensureBindingsLoadedAsync, y as REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL } from "./thread-bindings.session-updates-C9aKtVs6.mjs";
13
10
  import { asOptionalObjectRecord, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
11
+ import { parseStrictNonNegativeInteger as parseStrictNonNegativeInteger$1 } from "openclaw/plugin-sdk/number-runtime";
12
+ import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
14
13
  import { getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
15
14
  import { createSubsystemLogger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
16
15
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
@@ -63,12 +62,12 @@ function summarizeDiscordError(err) {
63
62
  function extractDiscordErrorStatus(err) {
64
63
  if (!err || typeof err !== "object") return;
65
64
  const candidate = err;
66
- return parseStrictNonNegativeInteger(candidate.status) ?? parseStrictNonNegativeInteger(candidate.statusCode) ?? parseStrictNonNegativeInteger(candidate.response?.status);
65
+ return parseStrictNonNegativeInteger$1(candidate.status) ?? parseStrictNonNegativeInteger$1(candidate.statusCode) ?? parseStrictNonNegativeInteger$1(candidate.response?.status);
67
66
  }
68
67
  function extractDiscordErrorCode(err) {
69
68
  if (!err || typeof err !== "object") return;
70
69
  const candidate = err;
71
- return parseStrictNonNegativeInteger(candidate.code) ?? parseStrictNonNegativeInteger(candidate.rawError?.code) ?? parseStrictNonNegativeInteger(candidate.body?.code) ?? parseStrictNonNegativeInteger(candidate.response?.body?.code) ?? parseStrictNonNegativeInteger(candidate.response?.data?.code);
70
+ return parseStrictNonNegativeInteger$1(candidate.code) ?? parseStrictNonNegativeInteger$1(candidate.rawError?.code) ?? parseStrictNonNegativeInteger$1(candidate.body?.code) ?? parseStrictNonNegativeInteger$1(candidate.response?.body?.code) ?? parseStrictNonNegativeInteger$1(candidate.response?.data?.code);
72
71
  }
73
72
  function isDiscordThreadGoneError(err) {
74
73
  if (extractDiscordErrorCode(err) === 10003) return true;
@@ -139,19 +138,14 @@ async function createWebhookForChannel(params) {
139
138
  }
140
139
  }
141
140
  function findReusableWebhook(params) {
142
- const reusableKey = toReusableWebhookKey({
143
- accountId: params.accountId,
144
- channelId: params.channelId
145
- });
141
+ const reusableKey = toReusableWebhookKey(params);
146
142
  const cached = REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL.get(reusableKey);
147
143
  if (cached) return {
148
144
  webhookId: cached.webhookId,
149
145
  webhookToken: cached.webhookToken
150
146
  };
151
147
  for (const record of BINDINGS_BY_THREAD_ID.values()) {
152
- if (record.accountId !== params.accountId) continue;
153
- if (record.channelId !== params.channelId) continue;
154
- if (!record.webhookId || !record.webhookToken) continue;
148
+ if (record.accountId !== params.accountId || record.channelId !== params.channelId || !record.webhookId || !record.webhookToken) continue;
155
149
  rememberReusableWebhook(record);
156
150
  return {
157
151
  webhookId: record.webhookId,