@openclaw/discord 2026.10.2 → 2026.10.5-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/account-inspect-8cCu6uPG.mjs +31 -0
- package/dist/.setup/{accounts-HE9-mj1L.mjs → accounts-ljrzXBJi.mjs} +47 -45
- package/dist/.setup/{allow-list-vxkG9_JD.mjs → allow-list-B_ToXtew.mjs} +34 -101
- package/dist/.setup/{api-DlNUkDqj.mjs → api-CtmE1OUN.mjs} +25 -31
- package/dist/.setup/{approval-handler.runtime-DmnEa54W.mjs → approval-handler.runtime-D7FoZSn0.mjs} +30 -53
- package/dist/.setup/{approval-message-updates-B0jdSqOj.mjs → approval-message-updates-CIGByUcE.mjs} +2 -2
- package/dist/.setup/{audit-BpikUwN_.mjs → audit-zSawfbsN.mjs} +5 -8
- package/dist/.setup/{channel-Dr-AUnGt.mjs → channel-DI7DMzu0.mjs} +136 -215
- package/dist/.setup/{channel-access-BRp3Y-rF.mjs → channel-access-DasWY_OV.mjs} +6 -7
- package/dist/.setup/{channel.setup-BmNvkidb.mjs → channel.setup-DdFVN1mr.mjs} +35 -64
- package/dist/.setup/{components-DLJR0xU-.mjs → components-HN9052L1.mjs} +123 -146
- package/dist/.setup/{config-schema-BQWfnSCx.mjs → config-schema-_uBILpQf.mjs} +7 -3
- package/dist/.setup/{conversation-binding-route-DicJC1Lj.mjs → conversation-binding-route-DTjCBx-O.mjs} +1 -1
- package/dist/.setup/{directory-config-gqsdcplU.mjs → directory-config-3iVub-3m.mjs} +1 -1
- package/dist/.setup/{directory-live-Bipr0eUJ.mjs → directory-live-DLygQVtW.mjs} +18 -22
- package/dist/.setup/{discord-9gysrhzp.mjs → discord-BGqgx-yd.mjs} +686 -854
- package/dist/.setup/{doctor-B2bskDcF.mjs → doctor-DSrNJ7m2.mjs} +36 -47
- package/dist/.setup/{doctor-contract-Bg3NPAMw.mjs → doctor-contract-Bwv8EuQ_.mjs} +7 -16
- package/dist/.setup/{handle-action-UmkjXBfo.mjs → handle-action-CXH1h1tq.mjs} +25 -38
- package/dist/.setup/{handle-action.guild-admin-CB4sc9VV.mjs → handle-action.guild-admin-CHKW6PIs.mjs} +25 -31
- package/dist/.setup/{live-policy-config-VxexfRKo.mjs → live-policy-config-BPoB3eQi.mjs} +1 -1
- package/dist/.setup/{message-handler-BK69A-NB.mjs → message-handler-Ii_etru1.mjs} +9 -14
- package/dist/.setup/{message-handler.preflight-DFpsh90H.mjs → message-handler.preflight-C7YuSRl_.mjs} +79 -128
- package/dist/.setup/{message-handler.preflight-pluralkit-BXGGVmpe.mjs → message-handler.preflight-pluralkit-C3iAG--b.mjs} +6 -6
- package/dist/.setup/{message-handler.process-TKoqcqIP.mjs → message-handler.process-ClgWYH6o.mjs} +234 -206
- package/dist/.setup/{outbound-adapter-D4wRAb5S.mjs → outbound-adapter-D8OOIuKn.mjs} +73 -112
- package/dist/.setup/{outbound-session-route-BvBH4LC6.mjs → outbound-session-route-B0Hpwn3Q.mjs} +57 -115
- package/dist/.setup/output-activity-uBpMSX75.mjs +11 -0
- package/dist/.setup/{pluralkit-a6_NLfH9.mjs → pluralkit-B64dfq_j.mjs} +3 -1
- package/dist/.setup/{preflight-audio-DHGIHEpv.mjs → preflight-audio-wWgsZG5F.mjs} +1 -5
- package/dist/.setup/{presence-cache-Dg3_dADn.mjs → presence-cache-DCeTsL73.mjs} +3 -6
- package/dist/.setup/{probe-BwSKpnZf.mjs → probe-D3P1x4aN.mjs} +10 -18
- package/dist/.setup/{provider-YP8gN9_o.mjs → provider-D9EzOfG8.mjs} +2990 -3903
- package/dist/.setup/{provider-session.runtime-D1gkPxHT.mjs → provider-session.runtime-CsnRvddI.mjs} +5 -5
- package/dist/.setup/provider.runtime-BQVcM7Pg.mjs +2 -0
- package/dist/.setup/{realtime-session.runtime-BKUQBy1u.mjs → realtime-session.runtime-CxGBk8H-.mjs} +69 -98
- package/dist/.setup/{receive-recovery-DgkX7Qvi.mjs → receive-recovery-eVmK2_hl.mjs} +2 -12
- package/dist/.setup/resolve-allowlist-common-DNSsUQRF.mjs +66 -0
- package/dist/.setup/resolve-channels-UdT38DzU.mjs +173 -0
- package/dist/.setup/{resolve-users-DNrwvunm.mjs → resolve-users-DnCsrXZ_.mjs} +12 -41
- package/dist/.setup/{runtime-CESTexGn.mjs → runtime-CRTkKU1G.mjs} +202 -313
- package/dist/.setup/{runtime-DPcmPST9.mjs → runtime-DPm3gZXk.mjs} +2 -2
- package/dist/.setup/{secret-config-contract-uOE2J7yM.mjs → secret-config-contract-CIsH7R3B.mjs} +9 -18
- package/dist/.setup/{security-audit-D42cp5N7.mjs → security-audit-BFT84Uny.mjs} +1 -2
- package/dist/.setup/security-contract-DNyyjTZZ.mjs +19 -0
- package/dist/.setup/{send-CJk3VP5q.mjs → send-DbILKgcm.mjs} +184 -241
- package/dist/.setup/{send.components-dPljuV24.mjs → send.components-FxOS3CeP.mjs} +47 -63
- package/dist/.setup/{send.outbound-rOboMO_6.mjs → send.outbound-_jx4Xpd3.mjs} +178 -202
- package/dist/.setup/{send.receipt-DVOg2Oaw.mjs → send.receipt-BAlzXd8e.mjs} +33 -109
- package/dist/.setup/{send.shared-C4CN24D9.mjs → send.shared-CjQ4jbMA.mjs} +97 -153
- package/dist/.setup/{sender-identity-AHpUNr72.mjs → sender-identity-BNBvGt1l.mjs} +1 -1
- package/dist/.setup/setup-plugin-api-xfOFmxHP.mjs +3 -0
- package/dist/.setup/{shared-BoBnM5kM.mjs → shared-CestGDpq.mjs} +30 -20
- package/dist/.setup/{subagent-hooks-HH8Uy9cx.mjs → subagent-hooks-CME7dSGf.mjs} +5 -10
- package/dist/.setup/{system-events-Cwxaww8i.mjs → system-events-BwwSDCw4.mjs} +2 -2
- package/dist/.setup/target-parsing-C-HyNxcE.mjs +48 -0
- package/dist/.setup/{target-resolver-CSFoPQ12.mjs → target-resolver-Bse8fuTi.mjs} +11 -27
- package/dist/.setup/targets-DZJjkzwv.mjs +3 -0
- package/dist/.setup/{thread-bindings-DjQCkmsd.mjs → thread-bindings-0hPTSK14.mjs} +61 -52
- package/dist/.setup/{thread-bindings.manager-D2-GYZ5s.mjs → thread-bindings.manager-CdNa6UIs.mjs} +138 -211
- package/dist/.setup/{thread-bindings.session-updates-Bu_CGr_O.mjs → thread-bindings.session-updates-DGSljVf6.mjs} +60 -99
- package/dist/.setup/threading-BKe3E3tp.mjs +246 -0
- package/dist/.setup/{timeouts-pun7VJ02.mjs → timeouts-CuNARfyw.mjs} +10 -18
- package/dist/.setup/{transcripts-source-CaZQnGRH.mjs → transcripts-source-0qQYVu2H.mjs} +50 -368
- package/dist/.setup/{voice-runtime-DDymtIw8.mjs → voice-runtime-QlZJ4sHv.mjs} +166 -322
- package/dist/account-inspect-api.js +1 -1
- package/dist/action-runtime-api.js +1 -1
- package/dist/activities-api.js +77 -120
- package/dist/api.js +19 -18
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/doctor-contract-api.js +1 -1
- package/dist/runtime-api.js +21 -20
- package/dist/secret-contract-api.js +1 -1
- package/dist/security-audit-contract-api.js +1 -1
- package/dist/security-contract-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 +38 -57
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/transcripts-source-api.js +1 -1
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/crypto.d.ts +2 -2
- package/node_modules/@types/node/dgram.d.ts +1 -1
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/zlib.d.ts +6 -0
- package/node_modules/@types/ws/README.md +1 -1
- package/node_modules/@types/ws/index.d.mts +4 -0
- package/node_modules/@types/ws/index.d.ts +4 -0
- package/node_modules/@types/ws/package.json +3 -3
- package/node_modules/discord-api-types/_generated_/rest/v10/interfaces.d.ts +21 -0
- package/node_modules/discord-api-types/_generated_/rest/v10/interfaces.d.ts.map +1 -1
- package/node_modules/discord-api-types/_generated_/rest/v9/interfaces.d.ts +21 -0
- package/node_modules/discord-api-types/_generated_/rest/v9/interfaces.d.ts.map +1 -1
- package/node_modules/discord-api-types/globals.d.ts +6 -0
- package/node_modules/discord-api-types/globals.d.ts.map +1 -1
- package/node_modules/discord-api-types/globals.js +6 -0
- package/node_modules/discord-api-types/globals.js.map +1 -1
- package/node_modules/discord-api-types/package.json +3 -3
- package/node_modules/discord-api-types/payloads/index.mjs +1 -0
- package/node_modules/discord-api-types/payloads/v10/applicationIdentityProfile.d.ts +207 -0
- package/node_modules/discord-api-types/payloads/v10/applicationIdentityProfile.d.ts.map +1 -0
- package/node_modules/discord-api-types/payloads/v10/applicationIdentityProfile.js +25 -0
- package/node_modules/discord-api-types/payloads/v10/applicationIdentityProfile.js.map +1 -0
- package/node_modules/discord-api-types/payloads/v10/autoModeration.d.ts +1 -1
- package/node_modules/discord-api-types/payloads/v10/autoModeration.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v10/guild.d.ts +27 -23
- package/node_modules/discord-api-types/payloads/v10/guild.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v10/guild.js +26 -22
- package/node_modules/discord-api-types/payloads/v10/guild.js.map +1 -1
- package/node_modules/discord-api-types/payloads/v10/index.d.ts +1 -0
- package/node_modules/discord-api-types/payloads/v10/index.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v10/index.js +1 -0
- package/node_modules/discord-api-types/payloads/v10/index.js.map +1 -1
- package/node_modules/discord-api-types/payloads/v10/index.mjs +1 -0
- package/node_modules/discord-api-types/payloads/v9/applicationIdentityProfile.d.ts +207 -0
- package/node_modules/discord-api-types/payloads/v9/applicationIdentityProfile.d.ts.map +1 -0
- package/node_modules/discord-api-types/payloads/v9/applicationIdentityProfile.js +25 -0
- package/node_modules/discord-api-types/payloads/v9/applicationIdentityProfile.js.map +1 -0
- package/node_modules/discord-api-types/payloads/v9/autoModeration.d.ts +1 -1
- package/node_modules/discord-api-types/payloads/v9/autoModeration.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v9/guild.d.ts +27 -23
- package/node_modules/discord-api-types/payloads/v9/guild.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v9/guild.js +26 -22
- package/node_modules/discord-api-types/payloads/v9/guild.js.map +1 -1
- package/node_modules/discord-api-types/payloads/v9/index.d.ts +1 -0
- package/node_modules/discord-api-types/payloads/v9/index.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v9/index.js +1 -0
- package/node_modules/discord-api-types/payloads/v9/index.js.map +1 -1
- package/node_modules/discord-api-types/payloads/v9/index.mjs +1 -0
- package/node_modules/discord-api-types/rest/common.d.ts +2 -0
- package/node_modules/discord-api-types/rest/common.d.ts.map +1 -1
- package/node_modules/discord-api-types/rest/common.js +2 -0
- package/node_modules/discord-api-types/rest/common.js.map +1 -1
- package/node_modules/discord-api-types/rest/v10/applicationIdentityProfile.d.ts +70 -0
- package/node_modules/discord-api-types/rest/v10/applicationIdentityProfile.d.ts.map +1 -0
- package/node_modules/discord-api-types/rest/v10/applicationIdentityProfile.js +3 -0
- package/node_modules/discord-api-types/rest/v10/applicationIdentityProfile.js.map +1 -0
- package/node_modules/discord-api-types/rest/v10/index.d.ts +1 -0
- package/node_modules/discord-api-types/rest/v10/index.d.ts.map +1 -1
- package/node_modules/discord-api-types/rest/v10/index.js +29 -0
- package/node_modules/discord-api-types/rest/v10/index.js.map +1 -1
- package/node_modules/discord-api-types/rest/v10/interactions.d.ts +4 -2
- package/node_modules/discord-api-types/rest/v10/interactions.d.ts.map +1 -1
- package/node_modules/discord-api-types/rest/v10/user.d.ts +2 -2
- package/node_modules/discord-api-types/rest/v10/user.d.ts.map +1 -1
- package/node_modules/discord-api-types/rest/v9/applicationIdentityProfile.d.ts +70 -0
- package/node_modules/discord-api-types/rest/v9/applicationIdentityProfile.d.ts.map +1 -0
- package/node_modules/discord-api-types/rest/v9/applicationIdentityProfile.js +3 -0
- package/node_modules/discord-api-types/rest/v9/applicationIdentityProfile.js.map +1 -0
- package/node_modules/discord-api-types/rest/v9/index.d.ts +1 -0
- package/node_modules/discord-api-types/rest/v9/index.d.ts.map +1 -1
- package/node_modules/discord-api-types/rest/v9/index.js +29 -0
- package/node_modules/discord-api-types/rest/v9/index.js.map +1 -1
- package/node_modules/discord-api-types/rest/v9/interactions.d.ts +4 -2
- package/node_modules/discord-api-types/rest/v9/interactions.d.ts.map +1 -1
- package/node_modules/discord-api-types/rest/v9/user.d.ts +2 -2
- package/node_modules/discord-api-types/rest/v9/user.d.ts.map +1 -1
- package/node_modules/discord-api-types/v10.mjs +1 -0
- package/node_modules/discord-api-types/v9.mjs +1 -0
- package/node_modules/micromark/dev/lib/compile.d.ts.map +1 -1
- package/node_modules/micromark/dev/lib/compile.js +14 -4
- package/node_modules/micromark/dev/lib/create-tokenizer.d.ts.map +1 -1
- package/node_modules/micromark/dev/lib/create-tokenizer.js +7 -6
- package/node_modules/micromark/dev/lib/initialize/document.js +25 -21
- package/node_modules/micromark/dev/lib/initialize/text.d.ts.map +1 -1
- package/node_modules/micromark/dev/lib/initialize/text.js +10 -6
- package/node_modules/micromark/dev/lib/preprocess.d.ts.map +1 -1
- package/node_modules/micromark/dev/lib/preprocess.js +19 -21
- package/node_modules/micromark/lib/compile.d.ts.map +1 -1
- package/node_modules/micromark/lib/compile.js +37 -29
- package/node_modules/micromark/lib/create-tokenizer.d.ts.map +1 -1
- package/node_modules/micromark/lib/create-tokenizer.js +37 -35
- package/node_modules/micromark/lib/initialize/document.js +21 -13
- package/node_modules/micromark/lib/initialize/text.d.ts.map +1 -1
- package/node_modules/micromark/lib/initialize/text.js +7 -3
- package/node_modules/micromark/lib/preprocess.d.ts.map +1 -1
- package/node_modules/micromark/lib/preprocess.js +16 -19
- package/node_modules/micromark/package.json +2 -15
- package/node_modules/micromark-core-commonmark/dev/lib/attention.js +18 -24
- package/node_modules/micromark-core-commonmark/dev/lib/code-fenced.d.ts.map +1 -1
- package/node_modules/micromark-core-commonmark/dev/lib/code-fenced.js +1 -43
- package/node_modules/micromark-core-commonmark/dev/lib/code-indented.js +19 -43
- package/node_modules/micromark-core-commonmark/dev/lib/heading-atx.js +2 -6
- package/node_modules/micromark-core-commonmark/dev/lib/html-flow.d.ts.map +1 -1
- package/node_modules/micromark-core-commonmark/dev/lib/html-flow.js +2 -53
- package/node_modules/micromark-core-commonmark/dev/lib/label-end.js +14 -12
- package/node_modules/micromark-core-commonmark/dev/lib/label-start-image.d.ts.map +1 -1
- package/node_modules/micromark-core-commonmark/dev/lib/label-start-image.js +14 -5
- package/node_modules/micromark-core-commonmark/dev/lib/label-start-link.d.ts.map +1 -1
- package/node_modules/micromark-core-commonmark/dev/lib/label-start-link.js +14 -5
- package/node_modules/micromark-core-commonmark/dev/lib/partial-non-lazy-continuation.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/partial-non-lazy-continuation.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/partial-non-lazy-continuation.js +67 -0
- package/node_modules/micromark-core-commonmark/dev/lib/setext-underline.d.ts.map +1 -1
- package/node_modules/micromark-core-commonmark/dev/lib/setext-underline.js +8 -5
- package/node_modules/micromark-core-commonmark/lib/attention.js +14 -24
- package/node_modules/micromark-core-commonmark/lib/code-fenced.d.ts.map +1 -1
- package/node_modules/micromark-core-commonmark/lib/code-fenced.js +1 -39
- package/node_modules/micromark-core-commonmark/lib/code-indented.js +11 -29
- package/node_modules/micromark-core-commonmark/lib/heading-atx.js +2 -6
- package/node_modules/micromark-core-commonmark/lib/html-flow.d.ts.map +1 -1
- package/node_modules/micromark-core-commonmark/lib/html-flow.js +2 -51
- package/node_modules/micromark-core-commonmark/lib/label-end.js +11 -10
- package/node_modules/micromark-core-commonmark/lib/label-start-image.d.ts.map +1 -1
- package/node_modules/micromark-core-commonmark/lib/label-start-image.js +11 -3
- package/node_modules/micromark-core-commonmark/lib/label-start-link.d.ts.map +1 -1
- package/node_modules/micromark-core-commonmark/lib/label-start-link.js +11 -3
- package/node_modules/micromark-core-commonmark/lib/partial-non-lazy-continuation.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/partial-non-lazy-continuation.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/partial-non-lazy-continuation.js +61 -0
- package/node_modules/micromark-core-commonmark/lib/setext-underline.d.ts.map +1 -1
- package/node_modules/micromark-core-commonmark/lib/setext-underline.js +7 -5
- package/node_modules/micromark-core-commonmark/package.json +4 -16
- package/node_modules/micromark-factory-space/dev/index.d.ts +24 -1
- package/node_modules/micromark-factory-space/dev/index.d.ts.map +1 -1
- package/node_modules/micromark-factory-space/dev/index.js +58 -3
- package/node_modules/micromark-factory-space/index.d.ts +24 -1
- package/node_modules/micromark-factory-space/index.d.ts.map +1 -1
- package/node_modules/micromark-factory-space/index.js +55 -3
- package/node_modules/micromark-factory-space/package.json +1 -10
- package/node_modules/micromark-factory-space/readme.md +25 -25
- package/node_modules/micromark-util-edit-map/dev/index.d.ts +78 -0
- package/node_modules/micromark-util-edit-map/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-util-edit-map/dev/index.js +237 -0
- package/node_modules/micromark-util-edit-map/index.d.ts +78 -0
- package/node_modules/micromark-util-edit-map/index.d.ts.map +1 -0
- package/node_modules/micromark-util-edit-map/index.js +225 -0
- package/node_modules/micromark-util-edit-map/license +22 -0
- package/node_modules/micromark-util-edit-map/package.json +48 -0
- package/node_modules/micromark-util-edit-map/readme.md +234 -0
- package/node_modules/micromark-util-types/index.d.ts +6 -3
- package/node_modules/micromark-util-types/package.json +2 -36
- package/node_modules/ws/lib/websocket.js +17 -3
- package/node_modules/ws/package.json +1 -1
- package/openclaw.plugin.json +3 -6
- package/package.json +7 -12
- package/dist/.setup/account-inspect-DsER5ILV.mjs +0 -45
- package/dist/.setup/provider.runtime-CZ51OIgD.mjs +0 -2
- package/dist/.setup/resolve-allowlist-common-BUyU3C-T.mjs +0 -27
- package/dist/.setup/resolve-channels-DA6QlhZN.mjs +0 -246
- package/dist/.setup/security-contract-DSHk7I2w.mjs +0 -26
- package/dist/.setup/setup-plugin-api-BVlCz3fm.mjs +0 -3
- package/dist/.setup/targets-bqXQENmX.mjs +0 -3
- package/dist/control-ui/2afbdab1d3aa65a789d8a3eba666f4b1ec5df07073538fe30d6cf32093a1fb2d/index.js +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.mjs";
|
|
2
2
|
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
3
|
-
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
3
|
import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
|
|
4
|
+
import { asOptionalObjectRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
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";
|
|
@@ -58,6 +58,12 @@ function openThreadBindingsStore() {
|
|
|
58
58
|
maxEntries: THREAD_BINDINGS_MAX_ENTRIES
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
|
+
function openThreadBindingsStoreAsync() {
|
|
62
|
+
return getDiscordRuntime().state.openKeyedStore({
|
|
63
|
+
namespace: THREAD_BINDINGS_NAMESPACE,
|
|
64
|
+
maxEntries: THREAD_BINDINGS_MAX_ENTRIES
|
|
65
|
+
});
|
|
66
|
+
}
|
|
61
67
|
function normalizeTargetKind(raw, targetSessionKey) {
|
|
62
68
|
if (raw === "subagent" || raw === "acp") return raw;
|
|
63
69
|
return targetSessionKey.includes(":subagent:") ? "subagent" : "acp";
|
|
@@ -69,7 +75,7 @@ function resolveBindingRecordKey(params) {
|
|
|
69
75
|
const threadId = normalizeOptionalStringifiedId(params.threadId);
|
|
70
76
|
if (!threadId) return;
|
|
71
77
|
return toBindingRecordKey({
|
|
72
|
-
accountId:
|
|
78
|
+
accountId: params.accountId,
|
|
73
79
|
threadId
|
|
74
80
|
});
|
|
75
81
|
}
|
|
@@ -92,7 +98,7 @@ function normalizePersistedBinding(threadIdKey, raw) {
|
|
|
92
98
|
const idleTimeoutMs = resolveOptionalIntegerOption(value.idleTimeoutMs, { min: 0 });
|
|
93
99
|
const maxAgeMs = resolveOptionalIntegerOption(value.maxAgeMs, { min: 0 });
|
|
94
100
|
const metadata = value.metadata && typeof value.metadata === "object" ? { ...value.metadata } : void 0;
|
|
95
|
-
|
|
101
|
+
return {
|
|
96
102
|
accountId,
|
|
97
103
|
channelId,
|
|
98
104
|
threadId,
|
|
@@ -101,15 +107,14 @@ function normalizePersistedBinding(threadIdKey, raw) {
|
|
|
101
107
|
agentId,
|
|
102
108
|
boundBy,
|
|
103
109
|
boundAt,
|
|
104
|
-
lastActivityAt
|
|
110
|
+
lastActivityAt,
|
|
111
|
+
...label !== void 0 ? { label } : {},
|
|
112
|
+
...webhookId !== void 0 ? { webhookId } : {},
|
|
113
|
+
...webhookToken !== void 0 ? { webhookToken } : {},
|
|
114
|
+
...idleTimeoutMs !== void 0 ? { idleTimeoutMs } : {},
|
|
115
|
+
...maxAgeMs !== void 0 ? { maxAgeMs } : {},
|
|
116
|
+
...metadata !== void 0 ? { metadata } : {}
|
|
105
117
|
};
|
|
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
118
|
}
|
|
114
119
|
function normalizeThreadBindingDurationMs(raw, defaultsTo) {
|
|
115
120
|
const durationMs = resolveOptionalIntegerOption(raw);
|
|
@@ -145,17 +150,11 @@ function resolvePreparedThreadBindingLifecycle(params) {
|
|
|
145
150
|
};
|
|
146
151
|
}
|
|
147
152
|
function resolveThreadBindingInactivityExpiresAt(params) {
|
|
148
|
-
const idleTimeoutMs = resolveThreadBindingIdleTimeoutMs(
|
|
149
|
-
record: params.record,
|
|
150
|
-
defaultIdleTimeoutMs: params.defaultIdleTimeoutMs
|
|
151
|
-
});
|
|
153
|
+
const idleTimeoutMs = resolveThreadBindingIdleTimeoutMs(params);
|
|
152
154
|
return resolveTimestampExpiry(params.record.lastActivityAt, idleTimeoutMs);
|
|
153
155
|
}
|
|
154
156
|
function resolveThreadBindingMaxAgeExpiresAt(params) {
|
|
155
|
-
const maxAgeMs = resolveThreadBindingMaxAgeMs(
|
|
156
|
-
record: params.record,
|
|
157
|
-
defaultMaxAgeMs: params.defaultMaxAgeMs
|
|
158
|
-
});
|
|
157
|
+
const maxAgeMs = resolveThreadBindingMaxAgeMs(params);
|
|
159
158
|
return resolveTimestampExpiry(params.record.boundAt, maxAgeMs);
|
|
160
159
|
}
|
|
161
160
|
function linkSessionBinding(targetSessionKey, bindingKey) {
|
|
@@ -180,10 +179,7 @@ function rememberReusableWebhook(record) {
|
|
|
180
179
|
const webhookId = record.webhookId?.trim();
|
|
181
180
|
const webhookToken = record.webhookToken?.trim();
|
|
182
181
|
if (!webhookId || !webhookToken) return;
|
|
183
|
-
const key = toReusableWebhookKey(
|
|
184
|
-
accountId: record.accountId,
|
|
185
|
-
channelId: record.channelId
|
|
186
|
-
});
|
|
182
|
+
const key = toReusableWebhookKey(record);
|
|
187
183
|
REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL.set(key, {
|
|
188
184
|
webhookId,
|
|
189
185
|
webhookToken
|
|
@@ -200,10 +196,7 @@ function refreshUnboundThreadWebhookIdentity(record) {
|
|
|
200
196
|
});
|
|
201
197
|
}
|
|
202
198
|
function setBindingRecord(record) {
|
|
203
|
-
const bindingKey = toBindingRecordKey(
|
|
204
|
-
accountId: record.accountId,
|
|
205
|
-
threadId: record.threadId
|
|
206
|
-
});
|
|
199
|
+
const bindingKey = toBindingRecordKey(record);
|
|
207
200
|
const existing = BINDINGS_BY_THREAD_ID.get(bindingKey);
|
|
208
201
|
if (existing) unlinkSessionBinding(existing.targetSessionKey, bindingKey);
|
|
209
202
|
BINDINGS_BY_THREAD_ID.set(bindingKey, record);
|
|
@@ -234,8 +227,7 @@ function restoreBindings(entries) {
|
|
|
234
227
|
THREAD_BINDINGS_STATE.loadedPersistentBindings = entries.length > 0;
|
|
235
228
|
for (const entry of entries) {
|
|
236
229
|
const normalized = normalizePersistedBinding(entry.key, entry.value);
|
|
237
|
-
if (
|
|
238
|
-
setBindingRecord(normalized);
|
|
230
|
+
if (normalized) setBindingRecord(normalized);
|
|
239
231
|
}
|
|
240
232
|
}
|
|
241
233
|
function ensureBindingsLoaded() {
|
|
@@ -253,10 +245,7 @@ function ensureBindingsLoaded() {
|
|
|
253
245
|
async function loadBindingsAsync() {
|
|
254
246
|
let entries;
|
|
255
247
|
try {
|
|
256
|
-
entries = await
|
|
257
|
-
namespace: THREAD_BINDINGS_NAMESPACE,
|
|
258
|
-
maxEntries: THREAD_BINDINGS_MAX_ENTRIES
|
|
259
|
-
}).entries();
|
|
248
|
+
entries = await openThreadBindingsStoreAsync().entries();
|
|
260
249
|
} catch {
|
|
261
250
|
if (!THREAD_BINDINGS_STATE.loadedBindings) {
|
|
262
251
|
beginBindingsLoad();
|
|
@@ -279,34 +268,28 @@ async function ensureBindingsLoadedAsync() {
|
|
|
279
268
|
}
|
|
280
269
|
}
|
|
281
270
|
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
271
|
const out = [];
|
|
287
|
-
for (const bindingKey of
|
|
272
|
+
for (const bindingKey of BINDINGS_BY_SESSION_KEY.get(params.targetSessionKey.trim()) ?? []) {
|
|
288
273
|
const record = BINDINGS_BY_THREAD_ID.get(bindingKey);
|
|
289
|
-
if (!record)
|
|
290
|
-
if (params.accountId && record.accountId !== params.accountId) continue;
|
|
291
|
-
if (params.targetKind && record.targetKind !== params.targetKind) continue;
|
|
292
|
-
out.push(bindingKey);
|
|
274
|
+
if (record && (!params.accountId || record.accountId === params.accountId) && (!params.targetKind || record.targetKind === params.targetKind)) out.push(bindingKey);
|
|
293
275
|
}
|
|
294
276
|
return out;
|
|
295
277
|
}
|
|
296
278
|
//#endregion
|
|
297
279
|
//#region extensions/discord/src/monitor/thread-bindings.persistence.ts
|
|
298
280
|
function shouldPersistAnyBindingState() {
|
|
299
|
-
|
|
300
|
-
return false;
|
|
281
|
+
return [...PERSIST_BY_ACCOUNT_ID.values()].some(Boolean);
|
|
301
282
|
}
|
|
302
283
|
function shouldPersistBindingMutations() {
|
|
303
|
-
|
|
304
|
-
return THREAD_BINDINGS_STATE.loadedPersistentBindings;
|
|
284
|
+
return shouldPersistAnyBindingState() || THREAD_BINDINGS_STATE.loadedPersistentBindings;
|
|
305
285
|
}
|
|
306
286
|
function snapshotThreadBindingJson(value) {
|
|
307
287
|
const serialized = JSON.stringify(value);
|
|
308
288
|
return serialized ? JSON.parse(serialized) : void 0;
|
|
309
289
|
}
|
|
290
|
+
function snapshotThreadBindingMetadata(input) {
|
|
291
|
+
return asOptionalObjectRecord(snapshotThreadBindingJson(input.metadata ? { ...input.metadata } : void 0));
|
|
292
|
+
}
|
|
310
293
|
function toPersistedBindingRecord(record) {
|
|
311
294
|
return normalizePersistedBinding(record.threadId, snapshotThreadBindingJson(record)) ?? { ...record };
|
|
312
295
|
}
|
|
@@ -337,7 +320,6 @@ async function commitBindingRecord(params) {
|
|
|
337
320
|
const revision = THREAD_BINDINGS_STATE.revision;
|
|
338
321
|
let authorityRefused = false;
|
|
339
322
|
let targetCommitted = false;
|
|
340
|
-
let committedWrites = 0;
|
|
341
323
|
const assertCurrent = () => {
|
|
342
324
|
try {
|
|
343
325
|
params.assertCurrent?.();
|
|
@@ -362,10 +344,7 @@ async function commitBindingRecord(params) {
|
|
|
362
344
|
};
|
|
363
345
|
THREAD_BINDINGS_STATE.activePersistence = active;
|
|
364
346
|
try {
|
|
365
|
-
const store =
|
|
366
|
-
namespace: THREAD_BINDINGS_NAMESPACE,
|
|
367
|
-
maxEntries: THREAD_BINDINGS_MAX_ENTRIES
|
|
368
|
-
});
|
|
347
|
+
const store = openThreadBindingsStoreAsync();
|
|
369
348
|
for (const [key, record] of records) {
|
|
370
349
|
assertCurrent();
|
|
371
350
|
const persisted = toPersistedBindingRecord(record);
|
|
@@ -374,7 +353,6 @@ async function commitBindingRecord(params) {
|
|
|
374
353
|
await store.register(key, persisted, { assertCurrent });
|
|
375
354
|
active.writingKey = void 0;
|
|
376
355
|
active.committedKeys.add(key);
|
|
377
|
-
committedWrites += 1;
|
|
378
356
|
targetCommitted ||= key === params.bindingKey;
|
|
379
357
|
}
|
|
380
358
|
assertCurrent();
|
|
@@ -385,7 +363,6 @@ async function commitBindingRecord(params) {
|
|
|
385
363
|
await store.delete(entry.key, { assertCurrent });
|
|
386
364
|
active.writingKey = void 0;
|
|
387
365
|
active.committedKeys.add(entry.key);
|
|
388
|
-
committedWrites += 1;
|
|
389
366
|
targetCommitted ||= entry.key === params.bindingKey;
|
|
390
367
|
}
|
|
391
368
|
if (!params.next) targetCommitted = true;
|
|
@@ -393,6 +370,7 @@ async function commitBindingRecord(params) {
|
|
|
393
370
|
THREAD_BINDINGS_STATE.loadedPersistentBindings = records.size > 0;
|
|
394
371
|
THREAD_BINDINGS_STATE.lastPersistedAtMs = now;
|
|
395
372
|
} catch (error) {
|
|
373
|
+
const committedWrites = active.committedKeys.size;
|
|
396
374
|
let failure = error;
|
|
397
375
|
if (!authorityRefused) try {
|
|
398
376
|
assertCurrent();
|
|
@@ -530,26 +508,21 @@ function removeBindingRecordSync(bindingKey) {
|
|
|
530
508
|
}
|
|
531
509
|
//#endregion
|
|
532
510
|
//#region extensions/discord/src/monitor/thread-bindings.session-shared.ts
|
|
533
|
-
function normalizeNonNegativeMs(raw) {
|
|
534
|
-
if (!Number.isFinite(raw)) return 0;
|
|
535
|
-
return Math.max(0, Math.floor(raw));
|
|
536
|
-
}
|
|
537
511
|
function resolveBindingIdsForTargetSession(params) {
|
|
538
512
|
ensureBindingsLoaded();
|
|
539
|
-
const targetSessionKey = params.targetSessionKey.trim();
|
|
540
|
-
if (!targetSessionKey) return [];
|
|
541
513
|
return resolveBindingIdsForSession({
|
|
542
|
-
|
|
543
|
-
accountId: params.accountId ? normalizeAccountId(params.accountId) : void 0
|
|
544
|
-
targetKind: params.targetKind
|
|
514
|
+
...params,
|
|
515
|
+
accountId: params.accountId ? normalizeAccountId(params.accountId) : void 0
|
|
545
516
|
});
|
|
546
517
|
}
|
|
547
518
|
function mutateBindingsForTargetSession(params, update, onRemoved) {
|
|
548
519
|
const accountId = params.accountId ? normalizeAccountId(params.accountId) : void 0;
|
|
549
|
-
const admittedOwners =
|
|
520
|
+
const admittedOwners = /* @__PURE__ */ new Map();
|
|
521
|
+
const ownerSnapshot = [...MANAGERS_BY_ACCOUNT_ID];
|
|
522
|
+
for (const [ownerAccountId, manager] of ownerSnapshot) if (accountId === void 0 || ownerAccountId === accountId) admittedOwners.set(ownerAccountId, {
|
|
550
523
|
manager,
|
|
551
524
|
stopping: manager.isStopping()
|
|
552
|
-
}
|
|
525
|
+
});
|
|
553
526
|
return runThreadBindingAccountOperation([...admittedOwners.values()].map(({ manager }) => manager), () => runThreadBindingMutation(async () => {
|
|
554
527
|
await ensureBindingsLoadedAsync();
|
|
555
528
|
const ids = resolveBindingIdsForTargetSession(params);
|
|
@@ -605,45 +578,33 @@ function updateBindingsForTargetSessionSync(ids, update) {
|
|
|
605
578
|
}
|
|
606
579
|
//#endregion
|
|
607
580
|
//#region extensions/discord/src/monitor/thread-bindings.session-updates.ts
|
|
608
|
-
|
|
609
|
-
const
|
|
610
|
-
|
|
611
|
-
return mutateBindingsForTargetSession(params, (existing, now) => ({
|
|
581
|
+
function createDurationUpdate(field, raw) {
|
|
582
|
+
const duration = resolveNonNegativeIntegerOption(raw, 0);
|
|
583
|
+
return (existing, now) => ({
|
|
612
584
|
...existing,
|
|
613
|
-
|
|
585
|
+
[field]: duration,
|
|
586
|
+
...field === "maxAgeMs" ? { boundAt: now } : {},
|
|
614
587
|
lastActivityAt: now
|
|
615
|
-
})
|
|
588
|
+
});
|
|
616
589
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
590
|
+
function createDurationSetters(field) {
|
|
591
|
+
return {
|
|
592
|
+
setAsync: async (input) => {
|
|
593
|
+
const params = { ...input };
|
|
594
|
+
return mutateBindingsForTargetSession(params, createDurationUpdate(field, params[field]));
|
|
595
|
+
},
|
|
596
|
+
set: (params) => {
|
|
597
|
+
return updateBindingsForTargetSessionSync(resolveBindingIdsForTargetSession(params), createDurationUpdate(field, params[field]));
|
|
598
|
+
}
|
|
599
|
+
};
|
|
626
600
|
}
|
|
601
|
+
const idleSetters = createDurationSetters("idleTimeoutMs");
|
|
602
|
+
const maxAgeSetters = createDurationSetters("maxAgeMs");
|
|
603
|
+
const setThreadBindingIdleTimeoutBySessionKeyAsync = idleSetters.setAsync;
|
|
604
|
+
const setThreadBindingMaxAgeBySessionKeyAsync = maxAgeSetters.setAsync;
|
|
627
605
|
/** @deprecated Use the awaited lifecycle setter; retained for the generic SDK contract. */
|
|
628
|
-
|
|
629
|
-
const ids = resolveBindingIdsForTargetSession(params);
|
|
630
|
-
const idleTimeoutMs = normalizeNonNegativeMs(params.idleTimeoutMs);
|
|
631
|
-
return updateBindingsForTargetSessionSync(ids, (existing, now) => ({
|
|
632
|
-
...existing,
|
|
633
|
-
idleTimeoutMs,
|
|
634
|
-
lastActivityAt: now
|
|
635
|
-
}));
|
|
636
|
-
}
|
|
606
|
+
const setThreadBindingIdleTimeoutBySessionKey = idleSetters.set;
|
|
637
607
|
/** @deprecated Use the awaited lifecycle setter; retained for the generic SDK contract. */
|
|
638
|
-
|
|
639
|
-
const ids = resolveBindingIdsForTargetSession(params);
|
|
640
|
-
const maxAgeMs = normalizeNonNegativeMs(params.maxAgeMs);
|
|
641
|
-
return updateBindingsForTargetSessionSync(ids, (existing, now) => ({
|
|
642
|
-
...existing,
|
|
643
|
-
maxAgeMs,
|
|
644
|
-
boundAt: now,
|
|
645
|
-
lastActivityAt: now
|
|
646
|
-
}));
|
|
647
|
-
}
|
|
608
|
+
const setThreadBindingMaxAgeBySessionKey = maxAgeSetters.set;
|
|
648
609
|
//#endregion
|
|
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,
|
|
610
|
+
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, 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, normalizeTargetKind as w, ensureBindingsLoadedAsync as x, REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL as y };
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
|
|
2
|
+
import { ct as createThread, ft as getChannelMessage, t as discord_exports } from "./discord-BGqgx-yd.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-0qQYVu2H.mjs";
|
|
4
|
+
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
5
|
+
import { buildAgentSessionKey } from "openclaw/plugin-sdk/routing";
|
|
6
|
+
import { normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
|
+
import { Routes } from "discord-api-types/v10";
|
|
8
|
+
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
9
|
+
import { resolveChannelModelOverride } from "openclaw/plugin-sdk/model-session-runtime";
|
|
10
|
+
import { generateConversationLabel } from "openclaw/plugin-sdk/reply-dispatch-runtime";
|
|
11
|
+
//#region extensions/discord/src/monitor/thread-title.ts
|
|
12
|
+
const DEFAULT_THREAD_TITLE_TIMEOUT_MS = 6e4;
|
|
13
|
+
const MAX_THREAD_TITLE_SOURCE_CHARS = 600;
|
|
14
|
+
const MAX_THREAD_TITLE_CHANNEL_NAME_CHARS = 120;
|
|
15
|
+
const MAX_THREAD_TITLE_CHANNEL_DESCRIPTION_CHARS = 320;
|
|
16
|
+
const DISCORD_THREAD_TITLE_SYSTEM_PROMPT = "Generate a concise Discord thread title (3-6 words) in sentence case: capitalize only the first word and words that are always capitalized. Return only the title. Use channel context when provided and avoid redundant channel-name words unless needed for clarity.";
|
|
17
|
+
async function generateThreadTitle(params) {
|
|
18
|
+
const sourceText = params.messageText.trim();
|
|
19
|
+
if (!sourceText) return null;
|
|
20
|
+
try {
|
|
21
|
+
const userMessage = buildThreadTitleCompletionUserMessage({
|
|
22
|
+
sourceText,
|
|
23
|
+
channelName: params.channelName,
|
|
24
|
+
channelDescription: params.channelDescription
|
|
25
|
+
});
|
|
26
|
+
const generated = await generateConversationLabel({
|
|
27
|
+
cfg: params.cfg,
|
|
28
|
+
agentId: params.agentId,
|
|
29
|
+
userMessage,
|
|
30
|
+
prompt: DISCORD_THREAD_TITLE_SYSTEM_PROMPT,
|
|
31
|
+
...params.modelRef ? { modelRef: params.modelRef } : {},
|
|
32
|
+
timeoutMs: Math.max(100, Math.floor(params.timeoutMs ?? DEFAULT_THREAD_TITLE_TIMEOUT_MS)),
|
|
33
|
+
maxLength: MAX_THREAD_TITLE_SOURCE_CHARS
|
|
34
|
+
});
|
|
35
|
+
return generated ? normalizeGeneratedThreadTitle(generated) : null;
|
|
36
|
+
} catch (err) {
|
|
37
|
+
logVerbose(`thread-title: title generation failed for agent ${params.agentId}: ${String(err)}`);
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function buildThreadTitleCompletionUserMessage(params) {
|
|
42
|
+
const sourceText = truncateThreadTitleText(params.sourceText, MAX_THREAD_TITLE_SOURCE_CHARS);
|
|
43
|
+
const channelName = normalizeTitleContextField(params.channelName, MAX_THREAD_TITLE_CHANNEL_NAME_CHARS);
|
|
44
|
+
const channelDescription = normalizeTitleContextField(params.channelDescription, MAX_THREAD_TITLE_CHANNEL_DESCRIPTION_CHARS);
|
|
45
|
+
return [
|
|
46
|
+
channelName ? `Channel: ${channelName}` : void 0,
|
|
47
|
+
channelDescription ? `Channel description: ${channelDescription}` : void 0,
|
|
48
|
+
`Message:\n${sourceText}`
|
|
49
|
+
].filter(Boolean).join("\n\n");
|
|
50
|
+
}
|
|
51
|
+
function truncateThreadTitleText(text, maxChars) {
|
|
52
|
+
if (text.length <= maxChars) return text;
|
|
53
|
+
return `${truncateUtf16Safe(text, maxChars)}...`;
|
|
54
|
+
}
|
|
55
|
+
function normalizeGeneratedThreadTitle(raw) {
|
|
56
|
+
return stripThreadTitleWrappers(raw.replace(/\r/g, "").split("\n").find((line) => line.trim() && !line.trim().startsWith("```")) ?? "");
|
|
57
|
+
}
|
|
58
|
+
function stripThreadTitleWrappers(raw) {
|
|
59
|
+
let current = raw.trim();
|
|
60
|
+
let previous = "";
|
|
61
|
+
while (current && current !== previous) {
|
|
62
|
+
previous = current;
|
|
63
|
+
current = current.replace(/^["'`]+|["'`]+$/g, "").trim();
|
|
64
|
+
for (const marker of [
|
|
65
|
+
"**",
|
|
66
|
+
"__",
|
|
67
|
+
"*",
|
|
68
|
+
"_",
|
|
69
|
+
"~~"
|
|
70
|
+
]) current = stripBalancedWrapper(current, marker);
|
|
71
|
+
}
|
|
72
|
+
return current;
|
|
73
|
+
}
|
|
74
|
+
function stripBalancedWrapper(text, marker) {
|
|
75
|
+
if (text.length < marker.length * 2 + 1 || !text.startsWith(marker) || !text.endsWith(marker)) return text;
|
|
76
|
+
const inner = text.slice(marker.length, text.length - marker.length);
|
|
77
|
+
return inner.includes(marker) ? text : inner;
|
|
78
|
+
}
|
|
79
|
+
function normalizeTitleContextField(raw, maxChars) {
|
|
80
|
+
const value = raw?.trim();
|
|
81
|
+
if (!value) return;
|
|
82
|
+
return truncateThreadTitleText(value.replace(/\s+/g, " "), maxChars);
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region extensions/discord/src/monitor/threading.auto-thread.ts
|
|
86
|
+
function resolveTrimmedDiscordMessageChannelId(params) {
|
|
87
|
+
return (params.messageChannelId || resolveDiscordMessageChannelId({ message: params.message })).trim();
|
|
88
|
+
}
|
|
89
|
+
function resolveDiscordAutoThreadContext(params) {
|
|
90
|
+
const createdThreadId = normalizeOptionalStringifiedId(params.createdThreadId) ?? "";
|
|
91
|
+
if (!createdThreadId) return null;
|
|
92
|
+
const parentSessionKey = normalizeOptionalString(params.parentSessionKey) ?? "";
|
|
93
|
+
if (!parentSessionKey) return null;
|
|
94
|
+
const threadSessionKey = params.groupScope === "main" ? parentSessionKey : buildAgentSessionKey({
|
|
95
|
+
agentId: params.agentId,
|
|
96
|
+
channel: params.channel,
|
|
97
|
+
peer: {
|
|
98
|
+
kind: "channel",
|
|
99
|
+
id: createdThreadId
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
const inheritsDistinctParent = threadSessionKey !== parentSessionKey;
|
|
103
|
+
return {
|
|
104
|
+
createdThreadId,
|
|
105
|
+
From: `${params.channel}:channel:${createdThreadId}`,
|
|
106
|
+
To: `channel:${createdThreadId}`,
|
|
107
|
+
OriginatingTo: `channel:${createdThreadId}`,
|
|
108
|
+
SessionKey: threadSessionKey,
|
|
109
|
+
...inheritsDistinctParent ? { ModelParentSessionKey: parentSessionKey } : {},
|
|
110
|
+
...inheritsDistinctParent && params.parentInheritanceEnabled === true ? { ParentSessionKey: parentSessionKey } : {}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
async function resolveDiscordAutoThreadReplyPlan(params) {
|
|
114
|
+
const messageChannelId = resolveTrimmedDiscordMessageChannelId(params);
|
|
115
|
+
const originalReplyTarget = `channel:${params.threadChannel?.id ?? (messageChannelId || "unknown")}`;
|
|
116
|
+
const createdThreadId = await maybeCreateDiscordAutoThread({
|
|
117
|
+
...params,
|
|
118
|
+
messageChannelId: messageChannelId || void 0
|
|
119
|
+
});
|
|
120
|
+
const deliveryPlan = resolveDiscordReplyDeliveryPlan({
|
|
121
|
+
replyTarget: originalReplyTarget,
|
|
122
|
+
replyToMode: params.replyToMode,
|
|
123
|
+
messageId: params.message.id,
|
|
124
|
+
threadChannel: params.threadChannel,
|
|
125
|
+
createdThreadId
|
|
126
|
+
});
|
|
127
|
+
const autoThreadContext = params.isGuildMessage ? resolveDiscordAutoThreadContext({
|
|
128
|
+
...params,
|
|
129
|
+
createdThreadId,
|
|
130
|
+
parentInheritanceEnabled: params.threadParentInheritanceEnabled
|
|
131
|
+
}) : null;
|
|
132
|
+
return {
|
|
133
|
+
...deliveryPlan,
|
|
134
|
+
createdThreadId,
|
|
135
|
+
autoThreadContext
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
async function maybeCreateDiscordAutoThread(params) {
|
|
139
|
+
if (!params.isGuildMessage || !params.channelConfig?.autoThread || params.threadChannel) return;
|
|
140
|
+
if (params.channelType === discord_exports.ChannelType.GuildForum || params.channelType === discord_exports.ChannelType.GuildMedia || params.channelType === discord_exports.ChannelType.GuildVoice || params.channelType === discord_exports.ChannelType.GuildStageVoice) return;
|
|
141
|
+
const messageChannelId = resolveTrimmedDiscordMessageChannelId(params);
|
|
142
|
+
if (!messageChannelId) return;
|
|
143
|
+
const findExistingThread = async () => {
|
|
144
|
+
try {
|
|
145
|
+
const existingThreadId = (await getChannelMessage(params.client.rest, messageChannelId, params.message.id))?.thread?.id;
|
|
146
|
+
if (existingThreadId) {
|
|
147
|
+
logVerbose(`discord: autoThread reusing existing thread ${existingThreadId} on ${messageChannelId}/${params.message.id}`);
|
|
148
|
+
return existingThreadId;
|
|
149
|
+
}
|
|
150
|
+
} catch {}
|
|
151
|
+
};
|
|
152
|
+
try {
|
|
153
|
+
const existingThreadId = await findExistingThread();
|
|
154
|
+
if (existingThreadId) return existingThreadId;
|
|
155
|
+
if (params.message.author?.bot) {
|
|
156
|
+
logVerbose(`discord: autoThread skipped for bot-authored message ${messageChannelId}/${params.message.id}`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const rawThreadSource = params.baseText || params.combinedBody || "Thread";
|
|
160
|
+
const threadName = sanitizeDiscordThreadName(rawThreadSource, params.message.id);
|
|
161
|
+
const archiveDuration = params.channelConfig?.autoArchiveDuration ? Number(params.channelConfig.autoArchiveDuration) : 60;
|
|
162
|
+
const createdId = (await createThread(params.client.rest, messageChannelId, { body: {
|
|
163
|
+
name: threadName,
|
|
164
|
+
auto_archive_duration: archiveDuration
|
|
165
|
+
} }, params.message.id))?.id || "";
|
|
166
|
+
if (createdId && params.channelConfig?.autoThreadName === "generated" && params.cfg && params.agentId) {
|
|
167
|
+
const modelRef = resolveDiscordThreadTitleModelRef({
|
|
168
|
+
cfg: params.cfg,
|
|
169
|
+
channel: params.channel,
|
|
170
|
+
agentId: params.agentId,
|
|
171
|
+
threadId: createdId,
|
|
172
|
+
messageChannelId,
|
|
173
|
+
channelName: params.channelName
|
|
174
|
+
});
|
|
175
|
+
maybeRenameDiscordAutoThread({
|
|
176
|
+
client: params.client,
|
|
177
|
+
threadId: createdId,
|
|
178
|
+
currentName: threadName,
|
|
179
|
+
fallbackId: params.message.id,
|
|
180
|
+
sourceText: rawThreadSource,
|
|
181
|
+
modelRef,
|
|
182
|
+
channelName: params.channelName,
|
|
183
|
+
channelDescription: params.channelDescription,
|
|
184
|
+
cfg: params.cfg,
|
|
185
|
+
agentId: params.agentId
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return createdId || void 0;
|
|
189
|
+
} catch (err) {
|
|
190
|
+
logVerbose(`discord: autoThread creation failed for ${messageChannelId}/${params.message.id}: ${String(err)}`);
|
|
191
|
+
return findExistingThread();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function resolveDiscordThreadTitleModelRef(params) {
|
|
195
|
+
const channel = params.channel?.trim();
|
|
196
|
+
if (!channel) return;
|
|
197
|
+
const parentSessionKey = buildAgentSessionKey({
|
|
198
|
+
agentId: params.agentId,
|
|
199
|
+
channel,
|
|
200
|
+
peer: {
|
|
201
|
+
kind: "channel",
|
|
202
|
+
id: params.messageChannelId
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
const channelLabel = params.channelName?.trim();
|
|
206
|
+
const groupChannel = channelLabel ? `#${channelLabel}` : void 0;
|
|
207
|
+
return resolveChannelModelOverride({
|
|
208
|
+
cfg: params.cfg,
|
|
209
|
+
channel,
|
|
210
|
+
groupId: params.threadId,
|
|
211
|
+
groupChatType: "channel",
|
|
212
|
+
groupChannel,
|
|
213
|
+
groupSubject: groupChannel,
|
|
214
|
+
parentSessionKey
|
|
215
|
+
})?.model;
|
|
216
|
+
}
|
|
217
|
+
async function maybeRenameDiscordAutoThread(params) {
|
|
218
|
+
try {
|
|
219
|
+
const fallbackName = sanitizeDiscordThreadName("", params.fallbackId);
|
|
220
|
+
const generated = await generateThreadTitle({
|
|
221
|
+
...params,
|
|
222
|
+
messageText: params.sourceText
|
|
223
|
+
});
|
|
224
|
+
if (!generated) return;
|
|
225
|
+
const nextName = sanitizeDiscordThreadName(generated, params.fallbackId);
|
|
226
|
+
if (!nextName || nextName === params.currentName || nextName === fallbackName) return;
|
|
227
|
+
await params.client.rest.patch(Routes.channel(params.threadId), { body: { name: nextName } });
|
|
228
|
+
} catch (err) {
|
|
229
|
+
logVerbose(`discord: autoThread rename failed for ${params.threadId}: ${String(err)}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region extensions/discord/src/monitor/threading.ts
|
|
234
|
+
var threading_exports = /* @__PURE__ */ __exportAll({
|
|
235
|
+
maybeCreateDiscordAutoThread: () => maybeCreateDiscordAutoThread,
|
|
236
|
+
resolveDiscordAutoThreadContext: () => resolveDiscordAutoThreadContext,
|
|
237
|
+
resolveDiscordAutoThreadReplyPlan: () => resolveDiscordAutoThreadReplyPlan,
|
|
238
|
+
resolveDiscordReplyDeliveryPlan: () => resolveDiscordReplyDeliveryPlan,
|
|
239
|
+
resolveDiscordReplyTarget: () => resolveDiscordReplyTarget,
|
|
240
|
+
resolveDiscordThreadChannel: () => resolveDiscordThreadChannel,
|
|
241
|
+
resolveDiscordThreadParentInfo: () => resolveDiscordThreadParentInfo,
|
|
242
|
+
resolveDiscordThreadStarter: () => resolveDiscordThreadStarter,
|
|
243
|
+
sanitizeDiscordThreadName: () => sanitizeDiscordThreadName
|
|
244
|
+
});
|
|
245
|
+
//#endregion
|
|
246
|
+
export { resolveDiscordAutoThreadReplyPlan as n, threading_exports as t };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
2
|
+
import { raceWithTimeout } from "openclaw/plugin-sdk/time-runtime";
|
|
2
3
|
//#region extensions/discord/src/monitor/timeouts.ts
|
|
3
4
|
const DISCORD_DEFAULT_LISTENER_TIMEOUT_MS = 12e4;
|
|
4
5
|
const DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS = 18e5;
|
|
@@ -27,7 +28,6 @@ async function runDiscordTaskWithTimeout(params) {
|
|
|
27
28
|
const abortSignals = [...params.abortSignals ?? [], timeoutAbortController?.signal].filter((signal) => Boolean(signal));
|
|
28
29
|
const mergedAbortSignal = abortSignals.length > 1 ? AbortSignal.any(abortSignals) : abortSignals[0];
|
|
29
30
|
let timedOut = false;
|
|
30
|
-
let timeoutHandle = null;
|
|
31
31
|
const runPromise = params.run(mergedAbortSignal).catch((error) => {
|
|
32
32
|
if (!timedOut) throw error;
|
|
33
33
|
if (timeoutAbortController?.signal.aborted && isAbortError(error)) {
|
|
@@ -36,25 +36,17 @@ async function runDiscordTaskWithTimeout(params) {
|
|
|
36
36
|
}
|
|
37
37
|
params.onErrorAfterTimeout?.(error);
|
|
38
38
|
});
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
await runPromise;
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
const timeoutPromise = new Promise((resolve) => {
|
|
45
|
-
timeoutHandle = setTimeout(() => resolve("timeout"), timeoutMs);
|
|
46
|
-
timeoutHandle.unref?.();
|
|
47
|
-
});
|
|
48
|
-
if (await Promise.race([runPromise.then(() => "completed"), timeoutPromise]) === "timeout") {
|
|
49
|
-
timedOut = true;
|
|
50
|
-
timeoutAbortController?.abort();
|
|
51
|
-
await params.onTimeout(timeoutMs);
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
39
|
+
if (!timeoutMs) {
|
|
40
|
+
await runPromise;
|
|
54
41
|
return false;
|
|
55
|
-
} finally {
|
|
56
|
-
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
57
42
|
}
|
|
43
|
+
if (await raceWithTimeout(runPromise.then(() => "completed"), timeoutMs, () => "timeout", { ref: false }) === "timeout") {
|
|
44
|
+
timedOut = true;
|
|
45
|
+
timeoutAbortController?.abort();
|
|
46
|
+
await params.onTimeout(timeoutMs);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
58
50
|
}
|
|
59
51
|
async function withAbortTimeout(params) {
|
|
60
52
|
const timeoutMs = resolveTimerTimeoutMs(params.timeoutMs, 1);
|