@openclaw/discord 2026.8.1-beta.2 → 2026.9.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{account-inspect-CqzrH14k.js → account-inspect-BDfKyuvL.js} +1 -1
- package/dist/account-inspect-api.js +1 -1
- package/dist/{accounts-DJTf1LtA.js → accounts-CfQ-vSyf.js} +34 -1
- package/dist/action-runtime-api.js +1 -1
- package/dist/{activities-api-DS7vpdtp.js → activities-api-q-9PaaHH.js} +134 -175
- package/dist/activities-api.js +1 -1
- package/dist/api.js +17 -17
- package/dist/{approval-handler.runtime-B6yEV79q.js → approval-handler.runtime-B7qhK3fR.js} +29 -106
- package/dist/{audit-Db-rlntl.js → audit-CBEv_ERu.js} +5 -5
- package/dist/{channel-CnnbJSt5.js → channel-Dx1tMTfx.js} +72 -50
- package/dist/{channel-actions.runtime-CLKrx6tr.js → channel-actions.runtime-CLWWu9nC.js} +28 -43
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/channel-type-CVLZyGYS.js +7 -0
- package/dist/{channel.setup-BFAO-V1P.js → channel.setup-DOzXS2Pk.js} +5 -5
- package/dist/{outbound-session-route-DxLkrgKQ.js → components-B9V5o361.js} +8 -70
- package/dist/{config-schema-BgEskFAs.js → config-schema-BR13IAx6.js} +33 -7
- package/dist/conversation-binding-route-DJYrY2TQ.js +43 -0
- package/dist/{directory-config-BVX7Cflc.js → directory-config-BK6eqekJ.js} +2 -2
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-DGIGxpIo.js → directory-live-DSAJSrJk.js} +3 -3
- package/dist/{doctor-BzC-TLnB.js → doctor-Cm7Y1pJ2.js} +33 -12
- package/dist/doctor-contract-api.js +2 -2
- package/dist/{handle-action.guild-admin-BNVTUISF.js → handle-action.guild-admin-BdwCRHmm.js} +9 -5
- package/dist/index.js +3 -4
- package/dist/{message-handler-Unk_f10F.js → message-handler-BXpWZyni.js} +82 -6
- package/dist/{message-handler.preflight-C9zecxR9.js → message-handler.preflight-Ba5LAY_X.js} +38 -50
- package/dist/{message-handler.process-DWQ6UHHu.js → message-handler.process-3HEzmemS.js} +204 -234
- package/dist/{message-utils-BSCPVgy0.js → message-text-aiwO5R2F.js} +41 -40
- package/dist/{outbound-adapter-D9nRivT1.js → outbound-adapter-BE4jSq2d.js} +113 -88
- package/dist/{outbound-components-cTzwBJ60.js → outbound-components-oLpg8Qzb.js} +3 -3
- package/dist/outbound-session-route-Cg15ZFJd.js +625 -0
- package/dist/owner-access-UlYi9t0M.js +107 -0
- package/dist/{pluralkit-DdiJ9KMK.js → pluralkit-Tiyl70dx.js} +1 -1
- package/dist/{probe-Bl-k5_Ku.js → probe-n6ZXxK8V.js} +1 -1
- package/dist/{probe.runtime-M9fREKvp.js → probe.runtime-CN4bdPfZ.js} +1 -1
- package/dist/{provider-DvSNb-2v.js → provider-B11xwilq.js} +720 -1325
- package/dist/{provider-session.runtime-BUEqD0rA.js → provider-session.runtime-B9xe-Qaf.js} +3 -3
- package/dist/provider.runtime-DiYaHvOz.js +2 -0
- package/dist/{realtime-session.runtime-C7wen-aF.js → realtime-session.runtime-CU8IQUS-.js} +97 -98
- package/dist/{resolve-allowlist-common-D04lpEzb.js → resolve-allowlist-common-BLoYaxEG.js} +2 -2
- package/dist/{resolve-channels-Dm7jEeg6.js → resolve-channels-C2sT_n67.js} +5 -4
- package/dist/{resolve-users-bktrCUUU.js → resolve-users-CzpjLwjy.js} +2 -2
- package/dist/{retry-CLpJcXXf.js → retry-Cv4jCU5Z.js} +111 -18
- package/dist/{runtime-DGsSyDTS.js → runtime-BHrTlFkf.js} +88 -85
- package/dist/{runtime-DoHjckYm.js → runtime-CY4PRMF-.js} +9 -10
- package/dist/runtime-api.js +19 -25
- package/dist/{sdk-runtime-QpY8PvCh.js → sdk-runtime-4geQHtXc.js} +57 -89
- package/dist/{secret-config-contract-B1akrlyY.js → secret-config-contract-B3i6WxV5.js} +53 -25
- package/dist/secret-contract-api.js +1 -1
- package/dist/security-audit-contract-api.js +1 -1
- package/dist/{security-audit.runtime-CPN0xFYz.js → security-audit.runtime-BVKF9VtY.js} +1 -1
- package/dist/{send-B7Q6Oc1I.js → send-C49MFF9j.js} +82 -19
- package/dist/{send.components-iJyFXw9L.js → send.components-DKKAw5VX.js} +21 -38
- package/dist/{send.outbound-DS5tHwfR.js → send.outbound-zam0TrZx.js} +77 -78
- package/dist/{send.shared-BmwFjW6T.js → send.shared-JjljcV4O.js} +135 -120
- package/dist/{sender-identity-QtalnCYv.js → sender-identity-BJtfyise.js} +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{shared-BIXIX6uJ.js → shared-_5EcP4jW.js} +38 -14
- package/dist/subagent-hooks-DQzvOptn.js +49 -0
- package/dist/subagent-hooks-api.js +1 -6
- package/dist/{system-events-CTqDf6_s.js → system-events-C7yxaHWP.js} +2 -2
- package/dist/{target-resolver-maOKSqO0.js → target-resolver-vxIh6O3-.js} +3 -3
- package/dist/targets-CtTKvntJ.js +3 -0
- package/dist/{thread-bindings-3L8p82GV.js → thread-bindings-DW5F9vat.js} +28 -26
- package/dist/{thread-bindings.manager-DCIH6WDC.js → thread-bindings.manager-ByOtwjo_.js} +9 -12
- package/dist/{thread-bindings.session-updates-bJ2KQFY6.js → thread-bindings.session-updates-CJb-BpPL.js} +1 -1
- package/dist/{thread-bindings.state-aeV8HNgV.js → thread-bindings.state-D8OMdk4O.js} +1 -1
- package/dist/threading-agH1T_6s.js +478 -0
- package/dist/transcripts-source-BR11iHA4.js +265 -0
- package/dist/transcripts-source-api.js +7 -2
- package/dist/{typing-CS-nNVoe.js → typing-Dc_YMY2e.js} +1 -1
- package/dist/{voice-runtime-BEdqNcST.js → voice-runtime-DIeaa8fJ.js} +230 -148
- package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/README.md +19 -19
- package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/dist/v1.js +7 -3
- package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/dist/v7.js +5 -2
- package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/dist-node/v1.js +7 -3
- package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/dist-node/v7.js +5 -2
- package/node_modules/@discord/embedded-app-sdk/node_modules/uuid/package.json +4 -3
- package/node_modules/@discordjs/voice/node_modules/@types/node/README.md +1 -1
- package/node_modules/@discordjs/voice/node_modules/@types/node/child_process.d.ts +0 -1
- package/node_modules/@discordjs/voice/node_modules/@types/node/crypto.d.ts +6 -6
- package/node_modules/@discordjs/voice/node_modules/@types/node/dns/promises.d.ts +5 -5
- package/node_modules/@discordjs/voice/node_modules/@types/node/dns.d.ts +5 -5
- package/node_modules/@discordjs/voice/node_modules/@types/node/fs.d.ts +7 -0
- package/node_modules/@discordjs/voice/node_modules/@types/node/http.d.ts +30 -0
- package/node_modules/@discordjs/voice/node_modules/@types/node/http2.d.ts +4 -4
- package/node_modules/@discordjs/voice/node_modules/@types/node/os.d.ts +30 -30
- package/node_modules/@discordjs/voice/node_modules/@types/node/package.json +2 -2
- package/node_modules/@discordjs/voice/node_modules/@types/node/perf_hooks.d.ts +2 -1
- package/node_modules/@discordjs/voice/node_modules/@types/node/process.d.ts +42 -43
- package/node_modules/@discordjs/voice/node_modules/@types/node/quic.d.ts +1049 -84
- package/node_modules/@discordjs/voice/node_modules/@types/node/sqlite.d.ts +14 -1
- package/node_modules/@discordjs/voice/node_modules/@types/node/stream/iter.d.ts +3 -2
- package/node_modules/@discordjs/voice/node_modules/@types/node/test.d.ts +61 -0
- package/node_modules/@discordjs/voice/node_modules/@types/node/v8.d.ts +20 -23
- package/node_modules/discord-api-types/CHANGELOG.md +8 -0
- package/node_modules/discord-api-types/package.json +4 -4
- package/node_modules/discord-api-types/payloads/v10/channel.d.ts +2 -2
- package/node_modules/discord-api-types/payloads/v10/channel.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v10/gateway.d.ts +4 -0
- package/node_modules/discord-api-types/payloads/v10/gateway.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v10/gateway.js.map +1 -1
- package/node_modules/discord-api-types/payloads/v10/message.d.ts +4 -1
- package/node_modules/discord-api-types/payloads/v10/message.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v10/message.js +1 -0
- package/node_modules/discord-api-types/payloads/v10/message.js.map +1 -1
- package/node_modules/discord-api-types/payloads/v9/channel.d.ts +2 -2
- package/node_modules/discord-api-types/payloads/v9/channel.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v9/gateway.d.ts +4 -0
- package/node_modules/discord-api-types/payloads/v9/gateway.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v9/gateway.js.map +1 -1
- package/node_modules/discord-api-types/payloads/v9/message.d.ts +4 -1
- package/node_modules/discord-api-types/payloads/v9/message.d.ts.map +1 -1
- package/node_modules/discord-api-types/payloads/v9/message.js +1 -0
- package/node_modules/discord-api-types/payloads/v9/message.js.map +1 -1
- package/node_modules/typebox/build/format/date.d.mts +1 -1
- package/node_modules/typebox/build/format/date.mjs +1 -1
- package/node_modules/typebox/build/format/date_time.d.mts +2 -2
- package/node_modules/typebox/build/format/date_time.mjs +3 -3
- package/node_modules/typebox/build/format/email.d.mts +1 -1
- package/node_modules/typebox/build/format/email.mjs +2 -2
- package/node_modules/typebox/build/format/hostname.mjs +2 -10
- package/node_modules/typebox/build/format/idn_email.d.mts +1 -1
- package/node_modules/typebox/build/format/idn_email.mjs +3 -3
- package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idn_hostname.mjs +3 -11
- package/node_modules/typebox/build/format/idna/format/bidi.d.mts +3 -0
- package/node_modules/typebox/build/format/idna/format/bidi.mjs +98 -0
- package/node_modules/typebox/build/format/idna/format/puny.d.mts +3 -0
- package/node_modules/typebox/build/format/idna/format/puny.mjs +144 -0
- package/node_modules/typebox/build/format/idna/hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/hostname.mjs +16 -0
- package/node_modules/typebox/build/format/idna/idn-hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/idn-hostname.mjs +23 -0
- package/node_modules/typebox/build/format/idna/index.d.mts +2 -0
- package/node_modules/typebox/build/format/idna/index.mjs +2 -0
- package/node_modules/typebox/build/format/idna/label/ascii.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/ascii.mjs +9 -0
- package/node_modules/typebox/build/format/idna/label/puny.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/puny.mjs +28 -0
- package/node_modules/typebox/build/format/idna/label/unicode.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/unicode.mjs +106 -0
- package/node_modules/typebox/build/format/idna/pattern/pattern.d.mts +30 -0
- package/node_modules/typebox/build/format/idna/pattern/pattern.mjs +70 -0
- package/node_modules/typebox/build/format/ipv4.d.mts +0 -1
- package/node_modules/typebox/build/format/ipv4.mjs +2 -32
- package/node_modules/typebox/build/format/ipv6.mjs +2 -61
- package/node_modules/typebox/build/format/iri.d.mts +2 -2
- package/node_modules/typebox/build/format/iri.mjs +26 -8
- package/node_modules/typebox/build/format/iri_reference.d.mts +2 -2
- package/node_modules/typebox/build/format/iri_reference.mjs +9 -55
- package/node_modules/typebox/build/format/regex.d.mts +1 -2
- package/node_modules/typebox/build/format/regex.mjs +2 -6
- package/node_modules/typebox/build/format/time.d.mts +2 -2
- package/node_modules/typebox/build/format/time.mjs +19 -14
- package/node_modules/typebox/build/format/uri.d.mts +1 -1
- package/node_modules/typebox/build/format/uri.mjs +3 -130
- package/node_modules/typebox/build/format/uri_reference.d.mts +1 -1
- package/node_modules/typebox/build/format/uri_reference.mjs +2 -3
- package/node_modules/typebox/build/format/uri_template.d.mts +2 -3
- package/node_modules/typebox/build/format/uri_template.mjs +4 -5
- package/node_modules/typebox/build/format/url.d.mts +3 -3
- package/node_modules/typebox/build/format/url.mjs +4 -5
- package/node_modules/typebox/build/guard/emit.d.mts +3 -1
- package/node_modules/typebox/build/guard/emit.mjs +12 -5
- package/node_modules/typebox/build/guard/guard.d.mts +8 -2
- package/node_modules/typebox/build/guard/guard.mjs +25 -4
- package/node_modules/typebox/build/guard/string.d.mts +2 -2
- package/node_modules/typebox/build/guard/string.mjs +7 -7
- package/node_modules/typebox/build/schema/engine/_context.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -2
- package/node_modules/typebox/build/schema/engine/_regexp.d.mts +2 -0
- package/node_modules/typebox/build/schema/engine/_regexp.mjs +4 -0
- package/node_modules/typebox/build/schema/engine/_stack.mjs +12 -13
- package/node_modules/typebox/build/schema/engine/additionalItems.mjs +17 -7
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +4 -3
- package/node_modules/typebox/build/schema/engine/contains.mjs +18 -6
- package/node_modules/typebox/build/schema/engine/enum.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/items.mjs +26 -6
- package/node_modules/typebox/build/schema/engine/maxContains.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/minContains.mjs +14 -4
- package/node_modules/typebox/build/schema/engine/not.mjs +4 -2
- package/node_modules/typebox/build/schema/engine/oneOf.mjs +7 -6
- package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +4 -3
- package/node_modules/typebox/build/schema/engine/ref.mjs +1 -7
- package/node_modules/typebox/build/schema/engine/schema.mjs +13 -4
- package/node_modules/typebox/build/schema/engine/type.mjs +1 -1
- package/node_modules/typebox/build/schema/resolve/resolve.d.mts +4 -1
- package/node_modules/typebox/build/schema/resolve/resolve.mjs +202 -1
- package/node_modules/typebox/build/schema/static/propertyNames.d.mts +5 -0
- package/node_modules/typebox/build/schema/static/propertyNames.mjs +3 -0
- package/node_modules/typebox/build/schema/static/schema.d.mts +3 -0
- package/node_modules/typebox/build/schema/types/index.d.mts +0 -2
- package/node_modules/typebox/build/schema/types/index.mjs +0 -2
- package/node_modules/typebox/build/system/memory/clone.mjs +14 -11
- package/node_modules/typebox/build/system/memory/discard.mjs +6 -5
- package/node_modules/typebox/build/system/settings/settings.d.mts +9 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +2 -0
- package/node_modules/typebox/build/type/engine/call/distribute_arguments.d.mts +6 -1
- package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +16 -3
- package/node_modules/typebox/build/type/engine/call/instantiate.mjs +34 -4
- package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +5 -5
- package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +20 -26
- package/node_modules/typebox/build/type/engine/evaluate/compare.d.mts +6 -10
- package/node_modules/typebox/build/type/engine/evaluate/compare.mjs +9 -13
- package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +7 -4
- package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +12 -19
- package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +4 -20
- package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +8 -20
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +4 -4
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +11 -8
- package/node_modules/typebox/build/type/engine/evaluate/flatten.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/evaluate/flatten.mjs +3 -4
- package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +17 -2
- package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +26 -6
- package/node_modules/typebox/build/type/engine/exclude/operation.mjs +3 -4
- package/node_modules/typebox/build/type/engine/extract/operation.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/extract/operation.mjs +3 -4
- package/node_modules/typebox/build/type/engine/priority/priority.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/priority/priority.mjs +3 -4
- package/node_modules/typebox/build/type/script/mapping.d.mts +32 -29
- package/node_modules/typebox/build/type/script/mapping.mjs +18 -25
- package/node_modules/typebox/build/type/script/parser.d.mts +19 -25
- package/node_modules/typebox/build/type/script/parser.mjs +27 -23
- package/node_modules/typebox/build/value/errors/errors.d.mts +2 -2
- package/node_modules/typebox/build/value/errors/errors.mjs +1 -1
- package/node_modules/typebox/package.json +27 -27
- package/node_modules/typebox/readme.md +79 -82
- package/node_modules/undici/docs/docs/api/Client.md +21 -8
- package/node_modules/undici/lib/api/readable.js +33 -43
- package/node_modules/undici/lib/core/connect.js +16 -2
- package/node_modules/undici/lib/core/symbols.js +1 -0
- package/node_modules/undici/lib/dispatcher/client-h1.js +3 -3
- package/node_modules/undici/lib/dispatcher/client-h2.js +179 -10
- package/node_modules/undici/lib/dispatcher/client.js +74 -29
- package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +28 -6
- package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +15 -1
- package/node_modules/undici/lib/handler/retry-handler.js +7 -2
- package/node_modules/undici/lib/interceptor/cache.js +5 -2
- package/node_modules/undici/lib/interceptor/deduplicate.js +1 -1
- package/node_modules/undici/lib/mock/mock-utils.js +213 -24
- package/node_modules/undici/lib/util/cache.js +2 -4
- package/node_modules/undici/lib/web/websocket/websocket.js +22 -0
- package/node_modules/undici/package.json +1 -1
- package/node_modules/undici/types/client.d.ts +40 -0
- package/node_modules/ws/lib/permessage-deflate.js +3 -1
- package/node_modules/ws/package.json +1 -1
- package/openclaw.plugin.json +12 -6
- package/package.json +8 -10
- package/dist/approval-message-safety-AcIxvrf3.js +0 -140
- package/dist/audit-core-xwjIczO0.js +0 -105
- package/dist/channel-actions-5s_hjYKd.js +0 -208
- package/dist/channel-api-CAJ0wMoV.js +0 -21
- package/dist/inbound-event-delivery-De2qxTrP.js +0 -39
- package/dist/provider.runtime-C9PnJZbZ.js +0 -2
- package/dist/runtime-api.actions.js +0 -3
- package/dist/runtime-api.lookup.js +0 -7
- package/dist/runtime-api.monitor-CHxrFPnW.js +0 -5
- package/dist/runtime-api.monitor.js +0 -8
- package/dist/runtime-api.send.js +0 -7
- package/dist/runtime-api.threads.js +0 -5
- package/dist/send.reactions-BAn0iiVQ.js +0 -78
- package/dist/send.receipt-IPI1p-SP.js +0 -66
- package/dist/subagent-hooks-CTt5KCJr.js +0 -120
- package/dist/subagent-progress-DhaE_h8a.js +0 -109
- package/dist/targets-yUFTHoAx.js +0 -3
- package/dist/transcripts-source-CfFMexGt.js +0 -123
- package/node_modules/p-map/index.d.ts +0 -155
- package/node_modules/p-map/index.js +0 -285
- package/node_modules/p-map/license +0 -9
- package/node_modules/p-map/package.json +0 -57
- package/node_modules/p-map/readme.md +0 -190
- package/node_modules/typebox/build/format/_idna.d.mts +0 -2
- package/node_modules/typebox/build/format/_idna.mjs +0 -246
- package/node_modules/typebox/build/format/_puny.d.mts +0 -1
- package/node_modules/typebox/build/format/_puny.mjs +0 -77
- package/node_modules/typebox/build/schema/resolve/ref.d.mts +0 -3
- package/node_modules/typebox/build/schema/resolve/ref.mjs +0 -146
- package/node_modules/typebox/build/schema/types/contentEncoding.d.mts +0 -9
- package/node_modules/typebox/build/schema/types/contentEncoding.mjs +0 -13
- package/node_modules/typebox/build/schema/types/contentMediaType.d.mts +0 -9
- package/node_modules/typebox/build/schema/types/contentMediaType.mjs +0 -13
- package/dist/{allow-list-DnxIlPP2.js → allow-list-BDMimASD.js} +1 -1
- package/dist/{doctor-contract-DLa-BTiU.js → doctor-contract-DsWvKIXF.js} +1 -1
- package/dist/{security-audit-jGnJF__m.js → security-audit-BfJhAXZp.js} +1 -1
|
@@ -1,39 +1,42 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { D as canViewDiscordGuildChannel, F as createDiscordRestClient, H as registerGateway, K as validateDiscordProxyUrl, U as unregisterGateway, q as withValidatedDiscordProxy, z as DISCORD_REST_TIMEOUT_MS } from "./send.shared-BmwFjW6T.js";
|
|
6
|
-
import { _ as resolveDiscordModalEntryWithPersistence, g as resolveDiscordComponentEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-iJyFXw9L.js";
|
|
1
|
+
import { A as ThreadUpdateListener, C as MessageCreateListener, D as ReadyListener, E as PresenceUpdateListener, G as User, H as CommandWithSubcommands, I as RateLimitError, K as hasDiscordV2Components, M as Client, N as Plugin, S as InteractionCreateListener, T as MessageReactionRemoveListener, U as Guild, V as Command, W as Message, Z as Modal, a as chunkDiscordTextWithMode, b as GuildCreateListener, ct as Row, dt as StringSelectMenu, et as Button, ft as TextDisplay, ht as BaseMessageInteractiveComponent, k as ThreadDeleteListener, nt as Container, ut as Separator, w as MessageReactionAddListener, x as GuildDeleteListener, y as discord_exports } from "./retry-Cv4jCU5Z.js";
|
|
2
|
+
import { C as parseDiscordComponentCustomId, D as decodeCustomIdComponent, E as parseDiscordModalCustomIdForInteraction, O as encodeCustomIdComponent, S as parseDiscordActivityCustomIdForInteraction, T as parseDiscordModalCustomId, c as parseExecApprovalData, o as parseDiscordQuestionData, v as buildDiscordActivityCustomId, w as parseDiscordComponentCustomIdForInteraction } from "./components-B9V5o361.js";
|
|
3
|
+
import { c as resolveDiscordAccount, f as resolveDiscordAccountDmPolicy, l as resolveDiscordAccountAllowFrom, m as normalizeDiscordToken, p as resolveDiscordMaxLinesPerMessage } from "./accounts-CfQ-vSyf.js";
|
|
4
|
+
import { a as resolveDiscordComponentEntryWithPersistence, o as resolveDiscordModalEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-DKKAw5VX.js";
|
|
7
5
|
import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
|
|
8
6
|
import { a as isDiscordRateLimitResponseBody, o as summarizeDiscordResponseBody } from "./api-DNVbJyEy.js";
|
|
9
|
-
import { C as resolveTimestampMs, a as normalizeDiscordSlug, b as formatDiscordReactionEmoji, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordCommandOwnerAllowFrom, f as resolveDiscordGuildEntry, g as resolveDiscordOwnerAllowFrom, h as resolveDiscordOwnerAccess, i as normalizeDiscordDisplaySlug, l as resolveDiscordChannelPolicyCommandAuthorizer, m as resolveDiscordMemberAllowed, n as isDiscordGroupAllowedByPolicy, o as resolveDiscordAllowListMatch, p as resolveDiscordMemberAccessState, r as normalizeDiscordAllowList,
|
|
10
|
-
import {
|
|
7
|
+
import { C as resolveTimestampMs, a as normalizeDiscordSlug, b as formatDiscordReactionEmoji, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordCommandOwnerAllowFrom, f as resolveDiscordGuildEntry, g as resolveDiscordOwnerAllowFrom, h as resolveDiscordOwnerAccess, i as normalizeDiscordDisplaySlug, l as resolveDiscordChannelPolicyCommandAuthorizer, m as resolveDiscordMemberAllowed, n as isDiscordGroupAllowedByPolicy, o as resolveDiscordAllowListMatch, p as resolveDiscordMemberAccessState, r as normalizeDiscordAllowList, v as resolveGroupDmAllow, x as formatDiscordUserTag, y as shouldEmitDiscordReactionNotification } from "./allow-list-BDMimASD.js";
|
|
8
|
+
import { B as validateDiscordProxyUrl, G as unregisterGateway, P as createDiscordRestClient, R as DISCORD_REST_TIMEOUT_MS, V as withValidatedDiscordProxy, W as registerGateway, b as canViewDiscordGuildChannel } from "./send.shared-JjljcV4O.js";
|
|
9
|
+
import { a as formatMention, t as sendMessageDiscord } from "./send.outbound-zam0TrZx.js";
|
|
10
|
+
import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
|
|
11
|
+
import { n as getDiscordActivitiesRuntime } from "./runtime-CY4PRMF-.js";
|
|
12
|
+
import { n as resolveDiscordVoiceEnabled, r as authorizeDiscordVoiceIngress, t as resolveDiscordVoiceAccess } from "./owner-access-UlYi9t0M.js";
|
|
11
13
|
import { i as setPresence, t as clearPresences } from "./presence-cache-z1N8MbJ3.js";
|
|
12
|
-
import {
|
|
14
|
+
import { s as sendVoiceMessageDiscord } from "./send-C49MFF9j.js";
|
|
13
15
|
import { c as raceWithTimeout, u as withAbortTimeout } from "./timeouts-B9cy6RvQ.js";
|
|
14
|
-
import {
|
|
15
|
-
import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-
|
|
16
|
-
import { t as resolveDiscordUserAllowlist } from "./resolve-users-
|
|
17
|
-
import { a as isThreadArchived, c as resolveDiscordChannelInfoSafe,
|
|
18
|
-
import { a as probeDiscordApplicationId, r as parseApplicationIdFromToken } from "./probe-
|
|
16
|
+
import { S as isDiscordExecApprovalClientEnabled, b as getDiscordExecApprovalApprovers, c as resolveDiscordEffectiveRoute, i as buildDiscordConversationRouteContext, n as DISCORD_APPROVAL_ALLOWED_MENTIONS, o as resolveDiscordBoundConversationRoute, r as formatDiscordApprovalDisplayValue, u as resolveDiscordConversationIdentity } from "./outbound-session-route-Cg15ZFJd.js";
|
|
17
|
+
import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-C2sT_n67.js";
|
|
18
|
+
import { t as resolveDiscordUserAllowlist } from "./resolve-users-CzpjLwjy.js";
|
|
19
|
+
import { a as isThreadArchived, c as resolveDiscordChannelInfoSafe, f as resolveDiscordChannelTopicSafe, h as formatThreadBindingDurationLabel, l as resolveDiscordChannelNameSafe, r as getThreadBindingManager, s as resolveDiscordChannelIdSafe, u as resolveDiscordChannelParentIdSafe } from "./thread-bindings.manager-ByOtwjo_.js";
|
|
20
|
+
import { a as probeDiscordApplicationId, r as parseApplicationIdFromToken } from "./probe-n6ZXxK8V.js";
|
|
19
21
|
import { i as sanitizeRecentModels, n as normalizeModelRef, r as preferenceTimestampMs, t as buildPreferenceModelKey } from "./model-picker-preference-primitives-BHT1LkR_.js";
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { buildAgentSessionKey, deriveLastRoutePolicy, isAcpSessionKey, isSubagentSessionKey, parseAgentSessionKey, resolveAgentIdFromSessionKey, resolveAgentRoute } from "openclaw/plugin-sdk/routing";
|
|
24
|
-
import { asFiniteNumber, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, normalizeStringEntries, parseFiniteNumber, parseStrictNonNegativeInteger, summarizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
25
|
-
import { getRuntimeConfig, getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
|
|
22
|
+
import { f as resolveDiscordChannelInfo, u as resolveDiscordMessageStickers } from "./message-text-aiwO5R2F.js";
|
|
23
|
+
import { i as resolveDiscordThreadParentInfo } from "./threading-agH1T_6s.js";
|
|
24
|
+
import { t as resolveDiscordSenderIdentity } from "./sender-identity-BJtfyise.js";
|
|
26
25
|
import { logDebug, logError } from "openclaw/plugin-sdk/logging-core";
|
|
27
26
|
import { ApplicationCommandOptionType, ButtonStyle, ChannelType, ComponentType, GatewayCloseCodes, GatewayCloseCodes as GatewayCloseCodes$1, GatewayDispatchEvents, GatewayIntentBits, GatewayOpcodes } from "discord-api-types/v10";
|
|
28
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
29
|
-
import { MAX_DATE_TIMESTAMP_MS, asDateTimestampMs, parseFiniteNumber as parseFiniteNumber$1, parseStrictInteger, parseStrictPositiveInteger, resolveDateTimestampMs, resolveTimestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
30
|
-
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
31
27
|
import { Type } from "typebox";
|
|
32
28
|
import { Check, Errors } from "typebox/value";
|
|
29
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
30
|
+
import { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, asDateTimestampMs, asSafeIntegerInRange, parseFiniteNumber, parseStrictInteger, parseStrictPositiveInteger, resolveDateTimestampMs, resolveTimestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
31
|
+
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
33
32
|
import { inspect } from "node:util";
|
|
34
33
|
import { readResponseWithLimit } from "openclaw/plugin-sdk/response-limit-runtime";
|
|
35
34
|
import { PlatformMessageNotDispatchedError, formatErrorMessage, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
|
|
36
35
|
import { fetchWithSsrFGuard, formatErrorMessage as formatErrorMessage$1 } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
36
|
+
import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
37
|
+
import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
|
|
38
|
+
import { asFiniteNumber, asOptionalRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, parseFiniteNumber as parseFiniteNumber$1, parseStrictNonNegativeInteger as parseStrictNonNegativeInteger$1, summarizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
39
|
+
import { getRuntimeConfig, getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
|
|
37
40
|
import { createHttp1EnvHttpProxyAgent, createHttp1ProxyAgent, createNodeProxyAgent, resolveEnvHttpProxyAgentOptions, wrapFetchWithAbortSignal } from "openclaw/plugin-sdk/fetch-runtime";
|
|
38
41
|
import { createNonExitingRuntime, createSubsystemLogger, danger, formatDurationSeconds, isVerbose, logVerbose, shouldLogVerbose, sleepWithAbort, warn } from "openclaw/plugin-sdk/runtime-env";
|
|
39
42
|
import { sliceUtf16Safe, truncateUtf16Safe, withTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
@@ -41,33 +44,31 @@ import { addAllowlistUserEntriesFromConfigEntry, buildAllowlistResolutionSummary
|
|
|
41
44
|
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
42
45
|
import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
|
|
43
46
|
import { chunkItems, findCodeRegions, sanitizeAssistantVisibleText, sanitizeAssistantVisibleTextWithProfile } from "openclaw/plugin-sdk/text-chunking";
|
|
44
|
-
import { createReplyReferencePlanner } from "openclaw/plugin-sdk/reply-reference";
|
|
45
47
|
import { buildOutboundSessionContext, listMessageReceiptPlatformIds, resolveChannelStreamingBlockEnabled, sendDurableMessageBatch } from "openclaw/plugin-sdk/channel-outbound";
|
|
46
48
|
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
|
|
47
49
|
import { resolveSendableOutboundReplyParts, resolveTextChunksWithFallback } from "openclaw/plugin-sdk/reply-payload";
|
|
48
50
|
import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
|
|
49
51
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
50
|
-
import {
|
|
52
|
+
import { buildCommandTextFromArgs, findCommandByNativeName, formatCommandArgMenuTitle, listChatCommands, listNativeCommandSpecsForConfig, listSkillCommandsForAgents, resolveCommandAuthorizedFromAuthorizers, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverride, serializeCommandArgs } from "openclaw/plugin-sdk/command-auth-native";
|
|
51
53
|
import { GROUP_POLICY_BLOCKED_LABEL, resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
54
|
+
import { resolvePinnedMainDmOwnerFromAllowlist as resolvePinnedMainDmOwnerFromAllowlist$1 } from "openclaw/plugin-sdk/security-runtime";
|
|
52
55
|
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
|
|
53
56
|
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
|
54
|
-
import { questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
|
|
55
57
|
import { buildPairingReply, upsertChannelPairingRequest, upsertChannelPairingRequest as upsertChannelPairingRequest$1 } from "openclaw/plugin-sdk/conversation-runtime";
|
|
58
|
+
import * as conversationRuntime from "openclaw/plugin-sdk/conversation-binding-runtime";
|
|
59
|
+
import { questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
|
|
56
60
|
import { clearExpiredCooldowns, ensureAuthProfileStore, formatReasoningMessage, getPreparedModelCatalogSnapshot, isProfileInCooldown, listAgentIds, loadPreparedModelCatalog, resolveAgentAvatar, resolveAgentDir, resolveDefaultModelForAgent, resolveHumanDelayConfig, resolveProfilesUnavailableReason } from "openclaw/plugin-sdk/agent-runtime";
|
|
57
61
|
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
|
|
58
62
|
import { resolveNativeCommandsEnabled, resolveNativeSkillsEnabled } from "openclaw/plugin-sdk/native-command-config-runtime";
|
|
59
63
|
import { requestHeartbeat } from "openclaw/plugin-sdk/heartbeat-runtime";
|
|
60
64
|
import { enqueueRoutedSystemEvent, enqueueRoutedSystemEvent as enqueueRoutedSystemEvent$1 } from "openclaw/plugin-sdk/system-event-runtime";
|
|
65
|
+
import { deleteSessionEntry, getSessionEntry, listSessionEntries, readSessionUpdatedAt as readSessionUpdatedAt$1, resolveStorePath, resolveStorePath as resolveStorePath$1 } from "openclaw/plugin-sdk/session-store-runtime";
|
|
61
66
|
import { createChannelIngressResolver, defineStableChannelIngressIdentity, readChannelIngressStoreAllowFromForDmPolicy } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
67
|
+
import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-dispatch-runtime";
|
|
62
68
|
import { createChannelPartialDeliveryError, dispatchChannelInboundTurn, formatInboundEnvelope, hasVisibleInboundReplyDispatch, isChannelPartialDeliveryError, resolveEnvelopeFormatOptions, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent } from "openclaw/plugin-sdk/channel-inbound";
|
|
63
|
-
import { resolveChannelModelOverride } from "openclaw/plugin-sdk/model-session-runtime";
|
|
64
|
-
import { finalizeInboundContext, generateConversationLabel } from "openclaw/plugin-sdk/reply-dispatch-runtime";
|
|
65
|
-
import { deleteSessionEntry, getSessionEntry, listSessionEntries, readSessionUpdatedAt as readSessionUpdatedAt$1, resolveStorePath, resolveStorePath as resolveStorePath$1 } from "openclaw/plugin-sdk/session-store-runtime";
|
|
66
|
-
import { buildCommandTextFromArgs, findCommandByNativeName, formatCommandArgMenuTitle, listChatCommands, listNativeCommandSpecsForConfig, listSkillCommandsForAgents, resolveCommandAuthorizedFromAuthorizers, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverride, serializeCommandArgs } from "openclaw/plugin-sdk/command-auth-native";
|
|
67
69
|
import { buildCommandTextFromArgs as buildCommandTextFromArgs$1, findCommandByNativeName as findCommandByNativeName$1, mergeNativeCommandSpecs, parseCommandArgs, resolveCommandArgChoices, resolveCommandArgMenu, serializeCommandArgs as serializeCommandArgs$1 } from "openclaw/plugin-sdk/native-command-registry";
|
|
68
70
|
import { PLUGIN_COMMAND_DISPATCH } from "openclaw/plugin-sdk/plugin-command-runtime";
|
|
69
71
|
import { resolveDirectStatusReplyForSession } from "openclaw/plugin-sdk/command-status-runtime";
|
|
70
|
-
import * as conversationRuntime from "openclaw/plugin-sdk/conversation-binding-runtime";
|
|
71
72
|
import { normalizeProviderId } from "openclaw/plugin-sdk/provider-model-shared";
|
|
72
73
|
import { EventEmitter } from "node:events";
|
|
73
74
|
import * as ws from "ws";
|
|
@@ -140,6 +141,205 @@ async function runDiscordListenerWithSlowLog(params) {
|
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
143
|
//#endregion
|
|
144
|
+
//#region extensions/discord/src/monitor/presence-events.ts
|
|
145
|
+
const DISCORD_PRESENCE_GREETING_COOLDOWN_MS = 480 * 60 * 1e3;
|
|
146
|
+
function isDiscordOnlineStatus(status) {
|
|
147
|
+
return status === "online" || status === "idle" || status === "dnd";
|
|
148
|
+
}
|
|
149
|
+
function isDiscordOfflineStatus(status) {
|
|
150
|
+
return status === "offline";
|
|
151
|
+
}
|
|
152
|
+
function resolveDiscordOnlinePresenceEvent(params) {
|
|
153
|
+
const config = params.config;
|
|
154
|
+
const userId = params.data.user?.id?.trim();
|
|
155
|
+
if (!config || config.enabled === false || !userId || userId === params.botUserId || params.data.user.bot === true || !isDiscordOnlineStatus(params.data.status) || !params.availabilityKind) return null;
|
|
156
|
+
if (config.users !== void 0 && !config.users.includes(userId)) return null;
|
|
157
|
+
if (params.lastEmittedAtMs !== void 0 && params.nowMs - params.lastEmittedAtMs < 288e5) return null;
|
|
158
|
+
const lines = [
|
|
159
|
+
"Discord online-presence event:",
|
|
160
|
+
params.availabilityKind === "observed-offline" ? `A human member became available online after being observed offline in guild_id=${JSON.stringify(params.data.guild_id)} user_id=${JSON.stringify(userId)} status=${JSON.stringify(params.data.status)}.` : `A human member became newly visible online since the current guild snapshot in guild_id=${JSON.stringify(params.data.guild_id)} user_id=${JSON.stringify(userId)} status=${JSON.stringify(params.data.status)}. They may have come online or joined after the snapshot; do not claim an exact prior status.`,
|
|
161
|
+
`The authorized greeting target is channel_id=${JSON.stringify(config.channelId)}.`,
|
|
162
|
+
"Before greeting, retrieve relevant memory and wiki context for this immutable user_id, including a known timezone when available. Use their local time for the greeting; if their timezone is unknown, do not guess.",
|
|
163
|
+
"Send at most one short, natural greeting to the target channel. Do not reveal private memory. If no greeting is appropriate, stay silent."
|
|
164
|
+
];
|
|
165
|
+
return {
|
|
166
|
+
channelId: config.channelId,
|
|
167
|
+
userId,
|
|
168
|
+
text: lines.join("\n")
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region extensions/discord/src/monitor/presence-cooldown-store.ts
|
|
173
|
+
const DISCORD_PRESENCE_COOLDOWN_MAX_ENTRIES = 25e3;
|
|
174
|
+
function openDiscordPresenceCooldownStore() {
|
|
175
|
+
return getDiscordRuntime().state.openSyncKeyedStore({
|
|
176
|
+
namespace: "presence-greeting-cooldowns",
|
|
177
|
+
maxEntries: DISCORD_PRESENCE_COOLDOWN_MAX_ENTRIES,
|
|
178
|
+
overflowPolicy: "reject-new",
|
|
179
|
+
defaultTtlMs: DISCORD_PRESENCE_GREETING_COOLDOWN_MS
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region extensions/discord/src/monitor/presence-emission-gate.ts
|
|
184
|
+
const DISCORD_PRESENCE_RECONNECT_SUPPRESS_MS = 300 * 1e3;
|
|
185
|
+
const DISCORD_PRESENCE_BURST_LIMIT = 8;
|
|
186
|
+
const DISCORD_PRESENCE_BURST_WINDOW_MS = 60 * 1e3;
|
|
187
|
+
function resolveDiscordPresenceGateOptions(config) {
|
|
188
|
+
return {
|
|
189
|
+
reconnectSuppressMs: config?.reconnectSuppressSeconds !== void 0 ? config.reconnectSuppressSeconds * 1e3 : DISCORD_PRESENCE_RECONNECT_SUPPRESS_MS,
|
|
190
|
+
burstLimit: config?.burstLimit ?? DISCORD_PRESENCE_BURST_LIMIT,
|
|
191
|
+
burstWindowMs: config?.burstWindowSeconds !== void 0 ? config.burstWindowSeconds * 1e3 : DISCORD_PRESENCE_BURST_WINDOW_MS
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Per-account lifecycle gate for online-presence events. Reconnect state belongs to the Gateway
|
|
196
|
+
* session, while burst state follows the guild-owned configuration that supplies its limits.
|
|
197
|
+
*/
|
|
198
|
+
var DiscordPresenceEmissionGate = class {
|
|
199
|
+
constructor() {
|
|
200
|
+
this.reconnectLogged = false;
|
|
201
|
+
this.burstByGuild = /* @__PURE__ */ new Map();
|
|
202
|
+
this.nextReservationId = 0;
|
|
203
|
+
}
|
|
204
|
+
noteGatewaySessionReset(nowMs) {
|
|
205
|
+
this.lastSessionResetAtMs = nowMs;
|
|
206
|
+
this.reconnectLogged = false;
|
|
207
|
+
}
|
|
208
|
+
evaluateReconnectWindow(nowMs, options) {
|
|
209
|
+
if (this.lastSessionResetAtMs !== void 0 && options.reconnectSuppressMs > 0 && nowMs - this.lastSessionResetAtMs < options.reconnectSuppressMs) {
|
|
210
|
+
const shouldLog = !this.reconnectLogged;
|
|
211
|
+
this.reconnectLogged = true;
|
|
212
|
+
return {
|
|
213
|
+
allowed: false,
|
|
214
|
+
reason: "reconnect-window",
|
|
215
|
+
shouldLog
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
return { allowed: true };
|
|
219
|
+
}
|
|
220
|
+
reserveBurst(guildId, nowMs, options) {
|
|
221
|
+
const state = this.burstByGuild.get(guildId) ?? {
|
|
222
|
+
reservations: [],
|
|
223
|
+
logged: false
|
|
224
|
+
};
|
|
225
|
+
state.reservations = state.reservations.filter((reservation) => !reservation.committed || nowMs - reservation.atMs < options.burstWindowMs);
|
|
226
|
+
this.burstByGuild.set(guildId, state);
|
|
227
|
+
if (state.reservations.length >= options.burstLimit) {
|
|
228
|
+
const shouldLog = !state.logged;
|
|
229
|
+
state.logged = true;
|
|
230
|
+
return {
|
|
231
|
+
allowed: false,
|
|
232
|
+
reason: state.reservations.some((reservation) => !reservation.committed) ? "burst-pending" : "burst",
|
|
233
|
+
shouldLog
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
state.logged = false;
|
|
237
|
+
const reservation = {
|
|
238
|
+
id: this.nextReservationId++,
|
|
239
|
+
atMs: nowMs,
|
|
240
|
+
committed: false
|
|
241
|
+
};
|
|
242
|
+
state.reservations.push(reservation);
|
|
243
|
+
return {
|
|
244
|
+
allowed: true,
|
|
245
|
+
reservation: reservation.id
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
commitBurst(guildId, reservation, nowMs) {
|
|
249
|
+
const entry = this.burstByGuild.get(guildId)?.reservations.find((candidate) => candidate.id === reservation);
|
|
250
|
+
if (!entry) return;
|
|
251
|
+
entry.atMs = nowMs;
|
|
252
|
+
entry.committed = true;
|
|
253
|
+
}
|
|
254
|
+
releaseBurst(guildId, reservation) {
|
|
255
|
+
const state = this.burstByGuild.get(guildId);
|
|
256
|
+
if (!state) return;
|
|
257
|
+
state.reservations = state.reservations.filter((candidate) => candidate.id !== reservation);
|
|
258
|
+
if (state.reservations.length === 0 && !state.logged) this.burstByGuild.delete(guildId);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
//#endregion
|
|
262
|
+
//#region extensions/discord/src/monitor/presence-transition-cache.ts
|
|
263
|
+
const DEFAULT_PRESENCE_BASELINE_MAX_ENTRIES = 75e3;
|
|
264
|
+
var DiscordPresenceBaselineCache = class {
|
|
265
|
+
constructor(maxEntries = DEFAULT_PRESENCE_BASELINE_MAX_ENTRIES) {
|
|
266
|
+
this.maxEntries = maxEntries;
|
|
267
|
+
this.offlineByKey = /* @__PURE__ */ new Map();
|
|
268
|
+
this.onlineByKey = /* @__PURE__ */ new Map();
|
|
269
|
+
}
|
|
270
|
+
clear() {
|
|
271
|
+
this.offlineByKey.clear();
|
|
272
|
+
this.onlineByKey.clear();
|
|
273
|
+
}
|
|
274
|
+
clearScope(scope) {
|
|
275
|
+
for (const markers of [this.offlineByKey, this.onlineByKey]) for (const [key, markerScope] of markers) if (markerScope === scope) markers.delete(key);
|
|
276
|
+
}
|
|
277
|
+
isOffline(scope, key) {
|
|
278
|
+
return this.offlineByKey.get(key) === scope;
|
|
279
|
+
}
|
|
280
|
+
isOnline(scope, key) {
|
|
281
|
+
return this.onlineByKey.get(key) === scope;
|
|
282
|
+
}
|
|
283
|
+
observeOffline(scope, key) {
|
|
284
|
+
this.deleteMarker(this.onlineByKey, scope, key);
|
|
285
|
+
return this.observe(this.offlineByKey, scope, key);
|
|
286
|
+
}
|
|
287
|
+
observeOnline(scope, key) {
|
|
288
|
+
this.deleteMarker(this.offlineByKey, scope, key);
|
|
289
|
+
return this.observe(this.onlineByKey, scope, key);
|
|
290
|
+
}
|
|
291
|
+
deleteMarker(markers, scope, key) {
|
|
292
|
+
if (markers.get(key) === scope) markers.delete(key);
|
|
293
|
+
}
|
|
294
|
+
observe(markers, scope, key) {
|
|
295
|
+
markers.delete(key);
|
|
296
|
+
markers.set(key, scope);
|
|
297
|
+
let evictedScope;
|
|
298
|
+
while (markers.size > this.maxEntries) {
|
|
299
|
+
const oldestKey = markers.keys().next().value;
|
|
300
|
+
if (oldestKey === void 0) break;
|
|
301
|
+
evictedScope = markers.get(oldestKey);
|
|
302
|
+
markers.delete(oldestKey);
|
|
303
|
+
}
|
|
304
|
+
return evictedScope;
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
//#endregion
|
|
308
|
+
//#region extensions/discord/src/monitor/thread-session-close.ts
|
|
309
|
+
/**
|
|
310
|
+
* Closes every session entry in the store whose key contains {@link threadId}.
|
|
311
|
+
* The explicit lifecycle deletion archives the old transcript and guarantees
|
|
312
|
+
* that a later inbound message starts a fresh session in every reset mode.
|
|
313
|
+
*/
|
|
314
|
+
async function closeDiscordThreadSessions(params) {
|
|
315
|
+
const { cfg, threadId } = params;
|
|
316
|
+
const normalizedThreadId = normalizeOptionalLowercaseString(threadId) ?? "";
|
|
317
|
+
if (!normalizedThreadId) return 0;
|
|
318
|
+
const segmentRe = new RegExp(`:${normalizedThreadId}(?::|$)`, "i");
|
|
319
|
+
function sessionKeyContainsThreadId(key) {
|
|
320
|
+
return segmentRe.test(key);
|
|
321
|
+
}
|
|
322
|
+
let resetCount = 0;
|
|
323
|
+
for (const agentId of listAgentIds(cfg)) {
|
|
324
|
+
const storePath = resolveStorePath(cfg.session?.store, { agentId });
|
|
325
|
+
for (const { sessionKey, entry } of listSessionEntries({
|
|
326
|
+
agentId,
|
|
327
|
+
storePath,
|
|
328
|
+
readOnly: true
|
|
329
|
+
})) {
|
|
330
|
+
if (!sessionKeyContainsThreadId(sessionKey)) continue;
|
|
331
|
+
if (await deleteSessionEntry({
|
|
332
|
+
archiveTranscript: true,
|
|
333
|
+
expectedSessionId: entry.sessionId ?? null,
|
|
334
|
+
expectedUpdatedAt: entry.updatedAt,
|
|
335
|
+
sessionKey,
|
|
336
|
+
storePath
|
|
337
|
+
})) resetCount += 1;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return resetCount;
|
|
341
|
+
}
|
|
342
|
+
//#endregion
|
|
143
343
|
//#region extensions/discord/src/monitor/dm-command-auth.ts
|
|
144
344
|
const DISCORD_ALLOW_LIST_PREFIXES = [
|
|
145
345
|
"discord:",
|
|
@@ -305,474 +505,16 @@ async function resolveDiscordTextCommandAccess(params) {
|
|
|
305
505
|
});
|
|
306
506
|
}
|
|
307
507
|
//#endregion
|
|
308
|
-
//#region extensions/discord/src/monitor/thread-
|
|
309
|
-
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
const MAX_THREAD_TITLE_CHANNEL_DESCRIPTION_CHARS = 320;
|
|
313
|
-
const DISCORD_THREAD_TITLE_SYSTEM_PROMPT = "Generate a concise Discord thread title (3-6 words). Return only the title. Use channel context when provided and avoid redundant channel-name words unless needed for clarity.";
|
|
314
|
-
async function generateThreadTitle(params) {
|
|
315
|
-
const sourceText = params.messageText.trim();
|
|
316
|
-
if (!sourceText) return null;
|
|
317
|
-
try {
|
|
318
|
-
const userMessage = buildThreadTitleCompletionUserMessage({
|
|
319
|
-
sourceText,
|
|
320
|
-
channelName: params.channelName,
|
|
321
|
-
channelDescription: params.channelDescription
|
|
322
|
-
});
|
|
323
|
-
const timeoutMs = resolveThreadTitleTimeoutMs(params.timeoutMs);
|
|
324
|
-
const generated = await generateConversationLabel({
|
|
325
|
-
cfg: params.cfg,
|
|
326
|
-
agentId: params.agentId,
|
|
327
|
-
userMessage,
|
|
328
|
-
prompt: DISCORD_THREAD_TITLE_SYSTEM_PROMPT,
|
|
329
|
-
...params.modelRef ? { modelRef: params.modelRef } : {},
|
|
330
|
-
timeoutMs,
|
|
331
|
-
maxLength: MAX_THREAD_TITLE_SOURCE_CHARS
|
|
332
|
-
});
|
|
333
|
-
return generated ? normalizeGeneratedThreadTitle(generated) : null;
|
|
334
|
-
} catch (err) {
|
|
335
|
-
logVerbose(`thread-title: title generation failed for agent ${params.agentId}: ${String(err)}`);
|
|
336
|
-
return null;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
function buildThreadTitleCompletionUserMessage(params) {
|
|
340
|
-
const sourceText = truncateThreadTitleSourceText(params.sourceText);
|
|
341
|
-
const channelName = normalizeTitleContextField(params.channelName, MAX_THREAD_TITLE_CHANNEL_NAME_CHARS);
|
|
342
|
-
const channelDescription = normalizeTitleContextField(params.channelDescription, MAX_THREAD_TITLE_CHANNEL_DESCRIPTION_CHARS);
|
|
343
|
-
const messageLines = [];
|
|
344
|
-
if (channelName) messageLines.push(`Channel: ${channelName}`);
|
|
345
|
-
if (channelDescription) messageLines.push(`Channel description: ${channelDescription}`);
|
|
346
|
-
messageLines.push(`Message:\n${sourceText}`);
|
|
347
|
-
return messageLines.join("\n\n");
|
|
348
|
-
}
|
|
349
|
-
function truncateThreadTitleSourceText(sourceText) {
|
|
350
|
-
if (sourceText.length <= MAX_THREAD_TITLE_SOURCE_CHARS) return sourceText;
|
|
351
|
-
return `${truncateUtf16Safe(sourceText, MAX_THREAD_TITLE_SOURCE_CHARS)}...`;
|
|
352
|
-
}
|
|
353
|
-
function resolveThreadTitleTimeoutMs(timeoutMs) {
|
|
354
|
-
return Math.max(100, Math.floor(timeoutMs ?? DEFAULT_THREAD_TITLE_TIMEOUT_MS));
|
|
355
|
-
}
|
|
356
|
-
function normalizeGeneratedThreadTitle(raw) {
|
|
357
|
-
const lines = raw.replace(/\r/g, "").split("\n");
|
|
358
|
-
let firstLine = "";
|
|
359
|
-
for (const line of lines) {
|
|
360
|
-
const trimmed = line.trim();
|
|
361
|
-
if (!trimmed) continue;
|
|
362
|
-
if (!firstLine && trimmed.startsWith("```")) continue;
|
|
363
|
-
firstLine = trimmed;
|
|
364
|
-
break;
|
|
365
|
-
}
|
|
366
|
-
return stripThreadTitleWrappers(firstLine);
|
|
367
|
-
}
|
|
368
|
-
function stripThreadTitleWrappers(raw) {
|
|
369
|
-
let current = raw.trim();
|
|
370
|
-
let previous = "";
|
|
371
|
-
while (current && current !== previous) {
|
|
372
|
-
previous = current;
|
|
373
|
-
current = current.replace(/^["'`]+|["'`]+$/g, "").trim();
|
|
374
|
-
current = stripBalancedWrapper(current, "**");
|
|
375
|
-
current = stripBalancedWrapper(current, "__");
|
|
376
|
-
current = stripBalancedWrapper(current, "*");
|
|
377
|
-
current = stripBalancedWrapper(current, "_");
|
|
378
|
-
current = stripBalancedWrapper(current, "~~");
|
|
379
|
-
}
|
|
380
|
-
return current;
|
|
381
|
-
}
|
|
382
|
-
function stripBalancedWrapper(text, marker) {
|
|
383
|
-
if (text.length < marker.length * 2 + 1) return text;
|
|
384
|
-
if (!text.startsWith(marker) || !text.endsWith(marker)) return text;
|
|
385
|
-
const inner = text.slice(marker.length, text.length - marker.length);
|
|
386
|
-
if (!inner || inner.includes(marker)) return text;
|
|
387
|
-
return inner;
|
|
388
|
-
}
|
|
389
|
-
function normalizeTitleContextField(raw, maxChars) {
|
|
390
|
-
const value = raw?.trim();
|
|
391
|
-
if (!value) return;
|
|
392
|
-
const singleLine = value.replace(/\s+/g, " ");
|
|
393
|
-
if (singleLine.length <= maxChars) return singleLine;
|
|
394
|
-
return `${truncateUtf16Safe(singleLine, maxChars)}...`;
|
|
395
|
-
}
|
|
396
|
-
//#endregion
|
|
397
|
-
//#region extensions/discord/src/monitor/threading.cache.ts
|
|
398
|
-
const DISCORD_THREAD_STARTER_CACHE_TTL_MS = 300 * 1e3;
|
|
399
|
-
const DISCORD_THREAD_STARTER_CACHE_MAX = 500;
|
|
400
|
-
const DISCORD_THREAD_STARTER_CACHE = /* @__PURE__ */ new Map();
|
|
401
|
-
function resetDiscordThreadStarterCacheForTest() {
|
|
402
|
-
DISCORD_THREAD_STARTER_CACHE.clear();
|
|
403
|
-
}
|
|
404
|
-
function getCachedThreadStarter(key, now) {
|
|
405
|
-
const entry = DISCORD_THREAD_STARTER_CACHE.get(key);
|
|
406
|
-
if (!entry) return;
|
|
407
|
-
if (now - entry.updatedAt > DISCORD_THREAD_STARTER_CACHE_TTL_MS) {
|
|
408
|
-
DISCORD_THREAD_STARTER_CACHE.delete(key);
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
DISCORD_THREAD_STARTER_CACHE.delete(key);
|
|
412
|
-
DISCORD_THREAD_STARTER_CACHE.set(key, {
|
|
413
|
-
...entry,
|
|
414
|
-
updatedAt: now
|
|
415
|
-
});
|
|
416
|
-
return entry.value;
|
|
417
|
-
}
|
|
418
|
-
function setCachedThreadStarter(key, value, now) {
|
|
419
|
-
DISCORD_THREAD_STARTER_CACHE.delete(key);
|
|
420
|
-
DISCORD_THREAD_STARTER_CACHE.set(key, {
|
|
421
|
-
value,
|
|
422
|
-
updatedAt: now
|
|
423
|
-
});
|
|
424
|
-
while (DISCORD_THREAD_STARTER_CACHE.size > DISCORD_THREAD_STARTER_CACHE_MAX) {
|
|
425
|
-
const iter = DISCORD_THREAD_STARTER_CACHE.keys().next();
|
|
426
|
-
if (iter.done) break;
|
|
427
|
-
DISCORD_THREAD_STARTER_CACHE.delete(iter.value);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
//#endregion
|
|
431
|
-
//#region extensions/discord/src/monitor/threading.starter.ts
|
|
432
|
-
function isDiscordThreadType(type) {
|
|
433
|
-
return type === discord_exports.ChannelType.PublicThread || type === discord_exports.ChannelType.PrivateThread || type === discord_exports.ChannelType.AnnouncementThread;
|
|
434
|
-
}
|
|
435
|
-
function isDiscordForumParentType(parentType) {
|
|
436
|
-
return parentType === discord_exports.ChannelType.GuildForum || parentType === discord_exports.ChannelType.GuildMedia;
|
|
437
|
-
}
|
|
438
|
-
function resolveDiscordThreadChannel(params) {
|
|
439
|
-
if (!params.isGuildMessage) return null;
|
|
440
|
-
const { message, channelInfo } = params;
|
|
441
|
-
const channel = "channel" in message ? message.channel : void 0;
|
|
442
|
-
if (channel && typeof channel === "object" && "isThread" in channel && typeof channel.isThread === "function" && channel.isThread()) return channel;
|
|
443
|
-
if (!isDiscordThreadType(channelInfo?.type)) return null;
|
|
444
|
-
const messageChannelId = params.messageChannelId || resolveDiscordMessageChannelId({ message });
|
|
445
|
-
if (!messageChannelId) return null;
|
|
446
|
-
return {
|
|
447
|
-
id: messageChannelId,
|
|
448
|
-
name: channelInfo?.name ?? void 0,
|
|
449
|
-
parentId: channelInfo?.parentId ?? void 0,
|
|
450
|
-
parent: void 0,
|
|
451
|
-
ownerId: channelInfo?.ownerId ?? void 0
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
async function resolveDiscordThreadParentInfo(params) {
|
|
455
|
-
const { threadChannel, channelInfo, client } = params;
|
|
456
|
-
const parent = resolveDiscordChannelParentSafe(threadChannel);
|
|
457
|
-
let parentId = resolveDiscordChannelParentIdSafe(threadChannel) ?? resolveDiscordChannelIdSafe(parent) ?? channelInfo?.parentId ?? void 0;
|
|
458
|
-
if (!parentId && threadChannel.id) parentId = (await resolveDiscordChannelInfo(client, threadChannel.id))?.parentId ?? void 0;
|
|
459
|
-
if (!parentId) return {};
|
|
460
|
-
let parentName = resolveDiscordChannelNameSafe(parent);
|
|
461
|
-
const parentInfo = await resolveDiscordChannelInfo(client, parentId);
|
|
462
|
-
parentName = parentName ?? parentInfo?.name;
|
|
463
|
-
const parentType = parentInfo?.type;
|
|
508
|
+
//#region extensions/discord/src/monitor/thread-channel-context.ts
|
|
509
|
+
function buildFetchedChannelInfo(channel) {
|
|
510
|
+
const channelInfo = resolveDiscordChannelInfoSafe(channel);
|
|
511
|
+
if (channelInfo.type === void 0) return null;
|
|
464
512
|
return {
|
|
465
|
-
|
|
466
|
-
name:
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
async function resolveDiscordThreadStarter(params) {
|
|
471
|
-
const cacheKey = params.channel.id;
|
|
472
|
-
const cached = getCachedThreadStarter(cacheKey, Date.now());
|
|
473
|
-
if (cached) return cached;
|
|
474
|
-
try {
|
|
475
|
-
const messageChannelId = resolveDiscordThreadStarterMessageChannelId(params);
|
|
476
|
-
if (!messageChannelId) return null;
|
|
477
|
-
const starter = await fetchDiscordThreadStarterMessage({
|
|
478
|
-
client: params.client,
|
|
479
|
-
messageChannelId,
|
|
480
|
-
threadId: params.channel.id
|
|
481
|
-
});
|
|
482
|
-
if (!starter) return null;
|
|
483
|
-
const payload = buildDiscordThreadStarterPayload({
|
|
484
|
-
starter,
|
|
485
|
-
resolveTimestampMs: params.resolveTimestampMs
|
|
486
|
-
});
|
|
487
|
-
if (!payload) return null;
|
|
488
|
-
setCachedThreadStarter(cacheKey, payload, Date.now());
|
|
489
|
-
return payload;
|
|
490
|
-
} catch {
|
|
491
|
-
return null;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
function resolveDiscordThreadStarterMessageChannelId(params) {
|
|
495
|
-
return isDiscordForumParentType(params.parentType) ? params.channel.id : params.parentId;
|
|
496
|
-
}
|
|
497
|
-
async function fetchDiscordThreadStarterMessage(params) {
|
|
498
|
-
const starter = await getChannelMessage(params.client.rest, params.messageChannelId, params.threadId);
|
|
499
|
-
return starter ? starter : null;
|
|
500
|
-
}
|
|
501
|
-
function buildDiscordThreadStarterPayload(params) {
|
|
502
|
-
const text = resolveDiscordThreadStarterText(params.starter);
|
|
503
|
-
if (!text) return null;
|
|
504
|
-
return {
|
|
505
|
-
text,
|
|
506
|
-
...resolveDiscordThreadStarterIdentity(params.starter),
|
|
507
|
-
timestamp: params.resolveTimestampMs(params.starter.timestamp) ?? void 0
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
function resolveDiscordThreadStarterText(starter) {
|
|
511
|
-
const content = normalizeOptionalString(starter.content) ?? "";
|
|
512
|
-
const embedText = resolveDiscordEmbedText(starter.embeds?.[0]);
|
|
513
|
-
const forwardedText = resolveDiscordForwardedMessagesTextFromSnapshots(starter.message_snapshots);
|
|
514
|
-
return [content || embedText || forwardedText, formatDiscordMediaText({
|
|
515
|
-
attachments: starter.attachments ?? void 0,
|
|
516
|
-
stickers: starter.sticker_items ?? void 0
|
|
517
|
-
})].filter(Boolean).join("\n");
|
|
518
|
-
}
|
|
519
|
-
function resolveDiscordThreadStarterIdentity(starter) {
|
|
520
|
-
return {
|
|
521
|
-
author: resolveDiscordThreadStarterAuthor(starter),
|
|
522
|
-
authorId: starter.author?.id ?? void 0,
|
|
523
|
-
authorName: starter.author?.username ?? void 0,
|
|
524
|
-
authorTag: resolveDiscordThreadStarterAuthorTag(starter.author),
|
|
525
|
-
memberRoleIds: resolveDiscordThreadStarterRoleIds(starter.member)
|
|
526
|
-
};
|
|
527
|
-
}
|
|
528
|
-
function resolveDiscordThreadStarterAuthor(starter) {
|
|
529
|
-
return starter.member?.nick ?? starter.member?.displayName ?? resolveDiscordThreadStarterAuthorTag(starter.author) ?? starter.author?.username ?? starter.author?.id ?? "Unknown";
|
|
530
|
-
}
|
|
531
|
-
function resolveDiscordThreadStarterAuthorTag(author) {
|
|
532
|
-
if (!author?.username || !author.discriminator) return;
|
|
533
|
-
if (author.discriminator !== "0") return `${author.username}#${author.discriminator}`;
|
|
534
|
-
return author.username;
|
|
535
|
-
}
|
|
536
|
-
function resolveDiscordThreadStarterRoleIds(member) {
|
|
537
|
-
return Array.isArray(member?.roles) ? member.roles : void 0;
|
|
538
|
-
}
|
|
539
|
-
function resolveDiscordReplyTarget(opts) {
|
|
540
|
-
if (opts.replyToMode === "off") return;
|
|
541
|
-
const replyToId = normalizeOptionalString(opts.replyToId);
|
|
542
|
-
if (!replyToId) return;
|
|
543
|
-
if (opts.replyToMode === "all") return replyToId;
|
|
544
|
-
return opts.hasReplied ? void 0 : replyToId;
|
|
545
|
-
}
|
|
546
|
-
function sanitizeDiscordThreadName(rawName, fallbackId) {
|
|
547
|
-
return truncateUtf16Safe(truncateUtf16Safe(rawName.replace(/<@!?\d+>/g, "").replace(/<@&\d+>/g, "").replace(/<#\d+>/g, "").replace(/\s+/g, " ").trim() || `Thread ${fallbackId}`, 80), 100) || `Thread ${fallbackId}`;
|
|
548
|
-
}
|
|
549
|
-
function resolveDiscordReplyDeliveryPlan(params) {
|
|
550
|
-
const originalReplyTarget = params.replyTarget;
|
|
551
|
-
let deliverTarget = originalReplyTarget;
|
|
552
|
-
let replyTarget = originalReplyTarget;
|
|
553
|
-
if (params.createdThreadId) {
|
|
554
|
-
deliverTarget = `channel:${params.createdThreadId}`;
|
|
555
|
-
replyTarget = deliverTarget;
|
|
556
|
-
}
|
|
557
|
-
const allowReference = deliverTarget === originalReplyTarget;
|
|
558
|
-
const replyReference = createReplyReferencePlanner({
|
|
559
|
-
replyToMode: allowReference ? params.replyToMode : "off",
|
|
560
|
-
existingId: params.threadChannel ? params.messageId : void 0,
|
|
561
|
-
startId: params.messageId,
|
|
562
|
-
allowReference
|
|
563
|
-
});
|
|
564
|
-
return {
|
|
565
|
-
deliverTarget,
|
|
566
|
-
replyTarget,
|
|
567
|
-
replyReference
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
//#endregion
|
|
571
|
-
//#region extensions/discord/src/monitor/threading.auto-thread.ts
|
|
572
|
-
function resolveTrimmedDiscordMessageChannelId(params) {
|
|
573
|
-
return (params.messageChannelId || resolveDiscordMessageChannelId({ message: params.message })).trim();
|
|
574
|
-
}
|
|
575
|
-
function resolveDiscordAutoThreadContext(params) {
|
|
576
|
-
const createdThreadId = normalizeOptionalStringifiedId(params.createdThreadId) ?? "";
|
|
577
|
-
if (!createdThreadId) return null;
|
|
578
|
-
const messageChannelId = normalizeOptionalString(params.messageChannelId) ?? "";
|
|
579
|
-
if (!messageChannelId) return null;
|
|
580
|
-
const threadSessionKey = buildAgentSessionKey({
|
|
581
|
-
agentId: params.agentId,
|
|
582
|
-
channel: params.channel,
|
|
583
|
-
peer: {
|
|
584
|
-
kind: "channel",
|
|
585
|
-
id: createdThreadId
|
|
586
|
-
}
|
|
587
|
-
});
|
|
588
|
-
const parentSessionKey = buildAgentSessionKey({
|
|
589
|
-
agentId: params.agentId,
|
|
590
|
-
channel: params.channel,
|
|
591
|
-
peer: {
|
|
592
|
-
kind: "channel",
|
|
593
|
-
id: messageChannelId
|
|
594
|
-
}
|
|
595
|
-
});
|
|
596
|
-
return {
|
|
597
|
-
createdThreadId,
|
|
598
|
-
From: `${params.channel}:channel:${createdThreadId}`,
|
|
599
|
-
To: `channel:${createdThreadId}`,
|
|
600
|
-
OriginatingTo: `channel:${createdThreadId}`,
|
|
601
|
-
SessionKey: threadSessionKey,
|
|
602
|
-
ModelParentSessionKey: parentSessionKey,
|
|
603
|
-
...params.parentInheritanceEnabled === true ? { ParentSessionKey: parentSessionKey } : {}
|
|
604
|
-
};
|
|
605
|
-
}
|
|
606
|
-
async function resolveDiscordAutoThreadReplyPlan(params) {
|
|
607
|
-
const messageChannelId = resolveTrimmedDiscordMessageChannelId(params);
|
|
608
|
-
const originalReplyTarget = `channel:${params.threadChannel?.id ?? (messageChannelId || "unknown")}`;
|
|
609
|
-
const createdThreadId = await maybeCreateDiscordAutoThread({
|
|
610
|
-
client: params.client,
|
|
611
|
-
message: params.message,
|
|
612
|
-
messageChannelId: messageChannelId || void 0,
|
|
613
|
-
channel: params.channel,
|
|
614
|
-
isGuildMessage: params.isGuildMessage,
|
|
615
|
-
channelConfig: params.channelConfig,
|
|
616
|
-
threadChannel: params.threadChannel,
|
|
617
|
-
channelType: params.channelType,
|
|
618
|
-
channelName: params.channelName,
|
|
619
|
-
channelDescription: params.channelDescription,
|
|
620
|
-
baseText: params.baseText,
|
|
621
|
-
combinedBody: params.combinedBody,
|
|
622
|
-
cfg: params.cfg,
|
|
623
|
-
agentId: params.agentId
|
|
624
|
-
});
|
|
625
|
-
const deliveryPlan = resolveDiscordReplyDeliveryPlan({
|
|
626
|
-
replyTarget: originalReplyTarget,
|
|
627
|
-
replyToMode: params.replyToMode,
|
|
628
|
-
messageId: params.message.id,
|
|
629
|
-
threadChannel: params.threadChannel,
|
|
630
|
-
createdThreadId
|
|
631
|
-
});
|
|
632
|
-
const autoThreadContext = params.isGuildMessage ? resolveDiscordAutoThreadContext({
|
|
633
|
-
agentId: params.agentId,
|
|
634
|
-
channel: params.channel,
|
|
635
|
-
messageChannelId,
|
|
636
|
-
createdThreadId,
|
|
637
|
-
parentInheritanceEnabled: params.threadParentInheritanceEnabled
|
|
638
|
-
}) : null;
|
|
639
|
-
return {
|
|
640
|
-
...deliveryPlan,
|
|
641
|
-
createdThreadId,
|
|
642
|
-
autoThreadContext
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
|
-
async function maybeCreateDiscordAutoThread(params) {
|
|
646
|
-
if (!params.isGuildMessage) return;
|
|
647
|
-
if (!params.channelConfig?.autoThread) return;
|
|
648
|
-
if (params.threadChannel) return;
|
|
649
|
-
if (params.channelType === discord_exports.ChannelType.GuildForum || params.channelType === discord_exports.ChannelType.GuildMedia || params.channelType === discord_exports.ChannelType.GuildVoice || params.channelType === discord_exports.ChannelType.GuildStageVoice) return;
|
|
650
|
-
const messageChannelId = resolveTrimmedDiscordMessageChannelId(params);
|
|
651
|
-
if (!messageChannelId) return;
|
|
652
|
-
try {
|
|
653
|
-
try {
|
|
654
|
-
const existingThreadId = (await getChannelMessage(params.client.rest, messageChannelId, params.message.id))?.thread?.id;
|
|
655
|
-
if (existingThreadId) {
|
|
656
|
-
logVerbose(`discord: autoThread reusing existing thread ${existingThreadId} on ${messageChannelId}/${params.message.id}`);
|
|
657
|
-
return existingThreadId;
|
|
658
|
-
}
|
|
659
|
-
} catch {}
|
|
660
|
-
if (params.message.author?.bot) {
|
|
661
|
-
logVerbose(`discord: autoThread skipped for bot-authored message ${messageChannelId}/${params.message.id}`);
|
|
662
|
-
return;
|
|
663
|
-
}
|
|
664
|
-
const rawThreadSource = params.baseText || params.combinedBody || "Thread";
|
|
665
|
-
const threadName = sanitizeDiscordThreadName(rawThreadSource, params.message.id);
|
|
666
|
-
const archiveDuration = params.channelConfig?.autoArchiveDuration ? Number(params.channelConfig.autoArchiveDuration) : 60;
|
|
667
|
-
const createdId = (await createThread(params.client.rest, messageChannelId, { body: {
|
|
668
|
-
name: threadName,
|
|
669
|
-
auto_archive_duration: archiveDuration
|
|
670
|
-
} }, params.message.id))?.id || "";
|
|
671
|
-
if (createdId && params.channelConfig?.autoThreadName === "generated" && params.cfg && params.agentId) {
|
|
672
|
-
const modelRef = resolveDiscordThreadTitleModelRef({
|
|
673
|
-
cfg: params.cfg,
|
|
674
|
-
channel: params.channel,
|
|
675
|
-
agentId: params.agentId,
|
|
676
|
-
threadId: createdId,
|
|
677
|
-
messageChannelId,
|
|
678
|
-
channelName: params.channelName
|
|
679
|
-
});
|
|
680
|
-
maybeRenameDiscordAutoThread({
|
|
681
|
-
client: params.client,
|
|
682
|
-
threadId: createdId,
|
|
683
|
-
currentName: threadName,
|
|
684
|
-
fallbackId: params.message.id,
|
|
685
|
-
sourceText: rawThreadSource,
|
|
686
|
-
modelRef,
|
|
687
|
-
channelName: params.channelName,
|
|
688
|
-
channelDescription: params.channelDescription,
|
|
689
|
-
cfg: params.cfg,
|
|
690
|
-
agentId: params.agentId
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
return createdId || void 0;
|
|
694
|
-
} catch (err) {
|
|
695
|
-
logVerbose(`discord: autoThread creation failed for ${messageChannelId}/${params.message.id}: ${String(err)}`);
|
|
696
|
-
try {
|
|
697
|
-
const existingThreadId = (await getChannelMessage(params.client.rest, messageChannelId, params.message.id))?.thread?.id || "";
|
|
698
|
-
if (existingThreadId) {
|
|
699
|
-
logVerbose(`discord: autoThread reusing existing thread ${existingThreadId} on ${messageChannelId}/${params.message.id}`);
|
|
700
|
-
return existingThreadId;
|
|
701
|
-
}
|
|
702
|
-
} catch {}
|
|
703
|
-
return;
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
function resolveDiscordThreadTitleModelRef(params) {
|
|
707
|
-
const channel = params.channel?.trim();
|
|
708
|
-
if (!channel) return;
|
|
709
|
-
const parentSessionKey = buildAgentSessionKey({
|
|
710
|
-
agentId: params.agentId,
|
|
711
|
-
channel,
|
|
712
|
-
peer: {
|
|
713
|
-
kind: "channel",
|
|
714
|
-
id: params.messageChannelId
|
|
715
|
-
}
|
|
716
|
-
});
|
|
717
|
-
const channelLabel = params.channelName?.trim();
|
|
718
|
-
const groupChannel = channelLabel ? `#${channelLabel}` : void 0;
|
|
719
|
-
return resolveChannelModelOverride({
|
|
720
|
-
cfg: params.cfg,
|
|
721
|
-
channel,
|
|
722
|
-
groupId: params.threadId,
|
|
723
|
-
groupChatType: "channel",
|
|
724
|
-
groupChannel,
|
|
725
|
-
groupSubject: groupChannel,
|
|
726
|
-
parentSessionKey
|
|
727
|
-
})?.model;
|
|
728
|
-
}
|
|
729
|
-
async function maybeRenameDiscordAutoThread(params) {
|
|
730
|
-
try {
|
|
731
|
-
const fallbackName = sanitizeDiscordThreadName("", params.fallbackId);
|
|
732
|
-
const generated = await generateThreadTitle({
|
|
733
|
-
cfg: params.cfg,
|
|
734
|
-
agentId: params.agentId,
|
|
735
|
-
messageText: params.sourceText,
|
|
736
|
-
modelRef: params.modelRef,
|
|
737
|
-
channelName: params.channelName,
|
|
738
|
-
channelDescription: params.channelDescription
|
|
739
|
-
});
|
|
740
|
-
if (!generated) return;
|
|
741
|
-
const nextName = sanitizeDiscordThreadName(generated, params.fallbackId);
|
|
742
|
-
if (!nextName || nextName === params.currentName || nextName === fallbackName) return;
|
|
743
|
-
await editChannel(params.client.rest, params.threadId, { body: { name: nextName } });
|
|
744
|
-
} catch (err) {
|
|
745
|
-
logVerbose(`discord: autoThread rename failed for ${params.threadId}: ${String(err)}`);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
//#endregion
|
|
749
|
-
//#region extensions/discord/src/monitor/threading.ts
|
|
750
|
-
var threading_exports = /* @__PURE__ */ __exportAll({
|
|
751
|
-
maybeCreateDiscordAutoThread: () => maybeCreateDiscordAutoThread,
|
|
752
|
-
resetDiscordThreadStarterCacheForTest: () => resetDiscordThreadStarterCacheForTest,
|
|
753
|
-
resolveDiscordAutoThreadContext: () => resolveDiscordAutoThreadContext,
|
|
754
|
-
resolveDiscordAutoThreadReplyPlan: () => resolveDiscordAutoThreadReplyPlan,
|
|
755
|
-
resolveDiscordReplyDeliveryPlan: () => resolveDiscordReplyDeliveryPlan,
|
|
756
|
-
resolveDiscordReplyTarget: () => resolveDiscordReplyTarget,
|
|
757
|
-
resolveDiscordThreadChannel: () => resolveDiscordThreadChannel,
|
|
758
|
-
resolveDiscordThreadParentInfo: () => resolveDiscordThreadParentInfo,
|
|
759
|
-
resolveDiscordThreadStarter: () => resolveDiscordThreadStarter,
|
|
760
|
-
sanitizeDiscordThreadName: () => sanitizeDiscordThreadName
|
|
761
|
-
});
|
|
762
|
-
//#endregion
|
|
763
|
-
//#region extensions/discord/src/monitor/thread-channel-context.ts
|
|
764
|
-
function isDiscordThreadChannelType(type) {
|
|
765
|
-
return type === discord_exports.ChannelType.PublicThread || type === discord_exports.ChannelType.PrivateThread || type === discord_exports.ChannelType.AnnouncementThread;
|
|
766
|
-
}
|
|
767
|
-
function buildFetchedChannelInfo(channel) {
|
|
768
|
-
const channelInfo = resolveDiscordChannelInfoSafe(channel);
|
|
769
|
-
if (channelInfo.type === void 0) return null;
|
|
770
|
-
return {
|
|
771
|
-
type: channelInfo.type,
|
|
772
|
-
name: channelInfo.name,
|
|
773
|
-
topic: channelInfo.topic,
|
|
774
|
-
parentId: channelInfo.parentId,
|
|
775
|
-
ownerId: channelInfo.ownerId
|
|
513
|
+
type: channelInfo.type,
|
|
514
|
+
name: channelInfo.name,
|
|
515
|
+
topic: channelInfo.topic,
|
|
516
|
+
parentId: channelInfo.parentId,
|
|
517
|
+
ownerId: channelInfo.ownerId
|
|
776
518
|
};
|
|
777
519
|
}
|
|
778
520
|
async function resolveDiscordThreadLikeChannelContext(params) {
|
|
@@ -1090,8 +832,8 @@ async function handleDiscordReactionEvent(params) {
|
|
|
1090
832
|
const guildSlug = guildInfo?.slug || (data.guild?.name ? normalizeDiscordSlug(data.guild.name) : data.guild_id ?? (isGroupDm ? "group-dm" : "dm"));
|
|
1091
833
|
const channelLabel = channelSlug ? `#${channelSlug}` : channelName ? `#${normalizeDiscordSlug(channelName)}` : `#${data.channel_id}`;
|
|
1092
834
|
reactionBase = {
|
|
1093
|
-
baseText: `Discord reaction ${action}: ${emojiLabel} by ${actorLabel} on ${guildSlug} ${channelLabel} msg ${data.message_id}`,
|
|
1094
|
-
contextKey: `discord:reaction:${action}:${data.message_id}:${user.id}:${emojiLabel}`
|
|
835
|
+
baseText: `Discord ${data.burst ? "super " : ""}reaction ${action}: ${emojiLabel} by ${actorLabel} on ${guildSlug} ${channelLabel} msg ${data.message_id}`,
|
|
836
|
+
contextKey: `discord:reaction:${action}:${data.message_id}:${user.id}:${emojiLabel}${data.burst ? ":burst" : ""}`
|
|
1095
837
|
};
|
|
1096
838
|
return reactionBase;
|
|
1097
839
|
};
|
|
@@ -1101,294 +843,95 @@ async function handleDiscordReactionEvent(params) {
|
|
|
1101
843
|
cfg: params.cfg,
|
|
1102
844
|
channel: "discord",
|
|
1103
845
|
accountId: params.accountId,
|
|
1104
|
-
guildId: data.guild_id ?? void 0,
|
|
1105
|
-
memberRoleIds,
|
|
1106
|
-
peer: {
|
|
1107
|
-
kind: isDirectMessage ? "direct" : isGroupDm ? "group" : "channel",
|
|
1108
|
-
id: isDirectMessage ? user.id : data.channel_id
|
|
1109
|
-
},
|
|
1110
|
-
parentPeer: parentPeerId ? {
|
|
1111
|
-
kind: "channel",
|
|
1112
|
-
id: parentPeerId
|
|
1113
|
-
} : void 0
|
|
1114
|
-
}), { contextKey });
|
|
1115
|
-
};
|
|
1116
|
-
const shouldNotifyReaction = (options) => shouldEmitDiscordReactionNotification({
|
|
1117
|
-
mode: options.mode,
|
|
1118
|
-
botId: botUserId,
|
|
1119
|
-
messageAuthorId: options.messageAuthorId,
|
|
1120
|
-
userId: user.id,
|
|
1121
|
-
userName: user.username,
|
|
1122
|
-
userTag: formatDiscordUserTag(user),
|
|
1123
|
-
channelConfig: options.channelConfig,
|
|
1124
|
-
guildInfo,
|
|
1125
|
-
memberRoleIds,
|
|
1126
|
-
allowNameMatching: params.allowNameMatching
|
|
1127
|
-
});
|
|
1128
|
-
const emitReactionWithAuthor = (message) => {
|
|
1129
|
-
const { baseText } = resolveReactionBase();
|
|
1130
|
-
const authorLabel = message?.author ? formatDiscordUserTag(message.author) : void 0;
|
|
1131
|
-
const text = authorLabel ? `${baseText} from ${authorLabel}` : baseText;
|
|
1132
|
-
emitReaction(text, parentId);
|
|
1133
|
-
};
|
|
1134
|
-
const resolveThreadChannelConfig = () => resolveDiscordChannelConfigWithFallback({
|
|
1135
|
-
guildInfo,
|
|
1136
|
-
channelId: data.channel_id,
|
|
1137
|
-
channelName,
|
|
1138
|
-
channelSlug,
|
|
1139
|
-
parentId,
|
|
1140
|
-
parentName,
|
|
1141
|
-
parentSlug,
|
|
1142
|
-
scope: "thread"
|
|
1143
|
-
});
|
|
1144
|
-
const authorizeReactionIngressForChannel = async (channelConfig) => await authorizeDiscordReactionIngress({
|
|
1145
|
-
...reactionIngressBase,
|
|
1146
|
-
channelConfig
|
|
1147
|
-
});
|
|
1148
|
-
const resolveThreadChannelAccess = async () => {
|
|
1149
|
-
const channelConfig = resolveThreadChannelConfig();
|
|
1150
|
-
return {
|
|
1151
|
-
access: await authorizeReactionIngressForChannel(channelConfig),
|
|
1152
|
-
channelConfig
|
|
1153
|
-
};
|
|
1154
|
-
};
|
|
1155
|
-
if (isThreadChannel) {
|
|
1156
|
-
await handleDiscordThreadReactionNotification({
|
|
1157
|
-
reactionMode,
|
|
1158
|
-
message: data.message,
|
|
1159
|
-
parentId,
|
|
1160
|
-
resolveThreadChannelAccess,
|
|
1161
|
-
shouldNotifyReaction,
|
|
1162
|
-
resolveReactionBase,
|
|
1163
|
-
emitReaction,
|
|
1164
|
-
emitReactionWithAuthor
|
|
1165
|
-
});
|
|
1166
|
-
return;
|
|
1167
|
-
}
|
|
1168
|
-
const channelConfig = resolveDiscordChannelConfigWithFallback({
|
|
1169
|
-
guildInfo,
|
|
1170
|
-
channelId: data.channel_id,
|
|
1171
|
-
channelName,
|
|
1172
|
-
channelSlug,
|
|
1173
|
-
parentId,
|
|
1174
|
-
parentName,
|
|
1175
|
-
parentSlug,
|
|
1176
|
-
scope: "channel"
|
|
1177
|
-
});
|
|
1178
|
-
await handleDiscordChannelReactionNotification({
|
|
1179
|
-
isGuildMessage,
|
|
1180
|
-
reactionMode,
|
|
1181
|
-
message: data.message,
|
|
1182
|
-
channelConfig,
|
|
1183
|
-
parentId,
|
|
1184
|
-
authorizeReactionIngressForChannel,
|
|
1185
|
-
shouldNotifyReaction,
|
|
1186
|
-
resolveReactionBase,
|
|
1187
|
-
emitReaction,
|
|
1188
|
-
emitReactionWithAuthor
|
|
1189
|
-
});
|
|
1190
|
-
} catch (err) {
|
|
1191
|
-
params.logger.error(danger(`discord reaction handler failed: ${String(err)}`));
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
//#endregion
|
|
1195
|
-
//#region extensions/discord/src/monitor/presence-events.ts
|
|
1196
|
-
const DISCORD_PRESENCE_GREETING_COOLDOWN_MS = 480 * 60 * 1e3;
|
|
1197
|
-
function isDiscordOnlineStatus(status) {
|
|
1198
|
-
return status === "online" || status === "idle" || status === "dnd";
|
|
1199
|
-
}
|
|
1200
|
-
function isDiscordOfflineStatus(status) {
|
|
1201
|
-
return status === "offline";
|
|
1202
|
-
}
|
|
1203
|
-
function resolveDiscordOnlinePresenceEvent(params) {
|
|
1204
|
-
const config = params.config;
|
|
1205
|
-
const userId = params.data.user?.id?.trim();
|
|
1206
|
-
if (!config || config.enabled === false || !userId || userId === params.botUserId || params.data.user.bot === true || !isDiscordOnlineStatus(params.data.status) || !params.availabilityKind) return null;
|
|
1207
|
-
if (config.users !== void 0 && !config.users.includes(userId)) return null;
|
|
1208
|
-
if (params.lastEmittedAtMs !== void 0 && params.nowMs - params.lastEmittedAtMs < 288e5) return null;
|
|
1209
|
-
const lines = [
|
|
1210
|
-
"Discord online-presence event:",
|
|
1211
|
-
params.availabilityKind === "observed-offline" ? `A human member became available online after being observed offline in guild_id=${JSON.stringify(params.data.guild_id)} user_id=${JSON.stringify(userId)} status=${JSON.stringify(params.data.status)}.` : `A human member became newly visible online since the current guild snapshot in guild_id=${JSON.stringify(params.data.guild_id)} user_id=${JSON.stringify(userId)} status=${JSON.stringify(params.data.status)}. They may have come online or joined after the snapshot; do not claim an exact prior status.`,
|
|
1212
|
-
`The authorized greeting target is channel_id=${JSON.stringify(config.channelId)}.`,
|
|
1213
|
-
"Before greeting, retrieve relevant memory and wiki context for this immutable user_id, including a known timezone when available. Use their local time for the greeting; if their timezone is unknown, do not guess.",
|
|
1214
|
-
"Send at most one short, natural greeting to the target channel. Do not reveal private memory. If no greeting is appropriate, stay silent."
|
|
1215
|
-
];
|
|
1216
|
-
return {
|
|
1217
|
-
channelId: config.channelId,
|
|
1218
|
-
userId,
|
|
1219
|
-
text: lines.join("\n")
|
|
1220
|
-
};
|
|
1221
|
-
}
|
|
1222
|
-
//#endregion
|
|
1223
|
-
//#region extensions/discord/src/monitor/presence-cooldown-store.ts
|
|
1224
|
-
const DISCORD_PRESENCE_COOLDOWN_MAX_ENTRIES = 25e3;
|
|
1225
|
-
function openDiscordPresenceCooldownStore() {
|
|
1226
|
-
return getDiscordRuntime().state.openSyncKeyedStore({
|
|
1227
|
-
namespace: "presence-greeting-cooldowns",
|
|
1228
|
-
maxEntries: DISCORD_PRESENCE_COOLDOWN_MAX_ENTRIES,
|
|
1229
|
-
overflowPolicy: "reject-new",
|
|
1230
|
-
defaultTtlMs: DISCORD_PRESENCE_GREETING_COOLDOWN_MS
|
|
1231
|
-
});
|
|
1232
|
-
}
|
|
1233
|
-
//#endregion
|
|
1234
|
-
//#region extensions/discord/src/monitor/presence-emission-gate.ts
|
|
1235
|
-
const DISCORD_PRESENCE_RECONNECT_SUPPRESS_MS = 300 * 1e3;
|
|
1236
|
-
const DISCORD_PRESENCE_BURST_LIMIT = 8;
|
|
1237
|
-
const DISCORD_PRESENCE_BURST_WINDOW_MS = 60 * 1e3;
|
|
1238
|
-
function resolveDiscordPresenceGateOptions(config) {
|
|
1239
|
-
return {
|
|
1240
|
-
reconnectSuppressMs: config?.reconnectSuppressSeconds !== void 0 ? config.reconnectSuppressSeconds * 1e3 : DISCORD_PRESENCE_RECONNECT_SUPPRESS_MS,
|
|
1241
|
-
burstLimit: config?.burstLimit ?? DISCORD_PRESENCE_BURST_LIMIT,
|
|
1242
|
-
burstWindowMs: config?.burstWindowSeconds !== void 0 ? config.burstWindowSeconds * 1e3 : DISCORD_PRESENCE_BURST_WINDOW_MS
|
|
1243
|
-
};
|
|
1244
|
-
}
|
|
1245
|
-
/**
|
|
1246
|
-
* Per-account lifecycle gate for online-presence events. Reconnect state belongs to the Gateway
|
|
1247
|
-
* session, while burst state follows the guild-owned configuration that supplies its limits.
|
|
1248
|
-
*/
|
|
1249
|
-
var DiscordPresenceEmissionGate = class {
|
|
1250
|
-
constructor() {
|
|
1251
|
-
this.reconnectLogged = false;
|
|
1252
|
-
this.burstByGuild = /* @__PURE__ */ new Map();
|
|
1253
|
-
this.nextReservationId = 0;
|
|
1254
|
-
}
|
|
1255
|
-
noteGatewaySessionReset(nowMs) {
|
|
1256
|
-
this.lastSessionResetAtMs = nowMs;
|
|
1257
|
-
this.reconnectLogged = false;
|
|
1258
|
-
}
|
|
1259
|
-
evaluateReconnectWindow(nowMs, options) {
|
|
1260
|
-
if (this.lastSessionResetAtMs !== void 0 && options.reconnectSuppressMs > 0 && nowMs - this.lastSessionResetAtMs < options.reconnectSuppressMs) {
|
|
1261
|
-
const shouldLog = !this.reconnectLogged;
|
|
1262
|
-
this.reconnectLogged = true;
|
|
1263
|
-
return {
|
|
1264
|
-
allowed: false,
|
|
1265
|
-
reason: "reconnect-window",
|
|
1266
|
-
shouldLog
|
|
1267
|
-
};
|
|
1268
|
-
}
|
|
1269
|
-
return { allowed: true };
|
|
1270
|
-
}
|
|
1271
|
-
reserveBurst(guildId, nowMs, options) {
|
|
1272
|
-
const state = this.burstByGuild.get(guildId) ?? {
|
|
1273
|
-
reservations: [],
|
|
1274
|
-
logged: false
|
|
1275
|
-
};
|
|
1276
|
-
state.reservations = state.reservations.filter((reservation) => !reservation.committed || nowMs - reservation.atMs < options.burstWindowMs);
|
|
1277
|
-
this.burstByGuild.set(guildId, state);
|
|
1278
|
-
if (state.reservations.length >= options.burstLimit) {
|
|
1279
|
-
const shouldLog = !state.logged;
|
|
1280
|
-
state.logged = true;
|
|
1281
|
-
return {
|
|
1282
|
-
allowed: false,
|
|
1283
|
-
reason: state.reservations.some((reservation) => !reservation.committed) ? "burst-pending" : "burst",
|
|
1284
|
-
shouldLog
|
|
1285
|
-
};
|
|
1286
|
-
}
|
|
1287
|
-
state.logged = false;
|
|
1288
|
-
const reservation = {
|
|
1289
|
-
id: this.nextReservationId++,
|
|
1290
|
-
atMs: nowMs,
|
|
1291
|
-
committed: false
|
|
1292
|
-
};
|
|
1293
|
-
state.reservations.push(reservation);
|
|
1294
|
-
return {
|
|
1295
|
-
allowed: true,
|
|
1296
|
-
reservation: reservation.id
|
|
1297
|
-
};
|
|
1298
|
-
}
|
|
1299
|
-
commitBurst(guildId, reservation, nowMs) {
|
|
1300
|
-
const entry = this.burstByGuild.get(guildId)?.reservations.find((candidate) => candidate.id === reservation);
|
|
1301
|
-
if (!entry) return;
|
|
1302
|
-
entry.atMs = nowMs;
|
|
1303
|
-
entry.committed = true;
|
|
1304
|
-
}
|
|
1305
|
-
releaseBurst(guildId, reservation) {
|
|
1306
|
-
const state = this.burstByGuild.get(guildId);
|
|
1307
|
-
if (!state) return;
|
|
1308
|
-
state.reservations = state.reservations.filter((candidate) => candidate.id !== reservation);
|
|
1309
|
-
if (state.reservations.length === 0 && !state.logged) this.burstByGuild.delete(guildId);
|
|
1310
|
-
}
|
|
1311
|
-
};
|
|
1312
|
-
//#endregion
|
|
1313
|
-
//#region extensions/discord/src/monitor/presence-transition-cache.ts
|
|
1314
|
-
const DEFAULT_PRESENCE_BASELINE_MAX_ENTRIES = 75e3;
|
|
1315
|
-
var DiscordPresenceBaselineCache = class {
|
|
1316
|
-
constructor(maxEntries = DEFAULT_PRESENCE_BASELINE_MAX_ENTRIES) {
|
|
1317
|
-
this.maxEntries = maxEntries;
|
|
1318
|
-
this.offlineByKey = /* @__PURE__ */ new Map();
|
|
1319
|
-
this.onlineByKey = /* @__PURE__ */ new Map();
|
|
1320
|
-
}
|
|
1321
|
-
clear() {
|
|
1322
|
-
this.offlineByKey.clear();
|
|
1323
|
-
this.onlineByKey.clear();
|
|
1324
|
-
}
|
|
1325
|
-
clearScope(scope) {
|
|
1326
|
-
for (const markers of [this.offlineByKey, this.onlineByKey]) for (const [key, markerScope] of markers) if (markerScope === scope) markers.delete(key);
|
|
1327
|
-
}
|
|
1328
|
-
isOffline(scope, key) {
|
|
1329
|
-
return this.offlineByKey.get(key) === scope;
|
|
1330
|
-
}
|
|
1331
|
-
isOnline(scope, key) {
|
|
1332
|
-
return this.onlineByKey.get(key) === scope;
|
|
1333
|
-
}
|
|
1334
|
-
observeOffline(scope, key) {
|
|
1335
|
-
this.deleteMarker(this.onlineByKey, scope, key);
|
|
1336
|
-
return this.observe(this.offlineByKey, scope, key);
|
|
1337
|
-
}
|
|
1338
|
-
observeOnline(scope, key) {
|
|
1339
|
-
this.deleteMarker(this.offlineByKey, scope, key);
|
|
1340
|
-
return this.observe(this.onlineByKey, scope, key);
|
|
1341
|
-
}
|
|
1342
|
-
deleteMarker(markers, scope, key) {
|
|
1343
|
-
if (markers.get(key) === scope) markers.delete(key);
|
|
1344
|
-
}
|
|
1345
|
-
observe(markers, scope, key) {
|
|
1346
|
-
markers.delete(key);
|
|
1347
|
-
markers.set(key, scope);
|
|
1348
|
-
let evictedScope;
|
|
1349
|
-
while (markers.size > this.maxEntries) {
|
|
1350
|
-
const oldestKey = markers.keys().next().value;
|
|
1351
|
-
if (oldestKey === void 0) break;
|
|
1352
|
-
evictedScope = markers.get(oldestKey);
|
|
1353
|
-
markers.delete(oldestKey);
|
|
1354
|
-
}
|
|
1355
|
-
return evictedScope;
|
|
1356
|
-
}
|
|
1357
|
-
};
|
|
1358
|
-
//#endregion
|
|
1359
|
-
//#region extensions/discord/src/monitor/thread-session-close.ts
|
|
1360
|
-
/**
|
|
1361
|
-
* Closes every session entry in the store whose key contains {@link threadId}.
|
|
1362
|
-
* The explicit lifecycle deletion archives the old transcript and guarantees
|
|
1363
|
-
* that a later inbound message starts a fresh session in every reset mode.
|
|
1364
|
-
*/
|
|
1365
|
-
async function closeDiscordThreadSessions(params) {
|
|
1366
|
-
const { cfg, threadId } = params;
|
|
1367
|
-
const normalizedThreadId = normalizeOptionalLowercaseString(threadId) ?? "";
|
|
1368
|
-
if (!normalizedThreadId) return 0;
|
|
1369
|
-
const segmentRe = new RegExp(`:${normalizedThreadId}(?::|$)`, "i");
|
|
1370
|
-
function sessionKeyContainsThreadId(key) {
|
|
1371
|
-
return segmentRe.test(key);
|
|
1372
|
-
}
|
|
1373
|
-
let resetCount = 0;
|
|
1374
|
-
for (const agentId of listAgentIds(cfg)) {
|
|
1375
|
-
const storePath = resolveStorePath(cfg.session?.store, { agentId });
|
|
1376
|
-
for (const { sessionKey, entry } of listSessionEntries({
|
|
1377
|
-
agentId,
|
|
1378
|
-
storePath,
|
|
1379
|
-
readOnly: true
|
|
1380
|
-
})) {
|
|
1381
|
-
if (!sessionKeyContainsThreadId(sessionKey)) continue;
|
|
1382
|
-
if (await deleteSessionEntry({
|
|
1383
|
-
archiveTranscript: true,
|
|
1384
|
-
expectedSessionId: entry.sessionId ?? null,
|
|
1385
|
-
expectedUpdatedAt: entry.updatedAt,
|
|
1386
|
-
sessionKey,
|
|
1387
|
-
storePath
|
|
1388
|
-
})) resetCount += 1;
|
|
846
|
+
guildId: data.guild_id ?? void 0,
|
|
847
|
+
memberRoleIds,
|
|
848
|
+
peer: {
|
|
849
|
+
kind: isDirectMessage ? "direct" : isGroupDm ? "group" : "channel",
|
|
850
|
+
id: isDirectMessage ? user.id : data.channel_id
|
|
851
|
+
},
|
|
852
|
+
parentPeer: parentPeerId ? {
|
|
853
|
+
kind: "channel",
|
|
854
|
+
id: parentPeerId
|
|
855
|
+
} : void 0
|
|
856
|
+
}), { contextKey });
|
|
857
|
+
};
|
|
858
|
+
const shouldNotifyReaction = (options) => shouldEmitDiscordReactionNotification({
|
|
859
|
+
mode: options.mode,
|
|
860
|
+
botId: botUserId,
|
|
861
|
+
messageAuthorId: options.messageAuthorId,
|
|
862
|
+
userId: user.id,
|
|
863
|
+
userName: user.username,
|
|
864
|
+
userTag: formatDiscordUserTag(user),
|
|
865
|
+
channelConfig: options.channelConfig,
|
|
866
|
+
guildInfo,
|
|
867
|
+
memberRoleIds,
|
|
868
|
+
allowNameMatching: params.allowNameMatching
|
|
869
|
+
});
|
|
870
|
+
const emitReactionWithAuthor = (message) => {
|
|
871
|
+
const { baseText } = resolveReactionBase();
|
|
872
|
+
const authorLabel = message?.author ? formatDiscordUserTag(message.author) : void 0;
|
|
873
|
+
const text = authorLabel ? `${baseText} from ${authorLabel}` : baseText;
|
|
874
|
+
emitReaction(text, parentId);
|
|
875
|
+
};
|
|
876
|
+
const resolveThreadChannelConfig = () => resolveDiscordChannelConfigWithFallback({
|
|
877
|
+
guildInfo,
|
|
878
|
+
channelId: data.channel_id,
|
|
879
|
+
channelName,
|
|
880
|
+
channelSlug,
|
|
881
|
+
parentId,
|
|
882
|
+
parentName,
|
|
883
|
+
parentSlug,
|
|
884
|
+
scope: "thread"
|
|
885
|
+
});
|
|
886
|
+
const authorizeReactionIngressForChannel = async (channelConfig) => await authorizeDiscordReactionIngress({
|
|
887
|
+
...reactionIngressBase,
|
|
888
|
+
channelConfig
|
|
889
|
+
});
|
|
890
|
+
const resolveThreadChannelAccess = async () => {
|
|
891
|
+
const channelConfig = resolveThreadChannelConfig();
|
|
892
|
+
return {
|
|
893
|
+
access: await authorizeReactionIngressForChannel(channelConfig),
|
|
894
|
+
channelConfig
|
|
895
|
+
};
|
|
896
|
+
};
|
|
897
|
+
if (isThreadChannel) {
|
|
898
|
+
await handleDiscordThreadReactionNotification({
|
|
899
|
+
reactionMode,
|
|
900
|
+
message: data.message,
|
|
901
|
+
parentId,
|
|
902
|
+
resolveThreadChannelAccess,
|
|
903
|
+
shouldNotifyReaction,
|
|
904
|
+
resolveReactionBase,
|
|
905
|
+
emitReaction,
|
|
906
|
+
emitReactionWithAuthor
|
|
907
|
+
});
|
|
908
|
+
return;
|
|
1389
909
|
}
|
|
910
|
+
const channelConfig = resolveDiscordChannelConfigWithFallback({
|
|
911
|
+
guildInfo,
|
|
912
|
+
channelId: data.channel_id,
|
|
913
|
+
channelName,
|
|
914
|
+
channelSlug,
|
|
915
|
+
parentId,
|
|
916
|
+
parentName,
|
|
917
|
+
parentSlug,
|
|
918
|
+
scope: "channel"
|
|
919
|
+
});
|
|
920
|
+
await handleDiscordChannelReactionNotification({
|
|
921
|
+
isGuildMessage,
|
|
922
|
+
reactionMode,
|
|
923
|
+
message: data.message,
|
|
924
|
+
channelConfig,
|
|
925
|
+
parentId,
|
|
926
|
+
authorizeReactionIngressForChannel,
|
|
927
|
+
shouldNotifyReaction,
|
|
928
|
+
resolveReactionBase,
|
|
929
|
+
emitReaction,
|
|
930
|
+
emitReactionWithAuthor
|
|
931
|
+
});
|
|
932
|
+
} catch (err) {
|
|
933
|
+
params.logger.error(danger(`discord reaction handler failed: ${String(err)}`));
|
|
1390
934
|
}
|
|
1391
|
-
return resetCount;
|
|
1392
935
|
}
|
|
1393
936
|
//#endregion
|
|
1394
937
|
//#region extensions/discord/src/monitor/listeners.ts
|
|
@@ -1815,11 +1358,16 @@ function isDiscordUnknownInteraction(error) {
|
|
|
1815
1358
|
if (/Unknown interaction/i.test(err.rawBody?.message ?? "")) return true;
|
|
1816
1359
|
return false;
|
|
1817
1360
|
}
|
|
1361
|
+
function resolveDiscordInteractionMessageParts(payload) {
|
|
1362
|
+
const { components, embeds } = payload.channelData?.discord ?? {};
|
|
1363
|
+
return {
|
|
1364
|
+
components: Array.isArray(components) && components.length > 0 ? components : void 0,
|
|
1365
|
+
embeds: Array.isArray(embeds) && embeds.length > 0 ? embeds : void 0
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1818
1368
|
function hasRenderableReplyPayload(payload) {
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
if (Array.isArray(discordData?.components) && discordData.components.length > 0) return true;
|
|
1822
|
-
return false;
|
|
1369
|
+
const { components, embeds } = resolveDiscordInteractionMessageParts(payload);
|
|
1370
|
+
return resolveSendableOutboundReplyParts(payload).hasContent || Boolean(components || embeds);
|
|
1823
1371
|
}
|
|
1824
1372
|
async function safeDiscordInteractionCall(label, fn) {
|
|
1825
1373
|
try {
|
|
@@ -1839,33 +1387,25 @@ async function settleDiscordInteractionWithoutVisibleReply(interaction) {
|
|
|
1839
1387
|
async function deliverDiscordInteractionReply(params) {
|
|
1840
1388
|
const { interaction, payload, textLimit, maxLinesPerMessage, preferFollowUp, chunkMode } = params;
|
|
1841
1389
|
const reply = resolveSendableOutboundReplyParts(payload);
|
|
1842
|
-
|
|
1843
|
-
let firstMessageComponents = Array.isArray(discordData?.components) && discordData.components.length > 0 ? discordData.components : void 0;
|
|
1390
|
+
let { components: firstMessageComponents, embeds: firstMessageEmbeds } = resolveDiscordInteractionMessageParts(payload);
|
|
1844
1391
|
let payloadDelivered = false;
|
|
1845
|
-
const sendMessage = async (content, files, components) => {
|
|
1846
|
-
const
|
|
1847
|
-
const payloadLocal =
|
|
1848
|
-
...
|
|
1392
|
+
const sendMessage = async (content, files, components, embeds) => {
|
|
1393
|
+
const hasV2 = hasDiscordV2Components(components);
|
|
1394
|
+
const payloadLocal = {
|
|
1395
|
+
...content && !hasV2 ? { content } : {},
|
|
1849
1396
|
...components ? { components } : {},
|
|
1397
|
+
...embeds && !hasV2 ? { embeds } : {},
|
|
1850
1398
|
...params.responseEphemeral !== void 0 ? { ephemeral: params.responseEphemeral } : {},
|
|
1851
|
-
files
|
|
1852
|
-
} : {
|
|
1853
|
-
...contentPayload,
|
|
1854
|
-
...components ? { components } : {},
|
|
1855
|
-
...params.responseEphemeral !== void 0 ? { ephemeral: params.responseEphemeral } : {}
|
|
1399
|
+
...files?.length ? { files } : {}
|
|
1856
1400
|
};
|
|
1857
1401
|
let result;
|
|
1858
1402
|
try {
|
|
1859
1403
|
result = await safeDiscordInteractionCall("interaction send", async () => {
|
|
1860
|
-
if (!preferFollowUp && !payloadDelivered)
|
|
1861
|
-
|
|
1862
|
-
payloadDelivered = true;
|
|
1863
|
-
firstMessageComponents = void 0;
|
|
1864
|
-
return;
|
|
1865
|
-
}
|
|
1866
|
-
await interaction.followUp(payloadLocal);
|
|
1404
|
+
if (!preferFollowUp && !payloadDelivered) await interaction.reply(payloadLocal);
|
|
1405
|
+
else await interaction.followUp(payloadLocal);
|
|
1867
1406
|
payloadDelivered = true;
|
|
1868
1407
|
firstMessageComponents = void 0;
|
|
1408
|
+
firstMessageEmbeds = void 0;
|
|
1869
1409
|
});
|
|
1870
1410
|
} catch (error) {
|
|
1871
1411
|
if (!payloadDelivered) throw error;
|
|
@@ -1890,99 +1430,27 @@ async function deliverDiscordInteractionReply(params) {
|
|
|
1890
1430
|
maxLines: maxLinesPerMessage,
|
|
1891
1431
|
chunkMode
|
|
1892
1432
|
}));
|
|
1893
|
-
await sendMessage(chunks[0] ?? "", media, firstMessageComponents);
|
|
1433
|
+
await sendMessage(chunks[0] ?? "", media, firstMessageComponents, firstMessageEmbeds);
|
|
1894
1434
|
for (const chunk of chunks.slice(1)) {
|
|
1895
1435
|
if (!chunk.trim()) continue;
|
|
1896
1436
|
await sendMessage(chunk);
|
|
1897
1437
|
}
|
|
1898
1438
|
return payloadDelivered;
|
|
1899
1439
|
}
|
|
1900
|
-
if (!reply.hasText && !firstMessageComponents) return false;
|
|
1901
|
-
|
|
1440
|
+
if (!reply.hasText && !firstMessageComponents && !firstMessageEmbeds) return false;
|
|
1441
|
+
const chunks = resolveTextChunksWithFallback(reply.text, chunkDiscordTextWithMode(reply.text, {
|
|
1902
1442
|
maxChars: textLimit,
|
|
1903
1443
|
maxLines: maxLinesPerMessage,
|
|
1904
1444
|
chunkMode
|
|
1905
|
-
}))
|
|
1906
|
-
if (chunks.length === 0
|
|
1445
|
+
}));
|
|
1446
|
+
if (chunks.length === 0) chunks.push("");
|
|
1907
1447
|
for (const chunk of chunks) {
|
|
1908
|
-
if (!chunk.trim() && !firstMessageComponents) continue;
|
|
1909
|
-
await sendMessage(chunk, void 0, firstMessageComponents);
|
|
1448
|
+
if (!chunk.trim() && !firstMessageComponents && !firstMessageEmbeds) continue;
|
|
1449
|
+
await sendMessage(chunk, void 0, firstMessageComponents, firstMessageEmbeds);
|
|
1910
1450
|
}
|
|
1911
1451
|
return payloadDelivered;
|
|
1912
1452
|
}
|
|
1913
1453
|
//#endregion
|
|
1914
|
-
//#region extensions/discord/src/monitor/route-resolution.ts
|
|
1915
|
-
function buildDiscordRoutePeer(params) {
|
|
1916
|
-
return {
|
|
1917
|
-
kind: params.isDirectMessage ? "direct" : params.isGroupDm ? "group" : "channel",
|
|
1918
|
-
id: params.isDirectMessage ? params.directUserId?.trim() || params.conversationId : params.conversationId
|
|
1919
|
-
};
|
|
1920
|
-
}
|
|
1921
|
-
function resolveDiscordConversationRoute(params) {
|
|
1922
|
-
return resolveAgentRoute({
|
|
1923
|
-
cfg: params.cfg,
|
|
1924
|
-
channel: "discord",
|
|
1925
|
-
accountId: params.accountId,
|
|
1926
|
-
guildId: params.guildId ?? void 0,
|
|
1927
|
-
memberRoleIds: params.memberRoleIds,
|
|
1928
|
-
peer: params.peer,
|
|
1929
|
-
parentPeer: params.parentConversationId ? {
|
|
1930
|
-
kind: "channel",
|
|
1931
|
-
id: params.parentConversationId
|
|
1932
|
-
} : void 0
|
|
1933
|
-
});
|
|
1934
|
-
}
|
|
1935
|
-
function resolveDiscordBoundConversationRoute(params) {
|
|
1936
|
-
return resolveDiscordEffectiveRoute({
|
|
1937
|
-
route: resolveDiscordConversationRoute({
|
|
1938
|
-
cfg: params.cfg,
|
|
1939
|
-
accountId: params.accountId,
|
|
1940
|
-
guildId: params.guildId,
|
|
1941
|
-
memberRoleIds: params.memberRoleIds,
|
|
1942
|
-
peer: buildDiscordRoutePeer({
|
|
1943
|
-
isDirectMessage: params.isDirectMessage,
|
|
1944
|
-
isGroupDm: params.isGroupDm,
|
|
1945
|
-
directUserId: params.directUserId,
|
|
1946
|
-
conversationId: params.conversationId
|
|
1947
|
-
}),
|
|
1948
|
-
parentConversationId: params.parentConversationId
|
|
1949
|
-
}),
|
|
1950
|
-
boundSessionKey: params.boundSessionKey,
|
|
1951
|
-
configuredRoute: params.configuredRoute,
|
|
1952
|
-
matchedBy: params.matchedBy
|
|
1953
|
-
});
|
|
1954
|
-
}
|
|
1955
|
-
function resolveDiscordEffectiveRoute(params) {
|
|
1956
|
-
const boundSessionKey = params.boundSessionKey?.trim();
|
|
1957
|
-
if (!boundSessionKey) return params.configuredRoute?.route ?? params.route;
|
|
1958
|
-
return {
|
|
1959
|
-
...params.route,
|
|
1960
|
-
sessionKey: boundSessionKey,
|
|
1961
|
-
agentId: resolveAgentIdFromSessionKey(boundSessionKey),
|
|
1962
|
-
lastRoutePolicy: deriveLastRoutePolicy({
|
|
1963
|
-
sessionKey: boundSessionKey,
|
|
1964
|
-
mainSessionKey: params.route.mainSessionKey
|
|
1965
|
-
}),
|
|
1966
|
-
...params.matchedBy ? { matchedBy: params.matchedBy } : {}
|
|
1967
|
-
};
|
|
1968
|
-
}
|
|
1969
|
-
function hasExplicitRuntimeBindingIntent(record) {
|
|
1970
|
-
if (record.targetKind === "subagent") return true;
|
|
1971
|
-
if (isAcpSessionKey(record.targetSessionKey) || isSubagentSessionKey(record.targetSessionKey)) return true;
|
|
1972
|
-
const metadata = record.metadata;
|
|
1973
|
-
if (!metadata || typeof metadata !== "object") return false;
|
|
1974
|
-
return typeof metadata.boundBy === "string" || typeof metadata.label === "string" || typeof metadata.threadName === "string" || metadata.pluginBindingOwner === "plugin";
|
|
1975
|
-
}
|
|
1976
|
-
function shouldIgnoreStaleDiscordRouteBinding(params) {
|
|
1977
|
-
const bindingRecord = params.bindingRecord;
|
|
1978
|
-
const boundSessionKey = bindingRecord?.targetSessionKey?.trim();
|
|
1979
|
-
if (!bindingRecord || !boundSessionKey || hasExplicitRuntimeBindingIntent(bindingRecord)) return false;
|
|
1980
|
-
const bound = parseAgentSessionKey(boundSessionKey);
|
|
1981
|
-
const routed = parseAgentSessionKey(params.route.sessionKey);
|
|
1982
|
-
if (!bound || !routed || bound.rest !== routed.rest) return false;
|
|
1983
|
-
return bound.agentId !== params.route.agentId;
|
|
1984
|
-
}
|
|
1985
|
-
//#endregion
|
|
1986
1454
|
//#region extensions/discord/src/monitor/native-command-route.ts
|
|
1987
1455
|
async function resolveDiscordNativeInteractionRouteState(params) {
|
|
1988
1456
|
const route = resolveDiscordBoundConversationRoute({
|
|
@@ -2050,6 +1518,7 @@ async function dispatchDiscordNativeAgentReply(params) {
|
|
|
2050
1518
|
sessionKey: params.ctxPayload.SessionKey ?? params.effectiveRoute.sessionKey
|
|
2051
1519
|
},
|
|
2052
1520
|
ctxPayload: params.ctxPayload,
|
|
1521
|
+
dispatchReplyFromConfig: params.dispatchReplyFromConfig,
|
|
2053
1522
|
delivery: {
|
|
2054
1523
|
deliver: async (payload) => {
|
|
2055
1524
|
if (params.suppressReplies) return {
|
|
@@ -2099,28 +1568,171 @@ async function dispatchDiscordNativeAgentReply(params) {
|
|
|
2099
1568
|
disableBlockStreaming: typeof blockStreamingEnabled === "boolean" ? !blockStreamingEnabled : void 0
|
|
2100
1569
|
}
|
|
2101
1570
|
});
|
|
2102
|
-
const deliberateSilentTerminalReply = turnResult.dispatched && turnResult.dispatchResult.deliberateSilentTerminalReply === true;
|
|
2103
|
-
const dispatchResult = {
|
|
2104
|
-
dispatched: turnResult.dispatched,
|
|
2105
|
-
...hiddenFinalReply ? { hiddenFinalReply } : {}
|
|
1571
|
+
const deliberateSilentTerminalReply = turnResult.dispatched && turnResult.dispatchResult.deliberateSilentTerminalReply === true;
|
|
1572
|
+
const dispatchResult = {
|
|
1573
|
+
dispatched: turnResult.dispatched,
|
|
1574
|
+
...hiddenFinalReply ? { hiddenFinalReply } : {}
|
|
1575
|
+
};
|
|
1576
|
+
if (!didReply && (params.suppressReplies || finalReplyOutcome === "suppressed" || deliberateSilentTerminalReply)) {
|
|
1577
|
+
await settleDiscordInteractionWithoutVisibleReply(params.interaction);
|
|
1578
|
+
return dispatchResult;
|
|
1579
|
+
}
|
|
1580
|
+
if (didReply || turnResult.dispatched && hasVisibleInboundReplyDispatch(turnResult.dispatchResult)) return dispatchResult;
|
|
1581
|
+
await safeDiscordInteractionCall("interaction empty fallback", async () => {
|
|
1582
|
+
const payload = {
|
|
1583
|
+
content: DISCORD_EMPTY_VISIBLE_REPLY_WARNING,
|
|
1584
|
+
ephemeral: true
|
|
1585
|
+
};
|
|
1586
|
+
if (params.preferFollowUp) {
|
|
1587
|
+
await params.interaction.followUp(payload);
|
|
1588
|
+
return;
|
|
1589
|
+
}
|
|
1590
|
+
await params.interaction.reply(payload);
|
|
1591
|
+
});
|
|
1592
|
+
return dispatchResult;
|
|
1593
|
+
}
|
|
1594
|
+
//#endregion
|
|
1595
|
+
//#region extensions/discord/src/monitor/commands.ts
|
|
1596
|
+
function resolveDiscordSlashCommandConfig(raw) {
|
|
1597
|
+
return { ephemeral: raw?.ephemeral !== false };
|
|
1598
|
+
}
|
|
1599
|
+
//#endregion
|
|
1600
|
+
//#region extensions/discord/src/monitor/native-command-arg-ui.ts
|
|
1601
|
+
const DISCORD_COMMAND_ARG_CUSTOM_ID_KEY = "cmdarg";
|
|
1602
|
+
function createCommandArgsWithValue(params) {
|
|
1603
|
+
return { values: { [params.argName]: params.value } };
|
|
1604
|
+
}
|
|
1605
|
+
function buildDiscordCommandArgCustomId(params) {
|
|
1606
|
+
return [
|
|
1607
|
+
`${DISCORD_COMMAND_ARG_CUSTOM_ID_KEY}:command=${encodeCustomIdComponent(params.command)}`,
|
|
1608
|
+
`arg=${encodeCustomIdComponent(params.arg)}`,
|
|
1609
|
+
`value=${encodeCustomIdComponent(params.value)}`,
|
|
1610
|
+
`user=${encodeCustomIdComponent(params.userId)}`
|
|
1611
|
+
].join(";");
|
|
1612
|
+
}
|
|
1613
|
+
function parseDiscordCommandArgData(data) {
|
|
1614
|
+
if (!data || typeof data !== "object") return null;
|
|
1615
|
+
const coerce = (value) => typeof value === "string" || typeof value === "number" ? String(value) : "";
|
|
1616
|
+
const rawCommand = coerce(data.command);
|
|
1617
|
+
const rawArg = coerce(data.arg);
|
|
1618
|
+
const rawValue = coerce(data.value);
|
|
1619
|
+
const rawUser = coerce(data.user);
|
|
1620
|
+
if (!rawCommand || !rawArg || !rawValue || !rawUser) return null;
|
|
1621
|
+
return {
|
|
1622
|
+
command: decodeCustomIdComponent(rawCommand),
|
|
1623
|
+
arg: decodeCustomIdComponent(rawArg),
|
|
1624
|
+
value: decodeCustomIdComponent(rawValue),
|
|
1625
|
+
userId: decodeCustomIdComponent(rawUser)
|
|
1626
|
+
};
|
|
1627
|
+
}
|
|
1628
|
+
async function handleDiscordCommandArgInteraction(params) {
|
|
1629
|
+
const { interaction, data, ctx } = params;
|
|
1630
|
+
const clearWithMessage = async (content) => await params.safeInteractionCall("command arg update", () => interaction.update({
|
|
1631
|
+
content,
|
|
1632
|
+
components: []
|
|
1633
|
+
}));
|
|
1634
|
+
const parsed = parseDiscordCommandArgData(data);
|
|
1635
|
+
if (!parsed) {
|
|
1636
|
+
await clearWithMessage("Sorry, that selection is no longer available.");
|
|
1637
|
+
return;
|
|
1638
|
+
}
|
|
1639
|
+
if (interaction.user?.id && interaction.user.id !== parsed.userId) {
|
|
1640
|
+
await params.safeInteractionCall("command arg ack", () => interaction.acknowledge());
|
|
1641
|
+
return;
|
|
1642
|
+
}
|
|
1643
|
+
const commandDefinition = findCommandByNativeName(parsed.command, "discord") ?? listChatCommands().find((entry) => entry.key === parsed.command);
|
|
1644
|
+
if (!commandDefinition) {
|
|
1645
|
+
await clearWithMessage("Sorry, that command is no longer available.");
|
|
1646
|
+
return;
|
|
1647
|
+
}
|
|
1648
|
+
if (await clearWithMessage(`⏳ Applying ${parsed.value}...`) === null) return;
|
|
1649
|
+
const commandArgs = createCommandArgsWithValue({
|
|
1650
|
+
argName: parsed.arg,
|
|
1651
|
+
value: parsed.value
|
|
1652
|
+
});
|
|
1653
|
+
const commandArgsWithRaw = {
|
|
1654
|
+
...commandArgs,
|
|
1655
|
+
raw: serializeCommandArgs(commandDefinition, commandArgs)
|
|
1656
|
+
};
|
|
1657
|
+
const prompt = buildCommandTextFromArgs(commandDefinition, commandArgsWithRaw);
|
|
1658
|
+
await params.dispatchCommandInteraction({
|
|
1659
|
+
interaction,
|
|
1660
|
+
prompt,
|
|
1661
|
+
command: commandDefinition,
|
|
1662
|
+
commandArgs: commandArgsWithRaw,
|
|
1663
|
+
cfg: ctx.cfg,
|
|
1664
|
+
discordConfig: ctx.discordConfig,
|
|
1665
|
+
accountId: ctx.accountId,
|
|
1666
|
+
sessionPrefix: ctx.sessionPrefix,
|
|
1667
|
+
preferFollowUp: true,
|
|
1668
|
+
threadBindings: ctx.threadBindings,
|
|
1669
|
+
responseEphemeral: resolveDiscordSlashCommandConfig(ctx.discordConfig?.slashCommand).ephemeral,
|
|
1670
|
+
dispatchReplyFromConfig: ctx.dispatchReplyFromConfig,
|
|
1671
|
+
pluginCommandDispatch: { kind: "non-plugin" }
|
|
1672
|
+
});
|
|
1673
|
+
}
|
|
1674
|
+
async function runDiscordCommandArgButton(params) {
|
|
1675
|
+
await handleDiscordCommandArgInteraction(params);
|
|
1676
|
+
}
|
|
1677
|
+
var DiscordCommandArgButton = class extends Button {
|
|
1678
|
+
constructor(params) {
|
|
1679
|
+
super();
|
|
1680
|
+
this.style = ButtonStyle.Secondary;
|
|
1681
|
+
this.label = params.label;
|
|
1682
|
+
this.customId = params.customId;
|
|
1683
|
+
this.params = params;
|
|
1684
|
+
}
|
|
1685
|
+
async run(interaction, data) {
|
|
1686
|
+
await runDiscordCommandArgButton({
|
|
1687
|
+
...this.params,
|
|
1688
|
+
interaction,
|
|
1689
|
+
data
|
|
1690
|
+
});
|
|
1691
|
+
}
|
|
1692
|
+
};
|
|
1693
|
+
function buildDiscordCommandArgMenu(params) {
|
|
1694
|
+
const { command, menu, interaction } = params;
|
|
1695
|
+
const commandLabel = command.nativeName ?? command.key;
|
|
1696
|
+
const userId = interaction.user?.id ?? "";
|
|
1697
|
+
const rows = chunkItems(menu.choices, 4).map((choices) => {
|
|
1698
|
+
return new Row(choices.map((choice) => new DiscordCommandArgButton({
|
|
1699
|
+
label: choice.label,
|
|
1700
|
+
customId: buildDiscordCommandArgCustomId({
|
|
1701
|
+
command: commandLabel,
|
|
1702
|
+
arg: menu.arg.name,
|
|
1703
|
+
value: choice.value,
|
|
1704
|
+
userId
|
|
1705
|
+
}),
|
|
1706
|
+
ctx: params.ctx,
|
|
1707
|
+
safeInteractionCall: params.safeInteractionCall,
|
|
1708
|
+
dispatchCommandInteraction: params.dispatchCommandInteraction
|
|
1709
|
+
})));
|
|
1710
|
+
});
|
|
1711
|
+
return {
|
|
1712
|
+
content: formatCommandArgMenuTitle({
|
|
1713
|
+
command,
|
|
1714
|
+
menu
|
|
1715
|
+
}),
|
|
1716
|
+
components: rows
|
|
2106
1717
|
};
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
1718
|
+
}
|
|
1719
|
+
var DiscordCommandArgFallbackButton = class extends Button {
|
|
1720
|
+
constructor(params) {
|
|
1721
|
+
super();
|
|
1722
|
+
this.params = params;
|
|
1723
|
+
this.label = "cmdarg";
|
|
1724
|
+
this.customId = "cmdarg:seed=1";
|
|
2110
1725
|
}
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
};
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
await params.interaction.reply(payload);
|
|
2122
|
-
});
|
|
2123
|
-
return dispatchResult;
|
|
1726
|
+
async run(interaction, data) {
|
|
1727
|
+
await runDiscordCommandArgButton({
|
|
1728
|
+
...this.params,
|
|
1729
|
+
interaction,
|
|
1730
|
+
data
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
};
|
|
1734
|
+
function createDiscordCommandArgFallbackButton$1(params) {
|
|
1735
|
+
return new DiscordCommandArgFallbackButton(params);
|
|
2124
1736
|
}
|
|
2125
1737
|
//#endregion
|
|
2126
1738
|
//#region extensions/discord/src/monitor/native-interaction-channel-context.ts
|
|
@@ -2398,11 +2010,11 @@ async function resolveDiscordNativeAutocompleteAuthorized(params) {
|
|
|
2398
2010
|
//#endregion
|
|
2399
2011
|
//#region extensions/discord/src/monitor/native-command-bypass.ts
|
|
2400
2012
|
function shouldBypassConfiguredAcpEnsure(commandName) {
|
|
2401
|
-
return
|
|
2013
|
+
return commandName.trim().toLowerCase() === "acp";
|
|
2402
2014
|
}
|
|
2403
2015
|
function shouldBypassConfiguredAcpGuildGuards(commandName) {
|
|
2404
|
-
const
|
|
2405
|
-
return
|
|
2016
|
+
const command = commandName.trim().toLowerCase();
|
|
2017
|
+
return command === "new" || command === "reset";
|
|
2406
2018
|
}
|
|
2407
2019
|
//#endregion
|
|
2408
2020
|
//#region extensions/discord/src/monitor/inbound-context.ts
|
|
@@ -2423,279 +2035,103 @@ function createDiscordSupplementalContextAccessChecker(params) {
|
|
|
2423
2035
|
userName: sender.name,
|
|
2424
2036
|
userTag: sender.tag,
|
|
2425
2037
|
allowNameMatching: params.allowNameMatching
|
|
2426
|
-
})
|
|
2427
|
-
});
|
|
2428
|
-
};
|
|
2429
|
-
}
|
|
2430
|
-
function buildDiscordGroupSystemPrompt(channelConfig) {
|
|
2431
|
-
const systemPromptParts = [channelConfig?.systemPrompt?.trim() || null].filter((entry) => Boolean(entry));
|
|
2432
|
-
return systemPromptParts.length > 0 ? systemPromptParts.join("\n\n") : void 0;
|
|
2433
|
-
}
|
|
2434
|
-
function buildDiscordChannelStructuredContext(params) {
|
|
2435
|
-
if (!params.isGuild) return;
|
|
2436
|
-
const entries = [];
|
|
2437
|
-
if (typeof params.channelTopic === "string" && params.channelTopic.trim().length > 0) entries.push({
|
|
2438
|
-
label: "Discord channel metadata",
|
|
2439
|
-
source: "discord",
|
|
2440
|
-
type: "channel_metadata",
|
|
2441
|
-
payload: { topic: params.channelTopic.trim() }
|
|
2442
|
-
});
|
|
2443
|
-
return entries.length > 0 ? entries : void 0;
|
|
2444
|
-
}
|
|
2445
|
-
function buildDiscordInboundAccessContext(params) {
|
|
2446
|
-
return {
|
|
2447
|
-
groupSystemPrompt: params.isGuild ? buildDiscordGroupSystemPrompt(params.channelConfig) : void 0,
|
|
2448
|
-
channelStructuredContext: buildDiscordChannelStructuredContext({
|
|
2449
|
-
isGuild: params.isGuild,
|
|
2450
|
-
channelTopic: params.channelTopic
|
|
2451
|
-
}),
|
|
2452
|
-
ownerAllowFrom: resolveDiscordOwnerAllowFrom({
|
|
2453
|
-
channelConfig: params.channelConfig,
|
|
2454
|
-
guildInfo: params.guildInfo,
|
|
2455
|
-
sender: params.sender,
|
|
2456
|
-
allowNameMatching: params.allowNameMatching
|
|
2457
|
-
})
|
|
2458
|
-
};
|
|
2459
|
-
}
|
|
2460
|
-
//#endregion
|
|
2461
|
-
//#region extensions/discord/src/monitor/native-command-context.ts
|
|
2462
|
-
function buildDiscordNativeCommandContext(params) {
|
|
2463
|
-
const conversationLabel = params.isDirectMessage ? params.user.globalName ?? params.user.username : params.channelId;
|
|
2464
|
-
const { groupSystemPrompt, ownerAllowFrom, channelStructuredContext } = buildDiscordInboundAccessContext({
|
|
2465
|
-
channelConfig: params.channelConfig,
|
|
2466
|
-
guildInfo: params.guildInfo,
|
|
2467
|
-
sender: params.sender,
|
|
2468
|
-
allowNameMatching: params.allowNameMatching,
|
|
2469
|
-
isGuild: params.isGuild,
|
|
2470
|
-
channelTopic: params.channelTopic
|
|
2471
|
-
});
|
|
2472
|
-
return finalizeInboundContext({
|
|
2473
|
-
Body: params.prompt,
|
|
2474
|
-
BodyForAgent: params.prompt,
|
|
2475
|
-
RawBody: params.prompt,
|
|
2476
|
-
CommandBody: params.prompt,
|
|
2477
|
-
CommandArgs: params.commandArgs,
|
|
2478
|
-
From: params.isDirectMessage ? `discord:${params.user.id}` : params.isGroupDm ? `discord:group:${params.channelId}` : `discord:channel:${params.channelId}`,
|
|
2479
|
-
To: `slash:${params.user.id}`,
|
|
2480
|
-
SessionKey: params.sessionKey,
|
|
2481
|
-
CommandTargetSessionKey: params.commandTargetSessionKey,
|
|
2482
|
-
AccountId: params.accountId ?? void 0,
|
|
2483
|
-
ChatType: params.isDirectMessage ? "direct" : params.isGroupDm ? "group" : "channel",
|
|
2484
|
-
ConversationLabel: conversationLabel,
|
|
2485
|
-
GroupSubject: params.isGuild ? params.guildName : void 0,
|
|
2486
|
-
GroupSpace: params.isGuild ? params.guildInfo?.id ?? params.guildInfo?.slug ?? params.guildId : void 0,
|
|
2487
|
-
MemberRoleIds: params.memberRoleIds,
|
|
2488
|
-
GroupSystemPrompt: groupSystemPrompt,
|
|
2489
|
-
ChannelStructuredContext: channelStructuredContext,
|
|
2490
|
-
OwnerAllowFrom: ownerAllowFrom,
|
|
2491
|
-
SenderName: params.user.globalName ?? params.user.username,
|
|
2492
|
-
SenderId: params.user.id,
|
|
2493
|
-
SenderUsername: params.user.username,
|
|
2494
|
-
SenderTag: params.sender.tag,
|
|
2495
|
-
Provider: "discord",
|
|
2496
|
-
Surface: "discord",
|
|
2497
|
-
WasMentioned: true,
|
|
2498
|
-
MessageSid: params.interactionId,
|
|
2499
|
-
MessageThreadId: params.isThreadChannel ? params.channelId : void 0,
|
|
2500
|
-
Timestamp: params.timestampMs ?? Date.now(),
|
|
2501
|
-
CommandAuthorized: params.commandAuthorized,
|
|
2502
|
-
CommandTurn: {
|
|
2503
|
-
kind: "native",
|
|
2504
|
-
source: "native",
|
|
2505
|
-
authorized: params.commandAuthorized,
|
|
2506
|
-
body: params.prompt
|
|
2507
|
-
},
|
|
2508
|
-
CommandSource: "native",
|
|
2509
|
-
OriginatingChannel: "discord",
|
|
2510
|
-
OriginatingTo: resolveDiscordConversationIdentity({
|
|
2511
|
-
isDirectMessage: params.isDirectMessage,
|
|
2512
|
-
userId: params.user.id,
|
|
2513
|
-
channelId: params.channelId
|
|
2514
|
-
}) ?? (params.isDirectMessage ? `user:${params.user.id}` : `channel:${params.channelId}`),
|
|
2515
|
-
ThreadParentId: params.isThreadChannel ? params.threadParentId : void 0
|
|
2516
|
-
});
|
|
2517
|
-
}
|
|
2518
|
-
//#endregion
|
|
2519
|
-
//#region extensions/discord/src/monitor/native-command-status.ts
|
|
2520
|
-
async function maybeDeliverDiscordDirectStatus(params) {
|
|
2521
|
-
if (params.suppressReplies || params.commandName !== "status") return null;
|
|
2522
|
-
const statusReply = await params.resolveDirectStatusReplyForSession({
|
|
2523
|
-
cfg: params.cfg,
|
|
2524
|
-
sessionKey: params.commandTargetSessionKey?.trim() || params.sessionKey,
|
|
2525
|
-
channel: params.channel,
|
|
2526
|
-
senderId: params.senderId,
|
|
2527
|
-
senderIsOwner: params.senderIsOwner,
|
|
2528
|
-
isAuthorizedSender: params.isAuthorizedSender,
|
|
2529
|
-
isGroup: params.isGroup,
|
|
2530
|
-
defaultGroupActivation: params.defaultGroupActivation
|
|
2531
|
-
});
|
|
2532
|
-
if (statusReply && hasRenderableReplyPayload(statusReply)) {
|
|
2533
|
-
await deliverDiscordInteractionReply({
|
|
2534
|
-
interaction: params.interaction,
|
|
2535
|
-
payload: statusReply,
|
|
2536
|
-
mediaLocalRoots: params.mediaLocalRoots,
|
|
2537
|
-
textLimit: resolveTextChunkLimit(params.cfg, "discord", params.accountId, { fallbackLimit: 2e3 }),
|
|
2538
|
-
maxLinesPerMessage: resolveDiscordMaxLinesPerMessage({
|
|
2539
|
-
cfg: params.cfg,
|
|
2540
|
-
discordConfig: params.discordConfig,
|
|
2541
|
-
accountId: params.accountId
|
|
2542
|
-
}),
|
|
2543
|
-
preferFollowUp: params.preferFollowUp,
|
|
2544
|
-
responseEphemeral: params.responseEphemeral,
|
|
2545
|
-
chunkMode: resolveChunkMode(params.cfg, "discord", params.accountId)
|
|
2546
|
-
});
|
|
2547
|
-
return {
|
|
2548
|
-
accepted: true,
|
|
2549
|
-
effectiveRoute: params.effectiveRoute
|
|
2550
|
-
};
|
|
2551
|
-
}
|
|
2552
|
-
await params.respond("Status unavailable.");
|
|
2553
|
-
return {
|
|
2554
|
-
accepted: true,
|
|
2555
|
-
effectiveRoute: params.effectiveRoute
|
|
2556
|
-
};
|
|
2557
|
-
}
|
|
2558
|
-
//#endregion
|
|
2559
|
-
//#region extensions/discord/src/monitor/commands.ts
|
|
2560
|
-
function resolveDiscordSlashCommandConfig(raw) {
|
|
2561
|
-
return { ephemeral: raw?.ephemeral !== false };
|
|
2562
|
-
}
|
|
2563
|
-
//#endregion
|
|
2564
|
-
//#region extensions/discord/src/monitor/native-command-arg-ui.ts
|
|
2565
|
-
const DISCORD_COMMAND_ARG_CUSTOM_ID_KEY = "cmdarg";
|
|
2566
|
-
function createCommandArgsWithValue(params) {
|
|
2567
|
-
return { values: { [params.argName]: params.value } };
|
|
2568
|
-
}
|
|
2569
|
-
function buildDiscordCommandArgCustomId(params) {
|
|
2570
|
-
return [
|
|
2571
|
-
`${DISCORD_COMMAND_ARG_CUSTOM_ID_KEY}:command=${encodeCustomIdComponent(params.command)}`,
|
|
2572
|
-
`arg=${encodeCustomIdComponent(params.arg)}`,
|
|
2573
|
-
`value=${encodeCustomIdComponent(params.value)}`,
|
|
2574
|
-
`user=${encodeCustomIdComponent(params.userId)}`
|
|
2575
|
-
].join(";");
|
|
2576
|
-
}
|
|
2577
|
-
function parseDiscordCommandArgData(data) {
|
|
2578
|
-
if (!data || typeof data !== "object") return null;
|
|
2579
|
-
const coerce = (value) => typeof value === "string" || typeof value === "number" ? String(value) : "";
|
|
2580
|
-
const rawCommand = coerce(data.command);
|
|
2581
|
-
const rawArg = coerce(data.arg);
|
|
2582
|
-
const rawValue = coerce(data.value);
|
|
2583
|
-
const rawUser = coerce(data.user);
|
|
2584
|
-
if (!rawCommand || !rawArg || !rawValue || !rawUser) return null;
|
|
2585
|
-
return {
|
|
2586
|
-
command: decodeCustomIdComponent(rawCommand),
|
|
2587
|
-
arg: decodeCustomIdComponent(rawArg),
|
|
2588
|
-
value: decodeCustomIdComponent(rawValue),
|
|
2589
|
-
userId: decodeCustomIdComponent(rawUser)
|
|
2590
|
-
};
|
|
2591
|
-
}
|
|
2592
|
-
async function handleDiscordCommandArgInteraction(params) {
|
|
2593
|
-
const { interaction, data, ctx } = params;
|
|
2594
|
-
const clearWithMessage = async (content) => await params.safeInteractionCall("command arg update", () => interaction.update({
|
|
2595
|
-
content,
|
|
2596
|
-
components: []
|
|
2597
|
-
}));
|
|
2598
|
-
const parsed = parseDiscordCommandArgData(data);
|
|
2599
|
-
if (!parsed) {
|
|
2600
|
-
await clearWithMessage("Sorry, that selection is no longer available.");
|
|
2601
|
-
return;
|
|
2602
|
-
}
|
|
2603
|
-
if (interaction.user?.id && interaction.user.id !== parsed.userId) {
|
|
2604
|
-
await params.safeInteractionCall("command arg ack", () => interaction.acknowledge());
|
|
2605
|
-
return;
|
|
2606
|
-
}
|
|
2607
|
-
const commandDefinition = findCommandByNativeName(parsed.command, "discord") ?? listChatCommands().find((entry) => entry.key === parsed.command);
|
|
2608
|
-
if (!commandDefinition) {
|
|
2609
|
-
await clearWithMessage("Sorry, that command is no longer available.");
|
|
2610
|
-
return;
|
|
2611
|
-
}
|
|
2612
|
-
if (await clearWithMessage(`⏳ Applying ${parsed.value}...`) === null) return;
|
|
2613
|
-
const commandArgs = createCommandArgsWithValue({
|
|
2614
|
-
argName: parsed.arg,
|
|
2615
|
-
value: parsed.value
|
|
2616
|
-
});
|
|
2617
|
-
const commandArgsWithRaw = {
|
|
2618
|
-
...commandArgs,
|
|
2619
|
-
raw: serializeCommandArgs(commandDefinition, commandArgs)
|
|
2620
|
-
};
|
|
2621
|
-
const prompt = buildCommandTextFromArgs(commandDefinition, commandArgsWithRaw);
|
|
2622
|
-
await params.dispatchCommandInteraction({
|
|
2623
|
-
interaction,
|
|
2624
|
-
prompt,
|
|
2625
|
-
command: commandDefinition,
|
|
2626
|
-
commandArgs: commandArgsWithRaw,
|
|
2627
|
-
cfg: ctx.cfg,
|
|
2628
|
-
discordConfig: ctx.discordConfig,
|
|
2629
|
-
accountId: ctx.accountId,
|
|
2630
|
-
sessionPrefix: ctx.sessionPrefix,
|
|
2631
|
-
preferFollowUp: true,
|
|
2632
|
-
threadBindings: ctx.threadBindings,
|
|
2633
|
-
responseEphemeral: resolveDiscordSlashCommandConfig(ctx.discordConfig?.slashCommand).ephemeral,
|
|
2634
|
-
pluginCommandDispatch: { kind: "non-plugin" }
|
|
2635
|
-
});
|
|
2038
|
+
})
|
|
2039
|
+
});
|
|
2040
|
+
};
|
|
2636
2041
|
}
|
|
2637
|
-
|
|
2638
|
-
|
|
2042
|
+
function buildDiscordGroupSystemPrompt(channelConfig) {
|
|
2043
|
+
const systemPromptParts = [channelConfig?.systemPrompt?.trim() || null].filter((entry) => Boolean(entry));
|
|
2044
|
+
return systemPromptParts.length > 0 ? systemPromptParts.join("\n\n") : void 0;
|
|
2639
2045
|
}
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
async run(interaction, data) {
|
|
2649
|
-
await runDiscordCommandArgButton({
|
|
2650
|
-
...this.params,
|
|
2651
|
-
interaction,
|
|
2652
|
-
data
|
|
2653
|
-
});
|
|
2654
|
-
}
|
|
2655
|
-
};
|
|
2656
|
-
function buildDiscordCommandArgMenu(params) {
|
|
2657
|
-
const { command, menu, interaction } = params;
|
|
2658
|
-
const commandLabel = command.nativeName ?? command.key;
|
|
2659
|
-
const userId = interaction.user?.id ?? "";
|
|
2660
|
-
const rows = chunkItems(menu.choices, 4).map((choices) => {
|
|
2661
|
-
return new Row(choices.map((choice) => new DiscordCommandArgButton({
|
|
2662
|
-
label: choice.label,
|
|
2663
|
-
customId: buildDiscordCommandArgCustomId({
|
|
2664
|
-
command: commandLabel,
|
|
2665
|
-
arg: menu.arg.name,
|
|
2666
|
-
value: choice.value,
|
|
2667
|
-
userId
|
|
2668
|
-
}),
|
|
2669
|
-
ctx: params.ctx,
|
|
2670
|
-
safeInteractionCall: params.safeInteractionCall,
|
|
2671
|
-
dispatchCommandInteraction: params.dispatchCommandInteraction
|
|
2672
|
-
})));
|
|
2046
|
+
function buildDiscordChannelStructuredContext(params) {
|
|
2047
|
+
if (!params.isGuild) return;
|
|
2048
|
+
const entries = [];
|
|
2049
|
+
if (typeof params.channelTopic === "string" && params.channelTopic.trim().length > 0) entries.push({
|
|
2050
|
+
label: "Discord channel metadata",
|
|
2051
|
+
source: "discord",
|
|
2052
|
+
type: "channel_metadata",
|
|
2053
|
+
payload: { topic: params.channelTopic.trim() }
|
|
2673
2054
|
});
|
|
2055
|
+
return entries.length > 0 ? entries : void 0;
|
|
2056
|
+
}
|
|
2057
|
+
function buildDiscordInboundAccessContext(params) {
|
|
2674
2058
|
return {
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2059
|
+
groupSystemPrompt: params.isGuild ? buildDiscordGroupSystemPrompt(params.channelConfig) : void 0,
|
|
2060
|
+
channelStructuredContext: buildDiscordChannelStructuredContext({
|
|
2061
|
+
isGuild: params.isGuild,
|
|
2062
|
+
channelTopic: params.channelTopic
|
|
2678
2063
|
}),
|
|
2679
|
-
|
|
2064
|
+
ownerAllowFrom: resolveDiscordOwnerAllowFrom({
|
|
2065
|
+
channelConfig: params.channelConfig,
|
|
2066
|
+
guildInfo: params.guildInfo,
|
|
2067
|
+
sender: params.sender,
|
|
2068
|
+
allowNameMatching: params.allowNameMatching
|
|
2069
|
+
})
|
|
2680
2070
|
};
|
|
2681
2071
|
}
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2072
|
+
//#endregion
|
|
2073
|
+
//#region extensions/discord/src/monitor/native-command-context.ts
|
|
2074
|
+
function buildDiscordNativeCommandContext(params) {
|
|
2075
|
+
const conversationLabel = params.isDirectMessage ? params.user.globalName ?? params.user.username : params.channelId;
|
|
2076
|
+
const { groupSystemPrompt, ownerAllowFrom, channelStructuredContext } = buildDiscordInboundAccessContext({
|
|
2077
|
+
channelConfig: params.channelConfig,
|
|
2078
|
+
guildInfo: params.guildInfo,
|
|
2079
|
+
sender: params.sender,
|
|
2080
|
+
allowNameMatching: params.allowNameMatching,
|
|
2081
|
+
isGuild: params.isGuild,
|
|
2082
|
+
channelTopic: params.channelTopic
|
|
2083
|
+
});
|
|
2084
|
+
return finalizeInboundContext({
|
|
2085
|
+
Body: params.prompt,
|
|
2086
|
+
BodyForAgent: params.prompt,
|
|
2087
|
+
RawBody: params.prompt,
|
|
2088
|
+
CommandBody: params.prompt,
|
|
2089
|
+
CommandArgs: params.commandArgs,
|
|
2090
|
+
From: params.isDirectMessage ? `discord:${params.user.id}` : params.isGroupDm ? `discord:group:${params.channelId}` : `discord:channel:${params.channelId}`,
|
|
2091
|
+
To: `slash:${params.user.id}`,
|
|
2092
|
+
SessionKey: params.sessionKey,
|
|
2093
|
+
CommandTargetSessionKey: params.commandTargetSessionKey,
|
|
2094
|
+
AccountId: params.accountId ?? void 0,
|
|
2095
|
+
ChatType: params.isDirectMessage ? "direct" : params.isGroupDm ? "group" : "channel",
|
|
2096
|
+
...buildDiscordConversationRouteContext({
|
|
2097
|
+
isDirectMessage: params.isDirectMessage,
|
|
2098
|
+
isGroupDm: params.isGroupDm,
|
|
2099
|
+
directUserId: params.user.id,
|
|
2100
|
+
conversationId: params.channelId,
|
|
2101
|
+
isThread: params.isThreadChannel,
|
|
2102
|
+
parentConversationId: params.threadParentId
|
|
2103
|
+
}),
|
|
2104
|
+
ConversationLabel: conversationLabel,
|
|
2105
|
+
GroupSubject: params.isGuild ? params.guildName : void 0,
|
|
2106
|
+
GroupSpace: params.isGuild ? params.guildInfo?.id ?? params.guildInfo?.slug ?? params.guildId : void 0,
|
|
2107
|
+
MemberRoleIds: params.memberRoleIds,
|
|
2108
|
+
GroupSystemPrompt: groupSystemPrompt,
|
|
2109
|
+
ChannelStructuredContext: channelStructuredContext,
|
|
2110
|
+
OwnerAllowFrom: ownerAllowFrom,
|
|
2111
|
+
SenderName: params.user.globalName ?? params.user.username,
|
|
2112
|
+
SenderId: params.user.id,
|
|
2113
|
+
SenderUsername: params.user.username,
|
|
2114
|
+
SenderTag: params.sender.tag,
|
|
2115
|
+
Provider: "discord",
|
|
2116
|
+
Surface: "discord",
|
|
2117
|
+
WasMentioned: true,
|
|
2118
|
+
MessageSid: params.interactionId,
|
|
2119
|
+
Timestamp: params.timestampMs ?? Date.now(),
|
|
2120
|
+
CommandAuthorized: params.commandAuthorized,
|
|
2121
|
+
CommandTurn: {
|
|
2122
|
+
kind: "native",
|
|
2123
|
+
source: "native",
|
|
2124
|
+
authorized: params.commandAuthorized,
|
|
2125
|
+
body: params.prompt
|
|
2126
|
+
},
|
|
2127
|
+
CommandSource: "native",
|
|
2128
|
+
OriginatingChannel: "discord",
|
|
2129
|
+
OriginatingTo: resolveDiscordConversationIdentity({
|
|
2130
|
+
isDirectMessage: params.isDirectMessage,
|
|
2131
|
+
userId: params.user.id,
|
|
2132
|
+
channelId: params.channelId
|
|
2133
|
+
}) ?? (params.isDirectMessage ? `user:${params.user.id}` : `channel:${params.channelId}`)
|
|
2134
|
+
});
|
|
2699
2135
|
}
|
|
2700
2136
|
//#endregion
|
|
2701
2137
|
//#region extensions/discord/src/monitor/model-picker-preferences.ts
|
|
@@ -3694,6 +3130,7 @@ async function applyDiscordModelPickerSelection(params) {
|
|
|
3694
3130
|
preferFollowUp: true,
|
|
3695
3131
|
threadBindings: params.threadBindings,
|
|
3696
3132
|
suppressReplies: true,
|
|
3133
|
+
dispatchReplyFromConfig: params.dispatchReplyFromConfig,
|
|
3697
3134
|
pluginCommandDispatch: { kind: "non-plugin" }
|
|
3698
3135
|
}), 12e3);
|
|
3699
3136
|
if (!dispatchResult.accepted) return {
|
|
@@ -4351,6 +3788,7 @@ async function handleDiscordModelPickerInteraction(params) {
|
|
|
4351
3788
|
accountId: ctx.accountId,
|
|
4352
3789
|
sessionPrefix: ctx.sessionPrefix,
|
|
4353
3790
|
threadBindings: ctx.threadBindings,
|
|
3791
|
+
dispatchReplyFromConfig: ctx.dispatchReplyFromConfig,
|
|
4354
3792
|
route,
|
|
4355
3793
|
resolvedModelRef,
|
|
4356
3794
|
selectedRuntime,
|
|
@@ -4414,6 +3852,46 @@ function createDiscordModelPickerFallbackSelect$1(params) {
|
|
|
4414
3852
|
return new DiscordModelPickerFallbackSelect(params);
|
|
4415
3853
|
}
|
|
4416
3854
|
//#endregion
|
|
3855
|
+
//#region extensions/discord/src/monitor/native-command-status.ts
|
|
3856
|
+
async function maybeDeliverDiscordDirectStatus(params) {
|
|
3857
|
+
if (params.suppressReplies || params.commandName !== "status") return null;
|
|
3858
|
+
const statusReply = await params.resolveDirectStatusReplyForSession({
|
|
3859
|
+
cfg: params.cfg,
|
|
3860
|
+
sessionKey: params.commandTargetSessionKey?.trim() || params.sessionKey,
|
|
3861
|
+
channel: params.channel,
|
|
3862
|
+
senderId: params.senderId,
|
|
3863
|
+
senderIsOwner: params.senderIsOwner,
|
|
3864
|
+
isAuthorizedSender: params.isAuthorizedSender,
|
|
3865
|
+
isGroup: params.isGroup,
|
|
3866
|
+
defaultGroupActivation: params.defaultGroupActivation
|
|
3867
|
+
});
|
|
3868
|
+
if (statusReply && hasRenderableReplyPayload(statusReply)) {
|
|
3869
|
+
await deliverDiscordInteractionReply({
|
|
3870
|
+
interaction: params.interaction,
|
|
3871
|
+
payload: statusReply,
|
|
3872
|
+
mediaLocalRoots: params.mediaLocalRoots,
|
|
3873
|
+
textLimit: resolveTextChunkLimit(params.cfg, "discord", params.accountId, { fallbackLimit: 2e3 }),
|
|
3874
|
+
maxLinesPerMessage: resolveDiscordMaxLinesPerMessage({
|
|
3875
|
+
cfg: params.cfg,
|
|
3876
|
+
discordConfig: params.discordConfig,
|
|
3877
|
+
accountId: params.accountId
|
|
3878
|
+
}),
|
|
3879
|
+
preferFollowUp: params.preferFollowUp,
|
|
3880
|
+
responseEphemeral: params.responseEphemeral,
|
|
3881
|
+
chunkMode: resolveChunkMode(params.cfg, "discord", params.accountId)
|
|
3882
|
+
});
|
|
3883
|
+
return {
|
|
3884
|
+
accepted: true,
|
|
3885
|
+
effectiveRoute: params.effectiveRoute
|
|
3886
|
+
};
|
|
3887
|
+
}
|
|
3888
|
+
await params.respond("Status unavailable.");
|
|
3889
|
+
return {
|
|
3890
|
+
accepted: true,
|
|
3891
|
+
effectiveRoute: params.effectiveRoute
|
|
3892
|
+
};
|
|
3893
|
+
}
|
|
3894
|
+
//#endregion
|
|
4417
3895
|
//#region extensions/discord/src/monitor/native-command.args.ts
|
|
4418
3896
|
function readDiscordCommandArgs(interaction, definitions) {
|
|
4419
3897
|
if (!definitions || definitions.length === 0) return;
|
|
@@ -4446,7 +3924,7 @@ const DISCORD_COMMAND_DESCRIPTION_MAX = 100;
|
|
|
4446
3924
|
function truncateDiscordCommandDescription(params) {
|
|
4447
3925
|
const { value, label } = params;
|
|
4448
3926
|
if (value.length <= DISCORD_COMMAND_DESCRIPTION_MAX) return value;
|
|
4449
|
-
log$1.
|
|
3927
|
+
log$1.debug(`discord: truncating native command description (${label}) from ${value.length} to ${DISCORD_COMMAND_DESCRIPTION_MAX}: ${JSON.stringify(value)}`);
|
|
4450
3928
|
return truncateUtf16Safe(value, DISCORD_COMMAND_DESCRIPTION_MAX);
|
|
4451
3929
|
}
|
|
4452
3930
|
function truncateDiscordCommandDescriptionLocalizations(params) {
|
|
@@ -4543,7 +4021,7 @@ function buildDiscordCommandOptions(params) {
|
|
|
4543
4021
|
const log = createSubsystemLogger("discord/native-command");
|
|
4544
4022
|
const NON_PLUGIN_COMMAND_DISPATCH = Object.freeze({ kind: "non-plugin" });
|
|
4545
4023
|
function createDiscordNativeCommand(params) {
|
|
4546
|
-
const { command, cfg, discordConfig, accountId, sessionPrefix, ephemeralDefault, threadBindings } = params;
|
|
4024
|
+
const { command, cfg, discordConfig, accountId, sessionPrefix, ephemeralDefault, threadBindings, dispatchReplyFromConfig } = params;
|
|
4547
4025
|
const fallbackCommandDefinition = createNativeCommandDefinition(command);
|
|
4548
4026
|
const pluginCommandCandidate = "prepareDispatch" in command ? command : void 0;
|
|
4549
4027
|
const commandDefinition = pluginCommandCandidate ? fallbackCommandDefinition : findCommandByNativeName$1(command.name, "discord", { includeBundledChannelFallback: false }) ?? fallbackCommandDefinition;
|
|
@@ -4610,13 +4088,14 @@ function createDiscordNativeCommand(params) {
|
|
|
4610
4088
|
preferFollowUp: true,
|
|
4611
4089
|
threadBindings,
|
|
4612
4090
|
responseEphemeral: ephemeralDefault,
|
|
4091
|
+
dispatchReplyFromConfig,
|
|
4613
4092
|
pluginCommandDispatch: preparedPluginCommand ?? NON_PLUGIN_COMMAND_DISPATCH
|
|
4614
4093
|
});
|
|
4615
4094
|
}
|
|
4616
4095
|
}();
|
|
4617
4096
|
}
|
|
4618
4097
|
async function dispatchDiscordCommandInteraction(params) {
|
|
4619
|
-
const { interaction, prompt, command, commandArgs, cfg: inputConfig, discordConfig, accountId, sessionPrefix, preferFollowUp, threadBindings, responseEphemeral, suppressReplies } = params;
|
|
4098
|
+
const { interaction, prompt, command, commandArgs, cfg: inputConfig, discordConfig, accountId, sessionPrefix, preferFollowUp, threadBindings, responseEphemeral, suppressReplies, dispatchReplyFromConfig } = params;
|
|
4620
4099
|
const cfg = getRuntimeConfigSnapshot() ?? inputConfig;
|
|
4621
4100
|
const commandName = command.nativeName ?? command.key;
|
|
4622
4101
|
const respond = async (content, options) => {
|
|
@@ -4854,7 +4333,8 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
4854
4333
|
discordConfig,
|
|
4855
4334
|
accountId,
|
|
4856
4335
|
sessionPrefix,
|
|
4857
|
-
threadBindings
|
|
4336
|
+
threadBindings,
|
|
4337
|
+
dispatchReplyFromConfig
|
|
4858
4338
|
},
|
|
4859
4339
|
safeInteractionCall: safeDiscordInteractionCall,
|
|
4860
4340
|
dispatchCommandInteraction: dispatchDiscordCommandInteraction
|
|
@@ -5041,6 +4521,7 @@ async function dispatchDiscordCommandInteraction(params) {
|
|
|
5041
4521
|
preferFollowUp,
|
|
5042
4522
|
responseEphemeral,
|
|
5043
4523
|
suppressReplies,
|
|
4524
|
+
dispatchReplyFromConfig,
|
|
5044
4525
|
log,
|
|
5045
4526
|
pluginCommandDispatch: params.pluginCommandDispatch
|
|
5046
4527
|
});
|
|
@@ -5097,7 +4578,7 @@ function canResumeAfterGatewayClose(code) {
|
|
|
5097
4578
|
//#region extensions/discord/src/internal/gateway-identify-limiter.ts
|
|
5098
4579
|
const IDENTIFY_WINDOW_MS = 5e3;
|
|
5099
4580
|
function normalizeMaxConcurrency(value) {
|
|
5100
|
-
const parsed = parseFiniteNumber
|
|
4581
|
+
const parsed = parseFiniteNumber(value);
|
|
5101
4582
|
return parsed === void 0 ? 1 : Math.max(1, Math.floor(parsed));
|
|
5102
4583
|
}
|
|
5103
4584
|
var GatewayIdentifyLimiter = class {
|
|
@@ -5305,7 +4786,7 @@ var DiscordGatewayVoiceStateCache = class {
|
|
|
5305
4786
|
}
|
|
5306
4787
|
listVoiceChannelStates(guildId, channelId) {
|
|
5307
4788
|
const states = this.statesByGuild.get(guildId);
|
|
5308
|
-
if (!states) return
|
|
4789
|
+
if (!states) return null;
|
|
5309
4790
|
const result = [];
|
|
5310
4791
|
for (const state of states.values()) if (state.channel_id === channelId) result.push({ ...state });
|
|
5311
4792
|
return result;
|
|
@@ -5415,6 +4896,9 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5415
4896
|
listVoiceChannelStates(guildId, channelId) {
|
|
5416
4897
|
return this.voiceStateCache.listVoiceChannelStates(guildId, channelId);
|
|
5417
4898
|
}
|
|
4899
|
+
async fetchGuildEmojis(guildId, fetcher) {
|
|
4900
|
+
return this.client ? await this.client.fetchGuildEmojis(guildId, fetcher) : await fetcher();
|
|
4901
|
+
}
|
|
5418
4902
|
takeVoiceStateTransition(state) {
|
|
5419
4903
|
return this.voiceStateCache.takeTransition(state);
|
|
5420
4904
|
}
|
|
@@ -5518,7 +5002,10 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5518
5002
|
if (payload.s !== null && payload.s !== void 0) this.sequence = payload.s;
|
|
5519
5003
|
switch (payload.op) {
|
|
5520
5004
|
case GatewayOpcodes.Hello: {
|
|
5521
|
-
this.startHeartbeat(payload.d
|
|
5005
|
+
this.startHeartbeat(asSafeIntegerInRange(asOptionalRecord(payload.d)?.heartbeat_interval, {
|
|
5006
|
+
min: 1,
|
|
5007
|
+
max: MAX_TIMER_TIMEOUT_MS
|
|
5008
|
+
}) ?? 45e3);
|
|
5522
5009
|
const resumeState = resume ? this.getResumeState() : null;
|
|
5523
5010
|
if (resumeState) this.send({
|
|
5524
5011
|
op: GatewayOpcodes.Resume,
|
|
@@ -5721,12 +5208,6 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5721
5208
|
}
|
|
5722
5209
|
};
|
|
5723
5210
|
//#endregion
|
|
5724
|
-
//#region extensions/discord/src/voice/config.ts
|
|
5725
|
-
function resolveDiscordVoiceEnabled(voice) {
|
|
5726
|
-
if (voice?.enabled !== void 0) return voice.enabled;
|
|
5727
|
-
return voice !== void 0;
|
|
5728
|
-
}
|
|
5729
|
-
//#endregion
|
|
5730
5211
|
//#region extensions/discord/src/monitor/presence.ts
|
|
5731
5212
|
const DEFAULT_CUSTOM_ACTIVITY_TYPE$1 = 4;
|
|
5732
5213
|
const CUSTOM_STATUS_NAME$1 = "Custom Status";
|
|
@@ -6268,7 +5749,7 @@ function resolveDiscordGatewayIntents(params) {
|
|
|
6268
5749
|
const intentsConfig = params?.intentsConfig;
|
|
6269
5750
|
const voiceEnabled = params?.voiceEnabled;
|
|
6270
5751
|
const voiceStatesEnabled = intentsConfig?.voiceStates ?? voiceEnabled ?? false;
|
|
6271
|
-
let intents = GatewayIntents.Guilds | GatewayIntents.GuildMessages | GatewayIntents.DirectMessages | GatewayIntents.GuildMessageReactions | GatewayIntents.DirectMessageReactions;
|
|
5752
|
+
let intents = GatewayIntents.Guilds | GatewayIntents.GuildExpressions | GatewayIntents.GuildMessages | GatewayIntents.DirectMessages | GatewayIntents.GuildMessageReactions | GatewayIntents.DirectMessageReactions;
|
|
6272
5753
|
if (intentsConfig?.messageContent !== false) intents |= GatewayIntents.MessageContent;
|
|
6273
5754
|
if (voiceStatesEnabled) intents |= GatewayIntents.GuildVoiceStates;
|
|
6274
5755
|
if (intentsConfig?.presence) intents |= GatewayIntents.GuildPresences;
|
|
@@ -7045,7 +6526,7 @@ async function runDiscordGatewayLifecycle(params) {
|
|
|
7045
6526
|
gatewayEmitter?.removeListener(DISCORD_GATEWAY_TRANSPORT_ACTIVITY_EVENT, onGatewayTransportActivity);
|
|
7046
6527
|
if (params.voiceManager) {
|
|
7047
6528
|
await params.voiceManager.destroy();
|
|
7048
|
-
const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-
|
|
6529
|
+
const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-BR11iHA4.js").then((n) => n.n);
|
|
7049
6530
|
setDiscordTranscriptsVoiceManager({
|
|
7050
6531
|
accountId: params.accountId,
|
|
7051
6532
|
manager: null
|
|
@@ -7060,7 +6541,7 @@ async function runDiscordGatewayLifecycle(params) {
|
|
|
7060
6541
|
let discordVoiceRuntimePromise;
|
|
7061
6542
|
let discordProviderSessionRuntimePromise;
|
|
7062
6543
|
async function loadDiscordVoiceRuntime() {
|
|
7063
|
-
const promise = discordVoiceRuntimePromise ?? import("./voice-runtime-
|
|
6544
|
+
const promise = discordVoiceRuntimePromise ?? import("./voice-runtime-DIeaa8fJ.js");
|
|
7064
6545
|
discordVoiceRuntimePromise = promise;
|
|
7065
6546
|
try {
|
|
7066
6547
|
return await promise;
|
|
@@ -7070,7 +6551,7 @@ async function loadDiscordVoiceRuntime() {
|
|
|
7070
6551
|
}
|
|
7071
6552
|
}
|
|
7072
6553
|
async function loadDiscordProviderSessionRuntime() {
|
|
7073
|
-
const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-
|
|
6554
|
+
const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-B9xe-Qaf.js");
|
|
7074
6555
|
discordProviderSessionRuntimePromise = promise;
|
|
7075
6556
|
try {
|
|
7076
6557
|
return await promise;
|
|
@@ -7431,102 +6912,6 @@ async function cleanupDiscordProviderStartup(params) {
|
|
|
7431
6912
|
if (!params.lifecycleStarted) params.threadBindings.stop();
|
|
7432
6913
|
}
|
|
7433
6914
|
//#endregion
|
|
7434
|
-
//#region extensions/discord/src/voice/access.ts
|
|
7435
|
-
async function authorizeDiscordVoiceIngress(params) {
|
|
7436
|
-
const groupPolicy = params.groupPolicy ?? resolveOpenProviderRuntimeGroupPolicy({
|
|
7437
|
-
providerConfigPresent: params.cfg.channels?.discord !== void 0,
|
|
7438
|
-
groupPolicy: params.discordConfig.groupPolicy,
|
|
7439
|
-
defaultGroupPolicy: params.cfg.channels?.defaults?.groupPolicy
|
|
7440
|
-
}).groupPolicy;
|
|
7441
|
-
const guildInfo = resolveDiscordGuildEntry({
|
|
7442
|
-
guild: params.guild ?? {
|
|
7443
|
-
id: params.guildId,
|
|
7444
|
-
...params.guildName ? { name: params.guildName } : {}
|
|
7445
|
-
},
|
|
7446
|
-
guildId: params.guildId,
|
|
7447
|
-
guildEntries: params.discordConfig.guilds
|
|
7448
|
-
});
|
|
7449
|
-
const channelConfig = params.channelId ? resolveDiscordChannelConfigWithFallback({
|
|
7450
|
-
guildInfo,
|
|
7451
|
-
channelId: params.channelId,
|
|
7452
|
-
channelName: params.channelName,
|
|
7453
|
-
channelSlug: params.channelSlug,
|
|
7454
|
-
parentId: params.parentId,
|
|
7455
|
-
parentName: params.parentName,
|
|
7456
|
-
parentSlug: params.parentSlug,
|
|
7457
|
-
scope: params.scope
|
|
7458
|
-
}) : null;
|
|
7459
|
-
if (channelConfig?.enabled === false) return {
|
|
7460
|
-
ok: false,
|
|
7461
|
-
message: "This channel is disabled."
|
|
7462
|
-
};
|
|
7463
|
-
const channelAllowlistConfigured = Boolean(guildInfo?.channels) && Object.keys(guildInfo?.channels ?? {}).length > 0;
|
|
7464
|
-
if (!params.channelId && groupPolicy === "allowlist" && channelAllowlistConfigured) return {
|
|
7465
|
-
ok: false,
|
|
7466
|
-
message: `${params.channelLabel ?? "This channel"} is not allowlisted for voice commands.`
|
|
7467
|
-
};
|
|
7468
|
-
const channelAllowed = channelConfig ? channelConfig.allowed : !channelAllowlistConfigured;
|
|
7469
|
-
if (!isDiscordGroupAllowedByPolicy({
|
|
7470
|
-
groupPolicy,
|
|
7471
|
-
guildAllowlisted: Boolean(guildInfo),
|
|
7472
|
-
channelAllowlistConfigured,
|
|
7473
|
-
channelAllowed
|
|
7474
|
-
}) || channelConfig?.allowed === false) return {
|
|
7475
|
-
ok: false,
|
|
7476
|
-
message: `${params.channelLabel ?? "This channel"} is not allowlisted for voice commands.`
|
|
7477
|
-
};
|
|
7478
|
-
const { hasAccessRestrictions, memberAllowed } = resolveDiscordMemberAccessState({
|
|
7479
|
-
channelConfig,
|
|
7480
|
-
guildInfo,
|
|
7481
|
-
memberRoleIds: params.memberRoleIds,
|
|
7482
|
-
sender: params.sender,
|
|
7483
|
-
allowNameMatching: false
|
|
7484
|
-
});
|
|
7485
|
-
const admissionAllowList = normalizeDiscordAllowList(params.admissionAllowFrom ?? params.discordConfig.allowFrom ?? params.discordConfig.allowFrom, [
|
|
7486
|
-
"discord:",
|
|
7487
|
-
"user:",
|
|
7488
|
-
"pk:"
|
|
7489
|
-
]);
|
|
7490
|
-
const admissionAllowed = admissionAllowList ? allowListMatches(admissionAllowList, params.sender, { allowNameMatching: false }) : false;
|
|
7491
|
-
const useAccessGroups = params.useAccessGroups ?? true;
|
|
7492
|
-
return resolveCommandAuthorizedFromAuthorizers({
|
|
7493
|
-
useAccessGroups,
|
|
7494
|
-
authorizers: useAccessGroups ? [{
|
|
7495
|
-
configured: admissionAllowList != null,
|
|
7496
|
-
allowed: admissionAllowed
|
|
7497
|
-
}, {
|
|
7498
|
-
configured: hasAccessRestrictions,
|
|
7499
|
-
allowed: memberAllowed
|
|
7500
|
-
}] : [{
|
|
7501
|
-
configured: hasAccessRestrictions,
|
|
7502
|
-
allowed: memberAllowed
|
|
7503
|
-
}],
|
|
7504
|
-
modeWhenAccessGroupsOff: "configured"
|
|
7505
|
-
}) ? {
|
|
7506
|
-
ok: true,
|
|
7507
|
-
channelConfig
|
|
7508
|
-
} : {
|
|
7509
|
-
ok: false,
|
|
7510
|
-
message: "You are not authorized to use this command."
|
|
7511
|
-
};
|
|
7512
|
-
}
|
|
7513
|
-
//#endregion
|
|
7514
|
-
//#region extensions/discord/src/voice/owner-access.ts
|
|
7515
|
-
function resolveDiscordVoiceAccess(params) {
|
|
7516
|
-
const commandOwnerAllowFrom = resolveDiscordCommandOwnerAllowFrom(params.cfg);
|
|
7517
|
-
if (commandOwnerAllowFrom) return {
|
|
7518
|
-
admissionAllowFrom: commandOwnerAllowFrom,
|
|
7519
|
-
ownerAllowFrom: commandOwnerAllowFrom
|
|
7520
|
-
};
|
|
7521
|
-
return {
|
|
7522
|
-
admissionAllowFrom: resolveDiscordAccountAllowFrom({
|
|
7523
|
-
cfg: params.cfg,
|
|
7524
|
-
accountId: params.accountId
|
|
7525
|
-
}) ?? params.discordConfig.allowFrom ?? [],
|
|
7526
|
-
ownerAllowFrom: []
|
|
7527
|
-
};
|
|
7528
|
-
}
|
|
7529
|
-
//#endregion
|
|
7530
6915
|
//#region extensions/discord/src/voice/command.ts
|
|
7531
6916
|
const VOICE_CHANNEL_TYPES = [ChannelType.GuildVoice, ChannelType.GuildStageVoice];
|
|
7532
6917
|
const DISCORD_VOICE_COMMAND_SPEC = {
|
|
@@ -7890,8 +7275,8 @@ function formatDiscordDeployRestOperation(err) {
|
|
|
7890
7275
|
function formatDiscordDeployErrorMessage(err) {
|
|
7891
7276
|
if (!isAbortLikeError(err)) return formatErrorMessage$1(err);
|
|
7892
7277
|
const deployErr = err && typeof err === "object" ? err : {};
|
|
7893
|
-
const requestMs = parseFiniteNumber(deployErr.deployRequestMs);
|
|
7894
|
-
const timeoutMs = parseFiniteNumber(deployErr.deployTimeoutMs);
|
|
7278
|
+
const requestMs = parseFiniteNumber$1(deployErr.deployRequestMs);
|
|
7279
|
+
const timeoutMs = parseFiniteNumber$1(deployErr.deployTimeoutMs);
|
|
7895
7280
|
const operation = formatDiscordDeployRestOperation(deployErr);
|
|
7896
7281
|
if (!(requestMs !== void 0 || timeoutMs !== void 0 || deployErr.deployRestMethod !== void 0 || deployErr.deployRestPath !== void 0)) return "Discord REST request was aborted";
|
|
7897
7282
|
const timing = [];
|
|
@@ -7904,8 +7289,8 @@ function formatDiscordDeployErrorMessage(err) {
|
|
|
7904
7289
|
function resolveDiscordDeployRateLimitDetails(err) {
|
|
7905
7290
|
if (!err || typeof err !== "object") return;
|
|
7906
7291
|
const deployErr = err;
|
|
7907
|
-
const status = parseStrictNonNegativeInteger(deployErr.status) ?? parseStrictNonNegativeInteger(deployErr.statusCode);
|
|
7908
|
-
const retryAfterSeconds = parseFiniteNumber(deployErr.retryAfter) ?? parseFiniteNumber(readDiscordDeployObjectField(deployErr.rawBody, "retry_after"));
|
|
7292
|
+
const status = parseStrictNonNegativeInteger$1(deployErr.status) ?? parseStrictNonNegativeInteger$1(deployErr.statusCode);
|
|
7293
|
+
const retryAfterSeconds = parseFiniteNumber$1(deployErr.retryAfter) ?? parseFiniteNumber$1(readDiscordDeployObjectField(deployErr.rawBody, "retry_after"));
|
|
7909
7294
|
if (!(err instanceof RateLimitError || status === 429 || retryAfterSeconds !== void 0)) return;
|
|
7910
7295
|
const rawGlobal = readDiscordDeployObjectField(deployErr.rawBody, "global");
|
|
7911
7296
|
const scope = typeof deployErr.scope === "string" && deployErr.scope.trim().length > 0 ? deployErr.scope : rawGlobal === true ? "global" : rawGlobal === false ? "route" : void 0;
|
|
@@ -7995,8 +7380,8 @@ function formatDiscordDeployErrorDetails(err) {
|
|
|
7995
7380
|
function isDiscordDeployDailyCreateLimit(err) {
|
|
7996
7381
|
if (!err || typeof err !== "object") return false;
|
|
7997
7382
|
const deployErr = err;
|
|
7998
|
-
const discordCode = parseStrictNonNegativeInteger(deployErr.discordCode);
|
|
7999
|
-
const rawCode = parseStrictNonNegativeInteger(readDiscordDeployObjectField(deployErr.rawBody, "code"));
|
|
7383
|
+
const discordCode = parseStrictNonNegativeInteger$1(deployErr.discordCode);
|
|
7384
|
+
const rawCode = parseStrictNonNegativeInteger$1(readDiscordDeployObjectField(deployErr.rawBody, "code"));
|
|
8000
7385
|
return (discordCode === 30034 || rawCode === 30034) && /daily application command creates/i.test(formatErrorMessage$1(err));
|
|
8001
7386
|
}
|
|
8002
7387
|
//#endregion
|
|
@@ -8214,9 +7599,6 @@ function formatUsername(user) {
|
|
|
8214
7599
|
if (user.discriminator && user.discriminator !== "0") return `${user.username}#${user.discriminator}`;
|
|
8215
7600
|
return user.username;
|
|
8216
7601
|
}
|
|
8217
|
-
function isThreadChannelType(channelType) {
|
|
8218
|
-
return channelType === ChannelType.PublicThread || channelType === ChannelType.PrivateThread || channelType === ChannelType.AnnouncementThread;
|
|
8219
|
-
}
|
|
8220
7602
|
function resolveAgentComponentRoute(params) {
|
|
8221
7603
|
return resolveAgentRoute({
|
|
8222
7604
|
cfg: params.ctx.cfg,
|
|
@@ -8259,7 +7641,7 @@ function resolveDiscordChannelContext(interaction) {
|
|
|
8259
7641
|
const channelSlug = channelName ? normalizeDiscordSlug(channelName) : "";
|
|
8260
7642
|
const displayChannelSlug = channelName ? normalizeDiscordDisplaySlug(channelName) : "";
|
|
8261
7643
|
const channelType = channelInfo.type;
|
|
8262
|
-
const isThread =
|
|
7644
|
+
const isThread = isDiscordThreadChannelType(channelType);
|
|
8263
7645
|
let parentId;
|
|
8264
7646
|
let parentName;
|
|
8265
7647
|
let parentSlug = "";
|
|
@@ -8757,7 +8139,8 @@ function resolveReplyContext(message, resolveDiscordMessageText) {
|
|
|
8757
8139
|
const referenced = message.referencedMessage;
|
|
8758
8140
|
if (!referenced?.author) return null;
|
|
8759
8141
|
const referencedText = resolveDiscordMessageText(referenced, { includeForwarded: true });
|
|
8760
|
-
|
|
8142
|
+
const hasVisibleMedia = referenced.attachments.length > 0 || !referencedText && resolveDiscordMessageStickers(referenced).length > 0;
|
|
8143
|
+
if (!referencedText && !hasVisibleMedia) return null;
|
|
8761
8144
|
const sender = resolveDiscordSenderIdentity({
|
|
8762
8145
|
author: referenced.author,
|
|
8763
8146
|
pluralkitInfo: null
|
|
@@ -8773,7 +8156,7 @@ function resolveReplyContext(message, resolveDiscordMessageText) {
|
|
|
8773
8156
|
const roles = referenced.member?.roles;
|
|
8774
8157
|
return Array.isArray(roles) ? roles.map((roleId) => roleId) : void 0;
|
|
8775
8158
|
})(),
|
|
8776
|
-
body: referencedText,
|
|
8159
|
+
...referencedText ? { body: referencedText } : {},
|
|
8777
8160
|
timestamp: resolveTimestampMs(referenced.timestamp)
|
|
8778
8161
|
};
|
|
8779
8162
|
}
|
|
@@ -8933,6 +8316,7 @@ async function deliverDiscordReply(params) {
|
|
|
8933
8316
|
formatting: delivery.formatting,
|
|
8934
8317
|
threadId: delivery.threadId,
|
|
8935
8318
|
identity: delivery.identity,
|
|
8319
|
+
onPlatformSendDispatch: params.onPlatformSendDispatch,
|
|
8936
8320
|
deps: createDiscordDeliveryDeps({
|
|
8937
8321
|
cfg: params.cfg,
|
|
8938
8322
|
token: params.token,
|
|
@@ -8971,7 +8355,7 @@ async function deliverDiscordReply(params) {
|
|
|
8971
8355
|
//#endregion
|
|
8972
8356
|
//#region extensions/discord/src/monitor/agent-components.dispatch.ts
|
|
8973
8357
|
const loadConversationRuntime$1 = createLazyRuntimeModule(() => import("./agent-components.runtime-CEPrf2SY.js"));
|
|
8974
|
-
const loadTypingRuntime = createLazyRuntimeModule(() => import("./typing-
|
|
8358
|
+
const loadTypingRuntime = createLazyRuntimeModule(() => import("./typing-Dc_YMY2e.js").then((n) => n.n));
|
|
8975
8359
|
function buildDiscordComponentConversationLabel(params) {
|
|
8976
8360
|
if (params.interactionCtx.isDirectMessage) return buildDirectLabel(params.interactionCtx.user);
|
|
8977
8361
|
if (params.interactionCtx.isGroupDm) return `Group DM #${params.channelCtx.channelName ?? params.interactionCtx.channelId} channel id:${params.interactionCtx.channelId}`;
|
|
@@ -9093,6 +8477,14 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
9093
8477
|
SessionKey: sessionKey,
|
|
9094
8478
|
AccountId: accountId,
|
|
9095
8479
|
ChatType: chatType,
|
|
8480
|
+
...buildDiscordConversationRouteContext({
|
|
8481
|
+
isDirectMessage: interactionCtx.isDirectMessage,
|
|
8482
|
+
isGroupDm: interactionCtx.isGroupDm,
|
|
8483
|
+
directUserId: interactionCtx.userId,
|
|
8484
|
+
conversationId: interactionCtx.channelId,
|
|
8485
|
+
isThread: channelCtx.isThread,
|
|
8486
|
+
parentConversationId: channelCtx.parentId
|
|
8487
|
+
}),
|
|
9096
8488
|
ConversationLabel: fromLabel,
|
|
9097
8489
|
SenderName: senderName,
|
|
9098
8490
|
SenderId: interactionCtx.userId,
|
|
@@ -9161,6 +8553,7 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
9161
8553
|
sessionKey
|
|
9162
8554
|
},
|
|
9163
8555
|
ctxPayload,
|
|
8556
|
+
dispatchReplyFromConfig: ctx.channelRuntime?.reply?.dispatchReplyFromConfig,
|
|
9164
8557
|
record: {
|
|
9165
8558
|
updateLastRoute: interactionCtx.isDirectMessage ? {
|
|
9166
8559
|
sessionKey: inboundLastRouteSessionKey,
|
|
@@ -9202,7 +8595,8 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
9202
8595
|
chunkMode: resolveChunkMode(ctx.cfg, "discord", accountId),
|
|
9203
8596
|
mediaLocalRoots,
|
|
9204
8597
|
kind: info.kind,
|
|
9205
|
-
bindPendingFinalDelivery: info.bindPendingFinalDelivery
|
|
8598
|
+
bindPendingFinalDelivery: info.bindPendingFinalDelivery,
|
|
8599
|
+
onPlatformSendDispatch: info.onPlatformSendDispatch
|
|
9206
8600
|
});
|
|
9207
8601
|
if (result.visibleReplySent) replyReference.markSent();
|
|
9208
8602
|
return result;
|
|
@@ -9367,7 +8761,7 @@ async function dispatchPluginDiscordInteractiveEvent(params) {
|
|
|
9367
8761
|
}
|
|
9368
8762
|
//#endregion
|
|
9369
8763
|
//#region extensions/discord/src/monitor/agent-components.handlers.ts
|
|
9370
|
-
const loadComponentsRuntime = createLazyRuntimeModule(() => import("./
|
|
8764
|
+
const loadComponentsRuntime = createLazyRuntimeModule(() => import("./components-B9V5o361.js").then((n) => n.t));
|
|
9371
8765
|
async function handleDiscordComponentEvent(params) {
|
|
9372
8766
|
const parsed = parseDiscordComponentData(params.data, resolveInteractionCustomId(params.interaction));
|
|
9373
8767
|
if (!parsed) {
|
|
@@ -10013,29 +9407,24 @@ var QuestionButton = class extends Button {
|
|
|
10013
9407
|
try {
|
|
10014
9408
|
await interaction.acknowledge();
|
|
10015
9409
|
} catch {}
|
|
10016
|
-
let
|
|
9410
|
+
let content;
|
|
10017
9411
|
try {
|
|
10018
|
-
|
|
9412
|
+
content = (await this.ctx.resolveQuestion({
|
|
10019
9413
|
cfg: this.ctx.cfg,
|
|
10020
9414
|
questionId: callback.questionId,
|
|
10021
9415
|
optionIndex: callback.optionIndex,
|
|
10022
9416
|
senderId: interaction.userId,
|
|
10023
9417
|
clientDisplayName: `Discord question (${this.ctx.accountId})`
|
|
10024
|
-
});
|
|
9418
|
+
})).status === "answered" ? "Answer submitted." : "This question was already answered.";
|
|
10025
9419
|
} catch {
|
|
10026
|
-
|
|
10027
|
-
await interaction.followUp({
|
|
10028
|
-
content: "Could not submit this answer.",
|
|
10029
|
-
ephemeral: true
|
|
10030
|
-
});
|
|
10031
|
-
} catch {}
|
|
10032
|
-
return;
|
|
9420
|
+
content = "Could not submit this answer.";
|
|
10033
9421
|
}
|
|
10034
9422
|
try {
|
|
10035
|
-
|
|
10036
|
-
content
|
|
9423
|
+
const feedback = {
|
|
9424
|
+
content,
|
|
10037
9425
|
ephemeral: true
|
|
10038
|
-
}
|
|
9426
|
+
};
|
|
9427
|
+
await (interaction.responseState === "unacknowledged" ? interaction.reply(feedback) : interaction.followUp(feedback));
|
|
10039
9428
|
} catch {}
|
|
10040
9429
|
}
|
|
10041
9430
|
};
|
|
@@ -10079,7 +9468,8 @@ function createDiscordProviderInteractionSurface(params) {
|
|
|
10079
9468
|
accountId: params.accountId,
|
|
10080
9469
|
sessionPrefix: params.sessionPrefix,
|
|
10081
9470
|
ephemeralDefault: params.ephemeralDefault,
|
|
10082
|
-
threadBindings: params.threadBindings
|
|
9471
|
+
threadBindings: params.threadBindings,
|
|
9472
|
+
dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
|
|
10083
9473
|
});
|
|
10084
9474
|
});
|
|
10085
9475
|
const execApprovalsConfig = params.discordConfig.execApprovals ?? {};
|
|
@@ -10124,21 +9514,24 @@ function createDiscordProviderInteractionSurface(params) {
|
|
|
10124
9514
|
discordConfig: params.discordConfig,
|
|
10125
9515
|
accountId: params.accountId,
|
|
10126
9516
|
sessionPrefix: params.sessionPrefix,
|
|
10127
|
-
threadBindings: params.threadBindings
|
|
9517
|
+
threadBindings: params.threadBindings,
|
|
9518
|
+
dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
|
|
10128
9519
|
}),
|
|
10129
9520
|
createDiscordModelPickerFallbackButton({
|
|
10130
9521
|
cfg: params.cfg,
|
|
10131
9522
|
discordConfig: params.discordConfig,
|
|
10132
9523
|
accountId: params.accountId,
|
|
10133
9524
|
sessionPrefix: params.sessionPrefix,
|
|
10134
|
-
threadBindings: params.threadBindings
|
|
9525
|
+
threadBindings: params.threadBindings,
|
|
9526
|
+
dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
|
|
10135
9527
|
}),
|
|
10136
9528
|
createDiscordModelPickerFallbackSelect({
|
|
10137
9529
|
cfg: params.cfg,
|
|
10138
9530
|
discordConfig: params.discordConfig,
|
|
10139
9531
|
accountId: params.accountId,
|
|
10140
9532
|
sessionPrefix: params.sessionPrefix,
|
|
10141
|
-
threadBindings: params.threadBindings
|
|
9533
|
+
threadBindings: params.threadBindings,
|
|
9534
|
+
dispatchReplyFromConfig: params.channelRuntime?.reply?.dispatchReplyFromConfig
|
|
10142
9535
|
})
|
|
10143
9536
|
];
|
|
10144
9537
|
const activityButton = createDiscordActivityButton({
|
|
@@ -10149,6 +9542,7 @@ function createDiscordProviderInteractionSurface(params) {
|
|
|
10149
9542
|
allowFrom: params.allowFrom,
|
|
10150
9543
|
dmPolicy: params.dmPolicy,
|
|
10151
9544
|
runtime: params.runtime,
|
|
9545
|
+
channelRuntime: params.channelRuntime,
|
|
10152
9546
|
token: params.token
|
|
10153
9547
|
}, params.applicationId);
|
|
10154
9548
|
if (activityButton) components.push(activityButton);
|
|
@@ -10641,6 +10035,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10641
10035
|
let earlyGatewayEmitter = gatewaySupervisor?.emitter;
|
|
10642
10036
|
let onEarlyGatewayDebug;
|
|
10643
10037
|
try {
|
|
10038
|
+
const pluginChannelRuntime = opts.channelRuntime;
|
|
10644
10039
|
const { commands, components, modals } = createDiscordProviderInteractionSurface({
|
|
10645
10040
|
cfg,
|
|
10646
10041
|
discordConfig: discordCfg,
|
|
@@ -10660,7 +10055,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10660
10055
|
allowFrom,
|
|
10661
10056
|
dmPolicy,
|
|
10662
10057
|
runtime,
|
|
10663
|
-
channelRuntime:
|
|
10058
|
+
channelRuntime: pluginChannelRuntime,
|
|
10664
10059
|
abortSignal: opts.abortSignal,
|
|
10665
10060
|
createNativeCommand: discordProviderRuntime.createDiscordNativeCommand
|
|
10666
10061
|
});
|
|
@@ -10734,7 +10129,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10734
10129
|
runtime,
|
|
10735
10130
|
botUserId
|
|
10736
10131
|
});
|
|
10737
|
-
const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-
|
|
10132
|
+
const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-BR11iHA4.js").then((n) => n.n);
|
|
10738
10133
|
setDiscordTranscriptsVoiceManager({
|
|
10739
10134
|
accountId: account.accountId,
|
|
10740
10135
|
manager: voiceManager
|
|
@@ -10752,7 +10147,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10752
10147
|
accountId: account.accountId,
|
|
10753
10148
|
token,
|
|
10754
10149
|
runtime,
|
|
10755
|
-
buildContext:
|
|
10150
|
+
buildContext: pluginChannelRuntime?.inbound.buildContext,
|
|
10756
10151
|
setStatus: opts.setStatus,
|
|
10757
10152
|
abortSignal: opts.abortSignal,
|
|
10758
10153
|
botUserId,
|
|
@@ -10840,4 +10235,4 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10840
10235
|
}
|
|
10841
10236
|
}
|
|
10842
10237
|
//#endregion
|
|
10843
|
-
export {
|
|
10238
|
+
export { mapGatewayDispatchData as _, sanitizeDiscordFrontChannelReplyPayloads as a, resolveDiscordDmCommandAccess as b, resolveReplyContext as c, waitForDiscordGatewayPluginRegistration as d, createDiscordNativeCommand as f, handleDiscordDmCommandDecision as g, createDiscordSupplementalContextAccessChecker as h, formatDiscordReplySkip as i, createDiscordGatewayPlugin as l, buildDiscordInboundAccessContext as m, deliverDiscordReply as n, buildDirectLabel as o, buildDiscordGroupSystemPrompt as p, formatDiscordReplyDeliveryFailure as r, buildGuildLabel as s, monitorDiscordProvider as t, resolveDiscordGatewayIntents as u, registerDiscordListener as v, resolveDiscordTextCommandAccess as x, resolveFetchedDiscordThreadLikeChannelContext as y };
|