@livekit/agents 0.7.9 → 1.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (627) hide show
  1. package/dist/_exceptions.cjs +109 -0
  2. package/dist/_exceptions.cjs.map +1 -0
  3. package/dist/_exceptions.d.cts +64 -0
  4. package/dist/_exceptions.d.ts +64 -0
  5. package/dist/_exceptions.d.ts.map +1 -0
  6. package/dist/_exceptions.js +80 -0
  7. package/dist/_exceptions.js.map +1 -0
  8. package/dist/audio.cjs +10 -3
  9. package/dist/audio.cjs.map +1 -1
  10. package/dist/audio.d.cts +2 -0
  11. package/dist/audio.d.ts +2 -0
  12. package/dist/audio.d.ts.map +1 -1
  13. package/dist/audio.js +8 -2
  14. package/dist/audio.js.map +1 -1
  15. package/dist/cli.cjs +25 -0
  16. package/dist/cli.cjs.map +1 -1
  17. package/dist/cli.d.ts.map +1 -1
  18. package/dist/cli.js +25 -0
  19. package/dist/cli.js.map +1 -1
  20. package/dist/constants.cjs +6 -3
  21. package/dist/constants.cjs.map +1 -1
  22. package/dist/constants.d.cts +2 -1
  23. package/dist/constants.d.ts +2 -1
  24. package/dist/constants.d.ts.map +1 -1
  25. package/dist/constants.js +4 -2
  26. package/dist/constants.js.map +1 -1
  27. package/dist/http_server.cjs.map +1 -1
  28. package/dist/http_server.d.cts +1 -0
  29. package/dist/http_server.d.ts +1 -0
  30. package/dist/http_server.d.ts.map +1 -1
  31. package/dist/http_server.js.map +1 -1
  32. package/dist/index.cjs +27 -20
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +13 -10
  35. package/dist/index.d.ts +13 -10
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +15 -11
  38. package/dist/index.js.map +1 -1
  39. package/dist/inference_runner.cjs +0 -1
  40. package/dist/inference_runner.cjs.map +1 -1
  41. package/dist/inference_runner.d.cts +2 -3
  42. package/dist/inference_runner.d.ts +2 -3
  43. package/dist/inference_runner.d.ts.map +1 -1
  44. package/dist/inference_runner.js +0 -1
  45. package/dist/inference_runner.js.map +1 -1
  46. package/dist/ipc/inference_proc_executor.cjs +2 -2
  47. package/dist/ipc/inference_proc_executor.cjs.map +1 -1
  48. package/dist/ipc/inference_proc_executor.js +2 -2
  49. package/dist/ipc/inference_proc_executor.js.map +1 -1
  50. package/dist/ipc/job_executor.cjs.map +1 -1
  51. package/dist/ipc/job_executor.js.map +1 -1
  52. package/dist/ipc/job_proc_executor.cjs +1 -0
  53. package/dist/ipc/job_proc_executor.cjs.map +1 -1
  54. package/dist/ipc/job_proc_executor.js +1 -0
  55. package/dist/ipc/job_proc_executor.js.map +1 -1
  56. package/dist/ipc/job_proc_lazy_main.cjs +1 -1
  57. package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
  58. package/dist/ipc/job_proc_lazy_main.js +1 -1
  59. package/dist/ipc/job_proc_lazy_main.js.map +1 -1
  60. package/dist/ipc/supervised_proc.d.cts +1 -1
  61. package/dist/ipc/supervised_proc.d.ts +1 -1
  62. package/dist/ipc/supervised_proc.d.ts.map +1 -1
  63. package/dist/job.cjs +14 -2
  64. package/dist/job.cjs.map +1 -1
  65. package/dist/job.d.cts +8 -0
  66. package/dist/job.d.ts +8 -0
  67. package/dist/job.d.ts.map +1 -1
  68. package/dist/job.js +12 -1
  69. package/dist/job.js.map +1 -1
  70. package/dist/llm/chat_context.cjs +332 -82
  71. package/dist/llm/chat_context.cjs.map +1 -1
  72. package/dist/llm/chat_context.d.cts +152 -48
  73. package/dist/llm/chat_context.d.ts +152 -48
  74. package/dist/llm/chat_context.d.ts.map +1 -1
  75. package/dist/llm/chat_context.js +327 -81
  76. package/dist/llm/chat_context.js.map +1 -1
  77. package/dist/llm/chat_context.test.cjs +380 -0
  78. package/dist/llm/chat_context.test.cjs.map +1 -0
  79. package/dist/llm/chat_context.test.js +385 -0
  80. package/dist/llm/chat_context.test.js.map +1 -0
  81. package/dist/llm/index.cjs +37 -8
  82. package/dist/llm/index.cjs.map +1 -1
  83. package/dist/llm/index.d.cts +7 -3
  84. package/dist/llm/index.d.ts +7 -3
  85. package/dist/llm/index.d.ts.map +1 -1
  86. package/dist/llm/index.js +39 -9
  87. package/dist/llm/index.js.map +1 -1
  88. package/dist/llm/llm.cjs +98 -33
  89. package/dist/llm/llm.cjs.map +1 -1
  90. package/dist/llm/llm.d.cts +50 -24
  91. package/dist/llm/llm.d.ts +50 -24
  92. package/dist/llm/llm.d.ts.map +1 -1
  93. package/dist/llm/llm.js +99 -33
  94. package/dist/llm/llm.js.map +1 -1
  95. package/dist/llm/provider_format/google.cjs +128 -0
  96. package/dist/llm/provider_format/google.cjs.map +1 -0
  97. package/dist/llm/provider_format/google.d.cts +6 -0
  98. package/dist/llm/provider_format/google.d.ts +6 -0
  99. package/dist/llm/provider_format/google.d.ts.map +1 -0
  100. package/dist/llm/provider_format/google.js +104 -0
  101. package/dist/llm/provider_format/google.js.map +1 -0
  102. package/dist/llm/provider_format/google.test.cjs +676 -0
  103. package/dist/llm/provider_format/google.test.cjs.map +1 -0
  104. package/dist/llm/provider_format/google.test.js +675 -0
  105. package/dist/llm/provider_format/google.test.js.map +1 -0
  106. package/dist/llm/provider_format/index.cjs +40 -0
  107. package/dist/llm/provider_format/index.cjs.map +1 -0
  108. package/dist/llm/provider_format/index.d.cts +4 -0
  109. package/dist/llm/provider_format/index.d.ts +4 -0
  110. package/dist/llm/provider_format/index.d.ts.map +1 -0
  111. package/dist/llm/provider_format/index.js +16 -0
  112. package/dist/llm/provider_format/index.js.map +1 -0
  113. package/dist/llm/provider_format/openai.cjs +116 -0
  114. package/dist/llm/provider_format/openai.cjs.map +1 -0
  115. package/dist/llm/provider_format/openai.d.cts +3 -0
  116. package/dist/llm/provider_format/openai.d.ts +3 -0
  117. package/dist/llm/provider_format/openai.d.ts.map +1 -0
  118. package/dist/llm/provider_format/openai.js +92 -0
  119. package/dist/llm/provider_format/openai.js.map +1 -0
  120. package/dist/llm/provider_format/openai.test.cjs +490 -0
  121. package/dist/llm/provider_format/openai.test.cjs.map +1 -0
  122. package/dist/llm/provider_format/openai.test.js +489 -0
  123. package/dist/llm/provider_format/openai.test.js.map +1 -0
  124. package/dist/llm/provider_format/utils.cjs +146 -0
  125. package/dist/llm/provider_format/utils.cjs.map +1 -0
  126. package/dist/llm/provider_format/utils.d.cts +38 -0
  127. package/dist/llm/provider_format/utils.d.ts +38 -0
  128. package/dist/llm/provider_format/utils.d.ts.map +1 -0
  129. package/dist/llm/provider_format/utils.js +122 -0
  130. package/dist/llm/provider_format/utils.js.map +1 -0
  131. package/dist/llm/realtime.cjs +77 -0
  132. package/dist/llm/realtime.cjs.map +1 -0
  133. package/dist/llm/realtime.d.cts +98 -0
  134. package/dist/llm/realtime.d.ts +98 -0
  135. package/dist/llm/realtime.d.ts.map +1 -0
  136. package/dist/llm/realtime.js +52 -0
  137. package/dist/llm/realtime.js.map +1 -0
  138. package/dist/llm/remote_chat_context.cjs +112 -0
  139. package/dist/llm/remote_chat_context.cjs.map +1 -0
  140. package/dist/llm/remote_chat_context.d.cts +23 -0
  141. package/dist/llm/remote_chat_context.d.ts +23 -0
  142. package/dist/llm/remote_chat_context.d.ts.map +1 -0
  143. package/dist/llm/remote_chat_context.js +88 -0
  144. package/dist/llm/remote_chat_context.js.map +1 -0
  145. package/dist/llm/remote_chat_context.test.cjs +225 -0
  146. package/dist/llm/remote_chat_context.test.cjs.map +1 -0
  147. package/dist/llm/remote_chat_context.test.js +224 -0
  148. package/dist/llm/remote_chat_context.test.js.map +1 -0
  149. package/dist/llm/tool_context.cjs +111 -0
  150. package/dist/llm/tool_context.cjs.map +1 -0
  151. package/dist/llm/tool_context.d.cts +125 -0
  152. package/dist/llm/tool_context.d.ts +125 -0
  153. package/dist/llm/tool_context.d.ts.map +1 -0
  154. package/dist/llm/tool_context.js +80 -0
  155. package/dist/llm/tool_context.js.map +1 -0
  156. package/dist/llm/tool_context.test.cjs +162 -0
  157. package/dist/llm/tool_context.test.cjs.map +1 -0
  158. package/dist/llm/tool_context.test.js +161 -0
  159. package/dist/llm/tool_context.test.js.map +1 -0
  160. package/dist/llm/tool_context.type.test.cjs +92 -0
  161. package/dist/llm/tool_context.type.test.cjs.map +1 -0
  162. package/dist/llm/tool_context.type.test.js +91 -0
  163. package/dist/llm/tool_context.type.test.js.map +1 -0
  164. package/dist/llm/utils.cjs +260 -0
  165. package/dist/llm/utils.cjs.map +1 -0
  166. package/dist/llm/utils.d.cts +42 -0
  167. package/dist/llm/utils.d.ts +42 -0
  168. package/dist/llm/utils.d.ts.map +1 -0
  169. package/dist/llm/utils.js +223 -0
  170. package/dist/llm/utils.js.map +1 -0
  171. package/dist/llm/utils.test.cjs +513 -0
  172. package/dist/llm/utils.test.cjs.map +1 -0
  173. package/dist/llm/utils.test.js +490 -0
  174. package/dist/llm/utils.test.js.map +1 -0
  175. package/dist/metrics/base.cjs +0 -27
  176. package/dist/metrics/base.cjs.map +1 -1
  177. package/dist/metrics/base.d.cts +105 -63
  178. package/dist/metrics/base.d.ts +105 -63
  179. package/dist/metrics/base.d.ts.map +1 -1
  180. package/dist/metrics/base.js +0 -19
  181. package/dist/metrics/base.js.map +1 -1
  182. package/dist/metrics/index.cjs +0 -3
  183. package/dist/metrics/index.cjs.map +1 -1
  184. package/dist/metrics/index.d.cts +2 -3
  185. package/dist/metrics/index.d.ts +2 -3
  186. package/dist/metrics/index.d.ts.map +1 -1
  187. package/dist/metrics/index.js +0 -2
  188. package/dist/metrics/index.js.map +1 -1
  189. package/dist/metrics/usage_collector.cjs +17 -12
  190. package/dist/metrics/usage_collector.cjs.map +1 -1
  191. package/dist/metrics/usage_collector.d.cts +3 -2
  192. package/dist/metrics/usage_collector.d.ts +3 -2
  193. package/dist/metrics/usage_collector.d.ts.map +1 -1
  194. package/dist/metrics/usage_collector.js +17 -12
  195. package/dist/metrics/usage_collector.js.map +1 -1
  196. package/dist/metrics/utils.cjs +22 -59
  197. package/dist/metrics/utils.cjs.map +1 -1
  198. package/dist/metrics/utils.d.cts +1 -8
  199. package/dist/metrics/utils.d.ts +1 -8
  200. package/dist/metrics/utils.d.ts.map +1 -1
  201. package/dist/metrics/utils.js +22 -52
  202. package/dist/metrics/utils.js.map +1 -1
  203. package/dist/multimodal/index.cjs +0 -2
  204. package/dist/multimodal/index.cjs.map +1 -1
  205. package/dist/multimodal/index.d.cts +0 -1
  206. package/dist/multimodal/index.d.ts +0 -1
  207. package/dist/multimodal/index.d.ts.map +1 -1
  208. package/dist/multimodal/index.js +0 -1
  209. package/dist/multimodal/index.js.map +1 -1
  210. package/dist/plugin.cjs +24 -8
  211. package/dist/plugin.cjs.map +1 -1
  212. package/dist/plugin.d.cts +18 -4
  213. package/dist/plugin.d.ts +18 -4
  214. package/dist/plugin.d.ts.map +1 -1
  215. package/dist/plugin.js +22 -7
  216. package/dist/plugin.js.map +1 -1
  217. package/dist/stream/deferred_stream.cjs +98 -0
  218. package/dist/stream/deferred_stream.cjs.map +1 -0
  219. package/dist/stream/deferred_stream.d.cts +27 -0
  220. package/dist/stream/deferred_stream.d.ts +27 -0
  221. package/dist/stream/deferred_stream.d.ts.map +1 -0
  222. package/dist/stream/deferred_stream.js +73 -0
  223. package/dist/stream/deferred_stream.js.map +1 -0
  224. package/dist/stream/deferred_stream.test.cjs +527 -0
  225. package/dist/stream/deferred_stream.test.cjs.map +1 -0
  226. package/dist/stream/deferred_stream.test.js +526 -0
  227. package/dist/stream/deferred_stream.test.js.map +1 -0
  228. package/dist/stream/identity_transform.cjs +42 -0
  229. package/dist/stream/identity_transform.cjs.map +1 -0
  230. package/dist/stream/identity_transform.d.cts +6 -0
  231. package/dist/stream/identity_transform.d.ts +6 -0
  232. package/dist/stream/identity_transform.d.ts.map +1 -0
  233. package/dist/stream/identity_transform.js +18 -0
  234. package/dist/stream/identity_transform.js.map +1 -0
  235. package/dist/stream/identity_transform.test.cjs +125 -0
  236. package/dist/stream/identity_transform.test.cjs.map +1 -0
  237. package/dist/stream/identity_transform.test.js +124 -0
  238. package/dist/stream/identity_transform.test.js.map +1 -0
  239. package/dist/stream/index.cjs +38 -0
  240. package/dist/stream/index.cjs.map +1 -0
  241. package/dist/stream/index.d.cts +5 -0
  242. package/dist/stream/index.d.ts +5 -0
  243. package/dist/stream/index.d.ts.map +1 -0
  244. package/dist/stream/index.js +11 -0
  245. package/dist/stream/index.js.map +1 -0
  246. package/dist/stream/merge_readable_streams.cjs +59 -0
  247. package/dist/stream/merge_readable_streams.cjs.map +1 -0
  248. package/dist/stream/merge_readable_streams.d.cts +4 -0
  249. package/dist/stream/merge_readable_streams.d.ts +4 -0
  250. package/dist/stream/merge_readable_streams.d.ts.map +1 -0
  251. package/dist/stream/merge_readable_streams.js +35 -0
  252. package/dist/stream/merge_readable_streams.js.map +1 -0
  253. package/dist/stream/stream_channel.cjs +47 -0
  254. package/dist/stream/stream_channel.cjs.map +1 -0
  255. package/dist/stream/stream_channel.d.cts +9 -0
  256. package/dist/stream/stream_channel.d.ts +9 -0
  257. package/dist/stream/stream_channel.d.ts.map +1 -0
  258. package/dist/stream/stream_channel.js +23 -0
  259. package/dist/stream/stream_channel.js.map +1 -0
  260. package/dist/stream/stream_channel.test.cjs +97 -0
  261. package/dist/stream/stream_channel.test.cjs.map +1 -0
  262. package/dist/stream/stream_channel.test.js +96 -0
  263. package/dist/stream/stream_channel.test.js.map +1 -0
  264. package/dist/stt/stream_adapter.cjs +3 -4
  265. package/dist/stt/stream_adapter.cjs.map +1 -1
  266. package/dist/stt/stream_adapter.d.cts +1 -0
  267. package/dist/stt/stream_adapter.d.ts +1 -0
  268. package/dist/stt/stream_adapter.d.ts.map +1 -1
  269. package/dist/stt/stream_adapter.js +3 -4
  270. package/dist/stt/stream_adapter.js.map +1 -1
  271. package/dist/stt/stt.cjs +101 -10
  272. package/dist/stt/stt.cjs.map +1 -1
  273. package/dist/stt/stt.d.cts +26 -5
  274. package/dist/stt/stt.d.ts +26 -5
  275. package/dist/stt/stt.d.ts.map +1 -1
  276. package/dist/stt/stt.js +102 -11
  277. package/dist/stt/stt.js.map +1 -1
  278. package/dist/tokenize/basic/basic.cjs +10 -5
  279. package/dist/tokenize/basic/basic.cjs.map +1 -1
  280. package/dist/tokenize/basic/basic.d.cts +7 -1
  281. package/dist/tokenize/basic/basic.d.ts +7 -1
  282. package/dist/tokenize/basic/basic.d.ts.map +1 -1
  283. package/dist/tokenize/basic/basic.js +10 -5
  284. package/dist/tokenize/basic/basic.js.map +1 -1
  285. package/dist/tokenize/basic/sentence.cjs +14 -6
  286. package/dist/tokenize/basic/sentence.cjs.map +1 -1
  287. package/dist/tokenize/basic/sentence.d.cts +1 -1
  288. package/dist/tokenize/basic/sentence.d.ts +1 -1
  289. package/dist/tokenize/basic/sentence.d.ts.map +1 -1
  290. package/dist/tokenize/basic/sentence.js +14 -6
  291. package/dist/tokenize/basic/sentence.js.map +1 -1
  292. package/dist/tokenize/token_stream.cjs +5 -3
  293. package/dist/tokenize/token_stream.cjs.map +1 -1
  294. package/dist/tokenize/token_stream.d.cts +1 -0
  295. package/dist/tokenize/token_stream.d.ts +1 -0
  296. package/dist/tokenize/token_stream.d.ts.map +1 -1
  297. package/dist/tokenize/token_stream.js +6 -4
  298. package/dist/tokenize/token_stream.js.map +1 -1
  299. package/dist/transcription.cjs +1 -2
  300. package/dist/transcription.cjs.map +1 -1
  301. package/dist/transcription.d.ts.map +1 -1
  302. package/dist/transcription.js +2 -3
  303. package/dist/transcription.js.map +1 -1
  304. package/dist/tts/index.cjs +2 -4
  305. package/dist/tts/index.cjs.map +1 -1
  306. package/dist/tts/index.d.cts +1 -1
  307. package/dist/tts/index.d.ts +1 -1
  308. package/dist/tts/index.d.ts.map +1 -1
  309. package/dist/tts/index.js +1 -3
  310. package/dist/tts/index.js.map +1 -1
  311. package/dist/tts/stream_adapter.cjs +26 -13
  312. package/dist/tts/stream_adapter.cjs.map +1 -1
  313. package/dist/tts/stream_adapter.d.cts +1 -1
  314. package/dist/tts/stream_adapter.d.ts +1 -1
  315. package/dist/tts/stream_adapter.d.ts.map +1 -1
  316. package/dist/tts/stream_adapter.js +27 -14
  317. package/dist/tts/stream_adapter.js.map +1 -1
  318. package/dist/tts/tts.cjs +157 -25
  319. package/dist/tts/tts.cjs.map +1 -1
  320. package/dist/tts/tts.d.cts +29 -5
  321. package/dist/tts/tts.d.ts +29 -5
  322. package/dist/tts/tts.d.ts.map +1 -1
  323. package/dist/tts/tts.js +157 -24
  324. package/dist/tts/tts.js.map +1 -1
  325. package/dist/types.cjs +60 -0
  326. package/dist/types.cjs.map +1 -0
  327. package/dist/types.d.cts +13 -0
  328. package/dist/types.d.ts +13 -0
  329. package/dist/types.d.ts.map +1 -0
  330. package/dist/types.js +35 -0
  331. package/dist/types.js.map +1 -0
  332. package/dist/utils.cjs +281 -27
  333. package/dist/utils.cjs.map +1 -1
  334. package/dist/utils.d.cts +134 -9
  335. package/dist/utils.d.ts +134 -9
  336. package/dist/utils.d.ts.map +1 -1
  337. package/dist/utils.js +265 -26
  338. package/dist/utils.js.map +1 -1
  339. package/dist/utils.test.cjs +492 -0
  340. package/dist/utils.test.cjs.map +1 -0
  341. package/dist/utils.test.js +498 -0
  342. package/dist/utils.test.js.map +1 -0
  343. package/dist/vad.cjs +76 -20
  344. package/dist/vad.cjs.map +1 -1
  345. package/dist/vad.d.cts +25 -5
  346. package/dist/vad.d.ts +25 -5
  347. package/dist/vad.d.ts.map +1 -1
  348. package/dist/vad.js +76 -20
  349. package/dist/vad.js.map +1 -1
  350. package/dist/voice/agent.cjs +245 -0
  351. package/dist/voice/agent.cjs.map +1 -0
  352. package/dist/voice/agent.d.cts +78 -0
  353. package/dist/voice/agent.d.ts +78 -0
  354. package/dist/voice/agent.d.ts.map +1 -0
  355. package/dist/voice/agent.js +220 -0
  356. package/dist/voice/agent.js.map +1 -0
  357. package/dist/voice/agent.test.cjs +61 -0
  358. package/dist/voice/agent.test.cjs.map +1 -0
  359. package/dist/voice/agent.test.js +60 -0
  360. package/dist/voice/agent.test.js.map +1 -0
  361. package/dist/voice/agent_activity.cjs +1453 -0
  362. package/dist/voice/agent_activity.cjs.map +1 -0
  363. package/dist/voice/agent_activity.d.cts +94 -0
  364. package/dist/voice/agent_activity.d.ts +94 -0
  365. package/dist/voice/agent_activity.d.ts.map +1 -0
  366. package/dist/voice/agent_activity.js +1449 -0
  367. package/dist/voice/agent_activity.js.map +1 -0
  368. package/dist/voice/agent_session.cjs +312 -0
  369. package/dist/voice/agent_session.cjs.map +1 -0
  370. package/dist/voice/agent_session.d.cts +121 -0
  371. package/dist/voice/agent_session.d.ts +121 -0
  372. package/dist/voice/agent_session.d.ts.map +1 -0
  373. package/dist/voice/agent_session.js +295 -0
  374. package/dist/voice/agent_session.js.map +1 -0
  375. package/dist/voice/audio_recognition.cjs +375 -0
  376. package/dist/voice/audio_recognition.cjs.map +1 -0
  377. package/dist/voice/audio_recognition.d.cts +80 -0
  378. package/dist/voice/audio_recognition.d.ts +80 -0
  379. package/dist/voice/audio_recognition.d.ts.map +1 -0
  380. package/dist/voice/audio_recognition.js +351 -0
  381. package/dist/voice/audio_recognition.js.map +1 -0
  382. package/dist/voice/events.cjs +145 -0
  383. package/dist/voice/events.cjs.map +1 -0
  384. package/dist/voice/events.d.cts +124 -0
  385. package/dist/voice/events.d.ts +124 -0
  386. package/dist/voice/events.d.ts.map +1 -0
  387. package/dist/voice/events.js +110 -0
  388. package/dist/voice/events.js.map +1 -0
  389. package/dist/voice/generation.cjs +700 -0
  390. package/dist/voice/generation.cjs.map +1 -0
  391. package/dist/voice/generation.d.cts +115 -0
  392. package/dist/voice/generation.d.ts +115 -0
  393. package/dist/voice/generation.d.ts.map +1 -0
  394. package/dist/voice/generation.js +672 -0
  395. package/dist/voice/generation.js.map +1 -0
  396. package/dist/voice/index.cjs +40 -0
  397. package/dist/voice/index.cjs.map +1 -0
  398. package/dist/voice/index.d.cts +5 -0
  399. package/dist/voice/index.d.ts +5 -0
  400. package/dist/voice/index.d.ts.map +1 -0
  401. package/dist/voice/index.js +11 -0
  402. package/dist/voice/index.js.map +1 -0
  403. package/dist/voice/io.cjs +245 -0
  404. package/dist/voice/io.cjs.map +1 -0
  405. package/dist/voice/io.d.cts +101 -0
  406. package/dist/voice/io.d.ts +101 -0
  407. package/dist/voice/io.d.ts.map +1 -0
  408. package/dist/voice/io.js +217 -0
  409. package/dist/voice/io.js.map +1 -0
  410. package/dist/voice/room_io/_input.cjs +121 -0
  411. package/dist/voice/room_io/_input.cjs.map +1 -0
  412. package/dist/voice/room_io/_input.d.cts +24 -0
  413. package/dist/voice/room_io/_input.d.ts +24 -0
  414. package/dist/voice/room_io/_input.d.ts.map +1 -0
  415. package/dist/voice/room_io/_input.js +102 -0
  416. package/dist/voice/room_io/_input.js.map +1 -0
  417. package/dist/voice/room_io/_output.cjs +358 -0
  418. package/dist/voice/room_io/_output.cjs.map +1 -0
  419. package/dist/voice/room_io/_output.d.cts +75 -0
  420. package/dist/voice/room_io/_output.d.ts +75 -0
  421. package/dist/voice/room_io/_output.d.ts.map +1 -0
  422. package/dist/voice/room_io/_output.js +342 -0
  423. package/dist/voice/room_io/_output.js.map +1 -0
  424. package/dist/voice/room_io/index.cjs +25 -0
  425. package/dist/voice/room_io/index.cjs.map +1 -0
  426. package/dist/voice/room_io/index.d.cts +3 -0
  427. package/dist/voice/room_io/index.d.ts +3 -0
  428. package/dist/voice/room_io/index.d.ts.map +1 -0
  429. package/dist/voice/room_io/index.js +3 -0
  430. package/dist/voice/room_io/index.js.map +1 -0
  431. package/dist/voice/room_io/room_io.cjs +370 -0
  432. package/dist/voice/room_io/room_io.cjs.map +1 -0
  433. package/dist/voice/room_io/room_io.d.cts +73 -0
  434. package/dist/voice/room_io/room_io.d.ts +73 -0
  435. package/dist/voice/room_io/room_io.d.ts.map +1 -0
  436. package/dist/voice/room_io/room_io.js +361 -0
  437. package/dist/voice/room_io/room_io.js.map +1 -0
  438. package/dist/{pipeline/index.cjs → voice/run_context.cjs} +16 -11
  439. package/dist/voice/run_context.cjs.map +1 -0
  440. package/dist/voice/run_context.d.cts +12 -0
  441. package/dist/voice/run_context.d.ts +12 -0
  442. package/dist/voice/run_context.d.ts.map +1 -0
  443. package/dist/voice/run_context.js +14 -0
  444. package/dist/voice/run_context.js.map +1 -0
  445. package/dist/voice/speech_handle.cjs +105 -0
  446. package/dist/voice/speech_handle.cjs.map +1 -0
  447. package/dist/voice/speech_handle.d.cts +46 -0
  448. package/dist/voice/speech_handle.d.ts +46 -0
  449. package/dist/voice/speech_handle.d.ts.map +1 -0
  450. package/dist/voice/speech_handle.js +81 -0
  451. package/dist/voice/speech_handle.js.map +1 -0
  452. package/dist/voice/transcription/_utils.cjs +45 -0
  453. package/dist/voice/transcription/_utils.cjs.map +1 -0
  454. package/dist/voice/transcription/_utils.d.cts +3 -0
  455. package/dist/voice/transcription/_utils.d.ts +3 -0
  456. package/dist/voice/transcription/_utils.d.ts.map +1 -0
  457. package/dist/voice/transcription/_utils.js +21 -0
  458. package/dist/voice/transcription/_utils.js.map +1 -0
  459. package/dist/voice/transcription/index.cjs +23 -0
  460. package/dist/voice/transcription/index.cjs.map +1 -0
  461. package/dist/voice/transcription/index.d.cts +2 -0
  462. package/dist/voice/transcription/index.d.ts +2 -0
  463. package/dist/voice/transcription/index.d.ts.map +1 -0
  464. package/dist/voice/transcription/index.js +2 -0
  465. package/dist/voice/transcription/index.js.map +1 -0
  466. package/dist/voice/transcription/synchronizer.cjs +380 -0
  467. package/dist/voice/transcription/synchronizer.cjs.map +1 -0
  468. package/dist/voice/transcription/synchronizer.d.cts +86 -0
  469. package/dist/voice/transcription/synchronizer.d.ts +86 -0
  470. package/dist/voice/transcription/synchronizer.d.ts.map +1 -0
  471. package/dist/voice/transcription/synchronizer.js +355 -0
  472. package/dist/voice/transcription/synchronizer.js.map +1 -0
  473. package/dist/worker.cjs +22 -4
  474. package/dist/worker.cjs.map +1 -1
  475. package/dist/worker.d.cts +1 -1
  476. package/dist/worker.d.ts +1 -1
  477. package/dist/worker.d.ts.map +1 -1
  478. package/dist/worker.js +22 -4
  479. package/dist/worker.js.map +1 -1
  480. package/package.json +9 -2
  481. package/src/_exceptions.ts +137 -0
  482. package/src/audio.ts +12 -1
  483. package/src/cli.ts +37 -0
  484. package/src/constants.ts +2 -1
  485. package/src/http_server.ts +1 -0
  486. package/src/index.ts +13 -10
  487. package/src/inference_runner.ts +2 -3
  488. package/src/ipc/inference_proc_executor.ts +2 -2
  489. package/src/ipc/job_executor.ts +1 -1
  490. package/src/ipc/job_proc_executor.ts +1 -1
  491. package/src/ipc/job_proc_lazy_main.ts +1 -1
  492. package/src/job.ts +18 -0
  493. package/src/llm/__snapshots__/chat_context.test.ts.snap +527 -0
  494. package/src/llm/__snapshots__/tool_context.test.ts.snap +177 -0
  495. package/src/llm/__snapshots__/utils.test.ts.snap +65 -0
  496. package/src/llm/chat_context.test.ts +450 -0
  497. package/src/llm/chat_context.ts +501 -103
  498. package/src/llm/index.ts +53 -18
  499. package/src/llm/llm.ts +149 -50
  500. package/src/llm/provider_format/google.test.ts +772 -0
  501. package/src/llm/provider_format/google.ts +130 -0
  502. package/src/llm/provider_format/index.ts +23 -0
  503. package/src/llm/provider_format/openai.test.ts +581 -0
  504. package/src/llm/provider_format/openai.ts +118 -0
  505. package/src/llm/provider_format/utils.ts +183 -0
  506. package/src/llm/realtime.ts +151 -0
  507. package/src/llm/remote_chat_context.test.ts +290 -0
  508. package/src/llm/remote_chat_context.ts +114 -0
  509. package/src/llm/tool_context.test.ts +198 -0
  510. package/src/llm/tool_context.ts +259 -0
  511. package/src/llm/tool_context.type.test.ts +115 -0
  512. package/src/llm/utils.test.ts +670 -0
  513. package/src/llm/utils.ts +324 -0
  514. package/src/metrics/base.ts +110 -78
  515. package/src/metrics/index.ts +3 -9
  516. package/src/metrics/usage_collector.ts +19 -13
  517. package/src/metrics/utils.ts +24 -69
  518. package/src/multimodal/index.ts +0 -1
  519. package/src/plugin.ts +26 -8
  520. package/src/stream/deferred_stream.test.ts +755 -0
  521. package/src/stream/deferred_stream.ts +110 -0
  522. package/src/stream/identity_transform.test.ts +179 -0
  523. package/src/stream/identity_transform.ts +18 -0
  524. package/src/stream/index.ts +7 -0
  525. package/src/stream/merge_readable_streams.ts +40 -0
  526. package/src/stream/stream_channel.test.ts +129 -0
  527. package/src/stream/stream_channel.ts +32 -0
  528. package/src/stt/stream_adapter.ts +3 -5
  529. package/src/stt/stt.ts +135 -17
  530. package/src/tokenize/basic/basic.ts +13 -5
  531. package/src/tokenize/basic/sentence.ts +20 -6
  532. package/src/tokenize/token_stream.ts +7 -4
  533. package/src/transcription.ts +2 -3
  534. package/src/tts/index.ts +0 -1
  535. package/src/tts/stream_adapter.ts +42 -16
  536. package/src/tts/tts.ts +203 -21
  537. package/src/types.ts +42 -0
  538. package/src/utils.test.ts +658 -0
  539. package/src/utils.ts +375 -44
  540. package/src/vad.ts +90 -22
  541. package/src/voice/agent.test.ts +80 -0
  542. package/src/voice/agent.ts +332 -0
  543. package/src/voice/agent_activity.ts +1913 -0
  544. package/src/voice/agent_session.ts +460 -0
  545. package/src/voice/audio_recognition.ts +474 -0
  546. package/src/voice/events.ts +252 -0
  547. package/src/voice/generation.ts +881 -0
  548. package/src/voice/index.ts +7 -0
  549. package/src/voice/io.ts +304 -0
  550. package/src/voice/room_io/_input.ts +144 -0
  551. package/src/voice/room_io/_output.ts +436 -0
  552. package/src/voice/room_io/index.ts +5 -0
  553. package/src/voice/room_io/room_io.ts +495 -0
  554. package/src/voice/run_context.ts +20 -0
  555. package/src/voice/speech_handle.ts +104 -0
  556. package/src/voice/transcription/_utils.ts +25 -0
  557. package/src/voice/transcription/index.ts +4 -0
  558. package/src/voice/transcription/synchronizer.ts +478 -0
  559. package/src/worker.ts +22 -2
  560. package/dist/llm/function_context.cjs +0 -103
  561. package/dist/llm/function_context.cjs.map +0 -1
  562. package/dist/llm/function_context.d.cts +0 -47
  563. package/dist/llm/function_context.d.ts +0 -47
  564. package/dist/llm/function_context.d.ts.map +0 -1
  565. package/dist/llm/function_context.js +0 -78
  566. package/dist/llm/function_context.js.map +0 -1
  567. package/dist/llm/function_context.test.cjs +0 -218
  568. package/dist/llm/function_context.test.cjs.map +0 -1
  569. package/dist/llm/function_context.test.js +0 -217
  570. package/dist/llm/function_context.test.js.map +0 -1
  571. package/dist/multimodal/multimodal_agent.cjs +0 -486
  572. package/dist/multimodal/multimodal_agent.cjs.map +0 -1
  573. package/dist/multimodal/multimodal_agent.d.cts +0 -48
  574. package/dist/multimodal/multimodal_agent.d.ts +0 -48
  575. package/dist/multimodal/multimodal_agent.d.ts.map +0 -1
  576. package/dist/multimodal/multimodal_agent.js +0 -461
  577. package/dist/multimodal/multimodal_agent.js.map +0 -1
  578. package/dist/pipeline/agent_output.cjs +0 -197
  579. package/dist/pipeline/agent_output.cjs.map +0 -1
  580. package/dist/pipeline/agent_output.d.cts +0 -33
  581. package/dist/pipeline/agent_output.d.ts +0 -33
  582. package/dist/pipeline/agent_output.d.ts.map +0 -1
  583. package/dist/pipeline/agent_output.js +0 -172
  584. package/dist/pipeline/agent_output.js.map +0 -1
  585. package/dist/pipeline/agent_playout.cjs +0 -175
  586. package/dist/pipeline/agent_playout.cjs.map +0 -1
  587. package/dist/pipeline/agent_playout.d.cts +0 -40
  588. package/dist/pipeline/agent_playout.d.ts +0 -40
  589. package/dist/pipeline/agent_playout.d.ts.map +0 -1
  590. package/dist/pipeline/agent_playout.js +0 -139
  591. package/dist/pipeline/agent_playout.js.map +0 -1
  592. package/dist/pipeline/human_input.cjs +0 -171
  593. package/dist/pipeline/human_input.cjs.map +0 -1
  594. package/dist/pipeline/human_input.d.cts +0 -30
  595. package/dist/pipeline/human_input.d.ts +0 -30
  596. package/dist/pipeline/human_input.d.ts.map +0 -1
  597. package/dist/pipeline/human_input.js +0 -146
  598. package/dist/pipeline/human_input.js.map +0 -1
  599. package/dist/pipeline/index.cjs.map +0 -1
  600. package/dist/pipeline/index.d.cts +0 -2
  601. package/dist/pipeline/index.d.ts +0 -2
  602. package/dist/pipeline/index.d.ts.map +0 -1
  603. package/dist/pipeline/index.js +0 -11
  604. package/dist/pipeline/index.js.map +0 -1
  605. package/dist/pipeline/pipeline_agent.cjs +0 -859
  606. package/dist/pipeline/pipeline_agent.cjs.map +0 -1
  607. package/dist/pipeline/pipeline_agent.d.cts +0 -150
  608. package/dist/pipeline/pipeline_agent.d.ts +0 -150
  609. package/dist/pipeline/pipeline_agent.d.ts.map +0 -1
  610. package/dist/pipeline/pipeline_agent.js +0 -837
  611. package/dist/pipeline/pipeline_agent.js.map +0 -1
  612. package/dist/pipeline/speech_handle.cjs +0 -176
  613. package/dist/pipeline/speech_handle.cjs.map +0 -1
  614. package/dist/pipeline/speech_handle.d.cts +0 -37
  615. package/dist/pipeline/speech_handle.d.ts +0 -37
  616. package/dist/pipeline/speech_handle.d.ts.map +0 -1
  617. package/dist/pipeline/speech_handle.js +0 -152
  618. package/dist/pipeline/speech_handle.js.map +0 -1
  619. package/src/llm/function_context.test.ts +0 -248
  620. package/src/llm/function_context.ts +0 -142
  621. package/src/multimodal/multimodal_agent.ts +0 -592
  622. package/src/pipeline/agent_output.ts +0 -219
  623. package/src/pipeline/agent_playout.ts +0 -192
  624. package/src/pipeline/human_input.ts +0 -188
  625. package/src/pipeline/index.ts +0 -15
  626. package/src/pipeline/pipeline_agent.ts +0 -1197
  627. package/src/pipeline/speech_handle.ts +0 -201
