@openclaw/discord 2026.9.5 → 2026.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/icon.png +0 -0
- package/dist/.setup/{account-inspect-BwQj24ht.mjs → account-inspect-De8hOUxG.mjs} +1 -1
- package/dist/.setup/{accounts-CwJQoLjM.mjs → accounts-ChaMcixG.mjs} +1 -4
- package/dist/.setup/{activities-api-DBwRt5ES.mjs → activities-api-tvbsU2e3.mjs} +38 -66
- package/dist/.setup/{api-CBK9zcq5.mjs → api-DVbJwZVt.mjs} +10 -2
- package/dist/.setup/{approval-handler.runtime-Du3n5ypX.mjs → approval-handler.runtime-DxCK2Rux.mjs} +49 -125
- package/dist/.setup/{approval-message-updates-BN7JtScm.mjs → approval-message-updates-BKFqavHZ.mjs} +2 -2
- package/dist/.setup/{audit-C8uaKoa9.mjs → audit-CLg9I71N.mjs} +5 -5
- package/dist/.setup/{channel-ChKdlBgH.mjs → channel-DxlUVU9t.mjs} +125 -228
- package/dist/.setup/{channel-type-DKnjV1XW.mjs → channel-type-DRCrEMss.mjs} +22 -22
- package/dist/.setup/{channel.setup-BlC3-Kzz.mjs → channel.setup-CRo1GjV7.mjs} +6 -9
- package/dist/.setup/{components-MqMWUWnE.mjs → components-Cq1PvIpN.mjs} +42 -71
- package/dist/.setup/{config-schema-CiZz-mtA.mjs → config-schema-oxELUSDx.mjs} +19 -44
- package/dist/.setup/{conversation-binding-route-_rz33QHO.mjs → conversation-binding-route-Caz_XuFH.mjs} +14 -6
- package/dist/.setup/{directory-config-BytTftz-.mjs → directory-config-esqNn0Eo.mjs} +6 -9
- package/dist/.setup/{directory-live--EGTH0DC.mjs → directory-live-DtKRHuGV.mjs} +6 -12
- package/dist/.setup/{discord-BXpHW-cu.mjs → discord-0xJYfdDD.mjs} +82 -386
- package/dist/.setup/{doctor-DxcdkXzz.mjs → doctor-BCl1H5tl.mjs} +21 -36
- package/dist/.setup/{doctor-contract-Co5vRCZ6.mjs → doctor-contract-CvvgwrrG.mjs} +41 -50
- package/dist/.setup/{channel-actions.runtime-CJmiFfps.mjs → handle-action-CUvQWnE7.mjs} +74 -105
- package/dist/.setup/{handle-action.guild-admin-DAFyh_yV.mjs → handle-action.guild-admin-Df-8gVle.mjs} +63 -121
- package/dist/.setup/{live-policy-config-eKQ-PLdy.mjs → live-policy-config-8Pv20CHc.mjs} +2 -3
- package/dist/.setup/{message-handler-DnUrDpaU.mjs → message-handler-B-Jk4oDk.mjs} +18 -93
- package/dist/.setup/message-handler.preflight-pluralkit-CWLUBVcx.mjs +141 -0
- package/dist/.setup/{message-handler.preflight-CtqaF_fb.mjs → message-handler.preflight-v-__NSDq.mjs} +73 -287
- package/dist/.setup/{message-handler.process-Dz1xvuQU.mjs → message-handler.process-BNFFuChn.mjs} +423 -374
- package/dist/.setup/{outbound-adapter-C8v79z9Z.mjs → outbound-adapter-BobT-kse.mjs} +105 -19
- package/dist/.setup/{outbound-session-route-CqWbuMOm.mjs → outbound-session-route-zVGxxceg.mjs} +142 -109
- package/dist/.setup/{pluralkit-CdAt1G0P.mjs → pluralkit-a6_NLfH9.mjs} +1 -1
- package/dist/.setup/{preflight-audio-DrnqFA8U.mjs → preflight-audio-DHGIHEpv.mjs} +2 -1
- package/dist/.setup/{presence-cache-dYSHPWMx.mjs → presence-cache-Di3H3DIU.mjs} +0 -4
- package/dist/.setup/{probe-CupW4we4.mjs → probe-LYrIHlBF.mjs} +13 -4
- package/dist/.setup/{provider-72zIvN-i.mjs → provider-B_G5hASF.mjs} +1112 -1668
- package/dist/.setup/provider-session.runtime-BYlTBFD2.mjs +6 -0
- package/dist/.setup/provider.runtime-CUE3UxER.mjs +2 -0
- package/dist/.setup/{realtime-session.runtime-DTccTgTM.mjs → realtime-session.runtime-oUd9DOcz.mjs} +372 -345
- package/dist/.setup/receive-recovery-CHPOsnLc.mjs +514 -0
- package/dist/.setup/{resolve-allowlist-common-CwMBzbx9.mjs → resolve-allowlist-common-DPdRggu5.mjs} +4 -7
- package/dist/.setup/{resolve-channels-BbvsLQOZ.mjs → resolve-channels-BFPNRmVv.mjs} +21 -40
- package/dist/.setup/{resolve-users-ByFlR7LQ.mjs → resolve-users-0-aBuCy3.mjs} +4 -4
- package/dist/.setup/{retry-DBfcEgmO.mjs → retry-pz_cSha2.mjs} +81 -16
- package/dist/.setup/rolldown-runtime-B4FMCO8f.mjs +28 -0
- package/dist/.setup/{runtime-SchNfUsQ.mjs → runtime-FN000lxA.mjs} +83 -166
- package/dist/.setup/runtime-doctor-migrations-CshUGl36.mjs +159 -0
- package/dist/.setup/{runtime-BVoa7hhx.mjs → runtime-sUksZ--Q.mjs} +2 -5
- package/dist/.setup/{secret-config-contract-DFu9hfU8.mjs → secret-config-contract-uOE2J7yM.mjs} +15 -85
- package/dist/.setup/{security-audit-s5w50-Ly.mjs → security-audit-Cdaegq7C.mjs} +3 -1
- package/dist/.setup/{send-CKDczUNL.mjs → send-CrfEI6Bs.mjs} +73 -114
- package/dist/.setup/{send.components-DWQjXhPV.mjs → send.components-DxQAMfES.mjs} +62 -107
- package/dist/.setup/{send.outbound-D0hQ7s50.mjs → send.outbound-BISKnb-a.mjs} +79 -154
- package/dist/.setup/{send.shared-Zwx6BxQ5.mjs → send.shared-DGFkbkQR.mjs} +10 -25
- package/dist/.setup/{sender-identity-0Ymgvmaj.mjs → sender-identity-B9X5Vb9R.mjs} +2 -3
- package/dist/.setup/setup-plugin-api-BQUBxbhe.mjs +3 -0
- package/dist/.setup/{shared-CaA3Vv4n.mjs → shared-B3wZ4hN-.mjs} +25 -32
- package/dist/.setup/{subagent-hooks-Bired9q6.mjs → subagent-hooks-nlUE9ow7.mjs} +5 -6
- package/dist/.setup/system-events-CdeZnvPV.mjs +33 -0
- package/dist/.setup/{target-resolver-B6MrxbYv.mjs → target-resolver-BuLapkhy.mjs} +9 -12
- package/dist/.setup/targets-0KUcEIYx.mjs +3 -0
- package/dist/.setup/{thread-bindings-CK5272V3.mjs → thread-bindings-D7TfgjR_.mjs} +33 -35
- package/dist/.setup/thread-bindings.manager-DN-NissX.mjs +819 -0
- package/dist/.setup/thread-bindings.session-updates-CshfKghV.mjs +359 -0
- package/dist/.setup/{thread-bindings.state-BThFQEga.mjs → thread-bindings.state-g6v9zAym.mjs} +21 -62
- package/dist/.setup/{transcripts-source-CuWYgayu.mjs → transcripts-source-p8EV179h.mjs} +133 -238
- package/dist/.setup/{typing-BKZL5fGj.mjs → typing-BiHCzBRu.mjs} +2 -1
- package/dist/.setup/{voice-runtime-DHVQ2mFz.mjs → voice-runtime-B46rcwrG.mjs} +633 -1085
- package/dist/account-inspect-api.js +1 -1
- package/dist/action-runtime-api.js +1 -1
- package/dist/activities-api.js +1 -1
- package/dist/api.js +18 -18
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/doctor-contract-api.js +4 -4
- package/dist/index.js +1 -1
- package/dist/runtime-api.js +20 -20
- package/dist/secret-contract-api.js +1 -1
- package/dist/security-audit-contract-api.js +1 -1
- package/dist/setup-entry.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/src/voice/audio-worker.runtime.js +1056 -0
- package/dist/subagent-hooks-api.js +3 -4
- package/dist/transcripts-source-api.js +1 -1
- package/node_modules/@napi-rs/wasm-runtime/dist/emnapi-plugins.cjs +8 -4
- package/node_modules/@napi-rs/wasm-runtime/dist/emnapi-plugins.js +8 -4
- package/node_modules/@napi-rs/wasm-runtime/dist/fs-proxy.cjs +1 -1
- package/node_modules/@napi-rs/wasm-runtime/dist/fs.js +770 -695
- package/node_modules/@napi-rs/wasm-runtime/fs-proxy.js +3 -2
- package/node_modules/@napi-rs/wasm-runtime/package.json +1 -1
- package/node_modules/@tybys/wasm-util/LICENSE +21 -0
- package/node_modules/@tybys/wasm-util/package.json +1 -1
- package/node_modules/@types/node/README.md +2 -2
- package/node_modules/@types/node/child_process.d.ts +1 -1
- package/node_modules/@types/node/crypto.d.ts +20 -8
- package/node_modules/@types/node/ffi.d.ts +14 -0
- package/node_modules/@types/node/http2.d.ts +3 -2
- package/node_modules/@types/node/net.d.ts +16 -4
- package/node_modules/@types/node/package.json +2 -17
- package/node_modules/@types/node/process.d.ts +1 -0
- package/node_modules/@types/node/quic.d.ts +39 -1
- package/node_modules/@types/node/stream/iter.d.ts +9 -12
- package/node_modules/@types/node/test/reporters.d.ts +1 -0
- package/node_modules/@types/node/test.d.ts +72 -0
- package/node_modules/@types/node/tls.d.ts +14 -10
- package/node_modules/@types/node/vm.d.ts +2 -1
- package/node_modules/@types/node/web-globals/streams.d.ts +4 -0
- package/node_modules/@types/node/worker_threads.d.ts +4 -1
- package/node_modules/typebox/build/compile/code.mjs +1 -2
- package/node_modules/typebox/build/compile/validator.mjs +5 -1
- package/node_modules/typebox/build/format/iri.mjs +16 -9
- package/node_modules/typebox/build/guard/emit.mjs +2 -2
- package/node_modules/typebox/build/guard/guard.d.mts +7 -5
- package/node_modules/typebox/build/guard/guard.mjs +14 -9
- package/node_modules/typebox/build/guard/index.mjs +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
- package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
- package/node_modules/typebox/build/schema/build.mjs +2 -3
- package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
- package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
- package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
- package/node_modules/typebox/build/schema/parse.mjs +3 -0
- package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
- package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
- package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
- package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
- package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
- package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
- package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
- package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
- package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
- package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +3 -1
- package/node_modules/zod/README.md +2 -2
- package/node_modules/zod/compile.cjs +19 -0
- package/node_modules/zod/index.cjs +19 -0
- package/node_modules/zod/locales/index.cjs +19 -0
- package/node_modules/zod/mini/index.cjs +19 -0
- package/node_modules/zod/package.json +8 -7
- package/node_modules/zod/src/v3/helpers/errorUtil.ts +1 -1
- package/node_modules/zod/src/v4/classic/external.ts +2 -0
- package/node_modules/zod/src/v4/classic/from-json-schema.ts +248 -25
- package/node_modules/zod/src/v4/classic/schemas.ts +243 -168
- package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +60 -9
- package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +6 -0
- package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +2 -2
- package/node_modules/zod/src/v4/classic/tests/cyclic-data.test.ts +265 -0
- package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +112 -6
- package/node_modules/zod/src/v4/classic/tests/enum.test.ts +9 -0
- package/node_modules/zod/src/v4/classic/tests/error.test.ts +130 -1
- package/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +157 -0
- package/node_modules/zod/src/v4/classic/tests/iban.test.ts +81 -0
- package/node_modules/zod/src/v4/classic/tests/instance-footprint.test.ts +40 -2
- package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +27 -7
- package/node_modules/zod/src/v4/classic/tests/issue-schema.test.ts +88 -56
- package/node_modules/zod/src/v4/classic/tests/number.test.ts +39 -0
- package/node_modules/zod/src/v4/classic/tests/object.test.ts +56 -0
- package/node_modules/zod/src/v4/classic/tests/optin-ladder.test.ts +3 -2
- package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +70 -0
- package/node_modules/zod/src/v4/classic/tests/properties.test.ts +141 -0
- package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +46 -1
- package/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +19 -0
- package/node_modules/zod/src/v4/classic/tests/string.test.ts +95 -1
- package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +33 -1
- package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +234 -38
- package/node_modules/zod/src/v4/classic/tests/validate.test.ts +569 -0
- package/node_modules/zod/src/v4/core/api.ts +44 -28
- package/node_modules/zod/src/v4/core/checks.ts +62 -102
- package/node_modules/zod/src/v4/core/compile.ts +218 -93
- package/node_modules/zod/src/v4/core/core.ts +1 -3
- package/node_modules/zod/src/v4/core/doc.ts +6 -2
- package/node_modules/zod/src/v4/core/errors.ts +3 -6
- package/node_modules/zod/src/v4/core/json-schema-generator.ts +2 -2
- package/node_modules/zod/src/v4/core/json-schema-processors.ts +185 -81
- package/node_modules/zod/src/v4/core/memoizer.ts +75 -28
- package/node_modules/zod/src/v4/core/parse.ts +37 -16
- package/node_modules/zod/src/v4/core/regexes.ts +14 -4
- package/node_modules/zod/src/v4/core/schemas.ts +296 -132
- package/node_modules/zod/src/v4/core/tests/cached.test.ts +54 -0
- package/node_modules/zod/src/v4/core/tests/compile-differential.test.ts +35 -0
- package/node_modules/zod/src/v4/core/tests/compile-generative.test.ts +445 -0
- package/node_modules/zod/src/v4/core/tests/compile.test.ts +399 -2
- package/node_modules/zod/src/v4/core/tests/email-regex.test.ts +140 -0
- package/node_modules/zod/src/v4/core/tests/locales/tg.test.ts +85 -0
- package/node_modules/zod/src/v4/core/tests/polyfill-collision.test.ts +46 -0
- package/node_modules/zod/src/v4/core/tests/url-no-canparse.test.ts +118 -16
- package/node_modules/zod/src/v4/core/to-json-schema.ts +9 -7
- package/node_modules/zod/src/v4/core/util.ts +218 -147
- package/node_modules/zod/src/v4/core/versions.ts +2 -2
- package/node_modules/zod/src/v4/locales/ar.ts +2 -0
- package/node_modules/zod/src/v4/locales/az.ts +2 -0
- package/node_modules/zod/src/v4/locales/be.ts +2 -0
- package/node_modules/zod/src/v4/locales/bg.ts +2 -0
- package/node_modules/zod/src/v4/locales/bn.ts +2 -0
- package/node_modules/zod/src/v4/locales/ca.ts +2 -0
- package/node_modules/zod/src/v4/locales/ckb.ts +2 -0
- package/node_modules/zod/src/v4/locales/cs.ts +2 -0
- package/node_modules/zod/src/v4/locales/da.ts +2 -0
- package/node_modules/zod/src/v4/locales/de.ts +2 -0
- package/node_modules/zod/src/v4/locales/el.ts +2 -0
- package/node_modules/zod/src/v4/locales/en.ts +2 -0
- package/node_modules/zod/src/v4/locales/eo.ts +2 -0
- package/node_modules/zod/src/v4/locales/es.ts +2 -0
- package/node_modules/zod/src/v4/locales/fa.ts +2 -0
- package/node_modules/zod/src/v4/locales/fi.ts +2 -0
- package/node_modules/zod/src/v4/locales/fr-CA.ts +2 -0
- package/node_modules/zod/src/v4/locales/fr.ts +2 -0
- package/node_modules/zod/src/v4/locales/gu.ts +2 -0
- package/node_modules/zod/src/v4/locales/he.ts +2 -0
- package/node_modules/zod/src/v4/locales/hi.ts +2 -0
- package/node_modules/zod/src/v4/locales/hr.ts +2 -0
- package/node_modules/zod/src/v4/locales/hu.ts +2 -0
- package/node_modules/zod/src/v4/locales/hy.ts +2 -0
- package/node_modules/zod/src/v4/locales/id.ts +2 -0
- package/node_modules/zod/src/v4/locales/index.ts +1 -0
- package/node_modules/zod/src/v4/locales/is.ts +2 -0
- package/node_modules/zod/src/v4/locales/it.ts +2 -0
- package/node_modules/zod/src/v4/locales/ja.ts +2 -0
- package/node_modules/zod/src/v4/locales/ka.ts +2 -0
- package/node_modules/zod/src/v4/locales/km.ts +2 -0
- package/node_modules/zod/src/v4/locales/kn.ts +2 -0
- package/node_modules/zod/src/v4/locales/ko.ts +2 -0
- package/node_modules/zod/src/v4/locales/lt.ts +2 -0
- package/node_modules/zod/src/v4/locales/mk.ts +2 -0
- package/node_modules/zod/src/v4/locales/ms.ts +2 -0
- package/node_modules/zod/src/v4/locales/ne.ts +2 -0
- package/node_modules/zod/src/v4/locales/nl.ts +2 -0
- package/node_modules/zod/src/v4/locales/nn.ts +2 -0
- package/node_modules/zod/src/v4/locales/no.ts +2 -0
- package/node_modules/zod/src/v4/locales/ota.ts +2 -0
- package/node_modules/zod/src/v4/locales/pl.ts +2 -0
- package/node_modules/zod/src/v4/locales/ps.ts +2 -0
- package/node_modules/zod/src/v4/locales/pt-BR.ts +2 -0
- package/node_modules/zod/src/v4/locales/pt.ts +2 -0
- package/node_modules/zod/src/v4/locales/ro.ts +2 -0
- package/node_modules/zod/src/v4/locales/ru.ts +2 -0
- package/node_modules/zod/src/v4/locales/sk.ts +2 -0
- package/node_modules/zod/src/v4/locales/sl.ts +2 -0
- package/node_modules/zod/src/v4/locales/sv.ts +2 -0
- package/node_modules/zod/src/v4/locales/ta.ts +2 -0
- package/node_modules/zod/src/v4/locales/tg.ts +135 -0
- package/node_modules/zod/src/v4/locales/th.ts +2 -0
- package/node_modules/zod/src/v4/locales/tk.ts +2 -0
- package/node_modules/zod/src/v4/locales/tr.ts +2 -0
- package/node_modules/zod/src/v4/locales/uk.ts +2 -0
- package/node_modules/zod/src/v4/locales/ur.ts +2 -0
- package/node_modules/zod/src/v4/locales/uz.ts +2 -0
- package/node_modules/zod/src/v4/locales/vi.ts +2 -0
- package/node_modules/zod/src/v4/locales/yo.ts +2 -0
- package/node_modules/zod/src/v4/locales/zh-CN.ts +2 -0
- package/node_modules/zod/src/v4/locales/zh-TW.ts +2 -0
- package/node_modules/zod/src/v4/mini/external.ts +2 -0
- package/node_modules/zod/src/v4/mini/schemas.ts +32 -7
- package/node_modules/zod/src/v4/mini/tests/checks.test.ts +1 -1
- package/node_modules/zod/src/v4/mini/tests/computed.test.ts +11 -17
- package/node_modules/zod/src/v4/mini/tests/index.test.ts +86 -0
- package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +16 -0
- package/node_modules/zod/src/v4/mini/tests/string.test.ts +23 -0
- package/node_modules/zod/v3/ZodError.cjs +19 -0
- package/node_modules/zod/v3/errors.cjs +19 -0
- package/node_modules/zod/v3/external.cjs +19 -0
- package/node_modules/zod/v3/helpers/enumUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/errorUtil.cjs +20 -1
- package/node_modules/zod/v3/helpers/errorUtil.js +1 -1
- package/node_modules/zod/v3/helpers/parseUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/partialUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/typeAliases.cjs +19 -0
- package/node_modules/zod/v3/helpers/util.cjs +19 -0
- package/node_modules/zod/v3/index.cjs +19 -0
- package/node_modules/zod/v3/standard-schema.cjs +19 -0
- package/node_modules/zod/v3/types.cjs +19 -0
- package/node_modules/zod/v4/classic/checks.cjs +19 -0
- package/node_modules/zod/v4/classic/coerce.cjs +19 -0
- package/node_modules/zod/v4/classic/compat.cjs +19 -0
- package/node_modules/zod/v4/classic/deep-partial.cjs +19 -0
- package/node_modules/zod/v4/classic/errors.cjs +19 -0
- package/node_modules/zod/v4/classic/external.cjs +22 -1
- package/node_modules/zod/v4/classic/external.d.cts +1 -1
- package/node_modules/zod/v4/classic/external.d.ts +1 -1
- package/node_modules/zod/v4/classic/external.js +1 -1
- package/node_modules/zod/v4/classic/from-json-schema.cjs +264 -24
- package/node_modules/zod/v4/classic/from-json-schema.js +245 -24
- package/node_modules/zod/v4/classic/in-out.cjs +19 -0
- package/node_modules/zod/v4/classic/index.cjs +19 -0
- package/node_modules/zod/v4/classic/iso.cjs +19 -0
- package/node_modules/zod/v4/classic/parse.cjs +19 -0
- package/node_modules/zod/v4/classic/schemas.cjs +100 -35
- package/node_modules/zod/v4/classic/schemas.d.cts +15 -1
- package/node_modules/zod/v4/classic/schemas.d.ts +15 -1
- package/node_modules/zod/v4/classic/schemas.js +77 -33
- package/node_modules/zod/v4/core/api.cjs +45 -22
- package/node_modules/zod/v4/core/api.d.cts +12 -6
- package/node_modules/zod/v4/core/api.d.ts +12 -6
- package/node_modules/zod/v4/core/api.js +25 -22
- package/node_modules/zod/v4/core/checks.cjs +51 -97
- package/node_modules/zod/v4/core/checks.d.cts +17 -1
- package/node_modules/zod/v4/core/checks.d.ts +17 -1
- package/node_modules/zod/v4/core/checks.js +31 -96
- package/node_modules/zod/v4/core/compile.cjs +173 -78
- package/node_modules/zod/v4/core/compile.d.cts +18 -4
- package/node_modules/zod/v4/core/compile.d.ts +18 -4
- package/node_modules/zod/v4/core/compile.js +154 -79
- package/node_modules/zod/v4/core/core.cjs +20 -1
- package/node_modules/zod/v4/core/core.js +1 -1
- package/node_modules/zod/v4/core/doc.cjs +26 -2
- package/node_modules/zod/v4/core/doc.js +7 -2
- package/node_modules/zod/v4/core/errors.cjs +21 -5
- package/node_modules/zod/v4/core/errors.js +2 -5
- package/node_modules/zod/v4/core/index.cjs +19 -0
- package/node_modules/zod/v4/core/json-schema-generator.cjs +20 -1
- package/node_modules/zod/v4/core/json-schema-generator.js +2 -2
- package/node_modules/zod/v4/core/json-schema-processors.cjs +188 -72
- package/node_modules/zod/v4/core/json-schema-processors.d.cts +16 -0
- package/node_modules/zod/v4/core/json-schema-processors.d.ts +16 -0
- package/node_modules/zod/v4/core/json-schema-processors.js +170 -74
- package/node_modules/zod/v4/core/json-schema.cjs +19 -0
- package/node_modules/zod/v4/core/memoizer.cjs +111 -23
- package/node_modules/zod/v4/core/memoizer.js +69 -23
- package/node_modules/zod/v4/core/parse.cjs +56 -16
- package/node_modules/zod/v4/core/parse.js +37 -16
- package/node_modules/zod/v4/core/regexes.cjs +31 -6
- package/node_modules/zod/v4/core/regexes.d.cts +3 -0
- package/node_modules/zod/v4/core/regexes.d.ts +3 -0
- package/node_modules/zod/v4/core/regexes.js +10 -4
- package/node_modules/zod/v4/core/registries.cjs +19 -0
- package/node_modules/zod/v4/core/schemas.cjs +302 -114
- package/node_modules/zod/v4/core/schemas.d.cts +28 -8
- package/node_modules/zod/v4/core/schemas.d.ts +28 -8
- package/node_modules/zod/v4/core/schemas.js +279 -113
- package/node_modules/zod/v4/core/standard-schema.cjs +19 -0
- package/node_modules/zod/v4/core/to-json-schema.cjs +28 -7
- package/node_modules/zod/v4/core/to-json-schema.d.cts +4 -3
- package/node_modules/zod/v4/core/to-json-schema.d.ts +4 -3
- package/node_modules/zod/v4/core/to-json-schema.js +7 -6
- package/node_modules/zod/v4/core/util.cjs +177 -143
- package/node_modules/zod/v4/core/util.d.cts +25 -4
- package/node_modules/zod/v4/core/util.d.ts +25 -4
- package/node_modules/zod/v4/core/util.js +156 -143
- package/node_modules/zod/v4/core/versions.cjs +21 -2
- package/node_modules/zod/v4/core/versions.d.cts +1 -1
- package/node_modules/zod/v4/core/versions.d.ts +1 -1
- package/node_modules/zod/v4/core/versions.js +2 -2
- package/node_modules/zod/v4/core/visit.cjs +19 -0
- package/node_modules/zod/v4/index.cjs +19 -0
- package/node_modules/zod/v4/locales/ar.cjs +2 -0
- package/node_modules/zod/v4/locales/ar.js +2 -0
- package/node_modules/zod/v4/locales/az.cjs +2 -0
- package/node_modules/zod/v4/locales/az.js +2 -0
- package/node_modules/zod/v4/locales/be.cjs +2 -0
- package/node_modules/zod/v4/locales/be.js +2 -0
- package/node_modules/zod/v4/locales/bg.cjs +2 -0
- package/node_modules/zod/v4/locales/bg.js +2 -0
- package/node_modules/zod/v4/locales/bn.cjs +2 -0
- package/node_modules/zod/v4/locales/bn.js +2 -0
- package/node_modules/zod/v4/locales/ca.cjs +2 -0
- package/node_modules/zod/v4/locales/ca.js +2 -0
- package/node_modules/zod/v4/locales/ckb.cjs +2 -0
- package/node_modules/zod/v4/locales/ckb.js +2 -0
- package/node_modules/zod/v4/locales/cs.cjs +2 -0
- package/node_modules/zod/v4/locales/cs.js +2 -0
- package/node_modules/zod/v4/locales/da.cjs +2 -0
- package/node_modules/zod/v4/locales/da.js +2 -0
- package/node_modules/zod/v4/locales/de.cjs +2 -0
- package/node_modules/zod/v4/locales/de.js +2 -0
- package/node_modules/zod/v4/locales/el.cjs +2 -0
- package/node_modules/zod/v4/locales/el.js +2 -0
- package/node_modules/zod/v4/locales/en.cjs +2 -0
- package/node_modules/zod/v4/locales/en.js +2 -0
- package/node_modules/zod/v4/locales/eo.cjs +2 -0
- package/node_modules/zod/v4/locales/eo.js +2 -0
- package/node_modules/zod/v4/locales/es.cjs +2 -0
- package/node_modules/zod/v4/locales/es.js +2 -0
- package/node_modules/zod/v4/locales/fa.cjs +2 -0
- package/node_modules/zod/v4/locales/fa.js +2 -0
- package/node_modules/zod/v4/locales/fi.cjs +2 -0
- package/node_modules/zod/v4/locales/fi.js +2 -0
- package/node_modules/zod/v4/locales/fr-CA.cjs +2 -0
- package/node_modules/zod/v4/locales/fr-CA.js +2 -0
- package/node_modules/zod/v4/locales/fr.cjs +2 -0
- package/node_modules/zod/v4/locales/fr.js +2 -0
- package/node_modules/zod/v4/locales/gu.cjs +2 -0
- package/node_modules/zod/v4/locales/gu.js +2 -0
- package/node_modules/zod/v4/locales/he.cjs +2 -0
- package/node_modules/zod/v4/locales/he.js +2 -0
- package/node_modules/zod/v4/locales/hi.cjs +2 -0
- package/node_modules/zod/v4/locales/hi.js +2 -0
- package/node_modules/zod/v4/locales/hr.cjs +2 -0
- package/node_modules/zod/v4/locales/hr.js +2 -0
- package/node_modules/zod/v4/locales/hu.cjs +2 -0
- package/node_modules/zod/v4/locales/hu.js +2 -0
- package/node_modules/zod/v4/locales/hy.cjs +2 -0
- package/node_modules/zod/v4/locales/hy.js +2 -0
- package/node_modules/zod/v4/locales/id.cjs +2 -0
- package/node_modules/zod/v4/locales/id.js +2 -0
- package/node_modules/zod/v4/locales/index.cjs +22 -1
- package/node_modules/zod/v4/locales/index.d.cts +1 -0
- package/node_modules/zod/v4/locales/index.d.ts +1 -0
- package/node_modules/zod/v4/locales/index.js +1 -0
- package/node_modules/zod/v4/locales/is.cjs +2 -0
- package/node_modules/zod/v4/locales/is.js +2 -0
- package/node_modules/zod/v4/locales/it.cjs +2 -0
- package/node_modules/zod/v4/locales/it.js +2 -0
- package/node_modules/zod/v4/locales/ja.cjs +2 -0
- package/node_modules/zod/v4/locales/ja.js +2 -0
- package/node_modules/zod/v4/locales/ka.cjs +2 -0
- package/node_modules/zod/v4/locales/ka.js +2 -0
- package/node_modules/zod/v4/locales/km.cjs +2 -0
- package/node_modules/zod/v4/locales/km.js +2 -0
- package/node_modules/zod/v4/locales/kn.cjs +2 -0
- package/node_modules/zod/v4/locales/kn.js +2 -0
- package/node_modules/zod/v4/locales/ko.cjs +2 -0
- package/node_modules/zod/v4/locales/ko.js +2 -0
- package/node_modules/zod/v4/locales/lt.cjs +2 -0
- package/node_modules/zod/v4/locales/lt.js +2 -0
- package/node_modules/zod/v4/locales/mk.cjs +2 -0
- package/node_modules/zod/v4/locales/mk.js +2 -0
- package/node_modules/zod/v4/locales/ms.cjs +2 -0
- package/node_modules/zod/v4/locales/ms.js +2 -0
- package/node_modules/zod/v4/locales/ne.cjs +2 -0
- package/node_modules/zod/v4/locales/ne.js +2 -0
- package/node_modules/zod/v4/locales/nl.cjs +2 -0
- package/node_modules/zod/v4/locales/nl.js +2 -0
- package/node_modules/zod/v4/locales/nn.cjs +2 -0
- package/node_modules/zod/v4/locales/nn.js +2 -0
- package/node_modules/zod/v4/locales/no.cjs +2 -0
- package/node_modules/zod/v4/locales/no.js +2 -0
- package/node_modules/zod/v4/locales/ota.cjs +2 -0
- package/node_modules/zod/v4/locales/ota.js +2 -0
- package/node_modules/zod/v4/locales/pl.cjs +2 -0
- package/node_modules/zod/v4/locales/pl.js +2 -0
- package/node_modules/zod/v4/locales/ps.cjs +2 -0
- package/node_modules/zod/v4/locales/ps.js +2 -0
- package/node_modules/zod/v4/locales/pt-BR.cjs +2 -0
- package/node_modules/zod/v4/locales/pt-BR.js +2 -0
- package/node_modules/zod/v4/locales/pt.cjs +2 -0
- package/node_modules/zod/v4/locales/pt.js +2 -0
- package/node_modules/zod/v4/locales/ro.cjs +2 -0
- package/node_modules/zod/v4/locales/ro.js +2 -0
- package/node_modules/zod/v4/locales/ru.cjs +2 -0
- package/node_modules/zod/v4/locales/ru.js +2 -0
- package/node_modules/zod/v4/locales/sk.cjs +2 -0
- package/node_modules/zod/v4/locales/sk.js +2 -0
- package/node_modules/zod/v4/locales/sl.cjs +2 -0
- package/node_modules/zod/v4/locales/sl.js +2 -0
- package/node_modules/zod/v4/locales/sv.cjs +2 -0
- package/node_modules/zod/v4/locales/sv.js +2 -0
- package/node_modules/zod/v4/locales/ta.cjs +2 -0
- package/node_modules/zod/v4/locales/ta.js +2 -0
- package/node_modules/zod/v4/locales/tg.cjs +144 -0
- package/node_modules/zod/v4/locales/tg.d.cts +5 -0
- package/node_modules/zod/v4/locales/tg.d.ts +4 -0
- package/node_modules/zod/v4/locales/tg.js +117 -0
- package/node_modules/zod/v4/locales/th.cjs +2 -0
- package/node_modules/zod/v4/locales/th.js +2 -0
- package/node_modules/zod/v4/locales/tk.cjs +2 -0
- package/node_modules/zod/v4/locales/tk.js +2 -0
- package/node_modules/zod/v4/locales/tr.cjs +2 -0
- package/node_modules/zod/v4/locales/tr.js +2 -0
- package/node_modules/zod/v4/locales/uk.cjs +2 -0
- package/node_modules/zod/v4/locales/uk.js +2 -0
- package/node_modules/zod/v4/locales/ur.cjs +2 -0
- package/node_modules/zod/v4/locales/ur.js +2 -0
- package/node_modules/zod/v4/locales/uz.cjs +2 -0
- package/node_modules/zod/v4/locales/uz.js +2 -0
- package/node_modules/zod/v4/locales/vi.cjs +2 -0
- package/node_modules/zod/v4/locales/vi.js +2 -0
- package/node_modules/zod/v4/locales/yo.cjs +2 -0
- package/node_modules/zod/v4/locales/yo.js +2 -0
- package/node_modules/zod/v4/locales/zh-CN.cjs +2 -0
- package/node_modules/zod/v4/locales/zh-CN.js +2 -0
- package/node_modules/zod/v4/locales/zh-TW.cjs +2 -0
- package/node_modules/zod/v4/locales/zh-TW.js +2 -0
- package/node_modules/zod/v4/mini/checks.cjs +19 -0
- package/node_modules/zod/v4/mini/coerce.cjs +19 -0
- package/node_modules/zod/v4/mini/deep-partial.cjs +19 -0
- package/node_modules/zod/v4/mini/external.cjs +22 -1
- package/node_modules/zod/v4/mini/external.d.cts +1 -1
- package/node_modules/zod/v4/mini/external.d.ts +1 -1
- package/node_modules/zod/v4/mini/external.js +1 -1
- package/node_modules/zod/v4/mini/in-out.cjs +19 -0
- package/node_modules/zod/v4/mini/index.cjs +19 -0
- package/node_modules/zod/v4/mini/iso.cjs +19 -0
- package/node_modules/zod/v4/mini/parse.cjs +19 -0
- package/node_modules/zod/v4/mini/schemas.cjs +44 -8
- package/node_modules/zod/v4/mini/schemas.d.cts +6 -1
- package/node_modules/zod/v4/mini/schemas.d.ts +6 -1
- package/node_modules/zod/v4/mini/schemas.js +21 -6
- package/node_modules/zod/v4-mini/index.cjs +19 -0
- package/openclaw.plugin.json +21 -1
- package/package.json +9 -6
- package/dist/.setup/agent-components.runtime-CEPrf2SY.mjs +0 -4
- package/dist/.setup/message-handler.history-CJOsN9w5.mjs +0 -28
- package/dist/.setup/probe.runtime-DBQ_AGPe.mjs +0 -2
- package/dist/.setup/provider-session.runtime-BW7QrF5C.mjs +0 -6
- package/dist/.setup/provider.runtime-DuhmKdDU.mjs +0 -2
- package/dist/.setup/security-audit.runtime-DHtYenx9.mjs +0 -2
- package/dist/.setup/setup-plugin-api-CINIEBLa.mjs +0 -3
- package/dist/.setup/system-events-B2YEEMbS.mjs +0 -34
- package/dist/.setup/targets-D1mAB5yO.mjs +0 -3
- package/dist/.setup/thread-bindings.manager-eexkKyrG.mjs +0 -678
- package/dist/.setup/thread-bindings.session-updates-DCQq1WZ5.mjs +0 -55
- /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
package/dist/.setup/{realtime-session.runtime-DTccTgTM.mjs → realtime-session.runtime-oUd9DOcz.mjs}
RENAMED
|
@@ -1,16 +1,83 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as discordRealtimeVoiceSecretOwnerId } from "./secret-config-contract-
|
|
3
|
-
import {
|
|
1
|
+
import { _ as releaseDiscordAudioInput, g as getDiscordAudioOutputStatus, h as admitDiscordAudioInput, m as DiscordAudioOutputStatus, u as createDiscordPcmToRealtimeConverter, v as restoreDiscordAudioError, x as setDiscordAudioOutputStatus } from "./receive-recovery-CHPOsnLc.mjs";
|
|
2
|
+
import { n as discordRealtimeVoiceSecretOwnerId } from "./secret-config-contract-uOE2J7yM.mjs";
|
|
3
|
+
import { g as logVoiceVerbose } from "./provider-B_G5hASF.mjs";
|
|
4
|
+
import { a as logDiscordVoiceAgentControlResult, c as formatRealtimeLifecycleLog, i as handleDiscordVoiceAgentControlToolCall, l as formatVoiceLogPreview, n as DiscordRealtimeRecording, o as maybeControlDiscordVoiceAgentRun, r as formatVoiceIngressPrompt, s as formatRealtimeInterruptionLog, u as shouldLogRealtimeVerboseEvent } from "./voice-runtime-B46rcwrG.mjs";
|
|
4
5
|
import { randomUUID } from "node:crypto";
|
|
5
6
|
import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
6
7
|
import { formatErrorMessage } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
7
8
|
import { formatErrorMessage as formatErrorMessage$1, readErrorName, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
|
|
9
|
+
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
8
10
|
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
|
9
11
|
import { sliceUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
12
|
+
import { MessageChannel } from "node:worker_threads";
|
|
10
13
|
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
11
14
|
import { REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME, REALTIME_VOICE_AGENT_CONTROL_TOOL, REALTIME_VOICE_AGENT_CONTROL_TOOL_NAME, REALTIME_VOICE_AUDIO_FORMAT_PCM16_24KHZ, buildRealtimeVoiceAgentErrorProviderResult, buildRealtimeVoiceSessionInstructions, buildRealtimeVoiceSpeakExactMessage, canonicalizeRealtimeVoiceProviderId, classifyRealtimeVoiceConsultToolCall, classifySkippableRealtimeVoiceConsultTranscript, createRealtimeVoiceAgentTalkbackQueue, createRealtimeVoiceOutputActivityTracker, createRealtimeVoiceSessionHarness, isRealtimeVoiceAudioAudible, isRealtimeVoiceWakeNameRequired, matchRealtimeVoiceActivationName, matchRealtimeVoiceConsultQuestions, projectInternalRealtimeVoicePublicConfig, realtimeVoiceAudioDurationMs, registerRealtimeVoiceSelection, resolveConfiguredRealtimeVoiceProvider, resolveRealtimeVoiceAgentConsultTools, resolveRealtimeVoiceBargeIn, resolveRealtimeVoiceInterruptResponseOnInputAudio, resolveRealtimeVoiceMinBargeInAudioEndMs, resolveRealtimeVoiceSessionPolicy } from "openclaw/plugin-sdk/realtime-voice";
|
|
12
|
-
import { PassThrough, pipeline } from "node:stream";
|
|
13
15
|
import { assertSecretOwnerAvailable, isSecretOwnerAvailable } from "openclaw/plugin-sdk/channel-secret-owner-runtime";
|
|
16
|
+
//#region extensions/discord/src/voice/realtime-player.ts
|
|
17
|
+
/** Room-level policy stays on main; the worker owns the physical player and FIFO. */
|
|
18
|
+
var DiscordRealtimePlayer = class {
|
|
19
|
+
constructor(audio) {
|
|
20
|
+
this.audio = audio;
|
|
21
|
+
this.lanes = /* @__PURE__ */ new Set();
|
|
22
|
+
this.outputs = /* @__PURE__ */ new Map();
|
|
23
|
+
this.closed = false;
|
|
24
|
+
this.onEvent = (event) => {
|
|
25
|
+
if (event.type === "output-start" || event.type === "continuous-start") this.current = event.id;
|
|
26
|
+
if ((event.type === "output-close" || event.type === "continuous-idle") && this.current === event.id) this.current = void 0;
|
|
27
|
+
};
|
|
28
|
+
audio.on("event", this.onEvent);
|
|
29
|
+
}
|
|
30
|
+
registerLane(lane) {
|
|
31
|
+
this.lanes.add(lane);
|
|
32
|
+
return () => this.lanes.delete(lane);
|
|
33
|
+
}
|
|
34
|
+
registerOutput(id, onBargeIn) {
|
|
35
|
+
this.outputs.set(id, onBargeIn);
|
|
36
|
+
return () => {
|
|
37
|
+
this.outputs.delete(id);
|
|
38
|
+
if (this.current === id) this.current = void 0;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
handleBargeIn(reason = "barge-in") {
|
|
42
|
+
const current = this.current === void 0 ? void 0 : this.outputs.get(this.current);
|
|
43
|
+
if (current) return current(reason);
|
|
44
|
+
let interrupted = false;
|
|
45
|
+
for (const lane of [...this.lanes].filter((candidate) => candidate.hasOutput())) interrupted = lane.onBargeIn(reason) || interrupted;
|
|
46
|
+
return interrupted;
|
|
47
|
+
}
|
|
48
|
+
isActive() {
|
|
49
|
+
return this.current !== void 0 || [...this.lanes].some((lane) => lane.hasOutput());
|
|
50
|
+
}
|
|
51
|
+
cancelForControl() {
|
|
52
|
+
this.transition(() => {
|
|
53
|
+
for (const lane of this.lanes) lane.cancelForControl();
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
transition(action) {
|
|
57
|
+
this.audio.send({
|
|
58
|
+
type: "output-hold",
|
|
59
|
+
hold: true
|
|
60
|
+
});
|
|
61
|
+
try {
|
|
62
|
+
action();
|
|
63
|
+
} finally {
|
|
64
|
+
this.audio.send({
|
|
65
|
+
type: "output-hold",
|
|
66
|
+
hold: false
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
close() {
|
|
71
|
+
if (this.closed) return;
|
|
72
|
+
this.closed = true;
|
|
73
|
+
this.lanes.clear();
|
|
74
|
+
this.outputs.clear();
|
|
75
|
+
this.current = void 0;
|
|
76
|
+
this.audio.off("event", this.onEvent);
|
|
77
|
+
this.audio.send({ type: "output-shutdown" });
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
//#endregion
|
|
14
81
|
//#region extensions/discord/src/voice/realtime-transcript.ts
|
|
15
82
|
const PARTIAL_TRANSCRIPT_MAX_CHARS = 240;
|
|
16
83
|
function mergeRealtimePartialTranscript(previous, next) {
|
|
@@ -21,7 +88,7 @@ function mergeRealtimePartialTranscript(previous, next) {
|
|
|
21
88
|
}
|
|
22
89
|
//#endregion
|
|
23
90
|
//#region extensions/discord/src/voice/realtime-turns.ts
|
|
24
|
-
const logger$
|
|
91
|
+
const logger$4 = createSubsystemLogger("discord/voice");
|
|
25
92
|
const DISCORD_REALTIME_WAKE_NAME_FOLLOWUP_TTL_MS = 1e4;
|
|
26
93
|
const REALTIME_PCM16_BYTES_PER_SAMPLE = 2;
|
|
27
94
|
const DISCORD_REALTIME_TRAILING_SILENCE_MIN_MS = 700;
|
|
@@ -100,11 +167,11 @@ var DiscordRealtimeTurns = class {
|
|
|
100
167
|
const pendingWakeNameFollowup = this.consumePendingWakeNameFollowup();
|
|
101
168
|
if (!pendingWakeNameFollowup) {
|
|
102
169
|
this.consumePendingSpeakerContext();
|
|
103
|
-
logger$
|
|
170
|
+
logger$4.info(`discord voice: realtime wake-name gate ignored transcript chars=${trimmed.length} humanParticipants=${humanParticipantCount} voiceSession=${this.params.entry.voiceSessionKey} agent=${this.params.entry.route.agentId} wakeNames=${this.params.wakeNames().join(",") || "none"}`);
|
|
104
171
|
return;
|
|
105
172
|
}
|
|
106
173
|
forcedSpeakerContext = pendingWakeNameFollowup;
|
|
107
|
-
logger$
|
|
174
|
+
logger$4.info(`discord voice: realtime wake-name follow-up accepted chars=${trimmed.length} speaker=${forcedSpeakerContext.speakerLabel} voiceSession=${this.params.entry.voiceSessionKey} agent=${this.params.entry.route.agentId}`);
|
|
108
175
|
}
|
|
109
176
|
const acceptedText = wakeNameResult.allowed ? wakeNameResult.text || trimmed : trimmed;
|
|
110
177
|
if (wakeNameResult.allowed && !wakeNameResult.text.trim()) {
|
|
@@ -157,11 +224,11 @@ var DiscordRealtimeTurns = class {
|
|
|
157
224
|
this.registerSpeakerTurnAudioStarted(turn);
|
|
158
225
|
turn.inputRealtimeBytes += realtimePcm.length;
|
|
159
226
|
turn.inputChunks += 1;
|
|
160
|
-
if (turn.inputChunks === 1) logger$
|
|
227
|
+
if (turn.inputChunks === 1) logger$4.info(`discord voice: realtime input audio started guild=${this.params.entry.guildId} channel=${this.params.entry.channelId} user=${turn.context.userId} speaker=${turn.context.speakerLabel} discordBytes=${discordPcm48kStereo.length} realtimeBytes=${realtimePcm.length} outputAudioMs=${this.params.playback.outputAudioMs()} outputActive=${this.params.playback.isOutputAudioActive()}`);
|
|
161
228
|
if (!turn.interruptedPlayback && isRealtimeVoiceAudioAudible(discordPcm48kStereo, REALTIME_VOICE_AUDIO_FORMAT_PCM16_24KHZ) && isRealtimeVoiceAudioAudible(realtimePcm, REALTIME_VOICE_AUDIO_FORMAT_PCM16_24KHZ) && this.params.interruptRoomPlayback()) {
|
|
162
229
|
turn.interruptedPlayback = true;
|
|
163
230
|
logVoiceVerbose(`realtime barge-in from active speaker audio: guild ${this.params.entry.guildId} channel ${this.params.entry.channelId} user ${turn.context.userId}`);
|
|
164
|
-
logger$
|
|
231
|
+
logger$4.info(`discord voice: realtime barge-in detected source=active-speaker-audio guild=${this.params.entry.guildId} channel=${this.params.entry.channelId} user=${turn.context.userId} speaker=${turn.context.speakerLabel} discordBytes=${discordPcm48kStereo.length} realtimeBytes=${realtimePcm.length}`);
|
|
165
232
|
}
|
|
166
233
|
if (this.params.recordInputAudio(realtimePcm) && this.isTurnProviderCurrent(turn)) bridge.sendAudio(realtimePcm);
|
|
167
234
|
}
|
|
@@ -175,13 +242,13 @@ var DiscordRealtimeTurns = class {
|
|
|
175
242
|
turn.lastAudioAt = Date.now();
|
|
176
243
|
if (turn.hasAudio) return;
|
|
177
244
|
turn.hasAudio = true;
|
|
178
|
-
logger$
|
|
245
|
+
logger$4.info(`discord voice: realtime speaker turn opened guild=${this.params.entry.guildId} channel=${this.params.entry.channelId} user=${turn.context.userId} speaker=${turn.context.speakerLabel} owner=${turn.context.senderIsOwner}`);
|
|
179
246
|
}
|
|
180
247
|
logSpeakerTurnClosed(turn) {
|
|
181
248
|
if (turn.closed || !turn.hasAudio) return;
|
|
182
249
|
const elapsedMs = Date.now() - turn.startedAt;
|
|
183
250
|
const sinceLastAudioMs = turn.lastAudioAt ? Date.now() - turn.lastAudioAt : void 0;
|
|
184
|
-
logger$
|
|
251
|
+
logger$4.info(`discord voice: realtime speaker turn closed guild=${this.params.entry.guildId} channel=${this.params.entry.channelId} user=${turn.context.userId} speaker=${turn.context.speakerLabel} owner=${turn.context.senderIsOwner} hasAudio=${turn.hasAudio} chunks=${turn.inputChunks} discordBytes=${turn.inputDiscordBytes} realtimeBytes=${turn.inputRealtimeBytes} elapsedMs=${elapsedMs}${sinceLastAudioMs === void 0 ? "" : ` sinceLastAudioMs=${sinceLastAudioMs}`} interruptedPlayback=${turn.interruptedPlayback}`);
|
|
185
252
|
}
|
|
186
253
|
sendRealtimeTrailingSilenceForTurn(turn) {
|
|
187
254
|
const bridge = turn.bridge;
|
|
@@ -192,7 +259,7 @@ var DiscordRealtimeTurns = class {
|
|
|
192
259
|
const silenceBytes = Math.ceil(24e3 * silenceMs / 1e3) * REALTIME_PCM16_BYTES_PER_SAMPLE;
|
|
193
260
|
const silence = Buffer.alloc(silenceBytes);
|
|
194
261
|
bridge.sendAudio(silence);
|
|
195
|
-
logger$
|
|
262
|
+
logger$4.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}`);
|
|
196
263
|
}
|
|
197
264
|
resolveWakeNameTranscript(text, requireWakeName) {
|
|
198
265
|
if (!requireWakeName) return {
|
|
@@ -205,7 +272,7 @@ var DiscordRealtimeTurns = class {
|
|
|
205
272
|
};
|
|
206
273
|
const wakeNameResult = matchRealtimeVoiceActivationName(text, this.params.wakeNames());
|
|
207
274
|
if (wakeNameResult) {
|
|
208
|
-
logger$
|
|
275
|
+
logger$4.info(`discord voice: realtime wake-name gate matched canonical=${wakeNameResult.activationName} heard=${wakeNameResult.heardName} match=${wakeNameResult.match} voiceSession=${this.params.entry.voiceSessionKey} agent=${this.params.entry.route.agentId}`);
|
|
209
276
|
return wakeNameResult;
|
|
210
277
|
}
|
|
211
278
|
return {
|
|
@@ -219,7 +286,7 @@ var DiscordRealtimeTurns = class {
|
|
|
219
286
|
armWakeNameFollowup() {
|
|
220
287
|
const context = this.consumePendingSpeakerContext();
|
|
221
288
|
if (!context) {
|
|
222
|
-
logger$
|
|
289
|
+
logger$4.warn(`discord voice: realtime wake-name follow-up has no speaker context voiceSession=${this.params.entry.voiceSessionKey} agent=${this.params.entry.route.agentId}`);
|
|
223
290
|
return;
|
|
224
291
|
}
|
|
225
292
|
const expiresAt = resolveExpiresAtMsFromDurationMs(DISCORD_REALTIME_WAKE_NAME_FOLLOWUP_TTL_MS);
|
|
@@ -228,7 +295,7 @@ var DiscordRealtimeTurns = class {
|
|
|
228
295
|
context,
|
|
229
296
|
expiresAt
|
|
230
297
|
};
|
|
231
|
-
logger$
|
|
298
|
+
logger$4.info(`discord voice: realtime wake-name follow-up armed speaker=${context.speakerLabel} voiceSession=${this.params.entry.voiceSessionKey} agent=${this.params.entry.route.agentId}`);
|
|
232
299
|
}
|
|
233
300
|
consumePendingWakeNameFollowup() {
|
|
234
301
|
const pending = this.pendingWakeNameFollowup;
|
|
@@ -245,7 +312,7 @@ function isDiscordRealtimeSpeakerContext(value) {
|
|
|
245
312
|
}
|
|
246
313
|
//#endregion
|
|
247
314
|
//#region extensions/discord/src/voice/realtime-consults.ts
|
|
248
|
-
const logger$
|
|
315
|
+
const logger$3 = createSubsystemLogger("discord/voice");
|
|
249
316
|
const DISCORD_REALTIME_TALKBACK_DEBOUNCE_MS = 350;
|
|
250
317
|
const DISCORD_REALTIME_FALLBACK_TEXT = "I hit an error while checking that. Please try again.";
|
|
251
318
|
const DISCORD_REALTIME_FORCED_CONSULT_FALLBACK_DELAY_MS = 200;
|
|
@@ -318,16 +385,16 @@ var DiscordRealtimeConsults = class {
|
|
|
318
385
|
const outcome = classifyRealtimeVoiceConsultToolCall(event.args, { retainedExactSpeechTexts: this.params.playback.retainedExactSpeechTexts() });
|
|
319
386
|
switch (outcome.kind) {
|
|
320
387
|
case "exact-speech-echo":
|
|
321
|
-
logger$
|
|
388
|
+
logger$3.info(`discord voice: realtime exact speech consult bypassed call=${callId} answerChars=${outcome.text.length}`);
|
|
322
389
|
await session.submitToolResult(callId, { text: outcome.text });
|
|
323
390
|
return;
|
|
324
391
|
case "malformed":
|
|
325
|
-
logger$
|
|
392
|
+
logger$3.warn(`discord voice: realtime consult rejected malformed args call=${callId}: ${outcome.error}`);
|
|
326
393
|
await session.submitToolResult(callId, { error: outcome.error });
|
|
327
394
|
return;
|
|
328
395
|
}
|
|
329
396
|
const consultMessage = outcome.message;
|
|
330
|
-
logger$
|
|
397
|
+
logger$3.info(`discord voice: realtime consult requested call=${callId} voiceSession=${this.params.entry.voiceSessionKey} supervisorSession=${this.params.entry.route.sessionKey} agent=${this.params.entry.route.agentId} question=${formatVoiceLogPreview(consultMessage)}`);
|
|
331
398
|
const nativeConsult = this.params.harness.forcedConsults.recordNativeConsult(event.args, callId);
|
|
332
399
|
if (nativeConsult.kind === "already_delivered" && this.params.harness.forcedConsults.isCancelled(nativeConsult.handle)) {
|
|
333
400
|
await this.submitTerminalRealtimeToolResult(callId, session, CANCELLED_CONSULT_RESULT);
|
|
@@ -342,7 +409,7 @@ var DiscordRealtimeConsults = class {
|
|
|
342
409
|
if (recentConsult) {
|
|
343
410
|
const recentSpeaker = recentConsult.context?.speaker;
|
|
344
411
|
if (this.params.turns.hasPendingSpeakerAudioContext()) {
|
|
345
|
-
logger$
|
|
412
|
+
logger$3.info(`discord voice: realtime consult matched recent agent result but newer speaker audio is pending call=${callId} speaker=${recentSpeaker?.speakerLabel ?? "unknown"} owner=${recentSpeaker?.senderIsOwner ?? false}`);
|
|
346
413
|
await session.submitToolResult(callId, { error: "Discord speaker context changed before this realtime consult completed" });
|
|
347
414
|
return;
|
|
348
415
|
}
|
|
@@ -351,14 +418,22 @@ var DiscordRealtimeConsults = class {
|
|
|
351
418
|
}
|
|
352
419
|
if (!context) {
|
|
353
420
|
context = this.params.turns.consumePendingSpeakerContext();
|
|
354
|
-
if (context)
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
421
|
+
if (context) {
|
|
422
|
+
recent = this.params.harness.forcedConsults.prepare(consultMessage, {
|
|
423
|
+
context: {
|
|
424
|
+
speaker: context,
|
|
425
|
+
providerEpoch: this.params.providerEpoch(),
|
|
426
|
+
delivery: "provider"
|
|
427
|
+
},
|
|
428
|
+
...callId === "unknown" ? {} : { id: `native-consult:${callId}` }
|
|
429
|
+
});
|
|
430
|
+
if (!recent) throw new Error("Discord realtime consult context requires a non-empty question");
|
|
431
|
+
this.params.harness.forcedConsults.markStarted(recent);
|
|
432
|
+
}
|
|
358
433
|
}
|
|
359
434
|
const state = recent?.context;
|
|
360
435
|
if (!context || !state) {
|
|
361
|
-
logger$
|
|
436
|
+
logger$3.warn(`discord voice: realtime consult has no speaker context call=${callId}`);
|
|
362
437
|
await session.submitToolResult(callId, { error: "No Discord speaker context available" });
|
|
363
438
|
return;
|
|
364
439
|
}
|
|
@@ -371,8 +446,8 @@ var DiscordRealtimeConsults = class {
|
|
|
371
446
|
deliveryOwner: "consult"
|
|
372
447
|
}));
|
|
373
448
|
if (this.params.stopped() || providerEpoch !== this.params.providerEpoch()) return;
|
|
374
|
-
if ("text" in result) logger$
|
|
375
|
-
else if ("error" in result) logger$
|
|
449
|
+
if ("text" in result) logger$3.info(`discord voice: realtime consult answer (${result.text.length} chars) voiceSession=${this.params.entry.voiceSessionKey} supervisorSession=${this.params.entry.route.sessionKey} agent=${this.params.entry.route.agentId} speaker=${context.speakerLabel} owner=${context.senderIsOwner}: ${formatVoiceLogPreview(result.text)}`);
|
|
450
|
+
else if ("error" in result) logger$3.warn(`discord voice: realtime consult failed call=${callId}: ${result.error}`);
|
|
376
451
|
delivery.submissionStarted = true;
|
|
377
452
|
await this.submitAgentProxyConsultResult(callId, session, result);
|
|
378
453
|
if (state.delivery === "provider-pending") state.delivery = "provider";
|
|
@@ -394,10 +469,10 @@ var DiscordRealtimeConsults = class {
|
|
|
394
469
|
if (this.params.stopped() || providerEpoch !== this.params.providerEpoch()) return;
|
|
395
470
|
if (readErrorName(error) === "AbortError") {
|
|
396
471
|
if (pendingForcedConsult) this.params.harness.forcedConsults.remove(pendingForcedConsult);
|
|
397
|
-
logger$
|
|
472
|
+
logger$3.warn(`discord voice: realtime transcript cancelled: ${formatErrorMessage$1(error)}`);
|
|
398
473
|
return;
|
|
399
474
|
}
|
|
400
|
-
logger$
|
|
475
|
+
logger$3.warn(`discord voice: realtime active-run control failed; falling back to normal transcript handling: ${formatErrorMessage$1(error)}`);
|
|
401
476
|
control = void 0;
|
|
402
477
|
}
|
|
403
478
|
if (this.params.stopped() || providerEpoch !== this.params.providerEpoch()) return;
|
|
@@ -409,7 +484,7 @@ var DiscordRealtimeConsults = class {
|
|
|
409
484
|
}
|
|
410
485
|
if (!this.params.isAgentProxy()) return;
|
|
411
486
|
if (usesRealtimeAgentHandoff) {
|
|
412
|
-
if (pendingForcedConsult) this.
|
|
487
|
+
if (pendingForcedConsult) this.params.harness.forcedConsults.schedule(pendingForcedConsult, DISCORD_REALTIME_FORCED_CONSULT_FALLBACK_DELAY_MS, (handle) => void this.runForcedAgentProxyConsult(handle));
|
|
413
488
|
return;
|
|
414
489
|
}
|
|
415
490
|
this.talkback.enqueue(acceptedText, fallbackSpeakerContext);
|
|
@@ -419,7 +494,7 @@ var DiscordRealtimeConsults = class {
|
|
|
419
494
|
return createRealtimeVoiceAgentTalkbackQueue({
|
|
420
495
|
debounceMs: this.params.debounceMs() ?? DISCORD_REALTIME_TALKBACK_DEBOUNCE_MS,
|
|
421
496
|
isStopped: () => this.params.stopped() || providerEpoch !== this.params.providerEpoch(),
|
|
422
|
-
logger: logger$
|
|
497
|
+
logger: logger$3,
|
|
423
498
|
logPrefix: "[discord] realtime agent",
|
|
424
499
|
responseStyle: "Brief, natural spoken answer for a Discord voice channel.",
|
|
425
500
|
fallbackText: DISCORD_REALTIME_FALLBACK_TEXT,
|
|
@@ -468,7 +543,7 @@ var DiscordRealtimeConsults = class {
|
|
|
468
543
|
const skipReason = classifySkippableRealtimeVoiceConsultTranscript(question);
|
|
469
544
|
if (skipReason) {
|
|
470
545
|
const context = this.params.turns.consumePendingSpeakerContext();
|
|
471
|
-
logger$
|
|
546
|
+
logger$3.info(`discord voice: realtime forced agent consult skipped reason=${skipReason} chars=${question.length} speaker=${context?.speakerLabel ?? "unknown"} transcript=${formatVoiceLogPreview(question)}`);
|
|
472
547
|
return;
|
|
473
548
|
}
|
|
474
549
|
const context = speakerContext ?? this.params.turns.consumePendingSpeakerContext();
|
|
@@ -478,7 +553,7 @@ var DiscordRealtimeConsults = class {
|
|
|
478
553
|
logVoiceVerbose(`realtime forced agent consult skipped (already delegated): guild ${this.params.entry.guildId} channel ${this.params.entry.channelId} speaker ${recent.context?.speaker.userId ?? "unknown"}`);
|
|
479
554
|
return;
|
|
480
555
|
}
|
|
481
|
-
logger$
|
|
556
|
+
logger$3.warn("discord voice: realtime forced agent consult has no speaker context");
|
|
482
557
|
return;
|
|
483
558
|
}
|
|
484
559
|
return this.params.harness.forcedConsults.prepare(question, { context: {
|
|
@@ -487,9 +562,6 @@ var DiscordRealtimeConsults = class {
|
|
|
487
562
|
delivery: "provider"
|
|
488
563
|
} });
|
|
489
564
|
}
|
|
490
|
-
schedulePreparedForcedAgentProxyConsult(pending) {
|
|
491
|
-
this.params.harness.forcedConsults.schedule(pending, DISCORD_REALTIME_FORCED_CONSULT_FALLBACK_DELAY_MS, (handle) => void this.runForcedAgentProxyConsult(handle));
|
|
492
|
-
}
|
|
493
565
|
async runForcedAgentProxyConsult(pending) {
|
|
494
566
|
this.params.harness.forcedConsults.markStarted(pending);
|
|
495
567
|
const state = pending.context;
|
|
@@ -504,9 +576,9 @@ var DiscordRealtimeConsults = class {
|
|
|
504
576
|
return;
|
|
505
577
|
}
|
|
506
578
|
const startedAt = Date.now();
|
|
507
|
-
logger$
|
|
508
|
-
logger$
|
|
509
|
-
if (this.params.playback.hasInterruptibleOutputAudio()) logger$
|
|
579
|
+
logger$3.info(`discord voice: realtime forced agent consult starting chars=${question.length} voiceSession=${this.params.entry.voiceSessionKey} supervisorSession=${this.params.entry.route.sessionKey} agent=${this.params.entry.route.agentId} speaker=${context.speakerLabel} owner=${context.senderIsOwner}`);
|
|
580
|
+
logger$3.debug(`discord voice: realtime forced agent consult reason=${DISCORD_REALTIME_FORCED_CONSULT_REASON} consultPolicy=${this.params.consultPolicy()} wakeNamePolicy=${this.params.wakeNamePolicy()} requireWakeName=${this.params.isWakeNameRequired()} voiceSession=${this.params.entry.voiceSessionKey} supervisorSession=${this.params.entry.route.sessionKey} agent=${this.params.entry.route.agentId} speaker=${context.speakerLabel}`);
|
|
581
|
+
if (this.params.playback.hasInterruptibleOutputAudio()) logger$3.info(`discord voice: realtime forced agent consult preserving active playback guild=${this.params.entry.guildId} channel=${this.params.entry.channelId} outputAudioMs=${this.params.playback.outputAudioMs()} outputActive=${this.params.playback.isOutputAudioActive()} playbackChunks=${this.params.harness.outputActivity.snapshot().chunks}`);
|
|
510
582
|
state.delivery = "forced-pending";
|
|
511
583
|
const result = await this.trackAgentProxyConsult(pending, this.runAgentTurn({
|
|
512
584
|
context,
|
|
@@ -516,27 +588,14 @@ var DiscordRealtimeConsults = class {
|
|
|
516
588
|
const deliveries = this.providerDeliveries.get(state);
|
|
517
589
|
await Promise.all(Array.from(deliveries ?? [], (delivery) => delivery.promise));
|
|
518
590
|
if (state.providerEpoch !== this.params.providerEpoch() || "status" in result) return;
|
|
519
|
-
if ("text" in result) logger$
|
|
520
|
-
else logger$
|
|
591
|
+
if ("text" in result) logger$3.info(`discord voice: realtime forced agent consult answer (${result.text.length} chars) elapsedMs=${Date.now() - startedAt} voiceSession=${this.params.entry.voiceSessionKey} supervisorSession=${this.params.entry.route.sessionKey} agent=${this.params.entry.route.agentId}: ${formatVoiceLogPreview(result.text)}`);
|
|
592
|
+
else logger$3.warn(`discord voice: realtime forced agent consult failed elapsedMs=${Date.now() - startedAt}: ${result.error}`);
|
|
521
593
|
const text = "text" in result ? result.text : DISCORD_REALTIME_FALLBACK_TEXT;
|
|
522
594
|
if (text.trim() && state.delivery === "forced-pending") {
|
|
523
595
|
state.delivery = "playback";
|
|
524
596
|
this.params.playback.enqueueExactSpeechMessage(text);
|
|
525
597
|
}
|
|
526
598
|
}
|
|
527
|
-
rememberRecentAgentProxyConsultContext(question, context, options = {}) {
|
|
528
|
-
const handle = this.params.harness.forcedConsults.prepare(question, {
|
|
529
|
-
context: {
|
|
530
|
-
speaker: context,
|
|
531
|
-
providerEpoch: this.params.providerEpoch(),
|
|
532
|
-
delivery: "provider"
|
|
533
|
-
},
|
|
534
|
-
...options.id ? { id: options.id } : {}
|
|
535
|
-
});
|
|
536
|
-
if (!handle) throw new Error("Discord realtime consult context requires a non-empty question");
|
|
537
|
-
if (options.started) this.params.harness.forcedConsults.markStarted(handle);
|
|
538
|
-
return handle;
|
|
539
|
-
}
|
|
540
599
|
trackAgentProxyConsult(recent, promise) {
|
|
541
600
|
const state = recent?.context;
|
|
542
601
|
if (recent) this.params.harness.forcedConsults.markStarted(recent);
|
|
@@ -569,7 +628,7 @@ var DiscordRealtimeConsults = class {
|
|
|
569
628
|
const pendingResult = state.result ?? state.promise;
|
|
570
629
|
if (!pendingResult) return false;
|
|
571
630
|
const providerDelivery = state.delivery === "provider-pending" || state.delivery === "forced-pending" && !state.result && session.bridge.supportsToolResultSuppression === false ? this.beginProviderDelivery(state) : void 0;
|
|
572
|
-
logger$
|
|
631
|
+
logger$3.info(`discord voice: realtime consult ${state.result ? "reused recent" : "joined in-flight"} agent result call=${callId} speaker=${state.speaker.speakerLabel} owner=${state.speaker.senderIsOwner}`);
|
|
573
632
|
try {
|
|
574
633
|
const result = await pendingResult;
|
|
575
634
|
if (this.params.stopped() || state.providerEpoch !== this.params.providerEpoch() || state.delivery === "detached" || state.delivery === "retired") return true;
|
|
@@ -629,286 +688,156 @@ var DiscordRealtimeConsults = class {
|
|
|
629
688
|
};
|
|
630
689
|
//#endregion
|
|
631
690
|
//#region extensions/discord/src/voice/realtime-output.ts
|
|
632
|
-
|
|
633
|
-
const DISCORD_RAW_PCM_FRAME_BYTES = 3840;
|
|
634
|
-
const DISCORD_RAW_PCM_BYTES_PER_MS = 192;
|
|
635
|
-
const DISCORD_REALTIME_OUTPUT_PREROLL_FRAMES = 25;
|
|
636
|
-
const DISCORD_CONTINUOUS_PREROLL_FRAMES = 6;
|
|
637
|
-
const DISCORD_CONTINUOUS_START_DEADLINE_MS = 120;
|
|
638
|
-
const DISCORD_REALTIME_OUTPUT_PLAYBACK_WATCHDOG_MARGIN_MS = 3e3;
|
|
639
|
-
/** One output stream retains ownership through queued and audible playback. */
|
|
691
|
+
/** Main retains provider item identity; physical output state belongs to the worker. */
|
|
640
692
|
var DiscordRealtimeOutput = class {
|
|
693
|
+
get activity() {
|
|
694
|
+
if (Atomics.load(this.clock, 2) !== 0n && !this.activityTracker.snapshot().playbackStarted) this.activityTracker.markPlaybackStarted();
|
|
695
|
+
return this.activityTracker;
|
|
696
|
+
}
|
|
641
697
|
constructor(params) {
|
|
642
698
|
this.params = params;
|
|
643
|
-
this.
|
|
644
|
-
this.
|
|
645
|
-
this.
|
|
646
|
-
this.
|
|
647
|
-
this.playbackMarks = [];
|
|
648
|
-
this.playedPcmBytes = 0;
|
|
649
|
-
this.lastAudiblePcmEndBytes = 0;
|
|
650
|
-
this.reportedPlaybackMs = 0;
|
|
651
|
-
this.audioSpans = [];
|
|
652
|
-
this.buffers = [];
|
|
653
|
-
this.bufferedBytes = 0;
|
|
699
|
+
this.activityTracker = createRealtimeVoiceOutputActivityTracker();
|
|
700
|
+
this.clock = new BigInt64Array(new SharedArrayBuffer(24));
|
|
701
|
+
this.marks = /* @__PURE__ */ new Map();
|
|
702
|
+
this.nextMark = 0;
|
|
654
703
|
this.closed = false;
|
|
655
|
-
this.
|
|
656
|
-
this.
|
|
657
|
-
|
|
704
|
+
this.reportedPlaybackMs = 0;
|
|
705
|
+
this.spans = [];
|
|
706
|
+
this.onEvent = (event) => {
|
|
707
|
+
if (!("id" in event) || event.id !== this.id || this.closed) return;
|
|
708
|
+
switch (event.type) {
|
|
709
|
+
case "output-start":
|
|
710
|
+
this.activity.markPlaybackStarted();
|
|
711
|
+
this.params.onStart();
|
|
712
|
+
break;
|
|
713
|
+
case "output-close":
|
|
714
|
+
this.retire(event.reason);
|
|
715
|
+
break;
|
|
716
|
+
case "output-error":
|
|
717
|
+
this.params.onError(restoreDiscordAudioError(event.error));
|
|
718
|
+
break;
|
|
719
|
+
case "output-mark": {
|
|
720
|
+
const acknowledge = this.marks.get(event.markId);
|
|
721
|
+
this.marks.delete(event.markId);
|
|
722
|
+
try {
|
|
723
|
+
acknowledge?.();
|
|
724
|
+
} catch (error) {
|
|
725
|
+
this.params.onError(error);
|
|
726
|
+
}
|
|
727
|
+
break;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
this.onStopped = () => {
|
|
732
|
+
if (!this.closed) {
|
|
733
|
+
this.params.onError(/* @__PURE__ */ new Error("Discord audio worker stopped during playback."));
|
|
734
|
+
this.retire("worker-stopped");
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
this.id = params.player.audio.allocateId();
|
|
738
|
+
this.unregister = params.player.registerOutput(this.id, params.onBargeIn);
|
|
739
|
+
params.player.audio.on("event", this.onEvent);
|
|
740
|
+
params.player.audio.on("stopped", this.onStopped);
|
|
741
|
+
params.player.audio.send({
|
|
742
|
+
type: "output-create",
|
|
743
|
+
id: this.id,
|
|
744
|
+
continuous: params.continuous,
|
|
745
|
+
clock: this.clock.buffer
|
|
658
746
|
});
|
|
659
747
|
}
|
|
748
|
+
playedBytes() {
|
|
749
|
+
return Number(Atomics.load(this.clock, 0));
|
|
750
|
+
}
|
|
660
751
|
pendingBytes() {
|
|
661
|
-
return this.closed ? 0 : Math.max(0, this.activity.snapshot().sourceAudioBytes * 4 - this.
|
|
752
|
+
return this.closed ? 0 : Math.max(0, this.activity.snapshot().sourceAudioBytes * 4 - this.playedBytes());
|
|
662
753
|
}
|
|
663
754
|
isAcceptingAudio() {
|
|
664
|
-
return !this.closed && !this.activity.snapshot().streamEnding && (
|
|
665
|
-
}
|
|
666
|
-
hasUnplayedAudibleAudio() {
|
|
667
|
-
return !this.closed && this.playedPcmBytes < this.lastAudiblePcmEndBytes;
|
|
755
|
+
return !this.closed && !this.activity.snapshot().streamEnding && getDiscordAudioOutputStatus(this.clock) < DiscordAudioOutputStatus.Retiring;
|
|
668
756
|
}
|
|
669
757
|
playbackItems() {
|
|
670
|
-
const playedMs = Math.min(this.
|
|
671
|
-
for (const span of this.
|
|
758
|
+
const playedMs = Math.min(this.playedBytes() / 192, this.activity.snapshot().audioMs);
|
|
759
|
+
for (const span of this.spans) span.item.audioEndMs += Math.max(0, Math.min(playedMs, span.endMs) - Math.max(this.reportedPlaybackMs, span.startMs));
|
|
672
760
|
this.reportedPlaybackMs = playedMs;
|
|
673
|
-
return this.
|
|
761
|
+
return this.spans.filter(({ endMs }) => endMs > playedMs).map(({ item }) => item);
|
|
674
762
|
}
|
|
675
763
|
markPlayback(acknowledge) {
|
|
676
|
-
if (
|
|
677
|
-
|
|
678
|
-
|
|
764
|
+
if (this.closed) return;
|
|
765
|
+
const markId = ++this.nextMark;
|
|
766
|
+
this.marks.set(markId, acknowledge);
|
|
767
|
+
this.params.player.audio.send({
|
|
768
|
+
type: "output-mark",
|
|
769
|
+
id: this.id,
|
|
770
|
+
markId
|
|
679
771
|
});
|
|
680
772
|
}
|
|
681
|
-
append(
|
|
682
|
-
if (this.closed) return;
|
|
773
|
+
append(audio, audible, item, onAccepted) {
|
|
774
|
+
if (this.closed || this.activity.snapshot().streamEnding || !admitDiscordAudioInput(this.clock)) return false;
|
|
775
|
+
try {
|
|
776
|
+
onAccepted();
|
|
777
|
+
} catch (error) {
|
|
778
|
+
releaseDiscordAudioInput(this.clock);
|
|
779
|
+
throw error;
|
|
780
|
+
}
|
|
781
|
+
if (this.closed) {
|
|
782
|
+
releaseDiscordAudioInput(this.clock);
|
|
783
|
+
return true;
|
|
784
|
+
}
|
|
683
785
|
const previous = this.activity.snapshot();
|
|
684
|
-
const sinkBytes = Math.floor((previous.sourceAudioBytes +
|
|
685
|
-
const audioMs = (sinkBytes - previous.sinkAudioBytes) /
|
|
686
|
-
const startMs = previous.audioMs;
|
|
786
|
+
const sinkBytes = Math.floor((previous.sourceAudioBytes + audio.length) / 2) * 8;
|
|
787
|
+
const audioMs = (sinkBytes - previous.sinkAudioBytes) / 192;
|
|
687
788
|
if (item) {
|
|
688
|
-
const
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
else this.audioSpans.push({
|
|
789
|
+
const last = this.spans.at(-1);
|
|
790
|
+
if (last?.item === item && last.endMs === previous.audioMs) last.endMs += audioMs;
|
|
791
|
+
else this.spans.push({
|
|
692
792
|
item,
|
|
693
|
-
startMs,
|
|
694
|
-
endMs
|
|
793
|
+
startMs: previous.audioMs,
|
|
794
|
+
endMs: previous.audioMs + audioMs
|
|
695
795
|
});
|
|
696
796
|
}
|
|
697
797
|
this.activity.markAudio({
|
|
698
798
|
audioMs,
|
|
699
|
-
sourceAudioBytes:
|
|
799
|
+
sourceAudioBytes: audio.length,
|
|
700
800
|
sinkAudioBytes: sinkBytes - previous.sinkAudioBytes
|
|
701
801
|
});
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
this.
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
if (this.params.continuous) this.enqueuePlayback();
|
|
710
|
-
const prerollFrames = this.params.continuous ? DISCORD_CONTINUOUS_PREROLL_FRAMES : DISCORD_REALTIME_OUTPUT_PREROLL_FRAMES;
|
|
711
|
-
if (this.activity.snapshot().sinkAudioBytes >= DISCORD_RAW_PCM_FRAME_BYTES * prerollFrames) this.startPlayback();
|
|
712
|
-
else if (this.params.continuous && !this.ready && !this.startupTimer) {
|
|
713
|
-
this.startupTimer = setTimeout(() => {
|
|
714
|
-
this.startupTimer = void 0;
|
|
715
|
-
this.startPlayback();
|
|
716
|
-
}, DISCORD_CONTINUOUS_START_DEADLINE_MS);
|
|
717
|
-
this.startupTimer.unref?.();
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
writeConverted(pcm) {
|
|
721
|
-
if (pcm.length === 0 || this.closed) return;
|
|
722
|
-
if (this.activity.snapshot().playbackStarted && !this.drainHandler) {
|
|
723
|
-
if (!this.stream.write(pcm)) this.waitForDrain();
|
|
724
|
-
return;
|
|
725
|
-
}
|
|
726
|
-
this.buffers.push(pcm);
|
|
727
|
-
this.bufferedBytes += pcm.length;
|
|
802
|
+
this.params.player.audio.send({
|
|
803
|
+
type: "output-audio",
|
|
804
|
+
id: this.id,
|
|
805
|
+
audio,
|
|
806
|
+
audible
|
|
807
|
+
});
|
|
808
|
+
return true;
|
|
728
809
|
}
|
|
729
810
|
finish(reason, playBuffered) {
|
|
730
811
|
if (this.closed) return;
|
|
731
|
-
this.clearSilenceTimer();
|
|
732
|
-
if (playBuffered) this.writeConverted(this.converter.flush());
|
|
733
812
|
this.activity.markStreamEnding();
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
this.
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
if (this.
|
|
742
|
-
this.scheduleWatchdog(reason);
|
|
743
|
-
if (!this.drainHandler) this.stream.end();
|
|
744
|
-
}
|
|
813
|
+
if (!playBuffered) setDiscordAudioOutputStatus(this.clock, DiscordAudioOutputStatus.Closed);
|
|
814
|
+
this.params.player.audio.send({
|
|
815
|
+
type: "output-finish",
|
|
816
|
+
id: this.id,
|
|
817
|
+
reason,
|
|
818
|
+
playBuffered
|
|
819
|
+
});
|
|
820
|
+
if (!playBuffered) this.retire(reason);
|
|
745
821
|
}
|
|
746
822
|
close(reason) {
|
|
747
823
|
if (this.closed) return;
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
clearTimeout(this.startupTimer);
|
|
754
|
-
this.startupTimer = void 0;
|
|
755
|
-
this.playbackMarks = [];
|
|
756
|
-
this.playbackItems();
|
|
757
|
-
this.clearWatchdog();
|
|
758
|
-
const activity = this.activity.snapshot();
|
|
759
|
-
logger$3.info(`discord voice: realtime audio playback stopped reason=${reason} ${this.params.logContext} audioMs=${Math.floor(activity.audioMs)} elapsedMs=${this.activity.elapsedPlaybackMs()} chunks=${activity.chunks} discordBytes=${activity.sinkAudioBytes} realtimeBytes=${activity.sourceAudioBytes}`);
|
|
760
|
-
this.buffers = [];
|
|
761
|
-
this.bufferedBytes = 0;
|
|
762
|
-
if (this.drainHandler) {
|
|
763
|
-
this.stream.off("drain", this.drainHandler);
|
|
764
|
-
this.drainHandler = void 0;
|
|
765
|
-
}
|
|
766
|
-
this.stream.end();
|
|
767
|
-
this.stream.destroy();
|
|
768
|
-
if (lostPlaybackMarks) this.params.onError(/* @__PURE__ */ new Error(`Discord realtime audio stopped before playback completed: ${reason}`));
|
|
769
|
-
this.params.onClose(this, reason);
|
|
770
|
-
if (this.request) {
|
|
771
|
-
this.params.player.cancel(this.request);
|
|
772
|
-
this.request = void 0;
|
|
773
|
-
}
|
|
774
|
-
try {
|
|
775
|
-
for (const mark of heardMarks) mark.acknowledge();
|
|
776
|
-
} catch (error) {
|
|
777
|
-
this.params.onError(error);
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
startPlayback() {
|
|
781
|
-
if (this.closed || this.ready) return;
|
|
782
|
-
clearTimeout(this.startupTimer);
|
|
783
|
-
this.startupTimer = void 0;
|
|
784
|
-
if (this.bufferedBytes < DISCORD_RAW_PCM_FRAME_BYTES) this.writeConverted(this.converter.drain());
|
|
785
|
-
this.ready = true;
|
|
786
|
-
this.enqueuePlayback();
|
|
787
|
-
}
|
|
788
|
-
enqueuePlayback() {
|
|
789
|
-
this.request ??= {
|
|
790
|
-
isReady: () => this.ready,
|
|
791
|
-
createResource: () => this.createResource(),
|
|
792
|
-
onStart: () => {
|
|
793
|
-
this.activity.markPlaybackStarted();
|
|
794
|
-
this.params.onStart();
|
|
795
|
-
if (this.activity.snapshot().streamEnding) {
|
|
796
|
-
this.scheduleWatchdog("player-start");
|
|
797
|
-
if (!this.drainHandler) this.stream.end();
|
|
798
|
-
}
|
|
799
|
-
},
|
|
800
|
-
onIdle: () => this.close(this.failed ? "output-pipeline-error" : "player-idle"),
|
|
801
|
-
onBargeIn: this.params.onBargeIn,
|
|
802
|
-
onError: this.params.onError
|
|
803
|
-
};
|
|
804
|
-
this.params.player.enqueue(this.request);
|
|
805
|
-
}
|
|
806
|
-
createResource() {
|
|
807
|
-
const voiceSdk = loadDiscordVoiceSdk();
|
|
808
|
-
const opusStream = createDiscordOpusEncodeStream();
|
|
809
|
-
opusStream.once("error", () => {
|
|
810
|
-
this.failed = true;
|
|
824
|
+
setDiscordAudioOutputStatus(this.clock, DiscordAudioOutputStatus.Closed);
|
|
825
|
+
this.params.player.audio.send({
|
|
826
|
+
type: "output-close",
|
|
827
|
+
id: this.id,
|
|
828
|
+
reason
|
|
811
829
|
});
|
|
812
|
-
|
|
813
|
-
if (!error || this.closed) return;
|
|
814
|
-
logger$3.warn(`discord voice: realtime output pipeline failed ${this.params.logContext}: ${formatErrorMessage(error)}`);
|
|
815
|
-
this.close("output-pipeline-error");
|
|
816
|
-
});
|
|
817
|
-
const buffered = Buffer.concat(this.buffers, this.bufferedBytes);
|
|
818
|
-
this.buffers = [];
|
|
819
|
-
this.bufferedBytes = 0;
|
|
820
|
-
if (buffered.length > 0 && !this.stream.write(buffered)) this.waitForDrain();
|
|
821
|
-
if (this.params.continuous && buffered.length > 0 && buffered.length < DISCORD_RAW_PCM_FRAME_BYTES) opusStream.flushPartialFrameWhenReady();
|
|
822
|
-
const resource = voiceSdk.createAudioResource(opusStream, { inputType: voiceSdk.StreamType.Opus });
|
|
823
|
-
const read = resource.read.bind(resource);
|
|
824
|
-
resource.read = () => {
|
|
825
|
-
let packet;
|
|
826
|
-
try {
|
|
827
|
-
packet = read();
|
|
828
|
-
if (!packet && opusStream.flushPartialFrame()) packet = read();
|
|
829
|
-
if (packet) {
|
|
830
|
-
this.playedPcmBytes += opusStream.takePcmBytes(packet);
|
|
831
|
-
const remaining = this.activity.snapshot().sinkAudioBytes - this.playedPcmBytes;
|
|
832
|
-
if (remaining > 0 && remaining <= DISCORD_RAW_PCM_FRAME_BYTES) this.writeConverted(this.converter.drain());
|
|
833
|
-
this.scheduleSilenceRetirement();
|
|
834
|
-
}
|
|
835
|
-
} catch (error) {
|
|
836
|
-
opusStream.destroy(error instanceof Error ? error : new Error(formatErrorMessage(error)));
|
|
837
|
-
return null;
|
|
838
|
-
}
|
|
839
|
-
if (this.playbackMarks.length > 0) queueMicrotask(() => this.acknowledgePlayedMarks());
|
|
840
|
-
return packet;
|
|
841
|
-
};
|
|
842
|
-
return resource;
|
|
830
|
+
this.retire(reason);
|
|
843
831
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
this.params.onError(error);
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
scheduleSilenceRetirement() {
|
|
857
|
-
const activity = this.activity.snapshot();
|
|
858
|
-
if (!this.params.continuous || this.closed || activity.streamEnding || !activity.playbackStarted || this.hasUnplayedAudibleAudio()) return;
|
|
859
|
-
this.silentSince ??= performance.now();
|
|
860
|
-
if (activity.sinkAudioBytes <= this.lastAudiblePcmEndBytes || this.silenceTimer) return;
|
|
861
|
-
this.silenceTimer = setTimeout(() => {
|
|
862
|
-
this.silenceTimer = void 0;
|
|
863
|
-
if (!this.closed && !this.activity.snapshot().streamEnding && !this.hasUnplayedAudibleAudio()) this.finish("continuous-idle", true);
|
|
864
|
-
}, Math.max(0, DISCORD_REALTIME_PLAYBACK_IDLE_MS - (performance.now() - this.silentSince)));
|
|
865
|
-
this.silenceTimer.unref?.();
|
|
866
|
-
}
|
|
867
|
-
clearSilenceTimer() {
|
|
868
|
-
clearTimeout(this.silenceTimer);
|
|
869
|
-
this.silenceTimer = void 0;
|
|
870
|
-
}
|
|
871
|
-
waitForDrain() {
|
|
872
|
-
if (this.drainHandler || this.closed) return;
|
|
873
|
-
logger$3.info(`discord voice: realtime audio playback buffering ${this.params.logContext} bufferedBytes=${this.stream.writableLength + this.stream.readableLength}`);
|
|
874
|
-
this.drainHandler = () => {
|
|
875
|
-
this.drainHandler = void 0;
|
|
876
|
-
if (this.closed) return;
|
|
877
|
-
let refreshWatchdog = this.activity.snapshot().streamEnding;
|
|
878
|
-
while (this.buffers.length > 0) {
|
|
879
|
-
const buffered = this.buffers.shift();
|
|
880
|
-
if (!buffered) break;
|
|
881
|
-
this.bufferedBytes -= buffered.length;
|
|
882
|
-
const writable = this.stream.write(buffered);
|
|
883
|
-
if (refreshWatchdog) {
|
|
884
|
-
this.scheduleWatchdog("output-drain");
|
|
885
|
-
refreshWatchdog = false;
|
|
886
|
-
}
|
|
887
|
-
if (!writable) {
|
|
888
|
-
this.waitForDrain();
|
|
889
|
-
return;
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
if (this.activity.snapshot().streamEnding) this.stream.end();
|
|
893
|
-
};
|
|
894
|
-
this.stream.once("drain", this.drainHandler);
|
|
895
|
-
}
|
|
896
|
-
scheduleWatchdog(reason) {
|
|
897
|
-
this.clearWatchdog();
|
|
898
|
-
const timeoutMs = this.activity.playbackWatchdogDelayMs({
|
|
899
|
-
marginMs: DISCORD_REALTIME_OUTPUT_PLAYBACK_WATCHDOG_MARGIN_MS,
|
|
900
|
-
minMs: DISCORD_REALTIME_OUTPUT_PLAYBACK_WATCHDOG_MARGIN_MS
|
|
901
|
-
});
|
|
902
|
-
if (timeoutMs === void 0) return;
|
|
903
|
-
this.watchdog = setTimeout(() => {
|
|
904
|
-
this.watchdog = void 0;
|
|
905
|
-
logger$3.warn(`discord voice: realtime audio playback watchdog fired reason=${reason} ${this.params.logContext} audioMs=${Math.floor(this.activity.snapshot().audioMs)} elapsedMs=${this.activity.elapsedPlaybackMs()}`);
|
|
906
|
-
this.close("playback-watchdog");
|
|
907
|
-
}, timeoutMs);
|
|
908
|
-
}
|
|
909
|
-
clearWatchdog() {
|
|
910
|
-
clearTimeout(this.watchdog);
|
|
911
|
-
this.watchdog = void 0;
|
|
832
|
+
retire(reason) {
|
|
833
|
+
if (this.closed) return;
|
|
834
|
+
this.playbackItems();
|
|
835
|
+
this.closed = true;
|
|
836
|
+
this.marks.clear();
|
|
837
|
+
this.params.player.audio.off("event", this.onEvent);
|
|
838
|
+
this.params.player.audio.off("stopped", this.onStopped);
|
|
839
|
+
this.unregister();
|
|
840
|
+
this.params.onClose(this, reason);
|
|
912
841
|
}
|
|
913
842
|
};
|
|
914
843
|
//#endregion
|
|
@@ -930,12 +859,14 @@ function normalizeControlSpeechText(text) {
|
|
|
930
859
|
var DiscordRealtimePlayback = class {
|
|
931
860
|
constructor(params) {
|
|
932
861
|
this.params = params;
|
|
862
|
+
this.outputClearGeneration = 0;
|
|
933
863
|
this.outputs = /* @__PURE__ */ new Set();
|
|
934
864
|
this.generatingItems = /* @__PURE__ */ new Map();
|
|
935
865
|
this.responseAudio = "completed";
|
|
936
866
|
this.queuedExactSpeechMessages = [];
|
|
937
867
|
this.retainedSpeechClosed = false;
|
|
938
868
|
this.exactSpeechState = { status: "idle" };
|
|
869
|
+
this.nextExactSpeechEpoch = 0n;
|
|
939
870
|
this.wakeNameAckIndex = 0;
|
|
940
871
|
this.unregisterPlayerLane = this.params.player.registerLane({
|
|
941
872
|
hasOutput: () => this.isOutputAudioActive(),
|
|
@@ -943,16 +874,77 @@ var DiscordRealtimePlayback = class {
|
|
|
943
874
|
cancelForControl: () => this.cancelForControl()
|
|
944
875
|
});
|
|
945
876
|
}
|
|
877
|
+
/** Only continuous provider media uses this generation-scoped, PCM24k mono port. */
|
|
878
|
+
createOutputAudioPort(enabled = true) {
|
|
879
|
+
this.directOutput?.close();
|
|
880
|
+
const { port1, port2 } = new MessageChannel();
|
|
881
|
+
const id = this.params.entry.audio.allocateId();
|
|
882
|
+
const state = new Int32Array(new SharedArrayBuffer(4));
|
|
883
|
+
const clock = new BigInt64Array(new SharedArrayBuffer(24));
|
|
884
|
+
const unregister = this.params.player.registerOutput(id, (reason) => this.handleBargeIn(reason));
|
|
885
|
+
const onEvent = (event) => {
|
|
886
|
+
if (!("id" in event) || event.id !== id || this.directOutput?.id !== id) return;
|
|
887
|
+
if ((event.type === "continuous-start" || event.type === "continuous-idle") && this.exactSpeechState.status === "active" && this.exactSpeechState.direct && event.speechEpoch !== this.exactSpeechState.direct.epoch) return;
|
|
888
|
+
if (event.type === "continuous-error") this.stopAfterPlaybackFailure("direct-output-error", restoreDiscordAudioError(event.error));
|
|
889
|
+
if (event.type === "continuous-start") this.params.harness.outputActivity.markPlaybackStarted();
|
|
890
|
+
if (event.type === "continuous-flushed" && event.marker === this.pendingDirectCompletion) {
|
|
891
|
+
this.pendingDirectCompletion = void 0;
|
|
892
|
+
this.responseAudio = "completed";
|
|
893
|
+
this.completeExactSpeechResponse("provider-completed");
|
|
894
|
+
}
|
|
895
|
+
if (event.type === "continuous-idle") {
|
|
896
|
+
this.responseAudio = "completed";
|
|
897
|
+
this.params.harness.finishOutputAudio("player-idle");
|
|
898
|
+
this.params.harness.outputActivity.reset();
|
|
899
|
+
this.completeExactSpeechResponse("player-idle");
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
const close = () => {
|
|
903
|
+
Atomics.store(state, 0, 1);
|
|
904
|
+
this.params.entry.audio.off("event", onEvent);
|
|
905
|
+
unregister();
|
|
906
|
+
this.params.entry.audio.send({
|
|
907
|
+
type: "continuous-close",
|
|
908
|
+
id
|
|
909
|
+
});
|
|
910
|
+
if (this.directOutput?.id === id) this.directOutput = void 0;
|
|
911
|
+
};
|
|
912
|
+
this.directOutput = {
|
|
913
|
+
id,
|
|
914
|
+
clock,
|
|
915
|
+
close
|
|
916
|
+
};
|
|
917
|
+
this.params.entry.audio.on("event", onEvent);
|
|
918
|
+
this.params.entry.audio.send({
|
|
919
|
+
type: "continuous-port",
|
|
920
|
+
id,
|
|
921
|
+
enabled,
|
|
922
|
+
port: port1,
|
|
923
|
+
state: state.buffer,
|
|
924
|
+
clock: clock.buffer
|
|
925
|
+
}, [port1]);
|
|
926
|
+
return {
|
|
927
|
+
port: port2,
|
|
928
|
+
state: state.buffer
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
activateOutputAudioPort() {
|
|
932
|
+
if (this.directOutput) this.params.entry.audio.send({
|
|
933
|
+
type: "continuous-activate",
|
|
934
|
+
id: this.directOutput.id
|
|
935
|
+
});
|
|
936
|
+
}
|
|
946
937
|
close(preserveUnplayedSpeech = false) {
|
|
947
938
|
this.unregisterPlayerLane();
|
|
948
|
-
if (preserveUnplayedSpeech) this.
|
|
939
|
+
if (preserveUnplayedSpeech) this.retireExactSpeech(true);
|
|
949
940
|
else {
|
|
950
941
|
this.retainedSpeechClosed = true;
|
|
951
942
|
this.speechSuccessor = void 0;
|
|
952
943
|
this.queuedExactSpeechMessages = [];
|
|
953
|
-
this.
|
|
944
|
+
this.retireExactSpeech();
|
|
954
945
|
}
|
|
955
946
|
this.clearOutputAudio("session-close");
|
|
947
|
+
this.directOutput?.close();
|
|
956
948
|
}
|
|
957
949
|
transferPendingSpeechTo(target) {
|
|
958
950
|
this.speechSuccessor = target;
|
|
@@ -970,13 +962,14 @@ var DiscordRealtimePlayback = class {
|
|
|
970
962
|
return false;
|
|
971
963
|
}
|
|
972
964
|
logger$2.info(`discord voice: realtime barge-in requested reason=${reason} guild=${this.params.entry.guildId} channel=${this.params.entry.channelId} outputAudioMs=${this.outputAudioMs()} outputActive=${this.isOutputAudioActive()} playbackChunks=${this.params.harness.outputActivity.snapshot().chunks}`);
|
|
965
|
+
const clearGeneration = this.outputClearGeneration;
|
|
973
966
|
const bridge = this.params.bridge();
|
|
974
967
|
const outputs = Array.from(this.outputs);
|
|
975
968
|
const items = Array.from(this.generatingItems.values());
|
|
976
969
|
this.params.harness.handleBargeIn({ audioPlaybackActive: true }, () => {
|
|
977
970
|
if (!bridge?.bridge.handleBargeIn) this.clearOutputAudio(reason);
|
|
978
971
|
});
|
|
979
|
-
return outputs.some((output) => !this.outputs.has(output)) || items.some((item) => this.generatingItems.get(item.itemId) !== item);
|
|
972
|
+
return clearGeneration !== this.outputClearGeneration || outputs.some((output) => !this.outputs.has(output)) || items.some((item) => this.generatingItems.get(item.itemId) !== item);
|
|
980
973
|
}
|
|
981
974
|
isBargeInEnabled() {
|
|
982
975
|
if (this.params.wakeNameRequired()) return false;
|
|
@@ -1043,10 +1036,15 @@ var DiscordRealtimePlayback = class {
|
|
|
1043
1036
|
this.generatingItems.set(metadata.itemId, item);
|
|
1044
1037
|
}
|
|
1045
1038
|
}
|
|
1046
|
-
this.params.harness.recordOutputAudio(realtimePcm24kMono, activity);
|
|
1047
|
-
output.append(realtimePcm24kMono, audible, item)
|
|
1039
|
+
const onAccepted = () => this.params.harness.recordOutputAudio(realtimePcm24kMono, activity);
|
|
1040
|
+
if (!output.append(realtimePcm24kMono, audible, item, onAccepted)) {
|
|
1041
|
+
this.generatingOutput = void 0;
|
|
1042
|
+
this.sendOutputAudio(realtimePcm24kMono, metadata);
|
|
1043
|
+
}
|
|
1048
1044
|
}
|
|
1049
1045
|
clearOutputAudio(reason = "clear") {
|
|
1046
|
+
this.outputClearGeneration += 1;
|
|
1047
|
+
this.retireExactSpeech();
|
|
1050
1048
|
if (this.isContinuousOutput()) this.responseAudio = "completed";
|
|
1051
1049
|
else if (this.responseAudio === "accepting") this.responseAudio = "discarding";
|
|
1052
1050
|
this.generatingOutput = void 0;
|
|
@@ -1055,9 +1053,26 @@ var DiscordRealtimePlayback = class {
|
|
|
1055
1053
|
this.outputs.clear();
|
|
1056
1054
|
for (const output of outputs.toReversed()) output.close(reason);
|
|
1057
1055
|
this.params.harness.outputActivity.reset();
|
|
1056
|
+
if (this.directOutput) {
|
|
1057
|
+
if (reason === "session-close" || this.params.stopped()) this.directOutput.close();
|
|
1058
|
+
else this.params.entry.audio.send({
|
|
1059
|
+
type: "continuous-clear",
|
|
1060
|
+
id: this.directOutput.id
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1058
1063
|
this.completeExactSpeechResponse(reason);
|
|
1059
1064
|
}
|
|
1060
1065
|
handleResponseDone(outcome) {
|
|
1066
|
+
if (this.directOutput && outcome.status === "completed") {
|
|
1067
|
+
const marker = this.params.entry.audio.allocateId();
|
|
1068
|
+
this.pendingDirectCompletion = marker;
|
|
1069
|
+
this.params.entry.audio.send({
|
|
1070
|
+
type: "continuous-flush",
|
|
1071
|
+
id: this.directOutput.id,
|
|
1072
|
+
marker
|
|
1073
|
+
});
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1061
1076
|
const output = this.generatingOutput;
|
|
1062
1077
|
this.generatingOutput = void 0;
|
|
1063
1078
|
this.generatingItems.clear();
|
|
@@ -1077,8 +1092,9 @@ var DiscordRealtimePlayback = class {
|
|
|
1077
1092
|
/** Accept completed consult ownership without starting provider work during transport cleanup. */
|
|
1078
1093
|
retainExactSpeechMessage(text) {
|
|
1079
1094
|
if (!text.trim()) return false;
|
|
1080
|
-
const
|
|
1081
|
-
const
|
|
1095
|
+
const retained = this.retainedExactSpeechTexts();
|
|
1096
|
+
const retainedMessages = retained.length;
|
|
1097
|
+
const retainedBytes = retained.reduce((total, message) => total + Buffer.byteLength(message, "utf8"), 0);
|
|
1082
1098
|
const incomingBytes = Buffer.byteLength(text, "utf8");
|
|
1083
1099
|
if (retainedMessages >= DISCORD_REALTIME_MAX_RETAINED_RESPONSES || retainedBytes + incomingBytes > DISCORD_REALTIME_MAX_RETAINED_EXACT_SPEECH_BYTES) {
|
|
1084
1100
|
this.stopAfterPlaybackFailure("exact-speech-overflow", /* @__PURE__ */ new Error(`Discord realtime exact speech overflow: retained=${retainedMessages} retainedBytes=${retainedBytes} incomingBytes=${incomingBytes}`));
|
|
@@ -1122,8 +1138,12 @@ var DiscordRealtimePlayback = class {
|
|
|
1122
1138
|
}
|
|
1123
1139
|
cancelForControl() {
|
|
1124
1140
|
this.queuedExactSpeechMessages = [];
|
|
1125
|
-
this.
|
|
1126
|
-
if (this.responseAudio === "completed" && this.
|
|
1141
|
+
this.retireExactSpeech();
|
|
1142
|
+
if (this.responseAudio === "completed" && !this.isOutputAudioActive()) return;
|
|
1143
|
+
if (this.isContinuousOutput()) {
|
|
1144
|
+
this.params.harness.flushOutput(() => this.clearOutputAudio("active-run-control"));
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1127
1147
|
this.params.harness.handleBargeIn({
|
|
1128
1148
|
audioPlaybackActive: true,
|
|
1129
1149
|
force: true
|
|
@@ -1147,22 +1167,25 @@ var DiscordRealtimePlayback = class {
|
|
|
1147
1167
|
}
|
|
1148
1168
|
resetProviderContinuity(reason) {
|
|
1149
1169
|
this.lastControlSpeech = void 0;
|
|
1150
|
-
this.
|
|
1170
|
+
this.retireExactSpeech(true);
|
|
1151
1171
|
this.responseAudio = "discarding";
|
|
1152
1172
|
this.params.harness.flushOutput(() => this.clearOutputAudio(reason));
|
|
1153
1173
|
this.responseAudio = "completed";
|
|
1154
1174
|
this.params.harness.finishOutputAudio(reason);
|
|
1155
1175
|
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1176
|
+
retireExactSpeech(preserveUnplayed = false) {
|
|
1177
|
+
this.pendingDirectCompletion = void 0;
|
|
1178
|
+
const speech = this.exactSpeechState;
|
|
1158
1179
|
this.exactSpeechState = { status: "idle" };
|
|
1159
|
-
if (
|
|
1180
|
+
if (speech.status !== "active") return;
|
|
1181
|
+
const directStarted = speech.direct && Atomics.exchange(speech.direct.clock, 2, 0n) === -speech.direct.epoch;
|
|
1182
|
+
if (preserveUnplayed && !directStarted && !speech.output?.activity.snapshot().playbackStarted) this.queuedExactSpeechMessages.unshift(speech.message);
|
|
1160
1183
|
}
|
|
1161
1184
|
outputAudioMs() {
|
|
1162
|
-
return Math.floor(this.params.harness.outputActivity.snapshot().audioMs);
|
|
1185
|
+
return this.directOutput ? Math.floor(Number(Atomics.load(this.directOutput.clock, 1)) / 48) : Math.floor(this.params.harness.outputActivity.snapshot().audioMs);
|
|
1163
1186
|
}
|
|
1164
1187
|
isOutputAudioActive() {
|
|
1165
|
-
return this.outputs.size > 0 || this.generatingItems.size > 0;
|
|
1188
|
+
return this.outputs.size > 0 || this.generatingItems.size > 0 || this.directOutput !== void 0 && Atomics.load(this.directOutput.clock, 0) > 0n;
|
|
1166
1189
|
}
|
|
1167
1190
|
isContinuousOutput() {
|
|
1168
1191
|
return this.params.bridge()?.bridge.outputAudioMode === "continuous";
|
|
@@ -1172,7 +1195,7 @@ var DiscordRealtimePlayback = class {
|
|
|
1172
1195
|
this.speechSuccessor = void 0;
|
|
1173
1196
|
this.params.stopTerminally();
|
|
1174
1197
|
this.queuedExactSpeechMessages = [];
|
|
1175
|
-
this.
|
|
1198
|
+
this.retireExactSpeech();
|
|
1176
1199
|
this.clearOutputAudio(reason);
|
|
1177
1200
|
this.params.onTerminalError(error);
|
|
1178
1201
|
}
|
|
@@ -1180,7 +1203,6 @@ var DiscordRealtimePlayback = class {
|
|
|
1180
1203
|
const logContext = `guild=${this.params.entry.guildId} channel=${this.params.entry.channelId}`;
|
|
1181
1204
|
const output = new DiscordRealtimeOutput({
|
|
1182
1205
|
player: this.params.player,
|
|
1183
|
-
logContext,
|
|
1184
1206
|
continuous: this.isContinuousOutput(),
|
|
1185
1207
|
onStart: () => {
|
|
1186
1208
|
this.params.harness.outputActivity.markPlaybackStarted();
|
|
@@ -1214,25 +1236,27 @@ var DiscordRealtimePlayback = class {
|
|
|
1214
1236
|
}
|
|
1215
1237
|
sendExactSpeechMessage(text) {
|
|
1216
1238
|
if (this.params.stopped() || !text.trim()) return;
|
|
1239
|
+
const direct = this.directOutput ? {
|
|
1240
|
+
clock: this.directOutput.clock,
|
|
1241
|
+
epoch: ++this.nextExactSpeechEpoch
|
|
1242
|
+
} : void 0;
|
|
1217
1243
|
this.exactSpeechState = {
|
|
1218
1244
|
status: "active",
|
|
1219
|
-
message: text
|
|
1245
|
+
message: text,
|
|
1246
|
+
direct
|
|
1220
1247
|
};
|
|
1248
|
+
if (direct) Atomics.store(direct.clock, 2, direct.epoch);
|
|
1221
1249
|
this.beginResponse();
|
|
1222
1250
|
this.params.bridge()?.sendUserMessage(this.params.buildSpeakExactMessage(text));
|
|
1223
1251
|
}
|
|
1224
1252
|
completeExactSpeechResponse(reason) {
|
|
1225
|
-
if (this.responseAudio !== "completed" || this.
|
|
1226
|
-
this.
|
|
1253
|
+
if (this.pendingDirectCompletion !== void 0 || this.responseAudio !== "completed" || this.isOutputAudioActive()) return;
|
|
1254
|
+
this.retireExactSpeech();
|
|
1227
1255
|
this.drainQueuedExactSpeechMessages(reason);
|
|
1228
1256
|
}
|
|
1229
1257
|
};
|
|
1230
1258
|
//#endregion
|
|
1231
1259
|
//#region extensions/discord/src/voice/realtime-speaker-config.ts
|
|
1232
|
-
function readProviderConfigString(config, key) {
|
|
1233
|
-
const value = config[key];
|
|
1234
|
-
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
1235
|
-
}
|
|
1236
1260
|
/** Resolve the same provider, voice catalog, and policies for initial and replacement connections. */
|
|
1237
1261
|
function resolveDiscordRealtimeSpeakerConfig(params) {
|
|
1238
1262
|
const { realtimeConfig, isAgentProxy } = params;
|
|
@@ -1243,11 +1267,14 @@ function resolveDiscordRealtimeSpeakerConfig(params) {
|
|
|
1243
1267
|
if (canonicalProviderId) ownerProviderIds.add(canonicalProviderId);
|
|
1244
1268
|
for (const providerId of ownerProviderIds) assertSecretOwnerAvailable("capability", discordRealtimeVoiceSecretOwnerId(params.accountId, providerId));
|
|
1245
1269
|
}
|
|
1270
|
+
const configuredVoice = realtimeConfig?.speakerVoice || realtimeConfig?.speakerVoiceId;
|
|
1246
1271
|
const resolved = resolveConfiguredRealtimeVoiceProvider({
|
|
1247
1272
|
configuredProviderId: realtimeConfig?.provider,
|
|
1248
|
-
providerConfigs:
|
|
1273
|
+
providerConfigs: { ...realtimeConfig?.providers },
|
|
1249
1274
|
providerConfigOverrides: {
|
|
1250
|
-
...
|
|
1275
|
+
...realtimeConfig?.model ? { model: realtimeConfig.model } : {},
|
|
1276
|
+
...configuredVoice ? { voice: configuredVoice } : {},
|
|
1277
|
+
...typeof realtimeConfig?.minBargeInAudioEndMs === "number" ? { minBargeInAudioEndMs: realtimeConfig.minBargeInAudioEndMs } : {},
|
|
1251
1278
|
...params.voiceOverride ? {
|
|
1252
1279
|
voice: params.voiceOverride,
|
|
1253
1280
|
speakerVoice: params.voiceOverride
|
|
@@ -1265,14 +1292,14 @@ function resolveDiscordRealtimeSpeakerConfig(params) {
|
|
|
1265
1292
|
});
|
|
1266
1293
|
assertSecretOwnerAvailable("capability", discordRealtimeVoiceSecretOwnerId(params.accountId, resolved.provider.id));
|
|
1267
1294
|
const capabilities = resolved.capabilities;
|
|
1268
|
-
const model =
|
|
1295
|
+
const model = normalizeOptionalString(resolved.providerConfig.model) ?? resolved.provider.defaultModel;
|
|
1269
1296
|
const voices = [...capabilities?.voices ?? (model ? capabilities?.voicesByModel?.[model] : void 0) ?? resolved.provider.voices ?? []];
|
|
1270
1297
|
const publicConfig = projectInternalRealtimeVoicePublicConfig({
|
|
1271
1298
|
provider: resolved.provider,
|
|
1272
1299
|
providerConfig: resolved.providerConfig,
|
|
1273
1300
|
config: {
|
|
1274
1301
|
model,
|
|
1275
|
-
voice:
|
|
1302
|
+
voice: normalizeOptionalString(resolved.providerConfig.speakerVoice) ?? normalizeOptionalString(resolved.providerConfig.voice)
|
|
1276
1303
|
}
|
|
1277
1304
|
});
|
|
1278
1305
|
const selection = {
|
|
@@ -1323,7 +1350,7 @@ function resolveDiscordRealtimeSpeakerConfig(params) {
|
|
|
1323
1350
|
bargeIn,
|
|
1324
1351
|
minBargeInAudioEndMs,
|
|
1325
1352
|
resolvedModel: model,
|
|
1326
|
-
resolvedVoice:
|
|
1353
|
+
resolvedVoice: normalizeOptionalString(resolved.providerConfig.voice)
|
|
1327
1354
|
};
|
|
1328
1355
|
}
|
|
1329
1356
|
//#endregion
|
|
@@ -1331,9 +1358,6 @@ function resolveDiscordRealtimeSpeakerConfig(params) {
|
|
|
1331
1358
|
const logger$1 = createSubsystemLogger("discord/voice");
|
|
1332
1359
|
const DISCORD_REALTIME_DUPLICATE_ERROR_SUPPRESS_MS = 6e4;
|
|
1333
1360
|
const discordRealtimeTalkPayload = () => ({});
|
|
1334
|
-
function isDiscordAgentProxyVoiceMode(mode) {
|
|
1335
|
-
return mode === "agent-proxy";
|
|
1336
|
-
}
|
|
1337
1361
|
var DiscordRealtimeSpeakerSession = class {
|
|
1338
1362
|
constructor(params) {
|
|
1339
1363
|
this.params = params;
|
|
@@ -1356,7 +1380,12 @@ var DiscordRealtimeSpeakerSession = class {
|
|
|
1356
1380
|
this.inputIdleListeners = /* @__PURE__ */ new Set();
|
|
1357
1381
|
this.lastActivityAt = Date.now();
|
|
1358
1382
|
this.outputEnabled = !params.standby;
|
|
1359
|
-
|
|
1383
|
+
const recordingEpoch = this.providerContinuityEpoch;
|
|
1384
|
+
this.recording = new DiscordRealtimeRecording({
|
|
1385
|
+
entry: this.params.entry,
|
|
1386
|
+
isCurrent: () => this.lifecycle.status !== "stopped" && this.providerContinuityEpoch === recordingEpoch,
|
|
1387
|
+
warn: (message) => logger$1.warn(message)
|
|
1388
|
+
});
|
|
1360
1389
|
this.harness = createRealtimeVoiceSessionHarness({
|
|
1361
1390
|
talk: {
|
|
1362
1391
|
sessionId: this.params.sessionId,
|
|
@@ -1427,7 +1456,7 @@ var DiscordRealtimeSpeakerSession = class {
|
|
|
1427
1456
|
debounceMs: () => this.realtimeConfig?.debounceMs,
|
|
1428
1457
|
entry: this.params.entry,
|
|
1429
1458
|
harness: this.harness,
|
|
1430
|
-
isAgentProxy: () =>
|
|
1459
|
+
isAgentProxy: () => this.params.mode === "agent-proxy" && !this.handlesAgentConsult,
|
|
1431
1460
|
isWakeNameRequired: () => this.isWakeNameRequired(),
|
|
1432
1461
|
playback: this.playback,
|
|
1433
1462
|
providerEpoch: () => this.providerContinuityEpoch,
|
|
@@ -1450,7 +1479,7 @@ var DiscordRealtimeSpeakerSession = class {
|
|
|
1450
1479
|
agentId: this.params.entry.route.agentId,
|
|
1451
1480
|
cfg: this.params.cfg,
|
|
1452
1481
|
realtimeConfig: this.realtimeConfig,
|
|
1453
|
-
isAgentProxy:
|
|
1482
|
+
isAgentProxy: this.params.mode === "agent-proxy",
|
|
1454
1483
|
bootstrapContextInstructions: this.params.bootstrapContextInstructions,
|
|
1455
1484
|
voiceOverride: this.params.voiceOverride,
|
|
1456
1485
|
conversationHistory: this.params.conversationHistory
|
|
@@ -1548,6 +1577,7 @@ var DiscordRealtimeSpeakerSession = class {
|
|
|
1548
1577
|
}
|
|
1549
1578
|
const humanParticipantCount = this.humanParticipantCount();
|
|
1550
1579
|
logger$1.info(`discord voice: realtime bridge starting mode=${this.params.mode} provider=${resolved.provider.id} model=${resolvedModel ?? "default"} voice=${resolvedVoice ?? "default"} consultPolicy=${consultPolicy} toolPolicy=${toolPolicy} autoRespond=${autoRespondToAudio} wakeNamePolicy=${this.wakeNamePolicy} requireWakeName=${this.isWakeNameRequired(humanParticipantCount)} humanParticipants=${humanParticipantCount} wakeNames=${this.wakeNames.join(",") || "none"} interruptResponse=${interruptResponseOnInputAudio} bargeIn=${bargeIn} minBargeInAudioEndMs=${minBargeInAudioEndMs}`);
|
|
1580
|
+
this.attachOutputAudioPort();
|
|
1551
1581
|
await this.bridge.connect();
|
|
1552
1582
|
if (!this.markLifecycleReady(lifecycleGeneration)) {
|
|
1553
1583
|
await this.close();
|
|
@@ -1671,6 +1701,11 @@ var DiscordRealtimeSpeakerSession = class {
|
|
|
1671
1701
|
activateOutput() {
|
|
1672
1702
|
this.readVoiceSelection();
|
|
1673
1703
|
this.outputEnabled = true;
|
|
1704
|
+
this.playback.activateOutputAudioPort();
|
|
1705
|
+
}
|
|
1706
|
+
attachOutputAudioPort() {
|
|
1707
|
+
const provider = this.bridge?.bridge;
|
|
1708
|
+
if (this.wakeNamePolicy === "never" && provider?.outputAudioMode === "continuous" && provider.setAudioOutputPort) provider.setAudioOutputPort(this.playback.createOutputAudioPort(this.outputEnabled));
|
|
1674
1709
|
}
|
|
1675
1710
|
hasActiveInput() {
|
|
1676
1711
|
return this.captures.size > 0;
|
|
@@ -1750,14 +1785,6 @@ var DiscordRealtimeSpeakerSession = class {
|
|
|
1750
1785
|
this.turns.resetProviderContinuity();
|
|
1751
1786
|
this.playback.resetProviderContinuity(reason);
|
|
1752
1787
|
}
|
|
1753
|
-
createRecording() {
|
|
1754
|
-
const epoch = this.providerContinuityEpoch;
|
|
1755
|
-
return new DiscordRealtimeRecording({
|
|
1756
|
-
entry: this.params.entry,
|
|
1757
|
-
isCurrent: () => this.lifecycle.status !== "stopped" && this.providerContinuityEpoch === epoch,
|
|
1758
|
-
warn: (message) => logger$1.warn(message)
|
|
1759
|
-
});
|
|
1760
|
-
}
|
|
1761
1788
|
logRealtimeError(message) {
|
|
1762
1789
|
const now = Date.now();
|
|
1763
1790
|
if (this.lastRealtimeError?.message === message && now - this.lastRealtimeError.lastLoggedAt < DISCORD_REALTIME_DUPLICATE_ERROR_SUPPRESS_MS) {
|
|
@@ -1795,7 +1822,7 @@ var DiscordRealtimeVoiceSession = class {
|
|
|
1795
1822
|
this.changingVoice = false;
|
|
1796
1823
|
this.callAbort = new AbortController();
|
|
1797
1824
|
this.candidates = /* @__PURE__ */ new Set();
|
|
1798
|
-
this.player = new DiscordRealtimePlayer(params.entry.
|
|
1825
|
+
this.player = new DiscordRealtimePlayer(params.entry.audio);
|
|
1799
1826
|
}
|
|
1800
1827
|
async connect() {
|
|
1801
1828
|
if (this.closed) throw new Error("Discord realtime voice session is closed");
|