@openclaw/discord 2026.7.2-beta.2 → 2026.7.2-beta.3

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 (85) hide show
  1. package/dist/action-runtime-api.js +1 -1
  2. package/dist/{activities-api-D0D_87n3.js → activities-api-DS1L7KRY.js} +15 -42
  3. package/dist/activities-api.js +1 -1
  4. package/dist/{allow-list-B7qOH5xu.js → allow-list-DzKrtfah.js} +18 -7
  5. package/dist/{api-B88T4rFN.js → api-C43z8vUm.js} +3 -1
  6. package/dist/api.js +25 -16
  7. package/dist/{approval-handler.runtime-B7E1-x5q.js → approval-handler.runtime-BbkfPoGc.js} +5 -6
  8. package/dist/{conversation-identity-BPcbhCAH.js → approval-message-safety-DrLlgIPz.js} +48 -2
  9. package/dist/{audit-CjpnY1yb.js → audit-BC6bgPMX.js} +3 -3
  10. package/dist/{channel-BDfKr14H.js → channel-5MfaC2IE.js} +18 -18
  11. package/dist/{channel-actions-BQct-o4T.js → channel-actions-DicWTbYH.js} +2 -2
  12. package/dist/{channel-actions.runtime-CC4QwYVO.js → channel-actions.runtime-D9Qadn-l.js} +8 -8
  13. package/dist/channel-config-api.js +1 -1
  14. package/dist/channel-plugin-api.js +1 -1
  15. package/dist/{channel.setup-BS4gd8sc.js → channel.setup-CJXfFclP.js} +3 -3
  16. package/dist/{chunk-CHpY_lsO.js → chunk-CWzmeWf_.js} +9 -49
  17. package/dist/{config-schema-CoDck1GW.js → config-schema-BxrgfSMD.js} +4 -0
  18. package/dist/{directory-config-G1QwBIdi.js → directory-config-CmukHSms.js} +1 -1
  19. package/dist/directory-contract-api.js +1 -1
  20. package/dist/{directory-live-nfvekMil.js → directory-live-BYlCRO__.js} +3 -3
  21. package/dist/{doctor-Bq4pJAQk.js → doctor-Ci7USQAW.js} +1 -1
  22. package/dist/{handle-action.guild-admin-LYY75_Oa.js → handle-action.guild-admin-Bsk2YBPs.js} +2 -2
  23. package/dist/index.js +2 -2
  24. package/dist/{manager.runtime-w6VVYQMl.js → manager.runtime-Cc8vS-M7.js} +98 -145
  25. package/dist/message-handler-CWJ-mQvH.js +590 -0
  26. package/dist/{message-handler.preflight-DnAH04Ss.js → message-handler.preflight-DK46_qbS.js} +16 -15
  27. package/dist/{message-handler.process-ClgKz8I5.js → message-handler.process-BK0mjFJH.js} +37 -61
  28. package/dist/{message-utils-BU3gc01v.js → message-utils-Cfe6CZ6N.js} +1 -1
  29. package/dist/{outbound-adapter-ByoXsR-V.js → outbound-adapter-B2_oa-zV.js} +36 -5
  30. package/dist/{outbound-components-7wAolLuS.js → outbound-components-BGhk6HI3.js} +3 -3
  31. package/dist/{outbound-session-route-D4QqePZN.js → outbound-session-route-M2bEY9tI.js} +36 -6
  32. package/dist/{pluralkit-r4wiI2yy.js → pluralkit-CT0VRsZd.js} +1 -1
  33. package/dist/{probe-WKeTYyJX.js → probe-C3SCKyYU.js} +1 -1
  34. package/dist/{probe.runtime-CRY-qUke.js → probe.runtime-D55QqC9u.js} +1 -1
  35. package/dist/{provider-PRlF_lZm.js → provider-HW0G-2l6.js} +868 -794
  36. package/dist/{provider-session.runtime-BZPUZRjn.js → provider-session.runtime-cCfGMsF_.js} +3 -3
  37. package/dist/provider.runtime-BWCRsVoT.js +2 -0
  38. package/dist/{resolve-allowlist-common-QN7VMZaC.js → resolve-allowlist-common-CJlqw_nC.js} +2 -2
  39. package/dist/{resolve-channels-BO9NUPlS.js → resolve-channels-9KcG3mLg.js} +4 -4
  40. package/dist/{resolve-users-CU3oG5-m.js → resolve-users-GCGf3oV0.js} +3 -3
  41. package/dist/{runtime-CCf5nkV3.js → runtime-CD5MRZkD.js} +1 -2
  42. package/dist/{runtime-BsefAQ9q.js → runtime-Z2qkKakn.js} +9 -8
  43. package/dist/runtime-api.actions.js +2 -2
  44. package/dist/runtime-api.js +23 -22
  45. package/dist/runtime-api.lookup.js +5 -5
  46. package/dist/runtime-api.monitor-C3EDYJqk.js +6 -0
  47. package/dist/runtime-api.monitor.js +8 -8
  48. package/dist/runtime-api.send.js +6 -5
  49. package/dist/runtime-api.threads.js +3 -3
  50. package/dist/{secret-config-contract-BDNrRWvd.js → secret-config-contract-B1akrlyY.js} +1 -0
  51. package/dist/secret-contract-api.js +1 -1
  52. package/dist/security-audit-contract-api.js +1 -1
  53. package/dist/{security-audit.runtime-K0nkzjzJ.js → security-audit.runtime-DEEywczv.js} +1 -1
  54. package/dist/{send-JJzVo_sK.js → send-CSRxNNgq.js} +7 -86
  55. package/dist/{send.components-CCRW54gK.js → send.components-DLqzOEPJ.js} +5 -4
  56. package/dist/{send.outbound-Cvulb-k_.js → send.outbound-C1SfX20w.js} +4 -3
  57. package/dist/send.reactions-Cj4ugX3F.js +85 -0
  58. package/dist/send.receipt-CuwRrpFz.js +48 -0
  59. package/dist/{send.shared-XuOTO1dW.js → send.shared-Dber6X57.js} +2 -2
  60. package/dist/{sender-identity-C62lBe18.js → sender-identity-mG_zsdox.js} +1 -1
  61. package/dist/session-binding-contract-api.js +1 -1
  62. package/dist/setup-plugin-api.js +1 -1
  63. package/dist/{shared-Bngr0I-v.js → shared-BEhmAdMY.js} +5 -5
  64. package/dist/{subagent-hooks-mSxRv4AE.js → subagent-hooks-Wrk61DwY.js} +2 -2
  65. package/dist/subagent-hooks-api.js +10 -1
  66. package/dist/subagent-progress-B2fpHe3m.js +662 -0
  67. package/dist/{system-events-BANBRAe3.js → system-events-AhfcKRRb.js} +2 -2
  68. package/dist/{target-resolver-BaEmTxeK.js → target-resolver-vqLA450R.js} +2 -2
  69. package/dist/targets-BjEMIe8t.js +3 -0
  70. package/dist/{thread-bindings-4MV-u8vU.js → thread-bindings-CJQoXuWY.js} +4 -4
  71. package/dist/{thread-bindings.discord-api-DXfXsHGZ.js → thread-bindings.discord-api-mNCWlgvM.js} +4 -4
  72. package/dist/{thread-bindings.manager-DJ4cO5Eu.js → thread-bindings.manager-D1z8mK4b.js} +3 -3
  73. package/dist/{timeouts-D5lWili0.js → timeouts-B9cy6RvQ.js} +1 -6
  74. package/dist/{transcripts-source-TDZcMriu.js → transcripts-source-DjDbt14x.js} +1 -1
  75. package/dist/transcripts-source-api.js +1 -1
  76. package/dist/{typing-CKd2NMWG.js → typing-wxtm1NlF.js} +2 -2
  77. package/npm-shrinkwrap.json +3 -3
  78. package/openclaw.plugin.json +10 -0
  79. package/package.json +4 -4
  80. package/dist/approval-message-safety-C-8BL6Kv.js +0 -47
  81. package/dist/message-handler-DExaghWK.js +0 -331
  82. package/dist/provider.runtime-BX8GcCYx.js +0 -2
  83. package/dist/runtime-api.monitor-DCS_ETft.js +0 -6
  84. package/dist/targets-fjJt3PYG.js +0 -3
  85. package/dist/{security-audit-aLbWmUjl.js → security-audit-DtT0SIns.js} +1 -1