@@ -0,0 +1,478 @@
1
+ // SPDX-FileCopyrightText: 2025 LiveKit, Inc.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ import type { AudioFrame } from '@livekit/rtc-node';
5
+ import { delay } from '@std/async';
6
+ import type { ReadableStream, WritableStreamDefaultWriter } from 'node:stream/web';
7
+ import { log } from '../../log.js';
8
+ import { IdentityTransform } from '../../stream/identity_transform.js';
9
+ import type { SentenceStream, SentenceTokenizer } from '../../tokenize/index.js';
10
+ import { basic } from '../../tokenize/index.js';
11
+ import { Future, Task } from '../../utils.js';
12
+ import { AudioOutput, type PlaybackFinishedEvent, TextOutput } from '../io.js';
13
+
14
+ const STANDARD_SPEECH_RATE = 3.83; // hyphens (syllables) per second
15
+
16
+ interface TextSyncOptions {
17
+ speed: number;
18
+ hyphenateWord: (word: string) => string[];
19
+ splitWords: (words: string) => [string, number, number][];
20
+ sentenceTokenizer: SentenceTokenizer;
21
+ }
22
+
23
+ interface TextData {
24
+ sentenceStream: SentenceStream;
25
+ pushedText: string;
26
+ done: boolean;
27
+ forwardedHyphens: number;
28
+ forwardedText: string;
29
+ }
30
+
31
+ interface AudioData {
32
+ pushedDuration: number;
33
+ done: boolean;
34
+ }
35
+
36
+ class SegmentSynchronizerImpl {
37
+ private textData: TextData;
38
+ private audioData: AudioData;
39
+ private speed: number;
40
+ private outputStream: IdentityTransform<string>;
41
+ private outputStreamWriter: WritableStreamDefaultWriter<string>;
42
+ private captureTask: Promise<void>;
43
+ private startWallTime?: number;
44
+
45
+ private startFuture: Future = new Future();
46
+ private closedFuture: Future = new Future();
47
+ private playbackCompleted: boolean = false;
48
+
49
+ private logger = log();
50
+
51
+ constructor(
52
+ private readonly options: TextSyncOptions,
53
+ private readonly nextInChain: TextOutput,
54
+ ) {
55
+ this.speed = options.speed * STANDARD_SPEECH_RATE; // hyphens per second
56
+ this.textData = {
57
+ sentenceStream: options.sentenceTokenizer.stream(),
58
+ pushedText: '',
59
+ done: false,
60
+ forwardedHyphens: 0,
61
+ forwardedText: '',
62
+ };
63
+ this.audioData = {
64
+ pushedDuration: 0,
65
+ done: false,
66
+ };
67
+ this.outputStream = new IdentityTransform();
68
+ this.outputStreamWriter = this.outputStream.writable.getWriter();
69
+
70
+ this.mainTask()
71
+ .then(() => {
72
+ this.outputStreamWriter.close();
73
+ })
74
+ .catch((error) => {
75
+ this.logger.error({ error }, 'mainTask SegmentSynchronizerImpl');
76
+ });
77
+ this.captureTask = this.captureTaskImpl();
78
+ }
79
+
80
+ get closed() {
81
+ return this.closedFuture.done;
82
+ }
83
+
84
+ get audioInputEnded() {
85
+ return this.audioData.done;
86
+ }
87
+
88
+ get textInputEnded() {
89
+ return this.textData.done;
90
+ }
91
+
92
+ get readable(): ReadableStream<string> {
93
+ return this.outputStream.readable;
94
+ }
95
+
96
+ pushAudio(frame: AudioFrame) {
97
+ if (this.closed) {
98
+ this.logger.warn('SegmentSynchronizerImpl.pushAudio called after close');
99
+ return;
100
+ }
101
+ // TODO(AJS-102): use frame.durationMs once available in rtc-node
102
+ const frameDuration = frame.samplesPerChannel / frame.sampleRate;
103
+
104
+ if (!this.startWallTime && frameDuration > 0) {
105
+ this.startWallTime = Date.now();
106
+ this.startFuture.resolve();
107
+ }
108
+
109
+ this.audioData.pushedDuration += frameDuration;
110
+ }
111
+
112
+ endAudioInput() {
113
+ if (this.closed) {
114
+ this.logger.warn('SegmentSynchronizerImpl.endAudioInput called after close');
115
+ return;
116
+ }
117
+
118
+ this.audioData.done = true;
119
+ }
120
+
121
+ pushText(text: string) {
122
+ if (this.closed) {
123
+ this.logger.warn('SegmentSynchronizerImpl.pushText called after close');
124
+ return;
125
+ }
126
+
127
+ this.textData.sentenceStream.pushText(text);
128
+ this.textData.pushedText += text;
129
+ }
130
+
131
+ endTextInput() {
132
+ if (this.closed) {
133
+ this.logger.warn('SegmentSynchronizerImpl.endTextInput called after close');
134
+ return;
135
+ }
136
+
137
+ this.textData.done = true;
138
+ this.textData.sentenceStream.endInput();
139
+ }
140
+
141
+ markPlaybackFinished(_playbackPosition: number, interrupted: boolean) {
142
+ if (this.closed) {
143
+ this.logger.warn('SegmentSynchronizerImpl.markPlaybackFinished called after close');
144
+ return;
145
+ }
146
+
147
+ if (!this.textData.done || !this.audioData.done) {
148
+ this.logger.warn(
149
+ { textDone: this.textData.done, audioDone: this.audioData.done },
150
+ 'SegmentSynchronizerImpl.markPlaybackFinished called before text/audio input is done',
151
+ );
152
+ return;
153
+ }
154
+
155
+ if (!interrupted) {
156
+ this.playbackCompleted = true;
157
+ }
158
+ }
159
+
160
+ get synchronizedTranscript(): string {
161
+ if (this.playbackCompleted) {
162
+ return this.textData.pushedText;
163
+ }
164
+ return this.textData.forwardedText;
165
+ }
166
+
167
+ private async captureTaskImpl() {
168
+ // Don't use a for-await loop here, because exiting the loop will close the writer in the
169
+ // outputStream, which will cause an error in the mainTask.then method.
170
+ const reader = this.outputStream.readable.getReader();
171
+ while (true) {
172
+ const { done, value: text } = await reader.read();
173
+ if (done) {
174
+ break;
175
+ }
176
+ this.textData.forwardedText += text;
177
+ await this.nextInChain.captureText(text);
178
+ }
179
+ reader.releaseLock();
180
+ this.nextInChain.flush();
181
+ }
182
+
183
+ private async mainTask(): Promise<void> {
184
+ await this.startFuture.await;
185
+
186
+ if (this.closed && !this.playbackCompleted) {
187
+ return;
188
+ }
189
+
190
+ if (!this.startWallTime) {
191
+ throw new Error('startWallTime is not set when starting SegmentSynchronizerImpl.mainTask');
192
+ }
193
+
194
+ for await (const textSegment of this.textData.sentenceStream) {
195
+ const sentence = textSegment.token;
196
+
197
+ let textCursor = 0;
198
+ if (this.closed && !this.playbackCompleted) {
199
+ return;
200
+ }
201
+
202
+ for (const [word, _, endPos] of this.options.splitWords(sentence)) {
203
+ if (this.closed && !this.playbackCompleted) {
204
+ return;
205
+ }
206
+
207
+ if (this.playbackCompleted) {
208
+ this.outputStreamWriter.write(sentence.slice(textCursor, endPos));
209
+ textCursor = endPos;
210
+ continue;
211
+ }
212
+
213
+ const wordHphens = this.options.hyphenateWord(word).length;
214
+ const elapsedSeconds = (Date.now() - this.startWallTime) / 1000;
215
+ const targetHyphens = elapsedSeconds * this.options.speed;
216
+ const hyphensBehind = Math.max(0, targetHyphens - this.textData.forwardedHyphens);
217
+ let delay = Math.max(0, wordHphens - hyphensBehind) / this.speed;
218
+
219
+ if (this.playbackCompleted) {
220
+ delay = 0;
221
+ }
222
+
223
+ await this.sleepIfNotClosed(delay / 2);
224
+ this.outputStreamWriter.write(sentence.slice(textCursor, endPos));
225
+ await this.sleepIfNotClosed(delay / 2);
226
+
227
+ this.textData.forwardedHyphens += wordHphens;
228
+ textCursor = endPos;
229
+ }
230
+
231
+ if (textCursor < sentence.length) {
232
+ const remaining = sentence.slice(textCursor);
233
+ this.outputStreamWriter.write(remaining);
234
+ }
235
+ }
236
+ }
237
+
238
+ private async sleepIfNotClosed(sleepTimeSeconds: number) {
239
+ if (this.closed) {
240
+ return;
241
+ }
242
+ await delay(sleepTimeSeconds * 1000);
243
+ }
244
+
245
+ async close(): Promise<void> {
246
+ if (this.closed) {
247
+ return;
248
+ }
249
+ this.closedFuture.resolve();
250
+ this.startFuture.resolve(); // avoid deadlock of mainTaskImpl in case it never started
251
+ this.textData.sentenceStream.close();
252
+ await this.captureTask;
253
+ }
254
+ }
255
+
256
+ export interface TranscriptionSynchronizerOptions {
257
+ speed: number;
258
+ hyphenateWord: (word: string) => string[];
259
+ splitWords: (words: string) => [string, number, number][];
260
+ sentenceTokenizer: SentenceTokenizer;
261
+ }
262
+
263
+ export const defaultTextSyncOptions: TranscriptionSynchronizerOptions = {
264
+ speed: 1,
265
+ hyphenateWord: basic.hyphenateWord,
266
+ splitWords: basic.splitWords,
267
+ sentenceTokenizer: new basic.SentenceTokenizer({
268
+ retainFormat: true,
269
+ }),
270
+ };
271
+
272
+ export class TranscriptionSynchronizer {
273
+ readonly audioOutput: SyncedAudioOutput;
274
+ readonly textOutput: SyncedTextOutput;
275
+
276
+ private options: TextSyncOptions;
277
+ private rotateSegmentTask: Task<void>;
278
+ private _enabled: boolean = true;
279
+ private closed: boolean = false;
280
+
281
+ /* @internal */
282
+ _impl: SegmentSynchronizerImpl;
283
+
284
+ private logger = log();
285
+
286
+ constructor(
287
+ nextInChainAudio: AudioOutput,
288
+ nextInChainText: TextOutput,
289
+ options: TranscriptionSynchronizerOptions = defaultTextSyncOptions,
290
+ ) {
291
+ this.audioOutput = new SyncedAudioOutput(this, nextInChainAudio);
292
+ this.textOutput = new SyncedTextOutput(this, nextInChainText);
293
+ this.options = {
294
+ speed: options.speed,
295
+ hyphenateWord: options.hyphenateWord,
296
+ splitWords: options.splitWords,
297
+ sentenceTokenizer: options.sentenceTokenizer,
298
+ };
299
+
300
+ // initial segment/first segment, recreated for each new segment
301
+ this._impl = new SegmentSynchronizerImpl(this.options, nextInChainText);
302
+ this.rotateSegmentTask = Task.from((controller) =>
303
+ this.rotateSegmentTaskImpl(controller.signal),
304
+ );
305
+ }
306
+
307
+ get enabled(): boolean {
308
+ return this._enabled;
309
+ }
310
+
311
+ set enabled(enabled: boolean) {
312
+ if (this._enabled === enabled) {
313
+ return;
314
+ }
315
+
316
+ this._enabled = enabled;
317
+ this.rotateSegment();
318
+ }
319
+
320
+ rotateSegment() {
321
+ if (this.closed) {
322
+ return;
323
+ }
324
+
325
+ if (!this.rotateSegmentTask.done) {
326
+ this.logger.warn('rotateSegment called while previous segment is still being rotated');
327
+ }
328
+ this.rotateSegmentTask = Task.from((controller) =>
329
+ this.rotateSegmentTaskImpl(controller.signal, this.rotateSegmentTask),
330
+ );
331
+ }
332
+
333
+ async close(): Promise<void> {
334
+ this.closed = true;
335
+ await this.rotateSegmentTask.cancelAndWait();
336
+ await this._impl.close();
337
+ }
338
+
339
+ async barrier(): Promise<void> {
340
+ if (this.rotateSegmentTask.done) {
341
+ return;
342
+ }
343
+ await this.rotateSegmentTask.result;
344
+ }
345
+
346
+ private async rotateSegmentTaskImpl(abort: AbortSignal, oldTask?: Task<void>) {
347
+ if (oldTask) {
348
+ await oldTask.result;
349
+ }
350
+
351
+ if (abort.aborted) {
352
+ return;
353
+ }
354
+ await this._impl.close();
355
+ this._impl = new SegmentSynchronizerImpl(this.options, this.textOutput.nextInChain);
356
+ }
357
+ }
358
+
359
+ class SyncedAudioOutput extends AudioOutput {
360
+ private pushedDuration: number = 0.0;
361
+
362
+ constructor(
363
+ public synchronizer: TranscriptionSynchronizer,
364
+ private nextInChainAudio: AudioOutput,
365
+ ) {
366
+ super(nextInChainAudio.sampleRate, nextInChainAudio);
367
+ }
368
+
369
+ async captureFrame(frame: AudioFrame): Promise<void> {
370
+ // using barrier() on capture should be sufficient, flush() must not be called if
371
+ // capture_frame isn't completed
372
+ await this.synchronizer.barrier();
373
+
374
+ await super.captureFrame(frame);
375
+ await this.nextInChainAudio.captureFrame(frame); // passthrough audio
376
+
377
+ // TODO(AJS-102): use frame.durationMs once available in rtc-node
378
+ this.pushedDuration += frame.samplesPerChannel / frame.sampleRate;
379
+
380
+ if (!this.synchronizer.enabled) {
381
+ return;
382
+ }
383
+
384
+ if (this.synchronizer._impl.audioInputEnded) {
385
+ this.logger.warn(
386
+ 'SegmentSynchronizerImpl audio marked as ended in capture audio, rotating segment',
387
+ );
388
+ this.synchronizer.rotateSegment();
389
+ await this.synchronizer.barrier();
390
+ }
391
+ this.synchronizer._impl.pushAudio(frame);
392
+ }
393
+
394
+ flush() {
395
+ super.flush();
396
+ this.nextInChainAudio.flush();
397
+
398
+ if (!this.synchronizer.enabled) {
399
+ return;
400
+ }
401
+
402
+ if (!this.pushedDuration) {
403
+ // in case there is no audio after the text was pushed, rotate the segment
404
+ this.synchronizer.rotateSegment();
405
+ return;
406
+ }
407
+
408
+ this.synchronizer._impl.endAudioInput();
409
+ }
410
+
411
+ clearBuffer() {
412
+ this.nextInChainAudio.clearBuffer();
413
+ }
414
+
415
+ // this is going to be automatically called by the next_in_chain
416
+ onPlaybackFinished(ev: PlaybackFinishedEvent) {
417
+ if (!this.synchronizer.enabled) {
418
+ super.onPlaybackFinished(ev);
419
+ return;
420
+ }
421
+
422
+ this.synchronizer._impl.markPlaybackFinished(ev.playbackPosition, ev.interrupted);
423
+ super.onPlaybackFinished({
424
+ playbackPosition: ev.playbackPosition,
425
+ interrupted: ev.interrupted,
426
+ synchronizedTranscript: this.synchronizer._impl.synchronizedTranscript,
427
+ });
428
+
429
+ this.synchronizer.rotateSegment();
430
+ this.pushedDuration = 0.0;
431
+ }
432
+ }
433
+
434
+ class SyncedTextOutput extends TextOutput {
435
+ private capturing: boolean = false;
436
+ private logger = log();
437
+
438
+ constructor(
439
+ private readonly synchronizer: TranscriptionSynchronizer,
440
+ public readonly nextInChain: TextOutput,
441
+ ) {
442
+ super(nextInChain);
443
+ }
444
+
445
+ async captureText(text: string): Promise<void> {
446
+ await this.synchronizer.barrier();
447
+
448
+ if (!this.synchronizer.enabled) {
449
+ // pass through to the next in chain
450
+ await this.nextInChain.captureText(text);
451
+ return;
452
+ }
453
+
454
+ this.capturing = true;
455
+ if (this.synchronizer._impl.textInputEnded) {
456
+ this.logger.warn(
457
+ 'SegmentSynchronizerImpl text marked as ended in capture text, rotating segment',
458
+ );
459
+ this.synchronizer.rotateSegment();
460
+ await this.synchronizer.barrier();
461
+ }
462
+ this.synchronizer._impl.pushText(text);
463
+ }
464
+
465
+ flush() {
466
+ if (!this.synchronizer.enabled) {
467
+ this.nextInChain.flush(); // passthrough text if the synchronizer is disabled
468
+ return;
469
+ }
470
+
471
+ if (!this.capturing) {
472
+ return;
473
+ }
474
+
475
+ this.capturing = false;
476
+ this.synchronizer._impl.endTextInput();
477
+ }
478
+ }
package/src/worker.ts CHANGED
@@ -32,11 +32,12 @@ import { version } from './version.js';
32
32
  const MAX_RECONNECT_ATTEMPTS = 10;
