@openclaw/discord 2026.6.11 → 2026.7.1-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/action-runtime-api.js +1 -1
  2. package/dist/{api-4GFMoWu0.js → api-CJvEMuA6.js} +9 -2
  3. package/dist/api.js +14 -14
  4. package/dist/{approval-handler.runtime-SsFtZQA6.js → approval-handler.runtime-Cg7CuLSc.js} +3 -3
  5. package/dist/{audit-CAnmyf2A.js → audit-BCVhE9Oe.js} +3 -3
  6. package/dist/{channel-YA7AbYP3.js → channel-CfngVOjW.js} +17 -37
  7. package/dist/{channel-actions-BJ3n5Z1l.js → channel-actions-DJ_i4v9b.js} +3 -6
  8. package/dist/{channel-actions.runtime-D2QTRgZ9.js → channel-actions.runtime-BDW12z0o.js} +5 -5
  9. package/dist/channel-plugin-api.js +1 -1
  10. package/dist/{channel.setup-B1zDEAR7.js → channel.setup-BYZ78cmU.js} +3 -3
  11. package/dist/{components-Dm4c_ce6.js → components-CBPNJhVP.js} +1 -1
  12. package/dist/{conversation-identity-DZ0BD7xO.js → conversation-identity-CnYbx3sO.js} +2 -2
  13. package/dist/{directory-config-BK1OhHa3.js → directory-config-CouAqvDj.js} +1 -1
  14. package/dist/directory-contract-api.js +1 -1
  15. package/dist/{directory-live-DP3CmwGf.js → directory-live-C8lwwDJo.js} +2 -2
  16. package/dist/{doctor-D3ngpo-Y.js → doctor-CKIw8urm.js} +1 -1
  17. package/dist/{handle-action.guild-admin-B2cOoU2D.js → handle-action.guild-admin-CHMDXefq.js} +2 -2
  18. package/dist/index.js +1 -1
  19. package/dist/{manager.runtime-CPHxr9B3.js → manager.runtime-BkMOU8kh.js} +4 -4
  20. package/dist/{message-handler-CKaTgBIV.js → message-handler-B2cEpj5S.js} +11 -15
  21. package/dist/{message-handler.preflight--eAiaewz.js → message-handler.preflight-B93Az6zg.js} +15 -41
  22. package/dist/{message-handler.process-PhKAmrEd.js → message-handler.process-CW5mMw4o.js} +204 -33
  23. package/dist/{message-utils-O1vK3kPu.js → message-utils-Dy9KeClm.js} +1 -1
  24. package/dist/{outbound-adapter-fO_7hbTh.js → outbound-adapter-n_qRwyHZ.js} +17 -23
  25. package/dist/{pluralkit-B3MzPaPU.js → pluralkit-DaWTJTmF.js} +3 -3
  26. package/dist/{preflight-audio-ClWbnQto.js → preflight-audio-DecwnhEA.js} +2 -5
  27. package/dist/{probe-CxnDikWm.js → probe-Bkf8mJlj.js} +3 -2
  28. package/dist/{probe.runtime-DLFkSDVB.js → probe.runtime-3Rerer9g.js} +1 -1
  29. package/dist/{provider-BJaJ20MY.js → provider-BuTO6czP.js} +68 -60
  30. package/dist/{provider-session.runtime-D6xc-60s.js → provider-session.runtime-DmBTGaQX.js} +3 -3
  31. package/dist/provider.runtime-CqZpKOCE.js +2 -0
  32. package/dist/{resolve-allowlist-common-BDpBb8dF.js → resolve-allowlist-common-BDNoAQll.js} +1 -1
  33. package/dist/{resolve-channels-iJIjYfRw.js → resolve-channels-C_rAwrkj.js} +3 -3
  34. package/dist/{resolve-users-_fv1mm1f.js → resolve-users-Cz1tkemy.js} +3 -3
  35. package/dist/{runtime-ywXByivr.js → runtime-DaaaVvJm.js} +330 -303
  36. package/dist/runtime-api.actions.js +2 -2
  37. package/dist/runtime-api.js +19 -19
  38. package/dist/runtime-api.lookup.js +5 -5
  39. package/dist/runtime-api.monitor-ChuqOjHq.js +6 -0
  40. package/dist/runtime-api.monitor.js +4 -4
  41. package/dist/runtime-api.send.js +5 -5
  42. package/dist/runtime-api.threads.js +3 -3
  43. package/dist/{send-Dc5uQX5H.js → send-B_yfprXu.js} +18 -9
  44. package/dist/{send.components-D4bl20xr.js → send.components-C2psXc7A.js} +4 -4
  45. package/dist/{send.outbound-5axvwLkl.js → send.outbound-BPcCF1v2.js} +5 -4
  46. package/dist/{send.receipt-B21MspvT.js → send.receipt-CK162xD0.js} +28 -1
  47. package/dist/{send.shared-9082A2sO.js → send.shared-CUTfqvXx.js} +4 -15
  48. package/dist/session-binding-contract-api.js +1 -1
  49. package/dist/setup-plugin-api.js +1 -1
  50. package/dist/{shared-D11J9bXI.js → shared-AnStShZr.js} +3 -10
  51. package/dist/{subagent-hooks-NTv6B4up.js → subagent-hooks-DkO-jpvh.js} +2 -2
  52. package/dist/subagent-hooks-api.js +2 -5
  53. package/dist/{system-events-BzaI1WpN.js → system-events-XRYuwB2n.js} +1 -1
  54. package/dist/{target-resolver-agnOrtOU.js → target-resolver-DYufMbXm.js} +2 -2
  55. package/dist/targets-BA7gf0K0.js +3 -0
  56. package/dist/{thread-bindings-DNitaHVh.js → thread-bindings-BuXtcLSp.js} +4 -4
  57. package/dist/{thread-bindings.discord-api-CjYNuvZa.js → thread-bindings.discord-api-CetgvIbE.js} +4 -4
  58. package/dist/{thread-bindings.manager-PZvJ4TJx.js → thread-bindings.manager-B7AHjU4s.js} +3 -3
  59. package/dist/{transcripts-source-Bi8N6h5X.js → transcripts-source-DW6d1eCL.js} +1 -1
  60. package/dist/transcripts-source-api.js +1 -1
  61. package/dist/{typing-BdRqXUN3.js → typing-BMQEI8OW.js} +1 -1
  62. package/npm-shrinkwrap.json +3 -3
  63. package/package.json +4 -4
  64. package/dist/provider.runtime-jNlHxUSW.js +0 -2
  65. package/dist/runtime-api.monitor-Bb5AaRzg.js +0 -6
  66. package/dist/targets-ClUPljCU.js +0 -3
