@kodelyth/discord 2026.5.39 → 2026.6.1

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 (126) hide show
  1. package/dist/account-inspect-Dqw-enky.js +81 -0
  2. package/dist/account-inspect-api.js +10 -0
  3. package/dist/accounts-B7OBFePq.js +224 -0
  4. package/dist/action-runtime-api.js +2 -0
  5. package/dist/agent-components.runtime-DVY_1VB4.js +4 -0
  6. package/dist/allow-list-B0s7evD7.js +354 -0
  7. package/dist/api-CXAcv9nZ.js +130 -0
  8. package/dist/api.js +23 -0
  9. package/dist/approval-handler.runtime-B9xUAF3n.js +426 -0
  10. package/dist/audit-DoiK49WO.js +24 -0
  11. package/dist/audit-core-BGrq3G7r.js +105 -0
  12. package/dist/channel-U_aeoFwW.js +795 -0
  13. package/dist/channel-actions-BxEBnEuv.js +173 -0
  14. package/dist/channel-actions.runtime-CPtpH-yl.js +263 -0
  15. package/dist/channel-api-BfjklLby.js +21 -0
  16. package/dist/channel-config-api.js +2 -0
  17. package/dist/channel-plugin-api.js +2 -0
  18. package/dist/channel.setup-BUSC0apv.js +337 -0
  19. package/dist/components-luonoe13.js +909 -0
  20. package/dist/config-api-DSYGqaLQ.js +2 -0
  21. package/dist/config-schema-DIqJBGwC.js +357 -0
  22. package/dist/configured-state.js +6 -0
  23. package/dist/contract-api.js +8 -0
  24. package/dist/conversation-identity-DXAm0_Mk.js +270 -0
  25. package/dist/directory-config-CYbuMmPS.js +49 -0
  26. package/dist/directory-contract-api.js +2 -0
  27. package/dist/directory-live-DX4dLRpJ.js +159 -0
  28. package/dist/doctor-bbKSvGVD.js +244 -0
  29. package/dist/doctor-contract-Btjt6NJD.js +383 -0
  30. package/dist/doctor-contract-api.js +2 -0
  31. package/dist/gateway-registry-BKSpa4GB.js +74 -0
  32. package/dist/handle-action.guild-admin-B5BArS2n.js +286 -0
  33. package/dist/inbound-context-WAOqhGlT.js +48 -0
  34. package/dist/inbound-event-delivery-C-1Ji3WP.js +65 -0
  35. package/dist/index.js +26 -0
  36. package/dist/manager.runtime-DXHynKE4.js +2356 -0
  37. package/dist/message-handler-mXzc3tA_.js +381 -0
  38. package/dist/message-handler.preflight-BPD1a347.js +1113 -0
  39. package/dist/message-handler.process-GUa3aV8z.js +1438 -0
  40. package/dist/message-utils-dUbem16p.js +549 -0
  41. package/dist/outbound-adapter-C18OAc1y.js +536 -0
  42. package/dist/pluralkit-D1Q2x0w5.js +22 -0
  43. package/dist/preflight-audio-CZtpWcIm.js +72 -0
  44. package/dist/preflight-audio.runtime-Brx_0_xW.js +7 -0
  45. package/dist/preview-streaming-D_slNIiO.js +8 -0
  46. package/dist/probe-D--Ca4JF.js +139 -0
  47. package/dist/probe.runtime-DQBchZzv.js +2 -0
  48. package/dist/provider-B2-31CIT.js +9565 -0
  49. package/dist/provider-session.runtime-BwzzSsrH.js +6 -0
  50. package/dist/provider.runtime-CP3oHLls.js +2 -0
  51. package/dist/resolve-allowlist-common-CqxPLcJO.js +34 -0
  52. package/dist/resolve-channels-0LX4pUbB.js +265 -0
  53. package/dist/resolve-users-CztOv0Qs.js +120 -0
  54. package/dist/runtime-DUaw66V_.js +1073 -0
  55. package/dist/runtime-api.actions.js +3 -0
  56. package/dist/runtime-api.js +30 -0
  57. package/dist/runtime-api.lookup.js +7 -0
  58. package/dist/runtime-api.monitor-CvVKvEXW.js +5 -0
  59. package/dist/runtime-api.monitor.js +8 -0
  60. package/dist/runtime-api.send.js +6 -0
  61. package/dist/runtime-api.threads.js +6 -0
  62. package/dist/runtime-fC6f4UF2.js +8 -0
  63. package/dist/runtime-setter-api.js +2 -0
  64. package/dist/secret-config-contract-B6WW5V88.js +115 -0
  65. package/dist/secret-contract-api.js +2 -0
  66. package/dist/security-audit-CnyIQKz6.js +120 -0
  67. package/dist/security-audit-contract-api.js +2 -0
  68. package/dist/security-audit.runtime-CQSkjNLu.js +2 -0
  69. package/dist/security-contract-DLvYOgLM.js +26 -0
  70. package/dist/security-contract-api.js +2 -0
  71. package/dist/security-doctor-DepqtNCI.js +18 -0
  72. package/dist/send-DCtPCHGk.js +881 -0
  73. package/dist/send.components-Bcgxvm52.js +474 -0
  74. package/dist/send.outbound-S9t0UuHc.js +330 -0
  75. package/dist/send.receipt-CDn3GBWC.js +3119 -0
  76. package/dist/send.shared-D4iBnAmn.js +669 -0
  77. package/dist/sender-identity-CxCe3_1a.js +43 -0
  78. package/dist/session-contract-Dwhw3RTY.js +6 -0
  79. package/dist/session-key-api.js +2 -0
  80. package/dist/session-key-normalization-CP8dPUid.js +23 -0
  81. package/dist/setup-entry.js +11 -0
  82. package/dist/setup-plugin-api.js +2 -0
  83. package/dist/shared-AIlvuZXt.js +171 -0
  84. package/dist/subagent-hooks-8bK-mgiU.js +120 -0
  85. package/dist/subagent-hooks-api.js +22 -0
  86. package/dist/system-events-Ba1TklaL.js +34 -0
  87. package/dist/target-resolver-BrtFQtoK.js +82 -0
  88. package/dist/targets-DWLLZE2l.js +3 -0
  89. package/dist/test-api.js +45 -0
  90. package/dist/thread-binding-api.js +4 -0
  91. package/dist/thread-bindings-9aKRmZv0.js +255 -0
  92. package/dist/thread-bindings.discord-api-ssGH5wc2.js +244 -0
  93. package/dist/thread-bindings.manager-0YBHGemk.js +534 -0
  94. package/dist/thread-bindings.session-updates-DJZGIwaU.js +54 -0
  95. package/dist/thread-bindings.state-eTFl-PqJ.js +318 -0
  96. package/dist/timeouts-CEwuGaWT.js +52 -0
  97. package/dist/timeouts.js +2 -0
  98. package/dist/typing-BmJKRpCS.js +14 -0
  99. package/package.json +19 -7
  100. package/account-inspect-api.js +0 -7
  101. package/action-runtime-api.js +0 -7
  102. package/api.js +0 -7
  103. package/channel-config-api.js +0 -7
  104. package/channel-plugin-api.js +0 -7
  105. package/configured-state.js +0 -7
  106. package/contract-api.js +0 -7
  107. package/directory-contract-api.js +0 -7
  108. package/doctor-contract-api.js +0 -7
  109. package/index.js +0 -7
  110. package/runtime-api.actions.js +0 -7
  111. package/runtime-api.js +0 -7
  112. package/runtime-api.lookup.js +0 -7
  113. package/runtime-api.monitor.js +0 -7
  114. package/runtime-api.send.js +0 -7
  115. package/runtime-api.threads.js +0 -7
  116. package/runtime-setter-api.js +0 -7
  117. package/secret-contract-api.js +0 -7
  118. package/security-audit-contract-api.js +0 -7
  119. package/security-contract-api.js +0 -7
  120. package/session-key-api.js +0 -7
  121. package/setup-entry.js +0 -7
  122. package/setup-plugin-api.js +0 -7
  123. package/subagent-hooks-api.js +0 -7
  124. package/test-api.js +0 -7
  125. package/thread-binding-api.js +0 -7
  126. package/timeouts.js +0 -7
