@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,13 +1,251 @@
1
- import { Yt as __exportAll, u as resolveDiscordChannelId, yt as getChannel } from "./chunk-DX4jpFQP.js";
2
- import { F as createDiscordRestClient } from "./send.shared-jpvAG_u6.js";
3
- import { C as resolveThreadBindingInactivityExpiresAt, D as setBindingRecord, E as saveBindingsToDisk, O as shouldDefaultPersist, S as resolveThreadBindingIdleTimeoutMs$1, T as resolveThreadBindingMaxAgeMs$1, _ as rememberThreadBindingToken, b as resolveBindingIdsForSession, c as ensureBindingsLoaded, f as normalizeTargetKind, h as refreshUnboundThreadWebhookIdentity, l as forgetThreadBindingToken, m as normalizeThreadId, n as MANAGERS_BY_ACCOUNT_ID, p as normalizeThreadBindingDurationMs, 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 removeBindingRecord, w as resolveThreadBindingMaxAgeExpiresAt, x as resolveBindingRecordKey, y as resetThreadBindingsForTests } from "./thread-bindings.state-Cgi5uRn-.js";
4
- import { S as resolveThreadBindingThreadName, a as isThreadArchived, b as resolveThreadBindingFarewellText, c as summarizeDiscordError, i as isDiscordThreadGoneError, l as DEFAULT_THREAD_BINDING_IDLE_TIMEOUT_MS, n as createWebhookForChannel, o as maybeSendBindingMessage, r as findReusableWebhook, s as resolveChannelIdForBinding, t as createThreadForBinding, u as THREAD_BINDINGS_SWEEP_INTERVAL_MS } from "./thread-bindings.discord-api-BoDNqamb.js";
5
- import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
1
+ import { Tt as getChannel, m as resolveDiscordChannelId, pt as createChannelWebhook, tn as __exportAll } from "./retry-CLpJcXXf.js";
2
+ import { F as createDiscordRestClient } from "./send.shared-BmwFjW6T.js";
3
+ import { t as sendMessageDiscord } from "./send.outbound-DS5tHwfR.js";
4
+ import { i as sendWebhookMessageDiscord, o as createThreadDiscord } from "./send-B7Q6Oc1I.js";
5
+ import { A as toReusableWebhookKey, C as resolveThreadBindingMaxAgeExpiresAt, D as shouldDefaultPersist, E as setBindingRecord, S as resolveThreadBindingInactivityExpiresAt, T as saveBindingsToDisk, _ as rememberThreadBindingToken, b as resolveBindingRecordKey, c as ensureBindingsLoaded, f as normalizeTargetKind, g as rememberReusableWebhook, h as refreshUnboundThreadWebhookIdentity, i as REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL, l as forgetThreadBindingToken, m as normalizeThreadId, n as MANAGERS_BY_ACCOUNT_ID, p as normalizeThreadBindingDurationMs, 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 removeBindingRecord, w as resolveThreadBindingMaxAgeMs$1, x as resolveThreadBindingIdleTimeoutMs$1, y as resolveBindingIdsForSession } from "./thread-bindings.state-aeV8HNgV.js";
6
+ import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
6
7
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
7
8
  import { getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
9
+ import { ChannelType } from "discord-api-types/v10";
10
+ import { parseStrictNonNegativeInteger as parseStrictNonNegativeInteger$1 } from "openclaw/plugin-sdk/number-runtime";
8
11
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
9
- import { registerSessionBindingAdapter, resolveThreadBindingConversationIdFromBindingId, unregisterSessionBindingAdapter } from "openclaw/plugin-sdk/conversation-runtime";
10
- import { resolveDefaultAgentId } from "openclaw/plugin-sdk/agent-runtime";
12
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
13
+ import { SYSTEM_MARK } from "openclaw/plugin-sdk/text-chunking";
14
+ import { formatThreadBindingDurationLabel, registerSessionBindingAdapter, resolveThreadBindingConversationIdFromBindingId, resolveThreadBindingFarewellText, resolveThreadBindingIntroText, resolveThreadBindingThreadName, unregisterSessionBindingAdapter } from "openclaw/plugin-sdk/conversation-runtime";
15
+ import { resolveSessionAgentId } from "openclaw/plugin-sdk/agent-scope-runtime";
16
+ //#region extensions/discord/src/monitor/thread-bindings.persona.ts
17
+ const THREAD_BINDING_PERSONA_MAX_CHARS = 80;
18
+ function normalizePersonaLabel(value) {
19
+ if (!value) return;
20
+ return value.replace(/\s+/g, " ").trim() || void 0;
21
+ }
22
+ function resolveThreadBindingPersona(params) {
23
+ return truncateUtf16Safe(`${SYSTEM_MARK} ${normalizePersonaLabel(params.label) || normalizePersonaLabel(params.agentId) || "agent"}`, THREAD_BINDING_PERSONA_MAX_CHARS);
24
+ }
25
+ function resolveThreadBindingPersonaFromRecord(record) {
26
+ return resolveThreadBindingPersona({
27
+ label: record.label,
28
+ agentId: record.agentId
29
+ });
30
+ }
31
+ //#endregion
32
+ //#region extensions/discord/src/monitor/channel-access.ts
33
+ function readDiscordChannelPropertySafe(channel, key) {
34
+ if (!channel || typeof channel !== "object") return;
35
+ try {
36
+ if (!(key in channel)) return;
37
+ return channel[key];
38
+ } catch {
39
+ return;
40
+ }
41
+ }
42
+ function resolveDiscordChannelStringPropertySafe(channel, key) {
43
+ const value = readDiscordChannelPropertySafe(channel, key);
44
+ return typeof value === "string" ? value : void 0;
45
+ }
46
+ function resolveDiscordChannelNumberPropertySafe(channel, key) {
47
+ const value = readDiscordChannelPropertySafe(channel, key);
48
+ return typeof value === "number" ? value : void 0;
49
+ }
50
+ const DISCORD_CHANNEL_SNAKE_CASE_ALIASES = {
51
+ ownerId: "owner_id",
52
+ parentId: "parent_id"
53
+ };
54
+ function resolveDiscordChannelStringWithAliasSafe(channel, camelKey) {
55
+ const camelValue = resolveDiscordChannelStringPropertySafe(channel, camelKey);
56
+ if (camelValue !== void 0) return camelValue;
57
+ const snakeKey = DISCORD_CHANNEL_SNAKE_CASE_ALIASES[camelKey];
58
+ if (!snakeKey) return;
59
+ const directSnakeValue = resolveDiscordChannelStringPropertySafe(channel, snakeKey);
60
+ if (directSnakeValue !== void 0) return directSnakeValue;
61
+ return resolveDiscordChannelStringPropertySafe(readDiscordChannelPropertySafe(channel, "rawData"), snakeKey);
62
+ }
63
+ function resolveDiscordChannelNameSafe(channel) {
64
+ return resolveDiscordChannelStringPropertySafe(channel, "name");
65
+ }
66
+ function resolveDiscordChannelIdSafe(channel) {
67
+ return resolveDiscordChannelStringPropertySafe(channel, "id");
68
+ }
69
+ function resolveDiscordChannelTopicSafe(channel) {
70
+ return resolveDiscordChannelStringPropertySafe(channel, "topic");
71
+ }
72
+ function resolveDiscordChannelParentIdSafe(channel) {
73
+ return resolveDiscordChannelStringWithAliasSafe(channel, "parentId");
74
+ }
75
+ function resolveDiscordChannelOwnerIdSafe(channel) {
76
+ return resolveDiscordChannelStringWithAliasSafe(channel, "ownerId");
77
+ }
78
+ function resolveDiscordChannelParentSafe(channel) {
79
+ return readDiscordChannelPropertySafe(channel, "parent");
80
+ }
81
+ function resolveDiscordChannelInfoSafe(channel) {
82
+ const parent = resolveDiscordChannelParentSafe(channel);
83
+ return {
84
+ name: resolveDiscordChannelNameSafe(channel),
85
+ topic: resolveDiscordChannelTopicSafe(channel),
86
+ type: resolveDiscordChannelNumberPropertySafe(channel, "type"),
87
+ parentId: resolveDiscordChannelParentIdSafe(channel),
88
+ ownerId: resolveDiscordChannelOwnerIdSafe(channel),
89
+ parentName: resolveDiscordChannelNameSafe(parent)
90
+ };
91
+ }
92
+ //#endregion
93
+ //#region extensions/discord/src/monitor/thread-bindings.types.ts
94
+ const THREAD_BINDINGS_SWEEP_INTERVAL_MS = 12e4;
95
+ const DEFAULT_THREAD_BINDING_IDLE_TIMEOUT_MS = 1440 * 60 * 1e3;
96
+ //#endregion
97
+ //#region extensions/discord/src/monitor/thread-bindings.discord-api.ts
98
+ function buildThreadTarget(threadId) {
99
+ return /^(channel:|user:)/i.test(threadId) ? threadId : `channel:${threadId}`;
100
+ }
101
+ function isThreadArchived(raw) {
102
+ if (!raw || typeof raw !== "object") return false;
103
+ const asRecord = raw;
104
+ if (asRecord.archived === true) return true;
105
+ if (asRecord.thread_metadata?.archived === true) return true;
106
+ if (asRecord.threadMetadata?.archived === true) return true;
107
+ return false;
108
+ }
109
+ function isThreadChannelType(type) {
110
+ return type === ChannelType.PublicThread || type === ChannelType.PrivateThread || type === ChannelType.AnnouncementThread;
111
+ }
112
+ function normalizeDiscordBindingChannelId(raw) {
113
+ const trimmed = normalizeOptionalString(raw) ?? "";
114
+ if (!trimmed) return null;
115
+ try {
116
+ return resolveDiscordChannelId(trimmed);
117
+ } catch {
118
+ return null;
119
+ }
120
+ }
121
+ function summarizeDiscordError(err) {
122
+ if (err instanceof Error) return err.message;
123
+ if (typeof err === "string") return err;
124
+ if (typeof err === "number" || typeof err === "boolean" || typeof err === "bigint" || typeof err === "symbol") return String(err);
125
+ return "error";
126
+ }
127
+ function extractNumericDiscordErrorValue(value) {
128
+ return parseStrictNonNegativeInteger$1(value);
129
+ }
130
+ function extractDiscordErrorStatus(err) {
131
+ if (!err || typeof err !== "object") return;
132
+ const candidate = err;
133
+ return extractNumericDiscordErrorValue(candidate.status) ?? extractNumericDiscordErrorValue(candidate.statusCode) ?? extractNumericDiscordErrorValue(candidate.response?.status);
134
+ }
135
+ function extractDiscordErrorCode(err) {
136
+ if (!err || typeof err !== "object") return;
137
+ const candidate = err;
138
+ return extractNumericDiscordErrorValue(candidate.code) ?? extractNumericDiscordErrorValue(candidate.rawError?.code) ?? extractNumericDiscordErrorValue(candidate.body?.code) ?? extractNumericDiscordErrorValue(candidate.response?.body?.code) ?? extractNumericDiscordErrorValue(candidate.response?.data?.code);
139
+ }
140
+ function isDiscordThreadGoneError(err) {
141
+ if (extractDiscordErrorCode(err) === 10003) return true;
142
+ const status = extractDiscordErrorStatus(err);
143
+ return status === 404 || status === 403;
144
+ }
145
+ async function maybeSendBindingMessage(params) {
146
+ const text = params.text.trim();
147
+ if (!text) return;
148
+ const record = params.record;
149
+ if (params.preferWebhook !== false && record.webhookId && record.webhookToken) try {
150
+ await sendWebhookMessageDiscord(text, {
151
+ cfg: params.cfg,
152
+ webhookId: record.webhookId,
153
+ webhookToken: record.webhookToken,
154
+ accountId: record.accountId,
155
+ threadId: record.threadId,
156
+ username: resolveThreadBindingPersonaFromRecord(record)
157
+ });
158
+ return;
159
+ } catch (err) {
160
+ logVerbose(`discord thread binding webhook send failed: ${summarizeDiscordError(err)}`);
161
+ }
162
+ try {
163
+ await sendMessageDiscord(buildThreadTarget(record.threadId), text, {
164
+ cfg: params.cfg,
165
+ accountId: record.accountId
166
+ });
167
+ } catch (err) {
168
+ logVerbose(`discord thread binding fallback send failed: ${summarizeDiscordError(err)}`);
169
+ }
170
+ }
171
+ async function createWebhookForChannel(params) {
172
+ try {
173
+ const rest = createDiscordRestClient({
174
+ cfg: params.cfg,
175
+ accountId: params.accountId,
176
+ token: params.token
177
+ }).rest;
178
+ const created = await createChannelWebhook(rest, params.channelId, { body: { name: "OpenClaw Agents" } });
179
+ const webhookId = normalizeOptionalString(created?.id) ?? "";
180
+ const webhookToken = normalizeOptionalString(created?.token) ?? "";
181
+ if (!webhookId || !webhookToken) return {};
182
+ return {
183
+ webhookId,
184
+ webhookToken
185
+ };
186
+ } catch (err) {
187
+ logVerbose(`discord thread binding webhook create failed for ${params.channelId}: ${summarizeDiscordError(err)}`);
188
+ return {};
189
+ }
190
+ }
191
+ function findReusableWebhook(params) {
192
+ const reusableKey = toReusableWebhookKey({
193
+ accountId: params.accountId,
194
+ channelId: params.channelId
195
+ });
196
+ const cached = REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL.get(reusableKey);
197
+ if (cached) return {
198
+ webhookId: cached.webhookId,
199
+ webhookToken: cached.webhookToken
200
+ };
201
+ for (const record of BINDINGS_BY_THREAD_ID.values()) {
202
+ if (record.accountId !== params.accountId) continue;
203
+ if (record.channelId !== params.channelId) continue;
204
+ if (!record.webhookId || !record.webhookToken) continue;
205
+ rememberReusableWebhook(record);
206
+ return {
207
+ webhookId: record.webhookId,
208
+ webhookToken: record.webhookToken
209
+ };
210
+ }
211
+ return {};
212
+ }
213
+ async function resolveChannelIdForBinding(params) {
214
+ const explicit = normalizeDiscordBindingChannelId(params.channelId);
215
+ if (explicit) return explicit;
216
+ const lookupThreadId = normalizeDiscordBindingChannelId(params.threadId);
217
+ if (!lookupThreadId) return null;
218
+ try {
219
+ const rest = createDiscordRestClient({
220
+ cfg: params.cfg,
221
+ accountId: params.accountId,
222
+ token: params.token
223
+ }).rest;
224
+ const channel = await getChannel(rest, lookupThreadId);
225
+ const channelInfo = resolveDiscordChannelInfoSafe(channel);
226
+ const channelId = normalizeOptionalString(resolveDiscordChannelIdSafe(channel)) ?? "";
227
+ const type = channelInfo.type;
228
+ const parentId = normalizeOptionalString(channelInfo.parentId) ?? "";
229
+ if (parentId && isThreadChannelType(type)) return parentId;
230
+ return channelId || null;
231
+ } catch (err) {
232
+ logVerbose(`discord thread binding channel resolve failed for ${lookupThreadId}: ${summarizeDiscordError(err)}`);
233
+ return null;
234
+ }
235
+ }
236
+ async function createThreadForBinding(params) {
237
+ try {
238
+ return (normalizeOptionalString((await createThreadDiscord(params.channelId, { name: params.threadName }, {
239
+ cfg: params.cfg,
240
+ accountId: params.accountId,
241
+ token: params.token
242
+ }))?.id) ?? "") || null;
243
+ } catch (err) {
244
+ logVerbose(`discord thread binding auto-thread create failed for ${params.channelId}: ${summarizeDiscordError(err)}`);
245
+ return null;
246
+ }
247
+ }
248
+ //#endregion
11
249
  //#region extensions/discord/src/monitor/thread-bindings.session-adapter.ts
12
250
  function normalizeChildBindingParentChannelId(raw) {
13
251
  const trimmed = normalizeOptionalString(raw) ?? "";
@@ -77,7 +315,7 @@ function toSessionBindingRecord(record, defaults) {
77
315
  };
78
316
  }
79
317
  function createThreadBindingSessionAdapter(params) {
80
- const toRecord = (entry) => toSessionBindingRecord(entry, params.defaults);
318
+ const serializeBinding = (entry) => toSessionBindingRecord(entry, params.defaults);
81
319
  return {
82
320
  channel: "discord",
83
321
  accountId: params.accountId,
@@ -120,13 +358,13 @@ function createThreadBindingSessionAdapter(params) {
120
358
  introText,
121
359
  metadata
122
360
  });
123
- return bound ? toRecord(bound) : null;
361
+ return bound ? serializeBinding(bound) : null;
124
362
  },
125
- listBySession: (targetSessionKey) => params.manager.listBySessionKey(targetSessionKey).map(toRecord),
363
+ listBySession: (targetSessionKey) => params.manager.listBySessionKey(targetSessionKey).map(serializeBinding),
126
364
  resolveByConversation: (ref) => {
127
365
  if (ref.channel !== "discord") return null;
128
366
  const binding = params.manager.getByThreadId(ref.conversationId);
129
- return binding ? toRecord(binding) : null;
367
+ return binding ? serializeBinding(binding) : null;
130
368
  },
131
369
  touch: (bindingId, at) => {
132
370
  const threadId = resolveThreadBindingConversationIdFromBindingId({
@@ -144,7 +382,7 @@ function createThreadBindingSessionAdapter(params) {
144
382
  if (input.targetSessionKey?.trim()) return params.manager.unbindBySessionKey({
145
383
  targetSessionKey: input.targetSessionKey,
146
384
  reason: input.reason
147
- }).map(toRecord);
385
+ }).map(serializeBinding);
148
386
  const threadId = resolveThreadBindingConversationIdFromBindingId({
149
387
  accountId: params.accountId,
150
388
  bindingId: input.bindingId
@@ -154,18 +392,16 @@ function createThreadBindingSessionAdapter(params) {
154
392
  threadId,
155
393
  reason: input.reason
156
394
  });
157
- return removed ? [toRecord(removed)] : [];
395
+ return removed ? [serializeBinding(removed)] : [];
158
396
  }
159
397
  };
160
398
  }
161
399
  //#endregion
162
400
  //#region extensions/discord/src/monitor/thread-bindings.manager.ts
163
401
  var thread_bindings_manager_exports = /* @__PURE__ */ __exportAll({
164
- __testing: () => testing,
165
402
  createNoopThreadBindingManager: () => createNoopThreadBindingManager,
166
403
  createThreadBindingManager: () => createThreadBindingManager,
167
- getThreadBindingManager: () => getThreadBindingManager,
168
- testing: () => testing
404
+ getThreadBindingManager: () => getThreadBindingManager
169
405
  });
170
406
  function registerManager(manager) {
171
407
  MANAGERS_BY_ACCOUNT_ID.set(manager.accountId, manager);
@@ -173,7 +409,6 @@ function registerManager(manager) {
173
409
  function unregisterManager(accountId, manager) {
174
410
  if (MANAGERS_BY_ACCOUNT_ID.get(accountId) === manager) MANAGERS_BY_ACCOUNT_ID.delete(accountId);
175
411
  }
176
- const SWEEPERS_BY_ACCOUNT_ID = /* @__PURE__ */ new Map();
177
412
  function createNoopManager(accountIdRaw) {
178
413
  return {
179
414
  accountId: normalizeAccountId(accountIdRaw),
@@ -297,7 +532,6 @@ function createThreadBindingManager(params) {
297
532
  }
298
533
  }
299
534
  };
300
- SWEEPERS_BY_ACCOUNT_ID.set(accountId, runSweepOnce);
301
535
  const manager = {
302
536
  accountId,
303
537
  getIdleTimeoutMs: () => idleTimeoutMs,
@@ -400,7 +634,10 @@ function createThreadBindingManager(params) {
400
634
  threadId,
401
635
  targetKind,
402
636
  targetSessionKey,
403
- agentId: normalizeOptionalString(bindParams.agentId) ?? normalizeOptionalString(existingValue?.agentId) ?? resolveAgentIdFromSessionKey(targetSessionKey, resolveDefaultAgentId(cfg)),
637
+ agentId: normalizeOptionalString(bindParams.agentId) ?? normalizeOptionalString(existingValue?.agentId) ?? resolveSessionAgentId({
638
+ config: cfg,
639
+ sessionKey: targetSessionKey
640
+ }),
404
641
  label: normalizeOptionalString(bindParams.label) ?? normalizeOptionalString(existingValue?.label),
405
642
  webhookId: webhookId || void 0,
406
643
  webhookToken: webhookToken || void 0,
@@ -485,7 +722,6 @@ function createThreadBindingManager(params) {
485
722
  clearInterval(sweepTimer);
486
723
  sweepTimer = null;
487
724
  }
488
- SWEEPERS_BY_ACCOUNT_ID.delete(accountId);
489
725
  unregisterManager(accountId, manager);
490
726
  unregisterSessionBindingAdapter({
491
727
  channel: "discord",
@@ -522,13 +758,5 @@ function getThreadBindingManager(accountId) {
522
758
  const normalized = normalizeAccountId(accountId);
523
759
  return MANAGERS_BY_ACCOUNT_ID.get(normalized) ?? null;
524
760
  }
525
- const testing = {
526
- resolveThreadBindingThreadName,
527
- resetThreadBindingsForTests,
528
- runThreadBindingSweepForAccount: async (accountId) => {
529
- const sweep = SWEEPERS_BY_ACCOUNT_ID.get(normalizeAccountId(accountId));
530
- if (sweep) await sweep();
531
- }
532
- };
533
761
  //#endregion
534
- export { thread_bindings_manager_exports as a, testing as i, createThreadBindingManager as n, getThreadBindingManager as r, createNoopThreadBindingManager as t };
762
+ export { resolveThreadBindingThreadName as _, isThreadArchived as a, resolveDiscordChannelInfoSafe as c, resolveDiscordChannelParentSafe as d, resolveDiscordChannelTopicSafe as f, resolveThreadBindingIntroText as g, formatThreadBindingDurationLabel as h, thread_bindings_manager_exports as i, resolveDiscordChannelNameSafe as l, resolveThreadBindingPersonaFromRecord as m, createThreadBindingManager as n, resolveChannelIdForBinding as o, resolveThreadBindingPersona as p, getThreadBindingManager as r, resolveDiscordChannelIdSafe as s, createNoopThreadBindingManager as t, resolveDiscordChannelParentIdSafe as u };
@@ -1,4 +1,4 @@
1
- import { D as setBindingRecord, E as saveBindingsToDisk, b as resolveBindingIdsForSession, c as ensureBindingsLoaded, k as shouldPersistBindingMutations, t as BINDINGS_BY_THREAD_ID } from "./thread-bindings.state-Cgi5uRn-.js";
1
+ import { E as setBindingRecord, O as shouldPersistBindingMutations, T as saveBindingsToDisk, c as ensureBindingsLoaded, t as BINDINGS_BY_THREAD_ID, y as resolveBindingIdsForSession } from "./thread-bindings.state-aeV8HNgV.js";
2
2
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
3
3
  //#region extensions/discord/src/monitor/thread-bindings.session-shared.ts
4
4
  function normalizeNonNegativeMs(raw) {
@@ -1,7 +1,7 @@
1
1
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
2
2
  import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
3
3
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
4
- import { recordOutboundMessageIdentity } from "openclaw/plugin-sdk/channel-outbound";
4
+ import { recordOutboundMessageIdentity } from "openclaw/plugin-sdk/outbound-echo-runtime";
5
5
  //#region extensions/discord/src/monitor/thread-bindings.state.ts
6
6
  const THREAD_BINDINGS_STATE_KEY = Symbol.for("openclaw.discordThreadBindingsState");
7
7
  let threadBindingsState;
@@ -284,18 +284,5 @@ function resolveBindingIdsForSession(params) {
284
284
  }
285
285
  return out;
286
286
  }
287
- function resetThreadBindingsForTests() {
288
- for (const manager of MANAGERS_BY_ACCOUNT_ID.values()) manager.stop();
289
- MANAGERS_BY_ACCOUNT_ID.clear();
290
- BINDINGS_BY_THREAD_ID.clear();
291
- BINDINGS_BY_SESSION_KEY.clear();
292
- REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL.clear();
293
- TOKENS_BY_ACCOUNT_ID.clear();
294
- PERSIST_BY_ACCOUNT_ID.clear();
295
- THREAD_BINDINGS_STATE.loadedBindings = false;
296
- THREAD_BINDINGS_STATE.loadedPersistentBindings = false;
297
- THREAD_BINDINGS_STATE.persistenceAvailable = true;
298
- THREAD_BINDINGS_STATE.lastPersistedAtMs = 0;
299
- }
300
287
  //#endregion
301
- export { toBindingRecordKey as A, resolveThreadBindingInactivityExpiresAt as C, setBindingRecord as D, saveBindingsToDisk as E, shouldDefaultPersist as O, resolveThreadBindingIdleTimeoutMs as S, resolveThreadBindingMaxAgeMs as T, rememberThreadBindingToken as _, THREAD_BINDINGS_MAX_ENTRIES as a, resolveBindingIdsForSession as b, ensureBindingsLoaded as c, normalizePersistedBinding as d, normalizeTargetKind as f, rememberReusableWebhook as g, refreshUnboundThreadWebhookIdentity as h, REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL as i, toReusableWebhookKey as j, shouldPersistBindingMutations as k, forgetThreadBindingToken as l, normalizeThreadId as m, MANAGERS_BY_ACCOUNT_ID as n, THREAD_BINDINGS_NAMESPACE as o, normalizeThreadBindingDurationMs as p, PERSIST_BY_ACCOUNT_ID as r, THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS as s, BINDINGS_BY_THREAD_ID as t, getThreadBindingToken as u, removeBindingRecord as v, resolveThreadBindingMaxAgeExpiresAt as w, resolveBindingRecordKey as x, resetThreadBindingsForTests as y };
288
+ export { toReusableWebhookKey as A, resolveThreadBindingMaxAgeExpiresAt as C, shouldDefaultPersist as D, setBindingRecord as E, shouldPersistBindingMutations as O, resolveThreadBindingInactivityExpiresAt as S, saveBindingsToDisk as T, rememberThreadBindingToken as _, THREAD_BINDINGS_MAX_ENTRIES as a, resolveBindingRecordKey as b, ensureBindingsLoaded as c, normalizePersistedBinding as d, normalizeTargetKind as f, rememberReusableWebhook as g, refreshUnboundThreadWebhookIdentity as h, REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL as i, toBindingRecordKey as k, forgetThreadBindingToken as l, normalizeThreadId as m, MANAGERS_BY_ACCOUNT_ID as n, THREAD_BINDINGS_NAMESPACE as o, normalizeThreadBindingDurationMs as p, PERSIST_BY_ACCOUNT_ID as r, THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS as s, BINDINGS_BY_THREAD_ID as t, getThreadBindingToken as u, removeBindingRecord as v, resolveThreadBindingMaxAgeMs as w, resolveThreadBindingIdleTimeoutMs as x, resolveBindingIdsForSession as y };
@@ -1,4 +1,4 @@
1
- import { Yt as __exportAll } from "./chunk-DX4jpFQP.js";
1
+ import { tn as __exportAll } from "./retry-CLpJcXXf.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-DIKGsTGT.js";
1
+ import { t as discordVoiceTranscriptsSourceProvider } from "./transcripts-source-CfFMexGt.js";
2
2
  export { discordVoiceTranscriptsSourceProvider };
@@ -1,4 +1,4 @@
1
- import { Dt as sendChannelTyping, Yt as __exportAll } from "./chunk-DX4jpFQP.js";
1
+ import { Nt as sendChannelTyping, tn as __exportAll } from "./retry-CLpJcXXf.js";
2
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 });