@openclaw/discord 2026.9.5 → 2026.9.7
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/assets/icon.png +0 -0
- package/dist/.setup/{account-inspect-BwQj24ht.mjs → account-inspect-De8hOUxG.mjs} +1 -1
- package/dist/.setup/{accounts-CwJQoLjM.mjs → accounts-ChaMcixG.mjs} +1 -4
- package/dist/.setup/{activities-api-DBwRt5ES.mjs → activities-api-tvbsU2e3.mjs} +38 -66
- package/dist/.setup/{api-CBK9zcq5.mjs → api-DVbJwZVt.mjs} +10 -2
- package/dist/.setup/{approval-handler.runtime-Du3n5ypX.mjs → approval-handler.runtime-DxCK2Rux.mjs} +49 -125
- package/dist/.setup/{approval-message-updates-BN7JtScm.mjs → approval-message-updates-BKFqavHZ.mjs} +2 -2
- package/dist/.setup/{audit-C8uaKoa9.mjs → audit-CLg9I71N.mjs} +5 -5
- package/dist/.setup/{channel-ChKdlBgH.mjs → channel-DxlUVU9t.mjs} +125 -228
- package/dist/.setup/{channel-type-DKnjV1XW.mjs → channel-type-DRCrEMss.mjs} +22 -22
- package/dist/.setup/{channel.setup-BlC3-Kzz.mjs → channel.setup-CRo1GjV7.mjs} +6 -9
- package/dist/.setup/{components-MqMWUWnE.mjs → components-Cq1PvIpN.mjs} +42 -71
- package/dist/.setup/{config-schema-CiZz-mtA.mjs → config-schema-oxELUSDx.mjs} +19 -44
- package/dist/.setup/{conversation-binding-route-_rz33QHO.mjs → conversation-binding-route-Caz_XuFH.mjs} +14 -6
- package/dist/.setup/{directory-config-BytTftz-.mjs → directory-config-esqNn0Eo.mjs} +6 -9
- package/dist/.setup/{directory-live--EGTH0DC.mjs → directory-live-DtKRHuGV.mjs} +6 -12
- package/dist/.setup/{discord-BXpHW-cu.mjs → discord-0xJYfdDD.mjs} +82 -386
- package/dist/.setup/{doctor-DxcdkXzz.mjs → doctor-BCl1H5tl.mjs} +21 -36
- package/dist/.setup/{doctor-contract-Co5vRCZ6.mjs → doctor-contract-CvvgwrrG.mjs} +41 -50
- package/dist/.setup/{channel-actions.runtime-CJmiFfps.mjs → handle-action-CUvQWnE7.mjs} +74 -105
- package/dist/.setup/{handle-action.guild-admin-DAFyh_yV.mjs → handle-action.guild-admin-Df-8gVle.mjs} +63 -121
- package/dist/.setup/{live-policy-config-eKQ-PLdy.mjs → live-policy-config-8Pv20CHc.mjs} +2 -3
- package/dist/.setup/{message-handler-DnUrDpaU.mjs → message-handler-B-Jk4oDk.mjs} +18 -93
- package/dist/.setup/message-handler.preflight-pluralkit-CWLUBVcx.mjs +141 -0
- package/dist/.setup/{message-handler.preflight-CtqaF_fb.mjs → message-handler.preflight-v-__NSDq.mjs} +73 -287
- package/dist/.setup/{message-handler.process-Dz1xvuQU.mjs → message-handler.process-BNFFuChn.mjs} +423 -374
- package/dist/.setup/{outbound-adapter-C8v79z9Z.mjs → outbound-adapter-BobT-kse.mjs} +105 -19
- package/dist/.setup/{outbound-session-route-CqWbuMOm.mjs → outbound-session-route-zVGxxceg.mjs} +142 -109
- package/dist/.setup/{pluralkit-CdAt1G0P.mjs → pluralkit-a6_NLfH9.mjs} +1 -1
- package/dist/.setup/{preflight-audio-DrnqFA8U.mjs → preflight-audio-DHGIHEpv.mjs} +2 -1
- package/dist/.setup/{presence-cache-dYSHPWMx.mjs → presence-cache-Di3H3DIU.mjs} +0 -4
- package/dist/.setup/{probe-CupW4we4.mjs → probe-LYrIHlBF.mjs} +13 -4
- package/dist/.setup/{provider-72zIvN-i.mjs → provider-B_G5hASF.mjs} +1112 -1668
- package/dist/.setup/provider-session.runtime-BYlTBFD2.mjs +6 -0
- package/dist/.setup/provider.runtime-CUE3UxER.mjs +2 -0
- package/dist/.setup/{realtime-session.runtime-DTccTgTM.mjs → realtime-session.runtime-oUd9DOcz.mjs} +372 -345
- package/dist/.setup/receive-recovery-CHPOsnLc.mjs +514 -0
- package/dist/.setup/{resolve-allowlist-common-CwMBzbx9.mjs → resolve-allowlist-common-DPdRggu5.mjs} +4 -7
- package/dist/.setup/{resolve-channels-BbvsLQOZ.mjs → resolve-channels-BFPNRmVv.mjs} +21 -40
- package/dist/.setup/{resolve-users-ByFlR7LQ.mjs → resolve-users-0-aBuCy3.mjs} +4 -4
- package/dist/.setup/{retry-DBfcEgmO.mjs → retry-pz_cSha2.mjs} +81 -16
- package/dist/.setup/rolldown-runtime-B4FMCO8f.mjs +28 -0
- package/dist/.setup/{runtime-SchNfUsQ.mjs → runtime-FN000lxA.mjs} +83 -166
- package/dist/.setup/runtime-doctor-migrations-CshUGl36.mjs +159 -0
- package/dist/.setup/{runtime-BVoa7hhx.mjs → runtime-sUksZ--Q.mjs} +2 -5
- package/dist/.setup/{secret-config-contract-DFu9hfU8.mjs → secret-config-contract-uOE2J7yM.mjs} +15 -85
- package/dist/.setup/{security-audit-s5w50-Ly.mjs → security-audit-Cdaegq7C.mjs} +3 -1
- package/dist/.setup/{send-CKDczUNL.mjs → send-CrfEI6Bs.mjs} +73 -114
- package/dist/.setup/{send.components-DWQjXhPV.mjs → send.components-DxQAMfES.mjs} +62 -107
- package/dist/.setup/{send.outbound-D0hQ7s50.mjs → send.outbound-BISKnb-a.mjs} +79 -154
- package/dist/.setup/{send.shared-Zwx6BxQ5.mjs → send.shared-DGFkbkQR.mjs} +10 -25
- package/dist/.setup/{sender-identity-0Ymgvmaj.mjs → sender-identity-B9X5Vb9R.mjs} +2 -3
- package/dist/.setup/setup-plugin-api-BQUBxbhe.mjs +3 -0
- package/dist/.setup/{shared-CaA3Vv4n.mjs → shared-B3wZ4hN-.mjs} +25 -32
- package/dist/.setup/{subagent-hooks-Bired9q6.mjs → subagent-hooks-nlUE9ow7.mjs} +5 -6
- package/dist/.setup/system-events-CdeZnvPV.mjs +33 -0
- package/dist/.setup/{target-resolver-B6MrxbYv.mjs → target-resolver-BuLapkhy.mjs} +9 -12
- package/dist/.setup/targets-0KUcEIYx.mjs +3 -0
- package/dist/.setup/{thread-bindings-CK5272V3.mjs → thread-bindings-D7TfgjR_.mjs} +33 -35
- package/dist/.setup/thread-bindings.manager-DN-NissX.mjs +819 -0
- package/dist/.setup/thread-bindings.session-updates-CshfKghV.mjs +359 -0
- package/dist/.setup/{thread-bindings.state-BThFQEga.mjs → thread-bindings.state-g6v9zAym.mjs} +21 -62
- package/dist/.setup/{transcripts-source-CuWYgayu.mjs → transcripts-source-p8EV179h.mjs} +133 -238
- package/dist/.setup/{typing-BKZL5fGj.mjs → typing-BiHCzBRu.mjs} +2 -1
- package/dist/.setup/{voice-runtime-DHVQ2mFz.mjs → voice-runtime-B46rcwrG.mjs} +633 -1085
- 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/directory-contract-api.js +1 -1
- package/dist/doctor-contract-api.js +4 -4
- package/dist/index.js +1 -1
- package/dist/runtime-api.js +20 -20
- package/dist/secret-contract-api.js +1 -1
- package/dist/security-audit-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 +1056 -0
- package/dist/subagent-hooks-api.js +3 -4
- package/dist/transcripts-source-api.js +1 -1
- package/node_modules/@napi-rs/wasm-runtime/dist/emnapi-plugins.cjs +8 -4
- package/node_modules/@napi-rs/wasm-runtime/dist/emnapi-plugins.js +8 -4
- package/node_modules/@napi-rs/wasm-runtime/dist/fs-proxy.cjs +1 -1
- package/node_modules/@napi-rs/wasm-runtime/dist/fs.js +770 -695
- package/node_modules/@napi-rs/wasm-runtime/fs-proxy.js +3 -2
- package/node_modules/@napi-rs/wasm-runtime/package.json +1 -1
- package/node_modules/@tybys/wasm-util/LICENSE +21 -0
- package/node_modules/@tybys/wasm-util/package.json +1 -1
- package/node_modules/@types/node/README.md +2 -2
- package/node_modules/@types/node/child_process.d.ts +1 -1
- package/node_modules/@types/node/crypto.d.ts +20 -8
- package/node_modules/@types/node/ffi.d.ts +14 -0
- package/node_modules/@types/node/http2.d.ts +3 -2
- package/node_modules/@types/node/net.d.ts +16 -4
- package/node_modules/@types/node/package.json +2 -17
- package/node_modules/@types/node/process.d.ts +1 -0
- package/node_modules/@types/node/quic.d.ts +39 -1
- package/node_modules/@types/node/stream/iter.d.ts +9 -12
- package/node_modules/@types/node/test/reporters.d.ts +1 -0
- package/node_modules/@types/node/test.d.ts +72 -0
- package/node_modules/@types/node/tls.d.ts +14 -10
- package/node_modules/@types/node/vm.d.ts +2 -1
- package/node_modules/@types/node/web-globals/streams.d.ts +4 -0
- package/node_modules/@types/node/worker_threads.d.ts +4 -1
- package/node_modules/typebox/build/compile/code.mjs +1 -2
- package/node_modules/typebox/build/compile/validator.mjs +5 -1
- package/node_modules/typebox/build/format/iri.mjs +16 -9
- package/node_modules/typebox/build/guard/emit.mjs +2 -2
- package/node_modules/typebox/build/guard/guard.d.mts +7 -5
- package/node_modules/typebox/build/guard/guard.mjs +14 -9
- package/node_modules/typebox/build/guard/index.mjs +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
- package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
- package/node_modules/typebox/build/schema/build.mjs +2 -3
- package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
- package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
- package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
- package/node_modules/typebox/build/schema/parse.mjs +3 -0
- package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
- package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
- package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
- package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
- package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
- package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
- package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
- package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
- package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
- package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +3 -1
- package/node_modules/zod/README.md +2 -2
- package/node_modules/zod/compile.cjs +19 -0
- package/node_modules/zod/index.cjs +19 -0
- package/node_modules/zod/locales/index.cjs +19 -0
- package/node_modules/zod/mini/index.cjs +19 -0
- package/node_modules/zod/package.json +8 -7
- package/node_modules/zod/src/v3/helpers/errorUtil.ts +1 -1
- package/node_modules/zod/src/v4/classic/external.ts +2 -0
- package/node_modules/zod/src/v4/classic/from-json-schema.ts +248 -25
- package/node_modules/zod/src/v4/classic/schemas.ts +243 -168
- package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +60 -9
- package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +6 -0
- package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +2 -2
- package/node_modules/zod/src/v4/classic/tests/cyclic-data.test.ts +265 -0
- package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +112 -6
- package/node_modules/zod/src/v4/classic/tests/enum.test.ts +9 -0
- package/node_modules/zod/src/v4/classic/tests/error.test.ts +130 -1
- package/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +157 -0
- package/node_modules/zod/src/v4/classic/tests/iban.test.ts +81 -0
- package/node_modules/zod/src/v4/classic/tests/instance-footprint.test.ts +40 -2
- package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +27 -7
- package/node_modules/zod/src/v4/classic/tests/issue-schema.test.ts +88 -56
- package/node_modules/zod/src/v4/classic/tests/number.test.ts +39 -0
- package/node_modules/zod/src/v4/classic/tests/object.test.ts +56 -0
- package/node_modules/zod/src/v4/classic/tests/optin-ladder.test.ts +3 -2
- package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +70 -0
- package/node_modules/zod/src/v4/classic/tests/properties.test.ts +141 -0
- package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +46 -1
- package/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +19 -0
- package/node_modules/zod/src/v4/classic/tests/string.test.ts +95 -1
- package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +33 -1
- package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +234 -38
- package/node_modules/zod/src/v4/classic/tests/validate.test.ts +569 -0
- package/node_modules/zod/src/v4/core/api.ts +44 -28
- package/node_modules/zod/src/v4/core/checks.ts +62 -102
- package/node_modules/zod/src/v4/core/compile.ts +218 -93
- package/node_modules/zod/src/v4/core/core.ts +1 -3
- package/node_modules/zod/src/v4/core/doc.ts +6 -2
- package/node_modules/zod/src/v4/core/errors.ts +3 -6
- package/node_modules/zod/src/v4/core/json-schema-generator.ts +2 -2
- package/node_modules/zod/src/v4/core/json-schema-processors.ts +185 -81
- package/node_modules/zod/src/v4/core/memoizer.ts +75 -28
- package/node_modules/zod/src/v4/core/parse.ts +37 -16
- package/node_modules/zod/src/v4/core/regexes.ts +14 -4
- package/node_modules/zod/src/v4/core/schemas.ts +296 -132
- package/node_modules/zod/src/v4/core/tests/cached.test.ts +54 -0
- package/node_modules/zod/src/v4/core/tests/compile-differential.test.ts +35 -0
- package/node_modules/zod/src/v4/core/tests/compile-generative.test.ts +445 -0
- package/node_modules/zod/src/v4/core/tests/compile.test.ts +399 -2
- package/node_modules/zod/src/v4/core/tests/email-regex.test.ts +140 -0
- package/node_modules/zod/src/v4/core/tests/locales/tg.test.ts +85 -0
- package/node_modules/zod/src/v4/core/tests/polyfill-collision.test.ts +46 -0
- package/node_modules/zod/src/v4/core/tests/url-no-canparse.test.ts +118 -16
- package/node_modules/zod/src/v4/core/to-json-schema.ts +9 -7
- package/node_modules/zod/src/v4/core/util.ts +218 -147
- package/node_modules/zod/src/v4/core/versions.ts +2 -2
- package/node_modules/zod/src/v4/locales/ar.ts +2 -0
- package/node_modules/zod/src/v4/locales/az.ts +2 -0
- package/node_modules/zod/src/v4/locales/be.ts +2 -0
- package/node_modules/zod/src/v4/locales/bg.ts +2 -0
- package/node_modules/zod/src/v4/locales/bn.ts +2 -0
- package/node_modules/zod/src/v4/locales/ca.ts +2 -0
- package/node_modules/zod/src/v4/locales/ckb.ts +2 -0
- package/node_modules/zod/src/v4/locales/cs.ts +2 -0
- package/node_modules/zod/src/v4/locales/da.ts +2 -0
- package/node_modules/zod/src/v4/locales/de.ts +2 -0
- package/node_modules/zod/src/v4/locales/el.ts +2 -0
- package/node_modules/zod/src/v4/locales/en.ts +2 -0
- package/node_modules/zod/src/v4/locales/eo.ts +2 -0
- package/node_modules/zod/src/v4/locales/es.ts +2 -0
- package/node_modules/zod/src/v4/locales/fa.ts +2 -0
- package/node_modules/zod/src/v4/locales/fi.ts +2 -0
- package/node_modules/zod/src/v4/locales/fr-CA.ts +2 -0
- package/node_modules/zod/src/v4/locales/fr.ts +2 -0
- package/node_modules/zod/src/v4/locales/gu.ts +2 -0
- package/node_modules/zod/src/v4/locales/he.ts +2 -0
- package/node_modules/zod/src/v4/locales/hi.ts +2 -0
- package/node_modules/zod/src/v4/locales/hr.ts +2 -0
- package/node_modules/zod/src/v4/locales/hu.ts +2 -0
- package/node_modules/zod/src/v4/locales/hy.ts +2 -0
- package/node_modules/zod/src/v4/locales/id.ts +2 -0
- package/node_modules/zod/src/v4/locales/index.ts +1 -0
- package/node_modules/zod/src/v4/locales/is.ts +2 -0
- package/node_modules/zod/src/v4/locales/it.ts +2 -0
- package/node_modules/zod/src/v4/locales/ja.ts +2 -0
- package/node_modules/zod/src/v4/locales/ka.ts +2 -0
- package/node_modules/zod/src/v4/locales/km.ts +2 -0
- package/node_modules/zod/src/v4/locales/kn.ts +2 -0
- package/node_modules/zod/src/v4/locales/ko.ts +2 -0
- package/node_modules/zod/src/v4/locales/lt.ts +2 -0
- package/node_modules/zod/src/v4/locales/mk.ts +2 -0
- package/node_modules/zod/src/v4/locales/ms.ts +2 -0
- package/node_modules/zod/src/v4/locales/ne.ts +2 -0
- package/node_modules/zod/src/v4/locales/nl.ts +2 -0
- package/node_modules/zod/src/v4/locales/nn.ts +2 -0
- package/node_modules/zod/src/v4/locales/no.ts +2 -0
- package/node_modules/zod/src/v4/locales/ota.ts +2 -0
- package/node_modules/zod/src/v4/locales/pl.ts +2 -0
- package/node_modules/zod/src/v4/locales/ps.ts +2 -0
- package/node_modules/zod/src/v4/locales/pt-BR.ts +2 -0
- package/node_modules/zod/src/v4/locales/pt.ts +2 -0
- package/node_modules/zod/src/v4/locales/ro.ts +2 -0
- package/node_modules/zod/src/v4/locales/ru.ts +2 -0
- package/node_modules/zod/src/v4/locales/sk.ts +2 -0
- package/node_modules/zod/src/v4/locales/sl.ts +2 -0
- package/node_modules/zod/src/v4/locales/sv.ts +2 -0
- package/node_modules/zod/src/v4/locales/ta.ts +2 -0
- package/node_modules/zod/src/v4/locales/tg.ts +135 -0
- package/node_modules/zod/src/v4/locales/th.ts +2 -0
- package/node_modules/zod/src/v4/locales/tk.ts +2 -0
- package/node_modules/zod/src/v4/locales/tr.ts +2 -0
- package/node_modules/zod/src/v4/locales/uk.ts +2 -0
- package/node_modules/zod/src/v4/locales/ur.ts +2 -0
- package/node_modules/zod/src/v4/locales/uz.ts +2 -0
- package/node_modules/zod/src/v4/locales/vi.ts +2 -0
- package/node_modules/zod/src/v4/locales/yo.ts +2 -0
- package/node_modules/zod/src/v4/locales/zh-CN.ts +2 -0
- package/node_modules/zod/src/v4/locales/zh-TW.ts +2 -0
- package/node_modules/zod/src/v4/mini/external.ts +2 -0
- package/node_modules/zod/src/v4/mini/schemas.ts +32 -7
- package/node_modules/zod/src/v4/mini/tests/checks.test.ts +1 -1
- package/node_modules/zod/src/v4/mini/tests/computed.test.ts +11 -17
- package/node_modules/zod/src/v4/mini/tests/index.test.ts +86 -0
- package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +16 -0
- package/node_modules/zod/src/v4/mini/tests/string.test.ts +23 -0
- package/node_modules/zod/v3/ZodError.cjs +19 -0
- package/node_modules/zod/v3/errors.cjs +19 -0
- package/node_modules/zod/v3/external.cjs +19 -0
- package/node_modules/zod/v3/helpers/enumUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/errorUtil.cjs +20 -1
- package/node_modules/zod/v3/helpers/errorUtil.js +1 -1
- package/node_modules/zod/v3/helpers/parseUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/partialUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/typeAliases.cjs +19 -0
- package/node_modules/zod/v3/helpers/util.cjs +19 -0
- package/node_modules/zod/v3/index.cjs +19 -0
- package/node_modules/zod/v3/standard-schema.cjs +19 -0
- package/node_modules/zod/v3/types.cjs +19 -0
- package/node_modules/zod/v4/classic/checks.cjs +19 -0
- package/node_modules/zod/v4/classic/coerce.cjs +19 -0
- package/node_modules/zod/v4/classic/compat.cjs +19 -0
- package/node_modules/zod/v4/classic/deep-partial.cjs +19 -0
- package/node_modules/zod/v4/classic/errors.cjs +19 -0
- package/node_modules/zod/v4/classic/external.cjs +22 -1
- package/node_modules/zod/v4/classic/external.d.cts +1 -1
- package/node_modules/zod/v4/classic/external.d.ts +1 -1
- package/node_modules/zod/v4/classic/external.js +1 -1
- package/node_modules/zod/v4/classic/from-json-schema.cjs +264 -24
- package/node_modules/zod/v4/classic/from-json-schema.js +245 -24
- package/node_modules/zod/v4/classic/in-out.cjs +19 -0
- package/node_modules/zod/v4/classic/index.cjs +19 -0
- package/node_modules/zod/v4/classic/iso.cjs +19 -0
- package/node_modules/zod/v4/classic/parse.cjs +19 -0
- package/node_modules/zod/v4/classic/schemas.cjs +100 -35
- package/node_modules/zod/v4/classic/schemas.d.cts +15 -1
- package/node_modules/zod/v4/classic/schemas.d.ts +15 -1
- package/node_modules/zod/v4/classic/schemas.js +77 -33
- package/node_modules/zod/v4/core/api.cjs +45 -22
- package/node_modules/zod/v4/core/api.d.cts +12 -6
- package/node_modules/zod/v4/core/api.d.ts +12 -6
- package/node_modules/zod/v4/core/api.js +25 -22
- package/node_modules/zod/v4/core/checks.cjs +51 -97
- package/node_modules/zod/v4/core/checks.d.cts +17 -1
- package/node_modules/zod/v4/core/checks.d.ts +17 -1
- package/node_modules/zod/v4/core/checks.js +31 -96
- package/node_modules/zod/v4/core/compile.cjs +173 -78
- package/node_modules/zod/v4/core/compile.d.cts +18 -4
- package/node_modules/zod/v4/core/compile.d.ts +18 -4
- package/node_modules/zod/v4/core/compile.js +154 -79
- package/node_modules/zod/v4/core/core.cjs +20 -1
- package/node_modules/zod/v4/core/core.js +1 -1
- package/node_modules/zod/v4/core/doc.cjs +26 -2
- package/node_modules/zod/v4/core/doc.js +7 -2
- package/node_modules/zod/v4/core/errors.cjs +21 -5
- package/node_modules/zod/v4/core/errors.js +2 -5
- package/node_modules/zod/v4/core/index.cjs +19 -0
- package/node_modules/zod/v4/core/json-schema-generator.cjs +20 -1
- package/node_modules/zod/v4/core/json-schema-generator.js +2 -2
- package/node_modules/zod/v4/core/json-schema-processors.cjs +188 -72
- package/node_modules/zod/v4/core/json-schema-processors.d.cts +16 -0
- package/node_modules/zod/v4/core/json-schema-processors.d.ts +16 -0
- package/node_modules/zod/v4/core/json-schema-processors.js +170 -74
- package/node_modules/zod/v4/core/json-schema.cjs +19 -0
- package/node_modules/zod/v4/core/memoizer.cjs +111 -23
- package/node_modules/zod/v4/core/memoizer.js +69 -23
- package/node_modules/zod/v4/core/parse.cjs +56 -16
- package/node_modules/zod/v4/core/parse.js +37 -16
- package/node_modules/zod/v4/core/regexes.cjs +31 -6
- package/node_modules/zod/v4/core/regexes.d.cts +3 -0
- package/node_modules/zod/v4/core/regexes.d.ts +3 -0
- package/node_modules/zod/v4/core/regexes.js +10 -4
- package/node_modules/zod/v4/core/registries.cjs +19 -0
- package/node_modules/zod/v4/core/schemas.cjs +302 -114
- package/node_modules/zod/v4/core/schemas.d.cts +28 -8
- package/node_modules/zod/v4/core/schemas.d.ts +28 -8
- package/node_modules/zod/v4/core/schemas.js +279 -113
- package/node_modules/zod/v4/core/standard-schema.cjs +19 -0
- package/node_modules/zod/v4/core/to-json-schema.cjs +28 -7
- package/node_modules/zod/v4/core/to-json-schema.d.cts +4 -3
- package/node_modules/zod/v4/core/to-json-schema.d.ts +4 -3
- package/node_modules/zod/v4/core/to-json-schema.js +7 -6
- package/node_modules/zod/v4/core/util.cjs +177 -143
- package/node_modules/zod/v4/core/util.d.cts +25 -4
- package/node_modules/zod/v4/core/util.d.ts +25 -4
- package/node_modules/zod/v4/core/util.js +156 -143
- package/node_modules/zod/v4/core/versions.cjs +21 -2
- package/node_modules/zod/v4/core/versions.d.cts +1 -1
- package/node_modules/zod/v4/core/versions.d.ts +1 -1
- package/node_modules/zod/v4/core/versions.js +2 -2
- package/node_modules/zod/v4/core/visit.cjs +19 -0
- package/node_modules/zod/v4/index.cjs +19 -0
- package/node_modules/zod/v4/locales/ar.cjs +2 -0
- package/node_modules/zod/v4/locales/ar.js +2 -0
- package/node_modules/zod/v4/locales/az.cjs +2 -0
- package/node_modules/zod/v4/locales/az.js +2 -0
- package/node_modules/zod/v4/locales/be.cjs +2 -0
- package/node_modules/zod/v4/locales/be.js +2 -0
- package/node_modules/zod/v4/locales/bg.cjs +2 -0
- package/node_modules/zod/v4/locales/bg.js +2 -0
- package/node_modules/zod/v4/locales/bn.cjs +2 -0
- package/node_modules/zod/v4/locales/bn.js +2 -0
- package/node_modules/zod/v4/locales/ca.cjs +2 -0
- package/node_modules/zod/v4/locales/ca.js +2 -0
- package/node_modules/zod/v4/locales/ckb.cjs +2 -0
- package/node_modules/zod/v4/locales/ckb.js +2 -0
- package/node_modules/zod/v4/locales/cs.cjs +2 -0
- package/node_modules/zod/v4/locales/cs.js +2 -0
- package/node_modules/zod/v4/locales/da.cjs +2 -0
- package/node_modules/zod/v4/locales/da.js +2 -0
- package/node_modules/zod/v4/locales/de.cjs +2 -0
- package/node_modules/zod/v4/locales/de.js +2 -0
- package/node_modules/zod/v4/locales/el.cjs +2 -0
- package/node_modules/zod/v4/locales/el.js +2 -0
- package/node_modules/zod/v4/locales/en.cjs +2 -0
- package/node_modules/zod/v4/locales/en.js +2 -0
- package/node_modules/zod/v4/locales/eo.cjs +2 -0
- package/node_modules/zod/v4/locales/eo.js +2 -0
- package/node_modules/zod/v4/locales/es.cjs +2 -0
- package/node_modules/zod/v4/locales/es.js +2 -0
- package/node_modules/zod/v4/locales/fa.cjs +2 -0
- package/node_modules/zod/v4/locales/fa.js +2 -0
- package/node_modules/zod/v4/locales/fi.cjs +2 -0
- package/node_modules/zod/v4/locales/fi.js +2 -0
- package/node_modules/zod/v4/locales/fr-CA.cjs +2 -0
- package/node_modules/zod/v4/locales/fr-CA.js +2 -0
- package/node_modules/zod/v4/locales/fr.cjs +2 -0
- package/node_modules/zod/v4/locales/fr.js +2 -0
- package/node_modules/zod/v4/locales/gu.cjs +2 -0
- package/node_modules/zod/v4/locales/gu.js +2 -0
- package/node_modules/zod/v4/locales/he.cjs +2 -0
- package/node_modules/zod/v4/locales/he.js +2 -0
- package/node_modules/zod/v4/locales/hi.cjs +2 -0
- package/node_modules/zod/v4/locales/hi.js +2 -0
- package/node_modules/zod/v4/locales/hr.cjs +2 -0
- package/node_modules/zod/v4/locales/hr.js +2 -0
- package/node_modules/zod/v4/locales/hu.cjs +2 -0
- package/node_modules/zod/v4/locales/hu.js +2 -0
- package/node_modules/zod/v4/locales/hy.cjs +2 -0
- package/node_modules/zod/v4/locales/hy.js +2 -0
- package/node_modules/zod/v4/locales/id.cjs +2 -0
- package/node_modules/zod/v4/locales/id.js +2 -0
- package/node_modules/zod/v4/locales/index.cjs +22 -1
- package/node_modules/zod/v4/locales/index.d.cts +1 -0
- package/node_modules/zod/v4/locales/index.d.ts +1 -0
- package/node_modules/zod/v4/locales/index.js +1 -0
- package/node_modules/zod/v4/locales/is.cjs +2 -0
- package/node_modules/zod/v4/locales/is.js +2 -0
- package/node_modules/zod/v4/locales/it.cjs +2 -0
- package/node_modules/zod/v4/locales/it.js +2 -0
- package/node_modules/zod/v4/locales/ja.cjs +2 -0
- package/node_modules/zod/v4/locales/ja.js +2 -0
- package/node_modules/zod/v4/locales/ka.cjs +2 -0
- package/node_modules/zod/v4/locales/ka.js +2 -0
- package/node_modules/zod/v4/locales/km.cjs +2 -0
- package/node_modules/zod/v4/locales/km.js +2 -0
- package/node_modules/zod/v4/locales/kn.cjs +2 -0
- package/node_modules/zod/v4/locales/kn.js +2 -0
- package/node_modules/zod/v4/locales/ko.cjs +2 -0
- package/node_modules/zod/v4/locales/ko.js +2 -0
- package/node_modules/zod/v4/locales/lt.cjs +2 -0
- package/node_modules/zod/v4/locales/lt.js +2 -0
- package/node_modules/zod/v4/locales/mk.cjs +2 -0
- package/node_modules/zod/v4/locales/mk.js +2 -0
- package/node_modules/zod/v4/locales/ms.cjs +2 -0
- package/node_modules/zod/v4/locales/ms.js +2 -0
- package/node_modules/zod/v4/locales/ne.cjs +2 -0
- package/node_modules/zod/v4/locales/ne.js +2 -0
- package/node_modules/zod/v4/locales/nl.cjs +2 -0
- package/node_modules/zod/v4/locales/nl.js +2 -0
- package/node_modules/zod/v4/locales/nn.cjs +2 -0
- package/node_modules/zod/v4/locales/nn.js +2 -0
- package/node_modules/zod/v4/locales/no.cjs +2 -0
- package/node_modules/zod/v4/locales/no.js +2 -0
- package/node_modules/zod/v4/locales/ota.cjs +2 -0
- package/node_modules/zod/v4/locales/ota.js +2 -0
- package/node_modules/zod/v4/locales/pl.cjs +2 -0
- package/node_modules/zod/v4/locales/pl.js +2 -0
- package/node_modules/zod/v4/locales/ps.cjs +2 -0
- package/node_modules/zod/v4/locales/ps.js +2 -0
- package/node_modules/zod/v4/locales/pt-BR.cjs +2 -0
- package/node_modules/zod/v4/locales/pt-BR.js +2 -0
- package/node_modules/zod/v4/locales/pt.cjs +2 -0
- package/node_modules/zod/v4/locales/pt.js +2 -0
- package/node_modules/zod/v4/locales/ro.cjs +2 -0
- package/node_modules/zod/v4/locales/ro.js +2 -0
- package/node_modules/zod/v4/locales/ru.cjs +2 -0
- package/node_modules/zod/v4/locales/ru.js +2 -0
- package/node_modules/zod/v4/locales/sk.cjs +2 -0
- package/node_modules/zod/v4/locales/sk.js +2 -0
- package/node_modules/zod/v4/locales/sl.cjs +2 -0
- package/node_modules/zod/v4/locales/sl.js +2 -0
- package/node_modules/zod/v4/locales/sv.cjs +2 -0
- package/node_modules/zod/v4/locales/sv.js +2 -0
- package/node_modules/zod/v4/locales/ta.cjs +2 -0
- package/node_modules/zod/v4/locales/ta.js +2 -0
- package/node_modules/zod/v4/locales/tg.cjs +144 -0
- package/node_modules/zod/v4/locales/tg.d.cts +5 -0
- package/node_modules/zod/v4/locales/tg.d.ts +4 -0
- package/node_modules/zod/v4/locales/tg.js +117 -0
- package/node_modules/zod/v4/locales/th.cjs +2 -0
- package/node_modules/zod/v4/locales/th.js +2 -0
- package/node_modules/zod/v4/locales/tk.cjs +2 -0
- package/node_modules/zod/v4/locales/tk.js +2 -0
- package/node_modules/zod/v4/locales/tr.cjs +2 -0
- package/node_modules/zod/v4/locales/tr.js +2 -0
- package/node_modules/zod/v4/locales/uk.cjs +2 -0
- package/node_modules/zod/v4/locales/uk.js +2 -0
- package/node_modules/zod/v4/locales/ur.cjs +2 -0
- package/node_modules/zod/v4/locales/ur.js +2 -0
- package/node_modules/zod/v4/locales/uz.cjs +2 -0
- package/node_modules/zod/v4/locales/uz.js +2 -0
- package/node_modules/zod/v4/locales/vi.cjs +2 -0
- package/node_modules/zod/v4/locales/vi.js +2 -0
- package/node_modules/zod/v4/locales/yo.cjs +2 -0
- package/node_modules/zod/v4/locales/yo.js +2 -0
- package/node_modules/zod/v4/locales/zh-CN.cjs +2 -0
- package/node_modules/zod/v4/locales/zh-CN.js +2 -0
- package/node_modules/zod/v4/locales/zh-TW.cjs +2 -0
- package/node_modules/zod/v4/locales/zh-TW.js +2 -0
- package/node_modules/zod/v4/mini/checks.cjs +19 -0
- package/node_modules/zod/v4/mini/coerce.cjs +19 -0
- package/node_modules/zod/v4/mini/deep-partial.cjs +19 -0
- package/node_modules/zod/v4/mini/external.cjs +22 -1
- package/node_modules/zod/v4/mini/external.d.cts +1 -1
- package/node_modules/zod/v4/mini/external.d.ts +1 -1
- package/node_modules/zod/v4/mini/external.js +1 -1
- package/node_modules/zod/v4/mini/in-out.cjs +19 -0
- package/node_modules/zod/v4/mini/index.cjs +19 -0
- package/node_modules/zod/v4/mini/iso.cjs +19 -0
- package/node_modules/zod/v4/mini/parse.cjs +19 -0
- package/node_modules/zod/v4/mini/schemas.cjs +44 -8
- package/node_modules/zod/v4/mini/schemas.d.cts +6 -1
- package/node_modules/zod/v4/mini/schemas.d.ts +6 -1
- package/node_modules/zod/v4/mini/schemas.js +21 -6
- package/node_modules/zod/v4-mini/index.cjs +19 -0
- package/openclaw.plugin.json +21 -1
- package/package.json +9 -6
- package/dist/.setup/agent-components.runtime-CEPrf2SY.mjs +0 -4
- package/dist/.setup/message-handler.history-CJOsN9w5.mjs +0 -28
- package/dist/.setup/probe.runtime-DBQ_AGPe.mjs +0 -2
- package/dist/.setup/provider-session.runtime-BW7QrF5C.mjs +0 -6
- package/dist/.setup/provider.runtime-DuhmKdDU.mjs +0 -2
- package/dist/.setup/security-audit.runtime-DHtYenx9.mjs +0 -2
- package/dist/.setup/setup-plugin-api-CINIEBLa.mjs +0 -3
- package/dist/.setup/system-events-B2YEEMbS.mjs +0 -34
- package/dist/.setup/targets-D1mAB5yO.mjs +0 -3
- package/dist/.setup/thread-bindings.manager-eexkKyrG.mjs +0 -678
- package/dist/.setup/thread-bindings.session-updates-DCQq1WZ5.mjs +0 -55
- /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { c as resolveDiscordAccount, f as resolveDiscordAccountDmPolicy, h as resolveDiscordToken, l as resolveDiscordAccountAllowFrom, m as normalizeDiscordToken, o as mergeDiscordAccountConfig, p as resolveDiscordMaxLinesPerMessage } from "./accounts-
|
|
5
|
-
import { a as registerDiscordComponentEntries, o as resolveDiscordComponentEntryWithPersistence, s as resolveDiscordModalEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-
|
|
1
|
+
import { C as parseDiscordActivityCustomIdForInteraction, D as parseDiscordModalCustomIdForInteraction, E as parseDiscordModalCustomId, O as decodeCustomIdComponent, T as parseDiscordComponentCustomIdForInteraction, c as parseExecApprovalData, d as buildDiscordComponentMessage, k as encodeCustomIdComponent, o as parseDiscordQuestionData, w as parseDiscordComponentCustomId, y as buildDiscordActivityCustomId } from "./components-Cq1PvIpN.mjs";
|
|
2
|
+
import { $ as BaseMessageInteractiveComponent, B as Container, D as Message, E as Guild, J as Separator, K as Row, O as User, P as Modal, R as Button, T as CommandWithSubcommands, X as TextDisplay, Y as StringSelectMenu, a as MessageCreateListener, c as PresenceUpdateListener, d as ThreadDeleteListener, f as ThreadUpdateListener, h as Plugin, i as InteractionCreateListener, k as hasDiscordV2Components, l as ReadyListener, m as Client, n as GuildCreateListener, o as MessageReactionAddListener, r as GuildDeleteListener, s as MessageReactionRemoveListener, t as discord_exports, v as RateLimitError, w as Command } from "./discord-0xJYfdDD.mjs";
|
|
3
|
+
import { D as getDiscordEndpointRuntime, E as assertDiscordEndpointGatewayUrl, S as formatDiscordUserTag, _ as resolveDiscordOwnerAllowFrom, a as normalizeDiscordDisplaySlug, b as shouldEmitDiscordReactionNotification, c as resolveDiscordChannelConfig, f as resolveDiscordGuildEntry, g as resolveDiscordOwnerAccess, i as normalizeDiscordAllowList, l as resolveDiscordChannelConfigWithFallback, m as resolveDiscordMemberAllowed, o as normalizeDiscordSlug, p as resolveDiscordMemberAccessState, r as isDiscordGroupAllowedByPolicy, s as resolveDiscordAllowListMatch, t as isDiscordThreadChannelType, u as resolveDiscordChannelPolicyCommandAuthorizer, w as resolveTimestampMs, x as formatDiscordReactionEmoji, y as resolveGroupDmAllow } from "./channel-type-DRCrEMss.mjs";
|
|
4
|
+
import { c as resolveDiscordAccount, f as resolveDiscordAccountDmPolicy, h as resolveDiscordToken, l as resolveDiscordAccountAllowFrom, m as normalizeDiscordToken, o as mergeDiscordAccountConfig, p as resolveDiscordMaxLinesPerMessage } from "./accounts-ChaMcixG.mjs";
|
|
5
|
+
import { a as registerDiscordComponentEntries, o as resolveDiscordComponentEntryWithPersistence, s as resolveDiscordModalEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-DxQAMfES.mjs";
|
|
6
6
|
import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.mjs";
|
|
7
|
-
import { a as isDiscordRateLimitResponseBody,
|
|
8
|
-
import { o as chunkDiscordTextWithMode } from "./retry-
|
|
9
|
-
import { B as
|
|
10
|
-
import { o as formatMention, t as sendMessageDiscord } from "./send.outbound-
|
|
11
|
-
import { n as getDiscordActivitiesRuntime } from "./runtime-
|
|
7
|
+
import { a as isDiscordRateLimitResponseBody, s as summarizeDiscordResponseBody } from "./api-DVbJwZVt.mjs";
|
|
8
|
+
import { o as chunkDiscordTextWithMode } from "./retry-pz_cSha2.mjs";
|
|
9
|
+
import { B as withValidatedDiscordProxy, C as hasAnyChannelPermissionDiscord, L as DISCORD_REST_TIMEOUT_MS, N as createDiscordRestClient, U as registerGateway, W as unregisterGateway, y as canViewDiscordGuildChannel, z as validateDiscordProxyUrl } from "./send.shared-DGFkbkQR.mjs";
|
|
10
|
+
import { o as formatMention, t as sendMessageDiscord } from "./send.outbound-BISKnb-a.mjs";
|
|
11
|
+
import { n as getDiscordActivitiesRuntime } from "./runtime-sUksZ--Q.mjs";
|
|
12
12
|
import { t as resolveDiscordCommandOwnerAllowFrom } from "./command-owners-D78sAoOz.mjs";
|
|
13
13
|
import { n as resolveDiscordChannelInfoSafe, o as resolveDiscordChannelTopicSafe, r as resolveDiscordChannelNameSafe } from "./channel-access-C12aDZ0p.mjs";
|
|
14
|
-
import { D as
|
|
15
|
-
import { i as setPresence, t as clearPresences } from "./presence-cache-
|
|
16
|
-
import { _ as readMessagesDiscord, s as sendVoiceMessageDiscord } from "./send-
|
|
14
|
+
import { D as resolveDiscordReferencedReplyMessage, O as resolveDiscordReferencedReplyMessageId, a as resolveDiscordVoiceEnabled, i as setDiscordTranscriptsVoiceManager, l as resolveDiscordThreadLikeChannelContext, o as authorizeDiscordVoiceIngress, s as resolveDiscordVoiceAccess, u as resolveFetchedDiscordThreadLikeChannelContext } from "./transcripts-source-p8EV179h.mjs";
|
|
15
|
+
import { i as setPresence, t as clearPresences } from "./presence-cache-Di3H3DIU.mjs";
|
|
16
|
+
import { _ as readMessagesDiscord, s as sendVoiceMessageDiscord } from "./send-CrfEI6Bs.mjs";
|
|
17
17
|
import { c as raceWithTimeout, u as withAbortTimeout } from "./timeouts-D86uWLt_.mjs";
|
|
18
|
-
import { D as isDiscordExecApprovalClientEnabled, T as getDiscordExecApprovalApprovers, a as resolveDiscordComponentSpec, c as formatDiscordApprovalDisplayValue, d as resolveDiscordBoundConversationRoute, h as resolveDiscordConversationIdentity, l as buildDiscordConversationRouteContext, n as DISCORD_PRESENTATION_CAPABILITIES, p as resolveDiscordEffectiveRoute, r as buildDiscordPresentationPayload, s as DISCORD_APPROVAL_ALLOWED_MENTIONS } from "./outbound-session-route-
|
|
19
|
-
import { n as discordIngressIdentity, t as selectDiscordLivePolicyConfig } from "./live-policy-config-
|
|
20
|
-
import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-
|
|
21
|
-
import { t as resolveDiscordUserAllowlist } from "./resolve-users-
|
|
22
|
-
import {
|
|
23
|
-
import { a as probeDiscordApplicationId, r as parseApplicationIdFromToken } from "./probe-
|
|
18
|
+
import { D as isDiscordExecApprovalClientEnabled, T as getDiscordExecApprovalApprovers, a as resolveDiscordComponentSpec, c as formatDiscordApprovalDisplayValue, d as resolveDiscordBoundConversationRoute, h as resolveDiscordConversationIdentity, l as buildDiscordConversationRouteContext, n as DISCORD_PRESENTATION_CAPABILITIES, p as resolveDiscordEffectiveRoute, r as buildDiscordPresentationPayload, s as DISCORD_APPROVAL_ALLOWED_MENTIONS, u as buildDiscordRoutePeer } from "./outbound-session-route-zVGxxceg.mjs";
|
|
19
|
+
import { n as discordIngressIdentity, t as selectDiscordLivePolicyConfig } from "./live-policy-config-8Pv20CHc.mjs";
|
|
20
|
+
import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-BFPNRmVv.mjs";
|
|
21
|
+
import { t as resolveDiscordUserAllowlist } from "./resolve-users-0-aBuCy3.mjs";
|
|
22
|
+
import { a as isThreadArchived, n as getThreadBindingManager } from "./thread-bindings.manager-DN-NissX.mjs";
|
|
23
|
+
import { a as probeDiscordApplicationId, r as parseApplicationIdFromToken } from "./probe-LYrIHlBF.mjs";
|
|
24
24
|
import { i as sanitizeRecentModels, n as normalizeModelRef, r as preferenceTimestampMs, t as buildPreferenceModelKey } from "./model-picker-preference-primitives-BHT1LkR_.mjs";
|
|
25
|
-
import { t as resolveDiscordSenderIdentity } from "./sender-identity-
|
|
26
|
-
import { n as hasDiscordApprovalControl, t as discordApprovalMessageUpdates } from "./approval-message-updates-
|
|
25
|
+
import { t as resolveDiscordSenderIdentity } from "./sender-identity-B9X5Vb9R.mjs";
|
|
26
|
+
import { n as hasDiscordApprovalControl, t as discordApprovalMessageUpdates } from "./approval-message-updates-BKFqavHZ.mjs";
|
|
27
27
|
import { createRequire } from "node:module";
|
|
28
28
|
import { logDebug, logError } from "openclaw/plugin-sdk/logging-core";
|
|
29
29
|
import { ApplicationCommandOptionType, ButtonStyle, ChannelType, ComponentType, GatewayCloseCodes, GatewayCloseCodes as GatewayCloseCodes$1, GatewayDispatchEvents, GatewayIntentBits, GatewayOpcodes, PermissionFlagsBits } from "discord-api-types/v10";
|
|
30
30
|
import { Type } from "typebox";
|
|
31
31
|
import { Check, Errors } from "typebox/value";
|
|
32
32
|
import { createHash, randomUUID } from "node:crypto";
|
|
33
|
-
import { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, asDateTimestampMs, asSafeIntegerInRange, parseFiniteNumber, parseStrictInteger, parseStrictPositiveInteger, resolveDateTimestampMs, resolveTimestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
34
33
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
34
|
+
import { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, asDateTimestampMs, asSafeIntegerInRange, parseFiniteNumber, parseStrictInteger, parseStrictPositiveInteger, resolveDateTimestampMs, resolvePromptHistoryLimit, resolveTimestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
35
35
|
import { inspect } from "node:util";
|
|
36
|
+
import * as fetchRuntimeSdk from "openclaw/plugin-sdk/fetch-runtime";
|
|
36
37
|
import { createHttp1EnvHttpProxyAgent, createHttp1ProxyAgent, createNodeProxyAgent, resolveEnvHttpProxyAgentOptions, wrapFetchWithAbortSignal } from "openclaw/plugin-sdk/fetch-runtime";
|
|
37
38
|
import { readResponseWithLimit } from "openclaw/plugin-sdk/response-limit-runtime";
|
|
38
39
|
import { fetchWithSsrFGuard, formatErrorMessage, resolvePinnedHostnameWithPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
@@ -53,29 +54,28 @@ import { buildOutboundSessionContext, listMessageReceiptPlatformIds, resolveChan
|
|
|
53
54
|
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
|
|
54
55
|
import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
|
|
55
56
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
56
|
-
import { buildCommandTextFromArgs, findCommandByNativeName, formatCommandArgMenuTitle, listChatCommands, listNativeCommandSpecsForConfig, listSkillCommandsForAgents, resolveCommandAuthorizedFromAuthorizers, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverride, serializeCommandArgs } from "openclaw/plugin-sdk/command-auth-native";
|
|
57
|
+
import { buildCommandTextFromArgs, findCommandByNativeName, formatCommandArgMenuTitle, listChatCommands, listNativeCommandSpecsForConfig, listSkillCommandsForAgents, resolveCommandAuthorization, resolveCommandAuthorizedFromAuthorizers, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverride, serializeCommandArgs } from "openclaw/plugin-sdk/command-auth-native";
|
|
57
58
|
import { GROUP_POLICY_BLOCKED_LABEL, resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
58
59
|
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
59
|
-
import {
|
|
60
|
-
import { createChannelPartialDeliveryError, createCommandTurnContext, dispatchChannelInboundTurn, formatInboundEnvelope, hasVisibleInboundReplyDispatch, isChannelPartialDeliveryError, resolveEnvelopeFormatOptions, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent } from "openclaw/plugin-sdk/channel-inbound";
|
|
60
|
+
import { buildChannelInboundEventContext, createChannelPartialDeliveryError, createCommandTurnContext, dispatchChannelInboundTurn, formatInboundEnvelope, hasVisibleInboundReplyDispatch, isChannelPartialDeliveryError, resolveEnvelopeFormatOptions, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent } from "openclaw/plugin-sdk/channel-inbound";
|
|
61
61
|
import path from "node:path";
|
|
62
|
-
import { resolvePinnedMainDmOwnerFromAllowlist
|
|
62
|
+
import { resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
|
|
63
63
|
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
|
|
64
64
|
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
|
65
|
-
import { buildPairingReply,
|
|
66
|
-
import
|
|
65
|
+
import { buildPairingReply, formatThreadBindingDurationLabel, upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
|
|
66
|
+
import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute } from "openclaw/plugin-sdk/conversation-binding-runtime";
|
|
67
67
|
import { questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
|
|
68
|
-
import {
|
|
69
|
-
import { clearExpiredCooldowns, ensureAuthProfileStore, formatReasoningMessage, getPreparedModelCatalogSnapshot, isProfileInCooldown, listAgentIds, loadPreparedModelCatalog, resolveAgentAvatar, resolveAgentDir, resolveDefaultModelForAgent, resolveHumanDelayConfig, resolveProfilesUnavailableReason } from "openclaw/plugin-sdk/agent-runtime";
|
|
68
|
+
import { readChannelIngressStoreAllowFromForDmPolicy } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
70
69
|
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
|
|
71
70
|
import { resolveNativeCommandsEnabled, resolveNativeSkillsEnabled } from "openclaw/plugin-sdk/native-command-config-runtime";
|
|
72
71
|
import { requestHeartbeat } from "openclaw/plugin-sdk/heartbeat-runtime";
|
|
73
|
-
import { enqueueRoutedSystemEvent
|
|
74
|
-
import {
|
|
75
|
-
import {
|
|
72
|
+
import { enqueueRoutedSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
|
|
73
|
+
import { clearExpiredCooldowns, ensureAuthProfileStore, formatReasoningMessage, getPreparedModelCatalogSnapshot, isProfileInCooldown, listAgentIds, loadPreparedModelCatalog, resolveAgentAvatar, resolveAgentDir, resolveDefaultModelForAgent, resolveHumanDelayConfig, resolveProfilesUnavailableReason } from "openclaw/plugin-sdk/agent-runtime";
|
|
74
|
+
import { deleteSessionEntry, getSessionEntry, listSessionEntries, readSessionUpdatedAt, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
75
|
+
import * as proxyCaptureSdk from "openclaw/plugin-sdk/proxy-capture";
|
|
76
|
+
import { resolveDebugProxySettings, resolveEffectiveDebugProxyUrl } from "openclaw/plugin-sdk/proxy-capture";
|
|
76
77
|
import { resolveRequestUrl } from "openclaw/plugin-sdk/request-url";
|
|
77
78
|
import { fetchWithRuntimeDispatcher } from "openclaw/plugin-sdk/runtime-fetch";
|
|
78
|
-
import { Agent } from "undici";
|
|
79
79
|
import * as dns from "node:dns";
|
|
80
80
|
import { buildCommandTextFromArgs as buildCommandTextFromArgs$1, findCommandByNativeName as findCommandByNativeName$1, mergeNativeCommandSpecs, parseCommandArgs, resolveCommandArgChoices, resolveCommandArgMenu, serializeCommandArgs as serializeCommandArgs$1 } from "openclaw/plugin-sdk/native-command-registry";
|
|
81
81
|
import { PLUGIN_COMMAND_DISPATCH } from "openclaw/plugin-sdk/plugin-command-runtime";
|
|
@@ -83,7 +83,7 @@ import { resolveDirectStatusReplyForSession } from "openclaw/plugin-sdk/command-
|
|
|
83
83
|
import * as modelsProviderRuntime from "openclaw/plugin-sdk/models-provider-runtime";
|
|
84
84
|
import { normalizeProviderId } from "openclaw/plugin-sdk/provider-model-shared";
|
|
85
85
|
import { EventEmitter } from "node:events";
|
|
86
|
-
import { Agent
|
|
86
|
+
import { Agent } from "node:https";
|
|
87
87
|
import { channelReadyPatch, createTransportActivityStatusPatch } from "openclaw/plugin-sdk/gateway-runtime";
|
|
88
88
|
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
|
89
89
|
import { stripPlainTextToolCallBlocks } from "openclaw/plugin-sdk/tool-payload";
|
|
@@ -382,7 +382,7 @@ function createDiscordDynamicAccessGroupResolver(params) {
|
|
|
382
382
|
};
|
|
383
383
|
}
|
|
384
384
|
function createDiscordIngressResolver(params) {
|
|
385
|
-
return
|
|
385
|
+
return getDiscordRuntime().channel.inbound.ingress.createResolver({
|
|
386
386
|
channelId: DISCORD_CHANNEL_ID,
|
|
387
387
|
accountId: params.accountId,
|
|
388
388
|
identity: discordIngressIdentity,
|
|
@@ -529,22 +529,10 @@ async function runDiscordReactionHandler(initialParams) {
|
|
|
529
529
|
listener: params.listener,
|
|
530
530
|
event: params.event,
|
|
531
531
|
run: async () => handleDiscordReactionEvent({
|
|
532
|
+
...params.handlerParams,
|
|
532
533
|
data: params.data,
|
|
533
534
|
client: params.client,
|
|
534
|
-
action: params.action
|
|
535
|
-
cfg: params.handlerParams.cfg,
|
|
536
|
-
isPolicyCurrent: params.handlerParams.isPolicyCurrent,
|
|
537
|
-
accountId: params.handlerParams.accountId,
|
|
538
|
-
botUserId: params.handlerParams.botUserId,
|
|
539
|
-
dmEnabled: params.handlerParams.dmEnabled,
|
|
540
|
-
groupDmEnabled: params.handlerParams.groupDmEnabled,
|
|
541
|
-
groupDmChannels: params.handlerParams.groupDmChannels,
|
|
542
|
-
dmPolicy: params.handlerParams.dmPolicy,
|
|
543
|
-
allowFrom: params.handlerParams.allowFrom,
|
|
544
|
-
groupPolicy: params.handlerParams.groupPolicy,
|
|
545
|
-
allowNameMatching: params.handlerParams.allowNameMatching,
|
|
546
|
-
guildEntries: params.handlerParams.guildEntries,
|
|
547
|
-
logger: params.handlerParams.logger
|
|
535
|
+
action: params.action
|
|
548
536
|
})
|
|
549
537
|
});
|
|
550
538
|
}
|
|
@@ -626,51 +614,6 @@ async function authorizeDiscordReactionIngress(params) {
|
|
|
626
614
|
};
|
|
627
615
|
return { allowed: true };
|
|
628
616
|
}
|
|
629
|
-
async function handleDiscordThreadReactionNotification(params) {
|
|
630
|
-
if (params.reactionMode === "off") return;
|
|
631
|
-
if (params.reactionMode === "all" || params.reactionMode === "allowlist") {
|
|
632
|
-
const { access, channelConfig } = await params.resolveThreadChannelAccess();
|
|
633
|
-
if (!access.allowed || !params.shouldNotifyReaction({
|
|
634
|
-
mode: params.reactionMode,
|
|
635
|
-
channelConfig
|
|
636
|
-
})) return;
|
|
637
|
-
const { baseText } = params.resolveReactionBase();
|
|
638
|
-
params.emitReaction(baseText, params.parentId);
|
|
639
|
-
return;
|
|
640
|
-
}
|
|
641
|
-
const message = await params.message.fetch().catch(() => null);
|
|
642
|
-
const { access, channelConfig } = await params.resolveThreadChannelAccess();
|
|
643
|
-
const messageAuthorId = message?.author?.id ?? void 0;
|
|
644
|
-
if (!access.allowed || !params.shouldNotifyReaction({
|
|
645
|
-
mode: params.reactionMode,
|
|
646
|
-
messageAuthorId,
|
|
647
|
-
channelConfig
|
|
648
|
-
})) return;
|
|
649
|
-
params.emitReactionWithAuthor(message);
|
|
650
|
-
}
|
|
651
|
-
async function handleDiscordChannelReactionNotification(params) {
|
|
652
|
-
if (params.isGuildMessage) {
|
|
653
|
-
if (!(await params.authorizeReactionIngressForChannel(params.channelConfig)).allowed) return;
|
|
654
|
-
}
|
|
655
|
-
if (params.reactionMode === "off") return;
|
|
656
|
-
if (params.reactionMode === "all" || params.reactionMode === "allowlist") {
|
|
657
|
-
if (!params.shouldNotifyReaction({
|
|
658
|
-
mode: params.reactionMode,
|
|
659
|
-
channelConfig: params.channelConfig
|
|
660
|
-
})) return;
|
|
661
|
-
const { baseText } = params.resolveReactionBase();
|
|
662
|
-
params.emitReaction(baseText, params.parentId);
|
|
663
|
-
return;
|
|
664
|
-
}
|
|
665
|
-
const message = await params.message.fetch().catch(() => null);
|
|
666
|
-
const messageAuthorId = message?.author?.id ?? void 0;
|
|
667
|
-
if (!params.shouldNotifyReaction({
|
|
668
|
-
mode: params.reactionMode,
|
|
669
|
-
messageAuthorId,
|
|
670
|
-
channelConfig: params.channelConfig
|
|
671
|
-
})) return;
|
|
672
|
-
params.emitReactionWithAuthor(message);
|
|
673
|
-
}
|
|
674
617
|
function hasDiscordGuildChannelOverrides(guildInfo) {
|
|
675
618
|
return Boolean(guildInfo?.channels && Object.keys(guildInfo.channels).length > 0);
|
|
676
619
|
}
|
|
@@ -758,57 +701,10 @@ async function handleDiscordReactionEvent(params) {
|
|
|
758
701
|
const parentId = isThreadChannel ? channelContext.threadParentId : channelContext.parentId;
|
|
759
702
|
const parentName = isThreadChannel ? channelContext.threadParentName : void 0;
|
|
760
703
|
const parentSlug = isThreadChannel ? channelContext.threadParentSlug : "";
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
const actorLabel = formatDiscordUserTag(user) || user.id;
|
|
766
|
-
const guildSlug = guildInfo?.slug || (data.guild?.name ? normalizeDiscordSlug(data.guild.name) : data.guild_id ?? (isGroupDm ? "group-dm" : "dm"));
|
|
767
|
-
const channelLabel = channelSlug ? `#${channelSlug}` : channelName ? `#${normalizeDiscordSlug(channelName)}` : `#${data.channel_id}`;
|
|
768
|
-
reactionBase = {
|
|
769
|
-
baseText: `Discord ${data.burst ? "super " : ""}reaction ${action}: ${emojiLabel} by ${actorLabel} on ${guildSlug} ${channelLabel} msg ${data.message_id}`,
|
|
770
|
-
contextKey: `discord:reaction:${action}:${data.message_id}:${user.id}:${emojiLabel}${data.burst ? ":burst" : ""}`
|
|
771
|
-
};
|
|
772
|
-
return reactionBase;
|
|
773
|
-
};
|
|
774
|
-
const emitReaction = (text, parentPeerId) => {
|
|
775
|
-
const { contextKey } = resolveReactionBase();
|
|
776
|
-
const route = resolveAgentRoute({
|
|
777
|
-
cfg: params.cfg,
|
|
778
|
-
channel: "discord",
|
|
779
|
-
accountId: params.accountId,
|
|
780
|
-
guildId: data.guild_id ?? void 0,
|
|
781
|
-
memberRoleIds,
|
|
782
|
-
peer: {
|
|
783
|
-
kind: isDirectMessage ? "direct" : isGroupDm ? "group" : "channel",
|
|
784
|
-
id: isDirectMessage ? user.id : data.channel_id
|
|
785
|
-
},
|
|
786
|
-
parentPeer: parentPeerId ? {
|
|
787
|
-
kind: "channel",
|
|
788
|
-
id: parentPeerId
|
|
789
|
-
} : void 0
|
|
790
|
-
});
|
|
791
|
-
enqueueRoutedSystemEvent(text, route, { contextKey });
|
|
792
|
-
};
|
|
793
|
-
const shouldNotifyReaction = (options) => shouldEmitDiscordReactionNotification({
|
|
794
|
-
mode: options.mode,
|
|
795
|
-
botId: botUserId,
|
|
796
|
-
messageAuthorId: options.messageAuthorId,
|
|
797
|
-
userId: user.id,
|
|
798
|
-
userName: user.username,
|
|
799
|
-
userTag: formatDiscordUserTag(user),
|
|
800
|
-
channelConfig: options.channelConfig,
|
|
801
|
-
guildInfo,
|
|
802
|
-
memberRoleIds,
|
|
803
|
-
allowNameMatching: params.allowNameMatching
|
|
804
|
-
});
|
|
805
|
-
const emitReactionWithAuthor = (message) => {
|
|
806
|
-
const { baseText } = resolveReactionBase();
|
|
807
|
-
const authorLabel = message?.author ? formatDiscordUserTag(message.author) : void 0;
|
|
808
|
-
const text = authorLabel ? `${baseText} from ${authorLabel}` : baseText;
|
|
809
|
-
emitReaction(text, parentId);
|
|
810
|
-
};
|
|
811
|
-
const resolveThreadChannelConfig = () => resolveDiscordChannelConfigWithFallback({
|
|
704
|
+
if (isThreadChannel && reactionMode === "off") return;
|
|
705
|
+
let message = null;
|
|
706
|
+
if (isThreadChannel && reactionMode === "own") message = await data.message.fetch().catch(() => null);
|
|
707
|
+
const channelConfig = resolveDiscordChannelConfigWithFallback({
|
|
812
708
|
guildInfo,
|
|
813
709
|
channelId: data.channel_id,
|
|
814
710
|
channelName,
|
|
@@ -816,54 +712,51 @@ async function handleDiscordReactionEvent(params) {
|
|
|
816
712
|
parentId,
|
|
817
713
|
parentName,
|
|
818
714
|
parentSlug,
|
|
819
|
-
scope: "thread"
|
|
820
|
-
});
|
|
821
|
-
const authorizeReactionIngressForChannel = async (channelConfig) => await authorizeDiscordReactionIngress({
|
|
822
|
-
...reactionIngressBase,
|
|
823
|
-
channelConfig
|
|
715
|
+
scope: isThreadChannel ? "thread" : "channel"
|
|
824
716
|
});
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
access: await authorizeReactionIngressForChannel(channelConfig),
|
|
717
|
+
if (isGuildMessage || isThreadChannel) {
|
|
718
|
+
if (!(await authorizeDiscordReactionIngress({
|
|
719
|
+
...reactionIngressBase,
|
|
829
720
|
channelConfig
|
|
830
|
-
};
|
|
831
|
-
};
|
|
832
|
-
if (isThreadChannel) {
|
|
833
|
-
await handleDiscordThreadReactionNotification({
|
|
834
|
-
reactionMode,
|
|
835
|
-
message: data.message,
|
|
836
|
-
parentId,
|
|
837
|
-
resolveThreadChannelAccess,
|
|
838
|
-
shouldNotifyReaction,
|
|
839
|
-
resolveReactionBase,
|
|
840
|
-
emitReaction,
|
|
841
|
-
emitReactionWithAuthor
|
|
842
|
-
});
|
|
843
|
-
return;
|
|
721
|
+
})).allowed) return;
|
|
844
722
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
scope: "channel"
|
|
854
|
-
});
|
|
855
|
-
await handleDiscordChannelReactionNotification({
|
|
856
|
-
isGuildMessage,
|
|
857
|
-
reactionMode,
|
|
858
|
-
message: data.message,
|
|
723
|
+
if (!isThreadChannel && reactionMode === "own") message = await data.message.fetch().catch(() => null);
|
|
724
|
+
if (!shouldEmitDiscordReactionNotification({
|
|
725
|
+
mode: reactionMode,
|
|
726
|
+
botId: botUserId,
|
|
727
|
+
messageAuthorId: message?.author?.id,
|
|
728
|
+
userId: user.id,
|
|
729
|
+
userName: user.username,
|
|
730
|
+
userTag: formatDiscordUserTag(user),
|
|
859
731
|
channelConfig,
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
732
|
+
guildInfo,
|
|
733
|
+
memberRoleIds,
|
|
734
|
+
allowNameMatching: params.allowNameMatching
|
|
735
|
+
})) return;
|
|
736
|
+
const emojiLabel = formatDiscordReactionEmoji(data.emoji);
|
|
737
|
+
const actorLabel = formatDiscordUserTag(user) || user.id;
|
|
738
|
+
const guildSlug = guildInfo?.slug || (data.guild?.name ? normalizeDiscordSlug(data.guild.name) : data.guild_id ?? (isGroupDm ? "group-dm" : "dm"));
|
|
739
|
+
const channelLabel = channelSlug ? `#${channelSlug}` : channelName ? `#${normalizeDiscordSlug(channelName)}` : `#${data.channel_id}`;
|
|
740
|
+
const baseText = `Discord ${data.burst ? "super " : ""}reaction ${action}: ${emojiLabel} by ${actorLabel} on ${guildSlug} ${channelLabel} msg ${data.message_id}`;
|
|
741
|
+
const authorLabel = message?.author ? formatDiscordUserTag(message.author) : void 0;
|
|
742
|
+
const text = authorLabel ? `${baseText} from ${authorLabel}` : baseText;
|
|
743
|
+
const contextKey = `discord:reaction:${action}:${data.message_id}:${user.id}:${emojiLabel}${data.burst ? ":burst" : ""}`;
|
|
744
|
+
const route = resolveAgentRoute({
|
|
745
|
+
cfg: params.cfg,
|
|
746
|
+
channel: "discord",
|
|
747
|
+
accountId: params.accountId,
|
|
748
|
+
guildId: data.guild_id ?? void 0,
|
|
749
|
+
memberRoleIds,
|
|
750
|
+
peer: {
|
|
751
|
+
kind: isDirectMessage ? "direct" : isGroupDm ? "group" : "channel",
|
|
752
|
+
id: isDirectMessage ? user.id : data.channel_id
|
|
753
|
+
},
|
|
754
|
+
parentPeer: parentId ? {
|
|
755
|
+
kind: "channel",
|
|
756
|
+
id: parentId
|
|
757
|
+
} : void 0
|
|
866
758
|
});
|
|
759
|
+
enqueueRoutedSystemEvent(text, route, { contextKey });
|
|
867
760
|
} catch (err) {
|
|
868
761
|
params.logger.error(danger(`discord reaction handler failed: ${String(err)}`));
|
|
869
762
|
}
|
|
@@ -899,7 +792,7 @@ var DiscordInteractionListener = class extends InteractionCreateListener {
|
|
|
899
792
|
}
|
|
900
793
|
async handle(data, client) {
|
|
901
794
|
this.onEvent?.();
|
|
902
|
-
Promise.resolve().then(() => client.handleInteraction(data
|
|
795
|
+
Promise.resolve().then(() => client.handleInteraction(data)).catch((err) => {
|
|
903
796
|
(this.logger ?? discordEventQueueLog).error(danger(`discord interaction handler failed: ${String(err)}`));
|
|
904
797
|
});
|
|
905
798
|
}
|
|
@@ -1254,7 +1147,7 @@ var DiscordThreadDeleteListener = class extends ThreadDeleteListener {
|
|
|
1254
1147
|
event: this.type,
|
|
1255
1148
|
run: async () => {
|
|
1256
1149
|
const threadId = data.id;
|
|
1257
|
-
getThreadBindingManager(this.accountId)?.unbindThread({
|
|
1150
|
+
await getThreadBindingManager(this.accountId)?.unbindThread({
|
|
1258
1151
|
threadId,
|
|
1259
1152
|
reason: "thread-delete",
|
|
1260
1153
|
sendFarewell: false
|
|
@@ -1276,14 +1169,12 @@ var DiscordThreadDeleteListener = class extends ThreadDeleteListener {
|
|
|
1276
1169
|
};
|
|
1277
1170
|
//#endregion
|
|
1278
1171
|
//#region extensions/discord/src/internal/gateway-dispatch.ts
|
|
1279
|
-
function dispatchVoiceGatewayEvent(client,
|
|
1280
|
-
const guildId = readGuildId(
|
|
1172
|
+
function dispatchVoiceGatewayEvent(client, payload) {
|
|
1173
|
+
const guildId = readGuildId(payload.d);
|
|
1281
1174
|
if (!guildId) return;
|
|
1282
1175
|
const adapter = (client.getPlugin("voice")?.adapters)?.get(guildId);
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
if (type === voiceServerUpdate) adapter?.onVoiceServerUpdate?.(data);
|
|
1286
|
-
if (type === voiceStateUpdate) adapter?.onVoiceStateUpdate?.(data);
|
|
1176
|
+
if (payload.t === GatewayDispatchEvents.VoiceServerUpdate) adapter?.onVoiceServerUpdate?.(payload.d);
|
|
1177
|
+
if (payload.t === GatewayDispatchEvents.VoiceStateUpdate) adapter?.onVoiceStateUpdate?.(payload.d);
|
|
1287
1178
|
}
|
|
1288
1179
|
function mapGatewayDispatchData(client, type, data) {
|
|
1289
1180
|
const messageCreate = GatewayDispatchEvents.MessageCreate;
|
|
@@ -1514,10 +1405,8 @@ async function resolveAllowFromByUserAllowlist(params) {
|
|
|
1514
1405
|
function collectGuildUserEntries(guildEntries) {
|
|
1515
1406
|
const userEntries = /* @__PURE__ */ new Set();
|
|
1516
1407
|
for (const guild of Object.values(guildEntries)) {
|
|
1517
|
-
if (!guild || typeof guild !== "object") continue;
|
|
1518
1408
|
addAllowlistUserEntriesFromConfigEntry(userEntries, guild);
|
|
1519
|
-
const
|
|
1520
|
-
for (const channel of Object.values(channels)) addAllowlistUserEntriesFromConfigEntry(userEntries, channel);
|
|
1409
|
+
for (const channel of Object.values(guild.channels ?? {})) addAllowlistUserEntriesFromConfigEntry(userEntries, channel);
|
|
1521
1410
|
}
|
|
1522
1411
|
return userEntries;
|
|
1523
1412
|
}
|
|
@@ -1534,15 +1423,13 @@ async function resolveGuildEntriesByUserAllowlist(params) {
|
|
|
1534
1423
|
formatResolved: formatDiscordUserResolved,
|
|
1535
1424
|
formatUnresolved: formatDiscordUserUnresolved
|
|
1536
1425
|
});
|
|
1537
|
-
const nextGuilds = {
|
|
1538
|
-
|
|
1539
|
-
|
|
1426
|
+
const nextGuilds = patchAllowlistUsersInConfigEntries({
|
|
1427
|
+
entries: params.guildEntries,
|
|
1428
|
+
resolvedMap,
|
|
1429
|
+
strategy: "canonicalize"
|
|
1430
|
+
});
|
|
1431
|
+
for (const [guildKey, guildConfig] of Object.entries(nextGuilds)) {
|
|
1540
1432
|
const nextGuild = { ...guildConfig };
|
|
1541
|
-
const users = guildConfig.users;
|
|
1542
|
-
if (Array.isArray(users) && users.length > 0) nextGuild.users = canonicalizeAllowlistWithResolvedIds({
|
|
1543
|
-
existing: users,
|
|
1544
|
-
resolvedMap
|
|
1545
|
-
});
|
|
1546
1433
|
const channels = guildConfig.channels ?? {};
|
|
1547
1434
|
if (channels && typeof channels === "object") nextGuild.channels = patchAllowlistUsersInConfigEntries({
|
|
1548
1435
|
entries: channels,
|
|
@@ -1602,7 +1489,7 @@ function isDiscordTransportHostname(hostname) {
|
|
|
1602
1489
|
return DISCORD_DNS_HOSTS.some((target) => normalized === target || normalized.endsWith(`.${target}`));
|
|
1603
1490
|
}
|
|
1604
1491
|
function reorderLookupAddresses(addresses) {
|
|
1605
|
-
if (
|
|
1492
|
+
if (addresses.length < 2) return addresses;
|
|
1606
1493
|
const ipv4 = addresses.filter((entry) => entry.family === 4);
|
|
1607
1494
|
const ipv6 = addresses.filter((entry) => entry.family === 6);
|
|
1608
1495
|
if (ipv4.length === 0) return ipv6;
|
|
@@ -1655,13 +1542,9 @@ function createDiscordEndpointDnsLookup(endpointHostname) {
|
|
|
1655
1542
|
}
|
|
1656
1543
|
//#endregion
|
|
1657
1544
|
//#region extensions/discord/src/monitor/rest-fetch.ts
|
|
1545
|
+
const captureSdk$2 = proxyCaptureSdk;
|
|
1546
|
+
const fetchSdk = fetchRuntimeSdk;
|
|
1658
1547
|
const discordDnsLookup$1 = createDiscordDnsLookup();
|
|
1659
|
-
function createDirectDiscordRestDispatcher() {
|
|
1660
|
-
return new Agent({
|
|
1661
|
-
allowH2: false,
|
|
1662
|
-
connect: { lookup: discordDnsLookup$1 }
|
|
1663
|
-
});
|
|
1664
|
-
}
|
|
1665
1548
|
function createEnvProxyDiscordRestDispatcher(runtime) {
|
|
1666
1549
|
const envProxyOptions = resolveEnvHttpProxyAgentOptions();
|
|
1667
1550
|
if (!envProxyOptions) return;
|
|
@@ -1680,7 +1563,7 @@ function createDiscordRestFetchWithDispatcher(dispatcher) {
|
|
|
1680
1563
|
...init,
|
|
1681
1564
|
dispatcher
|
|
1682
1565
|
}).then((response) => {
|
|
1683
|
-
|
|
1566
|
+
captureSdk$2.captureHttpExchangeAsync?.({
|
|
1684
1567
|
url: resolveRequestUrl(input),
|
|
1685
1568
|
method: init?.method ?? "GET",
|
|
1686
1569
|
requestHeaders: init?.headers,
|
|
@@ -1688,7 +1571,7 @@ function createDiscordRestFetchWithDispatcher(dispatcher) {
|
|
|
1688
1571
|
response,
|
|
1689
1572
|
flowId: randomUUID(),
|
|
1690
1573
|
meta: { subsystem: "discord-rest" }
|
|
1691
|
-
});
|
|
1574
|
+
}).catch(() => {});
|
|
1692
1575
|
return response;
|
|
1693
1576
|
})));
|
|
1694
1577
|
}
|
|
@@ -1700,7 +1583,12 @@ function resolveDiscordRestFetch(proxyUrl, runtime) {
|
|
|
1700
1583
|
runtime.log?.("discord: rest proxy enabled");
|
|
1701
1584
|
return fetcher;
|
|
1702
1585
|
}
|
|
1703
|
-
return createDiscordRestFetchWithDispatcher(createEnvProxyDiscordRestDispatcher(runtime) ??
|
|
1586
|
+
return createDiscordRestFetchWithDispatcher(createEnvProxyDiscordRestDispatcher(runtime) ?? fetchSdk.createHttp1Agent?.({ connect: { lookup: discordDnsLookup$1 } }) ?? createHttp1EnvHttpProxyAgent({
|
|
1587
|
+
httpProxy: "",
|
|
1588
|
+
httpsProxy: "",
|
|
1589
|
+
noProxy: "*",
|
|
1590
|
+
connect: { lookup: discordDnsLookup$1 }
|
|
1591
|
+
}));
|
|
1704
1592
|
}
|
|
1705
1593
|
//#endregion
|
|
1706
1594
|
//#region extensions/discord/src/monitor/live-policy.ts
|
|
@@ -1848,6 +1736,13 @@ async function readDiscordInteractionPolicy(readPolicy) {
|
|
|
1848
1736
|
//#endregion
|
|
1849
1737
|
//#region extensions/discord/src/monitor/native-command-reply.ts
|
|
1850
1738
|
const DISCORD_EMPTY_VISIBLE_REPLY_WARNING = "⚠️ Command produced no visible reply.";
|
|
1739
|
+
function resolveDiscordInteractionReplyOptions(params) {
|
|
1740
|
+
return {
|
|
1741
|
+
textLimit: resolveTextChunkLimit(params.cfg, "discord", params.accountId, { fallbackLimit: 2e3 }),
|
|
1742
|
+
maxLinesPerMessage: resolveDiscordMaxLinesPerMessage(params),
|
|
1743
|
+
chunkMode: resolveChunkMode(params.cfg, "discord", params.accountId)
|
|
1744
|
+
};
|
|
1745
|
+
}
|
|
1851
1746
|
function isDiscordUnknownInteraction(error) {
|
|
1852
1747
|
if (!error || typeof error !== "object") return false;
|
|
1853
1748
|
const err = error;
|
|
@@ -1937,55 +1832,33 @@ async function deliverDiscordInteractionReply(params) {
|
|
|
1937
1832
|
if (!payloadDelivered) throw expiry;
|
|
1938
1833
|
throw createChannelPartialDeliveryError(expiry, { visibleReplySent: true });
|
|
1939
1834
|
};
|
|
1940
|
-
|
|
1941
|
-
const
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
const chunks = resolveTextChunksWithFallback(reply.text, chunkDiscordTextWithMode(reply.text, {
|
|
1950
|
-
maxChars: textLimit,
|
|
1951
|
-
maxLines: maxLinesPerMessage,
|
|
1952
|
-
chunkMode
|
|
1953
|
-
}));
|
|
1954
|
-
await sendMessage(chunks[0] ?? "", media, firstMessageComponents, firstMessageEmbeds);
|
|
1955
|
-
for (const chunk of chunks.slice(1)) {
|
|
1956
|
-
if (!chunk.trim()) continue;
|
|
1957
|
-
await sendMessage(chunk);
|
|
1958
|
-
}
|
|
1959
|
-
return payloadDelivered;
|
|
1960
|
-
}
|
|
1961
|
-
if (!reply.hasText && !firstMessageComponents && !firstMessageEmbeds) return false;
|
|
1835
|
+
const files = reply.hasMedia ? await Promise.all(reply.mediaUrls.map(async (url) => {
|
|
1836
|
+
const loaded = await loadWebMedia(url, { localRoots: params.mediaLocalRoots });
|
|
1837
|
+
return {
|
|
1838
|
+
name: loaded.fileName ?? "upload",
|
|
1839
|
+
data: loaded.buffer,
|
|
1840
|
+
contentType: loaded.contentType
|
|
1841
|
+
};
|
|
1842
|
+
})) : void 0;
|
|
1843
|
+
if (!files && !reply.hasText && !firstMessageComponents && !firstMessageEmbeds) return false;
|
|
1962
1844
|
const chunks = resolveTextChunksWithFallback(reply.text, chunkDiscordTextWithMode(reply.text, {
|
|
1963
1845
|
maxChars: textLimit,
|
|
1964
1846
|
maxLines: maxLinesPerMessage,
|
|
1965
1847
|
chunkMode
|
|
1966
1848
|
}));
|
|
1967
1849
|
if (chunks.length === 0) chunks.push("");
|
|
1968
|
-
for (const chunk of chunks) {
|
|
1969
|
-
|
|
1970
|
-
|
|
1850
|
+
for (const [index, chunk] of chunks.entries()) {
|
|
1851
|
+
const chunkFiles = index === 0 ? files : void 0;
|
|
1852
|
+
if (!chunk.trim() && !chunkFiles && !firstMessageComponents && !firstMessageEmbeds) continue;
|
|
1853
|
+
await sendMessage(chunk, chunkFiles, firstMessageComponents, firstMessageEmbeds);
|
|
1971
1854
|
}
|
|
1972
1855
|
return payloadDelivered;
|
|
1973
1856
|
}
|
|
1974
1857
|
//#endregion
|
|
1975
1858
|
//#region extensions/discord/src/monitor/native-command-route.ts
|
|
1976
|
-
|
|
1977
|
-
const route = resolveDiscordBoundConversationRoute(
|
|
1978
|
-
|
|
1979
|
-
accountId: params.accountId,
|
|
1980
|
-
guildId: params.guildId,
|
|
1981
|
-
memberRoleIds: params.memberRoleIds,
|
|
1982
|
-
isDirectMessage: params.isDirectMessage,
|
|
1983
|
-
isGroupDm: params.isGroupDm,
|
|
1984
|
-
directUserId: params.directUserId,
|
|
1985
|
-
conversationId: params.conversationId,
|
|
1986
|
-
parentConversationId: params.parentConversationId
|
|
1987
|
-
});
|
|
1988
|
-
const configuredRoute = params.threadBinding == null ? conversationRuntime.resolveConfiguredBindingRoute({
|
|
1859
|
+
function resolveDiscordNativeInteractionRouteState(params) {
|
|
1860
|
+
const route = resolveDiscordBoundConversationRoute(params);
|
|
1861
|
+
const configuredRoute = params.threadBinding == null ? resolveConfiguredBindingRoute({
|
|
1989
1862
|
cfg: params.cfg,
|
|
1990
1863
|
route,
|
|
1991
1864
|
conversation: {
|
|
@@ -2008,17 +1881,14 @@ async function resolveDiscordNativeInteractionRouteState(params) {
|
|
|
2008
1881
|
}),
|
|
2009
1882
|
boundSessionKey,
|
|
2010
1883
|
configuredRoute,
|
|
2011
|
-
configuredBinding
|
|
2012
|
-
bindingReadiness: params.enforceConfiguredBindingReadiness && configuredBinding ? await conversationRuntime.ensureConfiguredBindingRouteReady({
|
|
2013
|
-
cfg: params.cfg,
|
|
2014
|
-
bindingResolution: configuredBinding
|
|
2015
|
-
}) : null
|
|
1884
|
+
configuredBinding
|
|
2016
1885
|
};
|
|
2017
1886
|
}
|
|
2018
1887
|
//#endregion
|
|
2019
1888
|
//#region extensions/discord/src/monitor/native-command.runtime.ts
|
|
2020
1889
|
const nativeCommandRuntime = {
|
|
2021
1890
|
dispatchChannelInboundTurn,
|
|
1891
|
+
ensureConfiguredBindingRouteReady,
|
|
2022
1892
|
resolveDirectStatusReplyForSession,
|
|
2023
1893
|
resolveDiscordNativeInteractionRouteState,
|
|
2024
1894
|
getSessionEntry
|
|
@@ -2055,15 +1925,9 @@ async function dispatchDiscordNativeAgentReply(params) {
|
|
|
2055
1925
|
sessionKey: params.ctxPayload.CommandTargetSessionKey ?? params.effectiveRoute.sessionKey
|
|
2056
1926
|
},
|
|
2057
1927
|
mediaLocalRoots: params.mediaLocalRoots,
|
|
2058
|
-
|
|
2059
|
-
maxLinesPerMessage: resolveDiscordMaxLinesPerMessage({
|
|
2060
|
-
cfg: params.cfg,
|
|
2061
|
-
discordConfig: params.discordConfig,
|
|
2062
|
-
accountId: params.accountId
|
|
2063
|
-
}),
|
|
1928
|
+
...resolveDiscordInteractionReplyOptions(params),
|
|
2064
1929
|
preferFollowUp: params.preferFollowUp || didReply,
|
|
2065
|
-
responseEphemeral: params.responseEphemeral
|
|
2066
|
-
chunkMode: resolveChunkMode(params.cfg, "discord", params.accountId)
|
|
1930
|
+
responseEphemeral: params.responseEphemeral
|
|
2067
1931
|
});
|
|
2068
1932
|
didReply ||= payloadDelivered;
|
|
2069
1933
|
return payloadDelivered ? { visibleReplySent: true } : {
|
|
@@ -2109,11 +1973,7 @@ async function dispatchDiscordNativeAgentReply(params) {
|
|
|
2109
1973
|
content: DISCORD_EMPTY_VISIBLE_REPLY_WARNING,
|
|
2110
1974
|
ephemeral: true
|
|
2111
1975
|
};
|
|
2112
|
-
|
|
2113
|
-
await params.interaction.followUp(payload);
|
|
2114
|
-
return;
|
|
2115
|
-
}
|
|
2116
|
-
await params.interaction.reply(payload);
|
|
1976
|
+
await params.interaction[params.preferFollowUp ? "followUp" : "reply"](payload);
|
|
2117
1977
|
});
|
|
2118
1978
|
return dispatchResult;
|
|
2119
1979
|
}
|
|
@@ -2125,9 +1985,6 @@ function resolveDiscordSlashCommandConfig(raw) {
|
|
|
2125
1985
|
//#endregion
|
|
2126
1986
|
//#region extensions/discord/src/monitor/native-command-arg-ui.ts
|
|
2127
1987
|
const DISCORD_COMMAND_ARG_CUSTOM_ID_KEY = "cmdarg";
|
|
2128
|
-
function createCommandArgsWithValue(params) {
|
|
2129
|
-
return { values: { [params.argName]: params.value } };
|
|
2130
|
-
}
|
|
2131
1988
|
function buildDiscordCommandArgCustomId(params) {
|
|
2132
1989
|
return [
|
|
2133
1990
|
`${DISCORD_COMMAND_ARG_CUSTOM_ID_KEY}:command=${encodeCustomIdComponent(params.command)}`,
|
|
@@ -2172,45 +2029,33 @@ async function handleDiscordCommandArgInteraction(params) {
|
|
|
2172
2029
|
return;
|
|
2173
2030
|
}
|
|
2174
2031
|
if (await clearWithMessage(`⏳ Applying ${parsed.value}...`) === null) return;
|
|
2175
|
-
const commandArgs =
|
|
2176
|
-
argName: parsed.arg,
|
|
2177
|
-
value: parsed.value
|
|
2178
|
-
});
|
|
2032
|
+
const commandArgs = { values: { [parsed.arg]: parsed.value } };
|
|
2179
2033
|
const commandArgsWithRaw = {
|
|
2180
2034
|
...commandArgs,
|
|
2181
2035
|
raw: serializeCommandArgs(commandDefinition, commandArgs)
|
|
2182
2036
|
};
|
|
2183
2037
|
const prompt = buildCommandTextFromArgs(commandDefinition, commandArgsWithRaw);
|
|
2184
2038
|
await params.dispatchCommandInteraction({
|
|
2185
|
-
|
|
2039
|
+
...ctx,
|
|
2186
2040
|
interaction,
|
|
2187
2041
|
prompt,
|
|
2188
2042
|
command: commandDefinition,
|
|
2189
2043
|
commandArgs: commandArgsWithRaw,
|
|
2190
|
-
cfg: ctx.cfg,
|
|
2191
|
-
discordConfig: ctx.discordConfig,
|
|
2192
|
-
accountId: ctx.accountId,
|
|
2193
|
-
sessionPrefix: ctx.sessionPrefix,
|
|
2194
2044
|
preferFollowUp: true,
|
|
2195
|
-
threadBindings: ctx.threadBindings,
|
|
2196
2045
|
responseEphemeral: resolveDiscordSlashCommandConfig(ctx.discordConfig?.slashCommand).ephemeral,
|
|
2197
|
-
dispatchReplyFromConfig: ctx.dispatchReplyFromConfig,
|
|
2198
2046
|
pluginCommandDispatch: { kind: "non-plugin" }
|
|
2199
2047
|
});
|
|
2200
2048
|
}
|
|
2201
|
-
async function runDiscordCommandArgButton(params) {
|
|
2202
|
-
await handleDiscordCommandArgInteraction(params);
|
|
2203
|
-
}
|
|
2204
2049
|
var DiscordCommandArgButton = class extends Button {
|
|
2205
2050
|
constructor(params) {
|
|
2206
2051
|
super();
|
|
2207
|
-
this.
|
|
2052
|
+
this.params = params;
|
|
2208
2053
|
this.label = params.label;
|
|
2209
2054
|
this.customId = params.customId;
|
|
2210
|
-
this.
|
|
2055
|
+
this.style = params.style ?? ButtonStyle.Secondary;
|
|
2211
2056
|
}
|
|
2212
2057
|
async run(interaction, data) {
|
|
2213
|
-
await
|
|
2058
|
+
await handleDiscordCommandArgInteraction({
|
|
2214
2059
|
...this.params,
|
|
2215
2060
|
interaction,
|
|
2216
2061
|
data
|
|
@@ -2244,23 +2089,205 @@ function buildDiscordCommandArgMenu(params) {
|
|
|
2244
2089
|
components: rows
|
|
2245
2090
|
};
|
|
2246
2091
|
}
|
|
2247
|
-
var DiscordCommandArgFallbackButton = class extends Button {
|
|
2248
|
-
constructor(params) {
|
|
2249
|
-
super();
|
|
2250
|
-
this.params = params;
|
|
2251
|
-
this.label = "cmdarg";
|
|
2252
|
-
this.customId = "cmdarg:seed=1";
|
|
2253
|
-
}
|
|
2254
|
-
async run(interaction, data) {
|
|
2255
|
-
await runDiscordCommandArgButton({
|
|
2256
|
-
...this.params,
|
|
2257
|
-
interaction,
|
|
2258
|
-
data
|
|
2259
|
-
});
|
|
2260
|
-
}
|
|
2261
|
-
};
|
|
2262
2092
|
function createDiscordCommandArgFallbackButton$1(params) {
|
|
2263
|
-
return new
|
|
2093
|
+
return new DiscordCommandArgButton({
|
|
2094
|
+
...params,
|
|
2095
|
+
label: "cmdarg",
|
|
2096
|
+
customId: "cmdarg:seed=1",
|
|
2097
|
+
style: ButtonStyle.Primary
|
|
2098
|
+
});
|
|
2099
|
+
}
|
|
2100
|
+
//#endregion
|
|
2101
|
+
//#region extensions/discord/src/monitor/inbound-context.ts
|
|
2102
|
+
function createDiscordSupplementalContextAccessChecker(params) {
|
|
2103
|
+
const userAllowList = params.channelConfig?.users ?? params.guildInfo?.users ?? [];
|
|
2104
|
+
const roleAllowList = params.channelConfig?.roles ?? params.guildInfo?.roles ?? [];
|
|
2105
|
+
const allowFrom = [...userAllowList, ...roleAllowList];
|
|
2106
|
+
return (sender) => {
|
|
2107
|
+
return resolveInboundSupplementalSenderAllowed({
|
|
2108
|
+
isGroup: params.isGuild,
|
|
2109
|
+
groupPolicy: allowFrom.length === 0 ? "open" : "allowlist",
|
|
2110
|
+
allowFrom,
|
|
2111
|
+
isSenderAllowed: () => resolveDiscordMemberAllowed({
|
|
2112
|
+
userAllowList,
|
|
2113
|
+
roleAllowList,
|
|
2114
|
+
memberRoleIds: [...sender.memberRoleIds ?? []],
|
|
2115
|
+
userId: sender.id ?? "",
|
|
2116
|
+
userName: sender.name,
|
|
2117
|
+
userTag: sender.tag,
|
|
2118
|
+
allowNameMatching: params.allowNameMatching
|
|
2119
|
+
})
|
|
2120
|
+
});
|
|
2121
|
+
};
|
|
2122
|
+
}
|
|
2123
|
+
function buildDiscordGroupSystemPrompt(channelConfig) {
|
|
2124
|
+
return channelConfig?.systemPrompt?.trim() || void 0;
|
|
2125
|
+
}
|
|
2126
|
+
function buildDiscordChannelStructuredContext(params) {
|
|
2127
|
+
if (!params.isGuild || typeof params.channelTopic !== "string" || !params.channelTopic.trim()) return;
|
|
2128
|
+
return [{
|
|
2129
|
+
label: "Discord channel metadata",
|
|
2130
|
+
source: "discord",
|
|
2131
|
+
type: "channel_metadata",
|
|
2132
|
+
payload: { topic: params.channelTopic.trim() }
|
|
2133
|
+
}];
|
|
2134
|
+
}
|
|
2135
|
+
function buildDiscordInboundAccessContext(params) {
|
|
2136
|
+
return {
|
|
2137
|
+
groupSystemPrompt: params.isGuild ? buildDiscordGroupSystemPrompt(params.channelConfig) : void 0,
|
|
2138
|
+
channelStructuredContext: buildDiscordChannelStructuredContext({
|
|
2139
|
+
isGuild: params.isGuild,
|
|
2140
|
+
channelTopic: params.channelTopic
|
|
2141
|
+
}),
|
|
2142
|
+
ownerAllowFrom: resolveDiscordOwnerAllowFrom({
|
|
2143
|
+
channelConfig: params.channelConfig,
|
|
2144
|
+
guildInfo: params.guildInfo,
|
|
2145
|
+
sender: params.sender,
|
|
2146
|
+
allowNameMatching: params.allowNameMatching
|
|
2147
|
+
})
|
|
2148
|
+
};
|
|
2149
|
+
}
|
|
2150
|
+
//#endregion
|
|
2151
|
+
//#region extensions/discord/src/monitor/native-command-context.ts
|
|
2152
|
+
async function buildDiscordNativeCommandContext(params) {
|
|
2153
|
+
const conversationLabel = params.isDirectMessage ? params.user.globalName ?? params.user.username : params.channelId;
|
|
2154
|
+
const { groupSystemPrompt, ownerAllowFrom, channelStructuredContext } = buildDiscordInboundAccessContext({
|
|
2155
|
+
channelConfig: params.channelConfig,
|
|
2156
|
+
guildInfo: params.guildInfo,
|
|
2157
|
+
sender: params.sender,
|
|
2158
|
+
allowNameMatching: params.allowNameMatching,
|
|
2159
|
+
isGuild: params.isGuild,
|
|
2160
|
+
channelTopic: params.channelTopic
|
|
2161
|
+
});
|
|
2162
|
+
const conversation = {
|
|
2163
|
+
kind: params.isDirectMessage ? "direct" : params.isGroupDm ? "group" : "channel",
|
|
2164
|
+
id: params.channelId,
|
|
2165
|
+
parentId: params.isThreadChannel ? params.threadParentId : void 0,
|
|
2166
|
+
threadId: params.isThreadChannel ? params.channelId : void 0
|
|
2167
|
+
};
|
|
2168
|
+
const allowFrom = params.commandAuthorized ? [`user:${params.user.id}`] : [];
|
|
2169
|
+
const channelIngress = await getDiscordRuntime().channel.inbound.ingress.createResolver({
|
|
2170
|
+
channelId: "discord",
|
|
2171
|
+
accountId: params.accountId,
|
|
2172
|
+
identity: discordIngressIdentity,
|
|
2173
|
+
useDefaultPairingStore: false
|
|
2174
|
+
}).command({
|
|
2175
|
+
subject: {
|
|
2176
|
+
stableId: params.user.id,
|
|
2177
|
+
aliases: { participantKind: "user" }
|
|
2178
|
+
},
|
|
2179
|
+
conversation,
|
|
2180
|
+
contextBinding: {
|
|
2181
|
+
agentId: params.agentId,
|
|
2182
|
+
sessionKey: params.sessionKey,
|
|
2183
|
+
nativeChannelId: params.channelId,
|
|
2184
|
+
messageId: params.interactionId,
|
|
2185
|
+
inboundEventKind: "user_request"
|
|
2186
|
+
},
|
|
2187
|
+
event: {
|
|
2188
|
+
kind: "native-command",
|
|
2189
|
+
mayPair: false
|
|
2190
|
+
},
|
|
2191
|
+
dmPolicy: "allowlist",
|
|
2192
|
+
groupPolicy: "allowlist",
|
|
2193
|
+
allowFrom,
|
|
2194
|
+
groupAllowFrom: allowFrom,
|
|
2195
|
+
command: { modeWhenAccessGroupsOff: "configured" }
|
|
2196
|
+
});
|
|
2197
|
+
return await (params.buildContext ?? buildChannelInboundEventContext)({
|
|
2198
|
+
channel: "discord",
|
|
2199
|
+
channelIngress,
|
|
2200
|
+
accountId: params.accountId,
|
|
2201
|
+
messageId: params.interactionId,
|
|
2202
|
+
timestamp: params.timestampMs ?? Date.now(),
|
|
2203
|
+
from: params.isDirectMessage ? `discord:${params.user.id}` : params.isGroupDm ? `discord:group:${params.channelId}` : `discord:channel:${params.channelId}`,
|
|
2204
|
+
sender: {
|
|
2205
|
+
id: params.user.id,
|
|
2206
|
+
name: params.user.globalName ?? params.user.username,
|
|
2207
|
+
username: params.user.username,
|
|
2208
|
+
tag: params.sender.tag,
|
|
2209
|
+
roles: params.memberRoleIds
|
|
2210
|
+
},
|
|
2211
|
+
conversation: {
|
|
2212
|
+
...conversation,
|
|
2213
|
+
nativeChannelId: params.channelId,
|
|
2214
|
+
routePeer: buildDiscordRoutePeer({
|
|
2215
|
+
isDirectMessage: params.isDirectMessage,
|
|
2216
|
+
isGroupDm: params.isGroupDm,
|
|
2217
|
+
directUserId: params.user.id,
|
|
2218
|
+
conversationId: params.channelId
|
|
2219
|
+
}),
|
|
2220
|
+
label: conversationLabel,
|
|
2221
|
+
spaceId: params.isGuild ? params.guildInfo?.id ?? params.guildInfo?.slug ?? params.guildId : void 0
|
|
2222
|
+
},
|
|
2223
|
+
route: {
|
|
2224
|
+
agentId: params.agentId,
|
|
2225
|
+
accountId: params.accountId,
|
|
2226
|
+
routeSessionKey: params.commandTargetSessionKey,
|
|
2227
|
+
dispatchSessionKey: params.sessionKey
|
|
2228
|
+
},
|
|
2229
|
+
reply: {
|
|
2230
|
+
to: `slash:${params.user.id}`,
|
|
2231
|
+
originatingTo: resolveDiscordConversationIdentity({
|
|
2232
|
+
isDirectMessage: params.isDirectMessage,
|
|
2233
|
+
userId: params.user.id,
|
|
2234
|
+
channelId: params.channelId
|
|
2235
|
+
}) ?? (params.isDirectMessage ? `user:${params.user.id}` : `channel:${params.channelId}`)
|
|
2236
|
+
},
|
|
2237
|
+
message: { rawBody: params.prompt },
|
|
2238
|
+
access: {
|
|
2239
|
+
mentions: {
|
|
2240
|
+
canDetectMention: true,
|
|
2241
|
+
wasMentioned: true
|
|
2242
|
+
},
|
|
2243
|
+
commands: { authorized: params.commandAuthorized }
|
|
2244
|
+
},
|
|
2245
|
+
commandTurn: {
|
|
2246
|
+
kind: "native",
|
|
2247
|
+
source: "native",
|
|
2248
|
+
authorized: params.commandAuthorized,
|
|
2249
|
+
body: params.prompt
|
|
2250
|
+
},
|
|
2251
|
+
supplemental: { groupSystemPrompt },
|
|
2252
|
+
extra: {
|
|
2253
|
+
CommandArgs: params.commandArgs,
|
|
2254
|
+
CommandTargetSessionKey: params.commandTargetSessionKey,
|
|
2255
|
+
CommandSource: "native",
|
|
2256
|
+
GroupSubject: params.isGuild ? params.guildName : void 0,
|
|
2257
|
+
ChannelStructuredContext: channelStructuredContext,
|
|
2258
|
+
OwnerAllowFrom: ownerAllowFrom
|
|
2259
|
+
}
|
|
2260
|
+
});
|
|
2261
|
+
}
|
|
2262
|
+
async function buildDiscordNativeInteractionContext(params) {
|
|
2263
|
+
const { interaction, route, boundSessionKey, sessionPrefix, channelContext, ...context } = params;
|
|
2264
|
+
const targets = resolveNativeCommandSessionTargets({
|
|
2265
|
+
agentId: route.agentId,
|
|
2266
|
+
sessionPrefix,
|
|
2267
|
+
userId: context.user.id,
|
|
2268
|
+
targetSessionKey: route.sessionKey,
|
|
2269
|
+
boundSessionKey
|
|
2270
|
+
});
|
|
2271
|
+
return {
|
|
2272
|
+
ctxPayload: await buildDiscordNativeCommandContext({
|
|
2273
|
+
...context,
|
|
2274
|
+
...targets,
|
|
2275
|
+
agentId: route.agentId,
|
|
2276
|
+
accountId: route.accountId,
|
|
2277
|
+
interactionId: interaction.rawData.id,
|
|
2278
|
+
channelId: channelContext.rawChannelId || "unknown",
|
|
2279
|
+
threadParentId: channelContext.threadParentId,
|
|
2280
|
+
memberRoleIds: Array.isArray(interaction.rawData.member?.roles) ? interaction.rawData.member.roles : [],
|
|
2281
|
+
guildId: interaction.guild?.id,
|
|
2282
|
+
guildName: interaction.guild?.name,
|
|
2283
|
+
channelTopic: resolveDiscordChannelTopicSafe(interaction.channel),
|
|
2284
|
+
isGuild: Boolean(interaction.guild),
|
|
2285
|
+
isDirectMessage: channelContext.isDirectMessage,
|
|
2286
|
+
isGroupDm: channelContext.isGroupDm,
|
|
2287
|
+
isThreadChannel: channelContext.isThreadChannel
|
|
2288
|
+
}),
|
|
2289
|
+
...targets
|
|
2290
|
+
};
|
|
2264
2291
|
}
|
|
2265
2292
|
//#endregion
|
|
2266
2293
|
//#region extensions/discord/src/monitor/native-interaction-channel-context.ts
|
|
@@ -2286,6 +2313,60 @@ async function resolveDiscordNativeInteractionChannelContext(params) {
|
|
|
2286
2313
|
}
|
|
2287
2314
|
//#endregion
|
|
2288
2315
|
//#region extensions/discord/src/monitor/native-command-auth.ts
|
|
2316
|
+
function resolveDiscordNativePolicyReader(params) {
|
|
2317
|
+
return params.readPolicy ?? createDiscordLivePolicyReader({
|
|
2318
|
+
...params,
|
|
2319
|
+
readConfig: () => getRuntimeConfigSnapshot() ?? params.cfg,
|
|
2320
|
+
resolvedAllowlist: {
|
|
2321
|
+
guildEntries: params.discordConfig?.guilds,
|
|
2322
|
+
allowFrom: params.discordConfig?.allowFrom ?? resolveDiscordAccountAllowFrom(params)
|
|
2323
|
+
}
|
|
2324
|
+
});
|
|
2325
|
+
}
|
|
2326
|
+
function createDiscordNativeCommandAuthority(params) {
|
|
2327
|
+
const assertAdmittedOwner = resolveCommandAuthorization(params).assertOwnerCurrent;
|
|
2328
|
+
const readAuthorization = () => {
|
|
2329
|
+
const cfg = getRuntimeConfigSnapshot() ?? params.cfg;
|
|
2330
|
+
const owners = resolveDiscordCommandOwnerAllowFrom(cfg);
|
|
2331
|
+
const senderIsOwner = params.isPolicyCurrent?.() !== false && (resolveDiscordOwnerAccess({
|
|
2332
|
+
allowFrom: owners,
|
|
2333
|
+
sender: params.sender,
|
|
2334
|
+
allowNameMatching: params.allowNameMatching
|
|
2335
|
+
}).ownerAllowed || resolveCommandAuthorization({
|
|
2336
|
+
...params,
|
|
2337
|
+
cfg
|
|
2338
|
+
}).senderIsOwner);
|
|
2339
|
+
const commands = resolveDiscordNativeCommandAllowlistAccess({
|
|
2340
|
+
cfg,
|
|
2341
|
+
sender: params.sender,
|
|
2342
|
+
guildId: params.guildId
|
|
2343
|
+
});
|
|
2344
|
+
return {
|
|
2345
|
+
senderIsOwner,
|
|
2346
|
+
allowed: (!commands.configured || commands.allowed) && (!owners || owners.includes("*") || senderIsOwner || commands.allowed || params.commandName === "status" || params.pluginCommand)
|
|
2347
|
+
};
|
|
2348
|
+
};
|
|
2349
|
+
const assertActive = () => {
|
|
2350
|
+
assertAdmittedOwner?.();
|
|
2351
|
+
if (params.isPolicyCurrent?.() === false || !readAuthorization().allowed) throw new Error("Discord command authority changed; send a new request.");
|
|
2352
|
+
};
|
|
2353
|
+
return {
|
|
2354
|
+
assertActive,
|
|
2355
|
+
assertOwnerCurrent: () => {
|
|
2356
|
+
assertActive();
|
|
2357
|
+
if (!readAuthorization().senderIsOwner) throw new Error("Discord owner authority changed; send a new request.");
|
|
2358
|
+
},
|
|
2359
|
+
senderIsOwner: () => readAuthorization().senderIsOwner,
|
|
2360
|
+
isAllowed: () => {
|
|
2361
|
+
try {
|
|
2362
|
+
assertActive();
|
|
2363
|
+
return true;
|
|
2364
|
+
} catch {
|
|
2365
|
+
return false;
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
};
|
|
2369
|
+
}
|
|
2289
2370
|
function resolveDiscordNativeCommandAllowlistAccess(params) {
|
|
2290
2371
|
const commandsAllowFrom = params.cfg.commands?.allowFrom;
|
|
2291
2372
|
if (!commandsAllowFrom || typeof commandsAllowFrom !== "object") return {
|
|
@@ -2327,10 +2408,7 @@ function resolveDiscordNativeCommandChannelAccessContext(params) {
|
|
|
2327
2408
|
const guild = params.guild ?? null;
|
|
2328
2409
|
const commandsAllowFromAccess = resolveDiscordNativeCommandAllowlistAccess({
|
|
2329
2410
|
cfg: params.cfg,
|
|
2330
|
-
accountId: params.accountId,
|
|
2331
2411
|
sender: params.sender,
|
|
2332
|
-
chatType: params.isDirectMessage ? "direct" : params.isThreadChannel ? "thread" : guild ? "channel" : "group",
|
|
2333
|
-
conversationId: params.rawChannelId || void 0,
|
|
2334
2412
|
guildId: guild?.id
|
|
2335
2413
|
});
|
|
2336
2414
|
const guildInfo = resolveDiscordGuildEntry({
|
|
@@ -2372,10 +2450,6 @@ async function resolveDiscordGuildNativeCommandAuthorized(params) {
|
|
|
2372
2450
|
sender: params.sender,
|
|
2373
2451
|
allowNameMatching: params.allowNameMatching
|
|
2374
2452
|
});
|
|
2375
|
-
const commandAllowlistAuthorizer = {
|
|
2376
|
-
configured: params.commandsAllowFromAccess.configured,
|
|
2377
|
-
allowed: params.commandsAllowFromAccess.allowed
|
|
2378
|
-
};
|
|
2379
2453
|
const ownerAuthorizer = {
|
|
2380
2454
|
configured: params.ownerAllowListConfigured,
|
|
2381
2455
|
allowed: params.ownerAllowed
|
|
@@ -2393,9 +2467,9 @@ async function resolveDiscordGuildNativeCommandAuthorized(params) {
|
|
|
2393
2467
|
ownerAuthorizer,
|
|
2394
2468
|
memberAuthorizer
|
|
2395
2469
|
];
|
|
2396
|
-
const authorizers = params.commandsAllowFromAccess.configured ? [
|
|
2470
|
+
const authorizers = params.commandsAllowFromAccess.configured ? [params.commandsAllowFromAccess] : fallbackAuthorizers;
|
|
2397
2471
|
return resolveCommandAuthorizedFromAuthorizers({
|
|
2398
|
-
useAccessGroups:
|
|
2472
|
+
useAccessGroups: true,
|
|
2399
2473
|
authorizers,
|
|
2400
2474
|
modeWhenAccessGroupsOff: "configured"
|
|
2401
2475
|
});
|
|
@@ -2425,43 +2499,31 @@ async function resolveDiscordNativeAutocompleteAuthorized(params) {
|
|
|
2425
2499
|
author: user,
|
|
2426
2500
|
pluralkitInfo: null
|
|
2427
2501
|
});
|
|
2428
|
-
const
|
|
2502
|
+
const channelContext = await resolveDiscordNativeInteractionChannelContext({
|
|
2429
2503
|
channel: interaction.channel,
|
|
2430
2504
|
client: interaction.client,
|
|
2431
2505
|
hasGuild: Boolean(interaction.guild),
|
|
2432
2506
|
channelIdFallback: interaction.rawData.channel_id ?? ""
|
|
2433
2507
|
});
|
|
2508
|
+
const { isDirectMessage, isGroupDm, isThreadChannel, channelName, channelSlug, rawChannelId, threadParentId } = channelContext;
|
|
2434
2509
|
if (params.isPolicyCurrent?.() === false) return false;
|
|
2435
2510
|
const memberRoleIds = Array.isArray(interaction.rawData.member?.roles) ? interaction.rawData.member.roles.map((roleId) => roleId) : [];
|
|
2436
2511
|
const allowNameMatching = isDangerousNameMatchingEnabled(discordConfig);
|
|
2437
|
-
const useAccessGroups = true;
|
|
2438
2512
|
const configuredDmAllowFrom = resolveDiscordAccountAllowFrom({
|
|
2439
2513
|
cfg,
|
|
2440
2514
|
accountId
|
|
2441
2515
|
}) ?? [];
|
|
2442
2516
|
const { ownerAllowList, ownerAllowed: ownerOk } = resolveDiscordOwnerAccess({
|
|
2443
2517
|
allowFrom: configuredDmAllowFrom,
|
|
2444
|
-
sender
|
|
2445
|
-
id: sender.id,
|
|
2446
|
-
name: sender.name,
|
|
2447
|
-
tag: sender.tag
|
|
2448
|
-
},
|
|
2518
|
+
sender,
|
|
2449
2519
|
allowNameMatching
|
|
2450
2520
|
});
|
|
2451
2521
|
const { commandsAllowFromAccess, guildInfo, channelConfig } = resolveDiscordNativeCommandChannelAccessContext({
|
|
2452
2522
|
cfg,
|
|
2453
2523
|
discordConfig,
|
|
2454
|
-
accountId,
|
|
2455
2524
|
sender,
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
guild: interaction.guild ?? null,
|
|
2459
|
-
rawChannelId,
|
|
2460
|
-
channelName,
|
|
2461
|
-
channelSlug,
|
|
2462
|
-
threadParentId,
|
|
2463
|
-
threadParentName,
|
|
2464
|
-
threadParentSlug
|
|
2525
|
+
...channelContext,
|
|
2526
|
+
guild: interaction.guild ?? null
|
|
2465
2527
|
});
|
|
2466
2528
|
if (channelConfig?.enabled === false) return false;
|
|
2467
2529
|
if (interaction.guild && channelConfig?.allowed === false) return false;
|
|
@@ -2488,11 +2550,7 @@ async function resolveDiscordNativeAutocompleteAuthorized(params) {
|
|
|
2488
2550
|
accountId,
|
|
2489
2551
|
dmPolicy,
|
|
2490
2552
|
configuredAllowFrom: configuredDmAllowFrom,
|
|
2491
|
-
sender
|
|
2492
|
-
id: sender.id,
|
|
2493
|
-
name: sender.name,
|
|
2494
|
-
tag: sender.tag
|
|
2495
|
-
},
|
|
2553
|
+
sender,
|
|
2496
2554
|
allowNameMatching,
|
|
2497
2555
|
cfg,
|
|
2498
2556
|
rest: interaction.client.rest
|
|
@@ -2507,162 +2565,73 @@ async function resolveDiscordNativeAutocompleteAuthorized(params) {
|
|
|
2507
2565
|
channelName,
|
|
2508
2566
|
channelSlug
|
|
2509
2567
|
}).allowed) return false;
|
|
2510
|
-
if (
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
allowNameMatching
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2568
|
+
if (!isDirectMessage) {
|
|
2569
|
+
if (!await resolveDiscordGuildNativeCommandAuthorized({
|
|
2570
|
+
cfg,
|
|
2571
|
+
discordConfig,
|
|
2572
|
+
commandsAllowFromAccess,
|
|
2573
|
+
guildInfo,
|
|
2574
|
+
channelConfig,
|
|
2575
|
+
memberRoleIds,
|
|
2576
|
+
sender,
|
|
2577
|
+
allowNameMatching,
|
|
2578
|
+
ownerAllowListConfigured: ownerAllowList != null,
|
|
2579
|
+
ownerAllowed: ownerOk
|
|
2580
|
+
})) return false;
|
|
2523
2581
|
}
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
discordConfig,
|
|
2528
|
-
useAccessGroups,
|
|
2529
|
-
commandsAllowFromAccess,
|
|
2530
|
-
guildInfo,
|
|
2531
|
-
channelConfig,
|
|
2532
|
-
memberRoleIds,
|
|
2582
|
+
const commandOwnerAllowFrom = resolveDiscordCommandOwnerAllowFrom(cfg);
|
|
2583
|
+
if (params.skipCommandOwnerAllowFrom !== true && commandOwnerAllowFrom && !commandOwnerAllowFrom.includes("*") && !commandsAllowFromAccess.allowed && !resolveDiscordOwnerAccess({
|
|
2584
|
+
allowFrom: commandOwnerAllowFrom,
|
|
2533
2585
|
sender,
|
|
2534
|
-
allowNameMatching
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2586
|
+
allowNameMatching
|
|
2587
|
+
}).ownerAllowed) {
|
|
2588
|
+
const routeState = resolveDiscordNativeInteractionRouteState({
|
|
2589
|
+
cfg,
|
|
2590
|
+
accountId,
|
|
2591
|
+
guildId: interaction.guild?.id,
|
|
2592
|
+
memberRoleIds,
|
|
2593
|
+
isDirectMessage,
|
|
2594
|
+
isGroupDm,
|
|
2595
|
+
directUserId: user.id,
|
|
2596
|
+
conversationId: rawChannelId,
|
|
2597
|
+
parentConversationId: threadParentId,
|
|
2598
|
+
threadBinding: isThreadChannel ? params.threadBindings?.getByThreadId(rawChannelId) : void 0
|
|
2599
|
+
});
|
|
2600
|
+
const { ctxPayload } = await buildDiscordNativeInteractionContext({
|
|
2601
|
+
buildContext: params.buildContext,
|
|
2602
|
+
interaction,
|
|
2603
|
+
channelContext,
|
|
2604
|
+
route: routeState.effectiveRoute,
|
|
2605
|
+
boundSessionKey: routeState.boundSessionKey,
|
|
2606
|
+
sessionPrefix: params.sessionPrefix ?? "discord:slash",
|
|
2607
|
+
channelConfig,
|
|
2608
|
+
guildInfo,
|
|
2609
|
+
allowNameMatching,
|
|
2610
|
+
commandAuthorized: true,
|
|
2611
|
+
user,
|
|
2612
|
+
sender,
|
|
2613
|
+
prompt: "",
|
|
2614
|
+
commandArgs: {}
|
|
2615
|
+
});
|
|
2616
|
+
if (!resolveCommandAuthorization({
|
|
2617
|
+
ctx: ctxPayload,
|
|
2618
|
+
cfg,
|
|
2619
|
+
commandAuthorized: true
|
|
2620
|
+
}).senderIsOwner) return false;
|
|
2621
|
+
}
|
|
2538
2622
|
return params.isPolicyCurrent?.() !== false;
|
|
2539
2623
|
}
|
|
2540
2624
|
//#endregion
|
|
2541
2625
|
//#region extensions/discord/src/monitor/native-command-bypass.ts
|
|
2542
2626
|
function shouldBypassConfiguredAcpEnsure(commandName) {
|
|
2543
|
-
|
|
2627
|
+
const command = commandName.trim().toLowerCase();
|
|
2628
|
+
return command === "acp" || command === "status";
|
|
2544
2629
|
}
|
|
2545
2630
|
function shouldBypassConfiguredAcpGuildGuards(commandName) {
|
|
2546
2631
|
const command = commandName.trim().toLowerCase();
|
|
2547
2632
|
return command === "new" || command === "reset";
|
|
2548
2633
|
}
|
|
2549
2634
|
//#endregion
|
|
2550
|
-
//#region extensions/discord/src/monitor/inbound-context.ts
|
|
2551
|
-
function createDiscordSupplementalContextAccessChecker(params) {
|
|
2552
|
-
const userAllowList = params.channelConfig?.users ?? params.guildInfo?.users ?? [];
|
|
2553
|
-
const roleAllowList = params.channelConfig?.roles ?? params.guildInfo?.roles ?? [];
|
|
2554
|
-
const allowFrom = [...userAllowList, ...roleAllowList];
|
|
2555
|
-
return (sender) => {
|
|
2556
|
-
return resolveInboundSupplementalSenderAllowed({
|
|
2557
|
-
isGroup: params.isGuild,
|
|
2558
|
-
groupPolicy: allowFrom.length === 0 ? "open" : "allowlist",
|
|
2559
|
-
allowFrom,
|
|
2560
|
-
isSenderAllowed: () => resolveDiscordMemberAllowed({
|
|
2561
|
-
userAllowList,
|
|
2562
|
-
roleAllowList,
|
|
2563
|
-
memberRoleIds: [...sender.memberRoleIds ?? []],
|
|
2564
|
-
userId: sender.id ?? "",
|
|
2565
|
-
userName: sender.name,
|
|
2566
|
-
userTag: sender.tag,
|
|
2567
|
-
allowNameMatching: params.allowNameMatching
|
|
2568
|
-
})
|
|
2569
|
-
});
|
|
2570
|
-
};
|
|
2571
|
-
}
|
|
2572
|
-
function buildDiscordGroupSystemPrompt(channelConfig) {
|
|
2573
|
-
return channelConfig?.systemPrompt?.trim() || void 0;
|
|
2574
|
-
}
|
|
2575
|
-
function buildDiscordChannelStructuredContext(params) {
|
|
2576
|
-
if (!params.isGuild) return;
|
|
2577
|
-
const entries = [];
|
|
2578
|
-
if (typeof params.channelTopic === "string" && params.channelTopic.trim().length > 0) entries.push({
|
|
2579
|
-
label: "Discord channel metadata",
|
|
2580
|
-
source: "discord",
|
|
2581
|
-
type: "channel_metadata",
|
|
2582
|
-
payload: { topic: params.channelTopic.trim() }
|
|
2583
|
-
});
|
|
2584
|
-
return entries.length > 0 ? entries : void 0;
|
|
2585
|
-
}
|
|
2586
|
-
function buildDiscordInboundAccessContext(params) {
|
|
2587
|
-
return {
|
|
2588
|
-
groupSystemPrompt: params.isGuild ? buildDiscordGroupSystemPrompt(params.channelConfig) : void 0,
|
|
2589
|
-
channelStructuredContext: buildDiscordChannelStructuredContext({
|
|
2590
|
-
isGuild: params.isGuild,
|
|
2591
|
-
channelTopic: params.channelTopic
|
|
2592
|
-
}),
|
|
2593
|
-
ownerAllowFrom: resolveDiscordOwnerAllowFrom({
|
|
2594
|
-
channelConfig: params.channelConfig,
|
|
2595
|
-
guildInfo: params.guildInfo,
|
|
2596
|
-
sender: params.sender,
|
|
2597
|
-
allowNameMatching: params.allowNameMatching
|
|
2598
|
-
})
|
|
2599
|
-
};
|
|
2600
|
-
}
|
|
2601
|
-
//#endregion
|
|
2602
|
-
//#region extensions/discord/src/monitor/native-command-context.ts
|
|
2603
|
-
function buildDiscordNativeCommandContext(params) {
|
|
2604
|
-
const conversationLabel = params.isDirectMessage ? params.user.globalName ?? params.user.username : params.channelId;
|
|
2605
|
-
const { groupSystemPrompt, ownerAllowFrom, channelStructuredContext } = buildDiscordInboundAccessContext({
|
|
2606
|
-
channelConfig: params.channelConfig,
|
|
2607
|
-
guildInfo: params.guildInfo,
|
|
2608
|
-
sender: params.sender,
|
|
2609
|
-
allowNameMatching: params.allowNameMatching,
|
|
2610
|
-
isGuild: params.isGuild,
|
|
2611
|
-
channelTopic: params.channelTopic
|
|
2612
|
-
});
|
|
2613
|
-
return finalizeInboundContext({
|
|
2614
|
-
Body: params.prompt,
|
|
2615
|
-
BodyForAgent: params.prompt,
|
|
2616
|
-
RawBody: params.prompt,
|
|
2617
|
-
CommandBody: params.prompt,
|
|
2618
|
-
CommandArgs: params.commandArgs,
|
|
2619
|
-
From: params.isDirectMessage ? `discord:${params.user.id}` : params.isGroupDm ? `discord:group:${params.channelId}` : `discord:channel:${params.channelId}`,
|
|
2620
|
-
To: `slash:${params.user.id}`,
|
|
2621
|
-
SessionKey: params.sessionKey,
|
|
2622
|
-
CommandTargetSessionKey: params.commandTargetSessionKey,
|
|
2623
|
-
AccountId: params.accountId ?? void 0,
|
|
2624
|
-
ChatType: params.isDirectMessage ? "direct" : params.isGroupDm ? "group" : "channel",
|
|
2625
|
-
...buildDiscordConversationRouteContext({
|
|
2626
|
-
isDirectMessage: params.isDirectMessage,
|
|
2627
|
-
isGroupDm: params.isGroupDm,
|
|
2628
|
-
directUserId: params.user.id,
|
|
2629
|
-
conversationId: params.channelId,
|
|
2630
|
-
isThread: params.isThreadChannel,
|
|
2631
|
-
parentConversationId: params.threadParentId
|
|
2632
|
-
}),
|
|
2633
|
-
ConversationLabel: conversationLabel,
|
|
2634
|
-
GroupSubject: params.isGuild ? params.guildName : void 0,
|
|
2635
|
-
GroupSpace: params.isGuild ? params.guildInfo?.id ?? params.guildInfo?.slug ?? params.guildId : void 0,
|
|
2636
|
-
MemberRoleIds: params.memberRoleIds,
|
|
2637
|
-
GroupSystemPrompt: groupSystemPrompt,
|
|
2638
|
-
ChannelStructuredContext: channelStructuredContext,
|
|
2639
|
-
OwnerAllowFrom: ownerAllowFrom,
|
|
2640
|
-
SenderName: params.user.globalName ?? params.user.username,
|
|
2641
|
-
SenderId: params.user.id,
|
|
2642
|
-
SenderUsername: params.user.username,
|
|
2643
|
-
SenderTag: params.sender.tag,
|
|
2644
|
-
Provider: "discord",
|
|
2645
|
-
Surface: "discord",
|
|
2646
|
-
WasMentioned: true,
|
|
2647
|
-
MessageSid: params.interactionId,
|
|
2648
|
-
Timestamp: params.timestampMs ?? Date.now(),
|
|
2649
|
-
CommandAuthorized: params.commandAuthorized,
|
|
2650
|
-
CommandTurn: {
|
|
2651
|
-
kind: "native",
|
|
2652
|
-
source: "native",
|
|
2653
|
-
authorized: params.commandAuthorized,
|
|
2654
|
-
body: params.prompt
|
|
2655
|
-
},
|
|
2656
|
-
CommandSource: "native",
|
|
2657
|
-
OriginatingChannel: "discord",
|
|
2658
|
-
OriginatingTo: resolveDiscordConversationIdentity({
|
|
2659
|
-
isDirectMessage: params.isDirectMessage,
|
|
2660
|
-
userId: params.user.id,
|
|
2661
|
-
channelId: params.channelId
|
|
2662
|
-
}) ?? (params.isDirectMessage ? `user:${params.user.id}` : `channel:${params.channelId}`)
|
|
2663
|
-
});
|
|
2664
|
-
}
|
|
2665
|
-
//#endregion
|
|
2666
2635
|
//#region extensions/discord/src/monitor/model-picker-preferences.ts
|
|
2667
2636
|
const DEFAULT_RECENT_LIMIT = 5;
|
|
2668
2637
|
const PREFERENCE_MAX_ENTRIES = 2e3;
|
|
@@ -2675,14 +2644,11 @@ function openPreferenceStore(env) {
|
|
|
2675
2644
|
...env ? { env } : {}
|
|
2676
2645
|
});
|
|
2677
2646
|
}
|
|
2678
|
-
function normalizeId(value) {
|
|
2679
|
-
return normalizeOptionalString(value) ?? "";
|
|
2680
|
-
}
|
|
2681
2647
|
function buildDiscordModelPickerPreferenceKey(scope) {
|
|
2682
|
-
const userId =
|
|
2648
|
+
const userId = normalizeOptionalString(scope.userId);
|
|
2683
2649
|
if (!userId) return null;
|
|
2684
2650
|
const accountId = normalizeAccountId(scope.accountId);
|
|
2685
|
-
const guildId =
|
|
2651
|
+
const guildId = normalizeOptionalString(scope.guildId);
|
|
2686
2652
|
if (guildId) return `discord:${accountId}:guild:${guildId}:user:${userId}`;
|
|
2687
2653
|
return `discord:${accountId}:dm:user:${userId}`;
|
|
2688
2654
|
}
|
|
@@ -2702,6 +2668,12 @@ function sanitizeStoredPreferenceEntry(value) {
|
|
|
2702
2668
|
function timestampOrder(value) {
|
|
2703
2669
|
return value !== void 0 && value >= 0 ? value : 0;
|
|
2704
2670
|
}
|
|
2671
|
+
function scopedPreferenceEntries(entries, scopeKey) {
|
|
2672
|
+
return entries.map((entry) => ({
|
|
2673
|
+
key: entry.key,
|
|
2674
|
+
value: sanitizeStoredPreferenceEntry(entry.value)
|
|
2675
|
+
})).filter((entry) => entry.value?.scopeKey === scopeKey);
|
|
2676
|
+
}
|
|
2705
2677
|
function comparePreferenceEntries(left, right) {
|
|
2706
2678
|
return preferenceTimestampMs(right.value.updatedAt) - preferenceTimestampMs(left.value.updatedAt) || timestampOrder(right.value.updatedOrder) - timestampOrder(left.value.updatedOrder) || left.key.localeCompare(right.key);
|
|
2707
2679
|
}
|
|
@@ -2720,10 +2692,7 @@ async function readDiscordModelPickerRecentModels(params) {
|
|
|
2720
2692
|
if (!key) return [];
|
|
2721
2693
|
const limit = Math.max(1, Math.min(params.limit ?? DEFAULT_RECENT_LIMIT, 10));
|
|
2722
2694
|
try {
|
|
2723
|
-
const recent = (await openPreferenceStore(params.env).entries()).map((entry) =>
|
|
2724
|
-
key: entry.key,
|
|
2725
|
-
value: sanitizeStoredPreferenceEntry(entry.value)
|
|
2726
|
-
})).filter((entry) => entry.value?.scopeKey === key).toSorted(comparePreferenceEntries).map((entry) => entry.value.modelRef);
|
|
2695
|
+
const recent = scopedPreferenceEntries(await openPreferenceStore(params.env).entries(), key).toSorted(comparePreferenceEntries).map((entry) => entry.value.modelRef);
|
|
2727
2696
|
if (!params.allowedModelRefs || params.allowedModelRefs.size === 0) return sanitizeRecentModels(recent, limit);
|
|
2728
2697
|
return sanitizeRecentModels(recent.filter((modelRef) => params.allowedModelRefs?.has(modelRef)), limit);
|
|
2729
2698
|
} catch {
|
|
@@ -2736,17 +2705,14 @@ async function recordDiscordModelPickerRecentModel(params) {
|
|
|
2736
2705
|
if (!key || !normalizedModelRef) return;
|
|
2737
2706
|
try {
|
|
2738
2707
|
const store = openPreferenceStore(params.env);
|
|
2739
|
-
const timestamp = nextPreferenceTimestamp((await store.entries()).map((entry) =>
|
|
2708
|
+
const timestamp = nextPreferenceTimestamp(scopedPreferenceEntries(await store.entries(), key).map((entry) => entry.value));
|
|
2740
2709
|
await store.register(buildPreferenceModelKey(key, normalizedModelRef), {
|
|
2741
2710
|
scopeKey: key,
|
|
2742
2711
|
modelRef: normalizedModelRef,
|
|
2743
2712
|
...timestamp
|
|
2744
2713
|
});
|
|
2745
2714
|
const limit = Math.max(1, Math.min(params.limit ?? DEFAULT_RECENT_LIMIT, 10));
|
|
2746
|
-
const scopedEntries = (await store.entries()).
|
|
2747
|
-
key: entry.key,
|
|
2748
|
-
value: sanitizeStoredPreferenceEntry(entry.value)
|
|
2749
|
-
})).filter((entry) => entry.value?.scopeKey === key).toSorted(comparePreferenceEntries);
|
|
2715
|
+
const scopedEntries = scopedPreferenceEntries(await store.entries(), key).toSorted(comparePreferenceEntries);
|
|
2750
2716
|
await Promise.all(scopedEntries.slice(limit).map((entry) => store.delete(entry.key)));
|
|
2751
2717
|
} catch {}
|
|
2752
2718
|
}
|
|
@@ -2789,11 +2755,6 @@ const PICKER_VIEWS = [
|
|
|
2789
2755
|
"models",
|
|
2790
2756
|
"recents"
|
|
2791
2757
|
];
|
|
2792
|
-
/**
|
|
2793
|
-
* Alpha buckets engage only when the sorted item list exceeds the single-page
|
|
2794
|
-
* select cap. Below this threshold the user gets the existing flat list +
|
|
2795
|
-
* prev/next behavior unchanged.
|
|
2796
|
-
*/
|
|
2797
2758
|
const DISCORD_MODEL_PICKER_BUCKET_THRESHOLD = DISCORD_COMPONENT_MAX_SELECT_OPTIONS;
|
|
2798
2759
|
/** Target items per alpha bucket. Discord caps selects at 25 options. */
|
|
2799
2760
|
const DISCORD_MODEL_PICKER_BUCKET_TARGET_SIZE = 20;
|
|
@@ -2815,9 +2776,7 @@ function isValidPickerView(value) {
|
|
|
2815
2776
|
return PICKER_VIEWS.includes(value);
|
|
2816
2777
|
}
|
|
2817
2778
|
function normalizeModelPickerPage(value) {
|
|
2818
|
-
|
|
2819
|
-
if (!Number.isFinite(numeric)) return 1;
|
|
2820
|
-
return Math.max(1, Math.floor(numeric));
|
|
2779
|
+
return normalizeOptionalModelPickerIndex(value) ?? 1;
|
|
2821
2780
|
}
|
|
2822
2781
|
function parseRawPage(value) {
|
|
2823
2782
|
if (typeof value === "number") return normalizeModelPickerPage(value);
|
|
@@ -2948,17 +2907,6 @@ function parseDiscordModelPickerData(data) {
|
|
|
2948
2907
|
...modelBucketRaw ? { modelBucket: modelBucketRaw } : {}
|
|
2949
2908
|
};
|
|
2950
2909
|
}
|
|
2951
|
-
/**
|
|
2952
|
-
* Split a sorted item list into letter-range buckets when its length exceeds
|
|
2953
|
-
* {@link DISCORD_MODEL_PICKER_BUCKET_THRESHOLD}. Items below the threshold
|
|
2954
|
-
* return a single "All" bucket so callers can render the same code path.
|
|
2955
|
-
*
|
|
2956
|
-
* The boundary extender keeps items sharing the same starting letter inside
|
|
2957
|
-
* the same bucket — selecting "A–G" never strands a stray "g" item in the
|
|
2958
|
-
* next bucket. If every item shares a first letter (e.g. all `qwen3-*`),
|
|
2959
|
-
* the function falls back to count-based numeric chunks so the user still
|
|
2960
|
-
* gets a finite-cardinality picker.
|
|
2961
|
-
*/
|
|
2962
2910
|
function computeAlphaBuckets(sortedItems) {
|
|
2963
2911
|
if (sortedItems.length === 0) return [];
|
|
2964
2912
|
if (sortedItems.length <= DISCORD_MODEL_PICKER_BUCKET_THRESHOLD) return [{
|
|
@@ -2993,16 +2941,8 @@ function computeAlphaBuckets(sortedItems) {
|
|
|
2993
2941
|
}
|
|
2994
2942
|
return buckets;
|
|
2995
2943
|
}
|
|
2996
|
-
/**
|
|
2997
|
-
* Pick the per-bucket target size such that the resulting bucket count never
|
|
2998
|
-
* exceeds {@link DISCORD_COMPONENT_MAX_SELECT_OPTIONS} (Discord's hard select
|
|
2999
|
-
* cap). Stays at the default {@link DISCORD_MODEL_PICKER_BUCKET_TARGET_SIZE}
|
|
3000
|
-
* for typical inputs and grows linearly for very large lists.
|
|
3001
|
-
*/
|
|
3002
2944
|
function computeBucketTargetSize(totalItems) {
|
|
3003
|
-
|
|
3004
|
-
const capByBucketCount = Math.ceil(totalItems / DISCORD_COMPONENT_MAX_SELECT_OPTIONS);
|
|
3005
|
-
return Math.max(minTarget, capByBucketCount);
|
|
2945
|
+
return Math.max(DISCORD_MODEL_PICKER_BUCKET_TARGET_SIZE, Math.ceil(totalItems / DISCORD_COMPONENT_MAX_SELECT_OPTIONS));
|
|
3006
2946
|
}
|
|
3007
2947
|
function chunkBucketsByCount(sortedItems) {
|
|
3008
2948
|
const buckets = [];
|
|
@@ -3018,37 +2958,15 @@ function chunkBucketsByCount(sortedItems) {
|
|
|
3018
2958
|
}
|
|
3019
2959
|
return buckets;
|
|
3020
2960
|
}
|
|
3021
|
-
/**
|
|
3022
|
-
* Resolve a bucket from a list given a (possibly user-supplied) bucket id.
|
|
3023
|
-
* Falls back to the first bucket when the id does not match — mirrors the
|
|
3024
|
-
* "bad customId → reset to defaults" semantics already used for other
|
|
3025
|
-
* state fields.
|
|
3026
|
-
*/
|
|
3027
2961
|
function resolveBucket(buckets, id) {
|
|
3028
|
-
|
|
3029
|
-
if (!id) return expectDefined(buckets.at(0), "non-empty model picker buckets");
|
|
3030
|
-
return buckets.find((bucket) => bucket.id === id) ?? expectDefined(buckets.at(0), "non-empty model picker buckets");
|
|
2962
|
+
return buckets.find((bucket) => bucket.id === id) ?? buckets[0] ?? null;
|
|
3031
2963
|
}
|
|
3032
|
-
/**
|
|
3033
|
-
* Derive the alpha-bucket id that contains a given provider id. Returns
|
|
3034
|
-
* `undefined` when bucketing is inactive (all providers fit in one bucket)
|
|
3035
|
-
* or the provider is unknown. Used by the interaction handler to recompute
|
|
3036
|
-
* `providerBucket` at re-render time without forcing every customId to
|
|
3037
|
-
* carry the bucket field — the bucket is a pure function of the provider
|
|
3038
|
-
* list + provider id.
|
|
3039
|
-
*/
|
|
3040
2964
|
function findProviderBucketId(data, provider) {
|
|
3041
2965
|
return findProviderBucketLocation(data, provider)?.bucket;
|
|
3042
2966
|
}
|
|
3043
2967
|
function findProviderBucketLocation(data, provider) {
|
|
3044
2968
|
return findModelPickerBucketLocation([...data.providers].toSorted(), normalizeProviderId(provider));
|
|
3045
2969
|
}
|
|
3046
|
-
/**
|
|
3047
|
-
* Derive the alpha-bucket id that contains a given model id within the
|
|
3048
|
-
* named provider. Same rationale as {@link findProviderBucketId} — saves
|
|
3049
|
-
* customId budget by recomputing the bucket from the durable state
|
|
3050
|
-
* (provider + model) rather than carrying it as a parameter.
|
|
3051
|
-
*/
|
|
3052
2970
|
function findModelBucketId(data, provider, model) {
|
|
3053
2971
|
const modelSet = data.byProvider.get(normalizeProviderId(provider));
|
|
3054
2972
|
return modelSet ? findModelPickerBucketLocation([...modelSet].toSorted(compareBucketItems), model)?.bucket : void 0;
|
|
@@ -3156,14 +3074,6 @@ function createModelSelect(params) {
|
|
|
3156
3074
|
}
|
|
3157
3075
|
return new DiscordModelPickerSelect();
|
|
3158
3076
|
}
|
|
3159
|
-
/**
|
|
3160
|
-
* Build the alpha-bucket select row that appears above the provider/model
|
|
3161
|
-
* surface when the list exceeds {@link DISCORD_MODEL_PICKER_BUCKET_THRESHOLD}.
|
|
3162
|
-
*
|
|
3163
|
-
* Selecting a bucket emits action=bucket. The chosen bucket travels in the
|
|
3164
|
-
* select value, while the custom_id carries only the stable context needed to
|
|
3165
|
-
* rebuild the picker under Discord's 100-character custom_id limit.
|
|
3166
|
-
*/
|
|
3167
3077
|
function buildBucketSelectRow(params) {
|
|
3168
3078
|
if (params.buckets.length <= 1) return null;
|
|
3169
3079
|
const options = params.buckets.map((bucket) => ({
|
|
@@ -3197,11 +3107,6 @@ function resolveExplicitRuntimeState(params) {
|
|
|
3197
3107
|
const runtime = params.pendingRuntime?.trim() || params.currentRuntime?.trim();
|
|
3198
3108
|
return runtime && runtime !== "auto" && runtime !== "default" ? runtime : void 0;
|
|
3199
3109
|
}
|
|
3200
|
-
function resolveSelectedRuntime(params) {
|
|
3201
|
-
const choices = getRuntimeChoices(params);
|
|
3202
|
-
const explicit = resolveExplicitRuntimeState(params);
|
|
3203
|
-
return explicit ? choices?.find((choice) => choice.id === explicit)?.id : choices?.[0]?.id;
|
|
3204
|
-
}
|
|
3205
3110
|
function getActiveBucketId(bucket) {
|
|
3206
3111
|
return bucket && bucket.id !== "all" ? bucket.id : void 0;
|
|
3207
3112
|
}
|
|
@@ -3237,18 +3142,18 @@ function buildRenderedShell(params) {
|
|
|
3237
3142
|
return { components: [new Container(containerComponents)] };
|
|
3238
3143
|
}
|
|
3239
3144
|
function buildProviderSelectRow(params) {
|
|
3240
|
-
if (params.page.items.length === 0) return null;
|
|
3241
3145
|
const options = params.page.items.map((provider) => ({
|
|
3242
3146
|
label: provider.id,
|
|
3243
3147
|
value: provider.id,
|
|
3244
3148
|
default: provider.id === params.currentProvider,
|
|
3245
|
-
description: `${provider.count} ${provider.count === 1 ? "model" : "models"}`
|
|
3149
|
+
...params.showModelCounts ? { description: `${provider.count} ${provider.count === 1 ? "model" : "models"}` } : {}
|
|
3246
3150
|
}));
|
|
3247
3151
|
return new Row([createModelSelect({
|
|
3248
3152
|
customId: buildDiscordModelPickerCustomId({
|
|
3249
3153
|
command: params.command,
|
|
3250
3154
|
action: "provider",
|
|
3251
3155
|
view: "models",
|
|
3156
|
+
provider: params.provider,
|
|
3252
3157
|
page: params.page.page,
|
|
3253
3158
|
providerPage: params.page.page,
|
|
3254
3159
|
providerBucket: params.providerBucket,
|
|
@@ -3292,40 +3197,27 @@ function buildModelRows(params) {
|
|
|
3292
3197
|
page: params.providerPage,
|
|
3293
3198
|
bucket: params.providerBucket
|
|
3294
3199
|
});
|
|
3295
|
-
const providerOptions = providerPage.items.map((provider) => ({
|
|
3296
|
-
label: provider.id,
|
|
3297
|
-
value: provider.id,
|
|
3298
|
-
default: provider.id === params.modelPage.provider
|
|
3299
|
-
}));
|
|
3300
3200
|
const activeProviderBucket = getActiveBucketId(providerPage.bucket);
|
|
3301
3201
|
const activeModelBucket = getActiveBucketId(params.modelPage.bucket);
|
|
3302
|
-
if (!((params.modelPage.buckets?.length ?? 0) > 1)) rows.push(
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
providerBucket: activeProviderBucket,
|
|
3311
|
-
userId: params.userId
|
|
3312
|
-
}),
|
|
3313
|
-
options: providerOptions,
|
|
3314
|
-
placeholder: "Select provider"
|
|
3315
|
-
})]));
|
|
3202
|
+
if (!((params.modelPage.buckets?.length ?? 0) > 1)) rows.push(buildProviderSelectRow({
|
|
3203
|
+
command: params.command,
|
|
3204
|
+
userId: params.userId,
|
|
3205
|
+
page: providerPage,
|
|
3206
|
+
provider: params.modelPage.provider,
|
|
3207
|
+
currentProvider: params.modelPage.provider,
|
|
3208
|
+
providerBucket: activeProviderBucket
|
|
3209
|
+
}));
|
|
3316
3210
|
const runtimeChoices = getRuntimeChoices({
|
|
3317
3211
|
data: params.data,
|
|
3318
3212
|
provider: params.modelPage.provider,
|
|
3319
3213
|
modelRef: params.pendingModel ?? params.currentModel
|
|
3320
3214
|
});
|
|
3321
3215
|
const currentRuntime = parsedCurrentModel?.provider === params.modelPage.provider ? params.currentRuntime : void 0;
|
|
3322
|
-
const
|
|
3323
|
-
data: params.data,
|
|
3324
|
-
provider: params.modelPage.provider,
|
|
3325
|
-
modelRef: params.pendingModel ?? params.currentModel,
|
|
3216
|
+
const explicitRuntime = resolveExplicitRuntimeState({
|
|
3326
3217
|
currentRuntime,
|
|
3327
3218
|
pendingRuntime: params.pendingRuntime
|
|
3328
3219
|
});
|
|
3220
|
+
const selectedRuntime = explicitRuntime ? runtimeChoices?.find((choice) => choice.id === explicitRuntime)?.id : runtimeChoices?.[0]?.id;
|
|
3329
3221
|
const compactRuntime = resolveCompactRuntimeState({
|
|
3330
3222
|
currentRuntime,
|
|
3331
3223
|
pendingRuntime: params.pendingRuntime
|
|
@@ -3387,7 +3279,7 @@ function buildModelRows(params) {
|
|
|
3387
3279
|
providerPage: providerPage.page,
|
|
3388
3280
|
modelIndex: params.pendingModelIndex,
|
|
3389
3281
|
modelToken: pendingModelToken,
|
|
3390
|
-
modelBucket:
|
|
3282
|
+
modelBucket: activeModelBucket
|
|
3391
3283
|
});
|
|
3392
3284
|
if (modelNavRow) rows.push(modelNavRow);
|
|
3393
3285
|
const resolvedDefault = params.data.resolvedDefault;
|
|
@@ -3454,7 +3346,9 @@ function buildModelRows(params) {
|
|
|
3454
3346
|
}));
|
|
3455
3347
|
return {
|
|
3456
3348
|
rows,
|
|
3457
|
-
buttonRow: new Row(buttonRowItems)
|
|
3349
|
+
buttonRow: new Row(buttonRowItems),
|
|
3350
|
+
runtimeChoices,
|
|
3351
|
+
selectedRuntime
|
|
3458
3352
|
};
|
|
3459
3353
|
}
|
|
3460
3354
|
function renderDiscordModelPickerProvidersView(params) {
|
|
@@ -3473,15 +3367,15 @@ function renderDiscordModelPickerProvidersView(params) {
|
|
|
3473
3367
|
currentBucketId: page.bucket?.id
|
|
3474
3368
|
});
|
|
3475
3369
|
if (bucketRow) rows.push(bucketRow);
|
|
3476
|
-
const activeProviderBucket = page.bucket
|
|
3477
|
-
|
|
3370
|
+
const activeProviderBucket = getActiveBucketId(page.bucket);
|
|
3371
|
+
if (page.items.length > 0) rows.push(buildProviderSelectRow({
|
|
3478
3372
|
command: params.command,
|
|
3479
3373
|
userId: params.userId,
|
|
3480
3374
|
page,
|
|
3481
3375
|
currentProvider: parsedCurrent?.provider,
|
|
3482
|
-
providerBucket: activeProviderBucket
|
|
3483
|
-
|
|
3484
|
-
|
|
3376
|
+
providerBucket: activeProviderBucket,
|
|
3377
|
+
showModelCounts: true
|
|
3378
|
+
}));
|
|
3485
3379
|
const navRow = buildPaginationRow({
|
|
3486
3380
|
command: params.command,
|
|
3487
3381
|
userId: params.userId,
|
|
@@ -3531,19 +3425,10 @@ function renderDiscordModelPickerModelsView(params) {
|
|
|
3531
3425
|
footer: "Choose a different provider."
|
|
3532
3426
|
});
|
|
3533
3427
|
}
|
|
3534
|
-
const { rows: modelRows, buttonRow } = buildModelRows({
|
|
3535
|
-
|
|
3536
|
-
userId: params.userId,
|
|
3537
|
-
data: params.data,
|
|
3428
|
+
const { rows: modelRows, buttonRow, runtimeChoices: choices, selectedRuntime } = buildModelRows({
|
|
3429
|
+
...params,
|
|
3538
3430
|
providerPage,
|
|
3539
|
-
modelPage
|
|
3540
|
-
currentModel: params.currentModel,
|
|
3541
|
-
currentRuntime: params.currentRuntime,
|
|
3542
|
-
pendingModel: params.pendingModel,
|
|
3543
|
-
pendingModelIndex: params.pendingModelIndex,
|
|
3544
|
-
pendingRuntime: params.pendingRuntime,
|
|
3545
|
-
quickModels: params.quickModels,
|
|
3546
|
-
providerBucket: params.providerBucket
|
|
3431
|
+
modelPage
|
|
3547
3432
|
});
|
|
3548
3433
|
const pendingRuntime = params.pendingRuntime?.trim();
|
|
3549
3434
|
const rows = [];
|
|
@@ -3555,24 +3440,11 @@ function renderDiscordModelPickerModelsView(params) {
|
|
|
3555
3440
|
currentBucketId: modelPage.bucket?.id,
|
|
3556
3441
|
provider: modelPage.provider,
|
|
3557
3442
|
runtimeToken: pendingRuntime ? createDiscordModelPickerRuntimeToken(pendingRuntime) : void 0,
|
|
3558
|
-
providerPage
|
|
3559
|
-
providerBucket: params.providerBucket
|
|
3443
|
+
providerPage
|
|
3560
3444
|
});
|
|
3561
3445
|
if (bucketRow) rows.push(bucketRow);
|
|
3562
3446
|
rows.push(...modelRows);
|
|
3563
3447
|
const defaultModel = `${params.data.resolvedDefault.provider}/${params.data.resolvedDefault.model}`;
|
|
3564
|
-
const choices = getRuntimeChoices({
|
|
3565
|
-
data: params.data,
|
|
3566
|
-
provider: modelPage.provider,
|
|
3567
|
-
modelRef: params.pendingModel ?? params.currentModel
|
|
3568
|
-
});
|
|
3569
|
-
const selectedRuntime = resolveSelectedRuntime({
|
|
3570
|
-
data: params.data,
|
|
3571
|
-
provider: modelPage.provider,
|
|
3572
|
-
modelRef: params.pendingModel ?? params.currentModel,
|
|
3573
|
-
currentRuntime: parseCurrentModelRef(params.currentModel)?.provider === modelPage.provider ? params.currentRuntime : void 0,
|
|
3574
|
-
pendingRuntime: params.pendingRuntime
|
|
3575
|
-
});
|
|
3576
3448
|
const selectedRuntimeLabel = choices?.find((choice) => choice.id === selectedRuntime)?.label;
|
|
3577
3449
|
const pendingLine = !params.pendingModel ? "Select a model, then press Submit." : !supportsDiscordModelPickerRuntimeChoices() ? `Selected: ${params.pendingModel} (press Submit)` : choices === void 0 ? "Could not confirm how to run this model. Open /models to try again." : choices.length === 0 ? "This model cannot run with your current connections. Choose another model." : selectedRuntimeLabel ? `Selected: ${params.pendingModel} · ${selectedRuntimeLabel} (press Submit)` : "Choose how to run this model, then press Submit.";
|
|
3578
3450
|
const detailLines = [formatCurrentModelLine(params.currentModel), `Default: ${defaultModel}`];
|
|
@@ -3662,6 +3534,7 @@ async function applyDiscordModelPickerSelection(params) {
|
|
|
3662
3534
|
preferFollowUp: true,
|
|
3663
3535
|
threadBindings: params.threadBindings,
|
|
3664
3536
|
suppressReplies: true,
|
|
3537
|
+
buildContext: params.buildContext,
|
|
3665
3538
|
dispatchReplyFromConfig: params.dispatchReplyFromConfig,
|
|
3666
3539
|
pluginCommandDispatch: { kind: "non-plugin" }
|
|
3667
3540
|
}), 12e3);
|
|
@@ -3710,21 +3583,11 @@ async function applyDiscordModelPickerSelection(params) {
|
|
|
3710
3583
|
}
|
|
3711
3584
|
//#endregion
|
|
3712
3585
|
//#region extensions/discord/src/monitor/native-command-model-picker-ui.ts
|
|
3713
|
-
function resolveDiscordModelPickerCommandContext(command) {
|
|
3714
|
-
const normalized = normalizeLowercaseStringOrEmpty(command.nativeName ?? command.key);
|
|
3715
|
-
if (normalized === "model" || normalized === "models") return normalized;
|
|
3716
|
-
return null;
|
|
3717
|
-
}
|
|
3718
|
-
function resolveCommandArgStringValue(args, key) {
|
|
3719
|
-
const value = args?.values?.[key];
|
|
3720
|
-
if (typeof value !== "string") return "";
|
|
3721
|
-
return value.trim();
|
|
3722
|
-
}
|
|
3723
3586
|
function shouldOpenDiscordModelPickerFromCommand(params) {
|
|
3724
|
-
const context =
|
|
3725
|
-
if (
|
|
3587
|
+
const context = normalizeLowercaseStringOrEmpty(params.command.nativeName ?? params.command.key);
|
|
3588
|
+
if (context !== "model" && context !== "models") return null;
|
|
3726
3589
|
const serializedArgs = normalizeOptionalString(serializeCommandArgs(params.command, params.commandArgs)) ?? "";
|
|
3727
|
-
if (context === "model") return !
|
|
3590
|
+
if (context === "model") return !normalizeOptionalString(params.commandArgs?.values?.model) && !serializedArgs ? context : null;
|
|
3728
3591
|
return serializedArgs ? null : context;
|
|
3729
3592
|
}
|
|
3730
3593
|
function buildDiscordModelPickerAllowedModelRefs(data) {
|
|
@@ -3746,7 +3609,7 @@ function resolveDiscordModelPickerPreferenceScope(params) {
|
|
|
3746
3609
|
function buildDiscordModelPickerNoticePayload(message) {
|
|
3747
3610
|
return { components: [new Container([new TextDisplay(message)])] };
|
|
3748
3611
|
}
|
|
3749
|
-
async function
|
|
3612
|
+
async function resolveDiscordModelPickerRoute(params) {
|
|
3750
3613
|
const { interaction, cfg, accountId } = params;
|
|
3751
3614
|
const { isDirectMessage, isGroupDm, isThreadChannel, rawChannelId, threadParentId } = await resolveDiscordNativeInteractionChannelContext({
|
|
3752
3615
|
channel: interaction.channel,
|
|
@@ -3756,7 +3619,7 @@ async function resolveDiscordModelPickerRouteState(params) {
|
|
|
3756
3619
|
});
|
|
3757
3620
|
const memberRoleIds = Array.isArray(interaction.rawData.member?.roles) ? interaction.rawData.member.roles.map((roleId) => roleId) : [];
|
|
3758
3621
|
const threadBinding = isThreadChannel ? params.threadBindings.getByThreadId(rawChannelId) : void 0;
|
|
3759
|
-
return
|
|
3622
|
+
return resolveDiscordNativeInteractionRouteState({
|
|
3760
3623
|
cfg,
|
|
3761
3624
|
accountId,
|
|
3762
3625
|
guildId: interaction.guild?.id ?? void 0,
|
|
@@ -3766,24 +3629,12 @@ async function resolveDiscordModelPickerRouteState(params) {
|
|
|
3766
3629
|
directUserId: interaction.user?.id ?? rawChannelId,
|
|
3767
3630
|
conversationId: rawChannelId,
|
|
3768
3631
|
parentConversationId: threadParentId,
|
|
3769
|
-
threadBinding
|
|
3770
|
-
|
|
3771
|
-
});
|
|
3772
|
-
}
|
|
3773
|
-
async function resolveDiscordModelPickerRoute(params) {
|
|
3774
|
-
return (await resolveDiscordModelPickerRouteState(params)).effectiveRoute;
|
|
3632
|
+
threadBinding
|
|
3633
|
+
}).effectiveRoute;
|
|
3775
3634
|
}
|
|
3776
3635
|
async function resolveDiscordNativeChoiceContext(params) {
|
|
3777
3636
|
try {
|
|
3778
|
-
const
|
|
3779
|
-
interaction: params.interaction,
|
|
3780
|
-
cfg: params.cfg,
|
|
3781
|
-
accountId: params.accountId,
|
|
3782
|
-
threadBindings: params.threadBindings,
|
|
3783
|
-
enforceConfiguredBindingReadiness: true
|
|
3784
|
-
});
|
|
3785
|
-
if (resolved.bindingReadiness && !resolved.bindingReadiness.ok) return null;
|
|
3786
|
-
const route = resolved.effectiveRoute;
|
|
3637
|
+
const route = params.route ?? await resolveDiscordModelPickerRoute(params);
|
|
3787
3638
|
const fallback = resolveDefaultModelForAgent({
|
|
3788
3639
|
cfg: params.cfg,
|
|
3789
3640
|
agentId: route.agentId
|
|
@@ -3898,8 +3749,6 @@ async function replyWithDiscordModelPickerProviders(params) {
|
|
|
3898
3749
|
provider: initialProvider,
|
|
3899
3750
|
model: parsedCurrentRef.model
|
|
3900
3751
|
}) : { page: 1 };
|
|
3901
|
-
const initialPage = initialResolved.page;
|
|
3902
|
-
const initialModelBucket = initialResolved.bucket;
|
|
3903
3752
|
const initialProviderLocation = findProviderBucketLocation(data, initialProvider);
|
|
3904
3753
|
const payload = {
|
|
3905
3754
|
...renderDiscordModelPickerModelsView({
|
|
@@ -3907,10 +3756,10 @@ async function replyWithDiscordModelPickerProviders(params) {
|
|
|
3907
3756
|
userId: params.userId,
|
|
3908
3757
|
data,
|
|
3909
3758
|
provider: initialProvider,
|
|
3910
|
-
page:
|
|
3759
|
+
page: initialResolved.page,
|
|
3911
3760
|
providerPage: initialProviderLocation?.page ?? 1,
|
|
3912
3761
|
providerBucket: initialProviderLocation?.bucket,
|
|
3913
|
-
modelBucket:
|
|
3762
|
+
modelBucket: initialResolved.bucket,
|
|
3914
3763
|
currentModel,
|
|
3915
3764
|
currentRuntime,
|
|
3916
3765
|
quickModels
|
|
@@ -3918,11 +3767,7 @@ async function replyWithDiscordModelPickerProviders(params) {
|
|
|
3918
3767
|
ephemeral: true
|
|
3919
3768
|
};
|
|
3920
3769
|
await params.safeInteractionCall("model picker reply", async () => {
|
|
3921
|
-
|
|
3922
|
-
await params.interaction.followUp(payload);
|
|
3923
|
-
return;
|
|
3924
|
-
}
|
|
3925
|
-
await params.interaction.reply(payload);
|
|
3770
|
+
await params.interaction[params.preferFollowUp ? "followUp" : "reply"](payload);
|
|
3926
3771
|
});
|
|
3927
3772
|
}
|
|
3928
3773
|
function splitDiscordModelRef(modelRef) {
|
|
@@ -3940,11 +3785,7 @@ function splitDiscordModelRef(modelRef) {
|
|
|
3940
3785
|
//#endregion
|
|
3941
3786
|
//#region extensions/discord/src/monitor/native-command-model-picker-interaction.ts
|
|
3942
3787
|
function resolveModelPickerSelectionValue(interaction) {
|
|
3943
|
-
|
|
3944
|
-
if (!Array.isArray(rawValues) || rawValues.length === 0) return null;
|
|
3945
|
-
const first = rawValues[0];
|
|
3946
|
-
if (typeof first !== "string") return null;
|
|
3947
|
-
return first.trim() || null;
|
|
3788
|
+
return normalizeOptionalString(interaction.values?.[0]) ?? null;
|
|
3948
3789
|
}
|
|
3949
3790
|
function resolveRuntimeToken(choices, token) {
|
|
3950
3791
|
if (!token) return;
|
|
@@ -4011,15 +3852,11 @@ function resolveDiscordModelPickerModelRefByToken(data, modelToken) {
|
|
|
4011
3852
|
return matchingRefs.length === 1 ? matchingRefs[0] ?? null : null;
|
|
4012
3853
|
}
|
|
4013
3854
|
function resolveDiscordModelPickerModelIndex(params) {
|
|
4014
|
-
const
|
|
4015
|
-
|
|
4016
|
-
const index = models.indexOf(params.model);
|
|
4017
|
-
if (index < 0) return null;
|
|
4018
|
-
return index + 1;
|
|
3855
|
+
const index = listDiscordModelPickerProviderModels(params.data, params.provider).indexOf(params.model);
|
|
3856
|
+
return index < 0 ? null : index + 1;
|
|
4019
3857
|
}
|
|
4020
3858
|
function resolveDiscordModelPickerModelSelection(params) {
|
|
4021
3859
|
const models = listDiscordModelPickerProviderModels(params.data, params.provider);
|
|
4022
|
-
if (!models.length) return null;
|
|
4023
3860
|
if (params.modelToken) {
|
|
4024
3861
|
const matchingModels = models.filter((model) => createDiscordModelPickerModelToken(params.provider, model) === params.modelToken);
|
|
4025
3862
|
return matchingModels.length === 1 ? matchingModels[0] ?? null : null;
|
|
@@ -4038,10 +3875,8 @@ async function handleDiscordModelPickerInteraction(params) {
|
|
|
4038
3875
|
await params.safeInteractionCall("model picker ack", () => interaction.acknowledge());
|
|
4039
3876
|
return;
|
|
4040
3877
|
}
|
|
4041
|
-
|
|
4042
|
-
if (!deferredUpdate) {
|
|
3878
|
+
if (!interaction.acknowledged) {
|
|
4043
3879
|
if (await params.safeInteractionCall("model picker defer", () => interaction.acknowledge()) === null) return;
|
|
4044
|
-
deferredUpdate = true;
|
|
4045
3880
|
}
|
|
4046
3881
|
const cfg = getRuntimeConfigSnapshot() ?? ctx.cfg;
|
|
4047
3882
|
const requireModelToken = cfg !== ctx.cfg;
|
|
@@ -4079,7 +3914,7 @@ async function handleDiscordModelPickerInteraction(params) {
|
|
|
4079
3914
|
allowedModelRefs,
|
|
4080
3915
|
limit: 5
|
|
4081
3916
|
});
|
|
4082
|
-
const updatePicker = async (payload) => await params.safeInteractionCall("model picker update", () =>
|
|
3917
|
+
const updatePicker = async (payload) => await params.safeInteractionCall("model picker update", () => interaction.editReply(payload));
|
|
4083
3918
|
const showNotice = async (message) => await updatePicker(buildDiscordModelPickerNoticePayload(message));
|
|
4084
3919
|
const updateModelsView = async (provider, state = {}) => {
|
|
4085
3920
|
const rendered = renderDiscordModelPickerModelsView({
|
|
@@ -4146,15 +3981,16 @@ async function handleDiscordModelPickerInteraction(params) {
|
|
|
4146
3981
|
}));
|
|
4147
3982
|
return;
|
|
4148
3983
|
}
|
|
4149
|
-
if (parsed.action === "bucket"
|
|
3984
|
+
if (parsed.view === "models" && (parsed.action === "bucket" || parsed.action === "back")) {
|
|
4150
3985
|
const provider = resolveModelPickerProvider({
|
|
4151
3986
|
parsedProvider,
|
|
4152
3987
|
currentModelRef,
|
|
4153
3988
|
data: pickerData
|
|
4154
3989
|
});
|
|
3990
|
+
const selectingBucket = parsed.action === "bucket";
|
|
4155
3991
|
await updateModelsView(provider, {
|
|
4156
|
-
page: 1,
|
|
4157
|
-
modelBucket: resolveSelectedBucket(interaction),
|
|
3992
|
+
page: selectingBucket ? 1 : parsed.page,
|
|
3993
|
+
modelBucket: selectingBucket ? resolveSelectedBucket(interaction) : parsed.modelBucket,
|
|
4158
3994
|
pendingRuntime: resolvePendingRuntime({
|
|
4159
3995
|
data: pickerData,
|
|
4160
3996
|
provider,
|
|
@@ -4197,22 +4033,6 @@ async function handleDiscordModelPickerInteraction(params) {
|
|
|
4197
4033
|
});
|
|
4198
4034
|
return;
|
|
4199
4035
|
}
|
|
4200
|
-
if (parsed.action === "back" && parsed.view === "models") {
|
|
4201
|
-
const provider = resolveModelPickerProvider({
|
|
4202
|
-
parsedProvider,
|
|
4203
|
-
currentModelRef,
|
|
4204
|
-
data: pickerData
|
|
4205
|
-
});
|
|
4206
|
-
await updateModelsView(provider, {
|
|
4207
|
-
modelBucket: parsed.modelBucket,
|
|
4208
|
-
pendingRuntime: resolvePendingRuntime({
|
|
4209
|
-
data: pickerData,
|
|
4210
|
-
provider,
|
|
4211
|
-
parsed
|
|
4212
|
-
})
|
|
4213
|
-
});
|
|
4214
|
-
return;
|
|
4215
|
-
}
|
|
4216
4036
|
if (parsed.action === "provider") {
|
|
4217
4037
|
const selectedProvider = resolveModelPickerSelectionValue(interaction) ?? parsed.provider;
|
|
4218
4038
|
if (!selectedProvider || !pickerData.byProvider.has(selectedProvider)) {
|
|
@@ -4284,9 +4104,8 @@ async function handleDiscordModelPickerInteraction(params) {
|
|
|
4284
4104
|
provider,
|
|
4285
4105
|
model: selectedModel
|
|
4286
4106
|
}) : void 0;
|
|
4287
|
-
const currentModelOnly = splitDiscordModelRef(currentModelRef ?? "");
|
|
4288
4107
|
await updateModelsView(provider, {
|
|
4289
|
-
modelBucket: parsed.modelBucket ?? (selectedModel ? findModelBucketId(pickerData, provider, selectedModel) :
|
|
4108
|
+
modelBucket: parsed.modelBucket ?? (selectedModel ? findModelBucketId(pickerData, provider, selectedModel) : currentModel && currentModel.provider === provider ? findModelBucketId(pickerData, provider, currentModel.model) : void 0),
|
|
4290
4109
|
...pendingModel ? { pendingModel } : {},
|
|
4291
4110
|
pendingModelIndex: pendingModelIndex ?? void 0,
|
|
4292
4111
|
pendingRuntime: selectedRuntime
|
|
@@ -4364,16 +4183,11 @@ async function handleDiscordModelPickerInteraction(params) {
|
|
|
4364
4183
|
return;
|
|
4365
4184
|
}
|
|
4366
4185
|
const applyResult = await applyDiscordModelPickerSelection({
|
|
4186
|
+
...ctx,
|
|
4367
4187
|
interaction,
|
|
4368
4188
|
selectionCommand,
|
|
4369
4189
|
dispatchCommandInteraction: params.dispatchCommandInteraction,
|
|
4370
4190
|
cfg,
|
|
4371
|
-
discordConfig: ctx.discordConfig,
|
|
4372
|
-
readPolicy: ctx.readPolicy,
|
|
4373
|
-
accountId: ctx.accountId,
|
|
4374
|
-
sessionPrefix: ctx.sessionPrefix,
|
|
4375
|
-
threadBindings: ctx.threadBindings,
|
|
4376
|
-
dispatchReplyFromConfig: ctx.dispatchReplyFromConfig,
|
|
4377
4191
|
route,
|
|
4378
4192
|
resolvedModelRef,
|
|
4379
4193
|
selectedRuntime,
|
|
@@ -4397,44 +4211,37 @@ async function handleDiscordModelPickerInteraction(params) {
|
|
|
4397
4211
|
}
|
|
4398
4212
|
if (parsed.action === "cancel") await showNotice(`ℹ️ Model kept as ${currentModelRef ?? "default"}.`);
|
|
4399
4213
|
}
|
|
4400
|
-
async function runDiscordModelPickerFallback(params) {
|
|
4401
|
-
await handleDiscordModelPickerInteraction(params);
|
|
4402
|
-
}
|
|
4403
|
-
var DiscordModelPickerFallbackButton = class extends Button {
|
|
4404
|
-
constructor(params) {
|
|
4405
|
-
super();
|
|
4406
|
-
this.params = params;
|
|
4407
|
-
this.label = "modelpick";
|
|
4408
|
-
this.customId = `${DISCORD_MODEL_PICKER_CUSTOM_ID_KEY}:seed=btn`;
|
|
4409
|
-
}
|
|
4410
|
-
async run(interaction, data) {
|
|
4411
|
-
await runDiscordModelPickerFallback({
|
|
4412
|
-
...this.params,
|
|
4413
|
-
interaction,
|
|
4414
|
-
data
|
|
4415
|
-
});
|
|
4416
|
-
}
|
|
4417
|
-
};
|
|
4418
|
-
var DiscordModelPickerFallbackSelect = class extends StringSelectMenu {
|
|
4419
|
-
constructor(params) {
|
|
4420
|
-
super();
|
|
4421
|
-
this.params = params;
|
|
4422
|
-
this.customId = `${DISCORD_MODEL_PICKER_CUSTOM_ID_KEY}:seed=sel`;
|
|
4423
|
-
this.options = [];
|
|
4424
|
-
}
|
|
4425
|
-
async run(interaction, data) {
|
|
4426
|
-
await runDiscordModelPickerFallback({
|
|
4427
|
-
...this.params,
|
|
4428
|
-
interaction,
|
|
4429
|
-
data
|
|
4430
|
-
});
|
|
4431
|
-
}
|
|
4432
|
-
};
|
|
4433
4214
|
function createDiscordModelPickerFallbackButton$1(params) {
|
|
4434
|
-
return new
|
|
4215
|
+
return new class extends Button {
|
|
4216
|
+
constructor(..._args) {
|
|
4217
|
+
super(..._args);
|
|
4218
|
+
this.label = "modelpick";
|
|
4219
|
+
this.customId = `${DISCORD_MODEL_PICKER_CUSTOM_ID_KEY}:seed=btn`;
|
|
4220
|
+
}
|
|
4221
|
+
async run(interaction, data) {
|
|
4222
|
+
await handleDiscordModelPickerInteraction({
|
|
4223
|
+
...params,
|
|
4224
|
+
interaction,
|
|
4225
|
+
data
|
|
4226
|
+
});
|
|
4227
|
+
}
|
|
4228
|
+
}();
|
|
4435
4229
|
}
|
|
4436
4230
|
function createDiscordModelPickerFallbackSelect$1(params) {
|
|
4437
|
-
return new
|
|
4231
|
+
return new class extends StringSelectMenu {
|
|
4232
|
+
constructor(..._args2) {
|
|
4233
|
+
super(..._args2);
|
|
4234
|
+
this.customId = `${DISCORD_MODEL_PICKER_CUSTOM_ID_KEY}:seed=sel`;
|
|
4235
|
+
this.options = [];
|
|
4236
|
+
}
|
|
4237
|
+
async run(interaction, data) {
|
|
4238
|
+
await handleDiscordModelPickerInteraction({
|
|
4239
|
+
...params,
|
|
4240
|
+
interaction,
|
|
4241
|
+
data
|
|
4242
|
+
});
|
|
4243
|
+
}
|
|
4244
|
+
}();
|
|
4438
4245
|
}
|
|
4439
4246
|
//#endregion
|
|
4440
4247
|
//#region extensions/discord/src/monitor/native-command-status.ts
|
|
@@ -4455,15 +4262,9 @@ async function maybeDeliverDiscordDirectStatus(params) {
|
|
|
4455
4262
|
interaction: params.interaction,
|
|
4456
4263
|
payload: statusReply,
|
|
4457
4264
|
mediaLocalRoots: params.mediaLocalRoots,
|
|
4458
|
-
|
|
4459
|
-
maxLinesPerMessage: resolveDiscordMaxLinesPerMessage({
|
|
4460
|
-
cfg: params.cfg,
|
|
4461
|
-
discordConfig: params.discordConfig,
|
|
4462
|
-
accountId: params.accountId
|
|
4463
|
-
}),
|
|
4265
|
+
...resolveDiscordInteractionReplyOptions(params),
|
|
4464
4266
|
preferFollowUp: params.preferFollowUp,
|
|
4465
|
-
responseEphemeral: params.responseEphemeral
|
|
4466
|
-
chunkMode: resolveChunkMode(params.cfg, "discord", params.accountId)
|
|
4267
|
+
responseEphemeral: params.responseEphemeral
|
|
4467
4268
|
});
|
|
4468
4269
|
return {
|
|
4469
4270
|
accepted: true,
|
|
@@ -4483,9 +4284,9 @@ function readDiscordCommandArgs(interaction, definitions) {
|
|
|
4483
4284
|
const values = {};
|
|
4484
4285
|
for (const definition of definitions) {
|
|
4485
4286
|
let value;
|
|
4486
|
-
if (definition.type === "number") value = interaction.options.getNumber(definition.name)
|
|
4487
|
-
else if (definition.type === "boolean") value = interaction.options.getBoolean(definition.name)
|
|
4488
|
-
else value = interaction.options.getString(definition.name)
|
|
4287
|
+
if (definition.type === "number") value = interaction.options.getNumber(definition.name);
|
|
4288
|
+
else if (definition.type === "boolean") value = interaction.options.getBoolean(definition.name);
|
|
4289
|
+
else value = interaction.options.getString(definition.name);
|
|
4489
4290
|
if (value != null) values[definition.name] = value;
|
|
4490
4291
|
}
|
|
4491
4292
|
return Object.keys(values).length > 0 ? { values } : void 0;
|
|
@@ -4520,26 +4321,21 @@ function truncateDiscordCommandDescriptionLocalizations(params) {
|
|
|
4520
4321
|
label: `${params.label} locale:${locale}`
|
|
4521
4322
|
})]));
|
|
4522
4323
|
}
|
|
4523
|
-
function resolveDiscordCommandLogLabel(command) {
|
|
4524
|
-
if (typeof command.nativeName === "string" && command.nativeName.trim().length > 0) return command.nativeName;
|
|
4525
|
-
return command.key;
|
|
4526
|
-
}
|
|
4527
4324
|
function buildDiscordCommandOptions(params) {
|
|
4528
4325
|
const { command, cfg, resolveConfig, authorizeChoiceContext, resolveChoiceContext } = params;
|
|
4529
|
-
const commandLabel =
|
|
4326
|
+
const commandLabel = command.nativeName?.trim() ? command.nativeName : command.key;
|
|
4530
4327
|
const args = command.args;
|
|
4531
4328
|
if (!args || args.length === 0) return;
|
|
4532
4329
|
return args.map((arg) => {
|
|
4533
|
-
const
|
|
4534
|
-
if (arg.type === "number" || arg.type === "boolean") return {
|
|
4330
|
+
const base = {
|
|
4535
4331
|
name: arg.name,
|
|
4536
4332
|
description: truncateDiscordCommandDescription({
|
|
4537
4333
|
value: arg.description,
|
|
4538
4334
|
label: `command:${commandLabel} arg:${arg.name}`
|
|
4539
4335
|
}),
|
|
4540
|
-
|
|
4541
|
-
required
|
|
4336
|
+
required: arg.required ?? false
|
|
4542
4337
|
};
|
|
4338
|
+
if (arg.type === "number" || arg.type === "boolean") return Object.assign(base, { type: arg.type === "number" ? ApplicationCommandOptionType.Number : ApplicationCommandOptionType.Boolean });
|
|
4543
4339
|
const resolvedChoices = resolveCommandArgChoices({
|
|
4544
4340
|
command,
|
|
4545
4341
|
arg,
|
|
@@ -4580,35 +4376,19 @@ function buildDiscordCommandOptions(params) {
|
|
|
4580
4376
|
name: choice.label,
|
|
4581
4377
|
value: choice.value
|
|
4582
4378
|
})) : void 0;
|
|
4583
|
-
return {
|
|
4584
|
-
name: arg.name,
|
|
4585
|
-
description: truncateDiscordCommandDescription({
|
|
4586
|
-
value: arg.description,
|
|
4587
|
-
label: `command:${commandLabel} arg:${arg.name}`
|
|
4588
|
-
}),
|
|
4379
|
+
return Object.assign(base, {
|
|
4589
4380
|
type: ApplicationCommandOptionType.String,
|
|
4590
|
-
required,
|
|
4591
4381
|
choices,
|
|
4592
4382
|
autocomplete
|
|
4593
|
-
};
|
|
4383
|
+
});
|
|
4594
4384
|
});
|
|
4595
4385
|
}
|
|
4596
4386
|
//#endregion
|
|
4597
4387
|
//#region extensions/discord/src/monitor/native-command.ts
|
|
4598
4388
|
const log = createSubsystemLogger("discord/native-command");
|
|
4599
4389
|
const NON_PLUGIN_COMMAND_DISPATCH = Object.freeze({ kind: "non-plugin" });
|
|
4600
|
-
function resolveDiscordNativePolicyReader(params) {
|
|
4601
|
-
return params.readPolicy ?? createDiscordLivePolicyReader({
|
|
4602
|
-
...params,
|
|
4603
|
-
readConfig: () => getRuntimeConfigSnapshot() ?? params.cfg,
|
|
4604
|
-
resolvedAllowlist: {
|
|
4605
|
-
guildEntries: params.discordConfig?.guilds,
|
|
4606
|
-
allowFrom: params.discordConfig?.allowFrom ?? resolveDiscordAccountAllowFrom(params)
|
|
4607
|
-
}
|
|
4608
|
-
});
|
|
4609
|
-
}
|
|
4610
4390
|
function createDiscordNativeCommand(params) {
|
|
4611
|
-
const { command, cfg, discordConfig, accountId, sessionPrefix, ephemeralDefault, threadBindings, dispatchReplyFromConfig } = params;
|
|
4391
|
+
const { command, cfg, discordConfig, accountId, sessionPrefix, ephemeralDefault, threadBindings, buildContext, dispatchReplyFromConfig } = params;
|
|
4612
4392
|
const fallbackCommandDefinition = createNativeCommandDefinition(command);
|
|
4613
4393
|
const pluginCommandCandidate = "prepareDispatch" in command ? command : void 0;
|
|
4614
4394
|
const commandDefinition = pluginCommandCandidate ? fallbackCommandDefinition : findCommandByNativeName$1(command.name, "discord", { includeBundledChannelFallback: false }) ?? fallbackCommandDefinition;
|
|
@@ -4627,6 +4407,9 @@ function createDiscordNativeCommand(params) {
|
|
|
4627
4407
|
...policy,
|
|
4628
4408
|
isPolicyCurrent: policy.isCurrent,
|
|
4629
4409
|
accountId,
|
|
4410
|
+
sessionPrefix,
|
|
4411
|
+
threadBindings,
|
|
4412
|
+
buildContext,
|
|
4630
4413
|
skipCommandOwnerAllowFrom: pluginCommandCandidate !== void 0
|
|
4631
4414
|
});
|
|
4632
4415
|
},
|
|
@@ -4681,6 +4464,7 @@ function createDiscordNativeCommand(params) {
|
|
|
4681
4464
|
preferFollowUp: true,
|
|
4682
4465
|
threadBindings,
|
|
4683
4466
|
responseEphemeral: ephemeralDefault,
|
|
4467
|
+
buildContext,
|
|
4684
4468
|
dispatchReplyFromConfig,
|
|
4685
4469
|
pluginCommandDispatch: preparedPluginCommand ?? NON_PLUGIN_COMMAND_DISPATCH
|
|
4686
4470
|
});
|
|
@@ -4688,7 +4472,7 @@ function createDiscordNativeCommand(params) {
|
|
|
4688
4472
|
}();
|
|
4689
4473
|
}
|
|
4690
4474
|
async function dispatchDiscordCommandInteraction(params) {
|
|
4691
|
-
const { interaction, prompt, command, commandArgs, cfg: inputConfig, discordConfig: inputDiscordConfig, accountId, sessionPrefix, preferFollowUp, threadBindings, responseEphemeral, suppressReplies, dispatchReplyFromConfig } = params;
|
|
4475
|
+
const { interaction, prompt, command, commandArgs, cfg: inputConfig, discordConfig: inputDiscordConfig, accountId, sessionPrefix, preferFollowUp, threadBindings, responseEphemeral, suppressReplies, buildContext, dispatchReplyFromConfig } = params;
|
|
4692
4476
|
const policy = await params.readPolicy?.();
|
|
4693
4477
|
const cfg = policy?.cfg ?? getRuntimeConfigSnapshot() ?? inputConfig;
|
|
4694
4478
|
const discordConfig = policy?.discordConfig ?? inputDiscordConfig;
|
|
@@ -4700,14 +4484,9 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4700
4484
|
...ephemeral !== void 0 ? { ephemeral } : {}
|
|
4701
4485
|
};
|
|
4702
4486
|
await safeDiscordInteractionCall("interaction reply", async () => {
|
|
4703
|
-
|
|
4704
|
-
await interaction.followUp(payload);
|
|
4705
|
-
return;
|
|
4706
|
-
}
|
|
4707
|
-
await interaction.reply(payload);
|
|
4487
|
+
await interaction[preferFollowUp ? "followUp" : "reply"](payload);
|
|
4708
4488
|
});
|
|
4709
4489
|
};
|
|
4710
|
-
const useAccessGroups = true;
|
|
4711
4490
|
const user = interaction.user;
|
|
4712
4491
|
if (!user) return { accepted: false };
|
|
4713
4492
|
const sender = resolveDiscordSenderIdentity({
|
|
@@ -4715,12 +4494,13 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4715
4494
|
pluralkitInfo: null
|
|
4716
4495
|
});
|
|
4717
4496
|
const channel = interaction.channel;
|
|
4718
|
-
const
|
|
4497
|
+
const channelContext = await resolveDiscordNativeInteractionChannelContext({
|
|
4719
4498
|
channel,
|
|
4720
4499
|
client: interaction.client,
|
|
4721
4500
|
hasGuild: Boolean(interaction.guild),
|
|
4722
4501
|
channelIdFallback: interaction.rawData.channel_id ?? ""
|
|
4723
4502
|
});
|
|
4503
|
+
const { isDirectMessage, isGroupDm, isThreadChannel, channelName, channelSlug, rawChannelId, threadParentId } = channelContext;
|
|
4724
4504
|
if (policy?.isCurrent() === false) {
|
|
4725
4505
|
await respond("Access policy changed. Try this interaction again.", { ephemeral: true });
|
|
4726
4506
|
return { accepted: false };
|
|
@@ -4731,47 +4511,20 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4731
4511
|
cfg,
|
|
4732
4512
|
accountId
|
|
4733
4513
|
}) ?? [];
|
|
4734
|
-
const
|
|
4735
|
-
const { ownerAllowList: discordOwnerAllowList, ownerAllowed: discordOwnerOk } = resolveDiscordOwnerAccess({
|
|
4514
|
+
const { ownerAllowList, ownerAllowed } = resolveDiscordOwnerAccess({
|
|
4736
4515
|
allowFrom: configuredDmAllowFrom,
|
|
4737
|
-
sender
|
|
4738
|
-
id: sender.id,
|
|
4739
|
-
name: sender.name,
|
|
4740
|
-
tag: sender.tag
|
|
4741
|
-
},
|
|
4742
|
-
allowNameMatching
|
|
4743
|
-
});
|
|
4744
|
-
const { ownerAllowed: commandOwnerOk } = resolveDiscordOwnerAccess({
|
|
4745
|
-
allowFrom: commandOwnerAllowFrom,
|
|
4746
|
-
sender: {
|
|
4747
|
-
id: sender.id,
|
|
4748
|
-
name: sender.name,
|
|
4749
|
-
tag: sender.tag
|
|
4750
|
-
},
|
|
4516
|
+
sender,
|
|
4751
4517
|
allowNameMatching
|
|
4752
4518
|
});
|
|
4753
|
-
const commandOwnerAllowAll = commandOwnerAllowFrom?.includes("*") === true;
|
|
4754
|
-
const senderIsCommandOwner = commandOwnerOk;
|
|
4755
|
-
const commandOwnerAccessAllowed = senderIsCommandOwner || commandOwnerAllowAll;
|
|
4756
|
-
const ownerAllowListConfigured = discordOwnerAllowList != null;
|
|
4757
|
-
const ownerOk = discordOwnerOk;
|
|
4758
4519
|
const { commandsAllowFromAccess, guildInfo, channelConfig } = resolveDiscordNativeCommandChannelAccessContext({
|
|
4759
4520
|
cfg,
|
|
4760
4521
|
discordConfig,
|
|
4761
|
-
accountId,
|
|
4762
4522
|
sender,
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
guild: interaction.guild ?? null,
|
|
4766
|
-
rawChannelId,
|
|
4767
|
-
channelName,
|
|
4768
|
-
channelSlug,
|
|
4769
|
-
threadParentId,
|
|
4770
|
-
threadParentName,
|
|
4771
|
-
threadParentSlug
|
|
4523
|
+
...channelContext,
|
|
4524
|
+
guild: interaction.guild ?? null
|
|
4772
4525
|
});
|
|
4773
|
-
let
|
|
4774
|
-
const getNativeRouteState = () =>
|
|
4526
|
+
let nativeRouteState;
|
|
4527
|
+
const getNativeRouteState = () => nativeRouteState ??= nativeCommandRuntime.resolveDiscordNativeInteractionRouteState({
|
|
4775
4528
|
cfg,
|
|
4776
4529
|
accountId,
|
|
4777
4530
|
guildId: interaction.guild?.id ?? void 0,
|
|
@@ -4781,19 +4534,18 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4781
4534
|
directUserId: user.id,
|
|
4782
4535
|
conversationId: rawChannelId || "unknown",
|
|
4783
4536
|
parentConversationId: threadParentId,
|
|
4784
|
-
threadBinding: isThreadChannel ? threadBindings.getByThreadId(rawChannelId) : void 0
|
|
4785
|
-
enforceConfiguredBindingReadiness: !shouldBypassConfiguredAcpEnsure(commandName)
|
|
4537
|
+
threadBinding: isThreadChannel ? threadBindings.getByThreadId(rawChannelId) : void 0
|
|
4786
4538
|
});
|
|
4787
|
-
const canBypassConfiguredAcpGuildGuards =
|
|
4539
|
+
const canBypassConfiguredAcpGuildGuards = () => {
|
|
4788
4540
|
if (!interaction.guild || !shouldBypassConfiguredAcpGuildGuards(commandName)) return false;
|
|
4789
|
-
const routeState =
|
|
4790
|
-
return routeState.effectiveRoute.matchedBy === "binding.channel" || routeState.boundSessionKey != null || routeState.configuredBinding != null
|
|
4541
|
+
const routeState = getNativeRouteState();
|
|
4542
|
+
return routeState.effectiveRoute.matchedBy === "binding.channel" || routeState.boundSessionKey != null || routeState.configuredBinding != null;
|
|
4791
4543
|
};
|
|
4792
|
-
if (channelConfig?.enabled === false && !
|
|
4544
|
+
if (channelConfig?.enabled === false && !canBypassConfiguredAcpGuildGuards()) {
|
|
4793
4545
|
await respond("This channel is disabled.");
|
|
4794
4546
|
return { accepted: false };
|
|
4795
4547
|
}
|
|
4796
|
-
if (interaction.guild && channelConfig?.allowed === false && !
|
|
4548
|
+
if (interaction.guild && channelConfig?.allowed === false && !canBypassConfiguredAcpGuildGuards()) {
|
|
4797
4549
|
await respond("This channel is not allowed.");
|
|
4798
4550
|
return { accepted: false };
|
|
4799
4551
|
}
|
|
@@ -4807,7 +4559,7 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4807
4559
|
groupPolicy,
|
|
4808
4560
|
guildInfo,
|
|
4809
4561
|
channelConfig
|
|
4810
|
-
}).allowed && !
|
|
4562
|
+
}).allowed && !canBypassConfiguredAcpGuildGuards()) {
|
|
4811
4563
|
await respond("This channel is not allowed.");
|
|
4812
4564
|
return { accepted: false };
|
|
4813
4565
|
}
|
|
@@ -4831,11 +4583,7 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4831
4583
|
accountId,
|
|
4832
4584
|
dmPolicy,
|
|
4833
4585
|
configuredAllowFrom: configuredDmAllowFrom,
|
|
4834
|
-
sender
|
|
4835
|
-
id: sender.id,
|
|
4836
|
-
name: sender.name,
|
|
4837
|
-
tag: sender.tag
|
|
4838
|
-
},
|
|
4586
|
+
sender,
|
|
4839
4587
|
allowNameMatching,
|
|
4840
4588
|
cfg,
|
|
4841
4589
|
rest: interaction.client.rest
|
|
@@ -4883,19 +4631,17 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4883
4631
|
if (!isDirectMessage) {
|
|
4884
4632
|
commandAuthorized = await resolveDiscordGuildNativeCommandAuthorized({
|
|
4885
4633
|
cfg,
|
|
4886
|
-
accountId,
|
|
4887
4634
|
discordConfig,
|
|
4888
|
-
useAccessGroups,
|
|
4889
4635
|
commandsAllowFromAccess,
|
|
4890
4636
|
guildInfo,
|
|
4891
4637
|
channelConfig,
|
|
4892
4638
|
memberRoleIds,
|
|
4893
4639
|
sender,
|
|
4894
4640
|
allowNameMatching,
|
|
4895
|
-
ownerAllowListConfigured,
|
|
4896
|
-
ownerAllowed
|
|
4641
|
+
ownerAllowListConfigured: ownerAllowList != null,
|
|
4642
|
+
ownerAllowed
|
|
4897
4643
|
});
|
|
4898
|
-
if (!commandAuthorized && !
|
|
4644
|
+
if (!commandAuthorized && !canBypassConfiguredAcpGuildGuards()) {
|
|
4899
4645
|
await respond("You are not authorized to use this command.", { ephemeral: true });
|
|
4900
4646
|
return { accepted: false };
|
|
4901
4647
|
}
|
|
@@ -4904,18 +4650,63 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4904
4650
|
await respond("Access policy changed. Try this interaction again.", { ephemeral: true });
|
|
4905
4651
|
return { accepted: false };
|
|
4906
4652
|
}
|
|
4907
|
-
|
|
4653
|
+
const routeState = getNativeRouteState();
|
|
4654
|
+
const effectiveRoute = routeState.effectiveRoute;
|
|
4655
|
+
const { ctxPayload, sessionKey, commandTargetSessionKey } = await buildDiscordNativeInteractionContext({
|
|
4656
|
+
buildContext,
|
|
4657
|
+
interaction,
|
|
4658
|
+
channelContext,
|
|
4659
|
+
route: effectiveRoute,
|
|
4660
|
+
boundSessionKey: routeState.boundSessionKey,
|
|
4661
|
+
sessionPrefix,
|
|
4662
|
+
prompt,
|
|
4663
|
+
commandArgs: commandArgs ?? {},
|
|
4664
|
+
channelConfig,
|
|
4665
|
+
guildInfo,
|
|
4666
|
+
allowNameMatching,
|
|
4667
|
+
commandAuthorized,
|
|
4668
|
+
user,
|
|
4669
|
+
sender
|
|
4670
|
+
});
|
|
4671
|
+
const mediaLocalRoots = getAgentScopedMediaLocalRoots(cfg, effectiveRoute.agentId);
|
|
4672
|
+
if (policy?.isCurrent() === false) {
|
|
4673
|
+
await respond("Access policy changed. Try this interaction again.", { ephemeral: true });
|
|
4674
|
+
return { accepted: false };
|
|
4675
|
+
}
|
|
4676
|
+
const authority = createDiscordNativeCommandAuthority({
|
|
4677
|
+
cfg,
|
|
4678
|
+
ctx: ctxPayload,
|
|
4679
|
+
commandAuthorized,
|
|
4680
|
+
sender,
|
|
4681
|
+
allowNameMatching,
|
|
4682
|
+
isPolicyCurrent: policy?.isCurrent,
|
|
4683
|
+
accountId,
|
|
4684
|
+
guildId: interaction.guild?.id,
|
|
4685
|
+
commandName,
|
|
4686
|
+
pluginCommand: params.pluginCommandDispatch.kind === "plugin"
|
|
4687
|
+
});
|
|
4688
|
+
if (!authority.isAllowed()) {
|
|
4689
|
+
await respond("You are not authorized to use this command.", { ephemeral: true });
|
|
4690
|
+
return { accepted: false };
|
|
4691
|
+
}
|
|
4692
|
+
const bindingReadiness = routeState.configuredBinding && !shouldBypassConfiguredAcpEnsure(commandName) ? await nativeCommandRuntime.ensureConfiguredBindingRouteReady({
|
|
4693
|
+
cfg,
|
|
4694
|
+
bindingResolution: routeState.configuredBinding,
|
|
4695
|
+
assertActive: authority.assertActive
|
|
4696
|
+
}) : null;
|
|
4697
|
+
if (!authority.isAllowed()) {
|
|
4908
4698
|
await respond("You are not authorized to use this command.", { ephemeral: true });
|
|
4909
4699
|
return { accepted: false };
|
|
4910
4700
|
}
|
|
4911
4701
|
const isGuild = Boolean(interaction.guild);
|
|
4912
4702
|
const channelId = rawChannelId || "unknown";
|
|
4913
4703
|
const menuNeedsModelContext = !(commandArgs?.raw && !commandArgs.values) && command.args?.some((arg) => typeof arg.choices === "function" && commandArgs?.values?.[arg.name] == null);
|
|
4914
|
-
const menuModelContext = menuNeedsModelContext ? await resolveDiscordNativeChoiceContext({
|
|
4704
|
+
const menuModelContext = menuNeedsModelContext && bindingReadiness?.ok !== false ? await resolveDiscordNativeChoiceContext({
|
|
4915
4705
|
interaction,
|
|
4916
4706
|
cfg,
|
|
4917
4707
|
accountId,
|
|
4918
|
-
threadBindings
|
|
4708
|
+
threadBindings,
|
|
4709
|
+
route: effectiveRoute
|
|
4919
4710
|
}) : null;
|
|
4920
4711
|
const menuModelCatalog = command.key === "think" && menuNeedsModelContext ? await loadPreparedModelCatalog({
|
|
4921
4712
|
config: cfg,
|
|
@@ -4925,17 +4716,20 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4925
4716
|
} : {},
|
|
4926
4717
|
readOnly: true
|
|
4927
4718
|
}) : void 0;
|
|
4928
|
-
const
|
|
4929
|
-
const menu = menuRouteState?.bindingReadiness?.ok === false ? null : resolveCommandArgMenu({
|
|
4719
|
+
const menu = command.key === "verbose" && bindingReadiness?.ok === false ? null : resolveCommandArgMenu({
|
|
4930
4720
|
command,
|
|
4931
4721
|
args: commandArgs,
|
|
4932
4722
|
cfg,
|
|
4933
|
-
session:
|
|
4723
|
+
session: command.key === "verbose" ? effectiveRoute : void 0,
|
|
4934
4724
|
provider: menuModelContext?.provider,
|
|
4935
4725
|
model: menuModelContext?.model,
|
|
4936
4726
|
agentRuntime: menuModelContext?.agentRuntime,
|
|
4937
4727
|
catalog: menuModelCatalog
|
|
4938
4728
|
});
|
|
4729
|
+
if (policy?.isCurrent() === false) {
|
|
4730
|
+
await respond("Access policy changed. Try this interaction again.", { ephemeral: true });
|
|
4731
|
+
return { accepted: false };
|
|
4732
|
+
}
|
|
4939
4733
|
if (menu) {
|
|
4940
4734
|
const menuPayload = buildDiscordCommandArgMenu({
|
|
4941
4735
|
command,
|
|
@@ -4947,20 +4741,13 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4947
4741
|
accountId,
|
|
4948
4742
|
sessionPrefix,
|
|
4949
4743
|
threadBindings,
|
|
4744
|
+
buildContext,
|
|
4950
4745
|
dispatchReplyFromConfig
|
|
4951
4746
|
},
|
|
4952
4747
|
safeInteractionCall: safeDiscordInteractionCall,
|
|
4953
4748
|
dispatchCommandInteraction: dispatchDiscordCommandInteraction
|
|
4954
4749
|
});
|
|
4955
|
-
|
|
4956
|
-
await safeDiscordInteractionCall("interaction follow-up", () => interaction.followUp({
|
|
4957
|
-
content: menuPayload.content,
|
|
4958
|
-
components: menuPayload.components,
|
|
4959
|
-
ephemeral: true
|
|
4960
|
-
}));
|
|
4961
|
-
return { accepted: true };
|
|
4962
|
-
}
|
|
4963
|
-
await safeDiscordInteractionCall("interaction reply", () => interaction.reply({
|
|
4750
|
+
await safeDiscordInteractionCall(preferFollowUp ? "interaction follow-up" : "interaction reply", () => interaction[preferFollowUp ? "followUp" : "reply"]({
|
|
4964
4751
|
content: menuPayload.content,
|
|
4965
4752
|
components: menuPayload.components,
|
|
4966
4753
|
ephemeral: true
|
|
@@ -4974,19 +4761,20 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4974
4761
|
}
|
|
4975
4762
|
const messageThreadId = !isDirectMessage && isThreadChannel ? channelId : void 0;
|
|
4976
4763
|
const pluginThreadParentId = !isDirectMessage && isThreadChannel ? threadParentId : void 0;
|
|
4977
|
-
const routeState = await getNativeRouteState();
|
|
4978
|
-
const { effectiveRoute } = routeState;
|
|
4979
4764
|
const pluginCommandAgentId = (isThreadChannel ? threadBindings.getByThreadId(rawChannelId)?.agentId : void 0) || routeState.configuredBinding?.statefulTarget.agentId || effectiveRoute.agentId;
|
|
4980
4765
|
const targetSessionEntry = nativeCommandRuntime.getSessionEntry({
|
|
4981
4766
|
agentId: pluginCommandAgentId,
|
|
4982
4767
|
sessionKey: effectiveRoute.sessionKey
|
|
4983
4768
|
});
|
|
4769
|
+
authority.assertActive();
|
|
4770
|
+
const senderIsOwner = authority.senderIsOwner();
|
|
4984
4771
|
const pluginReply = await params.pluginCommandDispatch.execute({
|
|
4985
4772
|
senderId: sender.id,
|
|
4986
4773
|
channel: "discord",
|
|
4987
4774
|
channelId,
|
|
4988
4775
|
isAuthorizedSender: commandAuthorized,
|
|
4989
|
-
senderIsOwner
|
|
4776
|
+
senderIsOwner,
|
|
4777
|
+
...senderIsOwner ? { assertOwnerCurrent: authority.assertOwnerCurrent } : {},
|
|
4990
4778
|
agentId: pluginCommandAgentId,
|
|
4991
4779
|
sessionKey: effectiveRoute.sessionKey,
|
|
4992
4780
|
authProfileId: targetSessionEntry?.authProfileOverride,
|
|
@@ -5015,15 +4803,13 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
5015
4803
|
await deliverDiscordInteractionReply({
|
|
5016
4804
|
interaction,
|
|
5017
4805
|
payload: pluginReply,
|
|
5018
|
-
|
|
5019
|
-
maxLinesPerMessage: resolveDiscordMaxLinesPerMessage({
|
|
4806
|
+
...resolveDiscordInteractionReplyOptions({
|
|
5020
4807
|
cfg,
|
|
5021
4808
|
discordConfig,
|
|
5022
4809
|
accountId
|
|
5023
4810
|
}),
|
|
5024
4811
|
preferFollowUp,
|
|
5025
|
-
responseEphemeral
|
|
5026
|
-
chunkMode: resolveChunkMode(cfg, "discord", accountId)
|
|
4812
|
+
responseEphemeral
|
|
5027
4813
|
});
|
|
5028
4814
|
return {
|
|
5029
4815
|
accepted: true,
|
|
@@ -5047,58 +4833,14 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
5047
4833
|
});
|
|
5048
4834
|
return { accepted: true };
|
|
5049
4835
|
}
|
|
5050
|
-
|
|
5051
|
-
const routeState = await getNativeRouteState();
|
|
5052
|
-
if (routeState.bindingReadiness && !routeState.bindingReadiness.ok) {
|
|
4836
|
+
if (bindingReadiness && !bindingReadiness.ok) {
|
|
5053
4837
|
const configuredBinding = routeState.configuredBinding;
|
|
5054
4838
|
if (configuredBinding) {
|
|
5055
|
-
logVerbose(`discord native command: configured ACP binding unavailable for channel ${configuredBinding.record.conversation.conversationId}: ${
|
|
4839
|
+
logVerbose(`discord native command: configured ACP binding unavailable for channel ${configuredBinding.record.conversation.conversationId}: ${bindingReadiness.error}`);
|
|
5056
4840
|
await respond("Configured ACP binding is unavailable right now. Please try again.");
|
|
5057
4841
|
return { accepted: false };
|
|
5058
4842
|
}
|
|
5059
4843
|
}
|
|
5060
|
-
const boundSessionKey = routeState.boundSessionKey;
|
|
5061
|
-
const effectiveRoute = routeState.effectiveRoute;
|
|
5062
|
-
const { sessionKey, commandTargetSessionKey } = resolveNativeCommandSessionTargets({
|
|
5063
|
-
agentId: effectiveRoute.agentId,
|
|
5064
|
-
sessionPrefix,
|
|
5065
|
-
userId: user.id,
|
|
5066
|
-
targetSessionKey: effectiveRoute.sessionKey,
|
|
5067
|
-
boundSessionKey
|
|
5068
|
-
});
|
|
5069
|
-
const mediaLocalRoots = getAgentScopedMediaLocalRoots(cfg, effectiveRoute.agentId);
|
|
5070
|
-
const ctxPayload = buildDiscordNativeCommandContext({
|
|
5071
|
-
prompt,
|
|
5072
|
-
commandArgs: commandArgs ?? {},
|
|
5073
|
-
sessionKey,
|
|
5074
|
-
commandTargetSessionKey,
|
|
5075
|
-
accountId: effectiveRoute.accountId,
|
|
5076
|
-
interactionId,
|
|
5077
|
-
channelId,
|
|
5078
|
-
threadParentId,
|
|
5079
|
-
memberRoleIds,
|
|
5080
|
-
guildId: interaction.guild?.id,
|
|
5081
|
-
guildName: interaction.guild?.name,
|
|
5082
|
-
channelTopic: resolveDiscordChannelTopicSafe(channel),
|
|
5083
|
-
channelConfig,
|
|
5084
|
-
guildInfo,
|
|
5085
|
-
allowNameMatching,
|
|
5086
|
-
commandAuthorized,
|
|
5087
|
-
isDirectMessage,
|
|
5088
|
-
isGroupDm,
|
|
5089
|
-
isGuild,
|
|
5090
|
-
isThreadChannel,
|
|
5091
|
-
user: {
|
|
5092
|
-
id: user.id,
|
|
5093
|
-
username: user.username,
|
|
5094
|
-
globalName: user.globalName
|
|
5095
|
-
},
|
|
5096
|
-
sender: {
|
|
5097
|
-
id: sender.id,
|
|
5098
|
-
name: sender.name,
|
|
5099
|
-
tag: sender.tag
|
|
5100
|
-
}
|
|
5101
|
-
});
|
|
5102
4844
|
const directStatusResult = await maybeDeliverDiscordDirectStatus({
|
|
5103
4845
|
commandName,
|
|
5104
4846
|
suppressReplies,
|
|
@@ -5110,7 +4852,7 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
5110
4852
|
commandTargetSessionKey,
|
|
5111
4853
|
channel: "discord",
|
|
5112
4854
|
senderId: sender.id,
|
|
5113
|
-
senderIsOwner:
|
|
4855
|
+
senderIsOwner: authority.senderIsOwner(),
|
|
5114
4856
|
isAuthorizedSender: commandAuthorized,
|
|
5115
4857
|
isGroup: isGuild || isGroupDm,
|
|
5116
4858
|
defaultGroupActivation: () => !isGuild ? "always" : channelConfig?.requireMention === false ? "always" : "mention",
|
|
@@ -5325,7 +5067,7 @@ var GatewaySendLimiter = class {
|
|
|
5325
5067
|
shouldEmitOverflowWarning = true;
|
|
5326
5068
|
}
|
|
5327
5069
|
}
|
|
5328
|
-
this.outboundQueue.push(
|
|
5070
|
+
this.outboundQueue.push(serialized);
|
|
5329
5071
|
if (shouldEmitOverflowWarning) this.emitOverflowWarning({
|
|
5330
5072
|
droppedEvents: this.droppedEvents,
|
|
5331
5073
|
maxQueuedEvents: GATEWAY_SEND_QUEUE_LIMIT,
|
|
@@ -5382,9 +5124,9 @@ var GatewaySendLimiter = class {
|
|
|
5382
5124
|
flush() {
|
|
5383
5125
|
while (this.outboundQueue.length > 0 && this.canSend(Date.now())) {
|
|
5384
5126
|
const queued = this.outboundQueue.shift();
|
|
5385
|
-
if (
|
|
5127
|
+
if (queued === void 0) continue;
|
|
5386
5128
|
try {
|
|
5387
|
-
this.sendSerialized(queued
|
|
5129
|
+
this.sendSerialized(queued);
|
|
5388
5130
|
} catch (error) {
|
|
5389
5131
|
this.emitError(error instanceof Error ? error : new Error(String(error), { cause: error }));
|
|
5390
5132
|
this.clear();
|
|
@@ -5519,9 +5261,6 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5519
5261
|
};
|
|
5520
5262
|
this.gatewayInfo = gatewayInfo;
|
|
5521
5263
|
}
|
|
5522
|
-
get ping() {
|
|
5523
|
-
return null;
|
|
5524
|
-
}
|
|
5525
5264
|
listVoiceChannelStates(guildId, channelId) {
|
|
5526
5265
|
return this.voiceStateCache.listVoiceChannelStates(guildId, channelId);
|
|
5527
5266
|
}
|
|
@@ -5555,8 +5294,8 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5555
5294
|
this.connect(false);
|
|
5556
5295
|
}
|
|
5557
5296
|
connect(resume = false) {
|
|
5558
|
-
this.
|
|
5559
|
-
this.
|
|
5297
|
+
this.reconnectTimer.stop();
|
|
5298
|
+
this.heartbeatTimers.stop();
|
|
5560
5299
|
if (this.isConnecting) return;
|
|
5561
5300
|
this.shouldReconnect = true;
|
|
5562
5301
|
this.lastHeartbeatAck = true;
|
|
@@ -5569,8 +5308,8 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5569
5308
|
}
|
|
5570
5309
|
disconnect() {
|
|
5571
5310
|
this.shouldReconnect = false;
|
|
5572
|
-
this.
|
|
5573
|
-
this.
|
|
5311
|
+
this.reconnectTimer.stop();
|
|
5312
|
+
this.heartbeatTimers.stop();
|
|
5574
5313
|
this.outboundLimiter.clear();
|
|
5575
5314
|
this.ws?.close(1e3, "Client disconnect");
|
|
5576
5315
|
this.ws = null;
|
|
@@ -5603,7 +5342,7 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5603
5342
|
socket.on("close", (code) => {
|
|
5604
5343
|
if (socket !== this.ws) return;
|
|
5605
5344
|
const closeCode = code;
|
|
5606
|
-
this.
|
|
5345
|
+
this.heartbeatTimers.stop();
|
|
5607
5346
|
this.outboundLimiter.clear();
|
|
5608
5347
|
this.isConnecting = false;
|
|
5609
5348
|
this.isConnected = false;
|
|
@@ -5688,12 +5427,6 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5688
5427
|
}
|
|
5689
5428
|
});
|
|
5690
5429
|
}
|
|
5691
|
-
stopHeartbeat() {
|
|
5692
|
-
this.heartbeatTimers.stop();
|
|
5693
|
-
}
|
|
5694
|
-
stopReconnectTimer() {
|
|
5695
|
-
this.reconnectTimer.stop();
|
|
5696
|
-
}
|
|
5697
5430
|
sendHeartbeat() {
|
|
5698
5431
|
if (!this.ws || this.ws.readyState !== READY_STATE_OPEN) return;
|
|
5699
5432
|
this.lastHeartbeatAck = false;
|
|
@@ -5759,7 +5492,7 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5759
5492
|
this.isConnected = true;
|
|
5760
5493
|
}
|
|
5761
5494
|
this.voiceStateCache.apply(payload);
|
|
5762
|
-
dispatchVoiceGatewayEvent(this.client, payload
|
|
5495
|
+
dispatchVoiceGatewayEvent(this.client, payload);
|
|
5763
5496
|
const data = payload.t === GatewayDispatchEvents.MessageCreate ? payload.d : mapGatewayDispatchData(this.client, payload.t, payload.d);
|
|
5764
5497
|
await this.client.dispatchGatewayEvent(payload.t, data);
|
|
5765
5498
|
if (payload.t === GatewayDispatchEvents.InteractionCreate && this.options.autoInteractions) await this.client.handleInteraction(payload.d);
|
|
@@ -5779,8 +5512,8 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5779
5512
|
}
|
|
5780
5513
|
scheduleReconnect(options) {
|
|
5781
5514
|
if (!this.shouldReconnect) return;
|
|
5782
|
-
this.
|
|
5783
|
-
this.
|
|
5515
|
+
this.heartbeatTimers.stop();
|
|
5516
|
+
this.reconnectTimer.stop();
|
|
5784
5517
|
this.ws?.close();
|
|
5785
5518
|
this.ws = null;
|
|
5786
5519
|
this.isConnecting = false;
|
|
@@ -5818,43 +5551,24 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5818
5551
|
d: data
|
|
5819
5552
|
}, true);
|
|
5820
5553
|
}
|
|
5821
|
-
requestGuildMembers(data) {
|
|
5822
|
-
if (!this.hasIntent(GatewayIntentBits.GuildMembers)) throw new Error("GUILD_MEMBERS intent is required for requestGuildMembers");
|
|
5823
|
-
if (data.presences && !this.hasIntent(GatewayIntentBits.GuildPresences)) throw new Error("GUILD_PRESENCES intent is required when requesting presences");
|
|
5824
|
-
if (!data.query && data.query !== "" && !data.user_ids) throw new Error("Either query or user_ids is required for requestGuildMembers");
|
|
5825
|
-
this.send({
|
|
5826
|
-
op: GatewayOpcodes.RequestGuildMembers,
|
|
5827
|
-
d: data
|
|
5828
|
-
});
|
|
5829
|
-
}
|
|
5830
5554
|
getRateLimitStatus() {
|
|
5831
5555
|
return this.outboundLimiter.getStatus();
|
|
5832
5556
|
}
|
|
5833
|
-
hasIntent(intent) {
|
|
5834
|
-
return Boolean((this.options.intents ?? 0) & intent);
|
|
5835
|
-
}
|
|
5836
5557
|
};
|
|
5837
5558
|
//#endregion
|
|
5838
5559
|
//#region extensions/discord/src/monitor/presence.ts
|
|
5839
|
-
const DEFAULT_CUSTOM_ACTIVITY_TYPE
|
|
5840
|
-
const CUSTOM_STATUS_NAME
|
|
5560
|
+
const DEFAULT_CUSTOM_ACTIVITY_TYPE = 4;
|
|
5561
|
+
const CUSTOM_STATUS_NAME = "Custom Status";
|
|
5841
5562
|
function resolveDiscordPresenceUpdate(config) {
|
|
5842
5563
|
const activityText = normalizeOptionalString(config.activity) ?? "";
|
|
5843
5564
|
const status = normalizeOptionalString(config.status) ?? "";
|
|
5844
5565
|
const activityType = config.activityType;
|
|
5845
5566
|
const activityUrl = normalizeOptionalString(config.activityUrl) ?? "";
|
|
5846
|
-
const hasActivity = Boolean(activityText);
|
|
5847
|
-
if (!hasActivity && !Boolean(status)) return {
|
|
5848
|
-
since: null,
|
|
5849
|
-
activities: [],
|
|
5850
|
-
status: "online",
|
|
5851
|
-
afk: false
|
|
5852
|
-
};
|
|
5853
5567
|
const activities = [];
|
|
5854
|
-
if (
|
|
5855
|
-
const resolvedType = activityType ?? DEFAULT_CUSTOM_ACTIVITY_TYPE
|
|
5856
|
-
const activity = resolvedType === DEFAULT_CUSTOM_ACTIVITY_TYPE
|
|
5857
|
-
name: CUSTOM_STATUS_NAME
|
|
5568
|
+
if (activityText) {
|
|
5569
|
+
const resolvedType = activityType ?? DEFAULT_CUSTOM_ACTIVITY_TYPE;
|
|
5570
|
+
const activity = resolvedType === DEFAULT_CUSTOM_ACTIVITY_TYPE ? {
|
|
5571
|
+
name: CUSTOM_STATUS_NAME,
|
|
5858
5572
|
type: resolvedType,
|
|
5859
5573
|
state: activityText
|
|
5860
5574
|
} : {
|
|
@@ -5873,8 +5587,6 @@ function resolveDiscordPresenceUpdate(config) {
|
|
|
5873
5587
|
}
|
|
5874
5588
|
//#endregion
|
|
5875
5589
|
//#region extensions/discord/src/monitor/auto-presence.ts
|
|
5876
|
-
const DEFAULT_CUSTOM_ACTIVITY_TYPE = 4;
|
|
5877
|
-
const CUSTOM_STATUS_NAME = "Custom Status";
|
|
5878
5590
|
const DEFAULT_INTERVAL_MS = 3e4;
|
|
5879
5591
|
const DEFAULT_MIN_UPDATE_INTERVAL_MS = 15e3;
|
|
5880
5592
|
const MIN_INTERVAL_MS = 5e3;
|
|
@@ -5894,13 +5606,6 @@ function resolveAutoPresenceConfig(config) {
|
|
|
5894
5606
|
minUpdateIntervalMs
|
|
5895
5607
|
};
|
|
5896
5608
|
}
|
|
5897
|
-
function buildCustomStatusActivity(text) {
|
|
5898
|
-
return {
|
|
5899
|
-
name: CUSTOM_STATUS_NAME,
|
|
5900
|
-
type: DEFAULT_CUSTOM_ACTIVITY_TYPE,
|
|
5901
|
-
state: text
|
|
5902
|
-
};
|
|
5903
|
-
}
|
|
5904
5609
|
function isExhaustedUnavailableReason(reason) {
|
|
5905
5610
|
if (!reason) return false;
|
|
5906
5611
|
return reason === "rate_limit" || reason === "overloaded" || reason === "billing" || reason === "auth" || reason === "auth_permanent";
|
|
@@ -5916,15 +5621,6 @@ function resolveAuthAvailability(params) {
|
|
|
5916
5621
|
now: params.now
|
|
5917
5622
|
})) ? "exhausted" : "degraded";
|
|
5918
5623
|
}
|
|
5919
|
-
function resolvePresenceActivities(params) {
|
|
5920
|
-
if (params.state === "healthy") return params.basePresence?.activities ?? [];
|
|
5921
|
-
return [buildCustomStatusActivity(params.state === "degraded" ? "runtime degraded" : "token exhausted")];
|
|
5922
|
-
}
|
|
5923
|
-
function resolvePresenceStatus(state) {
|
|
5924
|
-
if (state === "healthy") return "online";
|
|
5925
|
-
if (state === "exhausted") return "dnd";
|
|
5926
|
-
return "idle";
|
|
5927
|
-
}
|
|
5928
5624
|
function resolveDiscordAutoPresenceUpdate(params) {
|
|
5929
5625
|
if (!resolveAutoPresenceConfig(params.discordConfig.autoPresence).enabled) return null;
|
|
5930
5626
|
const now = params.now ?? Date.now();
|
|
@@ -5934,15 +5630,15 @@ function resolveDiscordAutoPresenceUpdate(params) {
|
|
|
5934
5630
|
now
|
|
5935
5631
|
});
|
|
5936
5632
|
const state = params.gatewayConnected ? availability : "degraded";
|
|
5937
|
-
return {
|
|
5633
|
+
return state === "healthy" ? {
|
|
5938
5634
|
since: null,
|
|
5939
|
-
activities:
|
|
5940
|
-
|
|
5941
|
-
basePresence
|
|
5942
|
-
}),
|
|
5943
|
-
status: resolvePresenceStatus(state),
|
|
5635
|
+
activities: basePresence.activities,
|
|
5636
|
+
status: "online",
|
|
5944
5637
|
afk: false
|
|
5945
|
-
}
|
|
5638
|
+
} : resolveDiscordPresenceUpdate({
|
|
5639
|
+
activity: state === "degraded" ? "runtime degraded" : "token exhausted",
|
|
5640
|
+
status: state === "degraded" ? "idle" : "dnd"
|
|
5641
|
+
});
|
|
5946
5642
|
}
|
|
5947
5643
|
function stablePresenceSignature(payload) {
|
|
5948
5644
|
return JSON.stringify({
|
|
@@ -6015,6 +5711,7 @@ function createDiscordAutoPresenceController(params) {
|
|
|
6015
5711
|
const DISCORD_GATEWAY_TRANSPORT_ACTIVITY_EVENT = "openclaw:discord-gateway-transport-activity";
|
|
6016
5712
|
//#endregion
|
|
6017
5713
|
//#region extensions/discord/src/monitor/gateway-metadata.ts
|
|
5714
|
+
const captureSdk$1 = proxyCaptureSdk;
|
|
6018
5715
|
const DISCORD_GATEWAY_BOT_URL = "https://discord.com/api/v10/gateway/bot";
|
|
6019
5716
|
const DISCORD_API_HOST = "discord.com";
|
|
6020
5717
|
const DEFAULT_DISCORD_GATEWAY_URL = "wss://gateway.discord.gg/";
|
|
@@ -6034,11 +5731,6 @@ const discordGatewayBotInfoSchema = Type.Object({
|
|
|
6034
5731
|
})
|
|
6035
5732
|
});
|
|
6036
5733
|
const gatewayMetadataFallbackLogLastAt = /* @__PURE__ */ new WeakMap();
|
|
6037
|
-
function resolveFetchInputUrl(input) {
|
|
6038
|
-
if (typeof input === "string") return input;
|
|
6039
|
-
if (input instanceof URL) return input.toString();
|
|
6040
|
-
return input.url;
|
|
6041
|
-
}
|
|
6042
5734
|
async function materializeGuardedResponse(response) {
|
|
6043
5735
|
const body = new Uint8Array(await readResponseWithLimit(response, DISCORD_GATEWAY_METADATA_MAX_BYTES, { onOverflow: ({ size, maxBytes }) => /* @__PURE__ */ new Error(`Discord gateway metadata response body too large: ${size} bytes (limit: ${maxBytes} bytes)`) }));
|
|
6044
5736
|
return new Response(body, {
|
|
@@ -6102,6 +5794,7 @@ function parseDiscordGatewayInfoBody(body) {
|
|
|
6102
5794
|
}
|
|
6103
5795
|
async function fetchDiscordGatewayInfo(params) {
|
|
6104
5796
|
let response;
|
|
5797
|
+
let body;
|
|
6105
5798
|
try {
|
|
6106
5799
|
response = await params.fetchImpl(params.gatewayBotUrl ?? DISCORD_GATEWAY_BOT_URL, {
|
|
6107
5800
|
...params.fetchInit,
|
|
@@ -6110,15 +5803,6 @@ async function fetchDiscordGatewayInfo(params) {
|
|
|
6110
5803
|
Authorization: `Bot ${params.token}`
|
|
6111
5804
|
}
|
|
6112
5805
|
});
|
|
6113
|
-
} catch (error) {
|
|
6114
|
-
throw createGatewayMetadataError({
|
|
6115
|
-
detail: formatErrorMessage$1(error),
|
|
6116
|
-
transient: true,
|
|
6117
|
-
cause: error
|
|
6118
|
-
});
|
|
6119
|
-
}
|
|
6120
|
-
let body;
|
|
6121
|
-
try {
|
|
6122
5806
|
body = await response.text();
|
|
6123
5807
|
} catch (error) {
|
|
6124
5808
|
throw createGatewayMetadataError({
|
|
@@ -6183,7 +5867,7 @@ async function fetchDiscordGatewayMetadataGuarded(input, init, options) {
|
|
|
6183
5867
|
const requestInit = init;
|
|
6184
5868
|
const signal = requestInit?.signal ?? void 0;
|
|
6185
5869
|
const guarded = await fetchWithSsrFGuard({
|
|
6186
|
-
url:
|
|
5870
|
+
url: input,
|
|
6187
5871
|
init: requestInit,
|
|
6188
5872
|
...signal ? { signal } : {},
|
|
6189
5873
|
policy: { allowedHostnames: [DISCORD_API_HOST] },
|
|
@@ -6204,7 +5888,7 @@ async function fetchDiscordGatewayMetadataGuarded(input, init, options) {
|
|
|
6204
5888
|
} finally {
|
|
6205
5889
|
await guarded.release();
|
|
6206
5890
|
}
|
|
6207
|
-
if (options?.capture)
|
|
5891
|
+
if (options?.capture) captureSdk$1.captureHttpExchangeAsync?.({
|
|
6208
5892
|
url: input,
|
|
6209
5893
|
method: init?.method ?? "GET",
|
|
6210
5894
|
requestHeaders: init?.headers,
|
|
@@ -6212,23 +5896,17 @@ async function fetchDiscordGatewayMetadataGuarded(input, init, options) {
|
|
|
6212
5896
|
response,
|
|
6213
5897
|
flowId: options.capture.flowId,
|
|
6214
5898
|
meta: options.capture.meta
|
|
6215
|
-
});
|
|
5899
|
+
}).catch(() => {});
|
|
6216
5900
|
return response;
|
|
6217
5901
|
}
|
|
6218
5902
|
//#endregion
|
|
6219
5903
|
//#region extensions/discord/src/monitor/gateway-plugin.ts
|
|
5904
|
+
const captureSdk = proxyCaptureSdk;
|
|
6220
5905
|
const DISCORD_GATEWAY_POLICY_VIOLATION_CLOSE_CODE = 1008;
|
|
6221
5906
|
const DISCORD_GATEWAY_WS_RECEIVER_LIMIT_CODE = "WS_ERR_TOO_MANY_BUFFERED_PARTS";
|
|
6222
5907
|
const DISCORD_GATEWAY_CLOSE_REASON_LOG_MAX_CHARS = 240;
|
|
6223
5908
|
const discordDnsLookup = createDiscordDnsLookup();
|
|
6224
5909
|
const registrationPromises = /* @__PURE__ */ new WeakMap();
|
|
6225
|
-
function assignGatewayClient(plugin, client) {
|
|
6226
|
-
plugin.client = client;
|
|
6227
|
-
}
|
|
6228
|
-
function hasGatewaySocketStarted(plugin) {
|
|
6229
|
-
const state = plugin;
|
|
6230
|
-
return state.ws != null || state.isConnecting === true;
|
|
6231
|
-
}
|
|
6232
5910
|
function readStringProperty(value, key) {
|
|
6233
5911
|
const property = value[key];
|
|
6234
5912
|
return typeof property === "string" && property ? property : void 0;
|
|
@@ -6304,7 +5982,7 @@ function createGatewayPlugin(params) {
|
|
|
6304
5982
|
return registration;
|
|
6305
5983
|
}
|
|
6306
5984
|
async registerClientInternal(client) {
|
|
6307
|
-
|
|
5985
|
+
this.client = client;
|
|
6308
5986
|
if (!this.gatewayInfo || this.gatewayInfoUsedFallback) {
|
|
6309
5987
|
const resolved = await fetchDiscordGatewayInfoWithTimeout({
|
|
6310
5988
|
token: client.options.token,
|
|
@@ -6329,7 +6007,7 @@ function createGatewayPlugin(params) {
|
|
|
6329
6007
|
await params.testing.registerClient(this, client);
|
|
6330
6008
|
return;
|
|
6331
6009
|
}
|
|
6332
|
-
if (
|
|
6010
|
+
if (this.ws != null || this.isConnecting) return;
|
|
6333
6011
|
return super.registerClient(client);
|
|
6334
6012
|
}
|
|
6335
6013
|
createWebSocket(url) {
|
|
@@ -6345,35 +6023,34 @@ function createGatewayPlugin(params) {
|
|
|
6345
6023
|
if (this.ws !== socket) return;
|
|
6346
6024
|
this.emitter.emit(DISCORD_GATEWAY_TRANSPORT_ACTIVITY_EVENT, { at: Date.now() });
|
|
6347
6025
|
};
|
|
6348
|
-
|
|
6349
|
-
|
|
6026
|
+
const captureEvent = (event) => {
|
|
6027
|
+
captureSdk.captureWsEventAsync?.({
|
|
6028
|
+
url,
|
|
6029
|
+
...event(),
|
|
6030
|
+
flowId: wsFlowId,
|
|
6031
|
+
meta: { subsystem: "discord-gateway" }
|
|
6032
|
+
}).catch(() => {});
|
|
6033
|
+
};
|
|
6034
|
+
captureEvent(() => ({
|
|
6350
6035
|
direction: "local",
|
|
6351
|
-
kind: "ws-open"
|
|
6352
|
-
|
|
6353
|
-
meta: { subsystem: "discord-gateway" }
|
|
6354
|
-
});
|
|
6036
|
+
kind: "ws-open"
|
|
6037
|
+
}));
|
|
6355
6038
|
socket.on?.("message", (data) => {
|
|
6356
6039
|
emitTransportActivity();
|
|
6357
|
-
|
|
6358
|
-
url,
|
|
6040
|
+
captureEvent(() => ({
|
|
6359
6041
|
direction: "inbound",
|
|
6360
6042
|
kind: "ws-frame",
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
meta: { subsystem: "discord-gateway" }
|
|
6364
|
-
});
|
|
6043
|
+
payload: Buffer.isBuffer(data) ? data : Buffer.from(String(data))
|
|
6044
|
+
}));
|
|
6365
6045
|
});
|
|
6366
6046
|
socket.on?.("close", (code, reason) => {
|
|
6367
6047
|
const closeReason = Buffer.isBuffer(reason) ? reason : Buffer.from(String(reason ?? ""));
|
|
6368
|
-
|
|
6369
|
-
url,
|
|
6048
|
+
captureEvent(() => ({
|
|
6370
6049
|
direction: "local",
|
|
6371
6050
|
kind: "ws-close",
|
|
6372
|
-
flowId: wsFlowId,
|
|
6373
6051
|
closeCode: code,
|
|
6374
|
-
payload: closeReason
|
|
6375
|
-
|
|
6376
|
-
});
|
|
6052
|
+
payload: closeReason
|
|
6053
|
+
}));
|
|
6377
6054
|
if (shouldLogDiscordGatewayTransportClose({
|
|
6378
6055
|
code,
|
|
6379
6056
|
reason: closeReason,
|
|
@@ -6387,14 +6064,11 @@ function createGatewayPlugin(params) {
|
|
|
6387
6064
|
});
|
|
6388
6065
|
socket.on?.("error", (error) => {
|
|
6389
6066
|
lastTransportError = describeDiscordGatewayTransportError(error);
|
|
6390
|
-
|
|
6391
|
-
url,
|
|
6067
|
+
captureEvent(() => ({
|
|
6392
6068
|
direction: "local",
|
|
6393
6069
|
kind: "error",
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
meta: { subsystem: "discord-gateway" }
|
|
6397
|
-
});
|
|
6070
|
+
errorText: error.message
|
|
6071
|
+
}));
|
|
6398
6072
|
params.runtime?.log?.(warn(formatDiscordGatewayTransportErrorLog({
|
|
6399
6073
|
flowId: wsFlowId,
|
|
6400
6074
|
error: lastTransportError
|
|
@@ -6445,7 +6119,7 @@ function createDiscordGatewayPlugin(params) {
|
|
|
6445
6119
|
} : void 0;
|
|
6446
6120
|
const endpointGatewayUrl = endpoint ? new URL(endpoint.gatewayOrigin) : void 0;
|
|
6447
6121
|
let fetchImpl = createDiscordGatewayMetadataFetch(debugProxySettings.enabled, endpoint ? { endpoint } : void 0);
|
|
6448
|
-
let wsAgent = endpointGatewayUrl?.protocol === "ws:" ? void 0 : new Agent
|
|
6122
|
+
let wsAgent = endpointGatewayUrl?.protocol === "ws:" ? void 0 : new Agent({ lookup: endpointGatewayUrl ? createDiscordEndpointDnsLookup(endpointGatewayUrl.hostname) : discordDnsLookup });
|
|
6449
6123
|
if (proxy && !endpoint) try {
|
|
6450
6124
|
validateDiscordProxyUrl(proxy);
|
|
6451
6125
|
wsAgent = params.testing?.createProxyAgent?.(proxy) ?? createNodeProxyAgent({
|
|
@@ -6524,29 +6198,16 @@ function formatDiscordGatewayErrorMessage(err) {
|
|
|
6524
6198
|
}
|
|
6525
6199
|
function classifyDiscordGatewayEvent(params) {
|
|
6526
6200
|
const message = formatDiscordGatewayErrorMessage(params.err);
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
};
|
|
6533
|
-
if (message.includes("Max reconnect attempts")) return {
|
|
6534
|
-
type: "reconnect-exhausted",
|
|
6535
|
-
err: params.err,
|
|
6536
|
-
message,
|
|
6537
|
-
shouldStopLifecycle: true
|
|
6538
|
-
};
|
|
6539
|
-
if (params.err instanceof TypeError || message.includes("Fatal Gateway error") || message.includes("Fatal gateway close code") || message.includes("Gateway HELLO missing heartbeat") || message.includes("Invalid gateway payload") || message.includes("Gateway socket emitted an unknown error")) return {
|
|
6540
|
-
type: "fatal",
|
|
6541
|
-
err: params.err,
|
|
6542
|
-
message,
|
|
6543
|
-
shouldStopLifecycle: true
|
|
6544
|
-
};
|
|
6201
|
+
let type;
|
|
6202
|
+
if (params.isDisallowedIntentsError(params.err)) type = "disallowed-intents";
|
|
6203
|
+
else if (message.includes("Max reconnect attempts")) type = "reconnect-exhausted";
|
|
6204
|
+
else if (params.err instanceof TypeError || message.includes("Fatal Gateway error") || message.includes("Fatal gateway close code") || message.includes("Gateway HELLO missing heartbeat") || message.includes("Invalid gateway payload") || message.includes("Gateway socket emitted an unknown error")) type = "fatal";
|
|
6205
|
+
else type = "other";
|
|
6545
6206
|
return {
|
|
6546
|
-
type
|
|
6207
|
+
type,
|
|
6547
6208
|
err: params.err,
|
|
6548
6209
|
message,
|
|
6549
|
-
shouldStopLifecycle:
|
|
6210
|
+
shouldStopLifecycle: type !== "other"
|
|
6550
6211
|
};
|
|
6551
6212
|
}
|
|
6552
6213
|
function createDiscordGatewaySupervisor(params) {
|
|
@@ -6562,7 +6223,7 @@ function createDiscordGatewaySupervisor(params) {
|
|
|
6562
6223
|
let lifecycleHandler;
|
|
6563
6224
|
let phase = "buffering";
|
|
6564
6225
|
const seenLateEventKeys = /* @__PURE__ */ new Set();
|
|
6565
|
-
const logLateEvent = (state
|
|
6226
|
+
const logLateEvent = (state, event) => {
|
|
6566
6227
|
const key = `${state}:${event.type}:${event.message}`;
|
|
6567
6228
|
if (seenLateEventKeys.has(key)) return;
|
|
6568
6229
|
seenLateEventKeys.add(key);
|
|
@@ -6575,13 +6236,13 @@ function createDiscordGatewaySupervisor(params) {
|
|
|
6575
6236
|
});
|
|
6576
6237
|
switch (phase) {
|
|
6577
6238
|
case "disposed":
|
|
6578
|
-
logLateEvent("disposed"
|
|
6239
|
+
logLateEvent("disposed", event);
|
|
6579
6240
|
return;
|
|
6580
6241
|
case "active":
|
|
6581
6242
|
lifecycleHandler?.(event);
|
|
6582
6243
|
return;
|
|
6583
6244
|
case "teardown":
|
|
6584
|
-
logLateEvent("teardown"
|
|
6245
|
+
logLateEvent("teardown", event);
|
|
6585
6246
|
return;
|
|
6586
6247
|
case "buffering": pending.push(event);
|
|
6587
6248
|
}
|
|
@@ -6733,12 +6394,6 @@ function normalizeGatewayReadyTimeoutMs(value) {
|
|
|
6733
6394
|
if (numeric === void 0) return;
|
|
6734
6395
|
return Math.min(numeric, MAX_DISCORD_GATEWAY_READY_TIMEOUT_MS);
|
|
6735
6396
|
}
|
|
6736
|
-
function resolveDiscordGatewayReadyTimeoutMs(params) {
|
|
6737
|
-
return normalizeGatewayReadyTimeoutMs(params?.env?.[DISCORD_GATEWAY_READY_TIMEOUT_ENV]) ?? DEFAULT_DISCORD_GATEWAY_READY_TIMEOUT_MS;
|
|
6738
|
-
}
|
|
6739
|
-
function resolveDiscordGatewayRuntimeReadyTimeoutMs(params) {
|
|
6740
|
-
return normalizeGatewayReadyTimeoutMs(params?.env?.[DISCORD_GATEWAY_RUNTIME_READY_TIMEOUT_ENV]) ?? DEFAULT_DISCORD_GATEWAY_RUNTIME_READY_TIMEOUT_MS;
|
|
6741
|
-
}
|
|
6742
6397
|
async function restartGatewayAfterReadyTimeout(params) {
|
|
6743
6398
|
if (!params.gateway || params.abortSignal?.aborted) return;
|
|
6744
6399
|
const socket = params.gateway.ws;
|
|
@@ -6767,44 +6422,32 @@ async function restartGatewayAfterReadyTimeout(params) {
|
|
|
6767
6422
|
socket.removeListener("close", onClose);
|
|
6768
6423
|
socket.removeListener("error", ignoreSocketError);
|
|
6769
6424
|
};
|
|
6770
|
-
const
|
|
6425
|
+
const finish = (error) => {
|
|
6771
6426
|
if (settled) return;
|
|
6772
6427
|
settled = true;
|
|
6773
6428
|
cleanup();
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
const finishReject = (error) => {
|
|
6777
|
-
if (params.abortSignal?.aborted) {
|
|
6778
|
-
finishResolve();
|
|
6779
|
-
return;
|
|
6780
|
-
}
|
|
6781
|
-
if (settled) return;
|
|
6782
|
-
settled = true;
|
|
6783
|
-
cleanup();
|
|
6784
|
-
reject(error);
|
|
6785
|
-
};
|
|
6786
|
-
const onClose = () => {
|
|
6787
|
-
finishResolve();
|
|
6429
|
+
if (error && !params.abortSignal?.aborted) reject(error);
|
|
6430
|
+
else resolve();
|
|
6788
6431
|
};
|
|
6432
|
+
const onClose = () => finish();
|
|
6433
|
+
const failClose = () => finish(/* @__PURE__ */ new Error(`discord gateway socket did not close within ${DISCORD_GATEWAY_STARTUP_DISCONNECT_DRAIN_TIMEOUT_MS}ms before restart`));
|
|
6789
6434
|
socket.on("error", ignoreSocketError);
|
|
6790
6435
|
socket.on("close", onClose);
|
|
6791
6436
|
params.gateway?.disconnect();
|
|
6792
6437
|
drainTimeout = setTimeout(() => {
|
|
6793
6438
|
if (settled) return;
|
|
6794
6439
|
if (typeof socket.terminate !== "function") {
|
|
6795
|
-
|
|
6440
|
+
failClose();
|
|
6796
6441
|
return;
|
|
6797
6442
|
}
|
|
6798
6443
|
params.runtime.error?.(danger(`discord: startup restart waiting on a stale gateway socket for ${DISCORD_GATEWAY_STARTUP_DISCONNECT_DRAIN_TIMEOUT_MS}ms; forcing terminate before reconnect`));
|
|
6799
6444
|
try {
|
|
6800
6445
|
socket.terminate();
|
|
6801
6446
|
} catch {
|
|
6802
|
-
|
|
6447
|
+
failClose();
|
|
6803
6448
|
return;
|
|
6804
6449
|
}
|
|
6805
|
-
terminateCloseTimeout = setTimeout(
|
|
6806
|
-
finishReject(/* @__PURE__ */ new Error(`discord gateway socket did not close within ${DISCORD_GATEWAY_STARTUP_DISCONNECT_DRAIN_TIMEOUT_MS}ms before restart`));
|
|
6807
|
-
}, DISCORD_GATEWAY_STARTUP_TERMINATE_CLOSE_TIMEOUT_MS);
|
|
6450
|
+
terminateCloseTimeout = setTimeout(failClose, DISCORD_GATEWAY_STARTUP_TERMINATE_CLOSE_TIMEOUT_MS);
|
|
6808
6451
|
terminateCloseTimeout.unref?.();
|
|
6809
6452
|
}, DISCORD_GATEWAY_STARTUP_DISCONNECT_DRAIN_TIMEOUT_MS);
|
|
6810
6453
|
drainTimeout.unref?.();
|
|
@@ -6845,9 +6488,6 @@ function createGatewayStatusObserver(params) {
|
|
|
6845
6488
|
}
|
|
6846
6489
|
queuedForceStopError = err;
|
|
6847
6490
|
};
|
|
6848
|
-
const pushConnectedStatus = (at) => {
|
|
6849
|
-
params.pushStatus(createDiscordReadyStatusPatch(at));
|
|
6850
|
-
};
|
|
6851
6491
|
const startReadyWatch = () => {
|
|
6852
6492
|
clearReadyWatch();
|
|
6853
6493
|
const pollConnected = () => {
|
|
@@ -6857,7 +6497,7 @@ function createGatewayStatusObserver(params) {
|
|
|
6857
6497
|
}
|
|
6858
6498
|
if (!params.gateway?.isConnected) return;
|
|
6859
6499
|
clearReadyWatch();
|
|
6860
|
-
|
|
6500
|
+
params.pushStatus(createDiscordReadyStatusPatch(Date.now()));
|
|
6861
6501
|
};
|
|
6862
6502
|
pollConnected();
|
|
6863
6503
|
if (!readyTimeoutId) {
|
|
@@ -7007,8 +6647,8 @@ async function runDiscordGatewayLifecycle(params) {
|
|
|
7007
6647
|
const pushStatus = (patch) => {
|
|
7008
6648
|
params.statusSink?.(patch);
|
|
7009
6649
|
};
|
|
7010
|
-
const gatewayReadyTimeoutMs =
|
|
7011
|
-
const gatewayRuntimeReadyTimeoutMs =
|
|
6650
|
+
const gatewayReadyTimeoutMs = normalizeGatewayReadyTimeoutMs(process.env[DISCORD_GATEWAY_READY_TIMEOUT_ENV]) ?? DEFAULT_DISCORD_GATEWAY_READY_TIMEOUT_MS;
|
|
6651
|
+
const gatewayRuntimeReadyTimeoutMs = normalizeGatewayReadyTimeoutMs(process.env[DISCORD_GATEWAY_RUNTIME_READY_TIMEOUT_ENV]) ?? DEFAULT_DISCORD_GATEWAY_RUNTIME_READY_TIMEOUT_MS;
|
|
7012
6652
|
const statusObserver = createGatewayStatusObserver({
|
|
7013
6653
|
gateway,
|
|
7014
6654
|
abortSignal: params.abortSignal,
|
|
@@ -7072,23 +6712,26 @@ async function runDiscordGatewayLifecycle(params) {
|
|
|
7072
6712
|
} catch (err) {
|
|
7073
6713
|
if (!sawDisallowedIntents && !params.isDisallowedIntentsError(err)) throw err;
|
|
7074
6714
|
} finally {
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
6715
|
+
try {
|
|
6716
|
+
lifecycleStopping = true;
|
|
6717
|
+
params.gatewaySupervisor.detachLifecycle();
|
|
6718
|
+
unregisterGateway(params.accountId);
|
|
6719
|
+
stopGatewayLogging();
|
|
6720
|
+
statusObserver.dispose();
|
|
6721
|
+
gatewayEmitter?.removeListener("debug", statusObserver.onGatewayDebug);
|
|
6722
|
+
gatewayEmitter?.removeListener(DISCORD_GATEWAY_TRANSPORT_ACTIVITY_EVENT, onGatewayTransportActivity);
|
|
6723
|
+
if (params.voiceManager) {
|
|
6724
|
+
await params.voiceManager.destroy();
|
|
6725
|
+
setDiscordTranscriptsVoiceManager({
|
|
6726
|
+
accountId: params.accountId,
|
|
6727
|
+
manager: null,
|
|
6728
|
+
expectedManager: params.voiceManager
|
|
6729
|
+
});
|
|
6730
|
+
params.voiceManagerRef.current = null;
|
|
6731
|
+
}
|
|
6732
|
+
} finally {
|
|
6733
|
+
await params.threadBindings.stop();
|
|
7090
6734
|
}
|
|
7091
|
-
params.threadBindings.stop();
|
|
7092
6735
|
}
|
|
7093
6736
|
}
|
|
7094
6737
|
//#endregion
|
|
@@ -7096,7 +6739,7 @@ async function runDiscordGatewayLifecycle(params) {
|
|
|
7096
6739
|
let discordVoiceRuntimePromise;
|
|
7097
6740
|
let discordProviderSessionRuntimePromise;
|
|
7098
6741
|
async function loadDiscordVoiceRuntime() {
|
|
7099
|
-
const promise = discordVoiceRuntimePromise ?? import("./voice-runtime-
|
|
6742
|
+
const promise = discordVoiceRuntimePromise ?? import("./voice-runtime-B46rcwrG.mjs").then((n) => n.t);
|
|
7100
6743
|
discordVoiceRuntimePromise = promise;
|
|
7101
6744
|
try {
|
|
7102
6745
|
return await promise;
|
|
@@ -7106,7 +6749,7 @@ async function loadDiscordVoiceRuntime() {
|
|
|
7106
6749
|
}
|
|
7107
6750
|
}
|
|
7108
6751
|
async function loadDiscordProviderSessionRuntime() {
|
|
7109
|
-
const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-
|
|
6752
|
+
const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-BYlTBFD2.mjs");
|
|
7110
6753
|
discordProviderSessionRuntimePromise = promise;
|
|
7111
6754
|
try {
|
|
7112
6755
|
return await promise;
|
|
@@ -7210,22 +6853,49 @@ async function probeDiscordAcpBindingHealth(params) {
|
|
|
7210
6853
|
//#endregion
|
|
7211
6854
|
//#region extensions/discord/src/monitor/provider.cleanup.ts
|
|
7212
6855
|
async function cleanupDiscordProviderStartup(params) {
|
|
7213
|
-
const listenersStopped = params.stopMonitorListeners?.();
|
|
7214
6856
|
try {
|
|
7215
|
-
|
|
6857
|
+
const listenersStopped = params.stopMonitorListeners?.();
|
|
6858
|
+
try {
|
|
6859
|
+
await params.deactivateMessageHandler?.();
|
|
6860
|
+
} finally {
|
|
6861
|
+
await listenersStopped;
|
|
6862
|
+
}
|
|
6863
|
+
params.autoPresenceController?.stop();
|
|
6864
|
+
params.setStatus?.({ connected: false });
|
|
6865
|
+
if (params.onEarlyGatewayDebug) params.earlyGatewayEmitter?.removeListener("debug", params.onEarlyGatewayDebug);
|
|
6866
|
+
if (!params.lifecycleStarted) try {
|
|
6867
|
+
params.lifecycleGateway?.disconnect();
|
|
6868
|
+
} catch (err) {
|
|
6869
|
+
params.runtime.error?.(danger(`discord: failed to disconnect gateway during startup cleanup: ${String(err)}`));
|
|
6870
|
+
}
|
|
6871
|
+
params.gatewaySupervisor?.dispose();
|
|
7216
6872
|
} finally {
|
|
7217
|
-
await
|
|
7218
|
-
}
|
|
7219
|
-
params.autoPresenceController?.stop();
|
|
7220
|
-
params.setStatus?.({ connected: false });
|
|
7221
|
-
if (params.onEarlyGatewayDebug) params.earlyGatewayEmitter?.removeListener("debug", params.onEarlyGatewayDebug);
|
|
7222
|
-
if (!params.lifecycleStarted) try {
|
|
7223
|
-
params.lifecycleGateway?.disconnect();
|
|
7224
|
-
} catch (err) {
|
|
7225
|
-
params.runtime.error?.(danger(`discord: failed to disconnect gateway during startup cleanup: ${String(err)}`));
|
|
6873
|
+
if (!params.lifecycleStarted) await params.threadBindings.stop();
|
|
7226
6874
|
}
|
|
7227
|
-
|
|
7228
|
-
|
|
6875
|
+
}
|
|
6876
|
+
//#endregion
|
|
6877
|
+
//#region extensions/discord/src/voice/session.ts
|
|
6878
|
+
const MIN_SEGMENT_SECONDS = .35;
|
|
6879
|
+
const CAPTURE_FINALIZE_GRACE_MS = 2e3;
|
|
6880
|
+
const VOICE_CONNECT_READY_TIMEOUT_MS = 3e4;
|
|
6881
|
+
const VOICE_RECONNECT_GRACE_MS = 15e3;
|
|
6882
|
+
function resolveVoiceTimeoutMs(value, fallbackMs) {
|
|
6883
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return fallbackMs;
|
|
6884
|
+
return Math.floor(value);
|
|
6885
|
+
}
|
|
6886
|
+
function resolveDiscordVoiceMode(voice) {
|
|
6887
|
+
const mode = voice?.mode;
|
|
6888
|
+
if (mode === "stt-tts" || mode === "bidi") return mode;
|
|
6889
|
+
return "agent-proxy";
|
|
6890
|
+
}
|
|
6891
|
+
function isDiscordRealtimeVoiceMode(mode) {
|
|
6892
|
+
return mode === "agent-proxy" || mode === "bidi";
|
|
6893
|
+
}
|
|
6894
|
+
function logVoiceVerbose(message) {
|
|
6895
|
+
logVerbose(`discord voice: ${message}`);
|
|
6896
|
+
}
|
|
6897
|
+
function isVoiceChannel(type) {
|
|
6898
|
+
return type === discord_exports.ChannelType.GuildVoice || type === discord_exports.ChannelType.GuildStageVoice;
|
|
7229
6899
|
}
|
|
7230
6900
|
//#endregion
|
|
7231
6901
|
//#region extensions/discord/src/voice/command.ts
|
|
@@ -7302,37 +6972,6 @@ async function authorizeVoiceCommand(interaction, params, options) {
|
|
|
7302
6972
|
guildId: interaction.guild.id
|
|
7303
6973
|
};
|
|
7304
6974
|
}
|
|
7305
|
-
async function resolveVoiceCommandRuntimeContext(interaction, params) {
|
|
7306
|
-
const guildId = interaction.guild?.id;
|
|
7307
|
-
if (!guildId) {
|
|
7308
|
-
await interaction.reply({
|
|
7309
|
-
content: "Unable to resolve guild for this command.",
|
|
7310
|
-
ephemeral: true
|
|
7311
|
-
});
|
|
7312
|
-
return null;
|
|
7313
|
-
}
|
|
7314
|
-
const manager = params.getManager();
|
|
7315
|
-
if (!manager) {
|
|
7316
|
-
await interaction.reply({
|
|
7317
|
-
content: "Voice manager is not available yet.",
|
|
7318
|
-
ephemeral: true
|
|
7319
|
-
});
|
|
7320
|
-
return null;
|
|
7321
|
-
}
|
|
7322
|
-
return {
|
|
7323
|
-
guildId,
|
|
7324
|
-
manager
|
|
7325
|
-
};
|
|
7326
|
-
}
|
|
7327
|
-
async function ensureVoiceCommandAccess(params) {
|
|
7328
|
-
const access = await authorizeVoiceCommand(params.interaction, params.context, { channelOverride: params.channelOverride });
|
|
7329
|
-
if (access.ok) return true;
|
|
7330
|
-
await params.interaction.reply({
|
|
7331
|
-
content: access.message ?? "Not authorized.",
|
|
7332
|
-
ephemeral: true
|
|
7333
|
-
});
|
|
7334
|
-
return false;
|
|
7335
|
-
}
|
|
7336
6975
|
function createDiscordVoiceCommand(startupParams) {
|
|
7337
6976
|
const params = {
|
|
7338
6977
|
...startupParams,
|
|
@@ -7348,7 +6987,6 @@ function createDiscordVoiceCommand(startupParams) {
|
|
|
7348
6987
|
}
|
|
7349
6988
|
})
|
|
7350
6989
|
};
|
|
7351
|
-
const resolveSessionChannelId = (manager, guildId) => manager.status().find((entry) => entry.guildId === guildId)?.channelId;
|
|
7352
6990
|
class JoinCommand extends Command {
|
|
7353
6991
|
constructor(..._args) {
|
|
7354
6992
|
super(..._args);
|
|
@@ -7384,7 +7022,7 @@ function createDiscordVoiceCommand(startupParams) {
|
|
|
7384
7022
|
});
|
|
7385
7023
|
return;
|
|
7386
7024
|
}
|
|
7387
|
-
if (!
|
|
7025
|
+
if (!isVoiceChannel(channel.type)) {
|
|
7388
7026
|
await interaction.reply({
|
|
7389
7027
|
content: "That is not a voice channel.",
|
|
7390
7028
|
ephemeral: true
|
|
@@ -7417,48 +7055,49 @@ function createDiscordVoiceCommand(startupParams) {
|
|
|
7417
7055
|
});
|
|
7418
7056
|
}
|
|
7419
7057
|
}
|
|
7420
|
-
class
|
|
7421
|
-
constructor(
|
|
7422
|
-
super(
|
|
7423
|
-
this.name =
|
|
7424
|
-
this.description = "Leave the current voice channel";
|
|
7425
|
-
this.defer = true;
|
|
7426
|
-
this.ephemeral = params.ephemeralDefault;
|
|
7427
|
-
}
|
|
7428
|
-
async run(interaction) {
|
|
7429
|
-
const runtimeContext = await resolveVoiceCommandRuntimeContext(interaction, params);
|
|
7430
|
-
if (!runtimeContext) return;
|
|
7431
|
-
const sessionChannelId = resolveSessionChannelId(runtimeContext.manager, runtimeContext.guildId);
|
|
7432
|
-
if (!await ensureVoiceCommandAccess({
|
|
7433
|
-
interaction,
|
|
7434
|
-
context: params,
|
|
7435
|
-
channelOverride: sessionChannelId ? { id: sessionChannelId } : void 0
|
|
7436
|
-
})) return;
|
|
7437
|
-
const result = await runtimeContext.manager.leave({ guildId: runtimeContext.guildId });
|
|
7438
|
-
await interaction.reply({
|
|
7439
|
-
content: result.message,
|
|
7440
|
-
ephemeral: true
|
|
7441
|
-
});
|
|
7442
|
-
}
|
|
7443
|
-
}
|
|
7444
|
-
class StatusCommand extends Command {
|
|
7445
|
-
constructor(..._args3) {
|
|
7446
|
-
super(..._args3);
|
|
7447
|
-
this.name = "status";
|
|
7448
|
-
this.description = "Show active voice sessions";
|
|
7058
|
+
class SessionCommand extends Command {
|
|
7059
|
+
constructor(name) {
|
|
7060
|
+
super();
|
|
7061
|
+
this.name = name;
|
|
7449
7062
|
this.defer = true;
|
|
7450
7063
|
this.ephemeral = params.ephemeralDefault;
|
|
7064
|
+
this.description = name === "leave" ? "Leave the current voice channel" : "Show active voice sessions";
|
|
7451
7065
|
}
|
|
7452
7066
|
async run(interaction) {
|
|
7453
|
-
const
|
|
7454
|
-
if (!
|
|
7455
|
-
|
|
7067
|
+
const guildId = interaction.guild?.id;
|
|
7068
|
+
if (!guildId) {
|
|
7069
|
+
await interaction.reply({
|
|
7070
|
+
content: "Unable to resolve guild for this command.",
|
|
7071
|
+
ephemeral: true
|
|
7072
|
+
});
|
|
7073
|
+
return;
|
|
7074
|
+
}
|
|
7075
|
+
const manager = params.getManager();
|
|
7076
|
+
if (!manager) {
|
|
7077
|
+
await interaction.reply({
|
|
7078
|
+
content: "Voice manager is not available yet.",
|
|
7079
|
+
ephemeral: true
|
|
7080
|
+
});
|
|
7081
|
+
return;
|
|
7082
|
+
}
|
|
7083
|
+
const sessions = manager.status().filter((entry) => entry.guildId === guildId);
|
|
7456
7084
|
const sessionChannelId = sessions[0]?.channelId;
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7085
|
+
const access = await authorizeVoiceCommand(interaction, params, { channelOverride: sessionChannelId ? { id: sessionChannelId } : void 0 });
|
|
7086
|
+
if (!access.ok) {
|
|
7087
|
+
await interaction.reply({
|
|
7088
|
+
content: access.message ?? "Not authorized.",
|
|
7089
|
+
ephemeral: true
|
|
7090
|
+
});
|
|
7091
|
+
return;
|
|
7092
|
+
}
|
|
7093
|
+
if (this.name === "leave") {
|
|
7094
|
+
const result = await manager.leave({ guildId });
|
|
7095
|
+
await interaction.reply({
|
|
7096
|
+
content: result.message,
|
|
7097
|
+
ephemeral: true
|
|
7098
|
+
});
|
|
7099
|
+
return;
|
|
7100
|
+
}
|
|
7462
7101
|
if (sessions.length === 0) {
|
|
7463
7102
|
await interaction.reply({
|
|
7464
7103
|
content: "No active voice sessions.",
|
|
@@ -7474,21 +7113,18 @@ function createDiscordVoiceCommand(startupParams) {
|
|
|
7474
7113
|
}
|
|
7475
7114
|
}
|
|
7476
7115
|
return new class extends CommandWithSubcommands {
|
|
7477
|
-
constructor(...
|
|
7478
|
-
super(...
|
|
7116
|
+
constructor(..._args2) {
|
|
7117
|
+
super(..._args2);
|
|
7479
7118
|
this.name = DISCORD_VOICE_COMMAND_SPEC.name;
|
|
7480
7119
|
this.description = DISCORD_VOICE_COMMAND_SPEC.description;
|
|
7481
7120
|
this.subcommands = [
|
|
7482
7121
|
new JoinCommand(),
|
|
7483
|
-
new
|
|
7484
|
-
new
|
|
7122
|
+
new SessionCommand("leave"),
|
|
7123
|
+
new SessionCommand("status")
|
|
7485
7124
|
];
|
|
7486
7125
|
}
|
|
7487
7126
|
}();
|
|
7488
7127
|
}
|
|
7489
|
-
function isVoiceChannelType(type) {
|
|
7490
|
-
return type === ChannelType.GuildVoice || type === ChannelType.GuildStageVoice;
|
|
7491
|
-
}
|
|
7492
7128
|
//#endregion
|
|
7493
7129
|
//#region extensions/discord/src/monitor/provider.commands.ts
|
|
7494
7130
|
const loadPluginCommandRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/plugin-command-runtime"));
|
|
@@ -7570,7 +7206,6 @@ function attachDiscordDeployRestContext(err, context) {
|
|
|
7570
7206
|
if (typeof context.timeoutMs === "number" && Number.isFinite(context.timeoutMs)) deployErr.deployTimeoutMs = context.timeoutMs;
|
|
7571
7207
|
}
|
|
7572
7208
|
function stringifyDiscordDeployField(value) {
|
|
7573
|
-
if (typeof value === "string") return JSON.stringify(value);
|
|
7574
7209
|
try {
|
|
7575
7210
|
return JSON.stringify(value);
|
|
7576
7211
|
} catch {
|
|
@@ -7588,8 +7223,7 @@ function readDiscordDeployRejectedFields(value) {
|
|
|
7588
7223
|
function resolveDiscordRejectedDeployEntriesSource(rawBody) {
|
|
7589
7224
|
if (!rawBody || typeof rawBody !== "object") return null;
|
|
7590
7225
|
const payload = rawBody;
|
|
7591
|
-
|
|
7592
|
-
return source && typeof source === "object" ? source : null;
|
|
7226
|
+
return (payload.errors && typeof payload.errors === "object" ? payload.errors : void 0) ?? rawBody;
|
|
7593
7227
|
}
|
|
7594
7228
|
function readDiscordDeployObjectField(value, field) {
|
|
7595
7229
|
return value && typeof value === "object" && field in value ? value[field] : void 0;
|
|
@@ -7604,9 +7238,7 @@ function formatDiscordDeployRestOperation(err) {
|
|
|
7604
7238
|
const method = typeof err.deployRestMethod === "string" && err.deployRestMethod.trim().length > 0 ? err.deployRestMethod.toUpperCase() : void 0;
|
|
7605
7239
|
const path = typeof err.deployRestPath === "string" && err.deployRestPath.trim().length > 0 ? err.deployRestPath : void 0;
|
|
7606
7240
|
if (method && path) return `${method} ${path}`;
|
|
7607
|
-
|
|
7608
|
-
if (path) return path;
|
|
7609
|
-
return "request";
|
|
7241
|
+
return method ?? path ?? "request";
|
|
7610
7242
|
}
|
|
7611
7243
|
function formatDiscordDeployErrorMessage(err) {
|
|
7612
7244
|
if (!isAbortLikeError(err)) return formatErrorMessage(err);
|
|
@@ -7642,19 +7274,19 @@ function formatDiscordDeployRateLimitDetails(err) {
|
|
|
7642
7274
|
const rateLimit = resolveDiscordDeployRateLimitDetails(err);
|
|
7643
7275
|
if (!rateLimit) return "";
|
|
7644
7276
|
const details = [];
|
|
7645
|
-
if (
|
|
7646
|
-
if (
|
|
7277
|
+
if (rateLimit.status !== void 0) details.push(`status=${rateLimit.status}`);
|
|
7278
|
+
if (rateLimit.retryAfterMs !== void 0) details.push(`retryAfter=${formatDurationSeconds(rateLimit.retryAfterMs, { decimals: 1 })}`);
|
|
7647
7279
|
if (rateLimit.scope) details.push(`scope=${rateLimit.scope}`);
|
|
7648
|
-
if (
|
|
7280
|
+
if (rateLimit.discordCode !== void 0) details.push(`code=${rateLimit.discordCode}`);
|
|
7649
7281
|
return details.length > 0 ? ` (${details.join(", ")})` : "";
|
|
7650
7282
|
}
|
|
7651
7283
|
function formatDiscordDeployRateLimitWarning(err, accountId) {
|
|
7652
7284
|
const rateLimit = resolveDiscordDeployRateLimitDetails(err);
|
|
7653
7285
|
if (!rateLimit) return;
|
|
7654
7286
|
const parts = [`[${accountId}] slash command deploy rate limited`];
|
|
7655
|
-
if (
|
|
7287
|
+
if (rateLimit.retryAfterMs !== void 0) parts.push(`retry after ${formatDurationSeconds(rateLimit.retryAfterMs, { decimals: 1 })}`);
|
|
7656
7288
|
if (rateLimit.scope) parts.push(`scope=${rateLimit.scope}`);
|
|
7657
|
-
if (
|
|
7289
|
+
if (rateLimit.discordCode !== void 0) parts.push(`code=${rateLimit.discordCode}`);
|
|
7658
7290
|
return `${parts.join("; ")}. Existing slash commands stay active. Message send/receive is unaffected.`;
|
|
7659
7291
|
}
|
|
7660
7292
|
function formatDiscordRejectedDeployEntries(params) {
|
|
@@ -7683,10 +7315,7 @@ function formatDiscordDeployErrorDetails(err) {
|
|
|
7683
7315
|
if (!err || typeof err !== "object") return "";
|
|
7684
7316
|
const rateLimitDetails = formatDiscordDeployRateLimitDetails(err);
|
|
7685
7317
|
if (rateLimitDetails) return rateLimitDetails;
|
|
7686
|
-
const status = err
|
|
7687
|
-
const discordCode = err.discordCode;
|
|
7688
|
-
const rawBody = err.rawBody;
|
|
7689
|
-
const requestBody = err.deployRequestBody;
|
|
7318
|
+
const { status, discordCode, rawBody, deployRequestBody: requestBody } = err;
|
|
7690
7319
|
const details = [];
|
|
7691
7320
|
if (typeof status === "number") details.push(`status=${status}`);
|
|
7692
7321
|
if (typeof discordCode === "number" || typeof discordCode === "string") details.push(`code=${discordCode}`);
|
|
@@ -7727,7 +7356,7 @@ function formatDiscordStartupGatewayState(gateway) {
|
|
|
7727
7356
|
const reconnectAttempts = gateway.reconnectAttempts;
|
|
7728
7357
|
return `gatewayConnected=${gateway.isConnected ? "true" : "false"} reconnectAttempts=${typeof reconnectAttempts === "number" ? reconnectAttempts : "na"}`;
|
|
7729
7358
|
}
|
|
7730
|
-
function logDiscordStartupPhase
|
|
7359
|
+
function logDiscordStartupPhase(params) {
|
|
7731
7360
|
if (!(params.isVerbose ?? isVerbose)()) return;
|
|
7732
7361
|
const elapsedMs = Math.max(0, Date.now() - params.startAt);
|
|
7733
7362
|
const suffix = [params.details, formatDiscordStartupGatewayState(params.gateway)].filter((value) => Boolean(value)).join(" ");
|
|
@@ -7835,7 +7464,7 @@ async function deployDiscordCommands(params) {
|
|
|
7835
7464
|
}
|
|
7836
7465
|
function runDiscordCommandDeployInBackground(params) {
|
|
7837
7466
|
if (!params.enabled) return;
|
|
7838
|
-
logDiscordStartupPhase
|
|
7467
|
+
logDiscordStartupPhase({
|
|
7839
7468
|
runtime: params.runtime,
|
|
7840
7469
|
accountId: params.accountId,
|
|
7841
7470
|
phase: "deploy-commands:scheduled",
|
|
@@ -7844,7 +7473,7 @@ function runDiscordCommandDeployInBackground(params) {
|
|
|
7844
7473
|
isVerbose: params.isVerbose
|
|
7845
7474
|
});
|
|
7846
7475
|
deployDiscordCommands(params).then(() => {
|
|
7847
|
-
logDiscordStartupPhase
|
|
7476
|
+
logDiscordStartupPhase({
|
|
7848
7477
|
runtime: params.runtime,
|
|
7849
7478
|
accountId: params.accountId,
|
|
7850
7479
|
phase: "deploy-commands:done",
|
|
@@ -7921,7 +7550,7 @@ var DiscordActivityButton = class extends Button {
|
|
|
7921
7550
|
};
|
|
7922
7551
|
function createDiscordActivityButton(ctx, applicationId, deps = {}) {
|
|
7923
7552
|
const runtime = getDiscordActivitiesRuntime();
|
|
7924
|
-
if (!runtime
|
|
7553
|
+
if (!runtime) return null;
|
|
7925
7554
|
if (applicationId) runtime.registerApplicationId(ctx.accountId, applicationId);
|
|
7926
7555
|
if (!runtime.resolveAccount(ctx.accountId, ctx.cfg)) return null;
|
|
7927
7556
|
return new DiscordActivityButton(ctx, {
|
|
@@ -8036,6 +7665,104 @@ async function resolveComponentInteractionContext(params) {
|
|
|
8036
7665
|
};
|
|
8037
7666
|
}
|
|
8038
7667
|
//#endregion
|
|
7668
|
+
//#region extensions/discord/src/monitor/agent-components-data.ts
|
|
7669
|
+
function readParsedComponentId(data) {
|
|
7670
|
+
if (!data || typeof data !== "object") return;
|
|
7671
|
+
return "cid" in data ? data.cid : data.componentId;
|
|
7672
|
+
}
|
|
7673
|
+
function normalizeComponentId(value) {
|
|
7674
|
+
if (typeof value === "string") return normalizeOptionalString(value);
|
|
7675
|
+
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
7676
|
+
}
|
|
7677
|
+
function mapOptionLabels(options, values) {
|
|
7678
|
+
if (!options || options.length === 0) return values;
|
|
7679
|
+
const map = new Map(options.map((option) => [option.value, option.label]));
|
|
7680
|
+
return values.map((value) => map.get(value) ?? value);
|
|
7681
|
+
}
|
|
7682
|
+
function parseAgentComponentData(data) {
|
|
7683
|
+
const raw = readParsedComponentId(data);
|
|
7684
|
+
const componentId = typeof raw === "string" ? decodeCustomIdComponent(raw) : typeof raw === "number" ? String(raw) : null;
|
|
7685
|
+
if (!componentId) return null;
|
|
7686
|
+
return { componentId };
|
|
7687
|
+
}
|
|
7688
|
+
function parseDiscordComponentData(data, customId) {
|
|
7689
|
+
if (!data || typeof data !== "object") return null;
|
|
7690
|
+
const rawComponentId = readParsedComponentId(data);
|
|
7691
|
+
const rawModalId = "mid" in data ? data.mid : data.modalId;
|
|
7692
|
+
let componentId = normalizeComponentId(rawComponentId);
|
|
7693
|
+
let modalId = normalizeComponentId(rawModalId);
|
|
7694
|
+
if (!componentId && customId) {
|
|
7695
|
+
const parsed = parseDiscordComponentCustomId(customId);
|
|
7696
|
+
if (parsed) {
|
|
7697
|
+
componentId = parsed.componentId;
|
|
7698
|
+
modalId = parsed.modalId;
|
|
7699
|
+
}
|
|
7700
|
+
}
|
|
7701
|
+
if (!componentId) return null;
|
|
7702
|
+
return {
|
|
7703
|
+
componentId,
|
|
7704
|
+
modalId
|
|
7705
|
+
};
|
|
7706
|
+
}
|
|
7707
|
+
function parseDiscordModalId(data, customId) {
|
|
7708
|
+
if (data && typeof data === "object") {
|
|
7709
|
+
const modalId = normalizeComponentId("mid" in data ? data.mid : data.modalId);
|
|
7710
|
+
if (modalId) return modalId;
|
|
7711
|
+
}
|
|
7712
|
+
if (customId) return parseDiscordModalCustomId(customId);
|
|
7713
|
+
return null;
|
|
7714
|
+
}
|
|
7715
|
+
function resolveInteractionCustomId(interaction) {
|
|
7716
|
+
if (!interaction?.rawData || typeof interaction.rawData !== "object") return;
|
|
7717
|
+
if (!("data" in interaction.rawData)) return;
|
|
7718
|
+
return normalizeOptionalString(interaction.rawData.data?.custom_id);
|
|
7719
|
+
}
|
|
7720
|
+
function mapSelectValues(entry, values) {
|
|
7721
|
+
switch (entry.selectType) {
|
|
7722
|
+
case "string": return mapOptionLabels(entry.options, values);
|
|
7723
|
+
case "user":
|
|
7724
|
+
case "role":
|
|
7725
|
+
case "mentionable":
|
|
7726
|
+
case "channel": return values.map((value) => `${entry.selectType}:${value}`);
|
|
7727
|
+
default: return values;
|
|
7728
|
+
}
|
|
7729
|
+
}
|
|
7730
|
+
function resolveModalFieldValues(field, interaction) {
|
|
7731
|
+
const fields = interaction.fields;
|
|
7732
|
+
const required = field.required === true;
|
|
7733
|
+
try {
|
|
7734
|
+
switch (field.type) {
|
|
7735
|
+
case "text": {
|
|
7736
|
+
const value = fields.getText(field.id, required);
|
|
7737
|
+
return value ? [value] : [];
|
|
7738
|
+
}
|
|
7739
|
+
case "select":
|
|
7740
|
+
case "checkbox":
|
|
7741
|
+
case "radio": return mapOptionLabels(field.options, fields.getStringSelect(field.id, required));
|
|
7742
|
+
case "role-select": try {
|
|
7743
|
+
return fields.getRoleSelect(field.id, required).map((role) => role.name ?? role.id);
|
|
7744
|
+
} catch {
|
|
7745
|
+
return fields.getStringSelect(field.id, required);
|
|
7746
|
+
}
|
|
7747
|
+
case "user-select": return fields.getUserSelect(field.id, required).map((user) => formatDiscordUserTag(user));
|
|
7748
|
+
default: return [];
|
|
7749
|
+
}
|
|
7750
|
+
} catch (err) {
|
|
7751
|
+
logError(`agent modal: failed to read field ${field.id}: ${String(err)}`);
|
|
7752
|
+
return [];
|
|
7753
|
+
}
|
|
7754
|
+
}
|
|
7755
|
+
function formatModalSubmissionText(entry, interaction) {
|
|
7756
|
+
const lines = [`Form "${entry.title}" submitted.`];
|
|
7757
|
+
for (const field of entry.fields) {
|
|
7758
|
+
const values = resolveModalFieldValues(field, interaction);
|
|
7759
|
+
if (values.length === 0) continue;
|
|
7760
|
+
lines.push(`- ${field.label}: ${values.join(", ")}`);
|
|
7761
|
+
}
|
|
7762
|
+
if (lines.length === 1) lines.push("- (no values)");
|
|
7763
|
+
return lines.join("\n");
|
|
7764
|
+
}
|
|
7765
|
+
//#endregion
|
|
8039
7766
|
//#region extensions/discord/src/monitor/agent-components-live-policy.ts
|
|
8040
7767
|
async function resolveAgentComponentPolicyContext(params) {
|
|
8041
7768
|
if (!params.ctx.readPolicy) return params.ctx;
|
|
@@ -8108,7 +7835,7 @@ async function ensureDmComponentAuthorized(params) {
|
|
|
8108
7835
|
channel: "discord",
|
|
8109
7836
|
accountId: ctx.accountId,
|
|
8110
7837
|
upsertPairingRequest: async ({ id, meta }) => {
|
|
8111
|
-
return await upsertChannelPairingRequest
|
|
7838
|
+
return await upsertChannelPairingRequest({
|
|
8112
7839
|
channel: "discord",
|
|
8113
7840
|
id,
|
|
8114
7841
|
accountId: ctx.accountId,
|
|
@@ -8258,7 +7985,7 @@ async function ensureGuildComponentMemberAllowed(params) {
|
|
|
8258
7985
|
return false;
|
|
8259
7986
|
}
|
|
8260
7987
|
async function ensureComponentUserAllowed(params) {
|
|
8261
|
-
const allowList = normalizeDiscordAllowList(params.
|
|
7988
|
+
const allowList = normalizeDiscordAllowList(params.allowedUsers, [
|
|
8262
7989
|
"discord:",
|
|
8263
7990
|
"user:",
|
|
8264
7991
|
"pk:"
|
|
@@ -8369,6 +8096,13 @@ async function resolveAuthorizedComponentInteraction(params) {
|
|
|
8369
8096
|
});
|
|
8370
8097
|
return null;
|
|
8371
8098
|
}
|
|
8099
|
+
if (params.allowedUsers !== void 0 && !await ensureComponentUserAllowed({
|
|
8100
|
+
...params,
|
|
8101
|
+
allowedUsers: params.allowedUsers,
|
|
8102
|
+
user,
|
|
8103
|
+
replyOpts,
|
|
8104
|
+
allowNameMatching
|
|
8105
|
+
})) return null;
|
|
8372
8106
|
return {
|
|
8373
8107
|
ctx,
|
|
8374
8108
|
interactionCtx,
|
|
@@ -8388,159 +8122,50 @@ async function resolveComponentCommandAuthorized(params) {
|
|
|
8388
8122
|
allowFrom: ctx.allowFrom,
|
|
8389
8123
|
sender: {
|
|
8390
8124
|
id: interactionCtx.user.id,
|
|
8391
|
-
name: interactionCtx.user.username,
|
|
8392
|
-
tag: formatDiscordUserTag(interactionCtx.user)
|
|
8393
|
-
},
|
|
8394
|
-
allowNameMatching: params.allowNameMatching
|
|
8395
|
-
});
|
|
8396
|
-
const { hasAccessRestrictions, memberAllowed } = resolveDiscordMemberAccessState({
|
|
8397
|
-
channelConfig,
|
|
8398
|
-
guildInfo,
|
|
8399
|
-
memberRoleIds: interactionCtx.memberRoleIds,
|
|
8400
|
-
sender: {
|
|
8401
|
-
id: interactionCtx.user.id,
|
|
8402
|
-
name: interactionCtx.user.username,
|
|
8403
|
-
tag: formatDiscordUserTag(interactionCtx.user)
|
|
8404
|
-
},
|
|
8405
|
-
allowNameMatching: params.allowNameMatching
|
|
8406
|
-
});
|
|
8407
|
-
return resolveCommandAuthorizedFromAuthorizers({
|
|
8408
|
-
useAccessGroups: true,
|
|
8409
|
-
authorizers: [{
|
|
8410
|
-
configured: ownerAllowList != null,
|
|
8411
|
-
allowed: ownerOk
|
|
8412
|
-
}, {
|
|
8413
|
-
configured: hasAccessRestrictions,
|
|
8414
|
-
allowed: memberAllowed
|
|
8415
|
-
}],
|
|
8416
|
-
modeWhenAccessGroupsOff: "configured"
|
|
8417
|
-
});
|
|
8418
|
-
}
|
|
8419
|
-
//#endregion
|
|
8420
|
-
//#region extensions/discord/src/monitor/agent-components-data.ts
|
|
8421
|
-
function readParsedComponentId(data) {
|
|
8422
|
-
if (!data || typeof data !== "object") return;
|
|
8423
|
-
return "cid" in data ? data.cid : data.componentId;
|
|
8424
|
-
}
|
|
8425
|
-
function normalizeComponentId(value) {
|
|
8426
|
-
if (typeof value === "string") {
|
|
8427
|
-
const trimmed = value.trim();
|
|
8428
|
-
return trimmed ? trimmed : void 0;
|
|
8429
|
-
}
|
|
8430
|
-
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
8431
|
-
}
|
|
8432
|
-
function mapOptionLabels(options, values) {
|
|
8433
|
-
if (!options || options.length === 0) return values;
|
|
8434
|
-
const map = new Map(options.map((option) => [option.value, option.label]));
|
|
8435
|
-
return values.map((value) => map.get(value) ?? value);
|
|
8436
|
-
}
|
|
8437
|
-
function parseAgentComponentData(data) {
|
|
8438
|
-
const raw = readParsedComponentId(data);
|
|
8439
|
-
const componentId = typeof raw === "string" ? decodeCustomIdComponent(raw) : typeof raw === "number" ? String(raw) : null;
|
|
8440
|
-
if (!componentId) return null;
|
|
8441
|
-
return { componentId };
|
|
8442
|
-
}
|
|
8443
|
-
function parseDiscordComponentData(data, customId) {
|
|
8444
|
-
if (!data || typeof data !== "object") return null;
|
|
8445
|
-
const rawComponentId = readParsedComponentId(data);
|
|
8446
|
-
const rawModalId = "mid" in data ? data.mid : data.modalId;
|
|
8447
|
-
let componentId = normalizeComponentId(rawComponentId);
|
|
8448
|
-
let modalId = normalizeComponentId(rawModalId);
|
|
8449
|
-
if (!componentId && customId) {
|
|
8450
|
-
const parsed = parseDiscordComponentCustomId(customId);
|
|
8451
|
-
if (parsed) {
|
|
8452
|
-
componentId = parsed.componentId;
|
|
8453
|
-
modalId = parsed.modalId;
|
|
8454
|
-
}
|
|
8455
|
-
}
|
|
8456
|
-
if (!componentId) return null;
|
|
8457
|
-
return {
|
|
8458
|
-
componentId,
|
|
8459
|
-
modalId
|
|
8460
|
-
};
|
|
8461
|
-
}
|
|
8462
|
-
function parseDiscordModalId(data, customId) {
|
|
8463
|
-
if (data && typeof data === "object") {
|
|
8464
|
-
const modalId = normalizeComponentId("mid" in data ? data.mid : data.modalId);
|
|
8465
|
-
if (modalId) return modalId;
|
|
8466
|
-
}
|
|
8467
|
-
if (customId) return parseDiscordModalCustomId(customId);
|
|
8468
|
-
return null;
|
|
8469
|
-
}
|
|
8470
|
-
function resolveInteractionCustomId(interaction) {
|
|
8471
|
-
if (!interaction?.rawData || typeof interaction.rawData !== "object") return;
|
|
8472
|
-
if (!("data" in interaction.rawData)) return;
|
|
8473
|
-
const customId = interaction.rawData.data?.custom_id;
|
|
8474
|
-
if (typeof customId !== "string") return;
|
|
8475
|
-
const trimmed = customId.trim();
|
|
8476
|
-
return trimmed ? trimmed : void 0;
|
|
8477
|
-
}
|
|
8478
|
-
function mapSelectValues(entry, values) {
|
|
8479
|
-
if (entry.selectType === "string") return mapOptionLabels(entry.options, values);
|
|
8480
|
-
if (entry.selectType === "user") return values.map((value) => `user:${value}`);
|
|
8481
|
-
if (entry.selectType === "role") return values.map((value) => `role:${value}`);
|
|
8482
|
-
if (entry.selectType === "mentionable") return values.map((value) => `mentionable:${value}`);
|
|
8483
|
-
if (entry.selectType === "channel") return values.map((value) => `channel:${value}`);
|
|
8484
|
-
return values;
|
|
8485
|
-
}
|
|
8486
|
-
function resolveModalFieldValues(field, interaction) {
|
|
8487
|
-
const fields = interaction.fields;
|
|
8488
|
-
const optionLabels = field.options?.map((option) => ({
|
|
8489
|
-
value: option.value,
|
|
8490
|
-
label: option.label
|
|
8491
|
-
}));
|
|
8492
|
-
const required = field.required === true;
|
|
8493
|
-
try {
|
|
8494
|
-
switch (field.type) {
|
|
8495
|
-
case "text": {
|
|
8496
|
-
const value = required ? fields.getText(field.id, true) : fields.getText(field.id);
|
|
8497
|
-
return value ? [value] : [];
|
|
8498
|
-
}
|
|
8499
|
-
case "select":
|
|
8500
|
-
case "checkbox":
|
|
8501
|
-
case "radio": return mapOptionLabels(optionLabels, required ? fields.getStringSelect(field.id, true) : fields.getStringSelect(field.id) ?? []);
|
|
8502
|
-
case "role-select": try {
|
|
8503
|
-
return (required ? fields.getRoleSelect(field.id, true) : fields.getRoleSelect(field.id) ?? []).map((role) => role.name ?? role.id);
|
|
8504
|
-
} catch {
|
|
8505
|
-
return required ? fields.getStringSelect(field.id, true) : fields.getStringSelect(field.id) ?? [];
|
|
8506
|
-
}
|
|
8507
|
-
case "user-select": return (required ? fields.getUserSelect(field.id, true) : fields.getUserSelect(field.id) ?? []).map((user) => formatDiscordUserTag(user));
|
|
8508
|
-
default: return [];
|
|
8509
|
-
}
|
|
8510
|
-
} catch (err) {
|
|
8511
|
-
logError(`agent modal: failed to read field ${field.id}: ${String(err)}`);
|
|
8512
|
-
return [];
|
|
8513
|
-
}
|
|
8514
|
-
}
|
|
8515
|
-
function formatModalSubmissionText(entry, interaction) {
|
|
8516
|
-
const lines = [`Form "${entry.title}" submitted.`];
|
|
8517
|
-
for (const field of entry.fields) {
|
|
8518
|
-
const values = resolveModalFieldValues(field, interaction);
|
|
8519
|
-
if (values.length === 0) continue;
|
|
8520
|
-
lines.push(`- ${field.label}: ${values.join(", ")}`);
|
|
8521
|
-
}
|
|
8522
|
-
if (lines.length === 1) lines.push("- (no values)");
|
|
8523
|
-
return lines.join("\n");
|
|
8125
|
+
name: interactionCtx.user.username,
|
|
8126
|
+
tag: formatDiscordUserTag(interactionCtx.user)
|
|
8127
|
+
},
|
|
8128
|
+
allowNameMatching: params.allowNameMatching
|
|
8129
|
+
});
|
|
8130
|
+
const { hasAccessRestrictions, memberAllowed } = resolveDiscordMemberAccessState({
|
|
8131
|
+
channelConfig,
|
|
8132
|
+
guildInfo,
|
|
8133
|
+
memberRoleIds: interactionCtx.memberRoleIds,
|
|
8134
|
+
sender: {
|
|
8135
|
+
id: interactionCtx.user.id,
|
|
8136
|
+
name: interactionCtx.user.username,
|
|
8137
|
+
tag: formatDiscordUserTag(interactionCtx.user)
|
|
8138
|
+
},
|
|
8139
|
+
allowNameMatching: params.allowNameMatching
|
|
8140
|
+
});
|
|
8141
|
+
return resolveCommandAuthorizedFromAuthorizers({
|
|
8142
|
+
useAccessGroups: true,
|
|
8143
|
+
authorizers: [{
|
|
8144
|
+
configured: ownerAllowList != null,
|
|
8145
|
+
allowed: ownerOk
|
|
8146
|
+
}, {
|
|
8147
|
+
configured: hasAccessRestrictions,
|
|
8148
|
+
allowed: memberAllowed
|
|
8149
|
+
}],
|
|
8150
|
+
modeWhenAccessGroupsOff: "configured"
|
|
8151
|
+
});
|
|
8524
8152
|
}
|
|
8525
8153
|
//#endregion
|
|
8526
|
-
//#region extensions/discord/src/monitor/agent-components-helpers.ts
|
|
8527
|
-
const AGENT_BUTTON_KEY = "agent";
|
|
8528
|
-
const AGENT_SELECT_KEY = "agentsel";
|
|
8529
|
-
//#endregion
|
|
8530
8154
|
//#region extensions/discord/src/monitor/reply-context.ts
|
|
8531
8155
|
function resolveReplyContext(message, resolveDiscordMessageText) {
|
|
8532
|
-
const
|
|
8533
|
-
if (!
|
|
8156
|
+
const id = resolveDiscordReferencedReplyMessageId(message);
|
|
8157
|
+
if (!id) return null;
|
|
8158
|
+
const referenced = resolveDiscordReferencedReplyMessage(message);
|
|
8159
|
+
const channelId = message.messageReference?.channel_id ?? message.channelId;
|
|
8160
|
+
if (!referenced?.author || referenced.id !== id) return null;
|
|
8534
8161
|
const referencedText = resolveDiscordMessageText(referenced, { includeForwarded: true });
|
|
8535
|
-
const hasVisibleMedia = referenced.attachments.length > 0 || !referencedText && resolveDiscordMessageStickers(referenced).length > 0;
|
|
8536
|
-
if (!referencedText && !hasVisibleMedia) return null;
|
|
8537
8162
|
const sender = resolveDiscordSenderIdentity({
|
|
8538
8163
|
author: referenced.author,
|
|
8539
8164
|
pluralkitInfo: null
|
|
8540
8165
|
});
|
|
8541
8166
|
return {
|
|
8542
|
-
id
|
|
8543
|
-
channelId
|
|
8167
|
+
id,
|
|
8168
|
+
channelId,
|
|
8544
8169
|
sender: sender.tag ?? sender.label ?? "unknown",
|
|
8545
8170
|
senderId: referenced.author.id,
|
|
8546
8171
|
senderName: referenced.author.username ?? void 0,
|
|
@@ -8624,14 +8249,10 @@ function formatDiscordReplySkip(params) {
|
|
|
8624
8249
|
const context = [`target=${params.target}`, params.sessionKey ? `session=${params.sessionKey}` : void 0].filter(Boolean).join(" ");
|
|
8625
8250
|
return `discord ${params.kind} reply skipped (${params.reason}): ${context}`;
|
|
8626
8251
|
}
|
|
8627
|
-
function resolveTargetChannelId(target) {
|
|
8628
|
-
if (!target.startsWith("channel:")) return;
|
|
8629
|
-
return target.slice(8).trim() || void 0;
|
|
8630
|
-
}
|
|
8631
8252
|
function resolveBoundThreadBinding(params) {
|
|
8632
8253
|
const sessionKey = params.sessionKey?.trim();
|
|
8633
8254
|
if (!params.threadBindings || !sessionKey) return;
|
|
8634
|
-
const targetChannelId =
|
|
8255
|
+
const targetChannelId = params.target.startsWith("channel:") ? params.target.slice(8).trim() : void 0;
|
|
8635
8256
|
if (!targetChannelId) return;
|
|
8636
8257
|
return params.threadBindings.listBySessionKey(sessionKey).find((entry) => entry.threadId === targetChannelId);
|
|
8637
8258
|
}
|
|
@@ -8662,27 +8283,6 @@ function createDiscordDeliveryDeps(params) {
|
|
|
8662
8283
|
})
|
|
8663
8284
|
};
|
|
8664
8285
|
}
|
|
8665
|
-
function resolveDiscordDeliveryOptions(params) {
|
|
8666
|
-
const binding = resolveBoundThreadBinding({
|
|
8667
|
-
threadBindings: params.threadBindings,
|
|
8668
|
-
sessionKey: params.sessionKey,
|
|
8669
|
-
target: params.target
|
|
8670
|
-
});
|
|
8671
|
-
return {
|
|
8672
|
-
to: binding ? `channel:${binding.channelId}` : params.target,
|
|
8673
|
-
threadId: binding?.threadId,
|
|
8674
|
-
agentId: binding?.agentId,
|
|
8675
|
-
identity: resolveBindingIdentity(params.cfg, binding),
|
|
8676
|
-
mediaAccess: params.mediaLocalRoots?.length ? { localRoots: params.mediaLocalRoots } : void 0,
|
|
8677
|
-
replyToMode: params.replyToMode ?? "all",
|
|
8678
|
-
formatting: {
|
|
8679
|
-
textLimit: params.textLimit,
|
|
8680
|
-
maxLinesPerMessage: params.maxLinesPerMessage,
|
|
8681
|
-
tableMode: params.tableMode,
|
|
8682
|
-
chunkMode: params.chunkMode
|
|
8683
|
-
}
|
|
8684
|
-
};
|
|
8685
|
-
}
|
|
8686
8286
|
function formatDiscordReasoningPayload(payload) {
|
|
8687
8287
|
if (payload.isReasoning !== true) return payload;
|
|
8688
8288
|
const text = typeof payload.text === "string" ? payload.text.trim() : "";
|
|
@@ -8694,8 +8294,8 @@ function formatDiscordReasoningPayload(payload) {
|
|
|
8694
8294
|
return nextPayload;
|
|
8695
8295
|
}
|
|
8696
8296
|
async function deliverDiscordReply(params) {
|
|
8697
|
-
params
|
|
8698
|
-
const
|
|
8297
|
+
const binding = resolveBoundThreadBinding(params);
|
|
8298
|
+
const to = binding ? `channel:${binding.channelId}` : params.target;
|
|
8699
8299
|
const payloads = sanitizeDiscordFrontChannelReplyPayloads(params.replies, { kind: params.kind }).map(formatDiscordReasoningPayload).map((payload) => params.bindPendingFinalDelivery?.(payload) ?? payload);
|
|
8700
8300
|
if (payloads.length === 0) return {
|
|
8701
8301
|
visibleReplySent: false,
|
|
@@ -8704,14 +8304,19 @@ async function deliverDiscordReply(params) {
|
|
|
8704
8304
|
const send = await sendDurableMessageBatch({
|
|
8705
8305
|
cfg: params.cfg,
|
|
8706
8306
|
channel: "discord",
|
|
8707
|
-
to
|
|
8307
|
+
to,
|
|
8708
8308
|
accountId: params.accountId,
|
|
8709
8309
|
payloads,
|
|
8710
8310
|
replyToId: normalizeOptionalString(params.replyToId),
|
|
8711
|
-
replyToMode:
|
|
8712
|
-
formatting:
|
|
8713
|
-
|
|
8714
|
-
|
|
8311
|
+
replyToMode: params.replyToMode ?? "all",
|
|
8312
|
+
formatting: {
|
|
8313
|
+
textLimit: params.textLimit,
|
|
8314
|
+
maxLinesPerMessage: params.maxLinesPerMessage,
|
|
8315
|
+
tableMode: params.tableMode,
|
|
8316
|
+
chunkMode: params.chunkMode
|
|
8317
|
+
},
|
|
8318
|
+
threadId: binding?.threadId,
|
|
8319
|
+
identity: resolveBindingIdentity(params.cfg, binding),
|
|
8715
8320
|
onPlatformSendDispatch: params.onPlatformSendDispatch,
|
|
8716
8321
|
assertDirectAdapterHandoff: params.assertPlatformSendAuthorized,
|
|
8717
8322
|
deps: createDiscordDeliveryDeps({
|
|
@@ -8720,11 +8325,11 @@ async function deliverDiscordReply(params) {
|
|
|
8720
8325
|
rest: params.rest,
|
|
8721
8326
|
allowedMentions: params.allowedMentions
|
|
8722
8327
|
}),
|
|
8723
|
-
mediaAccess:
|
|
8328
|
+
mediaAccess: params.mediaLocalRoots?.length ? { localRoots: params.mediaLocalRoots } : void 0,
|
|
8724
8329
|
session: buildOutboundSessionContext({
|
|
8725
8330
|
cfg: params.cfg,
|
|
8726
8331
|
sessionKey: params.sessionKey,
|
|
8727
|
-
agentId:
|
|
8332
|
+
agentId: binding?.agentId,
|
|
8728
8333
|
requesterAccountId: params.accountId
|
|
8729
8334
|
})
|
|
8730
8335
|
});
|
|
@@ -8740,7 +8345,7 @@ async function deliverDiscordReply(params) {
|
|
|
8740
8345
|
}
|
|
8741
8346
|
};
|
|
8742
8347
|
}
|
|
8743
|
-
if (send.results.length === 0) throw new Error(`discord final reply produced no delivered message for ${
|
|
8348
|
+
if (send.results.length === 0) throw new Error(`discord final reply produced no delivered message for ${to}`);
|
|
8744
8349
|
const deliveryResult = {
|
|
8745
8350
|
messageIds: listMessageReceiptPlatformIds(send.receipt),
|
|
8746
8351
|
receipt: send.receipt,
|
|
@@ -8751,8 +8356,8 @@ async function deliverDiscordReply(params) {
|
|
|
8751
8356
|
}
|
|
8752
8357
|
//#endregion
|
|
8753
8358
|
//#region extensions/discord/src/monitor/agent-components.dispatch.ts
|
|
8754
|
-
const
|
|
8755
|
-
const loadTypingRuntime = createLazyRuntimeModule(() => import("./typing-
|
|
8359
|
+
const loadReplyRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/reply-runtime"));
|
|
8360
|
+
const loadTypingRuntime = createLazyRuntimeModule(() => import("./typing-BiHCzBRu.mjs").then((n) => n.n));
|
|
8756
8361
|
function buildDiscordComponentConversationLabel(params) {
|
|
8757
8362
|
if (params.interactionCtx.isDirectMessage) return buildDirectLabel(params.interactionCtx.user);
|
|
8758
8363
|
if (params.interactionCtx.isGroupDm) return `Group DM #${params.channelCtx.channelName ?? params.interactionCtx.channelId} channel id:${params.interactionCtx.channelId}`;
|
|
@@ -8767,16 +8372,8 @@ function resolveDiscordComponentChatType(interactionCtx) {
|
|
|
8767
8372
|
if (interactionCtx.isGroupDm) return "group";
|
|
8768
8373
|
return "channel";
|
|
8769
8374
|
}
|
|
8770
|
-
function resolveDiscordComponentOriginatingTo(interactionCtx) {
|
|
8771
|
-
return resolveDiscordConversationIdentity({
|
|
8772
|
-
isDirectMessage: interactionCtx.isDirectMessage,
|
|
8773
|
-
userId: interactionCtx.userId,
|
|
8774
|
-
channelId: interactionCtx.channelId
|
|
8775
|
-
});
|
|
8776
|
-
}
|
|
8777
8375
|
async function dispatchDiscordComponentEvent(params) {
|
|
8778
8376
|
const { ctx, interaction, interactionCtx, channelCtx, guildInfo, eventText } = params;
|
|
8779
|
-
const runtime = ctx.runtime ?? createNonExitingRuntime();
|
|
8780
8377
|
const route = resolveAgentComponentRoute({
|
|
8781
8378
|
ctx,
|
|
8782
8379
|
rawGuildId: interactionCtx.rawGuildId,
|
|
@@ -8790,7 +8387,6 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
8790
8387
|
const sessionKey = params.routeOverrides?.sessionKey ?? route.sessionKey;
|
|
8791
8388
|
const agentId = params.routeOverrides?.agentId ?? route.agentId;
|
|
8792
8389
|
const accountId = params.routeOverrides?.accountId ?? route.accountId;
|
|
8793
|
-
const inboundLastRouteSessionKey = sessionKey;
|
|
8794
8390
|
const fromLabel = buildDiscordComponentConversationLabel({
|
|
8795
8391
|
interactionCtx,
|
|
8796
8392
|
interaction,
|
|
@@ -8825,7 +8421,7 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
8825
8421
|
isGuild: !interactionCtx.isDirectMessage
|
|
8826
8422
|
});
|
|
8827
8423
|
const groupSystemPrompt = buildDiscordGroupSystemPrompt(channelConfig);
|
|
8828
|
-
const pinnedMainDmOwner = interactionCtx.isDirectMessage ? resolvePinnedMainDmOwnerFromAllowlist
|
|
8424
|
+
const pinnedMainDmOwner = interactionCtx.isDirectMessage ? resolvePinnedMainDmOwnerFromAllowlist({
|
|
8829
8425
|
dmScope: ctx.cfg.session?.dmScope,
|
|
8830
8426
|
allowFrom: channelConfig?.users ?? guildInfo?.users,
|
|
8831
8427
|
normalizeEntry: (entry) => {
|
|
@@ -8844,12 +8440,17 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
8844
8440
|
guildInfo,
|
|
8845
8441
|
allowNameMatching
|
|
8846
8442
|
});
|
|
8847
|
-
const storePath = resolveStorePath
|
|
8443
|
+
const storePath = resolveStorePath(ctx.cfg.session?.store, { agentId });
|
|
8848
8444
|
const envelopeOptions = resolveEnvelopeFormatOptions(ctx.cfg);
|
|
8849
|
-
const previousTimestamp = readSessionUpdatedAt
|
|
8445
|
+
const previousTimestamp = readSessionUpdatedAt({
|
|
8850
8446
|
storePath,
|
|
8851
8447
|
sessionKey
|
|
8852
8448
|
});
|
|
8449
|
+
const originatingTo = resolveDiscordConversationIdentity({
|
|
8450
|
+
isDirectMessage: interactionCtx.isDirectMessage,
|
|
8451
|
+
userId: interactionCtx.userId,
|
|
8452
|
+
channelId: interactionCtx.channelId
|
|
8453
|
+
});
|
|
8853
8454
|
const timestamp = Date.now();
|
|
8854
8455
|
const combinedBody = formatInboundEnvelope({
|
|
8855
8456
|
channel: "Discord",
|
|
@@ -8861,9 +8462,7 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
8861
8462
|
previousTimestamp,
|
|
8862
8463
|
envelope: envelopeOptions
|
|
8863
8464
|
});
|
|
8864
|
-
const { createReplyReferencePlanner, finalizeInboundContext, resolveChunkMode, resolveTextChunkLimit } = await (
|
|
8865
|
-
return { ...await loadConversationRuntime$1() };
|
|
8866
|
-
})();
|
|
8465
|
+
const { createReplyReferencePlanner, finalizeInboundContext, resolveChunkMode, resolveTextChunkLimit } = await loadReplyRuntime();
|
|
8867
8466
|
const ctxPayload = finalizeInboundContext({
|
|
8868
8467
|
Body: combinedBody,
|
|
8869
8468
|
BodyForAgent: eventText,
|
|
@@ -8905,7 +8504,7 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
8905
8504
|
MessageSid: interaction.rawData.id,
|
|
8906
8505
|
Timestamp: timestamp,
|
|
8907
8506
|
OriginatingChannel: "discord",
|
|
8908
|
-
OriginatingTo:
|
|
8507
|
+
OriginatingTo: originatingTo ?? `channel:${interactionCtx.channelId}`
|
|
8909
8508
|
});
|
|
8910
8509
|
const deliverTarget = `channel:${interactionCtx.channelId}`;
|
|
8911
8510
|
const typingChannelId = interactionCtx.channelId;
|
|
@@ -8951,11 +8550,11 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
8951
8550
|
dispatchReplyFromConfig: ctx.channelRuntime?.reply?.dispatchReplyFromConfig,
|
|
8952
8551
|
record: {
|
|
8953
8552
|
updateLastRoute: interactionCtx.isDirectMessage ? {
|
|
8954
|
-
sessionKey
|
|
8553
|
+
sessionKey,
|
|
8955
8554
|
channel: "discord",
|
|
8956
|
-
to:
|
|
8555
|
+
to: originatingTo ?? `user:${interactionCtx.userId}`,
|
|
8957
8556
|
accountId,
|
|
8958
|
-
mainDmOwnerPin:
|
|
8557
|
+
mainDmOwnerPin: sessionKey === route.mainSessionKey && pinnedMainDmOwner ? {
|
|
8959
8558
|
ownerRecipient: pinnedMainDmOwner,
|
|
8960
8559
|
senderRecipient: interactionCtx.userId,
|
|
8961
8560
|
onSkip: ({ ownerRecipient, senderRecipient }) => {
|
|
@@ -8977,7 +8576,6 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
8977
8576
|
token,
|
|
8978
8577
|
accountId,
|
|
8979
8578
|
rest: interaction.client.rest,
|
|
8980
|
-
runtime,
|
|
8981
8579
|
replyToId,
|
|
8982
8580
|
replyToMode,
|
|
8983
8581
|
textLimit,
|
|
@@ -9034,7 +8632,7 @@ async function dispatchDiscordPluginInteractiveHandler(params) {
|
|
|
9034
8632
|
}
|
|
9035
8633
|
//#endregion
|
|
9036
8634
|
//#region extensions/discord/src/monitor/agent-components.plugin-interactive.ts
|
|
9037
|
-
const loadConversationRuntime = createLazyRuntimeModule(() => import("
|
|
8635
|
+
const loadConversationRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/conversation-runtime"));
|
|
9038
8636
|
async function dispatchPluginDiscordInteractiveEvent(params) {
|
|
9039
8637
|
const normalizedConversationId = params.interactionCtx.rawGuildId || params.channelCtx.channelType === ChannelType.GroupDM ? `channel:${params.interactionCtx.channelId}` : `user:${params.interactionCtx.userId}`;
|
|
9040
8638
|
let responded = false;
|
|
@@ -9089,13 +8687,16 @@ async function dispatchPluginDiscordInteractiveEvent(params) {
|
|
|
9089
8687
|
});
|
|
9090
8688
|
}
|
|
9091
8689
|
};
|
|
8690
|
+
const acknowledgeSilently = async () => {
|
|
8691
|
+
try {
|
|
8692
|
+
await respond.acknowledge();
|
|
8693
|
+
} catch {}
|
|
8694
|
+
};
|
|
9092
8695
|
const conversationRuntime = await loadConversationRuntime();
|
|
9093
8696
|
const pluginBindingApproval = conversationRuntime.parsePluginBindingApprovalCustomId(params.data);
|
|
9094
8697
|
if (pluginBindingApproval) {
|
|
9095
8698
|
const { buildPluginBindingResolvedText, resolvePluginConversationBindingApproval } = conversationRuntime;
|
|
9096
|
-
|
|
9097
|
-
await respond.acknowledge();
|
|
9098
|
-
} catch {}
|
|
8699
|
+
await acknowledgeSilently();
|
|
9099
8700
|
const resolved = await resolvePluginConversationBindingApproval({
|
|
9100
8701
|
approvalId: pluginBindingApproval.approvalId,
|
|
9101
8702
|
decision: pluginBindingApproval.decision,
|
|
@@ -9140,24 +8741,18 @@ async function dispatchPluginDiscordInteractiveEvent(params) {
|
|
|
9140
8741
|
}
|
|
9141
8742
|
},
|
|
9142
8743
|
respond,
|
|
9143
|
-
onMatched:
|
|
9144
|
-
try {
|
|
9145
|
-
await respond.acknowledge();
|
|
9146
|
-
} catch {}
|
|
9147
|
-
}
|
|
8744
|
+
onMatched: acknowledgeSilently
|
|
9148
8745
|
});
|
|
9149
8746
|
if (!dispatched.matched) return "unmatched";
|
|
9150
8747
|
if (dispatched.handled) {
|
|
9151
|
-
if (!responded)
|
|
9152
|
-
await respond.acknowledge();
|
|
9153
|
-
} catch {}
|
|
8748
|
+
if (!responded) await acknowledgeSilently();
|
|
9154
8749
|
return "handled";
|
|
9155
8750
|
}
|
|
9156
8751
|
return "unmatched";
|
|
9157
8752
|
}
|
|
9158
8753
|
//#endregion
|
|
9159
8754
|
//#region extensions/discord/src/monitor/agent-components.handlers.ts
|
|
9160
|
-
const loadComponentsRuntime = createLazyRuntimeModule(() => import("./components-
|
|
8755
|
+
const loadComponentsRuntime = createLazyRuntimeModule(() => import("./components-Cq1PvIpN.mjs").then((n) => n.t));
|
|
9161
8756
|
async function handleDiscordComponentEvent(params) {
|
|
9162
8757
|
const parsed = parseDiscordComponentData(params.data, resolveInteractionCustomId(params.interaction));
|
|
9163
8758
|
if (!parsed) {
|
|
@@ -9180,19 +8775,11 @@ async function handleDiscordComponentEvent(params) {
|
|
|
9180
8775
|
label: params.label,
|
|
9181
8776
|
componentLabel: params.componentLabel,
|
|
9182
8777
|
unauthorizedReply,
|
|
8778
|
+
allowedUsers: entry.allowedUsers,
|
|
9183
8779
|
defer: false
|
|
9184
8780
|
});
|
|
9185
8781
|
if (!authorized) return;
|
|
9186
|
-
const { ctx, interactionCtx, channelCtx, guildInfo,
|
|
9187
|
-
if (!await ensureComponentUserAllowed({
|
|
9188
|
-
entry,
|
|
9189
|
-
interaction: params.interaction,
|
|
9190
|
-
user,
|
|
9191
|
-
replyOpts,
|
|
9192
|
-
componentLabel: params.componentLabel,
|
|
9193
|
-
unauthorizedReply,
|
|
9194
|
-
allowNameMatching
|
|
9195
|
-
})) return;
|
|
8782
|
+
const { ctx, interactionCtx, channelCtx, guildInfo, commandAuthorized, replyOpts } = authorized;
|
|
9196
8783
|
const consumed = await resolveDiscordComponentEntryWithPersistence({
|
|
9197
8784
|
id: parsed.componentId,
|
|
9198
8785
|
consume: !entry.reusable
|
|
@@ -9228,14 +8815,11 @@ async function handleDiscordComponentEvent(params) {
|
|
|
9228
8815
|
label: consumed.label,
|
|
9229
8816
|
values
|
|
9230
8817
|
});
|
|
9231
|
-
|
|
9232
|
-
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
|
|
9236
|
-
} catch (err) {
|
|
9237
|
-
logError(`${params.label}: failed to acknowledge interaction: ${String(err)}`);
|
|
9238
|
-
}
|
|
8818
|
+
await ackComponentInteraction({
|
|
8819
|
+
interaction: params.interaction,
|
|
8820
|
+
replyOpts,
|
|
8821
|
+
label: params.label
|
|
8822
|
+
});
|
|
9239
8823
|
await dispatchDiscordComponentEvent({
|
|
9240
8824
|
ctx,
|
|
9241
8825
|
interaction: params.interaction,
|
|
@@ -9272,25 +8856,14 @@ async function handleDiscordModalTrigger(params) {
|
|
|
9272
8856
|
await replyUnavailableComponentInteraction(params.interaction, "This form is no longer available.");
|
|
9273
8857
|
return;
|
|
9274
8858
|
}
|
|
9275
|
-
|
|
9276
|
-
const authorized = await resolveAuthorizedComponentInteraction({
|
|
8859
|
+
if (!await resolveAuthorizedComponentInteraction({
|
|
9277
8860
|
ctx: params.ctx,
|
|
9278
8861
|
interaction: params.interaction,
|
|
9279
8862
|
label: params.label,
|
|
9280
8863
|
componentLabel: "form",
|
|
9281
|
-
unauthorizedReply,
|
|
8864
|
+
unauthorizedReply: "You are not authorized to use this form.",
|
|
8865
|
+
allowedUsers: entry.allowedUsers,
|
|
9282
8866
|
defer: false
|
|
9283
|
-
});
|
|
9284
|
-
if (!authorized) return;
|
|
9285
|
-
const { user, replyOpts, allowNameMatching } = authorized;
|
|
9286
|
-
if (!await ensureComponentUserAllowed({
|
|
9287
|
-
entry,
|
|
9288
|
-
interaction: params.interaction,
|
|
9289
|
-
user,
|
|
9290
|
-
replyOpts,
|
|
9291
|
-
componentLabel: "form",
|
|
9292
|
-
unauthorizedReply,
|
|
9293
|
-
allowNameMatching
|
|
9294
8867
|
})) return;
|
|
9295
8868
|
const consumed = await resolveDiscordComponentEntryWithPersistence({
|
|
9296
8869
|
id: parsed.componentId,
|
|
@@ -9325,11 +8898,11 @@ const discordComponentControlHandlers = {
|
|
|
9325
8898
|
var DiscordComponentModal = class extends Modal {
|
|
9326
8899
|
constructor(ctx) {
|
|
9327
8900
|
super();
|
|
8901
|
+
this.ctx = ctx;
|
|
9328
8902
|
this.title = "OpenClaw form";
|
|
9329
8903
|
this.customId = "__openclaw_discord_component_modal_wildcard__";
|
|
9330
8904
|
this.components = [];
|
|
9331
8905
|
this.customIdParser = parseDiscordModalCustomIdForInteraction;
|
|
9332
|
-
this.ctx = ctx;
|
|
9333
8906
|
}
|
|
9334
8907
|
async run(interaction, data) {
|
|
9335
8908
|
const modalId = parseDiscordModalId(data, resolveInteractionCustomId(interaction));
|
|
@@ -9346,32 +8919,18 @@ var DiscordComponentModal = class extends Modal {
|
|
|
9346
8919
|
await replyUnavailableComponentInteraction(interaction, "This form has expired.");
|
|
9347
8920
|
return;
|
|
9348
8921
|
}
|
|
9349
|
-
const unauthorizedReply = "You are not authorized to use this form.";
|
|
9350
8922
|
const authorized = await resolveAuthorizedComponentInteraction({
|
|
9351
8923
|
ctx: this.ctx,
|
|
9352
8924
|
interaction,
|
|
9353
8925
|
label: "discord component modal",
|
|
9354
8926
|
componentLabel: "form",
|
|
9355
|
-
unauthorizedReply,
|
|
8927
|
+
unauthorizedReply: "You are not authorized to use this form.",
|
|
8928
|
+
allowedUsers: modalEntry.allowedUsers,
|
|
9356
8929
|
defer: false
|
|
9357
8930
|
});
|
|
9358
8931
|
if (!authorized) return;
|
|
9359
8932
|
const ctx = authorized.ctx;
|
|
9360
|
-
const { interactionCtx, channelCtx, guildInfo,
|
|
9361
|
-
if (!await ensureComponentUserAllowed({
|
|
9362
|
-
entry: {
|
|
9363
|
-
id: modalEntry.id,
|
|
9364
|
-
kind: "button",
|
|
9365
|
-
label: modalEntry.title,
|
|
9366
|
-
allowedUsers: modalEntry.allowedUsers
|
|
9367
|
-
},
|
|
9368
|
-
interaction,
|
|
9369
|
-
user,
|
|
9370
|
-
replyOpts,
|
|
9371
|
-
componentLabel: "form",
|
|
9372
|
-
unauthorizedReply,
|
|
9373
|
-
allowNameMatching
|
|
9374
|
-
})) return;
|
|
8933
|
+
const { interactionCtx, channelCtx, guildInfo, commandAuthorized } = authorized;
|
|
9375
8934
|
const consumed = await resolveDiscordModalEntryWithPersistence({
|
|
9376
8935
|
id: modalId,
|
|
9377
8936
|
consume: !modalEntry.reusable
|
|
@@ -9421,6 +8980,8 @@ var DiscordComponentModal = class extends Modal {
|
|
|
9421
8980
|
};
|
|
9422
8981
|
//#endregion
|
|
9423
8982
|
//#region extensions/discord/src/monitor/agent-components.system-controls.ts
|
|
8983
|
+
const AGENT_BUTTON_KEY = "agent";
|
|
8984
|
+
const AGENT_SELECT_KEY = "agentsel";
|
|
9424
8985
|
async function runAgentSystemControlInteraction(params) {
|
|
9425
8986
|
const parsed = parseAgentComponentData(params.data);
|
|
9426
8987
|
if (!parsed) {
|
|
@@ -9468,7 +9029,7 @@ async function runAgentSystemControlInteraction(params) {
|
|
|
9468
9029
|
userId
|
|
9469
9030
|
});
|
|
9470
9031
|
logDebug(`${params.label}: enqueuing event for channel ${channelId}: ${eventText}`);
|
|
9471
|
-
enqueueRoutedSystemEvent
|
|
9032
|
+
enqueueRoutedSystemEvent(eventText, route, { contextKey: `${params.contextKeyPrefix}:${channelId}:${componentId}:${userId}:${params.interaction.id}` });
|
|
9472
9033
|
await ackComponentInteraction({
|
|
9473
9034
|
interaction: params.interaction,
|
|
9474
9035
|
replyOpts,
|
|
@@ -9478,10 +9039,10 @@ async function runAgentSystemControlInteraction(params) {
|
|
|
9478
9039
|
var AgentComponentButton = class extends Button {
|
|
9479
9040
|
constructor(ctx) {
|
|
9480
9041
|
super();
|
|
9042
|
+
this.ctx = ctx;
|
|
9481
9043
|
this.label = AGENT_BUTTON_KEY;
|
|
9482
9044
|
this.customId = `${AGENT_BUTTON_KEY}:seed=1`;
|
|
9483
9045
|
this.style = ButtonStyle.Primary;
|
|
9484
|
-
this.ctx = ctx;
|
|
9485
9046
|
}
|
|
9486
9047
|
async run(interaction, data) {
|
|
9487
9048
|
await runAgentSystemControlInteraction({
|
|
@@ -9501,9 +9062,9 @@ var AgentComponentButton = class extends Button {
|
|
|
9501
9062
|
var AgentSelectMenu = class extends StringSelectMenu {
|
|
9502
9063
|
constructor(ctx) {
|
|
9503
9064
|
super();
|
|
9065
|
+
this.ctx = ctx;
|
|
9504
9066
|
this.customId = `${AGENT_SELECT_KEY}:seed=1`;
|
|
9505
9067
|
this.options = [];
|
|
9506
|
-
this.ctx = ctx;
|
|
9507
9068
|
}
|
|
9508
9069
|
async run(interaction, data) {
|
|
9509
9070
|
const values = interaction.values ?? [];
|
|
@@ -9622,11 +9183,8 @@ var DiscordComponentButton = class extends Button {
|
|
|
9622
9183
|
});
|
|
9623
9184
|
}
|
|
9624
9185
|
};
|
|
9625
|
-
function createSelectControl(spec, ctx, handlers) {
|
|
9626
|
-
return new DiscordComponentSelectControl(spec, ctx, handlers);
|
|
9627
|
-
}
|
|
9628
9186
|
function bindSelectControl(spec) {
|
|
9629
|
-
return (ctx, handlers) =>
|
|
9187
|
+
return (ctx, handlers) => new DiscordComponentSelectControl(spec, ctx, handlers);
|
|
9630
9188
|
}
|
|
9631
9189
|
function createDiscordComponentButtonControl(ctx, handlers) {
|
|
9632
9190
|
return new DiscordComponentButton(ctx, handlers);
|
|
@@ -9638,24 +9196,15 @@ const createDiscordComponentMentionableSelectControl = bindSelectControl(SELECT_
|
|
|
9638
9196
|
const createDiscordComponentChannelSelectControl = bindSelectControl(SELECT_CONTROLS.channel);
|
|
9639
9197
|
//#endregion
|
|
9640
9198
|
//#region extensions/discord/src/monitor/agent-components.ts
|
|
9641
|
-
function bindDiscordComponentControl(createControl) {
|
|
9642
|
-
return (ctx) => createControl(ctx, discordComponentControlHandlers);
|
|
9643
|
-
}
|
|
9644
|
-
const createDiscordComponentButton = bindDiscordComponentControl(createDiscordComponentButtonControl);
|
|
9645
|
-
const createDiscordComponentStringSelect = bindDiscordComponentControl(createDiscordComponentStringSelectControl);
|
|
9646
|
-
const createDiscordComponentUserSelect = bindDiscordComponentControl(createDiscordComponentUserSelectControl);
|
|
9647
|
-
const createDiscordComponentRoleSelect = bindDiscordComponentControl(createDiscordComponentRoleSelectControl);
|
|
9648
|
-
const createDiscordComponentMentionableSelect = bindDiscordComponentControl(createDiscordComponentMentionableSelectControl);
|
|
9649
|
-
const createDiscordComponentChannelSelect = bindDiscordComponentControl(createDiscordComponentChannelSelectControl);
|
|
9650
9199
|
const createAgentComponentControls = [createAgentComponentButton, createAgentSelectMenu];
|
|
9651
9200
|
const createDiscordComponentControls = [
|
|
9652
|
-
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
];
|
|
9201
|
+
createDiscordComponentButtonControl,
|
|
9202
|
+
createDiscordComponentStringSelectControl,
|
|
9203
|
+
createDiscordComponentUserSelectControl,
|
|
9204
|
+
createDiscordComponentRoleSelectControl,
|
|
9205
|
+
createDiscordComponentMentionableSelectControl,
|
|
9206
|
+
createDiscordComponentChannelSelectControl
|
|
9207
|
+
].map((createControl) => (ctx) => createControl(ctx, discordComponentControlHandlers));
|
|
9659
9208
|
function createDiscordComponentModal(ctx) {
|
|
9660
9209
|
return new DiscordComponentModal(ctx);
|
|
9661
9210
|
}
|
|
@@ -9700,23 +9249,19 @@ var ExecApprovalButton = class extends Button {
|
|
|
9700
9249
|
async run(interaction, data) {
|
|
9701
9250
|
const parsed = parseExecApprovalData(data);
|
|
9702
9251
|
if (!parsed) {
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
});
|
|
9708
|
-
} catch {}
|
|
9252
|
+
await replySilently(interaction, {
|
|
9253
|
+
content: "This approval is no longer valid.",
|
|
9254
|
+
ephemeral: true
|
|
9255
|
+
});
|
|
9709
9256
|
return;
|
|
9710
9257
|
}
|
|
9711
9258
|
const approvers = this.ctx.getApprovers();
|
|
9712
9259
|
const userId = interaction.userId;
|
|
9713
9260
|
if (!approvers.some((id) => id === userId)) {
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
});
|
|
9719
|
-
} catch {}
|
|
9261
|
+
await replySilently(interaction, {
|
|
9262
|
+
content: "⛔ You are not authorized to approve requests.",
|
|
9263
|
+
ephemeral: true
|
|
9264
|
+
});
|
|
9720
9265
|
return;
|
|
9721
9266
|
}
|
|
9722
9267
|
const decisionLabel = parsed.action === "allow-once" ? "Allowed (once)" : parsed.action === "allow-always" ? "Allowed (always)" : "Denied";
|
|
@@ -9854,6 +9399,16 @@ function createDiscordQuestionButton(params) {
|
|
|
9854
9399
|
//#region extensions/discord/src/monitor/provider.interactions.ts
|
|
9855
9400
|
function createDiscordProviderInteractionSurface(params) {
|
|
9856
9401
|
const createNativeCommand = params.createNativeCommand ?? createDiscordNativeCommand;
|
|
9402
|
+
const commandContext = {
|
|
9403
|
+
readPolicy: params.readPolicy,
|
|
9404
|
+
cfg: params.cfg,
|
|
9405
|
+
discordConfig: params.discordConfig,
|
|
9406
|
+
accountId: params.accountId,
|
|
9407
|
+
sessionPrefix: params.sessionPrefix,
|
|
9408
|
+
threadBindings: params.threadBindings,
|
|
9409
|
+
buildContext: params.channelRuntime?.inbound.buildContext,
|
|
9410
|
+
dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
|
|
9411
|
+
};
|
|
9857
9412
|
const commands = params.commandSpecs.map((spec) => {
|
|
9858
9413
|
if (params.nativeEnabled && params.voiceEnabled && spec.name === DISCORD_VOICE_COMMAND_SPEC.name) return createDiscordVoiceCommand({
|
|
9859
9414
|
readPolicy: params.readPolicy,
|
|
@@ -9866,15 +9421,9 @@ function createDiscordProviderInteractionSurface(params) {
|
|
|
9866
9421
|
ephemeralDefault: params.ephemeralDefault
|
|
9867
9422
|
});
|
|
9868
9423
|
return createNativeCommand({
|
|
9869
|
-
|
|
9424
|
+
...commandContext,
|
|
9870
9425
|
command: spec,
|
|
9871
|
-
|
|
9872
|
-
discordConfig: params.discordConfig,
|
|
9873
|
-
accountId: params.accountId,
|
|
9874
|
-
sessionPrefix: params.sessionPrefix,
|
|
9875
|
-
ephemeralDefault: params.ephemeralDefault,
|
|
9876
|
-
threadBindings: params.threadBindings,
|
|
9877
|
-
dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
|
|
9426
|
+
ephemeralDefault: params.ephemeralDefault
|
|
9878
9427
|
});
|
|
9879
9428
|
});
|
|
9880
9429
|
const execApprovalsConfig = params.discordConfig.execApprovals ?? {};
|
|
@@ -9899,61 +9448,29 @@ function createDiscordProviderInteractionSurface(params) {
|
|
|
9899
9448
|
},
|
|
9900
9449
|
abortSignal: params.abortSignal
|
|
9901
9450
|
});
|
|
9902
|
-
const
|
|
9903
|
-
createDiscordQuestionButton({
|
|
9904
|
-
cfg: params.cfg,
|
|
9905
|
-
accountId: params.accountId,
|
|
9906
|
-
authContext: {
|
|
9907
|
-
readPolicy: params.readPolicy,
|
|
9908
|
-
cfg: params.cfg,
|
|
9909
|
-
accountId: params.accountId,
|
|
9910
|
-
discordConfig: params.discordConfig,
|
|
9911
|
-
runtime: params.runtime,
|
|
9912
|
-
token: params.token,
|
|
9913
|
-
guildEntries: params.guildEntries,
|
|
9914
|
-
allowFrom: params.allowFrom,
|
|
9915
|
-
dmPolicy: params.dmPolicy
|
|
9916
|
-
}
|
|
9917
|
-
}),
|
|
9918
|
-
createDiscordCommandArgFallbackButton({
|
|
9919
|
-
readPolicy: params.readPolicy,
|
|
9920
|
-
cfg: params.cfg,
|
|
9921
|
-
discordConfig: params.discordConfig,
|
|
9922
|
-
accountId: params.accountId,
|
|
9923
|
-
sessionPrefix: params.sessionPrefix,
|
|
9924
|
-
threadBindings: params.threadBindings,
|
|
9925
|
-
dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
|
|
9926
|
-
}),
|
|
9927
|
-
createDiscordModelPickerFallbackButton({
|
|
9928
|
-
readPolicy: params.readPolicy,
|
|
9929
|
-
cfg: params.cfg,
|
|
9930
|
-
discordConfig: params.discordConfig,
|
|
9931
|
-
accountId: params.accountId,
|
|
9932
|
-
sessionPrefix: params.sessionPrefix,
|
|
9933
|
-
threadBindings: params.threadBindings,
|
|
9934
|
-
dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
|
|
9935
|
-
}),
|
|
9936
|
-
createDiscordModelPickerFallbackSelect({
|
|
9937
|
-
readPolicy: params.readPolicy,
|
|
9938
|
-
cfg: params.cfg,
|
|
9939
|
-
discordConfig: params.discordConfig,
|
|
9940
|
-
accountId: params.accountId,
|
|
9941
|
-
sessionPrefix: params.sessionPrefix,
|
|
9942
|
-
threadBindings: params.threadBindings,
|
|
9943
|
-
dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
|
|
9944
|
-
})
|
|
9945
|
-
];
|
|
9946
|
-
const activityButton = createDiscordActivityButton({
|
|
9451
|
+
const componentContext = {
|
|
9947
9452
|
readPolicy: params.readPolicy,
|
|
9948
9453
|
cfg: params.cfg,
|
|
9949
|
-
discordConfig: params.discordConfig,
|
|
9950
9454
|
accountId: params.accountId,
|
|
9455
|
+
discordConfig: params.discordConfig,
|
|
9456
|
+
runtime: params.runtime,
|
|
9457
|
+
token: params.token,
|
|
9951
9458
|
guildEntries: params.guildEntries,
|
|
9952
9459
|
allowFrom: params.allowFrom,
|
|
9953
|
-
dmPolicy: params.dmPolicy
|
|
9954
|
-
|
|
9955
|
-
|
|
9956
|
-
|
|
9460
|
+
dmPolicy: params.dmPolicy
|
|
9461
|
+
};
|
|
9462
|
+
const components = [createDiscordQuestionButton({
|
|
9463
|
+
cfg: params.cfg,
|
|
9464
|
+
accountId: params.accountId,
|
|
9465
|
+
authContext: componentContext
|
|
9466
|
+
}), ...[
|
|
9467
|
+
createDiscordCommandArgFallbackButton,
|
|
9468
|
+
createDiscordModelPickerFallbackButton,
|
|
9469
|
+
createDiscordModelPickerFallbackSelect
|
|
9470
|
+
].map((create) => create(commandContext))];
|
|
9471
|
+
const activityButton = createDiscordActivityButton({
|
|
9472
|
+
...componentContext,
|
|
9473
|
+
channelRuntime: params.channelRuntime
|
|
9957
9474
|
}, params.applicationId);
|
|
9958
9475
|
if (activityButton) components.push(activityButton);
|
|
9959
9476
|
const modals = [];
|
|
@@ -9963,17 +9480,6 @@ function createDiscordProviderInteractionSurface(params) {
|
|
|
9963
9480
|
config: execApprovalsConfig
|
|
9964
9481
|
})));
|
|
9965
9482
|
if ((params.discordConfig.agentComponents ?? {}).enabled ?? true) {
|
|
9966
|
-
const componentContext = {
|
|
9967
|
-
readPolicy: params.readPolicy,
|
|
9968
|
-
cfg: params.cfg,
|
|
9969
|
-
discordConfig: params.discordConfig,
|
|
9970
|
-
accountId: params.accountId,
|
|
9971
|
-
guildEntries: params.guildEntries,
|
|
9972
|
-
allowFrom: params.allowFrom,
|
|
9973
|
-
dmPolicy: params.dmPolicy,
|
|
9974
|
-
runtime: params.runtime,
|
|
9975
|
-
token: params.token
|
|
9976
|
-
};
|
|
9977
9483
|
components.push(...createAgentComponentControls.map((create) => create(componentContext)));
|
|
9978
9484
|
components.push(...createDiscordComponentControls.map((create) => create(componentContext)));
|
|
9979
9485
|
modals.push(createDiscordComponentModal(componentContext));
|
|
@@ -10015,7 +9521,7 @@ var VoicePlugin = class extends Plugin {
|
|
|
10015
9521
|
}
|
|
10016
9522
|
},
|
|
10017
9523
|
destroy: () => {
|
|
10018
|
-
this.adapters.delete(guildId);
|
|
9524
|
+
if (this.adapters.get(guildId) === methods) this.adapters.delete(guildId);
|
|
10019
9525
|
}
|
|
10020
9526
|
};
|
|
10021
9527
|
};
|
|
@@ -10027,11 +9533,7 @@ function resolveDiscordPreflightChannelAccess(params) {
|
|
|
10027
9533
|
if (params.isGuildMessage && params.channelConfig?.enabled === false) {
|
|
10028
9534
|
logDebug(`[discord-preflight] drop: channel disabled`);
|
|
10029
9535
|
logVerbose(`Blocked discord channel ${params.messageChannelId} (channel disabled, ${params.channelMatchMeta})`);
|
|
10030
|
-
return
|
|
10031
|
-
allowed: false,
|
|
10032
|
-
channelAllowlistConfigured: false,
|
|
10033
|
-
channelAllowed: false
|
|
10034
|
-
};
|
|
9536
|
+
return false;
|
|
10035
9537
|
}
|
|
10036
9538
|
const groupDmAllowed = params.isGroupDm && resolveGroupDmAllow({
|
|
10037
9539
|
channels: params.groupDmChannels,
|
|
@@ -10039,11 +9541,7 @@ function resolveDiscordPreflightChannelAccess(params) {
|
|
|
10039
9541
|
channelName: params.displayChannelName,
|
|
10040
9542
|
channelSlug: params.displayChannelSlug
|
|
10041
9543
|
});
|
|
10042
|
-
if (params.isGroupDm && !groupDmAllowed) return
|
|
10043
|
-
allowed: false,
|
|
10044
|
-
channelAllowlistConfigured: false,
|
|
10045
|
-
channelAllowed: false
|
|
10046
|
-
};
|
|
9544
|
+
if (params.isGroupDm && !groupDmAllowed) return false;
|
|
10047
9545
|
const channelAllowlistConfigured = Boolean(params.guildInfo?.channels) && Object.keys(params.guildInfo?.channels ?? {}).length > 0;
|
|
10048
9546
|
const channelAllowed = params.channelConfig?.allowed !== false;
|
|
10049
9547
|
if (params.isGuildMessage && !isDiscordGroupAllowedByPolicy({
|
|
@@ -10062,30 +9560,18 @@ function resolveDiscordPreflightChannelAccess(params) {
|
|
|
10062
9560
|
logDebug(`[discord] Ignored message from channel ${params.messageChannelId} (not in guild allowlist). Add to guilds.<guildId>.channels to enable.`);
|
|
10063
9561
|
logVerbose(`Blocked discord channel ${params.messageChannelId} not in guild channel allowlist (groupPolicy: allowlist, ${params.channelMatchMeta})`);
|
|
10064
9562
|
}
|
|
10065
|
-
return
|
|
10066
|
-
allowed: false,
|
|
10067
|
-
channelAllowlistConfigured,
|
|
10068
|
-
channelAllowed
|
|
10069
|
-
};
|
|
9563
|
+
return false;
|
|
10070
9564
|
}
|
|
10071
9565
|
if (params.isGuildMessage && params.channelConfig?.allowed === false) {
|
|
10072
9566
|
logDebug(`[discord-preflight] drop: channelConfig.allowed===false`);
|
|
10073
9567
|
logVerbose(`Blocked discord channel ${params.messageChannelId} not in guild channel allowlist (${params.channelMatchMeta})`);
|
|
10074
|
-
return
|
|
10075
|
-
allowed: false,
|
|
10076
|
-
channelAllowlistConfigured,
|
|
10077
|
-
channelAllowed
|
|
10078
|
-
};
|
|
9568
|
+
return false;
|
|
10079
9569
|
}
|
|
10080
9570
|
if (params.isGuildMessage) {
|
|
10081
9571
|
logDebug(`[discord-preflight] pass: channel allowed`);
|
|
10082
9572
|
logVerbose(`discord: allow channel ${params.messageChannelId} (${params.channelMatchMeta})`);
|
|
10083
9573
|
}
|
|
10084
|
-
return
|
|
10085
|
-
allowed: true,
|
|
10086
|
-
channelAllowlistConfigured,
|
|
10087
|
-
channelAllowed
|
|
10088
|
-
};
|
|
9574
|
+
return true;
|
|
10089
9575
|
}
|
|
10090
9576
|
//#endregion
|
|
10091
9577
|
//#region extensions/discord/src/monitor/listeners.guild-join.ts
|
|
@@ -10142,7 +9628,7 @@ var DiscordGuildJoinIntroductionListener = class extends GuildCreateListener {
|
|
|
10142
9628
|
guildInfo,
|
|
10143
9629
|
channelConfig,
|
|
10144
9630
|
channelMatchMeta: `guild=${data.id} channel=${channel.id}`
|
|
10145
|
-
})
|
|
9631
|
+
});
|
|
10146
9632
|
if (roomAllowed) {
|
|
10147
9633
|
targetChannel = channel;
|
|
10148
9634
|
break;
|
|
@@ -10216,11 +9702,7 @@ var DiscordGuildJoinIntroductionListener = class extends GuildCreateListener {
|
|
|
10216
9702
|
//#region extensions/discord/src/monitor/provider.startup.ts
|
|
10217
9703
|
function registerLatePlugin(client, plugin) {
|
|
10218
9704
|
plugin.registerClient?.(client);
|
|
10219
|
-
plugin.
|
|
10220
|
-
if (!client.plugins.some((entry) => entry.id === plugin.id)) client.plugins.push({
|
|
10221
|
-
id: plugin.id,
|
|
10222
|
-
plugin
|
|
10223
|
-
});
|
|
9705
|
+
if (!client.plugins.some((entry) => entry.id === plugin.id)) client.plugins.push(plugin);
|
|
10224
9706
|
}
|
|
10225
9707
|
function createDiscordStatusReadyListener(params) {
|
|
10226
9708
|
return new class DiscordStatusReadyListener extends ReadyListener {
|
|
@@ -10232,21 +9714,17 @@ function createDiscordStatusReadyListener(params) {
|
|
|
10232
9714
|
}
|
|
10233
9715
|
const gateway = client.getPlugin("gateway");
|
|
10234
9716
|
if (!gateway) return;
|
|
10235
|
-
|
|
10236
|
-
if (!presence) return;
|
|
10237
|
-
gateway.updatePresence(presence);
|
|
9717
|
+
gateway.updatePresence(resolveDiscordPresenceUpdate(params.discordConfig));
|
|
10238
9718
|
}
|
|
10239
9719
|
}();
|
|
10240
9720
|
}
|
|
10241
9721
|
async function createDiscordMonitorClient(params) {
|
|
10242
9722
|
let autoPresenceController = null;
|
|
10243
|
-
const
|
|
9723
|
+
const constructorPlugins = [params.createGatewayPlugin({
|
|
10244
9724
|
discordConfig: params.discordConfig,
|
|
10245
9725
|
runtime: params.runtime
|
|
10246
9726
|
})];
|
|
10247
|
-
|
|
10248
|
-
const voicePlugin = clientPlugins.find((plugin) => plugin.id === "voice");
|
|
10249
|
-
const constructorPlugins = voicePlugin ? clientPlugins.filter((plugin) => plugin !== voicePlugin) : clientPlugins;
|
|
9727
|
+
const voicePlugin = params.voiceEnabled ? new VoicePlugin() : void 0;
|
|
10250
9728
|
const eventQueueOpts = {
|
|
10251
9729
|
listenerTimeout: 12e4,
|
|
10252
9730
|
slowListenerThreshold: 3e4
|
|
@@ -10256,16 +9734,11 @@ async function createDiscordMonitorClient(params) {
|
|
|
10256
9734
|
getAutoPresenceController: () => autoPresenceController
|
|
10257
9735
|
});
|
|
10258
9736
|
const client = params.createClient({
|
|
10259
|
-
baseUrl: "http://localhost",
|
|
10260
|
-
deploySecret: "a",
|
|
10261
9737
|
clientId: params.applicationId,
|
|
10262
|
-
publicKey: "a",
|
|
10263
9738
|
token: params.token,
|
|
10264
|
-
autoDeploy: false,
|
|
10265
9739
|
commandDeployHashStore: params.commandDeployHashStore,
|
|
10266
9740
|
requestOptions: {
|
|
10267
9741
|
timeout: DISCORD_REST_TIMEOUT_MS,
|
|
10268
|
-
runtimeProfile: "persistent",
|
|
10269
9742
|
maxQueueSize: 1e3,
|
|
10270
9743
|
...params.restFetch ? { fetch: params.restFetch } : {}
|
|
10271
9744
|
},
|
|
@@ -10319,9 +9792,8 @@ async function fetchDiscordBotIdentity(params) {
|
|
|
10319
9792
|
params.logStartupPhase("fetch-bot-identity:error", String(err));
|
|
10320
9793
|
throw new Error("Failed to resolve Discord bot identity", { cause: err });
|
|
10321
9794
|
}
|
|
10322
|
-
const
|
|
10323
|
-
const
|
|
10324
|
-
const botUserName = normalizeOptionalString(botUserRecord?.username) ?? normalizeOptionalString(botUserRecord?.globalName);
|
|
9795
|
+
const botUserId = normalizeOptionalString(botUser?.id);
|
|
9796
|
+
const botUserName = normalizeOptionalString(botUser?.username) ?? normalizeOptionalString(botUser?.globalName);
|
|
10325
9797
|
if (!botUserId) {
|
|
10326
9798
|
const details = "fetchUser(\"@me\") returned no usable id";
|
|
10327
9799
|
params.runtime.error?.(danger(`discord: failed to fetch bot identity: ${details}`));
|
|
@@ -10405,12 +9877,6 @@ function formatDiscordStartupStatusMessage(params) {
|
|
|
10405
9877
|
//#endregion
|
|
10406
9878
|
//#region extensions/discord/src/monitor/provider.ts
|
|
10407
9879
|
const DEFAULT_DISCORD_MEDIA_MAX_MB = 100;
|
|
10408
|
-
function logDiscordStartupPhase(params) {
|
|
10409
|
-
logDiscordStartupPhase$1({
|
|
10410
|
-
...params,
|
|
10411
|
-
isVerbose: discordProviderRuntime.isVerbose
|
|
10412
|
-
});
|
|
10413
|
-
}
|
|
10414
9880
|
const DISCORD_DISALLOWED_INTENTS_CODE = GatewayCloseCodes$1.DisallowedIntents;
|
|
10415
9881
|
function isDiscordDisallowedIntentsError(err) {
|
|
10416
9882
|
if (!err) return false;
|
|
@@ -10427,6 +9893,16 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10427
9893
|
const token = normalizeDiscordToken(opts.token ?? void 0, "channels.discord.token") ?? account.token;
|
|
10428
9894
|
if (!token) throw new Error(`Discord bot token missing for account "${account.accountId}" (set discord.accounts.${account.accountId}.token or DISCORD_BOT_TOKEN for default).`);
|
|
10429
9895
|
const runtime = opts.runtime ?? createNonExitingRuntime();
|
|
9896
|
+
let lifecycleGateway;
|
|
9897
|
+
const logStartupPhase = (phase, details) => logDiscordStartupPhase({
|
|
9898
|
+
runtime,
|
|
9899
|
+
accountId: account.accountId,
|
|
9900
|
+
phase,
|
|
9901
|
+
startAt: startupStartedAt,
|
|
9902
|
+
gateway: lifecycleGateway,
|
|
9903
|
+
details,
|
|
9904
|
+
isVerbose: discordProviderRuntime.isVerbose
|
|
9905
|
+
});
|
|
10430
9906
|
const rawDiscordCfg = account.config;
|
|
10431
9907
|
const discordRestFetch = resolveDiscordRestFetch(rawDiscordCfg.proxy, runtime);
|
|
10432
9908
|
const dmConfig = rawDiscordCfg.dm;
|
|
@@ -10456,7 +9932,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10456
9932
|
let allowFrom = configuredDmAllowFrom ?? [];
|
|
10457
9933
|
const mediaMaxBytes = (opts.mediaMaxMb ?? discordCfg.mediaMaxMb ?? DEFAULT_DISCORD_MEDIA_MAX_MB) * 1024 * 1024;
|
|
10458
9934
|
const textLimit = resolveTextChunkLimit(cfg, "discord", account.accountId, { fallbackLimit: 2e3 });
|
|
10459
|
-
const historyLimit =
|
|
9935
|
+
const historyLimit = resolvePromptHistoryLimit(opts.historyLimit ?? discordCfg.historyLimit ?? cfg.messages?.groupChat?.historyLimit, 20);
|
|
10460
9936
|
const replyToMode = opts.replyToMode ?? discordCfg.replyToMode ?? "off";
|
|
10461
9937
|
const dmEnabled = dmConfig?.enabled ?? true;
|
|
10462
9938
|
const dmPolicy = resolveDiscordAccountDmPolicy({
|
|
@@ -10532,12 +10008,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10532
10008
|
threadBindingIdleTimeoutMs,
|
|
10533
10009
|
threadBindingMaxAgeMs
|
|
10534
10010
|
});
|
|
10535
|
-
|
|
10536
|
-
runtime,
|
|
10537
|
-
accountId: account.accountId,
|
|
10538
|
-
phase: "fetch-application-id:start",
|
|
10539
|
-
startAt: startupStartedAt
|
|
10540
|
-
});
|
|
10011
|
+
logStartupPhase("fetch-application-id:start");
|
|
10541
10012
|
const parsedApplicationId = (typeof discordCfg.applicationId === "string" && discordCfg.applicationId.trim() ? discordCfg.applicationId.trim() : void 0) ?? parseApplicationIdFromToken(token);
|
|
10542
10013
|
const applicationIdProbe = parsedApplicationId ? {
|
|
10543
10014
|
kind: "resolved",
|
|
@@ -10563,13 +10034,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10563
10034
|
throw new Error(message, { cause: applicationIdProbe.error });
|
|
10564
10035
|
}
|
|
10565
10036
|
const applicationId = applicationIdProbe.applicationId;
|
|
10566
|
-
|
|
10567
|
-
runtime,
|
|
10568
|
-
accountId: account.accountId,
|
|
10569
|
-
phase: "fetch-application-id:done",
|
|
10570
|
-
startAt: startupStartedAt,
|
|
10571
|
-
details: `applicationId=${applicationId}`
|
|
10572
|
-
});
|
|
10037
|
+
logStartupPhase("fetch-application-id:done", `applicationId=${applicationId}`);
|
|
10573
10038
|
const { commandSpecs } = await resolveDiscordProviderCommandSpecs({
|
|
10574
10039
|
cfg,
|
|
10575
10040
|
runtime,
|
|
@@ -10592,7 +10057,6 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10592
10057
|
let deactivateMessageHandler;
|
|
10593
10058
|
let stopMonitorListeners;
|
|
10594
10059
|
let autoPresenceController = null;
|
|
10595
|
-
let lifecycleGateway;
|
|
10596
10060
|
let earlyGatewayEmitter = gatewaySupervisor?.emitter;
|
|
10597
10061
|
let onEarlyGatewayDebug;
|
|
10598
10062
|
try {
|
|
@@ -10672,14 +10136,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10672
10136
|
runtime.log?.(`discord startup [${account.accountId}] gateway-debug ${Math.max(0, Date.now() - startupStartedAt)}ms ${String(msg)}`);
|
|
10673
10137
|
};
|
|
10674
10138
|
earlyGatewayEmitter?.on("debug", onEarlyGatewayDebug);
|
|
10675
|
-
|
|
10676
|
-
runtime,
|
|
10677
|
-
accountId: account.accountId,
|
|
10678
|
-
phase: "deploy-commands:schedule",
|
|
10679
|
-
startAt: startupStartedAt,
|
|
10680
|
-
gateway: lifecycleGateway,
|
|
10681
|
-
details: `native=${nativeEnabled ? "on" : "off"} reconcile=on commandCount=${commands.length}`
|
|
10682
|
-
});
|
|
10139
|
+
logStartupPhase("deploy-commands:schedule", `native=${nativeEnabled ? "on" : "off"} reconcile=on commandCount=${commands.length}`);
|
|
10683
10140
|
runDiscordCommandDeployInBackground({
|
|
10684
10141
|
client,
|
|
10685
10142
|
runtime,
|
|
@@ -10695,14 +10152,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10695
10152
|
client,
|
|
10696
10153
|
token,
|
|
10697
10154
|
runtime,
|
|
10698
|
-
logStartupPhase
|
|
10699
|
-
runtime,
|
|
10700
|
-
accountId: account.accountId,
|
|
10701
|
-
phase,
|
|
10702
|
-
startAt: startupStartedAt,
|
|
10703
|
-
gateway: lifecycleGateway,
|
|
10704
|
-
details
|
|
10705
|
-
})
|
|
10155
|
+
logStartupPhase
|
|
10706
10156
|
});
|
|
10707
10157
|
let voiceManager = null;
|
|
10708
10158
|
if (voiceEnabled) {
|
|
@@ -10779,13 +10229,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10779
10229
|
messageHandler,
|
|
10780
10230
|
trackInboundEvent
|
|
10781
10231
|
});
|
|
10782
|
-
|
|
10783
|
-
runtime,
|
|
10784
|
-
accountId: account.accountId,
|
|
10785
|
-
phase: "client-start",
|
|
10786
|
-
startAt: startupStartedAt,
|
|
10787
|
-
gateway: lifecycleGateway
|
|
10788
|
-
});
|
|
10232
|
+
logStartupPhase("client-start");
|
|
10789
10233
|
const botIdentity = botUserId && botUserName ? `${botUserId} (${botUserName})` : botUserId ?? botUserName ?? "";
|
|
10790
10234
|
runtime.log?.(formatDiscordStartupStatusMessage({
|
|
10791
10235
|
gatewayReady: lifecycleGateway?.isConnected === true,
|
|
@@ -10824,4 +10268,4 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10824
10268
|
}
|
|
10825
10269
|
}
|
|
10826
10270
|
//#endregion
|
|
10827
|
-
export {
|
|
10271
|
+
export { resolveDiscordDmCommandAccess as A, buildDiscordGroupSystemPrompt as C, createDiscordLivePolicyReader as D, handleDiscordDmCommandDecision as E, mapGatewayDispatchData as O, createDiscordNativeCommand as S, createDiscordSupplementalContextAccessChecker as T, resolveDiscordVoiceMode as _, formatDiscordReplySkip as a, resolveDiscordGatewayIntents as b, buildGuildLabel as c, MIN_SEGMENT_SECONDS as d, VOICE_CONNECT_READY_TIMEOUT_MS as f, logVoiceVerbose as g, isVoiceChannel as h, formatDiscordReplyDeliveryFailure as i, resolveDiscordTextCommandAccess as j, registerDiscordListener as k, resolveReplyContext as l, isDiscordRealtimeVoiceMode as m, resolveDiscordPreflightChannelAccess as n, sanitizeDiscordFrontChannelReplyPayloads as o, VOICE_RECONNECT_GRACE_MS as p, deliverDiscordReply as r, buildDirectLabel as s, monitorDiscordProvider as t, CAPTURE_FINALIZE_GRACE_MS as u, resolveVoiceTimeoutMs as v, buildDiscordInboundAccessContext as w, waitForDiscordGatewayPluginRegistration as x, createDiscordGatewayPlugin as y };
|