@openclaw/discord 2026.9.5 → 2026.9.6

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.
Files changed (421) hide show
  1. package/dist/.setup/{activities-api-DBwRt5ES.mjs → activities-api-COU4-0nR.mjs} +4 -4
  2. package/dist/.setup/{approval-handler.runtime-Du3n5ypX.mjs → approval-handler.runtime-CbBktBb4.mjs} +5 -5
  3. package/dist/.setup/{approval-message-updates-BN7JtScm.mjs → approval-message-updates-jf9zMaIC.mjs} +1 -1
  4. package/dist/.setup/{audit-C8uaKoa9.mjs → audit-vKbh-LFR.mjs} +3 -3
  5. package/dist/.setup/{channel-ChKdlBgH.mjs → channel-Dv4e3Jpc.mjs} +19 -16
  6. package/dist/.setup/{channel-actions.runtime-CJmiFfps.mjs → channel-actions.runtime-leZuw01r.mjs} +13 -7
  7. package/dist/.setup/{channel.setup-BlC3-Kzz.mjs → channel.setup-0NX6FFwi.mjs} +1 -1
  8. package/dist/.setup/{components-MqMWUWnE.mjs → components-yBEb75bB.mjs} +1 -2
  9. package/dist/.setup/{conversation-binding-route-_rz33QHO.mjs → conversation-binding-route-B7qImK_b.mjs} +6 -3
  10. package/dist/.setup/{doctor-DxcdkXzz.mjs → doctor-D1R-uFIu.mjs} +2 -2
  11. package/dist/.setup/{handle-action.guild-admin-DAFyh_yV.mjs → handle-action.guild-admin-DcFa8NwA.mjs} +3 -3
  12. package/dist/.setup/{message-handler-DnUrDpaU.mjs → message-handler-X6ejmbtY.mjs} +6 -5
  13. package/dist/.setup/{message-handler.preflight-CtqaF_fb.mjs → message-handler.preflight-DE_POxFc.mjs} +14 -117
  14. package/dist/.setup/message-handler.preflight-pluralkit-8Xji34AF.mjs +143 -0
  15. package/dist/.setup/{message-handler.process-Dz1xvuQU.mjs → message-handler.process-CCmIVnxy.mjs} +387 -317
  16. package/dist/.setup/{outbound-adapter-C8v79z9Z.mjs → outbound-adapter-ClIgmu4F.mjs} +5 -5
  17. package/dist/.setup/{outbound-session-route-CqWbuMOm.mjs → outbound-session-route-VulUE0yV.mjs} +7 -6
  18. package/dist/.setup/{preflight-audio-DrnqFA8U.mjs → preflight-audio-DHGIHEpv.mjs} +2 -1
  19. package/dist/.setup/{provider-72zIvN-i.mjs → provider-iOf73HW-.mjs} +425 -286
  20. package/dist/.setup/{provider-session.runtime-BW7QrF5C.mjs → provider-session.runtime-DrGAYnZv.mjs} +3 -3
  21. package/dist/.setup/provider.runtime-BmjW_pIw.mjs +2 -0
  22. package/dist/.setup/{realtime-session.runtime-DTccTgTM.mjs → realtime-session.runtime-Dz8uVutq.mjs} +338 -297
  23. package/dist/.setup/receive-recovery-DHst8WRx.mjs +517 -0
  24. package/dist/.setup/{retry-DBfcEgmO.mjs → retry-BEYkDy0P.mjs} +78 -13
  25. package/dist/.setup/{runtime-SchNfUsQ.mjs → runtime-B8lJfyrA.mjs} +30 -11
  26. package/dist/.setup/{runtime-BVoa7hhx.mjs → runtime-DisDbixd.mjs} +1 -1
  27. package/dist/.setup/{send-CKDczUNL.mjs → send-CIBzvXjS.mjs} +23 -9
  28. package/dist/.setup/{send.components-DWQjXhPV.mjs → send.components-ChY21qr-.mjs} +4 -4
  29. package/dist/.setup/{send.outbound-D0hQ7s50.mjs → send.outbound-QTyuFupn.mjs} +15 -16
  30. package/dist/.setup/{send.shared-Zwx6BxQ5.mjs → send.shared-VNvWfX2T.mjs} +2 -2
  31. package/dist/.setup/setup-plugin-api-Dvr41dyx.mjs +3 -0
  32. package/dist/.setup/{shared-CaA3Vv4n.mjs → shared-DHPDaMSx.mjs} +1 -1
  33. package/dist/.setup/{subagent-hooks-Bired9q6.mjs → subagent-hooks-CjW7r8Pe.mjs} +1 -1
  34. package/dist/.setup/{target-resolver-B6MrxbYv.mjs → target-resolver-BXpy6VT8.mjs} +1 -1
  35. package/dist/.setup/targets-CvemhN3i.mjs +3 -0
  36. package/dist/.setup/{thread-bindings-CK5272V3.mjs → thread-bindings-CEh2dhqP.mjs} +3 -3
  37. package/dist/.setup/{thread-bindings.manager-eexkKyrG.mjs → thread-bindings.manager-ve-i6oqt.mjs} +94 -45
  38. package/dist/.setup/{transcripts-source-CuWYgayu.mjs → transcripts-source-DVegW0WI.mjs} +61 -7
  39. package/dist/.setup/{voice-runtime-DHVQ2mFz.mjs → voice-runtime-elTtjEIG.mjs} +553 -901
  40. package/dist/action-runtime-api.js +1 -1
  41. package/dist/activities-api.js +1 -1
  42. package/dist/api.js +10 -10
  43. package/dist/channel-plugin-api.js +1 -1
  44. package/dist/index.js +1 -1
  45. package/dist/runtime-api.js +12 -12
  46. package/dist/setup-entry.js +1 -1
  47. package/dist/setup-plugin-api.js +1 -1
  48. package/dist/src/voice/audio-worker.runtime.js +1065 -0
  49. package/dist/subagent-hooks-api.js +1 -1
  50. package/dist/transcripts-source-api.js +1 -1
  51. package/node_modules/@napi-rs/wasm-runtime/dist/emnapi-plugins.cjs +8 -4
  52. package/node_modules/@napi-rs/wasm-runtime/dist/emnapi-plugins.js +8 -4
  53. package/node_modules/@napi-rs/wasm-runtime/dist/fs-proxy.cjs +1 -1
  54. package/node_modules/@napi-rs/wasm-runtime/dist/fs.js +770 -695
  55. package/node_modules/@napi-rs/wasm-runtime/fs-proxy.js +3 -2
  56. package/node_modules/@napi-rs/wasm-runtime/package.json +1 -1
  57. package/node_modules/@tybys/wasm-util/LICENSE +21 -0
  58. package/node_modules/@tybys/wasm-util/package.json +1 -1
  59. package/node_modules/@types/node/README.md +1 -1
  60. package/node_modules/@types/node/package.json +2 -2
  61. package/node_modules/@types/node/web-globals/streams.d.ts +4 -0
  62. package/node_modules/zod/README.md +2 -2
  63. package/node_modules/zod/compile.cjs +19 -0
  64. package/node_modules/zod/index.cjs +19 -0
  65. package/node_modules/zod/locales/index.cjs +19 -0
  66. package/node_modules/zod/mini/index.cjs +19 -0
  67. package/node_modules/zod/package.json +8 -7
  68. package/node_modules/zod/src/v3/helpers/errorUtil.ts +1 -1
  69. package/node_modules/zod/src/v4/classic/external.ts +2 -0
  70. package/node_modules/zod/src/v4/classic/from-json-schema.ts +248 -25
  71. package/node_modules/zod/src/v4/classic/schemas.ts +243 -168
  72. package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +60 -9
  73. package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +6 -0
  74. package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +2 -2
  75. package/node_modules/zod/src/v4/classic/tests/cyclic-data.test.ts +265 -0
  76. package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +112 -6
  77. package/node_modules/zod/src/v4/classic/tests/enum.test.ts +9 -0
  78. package/node_modules/zod/src/v4/classic/tests/error.test.ts +130 -1
  79. package/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +157 -0
  80. package/node_modules/zod/src/v4/classic/tests/iban.test.ts +81 -0
  81. package/node_modules/zod/src/v4/classic/tests/instance-footprint.test.ts +40 -2
  82. package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +27 -7
  83. package/node_modules/zod/src/v4/classic/tests/issue-schema.test.ts +88 -56
  84. package/node_modules/zod/src/v4/classic/tests/number.test.ts +39 -0
  85. package/node_modules/zod/src/v4/classic/tests/object.test.ts +56 -0
  86. package/node_modules/zod/src/v4/classic/tests/optin-ladder.test.ts +3 -2
  87. package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +70 -0
  88. package/node_modules/zod/src/v4/classic/tests/properties.test.ts +141 -0
  89. package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +46 -1
  90. package/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +19 -0
  91. package/node_modules/zod/src/v4/classic/tests/string.test.ts +95 -1
  92. package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +33 -1
  93. package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +234 -38
  94. package/node_modules/zod/src/v4/classic/tests/validate.test.ts +569 -0
  95. package/node_modules/zod/src/v4/core/api.ts +44 -28
  96. package/node_modules/zod/src/v4/core/checks.ts +62 -102
  97. package/node_modules/zod/src/v4/core/compile.ts +218 -93
  98. package/node_modules/zod/src/v4/core/core.ts +1 -3
  99. package/node_modules/zod/src/v4/core/doc.ts +6 -2
  100. package/node_modules/zod/src/v4/core/errors.ts +3 -6
  101. package/node_modules/zod/src/v4/core/json-schema-generator.ts +2 -2
  102. package/node_modules/zod/src/v4/core/json-schema-processors.ts +185 -81
  103. package/node_modules/zod/src/v4/core/memoizer.ts +75 -28
  104. package/node_modules/zod/src/v4/core/parse.ts +37 -16
  105. package/node_modules/zod/src/v4/core/regexes.ts +14 -4
  106. package/node_modules/zod/src/v4/core/schemas.ts +296 -132
  107. package/node_modules/zod/src/v4/core/tests/cached.test.ts +54 -0
  108. package/node_modules/zod/src/v4/core/tests/compile-differential.test.ts +35 -0
  109. package/node_modules/zod/src/v4/core/tests/compile-generative.test.ts +445 -0
  110. package/node_modules/zod/src/v4/core/tests/compile.test.ts +399 -2
  111. package/node_modules/zod/src/v4/core/tests/email-regex.test.ts +140 -0
  112. package/node_modules/zod/src/v4/core/tests/locales/tg.test.ts +85 -0
  113. package/node_modules/zod/src/v4/core/tests/polyfill-collision.test.ts +46 -0
  114. package/node_modules/zod/src/v4/core/tests/url-no-canparse.test.ts +118 -16
  115. package/node_modules/zod/src/v4/core/to-json-schema.ts +9 -7
  116. package/node_modules/zod/src/v4/core/util.ts +218 -147
  117. package/node_modules/zod/src/v4/core/versions.ts +2 -2
  118. package/node_modules/zod/src/v4/locales/ar.ts +2 -0
  119. package/node_modules/zod/src/v4/locales/az.ts +2 -0
  120. package/node_modules/zod/src/v4/locales/be.ts +2 -0
  121. package/node_modules/zod/src/v4/locales/bg.ts +2 -0
  122. package/node_modules/zod/src/v4/locales/bn.ts +2 -0
  123. package/node_modules/zod/src/v4/locales/ca.ts +2 -0
  124. package/node_modules/zod/src/v4/locales/ckb.ts +2 -0
  125. package/node_modules/zod/src/v4/locales/cs.ts +2 -0
  126. package/node_modules/zod/src/v4/locales/da.ts +2 -0
  127. package/node_modules/zod/src/v4/locales/de.ts +2 -0
  128. package/node_modules/zod/src/v4/locales/el.ts +2 -0
  129. package/node_modules/zod/src/v4/locales/en.ts +2 -0
  130. package/node_modules/zod/src/v4/locales/eo.ts +2 -0
  131. package/node_modules/zod/src/v4/locales/es.ts +2 -0
  132. package/node_modules/zod/src/v4/locales/fa.ts +2 -0
  133. package/node_modules/zod/src/v4/locales/fi.ts +2 -0
  134. package/node_modules/zod/src/v4/locales/fr-CA.ts +2 -0
  135. package/node_modules/zod/src/v4/locales/fr.ts +2 -0
  136. package/node_modules/zod/src/v4/locales/gu.ts +2 -0
  137. package/node_modules/zod/src/v4/locales/he.ts +2 -0
  138. package/node_modules/zod/src/v4/locales/hi.ts +2 -0
  139. package/node_modules/zod/src/v4/locales/hr.ts +2 -0
  140. package/node_modules/zod/src/v4/locales/hu.ts +2 -0
  141. package/node_modules/zod/src/v4/locales/hy.ts +2 -0
  142. package/node_modules/zod/src/v4/locales/id.ts +2 -0
  143. package/node_modules/zod/src/v4/locales/index.ts +1 -0
  144. package/node_modules/zod/src/v4/locales/is.ts +2 -0
  145. package/node_modules/zod/src/v4/locales/it.ts +2 -0
  146. package/node_modules/zod/src/v4/locales/ja.ts +2 -0
  147. package/node_modules/zod/src/v4/locales/ka.ts +2 -0
  148. package/node_modules/zod/src/v4/locales/km.ts +2 -0
  149. package/node_modules/zod/src/v4/locales/kn.ts +2 -0
  150. package/node_modules/zod/src/v4/locales/ko.ts +2 -0
  151. package/node_modules/zod/src/v4/locales/lt.ts +2 -0
  152. package/node_modules/zod/src/v4/locales/mk.ts +2 -0
  153. package/node_modules/zod/src/v4/locales/ms.ts +2 -0
  154. package/node_modules/zod/src/v4/locales/ne.ts +2 -0
  155. package/node_modules/zod/src/v4/locales/nl.ts +2 -0
  156. package/node_modules/zod/src/v4/locales/nn.ts +2 -0
  157. package/node_modules/zod/src/v4/locales/no.ts +2 -0
  158. package/node_modules/zod/src/v4/locales/ota.ts +2 -0
  159. package/node_modules/zod/src/v4/locales/pl.ts +2 -0
  160. package/node_modules/zod/src/v4/locales/ps.ts +2 -0
  161. package/node_modules/zod/src/v4/locales/pt-BR.ts +2 -0
  162. package/node_modules/zod/src/v4/locales/pt.ts +2 -0
  163. package/node_modules/zod/src/v4/locales/ro.ts +2 -0
  164. package/node_modules/zod/src/v4/locales/ru.ts +2 -0
  165. package/node_modules/zod/src/v4/locales/sk.ts +2 -0
  166. package/node_modules/zod/src/v4/locales/sl.ts +2 -0
  167. package/node_modules/zod/src/v4/locales/sv.ts +2 -0
  168. package/node_modules/zod/src/v4/locales/ta.ts +2 -0
  169. package/node_modules/zod/src/v4/locales/tg.ts +135 -0
  170. package/node_modules/zod/src/v4/locales/th.ts +2 -0
  171. package/node_modules/zod/src/v4/locales/tk.ts +2 -0
  172. package/node_modules/zod/src/v4/locales/tr.ts +2 -0
  173. package/node_modules/zod/src/v4/locales/uk.ts +2 -0
  174. package/node_modules/zod/src/v4/locales/ur.ts +2 -0
  175. package/node_modules/zod/src/v4/locales/uz.ts +2 -0
  176. package/node_modules/zod/src/v4/locales/vi.ts +2 -0
  177. package/node_modules/zod/src/v4/locales/yo.ts +2 -0
  178. package/node_modules/zod/src/v4/locales/zh-CN.ts +2 -0
  179. package/node_modules/zod/src/v4/locales/zh-TW.ts +2 -0
  180. package/node_modules/zod/src/v4/mini/external.ts +2 -0
  181. package/node_modules/zod/src/v4/mini/schemas.ts +32 -7
  182. package/node_modules/zod/src/v4/mini/tests/checks.test.ts +1 -1
  183. package/node_modules/zod/src/v4/mini/tests/computed.test.ts +11 -17
  184. package/node_modules/zod/src/v4/mini/tests/index.test.ts +86 -0
  185. package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +16 -0
  186. package/node_modules/zod/src/v4/mini/tests/string.test.ts +23 -0
  187. package/node_modules/zod/v3/ZodError.cjs +19 -0
  188. package/node_modules/zod/v3/errors.cjs +19 -0
  189. package/node_modules/zod/v3/external.cjs +19 -0
  190. package/node_modules/zod/v3/helpers/enumUtil.cjs +19 -0
  191. package/node_modules/zod/v3/helpers/errorUtil.cjs +20 -1
  192. package/node_modules/zod/v3/helpers/errorUtil.js +1 -1
  193. package/node_modules/zod/v3/helpers/parseUtil.cjs +19 -0
  194. package/node_modules/zod/v3/helpers/partialUtil.cjs +19 -0
  195. package/node_modules/zod/v3/helpers/typeAliases.cjs +19 -0
  196. package/node_modules/zod/v3/helpers/util.cjs +19 -0
  197. package/node_modules/zod/v3/index.cjs +19 -0
  198. package/node_modules/zod/v3/standard-schema.cjs +19 -0
  199. package/node_modules/zod/v3/types.cjs +19 -0
  200. package/node_modules/zod/v4/classic/checks.cjs +19 -0
  201. package/node_modules/zod/v4/classic/coerce.cjs +19 -0
  202. package/node_modules/zod/v4/classic/compat.cjs +19 -0
  203. package/node_modules/zod/v4/classic/deep-partial.cjs +19 -0
  204. package/node_modules/zod/v4/classic/errors.cjs +19 -0
  205. package/node_modules/zod/v4/classic/external.cjs +22 -1
  206. package/node_modules/zod/v4/classic/external.d.cts +1 -1
  207. package/node_modules/zod/v4/classic/external.d.ts +1 -1
  208. package/node_modules/zod/v4/classic/external.js +1 -1
  209. package/node_modules/zod/v4/classic/from-json-schema.cjs +264 -24
  210. package/node_modules/zod/v4/classic/from-json-schema.js +245 -24
  211. package/node_modules/zod/v4/classic/in-out.cjs +19 -0
  212. package/node_modules/zod/v4/classic/index.cjs +19 -0
  213. package/node_modules/zod/v4/classic/iso.cjs +19 -0
  214. package/node_modules/zod/v4/classic/parse.cjs +19 -0
  215. package/node_modules/zod/v4/classic/schemas.cjs +100 -35
  216. package/node_modules/zod/v4/classic/schemas.d.cts +15 -1
  217. package/node_modules/zod/v4/classic/schemas.d.ts +15 -1
  218. package/node_modules/zod/v4/classic/schemas.js +77 -33
  219. package/node_modules/zod/v4/core/api.cjs +45 -22
  220. package/node_modules/zod/v4/core/api.d.cts +12 -6
  221. package/node_modules/zod/v4/core/api.d.ts +12 -6
  222. package/node_modules/zod/v4/core/api.js +25 -22
  223. package/node_modules/zod/v4/core/checks.cjs +51 -97
  224. package/node_modules/zod/v4/core/checks.d.cts +17 -1
  225. package/node_modules/zod/v4/core/checks.d.ts +17 -1
  226. package/node_modules/zod/v4/core/checks.js +31 -96
  227. package/node_modules/zod/v4/core/compile.cjs +173 -78
  228. package/node_modules/zod/v4/core/compile.d.cts +18 -4
  229. package/node_modules/zod/v4/core/compile.d.ts +18 -4
  230. package/node_modules/zod/v4/core/compile.js +154 -79
  231. package/node_modules/zod/v4/core/core.cjs +20 -1
  232. package/node_modules/zod/v4/core/core.js +1 -1
  233. package/node_modules/zod/v4/core/doc.cjs +26 -2
  234. package/node_modules/zod/v4/core/doc.js +7 -2
  235. package/node_modules/zod/v4/core/errors.cjs +21 -5
  236. package/node_modules/zod/v4/core/errors.js +2 -5
  237. package/node_modules/zod/v4/core/index.cjs +19 -0
  238. package/node_modules/zod/v4/core/json-schema-generator.cjs +20 -1
  239. package/node_modules/zod/v4/core/json-schema-generator.js +2 -2
  240. package/node_modules/zod/v4/core/json-schema-processors.cjs +188 -72
  241. package/node_modules/zod/v4/core/json-schema-processors.d.cts +16 -0
  242. package/node_modules/zod/v4/core/json-schema-processors.d.ts +16 -0
  243. package/node_modules/zod/v4/core/json-schema-processors.js +170 -74
  244. package/node_modules/zod/v4/core/json-schema.cjs +19 -0
  245. package/node_modules/zod/v4/core/memoizer.cjs +111 -23
  246. package/node_modules/zod/v4/core/memoizer.js +69 -23
  247. package/node_modules/zod/v4/core/parse.cjs +56 -16
  248. package/node_modules/zod/v4/core/parse.js +37 -16
  249. package/node_modules/zod/v4/core/regexes.cjs +31 -6
  250. package/node_modules/zod/v4/core/regexes.d.cts +3 -0
  251. package/node_modules/zod/v4/core/regexes.d.ts +3 -0
  252. package/node_modules/zod/v4/core/regexes.js +10 -4
  253. package/node_modules/zod/v4/core/registries.cjs +19 -0
  254. package/node_modules/zod/v4/core/schemas.cjs +302 -114
  255. package/node_modules/zod/v4/core/schemas.d.cts +28 -8
  256. package/node_modules/zod/v4/core/schemas.d.ts +28 -8
  257. package/node_modules/zod/v4/core/schemas.js +279 -113
  258. package/node_modules/zod/v4/core/standard-schema.cjs +19 -0
  259. package/node_modules/zod/v4/core/to-json-schema.cjs +28 -7
  260. package/node_modules/zod/v4/core/to-json-schema.d.cts +4 -3
  261. package/node_modules/zod/v4/core/to-json-schema.d.ts +4 -3
  262. package/node_modules/zod/v4/core/to-json-schema.js +7 -6
  263. package/node_modules/zod/v4/core/util.cjs +177 -143
  264. package/node_modules/zod/v4/core/util.d.cts +25 -4
  265. package/node_modules/zod/v4/core/util.d.ts +25 -4
  266. package/node_modules/zod/v4/core/util.js +156 -143
  267. package/node_modules/zod/v4/core/versions.cjs +21 -2
  268. package/node_modules/zod/v4/core/versions.d.cts +1 -1
  269. package/node_modules/zod/v4/core/versions.d.ts +1 -1
  270. package/node_modules/zod/v4/core/versions.js +2 -2
  271. package/node_modules/zod/v4/core/visit.cjs +19 -0
  272. package/node_modules/zod/v4/index.cjs +19 -0
  273. package/node_modules/zod/v4/locales/ar.cjs +2 -0
  274. package/node_modules/zod/v4/locales/ar.js +2 -0
  275. package/node_modules/zod/v4/locales/az.cjs +2 -0
  276. package/node_modules/zod/v4/locales/az.js +2 -0
  277. package/node_modules/zod/v4/locales/be.cjs +2 -0
  278. package/node_modules/zod/v4/locales/be.js +2 -0
  279. package/node_modules/zod/v4/locales/bg.cjs +2 -0
  280. package/node_modules/zod/v4/locales/bg.js +2 -0
  281. package/node_modules/zod/v4/locales/bn.cjs +2 -0
  282. package/node_modules/zod/v4/locales/bn.js +2 -0
  283. package/node_modules/zod/v4/locales/ca.cjs +2 -0
  284. package/node_modules/zod/v4/locales/ca.js +2 -0
  285. package/node_modules/zod/v4/locales/ckb.cjs +2 -0
  286. package/node_modules/zod/v4/locales/ckb.js +2 -0
  287. package/node_modules/zod/v4/locales/cs.cjs +2 -0
  288. package/node_modules/zod/v4/locales/cs.js +2 -0
  289. package/node_modules/zod/v4/locales/da.cjs +2 -0
  290. package/node_modules/zod/v4/locales/da.js +2 -0
  291. package/node_modules/zod/v4/locales/de.cjs +2 -0
  292. package/node_modules/zod/v4/locales/de.js +2 -0
  293. package/node_modules/zod/v4/locales/el.cjs +2 -0
  294. package/node_modules/zod/v4/locales/el.js +2 -0
  295. package/node_modules/zod/v4/locales/en.cjs +2 -0
  296. package/node_modules/zod/v4/locales/en.js +2 -0
  297. package/node_modules/zod/v4/locales/eo.cjs +2 -0
  298. package/node_modules/zod/v4/locales/eo.js +2 -0
  299. package/node_modules/zod/v4/locales/es.cjs +2 -0
  300. package/node_modules/zod/v4/locales/es.js +2 -0
  301. package/node_modules/zod/v4/locales/fa.cjs +2 -0
  302. package/node_modules/zod/v4/locales/fa.js +2 -0
  303. package/node_modules/zod/v4/locales/fi.cjs +2 -0
  304. package/node_modules/zod/v4/locales/fi.js +2 -0
  305. package/node_modules/zod/v4/locales/fr-CA.cjs +2 -0
  306. package/node_modules/zod/v4/locales/fr-CA.js +2 -0
  307. package/node_modules/zod/v4/locales/fr.cjs +2 -0
  308. package/node_modules/zod/v4/locales/fr.js +2 -0
  309. package/node_modules/zod/v4/locales/gu.cjs +2 -0
  310. package/node_modules/zod/v4/locales/gu.js +2 -0
  311. package/node_modules/zod/v4/locales/he.cjs +2 -0
  312. package/node_modules/zod/v4/locales/he.js +2 -0
  313. package/node_modules/zod/v4/locales/hi.cjs +2 -0
  314. package/node_modules/zod/v4/locales/hi.js +2 -0
  315. package/node_modules/zod/v4/locales/hr.cjs +2 -0
  316. package/node_modules/zod/v4/locales/hr.js +2 -0
  317. package/node_modules/zod/v4/locales/hu.cjs +2 -0
  318. package/node_modules/zod/v4/locales/hu.js +2 -0
  319. package/node_modules/zod/v4/locales/hy.cjs +2 -0
  320. package/node_modules/zod/v4/locales/hy.js +2 -0
  321. package/node_modules/zod/v4/locales/id.cjs +2 -0
  322. package/node_modules/zod/v4/locales/id.js +2 -0
  323. package/node_modules/zod/v4/locales/index.cjs +22 -1
  324. package/node_modules/zod/v4/locales/index.d.cts +1 -0
  325. package/node_modules/zod/v4/locales/index.d.ts +1 -0
  326. package/node_modules/zod/v4/locales/index.js +1 -0
  327. package/node_modules/zod/v4/locales/is.cjs +2 -0
  328. package/node_modules/zod/v4/locales/is.js +2 -0
  329. package/node_modules/zod/v4/locales/it.cjs +2 -0
  330. package/node_modules/zod/v4/locales/it.js +2 -0
  331. package/node_modules/zod/v4/locales/ja.cjs +2 -0
  332. package/node_modules/zod/v4/locales/ja.js +2 -0
  333. package/node_modules/zod/v4/locales/ka.cjs +2 -0
  334. package/node_modules/zod/v4/locales/ka.js +2 -0
  335. package/node_modules/zod/v4/locales/km.cjs +2 -0
  336. package/node_modules/zod/v4/locales/km.js +2 -0
  337. package/node_modules/zod/v4/locales/kn.cjs +2 -0
  338. package/node_modules/zod/v4/locales/kn.js +2 -0
  339. package/node_modules/zod/v4/locales/ko.cjs +2 -0
  340. package/node_modules/zod/v4/locales/ko.js +2 -0
  341. package/node_modules/zod/v4/locales/lt.cjs +2 -0
  342. package/node_modules/zod/v4/locales/lt.js +2 -0
  343. package/node_modules/zod/v4/locales/mk.cjs +2 -0
  344. package/node_modules/zod/v4/locales/mk.js +2 -0
  345. package/node_modules/zod/v4/locales/ms.cjs +2 -0
  346. package/node_modules/zod/v4/locales/ms.js +2 -0
  347. package/node_modules/zod/v4/locales/ne.cjs +2 -0
  348. package/node_modules/zod/v4/locales/ne.js +2 -0
  349. package/node_modules/zod/v4/locales/nl.cjs +2 -0
  350. package/node_modules/zod/v4/locales/nl.js +2 -0
  351. package/node_modules/zod/v4/locales/nn.cjs +2 -0
  352. package/node_modules/zod/v4/locales/nn.js +2 -0
  353. package/node_modules/zod/v4/locales/no.cjs +2 -0
  354. package/node_modules/zod/v4/locales/no.js +2 -0
  355. package/node_modules/zod/v4/locales/ota.cjs +2 -0
  356. package/node_modules/zod/v4/locales/ota.js +2 -0
  357. package/node_modules/zod/v4/locales/pl.cjs +2 -0
  358. package/node_modules/zod/v4/locales/pl.js +2 -0
  359. package/node_modules/zod/v4/locales/ps.cjs +2 -0
  360. package/node_modules/zod/v4/locales/ps.js +2 -0
  361. package/node_modules/zod/v4/locales/pt-BR.cjs +2 -0
  362. package/node_modules/zod/v4/locales/pt-BR.js +2 -0
  363. package/node_modules/zod/v4/locales/pt.cjs +2 -0
  364. package/node_modules/zod/v4/locales/pt.js +2 -0
  365. package/node_modules/zod/v4/locales/ro.cjs +2 -0
  366. package/node_modules/zod/v4/locales/ro.js +2 -0
  367. package/node_modules/zod/v4/locales/ru.cjs +2 -0
  368. package/node_modules/zod/v4/locales/ru.js +2 -0
  369. package/node_modules/zod/v4/locales/sk.cjs +2 -0
  370. package/node_modules/zod/v4/locales/sk.js +2 -0
  371. package/node_modules/zod/v4/locales/sl.cjs +2 -0
  372. package/node_modules/zod/v4/locales/sl.js +2 -0
  373. package/node_modules/zod/v4/locales/sv.cjs +2 -0
  374. package/node_modules/zod/v4/locales/sv.js +2 -0
  375. package/node_modules/zod/v4/locales/ta.cjs +2 -0
  376. package/node_modules/zod/v4/locales/ta.js +2 -0
  377. package/node_modules/zod/v4/locales/tg.cjs +144 -0
  378. package/node_modules/zod/v4/locales/tg.d.cts +5 -0
  379. package/node_modules/zod/v4/locales/tg.d.ts +4 -0
  380. package/node_modules/zod/v4/locales/tg.js +117 -0
  381. package/node_modules/zod/v4/locales/th.cjs +2 -0
  382. package/node_modules/zod/v4/locales/th.js +2 -0
  383. package/node_modules/zod/v4/locales/tk.cjs +2 -0
  384. package/node_modules/zod/v4/locales/tk.js +2 -0
  385. package/node_modules/zod/v4/locales/tr.cjs +2 -0
  386. package/node_modules/zod/v4/locales/tr.js +2 -0
  387. package/node_modules/zod/v4/locales/uk.cjs +2 -0
  388. package/node_modules/zod/v4/locales/uk.js +2 -0
  389. package/node_modules/zod/v4/locales/ur.cjs +2 -0
  390. package/node_modules/zod/v4/locales/ur.js +2 -0
  391. package/node_modules/zod/v4/locales/uz.cjs +2 -0
  392. package/node_modules/zod/v4/locales/uz.js +2 -0
  393. package/node_modules/zod/v4/locales/vi.cjs +2 -0
  394. package/node_modules/zod/v4/locales/vi.js +2 -0
  395. package/node_modules/zod/v4/locales/yo.cjs +2 -0
  396. package/node_modules/zod/v4/locales/yo.js +2 -0
  397. package/node_modules/zod/v4/locales/zh-CN.cjs +2 -0
  398. package/node_modules/zod/v4/locales/zh-CN.js +2 -0
  399. package/node_modules/zod/v4/locales/zh-TW.cjs +2 -0
  400. package/node_modules/zod/v4/locales/zh-TW.js +2 -0
  401. package/node_modules/zod/v4/mini/checks.cjs +19 -0
  402. package/node_modules/zod/v4/mini/coerce.cjs +19 -0
  403. package/node_modules/zod/v4/mini/deep-partial.cjs +19 -0
  404. package/node_modules/zod/v4/mini/external.cjs +22 -1
  405. package/node_modules/zod/v4/mini/external.d.cts +1 -1
  406. package/node_modules/zod/v4/mini/external.d.ts +1 -1
  407. package/node_modules/zod/v4/mini/external.js +1 -1
  408. package/node_modules/zod/v4/mini/in-out.cjs +19 -0
  409. package/node_modules/zod/v4/mini/index.cjs +19 -0
  410. package/node_modules/zod/v4/mini/iso.cjs +19 -0
  411. package/node_modules/zod/v4/mini/parse.cjs +19 -0
  412. package/node_modules/zod/v4/mini/schemas.cjs +44 -8
  413. package/node_modules/zod/v4/mini/schemas.d.cts +6 -1
  414. package/node_modules/zod/v4/mini/schemas.d.ts +6 -1
  415. package/node_modules/zod/v4/mini/schemas.js +21 -6
  416. package/node_modules/zod/v4-mini/index.cjs +19 -0
  417. package/package.json +8 -5
  418. package/dist/.setup/message-handler.history-CJOsN9w5.mjs +0 -28
  419. package/dist/.setup/provider.runtime-DuhmKdDU.mjs +0 -2
  420. package/dist/.setup/setup-plugin-api-CINIEBLa.mjs +0 -3
  421. package/dist/.setup/targets-D1mAB5yO.mjs +0 -3
