@openclaw/discord 2026.10.5 → 2026.10.10-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/dist/.setup/{approval-handler.runtime-D88-QVlO.mjs → approval-handler.runtime-BvF8oUpa.mjs} +9 -9
- package/dist/.setup/{approval-message-updates-CIGByUcE.mjs → approval-message-updates-wbUqLtLI.mjs} +2 -2
- package/dist/.setup/{audit-TGIPL0f_.mjs → audit-UwzCdDJk.mjs} +3 -3
- package/dist/.setup/{channel-C24afwHP.mjs → channel-BlvyeRAu.mjs} +72 -49
- package/dist/.setup/{channel.setup-B3KEh05g.mjs → channel.setup-By7wNopw.mjs} +1 -1
- package/dist/.setup/{command-owners-C7rUdqUX.mjs → command-owners-D78sAoOz.mjs} +1 -1
- package/dist/.setup/{components-HN9052L1.mjs → components-C_cuoW1q.mjs} +1 -1
- package/dist/.setup/conversation-binding-route-fdYsXexV.mjs +68 -0
- package/dist/.setup/{discord-BGqgx-yd.mjs → discord-Cl2OPTZ6.mjs} +18 -14
- package/dist/.setup/{doctor-9Ka20lDD.mjs → doctor-94GSI6lY.mjs} +2 -2
- package/dist/.setup/{handle-action-CsQmpfGZ.mjs → handle-action-0-FZD3Am.mjs} +7 -7
- package/dist/.setup/{handle-action.guild-admin-Aw-vutu3.mjs → handle-action.guild-admin-DfAWANBE.mjs} +2 -2
- package/dist/.setup/{message-handler-C_BQFYCW.mjs → message-handler-CtR2w7W_.mjs} +4 -4
- package/dist/.setup/{message-handler.preflight-C_xFOxPN.mjs → message-handler.preflight-BqUw7LWb.mjs} +11 -10
- package/dist/.setup/{message-handler.preflight-pluralkit-CfRsEwg4.mjs → message-handler.preflight-pluralkit-BU9I_X-b.mjs} +4 -6
- package/dist/.setup/{message-handler.process-_np9if7z.mjs → message-handler.process-BZeWmSNC.mjs} +40 -50
- package/dist/.setup/{outbound-adapter-L3UDoMOG.mjs → outbound-adapter-DBwgKemw.mjs} +5 -5
- package/dist/.setup/{outbound-session-route-iwnu6IK8.mjs → outbound-session-route-CsHHPxsQ.mjs} +24 -7
- package/dist/.setup/{provider-CbmXLYrW.mjs → provider-DUTsZJHz.mjs} +230 -205
- package/dist/.setup/{provider-session.runtime-BMOuDbod.mjs → provider-session.runtime-Ucr3XodI.mjs} +3 -3
- package/dist/.setup/provider.runtime-J8NuMCNs.mjs +1 -0
- package/dist/.setup/{realtime-session.runtime-YCumnRSE.mjs → realtime-session.runtime-bNnPOKP_.mjs} +161 -150
- package/dist/.setup/{receive-recovery-eVmK2_hl.mjs → receive-recovery-CKvaG2Hf.mjs} +4 -25
- package/dist/.setup/{runtime-DPm3gZXk.mjs → runtime-Cg5pIBm_.mjs} +1 -1
- package/dist/.setup/{runtime-CRTkKU1G.mjs → runtime-DE6W14G3.mjs} +7 -7
- package/dist/.setup/{send-DbILKgcm.mjs → send-yR1hfybW.mjs} +26 -12
- package/dist/.setup/{send.components-FxOS3CeP.mjs → send.components--dxMjc2O.mjs} +5 -5
- package/dist/.setup/{send.outbound-_jx4Xpd3.mjs → send.outbound-B5vQwgUK.mjs} +10 -4
- package/dist/.setup/{send.receipt-BAlzXd8e.mjs → send.receipt-eE3zLTDH.mjs} +3 -9
- package/dist/.setup/{send.shared-CjQ4jbMA.mjs → send.shared-iGf1rqAm.mjs} +4 -3
- package/dist/.setup/setup-plugin-api-DVpA_yqS.mjs +2 -0
- package/dist/.setup/{shared-C027f-lL.mjs → shared-DgzLizSt.mjs} +1 -1
- package/dist/.setup/{subagent-hooks-CME7dSGf.mjs → subagent-hooks-tBtaqWkD.mjs} +21 -12
- package/dist/.setup/{system-events-BwwSDCw4.mjs → system-events-DGsxf-l9.mjs} +1 -1
- package/dist/.setup/{target-resolver-Bse8fuTi.mjs → target-resolver-BFOKmBni.mjs} +1 -1
- package/dist/.setup/{targets-DZJjkzwv.mjs → targets-UbCpek5o.mjs} +1 -1
- package/dist/.setup/{thread-bindings-0hPTSK14.mjs → thread-bindings-Dsc3zsrI.mjs} +29 -7
- package/dist/.setup/{thread-bindings.manager-CdNa6UIs.mjs → thread-bindings.manager-BMpmKLQh.mjs} +63 -19
- package/dist/.setup/{thread-bindings.session-updates-DGSljVf6.mjs → thread-bindings.session-updates-BMdJeJMc.mjs} +39 -122
- package/dist/.setup/{threading-BWz5lW0p.mjs → threading-Cg_QRc8s.mjs} +2 -2
- package/dist/.setup/{transcripts-source-EMrQb132.mjs → transcripts-source-fRvFsZng.mjs} +12 -17
- package/dist/.setup/{voice-runtime-BFEBhf2B.mjs → voice-runtime-DHDNu0fz.mjs} +73 -120
- package/dist/action-runtime-api.js +1 -1
- package/dist/activities-api.js +3 -3
- package/dist/api.js +11 -11
- package/dist/channel-plugin-api.js +1 -1
- package/dist/runtime-api.js +15 -15
- package/dist/setup-entry.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/src/voice/audio-worker.runtime.js +8 -11
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/transcripts-source-api.js +1 -1
- package/node_modules/mdast-util-from-markdown/dev/lib/index.js +152 -45
- package/node_modules/mdast-util-from-markdown/dev/lib/types.d.ts +26 -0
- package/node_modules/mdast-util-from-markdown/lib/index.js +133 -40
- package/node_modules/mdast-util-from-markdown/lib/types.d.ts +26 -0
- package/node_modules/mdast-util-from-markdown/package.json +6 -7
- package/node_modules/mdast-util-from-markdown/readme.md +15 -1
- package/node_modules/typebox/build/value/clean/from_object.mjs +1 -1
- package/node_modules/typebox/package.json +1 -1
- package/package.json +6 -6
- package/dist/.setup/conversation-binding-route-r4XyytCE.mjs +0 -51
- package/dist/.setup/provider.runtime-1yN_05AK.mjs +0 -1
- package/dist/.setup/setup-plugin-api-BFl2FljJ.mjs +0 -2
|
@@ -5,8 +5,8 @@ import { asOptionalObjectRecord, normalizeLowercaseStringOrEmpty, normalizeOptio
|
|
|
5
5
|
import { resolveNonNegativeIntegerOption, resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
|
|
6
6
|
import { resolveGlobalSingleton } from "openclaw/plugin-sdk/global-singleton";
|
|
7
7
|
import { createPluginStateErrorReporter } from "openclaw/plugin-sdk/plugin-state-runtime";
|
|
8
|
+
import { resolveThreadBindingExpiry, warnPluginSdkDeprecation } from "openclaw/plugin-sdk/thread-bindings-session-runtime";
|
|
8
9
|
import { recordOutboundMessageIdentity } from "openclaw/plugin-sdk/outbound-echo-runtime";
|
|
9
|
-
import { resolveThreadBindingExpiry } from "openclaw/plugin-sdk/thread-bindings-session-runtime";
|
|
10
10
|
//#region extensions/discord/src/monitor/thread-bindings.state.ts
|
|
11
11
|
const THREAD_BINDINGS_STATE_KEY = Symbol.for("openclaw.discordThreadBindingsState");
|
|
12
12
|
function createThreadBindingsGlobalState() {
|
|
@@ -21,7 +21,6 @@ function createThreadBindingsGlobalState() {
|
|
|
21
21
|
loadedPersistentBindings: false,
|
|
22
22
|
persistenceAvailable: true,
|
|
23
23
|
lastPersistedAtMs: 0,
|
|
24
|
-
revision: 0,
|
|
25
24
|
mutationTail: Promise.resolve(),
|
|
26
25
|
accountOperationTails: /* @__PURE__ */ new WeakMap()
|
|
27
26
|
};
|
|
@@ -59,7 +58,7 @@ function openThreadBindingsStore() {
|
|
|
59
58
|
});
|
|
60
59
|
}
|
|
61
60
|
function openThreadBindingsStoreAsync() {
|
|
62
|
-
return getDiscordRuntime().state.
|
|
61
|
+
return getDiscordRuntime().state.openKeyedStoreV2({
|
|
63
62
|
namespace: THREAD_BINDINGS_NAMESPACE,
|
|
64
63
|
maxEntries: THREAD_BINDINGS_MAX_ENTRIES
|
|
65
64
|
});
|
|
@@ -200,7 +199,6 @@ function setBindingRecord(record) {
|
|
|
200
199
|
const existing = BINDINGS_BY_THREAD_ID.get(bindingKey);
|
|
201
200
|
if (existing) unlinkSessionBinding(existing.targetSessionKey, bindingKey);
|
|
202
201
|
BINDINGS_BY_THREAD_ID.set(bindingKey, record);
|
|
203
|
-
THREAD_BINDINGS_STATE.revision += 1;
|
|
204
202
|
linkSessionBinding(record.targetSessionKey, bindingKey);
|
|
205
203
|
rememberReusableWebhook(record);
|
|
206
204
|
}
|
|
@@ -210,14 +208,12 @@ function removeBindingRecord(bindingKeyRaw) {
|
|
|
210
208
|
const existing = BINDINGS_BY_THREAD_ID.get(key);
|
|
211
209
|
if (!existing) return null;
|
|
212
210
|
BINDINGS_BY_THREAD_ID.delete(key);
|
|
213
|
-
THREAD_BINDINGS_STATE.revision += 1;
|
|
214
211
|
unlinkSessionBinding(existing.targetSessionKey, key);
|
|
215
212
|
return existing;
|
|
216
213
|
}
|
|
217
214
|
function beginBindingsLoad() {
|
|
218
215
|
THREAD_BINDINGS_STATE.loadedBindings = true;
|
|
219
216
|
BINDINGS_BY_THREAD_ID.clear();
|
|
220
|
-
THREAD_BINDINGS_STATE.revision += 1;
|
|
221
217
|
BINDINGS_BY_SESSION_KEY.clear();
|
|
222
218
|
REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL.clear();
|
|
223
219
|
THREAD_BINDINGS_STATE.loadedPersistentBindings = false;
|
|
@@ -317,13 +313,12 @@ function drainThreadBindingMutations() {
|
|
|
317
313
|
return THREAD_BINDINGS_STATE.mutationTail;
|
|
318
314
|
}
|
|
319
315
|
async function commitBindingRecord(params) {
|
|
320
|
-
const revision = THREAD_BINDINGS_STATE.revision;
|
|
321
316
|
let authorityRefused = false;
|
|
322
317
|
let targetCommitted = false;
|
|
318
|
+
let committedWrites = 0;
|
|
323
319
|
const assertCurrent = () => {
|
|
324
320
|
try {
|
|
325
321
|
params.assertCurrent?.();
|
|
326
|
-
if (THREAD_BINDINGS_STATE.revision !== revision || BINDINGS_BY_THREAD_ID.get(params.bindingKey) !== params.previous) throw new Error("Discord thread binding changed during persistence");
|
|
327
322
|
} catch (error) {
|
|
328
323
|
authorityRefused = true;
|
|
329
324
|
throw error;
|
|
@@ -335,34 +330,21 @@ async function commitBindingRecord(params) {
|
|
|
335
330
|
const records = new Map(BINDINGS_BY_THREAD_ID);
|
|
336
331
|
if (params.next) records.set(params.bindingKey, params.next);
|
|
337
332
|
else records.delete(params.bindingKey);
|
|
338
|
-
const active = {
|
|
339
|
-
targetKey: params.bindingKey,
|
|
340
|
-
deletingTarget: params.next === null,
|
|
341
|
-
nextRecord: params.next,
|
|
342
|
-
writingKey: void 0,
|
|
343
|
-
committedKeys: /* @__PURE__ */ new Set()
|
|
344
|
-
};
|
|
345
|
-
THREAD_BINDINGS_STATE.activePersistence = active;
|
|
346
333
|
try {
|
|
347
334
|
const store = openThreadBindingsStoreAsync();
|
|
348
335
|
for (const [key, record] of records) {
|
|
349
336
|
assertCurrent();
|
|
350
337
|
const persisted = toPersistedBindingRecord(record);
|
|
351
|
-
if (key === params.bindingKey) active.nextRecord = persisted;
|
|
352
|
-
active.writingKey = key;
|
|
353
338
|
await store.register(key, persisted, { assertCurrent });
|
|
354
|
-
|
|
355
|
-
active.committedKeys.add(key);
|
|
339
|
+
committedWrites += 1;
|
|
356
340
|
targetCommitted ||= key === params.bindingKey;
|
|
357
341
|
}
|
|
358
342
|
assertCurrent();
|
|
359
343
|
const entries = await store.entries();
|
|
360
344
|
assertCurrent();
|
|
361
345
|
for (const entry of entries) if (!records.has(entry.key)) {
|
|
362
|
-
active.writingKey = entry.key;
|
|
363
346
|
await store.delete(entry.key, { assertCurrent });
|
|
364
|
-
|
|
365
|
-
active.committedKeys.add(entry.key);
|
|
347
|
+
committedWrites += 1;
|
|
366
348
|
targetCommitted ||= entry.key === params.bindingKey;
|
|
367
349
|
}
|
|
368
350
|
if (!params.next) targetCommitted = true;
|
|
@@ -370,7 +352,6 @@ async function commitBindingRecord(params) {
|
|
|
370
352
|
THREAD_BINDINGS_STATE.loadedPersistentBindings = records.size > 0;
|
|
371
353
|
THREAD_BINDINGS_STATE.lastPersistedAtMs = now;
|
|
372
354
|
} catch (error) {
|
|
373
|
-
const committedWrites = active.committedKeys.size;
|
|
374
355
|
let failure = error;
|
|
375
356
|
if (!authorityRefused) try {
|
|
376
357
|
assertCurrent();
|
|
@@ -390,8 +371,6 @@ async function commitBindingRecord(params) {
|
|
|
390
371
|
THREAD_BINDINGS_STATE.persistenceAvailable = false;
|
|
391
372
|
logVerbose("discord thread binding persistence unavailable; keeping bindings in memory");
|
|
392
373
|
}
|
|
393
|
-
} finally {
|
|
394
|
-
delete THREAD_BINDINGS_STATE.activePersistence;
|
|
395
374
|
}
|
|
396
375
|
}
|
|
397
376
|
if (!targetCommitted) assertCurrent();
|
|
@@ -399,38 +378,17 @@ async function commitBindingRecord(params) {
|
|
|
399
378
|
if (params.next) setBindingRecord(params.next);
|
|
400
379
|
else removeBindingRecord(params.bindingKey);
|
|
401
380
|
}
|
|
402
|
-
function persistBindingsSync(update
|
|
381
|
+
function persistBindingsSync(update) {
|
|
403
382
|
const store = openThreadBindingsStore();
|
|
404
|
-
const active = THREAD_BINDINGS_STATE.activePersistence;
|
|
405
383
|
let updatedRecord;
|
|
406
|
-
for (const [key, record] of BINDINGS_BY_THREAD_ID) if (key === update?.bindingKey
|
|
384
|
+
for (const [key, record] of BINDINGS_BY_THREAD_ID) if (key === update?.bindingKey) {
|
|
407
385
|
if (!store.update) throw new Error("Discord synchronous compatibility requires atomic state update");
|
|
408
|
-
|
|
409
|
-
store.update(key, (
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
if (!current && active.deletingTarget) base = void 0;
|
|
413
|
-
else if (current && active.nextRecord && (active.writingKey === key || active.committedKeys.has(key)) && JSON.stringify(toPersistedBindingRecord(current)) === JSON.stringify(toPersistedBindingRecord(active.nextRecord))) base = normalizePersistedBinding(key, current) ?? record;
|
|
414
|
-
}
|
|
415
|
-
if (key === update?.bindingKey) update.observe?.(current && normalizePersistedBinding(key, current) ? base : void 0);
|
|
416
|
-
next = base ? key === update?.bindingKey ? update.transform(base) : base : void 0;
|
|
417
|
-
return next ? toPersistedBindingRecord(next) : void 0;
|
|
418
|
-
});
|
|
419
|
-
if (key === update?.bindingKey) updatedRecord = next;
|
|
420
|
-
if (next) {
|
|
421
|
-
if (next !== record) setBindingRecord(next);
|
|
422
|
-
} else if (!(active?.targetKey === key && active.deletingTarget)) removeBindingRecord(key);
|
|
386
|
+
const next = update.transform(record);
|
|
387
|
+
store.update(key, () => toPersistedBindingRecord(next));
|
|
388
|
+
updatedRecord = next;
|
|
389
|
+
if (next !== record) setBindingRecord(next);
|
|
423
390
|
} else store.register(key, toPersistedBindingRecord(record));
|
|
424
|
-
for (const entry of store.entries()) if (!BINDINGS_BY_THREAD_ID.has(entry.key))
|
|
425
|
-
if (entry.key !== removedKey && active?.targetKey === entry.key && !active.deletingTarget) {
|
|
426
|
-
const committed = normalizePersistedBinding(entry.key, entry.value);
|
|
427
|
-
if (committed) {
|
|
428
|
-
setBindingRecord(committed);
|
|
429
|
-
continue;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
store.delete(entry.key);
|
|
433
|
-
}
|
|
391
|
+
for (const entry of store.entries()) if (!BINDINGS_BY_THREAD_ID.has(entry.key)) store.delete(entry.key);
|
|
434
392
|
THREAD_BINDINGS_STATE.loadedPersistentBindings = BINDINGS_BY_THREAD_ID.size > 0;
|
|
435
393
|
THREAD_BINDINGS_STATE.lastPersistedAtMs = Date.now();
|
|
436
394
|
return updatedRecord;
|
|
@@ -440,76 +398,36 @@ function updateBindingRecordSync(params) {
|
|
|
440
398
|
const record = BINDINGS_BY_THREAD_ID.get(params.bindingKey);
|
|
441
399
|
if (!record) return null;
|
|
442
400
|
const now = Date.now();
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
if (persist) try {
|
|
446
|
-
return persistBindingsSync({
|
|
447
|
-
...params,
|
|
448
|
-
observe: (current) => {
|
|
449
|
-
observed = current;
|
|
450
|
-
}
|
|
451
|
-
}) ?? null;
|
|
401
|
+
if (params.persist && THREAD_BINDINGS_STATE.persistenceAvailable && (!params.minIntervalMs || now - THREAD_BINDINGS_STATE.lastPersistedAtMs >= params.minIntervalMs)) try {
|
|
402
|
+
return persistBindingsSync(params) ?? null;
|
|
452
403
|
} catch {
|
|
453
404
|
THREAD_BINDINGS_STATE.persistenceAvailable = false;
|
|
454
405
|
logVerbose("discord thread binding persistence unavailable; keeping bindings in memory");
|
|
455
406
|
}
|
|
456
407
|
const current = BINDINGS_BY_THREAD_ID.get(params.bindingKey);
|
|
457
408
|
if (current !== record) return current ?? null;
|
|
458
|
-
|
|
459
|
-
logVerbose("discord synchronous binding update skipped: pending target read unavailable");
|
|
460
|
-
return null;
|
|
461
|
-
}
|
|
462
|
-
const next = params.transform(observed ?? record);
|
|
409
|
+
const next = params.transform(record);
|
|
463
410
|
setBindingRecord(next);
|
|
464
411
|
return next;
|
|
465
412
|
}
|
|
466
413
|
/** Public SDK compatibility only; bundled callers await worker mutations. */
|
|
467
414
|
function removeBindingRecordSync(bindingKey) {
|
|
468
|
-
|
|
469
|
-
if (!
|
|
470
|
-
if (!shouldPersistBindingMutations() || !THREAD_BINDINGS_STATE.persistenceAvailable) return THREAD_BINDINGS_STATE.activePersistence?.targetKey === bindingKey ? null : removeBindingRecord(bindingKey);
|
|
415
|
+
if (!BINDINGS_BY_THREAD_ID.get(bindingKey)) return null;
|
|
416
|
+
if (!shouldPersistBindingMutations() || !THREAD_BINDINGS_STATE.persistenceAvailable) return removeBindingRecord(bindingKey);
|
|
471
417
|
let removed = null;
|
|
472
|
-
let observed = null;
|
|
473
|
-
let replacement;
|
|
474
418
|
try {
|
|
475
|
-
|
|
476
|
-
if (!store.deleteIf) throw new Error("Discord synchronous compatibility requires atomic state deletion");
|
|
477
|
-
const deleted = store.deleteIf(bindingKey, (current) => {
|
|
478
|
-
const normalized = normalizePersistedBinding(bindingKey, current);
|
|
479
|
-
observed = normalized;
|
|
480
|
-
const pending = THREAD_BINDINGS_STATE.activePersistence;
|
|
481
|
-
if (normalized && pending?.targetKey === bindingKey && pending.nextRecord && (pending.writingKey === bindingKey || pending.committedKeys.has(bindingKey)) && JSON.stringify(toPersistedBindingRecord(normalized)) === JSON.stringify(toPersistedBindingRecord(pending.nextRecord)) && (normalized.targetSessionKey !== record.targetSessionKey || normalized.targetKind !== record.targetKind)) {
|
|
482
|
-
replacement = normalized;
|
|
483
|
-
return false;
|
|
484
|
-
}
|
|
485
|
-
return true;
|
|
486
|
-
});
|
|
487
|
-
if (replacement) {
|
|
488
|
-
setBindingRecord(replacement);
|
|
489
|
-
return null;
|
|
490
|
-
}
|
|
491
|
-
const pending = THREAD_BINDINGS_STATE.activePersistence;
|
|
492
|
-
if (!deleted && pending?.targetKey === bindingKey && pending.deletingTarget) return null;
|
|
419
|
+
openThreadBindingsStore().delete(bindingKey);
|
|
493
420
|
removed = removeBindingRecord(bindingKey);
|
|
494
|
-
persistBindingsSync(
|
|
421
|
+
persistBindingsSync();
|
|
495
422
|
return removed;
|
|
496
423
|
} catch {
|
|
497
424
|
THREAD_BINDINGS_STATE.persistenceAvailable = false;
|
|
498
|
-
if (replacement) {
|
|
499
|
-
setBindingRecord(replacement);
|
|
500
|
-
return null;
|
|
501
|
-
}
|
|
502
|
-
if (THREAD_BINDINGS_STATE.activePersistence?.targetKey === bindingKey && !observed && !removed) {
|
|
503
|
-
logVerbose("discord synchronous binding removal skipped: pending target read unavailable");
|
|
504
|
-
return null;
|
|
505
|
-
}
|
|
506
425
|
return removed ?? removeBindingRecord(bindingKey);
|
|
507
426
|
}
|
|
508
427
|
}
|
|
509
428
|
//#endregion
|
|
510
429
|
//#region extensions/discord/src/monitor/thread-bindings.session-shared.ts
|
|
511
430
|
function resolveBindingIdsForTargetSession(params) {
|
|
512
|
-
ensureBindingsLoaded();
|
|
513
431
|
return resolveBindingIdsForSession({
|
|
514
432
|
...params,
|
|
515
433
|
accountId: params.accountId ? normalizeAccountId(params.accountId) : void 0
|
|
@@ -517,41 +435,33 @@ function resolveBindingIdsForTargetSession(params) {
|
|
|
517
435
|
}
|
|
518
436
|
function mutateBindingsForTargetSession(params, update, onRemoved) {
|
|
519
437
|
const accountId = params.accountId ? normalizeAccountId(params.accountId) : void 0;
|
|
520
|
-
const
|
|
521
|
-
const
|
|
522
|
-
for (const [ownerAccountId, manager] of
|
|
523
|
-
manager
|
|
524
|
-
|
|
525
|
-
}
|
|
526
|
-
return runThreadBindingAccountOperation(
|
|
438
|
+
const managers = [];
|
|
439
|
+
const stoppingAtAdmission = /* @__PURE__ */ new Map();
|
|
440
|
+
for (const [ownerAccountId, manager] of MANAGERS_BY_ACCOUNT_ID) if (accountId === void 0 || ownerAccountId === accountId) {
|
|
441
|
+
managers.push(manager);
|
|
442
|
+
stoppingAtAdmission.set(ownerAccountId, manager.isStopping());
|
|
443
|
+
}
|
|
444
|
+
return runThreadBindingAccountOperation(managers, () => runThreadBindingMutation(async () => {
|
|
527
445
|
await ensureBindingsLoadedAsync();
|
|
528
446
|
const ids = resolveBindingIdsForTargetSession(params);
|
|
529
|
-
const owners = /* @__PURE__ */ new Map();
|
|
530
447
|
for (const bindingKey of ids) {
|
|
531
448
|
const existing = BINDINGS_BY_THREAD_ID.get(bindingKey);
|
|
532
449
|
if (!existing) continue;
|
|
533
450
|
const manager = MANAGERS_BY_ACCOUNT_ID.get(existing.accountId);
|
|
534
|
-
|
|
535
|
-
if (admitted?.stopping || !admitted && manager?.isStopping()) throw new Error("Discord thread binding manager is stopping");
|
|
536
|
-
if (admitted?.manager !== manager) throw new Error("Discord thread binding manager changed");
|
|
537
|
-
owners.set(existing.accountId, manager);
|
|
451
|
+
if (stoppingAtAdmission.get(existing.accountId) ?? manager?.isStopping()) throw new Error("Discord thread binding manager is stopping");
|
|
538
452
|
}
|
|
539
453
|
const now = Date.now();
|
|
540
454
|
const updated = [];
|
|
541
455
|
for (const bindingKey of ids) {
|
|
542
456
|
const existing = BINDINGS_BY_THREAD_ID.get(bindingKey);
|
|
543
457
|
if (!existing) continue;
|
|
544
|
-
const manager =
|
|
545
|
-
const assertCurrent = () => {
|
|
546
|
-
if (MANAGERS_BY_ACCOUNT_ID.get(existing.accountId) !== manager) throw new Error("Discord thread binding manager changed");
|
|
547
|
-
};
|
|
458
|
+
const manager = MANAGERS_BY_ACCOUNT_ID.get(existing.accountId);
|
|
548
459
|
const nextRecord = update(existing, now);
|
|
549
460
|
await commitBindingRecord({
|
|
550
461
|
bindingKey,
|
|
551
462
|
previous: existing,
|
|
552
463
|
next: nextRecord,
|
|
553
|
-
persist: shouldPersistBindingMutations()
|
|
554
|
-
assertCurrent
|
|
464
|
+
persist: shouldPersistBindingMutations()
|
|
555
465
|
});
|
|
556
466
|
if (!nextRecord) onRemoved?.(existing, manager);
|
|
557
467
|
updated.push(nextRecord ?? existing);
|
|
@@ -594,6 +504,13 @@ function createDurationSetters(field) {
|
|
|
594
504
|
return mutateBindingsForTargetSession(params, createDurationUpdate(field, params[field]));
|
|
595
505
|
},
|
|
596
506
|
set: (params) => {
|
|
507
|
+
const method = field === "idleTimeoutMs" ? "setThreadBindingIdleTimeoutBySessionKey" : "setThreadBindingMaxAgeBySessionKey";
|
|
508
|
+
warnPluginSdkDeprecation({
|
|
509
|
+
family: "conversation-bindings",
|
|
510
|
+
method,
|
|
511
|
+
replacement: `${method}Async`
|
|
512
|
+
});
|
|
513
|
+
ensureBindingsLoaded();
|
|
597
514
|
return updateBindingsForTargetSessionSync(resolveBindingIdsForTargetSession(params), createDurationUpdate(field, params[field]));
|
|
598
515
|
}
|
|
599
516
|
};
|
|
@@ -602,9 +519,9 @@ const idleSetters = createDurationSetters("idleTimeoutMs");
|
|
|
602
519
|
const maxAgeSetters = createDurationSetters("maxAgeMs");
|
|
603
520
|
const setThreadBindingIdleTimeoutBySessionKeyAsync = idleSetters.setAsync;
|
|
604
521
|
const setThreadBindingMaxAgeBySessionKeyAsync = maxAgeSetters.setAsync;
|
|
605
|
-
/** @deprecated Use
|
|
522
|
+
/** @deprecated Use setThreadBindingIdleTimeoutBySessionKeyAsync; compatible through 2026-12-31, removed in the first January 2027 stable. */
|
|
606
523
|
const setThreadBindingIdleTimeoutBySessionKey = idleSetters.set;
|
|
607
|
-
/** @deprecated Use
|
|
524
|
+
/** @deprecated Use setThreadBindingMaxAgeBySessionKeyAsync; compatible through 2026-12-31, removed in the first January 2027 stable. */
|
|
608
525
|
const setThreadBindingMaxAgeBySessionKey = maxAgeSetters.set;
|
|
609
526
|
//#endregion
|
|
610
|
-
export {
|
|
527
|
+
export { resolveBindingIdsForSession as A, forgetThreadBindingToken as C, refreshUnboundThreadWebhookIdentity as D, normalizeThreadBindingDurationMs as E, resolveThreadBindingMaxAgeExpiresAt as F, resolveThreadBindingMaxAgeMs as I, shouldDefaultPersist as L, resolvePreparedThreadBindingLifecycle as M, resolveThreadBindingIdleTimeoutMs as N, rememberReusableWebhook as O, resolveThreadBindingInactivityExpiresAt as P, toBindingRecordKey as R, ensureBindingsLoadedAsync as S, normalizeTargetKind 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, resolveBindingRecordKey as j, rememberThreadBindingToken as k, drainThreadBindingMutations as l, snapshotThreadBindingMetadata 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, getThreadBindingToken as w, ensureBindingsLoaded as x, REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL as y, toReusableWebhookKey as z };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { d as resolveDiscordReplyDeliveryPlan, f as resolveDiscordReplyTarget, g as sanitizeDiscordThreadName, h as resolveDiscordThreadStarter, j as resolveDiscordMessageChannelId, m as resolveDiscordThreadParentInfo, p as resolveDiscordThreadChannel } from "./transcripts-source-
|
|
2
|
+
import { lt as createThread, pt as getChannelMessage, t as discord_exports } from "./discord-Cl2OPTZ6.mjs";
|
|
3
|
+
import { d as resolveDiscordReplyDeliveryPlan, f as resolveDiscordReplyTarget, g as sanitizeDiscordThreadName, h as resolveDiscordThreadStarter, j as resolveDiscordMessageChannelId, m as resolveDiscordThreadParentInfo, p as resolveDiscordThreadChannel } from "./transcripts-source-fRvFsZng.mjs";
|
|
4
4
|
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
5
5
|
import { buildAgentSessionKey } from "openclaw/plugin-sdk/routing";
|
|
6
6
|
import { normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { l as resolveDiscordAccount, o as listEnabledDiscordAccounts, u as resolveDiscordAccountAllowFrom } from "./accounts-ljrzXBJi.mjs";
|
|
2
2
|
import { A as isDiscordThreadChannelType, D as getDiscordEndpointRuntime, f as resolveDiscordGuildEntry, i as normalizeDiscordAllowList, k as resolveDiscordEndpointMediaGuard, l as resolveDiscordChannelConfigWithFallback, n as hasConfiguredDiscordChannels, o as normalizeDiscordSlug, p as resolveDiscordMemberAccessState, r as isDiscordGroupAllowedByPolicy, t as allowListMatches } from "./allow-list-B_ToXtew.mjs";
|
|
3
|
-
import { L as DiscordError,
|
|
3
|
+
import { L as DiscordError, pt as getChannelMessage, t as discord_exports } from "./discord-Cl2OPTZ6.mjs";
|
|
4
4
|
import { l as withAbortTimeout } from "./timeouts-CuNARfyw.mjs";
|
|
5
|
-
import { t as resolveDiscordCommandOwnerAllowFrom } from "./command-owners-
|
|
5
|
+
import { t as resolveDiscordCommandOwnerAllowFrom } from "./command-owners-D78sAoOz.mjs";
|
|
6
6
|
import { a as resolveDiscordChannelParentSafe, i as resolveDiscordChannelParentIdSafe, n as resolveDiscordChannelInfoSafe, r as resolveDiscordChannelNameSafe, t as resolveDiscordChannelIdSafe } from "./channel-access-DasWY_OV.mjs";
|
|
7
7
|
import { createSubsystemLogger, getChildLogger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
8
8
|
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
@@ -10,7 +10,6 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOpti
|
|
|
10
10
|
import { ComponentType, StickerFormatType } from "discord-api-types/v10";
|
|
11
11
|
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
12
12
|
import { saveRemoteMedia } from "openclaw/plugin-sdk/media-runtime";
|
|
13
|
-
import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
14
13
|
import { formatErrorMessage } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
15
14
|
import { resolveGlobalSingleton } from "openclaw/plugin-sdk/global-singleton";
|
|
16
15
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
@@ -27,14 +26,11 @@ const DISCORD_CHANNEL_INFO_CACHE_TTL_MS = 3e5;
|
|
|
27
26
|
const DISCORD_CHANNEL_INFO_NEGATIVE_CACHE_TTL_MS = 3e4;
|
|
28
27
|
const DISCORD_CHANNEL_INFO_CACHE_MAX_ENTRIES = 1e3;
|
|
29
28
|
function cacheDiscordChannelInfo(channelId, value, ttlMs, nowMs) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
});
|
|
36
|
-
pruneMapToMaxSize(discordChannelInfoCacheState.entries, DISCORD_CHANNEL_INFO_CACHE_MAX_ENTRIES);
|
|
37
|
-
}
|
|
29
|
+
discordChannelInfoCacheState.entries.set(channelId, {
|
|
30
|
+
value,
|
|
31
|
+
expiresAt: nowMs + ttlMs
|
|
32
|
+
});
|
|
33
|
+
pruneMapToMaxSize(discordChannelInfoCacheState.entries, DISCORD_CHANNEL_INFO_CACHE_MAX_ENTRIES);
|
|
38
34
|
}
|
|
39
35
|
function normalizeDiscordChannelId(value) {
|
|
40
36
|
return normalizeOptionalStringifiedId(value) ?? "";
|
|
@@ -55,26 +51,25 @@ function buildDiscordChannelInfo(channel, options) {
|
|
|
55
51
|
};
|
|
56
52
|
}
|
|
57
53
|
async function resolveDiscordChannelInfo(client, channelId) {
|
|
58
|
-
const
|
|
59
|
-
const now = asDateTimestampMs(rawNow);
|
|
54
|
+
const now = Date.now();
|
|
60
55
|
const cached = discordChannelInfoCacheState.entries.get(channelId);
|
|
61
56
|
if (cached) {
|
|
62
|
-
if (
|
|
57
|
+
if (cached.expiresAt > now) return cached.value;
|
|
63
58
|
discordChannelInfoCacheState.entries.delete(channelId);
|
|
64
59
|
}
|
|
65
60
|
try {
|
|
66
61
|
const channel = await client.fetchChannel(channelId);
|
|
67
62
|
if (!channel) {
|
|
68
|
-
cacheDiscordChannelInfo(channelId, null, DISCORD_CHANNEL_INFO_NEGATIVE_CACHE_TTL_MS,
|
|
63
|
+
cacheDiscordChannelInfo(channelId, null, DISCORD_CHANNEL_INFO_NEGATIVE_CACHE_TTL_MS, now);
|
|
69
64
|
return null;
|
|
70
65
|
}
|
|
71
66
|
const payload = buildDiscordChannelInfo(channel, { rawTypeFallback: true });
|
|
72
67
|
if (!payload) return null;
|
|
73
|
-
cacheDiscordChannelInfo(channelId, payload, DISCORD_CHANNEL_INFO_CACHE_TTL_MS,
|
|
68
|
+
cacheDiscordChannelInfo(channelId, payload, DISCORD_CHANNEL_INFO_CACHE_TTL_MS, now);
|
|
74
69
|
return payload;
|
|
75
70
|
} catch (err) {
|
|
76
71
|
logVerbose(`discord: failed to fetch channel ${channelId}: ${String(err)}`);
|
|
77
|
-
cacheDiscordChannelInfo(channelId, null, DISCORD_CHANNEL_INFO_NEGATIVE_CACHE_TTL_MS,
|
|
72
|
+
cacheDiscordChannelInfo(channelId, null, DISCORD_CHANNEL_INFO_NEGATIVE_CACHE_TTL_MS, now);
|
|
78
73
|
return null;
|
|
79
74
|
}
|
|
80
75
|
}
|