@openclaw/discord 2026.5.28 → 2026.5.31-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/{account-inspect-C4sJZNbI.js → account-inspect-DDZtT5C8.js} +9 -7
- package/dist/account-inspect-api.js +1 -1
- package/dist/{accounts-dXTfmnSZ.js → accounts-P19jm1lf.js} +1 -1
- package/dist/action-runtime-api.js +1 -1
- package/dist/api.js +16 -16
- package/dist/{approval-handler.runtime-CN_E7nkQ.js → approval-handler.runtime-DSFfzXpo.js} +4 -4
- package/dist/{audit-BFCBp74H.js → audit-kgIklCyI.js} +4 -4
- package/dist/{channel-COXb22wL.js → channel-D0gX0yj6.js} +44 -31
- package/dist/{channel-actions-C2g9OmnG.js → channel-actions-DDoc4V7x.js} +4 -4
- package/dist/{channel-actions.runtime-drnbrgpt.js → channel-actions.runtime-CqZfnMaA.js} +5 -5
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.setup-BsrP5-hv.js → channel.setup-BNZm3eed.js} +8 -23
- package/dist/{components-CjQujWa1.js → components-DcLQ2JkV.js} +1 -1
- package/dist/{config-schema-3tZYNVTM.js → config-schema-spuxW477.js} +17 -1
- package/dist/contract-api.js +3 -3
- package/dist/{conversation-identity-CsPV1Gjx.js → conversation-identity-BURFgcfI.js} +7 -5
- package/dist/{directory-config-BqPvRoDv.js → directory-config-B9Jw1Q2R.js} +2 -2
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-CCI0IMZq.js → directory-live-CDWUg-nA.js} +2 -2
- package/dist/{doctor-Dy7sI1sL.js → doctor-BUhqxLb9.js} +4 -5
- package/dist/{doctor-contract-8-Ia3d_X.js → doctor-contract-BAu3WLvd.js} +5 -5
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{handle-action.guild-admin-BmjclQbR.js → handle-action.guild-admin-Dpa-kUzu.js} +1 -1
- package/dist/index.js +1 -1
- package/dist/legacy-state-migrations-api.js +3 -1
- package/dist/{manager.runtime-ClhnLsZf.js → manager.runtime-BWBENHRA.js} +22 -19
- package/dist/{message-handler-BnhAHqem.js → message-handler-HO8BbZmQ.js} +182 -29
- package/dist/{message-handler.preflight-B1RTQ6ZO.js → message-handler.preflight-DxHBPQvD.js} +24 -17
- package/dist/{message-handler.process-B1ODKav3.js → message-handler.process-Cq3j7A9k.js} +41 -29
- package/dist/{message-utils-CmB03FoF.js → message-utils-D_3KTxh_.js} +19 -15
- package/dist/{outbound-adapter-DfY2Dtf3.js → outbound-adapter-BkPkILpq.js} +52 -87
- package/dist/{pluralkit-DAZN3ZMK.js → pluralkit-Ds9aZAM4.js} +1 -1
- package/dist/{probe-BiEg-_i1.js → probe-2MdGjUAf.js} +1 -1
- package/dist/{probe.runtime-Dja7CbJT.js → probe.runtime-J927koKG.js} +1 -1
- package/dist/{provider-DCcqVFp-.js → provider-BK8hjk_y.js} +224 -150
- package/dist/{provider-session.runtime-mKSG07RE.js → provider-session.runtime-CYMFlLg9.js} +3 -3
- package/dist/provider.runtime-RfQSSM_v.js +2 -0
- package/dist/{resolve-allowlist-common-DAIbZobr.js → resolve-allowlist-common-BIf3417N.js} +1 -1
- package/dist/{resolve-channels-D1zgoxnw.js → resolve-channels-DK-3f_aA.js} +2 -2
- package/dist/{resolve-users-wPAvLk_8.js → resolve-users-DUDPsfWt.js} +2 -2
- package/dist/{runtime-gaB5-Wsj.js → runtime-Blf_d9E7.js} +8 -8
- package/dist/runtime-api.actions.js +2 -2
- package/dist/runtime-api.js +22 -22
- package/dist/runtime-api.lookup.js +5 -5
- package/dist/runtime-api.monitor-LVbgPRHA.js +6 -0
- package/dist/runtime-api.monitor.js +5 -5
- package/dist/runtime-api.send.js +5 -5
- package/dist/runtime-api.threads.js +5 -5
- package/dist/{send-CBxhnbKU.js → send-BHkA8a-k.js} +7 -7
- package/dist/{send.components-uuQuHL3t.js → send.components-CUHzDapa.js} +26 -12
- package/dist/{send.outbound-DZHJYmNF.js → send.outbound-DSKZbjML.js} +15 -5
- package/dist/{send.receipt-3y2lVFRf.js → send.receipt-CjsWpitW.js} +25 -13
- package/dist/{send.shared-Ddl21-Gt.js → send.shared-Cluujl6W.js} +3 -3
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{shared-D3NkInmq.js → shared-BMGLQw74.js} +5 -5
- package/dist/{subagent-hooks-BacIbIBD.js → subagent-hooks-7jAn9HT5.js} +3 -3
- package/dist/subagent-hooks-api.js +1 -5
- package/dist/{system-events-Cw6Hp8RF.js → system-events-BjuNA9Zs.js} +1 -1
- package/dist/{target-resolver-jjQzAS6T.js → target-resolver-BYuWNVQp.js} +3 -3
- package/dist/targets-BNDUOdvI.js +3 -0
- package/dist/{thread-bindings-BBq-yzq2.js → thread-bindings-CKruJE91.js} +6 -6
- package/dist/{thread-bindings.discord-api-5QgEd_dW.js → thread-bindings.discord-api-BjLUwwSP.js} +5 -5
- package/dist/{thread-bindings.manager-COkxjwR9.js → thread-bindings.manager-Dji7SZHG.js} +4 -4
- package/dist/{thread-bindings.session-updates-D5gY2ZTE.js → thread-bindings.session-updates-DoDFvU_h.js} +1 -1
- package/dist/{thread-bindings.state-BsOnj5NX.js → thread-bindings.state-DYp4FVEB.js} +8 -2
- package/dist/{timeouts-l_PsHQvX.js → timeouts-CEJ3--Uw.js} +5 -2
- package/dist/timeouts.js +1 -1
- package/dist/{transcripts-source-DDrS8HrV.js → transcripts-source-O73_YIDs.js} +1 -1
- package/dist/transcripts-source-api.js +1 -1
- package/dist/{typing-B7bCMPJJ.js → typing-CKW0i8du.js} +2 -2
- package/node_modules/typebox/build/type/script/mapping.d.mts +5 -2
- package/node_modules/typebox/build/type/script/mapping.mjs +15 -8
- package/node_modules/typebox/build/type/script/parser.d.mts +3 -1
- package/node_modules/typebox/build/type/script/parser.mjs +2 -1
- package/node_modules/typebox/package.json +29 -29
- package/npm-shrinkwrap.json +7 -38
- package/openclaw.plugin.json +77 -1
- package/package.json +5 -5
- package/dist/provider.runtime-BmpunJHX.js +0 -2
- package/dist/runtime-api.monitor-B38upMUK.js +0 -5
- package/dist/targets-BVKF5wbg.js +0 -3
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { Ht as parseDiscordTarget, _ as VoiceStateUpdateListener, c as discord_exports, h as ResumedListener, jt as getGuildVoiceState, m as ReadyListener } from "./send.receipt-
|
|
2
|
-
import { c as resolveDiscordAccountAllowFrom } from "./accounts-
|
|
1
|
+
import { Ht as parseDiscordTarget, _ as VoiceStateUpdateListener, c as discord_exports, h as ResumedListener, jt as getGuildVoiceState, m as ReadyListener } from "./send.receipt-CjsWpitW.js";
|
|
2
|
+
import { c as resolveDiscordAccountAllowFrom } from "./accounts-P19jm1lf.js";
|
|
3
3
|
import { a as normalizeDiscordSlug, b as formatDiscordUserTag, m as resolveDiscordOwnerAccess } from "./allow-list-BnkWtVpA.js";
|
|
4
|
-
import {
|
|
4
|
+
import { o as formatMention } from "./send.outbound-DSKZbjML.js";
|
|
5
5
|
import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
|
|
6
|
-
import { f as buildDiscordGroupSystemPrompt, o as authorizeDiscordVoiceIngress, u as resolveDiscordVoiceEnabled } from "./provider-
|
|
6
|
+
import { f as buildDiscordGroupSystemPrompt, o as authorizeDiscordVoiceIngress, u as resolveDiscordVoiceEnabled } from "./provider-BK8hjk_y.js";
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
8
|
import { asBoolean, normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
9
9
|
import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
|
|
10
|
+
import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
10
11
|
import path from "node:path";
|
|
11
12
|
import { resolveFfmpegBin } from "openclaw/plugin-sdk/media-runtime";
|
|
12
13
|
import { createSubsystemLogger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
@@ -1425,17 +1426,21 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1425
1426
|
logger$2.warn(`discord voice: realtime wake-name follow-up has no speaker context voiceSession=${this.params.entry.voiceSessionKey} agent=${this.params.entry.route.agentId}`);
|
|
1426
1427
|
return;
|
|
1427
1428
|
}
|
|
1429
|
+
const expiresAt = resolveExpiresAtMsFromDurationMs(DISCORD_REALTIME_WAKE_NAME_FOLLOWUP_TTL_MS);
|
|
1430
|
+
if (expiresAt === void 0) return;
|
|
1428
1431
|
this.pendingWakeNameFollowup = {
|
|
1429
1432
|
context,
|
|
1430
1433
|
startedAt: turn?.startedAt ?? Date.now(),
|
|
1431
|
-
expiresAt
|
|
1434
|
+
expiresAt
|
|
1432
1435
|
};
|
|
1433
1436
|
logger$2.info(`discord voice: realtime wake-name follow-up armed speaker=${context.speakerLabel} voiceSession=${this.params.entry.voiceSessionKey} agent=${this.params.entry.route.agentId}`);
|
|
1434
1437
|
}
|
|
1435
1438
|
consumePendingWakeNameFollowup() {
|
|
1436
1439
|
const pending = this.pendingWakeNameFollowup;
|
|
1437
1440
|
this.pendingWakeNameFollowup = void 0;
|
|
1438
|
-
|
|
1441
|
+
const now = asDateTimestampMs(Date.now());
|
|
1442
|
+
const expiresAt = pending ? asDateTimestampMs(pending.expiresAt) : void 0;
|
|
1443
|
+
if (!pending || now === void 0 || expiresAt === void 0 || now > expiresAt) return;
|
|
1439
1444
|
const currentTurn = this.peekPendingSpeakerTurn();
|
|
1440
1445
|
if (currentTurn && currentTurn.context.userId !== pending.context.userId) return;
|
|
1441
1446
|
if (currentTurn) this.consumePendingSpeakerContext();
|
|
@@ -1949,7 +1954,9 @@ var DiscordVoiceSpeakerContextResolver = class {
|
|
|
1949
1954
|
const key = this.resolveCacheKey(guildId, userId);
|
|
1950
1955
|
const cached = this.cache.get(key);
|
|
1951
1956
|
if (!cached) return;
|
|
1952
|
-
|
|
1957
|
+
const now = asDateTimestampMs(Date.now());
|
|
1958
|
+
const expiresAt = asDateTimestampMs(cached.expiresAt);
|
|
1959
|
+
if (now === void 0 || expiresAt === void 0 || expiresAt <= now) {
|
|
1953
1960
|
this.cache.delete(key);
|
|
1954
1961
|
return;
|
|
1955
1962
|
}
|
|
@@ -1963,9 +1970,10 @@ var DiscordVoiceSpeakerContextResolver = class {
|
|
|
1963
1970
|
}
|
|
1964
1971
|
setCachedContext(guildId, userId, context) {
|
|
1965
1972
|
const key = this.resolveCacheKey(guildId, userId);
|
|
1966
|
-
|
|
1973
|
+
const expiresAt = resolveExpiresAtMsFromDurationMs(SPEAKER_CONTEXT_CACHE_TTL_MS);
|
|
1974
|
+
if (expiresAt !== void 0) this.cache.set(key, {
|
|
1967
1975
|
...context,
|
|
1968
|
-
expiresAt
|
|
1976
|
+
expiresAt
|
|
1969
1977
|
});
|
|
1970
1978
|
}
|
|
1971
1979
|
};
|
|
@@ -2394,11 +2402,6 @@ var DiscordVoiceManager$1 = class {
|
|
|
2394
2402
|
logger.info(`discord voice: joining guild=${guildId} channel=${channelId} mode=${voiceMode} agent=${route.agentId} voiceSession=${voiceRoute.sessionKey} supervisorSession=${route.sessionKey} agentSessionMode=${agentSessionMode}${agentSessionTarget ? ` agentSessionTarget=${agentSessionTarget}` : ""} voiceModel=${voiceConfig?.model ?? "route-default"} realtimeProvider=${voiceConfig?.realtime?.provider ?? "auto"} realtimeModel=${voiceConfig?.realtime?.model ?? "provider-default"} realtimeVoice=${voiceConfig?.realtime?.voice ?? "provider-default"}`);
|
|
2395
2403
|
const player = voiceSdk.createAudioPlayer();
|
|
2396
2404
|
connection.subscribe(player);
|
|
2397
|
-
let speakingHandler;
|
|
2398
|
-
let speakingEndHandler;
|
|
2399
|
-
let disconnectedHandler;
|
|
2400
|
-
let destroyedHandler;
|
|
2401
|
-
let playerErrorHandler;
|
|
2402
2405
|
let stopped = false;
|
|
2403
2406
|
const clearSessionIfCurrent = () => {
|
|
2404
2407
|
if (this.sessions.get(guildId)?.connection === connection) this.sessions.delete(guildId);
|
|
@@ -2474,15 +2477,15 @@ var DiscordVoiceManager$1 = class {
|
|
|
2474
2477
|
channelId
|
|
2475
2478
|
};
|
|
2476
2479
|
}
|
|
2477
|
-
speakingHandler = (userId) => {
|
|
2480
|
+
const speakingHandler = (userId) => {
|
|
2478
2481
|
this.handleSpeakingStart(entry, userId).catch((err) => {
|
|
2479
2482
|
logger.warn(`discord voice: capture failed: ${formatErrorMessage(err)}`);
|
|
2480
2483
|
});
|
|
2481
2484
|
};
|
|
2482
|
-
speakingEndHandler = (userId) => {
|
|
2485
|
+
const speakingEndHandler = (userId) => {
|
|
2483
2486
|
this.scheduleCaptureFinalize(entry, userId, "speaker end");
|
|
2484
2487
|
};
|
|
2485
|
-
disconnectedHandler = async () => {
|
|
2488
|
+
const disconnectedHandler = async () => {
|
|
2486
2489
|
try {
|
|
2487
2490
|
logVoiceVerbose(`disconnected: attempting recovery guild ${guildId} channel ${channelId} grace=${reconnectGraceMs}ms`);
|
|
2488
2491
|
await Promise.race([voiceSdk.entersState(connection, voiceSdk.VoiceConnectionStatus.Signalling, reconnectGraceMs), voiceSdk.entersState(connection, voiceSdk.VoiceConnectionStatus.Connecting, reconnectGraceMs)]);
|
|
@@ -2496,14 +2499,14 @@ var DiscordVoiceManager$1 = class {
|
|
|
2496
2499
|
});
|
|
2497
2500
|
}
|
|
2498
2501
|
};
|
|
2499
|
-
destroyedHandler = () => {
|
|
2502
|
+
const destroyedHandler = () => {
|
|
2500
2503
|
clearSessionIfCurrent();
|
|
2501
2504
|
stopEntry(entry, {
|
|
2502
2505
|
destroyConnection: false,
|
|
2503
2506
|
reason: `destroyed guild ${guildId} channel ${channelId}`
|
|
2504
2507
|
});
|
|
2505
2508
|
};
|
|
2506
|
-
playerErrorHandler = (err) => {
|
|
2509
|
+
const playerErrorHandler = (err) => {
|
|
2507
2510
|
logger.warn(`discord voice: playback error: ${formatErrorMessage(err)}`);
|
|
2508
2511
|
};
|
|
2509
2512
|
this.enableDaveReceivePassthrough(entry, "post-join warmup", 30);
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { I as createDiscordRestClient } from "./send.shared-
|
|
2
|
-
import { d as resolveDiscordChannelNameSafe, l as resolveDiscordChannelIdSafe, p as resolveDiscordChannelParentSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-
|
|
3
|
-
import { a as mergeAbortSignals } from "./timeouts-
|
|
4
|
-
import { c as hasDiscordMessageStickers, d as resolveDiscordMessageChannelId, r as resolveDiscordMessageText } from "./message-utils-
|
|
5
|
-
import { t as sendTyping } from "./typing-
|
|
1
|
+
import { I as createDiscordRestClient } from "./send.shared-Cluujl6W.js";
|
|
2
|
+
import { d as resolveDiscordChannelNameSafe, l as resolveDiscordChannelIdSafe, p as resolveDiscordChannelParentSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-BjLUwwSP.js";
|
|
3
|
+
import { a as mergeAbortSignals } from "./timeouts-CEJ3--Uw.js";
|
|
4
|
+
import { c as hasDiscordMessageStickers, d as resolveDiscordMessageChannelId, r as resolveDiscordMessageText } from "./message-utils-D_3KTxh_.js";
|
|
5
|
+
import { t as sendTyping } from "./typing-CKW0i8du.js";
|
|
6
6
|
import { danger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
7
|
-
import { createChannelRunQueue } from "openclaw/plugin-sdk/channel-outbound";
|
|
7
|
+
import { createChannelRunQueue, createTypingCallbacks, resolveChannelMessageSourceReplyDeliveryMode } from "openclaw/plugin-sdk/channel-outbound";
|
|
8
8
|
import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
9
9
|
import { resolveBatchedReplyThreadingPolicy } from "openclaw/plugin-sdk/reply-reference";
|
|
10
10
|
import { createChannelInboundDebouncer, shouldDebounceTextInbound } from "openclaw/plugin-sdk/channel-inbound";
|
|
11
11
|
import { createClaimableDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
|
|
12
|
+
import { logTypingFailure } from "openclaw/plugin-sdk/channel-feedback";
|
|
12
13
|
//#region extensions/discord/src/monitor/inbound-dedupe.ts
|
|
13
14
|
const RECENT_DISCORD_MESSAGE_TTL_MS = 5 * 6e4;
|
|
14
15
|
const RECENT_DISCORD_MESSAGE_MAX = 5e3;
|
|
@@ -59,7 +60,7 @@ function resolveDiscordInboundJobQueueKey(ctx) {
|
|
|
59
60
|
return ctx.messageChannelId;
|
|
60
61
|
}
|
|
61
62
|
function buildDiscordInboundJob(ctx, options) {
|
|
62
|
-
const { runtime, abortSignal, guildHistories, client, threadBindings, discordRestFetch, message, data, threadChannel, ...payload } = ctx;
|
|
63
|
+
const { runtime, abortSignal, guildHistories, client, threadBindings, replyTypingFeedback, discordRestFetch, message, data, threadChannel, ...payload } = ctx;
|
|
63
64
|
const sanitizedMessage = sanitizeDiscordInboundMessage(message);
|
|
64
65
|
return {
|
|
65
66
|
queueKey: resolveDiscordInboundJobQueueKey(ctx),
|
|
@@ -78,6 +79,7 @@ function buildDiscordInboundJob(ctx, options) {
|
|
|
78
79
|
guildHistories,
|
|
79
80
|
client,
|
|
80
81
|
threadBindings,
|
|
82
|
+
replyTypingFeedback,
|
|
81
83
|
discordRestFetch
|
|
82
84
|
},
|
|
83
85
|
replayKeys: options?.replayKeys ? [...options.replayKeys] : void 0
|
|
@@ -118,10 +120,65 @@ function applyImplicitReplyBatchGate(ctx, replyToMode, isBatched) {
|
|
|
118
120
|
ctx.ReplyThreading = replyThreading;
|
|
119
121
|
}
|
|
120
122
|
//#endregion
|
|
123
|
+
//#region extensions/discord/src/monitor/message-handler.reply-typing-policy.ts
|
|
124
|
+
function resolveDiscordSourceReplyDeliveryMode(ctx) {
|
|
125
|
+
return resolveChannelMessageSourceReplyDeliveryMode({
|
|
126
|
+
cfg: ctx.cfg,
|
|
127
|
+
ctx: {
|
|
128
|
+
ChatType: ctx.isDirectMessage ? "direct" : ctx.isGroupDm ? "group" : ctx.isGuildMessage ? "channel" : void 0,
|
|
129
|
+
InboundEventKind: ctx.inboundEventKind
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function resolveDiscordAcceptedTypingPrestart(ctx) {
|
|
134
|
+
const sourceReplyDeliveryMode = resolveDiscordSourceReplyDeliveryMode(ctx);
|
|
135
|
+
if (ctx.abortSignal?.aborted) return {
|
|
136
|
+
sourceReplyDeliveryMode,
|
|
137
|
+
shouldPrestart: false,
|
|
138
|
+
reason: "aborted"
|
|
139
|
+
};
|
|
140
|
+
if (!ctx.messageText.trim()) return {
|
|
141
|
+
sourceReplyDeliveryMode,
|
|
142
|
+
shouldPrestart: false,
|
|
143
|
+
reason: "empty"
|
|
144
|
+
};
|
|
145
|
+
if (ctx.inboundEventKind === "room_event") return {
|
|
146
|
+
sourceReplyDeliveryMode,
|
|
147
|
+
shouldPrestart: false,
|
|
148
|
+
reason: "room-event"
|
|
149
|
+
};
|
|
150
|
+
const configuredTypingMode = ctx.cfg.session?.typingMode ?? ctx.cfg.agents?.defaults?.typingMode;
|
|
151
|
+
if (configuredTypingMode !== void 0) return {
|
|
152
|
+
sourceReplyDeliveryMode,
|
|
153
|
+
shouldPrestart: configuredTypingMode === "instant",
|
|
154
|
+
reason: configuredTypingMode === "instant" ? "configured-instant" : "configured-not-instant"
|
|
155
|
+
};
|
|
156
|
+
if (sourceReplyDeliveryMode === "message_tool_only") return {
|
|
157
|
+
sourceReplyDeliveryMode,
|
|
158
|
+
shouldPrestart: true,
|
|
159
|
+
reason: "tool-only"
|
|
160
|
+
};
|
|
161
|
+
if (!ctx.isGuildMessage && !ctx.isGroupDm) return {
|
|
162
|
+
sourceReplyDeliveryMode,
|
|
163
|
+
shouldPrestart: true,
|
|
164
|
+
reason: "direct"
|
|
165
|
+
};
|
|
166
|
+
if (ctx.effectiveWasMentioned) return {
|
|
167
|
+
sourceReplyDeliveryMode,
|
|
168
|
+
shouldPrestart: true,
|
|
169
|
+
reason: "mentioned-group"
|
|
170
|
+
};
|
|
171
|
+
return {
|
|
172
|
+
sourceReplyDeliveryMode,
|
|
173
|
+
shouldPrestart: false,
|
|
174
|
+
reason: "defer-to-message"
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
//#endregion
|
|
121
178
|
//#region extensions/discord/src/monitor/message-run-queue.ts
|
|
122
179
|
let messageProcessRuntimePromise;
|
|
123
180
|
async function loadMessageProcessRuntime() {
|
|
124
|
-
messageProcessRuntimePromise ??= import("./message-handler.process-
|
|
181
|
+
messageProcessRuntimePromise ??= import("./message-handler.process-Cq3j7A9k.js");
|
|
125
182
|
return await messageProcessRuntimePromise;
|
|
126
183
|
}
|
|
127
184
|
async function processDiscordQueuedMessage(params) {
|
|
@@ -146,8 +203,20 @@ async function processDiscordQueuedMessage(params) {
|
|
|
146
203
|
throw error;
|
|
147
204
|
}
|
|
148
205
|
}
|
|
206
|
+
function cleanupSkippedDiscordQueuedMessage(params) {
|
|
207
|
+
try {
|
|
208
|
+
params.job.runtime.replyTypingFeedback?.onCleanup?.();
|
|
209
|
+
} finally {
|
|
210
|
+
releaseDiscordInboundReplay({
|
|
211
|
+
replayKeys: params.job.replayKeys,
|
|
212
|
+
error: new DiscordRetryableInboundError("discord queued run skipped before processing"),
|
|
213
|
+
replayGuard: params.replayGuard
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
149
217
|
function createDiscordMessageRunQueue(params) {
|
|
150
218
|
const replayGuard = params.replayGuard ?? createDiscordInboundReplayGuard();
|
|
219
|
+
const skippedCleanup = /* @__PURE__ */ new Set();
|
|
151
220
|
const runQueue = createChannelRunQueue({
|
|
152
221
|
setStatus: params.setStatus,
|
|
153
222
|
abortSignal: params.abortSignal,
|
|
@@ -155,9 +224,31 @@ function createDiscordMessageRunQueue(params) {
|
|
|
155
224
|
params.runtime.error(danger(`discord message run failed: ${String(error)}`));
|
|
156
225
|
}
|
|
157
226
|
});
|
|
227
|
+
let lifecycleActive = !params.abortSignal?.aborted;
|
|
228
|
+
const cleanupSkippedQueuedMessages = () => {
|
|
229
|
+
if (!lifecycleActive && skippedCleanup.size === 0) return;
|
|
230
|
+
lifecycleActive = false;
|
|
231
|
+
const cleanups = [...skippedCleanup];
|
|
232
|
+
skippedCleanup.clear();
|
|
233
|
+
for (const cleanup of cleanups) cleanup();
|
|
234
|
+
};
|
|
235
|
+
if (params.abortSignal?.aborted) cleanupSkippedQueuedMessages();
|
|
236
|
+
else params.abortSignal?.addEventListener("abort", cleanupSkippedQueuedMessages, { once: true });
|
|
158
237
|
return {
|
|
159
238
|
enqueue(job) {
|
|
239
|
+
const cleanupSkipped = () => {
|
|
240
|
+
cleanupSkippedDiscordQueuedMessage({
|
|
241
|
+
job,
|
|
242
|
+
replayGuard
|
|
243
|
+
});
|
|
244
|
+
};
|
|
245
|
+
if (!lifecycleActive) {
|
|
246
|
+
cleanupSkipped();
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
skippedCleanup.add(cleanupSkipped);
|
|
160
250
|
runQueue.enqueue(job.queueKey, async ({ lifecycleSignal }) => {
|
|
251
|
+
skippedCleanup.delete(cleanupSkipped);
|
|
161
252
|
await processDiscordQueuedMessage({
|
|
162
253
|
job,
|
|
163
254
|
lifecycleSignal,
|
|
@@ -166,39 +257,88 @@ function createDiscordMessageRunQueue(params) {
|
|
|
166
257
|
});
|
|
167
258
|
});
|
|
168
259
|
},
|
|
169
|
-
deactivate
|
|
260
|
+
deactivate() {
|
|
261
|
+
runQueue.deactivate();
|
|
262
|
+
cleanupSkippedQueuedMessages();
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function createDiscordReplyTypingFeedback(params) {
|
|
267
|
+
let channelId = params.channelId;
|
|
268
|
+
const rest = params.rest ?? createDiscordRestClient({
|
|
269
|
+
cfg: params.cfg,
|
|
270
|
+
token: params.token,
|
|
271
|
+
accountId: params.accountId
|
|
272
|
+
}).rest;
|
|
273
|
+
const createCallbacks = () => createTypingCallbacks({
|
|
274
|
+
start: () => sendTyping({
|
|
275
|
+
rest,
|
|
276
|
+
channelId
|
|
277
|
+
}),
|
|
278
|
+
onStartError: (err) => {
|
|
279
|
+
logTypingFailure({
|
|
280
|
+
log: params.log,
|
|
281
|
+
channel: "discord",
|
|
282
|
+
target: channelId,
|
|
283
|
+
error: err
|
|
284
|
+
});
|
|
285
|
+
},
|
|
286
|
+
maxDurationMs: params.maxDurationMs ?? 12e5
|
|
287
|
+
});
|
|
288
|
+
const updateChannelId = (nextChannelId) => {
|
|
289
|
+
const trimmed = nextChannelId.trim();
|
|
290
|
+
if (trimmed) channelId = trimmed;
|
|
291
|
+
};
|
|
292
|
+
let callbacks = createCallbacks();
|
|
293
|
+
return {
|
|
294
|
+
onReplyStart: () => callbacks.onReplyStart(),
|
|
295
|
+
onIdle: () => callbacks.onIdle?.(),
|
|
296
|
+
onCleanup: () => callbacks.onCleanup?.(),
|
|
297
|
+
updateChannelId,
|
|
298
|
+
restartForDispatch: (nextChannelId) => {
|
|
299
|
+
updateChannelId(nextChannelId);
|
|
300
|
+
callbacks.onCleanup?.();
|
|
301
|
+
callbacks = createCallbacks();
|
|
302
|
+
},
|
|
303
|
+
getChannelId: () => channelId
|
|
170
304
|
};
|
|
171
305
|
}
|
|
172
306
|
//#endregion
|
|
173
307
|
//#region extensions/discord/src/monitor/message-handler.ts
|
|
174
308
|
let messagePreflightRuntimePromise;
|
|
175
309
|
async function loadMessagePreflightRuntime() {
|
|
176
|
-
messagePreflightRuntimePromise ??= import("./message-handler.preflight-
|
|
310
|
+
messagePreflightRuntimePromise ??= import("./message-handler.preflight-DxHBPQvD.js");
|
|
177
311
|
return await messagePreflightRuntimePromise;
|
|
178
312
|
}
|
|
179
313
|
function isNonEmptyString(value) {
|
|
180
314
|
return typeof value === "string" && value.length > 0;
|
|
181
315
|
}
|
|
182
|
-
function
|
|
183
|
-
|
|
184
|
-
if (!ctx.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
function queueAcceptedDiscordTypingCue(ctx) {
|
|
190
|
-
if (!shouldSendAcceptedDiscordTypingCue(ctx)) return;
|
|
191
|
-
const { rest } = createDiscordRestClient({
|
|
316
|
+
function startAcceptedTypingFeedback(params) {
|
|
317
|
+
const { ctx, createFeedback, dedupeKey, activeFeedback } = params;
|
|
318
|
+
if (!resolveDiscordAcceptedTypingPrestart(ctx).shouldPrestart) return;
|
|
319
|
+
const channelId = ctx.messageChannelId.trim();
|
|
320
|
+
if (activeFeedback.get(dedupeKey)) return;
|
|
321
|
+
const replyTypingFeedback = ctx.replyTypingFeedback ?? (createFeedback ?? createDiscordReplyTypingFeedback)({
|
|
192
322
|
cfg: ctx.cfg,
|
|
193
323
|
token: ctx.token,
|
|
194
|
-
accountId: ctx.accountId
|
|
324
|
+
accountId: ctx.accountId,
|
|
325
|
+
channelId: ctx.messageChannelId,
|
|
326
|
+
log: logVerbose
|
|
327
|
+
});
|
|
328
|
+
const cleanup = replyTypingFeedback.onCleanup;
|
|
329
|
+
replyTypingFeedback.onCleanup = () => {
|
|
330
|
+
cleanup?.();
|
|
331
|
+
if (activeFeedback.get(dedupeKey)?.feedback === replyTypingFeedback) activeFeedback.delete(dedupeKey);
|
|
332
|
+
};
|
|
333
|
+
activeFeedback.set(dedupeKey, {
|
|
334
|
+
channelId,
|
|
335
|
+
feedback: replyTypingFeedback
|
|
195
336
|
});
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}).catch((err) => {
|
|
200
|
-
logVerbose(`discord early typing cue failed for channel ${ctx.messageChannelId}: ${String(err)}`);
|
|
337
|
+
ctx.replyTypingFeedback = replyTypingFeedback;
|
|
338
|
+
replyTypingFeedback.onReplyStart().catch((err) => {
|
|
339
|
+
logVerbose(`discord accepted typing feedback failed: ${String(err)}`);
|
|
201
340
|
});
|
|
341
|
+
return replyTypingFeedback;
|
|
202
342
|
}
|
|
203
343
|
function createDiscordMessageHandler(params) {
|
|
204
344
|
const { groupPolicy } = resolveOpenProviderRuntimeGroupPolicy({
|
|
@@ -209,6 +349,7 @@ function createDiscordMessageHandler(params) {
|
|
|
209
349
|
const ackReactionScope = params.discordConfig?.ackReactionScope ?? params.cfg.messages?.ackReactionScope ?? "group-mentions";
|
|
210
350
|
const preflightDiscordMessageImpl = params.testing?.preflightDiscordMessage;
|
|
211
351
|
const replayGuard = createDiscordInboundReplayGuard();
|
|
352
|
+
const prestartedTypingFeedback = /* @__PURE__ */ new Map();
|
|
212
353
|
const messageRunQueue = createDiscordMessageRunQueue({
|
|
213
354
|
runtime: params.runtime,
|
|
214
355
|
setStatus: params.setStatus,
|
|
@@ -269,8 +410,14 @@ function createDiscordMessageHandler(params) {
|
|
|
269
410
|
});
|
|
270
411
|
return;
|
|
271
412
|
}
|
|
413
|
+
const queueKey = resolveDiscordInboundJobQueueKey(ctx);
|
|
414
|
+
startAcceptedTypingFeedback({
|
|
415
|
+
ctx,
|
|
416
|
+
createFeedback: params.testing?.createReplyTypingFeedback,
|
|
417
|
+
dedupeKey: queueKey,
|
|
418
|
+
activeFeedback: prestartedTypingFeedback
|
|
419
|
+
});
|
|
272
420
|
applyImplicitReplyBatchGate(ctx, params.replyToMode, false);
|
|
273
|
-
queueAcceptedDiscordTypingCue(ctx);
|
|
274
421
|
messageRunQueue.enqueue(buildDiscordInboundJob(ctx, { replayKeys }));
|
|
275
422
|
return;
|
|
276
423
|
}
|
|
@@ -322,6 +469,13 @@ function createDiscordMessageHandler(params) {
|
|
|
322
469
|
});
|
|
323
470
|
return;
|
|
324
471
|
}
|
|
472
|
+
const queueKey = resolveDiscordInboundJobQueueKey(ctx);
|
|
473
|
+
startAcceptedTypingFeedback({
|
|
474
|
+
ctx,
|
|
475
|
+
createFeedback: params.testing?.createReplyTypingFeedback,
|
|
476
|
+
dedupeKey: queueKey,
|
|
477
|
+
activeFeedback: prestartedTypingFeedback
|
|
478
|
+
});
|
|
325
479
|
applyImplicitReplyBatchGate(ctx, params.replyToMode, true);
|
|
326
480
|
if (entries.length > 1) {
|
|
327
481
|
const ids = entries.map((entry) => entry.data.message?.id).filter(isNonEmptyString);
|
|
@@ -332,7 +486,6 @@ function createDiscordMessageHandler(params) {
|
|
|
332
486
|
ctxBatch.MessageSidLast = ids[ids.length - 1];
|
|
333
487
|
}
|
|
334
488
|
}
|
|
335
|
-
queueAcceptedDiscordTypingCue(ctx);
|
|
336
489
|
messageRunQueue.enqueue(buildDiscordInboundJob(ctx, { replayKeys }));
|
|
337
490
|
} catch (error) {
|
|
338
491
|
if (error instanceof DiscordRetryableInboundError) releaseDiscordInboundReplay({
|
|
@@ -378,4 +531,4 @@ function createDiscordMessageHandler(params) {
|
|
|
378
531
|
return handler;
|
|
379
532
|
}
|
|
380
533
|
//#endregion
|
|
381
|
-
export { createDiscordMessageHandler as t };
|
|
534
|
+
export { createDiscordReplyTypingFeedback as n, createDiscordMessageHandler as t };
|
package/dist/{message-handler.preflight-B1RTQ6ZO.js → message-handler.preflight-DxHBPQvD.js}
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { c as discord_exports, k as Message, mt as getChannelMessage } from "./send.receipt-
|
|
2
|
-
import { o as resolveDefaultDiscordAccountId } from "./accounts-
|
|
1
|
+
import { c as discord_exports, k as Message, mt as getChannelMessage } from "./send.receipt-CjsWpitW.js";
|
|
2
|
+
import { o as resolveDefaultDiscordAccountId } from "./accounts-P19jm1lf.js";
|
|
3
3
|
import { S as resolveTimestampMs, _ as resolveGroupDmAllow, a as normalizeDiscordSlug, b as formatDiscordUserTag, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordGuildEntry, f as resolveDiscordMemberAccessState, g as resolveDiscordShouldRequireMention, i as normalizeDiscordDisplaySlug, n as isDiscordGroupAllowedByPolicy, x as resolveDiscordSystemLocation } from "./allow-list-BnkWtVpA.js";
|
|
4
|
-
import { t as resolveDiscordConversationIdentity } from "./conversation-identity-
|
|
5
|
-
import { l as isRecentlyUnboundThreadWebhookMessage } from "./thread-bindings.state-
|
|
6
|
-
import { d as resolveDiscordChannelNameSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-
|
|
7
|
-
import "./thread-bindings-
|
|
8
|
-
import { D as resolveDiscordTextCommandAccess, E as resolveDiscordDmCommandAccess, _ as resolveDiscordEffectiveRoute, g as resolveDiscordConversationRoute, h as buildDiscordRoutePeer, v as shouldIgnoreStaleDiscordRouteBinding, y as handleDiscordDmCommandDecision } from "./provider-
|
|
9
|
-
import { d as resolveDiscordMessageChannelId, l as resolveDiscordMessageStickers, o as resolveMediaList, r as resolveDiscordMessageText, u as resolveDiscordChannelInfo } from "./message-utils-
|
|
4
|
+
import { t as resolveDiscordConversationIdentity } from "./conversation-identity-BURFgcfI.js";
|
|
5
|
+
import { l as isRecentlyUnboundThreadWebhookMessage } from "./thread-bindings.state-DYp4FVEB.js";
|
|
6
|
+
import { d as resolveDiscordChannelNameSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-BjLUwwSP.js";
|
|
7
|
+
import "./thread-bindings-CKruJE91.js";
|
|
8
|
+
import { D as resolveDiscordTextCommandAccess, E as resolveDiscordDmCommandAccess, _ as resolveDiscordEffectiveRoute, g as resolveDiscordConversationRoute, h as buildDiscordRoutePeer, v as shouldIgnoreStaleDiscordRouteBinding, y as handleDiscordDmCommandDecision } from "./provider-BK8hjk_y.js";
|
|
9
|
+
import { d as resolveDiscordMessageChannelId, l as resolveDiscordMessageStickers, o as resolveMediaList, r as resolveDiscordMessageText, u as resolveDiscordChannelInfo } from "./message-utils-D_3KTxh_.js";
|
|
10
10
|
import { n as resolveDiscordWebhookId, t as resolveDiscordSenderIdentity } from "./sender-identity-BFp5w0F8.js";
|
|
11
11
|
import { normalizeOptionalString, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
12
12
|
import { getChildLogger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
@@ -28,9 +28,12 @@ async function loadConversationRuntime$1() {
|
|
|
28
28
|
return await conversationRuntimePromise$1;
|
|
29
29
|
}
|
|
30
30
|
async function loadDiscordSendRuntime() {
|
|
31
|
-
discordSendRuntimePromise ??= import("./send-
|
|
31
|
+
discordSendRuntimePromise ??= import("./send-BHkA8a-k.js").then((n) => n.t);
|
|
32
32
|
return await discordSendRuntimePromise;
|
|
33
33
|
}
|
|
34
|
+
function resolveDiscordDmPairingSenderId(sender) {
|
|
35
|
+
return sender.isPluralKit ? `pk:${sender.id}` : sender.id;
|
|
36
|
+
}
|
|
34
37
|
async function resolveDiscordDmPreflightAccess(params) {
|
|
35
38
|
if (params.dmPolicy === "disabled") {
|
|
36
39
|
logVerbose("discord: drop dm (dmPolicy: disabled)");
|
|
@@ -69,9 +72,9 @@ async function resolveDiscordDmPreflightAccess(params) {
|
|
|
69
72
|
senderAccess: dmAccess.senderAccess,
|
|
70
73
|
accountId: params.resolvedAccountId,
|
|
71
74
|
sender: {
|
|
72
|
-
id: params.
|
|
73
|
-
tag: formatDiscordUserTag(params.author),
|
|
74
|
-
name: params.author.username ?? void 0
|
|
75
|
+
id: resolveDiscordDmPairingSenderId(params.sender),
|
|
76
|
+
tag: params.sender.tag ?? formatDiscordUserTag(params.author),
|
|
77
|
+
name: params.sender.name ?? params.author.username ?? void 0
|
|
75
78
|
},
|
|
76
79
|
onPairingCreated: async (code) => {
|
|
77
80
|
logVerbose(`discord pairing request sender=${params.author.id} tag=${formatDiscordUserTag(params.author)} reason=${dmAccess.senderAccess.reasonCode}`);
|
|
@@ -423,7 +426,7 @@ let preflightAudioRuntimePromise;
|
|
|
423
426
|
let systemEventsRuntimePromise;
|
|
424
427
|
let discordThreadingRuntimePromise;
|
|
425
428
|
async function loadPluralKitRuntime() {
|
|
426
|
-
pluralkitRuntimePromise ??= import("./pluralkit-
|
|
429
|
+
pluralkitRuntimePromise ??= import("./pluralkit-Ds9aZAM4.js").then((n) => n.n);
|
|
427
430
|
return await pluralkitRuntimePromise;
|
|
428
431
|
}
|
|
429
432
|
async function loadPreflightAudioRuntime() {
|
|
@@ -431,11 +434,11 @@ async function loadPreflightAudioRuntime() {
|
|
|
431
434
|
return await preflightAudioRuntimePromise;
|
|
432
435
|
}
|
|
433
436
|
async function loadSystemEventsRuntime() {
|
|
434
|
-
systemEventsRuntimePromise ??= import("./system-events-
|
|
437
|
+
systemEventsRuntimePromise ??= import("./system-events-BjuNA9Zs.js");
|
|
435
438
|
return await systemEventsRuntimePromise;
|
|
436
439
|
}
|
|
437
440
|
async function loadDiscordThreadingRuntime() {
|
|
438
|
-
discordThreadingRuntimePromise ??= import("./provider-
|
|
441
|
+
discordThreadingRuntimePromise ??= import("./provider-BK8hjk_y.js").then((n) => n.x);
|
|
439
442
|
return await discordThreadingRuntimePromise;
|
|
440
443
|
}
|
|
441
444
|
function isPreflightAborted(abortSignal) {
|
|
@@ -796,7 +799,11 @@ async function preflightDiscordMessage(params) {
|
|
|
796
799
|
logVerbose(`discord: drop bound-thread bot system message ${message.id}`);
|
|
797
800
|
return null;
|
|
798
801
|
}
|
|
799
|
-
const mentionRegexes = buildMentionRegexes(params.cfg, effectiveRoute.agentId
|
|
802
|
+
const mentionRegexes = buildMentionRegexes(params.cfg, effectiveRoute.agentId, {
|
|
803
|
+
provider: "discord",
|
|
804
|
+
conversationId: messageChannelId,
|
|
805
|
+
providerPolicy: params.discordConfig?.mentionPatterns
|
|
806
|
+
});
|
|
800
807
|
const explicitlyMentioned = Boolean(botId && message.mentionedUsers?.some((user) => user.id === botId));
|
|
801
808
|
const hasAnyMention = !isDirectMessage && ((message.mentionedUsers?.length ?? 0) > 0 || (message.mentionedRoles?.length ?? 0) > 0 || message.mentionedEveryone && (!author.bot || sender.isPluralKit));
|
|
802
809
|
const hasUserOrRoleMention = !isDirectMessage && ((message.mentionedUsers?.length ?? 0) > 0 || (message.mentionedRoles?.length ?? 0) > 0);
|
|
@@ -809,7 +816,7 @@ async function preflightDiscordMessage(params) {
|
|
|
809
816
|
guildId: params.data.guild_id ?? void 0,
|
|
810
817
|
guildEntries: params.guildEntries
|
|
811
818
|
}) : null;
|
|
812
|
-
logDebug(`[discord-preflight] guild_id=${params.data.guild_id} guild_obj=${
|
|
819
|
+
logDebug(`[discord-preflight] guild_id=${params.data.guild_id} guild_obj=${Boolean(params.data.guild)} guild_obj_id=${params.data.guild?.id} guildInfo=${Boolean(guildInfo)} guildEntries=${params.guildEntries ? Object.keys(params.guildEntries).join(",") : "none"}`);
|
|
813
820
|
if (isGuildMessage && params.guildEntries && Object.keys(params.guildEntries).length > 0 && !guildInfo) {
|
|
814
821
|
logDebug(`[discord-preflight] guild blocked: guild_id=${params.data.guild_id} guildEntries keys=${Object.keys(params.guildEntries).join(",")}`);
|
|
815
822
|
logVerbose(`Blocked discord guild ${params.data.guild_id ?? "unknown"} (not in discord.guilds)`);
|
|
@@ -1,17 +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-
|
|
2
|
-
import { f as resolveDiscordMaxLinesPerMessage } from "./accounts-
|
|
3
|
-
import { I as createDiscordRestClient, L as createDiscordRuntimeAccountContext, _ as resolveDiscordMessageFlags, d as resolveDiscordTargetChannelId } from "./send.shared-
|
|
1
|
+
import { Ut as resolveDiscordChannelId, c as discord_exports, ft as editChannelMessage, s as chunkDiscordTextWithMode, st as createChannelMessage, ut as deleteChannelMessage } from "./send.receipt-CjsWpitW.js";
|
|
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-Cluujl6W.js";
|
|
4
4
|
import { S as resolveTimestampMs, a as normalizeDiscordSlug, r as normalizeDiscordAllowList } from "./allow-list-BnkWtVpA.js";
|
|
5
|
-
import { a as removeReactionDiscord, f as editMessageDiscord, r as reactMessageDiscord } from "./send-
|
|
6
|
-
import "./
|
|
7
|
-
import
|
|
5
|
+
import { a as removeReactionDiscord, f as editMessageDiscord, r as reactMessageDiscord } from "./send-BHkA8a-k.js";
|
|
6
|
+
import { a as discordTextHasTargetedMention, i as discordTextHasBroadcastMention, s as rewriteDiscordKnownMentions } from "./send.outbound-DSKZbjML.js";
|
|
7
|
+
import "./targets-BNDUOdvI.js";
|
|
8
|
+
import { t as resolveDiscordConversationIdentity } from "./conversation-identity-BURFgcfI.js";
|
|
8
9
|
import { t as beginDiscordInboundEventDeliveryCorrelation } from "./inbound-event-delivery-CEPlt2uz.js";
|
|
9
|
-
import { t as DISCORD_TEXT_CHUNK_LIMIT } from "./outbound-adapter-
|
|
10
|
+
import { t as DISCORD_TEXT_CHUNK_LIMIT } from "./outbound-adapter-BkPkILpq.js";
|
|
10
11
|
import { t as resolveDiscordPreviewStreamMode } from "./preview-streaming-DXT8oJdo.js";
|
|
11
|
-
import { n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-
|
|
12
|
-
import { S as resolveDiscordAutoThreadReplyPlan, a as resolveReplyContext, i as buildGuildLabel, m as createDiscordSupplementalContextAccessChecker, n as deliverDiscordReply, p as buildDiscordInboundAccessContext, r as buildDirectLabel, w as resolveDiscordThreadStarter } from "./provider-
|
|
13
|
-
import { a as resolveForwardedMediaList, o as resolveMediaList, r as resolveDiscordMessageText, s as resolveReferencedReplyMediaList } from "./message-utils-
|
|
14
|
-
import {
|
|
12
|
+
import { n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-CEJ3--Uw.js";
|
|
13
|
+
import { S as resolveDiscordAutoThreadReplyPlan, a as resolveReplyContext, i as buildGuildLabel, m as createDiscordSupplementalContextAccessChecker, n as deliverDiscordReply, p as buildDiscordInboundAccessContext, r as buildDirectLabel, w as resolveDiscordThreadStarter } from "./provider-BK8hjk_y.js";
|
|
14
|
+
import { a as resolveForwardedMediaList, o as resolveMediaList, r as resolveDiscordMessageText, s as resolveReferencedReplyMediaList } from "./message-utils-D_3KTxh_.js";
|
|
15
|
+
import { n as createDiscordReplyTypingFeedback } from "./message-handler-HO8BbZmQ.js";
|
|
15
16
|
import { buildAgentSessionKey, normalizeAccountId, resolveAccountEntry, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
|
|
16
17
|
import { MessageFlags } from "discord-api-types/v10";
|
|
17
18
|
import path from "node:path";
|
|
@@ -30,7 +31,7 @@ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
|
30
31
|
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
|
|
31
32
|
import { loadSessionStore, readLatestAssistantTextFromSessionTranscript, readSessionUpdatedAt, resolveAndPersistSessionFile, resolveSessionStoreEntry, 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";
|
|
33
|
-
import { DEFAULT_TIMING, createStatusReactionController, logAckFailure,
|
|
34
|
+
import { DEFAULT_TIMING, createStatusReactionController, logAckFailure, shouldAckReaction } from "openclaw/plugin-sdk/channel-feedback";
|
|
34
35
|
import { createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
|
|
35
36
|
import { resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
|
|
36
37
|
//#region extensions/discord/src/monitor/ack-reactions.ts
|
|
@@ -286,6 +287,7 @@ async function buildDiscordMessageProcessContext(params) {
|
|
|
286
287
|
id: messageChannelId,
|
|
287
288
|
label: fromLabel,
|
|
288
289
|
spaceId: isGuildMessage ? (guildInfo?.id ?? guildSlug) || void 0 : void 0,
|
|
290
|
+
parentId: threadChannel ? threadParentId : void 0,
|
|
289
291
|
threadId: threadChannel?.id ?? autoThreadContext?.createdThreadId ?? void 0
|
|
290
292
|
},
|
|
291
293
|
route: {
|
|
@@ -848,7 +850,6 @@ function sleep(ms) {
|
|
|
848
850
|
setTimeout(resolve, ms);
|
|
849
851
|
});
|
|
850
852
|
}
|
|
851
|
-
const DISCORD_TYPING_MAX_DURATION_MS = 20 * 6e4;
|
|
852
853
|
let replyRuntimePromise;
|
|
853
854
|
async function loadReplyRuntime() {
|
|
854
855
|
replyRuntimePromise ??= import("openclaw/plugin-sdk/reply-runtime");
|
|
@@ -877,8 +878,15 @@ function readToolBooleanArg(args, key) {
|
|
|
877
878
|
return args[key] === true;
|
|
878
879
|
}
|
|
879
880
|
async function processDiscordMessage(ctx, observer) {
|
|
881
|
+
try {
|
|
882
|
+
await processDiscordMessageInner(ctx, observer);
|
|
883
|
+
} finally {
|
|
884
|
+
ctx.replyTypingFeedback?.onCleanup?.();
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
async function processDiscordMessageInner(ctx, observer) {
|
|
880
888
|
const dispatchStartedAt = Date.now();
|
|
881
|
-
const { cfg, discordConfig, accountId, token, runtime, guildHistories, historyLimit, mediaMaxBytes, textLimit, replyToMode, ackReactionScope, message, messageChannelId, isGuildMessage, isDirectMessage, isGroupDm, messageText, shouldRequireMention, canDetectMention, effectiveWasMentioned, shouldBypassMention, channelConfig, threadBindings, route, discordRestFetch, abortSignal, botLoopProtection } = ctx;
|
|
889
|
+
const { cfg, discordConfig, accountId, token, runtime, guildHistories, historyLimit, mediaMaxBytes, textLimit, replyToMode, ackReactionScope, message, messageChannelId, isGuildMessage, isDirectMessage, isGroupDm, messageText, shouldRequireMention, canDetectMention, effectiveWasMentioned, shouldBypassMention, channelConfig, threadBindings, route, discordRestFetch, abortSignal, botLoopProtection, replyTypingFeedback } = ctx;
|
|
882
890
|
if (isProcessAborted(abortSignal)) return;
|
|
883
891
|
if (botLoopProtection) {
|
|
884
892
|
const botLoopResult = recordChannelBotPairLoopAndCheckSuppression(botLoopProtection);
|
|
@@ -1050,26 +1058,22 @@ async function processDiscordMessage(ctx, observer) {
|
|
|
1050
1058
|
sessionKey: persistedSessionKey
|
|
1051
1059
|
});
|
|
1052
1060
|
const typingChannelId = deliverTarget.startsWith("channel:") ? deliverTarget.slice(8) : messageChannelId;
|
|
1061
|
+
const typingFeedback = replyTypingFeedback ?? createDiscordReplyTypingFeedback({
|
|
1062
|
+
cfg,
|
|
1063
|
+
token,
|
|
1064
|
+
accountId,
|
|
1065
|
+
channelId: typingChannelId,
|
|
1066
|
+
rest: feedbackRest,
|
|
1067
|
+
log: logVerbose
|
|
1068
|
+
});
|
|
1069
|
+
if (replyTypingFeedback) replyTypingFeedback.restartForDispatch(typingChannelId);
|
|
1070
|
+
else typingFeedback.updateChannelId(typingChannelId);
|
|
1053
1071
|
const { onModelSelected, ...replyPipeline } = createChannelMessageReplyPipeline({
|
|
1054
1072
|
cfg,
|
|
1055
1073
|
agentId: route.agentId,
|
|
1056
1074
|
channel: "discord",
|
|
1057
1075
|
accountId: route.accountId,
|
|
1058
|
-
|
|
1059
|
-
start: () => sendTyping({
|
|
1060
|
-
rest: feedbackRest,
|
|
1061
|
-
channelId: typingChannelId
|
|
1062
|
-
}),
|
|
1063
|
-
onStartError: (err) => {
|
|
1064
|
-
logTypingFailure({
|
|
1065
|
-
log: logVerbose,
|
|
1066
|
-
channel: "discord",
|
|
1067
|
-
target: typingChannelId,
|
|
1068
|
-
error: err
|
|
1069
|
-
});
|
|
1070
|
-
},
|
|
1071
|
-
maxDurationMs: DISCORD_TYPING_MAX_DURATION_MS
|
|
1072
|
-
}
|
|
1076
|
+
typingCallbacks: typingFeedback
|
|
1073
1077
|
});
|
|
1074
1078
|
const tableMode = resolveMarkdownTableMode({
|
|
1075
1079
|
cfg,
|
|
@@ -1241,6 +1245,14 @@ async function processDiscordMessage(ctx, observer) {
|
|
|
1241
1245
|
},
|
|
1242
1246
|
buildFinalEdit: () => {
|
|
1243
1247
|
if (draftPreview.finalizedViaPreviewMessage || hasMedia && !ttsSupplement || typeof previewFinalText !== "string" || hasExplicitReplyDirective || payload.isError) return;
|
|
1248
|
+
const rewrittenFinal = rewriteDiscordKnownMentions(previewFinalText, {
|
|
1249
|
+
accountId,
|
|
1250
|
+
mentionAliases: resolveDiscordAccount({
|
|
1251
|
+
cfg,
|
|
1252
|
+
accountId
|
|
1253
|
+
}).config.mentionAliases
|
|
1254
|
+
});
|
|
1255
|
+
if (discordTextHasTargetedMention(rewrittenFinal) && !discordTextHasBroadcastMention(rewrittenFinal)) return;
|
|
1244
1256
|
return {
|
|
1245
1257
|
content: previewFinalText,
|
|
1246
1258
|
...finalPreviewFlags ? { flags: finalPreviewFlags } : {}
|