@@ -1,16 +1,82 @@
1
- import { a as buildProviderConfigs, i as buildProviderConfigOverrides } from "./transcripts-source-CuWYgayu.mjs";
1
+ import { a as buildProviderConfigOverrides, o as buildProviderConfigs } from "./transcripts-source-DVegW0WI.mjs";
2
+ import { S as setDiscordAudioOutputStatus, _ as getDiscordAudioOutputStatus, d as createDiscordPcmToRealtimeConverter, g as admitDiscordAudioInput, h as DiscordAudioOutputStatus, v as releaseDiscordAudioInput, y as restoreDiscordAudioError } from "./receive-recovery-DHst8WRx.mjs";
2
3
  import { n as discordRealtimeVoiceSecretOwnerId } from "./secret-config-contract-DFu9hfU8.mjs";
3
- import { _ as loadDiscordVoiceSdk, a as createDiscordPcmToRealtimeConverter, c as handleDiscordVoiceAgentControlToolCall, d as formatRealtimeInterruptionLog, f as formatRealtimeLifecycleLog, g as DiscordRealtimePlayer, h as DISCORD_REALTIME_PLAYBACK_IDLE_MS, i as createDiscordOpusEncodeStream, l as logDiscordVoiceAgentControlResult, m as shouldLogRealtimeVerboseEvent, n as DiscordRealtimeRecording, o as createRealtimePcmToDiscordConverter, p as formatVoiceLogPreview, r as logVoiceVerbose, s as formatVoiceIngressPrompt, u as maybeControlDiscordVoiceAgentRun } from "./voice-runtime-DHVQ2mFz.mjs";
4
+ import { a as handleDiscordVoiceAgentControlToolCall, c as formatRealtimeInterruptionLog, d as shouldLogRealtimeVerboseEvent, i as formatVoiceIngressPrompt, l as formatRealtimeLifecycleLog, n as DiscordRealtimeRecording, o as logDiscordVoiceAgentControlResult, r as logVoiceVerbose, s as maybeControlDiscordVoiceAgentRun, u as formatVoiceLogPreview } from "./voice-runtime-elTtjEIG.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";
8
9
  import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
