@livekit/agents 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (959) hide show
  1. package/dist/_exceptions.cjs.map +1 -1
  2. package/dist/_exceptions.d.ts.map +1 -1
  3. package/dist/_exceptions.js.map +1 -1
  4. package/dist/audio.cjs +89 -3
  5. package/dist/audio.cjs.map +1 -1
  6. package/dist/audio.d.cts +36 -1
  7. package/dist/audio.d.ts +36 -1
  8. package/dist/audio.d.ts.map +1 -1
  9. package/dist/audio.js +76 -2
  10. package/dist/audio.js.map +1 -1
  11. package/dist/beta/index.cjs +29 -0
  12. package/dist/beta/index.cjs.map +1 -0
  13. package/dist/beta/index.d.cts +2 -0
  14. package/dist/beta/index.d.ts +2 -0
  15. package/dist/beta/index.d.ts.map +1 -0
  16. package/dist/beta/index.js +7 -0
  17. package/dist/beta/index.js.map +1 -0
  18. package/dist/beta/workflows/index.cjs +29 -0
  19. package/dist/beta/workflows/index.cjs.map +1 -0
  20. package/dist/beta/workflows/index.d.cts +2 -0
  21. package/dist/beta/workflows/index.d.ts +2 -0
  22. package/dist/beta/workflows/index.d.ts.map +1 -0
  23. package/dist/beta/workflows/index.js +7 -0
  24. package/dist/beta/workflows/index.js.map +1 -0
  25. package/dist/beta/workflows/task_group.cjs +165 -0
  26. package/dist/beta/workflows/task_group.cjs.map +1 -0
  27. package/dist/beta/workflows/task_group.d.cts +32 -0
  28. package/dist/beta/workflows/task_group.d.ts +32 -0
  29. package/dist/beta/workflows/task_group.d.ts.map +1 -0
  30. package/dist/beta/workflows/task_group.js +141 -0
  31. package/dist/beta/workflows/task_group.js.map +1 -0
  32. package/dist/cli.cjs +44 -46
  33. package/dist/cli.cjs.map +1 -1
  34. package/dist/cli.d.cts +3 -3
  35. package/dist/cli.d.ts +3 -3
  36. package/dist/cli.d.ts.map +1 -1
  37. package/dist/cli.js +45 -47
  38. package/dist/cli.js.map +1 -1
  39. package/dist/connection_pool.cjs +242 -0
  40. package/dist/connection_pool.cjs.map +1 -0
  41. package/dist/connection_pool.d.cts +123 -0
  42. package/dist/connection_pool.d.ts +123 -0
  43. package/dist/connection_pool.d.ts.map +1 -0
  44. package/dist/connection_pool.js +218 -0
  45. package/dist/connection_pool.js.map +1 -0
  46. package/dist/connection_pool.test.cjs +256 -0
  47. package/dist/connection_pool.test.cjs.map +1 -0
  48. package/dist/connection_pool.test.js +255 -0
  49. package/dist/connection_pool.test.js.map +1 -0
  50. package/dist/constants.cjs +30 -0
  51. package/dist/constants.cjs.map +1 -1
  52. package/dist/constants.d.cts +10 -0
  53. package/dist/constants.d.ts +10 -0
  54. package/dist/constants.d.ts.map +1 -1
  55. package/dist/constants.js +20 -0
  56. package/dist/constants.js.map +1 -1
  57. package/dist/cpu.cjs +189 -0
  58. package/dist/cpu.cjs.map +1 -0
  59. package/dist/cpu.d.cts +24 -0
  60. package/dist/cpu.d.ts +24 -0
  61. package/dist/cpu.d.ts.map +1 -0
  62. package/dist/cpu.js +152 -0
  63. package/dist/cpu.js.map +1 -0
  64. package/dist/cpu.test.cjs +227 -0
  65. package/dist/cpu.test.cjs.map +1 -0
  66. package/dist/cpu.test.js +204 -0
  67. package/dist/cpu.test.js.map +1 -0
  68. package/dist/http_server.cjs +9 -6
  69. package/dist/http_server.cjs.map +1 -1
  70. package/dist/http_server.d.cts +5 -1
  71. package/dist/http_server.d.ts +5 -1
  72. package/dist/http_server.d.ts.map +1 -1
  73. package/dist/http_server.js +9 -6
  74. package/dist/http_server.js.map +1 -1
  75. package/dist/index.cjs +24 -9
  76. package/dist/index.cjs.map +1 -1
  77. package/dist/index.d.cts +15 -11
  78. package/dist/index.d.ts +15 -11
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +18 -9
  81. package/dist/index.js.map +1 -1
  82. package/dist/inference/api_protos.cjs +70 -2
  83. package/dist/inference/api_protos.cjs.map +1 -1
  84. package/dist/inference/api_protos.d.cts +373 -32
  85. package/dist/inference/api_protos.d.ts +373 -32
  86. package/dist/inference/api_protos.d.ts.map +1 -1
  87. package/dist/inference/api_protos.js +62 -2
  88. package/dist/inference/api_protos.js.map +1 -1
  89. package/dist/inference/index.cjs +8 -0
  90. package/dist/inference/index.cjs.map +1 -1
  91. package/dist/inference/index.d.cts +3 -4
  92. package/dist/inference/index.d.ts +3 -4
  93. package/dist/inference/index.d.ts.map +1 -1
  94. package/dist/inference/index.js +18 -3
  95. package/dist/inference/index.js.map +1 -1
  96. package/dist/inference/interruption/defaults.cjs +81 -0
  97. package/dist/inference/interruption/defaults.cjs.map +1 -0
  98. package/dist/inference/interruption/defaults.d.cts +19 -0
  99. package/dist/inference/interruption/defaults.d.ts +19 -0
  100. package/dist/inference/interruption/defaults.d.ts.map +1 -0
  101. package/dist/inference/interruption/defaults.js +46 -0
  102. package/dist/inference/interruption/defaults.js.map +1 -0
  103. package/dist/inference/interruption/errors.cjs +44 -0
  104. package/dist/inference/interruption/errors.cjs.map +1 -0
  105. package/dist/inference/interruption/errors.d.cts +12 -0
  106. package/dist/inference/interruption/errors.d.ts +12 -0
  107. package/dist/inference/interruption/errors.d.ts.map +1 -0
  108. package/dist/inference/interruption/errors.js +20 -0
  109. package/dist/inference/interruption/errors.js.map +1 -0
  110. package/dist/inference/interruption/http_transport.cjs +163 -0
  111. package/dist/inference/interruption/http_transport.cjs.map +1 -0
  112. package/dist/inference/interruption/http_transport.d.cts +65 -0
  113. package/dist/inference/interruption/http_transport.d.ts +65 -0
  114. package/dist/inference/interruption/http_transport.d.ts.map +1 -0
  115. package/dist/inference/interruption/http_transport.js +137 -0
  116. package/dist/inference/interruption/http_transport.js.map +1 -0
  117. package/dist/inference/interruption/interruption_cache_entry.cjs +58 -0
  118. package/dist/inference/interruption/interruption_cache_entry.cjs.map +1 -0
  119. package/dist/inference/interruption/interruption_cache_entry.d.cts +30 -0
  120. package/dist/inference/interruption/interruption_cache_entry.d.ts +30 -0
  121. package/dist/inference/interruption/interruption_cache_entry.d.ts.map +1 -0
  122. package/dist/inference/interruption/interruption_cache_entry.js +34 -0
  123. package/dist/inference/interruption/interruption_cache_entry.js.map +1 -0
  124. package/dist/inference/interruption/interruption_detector.cjs +198 -0
  125. package/dist/inference/interruption/interruption_detector.cjs.map +1 -0
  126. package/dist/inference/interruption/interruption_detector.d.cts +59 -0
  127. package/dist/inference/interruption/interruption_detector.d.ts +59 -0
  128. package/dist/inference/interruption/interruption_detector.d.ts.map +1 -0
  129. package/dist/inference/interruption/interruption_detector.js +164 -0
  130. package/dist/inference/interruption/interruption_detector.js.map +1 -0
  131. package/dist/inference/interruption/interruption_stream.cjs +368 -0
  132. package/dist/inference/interruption/interruption_stream.cjs.map +1 -0
  133. package/dist/inference/interruption/interruption_stream.d.cts +46 -0
  134. package/dist/inference/interruption/interruption_stream.d.ts +46 -0
  135. package/dist/inference/interruption/interruption_stream.d.ts.map +1 -0
  136. package/dist/inference/interruption/interruption_stream.js +344 -0
  137. package/dist/inference/interruption/interruption_stream.js.map +1 -0
  138. package/dist/inference/interruption/types.cjs +17 -0
  139. package/dist/inference/interruption/types.cjs.map +1 -0
  140. package/dist/inference/interruption/types.d.cts +66 -0
  141. package/dist/inference/interruption/types.d.ts +66 -0
  142. package/dist/inference/interruption/types.d.ts.map +1 -0
  143. package/dist/inference/interruption/types.js +1 -0
  144. package/dist/inference/interruption/types.js.map +1 -0
  145. package/dist/inference/interruption/utils.cjs +130 -0
  146. package/dist/inference/interruption/utils.cjs.map +1 -0
  147. package/dist/inference/interruption/utils.d.cts +41 -0
  148. package/dist/inference/interruption/utils.d.ts +41 -0
  149. package/dist/inference/interruption/utils.d.ts.map +1 -0
  150. package/dist/inference/interruption/utils.js +105 -0
  151. package/dist/inference/interruption/utils.js.map +1 -0
  152. package/dist/inference/interruption/utils.test.cjs +105 -0
  153. package/dist/inference/interruption/utils.test.cjs.map +1 -0
  154. package/dist/inference/interruption/utils.test.js +104 -0
  155. package/dist/inference/interruption/utils.test.js.map +1 -0
  156. package/dist/inference/interruption/ws_transport.cjs +347 -0
  157. package/dist/inference/interruption/ws_transport.cjs.map +1 -0
  158. package/dist/inference/interruption/ws_transport.d.cts +33 -0
  159. package/dist/inference/interruption/ws_transport.d.ts +33 -0
  160. package/dist/inference/interruption/ws_transport.d.ts.map +1 -0
  161. package/dist/inference/interruption/ws_transport.js +313 -0
  162. package/dist/inference/interruption/ws_transport.js.map +1 -0
  163. package/dist/inference/llm.cjs +106 -66
  164. package/dist/inference/llm.cjs.map +1 -1
  165. package/dist/inference/llm.d.cts +65 -43
  166. package/dist/inference/llm.d.ts +65 -43
  167. package/dist/inference/llm.d.ts.map +1 -1
  168. package/dist/inference/llm.js +100 -66
  169. package/dist/inference/llm.js.map +1 -1
  170. package/dist/inference/stt.cjs +319 -170
  171. package/dist/inference/stt.cjs.map +1 -1
  172. package/dist/inference/stt.d.cts +64 -15
  173. package/dist/inference/stt.d.ts +64 -15
  174. package/dist/inference/stt.d.ts.map +1 -1
  175. package/dist/inference/stt.js +319 -170
  176. package/dist/inference/stt.js.map +1 -1
  177. package/dist/inference/stt.test.cjs +218 -0
  178. package/dist/inference/stt.test.cjs.map +1 -0
  179. package/dist/inference/stt.test.js +217 -0
  180. package/dist/inference/stt.test.js.map +1 -0
  181. package/dist/inference/tts.cjs +249 -71
  182. package/dist/inference/tts.cjs.map +1 -1
  183. package/dist/inference/tts.d.cts +94 -17
  184. package/dist/inference/tts.d.ts +94 -17
  185. package/dist/inference/tts.d.ts.map +1 -1
  186. package/dist/inference/tts.js +249 -77
  187. package/dist/inference/tts.js.map +1 -1
  188. package/dist/inference/tts.test.cjs +305 -0
  189. package/dist/inference/tts.test.cjs.map +1 -0
  190. package/dist/inference/tts.test.js +304 -0
  191. package/dist/inference/tts.test.js.map +1 -0
  192. package/dist/inference/utils.cjs +26 -7
  193. package/dist/inference/utils.cjs.map +1 -1
  194. package/dist/inference/utils.d.cts +14 -1
  195. package/dist/inference/utils.d.ts +14 -1
  196. package/dist/inference/utils.d.ts.map +1 -1
  197. package/dist/inference/utils.js +18 -2
  198. package/dist/inference/utils.js.map +1 -1
  199. package/dist/ipc/inference_proc_executor.cjs +6 -3
  200. package/dist/ipc/inference_proc_executor.cjs.map +1 -1
  201. package/dist/ipc/inference_proc_executor.d.ts.map +1 -1
  202. package/dist/ipc/inference_proc_executor.js +6 -3
  203. package/dist/ipc/inference_proc_executor.js.map +1 -1
  204. package/dist/ipc/inference_proc_lazy_main.cjs +13 -1
  205. package/dist/ipc/inference_proc_lazy_main.cjs.map +1 -1
  206. package/dist/ipc/inference_proc_lazy_main.js +13 -1
  207. package/dist/ipc/inference_proc_lazy_main.js.map +1 -1
  208. package/dist/ipc/job_proc_executor.cjs +6 -1
  209. package/dist/ipc/job_proc_executor.cjs.map +1 -1
  210. package/dist/ipc/job_proc_executor.d.ts.map +1 -1
  211. package/dist/ipc/job_proc_executor.js +6 -1
  212. package/dist/ipc/job_proc_executor.js.map +1 -1
  213. package/dist/ipc/job_proc_lazy_main.cjs +89 -17
  214. package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
  215. package/dist/ipc/job_proc_lazy_main.js +68 -18
  216. package/dist/ipc/job_proc_lazy_main.js.map +1 -1
  217. package/dist/ipc/supervised_proc.cjs +34 -8
  218. package/dist/ipc/supervised_proc.cjs.map +1 -1
  219. package/dist/ipc/supervised_proc.d.cts +8 -0
  220. package/dist/ipc/supervised_proc.d.ts +8 -0
  221. package/dist/ipc/supervised_proc.d.ts.map +1 -1
  222. package/dist/ipc/supervised_proc.js +34 -8
  223. package/dist/ipc/supervised_proc.js.map +1 -1
  224. package/dist/ipc/supervised_proc.test.cjs +145 -0
  225. package/dist/ipc/supervised_proc.test.cjs.map +1 -0
  226. package/dist/ipc/supervised_proc.test.js +122 -0
  227. package/dist/ipc/supervised_proc.test.js.map +1 -0
  228. package/dist/job.cjs +109 -1
  229. package/dist/job.cjs.map +1 -1
  230. package/dist/job.d.cts +14 -0
  231. package/dist/job.d.ts +14 -0
  232. package/dist/job.d.ts.map +1 -1
  233. package/dist/job.js +99 -1
  234. package/dist/job.js.map +1 -1
  235. package/dist/language.cjs +394 -0
  236. package/dist/language.cjs.map +1 -0
  237. package/dist/language.d.cts +15 -0
  238. package/dist/language.d.ts +15 -0
  239. package/dist/language.d.ts.map +1 -0
  240. package/dist/language.js +363 -0
  241. package/dist/language.js.map +1 -0
  242. package/dist/language.test.cjs +43 -0
  243. package/dist/language.test.cjs.map +1 -0
  244. package/dist/language.test.js +49 -0
  245. package/dist/language.test.js.map +1 -0
  246. package/dist/llm/chat_context.cjs +345 -3
  247. package/dist/llm/chat_context.cjs.map +1 -1
  248. package/dist/llm/chat_context.d.cts +86 -2
  249. package/dist/llm/chat_context.d.ts +86 -2
  250. package/dist/llm/chat_context.d.ts.map +1 -1
  251. package/dist/llm/chat_context.js +344 -3
  252. package/dist/llm/chat_context.js.map +1 -1
  253. package/dist/llm/chat_context.test.cjs +692 -0
  254. package/dist/llm/chat_context.test.cjs.map +1 -1
  255. package/dist/llm/chat_context.test.js +692 -0
  256. package/dist/llm/chat_context.test.js.map +1 -1
  257. package/dist/llm/fallback_adapter.cjs +280 -0
  258. package/dist/llm/fallback_adapter.cjs.map +1 -0
  259. package/dist/llm/fallback_adapter.d.cts +73 -0
  260. package/dist/llm/fallback_adapter.d.ts +73 -0
  261. package/dist/llm/fallback_adapter.d.ts.map +1 -0
  262. package/dist/llm/fallback_adapter.js +256 -0
  263. package/dist/llm/fallback_adapter.js.map +1 -0
  264. package/dist/llm/fallback_adapter.test.cjs +176 -0
  265. package/dist/llm/fallback_adapter.test.cjs.map +1 -0
  266. package/dist/llm/fallback_adapter.test.js +175 -0
  267. package/dist/llm/fallback_adapter.test.js.map +1 -0
  268. package/dist/llm/index.cjs +11 -0
  269. package/dist/llm/index.cjs.map +1 -1
  270. package/dist/llm/index.d.cts +4 -3
  271. package/dist/llm/index.d.ts +4 -3
  272. package/dist/llm/index.d.ts.map +1 -1
  273. package/dist/llm/index.js +13 -1
  274. package/dist/llm/index.js.map +1 -1
  275. package/dist/llm/llm.cjs +65 -11
  276. package/dist/llm/llm.cjs.map +1 -1
  277. package/dist/llm/llm.d.cts +13 -2
  278. package/dist/llm/llm.d.ts +13 -2
  279. package/dist/llm/llm.d.ts.map +1 -1
  280. package/dist/llm/llm.js +65 -11
  281. package/dist/llm/llm.js.map +1 -1
  282. package/dist/llm/provider_format/google.cjs +6 -2
  283. package/dist/llm/provider_format/google.cjs.map +1 -1
  284. package/dist/llm/provider_format/google.d.cts +1 -1
  285. package/dist/llm/provider_format/google.d.ts +1 -1
  286. package/dist/llm/provider_format/google.d.ts.map +1 -1
  287. package/dist/llm/provider_format/google.js +6 -2
  288. package/dist/llm/provider_format/google.js.map +1 -1
  289. package/dist/llm/provider_format/google.test.cjs +48 -0
  290. package/dist/llm/provider_format/google.test.cjs.map +1 -1
  291. package/dist/llm/provider_format/google.test.js +54 -1
  292. package/dist/llm/provider_format/google.test.js.map +1 -1
  293. package/dist/llm/provider_format/index.cjs +2 -0
  294. package/dist/llm/provider_format/index.cjs.map +1 -1
  295. package/dist/llm/provider_format/index.d.cts +2 -2
  296. package/dist/llm/provider_format/index.d.ts +2 -2
  297. package/dist/llm/provider_format/index.d.ts.map +1 -1
  298. package/dist/llm/provider_format/index.js +6 -1
  299. package/dist/llm/provider_format/index.js.map +1 -1
  300. package/dist/llm/provider_format/openai.cjs +126 -24
  301. package/dist/llm/provider_format/openai.cjs.map +1 -1
  302. package/dist/llm/provider_format/openai.d.cts +1 -0
  303. package/dist/llm/provider_format/openai.d.ts +1 -0
  304. package/dist/llm/provider_format/openai.d.ts.map +1 -1
  305. package/dist/llm/provider_format/openai.js +124 -23
  306. package/dist/llm/provider_format/openai.js.map +1 -1
  307. package/dist/llm/provider_format/openai.test.cjs +393 -0
  308. package/dist/llm/provider_format/openai.test.cjs.map +1 -1
  309. package/dist/llm/provider_format/openai.test.js +400 -2
  310. package/dist/llm/provider_format/openai.test.js.map +1 -1
  311. package/dist/llm/provider_format/utils.cjs +5 -4
  312. package/dist/llm/provider_format/utils.cjs.map +1 -1
  313. package/dist/llm/provider_format/utils.d.ts.map +1 -1
  314. package/dist/llm/provider_format/utils.js +5 -4
  315. package/dist/llm/provider_format/utils.js.map +1 -1
  316. package/dist/llm/realtime.cjs +3 -0
  317. package/dist/llm/realtime.cjs.map +1 -1
  318. package/dist/llm/realtime.d.cts +15 -1
  319. package/dist/llm/realtime.d.ts +15 -1
  320. package/dist/llm/realtime.d.ts.map +1 -1
  321. package/dist/llm/realtime.js +3 -0
  322. package/dist/llm/realtime.js.map +1 -1
  323. package/dist/llm/remote_chat_context.cjs.map +1 -1
  324. package/dist/llm/remote_chat_context.d.cts +2 -0
  325. package/dist/llm/remote_chat_context.d.ts +2 -0
  326. package/dist/llm/remote_chat_context.d.ts.map +1 -1
  327. package/dist/llm/remote_chat_context.js.map +1 -1
  328. package/dist/llm/tool_context.cjs +50 -2
  329. package/dist/llm/tool_context.cjs.map +1 -1
  330. package/dist/llm/tool_context.d.cts +47 -11
  331. package/dist/llm/tool_context.d.ts +47 -11
  332. package/dist/llm/tool_context.d.ts.map +1 -1
  333. package/dist/llm/tool_context.js +48 -3
  334. package/dist/llm/tool_context.js.map +1 -1
  335. package/dist/llm/tool_context.test.cjs +197 -0
  336. package/dist/llm/tool_context.test.cjs.map +1 -1
  337. package/dist/llm/tool_context.test.js +175 -0
  338. package/dist/llm/tool_context.test.js.map +1 -1
  339. package/dist/llm/utils.cjs +107 -12
  340. package/dist/llm/utils.cjs.map +1 -1
  341. package/dist/llm/utils.d.cts +10 -3
  342. package/dist/llm/utils.d.ts +10 -3
  343. package/dist/llm/utils.d.ts.map +1 -1
  344. package/dist/llm/utils.js +106 -12
  345. package/dist/llm/utils.js.map +1 -1
  346. package/dist/llm/utils.test.cjs +90 -0
  347. package/dist/llm/utils.test.cjs.map +1 -1
  348. package/dist/llm/utils.test.js +98 -2
  349. package/dist/llm/utils.test.js.map +1 -1
  350. package/dist/llm/zod-utils.cjs +102 -0
  351. package/dist/llm/zod-utils.cjs.map +1 -0
  352. package/dist/llm/zod-utils.d.cts +65 -0
  353. package/dist/llm/zod-utils.d.ts +65 -0
  354. package/dist/llm/zod-utils.d.ts.map +1 -0
  355. package/dist/llm/zod-utils.js +64 -0
  356. package/dist/llm/zod-utils.js.map +1 -0
  357. package/dist/llm/zod-utils.test.cjs +472 -0
  358. package/dist/llm/zod-utils.test.cjs.map +1 -0
  359. package/dist/llm/zod-utils.test.js +455 -0
  360. package/dist/llm/zod-utils.test.js.map +1 -0
  361. package/dist/log.cjs +45 -14
  362. package/dist/log.cjs.map +1 -1
  363. package/dist/log.d.cts +8 -1
  364. package/dist/log.d.ts +8 -1
  365. package/dist/log.d.ts.map +1 -1
  366. package/dist/log.js +45 -15
  367. package/dist/log.js.map +1 -1
  368. package/dist/metrics/base.cjs.map +1 -1
  369. package/dist/metrics/base.d.cts +75 -19
  370. package/dist/metrics/base.d.ts +75 -19
  371. package/dist/metrics/base.d.ts.map +1 -1
  372. package/dist/metrics/index.cjs +5 -0
  373. package/dist/metrics/index.cjs.map +1 -1
  374. package/dist/metrics/index.d.cts +2 -1
  375. package/dist/metrics/index.d.ts +2 -1
  376. package/dist/metrics/index.d.ts.map +1 -1
  377. package/dist/metrics/index.js +6 -0
  378. package/dist/metrics/index.js.map +1 -1
  379. package/dist/metrics/model_usage.cjs +189 -0
  380. package/dist/metrics/model_usage.cjs.map +1 -0
  381. package/dist/metrics/model_usage.d.cts +92 -0
  382. package/dist/metrics/model_usage.d.ts +92 -0
  383. package/dist/metrics/model_usage.d.ts.map +1 -0
  384. package/dist/metrics/model_usage.js +164 -0
  385. package/dist/metrics/model_usage.js.map +1 -0
  386. package/dist/metrics/model_usage.test.cjs +474 -0
  387. package/dist/metrics/model_usage.test.cjs.map +1 -0
  388. package/dist/metrics/model_usage.test.js +476 -0
  389. package/dist/metrics/model_usage.test.js.map +1 -0
  390. package/dist/metrics/usage_collector.cjs +5 -2
  391. package/dist/metrics/usage_collector.cjs.map +1 -1
  392. package/dist/metrics/usage_collector.d.cts +10 -1
  393. package/dist/metrics/usage_collector.d.ts +10 -1
  394. package/dist/metrics/usage_collector.d.ts.map +1 -1
  395. package/dist/metrics/usage_collector.js +5 -2
  396. package/dist/metrics/usage_collector.js.map +1 -1
  397. package/dist/metrics/utils.cjs +23 -7
  398. package/dist/metrics/utils.cjs.map +1 -1
  399. package/dist/metrics/utils.d.ts.map +1 -1
  400. package/dist/metrics/utils.js +23 -7
  401. package/dist/metrics/utils.js.map +1 -1
  402. package/dist/stream/deferred_stream.cjs +31 -10
  403. package/dist/stream/deferred_stream.cjs.map +1 -1
  404. package/dist/stream/deferred_stream.d.cts +6 -1
  405. package/dist/stream/deferred_stream.d.ts +6 -1
  406. package/dist/stream/deferred_stream.d.ts.map +1 -1
  407. package/dist/stream/deferred_stream.js +31 -10
  408. package/dist/stream/deferred_stream.js.map +1 -1
  409. package/dist/stream/deferred_stream.test.cjs +2 -2
  410. package/dist/stream/deferred_stream.test.cjs.map +1 -1
  411. package/dist/stream/deferred_stream.test.js +2 -2
  412. package/dist/stream/deferred_stream.test.js.map +1 -1
  413. package/dist/stream/index.cjs +3 -0
  414. package/dist/stream/index.cjs.map +1 -1
  415. package/dist/stream/index.d.cts +1 -0
  416. package/dist/stream/index.d.ts +1 -0
  417. package/dist/stream/index.d.ts.map +1 -1
  418. package/dist/stream/index.js +2 -0
  419. package/dist/stream/index.js.map +1 -1
  420. package/dist/stream/multi_input_stream.cjs +139 -0
  421. package/dist/stream/multi_input_stream.cjs.map +1 -0
  422. package/dist/stream/multi_input_stream.d.cts +55 -0
  423. package/dist/stream/multi_input_stream.d.ts +55 -0
  424. package/dist/stream/multi_input_stream.d.ts.map +1 -0
  425. package/dist/stream/multi_input_stream.js +115 -0
  426. package/dist/stream/multi_input_stream.js.map +1 -0
  427. package/dist/stream/multi_input_stream.test.cjs +344 -0
  428. package/dist/stream/multi_input_stream.test.cjs.map +1 -0
  429. package/dist/stream/multi_input_stream.test.js +343 -0
  430. package/dist/stream/multi_input_stream.test.js.map +1 -0
  431. package/dist/stream/stream_channel.cjs +39 -1
  432. package/dist/stream/stream_channel.cjs.map +1 -1
  433. package/dist/stream/stream_channel.d.cts +5 -2
  434. package/dist/stream/stream_channel.d.ts +5 -2
  435. package/dist/stream/stream_channel.d.ts.map +1 -1
  436. package/dist/stream/stream_channel.js +39 -1
  437. package/dist/stream/stream_channel.js.map +1 -1
  438. package/dist/stream/stream_channel.test.cjs +27 -0
  439. package/dist/stream/stream_channel.test.cjs.map +1 -1
  440. package/dist/stream/stream_channel.test.js +27 -0
  441. package/dist/stream/stream_channel.test.js.map +1 -1
  442. package/dist/stt/stream_adapter.cjs +24 -9
  443. package/dist/stt/stream_adapter.cjs.map +1 -1
  444. package/dist/stt/stream_adapter.d.cts +7 -3
  445. package/dist/stt/stream_adapter.d.ts +7 -3
  446. package/dist/stt/stream_adapter.d.ts.map +1 -1
  447. package/dist/stt/stream_adapter.js +24 -9
  448. package/dist/stt/stream_adapter.js.map +1 -1
  449. package/dist/stt/stt.cjs +94 -19
  450. package/dist/stt/stt.cjs.map +1 -1
  451. package/dist/stt/stt.d.cts +68 -5
  452. package/dist/stt/stt.d.ts +68 -5
  453. package/dist/stt/stt.d.ts.map +1 -1
  454. package/dist/stt/stt.js +96 -21
  455. package/dist/stt/stt.js.map +1 -1
  456. package/dist/telemetry/index.cjs +72 -0
  457. package/dist/telemetry/index.cjs.map +1 -0
  458. package/dist/telemetry/index.d.cts +7 -0
  459. package/dist/telemetry/index.d.ts +7 -0
  460. package/dist/telemetry/index.d.ts.map +1 -0
  461. package/dist/telemetry/index.js +37 -0
  462. package/dist/telemetry/index.js.map +1 -0
  463. package/dist/telemetry/logging.cjs +65 -0
  464. package/dist/telemetry/logging.cjs.map +1 -0
  465. package/dist/telemetry/logging.d.cts +21 -0
  466. package/dist/telemetry/logging.d.ts +21 -0
  467. package/dist/telemetry/logging.d.ts.map +1 -0
  468. package/dist/telemetry/logging.js +40 -0
  469. package/dist/telemetry/logging.js.map +1 -0
  470. package/dist/telemetry/otel_http_exporter.cjs +166 -0
  471. package/dist/telemetry/otel_http_exporter.cjs.map +1 -0
  472. package/dist/telemetry/otel_http_exporter.d.cts +63 -0
  473. package/dist/telemetry/otel_http_exporter.d.ts +63 -0
  474. package/dist/telemetry/otel_http_exporter.d.ts.map +1 -0
  475. package/dist/telemetry/otel_http_exporter.js +142 -0
  476. package/dist/telemetry/otel_http_exporter.js.map +1 -0
  477. package/dist/telemetry/pino_otel_transport.cjs +217 -0
  478. package/dist/telemetry/pino_otel_transport.cjs.map +1 -0
  479. package/dist/telemetry/pino_otel_transport.d.cts +58 -0
  480. package/dist/telemetry/pino_otel_transport.d.ts +58 -0
  481. package/dist/telemetry/pino_otel_transport.d.ts.map +1 -0
  482. package/dist/telemetry/pino_otel_transport.js +189 -0
  483. package/dist/telemetry/pino_otel_transport.js.map +1 -0
  484. package/dist/telemetry/trace_types.cjs +233 -0
  485. package/dist/telemetry/trace_types.cjs.map +1 -0
  486. package/dist/telemetry/trace_types.d.cts +74 -0
  487. package/dist/telemetry/trace_types.d.ts +74 -0
  488. package/dist/telemetry/trace_types.d.ts.map +1 -0
  489. package/dist/telemetry/trace_types.js +141 -0
  490. package/dist/telemetry/trace_types.js.map +1 -0
  491. package/dist/telemetry/traces.cjs +484 -0
  492. package/dist/telemetry/traces.cjs.map +1 -0
  493. package/dist/telemetry/traces.d.cts +116 -0
  494. package/dist/telemetry/traces.d.ts +116 -0
  495. package/dist/telemetry/traces.d.ts.map +1 -0
  496. package/dist/telemetry/traces.js +449 -0
  497. package/dist/telemetry/traces.js.map +1 -0
  498. package/dist/telemetry/utils.cjs +86 -0
  499. package/dist/telemetry/utils.cjs.map +1 -0
  500. package/dist/telemetry/utils.d.cts +5 -0
  501. package/dist/telemetry/utils.d.ts +5 -0
  502. package/dist/telemetry/utils.d.ts.map +1 -0
  503. package/dist/telemetry/utils.js +51 -0
  504. package/dist/telemetry/utils.js.map +1 -0
  505. package/dist/tokenize/basic/sentence.cjs +3 -3
  506. package/dist/tokenize/basic/sentence.cjs.map +1 -1
  507. package/dist/tokenize/basic/sentence.js +3 -3
  508. package/dist/tokenize/basic/sentence.js.map +1 -1
  509. package/dist/tokenize/tokenizer.test.cjs +3 -1
  510. package/dist/tokenize/tokenizer.test.cjs.map +1 -1
  511. package/dist/tokenize/tokenizer.test.js +3 -1
  512. package/dist/tokenize/tokenizer.test.js.map +1 -1
  513. package/dist/transcription.cjs.map +1 -1
  514. package/dist/transcription.d.cts +6 -0
  515. package/dist/transcription.d.ts +6 -0
  516. package/dist/transcription.d.ts.map +1 -1
  517. package/dist/transcription.js.map +1 -1
  518. package/dist/tts/fallback_adapter.cjs +472 -0
  519. package/dist/tts/fallback_adapter.cjs.map +1 -0
  520. package/dist/tts/fallback_adapter.d.cts +110 -0
  521. package/dist/tts/fallback_adapter.d.ts +110 -0
  522. package/dist/tts/fallback_adapter.d.ts.map +1 -0
  523. package/dist/tts/fallback_adapter.js +448 -0
  524. package/dist/tts/fallback_adapter.js.map +1 -0
  525. package/dist/tts/index.cjs +3 -0
  526. package/dist/tts/index.cjs.map +1 -1
  527. package/dist/tts/index.d.cts +1 -0
  528. package/dist/tts/index.d.ts +1 -0
  529. package/dist/tts/index.d.ts.map +1 -1
  530. package/dist/tts/index.js +2 -0
  531. package/dist/tts/index.js.map +1 -1
  532. package/dist/tts/stream_adapter.cjs +25 -8
  533. package/dist/tts/stream_adapter.cjs.map +1 -1
  534. package/dist/tts/stream_adapter.d.cts +6 -3
  535. package/dist/tts/stream_adapter.d.ts +6 -3
  536. package/dist/tts/stream_adapter.d.ts.map +1 -1
  537. package/dist/tts/stream_adapter.js +25 -8
  538. package/dist/tts/stream_adapter.js.map +1 -1
  539. package/dist/tts/tts.cjs +189 -57
  540. package/dist/tts/tts.cjs.map +1 -1
  541. package/dist/tts/tts.d.cts +58 -6
  542. package/dist/tts/tts.d.ts +58 -6
  543. package/dist/tts/tts.d.ts.map +1 -1
  544. package/dist/tts/tts.js +191 -59
  545. package/dist/tts/tts.js.map +1 -1
  546. package/dist/typed_promise.cjs +48 -0
  547. package/dist/typed_promise.cjs.map +1 -0
  548. package/dist/typed_promise.d.cts +24 -0
  549. package/dist/typed_promise.d.ts +24 -0
  550. package/dist/typed_promise.d.ts.map +1 -0
  551. package/dist/typed_promise.js +28 -0
  552. package/dist/typed_promise.js.map +1 -0
  553. package/dist/types.cjs +24 -32
  554. package/dist/types.cjs.map +1 -1
  555. package/dist/types.d.cts +45 -10
  556. package/dist/types.d.ts +45 -10
  557. package/dist/types.d.ts.map +1 -1
  558. package/dist/types.js +20 -30
  559. package/dist/types.js.map +1 -1
  560. package/dist/utils.cjs +124 -28
  561. package/dist/utils.cjs.map +1 -1
  562. package/dist/utils.d.cts +41 -1
  563. package/dist/utils.d.ts +41 -1
  564. package/dist/utils.d.ts.map +1 -1
  565. package/dist/utils.js +119 -27
  566. package/dist/utils.js.map +1 -1
  567. package/dist/utils.test.cjs +73 -1
  568. package/dist/utils.test.cjs.map +1 -1
  569. package/dist/utils.test.js +74 -10
  570. package/dist/utils.test.js.map +1 -1
  571. package/dist/vad.cjs +35 -15
  572. package/dist/vad.cjs.map +1 -1
  573. package/dist/vad.d.cts +15 -5
  574. package/dist/vad.d.ts +15 -5
  575. package/dist/vad.d.ts.map +1 -1
  576. package/dist/vad.js +35 -15
  577. package/dist/vad.js.map +1 -1
  578. package/dist/version.cjs +1 -1
  579. package/dist/version.cjs.map +1 -1
  580. package/dist/version.d.cts +1 -1
  581. package/dist/version.d.ts +1 -1
  582. package/dist/version.d.ts.map +1 -1
  583. package/dist/version.js +1 -1
  584. package/dist/version.js.map +1 -1
  585. package/dist/voice/agent.cjs +258 -35
  586. package/dist/voice/agent.cjs.map +1 -1
  587. package/dist/voice/agent.d.cts +54 -13
  588. package/dist/voice/agent.d.ts +54 -13
  589. package/dist/voice/agent.d.ts.map +1 -1
  590. package/dist/voice/agent.js +254 -34
  591. package/dist/voice/agent.js.map +1 -1
  592. package/dist/voice/agent.test.cjs +314 -0
  593. package/dist/voice/agent.test.cjs.map +1 -1
  594. package/dist/voice/agent.test.js +316 -2
  595. package/dist/voice/agent.test.js.map +1 -1
  596. package/dist/voice/agent_activity.cjs +1116 -385
  597. package/dist/voice/agent_activity.cjs.map +1 -1
  598. package/dist/voice/agent_activity.d.cts +72 -11
  599. package/dist/voice/agent_activity.d.ts +72 -11
  600. package/dist/voice/agent_activity.d.ts.map +1 -1
  601. package/dist/voice/agent_activity.js +1119 -383
  602. package/dist/voice/agent_activity.js.map +1 -1
  603. package/dist/voice/agent_activity.test.cjs +135 -0
  604. package/dist/voice/agent_activity.test.cjs.map +1 -0
  605. package/dist/voice/agent_activity.test.js +134 -0
  606. package/dist/voice/agent_activity.test.js.map +1 -0
  607. package/dist/voice/agent_session.cjs +550 -90
  608. package/dist/voice/agent_session.cjs.map +1 -1
  609. package/dist/voice/agent_session.d.cts +185 -25
  610. package/dist/voice/agent_session.d.ts +185 -25
  611. package/dist/voice/agent_session.d.ts.map +1 -1
  612. package/dist/voice/agent_session.js +556 -91
  613. package/dist/voice/agent_session.js.map +1 -1
  614. package/dist/voice/audio_recognition.cjs +605 -46
  615. package/dist/voice/audio_recognition.cjs.map +1 -1
  616. package/dist/voice/audio_recognition.d.cts +96 -4
  617. package/dist/voice/audio_recognition.d.ts +96 -4
  618. package/dist/voice/audio_recognition.d.ts.map +1 -1
  619. package/dist/voice/audio_recognition.js +611 -47
  620. package/dist/voice/audio_recognition.js.map +1 -1
  621. package/dist/voice/audio_recognition_span.test.cjs +295 -0
  622. package/dist/voice/audio_recognition_span.test.cjs.map +1 -0
  623. package/dist/voice/audio_recognition_span.test.js +299 -0
  624. package/dist/voice/audio_recognition_span.test.js.map +1 -0
  625. package/dist/voice/avatar/datastream_io.cjs +7 -1
  626. package/dist/voice/avatar/datastream_io.cjs.map +1 -1
  627. package/dist/voice/avatar/datastream_io.d.cts +1 -0
  628. package/dist/voice/avatar/datastream_io.d.ts +1 -0
  629. package/dist/voice/avatar/datastream_io.d.ts.map +1 -1
  630. package/dist/voice/avatar/datastream_io.js +7 -1
  631. package/dist/voice/avatar/datastream_io.js.map +1 -1
  632. package/dist/voice/background_audio.cjs +367 -0
  633. package/dist/voice/background_audio.cjs.map +1 -0
  634. package/dist/voice/background_audio.d.cts +123 -0
  635. package/dist/voice/background_audio.d.ts +123 -0
  636. package/dist/voice/background_audio.d.ts.map +1 -0
  637. package/dist/voice/background_audio.js +343 -0
  638. package/dist/voice/background_audio.js.map +1 -0
  639. package/dist/voice/events.cjs +3 -0
  640. package/dist/voice/events.cjs.map +1 -1
  641. package/dist/voice/events.d.cts +16 -9
  642. package/dist/voice/events.d.ts +16 -9
  643. package/dist/voice/events.d.ts.map +1 -1
  644. package/dist/voice/events.js +3 -0
  645. package/dist/voice/events.js.map +1 -1
  646. package/dist/voice/generation.cjs +205 -41
  647. package/dist/voice/generation.cjs.map +1 -1
  648. package/dist/voice/generation.d.cts +21 -5
  649. package/dist/voice/generation.d.ts +21 -5
  650. package/dist/voice/generation.d.ts.map +1 -1
  651. package/dist/voice/generation.js +215 -43
  652. package/dist/voice/generation.js.map +1 -1
  653. package/dist/voice/generation_tools.test.cjs +236 -0
  654. package/dist/voice/generation_tools.test.cjs.map +1 -0
  655. package/dist/voice/generation_tools.test.js +235 -0
  656. package/dist/voice/generation_tools.test.js.map +1 -0
  657. package/dist/voice/index.cjs +33 -2
  658. package/dist/voice/index.cjs.map +1 -1
  659. package/dist/voice/index.d.cts +8 -2
  660. package/dist/voice/index.d.ts +8 -2
  661. package/dist/voice/index.d.ts.map +1 -1
  662. package/dist/voice/index.js +19 -2
  663. package/dist/voice/index.js.map +1 -1
  664. package/dist/voice/interruption_detection.test.cjs +114 -0
  665. package/dist/voice/interruption_detection.test.cjs.map +1 -0
  666. package/dist/voice/interruption_detection.test.js +113 -0
  667. package/dist/voice/interruption_detection.test.js.map +1 -0
  668. package/dist/voice/io.cjs +66 -6
  669. package/dist/voice/io.cjs.map +1 -1
  670. package/dist/voice/io.d.cts +67 -7
  671. package/dist/voice/io.d.ts +67 -7
  672. package/dist/voice/io.d.ts.map +1 -1
  673. package/dist/voice/io.js +62 -5
  674. package/dist/voice/io.js.map +1 -1
  675. package/dist/voice/recorder_io/index.cjs +23 -0
  676. package/dist/voice/recorder_io/index.cjs.map +1 -0
  677. package/dist/voice/recorder_io/index.d.cts +2 -0
  678. package/dist/voice/recorder_io/index.d.ts +2 -0
  679. package/dist/voice/recorder_io/index.d.ts.map +1 -0
  680. package/dist/voice/recorder_io/index.js +2 -0
  681. package/dist/voice/recorder_io/index.js.map +1 -0
  682. package/dist/voice/recorder_io/recorder_io.cjs +607 -0
  683. package/dist/voice/recorder_io/recorder_io.cjs.map +1 -0
  684. package/dist/voice/recorder_io/recorder_io.d.cts +106 -0
  685. package/dist/voice/recorder_io/recorder_io.d.ts +106 -0
  686. package/dist/voice/recorder_io/recorder_io.d.ts.map +1 -0
  687. package/dist/voice/recorder_io/recorder_io.js +573 -0
  688. package/dist/voice/recorder_io/recorder_io.js.map +1 -0
  689. package/dist/voice/remote_session.cjs +922 -0
  690. package/dist/voice/remote_session.cjs.map +1 -0
  691. package/dist/voice/remote_session.d.cts +108 -0
  692. package/dist/voice/remote_session.d.ts +108 -0
  693. package/dist/voice/remote_session.d.ts.map +1 -0
  694. package/dist/voice/remote_session.js +887 -0
  695. package/dist/voice/remote_session.js.map +1 -0
  696. package/dist/voice/report.cjs +88 -0
  697. package/dist/voice/report.cjs.map +1 -0
  698. package/dist/voice/report.d.cts +49 -0
  699. package/dist/voice/report.d.ts +49 -0
  700. package/dist/voice/report.d.ts.map +1 -0
  701. package/dist/voice/report.js +63 -0
  702. package/dist/voice/report.js.map +1 -0
  703. package/dist/voice/report.test.cjs +121 -0
  704. package/dist/voice/report.test.cjs.map +1 -0
  705. package/dist/voice/report.test.js +120 -0
  706. package/dist/voice/report.test.js.map +1 -0
  707. package/dist/voice/room_io/_input.cjs +40 -7
  708. package/dist/voice/room_io/_input.cjs.map +1 -1
  709. package/dist/voice/room_io/_input.d.cts +5 -2
  710. package/dist/voice/room_io/_input.d.ts +5 -2
  711. package/dist/voice/room_io/_input.d.ts.map +1 -1
  712. package/dist/voice/room_io/_input.js +41 -8
  713. package/dist/voice/room_io/_input.js.map +1 -1
  714. package/dist/voice/room_io/_output.cjs +19 -11
  715. package/dist/voice/room_io/_output.cjs.map +1 -1
  716. package/dist/voice/room_io/_output.d.cts +7 -4
  717. package/dist/voice/room_io/_output.d.ts +7 -4
  718. package/dist/voice/room_io/_output.d.ts.map +1 -1
  719. package/dist/voice/room_io/_output.js +20 -12
  720. package/dist/voice/room_io/_output.js.map +1 -1
  721. package/dist/voice/room_io/room_io.cjs +33 -6
  722. package/dist/voice/room_io/room_io.cjs.map +1 -1
  723. package/dist/voice/room_io/room_io.d.cts +29 -9
  724. package/dist/voice/room_io/room_io.d.ts +29 -9
  725. package/dist/voice/room_io/room_io.d.ts.map +1 -1
  726. package/dist/voice/room_io/room_io.js +33 -7
  727. package/dist/voice/room_io/room_io.js.map +1 -1
  728. package/dist/voice/speech_handle.cjs +22 -4
  729. package/dist/voice/speech_handle.cjs.map +1 -1
  730. package/dist/voice/speech_handle.d.cts +17 -2
  731. package/dist/voice/speech_handle.d.ts +17 -2
  732. package/dist/voice/speech_handle.d.ts.map +1 -1
  733. package/dist/voice/speech_handle.js +21 -4
  734. package/dist/voice/speech_handle.js.map +1 -1
  735. package/dist/voice/testing/fake_llm.cjs +127 -0
  736. package/dist/voice/testing/fake_llm.cjs.map +1 -0
  737. package/dist/voice/testing/fake_llm.d.cts +30 -0
  738. package/dist/voice/testing/fake_llm.d.ts +30 -0
  739. package/dist/voice/testing/fake_llm.d.ts.map +1 -0
  740. package/dist/voice/testing/fake_llm.js +103 -0
  741. package/dist/voice/testing/fake_llm.js.map +1 -0
  742. package/dist/voice/testing/index.cjs +57 -0
  743. package/dist/voice/testing/index.cjs.map +1 -0
  744. package/dist/voice/testing/index.d.cts +21 -0
  745. package/dist/voice/testing/index.d.ts +21 -0
  746. package/dist/voice/testing/index.d.ts.map +1 -0
  747. package/dist/voice/testing/index.js +35 -0
  748. package/dist/voice/testing/index.js.map +1 -0
  749. package/dist/voice/testing/run_result.cjs +817 -0
  750. package/dist/voice/testing/run_result.cjs.map +1 -0
  751. package/dist/voice/testing/run_result.d.cts +385 -0
  752. package/dist/voice/testing/run_result.d.ts +385 -0
  753. package/dist/voice/testing/run_result.d.ts.map +1 -0
  754. package/dist/voice/testing/run_result.js +790 -0
  755. package/dist/voice/testing/run_result.js.map +1 -0
  756. package/dist/voice/testing/types.cjs +46 -0
  757. package/dist/voice/testing/types.cjs.map +1 -0
  758. package/dist/voice/testing/types.d.cts +83 -0
  759. package/dist/voice/testing/types.d.ts +83 -0
  760. package/dist/voice/testing/types.d.ts.map +1 -0
  761. package/dist/voice/testing/types.js +19 -0
  762. package/dist/voice/testing/types.js.map +1 -0
  763. package/dist/voice/transcription/synchronizer.cjs +139 -15
  764. package/dist/voice/transcription/synchronizer.cjs.map +1 -1
  765. package/dist/voice/transcription/synchronizer.d.cts +35 -4
  766. package/dist/voice/transcription/synchronizer.d.ts +35 -4
  767. package/dist/voice/transcription/synchronizer.d.ts.map +1 -1
  768. package/dist/voice/transcription/synchronizer.js +143 -16
  769. package/dist/voice/transcription/synchronizer.js.map +1 -1
  770. package/dist/voice/transcription/synchronizer.test.cjs +151 -0
  771. package/dist/voice/transcription/synchronizer.test.cjs.map +1 -0
  772. package/dist/voice/transcription/synchronizer.test.js +150 -0
  773. package/dist/voice/transcription/synchronizer.test.js.map +1 -0
  774. package/dist/voice/turn_config/endpointing.cjs +33 -0
  775. package/dist/voice/turn_config/endpointing.cjs.map +1 -0
  776. package/dist/voice/turn_config/endpointing.d.cts +30 -0
  777. package/dist/voice/turn_config/endpointing.d.ts +30 -0
  778. package/dist/voice/turn_config/endpointing.d.ts.map +1 -0
  779. package/dist/voice/turn_config/endpointing.js +9 -0
  780. package/dist/voice/turn_config/endpointing.js.map +1 -0
  781. package/dist/voice/turn_config/interruption.cjs +37 -0
  782. package/dist/voice/turn_config/interruption.cjs.map +1 -0
  783. package/dist/voice/turn_config/interruption.d.cts +53 -0
  784. package/dist/voice/turn_config/interruption.d.ts +53 -0
  785. package/dist/voice/turn_config/interruption.d.ts.map +1 -0
  786. package/dist/voice/turn_config/interruption.js +13 -0
  787. package/dist/voice/turn_config/interruption.js.map +1 -0
  788. package/dist/voice/turn_config/turn_handling.cjs +35 -0
  789. package/dist/voice/turn_config/turn_handling.cjs.map +1 -0
  790. package/dist/voice/turn_config/turn_handling.d.cts +36 -0
  791. package/dist/voice/turn_config/turn_handling.d.ts +36 -0
  792. package/dist/voice/turn_config/turn_handling.d.ts.map +1 -0
  793. package/dist/voice/turn_config/turn_handling.js +11 -0
  794. package/dist/voice/turn_config/turn_handling.js.map +1 -0
  795. package/dist/voice/turn_config/utils.cjs +157 -0
  796. package/dist/voice/turn_config/utils.cjs.map +1 -0
  797. package/dist/voice/turn_config/utils.d.cts +37 -0
  798. package/dist/voice/turn_config/utils.d.ts +37 -0
  799. package/dist/voice/turn_config/utils.d.ts.map +1 -0
  800. package/dist/voice/turn_config/utils.js +131 -0
  801. package/dist/voice/turn_config/utils.js.map +1 -0
  802. package/dist/voice/turn_config/utils.test.cjs +128 -0
  803. package/dist/voice/turn_config/utils.test.cjs.map +1 -0
  804. package/dist/voice/turn_config/utils.test.js +127 -0
  805. package/dist/voice/turn_config/utils.test.js.map +1 -0
  806. package/dist/voice/utils.cjs +47 -0
  807. package/dist/voice/utils.cjs.map +1 -0
  808. package/dist/voice/utils.d.cts +4 -0
  809. package/dist/voice/utils.d.ts +4 -0
  810. package/dist/voice/utils.d.ts.map +1 -0
  811. package/dist/voice/utils.js +23 -0
  812. package/dist/voice/utils.js.map +1 -0
  813. package/dist/worker.cjs +44 -52
  814. package/dist/worker.cjs.map +1 -1
  815. package/dist/worker.d.cts +18 -8
  816. package/dist/worker.d.ts +18 -8
  817. package/dist/worker.d.ts.map +1 -1
  818. package/dist/worker.js +43 -43
  819. package/dist/worker.js.map +1 -1
  820. package/package.json +35 -13
  821. package/resources/NOTICE +2 -0
  822. package/resources/keyboard-typing.ogg +0 -0
  823. package/resources/keyboard-typing2.ogg +0 -0
  824. package/resources/office-ambience.ogg +0 -0
  825. package/src/_exceptions.ts +5 -0
  826. package/src/audio.ts +132 -1
  827. package/src/beta/index.ts +9 -0
  828. package/src/beta/workflows/index.ts +9 -0
  829. package/src/beta/workflows/task_group.ts +203 -0
  830. package/src/cli.ts +57 -66
  831. package/src/connection_pool.test.ts +346 -0
  832. package/src/connection_pool.ts +307 -0
  833. package/src/constants.ts +14 -0
  834. package/src/cpu.test.ts +239 -0
  835. package/src/cpu.ts +173 -0
  836. package/src/http_server.ts +18 -6
  837. package/src/index.ts +15 -13
  838. package/src/inference/api_protos.ts +85 -2
  839. package/src/inference/index.ts +32 -4
  840. package/src/inference/interruption/defaults.ts +51 -0
  841. package/src/inference/interruption/errors.ts +25 -0
  842. package/src/inference/interruption/http_transport.ts +207 -0
  843. package/src/inference/interruption/interruption_cache_entry.ts +50 -0
  844. package/src/inference/interruption/interruption_detector.ts +204 -0
  845. package/src/inference/interruption/interruption_stream.ts +467 -0
  846. package/src/inference/interruption/types.ts +84 -0
  847. package/src/inference/interruption/utils.test.ts +132 -0
  848. package/src/inference/interruption/utils.ts +137 -0
  849. package/src/inference/interruption/ws_transport.ts +416 -0
  850. package/src/inference/llm.ts +214 -163
  851. package/src/inference/stt.test.ts +253 -0
  852. package/src/inference/stt.ts +449 -208
  853. package/src/inference/tts.test.ts +354 -0
  854. package/src/inference/tts.ts +417 -115
  855. package/src/inference/utils.ts +30 -2
  856. package/src/ipc/inference_proc_executor.ts +11 -3
  857. package/src/ipc/inference_proc_lazy_main.ts +13 -1
  858. package/src/ipc/job_proc_executor.ts +11 -1
  859. package/src/ipc/job_proc_lazy_main.ts +86 -20
  860. package/src/ipc/supervised_proc.test.ts +153 -0
  861. package/src/ipc/supervised_proc.ts +39 -10
  862. package/src/job.ts +120 -1
  863. package/src/language.test.ts +62 -0
  864. package/src/language.ts +380 -0
  865. package/src/llm/__snapshots__/zod-utils.test.ts.snap +559 -0
  866. package/src/llm/chat_context.test.ts +787 -0
  867. package/src/llm/chat_context.ts +493 -2
  868. package/src/llm/fallback_adapter.test.ts +238 -0
  869. package/src/llm/fallback_adapter.ts +394 -0
  870. package/src/llm/index.ts +13 -0
  871. package/src/llm/llm.ts +77 -12
  872. package/src/llm/provider_format/google.test.ts +72 -1
  873. package/src/llm/provider_format/google.ts +10 -6
  874. package/src/llm/provider_format/index.ts +7 -2
  875. package/src/llm/provider_format/openai.test.ts +480 -2
  876. package/src/llm/provider_format/openai.ts +152 -21
  877. package/src/llm/provider_format/utils.ts +11 -5
  878. package/src/llm/realtime.ts +23 -2
  879. package/src/llm/remote_chat_context.ts +2 -2
  880. package/src/llm/tool_context.test.ts +210 -1
  881. package/src/llm/tool_context.ts +115 -17
  882. package/src/llm/utils.test.ts +103 -2
  883. package/src/llm/utils.ts +152 -16
  884. package/src/llm/zod-utils.test.ts +577 -0
  885. package/src/llm/zod-utils.ts +153 -0
  886. package/src/log.ts +71 -19
  887. package/src/metrics/base.ts +78 -19
  888. package/src/metrics/index.ts +12 -0
  889. package/src/metrics/model_usage.test.ts +545 -0
  890. package/src/metrics/model_usage.ts +262 -0
  891. package/src/metrics/usage_collector.ts +14 -3
  892. package/src/metrics/utils.ts +27 -7
  893. package/src/stream/deferred_stream.test.ts +3 -3
  894. package/src/stream/deferred_stream.ts +43 -11
  895. package/src/stream/index.ts +1 -0
  896. package/src/stream/multi_input_stream.test.ts +545 -0
  897. package/src/stream/multi_input_stream.ts +172 -0
  898. package/src/stream/stream_channel.test.ts +37 -0
  899. package/src/stream/stream_channel.ts +43 -3
  900. package/src/stt/stream_adapter.ts +30 -9
  901. package/src/stt/stt.ts +140 -23
  902. package/src/telemetry/index.ts +28 -0
  903. package/src/telemetry/logging.ts +55 -0
  904. package/src/telemetry/otel_http_exporter.ts +218 -0
  905. package/src/telemetry/pino_otel_transport.ts +265 -0
  906. package/src/telemetry/trace_types.ts +109 -0
  907. package/src/telemetry/traces.ts +673 -0
  908. package/src/telemetry/utils.ts +61 -0
  909. package/src/tokenize/basic/sentence.ts +3 -3
  910. package/src/tokenize/tokenizer.test.ts +4 -0
  911. package/src/transcription.ts +6 -0
  912. package/src/tts/fallback_adapter.ts +586 -0
  913. package/src/tts/index.ts +1 -0
  914. package/src/tts/stream_adapter.ts +38 -8
  915. package/src/tts/tts.ts +245 -62
  916. package/src/typed_promise.ts +67 -0
  917. package/src/types.ts +62 -33
  918. package/src/utils.test.ts +90 -10
  919. package/src/utils.ts +178 -33
  920. package/src/vad.ts +42 -18
  921. package/src/version.ts +1 -1
  922. package/src/voice/agent.test.ts +347 -2
  923. package/src/voice/agent.ts +346 -44
  924. package/src/voice/agent_activity.test.ts +194 -0
  925. package/src/voice/agent_activity.ts +1457 -388
  926. package/src/voice/agent_session.ts +817 -112
  927. package/src/voice/audio_recognition.ts +845 -70
  928. package/src/voice/audio_recognition_span.test.ts +341 -0
  929. package/src/voice/avatar/datastream_io.ts +9 -1
  930. package/src/voice/background_audio.ts +494 -0
  931. package/src/voice/events.ts +27 -7
  932. package/src/voice/generation.ts +310 -56
  933. package/src/voice/generation_tools.test.ts +268 -0
  934. package/src/voice/index.ts +17 -3
  935. package/src/voice/interruption_detection.test.ts +151 -0
  936. package/src/voice/io.ts +115 -12
  937. package/src/voice/recorder_io/index.ts +4 -0
  938. package/src/voice/recorder_io/recorder_io.ts +783 -0
  939. package/src/voice/remote_session.ts +1083 -0
  940. package/src/voice/report.test.ts +136 -0
  941. package/src/voice/report.ts +140 -0
  942. package/src/voice/room_io/_input.ts +45 -10
  943. package/src/voice/room_io/_output.ts +26 -14
  944. package/src/voice/room_io/room_io.ts +67 -22
  945. package/src/voice/speech_handle.ts +38 -6
  946. package/src/voice/testing/fake_llm.ts +138 -0
  947. package/src/voice/testing/index.ts +52 -0
  948. package/src/voice/testing/run_result.ts +995 -0
  949. package/src/voice/testing/types.ts +118 -0
  950. package/src/voice/transcription/synchronizer.test.ts +206 -0
  951. package/src/voice/transcription/synchronizer.ts +204 -19
  952. package/src/voice/turn_config/endpointing.ts +33 -0
  953. package/src/voice/turn_config/interruption.ts +56 -0
  954. package/src/voice/turn_config/turn_handling.ts +45 -0
  955. package/src/voice/turn_config/utils.test.ts +148 -0
  956. package/src/voice/turn_config/utils.ts +167 -0
  957. package/src/voice/utils.ts +29 -0
  958. package/src/worker.ts +92 -78
  959. package/src/llm/__snapshots__/utils.test.ts.snap +0 -65
