@openclaw/discord 2026.9.1 → 2026.9.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 (138) hide show
  1. package/dist/action-runtime-api.js +1 -1
  2. package/dist/{activities-api-E-segZn6.js → activities-api-CTcGq3Hf.js} +4 -4
  3. package/dist/activities-api.js +1 -1
  4. package/dist/{allow-list-C2JuH-R0.js → allow-list-DBTtR2dz.js} +3 -29
  5. package/dist/api.js +12 -12
  6. package/dist/{approval-handler.runtime-CW5k3mSa.js → approval-handler.runtime-DUSe5fyH.js} +5 -5
  7. package/dist/{audit-B9rydv5a.js → audit-DpPfwoJM.js} +4 -4
  8. package/dist/{channel-D93LnbTE.js → channel-BHajPgwR.js} +16 -16
  9. package/dist/{channel-actions.runtime-DMFv4doE.js → channel-actions.runtime-DS8pXo0S.js} +29 -32
  10. package/dist/channel-plugin-api.js +1 -1
  11. package/dist/{channel.setup-DTL7kPOM.js → channel.setup-BWmMe1tT.js} +3 -3
  12. package/dist/command-owners-D78sAoOz.js +10 -0
  13. package/dist/{components-DmXYIQ26.js → components-BimX47Mq.js} +1 -1
  14. package/dist/{conversation-binding-route-24afmvEC.js → conversation-binding-route-DuR5NGIx.js} +1 -1
  15. package/dist/{directory-config-BD4YL7wT.js → directory-config-CD2v2Szs.js} +1 -1
  16. package/dist/directory-contract-api.js +1 -1
  17. package/dist/{directory-live-BrFVc1Ds.js → directory-live-DaJzWJ2N.js} +2 -2
  18. package/dist/{doctor-BUB41_lr.js → doctor-D4HH1inA.js} +6 -3
  19. package/dist/doctor-contract-api.js +28 -26
  20. package/dist/{handle-action.guild-admin-B0egstYq.js → handle-action.guild-admin-4We6wWQU.js} +6 -3
  21. package/dist/index.js +1 -1
  22. package/dist/{ingress-identity-BCzfPPYM.js → ingress-identity-XNmW-mZS.js} +1 -1
  23. package/dist/{message-handler-Qdw9c0j4.js → message-handler-DhgBabyU.js} +52 -65
  24. package/dist/{message-handler.preflight-Dxi2yBfR.js → message-handler.preflight-oZ7dQCd0.js} +12 -12
  25. package/dist/{message-handler.process-BYDjtxZJ.js → message-handler.process-BzCYf1pa.js} +14 -14
  26. package/dist/{message-text-BRVqYm-t.js → message-text-DK4NnBg-.js} +1 -1
  27. package/dist/{outbound-adapter-DEhthWTk.js → outbound-adapter-CtggmGh9.js} +6 -6
  28. package/dist/{outbound-components-DehyxvA4.js → outbound-components-Dn8SJWMS.js} +3 -3
  29. package/dist/{outbound-session-route-BFGRF9fE.js → outbound-session-route-Q_HEusBQ.js} +5 -6
  30. package/dist/{owner-access-yc1sX7Gx.js → owner-access-Cp8r6Ipf.js} +3 -2
  31. package/dist/{pluralkit-XmmAHoV6.js → pluralkit-BY75YcK0.js} +1 -1
  32. package/dist/{provider-session.runtime-BA2BPyZ4.js → provider-session.runtime-BL2lHBH7.js} +3 -3
  33. package/dist/{provider-DuDtKbF8.js → provider-uKmmrDM4.js} +28 -28
  34. package/dist/provider.runtime-C-IkWF2w.js +2 -0
  35. package/dist/{realtime-session.runtime-DgSbX6ay.js → realtime-session.runtime-CGYm1t_0.js} +705 -295
  36. package/dist/{resolve-allowlist-common-BJ5UZNNT.js → resolve-allowlist-common-sKIKy-cF.js} +1 -1
  37. package/dist/{resolve-channels-CYseD5Uw.js → resolve-channels-CoiMlWy0.js} +3 -3
  38. package/dist/{resolve-users-DrmhDrqm.js → resolve-users-DJpiokfW.js} +2 -2
  39. package/dist/{retry-BNCxiyyR.js → retry-DQt1zDgH.js} +238 -184
  40. package/dist/{runtime-DB7Fb6AU.js → runtime-BHsdEdr5.js} +1 -1
  41. package/dist/{runtime-BbWNtfyq.js → runtime-Ghtfh5ZA.js} +32 -24
  42. package/dist/runtime-api.js +18 -18
  43. package/dist/{send-BnTEIeLE.js → send-CZeWKUiA.js} +3 -3
  44. package/dist/{send.components-BWVEcjRP.js → send.components-BG5IDABj.js} +4 -4
  45. package/dist/{send.outbound-b5xwHTlL.js → send.outbound-DHuFUL6W.js} +10 -44
  46. package/dist/{send.shared-5vxBTagO.js → send.shared-B0n_fWzu.js} +62 -141
  47. package/dist/{sender-identity-Dt0imZyY.js → sender-identity-B8Ncfi63.js} +1 -1
  48. package/dist/setup-plugin-api.js +1 -1
  49. package/dist/{shared-BSJWHEMA.js → shared-C3dKun_X.js} +6 -3
  50. package/dist/{subagent-hooks-IzQKX4RQ.js → subagent-hooks-ZoQXEI1E.js} +2 -2
  51. package/dist/subagent-hooks-api.js +1 -1
  52. package/dist/{system-events-BOiDS8b3.js → system-events-DFF_awl7.js} +2 -2
  53. package/dist/{target-resolver-BVI8xSSC.js → target-resolver-DLtHDwMK.js} +2 -2
  54. package/dist/targets-BObRyaKX.js +3 -0
  55. package/dist/{thread-bindings-D7mcaXQC.js → thread-bindings-DKvsNjQR.js} +5 -5
  56. package/dist/{thread-bindings.manager-B1oySiVc.js → thread-bindings.manager-pbbRT5gb.js} +5 -5
  57. package/dist/{thread-bindings.session-updates-CC7HoQvt.js → thread-bindings.session-updates-t6jeFB1-.js} +1 -1
  58. package/dist/{thread-bindings.state-D8OMdk4O.js → thread-bindings.state-DtgOqsbX.js} +34 -1
  59. package/dist/{threading-OQnL-0Zx.js → threading-BCx49X-6.js} +3 -3
  60. package/dist/{transcripts-source-D8lH7AkN.js → transcripts-source-Dc6Nnli5.js} +48 -5
  61. package/dist/transcripts-source-api.js +1 -1
  62. package/dist/{typing-C9q0AQMb.js → typing-CuopV-Hi.js} +1 -1
  63. package/dist/{voice-runtime-Dfhjh1tV.js → voice-runtime-BQnILUbG.js} +82 -35
  64. package/node_modules/@discordjs/voice/node_modules/@types/node/README.md +1 -1
  65. package/node_modules/@discordjs/voice/node_modules/@types/node/buffer.buffer.d.ts +5 -5
  66. package/node_modules/@discordjs/voice/node_modules/@types/node/crypto.d.ts +2 -2
  67. package/node_modules/@discordjs/voice/node_modules/@types/node/http.d.ts +16 -0
  68. package/node_modules/@discordjs/voice/node_modules/@types/node/http2.d.ts +10 -2
  69. package/node_modules/@discordjs/voice/node_modules/@types/node/package.json +2 -2
  70. package/node_modules/@discordjs/voice/node_modules/@types/node/process.d.ts +52 -0
  71. package/node_modules/@discordjs/voice/node_modules/@types/node/quic.d.ts +210 -28
  72. package/node_modules/@discordjs/voice/node_modules/@types/node/sqlite.d.ts +6 -2
  73. package/node_modules/@discordjs/voice/node_modules/@types/node/test.d.ts +36 -0
  74. package/node_modules/typebox/build/format/json_pointer.d.mts +2 -2
  75. package/node_modules/typebox/build/format/json_pointer.mjs +2 -2
  76. package/node_modules/typebox/build/format/json_pointer_uri_fragment.d.mts +2 -2
  77. package/node_modules/typebox/build/format/json_pointer_uri_fragment.mjs +2 -2
  78. package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
  79. package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
  80. package/node_modules/typebox/build/system/memory/assign.mjs +2 -1
  81. package/node_modules/typebox/build/system/memory/create.mjs +3 -4
  82. package/node_modules/typebox/build/system/memory/discard.mjs +2 -2
  83. package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
  84. package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
  85. package/node_modules/typebox/build/system/memory/update.mjs +3 -2
  86. package/node_modules/typebox/package.json +1 -1
  87. package/node_modules/undici/docs/docs/api/Client.md +4 -0
  88. package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +3 -2
  89. package/node_modules/undici/docs/docs/api/EventSource.md +4 -0
  90. package/node_modules/undici/docs/docs/api/Interceptors.md +7 -3
  91. package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +7 -1
  92. package/node_modules/undici/lib/cache/memory-cache-store.js +2 -2
  93. package/node_modules/undici/lib/core/symbols.js +2 -0
  94. package/node_modules/undici/lib/dispatcher/agent.js +7 -2
  95. package/node_modules/undici/lib/dispatcher/balanced-pool.js +7 -4
  96. package/node_modules/undici/lib/dispatcher/client-h1.js +12 -4
  97. package/node_modules/undici/lib/dispatcher/client-h2.js +43 -3
  98. package/node_modules/undici/lib/dispatcher/client.js +3 -2
  99. package/node_modules/undici/lib/dispatcher/dispatcher-base.js +13 -1
  100. package/node_modules/undici/lib/dispatcher/dispatcher.js +15 -1
  101. package/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +3 -0
  102. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +10 -3
  103. package/node_modules/undici/lib/dispatcher/proxy-agent.js +18 -1
  104. package/node_modules/undici/lib/dispatcher/retry-agent.js +3 -0
  105. package/node_modules/undici/lib/dispatcher/round-robin-pool.js +1 -1
  106. package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +91 -21
  107. package/node_modules/undici/lib/handler/cache-handler.js +29 -5
  108. package/node_modules/undici/lib/handler/decorator-handler.js +7 -1
  109. package/node_modules/undici/lib/handler/deduplication-handler.js +12 -6
  110. package/node_modules/undici/lib/handler/redirect-handler.js +21 -4
  111. package/node_modules/undici/lib/handler/retry-handler.js +148 -30
  112. package/node_modules/undici/lib/interceptor/cache.js +65 -12
  113. package/node_modules/undici/lib/interceptor/decompress.js +115 -13
  114. package/node_modules/undici/lib/interceptor/deduplicate.js +5 -4
  115. package/node_modules/undici/lib/interceptor/dns.js +7 -0
  116. package/node_modules/undici/lib/interceptor/dump.js +10 -23
  117. package/node_modules/undici/lib/mock/mock-agent.js +13 -1
  118. package/node_modules/undici/lib/mock/mock-utils.js +11 -10
  119. package/node_modules/undici/lib/util/cache.js +45 -3
  120. package/node_modules/undici/lib/web/cookies/parse.js +150 -147
  121. package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +28 -1
  122. package/node_modules/undici/lib/web/eventsource/eventsource.js +13 -3
  123. package/node_modules/undici/lib/web/fetch/index.js +6 -0
  124. package/node_modules/undici/lib/web/fetch/request.js +2 -3
  125. package/node_modules/undici/lib/web/fetch/util.js +6 -1
  126. package/node_modules/undici/lib/web/webidl/index.js +3 -3
  127. package/node_modules/undici/lib/web/websocket/connection.js +1 -1
  128. package/node_modules/undici/lib/web/websocket/permessage-deflate.js +5 -0
  129. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -10
  130. package/node_modules/undici/package.json +3 -3
  131. package/node_modules/undici/types/client.d.ts +10 -0
  132. package/node_modules/undici/types/interceptors.d.ts +2 -0
  133. package/node_modules/undici/types/mock-agent.d.ts +11 -10
  134. package/node_modules/undici/types/socks5-proxy-agent.d.ts +2 -0
  135. package/openclaw.plugin.json +1 -2
  136. package/package.json +6 -6
  137. package/dist/provider.runtime-Db8YwZBv.js +0 -2
  138. package/dist/targets-DbxVbq8k.js +0 -3