9
10
  import { sliceUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
11
+ import { MessageChannel } from "node:worker_threads";
10
12
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
11
13
  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
14
  import { assertSecretOwnerAvailable, isSecretOwnerAvailable } from "openclaw/plugin-sdk/channel-secret-owner-runtime";
15
+ //#region extensions/discord/src/voice/realtime-player.ts
16
+ /** Room-level policy stays on main; the worker owns the physical player and FIFO. */
17
+ var DiscordRealtimePlayer = class {
18
+ constructor(audio) {
19
+ this.audio = audio;
20
+ this.lanes = /* @__PURE__ */ new Set();
21
+ this.outputs = /* @__PURE__ */ new Map();
22
+ this.closed = false;
23
+ this.onEvent = (event) => {
24
+ if (event.type === "output-start" || event.type === "continuous-start") this.current = event.id;
25
+ if ((event.type === "output-close" || event.type === "continuous-idle") && this.current === event.id) this.current = void 0;
26
+ };
27
+ audio.on("event", this.onEvent);
28
+ }
29
+ registerLane(lane) {
30
+ this.lanes.add(lane);
31
+ return () => this.lanes.delete(lane);
32
+ }
33
+ registerOutput(id, onBargeIn) {
34
+ this.outputs.set(id, onBargeIn);
35
+ return () => {
36
+ this.outputs.delete(id);
37
+ if (this.current === id) this.current = void 0;
38
+ };
39
+ }
40
+ handleBargeIn(reason = "barge-in") {
41
+ const current = this.current === void 0 ? void 0 : this.outputs.get(this.current);
42
+ if (current) return current(reason);
43
+ let interrupted = false;
44
+ for (const lane of [...this.lanes].filter((candidate) => candidate.hasOutput())) interrupted = lane.onBargeIn(reason) || interrupted;
45
+ return interrupted;
46
+ }
47
+ isActive() {
48
+ return this.current !== void 0 || [...this.lanes].some((lane) => lane.hasOutput());
49
+ }
50
+ cancelForControl() {
51
+ this.transition(() => {
52
+ for (const lane of this.lanes) lane.cancelForControl();
53
+ });
54
+ }
55
+ transition(action) {
56
+ this.audio.send({
57
+ type: "output-hold",
58
+ hold: true
59
+ });
60
+ try {
61
+ action();
62
+ } finally {
63
+ this.audio.send({
64
+ type: "output-hold",
65
+ hold: false
66
+ });
67
+ }
68
+ }
69
+ close() {
70
+ if (this.closed) return;
71
+ this.closed = true;
72
+ this.lanes.clear();
73
+ this.outputs.clear();
74
+ this.current = void 0;
75
+ this.audio.off("event", this.onEvent);
76
+ this.audio.send({ type: "output-shutdown" });
77
+ }
78
+ };
79
+ //#endregion
14
80
  //#region extensions/discord/src/voice/realtime-transcript.ts
15
81
  const PARTIAL_TRANSCRIPT_MAX_CHARS = 240;
16
82
  function mergeRealtimePartialTranscript(previous, next) {
@@ -21,7 +87,7 @@ function mergeRealtimePartialTranscript(previous, next) {
21
87
  }
22
88
  //#endregion
23
89
  //#region extensions/discord/src/voice/realtime-turns.ts
24
- const logger$5 = createSubsystemLogger("discord/voice");
90
+ const logger$4 = createSubsystemLogger("discord/voice");
25
91
  const DISCORD_REALTIME_WAKE_NAME_FOLLOWUP_TTL_MS = 1e4;
26
92
  const REALTIME_PCM16_BYTES_PER_SAMPLE = 2;
27
93
  const DISCORD_REALTIME_TRAILING_SILENCE_MIN_MS = 700;
@@ -100,11 +166,11 @@ var DiscordRealtimeTurns = class {
100
166
  const pendingWakeNameFollowup = this.consumePendingWakeNameFollowup();
101
167
  if (!pendingWakeNameFollowup) {
102
168
  this.consumePendingSpeakerContext();
103
- logger$5.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"}`);
169
+ 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
170
  return;
105
171
  }
106
172
  forcedSpeakerContext = pendingWakeNameFollowup;
107
- logger$5.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}`);
173
+ 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
174
  }
109
175
  const acceptedText = wakeNameResult.allowed ? wakeNameResult.text || trimmed : trimmed;
110
176
  if (wakeNameResult.allowed && !wakeNameResult.text.trim()) {
@@ -157,11 +223,11 @@ var DiscordRealtimeTurns = class {
157
223
  this.registerSpeakerTurnAudioStarted(turn);
158
224
  turn.inputRealtimeBytes += realtimePcm.length;
159
225
  turn.inputChunks += 1;
160
- if (turn.inputChunks === 1) logger$5.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()}`);
226
+ 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
227
  if (!turn.interruptedPlayback && isRealtimeVoiceAudioAudible(discordPcm48kStereo, REALTIME_VOICE_AUDIO_FORMAT_PCM16_24KHZ) && isRealtimeVoiceAudioAudible(realtimePcm, REALTIME_VOICE_AUDIO_FORMAT_PCM16_24KHZ) && this.params.interruptRoomPlayback()) {
162
228
  turn.interruptedPlayback = true;
163
229
  logVoiceVerbose(`realtime barge-in from active speaker audio: guild ${this.params.entry.guildId} channel ${this.params.entry.channelId} user ${turn.context.userId}`);
164
- logger$5.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}`);
230
+ 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
231
  }
166
232
  if (this.params.recordInputAudio(realtimePcm) && this.isTurnProviderCurrent(turn)) bridge.sendAudio(realtimePcm);
167
233
  }
@@ -175,13 +241,13 @@ var DiscordRealtimeTurns = class {
175
241
  turn.lastAudioAt = Date.now();
176
242
  if (turn.hasAudio) return;
177
243
  turn.hasAudio = true;
178
- logger$5.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}`);
244
+ 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
245
  }