@@ -1,12 +1,29 @@
1
- import { Agent, StopResponse } from "./agent.js";
1
+ import { Agent, AgentTask, StopResponse } from "./agent.js";
2
2
  import { AgentSession } from "./agent_session.js";
3
3
  export * from "./avatar/index.js";
4
+ export * from "./background_audio.js";
5
+ import {
6
+ RemoteSession,
7
+ SessionHost,
8
+ SessionTransport,
9
+ RoomSessionTransport
10
+ } from "./remote_session.js";
4
11
  export * from "./events.js";
12
+ import {} from "./io.js";
13
+ export * from "./report.js";
14
+ export * from "./room_io/index.js";
5
15
  import { RunContext } from "./run_context.js";
16
+ import * as testing from "./testing/index.js";
6
17
  export {
7
18
  Agent,
8
19
  AgentSession,
20
+ AgentTask,
21
+ RemoteSession,
22
+ RoomSessionTransport,
9
23
  RunContext,
10
- StopResponse
24
+ SessionHost,
25
+ SessionTransport,
26
+ StopResponse,
27
+ testing
11
28
  };
12
29
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/voice/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport { Agent, StopResponse, type AgentOptions, type ModelSettings } from './agent.js';\nexport { AgentSession, type AgentSessionOptions } from './agent_session.js';\n\nexport * from './avatar/index.js';\nexport * from './events.js';\nexport { RunContext } from './run_context.js';\n"],"mappings":"AAGA,SAAS,OAAO,oBAA2D;AAC3E,SAAS,oBAA8C;AAEvD,cAAc;AACd,cAAc;AACd,SAAS,kBAAkB;","names":[]}
1
+ {"version":3,"sources":["../../src/voice/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport { Agent, AgentTask, StopResponse, type AgentOptions, type ModelSettings } from './agent.js';\nexport { AgentSession, type AgentSessionOptions, type VoiceOptions } from './agent_session.js';\nexport * from './avatar/index.js';\nexport * from './background_audio.js';\nexport {\n type TextInputCallback,\n type TextInputEvent,\n RemoteSession,\n type RemoteSessionCallbacks,\n type RemoteSessionEventTypes,\n SessionHost,\n SessionTransport,\n RoomSessionTransport,\n} from './remote_session.js';\nexport * from './events.js';\nexport { type TimedString } from './io.js';\nexport * from './report.js';\nexport * from './room_io/index.js';\nexport { RunContext } from './run_context.js';\nexport * as testing from './testing/index.js';\n"],"mappings":"AAGA,SAAS,OAAO,WAAW,oBAA2D;AACtF,SAAS,oBAAiE;AAC1E,cAAc;AACd,cAAc;AACd;AAAA,EAGE;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,cAAc;AACd,eAAiC;AACjC,cAAc;AACd,cAAc;AACd,SAAS,kBAAkB;AAC3B,YAAY,aAAa;","names":[]}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var import_vitest = require("vitest");
3
+ var import_word = require("../tokenize/basic/word.cjs");
4
+ (0, import_vitest.describe)("Interruption Detection - Word Counting", () => {
5
+ (0, import_vitest.describe)("Word Splitting Behavior", () => {
6
+ (0, import_vitest.it)("should count empty string as 0 words", () => {
7
+ const text = "";
8
+ const wordCount = (0, import_word.splitWords)(text, true).length;
9
+ (0, import_vitest.expect)(wordCount).toBe(0);
10
+ });
11
+ (0, import_vitest.it)("should count single word correctly", () => {
12
+ const text = "hello";
13
+ const wordCount = (0, import_word.splitWords)(text, true).length;
14
+ (0, import_vitest.expect)(wordCount).toBe(1);
15
+ });
16
+ (0, import_vitest.it)("should count two words correctly", () => {
17
+ const text = "hello world";
18
+ const wordCount = (0, import_word.splitWords)(text, true).length;
19
+ (0, import_vitest.expect)(wordCount).toBe(2);
20
+ });
21
+ (0, import_vitest.it)("should count multiple words correctly", () => {
22
+ const text = "hello this is a full sentence";
23
+ const wordCount = (0, import_word.splitWords)(text, true).length;
24
+ (0, import_vitest.expect)(wordCount).toBe(6);
25
+ });
26
+ (0, import_vitest.it)("should handle punctuation correctly", () => {
27
+ const text = "hello, world!";
28
+ const wordCount = (0, import_word.splitWords)(text, true).length;
29
+ (0, import_vitest.expect)(wordCount).toBe(2);
30
+ });
31
+ (0, import_vitest.it)("should handle multiple spaces between words", () => {
32
+ const text = "hello world";
33
+ const wordCount = (0, import_word.splitWords)(text, true).length;
34
+ (0, import_vitest.expect)(wordCount).toBe(2);
35
+ });
36
+ (0, import_vitest.it)("should count whitespace-only string as 0 words", () => {
37
+ const text = " ";
38
+ const wordCount = (0, import_word.splitWords)(text, true).length;
39
+ (0, import_vitest.expect)(wordCount).toBe(0);
40
+ });
41
+ (0, import_vitest.it)("should handle leading and trailing whitespace", () => {
42
+ const text = " hello world ";
43
+ const wordCount = (0, import_word.splitWords)(text, true).length;
44
+ (0, import_vitest.expect)(wordCount).toBe(2);
45
+ });
46
+ });
47
+ (0, import_vitest.describe)("Integration: Full Interruption Check Logic", () => {
48
+ (0, import_vitest.it)("should block interruption for empty transcript with threshold 2", () => {
49
+ const text = "";
50
+ const minInterruptionWords = 2;
51
+ const normalizedText = text ?? "";
52
+ const wordCount = (0, import_word.splitWords)(normalizedText, true).length;
53
+ const shouldBlock = wordCount < minInterruptionWords;
54
+ (0, import_vitest.expect)(normalizedText).toBe("");
55
+ (0, import_vitest.expect)(wordCount).toBe(0);
56
+ (0, import_vitest.expect)(shouldBlock).toBe(true);
57
+ });
58
+ (0, import_vitest.it)("should block interruption for undefined transcript with threshold 2", () => {
59
+ const text = void 0;
60
+ const minInterruptionWords = 2;
61
+ const normalizedText = text ?? "";
62
+ const wordCount = (0, import_word.splitWords)(normalizedText, true).length;
63
+ const shouldBlock = wordCount < minInterruptionWords;
64
+ (0, import_vitest.expect)(normalizedText).toBe("");
65
+ (0, import_vitest.expect)(wordCount).toBe(0);
66
+ (0, import_vitest.expect)(shouldBlock).toBe(true);
67
+ });
68
+ (0, import_vitest.it)("should block interruption for single word with threshold 2", () => {
69
+ const text = "hello";
70
+ const minInterruptionWords = 2;
71
+ const normalizedText = text ?? "";
72
+ const wordCount = (0, import_word.splitWords)(normalizedText, true).length;
73
+ const shouldBlock = wordCount < minInterruptionWords;
74
+ (0, import_vitest.expect)(normalizedText).toBe("hello");
75
+ (0, import_vitest.expect)(wordCount).toBe(1);
76
+ (0, import_vitest.expect)(shouldBlock).toBe(true);
77
+ });
78
+ (0, import_vitest.it)("should allow interruption when word count exactly meets threshold", () => {
79
+ const text = "hello world";
80
+ const minInterruptionWords = 2;
81
+ const normalizedText = text ?? "";
82
+ const wordCount = (0, import_word.splitWords)(normalizedText, true).length;
83
+ const shouldBlock = wordCount < minInterruptionWords;
84
+ (0, import_vitest.expect)(normalizedText).toBe("hello world");
85
+ (0, import_vitest.expect)(wordCount).toBe(2);
86
+ (0, import_vitest.expect)(shouldBlock).toBe(false);
87
+ });
88
+ (0, import_vitest.it)("should allow interruption when word count exceeds threshold", () => {
89
+ const text = "hello this is a full sentence";
90
+ const minInterruptionWords = 2;
91
+ const normalizedText = text ?? "";
92
+ const wordCount = (0, import_word.splitWords)(normalizedText, true).length;
93
+ const shouldBlock = wordCount < minInterruptionWords;
94
+ (0, import_vitest.expect)(normalizedText).toBe("hello this is a full sentence");
95
+ (0, import_vitest.expect)(wordCount).toBe(6);
96
+ (0, import_vitest.expect)(shouldBlock).toBe(false);
97
+ });
98
+ (0, import_vitest.it)("should apply consistent word counting logic in both methods", () => {
99
+ const transcripts = ["", "hello", "hello world", "this is a longer sentence"];
100
+ const threshold = 2;
101
+ transcripts.forEach((transcript) => {
102
+ const text1 = transcript;
103
+ const normalizedText1 = text1 ?? "";
104
+ const wordCount1 = (0, import_word.splitWords)(normalizedText1, true).length;
105
+ const shouldBlock1 = wordCount1 < threshold;
106
+ const wordCount2 = (0, import_word.splitWords)(transcript, true).length;
107
+ const shouldBlock2 = wordCount2 < threshold;
108
+ (0, import_vitest.expect)(wordCount1).toBe(wordCount2);
109
+ (0, import_vitest.expect)(shouldBlock1).toBe(shouldBlock2);
110
+ });
111
+ });
112
+ });
113
+ });
114
+ //# sourceMappingURL=interruption_detection.test.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/voice/interruption_detection.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Unit tests for interruption detection logic in AgentActivity.\n *\n * Tests the refactored minInterruptionWords check which ensures:\n * - Consistent word count filtering across all speech scenarios\n * - Proper handling of empty strings, undefined, and short speech\n * - Interruptions allowed only when word count meets or exceeds minInterruptionWords threshold\n */\nimport { describe, expect, it } from 'vitest';\nimport { splitWords } from '../tokenize/basic/word.js';\n\ndescribe('Interruption Detection - Word Counting', () => {\n describe('Word Splitting Behavior', () => {\n it('should count empty string as 0 words', () => {\n const text = '';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(0);\n });\n\n it('should count single word correctly', () => {\n const text = 'hello';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(1);\n });\n\n it('should count two words correctly', () => {\n const text = 'hello world';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(2);\n });\n\n it('should count multiple words correctly', () => {\n const text = 'hello this is a full sentence';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(6);\n });\n\n it('should handle punctuation correctly', () => {\n const text = 'hello, world!';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(2);\n });\n\n it('should handle multiple spaces between words', () => {\n const text = 'hello world';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(2);\n });\n\n it('should count whitespace-only string as 0 words', () => {\n const text = ' ';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(0);\n });\n\n it('should handle leading and trailing whitespace', () => {\n const text = ' hello world ';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(2);\n });\n });\n\n describe('Integration: Full Interruption Check Logic', () => {\n it('should block interruption for empty transcript with threshold 2', () => {\n const text = '';\n const minInterruptionWords = 2;\n\n const normalizedText = text ?? '';\n const wordCount = splitWords(normalizedText, true).length;\n const shouldBlock = wordCount < minInterruptionWords;\n\n expect(normalizedText).toBe('');\n expect(wordCount).toBe(0);\n expect(shouldBlock).toBe(true);\n });\n\n it('should block interruption for undefined transcript with threshold 2', () => {\n const text: string | undefined = undefined;\n const minInterruptionWords = 2;\n\n const normalizedText = text ?? '';\n const wordCount = splitWords(normalizedText, true).length;\n const shouldBlock = wordCount < minInterruptionWords;\n\n expect(normalizedText).toBe('');\n expect(wordCount).toBe(0);\n expect(shouldBlock).toBe(true);\n });\n\n it('should block interruption for single word with threshold 2', () => {\n const text = 'hello';\n const minInterruptionWords = 2;\n\n const normalizedText = text ?? '';\n const wordCount = splitWords(normalizedText, true).length;\n const shouldBlock = wordCount < minInterruptionWords;\n\n expect(normalizedText).toBe('hello');\n expect(wordCount).toBe(1);\n expect(shouldBlock).toBe(true);\n });\n\n it('should allow interruption when word count exactly meets threshold', () => {\n const text = 'hello world';\n const minInterruptionWords = 2;\n\n const normalizedText = text ?? '';\n const wordCount = splitWords(normalizedText, true).length;\n const shouldBlock = wordCount < minInterruptionWords;\n\n expect(normalizedText).toBe('hello world');\n expect(wordCount).toBe(2);\n expect(shouldBlock).toBe(false);\n });\n\n it('should allow interruption when word count exceeds threshold', () => {\n const text = 'hello this is a full sentence';\n const minInterruptionWords = 2;\n\n const normalizedText = text ?? '';\n const wordCount = splitWords(normalizedText, true).length;\n const shouldBlock = wordCount < minInterruptionWords;\n\n expect(normalizedText).toBe('hello this is a full sentence');\n expect(wordCount).toBe(6);\n expect(shouldBlock).toBe(false);\n });\n\n it('should apply consistent word counting logic in both methods', () => {\n const transcripts = ['', 'hello', 'hello world', 'this is a longer sentence'];\n const threshold = 2;\n\n transcripts.forEach((transcript) => {\n const text1 = transcript;\n const normalizedText1 = text1 ?? '';\n const wordCount1 = splitWords(normalizedText1, true).length;\n const shouldBlock1 = wordCount1 < threshold;\n\n const wordCount2 = splitWords(transcript, true).length;\n const shouldBlock2 = wordCount2 < threshold;\n\n expect(wordCount1).toBe(wordCount2);\n expect(shouldBlock1).toBe(shouldBlock2);\n });\n });\n });\n});\n"],"mappings":";AAYA,oBAAqC;AACrC,kBAA2B;AAAA,IAE3B,wBAAS,0CAA0C,MAAM;AACvD,8BAAS,2BAA2B,MAAM;AACxC,0BAAG,wCAAwC,MAAM;AAC/C,YAAM,OAAO;AACb,YAAM,gBAAY,wBAAW,MAAM,IAAI,EAAE;AACzC,gCAAO,SAAS,EAAE,KAAK,CAAC;AAAA,IAC1B,CAAC;AAED,0BAAG,sCAAsC,MAAM;AAC7C,YAAM,OAAO;AACb,YAAM,gBAAY,wBAAW,MAAM,IAAI,EAAE;AACzC,gCAAO,SAAS,EAAE,KAAK,CAAC;AAAA,IAC1B,CAAC;AAED,0BAAG,oCAAoC,MAAM;AAC3C,YAAM,OAAO;AACb,YAAM,gBAAY,wBAAW,MAAM,IAAI,EAAE;AACzC,gCAAO,SAAS,EAAE,KAAK,CAAC;AAAA,IAC1B,CAAC;AAED,0BAAG,yCAAyC,MAAM;AAChD,YAAM,OAAO;AACb,YAAM,gBAAY,wBAAW,MAAM,IAAI,EAAE;AACzC,gCAAO,SAAS,EAAE,KAAK,CAAC;AAAA,IAC1B,CAAC;AAED,0BAAG,uCAAuC,MAAM;AAC9C,YAAM,OAAO;AACb,YAAM,gBAAY,wBAAW,MAAM,IAAI,EAAE;AACzC,gCAAO,SAAS,EAAE,KAAK,CAAC;AAAA,IAC1B,CAAC;AAED,0BAAG,+CAA+C,MAAM;AACtD,YAAM,OAAO;AACb,YAAM,gBAAY,wBAAW,MAAM,IAAI,EAAE;AACzC,gCAAO,SAAS,EAAE,KAAK,CAAC;AAAA,IAC1B,CAAC;AAED,0BAAG,kDAAkD,MAAM;AACzD,YAAM,OAAO;AACb,YAAM,gBAAY,wBAAW,MAAM,IAAI,EAAE;AACzC,gCAAO,SAAS,EAAE,KAAK,CAAC;AAAA,IAC1B,CAAC;AAED,0BAAG,iDAAiD,MAAM;AACxD,YAAM,OAAO;AACb,YAAM,gBAAY,wBAAW,MAAM,IAAI,EAAE;AACzC,gCAAO,SAAS,EAAE,KAAK,CAAC;AAAA,IAC1B,CAAC;AAAA,EACH,CAAC;AAED,8BAAS,8CAA8C,MAAM;AAC3D,0BAAG,mEAAmE,MAAM;AAC1E,YAAM,OAAO;AACb,YAAM,uBAAuB;AAE7B,YAAM,iBAAiB,QAAQ;AAC/B,YAAM,gBAAY,wBAAW,gBAAgB,IAAI,EAAE;AACnD,YAAM,cAAc,YAAY;AAEhC,gCAAO,cAAc,EAAE,KAAK,EAAE;AAC9B,gCAAO,SAAS,EAAE,KAAK,CAAC;AACxB,gCAAO,WAAW,EAAE,KAAK,IAAI;AAAA,IAC/B,CAAC;AAED,0BAAG,uEAAuE,MAAM;AAC9E,YAAM,OAA2B;AACjC,YAAM,uBAAuB;AAE7B,YAAM,iBAAiB,QAAQ;AAC/B,YAAM,gBAAY,wBAAW,gBAAgB,IAAI,EAAE;AACnD,YAAM,cAAc,YAAY;AAEhC,gCAAO,cAAc,EAAE,KAAK,EAAE;AAC9B,gCAAO,SAAS,EAAE,KAAK,CAAC;AACxB,gCAAO,WAAW,EAAE,KAAK,IAAI;AAAA,IAC/B,CAAC;AAED,0BAAG,8DAA8D,MAAM;AACrE,YAAM,OAAO;AACb,YAAM,uBAAuB;AAE7B,YAAM,iBAAiB,QAAQ;AAC/B,YAAM,gBAAY,wBAAW,gBAAgB,IAAI,EAAE;AACnD,YAAM,cAAc,YAAY;AAEhC,gCAAO,cAAc,EAAE,KAAK,OAAO;AACnC,gCAAO,SAAS,EAAE,KAAK,CAAC;AACxB,gCAAO,WAAW,EAAE,KAAK,IAAI;AAAA,IAC/B,CAAC;AAED,0BAAG,qEAAqE,MAAM;AAC5E,YAAM,OAAO;AACb,YAAM,uBAAuB;AAE7B,YAAM,iBAAiB,QAAQ;AAC/B,YAAM,gBAAY,wBAAW,gBAAgB,IAAI,EAAE;AACnD,YAAM,cAAc,YAAY;AAEhC,gCAAO,cAAc,EAAE,KAAK,aAAa;AACzC,gCAAO,SAAS,EAAE,KAAK,CAAC;AACxB,gCAAO,WAAW,EAAE,KAAK,KAAK;AAAA,IAChC,CAAC;AAED,0BAAG,+DAA+D,MAAM;AACtE,YAAM,OAAO;AACb,YAAM,uBAAuB;AAE7B,YAAM,iBAAiB,QAAQ;AAC/B,YAAM,gBAAY,wBAAW,gBAAgB,IAAI,EAAE;AACnD,YAAM,cAAc,YAAY;AAEhC,gCAAO,cAAc,EAAE,KAAK,+BAA+B;AAC3D,gCAAO,SAAS,EAAE,KAAK,CAAC;AACxB,gCAAO,WAAW,EAAE,KAAK,KAAK;AAAA,IAChC,CAAC;AAED,0BAAG,+DAA+D,MAAM;AACtE,YAAM,cAAc,CAAC,IAAI,SAAS,eAAe,2BAA2B;AAC5E,YAAM,YAAY;AAElB,kBAAY,QAAQ,CAAC,eAAe;AAClC,cAAM,QAAQ;AACd,cAAM,kBAAkB,SAAS;AACjC,cAAM,iBAAa,wBAAW,iBAAiB,IAAI,EAAE;AACrD,cAAM,eAAe,aAAa;AAElC,cAAM,iBAAa,wBAAW,YAAY,IAAI,EAAE;AAChD,cAAM,eAAe,aAAa;AAElC,kCAAO,UAAU,EAAE,KAAK,UAAU;AAClC,kCAAO,YAAY,EAAE,KAAK,YAAY;AAAA,MACxC,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH,CAAC;","names":[]}
@@ -0,0 +1,113 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { splitWords } from "../tokenize/basic/word.js";
3
+ describe("Interruption Detection - Word Counting", () => {
4
+ describe("Word Splitting Behavior", () => {
5
+ it("should count empty string as 0 words", () => {
6
+ const text = "";
7
+ const wordCount = splitWords(text, true).length;
8
+ expect(wordCount).toBe(0);
9
+ });
10
+ it("should count single word correctly", () => {
11
+ const text = "hello";
12
+ const wordCount = splitWords(text, true).length;
13
+ expect(wordCount).toBe(1);
14
+ });
15
+ it("should count two words correctly", () => {
16
+ const text = "hello world";
17
+ const wordCount = splitWords(text, true).length;
18
+ expect(wordCount).toBe(2);
19
+ });
20
+ it("should count multiple words correctly", () => {
21
+ const text = "hello this is a full sentence";
22
+ const wordCount = splitWords(text, true).length;
23
+ expect(wordCount).toBe(6);
24
+ });
25
+ it("should handle punctuation correctly", () => {
26
+ const text = "hello, world!";
27
+ const wordCount = splitWords(text, true).length;
28
+ expect(wordCount).toBe(2);
29
+ });
30
+ it("should handle multiple spaces between words", () => {
31
+ const text = "hello world";
32
+ const wordCount = splitWords(text, true).length;
33
+ expect(wordCount).toBe(2);
34
+ });
35
+ it("should count whitespace-only string as 0 words", () => {
36
+ const text = " ";
37
+ const wordCount = splitWords(text, true).length;
38
+ expect(wordCount).toBe(0);
39
+ });
40
+ it("should handle leading and trailing whitespace", () => {
41
+ const text = " hello world ";
42
+ const wordCount = splitWords(text, true).length;
43
+ expect(wordCount).toBe(2);
44
+ });
45
+ });
46
+ describe("Integration: Full Interruption Check Logic", () => {
47
+ it("should block interruption for empty transcript with threshold 2", () => {
48
+ const text = "";
49
+ const minInterruptionWords = 2;
50
+ const normalizedText = text ?? "";
51
+ const wordCount = splitWords(normalizedText, true).length;
52
+ const shouldBlock = wordCount < minInterruptionWords;
53
+ expect(normalizedText).toBe("");
54
+ expect(wordCount).toBe(0);
55
+ expect(shouldBlock).toBe(true);
56
+ });
57
+ it("should block interruption for undefined transcript with threshold 2", () => {
58
+ const text = void 0;
59
+ const minInterruptionWords = 2;
60
+ const normalizedText = text ?? "";
61
+ const wordCount = splitWords(normalizedText, true).length;
62
+ const shouldBlock = wordCount < minInterruptionWords;
63
+ expect(normalizedText).toBe("");
64
+ expect(wordCount).toBe(0);
65
+ expect(shouldBlock).toBe(true);
66
+ });
67
+ it("should block interruption for single word with threshold 2", () => {
68
+ const text = "hello";
69
+ const minInterruptionWords = 2;
70
+ const normalizedText = text ?? "";
71
+ const wordCount = splitWords(normalizedText, true).length;
72
+ const shouldBlock = wordCount < minInterruptionWords;
73
+ expect(normalizedText).toBe("hello");
74
+ expect(wordCount).toBe(1);
75
+ expect(shouldBlock).toBe(true);
76
+ });
77
+ it("should allow interruption when word count exactly meets threshold", () => {
78
+ const text = "hello world";
79
+ const minInterruptionWords = 2;
80
+ const normalizedText = text ?? "";
81
+ const wordCount = splitWords(normalizedText, true).length;
82
+ const shouldBlock = wordCount < minInterruptionWords;
83
+ expect(normalizedText).toBe("hello world");
84
+ expect(wordCount).toBe(2);
85
+ expect(shouldBlock).toBe(false);
86
+ });
87
+ it("should allow interruption when word count exceeds threshold", () => {
88
+ const text = "hello this is a full sentence";
89
+ const minInterruptionWords = 2;
90
+ const normalizedText = text ?? "";
91
+ const wordCount = splitWords(normalizedText, true).length;
92
+ const shouldBlock = wordCount < minInterruptionWords;
93
+ expect(normalizedText).toBe("hello this is a full sentence");
94
+ expect(wordCount).toBe(6);
95
+ expect(shouldBlock).toBe(false);
96
+ });
97
+ it("should apply consistent word counting logic in both methods", () => {
98
+ const transcripts = ["", "hello", "hello world", "this is a longer sentence"];
99
+ const threshold = 2;
100
+ transcripts.forEach((transcript) => {
101
+ const text1 = transcript;
102
+ const normalizedText1 = text1 ?? "";
103
+ const wordCount1 = splitWords(normalizedText1, true).length;
104
+ const shouldBlock1 = wordCount1 < threshold;
105
+ const wordCount2 = splitWords(transcript, true).length;
106
+ const shouldBlock2 = wordCount2 < threshold;
107
+ expect(wordCount1).toBe(wordCount2);
108
+ expect(shouldBlock1).toBe(shouldBlock2);
109
+ });
110
+ });
111
+ });
112
+ });
113
+ //# sourceMappingURL=interruption_detection.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/voice/interruption_detection.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Unit tests for interruption detection logic in AgentActivity.\n *\n * Tests the refactored minInterruptionWords check which ensures:\n * - Consistent word count filtering across all speech scenarios\n * - Proper handling of empty strings, undefined, and short speech\n * - Interruptions allowed only when word count meets or exceeds minInterruptionWords threshold\n */\nimport { describe, expect, it } from 'vitest';\nimport { splitWords } from '../tokenize/basic/word.js';\n\ndescribe('Interruption Detection - Word Counting', () => {\n describe('Word Splitting Behavior', () => {\n it('should count empty string as 0 words', () => {\n const text = '';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(0);\n });\n\n it('should count single word correctly', () => {\n const text = 'hello';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(1);\n });\n\n it('should count two words correctly', () => {\n const text = 'hello world';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(2);\n });\n\n it('should count multiple words correctly', () => {\n const text = 'hello this is a full sentence';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(6);\n });\n\n it('should handle punctuation correctly', () => {\n const text = 'hello, world!';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(2);\n });\n\n it('should handle multiple spaces between words', () => {\n const text = 'hello world';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(2);\n });\n\n it('should count whitespace-only string as 0 words', () => {\n const text = ' ';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(0);\n });\n\n it('should handle leading and trailing whitespace', () => {\n const text = ' hello world ';\n const wordCount = splitWords(text, true).length;\n expect(wordCount).toBe(2);\n });\n });\n\n describe('Integration: Full Interruption Check Logic', () => {\n it('should block interruption for empty transcript with threshold 2', () => {\n const text = '';\n const minInterruptionWords = 2;\n\n const normalizedText = text ?? '';\n const wordCount = splitWords(normalizedText, true).length;\n const shouldBlock = wordCount < minInterruptionWords;\n\n expect(normalizedText).toBe('');\n expect(wordCount).toBe(0);\n expect(shouldBlock).toBe(true);\n });\n\n it('should block interruption for undefined transcript with threshold 2', () => {\n const text: string | undefined = undefined;\n const minInterruptionWords = 2;\n\n const normalizedText = text ?? '';\n const wordCount = splitWords(normalizedText, true).length;\n const shouldBlock = wordCount < minInterruptionWords;\n\n expect(normalizedText).toBe('');\n expect(wordCount).toBe(0);\n expect(shouldBlock).toBe(true);\n });\n\n it('should block interruption for single word with threshold 2', () => {\n const text = 'hello';\n const minInterruptionWords = 2;\n\n const normalizedText = text ?? '';\n const wordCount = splitWords(normalizedText, true).length;\n const shouldBlock = wordCount < minInterruptionWords;\n\n expect(normalizedText).toBe('hello');\n expect(wordCount).toBe(1);\n expect(shouldBlock).toBe(true);\n });\n\n it('should allow interruption when word count exactly meets threshold', () => {\n const text = 'hello world';\n const minInterruptionWords = 2;\n\n const normalizedText = text ?? '';\n const wordCount = splitWords(normalizedText, true).length;\n const shouldBlock = wordCount < minInterruptionWords;\n\n expect(normalizedText).toBe('hello world');\n expect(wordCount).toBe(2);\n expect(shouldBlock).toBe(false);\n });\n\n it('should allow interruption when word count exceeds threshold', () => {\n const text = 'hello this is a full sentence';\n const minInterruptionWords = 2;\n\n const normalizedText = text ?? '';\n const wordCount = splitWords(normalizedText, true).length;\n const shouldBlock = wordCount < minInterruptionWords;\n\n expect(normalizedText).toBe('hello this is a full sentence');\n expect(wordCount).toBe(6);\n expect(shouldBlock).toBe(false);\n });\n\n it('should apply consistent word counting logic in both methods', () => {\n const transcripts = ['', 'hello', 'hello world', 'this is a longer sentence'];\n const threshold = 2;\n\n transcripts.forEach((transcript) => {\n const text1 = transcript;\n const normalizedText1 = text1 ?? '';\n const wordCount1 = splitWords(normalizedText1, true).length;\n const shouldBlock1 = wordCount1 < threshold;\n\n const wordCount2 = splitWords(transcript, true).length;\n const shouldBlock2 = wordCount2 < threshold;\n\n expect(wordCount1).toBe(wordCount2);\n expect(shouldBlock1).toBe(shouldBlock2);\n });\n });\n });\n});\n"],"mappings":"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","names":[]}
package/dist/voice/io.cjs CHANGED
@@ -22,17 +22,37 @@ __export(io_exports, {
22
22
  AgentOutput: () => AgentOutput,
23
23
  AudioInput: () => AudioInput,
24
24
  AudioOutput: () => AudioOutput,
25
- TextOutput: () => TextOutput
25
+ TIMED_STRING_SYMBOL: () => TIMED_STRING_SYMBOL,
26
+ TextOutput: () => TextOutput,
27
+ createTimedString: () => createTimedString,
28
+ isTimedString: () => isTimedString
26
29
  });
