@openclaw/discord 2026.8.1-beta.2 → 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 (100) hide show
  1. package/dist/{account-inspect-CqzrH14k.js → account-inspect-D5xmUpnj.js} +1 -1
  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/{activities-api-DS7vpdtp.js → activities-api-KCBAmWxD.js} +133 -175
  6. package/dist/activities-api.js +1 -1
  7. package/dist/api.js +17 -17
  8. package/dist/{approval-handler.runtime-B6yEV79q.js → approval-handler.runtime-B12RCYr8.js} +6 -6
  9. package/dist/{approval-message-safety-AcIxvrf3.js → approval-message-safety-XGFPbDoI.js} +89 -3
  10. package/dist/{audit-Db-rlntl.js → audit-Yc7eZDd6.js} +5 -5
  11. package/dist/{channel-actions-5s_hjYKd.js → channel-actions-Dr2QI8Bf.js} +10 -6
  12. package/dist/{channel-actions.runtime-CLKrx6tr.js → channel-actions.runtime-CODTvo7c.js} +53 -68
  13. package/dist/{channel-CnnbJSt5.js → channel-cXYzGc4L.js} +74 -50
  14. package/dist/channel-config-api.js +1 -1
  15. package/dist/channel-plugin-api.js +1 -1
  16. package/dist/{channel.setup-BFAO-V1P.js → channel.setup-CSiwnMgs.js} +5 -5
  17. package/dist/{outbound-session-route-DxLkrgKQ.js → components-ezGKo_Yh.js} +3 -49
  18. package/dist/{config-schema-BgEskFAs.js → config-schema-DC5kDtQ5.js} +33 -7
  19. package/dist/conversation-binding-route-D6rCQ5S0.js +43 -0
  20. package/dist/{directory-config-BVX7Cflc.js → directory-config-XyCfoqLg.js} +2 -2
  21. package/dist/directory-contract-api.js +1 -1
  22. package/dist/{directory-live-DGIGxpIo.js → directory-live-Df0NbFJB.js} +3 -3
  23. package/dist/{doctor-BzC-TLnB.js → doctor-DYY31GrO.js} +33 -12
  24. package/dist/doctor-contract-api.js +3 -3
  25. package/dist/{handle-action.guild-admin-BNVTUISF.js → handle-action.guild-admin-6Tvvinsa.js} +2 -2
  26. package/dist/index.js +3 -4
  27. package/dist/{message-handler-Unk_f10F.js → message-handler-B61q5MOF.js} +82 -6
  28. package/dist/{message-handler.preflight-C9zecxR9.js → message-handler.preflight-Bzg_Hawz.js} +36 -46
  29. package/dist/{message-handler.process-DWQ6UHHu.js → message-handler.process--4_712Ec.js} +159 -183
  30. package/dist/{message-utils-BSCPVgy0.js → message-utils-BXLLnFl6.js} +31 -32
  31. package/dist/{outbound-adapter-D9nRivT1.js → outbound-adapter-DxHTOqiN.js} +83 -53
  32. package/dist/{outbound-components-cTzwBJ60.js → outbound-components-B2PL0ooH.js} +3 -3
  33. package/dist/owner-access-Bg41VzAf.js +107 -0
  34. package/dist/{pluralkit-DdiJ9KMK.js → pluralkit-dUl4v1X3.js} +1 -1
  35. package/dist/{probe-Bl-k5_Ku.js → probe-BTdtVRwU.js} +1 -1
  36. package/dist/{probe.runtime-M9fREKvp.js → probe.runtime-Dq5-PRKT.js} +1 -1
  37. package/dist/{provider-DvSNb-2v.js → provider-DlK_ynqt.js} +356 -967
  38. package/dist/{provider-session.runtime-BUEqD0rA.js → provider-session.runtime-CvvphHvs.js} +3 -3
  39. package/dist/provider.runtime-CzKGRiAF.js +2 -0
  40. package/dist/{realtime-session.runtime-C7wen-aF.js → realtime-session.runtime-ysbMG8v7.js} +24 -13
  41. package/dist/{resolve-allowlist-common-D04lpEzb.js → resolve-allowlist-common-DIVXbD1P.js} +2 -2
  42. package/dist/{resolve-channels-Dm7jEeg6.js → resolve-channels-CGeUoIqb.js} +3 -3
  43. package/dist/{resolve-users-bktrCUUU.js → resolve-users-BtKxLUZv.js} +2 -2
  44. package/dist/{retry-CLpJcXXf.js → retry-DNsVTeTo.js} +18 -64
  45. package/dist/{runtime-DoHjckYm.js → runtime-CQovMsH3.js} +9 -10
  46. package/dist/{runtime-DGsSyDTS.js → runtime-D71_VFLr.js} +29 -43
  47. package/dist/runtime-api.actions.js +2 -2
  48. package/dist/runtime-api.js +22 -21
  49. package/dist/runtime-api.lookup.js +5 -5
  50. package/dist/runtime-api.monitor-CzeTYF32.js +6 -0
  51. package/dist/runtime-api.monitor.js +6 -5
  52. package/dist/runtime-api.send.js +6 -6
  53. package/dist/runtime-api.threads.js +4 -4
  54. package/dist/{sdk-runtime-QpY8PvCh.js → sdk-runtime-37OU6_Yh.js} +3 -4
  55. package/dist/{secret-config-contract-B1akrlyY.js → secret-config-contract-B3i6WxV5.js} +53 -25
  56. package/dist/secret-contract-api.js +1 -1
  57. package/dist/security-audit-contract-api.js +1 -1
  58. package/dist/{security-audit.runtime-CPN0xFYz.js → security-audit.runtime-BVKF9VtY.js} +1 -1
  59. package/dist/{send-B7Q6Oc1I.js → send-rQIffSYu.js} +10 -10
  60. package/dist/{send.components-iJyFXw9L.js → send.components-ChK1wS7w.js} +14 -24
  61. package/dist/{send.outbound-DS5tHwfR.js → send.outbound-HIkgji_7.js} +26 -16
  62. package/dist/{send.reactions-BAn0iiVQ.js → send.reactions-gmJ6yFPo.js} +2 -2
  63. package/dist/{send.receipt-IPI1p-SP.js → send.receipt-Cnhoautb.js} +11 -1
  64. package/dist/{send.shared-BmwFjW6T.js → send.shared-B3fpaLWJ.js} +104 -104
  65. package/dist/{sender-identity-QtalnCYv.js → sender-identity-BJtfyise.js} +1 -1
  66. package/dist/setup-plugin-api.js +1 -1
  67. package/dist/{shared-BIXIX6uJ.js → shared-CaAaoksy.js} +15 -10
  68. package/dist/subagent-hooks-CNT2ZJTJ.js +49 -0
  69. package/dist/subagent-hooks-api.js +2 -2
  70. package/dist/{subagent-progress-DhaE_h8a.js → subagent-progress-FPLqBY1s.js} +5 -4
  71. package/dist/{system-events-CTqDf6_s.js → system-events-Nuwoq_au.js} +2 -2
  72. package/dist/{target-resolver-maOKSqO0.js → target-resolver-DIXShHaZ.js} +3 -3
  73. package/dist/targets-B2pf49zc.js +3 -0
  74. package/dist/{thread-bindings-3L8p82GV.js → thread-bindings-VlymUnbz.js} +29 -26
  75. package/dist/{thread-bindings.manager-DCIH6WDC.js → thread-bindings.manager-CngsgErq.js} +9 -8
  76. package/dist/{thread-bindings.session-updates-bJ2KQFY6.js → thread-bindings.session-updates-CJb-BpPL.js} +1 -1
  77. package/dist/{thread-bindings.state-aeV8HNgV.js → thread-bindings.state-D8OMdk4O.js} +1 -1
  78. package/dist/threading-DU6pgeGm.js +456 -0
  79. package/dist/transcripts-source-DeIMNbRh.js +265 -0
  80. package/dist/transcripts-source-api.js +7 -2
  81. package/dist/{typing-CS-nNVoe.js → typing-oLiS5Z13.js} +1 -1
  82. package/dist/{voice-runtime-BEdqNcST.js → voice-runtime-CjNFaynA.js} +181 -91
  83. package/openclaw.plugin.json +12 -6
  84. package/package.json +4 -6
  85. package/dist/accounts-DJTf1LtA.js +0 -219
  86. package/dist/channel-api-CAJ0wMoV.js +0 -21
  87. package/dist/provider.runtime-C9PnJZbZ.js +0 -2
  88. package/dist/runtime-api.monitor-CHxrFPnW.js +0 -5
  89. package/dist/subagent-hooks-CTt5KCJr.js +0 -120
  90. package/dist/targets-yUFTHoAx.js +0 -3
  91. package/dist/transcripts-source-CfFMexGt.js +0 -123
  92. package/node_modules/p-map/index.d.ts +0 -155
  93. package/node_modules/p-map/index.js +0 -285
  94. package/node_modules/p-map/license +0 -9
  95. package/node_modules/p-map/package.json +0 -57
  96. package/node_modules/p-map/readme.md +0 -190
  97. package/dist/{allow-list-DnxIlPP2.js → allow-list-BDMimASD.js} +1 -1
  98. package/dist/{audit-core-xwjIczO0.js → audit-core-BCX8UeFH.js} +1 -1
  99. package/dist/{doctor-contract-DLa-BTiU.js → doctor-contract-DsWvKIXF.js} +1 -1
  100. package/dist/{security-audit-jGnJF__m.js → security-audit-BfJhAXZp.js} +1 -1
