@openclaw/discord 2026.9.8 → 2026.10.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/.setup/{account-inspect-De8hOUxG.mjs → account-inspect-CjKqkDnH.mjs} +2 -2
- package/dist/.setup/{accounts-ChaMcixG.mjs → accounts-DXHCL8Zm.mjs} +9 -32
- package/dist/.setup/{active-turn-thread-route-fmHl1HNd.mjs → active-turn-thread-route-C4tp9noA.mjs} +5 -9
- package/dist/.setup/{activities-api-tvbsU2e3.mjs → activities-api-BL_hJ0JQ.mjs} +15 -18
- package/dist/.setup/{api-DVbJwZVt.mjs → api-_oznjffB.mjs} +1 -1
- package/dist/.setup/{approval-handler.runtime-DxCK2Rux.mjs → approval-handler.runtime-BilYSrRF.mjs} +22 -61
- package/dist/.setup/{approval-message-updates-BKFqavHZ.mjs → approval-message-updates-CgRwc2_Q.mjs} +2 -2
- package/dist/.setup/{audit-CLg9I71N.mjs → audit-DtvzxONM.mjs} +4 -4
- package/dist/.setup/{channel-access-C12aDZ0p.mjs → channel-access-BRp3Y-rF.mjs} +4 -17
- package/dist/.setup/{channel-type-DRCrEMss.mjs → channel-type-D1_b5UhU.mjs} +12 -16
- package/dist/.setup/{channel-DxlUVU9t.mjs → channel-z5lQMS_9.mjs} +79 -75
- package/dist/.setup/{channel.setup-CRo1GjV7.mjs → channel.setup-DBJtugJO.mjs} +14 -34
- package/dist/.setup/{components-Cq1PvIpN.mjs → components-CzXLR3QH.mjs} +56 -72
- package/dist/.setup/{config-schema-oxELUSDx.mjs → config-schema-CsemBDpS.mjs} +6 -17
- package/dist/.setup/{conversation-binding-route-Caz_XuFH.mjs → conversation-binding-route-Bi62ApSt.mjs} +1 -1
- package/dist/.setup/{directory-config-esqNn0Eo.mjs → directory-config-BH1LA-gi.mjs} +1 -1
- package/dist/.setup/{directory-live-DtKRHuGV.mjs → directory-live-C9xz7IPm.mjs} +10 -13
- package/dist/.setup/{discord-0xJYfdDD.mjs → discord-J7aRzq2Q.mjs} +101 -381
- package/dist/.setup/{doctor-BCl1H5tl.mjs → doctor-DxSAngJq.mjs} +31 -70
- package/dist/.setup/doctor-contract-Bg3NPAMw.mjs +137 -0
- package/dist/.setup/{handle-action-CUvQWnE7.mjs → handle-action-DlmFX-_G.mjs} +10 -11
- package/dist/.setup/{handle-action.guild-admin-Df-8gVle.mjs → handle-action.guild-admin-BnyqTczR.mjs} +67 -129
- package/dist/.setup/{live-policy-config-8Pv20CHc.mjs → live-policy-config-emmPNyh4.mjs} +1 -1
- package/dist/.setup/{message-handler-B-Jk4oDk.mjs → message-handler-BNToPZrx.mjs} +7 -6
- package/dist/.setup/{message-handler.preflight-v-__NSDq.mjs → message-handler.preflight-D0BcCyI7.mjs} +13 -23
- package/dist/.setup/{message-handler.preflight-pluralkit-CWLUBVcx.mjs → message-handler.preflight-pluralkit-D1g3eq0B.mjs} +5 -8
- package/dist/.setup/{message-handler.process-BNFFuChn.mjs → message-handler.process-CThRmCWK.mjs} +57 -96
- package/dist/.setup/{outbound-adapter-BobT-kse.mjs → outbound-adapter-BPq0c2wY.mjs} +11 -17
- package/dist/.setup/{outbound-session-route-zVGxxceg.mjs → outbound-session-route-DGPPKA0z.mjs} +21 -46
- package/dist/.setup/{presence-cache-Di3H3DIU.mjs → presence-cache-Dg3_dADn.mjs} +2 -4
- package/dist/.setup/{probe-LYrIHlBF.mjs → probe-DIRY8vh7.mjs} +17 -27
- package/dist/.setup/{provider-B_G5hASF.mjs → provider-D2OKMo0f.mjs} +273 -446
- package/dist/.setup/{provider-session.runtime-BYlTBFD2.mjs → provider-session.runtime-BupCTZQv.mjs} +3 -3
- package/dist/.setup/provider.runtime-BaW_JnfU.mjs +2 -0
- package/dist/.setup/{realtime-session.runtime-oUd9DOcz.mjs → realtime-session.runtime-D5RSC8Mm.mjs} +6 -8
- package/dist/.setup/{receive-recovery-CHPOsnLc.mjs → receive-recovery-GqF2PUN_.mjs} +1 -4
- package/dist/.setup/{resolve-allowlist-common-DPdRggu5.mjs → resolve-allowlist-common-DUYRrrVB.mjs} +5 -9
- package/dist/.setup/{resolve-channels-BFPNRmVv.mjs → resolve-channels--MUatisx.mjs} +3 -3
- package/dist/.setup/{resolve-users-0-aBuCy3.mjs → resolve-users-CxLcDmM0.mjs} +6 -9
- package/dist/.setup/{retry-pz_cSha2.mjs → retry-BKzO25k4.mjs} +27 -51
- package/dist/.setup/{runtime-sUksZ--Q.mjs → runtime-CerRBfaa.mjs} +2 -2
- package/dist/.setup/{runtime-FN000lxA.mjs → runtime-CwUA0RLr.mjs} +228 -255
- package/dist/.setup/{runtime-doctor-migrations-CshUGl36.mjs → runtime-doctor-migrations-BPV-R4G9.mjs} +6 -0
- package/dist/.setup/{security-audit-Cdaegq7C.mjs → security-audit-D42cp5N7.mjs} +21 -48
- package/dist/.setup/{send-CrfEI6Bs.mjs → send-2X7m2Zmw.mjs} +45 -58
- package/dist/.setup/{send.components-DxQAMfES.mjs → send.components-RqvgmCs3.mjs} +44 -90
- package/dist/.setup/{send.outbound-BISKnb-a.mjs → send.outbound-B4QHSEzm.mjs} +60 -98
- package/dist/.setup/{send.shared-DGFkbkQR.mjs → send.shared-BQIUh6Vn.mjs} +13 -20
- package/dist/.setup/{sender-identity-B9X5Vb9R.mjs → sender-identity-CooeYfAn.mjs} +1 -1
- package/dist/.setup/{session-key-normalization-wJgsKPNF.mjs → session-key-normalization-CCHGNSQw.mjs} +3 -9
- package/dist/.setup/setup-plugin-api-nn_giXvZ.mjs +3 -0
- package/dist/.setup/{shared-B3wZ4hN-.mjs → shared-CIJn6AEC.mjs} +7 -7
- package/dist/.setup/{subagent-hooks-nlUE9ow7.mjs → subagent-hooks-BYlVnxzy.mjs} +4 -9
- package/dist/.setup/{system-events-CdeZnvPV.mjs → system-events-CQ3if_pS.mjs} +2 -2
- package/dist/.setup/{target-resolver-BuLapkhy.mjs → target-resolver-Dzxf80Y3.mjs} +5 -13
- package/dist/.setup/targets-Lf8D55w-.mjs +3 -0
- package/dist/.setup/{thread-bindings-D7TfgjR_.mjs → thread-bindings-yNNlcUWE.mjs} +5 -6
- package/dist/.setup/{thread-bindings.manager-DN-NissX.mjs → thread-bindings.manager-plk0zJAW.mjs} +14 -20
- package/dist/.setup/{thread-bindings.session-updates-CshfKghV.mjs → thread-bindings.session-updates-C9aKtVs6.mjs} +295 -5
- package/dist/.setup/{timeouts-D86uWLt_.mjs → timeouts-pun7VJ02.mjs} +2 -15
- package/dist/.setup/{transcripts-source-p8EV179h.mjs → transcripts-source-CNWswry-.mjs} +31 -79
- package/dist/.setup/typing-CNlSKY5S.mjs +11 -0
- package/dist/.setup/{voice-runtime-B46rcwrG.mjs → voice-runtime-Bc75quiH.mjs} +62 -110
- package/dist/account-inspect-api.js +1 -1
- package/dist/action-runtime-api.js +1 -1
- package/dist/activities-api.js +1 -1
- package/dist/api.js +18 -18
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/control-ui/2afbdab1d3aa65a789d8a3eba666f4b1ec5df07073538fe30d6cf32093a1fb2d/index.js +1 -0
- package/dist/directory-contract-api.js +1 -1
- package/dist/doctor-contract-api.js +19 -128
- package/dist/index.js +1 -1
- package/dist/runtime-api.js +20 -21
- package/dist/security-audit-contract-api.js +1 -1
- package/dist/session-key-api.js +1 -1
- package/dist/setup-entry.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/src/voice/audio-worker.runtime.js +6 -8
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/transcripts-source-api.js +1 -1
- package/node_modules/libopus-wasm/CHANGELOG.md +8 -0
- package/node_modules/libopus-wasm/dist/discordjs.d.ts.map +1 -1
- package/node_modules/libopus-wasm/dist/discordjs.js +14 -2
- package/node_modules/libopus-wasm/dist/generated/libopus.generated.mjs +0 -0
- package/node_modules/libopus-wasm/dist/index.d.ts.map +1 -1
- package/node_modules/libopus-wasm/dist/index.js +55 -100
- package/node_modules/libopus-wasm/package.json +5 -5
- package/node_modules/undici/README.md +10 -1
- package/node_modules/undici/docs/docs/api/Agent.md +8 -8
- package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +9 -6
- package/node_modules/undici/docs/docs/api/Dispatcher.md +9 -0
- package/node_modules/undici/docs/docs/api/Errors.md +25 -0
- package/node_modules/undici/docs/docs/api/Fetch.md +10 -0
- package/node_modules/undici/docs/docs/api/Interceptors.md +4 -3
- package/node_modules/undici/docs/docs/api/Pool.md +5 -6
- package/node_modules/undici/docs/docs/index.md +10 -1
- package/node_modules/undici/lib/api/readable.js +1 -2
- package/node_modules/undici/lib/core/request.js +23 -2
- package/node_modules/undici/lib/core/util.js +0 -39
- package/node_modules/undici/lib/dispatcher/client-h1.js +11 -4
- package/node_modules/undici/lib/dispatcher/client-h2.js +52 -8
- package/node_modules/undici/lib/dispatcher/client.js +6 -1
- package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +21 -6
- package/node_modules/undici/lib/dispatcher/pool-base.js +63 -2
- package/node_modules/undici/lib/dispatcher/pool.js +90 -7
- package/node_modules/undici/lib/dispatcher/proxy-agent.js +16 -3
- package/node_modules/undici/lib/handler/deduplication-handler.js +24 -11
- package/node_modules/undici/lib/handler/redirect-handler.js +5 -0
- package/node_modules/undici/lib/handler/retry-handler.js +72 -13
- package/node_modules/undici/lib/interceptor/cache.js +4 -1
- package/node_modules/undici/lib/interceptor/decompress.js +236 -69
- package/node_modules/undici/lib/web/cache/cache.js +17 -8
- package/node_modules/undici/lib/web/cache/cachestorage.js +11 -5
- package/node_modules/undici/lib/web/cookies/index.js +19 -7
- package/node_modules/undici/lib/web/cookies/util.js +3 -1
- package/node_modules/undici/lib/web/eventsource/eventsource.js +25 -1
- package/node_modules/undici/lib/web/fetch/body.js +22 -15
- package/node_modules/undici/lib/web/fetch/data-url.js +6 -6
- package/node_modules/undici/lib/web/fetch/formdata.js +30 -36
- package/node_modules/undici/lib/web/fetch/headers.js +34 -31
- package/node_modules/undici/lib/web/fetch/index.js +46 -25
- package/node_modules/undici/lib/web/fetch/request.js +74 -79
- package/node_modules/undici/lib/web/fetch/response.js +43 -44
- package/node_modules/undici/lib/web/fetch/util.js +7 -7
- package/node_modules/undici/lib/web/infra/index.js +16 -1
- package/node_modules/undici/lib/web/webidl/index.js +2 -14
- package/node_modules/undici/lib/web/websocket/connection.js +33 -12
- package/node_modules/undici/lib/web/websocket/events.js +43 -26
- package/node_modules/undici/lib/web/websocket/receiver.js +2 -0
- package/node_modules/undici/lib/web/websocket/stream/websocketerror.js +13 -10
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +19 -4
- package/node_modules/undici/lib/web/websocket/websocket.js +44 -41
- package/node_modules/undici/package.json +1 -1
- package/node_modules/undici/types/diagnostics-channel.d.ts +2 -1
- package/node_modules/undici/types/interceptors.d.ts +1 -1
- package/node_modules/undici/types/webidl.d.ts +13 -7
- package/openclaw.plugin.json +6 -0
- package/package.json +12 -7
- package/dist/.setup/doctor-contract-CvvgwrrG.mjs +0 -409
- package/dist/.setup/model-picker-preference-primitives-BHT1LkR_.mjs +0 -37
- package/dist/.setup/provider.runtime-CUE3UxER.mjs +0 -2
- package/dist/.setup/setup-plugin-api-BQUBxbhe.mjs +0 -3
- package/dist/.setup/targets-0KUcEIYx.mjs +0 -3
- package/dist/.setup/thread-bindings.state-g6v9zAym.mjs +0 -331
- package/dist/.setup/typing-BiHCzBRu.mjs +0 -15
|
@@ -1,8 +1,299 @@
|
|
|
1
1
|
import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
+
import { resolveNonNegativeIntegerOption, resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
|
|
4
|
+
import { resolveGlobalSingleton } from "openclaw/plugin-sdk/global-singleton";
|
|
5
|
+
import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
|
|
4
6
|
import { createPluginStateErrorReporter } from "openclaw/plugin-sdk/plugin-state-runtime";
|
|
5
7
|
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
8
|
+
import { recordOutboundMessageIdentity } from "openclaw/plugin-sdk/outbound-echo-runtime";
|
|
9
|
+
import { resolveThreadBindingExpiry } from "openclaw/plugin-sdk/thread-bindings-session-runtime";
|
|
10
|
+
//#region extensions/discord/src/monitor/thread-bindings.state.ts
|
|
11
|
+
const THREAD_BINDINGS_STATE_KEY = Symbol.for("openclaw.discordThreadBindingsState");
|
|
12
|
+
function createThreadBindingsGlobalState() {
|
|
13
|
+
return {
|
|
14
|
+
managersByAccountId: /* @__PURE__ */ new Map(),
|
|
15
|
+
bindingsByThreadId: /* @__PURE__ */ new Map(),
|
|
16
|
+
bindingsBySessionKey: /* @__PURE__ */ new Map(),
|
|
17
|
+
tokensByAccountId: /* @__PURE__ */ new Map(),
|
|
18
|
+
reusableWebhooksByAccountChannel: /* @__PURE__ */ new Map(),
|
|
19
|
+
persistByAccountId: /* @__PURE__ */ new Map(),
|
|
20
|
+
loadedBindings: false,
|
|
21
|
+
loadedPersistentBindings: false,
|
|
22
|
+
persistenceAvailable: true,
|
|
23
|
+
lastPersistedAtMs: 0,
|
|
24
|
+
revision: 0,
|
|
25
|
+
mutationTail: Promise.resolve(),
|
|
26
|
+
accountOperationTails: /* @__PURE__ */ new WeakMap()
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const THREAD_BINDINGS_STATE = resolveGlobalSingleton(THREAD_BINDINGS_STATE_KEY, createThreadBindingsGlobalState);
|
|
30
|
+
THREAD_BINDINGS_STATE.accountOperationTails ??= /* @__PURE__ */ new WeakMap();
|
|
31
|
+
const MANAGERS_BY_ACCOUNT_ID = THREAD_BINDINGS_STATE.managersByAccountId;
|
|
32
|
+
const BINDINGS_BY_THREAD_ID = THREAD_BINDINGS_STATE.bindingsByThreadId;
|
|
33
|
+
const BINDINGS_BY_SESSION_KEY = THREAD_BINDINGS_STATE.bindingsBySessionKey;
|
|
34
|
+
const TOKENS_BY_ACCOUNT_ID = THREAD_BINDINGS_STATE.tokensByAccountId;
|
|
35
|
+
const REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL = THREAD_BINDINGS_STATE.reusableWebhooksByAccountChannel;
|
|
36
|
+
const PERSIST_BY_ACCOUNT_ID = THREAD_BINDINGS_STATE.persistByAccountId;
|
|
37
|
+
const THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS = 15e3;
|
|
38
|
+
const THREAD_BINDINGS_NAMESPACE = "thread-bindings";
|
|
39
|
+
const THREAD_BINDINGS_MAX_ENTRIES = 1e4;
|
|
40
|
+
function rememberThreadBindingToken(params) {
|
|
41
|
+
const normalizedAccountId = normalizeAccountId(params.accountId);
|
|
42
|
+
const token = params.token?.trim();
|
|
43
|
+
if (!token) return;
|
|
44
|
+
TOKENS_BY_ACCOUNT_ID.set(normalizedAccountId, token);
|
|
45
|
+
}
|
|
46
|
+
function forgetThreadBindingToken(accountId) {
|
|
47
|
+
TOKENS_BY_ACCOUNT_ID.delete(normalizeAccountId(accountId));
|
|
48
|
+
}
|
|
49
|
+
function getThreadBindingToken(accountId) {
|
|
50
|
+
return TOKENS_BY_ACCOUNT_ID.get(normalizeAccountId(accountId));
|
|
51
|
+
}
|
|
52
|
+
function shouldDefaultPersist() {
|
|
53
|
+
return !(process.env.VITEST || false);
|
|
54
|
+
}
|
|
55
|
+
function openThreadBindingsStore() {
|
|
56
|
+
return getDiscordRuntime().state.openSyncKeyedStore({
|
|
57
|
+
namespace: THREAD_BINDINGS_NAMESPACE,
|
|
58
|
+
maxEntries: THREAD_BINDINGS_MAX_ENTRIES
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function normalizeTargetKind(raw, targetSessionKey) {
|
|
62
|
+
if (raw === "subagent" || raw === "acp") return raw;
|
|
63
|
+
return targetSessionKey.includes(":subagent:") ? "subagent" : "acp";
|
|
64
|
+
}
|
|
65
|
+
function toBindingRecordKey(params) {
|
|
66
|
+
return `${normalizeAccountId(params.accountId)}:${params.threadId.trim()}`;
|
|
67
|
+
}
|
|
68
|
+
function resolveBindingRecordKey(params) {
|
|
69
|
+
const threadId = normalizeOptionalStringifiedId(params.threadId);
|
|
70
|
+
if (!threadId) return;
|
|
71
|
+
return toBindingRecordKey({
|
|
72
|
+
accountId: normalizeAccountId(params.accountId),
|
|
73
|
+
threadId
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function normalizePersistedBinding(threadIdKey, raw) {
|
|
77
|
+
if (!raw || typeof raw !== "object") return null;
|
|
78
|
+
const value = raw;
|
|
79
|
+
const threadId = normalizeOptionalStringifiedId(value.threadId ?? threadIdKey);
|
|
80
|
+
const channelId = normalizeOptionalString(value.channelId) ?? "";
|
|
81
|
+
const targetSessionKey = normalizeOptionalString(value.targetSessionKey) ?? "";
|
|
82
|
+
if (!threadId || !channelId || !targetSessionKey) return null;
|
|
83
|
+
const accountId = normalizeAccountId(value.accountId);
|
|
84
|
+
const targetKind = normalizeTargetKind(value.targetKind, targetSessionKey);
|
|
85
|
+
const agentId = (normalizeOptionalString(value.agentId) ?? "") || resolveAgentIdFromSessionKey(targetSessionKey);
|
|
86
|
+
const label = normalizeOptionalString(value.label);
|
|
87
|
+
const webhookId = normalizeOptionalString(value.webhookId);
|
|
88
|
+
const webhookToken = normalizeOptionalString(value.webhookToken);
|
|
89
|
+
const boundBy = normalizeOptionalString(value.boundBy) ?? "system";
|
|
90
|
+
const boundAt = resolveOptionalIntegerOption(value.boundAt) ?? Date.now();
|
|
91
|
+
const lastActivityAt = resolveOptionalIntegerOption(value.lastActivityAt, { min: 0 }) ?? boundAt;
|
|
92
|
+
const idleTimeoutMs = resolveOptionalIntegerOption(value.idleTimeoutMs, { min: 0 });
|
|
93
|
+
const maxAgeMs = resolveOptionalIntegerOption(value.maxAgeMs, { min: 0 });
|
|
94
|
+
const metadata = value.metadata && typeof value.metadata === "object" ? { ...value.metadata } : void 0;
|
|
95
|
+
const record = {
|
|
96
|
+
accountId,
|
|
97
|
+
channelId,
|
|
98
|
+
threadId,
|
|
99
|
+
targetKind,
|
|
100
|
+
targetSessionKey,
|
|
101
|
+
agentId,
|
|
102
|
+
boundBy,
|
|
103
|
+
boundAt,
|
|
104
|
+
lastActivityAt
|
|
105
|
+
};
|
|
106
|
+
if (label !== void 0) record.label = label;
|
|
107
|
+
if (webhookId !== void 0) record.webhookId = webhookId;
|
|
108
|
+
if (webhookToken !== void 0) record.webhookToken = webhookToken;
|
|
109
|
+
if (idleTimeoutMs !== void 0) record.idleTimeoutMs = idleTimeoutMs;
|
|
110
|
+
if (maxAgeMs !== void 0) record.maxAgeMs = maxAgeMs;
|
|
111
|
+
if (metadata !== void 0) record.metadata = metadata;
|
|
112
|
+
return record;
|
|
113
|
+
}
|
|
114
|
+
function normalizeThreadBindingDurationMs(raw, defaultsTo) {
|
|
115
|
+
const durationMs = resolveOptionalIntegerOption(raw);
|
|
116
|
+
return durationMs !== void 0 && durationMs >= 0 ? durationMs : defaultsTo;
|
|
117
|
+
}
|
|
118
|
+
function resolveThreadBindingIdleTimeoutMs(params) {
|
|
119
|
+
return resolveNonNegativeIntegerOption(params.record.idleTimeoutMs, params.defaultIdleTimeoutMs);
|
|
120
|
+
}
|
|
121
|
+
function resolveThreadBindingMaxAgeMs(params) {
|
|
122
|
+
return resolveNonNegativeIntegerOption(params.record.maxAgeMs, params.defaultMaxAgeMs);
|
|
123
|
+
}
|
|
124
|
+
function resolveTimestampExpiry(timestamp, durationMs) {
|
|
125
|
+
if (durationMs <= 0) return;
|
|
126
|
+
const at = Math.floor(timestamp);
|
|
127
|
+
return Number.isFinite(at) && at > 0 ? at + durationMs : void 0;
|
|
128
|
+
}
|
|
129
|
+
function resolvePreparedThreadBindingLifecycle(params) {
|
|
130
|
+
const idleTimeoutMs = resolveThreadBindingIdleTimeoutMs({
|
|
131
|
+
record: params.record,
|
|
132
|
+
defaultIdleTimeoutMs: params.idleTimeoutMs
|
|
133
|
+
});
|
|
134
|
+
const maxAgeMs = resolveThreadBindingMaxAgeMs({
|
|
135
|
+
record: params.record,
|
|
136
|
+
defaultMaxAgeMs: params.maxAgeMs
|
|
137
|
+
});
|
|
138
|
+
return {
|
|
139
|
+
idleTimeoutMs,
|
|
140
|
+
maxAgeMs,
|
|
141
|
+
...resolveThreadBindingExpiry({
|
|
142
|
+
inactivityExpiresAt: resolveTimestampExpiry(params.record.lastActivityAt, idleTimeoutMs),
|
|
143
|
+
maxAgeExpiresAt: resolveTimestampExpiry(params.record.boundAt, maxAgeMs)
|
|
144
|
+
})
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function resolveThreadBindingInactivityExpiresAt(params) {
|
|
148
|
+
const idleTimeoutMs = resolveThreadBindingIdleTimeoutMs({
|
|
149
|
+
record: params.record,
|
|
150
|
+
defaultIdleTimeoutMs: params.defaultIdleTimeoutMs
|
|
151
|
+
});
|
|
152
|
+
return resolveTimestampExpiry(params.record.lastActivityAt, idleTimeoutMs);
|
|
153
|
+
}
|
|
154
|
+
function resolveThreadBindingMaxAgeExpiresAt(params) {
|
|
155
|
+
const maxAgeMs = resolveThreadBindingMaxAgeMs({
|
|
156
|
+
record: params.record,
|
|
157
|
+
defaultMaxAgeMs: params.defaultMaxAgeMs
|
|
158
|
+
});
|
|
159
|
+
return resolveTimestampExpiry(params.record.boundAt, maxAgeMs);
|
|
160
|
+
}
|
|
161
|
+
function linkSessionBinding(targetSessionKey, bindingKey) {
|
|
162
|
+
const key = targetSessionKey.trim();
|
|
163
|
+
if (!key) return;
|
|
164
|
+
const threads = BINDINGS_BY_SESSION_KEY.get(key) ?? /* @__PURE__ */ new Set();
|
|
165
|
+
threads.add(bindingKey);
|
|
166
|
+
BINDINGS_BY_SESSION_KEY.set(key, threads);
|
|
167
|
+
}
|
|
168
|
+
function unlinkSessionBinding(targetSessionKey, bindingKey) {
|
|
169
|
+
const key = targetSessionKey.trim();
|
|
170
|
+
if (!key) return;
|
|
171
|
+
const threads = BINDINGS_BY_SESSION_KEY.get(key);
|
|
172
|
+
if (!threads) return;
|
|
173
|
+
threads.delete(bindingKey);
|
|
174
|
+
if (threads.size === 0) BINDINGS_BY_SESSION_KEY.delete(key);
|
|
175
|
+
}
|
|
176
|
+
function toReusableWebhookKey(params) {
|
|
177
|
+
return `${normalizeLowercaseStringOrEmpty(params.accountId)}:${params.channelId.trim()}`;
|
|
178
|
+
}
|
|
179
|
+
function rememberReusableWebhook(record) {
|
|
180
|
+
const webhookId = record.webhookId?.trim();
|
|
181
|
+
const webhookToken = record.webhookToken?.trim();
|
|
182
|
+
if (!webhookId || !webhookToken) return;
|
|
183
|
+
const key = toReusableWebhookKey({
|
|
184
|
+
accountId: record.accountId,
|
|
185
|
+
channelId: record.channelId
|
|
186
|
+
});
|
|
187
|
+
REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL.set(key, {
|
|
188
|
+
webhookId,
|
|
189
|
+
webhookToken
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function refreshUnboundThreadWebhookIdentity(record) {
|
|
193
|
+
const sourceId = record.webhookId?.trim();
|
|
194
|
+
if (!sourceId) return;
|
|
195
|
+
recordOutboundMessageIdentity({
|
|
196
|
+
channel: "discord",
|
|
197
|
+
accountId: record.accountId,
|
|
198
|
+
conversationId: record.threadId,
|
|
199
|
+
sourceId
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
function setBindingRecord(record) {
|
|
203
|
+
const bindingKey = toBindingRecordKey({
|
|
204
|
+
accountId: record.accountId,
|
|
205
|
+
threadId: record.threadId
|
|
206
|
+
});
|
|
207
|
+
const existing = BINDINGS_BY_THREAD_ID.get(bindingKey);
|
|
208
|
+
if (existing) unlinkSessionBinding(existing.targetSessionKey, bindingKey);
|
|
209
|
+
BINDINGS_BY_THREAD_ID.set(bindingKey, record);
|
|
210
|
+
THREAD_BINDINGS_STATE.revision += 1;
|
|
211
|
+
linkSessionBinding(record.targetSessionKey, bindingKey);
|
|
212
|
+
rememberReusableWebhook(record);
|
|
213
|
+
}
|
|
214
|
+
function removeBindingRecord(bindingKeyRaw) {
|
|
215
|
+
const key = bindingKeyRaw.trim();
|
|
216
|
+
if (!key) return null;
|
|
217
|
+
const existing = BINDINGS_BY_THREAD_ID.get(key);
|
|
218
|
+
if (!existing) return null;
|
|
219
|
+
BINDINGS_BY_THREAD_ID.delete(key);
|
|
220
|
+
THREAD_BINDINGS_STATE.revision += 1;
|
|
221
|
+
unlinkSessionBinding(existing.targetSessionKey, key);
|
|
222
|
+
return existing;
|
|
223
|
+
}
|
|
224
|
+
function beginBindingsLoad() {
|
|
225
|
+
THREAD_BINDINGS_STATE.loadedBindings = true;
|
|
226
|
+
BINDINGS_BY_THREAD_ID.clear();
|
|
227
|
+
THREAD_BINDINGS_STATE.revision += 1;
|
|
228
|
+
BINDINGS_BY_SESSION_KEY.clear();
|
|
229
|
+
REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL.clear();
|
|
230
|
+
THREAD_BINDINGS_STATE.loadedPersistentBindings = false;
|
|
231
|
+
}
|
|
232
|
+
function restoreBindings(entries) {
|
|
233
|
+
THREAD_BINDINGS_STATE.persistenceAvailable = true;
|
|
234
|
+
THREAD_BINDINGS_STATE.loadedPersistentBindings = entries.length > 0;
|
|
235
|
+
for (const entry of entries) {
|
|
236
|
+
const normalized = normalizePersistedBinding(entry.key, entry.value);
|
|
237
|
+
if (!normalized) continue;
|
|
238
|
+
setBindingRecord(normalized);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function ensureBindingsLoaded() {
|
|
242
|
+
if (THREAD_BINDINGS_STATE.loadedBindings) return;
|
|
243
|
+
beginBindingsLoad();
|
|
244
|
+
let entries;
|
|
245
|
+
try {
|
|
246
|
+
entries = openThreadBindingsStore().entries();
|
|
247
|
+
} catch {
|
|
248
|
+
THREAD_BINDINGS_STATE.persistenceAvailable = false;
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
restoreBindings(entries);
|
|
252
|
+
}
|
|
253
|
+
async function loadBindingsAsync() {
|
|
254
|
+
let entries;
|
|
255
|
+
try {
|
|
256
|
+
entries = await getDiscordRuntime().state.openKeyedStore({
|
|
257
|
+
namespace: THREAD_BINDINGS_NAMESPACE,
|
|
258
|
+
maxEntries: THREAD_BINDINGS_MAX_ENTRIES
|
|
259
|
+
}).entries();
|
|
260
|
+
} catch {
|
|
261
|
+
if (!THREAD_BINDINGS_STATE.loadedBindings) {
|
|
262
|
+
beginBindingsLoad();
|
|
263
|
+
THREAD_BINDINGS_STATE.persistenceAvailable = false;
|
|
264
|
+
logVerbose("discord thread binding persistence unavailable; keeping bindings in memory");
|
|
265
|
+
}
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (THREAD_BINDINGS_STATE.loadedBindings) return;
|
|
269
|
+
beginBindingsLoad();
|
|
270
|
+
restoreBindings(entries);
|
|
271
|
+
}
|
|
272
|
+
async function ensureBindingsLoadedAsync() {
|
|
273
|
+
if (THREAD_BINDINGS_STATE.loadedBindings) return;
|
|
274
|
+
const loading = THREAD_BINDINGS_STATE.loadingBindings ??= loadBindingsAsync();
|
|
275
|
+
try {
|
|
276
|
+
await loading;
|
|
277
|
+
} finally {
|
|
278
|
+
if (THREAD_BINDINGS_STATE.loadingBindings === loading) delete THREAD_BINDINGS_STATE.loadingBindings;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
function resolveBindingIdsForSession(params) {
|
|
282
|
+
const key = params.targetSessionKey.trim();
|
|
283
|
+
if (!key) return [];
|
|
284
|
+
const ids = BINDINGS_BY_SESSION_KEY.get(key);
|
|
285
|
+
if (!ids) return [];
|
|
286
|
+
const out = [];
|
|
287
|
+
for (const bindingKey of ids.values()) {
|
|
288
|
+
const record = BINDINGS_BY_THREAD_ID.get(bindingKey);
|
|
289
|
+
if (!record) continue;
|
|
290
|
+
if (params.accountId && record.accountId !== params.accountId) continue;
|
|
291
|
+
if (params.targetKind && record.targetKind !== params.targetKind) continue;
|
|
292
|
+
out.push(bindingKey);
|
|
293
|
+
}
|
|
294
|
+
return out;
|
|
295
|
+
}
|
|
296
|
+
//#endregion
|
|
6
297
|
//#region extensions/discord/src/monitor/thread-bindings.persistence.ts
|
|
7
298
|
function shouldPersistAnyBindingState() {
|
|
8
299
|
for (const value of PERSIST_BY_ACCOUNT_ID.values()) if (value) return true;
|
|
@@ -247,10 +538,9 @@ function resolveBindingIdsForTargetSession(params) {
|
|
|
247
538
|
ensureBindingsLoaded();
|
|
248
539
|
const targetSessionKey = params.targetSessionKey.trim();
|
|
249
540
|
if (!targetSessionKey) return [];
|
|
250
|
-
const accountId = params.accountId ? normalizeAccountId(params.accountId) : void 0;
|
|
251
541
|
return resolveBindingIdsForSession({
|
|
252
542
|
targetSessionKey,
|
|
253
|
-
accountId,
|
|
543
|
+
accountId: params.accountId ? normalizeAccountId(params.accountId) : void 0,
|
|
254
544
|
targetKind: params.targetKind
|
|
255
545
|
});
|
|
256
546
|
}
|
|
@@ -356,4 +646,4 @@ function setThreadBindingMaxAgeBySessionKey(params) {
|
|
|
356
646
|
}));
|
|
357
647
|
}
|
|
358
648
|
//#endregion
|
|
359
|
-
export { mutateBindingsForTargetSession as a, drainThreadBindingAccountOperations as c, runThreadBindingAccountOperation as d, runThreadBindingMutation as f, updateBindingRecordSync as h, setThreadBindingMaxAgeBySessionKeyAsync as i, drainThreadBindingMutations as l, snapshotThreadBindingJson as m, setThreadBindingIdleTimeoutBySessionKeyAsync as n, resolveBindingIdsForTargetSession as o, shouldPersistAnyBindingState as p, setThreadBindingMaxAgeBySessionKey as r, commitBindingRecord as s, setThreadBindingIdleTimeoutBySessionKey as t, removeBindingRecordSync as u };
|
|
649
|
+
export { resolveBindingRecordKey as A, getThreadBindingToken as C, rememberReusableWebhook as D, refreshUnboundThreadWebhookIdentity as E, resolveThreadBindingMaxAgeMs as F, shouldDefaultPersist as I, toBindingRecordKey as L, resolveThreadBindingIdleTimeoutMs as M, resolveThreadBindingInactivityExpiresAt as N, rememberThreadBindingToken as O, resolveThreadBindingMaxAgeExpiresAt as P, toReusableWebhookKey as R, forgetThreadBindingToken as S, normalizeThreadBindingDurationMs as T, MANAGERS_BY_ACCOUNT_ID as _, mutateBindingsForTargetSession as a, THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS as b, drainThreadBindingAccountOperations as c, runThreadBindingAccountOperation as d, runThreadBindingMutation as f, BINDINGS_BY_THREAD_ID as g, updateBindingRecordSync as h, setThreadBindingMaxAgeBySessionKeyAsync as i, resolvePreparedThreadBindingLifecycle as j, resolveBindingIdsForSession as k, drainThreadBindingMutations as l, snapshotThreadBindingJson as m, setThreadBindingIdleTimeoutBySessionKeyAsync as n, resolveBindingIdsForTargetSession as o, shouldPersistAnyBindingState as p, setThreadBindingMaxAgeBySessionKey as r, commitBindingRecord as s, setThreadBindingIdleTimeoutBySessionKey as t, removeBindingRecordSync as u, PERSIST_BY_ACCOUNT_ID as v, normalizeTargetKind as w, ensureBindingsLoadedAsync as x, REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL as y };
|
|
@@ -56,27 +56,14 @@ async function runDiscordTaskWithTimeout(params) {
|
|
|
56
56
|
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
async function raceWithTimeout(params) {
|
|
60
|
-
const timeoutMs = resolveTimerTimeoutMs(params.timeoutMs, 1);
|
|
61
|
-
let timeoutTimer;
|
|
62
|
-
const timeoutPromise = new Promise((resolve) => {
|
|
63
|
-
timeoutTimer = setTimeout(() => resolve(params.onTimeout()), timeoutMs);
|
|
64
|
-
timeoutTimer.unref?.();
|
|
65
|
-
});
|
|
66
|
-
try {
|
|
67
|
-
return await Promise.race([params.promise, timeoutPromise]);
|
|
68
|
-
} finally {
|
|
69
|
-
if (timeoutTimer) clearTimeout(timeoutTimer);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
59
|
async function withAbortTimeout(params) {
|
|
73
60
|
const timeoutMs = resolveTimerTimeoutMs(params.timeoutMs, 1);
|
|
74
61
|
const controller = new AbortController();
|
|
75
62
|
let timeoutTimer;
|
|
76
63
|
const timeoutPromise = new Promise((_, reject) => {
|
|
77
64
|
timeoutTimer = setTimeout(() => {
|
|
78
|
-
controller.abort();
|
|
79
65
|
reject(params.createTimeoutError());
|
|
66
|
+
controller.abort();
|
|
80
67
|
}, timeoutMs);
|
|
81
68
|
timeoutTimer.unref?.();
|
|
82
69
|
});
|
|
@@ -87,4 +74,4 @@ async function withAbortTimeout(params) {
|
|
|
87
74
|
}
|
|
88
75
|
}
|
|
89
76
|
//#endregion
|
|
90
|
-
export { isAbortError as a,
|
|
77
|
+
export { isAbortError as a, runDiscordTaskWithTimeout as c, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS as i, withAbortTimeout as l, DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS as n, normalizeDiscordInboundWorkerTimeoutMs as o, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS as r, normalizeDiscordListenerTimeoutMs as s, DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS as t };
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
|
|
2
|
-
import { _ as DiscordError,
|
|
3
|
-
import {
|
|
4
|
-
import { a as listEnabledDiscordAccounts, c as resolveDiscordAccount, l as resolveDiscordAccountAllowFrom } from "./accounts-
|
|
2
|
+
import { _ as DiscordError, ct as createThread, ft as getChannelMessage, t as discord_exports } from "./discord-J7aRzq2Q.mjs";
|
|
3
|
+
import { A as resolveDiscordEndpointMediaGuard, O as getDiscordEndpointRuntime, a as normalizeDiscordAllowList, i as isDiscordGroupAllowedByPolicy, m as resolveDiscordMemberAccessState, n as allowListMatches, p as resolveDiscordGuildEntry, r as hasConfiguredDiscordChannels, s as normalizeDiscordSlug, t as isDiscordThreadChannelType, u as resolveDiscordChannelConfigWithFallback } from "./channel-type-D1_b5UhU.mjs";
|
|
4
|
+
import { a as listEnabledDiscordAccounts, c as resolveDiscordAccount, l as resolveDiscordAccountAllowFrom } from "./accounts-DXHCL8Zm.mjs";
|
|
5
5
|
import { t as resolveDiscordCommandOwnerAllowFrom } from "./command-owners-D78sAoOz.mjs";
|
|
6
|
-
import { a as resolveDiscordChannelParentSafe, i as resolveDiscordChannelParentIdSafe, n as resolveDiscordChannelInfoSafe, r as resolveDiscordChannelNameSafe, t as resolveDiscordChannelIdSafe } from "./channel-access-
|
|
7
|
-
import {
|
|
6
|
+
import { a as resolveDiscordChannelParentSafe, i as resolveDiscordChannelParentIdSafe, n as resolveDiscordChannelInfoSafe, r as resolveDiscordChannelNameSafe, t as resolveDiscordChannelIdSafe } from "./channel-access-BRp3Y-rF.mjs";
|
|
7
|
+
import { l as withAbortTimeout } from "./timeouts-pun7VJ02.mjs";
|
|
8
|
+
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId, summarizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
9
|
+
import { ComponentType, Routes, StickerFormatType } from "discord-api-types/v10";
|
|
8
10
|
import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
9
11
|
import { formatErrorMessage } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
10
12
|
import { resolveGlobalSingleton } from "openclaw/plugin-sdk/global-singleton";
|
|
11
13
|
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
12
14
|
import { buildAgentSessionKey } from "openclaw/plugin-sdk/routing";
|
|
13
|
-
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId, summarizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
14
15
|
import { getFileExtension, normalizeMimeType } from "openclaw/plugin-sdk/media-mime";
|
|
15
16
|
import { createSubsystemLogger, getChildLogger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
16
17
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
@@ -95,14 +96,13 @@ async function generateThreadTitle(params) {
|
|
|
95
96
|
channelName: params.channelName,
|
|
96
97
|
channelDescription: params.channelDescription
|
|
97
98
|
});
|
|
98
|
-
const timeoutMs = resolveThreadTitleTimeoutMs(params.timeoutMs);
|
|
99
99
|
const generated = await generateConversationLabel({
|
|
100
100
|
cfg: params.cfg,
|
|
101
101
|
agentId: params.agentId,
|
|
102
102
|
userMessage,
|
|
103
103
|
prompt: DISCORD_THREAD_TITLE_SYSTEM_PROMPT,
|
|
104
104
|
...params.modelRef ? { modelRef: params.modelRef } : {},
|
|
105
|
-
timeoutMs,
|
|
105
|
+
timeoutMs: Math.max(100, Math.floor(params.timeoutMs ?? DEFAULT_THREAD_TITLE_TIMEOUT_MS)),
|
|
106
106
|
maxLength: MAX_THREAD_TITLE_SOURCE_CHARS
|
|
107
107
|
});
|
|
108
108
|
return generated ? normalizeGeneratedThreadTitle(generated) : null;
|
|
@@ -125,20 +125,8 @@ function truncateThreadTitleSourceText(sourceText) {
|
|
|
125
125
|
if (sourceText.length <= MAX_THREAD_TITLE_SOURCE_CHARS) return sourceText;
|
|
126
126
|
return `${truncateUtf16Safe(sourceText, MAX_THREAD_TITLE_SOURCE_CHARS)}...`;
|
|
127
127
|
}
|
|
128
|
-
function resolveThreadTitleTimeoutMs(timeoutMs) {
|
|
129
|
-
return Math.max(100, Math.floor(timeoutMs ?? DEFAULT_THREAD_TITLE_TIMEOUT_MS));
|
|
130
|
-
}
|
|
131
128
|
function normalizeGeneratedThreadTitle(raw) {
|
|
132
|
-
|
|
133
|
-
let firstLine = "";
|
|
134
|
-
for (const line of lines) {
|
|
135
|
-
const trimmed = line.trim();
|
|
136
|
-
if (!trimmed) continue;
|
|
137
|
-
if (!firstLine && trimmed.startsWith("```")) continue;
|
|
138
|
-
firstLine = trimmed;
|
|
139
|
-
break;
|
|
140
|
-
}
|
|
141
|
-
return stripThreadTitleWrappers(firstLine);
|
|
129
|
+
return stripThreadTitleWrappers(raw.replace(/\r/g, "").split("\n").find((line) => line.trim() && !line.trim().startsWith("```")) ?? "");
|
|
142
130
|
}
|
|
143
131
|
function stripThreadTitleWrappers(raw) {
|
|
144
132
|
let current = raw.trim();
|
|
@@ -155,11 +143,9 @@ function stripThreadTitleWrappers(raw) {
|
|
|
155
143
|
return current;
|
|
156
144
|
}
|
|
157
145
|
function stripBalancedWrapper(text, marker) {
|
|
158
|
-
if (text.length < marker.length * 2 + 1) return text;
|
|
159
|
-
if (!text.startsWith(marker) || !text.endsWith(marker)) return text;
|
|
146
|
+
if (text.length < marker.length * 2 + 1 || !text.startsWith(marker) || !text.endsWith(marker)) return text;
|
|
160
147
|
const inner = text.slice(marker.length, text.length - marker.length);
|
|
161
|
-
|
|
162
|
-
return inner;
|
|
148
|
+
return inner.includes(marker) ? text : inner;
|
|
163
149
|
}
|
|
164
150
|
function normalizeTitleContextField(raw, maxChars) {
|
|
165
151
|
const value = raw?.trim();
|
|
@@ -351,41 +337,22 @@ async function resolveReferencedReplyMediaList(message, maxBytes, options) {
|
|
|
351
337
|
const referencedReply = resolveDiscordReferencedReplyMessage(message);
|
|
352
338
|
return referencedReply ? resolveMessageMedia(referencedReply, createDiscordMediaOperation(maxBytes, options), "discord: failed to download referenced reply") : [];
|
|
353
339
|
}
|
|
354
|
-
async function fetchDiscordMedia(params) {
|
|
355
|
-
const endpointGuard = resolveDiscordEndpointMediaGuard(params.url,
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
url: params.url,
|
|
362
|
-
filePathHint: params.filePathHint,
|
|
363
|
-
maxBytes: params.maxBytes,
|
|
364
|
-
fetchImpl: endpointGuard ? void 0 : params.fetchImpl,
|
|
365
|
-
ssrfPolicy: endpointGuard?.ssrfPolicy ?? params.ssrfPolicy,
|
|
340
|
+
async function fetchDiscordMedia(operation, params) {
|
|
341
|
+
const endpointGuard = resolveDiscordEndpointMediaGuard(params.url, operation.endpointRuntime);
|
|
342
|
+
const save = (signal) => saveRemoteMedia({
|
|
343
|
+
...params,
|
|
344
|
+
maxBytes: operation.maxBytes,
|
|
345
|
+
fetchImpl: endpointGuard ? void 0 : operation.fetchImpl,
|
|
346
|
+
ssrfPolicy: endpointGuard?.ssrfPolicy ?? operation.ssrfPolicy,
|
|
366
347
|
...endpointGuard ? { maxRedirects: endpointGuard.maxRedirects } : {},
|
|
367
|
-
readIdleTimeoutMs:
|
|
368
|
-
fallbackContentType: params.fallbackContentType,
|
|
369
|
-
originalFilename: params.originalFilename,
|
|
348
|
+
readIdleTimeoutMs: operation.readIdleTimeoutMs,
|
|
370
349
|
...signal ? { requestInit: { signal } } : {}
|
|
371
|
-
}).catch((error) => {
|
|
372
|
-
if (timedOut) return new Promise(() => {});
|
|
373
|
-
throw error;
|
|
374
350
|
});
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
timeoutAbortController?.abort();
|
|
381
|
-
reject(/* @__PURE__ */ new Error(`discord media download timed out after ${params.totalTimeoutMs}ms`));
|
|
382
|
-
}, params.totalTimeoutMs);
|
|
383
|
-
timeoutHandle.unref?.();
|
|
384
|
-
});
|
|
385
|
-
return await Promise.race([savePromise, timeoutPromise]);
|
|
386
|
-
} finally {
|
|
387
|
-
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
388
|
-
}
|
|
351
|
+
return operation.totalTimeoutMs ? withAbortTimeout({
|
|
352
|
+
timeoutMs: operation.totalTimeoutMs,
|
|
353
|
+
createTimeoutError: () => /* @__PURE__ */ new Error(`discord media download timed out after ${operation.totalTimeoutMs}ms`),
|
|
354
|
+
run: (signal) => save(operation.abortSignal ? AbortSignal.any([operation.abortSignal, signal]) : signal)
|
|
355
|
+
}) : save(operation.abortSignal);
|
|
389
356
|
}
|
|
390
357
|
async function appendResolvedMediaFromAttachments(params) {
|
|
391
358
|
const attachments = params.attachments;
|
|
@@ -398,16 +365,9 @@ async function appendResolvedMediaFromAttachments(params) {
|
|
|
398
365
|
continue;
|
|
399
366
|
}
|
|
400
367
|
try {
|
|
401
|
-
const saved = await fetchDiscordMedia({
|
|
368
|
+
const saved = await fetchDiscordMedia(params, {
|
|
402
369
|
url: attachmentUrl,
|
|
403
370
|
filePathHint: attachment.filename ?? attachmentUrl,
|
|
404
|
-
maxBytes: params.maxBytes,
|
|
405
|
-
fetchImpl: params.fetchImpl,
|
|
406
|
-
ssrfPolicy: params.ssrfPolicy,
|
|
407
|
-
readIdleTimeoutMs: params.readIdleTimeoutMs,
|
|
408
|
-
totalTimeoutMs: params.totalTimeoutMs,
|
|
409
|
-
abortSignal: params.abortSignal,
|
|
410
|
-
endpointRuntime: params.endpointRuntime,
|
|
411
371
|
fallbackContentType: attachment.content_type,
|
|
412
372
|
originalFilename: attachment.filename
|
|
413
373
|
});
|
|
@@ -423,8 +383,7 @@ async function appendResolvedMediaFromAttachments(params) {
|
|
|
423
383
|
} catch (err) {
|
|
424
384
|
const id = attachment.id ?? attachmentUrl;
|
|
425
385
|
getChildLogger({ module: "discord-media" }).warn(`${params.errorPrefix} ${id}: ${String(err)}`);
|
|
426
|
-
|
|
427
|
-
params.out.push({ ...classification });
|
|
386
|
+
params.out.push(resolveDiscordMediaClassification({ attachment }));
|
|
428
387
|
}
|
|
429
388
|
}
|
|
430
389
|
}
|
|
@@ -473,16 +432,9 @@ async function appendResolvedMediaFromStickers(params) {
|
|
|
473
432
|
const candidates = resolveStickerAssetCandidates(sticker);
|
|
474
433
|
let lastError;
|
|
475
434
|
for (const candidate of candidates) try {
|
|
476
|
-
const saved = await fetchDiscordMedia({
|
|
435
|
+
const saved = await fetchDiscordMedia(params, {
|
|
477
436
|
url: candidate.url,
|
|
478
437
|
filePathHint: candidate.fileName,
|
|
479
|
-
maxBytes: params.maxBytes,
|
|
480
|
-
fetchImpl: params.fetchImpl,
|
|
481
|
-
ssrfPolicy: params.ssrfPolicy,
|
|
482
|
-
readIdleTimeoutMs: params.readIdleTimeoutMs,
|
|
483
|
-
totalTimeoutMs: params.totalTimeoutMs,
|
|
484
|
-
abortSignal: params.abortSignal,
|
|
485
|
-
endpointRuntime: params.endpointRuntime,
|
|
486
438
|
fallbackContentType: inferStickerContentType(sticker),
|
|
487
439
|
originalFilename: candidate.fileName
|
|
488
440
|
});
|
|
@@ -499,7 +451,7 @@ async function appendResolvedMediaFromStickers(params) {
|
|
|
499
451
|
}
|
|
500
452
|
if (lastError) {
|
|
501
453
|
getChildLogger({ module: "discord-media" }).warn(`${params.errorPrefix} ${sticker.id}: ${formatStickerError(lastError)}`);
|
|
502
|
-
|
|
454
|
+
params.out.push({
|
|
503
455
|
contentType: inferStickerContentType(sticker),
|
|
504
456
|
kind: "sticker"
|
|
505
457
|
});
|
|
@@ -768,7 +720,7 @@ function resolveDiscordReplyTarget(opts) {
|
|
|
768
720
|
}
|
|
769
721
|
function sanitizeDiscordThreadName(rawName, fallbackId) {
|
|
770
722
|
const baseSource = rawName.replace(/<@!?\d+>/g, "").replace(/<@&\d+>/g, "").replace(/<#\d+>/g, "").replace(/\s+/g, " ").trim() || `Thread ${fallbackId}`;
|
|
771
|
-
return truncateUtf16Safe(baseSource, 80)
|
|
723
|
+
return truncateUtf16Safe(baseSource, 80);
|
|
772
724
|
}
|
|
773
725
|
function resolveDiscordReplyDeliveryPlan(params) {
|
|
774
726
|
const deliverTarget = params.createdThreadId ? `channel:${params.createdThreadId}` : params.replyTarget;
|
|
@@ -936,7 +888,7 @@ async function maybeRenameDiscordAutoThread(params) {
|
|
|
936
888
|
if (!generated) return;
|
|
937
889
|
const nextName = sanitizeDiscordThreadName(generated, params.fallbackId);
|
|
938
890
|
if (!nextName || nextName === params.currentName || nextName === fallbackName) return;
|
|
939
|
-
await
|
|
891
|
+
await params.client.rest.patch(Routes.channel(params.threadId), { body: { name: nextName } });
|
|
940
892
|
} catch (err) {
|
|
941
893
|
logVerbose(`discord: autoThread rename failed for ${params.threadId}: ${String(err)}`);
|
|
942
894
|
}
|
|
@@ -1088,7 +1040,7 @@ async function authorizeDiscordVoiceIngress(initialParams) {
|
|
|
1088
1040
|
ok: false,
|
|
1089
1041
|
message: "This channel is disabled."
|
|
1090
1042
|
};
|
|
1091
|
-
const channelAllowlistConfigured =
|
|
1043
|
+
const channelAllowlistConfigured = hasConfiguredDiscordChannels(guildInfo?.channels);
|
|
1092
1044
|
if (!params.channelId && groupPolicy === "allowlist" && channelAllowlistConfigured) return {
|
|
1093
1045
|
ok: false,
|
|
1094
1046
|
message: `${params.channelLabel ?? "This channel"} is not allowlisted for voice commands.`
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
|
|
2
|
+
import { Routes } from "discord-api-types/v10";
|
|
3
|
+
import { raceWithTimeout } from "openclaw/plugin-sdk/time-runtime";
|
|
4
|
+
//#region extensions/discord/src/monitor/typing.ts
|
|
5
|
+
var typing_exports = /* @__PURE__ */ __exportAll({ sendTyping: () => sendTyping });
|
|
6
|
+
const DISCORD_TYPING_START_TIMEOUT_MS = 5e3;
|
|
7
|
+
async function sendTyping(params) {
|
|
8
|
+
if ((await raceWithTimeout(params.rest.post(Routes.channelTyping(params.channelId)).then(() => ({ kind: "sent" })), DISCORD_TYPING_START_TIMEOUT_MS, () => ({ kind: "timeout" }), { ref: false })).kind === "timeout") throw new Error(`discord typing start timed out after ${DISCORD_TYPING_START_TIMEOUT_MS}ms`);
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { typing_exports as n, sendTyping as t };
|