180
246
  logSpeakerTurnClosed(turn) {
181
247
  if (turn.closed || !turn.hasAudio) return;
182
248
  const elapsedMs = Date.now() - turn.startedAt;
183
249
  const sinceLastAudioMs = turn.lastAudioAt ? Date.now() - turn.lastAudioAt : void 0;
184
- logger$5.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}`);
250
+ 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
251
  }
186
252
  sendRealtimeTrailingSilenceForTurn(turn) {
187
253
  const bridge = turn.bridge;
@@ -192,7 +258,7 @@ var DiscordRealtimeTurns = class {
192
258
  const silenceBytes = Math.ceil(24e3 * silenceMs / 1e3) * REALTIME_PCM16_BYTES_PER_SAMPLE;
193
259
  const silence = Buffer.alloc(silenceBytes);
194
260
  bridge.sendAudio(silence);
195
- logger$5.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}`);
261
+ 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
262
  }
197
263
  resolveWakeNameTranscript(text, requireWakeName) {
198
264
  if (!requireWakeName) return {
@@ -205,7 +271,7 @@ var DiscordRealtimeTurns = class {
205
271
  };
206
272
  const wakeNameResult = matchRealtimeVoiceActivationName(text, this.params.wakeNames());
207
273
  if (wakeNameResult) {
208
- logger$5.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}`);
274
+ 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
275
  return wakeNameResult;
210
276
  }
211
277
  return {
@@ -219,7 +285,7 @@ var DiscordRealtimeTurns = class {
219
285
  armWakeNameFollowup() {
220
286
  const context = this.consumePendingSpeakerContext();
221
287
  if (!context) {
222
- logger$5.warn(`discord voice: realtime wake-name follow-up has no speaker context voiceSession=${this.params.entry.voiceSessionKey} agent=${this.params.entry.route.agentId}`);
288
+ 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
289
  return;
224
290
  }
225
291
  const expiresAt = resolveExpiresAtMsFromDurationMs(DISCORD_REALTIME_WAKE_NAME_FOLLOWUP_TTL_MS);
@@ -228,7 +294,7 @@ var DiscordRealtimeTurns = class {
228
294
  context,
229
295
  expiresAt
230
296
  };
231
- logger$5.info(`discord voice: realtime wake-name follow-up armed speaker=${context.speakerLabel} voiceSession=${this.params.entry.voiceSessionKey} agent=${this.params.entry.route.agentId}`);
297
+ 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
298
  }
233
299
  consumePendingWakeNameFollowup() {
234
300
  const pending = this.pendingWakeNameFollowup;
@@ -245,7 +311,7 @@ function isDiscordRealtimeSpeakerContext(value) {
245
311
  }
246
312
  //#endregion
247
313
  //#region extensions/discord/src/voice/realtime-consults.ts
248
- const logger$4 = createSubsystemLogger("discord/voice");
314
+ const logger$3 = createSubsystemLogger("discord/voice");
249
315
  const DISCORD_REALTIME_TALKBACK_DEBOUNCE_MS = 350;
250
316
  const DISCORD_REALTIME_FALLBACK_TEXT = "I hit an error while checking that. Please try again.";
251
317
  const DISCORD_REALTIME_FORCED_CONSULT_FALLBACK_DELAY_MS = 200;
@@ -318,16 +384,16 @@ var DiscordRealtimeConsults = class {
318
384
  const outcome = classifyRealtimeVoiceConsultToolCall(event.args, { retainedExactSpeechTexts: this.params.playback.retainedExactSpeechTexts() });
319
385
  switch (outcome.kind) {
320
386
  case "exact-speech-echo":
321
- logger$4.info(`discord voice: realtime exact speech consult bypassed call=${callId || "unknown"} answerChars=${outcome.text.length}`);
387
+ logger$3.info(`discord voice: realtime exact speech consult bypassed call=${callId || "unknown"} answerChars=${outcome.text.length}`);
322
388
  await session.submitToolResult(callId, { text: outcome.text });
323
389
  return;
324
390
  case "malformed":
325
- logger$4.warn(`discord voice: realtime consult rejected malformed args call=${callId || "unknown"}: ${outcome.error}`);
391
+ logger$3.warn(`discord voice: realtime consult rejected malformed args call=${callId || "unknown"}: ${outcome.error}`);
326
392
  await session.submitToolResult(callId, { error: outcome.error });
327
393
  return;
328
394
  }
329
395
  const consultMessage = outcome.message;
330
- logger$4.info(`discord voice: realtime consult requested call=${callId || "unknown"} voiceSession=${this.params.entry.voiceSessionKey} supervisorSession=${this.params.entry.route.sessionKey} agent=${this.params.entry.route.agentId} question=${formatVoiceLogPreview(consultMessage)}`);
396
+ logger$3.info(`discord voice: realtime consult requested call=${callId || "unknown"} voiceSession=${this.params.entry.voiceSessionKey} supervisorSession=${this.params.entry.route.sessionKey} agent=${this.params.entry.route.agentId} question=${formatVoiceLogPreview(consultMessage)}`);
331
397
  const nativeConsult = this.params.harness.forcedConsults.recordNativeConsult(event.args, callId);
332
398
  if (nativeConsult.kind === "already_delivered" && this.params.harness.forcedConsults.isCancelled(nativeConsult.handle)) {
333
399
  await this.submitTerminalRealtimeToolResult(callId, session, CANCELLED_CONSULT_RESULT);
@@ -342,7 +408,7 @@ var DiscordRealtimeConsults = class {
342
408
  if (recentConsult) {
343
409
  const recentSpeaker = recentConsult.context?.speaker;
344
410
  if (this.params.turns.hasPendingSpeakerAudioContext()) {
345
- logger$4.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}`);
411
+ 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
412
  await session.submitToolResult(callId, { error: "Discord speaker context changed before this realtime consult completed" });
347
413
  return;
348
414
  }