33
33
  const ASSIGNMENT_TIMEOUT = 7.5 * 1000;
34
34
  const UPDATE_LOAD_INTERVAL = 2.5 * 1000;
35
+ const PROJECT_TYPE = 'nodejs';
35
36
 
36
37
  class Default {
37
38
  static loadThreshold(production: boolean): number {
38
39
  if (production) {
39
- return 0.65;
40
+ return 0.7;
40
41
  } else {
41
42
  return Infinity;
42
43
  }
@@ -44,6 +45,7 @@ class Default {
44
45
 
45
46
  static numIdleProcesses(production: boolean): number {
46
47
  if (production) {
48
+ // TODO: use number of cores
47
49
  return 3;
48
50
  } else {
49
51
  return 0;
@@ -165,7 +167,7 @@ export class WorkerOptions {
165
167
  jobMemoryWarnMB: number;
166
168
  jobMemoryLimitMB: number;
167
169
 
168
- /** @param options */
170
+ /** @param options - Worker options */
169
171
  constructor({
170
172
  agent,
171
173
  requestFunc = defaultRequestFunc,
@@ -299,6 +301,22 @@ export class Worker {
299
301
  'API Secret is required: Set LIVEKIT_API_SECRET, run with --api-secret, or pass apiSecret in WorkerOptions',
300
302
  );
301
303
 
304
+ if (opts.workerToken) {
305
+ if (opts.loadFunc !== defaultCpuLoad) {
306
+ this.#logger.warn(
307
+ 'custom loadFunc is not supported when deploying to Cloud, using defaults',
308
+ );
309
+ opts.loadFunc = defaultCpuLoad;
310
+ }
311
+ const loadThreshold = Default.loadThreshold(opts.production);
312
+ if (opts.loadThreshold !== loadThreshold) {
313
+ this.#logger.warn(
314
+ 'custom loadThreshold is not supported when deploying to Cloud, using defaults',
315
+ );
316
+ opts.loadThreshold = loadThreshold;
317
+ }
318
+ }
319
+
302
320
  if (Object.entries(InferenceRunner.registeredRunners).length) {
303
321
  this.#inferenceExecutor = new InferenceProcExecutor({
304
322
  runners: InferenceRunner.registeredRunners,
@@ -328,6 +346,7 @@ export class Worker {
328
346
  worker_type: JobType[opts.workerType],
329
347
  active_jobs: this.activeJobs.length,
330
348
  sdk_version: version,
349
+ project_type: PROJECT_TYPE,
331
350
  }));
332
351
  }
333
352
 
@@ -685,6 +704,7 @@ export class Worker {
685
704
  job: msg.job!,
686
705
  url: asgn.url || this.#opts.wsURL,
687
706
  token: asgn.token,
707
+ workerId: this.id,
688
708
  });
689
709
  } else {
690
710
  this.#logger.child({ requestId: req.id }).warn('pending assignment not found');
@@ -1,103 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var function_context_exports = {};
20
- __export(function_context_exports, {
21
- oaiBuildFunctionInfo: () => oaiBuildFunctionInfo,
22
- oaiParams: () => oaiParams
23
- });
24
- module.exports = __toCommonJS(function_context_exports);
25
- var import_zod = require("zod");
26
- const looksLikeInstanceof = (value, target) => {
27
- let current = value == null ? void 0 : value.constructor;
28
- do {
29
- if ((current == null ? void 0 : current.name) === target.name) return true;
30
- current = Object.getPrototypeOf(current);
31
- } while (current == null ? void 0 : current.name);
32
- return false;
33
- };
34
- const oaiParams = (p) => {
35
- const properties = {};
36
- const requiredProperties = [];
37
- const processZodType = (field) => {
38
- const isOptional = field instanceof import_zod.z.ZodOptional;
39
- const nestedField = isOptional ? field._def.innerType : field;
40
- const description = field._def.description;
41
- if (looksLikeInstanceof(nestedField, import_zod.z.ZodEnum)) {
42
- return {
43
- type: typeof nestedField._def.values[0],
44
- ...description && { description },
45
- enum: nestedField._def.values
46
- };
47
- } else if (looksLikeInstanceof(nestedField, import_zod.z.ZodArray)) {
48
- const elementType = nestedField._def.type;
49
- return {
50
- type: "array",
51
- ...description && { description },
52
- items: processZodType(elementType)
53
- };
54
- } else if (looksLikeInstanceof(nestedField, import_zod.z.ZodObject)) {
55
- const { properties: properties2, required } = oaiParams(nestedField);
56
- return {
57
- type: "object",
58
- ...description && { description },
59
- properties: properties2,
60
- required
61
- };
62
- } else {
63
- let type2 = nestedField._def.typeName.toLowerCase();
64
- type2 = type2.includes("zod") ? type2.substring(3) : type2;
65
- return {
66
- type: type2,
67
- ...description && { description }
68
- };
69
- }
70
- };
71
- for (const key in p.shape) {
72
- const field = p.shape[key];
73
- properties[key] = processZodType(field);
74
- if (!(field instanceof import_zod.z.ZodOptional)) {
75
- requiredProperties.push(key);
76
- }
77
- }
78
- const type = "object";
79
- return {
80
- type,
81
- properties,
82
- required: requiredProperties
83
- };
84
- };
85
- const oaiBuildFunctionInfo = (fncCtx, toolCallId, fncName, rawArgs) => {
86
- const func = fncCtx[fncName];
87
- if (!func) {
88
- throw new Error(`AI function ${fncName} not found`);
89
- }
90
- return {
91
- name: fncName,
92
- func,
93
- toolCallId,
94
- rawParams: rawArgs,
95
- params: JSON.parse(rawArgs)
96
- };
97
- };
98
- // Annotate the CommonJS export names for ESM import in node:
99
- 0 && (module.exports = {
100
- oaiBuildFunctionInfo,
101
- oaiParams
102
- });
103
- //# sourceMappingURL=function_context.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/llm/function_context.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { z } from 'zod';\n\n// heavily inspired by Vercel AI's `tool()`:\n// https://github.com/vercel/ai/blob/3b0983b/packages/ai/core/tool/tool.ts\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/** Type reinforcement for the callable function's execute parameters. */\nexport type inferParameters<P extends z.ZodTypeAny> = z.infer<P>;\n\n/** Raw OpenAI-adherent function parameters. */\nexport type OpenAIFunctionParameters = {\n type: 'object';\n properties: { [id: string]: any };\n required: string[];\n additionalProperties: boolean;\n};\n\n/** A definition for a function callable by the LLM. */\nexport interface CallableFunction<P extends z.ZodTypeAny = any, R = any> {\n description: string;\n parameters: OpenAIFunctionParameters | P;\n execute: (args: inferParameters<P>) => PromiseLike<R>;\n}\n\n/** A function that has been called but is not yet running */\nexport interface FunctionCallInfo<P extends z.ZodTypeAny = any, R = any> {\n name: string;\n func: CallableFunction<P, R>;\n toolCallId: string;\n rawParams: string;\n params: inferParameters<P>;\n task?: PromiseLike<CallableFunctionResult>;\n}\n\n/** The result of a ran FunctionCallInfo. */\nexport interface CallableFunctionResult {\n name: string;\n toolCallId: string;\n result?: any;\n error?: any;\n}\n\n/** An object containing callable functions and their names */\nexport type FunctionContext = {\n [name: string]: CallableFunction;\n};\n\n// XXX: Zod is victim to the dual-package hazard. this is a hacky sorta-fix\n// until Zod v4.0.0 is released.\n// https://github.com/colinhacks/zod/issues/2241#issuecomment-2142688925\nconst looksLikeInstanceof = <T>(value: unknown, target: new (...args: any[]) => T): value is T => {\n let current = value?.constructor;\n do {\n if (current?.name === target.name) return true;\n // eslint-disable-next-line @typescript-eslint/ban-types\n current = Object.getPrototypeOf(current) as Function;\n } while (current?.name);\n return false;\n};\n\n/** @internal */\nexport const oaiParams = (p: z.AnyZodObject) => {\n const properties: Record<string, any> = {};\n const requiredProperties: string[] = [];\n\n const processZodType = (field: z.ZodTypeAny): any => {\n const isOptional = field instanceof z.ZodOptional;\n const nestedField = isOptional ? field._def.innerType : field;\n const description = field._def.description;\n\n if (looksLikeInstanceof(nestedField, z.ZodEnum)) {\n return {\n type: typeof nestedField._def.values[0],\n ...(description && { description }),\n enum: nestedField._def.values,\n };\n } else if (looksLikeInstanceof(nestedField, z.ZodArray)) {\n const elementType = nestedField._def.type;\n return {\n type: 'array',\n ...(description && { description }),\n items: processZodType(elementType),\n };\n } else if (looksLikeInstanceof(nestedField, z.ZodObject)) {\n const { properties, required } = oaiParams(nestedField);\n return {\n type: 'object',\n ...(description && { description }),\n properties,\n required,\n };\n } else {\n let type = nestedField._def.typeName.toLowerCase();\n type = type.includes('zod') ? type.substring(3) : type;\n return {\n type,\n ...(description && { description }),\n };\n }\n };\n\n for (const key in p.shape) {\n const field = p.shape[key];\n properties[key] = processZodType(field);\n\n if (!(field instanceof z.ZodOptional)) {\n requiredProperties.push(key);\n }\n }\n\n const type = 'object' as const;\n return {\n type,\n properties,\n required: requiredProperties,\n };\n};\n\n/** @internal */\nexport const oaiBuildFunctionInfo = (\n fncCtx: FunctionContext,\n toolCallId: string,\n fncName: string,\n rawArgs: string,\n): FunctionCallInfo => {\n const func = fncCtx[fncName];\n if (!func) {\n throw new Error(`AI function ${fncName} not found`);\n }\n\n return {\n name: fncName,\n func,\n toolCallId,\n rawParams: rawArgs,\n params: JSON.parse(rawArgs),\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAAkB;AAmDlB,MAAM,sBAAsB,CAAI,OAAgB,WAAkD;AAChG,MAAI,UAAU,+BAAO;AACrB,KAAG;AACD,SAAI,mCAAS,UAAS,OAAO,KAAM,QAAO;AAE1C,cAAU,OAAO,eAAe,OAAO;AAAA,EACzC,SAAS,mCAAS;AAClB,SAAO;AACT;AAGO,MAAM,YAAY,CAAC,MAAsB;AAC9C,QAAM,aAAkC,CAAC;AACzC,QAAM,qBAA+B,CAAC;AAEtC,QAAM,iBAAiB,CAAC,UAA6B;AACnD,UAAM,aAAa,iBAAiB,aAAE;AACtC,UAAM,cAAc,aAAa,MAAM,KAAK,YAAY;AACxD,UAAM,cAAc,MAAM,KAAK;AAE/B,QAAI,oBAAoB,aAAa,aAAE,OAAO,GAAG;AAC/C,aAAO;AAAA,QACL,MAAM,OAAO,YAAY,KAAK,OAAO,CAAC;AAAA,QACtC,GAAI,eAAe,EAAE,YAAY;AAAA,QACjC,MAAM,YAAY,KAAK;AAAA,MACzB;AAAA,IACF,WAAW,oBAAoB,aAAa,aAAE,QAAQ,GAAG;AACvD,YAAM,cAAc,YAAY,KAAK;AACrC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,GAAI,eAAe,EAAE,YAAY;AAAA,QACjC,OAAO,eAAe,WAAW;AAAA,MACnC;AAAA,IACF,WAAW,oBAAoB,aAAa,aAAE,SAAS,GAAG;AACxD,YAAM,EAAE,YAAAA,aAAY,SAAS,IAAI,UAAU,WAAW;AACtD,aAAO;AAAA,QACL,MAAM;AAAA,QACN,GAAI,eAAe,EAAE,YAAY;AAAA,QACjC,YAAAA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,UAAIC,QAAO,YAAY,KAAK,SAAS,YAAY;AACjD,MAAAA,QAAOA,MAAK,SAAS,KAAK,IAAIA,MAAK,UAAU,CAAC,IAAIA;AAClD,aAAO;AAAA,QACL,MAAAA;AAAA,QACA,GAAI,eAAe,EAAE,YAAY;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAEA,aAAW,OAAO,EAAE,OAAO;AACzB,UAAM,QAAQ,EAAE,MAAM,GAAG;AACzB,eAAW,GAAG,IAAI,eAAe,KAAK;AAEtC,QAAI,EAAE,iBAAiB,aAAE,cAAc;AACrC,yBAAmB,KAAK,GAAG;AAAA,IAC7B;AAAA,EACF;AAEA,QAAM,OAAO;AACb,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EACZ;AACF;AAGO,MAAM,uBAAuB,CAClC,QACA,YACA,SACA,YACqB;AACrB,QAAM,OAAO,OAAO,OAAO;AAC3B,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,eAAe,OAAO,YAAY;AAAA,EACpD;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,QAAQ,KAAK,MAAM,OAAO;AAAA,EAC5B;AACF;","names":["properties","type"]}
@@ -1,47 +0,0 @@
1
- import { z } from 'zod';
2
- /** Type reinforcement for the callable function's execute parameters. */
3
- export type inferParameters<P extends z.ZodTypeAny> = z.infer<P>;
4
- /** Raw OpenAI-adherent function parameters. */
5
- export type OpenAIFunctionParameters = {
6
- type: 'object';
7
- properties: {
8
- [id: string]: any;
9
- };
10
- required: string[];
11
- additionalProperties: boolean;
12
- };
13
- /** A definition for a function callable by the LLM. */
14
- export interface CallableFunction<P extends z.ZodTypeAny = any, R = any> {
15
- description: string;
16
- parameters: OpenAIFunctionParameters | P;
17
- execute: (args: inferParameters<P>) => PromiseLike<R>;
18
- }
19
- /** A function that has been called but is not yet running */
20
- export interface FunctionCallInfo<P extends z.ZodTypeAny = any, R = any> {
21
- name: string;
22
- func: CallableFunction<P, R>;
23
- toolCallId: string;
24
- rawParams: string;
25
- params: inferParameters<P>;
26
- task?: PromiseLike<CallableFunctionResult>;
27
- }
28
- /** The result of a ran FunctionCallInfo. */
29
- export interface CallableFunctionResult {
30
- name: string;
31
- toolCallId: string;
32
- result?: any;
33
- error?: any;
34
- }
35
- /** An object containing callable functions and their names */
36
- export type FunctionContext = {
37
- [name: string]: CallableFunction;
38
- };
39
- /** @internal */
40
- export declare const oaiParams: (p: z.AnyZodObject) => {
41
- type: "object";
42
- properties: Record<string, any>;
43
- required: string[];
44
- };
45
- /** @internal */
46
- export declare const oaiBuildFunctionInfo: (fncCtx: FunctionContext, toolCallId: string, fncName: string, rawArgs: string) => FunctionCallInfo;
47
- //# sourceMappingURL=function_context.d.ts.map