@@ -1,9 +1,9 @@
1
- import { Zt as __exportAll, d as parseDiscordTarget } from "./chunk-CHpY_lsO.js";
2
- import "./targets-fjJt3PYG.js";
1
+ import { Yt as __exportAll, l as parseDiscordTarget } from "./chunk-CWzmeWf_.js";
2
+ import "./targets-BjEMIe8t.js";
3
3
  import { A as shouldPersistBindingMutations, C as resolveThreadBindingIdleTimeoutMs$1, D as saveBindingsToDisk, E as resolveThreadBindingMaxAgeMs$1, T as resolveThreadBindingMaxAgeExpiresAt, d as isRecentlyUnboundThreadWebhookMessage, g as rememberRecentUnboundWebhookEcho, h as normalizeThreadId, n as MANAGERS_BY_ACCOUNT_ID, t as BINDINGS_BY_THREAD_ID, u as getThreadBindingToken, w as resolveThreadBindingInactivityExpiresAt, y as removeBindingRecord } from "./thread-bindings.state-C5afR9TD.js";
4
4
  import { n as setThreadBindingMaxAgeBySessionKey, r as resolveBindingIdsForTargetSession, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-DnTpkroM.js";
5
- import { _ as formatThreadBindingDurationLabel, b as resolveThreadBindingThreadName, g as resolveThreadBindingPersonaFromRecord, h as resolveThreadBindingPersona, s as resolveChannelIdForBinding, y as resolveThreadBindingIntroText } from "./thread-bindings.discord-api-DXfXsHGZ.js";
6
- import { i as testing, n as createThreadBindingManager, r as getThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-DJ4cO5Eu.js";
5
+ import { _ as formatThreadBindingDurationLabel, b as resolveThreadBindingThreadName, g as resolveThreadBindingPersonaFromRecord, h as resolveThreadBindingPersona, s as resolveChannelIdForBinding, y as resolveThreadBindingIntroText } from "./thread-bindings.discord-api-mNCWlgvM.js";
6
+ import { i as testing, n as createThreadBindingManager, r as getThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-D1z8mK4b.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,7 +1,7 @@
1
- import { f as resolveDiscordChannelId, lt as createChannelWebhook, xt as getChannel } from "./chunk-CHpY_lsO.js";
2
- import { F as createDiscordRestClient } from "./send.shared-XuOTO1dW.js";
3
- import { t as sendMessageDiscord } from "./send.outbound-Cvulb-k_.js";
4
- import { c as sendWebhookMessageDiscord, u as createThreadDiscord } from "./send-JJzVo_sK.js";
1
+ import { st as createChannelWebhook, u as resolveDiscordChannelId, yt as getChannel } from "./chunk-CWzmeWf_.js";
2
+ import { F as createDiscordRestClient } from "./send.shared-Dber6X57.js";
3
+ import { t as sendMessageDiscord } from "./send.outbound-C1SfX20w.js";
4
+ import { a as createThreadDiscord, r as sendWebhookMessageDiscord } from "./send-CSRxNNgq.js";
5
5
  import { M as toReusableWebhookKey, _ as rememberReusableWebhook, i as REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL, t as BINDINGS_BY_THREAD_ID } from "./thread-bindings.state-C5afR9TD.js";
6
6
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  import { ChannelType } from "discord-api-types/v10";
@@ -1,7 +1,7 @@
1
- import { Zt as __exportAll, f as resolveDiscordChannelId, xt as getChannel } from "./chunk-CHpY_lsO.js";
2
- import { F as createDiscordRestClient } from "./send.shared-XuOTO1dW.js";
1
+ import { Yt as __exportAll, u as resolveDiscordChannelId, yt as getChannel } from "./chunk-CWzmeWf_.js";
2
+ import { F as createDiscordRestClient } from "./send.shared-Dber6X57.js";
3
3
  import { C as resolveThreadBindingIdleTimeoutMs$1, D as saveBindingsToDisk, E as resolveThreadBindingMaxAgeMs$1, F as THREAD_BINDINGS_SWEEP_INTERVAL_MS, N as DEFAULT_THREAD_BINDING_IDLE_TIMEOUT_MS, O as setBindingRecord, S as resolveBindingRecordKey, T as resolveThreadBindingMaxAgeExpiresAt, b as resetThreadBindingsForTests, c as ensureBindingsLoaded, g as rememberRecentUnboundWebhookEcho, h as normalizeThreadId, k as shouldDefaultPersist, l as forgetThreadBindingToken, m as normalizeThreadBindingDurationMs, n as MANAGERS_BY_ACCOUNT_ID, p as normalizeTargetKind, r as PERSIST_BY_ACCOUNT_ID, s as THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS, t as BINDINGS_BY_THREAD_ID, u as getThreadBindingToken, v as rememberThreadBindingToken, w as resolveThreadBindingInactivityExpiresAt, x as resolveBindingIdsForSession, y as removeBindingRecord } from "./thread-bindings.state-C5afR9TD.js";
4
- import { a as isThreadArchived, b as resolveThreadBindingThreadName, c as summarizeDiscordError, i as isDiscordThreadGoneError, n as createWebhookForChannel, o as maybeSendBindingMessage, r as findReusableWebhook, s as resolveChannelIdForBinding, t as createThreadForBinding, v as resolveThreadBindingFarewellText } from "./thread-bindings.discord-api-DXfXsHGZ.js";
4
+ import { a as isThreadArchived, b as resolveThreadBindingThreadName, c as summarizeDiscordError, i as isDiscordThreadGoneError, n as createWebhookForChannel, o as maybeSendBindingMessage, r as findReusableWebhook, s as resolveChannelIdForBinding, t as createThreadForBinding, v as resolveThreadBindingFarewellText } from "./thread-bindings.discord-api-mNCWlgvM.js";
5
5
  import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
6
6
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  import { getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
@@ -20,11 +20,6 @@ function isAbortError(error) {
20
20
  if (typeof error !== "object" || error === null) return false;
21
21
  return "name" in error && String(error.name) === "AbortError";
22
22
  }
23
- /** @deprecated Use native `AbortSignal.any` after filtering optional signals at the call site. */
24
- function mergeAbortSignals(signals) {
25
- const activeSignals = signals.filter((signal) => Boolean(signal));
26
- return activeSignals.length > 1 ? AbortSignal.any(activeSignals) : activeSignals[0];
27
- }
28
23
  /** @deprecated Discord no longer uses this for channel-owned message run timeouts. */
29
24
  async function runDiscordTaskWithTimeout(params) {
30
25
  const timeoutMs = params.timeoutMs === void 0 ? void 0 : resolveTimerTimeoutMs(params.timeoutMs, 0, 0);
@@ -92,4 +87,4 @@ async function withAbortTimeout(params) {
92
87
  }
93
88
  }
94
89
  //#endregion
95
- export { isAbortError as a, normalizeDiscordListenerTimeoutMs as c, withAbortTimeout as d, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS as i, raceWithTimeout as l, DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS as n, mergeAbortSignals as o, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS as r, normalizeDiscordInboundWorkerTimeoutMs as s, DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS as t, runDiscordTaskWithTimeout as u };
90
+ export { isAbortError as a, raceWithTimeout as c, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS as i, runDiscordTaskWithTimeout as l, DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS as n, normalizeDiscordInboundWorkerTimeoutMs as o, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS as r, normalizeDiscordListenerTimeoutMs as s, DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS as t, withAbortTimeout as u };
@@ -1,4 +1,4 @@
1
- import { Zt as __exportAll } from "./chunk-CHpY_lsO.js";
1
+ import { Yt as __exportAll } from "./chunk-CWzmeWf_.js";
2
2
  //#region extensions/discord/src/voice/transcripts-source.ts
3
3
  var transcripts_source_exports = /* @__PURE__ */ __exportAll({
4
4
  discordVoiceTranscriptsSourceProvider: () => discordVoiceTranscriptsSourceProvider,
@@ -1,2 +1,2 @@
1
- import { t as discordVoiceTranscriptsSourceProvider } from "./transcripts-source-TDZcMriu.js";
1
+ import { t as discordVoiceTranscriptsSourceProvider } from "./transcripts-source-DjDbt14x.js";
2
2
  export { discordVoiceTranscriptsSourceProvider };
@@ -1,5 +1,5 @@
1
- import { Zt as __exportAll, kt as sendChannelTyping } from "./chunk-CHpY_lsO.js";
2
- import { l as raceWithTimeout } from "./timeouts-D5lWili0.js";
1
+ import { Dt as sendChannelTyping, Yt as __exportAll } from "./chunk-CWzmeWf_.js";
2
+ import { c as raceWithTimeout } from "./timeouts-B9cy6RvQ.js";
3
3
  //#region extensions/discord/src/monitor/typing.ts
4
4
  var typing_exports = /* @__PURE__ */ __exportAll({ sendTyping: () => sendTyping });
5
5
  const DISCORD_TYPING_START_TIMEOUT_MS = 5e3;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@openclaw/discord",
3
- "version": "2026.7.2-beta.2",
3
+ "version": "2026.7.2-beta.3",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/discord",
9
- "version": "2026.7.2-beta.2",
9
+ "version": "2026.7.2-beta.3",
10
10
  "dependencies": {
11
11
  "@discord/embedded-app-sdk": "2.5.0",
12
12
  "@discordjs/voice": "0.19.2",
@@ -18,7 +18,7 @@
18
18
  "ws": "8.21.0"
19
19
  },
20
20
  "peerDependencies": {
21
- "openclaw": ">=2026.7.2-beta.2"
21
+ "openclaw": ">=2026.7.2-beta.3"
22
22
  },
23
23
  "peerDependenciesMeta": {
24
24
  "openclaw": {
@@ -1086,6 +1086,9 @@
1086
1086
  },
1087
1087
  "additionalProperties": false
1088
1088
  },
1089
+ "subagentProgress": {
1090
+ "type": "boolean"
1091
+ },
1089
1092
  "intents": {
1090
1093
  "type": "object",
1091
1094
  "properties": {
@@ -2951,6 +2954,9 @@
2951
2954
  },
2952
2955
  "additionalProperties": false
2953
2956
  },
2957
+ "subagentProgress": {
2958
+ "type": "boolean"
2959
+ },
2954
2960
  "intents": {
2955
2961
  "type": "object",
2956
2962
  "properties": {
@@ -3950,6 +3956,10 @@
3950
3956
  "label": "Discord Thread Spawn Context",
3951
3957
  "help": "Default native subagent context for thread-bound spawns. \"fork\" starts from the requester transcript; \"isolated\" starts clean. Default: \"fork\"."
3952
3958
  },
3959
+ "subagentProgress": {
3960
+ "label": "Discord Subagent Progress",
3961
+ "help": "Show active subagent count reactions and typing on the source message. Default: false."
3962
+ },
3953
3963
  "ui.components.accentColor": {
3954
3964
  "label": "Discord Component Accent Color",
3955
3965
  "help": "Accent color for Discord component containers (hex). Set per account via channels.discord.accounts.<id>.ui.components.accentColor."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/discord",
3
- "version": "2026.7.2-beta.2",
3
+ "version": "2026.7.2-beta.3",
4
4
  "description": "OpenClaw Discord channel plugin for channels, DMs, commands, and app events.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,7 +18,7 @@
18
18
  "ws": "8.21.0"
19
19
  },
20
20
  "peerDependencies": {
21
- "openclaw": ">=2026.7.2-beta.2"
21
+ "openclaw": ">=2026.7.2-beta.3"
22
22
  },
23
23
  "peerDependenciesMeta": {
24
24
  "openclaw": {
@@ -63,10 +63,10 @@
63
63
  "allowInvalidConfigRecovery": true
64
64
  },
65
65
  "compat": {
66
- "pluginApi": ">=2026.7.2-beta.2"
66
+ "pluginApi": ">=2026.7.2-beta.3"
67
67
  },
68
68
  "build": {
69
- "openclawVersion": "2026.7.2-beta.2",
69
+ "openclawVersion": "2026.7.2-beta.3",
70
70
  "staticAssets": [
71
71
  {
72
72
  "source": "./assets/embedded-app-sdk.mjs",
@@ -1,47 +0,0 @@
1
- //#region extensions/discord/src/approval-message-safety.ts
2
- const DISCORD_APPROVAL_ALLOWED_MENTIONS = { parse: [] };
3
- const DISCORD_MARKDOWN_META_CHARACTERS = /* @__PURE__ */ new Set([
4
- "\\",
5
- "`",
6
- "*",
7
- "_",
8
- "{",
9
- "}",
10
- "[",
11
- "]",
12
- "(",
13
- ")",
14
- "<",
15
- ">",
16
- "#",
17
- "+",
18
- "-",
19
- ".",
20
- "!",
21
- "|",
22
- "~"
23
- ]);
24
- function escapeDiscordApprovalDisplayCharacter(character) {
25
- if (character === "\n") return "\\n";
26
- if (character === "\r") return "\\r";
27
- if (character === " ") return "\\t";
28
- const codePoint = character.codePointAt(0) ?? 0;
29
- if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159 || codePoint === 8232 || codePoint === 8233) return `\\u{${codePoint.toString(16).padStart(4, "0")}}`;
30
- return DISCORD_MARKDOWN_META_CHARACTERS.has(character) ? `\\${character}` : character;
31
- }
32
- /** Keep opaque approval metadata bounded, single-line, and inert in Discord Markdown. */
33
- function formatDiscordApprovalDisplayValue(value, maxChars = 200) {
34
- const limit = Number.isFinite(maxChars) ? Math.max(0, Math.trunc(maxChars)) : 200;
35
- const escapedParts = Array.from(value, escapeDiscordApprovalDisplayCharacter);
36
- const escaped = escapedParts.join("");
37
- if (escaped.length <= limit) return escaped;
38
- if (limit <= 3) return ".".repeat(limit);
39
- let bounded = "";
40
- for (const part of escapedParts) {
41
- if (bounded.length + part.length > limit - 3) break;
42
- bounded += part;
43
- }
44
- return `${bounded}...`;
45
- }
46
- //#endregion
47
- export { formatDiscordApprovalDisplayValue as n, DISCORD_APPROVAL_ALLOWED_MENTIONS as t };
@@ -1,331 +0,0 @@
1
- import { d as resolveDiscordChannelNameSafe, l as resolveDiscordChannelIdSafe, p as resolveDiscordChannelParentSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-DXfXsHGZ.js";
2
- import { c as hasDiscordMessageStickers, d as resolveDiscordMessageChannelId, r as resolveDiscordMessageText } from "./message-utils-BU3gc01v.js";
3
- import { danger } from "openclaw/plugin-sdk/runtime-env";
4
- import { resolveBatchedReplyThreadingPolicy } from "openclaw/plugin-sdk/reply-reference";
5
- import { createChannelRunQueue } from "openclaw/plugin-sdk/channel-outbound";
6
- import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
7
- import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
8
- import { createChannelInboundDebouncer, shouldDebounceTextInbound } from "openclaw/plugin-sdk/channel-inbound";
9
- import { createChannelReplayGuard } from "openclaw/plugin-sdk/persistent-dedupe";
10
- //#region extensions/discord/src/monitor/inbound-dedupe.ts
11
- const RECENT_DISCORD_MESSAGE_TTL_MS = 5 * 6e4;
12
- const RECENT_DISCORD_MESSAGE_MAX = 5e3;
13
- function createDiscordInboundReplayGuard() {
14
- return createChannelReplayGuard({
15
- dedupe: {
16
- ttlMs: RECENT_DISCORD_MESSAGE_TTL_MS,
17
- memoryMaxSize: RECENT_DISCORD_MESSAGE_MAX
18
- },
19
- buildReplayKey: (keys) => keys
20
- });
21
- }
22
- var DiscordRetryableInboundError = class extends Error {
23
- constructor(message, options) {
24
- super(message, options);
25
- this.name = "DiscordRetryableInboundError";
26
- }
27
- };
28
- function buildDiscordInboundReplayKey(params) {
29
- const messageId = params.data.message?.id?.trim();
30
- if (!messageId) return null;
31
- const channelId = resolveDiscordMessageChannelId({
32
- message: params.data.message,
33
- eventChannelId: params.data.channel_id
34
- });
35
- if (!channelId) return null;
36
- return `${params.accountId}:${channelId}:${messageId}`;
37
- }
38
- //#endregion
39
- //#region extensions/discord/src/monitor/inbound-job.ts
40
- function resolveDiscordInboundJobQueueKey(ctx) {
41
- const sessionKey = ctx.route.sessionKey?.trim();
42
- if (sessionKey) return sessionKey;
43
- const baseSessionKey = ctx.baseSessionKey?.trim();
44
- if (baseSessionKey) return baseSessionKey;
45
- return ctx.messageChannelId;
46
- }
47
- function buildDiscordInboundJob(ctx, options) {
48
- const { runtime, abortSignal, guildHistories, client, threadBindings, discordRestFetch, message, data, threadChannel, ...payload } = ctx;
49
- const sanitizedMessage = sanitizeDiscordInboundMessage(message);
50
- return {
51
- queueKey: resolveDiscordInboundJobQueueKey(ctx),
52
- payload: {
53
- ...payload,
54
- message: sanitizedMessage,
55
- data: {
56
- ...data,
57
- message: sanitizedMessage
58
- },
59
- threadChannel: normalizeDiscordThreadChannel(threadChannel)
60
- },
61
- runtime: {
62
- runtime,
63
- abortSignal,
64
- guildHistories,
65
- client,
66
- threadBindings,
67
- discordRestFetch
68
- },
69
- replayClaims: options?.replayClaims
70
- };
71
- }
72
- function materializeDiscordInboundJob(job, abortSignal) {
73
- return {
74
- ...job.payload,
75
- ...job.runtime,
76
- abortSignal: abortSignal ?? job.runtime.abortSignal
77
- };
78
- }
79
- function sanitizeDiscordInboundMessage(message) {
80
- const descriptors = Object.getOwnPropertyDescriptors(message);
81
- delete descriptors.channel;
82
- return Object.create(Object.getPrototypeOf(message), descriptors);
83
- }
84
- function normalizeDiscordThreadChannel(threadChannel) {
85
- if (!threadChannel) return null;
86
- const channelInfo = resolveDiscordChannelInfoSafe(threadChannel);
87
- const parent = resolveDiscordChannelParentSafe(threadChannel);
88
- return {
89
- id: threadChannel.id,
90
- name: channelInfo.name,
91
- parentId: channelInfo.parentId,
92
- parent: parent ? {
93
- id: resolveDiscordChannelIdSafe(parent),
94
- name: resolveDiscordChannelNameSafe(parent)
95
- } : void 0,
96
- ownerId: channelInfo.ownerId
97
- };
98
- }
99
- //#endregion
100
- //#region extensions/discord/src/monitor/message-handler.batch-gate.ts
101
- function applyImplicitReplyBatchGate(ctx, replyToMode, isBatched) {
102
- const replyThreading = resolveBatchedReplyThreadingPolicy(replyToMode, isBatched);
103
- if (!replyThreading) return;
104
- ctx.ReplyThreading = replyThreading;
105
- }
106
- //#endregion
107
- //#region extensions/discord/src/monitor/message-run-queue.ts
108
- const loadMessageProcessRuntime = createLazyRuntimeModule(() => import("./message-handler.process-ClgKz8I5.js"));
109
- async function processDiscordQueuedMessage(params) {
110
- const processDiscordMessageImpl = params.testing?.processDiscordMessage ?? (await loadMessageProcessRuntime()).processDiscordMessage;
111
- const abortSignal = params.job.runtime.abortSignal && params.lifecycleSignal ? AbortSignal.any([params.job.runtime.abortSignal, params.lifecycleSignal]) : params.job.runtime.abortSignal ?? params.lifecycleSignal;
112
- try {
113
- await processDiscordMessageImpl(materializeDiscordInboundJob(params.job, abortSignal));
114
- await Promise.all(params.job.replayClaims?.map((claim) => claim.commit()) ?? []);
115
- } catch (error) {
116
- if (error instanceof DiscordRetryableInboundError) for (const claim of params.job.replayClaims ?? []) claim.release({ error });
117
- else await Promise.all(params.job.replayClaims?.map((claim) => claim.commit()) ?? []);
118
- throw error;
119
- }
120
- }
121
- function cleanupSkippedDiscordQueuedMessage(params) {
122
- for (const claim of params.job.replayClaims ?? []) claim.release({ error: new DiscordRetryableInboundError("discord queued run skipped before processing") });
123
- }
124
- function createDiscordMessageRunQueue(params) {
125
- const skippedCleanup = /* @__PURE__ */ new Set();
126
- const runQueue = createChannelRunQueue({
127
- setStatus: params.setStatus,
128
- abortSignal: params.abortSignal,
129
- onError: (error) => {
130
- params.runtime.error(danger(`discord message run failed: ${String(error)}`));
131
- }
132
- });
133
- let lifecycleActive = !params.abortSignal?.aborted;
134
- const cleanupSkippedQueuedMessages = () => {
135
- params.abortSignal?.removeEventListener("abort", cleanupSkippedQueuedMessages);
136
- if (!lifecycleActive && skippedCleanup.size === 0) return;
137
- lifecycleActive = false;
138
- const cleanups = [...skippedCleanup];
139
- skippedCleanup.clear();
140
- for (const cleanup of cleanups) cleanup();
141
- };
142
- if (params.abortSignal?.aborted) cleanupSkippedQueuedMessages();
143
- else params.abortSignal?.addEventListener("abort", cleanupSkippedQueuedMessages, { once: true });
144
- return {
145
- enqueue(job) {
146
- const cleanupSkipped = () => {
147
- cleanupSkippedDiscordQueuedMessage({ job });
148
- };
149
- if (!lifecycleActive) {
150
- cleanupSkipped();
151
- return;
152
- }
153
- skippedCleanup.add(cleanupSkipped);
154
- runQueue.enqueue(job.queueKey, async ({ lifecycleSignal }) => {
155
- skippedCleanup.delete(cleanupSkipped);
156
- await processDiscordQueuedMessage({
157
- job,
158
- lifecycleSignal,
159
- testing: params.testing
160
- });
161
- });
162
- },
163
- deactivate() {
164
- runQueue.deactivate();
165
- cleanupSkippedQueuedMessages();
166
- }
167
- };
168
- }
169
- //#endregion
170
- //#region extensions/discord/src/monitor/message-handler.ts
171
- const loadMessagePreflightRuntime = createLazyRuntimeModule(() => import("./message-handler.preflight-DnAH04Ss.js"));
172
- function isNonEmptyString(value) {
173
- return typeof value === "string" && value.length > 0;
174
- }
175
- function createDiscordMessageHandler(params) {
176
- const { groupPolicy } = resolveOpenProviderRuntimeGroupPolicy({
177
- providerConfigPresent: params.cfg.channels?.discord !== void 0,
178
- groupPolicy: params.discordConfig?.groupPolicy,
179
- defaultGroupPolicy: params.cfg.channels?.defaults?.groupPolicy
180
- });
181
- const ackReactionScope = params.discordConfig?.ackReactionScope ?? params.cfg.messages?.ackReactionScope ?? "group-mentions";
182
- const preflightDiscordMessageImpl = params.testing?.preflightDiscordMessage;
183
- const replayGuard = createDiscordInboundReplayGuard();
184
- const messageRunQueue = createDiscordMessageRunQueue({
185
- runtime: params.runtime,
186
- setStatus: params.setStatus,
187
- abortSignal: params.abortSignal,
188
- testing: params.testing
189
- });
190
- const { debouncer } = createChannelInboundDebouncer({
191
- cfg: params.cfg,
192
- channel: "discord",
193
- buildKey: (entry) => {
194
- const message = entry.data.message;
195
- const authorId = entry.data.author?.id;
196
- if (!message || !authorId) return null;
197
- const channelId = resolveDiscordMessageChannelId({
198
- message,
199
- eventChannelId: entry.data.channel_id
200
- });
201
- if (!channelId) return null;
202
- return `discord:${params.accountId}:${channelId}:${authorId}`;
203
- },
204
- shouldDebounce: (entry) => {
205
- const message = entry.data.message;
206
- if (!message) return false;
207
- return shouldDebounceTextInbound({
208
- text: resolveDiscordMessageText(message, { includeForwarded: false }),
209
- cfg: params.cfg,
210
- hasMedia: message.attachments && message.attachments.length > 0 || hasDiscordMessageStickers(message)
211
- });
212
- },
213
- onFlush: async (entries) => {
214
- const last = entries.at(-1);
215
- if (!last) return;
216
- const replayClaims = entries.map((entry) => entry.replayClaim).filter((claim) => claim !== void 0);
217
- const abortSignal = last.abortSignal;
218
- if (abortSignal?.aborted) {
219
- for (const claim of replayClaims) claim.release({ error: abortSignal.reason });
220
- return;
221
- }
222
- try {
223
- if (entries.length === 1) {
224
- const ctx = await (preflightDiscordMessageImpl ?? (await loadMessagePreflightRuntime()).preflightDiscordMessage)({
225
- ...params,
226
- ackReactionScope,
227
- groupPolicy,
228
- abortSignal,
229
- data: last.data,
230
- client: last.client
231
- });
232
- if (!ctx) {
233
- await Promise.all(replayClaims.map((claim) => claim.commit()));
234
- return;
235
- }
236
- applyImplicitReplyBatchGate(ctx, params.replyToMode, false);
237
- messageRunQueue.enqueue(buildDiscordInboundJob(ctx, { replayClaims }));
238
- return;
239
- }
240
- const combinedBaseText = entries.map((entry) => resolveDiscordMessageText(entry.data.message, { includeForwarded: false })).filter(Boolean).join("\n");
241
- const syntheticMessage = Object.create(Object.getPrototypeOf(last.data.message), {
242
- ...Object.getOwnPropertyDescriptors(last.data.message),
243
- content: {
244
- value: combinedBaseText,
245
- enumerable: true,
246
- configurable: true
247
- },
248
- attachments: {
249
- value: [],
250
- enumerable: true,
251
- configurable: true
252
- },
253
- message_snapshots: {
254
- value: last.data.message.message_snapshots,
255
- enumerable: true,
256
- configurable: true
257
- },
258
- messageSnapshots: {
259
- value: last.data.message.messageSnapshots,
260
- enumerable: true,
261
- configurable: true
262
- },
263
- rawData: {
264
- value: { ...last.data.message.rawData },
265
- enumerable: true,
266
- configurable: true
267
- }
268
- });
269
- const syntheticData = {
270
- ...last.data,
271
- message: syntheticMessage
272
- };
273
- const ctx = await (preflightDiscordMessageImpl ?? (await loadMessagePreflightRuntime()).preflightDiscordMessage)({
274
- ...params,
275
- ackReactionScope,
276
- groupPolicy,
277
- abortSignal,
278
- data: syntheticData,
279
- client: last.client
280
- });
281
- if (!ctx) {
282
- await Promise.all(replayClaims.map((claim) => claim.commit()));
283
- return;
284
- }
285
- applyImplicitReplyBatchGate(ctx, params.replyToMode, true);
286
- if (entries.length > 1) {
287
- const ids = entries.map((entry) => entry.data.message?.id).filter(isNonEmptyString);
288
- if (ids.length > 0) {
289
- const ctxBatch = ctx;
290
- ctxBatch.MessageSids = ids;
291
- ctxBatch.MessageSidFirst = ids[0];
292
- ctxBatch.MessageSidLast = ids[ids.length - 1];
293
- }
294
- }
295
- messageRunQueue.enqueue(buildDiscordInboundJob(ctx, { replayClaims }));
296
- } catch (error) {
297
- if (error instanceof DiscordRetryableInboundError) for (const claim of replayClaims) claim.release({ error });
298
- else await Promise.all(replayClaims.map((claim) => claim.commit()));
299
- throw error;
300
- }
301
- },
302
- onError: (err) => {
303
- params.runtime.error(danger(`discord debounce flush failed: ${String(err)}`));
304
- }
305
- });
306
- const handler = async (data, client, options) => {
307
- try {
308
- if (options?.abortSignal?.aborted) return;
309
- const msgAuthorId = data.message?.author?.id ?? data.author?.id;
310
- if (params.botUserId && msgAuthorId === params.botUserId) return;
311
- const replayKey = buildDiscordInboundReplayKey({
312
- accountId: params.accountId,
313
- data
314
- });
315
- const replayClaim = await replayGuard.claim(replayKey);
316
- if (replayClaim.kind !== "claimed" && replayClaim.kind !== "invalid") return;
317
- await debouncer.enqueue({
318
- data,
319
- client,
320
- abortSignal: options?.abortSignal,
321
- ...replayClaim.kind === "claimed" ? { replayClaim: replayClaim.handle } : {}
322
- });
323
- } catch (err) {
324
- params.runtime.error(danger(`handler failed: ${String(err)}`));
325
- }
326
- };
327
- handler.deactivate = messageRunQueue.deactivate;
328
- return handler;
329
- }
330
- //#endregion
331
- export { DiscordRetryableInboundError as n, createDiscordMessageHandler as t };
@@ -1,2 +0,0 @@
1
- import { t as monitorDiscordProvider } from "./provider-PRlF_lZm.js";
2
- export { monitorDiscordProvider };
@@ -1,6 +0,0 @@
1
- import "./allow-list-B7qOH5xu.js";
2
- import "./timeouts-D5lWili0.js";
3
- import "./provider-PRlF_lZm.js";
4
- import "./message-utils-BU3gc01v.js";
5
- import "./message-handler-DExaghWK.js";
6
- export {};
@@ -1,3 +0,0 @@
1
- import "./chunk-CHpY_lsO.js";
2
- import "./target-resolver-BaEmTxeK.js";
3
- export {};
@@ -1,8 +1,8 @@
1
1
  import { t as isDiscordMutableAllowEntry } from "./security-doctor-nGgPm65L.js";
2
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
- import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
4
3
  import { coerceNativeSetting, normalizeAllowFromList } from "openclaw/plugin-sdk/channel-policy";
5
4
  import { readChannelAllowFromStore } from "openclaw/plugin-sdk/conversation-runtime";
5
+ import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
6
6
  import { resolveNativeCommandsEnabled, resolveNativeSkillsEnabled } from "openclaw/plugin-sdk/native-command-config-runtime";
7
7
  //#region extensions/discord/src/security-audit.ts
8
8
  function addDiscordNameBasedEntries(params) {