@@ -1,17 +1,17 @@
1
- import { m as resolveDiscordChannelId, p as parseDiscordTarget } from "./retry-CLpJcXXf.js";
2
- import { a as buildDiscordPresentationComponents, i as buildDiscordInteractiveComponents } from "./outbound-session-route-DxLkrgKQ.js";
3
- import { a as readDiscordAutoArchiveDurationParam, t as handleDiscordAction } from "./runtime-DGsSyDTS.js";
4
- import "./targets-yUFTHoAx.js";
1
+ import { i as buildDiscordPresentationComponents, r as buildDiscordInteractiveComponents } from "./components-ezGKo_Yh.js";
2
+ import { A as resolveDiscordChannelId, k as parseDiscordTarget } from "./accounts-DNl-oCEw.js";
3
+ import { a as readDiscordAutoArchiveDurationParam, t as handleDiscordAction } from "./runtime-D71_VFLr.js";
4
+ import "./targets-B2pf49zc.js";
5
5
  import "./action-runtime-api.js";
6
6
  import { t as discordInboundEventDelivery } from "./inbound-event-delivery-De2qxTrP.js";
7
- import { r as isDiscordComponentSpecWithinMessageLimit, t as DISCORD_PRESENTATION_CAPABILITIES } from "./outbound-components-cTzwBJ60.js";
8
- import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-BNVTUISF.js";
7
+ import { r as isDiscordComponentSpecWithinMessageLimit, t as DISCORD_PRESENTATION_CAPABILITIES } from "./outbound-components-B2PL0ooH.js";
8
+ import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-6Tvvinsa.js";
9
9
  import { n as notifyDiscordActiveTurnThreadCreated, r as notifyDiscordActiveTurnThreadReplyDelivered } from "./active-turn-thread-route-fmHl1HNd.js";
