@openclaw/discord 2026.8.1-beta.2 → 2026.8.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-Dl-TOyOX.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-q4Zqo44V.js} +29 -106
- package/dist/{audit-Db-rlntl.js → audit-DgrvFPGt.js} +5 -5
- package/dist/{channel-CnnbJSt5.js → channel-BsQUalPw.js} +72 -50
- package/dist/{channel-actions.runtime-CLKrx6tr.js → channel-actions.runtime-UMGGIfSy.js} +31 -45
- 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-rPs4dsk_.js} +5 -5
- package/dist/{outbound-session-route-DxLkrgKQ.js → components-Dk35LTf_.js} +34 -76
- package/dist/{config-schema-BgEskFAs.js → config-schema-CxPqtVI1.js} +46 -14
- package/dist/conversation-binding-route-BjvX4e35.js +43 -0
- package/dist/{directory-config-BVX7Cflc.js → directory-config-B7DY_pNG.js} +2 -2
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-DGIGxpIo.js → directory-live-DuAXKkan.js} +3 -3
- package/dist/doctor-contract-api.js +2 -2
- package/dist/{doctor-BzC-TLnB.js → doctor-zQTtn6hm.js} +33 -12
- package/dist/{handle-action.guild-admin-BNVTUISF.js → handle-action.guild-admin-DZewwLr1.js} +9 -5
- package/dist/index.js +3 -4
- package/dist/ingress-identity-CzZKcPK8.js +60 -0
- package/dist/{message-handler-Unk_f10F.js → message-handler-C5By3yl5.js} +82 -6
- package/dist/{message-handler.preflight-C9zecxR9.js → message-handler.preflight-DrszWuHw.js} +44 -118
- package/dist/{message-handler.process-DWQ6UHHu.js → message-handler.process-DyFPDLCt.js} +205 -235
- package/dist/{message-utils-BSCPVgy0.js → message-text-Ca8M6TU8.js} +43 -42
- package/dist/{outbound-adapter-D9nRivT1.js → outbound-adapter-Dif8p481.js} +118 -91
- package/dist/{outbound-components-cTzwBJ60.js → outbound-components-wjv7yyAj.js} +5 -4
- package/dist/outbound-session-route-Bn4uXaoE.js +665 -0
- package/dist/owner-access-UlYi9t0M.js +107 -0
- package/dist/{pluralkit-DdiJ9KMK.js → pluralkit-9EuEN4UD.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-LXiOcJrH.js} +887 -1350
- package/dist/{provider-session.runtime-BUEqD0rA.js → provider-session.runtime-DSNe7r2W.js} +3 -3
- package/dist/provider.runtime-DiInaDXO.js +2 -0
- package/dist/{realtime-session.runtime-C7wen-aF.js → realtime-session.runtime-DOViOIjY.js} +129 -134
- package/dist/{resolve-allowlist-common-D04lpEzb.js → resolve-allowlist-common-BLoYaxEG.js} +2 -2
- package/dist/{resolve-channels-Dm7jEeg6.js → resolve-channels-D2yl_2CN.js} +5 -4
- package/dist/{resolve-users-bktrCUUU.js → resolve-users-BLxfqajZ.js} +2 -2
- package/dist/{retry-CLpJcXXf.js → retry-DqHCW6PV.js} +187 -19
- package/dist/{runtime-DGsSyDTS.js → runtime-BYamRVPN.js} +89 -86
- package/dist/{runtime-DoHjckYm.js → runtime-DrxVBTtp.js} +9 -10
- package/dist/runtime-api.js +19 -25
- package/dist/{sdk-runtime-QpY8PvCh.js → sdk-runtime-6tfgYDjY.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-jGnJF__m.js → security-audit-DKfK-iPY.js} +11 -12
- package/dist/security-audit-contract-api.js +1 -1
- package/dist/{security-audit.runtime-CPN0xFYz.js → security-audit.runtime-sKZyKgpx.js} +1 -1
- package/dist/{send-B7Q6Oc1I.js → send-UJHiAm4C.js} +82 -19
- package/dist/{send.components-iJyFXw9L.js → send.components-CrBJpGT_.js} +22 -39
- package/dist/{send.outbound-DS5tHwfR.js → send.outbound-D7JYmfm9.js} +77 -78
- package/dist/{send.shared-BmwFjW6T.js → send.shared-DZJ1akvQ.js} +136 -121
- 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-Dii2HTn7.js} +41 -14
- package/dist/subagent-hooks-JyGrtQIl.js +49 -0
- package/dist/subagent-hooks-api.js +1 -6
- package/dist/{system-events-CTqDf6_s.js → system-events-BEmcj4xJ.js} +2 -2
- package/dist/{target-resolver-maOKSqO0.js → target-resolver-V-IYae6s.js} +3 -3
- package/dist/targets-CQp53cGj.js +3 -0
- package/dist/{thread-bindings-3L8p82GV.js → thread-bindings-DvYP79fy.js} +28 -26
- package/dist/{thread-bindings.manager-DCIH6WDC.js → thread-bindings.manager-Clm77DBM.js} +11 -14
- 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-CXuu_7o9.js +478 -0
- package/dist/transcripts-source-BLEMH_yi.js +270 -0
- package/dist/transcripts-source-api.js +7 -2
- package/dist/{typing-CS-nNVoe.js → typing-B9snnwMe.js} +1 -1
- package/dist/{voice-runtime-BEdqNcST.js → voice-runtime-DY6_o73o.js} +250 -150
- 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 +24 -10
- package/package.json +8 -10
- package/skills/discord/SKILL.md +1 -1
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as createThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-
|
|
2
|
-
import { a as reconcileAcpThreadBindingsOnStartup } from "./thread-bindings-
|
|
3
|
-
import { t as createDiscordMessageHandler } from "./message-handler-
|
|
1
|
+
import { n as createThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-Clm77DBM.js";
|
|
2
|
+
import { a as reconcileAcpThreadBindingsOnStartup } from "./thread-bindings-DvYP79fy.js";
|
|
3
|
+
import { t as createDiscordMessageHandler } from "./message-handler-C5By3yl5.js";
|
|
4
4
|
import { resolveThreadBindingIdleTimeoutMs, resolveThreadBindingMaxAgeMs, resolveThreadBindingsEnabled } from "openclaw/plugin-sdk/conversation-runtime";
|
|
5
5
|
import { getAcpSessionManager, isAcpRuntimeError } from "openclaw/plugin-sdk/acp-runtime";
|
|
6
6
|
export { createDiscordMessageHandler, createNoopThreadBindingManager, createThreadBindingManager, getAcpSessionManager, isAcpRuntimeError, reconcileAcpThreadBindingsOnStartup, resolveThreadBindingIdleTimeoutMs, resolveThreadBindingMaxAgeMs, resolveThreadBindingsEnabled };
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as discordRealtimeVoiceSecretOwnerId } from "./secret-config-contract-B3i6WxV5.js";
|
|
2
|
+
import { b as maybeControlDiscordVoiceAgentRun, f as convertDiscordPcm48kStereoToRealtimePcm24kMono, l as logVoiceVerbose, m as createDiscordOpusEncodeStream, p as convertRealtimePcm24kMonoToDiscordPcm48kStereo, t as loadDiscordVoiceSdk, x as formatVoiceLogPreview, y as formatVoiceIngressPrompt } from "./sdk-runtime-6tfgYDjY.js";
|
|
2
3
|
import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
3
4
|
import { formatErrorMessage } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
4
5
|
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
|
5
6
|
import { sliceUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
6
|
-
import {
|
|
7
|
+
import { assertSecretOwnerAvailable, isSecretOwnerAvailable } from "openclaw/plugin-sdk/channel-secret-owner-runtime";
|
|
8
|
+
import { REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME, REALTIME_VOICE_AGENT_CONTROL_TOOL, REALTIME_VOICE_AGENT_CONTROL_TOOL_NAME, REALTIME_VOICE_AUDIO_FORMAT_PCM16_24KHZ, buildRealtimeVoiceSessionInstructions, buildRealtimeVoiceSpeakExactMessage, canonicalizeRealtimeVoiceProviderId, classifyRealtimeVoiceConsultToolCall, classifySkippableRealtimeVoiceConsultTranscript, controlRealtimeVoiceAgentRun, createRealtimeVoiceAgentTalkbackQueue, createRealtimeVoiceSessionHarness, createRealtimeVoiceTurnContextTracker, isRealtimeVoiceWakeNameRequired, matchRealtimeVoiceActivationName, matchRealtimeVoiceConsultQuestions, parseRealtimeVoiceAgentControlToolArgs, realtimeVoiceAudioDurationMs, resolveConfiguredRealtimeVoiceProvider, resolveRealtimeVoiceAgentConsultTools, resolveRealtimeVoiceBargeIn, resolveRealtimeVoiceInterruptResponseOnInputAudio, resolveRealtimeVoiceMinBargeInAudioEndMs, resolveRealtimeVoiceSessionPolicy } from "openclaw/plugin-sdk/realtime-voice";
|
|
7
9
|
import { PassThrough, pipeline } from "node:stream";
|
|
8
10
|
//#region extensions/discord/src/voice/realtime-transcript.ts
|
|
9
11
|
function mergeRealtimePartialTranscript(previous, next) {
|
|
@@ -17,7 +19,7 @@ const logger$3 = createSubsystemLogger("discord/voice");
|
|
|
17
19
|
const DISCORD_REALTIME_PENDING_SPEAKER_CONTEXT_LIMIT = 32;
|
|
18
20
|
const DISCORD_REALTIME_IGNORED_WAKE_NAME_CONTEXT_TTL_MS = 1e4;
|
|
19
21
|
const DISCORD_REALTIME_WAKE_NAME_FOLLOWUP_TTL_MS = 1e4;
|
|
20
|
-
const REALTIME_PCM16_BYTES_PER_SAMPLE
|
|
22
|
+
const REALTIME_PCM16_BYTES_PER_SAMPLE = 2;
|
|
21
23
|
const DISCORD_REALTIME_TRAILING_SILENCE_MIN_MS = 700;
|
|
22
24
|
const DISCORD_REALTIME_TRAILING_SILENCE_MAX_MS = 3e3;
|
|
23
25
|
var DiscordRealtimeTurns = class {
|
|
@@ -37,6 +39,7 @@ var DiscordRealtimeTurns = class {
|
|
|
37
39
|
...context,
|
|
38
40
|
userId
|
|
39
41
|
}, {
|
|
42
|
+
transcripts: this.params.entry.transcripts,
|
|
40
43
|
inputDiscordBytes: 0,
|
|
41
44
|
inputRealtimeBytes: 0,
|
|
42
45
|
inputChunks: 0,
|
|
@@ -153,7 +156,7 @@ var DiscordRealtimeTurns = class {
|
|
|
153
156
|
const providerId = this.params.providerId() ?? this.params.realtimeConfig()?.provider ?? "openai";
|
|
154
157
|
const rawSilenceDurationMs = (this.params.realtimeConfig()?.providers?.[providerId])?.silenceDurationMs;
|
|
155
158
|
const silenceMs = Math.min(DISCORD_REALTIME_TRAILING_SILENCE_MAX_MS, Math.max(DISCORD_REALTIME_TRAILING_SILENCE_MIN_MS, typeof rawSilenceDurationMs === "number" && Number.isFinite(rawSilenceDurationMs) ? rawSilenceDurationMs : 0));
|
|
156
|
-
const silenceBytes = Math.ceil(24e3 * silenceMs / 1e3) * REALTIME_PCM16_BYTES_PER_SAMPLE
|
|
159
|
+
const silenceBytes = Math.ceil(24e3 * silenceMs / 1e3) * REALTIME_PCM16_BYTES_PER_SAMPLE;
|
|
157
160
|
const silence = Buffer.alloc(silenceBytes);
|
|
158
161
|
bridge.sendAudio(silence);
|
|
159
162
|
logger$3.info(`discord voice: realtime trailing silence sent guild=${this.params.entry.guildId} channel=${this.params.entry.channelId} user=${turn.context.userId} speaker=${turn.context.speakerLabel} silenceMs=${silenceMs} realtimeBytes=${silence.length}`);
|
|
@@ -183,12 +186,13 @@ var DiscordRealtimeTurns = class {
|
|
|
183
186
|
transcriptAttributionFromTurn(turn) {
|
|
184
187
|
return turn ? {
|
|
185
188
|
context: turn.context,
|
|
186
|
-
startedAt: turn.startedAt
|
|
189
|
+
startedAt: turn.startedAt,
|
|
190
|
+
transcripts: turn.transcripts
|
|
187
191
|
} : void 0;
|
|
188
192
|
}
|
|
189
193
|
recordTranscriptUtterance(text, attribution, providerEpoch) {
|
|
190
|
-
const transcripts =
|
|
191
|
-
if (!transcripts || !attribution) return;
|
|
194
|
+
const transcripts = attribution?.transcripts;
|
|
195
|
+
if (!transcripts || !attribution || this.params.entry.transcripts !== transcripts) return;
|
|
192
196
|
const context = attribution.context;
|
|
193
197
|
const utterance = {
|
|
194
198
|
sessionId: transcripts.sessionId,
|
|
@@ -207,7 +211,7 @@ var DiscordRealtimeTurns = class {
|
|
|
207
211
|
}
|
|
208
212
|
};
|
|
209
213
|
Promise.resolve().then(() => {
|
|
210
|
-
if (providerEpoch !== this.params.providerEpoch()) return;
|
|
214
|
+
if (providerEpoch !== this.params.providerEpoch() || this.params.entry.transcripts !== transcripts) return;
|
|
211
215
|
return transcripts.onUtterance(utterance);
|
|
212
216
|
}).catch((error) => {
|
|
213
217
|
logger$3.warn(`discord voice: realtime transcripts utterance failed: ${formatErrorMessage(error)}`);
|
|
@@ -224,6 +228,7 @@ var DiscordRealtimeTurns = class {
|
|
|
224
228
|
if (expiresAt === void 0) return;
|
|
225
229
|
this.pendingWakeNameFollowup = {
|
|
226
230
|
context,
|
|
231
|
+
transcripts: turn?.transcripts,
|
|
227
232
|
startedAt: turn?.startedAt ?? Date.now(),
|
|
228
233
|
expiresAt
|
|
229
234
|
};
|
|
@@ -240,7 +245,8 @@ var DiscordRealtimeTurns = class {
|
|
|
240
245
|
if (currentTurn) this.consumePendingSpeakerContext();
|
|
241
246
|
return {
|
|
242
247
|
context: pending.context,
|
|
243
|
-
startedAt: pending.startedAt
|
|
248
|
+
startedAt: pending.startedAt,
|
|
249
|
+
transcripts: pending.transcripts
|
|
244
250
|
};
|
|
245
251
|
}
|
|
246
252
|
rememberIgnoredWakeNameSpeakerContext(context) {
|
|
@@ -356,7 +362,9 @@ var DiscordRealtimeConsults = class {
|
|
|
356
362
|
await session.submitToolResult(callId, { text });
|
|
357
363
|
}
|
|
358
364
|
async handleAcceptedTranscript(acceptedText, forcedSpeakerContext, providerEpoch) {
|
|
359
|
-
const
|
|
365
|
+
const usesRealtimeAgentHandoff = this.params.usesRealtimeAgentHandoff();
|
|
366
|
+
const fallbackSpeakerContext = this.params.isAgentProxy && !usesRealtimeAgentHandoff ? forcedSpeakerContext ?? this.params.turns.consumePendingSpeakerContext() : void 0;
|
|
367
|
+
const pendingForcedConsult = this.params.isAgentProxy && usesRealtimeAgentHandoff ? this.prepareForcedAgentProxyConsult(acceptedText, forcedSpeakerContext) : void 0;
|
|
360
368
|
let control;
|
|
361
369
|
try {
|
|
362
370
|
control = await maybeControlDiscordVoiceAgentRun({
|
|
@@ -376,11 +384,11 @@ var DiscordRealtimeConsults = class {
|
|
|
376
384
|
return;
|
|
377
385
|
}
|
|
378
386
|
if (!this.params.isAgentProxy) return;
|
|
379
|
-
if (
|
|
387
|
+
if (usesRealtimeAgentHandoff) {
|
|
380
388
|
if (pendingForcedConsult) this.schedulePreparedForcedAgentProxyConsult(pendingForcedConsult);
|
|
381
389
|
return;
|
|
382
390
|
}
|
|
383
|
-
this.talkback.enqueue(acceptedText,
|
|
391
|
+
this.talkback.enqueue(acceptedText, fallbackSpeakerContext);
|
|
384
392
|
}
|
|
385
393
|
createTalkbackQueue() {
|
|
386
394
|
const providerEpoch = this.params.providerEpoch();
|
|
@@ -600,11 +608,11 @@ var DiscordRealtimeConsults = class {
|
|
|
600
608
|
if (providerOwnsDelivery) {
|
|
601
609
|
state.handledByForcedPlayback = false;
|
|
602
610
|
state.settleProviderDelivery = void 0;
|
|
603
|
-
resolveProviderDelivery?.(
|
|
611
|
+
resolveProviderDelivery?.();
|
|
604
612
|
}
|
|
605
613
|
} catch (error) {
|
|
606
614
|
state.settleProviderDelivery = void 0;
|
|
607
|
-
resolveProviderDelivery?.(
|
|
615
|
+
resolveProviderDelivery?.();
|
|
608
616
|
throw error;
|
|
609
617
|
}
|
|
610
618
|
return true;
|
|
@@ -614,7 +622,7 @@ var DiscordRealtimeConsults = class {
|
|
|
614
622
|
const state = handle.context;
|
|
615
623
|
if (!state) continue;
|
|
616
624
|
state.handledByForcedPlayback = false;
|
|
617
|
-
state.settleProviderDelivery?.(
|
|
625
|
+
state.settleProviderDelivery?.();
|
|
618
626
|
state.settleProviderDelivery = void 0;
|
|
619
627
|
state.providerDelivery = void 0;
|
|
620
628
|
}
|
|
@@ -625,35 +633,27 @@ var DiscordRealtimeConsults = class {
|
|
|
625
633
|
//#region extensions/discord/src/voice/realtime-playback.ts
|
|
626
634
|
const logger$1 = createSubsystemLogger("discord/voice");
|
|
627
635
|
const DISCORD_REALTIME_CONTROL_SPEECH_DEDUPE_MS = 5e3;
|
|
628
|
-
const DISCORD_REALTIME_OUTPUT_PLAYBACK_WATCHDOG_MARGIN_MS =
|
|
636
|
+
const DISCORD_REALTIME_OUTPUT_PLAYBACK_WATCHDOG_MARGIN_MS = 3e3;
|
|
629
637
|
const DISCORD_REALTIME_MAX_RETAINED_EXACT_SPEECH_MESSAGES = 32;
|
|
630
638
|
const DISCORD_REALTIME_MAX_RETAINED_EXACT_SPEECH_BYTES = 32 * 1024;
|
|
631
|
-
const DISCORD_REALTIME_CANCELLATION_RACE_DETAIL = "Cancellation failed: no active response found";
|
|
632
639
|
const DISCORD_REALTIME_WAKE_ACKS = [
|
|
633
640
|
"Yeah.",
|
|
634
641
|
"Mm-hmm.",
|
|
635
642
|
"Got it.",
|
|
636
643
|
"One sec."
|
|
637
644
|
];
|
|
638
|
-
const REALTIME_PCM16_BYTES_PER_SAMPLE = 2;
|
|
639
645
|
const DISCORD_RAW_PCM_FRAME_BYTES = 3840;
|
|
640
646
|
const DISCORD_REALTIME_OUTPUT_PREROLL_FRAMES = 25;
|
|
641
|
-
|
|
642
|
-
return event.direction === "server" && event.type === "error" && event.detail === DISCORD_REALTIME_CANCELLATION_RACE_DETAIL;
|
|
643
|
-
}
|
|
647
|
+
const DISCORD_REALTIME_MAX_PENDING_OUTPUT_BYTES = DISCORD_RAW_PCM_FRAME_BYTES * 6e3;
|
|
644
648
|
function normalizeControlSpeechText(text) {
|
|
645
649
|
return text.toLowerCase().replace(/\s+/g, " ").trim();
|
|
646
650
|
}
|
|
647
|
-
function pcm16MonoDurationMs(audio, sampleRate) {
|
|
648
|
-
if (audio.length === 0 || sampleRate <= 0) return 0;
|
|
649
|
-
return audio.length / REALTIME_PCM16_BYTES_PER_SAMPLE * 1e3 / sampleRate;
|
|
650
|
-
}
|
|
651
651
|
var DiscordRealtimePlayback = class {
|
|
652
652
|
constructor(params) {
|
|
653
653
|
this.params = params;
|
|
654
654
|
this.outputStream = null;
|
|
655
|
-
this.
|
|
656
|
-
this.
|
|
655
|
+
this.outputPacedBuffers = [];
|
|
656
|
+
this.outputPacedBytes = 0;
|
|
657
657
|
this.queuedExactSpeechMessages = [];
|
|
658
658
|
this.exactSpeechState = { status: "idle" };
|
|
659
659
|
this.wakeNameAckIndex = 0;
|
|
@@ -668,7 +668,6 @@ var DiscordRealtimePlayback = class {
|
|
|
668
668
|
this.params.entry.player.on(voiceSdk.AudioPlayerStatus.Idle, this.playerIdleHandler);
|
|
669
669
|
}
|
|
670
670
|
close() {
|
|
671
|
-
this.playbackState = { status: "idle" };
|
|
672
671
|
this.queuedExactSpeechMessages = [];
|
|
673
672
|
this.exactSpeechState = { status: "idle" };
|
|
674
673
|
this.clearOutputAudio("session-close");
|
|
@@ -703,7 +702,7 @@ var DiscordRealtimePlayback = class {
|
|
|
703
702
|
}
|
|
704
703
|
sendOutputAudio(realtimePcm24kMono) {
|
|
705
704
|
this.params.markProviderGenerationObserved();
|
|
706
|
-
if (this.params.stopped()
|
|
705
|
+
if (this.params.stopped()) return;
|
|
707
706
|
const discordPcm = convertRealtimePcm24kMonoToDiscordPcm48kStereo(realtimePcm24kMono);
|
|
708
707
|
if (discordPcm.length === 0) return;
|
|
709
708
|
this.params.bridge()?.setMediaTimestamp(this.outputAudioMs());
|
|
@@ -717,7 +716,7 @@ var DiscordRealtimePlayback = class {
|
|
|
717
716
|
audioStarted: true
|
|
718
717
|
};
|
|
719
718
|
this.params.harness.recordOutputAudio(realtimePcm24kMono, {
|
|
720
|
-
audioMs:
|
|
719
|
+
audioMs: realtimeVoiceAudioDurationMs(REALTIME_VOICE_AUDIO_FORMAT_PCM16_24KHZ, realtimePcm24kMono.byteLength),
|
|
721
720
|
sourceAudioBytes: realtimePcm24kMono.length,
|
|
722
721
|
sinkAudioBytes: discordPcm.length
|
|
723
722
|
});
|
|
@@ -741,19 +740,10 @@ var DiscordRealtimePlayback = class {
|
|
|
741
740
|
this.completeExactSpeechResponse(reason);
|
|
742
741
|
return;
|
|
743
742
|
}
|
|
744
|
-
stream.end();
|
|
745
|
-
}
|
|
746
|
-
handleProviderEvent(event) {
|
|
747
|
-
if (!(this.playbackState.status === "backpressured" && isRealtimeResponseCancellationRace(event))) return;
|
|
748
|
-
const outputBackpressured = this.playbackState.status === "backpressured";
|
|
749
|
-
if (outputBackpressured) this.playbackState = { status: "idle" };
|
|
750
|
-
if (this.exactSpeechState.status === "active" && (outputBackpressured || !this.exactSpeechState.audioStarted)) this.completeExactSpeechResponse(event.type);
|
|
751
|
-
this.finishOutputAudioStream(event.type, { playBuffered: false });
|
|
743
|
+
if (!this.outputDrainHandler) stream.end();
|
|
752
744
|
}
|
|
753
745
|
handleResponseDone(outcome) {
|
|
754
|
-
|
|
755
|
-
if (outputBackpressured) this.playbackState = { status: "idle" };
|
|
756
|
-
if (this.exactSpeechState.status === "active" && (outputBackpressured || !this.exactSpeechState.audioStarted)) this.completeExactSpeechResponse(outcome.status);
|
|
746
|
+
if (this.exactSpeechState.status === "active" && !this.exactSpeechState.audioStarted) this.completeExactSpeechResponse(outcome.status);
|
|
757
747
|
this.finishOutputAudioStream(outcome.status, { playBuffered: outcome.status === "completed" });
|
|
758
748
|
}
|
|
759
749
|
enqueueExactSpeechMessage(text) {
|
|
@@ -762,11 +752,7 @@ var DiscordRealtimePlayback = class {
|
|
|
762
752
|
const retainedBytes = this.queuedExactSpeechMessages.reduce((total, message) => total + Buffer.byteLength(message, "utf8"), 0) + Buffer.byteLength(this.exactSpeechState.status === "active" ? this.exactSpeechState.message : "", "utf8");
|
|
763
753
|
const incomingBytes = Buffer.byteLength(text, "utf8");
|
|
764
754
|
if (retainedMessages >= DISCORD_REALTIME_MAX_RETAINED_EXACT_SPEECH_MESSAGES || retainedBytes + incomingBytes > DISCORD_REALTIME_MAX_RETAINED_EXACT_SPEECH_BYTES) {
|
|
765
|
-
this.
|
|
766
|
-
this.queuedExactSpeechMessages = [];
|
|
767
|
-
this.exactSpeechState = { status: "idle" };
|
|
768
|
-
this.clearOutputAudio("exact-speech-overflow");
|
|
769
|
-
this.params.onTerminalError(/* @__PURE__ */ new Error(`Discord realtime exact speech overflow: retained=${retainedMessages} retainedBytes=${retainedBytes} incomingBytes=${incomingBytes}`));
|
|
755
|
+
this.stopAfterOverflow("exact-speech-overflow", /* @__PURE__ */ new Error(`Discord realtime exact speech overflow: retained=${retainedMessages} retainedBytes=${retainedBytes} incomingBytes=${incomingBytes}`));
|
|
770
756
|
return;
|
|
771
757
|
}
|
|
772
758
|
if (!this.params.bridgeReady() || this.exactSpeechState.status === "active" || this.hasInterruptibleOutputAudio()) {
|
|
@@ -846,84 +832,83 @@ var DiscordRealtimePlayback = class {
|
|
|
846
832
|
currentOutputStream() {
|
|
847
833
|
return this.outputStream;
|
|
848
834
|
}
|
|
835
|
+
stopAfterOverflow(reason, error) {
|
|
836
|
+
this.params.stopTerminally();
|
|
837
|
+
this.queuedExactSpeechMessages = [];
|
|
838
|
+
this.exactSpeechState = { status: "idle" };
|
|
839
|
+
this.clearOutputAudio(reason);
|
|
840
|
+
this.params.onTerminalError(error);
|
|
841
|
+
}
|
|
849
842
|
ensureOutputStream() {
|
|
850
843
|
if (this.outputStream && !this.outputStream.destroyed && !this.outputStream.writableEnded) return this.outputStream;
|
|
851
844
|
const stream = new PassThrough({ highWaterMark: DISCORD_RAW_PCM_FRAME_BYTES * 128 });
|
|
852
845
|
this.outputStream = stream;
|
|
853
|
-
this.
|
|
854
|
-
|
|
855
|
-
stream
|
|
856
|
-
};
|
|
857
|
-
this.outputPacedBuffer = Buffer.alloc(0);
|
|
846
|
+
this.outputPacedBuffers = [];
|
|
847
|
+
this.outputPacedBytes = 0;
|
|
858
848
|
this.params.harness.outputActivity.markStreamOpened();
|
|
859
849
|
stream.once("close", () => {
|
|
860
|
-
if (this.params.harness.outputActivity.snapshot().playbackStarted) return;
|
|
861
|
-
this.
|
|
850
|
+
if (this.outputStream !== stream || this.params.harness.outputActivity.snapshot().playbackStarted) return;
|
|
851
|
+
this.resetOutputStream("stream-close");
|
|
852
|
+
this.completeExactSpeechResponse("stream-close");
|
|
862
853
|
});
|
|
863
854
|
return stream;
|
|
864
855
|
}
|
|
865
|
-
handleOutputStreamClosed(stream, reason) {
|
|
866
|
-
if (this.outputStream !== stream) return;
|
|
867
|
-
this.logOutputAudioStopped(reason);
|
|
868
|
-
this.clearOutputPlaybackWatchdog();
|
|
869
|
-
this.outputStream = null;
|
|
870
|
-
if (this.playbackState.status !== "backpressured") this.playbackState = { status: "idle" };
|
|
871
|
-
this.outputPacedBuffer = Buffer.alloc(0);
|
|
872
|
-
this.params.harness.outputActivity.reset();
|
|
873
|
-
this.completeExactSpeechResponse(reason);
|
|
874
|
-
}
|
|
875
856
|
queueOutputAudio(stream, discordPcm) {
|
|
876
|
-
|
|
877
|
-
|
|
857
|
+
const pendingBytes = this.outputPacedBytes + stream.writableLength + stream.readableLength;
|
|
858
|
+
if (discordPcm.length > DISCORD_REALTIME_MAX_PENDING_OUTPUT_BYTES - pendingBytes) {
|
|
859
|
+
this.stopAfterOverflow("output-audio-overflow", /* @__PURE__ */ new Error(`Discord realtime audio playback overflow: pendingBytes=${pendingBytes} incomingBytes=${discordPcm.length}`));
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
if (this.params.harness.outputActivity.snapshot().playbackStarted && !this.outputDrainHandler) {
|
|
863
|
+
if (!stream.write(discordPcm)) this.waitForOutputDrain(stream);
|
|
878
864
|
return;
|
|
879
865
|
}
|
|
880
|
-
this.
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
this.
|
|
887
|
-
|
|
888
|
-
stream
|
|
889
|
-
|
|
866
|
+
this.outputPacedBuffers.push(discordPcm);
|
|
867
|
+
this.outputPacedBytes += discordPcm.length;
|
|
868
|
+
if (!this.outputDrainHandler && this.outputPacedBytes >= DISCORD_RAW_PCM_FRAME_BYTES * DISCORD_REALTIME_OUTPUT_PREROLL_FRAMES) this.startOutputPlayback(stream);
|
|
869
|
+
}
|
|
870
|
+
waitForOutputDrain(stream) {
|
|
871
|
+
if (this.outputDrainHandler || this.outputStream !== stream) return;
|
|
872
|
+
logger$1.info(`discord voice: realtime audio playback buffering guild=${this.params.entry.guildId} channel=${this.params.entry.channelId} bufferedBytes=${stream.writableLength + stream.readableLength}`);
|
|
873
|
+
this.outputDrainHandler = () => {
|
|
874
|
+
if (this.params.stopped() || this.outputStream !== stream || stream.destroyed) return;
|
|
875
|
+
this.outputDrainHandler = void 0;
|
|
876
|
+
let refreshWatchdog = this.params.harness.outputActivity.snapshot().streamEnding;
|
|
877
|
+
while (this.outputPacedBuffers.length > 0) {
|
|
878
|
+
const buffered = this.outputPacedBuffers.shift();
|
|
879
|
+
if (!buffered) break;
|
|
880
|
+
this.outputPacedBytes -= buffered.length;
|
|
881
|
+
const writable = stream.write(buffered);
|
|
882
|
+
if (refreshWatchdog) {
|
|
883
|
+
this.scheduleOutputPlaybackWatchdog("output-drain", stream);
|
|
884
|
+
refreshWatchdog = false;
|
|
885
|
+
}
|
|
886
|
+
if (!writable) {
|
|
887
|
+
this.waitForOutputDrain(stream);
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
if (this.params.harness.outputActivity.snapshot().streamEnding) stream.end();
|
|
890
892
|
};
|
|
891
|
-
|
|
892
|
-
logger$1.warn(`discord voice: realtime audio playback backpressured guild=${this.params.entry.guildId} channel=${this.params.entry.channelId} bufferedBytes=${bufferedBytes}`);
|
|
893
|
-
this.clearOutputAudio("output-backpressure");
|
|
894
|
-
queueMicrotask(() => {
|
|
895
|
-
if (this.params.stopped() || this.playbackState.status !== "backpressured" || this.playbackState.token !== token) return;
|
|
896
|
-
this.params.harness.handleBargeIn({
|
|
897
|
-
audioPlaybackActive: true,
|
|
898
|
-
force: true
|
|
899
|
-
}, () => {});
|
|
900
|
-
});
|
|
893
|
+
stream.once("drain", this.outputDrainHandler);
|
|
901
894
|
}
|
|
902
895
|
startOutputPlayback(stream) {
|
|
903
896
|
if (this.params.harness.outputActivity.snapshot().playbackStarted || stream.destroyed) return;
|
|
904
897
|
const voiceSdk = loadDiscordVoiceSdk();
|
|
905
898
|
const opusStream = createDiscordOpusEncodeStream();
|
|
906
|
-
opusStream.on("error", (err) => {
|
|
907
|
-
logger$1.warn(`discord voice: realtime opus encode failed guild=${this.params.entry.guildId} channel=${this.params.entry.channelId}: ${formatErrorMessage(err)}`);
|
|
908
|
-
this.resetOutputStream("opus-encode-error");
|
|
909
|
-
});
|
|
910
|
-
opusStream.once("close", () => this.handleOutputStreamClosed(stream, "stream-close"));
|
|
911
899
|
pipeline(stream, opusStream, (err) => {
|
|
912
|
-
if (!err) return;
|
|
900
|
+
if (!err || this.outputStream !== stream) return;
|
|
913
901
|
logger$1.warn(`discord voice: realtime output pipeline failed guild=${this.params.entry.guildId} channel=${this.params.entry.channelId}: ${formatErrorMessage(err)}`);
|
|
914
|
-
this.
|
|
902
|
+
this.clearOutputAudio("output-pipeline-error");
|
|
903
|
+
this.completeExactSpeechResponse("output-pipeline-error");
|
|
915
904
|
});
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
905
|
+
const buffered = Buffer.concat(this.outputPacedBuffers, this.outputPacedBytes);
|
|
906
|
+
this.outputPacedBuffers = [];
|
|
907
|
+
this.outputPacedBytes = 0;
|
|
908
|
+
if (buffered.length > 0 && !stream.write(buffered)) this.waitForOutputDrain(stream);
|
|
920
909
|
const resource = voiceSdk.createAudioResource(opusStream, { inputType: voiceSdk.StreamType.Opus });
|
|
921
910
|
this.params.entry.player.play(resource);
|
|
922
911
|
this.params.harness.outputActivity.markPlaybackStarted();
|
|
923
|
-
this.playbackState = {
|
|
924
|
-
status: "playing",
|
|
925
|
-
stream
|
|
926
|
-
};
|
|
927
912
|
const realtimeConfig = this.params.realtimeConfig();
|
|
928
913
|
logger$1.info(`discord voice: realtime audio playback started guild=${this.params.entry.guildId} channel=${this.params.entry.channelId} mode=${this.params.mode} model=${realtimeConfig?.model ?? "provider-default"} voice=${realtimeConfig?.speakerVoice ?? realtimeConfig?.speakerVoiceId ?? "provider-default"}`);
|
|
929
914
|
}
|
|
@@ -932,15 +917,22 @@ var DiscordRealtimePlayback = class {
|
|
|
932
917
|
this.clearOutputPlaybackWatchdog();
|
|
933
918
|
this.logOutputAudioStopped(reason);
|
|
934
919
|
this.outputStream = null;
|
|
935
|
-
|
|
936
|
-
this.
|
|
920
|
+
this.outputPacedBuffers = [];
|
|
921
|
+
this.outputPacedBytes = 0;
|
|
922
|
+
if (this.outputDrainHandler) {
|
|
923
|
+
stream?.off("drain", this.outputDrainHandler);
|
|
924
|
+
this.outputDrainHandler = void 0;
|
|
925
|
+
}
|
|
937
926
|
this.params.harness.outputActivity.reset();
|
|
938
927
|
stream?.end();
|
|
939
928
|
stream?.destroy();
|
|
940
929
|
}
|
|
941
930
|
scheduleOutputPlaybackWatchdog(reason, stream) {
|
|
942
931
|
this.clearOutputPlaybackWatchdog();
|
|
943
|
-
const timeoutMs = this.params.harness.outputActivity.playbackWatchdogDelayMs({
|
|
932
|
+
const timeoutMs = this.params.harness.outputActivity.playbackWatchdogDelayMs({
|
|
933
|
+
marginMs: DISCORD_REALTIME_OUTPUT_PLAYBACK_WATCHDOG_MARGIN_MS,
|
|
934
|
+
minMs: DISCORD_REALTIME_OUTPUT_PLAYBACK_WATCHDOG_MARGIN_MS
|
|
935
|
+
});
|
|
944
936
|
if (timeoutMs === void 0) return;
|
|
945
937
|
this.outputPlaybackWatchdog = setTimeout(() => {
|
|
946
938
|
this.outputPlaybackWatchdog = void 0;
|
|
@@ -1030,7 +1022,6 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1030
1022
|
status: "inactive",
|
|
1031
1023
|
generation: 0
|
|
1032
1024
|
};
|
|
1033
|
-
this.nextLifecycleGeneration = 0;
|
|
1034
1025
|
this.consultToolPolicy = "safe-read-only";
|
|
1035
1026
|
this.consultPolicy = "auto";
|
|
1036
1027
|
this.wakeNamePolicy = "never";
|
|
@@ -1073,7 +1064,7 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1073
1064
|
providerId: () => this.realtimeProviderId,
|
|
1074
1065
|
realtimeConfig: () => this.realtimeConfig,
|
|
1075
1066
|
stopTerminally: () => {
|
|
1076
|
-
this.
|
|
1067
|
+
this.lifecycle.status = "stopped";
|
|
1077
1068
|
this.consults.close();
|
|
1078
1069
|
},
|
|
1079
1070
|
stopped: () => this.isStopped(),
|
|
@@ -1112,20 +1103,30 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1112
1103
|
});
|
|
1113
1104
|
}
|
|
1114
1105
|
async connect() {
|
|
1115
|
-
const lifecycleGeneration =
|
|
1106
|
+
const lifecycleGeneration = this.lifecycle.generation + 1;
|
|
1116
1107
|
this.lifecycle = {
|
|
1117
1108
|
status: "starting",
|
|
1118
|
-
generation: lifecycleGeneration
|
|
1119
|
-
instance: this
|
|
1109
|
+
generation: lifecycleGeneration
|
|
1120
1110
|
};
|
|
1111
|
+
const configuredProviderId = this.realtimeConfig?.provider?.trim();
|
|
1112
|
+
if (configuredProviderId) {
|
|
1113
|
+
const ownerProviderIds = /* @__PURE__ */ new Set([configuredProviderId]);
|
|
1114
|
+
const canonicalProviderId = canonicalizeRealtimeVoiceProviderId(configuredProviderId, this.params.cfg);
|
|
1115
|
+
if (canonicalProviderId) ownerProviderIds.add(canonicalProviderId);
|
|
1116
|
+
for (const providerId of ownerProviderIds) assertSecretOwnerAvailable("capability", discordRealtimeVoiceSecretOwnerId(this.params.accountId, providerId));
|
|
1117
|
+
}
|
|
1121
1118
|
const resolved = resolveConfiguredRealtimeVoiceProvider({
|
|
1122
1119
|
configuredProviderId: this.realtimeConfig?.provider,
|
|
1123
1120
|
providerConfigs: buildProviderConfigs(this.realtimeConfig),
|
|
1124
1121
|
providerConfigOverrides: buildProviderConfigOverrides(this.realtimeConfig),
|
|
1125
1122
|
cfg: this.params.cfg,
|
|
1123
|
+
agentId: this.params.entry.route.agentId,
|
|
1126
1124
|
defaultModel: this.realtimeConfig?.model,
|
|
1125
|
+
isProviderAvailable: (provider) => isSecretOwnerAvailable("capability", discordRealtimeVoiceSecretOwnerId(this.params.accountId, provider.id)),
|
|
1126
|
+
assertProviderAvailable: (provider) => assertSecretOwnerAvailable("capability", discordRealtimeVoiceSecretOwnerId(this.params.accountId, provider.id)),
|
|
1127
1127
|
noRegisteredProviderMessage: "No configured realtime voice provider registered"
|
|
1128
1128
|
});
|
|
1129
|
+
assertSecretOwnerAvailable("capability", discordRealtimeVoiceSecretOwnerId(this.params.accountId, resolved.provider.id));
|
|
1129
1130
|
this.realtimeProviderId = resolved.provider.id;
|
|
1130
1131
|
const isAgentProxy = isDiscordAgentProxyVoiceMode(this.params.mode);
|
|
1131
1132
|
const { toolPolicy, consultToolsAllow, consultPolicy, wakeNamePolicy, wakeNames, autoRespondToAudio } = resolveRealtimeVoiceSessionPolicy({
|
|
@@ -1158,9 +1159,14 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1158
1159
|
toolPolicy,
|
|
1159
1160
|
consultPolicy
|
|
1160
1161
|
});
|
|
1162
|
+
const onReady = () => {
|
|
1163
|
+
this.markProviderGenerationObserved();
|
|
1164
|
+
if (this.markLifecycleReady(lifecycleGeneration)) this.playback.drainQueuedExactSpeechMessages("provider-ready");
|
|
1165
|
+
};
|
|
1161
1166
|
this.bridge = this.harness.createBridge({
|
|
1162
1167
|
provider: resolved.provider,
|
|
1163
1168
|
cfg: this.params.cfg,
|
|
1169
|
+
agentId: this.params.entry.route.agentId,
|
|
1164
1170
|
providerConfig: resolved.providerConfig,
|
|
1165
1171
|
audioFormat: REALTIME_VOICE_AUDIO_FORMAT_PCM16_24KHZ,
|
|
1166
1172
|
instructions,
|
|
@@ -1191,11 +1197,11 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1191
1197
|
this.markProviderGenerationObserved();
|
|
1192
1198
|
return this.consults.handleToolCall(event, session);
|
|
1193
1199
|
},
|
|
1194
|
-
onReady
|
|
1195
|
-
|
|
1196
|
-
|
|
1200
|
+
onReady,
|
|
1201
|
+
onEvent: (event) => {
|
|
1202
|
+
this.handleBridgeEvent(event);
|
|
1203
|
+
if (event.direction === "client" && event.type === "session.reconnect.ready") onReady();
|
|
1197
1204
|
},
|
|
1198
|
-
onEvent: (event) => this.handleBridgeEvent(event),
|
|
1199
1205
|
onResponseDone: (outcome) => {
|
|
1200
1206
|
this.markProviderGenerationObserved();
|
|
1201
1207
|
this.playback.handleResponseDone(outcome);
|
|
@@ -1204,10 +1210,16 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1204
1210
|
},
|
|
1205
1211
|
onError: (error) => this.logRealtimeError(formatErrorMessage(error)),
|
|
1206
1212
|
onClose: (reason) => {
|
|
1207
|
-
this.
|
|
1208
|
-
|
|
1213
|
+
if (!this.isStopped()) {
|
|
1214
|
+
this.lifecycle.status = "stopped";
|
|
1215
|
+
this.params.onTerminalError(/* @__PURE__ */ new Error(`Realtime provider closed unexpectedly: ${reason}`));
|
|
1216
|
+
}
|
|
1209
1217
|
}
|
|
1210
1218
|
});
|
|
1219
|
+
if (this.isStopped()) {
|
|
1220
|
+
this.close();
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1211
1223
|
const resolvedModel = readProviderConfigString(resolved.providerConfig, "model") ?? resolved.provider.defaultModel;
|
|
1212
1224
|
const resolvedVoice = readProviderConfigString(resolved.providerConfig, "voice");
|
|
1213
1225
|
const humanParticipantCount = this.humanParticipantCount();
|
|
@@ -1223,7 +1235,7 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1223
1235
|
logger.info(`discord voice: realtime bridge ready mode=${this.params.mode} provider=${resolved.provider.id} model=${resolvedModel ?? "default"} voice=${resolvedVoice ?? "default"}`);
|
|
1224
1236
|
}
|
|
1225
1237
|
close() {
|
|
1226
|
-
this.
|
|
1238
|
+
this.lifecycle.status = "stopped";
|
|
1227
1239
|
this.providerContinuityEpoch += 1;
|
|
1228
1240
|
this.flushSuppressedRealtimeErrors();
|
|
1229
1241
|
this.consults.close();
|
|
@@ -1255,21 +1267,9 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1255
1267
|
}
|
|
1256
1268
|
markLifecycleReady(generation) {
|
|
1257
1269
|
if (this.lifecycle.status !== "starting" && this.lifecycle.status !== "active" || this.lifecycle.generation !== generation) return false;
|
|
1258
|
-
this.lifecycle =
|
|
1259
|
-
status: "active",
|
|
1260
|
-
generation,
|
|
1261
|
-
instance: this
|
|
1262
|
-
};
|
|
1270
|
+
this.lifecycle.status = "active";
|
|
1263
1271
|
return true;
|
|
1264
1272
|
}
|
|
1265
|
-
stopLifecycle(reason) {
|
|
1266
|
-
const generation = this.lifecycle.generation;
|
|
1267
|
-
this.lifecycle = {
|
|
1268
|
-
status: "stopped",
|
|
1269
|
-
generation,
|
|
1270
|
-
reason
|
|
1271
|
-
};
|
|
1272
|
-
}
|
|
1273
1273
|
humanParticipantCount() {
|
|
1274
1274
|
return this.params.getHumanParticipantCount?.() ?? 0;
|
|
1275
1275
|
}
|
|
@@ -1282,7 +1282,6 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1282
1282
|
if (event.direction === "client" && event.type === "session.continuity.reset") this.resetProviderContinuity(event.type);
|
|
1283
1283
|
if (event.direction === "server" && event.type === "input_audio_buffer.speech_started") this.turns.resetPartialWakeNameTracking();
|
|
1284
1284
|
if (shouldLogRealtimeVerboseEvent(event)) logVoiceVerbose(`realtime ${event.direction}:${event.type}${detail}`);
|
|
1285
|
-
this.playback.handleProviderEvent(event);
|
|
1286
1285
|
const interruptionLog = formatRealtimeInterruptionLog(event);
|
|
1287
1286
|
if (interruptionLog) logger.info(interruptionLog);
|
|
1288
1287
|
const lifecycleLog = formatRealtimeLifecycleLog(event);
|
|
@@ -1294,11 +1293,7 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1294
1293
|
resetProviderContinuity(reason) {
|
|
1295
1294
|
if (!this.providerGenerationObserved) return;
|
|
1296
1295
|
this.providerGenerationObserved = false;
|
|
1297
|
-
if (this.lifecycle.status === "active") this.lifecycle =
|
|
1298
|
-
status: "starting",
|
|
1299
|
-
generation: this.lifecycle.generation,
|
|
1300
|
-
instance: this
|
|
1301
|
-
};
|
|
1296
|
+
if (this.lifecycle.status === "active") this.lifecycle.status = "starting";
|
|
1302
1297
|
this.providerContinuityEpoch += 1;
|
|
1303
1298
|
this.consults.resetProviderContinuity();
|
|
1304
1299
|
this.turns.resetProviderContinuity();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { m as normalizeDiscordToken } from "./accounts-CfQ-vSyf.js";
|
|
2
2
|
import { r as fetchDiscord } from "./api-DNVbJyEy.js";
|
|
3
|
-
import { a as normalizeDiscordSlug } from "./allow-list-
|
|
3
|
+
import { a as normalizeDiscordSlug } from "./allow-list-BDMimASD.js";
|
|
4
4
|
//#region extensions/discord/src/guilds.ts
|
|
5
5
|
async function listGuilds(token, fetcher, options) {
|
|
6
6
|
return (await fetchDiscord("/users/@me/guilds", token, fetcher, options)).filter((guild) => typeof guild.id === "string" && typeof guild.name === "string").map((guild) => ({
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { on as __exportAll } from "./retry-DqHCW6PV.js";
|
|
2
2
|
import { n as DiscordApiError, r as fetchDiscord, t as DISCORD_DIRECTORY_LOOKUP_TIMEOUT_MS } from "./api-DNVbJyEy.js";
|
|
3
|
-
import { a as normalizeDiscordSlug } from "./allow-list-
|
|
4
|
-
import {
|
|
3
|
+
import { a as normalizeDiscordSlug } from "./allow-list-BDMimASD.js";
|
|
4
|
+
import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
|
|
5
|
+
import { i as listGuilds, n as filterDiscordGuilds, r as resolveDiscordAllowlistToken, t as buildDiscordUnresolvedResults } from "./resolve-allowlist-common-BLoYaxEG.js";
|
|
5
6
|
//#region extensions/discord/src/resolve-channels.ts
|
|
6
7
|
var resolve_channels_exports = /* @__PURE__ */ __exportAll({ resolveDiscordChannelAllowlist: () => resolveDiscordChannelAllowlist });
|
|
7
8
|
function parseDiscordChannelInput(raw) {
|
|
@@ -79,7 +80,7 @@ async function fetchChannel(token, fetcher, channelId) {
|
|
|
79
80
|
function preferActiveMatch(candidates) {
|
|
80
81
|
if (candidates.length === 0) return;
|
|
81
82
|
const scored = candidates.map((channel) => {
|
|
82
|
-
const isThread = channel.type
|
|
83
|
+
const isThread = isDiscordThreadChannelType(channel.type);
|
|
83
84
|
return {
|
|
84
85
|
channel,
|
|
85
86
|
score: (Boolean(channel.archived) ? 0 : 2) + (isThread ? 0 : 1)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { on as __exportAll } from "./retry-DqHCW6PV.js";
|
|
2
2
|
import { r as fetchDiscord, t as DISCORD_DIRECTORY_LOOKUP_TIMEOUT_MS } from "./api-DNVbJyEy.js";
|
|
3
|
-
import { i as listGuilds, n as filterDiscordGuilds, r as resolveDiscordAllowlistToken, t as buildDiscordUnresolvedResults } from "./resolve-allowlist-common-
|
|
3
|
+
import { i as listGuilds, n as filterDiscordGuilds, r as resolveDiscordAllowlistToken, t as buildDiscordUnresolvedResults } from "./resolve-allowlist-common-BLoYaxEG.js";
|
|
4
4
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
//#region extensions/discord/src/resolve-users.ts
|
|
6
6
|
var resolve_users_exports = /* @__PURE__ */ __exportAll({ resolveDiscordUserAllowlist: () => resolveDiscordUserAllowlist });
|