@openclaw/discord 2026.7.2-beta.7 → 2026.8.1-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 (114) hide show
  1. package/dist/{account-inspect-SXiCBCgP.js → account-inspect-D5xmUpnj.js} +49 -43
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/accounts-DNl-oCEw.js +371 -0
  4. package/dist/action-runtime-api.js +1 -1
  5. package/dist/{active-turn-thread-route-MlKWp8RD.js → active-turn-thread-route-fmHl1HNd.js} +9 -11
  6. package/dist/{activities-api-DTKsuDxf.js → activities-api-KCBAmWxD.js} +133 -175
  7. package/dist/activities-api.js +1 -1
  8. package/dist/{allow-list-DzKrtfah.js → allow-list-BDMimASD.js} +2 -3
  9. package/dist/{api-DnrK9gML.js → api-DNVbJyEy.js} +7 -2
  10. package/dist/api.js +18 -18
  11. package/dist/{approval-handler.runtime-HymvFTYn.js → approval-handler.runtime-B12RCYr8.js} +6 -6
  12. package/dist/{approval-message-safety-DEyKVsAw.js → approval-message-safety-XGFPbDoI.js} +89 -3
  13. package/dist/{audit-CjsrabP8.js → audit-Yc7eZDd6.js} +5 -5
  14. package/dist/{channel-actions-uXFTJX3o.js → channel-actions-Dr2QI8Bf.js} +11 -7
  15. package/dist/{channel-actions.runtime-CIYU90sl.js → channel-actions.runtime-CODTvo7c.js} +99 -97
  16. package/dist/{channel-vKa-76xY.js → channel-cXYzGc4L.js} +102 -104
  17. package/dist/channel-config-api.js +1 -1
  18. package/dist/channel-plugin-api.js +1 -1
  19. package/dist/{channel.setup-CmcwZ_qd.js → channel.setup-CSiwnMgs.js} +16 -54
  20. package/dist/{outbound-session-route-H-HoyH5U.js → components-ezGKo_Yh.js} +69 -142
  21. package/dist/{config-schema-WHRQcY19.js → config-schema-DC5kDtQ5.js} +42 -11
  22. package/dist/conversation-binding-route-D6rCQ5S0.js +43 -0
  23. package/dist/{directory-config-D_LojtCe.js → directory-config-XyCfoqLg.js} +2 -2
  24. package/dist/directory-contract-api.js +1 -1
  25. package/dist/{directory-live-Bw5Ephzv.js → directory-live-Df0NbFJB.js} +7 -4
  26. package/dist/{doctor-Bc4S1qyd.js → doctor-DYY31GrO.js} +34 -13
  27. package/dist/{doctor-contract-CCFMIDk9.js → doctor-contract-DsWvKIXF.js} +2 -3
  28. package/dist/doctor-contract-api.js +147 -2
  29. package/dist/{handle-action.guild-admin-D6VRRW-C.js → handle-action.guild-admin-6Tvvinsa.js} +4 -7
  30. package/dist/{inbound-event-delivery-CEPlt2uz.js → inbound-event-delivery-De2qxTrP.js} +4 -25
  31. package/dist/index.js +5 -4
  32. package/dist/{message-handler-CeiSulIw.js → message-handler-B61q5MOF.js} +118 -33
  33. package/dist/{message-handler.preflight-DibgQFf2.js → message-handler.preflight-Bzg_Hawz.js} +75 -61
  34. package/dist/{message-handler.process-Dnc_oz9y.js → message-handler.process--4_712Ec.js} +236 -296
  35. package/dist/{message-utils-BgTwT_q7.js → message-utils-BXLLnFl6.js} +34 -35
  36. package/dist/{model-picker-preference-primitives-D25pnCOu.js → model-picker-preference-primitives-BHT1LkR_.js} +3 -3
  37. package/dist/{outbound-adapter-DtE-i2OJ.js → outbound-adapter-DxHTOqiN.js} +157 -68
  38. package/dist/{outbound-components-C7GVyfPh.js → outbound-components-B2PL0ooH.js} +3 -3
  39. package/dist/owner-access-Bg41VzAf.js +107 -0
  40. package/dist/{pluralkit-CD4B11JB.js → pluralkit-dUl4v1X3.js} +1 -1
  41. package/dist/{preflight-audio-BjnQZ5yS.js → preflight-audio-DrnqFA8U.js} +22 -28
  42. package/dist/{probe-BeWKhjqX.js → probe-BTdtVRwU.js} +37 -13
  43. package/dist/probe.runtime-Dq5-PRKT.js +2 -0
  44. package/dist/{provider-DfQJX3z5.js → provider-DlK_ynqt.js} +1131 -2021
  45. package/dist/{provider-session.runtime-Bo88k0pV.js → provider-session.runtime-CvvphHvs.js} +3 -3
  46. package/dist/provider.runtime-CzKGRiAF.js +2 -0
  47. package/dist/realtime-session.runtime-ysbMG8v7.js +1351 -0
  48. package/dist/{resolve-allowlist-common-DHERApxi.js → resolve-allowlist-common-DIVXbD1P.js} +3 -3
  49. package/dist/{resolve-channels-BjepAj8b.js → resolve-channels-CGeUoIqb.js} +4 -4
  50. package/dist/{resolve-users-Bc28htgt.js → resolve-users-BtKxLUZv.js} +3 -3
  51. package/dist/{chunk-DX4jpFQP.js → retry-DNsVTeTo.js} +308 -131
  52. package/dist/{runtime-BmW_j_hl.js → runtime-CQovMsH3.js} +12 -15
  53. package/dist/{runtime-_aRC6V2s.js → runtime-D71_VFLr.js} +49 -58
  54. package/dist/runtime-api.actions.js +2 -2
  55. package/dist/runtime-api.js +23 -23
  56. package/dist/runtime-api.lookup.js +5 -5
  57. package/dist/runtime-api.monitor-CzeTYF32.js +6 -0
  58. package/dist/runtime-api.monitor.js +6 -5
  59. package/dist/runtime-api.send.js +6 -6
  60. package/dist/runtime-api.threads.js +5 -6
  61. package/dist/sdk-runtime-37OU6_Yh.js +369 -0
  62. package/dist/{secret-config-contract-B1akrlyY.js → secret-config-contract-B3i6WxV5.js} +53 -25
  63. package/dist/secret-contract-api.js +1 -1
  64. package/dist/security-audit-contract-api.js +1 -1
  65. package/dist/{security-audit.runtime-CPN0xFYz.js → security-audit.runtime-BVKF9VtY.js} +1 -1
  66. package/dist/{send-CdkZ6zeW.js → send-rQIffSYu.js} +180 -91
  67. package/dist/{send.components-5uqwkjgE.js → send.components-ChK1wS7w.js} +32 -46
  68. package/dist/{send.outbound-D-80Ej-t.js → send.outbound-HIkgji_7.js} +57 -34
  69. package/dist/{send.reactions-CtlmGd_o.js → send.reactions-gmJ6yFPo.js} +14 -21
  70. package/dist/{send.receipt-CuwRrpFz.js → send.receipt-Cnhoautb.js} +29 -1
  71. package/dist/{send.shared-jpvAG_u6.js → send.shared-B3fpaLWJ.js} +112 -181
  72. package/dist/{sender-identity-mG_zsdox.js → sender-identity-BJtfyise.js} +1 -1
  73. package/dist/setup-entry.js +0 -5
  74. package/dist/setup-plugin-api.js +1 -1
  75. package/dist/{shared-CXF1tup1.js → shared-CaAaoksy.js} +27 -23
  76. package/dist/subagent-hooks-CNT2ZJTJ.js +49 -0
  77. package/dist/subagent-hooks-api.js +2 -6
  78. package/dist/subagent-progress-FPLqBY1s.js +110 -0
  79. package/dist/{system-events-DdUqf91B.js → system-events-Nuwoq_au.js} +2 -2
  80. package/dist/{target-resolver-C3s_2m0t.js → target-resolver-DIXShHaZ.js} +3 -3
  81. package/dist/targets-B2pf49zc.js +3 -0
  82. package/dist/{thread-bindings-C-M-ly7P.js → thread-bindings-VlymUnbz.js} +29 -28
  83. package/dist/{thread-bindings.manager-DYvSlrva.js → thread-bindings.manager-CngsgErq.js} +258 -29
  84. package/dist/{thread-bindings.session-updates-DAIlp7Px.js → thread-bindings.session-updates-CJb-BpPL.js} +1 -1
  85. package/dist/{thread-bindings.state-Cgi5uRn-.js → thread-bindings.state-D8OMdk4O.js} +3 -16
  86. package/dist/threading-DU6pgeGm.js +456 -0
  87. package/dist/transcripts-source-DeIMNbRh.js +265 -0
  88. package/dist/transcripts-source-api.js +7 -2
  89. package/dist/{typing--Mzo2kM7.js → typing-oLiS5Z13.js} +1 -1
  90. package/dist/voice-runtime-CjNFaynA.js +2549 -0
  91. package/openclaw.plugin.json +215 -25
  92. package/package.json +15 -11
  93. package/skills/discord/SKILL.md +22 -115
  94. package/dist/accounts-DJTf1LtA.js +0 -219
  95. package/dist/channel-api-CAJ0wMoV.js +0 -21
  96. package/dist/legacy-state-migrations-api.js +0 -138
  97. package/dist/manager.runtime-Bjav3pfC.js +0 -3655
  98. package/dist/preflight-audio.runtime-CoCXMM8r.js +0 -7
  99. package/dist/probe.runtime-DqFGFMbZ.js +0 -2
  100. package/dist/provider.runtime-Cy7XZmyh.js +0 -2
  101. package/dist/runtime-api.monitor-CCRubd3-.js +0 -5
  102. package/dist/session-binding-contract-api.js +0 -2
  103. package/dist/subagent-hooks-Dxy7Fmnq.js +0 -120
  104. package/dist/subagent-progress-DI3sYLLo.js +0 -664
  105. package/dist/targets-Dv_RN7vT.js +0 -3
  106. package/dist/thread-bindings.discord-api-BoDNqamb.js +0 -246
  107. package/dist/transcripts-source-DIKGsTGT.js +0 -123
  108. package/node_modules/p-map/index.d.ts +0 -155
  109. package/node_modules/p-map/index.js +0 -285
  110. package/node_modules/p-map/license +0 -9
  111. package/node_modules/p-map/package.json +0 -57
  112. package/node_modules/p-map/readme.md +0 -190
  113. package/dist/{audit-core-xwjIczO0.js → audit-core-BCX8UeFH.js} +1 -1
  114. package/dist/{security-audit-jGnJF__m.js → security-audit-BfJhAXZp.js} +1 -1