10
10
  import { normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
11
11
  import { resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
12
- import { adaptMessagePresentationForChannel, normalizeLegacyInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText } from "openclaw/plugin-sdk/interactive-runtime";
13
12
  import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
14
- import { readPositiveIntegerParam, readStringArrayParam, readStringParam as readStringParam$1 } from "openclaw/plugin-sdk/agent-runtime";
13
+ import { adaptMessagePresentationForChannel, normalizeLegacyInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText } from "openclaw/plugin-sdk/interactive-runtime";
14
+ import { readPositiveIntegerParam, readStringArrayParam, readStringParam } from "openclaw/plugin-sdk/agent-runtime";
15
15
  //#region extensions/discord/src/actions/handle-action.ts
16
16
  const providerId = "discord";
17
17
  function withCurrentSourceReplyRoute(result) {
@@ -31,7 +31,7 @@ function readCurrentDiscordTarget(toolContext) {
31
31
  }
32
32
  async function handleDiscordMessageAction(ctx) {
33
33
  const { action, params, cfg } = ctx;
34
- const accountId = ctx.accountId ?? readStringParam$1(params, "accountId");
34
+ const accountId = ctx.accountId ?? readStringParam(params, "accountId");
35
35
  const readContext = ctx.requesterAccountId && ctx.toolContext?.currentChannelProvider && ctx.toolContext.currentChannelId ? {
36
36
  requesterAccountId: ctx.requesterAccountId,
37
37
  currentChannelProvider: ctx.toolContext.currentChannelProvider,
@@ -45,6 +45,7 @@ async function handleDiscordMessageAction(ctx) {
45
45
  mediaAccess: ctx.mediaAccess,
46
46
  mediaLocalRoots: ctx.mediaLocalRoots,
47
47
  mediaReadFile: ctx.mediaReadFile,
48
+ ...ctx.reply ? { reply: ctx.reply } : {},
48
49
  ...readPolicyOptions
49
50
  };
50
51
  const notifyVisibleOutbound = (result, to, fallbackSessionKey) => {
@@ -72,21 +73,21 @@ async function handleDiscordMessageAction(ctx) {
72
73
  return result;
73
74
  };
74
75
  const readTarget = () => {
75
- const target = readStringParam$1(params, "channelId") ?? readStringParam$1(params, "to") ?? readCurrentDiscordTarget(ctx.toolContext);
76
+ const target = readStringParam(params, "channelId") ?? readStringParam(params, "to") ?? readCurrentDiscordTarget(ctx.toolContext);
76
77
  if (!target) throw new Error("Discord channel target is required (use channel:<id>).");
77
78
  return target;
78
79
  };
79
80
  const resolveChannelId = () => resolveDiscordChannelId(readTarget());
80
81
  const readSendTarget = () => {
81
- const target = readStringParam$1(params, "to") ?? readStringParam$1(params, "target") ?? readCurrentDiscordTarget(ctx.toolContext);
82
+ const target = readStringParam(params, "to") ?? readStringParam(params, "target") ?? readCurrentDiscordTarget(ctx.toolContext);
82
83
  if (!target) throw new Error("Discord channel target is required (use channel:<id>).");
83
84
  return target;
84
85
  };
85
86
  if (action === "send") {
86
87
  const to = readSendTarget();
87
88
  const asVoice = readBooleanParam(params, "asVoice") === true;
88
- const mediaUrl = readStringParam$1(params, "media", { trim: false }) ?? readStringParam$1(params, "path", { trim: false }) ?? readStringParam$1(params, "filePath", { trim: false });
89
- const requestedContent = readStringParam$1(params, "message", { allowEmpty: true });
89
+ const mediaUrl = readStringParam(params, "media", { trim: false }) ?? readStringParam(params, "path", { trim: false }) ?? readStringParam(params, "filePath", { trim: false });
90
+ const requestedContent = readStringParam(params, "message", { allowEmpty: true });
90
91
  const presentation = params.components == null ? normalizeMessagePresentation(params.presentation) : void 0;
91
92
  const adaptedPresentation = presentation ? adaptMessagePresentationForChannel({
92
93
  presentation,
@@ -102,23 +103,23 @@ async function handleDiscordMessageAction(ctx) {
102
103
  const rawComponents = presentationFellBack ? void 0 : params.components ?? presentationComponents ?? buildDiscordInteractiveComponents(normalizeLegacyInteractiveReply(params.interactive));
103
104
  const hasComponents = Boolean(rawComponents) && (typeof rawComponents === "function" || typeof rawComponents === "object");
104
105
  const components = hasComponents ? rawComponents : void 0;
105
- const content = readStringParam$1(params, "message", {
106
- required: !asVoice && !hasComponents && !mediaUrl && !presentationFellBack,
106
+ const rawEmbeds = params.embeds;
107
+ const embeds = Array.isArray(rawEmbeds) ? rawEmbeds : void 0;
108
+ const content = readStringParam(params, "message", {
109
+ required: !asVoice && !hasComponents && !embeds?.length && !mediaUrl && !presentationFellBack,
107
110
  allowEmpty: true
108
111
  });
109
112
  const deliveryContent = presentationFellBack && adaptedPresentation ? renderMessagePresentationFallbackText({
110
113
  text: content,
111
114
  presentation: adaptedPresentation
112
115
  }) : content;
113
- const filename = readStringParam$1(params, "filename");
114
- const replyTo = readStringParam$1(params, "replyTo");
115
- const rawEmbeds = params.embeds;
116
- const embeds = Array.isArray(rawEmbeds) ? rawEmbeds : void 0;
116
+ const filename = readStringParam(params, "filename");
117
+ const replyTo = readStringParam(params, "replyTo");
117
118
  const silent = readBooleanParam(params, "silent") === true;
118
119
  const suppressEmbeds = readBooleanParam(params, "suppressEmbeds");
119
- const sessionKey = readStringParam$1(params, "__sessionKey");
120
- const agentId = readStringParam$1(params, "__agentId");
121
- const threadName = readStringParam$1(params, "threadName");
120
+ const sessionKey = readStringParam(params, "__sessionKey");
121
+ const agentId = readStringParam(params, "__agentId");
122
+ const threadName = readStringParam(params, "threadName");
122
123
  const result = await handleDiscordAction({
123
124
  action: "sendMessage",
124
125
  accountId: accountId ?? void 0,
@@ -141,15 +142,18 @@ async function handleDiscordMessageAction(ctx) {
141
142
  }
142
143
  if (action === "upload-file") {
143
144
  const to = readSendTarget();
144
- const mediaUrl = readStringParam$1(params, "filePath", { trim: false }) ?? readStringParam$1(params, "path", { trim: false }) ?? readStringParam$1(params, "media", { trim: false });
145
- if (!mediaUrl) throw new Error("upload-file requires filePath, path, or media.");
146
- const content = readStringParam$1(params, "message", { allowEmpty: true }) ?? readStringParam$1(params, "content", { allowEmpty: true });
147
- const filename = readStringParam$1(params, "filename");
148
- const replyTo = readStringParam$1(params, "replyTo");
145
+ const mediaUrl = readStringParam(params, "filePath", { trim: false }) ?? readStringParam(params, "path", { trim: false }) ?? readStringParam(params, "media", { trim: false });
146
+ if (!mediaUrl) {
147
+ if (readStringParam(params, "buffer", { trim: false })) throw new Error("Use action: \"send\" for base64 buffer attachments; upload-file requires filePath, path, or media.");
148
+ throw new Error("upload-file requires filePath, path, or media.");
149
+ }
150
+ const content = readStringParam(params, "message", { allowEmpty: true }) ?? readStringParam(params, "content", { allowEmpty: true }) ?? readStringParam(params, "caption", { allowEmpty: true });
151
+ const filename = readStringParam(params, "filename");
152
+ const replyTo = readStringParam(params, "replyTo");
149
153
  const silent = readBooleanParam(params, "silent") === true;
150
154
  const suppressEmbeds = readBooleanParam(params, "suppressEmbeds");
151
- const sessionKey = readStringParam$1(params, "__sessionKey");
152
- const agentId = readStringParam$1(params, "__agentId");
155
+ const sessionKey = readStringParam(params, "__sessionKey");
156
+ const agentId = readStringParam(params, "__agentId");
153
157
  const result = await handleDiscordAction({
154
158
  action: "sendMessage",
155
159
  accountId: accountId ?? void 0,
@@ -166,32 +170,13 @@ async function handleDiscordMessageAction(ctx) {
166
170
  notifyVisibleOutbound(result, to, sessionKey);
167
171
  return withAdoptedThreadReplyRoute(result, to, sessionKey);
168
172
  }
169
- if (action === "poll") {
170
- const to = readStringParam$1(params, "to", { required: true });
171
- const question = readStringParam$1(params, "pollQuestion", { required: true });
172
- const answers = readStringArrayParam(params, "pollOption", { required: true });
173
- const allowMultiselect = readBooleanParam(params, "pollMulti");
174
- const durationHours = readPositiveIntegerParam(params, "pollDurationHours");
175
- const result = await handleDiscordAction({
176
- action: "poll",
177
- accountId: accountId ?? void 0,
178
- to,
179
- question,
180
- answers,
181
- allowMultiselect,
182
- durationHours: durationHours ?? void 0,
183
- content: readStringParam$1(params, "message")
184
- }, cfg, actionOptions);
185
- notifyVisibleOutbound(result, to);
186
- return result;
187
- }
188
173
  if (action === "react") {
189
174
  const messageId = normalizeOptionalStringifiedId(resolveReactionMessageId({
190
175
  args: params,
191
176
  toolContext: ctx.toolContext
192
177
  })) ?? "";
193
178
  if (!messageId) throw new Error("messageId required. Provide messageId explicitly or react to the current inbound message.");
194
- const emoji = readStringParam$1(params, "emoji", { allowEmpty: true });
179
+ const emoji = readStringParam(params, "emoji", { allowEmpty: true });
195
180
  const remove = readBooleanParam(params, "remove");
196
181
  return await handleDiscordAction({
197
182
  action: "react",
@@ -203,7 +188,7 @@ async function handleDiscordMessageAction(ctx) {
203
188
  }, cfg, actionOptions);
204
189
  }
205
190
  if (action === "reactions") {
206
- const messageId = readStringParam$1(params, "messageId", { required: true });
191
+ const messageId = readStringParam(params, "messageId", { required: true });
207
192
  const limit = readPositiveIntegerParam(params, "limit");
208
193
  return await handleDiscordAction({
209
194
  action: "reactions",
@@ -220,14 +205,14 @@ async function handleDiscordMessageAction(ctx) {
220
205
  accountId: accountId ?? void 0,
221
206
  channelId: resolveChannelId(),
222
207
  limit,
223
- before: readStringParam$1(params, "before"),
224
- after: readStringParam$1(params, "after"),
225
- around: readStringParam$1(params, "around")
208
+ before: readStringParam(params, "before"),
209
+ after: readStringParam(params, "after"),
210
+ around: readStringParam(params, "around")
226
211
  }, cfg, actionOptions);
227
212
  }
228
213
  if (action === "edit") {
229
- const messageId = readStringParam$1(params, "messageId", { required: true });
230
- const content = readStringParam$1(params, "message", { required: true });
214
+ const messageId = readStringParam(params, "messageId", { required: true });
215
+ const content = readStringParam(params, "message", { required: true });
231
216
  return await handleDiscordAction({
232
217
  action: "editMessage",
233
218
  accountId: accountId ?? void 0,
@@ -237,7 +222,7 @@ async function handleDiscordMessageAction(ctx) {
237
222
  }, cfg, actionOptions);
238
223
  }
239
224
  if (action === "delete") {
240
- const messageId = readStringParam$1(params, "messageId", { required: true });
225
+ const messageId = readStringParam(params, "messageId", { required: true });
241
226
  return await handleDiscordAction({
242
227
  action: "deleteMessage",
243
228
  accountId: accountId ?? void 0,
@@ -246,7 +231,7 @@ async function handleDiscordMessageAction(ctx) {
246
231
  }, cfg, actionOptions);
247
232
  }
248
233
  if (action === "pin" || action === "unpin" || action === "list-pins") {
249
- const messageId = action === "list-pins" ? void 0 : readStringParam$1(params, "messageId", { required: true });
234
+ const messageId = action === "list-pins" ? void 0 : readStringParam(params, "messageId", { required: true });
250
235
  return await handleDiscordAction({
251
236
  action: action === "pin" ? "pinMessage" : action === "unpin" ? "unpinMessage" : "listPins",
252
237
  accountId: accountId ?? void 0,
@@ -260,9 +245,9 @@ async function handleDiscordMessageAction(ctx) {
260
245
  channelId: resolveChannelId()
261
246
  }, cfg, actionOptions);
262
247
  if (action === "thread-create") {
263
- const name = readStringParam$1(params, "threadName", { required: true });
264
- const messageId = readStringParam$1(params, "messageId");
265
- const content = readStringParam$1(params, "message");
248
+ const name = readStringParam(params, "threadName", { required: true });
249
+ const messageId = readStringParam(params, "messageId");
250
+ const content = readStringParam(params, "message");
266
251
  const autoArchiveMinutes = readDiscordAutoArchiveDurationParam(params, "autoArchiveMin");
267
252
  const appliedTags = readStringArrayParam(params, "appliedTags");
268
253
  const result = await handleDiscordAction({
@@ -290,7 +275,7 @@ async function handleDiscordMessageAction(ctx) {
290
275
  return result;
291
276
  }
292
277
  if (action === "sticker") {
293
- const to = readStringParam$1(params, "to", { required: true });
278
+ const to = readStringParam(params, "to", { required: true });
294
279
  const stickerIds = readStringArrayParam(params, "stickerId", {
295
280
  required: true,
296
281
  label: "sticker-id"
@@ -300,7 +285,7 @@ async function handleDiscordMessageAction(ctx) {
300
285
  accountId: accountId ?? void 0,
301
286
  to,
302
287
  stickerIds,
303
- content: readStringParam$1(params, "message")
288
+ content: readStringParam(params, "message")
304
289
  }, cfg, actionOptions);
305
290
  notifyVisibleOutbound(result, to);
306
291
  return result;
@@ -308,11 +293,11 @@ async function handleDiscordMessageAction(ctx) {
308
293
  if (action === "set-presence") return await handleDiscordAction({
309
294
  action: "setPresence",
310
295
  accountId: accountId ?? void 0,
311
- status: readStringParam$1(params, "status"),
312
- activityType: readStringParam$1(params, "activityType"),
313
- activityName: readStringParam$1(params, "activityName"),
314
- activityUrl: readStringParam$1(params, "activityUrl"),
315
- activityState: readStringParam$1(params, "activityState")
296
+ status: readStringParam(params, "status"),
297
+ activityType: readStringParam(params, "activityType"),
298
+ activityName: readStringParam(params, "activityName"),
299
+ activityUrl: readStringParam(params, "activityUrl"),
300
+ activityState: readStringParam(params, "activityState")
316
301
  }, cfg, actionOptions);
317
302
  const adminResult = await tryHandleDiscordMessageActionGuildAdmin({
318
303
  ctx,
@@ -322,7 +307,7 @@ async function handleDiscordMessageAction(ctx) {
322
307
  });
323
308
  if (adminResult !== void 0) {
324
309
  if (action === "thread-reply") {
325
- const threadId = readStringParam$1(params, "threadId") ?? readTarget();
310
+ const threadId = readStringParam(params, "threadId") ?? readTarget();
326
311
  notifyVisibleOutbound(adminResult, threadId);
327
312
  return withAdoptedThreadReplyRoute(adminResult, threadId);
328
313
  }
@@ -1,22 +1,21 @@
1
- import { d as normalizeDiscordMessagingTarget, p as parseDiscordTarget, u as looksLikeDiscordTargetId } from "./retry-CLpJcXXf.js";
2
- import { c as resolveDiscordAccountAllowFrom, i as listEnabledDiscordAccounts, o as resolveDefaultDiscordAccountId, r as listDiscordAccountIds, s as resolveDiscordAccount } from "./accounts-DJTf1LtA.js";
3
- import { t as resolveDiscordOutboundSessionRoute } from "./outbound-session-route-DxLkrgKQ.js";
1
+ import { d as normalizeDiscordMessagingTarget, u as looksLikeDiscordTargetId } from "./retry-DNsVTeTo.js";
2
+ import { F as projectCredentialSnapshotFields, I as resolveConfiguredFromCredentialStatuses, M as PAIRING_APPROVED_MESSAGE, N as buildTokenChannelStatusSummary, O as resolveDiscordOutboundSessionRoute, c as resolveDiscordAccount, i as listDiscordStartupAccountIds, j as DEFAULT_ACCOUNT_ID, k as parseDiscordTarget, l as resolveDiscordAccountAllowFrom, r as listDiscordAccountIds, s as resolveDefaultDiscordAccountId } from "./accounts-DNl-oCEw.js";
4
3
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
5
- import { a as projectCredentialSnapshotFields, n as PAIRING_APPROVED_MESSAGE, o as resolveConfiguredFromCredentialStatuses, r as buildTokenChannelStatusSummary, t as DEFAULT_ACCOUNT_ID } from "./channel-api-CAJ0wMoV.js";
6
4
  import { u as withAbortTimeout } from "./timeouts-B9cy6RvQ.js";
7
- import { a as getDiscordExecApprovalApprovers, c as shouldSuppressLocalDiscordExecApprovalPrompt, d as createChannelNativeOriginTargetResolver, f as isChannelExecApprovalClientEnabledFromConfig, i as resolveDiscordCurrentConversationIdentity, l as createApproverRestrictedNativeApprovalCapability, o as isDiscordExecApprovalApprover, p as matchesApprovalRequestFilters, s as isDiscordExecApprovalClientEnabled, u as createChannelApproverDmTargetResolver } from "./approval-message-safety-AcIxvrf3.js";
8
- import { r as resolveRequiredDiscordChannelPermissions } from "./audit-core-xwjIczO0.js";
9
- import { t as discordMessageActions$1 } from "./channel-actions-5s_hjYKd.js";
5
+ import { _ as createChannelApproverDmTargetResolver, b as matchesApprovalRequestFilters, d as resolveDiscordRuntimeBindingConversationId, f as getDiscordExecApprovalApprovers, g as createApproverRestrictedNativeApprovalCapability, h as shouldSuppressLocalDiscordExecApprovalPrompt, m as isDiscordExecApprovalClientEnabled, o as resolveDiscordConversationRoute, p as isDiscordExecApprovalApprover, u as resolveDiscordCurrentConversationIdentity, v as createChannelNativeOriginTargetResolver, y as isChannelExecApprovalClientEnabledFromConfig } from "./approval-message-safety-XGFPbDoI.js";
6
+ import { r as resolveRequiredDiscordChannelPermissions } from "./audit-core-BCX8UeFH.js";
7
+ import { t as discordMessageActions } from "./channel-actions-Dr2QI8Bf.js";
10
8
  import { r as openDiscordCommandDeployHashStore } from "./command-deploy-store-DFkBTViB.js";
11
- import { n as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-bJ2KQFY6.js";
12
- import { n as discordOutbound } from "./outbound-adapter-D9nRivT1.js";
13
- import { a as discordSecurityAdapter, i as discordSetupContract, n as discordConfigAdapter, t as createDiscordPluginBase } from "./shared-BIXIX6uJ.js";
9
+ import { t as resolveDiscordConversationBindingRoute } from "./conversation-binding-route-D6rCQ5S0.js";
10
+ import { n as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-CJb-BpPL.js";
11
+ import { n as discordOutbound } from "./outbound-adapter-DxHTOqiN.js";
12
+ import { a as discordSecurityAdapter, i as discordSetupContract, n as discordConfigAdapter, t as createDiscordPluginBase } from "./shared-CaAaoksy.js";
14
13
  import { t as normalizeExplicitDiscordSessionKey } from "./session-key-normalization-wJgsKPNF.js";
15
14
  import { t as defaultTopLevelPlacement } from "./thread-binding-api-BDZJD4na.js";
16
- import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
17
15
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
18
- import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
16
+ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
19
17
  import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
18
+ import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
20
19
  import { createChannelMessageAdapterFromOutbound } from "openclaw/plugin-sdk/channel-outbound";
21
20
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
22
21
  import { buildLegacyDmAccountAllowlistAdapter, createAccountScopedAllowlistNameResolver, createNestedAllowlistOverrideResolver } from "openclaw/plugin-sdk/allowlist-config-edit";
@@ -26,6 +25,7 @@ import { appendMatchMetadata, createComputedAccountStatusAdapter, createDefaultC
26
25
  import { resolveTargetsWithOptionalToken } from "openclaw/plugin-sdk/target-resolver-runtime";
27
26
  import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
28
27
  import { doesApprovalRequestSelectChannelAccount, resolveApprovalRequestSessionConversation } from "openclaw/plugin-sdk/approval-native-runtime";
28
+ import { resolveThreadBindingSpawnPolicy } from "openclaw/plugin-sdk/conversation-runtime";
29
29
  import { resolveScopeRequireMention, resolveScopeToolsPolicy, scopeKey } from "openclaw/plugin-sdk/channel-policy";
30
30
  import { normalizeAtHashSlug } from "openclaw/plugin-sdk/string-normalization-runtime";
31
31
  //#region extensions/discord/src/approval-shared.ts
@@ -194,7 +194,7 @@ function createDiscordApprovalCapability(configOverride) {
194
194
  request,
195
195
  configOverride
196
196
  }),
197
- load: async () => (await import("./approval-handler.runtime-B6yEV79q.js")).discordApprovalNativeRuntime
197
+ load: async () => (await import("./approval-handler.runtime-B12RCYr8.js")).discordApprovalNativeRuntime
198
198
  })
199
199
  });
200
200
  }
@@ -301,22 +301,70 @@ function resolveDiscordInboundConversation(params) {
301
301
  }
302
302
  //#endregion
303
303
  //#region extensions/discord/src/channel.loaders.ts
304
- const loadDiscordDirectoryConfigModule = createLazyRuntimeModule(() => import("./directory-config-BVX7Cflc.js").then((n) => n.t));
305
- const loadDiscordResolveChannelsModule = createLazyRuntimeModule(() => import("./resolve-channels-Dm7jEeg6.js").then((n) => n.n));
306
- const loadDiscordResolveUsersModule = createLazyRuntimeModule(() => import("./resolve-users-bktrCUUU.js").then((n) => n.n));
307
- const loadDiscordThreadBindingsManagerModule = createLazyRuntimeModule(() => import("./thread-bindings.manager-DCIH6WDC.js").then((n) => n.i));
308
- const loadDiscordTargetResolverModule = createLazyRuntimeModule(() => import("./target-resolver-maOKSqO0.js").then((n) => n.r));
309
- const loadDiscordProviderRuntime = createLazyRuntimeModule(() => import("./provider.runtime-C9PnJZbZ.js"));
310
- const loadDiscordProbeRuntime = createLazyRuntimeModule(() => import("./probe.runtime-M9fREKvp.js"));
304
+ const loadDiscordDirectoryConfigModule = createLazyRuntimeModule(() => import("./directory-config-XyCfoqLg.js").then((n) => n.t));
305
+ const loadDiscordResolveChannelsModule = createLazyRuntimeModule(() => import("./resolve-channels-CGeUoIqb.js").then((n) => n.n));
306
+ const loadDiscordResolveUsersModule = createLazyRuntimeModule(() => import("./resolve-users-BtKxLUZv.js").then((n) => n.n));
307
+ const loadDiscordThreadBindingsManagerModule = createLazyRuntimeModule(() => import("./thread-bindings.manager-CngsgErq.js").then((n) => n.i));
308
+ const loadDiscordTargetResolverModule = createLazyRuntimeModule(() => import("./target-resolver-DIXShHaZ.js").then((n) => n.r));
309
+ const loadDiscordProviderRuntime = createLazyRuntimeModule(() => import("./provider.runtime-CzKGRiAF.js"));
310
+ const loadDiscordProbeRuntime = createLazyRuntimeModule(() => import("./probe.runtime-Dq5-PRKT.js"));
311
311
  async function probeDiscordStatusAccount(params) {
312
312
  const startedAtMs = Date.now();
313
313
  const runtime = await loadDiscordProbeRuntime();
314
314
  const remainingMs = Math.max(1, params.timeoutMs - Math.max(0, Date.now() - startedAtMs));
315
315
  return await runtime.probeDiscord(params.token, remainingMs, { includeApplication: true });
316
316
  }
317
- const loadDiscordAuditModule = createLazyRuntimeModule(() => import("./audit-Db-rlntl.js").then((n) => n.n));
318
- const loadDiscordSendModule = createLazyRuntimeModule(() => import("./send-B7Q6Oc1I.js").then((n) => n.t));
319
- const loadDiscordDirectoryLiveModule = createLazyRuntimeModule(() => import("./directory-live-DGIGxpIo.js").then((n) => n.t));
317
+ const loadDiscordAuditModule = createLazyRuntimeModule(() => import("./audit-Yc7eZDd6.js").then((n) => n.n));
318
+ const loadDiscordSendModule = createLazyRuntimeModule(() => import("./send-rQIffSYu.js").then((n) => n.t));
319
+ const loadDiscordDirectoryLiveModule = createLazyRuntimeModule(() => import("./directory-live-Df0NbFJB.js").then((n) => n.t));
320
+ //#endregion
321
+ //#region extensions/discord/src/conversation-route-owner.ts
322
+ function inspectDiscordConversationRouteOwner(params) {
323
+ const direct = params.conversation.kind === "direct";
324
+ const nativeConversationId = params.conversation.nativeChannelId ?? params.conversation.peerId;
325
+ const threadConversationId = direct ? void 0 : params.conversation.threadId;
326
+ const runtimeConversationId = threadConversationId ?? resolveDiscordRuntimeBindingConversationId({
327
+ isDirectMessage: direct,
328
+ isGroupDm: params.conversation.kind === "group",
329
+ userId: direct ? params.conversation.peerId : void 0,
330
+ channelId: nativeConversationId
331
+ });
332
+ const route = resolveDiscordConversationRoute({
333
+ cfg: params.cfg,
334
+ accountId: params.accountId,
335
+ guildId: params.conversation.context?.guildId,
336
+ memberRoleIds: params.conversation.context?.memberRoleIds,
337
+ peer: {
338
+ kind: params.conversation.kind,
339
+ id: params.conversation.peerId
340
+ },
341
+ parentConversationId: params.conversation.context?.parentPeerId
342
+ });
343
+ const { runtimeRoute, configuredRoute } = resolveDiscordConversationBindingRoute({
344
+ cfg: params.cfg,
345
+ route,
346
+ accountId: params.accountId,
347
+ runtimeConversationId,
348
+ configuredConversationId: threadConversationId ?? nativeConversationId,
349
+ parentConversationId: params.conversation.context?.parentPeerId,
350
+ touchBinding: false
351
+ });
352
+ if (!runtimeRoute.bindingOwnerAvailable && resolveThreadBindingSpawnPolicy({
353
+ cfg: params.cfg,
354
+ channel: "discord",
355
+ accountId: params.accountId,
356
+ kind: "subagent"
357
+ }).enabled) return { kind: "unavailable" };
358
+ if (runtimeRoute.pluginId) return {
359
+ kind: "plugin",
360
+ pluginId: runtimeRoute.pluginId,
361
+ fallbackAgentId: route.agentId
362
+ };
363
+ return {
364
+ kind: "agent",
365
+ agentId: runtimeRoute.boundAgentId ?? configuredRoute?.boundAgentId ?? route.agentId
366
+ };
367
+ }
320
368
  //#endregion
321
369
  //#region extensions/discord/src/group-policy.ts
322
370
  function normalizeDiscordSlug(value) {
@@ -513,34 +561,8 @@ function startDiscordStartupProbe(params) {
513
561
  function shouldTreatDiscordDeliveredTextAsVisible(params) {
514
562
  return params.kind === "block" && typeof params.text === "string" && params.text.trim().length > 0;
515
563
  }
516
- function resolveRuntimeDiscordMessageActions() {
517
- try {
518
- return getDiscordRuntime().channel?.discord?.messageActions ?? null;
519
- } catch {
520
- return null;
521
- }
522
- }
523
- const discordMessageActions = {
524
- resolveExecutionMode: (ctx) => resolveRuntimeDiscordMessageActions()?.resolveExecutionMode?.(ctx) ?? discordMessageActions$1.resolveExecutionMode?.(ctx) ?? "local",
525
- describeMessageTool: (ctx) => resolveRuntimeDiscordMessageActions()?.describeMessageTool?.(ctx) ?? discordMessageActions$1.describeMessageTool?.(ctx) ?? null,
526
- requiresTrustedRequesterSender: (ctx) => resolveRuntimeDiscordMessageActions()?.requiresTrustedRequesterSender?.(ctx) ?? discordMessageActions$1.requiresTrustedRequesterSender?.(ctx) ?? false,
527
- extractToolSend: (ctx) => resolveRuntimeDiscordMessageActions()?.extractToolSend?.(ctx) ?? discordMessageActions$1.extractToolSend?.(ctx) ?? null,
528
- prepareSendPayload: (ctx) => resolveRuntimeDiscordMessageActions()?.prepareSendPayload?.(ctx) ?? discordMessageActions$1.prepareSendPayload?.(ctx) ?? null,
529
- handleAction: async (ctx) => {
530
- const runtimeHandleAction = resolveRuntimeDiscordMessageActions()?.handleAction;
531
- if (runtimeHandleAction) return await runtimeHandleAction(ctx);
532
- if (!discordMessageActions$1.handleAction) throw new Error("Discord message actions not available");
533
- return await discordMessageActions$1.handleAction(ctx);
534
- }
535
- };
536
- function resolveDiscordStartupAccountIds(cfg) {
537
- const startupAccountIds = listEnabledDiscordAccounts(cfg).filter((candidate) => resolveConfiguredFromCredentialStatuses(candidate) ?? Boolean(normalizeOptionalString(candidate.token))).map((candidate) => candidate.accountId);
538
- const defaultAccountId = resolveDefaultDiscordAccountId(cfg);
539
- if (!startupAccountIds.includes(defaultAccountId)) return startupAccountIds;
540
- return [defaultAccountId, ...startupAccountIds.filter((candidateId) => candidateId !== defaultAccountId)];
541
- }
542
564
  function resolveDiscordStartupDelayMs(cfg, accountId) {
543
- const startupIndex = resolveDiscordStartupAccountIds(cfg).findIndex((candidateId) => candidateId === accountId);
565
+ const startupIndex = listDiscordStartupAccountIds(cfg).findIndex((candidateId) => candidateId === accountId);
544
566
  return startupIndex <= 0 ? 0 : startupIndex * DISCORD_ACCOUNT_STARTUP_STAGGER_MS;
545
567
  }
546
568
  function formatDiscordIntents(intents) {
@@ -607,6 +629,7 @@ const discordPlugin = createChatChannelPlugin({
607
629
  "- Forms: add `components.modal` (title, fields). OpenClaw adds a trigger button and routes submissions as new messages."
608
630
  ] },
609
631
  messaging: {
632
+ resolveConversationRouteOwner: inspectDiscordConversationRouteOwner,
610
633
  targetPrefixes: ["discord"],
611
634
  directTargetStyle: "user-prefixed",
612
635
  targetIdComparison: "lowercase",
@@ -723,6 +746,7 @@ const discordPlugin = createChatChannelPlugin({
723
746
  },
724
747
  conversationBindings: {
725
748
  supportsCurrentConversationBinding: true,
749
+ bindingStore: "adapter",
726
750
  defaultTopLevelPlacement,
727
751
  createManager: async ({ cfg, accountId }) => (await loadDiscordThreadBindingsManagerModule()).createThreadBindingManager({
728
752
  cfg,
@@ -1,2 +1,2 @@
1
- import { t as DiscordChannelConfigSchema } from "./config-schema-BgEskFAs.js";
1
+ import { t as DiscordChannelConfigSchema } from "./config-schema-DC5kDtQ5.js";
2
2
  export { DiscordChannelConfigSchema };
@@ -1,2 +1,2 @@
1
- import { t as discordPlugin } from "./channel-CnnbJSt5.js";
1
+ import { t as discordPlugin } from "./channel-cXYzGc4L.js";
2
2
  export { discordPlugin };
@@ -1,8 +1,8 @@
1
- import { a as mergeDiscordAccountConfig, c as resolveDiscordAccountAllowFrom, l as resolveDiscordAccountConfig, m as resolveDiscordToken, o as resolveDefaultDiscordAccountId } from "./accounts-DJTf1LtA.js";
2
- import { n as inspectDiscordAccountTokenState } from "./account-inspect-CqzrH14k.js";
3
- import { i as discordSetupContract, t as createDiscordPluginBase } from "./shared-BIXIX6uJ.js";
4
- import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-Dm7jEeg6.js";
5
- import { t as resolveDiscordUserAllowlist } from "./resolve-users-bktrCUUU.js";
1
+ import { h as resolveDiscordToken, l as resolveDiscordAccountAllowFrom, o as mergeDiscordAccountConfig, s as resolveDefaultDiscordAccountId, u as resolveDiscordAccountConfig } from "./accounts-DNl-oCEw.js";
2
+ import { n as inspectDiscordAccountTokenState } from "./account-inspect-D5xmUpnj.js";
3
+ import { i as discordSetupContract, t as createDiscordPluginBase } from "./shared-CaAaoksy.js";
4
+ import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-CGeUoIqb.js";
5
+ import { t as resolveDiscordUserAllowlist } from "./resolve-users-BtKxLUZv.js";
6
6
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
7
7
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { resolveBasicAllowFromEntries } from "openclaw/plugin-sdk/allow-from";
@@ -1,11 +1,9 @@
1
- import { $ as LinkButton, G as Label, J as TextInput, K as Modal, Q as File, W as CheckboxGroup, X as ChannelSelectMenu, Y as Button, Z as Container, at as Separator, ct as Thumbnail, dt as parseCustomId, et as MediaGallery, it as Section, lt as UserSelectMenu, nt as RoleSelectMenu, ot as StringSelectMenu, p as parseDiscordTarget, q as RadioGroup, rt as Row, st as TextDisplay, tn as __exportAll, tt as MentionableSelectMenu } from "./retry-CLpJcXXf.js";
2
- import { buildOutboundBaseSessionKey } from "openclaw/plugin-sdk/routing";
3
- import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { $ as MediaGallery, G as Modal, J as Button, K as RadioGroup, Q as LinkButton, U as CheckboxGroup, W as Label, X as Container, Y as ChannelSelectMenu, Z as File, at as StringSelectMenu, ct as UserSelectMenu, en as __exportAll, et as MentionableSelectMenu, it as Separator, nt as Row, ot as TextDisplay, q as TextInput, rt as Section, st as Thumbnail, tt as RoleSelectMenu, ut as parseCustomId } from "./retry-DNsVTeTo.js";
4
2
  import { ButtonStyle, MessageFlags, TextInputStyle } from "discord-api-types/v10";
5
3
  import crypto from "node:crypto";
4
+ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
5
  import { reduceLegacyInteractiveReply, resolveMessagePresentationActionValue, resolveMessagePresentationButtonAction, resolveMessagePresentationOptionAction } from "openclaw/plugin-sdk/interactive-runtime";
7
6
  import { buildApprovalResolutionRef } from "openclaw/plugin-sdk/approval-reference-runtime";
8
- import { buildThreadAwareOutboundSessionRoute } from "openclaw/plugin-sdk/channel-core";
9
7
  //#region extensions/discord/src/custom-id-codec.ts
10
8
  /**
11
9
  * URI-component codec for values embedded in `k=v;` custom-id grammars
@@ -1071,48 +1069,4 @@ function formatDiscordComponentEventText(params) {
1071
1069
  return `Selected ${values.join(", ")} from "${params.label}".`;
1072
1070
  }
1073
1071
  //#endregion
1074
- //#region extensions/discord/src/outbound-session-route.ts
1075
- function resolveDiscordOutboundSessionRoute(params) {
1076
- const parsed = parseDiscordTarget(params.target, { defaultKind: resolveDiscordOutboundTargetKindHint(params) });
1077
- if (!parsed) return null;
1078
- const explicitThreadId = params.threadId == null ? void 0 : String(params.threadId).trim();
1079
- const peerId = explicitThreadId || parsed.id;
1080
- const isDm = parsed.kind === "user" && !explicitThreadId;
1081
- const recipientSessionExact = /^\d+$/.test(peerId);
1082
- const peer = {
1083
- kind: isDm ? "direct" : "channel",
1084
- id: peerId
1085
- };
1086
- const baseSessionKey = buildOutboundBaseSessionKey({
1087
- cfg: params.cfg,
1088
- agentId: params.agentId,
1089
- channel: "discord",
1090
- accountId: params.accountId,
1091
- peer
1092
- });
1093
- return buildThreadAwareOutboundSessionRoute({
1094
- route: {
1095
- sessionKey: baseSessionKey,
1096
- baseSessionKey,
1097
- recipientSessionExact,
1098
- peer,
1099
- chatType: isDm ? "direct" : "channel",
1100
- from: isDm ? `discord:${peerId}` : `discord:channel:${peerId}`,
1101
- to: isDm ? `user:${peerId}` : `channel:${peerId}`
1102
- },
1103
- threadId: params.threadId,
1104
- precedence: ["threadId"],
1105
- useSuffix: false
1106
- });
1107
- }
1108
- function resolveDiscordOutboundTargetKindHint(params) {
1109
- const resolvedKind = params.resolvedTarget?.kind;
1110
- if (resolvedKind === "user") return "user";
1111
- if (resolvedKind === "group" || resolvedKind === "channel") return "channel";
1112
- const target = params.target.trim();
1113
- if (/^channel:/i.test(target)) return "channel";
1114
- if (/^(user:|discord:|@|<@!?)/i.test(target)) return "user";
1115
- return "channel";
1116
- }
1117
- //#endregion
1118
- export { parseDiscordActivityCustomIdForInteraction as C, parseDiscordModalCustomIdForInteraction as D, parseDiscordModalCustomId as E, decodeCustomIdComponent as O, parseDiscordActivityCustomId as S, parseDiscordComponentCustomIdForInteraction as T, DISCORD_COMPONENT_CUSTOM_ID_KEY as _, buildDiscordPresentationComponents as a, buildDiscordComponentCustomId as b, buildExecApprovalCustomId as c, createDiscordFormModal as d, buildDiscordComponentMessage as f, resolveDiscordComponentAttachmentName as g, readDiscordComponentSpec as h, buildDiscordInteractiveComponents as i, encodeCustomIdComponent as k, parseExecApprovalData as l, DISCORD_COMPONENT_ATTACHMENT_PREFIX as m, components_exports as n, shared_interactive_exports as o, buildDiscordComponentMessageFlags as p, formatDiscordComponentEventText as r, parseDiscordQuestionData as s, resolveDiscordOutboundSessionRoute as t, DiscordFormModal as u, DISCORD_MODAL_CUSTOM_ID_KEY as v, parseDiscordComponentCustomId as w, buildDiscordModalCustomId as x, buildDiscordActivityCustomId as y };
1072
+ export { parseDiscordComponentCustomId as C, decodeCustomIdComponent as D, parseDiscordModalCustomIdForInteraction as E, encodeCustomIdComponent as O, parseDiscordActivityCustomIdForInteraction as S, parseDiscordModalCustomId as T, DISCORD_MODAL_CUSTOM_ID_KEY as _, shared_interactive_exports as a, buildDiscordModalCustomId as b, parseExecApprovalData as c, buildDiscordComponentMessage as d, buildDiscordComponentMessageFlags as f, DISCORD_COMPONENT_CUSTOM_ID_KEY as g, resolveDiscordComponentAttachmentName as h, buildDiscordPresentationComponents as i, DiscordFormModal as l, readDiscordComponentSpec as m, formatDiscordComponentEventText as n, parseDiscordQuestionData as o, DISCORD_COMPONENT_ATTACHMENT_PREFIX as p, buildDiscordInteractiveComponents as r, buildExecApprovalCustomId as s, components_exports as t, createDiscordFormModal as u, buildDiscordActivityCustomId as v, parseDiscordComponentCustomIdForInteraction as w, parseDiscordActivityCustomId as x, buildDiscordComponentCustomId as y };
@@ -1,6 +1,8 @@
1
+ import { normalizeLegacyDmAliases } from "openclaw/plugin-sdk/channel-config-helpers";
1
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
2
- import { buildSecretInputSchema, registerSensitiveConfigSchema } from "openclaw/plugin-sdk/secret-input";
3
3
  import { ChannelBotLoopProtectionSchema, ChannelDangerouslyAllowNameMatchingSchema, ChannelPreviewStreamingConfigSchema, ChannelStreamingProgressSchema, ProviderCommandsSchema, TtsConfigSchema, buildChannelAllowBotsSchema, buildChannelConfigSchema, buildChannelExecApprovalsSchema, buildChannelReactionShape, buildCommonChannelAccountShape, buildGroupEntrySchema, requireAllowlistAllowFrom, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
4
+ import { asObjectRecord } from "openclaw/plugin-sdk/runtime-doctor-migrations";
5
+ import { buildSecretInputSchema, registerSensitiveConfigSchema } from "openclaw/plugin-sdk/secret-input";
4
6
  import { z } from "zod";
5
7
  import { createChannelConfigUiHints } from "openclaw/plugin-sdk/channel-core";
6
8
  //#region extensions/discord/src/config-ui-hints.ts
@@ -168,7 +170,11 @@ const discordChannelConfigUiHints = {
168
170
  },
169
171
  "voice.autoJoin": {
170
172
  label: "Discord Voice Auto-Join",
171
- help: "Voice channels to auto-join on startup (list of guildId/channelId entries)."
173
+ help: "Voice channels to auto-join (list of guildId/channelId entries). Set whenOccupied on an entry to connect only while humans are present."
174
+ },
175
+ "voice.autoJoin.*.whenOccupied": {
176
+ label: "Discord Voice Auto-Join When Occupied",
177
+ help: "Join and remain in this auto-managed voice channel only while at least one human is present. The OpenClaw bot and other bots do not count. Default: false."
172
178
  },
173
179
  "voice.allowedChannels": {
174
180
  label: "Discord Voice Allowed Channels",
@@ -301,7 +307,7 @@ const discordChannelConfigUiHints = {
301
307
  },
302
308
  activities: {
303
309
  label: "Discord Activities",
304
- help: "Enable Discord Activity widgets for this account. Routes, the agent tool, and the launch handler remain disabled when this block is absent."
310
+ help: "Enable the Discord Activity presenter for the core show_widget tool on this account. Activity routes and the launch handler remain disabled when this block is absent."
305
311
  },
306
312
  "activities.clientSecret": {
307
313
  label: "Discord Activities Client Secret",
@@ -389,7 +395,8 @@ const DiscordGuildSchema = buildGroupEntrySchema({
389
395
  ] });
390
396
  const DiscordVoiceAutoJoinSchema = z.object({
391
397
  guildId: z.string().min(1),
392
- channelId: z.string().min(1)
398
+ channelId: z.string().min(1),
399
+ whenOccupied: z.boolean().optional()
393
400
  }).strict();
394
401
  const DiscordVoiceAllowedChannelSchema = z.object({
395
402
  guildId: z.string().min(1),
@@ -454,7 +461,7 @@ const DiscordVoiceSchema = z.object({
454
461
  captureSilenceGraceMs: z.number().int().positive().max(3e4).optional(),
455
462
  tts: TtsConfigSchema.optional()
456
463
  }).strict().optional();
457
- const DiscordAccountSchema = z.object({
464
+ const DiscordAccountSchemaBase = z.object({
458
465
  ...buildCommonChannelAccountShape({
459
466
  omit: ["groupAllowFrom"],
460
467
  groupPolicyDefault: true,
@@ -583,7 +590,25 @@ const DiscordAccountSchema = z.object({
583
590
  path: ["autoPresence", "minUpdateIntervalMs"]
584
591
  });
585
592
  });
586
- const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordAccountSchema.extend({
593
+ function normalizeShippedDiscordDmAliases(value) {
594
+ const entry = asObjectRecord(value);
595
+ if (!entry) return value;
596
+ const updated = normalizeLegacyDmAliases({
597
+ entry,
598
+ pathPrefix: "channels.discord",
599
+ changes: []
600
+ }).entry;
601
+ const dm = asObjectRecord(updated.dm);
602
+ if (!dm || dm.policy === void 0 && dm.allowFrom === void 0) return updated;
603
+ const { policy: _policy, allowFrom: _allowFrom, ...retainedDm } = dm;
604
+ const { dm: _dm, ...rest } = updated;
605
+ return Object.keys(retainedDm).length > 0 ? {
606
+ ...rest,
607
+ dm: retainedDm
608
+ } : rest;
609
+ }
610
+ const DiscordAccountSchema = z.preprocess(normalizeShippedDiscordDmAliases, DiscordAccountSchemaBase);
611
+ const DiscordConfigSchemaBase = DiscordAccountSchemaBase.extend({
587
612
  accounts: z.record(z.string(), DiscordAccountSchema.optional()).optional(),
588
613
  defaultAccount: z.string().optional()
589
614
  }).superRefine((value, ctx) => {
@@ -631,6 +656,7 @@ const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordAccountSchema
631
656
  message: "channels.discord.accounts.*.dmPolicy=\"allowlist\" requires channels.discord.accounts.*.allowFrom (or channels.discord.allowFrom) to contain at least one sender ID"
632
657
  });
633
658
  }
634
- }), { uiHints: discordChannelConfigUiHints });
659
+ });
660
+ const DiscordChannelConfigSchema = buildChannelConfigSchema(z.preprocess(normalizeShippedDiscordDmAliases, DiscordConfigSchemaBase), { uiHints: discordChannelConfigUiHints });
635
661
  //#endregion
636
662
  export { DiscordChannelConfigSchema as t };