@openclaw/discord 2026.7.2-beta.7 → 2026.8.1-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/{account-inspect-SXiCBCgP.js → account-inspect-CqzrH14k.js} +48 -42
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/action-runtime-api.js +1 -1
  4. package/dist/{active-turn-thread-route-MlKWp8RD.js → active-turn-thread-route-fmHl1HNd.js} +9 -11
  5. package/dist/{activities-api-DTKsuDxf.js → activities-api-DS7vpdtp.js} +4 -4
  6. package/dist/activities-api.js +1 -1
  7. package/dist/{allow-list-DzKrtfah.js → allow-list-DnxIlPP2.js} +2 -3
  8. package/dist/{api-DnrK9gML.js → api-DNVbJyEy.js} +7 -2
  9. package/dist/api.js +15 -15
  10. package/dist/{approval-handler.runtime-HymvFTYn.js → approval-handler.runtime-B6yEV79q.js} +5 -5
  11. package/dist/{approval-message-safety-DEyKVsAw.js → approval-message-safety-AcIxvrf3.js} +1 -1
  12. package/dist/{audit-CjsrabP8.js → audit-Db-rlntl.js} +4 -4
  13. package/dist/{channel-vKa-76xY.js → channel-CnnbJSt5.js} +46 -72
  14. package/dist/{channel-actions-uXFTJX3o.js → channel-actions-5s_hjYKd.js} +4 -4
  15. package/dist/{channel-actions.runtime-CIYU90sl.js → channel-actions.runtime-CLKrx6tr.js} +53 -36
  16. package/dist/channel-config-api.js +1 -1
  17. package/dist/channel-plugin-api.js +1 -1
  18. package/dist/{channel.setup-CmcwZ_qd.js → channel.setup-BFAO-V1P.js} +15 -53
  19. package/dist/{config-schema-WHRQcY19.js → config-schema-BgEskFAs.js} +9 -4
  20. package/dist/{directory-config-D_LojtCe.js → directory-config-BVX7Cflc.js} +1 -1
  21. package/dist/directory-contract-api.js +1 -1
  22. package/dist/{directory-live-Bw5Ephzv.js → directory-live-DGIGxpIo.js} +6 -3
  23. package/dist/{doctor-Bc4S1qyd.js → doctor-BzC-TLnB.js} +4 -4
  24. package/dist/{doctor-contract-CCFMIDk9.js → doctor-contract-DLa-BTiU.js} +2 -3
  25. package/dist/doctor-contract-api.js +147 -2
  26. package/dist/{handle-action.guild-admin-D6VRRW-C.js → handle-action.guild-admin-BNVTUISF.js} +4 -7
  27. package/dist/{inbound-event-delivery-CEPlt2uz.js → inbound-event-delivery-De2qxTrP.js} +4 -25
  28. package/dist/index.js +4 -2
  29. package/dist/{message-handler-CeiSulIw.js → message-handler-Unk_f10F.js} +41 -32
  30. package/dist/{message-handler.preflight-DibgQFf2.js → message-handler.preflight-C9zecxR9.js} +50 -26
  31. package/dist/{message-handler.process-Dnc_oz9y.js → message-handler.process-DWQ6UHHu.js} +130 -166
  32. package/dist/{message-utils-BgTwT_q7.js → message-utils-BSCPVgy0.js} +4 -4
  33. package/dist/{model-picker-preference-primitives-D25pnCOu.js → model-picker-preference-primitives-BHT1LkR_.js} +3 -3
  34. package/dist/{outbound-adapter-DtE-i2OJ.js → outbound-adapter-D9nRivT1.js} +91 -32
  35. package/dist/{outbound-components-C7GVyfPh.js → outbound-components-cTzwBJ60.js} +3 -3
  36. package/dist/{outbound-session-route-H-HoyH5U.js → outbound-session-route-DxLkrgKQ.js} +68 -95
  37. package/dist/{pluralkit-CD4B11JB.js → pluralkit-DdiJ9KMK.js} +1 -1
  38. package/dist/{preflight-audio-BjnQZ5yS.js → preflight-audio-DrnqFA8U.js} +22 -28
  39. package/dist/{probe-BeWKhjqX.js → probe-Bl-k5_Ku.js} +36 -12
  40. package/dist/probe.runtime-M9fREKvp.js +2 -0
  41. package/dist/{provider-DfQJX3z5.js → provider-DvSNb-2v.js} +969 -1248
  42. package/dist/{provider-session.runtime-Bo88k0pV.js → provider-session.runtime-BUEqD0rA.js} +3 -3
  43. package/dist/provider.runtime-C9PnJZbZ.js +2 -0
  44. package/dist/realtime-session.runtime-C7wen-aF.js +1340 -0
  45. package/dist/{resolve-allowlist-common-DHERApxi.js → resolve-allowlist-common-D04lpEzb.js} +2 -2
  46. package/dist/{resolve-channels-BjepAj8b.js → resolve-channels-Dm7jEeg6.js} +4 -4
  47. package/dist/{resolve-users-Bc28htgt.js → resolve-users-bktrCUUU.js} +3 -3
  48. package/dist/{chunk-DX4jpFQP.js → retry-CLpJcXXf.js} +291 -68
  49. package/dist/{runtime-_aRC6V2s.js → runtime-DGsSyDTS.js} +30 -25
  50. package/dist/{runtime-BmW_j_hl.js → runtime-DoHjckYm.js} +4 -6
  51. package/dist/runtime-api.actions.js +2 -2
  52. package/dist/runtime-api.js +22 -23
  53. package/dist/runtime-api.lookup.js +5 -5
  54. package/dist/runtime-api.monitor-CHxrFPnW.js +5 -0
  55. package/dist/runtime-api.monitor.js +5 -5
  56. package/dist/runtime-api.send.js +6 -6
  57. package/dist/runtime-api.threads.js +5 -6
  58. package/dist/sdk-runtime-QpY8PvCh.js +370 -0
  59. package/dist/{send-CdkZ6zeW.js → send-B7Q6Oc1I.js} +175 -86
  60. package/dist/{send.components-5uqwkjgE.js → send.components-iJyFXw9L.js} +24 -28
  61. package/dist/{send.outbound-D-80Ej-t.js → send.outbound-DS5tHwfR.js} +37 -24
  62. package/dist/{send.reactions-CtlmGd_o.js → send.reactions-BAn0iiVQ.js} +14 -21
  63. package/dist/{send.receipt-CuwRrpFz.js → send.receipt-IPI1p-SP.js} +19 -1
  64. package/dist/{send.shared-jpvAG_u6.js → send.shared-BmwFjW6T.js} +16 -85
  65. package/dist/{sender-identity-mG_zsdox.js → sender-identity-QtalnCYv.js} +1 -1
  66. package/dist/setup-entry.js +0 -5
  67. package/dist/setup-plugin-api.js +1 -1
  68. package/dist/{shared-CXF1tup1.js → shared-BIXIX6uJ.js} +16 -17
  69. package/dist/{subagent-hooks-Dxy7Fmnq.js → subagent-hooks-CTt5KCJr.js} +2 -2
  70. package/dist/subagent-hooks-api.js +2 -6
  71. package/dist/subagent-progress-DhaE_h8a.js +109 -0
  72. package/dist/{system-events-DdUqf91B.js → system-events-CTqDf6_s.js} +2 -2
  73. package/dist/{target-resolver-C3s_2m0t.js → target-resolver-maOKSqO0.js} +2 -2
  74. package/dist/targets-yUFTHoAx.js +3 -0
  75. package/dist/{thread-bindings-C-M-ly7P.js → thread-bindings-3L8p82GV.js} +5 -7
  76. package/dist/{thread-bindings.manager-DYvSlrva.js → thread-bindings.manager-DCIH6WDC.js} +257 -29
  77. package/dist/{thread-bindings.session-updates-DAIlp7Px.js → thread-bindings.session-updates-bJ2KQFY6.js} +1 -1
  78. package/dist/{thread-bindings.state-Cgi5uRn-.js → thread-bindings.state-aeV8HNgV.js} +2 -15
  79. package/dist/{transcripts-source-DIKGsTGT.js → transcripts-source-CfFMexGt.js} +1 -1
  80. package/dist/transcripts-source-api.js +1 -1
  81. package/dist/{typing--Mzo2kM7.js → typing-CS-nNVoe.js} +1 -1
  82. package/dist/voice-runtime-BEdqNcST.js +2459 -0
  83. package/openclaw.plugin.json +203 -19
  84. package/package.json +15 -9
  85. package/skills/discord/SKILL.md +22 -115
  86. package/dist/legacy-state-migrations-api.js +0 -138
  87. package/dist/manager.runtime-Bjav3pfC.js +0 -3655
  88. package/dist/preflight-audio.runtime-CoCXMM8r.js +0 -7
  89. package/dist/probe.runtime-DqFGFMbZ.js +0 -2
  90. package/dist/provider.runtime-Cy7XZmyh.js +0 -2
  91. package/dist/runtime-api.monitor-CCRubd3-.js +0 -5
  92. package/dist/session-binding-contract-api.js +0 -2
  93. package/dist/subagent-progress-DI3sYLLo.js +0 -664
  94. package/dist/targets-Dv_RN7vT.js +0 -3
  95. package/dist/thread-bindings.discord-api-BoDNqamb.js +0 -246
