@openclaw/discord 2026.7.1-beta.6 → 2026.7.2-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.
- package/dist/action-runtime-api.js +1 -1
- package/dist/{allow-list-C-MqM-B_.js → allow-list-B7qOH5xu.js} +22 -1
- package/dist/{api-DPRqYi4Z.js → api--f62GFaS.js} +38 -23
- package/dist/api.js +15 -15
- package/dist/approval-custom-id-NYPYj9Po.js +58 -0
- package/dist/{approval-handler.runtime-Bw2pZNk1.js → approval-handler.runtime-DeyIiw5I.js} +28 -23
- package/dist/approval-message-safety-C-8BL6Kv.js +47 -0
- package/dist/{audit-MLpDpN3Z.js → audit-Df2w046a.js} +3 -3
- package/dist/{channel-actions-D_fjVUZ_.js → channel-actions-ChpBSRcu.js} +6 -4
- package/dist/{channel-actions.runtime-CVHlFqQg.js → channel-actions.runtime-D8V8tyCq.js} +41 -12
- package/dist/channel-config-api.js +1 -1
- package/dist/{channel-DGWPH5u3.js → channel-nYmJ7FKQ.js} +275 -62
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.setup-tZcpIn4e.js → channel.setup-DyihrqHH.js} +3 -3
- package/dist/{components-BIBizbtZ.js → components-BVrfRS-F.js} +78 -52
- package/dist/config-api-B18fR8M5.js +3 -0
- package/dist/{config-schema-BgIhO3ko.js → config-schema-_bUKcWRm.js} +42 -82
- package/dist/conversation-identity-BpkAzklg.js +94 -0
- package/dist/{directory-config-ByaUKL1f.js → directory-config-BUe-qq_C.js} +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-BX79ImQA.js → directory-live-DZByMdPO.js} +6 -6
- package/dist/{doctor-Bgoxm5AN.js → doctor-bMaWXFKu.js} +5 -4
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{doctor-contract-CU7lnZTF.js → doctor-contract-wId6pV41.js} +41 -37
- package/dist/{handle-action.guild-admin-CgJSNVui.js → handle-action.guild-admin-C_PQcBEV.js} +12 -12
- package/dist/index.js +1 -1
- package/dist/legacy-state-migrations-api.js +24 -2
- package/dist/{manager.runtime-DaB-CTrt.js → manager.runtime-3RVMVkyx.js} +546 -154
- package/dist/{message-handler-DcgvugZt.js → message-handler-CIxWq5Yh.js} +8 -9
- package/dist/{message-handler.preflight-DvLXiYVH.js → message-handler.preflight-BI86IbHz.js} +46 -22
- package/dist/{message-handler.process-Cjf30P_B.js → message-handler.process-bPS_9_tb.js} +241 -107
- package/dist/{message-utils-B_3yA5bN.js → message-utils-D4j07taS.js} +2 -3
- package/dist/{outbound-adapter-82RWi_SR.js → outbound-adapter-Czny0Fae.js} +16 -68
- package/dist/outbound-components-oJKLj62G.js +99 -0
- package/dist/pluralkit-UXq1OyUI.js +40 -0
- package/dist/{probe-D1ImJEo2.js → probe-DxjMBeVG.js} +1 -1
- package/dist/{probe.runtime-B1dsEeBD.js → probe.runtime-Bc8Oo6e8.js} +1 -1
- package/dist/{provider-BkfbC9FQ.js → provider-DWvDNb4J.js} +702 -236
- package/dist/{provider-session.runtime-BDjyFw6Y.js → provider-session.runtime-D5pCGibh.js} +3 -3
- package/dist/provider.runtime-C2iIfbTs.js +2 -0
- package/dist/{resolve-allowlist-common-CWbE8XlH.js → resolve-allowlist-common-B9S8LLBd.js} +5 -5
- package/dist/{resolve-channels-CcpvWoRa.js → resolve-channels-BrkWOKdG.js} +7 -7
- package/dist/{resolve-users-DJamun9s.js → resolve-users-OjrXXvJP.js} +5 -5
- package/dist/{runtime-C6rRmQ6l.js → runtime-C618lis9.js} +223 -33
- package/dist/runtime-api.actions.js +2 -2
- package/dist/runtime-api.js +23 -23
- package/dist/runtime-api.lookup.js +5 -5
- package/dist/runtime-api.monitor-DSbfGnzS.js +6 -0
- package/dist/runtime-api.monitor.js +7 -7
- package/dist/runtime-api.send.js +5 -5
- package/dist/runtime-api.threads.js +5 -5
- package/dist/{send-iJ0B4bAX.js → send-BFpa_DHn.js} +21 -12
- package/dist/{send.components-D0I39utR.js → send.components-BaXQJKWT.js} +15 -10
- package/dist/{send.outbound-Bj61Q3a0.js → send.outbound-BlA6VzSE.js} +22 -12
- package/dist/{send.receipt-BpBQED_5.js → send.receipt-aegk69an.js} +59 -75
- package/dist/{send.shared-wAwMhHDN.js → send.shared-Xz7IMVpu.js} +44 -20
- package/dist/{sender-identity-CEsfDF0L.js → sender-identity-C62lBe18.js} +1 -1
- package/dist/session-binding-contract-api.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{shared-BQVKfnev.js → shared-BLYBt5SA.js} +3 -3
- package/dist/{subagent-hooks-B-bJxxGg.js → subagent-hooks-DKJ4p-Oy.js} +2 -2
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/{system-events-DVnqSyTt.js → system-events-DKwfE-2z.js} +2 -2
- package/dist/{target-resolver-CwHaSLt3.js → target-resolver-BQyEHyeS.js} +2 -2
- package/dist/targets-DvItNIvP.js +3 -0
- package/dist/thread-binding-api-BDZJD4na.js +4 -0
- package/dist/thread-binding-api.js +1 -3
- package/dist/{thread-bindings-DsTxqu3E.js → thread-bindings-BbzjUuNB.js} +26 -43
- package/dist/{thread-bindings.discord-api-BjIf9lGs.js → thread-bindings.discord-api-DJD3qwIN.js} +8 -10
- package/dist/{thread-bindings.manager-Bwmtqc3E.js → thread-bindings.manager-BIBm6bQd.js} +4 -4
- package/dist/{thread-bindings.session-updates-Chs3HgGa.js → thread-bindings.session-updates-eRcJlzIU.js} +1 -1
- package/dist/{thread-bindings.state-iSWjCYjB.js → thread-bindings.state-9VAxhVf6.js} +3 -14
- package/dist/{timeouts-C5TBc_9x.js → timeouts-ZRc9Lw4y.js} +3 -15
- package/dist/timeouts.js +1 -1
- package/dist/{transcripts-source-BvvM5Ns9.js → transcripts-source-CLZ5X8fh.js} +1 -1
- package/dist/transcripts-source-api.js +1 -1
- package/dist/{typing-BVcJgILg.js → typing-BnYT7Szq.js} +2 -2
- package/node_modules/p-map/index.d.ts +155 -0
- package/node_modules/p-map/index.js +284 -0
- package/node_modules/p-map/license +9 -0
- package/node_modules/p-map/package.json +57 -0
- package/node_modules/p-map/readme.md +190 -0
- package/npm-shrinkwrap.json +16 -3
- package/openclaw.plugin.json +70 -2
- package/package.json +6 -4
- package/dist/config-api-JiPdJeb0.js +0 -2
- package/dist/conversation-identity-DWC5d8Sy.js +0 -272
- package/dist/pluralkit-DcD-3EcL.js +0 -24
- package/dist/preview-streaming-DXT8oJdo.js +0 -8
- package/dist/provider.runtime-WrJXikSv.js +0 -2
- package/dist/runtime-api.monitor-C2_WVtJf.js +0 -6
- package/dist/targets-69w7c3vU.js +0 -3
|
@@ -1,31 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Yt as resolveDiscordChannelId, d as discord_exports, gt as deleteChannelMessage, pt as createChannelMessage, u as chunkDiscordTextWithMode, vt as editChannelMessage } from "./send.receipt-aegk69an.js";
|
|
2
2
|
import { f as resolveDiscordMaxLinesPerMessage } from "./accounts-P19jm1lf.js";
|
|
3
|
-
import { I as createDiscordRestClient, L as createDiscordRuntimeAccountContext, _ as resolveDiscordMessageFlags, d as resolveDiscordTargetChannelId } from "./send.shared-
|
|
4
|
-
import {
|
|
5
|
-
import { a as removeReactionDiscord, f as editMessageDiscord, r as reactMessageDiscord } from "./send-
|
|
6
|
-
import { i as discordTextHasBroadcastMention } from "./send.outbound-
|
|
7
|
-
import "./
|
|
8
|
-
import
|
|
3
|
+
import { I as createDiscordRestClient, L as createDiscordRuntimeAccountContext, _ as resolveDiscordMessageFlags, d as resolveDiscordTargetChannelId } from "./send.shared-Xz7IMVpu.js";
|
|
4
|
+
import { C as resolveTimestampMs, a as normalizeDiscordSlug, r as normalizeDiscordAllowList } from "./allow-list-B7qOH5xu.js";
|
|
5
|
+
import { a as removeReactionDiscord, f as editMessageDiscord, r as reactMessageDiscord } from "./send-BFpa_DHn.js";
|
|
6
|
+
import { i as discordTextHasBroadcastMention } from "./send.outbound-BlA6VzSE.js";
|
|
7
|
+
import { n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-ZRc9Lw4y.js";
|
|
8
|
+
import "./targets-DvItNIvP.js";
|
|
9
|
+
import { t as resolveDiscordConversationIdentity } from "./conversation-identity-BpkAzklg.js";
|
|
9
10
|
import { t as beginDiscordInboundEventDeliveryCorrelation } from "./inbound-event-delivery-CEPlt2uz.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { r as resolveDiscordMessageText, s as resolveReferencedReplyMediaList } from "./message-utils-B_3yA5bN.js";
|
|
15
|
-
import { n as createDiscordReplyTypingFeedback } from "./message-handler-DcgvugZt.js";
|
|
11
|
+
import { t as DISCORD_TEXT_CHUNK_LIMIT } from "./outbound-adapter-Czny0Fae.js";
|
|
12
|
+
import { D as resolveDiscordThreadStarter, T as resolveDiscordAutoThreadReplyPlan, _ as createDiscordSupplementalContextAccessChecker, a as buildDirectLabel, g as buildDiscordInboundAccessContext, i as sanitizeDiscordFrontChannelReplyPayloads, n as deliverDiscordReply, o as buildGuildLabel, r as formatDiscordReplyDeliveryFailure, s as resolveReplyContext } from "./provider-DWvDNb4J.js";
|
|
13
|
+
import { r as resolveDiscordMessageText, s as resolveReferencedReplyMediaList } from "./message-utils-D4j07taS.js";
|
|
14
|
+
import { n as createDiscordReplyTypingFeedback, r as DiscordRetryableInboundError } from "./message-handler-CIxWq5Yh.js";
|
|
16
15
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
17
16
|
import { buildAgentSessionKey, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
|
|
18
|
-
import { MessageFlags } from "discord-api-types/v10";
|
|
19
17
|
import { evaluateSupplementalContextVisibility } from "openclaw/plugin-sdk/security-runtime";
|
|
18
|
+
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
20
19
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
21
20
|
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
|
|
22
21
|
import { getReplyPayloadTtsSupplement, isReplyPayloadNonTerminalToolErrorWarning, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
|
|
23
22
|
import { resolveChunkMode } from "openclaw/plugin-sdk/reply-chunking";
|
|
24
|
-
import { danger, logVerbose, shouldLogVerbose, sleep } from "openclaw/plugin-sdk/runtime-env";
|
|
23
|
+
import { danger, logVerbose, shouldLogVerbose, sleep, sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
|
|
25
24
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
26
25
|
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
27
26
|
import { convertMarkdownTables, stripInlineDirectiveTagsForDelivery, stripReasoningTagsFromText } from "openclaw/plugin-sdk/text-chunking";
|
|
28
|
-
import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createFinalizableDraftLifecycle, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, isChannelProgressDraftWorkToolName, resolveChannelDraftStreamingChunking, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages, resolveTranscriptBackedChannelFinalText } from "openclaw/plugin-sdk/channel-outbound";
|
|
27
|
+
import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createFinalizableDraftLifecycle, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, isChannelProgressDraftWorkToolName, resolveChannelDraftStreamingChunking, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelPreviewStreamMode, resolveChannelProgressDraftConfig, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewCommandText, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingProgressNarration, resolveChannelStreamingSuppressDefaultToolProgressMessages, resolveTranscriptBackedChannelFinalText } from "openclaw/plugin-sdk/channel-outbound";
|
|
29
28
|
import { recordInboundSession, resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/conversation-runtime";
|
|
30
29
|
import { EmbeddedBlockChunker, resolveAckReaction, resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
|
|
31
30
|
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
|
|
@@ -71,6 +70,63 @@ function queueInitialDiscordAckReaction(params) {
|
|
|
71
70
|
});
|
|
72
71
|
}
|
|
73
72
|
//#endregion
|
|
73
|
+
//#region extensions/discord/src/monitor/message-handler.retry.ts
|
|
74
|
+
const REPLY_SESSION_INIT_CONFLICT_MESSAGE_RE = /^reply session initialization conflicted for \S+$/u;
|
|
75
|
+
const DISCORD_SESSION_INIT_CONFLICT_RETRY_DELAYS_MS = [
|
|
76
|
+
250,
|
|
77
|
+
1e3,
|
|
78
|
+
2500
|
|
79
|
+
];
|
|
80
|
+
const DISCORD_SESSION_CONFLICT_FAILURE_TEXT = "⚠️ Couldn't process this message because the session stayed busy. Please try again in a moment.";
|
|
81
|
+
function isReplySessionInitConflictError(error) {
|
|
82
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
83
|
+
return REPLY_SESSION_INIT_CONFLICT_MESSAGE_RE.test(message);
|
|
84
|
+
}
|
|
85
|
+
var DiscordReplySessionConflictExhaustedError = class extends DiscordRetryableInboundError {
|
|
86
|
+
constructor(message, options) {
|
|
87
|
+
super(message, options);
|
|
88
|
+
this.name = "DiscordReplySessionConflictExhaustedError";
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
async function dispatchDiscordReplyWithSessionConflictRetry(params) {
|
|
92
|
+
for (let retryIndex = 0;; retryIndex += 1) try {
|
|
93
|
+
return await params.dispatch();
|
|
94
|
+
} catch (error) {
|
|
95
|
+
if (!isReplySessionInitConflictError(error)) throw error;
|
|
96
|
+
const delayMs = DISCORD_SESSION_INIT_CONFLICT_RETRY_DELAYS_MS[retryIndex];
|
|
97
|
+
if (delayMs === void 0) throw new DiscordReplySessionConflictExhaustedError(`discord: reply session init conflict persisted after shared and channel retries: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
98
|
+
params.onRetry?.(retryIndex + 1, delayMs);
|
|
99
|
+
await sleepWithAbort(delayMs, params.abortSignal);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function withDiscordSessionRetry(dispatch, abortSignal) {
|
|
103
|
+
return (dispatchParams) => dispatchDiscordReplyWithSessionConflictRetry({
|
|
104
|
+
dispatch: () => dispatch(dispatchParams),
|
|
105
|
+
abortSignal,
|
|
106
|
+
onRetry: (attempt, delayMs) => {
|
|
107
|
+
logVerbose(`discord: reply session init conflict; retrying dispatch ${attempt} after ${delayMs}ms`);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
async function completeDiscordSessionConflict(error, deliver, onDeliveryError) {
|
|
112
|
+
if (!(error instanceof DiscordReplySessionConflictExhaustedError)) return false;
|
|
113
|
+
try {
|
|
114
|
+
await deliver({
|
|
115
|
+
text: DISCORD_SESSION_CONFLICT_FAILURE_TEXT,
|
|
116
|
+
isError: true
|
|
117
|
+
}, { kind: "final" });
|
|
118
|
+
return true;
|
|
119
|
+
} catch (deliveryError) {
|
|
120
|
+
onDeliveryError(deliveryError, { kind: "final" });
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function removeDiscordReplayHistoryEntry(historyMap, historyKey, messageId) {
|
|
125
|
+
const history = historyMap.get(historyKey);
|
|
126
|
+
if (!history) return;
|
|
127
|
+
for (let index = history.length - 1; index >= 0; index -= 1) if (history[index]?.messageId === messageId) history.splice(index, 1);
|
|
128
|
+
}
|
|
129
|
+
//#endregion
|
|
74
130
|
//#region extensions/discord/src/monitor/message-handler.context.ts
|
|
75
131
|
function normalizeDiscordDmOwnerEntry(entry) {
|
|
76
132
|
const candidate = normalizeDiscordAllowList([entry], [
|
|
@@ -98,7 +154,6 @@ async function buildDiscordMessageProcessContext(params) {
|
|
|
98
154
|
const threadParentInheritanceEnabled = discordConfig?.thread?.inheritParent ?? false;
|
|
99
155
|
const forumContextLine = Boolean(threadChannelId && isForumParent && forumParentSlug) && message.id === threadChannelId ? `[Forum parent: #${forumParentSlug}]` : null;
|
|
100
156
|
const groupChannel = isGuildMessage && displayChannelSlug ? `#${displayChannelSlug}` : void 0;
|
|
101
|
-
const groupSubject = isDirectMessage ? void 0 : groupChannel;
|
|
102
157
|
const senderName = sender.isPluralKit ? sender.name ?? author.username : data.member?.nickname ?? author.globalName ?? author.username;
|
|
103
158
|
const senderUsername = sender.isPluralKit ? sender.tag ?? sender.name ?? author.username : author.username;
|
|
104
159
|
const { groupSystemPrompt, ownerAllowFrom, untrustedContext } = buildDiscordInboundAccessContext({
|
|
@@ -136,7 +191,6 @@ async function buildDiscordMessageProcessContext(params) {
|
|
|
136
191
|
sessionKey: route.sessionKey
|
|
137
192
|
});
|
|
138
193
|
const channelHistory = createChannelHistoryWindow({ historyMap: guildHistories });
|
|
139
|
-
const isRoomEvent = ctx.inboundEventKind === "room_event";
|
|
140
194
|
let combinedBody = formatInboundEnvelope({
|
|
141
195
|
channel: "Discord",
|
|
142
196
|
from: fromLabel,
|
|
@@ -147,21 +201,24 @@ async function buildDiscordMessageProcessContext(params) {
|
|
|
147
201
|
previousTimestamp,
|
|
148
202
|
envelope: envelopeOptions
|
|
149
203
|
});
|
|
150
|
-
const shouldIncludeChannelHistory = !isDirectMessage && (
|
|
151
|
-
if (shouldIncludeChannelHistory)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
204
|
+
const shouldIncludeChannelHistory = !isDirectMessage && (ctx.inboundEventKind === "room_event" || !(isGuildMessage && channelConfig?.autoThread && !threadChannel));
|
|
205
|
+
if (shouldIncludeChannelHistory) {
|
|
206
|
+
removeDiscordReplayHistoryEntry(guildHistories, messageChannelId, message.id);
|
|
207
|
+
combinedBody = channelHistory.buildPendingContext({
|
|
208
|
+
historyKey: messageChannelId,
|
|
209
|
+
limit: historyLimit,
|
|
210
|
+
currentMessage: combinedBody,
|
|
211
|
+
formatEntry: (entry) => formatInboundEnvelope({
|
|
212
|
+
channel: "Discord",
|
|
213
|
+
from: fromLabel,
|
|
214
|
+
timestamp: entry.timestamp,
|
|
215
|
+
body: `${entry.body} [id:${entry.messageId ?? "unknown"} channel:${messageChannelId}]`,
|
|
216
|
+
chatType: "channel",
|
|
217
|
+
senderLabel: entry.sender,
|
|
218
|
+
envelope: envelopeOptions
|
|
219
|
+
})
|
|
220
|
+
});
|
|
221
|
+
}
|
|
165
222
|
const replyContext = resolveReplyContext(message, resolveDiscordMessageText);
|
|
166
223
|
const replySenderAllowed = replyContext ? isSupplementalContextSenderAllowed({
|
|
167
224
|
id: replyContext.senderId,
|
|
@@ -228,7 +285,7 @@ async function buildDiscordMessageProcessContext(params) {
|
|
|
228
285
|
message,
|
|
229
286
|
messageChannelId,
|
|
230
287
|
isGuildMessage,
|
|
231
|
-
channelConfig:
|
|
288
|
+
channelConfig: ctx.inboundEventKind === "room_event" ? null : channelConfig,
|
|
232
289
|
threadChannel,
|
|
233
290
|
channelType: channelInfo?.type,
|
|
234
291
|
channelName: channelInfo?.name,
|
|
@@ -287,6 +344,7 @@ async function buildDiscordMessageProcessContext(params) {
|
|
|
287
344
|
conversation: {
|
|
288
345
|
kind: isDirectMessage ? "direct" : "channel",
|
|
289
346
|
id: messageChannelId,
|
|
347
|
+
nativeChannelId: messageChannelId,
|
|
290
348
|
label: fromLabel,
|
|
291
349
|
spaceId: isGuildMessage ? (guildInfo?.id ?? guildSlug) || void 0 : void 0,
|
|
292
350
|
parentId: threadChannel ? threadParentId : void 0,
|
|
@@ -356,7 +414,7 @@ async function buildDiscordMessageProcessContext(params) {
|
|
|
356
414
|
},
|
|
357
415
|
extra: {
|
|
358
416
|
...preflightAudioTranscript !== void 0 ? { Transcript: preflightAudioTranscript } : {},
|
|
359
|
-
GroupSubject:
|
|
417
|
+
GroupSubject: isDirectMessage ? void 0 : groupChannel,
|
|
360
418
|
GroupChannel: groupChannel,
|
|
361
419
|
...isGuildMessage ? { GroupRequireMention: ctx.groupRequireMention } : {},
|
|
362
420
|
UntrustedStructuredContext: untrustedContext,
|
|
@@ -364,7 +422,7 @@ async function buildDiscordMessageProcessContext(params) {
|
|
|
364
422
|
}
|
|
365
423
|
});
|
|
366
424
|
const persistedSessionKey = ctxPayload.SessionKey ?? route.sessionKey;
|
|
367
|
-
if (
|
|
425
|
+
if (ctx.inboundEventKind === "room_event" && shouldIncludeChannelHistory) await channelHistory.recordWithMedia({
|
|
368
426
|
historyKey: messageChannelId,
|
|
369
427
|
limit: historyLimit,
|
|
370
428
|
entry: {
|
|
@@ -435,7 +493,11 @@ function createDiscordDraftStream(params) {
|
|
|
435
493
|
};
|
|
436
494
|
let streamMessageId;
|
|
437
495
|
let lastSentText = "";
|
|
496
|
+
let streamGeneration = 0;
|
|
497
|
+
let activeCreateGeneration;
|
|
498
|
+
let discardActiveCreate = false;
|
|
438
499
|
const sendOrEditStreamMessage = async (text) => {
|
|
500
|
+
const generation = streamGeneration;
|
|
439
501
|
if (streamState.stopped && !streamState.final) return false;
|
|
440
502
|
const trimmed = text.trimEnd();
|
|
441
503
|
if (!trimmed) return false;
|
|
@@ -463,12 +525,24 @@ function createDiscordDraftStream(params) {
|
|
|
463
525
|
message_id: replyToMessageId,
|
|
464
526
|
fail_if_not_exists: false
|
|
465
527
|
} : void 0;
|
|
528
|
+
activeCreateGeneration = generation;
|
|
466
529
|
const sentMessageId = (await createChannelMessage(rest, channelId, { body: {
|
|
467
530
|
content: trimmed,
|
|
468
531
|
allowed_mentions: DISCORD_PREVIEW_ALLOWED_MENTIONS,
|
|
469
532
|
...flags ? { flags } : {},
|
|
470
533
|
...messageReference ? { message_reference: messageReference } : {}
|
|
471
534
|
} }))?.id;
|
|
535
|
+
const shouldDiscardStaleCreate = activeCreateGeneration === generation && discardActiveCreate;
|
|
536
|
+
activeCreateGeneration = void 0;
|
|
537
|
+
discardActiveCreate = false;
|
|
538
|
+
if (generation !== streamGeneration) {
|
|
539
|
+
if (shouldDiscardStaleCreate && typeof sentMessageId === "string" && sentMessageId) try {
|
|
540
|
+
await deleteChannelMessage(rest, channelId, sentMessageId);
|
|
541
|
+
} catch (err) {
|
|
542
|
+
params.warn?.(`discord stale stream preview cleanup failed: ${formatErrorMessage(err)}`);
|
|
543
|
+
}
|
|
544
|
+
return true;
|
|
545
|
+
}
|
|
472
546
|
if (typeof sentMessageId !== "string" || !sentMessageId) {
|
|
473
547
|
streamState.stopped = true;
|
|
474
548
|
params.warn?.("discord stream preview stopped (missing message id from send)");
|
|
@@ -477,6 +551,11 @@ function createDiscordDraftStream(params) {
|
|
|
477
551
|
streamMessageId = sentMessageId;
|
|
478
552
|
return true;
|
|
479
553
|
} catch (err) {
|
|
554
|
+
if (activeCreateGeneration === generation) {
|
|
555
|
+
activeCreateGeneration = void 0;
|
|
556
|
+
discardActiveCreate = false;
|
|
557
|
+
}
|
|
558
|
+
if (generation !== streamGeneration) return true;
|
|
480
559
|
streamState.stopped = true;
|
|
481
560
|
params.warn?.(`discord stream preview failed: ${formatErrorMessage(err)}`);
|
|
482
561
|
return false;
|
|
@@ -501,10 +580,15 @@ function createDiscordDraftStream(params) {
|
|
|
501
580
|
warn: params.warn,
|
|
502
581
|
warnPrefix: "discord stream preview cleanup failed"
|
|
503
582
|
});
|
|
504
|
-
const forceNewMessage = () => {
|
|
583
|
+
const forceNewMessage = (mode = "preserve") => {
|
|
584
|
+
if (mode === "discard" && activeCreateGeneration !== void 0) discardActiveCreate = true;
|
|
585
|
+
streamGeneration += 1;
|
|
586
|
+
streamState.stopped = false;
|
|
587
|
+
streamState.final = false;
|
|
505
588
|
streamMessageId = void 0;
|
|
506
589
|
lastSentText = "";
|
|
507
590
|
loop.resetPending();
|
|
591
|
+
loop.resetThrottleWindow();
|
|
508
592
|
};
|
|
509
593
|
const deleteCurrentMessage = async () => {
|
|
510
594
|
loop.resetPending();
|
|
@@ -534,6 +618,12 @@ function createDiscordDraftStream(params) {
|
|
|
534
618
|
};
|
|
535
619
|
}
|
|
536
620
|
//#endregion
|
|
621
|
+
//#region extensions/discord/src/preview-streaming.ts
|
|
622
|
+
function resolveDiscordPreviewStreamMode(params = {}) {
|
|
623
|
+
if (params.streaming === void 0) return "progress";
|
|
624
|
+
return resolveChannelPreviewStreamMode(params, "off");
|
|
625
|
+
}
|
|
626
|
+
//#endregion
|
|
537
627
|
//#region extensions/discord/src/monitor/message-handler.draft-preview.ts
|
|
538
628
|
function createDiscordDraftPreviewController(params) {
|
|
539
629
|
const discordStreamMode = resolveDiscordPreviewStreamMode(params.discordConfig);
|
|
@@ -560,7 +650,14 @@ function createDiscordDraftPreviewController(params) {
|
|
|
560
650
|
let finalizedViaPreviewMessage = false;
|
|
561
651
|
let finalReplyDelivered = false;
|
|
562
652
|
let progressDraftStartedBeforeFinal = false;
|
|
563
|
-
|
|
653
|
+
let progressDraftCollapsed = false;
|
|
654
|
+
let progressNarratorLifecycle;
|
|
655
|
+
const progressConfig = resolveChannelProgressDraftConfig(params.discordConfig);
|
|
656
|
+
const progressHasExplicitLabel = progressConfig.label !== void 0 || progressConfig.labels !== void 0;
|
|
657
|
+
const progressToolDefault = progressConfig.toolProgress ?? progressHasExplicitLabel;
|
|
658
|
+
const previewToolProgressEnabled = Boolean(draftStream) && resolveChannelStreamingPreviewToolProgress(params.discordConfig, discordStreamMode === "progress" ? progressToolDefault : true);
|
|
659
|
+
const narrationProgressEnabled = Boolean(draftStream) && discordStreamMode === "progress" && resolveChannelStreamingProgressNarration(params.discordConfig);
|
|
660
|
+
const narrationHideCommandText = narrationProgressEnabled && resolveChannelStreamingPreviewCommandText(params.discordConfig) === "status";
|
|
564
661
|
const suppressDefaultToolProgressMessages = Boolean(draftStream) && resolveChannelStreamingSuppressDefaultToolProgressMessages(params.discordConfig, {
|
|
565
662
|
draftStreamActive: true,
|
|
566
663
|
previewToolProgressEnabled
|
|
@@ -573,7 +670,7 @@ function createDiscordDraftPreviewController(params) {
|
|
|
573
670
|
seed: progressSeed,
|
|
574
671
|
reasoningLinePrefix: "🧠 ",
|
|
575
672
|
commentaryLinePrefix: "💬 ",
|
|
576
|
-
reasoningGate:
|
|
673
|
+
reasoningGate: previewToolProgressEnabled,
|
|
577
674
|
commentaryItalics: false,
|
|
578
675
|
update: async (previewText, options) => {
|
|
579
676
|
lastPartialText = previewText;
|
|
@@ -605,23 +702,42 @@ function createDiscordDraftPreviewController(params) {
|
|
|
605
702
|
}
|
|
606
703
|
resetProgressState();
|
|
607
704
|
};
|
|
705
|
+
const pushPreambleHeadline = async (text, options) => {
|
|
706
|
+
if (discordStreamMode === "progress") await progressDraft.pushPreambleHeadline(text, options);
|
|
707
|
+
};
|
|
608
708
|
return {
|
|
609
709
|
draftStream,
|
|
610
710
|
previewToolProgressEnabled,
|
|
711
|
+
narrationProgressEnabled,
|
|
712
|
+
narrationHideCommandText,
|
|
611
713
|
commentaryProgressEnabled: progressDraft.commentaryProgressEnabled,
|
|
612
714
|
suppressDefaultToolProgressMessages,
|
|
613
715
|
get isProgressMode() {
|
|
614
716
|
return discordStreamMode === "progress";
|
|
615
717
|
},
|
|
616
718
|
get hasProgressDraftStarted() {
|
|
617
|
-
return progressDraft.hasStarted
|
|
719
|
+
return progressDraft.hasStarted;
|
|
720
|
+
},
|
|
721
|
+
get isProgressDraftVisible() {
|
|
722
|
+
return progressDraft.isVisible;
|
|
723
|
+
},
|
|
724
|
+
get hasProgressDraftToCollapse() {
|
|
725
|
+
return !progressDraftCollapsed && (progressDraft.hasStarted || progressDraftStartedBeforeFinal);
|
|
726
|
+
},
|
|
727
|
+
markProgressDraftCollapsed() {
|
|
728
|
+
progressDraftCollapsed = true;
|
|
729
|
+
progressDraftStartedBeforeFinal = false;
|
|
618
730
|
},
|
|
619
731
|
get finalizedViaPreviewMessage() {
|
|
620
732
|
return finalizedViaPreviewMessage;
|
|
621
733
|
},
|
|
734
|
+
setProgressNarratorLifecycle(lifecycle) {
|
|
735
|
+
progressNarratorLifecycle = lifecycle;
|
|
736
|
+
},
|
|
622
737
|
markFinalReplyStarted() {
|
|
623
738
|
progressDraftStartedBeforeFinal ||= progressDraft.hasStarted;
|
|
624
739
|
progressDraft.markFinalReplyStarted();
|
|
740
|
+
progressNarratorLifecycle?.stopTurn();
|
|
625
741
|
},
|
|
626
742
|
markFinalReplyDelivered() {
|
|
627
743
|
finalReplyDelivered = true;
|
|
@@ -637,6 +753,15 @@ function createDiscordDraftPreviewController(params) {
|
|
|
637
753
|
async pushReasoningProgress(text, options) {
|
|
638
754
|
await progressDraft.pushReasoningProgress(text, options);
|
|
639
755
|
},
|
|
756
|
+
async pushNarrationProgress(text) {
|
|
757
|
+
await progressDraft.pushNarrationProgress(text);
|
|
758
|
+
},
|
|
759
|
+
pushPreambleHeadline,
|
|
760
|
+
async pushPreambleItemEvent(payload, noteCommentary) {
|
|
761
|
+
await pushPreambleHeadline(payload.progressText, { itemId: payload.itemId });
|
|
762
|
+
if (!progressDraft.commentaryProgressEnabled) return;
|
|
763
|
+
if (await progressDraft.pushCommentaryProgress(payload.progressText, { itemId: payload.itemId })) noteCommentary(payload.itemId, payload.progressText);
|
|
764
|
+
},
|
|
640
765
|
async pushCommentaryProgress(text, options) {
|
|
641
766
|
await progressDraft.pushCommentaryProgress(text, options);
|
|
642
767
|
},
|
|
@@ -650,7 +775,7 @@ function createDiscordDraftPreviewController(params) {
|
|
|
650
775
|
});
|
|
651
776
|
if (!chunks.length && formatted) chunks.push(formatted);
|
|
652
777
|
if (chunks.length !== 1) return;
|
|
653
|
-
const trimmed = chunks
|
|
778
|
+
const trimmed = expectDefined(chunks.at(0), "single Discord preview chunk").trim();
|
|
654
779
|
if (!trimmed) return;
|
|
655
780
|
const currentPreviewText = discordStreamMode === "block" ? draftText : lastPartialText;
|
|
656
781
|
if (currentPreviewText && currentPreviewText.startsWith(trimmed) && trimmed.length < currentPreviewText.length) return;
|
|
@@ -696,9 +821,20 @@ function createDiscordDraftPreviewController(params) {
|
|
|
696
821
|
});
|
|
697
822
|
},
|
|
698
823
|
handleAssistantMessageBoundary() {
|
|
699
|
-
progressDraft.beginNewTurn();
|
|
700
|
-
if (
|
|
824
|
+
const beganNewTurn = progressDraft.beginNewTurn();
|
|
825
|
+
if (beganNewTurn) {
|
|
826
|
+
progressDraftCollapsed = false;
|
|
827
|
+
progressDraftStartedBeforeFinal = false;
|
|
828
|
+
finalReplyDelivered = false;
|
|
829
|
+
finalizedViaPreviewMessage = false;
|
|
830
|
+
progressNarratorLifecycle?.beginTurn();
|
|
831
|
+
}
|
|
832
|
+
if (discordStreamMode === "progress") {
|
|
833
|
+
if (beganNewTurn) draftStream?.forceNewMessage("discard");
|
|
834
|
+
return beganNewTurn;
|
|
835
|
+
}
|
|
701
836
|
forceNewMessageIfNeeded();
|
|
837
|
+
return beganNewTurn;
|
|
702
838
|
},
|
|
703
839
|
async flush() {
|
|
704
840
|
if (!draftStream) return;
|
|
@@ -718,7 +854,7 @@ function createDiscordDraftPreviewController(params) {
|
|
|
718
854
|
try {
|
|
719
855
|
progressDraft.cancel();
|
|
720
856
|
if (!finalReplyDelivered) await draftStream?.discardPending();
|
|
721
|
-
if (!
|
|
857
|
+
if (!finalizedViaPreviewMessage && draftStream?.messageId()) await draftStream.clear();
|
|
722
858
|
} catch (err) {
|
|
723
859
|
params.log(`discord: draft cleanup failed: ${String(err)}`);
|
|
724
860
|
}
|
|
@@ -739,14 +875,13 @@ const TARGETED_ONLY_ALLOWED_MENTIONS = { parse: ["users", "roles"] };
|
|
|
739
875
|
function isProcessAborted(abortSignal) {
|
|
740
876
|
return Boolean(abortSignal?.aborted);
|
|
741
877
|
}
|
|
742
|
-
function formatDiscordReplyDeliveryFailure(params) {
|
|
743
|
-
const context = [`target=${params.target}`, params.sessionKey ? `session=${params.sessionKey}` : void 0].filter(Boolean).join(" ");
|
|
744
|
-
return `discord ${params.kind} reply failed (${context}): ${String(params.err)}`;
|
|
745
|
-
}
|
|
746
878
|
function isFallbackOnlyToolWarningFinal(payload) {
|
|
747
879
|
if (payload.isError !== true || !isReplyPayloadNonTerminalToolErrorWarning(payload)) return false;
|
|
748
880
|
return !resolveSendableOutboundReplyParts(payload).hasMedia;
|
|
749
881
|
}
|
|
882
|
+
function isFailedProgress(payload) {
|
|
883
|
+
return payload.phase === "error" || payload.status === "failed" || payload.status === "error" || typeof payload.exitCode === "number" && payload.exitCode !== 0;
|
|
884
|
+
}
|
|
750
885
|
function formatDiscordReplySkip(params) {
|
|
751
886
|
const context = [`target=${params.target}`, params.sessionKey ? `session=${params.sessionKey}` : void 0].filter(Boolean).join(" ");
|
|
752
887
|
return `discord ${params.kind} reply skipped (${params.reason}): ${context}`;
|
|
@@ -776,7 +911,7 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
776
911
|
}
|
|
777
912
|
const boundThreadId = ctx.threadBinding?.conversation?.conversationId?.trim();
|
|
778
913
|
if (boundThreadId && typeof threadBindings.touchThread === "function") threadBindings.touchThread({ threadId: boundThreadId });
|
|
779
|
-
const { dispatchReplyWithBufferedBlockDispatcher } = await loadReplyRuntime();
|
|
914
|
+
const { dispatchReplyWithBufferedBlockDispatcher: dispatchReply } = await loadReplyRuntime();
|
|
780
915
|
const sourceReplyDeliveryMode = resolveChannelMessageSourceReplyDeliveryMode({
|
|
781
916
|
cfg,
|
|
782
917
|
ctx: {
|
|
@@ -1016,7 +1151,6 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1016
1151
|
log: logVerbose
|
|
1017
1152
|
});
|
|
1018
1153
|
let shouldYieldDraftProgress = () => false;
|
|
1019
|
-
const finalPreviewFlags = discordConfig?.suppressEmbeds ?? true ? MessageFlags.SuppressEmbeds : void 0;
|
|
1020
1154
|
let finalReplyStartNotified = false;
|
|
1021
1155
|
const notifyFinalReplyStart = () => {
|
|
1022
1156
|
if (finalReplyStartNotified) return;
|
|
@@ -1061,11 +1195,12 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1061
1195
|
})();
|
|
1062
1196
|
const reasoningDurableEnabled = reasoningLevel === "on";
|
|
1063
1197
|
const reasoningWindowEnabled = reasoningLevel === "stream";
|
|
1064
|
-
|
|
1198
|
+
let progressTurnStartedAt = Date.now();
|
|
1065
1199
|
let progressReasoningSteps = 0;
|
|
1066
1200
|
let progressToolCalls = 0;
|
|
1067
1201
|
let progressCommentaryNotes = 0;
|
|
1068
|
-
let
|
|
1202
|
+
let progressReceiptLine;
|
|
1203
|
+
let clearProgressDraftAfterFinalDelivery = false;
|
|
1069
1204
|
const seenCommentaryIds = /* @__PURE__ */ new Set();
|
|
1070
1205
|
let lastCommentaryNoteText = "";
|
|
1071
1206
|
const noteWindowCommentary = (itemId, noteText) => {
|
|
@@ -1089,6 +1224,24 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1089
1224
|
progressReasoningSteps += 1;
|
|
1090
1225
|
}
|
|
1091
1226
|
};
|
|
1227
|
+
const resetProgressTurnState = () => {
|
|
1228
|
+
finalReplyStartNotified = false;
|
|
1229
|
+
userFacingFinalDelivered = false;
|
|
1230
|
+
userFacingFinalDeliveryFailed = false;
|
|
1231
|
+
pendingToolWarningFinal = void 0;
|
|
1232
|
+
progressTurnStartedAt = Date.now();
|
|
1233
|
+
progressReasoningSteps = 0;
|
|
1234
|
+
progressToolCalls = 0;
|
|
1235
|
+
progressCommentaryNotes = 0;
|
|
1236
|
+
progressReceiptLine = void 0;
|
|
1237
|
+
clearProgressDraftAfterFinalDelivery = false;
|
|
1238
|
+
seenCommentaryIds.clear();
|
|
1239
|
+
lastCommentaryNoteText = "";
|
|
1240
|
+
windowReasoningOpen = false;
|
|
1241
|
+
};
|
|
1242
|
+
const handleAssistantMessageBoundary = () => {
|
|
1243
|
+
if (draftPreview.handleAssistantMessageBoundary()) resetProgressTurnState();
|
|
1244
|
+
};
|
|
1092
1245
|
const buildProgressSummaryLine = () => {
|
|
1093
1246
|
closePendingWindowThought();
|
|
1094
1247
|
const seconds = Math.max(1, Math.round((Date.now() - progressTurnStartedAt) / 1e3));
|
|
@@ -1161,7 +1314,6 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1161
1314
|
kind: "block"
|
|
1162
1315
|
});
|
|
1163
1316
|
replyReference.markSent();
|
|
1164
|
-
persistentReasoningDelivered = true;
|
|
1165
1317
|
return { visibleReplySent: true };
|
|
1166
1318
|
}
|
|
1167
1319
|
if (isFinal && !options?.allowFallbackOnlyToolWarning && isFallbackOnlyToolWarningFinal(payload)) {
|
|
@@ -1193,51 +1345,10 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1193
1345
|
if (draftStream && draftPreview.isProgressMode && info.kind === "block") {
|
|
1194
1346
|
if (!resolveSendableOutboundReplyParts(deliverablePayload).hasMedia && !deliverablePayload.isError) return { visibleReplySent: false };
|
|
1195
1347
|
}
|
|
1196
|
-
if (draftStream && isFinal && draftPreview.isProgressMode &&
|
|
1348
|
+
if (draftStream && isFinal && draftPreview.isProgressMode && !deliverablePayload.isError && draftPreview.hasProgressDraftToCollapse && draftStream) {
|
|
1197
1349
|
await draftPreview.flush();
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
await deliverDiscordReply({
|
|
1201
|
-
cfg,
|
|
1202
|
-
replies: [{ text: buildProgressSummaryLine() }],
|
|
1203
|
-
target: deliverTarget,
|
|
1204
|
-
token,
|
|
1205
|
-
accountId,
|
|
1206
|
-
rest: deliveryRest,
|
|
1207
|
-
runtime,
|
|
1208
|
-
replyToId: replyReference.use(),
|
|
1209
|
-
replyToMode,
|
|
1210
|
-
textLimit,
|
|
1211
|
-
maxLinesPerMessage,
|
|
1212
|
-
tableMode,
|
|
1213
|
-
chunkMode,
|
|
1214
|
-
sessionKey: ctxPayload.SessionKey,
|
|
1215
|
-
threadBindings,
|
|
1216
|
-
mediaLocalRoots,
|
|
1217
|
-
kind: "block"
|
|
1218
|
-
});
|
|
1219
|
-
replyReference.markSent();
|
|
1220
|
-
draftPreview.markPreviewFinalized();
|
|
1221
|
-
} else {
|
|
1222
|
-
const draftId = draftStream.messageId();
|
|
1223
|
-
if (draftId !== void 0) {
|
|
1224
|
-
await draftStream.seal();
|
|
1225
|
-
try {
|
|
1226
|
-
await editMessageDiscord(deliverChannelId, draftId, {
|
|
1227
|
-
content: buildProgressSummaryLine(),
|
|
1228
|
-
...finalPreviewFlags ? { flags: finalPreviewFlags } : {}
|
|
1229
|
-
}, {
|
|
1230
|
-
cfg,
|
|
1231
|
-
accountId,
|
|
1232
|
-
rest: deliveryRest
|
|
1233
|
-
});
|
|
1234
|
-
draftPreview.markPreviewFinalized();
|
|
1235
|
-
} catch (err) {
|
|
1236
|
-
logVerbose(`discord: progress draft summary edit failed; clearing draft (${String(err)})`);
|
|
1237
|
-
await draftStream.clear();
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1350
|
+
progressReceiptLine = buildProgressSummaryLine();
|
|
1351
|
+
clearProgressDraftAfterFinalDelivery = true;
|
|
1241
1352
|
}
|
|
1242
1353
|
if (draftStream && isFinal && !draftPreview.isProgressMode && !deliverablePayload.isError) {
|
|
1243
1354
|
const ttsSupplement = getReplyPayloadTtsSupplement(deliverablePayload);
|
|
@@ -1319,9 +1430,14 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1319
1430
|
}
|
|
1320
1431
|
const replyToId = replyReference.use();
|
|
1321
1432
|
if (isFinal) notifyFinalReplyStart();
|
|
1433
|
+
const receiptLine = isFinal && deliverablePayload.isError !== true ? progressReceiptLine : void 0;
|
|
1434
|
+
const payloadForDelivery = receiptLine ? {
|
|
1435
|
+
...deliverablePayload,
|
|
1436
|
+
text: deliverablePayload.text?.trim() ? `${deliverablePayload.text.trimEnd()}\n${receiptLine}` : receiptLine
|
|
1437
|
+
} : deliverablePayload;
|
|
1322
1438
|
await deliverDiscordReply({
|
|
1323
1439
|
cfg,
|
|
1324
|
-
replies: [
|
|
1440
|
+
replies: [payloadForDelivery],
|
|
1325
1441
|
target: deliverTarget,
|
|
1326
1442
|
token,
|
|
1327
1443
|
accountId,
|
|
@@ -1339,7 +1455,18 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1339
1455
|
kind: info.kind
|
|
1340
1456
|
});
|
|
1341
1457
|
replyReference.markSent();
|
|
1342
|
-
if (isFinal && deliverablePayload.isError !== true)
|
|
1458
|
+
if (isFinal && deliverablePayload.isError !== true) {
|
|
1459
|
+
if (receiptLine) {
|
|
1460
|
+
progressReceiptLine = void 0;
|
|
1461
|
+
draftPreview.markProgressDraftCollapsed();
|
|
1462
|
+
}
|
|
1463
|
+
markUserFacingFinalDelivered();
|
|
1464
|
+
if (clearProgressDraftAfterFinalDelivery) {
|
|
1465
|
+
clearProgressDraftAfterFinalDelivery = false;
|
|
1466
|
+
await draftStream?.discardPending();
|
|
1467
|
+
await draftStream?.clear();
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1343
1470
|
return { visibleReplySent: true };
|
|
1344
1471
|
};
|
|
1345
1472
|
const onDiscordDeliveryError = (err, info) => {
|
|
@@ -1387,7 +1514,7 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1387
1514
|
ctxPayload,
|
|
1388
1515
|
recordInboundSession,
|
|
1389
1516
|
afterRecord: queueInitialAckReactionAfterRecord,
|
|
1390
|
-
dispatchReplyWithBufferedBlockDispatcher,
|
|
1517
|
+
dispatchReplyWithBufferedBlockDispatcher: withDiscordSessionRetry(dispatchReply, abortSignal),
|
|
1391
1518
|
dispatcherOptions: {
|
|
1392
1519
|
...replyPipeline,
|
|
1393
1520
|
humanDelay: resolveHumanDelayConfig(cfg, route.agentId),
|
|
@@ -1416,20 +1543,28 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1416
1543
|
allowProgressCallbacksWhenSourceDeliverySuppressed: sourceRepliesAreToolOnly && draftPreview.draftStream && draftPreview.isProgressMode ? true : void 0,
|
|
1417
1544
|
disableBlockStreaming: sourceRepliesAreToolOnly ? true : draftPreview.disableBlockStreamingForDraft ?? (typeof resolvedBlockStreamingEnabled === "boolean" ? !resolvedBlockStreamingEnabled : void 0),
|
|
1418
1545
|
onPartialReply: draftPreview.draftStream && !draftPreview.isProgressMode ? (payload) => draftPreview.updateFromPartial(payload.text) : void 0,
|
|
1419
|
-
onAssistantMessageStart: draftPreview.draftStream ?
|
|
1546
|
+
onAssistantMessageStart: draftPreview.draftStream ? handleAssistantMessageBoundary : void 0,
|
|
1420
1547
|
onReasoningEnd: draftPreview.draftStream ? () => {
|
|
1421
1548
|
closePendingWindowThought();
|
|
1422
|
-
|
|
1549
|
+
handleAssistantMessageBoundary();
|
|
1423
1550
|
} : void 0,
|
|
1424
1551
|
onModelSelected,
|
|
1425
1552
|
suppressDefaultToolProgressMessages: sourceRepliesAreToolOnly && statusReactionsExplicitlyEnabled || draftPreview.suppressDefaultToolProgressMessages ? true : void 0,
|
|
1426
1553
|
allowToolLifecycleWhenProgressHidden: statusReactionsEnabled ? true : void 0,
|
|
1427
1554
|
commentaryProgressEnabled: draftPreview.isProgressMode ? draftPreview.commentaryProgressEnabled : void 0,
|
|
1555
|
+
progressPreambleEnabled: draftPreview.draftStream && draftPreview.isProgressMode ? true : void 0,
|
|
1428
1556
|
commentaryPayloadsEnabled: draftPreview.isProgressMode ? draftPreview.commentaryProgressEnabled : void 0,
|
|
1429
1557
|
reasoningPayloadsEnabled: reasoningDurableEnabled,
|
|
1430
1558
|
onVerboseProgressVisibility: (isActive) => {
|
|
1431
1559
|
shouldYieldDraftProgress = isActive;
|
|
1432
1560
|
},
|
|
1561
|
+
onNarrationUpdate: draftPreview.narrationProgressEnabled ? async (payload) => {
|
|
1562
|
+
if (isProcessAborted(abortSignal) || shouldYieldDraftProgress()) return;
|
|
1563
|
+
await draftPreview.pushNarrationProgress(payload.text);
|
|
1564
|
+
} : void 0,
|
|
1565
|
+
onProgressNarratorLifecycle: draftPreview.narrationProgressEnabled ? (lifecycle) => draftPreview.setProgressNarratorLifecycle(lifecycle) : void 0,
|
|
1566
|
+
isProgressDraftVisible: draftPreview.narrationProgressEnabled ? () => draftPreview.isProgressDraftVisible : void 0,
|
|
1567
|
+
narrationHideCommandText: draftPreview.narrationHideCommandText ? true : void 0,
|
|
1433
1568
|
onReasoningStream: async (payload) => {
|
|
1434
1569
|
if (payload?.requiresReasoningProgressOptIn === true && !reasoningWindowEnabled) return;
|
|
1435
1570
|
if (payload?.text) windowReasoningOpen = true;
|
|
@@ -1454,13 +1589,10 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1454
1589
|
}, payload.detailMode ? { detailMode: payload.detailMode } : void 0), { toolName: payload.name });
|
|
1455
1590
|
},
|
|
1456
1591
|
onItemEvent: async (payload) => {
|
|
1592
|
+
if (isFailedProgress(payload)) return false;
|
|
1457
1593
|
if (payload.kind === "preamble") {
|
|
1458
1594
|
if (shouldYieldDraftProgress()) return;
|
|
1459
|
-
|
|
1460
|
-
noteWindowCommentary(payload.itemId, payload.progressText);
|
|
1461
|
-
await draftPreview.pushCommentaryProgress(payload.progressText, { itemId: payload.itemId });
|
|
1462
|
-
}
|
|
1463
|
-
return;
|
|
1595
|
+
return await draftPreview.pushPreambleItemEvent(payload, noteWindowCommentary);
|
|
1464
1596
|
}
|
|
1465
1597
|
if (shouldYieldDraftProgress()) return;
|
|
1466
1598
|
await draftPreview.pushToolProgress(buildChannelProgressDraftLineForEntry(discordConfig, {
|
|
@@ -1499,6 +1631,7 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1499
1631
|
}));
|
|
1500
1632
|
},
|
|
1501
1633
|
onCommandOutput: async (payload) => {
|
|
1634
|
+
if (isFailedProgress(payload)) return false;
|
|
1502
1635
|
if (payload.phase !== "end") return;
|
|
1503
1636
|
if (shouldYieldDraftProgress()) return;
|
|
1504
1637
|
await draftPreview.pushToolProgress(buildChannelProgressDraftLine({
|
|
@@ -1551,6 +1684,7 @@ async function processDiscordMessageInner(ctx, observer) {
|
|
|
1551
1684
|
return;
|
|
1552
1685
|
}
|
|
1553
1686
|
dispatchError = true;
|
|
1687
|
+
if (await completeDiscordSessionConflict(err, deliverDiscordPayload, onDiscordDeliveryError)) return;
|
|
1554
1688
|
throw err;
|
|
1555
1689
|
} finally {
|
|
1556
1690
|
endDiscordInboundEventDeliveryCorrelation();
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-BjIf9lGs.js";
|
|
1
|
+
import { u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-DJD3qwIN.js";
|
|
3
2
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
3
|
import { ComponentType, StickerFormatType } from "discord-api-types/v10";
|
|
5
4
|
import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
@@ -275,7 +274,7 @@ async function resolveReferencedReplyMediaList(message, maxBytes, options) {
|
|
|
275
274
|
}
|
|
276
275
|
async function fetchDiscordMedia(params) {
|
|
277
276
|
const timeoutAbortController = params.totalTimeoutMs ? new AbortController() : void 0;
|
|
278
|
-
const signal =
|
|
277
|
+
const signal = params.abortSignal && timeoutAbortController ? AbortSignal.any([params.abortSignal, timeoutAbortController.signal]) : params.abortSignal ?? timeoutAbortController?.signal;
|
|
279
278
|
let timedOut = false;
|
|
280
279
|
let timeoutHandle = null;
|
|
281
280
|
const savePromise = saveRemoteMedia({
|