@livekit/agents 1.0.47 → 1.1.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (444) hide show
  1. package/dist/beta/index.cjs +29 -0
  2. package/dist/beta/index.cjs.map +1 -0
  3. package/dist/beta/index.d.cts +2 -0
  4. package/dist/beta/index.d.ts +2 -0
  5. package/dist/beta/index.d.ts.map +1 -0
  6. package/dist/beta/index.js +7 -0
  7. package/dist/beta/index.js.map +1 -0
  8. package/dist/beta/workflows/index.cjs +29 -0
  9. package/dist/beta/workflows/index.cjs.map +1 -0
  10. package/dist/beta/workflows/index.d.cts +2 -0
  11. package/dist/beta/workflows/index.d.ts +2 -0
  12. package/dist/beta/workflows/index.d.ts.map +1 -0
  13. package/dist/beta/workflows/index.js +7 -0
  14. package/dist/beta/workflows/index.js.map +1 -0
  15. package/dist/beta/workflows/task_group.cjs +162 -0
  16. package/dist/beta/workflows/task_group.cjs.map +1 -0
  17. package/dist/beta/workflows/task_group.d.cts +32 -0
  18. package/dist/beta/workflows/task_group.d.ts +32 -0
  19. package/dist/beta/workflows/task_group.d.ts.map +1 -0
  20. package/dist/beta/workflows/task_group.js +138 -0
  21. package/dist/beta/workflows/task_group.js.map +1 -0
  22. package/dist/constants.cjs +27 -0
  23. package/dist/constants.cjs.map +1 -1
  24. package/dist/constants.d.cts +9 -0
  25. package/dist/constants.d.ts +9 -0
  26. package/dist/constants.d.ts.map +1 -1
  27. package/dist/constants.js +18 -0
  28. package/dist/constants.js.map +1 -1
  29. package/dist/index.cjs +3 -0
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +2 -1
  32. package/dist/index.d.ts +2 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +2 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/inference/api_protos.d.cts +12 -12
  37. package/dist/inference/api_protos.d.ts +12 -12
  38. package/dist/inference/interruption/defaults.cjs +81 -0
  39. package/dist/inference/interruption/defaults.cjs.map +1 -0
  40. package/dist/inference/interruption/defaults.d.cts +19 -0
  41. package/dist/inference/interruption/defaults.d.ts +19 -0
  42. package/dist/inference/interruption/defaults.d.ts.map +1 -0
  43. package/dist/inference/interruption/defaults.js +46 -0
  44. package/dist/inference/interruption/defaults.js.map +1 -0
  45. package/dist/inference/interruption/errors.cjs +44 -0
  46. package/dist/inference/interruption/errors.cjs.map +1 -0
  47. package/dist/inference/interruption/errors.d.cts +12 -0
  48. package/dist/inference/interruption/errors.d.ts +12 -0
  49. package/dist/inference/interruption/errors.d.ts.map +1 -0
  50. package/dist/inference/interruption/errors.js +20 -0
  51. package/dist/inference/interruption/errors.js.map +1 -0
  52. package/dist/inference/interruption/http_transport.cjs +147 -0
  53. package/dist/inference/interruption/http_transport.cjs.map +1 -0
  54. package/dist/inference/interruption/http_transport.d.cts +63 -0
  55. package/dist/inference/interruption/http_transport.d.ts +63 -0
  56. package/dist/inference/interruption/http_transport.d.ts.map +1 -0
  57. package/dist/inference/interruption/http_transport.js +121 -0
  58. package/dist/inference/interruption/http_transport.js.map +1 -0
  59. package/dist/inference/interruption/interruption_cache_entry.cjs +58 -0
  60. package/dist/inference/interruption/interruption_cache_entry.cjs.map +1 -0
  61. package/dist/inference/interruption/interruption_cache_entry.d.cts +30 -0
  62. package/dist/inference/interruption/interruption_cache_entry.d.ts +30 -0
  63. package/dist/inference/interruption/interruption_cache_entry.d.ts.map +1 -0
  64. package/dist/inference/interruption/interruption_cache_entry.js +34 -0
  65. package/dist/inference/interruption/interruption_cache_entry.js.map +1 -0
  66. package/dist/inference/interruption/interruption_detector.cjs +181 -0
  67. package/dist/inference/interruption/interruption_detector.cjs.map +1 -0
  68. package/dist/inference/interruption/interruption_detector.d.cts +59 -0
  69. package/dist/inference/interruption/interruption_detector.d.ts +59 -0
  70. package/dist/inference/interruption/interruption_detector.d.ts.map +1 -0
  71. package/dist/inference/interruption/interruption_detector.js +147 -0
  72. package/dist/inference/interruption/interruption_detector.js.map +1 -0
  73. package/dist/inference/interruption/interruption_stream.cjs +368 -0
  74. package/dist/inference/interruption/interruption_stream.cjs.map +1 -0
  75. package/dist/inference/interruption/interruption_stream.d.cts +46 -0
  76. package/dist/inference/interruption/interruption_stream.d.ts +46 -0
  77. package/dist/inference/interruption/interruption_stream.d.ts.map +1 -0
  78. package/dist/inference/interruption/interruption_stream.js +344 -0
  79. package/dist/inference/interruption/interruption_stream.js.map +1 -0
  80. package/dist/inference/interruption/types.cjs +17 -0
  81. package/dist/inference/interruption/types.cjs.map +1 -0
  82. package/dist/inference/interruption/types.d.cts +66 -0
  83. package/dist/inference/interruption/types.d.ts +66 -0
  84. package/dist/inference/interruption/types.d.ts.map +1 -0
  85. package/dist/inference/interruption/types.js +1 -0
  86. package/dist/inference/interruption/types.js.map +1 -0
  87. package/dist/inference/interruption/utils.cjs +130 -0
  88. package/dist/inference/interruption/utils.cjs.map +1 -0
  89. package/dist/inference/interruption/utils.d.cts +41 -0
  90. package/dist/inference/interruption/utils.d.ts +41 -0
  91. package/dist/inference/interruption/utils.d.ts.map +1 -0
  92. package/dist/inference/interruption/utils.js +105 -0
  93. package/dist/inference/interruption/utils.js.map +1 -0
  94. package/dist/inference/interruption/utils.test.cjs +105 -0
  95. package/dist/inference/interruption/utils.test.cjs.map +1 -0
  96. package/dist/inference/interruption/utils.test.js +104 -0
  97. package/dist/inference/interruption/utils.test.js.map +1 -0
  98. package/dist/inference/interruption/ws_transport.cjs +329 -0
  99. package/dist/inference/interruption/ws_transport.cjs.map +1 -0
  100. package/dist/inference/interruption/ws_transport.d.cts +33 -0
  101. package/dist/inference/interruption/ws_transport.d.ts +33 -0
  102. package/dist/inference/interruption/ws_transport.d.ts.map +1 -0
  103. package/dist/inference/interruption/ws_transport.js +295 -0
  104. package/dist/inference/interruption/ws_transport.js.map +1 -0
  105. package/dist/inference/llm.cjs +14 -10
  106. package/dist/inference/llm.cjs.map +1 -1
  107. package/dist/inference/llm.d.cts +2 -1
  108. package/dist/inference/llm.d.ts +2 -1
  109. package/dist/inference/llm.d.ts.map +1 -1
  110. package/dist/inference/llm.js +8 -10
  111. package/dist/inference/llm.js.map +1 -1
  112. package/dist/inference/stt.cjs +7 -2
  113. package/dist/inference/stt.cjs.map +1 -1
  114. package/dist/inference/stt.d.cts +2 -0
  115. package/dist/inference/stt.d.ts +2 -0
  116. package/dist/inference/stt.d.ts.map +1 -1
  117. package/dist/inference/stt.js +8 -3
  118. package/dist/inference/stt.js.map +1 -1
  119. package/dist/inference/tts.cjs +7 -2
  120. package/dist/inference/tts.cjs.map +1 -1
  121. package/dist/inference/tts.d.cts +2 -0
  122. package/dist/inference/tts.d.ts +2 -0
  123. package/dist/inference/tts.d.ts.map +1 -1
  124. package/dist/inference/tts.js +8 -3
  125. package/dist/inference/tts.js.map +1 -1
  126. package/dist/inference/utils.cjs +26 -7
  127. package/dist/inference/utils.cjs.map +1 -1
  128. package/dist/inference/utils.d.cts +13 -0
  129. package/dist/inference/utils.d.ts +13 -0
  130. package/dist/inference/utils.d.ts.map +1 -1
  131. package/dist/inference/utils.js +18 -2
  132. package/dist/inference/utils.js.map +1 -1
  133. package/dist/llm/chat_context.cjs +108 -2
  134. package/dist/llm/chat_context.cjs.map +1 -1
  135. package/dist/llm/chat_context.d.cts +28 -1
  136. package/dist/llm/chat_context.d.ts +28 -1
  137. package/dist/llm/chat_context.d.ts.map +1 -1
  138. package/dist/llm/chat_context.js +108 -2
  139. package/dist/llm/chat_context.js.map +1 -1
  140. package/dist/llm/chat_context.test.cjs +43 -0
  141. package/dist/llm/chat_context.test.cjs.map +1 -1
  142. package/dist/llm/chat_context.test.js +43 -0
  143. package/dist/llm/chat_context.test.js.map +1 -1
  144. package/dist/llm/index.cjs +2 -0
  145. package/dist/llm/index.cjs.map +1 -1
  146. package/dist/llm/index.d.cts +2 -2
  147. package/dist/llm/index.d.ts +2 -2
  148. package/dist/llm/index.d.ts.map +1 -1
  149. package/dist/llm/index.js +3 -1
  150. package/dist/llm/index.js.map +1 -1
  151. package/dist/llm/llm.cjs +16 -1
  152. package/dist/llm/llm.cjs.map +1 -1
  153. package/dist/llm/llm.d.cts +9 -0
  154. package/dist/llm/llm.d.ts +9 -0
  155. package/dist/llm/llm.d.ts.map +1 -1
  156. package/dist/llm/llm.js +16 -1
  157. package/dist/llm/llm.js.map +1 -1
  158. package/dist/llm/provider_format/index.d.cts +1 -1
  159. package/dist/llm/provider_format/index.d.ts +1 -1
  160. package/dist/llm/realtime.cjs +3 -0
  161. package/dist/llm/realtime.cjs.map +1 -1
  162. package/dist/llm/realtime.d.cts +1 -0
  163. package/dist/llm/realtime.d.ts +1 -0
  164. package/dist/llm/realtime.d.ts.map +1 -1
  165. package/dist/llm/realtime.js +3 -0
  166. package/dist/llm/realtime.js.map +1 -1
  167. package/dist/llm/tool_context.cjs +7 -0
  168. package/dist/llm/tool_context.cjs.map +1 -1
  169. package/dist/llm/tool_context.d.cts +10 -2
  170. package/dist/llm/tool_context.d.ts +10 -2
  171. package/dist/llm/tool_context.d.ts.map +1 -1
  172. package/dist/llm/tool_context.js +6 -0
  173. package/dist/llm/tool_context.js.map +1 -1
  174. package/dist/metrics/base.cjs.map +1 -1
  175. package/dist/metrics/base.d.cts +45 -1
  176. package/dist/metrics/base.d.ts +45 -1
  177. package/dist/metrics/base.d.ts.map +1 -1
  178. package/dist/metrics/index.cjs +5 -0
  179. package/dist/metrics/index.cjs.map +1 -1
  180. package/dist/metrics/index.d.cts +2 -1
  181. package/dist/metrics/index.d.ts +2 -1
  182. package/dist/metrics/index.d.ts.map +1 -1
  183. package/dist/metrics/index.js +6 -0
  184. package/dist/metrics/index.js.map +1 -1
  185. package/dist/metrics/model_usage.cjs +189 -0
  186. package/dist/metrics/model_usage.cjs.map +1 -0
  187. package/dist/metrics/model_usage.d.cts +92 -0
  188. package/dist/metrics/model_usage.d.ts +92 -0
  189. package/dist/metrics/model_usage.d.ts.map +1 -0
  190. package/dist/metrics/model_usage.js +164 -0
  191. package/dist/metrics/model_usage.js.map +1 -0
  192. package/dist/metrics/model_usage.test.cjs +474 -0
  193. package/dist/metrics/model_usage.test.cjs.map +1 -0
  194. package/dist/metrics/model_usage.test.js +476 -0
  195. package/dist/metrics/model_usage.test.js.map +1 -0
  196. package/dist/metrics/usage_collector.cjs +3 -0
  197. package/dist/metrics/usage_collector.cjs.map +1 -1
  198. package/dist/metrics/usage_collector.d.cts +9 -0
  199. package/dist/metrics/usage_collector.d.ts +9 -0
  200. package/dist/metrics/usage_collector.d.ts.map +1 -1
  201. package/dist/metrics/usage_collector.js +3 -0
  202. package/dist/metrics/usage_collector.js.map +1 -1
  203. package/dist/metrics/utils.cjs +9 -0
  204. package/dist/metrics/utils.cjs.map +1 -1
  205. package/dist/metrics/utils.d.ts.map +1 -1
  206. package/dist/metrics/utils.js +9 -0
  207. package/dist/metrics/utils.js.map +1 -1
  208. package/dist/stream/multi_input_stream.test.cjs +4 -0
  209. package/dist/stream/multi_input_stream.test.cjs.map +1 -1
  210. package/dist/stream/multi_input_stream.test.js +5 -1
  211. package/dist/stream/multi_input_stream.test.js.map +1 -1
  212. package/dist/stream/stream_channel.cjs +31 -0
  213. package/dist/stream/stream_channel.cjs.map +1 -1
  214. package/dist/stream/stream_channel.d.cts +4 -2
  215. package/dist/stream/stream_channel.d.ts +4 -2
  216. package/dist/stream/stream_channel.d.ts.map +1 -1
  217. package/dist/stream/stream_channel.js +31 -0
  218. package/dist/stream/stream_channel.js.map +1 -1
  219. package/dist/stt/stt.cjs +34 -2
  220. package/dist/stt/stt.cjs.map +1 -1
  221. package/dist/stt/stt.d.cts +22 -0
  222. package/dist/stt/stt.d.ts +22 -0
  223. package/dist/stt/stt.d.ts.map +1 -1
  224. package/dist/stt/stt.js +34 -2
  225. package/dist/stt/stt.js.map +1 -1
  226. package/dist/telemetry/otel_http_exporter.cjs +24 -5
  227. package/dist/telemetry/otel_http_exporter.cjs.map +1 -1
  228. package/dist/telemetry/otel_http_exporter.d.cts +1 -0
  229. package/dist/telemetry/otel_http_exporter.d.ts +1 -0
  230. package/dist/telemetry/otel_http_exporter.d.ts.map +1 -1
  231. package/dist/telemetry/otel_http_exporter.js +24 -5
  232. package/dist/telemetry/otel_http_exporter.js.map +1 -1
  233. package/dist/telemetry/trace_types.cjs +5 -5
  234. package/dist/telemetry/trace_types.cjs.map +1 -1
  235. package/dist/telemetry/trace_types.d.cts +9 -5
  236. package/dist/telemetry/trace_types.d.ts +9 -5
  237. package/dist/telemetry/trace_types.d.ts.map +1 -1
  238. package/dist/telemetry/trace_types.js +5 -5
  239. package/dist/telemetry/trace_types.js.map +1 -1
  240. package/dist/telemetry/traces.cjs +47 -8
  241. package/dist/telemetry/traces.cjs.map +1 -1
  242. package/dist/telemetry/traces.d.ts.map +1 -1
  243. package/dist/telemetry/traces.js +47 -8
  244. package/dist/telemetry/traces.js.map +1 -1
  245. package/dist/tts/tts.cjs +64 -2
  246. package/dist/tts/tts.cjs.map +1 -1
  247. package/dist/tts/tts.d.cts +34 -0
  248. package/dist/tts/tts.d.ts +34 -0
  249. package/dist/tts/tts.d.ts.map +1 -1
  250. package/dist/tts/tts.js +64 -2
  251. package/dist/tts/tts.js.map +1 -1
  252. package/dist/utils.cjs +1 -0
  253. package/dist/utils.cjs.map +1 -1
  254. package/dist/utils.d.ts.map +1 -1
  255. package/dist/utils.js +1 -0
  256. package/dist/utils.js.map +1 -1
  257. package/dist/version.cjs +1 -1
  258. package/dist/version.js +1 -1
  259. package/dist/voice/agent.cjs +34 -4
  260. package/dist/voice/agent.cjs.map +1 -1
  261. package/dist/voice/agent.d.cts +11 -2
  262. package/dist/voice/agent.d.ts +11 -2
  263. package/dist/voice/agent.d.ts.map +1 -1
  264. package/dist/voice/agent.js +34 -4
  265. package/dist/voice/agent.js.map +1 -1
  266. package/dist/voice/agent_activity.cjs +292 -44
  267. package/dist/voice/agent_activity.cjs.map +1 -1
  268. package/dist/voice/agent_activity.d.cts +27 -6
  269. package/dist/voice/agent_activity.d.ts +27 -6
  270. package/dist/voice/agent_activity.d.ts.map +1 -1
  271. package/dist/voice/agent_activity.js +293 -45
  272. package/dist/voice/agent_activity.js.map +1 -1
  273. package/dist/voice/agent_session.cjs +105 -48
  274. package/dist/voice/agent_session.cjs.map +1 -1
  275. package/dist/voice/agent_session.d.cts +90 -20
  276. package/dist/voice/agent_session.d.ts +90 -20
  277. package/dist/voice/agent_session.d.ts.map +1 -1
  278. package/dist/voice/agent_session.js +105 -46
  279. package/dist/voice/agent_session.js.map +1 -1
  280. package/dist/voice/audio_recognition.cjs +287 -6
  281. package/dist/voice/audio_recognition.cjs.map +1 -1
  282. package/dist/voice/audio_recognition.d.cts +42 -3
  283. package/dist/voice/audio_recognition.d.ts +42 -3
  284. package/dist/voice/audio_recognition.d.ts.map +1 -1
  285. package/dist/voice/audio_recognition.js +289 -7
  286. package/dist/voice/audio_recognition.js.map +1 -1
  287. package/dist/voice/client_events.cjs +554 -0
  288. package/dist/voice/client_events.cjs.map +1 -0
  289. package/dist/voice/client_events.d.cts +195 -0
  290. package/dist/voice/client_events.d.ts +195 -0
  291. package/dist/voice/client_events.d.ts.map +1 -0
  292. package/dist/voice/client_events.js +548 -0
  293. package/dist/voice/client_events.js.map +1 -0
  294. package/dist/voice/events.cjs +1 -0
  295. package/dist/voice/events.cjs.map +1 -1
  296. package/dist/voice/events.d.cts +8 -5
  297. package/dist/voice/events.d.ts +8 -5
  298. package/dist/voice/events.d.ts.map +1 -1
  299. package/dist/voice/events.js +1 -0
  300. package/dist/voice/events.js.map +1 -1
  301. package/dist/voice/generation.cjs +43 -8
  302. package/dist/voice/generation.cjs.map +1 -1
  303. package/dist/voice/generation.d.cts +3 -3
  304. package/dist/voice/generation.d.ts +3 -3
  305. package/dist/voice/generation.d.ts.map +1 -1
  306. package/dist/voice/generation.js +43 -8
  307. package/dist/voice/generation.js.map +1 -1
  308. package/dist/voice/index.cjs +1 -0
  309. package/dist/voice/index.cjs.map +1 -1
  310. package/dist/voice/index.d.cts +1 -0
  311. package/dist/voice/index.d.ts +1 -0
  312. package/dist/voice/index.d.ts.map +1 -1
  313. package/dist/voice/index.js +1 -0
  314. package/dist/voice/index.js.map +1 -1
  315. package/dist/voice/report.cjs +20 -8
  316. package/dist/voice/report.cjs.map +1 -1
  317. package/dist/voice/report.d.cts +5 -0
  318. package/dist/voice/report.d.ts +5 -0
  319. package/dist/voice/report.d.ts.map +1 -1
  320. package/dist/voice/report.js +20 -8
  321. package/dist/voice/report.js.map +1 -1
  322. package/dist/voice/report.test.cjs +106 -0
  323. package/dist/voice/report.test.cjs.map +1 -0
  324. package/dist/voice/report.test.js +105 -0
  325. package/dist/voice/report.test.js.map +1 -0
  326. package/dist/voice/room_io/room_io.cjs +16 -41
  327. package/dist/voice/room_io/room_io.cjs.map +1 -1
  328. package/dist/voice/room_io/room_io.d.cts +4 -9
  329. package/dist/voice/room_io/room_io.d.ts +4 -9
  330. package/dist/voice/room_io/room_io.d.ts.map +1 -1
  331. package/dist/voice/room_io/room_io.js +17 -43
  332. package/dist/voice/room_io/room_io.js.map +1 -1
  333. package/dist/voice/testing/fake_llm.cjs +127 -0
  334. package/dist/voice/testing/fake_llm.cjs.map +1 -0
  335. package/dist/voice/testing/fake_llm.d.cts +30 -0
  336. package/dist/voice/testing/fake_llm.d.ts +30 -0
  337. package/dist/voice/testing/fake_llm.d.ts.map +1 -0
  338. package/dist/voice/testing/fake_llm.js +103 -0
  339. package/dist/voice/testing/fake_llm.js.map +1 -0
  340. package/dist/voice/testing/index.cjs +3 -0
  341. package/dist/voice/testing/index.cjs.map +1 -1
  342. package/dist/voice/testing/index.d.cts +1 -0
  343. package/dist/voice/testing/index.d.ts +1 -0
  344. package/dist/voice/testing/index.d.ts.map +1 -1
  345. package/dist/voice/testing/index.js +2 -0
  346. package/dist/voice/testing/index.js.map +1 -1
  347. package/dist/voice/turn_config/endpointing.cjs +33 -0
  348. package/dist/voice/turn_config/endpointing.cjs.map +1 -0
  349. package/dist/voice/turn_config/endpointing.d.cts +30 -0
  350. package/dist/voice/turn_config/endpointing.d.ts +30 -0
  351. package/dist/voice/turn_config/endpointing.d.ts.map +1 -0
  352. package/dist/voice/turn_config/endpointing.js +9 -0
  353. package/dist/voice/turn_config/endpointing.js.map +1 -0
  354. package/dist/voice/turn_config/interruption.cjs +37 -0
  355. package/dist/voice/turn_config/interruption.cjs.map +1 -0
  356. package/dist/voice/turn_config/interruption.d.cts +53 -0
  357. package/dist/voice/turn_config/interruption.d.ts +53 -0
  358. package/dist/voice/turn_config/interruption.d.ts.map +1 -0
  359. package/dist/voice/turn_config/interruption.js +13 -0
  360. package/dist/voice/turn_config/interruption.js.map +1 -0
  361. package/dist/voice/turn_config/turn_handling.cjs +35 -0
  362. package/dist/voice/turn_config/turn_handling.cjs.map +1 -0
  363. package/dist/voice/turn_config/turn_handling.d.cts +36 -0
  364. package/dist/voice/turn_config/turn_handling.d.ts +36 -0
  365. package/dist/voice/turn_config/turn_handling.d.ts.map +1 -0
  366. package/dist/voice/turn_config/turn_handling.js +11 -0
  367. package/dist/voice/turn_config/turn_handling.js.map +1 -0
  368. package/dist/voice/turn_config/utils.cjs +97 -0
  369. package/dist/voice/turn_config/utils.cjs.map +1 -0
  370. package/dist/voice/turn_config/utils.d.cts +25 -0
  371. package/dist/voice/turn_config/utils.d.ts +25 -0
  372. package/dist/voice/turn_config/utils.d.ts.map +1 -0
  373. package/dist/voice/turn_config/utils.js +73 -0
  374. package/dist/voice/turn_config/utils.js.map +1 -0
  375. package/dist/voice/turn_config/utils.test.cjs +86 -0
  376. package/dist/voice/turn_config/utils.test.cjs.map +1 -0
  377. package/dist/voice/turn_config/utils.test.js +85 -0
  378. package/dist/voice/turn_config/utils.test.js.map +1 -0
  379. package/dist/voice/wire_format.cjs +798 -0
  380. package/dist/voice/wire_format.cjs.map +1 -0
  381. package/dist/voice/wire_format.d.cts +5503 -0
  382. package/dist/voice/wire_format.d.ts +5503 -0
  383. package/dist/voice/wire_format.d.ts.map +1 -0
  384. package/dist/voice/wire_format.js +728 -0
  385. package/dist/voice/wire_format.js.map +1 -0
  386. package/package.json +2 -1
  387. package/src/beta/index.ts +9 -0
  388. package/src/beta/workflows/index.ts +9 -0
  389. package/src/beta/workflows/task_group.ts +194 -0
  390. package/src/constants.ts +13 -0
  391. package/src/index.ts +2 -1
  392. package/src/inference/interruption/defaults.ts +51 -0
  393. package/src/inference/interruption/errors.ts +25 -0
  394. package/src/inference/interruption/http_transport.ts +187 -0
  395. package/src/inference/interruption/interruption_cache_entry.ts +50 -0
  396. package/src/inference/interruption/interruption_detector.ts +188 -0
  397. package/src/inference/interruption/interruption_stream.ts +467 -0
  398. package/src/inference/interruption/types.ts +84 -0
  399. package/src/inference/interruption/utils.test.ts +132 -0
  400. package/src/inference/interruption/utils.ts +137 -0
  401. package/src/inference/interruption/ws_transport.ts +402 -0
  402. package/src/inference/llm.ts +9 -12
  403. package/src/inference/stt.ts +10 -3
  404. package/src/inference/tts.ts +10 -3
  405. package/src/inference/utils.ts +29 -1
  406. package/src/llm/chat_context.test.ts +48 -0
  407. package/src/llm/chat_context.ts +161 -0
  408. package/src/llm/index.ts +2 -0
  409. package/src/llm/llm.ts +16 -0
  410. package/src/llm/realtime.ts +4 -0
  411. package/src/llm/tool_context.ts +14 -0
  412. package/src/metrics/base.ts +48 -1
  413. package/src/metrics/index.ts +11 -0
  414. package/src/metrics/model_usage.test.ts +545 -0
  415. package/src/metrics/model_usage.ts +262 -0
  416. package/src/metrics/usage_collector.ts +11 -0
  417. package/src/metrics/utils.ts +11 -0
  418. package/src/stream/multi_input_stream.test.ts +6 -1
  419. package/src/stream/stream_channel.ts +34 -2
  420. package/src/stt/stt.ts +38 -0
  421. package/src/telemetry/otel_http_exporter.ts +28 -5
  422. package/src/telemetry/trace_types.ts +11 -8
  423. package/src/telemetry/traces.ts +111 -54
  424. package/src/tts/tts.ts +69 -1
  425. package/src/utils.ts +5 -0
  426. package/src/voice/agent.ts +41 -3
  427. package/src/voice/agent_activity.ts +371 -34
  428. package/src/voice/agent_session.ts +207 -59
  429. package/src/voice/audio_recognition.ts +385 -9
  430. package/src/voice/client_events.ts +838 -0
  431. package/src/voice/events.ts +14 -4
  432. package/src/voice/generation.ts +52 -9
  433. package/src/voice/index.ts +1 -0
  434. package/src/voice/report.test.ts +117 -0
  435. package/src/voice/report.ts +29 -6
  436. package/src/voice/room_io/room_io.ts +21 -64
  437. package/src/voice/testing/fake_llm.ts +138 -0
  438. package/src/voice/testing/index.ts +2 -0
  439. package/src/voice/turn_config/endpointing.ts +33 -0
  440. package/src/voice/turn_config/interruption.ts +56 -0
  441. package/src/voice/turn_config/turn_handling.ts +45 -0
  442. package/src/voice/turn_config/utils.test.ts +100 -0
  443. package/src/voice/turn_config/utils.ts +103 -0
  444. package/src/voice/wire_format.ts +827 -0