@@ -358,7 +424,7 @@ var DiscordRealtimeConsults = class {
358
424
  }
359
425
  const state = recent?.context;
360
426
  if (!context || !state) {
361
- logger$4.warn(`discord voice: realtime consult has no speaker context call=${callId || "unknown"}`);
427
+ logger$3.warn(`discord voice: realtime consult has no speaker context call=${callId || "unknown"}`);
362
428
  await session.submitToolResult(callId, { error: "No Discord speaker context available" });
363
429
  return;
364
430
  }
@@ -371,8 +437,8 @@ var DiscordRealtimeConsults = class {
371
437
  deliveryOwner: "consult"
372
438
  }));
373
439
  if (this.params.stopped() || providerEpoch !== this.params.providerEpoch()) return;
374
- if ("text" in result) logger$4.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)}`);
375
- else if ("error" in result) logger$4.warn(`discord voice: realtime consult failed call=${callId}: ${result.error}`);
440
+ 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)}`);
441
+ else if ("error" in result) logger$3.warn(`discord voice: realtime consult failed call=${callId}: ${result.error}`);
376
442
  delivery.submissionStarted = true;
377
443
  await this.submitAgentProxyConsultResult(callId, session, result);
378
444
  if (state.delivery === "provider-pending") state.delivery = "provider";
@@ -394,10 +460,10 @@ var DiscordRealtimeConsults = class {
394
460
  if (this.params.stopped() || providerEpoch !== this.params.providerEpoch()) return;
395
461
  if (readErrorName(error) === "AbortError") {
396
462
  if (pendingForcedConsult) this.params.harness.forcedConsults.remove(pendingForcedConsult);
397
- logger$4.warn(`discord voice: realtime transcript cancelled: ${formatErrorMessage$1(error)}`);
463
+ logger$3.warn(`discord voice: realtime transcript cancelled: ${formatErrorMessage$1(error)}`);
398
464
  return;
399
465
  }
400
- logger$4.warn(`discord voice: realtime active-run control failed; falling back to normal transcript handling: ${formatErrorMessage$1(error)}`);
466
+ logger$3.warn(`discord voice: realtime active-run control failed; falling back to normal transcript handling: ${formatErrorMessage$1(error)}`);
401
467
  control = void 0;
402
468
  }
