@openclaw/discord 2026.9.3 → 2026.9.4

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 (46) hide show
  1. package/dist/action-runtime-api.js +1 -1
  2. package/dist/{activities-api-D--xtQQu.js → activities-api-w8j7Elou.js} +4 -4
  3. package/dist/activities-api.js +1 -1
  4. package/dist/api.js +9 -9
  5. package/dist/{approval-handler.runtime-CUNkTLDO.js → approval-handler.runtime-BnPUU5NK.js} +4 -4
  6. package/dist/{audit-DzHj2Z4w.js → audit-BgAgIzwo.js} +3 -3
  7. package/dist/{channel-aAywxCij.js → channel-C_OFFR5Y.js} +12 -11
  8. package/dist/{channel-actions.runtime-rmse1yrM.js → channel-actions.runtime-tShzmemq.js} +7 -7
  9. package/dist/channel-plugin-api.js +1 -1
  10. package/dist/{components-kvIwhN7i.js → components-DBFTIN6P.js} +1 -0
  11. package/dist/{conversation-binding-route-qfe7oPy5.js → conversation-binding-route-CB9PRqgi.js} +1 -1
  12. package/dist/doctor-contract-api.js +2 -1
  13. package/dist/{handle-action.guild-admin-D4XdoA8-.js → handle-action.guild-admin-CpEwox_X.js} +2 -2
  14. package/dist/index.js +1 -1
  15. package/dist/{message-handler-B0DbuhWz.js → message-handler-C7FZGKa8.js} +5 -4
  16. package/dist/{message-handler.preflight-BkHVlYis.js → message-handler.preflight-DFpwDW2W.js} +5 -4
  17. package/dist/{message-handler.process-CWh432Ak.js → message-handler.process-ZKrmmA9D.js} +12 -12
  18. package/dist/{outbound-adapter-CO2BRlRl.js → outbound-adapter-C8PTt7_p.js} +6 -6
  19. package/dist/{outbound-components-BvskBqEN.js → outbound-components-DrlHcWfM.js} +3 -3
  20. package/dist/{outbound-session-route-DZBYPGTR.js → outbound-session-route-B0N6os97.js} +3 -3
  21. package/dist/{presence-cache-z1N8MbJ3.js → presence-cache-dYSHPWMx.js} +1 -1
  22. package/dist/{provider-PI8UiejY.js → provider-DmRHCZ_K.js} +22 -15
  23. package/dist/{provider-session.runtime-BejUb3gm.js → provider-session.runtime-U1M8_EYY.js} +3 -3
  24. package/dist/provider.runtime-CqfE-RvC.js +2 -0
  25. package/dist/{realtime-session.runtime-MqPrvmQ1.js → realtime-session.runtime-Bjsk9Q5t.js} +1 -1
  26. package/dist/{retry-B0lQ1Ado.js → retry-DKeoT7UO.js} +9 -4
  27. package/dist/{runtime-D-ZFlMQ2.js → runtime-CbknwoBH.js} +1 -1
  28. package/dist/{runtime-Cv8GdXSO.js → runtime-Dxl-ZOvg.js} +8 -8
  29. package/dist/runtime-api.js +14 -14
  30. package/dist/{send-Bdp3zZH5.js → send-CLpzfzJe.js} +3 -3
  31. package/dist/{send.components-Bj22B3_O.js → send.components-BWnkX4QN.js} +20 -45
  32. package/dist/{send.outbound-DF0P3C9J.js → send.outbound-BVTWrl_4.js} +2 -2
  33. package/dist/{send.shared-D4BAjlRo.js → send.shared-BHPM3CSl.js} +2 -2
  34. package/dist/{subagent-hooks-BAwybBDC.js → subagent-hooks-DfsiwCec.js} +1 -1
  35. package/dist/subagent-hooks-api.js +1 -1
  36. package/dist/{target-resolver-BgKUUwLy.js → target-resolver-CoFQ7iSX.js} +1 -1
  37. package/dist/targets-Cm6aV9nJ.js +3 -0
  38. package/dist/{thread-bindings-B0wnEg_y.js → thread-bindings-uudC_0TY.js} +5 -5
  39. package/dist/{thread-bindings.manager-DM7M3vzn.js → thread-bindings.manager-BeUxc8nr.js} +5 -5
  40. package/dist/{thread-bindings.session-updates-CSBmgCcx.js → thread-bindings.session-updates-BwkXpcy0.js} +1 -1
  41. package/dist/{thread-bindings.state-jNRrsgzV.js → thread-bindings.state-dDn-dwBw.js} +2 -16
  42. package/dist/{voice-runtime-BhRqlbEt.js → voice-runtime-DMYDMkJx.js} +4 -4
  43. package/openclaw.plugin.json +4 -0
  44. package/package.json +5 -4
  45. package/dist/provider.runtime-C-Oh3OHA.js +0 -2
  46. package/dist/targets-fCxslBZ3.js +0 -3
@@ -1,2 +1,2 @@
1
- import { t as handleDiscordAction } from "./runtime-Cv8GdXSO.js";
1
+ import { t as handleDiscordAction } from "./runtime-Dxl-ZOvg.js";
2
2
  export { handleDiscordAction };
@@ -1,8 +1,8 @@
1
- import { S as parseDiscordActivityCustomId, i as buildDiscordPresentationComponents } from "./components-kvIwhN7i.js";
1
+ import { S as parseDiscordActivityCustomId, i as buildDiscordPresentationComponents } from "./components-DBFTIN6P.js";
2
2
  import { c as resolveDiscordAccount } from "./accounts-CwJQoLjM.js";
3
- import { r as sendDiscordComponentMessage } from "./send.components-Bj22B3_O.js";
4
- import { y as resolveDiscordChannelId$1 } from "./retry-B0lQ1Ado.js";
5
- import { r as setDiscordActivitiesRuntime, t as DiscordActivitiesRuntime } from "./runtime-D-ZFlMQ2.js";
3
+ import { r as sendDiscordComponentMessage } from "./send.components-BWnkX4QN.js";
4
+ import { y as resolveDiscordChannelId$1 } from "./retry-DKeoT7UO.js";
5
+ import { r as setDiscordActivitiesRuntime, t as DiscordActivitiesRuntime } from "./runtime-CbknwoBH.js";
6
6
  import fs from "node:fs/promises";
7
7
  import { logError } from "openclaw/plugin-sdk/logging-core";
8
8
  import { resolveRequestClientIp } from "openclaw/plugin-sdk/webhook-ingress";
@@ -1,2 +1,2 @@
1
- import { t as registerDiscordActivities } from "./activities-api-D--xtQQu.js";
1
+ import { t as registerDiscordActivities } from "./activities-api-w8j7Elou.js";
2
2
  export { registerDiscordActivities };
package/dist/api.js CHANGED
@@ -1,24 +1,24 @@
1
- import { D as parseDiscordModalCustomIdForInteraction, E as parseDiscordModalCustomId, T as parseDiscordComponentCustomIdForInteraction, _ as DISCORD_COMPONENT_CUSTOM_ID_KEY, b as buildDiscordComponentCustomId, d as buildDiscordComponentMessage, f as buildDiscordComponentMessageFlags, g as resolveDiscordComponentAttachmentName, h as readDiscordComponentSpec, l as DiscordFormModal, n as formatDiscordComponentEventText, p as DISCORD_COMPONENT_ATTACHMENT_PREFIX, r as buildDiscordInteractiveComponents, u as createDiscordFormModal, v as DISCORD_MODAL_CUSTOM_ID_KEY, w as parseDiscordComponentCustomId, x as buildDiscordModalCustomId } from "./components-kvIwhN7i.js";
1
+ import { D as parseDiscordModalCustomIdForInteraction, E as parseDiscordModalCustomId, T as parseDiscordComponentCustomIdForInteraction, _ as DISCORD_COMPONENT_CUSTOM_ID_KEY, b as buildDiscordComponentCustomId, d as buildDiscordComponentMessage, f as buildDiscordComponentMessageFlags, g as resolveDiscordComponentAttachmentName, h as readDiscordComponentSpec, l as DiscordFormModal, n as formatDiscordComponentEventText, p as DISCORD_COMPONENT_ATTACHMENT_PREFIX, r as buildDiscordInteractiveComponents, u as createDiscordFormModal, v as DISCORD_MODAL_CUSTOM_ID_KEY, w as parseDiscordComponentCustomId, x as buildDiscordModalCustomId } from "./components-DBFTIN6P.js";
2
2
  import { a as listEnabledDiscordAccounts, c as resolveDiscordAccount, o as mergeDiscordAccountConfig, p as resolveDiscordMaxLinesPerMessage, r as listDiscordAccountIds, s as resolveDefaultDiscordAccountId, t as createDiscordActionGate, u as resolveDiscordAccountConfig } from "./accounts-CwJQoLjM.js";
3
3
  import { i as requestDiscord, n as DiscordApiError, r as fetchDiscord } from "./api-LIV--eMq.js";
4
- import { _ as normalizeDiscordOutboundTarget, g as normalizeDiscordMessagingTarget, h as looksLikeDiscordTargetId, v as parseDiscordTarget, y as resolveDiscordChannelId } from "./retry-B0lQ1Ado.js";
5
- import { i as parseDiscordSendTarget, n as resolveDiscordTarget } from "./target-resolver-BgKUUwLy.js";
4
+ import { _ as normalizeDiscordOutboundTarget, g as normalizeDiscordMessagingTarget, h as looksLikeDiscordTargetId, v as parseDiscordTarget, y as resolveDiscordChannelId } from "./retry-DKeoT7UO.js";
5
+ import { i as parseDiscordSendTarget, n as resolveDiscordTarget } from "./target-resolver-CoFQ7iSX.js";
6
6
  import { t as inspectDiscordAccount } from "./account-inspect-BY-ve3yH.js";
