@openclaw/discord 2026.5.14-beta.2 → 2026.5.16-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 (49) hide show
  1. package/dist/action-runtime-api.js +1 -1
  2. package/dist/api.js +6 -6
  3. package/dist/{approval-handler.runtime-Uco62pII.js → approval-handler.runtime-CS97g4S1.js} +2 -2
  4. package/dist/{audit-eSlKbMHw.js → audit-BZOw16KT.js} +2 -2
  5. package/dist/{channel-actions-DANVAtKL.js → channel-actions-0dOFg3Mu.js} +1 -1
  6. package/dist/{channel-actions.runtime-CpIslHS9.js → channel-actions.runtime-BB30vneH.js} +6 -2
  7. package/dist/channel-config-api.js +1 -1
  8. package/dist/{channel-BjBa8nYY.js → channel-ngFtP-WD.js} +8 -8
  9. package/dist/channel-plugin-api.js +1 -1
  10. package/dist/{channel.setup-DBFcGRFD.js → channel.setup-BwmvzHMR.js} +32 -30
  11. package/dist/{config-schema-D7AtCpJa.js → config-schema-D0eb2vPJ.js} +4 -0
  12. package/dist/contract-api.js +1 -1
  13. package/dist/{conversation-identity-C3AI-1tz.js → conversation-identity-Dh8wIQ_K.js} +1 -1
  14. package/dist/{doctor-mn2XyjuF.js → doctor-CWTWiBru.js} +1 -1
  15. package/dist/{handle-action.guild-admin-DriifPwO.js → handle-action.guild-admin-DOW3XfEG.js} +1 -1
  16. package/dist/{inbound-context-DD7n3Q6U.js → inbound-context-BdfOEkhj.js} +7 -10
  17. package/dist/{manager.runtime-DauS2xA3.js → manager.runtime-D8sDxzBv.js} +3 -3
  18. package/dist/{message-handler-CMHwRlxG.js → message-handler-D-Nboii4.js} +5 -5
  19. package/dist/{message-handler.preflight-C0sT-ewp.js → message-handler.preflight-BMgBVbmR.js} +98 -17
  20. package/dist/{message-handler.process-Cy7_-0H0.js → message-handler.process-Dfu_aSv1.js} +240 -199
  21. package/dist/{message-utils-N5UTOXQ2.js → message-utils-CY91O2k2.js} +35 -2
  22. package/dist/{outbound-adapter-Cw9JsRTY.js → outbound-adapter-Fe4Ee_GO.js} +3 -3
  23. package/dist/{provider-nzJg2k5t.js → provider-B81nXBRc.js} +15 -12
  24. package/dist/{provider-session.runtime-DMxaLPB3.js → provider-session.runtime-C7p_WbqZ.js} +3 -3
  25. package/dist/provider.runtime-B_3TYTb7.js +2 -0
  26. package/dist/{runtime-DL82ijB1.js → runtime-ToiiUiXe.js} +24 -8
  27. package/dist/runtime-api.actions.js +2 -2
  28. package/dist/runtime-api.js +14 -14
  29. package/dist/runtime-api.lookup.js +1 -1
  30. package/dist/runtime-api.monitor-DJQdXyzE.js +5 -0
  31. package/dist/runtime-api.monitor.js +4 -4
  32. package/dist/runtime-api.send.js +4 -4
  33. package/dist/runtime-api.threads.js +3 -3
  34. package/dist/{send-BqzTEkt9.js → send-CvXckvRn.js} +14 -3
  35. package/dist/{send.components-D6pXHVrU.js → send.components-BlNbbG3H.js} +4 -3
  36. package/dist/{send.outbound-D8o8BW6q.js → send.outbound-BKh71kjw.js} +45 -22
  37. package/dist/{send.shared-DSpva7uA.js → send.shared-Bdj-DP6-.js} +41 -26
  38. package/dist/setup-plugin-api.js +1 -1
  39. package/dist/{shared-0kdaIxXP.js → shared-LuaeDRhK.js} +2 -2
  40. package/dist/subagent-hooks-api.js +1 -1
  41. package/dist/{subagent-hooks-DhuBhwRw.js → subagent-hooks-vwV-pjIA.js} +1 -1
  42. package/dist/test-api.js +5 -5
  43. package/dist/{thread-bindings-C1f7Iim4.js → thread-bindings-BwcE40jS.js} +2 -2
  44. package/dist/{thread-bindings.discord-api-DJACBZJ1.js → thread-bindings.discord-api-BtXi8-Fz.js} +3 -3
  45. package/dist/{thread-bindings.manager-DN_q0IW7.js → thread-bindings.manager-BL5QlX3G.js} +2 -2
  46. package/openclaw.plugin.json +10 -0
  47. package/package.json +4 -4
  48. package/dist/provider.runtime-S-wZdzK5.js +0 -2
  49. package/dist/runtime-api.monitor-DbLcHuhE.js +0 -5
@@ -1,2 +1,2 @@
1
- import { t as handleDiscordAction } from "./runtime-DL82ijB1.js";
1
+ import { t as handleDiscordAction } from "./runtime-ToiiUiXe.js";
2
2
  export { handleDiscordAction };