27
30
  module.exports = __toCommonJS(io_exports);
28
31
  var import_node_events = require("node:events");
29
32
  var import_log = require("../log.cjs");
30
- var import_deferred_stream = require("../stream/deferred_stream.cjs");
33
+ var import_multi_input_stream = require("../stream/multi_input_stream.cjs");
31
34
  var import_utils = require("../utils.cjs");
35
+ const TIMED_STRING_SYMBOL = Symbol.for("lk.TimedString");
36
+ function createTimedString(opts) {
37
+ return {
38
+ [TIMED_STRING_SYMBOL]: true,
39
+ text: opts.text,
40
+ startTime: opts.startTime,
41
+ endTime: opts.endTime,
42
+ confidence: opts.confidence,
43
+ startTimeOffset: opts.startTimeOffset
44
+ };
45
+ }
46
+ function isTimedString(value) {
47
+ return typeof value === "object" && value !== null && TIMED_STRING_SYMBOL in value && value[TIMED_STRING_SYMBOL] === true;
48
+ }
32
49
  class AudioInput {
33
- deferredStream = new import_deferred_stream.DeferredReadableStream();
50
+ multiStream = new import_multi_input_stream.MultiInputStream();
34
51
  get stream() {
35
- return this.deferredStream.stream;
52
+ return this.multiStream.stream;
53
+ }
54
+ async close() {
55
+ await this.multiStream.close();
36
56
  }
37
57
  onAttached() {
38
58
  }
@@ -40,17 +60,23 @@ class AudioInput {
40
60
  }
41
61
  }
