@openclaw/discord 2026.5.12 → 2026.5.14-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 (117) hide show
  1. package/dist/{account-inspect-D7jL5YDH.js → account-inspect-B_N30NV0.js} +1 -1
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/{accounts-BcwyaFd-.js → accounts-DnNVBDfc.js} +95 -4
  4. package/dist/action-runtime-api.js +1 -1
  5. package/dist/{allow-list-n8Ki-Rt3.js → allow-list-CBI-M84K.js} +24 -2
  6. package/dist/api.js +19 -21
  7. package/dist/{approval-handler.runtime-S-ircYcz.js → approval-handler.runtime-Uco62pII.js} +4 -4
  8. package/dist/{audit-BliEqCEc.js → audit-eSlKbMHw.js} +5 -5
  9. package/dist/{channel-Bliqi-Qi.js → channel-BjBa8nYY.js} +23 -25
  10. package/dist/{channel-actions-Cn_K00Vy.js → channel-actions-DANVAtKL.js} +4 -4
  11. package/dist/{channel-actions.runtime-DcsRvPnx.js → channel-actions.runtime-CpIslHS9.js} +7 -5
  12. package/dist/channel-config-api.js +1 -1
  13. package/dist/channel-plugin-api.js +1 -1
  14. package/dist/{channel.setup-DR-xVYso.js → channel.setup-DBFcGRFD.js} +4 -5
  15. package/dist/{components-Dxq2mU57.js → components-Cgm7XT8-.js} +120 -3
  16. package/dist/{config-schema-D2KGskAp.js → config-schema-D7AtCpJa.js} +21 -1
  17. package/dist/contract-api.js +7 -7
  18. package/dist/{approval-native-Gtqpyfdj.js → conversation-identity-C3AI-1tz.js} +123 -6
  19. package/dist/{directory-config-CDl4JTCA.js → directory-config-CW_JusGS.js} +2 -2
  20. package/dist/directory-contract-api.js +1 -1
  21. package/dist/directory-live-MrDSKsMf.js +159 -0
  22. package/dist/doctor-contract-api.js +1 -1
  23. package/dist/{doctor-contract-BGjjFBdq.js → doctor-contract-ftWAMvBl.js} +1 -1
  24. package/dist/{doctor-jcX_qXsS.js → doctor-mn2XyjuF.js} +5 -5
  25. package/dist/{handle-action.guild-admin-C4phin-a.js → handle-action.guild-admin-DriifPwO.js} +1 -1
  26. package/dist/{inbound-context-jtKcY9on.js → inbound-context-DD7n3Q6U.js} +1 -1
  27. package/dist/{manager.runtime-DqMGETqp.js → manager.runtime-DauS2xA3.js} +107 -25
  28. package/dist/{message-handler-DIsnboy2.js → message-handler-CMHwRlxG.js} +7 -7
  29. package/dist/{message-handler.preflight-BRH-dv1o.js → message-handler.preflight-C0sT-ewp.js} +27 -17
  30. package/dist/{message-handler.process-Bs5wropA.js → message-handler.process-Cy7_-0H0.js} +46 -37
  31. package/dist/{message-utils-ByofKwPe.js → message-utils-N5UTOXQ2.js} +16 -12
  32. package/dist/{outbound-adapter-lWjkSeyP.js → outbound-adapter-Cw9JsRTY.js} +7 -10
  33. package/dist/{pluralkit-B1HTaBc9.js → pluralkit-B2AqgTHV.js} +1 -1
  34. package/dist/{preflight-audio-CD97vnac.js → preflight-audio-DFGpAvzi.js} +1 -1
  35. package/dist/{probe-BZtr8qle.js → probe-CiBYm-vD.js} +2 -2
  36. package/dist/{probe.runtime-0F0UzBoJ.js → probe.runtime-9hi1GYNU.js} +1 -1
  37. package/dist/{provider-DABvNRT0.js → provider-nzJg2k5t.js} +1039 -45
  38. package/dist/{provider-session.runtime-BZyP90-i.js → provider-session.runtime-DMxaLPB3.js} +3 -3
  39. package/dist/provider.runtime-S-wZdzK5.js +2 -0
  40. package/dist/{resolve-allowlist-common-CVHYb5Hb.js → resolve-allowlist-common-DybgkAjk.js} +3 -3
  41. package/dist/{resolve-channels-JNt3Ak6P.js → resolve-channels-u7_agBcm.js} +4 -4
  42. package/dist/{resolve-users-CrjbUxrL.js → resolve-users-Bc25I6OP.js} +3 -3
  43. package/dist/{runtime-CdnAT8R5.js → runtime-DL82ijB1.js} +102 -46
  44. package/dist/runtime-api.actions.js +2 -2
  45. package/dist/runtime-api.js +25 -26
  46. package/dist/runtime-api.lookup.js +6 -6
  47. package/dist/runtime-api.monitor-DbLcHuhE.js +5 -0
  48. package/dist/runtime-api.monitor.js +7 -8
  49. package/dist/runtime-api.send.js +5 -5
  50. package/dist/runtime-api.threads.js +5 -5
  51. package/dist/runtime-setter-api.js +1 -1
  52. package/dist/secret-contract-api.js +1 -1
  53. package/dist/{security-audit-BQ_sGK3J.js → security-audit-CLPZKYi4.js} +1 -1
  54. package/dist/security-audit-contract-api.js +1 -1
  55. package/dist/{security-audit.runtime-B7Gmz2DX.js → security-audit.runtime-CCm9leFJ.js} +1 -1
  56. package/dist/security-contract-api.js +1 -1
  57. package/dist/{send-DCFuSiBi.js → send-BqzTEkt9.js} +4 -6
  58. package/dist/{send.components-DxDqPJZQ.js → send.components-D6pXHVrU.js} +8 -10
  59. package/dist/{send.outbound-PM0J0F60.js → send.outbound-D8o8BW6q.js} +91 -7
  60. package/dist/{discord-BqYcwxvG.js → send.receipt-nKLxvA1s.js} +319 -1
  61. package/dist/{send.shared-Dza0jdso.js → send.shared-DSpva7uA.js} +4 -6
  62. package/dist/{sender-identity-w9rSI-nD.js → sender-identity-BTGL3VbF.js} +1 -1
  63. package/dist/session-key-api.js +1 -1
  64. package/dist/setup-plugin-api.js +1 -1
  65. package/dist/{shared-Yp_M6Cfp.js → shared-0kdaIxXP.js} +16 -14
  66. package/dist/{subagent-hooks-CtN-hfXy.js → subagent-hooks-DhuBhwRw.js} +3 -3
  67. package/dist/subagent-hooks-api.js +1 -1
  68. package/dist/{system-events-B04UOvPg.js → system-events-Bnit0zkQ.js} +2 -2
  69. package/dist/{target-resolver-CgJei-kD.js → target-resolver-BsGT9hI7.js} +3 -6
  70. package/dist/targets-DwW6OieO.js +3 -0
  71. package/dist/test-api.js +4 -4
  72. package/dist/{thread-bindings-B4of4OmR.js → thread-bindings-C1f7Iim4.js} +6 -7
  73. package/dist/{thread-bindings.discord-api-BAw15EQb.js → thread-bindings.discord-api-DJACBZJ1.js} +67 -8
  74. package/dist/{thread-bindings.manager-DNFl10CA.js → thread-bindings.manager-DN_q0IW7.js} +4 -5
  75. package/dist/{thread-bindings.session-updates-D18cCLmN.js → thread-bindings.session-updates-ZnRRzzgf.js} +1 -1
  76. package/dist/timeouts.js +1 -1
  77. package/dist/{typing-_jePdFIw.js → typing-C_8U8J7E.js} +2 -2
  78. package/openclaw.plugin.json +68 -0
  79. package/package.json +6 -6
  80. package/dist/access-Dxmzr0ix.js +0 -89
  81. package/dist/approval-shared-BFnWKSQD.js +0 -93
  82. package/dist/channel-access-BL-wemES.js +0 -62
  83. package/dist/chunk-DYl-_5RL.js +0 -179
  84. package/dist/conversation-identity-CvIx6J7M.js +0 -31
  85. package/dist/directory-cache-Ddl-Oxue.js +0 -62
  86. package/dist/directory-live-ApUXOSj0.js +0 -101
  87. package/dist/doctor-shared-D_QLzu30.js +0 -4
  88. package/dist/format-D8TsaXxW.js +0 -24
  89. package/dist/mentions-BZoGn0ul.js +0 -88
  90. package/dist/normalize-Cu94FOqy.js +0 -58
  91. package/dist/outbound-session-route-BaJRt05p.js +0 -43
  92. package/dist/provider.runtime-Cmv1SFtb.js +0 -2
  93. package/dist/reply-delivery-CUSK6SA_.js +0 -191
  94. package/dist/route-resolution-BFfF9xmG.js +0 -268
  95. package/dist/runtime-api.monitor-W_dJ5EQu.js +0 -6
  96. package/dist/send.receipt-BAZw2Zsz.js +0 -35
  97. package/dist/shared-interactive-DavY6jYt.js +0 -79
  98. package/dist/target-parsing-D-H7nnh2.js +0 -51
  99. package/dist/targets-DToZUkgV.js +0 -3
  100. package/dist/threading-CLZ3v7-y.js +0 -475
  101. package/dist/token-BZtonk7d.js +0 -93
  102. /package/dist/{agent-components.runtime-zT8qPsnM.js → agent-components.runtime-CEMbMQcQ.js} +0 -0
  103. /package/dist/{api-DzNBVTto.js → api-DgQLz1wq.js} +0 -0
  104. /package/dist/{audit-core-BgDZSkIR.js → audit-core-DRyoXREU.js} +0 -0
  105. /package/dist/{channel-api-CTSWMrnD.js → channel-api-JudoSiJv.js} +0 -0
  106. /package/dist/{config-api-CFZtoMaS.js → config-api-oLS_52S7.js} +0 -0
  107. /package/dist/{gateway-registry-BKG4KIVC.js → gateway-registry-BKSpa4GB.js} +0 -0
  108. /package/dist/{preflight-audio.runtime-fXnUxxBa.js → preflight-audio.runtime-Drc-OFcp.js} +0 -0
  109. /package/dist/{preview-streaming-DCPAe24T.js → preview-streaming-CXTZydhx.js} +0 -0
  110. /package/dist/{runtime-BqCoo-zp.js → runtime-Tqtvj5GX.js} +0 -0
  111. /package/dist/{secret-config-contract-BCQNNS7N.js → secret-config-contract-B3347_eU.js} +0 -0
  112. /package/dist/{security-contract-DkCMKSvb.js → security-contract-DyCRvz_Q.js} +0 -0
  113. /package/dist/{security-doctor-BJH5YIGL.js → security-doctor-Cp-NqNdS.js} +0 -0
  114. /package/dist/{session-contract-D871HDFG.js → session-contract-ugfEa9Xc.js} +0 -0
  115. /package/dist/{session-key-normalization-BV82IME9.js → session-key-normalization-B7h83qD2.js} +0 -0
  116. /package/dist/{thread-bindings.state-SPlv6mh7.js → thread-bindings.state-BdBeo7Rx.js} +0 -0
  117. /package/dist/{timeouts-C3FYXWJX.js → timeouts-snXNwR4m.js} +0 -0