7
7
  import { 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-D86uWLt_.js";
8
- import "./targets-fCxslBZ3.js";
9
- import { C as shouldSuppressLocalDiscordExecApprovalPrompt, S as isDiscordExecApprovalClientEnabled, b as getDiscordExecApprovalApprovers, x as isDiscordExecApprovalApprover } from "./outbound-session-route-DZBYPGTR.js";
10
- import { i as resolveDiscordGroupToolPolicy, n as collectDiscordStatusIssues, r as resolveDiscordGroupRequireMention, t as discordPlugin } from "./channel-aAywxCij.js";
8
+ import "./targets-Cm6aV9nJ.js";
9
+ import { C as shouldSuppressLocalDiscordExecApprovalPrompt, S as isDiscordExecApprovalClientEnabled, b as getDiscordExecApprovalApprovers, x as isDiscordExecApprovalApprover } from "./outbound-session-route-B0N6os97.js";
10
+ import { i as resolveDiscordGroupToolPolicy, n as collectDiscordStatusIssues, r as resolveDiscordGroupRequireMention, t as discordPlugin } from "./channel-C_OFFR5Y.js";
11
11
  import { t as normalizeExplicitDiscordSessionKey } from "./session-key-normalization-wJgsKPNF.js";
12
12
  import { t as discordSetupPlugin } from "./channel.setup-CpAwAiS0.js";
13
- import { n as handleDiscordSubagentEnded, t as handleDiscordSubagentDeliveryTarget } from "./subagent-hooks-BAwybBDC.js";
14
- import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-D4XdoA8-.js";
13
+ import { n as handleDiscordSubagentEnded, t as handleDiscordSubagentDeliveryTarget } from "./subagent-hooks-DfsiwCec.js";
14
+ import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-CpEwox_X.js";
15
15
  import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-D1uDGbWh.js";
16
16
  import { t as fetchPluralKitMessageInfo } from "./pluralkit-BiUW53Yn.js";
17
17
  import { i as probeDiscord, n as fetchDiscordApplicationSummary, o as resolveDiscordPrivilegedIntentsFromFlags, r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-BcoN44eK.js";
18
18
  import { t as collectDiscordSecurityAuditFindings } from "./security-audit-DKfK-iPY.js";
19
19
  import { resolveOpenProviderRuntimeGroupPolicy as resolveDiscordRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
20
20
  //#region extensions/discord/api.ts
21
- const handleDiscordMessageAction = async (...args) => (await import("./channel-actions.runtime-rmse1yrM.js")).handleDiscordMessageAction(...args);
21
+ const handleDiscordMessageAction = async (...args) => (await import("./channel-actions.runtime-tShzmemq.js")).handleDiscordMessageAction(...args);
22
22
  /**
23
23
  * @deprecated Shipped `@openclaw/discord/api` compatibility only. Use native
24
24
  * `AbortSignal.any` after filtering optional signals. Removal with the next
@@ -1,8 +1,8 @@
1
1
  import { $ as stripUndefinedFields, I as Button, J as TextDisplay, K as Separator, R as Container, W as Row, dt as editChannelMessage, k as serializePayload, lt as deleteChannelMessage, ot as createChannelMessage, tt as createUserDmChannel } from "./discord-CmL3ati-.js";
2
- import { s as buildExecApprovalCustomId } from "./components-kvIwhN7i.js";
3
- import { N as createDiscordClient, O as createDiscordMessageNonce } from "./send.shared-D4BAjlRo.js";
4
- import { S as isDiscordExecApprovalClientEnabled, n as DISCORD_APPROVAL_ALLOWED_MENTIONS, r as formatDiscordApprovalDisplayValue } from "./outbound-session-route-DZBYPGTR.js";
5
- import { a as shouldHandleDiscordApprovalRequest } from "./channel-aAywxCij.js";
2
+ import { s as buildExecApprovalCustomId } from "./components-DBFTIN6P.js";
3
+ import { N as createDiscordClient, O as createDiscordMessageNonce } from "./send.shared-BHPM3CSl.js";
4
+ import { S as isDiscordExecApprovalClientEnabled, n as DISCORD_APPROVAL_ALLOWED_MENTIONS, r as formatDiscordApprovalDisplayValue } from "./outbound-session-route-B0N6os97.js";
5
+ import { a as shouldHandleDiscordApprovalRequest } from "./channel-C_OFFR5Y.js";
6
6
  import { logDebug, logError } from "openclaw/plugin-sdk/logging-core";
7
7
  import { ButtonStyle } from "discord-api-types/v10";
8
8
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -1,8 +1,8 @@
1
1
  import { Ht as __exportAll } from "./discord-CmL3ati-.js";
2
- import { x as fetchChannelPermissionsDiscord } from "./send.shared-D4BAjlRo.js";
2
+ import { x as fetchChannelPermissionsDiscord } from "./send.shared-BHPM3CSl.js";
3
3
  import { t as inspectDiscordAccount } from "./account-inspect-BY-ve3yH.js";
4
- import "./send-Bdp3zZH5.js";
5
- import { _ as auditDiscordChannelPermissionsWithFetcher, v as collectDiscordAuditChannelIdsForAccount } from "./outbound-session-route-DZBYPGTR.js";
4
+ import "./send-CLpzfzJe.js";
5
+ import { _ as auditDiscordChannelPermissionsWithFetcher, v as collectDiscordAuditChannelIdsForAccount } from "./outbound-session-route-B0N6os97.js";
6
6
  //#region extensions/discord/src/audit.ts
7
7
  var audit_exports = /* @__PURE__ */ __exportAll({
8
8
  auditDiscordChannelPermissions: () => auditDiscordChannelPermissions,
@@ -1,13 +1,13 @@
1
1
  import { c as resolveDiscordAccount, i as listDiscordStartupAccountIds, l as resolveDiscordAccountAllowFrom, r as listDiscordAccountIds, s as resolveDefaultDiscordAccountId } from "./accounts-CwJQoLjM.js";
2
2
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
3
- import { g as normalizeDiscordMessagingTarget, h as looksLikeDiscordTargetId, v as parseDiscordTarget } from "./retry-B0lQ1Ado.js";
3
+ import { g as normalizeDiscordMessagingTarget, h as looksLikeDiscordTargetId, v as parseDiscordTarget } from "./retry-DKeoT7UO.js";
4
4
  import { u as withAbortTimeout } from "./timeouts-D86uWLt_.js";
5
- import { C as shouldSuppressLocalDiscordExecApprovalPrompt, D as isChannelExecApprovalClientEnabledFromConfig, E as createChannelNativeOriginTargetResolver, O as matchesApprovalRequestFilters, S as isDiscordExecApprovalClientEnabled, T as createChannelApproverDmTargetResolver, b as getDiscordExecApprovalApprovers, d as resolveDiscordCurrentConversationIdentity, f as resolveDiscordRuntimeBindingConversationId, p as discordMessageActions, s as resolveDiscordConversationRoute, t as resolveDiscordOutboundSessionRoute, w as createApproverRestrictedNativeApprovalCapability, x as isDiscordExecApprovalApprover, y as resolveRequiredDiscordChannelPermissions } from "./outbound-session-route-DZBYPGTR.js";
5
+ import { C as shouldSuppressLocalDiscordExecApprovalPrompt, D as isChannelExecApprovalClientEnabledFromConfig, E as createChannelNativeOriginTargetResolver, O as matchesApprovalRequestFilters, S as isDiscordExecApprovalClientEnabled, T as createChannelApproverDmTargetResolver, b as getDiscordExecApprovalApprovers, d as resolveDiscordCurrentConversationIdentity, f as resolveDiscordRuntimeBindingConversationId, p as discordMessageActions, s as resolveDiscordConversationRoute, t as resolveDiscordOutboundSessionRoute, w as createApproverRestrictedNativeApprovalCapability, x as isDiscordExecApprovalApprover, y as resolveRequiredDiscordChannelPermissions } from "./outbound-session-route-B0N6os97.js";
6
6
  import { a as discordSecurityAdapter, c as buildTokenChannelStatusSummary, i as discordSetupContract, l as projectCredentialSnapshotFields, n as discordConfigAdapter, o as DEFAULT_ACCOUNT_ID, s as PAIRING_APPROVED_MESSAGE, t as createDiscordPluginBase, u as resolveConfiguredFromCredentialStatuses } from "./shared-CPPR0Xo4.js";
7
7
  import { r as openDiscordCommandDeployHashStore } from "./command-deploy-store-DFkBTViB.js";
8
- import { t as resolveDiscordConversationBindingRoute } from "./conversation-binding-route-qfe7oPy5.js";
9
- import { n as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-CSBmgCcx.js";
10
- import { n as discordOutbound } from "./outbound-adapter-CO2BRlRl.js";
8
+ import { t as resolveDiscordConversationBindingRoute } from "./conversation-binding-route-CB9PRqgi.js";
9
+ import { n as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-BwkXpcy0.js";
10
+ import { n as discordOutbound } from "./outbound-adapter-C8PTt7_p.js";
11
11
  import { t as normalizeExplicitDiscordSessionKey } from "./session-key-normalization-wJgsKPNF.js";
12
12
  import { t as defaultTopLevelPlacement } from "./thread-binding-api-BDZJD4na.js";
13
13
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
@@ -182,6 +182,7 @@ function createDiscordApprovalCapability(configOverride) {
182
182
  resolveApproverDmTargets: createDiscordApproverDmTargetResolver(configOverride),
183
183
  notifyOriginWhenDmOnly: true,
184
184
  nativeRuntime: createLazyChannelApprovalNativeRuntimeAdapter({
185
+ capabilityBoundary: true,
185
186
  eventKinds: [
186
187
  "exec",
187
188
  "plugin",
@@ -198,7 +199,7 @@ function createDiscordApprovalCapability(configOverride) {
198
199
  request,
199
200
  configOverride
200
201
  }),
201
- load: async () => (await import("./approval-handler.runtime-CUNkTLDO.js")).discordApprovalNativeRuntime
202
+ load: async () => (await import("./approval-handler.runtime-BnPUU5NK.js")).discordApprovalNativeRuntime
202
203
  })
203
204
  });
204
205
  }
@@ -308,9 +309,9 @@ function resolveDiscordInboundConversation(params) {
308
309
  const loadDiscordDirectoryConfigModule = createLazyRuntimeModule(() => import("./directory-config-D1uDGbWh.js").then((n) => n.t));
309
310
  const loadDiscordResolveChannelsModule = createLazyRuntimeModule(() => import("./resolve-channels-VbpLmUS8.js").then((n) => n.n));
310
311
  const loadDiscordResolveUsersModule = createLazyRuntimeModule(() => import("./resolve-users-D-wRFsd5.js").then((n) => n.n));
311
- const loadDiscordThreadBindingsManagerModule = createLazyRuntimeModule(() => import("./thread-bindings.manager-DM7M3vzn.js").then((n) => n.i));
312
- const loadDiscordTargetResolverModule = createLazyRuntimeModule(() => import("./target-resolver-BgKUUwLy.js").then((n) => n.r));
313
- const loadDiscordProviderRuntime = createLazyRuntimeModule(() => import("./provider.runtime-C-Oh3OHA.js"));
312
+ const loadDiscordThreadBindingsManagerModule = createLazyRuntimeModule(() => import("./thread-bindings.manager-BeUxc8nr.js").then((n) => n.i));
313
+ const loadDiscordTargetResolverModule = createLazyRuntimeModule(() => import("./target-resolver-CoFQ7iSX.js").then((n) => n.r));
314
+ const loadDiscordProviderRuntime = createLazyRuntimeModule(() => import("./provider.runtime-CqfE-RvC.js"));
314
315
  const loadDiscordProbeRuntime = createLazyRuntimeModule(() => import("./probe.runtime-BnuED0fI.js"));
315
316
  async function probeDiscordStatusAccount(params) {
316
317
  const startedAtMs = Date.now();
@@ -318,8 +319,8 @@ async function probeDiscordStatusAccount(params) {
318
319
  const remainingMs = Math.max(1, params.timeoutMs - Math.max(0, Date.now() - startedAtMs));
319
320
  return await runtime.probeDiscord(params.token, remainingMs, { includeApplication: true });
320
321
  }
321
- const loadDiscordAuditModule = createLazyRuntimeModule(() => import("./audit-DzHj2Z4w.js").then((n) => n.n));
322
- const loadDiscordSendModule = createLazyRuntimeModule(() => import("./send-Bdp3zZH5.js").then((n) => n.t));
322
+ const loadDiscordAuditModule = createLazyRuntimeModule(() => import("./audit-BgAgIzwo.js").then((n) => n.n));
323
+ const loadDiscordSendModule = createLazyRuntimeModule(() => import("./send-CLpzfzJe.js").then((n) => n.t));
323
324
  const loadDiscordDirectoryLiveModule = createLazyRuntimeModule(() => import("./directory-live-C5o1uKlw.js").then((n) => n.t));
324
325
  //#endregion
325
326
  //#region extensions/discord/src/conversation-route-owner.ts
@@ -1,11 +1,11 @@
1
- import { i as buildDiscordPresentationComponents, m as coerceDiscordComponentParam, r as buildDiscordInteractiveComponents } from "./components-kvIwhN7i.js";
2
- import { v as parseDiscordTarget, y as resolveDiscordChannelId } from "./retry-B0lQ1Ado.js";
3
- import { a as readDiscordAutoArchiveDurationParam, t as handleDiscordAction } from "./runtime-Cv8GdXSO.js";
4
- import "./targets-fCxslBZ3.js";
1
+ import { i as buildDiscordPresentationComponents, m as coerceDiscordComponentParam, r as buildDiscordInteractiveComponents } from "./components-DBFTIN6P.js";
2
+ import { v as parseDiscordTarget, y as resolveDiscordChannelId } from "./retry-DKeoT7UO.js";
3
+ import { a as readDiscordAutoArchiveDurationParam, t as handleDiscordAction } from "./runtime-Dxl-ZOvg.js";
4
+ import "./targets-Cm6aV9nJ.js";
5
5
  import "./action-runtime-api.js";
6
- import { h as discordInboundEventDelivery } from "./outbound-session-route-DZBYPGTR.js";
7
- import { r as isDiscordComponentSpecWithinMessageLimit, t as DISCORD_PRESENTATION_CAPABILITIES } from "./outbound-components-BvskBqEN.js";
8
- import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-D4XdoA8-.js";
6
+ import { h as discordInboundEventDelivery } from "./outbound-session-route-B0N6os97.js";
7
+ import { r as isDiscordComponentSpecWithinMessageLimit, t as DISCORD_PRESENTATION_CAPABILITIES } from "./outbound-components-DrlHcWfM.js";
8
+ import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-CpEwox_X.js";
9
9
  import { n as notifyDiscordActiveTurnThreadCreated, r as notifyDiscordActiveTurnThreadReplyDelivered } from "./active-turn-thread-route-fmHl1HNd.js";
10
10
  import { normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
11
11
  import { adaptMessagePresentationForChannel, normalizeLegacyInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText } from "openclaw/plugin-sdk/interactive-runtime";
@@ -1,2 +1,2 @@
1
- import { t as discordPlugin } from "./channel-aAywxCij.js";
1
+ import { t as discordPlugin } from "./channel-C_OFFR5Y.js";
2
2
  export { discordPlugin };
@@ -493,6 +493,7 @@ function createButtonComponent(params) {
493
493
  super(..._args6);
494
494
  this.label = params.spec.label;
495
495
  this.url = linkUrl;
496
+ this.emoji = params.spec.emoji;
496
497
  this.disabled = params.spec.disabled ?? false;
497
498
  }
498
499
  }
@@ -1,4 +1,4 @@
1
- import { l as shouldIgnoreStaleDiscordRouteBinding } from "./outbound-session-route-DZBYPGTR.js";
1
+ import { l as shouldIgnoreStaleDiscordRouteBinding } from "./outbound-session-route-B0N6os97.js";
2
2
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
3
3
  import { resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-binding-runtime";
4
4
  //#region extensions/discord/src/monitor/conversation-binding-route.ts
@@ -75,6 +75,7 @@ const detectDiscordLegacyStateMigrations = async ({ stateDir }) => {
75
75
  scopeKey: "",
76
76
  cleanupSource: "remove",
77
77
  cleanupWhenEmpty: true,
78
+ cleanupWarningDisposition: "recoverable",
78
79
  readEntries: () => []
79
80
  });
80
81
  const modelPickerSourcePath = path.join(stateDir, "discord", "model-picker-preferences.json");
@@ -110,7 +111,7 @@ const detectDiscordLegacyStateMigrations = async ({ stateDir }) => {
110
111
  });
111
112
  const threadBindingsSourcePath = path.join(stateDir, "discord", "thread-bindings.json");
112
113
  if (fileExists(threadBindingsSourcePath)) {
113
- const { normalizePersistedBinding, THREAD_BINDINGS_MAX_ENTRIES, THREAD_BINDINGS_NAMESPACE, toBindingRecordKey } = await import("./thread-bindings.state-jNRrsgzV.js").then((n) => n.D);
114
+ const { normalizePersistedBinding, THREAD_BINDINGS_MAX_ENTRIES, THREAD_BINDINGS_NAMESPACE, toBindingRecordKey } = await import("./thread-bindings.state-dDn-dwBw.js").then((n) => n.D);
114
115
  plans.push({
115
116
  kind: "plugin-state-import",
116
117
  label: "Discord thread bindings",
@@ -1,6 +1,6 @@
1
- import { c as readDiscordChannelMoveParams, n as isDiscordModerationAction, o as readDiscordChannelCreateParams, r as readDiscordModerationCommand, s as readDiscordChannelEditParams, t as handleDiscordAction } from "./runtime-Cv8GdXSO.js";
1
+ import { c as readDiscordChannelMoveParams, n as isDiscordModerationAction, o as readDiscordChannelCreateParams, r as readDiscordModerationCommand, s as readDiscordChannelEditParams, t as handleDiscordAction } from "./runtime-Dxl-ZOvg.js";
2
2
  import "./action-runtime-api.js";
3
- import { m as isTrustedRequesterGuildAdminAction } from "./outbound-session-route-DZBYPGTR.js";
3
+ import { m as isTrustedRequesterGuildAdminAction } from "./outbound-session-route-B0N6os97.js";
4
4
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
6
6
  import { readNonNegativeIntegerParam, readPositiveIntegerParam, readStringArrayParam, readStringParam } from "openclaw/plugin-sdk/agent-runtime";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as registerDiscordActivities } from "./activities-api-D--xtQQu.js";
1
+ import { t as registerDiscordActivities } from "./activities-api-w8j7Elou.js";
2
2
  import { registerDiscordSubagentHooks } from "./subagent-hooks-api.js";
3
3
  import { registerDiscordTranscriptSourceProvider } from "./transcripts-source-api.js";
4
4
  import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
@@ -1,7 +1,7 @@
1
1
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
2
2
  import { a as resolveDiscordChannelParentSafe, n as resolveDiscordChannelInfoSafe, r as resolveDiscordChannelNameSafe, t as resolveDiscordChannelIdSafe } from "./channel-access-C12aDZ0p.js";
3
3
  import { C as resolveDiscordCdnPolicy, D as resolveDiscordReferencedReplyMessageId, k as resolveDiscordMessageChannelId, v as resolveDiscordMessageText, w as hasDiscordMessageStickers } from "./transcripts-source-VkgenQv-.js";
4
- import { v as createDiscordLivePolicyReader, y as mapGatewayDispatchData } from "./provider-PI8UiejY.js";
4
+ import { v as createDiscordLivePolicyReader, y as mapGatewayDispatchData } from "./provider-DmRHCZ_K.js";
5
5
  import { logDebug } from "openclaw/plugin-sdk/logging-core";
6
6
  import { GatewayDispatchEvents } from "discord-api-types/v10";
7
7
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
@@ -118,7 +118,7 @@ function createDiscordIngressMonitor(params) {
118
118
  //#endregion
119
119
  //#region extensions/discord/src/monitor/inbound-job.ts
120
120
  function buildDiscordInboundJob(ctx, options) {
121
- const { runtime, abortSignal, guildHistories, client, turnAdoptionLifecycle, threadBindings, discordRestFetch, message, data, threadChannel, ...payload } = ctx;
121
+ const { runtime, buildContext, abortSignal, guildHistories, client, turnAdoptionLifecycle, threadBindings, discordRestFetch, message, data, threadChannel, ...payload } = ctx;
122
122
  const sanitizedMessage = sanitizeDiscordInboundMessage(message);
123
123
  return {
124
124
  payload: {
@@ -132,6 +132,7 @@ function buildDiscordInboundJob(ctx, options) {
132
132
  },
133
133
  runtime: {
134
134
  runtime,
135
+ buildContext,
135
136
  abortSignal,
136
137
  guildHistories,
137
138
  client,
@@ -249,7 +250,7 @@ function applyImplicitReplyBatchGate(ctx, replyToMode, isBatched) {
249
250
  }
250
251
  //#endregion
251
252
  //#region extensions/discord/src/monitor/message-run-queue.ts
252
- const loadMessageProcessRuntime = createLazyRuntimeModule(() => import("./message-handler.process-CWh432Ak.js"));
253
+ const loadMessageProcessRuntime = createLazyRuntimeModule(() => import("./message-handler.process-ZKrmmA9D.js"));
253
254
  async function processDiscordQueuedMessage(params) {
254
255
  const abortSignal = params.job.runtime.abortSignal && params.lifecycleSignal ? AbortSignal.any([params.job.runtime.abortSignal, params.lifecycleSignal]) : params.job.runtime.abortSignal ?? params.lifecycleSignal;
255
256
  try {
@@ -336,7 +337,7 @@ function createDiscordMessageRunQueue(params) {
336
337
  }
337
338
  //#endregion
338
339
  //#region extensions/discord/src/monitor/message-dispatcher.ts
339
- const loadMessagePreflightRuntime = createLazyRuntimeModule(() => import("./message-handler.preflight-BkHVlYis.js"));
340
+ const loadMessagePreflightRuntime = createLazyRuntimeModule(() => import("./message-handler.preflight-DFpwDW2W.js"));
340
341
  function isNonEmptyString(value) {
341
342
  return typeof value === "string" && value.length > 0;
342
343
  }
@@ -5,9 +5,9 @@ import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
5
5
  import { n as resolveDiscordChannelInfoSafe, r as resolveDiscordChannelNameSafe } from "./channel-access-C12aDZ0p.js";
6
6
  import { E as resolveDiscordReferencedReplyMessage, O as resolveDiscordChannelInfo, T as resolveDiscordMessageStickers, _ as resolveDiscordMessageMentionDocuments, b as resolveForwardedMediaList, g as resolveDiscordMessageHistoryText, h as resolveDiscordMessageBatch, k as resolveDiscordMessageChannelId, v as resolveDiscordMessageText, x as resolveMediaList } from "./transcripts-source-VkgenQv-.js";
7
7
  import { n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-D86uWLt_.js";
8
- import { a as buildDiscordRoutePeer, c as resolveDiscordEffectiveRoute, f as resolveDiscordRuntimeBindingConversationId, s as resolveDiscordConversationRoute, u as resolveDiscordConversationIdentity } from "./outbound-session-route-DZBYPGTR.js";
9
- import { t as resolveDiscordConversationBindingRoute } from "./conversation-binding-route-qfe7oPy5.js";
10
- import { S as resolveDiscordTextCommandAccess, _ as handleDiscordDmCommandDecision, n as resolveDiscordPreflightChannelAccess, x as resolveDiscordDmCommandAccess } from "./provider-PI8UiejY.js";
8
+ import { a as buildDiscordRoutePeer, c as resolveDiscordEffectiveRoute, f as resolveDiscordRuntimeBindingConversationId, s as resolveDiscordConversationRoute, u as resolveDiscordConversationIdentity } from "./outbound-session-route-B0N6os97.js";
9
+ import { t as resolveDiscordConversationBindingRoute } from "./conversation-binding-route-CB9PRqgi.js";
10
+ import { S as resolveDiscordTextCommandAccess, _ as handleDiscordDmCommandDecision, n as resolveDiscordPreflightChannelAccess, x as resolveDiscordDmCommandAccess } from "./provider-DmRHCZ_K.js";
11
11
  import { n as resolveDiscordWebhookId, t as resolveDiscordSenderIdentity } from "./sender-identity-f3l5OYgV.js";
12
12
  import { t as createDiscordHistorySenderProvenance } from "./message-handler.history-CJOsN9w5.js";
13
13
  import { logDebug } from "openclaw/plugin-sdk/logging-core";
@@ -29,7 +29,7 @@ import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-surface";
29
29
  import { createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
30
30
  //#region extensions/discord/src/monitor/message-handler.dm-preflight.ts
31
31
  const loadConversationRuntime$1 = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/conversation-binding-runtime"));
32
- const loadDiscordSendRuntime = createLazyRuntimeModule(() => import("./send-Bdp3zZH5.js").then((n) => n.t));
32
+ const loadDiscordSendRuntime = createLazyRuntimeModule(() => import("./send-CLpzfzJe.js").then((n) => n.t));
33
33
  function resolveDiscordDmPairingSenderId(sender) {
34
34
  return sender.isPluralKit ? `pk:${sender.id}` : sender.id;
35
35
  }
@@ -311,6 +311,7 @@ function buildDiscordMessagePreflightContext({ preflightParams, ...fields }) {
311
311
  accountId: preflightParams.accountId,
312
312
  token: preflightParams.token,
313
313
  runtime: preflightParams.runtime,
314
+ buildContext: preflightParams.buildContext,
314
315
  botUserId: preflightParams.botUserId,
315
316
  abortSignal: preflightParams.abortSignal,
316
317
  guildHistories: preflightParams.guildHistories,
@@ -1,16 +1,16 @@
1
1
  import { dt as editChannelMessage, lt as deleteChannelMessage, ot as createChannelMessage, t as discord_exports } from "./discord-CmL3ati-.js";
2
2
  import { S as resolveTimestampMs, a as normalizeDiscordSlug, r as normalizeDiscordAllowList } from "./allow-list-DWEio925.js";
3
3
  import { p as resolveDiscordMaxLinesPerMessage } from "./accounts-CwJQoLjM.js";
4
- import { o as chunkDiscordTextWithMode, y as resolveDiscordChannelId } from "./retry-B0lQ1Ado.js";
5
- import { F as createDiscordRuntimeAccountContext, P as createDiscordRestClient, d as resolveDiscordTargetChannelId, k as resolveDiscordMessageFlags } from "./send.shared-D4BAjlRo.js";
6
- import { a as discordTextHasBroadcastMention } from "./send.outbound-DF0P3C9J.js";
4
+ import { o as chunkDiscordTextWithMode, y as resolveDiscordChannelId } from "./retry-DKeoT7UO.js";
5
+ import { F as createDiscordRuntimeAccountContext, P as createDiscordRestClient, d as resolveDiscordTargetChannelId, k as resolveDiscordMessageFlags } from "./send.shared-BHPM3CSl.js";
6
+ import { a as discordTextHasBroadcastMention } from "./send.outbound-BVTWrl_4.js";
7
7
  import { S as resolveReferencedReplyMediaList, T as resolveDiscordMessageStickers, d as resolveDiscordAutoThreadReplyPlan, p as resolveDiscordThreadStarter, v as resolveDiscordMessageText, y as formatDiscordMediaText } from "./transcripts-source-VkgenQv-.js";
8
- import { a as removeReactionDiscord, f as editMessageDiscord, r as reactMessageDiscord } from "./send-Bdp3zZH5.js";
8
+ import { a as removeReactionDiscord, f as editMessageDiscord, r as reactMessageDiscord } from "./send-CLpzfzJe.js";
9
9
  import { n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-D86uWLt_.js";
10
- import "./targets-fCxslBZ3.js";
11
- import { a as buildDiscordRoutePeer, h as discordInboundEventDelivery, u as resolveDiscordConversationIdentity } from "./outbound-session-route-DZBYPGTR.js";
12
- import { t as DISCORD_TEXT_CHUNK_LIMIT } from "./outbound-adapter-CO2BRlRl.js";
13
- import { a as formatDiscordReplySkip, c as buildGuildLabel, g as createDiscordSupplementalContextAccessChecker, h as buildDiscordInboundAccessContext, i as formatDiscordReplyDeliveryFailure, l as resolveReplyContext, o as sanitizeDiscordFrontChannelReplyPayloads, r as deliverDiscordReply, s as buildDirectLabel } from "./provider-PI8UiejY.js";
10
+ import "./targets-Cm6aV9nJ.js";
11
+ import { a as buildDiscordRoutePeer, h as discordInboundEventDelivery, u as resolveDiscordConversationIdentity } from "./outbound-session-route-B0N6os97.js";
12
+ import { t as DISCORD_TEXT_CHUNK_LIMIT } from "./outbound-adapter-C8PTt7_p.js";
13
+ import { a as formatDiscordReplySkip, c as buildGuildLabel, g as createDiscordSupplementalContextAccessChecker, h as buildDiscordInboundAccessContext, i as formatDiscordReplyDeliveryFailure, l as resolveReplyContext, o as sanitizeDiscordFrontChannelReplyPayloads, r as deliverDiscordReply, s as buildDirectLabel } from "./provider-DmRHCZ_K.js";
14
14
  import { n as resolveDiscordWebhookId } from "./sender-identity-f3l5OYgV.js";
15
15
  import { t as beginDiscordActiveTurnThreadRoute } from "./active-turn-thread-route-fmHl1HNd.js";
16
16
  import { n as filterDiscordHistoryEntriesForContext, t as createDiscordHistorySenderProvenance } from "./message-handler.history-CJOsN9w5.js";
@@ -1187,11 +1187,11 @@ function createDiscordDraftPreviewController(params) {
1187
1187
  }
1188
1188
  await draftStream.flush();
1189
1189
  },
1190
- async cleanup() {
1190
+ async cleanup({ finalDeliveryFailed = false } = {}) {
1191
1191
  try {
1192
1192
  progressDraft.cancel();
1193
1193
  if (finalReplyError !== false) await draftStream?.discardPending();
1194
- if (finalReplyError !== true && !finalizedViaPreviewMessage && draftStream?.messageId()) await draftStream.clear();
1194
+ if (!(discordStreamMode === "progress" && finalDeliveryFailed) && finalReplyError !== true && !finalizedViaPreviewMessage && draftStream?.messageId()) await draftStream.clear();
1195
1195
  await draftStream?.cleanupPendingMessages();
1196
1196
  } catch (err) {
1197
1197
  params.log(`discord: draft cleanup failed: ${String(err)}`);
@@ -1602,7 +1602,7 @@ async function processDiscordMessageInner(ctx, observer) {
1602
1602
  }
1603
1603
  if (isFinal && !replyLifecycleStarted && !isRoomEvent && configuredTypingMode !== "never") await onDiscordReplyStart();
1604
1604
  const draftStream = draftPreview.draftStream;
1605
- if (draftStream && draftPreview.isProgressMode && info.kind === "block" && !options?.allowProgressBlock) {
1605
+ if (draftStream && draftPreview.isProgressMode && info.kind === "block" && !deliverablePayload.isCommentary && !options?.allowProgressBlock) {
1606
1606
  if (!resolveSendableOutboundReplyParts(deliverablePayload).hasMedia && !deliverablePayload.isError) return { visibleReplySent: false };
1607
1607
  }
1608
1608
  if (draftStream && isFinal && draftPreview.isProgressMode && !deliverablePayload.isError && draftPreview.hasProgressDraftToCollapse && draftStream) {
@@ -1842,7 +1842,7 @@ async function processDiscordMessageInner(ctx, observer) {
1842
1842
  } finally {
1843
1843
  activeThreadRoute.end();
1844
1844
  endDeliveryCorrelation();
1845
- await draftPreview.cleanup();
1845
+ await draftPreview.cleanup({ finalDeliveryFailed: userFacingFinalDeliveryFailed });
1846
1846
  dispatchError ||= readAgentRunTerminalOutcome(dispatchResult) === "failed";
1847
1847
  const finalReceipt = dispatchResult?.settledReceipt?.counts.final;
1848
1848
  const finalDeliveryFailed = (finalReceipt?.failedBeforeSend ?? 0) + (finalReceipt?.failedAfterSend ?? 0) > 0;
@@ -1,7 +1,7 @@
1
1
  import { t as createDiscordActionGate } from "./accounts-CwJQoLjM.js";
2
- import { _ as normalizeDiscordOutboundTarget, c as createDiscordSendReceiptFromResults, i as hasDiscordMessageCreateAmbiguity, o as chunkDiscordTextWithMode, p as resolveDiscordReplyReference, s as createDiscordSendReceipt, t as canFallbackDiscordWebhookSend, u as toDiscordOutboundDeliveryResult } from "./retry-B0lQ1Ado.js";
3
- import { g as notifyDiscordInboundEventOutboundPayloadSuccess, h as discordInboundEventDelivery, r as formatDiscordApprovalDisplayValue } from "./outbound-session-route-DZBYPGTR.js";
4
- import { a as sendDiscordComponentMessageLazy, i as resolveDiscordComponentSpec, n as buildDiscordPresentationPayload, t as DISCORD_PRESENTATION_CAPABILITIES } from "./outbound-components-BvskBqEN.js";
2
+ import { _ as normalizeDiscordOutboundTarget, c as createDiscordSendReceiptFromResults, i as hasDiscordMessageCreateAmbiguity, o as chunkDiscordTextWithMode, p as resolveDiscordReplyReference, s as createDiscordSendReceipt, t as canFallbackDiscordWebhookSend, u as toDiscordOutboundDeliveryResult } from "./retry-DKeoT7UO.js";
3
+ import { g as notifyDiscordInboundEventOutboundPayloadSuccess, h as discordInboundEventDelivery, r as formatDiscordApprovalDisplayValue } from "./outbound-session-route-B0N6os97.js";
4
+ import { a as sendDiscordComponentMessageLazy, i as resolveDiscordComponentSpec, n as buildDiscordPresentationPayload, t as DISCORD_PRESENTATION_CAPABILITIES } from "./outbound-components-DrlHcWfM.js";
5
5
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
6
6
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  import { getReplyPayloadTtsSupplement, resolvePayloadMediaUrls, sendPayloadMediaSequenceOrFallback, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
@@ -60,7 +60,7 @@ function normalizeDiscordApprovalPayload(payload) {
60
60
  }
61
61
  //#endregion
62
62
  //#region extensions/discord/src/outbound-send-context.ts
63
- const loadDiscordSendRuntime = createLazyRuntimeModule(() => import("./send-Bdp3zZH5.js").then((n) => n.t));
63
+ const loadDiscordSendRuntime = createLazyRuntimeModule(() => import("./send-CLpzfzJe.js").then((n) => n.t));
64
64
  function resolveDiscordOutboundTarget(params) {
65
65
  if (params.threadId == null) return params.to;
66
66
  const threadId = normalizeOptionalStringifiedId(params.threadId) ?? "";
@@ -280,8 +280,8 @@ async function sendDiscordOutboundPayload(params) {
280
280
  //#region extensions/discord/src/outbound-adapter.ts
281
281
  const DISCORD_TEXT_CHUNK_LIMIT = 2e3;
282
282
  const log = createSubsystemLogger("discord/outbound");
283
- const loadDiscordThreadBindings = createLazyRuntimeModule(() => import("./thread-bindings-B0wnEg_y.js").then((n) => n.t));
284
- const loadDiscordComponentSendRuntime = createLazyRuntimeModule(() => import("./send.components-Bj22B3_O.js").then((n) => n.i));
283
+ const loadDiscordThreadBindings = createLazyRuntimeModule(() => import("./thread-bindings-uudC_0TY.js").then((n) => n.t));
284
+ const loadDiscordComponentSendRuntime = createLazyRuntimeModule(() => import("./send.components-BWnkX4QN.js").then((n) => n.i));
285
285
  function resolveDiscordDeliveryOptions(params) {
286
286
  return {
287
287
  onPlatformSendDispatch: params.onPlatformSendDispatch,
@@ -1,4 +1,4 @@
1
- import { h as readDiscordComponentSpec } from "./components-kvIwhN7i.js";
1
+ import { h as readDiscordComponentSpec } from "./components-DBFTIN6P.js";
2
2
  import { resolveAskUserQuestionOptionIndices } from "openclaw/plugin-sdk/reply-payload";
3
3
  import { createLazyRuntimeModule, createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
4
4
  //#region extensions/discord/src/outbound-components.ts
@@ -31,11 +31,11 @@ const DISCORD_PRESENTATION_CAPABILITIES = {
31
31
  }
32
32
  }
33
33
  };
34
- const loadDiscordComponentSend = createLazyRuntimeNamedExport(() => import("./send.components-Bj22B3_O.js").then((n) => n.i), "sendDiscordComponentMessage");
34
+ const loadDiscordComponentSend = createLazyRuntimeNamedExport(() => import("./send.components-BWnkX4QN.js").then((n) => n.i), "sendDiscordComponentMessage");
35
35
  async function sendDiscordComponentMessageLazy(...args) {
36
36
  return await (await loadDiscordComponentSend())(...args);
37
37
  }
38
- const loadDiscordSharedInteractive = createLazyRuntimeModule(() => import("./components-kvIwhN7i.js").then((n) => n.a));
38
+ const loadDiscordSharedInteractive = createLazyRuntimeModule(() => import("./components-DBFTIN6P.js").then((n) => n.a));
39
39
  function addPayloadTextFallback(spec, payload) {
40
40
  return spec.text ? spec : {
41
41
  ...spec,
@@ -1,6 +1,6 @@
1
- import { h as readDiscordComponentSpec, m as coerceDiscordComponentParam } from "./components-kvIwhN7i.js";
1
+ import { h as readDiscordComponentSpec, m as coerceDiscordComponentParam } from "./components-DBFTIN6P.js";
2
2
  import { c as resolveDiscordAccount, r as listDiscordAccountIds, t as createDiscordActionGate } from "./accounts-CwJQoLjM.js";
3
- import { g as normalizeDiscordMessagingTarget, v as parseDiscordTarget } from "./retry-B0lQ1Ado.js";
3
+ import { g as normalizeDiscordMessagingTarget, v as parseDiscordTarget } from "./retry-DKeoT7UO.js";
4
4
  import { n as resolveDiscordCommandOwnerEntries } from "./command-owners-D78sAoOz.js";
5
5
  import { t as inspectDiscordAccount } from "./account-inspect-BY-ve3yH.js";
6
6
  import { ChannelType } from "discord-api-types/v10";
@@ -264,7 +264,7 @@ function matchesCurrentDiscordThread(params) {
264
264
  if (!requestedTarget) return false;
265
265
  return [params.toolContext.currentChannelId, params.toolContext.currentMessagingTarget].some((currentTarget) => currentTarget !== void 0 && normalizeDiscordMessagingTarget(currentTarget) === requestedTarget);
266
266
  }
267
- const loadDiscordChannelActionsRuntime = createLazyRuntimeModule(() => import("./channel-actions.runtime-rmse1yrM.js"));
267
+ const loadDiscordChannelActionsRuntime = createLazyRuntimeModule(() => import("./channel-actions.runtime-tShzmemq.js"));
268
268
  function listDiscoverableDiscordAccounts(cfg) {
269
269
  return listDiscordAccountIds(cfg).map((accountId) => inspectDiscordAccount({
270
270
  cfg,
@@ -1,7 +1,7 @@
1
1
  //#region extensions/discord/src/monitor/presence-cache.ts
2
2
  /**
3
3
  * In-memory cache of Discord user presence data.
4
- * Populated by PRESENCE_UPDATE gateway events when the GuildPresences intent is enabled.
4
+ * Populated by GUILD_CREATE snapshots and PRESENCE_UPDATE when GuildPresences is enabled.
5
5
  * Per-account maps are capped to prevent unbounded growth (#4948).
6
6
  */
7
7
  const MAX_PRESENCE_PER_ACCOUNT = 5e3;
@@ -1,26 +1,26 @@
1
1
  import { C as Command, D as User, E as Message, I as Button, J as TextDisplay, K as Separator, N as Modal, O as hasDiscordV2Components, R as Container, T as Guild, W as Row, Z as BaseMessageInteractiveComponent, a as MessageCreateListener, c as PresenceUpdateListener, d as ThreadDeleteListener, f as ThreadUpdateListener, h as Plugin, i as InteractionCreateListener, l as ReadyListener, m as Client, n as GuildCreateListener, o as MessageReactionAddListener, q as StringSelectMenu, r as GuildDeleteListener, s as MessageReactionRemoveListener, t as discord_exports, v as RateLimitError, w as CommandWithSubcommands } from "./discord-CmL3ati-.js";
2
- import { C as parseDiscordActivityCustomIdForInteraction, D as parseDiscordModalCustomIdForInteraction, E as parseDiscordModalCustomId, O as decodeCustomIdComponent, T as parseDiscordComponentCustomIdForInteraction, c as parseExecApprovalData, k as encodeCustomIdComponent, o as parseDiscordQuestionData, w as parseDiscordComponentCustomId, y as buildDiscordActivityCustomId } from "./components-kvIwhN7i.js";
2
+ import { C as parseDiscordActivityCustomIdForInteraction, D as parseDiscordModalCustomIdForInteraction, E as parseDiscordModalCustomId, O as decodeCustomIdComponent, T as parseDiscordComponentCustomIdForInteraction, c as parseExecApprovalData, k as encodeCustomIdComponent, o as parseDiscordQuestionData, w as parseDiscordComponentCustomId, y as buildDiscordActivityCustomId } from "./components-DBFTIN6P.js";
3
3
  import { S as resolveTimestampMs, _ as resolveGroupDmAllow, a as normalizeDiscordSlug, b as formatDiscordUserTag, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordGuildEntry, f as resolveDiscordMemberAccessState, h as resolveDiscordOwnerAllowFrom, i as normalizeDiscordDisplaySlug, l as resolveDiscordChannelPolicyCommandAuthorizer, m as resolveDiscordOwnerAccess, n as isDiscordGroupAllowedByPolicy, o as resolveDiscordAllowListMatch, p as resolveDiscordMemberAllowed, r as normalizeDiscordAllowList, s as resolveDiscordChannelConfig, v as shouldEmitDiscordReactionNotification, y as formatDiscordReactionEmoji } from "./allow-list-DWEio925.js";
4
4
  import { c as resolveDiscordAccount, f as resolveDiscordAccountDmPolicy, h as resolveDiscordToken, l as resolveDiscordAccountAllowFrom, m as normalizeDiscordToken, o as mergeDiscordAccountConfig, p as resolveDiscordMaxLinesPerMessage } from "./accounts-CwJQoLjM.js";
5
- import { a as resolveDiscordComponentEntryWithPersistence, o as resolveDiscordModalEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-Bj22B3_O.js";
5
+ import { a as resolveDiscordComponentEntryWithPersistence, o as resolveDiscordModalEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-BWnkX4QN.js";
6
6
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
7
7
  import { a as isDiscordRateLimitResponseBody, o as summarizeDiscordResponseBody } from "./api-LIV--eMq.js";
8
- import { o as chunkDiscordTextWithMode } from "./retry-B0lQ1Ado.js";
9
- import { B as validateDiscordProxyUrl, G as unregisterGateway, P as createDiscordRestClient, R as DISCORD_REST_TIMEOUT_MS, V as withValidatedDiscordProxy, W as registerGateway, b as canViewDiscordGuildChannel, w as hasAnyChannelPermissionDiscord } from "./send.shared-D4BAjlRo.js";
10
- import { o as formatMention, t as sendMessageDiscord } from "./send.outbound-DF0P3C9J.js";
8
+ import { o as chunkDiscordTextWithMode } from "./retry-DKeoT7UO.js";
9
+ import { B as validateDiscordProxyUrl, G as unregisterGateway, P as createDiscordRestClient, R as DISCORD_REST_TIMEOUT_MS, V as withValidatedDiscordProxy, W as registerGateway, b as canViewDiscordGuildChannel, w as hasAnyChannelPermissionDiscord } from "./send.shared-BHPM3CSl.js";
10
+ import { o as formatMention, t as sendMessageDiscord } from "./send.outbound-BVTWrl_4.js";
11
11
  import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
12
- import { n as getDiscordActivitiesRuntime } from "./runtime-D-ZFlMQ2.js";
12
+ import { n as getDiscordActivitiesRuntime } from "./runtime-CbknwoBH.js";
13
13
  import { t as resolveDiscordCommandOwnerAllowFrom } from "./command-owners-D78sAoOz.js";
14
14
  import { n as resolveDiscordChannelInfoSafe, o as resolveDiscordChannelTopicSafe, r as resolveDiscordChannelNameSafe } from "./channel-access-C12aDZ0p.js";
15
15
  import { T as resolveDiscordMessageStickers, a as authorizeDiscordVoiceIngress, c as resolveDiscordThreadLikeChannelContext, i as resolveDiscordVoiceEnabled, l as resolveFetchedDiscordThreadLikeChannelContext, o as resolveDiscordVoiceAccess, r as setDiscordTranscriptsVoiceManager } from "./transcripts-source-VkgenQv-.js";
16
- import { i as setPresence, t as clearPresences } from "./presence-cache-z1N8MbJ3.js";
17
- import { _ as readMessagesDiscord, s as sendVoiceMessageDiscord } from "./send-Bdp3zZH5.js";
16
+ import { i as setPresence, t as clearPresences } from "./presence-cache-dYSHPWMx.js";
17
+ import { _ as readMessagesDiscord, s as sendVoiceMessageDiscord } from "./send-CLpzfzJe.js";
18
18
  import { c as raceWithTimeout, u as withAbortTimeout } from "./timeouts-D86uWLt_.js";
19
- import { S as isDiscordExecApprovalClientEnabled, b as getDiscordExecApprovalApprovers, c as resolveDiscordEffectiveRoute, i as buildDiscordConversationRouteContext, n as DISCORD_APPROVAL_ALLOWED_MENTIONS, o as resolveDiscordBoundConversationRoute, r as formatDiscordApprovalDisplayValue, u as resolveDiscordConversationIdentity } from "./outbound-session-route-DZBYPGTR.js";
19
+ import { S as isDiscordExecApprovalClientEnabled, b as getDiscordExecApprovalApprovers, c as resolveDiscordEffectiveRoute, i as buildDiscordConversationRouteContext, n as DISCORD_APPROVAL_ALLOWED_MENTIONS, o as resolveDiscordBoundConversationRoute, r as formatDiscordApprovalDisplayValue, u as resolveDiscordConversationIdentity } from "./outbound-session-route-B0N6os97.js";
20
20
  import { n as discordIngressIdentity, t as selectDiscordLivePolicyConfig } from "./live-policy-config-BblutQAq.js";
21
21
  import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-VbpLmUS8.js";
22
22
  import { t as resolveDiscordUserAllowlist } from "./resolve-users-D-wRFsd5.js";
23
- import { a as isThreadArchived, l as formatThreadBindingDurationLabel, r as getThreadBindingManager } from "./thread-bindings.manager-DM7M3vzn.js";
23
+ import { a as isThreadArchived, l as formatThreadBindingDurationLabel, r as getThreadBindingManager } from "./thread-bindings.manager-BeUxc8nr.js";
24
24
  import { a as probeDiscordApplicationId, r as parseApplicationIdFromToken } from "./probe-BcoN44eK.js";
25
25
  import { i as sanitizeRecentModels, n as normalizeModelRef, r as preferenceTimestampMs, t as buildPreferenceModelKey } from "./model-picker-preference-primitives-BHT1LkR_.js";
26
26
  import { t as resolveDiscordSenderIdentity } from "./sender-identity-f3l5OYgV.js";
@@ -914,6 +914,13 @@ var DiscordPresenceListener = class extends PresenceUpdateListener {
914
914
  this.emissionGate = params.emissionGate ?? new DiscordPresenceEmissionGate();
915
915
  }
916
916
  async seedGuildSnapshot(data) {
917
+ if (data.unavailable !== true && "presences" in data && Array.isArray(data.presences)) for (const presence of data.presences) {
918
+ const userId = presence.user?.id;
919
+ if (userId) setPresence(this.params.accountId, userId, {
920
+ ...presence,
921
+ guild_id: data.id
922
+ });
923
+ }
917
924
  if (!this.params.readPolicy) {
918
925
  this.seedGuildSnapshotWithPolicy(data, this.params.guildEntries);
919
926
  return;
@@ -962,11 +969,11 @@ var DiscordPresenceListener = class extends PresenceUpdateListener {
962
969
  }
963
970
  }
964
971
  async handle(data, client) {
965
- const pendingSeed = this.pendingGuildSeeds.get(data.guild_id);
966
- if (pendingSeed && !await pendingSeed) return;
967
972
  const userId = data.user?.id;
968
973
  if (!userId) return;
969
974
  setPresence(this.params.accountId, userId, data);
975
+ const pendingSeed = this.pendingGuildSeeds.get(data.guild_id);
976
+ if (pendingSeed && !await pendingSeed) return;
970
977
  const presenceKey = `${this.params.accountId}:${data.guild_id}:${userId}`;
971
978
  const gatewayGeneration = this.gatewayGeneration;
972
979
  const guildGeneration = this.guildPresenceState.get(data.guild_id)?.generation ?? 0;
@@ -6939,7 +6946,7 @@ async function runDiscordGatewayLifecycle(params) {
6939
6946
  let discordVoiceRuntimePromise;
6940
6947
  let discordProviderSessionRuntimePromise;
6941
6948
  async function loadDiscordVoiceRuntime() {
6942
- const promise = discordVoiceRuntimePromise ?? import("./voice-runtime-BhRqlbEt.js").then((n) => n.t);
6949
+ const promise = discordVoiceRuntimePromise ?? import("./voice-runtime-DMYDMkJx.js").then((n) => n.t);
6943
6950
  discordVoiceRuntimePromise = promise;
6944
6951
  try {
6945
6952
  return await promise;
@@ -6949,7 +6956,7 @@ async function loadDiscordVoiceRuntime() {
6949
6956
  }
6950
6957
  }
6951
6958
  async function loadDiscordProviderSessionRuntime() {
6952
- const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-BejUb3gm.js");
6959
+ const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-U1M8_EYY.js");
6953
6960
  discordProviderSessionRuntimePromise = promise;
6954
6961
  try {
6955
6962
  return await promise;
@@ -8997,7 +9004,7 @@ async function dispatchPluginDiscordInteractiveEvent(params) {
8997
9004
  }
8998
9005
  //#endregion
8999
9006
  //#region extensions/discord/src/monitor/agent-components.handlers.ts
9000
- const loadComponentsRuntime = createLazyRuntimeModule(() => import("./components-kvIwhN7i.js").then((n) => n.t));
9007
+ const loadComponentsRuntime = createLazyRuntimeModule(() => import("./components-DBFTIN6P.js").then((n) => n.t));
9001
9008
  async function handleDiscordComponentEvent(params) {
9002
9009
  const parsed = parseDiscordComponentData(params.data, resolveInteractionCustomId(params.interaction));
9003
9010
  if (!parsed) {
@@ -1,6 +1,6 @@
1
- import { n as createThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-DM7M3vzn.js";
2
- import { a as reconcileAcpThreadBindingsOnStartup } from "./thread-bindings-B0wnEg_y.js";
3
- import { t as createDiscordMessageHandler } from "./message-handler-B0DbuhWz.js";
1
+ import { n as createThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-BeUxc8nr.js";
2
+ import { a as reconcileAcpThreadBindingsOnStartup } from "./thread-bindings-uudC_0TY.js";
3
+ import { t as createDiscordMessageHandler } from "./message-handler-C7FZGKa8.js";
4
4
  import { resolveThreadBindingIdleTimeoutMs, resolveThreadBindingMaxAgeMs, resolveThreadBindingsEnabled } from "openclaw/plugin-sdk/conversation-runtime";
5
5
  import { getAcpSessionManager, isAcpRuntimeError } from "openclaw/plugin-sdk/acp-runtime";
6
6
  export { createDiscordMessageHandler, createNoopThreadBindingManager, createThreadBindingManager, getAcpSessionManager, isAcpRuntimeError, reconcileAcpThreadBindingsOnStartup, resolveThreadBindingIdleTimeoutMs, resolveThreadBindingMaxAgeMs, resolveThreadBindingsEnabled };
@@ -0,0 +1,2 @@
1
+ import { t as monitorDiscordProvider } from "./provider-DmRHCZ_K.js";
2
+ export { monitorDiscordProvider };
@@ -1,5 +1,5 @@
1
1
  import { n as discordRealtimeVoiceSecretOwnerId } from "./secret-config-contract-DFu9hfU8.js";
2
- import { a as convertRealtimePcm24kMonoToDiscordPcm48kStereo, c as maybeControlDiscordVoiceAgentRun, i as convertDiscordPcm48kStereoToRealtimePcm24kMono, l as formatVoiceLogPreview, n as DiscordRealtimeRecording, o as createDiscordOpusEncodeStream, r as logVoiceVerbose, s as formatVoiceIngressPrompt, u as loadDiscordVoiceSdk } from "./voice-runtime-BhRqlbEt.js";
2
+ import { a as convertRealtimePcm24kMonoToDiscordPcm48kStereo, c as maybeControlDiscordVoiceAgentRun, i as convertDiscordPcm48kStereoToRealtimePcm24kMono, l as formatVoiceLogPreview, n as DiscordRealtimeRecording, o as createDiscordOpusEncodeStream, r as logVoiceVerbose, s as formatVoiceIngressPrompt, u as loadDiscordVoiceSdk } from "./voice-runtime-DMYDMkJx.js";
3
3
  import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
4
4
  import { formatErrorMessage } from "openclaw/plugin-sdk/ssrf-runtime";
5
5
  import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
@@ -231,7 +231,9 @@ function resolveDiscordChunkLimit(value, fallback) {
231
231
  }
232
232
  function countLines(text) {
233
233
  if (!text) return 0;
234
- return text.split("\n").length;
234
+ let count = 1;
235
+ for (let index = text.indexOf("\n"); index !== -1; index = text.indexOf("\n", index + 1)) count += 1;
236
+ return count;
235
237
  }
236
238
  function parseFenceLine(line, maxChars = Number.POSITIVE_INFINITY) {
237
239
  const match = line.match(FENCE_RE);
@@ -406,10 +408,13 @@ function createDiscordRanges(source, maxChars, maxLines) {
406
408
  const code = expectDefined(span.source, "inline code source map");
407
409
  const atomicTicks = (renderInlineCode("`", marker)?.length ?? Infinity) + code.prefix.text.length > maxChars;
408
410
  const pattern = atomicTicks ? /`+|\r\n|[\s\S]/gu : /\r\n|[\s\S]/gu;
409
- if (Array.from(source.slice(start, finish).matchAll(pattern)).every(({ index, 0: raw }) => {
411
+ let fits = true;
412
+ for (const { index, 0: raw } of source.slice(start, finish).matchAll(pattern)) {
410
413
  const value = code.value.slice(code.offsets[index], code.offsets[index + raw.length]);
411
- return !value || (renderInlineCode(value, marker)?.length ?? Infinity) + code.prefix.text.length <= maxChars;
412
- }) && (maxLines > 1 || !code.value.includes("\n"))) spans.push({
414
+ fits = !value || (renderInlineCode(value, marker)?.length ?? Infinity) + code.prefix.text.length <= maxChars;
415
+ if (!fits) break;
416
+ }
417
+ if (fits && (maxLines > 1 || !code.value.includes("\n"))) spans.push({
413
418
  start,
414
419
  end: finish,
415
420
  code,
@@ -1,5 +1,5 @@
1
1
  import { c as resolveDiscordAccount, g as selectDiscordActivitiesRuntimeConfig, n as isDiscordAccountEnabledForRuntime, r as listDiscordAccountIds } from "./accounts-CwJQoLjM.js";
2
- import { z as resolveDiscordProxyFetchForAccount } from "./send.shared-D4BAjlRo.js";
2
+ import { z as resolveDiscordProxyFetchForAccount } from "./send.shared-BHPM3CSl.js";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  //#region extensions/discord/src/activities/config.ts
5
5
  function resolveDiscordActivitiesConfig(account, env = process.env) {
@@ -1,14 +1,14 @@
1
- import { h as readDiscordComponentSpec, m as coerceDiscordComponentParam } from "./components-kvIwhN7i.js";
1
+ import { h as readDiscordComponentSpec, m as coerceDiscordComponentParam } from "./components-DBFTIN6P.js";
2
2
  import { _ as resolveGroupDmAllow, a as normalizeDiscordSlug, c as resolveDiscordChannelConfigWithFallback, n as isDiscordGroupAllowedByPolicy } from "./allow-list-DWEio925.js";
3
3
  import { o as mergeDiscordAccountConfig, s as resolveDefaultDiscordAccountId, t as createDiscordActionGate } from "./accounts-CwJQoLjM.js";
4
- import { r as sendDiscordComponentMessage } from "./send.components-Bj22B3_O.js";
5
- import { d as createReusableDiscordReplyReference, p as resolveDiscordReplyReference, y as resolveDiscordChannelId } from "./retry-B0lQ1Ado.js";
6
- import { F as createDiscordRuntimeAccountContext, T as hasAnyGuildPermissionDiscord, U as getGateway, d as resolveDiscordTargetChannelId, v as canManageGuildMemberRoleDiscord, w as hasAnyChannelPermissionDiscord, x as fetchChannelPermissionsDiscord, y as canManageGuildRoleDiscord } from "./send.shared-D4BAjlRo.js";
7
- import { r as sendStickerDiscord, t as sendMessageDiscord } from "./send.outbound-DF0P3C9J.js";
4
+ import { r as sendDiscordComponentMessage } from "./send.components-BWnkX4QN.js";
5
+ import { d as createReusableDiscordReplyReference, p as resolveDiscordReplyReference, y as resolveDiscordChannelId } from "./retry-DKeoT7UO.js";
6
+ import { F as createDiscordRuntimeAccountContext, T as hasAnyGuildPermissionDiscord, U as getGateway, d as resolveDiscordTargetChannelId, v as canManageGuildMemberRoleDiscord, w as hasAnyChannelPermissionDiscord, x as fetchChannelPermissionsDiscord, y as canManageGuildRoleDiscord } from "./send.shared-BHPM3CSl.js";
7
+ import { r as sendStickerDiscord, t as sendMessageDiscord } from "./send.outbound-BVTWrl_4.js";
8
8
  import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
9
- import { n as getPresence } from "./presence-cache-z1N8MbJ3.js";
10
- import { A as listScheduledEventsDiscord, B as moveChannelDiscord, C as fetchChannelInfoDiscord, D as fetchVoiceStatusDiscord, E as fetchRoleInfoDiscord, F as uploadEmojiDiscord, H as setChannelPermissionDiscord, I as uploadStickerDiscord, L as createChannelDiscord, M as resolveEventCoverImage, N as timeoutMemberDiscord, O as kickMemberDiscord, P as listGuildEmojisDiscord, R as deleteChannelDiscord, S as createScheduledEventDiscord, T as fetchMemberInfoDiscord, V as removeChannelPermissionDiscord, _ as readMessagesDiscord, a as removeReactionDiscord, b as addRoleDiscord, d as deleteMessageDiscord, f as editMessageDiscord, g as pinMessageDiscord, h as listThreadsDiscord, i as removeOwnReactionsDiscord, j as removeRoleDiscord, k as listGuildChannelsDiscord, l as DiscordThreadInitialMessageError, m as listPinsDiscord, n as fetchReactionsDiscord, p as fetchMessageDiscord, r as reactMessageDiscord, s as sendVoiceMessageDiscord, u as createThreadDiscord, v as searchMessagesDiscord, w as fetchGuildInfoDiscord, x as banMemberDiscord, y as unpinMessageDiscord, z as editChannelDiscord } from "./send-Bdp3zZH5.js";
11
- import "./targets-fCxslBZ3.js";
9
+ import { n as getPresence } from "./presence-cache-dYSHPWMx.js";
10
+ import { A as listScheduledEventsDiscord, B as moveChannelDiscord, C as fetchChannelInfoDiscord, D as fetchVoiceStatusDiscord, E as fetchRoleInfoDiscord, F as uploadEmojiDiscord, H as setChannelPermissionDiscord, I as uploadStickerDiscord, L as createChannelDiscord, M as resolveEventCoverImage, N as timeoutMemberDiscord, O as kickMemberDiscord, P as listGuildEmojisDiscord, R as deleteChannelDiscord, S as createScheduledEventDiscord, T as fetchMemberInfoDiscord, V as removeChannelPermissionDiscord, _ as readMessagesDiscord, a as removeReactionDiscord, b as addRoleDiscord, d as deleteMessageDiscord, f as editMessageDiscord, g as pinMessageDiscord, h as listThreadsDiscord, i as removeOwnReactionsDiscord, j as removeRoleDiscord, k as listGuildChannelsDiscord, l as DiscordThreadInitialMessageError, m as listPinsDiscord, n as fetchReactionsDiscord, p as fetchMessageDiscord, r as reactMessageDiscord, s as sendVoiceMessageDiscord, u as createThreadDiscord, v as searchMessagesDiscord, w as fetchGuildInfoDiscord, x as banMemberDiscord, y as unpinMessageDiscord, z as editChannelDiscord } from "./send-CLpzfzJe.js";
11
+ import "./targets-Cm6aV9nJ.js";
12
12
  import { ChannelType, PermissionFlagsBits } from "discord-api-types/v10";
13
13
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
14
14
  import { asBoolean, isRecord, normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -1,23 +1,23 @@
1
1
  import { _ as resolveGroupDmAllow, a as normalizeDiscordSlug, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordGuildEntry, g as resolveDiscordShouldRequireMention, n as isDiscordGroupAllowedByPolicy, r as normalizeDiscordAllowList, s as resolveDiscordChannelConfig, t as allowListMatches, u as resolveDiscordCommandAuthorized, v as shouldEmitDiscordReactionNotification } from "./allow-list-DWEio925.js";
2
- import { n as registerBuiltDiscordComponentMessage, r as sendDiscordComponentMessage, t as editDiscordComponentMessage } from "./send.components-Bj22B3_O.js";
2
+ import { n as registerBuiltDiscordComponentMessage, r as sendDiscordComponentMessage, t as editDiscordComponentMessage } from "./send.components-BWnkX4QN.js";
3
3
  import { r as setDiscordRuntime } from "./runtime-DgnVQ7zW.js";
4
4
  import { n as listDiscordDirectoryGroupsLive, r as listDiscordDirectoryPeersLive } from "./directory-live-C5o1uKlw.js";
5
- import { C as hasAllGuildPermissionsDiscord, G as unregisterGateway, H as clearGateways, S as fetchMemberGuildPermissionsDiscord, T as hasAnyGuildPermissionDiscord, U as getGateway, W as registerGateway, _ as DiscordSendError, x as fetchChannelPermissionsDiscord } from "./send.shared-D4BAjlRo.js";
6
- import { n as sendPollDiscord, r as sendStickerDiscord, t as sendMessageDiscord } from "./send.outbound-DF0P3C9J.js";
5
+ import { C as hasAllGuildPermissionsDiscord, G as unregisterGateway, H as clearGateways, S as fetchMemberGuildPermissionsDiscord, T as hasAnyGuildPermissionDiscord, U as getGateway, W as registerGateway, _ as DiscordSendError, x as fetchChannelPermissionsDiscord } from "./send.shared-BHPM3CSl.js";
6
+ import { n as sendPollDiscord, r as sendStickerDiscord, t as sendMessageDiscord } from "./send.outbound-BVTWrl_4.js";
7
7
  import { f as resolveDiscordReplyTarget, m as sanitizeDiscordThreadName } from "./transcripts-source-VkgenQv-.js";
8
- import { i as setPresence, n as getPresence, r as presenceCacheSize, t as clearPresences } from "./presence-cache-z1N8MbJ3.js";
9
- import { A as listScheduledEventsDiscord, B as moveChannelDiscord, C as fetchChannelInfoDiscord, D as fetchVoiceStatusDiscord, E as fetchRoleInfoDiscord, F as uploadEmojiDiscord, H as setChannelPermissionDiscord, I as uploadStickerDiscord, L as createChannelDiscord, M as resolveEventCoverImage, N as timeoutMemberDiscord, O as kickMemberDiscord, P as listGuildEmojisDiscord, R as deleteChannelDiscord, S as createScheduledEventDiscord, T as fetchMemberInfoDiscord, V as removeChannelPermissionDiscord, _ as readMessagesDiscord, a as removeReactionDiscord, b as addRoleDiscord, c as sendWebhookMessageDiscord, d as deleteMessageDiscord, f as editMessageDiscord, g as pinMessageDiscord, h as listThreadsDiscord, i as removeOwnReactionsDiscord, j as removeRoleDiscord, k as listGuildChannelsDiscord, m as listPinsDiscord, n as fetchReactionsDiscord, o as sendTypingDiscord, p as fetchMessageDiscord, r as reactMessageDiscord, s as sendVoiceMessageDiscord, u as createThreadDiscord, v as searchMessagesDiscord, x as banMemberDiscord, y as unpinMessageDiscord, z as editChannelDiscord } from "./send-Bdp3zZH5.js";
8
+ import { i as setPresence, n as getPresence, r as presenceCacheSize, t as clearPresences } from "./presence-cache-dYSHPWMx.js";
9
+ import { A as listScheduledEventsDiscord, B as moveChannelDiscord, C as fetchChannelInfoDiscord, D as fetchVoiceStatusDiscord, E as fetchRoleInfoDiscord, F as uploadEmojiDiscord, H as setChannelPermissionDiscord, I as uploadStickerDiscord, L as createChannelDiscord, M as resolveEventCoverImage, N as timeoutMemberDiscord, O as kickMemberDiscord, P as listGuildEmojisDiscord, R as deleteChannelDiscord, S as createScheduledEventDiscord, T as fetchMemberInfoDiscord, V as removeChannelPermissionDiscord, _ as readMessagesDiscord, a as removeReactionDiscord, b as addRoleDiscord, c as sendWebhookMessageDiscord, d as deleteMessageDiscord, f as editMessageDiscord, g as pinMessageDiscord, h as listThreadsDiscord, i as removeOwnReactionsDiscord, j as removeRoleDiscord, k as listGuildChannelsDiscord, m as listPinsDiscord, n as fetchReactionsDiscord, o as sendTypingDiscord, p as fetchMessageDiscord, r as reactMessageDiscord, s as sendVoiceMessageDiscord, u as createThreadDiscord, v as searchMessagesDiscord, x as banMemberDiscord, y as unpinMessageDiscord, z as editChannelDiscord } from "./send-CLpzfzJe.js";
10
10
  import { a as isAbortError, i as DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, l as runDiscordTaskWithTimeout, n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, o as normalizeDiscordInboundWorkerTimeoutMs, r as DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, s as normalizeDiscordListenerTimeoutMs, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-D86uWLt_.js";
11
- import { c as readDiscordChannelMoveParams, i as requiredGuildPermissionForModerationAction, l as readDiscordParentIdParam, n as isDiscordModerationAction, o as readDiscordChannelCreateParams, r as readDiscordModerationCommand, s as readDiscordChannelEditParams, t as handleDiscordAction } from "./runtime-Cv8GdXSO.js";
12
- import { p as discordMessageActions, t as resolveDiscordOutboundSessionRoute } from "./outbound-session-route-DZBYPGTR.js";
13
- import { S as resolveThreadBindingMaxAgeMs, b as resolveThreadBindingInactivityExpiresAt, x as resolveThreadBindingMaxAgeExpiresAt, y as resolveThreadBindingIdleTimeoutMs } from "./thread-bindings.state-jNRrsgzV.js";
14
- import { n as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-CSBmgCcx.js";
11
+ import { c as readDiscordChannelMoveParams, i as requiredGuildPermissionForModerationAction, l as readDiscordParentIdParam, n as isDiscordModerationAction, o as readDiscordChannelCreateParams, r as readDiscordModerationCommand, s as readDiscordChannelEditParams, t as handleDiscordAction } from "./runtime-Dxl-ZOvg.js";
12
+ import { p as discordMessageActions, t as resolveDiscordOutboundSessionRoute } from "./outbound-session-route-B0N6os97.js";
13
+ import { S as resolveThreadBindingMaxAgeMs, b as resolveThreadBindingInactivityExpiresAt, x as resolveThreadBindingMaxAgeExpiresAt, y as resolveThreadBindingIdleTimeoutMs } from "./thread-bindings.state-dDn-dwBw.js";
14
+ import { n as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-BwkXpcy0.js";
15
15
  import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-VbpLmUS8.js";
16
16
  import { t as resolveDiscordUserAllowlist } from "./resolve-users-D-wRFsd5.js";
17
- import { c as resolveThreadBindingPersonaFromRecord, d as resolveThreadBindingThreadName, l as formatThreadBindingDurationLabel, n as createThreadBindingManager, r as getThreadBindingManager, s as resolveThreadBindingPersona, t as createNoopThreadBindingManager, u as resolveThreadBindingIntroText } from "./thread-bindings.manager-DM7M3vzn.js";
18
- import { a as reconcileAcpThreadBindingsOnStartup, c as resolveDiscordThreadBindingMaxAgeMs, i as listThreadBindingsForAccount, l as resolveThreadBindingsEnabled, n as autoBindSpawnedDiscordSubagent, o as unbindThreadBindingsBySessionKey, r as listThreadBindingsBySessionKey, s as resolveDiscordThreadBindingIdleTimeoutMs } from "./thread-bindings-B0wnEg_y.js";
17
+ import { c as resolveThreadBindingPersonaFromRecord, d as resolveThreadBindingThreadName, l as formatThreadBindingDurationLabel, n as createThreadBindingManager, r as getThreadBindingManager, s as resolveThreadBindingPersona, t as createNoopThreadBindingManager, u as resolveThreadBindingIntroText } from "./thread-bindings.manager-BeUxc8nr.js";
18
+ import { a as reconcileAcpThreadBindingsOnStartup, c as resolveDiscordThreadBindingMaxAgeMs, i as listThreadBindingsForAccount, l as resolveThreadBindingsEnabled, n as autoBindSpawnedDiscordSubagent, o as unbindThreadBindingsBySessionKey, r as listThreadBindingsBySessionKey, s as resolveDiscordThreadBindingIdleTimeoutMs } from "./thread-bindings-uudC_0TY.js";
19
19
  import { i as probeDiscord, n as fetchDiscordApplicationSummary, o as resolveDiscordPrivilegedIntentsFromFlags, r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-BcoN44eK.js";
20
- import { r as collectDiscordAuditChannelIds, t as auditDiscordChannelPermissions } from "./audit-DzHj2Z4w.js";
21
- import { b as registerDiscordListener, d as resolveDiscordGatewayIntents, f as waitForDiscordGatewayPluginRegistration, p as createDiscordNativeCommand, t as monitorDiscordProvider, u as createDiscordGatewayPlugin } from "./provider-PI8UiejY.js";
22
- import { t as createDiscordMessageHandler } from "./message-handler-B0DbuhWz.js";
20
+ import { r as collectDiscordAuditChannelIds, t as auditDiscordChannelPermissions } from "./audit-BgAgIzwo.js";
21
+ import { b as registerDiscordListener, d as resolveDiscordGatewayIntents, f as waitForDiscordGatewayPluginRegistration, p as createDiscordNativeCommand, t as monitorDiscordProvider, u as createDiscordGatewayPlugin } from "./provider-DmRHCZ_K.js";
22
+ import { t as createDiscordMessageHandler } from "./message-handler-C7FZGKa8.js";
23
23
  export { DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS, DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, DiscordSendError, addRoleDiscord, allowListMatches, auditDiscordChannelPermissions, autoBindSpawnedDiscordSubagent, banMemberDiscord, clearGateways, clearPresences, collectDiscordAuditChannelIds, createChannelDiscord, createDiscordGatewayPlugin, createDiscordMessageHandler, createDiscordNativeCommand, createNoopThreadBindingManager, createScheduledEventDiscord, createThreadBindingManager, createThreadDiscord, deleteChannelDiscord, deleteMessageDiscord, discordMessageActions, editChannelDiscord, editDiscordComponentMessage, editMessageDiscord, fetchChannelInfoDiscord, fetchChannelPermissionsDiscord, fetchDiscordApplicationId, fetchDiscordApplicationSummary, fetchMemberGuildPermissionsDiscord, fetchMemberInfoDiscord, fetchMessageDiscord, fetchReactionsDiscord, fetchRoleInfoDiscord, fetchVoiceStatusDiscord, formatThreadBindingDurationLabel, getGateway, getPresence, getThreadBindingManager, handleDiscordAction, hasAllGuildPermissionsDiscord, hasAnyGuildPermissionDiscord, isAbortError, isDiscordGroupAllowedByPolicy, isDiscordModerationAction, kickMemberDiscord, listDiscordDirectoryGroupsLive, listDiscordDirectoryPeersLive, listGuildChannelsDiscord, listGuildEmojisDiscord, listPinsDiscord, listScheduledEventsDiscord, listThreadBindingsBySessionKey, listThreadBindingsForAccount, listThreadsDiscord, monitorDiscordProvider, moveChannelDiscord, normalizeDiscordAllowList, normalizeDiscordInboundWorkerTimeoutMs, normalizeDiscordListenerTimeoutMs, normalizeDiscordSlug, parseApplicationIdFromToken, pinMessageDiscord, presenceCacheSize, probeDiscord, reactMessageDiscord, readDiscordChannelCreateParams, readDiscordChannelEditParams, readDiscordChannelMoveParams, readDiscordModerationCommand, readDiscordParentIdParam, readMessagesDiscord, reconcileAcpThreadBindingsOnStartup, registerBuiltDiscordComponentMessage, registerDiscordListener, registerGateway, removeChannelPermissionDiscord, removeOwnReactionsDiscord, removeReactionDiscord, removeRoleDiscord, requiredGuildPermissionForModerationAction, resolveDiscordChannelAllowlist, resolveDiscordChannelConfig, resolveDiscordChannelConfigWithFallback, resolveDiscordCommandAuthorized, resolveDiscordGatewayIntents, resolveDiscordGuildEntry, resolveDiscordOutboundSessionRoute, resolveDiscordPrivilegedIntentsFromFlags, resolveDiscordReplyTarget, resolveDiscordShouldRequireMention, resolveDiscordThreadBindingIdleTimeoutMs, resolveDiscordThreadBindingMaxAgeMs, resolveDiscordUserAllowlist, resolveEventCoverImage, resolveGroupDmAllow, resolveThreadBindingIdleTimeoutMs, resolveThreadBindingInactivityExpiresAt, resolveThreadBindingIntroText, resolveThreadBindingMaxAgeExpiresAt, resolveThreadBindingMaxAgeMs, resolveThreadBindingPersona, resolveThreadBindingPersonaFromRecord, resolveThreadBindingThreadName, resolveThreadBindingsEnabled, runDiscordTaskWithTimeout, sanitizeDiscordThreadName, searchMessagesDiscord, sendDiscordComponentMessage, sendMessageDiscord, sendPollDiscord, sendStickerDiscord, sendTypingDiscord, sendVoiceMessageDiscord, sendWebhookMessageDiscord, setChannelPermissionDiscord, setDiscordRuntime, setPresence, setThreadBindingIdleTimeoutBySessionKey, setThreadBindingMaxAgeBySessionKey, shouldEmitDiscordReactionNotification, timeoutMemberDiscord, unbindThreadBindingsBySessionKey, unpinMessageDiscord, unregisterGateway, uploadEmojiDiscord, uploadStickerDiscord, waitForDiscordGatewayPluginRegistration };
@@ -1,8 +1,8 @@
1
1
  import { At as getGuildMember, Bt as removeGuildMemberRole, Ct as createGuildBan, Dt as createGuildSticker, Et as createGuildScheduledEvent, Ft as listGuildRoles, Ht as __exportAll, It as listGuildScheduledEvents, Lt as moveGuildChannels, Mt as listGuildActiveThreads, Nt as listGuildChannels, Ot as deleteChannelPermission, Pt as listGuildEmojis, Rt as putChannelPermission, S as readRetryAfter, St as addGuildMemberRole, Tt as createGuildEmoji, Vt as timeoutGuildMember, _ as DiscordError, _t as listChannelPins, at as listMessageReactionUsers, b as readDiscordCode, bt as sendChannelTyping, ct as deleteChannel, dt as editChannelMessage, ft as getChannel, gt as listChannelMessages, ht as listChannelArchivedThreads, it as deleteOwnMessageReaction, jt as getGuildVoiceState, kt as getGuild, lt as deleteChannelMessage, pt as getChannelMessage, rt as createOwnMessageReaction, st as createThread, ut as editChannel, v as RateLimitError, vt as pinChannelMessage, wt as createGuildChannel, x as readDiscordMessage, xt as unpinChannelMessage, y as isUnknownDiscordVoiceStateError, yt as searchGuildMessages, zt as removeGuildMember } from "./discord-CmL3ati-.js";
2
2
  import { C as parseDiscordRetryAfterBodySeconds } from "./allow-list-DWEio925.js";
3
- import { a as recordDiscordMessageCreateAmbiguity, c as createDiscordSendReceiptFromResults, l as createDiscordSendResult, n as classifyDiscordDeliveryFailure, o as chunkDiscordTextWithMode, r as createDiscordRetryRunner } from "./retry-B0lQ1Ado.js";
4
- import { C as hasAllGuildPermissionsDiscord, I as resolveDiscordClientAccountContext, K as parseAndResolveChannelRecipient, L as resolveDiscordRest, M as resolveDiscordSuppressEmbeds, N as createDiscordClient, O as createDiscordMessageNonce, R as DISCORD_REST_TIMEOUT_MS, S as fetchMemberGuildPermissionsDiscord, T as hasAnyGuildPermissionDiscord, _ as DiscordSendError, b as canViewDiscordGuildChannel, g as DISCORD_MAX_STICKER_BYTES, h as DISCORD_MAX_EVENT_COVER_BYTES, i as formatReactionEmoji, k as resolveDiscordMessageFlags, l as resolveChannelId, m as DISCORD_MAX_EMOJI_BYTES, n as buildDiscordTextChunks, o as normalizeEmojiName, p as sendDiscordText, r as buildReactionIdentifier, s as normalizeReactionEmoji, t as buildDiscordSendError, v as canManageGuildMemberRoleDiscord, w as hasAnyChannelPermissionDiscord, x as fetchChannelPermissionsDiscord, y as canManageGuildRoleDiscord } from "./send.shared-D4BAjlRo.js";
5
- import { i as prepareDiscordOutboundText, n as sendPollDiscord, r as sendStickerDiscord, t as sendMessageDiscord } from "./send.outbound-DF0P3C9J.js";
3
+ import { a as recordDiscordMessageCreateAmbiguity, c as createDiscordSendReceiptFromResults, l as createDiscordSendResult, n as classifyDiscordDeliveryFailure, o as chunkDiscordTextWithMode, r as createDiscordRetryRunner } from "./retry-DKeoT7UO.js";
4
+ import { C as hasAllGuildPermissionsDiscord, I as resolveDiscordClientAccountContext, K as parseAndResolveChannelRecipient, L as resolveDiscordRest, M as resolveDiscordSuppressEmbeds, N as createDiscordClient, O as createDiscordMessageNonce, R as DISCORD_REST_TIMEOUT_MS, S as fetchMemberGuildPermissionsDiscord, T as hasAnyGuildPermissionDiscord, _ as DiscordSendError, b as canViewDiscordGuildChannel, g as DISCORD_MAX_STICKER_BYTES, h as DISCORD_MAX_EVENT_COVER_BYTES, i as formatReactionEmoji, k as resolveDiscordMessageFlags, l as resolveChannelId, m as DISCORD_MAX_EMOJI_BYTES, n as buildDiscordTextChunks, o as normalizeEmojiName, p as sendDiscordText, r as buildReactionIdentifier, s as normalizeReactionEmoji, t as buildDiscordSendError, v as canManageGuildMemberRoleDiscord, w as hasAnyChannelPermissionDiscord, x as fetchChannelPermissionsDiscord, y as canManageGuildRoleDiscord } from "./send.shared-BHPM3CSl.js";
5
+ import { i as prepareDiscordOutboundText, n as sendPollDiscord, r as sendStickerDiscord, t as sendMessageDiscord } from "./send.outbound-BVTWrl_4.js";
6
6
  import { n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS } from "./timeouts-D86uWLt_.js";
7
7
  import fs from "node:fs/promises";
8
8
  import { ChannelType } from "discord-api-types/v10";
@@ -1,9 +1,9 @@
1
1
  import { Ht as __exportAll, dt as editChannelMessage, k as serializePayload, ot as createChannelMessage } from "./discord-CmL3ati-.js";
2
- import { d as buildDiscordComponentMessage, f as buildDiscordComponentMessageFlags, g as resolveDiscordComponentAttachmentName } from "./components-kvIwhN7i.js";
2
+ import { d as buildDiscordComponentMessage, f as buildDiscordComponentMessageFlags, g as resolveDiscordComponentAttachmentName } from "./components-DBFTIN6P.js";
3
3
  import { n as getOptionalDiscordRuntime } from "./runtime-DgnVQ7zW.js";
4
- import { l as createDiscordSendResult } from "./retry-B0lQ1Ado.js";
5
- import { E as SUPPRESS_NOTIFICATIONS_FLAG, K as parseAndResolveChannelRecipient, N as createDiscordClient, O as createDiscordMessageNonce, l as resolveChannelId, t as buildDiscordSendError, u as resolveDiscordChannel } from "./send.shared-D4BAjlRo.js";
6
- import { t as sendMessageDiscord } from "./send.outbound-DF0P3C9J.js";
4
+ import { l as createDiscordSendResult } from "./retry-DKeoT7UO.js";
5
+ import { E as SUPPRESS_NOTIFICATIONS_FLAG, K as parseAndResolveChannelRecipient, N as createDiscordClient, O as createDiscordMessageNonce, l as resolveChannelId, t as buildDiscordSendError, u as resolveDiscordChannel } from "./send.shared-BHPM3CSl.js";
6
+ import { t as sendMessageDiscord } from "./send.outbound-BVTWrl_4.js";
7
7
  import { ChannelType } from "discord-api-types/v10";
8
8
  import { asDateTimestampMs, isFutureDateTimestampMs, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
9
9
  import { hasNonEmptyString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -287,47 +287,22 @@ function withImplicitComponentAttachmentBlock(spec, attachmentName) {
287
287
  }]
288
288
  };
289
289
  }
290
- function hasClassicOnlyBlocks(spec) {
291
- return (spec.blocks ?? []).every((block) => block.type === "text" || block.type === "file");
292
- }
293
- function hasUnsupportedClassicFeatures(spec) {
294
- return Boolean(spec.modal || spec.container);
295
- }
296
- function hasAtMostOneNonSpoilerFile(spec) {
297
- let fileBlockCount = 0;
298
- for (const block of spec.blocks ?? []) {
299
- if (block.type !== "file") continue;
300
- fileBlockCount += 1;
301
- if (block.spoiler) return false;
302
- }
303
- return fileBlockCount <= 1;
304
- }
305
- /**
306
- * Keep the downgrade rules explicit because this path is only safe when the
307
- * spec means exactly what a plain Discord message can represent.
308
- */
309
- function getClassicDiscordMessageDecision(spec) {
310
- if (hasUnsupportedClassicFeatures(spec)) return {
311
- mode: "components",
312
- reason: "unsupported-feature"
313
- };
314
- if (!hasClassicOnlyBlocks(spec)) return {
315
- mode: "components",
316
- reason: "unsupported-block"
317
- };
318
- if (!hasAtMostOneNonSpoilerFile(spec)) return {
319
- mode: "components",
320
- reason: "multiple-or-spoiler-files"
321
- };
290
+ function resolveClassicDiscordMessage(spec) {
291
+ if (spec.modal || spec.container) return;
292
+ const parts = hasNonEmptyString(spec.text) ? [spec.text] : [];
293
+ let captionToMatch = parts[0];
294
+ let filename;
295
+ for (const block of spec.blocks ?? []) if (block.type === "text") {
296
+ if (!hasNonEmptyString(block.text)) continue;
297
+ if (block.text !== captionToMatch) parts.push(block.text);
298
+ captionToMatch = void 0;
299
+ } else if (block.type === "file" && !block.spoiler && filename === void 0) filename = resolveDiscordComponentAttachmentName(block.file);
300
+ else return;
322
301
  return {
323
- mode: "classic",
324
- reason: "plain-text-single-file"
302
+ text: parts.join("\n\n"),
303
+ filename
325
304
  };
326
305
  }
327
- function collapseClassicComponentText(spec) {
328
- const parts = [spec.text, ...(spec.blocks ?? []).flatMap((block) => block.type === "text" ? [block.text] : [])];
329
- return uniqueStrings(parts.filter(hasNonEmptyString)).join("\n\n");
330
- }
331
306
  function registerBuiltDiscordComponentMessage(params) {
332
307
  registerDiscordComponentEntries({
333
308
  entries: params.buildResult.entries,
@@ -393,14 +368,14 @@ async function buildDiscordComponentPayload(params) {
393
368
  };
394
369
  }
395
370
  async function sendDiscordComponentMessage(to, spec, opts) {
396
- const classicDecision = getClassicDiscordMessageDecision(spec);
397
- if (opts.mediaUrl && classicDecision.mode === "classic") return await sendMessageDiscord(to, collapseClassicComponentText(spec), {
371
+ const classicMessage = opts.mediaUrl ? resolveClassicDiscordMessage(spec) : void 0;
372
+ if (classicMessage) return await sendMessageDiscord(to, classicMessage.text, {
398
373
  cfg: opts.cfg,
399
374
  accountId: opts.accountId,
400
375
  token: opts.token,
401
376
  rest: opts.rest,
402
377
  mediaUrl: opts.mediaUrl,
403
- filename: opts.filename?.trim() || extractComponentAttachmentNames(spec)[0],
378
+ filename: opts.filename?.trim() || classicMessage.filename,
404
379
  mediaLocalRoots: opts.mediaLocalRoots,
405
380
  mediaReadFile: opts.mediaReadFile,
406
381
  mediaAccess: opts.mediaAccess,
@@ -1,7 +1,7 @@
1
1
  import { ot as createChannelMessage, st as createThread } from "./discord-CmL3ati-.js";
2
2
  import { i as normalizeDiscordHandleKey, o as resolveDiscordDirectoryUserId } from "./directory-live-C5o1uKlw.js";
3
- import { c as createDiscordSendReceiptFromResults, d as createReusableDiscordReplyReference, l as createDiscordSendResult } from "./retry-B0lQ1Ado.js";
4
- import { A as resolveDiscordSendComponents, D as buildDiscordMessageRequest, K as parseAndResolveChannelRecipient, M as resolveDiscordSuppressEmbeds, N as createDiscordClient, O as createDiscordMessageNonce, a as normalizeDiscordPollInput, c as normalizeStickerIds, f as sendDiscordMedia, j as resolveDiscordSendEmbeds, k as resolveDiscordMessageFlags, l as resolveChannelId, n as buildDiscordTextChunks, p as sendDiscordText, t as buildDiscordSendError, u as resolveDiscordChannel } from "./send.shared-D4BAjlRo.js";
3
+ import { c as createDiscordSendReceiptFromResults, d as createReusableDiscordReplyReference, l as createDiscordSendResult } from "./retry-DKeoT7UO.js";
4
+ import { A as resolveDiscordSendComponents, D as buildDiscordMessageRequest, K as parseAndResolveChannelRecipient, M as resolveDiscordSuppressEmbeds, N as createDiscordClient, O as createDiscordMessageNonce, a as normalizeDiscordPollInput, c as normalizeStickerIds, f as sendDiscordMedia, j as resolveDiscordSendEmbeds, k as resolveDiscordMessageFlags, l as resolveChannelId, n as buildDiscordTextChunks, p as sendDiscordText, t as buildDiscordSendError, u as resolveDiscordChannel } from "./send.shared-BHPM3CSl.js";
5
5
  import { ChannelType } from "discord-api-types/v10";
6
6
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
7
7
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -1,7 +1,7 @@
1
1
  import { A as Embed, At as getGuildMember, O as hasDiscordV2Components, ft as getChannel, g as RequestClient, k as serializePayload, kt as getGuild, mt as getThreadMember, nt as getCurrentUser, ot as createChannelMessage, tt as createUserDmChannel } from "./discord-CmL3ati-.js";
2
2
  import { c as resolveDiscordAccount, m as normalizeDiscordToken, o as mergeDiscordAccountConfig } from "./accounts-CwJQoLjM.js";
3
- import { f as resolveDiscordReplyMessageId, o as chunkDiscordTextWithMode, r as createDiscordRetryRunner } from "./retry-B0lQ1Ado.js";
4
- import { t as parseAndResolveDiscordTarget } from "./target-resolver-BgKUUwLy.js";
3
+ import { f as resolveDiscordReplyMessageId, o as chunkDiscordTextWithMode, r as createDiscordRetryRunner } from "./retry-DKeoT7UO.js";
4
+ import { t as parseAndResolveDiscordTarget } from "./target-resolver-CoFQ7iSX.js";
5
5
  import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
6
6
  import { ChannelType, MessageFlags, PermissionFlagsBits } from "discord-api-types/v10";
7
7
  import { randomBytes } from "node:crypto";
@@ -1,5 +1,5 @@
1
1
  import { Ht as __exportAll } from "./discord-CmL3ati-.js";
2
- import { o as unbindThreadBindingsBySessionKey, r as listThreadBindingsBySessionKey } from "./thread-bindings-B0wnEg_y.js";
2
+ import { o as unbindThreadBindingsBySessionKey, r as listThreadBindingsBySessionKey } from "./thread-bindings-uudC_0TY.js";
3
3
  import { normalizeOptionalLowercaseString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  //#region extensions/discord/src/subagent-hooks.ts
5
5
  var subagent_hooks_exports = /* @__PURE__ */ __exportAll({
@@ -1,6 +1,6 @@
1
1
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
2
2
  //#region extensions/discord/subagent-hooks-api.ts
3
- const loadDiscordSubagentHooksModule = createLazyRuntimeModule(() => import("./subagent-hooks-BAwybBDC.js").then((n) => n.r));
3
+ const loadDiscordSubagentHooksModule = createLazyRuntimeModule(() => import("./subagent-hooks-DfsiwCec.js").then((n) => n.r));
4
4
  function registerDiscordSubagentHooks(api) {
5
5
  api.on("subagent_ended", async (event) => {
6
6
  const { handleDiscordSubagentEnded } = await loadDiscordSubagentHooksModule();
@@ -1,7 +1,7 @@
1
1
  import { Ht as __exportAll } from "./discord-CmL3ati-.js";
2
2
  import { c as resolveDiscordAccount, l as resolveDiscordAccountAllowFrom } from "./accounts-CwJQoLjM.js";
3
3
  import { a as rememberDiscordDirectoryUser, r as listDiscordDirectoryPeersLive } from "./directory-live-C5o1uKlw.js";
4
- import { m as allowFromContainsDiscordUserId, v as parseDiscordTarget } from "./retry-B0lQ1Ado.js";
4
+ import { m as allowFromContainsDiscordUserId, v as parseDiscordTarget } from "./retry-DKeoT7UO.js";
5
5
  import { buildMessagingTarget } from "openclaw/plugin-sdk/channel-targets";
6
6
  //#region extensions/discord/src/send-target-parsing.ts
7
7
  const parseDiscordSendTarget = (raw, options = {}) => parseDiscordTarget(raw, options);
@@ -0,0 +1,3 @@
1
+ import "./retry-DKeoT7UO.js";
2
+ import "./target-resolver-CoFQ7iSX.js";
3
+ export {};
@@ -1,9 +1,9 @@
1
1
  import { Ht as __exportAll } from "./discord-CmL3ati-.js";
2
- import { v as parseDiscordTarget } from "./retry-B0lQ1Ado.js";
3
- import "./targets-fCxslBZ3.js";
4
- import { C as saveBindingsToDisk, E as shouldPersistBindingMutations, S as resolveThreadBindingMaxAgeMs$1, b as resolveThreadBindingInactivityExpiresAt, c as getThreadBindingToken, d as normalizeThreadId, f as refreshUnboundThreadWebhookIdentity, h as removeBindingRecord, n as MANAGERS_BY_ACCOUNT_ID, t as BINDINGS_BY_THREAD_ID, x as resolveThreadBindingMaxAgeExpiresAt, y as resolveThreadBindingIdleTimeoutMs$1 } from "./thread-bindings.state-jNRrsgzV.js";
5
- import { n as setThreadBindingMaxAgeBySessionKey, r as resolveBindingIdsForTargetSession, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-CSBmgCcx.js";
6
- import { c as resolveThreadBindingPersonaFromRecord, d as resolveThreadBindingThreadName, l as formatThreadBindingDurationLabel, n as createThreadBindingManager, o as resolveChannelIdForBinding, r as getThreadBindingManager, s as resolveThreadBindingPersona, t as createNoopThreadBindingManager, u as resolveThreadBindingIntroText } from "./thread-bindings.manager-DM7M3vzn.js";
2
+ import { v as parseDiscordTarget } from "./retry-DKeoT7UO.js";
3
+ import "./targets-Cm6aV9nJ.js";
4
+ import { C as saveBindingsToDisk, E as shouldPersistBindingMutations, S as resolveThreadBindingMaxAgeMs$1, b as resolveThreadBindingInactivityExpiresAt, c as getThreadBindingToken, d as normalizeThreadId, f as refreshUnboundThreadWebhookIdentity, h as removeBindingRecord, n as MANAGERS_BY_ACCOUNT_ID, t as BINDINGS_BY_THREAD_ID, x as resolveThreadBindingMaxAgeExpiresAt, y as resolveThreadBindingIdleTimeoutMs$1 } from "./thread-bindings.state-dDn-dwBw.js";
5
+ import { n as setThreadBindingMaxAgeBySessionKey, r as resolveBindingIdsForTargetSession, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-BwkXpcy0.js";
6
+ import { c as resolveThreadBindingPersonaFromRecord, d as resolveThreadBindingThreadName, l as formatThreadBindingDurationLabel, n as createThreadBindingManager, o as resolveChannelIdForBinding, r as getThreadBindingManager, s as resolveThreadBindingPersona, t as createNoopThreadBindingManager, u as resolveThreadBindingIntroText } from "./thread-bindings.manager-BeUxc8nr.js";
7
7
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
8
8
  import { normalizeOptionalLowercaseString, normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
9
9
  import { resolveThreadBindingIdleTimeoutMs, resolveThreadBindingMaxAgeMs, resolveThreadBindingsEnabled } from "openclaw/plugin-sdk/conversation-runtime";
@@ -1,11 +1,11 @@
1
1
  import { Ht as __exportAll, et as createChannelWebhook, ft as getChannel } from "./discord-CmL3ati-.js";
2
- import { t as canFallbackDiscordWebhookSend, y as resolveDiscordChannelId } from "./retry-B0lQ1Ado.js";
3
- import { P as createDiscordRestClient } from "./send.shared-D4BAjlRo.js";
4
- import { t as sendMessageDiscord } from "./send.outbound-DF0P3C9J.js";
2
+ import { t as canFallbackDiscordWebhookSend, y as resolveDiscordChannelId } from "./retry-DKeoT7UO.js";
3
+ import { P as createDiscordRestClient } from "./send.shared-BHPM3CSl.js";
4
+ import { t as sendMessageDiscord } from "./send.outbound-BVTWrl_4.js";
5
5
  import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
6
6
  import { n as resolveDiscordChannelInfoSafe, t as resolveDiscordChannelIdSafe } from "./channel-access-C12aDZ0p.js";
7
- import { c as sendWebhookMessageDiscord, u as createThreadDiscord } from "./send-Bdp3zZH5.js";
8
- import { C as saveBindingsToDisk, O as toReusableWebhookKey, S as resolveThreadBindingMaxAgeMs$1, T as shouldDefaultPersist, _ as resolveBindingRecordKey, a as THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS, c as getThreadBindingToken, d as normalizeThreadId, f as refreshUnboundThreadWebhookIdentity, g as resolveBindingIdsForSession, h as removeBindingRecord, i as REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL, l as normalizeTargetKind, m as rememberThreadBindingToken, n as MANAGERS_BY_ACCOUNT_ID, o as ensureBindingsLoaded, p as rememberReusableWebhook, r as PERSIST_BY_ACCOUNT_ID, s as forgetThreadBindingToken, t as BINDINGS_BY_THREAD_ID, u as normalizeThreadBindingDurationMs, v as resolvePreparedThreadBindingLifecycle, w as setBindingRecord, y as resolveThreadBindingIdleTimeoutMs$1 } from "./thread-bindings.state-jNRrsgzV.js";
7
+ import { c as sendWebhookMessageDiscord, u as createThreadDiscord } from "./send-CLpzfzJe.js";
8
+ import { C as saveBindingsToDisk, O as toReusableWebhookKey, S as resolveThreadBindingMaxAgeMs$1, T as shouldDefaultPersist, _ as resolveBindingRecordKey, a as THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS, c as getThreadBindingToken, d as normalizeThreadId, f as refreshUnboundThreadWebhookIdentity, g as resolveBindingIdsForSession, h as removeBindingRecord, i as REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL, l as normalizeTargetKind, m as rememberThreadBindingToken, n as MANAGERS_BY_ACCOUNT_ID, o as ensureBindingsLoaded, p as rememberReusableWebhook, r as PERSIST_BY_ACCOUNT_ID, s as forgetThreadBindingToken, t as BINDINGS_BY_THREAD_ID, u as normalizeThreadBindingDurationMs, v as resolvePreparedThreadBindingLifecycle, w as setBindingRecord, y as resolveThreadBindingIdleTimeoutMs$1 } from "./thread-bindings.state-dDn-dwBw.js";
9
9
  import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
10
10
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
11
11
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -1,4 +1,4 @@
1
- import { C as saveBindingsToDisk, E as shouldPersistBindingMutations, g as resolveBindingIdsForSession, o as ensureBindingsLoaded, t as BINDINGS_BY_THREAD_ID, w as setBindingRecord } from "./thread-bindings.state-jNRrsgzV.js";
1
+ import { C as saveBindingsToDisk, E as shouldPersistBindingMutations, g as resolveBindingIdsForSession, o as ensureBindingsLoaded, t as BINDINGS_BY_THREAD_ID, w as setBindingRecord } from "./thread-bindings.state-dDn-dwBw.js";
2
2
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
3
3
  //#region extensions/discord/src/monitor/thread-bindings.session-shared.ts
4
4
  function normalizeNonNegativeMs(raw) {
@@ -3,7 +3,7 @@ import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
3
3
  import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
4
4
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { recordOutboundMessageIdentity } from "openclaw/plugin-sdk/outbound-echo-runtime";
6
- import * as threadBindingRuntime from "openclaw/plugin-sdk/thread-bindings-session-runtime";
6
+ import { resolveThreadBindingExpiry } from "openclaw/plugin-sdk/thread-bindings-session-runtime";
7
7
  //#region extensions/discord/src/monitor/thread-bindings.state.ts
8
8
  var thread_bindings_state_exports = /* @__PURE__ */ __exportAll({
9
9
  BINDINGS_BY_THREAD_ID: () => BINDINGS_BY_THREAD_ID,
@@ -170,20 +170,6 @@ function resolveTimestampExpiry(timestamp, durationMs) {
170
170
  const at = Math.floor(timestamp);
171
171
  return Number.isFinite(at) && at > 0 ? at + durationMs : void 0;
172
172
  }
173
- const threadBindingExpirySdk = threadBindingRuntime;
174
- function resolveThreadBindingExpiryForHost(params) {
175
- if (threadBindingExpirySdk.resolveThreadBindingExpiry) return threadBindingExpirySdk.resolveThreadBindingExpiry(params);
176
- const { inactivityExpiresAt, maxAgeExpiresAt } = params;
177
- if (inactivityExpiresAt != null && (maxAgeExpiresAt == null || inactivityExpiresAt <= maxAgeExpiresAt)) return {
178
- expiresAt: inactivityExpiresAt,
179
- reason: "idle-expired"
180
- };
181
- if (maxAgeExpiresAt != null) return {
182
- expiresAt: maxAgeExpiresAt,
183
- reason: "max-age-expired"
184
- };
185
- return {};
186
- }
187
173
  function resolvePreparedThreadBindingLifecycle(params) {
188
174
  const idleTimeoutMs = resolveThreadBindingIdleTimeoutMs({
189
175
  record: params.record,
@@ -196,7 +182,7 @@ function resolvePreparedThreadBindingLifecycle(params) {
196
182
  return {
197
183
  idleTimeoutMs,
198
184
  maxAgeMs,
199
- ...resolveThreadBindingExpiryForHost({
185
+ ...resolveThreadBindingExpiry({
200
186
  inactivityExpiresAt: resolveTimestampExpiry(params.record.lastActivityAt, idleTimeoutMs),
201
187
  maxAgeExpiresAt: resolveTimestampExpiry(params.record.boundAt, maxAgeMs)
202
188
  })
@@ -1,10 +1,10 @@
1
1
  import { Ht as __exportAll, jt as getGuildVoiceState, l as ReadyListener, p as VoiceStateUpdateListener, t as discord_exports, u as ResumedListener, y as isUnknownDiscordVoiceStateError } from "./discord-CmL3ati-.js";
2
2
  import { a as normalizeDiscordSlug, b as formatDiscordUserTag, m as resolveDiscordOwnerAccess } from "./allow-list-DWEio925.js";
3
3
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
4
- import { v as parseDiscordTarget } from "./retry-B0lQ1Ado.js";
5
- import { o as formatMention } from "./send.outbound-DF0P3C9J.js";
4
+ import { v as parseDiscordTarget } from "./retry-DKeoT7UO.js";
5
+ import { o as formatMention } from "./send.outbound-BVTWrl_4.js";
6
6
  import { a as authorizeDiscordVoiceIngress, i as resolveDiscordVoiceEnabled, n as resolveDiscordTranscriptsCapture, o as resolveDiscordVoiceAccess, s as resolveDiscordVoiceAccessTarget } from "./transcripts-source-VkgenQv-.js";
7
- import { m as buildDiscordGroupSystemPrompt } from "./provider-PI8UiejY.js";
7
+ import { m as buildDiscordGroupSystemPrompt } from "./provider-DmRHCZ_K.js";
8
8
  import { createRequire } from "node:module";
9
9
  import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
10
10
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
@@ -2962,7 +2962,7 @@ var DiscordVoiceSessions = class {
2962
2962
  ok: false,
2963
2963
  message: "Discord realtime voice session stopped before startup completed."
2964
2964
  };
2965
- const { DiscordRealtimeVoiceSession } = await import("./realtime-session.runtime-MqPrvmQ1.js");
2965
+ const { DiscordRealtimeVoiceSession } = await import("./realtime-session.runtime-Bjsk9Q5t.js");
2966
2966
  const realtime = new DiscordRealtimeVoiceSession({
2967
2967
  accountId: this.params.accountId,
2968
2968
  bootstrapContextInstructions,
@@ -1,5 +1,9 @@
1
1
  {
2
2
  "id": "discord",
3
+ "categories": [
4
+ "channels",
5
+ "voice"
6
+ ],
3
7
  "doctorContract": {
4
8
  "configRepair": true,
5
9
  "stateMigrations": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/discord",
3
- "version": "2026.9.3",
3
+ "version": "2026.9.4",
4
4
  "description": "OpenClaw Discord channel plugin for channels, DMs, commands, and app events.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,7 +19,7 @@
19
19
  "zod": "4.4.3"
20
20
  },
21
21
  "peerDependencies": {
22
- "openclaw": ">=2026.9.3"
22
+ "openclaw": ">=2026.9.4"
23
23
  },
24
24
  "peerDependenciesMeta": {
25
25
  "openclaw": {
@@ -88,17 +88,18 @@
88
88
  }
89
89
  },
90
90
  "install": {
91
+ "clawhubSpec": "clawhub:@openclaw/discord",
91
92
  "npmSpec": "@openclaw/discord",
92
93
  "defaultChoice": "npm",
93
94
  "minHostVersion": ">=2026.5.26",
94
95
  "allowInvalidConfigRecovery": true
95
96
  },
96
97
  "compat": {
97
- "pluginApi": ">=2026.9.3"
98
+ "pluginApi": ">=2026.9.4"
98
99
  },
99
100
  "build": {
100
101
  "bundledDist": false,
101
- "openclawVersion": "2026.9.3",
102
+ "openclawVersion": "2026.9.4",
102
103
  "staticAssets": [
103
104
  {
104
105
  "source": "./assets/embedded-app-sdk.mjs",
@@ -1,2 +0,0 @@
1
- import { t as monitorDiscordProvider } from "./provider-PI8UiejY.js";
2
- export { monitorDiscordProvider };
@@ -1,3 +0,0 @@
1
- import "./retry-B0lQ1Ado.js";
2
- import "./target-resolver-BgKUUwLy.js";
3
- export {};