@livekit/agents 1.0.47 → 1.1.0-dev.0

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 (444) hide show
  1. package/dist/beta/index.cjs +29 -0
  2. package/dist/beta/index.cjs.map +1 -0
  3. package/dist/beta/index.d.cts +2 -0
  4. package/dist/beta/index.d.ts +2 -0
  5. package/dist/beta/index.d.ts.map +1 -0
  6. package/dist/beta/index.js +7 -0
  7. package/dist/beta/index.js.map +1 -0
  8. package/dist/beta/workflows/index.cjs +29 -0
  9. package/dist/beta/workflows/index.cjs.map +1 -0
  10. package/dist/beta/workflows/index.d.cts +2 -0
  11. package/dist/beta/workflows/index.d.ts +2 -0
  12. package/dist/beta/workflows/index.d.ts.map +1 -0
  13. package/dist/beta/workflows/index.js +7 -0
  14. package/dist/beta/workflows/index.js.map +1 -0
  15. package/dist/beta/workflows/task_group.cjs +162 -0
  16. package/dist/beta/workflows/task_group.cjs.map +1 -0
  17. package/dist/beta/workflows/task_group.d.cts +32 -0
  18. package/dist/beta/workflows/task_group.d.ts +32 -0
  19. package/dist/beta/workflows/task_group.d.ts.map +1 -0
  20. package/dist/beta/workflows/task_group.js +138 -0
  21. package/dist/beta/workflows/task_group.js.map +1 -0
  22. package/dist/constants.cjs +27 -0
  23. package/dist/constants.cjs.map +1 -1
  24. package/dist/constants.d.cts +9 -0
  25. package/dist/constants.d.ts +9 -0
  26. package/dist/constants.d.ts.map +1 -1
  27. package/dist/constants.js +18 -0
  28. package/dist/constants.js.map +1 -1
  29. package/dist/index.cjs +3 -0
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +2 -1
  32. package/dist/index.d.ts +2 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +2 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/inference/api_protos.d.cts +12 -12
  37. package/dist/inference/api_protos.d.ts +12 -12
  38. package/dist/inference/interruption/defaults.cjs +81 -0
  39. package/dist/inference/interruption/defaults.cjs.map +1 -0
  40. package/dist/inference/interruption/defaults.d.cts +19 -0
  41. package/dist/inference/interruption/defaults.d.ts +19 -0
  42. package/dist/inference/interruption/defaults.d.ts.map +1 -0
  43. package/dist/inference/interruption/defaults.js +46 -0
  44. package/dist/inference/interruption/defaults.js.map +1 -0
  45. package/dist/inference/interruption/errors.cjs +44 -0
  46. package/dist/inference/interruption/errors.cjs.map +1 -0
  47. package/dist/inference/interruption/errors.d.cts +12 -0
  48. package/dist/inference/interruption/errors.d.ts +12 -0
  49. package/dist/inference/interruption/errors.d.ts.map +1 -0
  50. package/dist/inference/interruption/errors.js +20 -0
  51. package/dist/inference/interruption/errors.js.map +1 -0
  52. package/dist/inference/interruption/http_transport.cjs +147 -0
  53. package/dist/inference/interruption/http_transport.cjs.map +1 -0
  54. package/dist/inference/interruption/http_transport.d.cts +63 -0
  55. package/dist/inference/interruption/http_transport.d.ts +63 -0
  56. package/dist/inference/interruption/http_transport.d.ts.map +1 -0
  57. package/dist/inference/interruption/http_transport.js +121 -0
  58. package/dist/inference/interruption/http_transport.js.map +1 -0
  59. package/dist/inference/interruption/interruption_cache_entry.cjs +58 -0
  60. package/dist/inference/interruption/interruption_cache_entry.cjs.map +1 -0
  61. package/dist/inference/interruption/interruption_cache_entry.d.cts +30 -0
  62. package/dist/inference/interruption/interruption_cache_entry.d.ts +30 -0
  63. package/dist/inference/interruption/interruption_cache_entry.d.ts.map +1 -0
  64. package/dist/inference/interruption/interruption_cache_entry.js +34 -0
  65. package/dist/inference/interruption/interruption_cache_entry.js.map +1 -0
  66. package/dist/inference/interruption/interruption_detector.cjs +181 -0
  67. package/dist/inference/interruption/interruption_detector.cjs.map +1 -0
  68. package/dist/inference/interruption/interruption_detector.d.cts +59 -0
  69. package/dist/inference/interruption/interruption_detector.d.ts +59 -0
  70. package/dist/inference/interruption/interruption_detector.d.ts.map +1 -0
  71. package/dist/inference/interruption/interruption_detector.js +147 -0
  72. package/dist/inference/interruption/interruption_detector.js.map +1 -0
  73. package/dist/inference/interruption/interruption_stream.cjs +368 -0
  74. package/dist/inference/interruption/interruption_stream.cjs.map +1 -0
  75. package/dist/inference/interruption/interruption_stream.d.cts +46 -0
  76. package/dist/inference/interruption/interruption_stream.d.ts +46 -0
  77. package/dist/inference/interruption/interruption_stream.d.ts.map +1 -0
  78. package/dist/inference/interruption/interruption_stream.js +344 -0
  79. package/dist/inference/interruption/interruption_stream.js.map +1 -0
  80. package/dist/inference/interruption/types.cjs +17 -0
  81. package/dist/inference/interruption/types.cjs.map +1 -0
  82. package/dist/inference/interruption/types.d.cts +66 -0
  83. package/dist/inference/interruption/types.d.ts +66 -0
  84. package/dist/inference/interruption/types.d.ts.map +1 -0
  85. package/dist/inference/interruption/types.js +1 -0
  86. package/dist/inference/interruption/types.js.map +1 -0
  87. package/dist/inference/interruption/utils.cjs +130 -0
  88. package/dist/inference/interruption/utils.cjs.map +1 -0
  89. package/dist/inference/interruption/utils.d.cts +41 -0
  90. package/dist/inference/interruption/utils.d.ts +41 -0
  91. package/dist/inference/interruption/utils.d.ts.map +1 -0
  92. package/dist/inference/interruption/utils.js +105 -0
  93. package/dist/inference/interruption/utils.js.map +1 -0
  94. package/dist/inference/interruption/utils.test.cjs +105 -0
  95. package/dist/inference/interruption/utils.test.cjs.map +1 -0
  96. package/dist/inference/interruption/utils.test.js +104 -0
  97. package/dist/inference/interruption/utils.test.js.map +1 -0
  98. package/dist/inference/interruption/ws_transport.cjs +329 -0
  99. package/dist/inference/interruption/ws_transport.cjs.map +1 -0
  100. package/dist/inference/interruption/ws_transport.d.cts +33 -0
  101. package/dist/inference/interruption/ws_transport.d.ts +33 -0
  102. package/dist/inference/interruption/ws_transport.d.ts.map +1 -0
  103. package/dist/inference/interruption/ws_transport.js +295 -0
  104. package/dist/inference/interruption/ws_transport.js.map +1 -0
  105. package/dist/inference/llm.cjs +14 -10
  106. package/dist/inference/llm.cjs.map +1 -1
  107. package/dist/inference/llm.d.cts +2 -1
  108. package/dist/inference/llm.d.ts +2 -1
  109. package/dist/inference/llm.d.ts.map +1 -1
  110. package/dist/inference/llm.js +8 -10
  111. package/dist/inference/llm.js.map +1 -1
  112. package/dist/inference/stt.cjs +7 -2
  113. package/dist/inference/stt.cjs.map +1 -1
  114. package/dist/inference/stt.d.cts +2 -0
  115. package/dist/inference/stt.d.ts +2 -0
  116. package/dist/inference/stt.d.ts.map +1 -1
  117. package/dist/inference/stt.js +8 -3
  118. package/dist/inference/stt.js.map +1 -1
  119. package/dist/inference/tts.cjs +7 -2
  120. package/dist/inference/tts.cjs.map +1 -1
  121. package/dist/inference/tts.d.cts +2 -0
  122. package/dist/inference/tts.d.ts +2 -0
  123. package/dist/inference/tts.d.ts.map +1 -1
  124. package/dist/inference/tts.js +8 -3
  125. package/dist/inference/tts.js.map +1 -1
  126. package/dist/inference/utils.cjs +26 -7
  127. package/dist/inference/utils.cjs.map +1 -1
  128. package/dist/inference/utils.d.cts +13 -0
  129. package/dist/inference/utils.d.ts +13 -0
  130. package/dist/inference/utils.d.ts.map +1 -1
  131. package/dist/inference/utils.js +18 -2
  132. package/dist/inference/utils.js.map +1 -1
  133. package/dist/llm/chat_context.cjs +108 -2
  134. package/dist/llm/chat_context.cjs.map +1 -1
  135. package/dist/llm/chat_context.d.cts +28 -1
  136. package/dist/llm/chat_context.d.ts +28 -1
  137. package/dist/llm/chat_context.d.ts.map +1 -1
  138. package/dist/llm/chat_context.js +108 -2
  139. package/dist/llm/chat_context.js.map +1 -1
  140. package/dist/llm/chat_context.test.cjs +43 -0
  141. package/dist/llm/chat_context.test.cjs.map +1 -1
  142. package/dist/llm/chat_context.test.js +43 -0
  143. package/dist/llm/chat_context.test.js.map +1 -1
  144. package/dist/llm/index.cjs +2 -0
  145. package/dist/llm/index.cjs.map +1 -1
  146. package/dist/llm/index.d.cts +2 -2
  147. package/dist/llm/index.d.ts +2 -2
  148. package/dist/llm/index.d.ts.map +1 -1
  149. package/dist/llm/index.js +3 -1
  150. package/dist/llm/index.js.map +1 -1
  151. package/dist/llm/llm.cjs +16 -1
  152. package/dist/llm/llm.cjs.map +1 -1
  153. package/dist/llm/llm.d.cts +9 -0
  154. package/dist/llm/llm.d.ts +9 -0
  155. package/dist/llm/llm.d.ts.map +1 -1
  156. package/dist/llm/llm.js +16 -1
  157. package/dist/llm/llm.js.map +1 -1
  158. package/dist/llm/provider_format/index.d.cts +1 -1
  159. package/dist/llm/provider_format/index.d.ts +1 -1
  160. package/dist/llm/realtime.cjs +3 -0
  161. package/dist/llm/realtime.cjs.map +1 -1
  162. package/dist/llm/realtime.d.cts +1 -0
  163. package/dist/llm/realtime.d.ts +1 -0
  164. package/dist/llm/realtime.d.ts.map +1 -1
  165. package/dist/llm/realtime.js +3 -0
  166. package/dist/llm/realtime.js.map +1 -1
  167. package/dist/llm/tool_context.cjs +7 -0
  168. package/dist/llm/tool_context.cjs.map +1 -1
  169. package/dist/llm/tool_context.d.cts +10 -2
  170. package/dist/llm/tool_context.d.ts +10 -2
  171. package/dist/llm/tool_context.d.ts.map +1 -1
  172. package/dist/llm/tool_context.js +6 -0
  173. package/dist/llm/tool_context.js.map +1 -1
  174. package/dist/metrics/base.cjs.map +1 -1
  175. package/dist/metrics/base.d.cts +45 -1
  176. package/dist/metrics/base.d.ts +45 -1
  177. package/dist/metrics/base.d.ts.map +1 -1
  178. package/dist/metrics/index.cjs +5 -0
  179. package/dist/metrics/index.cjs.map +1 -1
  180. package/dist/metrics/index.d.cts +2 -1
  181. package/dist/metrics/index.d.ts +2 -1
  182. package/dist/metrics/index.d.ts.map +1 -1
  183. package/dist/metrics/index.js +6 -0
  184. package/dist/metrics/index.js.map +1 -1
  185. package/dist/metrics/model_usage.cjs +189 -0
  186. package/dist/metrics/model_usage.cjs.map +1 -0
  187. package/dist/metrics/model_usage.d.cts +92 -0
  188. package/dist/metrics/model_usage.d.ts +92 -0
  189. package/dist/metrics/model_usage.d.ts.map +1 -0
  190. package/dist/metrics/model_usage.js +164 -0
  191. package/dist/metrics/model_usage.js.map +1 -0
  192. package/dist/metrics/model_usage.test.cjs +474 -0
  193. package/dist/metrics/model_usage.test.cjs.map +1 -0
  194. package/dist/metrics/model_usage.test.js +476 -0
  195. package/dist/metrics/model_usage.test.js.map +1 -0
  196. package/dist/metrics/usage_collector.cjs +3 -0
  197. package/dist/metrics/usage_collector.cjs.map +1 -1
  198. package/dist/metrics/usage_collector.d.cts +9 -0
  199. package/dist/metrics/usage_collector.d.ts +9 -0
  200. package/dist/metrics/usage_collector.d.ts.map +1 -1
  201. package/dist/metrics/usage_collector.js +3 -0
  202. package/dist/metrics/usage_collector.js.map +1 -1
  203. package/dist/metrics/utils.cjs +9 -0
  204. package/dist/metrics/utils.cjs.map +1 -1
  205. package/dist/metrics/utils.d.ts.map +1 -1
  206. package/dist/metrics/utils.js +9 -0
  207. package/dist/metrics/utils.js.map +1 -1
  208. package/dist/stream/multi_input_stream.test.cjs +4 -0
  209. package/dist/stream/multi_input_stream.test.cjs.map +1 -1
  210. package/dist/stream/multi_input_stream.test.js +5 -1
  211. package/dist/stream/multi_input_stream.test.js.map +1 -1
  212. package/dist/stream/stream_channel.cjs +31 -0
  213. package/dist/stream/stream_channel.cjs.map +1 -1
  214. package/dist/stream/stream_channel.d.cts +4 -2
  215. package/dist/stream/stream_channel.d.ts +4 -2
  216. package/dist/stream/stream_channel.d.ts.map +1 -1
  217. package/dist/stream/stream_channel.js +31 -0
  218. package/dist/stream/stream_channel.js.map +1 -1
  219. package/dist/stt/stt.cjs +34 -2
  220. package/dist/stt/stt.cjs.map +1 -1
  221. package/dist/stt/stt.d.cts +22 -0
  222. package/dist/stt/stt.d.ts +22 -0
  223. package/dist/stt/stt.d.ts.map +1 -1
  224. package/dist/stt/stt.js +34 -2
  225. package/dist/stt/stt.js.map +1 -1
  226. package/dist/telemetry/otel_http_exporter.cjs +24 -5
  227. package/dist/telemetry/otel_http_exporter.cjs.map +1 -1
  228. package/dist/telemetry/otel_http_exporter.d.cts +1 -0
  229. package/dist/telemetry/otel_http_exporter.d.ts +1 -0
  230. package/dist/telemetry/otel_http_exporter.d.ts.map +1 -1
  231. package/dist/telemetry/otel_http_exporter.js +24 -5
  232. package/dist/telemetry/otel_http_exporter.js.map +1 -1
  233. package/dist/telemetry/trace_types.cjs +5 -5
  234. package/dist/telemetry/trace_types.cjs.map +1 -1
  235. package/dist/telemetry/trace_types.d.cts +9 -5
  236. package/dist/telemetry/trace_types.d.ts +9 -5
  237. package/dist/telemetry/trace_types.d.ts.map +1 -1
  238. package/dist/telemetry/trace_types.js +5 -5
  239. package/dist/telemetry/trace_types.js.map +1 -1
  240. package/dist/telemetry/traces.cjs +47 -8
  241. package/dist/telemetry/traces.cjs.map +1 -1
  242. package/dist/telemetry/traces.d.ts.map +1 -1
  243. package/dist/telemetry/traces.js +47 -8
  244. package/dist/telemetry/traces.js.map +1 -1
  245. package/dist/tts/tts.cjs +64 -2
  246. package/dist/tts/tts.cjs.map +1 -1
  247. package/dist/tts/tts.d.cts +34 -0
  248. package/dist/tts/tts.d.ts +34 -0
  249. package/dist/tts/tts.d.ts.map +1 -1
  250. package/dist/tts/tts.js +64 -2
  251. package/dist/tts/tts.js.map +1 -1
  252. package/dist/utils.cjs +1 -0
  253. package/dist/utils.cjs.map +1 -1
  254. package/dist/utils.d.ts.map +1 -1
  255. package/dist/utils.js +1 -0
  256. package/dist/utils.js.map +1 -1
  257. package/dist/version.cjs +1 -1
  258. package/dist/version.js +1 -1
  259. package/dist/voice/agent.cjs +34 -4
  260. package/dist/voice/agent.cjs.map +1 -1
  261. package/dist/voice/agent.d.cts +11 -2
  262. package/dist/voice/agent.d.ts +11 -2
  263. package/dist/voice/agent.d.ts.map +1 -1
  264. package/dist/voice/agent.js +34 -4
  265. package/dist/voice/agent.js.map +1 -1
  266. package/dist/voice/agent_activity.cjs +292 -44
  267. package/dist/voice/agent_activity.cjs.map +1 -1
  268. package/dist/voice/agent_activity.d.cts +27 -6
  269. package/dist/voice/agent_activity.d.ts +27 -6
  270. package/dist/voice/agent_activity.d.ts.map +1 -1
  271. package/dist/voice/agent_activity.js +293 -45
  272. package/dist/voice/agent_activity.js.map +1 -1
  273. package/dist/voice/agent_session.cjs +105 -48
  274. package/dist/voice/agent_session.cjs.map +1 -1
  275. package/dist/voice/agent_session.d.cts +90 -20
  276. package/dist/voice/agent_session.d.ts +90 -20
  277. package/dist/voice/agent_session.d.ts.map +1 -1
  278. package/dist/voice/agent_session.js +105 -46
  279. package/dist/voice/agent_session.js.map +1 -1
  280. package/dist/voice/audio_recognition.cjs +287 -6
  281. package/dist/voice/audio_recognition.cjs.map +1 -1
  282. package/dist/voice/audio_recognition.d.cts +42 -3
  283. package/dist/voice/audio_recognition.d.ts +42 -3
  284. package/dist/voice/audio_recognition.d.ts.map +1 -1
  285. package/dist/voice/audio_recognition.js +289 -7
  286. package/dist/voice/audio_recognition.js.map +1 -1
  287. package/dist/voice/client_events.cjs +554 -0
  288. package/dist/voice/client_events.cjs.map +1 -0
  289. package/dist/voice/client_events.d.cts +195 -0
  290. package/dist/voice/client_events.d.ts +195 -0
  291. package/dist/voice/client_events.d.ts.map +1 -0
  292. package/dist/voice/client_events.js +548 -0
  293. package/dist/voice/client_events.js.map +1 -0
  294. package/dist/voice/events.cjs +1 -0
  295. package/dist/voice/events.cjs.map +1 -1
  296. package/dist/voice/events.d.cts +8 -5
  297. package/dist/voice/events.d.ts +8 -5
  298. package/dist/voice/events.d.ts.map +1 -1
  299. package/dist/voice/events.js +1 -0
  300. package/dist/voice/events.js.map +1 -1
  301. package/dist/voice/generation.cjs +43 -8
  302. package/dist/voice/generation.cjs.map +1 -1
  303. package/dist/voice/generation.d.cts +3 -3
  304. package/dist/voice/generation.d.ts +3 -3
  305. package/dist/voice/generation.d.ts.map +1 -1
  306. package/dist/voice/generation.js +43 -8
  307. package/dist/voice/generation.js.map +1 -1
  308. package/dist/voice/index.cjs +1 -0
  309. package/dist/voice/index.cjs.map +1 -1
  310. package/dist/voice/index.d.cts +1 -0
  311. package/dist/voice/index.d.ts +1 -0
  312. package/dist/voice/index.d.ts.map +1 -1
  313. package/dist/voice/index.js +1 -0
  314. package/dist/voice/index.js.map +1 -1
  315. package/dist/voice/report.cjs +20 -8
  316. package/dist/voice/report.cjs.map +1 -1
  317. package/dist/voice/report.d.cts +5 -0
  318. package/dist/voice/report.d.ts +5 -0
  319. package/dist/voice/report.d.ts.map +1 -1
  320. package/dist/voice/report.js +20 -8
  321. package/dist/voice/report.js.map +1 -1
  322. package/dist/voice/report.test.cjs +106 -0
  323. package/dist/voice/report.test.cjs.map +1 -0
  324. package/dist/voice/report.test.js +105 -0
  325. package/dist/voice/report.test.js.map +1 -0
  326. package/dist/voice/room_io/room_io.cjs +16 -41
  327. package/dist/voice/room_io/room_io.cjs.map +1 -1
  328. package/dist/voice/room_io/room_io.d.cts +4 -9
  329. package/dist/voice/room_io/room_io.d.ts +4 -9
  330. package/dist/voice/room_io/room_io.d.ts.map +1 -1
  331. package/dist/voice/room_io/room_io.js +17 -43
  332. package/dist/voice/room_io/room_io.js.map +1 -1
  333. package/dist/voice/testing/fake_llm.cjs +127 -0
  334. package/dist/voice/testing/fake_llm.cjs.map +1 -0
  335. package/dist/voice/testing/fake_llm.d.cts +30 -0
  336. package/dist/voice/testing/fake_llm.d.ts +30 -0
  337. package/dist/voice/testing/fake_llm.d.ts.map +1 -0
  338. package/dist/voice/testing/fake_llm.js +103 -0
  339. package/dist/voice/testing/fake_llm.js.map +1 -0
  340. package/dist/voice/testing/index.cjs +3 -0
  341. package/dist/voice/testing/index.cjs.map +1 -1
  342. package/dist/voice/testing/index.d.cts +1 -0
  343. package/dist/voice/testing/index.d.ts +1 -0
  344. package/dist/voice/testing/index.d.ts.map +1 -1
  345. package/dist/voice/testing/index.js +2 -0
  346. package/dist/voice/testing/index.js.map +1 -1
  347. package/dist/voice/turn_config/endpointing.cjs +33 -0
  348. package/dist/voice/turn_config/endpointing.cjs.map +1 -0
  349. package/dist/voice/turn_config/endpointing.d.cts +30 -0
  350. package/dist/voice/turn_config/endpointing.d.ts +30 -0
  351. package/dist/voice/turn_config/endpointing.d.ts.map +1 -0
  352. package/dist/voice/turn_config/endpointing.js +9 -0
  353. package/dist/voice/turn_config/endpointing.js.map +1 -0
  354. package/dist/voice/turn_config/interruption.cjs +37 -0
  355. package/dist/voice/turn_config/interruption.cjs.map +1 -0
  356. package/dist/voice/turn_config/interruption.d.cts +53 -0
  357. package/dist/voice/turn_config/interruption.d.ts +53 -0
  358. package/dist/voice/turn_config/interruption.d.ts.map +1 -0
  359. package/dist/voice/turn_config/interruption.js +13 -0
  360. package/dist/voice/turn_config/interruption.js.map +1 -0
  361. package/dist/voice/turn_config/turn_handling.cjs +35 -0
  362. package/dist/voice/turn_config/turn_handling.cjs.map +1 -0
  363. package/dist/voice/turn_config/turn_handling.d.cts +36 -0
  364. package/dist/voice/turn_config/turn_handling.d.ts +36 -0
  365. package/dist/voice/turn_config/turn_handling.d.ts.map +1 -0
  366. package/dist/voice/turn_config/turn_handling.js +11 -0
  367. package/dist/voice/turn_config/turn_handling.js.map +1 -0
  368. package/dist/voice/turn_config/utils.cjs +97 -0
  369. package/dist/voice/turn_config/utils.cjs.map +1 -0
  370. package/dist/voice/turn_config/utils.d.cts +25 -0
  371. package/dist/voice/turn_config/utils.d.ts +25 -0
  372. package/dist/voice/turn_config/utils.d.ts.map +1 -0
  373. package/dist/voice/turn_config/utils.js +73 -0
  374. package/dist/voice/turn_config/utils.js.map +1 -0
  375. package/dist/voice/turn_config/utils.test.cjs +86 -0
  376. package/dist/voice/turn_config/utils.test.cjs.map +1 -0
  377. package/dist/voice/turn_config/utils.test.js +85 -0
  378. package/dist/voice/turn_config/utils.test.js.map +1 -0
  379. package/dist/voice/wire_format.cjs +798 -0
  380. package/dist/voice/wire_format.cjs.map +1 -0
  381. package/dist/voice/wire_format.d.cts +5503 -0
  382. package/dist/voice/wire_format.d.ts +5503 -0
  383. package/dist/voice/wire_format.d.ts.map +1 -0
  384. package/dist/voice/wire_format.js +728 -0
  385. package/dist/voice/wire_format.js.map +1 -0
  386. package/package.json +2 -1
  387. package/src/beta/index.ts +9 -0
  388. package/src/beta/workflows/index.ts +9 -0
  389. package/src/beta/workflows/task_group.ts +194 -0
  390. package/src/constants.ts +13 -0
  391. package/src/index.ts +2 -1
  392. package/src/inference/interruption/defaults.ts +51 -0
  393. package/src/inference/interruption/errors.ts +25 -0
  394. package/src/inference/interruption/http_transport.ts +187 -0
  395. package/src/inference/interruption/interruption_cache_entry.ts +50 -0
  396. package/src/inference/interruption/interruption_detector.ts +188 -0
  397. package/src/inference/interruption/interruption_stream.ts +467 -0
  398. package/src/inference/interruption/types.ts +84 -0
  399. package/src/inference/interruption/utils.test.ts +132 -0
  400. package/src/inference/interruption/utils.ts +137 -0
  401. package/src/inference/interruption/ws_transport.ts +402 -0
  402. package/src/inference/llm.ts +9 -12
  403. package/src/inference/stt.ts +10 -3
  404. package/src/inference/tts.ts +10 -3
  405. package/src/inference/utils.ts +29 -1
  406. package/src/llm/chat_context.test.ts +48 -0
  407. package/src/llm/chat_context.ts +161 -0
  408. package/src/llm/index.ts +2 -0
  409. package/src/llm/llm.ts +16 -0
  410. package/src/llm/realtime.ts +4 -0
  411. package/src/llm/tool_context.ts +14 -0
  412. package/src/metrics/base.ts +48 -1
  413. package/src/metrics/index.ts +11 -0
  414. package/src/metrics/model_usage.test.ts +545 -0
  415. package/src/metrics/model_usage.ts +262 -0
  416. package/src/metrics/usage_collector.ts +11 -0
  417. package/src/metrics/utils.ts +11 -0
  418. package/src/stream/multi_input_stream.test.ts +6 -1
  419. package/src/stream/stream_channel.ts +34 -2
  420. package/src/stt/stt.ts +38 -0
  421. package/src/telemetry/otel_http_exporter.ts +28 -5
  422. package/src/telemetry/trace_types.ts +11 -8
  423. package/src/telemetry/traces.ts +111 -54
  424. package/src/tts/tts.ts +69 -1
  425. package/src/utils.ts +5 -0
  426. package/src/voice/agent.ts +41 -3
  427. package/src/voice/agent_activity.ts +371 -34
  428. package/src/voice/agent_session.ts +207 -59
  429. package/src/voice/audio_recognition.ts +385 -9
  430. package/src/voice/client_events.ts +838 -0
  431. package/src/voice/events.ts +14 -4
  432. package/src/voice/generation.ts +52 -9
  433. package/src/voice/index.ts +1 -0
  434. package/src/voice/report.test.ts +117 -0
  435. package/src/voice/report.ts +29 -6
  436. package/src/voice/room_io/room_io.ts +21 -64
  437. package/src/voice/testing/fake_llm.ts +138 -0
  438. package/src/voice/testing/index.ts +2 -0
  439. package/src/voice/turn_config/endpointing.ts +33 -0
  440. package/src/voice/turn_config/interruption.ts +56 -0
  441. package/src/voice/turn_config/turn_handling.ts +45 -0
  442. package/src/voice/turn_config/utils.test.ts +100 -0
  443. package/src/voice/turn_config/utils.ts +103 -0
  444. package/src/voice/wire_format.ts +827 -0
