@openclaw/discord 2026.6.11 → 2026.7.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) 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-DzoY4ufU.js} +3 -3
  5. package/dist/{audit-CAnmyf2A.js → audit-BXGKCgbA.js} +3 -3
  6. package/dist/{channel-YA7AbYP3.js → channel-Da36gsaP.js} +15 -15
  7. package/dist/{channel-actions-BJ3n5Z1l.js → channel-actions-CamohoDF.js} +2 -2
  8. package/dist/{channel-actions.runtime-D2QTRgZ9.js → channel-actions.runtime-C1y4B9J0.js} +5 -5
  9. package/dist/channel-plugin-api.js +1 -1
  10. package/dist/{channel.setup-B1zDEAR7.js → channel.setup-KhiBHeGT.js} +2 -2
  11. package/dist/{components-Dm4c_ce6.js → components-CBPNJhVP.js} +1 -1
  12. package/dist/{conversation-identity-DZ0BD7xO.js → conversation-identity-BEsyd7A1.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/{handle-action.guild-admin-B2cOoU2D.js → handle-action.guild-admin-zmPNo8TF.js} +2 -2
  17. package/dist/index.js +1 -1
  18. package/dist/{manager.runtime-CPHxr9B3.js → manager.runtime-TLLuQzsA.js} +4 -4
  19. package/dist/{message-handler-CKaTgBIV.js → message-handler-ClZrgeka.js} +10 -7
  20. package/dist/{message-handler.preflight--eAiaewz.js → message-handler.preflight-CjnHwEwP.js} +10 -10
  21. package/dist/{message-handler.process-PhKAmrEd.js → message-handler.process-OruF8JFV.js} +200 -22
  22. package/dist/{message-utils-O1vK3kPu.js → message-utils-C_tYBSAu.js} +1 -1
  23. package/dist/{outbound-adapter-fO_7hbTh.js → outbound-adapter-B0iwUl6c.js} +15 -9
  24. package/dist/{pluralkit-B3MzPaPU.js → pluralkit-DaWTJTmF.js} +3 -3
  25. package/dist/{probe-CxnDikWm.js → probe-Bkf8mJlj.js} +3 -2
  26. package/dist/{probe.runtime-DLFkSDVB.js → probe.runtime-3Rerer9g.js} +1 -1
  27. package/dist/{provider-BJaJ20MY.js → provider-CChQJujf.js} +64 -37
  28. package/dist/{provider-session.runtime-D6xc-60s.js → provider-session.runtime-Dy71XetI.js} +3 -3
  29. package/dist/provider.runtime-BiOSsG0m.js +2 -0
  30. package/dist/{resolve-allowlist-common-BDpBb8dF.js → resolve-allowlist-common-BDNoAQll.js} +1 -1
  31. package/dist/{resolve-channels-iJIjYfRw.js → resolve-channels-C_rAwrkj.js} +3 -3
  32. package/dist/{resolve-users-_fv1mm1f.js → resolve-users-Cz1tkemy.js} +3 -3
  33. package/dist/{runtime-ywXByivr.js → runtime-C-fNslbg.js} +9 -10
  34. package/dist/runtime-api.actions.js +2 -2
  35. package/dist/runtime-api.js +19 -19
  36. package/dist/runtime-api.lookup.js +5 -5
  37. package/dist/runtime-api.monitor-CN1_mmYY.js +6 -0
  38. package/dist/runtime-api.monitor.js +4 -4
  39. package/dist/runtime-api.send.js +5 -5
  40. package/dist/runtime-api.threads.js +3 -3
  41. package/dist/{send-Dc5uQX5H.js → send-BYTToRY1.js} +18 -9
  42. package/dist/{send.components-D4bl20xr.js → send.components-Cmv2qMB5.js} +4 -4
  43. package/dist/{send.outbound-5axvwLkl.js → send.outbound-BqvRMxXy.js} +5 -4
  44. package/dist/{send.receipt-B21MspvT.js → send.receipt-CK162xD0.js} +28 -1
  45. package/dist/{send.shared-9082A2sO.js → send.shared-YLGCAMjV.js} +2 -2
  46. package/dist/session-binding-contract-api.js +1 -1
  47. package/dist/setup-plugin-api.js +1 -1
  48. package/dist/subagent-hooks-api.js +1 -1
  49. package/dist/{subagent-hooks-NTv6B4up.js → subagent-hooks-cE_tFGCX.js} +2 -2
  50. package/dist/{system-events-BzaI1WpN.js → system-events-XRYuwB2n.js} +1 -1
  51. package/dist/{target-resolver-agnOrtOU.js → target-resolver-DYufMbXm.js} +2 -2
  52. package/dist/targets-BA7gf0K0.js +3 -0
  53. package/dist/{thread-bindings-DNitaHVh.js → thread-bindings-C1yhwdOw.js} +4 -4
  54. package/dist/{thread-bindings.discord-api-CjYNuvZa.js → thread-bindings.discord-api-XBJmlLaf.js} +4 -4
  55. package/dist/{thread-bindings.manager-PZvJ4TJx.js → thread-bindings.manager-BdFs0ot7.js} +3 -3
  56. package/dist/{transcripts-source-Bi8N6h5X.js → transcripts-source-DW6d1eCL.js} +1 -1
  57. package/dist/transcripts-source-api.js +1 -1
  58. package/dist/{typing-BdRqXUN3.js → typing-BMQEI8OW.js} +1 -1
  59. package/npm-shrinkwrap.json +3 -3
  60. package/package.json +4 -4
  61. package/dist/provider.runtime-jNlHxUSW.js +0 -2
  62. package/dist/runtime-api.monitor-Bb5AaRzg.js +0 -6
  63. package/dist/targets-ClUPljCU.js +0 -3
@@ -1,18 +1,18 @@
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-YLGCAMjV.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-BYTToRY1.js";
6
+ import { a as discordTextHasTargetedMention, i as discordTextHasBroadcastMention, s as rewriteDiscordKnownMentions } from "./send.outbound-BqvRMxXy.js";
7
+ import "./targets-BA7gf0K0.js";
8
+ import { t as resolveDiscordConversationIdentity } from "./conversation-identity-BEsyd7A1.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-B0iwUl6c.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-CChQJujf.js";
14
+ import { a as resolveForwardedMediaList, o as resolveMediaList, r as resolveDiscordMessageText, s as resolveReferencedReplyMediaList } from "./message-utils-C_tYBSAu.js";
15
+ import { n as createDiscordReplyTypingFeedback } from "./message-handler-ClZrgeka.js";
16
16
  import { buildAgentSessionKey, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
17
17
  import { MessageFlags } from "discord-api-types/v10";
18
18
  import { evaluateSupplementalContextVisibility } from "openclaw/plugin-sdk/security-runtime";
@@ -23,10 +23,10 @@ import { danger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtim
23
23
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
24
24
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
25
25
  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";
26
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
27
+ import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createFinalizableDraftLifecycle, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, isChannelProgressDraftWorkToolName, resolveChannelDraftStreamingChunking, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages, resolveTranscriptBackedChannelFinalText } from "openclaw/plugin-sdk/channel-outbound";
27
28
  import { recordInboundSession, resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/conversation-runtime";
28
29
  import { EmbeddedBlockChunker, resolveAckReaction, resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
29
- import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
30
30
  import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
31
31
  import { getSessionEntry, readSessionUpdatedAt, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
32
32
  import { buildChannelInboundEventContext, dispatchChannelInboundReply, formatInboundEnvelope, hasFinalInboundReplyDispatch, recordChannelBotPairLoopAndCheckSuppression, resolveEnvelopeFormatOptions, toHistoryMediaEntries, toInboundMediaFacts } from "openclaw/plugin-sdk/channel-inbound";
@@ -280,7 +280,8 @@ async function buildDiscordMessageProcessContext(params) {
280
280
  username: senderUsername,
281
281
  tag: sender.tag,
282
282
  roles: memberRoleIds,
283
- displayLabel: senderLabel
283
+ displayLabel: senderLabel,
284
+ isBot: author.bot && !sender.isPluralKit ? true : void 0
284
285
  },
285
286
  conversation: {
286
287
  kind: isDirectMessage ? "direct" : "channel",
@@ -536,7 +537,8 @@ function createDiscordDraftPreviewController(params) {
536
537
  const discordStreamMode = resolveDiscordPreviewStreamMode(params.discordConfig);
537
538
  const draftMaxChars = Math.min(params.textLimit, 2e3);
538
539
  const accountBlockStreamingEnabled = resolveChannelStreamingBlockEnabled(params.discordConfig) ?? params.cfg.agents?.defaults?.blockStreamingDefault === "on";
539
- const draftStream = !params.sourceRepliesAreToolOnly && discordStreamMode !== "off" && !accountBlockStreamingEnabled ? createDiscordDraftStream({
540
+ const canStreamProgressDraftForToolOnlySource = params.sourceRepliesAreToolOnly && discordStreamMode === "progress";
541
+ const draftStream = (!params.sourceRepliesAreToolOnly || canStreamProgressDraftForToolOnlySource) && discordStreamMode !== "off" && !accountBlockStreamingEnabled ? createDiscordDraftStream({
540
542
  rest: params.deliveryRest,
541
543
  channelId: params.deliverChannelId,
542
544
  maxChars: draftMaxChars,
@@ -567,6 +569,10 @@ function createDiscordDraftPreviewController(params) {
567
569
  mode: discordStreamMode,
568
570
  active: Boolean(draftStream),
569
571
  seed: progressSeed,
572
+ reasoningLinePrefix: "🧠 ",
573
+ commentaryLinePrefix: "💬 ",
574
+ reasoningGate: true,
575
+ commentaryItalics: false,
570
576
  update: async (previewText, options) => {
571
577
  lastPartialText = previewText;
572
578
  draftText = previewText;
@@ -688,6 +694,7 @@ function createDiscordDraftPreviewController(params) {
688
694
  });
689
695
  },
690
696
  handleAssistantMessageBoundary() {
697
+ progressDraft.beginNewTurn();
691
698
  if (discordStreamMode === "progress") return;
692
699
  forceNewMessageIfNeeded();
693
700
  },
@@ -803,6 +810,9 @@ async function processDiscordMessageInner(ctx, observer) {
803
810
  }
804
811
  });
805
812
  const sourceRepliesAreToolOnly = sourceReplyDeliveryMode === "message_tool_only";
813
+ const configuredTypingMode = cfg.session?.typingMode ?? cfg.agents?.defaults?.typingMode;
814
+ const configuredTypingInterval = cfg.agents?.defaults?.typingIntervalSeconds ?? cfg.session?.typingIntervalSeconds;
815
+ const shouldDisableCoreTypingKeepalive = Boolean(replyTypingFeedback) || sourceRepliesAreToolOnly && configuredTypingMode === void 0 && configuredTypingInterval === void 0;
806
816
  const ackReaction = resolveAckReaction(cfg, route.agentId, {
807
817
  channel: "discord",
808
818
  accountId
@@ -950,7 +960,8 @@ async function processDiscordMessageInner(ctx, observer) {
950
960
  accountId,
951
961
  channelId: typingChannelId,
952
962
  rest: feedbackRest,
953
- log: logVerbose
963
+ log: logVerbose,
964
+ keepaliveIntervalMs: shouldDisableCoreTypingKeepalive ? void 0 : 0
954
965
  });
955
966
  if (replyTypingFeedback) replyTypingFeedback.restartForDispatch(typingChannelId);
956
967
  else typingFeedback.updateChannelId(typingChannelId);
@@ -1024,7 +1035,7 @@ async function processDiscordMessageInner(ctx, observer) {
1024
1035
  chunkMode,
1025
1036
  log: logVerbose
1026
1037
  });
1027
- let verboseProgressActive = () => false;
1038
+ let shouldYieldDraftProgress = () => false;
1028
1039
  const finalPreviewFlags = discordConfig?.suppressEmbeds ?? true ? MessageFlags.SuppressEmbeds : void 0;
1029
1040
  let finalReplyStartNotified = false;
1030
1041
  const notifyFinalReplyStart = () => {
@@ -1043,6 +1054,71 @@ async function processDiscordMessageInner(ctx, observer) {
1043
1054
  draftPreview.markFinalReplyDelivered();
1044
1055
  observer?.onFinalReplyDelivered?.();
1045
1056
  };
1057
+ const formatDiscordReasoningQuote = (quoteText) => {
1058
+ const lines = quoteText.split("\n").map((line) => line.trim()).filter(Boolean);
1059
+ if (!lines.length) return;
1060
+ lines[0] = `🧠 ${lines[0]}`;
1061
+ return lines.map((line) => `> ${line}`).join("\n");
1062
+ };
1063
+ const reasoningLevel = (() => {
1064
+ const normalizedAgentId = (route.agentId ?? "").trim().toLowerCase() || "main";
1065
+ const cfgDefault = cfg.agents?.list?.find((entry) => ((entry?.id ?? "").trim().toLowerCase() || "main") === normalizedAgentId)?.reasoningDefault ?? cfg.agents?.defaults?.reasoningDefault;
1066
+ const configDefault = cfgDefault === "on" || cfgDefault === "stream" ? cfgDefault : "off";
1067
+ const sessionKey = ctxPayload.SessionKey;
1068
+ if (!sessionKey) return configDefault;
1069
+ try {
1070
+ const storePath = resolveStorePath(cfg.session?.store, { agentId: route.agentId });
1071
+ const level = getSessionEntry({
1072
+ agentId: route.agentId,
1073
+ sessionKey,
1074
+ storePath
1075
+ })?.reasoningLevel;
1076
+ if (level === "on" || level === "stream" || level === "off") return level;
1077
+ } catch {
1078
+ return "off";
1079
+ }
1080
+ return configDefault;
1081
+ })();
1082
+ const reasoningDurableEnabled = reasoningLevel === "on";
1083
+ const reasoningWindowEnabled = reasoningLevel === "stream";
1084
+ const progressTurnStartedAt = Date.now();
1085
+ let progressReasoningSteps = 0;
1086
+ let progressToolCalls = 0;
1087
+ let progressCommentaryNotes = 0;
1088
+ let persistentReasoningDelivered = false;
1089
+ const seenCommentaryIds = /* @__PURE__ */ new Set();
1090
+ let lastCommentaryNoteText = "";
1091
+ const noteWindowCommentary = (itemId, noteText) => {
1092
+ const trimmed = noteText?.trim();
1093
+ if (!trimmed) return;
1094
+ if (itemId) {
1095
+ if (seenCommentaryIds.has(itemId)) return;
1096
+ seenCommentaryIds.add(itemId);
1097
+ progressCommentaryNotes += 1;
1098
+ return;
1099
+ }
1100
+ if (trimmed !== lastCommentaryNoteText) {
1101
+ lastCommentaryNoteText = trimmed;
1102
+ progressCommentaryNotes += 1;
1103
+ }
1104
+ };
1105
+ let windowReasoningOpen = false;
1106
+ const closePendingWindowThought = () => {
1107
+ if (windowReasoningOpen) {
1108
+ windowReasoningOpen = false;
1109
+ progressReasoningSteps += 1;
1110
+ }
1111
+ };
1112
+ const buildProgressSummaryLine = () => {
1113
+ closePendingWindowThought();
1114
+ const seconds = Math.max(1, Math.round((Date.now() - progressTurnStartedAt) / 1e3));
1115
+ return `-# ${[
1116
+ ...progressReasoningSteps > 0 ? [`🧠 ${progressReasoningSteps} thought${progressReasoningSteps === 1 ? "" : "s"}`] : [],
1117
+ ...progressCommentaryNotes > 0 ? [`💬 ${progressCommentaryNotes} note${progressCommentaryNotes === 1 ? "" : "s"}`] : [],
1118
+ ...progressToolCalls > 0 ? [`🛠️ ${progressToolCalls} tool call${progressToolCalls === 1 ? "" : "s"}`] : [],
1119
+ `⏱️ ${seconds}s`
1120
+ ].join(" · ")}`;
1121
+ };
1046
1122
  const beforeDiscordPayloadDelivery = (payload, info) => {
1047
1123
  if (isProcessAborted(abortSignal)) {
1048
1124
  logVerbose(formatDiscordReplySkip({
@@ -1053,6 +1129,7 @@ async function processDiscordMessageInner(ctx, observer) {
1053
1129
  }));
1054
1130
  return null;
1055
1131
  }
1132
+ if (payload.isReasoning || payload.isCommentary) return payload;
1056
1133
  if (draftPreview.draftStream && draftPreview.isProgressMode && info.kind === "block") {
1057
1134
  if (!resolveSendableOutboundReplyParts(payload).hasMedia && !payload.isError) return null;
1058
1135
  }
@@ -1070,6 +1147,43 @@ async function processDiscordMessageInner(ctx, observer) {
1070
1147
  return { visibleReplySent: false };
1071
1148
  }
1072
1149
  const isFinal = info.kind === "final";
1150
+ if (payload.isReasoning) {
1151
+ const raw = (payload.text ?? "").trim();
1152
+ const body = raw.startsWith("Reasoning:\n") ? raw.slice(11).trim() : raw;
1153
+ if (!body) return { visibleReplySent: false };
1154
+ const chunks = chunkDiscordTextWithMode(body, {
1155
+ maxChars: Math.max(256, Math.min(textLimit, 2e3) - 8),
1156
+ maxLines: maxLinesPerMessage,
1157
+ chunkMode
1158
+ });
1159
+ const replies = (chunks.length ? chunks : [body]).map((chunk) => formatDiscordReasoningQuote(chunk)).filter((quote) => Boolean(quote)).map((quote) => Object.assign({}, payload, {
1160
+ text: quote,
1161
+ isReasoning: void 0
1162
+ }));
1163
+ if (!replies.length) return { visibleReplySent: false };
1164
+ await deliverDiscordReply({
1165
+ cfg,
1166
+ replies,
1167
+ target: deliverTarget,
1168
+ token,
1169
+ accountId,
1170
+ rest: deliveryRest,
1171
+ runtime,
1172
+ replyToId: replyReference.use(),
1173
+ replyToMode,
1174
+ textLimit,
1175
+ maxLinesPerMessage,
1176
+ tableMode,
1177
+ chunkMode,
1178
+ sessionKey: ctxPayload.SessionKey,
1179
+ threadBindings,
1180
+ mediaLocalRoots,
1181
+ kind: "block"
1182
+ });
1183
+ replyReference.markSent();
1184
+ persistentReasoningDelivered = true;
1185
+ return { visibleReplySent: true };
1186
+ }
1073
1187
  if (isFinal && !options?.allowFallbackOnlyToolWarning && isFallbackOnlyToolWarningFinal(payload)) {
1074
1188
  if (!userFacingFinalDelivered && (!finalReplyStartNotified || userFacingFinalDeliveryFailed)) pendingToolWarningFinal = {
1075
1189
  payload,
@@ -1099,7 +1213,53 @@ async function processDiscordMessageInner(ctx, observer) {
1099
1213
  if (draftStream && draftPreview.isProgressMode && info.kind === "block") {
1100
1214
  if (!resolveSendableOutboundReplyParts(deliverablePayload).hasMedia && !deliverablePayload.isError) return { visibleReplySent: false };
1101
1215
  }
1102
- if (draftStream && isFinal && (!draftPreview.isProgressMode || draftPreview.hasProgressDraftStarted) && !deliverablePayload.isError) {
1216
+ if (draftStream && isFinal && draftPreview.isProgressMode && draftPreview.hasProgressDraftStarted && !deliverablePayload.isError && draftStream) {
1217
+ await draftPreview.flush();
1218
+ if (persistentReasoningDelivered) {
1219
+ await draftStream.clear();
1220
+ await deliverDiscordReply({
1221
+ cfg,
1222
+ replies: [{ text: buildProgressSummaryLine() }],
1223
+ target: deliverTarget,
1224
+ token,
1225
+ accountId,
1226
+ rest: deliveryRest,
1227
+ runtime,
1228
+ replyToId: replyReference.use(),
1229
+ replyToMode,
1230
+ textLimit,
1231
+ maxLinesPerMessage,
1232
+ tableMode,
1233
+ chunkMode,
1234
+ sessionKey: ctxPayload.SessionKey,
1235
+ threadBindings,
1236
+ mediaLocalRoots,
1237
+ kind: "block"
1238
+ });
1239
+ replyReference.markSent();
1240
+ draftPreview.markPreviewFinalized();
1241
+ } else {
1242
+ const draftId = draftStream.messageId();
1243
+ if (draftId !== void 0) {
1244
+ await draftStream.seal();
1245
+ try {
1246
+ await editMessageDiscord(deliverChannelId, draftId, {
1247
+ content: buildProgressSummaryLine(),
1248
+ ...finalPreviewFlags ? { flags: finalPreviewFlags } : {}
1249
+ }, {
1250
+ cfg,
1251
+ accountId,
1252
+ rest: deliveryRest
1253
+ });
1254
+ draftPreview.markPreviewFinalized();
1255
+ } catch (err) {
1256
+ logVerbose(`discord: progress draft summary edit failed; clearing draft (${String(err)})`);
1257
+ await draftStream.clear();
1258
+ }
1259
+ }
1260
+ }
1261
+ }
1262
+ if (draftStream && isFinal && !draftPreview.isProgressMode && !deliverablePayload.isError) {
1103
1263
  const hasMedia = resolveSendableOutboundReplyParts(deliverablePayload).hasMedia;
1104
1264
  const ttsSupplement = getReplyPayloadTtsSupplement(deliverablePayload);
1105
1265
  const previewSourceText = deliverablePayload.text ?? ttsSupplement?.spokenText;
@@ -1312,28 +1472,40 @@ async function processDiscordMessageInner(ctx, observer) {
1312
1472
  abortSignal,
1313
1473
  skillFilter: channelConfig?.skills,
1314
1474
  sourceReplyDeliveryMode,
1475
+ typingKeepalive: shouldDisableCoreTypingKeepalive ? false : void 0,
1315
1476
  queuedDeliveryCorrelations: isRoomEvent ? [{ begin: beginDeliveryCorrelation }] : void 0,
1316
1477
  suppressTyping: isRoomEvent ? true : void 0,
1317
- allowProgressCallbacksWhenSourceDeliverySuppressed: sourceRepliesAreToolOnly && statusReactionsExplicitlyEnabled ? true : void 0,
1478
+ allowProgressCallbacksWhenSourceDeliverySuppressed: sourceRepliesAreToolOnly && draftPreview.draftStream && draftPreview.isProgressMode ? true : void 0,
1318
1479
  disableBlockStreaming: sourceRepliesAreToolOnly ? true : draftPreview.disableBlockStreamingForDraft ?? (typeof resolvedBlockStreamingEnabled === "boolean" ? !resolvedBlockStreamingEnabled : void 0),
1319
1480
  onPartialReply: draftPreview.draftStream && !draftPreview.isProgressMode ? (payload) => draftPreview.updateFromPartial(payload.text) : void 0,
1320
1481
  onAssistantMessageStart: draftPreview.draftStream ? () => draftPreview.handleAssistantMessageBoundary() : void 0,
1321
- onReasoningEnd: draftPreview.draftStream ? () => draftPreview.handleAssistantMessageBoundary() : void 0,
1482
+ onReasoningEnd: draftPreview.draftStream ? () => {
1483
+ closePendingWindowThought();
1484
+ return draftPreview.handleAssistantMessageBoundary();
1485
+ } : void 0,
1322
1486
  onModelSelected,
1323
1487
  suppressDefaultToolProgressMessages: sourceRepliesAreToolOnly && statusReactionsExplicitlyEnabled || draftPreview.suppressDefaultToolProgressMessages ? true : void 0,
1324
1488
  allowToolLifecycleWhenProgressHidden: statusReactionsEnabled ? true : void 0,
1325
1489
  commentaryProgressEnabled: draftPreview.isProgressMode ? draftPreview.commentaryProgressEnabled : void 0,
1490
+ commentaryPayloadsEnabled: draftPreview.isProgressMode ? draftPreview.commentaryProgressEnabled : void 0,
1491
+ reasoningPayloadsEnabled: reasoningDurableEnabled,
1326
1492
  onVerboseProgressVisibility: (isActive) => {
1327
- verboseProgressActive = isActive;
1493
+ shouldYieldDraftProgress = isActive;
1328
1494
  },
1329
1495
  onReasoningStream: async (payload) => {
1496
+ if (payload?.requiresReasoningProgressOptIn === true && !reasoningWindowEnabled) return;
1497
+ if (payload?.text) windowReasoningOpen = true;
1330
1498
  await statusReactions.setThinking();
1331
1499
  await draftPreview.pushReasoningProgress(payload?.text, { snapshot: payload?.isReasoningSnapshot === true });
1332
1500
  },
1501
+ streamReasoningInNonStreamModes: reasoningWindowEnabled,
1333
1502
  onToolStart: async (payload) => {
1334
1503
  if (isProcessAborted(abortSignal)) return;
1335
1504
  await maybeBindStatusReactionsToToolReaction(payload);
1336
1505
  await statusReactions.setTool(payload.name);
1506
+ if (payload.phase === "start") closePendingWindowThought();
1507
+ if (shouldYieldDraftProgress()) return;
1508
+ if (payload.phase === "start" && isChannelProgressDraftWorkToolName(payload.name)) progressToolCalls += 1;
1337
1509
  await draftPreview.pushToolProgress(buildChannelProgressDraftLineForEntry(discordConfig, {
1338
1510
  event: "tool",
1339
1511
  itemId: payload.itemId,
@@ -1345,10 +1517,14 @@ async function processDiscordMessageInner(ctx, observer) {
1345
1517
  },
1346
1518
  onItemEvent: async (payload) => {
1347
1519
  if (payload.kind === "preamble") {
1348
- if (verboseProgressActive()) return;
1349
- if (draftPreview.commentaryProgressEnabled && payload.progressText) await draftPreview.pushCommentaryProgress(payload.progressText, { itemId: payload.itemId });
1520
+ if (shouldYieldDraftProgress()) return;
1521
+ if (draftPreview.commentaryProgressEnabled && payload.progressText) {
1522
+ noteWindowCommentary(payload.itemId, payload.progressText);
1523
+ await draftPreview.pushCommentaryProgress(payload.progressText, { itemId: payload.itemId });
1524
+ }
1350
1525
  return;
1351
1526
  }
1527
+ if (shouldYieldDraftProgress()) return;
1352
1528
  await draftPreview.pushToolProgress(buildChannelProgressDraftLineForEntry(discordConfig, {
1353
1529
  event: "item",
1354
1530
  itemId: payload.itemId,
@@ -1386,6 +1562,7 @@ async function processDiscordMessageInner(ctx, observer) {
1386
1562
  },
1387
1563
  onCommandOutput: async (payload) => {
1388
1564
  if (payload.phase !== "end") return;
1565
+ if (shouldYieldDraftProgress()) return;
1389
1566
  await draftPreview.pushToolProgress(buildChannelProgressDraftLine({
1390
1567
  event: "command-output",
1391
1568
  itemId: payload.itemId,
@@ -1399,6 +1576,7 @@ async function processDiscordMessageInner(ctx, observer) {
1399
1576
  },
1400
1577
  onPatchSummary: async (payload) => {
1401
1578
  if (payload.phase !== "end") return;
1579
+ if (shouldYieldDraftProgress()) return;
1402
1580
  await draftPreview.pushToolProgress(buildChannelProgressDraftLine({
1403
1581
  event: "patch",
1404
1582
  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-XBJmlLaf.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,6 +1,6 @@
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
6
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -86,11 +86,11 @@ function normalizeDiscordApprovalPayload(payload) {
86
86
  let discordComponentSendPromise;
87
87
  let discordSharedInteractivePromise;
88
88
  async function sendDiscordComponentMessageLazy(...args) {
89
- discordComponentSendPromise ??= import("./send.components-D4bl20xr.js").then((n) => n.i).then((module) => module.sendDiscordComponentMessage);
89
+ discordComponentSendPromise ??= import("./send.components-Cmv2qMB5.js").then((n) => n.i).then((module) => module.sendDiscordComponentMessage);
90
90
  return await (await discordComponentSendPromise)(...args);
91
91
  }
92
92
  function loadDiscordSharedInteractive() {
93
- discordSharedInteractivePromise ??= import("./components-Dm4c_ce6.js").then((n) => n.a);
93
+ discordSharedInteractivePromise ??= import("./components-CBPNJhVP.js").then((n) => n.a);
94
94
  return discordSharedInteractivePromise;
95
95
  }
96
96
  function addPayloadTextFallback(spec, payload) {
@@ -125,7 +125,7 @@ async function resolveDiscordComponentSpec(payload) {
125
125
  //#region extensions/discord/src/outbound-send-context.ts
126
126
  let discordSendRuntimePromise;
127
127
  async function loadDiscordSendRuntime() {
128
- discordSendRuntimePromise ??= import("./send-Dc5uQX5H.js").then((n) => n.t);
128
+ discordSendRuntimePromise ??= import("./send-BYTToRY1.js").then((n) => n.t);
129
129
  return await discordSendRuntimePromise;
130
130
  }
131
131
  function resolveDiscordOutboundTarget(params) {
@@ -210,14 +210,20 @@ async function sendDiscordOutboundPayload(params) {
210
210
  const mediaUrls = resolvePayloadMediaUrls(payload);
211
211
  const sendContext = await createDiscordPayloadSendContext(ctx);
212
212
  if (payload.audioAsVoice && mediaUrls.length > 0) {
213
- let lastResult = await sendContext.withRetry(async () => await sendContext.sendVoice(sendContext.target, mediaUrls[0], resolveDiscordDeliveryOptions(ctx, sendContext)));
213
+ const voiceReplyTo = sendContext.resolveReplyTo();
214
+ let lastResult = await sendContext.withRetry(async () => await sendContext.sendVoice(sendContext.target, mediaUrls[0], {
215
+ ...resolveDiscordDeliveryOptions(ctx, sendContext),
216
+ replyTo: voiceReplyTo
217
+ }));
214
218
  if (payload.text?.trim()) lastResult = await sendContext.withRetry(async () => await sendContext.send(sendContext.target, payload.text, {
215
219
  verbose: false,
216
- ...resolveDiscordFormattedDeliveryOptions(ctx, sendContext)
220
+ ...resolveDiscordFormattedDeliveryOptions(ctx, sendContext),
221
+ replyTo: voiceReplyTo
217
222
  }));
218
223
  for (const mediaUrl of mediaUrls.slice(1)) lastResult = await sendContext.withRetry(async () => await sendContext.send(sendContext.target, "", {
219
224
  verbose: false,
220
- ...resolveDiscordMediaDeliveryOptions(ctx, sendContext, mediaUrl)
225
+ ...resolveDiscordMediaDeliveryOptions(ctx, sendContext, mediaUrl),
226
+ replyTo: voiceReplyTo
221
227
  }));
222
228
  return attachChannelToResult("discord", lastResult);
223
229
  }
@@ -280,7 +286,7 @@ function stripDiscordInternalRuntimeScaffolding(text) {
280
286
  }
281
287
  let discordThreadBindingsPromise;
282
288
  function loadDiscordThreadBindings() {
283
- discordThreadBindingsPromise ??= import("./thread-bindings-DNitaHVh.js").then((n) => n.t);
289
+ discordThreadBindingsPromise ??= import("./thread-bindings-C1yhwdOw.js").then((n) => n.t);
284
290
  return discordThreadBindingsPromise;
285
291
  }
286
292
  function resolveDiscordWebhookIdentity(params) {
@@ -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,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 };