403
469
  if (this.params.stopped() || providerEpoch !== this.params.providerEpoch()) return;
@@ -419,7 +485,7 @@ var DiscordRealtimeConsults = class {
419
485
  return createRealtimeVoiceAgentTalkbackQueue({
420
486
  debounceMs: this.params.debounceMs() ?? DISCORD_REALTIME_TALKBACK_DEBOUNCE_MS,
421
487
  isStopped: () => this.params.stopped() || providerEpoch !== this.params.providerEpoch(),
422
- logger: logger$4,
488
+ logger: logger$3,
423
489
  logPrefix: "[discord] realtime agent",
424
490
  responseStyle: "Brief, natural spoken answer for a Discord voice channel.",
425
491
  fallbackText: DISCORD_REALTIME_FALLBACK_TEXT,
@@ -468,7 +534,7 @@ var DiscordRealtimeConsults = class {
468
534
  const skipReason = classifySkippableRealtimeVoiceConsultTranscript(question);
469
535
  if (skipReason) {
470
536
  const context = this.params.turns.consumePendingSpeakerContext();
471
- logger$4.info(`discord voice: realtime forced agent consult skipped reason=${skipReason} chars=${question.length} speaker=${context?.speakerLabel ?? "unknown"} transcript=${formatVoiceLogPreview(question)}`);
537
+ logger$3.info(`discord voice: realtime forced agent consult skipped reason=${skipReason} chars=${question.length} speaker=${context?.speakerLabel ?? "unknown"} transcript=${formatVoiceLogPreview(question)}`);
472
538
  return;
473
539
  }
474
540
  const context = speakerContext ?? this.params.turns.consumePendingSpeakerContext();
@@ -478,7 +544,7 @@ var DiscordRealtimeConsults = class {
478
544
  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
545
  return;
480
546
  }
481
- logger$4.warn("discord voice: realtime forced agent consult has no speaker context");
547
+ logger$3.warn("discord voice: realtime forced agent consult has no speaker context");
482
548
  return;
483
549
  }
484
550
  return this.params.harness.forcedConsults.prepare(question, { context: {
@@ -504,9 +570,9 @@ var DiscordRealtimeConsults = class {
504
570
  return;
505
571
  }
506
572
  const startedAt = Date.now();
507
- logger$4.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}`);
508
- logger$4.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}`);
509
- if (this.params.playback.hasInterruptibleOutputAudio()) logger$4.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}`);
573
+ 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}`);
574
+ 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}`);
575
+ 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
576
  state.delivery = "forced-pending";
511
577
  const result = await this.trackAgentProxyConsult(pending, this.runAgentTurn({
512
578
  context,
@@ -516,8 +582,8 @@ var DiscordRealtimeConsults = class {
516
582
  const deliveries = this.providerDeliveries.get(state);
517
583
  await Promise.all(Array.from(deliveries ?? [], (delivery) => delivery.promise));
518
584
  if (state.providerEpoch !== this.params.providerEpoch() || "status" in result) return;
519
- if ("text" in result) logger$4.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)}`);
520
- else logger$4.warn(`discord voice: realtime forced agent consult failed elapsedMs=${Date.now() - startedAt}: ${result.error}`);
585
+ 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)}`);
586
+ else logger$3.warn(`discord voice: realtime forced agent consult failed elapsedMs=${Date.now() - startedAt}: ${result.error}`);
521
587
  const text = "text" in result ? result.text : DISCORD_REALTIME_FALLBACK_TEXT;
522
588
  if (text.trim() && state.delivery === "forced-pending") {
523
589
  state.delivery = "playback";
@@ -569,7 +635,7 @@ var DiscordRealtimeConsults = class {
569
635
  const pendingResult = state.result ?? state.promise;
570
636
  if (!pendingResult) return false;
571
637
  const providerDelivery = state.delivery === "provider-pending" || state.delivery === "forced-pending" && !state.result && session.bridge.supportsToolResultSuppression === false ? this.beginProviderDelivery(state) : void 0;
572
- logger$4.info(`discord voice: realtime consult ${state.result ? "reused recent" : "joined in-flight"} agent result call=${callId} speaker=${state.speaker.speakerLabel} owner=${state.speaker.senderIsOwner}`);
638
+ 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
639
  try {
574
640
  const result = await pendingResult;
575
641
  if (this.params.stopped() || state.providerEpoch !== this.params.providerEpoch() || state.delivery === "detached" || state.delivery === "retired") return true;
@@ -629,286 +695,156 @@ var DiscordRealtimeConsults = class {
629
695
  };
630
696
  //#endregion
631
697
  //#region extensions/discord/src/voice/realtime-output.ts
632
- const logger$3 = createSubsystemLogger("discord/voice");
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. */
698
+ /** Main retains provider item identity; physical output state belongs to the worker. */
640
699
  var DiscordRealtimeOutput = class {
700
+ get activity() {
701
+ if (Atomics.load(this.clock, 2) !== 0n && !this.activityTracker.snapshot().playbackStarted) this.activityTracker.markPlaybackStarted();
702
+ return this.activityTracker;
703
+ }
641
704
  constructor(params) {
642
705
  this.params = params;
643
- this.activity = createRealtimeVoiceOutputActivityTracker();
644
- this.converter = createRealtimePcmToDiscordConverter();
645
- this.stream = new PassThrough({ highWaterMark: DISCORD_RAW_PCM_FRAME_BYTES * 128 });
646
- this.ready = false;
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;
706
+ this.activityTracker = createRealtimeVoiceOutputActivityTracker();
707
+ this.clock = new BigInt64Array(new SharedArrayBuffer(24));
708
+ this.marks = /* @__PURE__ */ new Map();
709
+ this.nextMark = 0;
654
710
  this.closed = false;
655
- this.failed = false;
656
- this.stream.once("close", () => {
657
- if (!this.activity.snapshot().playbackStarted) this.close("stream-close");
711
+ this.reportedPlaybackMs = 0;
712
+ this.spans = [];
713
+ this.onEvent = (event) => {
714
+ if (!("id" in event) || event.id !== this.id || this.closed) return;
715
+ switch (event.type) {
716
+ case "output-start":
717
+ this.activity.markPlaybackStarted();
718
+ this.params.onStart();
719
+ break;
720
+ case "output-close":
721
+ this.retire(event.reason);
722
+ break;
723
+ case "output-error":
724
+ this.params.onError(restoreDiscordAudioError(event.error));
725
+ break;
726
+ case "output-mark": {
727
+ const acknowledge = this.marks.get(event.markId);
728
+ this.marks.delete(event.markId);
729
+ try {
730
+ acknowledge?.();
731
+ } catch (error) {
732
+ this.params.onError(error);
733
+ }
734
+ break;
735
+ }
736
+ }
737
+ };
738
+ this.onStopped = () => {
739
+ if (!this.closed) {
740
+ this.params.onError(/* @__PURE__ */ new Error("Discord audio worker stopped during playback."));
741
+ this.retire("worker-stopped");
742
+ }
743
+ };
744
+ this.id = params.player.audio.allocateId();
745
+ this.unregister = params.player.registerOutput(this.id, params.onBargeIn);
746
+ params.player.audio.on("event", this.onEvent);
747
+ params.player.audio.on("stopped", this.onStopped);
748
+ params.player.audio.send({
749
+ type: "output-create",
750
+ id: this.id,
751
+ continuous: params.continuous,
752
+ clock: this.clock.buffer
658
753
  });
659
754
  }
755
+ playedBytes() {
756
+ return Number(Atomics.load(this.clock, 0));
757
+ }
660
758
  pendingBytes() {
661
- return this.closed ? 0 : Math.max(0, this.activity.snapshot().sourceAudioBytes * 4 - this.playedPcmBytes);
759
+ return this.closed ? 0 : Math.max(0, this.activity.snapshot().sourceAudioBytes * 4 - this.playedBytes());
662
760
  }
663
761
  isAcceptingAudio() {
664
- return !this.closed && !this.activity.snapshot().streamEnding && (!this.request || !this.params.player.isRetiring(this.request));
665
- }
666
- hasUnplayedAudibleAudio() {
667
- return !this.closed && this.playedPcmBytes < this.lastAudiblePcmEndBytes;
762
+ return !this.closed && !this.activity.snapshot().streamEnding && getDiscordAudioOutputStatus(this.clock) < DiscordAudioOutputStatus.Retiring;
668
763
  }
669
764
  playbackItems() {
670
- const playedMs = Math.min(this.playedPcmBytes / DISCORD_RAW_PCM_BYTES_PER_MS, this.activity.snapshot().audioMs);
671
- for (const span of this.audioSpans) span.item.audioEndMs += Math.max(0, Math.min(playedMs, span.endMs) - Math.max(this.reportedPlaybackMs, span.startMs));
765
+ const playedMs = Math.min(this.playedBytes() / 192, this.activity.snapshot().audioMs);
766
+ for (const span of this.spans) span.item.audioEndMs += Math.max(0, Math.min(playedMs, span.endMs) - Math.max(this.reportedPlaybackMs, span.startMs));
672
767
  this.reportedPlaybackMs = playedMs;
673
- return this.audioSpans.filter(({ endMs }) => endMs > playedMs).map(({ item }) => item);
768
+ return this.spans.filter(({ endMs }) => endMs > playedMs).map(({ item }) => item);
674
769
  }
675
770
  markPlayback(acknowledge) {
676
- if (!this.closed) this.playbackMarks.push({
677
- endBytes: this.activity.snapshot().sinkAudioBytes,
678
- acknowledge
771
+ if (this.closed) return;
772
+ const markId = ++this.nextMark;
773
+ this.marks.set(markId, acknowledge);
774
+ this.params.player.audio.send({
775
+ type: "output-mark",
776
+ id: this.id,
777
+ markId
679
778
  });
680
779
  }
681
- append(sourcePcm, audible, item) {
682
- if (this.closed) return;
780
+ append(audio, audible, item, onAccepted) {
781
+ if (this.closed || this.activity.snapshot().streamEnding || !admitDiscordAudioInput(this.clock)) return false;
782
+ try {
783
+ onAccepted();
784
+ } catch (error) {
785
+ releaseDiscordAudioInput(this.clock);
786
+ throw error;
787
+ }
788
+ if (this.closed) {
789
+ releaseDiscordAudioInput(this.clock);
790
+ return true;
791
+ }
683
792
  const previous = this.activity.snapshot();
684
- const sinkBytes = Math.floor((previous.sourceAudioBytes + sourcePcm.length) / 2) * 8;
685
- const audioMs = (sinkBytes - previous.sinkAudioBytes) / DISCORD_RAW_PCM_BYTES_PER_MS;
686
- const startMs = previous.audioMs;
793
+ const sinkBytes = Math.floor((previous.sourceAudioBytes + audio.length) / 2) * 8;
794
+ const audioMs = (sinkBytes - previous.sinkAudioBytes) / 192;
687
795
  if (item) {
688
- const previousSpan = this.audioSpans.at(-1);
689
- const endMs = startMs + audioMs;
690
- if (previousSpan?.item === item && previousSpan.endMs === startMs) previousSpan.endMs = endMs;
691
- else this.audioSpans.push({
796
+ const last = this.spans.at(-1);
797
+ if (last?.item === item && last.endMs === previous.audioMs) last.endMs += audioMs;
798
+ else this.spans.push({
692
799
  item,
693
- startMs,
694
- endMs
800
+ startMs: previous.audioMs,
801
+ endMs: previous.audioMs + audioMs
695
802
  });
696
803
  }
697
804
  this.activity.markAudio({
698
805
  audioMs,
699
- sourceAudioBytes: sourcePcm.length,
806
+ sourceAudioBytes: audio.length,
700
807
  sinkAudioBytes: sinkBytes - previous.sinkAudioBytes
701
808
  });
702
- if (audible) {
703
- this.clearSilenceTimer();
704
- this.silentSince = void 0;
705
- this.lastAudiblePcmEndBytes = this.activity.snapshot().sinkAudioBytes;
706
- }
707
- this.writeConverted(this.converter.process(sourcePcm));
708
- this.scheduleSilenceRetirement();
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;
809
+ this.params.player.audio.send({
810
+ type: "output-audio",
811
+ id: this.id,
812
+ audio,
813
+ audible
814
+ });
815
+ return true;
728
816
  }
729
817
  finish(reason, playBuffered) {
730
818
  if (this.closed) return;
731
- this.clearSilenceTimer();
732
- if (playBuffered) this.writeConverted(this.converter.flush());
733
819
  this.activity.markStreamEnding();
734
- const activity = this.activity.snapshot();
735
- logger$3.info(`discord voice: realtime audio playback finishing reason=${reason} ${this.params.logContext} audioMs=${Math.floor(activity.audioMs)} chunks=${activity.chunks}`);
736
- if (!playBuffered) {
737
- this.close(reason);
738
- return;
739
- }
740
- this.startPlayback();
741
- if (this.activity.snapshot().playbackStarted) {
742
- this.scheduleWatchdog(reason);
743
- if (!this.drainHandler) this.stream.end();
744
- }
820
+ if (!playBuffered) setDiscordAudioOutputStatus(this.clock, DiscordAudioOutputStatus.Closed);
821
+ this.params.player.audio.send({
822
+ type: "output-finish",
823
+ id: this.id,
824
+ reason,
825
+ playBuffered
826
+ });
827
+ if (!playBuffered) this.retire(reason);
745
828
  }
746
829
  close(reason) {
747
830
  if (this.closed) return;
748
- const playbackRetirement = reason === "player-idle" || reason === "output-pipeline-error" || reason === "playback-watchdog";
749
- const heardMarks = playbackRetirement ? this.playbackMarks.filter((mark) => mark.endBytes <= this.playedPcmBytes) : [];
750
- const lostPlaybackMarks = playbackRetirement && this.playbackMarks.some((mark) => mark.endBytes > this.playedPcmBytes);
751
- this.closed = true;
752
- this.clearSilenceTimer();
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;
811
- });
812
- pipeline(this.stream, opusStream, (error) => {
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;
843
- }
844
- acknowledgePlayedMarks() {
845
- try {
846
- while (!this.closed) {
847
- const mark = this.playbackMarks[0];
848
- if (!mark || mark.endBytes > this.playedPcmBytes) return;
849
- this.playbackMarks.shift();
850
- mark.acknowledge();
851
- }
852
- } catch (error) {
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
831
+ setDiscordAudioOutputStatus(this.clock, DiscordAudioOutputStatus.Closed);
832
+ this.params.player.audio.send({
833
+ type: "output-close",
834
+ id: this.id,
835
+ reason
901
836
  });
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);
837
+ this.retire(reason);
908
838
  }
909
- clearWatchdog() {
910
- clearTimeout(this.watchdog);
911
- this.watchdog = void 0;
839
+ retire(reason) {
840
+ if (this.closed) return;
841
+ this.playbackItems();
842
+ this.closed = true;
843
+ this.marks.clear();
844
+ this.params.player.audio.off("event", this.onEvent);
845
+ this.params.player.audio.off("stopped", this.onStopped);
846
+ this.unregister();
847
+ this.params.onClose(this, reason);
912
848
  }
913
849
  };
914
850
  //#endregion
@@ -930,12 +866,14 @@ function normalizeControlSpeechText(text) {
930
866
  var DiscordRealtimePlayback = class {
931
867
  constructor(params) {
932
868
  this.params = params;
869
+ this.outputClearGeneration = 0;
933
870
  this.outputs = /* @__PURE__ */ new Set();
934
871
  this.generatingItems = /* @__PURE__ */ new Map();
935
872
  this.responseAudio = "completed";
936
873
  this.queuedExactSpeechMessages = [];
937
874
  this.retainedSpeechClosed = false;
938
875
  this.exactSpeechState = { status: "idle" };
876
+ this.nextExactSpeechEpoch = 0n;
939
877
  this.wakeNameAckIndex = 0;
940
878
  this.unregisterPlayerLane = this.params.player.registerLane({
941
879
  hasOutput: () => this.isOutputAudioActive(),
@@ -943,16 +881,77 @@ var DiscordRealtimePlayback = class {
943
881
  cancelForControl: () => this.cancelForControl()
944
882
  });
945
883
  }
884
+ /** Only continuous provider media uses this generation-scoped, PCM24k mono port. */
885
+ createOutputAudioPort(enabled = true) {
886
+ this.directOutput?.close();
887
+ const { port1, port2 } = new MessageChannel();
888
+ const id = this.params.entry.audio.allocateId();
889
+ const state = new Int32Array(new SharedArrayBuffer(4));
890
+ const clock = new BigInt64Array(new SharedArrayBuffer(24));
891
+ const unregister = this.params.player.registerOutput(id, (reason) => this.handleBargeIn(reason));
892
+ const onEvent = (event) => {
893
+ if (!("id" in event) || event.id !== id || this.directOutput?.id !== id) return;
894
+ if ((event.type === "continuous-start" || event.type === "continuous-idle") && this.exactSpeechState.status === "active" && this.exactSpeechState.direct && event.speechEpoch !== this.exactSpeechState.direct.epoch) return;
895
+ if (event.type === "continuous-error") this.stopAfterPlaybackFailure("direct-output-error", restoreDiscordAudioError(event.error));
896
+ if (event.type === "continuous-start") this.params.harness.outputActivity.markPlaybackStarted();
897
+ if (event.type === "continuous-flushed" && event.marker === this.pendingDirectCompletion) {
898
+ this.pendingDirectCompletion = void 0;
899
+ this.responseAudio = "completed";
900
+ this.completeExactSpeechResponse("provider-completed");
901
+ }
902
+ if (event.type === "continuous-idle") {
903
+ this.responseAudio = "completed";
904
+ this.params.harness.finishOutputAudio("player-idle");
905
+ this.params.harness.outputActivity.reset();
906
+ this.completeExactSpeechResponse("player-idle");
907
+ }
908
+ };
909
+ const close = () => {
910
+ Atomics.store(state, 0, 1);
911
+ this.params.entry.audio.off("event", onEvent);
912
+ unregister();
913
+ this.params.entry.audio.send({
914
+ type: "continuous-close",
915
+ id
916
+ });
917
+ if (this.directOutput?.id === id) this.directOutput = void 0;
918
+ };
919
+ this.directOutput = {
920
+ id,
921
+ clock,
922
+ close
923
+ };
924
+ this.params.entry.audio.on("event", onEvent);
925
+ this.params.entry.audio.send({
926
+ type: "continuous-port",
927
+ id,
928
+ enabled,
929
+ port: port1,
930
+ state: state.buffer,
931
+ clock: clock.buffer
932
+ }, [port1]);
933
+ return {
934
+ port: port2,
935
+ state: state.buffer
936
+ };
937
+ }
938
+ activateOutputAudioPort() {
939
+ if (this.directOutput) this.params.entry.audio.send({
940
+ type: "continuous-activate",
941
+ id: this.directOutput.id
942
+ });
943
+ }
946
944
  close(preserveUnplayedSpeech = false) {
947
945
  this.unregisterPlayerLane();
948
- if (preserveUnplayedSpeech) this.requeueUnplayedExactSpeech();
946
+ if (preserveUnplayedSpeech) this.retireExactSpeech(true);
949
947
  else {
950
948
  this.retainedSpeechClosed = true;
951
949
  this.speechSuccessor = void 0;
952
950
  this.queuedExactSpeechMessages = [];
953
- this.exactSpeechState = { status: "idle" };
951
+ this.retireExactSpeech();
954
952
  }
955
953
  this.clearOutputAudio("session-close");
954
+ this.directOutput?.close();
956
955
  }
957
956
  transferPendingSpeechTo(target) {
958
957
  this.speechSuccessor = target;
@@ -970,13 +969,14 @@ var DiscordRealtimePlayback = class {
970
969
  return false;
971
970
  }
972
971
  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}`);