@@ -1,32 +1,33 @@
1
- import { Ut as resolveDiscordChannelId, c as discord_exports, ft as editChannelMessage, s as chunkDiscordTextWithMode, st as createChannelMessage, ut as deleteChannelMessage } from "./send.receipt-B21MspvT.js";
1
+ import { Ut as resolveDiscordChannelId, c as discord_exports, ft as editChannelMessage, s as chunkDiscordTextWithMode, st as createChannelMessage, ut as deleteChannelMessage } from "./send.receipt-CK162xD0.js";
2
2
  import { f as resolveDiscordMaxLinesPerMessage, s as resolveDiscordAccount } from "./accounts-P19jm1lf.js";
3
- import { I as createDiscordRestClient, L as createDiscordRuntimeAccountContext, _ as resolveDiscordMessageFlags, d as resolveDiscordTargetChannelId } from "./send.shared-9082A2sO.js";
3
+ import { I as createDiscordRestClient, L as createDiscordRuntimeAccountContext, _ as resolveDiscordMessageFlags, d as resolveDiscordTargetChannelId } from "./send.shared-CUTfqvXx.js";
4
4
  import { S as resolveTimestampMs, a as normalizeDiscordSlug, r as normalizeDiscordAllowList } from "./allow-list-C-MqM-B_.js";
5
- import { a as removeReactionDiscord, f as editMessageDiscord, r as reactMessageDiscord } from "./send-Dc5uQX5H.js";
6
- import { a as discordTextHasTargetedMention, i as discordTextHasBroadcastMention, s as rewriteDiscordKnownMentions } from "./send.outbound-5axvwLkl.js";
7
- import "./targets-ClUPljCU.js";
8
- import { t as resolveDiscordConversationIdentity } from "./conversation-identity-DZ0BD7xO.js";
5
+ import { a as removeReactionDiscord, f as editMessageDiscord, r as reactMessageDiscord } from "./send-B_yfprXu.js";
6
+ import { a as discordTextHasTargetedMention, i as discordTextHasBroadcastMention, s as rewriteDiscordKnownMentions } from "./send.outbound-BPcCF1v2.js";
7
+ import "./targets-BA7gf0K0.js";
8
+ import { t as resolveDiscordConversationIdentity } from "./conversation-identity-CnYbx3sO.js";
9
9
  import { t as beginDiscordInboundEventDeliveryCorrelation } from "./inbound-event-delivery-CEPlt2uz.js";