package/dist/api.js CHANGED
@@ -5,12 +5,12 @@ import { _ as parseDiscordComponentCustomId, b as parseDiscordModalCustomIdForIn
5
5
  import { n as fetchDiscord, r as requestDiscord, t as DiscordApiError } from "./api-DgQLz1wq.js";
6
6
  import { i as parseDiscordSendTarget, n as resolveDiscordTarget } from "./target-resolver-BsGT9hI7.js";
7
7
  import "./targets-DwW6OieO.js";
8
- import { a as getDiscordExecApprovalApprovers, c as shouldSuppressLocalDiscordExecApprovalPrompt, o as isDiscordExecApprovalApprover, s as isDiscordExecApprovalClientEnabled } from "./conversation-identity-C3AI-1tz.js";
9
- import { i as resolveDiscordGroupToolPolicy, n as collectDiscordStatusIssues, r as resolveDiscordGroupRequireMention, t as discordPlugin } from "./channel-BjBa8nYY.js";
8
+ import { a as getDiscordExecApprovalApprovers, c as shouldSuppressLocalDiscordExecApprovalPrompt, o as isDiscordExecApprovalApprover, s as isDiscordExecApprovalClientEnabled } from "./conversation-identity-Dh8wIQ_K.js";
9
+ import { i as resolveDiscordGroupToolPolicy, n as collectDiscordStatusIssues, r as resolveDiscordGroupRequireMention, t as discordPlugin } from "./channel-ngFtP-WD.js";
10
10
  import { t as normalizeExplicitDiscordSessionKey } from "./session-key-normalization-B7h83qD2.js";
11
- import { t as discordSetupPlugin } from "./channel.setup-DBFcGRFD.js";
12
- import { n as handleDiscordSubagentEnded, r as handleDiscordSubagentSpawning, t as handleDiscordSubagentDeliveryTarget } from "./subagent-hooks-DhuBhwRw.js";
13
- import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-DriifPwO.js";
11
+ import { t as discordSetupPlugin } from "./channel.setup-BwmvzHMR.js";
12
+ import { n as handleDiscordSubagentEnded, r as handleDiscordSubagentSpawning, t as handleDiscordSubagentDeliveryTarget } from "./subagent-hooks-vwV-pjIA.js";
13
+ import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-DOW3XfEG.js";
14
14
  import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-CW_JusGS.js";
15
15
  import { t as fetchPluralKitMessageInfo } from "./pluralkit-B2AqgTHV.js";
16
16
  import { a as resolveDiscordPrivilegedIntentsFromFlags, i as probeDiscord, n as fetchDiscordApplicationSummary, r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-CiBYm-vD.js";
@@ -18,6 +18,6 @@ import { t as collectDiscordSecurityAuditFindings } from "./security-audit-CLPZK
18
18
  import { a as mergeAbortSignals, i as DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, r as DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-snXNwR4m.js";
19
19
  import { resolveOpenProviderRuntimeGroupPolicy as resolveDiscordRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
20
20
  //#region extensions/discord/api.ts
21
- const handleDiscordMessageAction = async (...args) => (await import("./channel-actions.runtime-CpIslHS9.js")).handleDiscordMessageAction(...args);
21
+ const handleDiscordMessageAction = async (...args) => (await import("./channel-actions.runtime-BB30vneH.js")).handleDiscordMessageAction(...args);
22
22
  //#endregion
23
23
  export { DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS, DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, DISCORD_COMPONENT_ATTACHMENT_PREFIX, DISCORD_COMPONENT_CUSTOM_ID_KEY, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, DISCORD_MODAL_CUSTOM_ID_KEY, DiscordApiError, DiscordFormModal, buildDiscordComponentCustomId, buildDiscordComponentMessage, buildDiscordComponentMessageFlags, buildDiscordInteractiveComponents, buildDiscordModalCustomId, collectDiscordSecurityAuditFindings, collectDiscordStatusIssues, createDiscordActionGate, createDiscordFormModal, discordPlugin, discordSetupPlugin, fetchDiscord, fetchDiscordApplicationId, fetchDiscordApplicationSummary, fetchPluralKitMessageInfo, formatDiscordComponentEventText, getDiscordExecApprovalApprovers, handleDiscordMessageAction, handleDiscordSubagentDeliveryTarget, handleDiscordSubagentEnded, handleDiscordSubagentSpawning, inspectDiscordAccount, isDiscordExecApprovalApprover, isDiscordExecApprovalClientEnabled, listDiscordAccountIds, listDiscordDirectoryGroupsFromConfig, listDiscordDirectoryPeersFromConfig, listEnabledDiscordAccounts, looksLikeDiscordTargetId, mergeAbortSignals, mergeDiscordAccountConfig, normalizeDiscordMessagingTarget, normalizeDiscordOutboundTarget, normalizeExplicitDiscordSessionKey, parseApplicationIdFromToken, parseDiscordComponentCustomId, parseDiscordComponentCustomIdForInteraction as parseDiscordComponentCustomIdForCarbon, parseDiscordComponentCustomIdForInteraction, parseDiscordModalCustomId, parseDiscordModalCustomIdForInteraction as parseDiscordModalCustomIdForCarbon, parseDiscordModalCustomIdForInteraction, parseDiscordSendTarget, parseDiscordTarget, probeDiscord, readDiscordComponentSpec, requestDiscord, resolveDefaultDiscordAccountId, resolveDiscordAccount, resolveDiscordAccountConfig, resolveDiscordChannelId, resolveDiscordComponentAttachmentName, resolveDiscordGroupRequireMention, resolveDiscordGroupToolPolicy, resolveDiscordMaxLinesPerMessage, resolveDiscordPrivilegedIntentsFromFlags, resolveDiscordRuntimeGroupPolicy, resolveDiscordTarget, shouldSuppressLocalDiscordExecApprovalPrompt, tryHandleDiscordMessageActionGuildAdmin };
@@ -1,7 +1,7 @@
1
1
  import { B as Container, J as Separator, K as Row, M as serializePayload, R as Button, Wt as __exportAll, X as TextDisplay, ft as editChannelMessage, nt as createUserDmChannel, st as createChannelMessage, ut as deleteChannelMessage } from "./send.receipt-nKLxvA1s.js";
2
2
  import { t as inspectDiscordAccount } from "./account-inspect-B_N30NV0.js";
3
- import { j as createDiscordClient, y as stripUndefinedFields } from "./send.shared-DSpva7uA.js";
4
- import { i as shouldHandleDiscordApprovalRequest, s as isDiscordExecApprovalClientEnabled } from "./conversation-identity-C3AI-1tz.js";
3
+ import { M as createDiscordClient, b as stripUndefinedFields } from "./send.shared-Bdj-DP6-.js";
4
+ import { i as shouldHandleDiscordApprovalRequest, s as isDiscordExecApprovalClientEnabled } from "./conversation-identity-Dh8wIQ_K.js";
5
5
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  import { ButtonStyle } from "discord-api-types/v10";
7
7
  import { logDebug, logError } from "openclaw/plugin-sdk/logging-core";
@@ -1,7 +1,7 @@
1
1
  import { Wt as __exportAll } from "./send.receipt-nKLxvA1s.js";
2
2
  import { t as inspectDiscordAccount } from "./account-inspect-B_N30NV0.js";
3
- import { T as fetchChannelPermissionsDiscord } from "./send.shared-DSpva7uA.js";
4
- import "./send-BqzTEkt9.js";
3
+ import { E as fetchChannelPermissionsDiscord } from "./send.shared-Bdj-DP6-.js";
4
+ import "./send-CvXckvRn.js";
5
5
  import { n as collectDiscordAuditChannelIdsForAccount, t as auditDiscordChannelPermissionsWithFetcher } from "./audit-core-DRyoXREU.js";
6
6
  //#region extensions/discord/src/audit.ts
7
7
  var audit_exports = /* @__PURE__ */ __exportAll({
@@ -7,7 +7,7 @@ import { extractToolSend } from "openclaw/plugin-sdk/tool-send";
7
7
  //#region extensions/discord/src/channel-actions.ts
8
8
  let discordChannelActionsRuntimePromise;
9
9
  async function loadDiscordChannelActionsRuntime() {
10
- discordChannelActionsRuntimePromise ??= import("./channel-actions.runtime-CpIslHS9.js");
10
+ discordChannelActionsRuntimePromise ??= import("./channel-actions.runtime-BB30vneH.js");
11
11
  return await discordChannelActionsRuntimePromise;
12
12
  }
13
13
  function listDiscoverableDiscordAccounts(cfg) {
@@ -1,9 +1,9 @@
1
1
  import { Ut as resolveDiscordChannelId } from "./send.receipt-nKLxvA1s.js";
2
2
  import { i as buildDiscordPresentationComponents, r as buildDiscordInteractiveComponents } from "./components-Cgm7XT8-.js";
3
- import { t as handleDiscordAction } from "./runtime-DL82ijB1.js";
3
+ import { t as handleDiscordAction } from "./runtime-ToiiUiXe.js";
4
4
  import "./targets-DwW6OieO.js";
5
5
  import "./action-runtime-api.js";
6
- import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-DriifPwO.js";
6
+ import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-DOW3XfEG.js";
7
7
  import { normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
9
9
  import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
@@ -51,6 +51,7 @@ async function handleDiscordMessageAction(ctx) {
51
51
  const rawEmbeds = params.embeds;
52
52
  const embeds = Array.isArray(rawEmbeds) ? rawEmbeds : void 0;
53
53
  const silent = readBooleanParam(params, "silent") === true;
54
+ const suppressEmbeds = readBooleanParam(params, "suppressEmbeds");
54
55
  const sessionKey = readStringParam(params, "__sessionKey");
55
56
  const agentId = readStringParam(params, "__agentId");
56
57
  const threadName = readStringParam(params, "threadName");
@@ -67,6 +68,7 @@ async function handleDiscordMessageAction(ctx) {
67
68
  embeds,
68
69
  asVoice,
69
70
  silent,
71
+ ...suppressEmbeds === void 0 ? {} : { suppressEmbeds },
70
72
  __sessionKey: sessionKey ?? void 0,
71
73
  __agentId: agentId ?? void 0
72
74
  }, cfg, actionOptions);
@@ -79,6 +81,7 @@ async function handleDiscordMessageAction(ctx) {
79
81
  const filename = readStringParam(params, "filename");
80
82
  const replyTo = readStringParam(params, "replyTo");
81
83
  const silent = readBooleanParam(params, "silent") === true;
84
+ const suppressEmbeds = readBooleanParam(params, "suppressEmbeds");
82
85
  const sessionKey = readStringParam(params, "__sessionKey");
83
86
  const agentId = readStringParam(params, "__agentId");
84
87
  return await handleDiscordAction({
@@ -90,6 +93,7 @@ async function handleDiscordMessageAction(ctx) {
90
93
  filename: filename ?? void 0,
91
94
  replyTo: replyTo ?? void 0,
92
95
  silent,
96
+ ...suppressEmbeds === void 0 ? {} : { suppressEmbeds },
93
97
  __sessionKey: sessionKey ?? void 0,
94
98
  __agentId: agentId ?? void 0
95
99
  }, cfg, actionOptions);
@@ -1,2 +1,2 @@
1
- import { t as DiscordChannelConfigSchema } from "./config-schema-D7AtCpJa.js";
1
+ import { t as DiscordChannelConfigSchema } from "./config-schema-D0eb2vPJ.js";
2
2
  export { DiscordChannelConfigSchema };
@@ -3,12 +3,12 @@ import { c as resolveDiscordAccountAllowFrom, r as listDiscordAccountIds, s as r
3
3
  import { a as projectCredentialSnapshotFields, n as PAIRING_APPROVED_MESSAGE, o as resolveConfiguredFromCredentialStatuses, r as buildTokenChannelStatusSummary, t as DEFAULT_ACCOUNT_ID } from "./channel-api-JudoSiJv.js";
4
4
  import { x as resolveDiscordOutboundSessionRoute } from "./components-Cgm7XT8-.js";
5
5
  import { t as getDiscordRuntime } from "./runtime-Tqtvj5GX.js";
6
- import { c as shouldSuppressLocalDiscordExecApprovalPrompt, n as resolveDiscordCurrentConversationIdentity, r as getDiscordApprovalCapability } from "./conversation-identity-C3AI-1tz.js";
6
+ import { c as shouldSuppressLocalDiscordExecApprovalPrompt, n as resolveDiscordCurrentConversationIdentity, r as getDiscordApprovalCapability } from "./conversation-identity-Dh8wIQ_K.js";
7
7
  import { r as resolveRequiredDiscordChannelPermissions } from "./audit-core-DRyoXREU.js";
8
- import { t as discordMessageActions$1 } from "./channel-actions-DANVAtKL.js";
8
+ import { t as discordMessageActions$1 } from "./channel-actions-0dOFg3Mu.js";
9
9
  import { n as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-ZnRRzzgf.js";
10
- import { n as discordOutbound } from "./outbound-adapter-Cw9JsRTY.js";
11
- import { a as discordSecurityAdapter, i as discordSetupAdapter, n as discordConfigAdapter, t as createDiscordPluginBase } from "./shared-0kdaIxXP.js";
10
+ import { n as discordOutbound } from "./outbound-adapter-Fe4Ee_GO.js";
11
+ import { a as discordSecurityAdapter, i as discordSetupAdapter, n as discordConfigAdapter, t as createDiscordPluginBase } from "./shared-LuaeDRhK.js";
12
12
  import { t as normalizeExplicitDiscordSessionKey } from "./session-key-normalization-B7h83qD2.js";
13
13
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
14
14
  import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
@@ -129,10 +129,10 @@ let discordDirectoryLiveModulePromise;
129
129
  const loadDiscordDirectoryConfigModule = createLazyRuntimeModule(() => import("./directory-config-CW_JusGS.js").then((n) => n.t));
130
130
  const loadDiscordResolveChannelsModule = createLazyRuntimeModule(() => import("./resolve-channels-u7_agBcm.js").then((n) => n.n));
131
131
  const loadDiscordResolveUsersModule = createLazyRuntimeModule(() => import("./resolve-users-Bc25I6OP.js").then((n) => n.n));
132
- const loadDiscordThreadBindingsManagerModule = createLazyRuntimeModule(() => import("./thread-bindings.manager-DN_q0IW7.js").then((n) => n.a));
132
+ const loadDiscordThreadBindingsManagerModule = createLazyRuntimeModule(() => import("./thread-bindings.manager-BL5QlX3G.js").then((n) => n.a));
133
133
  const loadDiscordTargetResolverModule = createLazyRuntimeModule(() => import("./target-resolver-BsGT9hI7.js").then((n) => n.r));
134
134
  async function loadDiscordProviderRuntime() {
135
- discordProviderRuntimePromise ??= import("./provider.runtime-S-wZdzK5.js");
135
+ discordProviderRuntimePromise ??= import("./provider.runtime-B_3TYTb7.js");
136
136
  return await discordProviderRuntimePromise;
137
137
  }
138
138
  async function loadDiscordProbeRuntime() {
@@ -140,11 +140,11 @@ async function loadDiscordProbeRuntime() {
140
140
  return await discordProbeRuntimePromise;
141
141
  }
142
142
  async function loadDiscordAuditModule() {
143
- discordAuditModulePromise ??= import("./audit-eSlKbMHw.js").then((n) => n.n);
143
+ discordAuditModulePromise ??= import("./audit-BZOw16KT.js").then((n) => n.n);
144
144
  return await discordAuditModulePromise;
145
145
  }
146
146
  async function loadDiscordSendModule() {
147
- discordSendModulePromise ??= import("./send-BqzTEkt9.js").then((n) => n.t);
147
+ discordSendModulePromise ??= import("./send-CvXckvRn.js").then((n) => n.t);
148
148
  return await discordSendModulePromise;
149
149
  }
150
150
  async function loadDiscordDirectoryLiveModule() {
@@ -1,2 +1,2 @@
1
- import { t as discordPlugin } from "./channel-BjBa8nYY.js";
1
+ import { t as discordPlugin } from "./channel-ngFtP-WD.js";
2
2
  export { discordPlugin };
@@ -1,11 +1,11 @@
1
1
  import { a as mergeDiscordAccountConfig, c as resolveDiscordAccountAllowFrom, l as resolveDiscordAccountConfig, m as resolveDiscordToken, o as resolveDefaultDiscordAccountId } from "./accounts-DnNVBDfc.js";
2
- import { i as discordSetupAdapter, t as createDiscordPluginBase } from "./shared-0kdaIxXP.js";
2
+ import { i as discordSetupAdapter, t as createDiscordPluginBase } from "./shared-LuaeDRhK.js";
3
3
  import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-u7_agBcm.js";
4
4
  import { t as resolveDiscordUserAllowlist } from "./resolve-users-Bc25I6OP.js";
5
5
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
6
6
  import { hasConfiguredSecretInput, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
7
7
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
8
- import { createAccountScopedAllowFromSection, createAccountScopedGroupAccessSection, createLegacyCompatChannelDmPolicy, createStandardChannelSetupStatus, parseMentionOrPrefixedId, patchChannelConfigForAccount, promptLegacyChannelAllowFromForAccount, resolveEntriesWithOptionalToken, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup-runtime";
8
+ import { createAccountScopedAllowFromSection, createAccountScopedGroupAccessSection, createLegacyCompatChannelDmPolicy, createSetupTranslator, createStandardChannelSetupStatus, parseMentionOrPrefixedId, patchChannelConfigForAccount, promptLegacyChannelAllowFromForAccount, resolveEntriesWithOptionalToken, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup-runtime";
9
9
  import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
10
10
  import "openclaw/plugin-sdk/account-resolution";
11
11
  //#region extensions/discord/src/setup-account-state.ts
@@ -89,13 +89,14 @@ function inspectDiscordSetupAccount(params) {
89
89
  }
90
90
  //#endregion
91
91
  //#region extensions/discord/src/setup-core.ts
92
+ const t$1 = createSetupTranslator();
92
93
  const channel$1 = "discord";
93
94
  const DISCORD_TOKEN_HELP_LINES = [
94
- "1) Discord Developer Portal -> Applications -> New Application",
95
- "2) Bot -> Add Bot -> Reset Token -> copy token",
96
- "3) OAuth2 -> URL Generator -> scope 'bot' -> invite to your server",
97
- "Tip: enable Message Content Intent if you need message text. (Bot -> Privileged Gateway Intents -> Message Content Intent)",
98
- `Docs: ${formatDocsLink("/discord", "discord")}`
95
+ t$1("wizard.discord.tokenHelpCreateApplication"),
96
+ t$1("wizard.discord.tokenHelpCopyToken"),
97
+ t$1("wizard.discord.tokenHelpInviteBot"),
98
+ t$1("wizard.discord.tokenHelpMessageContentIntent"),
99
+ t$1("wizard.channels.docs", { link: formatDocsLink("/discord", "discord") })
99
100
  ];
100
101
  function mapDiscordSetupAllowlistEntries(resolved) {
101
102
  if (!Array.isArray(resolved)) return [];
@@ -151,10 +152,10 @@ function createDiscordSetupWizardBase(handlers) {
151
152
  channel: channel$1,
152
153
  status: createStandardChannelSetupStatus({
153
154
  channelLabel: "Discord",
154
- configuredLabel: "configured",
155
- unconfiguredLabel: "needs token",
156
- configuredHint: "configured",
157
- unconfiguredHint: "needs token",
155
+ configuredLabel: t$1("wizard.channels.statusConfigured"),
156
+ unconfiguredLabel: t$1("wizard.channels.statusNeedsToken"),
157
+ configuredHint: t$1("wizard.channels.statusConfigured"),
158
+ unconfiguredHint: t$1("wizard.channels.statusNeedsToken"),
158
159
  configuredScore: 2,
159
160
  unconfiguredScore: 1,
160
161
  resolveConfigured: ({ cfg, accountId }) => inspectDiscordSetupAccount({
@@ -165,13 +166,13 @@ function createDiscordSetupWizardBase(handlers) {
165
166
  credentials: [{
166
167
  inputKey: "token",
167
168
  providerHint: channel$1,
168
- credentialLabel: "Discord bot token",
169
+ credentialLabel: t$1("wizard.discord.botToken"),
169
170
  preferredEnvVar: "DISCORD_BOT_TOKEN",
170
- helpTitle: "Discord bot token",
171
+ helpTitle: t$1("wizard.discord.botToken"),
171
172
  helpLines: DISCORD_TOKEN_HELP_LINES,
172
- envPrompt: "DISCORD_BOT_TOKEN detected. Use env var?",
173
- keepPrompt: "Discord token already configured. Keep it?",
174
- inputPrompt: "Enter Discord bot token",
173
+ envPrompt: t$1("wizard.discord.tokenEnvPrompt"),
174
+ keepPrompt: t$1("wizard.discord.tokenKeepPrompt"),
175
+ inputPrompt: t$1("wizard.discord.tokenInputPrompt"),
175
176
  allowEnv: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID,
176
177
  inspect: ({ cfg, accountId }) => {
177
178
  const account = inspectDiscordSetupAccount({
@@ -188,7 +189,7 @@ function createDiscordSetupWizardBase(handlers) {
188
189
  }],
189
190
  groupAccess: createAccountScopedGroupAccessSection({
190
191
  channel: channel$1,
191
- label: "Discord channels",
192
+ label: t$1("wizard.discord.channelsLabel"),
192
193
  placeholder: "My Server/#general, guildId/channelId, #support",
193
194
  currentPolicy: ({ cfg, accountId }) => resolveDiscordSetupAccountConfig({
194
195
  cfg,
@@ -219,17 +220,17 @@ function createDiscordSetupWizardBase(handlers) {
219
220
  credentialInputKey: "token",
220
221
  helpTitle: "Discord allowlist",
221
222
  helpLines: [
222
- "Allowlist Discord DMs by username (we resolve to user ids).",
223
- "Examples:",
223
+ t$1("wizard.discord.allowlistIntro"),
224
+ t$1("wizard.discord.examples"),
224
225
  "- 123456789012345678",
225
226
  "- @alice",
226
227
  "- alice#1234",
227
- "Multiple entries: comma-separated.",
228
- `Docs: ${formatDocsLink("/discord", "discord")}`
228
+ t$1("wizard.discord.multipleEntries"),
229
+ t$1("wizard.channels.docs", { link: formatDocsLink("/discord", "discord") })
229
230
  ],
230
- message: "Discord allowFrom (usernames or ids)",
231
+ message: t$1("wizard.discord.allowFromPrompt"),
231
232
  placeholder: "@alice, 123456789012345678",
232
- invalidWithoutCredentialNote: "Bot token missing; use numeric user ids (or mention form) only.",
233
+ invalidWithoutCredentialNote: t$1("wizard.discord.allowFromInvalidWithoutToken"),
233
234
  parseId: parseDiscordAllowFromId,
234
235
  resolveEntries: handlers.resolveAllowFromEntries
235
236
  }),
@@ -239,6 +240,7 @@ function createDiscordSetupWizardBase(handlers) {
239
240
  }
240
241
  //#endregion
241
242
  //#region extensions/discord/src/setup-surface.ts
243
+ const t = createSetupTranslator();
242
244
  const channel = "discord";
243
245
  async function resolveDiscordAllowFromEntries(params) {
244
246
  return await resolveEntriesWithOptionalToken({
@@ -270,20 +272,20 @@ async function promptDiscordAllowFrom(params) {
270
272
  cfg,
271
273
  accountId
272
274
  }),
273
- noteTitle: "Discord allowlist",
275
+ noteTitle: t("wizard.discord.allowlistTitle"),
274
276
  noteLines: [
275
- "Allowlist Discord DMs by username (we resolve to user ids).",
276
- "Examples:",
277
+ t("wizard.discord.allowlistIntro"),
278
+ t("wizard.discord.examples"),
277
279
  "- 123456789012345678",
278
280
  "- @alice",
279
281
  "- alice#1234",
280
- "Multiple entries: comma-separated.",
281
- `Docs: ${formatDocsLink("/discord", "discord")}`
282
+ t("wizard.discord.multipleEntries"),
283
+ t("wizard.channels.docs", { link: formatDocsLink("/discord", "discord") })
282
284
  ],
283
- message: "Discord allowFrom (usernames or ids)",
285
+ message: t("wizard.discord.allowFromPrompt"),
284
286
  placeholder: "@alice, 123456789012345678",
285
287
  parseId: parseDiscordAllowFromId,
286
- invalidWithoutTokenNote: "Bot token missing; use numeric user ids (or mention form) only.",
288
+ invalidWithoutTokenNote: t("wizard.discord.allowFromInvalidWithoutToken"),
287
289
  resolveExisting: (account, cfg) => resolveDiscordAccountAllowFrom({
288
290
  cfg,
289
291
  accountId: account.accountId
@@ -110,6 +110,10 @@ const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordConfigSchema,
110
110
  label: "Discord Max Lines Per Message",
111
111
  help: "Soft max line count per Discord message (default: 17)."
112
112
  },
113
+ suppressEmbeds: {
114
+ label: "Discord Suppress Link Embeds",
115
+ help: "Suppress Discord-generated link embeds on outbound messages by default. Explicit embeds still send normally. Default: true."
116
+ },
113
117
  "thread.inheritParent": {
114
118
  label: "Discord Thread Parent Inheritance",
115
119
  help: "If true, Discord thread sessions inherit the parent channel transcript (default: false)."
@@ -2,7 +2,7 @@ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doc
2
2
  import { n as secretTargetRegistryEntries, t as collectRuntimeConfigAssignments } from "./secret-config-contract-B3347_eU.js";
3
3
  import { n as unsupportedSecretRefSurfacePatterns, t as collectUnsupportedSecretRefConfigCandidates } from "./security-contract-DyCRvz_Q.js";
4
4
  import { t as deriveLegacySessionChatType } from "./session-contract-ugfEa9Xc.js";
5
- import { r as createThreadBindingManager, t as __testing } from "./thread-bindings.manager-DN_q0IW7.js";
5
+ import { r as createThreadBindingManager, t as __testing } from "./thread-bindings.manager-BL5QlX3G.js";
6
6
  import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-CW_JusGS.js";
7
7
  import { t as collectDiscordSecurityAuditFindings } from "./security-audit-CLPZKYi4.js";
8
8
  export { collectDiscordSecurityAuditFindings, collectRuntimeConfigAssignments, collectUnsupportedSecretRefConfigCandidates, createThreadBindingManager, deriveLegacySessionChatType, __testing as discordThreadBindingTesting, legacyConfigRules, listDiscordDirectoryGroupsFromConfig, listDiscordDirectoryPeersFromConfig, normalizeCompatibilityConfig, secretTargetRegistryEntries, unsupportedSecretRefSurfacePatterns };
@@ -229,7 +229,7 @@ function createDiscordApprovalCapability(configOverride) {
229
229
  request,
230
230
  configOverride
231
231
  }),
232
- load: async () => (await import("./approval-handler.runtime-Uco62pII.js").then((n) => n.t)).discordApprovalNativeRuntime
232
+ load: async () => (await import("./approval-handler.runtime-CS97g4S1.js").then((n) => n.t)).discordApprovalNativeRuntime
233
233
  })
234
234
  });
235
235
  }
@@ -1,6 +1,6 @@
1
1
  import { o as resolveDefaultDiscordAccountId } from "./accounts-DnNVBDfc.js";
2
2
  import { t as inspectDiscordAccount } from "./account-inspect-B_N30NV0.js";
3
- import { r as DISCORD_LEGACY_CONFIG_RULES } from "./shared-0kdaIxXP.js";
3
+ import { r as DISCORD_LEGACY_CONFIG_RULES } from "./shared-LuaeDRhK.js";
4
4
  import { n as normalizeCompatibilityConfig } from "./doctor-contract-ftWAMvBl.js";
5
5
  import { t as isDiscordMutableAllowEntry } from "./security-doctor-Cp-NqNdS.js";
6
6
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -1,4 +1,4 @@
1
- import { a as readDiscordChannelCreateParams, n as isDiscordModerationAction, o as readDiscordChannelEditParams, r as readDiscordModerationCommand, s as readDiscordChannelMoveParams, t as handleDiscordAction } from "./runtime-DL82ijB1.js";
1
+ import { a as readDiscordChannelCreateParams, n as isDiscordModerationAction, o as readDiscordChannelEditParams, r as readDiscordModerationCommand, s as readDiscordChannelMoveParams, t as handleDiscordAction } from "./runtime-ToiiUiXe.js";
2
2
  import "./action-runtime-api.js";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { readNumberParam, readStringArrayParam, readStringParam } from "openclaw/plugin-sdk/agent-runtime";
@@ -1,5 +1,4 @@
1
1
  import { h as resolveDiscordOwnerAllowFrom, p as resolveDiscordMemberAllowed } from "./allow-list-CBI-M84K.js";
2
- import { buildUntrustedChannelMetadata, wrapExternalContent } from "openclaw/plugin-sdk/security-runtime";
3
2
  //#region extensions/discord/src/monitor/inbound-context.ts
4
3
  function createDiscordSupplementalContextAccessChecker(params) {
5
4
  return (sender) => {
@@ -21,14 +20,13 @@ function buildDiscordGroupSystemPrompt(channelConfig) {
21
20
  }
22
21
  function buildDiscordUntrustedContext(params) {
23
22
  if (!params.isGuild) return;
24
- const entries = [buildUntrustedChannelMetadata({
23
+ const entries = [];
24
+ if (typeof params.channelTopic === "string" && params.channelTopic.trim().length > 0) entries.push({
25
+ label: "Discord channel metadata",
25
26
  source: "discord",
26
- label: "Discord channel topic",
27
- entries: [params.channelTopic]
28
- }), typeof params.messageBody === "string" && params.messageBody.trim().length > 0 ? wrapExternalContent(`UNTRUSTED Discord message body\n${params.messageBody.trim()}`, {
29
- source: "unknown",
30
- includeWarning: false
31
- }) : void 0].filter((entry) => Boolean(entry));
27
+ type: "channel_metadata",
28
+ payload: { topic: params.channelTopic.trim() }
29
+ });
32
30
  return entries.length > 0 ? entries : void 0;
33
31
  }
34
32
  function buildDiscordInboundAccessContext(params) {
@@ -36,8 +34,7 @@ function buildDiscordInboundAccessContext(params) {
36
34
  groupSystemPrompt: params.isGuild ? buildDiscordGroupSystemPrompt(params.channelConfig) : void 0,
37
35
  untrustedContext: buildDiscordUntrustedContext({
38
36
  isGuild: params.isGuild,
39
- channelTopic: params.channelTopic,
40
- messageBody: params.messageBody
37
+ channelTopic: params.channelTopic
41
38
  }),
42
39
  ownerAllowFrom: resolveDiscordOwnerAllowFrom({
43
40
  channelConfig: params.channelConfig,
@@ -1,10 +1,10 @@
1
1
  import { Ht as parseDiscordTarget, _ as VoiceStateUpdateListener, c as discord_exports, h as ResumedListener, m as ReadyListener } from "./send.receipt-nKLxvA1s.js";
2
2
  import { c as resolveDiscordAccountAllowFrom } from "./accounts-DnNVBDfc.js";
3
3
  import { a as normalizeDiscordSlug, b as formatDiscordUserTag, m as resolveDiscordOwnerAccess } from "./allow-list-CBI-M84K.js";
4
- import { i as formatMention } from "./send.outbound-D8o8BW6q.js";
4
+ import { i as formatMention } from "./send.outbound-BKh71kjw.js";
5
5
  import { t as getDiscordRuntime } from "./runtime-Tqtvj5GX.js";
6
- import { o as authorizeDiscordVoiceIngress, u as resolveDiscordVoiceEnabled } from "./provider-nzJg2k5t.js";
7
- import { t as buildDiscordGroupSystemPrompt } from "./inbound-context-DD7n3Q6U.js";
6
+ import { o as authorizeDiscordVoiceIngress, u as resolveDiscordVoiceEnabled } from "./provider-B81nXBRc.js";
7
+ import { t as buildDiscordGroupSystemPrompt } from "./inbound-context-BdfOEkhj.js";
8
8
  import { createRequire } from "node:module";
9
9
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
10
10
  import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
@@ -1,7 +1,7 @@
1
- import { M as createDiscordRestClient } from "./send.shared-DSpva7uA.js";
2
- import { d as resolveDiscordChannelNameSafe, l as resolveDiscordChannelIdSafe, p as resolveDiscordChannelParentSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-DJACBZJ1.js";
1
+ import { N as createDiscordRestClient } from "./send.shared-Bdj-DP6-.js";
2
+ import { d as resolveDiscordChannelNameSafe, l as resolveDiscordChannelIdSafe, p as resolveDiscordChannelParentSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-BtXi8-Fz.js";
3
3
  import { a as mergeAbortSignals } from "./timeouts-snXNwR4m.js";
4
- import { l as resolveDiscordMessageChannelId, r as resolveDiscordMessageText, s as hasDiscordMessageStickers } from "./message-utils-N5UTOXQ2.js";
4
+ import { c as hasDiscordMessageStickers, d as resolveDiscordMessageChannelId, r as resolveDiscordMessageText } from "./message-utils-CY91O2k2.js";
5
5
  import { t as sendTyping } from "./typing-C_8U8J7E.js";
6
6
  import { danger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
7
7
  import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
@@ -121,7 +121,7 @@ function applyImplicitReplyBatchGate(ctx, replyToMode, isBatched) {
121
121
  //#region extensions/discord/src/monitor/message-run-queue.ts
122
122
  let messageProcessRuntimePromise;
123
123
  async function loadMessageProcessRuntime() {
124
- messageProcessRuntimePromise ??= import("./message-handler.process-Cy7_-0H0.js");
124
+ messageProcessRuntimePromise ??= import("./message-handler.process-Dfu_aSv1.js");
125
125
  return await messageProcessRuntimePromise;
126
126
  }
127
127
  async function processDiscordQueuedMessage(params) {
@@ -173,7 +173,7 @@ function createDiscordMessageRunQueue(params) {
173
173
  //#region extensions/discord/src/monitor/message-handler.ts
174
174
  let messagePreflightRuntimePromise;
175
175
  async function loadMessagePreflightRuntime() {
176
- messagePreflightRuntimePromise ??= import("./message-handler.preflight-C0sT-ewp.js");
176
+ messagePreflightRuntimePromise ??= import("./message-handler.preflight-BMgBVbmR.js");
177
177
  return await messagePreflightRuntimePromise;
178
178
  }
179
179
  function isNonEmptyString(value) {
@@ -1,12 +1,12 @@
1
1
  import { A as Message, c as discord_exports, mt as getChannelMessage } from "./send.receipt-nKLxvA1s.js";
2
2
  import { o as resolveDefaultDiscordAccountId } from "./accounts-DnNVBDfc.js";
3
3
  import { S as resolveTimestampMs, _ as resolveGroupDmAllow, a as normalizeDiscordSlug, b as formatDiscordUserTag, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordGuildEntry, f as resolveDiscordMemberAccessState, g as resolveDiscordShouldRequireMention, i as normalizeDiscordDisplaySlug, n as isDiscordGroupAllowedByPolicy, x as resolveDiscordSystemLocation } from "./allow-list-CBI-M84K.js";
4
- import { t as resolveDiscordConversationIdentity } from "./conversation-identity-C3AI-1tz.js";
4
+ import { t as resolveDiscordConversationIdentity } from "./conversation-identity-Dh8wIQ_K.js";
5
5
  import { l as isRecentlyUnboundThreadWebhookMessage } from "./thread-bindings.state-BdBeo7Rx.js";
6
- import { d as resolveDiscordChannelNameSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-DJACBZJ1.js";
7
- import "./thread-bindings-C1f7Iim4.js";
8
- import { C as resolveDiscordDmCommandAccess, f as buildDiscordRoutePeer, g as handleDiscordDmCommandDecision, h as shouldIgnoreStaleDiscordRouteBinding, m as resolveDiscordEffectiveRoute, p as resolveDiscordConversationRoute, w as resolveDiscordTextCommandAccess } from "./provider-nzJg2k5t.js";
9
- import { c as resolveDiscordChannelInfo, l as resolveDiscordMessageChannelId, r as resolveDiscordMessageText } from "./message-utils-N5UTOXQ2.js";
6
+ import { d as resolveDiscordChannelNameSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-BtXi8-Fz.js";
7
+ import "./thread-bindings-BwcE40jS.js";
8
+ import { C as resolveDiscordDmCommandAccess, f as buildDiscordRoutePeer, g as handleDiscordDmCommandDecision, h as shouldIgnoreStaleDiscordRouteBinding, m as resolveDiscordEffectiveRoute, p as resolveDiscordConversationRoute, w as resolveDiscordTextCommandAccess } from "./provider-B81nXBRc.js";
9
+ import { d as resolveDiscordMessageChannelId, l as resolveDiscordMessageStickers, o as resolveMediaList, r as resolveDiscordMessageText, u as resolveDiscordChannelInfo } from "./message-utils-CY91O2k2.js";
10
10
  import { n as resolveDiscordWebhookId, t as resolveDiscordSenderIdentity } from "./sender-identity-BTGL3VbF.js";
11
11
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
12
12
  import { getChildLogger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
@@ -14,11 +14,12 @@ import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runt
14
14
  import { formatAllowlistMatchMeta } from "openclaw/plugin-sdk/allow-from";
15
15
  import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
16
16
  import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
17
- import { buildMentionRegexes, implicitMentionKindWhen, logInboundDrop, matchesMentionWithExplicit, resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";
17
+ import { mimeTypeFromFilePath } from "openclaw/plugin-sdk/media-mime";
18
+ import { buildMentionRegexes, implicitMentionKindWhen, logInboundDrop, matchesMentionWithExplicit, resolveInboundMentionDecision, toInboundMediaFacts } from "openclaw/plugin-sdk/channel-inbound";
18
19
  import { logDebug } from "openclaw/plugin-sdk/logging-core";
20
+ import { recordDroppedChannelTurnHistory } from "openclaw/plugin-sdk/inbound-reply-dispatch";
19
21
  import { hasControlCommand } from "openclaw/plugin-sdk/command-detection";
20
22
  import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-surface";
21
- import { recordPendingHistoryEntryIfEnabled } from "openclaw/plugin-sdk/reply-history";
22
23
  //#region extensions/discord/src/monitor/message-handler.dm-preflight.ts
23
24
  let conversationRuntimePromise$1;
24
25
  let discordSendRuntimePromise;
@@ -27,7 +28,7 @@ async function loadConversationRuntime$1() {
27
28
  return await conversationRuntimePromise$1;
28
29
  }
29
30
  async function loadDiscordSendRuntime() {
30
- discordSendRuntimePromise ??= import("./send-BqzTEkt9.js").then((n) => n.t);
31
+ discordSendRuntimePromise ??= import("./send-CvXckvRn.js").then((n) => n.t);
31
32
  return await discordSendRuntimePromise;
32
33
  }
33
34
  async function resolveDiscordDmPreflightAccess(params) {
@@ -437,7 +438,7 @@ async function loadSystemEventsRuntime() {
437
438
  return await systemEventsRuntimePromise;
438
439
  }
439
440
  async function loadDiscordThreadingRuntime() {
440
- discordThreadingRuntimePromise ??= import("./provider-nzJg2k5t.js").then((n) => n.v);
441
+ discordThreadingRuntimePromise ??= import("./provider-B81nXBRc.js").then((n) => n.v);
441
442
  return await discordThreadingRuntimePromise;
442
443
  }
443
444
  function isPreflightAborted(abortSignal) {
@@ -560,6 +561,10 @@ async function resolveDiscordPreflightRoute(params) {
560
561
  }
561
562
  //#endregion
562
563
  //#region extensions/discord/src/monitor/message-handler.preflight.ts
564
+ const DISCORD_HISTORY_MEDIA_MAX_ATTACHMENTS = 4;
565
+ const DISCORD_HISTORY_MEDIA_MAX_BYTES = 10 * 1024 * 1024;
566
+ const DISCORD_HISTORY_MEDIA_IDLE_TIMEOUT_MS = 1e3;
567
+ const DISCORD_HISTORY_MEDIA_TOTAL_TIMEOUT_MS = 3e3;
563
568
  function resolveDiscordPreflightConversationKind(params) {
564
569
  const isGroupDm = params.channelType === discord_exports.ChannelType.GroupDM;
565
570
  return {
@@ -567,6 +572,81 @@ function resolveDiscordPreflightConversationKind(params) {
567
572
  isGroupDm
568
573
  };
569
574
  }
575
+ function isDiscordImageAttachmentCandidate(attachment) {
576
+ if ((attachment.content_type?.split(";")[0]?.trim().toLowerCase())?.startsWith("image/")) return true;
577
+ return Boolean(mimeTypeFromFilePath(attachment.filename)?.startsWith("image/") || mimeTypeFromFilePath(attachment.url)?.startsWith("image/"));
578
+ }
579
+ async function resolveDiscordHistoryMediaForPendingRecord(params) {
580
+ const imageAttachments = (params.message.attachments ?? []).filter(isDiscordImageAttachmentCandidate).slice(0, DISCORD_HISTORY_MEDIA_MAX_ATTACHMENTS);
581
+ const stickers = resolveDiscordMessageStickers(params.message).slice(0, Math.max(0, DISCORD_HISTORY_MEDIA_MAX_ATTACHMENTS - imageAttachments.length));
582
+ if (imageAttachments.length === 0 && stickers.length === 0) return [];
583
+ const rawData = (() => {
584
+ try {
585
+ return params.message.rawData;
586
+ } catch {
587
+ return {};
588
+ }
589
+ })();
590
+ const mediaMessage = Object.assign(Object.create(Object.getPrototypeOf(params.message)), params.message);
591
+ Object.defineProperties(mediaMessage, {
592
+ attachments: { value: imageAttachments },
593
+ rawData: { value: {
594
+ ...rawData,
595
+ attachments: imageAttachments,
596
+ sticker_items: stickers,
597
+ stickers
598
+ } },
599
+ stickers: { value: stickers }
600
+ });
601
+ return toInboundMediaFacts(await resolveMediaList(mediaMessage, Math.min(params.preflight.mediaMaxBytes, DISCORD_HISTORY_MEDIA_MAX_BYTES), {
602
+ fetchImpl: params.preflight.discordRestFetch,
603
+ ssrfPolicy: params.preflight.cfg.browser?.ssrfPolicy,
604
+ readIdleTimeoutMs: DISCORD_HISTORY_MEDIA_IDLE_TIMEOUT_MS,
605
+ totalTimeoutMs: DISCORD_HISTORY_MEDIA_TOTAL_TIMEOUT_MS,
606
+ abortSignal: params.preflight.abortSignal
607
+ }), {
608
+ kind: "image",
609
+ messageId: params.message.id
610
+ });
611
+ }
612
+ async function recordDiscordPendingHistoryEntry(params) {
613
+ if (params.preflight.historyLimit <= 0) return;
614
+ await recordDroppedChannelTurnHistory({
615
+ input: {
616
+ id: params.message.id,
617
+ timestamp: params.entry?.timestamp,
618
+ rawText: params.entry?.body ?? "",
619
+ textForAgent: params.entry?.body,
620
+ raw: params.message
621
+ },
622
+ admission: {
623
+ kind: "drop",
624
+ reason: "discord-preflight",
625
+ recordHistory: true
626
+ },
627
+ preflight: {
628
+ message: params.entry ? {
629
+ rawBody: params.entry.body,
630
+ body: params.entry.body,
631
+ bodyForAgent: params.entry.body,
632
+ senderLabel: params.entry.sender,
633
+ envelopeFrom: params.entry.sender
634
+ } : void 0,
635
+ history: {
636
+ key: params.historyKey,
637
+ historyMap: params.preflight.guildHistories,
638
+ limit: params.preflight.historyLimit,
639
+ recordOnDrop: true,
640
+ mediaLimit: DISCORD_HISTORY_MEDIA_MAX_ATTACHMENTS,
641
+ shouldRecord: () => !isPreflightAborted(params.preflight.abortSignal)
642
+ },
643
+ media: () => resolveDiscordHistoryMediaForPendingRecord({
644
+ preflight: params.preflight,
645
+ message: params.message
646
+ })
647
+ }
648
+ });
649
+ }
570
650
  async function preflightDiscordMessage(params) {
571
651
  if (isPreflightAborted(params.abortSignal)) return null;
572
652
  const logger = getChildLogger({ module: "discord-auto-reply" });
@@ -894,11 +974,11 @@ async function preflightDiscordMessage(params) {
894
974
  channelId: messageChannelId,
895
975
  reason: "no-mention"
896
976
  }, "discord: skipping guild message");
897
- recordPendingHistoryEntryIfEnabled({
898
- historyMap: params.guildHistories,
977
+ await recordDiscordPendingHistoryEntry({
978
+ preflight: params,
899
979
  historyKey: messageChannelId,
900
- limit: params.historyLimit,
901
- entry: historyEntry ?? null
980
+ message,
981
+ entry: historyEntry
902
982
  });
903
983
  return null;
904
984
  }
@@ -914,11 +994,11 @@ async function preflightDiscordMessage(params) {
914
994
  if (isGuildMessage && ignoreOtherMentions && hasUserOrRoleMention && !wasMentioned && !mentionDecision.implicitMention) {
915
995
  logDebug(`[discord-preflight] drop: other-mention`);
916
996
  logVerbose(`discord: drop guild message (another user/role mentioned, ignoreOtherMentions=true, botId=${botId})`);
917
- recordPendingHistoryEntryIfEnabled({
918
- historyMap: params.guildHistories,
997
+ await recordDiscordPendingHistoryEntry({
998
+ preflight: params,
919
999
  historyKey: messageChannelId,
920
- limit: params.historyLimit,
921
- entry: historyEntry ?? null
1000
+ message,
1001
+ entry: historyEntry
922
1002
  });
923
1003
  return null;
924
1004
  }
@@ -935,6 +1015,7 @@ async function preflightDiscordMessage(params) {
935
1015
  enqueueSystemEvent(systemText, {
936
1016
  sessionKey: effectiveRoute.sessionKey,
937
1017
  contextKey: `discord:system:${messageChannelId}:${message.id}`,
1018
+ forceSenderIsOwnerFalse: true,
938
1019
  trusted: false
939
1020
  });
940
1021
  return null;