@@ -1,6 +1,8 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
+ import type { InterruptionDetectionError } from '../inference/interruption/errors.js';
5
+ import type { OverlappingSpeechEvent } from '../inference/interruption/types.js';
4
6
  import type {
5
7
  ChatMessage,
6
8
  FunctionCall,
@@ -25,6 +27,7 @@ export enum AgentSessionEventTypes {
25
27
  FunctionToolsExecuted = 'function_tools_executed',
26
28
  MetricsCollected = 'metrics_collected',
27
29
  SpeechCreated = 'speech_created',
30
+ UserOverlappingSpeech = 'user_overlapping_speech',
28
31
  Error = 'error',
29
32
  Close = 'close',
30
33
  }
@@ -215,13 +218,13 @@ export const createSpeechCreatedEvent = ({
215
218
 
216
219
  export type ErrorEvent = {
217
220
  type: 'error';
218
- error: RealtimeModelError | STTError | TTSError | LLMError | unknown;
221
+ error: RealtimeModelError | STTError | TTSError | LLMError | InterruptionDetectionError | unknown;
219
222
  source: LLM | STT | TTS | RealtimeModel | unknown;
220
223
  createdAt: number;
221
224
  };
222
225
 
223
226
  export const createErrorEvent = (
224
- error: RealtimeModelError | STTError | TTSError | LLMError | unknown,
227
+ error: RealtimeModelError | STTError | TTSError | LLMError | InterruptionDetectionError | unknown,
225
228
  source: LLM | STT | TTS | RealtimeModel | unknown,
226
229
  createdAt: number = Date.now(),
227
230
  ): ErrorEvent => ({
@@ -233,14 +236,20 @@ export const createErrorEvent = (
233
236
 
234
237
  export type CloseEvent = {
235
238
  type: 'close';
236
- error: RealtimeModelError | STTError | TTSError | LLMError | null;
239
+ error: RealtimeModelError | STTError | TTSError | LLMError | InterruptionDetectionError | null;
237
240
  reason: ShutdownReason;
238
241
  createdAt: number;
239
242
  };
240
243
 
241
244
  export const createCloseEvent = (
242
245
  reason: ShutdownReason,
243
- error: RealtimeModelError | STTError | TTSError | LLMError | null = null,
246
+ error:
247
+ | RealtimeModelError
248
+ | STTError
249
+ | TTSError
250
+ | LLMError
251
+ | InterruptionDetectionError
252
+ | null = null,
244
253
  createdAt: number = Date.now(),
245
254
  ): CloseEvent => ({
246
255
  type: 'close',
@@ -257,5 +266,6 @@ export type AgentEvent =
257
266
  | ConversationItemAddedEvent
258
267
  | FunctionToolsExecutedEvent
259
268
  | SpeechCreatedEvent
269
+ | OverlappingSpeechEvent
260
270
  | ErrorEvent
261
271
  | CloseEvent;
@@ -51,6 +51,7 @@ export class _LLMGenerationData {
51
51
  generatedText: string = '';
52
52
  generatedToolCalls: FunctionCall[];
53
53
  id: string;
54
+ ttft?: number;
54
55
 
55
56
  constructor(
56
57
  public readonly textStream: ReadableStream<string>,
@@ -416,6 +417,8 @@ export function performLLMInference(
416
417
  toolCtx: ToolContext,
417
418
  modelSettings: ModelSettings,
418
419
  controller: AbortController,
420
+ model?: string,
421
+ provider?: string,
419
422
  ): [Task<void>, _LLMGenerationData] {
420
423
  const textStream = new IdentityTransform<string>();
421
424
  const toolCallStream = new IdentityTransform<FunctionCall>();
@@ -431,8 +434,17 @@ export function performLLMInference(
431
434
  );
432
435
  span.setAttribute(traceTypes.ATTR_FUNCTION_TOOLS, JSON.stringify(Object.keys(toolCtx)));
433
436
 
437
+ if (model) {
438
+ span.setAttribute(traceTypes.ATTR_GEN_AI_REQUEST_MODEL, model);
439
+ }
440
+ if (provider) {
441
+ span.setAttribute(traceTypes.ATTR_GEN_AI_PROVIDER_NAME, provider);
442
+ }
443
+
434
444
  let llmStreamReader: ReadableStreamDefaultReader<string | ChatChunk> | null = null;
435
445
  let llmStream: ReadableStream<string | ChatChunk> | null = null;
446
+ const startTime = performance.now() / 1000; // Convert to seconds
447
+ let firstTokenReceived = false;
436
448
 
437
449
  try {
438
450
  llmStream = await node(chatCtx, toolCtx, modelSettings);
@@ -455,6 +467,11 @@ export function performLLMInference(
455
467
  const { done, value: chunk } = result;
456
468
  if (done) break;
457
469
 
470
+ if (!firstTokenReceived) {
471
+ firstTokenReceived = true;
472
+ data.ttft = performance.now() / 1000 - startTime;
473
+ }
474
+
458
475
  if (typeof chunk === 'string') {
459
476
  data.generatedText += chunk;
460
477
  await textWriter.write(chunk);
@@ -493,6 +510,9 @@ export function performLLMInference(
493
510
  }
494
511
 
495
512
  span.setAttribute(traceTypes.ATTR_RESPONSE_TEXT, data.generatedText);
513
+ if (data.ttft !== undefined) {
514
+ span.setAttribute(traceTypes.ATTR_RESPONSE_TTFT, data.ttft);
515
+ }
496
516
  } catch (error) {
497
517
  if (error instanceof DOMException && error.name === 'AbortError') {
498
518
  // Abort signal was triggered, handle gracefully
@@ -527,6 +547,8 @@ export function performTTSInference(
527
547
  text: ReadableStream<string | TimedString>,
528
548
  modelSettings: ModelSettings,
529
549
  controller: AbortController,
550
+ model?: string,
551
+ provider?: string,
530
552
  ): [Task<void>, _TTSGenerationData] {
531
553
  const audioStream = new IdentityTransform<AudioFrame>();
532
554
  const outputWriter = audioStream.writable.getWriter();
@@ -558,10 +580,27 @@ export function performTTSInference(
558
580
  }
559
581
  })();
560
582
 
561
- const _performTTSInferenceImpl = async (signal: AbortSignal) => {
583
+ let ttfb: number | undefined;
584
+
585
+ const genData: _TTSGenerationData = {
586
+ audioStream: audioOutputStream,
587
+ timedTextsFut,
588
+ ttfb: undefined,
589
+ };
590
+
591
+ const _performTTSInferenceImpl = async (signal: AbortSignal, span: Span) => {
592
+ if (model) {
593
+ span.setAttribute(traceTypes.ATTR_GEN_AI_REQUEST_MODEL, model);
594
+ }
595
+ if (provider) {
596
+ span.setAttribute(traceTypes.ATTR_GEN_AI_PROVIDER_NAME, provider);
597
+ }
598
+
562
599
  let ttsStreamReader: ReadableStreamDefaultReader<AudioFrame> | null = null;
563
600
  let ttsStream: ReadableStream<AudioFrame> | null = null;
564
601
  let pushedDuration = 0;
602
+ const startTime = performance.now() / 1000; // Convert to seconds
603
+ let firstByteReceived = false;
565
604
 
566
605
  try {
567
606
  ttsStream = await node(textOnlyStream.readable, modelSettings);
@@ -595,6 +634,13 @@ export function performTTSInference(
595
634
  break;
596
635
  }
597
636
 
637
+ if (!firstByteReceived) {
638
+ firstByteReceived = true;
639
+ ttfb = performance.now() / 1000 - startTime;
640
+ genData.ttfb = ttfb;
641
+ span.setAttribute(traceTypes.ATTR_RESPONSE_TTFB, ttfb);
642
+ }
643
+
598
644
  // Write the audio frame to the output stream
599
645
  await outputWriter.write(frame);
600
646
 
@@ -631,6 +677,10 @@ export function performTTSInference(
631
677
  }
632
678
  throw error;
633
679
  } finally {
680
+ if (!timedTextsFut.done) {
681
+ // Ensure downstream consumers don't hang on errors.
682
+ timedTextsFut.resolve(null);
683
+ }
634
684
  ttsStreamReader?.releaseLock();
635
685
  await ttsStream?.cancel();
636
686
  await outputWriter.close();
@@ -642,16 +692,11 @@ export function performTTSInference(
642
692
  const currentContext = otelContext.active();
643
693
 
644
694
  const inferenceTask = async (signal: AbortSignal) =>
645
- tracer.startActiveSpan(async () => _performTTSInferenceImpl(signal), {
695
+ tracer.startActiveSpan(async (span) => _performTTSInferenceImpl(signal, span), {
646
696
  name: 'tts_node',
647
697
  context: currentContext,
648
698
  });
649
699
 
650
- const genData: _TTSGenerationData = {
651
- audioStream: audioOutputStream,
652
- timedTextsFut,
653
- };
654
-
655
700
  return [
656
701
  Task.from((controller) => inferenceTask(controller.signal), controller, 'performTTSInference'),
657
702
  genData,
@@ -719,7 +764,6 @@ export function performTextForwarding(
719
764
 
720
765
  export interface _AudioOut {
721
766
  audio: Array<AudioFrame>;
722
- /** Future that will be set with the timestamp of the first frame's capture */
723
767
  firstFrameFut: Future<number>;
724
768
  }
725
769
 
@@ -807,7 +851,6 @@ export function performAudioForwarding(
807
851
  ];
808
852
  }
809
853
 
810
- // function_tool span is already implemented in tracableToolExecution below (line ~796)
811
854
  export function performToolExecutions({
812
855
  session,
813
856
  speechHandle,
@@ -5,6 +5,7 @@ export { Agent, AgentTask, StopResponse, type AgentOptions, type ModelSettings }
5
5
  export { AgentSession, type AgentSessionOptions, type VoiceOptions } from './agent_session.js';
6
6
  export * from './avatar/index.js';
7
7
  export * from './background_audio.js';
8
+ export { type TextInputCallback, type TextInputEvent } from './client_events.js';
8
9
  export * from './events.js';
9
10
  export { type TimedString } from './io.js';
10
11
  export * from './report.js';
@@ -0,0 +1,117 @@
1
+ // SPDX-FileCopyrightText: 2026 LiveKit, Inc.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ import { describe, expect, it } from 'vitest';
5
+ import { ChatContext } from '../llm/chat_context.js';
6
+ import type { VoiceOptions } from './agent_session.js';
7
+ import { createSessionReport, sessionReportToJSON } from './report.js';
8
+
9
+ function baseOptions(): VoiceOptions {
10
+ return {
11
+ maxToolSteps: 3,
12
+ preemptiveGeneration: false,
13
+ userAwayTimeout: 15,
14
+ useTtsAlignedTranscript: true,
15
+ turnHandling: {},
16
+ };
17
+ }
18
+
19
+ function serializeOptions(options: VoiceOptions) {
20
+ const report = createSessionReport({
21
+ jobId: 'job',
22
+ roomId: 'room-id',
23
+ room: 'room',
24
+ options,
25
+ events: [],
26
+ chatHistory: ChatContext.empty(),
27
+ enableRecording: false,
28
+ timestamp: 0,
29
+ startedAt: 0,
30
+ });
31
+
32
+ const payload = sessionReportToJSON(report);
33
+ return payload.options as Record<string, unknown>;
34
+ }
35
+
36
+ describe('sessionReportToJSON', () => {
37
+ it('serializes interruption and endpointing values from turnHandling', () => {
38
+ const options = baseOptions();
39
+ options.turnHandling = {
40
+ interruption: {
41
+ mode: 'adaptive',
42
+ discardAudioIfUninterruptible: false,
43
+ minDuration: 1200,
44
+ minWords: 2,
45
+ },
46
+ endpointing: {
47
+ minDelay: 900,
48
+ maxDelay: 4500,
49
+ },
50
+ };
51
+
52
+ const serialized = serializeOptions(options);
53
+ expect(serialized).toMatchObject({
54
+ allow_interruptions: true,
55
+ discard_audio_if_uninterruptible: false,
56
+ min_interruption_duration: 1200,
57
+ min_interruption_words: 2,
58
+ min_endpointing_delay: 900,
59
+ max_endpointing_delay: 4500,
60
+ max_tool_steps: 3,
61
+ });
62
+ });
63
+
64
+ it('prefers turnHandling values over deprecated flat fields', () => {
65
+ const options = baseOptions();
66
+ options.allowInterruptions = false;
67
+ options.discardAudioIfUninterruptible = true;
68
+ options.minInterruptionDuration = 400;
69
+ options.minInterruptionWords = 1;
70
+ options.minEndpointingDelay = 500;
71
+ options.maxEndpointingDelay = 2500;
72
+ options.turnHandling = {
73
+ interruption: {
74
+ mode: 'vad',
75
+ discardAudioIfUninterruptible: false,
76
+ minDuration: 1400,
77
+ minWords: 4,
78
+ },
79
+ endpointing: {
80
+ minDelay: 700,
81
+ maxDelay: 3900,
82
+ },
83
+ };
84
+
85
+ const serialized = serializeOptions(options);
86
+ expect(serialized).toMatchObject({
87
+ allow_interruptions: true,
88
+ discard_audio_if_uninterruptible: false,
89
+ min_interruption_duration: 1400,
90
+ min_interruption_words: 4,
91
+ min_endpointing_delay: 700,
92
+ max_endpointing_delay: 3900,
93
+ max_tool_steps: 3,
94
+ });
95
+ });
96
+
97
+ it('falls back to deprecated flat fields when turnHandling values are absent', () => {
98
+ const options = baseOptions();
99
+ options.allowInterruptions = false;
100
+ options.discardAudioIfUninterruptible = false;
101
+ options.minInterruptionDuration = 600;
102
+ options.minInterruptionWords = 3;
103
+ options.minEndpointingDelay = 1000;
104
+ options.maxEndpointingDelay = 5000;
105
+
106
+ const serialized = serializeOptions(options);
107
+ expect(serialized).toMatchObject({
108
+ allow_interruptions: false,
109
+ discard_audio_if_uninterruptible: false,
110
+ min_interruption_duration: 600,
111
+ min_interruption_words: 3,
112
+ min_endpointing_delay: 1000,
113
+ max_endpointing_delay: 5000,
114
+ max_tool_steps: 3,
115
+ });
116
+ });
117
+ });
@@ -2,6 +2,7 @@
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
4
  import type { ChatContext } from '../llm/chat_context.js';
5
+ import { type ModelUsage, filterZeroValues } from '../metrics/model_usage.js';
5
6
  import type { VoiceOptions } from './agent_session.js';
6
7
  import type { AgentEvent } from './events.js';
7
8
 
@@ -23,6 +24,8 @@ export interface SessionReport {
23
24
  audioRecordingStartedAt?: number;
24
25
  /** Duration of the session in milliseconds */
25
26
  duration?: number;
27
+ /** Usage summaries for the session, one per model/provider combination */
28
+ modelUsage?: ModelUsage[];
26
29
  }
27
30
 
28
31
  export interface SessionReportOptions {
@@ -41,6 +44,8 @@ export interface SessionReportOptions {
41
44
  audioRecordingPath?: string;
42
45
  /** Timestamp when the audio recording started (milliseconds) */
43
46
  audioRecordingStartedAt?: number;
47
+ /** Usage summaries for the session, one per model/provider combination */
48
+ modelUsage?: ModelUsage[];
44
49
  }
45
50
 
46
51
  export function createSessionReport(opts: SessionReportOptions): SessionReport {
@@ -61,6 +66,7 @@ export function createSessionReport(opts: SessionReportOptions): SessionReport {
61
66
  audioRecordingStartedAt,
62
67
  duration:
63
68
  audioRecordingStartedAt !== undefined ? timestamp - audioRecordingStartedAt : undefined,
69
+ modelUsage: opts.modelUsage,
64
70
  };
65
71
  }
66
72
 
@@ -70,6 +76,22 @@ export function createSessionReport(opts: SessionReportOptions): SessionReport {
70
76
  // - Uploads to LiveKit Cloud observability endpoint with JWT auth
71
77
  export function sessionReportToJSON(report: SessionReport): Record<string, unknown> {
72
78
  const events: Record<string, unknown>[] = [];
79
+ const interruptionConfig = report.options.turnHandling?.interruption;
80
+ const endpointingConfig = report.options.turnHandling?.endpointing;
81
+
82
+ // Keep backwards compatibility with deprecated fields
83
+ const allowInterruptions =
84
+ interruptionConfig?.mode !== undefined
85
+ ? interruptionConfig.mode !== false
86
+ : report.options.allowInterruptions;
87
+ const discardAudioIfUninterruptible =
88
+ interruptionConfig?.discardAudioIfUninterruptible ??
89
+ report.options.discardAudioIfUninterruptible;
90
+ const minInterruptionDuration =
91
+ interruptionConfig?.minDuration ?? report.options.minInterruptionDuration;
92
+ const minInterruptionWords = interruptionConfig?.minWords ?? report.options.minInterruptionWords;
93
+ const minEndpointingDelay = endpointingConfig?.minDelay ?? report.options.minEndpointingDelay;
94
+ const maxEndpointingDelay = endpointingConfig?.maxDelay ?? report.options.maxEndpointingDelay;
73
95
 
74
96
  for (const event of report.events) {
75
97
  if (event.type === 'metrics_collected') {
@@ -85,16 +107,17 @@ export function sessionReportToJSON(report: SessionReport): Record<string, unkno
85
107
  room: report.room,
86
108
  events,
87
109
  options: {
88
- allow_interruptions: report.options.allowInterruptions,
89
- discard_audio_if_uninterruptible: report.options.discardAudioIfUninterruptible,
90
- min_interruption_duration: report.options.minInterruptionDuration,
91
- min_interruption_words: report.options.minInterruptionWords,
92
- min_endpointing_delay: report.options.minEndpointingDelay,
93
- max_endpointing_delay: report.options.maxEndpointingDelay,
110
+ allow_interruptions: allowInterruptions,
111
+ discard_audio_if_uninterruptible: discardAudioIfUninterruptible,
112
+ min_interruption_duration: minInterruptionDuration,
113
+ min_interruption_words: minInterruptionWords,
114
+ min_endpointing_delay: minEndpointingDelay,
115
+ max_endpointing_delay: maxEndpointingDelay,
94
116
  max_tool_steps: report.options.maxToolSteps,
95
117
  },
96
118
  chat_history: report.chatHistory.toJSON({ excludeTimestamp: false }),
97
119
  enable_user_data_training: report.enableRecording,
98
120
  timestamp: report.timestamp,
121
+ usage: report.modelUsage ? report.modelUsage.map(filterZeroValues) : null,
99
122
  };
100
123
  }
@@ -12,17 +12,16 @@ import {
12
12
  type RemoteParticipant,
13
13
  type Room,
14
14
  RoomEvent,
15
- type TextStreamInfo,
16
- type TextStreamReader,
17
15
  TrackPublishOptions,
18
16
  TrackSource,
19
17
  } from '@livekit/rtc-node';
20
18
  import type { WritableStreamDefaultWriter } from 'node:stream/web';
21
- import { ATTRIBUTE_PUBLISH_ON_BEHALF, TOPIC_CHAT } from '../../constants.js';
19
+ import { ATTRIBUTE_PUBLISH_ON_BEHALF } from '../../constants.js';
22
20
  import { log } from '../../log.js';
23
21
  import { IdentityTransform } from '../../stream/identity_transform.js';
24
- import { Future, Task } from '../../utils.js';
22
+ import { Future, Task, waitForAbort } from '../../utils.js';
25
23
  import { type AgentSession } from '../agent_session.js';
24
+ import type { TextInputCallback } from '../client_events.js';
26
25
  import {
27
26
  AgentSessionEventTypes,
28
27
  type AgentStateChangedEvent,
@@ -39,15 +38,7 @@ import {
39
38
  ParticipantTranscriptionOutput,
40
39
  } from './_output.js';
41
40
 
42
- export interface TextInputEvent {
43
- text: string;
44
- info: TextStreamInfo;
45
- participant: RemoteParticipant;
46
- }
47
-
48
- export type TextInputCallback = (sess: AgentSession, ev: TextInputEvent) => void | Promise<void>;
49
-
50
- const DEFAULT_TEXT_INPUT_CALLBACK: TextInputCallback = (sess: AgentSession, ev: TextInputEvent) => {
41
+ export const DEFAULT_TEXT_INPUT_CALLBACK: TextInputCallback = (sess, ev) => {
51
42
  sess.interrupt();
52
43
  sess.generateReply({ userInput: ev.text });
53
44
  };
@@ -146,8 +137,6 @@ export class RoomIO {
146
137
  private forwardUserTranscriptTask?: Task<void>;
147
138
  private initTask?: Task<void>;
148
139
 
149
- private textStreamHandlerRegistered = false;
150
-
151
140
  private logger = log();
152
141
 
153
142
  constructor({
@@ -177,7 +166,10 @@ export class RoomIO {
177
166
  : this.inputOptions.participantIdentity ?? null;
178
167
  }
179
168
  private async init(signal: AbortSignal): Promise<void> {
180
- await this.roomConnectedFuture.await;
169
+ await Promise.race([this.roomConnectedFuture.await, waitForAbort(signal)]);
170
+ if (signal.aborted) {
171
+ return;
172
+ }
181
173
 
182
174
  for (const participant of this.room.remoteParticipants.values()) {
183
175
  this.onParticipantConnected(participant);
@@ -186,7 +178,15 @@ export class RoomIO {
186
178
  return;
187
179
  }
188
180
 
189
- const participant = await this.participantAvailableFuture.await;
181
+ const participant = await Promise.race([
182
+ this.participantAvailableFuture.await,
183
+ waitForAbort(signal),
184
+ ]);
185
+
186
+ if (!participant) {
187
+ return;
188
+ }
189
+
190
190
  this.setParticipant(participant.identity);
191
191
 
192
192
  // init agent outputs
@@ -271,37 +271,6 @@ export class RoomIO {
271
271
  }
272
272
  };
273
273
 
274
- private onUserTextInput = (reader: TextStreamReader, participantInfo: { identity: string }) => {
275
- if (participantInfo.identity !== this.participantIdentity) {
276
- return;
277
- }
278
-
279
- const participant = this.room.remoteParticipants.get(participantInfo.identity);
280
- if (!participant) {
281
- this.logger.warn('participant not found, ignoring text input');
282
- return;
283
- }
284
-
285
- const readText = async () => {
286
- const text = await reader.readAll();
287
-
288
- const textInputResult = this.inputOptions.textInputCallback!(this.agentSession, {
289
- text,
290
- info: reader.info,
291
- participant,
292
- });
293
-
294
- // check if callback is a Promise
295
- if (textInputResult instanceof Promise) {
296
- await textInputResult;
297
- }
298
- };
299
-
300
- readText().catch((error) => {
301
- this.logger.error({ error }, 'Error reading text input');
302
- });
303
- };
304
-
305
274
  private async forwardUserTranscript(signal: AbortSignal): Promise<void> {
306
275
  const reader = this.userTranscriptStream.readable.getReader();
307
276
  try {
@@ -376,6 +345,10 @@ export class RoomIO {
376
345
  return this.participantAvailableFuture.done;
377
346
  }
378
347
 
348
+ get rtcRoom(): Room {
349
+ return this.room;
350
+ }
351
+
379
352
  get linkedParticipant(): RemoteParticipant | undefined {
380
353
  if (!this.isParticipantAvailable) {
381
354
  return undefined;
@@ -428,17 +401,6 @@ export class RoomIO {
428
401
  }
429
402
 
430
403
  start() {
431
- if (this.inputOptions.textEnabled) {
432
- try {
433
- this.room.registerTextStreamHandler(TOPIC_CHAT, this.onUserTextInput);
434
- this.textStreamHandlerRegistered = true;
435
- } catch (error) {
436
- if (this.inputOptions.textEnabled) {
437
- this.logger.warn(`text stream handler for topic "${TOPIC_CHAT}" already set, ignoring`);
438
- }
439
- }
440
- }
441
-
442
404
  // -- create inputs --
443
405
  if (this.inputOptions.audioEnabled) {
444
406
  this.audioInput = new ParticipantAudioInputStream({
@@ -514,11 +476,6 @@ export class RoomIO {
514
476
  this.agentSession.off(AgentSessionEventTypes.UserInputTranscribed, this.onUserInputTranscribed);
515
477
  this.agentSession.off(AgentSessionEventTypes.AgentStateChanged, this.onAgentStateChanged);
516
478
 
517
- if (this.textStreamHandlerRegistered) {
518
- this.room.unregisterTextStreamHandler(TOPIC_CHAT);
519
- this.textStreamHandlerRegistered = false;
520
- }
521
-
522
479
  await this.initTask?.cancelAndWait();
523
480
 
524
481
  // Close stream FIRST so reader.read() in forwardUserTranscript can exit.