10
10
  import { n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-C5TBc_9x.js";
11
- import { t as DISCORD_TEXT_CHUNK_LIMIT } from "./outbound-adapter-fO_7hbTh.js";
11
+ import { t as DISCORD_TEXT_CHUNK_LIMIT } from "./outbound-adapter-n_qRwyHZ.js";
12
12
  import { t as resolveDiscordPreviewStreamMode } from "./preview-streaming-DXT8oJdo.js";
13
- import { C as resolveDiscordAutoThreadReplyPlan, T as resolveDiscordThreadStarter, a as buildGuildLabel, h as createDiscordSupplementalContextAccessChecker, i as buildDirectLabel, m as buildDiscordInboundAccessContext, n as deliverDiscordReply, o as resolveReplyContext, r as sanitizeDiscordFrontChannelReplyPayloads } from "./provider-BJaJ20MY.js";
14
- import { a as resolveForwardedMediaList, o as resolveMediaList, r as resolveDiscordMessageText, s as resolveReferencedReplyMediaList } from "./message-utils-O1vK3kPu.js";
15
- import { n as createDiscordReplyTypingFeedback } from "./message-handler-CKaTgBIV.js";
13
+ import { C as resolveDiscordAutoThreadReplyPlan, T as resolveDiscordThreadStarter, a as buildGuildLabel, h as createDiscordSupplementalContextAccessChecker, i as buildDirectLabel, m as buildDiscordInboundAccessContext, n as deliverDiscordReply, o as resolveReplyContext, r as sanitizeDiscordFrontChannelReplyPayloads } from "./provider-BuTO6czP.js";
14
+ import { a as resolveForwardedMediaList, o as resolveMediaList, r as resolveDiscordMessageText, s as resolveReferencedReplyMediaList } from "./message-utils-Dy9KeClm.js";
15
+ import { n as createDiscordReplyTypingFeedback } from "./message-handler-B2cEpj5S.js";
16
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
16
17
  import { buildAgentSessionKey, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
17
18
  import { MessageFlags } from "discord-api-types/v10";
18
19
  import { evaluateSupplementalContextVisibility } from "openclaw/plugin-sdk/security-runtime";
19
20
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
20
21
  import { buildTtsSupplementMediaPayload, getReplyPayloadTtsSupplement, isReplyPayloadNonTerminalToolErrorWarning, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
21
22
  import { resolveChunkMode } from "openclaw/plugin-sdk/reply-chunking";
22
- import { danger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
23
+ import { danger, logVerbose, shouldLogVerbose, sleep } from "openclaw/plugin-sdk/runtime-env";
23
24
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
24
25
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
25
26
  import { convertMarkdownTables, stripInlineDirectiveTagsForDelivery, stripReasoningTagsFromText } from "openclaw/plugin-sdk/text-chunking";
26
- import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createFinalizableDraftLifecycle, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, resolveChannelDraftStreamingChunking, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages, resolveTranscriptBackedChannelFinalText } from "openclaw/plugin-sdk/channel-outbound";
27
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
28
+ import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createFinalizableDraftLifecycle, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, isChannelProgressDraftWorkToolName, resolveChannelDraftStreamingChunking, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages, resolveTranscriptBackedChannelFinalText } from "openclaw/plugin-sdk/channel-outbound";
27
29
  import { recordInboundSession, resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/conversation-runtime";
28
30
  import { EmbeddedBlockChunker, resolveAckReaction, resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
29
- import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
30
31
  import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
31
32
  import { getSessionEntry, readSessionUpdatedAt, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
32
33
  import { buildChannelInboundEventContext, dispatchChannelInboundReply, formatInboundEnvelope, hasFinalInboundReplyDispatch, recordChannelBotPairLoopAndCheckSuppression, resolveEnvelopeFormatOptions, toHistoryMediaEntries, toInboundMediaFacts } from "openclaw/plugin-sdk/channel-inbound";
@@ -280,7 +281,8 @@ async function buildDiscordMessageProcessContext(params) {
280
281
  username: senderUsername,
281
282
  tag: sender.tag,
282
283
  roles: memberRoleIds,
283
- displayLabel: senderLabel
284
+ displayLabel: senderLabel,
285
+ isBot: author.bot && !sender.isPluralKit ? true : void 0
284
286
  },
285
287
  conversation: {
286
288
  kind: isDirectMessage ? "direct" : "channel",
@@ -356,6 +358,7 @@ async function buildDiscordMessageProcessContext(params) {
356
358
  ...preflightAudioTranscript !== void 0 ? { Transcript: preflightAudioTranscript } : {},
357
359
  GroupSubject: groupSubject,
358
360
  GroupChannel: groupChannel,
361
+ ...isGuildMessage ? { GroupRequireMention: ctx.groupRequireMention } : {},
359
362
  UntrustedStructuredContext: untrustedContext,
360
363
  OwnerAllowFrom: ownerAllowFrom
361
364
  }
@@ -536,7 +539,8 @@ function createDiscordDraftPreviewController(params) {
536
539
  const discordStreamMode = resolveDiscordPreviewStreamMode(params.discordConfig);
537
540
  const draftMaxChars = Math.min(params.textLimit, 2e3);
538
541
  const accountBlockStreamingEnabled = resolveChannelStreamingBlockEnabled(params.discordConfig) ?? params.cfg.agents?.defaults?.blockStreamingDefault === "on";
539
- const draftStream = !params.sourceRepliesAreToolOnly && discordStreamMode !== "off" && !accountBlockStreamingEnabled ? createDiscordDraftStream({
542
+ const canStreamProgressDraftForToolOnlySource = params.sourceRepliesAreToolOnly && discordStreamMode === "progress";
543
+ const draftStream = (!params.sourceRepliesAreToolOnly || canStreamProgressDraftForToolOnlySource) && discordStreamMode !== "off" && !accountBlockStreamingEnabled ? createDiscordDraftStream({
540
544
  rest: params.deliveryRest,
541
545
  channelId: params.deliverChannelId,
542
546
  maxChars: draftMaxChars,
@@ -567,6 +571,10 @@ function createDiscordDraftPreviewController(params) {
567
571
  mode: discordStreamMode,
568
572
  active: Boolean(draftStream),
569
573
  seed: progressSeed,
574
+ reasoningLinePrefix: "🧠 ",
575
+ commentaryLinePrefix: "💬 ",
576
+ reasoningGate: true,
577
+ commentaryItalics: false,
570
578
  update: async (previewText, options) => {
571
579
  lastPartialText = previewText;
572
580
  draftText = previewText;
@@ -688,6 +696,7 @@ function createDiscordDraftPreviewController(params) {
688
696
  });
689
697
  },
690
698
  handleAssistantMessageBoundary() {
699
+ progressDraft.beginNewTurn();
691
700
  if (discordStreamMode === "progress") return;
692
701
  forceNewMessageIfNeeded();
693
702
  },
@@ -725,16 +734,7 @@ function shouldStartDiscordProgressDraftNow(line) {
725
734
  }
726
735
  //#endregion
727
736
  //#region extensions/discord/src/monitor/message-handler.process.ts
728
- function sleep(ms) {
729
- return new Promise((resolve) => {
730
- setTimeout(resolve, ms);
731
- });
732
- }
733
- let replyRuntimePromise;
734
- async function loadReplyRuntime() {
735
- replyRuntimePromise ??= import("openclaw/plugin-sdk/reply-runtime");
736
- return await replyRuntimePromise;
737
- }
737
+ const loadReplyRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/reply-runtime"));
738
738
  function isProcessAborted(abortSignal) {
739
739
  return Boolean(abortSignal?.aborted);
740
740
  }
@@ -803,6 +803,9 @@ async function processDiscordMessageInner(ctx, observer) {
803
803
  }
804
804
  });
805
805
  const sourceRepliesAreToolOnly = sourceReplyDeliveryMode === "message_tool_only";
806
+ const configuredTypingMode = cfg.session?.typingMode ?? cfg.agents?.defaults?.typingMode;
807
+ const configuredTypingInterval = cfg.agents?.defaults?.typingIntervalSeconds ?? cfg.session?.typingIntervalSeconds;
808
+ const shouldDisableCoreTypingKeepalive = Boolean(replyTypingFeedback) || sourceRepliesAreToolOnly && configuredTypingMode === void 0 && configuredTypingInterval === void 0;
806
809
  const ackReaction = resolveAckReaction(cfg, route.agentId, {
807
810
  channel: "discord",
808
811
  accountId
@@ -950,7 +953,8 @@ async function processDiscordMessageInner(ctx, observer) {
950
953
  accountId,
951
954
  channelId: typingChannelId,
952
955
  rest: feedbackRest,
953
- log: logVerbose
956
+ log: logVerbose,
957
+ keepaliveIntervalMs: shouldDisableCoreTypingKeepalive ? void 0 : 0
954
958
  });
955
959
  if (replyTypingFeedback) replyTypingFeedback.restartForDispatch(typingChannelId);
956
960
  else typingFeedback.updateChannelId(typingChannelId);
@@ -1024,7 +1028,7 @@ async function processDiscordMessageInner(ctx, observer) {
1024
1028
  chunkMode,
1025
1029
  log: logVerbose
1026
1030
  });
1027
- let verboseProgressActive = () => false;
1031
+ let shouldYieldDraftProgress = () => false;
1028
1032
  const finalPreviewFlags = discordConfig?.suppressEmbeds ?? true ? MessageFlags.SuppressEmbeds : void 0;
1029
1033
  let finalReplyStartNotified = false;
1030
1034
  const notifyFinalReplyStart = () => {
@@ -1043,6 +1047,71 @@ async function processDiscordMessageInner(ctx, observer) {
1043
1047
  draftPreview.markFinalReplyDelivered();
1044
1048
  observer?.onFinalReplyDelivered?.();
1045
1049
  };
1050
+ const formatDiscordReasoningQuote = (quoteText) => {
1051
+ const lines = quoteText.split("\n").map((line) => line.trim()).filter(Boolean);
1052
+ if (!lines.length) return;
1053
+ lines[0] = `🧠 ${lines[0]}`;
1054
+ return lines.map((line) => `> ${line}`).join("\n");
1055
+ };
1056
+ const reasoningLevel = (() => {
1057
+ const normalizedAgentId = (route.agentId ?? "").trim().toLowerCase() || "main";
1058
+ const cfgDefault = cfg.agents?.list?.find((entry) => ((entry?.id ?? "").trim().toLowerCase() || "main") === normalizedAgentId)?.reasoningDefault ?? cfg.agents?.defaults?.reasoningDefault;
1059
+ const configDefault = cfgDefault === "on" || cfgDefault === "stream" ? cfgDefault : "off";
1060
+ const sessionKey = ctxPayload.SessionKey;
1061
+ if (!sessionKey) return configDefault;
1062
+ try {
1063
+ const storePath = resolveStorePath(cfg.session?.store, { agentId: route.agentId });
1064
+ const level = getSessionEntry({
1065
+ agentId: route.agentId,
1066
+ sessionKey,
1067
+ storePath
1068
+ })?.reasoningLevel;
1069
+ if (level === "on" || level === "stream" || level === "off") return level;
1070
+ } catch {
1071
+ return "off";
1072
+ }
1073
+ return configDefault;
1074
+ })();
1075
+ const reasoningDurableEnabled = reasoningLevel === "on";
1076
+ const reasoningWindowEnabled = reasoningLevel === "stream";
1077
+ const progressTurnStartedAt = Date.now();
1078
+ let progressReasoningSteps = 0;
1079
+ let progressToolCalls = 0;
1080
+ let progressCommentaryNotes = 0;
1081
+ let persistentReasoningDelivered = false;
1082
+ const seenCommentaryIds = /* @__PURE__ */ new Set();
1083
+ let lastCommentaryNoteText = "";
1084
+ const noteWindowCommentary = (itemId, noteText) => {
1085
+ const trimmed = noteText?.trim();
1086
+ if (!trimmed) return;
1087
+ if (itemId) {
1088
+ if (seenCommentaryIds.has(itemId)) return;
1089
+ seenCommentaryIds.add(itemId);
1090
+ progressCommentaryNotes += 1;
1091
+ return;
1092
+ }
1093
+ if (trimmed !== lastCommentaryNoteText) {
1094
+ lastCommentaryNoteText = trimmed;
1095
+ progressCommentaryNotes += 1;
1096
+ }
1097
+ };
1098
+ let windowReasoningOpen = false;
1099
+ const closePendingWindowThought = () => {
1100
+ if (windowReasoningOpen) {
1101
+ windowReasoningOpen = false;
1102
+ progressReasoningSteps += 1;
1103
+ }
1104
+ };
1105
+ const buildProgressSummaryLine = () => {
1106
+ closePendingWindowThought();
1107
+ const seconds = Math.max(1, Math.round((Date.now() - progressTurnStartedAt) / 1e3));
1108
+ return `-# ${[
1109
+ ...progressReasoningSteps > 0 ? [`🧠 ${progressReasoningSteps} thought${progressReasoningSteps === 1 ? "" : "s"}`] : [],
1110
+ ...progressCommentaryNotes > 0 ? [`💬 ${progressCommentaryNotes} note${progressCommentaryNotes === 1 ? "" : "s"}`] : [],
1111
+ ...progressToolCalls > 0 ? [`🛠️ ${progressToolCalls} tool call${progressToolCalls === 1 ? "" : "s"}`] : [],
1112
+ `⏱️ ${seconds}s`
1113
+ ].join(" · ")}`;
1114
+ };
1046
1115
  const beforeDiscordPayloadDelivery = (payload, info) => {
1047
1116
  if (isProcessAborted(abortSignal)) {
1048
1117
  logVerbose(formatDiscordReplySkip({
@@ -1053,6 +1122,7 @@ async function processDiscordMessageInner(ctx, observer) {
1053
1122
  }));
1054
1123
  return null;
1055
1124
  }
1125
+ if (payload.isReasoning || payload.isCommentary) return payload;
1056
1126
  if (draftPreview.draftStream && draftPreview.isProgressMode && info.kind === "block") {
1057
1127
  if (!resolveSendableOutboundReplyParts(payload).hasMedia && !payload.isError) return null;
1058
1128
  }
@@ -1070,6 +1140,43 @@ async function processDiscordMessageInner(ctx, observer) {
1070
1140
  return { visibleReplySent: false };
1071
1141
  }
1072
1142
  const isFinal = info.kind === "final";
1143
+ if (payload.isReasoning) {
1144
+ const raw = (payload.text ?? "").trim();
1145
+ const body = raw.startsWith("Reasoning:\n") ? raw.slice(11).trim() : raw;
1146
+ if (!body) return { visibleReplySent: false };
1147
+ const chunks = chunkDiscordTextWithMode(body, {
1148
+ maxChars: Math.max(256, Math.min(textLimit, 2e3) - 8),
1149
+ maxLines: maxLinesPerMessage,
1150
+ chunkMode
1151
+ });
1152
+ const replies = (chunks.length ? chunks : [body]).map((chunk) => formatDiscordReasoningQuote(chunk)).filter((quote) => Boolean(quote)).map((quote) => Object.assign({}, payload, {
1153
+ text: quote,
1154
+ isReasoning: void 0
1155
+ }));
1156
+ if (!replies.length) return { visibleReplySent: false };
1157
+ await deliverDiscordReply({
1158
+ cfg,
1159
+ replies,
1160
+ target: deliverTarget,
1161
+ token,
1162
+ accountId,
1163
+ rest: deliveryRest,
1164
+ runtime,
1165
+ replyToId: replyReference.use(),
1166
+ replyToMode,
1167
+ textLimit,
1168
+ maxLinesPerMessage,
1169
+ tableMode,
1170
+ chunkMode,
1171
+ sessionKey: ctxPayload.SessionKey,
1172
+ threadBindings,
1173
+ mediaLocalRoots,
1174
+ kind: "block"
1175
+ });
1176
+ replyReference.markSent();
1177
+ persistentReasoningDelivered = true;
1178
+ return { visibleReplySent: true };
1179
+ }
1073
1180
  if (isFinal && !options?.allowFallbackOnlyToolWarning && isFallbackOnlyToolWarningFinal(payload)) {
1074
1181
  if (!userFacingFinalDelivered && (!finalReplyStartNotified || userFacingFinalDeliveryFailed)) pendingToolWarningFinal = {
1075
1182
  payload,
@@ -1099,7 +1206,53 @@ async function processDiscordMessageInner(ctx, observer) {
1099
1206
  if (draftStream && draftPreview.isProgressMode && info.kind === "block") {
1100
1207
  if (!resolveSendableOutboundReplyParts(deliverablePayload).hasMedia && !deliverablePayload.isError) return { visibleReplySent: false };
1101
1208
  }
1102
- if (draftStream && isFinal && (!draftPreview.isProgressMode || draftPreview.hasProgressDraftStarted) && !deliverablePayload.isError) {
1209
+ if (draftStream && isFinal && draftPreview.isProgressMode && draftPreview.hasProgressDraftStarted && !deliverablePayload.isError && draftStream) {
1210
+ await draftPreview.flush();
1211
+ if (persistentReasoningDelivered) {
1212
+ await draftStream.clear();
1213
+ await deliverDiscordReply({
1214
+ cfg,
1215
+ replies: [{ text: buildProgressSummaryLine() }],
1216
+ target: deliverTarget,
1217
+ token,
1218
+ accountId,
1219
+ rest: deliveryRest,
1220
+ runtime,
1221
+ replyToId: replyReference.use(),
1222
+ replyToMode,
1223
+ textLimit,
1224
+ maxLinesPerMessage,
1225
+ tableMode,
1226
+ chunkMode,
1227
+ sessionKey: ctxPayload.SessionKey,
1228
+ threadBindings,
1229
+ mediaLocalRoots,
1230
+ kind: "block"
1231
+ });
1232
+ replyReference.markSent();
1233
+ draftPreview.markPreviewFinalized();
1234
+ } else {
1235
+ const draftId = draftStream.messageId();
1236
+ if (draftId !== void 0) {
1237
+ await draftStream.seal();
1238
+ try {
1239
+ await editMessageDiscord(deliverChannelId, draftId, {
1240
+ content: buildProgressSummaryLine(),
1241
+ ...finalPreviewFlags ? { flags: finalPreviewFlags } : {}
1242
+ }, {
1243
+ cfg,
1244
+ accountId,
1245
+ rest: deliveryRest
1246
+ });
1247
+ draftPreview.markPreviewFinalized();
1248
+ } catch (err) {
1249
+ logVerbose(`discord: progress draft summary edit failed; clearing draft (${String(err)})`);
1250
+ await draftStream.clear();
1251
+ }
1252
+ }
1253
+ }
1254
+ }
1255
+ if (draftStream && isFinal && !draftPreview.isProgressMode && !deliverablePayload.isError) {
1103
1256
  const hasMedia = resolveSendableOutboundReplyParts(deliverablePayload).hasMedia;
1104
1257
  const ttsSupplement = getReplyPayloadTtsSupplement(deliverablePayload);
1105
1258
  const previewSourceText = deliverablePayload.text ?? ttsSupplement?.spokenText;
@@ -1312,28 +1465,40 @@ async function processDiscordMessageInner(ctx, observer) {
1312
1465
  abortSignal,
1313
1466
  skillFilter: channelConfig?.skills,
1314
1467
  sourceReplyDeliveryMode,
1468
+ typingKeepalive: shouldDisableCoreTypingKeepalive ? false : void 0,
1315
1469
  queuedDeliveryCorrelations: isRoomEvent ? [{ begin: beginDeliveryCorrelation }] : void 0,
1316
1470
  suppressTyping: isRoomEvent ? true : void 0,
1317
- allowProgressCallbacksWhenSourceDeliverySuppressed: sourceRepliesAreToolOnly && statusReactionsExplicitlyEnabled ? true : void 0,
1471
+ allowProgressCallbacksWhenSourceDeliverySuppressed: sourceRepliesAreToolOnly && draftPreview.draftStream && draftPreview.isProgressMode ? true : void 0,
1318
1472
  disableBlockStreaming: sourceRepliesAreToolOnly ? true : draftPreview.disableBlockStreamingForDraft ?? (typeof resolvedBlockStreamingEnabled === "boolean" ? !resolvedBlockStreamingEnabled : void 0),
1319
1473
  onPartialReply: draftPreview.draftStream && !draftPreview.isProgressMode ? (payload) => draftPreview.updateFromPartial(payload.text) : void 0,
1320
1474
  onAssistantMessageStart: draftPreview.draftStream ? () => draftPreview.handleAssistantMessageBoundary() : void 0,
1321
- onReasoningEnd: draftPreview.draftStream ? () => draftPreview.handleAssistantMessageBoundary() : void 0,
1475
+ onReasoningEnd: draftPreview.draftStream ? () => {
1476
+ closePendingWindowThought();
1477
+ return draftPreview.handleAssistantMessageBoundary();
1478
+ } : void 0,
1322
1479
  onModelSelected,
1323
1480
  suppressDefaultToolProgressMessages: sourceRepliesAreToolOnly && statusReactionsExplicitlyEnabled || draftPreview.suppressDefaultToolProgressMessages ? true : void 0,
1324
1481
  allowToolLifecycleWhenProgressHidden: statusReactionsEnabled ? true : void 0,
1325
1482
  commentaryProgressEnabled: draftPreview.isProgressMode ? draftPreview.commentaryProgressEnabled : void 0,
1483
+ commentaryPayloadsEnabled: draftPreview.isProgressMode ? draftPreview.commentaryProgressEnabled : void 0,
1484
+ reasoningPayloadsEnabled: reasoningDurableEnabled,
1326
1485
  onVerboseProgressVisibility: (isActive) => {
1327
- verboseProgressActive = isActive;
1486
+ shouldYieldDraftProgress = isActive;
1328
1487
  },
1329
1488
  onReasoningStream: async (payload) => {
1489
+ if (payload?.requiresReasoningProgressOptIn === true && !reasoningWindowEnabled) return;
1490
+ if (payload?.text) windowReasoningOpen = true;
1330
1491
  await statusReactions.setThinking();
1331
1492
  await draftPreview.pushReasoningProgress(payload?.text, { snapshot: payload?.isReasoningSnapshot === true });
1332
1493
  },
1494
+ streamReasoningInNonStreamModes: reasoningWindowEnabled,
1333
1495
  onToolStart: async (payload) => {
1334
1496
  if (isProcessAborted(abortSignal)) return;
1335
1497
  await maybeBindStatusReactionsToToolReaction(payload);
1336
1498
  await statusReactions.setTool(payload.name);
1499
+ if (payload.phase === "start") closePendingWindowThought();
1500
+ if (shouldYieldDraftProgress()) return;
1501
+ if (payload.phase === "start" && isChannelProgressDraftWorkToolName(payload.name)) progressToolCalls += 1;
1337
1502
  await draftPreview.pushToolProgress(buildChannelProgressDraftLineForEntry(discordConfig, {
1338
1503
  event: "tool",
1339
1504
  itemId: payload.itemId,
@@ -1345,10 +1510,14 @@ async function processDiscordMessageInner(ctx, observer) {
1345
1510
  },
1346
1511
  onItemEvent: async (payload) => {
1347
1512
  if (payload.kind === "preamble") {
1348
- if (verboseProgressActive()) return;
1349
- if (draftPreview.commentaryProgressEnabled && payload.progressText) await draftPreview.pushCommentaryProgress(payload.progressText, { itemId: payload.itemId });
1513
+ if (shouldYieldDraftProgress()) return;
1514
+ if (draftPreview.commentaryProgressEnabled && payload.progressText) {
1515
+ noteWindowCommentary(payload.itemId, payload.progressText);
1516
+ await draftPreview.pushCommentaryProgress(payload.progressText, { itemId: payload.itemId });
1517
+ }
1350
1518
  return;
1351
1519
  }
1520
+ if (shouldYieldDraftProgress()) return;
1352
1521
  await draftPreview.pushToolProgress(buildChannelProgressDraftLineForEntry(discordConfig, {
1353
1522
  event: "item",
1354
1523
  itemId: payload.itemId,
@@ -1386,6 +1555,7 @@ async function processDiscordMessageInner(ctx, observer) {
1386
1555
  },
1387
1556
  onCommandOutput: async (payload) => {
1388
1557
  if (payload.phase !== "end") return;
1558
+ if (shouldYieldDraftProgress()) return;
1389
1559
  await draftPreview.pushToolProgress(buildChannelProgressDraftLine({
1390
1560
  event: "command-output",
1391
1561
  itemId: payload.itemId,
@@ -1399,6 +1569,7 @@ async function processDiscordMessageInner(ctx, observer) {
1399
1569
  },
1400
1570
  onPatchSummary: async (payload) => {
1401
1571
  if (payload.phase !== "end") return;
1572
+ if (shouldYieldDraftProgress()) return;
1402
1573
  await draftPreview.pushToolProgress(buildChannelProgressDraftLine({
1403
1574
  event: "patch",
1404
1575
  itemId: payload.itemId,
@@ -1,5 +1,5 @@
1
1
  import { o as mergeAbortSignals } from "./timeouts-C5TBc_9x.js";
2
- import { u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-CjYNuvZa.js";
2
+ import { u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-CetgvIbE.js";
3
3
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { ComponentType, StickerFormatType } from "discord-api-types/v10";
5
5
  import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
@@ -1,8 +1,9 @@
1
- import { o as normalizeDiscordOutboundTarget, s as chunkDiscordTextWithMode, t as createDiscordSendReceipt, x as DiscordError } from "./send.receipt-B21MspvT.js";
1
+ import { o as normalizeDiscordOutboundTarget, s as chunkDiscordTextWithMode, t as createDiscordSendReceipt, x as DiscordError } from "./send.receipt-CK162xD0.js";
2
2
  import { s as resolveDiscordAccount } from "./accounts-P19jm1lf.js";
3
- import { d as readDiscordComponentSpec } from "./components-Dm4c_ce6.js";
3
+ import { d as readDiscordComponentSpec } from "./components-CBPNJhVP.js";
4
4
  import { t as parseDiscordRetryAfterBodySeconds } from "./retry-after-D5_VmM-_.js";
5
5
  import { n as notifyDiscordInboundEventOutboundPayloadSuccess } from "./inbound-event-delivery-CEPlt2uz.js";
6
+ import { createLazyRuntimeModule, createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
6
7
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
7
8
  import { resolvePayloadMediaUrls, sendPayloadMediaSequenceOrFallback, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
8
9
  import { resolveRetryConfig, retryAsync } from "openclaw/plugin-sdk/retry-runtime";
@@ -83,16 +84,11 @@ function normalizeDiscordApprovalPayload(payload) {
83
84
  }
84
85
  //#endregion
85
86
  //#region extensions/discord/src/outbound-components.ts
86
- let discordComponentSendPromise;
87
- let discordSharedInteractivePromise;
87
+ const loadDiscordComponentSend = createLazyRuntimeNamedExport(() => import("./send.components-C2psXc7A.js").then((n) => n.i), "sendDiscordComponentMessage");
88
88
  async function sendDiscordComponentMessageLazy(...args) {
89
- discordComponentSendPromise ??= import("./send.components-D4bl20xr.js").then((n) => n.i).then((module) => module.sendDiscordComponentMessage);
90
- return await (await discordComponentSendPromise)(...args);
91
- }
92
- function loadDiscordSharedInteractive() {
93
- discordSharedInteractivePromise ??= import("./components-Dm4c_ce6.js").then((n) => n.a);
94
- return discordSharedInteractivePromise;
89
+ return await (await loadDiscordComponentSend())(...args);
95
90
  }
91
+ const loadDiscordSharedInteractive = createLazyRuntimeModule(() => import("./components-CBPNJhVP.js").then((n) => n.a));
96
92
  function addPayloadTextFallback(spec, payload) {
97
93
  return spec.text ? spec : {
98
94
  ...spec,
@@ -123,11 +119,7 @@ async function resolveDiscordComponentSpec(payload) {
123
119
  }
124
120
  //#endregion
125
121
  //#region extensions/discord/src/outbound-send-context.ts
126
- let discordSendRuntimePromise;
127
- async function loadDiscordSendRuntime() {
128
- discordSendRuntimePromise ??= import("./send-Dc5uQX5H.js").then((n) => n.t);
129
- return await discordSendRuntimePromise;
130
- }
122
+ const loadDiscordSendRuntime = createLazyRuntimeModule(() => import("./send-B_yfprXu.js").then((n) => n.t));
131
123
  function resolveDiscordOutboundTarget(params) {
132
124
  if (params.threadId == null) return params.to;
133
125
  const threadId = normalizeOptionalStringifiedId(params.threadId) ?? "";
@@ -210,14 +202,20 @@ async function sendDiscordOutboundPayload(params) {
210
202
  const mediaUrls = resolvePayloadMediaUrls(payload);
211
203
  const sendContext = await createDiscordPayloadSendContext(ctx);
212
204
  if (payload.audioAsVoice && mediaUrls.length > 0) {
213
- let lastResult = await sendContext.withRetry(async () => await sendContext.sendVoice(sendContext.target, mediaUrls[0], resolveDiscordDeliveryOptions(ctx, sendContext)));
205
+ const voiceReplyTo = sendContext.resolveReplyTo();
206
+ let lastResult = await sendContext.withRetry(async () => await sendContext.sendVoice(sendContext.target, mediaUrls[0], {
207
+ ...resolveDiscordDeliveryOptions(ctx, sendContext),
208
+ replyTo: voiceReplyTo
209
+ }));
214
210
  if (payload.text?.trim()) lastResult = await sendContext.withRetry(async () => await sendContext.send(sendContext.target, payload.text, {
215
211
  verbose: false,
216
- ...resolveDiscordFormattedDeliveryOptions(ctx, sendContext)
212
+ ...resolveDiscordFormattedDeliveryOptions(ctx, sendContext),
213
+ replyTo: voiceReplyTo
217
214
  }));
218
215
  for (const mediaUrl of mediaUrls.slice(1)) lastResult = await sendContext.withRetry(async () => await sendContext.send(sendContext.target, "", {
219
216
  verbose: false,
220
- ...resolveDiscordMediaDeliveryOptions(ctx, sendContext, mediaUrl)
217
+ ...resolveDiscordMediaDeliveryOptions(ctx, sendContext, mediaUrl),
218
+ replyTo: voiceReplyTo
221
219
  }));
222
220
  return attachChannelToResult("discord", lastResult);
223
221
  }
@@ -278,11 +276,7 @@ const DISCORD_INTERNAL_RUNTIME_SCAFFOLDING_TAG_RE = /<\s*\/?\s*(?:system-reminde
278
276
  function stripDiscordInternalRuntimeScaffolding(text) {
279
277
  return text.replace(DISCORD_INTERNAL_RUNTIME_SCAFFOLDING_BLOCK_RE, "").replace(DISCORD_INTERNAL_RUNTIME_SCAFFOLDING_SELF_CLOSING_RE, "").replace(DISCORD_INTERNAL_RUNTIME_SCAFFOLDING_TAG_RE, "");
280
278
  }
281
- let discordThreadBindingsPromise;
282
- function loadDiscordThreadBindings() {
283
- discordThreadBindingsPromise ??= import("./thread-bindings-DNitaHVh.js").then((n) => n.t);
284
- return discordThreadBindingsPromise;
285
- }
279
+ const loadDiscordThreadBindings = createLazyRuntimeModule(() => import("./thread-bindings-BuXtcLSp.js").then((n) => n.t));
286
280
  function resolveDiscordWebhookIdentity(params) {
287
281
  const usernameRaw = normalizeOptionalString(params.identity?.name);
288
282
  const fallbackUsername = normalizeOptionalString(params.binding.label) ?? params.binding.agentId;
@@ -1,6 +1,6 @@
1
- import { Wt as __exportAll } from "./send.receipt-B21MspvT.js";
1
+ import { Wt as __exportAll } from "./send.receipt-CK162xD0.js";
2
2
  import { resolveFetch } from "openclaw/plugin-sdk/fetch-runtime";
3
- import { readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
3
+ import { readProviderJsonResponse, readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
4
4
  //#region extensions/discord/src/pluralkit.ts
5
5
  var pluralkit_exports = /* @__PURE__ */ __exportAll({ fetchPluralKitMessageInfo: () => fetchPluralKitMessageInfo });
6
6
  const PLURALKIT_API_BASE = "https://api.pluralkit.me/v2";
@@ -18,7 +18,7 @@ async function fetchPluralKitMessageInfo(params) {
18
18
  const detail = text.trim() ? `: ${text.trim()}` : "";
19
19
  throw new Error(`PluralKit API failed (${res.status})${detail}`);
20
20
  }
21
- return await res.json();
21
+ return await readProviderJsonResponse(res, "PluralKit message");
22
22
  }
23
23
  //#endregion
24
24
  export { pluralkit_exports as n, fetchPluralKitMessageInfo as t };
@@ -1,12 +1,9 @@
1
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
1
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
2
3
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
3
4
  import { getFileExtension } from "openclaw/plugin-sdk/media-mime";
4
5
  //#region extensions/discord/src/monitor/preflight-audio.ts
5
- let discordPreflightAudioRuntimePromise;
6
- function loadDiscordPreflightAudioRuntime() {
7
- discordPreflightAudioRuntimePromise ??= import("./preflight-audio.runtime-CoCXMM8r.js");
8
- return discordPreflightAudioRuntimePromise;
9
- }
6
+ const loadDiscordPreflightAudioRuntime = createLazyRuntimeModule(() => import("./preflight-audio.runtime-CoCXMM8r.js"));
10
7
  const AUDIO_ATTACHMENT_MIME_BY_EXT = new Map([
11
8
  [".aac", "audio/aac"],
12
9
  [".caf", "audio/x-caf"],
@@ -1,7 +1,8 @@
1
1
  import { p as normalizeDiscordToken } from "./accounts-P19jm1lf.js";
2
- import { n as fetchDiscord, t as DiscordApiError } from "./api-4GFMoWu0.js";
2
+ import { n as fetchDiscord, t as DiscordApiError } from "./api-CJvEMuA6.js";
3
3
  import { resolveFetch } from "openclaw/plugin-sdk/fetch-runtime";
4
4
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
5
+ import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
5
6
  import { fetchWithTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
6
7
  //#region extensions/discord/src/probe.ts
7
8
  const DISCORD_API_BASE = "https://discord.com/api/v10";
@@ -78,7 +79,7 @@ async function probeDiscord(token, timeoutMs, opts) {
78
79
  elapsedMs: Date.now() - started
79
80
  };
80
81
  }
81
- const json = await res.json();
82
+ const json = await readProviderJsonResponse(res, "discord.probe.getMe");
82
83
  result.ok = true;
83
84
  result.bot = {
84
85
  id: json.id ?? null,
@@ -1,2 +1,2 @@
1
- import { a as resolveDiscordPrivilegedIntentsFromFlags, i as probeDiscord, n as fetchDiscordApplicationSummary, r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-CxnDikWm.js";
1
+ import { a as resolveDiscordPrivilegedIntentsFromFlags, i as probeDiscord, n as fetchDiscordApplicationSummary, r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-Bkf8mJlj.js";
2
2
  export { fetchDiscordApplicationId, fetchDiscordApplicationSummary, parseApplicationIdFromToken, probeDiscord, resolveDiscordPrivilegedIntentsFromFlags };