@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
@@ -0,0 +1,456 @@
1
+ import { St as editChannel, Tt as getChannelMessage, en as __exportAll, p as discord_exports, yt as createThread } from "./retry-DNsVTeTo.js";
2
+ import { d as resolveDiscordChannelParentSafe, l as resolveDiscordChannelNameSafe, s as resolveDiscordChannelIdSafe, u as resolveDiscordChannelParentIdSafe } from "./thread-bindings.manager-CngsgErq.js";
3
+ import { a as formatDiscordMediaText, f as resolveDiscordChannelInfo, n as resolveDiscordForwardedMessagesTextFromSnapshots, p as resolveDiscordMessageChannelId, t as resolveDiscordEmbedText } from "./message-utils-BXLLnFl6.js";
4
+ import { buildAgentSessionKey } from "openclaw/plugin-sdk/routing";
5
+ import { normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
6
+ import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
7
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
8
+ import { createReplyReferencePlanner } from "openclaw/plugin-sdk/reply-reference";
9
+ import { resolveChannelModelOverride } from "openclaw/plugin-sdk/model-session-runtime";
10
+ import { generateConversationLabel } from "openclaw/plugin-sdk/reply-dispatch-runtime";
11
+ //#region extensions/discord/src/monitor/thread-title.ts
12
+ const DEFAULT_THREAD_TITLE_TIMEOUT_MS = 6e4;
13
+ const MAX_THREAD_TITLE_SOURCE_CHARS = 600;
14
+ const MAX_THREAD_TITLE_CHANNEL_NAME_CHARS = 120;
15
+ const MAX_THREAD_TITLE_CHANNEL_DESCRIPTION_CHARS = 320;
16
+ const DISCORD_THREAD_TITLE_SYSTEM_PROMPT = "Generate a concise Discord thread title (3-6 words) in sentence case: capitalize only the first word and words that are always capitalized. Return only the title. Use channel context when provided and avoid redundant channel-name words unless needed for clarity.";
17
+ async function generateThreadTitle(params) {
18
+ const sourceText = params.messageText.trim();
19
+ if (!sourceText) return null;
20
+ try {
21
+ const userMessage = buildThreadTitleCompletionUserMessage({
22
+ sourceText,
23
+ channelName: params.channelName,
24
+ channelDescription: params.channelDescription
25
+ });
26
+ const timeoutMs = resolveThreadTitleTimeoutMs(params.timeoutMs);
27
+ const generated = await generateConversationLabel({
28
+ cfg: params.cfg,
29
+ agentId: params.agentId,
30
+ userMessage,
31
+ prompt: DISCORD_THREAD_TITLE_SYSTEM_PROMPT,
32
+ ...params.modelRef ? { modelRef: params.modelRef } : {},
33
+ timeoutMs,
34
+ maxLength: MAX_THREAD_TITLE_SOURCE_CHARS
35
+ });
36
+ return generated ? normalizeGeneratedThreadTitle(generated) : null;
37
+ } catch (err) {
38
+ logVerbose(`thread-title: title generation failed for agent ${params.agentId}: ${String(err)}`);
39
+ return null;
40
+ }
41
+ }
42
+ function buildThreadTitleCompletionUserMessage(params) {
43
+ const sourceText = truncateThreadTitleSourceText(params.sourceText);
44
+ const channelName = normalizeTitleContextField(params.channelName, MAX_THREAD_TITLE_CHANNEL_NAME_CHARS);
45
+ const channelDescription = normalizeTitleContextField(params.channelDescription, MAX_THREAD_TITLE_CHANNEL_DESCRIPTION_CHARS);
46
+ const messageLines = [];
47
+ if (channelName) messageLines.push(`Channel: ${channelName}`);
48
+ if (channelDescription) messageLines.push(`Channel description: ${channelDescription}`);
49
+ messageLines.push(`Message:\n${sourceText}`);
50
+ return messageLines.join("\n\n");
51
+ }
52
+ function truncateThreadTitleSourceText(sourceText) {
53
+ if (sourceText.length <= MAX_THREAD_TITLE_SOURCE_CHARS) return sourceText;
54
+ return `${truncateUtf16Safe(sourceText, MAX_THREAD_TITLE_SOURCE_CHARS)}...`;
55
+ }
56
+ function resolveThreadTitleTimeoutMs(timeoutMs) {
57
+ return Math.max(100, Math.floor(timeoutMs ?? DEFAULT_THREAD_TITLE_TIMEOUT_MS));
58
+ }
59
+ function normalizeGeneratedThreadTitle(raw) {
60
+ const lines = raw.replace(/\r/g, "").split("\n");
61
+ let firstLine = "";
62
+ for (const line of lines) {
63
+ const trimmed = line.trim();
64
+ if (!trimmed) continue;
65
+ if (!firstLine && trimmed.startsWith("```")) continue;
66
+ firstLine = trimmed;
67
+ break;
68
+ }
69
+ return stripThreadTitleWrappers(firstLine);
70
+ }
71
+ function stripThreadTitleWrappers(raw) {
72
+ let current = raw.trim();
73
+ let previous = "";
74
+ while (current && current !== previous) {
75
+ previous = current;
76
+ current = current.replace(/^["'`]+|["'`]+$/g, "").trim();
77
+ current = stripBalancedWrapper(current, "**");
78
+ current = stripBalancedWrapper(current, "__");
79
+ current = stripBalancedWrapper(current, "*");
80
+ current = stripBalancedWrapper(current, "_");
81
+ current = stripBalancedWrapper(current, "~~");
82
+ }
83
+ return current;
84
+ }
85
+ function stripBalancedWrapper(text, marker) {
86
+ if (text.length < marker.length * 2 + 1) return text;
87
+ if (!text.startsWith(marker) || !text.endsWith(marker)) return text;
88
+ const inner = text.slice(marker.length, text.length - marker.length);
89
+ if (!inner || inner.includes(marker)) return text;
90
+ return inner;
91
+ }
92
+ function normalizeTitleContextField(raw, maxChars) {
93
+ const value = raw?.trim();
94
+ if (!value) return;
95
+ const singleLine = value.replace(/\s+/g, " ");
96
+ if (singleLine.length <= maxChars) return singleLine;
97
+ return `${truncateUtf16Safe(singleLine, maxChars)}...`;
98
+ }
99
+ //#endregion
100
+ //#region extensions/discord/src/monitor/threading.cache.ts
101
+ const DISCORD_THREAD_STARTER_CACHE_TTL_MS = 300 * 1e3;
102
+ const DISCORD_THREAD_STARTER_CACHE_MAX = 500;
103
+ const DISCORD_THREAD_STARTER_CACHE = /* @__PURE__ */ new Map();
104
+ function getCachedThreadStarter(key, now) {
105
+ const entry = DISCORD_THREAD_STARTER_CACHE.get(key);
106
+ if (!entry) return;
107
+ if (now - entry.updatedAt > DISCORD_THREAD_STARTER_CACHE_TTL_MS) {
108
+ DISCORD_THREAD_STARTER_CACHE.delete(key);
109
+ return;
110
+ }
111
+ DISCORD_THREAD_STARTER_CACHE.delete(key);
112
+ DISCORD_THREAD_STARTER_CACHE.set(key, {
113
+ ...entry,
114
+ updatedAt: now
115
+ });
116
+ return entry.value;
117
+ }
118
+ function setCachedThreadStarter(key, value, now) {
119
+ DISCORD_THREAD_STARTER_CACHE.delete(key);
120
+ DISCORD_THREAD_STARTER_CACHE.set(key, {
121
+ value,
122
+ updatedAt: now
123
+ });
124
+ while (DISCORD_THREAD_STARTER_CACHE.size > DISCORD_THREAD_STARTER_CACHE_MAX) {
125
+ const iter = DISCORD_THREAD_STARTER_CACHE.keys().next();
126
+ if (iter.done) break;
127
+ DISCORD_THREAD_STARTER_CACHE.delete(iter.value);
128
+ }
129
+ }
130
+ //#endregion
131
+ //#region extensions/discord/src/monitor/threading.starter.ts
132
+ function isDiscordThreadType(type) {
133
+ return type === discord_exports.ChannelType.PublicThread || type === discord_exports.ChannelType.PrivateThread || type === discord_exports.ChannelType.AnnouncementThread;
134
+ }
135
+ function isDiscordForumParentType(parentType) {
136
+ return parentType === discord_exports.ChannelType.GuildForum || parentType === discord_exports.ChannelType.GuildMedia;
137
+ }
138
+ function resolveDiscordThreadChannel(params) {
139
+ if (!params.isGuildMessage) return null;
140
+ const { message, channelInfo } = params;
141
+ const channel = "channel" in message ? message.channel : void 0;
142
+ if (channel && typeof channel === "object" && "isThread" in channel && typeof channel.isThread === "function" && channel.isThread()) return channel;
143
+ if (!isDiscordThreadType(channelInfo?.type)) return null;
144
+ const messageChannelId = params.messageChannelId || resolveDiscordMessageChannelId({ message });
145
+ if (!messageChannelId) return null;
146
+ return {
147
+ id: messageChannelId,
148
+ name: channelInfo?.name ?? void 0,
149
+ parentId: channelInfo?.parentId ?? void 0,
150
+ parent: void 0,
151
+ ownerId: channelInfo?.ownerId ?? void 0
152
+ };
153
+ }
154
+ async function resolveDiscordThreadParentInfo(params) {
155
+ const { threadChannel, channelInfo, client } = params;
156
+ const parent = resolveDiscordChannelParentSafe(threadChannel);
157
+ let parentId = resolveDiscordChannelParentIdSafe(threadChannel) ?? resolveDiscordChannelIdSafe(parent) ?? channelInfo?.parentId ?? void 0;
158
+ if (!parentId && threadChannel.id) parentId = (await resolveDiscordChannelInfo(client, threadChannel.id))?.parentId ?? void 0;
159
+ if (!parentId) return {};
160
+ let parentName = resolveDiscordChannelNameSafe(parent);
161
+ const parentInfo = await resolveDiscordChannelInfo(client, parentId);
162
+ parentName = parentName ?? parentInfo?.name;
163
+ const parentType = parentInfo?.type;
164
+ return {
165
+ id: parentId,
166
+ name: parentName,
167
+ type: parentType
168
+ };
169
+ }
170
+ async function resolveDiscordThreadStarter(params) {
171
+ const cacheKey = params.channel.id;
172
+ const cached = getCachedThreadStarter(cacheKey, Date.now());
173
+ if (cached) return cached;
174
+ try {
175
+ const messageChannelId = resolveDiscordThreadStarterMessageChannelId(params);
176
+ if (!messageChannelId) return null;
177
+ const starter = await fetchDiscordThreadStarterMessage({
178
+ client: params.client,
179
+ messageChannelId,
180
+ threadId: params.channel.id
181
+ });
182
+ if (!starter) return null;
183
+ const payload = buildDiscordThreadStarterPayload({
184
+ starter,
185
+ resolveTimestampMs: params.resolveTimestampMs
186
+ });
187
+ if (!payload) return null;
188
+ setCachedThreadStarter(cacheKey, payload, Date.now());
189
+ return payload;
190
+ } catch {
191
+ return null;
192
+ }
193
+ }
194
+ function resolveDiscordThreadStarterMessageChannelId(params) {
195
+ return isDiscordForumParentType(params.parentType) ? params.channel.id : params.parentId;
196
+ }
197
+ async function fetchDiscordThreadStarterMessage(params) {
198
+ const starter = await getChannelMessage(params.client.rest, params.messageChannelId, params.threadId);
199
+ return starter ? starter : null;
200
+ }
201
+ function buildDiscordThreadStarterPayload(params) {
202
+ const text = resolveDiscordThreadStarterText(params.starter);
203
+ if (!text) return null;
204
+ return {
205
+ text,
206
+ ...resolveDiscordThreadStarterIdentity(params.starter),
207
+ timestamp: params.resolveTimestampMs(params.starter.timestamp) ?? void 0
208
+ };
209
+ }
210
+ function resolveDiscordThreadStarterText(starter) {
211
+ const content = normalizeOptionalString(starter.content) ?? "";
212
+ const embedText = resolveDiscordEmbedText(starter.embeds);
213
+ const forwardedText = resolveDiscordForwardedMessagesTextFromSnapshots(starter.message_snapshots);
214
+ return [content || embedText || forwardedText, formatDiscordMediaText({
215
+ attachments: starter.attachments ?? void 0,
216
+ stickers: starter.sticker_items ?? void 0
217
+ })].filter(Boolean).join("\n");
218
+ }
219
+ function resolveDiscordThreadStarterIdentity(starter) {
220
+ return {
221
+ author: resolveDiscordThreadStarterAuthor(starter),
222
+ authorId: starter.author?.id ?? void 0,
223
+ authorName: starter.author?.username ?? void 0,
224
+ authorTag: resolveDiscordThreadStarterAuthorTag(starter.author),
225
+ memberRoleIds: resolveDiscordThreadStarterRoleIds(starter.member)
226
+ };
227
+ }
228
+ function resolveDiscordThreadStarterAuthor(starter) {
229
+ return starter.member?.nick ?? starter.member?.displayName ?? resolveDiscordThreadStarterAuthorTag(starter.author) ?? starter.author?.username ?? starter.author?.id ?? "Unknown";
230
+ }
231
+ function resolveDiscordThreadStarterAuthorTag(author) {
232
+ if (!author?.username || !author.discriminator) return;
233
+ if (author.discriminator !== "0") return `${author.username}#${author.discriminator}`;
234
+ return author.username;
235
+ }
236
+ function resolveDiscordThreadStarterRoleIds(member) {
237
+ return Array.isArray(member?.roles) ? member.roles : void 0;
238
+ }
239
+ function resolveDiscordReplyTarget(opts) {
240
+ if (opts.replyToMode === "off") return;
241
+ const replyToId = normalizeOptionalString(opts.replyToId);
242
+ if (!replyToId) return;
243
+ if (opts.replyToMode === "all") return replyToId;
244
+ return opts.hasReplied ? void 0 : replyToId;
245
+ }
246
+ function sanitizeDiscordThreadName(rawName, fallbackId) {
247
+ return truncateUtf16Safe(truncateUtf16Safe(rawName.replace(/<@!?\d+>/g, "").replace(/<@&\d+>/g, "").replace(/<#\d+>/g, "").replace(/\s+/g, " ").trim() || `Thread ${fallbackId}`, 80), 100) || `Thread ${fallbackId}`;
248
+ }
249
+ function resolveDiscordReplyDeliveryPlan(params) {
250
+ const originalReplyTarget = params.replyTarget;
251
+ let deliverTarget = originalReplyTarget;
252
+ let replyTarget = originalReplyTarget;
253
+ if (params.createdThreadId) {
254
+ deliverTarget = `channel:${params.createdThreadId}`;
255
+ replyTarget = deliverTarget;
256
+ }
257
+ const allowReference = deliverTarget === originalReplyTarget;
258
+ const replyReference = createReplyReferencePlanner({
259
+ replyToMode: allowReference ? params.replyToMode : "off",
260
+ existingId: params.threadChannel ? params.messageId : void 0,
261
+ startId: params.messageId,
262
+ allowReference
263
+ });
264
+ return {
265
+ deliverTarget,
266
+ replyTarget,
267
+ replyReference
268
+ };
269
+ }
270
+ //#endregion
271
+ //#region extensions/discord/src/monitor/threading.auto-thread.ts
272
+ function resolveTrimmedDiscordMessageChannelId(params) {
273
+ return (params.messageChannelId || resolveDiscordMessageChannelId({ message: params.message })).trim();
274
+ }
275
+ function resolveDiscordAutoThreadContext(params) {
276
+ const createdThreadId = normalizeOptionalStringifiedId(params.createdThreadId) ?? "";
277
+ if (!createdThreadId) return null;
278
+ const parentSessionKey = normalizeOptionalString(params.parentSessionKey) ?? "";
279
+ if (!parentSessionKey) return null;
280
+ const threadSessionKey = params.groupScope === "main" ? parentSessionKey : buildAgentSessionKey({
281
+ agentId: params.agentId,
282
+ channel: params.channel,
283
+ peer: {
284
+ kind: "channel",
285
+ id: createdThreadId
286
+ }
287
+ });
288
+ const inheritsDistinctParent = threadSessionKey !== parentSessionKey;
289
+ return {
290
+ createdThreadId,
291
+ From: `${params.channel}:channel:${createdThreadId}`,
292
+ To: `channel:${createdThreadId}`,
293
+ OriginatingTo: `channel:${createdThreadId}`,
294
+ SessionKey: threadSessionKey,
295
+ ...inheritsDistinctParent ? { ModelParentSessionKey: parentSessionKey } : {},
296
+ ...inheritsDistinctParent && params.parentInheritanceEnabled === true ? { ParentSessionKey: parentSessionKey } : {}
297
+ };
298
+ }
299
+ async function resolveDiscordAutoThreadReplyPlan(params) {
300
+ const messageChannelId = resolveTrimmedDiscordMessageChannelId(params);
301
+ const originalReplyTarget = `channel:${params.threadChannel?.id ?? (messageChannelId || "unknown")}`;
302
+ const createdThreadId = await maybeCreateDiscordAutoThread({
303
+ client: params.client,
304
+ message: params.message,
305
+ messageChannelId: messageChannelId || void 0,
306
+ channel: params.channel,
307
+ isGuildMessage: params.isGuildMessage,
308
+ channelConfig: params.channelConfig,
309
+ threadChannel: params.threadChannel,
310
+ channelType: params.channelType,
311
+ channelName: params.channelName,
312
+ channelDescription: params.channelDescription,
313
+ baseText: params.baseText,
314
+ combinedBody: params.combinedBody,
315
+ cfg: params.cfg,
316
+ agentId: params.agentId
317
+ });
318
+ const deliveryPlan = resolveDiscordReplyDeliveryPlan({
319
+ replyTarget: originalReplyTarget,
320
+ replyToMode: params.replyToMode,
321
+ messageId: params.message.id,
322
+ threadChannel: params.threadChannel,
323
+ createdThreadId
324
+ });
325
+ const autoThreadContext = params.isGuildMessage ? resolveDiscordAutoThreadContext({
326
+ agentId: params.agentId,
327
+ channel: params.channel,
328
+ parentSessionKey: params.parentSessionKey,
329
+ createdThreadId,
330
+ groupScope: params.groupScope,
331
+ parentInheritanceEnabled: params.threadParentInheritanceEnabled
332
+ }) : null;
333
+ return {
334
+ ...deliveryPlan,
335
+ createdThreadId,
336
+ autoThreadContext
337
+ };
338
+ }
339
+ async function maybeCreateDiscordAutoThread(params) {
340
+ if (!params.isGuildMessage) return;
341
+ if (!params.channelConfig?.autoThread) return;
342
+ if (params.threadChannel) return;
343
+ if (params.channelType === discord_exports.ChannelType.GuildForum || params.channelType === discord_exports.ChannelType.GuildMedia || params.channelType === discord_exports.ChannelType.GuildVoice || params.channelType === discord_exports.ChannelType.GuildStageVoice) return;
344
+ const messageChannelId = resolveTrimmedDiscordMessageChannelId(params);
345
+ if (!messageChannelId) return;
346
+ try {
347
+ try {
348
+ const existingThreadId = (await getChannelMessage(params.client.rest, messageChannelId, params.message.id))?.thread?.id;
349
+ if (existingThreadId) {
350
+ logVerbose(`discord: autoThread reusing existing thread ${existingThreadId} on ${messageChannelId}/${params.message.id}`);
351
+ return existingThreadId;
352
+ }
353
+ } catch {}
354
+ if (params.message.author?.bot) {
355
+ logVerbose(`discord: autoThread skipped for bot-authored message ${messageChannelId}/${params.message.id}`);
356
+ return;
357
+ }
358
+ const rawThreadSource = params.baseText || params.combinedBody || "Thread";
359
+ const threadName = sanitizeDiscordThreadName(rawThreadSource, params.message.id);
360
+ const archiveDuration = params.channelConfig?.autoArchiveDuration ? Number(params.channelConfig.autoArchiveDuration) : 60;
361
+ const createdId = (await createThread(params.client.rest, messageChannelId, { body: {
362
+ name: threadName,
363
+ auto_archive_duration: archiveDuration
364
+ } }, params.message.id))?.id || "";
365
+ if (createdId && params.channelConfig?.autoThreadName === "generated" && params.cfg && params.agentId) {
366
+ const modelRef = resolveDiscordThreadTitleModelRef({
367
+ cfg: params.cfg,
368
+ channel: params.channel,
369
+ agentId: params.agentId,
370
+ threadId: createdId,
371
+ messageChannelId,
372
+ channelName: params.channelName
373
+ });
374
+ maybeRenameDiscordAutoThread({
375
+ client: params.client,
376
+ threadId: createdId,
377
+ currentName: threadName,
378
+ fallbackId: params.message.id,
379
+ sourceText: rawThreadSource,
380
+ modelRef,
381
+ channelName: params.channelName,
382
+ channelDescription: params.channelDescription,
383
+ cfg: params.cfg,
384
+ agentId: params.agentId
385
+ });
386
+ }
387
+ return createdId || void 0;
388
+ } catch (err) {
389
+ logVerbose(`discord: autoThread creation failed for ${messageChannelId}/${params.message.id}: ${String(err)}`);
390
+ try {
391
+ const existingThreadId = (await getChannelMessage(params.client.rest, messageChannelId, params.message.id))?.thread?.id || "";
392
+ if (existingThreadId) {
393
+ logVerbose(`discord: autoThread reusing existing thread ${existingThreadId} on ${messageChannelId}/${params.message.id}`);
394
+ return existingThreadId;
395
+ }
396
+ } catch {}
397
+ return;
398
+ }
399
+ }
400
+ function resolveDiscordThreadTitleModelRef(params) {
401
+ const channel = params.channel?.trim();
402
+ if (!channel) return;
403
+ const parentSessionKey = buildAgentSessionKey({
404
+ agentId: params.agentId,
405
+ channel,
406
+ peer: {
407
+ kind: "channel",
408
+ id: params.messageChannelId
409
+ }
410
+ });
411
+ const channelLabel = params.channelName?.trim();
412
+ const groupChannel = channelLabel ? `#${channelLabel}` : void 0;
413
+ return resolveChannelModelOverride({
414
+ cfg: params.cfg,
415
+ channel,
416
+ groupId: params.threadId,
417
+ groupChatType: "channel",
418
+ groupChannel,
419
+ groupSubject: groupChannel,
420
+ parentSessionKey
421
+ })?.model;
422
+ }
423
+ async function maybeRenameDiscordAutoThread(params) {
424
+ try {
425
+ const fallbackName = sanitizeDiscordThreadName("", params.fallbackId);
426
+ const generated = await generateThreadTitle({
427
+ cfg: params.cfg,
428
+ agentId: params.agentId,
429
+ messageText: params.sourceText,
430
+ modelRef: params.modelRef,
431
+ channelName: params.channelName,
432
+ channelDescription: params.channelDescription
433
+ });
434
+ if (!generated) return;
435
+ const nextName = sanitizeDiscordThreadName(generated, params.fallbackId);
436
+ if (!nextName || nextName === params.currentName || nextName === fallbackName) return;
437
+ await editChannel(params.client.rest, params.threadId, { body: { name: nextName } });
438
+ } catch (err) {
439
+ logVerbose(`discord: autoThread rename failed for ${params.threadId}: ${String(err)}`);
440
+ }
441
+ }
442
+ //#endregion
443
+ //#region extensions/discord/src/monitor/threading.ts
444
+ var threading_exports = /* @__PURE__ */ __exportAll({
445
+ maybeCreateDiscordAutoThread: () => maybeCreateDiscordAutoThread,
446
+ resolveDiscordAutoThreadContext: () => resolveDiscordAutoThreadContext,
447
+ resolveDiscordAutoThreadReplyPlan: () => resolveDiscordAutoThreadReplyPlan,
448
+ resolveDiscordReplyDeliveryPlan: () => resolveDiscordReplyDeliveryPlan,
449
+ resolveDiscordReplyTarget: () => resolveDiscordReplyTarget,
450
+ resolveDiscordThreadChannel: () => resolveDiscordThreadChannel,
451
+ resolveDiscordThreadParentInfo: () => resolveDiscordThreadParentInfo,
452
+ resolveDiscordThreadStarter: () => resolveDiscordThreadStarter,
453
+ sanitizeDiscordThreadName: () => sanitizeDiscordThreadName
454
+ });
455
+ //#endregion
456
+ export { resolveDiscordThreadStarter as a, resolveDiscordThreadParentInfo as i, resolveDiscordAutoThreadReplyPlan as n, sanitizeDiscordThreadName as o, resolveDiscordReplyTarget as r, threading_exports as t };