972
+ const clearGeneration = this.outputClearGeneration;
973
973
  const bridge = this.params.bridge();
974
974
  const outputs = Array.from(this.outputs);
975
975
  const items = Array.from(this.generatingItems.values());
976
976
  this.params.harness.handleBargeIn({ audioPlaybackActive: true }, () => {
977
977
  if (!bridge?.bridge.handleBargeIn) this.clearOutputAudio(reason);
978
978
  });
979
- return outputs.some((output) => !this.outputs.has(output)) || items.some((item) => this.generatingItems.get(item.itemId) !== item);
979
+ return clearGeneration !== this.outputClearGeneration || outputs.some((output) => !this.outputs.has(output)) || items.some((item) => this.generatingItems.get(item.itemId) !== item);
980
980
  }
981
981
  isBargeInEnabled() {
982
982
  if (this.params.wakeNameRequired()) return false;
@@ -1043,10 +1043,15 @@ var DiscordRealtimePlayback = class {
1043
1043
  this.generatingItems.set(metadata.itemId, item);
1044
1044
  }
1045
1045
  }
1046
- this.params.harness.recordOutputAudio(realtimePcm24kMono, activity);
1047
- output.append(realtimePcm24kMono, audible, item);
1046
+ const onAccepted = () => this.params.harness.recordOutputAudio(realtimePcm24kMono, activity);
1047
+ if (!output.append(realtimePcm24kMono, audible, item, onAccepted)) {
1048
+ this.generatingOutput = void 0;
1049
+ this.sendOutputAudio(realtimePcm24kMono, metadata);
1050
+ }
1048
1051
  }