42
62
  class AudioOutput extends import_node_events.EventEmitter {
43
- constructor(sampleRate, nextInChain) {
63
+ constructor(sampleRate, nextInChain, capabilities = { pause: false }) {
44
64
  super();
45
65
  this.sampleRate = sampleRate;
46
66
  this.nextInChain = nextInChain;
67
+ this.capabilities = capabilities;
47
68
  if (this.nextInChain) {
69
+ this.nextInChain.on(
70
+ AudioOutput.EVENT_PLAYBACK_STARTED,
71
+ (ev) => this.onPlaybackStarted(ev.createdAt)
72
+ );
48
73
  this.nextInChain.on(
49
74
  AudioOutput.EVENT_PLAYBACK_FINISHED,
50
75
  (ev) => this.onPlaybackFinished(ev)
51
76
  );
52
77
  }
53
78
  }
79
+ static EVENT_PLAYBACK_STARTED = "playbackStarted";
54
80
  static EVENT_PLAYBACK_FINISHED = "playbackFinished";
55
81
  playbackFinishedFuture = new import_utils.Future();
56
82
  _capturing = false;
@@ -61,6 +87,14 @@ class AudioOutput extends import_node_events.EventEmitter {
61
87
  interrupted: false
62
88
  };
63
89
  logger = (0, import_log.log)();
90
+ capabilities;
91
+ /**
92
+ * Whether this output and all outputs in the chain support pause/resume.
93
+ */
94
+ get canPause() {
95
+ var _a;
96
+ return this.capabilities.pause && (((_a = this.nextInChain) == null ? void 0 : _a.canPause) ?? true);
97
+ }
64
98
  /**
65
99
  * Capture an audio frame for playback, frames can be pushed faster than real-time
66
100
  */
@@ -83,6 +117,13 @@ class AudioOutput extends import_node_events.EventEmitter {
83
117
  }
84
118
  return this.lastPlaybackEvent;
85
119
  }
120
+ /**
121
+ * Called when playback actually starts (first frame is sent to output).
122
+ * Developers building audio sinks should call this when the first frame is captured.
123
+ */
124
+ onPlaybackStarted(createdAt) {
125
+ this.emit(AudioOutput.EVENT_PLAYBACK_STARTED, { createdAt });
126
+ }
86
127
  /**
87
128
  * Developers building audio sinks must call this method when a playback/segment is finished.
88
129
  * Segments are segmented by calls to flush() or clearBuffer()
@@ -110,6 +151,22 @@ class AudioOutput extends import_node_events.EventEmitter {
110
151
  this.nextInChain.onDetached();
111
152
  }
112
153
  }
154
+ /**
155
+ * Pause the audio playback
156
+ */
157
+ pause() {
158
+ if (this.nextInChain) {
159
+ this.nextInChain.pause();
160
+ }
161
+ }
162
+ /**
163
+ * Resume the audio playback
164
+ */
165
+ resume() {
166
+ if (this.nextInChain) {
167
+ this.nextInChain.resume();
168
+ }
169
+ }
113
170
  }