@@ -0,0 +1,474 @@
1
+ import { M as serializePayload, Wt as __exportAll, ft as editChannelMessage, n as createDiscordSendResult, st as createChannelMessage } from "./send.receipt-CDn3GBWC.js";
2
+ import { s as resolveDiscordAccount } from "./accounts-B7OBFePq.js";
3
+ import "./config-api-DSYGqaLQ.js";
4
+ import "./channel-api-BfjklLby.js";
5
+ import { c as buildDiscordComponentMessage, f as resolveDiscordComponentAttachmentName, l as buildDiscordComponentMessageFlags } from "./components-luonoe13.js";
6
+ import { M as createDiscordClient, b as stripUndefinedFields, h as SUPPRESS_NOTIFICATIONS_FLAG, j as parseAndResolveRecipient, l as resolveChannelId, m as toDiscordFileBlob, t as buildDiscordSendError, u as resolveDiscordChannelType } from "./send.shared-D4iBnAmn.js";
7
+ import { t as sendMessageDiscord } from "./send.outbound-S9t0UuHc.js";
8
+ import { n as getOptionalDiscordRuntime } from "./runtime-fC6f4UF2.js";
9
+ import "klaw/plugin-sdk/account-id";
10
+ import "klaw/plugin-sdk/secret-input";
11
+ import "klaw/plugin-sdk/account-helpers";
12
+ import "klaw/plugin-sdk/channel-config-helpers";
13
+ import "klaw/plugin-sdk/routing";
14
+ import "klaw/plugin-sdk/channel-status";
15
+ import { assertMediaNotDataUrl, jsonResult, parseAvailableTags, readNumberParam, readReactionParams, readStringArrayParam, readStringParam, resolvePollMaxSelections, withNormalizedTimestamp } from "klaw/plugin-sdk/channel-actions";
16
+ import { readBooleanParam as readBooleanParam$1 } from "klaw/plugin-sdk/boolean-param";
17
+ import "klaw/plugin-sdk/channel-plugin-common";
18
+ import { loadOutboundMediaFromUrl } from "klaw/plugin-sdk/outbound-media";
19
+ import { ChannelType } from "discord-api-types/v10";
20
+ import { requireRuntimeConfig } from "klaw/plugin-sdk/plugin-config-runtime";
21
+ import { recordChannelActivity } from "klaw/plugin-sdk/channel-activity-runtime";
22
+ import { resolveGlobalMap } from "klaw/plugin-sdk/global-singleton";
23
+ //#region extensions/discord/src/components-registry.ts
24
+ const DEFAULT_COMPONENT_TTL_MS = 1800 * 1e3;
25
+ const PERSISTENT_COMPONENT_NAMESPACE = "discord.components";
26
+ const PERSISTENT_MODAL_NAMESPACE = "discord.modals";
27
+ const PERSISTENT_COMPONENT_MAX_ENTRIES = 500;
28
+ const PERSISTENT_MODAL_MAX_ENTRIES = 500;
29
+ const DISCORD_COMPONENT_ENTRIES_KEY = Symbol.for("klaw.discord.componentEntries");
30
+ const DISCORD_MODAL_ENTRIES_KEY = Symbol.for("klaw.discord.modalEntries");
31
+ let componentEntries;
32
+ let modalEntries;
33
+ let persistentComponentStore;
34
+ let persistentModalStore;
35
+ let persistentRegistryDisabled = false;
36
+ function getComponentEntries() {
37
+ componentEntries ??= resolveGlobalMap(DISCORD_COMPONENT_ENTRIES_KEY);
38
+ return componentEntries;
39
+ }
40
+ function getModalEntries() {
41
+ modalEntries ??= resolveGlobalMap(DISCORD_MODAL_ENTRIES_KEY);
42
+ return modalEntries;
43
+ }
44
+ function reportPersistentComponentRegistryError(error) {
45
+ try {
46
+ getOptionalDiscordRuntime()?.logging.getChildLogger({
47
+ plugin: "discord",
48
+ feature: "component-registry-state"
49
+ }).warn("Discord persistent component registry state failed", { error: String(error) });
50
+ } catch {}
51
+ }
52
+ function disablePersistentComponentRegistry(error) {
53
+ persistentRegistryDisabled = true;
54
+ persistentComponentStore = void 0;
55
+ persistentModalStore = void 0;
56
+ reportPersistentComponentRegistryError(error);
57
+ }
58
+ function getPersistentComponentStore() {
59
+ if (persistentRegistryDisabled) return;
60
+ if (persistentComponentStore) return persistentComponentStore;
61
+ const runtime = getOptionalDiscordRuntime();
62
+ if (!runtime) return;
63
+ try {
64
+ persistentComponentStore = runtime.state.openKeyedStore({
65
+ namespace: PERSISTENT_COMPONENT_NAMESPACE,
66
+ maxEntries: PERSISTENT_COMPONENT_MAX_ENTRIES,
67
+ defaultTtlMs: DEFAULT_COMPONENT_TTL_MS
68
+ });
69
+ return persistentComponentStore;
70
+ } catch (error) {
71
+ disablePersistentComponentRegistry(error);
72
+ return;
73
+ }
74
+ }
75
+ function getPersistentModalStore() {
76
+ if (persistentRegistryDisabled) return;
77
+ if (persistentModalStore) return persistentModalStore;
78
+ const runtime = getOptionalDiscordRuntime();
79
+ if (!runtime) return;
80
+ try {
81
+ persistentModalStore = runtime.state.openKeyedStore({
82
+ namespace: PERSISTENT_MODAL_NAMESPACE,
83
+ maxEntries: PERSISTENT_MODAL_MAX_ENTRIES,
84
+ defaultTtlMs: DEFAULT_COMPONENT_TTL_MS
85
+ });
86
+ return persistentModalStore;
87
+ } catch (error) {
88
+ disablePersistentComponentRegistry(error);
89
+ return;
90
+ }
91
+ }
92
+ function isExpired(entry, now) {
93
+ return typeof entry.expiresAt === "number" && entry.expiresAt <= now;
94
+ }
95
+ function normalizeEntryTimestamps(entry, now, ttlMs) {
96
+ const createdAt = entry.createdAt ?? now;
97
+ const expiresAt = entry.expiresAt ?? createdAt + ttlMs;
98
+ return {
99
+ ...entry,
100
+ createdAt,
101
+ expiresAt
102
+ };
103
+ }
104
+ function registerEntries(entries, store, params) {
105
+ const normalizedEntries = [];
106
+ for (const entry of entries) {
107
+ const normalized = normalizeEntryTimestamps({
108
+ ...entry,
109
+ messageId: params.messageId ?? entry.messageId
110
+ }, params.now, params.ttlMs);
111
+ store.set(entry.id, normalized);
112
+ normalizedEntries.push(normalized);
113
+ }
114
+ return normalizedEntries;
115
+ }
116
+ function resolveEntry(store, params) {
117
+ const entry = store.get(params.id);
118
+ if (!entry) return null;
119
+ if (isExpired(entry, Date.now())) {
120
+ store.delete(params.id);
121
+ return null;
122
+ }
123
+ if (params.consume !== false) store.delete(params.id);
124
+ return entry;
125
+ }
126
+ function readPersistedRegistryEntry(persisted) {
127
+ if (persisted?.version !== 1 || typeof persisted.entry?.id !== "string") return null;
128
+ return persisted.entry;
129
+ }
130
+ function registerPersistentRegistryEntries(params) {
131
+ if (params.entries.length === 0) return;
132
+ const store = params.openStore();
133
+ if (!store) return;
134
+ for (const entry of params.entries) store.register(entry.id, {
135
+ version: 1,
136
+ entry
137
+ }, { ttlMs: params.ttlMs }).catch(disablePersistentComponentRegistry);
138
+ }
139
+ function registerPersistentEntries(params) {
140
+ registerPersistentRegistryEntries({
141
+ entries: params.entries,
142
+ ttlMs: params.ttlMs,
143
+ openStore: getPersistentComponentStore
144
+ });
145
+ registerPersistentRegistryEntries({
146
+ entries: params.modals,
147
+ ttlMs: params.ttlMs,
148
+ openStore: getPersistentModalStore
149
+ });
150
+ }
151
+ function deletePersistentEntry(params) {
152
+ const store = params.openStore();
153
+ if (!store) return;
154
+ store.delete(params.id).catch(disablePersistentComponentRegistry);
155
+ }
156
+ function resolveComponentConsumptionIds(entry) {
157
+ if (!entry.consumptionGroupId) return [entry.id];
158
+ const ids = entry.consumptionGroupEntryIds?.filter((id) => typeof id === "string" && id) ?? [];
159
+ return ids.length > 0 ? Array.from(new Set(ids)) : [entry.id];
160
+ }
161
+ function deleteComponentConsumptionGroup(entry) {
162
+ const store = getComponentEntries();
163
+ for (const id of resolveComponentConsumptionIds(entry)) store.delete(id);
164
+ }
165
+ function deletePersistentComponentConsumptionGroup(entry) {
166
+ const store = getPersistentComponentStore();
167
+ if (!store) return;
168
+ for (const id of resolveComponentConsumptionIds(entry)) store.delete(id).catch(disablePersistentComponentRegistry);
169
+ }
170
+ async function resolvePersistentRegistryEntry(params) {
171
+ const store = params.openStore();
172
+ if (!store) return null;
173
+ try {
174
+ return readPersistedRegistryEntry(params.consume === false ? await store.lookup(params.id) : await store.consume(params.id));
175
+ } catch (error) {
176
+ disablePersistentComponentRegistry(error);
177
+ return null;
178
+ }
179
+ }
180
+ function registerDiscordComponentEntries(params) {
181
+ const now = Date.now();
182
+ const ttlMs = params.ttlMs ?? DEFAULT_COMPONENT_TTL_MS;
183
+ registerPersistentEntries({
184
+ entries: registerEntries(params.entries, getComponentEntries(), {
185
+ now,
186
+ ttlMs,
187
+ messageId: params.messageId
188
+ }),
189
+ modals: registerEntries(params.modals, getModalEntries(), {
190
+ now,
191
+ ttlMs,
192
+ messageId: params.messageId
193
+ }),
194
+ ttlMs
195
+ });
196
+ }
197
+ function resolveDiscordComponentEntry(params) {
198
+ const entry = resolveEntry(getComponentEntries(), params);
199
+ if (entry && params.consume !== false) deleteComponentConsumptionGroup(entry);
200
+ return entry;
201
+ }
202
+ async function resolveDiscordComponentEntryWithPersistence(params) {
203
+ const inMemory = resolveDiscordComponentEntry(params);
204
+ if (inMemory) {
205
+ if (params.consume !== false) deletePersistentComponentConsumptionGroup(inMemory);
206
+ return inMemory;
207
+ }
208
+ const persisted = await resolvePersistentRegistryEntry({
209
+ ...params,
210
+ openStore: getPersistentComponentStore
211
+ });
212
+ if (persisted && params.consume !== false) deletePersistentComponentConsumptionGroup(persisted);
213
+ return persisted;
214
+ }
215
+ function resolveDiscordModalEntry(params) {
216
+ return resolveEntry(getModalEntries(), params);
217
+ }
218
+ async function resolveDiscordModalEntryWithPersistence(params) {
219
+ const inMemory = resolveDiscordModalEntry(params);
220
+ if (inMemory) {
221
+ if (params.consume !== false) deletePersistentEntry({
222
+ ...params,
223
+ openStore: getPersistentModalStore
224
+ });
225
+ return inMemory;
226
+ }
227
+ return await resolvePersistentRegistryEntry({
228
+ ...params,
229
+ openStore: getPersistentModalStore
230
+ });
231
+ }
232
+ //#endregion
233
+ //#region extensions/discord/src/send.components.ts
234
+ var send_components_exports = /* @__PURE__ */ __exportAll({
235
+ editDiscordComponentMessage: () => editDiscordComponentMessage,
236
+ registerBuiltDiscordComponentMessage: () => registerBuiltDiscordComponentMessage,
237
+ sendDiscordComponentMessage: () => sendDiscordComponentMessage
238
+ });
239
+ const DISCORD_FORUM_LIKE_TYPES = new Set([ChannelType.GuildForum, ChannelType.GuildMedia]);
240
+ function extractComponentAttachmentNames(spec) {
241
+ const names = [];
242
+ for (const block of spec.blocks ?? []) if (block.type === "file") names.push(resolveDiscordComponentAttachmentName(block.file));
243
+ return names;
244
+ }
245
+ function hasComponentAttachmentBlock(spec) {
246
+ return (spec.blocks ?? []).some((block) => block.type === "file");
247
+ }
248
+ function withImplicitComponentAttachmentBlock(spec, attachmentName) {
249
+ if (!attachmentName || hasComponentAttachmentBlock(spec)) return spec;
250
+ return {
251
+ ...spec,
252
+ blocks: [...spec.blocks ?? [], {
253
+ type: "file",
254
+ file: `attachment://${attachmentName}`
255
+ }]
256
+ };
257
+ }
258
+ function hasClassicOnlyBlocks(spec) {
259
+ return (spec.blocks ?? []).every((block) => block.type === "text" || block.type === "file");
260
+ }
261
+ function hasUnsupportedClassicFeatures(spec) {
262
+ return Boolean(spec.modal || spec.container);
263
+ }
264
+ function hasAtMostOneNonSpoilerFile(spec) {
265
+ let fileBlockCount = 0;
266
+ for (const block of spec.blocks ?? []) {
267
+ if (block.type !== "file") continue;
268
+ fileBlockCount += 1;
269
+ if (block.spoiler) return false;
270
+ }
271
+ return fileBlockCount <= 1;
272
+ }
273
+ /**
274
+ * Keep the downgrade rules explicit because this path is only safe when the
275
+ * spec means exactly what a plain Discord message can represent.
276
+ */
277
+ function getClassicDiscordMessageDecision(spec) {
278
+ if (hasUnsupportedClassicFeatures(spec)) return {
279
+ mode: "components",
280
+ reason: "unsupported-feature"
281
+ };
282
+ if (!hasClassicOnlyBlocks(spec)) return {
283
+ mode: "components",
284
+ reason: "unsupported-block"
285
+ };
286
+ if (!hasAtMostOneNonSpoilerFile(spec)) return {
287
+ mode: "components",
288
+ reason: "multiple-or-spoiler-files"
289
+ };
290
+ return {
291
+ mode: "classic",
292
+ reason: "plain-text-single-file"
293
+ };
294
+ }
295
+ function collapseClassicComponentText(spec) {
296
+ const parts = [];
297
+ const addPart = (value) => {
298
+ if (typeof value !== "string") return;
299
+ const trimmed = value.trim();
300
+ if (!trimmed || parts.includes(trimmed)) return;
301
+ parts.push(trimmed);
302
+ };
303
+ addPart(spec.text);
304
+ for (const block of spec.blocks ?? []) if (block.type === "text") addPart(block.text);
305
+ return parts.join("\n\n");
306
+ }
307
+ function registerBuiltDiscordComponentMessage(params) {
308
+ registerDiscordComponentEntries({
309
+ entries: params.buildResult.entries,
310
+ modals: params.buildResult.modals,
311
+ messageId: params.messageId
312
+ });
313
+ }
314
+ async function buildDiscordComponentPayload(params) {
315
+ const messageReference = params.opts.replyTo ? {
316
+ message_id: params.opts.replyTo,
317
+ fail_if_not_exists: false
318
+ } : void 0;
319
+ let spec = params.spec;
320
+ let resolvedFileName;
321
+ let files;
322
+ if (params.opts.mediaUrl) {
323
+ const media = await loadOutboundMediaFromUrl(params.opts.mediaUrl, {
324
+ mediaAccess: params.opts.mediaAccess,
325
+ mediaLocalRoots: params.opts.mediaLocalRoots,
326
+ mediaReadFile: params.opts.mediaReadFile
327
+ });
328
+ resolvedFileName = params.opts.filename?.trim() || media.fileName || "upload";
329
+ spec = withImplicitComponentAttachmentBlock(spec, resolvedFileName);
330
+ files = [{
331
+ data: toDiscordFileBlob(media.buffer),
332
+ name: resolvedFileName
333
+ }];
334
+ }
335
+ const attachmentNames = extractComponentAttachmentNames(spec);
336
+ const uniqueAttachmentNames = [...new Set(attachmentNames)];
337
+ if (uniqueAttachmentNames.length > 1) throw new Error("Discord component attachments currently support a single file. Use media-gallery for multiple files.");
338
+ const expectedAttachmentName = uniqueAttachmentNames[0];
339
+ if (expectedAttachmentName && resolvedFileName && expectedAttachmentName !== resolvedFileName) throw new Error(`Component file block expects attachment "${expectedAttachmentName}", but the uploaded file is "${resolvedFileName}". Update components.blocks[].file or provide a matching filename.`);
340
+ if (!params.opts.mediaUrl && expectedAttachmentName) throw new Error("Discord component file blocks require a media attachment (media/path/filePath).");
341
+ const buildResult = buildDiscordComponentMessage({
342
+ spec,
343
+ sessionKey: params.opts.sessionKey,
344
+ agentId: params.opts.agentId,
345
+ accountId: params.accountId
346
+ });
347
+ const flags = buildDiscordComponentMessageFlags(buildResult.components);
348
+ const finalFlags = params.opts.silent ? (flags ?? 0) | SUPPRESS_NOTIFICATIONS_FLAG : flags ?? void 0;
349
+ return {
350
+ body: stripUndefinedFields({
351
+ ...serializePayload({
352
+ components: buildResult.components,
353
+ ...finalFlags ? { flags: finalFlags } : {},
354
+ ...files ? { files } : {}
355
+ }),
356
+ ...messageReference ? { message_reference: messageReference } : {}
357
+ }),
358
+ buildResult
359
+ };
360
+ }
361
+ async function sendDiscordComponentMessage(to, spec, opts) {
362
+ const classicDecision = getClassicDiscordMessageDecision(spec);
363
+ if (opts.mediaUrl && classicDecision.mode === "classic") return await sendMessageDiscord(to, collapseClassicComponentText(spec), {
364
+ cfg: opts.cfg,
365
+ accountId: opts.accountId,
366
+ token: opts.token,
367
+ rest: opts.rest,
368
+ mediaUrl: opts.mediaUrl,
369
+ filename: opts.filename,
370
+ mediaLocalRoots: opts.mediaLocalRoots,
371
+ mediaReadFile: opts.mediaReadFile,
372
+ mediaAccess: opts.mediaAccess,
373
+ replyTo: opts.replyTo,
374
+ silent: opts.silent,
375
+ textLimit: opts.textLimit,
376
+ maxLinesPerMessage: opts.maxLinesPerMessage,
377
+ tableMode: opts.tableMode,
378
+ chunkMode: opts.chunkMode,
379
+ ...opts.suppressEmbeds === void 0 ? {} : { suppressEmbeds: opts.suppressEmbeds }
380
+ });
381
+ const cfg = requireRuntimeConfig(opts.cfg, "Discord component send");
382
+ const accountInfo = resolveDiscordAccount({
383
+ cfg,
384
+ accountId: opts.accountId
385
+ });
386
+ const { token, rest, request } = createDiscordClient({
387
+ ...opts,
388
+ cfg
389
+ });
390
+ const { channelId } = await resolveChannelId(rest, await parseAndResolveRecipient(to, cfg, opts.accountId), request);
391
+ const channelType = await resolveDiscordChannelType(rest, channelId);
392
+ if (channelType && DISCORD_FORUM_LIKE_TYPES.has(channelType)) throw new Error("Discord components are not supported in forum-style channels");
393
+ const { body, buildResult } = await buildDiscordComponentPayload({
394
+ spec,
395
+ opts,
396
+ accountId: accountInfo.accountId
397
+ });
398
+ let result;
399
+ try {
400
+ result = await request(() => createChannelMessage(rest, channelId, { body }), "components");
401
+ } catch (err) {
402
+ throw await buildDiscordSendError(err, {
403
+ channelId,
404
+ cfg,
405
+ rest,
406
+ token,
407
+ hasMedia: Boolean(opts.mediaUrl)
408
+ });
409
+ }
410
+ registerBuiltDiscordComponentMessage({
411
+ buildResult,
412
+ messageId: result.id
413
+ });
414
+ recordChannelActivity({
415
+ channel: "discord",
416
+ accountId: accountInfo.accountId,
417
+ direction: "outbound"
418
+ });
419
+ return createDiscordSendResult({
420
+ result,
421
+ fallbackChannelId: channelId,
422
+ kind: "card",
423
+ ...opts.replyTo ? { replyToId: opts.replyTo } : {}
424
+ });
425
+ }
426
+ async function editDiscordComponentMessage(to, messageId, spec, opts) {
427
+ const cfg = requireRuntimeConfig(opts.cfg, "Discord component edit");
428
+ const accountInfo = resolveDiscordAccount({
429
+ cfg,
430
+ accountId: opts.accountId
431
+ });
432
+ const { token, rest, request } = createDiscordClient({
433
+ ...opts,
434
+ cfg
435
+ });
436
+ const { channelId } = await resolveChannelId(rest, await parseAndResolveRecipient(to, cfg, opts.accountId), request);
437
+ const { body, buildResult } = await buildDiscordComponentPayload({
438
+ spec,
439
+ opts,
440
+ accountId: accountInfo.accountId
441
+ });
442
+ let result;
443
+ try {
444
+ result = await request(() => editChannelMessage(rest, channelId, messageId, { body }), "components");
445
+ } catch (err) {
446
+ throw await buildDiscordSendError(err, {
447
+ channelId,
448
+ cfg,
449
+ rest,
450
+ token,
451
+ hasMedia: Boolean(opts.mediaUrl)
452
+ });
453
+ }
454
+ registerBuiltDiscordComponentMessage({
455
+ buildResult,
456
+ messageId: result.id ?? messageId
457
+ });
458
+ recordChannelActivity({
459
+ channel: "discord",
460
+ accountId: accountInfo.accountId,
461
+ direction: "outbound"
462
+ });
463
+ return createDiscordSendResult({
464
+ result: {
465
+ id: result.id ?? messageId,
466
+ channel_id: result.channel_id
467
+ },
468
+ fallbackChannelId: channelId,
469
+ kind: "card",
470
+ ...opts.replyTo ? { replyToId: opts.replyTo } : {}
471
+ });
472
+ }
473
+ //#endregion
474
+ export { resolveDiscordComponentEntryWithPersistence as a, jsonResult as c, readNumberParam as d, readReactionParams as f, withNormalizedTimestamp as g, resolvePollMaxSelections as h, send_components_exports as i, parseAvailableTags as l, readStringParam as m, registerBuiltDiscordComponentMessage as n, resolveDiscordModalEntryWithPersistence as o, readStringArrayParam as p, sendDiscordComponentMessage as r, assertMediaNotDataUrl as s, editDiscordComponentMessage as t, readBooleanParam$1 as u };