1049
1052
  clearOutputAudio(reason = "clear") {
1053
+ this.outputClearGeneration += 1;
1054
+ this.retireExactSpeech();
1050
1055
  if (this.isContinuousOutput()) this.responseAudio = "completed";
1051
1056
  else if (this.responseAudio === "accepting") this.responseAudio = "discarding";
1052
1057
  this.generatingOutput = void 0;
@@ -1055,9 +1060,26 @@ var DiscordRealtimePlayback = class {
1055
1060
  this.outputs.clear();
1056
1061
  for (const output of outputs.toReversed()) output.close(reason);
1057
1062
  this.params.harness.outputActivity.reset();
1063
+ if (this.directOutput) {
1064
+ if (reason === "session-close" || this.params.stopped()) this.directOutput.close();
1065
+ else this.params.entry.audio.send({
1066
+ type: "continuous-clear",
1067
+ id: this.directOutput.id
1068
+ });
1069
+ }
1058
1070
  this.completeExactSpeechResponse(reason);
1059
1071
  }
1060
1072
  handleResponseDone(outcome) {
1073
+ if (this.directOutput && outcome.status === "completed") {
1074
+ const marker = this.params.entry.audio.allocateId();
1075
+ this.pendingDirectCompletion = marker;
1076
+ this.params.entry.audio.send({
1077
+ type: "continuous-flush",
1078
+ id: this.directOutput.id,
1079
+ marker
1080
+ });
1081
+ return;
1082
+ }
1061
1083
  const output = this.generatingOutput;
1062
1084
  this.generatingOutput = void 0;
1063
1085
  this.generatingItems.clear();
@@ -1122,8 +1144,12 @@ var DiscordRealtimePlayback = class {
1122
1144
  }
1123
1145
  cancelForControl() {
1124
1146
  this.queuedExactSpeechMessages = [];
1125
- this.exactSpeechState = { status: "idle" };
1126
- if (this.responseAudio === "completed" && this.outputs.size === 0) return;
1147
+ this.retireExactSpeech();
1148
+ if (this.responseAudio === "completed" && !this.isOutputAudioActive()) return;
1149
+ if (this.isContinuousOutput()) {
1150
+ this.params.harness.flushOutput(() => this.clearOutputAudio("active-run-control"));
1151
+ return;
1152
+ }
1127
1153
  this.params.harness.handleBargeIn({
1128
1154
  audioPlaybackActive: true,
1129
1155
  force: true
@@ -1147,22 +1173,25 @@ var DiscordRealtimePlayback = class {
1147
1173
  }
1148
1174
  resetProviderContinuity(reason) {
1149
1175
  this.lastControlSpeech = void 0;
1150
- this.requeueUnplayedExactSpeech();
1176
+ this.retireExactSpeech(true);
1151
1177
  this.responseAudio = "discarding";
1152
1178
  this.params.harness.flushOutput(() => this.clearOutputAudio(reason));
1153
1179
  this.responseAudio = "completed";
1154
1180
  this.params.harness.finishOutputAudio(reason);
1155
1181
  }
1156
- requeueUnplayedExactSpeech() {
1157
- const replayExactSpeech = this.exactSpeechState.status === "active" && !this.exactSpeechState.output?.activity.snapshot().playbackStarted ? this.exactSpeechState.message : void 0;
1182
+ retireExactSpeech(preserveUnplayed = false) {
1183
+ this.pendingDirectCompletion = void 0;
1184
+ const speech = this.exactSpeechState;
1158
1185
  this.exactSpeechState = { status: "idle" };
1159
- if (replayExactSpeech) this.queuedExactSpeechMessages.unshift(replayExactSpeech);
1186
+ if (speech.status !== "active") return;
1187
+ const directStarted = speech.direct && Atomics.exchange(speech.direct.clock, 2, 0n) === -speech.direct.epoch;
1188
+ if (preserveUnplayed && !directStarted && !speech.output?.activity.snapshot().playbackStarted) this.queuedExactSpeechMessages.unshift(speech.message);
1160
1189
  }
1161
1190
  outputAudioMs() {
1162
- return Math.floor(this.params.harness.outputActivity.snapshot().audioMs);
1191
+ return this.directOutput ? Math.floor(Number(Atomics.load(this.directOutput.clock, 1)) / 48) : Math.floor(this.params.harness.outputActivity.snapshot().audioMs);
1163
1192
  }
1164
1193
  isOutputAudioActive() {
1165
- return this.outputs.size > 0 || this.generatingItems.size > 0;
1194
+ return this.outputs.size > 0 || this.generatingItems.size > 0 || this.directOutput !== void 0 && Atomics.load(this.directOutput.clock, 0) > 0n;
1166
1195
  }
1167
1196
  isContinuousOutput() {
1168
1197
  return this.params.bridge()?.bridge.outputAudioMode === "continuous";
@@ -1172,7 +1201,7 @@ var DiscordRealtimePlayback = class {
1172
1201
  this.speechSuccessor = void 0;
1173
1202
  this.params.stopTerminally();
1174
1203
  this.queuedExactSpeechMessages = [];
1175
- this.exactSpeechState = { status: "idle" };
1204
+ this.retireExactSpeech();
1176
1205
  this.clearOutputAudio(reason);
1177
1206
  this.params.onTerminalError(error);
1178
1207
  }
@@ -1214,16 +1243,22 @@ var DiscordRealtimePlayback = class {
1214
1243
  }
1215
1244
  sendExactSpeechMessage(text) {
1216
1245
  if (this.params.stopped() || !text.trim()) return;
1246
+ const direct = this.directOutput ? {
1247
+ clock: this.directOutput.clock,
1248
+ epoch: ++this.nextExactSpeechEpoch
1249
+ } : void 0;
1217
1250
  this.exactSpeechState = {
1218
1251
  status: "active",
1219
- message: text
1252
+ message: text,
1253
+ direct
1220
1254
  };
1255
+ if (direct) Atomics.store(direct.clock, 2, direct.epoch);
1221
1256
  this.beginResponse();
1222
1257
  this.params.bridge()?.sendUserMessage(this.params.buildSpeakExactMessage(text));
1223
1258
  }
1224
1259
  completeExactSpeechResponse(reason) {
1225
- if (this.responseAudio !== "completed" || this.outputs.size > 0) return;
1226
- this.exactSpeechState = { status: "idle" };
1260
+ if (this.pendingDirectCompletion !== void 0 || this.responseAudio !== "completed" || this.isOutputAudioActive()) return;
1261
+ this.retireExactSpeech();
1227
1262
  this.drainQueuedExactSpeechMessages(reason);
1228
1263
  }
1229
1264
  };
@@ -1548,6 +1583,7 @@ var DiscordRealtimeSpeakerSession = class {
1548
1583
  }
1549
1584
  const humanParticipantCount = this.humanParticipantCount();
1550
1585
  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}`);
1586
+ this.attachOutputAudioPort();
1551
1587
  await this.bridge.connect();
1552
1588
  if (!this.markLifecycleReady(lifecycleGeneration)) {
1553
1589
  await this.close();
@@ -1671,6 +1707,11 @@ var DiscordRealtimeSpeakerSession = class {
1671
1707
  activateOutput() {
1672
1708
  this.readVoiceSelection();
1673
1709
  this.outputEnabled = true;
1710
+ this.playback.activateOutputAudioPort();
1711
+ }
1712
+ attachOutputAudioPort() {
1713
+ const provider = this.bridge?.bridge;
1714
+ if (this.wakeNamePolicy === "never" && provider?.outputAudioMode === "continuous" && provider.setAudioOutputPort) provider.setAudioOutputPort(this.playback.createOutputAudioPort(this.outputEnabled));
1674
1715
  }
1675
1716
  hasActiveInput() {
1676
1717
  return this.captures.size > 0;
@@ -1795,7 +1836,7 @@ var DiscordRealtimeVoiceSession = class {
1795
1836
  this.changingVoice = false;
1796
1837
  this.callAbort = new AbortController();
1797
1838
  this.candidates = /* @__PURE__ */ new Set();
1798
- this.player = new DiscordRealtimePlayer(params.entry.player);
1839
+ this.player = new DiscordRealtimePlayer(params.entry.audio);
1799
1840
  }
1800
1841
  async connect() {
1801
1842
  if (this.closed) throw new Error("Discord realtime voice session is closed");