@@ -1,4 +1,4 @@
1
- import { a as mergeDiscordAccountConfig, l as resolveDiscordAccountConfig, o as resolveDefaultDiscordAccountId } from "./accounts-BcwyaFd-.js";
1
+ import { a as mergeDiscordAccountConfig, l as resolveDiscordAccountConfig, o as resolveDefaultDiscordAccountId } from "./accounts-DnNVBDfc.js";
2
2
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
3
3
  import { hasConfiguredSecretInput, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
4
4
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -1,4 +1,4 @@
1
- import { t as inspectDiscordAccount } from "./account-inspect-D7jL5YDH.js";
1
+ import { t as inspectDiscordAccount } from "./account-inspect-B_N30NV0.js";
2
2
  //#region extensions/discord/account-inspect-api.ts
3
3
  function inspectDiscordReadOnlyAccount(cfg, accountId) {
4
4
  return inspectDiscordAccount({
@@ -1,9 +1,99 @@
1
- import { n as resolveDiscordToken, r as selectDiscordRuntimeConfig } from "./token-BZtonk7d.js";
2
1
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
2
+ import { normalizeResolvedSecretInputString, resolveSecretInputString } from "openclaw/plugin-sdk/secret-input";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { createAccountActionGate, createAccountListHelpers, resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-helpers";
5
5
  import { mapAllowFromEntries, normalizeChannelDmPolicy, resolveChannelDmAllowFrom, resolveChannelDmPolicy } from "openclaw/plugin-sdk/channel-config-helpers";
6
- import { resolveAccountEntry } from "openclaw/plugin-sdk/routing";
6
+ import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, normalizeAccountId as normalizeAccountId$1, resolveAccountEntry } from "openclaw/plugin-sdk/routing";
7
+ import { getRuntimeConfigSnapshot, getRuntimeConfigSourceSnapshot, selectApplicableRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
8
+ //#region extensions/discord/src/runtime-config.ts
9
+ function selectDiscordRuntimeConfig(inputConfig) {
10
+ return selectApplicableRuntimeConfig({
11
+ inputConfig,
12
+ runtimeConfig: getRuntimeConfigSnapshot(),
13
+ runtimeSourceConfig: getRuntimeConfigSourceSnapshot()
14
+ }) ?? inputConfig;
15
+ }
16
+ //#endregion
17
+ //#region extensions/discord/src/token.ts
18
+ function stripDiscordBotPrefix(token) {
19
+ return token.replace(/^Bot\s+/i, "");
20
+ }
21
+ function normalizeDiscordToken(raw, path) {
22
+ const trimmed = normalizeResolvedSecretInputString({
23
+ value: raw,
24
+ path
25
+ });
26
+ if (!trimmed) return;
27
+ return stripDiscordBotPrefix(trimmed);
28
+ }
29
+ function resolveDiscordTokenValue(params) {
30
+ const resolved = resolveSecretInputString({
31
+ value: params.value,
32
+ path: params.path,
33
+ defaults: params.cfg.secrets?.defaults,
34
+ mode: "inspect"
35
+ });
36
+ if (resolved.status === "available") return {
37
+ status: "available",
38
+ value: stripDiscordBotPrefix(resolved.value)
39
+ };
40
+ if (resolved.status === "configured_unavailable") return { status: "configured_unavailable" };
41
+ return { status: "missing" };
42
+ }
43
+ function resolveDiscordToken(cfg, opts = {}) {
44
+ const selectedCfg = selectDiscordRuntimeConfig(cfg);
45
+ const accountId = normalizeAccountId$1(opts.accountId);
46
+ const discordCfg = selectedCfg?.channels?.discord;
47
+ const accountCfg = resolveAccountEntry(discordCfg?.accounts, accountId);
48
+ const hasAccountToken = Boolean(accountCfg && Object.prototype.hasOwnProperty.call(accountCfg, "token"));
49
+ const accountToken = resolveDiscordTokenValue({
50
+ cfg: selectedCfg,
51
+ value: accountCfg?.token,
52
+ path: `channels.discord.accounts.${accountId}.token`
53
+ });
54
+ if (accountToken.status === "available" && accountToken.value) return {
55
+ token: accountToken.value,
56
+ source: "config",
57
+ tokenStatus: "available"
58
+ };
59
+ if (accountToken.status === "configured_unavailable") return {
60
+ token: "",
61
+ source: "config",
62
+ tokenStatus: "configured_unavailable"
63
+ };
64
+ if (hasAccountToken) return {
65
+ token: "",
66
+ source: "none",
67
+ tokenStatus: "missing"
68
+ };
69
+ const configToken = resolveDiscordTokenValue({
70
+ cfg: selectedCfg,
71
+ value: discordCfg?.token,
72
+ path: "channels.discord.token"
73
+ });
74
+ if (configToken.status === "available" && configToken.value) return {
75
+ token: configToken.value,
76
+ source: "config",
77
+ tokenStatus: "available"
78
+ };
79
+ if (configToken.status === "configured_unavailable") return {
80
+ token: "",
81
+ source: "config",
82
+ tokenStatus: "configured_unavailable"
83
+ };
84
+ const envToken = accountId === DEFAULT_ACCOUNT_ID$1 ? normalizeDiscordToken(opts.envToken ?? process.env.DISCORD_BOT_TOKEN, "DISCORD_BOT_TOKEN") : void 0;
85
+ if (envToken) return {
86
+ token: envToken,
87
+ source: "env",
88
+ tokenStatus: "available"
89
+ };
90
+ return {
91
+ token: "",
92
+ source: "none",
93
+ tokenStatus: "missing"
94
+ };
95
+ }
96
+ //#endregion
7
97
  //#region extensions/discord/src/accounts.ts
8
98
  const { listAccountIds, resolveDefaultAccountId } = createAccountListHelpers("discord");
9
99
  const listDiscordAccountIds = listAccountIds;
@@ -15,7 +105,8 @@ function mergeDiscordAccountConfig(cfg, accountId) {
15
105
  return resolveMergedAccountConfig({
16
106
  channelConfig: cfg.channels?.discord,
17
107
  accounts: cfg.channels?.discord?.accounts,
18
- accountId
108
+ accountId,
109
+ nestedObjectKeys: ["botLoopProtection"]
19
110
  });
20
111
  }
21
112
  function resolveDiscordAccountAllowFrom(params) {
@@ -127,4 +218,4 @@ function listEnabledDiscordAccounts(cfg) {
127
218
  })).filter((account) => isDiscordAccountEnabledForRuntime(account, cfg));
128
219
  }
129
220
  //#endregion
130
- export { mergeDiscordAccountConfig as a, resolveDiscordAccountAllowFrom as c, resolveDiscordAccountDmPolicy as d, resolveDiscordMaxLinesPerMessage as f, listEnabledDiscordAccounts as i, resolveDiscordAccountConfig as l, isDiscordAccountEnabledForRuntime as n, resolveDefaultDiscordAccountId as o, listDiscordAccountIds as r, resolveDiscordAccount as s, createDiscordActionGate as t, resolveDiscordAccountDisabledReason as u };
221
+ export { mergeDiscordAccountConfig as a, resolveDiscordAccountAllowFrom as c, resolveDiscordAccountDmPolicy as d, resolveDiscordMaxLinesPerMessage as f, listEnabledDiscordAccounts as i, resolveDiscordAccountConfig as l, resolveDiscordToken as m, isDiscordAccountEnabledForRuntime as n, resolveDefaultDiscordAccountId as o, normalizeDiscordToken as p, listDiscordAccountIds as r, resolveDiscordAccount as s, createDiscordActionGate as t, resolveDiscordAccountDisabledReason as u };
@@ -1,2 +1,2 @@
1
- import { t as handleDiscordAction } from "./runtime-CdnAT8R5.js";
1
+ import { t as handleDiscordAction } from "./runtime-DL82ijB1.js";
2
2
  export { handleDiscordAction };
@@ -1,6 +1,28 @@
1
- import { n as formatDiscordUserTag } from "./format-D8TsaXxW.js";
2
1
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
2
  import { buildChannelKeyCandidates, resolveChannelEntryMatchWithFallback, resolveChannelMatchConfig } from "openclaw/plugin-sdk/channel-targets";
3
+ //#region extensions/discord/src/monitor/format.ts
4
+ function resolveDiscordSystemLocation(params) {
5
+ const { isDirectMessage, isGroupDm, guild, channelName } = params;
6
+ if (isDirectMessage) return "DM";
7
+ if (isGroupDm) return `Group DM #${channelName}`;
8
+ return guild?.name ? `${guild.name} #${channelName}` : `#${channelName}`;
9
+ }
10
+ function formatDiscordReactionEmoji(emoji) {
11
+ if (emoji.id && emoji.name) return `<:${emoji.name}:${emoji.id}>`;
12
+ if (emoji.id) return `emoji:${emoji.id}`;
13
+ return emoji.name ?? "emoji";
14
+ }
15
+ function formatDiscordUserTag(user) {
16
+ const discriminator = (user.discriminator ?? "").trim();
17
+ if (discriminator && discriminator !== "0") return `${user.username}#${discriminator}`;
18
+ return user.username ?? user.id;
19
+ }
20
+ function resolveTimestampMs(timestamp) {
21
+ if (!timestamp) return;
22
+ const parsed = Date.parse(timestamp);
23
+ return Number.isNaN(parsed) ? void 0 : parsed;
24
+ }
25
+ //#endregion
4
26
  //#region extensions/discord/src/monitor/allow-list.ts
5
27
  const DISCORD_OWNER_ALLOWLIST_PREFIXES = [
6
28
  "discord:",
@@ -329,4 +351,4 @@ function shouldEmitDiscordReactionNotification(params) {
329
351
  return false;
330
352
  }
331
353
  //#endregion
332
- export { resolveGroupDmAllow as _, normalizeDiscordSlug as a, resolveDiscordChannelConfigWithFallback as c, resolveDiscordGuildEntry as d, resolveDiscordMemberAccessState as f, resolveDiscordShouldRequireMention as g, resolveDiscordOwnerAllowFrom as h, normalizeDiscordDisplaySlug as i, resolveDiscordChannelPolicyCommandAuthorizer as l, resolveDiscordOwnerAccess as m, isDiscordGroupAllowedByPolicy as n, resolveDiscordAllowListMatch as o, resolveDiscordMemberAllowed as p, normalizeDiscordAllowList as r, resolveDiscordChannelConfig as s, allowListMatches as t, resolveDiscordCommandAuthorized as u, shouldEmitDiscordReactionNotification as v };
354
+ export { resolveTimestampMs as S, resolveGroupDmAllow as _, normalizeDiscordSlug as a, formatDiscordUserTag as b, resolveDiscordChannelConfigWithFallback as c, resolveDiscordGuildEntry as d, resolveDiscordMemberAccessState as f, resolveDiscordShouldRequireMention as g, resolveDiscordOwnerAllowFrom as h, normalizeDiscordDisplaySlug as i, resolveDiscordChannelPolicyCommandAuthorizer as l, resolveDiscordOwnerAccess as m, isDiscordGroupAllowedByPolicy as n, resolveDiscordAllowListMatch as o, resolveDiscordMemberAllowed as p, normalizeDiscordAllowList as r, resolveDiscordChannelConfig as s, allowListMatches as t, resolveDiscordCommandAuthorized as u, shouldEmitDiscordReactionNotification as v, resolveDiscordSystemLocation as x, formatDiscordReactionEmoji as y };
package/dist/api.js CHANGED
@@ -1,25 +1,23 @@
1
- import { a as mergeDiscordAccountConfig, f as resolveDiscordMaxLinesPerMessage, i as listEnabledDiscordAccounts, l as resolveDiscordAccountConfig, o as resolveDefaultDiscordAccountId, r as listDiscordAccountIds, s as resolveDiscordAccount, t as createDiscordActionGate } from "./accounts-BcwyaFd-.js";
2
- import { t as inspectDiscordAccount } from "./account-inspect-D7jL5YDH.js";
3
- import { n as resolveDiscordChannelId, t as parseDiscordTarget } from "./target-parsing-D-H7nnh2.js";
4
- import { n as fetchDiscord, r as requestDiscord, t as DiscordApiError } from "./api-DzNBVTto.js";
5
- import { i as normalizeDiscordOutboundTarget, n as looksLikeDiscordTargetId, r as normalizeDiscordMessagingTarget } from "./normalize-Cu94FOqy.js";
6
- import { i as parseDiscordSendTarget, n as resolveDiscordTarget } from "./target-resolver-CgJei-kD.js";
7
- import { _ as parseDiscordModalCustomIdForInteraction, a as buildDiscordComponentMessage, c as readDiscordComponentSpec, d as DISCORD_MODAL_CUSTOM_ID_KEY, f as buildDiscordComponentCustomId, g as parseDiscordModalCustomId, h as parseDiscordComponentCustomIdForInteraction, i as createDiscordFormModal, l as resolveDiscordComponentAttachmentName, m as parseDiscordComponentCustomId, n as formatDiscordComponentEventText, o as buildDiscordComponentMessageFlags, p as buildDiscordModalCustomId, r as DiscordFormModal, s as DISCORD_COMPONENT_ATTACHMENT_PREFIX, u as DISCORD_COMPONENT_CUSTOM_ID_KEY } from "./components-Dxq2mU57.js";
8
- import { t as buildDiscordInteractiveComponents } from "./shared-interactive-DavY6jYt.js";
9
- import "./targets-DToZUkgV.js";
10
- import { a as shouldSuppressLocalDiscordExecApprovalPrompt, i as isDiscordExecApprovalClientEnabled, n as getDiscordExecApprovalApprovers, r as isDiscordExecApprovalApprover } from "./approval-shared-BFnWKSQD.js";
11
- import { i as resolveDiscordGroupToolPolicy, n as collectDiscordStatusIssues, r as resolveDiscordGroupRequireMention, t as discordPlugin } from "./channel-Bliqi-Qi.js";
12
- import { t as normalizeExplicitDiscordSessionKey } from "./session-key-normalization-BV82IME9.js";
13
- import { t as discordSetupPlugin } from "./channel.setup-DR-xVYso.js";
14
- import { n as handleDiscordSubagentEnded, r as handleDiscordSubagentSpawning, t as handleDiscordSubagentDeliveryTarget } from "./subagent-hooks-CtN-hfXy.js";
15
- import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-C4phin-a.js";
16
- import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-CDl4JTCA.js";
17
- import { t as fetchPluralKitMessageInfo } from "./pluralkit-B1HTaBc9.js";
18
- import { a as resolveDiscordPrivilegedIntentsFromFlags, i as probeDiscord, n as fetchDiscordApplicationSummary, r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-BZtr8qle.js";
19
- import { t as collectDiscordSecurityAuditFindings } from "./security-audit-BQ_sGK3J.js";
20
- import { a as mergeAbortSignals, i as DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, r as DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-C3FYXWJX.js";
1
+ import { Ht as parseDiscordTarget, Ut as resolveDiscordChannelId, a as normalizeDiscordMessagingTarget, i as looksLikeDiscordTargetId, o as normalizeDiscordOutboundTarget } from "./send.receipt-nKLxvA1s.js";
2
+ import { a as mergeDiscordAccountConfig, f as resolveDiscordMaxLinesPerMessage, i as listEnabledDiscordAccounts, l as resolveDiscordAccountConfig, o as resolveDefaultDiscordAccountId, r as listDiscordAccountIds, s as resolveDiscordAccount, t as createDiscordActionGate } from "./accounts-DnNVBDfc.js";
3
+ import { t as inspectDiscordAccount } from "./account-inspect-B_N30NV0.js";
4
+ import { _ as parseDiscordComponentCustomId, b as parseDiscordModalCustomIdForInteraction, c as buildDiscordComponentMessage, d as readDiscordComponentSpec, f as resolveDiscordComponentAttachmentName, g as buildDiscordModalCustomId, h as buildDiscordComponentCustomId, l as buildDiscordComponentMessageFlags, m as DISCORD_MODAL_CUSTOM_ID_KEY, n as formatDiscordComponentEventText, o as DiscordFormModal, p as DISCORD_COMPONENT_CUSTOM_ID_KEY, r as buildDiscordInteractiveComponents, s as createDiscordFormModal, u as DISCORD_COMPONENT_ATTACHMENT_PREFIX, v as parseDiscordComponentCustomIdForInteraction, y as parseDiscordModalCustomId } from "./components-Cgm7XT8-.js";
5
+ import { n as fetchDiscord, r as requestDiscord, t as DiscordApiError } from "./api-DgQLz1wq.js";
6
+ import { i as parseDiscordSendTarget, n as resolveDiscordTarget } from "./target-resolver-BsGT9hI7.js";
7
+ import "./targets-DwW6OieO.js";
8
+ import { a as getDiscordExecApprovalApprovers, c as shouldSuppressLocalDiscordExecApprovalPrompt, o as isDiscordExecApprovalApprover, s as isDiscordExecApprovalClientEnabled } from "./conversation-identity-C3AI-1tz.js";
9
+ import { i as resolveDiscordGroupToolPolicy, n as collectDiscordStatusIssues, r as resolveDiscordGroupRequireMention, t as discordPlugin } from "./channel-BjBa8nYY.js";
10
+ import { t as normalizeExplicitDiscordSessionKey } from "./session-key-normalization-B7h83qD2.js";
11
+ import { t as discordSetupPlugin } from "./channel.setup-DBFcGRFD.js";
12
+ import { n as handleDiscordSubagentEnded, r as handleDiscordSubagentSpawning, t as handleDiscordSubagentDeliveryTarget } from "./subagent-hooks-DhuBhwRw.js";
13
+ import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-DriifPwO.js";
14
+ import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-CW_JusGS.js";
15
+ import { t as fetchPluralKitMessageInfo } from "./pluralkit-B2AqgTHV.js";
16
+ import { a as resolveDiscordPrivilegedIntentsFromFlags, i as probeDiscord, n as fetchDiscordApplicationSummary, r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-CiBYm-vD.js";
17
+ import { t as collectDiscordSecurityAuditFindings } from "./security-audit-CLPZKYi4.js";
18
+ import { a as mergeAbortSignals, i as DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, r as DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-snXNwR4m.js";
21
19
  import { resolveOpenProviderRuntimeGroupPolicy as resolveDiscordRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
22
20
  //#region extensions/discord/api.ts
23
- const handleDiscordMessageAction = async (...args) => (await import("./channel-actions.runtime-DcsRvPnx.js")).handleDiscordMessageAction(...args);
21
+ const handleDiscordMessageAction = async (...args) => (await import("./channel-actions.runtime-CpIslHS9.js")).handleDiscordMessageAction(...args);
24
22
  //#endregion
25
23
  export { DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS, DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, DISCORD_COMPONENT_ATTACHMENT_PREFIX, DISCORD_COMPONENT_CUSTOM_ID_KEY, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, DISCORD_MODAL_CUSTOM_ID_KEY, DiscordApiError, DiscordFormModal, buildDiscordComponentCustomId, buildDiscordComponentMessage, buildDiscordComponentMessageFlags, buildDiscordInteractiveComponents, buildDiscordModalCustomId, collectDiscordSecurityAuditFindings, collectDiscordStatusIssues, createDiscordActionGate, createDiscordFormModal, discordPlugin, discordSetupPlugin, fetchDiscord, fetchDiscordApplicationId, fetchDiscordApplicationSummary, fetchPluralKitMessageInfo, formatDiscordComponentEventText, getDiscordExecApprovalApprovers, handleDiscordMessageAction, handleDiscordSubagentDeliveryTarget, handleDiscordSubagentEnded, handleDiscordSubagentSpawning, inspectDiscordAccount, isDiscordExecApprovalApprover, isDiscordExecApprovalClientEnabled, listDiscordAccountIds, listDiscordDirectoryGroupsFromConfig, listDiscordDirectoryPeersFromConfig, listEnabledDiscordAccounts, looksLikeDiscordTargetId, mergeAbortSignals, mergeDiscordAccountConfig, normalizeDiscordMessagingTarget, normalizeDiscordOutboundTarget, normalizeExplicitDiscordSessionKey, parseApplicationIdFromToken, parseDiscordComponentCustomId, parseDiscordComponentCustomIdForInteraction as parseDiscordComponentCustomIdForCarbon, parseDiscordComponentCustomIdForInteraction, parseDiscordModalCustomId, parseDiscordModalCustomIdForInteraction as parseDiscordModalCustomIdForCarbon, parseDiscordModalCustomIdForInteraction, parseDiscordSendTarget, parseDiscordTarget, probeDiscord, readDiscordComponentSpec, requestDiscord, resolveDefaultDiscordAccountId, resolveDiscordAccount, resolveDiscordAccountConfig, resolveDiscordChannelId, resolveDiscordComponentAttachmentName, resolveDiscordGroupRequireMention, resolveDiscordGroupToolPolicy, resolveDiscordMaxLinesPerMessage, resolveDiscordPrivilegedIntentsFromFlags, resolveDiscordRuntimeGroupPolicy, resolveDiscordTarget, shouldSuppressLocalDiscordExecApprovalPrompt, tryHandleDiscordMessageActionGuildAdmin };
@@ -1,7 +1,7 @@
1
- import { Ft as __exportAll, N as Container, T as serializePayload, U as TextDisplay, V as Separator, Y as createUserDmChannel, at as editChannelMessage, et as createChannelMessage, j as Button, rt as deleteChannelMessage, z as Row } from "./discord-BqYcwxvG.js";
2
- import { t as inspectDiscordAccount } from "./account-inspect-D7jL5YDH.js";
3
- import { A as createDiscordClient, y as stripUndefinedFields } from "./send.shared-Dza0jdso.js";
4
- import { i as isDiscordExecApprovalClientEnabled, t as shouldHandleDiscordApprovalRequest } from "./approval-shared-BFnWKSQD.js";
1
+ import { B as Container, J as Separator, K as Row, M as serializePayload, R as Button, Wt as __exportAll, X as TextDisplay, ft as editChannelMessage, nt as createUserDmChannel, st as createChannelMessage, ut as deleteChannelMessage } from "./send.receipt-nKLxvA1s.js";
2
+ import { t as inspectDiscordAccount } from "./account-inspect-B_N30NV0.js";
3
+ import { j as createDiscordClient, y as stripUndefinedFields } from "./send.shared-DSpva7uA.js";
4
+ import { i as shouldHandleDiscordApprovalRequest, s as isDiscordExecApprovalClientEnabled } from "./conversation-identity-C3AI-1tz.js";
5
5
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  import { ButtonStyle } from "discord-api-types/v10";
7
7
  import { logDebug, logError } from "openclaw/plugin-sdk/logging-core";
@@ -1,8 +1,8 @@
1
- import { Ft as __exportAll } from "./discord-BqYcwxvG.js";
2
- import { t as inspectDiscordAccount } from "./account-inspect-D7jL5YDH.js";
3
- import { T as fetchChannelPermissionsDiscord } from "./send.shared-Dza0jdso.js";
4
- import "./send-DCFuSiBi.js";
5
- import { n as collectDiscordAuditChannelIdsForAccount, t as auditDiscordChannelPermissionsWithFetcher } from "./audit-core-BgDZSkIR.js";
1
+ import { Wt as __exportAll } from "./send.receipt-nKLxvA1s.js";
2
+ import { t as inspectDiscordAccount } from "./account-inspect-B_N30NV0.js";
3
+ import { T as fetchChannelPermissionsDiscord } from "./send.shared-DSpva7uA.js";
4
+ import "./send-BqzTEkt9.js";
5
+ import { n as collectDiscordAuditChannelIdsForAccount, t as auditDiscordChannelPermissionsWithFetcher } from "./audit-core-DRyoXREU.js";
6
6
  //#region extensions/discord/src/audit.ts
7
7
  var audit_exports = /* @__PURE__ */ __exportAll({
8
8
  auditDiscordChannelPermissions: () => auditDiscordChannelPermissions,
@@ -1,18 +1,15 @@
1
- import { c as resolveDiscordAccountAllowFrom, r as listDiscordAccountIds, s as resolveDiscordAccount } from "./accounts-BcwyaFd-.js";
2
- import { a as projectCredentialSnapshotFields, n as PAIRING_APPROVED_MESSAGE, o as resolveConfiguredFromCredentialStatuses, r as buildTokenChannelStatusSummary, t as DEFAULT_ACCOUNT_ID } from "./channel-api-CTSWMrnD.js";
3
- import { t as parseDiscordTarget } from "./target-parsing-D-H7nnh2.js";
4
- import { t as resolveDiscordOutboundSessionRoute } from "./outbound-session-route-BaJRt05p.js";
5
- import { n as looksLikeDiscordTargetId, r as normalizeDiscordMessagingTarget } from "./normalize-Cu94FOqy.js";
6
- import { t as getDiscordRuntime } from "./runtime-BqCoo-zp.js";
7
- import { a as shouldSuppressLocalDiscordExecApprovalPrompt } from "./approval-shared-BFnWKSQD.js";
8
- import { t as getDiscordApprovalCapability } from "./approval-native-Gtqpyfdj.js";
9
- import { r as resolveRequiredDiscordChannelPermissions } from "./audit-core-BgDZSkIR.js";
10
- import { t as discordMessageActions$1 } from "./channel-actions-Cn_K00Vy.js";
11
- import { n as resolveDiscordCurrentConversationIdentity } from "./conversation-identity-CvIx6J7M.js";
12
- import { n as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-D18cCLmN.js";
13
- import { n as discordOutbound } from "./outbound-adapter-lWjkSeyP.js";
14
- import { i as discordSecurityAdapter, n as discordConfigAdapter, r as discordSetupAdapter, t as createDiscordPluginBase } from "./shared-Yp_M6Cfp.js";
15
- import { t as normalizeExplicitDiscordSessionKey } from "./session-key-normalization-BV82IME9.js";
1
+ import { Ht as parseDiscordTarget, a as normalizeDiscordMessagingTarget, i as looksLikeDiscordTargetId } from "./send.receipt-nKLxvA1s.js";
2
+ import { c as resolveDiscordAccountAllowFrom, r as listDiscordAccountIds, s as resolveDiscordAccount } from "./accounts-DnNVBDfc.js";
3
+ import { a as projectCredentialSnapshotFields, n as PAIRING_APPROVED_MESSAGE, o as resolveConfiguredFromCredentialStatuses, r as buildTokenChannelStatusSummary, t as DEFAULT_ACCOUNT_ID } from "./channel-api-JudoSiJv.js";
4
+ import { x as resolveDiscordOutboundSessionRoute } from "./components-Cgm7XT8-.js";
5
+ import { t as getDiscordRuntime } from "./runtime-Tqtvj5GX.js";
6
+ import { c as shouldSuppressLocalDiscordExecApprovalPrompt, n as resolveDiscordCurrentConversationIdentity, r as getDiscordApprovalCapability } from "./conversation-identity-C3AI-1tz.js";
7
+ import { r as resolveRequiredDiscordChannelPermissions } from "./audit-core-DRyoXREU.js";
8
+ import { t as discordMessageActions$1 } from "./channel-actions-DANVAtKL.js";
9
+ import { n as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-ZnRRzzgf.js";
10
+ import { n as discordOutbound } from "./outbound-adapter-Cw9JsRTY.js";
11
+ import { a as discordSecurityAdapter, i as discordSetupAdapter, n as discordConfigAdapter, t as createDiscordPluginBase } from "./shared-0kdaIxXP.js";
12
+ import { t as normalizeExplicitDiscordSessionKey } from "./session-key-normalization-B7h83qD2.js";
16
13
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
17
14
  import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
18
15
  import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
@@ -129,29 +126,29 @@ let discordProbeRuntimePromise;
129
126
  let discordAuditModulePromise;
130
127
  let discordSendModulePromise;
131
128
  let discordDirectoryLiveModulePromise;
132
- const loadDiscordDirectoryConfigModule = createLazyRuntimeModule(() => import("./directory-config-CDl4JTCA.js").then((n) => n.t));
133
- const loadDiscordResolveChannelsModule = createLazyRuntimeModule(() => import("./resolve-channels-JNt3Ak6P.js").then((n) => n.n));
134
- const loadDiscordResolveUsersModule = createLazyRuntimeModule(() => import("./resolve-users-CrjbUxrL.js").then((n) => n.n));
135
- const loadDiscordThreadBindingsManagerModule = createLazyRuntimeModule(() => import("./thread-bindings.manager-DNFl10CA.js").then((n) => n.a));
136
- const loadDiscordTargetResolverModule = createLazyRuntimeModule(() => import("./target-resolver-CgJei-kD.js").then((n) => n.r));
129
+ const loadDiscordDirectoryConfigModule = createLazyRuntimeModule(() => import("./directory-config-CW_JusGS.js").then((n) => n.t));
130
+ const loadDiscordResolveChannelsModule = createLazyRuntimeModule(() => import("./resolve-channels-u7_agBcm.js").then((n) => n.n));
131
+ const loadDiscordResolveUsersModule = createLazyRuntimeModule(() => import("./resolve-users-Bc25I6OP.js").then((n) => n.n));
132
+ const loadDiscordThreadBindingsManagerModule = createLazyRuntimeModule(() => import("./thread-bindings.manager-DN_q0IW7.js").then((n) => n.a));
133
+ const loadDiscordTargetResolverModule = createLazyRuntimeModule(() => import("./target-resolver-BsGT9hI7.js").then((n) => n.r));
137
134
  async function loadDiscordProviderRuntime() {
138
- discordProviderRuntimePromise ??= import("./provider.runtime-Cmv1SFtb.js");
135
+ discordProviderRuntimePromise ??= import("./provider.runtime-S-wZdzK5.js");
139
136
  return await discordProviderRuntimePromise;
140
137
  }
141
138
  async function loadDiscordProbeRuntime() {
142
- discordProbeRuntimePromise ??= import("./probe.runtime-0F0UzBoJ.js");
139
+ discordProbeRuntimePromise ??= import("./probe.runtime-9hi1GYNU.js");
143
140
  return await discordProbeRuntimePromise;
144
141
  }
145
142
  async function loadDiscordAuditModule() {
146
- discordAuditModulePromise ??= import("./audit-BliEqCEc.js").then((n) => n.n);
143
+ discordAuditModulePromise ??= import("./audit-eSlKbMHw.js").then((n) => n.n);
147
144
  return await discordAuditModulePromise;
148
145
  }
149
146
  async function loadDiscordSendModule() {
150
- discordSendModulePromise ??= import("./send-DCFuSiBi.js").then((n) => n.t);
147
+ discordSendModulePromise ??= import("./send-BqzTEkt9.js").then((n) => n.t);
151
148
  return await discordSendModulePromise;
152
149
  }
153
150
  async function loadDiscordDirectoryLiveModule() {
154
- discordDirectoryLiveModulePromise ??= import("./directory-live-ApUXOSj0.js").then((n) => n.t);
151
+ discordDirectoryLiveModulePromise ??= import("./directory-live-MrDSKsMf.js").then((n) => n.t);
155
152
  return await discordDirectoryLiveModulePromise;
156
153
  }
157
154
  //#endregion
@@ -727,6 +724,7 @@ const discordPlugin = createChatChannelPlugin({
727
724
  }),
728
725
  gateway: { startAccount: async (ctx) => {
729
726
  const account = ctx.account;
727
+ if (account.tokenStatus === "configured_unavailable") throw new Error(`Discord bot token configured for account "${account.accountId}" is unavailable; resolve SecretRefs against the active runtime snapshot before using this account.`);
730
728
  const startupDelayMs = resolveDiscordStartupDelayMs(ctx.cfg, account.accountId);
731
729
  if (startupDelayMs > 0) {
732
730
  ctx.log?.info(`[${account.accountId}] delaying provider startup ${Math.round(startupDelayMs / 1e3)}s to reduce Discord startup rate limits`);
@@ -1,13 +1,13 @@
1
- import { r as listDiscordAccountIds, t as createDiscordActionGate } from "./accounts-BcwyaFd-.js";
2
- import { t as inspectDiscordAccount } from "./account-inspect-D7jL5YDH.js";
3
- import { c as readDiscordComponentSpec } from "./components-Dxq2mU57.js";
1
+ import { r as listDiscordAccountIds, t as createDiscordActionGate } from "./accounts-DnNVBDfc.js";
2
+ import { t as inspectDiscordAccount } from "./account-inspect-B_N30NV0.js";
3
+ import { d as readDiscordComponentSpec } from "./components-Cgm7XT8-.js";
4
4
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { createUnionActionGate } from "openclaw/plugin-sdk/channel-actions";
6
6
  import { extractToolSend } from "openclaw/plugin-sdk/tool-send";
7
7
  //#region extensions/discord/src/channel-actions.ts
8
8
  let discordChannelActionsRuntimePromise;
9
9
  async function loadDiscordChannelActionsRuntime() {
10
- discordChannelActionsRuntimePromise ??= import("./channel-actions.runtime-DcsRvPnx.js");
10
+ discordChannelActionsRuntimePromise ??= import("./channel-actions.runtime-CpIslHS9.js");
11
11
  return await discordChannelActionsRuntimePromise;
12
12
  }
13
13
  function listDiscoverableDiscordAccounts(cfg) {
@@ -1,9 +1,9 @@
1
- import { n as resolveDiscordChannelId } from "./target-parsing-D-H7nnh2.js";
2
- import { t as handleDiscordAction } from "./runtime-CdnAT8R5.js";
3
- import { n as buildDiscordPresentationComponents, t as buildDiscordInteractiveComponents } from "./shared-interactive-DavY6jYt.js";
4
- import "./targets-DToZUkgV.js";
1
+ import { Ut as resolveDiscordChannelId } from "./send.receipt-nKLxvA1s.js";
2
+ import { i as buildDiscordPresentationComponents, r as buildDiscordInteractiveComponents } from "./components-Cgm7XT8-.js";
3
+ import { t as handleDiscordAction } from "./runtime-DL82ijB1.js";
4
+ import "./targets-DwW6OieO.js";
5
5
  import "./action-runtime-api.js";
6
- import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-C4phin-a.js";
6
+ import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-DriifPwO.js";
7
7
  import { normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
9
9
  import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
@@ -53,11 +53,13 @@ async function handleDiscordMessageAction(ctx) {
53
53
  const silent = readBooleanParam(params, "silent") === true;
54
54
  const sessionKey = readStringParam(params, "__sessionKey");
55
55
  const agentId = readStringParam(params, "__agentId");
56
+ const threadName = readStringParam(params, "threadName");
56
57
  return await handleDiscordAction({
57
58
  action: "sendMessage",
58
59
  accountId: accountId ?? void 0,
59
60
  to,
60
61
  content: content ?? "",
62
+ ...threadName ? { threadName } : {},
61
63
  mediaUrl: mediaUrl ?? void 0,
62
64
  filename: filename ?? void 0,
63
65
  replyTo: replyTo ?? void 0,
@@ -1,2 +1,2 @@
1
- import { t as DiscordChannelConfigSchema } from "./config-schema-D2KGskAp.js";
1
+ import { t as DiscordChannelConfigSchema } from "./config-schema-D7AtCpJa.js";
2
2
  export { DiscordChannelConfigSchema };
@@ -1,2 +1,2 @@
1
- import { t as discordPlugin } from "./channel-Bliqi-Qi.js";
1
+ import { t as discordPlugin } from "./channel-BjBa8nYY.js";
2
2
  export { discordPlugin };
@@ -1,8 +1,7 @@
1
- import { n as resolveDiscordToken } from "./token-BZtonk7d.js";
2
- import { a as mergeDiscordAccountConfig, c as resolveDiscordAccountAllowFrom, l as resolveDiscordAccountConfig, o as resolveDefaultDiscordAccountId } from "./accounts-BcwyaFd-.js";
3
- import { r as discordSetupAdapter, t as createDiscordPluginBase } from "./shared-Yp_M6Cfp.js";
4
- import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-JNt3Ak6P.js";
5
- import { t as resolveDiscordUserAllowlist } from "./resolve-users-CrjbUxrL.js";
1
+ import { a as mergeDiscordAccountConfig, c as resolveDiscordAccountAllowFrom, l as resolveDiscordAccountConfig, m as resolveDiscordToken, o as resolveDefaultDiscordAccountId } from "./accounts-DnNVBDfc.js";
2
+ import { i as discordSetupAdapter, t as createDiscordPluginBase } from "./shared-0kdaIxXP.js";
3
+ import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-u7_agBcm.js";
4
+ import { t as resolveDiscordUserAllowlist } from "./resolve-users-Bc25I6OP.js";
6
5
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
7
6
  import { hasConfiguredSecretInput, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
8
7
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -1,8 +1,49 @@
1
- import { A as TextInput, B as Section, D as Label, E as CheckboxGroup, F as LinkButton, Ft as __exportAll, G as UserSelectMenu, H as StringSelectMenu, I as MediaGallery, L as MentionableSelectMenu, M as ChannelSelectMenu, N as Container, O as Modal, P as File, R as RoleSelectMenu, U as TextDisplay, V as Separator, W as Thumbnail, j as Button, k as RadioGroup, q as parseCustomId, z as Row } from "./discord-BqYcwxvG.js";
2
- import { t as buildDiscordInteractiveComponents } from "./shared-interactive-DavY6jYt.js";
1
+ import { B as Container, F as Modal, G as RoleSelectMenu, H as LinkButton, Ht as parseDiscordTarget, I as RadioGroup, J as Separator, K as Row, L as TextInput, N as CheckboxGroup, P as Label, Q as UserSelectMenu, R as Button, U as MediaGallery, V as File, W as MentionableSelectMenu, Wt as __exportAll, X as TextDisplay, Y as StringSelectMenu, Z as Thumbnail, et as parseCustomId, q as Section, z as ChannelSelectMenu } from "./send.receipt-nKLxvA1s.js";
3
2
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
3
+ import { buildOutboundBaseSessionKey } from "openclaw/plugin-sdk/routing";
4
+ import { buildThreadAwareOutboundSessionRoute } from "openclaw/plugin-sdk/channel-core";
4
5
  import { ButtonStyle, MessageFlags, TextInputStyle } from "discord-api-types/v10";
5
6
  import crypto from "node:crypto";
7
+ import { presentationToInteractiveControlsReply, reduceInteractiveReply } from "openclaw/plugin-sdk/interactive-runtime";
8
+ //#region extensions/discord/src/outbound-session-route.ts
9
+ function resolveDiscordOutboundSessionRoute(params) {
10
+ const parsed = parseDiscordTarget(params.target, { defaultKind: resolveDiscordOutboundTargetKindHint(params) });
11
+ if (!parsed) return null;
12
+ const isDm = parsed.kind === "user";
13
+ const peer = {
14
+ kind: isDm ? "direct" : "channel",
15
+ id: parsed.id
16
+ };
17
+ const baseSessionKey = buildOutboundBaseSessionKey({
18
+ cfg: params.cfg,
19
+ agentId: params.agentId,
20
+ channel: "discord",
21
+ accountId: params.accountId,
22
+ peer
23
+ });
24
+ return buildThreadAwareOutboundSessionRoute({
25
+ route: {
26
+ sessionKey: baseSessionKey,
27
+ baseSessionKey,
28
+ peer,
29
+ chatType: isDm ? "direct" : "channel",
30
+ from: isDm ? `discord:${parsed.id}` : `discord:channel:${parsed.id}`,
31
+ to: isDm ? `user:${parsed.id}` : `channel:${parsed.id}`
32
+ },
33
+ threadId: params.threadId,
34
+ precedence: ["threadId"],
35
+ useSuffix: false
36
+ });
37
+ }
38
+ function resolveDiscordOutboundTargetKindHint(params) {
39
+ const resolvedKind = params.resolvedTarget?.kind;
40
+ if (resolvedKind === "user") return "user";
41
+ if (resolvedKind === "group" || resolvedKind === "channel") return "channel";
42
+ const target = params.target.trim();
43
+ if (/^channel:/i.test(target)) return "channel";
44
+ if (/^(user:|discord:|@|<@!?)/i.test(target)) return "user";
45
+ }
46
+ //#endregion
6
47
  //#region extensions/discord/src/component-custom-id.ts
7
48
  const DISCORD_COMPONENT_CUSTOM_ID_KEY = "occomp";
8
49
  const DISCORD_MODAL_CUSTOM_ID_KEY = "ocmodal";
@@ -728,6 +769,82 @@ function createDiscordFormModal(entry) {
728
769
  });
729
770
  }
730
771
  //#endregion
772
+ //#region extensions/discord/src/shared-interactive.ts
773
+ var shared_interactive_exports = /* @__PURE__ */ __exportAll({
774
+ buildDiscordInteractiveComponents: () => buildDiscordInteractiveComponents,
775
+ buildDiscordPresentationComponents: () => buildDiscordPresentationComponents
776
+ });
777
+ function resolveDiscordInteractiveButtonStyle(style) {
778
+ return style ?? "secondary";
779
+ }
780
+ const DISCORD_INTERACTIVE_BUTTON_ROW_SIZE = 5;
781
+ function buildDiscordInteractiveComponents(interactive) {
782
+ const blocks = reduceInteractiveReply(interactive, [], (state, block) => {
783
+ if (block.type === "text") {
784
+ const text = block.text.trim();
785
+ if (text) state.push({
786
+ type: "text",
787
+ text
788
+ });
789
+ return state;
790
+ }
791
+ if (block.type === "buttons") {
792
+ if (block.buttons.length === 0) return state;
793
+ for (let index = 0; index < block.buttons.length; index += DISCORD_INTERACTIVE_BUTTON_ROW_SIZE) state.push({
794
+ type: "actions",
795
+ buttons: block.buttons.slice(index, index + DISCORD_INTERACTIVE_BUTTON_ROW_SIZE).map((button) => {
796
+ const spec = {
797
+ label: button.label,
798
+ style: button.url ? "link" : resolveDiscordInteractiveButtonStyle(button.style)
799
+ };
800
+ if (button.value) spec.callbackData = button.value;
801
+ if (button.url) spec.url = button.url;
802
+ return spec;
803
+ })
804
+ });
805
+ return state;
806
+ }
807
+ if (block.type === "select" && block.options.length > 0) state.push({
808
+ type: "actions",
809
+ select: {
810
+ type: "string",
811
+ placeholder: block.placeholder,
812
+ options: block.options.map((option) => ({
813
+ label: option.label,
814
+ value: option.value
815
+ }))
816
+ }
817
+ });
818
+ return state;
819
+ });
820
+ return blocks.length > 0 ? { blocks } : void 0;
821
+ }
822
+ function buildDiscordPresentationComponents(presentation) {
823
+ if (!presentation) return;
824
+ const spec = { blocks: [] };
825
+ if (presentation.title) spec.blocks?.push({
826
+ type: "text",
827
+ text: presentation.title
828
+ });
829
+ for (const block of presentation.blocks) {
830
+ if (block.type === "text" || block.type === "context") {
831
+ const text = block.text.trim();
832
+ if (text) spec.blocks?.push({
833
+ type: "text",
834
+ text: block.type === "context" ? `-# ${text}` : text
835
+ });
836
+ continue;
837
+ }
838
+ if (block.type === "divider") {
839
+ spec.blocks?.push({ type: "separator" });
840
+ continue;
841
+ }
842
+ }
843
+ const interactiveSpec = buildDiscordInteractiveComponents(presentationToInteractiveControlsReply(presentation));
844
+ if (interactiveSpec?.blocks?.length) spec.blocks?.push(...interactiveSpec.blocks);
845
+ return spec.blocks?.length ? spec : void 0;
846
+ }
847
+ //#endregion
731
848
  //#region extensions/discord/src/components.ts
732
849
  var components_exports = /* @__PURE__ */ __exportAll({
733
850
  DISCORD_COMPONENT_ATTACHMENT_PREFIX: () => DISCORD_COMPONENT_ATTACHMENT_PREFIX,
@@ -756,4 +873,4 @@ function formatDiscordComponentEventText(params) {
756
873
  return `Selected ${values.join(", ")} from "${params.label}".`;
757
874
  }
758
875
  //#endregion
759
- export { parseDiscordModalCustomIdForInteraction as _, buildDiscordComponentMessage as a, readDiscordComponentSpec as c, DISCORD_MODAL_CUSTOM_ID_KEY as d, buildDiscordComponentCustomId as f, parseDiscordModalCustomId as g, parseDiscordComponentCustomIdForInteraction as h, createDiscordFormModal as i, resolveDiscordComponentAttachmentName as l, parseDiscordComponentCustomId as m, formatDiscordComponentEventText as n, buildDiscordComponentMessageFlags as o, buildDiscordModalCustomId as p, DiscordFormModal as r, DISCORD_COMPONENT_ATTACHMENT_PREFIX as s, components_exports as t, DISCORD_COMPONENT_CUSTOM_ID_KEY as u };
876
+ export { parseDiscordComponentCustomId as _, shared_interactive_exports as a, parseDiscordModalCustomIdForInteraction as b, buildDiscordComponentMessage as c, readDiscordComponentSpec as d, resolveDiscordComponentAttachmentName as f, buildDiscordModalCustomId as g, buildDiscordComponentCustomId as h, buildDiscordPresentationComponents as i, buildDiscordComponentMessageFlags as l, DISCORD_MODAL_CUSTOM_ID_KEY as m, formatDiscordComponentEventText as n, DiscordFormModal as o, DISCORD_COMPONENT_CUSTOM_ID_KEY as p, buildDiscordInteractiveComponents as r, createDiscordFormModal as s, components_exports as t, DISCORD_COMPONENT_ATTACHMENT_PREFIX as u, parseDiscordComponentCustomIdForInteraction as v, resolveDiscordOutboundSessionRoute as x, parseDiscordModalCustomId as y };
@@ -1,4 +1,4 @@
1
- import { n as buildChannelConfigSchema, t as DiscordConfigSchema } from "./config-api-CFZtoMaS.js";
1
+ import { n as buildChannelConfigSchema, t as DiscordConfigSchema } from "./config-api-oLS_52S7.js";
2
2
  //#endregion
3
3
  //#region extensions/discord/src/config-schema.ts
4
4
  const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordConfigSchema, { uiHints: {
@@ -311,6 +311,26 @@ const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordConfigSchema,
311
311
  label: "Discord Allow Bot Messages",
312
312
  help: "Allow bot-authored messages to trigger Discord replies (default: false). Set \"mentions\" to only accept bot messages that mention the bot."
313
313
  },
314
+ botLoopProtection: {
315
+ label: "Discord Bot Loop Protection",
316
+ help: "Sliding-window guard for bot-to-bot Discord loops. Default is enabled whenever allowBots lets bot-authored messages reach dispatch."
317
+ },
318
+ "botLoopProtection.enabled": {
319
+ label: "Discord Bot Loop Protection Enabled",
320
+ help: "Enable the bot-pair loop guard. Defaults to true when allowBots is true or \"mentions\", and false when bot messages are ignored."
321
+ },
322
+ "botLoopProtection.maxEventsPerWindow": {
323
+ label: "Discord Bot Pair Events Per Window",
324
+ help: "Maximum messages a single Discord bot pair may exchange in the configured window before suppression starts. Default: 20."
325
+ },
326
+ "botLoopProtection.windowSeconds": {
327
+ label: "Discord Bot Loop Window Seconds",
328
+ help: "Sliding window length in seconds for Discord bot-pair loop budgets. Default: 60."
329
+ },
330
+ "botLoopProtection.cooldownSeconds": {
331
+ label: "Discord Bot Loop Cooldown Seconds",
332
+ help: "Seconds to suppress a Discord bot pair after it exceeds the loop budget. Default: 60."
333
+ },
314
334
  mentionAliases: {
315
335
  label: "Discord Mention Aliases",
316
336
  help: "Map outbound @handle text to stable Discord user IDs before sending. Set per account via channels.discord.accounts.<id>.mentionAliases."
@@ -1,8 +1,8 @@
1
- import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-BGjjFBdq.js";
2
- import { n as secretTargetRegistryEntries, t as collectRuntimeConfigAssignments } from "./secret-config-contract-BCQNNS7N.js";
3
- import { n as unsupportedSecretRefSurfacePatterns, t as collectUnsupportedSecretRefConfigCandidates } from "./security-contract-DkCMKSvb.js";
4
- import { t as deriveLegacySessionChatType } from "./session-contract-D871HDFG.js";
5
- import { r as createThreadBindingManager, t as __testing } from "./thread-bindings.manager-DNFl10CA.js";
6
- import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-CDl4JTCA.js";
7
- import { t as collectDiscordSecurityAuditFindings } from "./security-audit-BQ_sGK3J.js";
1
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-ftWAMvBl.js";
2
+ import { n as secretTargetRegistryEntries, t as collectRuntimeConfigAssignments } from "./secret-config-contract-B3347_eU.js";
3
+ import { n as unsupportedSecretRefSurfacePatterns, t as collectUnsupportedSecretRefConfigCandidates } from "./security-contract-DyCRvz_Q.js";
4
+ import { t as deriveLegacySessionChatType } from "./session-contract-ugfEa9Xc.js";
5
+ import { r as createThreadBindingManager, t as __testing } from "./thread-bindings.manager-DN_q0IW7.js";
6
+ import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-CW_JusGS.js";
7
+ import { t as collectDiscordSecurityAuditFindings } from "./security-audit-CLPZKYi4.js";
8
8
  export { collectDiscordSecurityAuditFindings, collectRuntimeConfigAssignments, collectUnsupportedSecretRefConfigCandidates, createThreadBindingManager, deriveLegacySessionChatType, __testing as discordThreadBindingTesting, legacyConfigRules, listDiscordDirectoryGroupsFromConfig, listDiscordDirectoryPeersFromConfig, normalizeCompatibilityConfig, secretTargetRegistryEntries, unsupportedSecretRefSurfacePatterns };