@@ -1,6 +1,6 @@
1
1
  import { m as normalizeDiscordToken } from "./accounts-CwJQoLjM.js";
2
2
  import { r as fetchDiscord } from "./api-BfmEP6wp.js";
3
- import { a as normalizeDiscordSlug } from "./allow-list-C2JuH-R0.js";
3
+ import { a as normalizeDiscordSlug } from "./allow-list-DBTtR2dz.js";
4
4
  //#region extensions/discord/src/guilds.ts
5
5
  async function listGuilds(token, fetcher, options) {
6
6
  return (await fetchDiscord("/users/@me/guilds", token, fetcher, options)).filter((guild) => typeof guild.id === "string" && typeof guild.name === "string").map((guild) => ({
@@ -1,8 +1,8 @@
1
- import { sn as __exportAll } from "./retry-BNCxiyyR.js";
1
+ import { sn as __exportAll } from "./retry-DQt1zDgH.js";
2
2
  import { n as DiscordApiError, r as fetchDiscord, t as DISCORD_DIRECTORY_LOOKUP_TIMEOUT_MS } from "./api-BfmEP6wp.js";
3
- import { a as normalizeDiscordSlug } from "./allow-list-C2JuH-R0.js";
3
+ import { a as normalizeDiscordSlug } from "./allow-list-DBTtR2dz.js";
4
4
  import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
5
- import { i as listGuilds, n as filterDiscordGuilds, r as resolveDiscordAllowlistToken, t as buildDiscordUnresolvedResults } from "./resolve-allowlist-common-BJ5UZNNT.js";
5
+ import { i as listGuilds, n as filterDiscordGuilds, r as resolveDiscordAllowlistToken, t as buildDiscordUnresolvedResults } from "./resolve-allowlist-common-sKIKy-cF.js";
6
6
  //#region extensions/discord/src/resolve-channels.ts
7
7
  var resolve_channels_exports = /* @__PURE__ */ __exportAll({ resolveDiscordChannelAllowlist: () => resolveDiscordChannelAllowlist });
8
8
  function parseDiscordChannelInput(raw) {
@@ -1,6 +1,6 @@
1
- import { sn as __exportAll } from "./retry-BNCxiyyR.js";
1
+ import { sn as __exportAll } from "./retry-DQt1zDgH.js";
2
2
  import { r as fetchDiscord, t as DISCORD_DIRECTORY_LOOKUP_TIMEOUT_MS } from "./api-BfmEP6wp.js";
3
- import { i as listGuilds, n as filterDiscordGuilds, r as resolveDiscordAllowlistToken, t as buildDiscordUnresolvedResults } from "./resolve-allowlist-common-BJ5UZNNT.js";
3
+ import { i as listGuilds, n as filterDiscordGuilds, r as resolveDiscordAllowlistToken, t as buildDiscordUnresolvedResults } from "./resolve-allowlist-common-sKIKy-cF.js";
4
4
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  //#region extensions/discord/src/resolve-users.ts
6
6
  var resolve_users_exports = /* @__PURE__ */ __exportAll({ resolveDiscordUserAllowlist: () => resolveDiscordUserAllowlist });
@@ -15,8 +15,8 @@ import { classifyTransientNetworkErrorCode, createChannelApiRetryRunner, parseRe
15
15
  import { buildMessagingTarget, parseMentionPrefixOrAtUserTarget, requireTargetKind } from "openclaw/plugin-sdk/channel-targets";
16
16
  import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
17
17
  import { resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
18
- import { chunkMarkdownTextWithMode } from "openclaw/plugin-sdk/reply-chunking";
19
- import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
18
+ import { chunkByParagraph } from "openclaw/plugin-sdk/reply-chunking";
19
+ import { avoidTrailingHighSurrogateBreak, chunkTextForOutbound, findCodeRegions } from "openclaw/plugin-sdk/text-chunking";
20
20
  import { isSingleUseReplyToMode } from "openclaw/plugin-sdk/reply-reference";
21
21
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
22
22
  import { attachChannelToResults } from "openclaw/plugin-sdk/channel-send-result";
@@ -3315,214 +3315,268 @@ function countLines(text) {
3315
3315
  if (!text) return 0;
3316
3316
  return text.split("\n").length;
3317
3317
  }
3318
- function parseFenceLine(line) {
3318
+ function parseFenceLine(line, maxChars = Number.POSITIVE_INFINITY) {
3319
3319
  const match = line.match(FENCE_RE);
3320
3320
  if (!match) return null;
3321
- const indent = match[1] ?? "";
3322
3321
  const marker = match[2] ?? "";
3322
+ const closeLine = (match[1] ?? "") + marker;
3323
+ const canBalance = closeLine.length * 2 + 3 <= maxChars;
3324
+ const reopenLine = line.length + closeLine.length + 3 <= maxChars ? line : closeLine;
3323
3325
  return {
3324
- indent,
3325
- markerChar: marker[0] ?? "`",
3326
- markerLen: marker.length,
3327
- openLine: line
3326
+ marker,
3327
+ closeLine,
3328
+ reopenLine: canBalance ? reopenLine : null
3328
3329
  };
3329
3330
  }
3330
- function closeFenceLine(openFence) {
3331
- return `${openFence.indent}${openFence.markerChar.repeat(openFence.markerLen)}`;
3331
+ function closesFence(open, close) {
3332
+ return open.marker[0] === close.marker[0] && close.marker.length >= open.marker.length;
3332
3333
  }
3333
- function canBalanceFence(openFence, maxChars) {
3334
- return closeFenceLine(openFence).length * 2 + 3 <= maxChars;
3335
- }
3336
- function reopenFenceLine(openFence, maxChars) {
3337
- const bareMarker = closeFenceLine(openFence);
3338
- if (!canBalanceFence(openFence, maxChars)) return null;
3339
- if (openFence.openLine.length + bareMarker.length + 3 <= maxChars) return openFence.openLine;
3340
- return bareMarker;
3341
- }
3342
- function closeFenceIfNeeded(text, openFence, maxChars) {
3343
- if (!openFence || !canBalanceFence(openFence, maxChars)) return text;
3344
- const closeLine = closeFenceLine(openFence);
3345
- if (!text) return closeLine;
3346
- if (!text.endsWith("\n")) return `${text}\n${closeLine}`;
3347
- return `${text}${closeLine}`;
3348
- }
3349
- /**
3350
- * Chunks outbound Discord text by both character count and (soft) line count,
3351
- * while keeping fenced code blocks balanced across chunks.
3352
- */
3353
3334
  function chunkDiscordText(text, opts = {}) {
3354
3335
  const hardMaxChars = resolveDiscordChunkLimit(opts.maxChars, DEFAULT_MAX_CHARS);
3355
3336
  const maxLines = resolveDiscordChunkLimit(opts.maxLines, DEFAULT_MAX_LINES);
3356
- const body = text ?? "";
3357
- if (!body) return [];
3358
- if (body.length <= hardMaxChars && countLines(body) <= maxLines) return [body];
3359
- const maxChars = hardMaxChars >= MIN_REASONING_ITALICS_CHUNK_CHARS && hasReasoningItalics(body) ? hardMaxChars - REASONING_ITALICS_MARKER_CHARS : hardMaxChars;
3360
- const lines = body.split("\n");
3337
+ if (!text) return [];
3338
+ if (text.length <= hardMaxChars && countLines(text) <= maxLines) return [text];
3339
+ const maxChars = hardMaxChars >= MIN_REASONING_ITALICS_CHUNK_CHARS && hasReasoningItalics(text) ? hardMaxChars - REASONING_ITALICS_MARKER_CHARS : hardMaxChars;
3340
+ const ranges = createDiscordRanges(text, maxChars, maxLines);
3361
3341
  const chunks = [];
3362
- let current = "";
3363
- let currentLines = 0;
3364
- let openFence = null;
3365
- const flush = () => {
3366
- if (!current) return;
3367
- const payload = closeFenceIfNeeded(current, openFence, maxChars);
3368
- if (payload.trim().length) chunks.push(payload);
3369
- current = "";
3370
- currentLines = 0;
3371
- if (openFence) {
3372
- const reopenLine = reopenFenceLine(openFence, maxChars);
3373
- if (reopenLine) {
3374
- current = reopenLine;
3375
- currentLines = 1;
3376
- }
3377
- }
3342
+ let current;
3343
+ let consumed = 0;
3344
+ let lineStart = 0;
3345
+ const raw = (frame) => {
3346
+ const prefix = ranges.fenceAt(frame.start)?.reopenLine ?? "";
3347
+ const body = text.slice(frame.start, frame.end);
3348
+ return prefix + (prefix ? "\n" : "") + body;
3349
+ };
3350
+ const render = (frame) => {
3351
+ const body = ranges.render(frame.start, frame.end);
3352
+ if (body === void 0) return;
3353
+ const prefix = ranges.fenceAt(frame.start)?.reopenLine ?? "";
3354
+ const result = prefix + (prefix ? "\n" : "") + body;
3355
+ const close = ranges.fenceAt(frame.end);
3356
+ return close?.reopenLine ? result + (result.endsWith("\n") ? "" : "\n") + close.closeLine : result;
3357
+ };
3358
+ const fits = (frame) => {
3359
+ const payload = render(frame);
3360
+ return payload !== void 0 && payload.length <= maxChars && countLines(payload) <= Math.max(maxLines, ranges.fenceAt(frame.start)?.reopenLine || ranges.fenceAt(frame.end)?.reopenLine ? 3 : 1);
3378
3361
  };
3379
- for (const originalLine of lines) {
3380
- const fenceInfo = parseFenceLine(originalLine);
3381
- const wasInsideFence = openFence !== null;
3382
- let nextOpenFence = openFence;
3383
- if (fenceInfo) {
3384
- if (!openFence) nextOpenFence = fenceInfo;
3385
- else if (openFence.markerChar === fenceInfo.markerChar && fenceInfo.markerLen >= openFence.markerLen) nextOpenFence = null;
3362
+ const flush = (frame) => {
3363
+ let end = ranges.overlaps(frame.start, frame.end) ? ranges.cutBoundary(frame.start, frame.end) : ranges.boundary(frame.start, frame.end);
3364
+ if (frame.end > frame.start && end <= frame.start) return frame;
3365
+ const minimum = ranges.boundary(frame.start, frame.start + 1);
3366
+ while (end > minimum && !fits({
3367
+ ...frame,
3368
+ end
3369
+ })) {
3370
+ const cut = ranges.cutBoundary(frame.start, end - 1);
3371
+ end = cut > frame.start ? cut : minimum;
3386
3372
  }
3387
- const candidateFence = nextOpenFence ?? openFence;
3388
- const fenceToReserve = candidateFence && canBalanceFence(candidateFence, maxChars) ? candidateFence : null;
3389
- const reserveChars = fenceToReserve ? closeFenceLine(fenceToReserve).length + 1 : 0;
3390
- const reserveLines = fenceToReserve ? 1 : 0;
3391
- const effectiveMaxChars = maxChars - reserveChars;
3392
- const effectiveMaxLines = maxLines - reserveLines;
3393
- const charLimit = effectiveMaxChars > 0 ? effectiveMaxChars : maxChars;
3394
- const lineLimit = effectiveMaxLines > 0 ? effectiveMaxLines : maxLines;
3395
- const reopenPrefixLen = fenceToReserve ? reopenFenceLine(fenceToReserve, maxChars)?.length ?? 0 : 0;
3396
- const prefixLen = current.length > 0 ? current.length + 1 : 0;
3397
- const reopenBudget = reopenPrefixLen > 0 ? reopenPrefixLen + 1 : 0;
3398
- const segmentLimit = Math.max(1, charLimit - Math.max(prefixLen, reopenBudget));
3399
- const segments = chunkTextForOutbound(originalLine, segmentLimit, { preserveWhitespace: wasInsideFence });
3400
- for (let segIndex = 0; segIndex < segments.length; segIndex++) {
3401
- const segment = segments[segIndex];
3402
- const isLineContinuation = segIndex > 0;
3403
- let delimiter = isLineContinuation ? "" : current.length > 0 ? "\n" : "";
3404
- let addition = `${delimiter}${segment}`;
3405
- const nextLen = current.length + addition.length;
3406
- const nextLines = currentLines + (isLineContinuation ? 0 : 1);
3407
- if ((nextLen > charLimit || nextLines > lineLimit) && current.length > 0) {
3408
- flush();
3409
- delimiter = current.length > 0 ? "\n" : "";
3410
- addition = `${delimiter}${segment}`;
3411
- }
3412
- if (current.length > 0) {
3413
- current += addition;
3414
- if (!isLineContinuation || delimiter) currentLines += 1;
3415
- } else {
3416
- current = expectDefined(segment, "current Discord chunk segment");
3417
- currentLines = 1;
3373
+ const payload = expectDefined(render({
3374
+ ...frame,
3375
+ end
3376
+ }), "renderable Discord source range");
3377
+ if (payload.trim()) chunks.push(payload);
3378
+ consumed = end;
3379
+ return end < frame.end ? {
3380
+ start: end,
3381
+ end: frame.end
3382
+ } : void 0;
3383
+ };
3384
+ for (const line of text.split("\n")) {
3385
+ const openFence = ranges.fenceAt(lineStart - 1);
3386
+ const candidateFence = ranges.fenceAt(lineStart + line.length) ?? openFence;
3387
+ const fence = candidateFence?.reopenLine ? candidateFence : null;
3388
+ const charLimit = maxChars - (fence ? fence.closeLine.length + 1 : 0);
3389
+ const lineLimit = Math.max(1, maxLines - (fence ? 1 : 0));
3390
+ const content = current ? raw(current) : ranges.fenceAt(consumed)?.reopenLine ?? "";
3391
+ const segmentLimit = openFence?.reopenLine && openFence.closeStart === lineStart && fits({
3392
+ start: lineStart,
3393
+ end: lineStart + line.length
3394
+ }) ? maxChars : Math.max(1, charLimit - Math.max(content ? content.length + 1 : 0, fence?.reopenLine ? fence.reopenLine.length + 1 : 0));
3395
+ let segmentStart = lineStart;
3396
+ for (const segment of chunkTextForOutbound(line, segmentLimit, { preserveWhitespace: Boolean(openFence) })) {
3397
+ const end = segmentStart + segment.length;
3398
+ const start = current?.start ?? (ranges.joins(consumed, segmentStart) ? consumed : segmentStart);
3399
+ const candidate = {
3400
+ start,
3401
+ end
3402
+ };
3403
+ const exceeds = openFence && !ranges.fenceAt(end) ? !fits(candidate) : raw(candidate).length > charLimit || countLines(raw(candidate)) > lineLimit || ranges.overlaps(start, end) && !fits(candidate);
3404
+ if (current && exceeds) {
3405
+ current = flush(current);
3406
+ candidate.start = current?.start ?? (ranges.joins(consumed, segmentStart) ? consumed : segmentStart);
3418
3407
  }
3408
+ current = raw(candidate) ? candidate : void 0;
3409
+ segmentStart = end;
3419
3410
  }
3420
- openFence = nextOpenFence;
3421
- }
3422
- if (current.length) {
3423
- const payload = closeFenceIfNeeded(current, openFence, maxChars);
3424
- if (payload.trim().length) chunks.push(payload);
3411
+ lineStart += line.length + 1;
3425
3412
  }
3413
+ while (current) current = flush(current);
3426
3414
  return rebalanceReasoningItalics(text, chunks, hardMaxChars);
3427
3415
  }
3428
3416
  function chunkDiscordTextWithMode(text, opts) {
3429
3417
  if ((opts.chunkMode ?? "length") !== "newline") return chunkDiscordText(text, opts);
3430
- const lineChunks = chunkMarkdownTextWithMode(text, resolveDiscordChunkLimit(opts.maxChars, DEFAULT_MAX_CHARS), "newline");
3431
- const chunks = [];
3432
- for (const line of lineChunks) {
3433
- const nested = chunkDiscordText(line, opts);
3434
- if (!nested.length && line) {
3435
- chunks.push(line);
3436
- continue;
3437
- }
3438
- chunks.push(...nested);
3439
- }
3440
- return chunks;
3441
- }
3442
- function leadingCodeSpanEnd(body) {
3443
- if (!body) return -1;
3444
- const firstNewline = body.indexOf("\n");
3445
- const openFence = parseFenceLine(firstNewline === -1 ? body : body.slice(0, firstNewline));
3446
- if (openFence) {
3447
- if (firstNewline === -1) return body.length;
3448
- let lineStart = firstNewline + 1;
3449
- while (lineStart <= body.length) {
3450
- const lineEnd = body.indexOf("\n", lineStart);
3451
- const line = lineEnd === -1 ? body.slice(lineStart) : body.slice(lineStart, lineEnd);
3452
- const closeFence = parseFenceLine(line);
3453
- const closeSuffix = closeFence ? line.slice(closeFence.indent.length + closeFence.markerLen) : "";
3454
- if (closeFence?.markerChar === openFence.markerChar && closeFence.markerLen >= openFence.markerLen && /^[ \t]*_?[ \t]*$/u.test(closeSuffix)) {
3455
- const markerEnd = closeFence.indent.length + closeFence.markerLen;
3456
- const trailingSpaces = /^ */.exec(line.slice(markerEnd))?.[0].length ?? 0;
3457
- return lineStart + markerEnd + trailingSpaces;
3458
- }
3459
- if (lineEnd === -1) return body.length;
3460
- lineStart = lineEnd + 1;
3461
- }
3462
- return body.length;
3463
- }
3464
- if (!body.startsWith("`")) return -1;
3465
- const ticks = /^(?<ticks>`+)/.exec(body)?.groups?.ticks;
3466
- if (!ticks) return -1;
3467
- for (let index = ticks.length; index < body.length;) {
3468
- if (body[index] !== "`") {
3469
- index += 1;
3470
- continue;
3471
- }
3472
- let runEnd = index + 1;
3473
- while (body[runEnd] === "`") runEnd += 1;
3474
- if (runEnd - index === ticks.length) return runEnd;
3475
- index = runEnd;
3476
- }
3477
- return -1;
3418
+ return chunkByParagraph(text, resolveDiscordChunkLimit(opts.maxChars, DEFAULT_MAX_CHARS), { splitLongParagraphs: false }).flatMap((line) => {
3419
+ const chunks = chunkDiscordText(line, opts);
3420
+ return chunks.length || !line ? chunks : [line];
3421
+ });
3478
3422
  }
3479
3423
  function leadingCodePrefixEnd(body) {
3480
- let prefixEnd = leadingCodeSpanEnd(body);
3481
- if (prefixEnd < 0) return -1;
3482
- while (prefixEnd < body.length) {
3483
- const separator = /^\s+/u.exec(body.slice(prefixEnd))?.[0] ?? "";
3484
- if (!separator) break;
3485
- const nextStart = prefixEnd + separator.length;
3486
- const nextEnd = leadingCodeSpanEnd(body.slice(nextStart));
3487
- if (nextEnd < 0) break;
3488
- prefixEnd = nextStart + nextEnd;
3424
+ let offset = 0;
3425
+ let prefixEnd = -1;
3426
+ while (offset < body.length) {
3427
+ const rest = body.slice(offset);
3428
+ const fence = parseFenceLine(rest.split("\n", 1)[0] ?? "");
3429
+ const marker = fence?.marker ?? /^`+/.exec(rest)?.[0];
3430
+ if (!marker) return prefixEnd;
3431
+ const pattern = fence ? `\\n( {0,3}${marker[0]}{${marker.length},} *)(?=[\\t ]*_?[\\t ]*(?:\\n|$))` : "(?<!`)`{" + marker.length + "}(?!`)";
3432
+ const delimiter = new RegExp(pattern, "g");
3433
+ delimiter.lastIndex = fence ? 0 : marker.length;
3434
+ const match = delimiter.exec(rest);
3435
+ if (!match) return fence ? body.length : prefixEnd;
3436
+ prefixEnd = offset + match.index + match[0].length;
3437
+ const separator = /^\s+/u.exec(body.slice(prefixEnd))?.[0];
3438
+ if (!separator) return prefixEnd;
3439
+ offset = prefixEnd + separator.length;
3489
3440
  }
3490
3441
  return prefixEnd;
3491
3442
  }
3492
- function hasReasoningItalicsOpen(chunk) {
3493
- const trimmed = chunk.trimStart();
3494
- if (trimmed.startsWith("_") || /^(?:Reasoning:|Thinking\.{0,3})\n+_/u.test(trimmed)) return true;
3495
- const codeEnd = leadingCodePrefixEnd(trimmed);
3496
- return codeEnd >= 0 && trimmed.slice(codeEnd).trimStart().startsWith("_");
3497
- }
3498
- function reopenReasoningItalicsAfterLeadingCode(body, codeEnd) {
3499
- const code = body.slice(0, codeEnd);
3500
- const rest = body.slice(codeEnd);
3501
- if (!rest.trim()) return code + rest;
3502
- if (/^\s*_\s*$/.test(rest)) return code;
3503
- const whitespaceLength = rest.length - rest.trimStart().length;
3504
- const whitespace = rest.slice(0, whitespaceLength);
3505
- const restBody = rest.slice(whitespaceLength);
3506
- return restBody.startsWith("_") ? code + rest : `${code}${whitespace}_${restBody}`;
3507
- }
3508
3443
  function rebalanceReasoningItalics(source, chunks, maxChars) {
3509
- if (chunks.length <= 1 || maxChars < MIN_REASONING_ITALICS_CHUNK_CHARS) return chunks;
3510
- if (!hasReasoningItalics(source)) return chunks;
3511
- const adjusted = [...chunks];
3512
- for (let i = 0; i < adjusted.length; i++) {
3513
- const isLast = i === adjusted.length - 1;
3514
- const current = expectDefined(adjusted[i], "Discord chunk adjustment index");
3515
- if (!current.trimEnd().endsWith("_") && hasReasoningItalicsOpen(current)) adjusted[i] = `${current}_`;
3516
- if (isLast) break;
3517
- const next = expectDefined(adjusted[i + 1], "non-final Discord chunk successor");
3518
- const leadingWhitespaceLen = next.length - next.trimStart().length;
3519
- const leadingWhitespace = next.slice(0, leadingWhitespaceLen);
3520
- const nextBody = next.slice(leadingWhitespaceLen);
3521
- if (nextBody.startsWith("_")) continue;
3522
- const codeEnd = leadingCodePrefixEnd(nextBody);
3523
- adjusted[i + 1] = codeEnd >= 0 ? `${leadingWhitespace}${reopenReasoningItalicsAfterLeadingCode(nextBody, codeEnd)}` : `${leadingWhitespace}_${nextBody}`;
3524
- }
3525
- return adjusted;
3444
+ if (chunks.length <= 1 || maxChars < MIN_REASONING_ITALICS_CHUNK_CHARS || !hasReasoningItalics(source)) return chunks;
3445
+ return chunks.map((chunk, index) => {
3446
+ const leadingWhitespace = chunk.length - chunk.trimStart().length;
3447
+ const codeEnd = leadingCodePrefixEnd(chunk.slice(leadingWhitespace));
3448
+ const prefixEnd = leadingWhitespace + Math.max(0, codeEnd);
3449
+ const prefix = chunk.slice(0, prefixEnd);
3450
+ let body = chunk.slice(prefixEnd);
3451
+ if (index > 0) {
3452
+ if (codeEnd >= 0 && /^\s*_\s*$/.test(body)) return prefix;
3453
+ const content = body.trimStart();
3454
+ if (content && !content.startsWith("_")) body = `${body.slice(0, body.length - content.length)}_${content}`;
3455
+ }
3456
+ if (!body.trimEnd().endsWith("_") && /^(?:_|(?:Reasoning:|Thinking\.{0,3})\n+_)/u.test(body.trimStart())) body += "_";
3457
+ return prefix + body;
3458
+ });
3459
+ }
3460
+ function renderInlineCode(body, delimiter) {
3461
+ const runs = new Set(Array.from(body.matchAll(/`+/g), (match) => match[0].length));
3462
+ let marker = delimiter;
3463
+ if (runs.has(marker.length) || marker.length >= 3 && /[\r\n]/.test(body)) {
3464
+ marker = "`";
3465
+ while (runs.has(marker.length)) marker += "`";
3466
+ }
3467
+ if (marker.length >= 3 && /[\r\n]/.test(body) && !body.split(/\r\n|[\r\n]/, 1)[0]?.includes("`")) return;
3468
+ const normalized = body.replace(/\r\n|[\r\n]/g, " ");
3469
+ const padding = body.startsWith("`") || body.endsWith("`") || normalized.startsWith(" ") && normalized.endsWith(" ") && /[^ ]/.test(normalized) ? " " : "";
3470
+ return marker + padding + body + padding + marker;
3471
+ }
3472
+ function createDiscordRanges(source, maxChars, maxLines) {
3473
+ const spans = [];
3474
+ const fences = [];
3475
+ let offset = 0;
3476
+ let plainStart = 0;
3477
+ let fence;
3478
+ const collect = (end) => {
3479
+ for (const span of findCodeRegions(source.slice(plainStart, end), {
3480
+ includeSource: true,
3481
+ syntax: "commonmark"
3482
+ })) {
3483
+ if (span.block) continue;
3484
+ const start = plainStart + span.start;
3485
+ const finish = plainStart + span.end;
3486
+ const marker = /^`+/.exec(source.slice(start, finish))?.[0];
3487
+ if (!marker) continue;
3488
+ const code = expectDefined(span.source, "inline code source map");
3489
+ const atomicTicks = (renderInlineCode("`", marker)?.length ?? Infinity) + code.prefix.text.length > maxChars;
3490
+ const pattern = atomicTicks ? /`+|\r\n|[\s\S]/gu : /\r\n|[\s\S]/gu;
3491
+ if (Array.from(source.slice(start, finish).matchAll(pattern)).every(({ index, 0: raw }) => {
3492
+ const value = code.value.slice(code.offsets[index], code.offsets[index + raw.length]);
3493
+ return !value || (renderInlineCode(value, marker)?.length ?? Infinity) + code.prefix.text.length <= maxChars;
3494
+ }) && (maxLines > 1 || !code.value.includes("\n"))) spans.push({
3495
+ start,
3496
+ end: finish,
3497
+ code,
3498
+ base: plainStart,
3499
+ marker,
3500
+ atomicTicks
3501
+ });
3502
+ }
3503
+ };
3504
+ for (const line of source.split("\n")) {
3505
+ const info = parseFenceLine(line, maxChars);
3506
+ if (info && !fence) {
3507
+ collect(offset);
3508
+ fence = {
3509
+ start: offset,
3510
+ bodyStart: offset + line.length + 1,
3511
+ closeStart: source.length,
3512
+ end: source.length,
3513
+ ...info
3514
+ };
3515
+ fences.push(fence);
3516
+ } else if (info && fence && closesFence(fence, info)) {
3517
+ fence.closeStart = offset;
3518
+ fence.end = offset + line.length;
3519
+ fence = void 0;
3520
+ plainStart = offset + line.length + 1;
3521
+ }
3522
+ offset += line.length + 1;
3523
+ }
3524
+ if (!fence) collect(source.length);
3525
+ const overlaps = (start, end) => spans.some((span) => span.start < end && span.end > start);
3526
+ const joins = (end, start) => end <= start && spans.some((span) => span.start < end && end < span.end && start < span.end);
3527
+ const boundary = (start, end) => {
3528
+ let safe = avoidTrailingHighSurrogateBreak(source, start, end);
3529
+ for (const span of spans) {
3530
+ const prefix = span.code.prefix;
3531
+ if (span.base + prefix.start < safe && safe < span.base + prefix.end) return span.base + prefix.start;
3532
+ if (span.start < safe && safe < span.end) {
3533
+ if (source[safe - 1] === "\r" && source[safe] === "\n") safe -= 1;
3534
+ if (span.atomicTicks) while (source[safe - 1] === "`" && source[safe] === "`") safe -= 1;
3535
+ }
3536
+ }
3537
+ return safe;
3538
+ };
3539
+ const render = (start, end) => {
3540
+ let cursor = start, text = "";
3541
+ for (const span of spans) {
3542
+ if (span.end <= start || span.start >= end) continue;
3543
+ const prefix = span.code.prefix;
3544
+ const prefixStart = span.base + prefix.start;
3545
+ if (start > span.base + prefix.ownerStart && cursor <= prefixStart) {
3546
+ text += source.slice(cursor, prefixStart) + prefix.text;
3547
+ cursor = span.base + prefix.end;
3548
+ }
3549
+ text += source.slice(cursor, Math.max(cursor, span.start));
3550
+ if (span.start >= start && span.end <= end) text += source.slice(span.start, span.end);
3551
+ else {
3552
+ const body = span.code.value.slice(span.code.offsets[Math.max(start, span.start) - span.start], span.code.offsets[Math.min(end, span.end) - span.start]);
3553
+ if (body) {
3554
+ const value = renderInlineCode(body, span.marker);
3555
+ if (value === void 0) return;
3556
+ text += (span.start < start ? span.code.prefix.text : "") + value;
3557
+ }
3558
+ }
3559
+ cursor = Math.min(end, span.end);
3560
+ }
3561
+ return text + source.slice(cursor, end);
3562
+ };
3563
+ const fenceAt = (position) => fences.find((range) => range.bodyStart - 1 <= position && (position < range.end || position === range.end && range.closeStart === range.end));
3564
+ const cutBoundary = (start, end) => {
3565
+ const safe = boundary(start, end);
3566
+ for (const range of fences) {
3567
+ if (start < range.start && range.start < safe && safe <= range.bodyStart) return range.start;
3568
+ if (range.closeStart < safe && safe < range.end) return range.closeStart;
3569
+ }
3570
+ return safe;
3571
+ };
3572
+ return {
3573
+ render,
3574
+ overlaps,
3575
+ joins,
3576
+ boundary,
3577
+ fenceAt,
3578
+ cutBoundary
3579
+ };
3526
3580
  }
3527
3581
  //#endregion
3528
3582
  //#region extensions/discord/src/retry.ts
@@ -1,5 +1,5 @@
1
1
  import { c as resolveDiscordAccount, g as selectDiscordActivitiesRuntimeConfig, n as isDiscordAccountEnabledForRuntime, r as listDiscordAccountIds } from "./accounts-CwJQoLjM.js";
2
- import { z as resolveDiscordProxyFetchForAccount } from "./send.shared-5vxBTagO.js";
2
+ import { z as resolveDiscordProxyFetchForAccount } from "./send.shared-B0n_fWzu.js";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  //#region extensions/discord/src/activities/config.ts
5
5
  function resolveDiscordActivitiesConfig(account, env = process.env) {
@@ -1,14 +1,14 @@
1
- import { d as createReusableDiscordReplyReference, p as resolveDiscordReplyReference, y as resolveDiscordChannelId } from "./retry-BNCxiyyR.js";
2
- import { h as readDiscordComponentSpec, m as coerceDiscordComponentParam } from "./components-DmXYIQ26.js";
1
+ import { d as createReusableDiscordReplyReference, p as resolveDiscordReplyReference, y as resolveDiscordChannelId } from "./retry-DQt1zDgH.js";
2
+ import { h as readDiscordComponentSpec, m as coerceDiscordComponentParam } from "./components-BimX47Mq.js";
3
3
  import { o as mergeDiscordAccountConfig, s as resolveDefaultDiscordAccountId, t as createDiscordActionGate } from "./accounts-CwJQoLjM.js";
4
- import { r as sendDiscordComponentMessage } from "./send.components-BWVEcjRP.js";
5
- import { a as normalizeDiscordSlug, c as resolveDiscordChannelConfigWithFallback, n as isDiscordGroupAllowedByPolicy, v as resolveGroupDmAllow } from "./allow-list-C2JuH-R0.js";
6
- import { F as createDiscordRuntimeAccountContext, T as hasAnyGuildPermissionDiscord, U as getGateway, d as resolveDiscordTargetChannelId, v as canManageGuildMemberRoleDiscord, w as hasAnyChannelPermissionDiscord, x as fetchChannelPermissionsDiscord, y as canManageGuildRoleDiscord } from "./send.shared-5vxBTagO.js";
7
- import { r as sendStickerDiscord, t as sendMessageDiscord } from "./send.outbound-b5xwHTlL.js";
4
+ import { r as sendDiscordComponentMessage } from "./send.components-BG5IDABj.js";
5
+ import { _ as resolveGroupDmAllow, a as normalizeDiscordSlug, c as resolveDiscordChannelConfigWithFallback, n as isDiscordGroupAllowedByPolicy } from "./allow-list-DBTtR2dz.js";
6
+ import { F as createDiscordRuntimeAccountContext, T as hasAnyGuildPermissionDiscord, U as getGateway, d as resolveDiscordTargetChannelId, v as canManageGuildMemberRoleDiscord, w as hasAnyChannelPermissionDiscord, x as fetchChannelPermissionsDiscord, y as canManageGuildRoleDiscord } from "./send.shared-B0n_fWzu.js";
7
+ import { r as sendStickerDiscord, t as sendMessageDiscord } from "./send.outbound-DHuFUL6W.js";
8
8
  import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
9
9
  import { n as getPresence } from "./presence-cache-z1N8MbJ3.js";
10
- import { A as listScheduledEventsDiscord, B as moveChannelDiscord, C as fetchChannelInfoDiscord, D as fetchVoiceStatusDiscord, E as fetchRoleInfoDiscord, F as uploadEmojiDiscord, H as setChannelPermissionDiscord, I as uploadStickerDiscord, L as createChannelDiscord, M as resolveEventCoverImage, N as timeoutMemberDiscord, O as kickMemberDiscord, P as listGuildEmojisDiscord, R as deleteChannelDiscord, S as createScheduledEventDiscord, T as fetchMemberInfoDiscord, V as removeChannelPermissionDiscord, _ as readMessagesDiscord, a as removeReactionDiscord, b as addRoleDiscord, d as deleteMessageDiscord, f as editMessageDiscord, g as pinMessageDiscord, h as listThreadsDiscord, i as removeOwnReactionsDiscord, j as removeRoleDiscord, k as listGuildChannelsDiscord, l as DiscordThreadInitialMessageError, m as listPinsDiscord, n as fetchReactionsDiscord, p as fetchMessageDiscord, r as reactMessageDiscord, s as sendVoiceMessageDiscord, u as createThreadDiscord, v as searchMessagesDiscord, w as fetchGuildInfoDiscord, x as banMemberDiscord, y as unpinMessageDiscord, z as editChannelDiscord } from "./send-BnTEIeLE.js";
11
- import "./targets-DbxVbq8k.js";
10
+ import { A as listScheduledEventsDiscord, B as moveChannelDiscord, C as fetchChannelInfoDiscord, D as fetchVoiceStatusDiscord, E as fetchRoleInfoDiscord, F as uploadEmojiDiscord, H as setChannelPermissionDiscord, I as uploadStickerDiscord, L as createChannelDiscord, M as resolveEventCoverImage, N as timeoutMemberDiscord, O as kickMemberDiscord, P as listGuildEmojisDiscord, R as deleteChannelDiscord, S as createScheduledEventDiscord, T as fetchMemberInfoDiscord, V as removeChannelPermissionDiscord, _ as readMessagesDiscord, a as removeReactionDiscord, b as addRoleDiscord, d as deleteMessageDiscord, f as editMessageDiscord, g as pinMessageDiscord, h as listThreadsDiscord, i as removeOwnReactionsDiscord, j as removeRoleDiscord, k as listGuildChannelsDiscord, l as DiscordThreadInitialMessageError, m as listPinsDiscord, n as fetchReactionsDiscord, p as fetchMessageDiscord, r as reactMessageDiscord, s as sendVoiceMessageDiscord, u as createThreadDiscord, v as searchMessagesDiscord, w as fetchGuildInfoDiscord, x as banMemberDiscord, y as unpinMessageDiscord, z as editChannelDiscord } from "./send-CZeWKUiA.js";
11
+ import "./targets-BObRyaKX.js";
12
12
  import { ChannelType, PermissionFlagsBits } from "discord-api-types/v10";
13
13
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
14
14
  import { asBoolean, isRecord, normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -1091,7 +1091,11 @@ async function handleDiscordMessageManagementAction(ctx) {
1091
1091
  if (!ctx.isActionEnabled("messages")) throw new Error("Discord message edits are disabled.");
1092
1092
  const channelId = ctx.resolveChannelId();
1093
1093
  const messageId = readStringParam(ctx.params, "messageId", { required: true });
1094
- const content = readStringParam(ctx.params, "content", { required: true });
1094
+ const content = readStringParam(ctx.params, "content", {
1095
+ required: true,
1096
+ allowEmpty: true,
1097
+ trim: false
1098
+ });
1095
1099
  await ctx.assertReadTargetAllowed({ channelId });
1096
1100
  const message = await discordMessagingActionRuntime.editMessageDiscord(channelId, messageId, { content }, ctx.withOpts());
1097
1101
  return jsonResult({
@@ -1322,7 +1326,7 @@ async function handleDiscordMessageSendAction(ctx) {
1322
1326
  case "sticker": {
1323
1327
  if (!ctx.isActionEnabled("stickers")) throw new Error("Discord stickers are disabled.");
1324
1328
  const to = readStringParam(ctx.params, "to", { required: true });
1325
- const content = readStringParam(ctx.params, "content");
1329
+ const content = readStringParam(ctx.params, "content", { trim: false });
1326
1330
  const stickerIds = readStringArrayParam(ctx.params, "stickerIds", {
1327
1331
  required: true,
1328
1332
  label: "stickerIds"
@@ -1350,7 +1354,8 @@ async function handleDiscordMessageSendAction(ctx) {
1350
1354
  const embeds = Array.isArray(rawEmbeds) ? rawEmbeds : void 0;
1351
1355
  const content = readStringParam(ctx.params, "content", {
1352
1356
  required: !asVoice && !componentSpec && !components && !embeds?.length && !mediaUrl,
1353
- allowEmpty: true
1357
+ allowEmpty: true,
1358
+ trim: false
1354
1359
  });
1355
1360
  const filename = readStringParam(ctx.params, "filename");
1356
1361
  const replyTo = readStringParam(ctx.params, "replyTo");
@@ -1437,7 +1442,7 @@ async function handleDiscordMessageSendAction(ctx) {
1437
1442
  const channelId = ctx.resolveChannelId();
1438
1443
  const name = readStringParam(ctx.params, "name", { required: true });
1439
1444
  const messageId = readStringParam(ctx.params, "messageId");
1440
- const content = readStringParam(ctx.params, "content");
1445
+ const content = readStringParam(ctx.params, "content", { trim: false });
1441
1446
  const payload = {
1442
1447
  name,
1443
1448
  messageId,
@@ -1500,7 +1505,10 @@ async function handleDiscordMessageSendAction(ctx) {
1500
1505
  case "threadReply": {
1501
1506
  if (!ctx.isActionEnabled("threads")) throw new Error("Discord threads are disabled.");
1502
1507
  const channelId = ctx.resolveChannelId();
1503
- const content = readStringParam(ctx.params, "content", { required: true });
1508
+ const content = readStringParam(ctx.params, "content", {
1509
+ required: true,
1510
+ trim: false
1511
+ });
1504
1512
  const mediaUrl = readStringParam(ctx.params, "mediaUrl");
1505
1513
  const replyTo = readStringParam(ctx.params, "replyTo");
1506
1514
  const result = await discordMessagingActionRuntime.sendMessageDiscord(`channel:${channelId}`, content, {
@@ -1624,14 +1632,14 @@ async function handleDiscordModerationAction(action, params, isActionEnabled, cf
1624
1632
  }
1625
1633
  //#endregion
1626
1634
  //#region extensions/discord/src/actions/runtime.presence.ts
1627
- const ACTIVITY_TYPE_MAP = {
1628
- playing: 0,
1629
- streaming: 1,
1630
- listening: 2,
1631
- watching: 3,
1632
- custom: 4,
1633
- competing: 5
1634
- };
1635
+ const ACTIVITY_TYPE_MAP = /* @__PURE__ */ new Map([
1636
+ ["playing", 0],
1637
+ ["streaming", 1],
1638
+ ["listening", 2],
1639
+ ["watching", 3],
1640
+ ["custom", 4],
1641
+ ["competing", 5]
1642
+ ]);
1635
1643
  const VALID_STATUSES = /* @__PURE__ */ new Set([
1636
1644
  "online",
1637
1645
  "dnd",
@@ -1652,9 +1660,9 @@ async function handleDiscordPresenceAction(action, params, isActionEnabled, cfg)
1652
1660
  const activityName = readStringParam(params, "activityName");
1653
1661
  const activities = [];
1654
1662
  if (activityTypeRaw || activityName) {
1655
- if (!activityTypeRaw) throw new Error(`activityType is required when activityName is provided. Valid types: ${Object.keys(ACTIVITY_TYPE_MAP).join(", ")}`);
1656
- const typeNum = ACTIVITY_TYPE_MAP[normalizeLowercaseStringOrEmpty(activityTypeRaw)];
1657
- if (typeNum === void 0) throw new Error(`Invalid activityType "${activityTypeRaw}". Must be one of: ${Object.keys(ACTIVITY_TYPE_MAP).join(", ")}`);
1663
+ if (!activityTypeRaw) throw new Error(`activityType is required when activityName is provided. Valid types: ${[...ACTIVITY_TYPE_MAP.keys()].join(", ")}`);
1664
+ const typeNum = ACTIVITY_TYPE_MAP.get(normalizeLowercaseStringOrEmpty(activityTypeRaw));
1665
+ if (typeNum === void 0) throw new Error(`Invalid activityType "${activityTypeRaw}". Must be one of: ${[...ACTIVITY_TYPE_MAP.keys()].join(", ")}`);
1658
1666
  const activity = {
1659
1667
  name: activityName ?? "",
1660
1668
  type: typeNum