114
171
  class TextOutput {
115
172
  constructor(nextInChain) {
@@ -240,6 +297,9 @@ class AgentOutput {
240
297
  AgentOutput,
241
298
  AudioInput,
242
299
  AudioOutput,
243
- TextOutput
300
+ TIMED_STRING_SYMBOL,
301
+ TextOutput,
302
+ createTimedString,
303
+ isTimedString
244
304
  });
245
305
  //# sourceMappingURL=io.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/voice/io.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport { EventEmitter } from 'node:events';\nimport type { ReadableStream } from 'node:stream/web';\nimport type { ChatContext } from '../llm/chat_context.js';\nimport type { ChatChunk } from '../llm/llm.js';\nimport type { ToolContext } from '../llm/tool_context.js';\nimport { log } from '../log.js';\nimport { DeferredReadableStream } from '../stream/deferred_stream.js';\nimport type { SpeechEvent } from '../stt/stt.js';\nimport { Future } from '../utils.js';\nimport type { ModelSettings } from './agent.js';\n\nexport type STTNode = (\n audio: ReadableStream<AudioFrame>,\n modelSettings: ModelSettings,\n) => Promise<ReadableStream<SpeechEvent | string> | null>;\n\nexport type LLMNode = (\n chatCtx: ChatContext,\n toolCtx: ToolContext,\n modelSettings: ModelSettings,\n) => Promise<ReadableStream<ChatChunk | string> | null>;\n\nexport type TTSNode = (\n text: ReadableStream<string>,\n modelSettings: ModelSettings,\n) => Promise<ReadableStream<AudioFrame> | null>;\nexport abstract class AudioInput {\n protected deferredStream: DeferredReadableStream<AudioFrame> =\n new DeferredReadableStream<AudioFrame>();\n\n get stream(): ReadableStream<AudioFrame> {\n return this.deferredStream.stream;\n }\n\n onAttached(): void {}\n\n onDetached(): void {}\n}\n\nexport abstract class AudioOutput extends EventEmitter {\n static readonly EVENT_PLAYBACK_FINISHED = 'playbackFinished';\n\n private playbackFinishedFuture: Future<void> = new Future();\n private _capturing: boolean = false;\n private playbackFinishedCount: number = 0;\n private playbackSegmentsCount: number = 0;\n private lastPlaybackEvent: PlaybackFinishedEvent = {\n playbackPosition: 0,\n interrupted: false,\n };\n protected logger = log();\n\n constructor(\n public sampleRate?: number,\n protected readonly nextInChain?: AudioOutput,\n ) {\n super();\n if (this.nextInChain) {\n this.nextInChain.on(AudioOutput.EVENT_PLAYBACK_FINISHED, (ev: PlaybackFinishedEvent) =>\n this.onPlaybackFinished(ev),\n );\n }\n }\n\n /**\n * Capture an audio frame for playback, frames can be pushed faster than real-time\n */\n async captureFrame(_frame: AudioFrame): Promise<void> {\n if (!this._capturing) {\n this._capturing = true;\n this.playbackSegmentsCount++;\n }\n }\n\n /**\n * Wait for the past audio segments to finish playing out.\n *\n * @returns The event that was emitted when the audio finished playing out (only the last segment information)\n */\n async waitForPlayout(): Promise<PlaybackFinishedEvent> {\n const target = this.playbackSegmentsCount;\n\n while (this.playbackFinishedCount < target) {\n await this.playbackFinishedFuture.await;\n this.playbackFinishedFuture = new Future();\n }\n\n return this.lastPlaybackEvent;\n }\n\n /**\n * Developers building audio sinks must call this method when a playback/segment is finished.\n * Segments are segmented by calls to flush() or clearBuffer()\n */\n onPlaybackFinished(options: PlaybackFinishedEvent) {\n if (this.playbackFinishedCount >= this.playbackSegmentsCount) {\n this.logger.warn('playback_finished called more times than playback segments were captured');\n return;\n }\n\n this.lastPlaybackEvent = options;\n this.playbackFinishedCount++;\n this.playbackFinishedFuture.resolve();\n this.emit(AudioOutput.EVENT_PLAYBACK_FINISHED, options);\n }\n\n flush(): void {\n this._capturing = false;\n }\n\n /**\n * Clear the buffer, stopping playback immediately\n */\n abstract clearBuffer(): void;\n\n onAttached(): void {\n if (this.nextInChain) {\n this.nextInChain.onAttached();\n }\n }\n\n onDetached(): void {\n if (this.nextInChain) {\n this.nextInChain.onDetached();\n }\n }\n}\n\nexport interface PlaybackFinishedEvent {\n // How much of the audio was played back\n playbackPosition: number;\n // Interrupted is True if playback was interrupted (clearBuffer() was called)\n interrupted: boolean;\n // Transcript synced with playback; may be partial if the audio was interrupted\n // When null, the transcript is not synchronized with the playback\n synchronizedTranscript?: string;\n}\n\nexport abstract class TextOutput {\n constructor(protected readonly nextInChain?: TextOutput) {}\n\n /**\n * Capture a text segment (Used by the output of LLM nodes)\n */\n abstract captureText(text: string): Promise<void>;\n\n /**\n * Mark the current text segment as complete (e.g LLM generation is complete)\n */\n abstract flush(): void;\n\n onAttached(): void {\n if (this.nextInChain) {\n this.nextInChain.onAttached();\n }\n }\n\n onDetached(): void {\n if (this.nextInChain) {\n this.nextInChain.onDetached();\n }\n }\n}\n\nexport class AgentInput {\n private _audioStream: AudioInput | null = null;\n // enabled by default\n private _audioEnabled: boolean = true;\n\n constructor(private readonly audioChanged: () => void) {}\n\n setAudioEnabled(enable: boolean): void {\n if (enable === this._audioEnabled) {\n return;\n }\n\n this._audioEnabled = enable;\n\n if (!this._audioStream) {\n return;\n }\n\n if (enable) {\n this._audioStream.onAttached();\n } else {\n this._audioStream.onDetached();\n }\n }\n\n get audioEnabled(): boolean {\n return this._audioEnabled;\n }\n\n get audio(): AudioInput | null {\n return this._audioStream;\n }\n\n set audio(stream: AudioInput | null) {\n this._audioStream = stream;\n this.audioChanged();\n }\n}\n\nexport class AgentOutput {\n private _audioSink: AudioOutput | null = null;\n private _transcriptionSink: TextOutput | null = null;\n private _audioEnabled: boolean = true;\n private _transcriptionEnabled: boolean = true;\n\n constructor(\n private readonly audioChanged: () => void,\n private readonly transcriptionChanged: () => void,\n ) {}\n\n setAudioEnabled(enabled: boolean): void {\n if (enabled === this._audioEnabled) {\n return;\n }\n\n this._audioEnabled = enabled;\n\n if (!this._audioSink) {\n return;\n }\n\n if (enabled) {\n this._audioSink.onAttached();\n } else {\n this._audioSink.onDetached();\n }\n }\n\n setTranscriptionEnabled(enabled: boolean): void {\n if (enabled === this._transcriptionEnabled) {\n return;\n }\n\n this._transcriptionEnabled = enabled;\n\n if (!this._transcriptionSink) {\n return;\n }\n\n if (enabled) {\n this._transcriptionSink.onAttached();\n } else {\n this._transcriptionSink.onDetached();\n }\n }\n\n get audioEnabled(): boolean {\n return this._audioEnabled;\n }\n\n get transcriptionEnabled(): boolean {\n return this._transcriptionEnabled;\n }\n\n get audio(): AudioOutput | null {\n return this._audioSink;\n }\n\n set audio(sink: AudioOutput | null) {\n if (sink === this._audioSink) {\n return;\n }\n\n if (this._audioSink) {\n this._audioSink.onDetached();\n }\n\n this._audioSink = sink;\n this.audioChanged();\n\n if (this._audioSink) {\n this._audioSink.onAttached();\n }\n }\n\n get transcription(): TextOutput | null {\n return this._transcriptionSink;\n }\n\n set transcription(sink: TextOutput | null) {\n if (sink === this._transcriptionSink) {\n return;\n }\n\n if (this._transcriptionSink) {\n this._transcriptionSink.onDetached();\n }\n\n this._transcriptionSink = sink;\n this.transcriptionChanged();\n\n if (this._transcriptionSink) {\n this._transcriptionSink.onAttached();\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/voice/io.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport { EventEmitter } from 'node:events';\nimport type { ReadableStream } from 'node:stream/web';\nimport type { ChatContext } from '../llm/chat_context.js';\nimport type { ChatChunk } from '../llm/llm.js';\nimport type { ToolContext } from '../llm/tool_context.js';\nimport { log } from '../log.js';\nimport { MultiInputStream } from '../stream/multi_input_stream.js';\nimport type { SpeechEvent } from '../stt/stt.js';\nimport { Future } from '../utils.js';\nimport type { ModelSettings } from './agent.js';\n\nexport type STTNode = (\n audio: ReadableStream<AudioFrame>,\n modelSettings: ModelSettings,\n) => Promise<ReadableStream<SpeechEvent | string> | null>;\n\nexport type LLMNode = (\n chatCtx: ChatContext,\n toolCtx: ToolContext,\n modelSettings: ModelSettings,\n) => Promise<ReadableStream<ChatChunk | string> | null>;\n\nexport type TTSNode = (\n text: ReadableStream<string>,\n modelSettings: ModelSettings,\n) => Promise<ReadableStream<AudioFrame> | null>;\n\n/**\n * Symbol used to identify TimedString objects.\n */\nexport const TIMED_STRING_SYMBOL = Symbol.for('lk.TimedString');\n\n/**\n * A string with optional start and end timestamps for word-level alignment.\n */\nexport interface TimedString {\n readonly [TIMED_STRING_SYMBOL]: true;\n text: string;\n startTime?: number; // seconds\n endTime?: number; // seconds\n confidence?: number;\n startTimeOffset?: number;\n}\n\n/**\n * Factory function to create a TimedString object.\n */\nexport function createTimedString(opts: {\n text: string;\n startTime?: number;\n endTime?: number;\n confidence?: number;\n startTimeOffset?: number;\n}): TimedString {\n return {\n [TIMED_STRING_SYMBOL]: true,\n text: opts.text,\n startTime: opts.startTime,\n endTime: opts.endTime,\n confidence: opts.confidence,\n startTimeOffset: opts.startTimeOffset,\n };\n}\n\n/**\n * Type guard to check if a value is a TimedString.\n */\nexport function isTimedString(value: unknown): value is TimedString {\n return (\n typeof value === 'object' &&\n value !== null &&\n TIMED_STRING_SYMBOL in value &&\n (value as TimedString)[TIMED_STRING_SYMBOL] === true\n );\n}\n\nexport interface AudioOutputCapabilities {\n /** Whether this output supports pause/resume functionality */\n pause: boolean;\n}\n\nexport abstract class AudioInput {\n protected multiStream: MultiInputStream<AudioFrame> = new MultiInputStream<AudioFrame>();\n\n get stream(): ReadableStream<AudioFrame> {\n return this.multiStream.stream;\n }\n\n async close(): Promise<void> {\n await this.multiStream.close();\n }\n\n onAttached(): void {}\n\n onDetached(): void {}\n}\n\nexport abstract class AudioOutput extends EventEmitter {\n static readonly EVENT_PLAYBACK_STARTED = 'playbackStarted';\n static readonly EVENT_PLAYBACK_FINISHED = 'playbackFinished';\n\n private playbackFinishedFuture: Future<void> = new Future();\n private _capturing: boolean = false;\n private playbackFinishedCount: number = 0;\n private playbackSegmentsCount: number = 0;\n private lastPlaybackEvent: PlaybackFinishedEvent = {\n playbackPosition: 0,\n interrupted: false,\n };\n protected logger = log();\n protected readonly capabilities: AudioOutputCapabilities;\n\n constructor(\n public sampleRate?: number,\n protected readonly nextInChain?: AudioOutput,\n capabilities: AudioOutputCapabilities = { pause: false },\n ) {\n super();\n this.capabilities = capabilities;\n\n if (this.nextInChain) {\n this.nextInChain.on(AudioOutput.EVENT_PLAYBACK_STARTED, (ev: PlaybackStartedEvent) =>\n this.onPlaybackStarted(ev.createdAt),\n );\n this.nextInChain.on(AudioOutput.EVENT_PLAYBACK_FINISHED, (ev: PlaybackFinishedEvent) =>\n this.onPlaybackFinished(ev),\n );\n }\n }\n\n /**\n * Whether this output and all outputs in the chain support pause/resume.\n */\n get canPause(): boolean {\n return this.capabilities.pause && (this.nextInChain?.canPause ?? true);\n }\n\n /**\n * Capture an audio frame for playback, frames can be pushed faster than real-time\n */\n async captureFrame(_frame: AudioFrame): Promise<void> {\n if (!this._capturing) {\n this._capturing = true;\n this.playbackSegmentsCount++;\n }\n }\n\n /**\n * Wait for the past audio segments to finish playing out.\n *\n * @returns The event that was emitted when the audio finished playing out (only the last segment information)\n */\n async waitForPlayout(): Promise<PlaybackFinishedEvent> {\n const target = this.playbackSegmentsCount;\n\n while (this.playbackFinishedCount < target) {\n await this.playbackFinishedFuture.await;\n this.playbackFinishedFuture = new Future();\n }\n\n return this.lastPlaybackEvent;\n }\n\n /**\n * Called when playback actually starts (first frame is sent to output).\n * Developers building audio sinks should call this when the first frame is captured.\n */\n onPlaybackStarted(createdAt: number): void {\n this.emit(AudioOutput.EVENT_PLAYBACK_STARTED, { createdAt } as PlaybackStartedEvent);\n }\n\n /**\n * Developers building audio sinks must call this method when a playback/segment is finished.\n * Segments are segmented by calls to flush() or clearBuffer()\n */\n onPlaybackFinished(options: PlaybackFinishedEvent) {\n if (this.playbackFinishedCount >= this.playbackSegmentsCount) {\n this.logger.warn('playback_finished called more times than playback segments were captured');\n return;\n }\n\n this.lastPlaybackEvent = options;\n this.playbackFinishedCount++;\n this.playbackFinishedFuture.resolve();\n this.emit(AudioOutput.EVENT_PLAYBACK_FINISHED, options);\n }\n\n flush(): void {\n this._capturing = false;\n }\n\n /**\n * Clear the buffer, stopping playback immediately\n */\n abstract clearBuffer(): void;\n\n onAttached(): void {\n if (this.nextInChain) {\n this.nextInChain.onAttached();\n }\n }\n\n onDetached(): void {\n if (this.nextInChain) {\n this.nextInChain.onDetached();\n }\n }\n\n /**\n * Pause the audio playback\n */\n pause(): void {\n if (this.nextInChain) {\n this.nextInChain.pause();\n }\n }\n\n /**\n * Resume the audio playback\n */\n resume(): void {\n if (this.nextInChain) {\n this.nextInChain.resume();\n }\n }\n}\n\nexport interface PlaybackFinishedEvent {\n /** How much of the audio was played back, in seconds */\n playbackPosition: number;\n /** True if playback was interrupted (clearBuffer() was called) */\n interrupted: boolean;\n /**\n * Transcript synced with playback; may be partial if the audio was interrupted.\n * When undefined, the transcript is not synchronized with the playback.\n */\n synchronizedTranscript?: string;\n}\n\nexport interface PlaybackStartedEvent {\n /** The timestamp (Date.now()) when the playback started */\n createdAt: number;\n}\n\nexport abstract class TextOutput {\n constructor(protected readonly nextInChain?: TextOutput) {}\n\n abstract captureText(text: string | TimedString): Promise<void>;\n\n /**\n * Mark the current text segment as complete (e.g LLM generation is complete)\n */\n abstract flush(): void;\n\n onAttached(): void {\n if (this.nextInChain) {\n this.nextInChain.onAttached();\n }\n }\n\n onDetached(): void {\n if (this.nextInChain) {\n this.nextInChain.onDetached();\n }\n }\n}\n\nexport class AgentInput {\n private _audioStream: AudioInput | null = null;\n // enabled by default\n private _audioEnabled: boolean = true;\n\n constructor(private readonly audioChanged: () => void) {}\n\n setAudioEnabled(enable: boolean): void {\n if (enable === this._audioEnabled) {\n return;\n }\n\n this._audioEnabled = enable;\n\n if (!this._audioStream) {\n return;\n }\n\n if (enable) {\n this._audioStream.onAttached();\n } else {\n this._audioStream.onDetached();\n }\n }\n\n get audioEnabled(): boolean {\n return this._audioEnabled;\n }\n\n get audio(): AudioInput | null {\n return this._audioStream;\n }\n\n set audio(stream: AudioInput | null) {\n this._audioStream = stream;\n this.audioChanged();\n }\n}\n\nexport class AgentOutput {\n private _audioSink: AudioOutput | null = null;\n private _transcriptionSink: TextOutput | null = null;\n private _audioEnabled: boolean = true;\n private _transcriptionEnabled: boolean = true;\n\n constructor(\n private readonly audioChanged: () => void,\n private readonly transcriptionChanged: () => void,\n ) {}\n\n setAudioEnabled(enabled: boolean): void {\n if (enabled === this._audioEnabled) {\n return;\n }\n\n this._audioEnabled = enabled;\n\n if (!this._audioSink) {\n return;\n }\n\n if (enabled) {\n this._audioSink.onAttached();\n } else {\n this._audioSink.onDetached();\n }\n }\n\n setTranscriptionEnabled(enabled: boolean): void {\n if (enabled === this._transcriptionEnabled) {\n return;\n }\n\n this._transcriptionEnabled = enabled;\n\n if (!this._transcriptionSink) {\n return;\n }\n\n if (enabled) {\n this._transcriptionSink.onAttached();\n } else {\n this._transcriptionSink.onDetached();\n }\n }\n\n get audioEnabled(): boolean {\n return this._audioEnabled;\n }\n\n get transcriptionEnabled(): boolean {\n return this._transcriptionEnabled;\n }\n\n get audio(): AudioOutput | null {\n return this._audioSink;\n }\n\n set audio(sink: AudioOutput | null) {\n if (sink === this._audioSink) {\n return;\n }\n\n if (this._audioSink) {\n this._audioSink.onDetached();\n }\n\n this._audioSink = sink;\n this.audioChanged();\n\n if (this._audioSink) {\n this._audioSink.onAttached();\n }\n }\n\n get transcription(): TextOutput | null {\n return this._transcriptionSink;\n }\n\n set transcription(sink: TextOutput | null) {\n if (sink === this._transcriptionSink) {\n return;\n }\n\n if (this._transcriptionSink) {\n this._transcriptionSink.onDetached();\n }\n\n this._transcriptionSink = sink;\n this.transcriptionChanged();\n\n if (this._transcriptionSink) {\n this._transcriptionSink.onAttached();\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -6,21 +6,56 @@ import type { ReadableStream } from 'node:stream/web';
6
6
  import type { ChatContext } from '../llm/chat_context.js';
7
7
  import type { ChatChunk } from '../llm/llm.js';
8
8
  import type { ToolContext } from '../llm/tool_context.js';
9
- import { DeferredReadableStream } from '../stream/deferred_stream.js';
9
+ import { MultiInputStream } from '../stream/multi_input_stream.js';
10
10
  import type { SpeechEvent } from '../stt/stt.js';
11
11
  import type { ModelSettings } from './agent.js';
12
12
  export type STTNode = (audio: ReadableStream<AudioFrame>, modelSettings: ModelSettings) => Promise<ReadableStream<SpeechEvent | string> | null>;
13
13
  export type LLMNode = (chatCtx: ChatContext, toolCtx: ToolContext, modelSettings: ModelSettings) => Promise<ReadableStream<ChatChunk | string> | null>;
14
14
  export type TTSNode = (text: ReadableStream<string>, modelSettings: ModelSettings) => Promise<ReadableStream<AudioFrame> | null>;
15
+ /**
16
+ * Symbol used to identify TimedString objects.
17
+ */
18
+ export declare const TIMED_STRING_SYMBOL: unique symbol;
19
+ /**
20
+ * A string with optional start and end timestamps for word-level alignment.
21
+ */
22
+ export interface TimedString {
23
+ readonly [TIMED_STRING_SYMBOL]: true;
24
+ text: string;
25
+ startTime?: number;
26
+ endTime?: number;
27
+ confidence?: number;
28
+ startTimeOffset?: number;
29
+ }
30
+ /**
31
+ * Factory function to create a TimedString object.
32
+ */
33
+ export declare function createTimedString(opts: {
34
+ text: string;
35
+ startTime?: number;
36
+ endTime?: number;
37
+ confidence?: number;
38
+ startTimeOffset?: number;
39
+ }): TimedString;
40
+ /**
41
+ * Type guard to check if a value is a TimedString.
42
+ */
43
+ export declare function isTimedString(value: unknown): value is TimedString;
44
+ export interface AudioOutputCapabilities {
45
+ /** Whether this output supports pause/resume functionality */
46
+ pause: boolean;
47
+ }
15
48
  export declare abstract class AudioInput {
16
- protected deferredStream: DeferredReadableStream<AudioFrame>;
49
+ protected multiStream: MultiInputStream<AudioFrame>;
17
50
  get stream(): ReadableStream<AudioFrame>;
51
+ close(): Promise<void>;
18
52
  onAttached(): void;
19
53
  onDetached(): void;
20
54
  }
21
55
  export declare abstract class AudioOutput extends EventEmitter {
22
56
  sampleRate?: number | undefined;
23
57
  protected readonly nextInChain?: AudioOutput | undefined;
58
+ static readonly EVENT_PLAYBACK_STARTED = "playbackStarted";
24
59
  static readonly EVENT_PLAYBACK_FINISHED = "playbackFinished";
25
60
  private playbackFinishedFuture;
26
61
  private _capturing;
@@ -28,7 +63,12 @@ export declare abstract class AudioOutput extends EventEmitter {
28
63
  private playbackSegmentsCount;
29
64
  private lastPlaybackEvent;
30
65
  protected logger: import("pino").Logger;
31
- constructor(sampleRate?: number | undefined, nextInChain?: AudioOutput | undefined);
66
+ protected readonly capabilities: AudioOutputCapabilities;
67
+ constructor(sampleRate?: number | undefined, nextInChain?: AudioOutput | undefined, capabilities?: AudioOutputCapabilities);
68
+ /**
69
+ * Whether this output and all outputs in the chain support pause/resume.
70
+ */
71
+ get canPause(): boolean;
32
72
  /**
33
73
  * Capture an audio frame for playback, frames can be pushed faster than real-time
34
74
  */
@@ -39,6 +79,11 @@ export declare abstract class AudioOutput extends EventEmitter {
39
79
  * @returns The event that was emitted when the audio finished playing out (only the last segment information)
40
80
  */
41
81
  waitForPlayout(): Promise<PlaybackFinishedEvent>;
82
+ /**
83
+ * Called when playback actually starts (first frame is sent to output).
84
+ * Developers building audio sinks should call this when the first frame is captured.
85
+ */
86
+ onPlaybackStarted(createdAt: number): void;
42
87
  /**
43
88
  * Developers building audio sinks must call this method when a playback/segment is finished.
44
89
  * Segments are segmented by calls to flush() or clearBuffer()
@@ -51,19 +96,34 @@ export declare abstract class AudioOutput extends EventEmitter {
51
96
  abstract clearBuffer(): void;
52
97
  onAttached(): void;
53
98
  onDetached(): void;
99
+ /**
100
+ * Pause the audio playback
101
+ */
102
+ pause(): void;
103
+ /**
104
+ * Resume the audio playback
105
+ */
106
+ resume(): void;
54
107
  }
55
108
  export interface PlaybackFinishedEvent {
109
+ /** How much of the audio was played back, in seconds */
56
110
  playbackPosition: number;
111
+ /** True if playback was interrupted (clearBuffer() was called) */
57
112
  interrupted: boolean;
113
+ /**
114
+ * Transcript synced with playback; may be partial if the audio was interrupted.
115
+ * When undefined, the transcript is not synchronized with the playback.
116
+ */
58
117
  synchronizedTranscript?: string;
59
118
  }
119
+ export interface PlaybackStartedEvent {
120
+ /** The timestamp (Date.now()) when the playback started */
121
+ createdAt: number;
122
+ }
60
123
  export declare abstract class TextOutput {
61
124
  protected readonly nextInChain?: TextOutput | undefined;
62
125
  constructor(nextInChain?: TextOutput | undefined);
63
- /**
64
- * Capture a text segment (Used by the output of LLM nodes)
65
- */
66
- abstract captureText(text: string): Promise<void>;
126
+ abstract captureText(text: string | TimedString): Promise<void>;
67
127
  /**
68
128
  * Mark the current text segment as complete (e.g LLM generation is complete)
69
129
  */