@@ -15,6 +15,7 @@ export declare class _LLMGenerationData {
15
15
  generatedText: string;
16
16
  generatedToolCalls: FunctionCall[];
17
17
  id: string;
18
+ ttft?: number;
18
19
  constructor(textStream: ReadableStream<string>, toolCallStream: ReadableStream<FunctionCall>);
19
20
  }
20
21
  /**
@@ -104,8 +105,8 @@ export declare function updateInstructions(options: {
104
105
  instructions: string;
105
106
  addIfMissing: boolean;
106
107
  }): void;
107
- export declare function performLLMInference(node: LLMNode, chatCtx: ChatContext, toolCtx: ToolContext, modelSettings: ModelSettings, controller: AbortController): [Task<void>, _LLMGenerationData];
108
- export declare function performTTSInference(node: TTSNode, text: ReadableStream<string | TimedString>, modelSettings: ModelSettings, controller: AbortController): [Task<void>, _TTSGenerationData];
108
+ export declare function performLLMInference(node: LLMNode, chatCtx: ChatContext, toolCtx: ToolContext, modelSettings: ModelSettings, controller: AbortController, model?: string, provider?: string): [Task<void>, _LLMGenerationData];
109
+ export declare function performTTSInference(node: TTSNode, text: ReadableStream<string | TimedString>, modelSettings: ModelSettings, controller: AbortController, model?: string, provider?: string): [Task<void>, _TTSGenerationData];
109
110
  export interface _TextOut {
110
111
  text: string;
111
112
  firstTextFut: Future;
@@ -113,7 +114,6 @@ export interface _TextOut {
113
114
  export declare function performTextForwarding(source: ReadableStream<string | TimedString>, controller: AbortController, textOutput: TextOutput | null): [Task<void>, _TextOut];
114
115
  export interface _AudioOut {
115
116
  audio: Array<AudioFrame>;
116
- /** Future that will be set with the timestamp of the first frame's capture */
117
117
  firstFrameFut: Future<number>;
118
118
  }
119
119
  export declare function performAudioForwarding(ttsStream: ReadableStream<AudioFrame>, audioOutput: AudioOutput, controller: AbortController): [Task<void>, _AudioOut];
@@ -1 +1 @@
1
- {"version":3,"file":"generation.d.ts","sourceRoot":"","sources":["../../src/voice/generation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generation.d.ts","sourceRoot":"","sources":["../../src/voice/generation.ts"],"names":[],"mappings":"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"}
@@ -37,6 +37,7 @@ class _LLMGenerationData {
37
37
  generatedText = "";
38
38
  generatedToolCalls;
39
39
  id;
40
+ ttft;
40
41
  }
41
42
  class _ToolOutput {
42
43
  output;
@@ -295,7 +296,7 @@ function updateInstructions(options) {
295
296
  );
296
297
  }
297
298
  }