@@ -1,15 +1,6 @@
1
- import { Dt as sendChannelTyping, bt as getChannelMessage, dt as deleteOwnMessageReaction, ft as listMessageReactionUsers, ut as createOwnMessageReaction } from "./chunk-DX4jpFQP.js";
2
- import { P as createDiscordClient, R as resolveDiscordRest, i as formatReactionEmoji, r as buildReactionIdentifier, s as normalizeReactionEmoji } from "./send.shared-jpvAG_u6.js";
1
+ import { Et as getChannelMessage, _t as deleteOwnMessageReaction, gt as createOwnMessageReaction, vt as listMessageReactionUsers } from "./retry-CLpJcXXf.js";
2
+ import { P as createDiscordClient, i as formatReactionEmoji, r as buildReactionIdentifier, s as normalizeReactionEmoji } from "./send.shared-BmwFjW6T.js";
3
3
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
4
- //#region extensions/discord/src/send.typing.ts
5
- async function sendTypingDiscord(channelId, opts) {
6
- await sendChannelTyping(resolveDiscordRest(opts), channelId);
7
- return {
8
- ok: true,
9
- channelId
10
- };
11
- }
12
- //#endregion
13
4
  //#region extensions/discord/src/send.reactions.ts
14
5
  function createDiscordReactionRuntimeClient(opts) {
15
6
  return createDiscordClient(opts);
@@ -32,16 +23,17 @@ async function reactMessageDiscord(channelId, messageId, emoji, opts) {
32
23
  return { ok: true };
33
24
  }
34
25
  async function removeReactionDiscord(channelId, messageId, emoji, opts) {
35
- const { rest } = isDiscordReactionRuntimeContext(opts) ? createDiscordReactionRuntimeClient(opts) : resolveDiscordReactionClient(opts);
36
- await deleteOwnMessageReaction(rest, channelId, messageId, normalizeReactionEmoji(emoji));
26
+ const { rest, request } = isDiscordReactionRuntimeContext(opts) ? createDiscordReactionRuntimeClient(opts) : resolveDiscordReactionClient(opts);
27
+ const encoded = normalizeReactionEmoji(emoji);
28
+ await request(() => deleteOwnMessageReaction(rest, channelId, messageId, encoded), "reaction-remove");
37
29
  return { ok: true };
38
30
  }
39
31
  async function removeOwnReactionsDiscord(channelId, messageId, opts) {
40
- const { rest } = isDiscordReactionRuntimeContext(opts) ? createDiscordReactionRuntimeClient(opts) : resolveDiscordReactionClient(opts);
41
- const message = await getChannelMessage(rest, channelId, messageId);
32
+ const { rest, request } = isDiscordReactionRuntimeContext(opts) ? createDiscordReactionRuntimeClient(opts) : resolveDiscordReactionClient(opts);
33
+ const message = await request(() => getChannelMessage(rest, channelId, messageId), "reaction-list");
42
34
  const identifiers = /* @__PURE__ */ new Set();
43
35
  for (const reaction of message.reactions ?? []) {
44
- const identifier = buildReactionIdentifier(reaction.emoji);
36
+ const identifier = reaction.me ? buildReactionIdentifier(reaction.emoji) : void 0;
45
37
  if (identifier) identifiers.add(identifier);
46
38
  }
47
39
  if (identifiers.size === 0) return {
@@ -49,22 +41,23 @@ async function removeOwnReactionsDiscord(channelId, messageId, opts) {
49
41
  removed: []
50
42
  };
51
43
  const removed = Array.from(identifiers);
52
- await Promise.all(removed.map((identifier) => deleteOwnMessageReaction(rest, channelId, messageId, normalizeReactionEmoji(identifier))));
44
+ await Promise.all(removed.map((identifier) => request(() => deleteOwnMessageReaction(rest, channelId, messageId, normalizeReactionEmoji(identifier)), "reaction-remove")));
53
45
  return {
54
46
  ok: true,
55
47
  removed
56
48
  };
57
49
  }
58
50
  async function fetchReactionsDiscord(channelId, messageId, opts) {
59
- const { rest } = isDiscordReactionRuntimeContext(opts) ? createDiscordReactionRuntimeClient(opts) : resolveDiscordReactionClient(opts);
60
- const reactions = (await getChannelMessage(rest, channelId, messageId)).reactions ?? [];
51
+ const { rest, request } = isDiscordReactionRuntimeContext(opts) ? createDiscordReactionRuntimeClient(opts) : resolveDiscordReactionClient(opts);
52
+ const reactions = (await request(() => getChannelMessage(rest, channelId, messageId), "reaction-list")).reactions ?? [];
61
53
  if (reactions.length === 0) return [];
62
54
  const limit = typeof opts.limit === "number" && Number.isFinite(opts.limit) ? Math.min(Math.max(Math.floor(opts.limit), 1), 100) : 100;
63
55
  const summaries = [];
64
56
  for (const reaction of reactions) {
65
57
  const identifier = buildReactionIdentifier(reaction.emoji);
66
58
  if (!identifier) continue;
67
- const users = await listMessageReactionUsers(rest, channelId, messageId, encodeURIComponent(identifier), { limit });
59
+ const encoded = encodeURIComponent(identifier);
60
+ const users = await request(() => listMessageReactionUsers(rest, channelId, messageId, encoded, { limit }), "reaction-users");
68
61
  summaries.push({
69
62
  emoji: {
70
63
  id: reaction.emoji.id ?? null,
@@ -82,4 +75,4 @@ async function fetchReactionsDiscord(channelId, messageId, opts) {
82
75
  return summaries;
83
76
  }
84
77
  //#endregion
85
- export { sendTypingDiscord as a, removeReactionDiscord as i, reactMessageDiscord as n, removeOwnReactionsDiscord as r, fetchReactionsDiscord as t };
78
+ export { removeReactionDiscord as i, reactMessageDiscord as n, removeOwnReactionsDiscord as r, fetchReactionsDiscord as t };
@@ -1,5 +1,23 @@
1
1
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
2
+ import { attachChannelToResults } from "openclaw/plugin-sdk/channel-send-result";
2
3
  //#region extensions/discord/src/send.receipt.ts
4
+ function createDiscordSendReceiptFromResults(params) {
5
+ const receipt = createMessageReceiptFromOutboundResults({
6
+ results: attachChannelToResults("discord", params.results),
7
+ threadId: params.threadId
8
+ });
9
+ return {
10
+ ...receipt,
11
+ parts: receipt.parts.map(({ platformMessageId, kind, threadId, replyToId, raw }, index) => ({
12
+ platformMessageId,
13
+ kind,
14
+ index,
15
+ threadId,
16
+ replyToId,
17
+ raw
18
+ }))
19
+ };
20
+ }
3
21
  function createDiscordSendReceipt(params) {
4
22
  return createMessageReceiptFromOutboundResults({
5
23
  results: params.platformMessageIds.map((messageId) => messageId.trim()).filter((messageId) => messageId && messageId !== "unknown").map((messageId, index) => {
@@ -45,4 +63,4 @@ function createDiscordSendResult(params) {
45
63
  };
46
64
  }
47
65
  //#endregion
48
- export { createDiscordSendResult as n, createDiscordSendReceipt as t };
66
+ export { createDiscordSendReceiptFromResults as n, createDiscordSendResult as r, createDiscordSendReceipt as t };
@@ -1,14 +1,11 @@
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";
1
+ import { A as RequestClient, Dt as getThreadMember, H as serializePayload, Ht as getGuild, Tt as getChannel, U as Embed, Ut as getGuildMember, a as chunkDiscordTextWithMode, ft as stripUndefinedFields, ht as getCurrentUser, mt as createUserDmChannel, n as createDiscordRetryRunner, s as resolveDiscordReplyMessageId, yt as createChannelMessage } from "./retry-CLpJcXXf.js";
2
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";
3
+ import { t as parseAndResolveDiscordTarget } from "./target-resolver-maOKSqO0.js";
4
4
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
5
5
  import { normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  import { ChannelType, MessageFlags, PermissionFlagsBits } from "discord-api-types/v10";
7
7
  import { randomBytes } from "node:crypto";
8
- import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
9
8
  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";
12
9
  import { makeProxyFetch } from "openclaw/plugin-sdk/fetch-runtime";
13
10
  import { danger } from "openclaw/plugin-sdk/runtime-env";
14
11
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
@@ -18,11 +15,9 @@ import { resolveTextChunksWithFallback } from "openclaw/plugin-sdk/reply-payload
18
15
  import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
19
16
  //#region extensions/discord/src/proxy-fetch.ts
20
17
  function resolveDiscordProxyUrl(account, cfg) {
21
- const accountProxy = account.config.proxy?.trim();
18
+ const accountProxy = normalizeOptionalString(account.config.proxy);
22
19
  if (accountProxy) return accountProxy;
23
- const channelProxy = cfg?.channels?.discord?.proxy;
24
- if (typeof channelProxy !== "string") return;
25
- return channelProxy.trim() || void 0;
20
+ return normalizeOptionalString(cfg?.channels?.discord?.proxy);
26
21
  }
27
22
  function resolveDiscordProxyFetchByUrl(proxyUrl, runtime) {
28
23
  return withValidatedDiscordProxy(proxyUrl, runtime, (proxy) => makeProxyFetch(proxy));
@@ -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 {
@@ -562,6 +489,9 @@ function resolveDiscordMessageFlags(params) {
562
489
  if (params.silent) flags |= SUPPRESS_NOTIFICATIONS_FLAG;
563
490
  return flags || void 0;
564
491
  }
492
+ function resolveDiscordSuppressEmbeds(params) {
493
+ return params.override ?? params.configured ?? true;
494
+ }
565
495
  function buildDiscordMessageRequest(params) {
566
496
  const payload = buildDiscordMessagePayload(params);
567
497
  const nonce = params.endpoint === "create-message" ? params.nonce ?? createDiscordMessageNonce() : void 0;
@@ -575,9 +505,6 @@ function buildDiscordMessageRequest(params) {
575
505
  enforce_nonce: nonce ? true : void 0
576
506
  });
577
507
  }
578
- function stripUndefinedFields(value) {
579
- return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
580
- }
581
508
  function hasV2Components(components) {
582
509
  return Boolean(components?.some((component) => "isV2" in component && component.isV2));
583
510
  }
@@ -710,7 +637,7 @@ function buildDiscordTextChunks(text, opts = {}) {
710
637
  }));
711
638
  }
712
639
  async function sendDiscordText(params) {
713
- const { rest, channelId, text, request, reply, maxLinesPerMessage, components, embeds, allowedMentions, chunkMode, silent, suppressEmbeds, maxChars, onResult } = params;
640
+ const { rest, channelId, text, request, reply, maxLinesPerMessage, components, embeds, allowedMentions, chunkMode, silent, suppressEmbeds, maxChars, onResult, onPlatformSendDispatch } = params;
714
641
  if (!text.trim()) throw new Error("Message must be non-empty for Discord sends");
715
642
  const chunks = buildDiscordTextChunks(text, {
716
643
  maxLinesPerMessage,
@@ -741,6 +668,7 @@ async function sendDiscordText(params) {
741
668
  flags,
742
669
  replyTo: chunkReplyTo
743
670
  });
671
+ await onPlatformSendDispatch?.();
744
672
  return {
745
673
  result: await request(() => createChannelMessage(rest, channelId, { body }), "text", { safety: "nonce-protected-create" }),
746
674
  replyToId: chunkReplyTo
@@ -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 { 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, resolveDiscordSuppressEmbeds 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 };
@@ -1,4 +1,4 @@
1
- import { x as formatDiscordUserTag } from "./allow-list-DzKrtfah.js";
1
+ import { x as formatDiscordUserTag } from "./allow-list-DnxIlPP2.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-BFAO-V1P.js";
2
2
  export { discordSetupPlugin };
@@ -1,8 +1,8 @@
1
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";
2
+ import { t as DiscordChannelConfigSchema } from "./config-schema-BgEskFAs.js";
3
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";
4
+ import { t as inspectDiscordAccount } from "./account-inspect-CqzrH14k.js";
5
+ import { n as normalizeCompatibilityConfig } from "./doctor-contract-DLa-BTiU.js";
6
6
  import { n as secretTargetRegistryEntries, t as collectRuntimeConfigAssignments } from "./secret-config-contract-B1akrlyY.js";
7
7
  import { n as unsupportedSecretRefSurfacePatterns, t as collectUnsupportedSecretRefConfigCandidates } from "./security-contract-DSHk7I2w.js";
8
8
  import { t as deriveLegacySessionChatType } from "./session-contract-BO5tlIdl.js";
@@ -54,13 +54,6 @@ const discordSecurityAdapter = {
54
54
  collectWarnings: collectDiscordSecurityWarnings,
55
55
  collectAuditFindings: async (params) => (await loadDiscordSecurityAuditModule()).collectDiscordSecurityAuditFindings(params)
56
56
  };
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
57
  const discordSetupContract = defineChannelSetupContract({
65
58
  fields: {
66
59
  token: {
@@ -76,10 +69,17 @@ const discordSetupContract = defineChannelSetupContract({
76
69
  cli: {
77
70
  flags: "--use-env",
78
71
  description: "Use DISCORD_BOT_TOKEN"
79
- }
72
+ },
73
+ envVars: ["DISCORD_BOT_TOKEN"]
80
74
  }
81
75
  },
82
- legacyAdapter: discordSetupAdapter
76
+ legacyAdapter: createEnvPatchedAccountSetupAdapter({
77
+ channelKey: "discord",
78
+ defaultAccountOnlyEnvError: "DISCORD_BOT_TOKEN can only be used for the default account.",
79
+ missingCredentialError: "Discord requires token (or --use-env).",
80
+ hasCredentials: (input) => Boolean(input.token),
81
+ buildPatch: (input) => input.token ? { token: input.token } : {}
82
+ })
83
83
  });
84
84
  //#endregion
85
85
  //#region extensions/discord/src/doctor-shared.ts
@@ -87,7 +87,7 @@ const DISCORD_LEGACY_CONFIG_RULES = [];
87
87
  //#endregion
88
88
  //#region extensions/discord/src/shared.ts
89
89
  const DISCORD_CHANNEL = "discord";
90
- const loadDiscordDoctorModule = createLazyRuntimeModule(() => import("./doctor-Bc4S1qyd.js"));
90
+ const loadDiscordDoctorModule = createLazyRuntimeModule(() => import("./doctor-BzC-TLnB.js"));
91
91
  const discordDoctor = {
92
92
  dmAllowFromMode: "topOnly",
93
93
  groupModel: "route",
@@ -128,7 +128,7 @@ const discordConfigAdapter = createScopedChannelConfigAdapter({
128
128
  function createDiscordPluginBase(params) {
129
129
  return {
130
130
  id: DISCORD_CHANNEL,
131
- ...params.setupContract ? { setupContract: params.setupContract } : {},
131
+ setupContract: params.setupContract,
132
132
  ...params.setupWizard ? { setupWizard: params.setupWizard } : {},
133
133
  meta: { ...getChatChannelMeta(DISCORD_CHANNEL) },
134
134
  capabilities: {
@@ -178,9 +178,8 @@ function createDiscordPluginBase(params) {
178
178
  unsupportedSecretRefSurfacePatterns,
179
179
  collectUnsupportedSecretRefConfigCandidates,
180
180
  collectRuntimeConfigAssignments
181
- },
182
- setup: params.setup
181
+ }
183
182
  };
184
183
  }
185
184
  //#endregion
186
- export { discordSetupContract as a, discordSetupAdapter as i, discordConfigAdapter as n, discordSecurityAdapter as o, DISCORD_LEGACY_CONFIG_RULES as r, createDiscordPluginBase as t };
185
+ export { discordSecurityAdapter as a, discordSetupContract as i, discordConfigAdapter as n, DISCORD_LEGACY_CONFIG_RULES as r, createDiscordPluginBase as t };
@@ -1,6 +1,6 @@
1
- import { Yt as __exportAll } from "./chunk-DX4jpFQP.js";
1
+ import { tn as __exportAll } from "./retry-CLpJcXXf.js";
2
2
  import { s as resolveDiscordAccount } from "./accounts-DJTf1LtA.js";
3
- import { n as autoBindSpawnedDiscordSubagent, o as unbindThreadBindingsBySessionKey, r as listThreadBindingsBySessionKey } from "./thread-bindings-C-M-ly7P.js";
3
+ import { n as autoBindSpawnedDiscordSubagent, o as unbindThreadBindingsBySessionKey, r as listThreadBindingsBySessionKey } from "./thread-bindings-3L8p82GV.js";
4
4
  import { normalizeOptionalLowercaseString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { formatThreadBindingDisabledError, formatThreadBindingSpawnDisabledError, resolveThreadBindingSpawnPolicy } from "openclaw/plugin-sdk/conversation-runtime";
6
6
  //#region extensions/discord/src/subagent-hooks.ts
@@ -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-CTt5KCJr.js").then((n) => n.i));
4
+ const loadDiscordSubagentProgressModule = createLazyRuntimeModule(() => import("./subagent-progress-DhaE_h8a.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);
@@ -0,0 +1,109 @@
1
+ import { l as resolveDiscordAccountConfig, s as resolveDiscordAccount } from "./accounts-DJTf1LtA.js";
2
+ import { i as removeReactionDiscord } from "./send.reactions-BAn0iiVQ.js";
3
+ import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/routing";
4
+ import { DEFAULT_EMOJIS } from "openclaw/plugin-sdk/channel-feedback";
5
+ //#region extensions/discord/src/subagent-progress.ts
6
+ const PROGRESS_STORE_TTL_MS = 10080 * 6e4;
7
+ const MAX_TRACKED_RUNS = 4096;
8
+ const RETRY_BASE_DELAY_MS = 1e3;
9
+ const RETRY_MAX_DELAY_MS = 60 * 6e4;
10
+ const RETRY_MAX_ATTEMPTS = 12;
11
+ const HISTORICAL_RUNNING_EMOJIS = /* @__PURE__ */ new Set([
12
+ "1️⃣",
13
+ "2️⃣",
14
+ "3️⃣",
15
+ "4️⃣",
16
+ "5️⃣",
17
+ "6️⃣",
18
+ "7️⃣",
19
+ "8️⃣",
20
+ "9️⃣",
21
+ "🔟"
22
+ ]);
23
+ const recoveryRetries = /* @__PURE__ */ new Map();
24
+ function logFailure(api, action, error) {
25
+ const message = error instanceof Error ? error.message : String(error);
26
+ api.logger.debug?.(`discord retired subagent progress ${action} failed: ${message}`);
27
+ }
28
+ function reservedReactionEmojis(api, accountAckReaction) {
29
+ const reserved = new Set(Object.values(DEFAULT_EMOJIS));
30
+ for (const emoji of [api.config.messages?.ackReaction, accountAckReaction]) if (emoji?.trim()) reserved.add(emoji.trim());
31
+ for (const agent of api.config.agents?.list ?? []) {
32
+ const emoji = agent.identity?.emoji?.trim();
33
+ if (emoji) reserved.add(emoji);
34
+ }
35
+ return reserved;
36
+ }
37
+ function clearRecoveryRetry(api) {
38
+ const retry = recoveryRetries.get(api);
39
+ if (retry?.timer) clearTimeout(retry.timer);
40
+ recoveryRetries.delete(api);
41
+ }
42
+ function scheduleRecoveryRetry(api) {
43
+ const retry = recoveryRetries.get(api) ?? { attempts: 0 };
44
+ if (retry.timer || retry.attempts >= RETRY_MAX_ATTEMPTS) return;
45
+ const delayMs = Math.min(RETRY_BASE_DELAY_MS * 2 ** retry.attempts, RETRY_MAX_DELAY_MS);
46
+ retry.attempts += 1;
47
+ retry.timer = setTimeout(() => {
48
+ retry.timer = void 0;
49
+ recoverDiscordSubagentProgress(api);
50
+ }, delayMs);
51
+ retry.timer.unref?.();
52
+ recoveryRetries.set(api, retry);
53
+ }
54
+ async function cleanPersistedReaction(api, store, entry) {
55
+ try {
56
+ if (entry.value.accountId !== DEFAULT_ACCOUNT_ID && !resolveDiscordAccountConfig(api.config, entry.value.accountId)) return false;
57
+ const account = resolveDiscordAccount({
58
+ cfg: api.config,
59
+ accountId: entry.value.accountId
60
+ });
61
+ if (!account.enabled || account.tokenStatus !== "available") return false;
62
+ const emoji = entry.value.runningEmoji;
63
+ if (emoji && HISTORICAL_RUNNING_EMOJIS.has(emoji) && !reservedReactionEmojis(api, account.config.ackReaction).has(emoji)) await removeReactionDiscord(entry.value.channelId, entry.value.messageId, emoji, {
64
+ cfg: api.config,
65
+ accountId: entry.value.accountId
66
+ });
67
+ await store.consume(entry.key);
68
+ return true;
69
+ } catch (error) {
70
+ logFailure(api, "startup cleanup", error);
71
+ return false;
72
+ }
73
+ }
74
+ async function recoverDiscordSubagentProgressImpl(api) {
75
+ let store;
76
+ try {
77
+ store = api.runtime.state.openKeyedStore({
78
+ namespace: "subagent-progress",
79
+ maxEntries: MAX_TRACKED_RUNS,
80
+ overflowPolicy: "reject-new",
81
+ defaultTtlMs: PROGRESS_STORE_TTL_MS
82
+ });
83
+ } catch (error) {
84
+ logFailure(api, "state store open", error);
85
+ scheduleRecoveryRetry(api);
86
+ return;
87
+ }
88
+ let entries;
89
+ try {
90
+ entries = await store.entries();
91
+ } catch (error) {
92
+ logFailure(api, "startup recovery list", error);
93
+ scheduleRecoveryRetry(api);
94
+ return;
95
+ }
96
+ let retryNeeded = false;
97
+ for (const entry of entries) if (!await cleanPersistedReaction(api, store, entry)) retryNeeded = true;
98
+ if (retryNeeded) scheduleRecoveryRetry(api);
99
+ else clearRecoveryRetry(api);
100
+ }
101
+ function resetDiscordSubagentProgressForTest() {
102
+ for (const [api, retry] of recoveryRetries) {
103
+ if (retry.timer) clearTimeout(retry.timer);
104
+ recoveryRetries.delete(api);
105
+ }
106
+ }
107
+ const recoverDiscordSubagentProgress = Object.assign(recoverDiscordSubagentProgressImpl, { resetForTest: resetDiscordSubagentProgressForTest });
108
+ //#endregion
109
+ export { recoverDiscordSubagentProgress };
@@ -1,5 +1,5 @@
1
- import { d as discord_exports } from "./chunk-DX4jpFQP.js";
2
- import { x as formatDiscordUserTag } from "./allow-list-DzKrtfah.js";
1
+ import { h as discord_exports } from "./retry-CLpJcXXf.js";
2
+ import { x as formatDiscordUserTag } from "./allow-list-DnxIlPP2.js";
3
3
  //#region extensions/discord/src/monitor/system-events.ts
4
4
  function resolveDiscordSystemEvent(message, location) {
5
5
  switch (message.type) {
@@ -1,6 +1,6 @@
1
- import { Yt as __exportAll, a as allowFromContainsDiscordUserId, l as parseDiscordTarget } from "./chunk-DX4jpFQP.js";
1
+ import { l as allowFromContainsDiscordUserId, p as parseDiscordTarget, tn as __exportAll } from "./retry-CLpJcXXf.js";
2
2
  import { c as resolveDiscordAccountAllowFrom, s as resolveDiscordAccount } from "./accounts-DJTf1LtA.js";
3
- import { a as rememberDiscordDirectoryUser, r as listDiscordDirectoryPeersLive } from "./directory-live-Bw5Ephzv.js";
3
+ import { a as rememberDiscordDirectoryUser, r as listDiscordDirectoryPeersLive } from "./directory-live-DGIGxpIo.js";
4
4
  import { buildMessagingTarget } from "openclaw/plugin-sdk/channel-targets";
5
5
  //#region extensions/discord/src/send-target-parsing.ts
6
6
  const parseDiscordSendTarget = (raw, options = {}) => parseDiscordTarget(raw, options);
@@ -0,0 +1,3 @@
1
+ import "./retry-CLpJcXXf.js";
2
+ import "./target-resolver-maOKSqO0.js";
3
+ export {};
@@ -1,9 +1,8 @@
1
- import { Yt as __exportAll, l as parseDiscordTarget } from "./chunk-DX4jpFQP.js";
2
- import "./targets-Dv_RN7vT.js";
3
- import { C as resolveThreadBindingInactivityExpiresAt, E as saveBindingsToDisk, S as resolveThreadBindingIdleTimeoutMs$1, T as resolveThreadBindingMaxAgeMs$1, h as refreshUnboundThreadWebhookIdentity, k as shouldPersistBindingMutations, m as normalizeThreadId, n as MANAGERS_BY_ACCOUNT_ID, t as BINDINGS_BY_THREAD_ID, u as getThreadBindingToken, v as removeBindingRecord, w as resolveThreadBindingMaxAgeExpiresAt } from "./thread-bindings.state-Cgi5uRn-.js";
4
- import { n as setThreadBindingMaxAgeBySessionKey, r as resolveBindingIdsForTargetSession, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-DAIlp7Px.js";
5
- import { S as resolveThreadBindingThreadName, _ as resolveThreadBindingPersona, s as resolveChannelIdForBinding, v as resolveThreadBindingPersonaFromRecord, x as resolveThreadBindingIntroText, y as formatThreadBindingDurationLabel } from "./thread-bindings.discord-api-BoDNqamb.js";
6
- import { i as testing, n as createThreadBindingManager, r as getThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-DYvSlrva.js";
1
+ import { p as parseDiscordTarget, tn as __exportAll } from "./retry-CLpJcXXf.js";
2
+ import "./targets-yUFTHoAx.js";
3
+ import { C as resolveThreadBindingMaxAgeExpiresAt, O as shouldPersistBindingMutations, S as resolveThreadBindingInactivityExpiresAt, T as saveBindingsToDisk, h as refreshUnboundThreadWebhookIdentity, m as normalizeThreadId, n as MANAGERS_BY_ACCOUNT_ID, t as BINDINGS_BY_THREAD_ID, u as getThreadBindingToken, v as removeBindingRecord, w as resolveThreadBindingMaxAgeMs$1, x as resolveThreadBindingIdleTimeoutMs$1 } from "./thread-bindings.state-aeV8HNgV.js";
4
+ import { n as setThreadBindingMaxAgeBySessionKey, r as resolveBindingIdsForTargetSession, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-bJ2KQFY6.js";
5
+ import { _ as resolveThreadBindingThreadName, g as resolveThreadBindingIntroText, h as formatThreadBindingDurationLabel, m as resolveThreadBindingPersonaFromRecord, n as createThreadBindingManager, o as resolveChannelIdForBinding, p as resolveThreadBindingPersona, r as getThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-DCIH6WDC.js";
7
6
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
8
7
  import { normalizeOptionalLowercaseString, normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
9
8
  import { resolveThreadBindingIdleTimeoutMs, resolveThreadBindingMaxAgeMs, resolveThreadBindingsEnabled } from "openclaw/plugin-sdk/conversation-runtime";
@@ -230,7 +229,6 @@ var thread_bindings_exports = /* @__PURE__ */ __exportAll({
230
229
  resolveThreadBindingsEnabled: () => resolveThreadBindingsEnabled,
231
230
  setThreadBindingIdleTimeoutBySessionKey: () => setThreadBindingIdleTimeoutBySessionKey,
232
231
  setThreadBindingMaxAgeBySessionKey: () => setThreadBindingMaxAgeBySessionKey,
233
- testing: () => testing,
234
232
  unbindThreadBindingsBySessionKey: () => unbindThreadBindingsBySessionKey
235
233
  });
236
234
  //#endregion