@@ -1,58 +1,18 @@
1
- import { D as RateLimitError, It as getGuild, L as serializePayload, Lt as getGuildMember, R as Embed, T as RequestClient, ct as createUserDmChannel, lt as getCurrentUser, pt as createChannelMessage, r as resolveDiscordReplyMessageId, t as chunkDiscordTextWithMode, xt as getThreadMember, yt as getChannel } from "./chunk-DX4jpFQP.js";
2
- import { a as mergeDiscordAccountConfig, p as normalizeDiscordToken, s as resolveDiscordAccount } from "./accounts-DJTf1LtA.js";
3
- import { t as parseAndResolveDiscordTarget } from "./target-resolver-C3s_2m0t.js";
4
- import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
5
- import { normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { B as hasDiscordV2Components, Et as getThreadMember, H as Embed, Ht as getGuildMember, O as RequestClient, V as serializePayload, Vt as getGuild, a as chunkDiscordTextWithMode, mt as getCurrentUser, n as createDiscordRetryRunner, pt as createUserDmChannel, s as resolveDiscordReplyMessageId, vt as createChannelMessage, wt as getChannel } from "./retry-DNsVTeTo.js";
2
+ import { c as resolveDiscordAccount, m as normalizeDiscordToken, o as mergeDiscordAccountConfig } from "./accounts-DNl-oCEw.js";
3
+ import { t as parseAndResolveDiscordTarget } from "./target-resolver-DIXShHaZ.js";
6
4
  import { ChannelType, MessageFlags, PermissionFlagsBits } from "discord-api-types/v10";
7
5
  import { randomBytes } from "node:crypto";
8
- import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
9
6
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
10
- import { collectErrorGraphCandidates, extractErrorCode, formatErrorMessage, readErrorName } from "openclaw/plugin-sdk/error-runtime";
11
- import { classifyTransientNetworkErrorCode, createChannelApiRetryRunner, resolveRetryConfig } from "openclaw/plugin-sdk/retry-runtime";
7
+ import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
8
+ import { normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
9
+ import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
12
10
  import { makeProxyFetch } from "openclaw/plugin-sdk/fetch-runtime";
13
11
  import { danger } from "openclaw/plugin-sdk/runtime-env";
14
- import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
15
12
  import { PollLayoutType } from "discord-api-types/payloads/v10";
16
13
  import { buildOutboundMediaLoadOptions, extensionForMime, normalizePollDurationHours, normalizePollInput } from "openclaw/plugin-sdk/media-runtime";
17
14
  import { resolveTextChunksWithFallback } from "openclaw/plugin-sdk/reply-payload";
18
15
  import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
19
- //#region extensions/discord/src/proxy-fetch.ts
20
- function resolveDiscordProxyUrl(account, cfg) {
21
- const accountProxy = account.config.proxy?.trim();
22
- if (accountProxy) return accountProxy;
23
- const channelProxy = cfg?.channels?.discord?.proxy;
24
- if (typeof channelProxy !== "string") return;
25
- return channelProxy.trim() || void 0;
26
- }
27
- function resolveDiscordProxyFetchByUrl(proxyUrl, runtime) {
28
- return withValidatedDiscordProxy(proxyUrl, runtime, (proxy) => makeProxyFetch(proxy));
29
- }
30
- function resolveDiscordProxyFetchForAccount(account, cfg, runtime) {
31
- return resolveDiscordProxyFetchByUrl(resolveDiscordProxyUrl(account, cfg), runtime);
32
- }
33
- function withValidatedDiscordProxy(proxyUrl, runtime, createValue) {
34
- const proxy = proxyUrl?.trim();
35
- if (!proxy) return;
36
- try {
37
- validateDiscordProxyUrl(proxy);
38
- return createValue(proxy);
39
- } catch (err) {
40
- runtime?.error?.(danger(`discord: invalid rest proxy: ${String(err)}`));
41
- return;
42
- }
43
- }
44
- function validateDiscordProxyUrl(proxyUrl) {
45
- let parsed;
46
- try {
47
- parsed = new URL(proxyUrl);
48
- } catch {
49
- throw new Error("Proxy URL must be a valid http or https URL");
50
- }
51
- if (!["http:", "https:"].includes(parsed.protocol)) throw new Error("Proxy URL must use http or https");
52
- if (!parsed.hostname) throw new Error("Proxy URL must include a host");
53
- return proxyUrl;
54
- }
55
- //#endregion
56
16
  //#region extensions/discord/src/recipient-resolution.ts
57
17
  async function parseAndResolveRecipient(raw, cfg, accountId, parseOptions = {}) {
58
18
  if (!cfg) throw new Error("Discord recipient resolution requires a resolved runtime config. Load and resolve config at the command or gateway boundary, then pass cfg through the runtime path.");
@@ -102,6 +62,41 @@ function clearGateways() {
102
62
  gatewayRegistry.clear();
103
63
  }
104
64
  //#endregion
65
+ //#region extensions/discord/src/proxy-fetch.ts
66
+ function resolveDiscordProxyUrl(account, cfg) {
67
+ const accountProxy = normalizeOptionalString(account.config.proxy);
68
+ if (accountProxy) return accountProxy;
69
+ return normalizeOptionalString(cfg?.channels?.discord?.proxy);
70
+ }
71
+ function resolveDiscordProxyFetchByUrl(proxyUrl, runtime) {
72
+ return withValidatedDiscordProxy(proxyUrl, runtime, (proxy) => makeProxyFetch(proxy));
73
+ }
74
+ function resolveDiscordProxyFetchForAccount(account, cfg, runtime) {
75
+ return resolveDiscordProxyFetchByUrl(resolveDiscordProxyUrl(account, cfg), runtime);
76
+ }
77
+ function withValidatedDiscordProxy(proxyUrl, runtime, createValue) {
78
+ const proxy = proxyUrl?.trim();
79
+ if (!proxy) return;
80
+ try {
81
+ validateDiscordProxyUrl(proxy);
82
+ return createValue(proxy);
83
+ } catch (err) {
84
+ runtime?.error?.(danger(`discord: invalid rest proxy: ${String(err)}`));
85
+ return;
86
+ }
87
+ }
88
+ function validateDiscordProxyUrl(proxyUrl) {
89
+ let parsed;
90
+ try {
91
+ parsed = new URL(proxyUrl);
92
+ } catch {
93
+ throw new Error("Proxy URL must be a valid http or https URL");
94
+ }
95
+ if (!["http:", "https:"].includes(parsed.protocol)) throw new Error("Proxy URL must use http or https");
96
+ if (!parsed.hostname) throw new Error("Proxy URL must include a host");
97
+ return proxyUrl;
98
+ }
99
+ //#endregion
105
100
  //#region extensions/discord/src/proxy-request-client.ts
106
101
  const DISCORD_REST_TIMEOUT_MS = 15e3;
107
102
  function createDiscordRequestClient(token, options) {
@@ -115,74 +110,6 @@ function createDiscordRequestClient(token, options) {
115
110
  });
116
111
  }
117
112
  //#endregion
118
- //#region extensions/discord/src/retry.ts
119
- const DISCORD_RETRY_DEFAULTS = {
120
- attempts: 3,
121
- minDelayMs: 500,
122
- maxDelayMs: 3e4,
123
- jitter: .1
124
- };
125
- const DISCORD_GATEWAY_RECONNECT_EXTRA_ATTEMPTS = 2;
126
- const DISCORD_RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([408, 429]);
127
- const DISCORD_TRANSIENT_MESSAGE_RE = /\b(?:bad gateway|fetch failed|network error|networkerror|service unavailable|socket hang up|temporarily unavailable|timed out|timeout)\b|connection (?:closed|reset|refused)/i;
128
- function readDiscordErrorStatus(err) {
129
- if (!err || typeof err !== "object") return;
130
- return parseStrictNonNegativeInteger("status" in err && err.status !== void 0 ? err.status : "statusCode" in err && err.statusCode !== void 0 ? err.statusCode : void 0);
131
- }
132
- function isRetryableDiscordTransientError(err) {
133
- if (err instanceof RateLimitError) return true;
134
- for (const candidate of collectErrorGraphCandidates(err, (current) => [current.cause, current.error])) {
135
- const status = readDiscordErrorStatus(candidate);
136
- if (status !== void 0 && (DISCORD_RETRYABLE_STATUS_CODES.has(status) || status >= 500)) return true;
137
- if (classifyTransientNetworkErrorCode(extractErrorCode(candidate))) return true;
138
- if (readErrorName(candidate) === "AbortError") return true;
139
- if ((candidate instanceof Error || candidate !== null && typeof candidate === "object") && DISCORD_TRANSIENT_MESSAGE_RE.test(formatErrorMessage(candidate))) return true;
140
- }
141
- return false;
142
- }
143
- function isRetryableDiscordPreConnectError(err) {
144
- if (err instanceof RateLimitError) return true;
145
- for (const candidate of collectErrorGraphCandidates(err, (current) => [current.cause, current.error])) {
146
- if (readDiscordErrorStatus(candidate) === 429) return true;
147
- if (classifyTransientNetworkErrorCode(extractErrorCode(candidate)) === "pre-connect") return true;
148
- }
149
- return false;
150
- }
151
- function resolveDiscordRetryPredicate(safety) {
152
- return safety === "non-idempotent-create" ? isRetryableDiscordPreConnectError : isRetryableDiscordTransientError;
153
- }
154
- function isRetryableDiscordGatewayTransportError(err) {
155
- if (!isRetryableDiscordTransientError(err) || err instanceof RateLimitError) return false;
156
- return !collectErrorGraphCandidates(err, (current) => [current.cause, current.error]).some((candidate) => readDiscordErrorStatus(candidate) !== void 0);
157
- }
158
- function createDiscordRetryRunner(params) {
159
- const retryConfig = resolveRetryConfig(DISCORD_RETRY_DEFAULTS, params.retry);
160
- const attempts = retryConfig.attempts > 1 ? retryConfig.attempts + DISCORD_GATEWAY_RECONNECT_EXTRA_ATTEMPTS : retryConfig.attempts;
161
- return (fn, label, options) => {
162
- const isRetryable = resolveDiscordRetryPredicate(options?.safety ?? "idempotent");
163
- let observedGatewayDisconnect = false;
164
- const runRequest = async () => {
165
- observedGatewayDisconnect ||= params.isGatewayDisconnected?.() === true;
166
- try {
167
- return await fn();
168
- } catch (err) {
169
- observedGatewayDisconnect ||= params.isGatewayDisconnected?.() === true;
170
- throw err;
171
- }
172
- };
173
- return createChannelApiRetryRunner({
174
- retry: {
175
- ...retryConfig,
176
- attempts
177
- },
178
- shouldRetry: (err, attempt) => isRetryable(err) && (attempt < retryConfig.attempts || observedGatewayDisconnect && isRetryableDiscordGatewayTransportError(err)),
179
- strictShouldRetry: true,
180
- retryAfterMs: (err) => err instanceof RateLimitError ? err.retryAfter * 1e3 : void 0,
181
- verbose: params.verbose
182
- })(runRequest, label);
183
- };
184
- }
185
- //#endregion
186
113
  //#region extensions/discord/src/client.ts
187
114
  function createDiscordRuntimeAccountContext(params) {
188
115
  return {
@@ -272,6 +199,59 @@ function resolveDiscordRest(opts) {
272
199
  return createDiscordRestClient(opts).rest;
273
200
  }
274
201
  //#endregion
202
+ //#region extensions/discord/src/send.message-request.ts
203
+ const SUPPRESS_EMBEDS_FLAG = MessageFlags.SuppressEmbeds;
204
+ const SUPPRESS_NOTIFICATIONS_FLAG = MessageFlags.SuppressNotifications;
205
+ function createDiscordMessageNonce() {
206
+ return randomBytes(12).toString("hex");
207
+ }
208
+ function resolveDiscordSendComponents(params) {
209
+ if (!params.components || !params.isFirst) return;
210
+ return typeof params.components === "function" ? params.components(params.text) : params.components;
211
+ }
212
+ function normalizeDiscordEmbeds(embeds) {
213
+ if (!embeds?.length) return;
214
+ return embeds.map((embed) => embed instanceof Embed ? embed : new Embed(embed));
215
+ }
216
+ function resolveDiscordSendEmbeds(params) {
217
+ if (!params.embeds || !params.isFirst) return;
218
+ return normalizeDiscordEmbeds(params.embeds);
219
+ }
220
+ function buildDiscordMessagePayload(params) {
221
+ const payload = {};
222
+ const hasV2 = hasDiscordV2Components(params.components);
223
+ const trimmed = params.text.trim();
224
+ if (!hasV2 && trimmed) payload.content = params.text;
225
+ if (params.components?.length) payload.components = params.components;
226
+ if (!hasV2 && params.embeds?.length) payload.embeds = params.embeds;
227
+ if (params.allowedMentions) payload.allowed_mentions = params.allowedMentions;
228
+ if (params.flags !== void 0) payload.flags = params.flags;
229
+ if (params.files?.length) payload.files = params.files;
230
+ return payload;
231
+ }
232
+ function resolveDiscordMessageFlags(params) {
233
+ let flags = 0;
234
+ if (params.suppressEmbeds) flags |= SUPPRESS_EMBEDS_FLAG;
235
+ if (params.silent) flags |= SUPPRESS_NOTIFICATIONS_FLAG;
236
+ return flags || void 0;
237
+ }
238
+ function resolveDiscordSuppressEmbeds(params) {
239
+ return params.override ?? params.configured ?? true;
240
+ }
241
+ function buildDiscordMessageRequest(params) {
242
+ const payload = buildDiscordMessagePayload(params);
243
+ const nonce = params.endpoint === "create-message" ? params.nonce ?? createDiscordMessageNonce() : void 0;
244
+ return {
245
+ ...serializePayload(payload),
246
+ ...params.replyTo ? { message_reference: {
247
+ message_id: params.replyTo,
248
+ fail_if_not_exists: false
249
+ } } : {},
250
+ ...nonce !== void 0 ? { nonce } : {},
251
+ ...nonce ? { enforce_nonce: true } : {}
252
+ };
253
+ }
254
+ //#endregion
275
255
  //#region extensions/discord/src/send.permissions.ts
276
256
  const PERMISSION_ENTRIES = Object.entries(PermissionFlagsBits).filter(([, value]) => typeof value === "bigint");
277
257
  const ALL_PERMISSIONS = PERMISSION_ENTRIES.reduce((acc, [, value]) => acc | value, 0n);
@@ -526,62 +506,6 @@ const DISCORD_MAX_EMOJI_BYTES = 256 * 1024;
526
506
  const DISCORD_MAX_STICKER_BYTES = 512 * 1024;
527
507
  const DISCORD_MAX_EVENT_COVER_BYTES = 8 * 1024 * 1024;
528
508
  //#endregion
529
- //#region extensions/discord/src/send.message-request.ts
530
- const SUPPRESS_EMBEDS_FLAG = MessageFlags.SuppressEmbeds;
531
- const SUPPRESS_NOTIFICATIONS_FLAG = MessageFlags.SuppressNotifications;
532
- function createDiscordMessageNonce() {
533
- return randomBytes(12).toString("hex");
534
- }
535
- function resolveDiscordSendComponents(params) {
536
- if (!params.components || !params.isFirst) return;
537
- return typeof params.components === "function" ? params.components(params.text) : params.components;
538
- }
539
- function normalizeDiscordEmbeds(embeds) {
540
- if (!embeds?.length) return;
541
- return embeds.map((embed) => embed instanceof Embed ? embed : new Embed(embed));
542
- }
543
- function resolveDiscordSendEmbeds(params) {
544
- if (!params.embeds || !params.isFirst) return;
545
- return normalizeDiscordEmbeds(params.embeds);
546
- }
547
- function buildDiscordMessagePayload(params) {
548
- const payload = {};
549
- const hasV2 = hasV2Components(params.components);
550
- const trimmed = params.text.trim();
551
- if (!hasV2 && trimmed) payload.content = params.text;
552
- if (params.components?.length) payload.components = params.components;
553
- if (!hasV2 && params.embeds?.length) payload.embeds = params.embeds;
554
- if (params.allowedMentions) payload.allowed_mentions = params.allowedMentions;
555
- if (params.flags !== void 0) payload.flags = params.flags;
556
- if (params.files?.length) payload.files = params.files;
557
- return payload;
558
- }
559
- function resolveDiscordMessageFlags(params) {
560
- let flags = 0;
561
- if (params.suppressEmbeds) flags |= SUPPRESS_EMBEDS_FLAG;
562
- if (params.silent) flags |= SUPPRESS_NOTIFICATIONS_FLAG;
563
- return flags || void 0;
564
- }
565
- function buildDiscordMessageRequest(params) {
566
- const payload = buildDiscordMessagePayload(params);
567
- const nonce = params.endpoint === "create-message" ? params.nonce ?? createDiscordMessageNonce() : void 0;
568
- return stripUndefinedFields({
569
- ...serializePayload(payload),
570
- ...params.replyTo ? { message_reference: {
571
- message_id: params.replyTo,
572
- fail_if_not_exists: false
573
- } } : {},
574
- nonce,
575
- enforce_nonce: nonce ? true : void 0
576
- });
577
- }
578
- function stripUndefinedFields(value) {
579
- return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
580
- }
581
- function hasV2Components(components) {
582
- return Boolean(components?.some((component) => "isV2" in component && component.isV2));
583
- }
584
- //#endregion
585
509
  //#region extensions/discord/src/send.shared.ts
586
510
  const DISCORD_TEXT_LIMIT = 2e3;
587
511
  const DISCORD_MAX_STICKERS = 3;
@@ -710,15 +634,14 @@ function buildDiscordTextChunks(text, opts = {}) {
710
634
  }));
711
635
  }
712
636
  async function sendDiscordText(params) {
713
- const { rest, channelId, text, request, reply, maxLinesPerMessage, components, embeds, allowedMentions, chunkMode, silent, suppressEmbeds, maxChars, onResult } = params;
714
- if (!text.trim()) throw new Error("Message must be non-empty for Discord sends");
637
+ const { rest, channelId, text, request, reply, maxLinesPerMessage, components, embeds, allowedMentions, chunkMode, silent, suppressEmbeds, maxChars, onResult, onPlatformSendDispatch } = params;
715
638
  const chunks = buildDiscordTextChunks(text, {
716
639
  maxLinesPerMessage,
717
640
  chunkMode,
718
641
  maxChars
719
642
  });
643
+ if (!chunks.length) chunks.push("");
720
644
  const sendChunk = async (chunk, isFirst) => {
721
- const chunkReplyTo = resolveDiscordReplyMessageId(reply, isFirst);
722
645
  const chunkComponents = resolveDiscordSendComponents({
723
646
  components,
724
647
  text: chunk,
@@ -728,6 +651,9 @@ async function sendDiscordText(params) {
728
651
  embeds,
729
652
  isFirst
730
653
  });
654
+ if (!chunk.trim() && !chunkComponents?.length && !chunkEmbeds?.length) throw new Error("Message must be non-empty for Discord sends");
655
+ const chunkReplyTo = resolveDiscordReplyMessageId(reply, isFirst);
656
+ const kind = chunkComponents?.length || chunkEmbeds?.length ? "card" : "text";
731
657
  const flags = resolveDiscordMessageFlags({
732
658
  silent,
733
659
  suppressEmbeds: suppressEmbeds && !chunkEmbeds?.length
@@ -741,14 +667,16 @@ async function sendDiscordText(params) {
741
667
  flags,
742
668
  replyTo: chunkReplyTo
743
669
  });
670
+ await onPlatformSendDispatch?.();
744
671
  return {
745
672
  result: await request(() => createChannelMessage(rest, channelId, { body }), "text", { safety: "nonce-protected-create" }),
746
- replyToId: chunkReplyTo
673
+ replyToId: chunkReplyTo,
674
+ kind
747
675
  };
748
676
  };
749
677
  if (chunks.length === 1) {
750
- const { result, replyToId } = await sendChunk(expectDefined(chunks.at(0), "single Discord text chunk"), true);
751
- await onResult?.(result, "text", replyToId);
678
+ const { result, replyToId, kind } = await sendChunk(expectDefined(chunks.at(0), "single Discord text chunk"), true);
679
+ await onResult?.(result, kind, replyToId);
752
680
  return {
753
681
  ...result,
754
682
  platformMessageIds: result.id ? [result.id] : []
@@ -759,7 +687,7 @@ async function sendDiscordText(params) {
759
687
  for (const [index, chunk] of chunks.entries()) {
760
688
  const sent = await sendChunk(chunk, index === 0);
761
689
  last = sent.result;
762
- await onResult?.(last, "text", sent.replyToId);
690
+ await onResult?.(last, sent.kind, sent.replyToId);
763
691
  if (last.id) platformMessageIds.push(last.id);
764
692
  }
765
693
  if (!last) throw new Error("Discord send failed (empty chunk result)");
@@ -769,7 +697,7 @@ async function sendDiscordText(params) {
769
697
  };
770
698
  }
771
699
  async function sendDiscordMedia(params) {
772
- const { rest, channelId, text, mediaUrl, filename, mediaAccess, mediaLocalRoots, mediaReadFile, maxBytes, reply, request, maxLinesPerMessage, components, embeds, allowedMentions, chunkMode, silent, suppressEmbeds, maxChars, onResult } = params;
700
+ const { rest, channelId, text, mediaUrl, filename, mediaAccess, mediaLocalRoots, mediaReadFile, maxBytes, reply, request, maxLinesPerMessage, components, embeds, allowedMentions, chunkMode, silent, suppressEmbeds, maxChars, onResult, onPlatformSendDispatch } = params;
773
701
  const media = await loadWebMedia(mediaUrl, buildOutboundMediaLoadOptions({
774
702
  maxBytes,
775
703
  mediaAccess,
@@ -805,11 +733,13 @@ async function sendDiscordMedia(params) {
805
733
  replyTo: resolveDiscordReplyMessageId(reply, true),
806
734
  files: [{
807
735
  data: media.buffer,
808
- name: resolvedFileName
736
+ name: resolvedFileName,
737
+ contentType: media.contentType
809
738
  }]
810
739
  });
811
740
  let res;
812
741
  try {
742
+ await onPlatformSendDispatch?.();
813
743
  res = await request(() => createChannelMessage(rest, channelId, { body }), "media", { safety: "nonce-protected-create" });
814
744
  } catch (err) {
815
745
  if (!isDiscordUploadTooLargeError(err)) throw err;
@@ -825,7 +755,8 @@ async function sendDiscordMedia(params) {
825
755
  suppressEmbeds,
826
756
  allowedMentions,
827
757
  maxChars,
828
- onResult
758
+ onResult,
759
+ onPlatformSendDispatch
829
760
  });
830
761
  }
831
762
  await onResult?.(res, "media", reply?.messageId);
@@ -862,4 +793,4 @@ function formatReactionEmoji(emoji) {
862
793
  return buildReactionIdentifier(emoji);
863
794
  }
864
795
  //#endregion
865
- export { hasAllGuildPermissionsDiscord as A, clearGateways as B, DISCORD_MAX_STICKER_BYTES as C, canViewDiscordGuildChannel as D, canManageGuildRoleDiscord as E, createDiscordRestClient as F, resolveDiscordProxyFetchForAccount as G, registerGateway as H, createDiscordRuntimeAccountContext as I, validateDiscordProxyUrl as K, resolveDiscordClientAccountContext as L, hasAnyGuildPermissionDiscord as M, isThreadChannelType as N, fetchChannelPermissionsDiscord as O, createDiscordClient as P, resolveDiscordRest as R, DISCORD_MAX_EVENT_COVER_BYTES as S, canManageGuildMemberRoleDiscord as T, unregisterGateway as U, getGateway as V, parseAndResolveChannelRecipient as W, resolveDiscordMessageFlags as _, normalizeDiscordPollInput as a, stripUndefinedFields as b, normalizeStickerIds as c, resolveDiscordTargetChannelId as d, sendDiscordMedia as f, createDiscordMessageNonce as g, buildDiscordMessageRequest as h, formatReactionEmoji as i, hasAnyChannelPermissionDiscord as j, fetchMemberGuildPermissionsDiscord as k, resolveChannelId as l, SUPPRESS_NOTIFICATIONS_FLAG as m, buildDiscordTextChunks as n, normalizeEmojiName as o, sendDiscordText as p, withValidatedDiscordProxy as q, buildReactionIdentifier as r, normalizeReactionEmoji as s, buildDiscordSendError as t, resolveDiscordChannel as u, resolveDiscordSendComponents as v, DiscordSendError as w, DISCORD_MAX_EMOJI_BYTES as x, resolveDiscordSendEmbeds as y, DISCORD_REST_TIMEOUT_MS as z };
796
+ export { resolveDiscordMessageFlags as A, resolveDiscordProxyFetchForAccount as B, hasAllGuildPermissionsDiscord as C, SUPPRESS_NOTIFICATIONS_FLAG as D, isThreadChannelType as E, createDiscordRestClient as F, registerGateway as G, withValidatedDiscordProxy as H, createDiscordRuntimeAccountContext as I, unregisterGateway as K, resolveDiscordClientAccountContext as L, resolveDiscordSendEmbeds as M, resolveDiscordSuppressEmbeds as N, buildDiscordMessageRequest as O, createDiscordClient as P, resolveDiscordRest as R, fetchMemberGuildPermissionsDiscord as S, hasAnyGuildPermissionDiscord as T, clearGateways as U, validateDiscordProxyUrl as V, getGateway as W, DiscordSendError as _, normalizeDiscordPollInput as a, canViewDiscordGuildChannel as b, normalizeStickerIds as c, resolveDiscordTargetChannelId as d, sendDiscordMedia as f, DISCORD_MAX_STICKER_BYTES as g, DISCORD_MAX_EVENT_COVER_BYTES as h, formatReactionEmoji as i, resolveDiscordSendComponents as j, createDiscordMessageNonce as k, resolveChannelId as l, DISCORD_MAX_EMOJI_BYTES as m, buildDiscordTextChunks as n, normalizeEmojiName as o, sendDiscordText as p, parseAndResolveChannelRecipient as q, buildReactionIdentifier as r, normalizeReactionEmoji as s, buildDiscordSendError as t, resolveDiscordChannel as u, canManageGuildMemberRoleDiscord as v, hasAnyChannelPermissionDiscord as w, fetchChannelPermissionsDiscord as x, canManageGuildRoleDiscord as y, DISCORD_REST_TIMEOUT_MS as z };
@@ -1,4 +1,4 @@
1
- import { x as formatDiscordUserTag } from "./allow-list-DzKrtfah.js";
1
+ import { x as formatDiscordUserTag } from "./allow-list-BDMimASD.js";
2
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  //#region extensions/discord/src/monitor/sender-identity.ts
4
4
  function resolveDiscordWebhookId(message) {
@@ -2,14 +2,9 @@ import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entr
2
2
  //#region extensions/discord/setup-entry.ts
3
3
  var setup_entry_default = defineBundledChannelSetupEntry({
4
4
  importMetaUrl: import.meta.url,
5
- features: { legacyStateMigrations: true },
6
5
  plugin: {
7
6
  specifier: "./setup-plugin-api.js",
8
7
  exportName: "discordSetupPlugin"
9
- },
10
- legacyStateMigrations: {
11
- specifier: "./legacy-state-migrations-api.js",
12
- exportName: "detectDiscordLegacyStateMigrations"
13
8
  }
14
9
  });
15
10
  //#endregion
@@ -1,2 +1,2 @@
1
- import { t as discordSetupPlugin } from "./channel.setup-CmcwZ_qd.js";
1
+ import { t as discordSetupPlugin } from "./channel.setup-CSiwnMgs.js";
2
2
  export { discordSetupPlugin };
@@ -1,9 +1,8 @@
1
- import { a as mergeDiscordAccountConfig, c as resolveDiscordAccountAllowFrom, d as resolveDiscordAccountDmPolicy, n as isDiscordAccountEnabledForRuntime, o as resolveDefaultDiscordAccountId, r as listDiscordAccountIds, s as resolveDiscordAccount, u as resolveDiscordAccountDisabledReason } from "./accounts-DJTf1LtA.js";
2
- import { t as DiscordChannelConfigSchema } from "./config-schema-WHRQcY19.js";
3
- import { i as getChatChannelMeta, o as resolveConfiguredFromCredentialStatuses } from "./channel-api-CAJ0wMoV.js";
4
- import { t as inspectDiscordAccount } from "./account-inspect-SXiCBCgP.js";
5
- import { n as normalizeCompatibilityConfig } from "./doctor-contract-CCFMIDk9.js";
6
- import { n as secretTargetRegistryEntries, t as collectRuntimeConfigAssignments } from "./secret-config-contract-B1akrlyY.js";
1
+ import { t as DiscordChannelConfigSchema } from "./config-schema-DC5kDtQ5.js";
2
+ import { I as resolveConfiguredFromCredentialStatuses, P as getChatChannelMeta, c as resolveDiscordAccount, d as resolveDiscordAccountDisabledReason, f as resolveDiscordAccountDmPolicy, l as resolveDiscordAccountAllowFrom, n as isDiscordAccountEnabledForRuntime, o as mergeDiscordAccountConfig, r as listDiscordAccountIds, s as resolveDefaultDiscordAccountId } from "./accounts-DNl-oCEw.js";
3
+ import { t as inspectDiscordAccount } from "./account-inspect-D5xmUpnj.js";
4
+ import { n as normalizeCompatibilityConfig } from "./doctor-contract-DsWvKIXF.js";
5
+ import { r as secretTargetRegistryEntries, t as collectRuntimeConfigAssignments } from "./secret-config-contract-B3i6WxV5.js";
7
6
  import { n as unsupportedSecretRefSurfacePatterns, t as collectUnsupportedSecretRefConfigCandidates } from "./security-contract-DSHk7I2w.js";
8
7
  import { t as deriveLegacySessionChatType } from "./session-contract-BO5tlIdl.js";
9
8
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
@@ -11,7 +10,7 @@ import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
11
10
  import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter, createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
12
11
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
13
12
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
14
- import { createOpenProviderConfiguredRouteWarningCollector } from "openclaw/plugin-sdk/channel-policy";
13
+ import { createConditionalWarningCollector, createOpenProviderConfiguredRouteWarningCollector } from "openclaw/plugin-sdk/channel-policy";
15
14
  import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
16
15
  import { createEnvPatchedAccountSetupAdapter } from "openclaw/plugin-sdk/setup-runtime";
17
16
  //#region extensions/discord/src/security.ts
@@ -48,19 +47,18 @@ const collectDiscordSecurityWarnings = createOpenProviderConfiguredRouteWarningC
48
47
  remediation: "Set channels.discord.groupPolicy=\"allowlist\" and configure channels.discord.guilds.<id>.channels"
49
48
  }
50
49
  });
51
- const loadDiscordSecurityAuditModule = createLazyRuntimeModule(() => import("./security-audit.runtime-CPN0xFYz.js"));
50
+ const collectDiscordSecurityFindings = createConditionalWarningCollector.findings({
51
+ collectWarnings: collectDiscordSecurityWarnings,
52
+ checkId: "channels.discord.groups.open",
53
+ severity: "critical",
54
+ title: "Discord security warning"
55
+ });
56
+ const loadDiscordSecurityAuditModule = createLazyRuntimeModule(() => import("./security-audit.runtime-BVKF9VtY.js"));
52
57
  const discordSecurityAdapter = {
53
58
  resolveDmPolicy: resolveDiscordDmPolicy,
54
- collectWarnings: collectDiscordSecurityWarnings,
59
+ collectWarnings: collectDiscordSecurityFindings,
55
60
  collectAuditFindings: async (params) => (await loadDiscordSecurityAuditModule()).collectDiscordSecurityAuditFindings(params)
56
61
  };
57
- const discordSetupAdapter = createEnvPatchedAccountSetupAdapter({
58
- channelKey: "discord",
59
- defaultAccountOnlyEnvError: "DISCORD_BOT_TOKEN can only be used for the default account.",
60
- missingCredentialError: "Discord requires token (or --use-env).",
61
- hasCredentials: (input) => Boolean(input.token),
62
- buildPatch: (input) => input.token ? { token: input.token } : {}
63
- });
64
62
  const discordSetupContract = defineChannelSetupContract({
65
63
  fields: {
66
64
  token: {
@@ -76,10 +74,17 @@ const discordSetupContract = defineChannelSetupContract({
76
74
  cli: {
77
75
  flags: "--use-env",
78
76
  description: "Use DISCORD_BOT_TOKEN"
79
- }
77
+ },
78
+ envVars: ["DISCORD_BOT_TOKEN"]
80
79
  }
81
80
  },
82
- legacyAdapter: discordSetupAdapter
81
+ legacyAdapter: createEnvPatchedAccountSetupAdapter({
82
+ channelKey: "discord",
83
+ defaultAccountOnlyEnvError: "DISCORD_BOT_TOKEN can only be used for the default account.",
84
+ missingCredentialError: "Discord requires token (or --use-env).",
85
+ hasCredentials: (input) => Boolean(input.token),
86
+ buildPatch: (input) => input.token ? { token: input.token } : {}
87
+ })
83
88
  });
84
89
  //#endregion
85
90
  //#region extensions/discord/src/doctor-shared.ts
@@ -87,7 +92,7 @@ const DISCORD_LEGACY_CONFIG_RULES = [];
87
92
  //#endregion
88
93
  //#region extensions/discord/src/shared.ts
89
94
  const DISCORD_CHANNEL = "discord";
90
- const loadDiscordDoctorModule = createLazyRuntimeModule(() => import("./doctor-Bc4S1qyd.js"));
95
+ const loadDiscordDoctorModule = createLazyRuntimeModule(() => import("./doctor-DYY31GrO.js"));
91
96
  const discordDoctor = {
92
97
  dmAllowFromMode: "topOnly",
93
98
  groupModel: "route",
@@ -128,7 +133,7 @@ const discordConfigAdapter = createScopedChannelConfigAdapter({
128
133
  function createDiscordPluginBase(params) {
129
134
  return {
130
135
  id: DISCORD_CHANNEL,
131
- ...params.setupContract ? { setupContract: params.setupContract } : {},
136
+ setupContract: params.setupContract,
132
137
  ...params.setupWizard ? { setupWizard: params.setupWizard } : {},
133
138
  meta: { ...getChatChannelMeta(DISCORD_CHANNEL) },
134
139
  capabilities: {
@@ -178,9 +183,8 @@ function createDiscordPluginBase(params) {
178
183
  unsupportedSecretRefSurfacePatterns,
179
184
  collectUnsupportedSecretRefConfigCandidates,
180
185
  collectRuntimeConfigAssignments
181
- },
182
- setup: params.setup
186
+ }
183
187
  };
184
188
  }
185
189
  //#endregion
186
- export { discordSetupContract as a, discordSetupAdapter as i, discordConfigAdapter as n, discordSecurityAdapter as o, DISCORD_LEGACY_CONFIG_RULES as r, createDiscordPluginBase as t };
190
+ export { discordSecurityAdapter as a, discordSetupContract as i, discordConfigAdapter as n, DISCORD_LEGACY_CONFIG_RULES as r, createDiscordPluginBase as t };
@@ -0,0 +1,49 @@
1
+ import { en as __exportAll } from "./retry-DNsVTeTo.js";
2
+ import { o as unbindThreadBindingsBySessionKey, r as listThreadBindingsBySessionKey } from "./thread-bindings-VlymUnbz.js";
3
+ import { normalizeOptionalLowercaseString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
4
+ //#region extensions/discord/src/subagent-hooks.ts
5
+ var subagent_hooks_exports = /* @__PURE__ */ __exportAll({
6
+ handleDiscordSubagentDeliveryTarget: () => handleDiscordSubagentDeliveryTarget,
7
+ handleDiscordSubagentEnded: () => handleDiscordSubagentEnded
8
+ });
9
+ function normalizeThreadBindingTargetKind(raw) {
10
+ const normalized = normalizeOptionalLowercaseString(raw);
11
+ if (normalized === "subagent" || normalized === "acp") return normalized;
12
+ }
13
+ function handleDiscordSubagentEnded(event) {
14
+ unbindThreadBindingsBySessionKey({
15
+ targetSessionKey: event.targetSessionKey,
16
+ accountId: event.accountId,
17
+ targetKind: normalizeThreadBindingTargetKind(event.targetKind),
18
+ reason: event.reason,
19
+ sendFarewell: event.sendFarewell
20
+ });
21
+ }
22
+ function handleDiscordSubagentDeliveryTarget(event) {
23
+ if (!event.expectsCompletionMessage) return;
24
+ if (normalizeOptionalLowercaseString(event.requesterOrigin?.channel) !== "discord") return;
25
+ const requesterAccountId = event.requesterOrigin?.accountId?.trim();
26
+ const requesterThreadId = event.requesterOrigin?.threadId != null && event.requesterOrigin.threadId !== "" ? normalizeOptionalStringifiedId(event.requesterOrigin.threadId) ?? "" : "";
27
+ const bindings = listThreadBindingsBySessionKey({
28
+ targetSessionKey: event.childSessionKey,
29
+ ...requesterAccountId ? { accountId: requesterAccountId } : {},
30
+ targetKind: "subagent"
31
+ });
32
+ if (bindings.length === 0) return;
33
+ let binding;
34
+ if (requesterThreadId) binding = bindings.find((entry) => {
35
+ if (entry.threadId !== requesterThreadId) return false;
36
+ if (requesterAccountId && entry.accountId !== requesterAccountId) return false;
37
+ return true;
38
+ });
39
+ if (!binding && bindings.length === 1) binding = bindings[0];
40
+ if (!binding) return;
41
+ return { origin: {
42
+ channel: "discord",
43
+ accountId: binding.accountId,
44
+ to: `channel:${binding.threadId}`,
45
+ threadId: binding.threadId
46
+ } };
47
+ }
48
+ //#endregion
49
+ export { handleDiscordSubagentEnded as n, subagent_hooks_exports as r, handleDiscordSubagentDeliveryTarget as t };
@@ -1,16 +1,12 @@
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-Dxy7Fmnq.js").then((n) => n.i));
4
- const loadDiscordSubagentProgressModule = createLazyRuntimeModule(() => import("./subagent-progress-DI3sYLLo.js"));
3
+ const loadDiscordSubagentHooksModule = createLazyRuntimeModule(() => import("./subagent-hooks-CNT2ZJTJ.js").then((n) => n.r));
4
+ const loadDiscordSubagentProgressModule = createLazyRuntimeModule(() => import("./subagent-progress-FPLqBY1s.js"));
5
5
  function registerDiscordSubagentHooks(api) {
6
6
  api.on("gateway_start", async () => {
7
7
  const { recoverDiscordSubagentProgress } = await loadDiscordSubagentProgressModule();
8
8
  await recoverDiscordSubagentProgress(api);
9
9
  });
10
- api.on("subagent_progress", async (event) => {
11
- const { handleDiscordSubagentProgress } = await loadDiscordSubagentProgressModule();
12
- await handleDiscordSubagentProgress(api, event);
13
- });
14
10
  api.on("subagent_ended", async (event) => {
15
11
  const { handleDiscordSubagentEnded } = await loadDiscordSubagentHooksModule();
16
12
  handleDiscordSubagentEnded(event);