298
- function performLLMInference(node, chatCtx, toolCtx, modelSettings, controller) {
299
+ function performLLMInference(node, chatCtx, toolCtx, modelSettings, controller, model, provider) {
299
300
  const textStream = new IdentityTransform();
300
301
  const toolCallStream = new IdentityTransform();
301
302
  const textWriter = textStream.writable.getWriter();
@@ -307,8 +308,16 @@ function performLLMInference(node, chatCtx, toolCtx, modelSettings, controller)
307
308
  JSON.stringify(chatCtx.toJSON({ excludeTimestamp: false }))
308
309
  );
309
310
  span.setAttribute(traceTypes.ATTR_FUNCTION_TOOLS, JSON.stringify(Object.keys(toolCtx)));
311
+ if (model) {
312
+ span.setAttribute(traceTypes.ATTR_GEN_AI_REQUEST_MODEL, model);
313
+ }
314
+ if (provider) {
315
+ span.setAttribute(traceTypes.ATTR_GEN_AI_PROVIDER_NAME, provider);
316
+ }
310
317
  let llmStreamReader = null;
311
318
  let llmStream = null;
319
+ const startTime = performance.now() / 1e3;
320
+ let firstTokenReceived = false;
312
321
  try {
313
322
  llmStream = await node(chatCtx, toolCtx, modelSettings);
314
323
  if (llmStream === null) {
@@ -323,6 +332,10 @@ function performLLMInference(node, chatCtx, toolCtx, modelSettings, controller)
323
332
  if (result === void 0) break;
324
333
  const { done, value: chunk } = result;
325
334
  if (done) break;
335
+ if (!firstTokenReceived) {
336
+ firstTokenReceived = true;
337
+ data.ttft = performance.now() / 1e3 - startTime;
338
+ }
326
339
  if (typeof chunk === "string") {
327
340
  data.generatedText += chunk;
328
341
  await textWriter.write(chunk);
@@ -352,6 +365,9 @@ function performLLMInference(node, chatCtx, toolCtx, modelSettings, controller)
352
365
  }
353
366
  }
354
367
  span.setAttribute(traceTypes.ATTR_RESPONSE_TEXT, data.generatedText);
368
+ if (data.ttft !== void 0) {
369
+ span.setAttribute(traceTypes.ATTR_RESPONSE_TTFT, data.ttft);
370
+ }
355
371
  } catch (error) {
356
372
  if (error instanceof DOMException && error.name === "AbortError") {
357
373
  return;
@@ -374,7 +390,7 @@ function performLLMInference(node, chatCtx, toolCtx, modelSettings, controller)
374
390
  data
375
391
  ];
376
392
  }
377
- function performTTSInference(node, text, modelSettings, controller) {
393
+ function performTTSInference(node, text, modelSettings, controller, model, provider) {
378
394
  const audioStream = new IdentityTransform();
379
395
  const outputWriter = audioStream.writable.getWriter();
380
396
  const audioOutputStream = audioStream.readable;
@@ -401,10 +417,24 @@ function performTTSInference(node, text, modelSettings, controller) {
401
417
  reader.releaseLock();
402
418
  }
403
419
  })();
404
- const _performTTSInferenceImpl = async (signal) => {
420
+ let ttfb;
421
+ const genData = {
422
+ audioStream: audioOutputStream,
423
+ timedTextsFut,
424
+ ttfb: void 0
425
+ };
426
+ const _performTTSInferenceImpl = async (signal, span) => {
427
+ if (model) {
428
+ span.setAttribute(traceTypes.ATTR_GEN_AI_REQUEST_MODEL, model);
429
+ }
430
+ if (provider) {
431
+ span.setAttribute(traceTypes.ATTR_GEN_AI_PROVIDER_NAME, provider);
432
+ }
405
433
  let ttsStreamReader = null;
406
434
  let ttsStream = null;
407
435
  let pushedDuration = 0;
436
+ const startTime = performance.now() / 1e3;
437
+ let firstByteReceived = false;
408
438
  try {
409
439
  ttsStream = await node(textOnlyStream.readable, modelSettings);
410
440
  if (ttsStream === null) {
@@ -426,6 +456,12 @@ function performTTSInference(node, text, modelSettings, controller) {
426
456
  if (done) {
427
457
  break;
428
458
  }
459
+ if (!firstByteReceived) {
460
+ firstByteReceived = true;
461
+ ttfb = performance.now() / 1e3 - startTime;
462
+ genData.ttfb = ttfb;
463
+ span.setAttribute(traceTypes.ATTR_RESPONSE_TTFB, ttfb);
464
+ }
429
465
  await outputWriter.write(frame);
430
466
  const timedTranscripts = frame.userdata[USERDATA_TIMED_TRANSCRIPT];
431
467
  if (timedTranscripts && timedTranscripts.length > 0) {
@@ -449,6 +485,9 @@ function performTTSInference(node, text, modelSettings, controller) {
449
485
  }
450
486
  throw error;
451
487
  } finally {
488
+ if (!timedTextsFut.done) {
489
+ timedTextsFut.resolve(null);
490
+ }
452
491
  ttsStreamReader == null ? void 0 : ttsStreamReader.releaseLock();
453
492
  await (ttsStream == null ? void 0 : ttsStream.cancel());
454
493
  await outputWriter.close();
@@ -456,14 +495,10 @@ function performTTSInference(node, text, modelSettings, controller) {
456
495
  }
457
496
  };
458
497
  const currentContext = otelContext.active();
459
- const inferenceTask = async (signal) => tracer.startActiveSpan(async () => _performTTSInferenceImpl(signal), {
498
+ const inferenceTask = async (signal) => tracer.startActiveSpan(async (span) => _performTTSInferenceImpl(signal, span), {
460
499
  name: "tts_node",
461
500
  context: currentContext
462
501
  });
463
- const genData = {
464
- audioStream: audioOutputStream,
465
- timedTextsFut
466
- };
467
502
  return [
468
503
  Task.from((controller2) => inferenceTask(controller2.signal), controller, "performTTSInference"),
469
504
  genData
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/voice/generation.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport { AudioResampler } from '@livekit/rtc-node';\nimport type { Span } from '@opentelemetry/api';\nimport { context as otelContext } from '@opentelemetry/api';\nimport type { ReadableStream, ReadableStreamDefaultReader } from 'stream/web';\nimport {\n type ChatContext,\n ChatMessage,\n FunctionCall,\n FunctionCallOutput,\n} from '../llm/chat_context.js';\nimport type { ChatChunk } from '../llm/llm.js';\nimport {\n type ToolChoice,\n type ToolContext,\n isAgentHandoff,\n isFunctionTool,\n isToolError,\n} from '../llm/tool_context.js';\nimport { isZodSchema, parseZodSchema } from '../llm/zod-utils.js';\nimport { log } from '../log.js';\nimport { IdentityTransform } from '../stream/identity_transform.js';\nimport { traceTypes, tracer } from '../telemetry/index.js';\nimport { USERDATA_TIMED_TRANSCRIPT } from '../types.js';\nimport { Future, Task, shortuuid, toError, waitForAbort } from '../utils.js';\nimport {\n type Agent,\n type ModelSettings,\n _setActivityTaskInfo,\n functionCallStorage,\n isStopResponse,\n} from './agent.js';\nimport type { AgentSession } from './agent_session.js';\nimport {\n AudioOutput,\n type LLMNode,\n type TTSNode,\n type TextOutput,\n type TimedString,\n createTimedString,\n isTimedString,\n} from './io.js';\nimport { RunContext } from './run_context.js';\nimport type { SpeechHandle } from './speech_handle.js';\n\n/** @internal */\nexport class _LLMGenerationData {\n generatedText: string = '';\n generatedToolCalls: FunctionCall[];\n id: string;\n\n constructor(\n public readonly textStream: ReadableStream<string>,\n public readonly toolCallStream: ReadableStream<FunctionCall>,\n ) {\n this.id = shortuuid('item_');\n this.generatedToolCalls = [];\n }\n}\n\n/**\n * TTS generation data containing audio stream and optional timed transcripts.\n * @internal\n */\nexport interface _TTSGenerationData {\n /** Audio frame stream from TTS */\n audioStream: ReadableStream<AudioFrame>;\n /**\n * Future that resolves to a stream of timed transcripts, or null if TTS doesn't support it.\n */\n timedTextsFut: Future<ReadableStream<TimedString> | null>;\n /** Time to first byte (set when first audio frame is received) */\n ttfb?: number;\n}\n\n// TODO(brian): remove this class in favor of ToolOutput\nexport class _ToolOutput {\n output: _JsOutput[];\n firstToolFut: Future;\n\n constructor() {\n this.output = [];\n this.firstToolFut = new Future();\n }\n}\n\n// TODO(brian): remove this class in favor of ToolExecutionOutput\nexport class _SanitizedOutput {\n toolCall: FunctionCall;\n toolCallOutput?: FunctionCallOutput;\n replyRequired: boolean;\n agentTask?: Agent;\n\n constructor(\n toolCall: FunctionCall,\n toolCallOutput: FunctionCallOutput | undefined,\n replyRequired: boolean,\n agentTask: Agent | undefined,\n ) {\n this.toolCall = toolCall;\n this.toolCallOutput = toolCallOutput;\n this.replyRequired = replyRequired;\n this.agentTask = agentTask;\n }\n\n static create(params: {\n toolCall: FunctionCall;\n toolCallOutput?: FunctionCallOutput;\n replyRequired?: boolean;\n agentTask?: Agent;\n }) {\n const { toolCall, toolCallOutput, replyRequired = true, agentTask } = params;\n return new _SanitizedOutput(toolCall, toolCallOutput, replyRequired, agentTask);\n }\n}\n\nfunction isValidToolOutput(toolOutput: unknown): boolean {\n const validTypes = ['string', 'number', 'boolean'];\n\n if (validTypes.includes(typeof toolOutput)) {\n return true;\n }\n\n if (toolOutput === undefined || toolOutput === null) {\n return true;\n }\n\n if (Array.isArray(toolOutput)) {\n return toolOutput.every(isValidToolOutput);\n }\n\n if (toolOutput instanceof Set) {\n return Array.from(toolOutput).every(isValidToolOutput);\n }\n\n if (toolOutput instanceof Map) {\n return Array.from(toolOutput.values()).every(isValidToolOutput);\n }\n\n if (toolOutput instanceof Object) {\n return Object.entries(toolOutput).every(\n ([key, value]) => validTypes.includes(typeof key) && isValidToolOutput(value),\n );\n }\n\n return false;\n}\n\nexport class ToolExecutionOutput {\n constructor(\n public readonly toolCall: FunctionCall,\n public readonly toolCallOutput: FunctionCallOutput | undefined,\n public readonly agentTask: Agent | undefined,\n public readonly rawOutput: unknown,\n public readonly rawException: Error | undefined,\n public readonly replyRequired: boolean,\n ) {}\n\n static create(params: {\n toolCall: FunctionCall;\n toolCallOutput?: FunctionCallOutput;\n agentTask?: Agent;\n rawOutput: unknown;\n rawException?: Error;\n replyRequired?: boolean;\n }) {\n const {\n toolCall,\n toolCallOutput,\n agentTask,\n rawOutput,\n rawException,\n replyRequired = true,\n } = params;\n return new ToolExecutionOutput(\n toolCall,\n toolCallOutput,\n agentTask,\n rawOutput,\n rawException,\n replyRequired,\n );\n }\n}\n\nexport interface ToolOutput {\n output: ToolExecutionOutput[];\n firstToolStartedFuture: Future<void>;\n}\n\n// TODO(brian): remove this class in favor of ToolExecutionOutput\nexport class _JsOutput {\n toolCall: FunctionCall;\n output: unknown;\n exception?: Error;\n\n #logger = log();\n\n constructor(toolCall: FunctionCall, output: unknown, exception: Error | undefined) {\n this.toolCall = toolCall;\n this.output = output;\n this.exception = exception;\n }\n\n static create(params: { toolCall: FunctionCall; output?: unknown; exception?: Error }) {\n const { toolCall, output = undefined, exception = undefined } = params;\n return new _JsOutput(toolCall, output, exception);\n }\n\n sanitize(): _SanitizedOutput {\n if (isToolError(this.exception)) {\n return _SanitizedOutput.create({\n toolCall: FunctionCall.create({ ...this.toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: this.toolCall.name,\n callId: this.toolCall.callId,\n output: this.exception.message,\n isError: true,\n }),\n });\n }\n\n if (isStopResponse(this.exception)) {\n return _SanitizedOutput.create({\n toolCall: FunctionCall.create({ ...this.toolCall }),\n });\n }\n\n if (this.exception !== undefined) {\n return _SanitizedOutput.create({\n toolCall: FunctionCall.create({ ...this.toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: this.toolCall.name,\n callId: this.toolCall.callId,\n output: 'An internal error occurred while executing the tool.', // Don't send the actual error message, as it may contain sensitive information\n isError: true,\n }),\n });\n }\n\n let agentTask: Agent | undefined = undefined;\n let toolOutput: unknown = this.output;\n if (isAgentHandoff(this.output)) {\n agentTask = this.output.agent;\n toolOutput = this.output.returns;\n }\n\n if (!isValidToolOutput(toolOutput)) {\n this.#logger.error(\n {\n callId: this.toolCall.callId,\n function: this.toolCall.name,\n },\n `AI function ${this.toolCall.name} returned an invalid output`,\n );\n return _SanitizedOutput.create({\n toolCall: FunctionCall.create({ ...this.toolCall }),\n toolCallOutput: undefined,\n });\n }\n\n return _SanitizedOutput.create({\n toolCall: FunctionCall.create({ ...this.toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: this.toolCall.name,\n callId: this.toolCall.callId,\n output: toolOutput !== undefined ? JSON.stringify(toolOutput) : '', // take the string representation of the output\n isError: false,\n }),\n replyRequired: toolOutput !== undefined, // require a reply if the tool returned an output\n agentTask,\n });\n }\n}\n\nexport function createToolOutput(params: {\n toolCall: FunctionCall;\n output?: unknown;\n exception?: Error;\n}): ToolExecutionOutput {\n const { toolCall, output, exception } = params;\n const logger = log();\n\n // support returning Exception instead of raising them (for devex purposes inside evals)\n let finalOutput = output;\n let finalException = exception;\n if (output instanceof Error) {\n finalException = output;\n finalOutput = undefined;\n }\n\n if (isToolError(finalException)) {\n return ToolExecutionOutput.create({\n toolCall: FunctionCall.create({ ...toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: toolCall.name,\n callId: toolCall.callId,\n output: finalException.message,\n isError: true,\n }),\n rawOutput: finalOutput,\n rawException: finalException,\n });\n }\n\n if (isStopResponse(finalException)) {\n return ToolExecutionOutput.create({\n toolCall: FunctionCall.create({ ...toolCall }),\n rawOutput: finalOutput,\n rawException: finalException,\n });\n }\n\n if (finalException !== undefined) {\n return ToolExecutionOutput.create({\n toolCall: FunctionCall.create({ ...toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: toolCall.name,\n callId: toolCall.callId,\n output: 'An internal error occurred', // Don't send the actual error message, as it may contain sensitive information\n isError: true,\n }),\n rawOutput: finalOutput,\n rawException: finalException,\n });\n }\n\n let agentTask: Agent | undefined = undefined;\n let toolOutput: unknown = finalOutput;\n if (isAgentHandoff(finalOutput)) {\n agentTask = finalOutput.agent;\n toolOutput = finalOutput.returns;\n }\n\n if (!isValidToolOutput(toolOutput)) {\n logger.error(\n {\n callId: toolCall.callId,\n output: finalOutput,\n },\n `AI function ${toolCall.name} returned an invalid output`,\n );\n return ToolExecutionOutput.create({\n toolCall: FunctionCall.create({ ...toolCall }),\n rawOutput: finalOutput,\n rawException: finalException,\n });\n }\n\n return ToolExecutionOutput.create({\n toolCall: FunctionCall.create({ ...toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: toolCall.name,\n callId: toolCall.callId,\n output: toolOutput !== undefined ? JSON.stringify(toolOutput) : '', // take the string representation of the output\n isError: false,\n }),\n replyRequired: toolOutput !== undefined, // require a reply if the tool returned an output\n agentTask,\n rawOutput: finalOutput,\n rawException: finalException,\n });\n}\n\nconst INSTRUCTIONS_MESSAGE_ID = 'lk.agent_task.instructions';\n\n/**\n * Update the instruction message in the chat context or insert a new one if missing.\n *\n * This function looks for an existing instruction message in the chat context using the identifier\n * 'INSTRUCTIONS_MESSAGE_ID'.\n *\n * @param options - The options for updating the instructions.\n * @param options.chatCtx - The chat context to update.\n * @param options.instructions - The instructions to add.\n * @param options.addIfMissing - Whether to add the instructions if they are missing.\n */\nexport function updateInstructions(options: {\n chatCtx: ChatContext;\n instructions: string;\n addIfMissing: boolean;\n}) {\n const { chatCtx, instructions, addIfMissing } = options;\n\n const idx = chatCtx.indexById(INSTRUCTIONS_MESSAGE_ID);\n if (idx !== undefined) {\n if (chatCtx.items[idx]!.type === 'message') {\n // create a new instance to avoid mutating the original\n chatCtx.items[idx] = ChatMessage.create({\n id: INSTRUCTIONS_MESSAGE_ID,\n role: 'system',\n content: [instructions],\n createdAt: chatCtx.items[idx]!.createdAt,\n });\n } else {\n throw new Error('expected the instructions inside the chatCtx to be of type \"message\"');\n }\n } else if (addIfMissing) {\n // insert the instructions at the beginning of the chat context\n chatCtx.items.unshift(\n ChatMessage.create({\n id: INSTRUCTIONS_MESSAGE_ID,\n role: 'system',\n content: [instructions],\n }),\n );\n }\n}\n\nexport function performLLMInference(\n node: LLMNode,\n chatCtx: ChatContext,\n toolCtx: ToolContext,\n modelSettings: ModelSettings,\n controller: AbortController,\n): [Task<void>, _LLMGenerationData] {\n const textStream = new IdentityTransform<string>();\n const toolCallStream = new IdentityTransform<FunctionCall>();\n\n const textWriter = textStream.writable.getWriter();\n const toolCallWriter = toolCallStream.writable.getWriter();\n const data = new _LLMGenerationData(textStream.readable, toolCallStream.readable);\n\n const _performLLMInferenceImpl = async (signal: AbortSignal, span: Span) => {\n span.setAttribute(\n traceTypes.ATTR_CHAT_CTX,\n JSON.stringify(chatCtx.toJSON({ excludeTimestamp: false })),\n );\n span.setAttribute(traceTypes.ATTR_FUNCTION_TOOLS, JSON.stringify(Object.keys(toolCtx)));\n\n let llmStreamReader: ReadableStreamDefaultReader<string | ChatChunk> | null = null;\n let llmStream: ReadableStream<string | ChatChunk> | null = null;\n\n try {\n llmStream = await node(chatCtx, toolCtx, modelSettings);\n if (llmStream === null) {\n await textWriter.close();\n return;\n }\n\n const abortPromise = waitForAbort(signal);\n\n // TODO(brian): add support for dynamic tools\n\n llmStreamReader = llmStream.getReader();\n while (true) {\n if (signal.aborted) break;\n\n const result = await Promise.race([llmStreamReader.read(), abortPromise]);\n if (result === undefined) break;\n\n const { done, value: chunk } = result;\n if (done) break;\n\n if (typeof chunk === 'string') {\n data.generatedText += chunk;\n await textWriter.write(chunk);\n // TODO(shubhra): better way to check??\n } else {\n if (chunk.delta === undefined) {\n continue;\n }\n\n if (chunk.delta.toolCalls) {\n for (const tool of chunk.delta.toolCalls) {\n if (tool.type !== 'function_call') continue;\n\n const toolCall = FunctionCall.create({\n callId: `${data.id}/fnc_${data.generatedToolCalls.length}`,\n name: tool.name,\n args: tool.args,\n // Preserve thought signature for Gemini 3+ thinking mode\n thoughtSignature: tool.thoughtSignature,\n extra: tool.extra || {},\n });\n\n data.generatedToolCalls.push(toolCall);\n await toolCallWriter.write(toolCall);\n }\n }\n\n if (chunk.delta.content) {\n data.generatedText += chunk.delta.content;\n await textWriter.write(chunk.delta.content);\n }\n }\n\n // No need to check if chunk is of type other than ChatChunk or string like in\n // Python since chunk is defined in the type ChatChunk | string in TypeScript\n }\n\n span.setAttribute(traceTypes.ATTR_RESPONSE_TEXT, data.generatedText);\n } catch (error) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n // Abort signal was triggered, handle gracefully\n return;\n }\n throw error;\n } finally {\n llmStreamReader?.releaseLock();\n await llmStream?.cancel();\n await textWriter.close();\n await toolCallWriter.close();\n }\n };\n\n // Capture the current context (agent_turn) to ensure llm_node is properly parented\n const currentContext = otelContext.active();\n\n const inferenceTask = async (signal: AbortSignal) =>\n tracer.startActiveSpan(async (span) => _performLLMInferenceImpl(signal, span), {\n name: 'llm_node',\n context: currentContext,\n });\n\n return [\n Task.from((controller) => inferenceTask(controller.signal), controller, 'performLLMInference'),\n data,\n ];\n}\n\nexport function performTTSInference(\n node: TTSNode,\n text: ReadableStream<string | TimedString>,\n modelSettings: ModelSettings,\n controller: AbortController,\n): [Task<void>, _TTSGenerationData] {\n const audioStream = new IdentityTransform<AudioFrame>();\n const outputWriter = audioStream.writable.getWriter();\n const audioOutputStream = audioStream.readable;\n\n const timedTextsFut = new Future<ReadableStream<TimedString> | null>();\n const timedTextsStream = new IdentityTransform<TimedString>();\n const timedTextsWriter = timedTextsStream.writable.getWriter();\n\n // Transform stream to extract text from TimedString objects\n const textOnlyStream = new IdentityTransform<string>();\n const textOnlyWriter = textOnlyStream.writable.getWriter();\n (async () => {\n const reader = text.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n const textValue = typeof value === 'string' ? value : value.text;\n await textOnlyWriter.write(textValue);\n }\n await textOnlyWriter.close();\n } catch (e) {\n await textOnlyWriter.abort(e as Error);\n } finally {\n reader.releaseLock();\n }\n })();\n\n const _performTTSInferenceImpl = async (signal: AbortSignal) => {\n let ttsStreamReader: ReadableStreamDefaultReader<AudioFrame> | null = null;\n let ttsStream: ReadableStream<AudioFrame> | null = null;\n let pushedDuration = 0;\n\n try {\n ttsStream = await node(textOnlyStream.readable, modelSettings);\n if (ttsStream === null) {\n timedTextsFut.resolve(null);\n await outputWriter.close();\n await timedTextsWriter.close();\n return;\n }\n\n // This is critical: the future must be resolved with the channel/stream before the loop\n // so that agent_activity can start reading while we write\n if (!timedTextsFut.done) {\n timedTextsFut.resolve(timedTextsStream.readable);\n }\n\n ttsStreamReader = ttsStream.getReader();\n\n // In Python, perform_tts_inference has a while loop processing multiple input segments\n // (separated by FlushSentinel), with pushed_duration accumulating across segments.\n // JS currently only does single inference, so initialPushedDuration is always 0.\n // TODO: Add FlushSentinel + multi-segment loop\n const initialPushedDuration = pushedDuration;\n\n while (true) {\n if (signal.aborted) {\n break;\n }\n const { done, value: frame } = await ttsStreamReader.read();\n if (done) {\n break;\n }\n\n // Write the audio frame to the output stream\n await outputWriter.write(frame);\n\n const timedTranscripts = frame.userdata[USERDATA_TIMED_TRANSCRIPT] as\n | TimedString[]\n | undefined;\n if (timedTranscripts && timedTranscripts.length > 0) {\n for (const timedText of timedTranscripts) {\n // Uses the INITIAL value (from previous inferences), not the accumulated value\n const adjustedTimedText = createTimedString({\n text: timedText.text,\n startTime:\n timedText.startTime !== undefined\n ? timedText.startTime + initialPushedDuration\n : undefined,\n endTime:\n timedText.endTime !== undefined\n ? timedText.endTime + initialPushedDuration\n : undefined,\n confidence: timedText.confidence,\n startTimeOffset: timedText.startTimeOffset,\n });\n await timedTextsWriter.write(adjustedTimedText);\n }\n }\n\n const frameDuration = frame.samplesPerChannel / frame.sampleRate;\n pushedDuration += frameDuration;\n }\n } catch (error) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n // Abort signal was triggered, handle gracefully\n return;\n }\n throw error;\n } finally {\n ttsStreamReader?.releaseLock();\n await ttsStream?.cancel();\n await outputWriter.close();\n await timedTextsWriter.close();\n }\n };\n\n // Capture the current context (agent_turn) to ensure tts_node is properly parented\n const currentContext = otelContext.active();\n\n const inferenceTask = async (signal: AbortSignal) =>\n tracer.startActiveSpan(async () => _performTTSInferenceImpl(signal), {\n name: 'tts_node',\n context: currentContext,\n });\n\n const genData: _TTSGenerationData = {\n audioStream: audioOutputStream,\n timedTextsFut,\n };\n\n return [\n Task.from((controller) => inferenceTask(controller.signal), controller, 'performTTSInference'),\n genData,\n ];\n}\n\nexport interface _TextOut {\n text: string;\n firstTextFut: Future;\n}\n\nasync function forwardText(\n source: ReadableStream<string | TimedString>,\n out: _TextOut,\n signal: AbortSignal,\n textOutput: TextOutput | null,\n): Promise<void> {\n const reader = source.getReader();\n try {\n while (true) {\n if (signal.aborted) {\n break;\n }\n const { done, value: delta } = await reader.read();\n if (done) break;\n\n const deltaIsTimedString = isTimedString(delta);\n const textDelta = deltaIsTimedString ? delta.text : delta;\n\n out.text += textDelta;\n if (textOutput !== null) {\n // Pass TimedString to textOutput for synchronized transcription\n await textOutput.captureText(delta);\n }\n if (!out.firstTextFut.done) {\n out.firstTextFut.resolve();\n }\n }\n } finally {\n if (textOutput !== null) {\n textOutput.flush();\n }\n reader?.releaseLock();\n }\n}\n\nexport function performTextForwarding(\n source: ReadableStream<string | TimedString>,\n controller: AbortController,\n textOutput: TextOutput | null,\n): [Task<void>, _TextOut] {\n const out = {\n text: '',\n firstTextFut: new Future(),\n };\n return [\n Task.from(\n (controller) => forwardText(source, out, controller.signal, textOutput),\n controller,\n 'performTextForwarding',\n ),\n out,\n ];\n}\n\nexport interface _AudioOut {\n audio: Array<AudioFrame>;\n /** Future that will be set with the timestamp of the first frame's capture */\n firstFrameFut: Future<number>;\n}\n\nasync function forwardAudio(\n ttsStream: ReadableStream<AudioFrame>,\n audioOutput: AudioOutput,\n out: _AudioOut,\n signal?: AbortSignal,\n): Promise<void> {\n const reader = ttsStream.getReader();\n let resampler: AudioResampler | null = null;\n\n const onPlaybackStarted = (ev: { createdAt: number }) => {\n if (!out.firstFrameFut.done) {\n out.firstFrameFut.resolve(ev.createdAt);\n }\n };\n\n try {\n audioOutput.on(AudioOutput.EVENT_PLAYBACK_STARTED, onPlaybackStarted);\n audioOutput.resume();\n\n while (true) {\n if (signal?.aborted) {\n break;\n }\n\n const { done, value: frame } = await reader.read();\n if (done) break;\n\n out.audio.push(frame);\n\n if (\n !out.firstFrameFut.done &&\n audioOutput.sampleRate &&\n audioOutput.sampleRate !== frame.sampleRate &&\n !resampler\n ) {\n resampler = new AudioResampler(frame.sampleRate, audioOutput.sampleRate, 1);\n }\n\n if (resampler) {\n for (const f of resampler.push(frame)) {\n await audioOutput.captureFrame(f);\n }\n } else {\n await audioOutput.captureFrame(frame);\n }\n }\n\n if (resampler) {\n for (const f of resampler.flush()) {\n await audioOutput.captureFrame(f);\n }\n }\n } finally {\n audioOutput.off(AudioOutput.EVENT_PLAYBACK_STARTED, onPlaybackStarted);\n\n if (!out.firstFrameFut.done) {\n out.firstFrameFut.reject(new Error('audio forwarding cancelled before playback started'));\n }\n\n reader?.releaseLock();\n audioOutput.flush();\n }\n}\n\nexport function performAudioForwarding(\n ttsStream: ReadableStream<AudioFrame>,\n audioOutput: AudioOutput,\n controller: AbortController,\n): [Task<void>, _AudioOut] {\n const out: _AudioOut = {\n audio: [],\n firstFrameFut: new Future<number>(),\n };\n\n return [\n Task.from(\n (controller) => forwardAudio(ttsStream, audioOutput, out, controller.signal),\n controller,\n 'performAudioForwarding',\n ),\n out,\n ];\n}\n\n// function_tool span is already implemented in tracableToolExecution below (line ~796)\nexport function performToolExecutions({\n session,\n speechHandle,\n toolCtx,\n toolChoice,\n toolCallStream,\n onToolExecutionStarted = () => {},\n onToolExecutionCompleted = () => {},\n controller,\n}: {\n session: AgentSession;\n speechHandle: SpeechHandle;\n toolCtx: ToolContext;\n toolChoice?: ToolChoice;\n toolCallStream: ReadableStream<FunctionCall>;\n onToolExecutionStarted?: (toolCall: FunctionCall) => void;\n onToolExecutionCompleted?: (toolExecutionOutput: ToolExecutionOutput) => void;\n controller: AbortController;\n}): [Task<void>, ToolOutput] {\n const logger = log();\n const toolOutput: ToolOutput = {\n output: [],\n firstToolStartedFuture: new Future(),\n };\n\n const toolCompleted = (out: ToolExecutionOutput) => {\n onToolExecutionCompleted(out);\n toolOutput.output.push(out);\n };\n\n const executeToolsTask = async (controller: AbortController) => {\n const signal = controller.signal;\n const reader = toolCallStream.getReader();\n\n const tasks: Task<void>[] = [];\n while (!signal.aborted) {\n const { done, value: toolCall } = await reader.read();\n if (signal.aborted) break;\n if (done) break;\n\n if (toolChoice === 'none') {\n logger.error(\n {\n function: toolCall.name,\n speech_id: speechHandle.id,\n },\n \"received a tool call with toolChoice set to 'none', ignoring\",\n );\n continue;\n }\n\n // TODO(brian): assert other toolChoice values\n\n const tool = toolCtx[toolCall.name];\n if (!tool) {\n logger.warn(\n {\n function: toolCall.name,\n speech_id: speechHandle.id,\n },\n `unknown AI function ${toolCall.name}`,\n );\n continue;\n }\n\n if (!isFunctionTool(tool)) {\n logger.error(\n {\n function: toolCall.name,\n speech_id: speechHandle.id,\n },\n `unknown tool type: ${typeof tool}`,\n );\n continue;\n }\n\n let parsedArgs: object | undefined;\n\n // Ensure valid arguments\n try {\n const jsonArgs = JSON.parse(toolCall.args);\n\n if (isZodSchema(tool.parameters)) {\n const result = await parseZodSchema<object>(tool.parameters, jsonArgs);\n if (result.success) {\n parsedArgs = result.data;\n } else {\n throw result.error;\n }\n } else {\n parsedArgs = jsonArgs;\n }\n } catch (rawError) {\n const error = toError(rawError);\n logger.error(\n {\n function: toolCall.name,\n arguments: toolCall.args,\n speech_id: speechHandle.id,\n error: error.message,\n },\n `tried to call AI function ${toolCall.name} with invalid arguments`,\n );\n toolCompleted(\n createToolOutput({\n toolCall,\n exception: error,\n }),\n );\n continue;\n }\n\n if (!toolOutput.firstToolStartedFuture.done) {\n toolOutput.firstToolStartedFuture.resolve();\n }\n\n onToolExecutionStarted(toolCall);\n\n logger.info(\n {\n function: toolCall.name,\n arguments: parsedArgs,\n speech_id: speechHandle.id,\n },\n 'Executing LLM tool call',\n );\n\n const _tracableToolExecutionImpl = async (toolExecTask: Promise<unknown>, span: Span) => {\n span.setAttribute(traceTypes.ATTR_FUNCTION_TOOL_NAME, toolCall.name);\n span.setAttribute(traceTypes.ATTR_FUNCTION_TOOL_ARGS, toolCall.args);\n\n // await for task to complete, if task is aborted, set exception\n let toolOutput: ToolExecutionOutput | undefined;\n try {\n const { result, isAborted } = await waitUntilAborted(toolExecTask, signal);\n toolOutput = createToolOutput({\n toolCall,\n exception: isAborted ? new Error('tool call was aborted') : undefined,\n output: isAborted ? undefined : result,\n });\n\n if (toolOutput.toolCallOutput) {\n span.setAttribute(\n traceTypes.ATTR_FUNCTION_TOOL_OUTPUT,\n toolOutput.toolCallOutput.output,\n );\n span.setAttribute(\n traceTypes.ATTR_FUNCTION_TOOL_IS_ERROR,\n toolOutput.toolCallOutput.isError,\n );\n }\n } catch (rawError) {\n logger.error(\n {\n function: toolCall.name,\n speech_id: speechHandle.id,\n error: toError(rawError).message,\n },\n 'exception occurred while executing tool',\n );\n toolOutput = createToolOutput({\n toolCall,\n exception: toError(rawError),\n });\n\n if (toolOutput.toolCallOutput) {\n span.setAttribute(\n traceTypes.ATTR_FUNCTION_TOOL_OUTPUT,\n toolOutput.toolCallOutput.output,\n );\n span.setAttribute(traceTypes.ATTR_FUNCTION_TOOL_IS_ERROR, true);\n }\n } finally {\n if (!toolOutput) throw new Error('toolOutput is undefined');\n toolCompleted(toolOutput);\n }\n };\n\n const tracableToolExecution = (toolExecTask: Promise<unknown>) =>\n tracer.startActiveSpan(async (span) => _tracableToolExecutionImpl(toolExecTask, span), {\n name: 'function_tool',\n });\n\n const toolTask = Task.from(\n async () => {\n // Ensure this task is marked inline before user tool code executes.\n const currentTask = Task.current();\n if (currentTask) {\n _setActivityTaskInfo(currentTask, {\n speechHandle,\n functionCall: toolCall,\n inlineTask: true,\n });\n }\n\n const toolExecution = functionCallStorage.run({ functionCall: toolCall }, async () => {\n return await tool.execute(parsedArgs, {\n ctx: new RunContext(session, speechHandle, toolCall),\n toolCallId: toolCall.callId,\n abortSignal: signal,\n });\n });\n\n await tracableToolExecution(toolExecution);\n },\n controller,\n `performToolExecution:${toolCall.name}`,\n );\n\n _setActivityTaskInfo(toolTask, {\n speechHandle,\n functionCall: toolCall,\n inlineTask: true,\n });\n // wait, not cancelling all tool calling tasks\n tasks.push(toolTask);\n }\n\n await Promise.allSettled(tasks.map((task) => task.result));\n if (toolOutput.output.length > 0) {\n logger.debug(\n {\n speech_id: speechHandle.id,\n },\n 'tools execution completed',\n );\n }\n };\n\n return [Task.from(executeToolsTask, controller, 'performToolExecutions'), toolOutput];\n}\n\ntype Aborted<T> =\n | {\n result: T;\n isAborted: false;\n }\n | {\n result: undefined;\n isAborted: true;\n };\n\nasync function waitUntilAborted<T>(promise: Promise<T>, signal: AbortSignal): Promise<Aborted<T>> {\n const abortFut = new Future<Aborted<T>>();\n\n const resolveAbort = () => {\n if (!abortFut.done) {\n abortFut.resolve({ result: undefined, isAborted: true });\n }\n };\n\n signal.addEventListener('abort', resolveAbort);\n\n promise\n .then((r) => {\n if (!abortFut.done) {\n abortFut.resolve({ result: r, isAborted: false });\n }\n })\n .catch((e) => {\n if (!abortFut.done) {\n abortFut.reject(e);\n }\n })\n .finally(() => {\n signal.removeEventListener('abort', resolveAbort);\n });\n\n return await abortFut.await;\n}\n\nexport function removeInstructions(chatCtx: ChatContext) {\n // loop in case there are items with the same id (shouldn't happen!)\n while (true) {\n const idx = chatCtx.indexById(INSTRUCTIONS_MESSAGE_ID);\n if (idx !== undefined) {\n chatCtx.items.splice(idx, 1);\n } else {\n break;\n }\n }\n}\n"],"mappings":"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","names":["controller","toolOutput"]}
1
+ {"version":3,"sources":["../../src/voice/generation.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport { AudioResampler } from '@livekit/rtc-node';\nimport type { Span } from '@opentelemetry/api';\nimport { context as otelContext } from '@opentelemetry/api';\nimport type { ReadableStream, ReadableStreamDefaultReader } from 'stream/web';\nimport {\n type ChatContext,\n ChatMessage,\n FunctionCall,\n FunctionCallOutput,\n} from '../llm/chat_context.js';\nimport type { ChatChunk } from '../llm/llm.js';\nimport {\n type ToolChoice,\n type ToolContext,\n isAgentHandoff,\n isFunctionTool,\n isToolError,\n} from '../llm/tool_context.js';\nimport { isZodSchema, parseZodSchema } from '../llm/zod-utils.js';\nimport { log } from '../log.js';\nimport { IdentityTransform } from '../stream/identity_transform.js';\nimport { traceTypes, tracer } from '../telemetry/index.js';\nimport { USERDATA_TIMED_TRANSCRIPT } from '../types.js';\nimport { Future, Task, shortuuid, toError, waitForAbort } from '../utils.js';\nimport {\n type Agent,\n type ModelSettings,\n _setActivityTaskInfo,\n functionCallStorage,\n isStopResponse,\n} from './agent.js';\nimport type { AgentSession } from './agent_session.js';\nimport {\n AudioOutput,\n type LLMNode,\n type TTSNode,\n type TextOutput,\n type TimedString,\n createTimedString,\n isTimedString,\n} from './io.js';\nimport { RunContext } from './run_context.js';\nimport type { SpeechHandle } from './speech_handle.js';\n\n/** @internal */\nexport class _LLMGenerationData {\n generatedText: string = '';\n generatedToolCalls: FunctionCall[];\n id: string;\n ttft?: number;\n\n constructor(\n public readonly textStream: ReadableStream<string>,\n public readonly toolCallStream: ReadableStream<FunctionCall>,\n ) {\n this.id = shortuuid('item_');\n this.generatedToolCalls = [];\n }\n}\n\n/**\n * TTS generation data containing audio stream and optional timed transcripts.\n * @internal\n */\nexport interface _TTSGenerationData {\n /** Audio frame stream from TTS */\n audioStream: ReadableStream<AudioFrame>;\n /**\n * Future that resolves to a stream of timed transcripts, or null if TTS doesn't support it.\n */\n timedTextsFut: Future<ReadableStream<TimedString> | null>;\n /** Time to first byte (set when first audio frame is received) */\n ttfb?: number;\n}\n\n// TODO(brian): remove this class in favor of ToolOutput\nexport class _ToolOutput {\n output: _JsOutput[];\n firstToolFut: Future;\n\n constructor() {\n this.output = [];\n this.firstToolFut = new Future();\n }\n}\n\n// TODO(brian): remove this class in favor of ToolExecutionOutput\nexport class _SanitizedOutput {\n toolCall: FunctionCall;\n toolCallOutput?: FunctionCallOutput;\n replyRequired: boolean;\n agentTask?: Agent;\n\n constructor(\n toolCall: FunctionCall,\n toolCallOutput: FunctionCallOutput | undefined,\n replyRequired: boolean,\n agentTask: Agent | undefined,\n ) {\n this.toolCall = toolCall;\n this.toolCallOutput = toolCallOutput;\n this.replyRequired = replyRequired;\n this.agentTask = agentTask;\n }\n\n static create(params: {\n toolCall: FunctionCall;\n toolCallOutput?: FunctionCallOutput;\n replyRequired?: boolean;\n agentTask?: Agent;\n }) {\n const { toolCall, toolCallOutput, replyRequired = true, agentTask } = params;\n return new _SanitizedOutput(toolCall, toolCallOutput, replyRequired, agentTask);\n }\n}\n\nfunction isValidToolOutput(toolOutput: unknown): boolean {\n const validTypes = ['string', 'number', 'boolean'];\n\n if (validTypes.includes(typeof toolOutput)) {\n return true;\n }\n\n if (toolOutput === undefined || toolOutput === null) {\n return true;\n }\n\n if (Array.isArray(toolOutput)) {\n return toolOutput.every(isValidToolOutput);\n }\n\n if (toolOutput instanceof Set) {\n return Array.from(toolOutput).every(isValidToolOutput);\n }\n\n if (toolOutput instanceof Map) {\n return Array.from(toolOutput.values()).every(isValidToolOutput);\n }\n\n if (toolOutput instanceof Object) {\n return Object.entries(toolOutput).every(\n ([key, value]) => validTypes.includes(typeof key) && isValidToolOutput(value),\n );\n }\n\n return false;\n}\n\nexport class ToolExecutionOutput {\n constructor(\n public readonly toolCall: FunctionCall,\n public readonly toolCallOutput: FunctionCallOutput | undefined,\n public readonly agentTask: Agent | undefined,\n public readonly rawOutput: unknown,\n public readonly rawException: Error | undefined,\n public readonly replyRequired: boolean,\n ) {}\n\n static create(params: {\n toolCall: FunctionCall;\n toolCallOutput?: FunctionCallOutput;\n agentTask?: Agent;\n rawOutput: unknown;\n rawException?: Error;\n replyRequired?: boolean;\n }) {\n const {\n toolCall,\n toolCallOutput,\n agentTask,\n rawOutput,\n rawException,\n replyRequired = true,\n } = params;\n return new ToolExecutionOutput(\n toolCall,\n toolCallOutput,\n agentTask,\n rawOutput,\n rawException,\n replyRequired,\n );\n }\n}\n\nexport interface ToolOutput {\n output: ToolExecutionOutput[];\n firstToolStartedFuture: Future<void>;\n}\n\n// TODO(brian): remove this class in favor of ToolExecutionOutput\nexport class _JsOutput {\n toolCall: FunctionCall;\n output: unknown;\n exception?: Error;\n\n #logger = log();\n\n constructor(toolCall: FunctionCall, output: unknown, exception: Error | undefined) {\n this.toolCall = toolCall;\n this.output = output;\n this.exception = exception;\n }\n\n static create(params: { toolCall: FunctionCall; output?: unknown; exception?: Error }) {\n const { toolCall, output = undefined, exception = undefined } = params;\n return new _JsOutput(toolCall, output, exception);\n }\n\n sanitize(): _SanitizedOutput {\n if (isToolError(this.exception)) {\n return _SanitizedOutput.create({\n toolCall: FunctionCall.create({ ...this.toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: this.toolCall.name,\n callId: this.toolCall.callId,\n output: this.exception.message,\n isError: true,\n }),\n });\n }\n\n if (isStopResponse(this.exception)) {\n return _SanitizedOutput.create({\n toolCall: FunctionCall.create({ ...this.toolCall }),\n });\n }\n\n if (this.exception !== undefined) {\n return _SanitizedOutput.create({\n toolCall: FunctionCall.create({ ...this.toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: this.toolCall.name,\n callId: this.toolCall.callId,\n output: 'An internal error occurred while executing the tool.', // Don't send the actual error message, as it may contain sensitive information\n isError: true,\n }),\n });\n }\n\n let agentTask: Agent | undefined = undefined;\n let toolOutput: unknown = this.output;\n if (isAgentHandoff(this.output)) {\n agentTask = this.output.agent;\n toolOutput = this.output.returns;\n }\n\n if (!isValidToolOutput(toolOutput)) {\n this.#logger.error(\n {\n callId: this.toolCall.callId,\n function: this.toolCall.name,\n },\n `AI function ${this.toolCall.name} returned an invalid output`,\n );\n return _SanitizedOutput.create({\n toolCall: FunctionCall.create({ ...this.toolCall }),\n toolCallOutput: undefined,\n });\n }\n\n return _SanitizedOutput.create({\n toolCall: FunctionCall.create({ ...this.toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: this.toolCall.name,\n callId: this.toolCall.callId,\n output: toolOutput !== undefined ? JSON.stringify(toolOutput) : '', // take the string representation of the output\n isError: false,\n }),\n replyRequired: toolOutput !== undefined, // require a reply if the tool returned an output\n agentTask,\n });\n }\n}\n\nexport function createToolOutput(params: {\n toolCall: FunctionCall;\n output?: unknown;\n exception?: Error;\n}): ToolExecutionOutput {\n const { toolCall, output, exception } = params;\n const logger = log();\n\n // support returning Exception instead of raising them (for devex purposes inside evals)\n let finalOutput = output;\n let finalException = exception;\n if (output instanceof Error) {\n finalException = output;\n finalOutput = undefined;\n }\n\n if (isToolError(finalException)) {\n return ToolExecutionOutput.create({\n toolCall: FunctionCall.create({ ...toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: toolCall.name,\n callId: toolCall.callId,\n output: finalException.message,\n isError: true,\n }),\n rawOutput: finalOutput,\n rawException: finalException,\n });\n }\n\n if (isStopResponse(finalException)) {\n return ToolExecutionOutput.create({\n toolCall: FunctionCall.create({ ...toolCall }),\n rawOutput: finalOutput,\n rawException: finalException,\n });\n }\n\n if (finalException !== undefined) {\n return ToolExecutionOutput.create({\n toolCall: FunctionCall.create({ ...toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: toolCall.name,\n callId: toolCall.callId,\n output: 'An internal error occurred', // Don't send the actual error message, as it may contain sensitive information\n isError: true,\n }),\n rawOutput: finalOutput,\n rawException: finalException,\n });\n }\n\n let agentTask: Agent | undefined = undefined;\n let toolOutput: unknown = finalOutput;\n if (isAgentHandoff(finalOutput)) {\n agentTask = finalOutput.agent;\n toolOutput = finalOutput.returns;\n }\n\n if (!isValidToolOutput(toolOutput)) {\n logger.error(\n {\n callId: toolCall.callId,\n output: finalOutput,\n },\n `AI function ${toolCall.name} returned an invalid output`,\n );\n return ToolExecutionOutput.create({\n toolCall: FunctionCall.create({ ...toolCall }),\n rawOutput: finalOutput,\n rawException: finalException,\n });\n }\n\n return ToolExecutionOutput.create({\n toolCall: FunctionCall.create({ ...toolCall }),\n toolCallOutput: FunctionCallOutput.create({\n name: toolCall.name,\n callId: toolCall.callId,\n output: toolOutput !== undefined ? JSON.stringify(toolOutput) : '', // take the string representation of the output\n isError: false,\n }),\n replyRequired: toolOutput !== undefined, // require a reply if the tool returned an output\n agentTask,\n rawOutput: finalOutput,\n rawException: finalException,\n });\n}\n\nconst INSTRUCTIONS_MESSAGE_ID = 'lk.agent_task.instructions';\n\n/**\n * Update the instruction message in the chat context or insert a new one if missing.\n *\n * This function looks for an existing instruction message in the chat context using the identifier\n * 'INSTRUCTIONS_MESSAGE_ID'.\n *\n * @param options - The options for updating the instructions.\n * @param options.chatCtx - The chat context to update.\n * @param options.instructions - The instructions to add.\n * @param options.addIfMissing - Whether to add the instructions if they are missing.\n */\nexport function updateInstructions(options: {\n chatCtx: ChatContext;\n instructions: string;\n addIfMissing: boolean;\n}) {\n const { chatCtx, instructions, addIfMissing } = options;\n\n const idx = chatCtx.indexById(INSTRUCTIONS_MESSAGE_ID);\n if (idx !== undefined) {\n if (chatCtx.items[idx]!.type === 'message') {\n // create a new instance to avoid mutating the original\n chatCtx.items[idx] = ChatMessage.create({\n id: INSTRUCTIONS_MESSAGE_ID,\n role: 'system',\n content: [instructions],\n createdAt: chatCtx.items[idx]!.createdAt,\n });\n } else {\n throw new Error('expected the instructions inside the chatCtx to be of type \"message\"');\n }\n } else if (addIfMissing) {\n // insert the instructions at the beginning of the chat context\n chatCtx.items.unshift(\n ChatMessage.create({\n id: INSTRUCTIONS_MESSAGE_ID,\n role: 'system',\n content: [instructions],\n }),\n );\n }\n}\n\nexport function performLLMInference(\n node: LLMNode,\n chatCtx: ChatContext,\n toolCtx: ToolContext,\n modelSettings: ModelSettings,\n controller: AbortController,\n model?: string,\n provider?: string,\n): [Task<void>, _LLMGenerationData] {\n const textStream = new IdentityTransform<string>();\n const toolCallStream = new IdentityTransform<FunctionCall>();\n\n const textWriter = textStream.writable.getWriter();\n const toolCallWriter = toolCallStream.writable.getWriter();\n const data = new _LLMGenerationData(textStream.readable, toolCallStream.readable);\n\n const _performLLMInferenceImpl = async (signal: AbortSignal, span: Span) => {\n span.setAttribute(\n traceTypes.ATTR_CHAT_CTX,\n JSON.stringify(chatCtx.toJSON({ excludeTimestamp: false })),\n );\n span.setAttribute(traceTypes.ATTR_FUNCTION_TOOLS, JSON.stringify(Object.keys(toolCtx)));\n\n if (model) {\n span.setAttribute(traceTypes.ATTR_GEN_AI_REQUEST_MODEL, model);\n }\n if (provider) {\n span.setAttribute(traceTypes.ATTR_GEN_AI_PROVIDER_NAME, provider);\n }\n\n let llmStreamReader: ReadableStreamDefaultReader<string | ChatChunk> | null = null;\n let llmStream: ReadableStream<string | ChatChunk> | null = null;\n const startTime = performance.now() / 1000; // Convert to seconds\n let firstTokenReceived = false;\n\n try {\n llmStream = await node(chatCtx, toolCtx, modelSettings);\n if (llmStream === null) {\n await textWriter.close();\n return;\n }\n\n const abortPromise = waitForAbort(signal);\n\n // TODO(brian): add support for dynamic tools\n\n llmStreamReader = llmStream.getReader();\n while (true) {\n if (signal.aborted) break;\n\n const result = await Promise.race([llmStreamReader.read(), abortPromise]);\n if (result === undefined) break;\n\n const { done, value: chunk } = result;\n if (done) break;\n\n if (!firstTokenReceived) {\n firstTokenReceived = true;\n data.ttft = performance.now() / 1000 - startTime;\n }\n\n if (typeof chunk === 'string') {\n data.generatedText += chunk;\n await textWriter.write(chunk);\n // TODO(shubhra): better way to check??\n } else {\n if (chunk.delta === undefined) {\n continue;\n }\n\n if (chunk.delta.toolCalls) {\n for (const tool of chunk.delta.toolCalls) {\n if (tool.type !== 'function_call') continue;\n\n const toolCall = FunctionCall.create({\n callId: `${data.id}/fnc_${data.generatedToolCalls.length}`,\n name: tool.name,\n args: tool.args,\n // Preserve thought signature for Gemini 3+ thinking mode\n thoughtSignature: tool.thoughtSignature,\n extra: tool.extra || {},\n });\n\n data.generatedToolCalls.push(toolCall);\n await toolCallWriter.write(toolCall);\n }\n }\n\n if (chunk.delta.content) {\n data.generatedText += chunk.delta.content;\n await textWriter.write(chunk.delta.content);\n }\n }\n\n // No need to check if chunk is of type other than ChatChunk or string like in\n // Python since chunk is defined in the type ChatChunk | string in TypeScript\n }\n\n span.setAttribute(traceTypes.ATTR_RESPONSE_TEXT, data.generatedText);\n if (data.ttft !== undefined) {\n span.setAttribute(traceTypes.ATTR_RESPONSE_TTFT, data.ttft);\n }\n } catch (error) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n // Abort signal was triggered, handle gracefully\n return;\n }\n throw error;\n } finally {\n llmStreamReader?.releaseLock();\n await llmStream?.cancel();\n await textWriter.close();\n await toolCallWriter.close();\n }\n };\n\n // Capture the current context (agent_turn) to ensure llm_node is properly parented\n const currentContext = otelContext.active();\n\n const inferenceTask = async (signal: AbortSignal) =>\n tracer.startActiveSpan(async (span) => _performLLMInferenceImpl(signal, span), {\n name: 'llm_node',\n context: currentContext,\n });\n\n return [\n Task.from((controller) => inferenceTask(controller.signal), controller, 'performLLMInference'),\n data,\n ];\n}\n\nexport function performTTSInference(\n node: TTSNode,\n text: ReadableStream<string | TimedString>,\n modelSettings: ModelSettings,\n controller: AbortController,\n model?: string,\n provider?: string,\n): [Task<void>, _TTSGenerationData] {\n const audioStream = new IdentityTransform<AudioFrame>();\n const outputWriter = audioStream.writable.getWriter();\n const audioOutputStream = audioStream.readable;\n\n const timedTextsFut = new Future<ReadableStream<TimedString> | null>();\n const timedTextsStream = new IdentityTransform<TimedString>();\n const timedTextsWriter = timedTextsStream.writable.getWriter();\n\n // Transform stream to extract text from TimedString objects\n const textOnlyStream = new IdentityTransform<string>();\n const textOnlyWriter = textOnlyStream.writable.getWriter();\n (async () => {\n const reader = text.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n const textValue = typeof value === 'string' ? value : value.text;\n await textOnlyWriter.write(textValue);\n }\n await textOnlyWriter.close();\n } catch (e) {\n await textOnlyWriter.abort(e as Error);\n } finally {\n reader.releaseLock();\n }\n })();\n\n let ttfb: number | undefined;\n\n const genData: _TTSGenerationData = {\n audioStream: audioOutputStream,\n timedTextsFut,\n ttfb: undefined,\n };\n\n const _performTTSInferenceImpl = async (signal: AbortSignal, span: Span) => {\n if (model) {\n span.setAttribute(traceTypes.ATTR_GEN_AI_REQUEST_MODEL, model);\n }\n if (provider) {\n span.setAttribute(traceTypes.ATTR_GEN_AI_PROVIDER_NAME, provider);\n }\n\n let ttsStreamReader: ReadableStreamDefaultReader<AudioFrame> | null = null;\n let ttsStream: ReadableStream<AudioFrame> | null = null;\n let pushedDuration = 0;\n const startTime = performance.now() / 1000; // Convert to seconds\n let firstByteReceived = false;\n\n try {\n ttsStream = await node(textOnlyStream.readable, modelSettings);\n if (ttsStream === null) {\n timedTextsFut.resolve(null);\n await outputWriter.close();\n await timedTextsWriter.close();\n return;\n }\n\n // This is critical: the future must be resolved with the channel/stream before the loop\n // so that agent_activity can start reading while we write\n if (!timedTextsFut.done) {\n timedTextsFut.resolve(timedTextsStream.readable);\n }\n\n ttsStreamReader = ttsStream.getReader();\n\n // In Python, perform_tts_inference has a while loop processing multiple input segments\n // (separated by FlushSentinel), with pushed_duration accumulating across segments.\n // JS currently only does single inference, so initialPushedDuration is always 0.\n // TODO: Add FlushSentinel + multi-segment loop\n const initialPushedDuration = pushedDuration;\n\n while (true) {\n if (signal.aborted) {\n break;\n }\n const { done, value: frame } = await ttsStreamReader.read();\n if (done) {\n break;\n }\n\n if (!firstByteReceived) {\n firstByteReceived = true;\n ttfb = performance.now() / 1000 - startTime;\n genData.ttfb = ttfb;\n span.setAttribute(traceTypes.ATTR_RESPONSE_TTFB, ttfb);\n }\n\n // Write the audio frame to the output stream\n await outputWriter.write(frame);\n\n const timedTranscripts = frame.userdata[USERDATA_TIMED_TRANSCRIPT] as\n | TimedString[]\n | undefined;\n if (timedTranscripts && timedTranscripts.length > 0) {\n for (const timedText of timedTranscripts) {\n // Uses the INITIAL value (from previous inferences), not the accumulated value\n const adjustedTimedText = createTimedString({\n text: timedText.text,\n startTime:\n timedText.startTime !== undefined\n ? timedText.startTime + initialPushedDuration\n : undefined,\n endTime:\n timedText.endTime !== undefined\n ? timedText.endTime + initialPushedDuration\n : undefined,\n confidence: timedText.confidence,\n startTimeOffset: timedText.startTimeOffset,\n });\n await timedTextsWriter.write(adjustedTimedText);\n }\n }\n\n const frameDuration = frame.samplesPerChannel / frame.sampleRate;\n pushedDuration += frameDuration;\n }\n } catch (error) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n // Abort signal was triggered, handle gracefully\n return;\n }\n throw error;\n } finally {\n if (!timedTextsFut.done) {\n // Ensure downstream consumers don't hang on errors.\n timedTextsFut.resolve(null);\n }\n ttsStreamReader?.releaseLock();\n await ttsStream?.cancel();\n await outputWriter.close();\n await timedTextsWriter.close();\n }\n };\n\n // Capture the current context (agent_turn) to ensure tts_node is properly parented\n const currentContext = otelContext.active();\n\n const inferenceTask = async (signal: AbortSignal) =>\n tracer.startActiveSpan(async (span) => _performTTSInferenceImpl(signal, span), {\n name: 'tts_node',\n context: currentContext,\n });\n\n return [\n Task.from((controller) => inferenceTask(controller.signal), controller, 'performTTSInference'),\n genData,\n ];\n}\n\nexport interface _TextOut {\n text: string;\n firstTextFut: Future;\n}\n\nasync function forwardText(\n source: ReadableStream<string | TimedString>,\n out: _TextOut,\n signal: AbortSignal,\n textOutput: TextOutput | null,\n): Promise<void> {\n const reader = source.getReader();\n try {\n while (true) {\n if (signal.aborted) {\n break;\n }\n const { done, value: delta } = await reader.read();\n if (done) break;\n\n const deltaIsTimedString = isTimedString(delta);\n const textDelta = deltaIsTimedString ? delta.text : delta;\n\n out.text += textDelta;\n if (textOutput !== null) {\n // Pass TimedString to textOutput for synchronized transcription\n await textOutput.captureText(delta);\n }\n if (!out.firstTextFut.done) {\n out.firstTextFut.resolve();\n }\n }\n } finally {\n if (textOutput !== null) {\n textOutput.flush();\n }\n reader?.releaseLock();\n }\n}\n\nexport function performTextForwarding(\n source: ReadableStream<string | TimedString>,\n controller: AbortController,\n textOutput: TextOutput | null,\n): [Task<void>, _TextOut] {\n const out = {\n text: '',\n firstTextFut: new Future(),\n };\n return [\n Task.from(\n (controller) => forwardText(source, out, controller.signal, textOutput),\n controller,\n 'performTextForwarding',\n ),\n out,\n ];\n}\n\nexport interface _AudioOut {\n audio: Array<AudioFrame>;\n firstFrameFut: Future<number>;\n}\n\nasync function forwardAudio(\n ttsStream: ReadableStream<AudioFrame>,\n audioOutput: AudioOutput,\n out: _AudioOut,\n signal?: AbortSignal,\n): Promise<void> {\n const reader = ttsStream.getReader();\n let resampler: AudioResampler | null = null;\n\n const onPlaybackStarted = (ev: { createdAt: number }) => {\n if (!out.firstFrameFut.done) {\n out.firstFrameFut.resolve(ev.createdAt);\n }\n };\n\n try {\n audioOutput.on(AudioOutput.EVENT_PLAYBACK_STARTED, onPlaybackStarted);\n audioOutput.resume();\n\n while (true) {\n if (signal?.aborted) {\n break;\n }\n\n const { done, value: frame } = await reader.read();\n if (done) break;\n\n out.audio.push(frame);\n\n if (\n !out.firstFrameFut.done &&\n audioOutput.sampleRate &&\n audioOutput.sampleRate !== frame.sampleRate &&\n !resampler\n ) {\n resampler = new AudioResampler(frame.sampleRate, audioOutput.sampleRate, 1);\n }\n\n if (resampler) {\n for (const f of resampler.push(frame)) {\n await audioOutput.captureFrame(f);\n }\n } else {\n await audioOutput.captureFrame(frame);\n }\n }\n\n if (resampler) {\n for (const f of resampler.flush()) {\n await audioOutput.captureFrame(f);\n }\n }\n } finally {\n audioOutput.off(AudioOutput.EVENT_PLAYBACK_STARTED, onPlaybackStarted);\n\n if (!out.firstFrameFut.done) {\n out.firstFrameFut.reject(new Error('audio forwarding cancelled before playback started'));\n }\n\n reader?.releaseLock();\n audioOutput.flush();\n }\n}\n\nexport function performAudioForwarding(\n ttsStream: ReadableStream<AudioFrame>,\n audioOutput: AudioOutput,\n controller: AbortController,\n): [Task<void>, _AudioOut] {\n const out: _AudioOut = {\n audio: [],\n firstFrameFut: new Future<number>(),\n };\n\n return [\n Task.from(\n (controller) => forwardAudio(ttsStream, audioOutput, out, controller.signal),\n controller,\n 'performAudioForwarding',\n ),\n out,\n ];\n}\n\nexport function performToolExecutions({\n session,\n speechHandle,\n toolCtx,\n toolChoice,\n toolCallStream,\n onToolExecutionStarted = () => {},\n onToolExecutionCompleted = () => {},\n controller,\n}: {\n session: AgentSession;\n speechHandle: SpeechHandle;\n toolCtx: ToolContext;\n toolChoice?: ToolChoice;\n toolCallStream: ReadableStream<FunctionCall>;\n onToolExecutionStarted?: (toolCall: FunctionCall) => void;\n onToolExecutionCompleted?: (toolExecutionOutput: ToolExecutionOutput) => void;\n controller: AbortController;\n}): [Task<void>, ToolOutput] {\n const logger = log();\n const toolOutput: ToolOutput = {\n output: [],\n firstToolStartedFuture: new Future(),\n };\n\n const toolCompleted = (out: ToolExecutionOutput) => {\n onToolExecutionCompleted(out);\n toolOutput.output.push(out);\n };\n\n const executeToolsTask = async (controller: AbortController) => {\n const signal = controller.signal;\n const reader = toolCallStream.getReader();\n\n const tasks: Task<void>[] = [];\n while (!signal.aborted) {\n const { done, value: toolCall } = await reader.read();\n if (signal.aborted) break;\n if (done) break;\n\n if (toolChoice === 'none') {\n logger.error(\n {\n function: toolCall.name,\n speech_id: speechHandle.id,\n },\n \"received a tool call with toolChoice set to 'none', ignoring\",\n );\n continue;\n }\n\n // TODO(brian): assert other toolChoice values\n\n const tool = toolCtx[toolCall.name];\n if (!tool) {\n logger.warn(\n {\n function: toolCall.name,\n speech_id: speechHandle.id,\n },\n `unknown AI function ${toolCall.name}`,\n );\n continue;\n }\n\n if (!isFunctionTool(tool)) {\n logger.error(\n {\n function: toolCall.name,\n speech_id: speechHandle.id,\n },\n `unknown tool type: ${typeof tool}`,\n );\n continue;\n }\n\n let parsedArgs: object | undefined;\n\n // Ensure valid arguments\n try {\n const jsonArgs = JSON.parse(toolCall.args);\n\n if (isZodSchema(tool.parameters)) {\n const result = await parseZodSchema<object>(tool.parameters, jsonArgs);\n if (result.success) {\n parsedArgs = result.data;\n } else {\n throw result.error;\n }\n } else {\n parsedArgs = jsonArgs;\n }\n } catch (rawError) {\n const error = toError(rawError);\n logger.error(\n {\n function: toolCall.name,\n arguments: toolCall.args,\n speech_id: speechHandle.id,\n error: error.message,\n },\n `tried to call AI function ${toolCall.name} with invalid arguments`,\n );\n toolCompleted(\n createToolOutput({\n toolCall,\n exception: error,\n }),\n );\n continue;\n }\n\n if (!toolOutput.firstToolStartedFuture.done) {\n toolOutput.firstToolStartedFuture.resolve();\n }\n\n onToolExecutionStarted(toolCall);\n\n logger.info(\n {\n function: toolCall.name,\n arguments: parsedArgs,\n speech_id: speechHandle.id,\n },\n 'Executing LLM tool call',\n );\n\n const _tracableToolExecutionImpl = async (toolExecTask: Promise<unknown>, span: Span) => {\n span.setAttribute(traceTypes.ATTR_FUNCTION_TOOL_NAME, toolCall.name);\n span.setAttribute(traceTypes.ATTR_FUNCTION_TOOL_ARGS, toolCall.args);\n\n // await for task to complete, if task is aborted, set exception\n let toolOutput: ToolExecutionOutput | undefined;\n try {\n const { result, isAborted } = await waitUntilAborted(toolExecTask, signal);\n toolOutput = createToolOutput({\n toolCall,\n exception: isAborted ? new Error('tool call was aborted') : undefined,\n output: isAborted ? undefined : result,\n });\n\n if (toolOutput.toolCallOutput) {\n span.setAttribute(\n traceTypes.ATTR_FUNCTION_TOOL_OUTPUT,\n toolOutput.toolCallOutput.output,\n );\n span.setAttribute(\n traceTypes.ATTR_FUNCTION_TOOL_IS_ERROR,\n toolOutput.toolCallOutput.isError,\n );\n }\n } catch (rawError) {\n logger.error(\n {\n function: toolCall.name,\n speech_id: speechHandle.id,\n error: toError(rawError).message,\n },\n 'exception occurred while executing tool',\n );\n toolOutput = createToolOutput({\n toolCall,\n exception: toError(rawError),\n });\n\n if (toolOutput.toolCallOutput) {\n span.setAttribute(\n traceTypes.ATTR_FUNCTION_TOOL_OUTPUT,\n toolOutput.toolCallOutput.output,\n );\n span.setAttribute(traceTypes.ATTR_FUNCTION_TOOL_IS_ERROR, true);\n }\n } finally {\n if (!toolOutput) throw new Error('toolOutput is undefined');\n toolCompleted(toolOutput);\n }\n };\n\n const tracableToolExecution = (toolExecTask: Promise<unknown>) =>\n tracer.startActiveSpan(async (span) => _tracableToolExecutionImpl(toolExecTask, span), {\n name: 'function_tool',\n });\n\n const toolTask = Task.from(\n async () => {\n // Ensure this task is marked inline before user tool code executes.\n const currentTask = Task.current();\n if (currentTask) {\n _setActivityTaskInfo(currentTask, {\n speechHandle,\n functionCall: toolCall,\n inlineTask: true,\n });\n }\n\n const toolExecution = functionCallStorage.run({ functionCall: toolCall }, async () => {\n return await tool.execute(parsedArgs, {\n ctx: new RunContext(session, speechHandle, toolCall),\n toolCallId: toolCall.callId,\n abortSignal: signal,\n });\n });\n\n await tracableToolExecution(toolExecution);\n },\n controller,\n `performToolExecution:${toolCall.name}`,\n );\n\n _setActivityTaskInfo(toolTask, {\n speechHandle,\n functionCall: toolCall,\n inlineTask: true,\n });\n // wait, not cancelling all tool calling tasks\n tasks.push(toolTask);\n }\n\n await Promise.allSettled(tasks.map((task) => task.result));\n if (toolOutput.output.length > 0) {\n logger.debug(\n {\n speech_id: speechHandle.id,\n },\n 'tools execution completed',\n );\n }\n };\n\n return [Task.from(executeToolsTask, controller, 'performToolExecutions'), toolOutput];\n}\n\ntype Aborted<T> =\n | {\n result: T;\n isAborted: false;\n }\n | {\n result: undefined;\n isAborted: true;\n };\n\nasync function waitUntilAborted<T>(promise: Promise<T>, signal: AbortSignal): Promise<Aborted<T>> {\n const abortFut = new Future<Aborted<T>>();\n\n const resolveAbort = () => {\n if (!abortFut.done) {\n abortFut.resolve({ result: undefined, isAborted: true });\n }\n };\n\n signal.addEventListener('abort', resolveAbort);\n\n promise\n .then((r) => {\n if (!abortFut.done) {\n abortFut.resolve({ result: r, isAborted: false });\n }\n })\n .catch((e) => {\n if (!abortFut.done) {\n abortFut.reject(e);\n }\n })\n .finally(() => {\n signal.removeEventListener('abort', resolveAbort);\n });\n\n return await abortFut.await;\n}\n\nexport function removeInstructions(chatCtx: ChatContext) {\n // loop in case there are items with the same id (shouldn't happen!)\n while (true) {\n const idx = chatCtx.indexById(INSTRUCTIONS_MESSAGE_ID);\n if (idx !== undefined) {\n chatCtx.items.splice(idx, 1);\n } else {\n break;\n }\n }\n}\n"],"mappings":"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","names":["controller","toolOutput"]}
@@ -41,6 +41,7 @@ var import_agent = require("./agent.cjs");
41
41
  var import_agent_session = require("./agent_session.cjs");
42
42
  __reExport(voice_exports, require("./avatar/index.cjs"), module.exports);
43
43
  __reExport(voice_exports, require("./background_audio.cjs"), module.exports);
44
+ var import_client_events = require("./client_events.cjs");
44
45
  __reExport(voice_exports, require("./events.cjs"), module.exports);
45
46
  var import_io = require("./io.cjs");
46
47
  __reExport(voice_exports, require("./report.cjs"), module.exports);
@@ -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, 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 * 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAAsF;AACtF,2BAA0E;AAC1E,0BAAc,8BALd;AAMA,0BAAc,kCANd;AAOA,0BAAc,wBAPd;AAQA,gBAAiC;AACjC,0BAAc,wBATd;AAUA,0BAAc,+BAVd;AAWA,yBAA2B;AAC3B,cAAyB;","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 { type TextInputCallback, type TextInputEvent } from './client_events.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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAAsF;AACtF,2BAA0E;AAC1E,0BAAc,8BALd;AAMA,0BAAc,kCANd;AAOA,2BAA4D;AAC5D,0BAAc,wBARd;AASA,gBAAiC;AACjC,0BAAc,wBAVd;AAWA,0BAAc,+BAXd;AAYA,yBAA2B;AAC3B,cAAyB;","names":[]}
@@ -2,6 +2,7 @@ export { Agent, AgentTask, StopResponse, type AgentOptions, type ModelSettings }
2
2
  export { AgentSession, type AgentSessionOptions, type VoiceOptions } from './agent_session.js';
3
3
  export * from './avatar/index.js';
4
4
  export * from './background_audio.js';
5
+ export { type TextInputCallback, type TextInputEvent } from './client_events.js';
5
6
  export * from './events.js';
6
7
  export { type TimedString } from './io.js';
7
8
  export * from './report.js';
@@ -2,6 +2,7 @@ export { Agent, AgentTask, StopResponse, type AgentOptions, type ModelSettings }
2
2
  export { AgentSession, type AgentSessionOptions, type VoiceOptions } from './agent_session.js';
3
3
  export * from './avatar/index.js';
4
4
  export * from './background_audio.js';
5
+ export { type TextInputCallback, type TextInputEvent } from './client_events.js';
5
6
  export * from './events.js';
6
7
  export { type TimedString } from './io.js';
7
8
  export * from './report.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/voice/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AACnG,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC/F,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/voice/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AACnG,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC/F,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACjF,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC"}
@@ -2,6 +2,7 @@ import { Agent, AgentTask, StopResponse } from "./agent.js";
2
2
  import { AgentSession } from "./agent_session.js";
3
3
  export * from "./avatar/index.js";
4
4
  export * from "./background_audio.js";
5
+ import {} from "./client_events.js";
5
6
  export * from "./events.js";
6
7
  import {} from "./io.js";
7
8
  export * from "./report.js";
@@ -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, 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 * 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,cAAc;AACd,eAAiC;AACjC,cAAc;AACd,cAAc;AACd,SAAS,kBAAkB;AAC3B,YAAY,aAAa;","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 { type TextInputCallback, type TextInputEvent } from './client_events.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,eAA4D;AAC5D,cAAc;AACd,eAAiC;AACjC,cAAc;AACd,cAAc;AACd,SAAS,kBAAkB;AAC3B,YAAY,aAAa;","names":[]}
@@ -22,6 +22,7 @@ __export(report_exports, {
22
22
  sessionReportToJSON: () => sessionReportToJSON
23
23
  });
24
24
  module.exports = __toCommonJS(report_exports);
25
+ var import_model_usage = require("../metrics/model_usage.cjs");
25
26
  function createSessionReport(opts) {
26
27
  const timestamp = opts.timestamp ?? Date.now();
27
28
  const audioRecordingStartedAt = opts.audioRecordingStartedAt;
@@ -37,11 +38,21 @@ function createSessionReport(opts) {
37
38
  timestamp,
38
39
  audioRecordingPath: opts.audioRecordingPath,
39
40
  audioRecordingStartedAt,
40
- duration: audioRecordingStartedAt !== void 0 ? timestamp - audioRecordingStartedAt : void 0
41
+ duration: audioRecordingStartedAt !== void 0 ? timestamp - audioRecordingStartedAt : void 0,
42
+ modelUsage: opts.modelUsage
41
43
  };
42
44
  }
43
45
  function sessionReportToJSON(report) {
46
+ var _a, _b;
44
47
  const events = [];
48
+ const interruptionConfig = (_a = report.options.turnHandling) == null ? void 0 : _a.interruption;
49
+ const endpointingConfig = (_b = report.options.turnHandling) == null ? void 0 : _b.endpointing;
50
+ const allowInterruptions = (interruptionConfig == null ? void 0 : interruptionConfig.mode) !== void 0 ? interruptionConfig.mode !== false : report.options.allowInterruptions;
51
+ const discardAudioIfUninterruptible = (interruptionConfig == null ? void 0 : interruptionConfig.discardAudioIfUninterruptible) ?? report.options.discardAudioIfUninterruptible;
52
+ const minInterruptionDuration = (interruptionConfig == null ? void 0 : interruptionConfig.minDuration) ?? report.options.minInterruptionDuration;
53
+ const minInterruptionWords = (interruptionConfig == null ? void 0 : interruptionConfig.minWords) ?? report.options.minInterruptionWords;
54
+ const minEndpointingDelay = (endpointingConfig == null ? void 0 : endpointingConfig.minDelay) ?? report.options.minEndpointingDelay;
55
+ const maxEndpointingDelay = (endpointingConfig == null ? void 0 : endpointingConfig.maxDelay) ?? report.options.maxEndpointingDelay;
45
56
  for (const event of report.events) {
46
57
  if (event.type === "metrics_collected") {
47
58
  continue;
@@ -54,17 +65,18 @@ function sessionReportToJSON(report) {
54
65
  room: report.room,
55
66
  events,
56
67
  options: {
57
- allow_interruptions: report.options.allowInterruptions,
58
- discard_audio_if_uninterruptible: report.options.discardAudioIfUninterruptible,
59
- min_interruption_duration: report.options.minInterruptionDuration,
60
- min_interruption_words: report.options.minInterruptionWords,
61
- min_endpointing_delay: report.options.minEndpointingDelay,
62
- max_endpointing_delay: report.options.maxEndpointingDelay,
68
+ allow_interruptions: allowInterruptions,
69
+ discard_audio_if_uninterruptible: discardAudioIfUninterruptible,
70
+ min_interruption_duration: minInterruptionDuration,
71
+ min_interruption_words: minInterruptionWords,
72
+ min_endpointing_delay: minEndpointingDelay,
73
+ max_endpointing_delay: maxEndpointingDelay,
63
74
  max_tool_steps: report.options.maxToolSteps
64
75
  },
65
76
  chat_history: report.chatHistory.toJSON({ excludeTimestamp: false }),
66
77
  enable_user_data_training: report.enableRecording,
67
- timestamp: report.timestamp
78
+ timestamp: report.timestamp,
79
+ usage: report.modelUsage ? report.modelUsage.map(import_model_usage.filterZeroValues) : null
68
80
  };
69
81
  }
70
82
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/voice/report.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { ChatContext } from '../llm/chat_context.js';\nimport type { VoiceOptions } from './agent_session.js';\nimport type { AgentEvent } from './events.js';\n\nexport interface SessionReport {\n jobId: string;\n roomId: string;\n room: string;\n options: VoiceOptions;\n events: AgentEvent[];\n chatHistory: ChatContext;\n enableRecording: boolean;\n /** Timestamp when the session started (milliseconds) */\n startedAt: number;\n /** Timestamp when the session report was created (milliseconds), typically at the end of the session */\n timestamp: number;\n /** Path to the audio recording file (if recording was enabled) */\n audioRecordingPath?: string;\n /** Timestamp when the audio recording started (milliseconds) */\n audioRecordingStartedAt?: number;\n /** Duration of the session in milliseconds */\n duration?: number;\n}\n\nexport interface SessionReportOptions {\n jobId: string;\n roomId: string;\n room: string;\n options: VoiceOptions;\n events: AgentEvent[];\n chatHistory: ChatContext;\n enableRecording?: boolean;\n /** Timestamp when the session started (milliseconds) */\n startedAt?: number;\n /** Timestamp when the session report was created (milliseconds) */\n timestamp?: number;\n /** Path to the audio recording file (if recording was enabled) */\n audioRecordingPath?: string;\n /** Timestamp when the audio recording started (milliseconds) */\n audioRecordingStartedAt?: number;\n}\n\nexport function createSessionReport(opts: SessionReportOptions): SessionReport {\n const timestamp = opts.timestamp ?? Date.now();\n const audioRecordingStartedAt = opts.audioRecordingStartedAt;\n\n return {\n jobId: opts.jobId,\n roomId: opts.roomId,\n room: opts.room,\n options: opts.options,\n events: opts.events,\n chatHistory: opts.chatHistory,\n enableRecording: opts.enableRecording ?? false,\n startedAt: opts.startedAt ?? Date.now(),\n timestamp,\n audioRecordingPath: opts.audioRecordingPath,\n audioRecordingStartedAt,\n duration:\n audioRecordingStartedAt !== undefined ? timestamp - audioRecordingStartedAt : undefined,\n };\n}\n\n// - header: protobuf MetricsRecordingHeader (room_id, duration, start_time)\n// - chat_history: JSON serialized chat history (use sessionReportToJSON)\n// - audio: audio recording file if available (ogg format)\n// - Uploads to LiveKit Cloud observability endpoint with JWT auth\nexport function sessionReportToJSON(report: SessionReport): Record<string, unknown> {\n const events: Record<string, unknown>[] = [];\n\n for (const event of report.events) {\n if (event.type === 'metrics_collected') {\n continue; // metrics are too noisy, Cloud is using the chat_history as the source of truth\n }\n\n events.push({ ...event });\n }\n\n return {\n job_id: report.jobId,\n room_id: report.roomId,\n room: report.room,\n events,\n options: {\n allow_interruptions: report.options.allowInterruptions,\n discard_audio_if_uninterruptible: report.options.discardAudioIfUninterruptible,\n min_interruption_duration: report.options.minInterruptionDuration,\n min_interruption_words: report.options.minInterruptionWords,\n min_endpointing_delay: report.options.minEndpointingDelay,\n max_endpointing_delay: report.options.maxEndpointingDelay,\n max_tool_steps: report.options.maxToolSteps,\n },\n chat_history: report.chatHistory.toJSON({ excludeTimestamp: false }),\n enable_user_data_training: report.enableRecording,\n timestamp: report.timestamp,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6CO,SAAS,oBAAoB,MAA2C;AAC7E,QAAM,YAAY,KAAK,aAAa,KAAK,IAAI;AAC7C,QAAM,0BAA0B,KAAK;AAErC,SAAO;AAAA,IACL,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,IACb,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,QAAQ,KAAK;AAAA,IACb,aAAa,KAAK;AAAA,IAClB,iBAAiB,KAAK,mBAAmB;AAAA,IACzC,WAAW,KAAK,aAAa,KAAK,IAAI;AAAA,IACtC;AAAA,IACA,oBAAoB,KAAK;AAAA,IACzB;AAAA,IACA,UACE,4BAA4B,SAAY,YAAY,0BAA0B;AAAA,EAClF;AACF;AAMO,SAAS,oBAAoB,QAAgD;AAClF,QAAM,SAAoC,CAAC;AAE3C,aAAW,SAAS,OAAO,QAAQ;AACjC,QAAI,MAAM,SAAS,qBAAqB;AACtC;AAAA,IACF;AAEA,WAAO,KAAK,EAAE,GAAG,MAAM,CAAC;AAAA,EAC1B;AAEA,SAAO;AAAA,IACL,QAAQ,OAAO;AAAA,IACf,SAAS,OAAO;AAAA,IAChB,MAAM,OAAO;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,qBAAqB,OAAO,QAAQ;AAAA,MACpC,kCAAkC,OAAO,QAAQ;AAAA,MACjD,2BAA2B,OAAO,QAAQ;AAAA,MAC1C,wBAAwB,OAAO,QAAQ;AAAA,MACvC,uBAAuB,OAAO,QAAQ;AAAA,MACtC,uBAAuB,OAAO,QAAQ;AAAA,MACtC,gBAAgB,OAAO,QAAQ;AAAA,IACjC;AAAA,IACA,cAAc,OAAO,YAAY,OAAO,EAAE,kBAAkB,MAAM,CAAC;AAAA,IACnE,2BAA2B,OAAO;AAAA,IAClC,WAAW,OAAO;AAAA,EACpB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/voice/report.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { ChatContext } from '../llm/chat_context.js';\nimport { type ModelUsage, filterZeroValues } from '../metrics/model_usage.js';\nimport type { VoiceOptions } from './agent_session.js';\nimport type { AgentEvent } from './events.js';\n\nexport interface SessionReport {\n jobId: string;\n roomId: string;\n room: string;\n options: VoiceOptions;\n events: AgentEvent[];\n chatHistory: ChatContext;\n enableRecording: boolean;\n /** Timestamp when the session started (milliseconds) */\n startedAt: number;\n /** Timestamp when the session report was created (milliseconds), typically at the end of the session */\n timestamp: number;\n /** Path to the audio recording file (if recording was enabled) */\n audioRecordingPath?: string;\n /** Timestamp when the audio recording started (milliseconds) */\n audioRecordingStartedAt?: number;\n /** Duration of the session in milliseconds */\n duration?: number;\n /** Usage summaries for the session, one per model/provider combination */\n modelUsage?: ModelUsage[];\n}\n\nexport interface SessionReportOptions {\n jobId: string;\n roomId: string;\n room: string;\n options: VoiceOptions;\n events: AgentEvent[];\n chatHistory: ChatContext;\n enableRecording?: boolean;\n /** Timestamp when the session started (milliseconds) */\n startedAt?: number;\n /** Timestamp when the session report was created (milliseconds) */\n timestamp?: number;\n /** Path to the audio recording file (if recording was enabled) */\n audioRecordingPath?: string;\n /** Timestamp when the audio recording started (milliseconds) */\n audioRecordingStartedAt?: number;\n /** Usage summaries for the session, one per model/provider combination */\n modelUsage?: ModelUsage[];\n}\n\nexport function createSessionReport(opts: SessionReportOptions): SessionReport {\n const timestamp = opts.timestamp ?? Date.now();\n const audioRecordingStartedAt = opts.audioRecordingStartedAt;\n\n return {\n jobId: opts.jobId,\n roomId: opts.roomId,\n room: opts.room,\n options: opts.options,\n events: opts.events,\n chatHistory: opts.chatHistory,\n enableRecording: opts.enableRecording ?? false,\n startedAt: opts.startedAt ?? Date.now(),\n timestamp,\n audioRecordingPath: opts.audioRecordingPath,\n audioRecordingStartedAt,\n duration:\n audioRecordingStartedAt !== undefined ? timestamp - audioRecordingStartedAt : undefined,\n modelUsage: opts.modelUsage,\n };\n}\n\n// - header: protobuf MetricsRecordingHeader (room_id, duration, start_time)\n// - chat_history: JSON serialized chat history (use sessionReportToJSON)\n// - audio: audio recording file if available (ogg format)\n// - Uploads to LiveKit Cloud observability endpoint with JWT auth\nexport function sessionReportToJSON(report: SessionReport): Record<string, unknown> {\n const events: Record<string, unknown>[] = [];\n const interruptionConfig = report.options.turnHandling?.interruption;\n const endpointingConfig = report.options.turnHandling?.endpointing;\n\n // Keep backwards compatibility with deprecated fields\n const allowInterruptions =\n interruptionConfig?.mode !== undefined\n ? interruptionConfig.mode !== false\n : report.options.allowInterruptions;\n const discardAudioIfUninterruptible =\n interruptionConfig?.discardAudioIfUninterruptible ??\n report.options.discardAudioIfUninterruptible;\n const minInterruptionDuration =\n interruptionConfig?.minDuration ?? report.options.minInterruptionDuration;\n const minInterruptionWords = interruptionConfig?.minWords ?? report.options.minInterruptionWords;\n const minEndpointingDelay = endpointingConfig?.minDelay ?? report.options.minEndpointingDelay;\n const maxEndpointingDelay = endpointingConfig?.maxDelay ?? report.options.maxEndpointingDelay;\n\n for (const event of report.events) {\n if (event.type === 'metrics_collected') {\n continue; // metrics are too noisy, Cloud is using the chat_history as the source of truth\n }\n\n events.push({ ...event });\n }\n\n return {\n job_id: report.jobId,\n room_id: report.roomId,\n room: report.room,\n events,\n options: {\n allow_interruptions: allowInterruptions,\n discard_audio_if_uninterruptible: discardAudioIfUninterruptible,\n min_interruption_duration: minInterruptionDuration,\n min_interruption_words: minInterruptionWords,\n min_endpointing_delay: minEndpointingDelay,\n max_endpointing_delay: maxEndpointingDelay,\n max_tool_steps: report.options.maxToolSteps,\n },\n chat_history: report.chatHistory.toJSON({ excludeTimestamp: false }),\n enable_user_data_training: report.enableRecording,\n timestamp: report.timestamp,\n usage: report.modelUsage ? report.modelUsage.map(filterZeroValues) : null,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,yBAAkD;AA8C3C,SAAS,oBAAoB,MAA2C;AAC7E,QAAM,YAAY,KAAK,aAAa,KAAK,IAAI;AAC7C,QAAM,0BAA0B,KAAK;AAErC,SAAO;AAAA,IACL,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,IACb,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,QAAQ,KAAK;AAAA,IACb,aAAa,KAAK;AAAA,IAClB,iBAAiB,KAAK,mBAAmB;AAAA,IACzC,WAAW,KAAK,aAAa,KAAK,IAAI;AAAA,IACtC;AAAA,IACA,oBAAoB,KAAK;AAAA,IACzB;AAAA,IACA,UACE,4BAA4B,SAAY,YAAY,0BAA0B;AAAA,IAChF,YAAY,KAAK;AAAA,EACnB;AACF;AAMO,SAAS,oBAAoB,QAAgD;AA5EpF;AA6EE,QAAM,SAAoC,CAAC;AAC3C,QAAM,sBAAqB,YAAO,QAAQ,iBAAf,mBAA6B;AACxD,QAAM,qBAAoB,YAAO,QAAQ,iBAAf,mBAA6B;AAGvD,QAAM,sBACJ,yDAAoB,UAAS,SACzB,mBAAmB,SAAS,QAC5B,OAAO,QAAQ;AACrB,QAAM,iCACJ,yDAAoB,kCACpB,OAAO,QAAQ;AACjB,QAAM,2BACJ,yDAAoB,gBAAe,OAAO,QAAQ;AACpD,QAAM,wBAAuB,yDAAoB,aAAY,OAAO,QAAQ;AAC5E,QAAM,uBAAsB,uDAAmB,aAAY,OAAO,QAAQ;AAC1E,QAAM,uBAAsB,uDAAmB,aAAY,OAAO,QAAQ;AAE1E,aAAW,SAAS,OAAO,QAAQ;AACjC,QAAI,MAAM,SAAS,qBAAqB;AACtC;AAAA,IACF;AAEA,WAAO,KAAK,EAAE,GAAG,MAAM,CAAC;AAAA,EAC1B;AAEA,SAAO;AAAA,IACL,QAAQ,OAAO;AAAA,IACf,SAAS,OAAO;AAAA,IAChB,MAAM,OAAO;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,qBAAqB;AAAA,MACrB,kCAAkC;AAAA,MAClC,2BAA2B;AAAA,MAC3B,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,gBAAgB,OAAO,QAAQ;AAAA,IACjC;AAAA,IACA,cAAc,OAAO,YAAY,OAAO,EAAE,kBAAkB,MAAM,CAAC;AAAA,IACnE,2BAA2B,OAAO;AAAA,IAClC,WAAW,OAAO;AAAA,IAClB,OAAO,OAAO,aAAa,OAAO,WAAW,IAAI,mCAAgB,IAAI;AAAA,EACvE;AACF;","names":[]}
@@ -1,4 +1,5 @@
1
1
  import type { ChatContext } from '../llm/chat_context.js';
2
+ import { type ModelUsage } from '../metrics/model_usage.js';
2
3
  import type { VoiceOptions } from './agent_session.js';
3
4
  import type { AgentEvent } from './events.js';
4
5
  export interface SessionReport {
@@ -19,6 +20,8 @@ export interface SessionReport {
19
20
  audioRecordingStartedAt?: number;
20
21
  /** Duration of the session in milliseconds */
21
22
  duration?: number;
23
+ /** Usage summaries for the session, one per model/provider combination */
24
+ modelUsage?: ModelUsage[];
22
25
  }
23
26
  export interface SessionReportOptions {
24
27
  jobId: string;
@@ -36,6 +39,8 @@ export interface SessionReportOptions {
36
39
  audioRecordingPath?: string;
37
40
  /** Timestamp when the audio recording started (milliseconds) */
38
41
  audioRecordingStartedAt?: number;
42
+ /** Usage summaries for the session, one per model/provider combination */
43
+ modelUsage?: ModelUsage[];
39
44
  }
40
45
  export declare function createSessionReport(opts: SessionReportOptions): SessionReport;
41
46
  export declare function sessionReportToJSON(report: SessionReport): Record<string, unknown>;
@@ -1,4 +1,5 @@
1
1
  import type { ChatContext } from '../llm/chat_context.js';
2
+ import { type ModelUsage } from '../metrics/model_usage.js';
2
3
  import type { VoiceOptions } from './agent_session.js';
3
4
  import type { AgentEvent } from './events.js';
4
5
  export interface SessionReport {
@@ -19,6 +20,8 @@ export interface SessionReport {
19
20
  audioRecordingStartedAt?: number;
20
21
  /** Duration of the session in milliseconds */
21
22
  duration?: number;
23
+ /** Usage summaries for the session, one per model/provider combination */
24
+ modelUsage?: ModelUsage[];
22
25
  }
23
26
  export interface SessionReportOptions {
24
27
  jobId: string;
@@ -36,6 +39,8 @@ export interface SessionReportOptions {
36
39
  audioRecordingPath?: string;
37
40
  /** Timestamp when the audio recording started (milliseconds) */
38
41
  audioRecordingStartedAt?: number;
42
+ /** Usage summaries for the session, one per model/provider combination */
43
+ modelUsage?: ModelUsage[];
39
44
  }
40
45
  export declare function createSessionReport(opts: SessionReportOptions): SessionReport;
41
46
  export declare function sessionReportToJSON(report: SessionReport): Record<string, unknown>;