@livekit/agents 1.1.0-dev.0 → 1.2.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 (292) hide show
  1. package/dist/cli.cjs +2 -0
  2. package/dist/cli.cjs.map +1 -1
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +2 -0
  5. package/dist/cli.js.map +1 -1
  6. package/dist/constants.cjs +3 -0
  7. package/dist/constants.cjs.map +1 -1
  8. package/dist/constants.d.cts +1 -0
  9. package/dist/constants.d.ts +1 -0
  10. package/dist/constants.d.ts.map +1 -1
  11. package/dist/constants.js +2 -0
  12. package/dist/constants.js.map +1 -1
  13. package/dist/cpu.cjs +189 -0
  14. package/dist/cpu.cjs.map +1 -0
  15. package/dist/cpu.d.cts +24 -0
  16. package/dist/cpu.d.ts +24 -0
  17. package/dist/cpu.d.ts.map +1 -0
  18. package/dist/cpu.js +152 -0
  19. package/dist/cpu.js.map +1 -0
  20. package/dist/cpu.test.cjs +227 -0
  21. package/dist/cpu.test.cjs.map +1 -0
  22. package/dist/cpu.test.js +204 -0
  23. package/dist/cpu.test.js.map +1 -0
  24. package/dist/index.cjs +12 -10
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +13 -13
  27. package/dist/index.d.ts +13 -13
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +11 -10
  30. package/dist/index.js.map +1 -1
  31. package/dist/inference/interruption/defaults.cjs +1 -1
  32. package/dist/inference/interruption/defaults.cjs.map +1 -1
  33. package/dist/inference/interruption/defaults.d.cts +1 -1
  34. package/dist/inference/interruption/defaults.d.ts +1 -1
  35. package/dist/inference/interruption/defaults.d.ts.map +1 -1
  36. package/dist/inference/interruption/defaults.js +1 -1
  37. package/dist/inference/interruption/defaults.js.map +1 -1
  38. package/dist/inference/interruption/http_transport.cjs +44 -28
  39. package/dist/inference/interruption/http_transport.cjs.map +1 -1
  40. package/dist/inference/interruption/http_transport.d.ts.map +1 -1
  41. package/dist/inference/interruption/http_transport.js +45 -29
  42. package/dist/inference/interruption/http_transport.js.map +1 -1
  43. package/dist/inference/interruption/interruption_detector.cjs +22 -5
  44. package/dist/inference/interruption/interruption_detector.cjs.map +1 -1
  45. package/dist/inference/interruption/interruption_detector.d.cts +2 -2
  46. package/dist/inference/interruption/interruption_detector.d.ts +2 -2
  47. package/dist/inference/interruption/interruption_detector.d.ts.map +1 -1
  48. package/dist/inference/interruption/interruption_detector.js +22 -5
  49. package/dist/inference/interruption/interruption_detector.js.map +1 -1
  50. package/dist/inference/interruption/interruption_stream.cjs +4 -4
  51. package/dist/inference/interruption/interruption_stream.cjs.map +1 -1
  52. package/dist/inference/interruption/interruption_stream.js +4 -4
  53. package/dist/inference/interruption/interruption_stream.js.map +1 -1
  54. package/dist/inference/interruption/types.cjs.map +1 -1
  55. package/dist/inference/interruption/types.d.cts +2 -2
  56. package/dist/inference/interruption/types.d.ts +2 -2
  57. package/dist/inference/interruption/types.d.ts.map +1 -1
  58. package/dist/inference/interruption/ws_transport.cjs +60 -47
  59. package/dist/inference/interruption/ws_transport.cjs.map +1 -1
  60. package/dist/inference/interruption/ws_transport.d.ts.map +1 -1
  61. package/dist/inference/interruption/ws_transport.js +60 -47
  62. package/dist/inference/interruption/ws_transport.js.map +1 -1
  63. package/dist/inference/llm.cjs.map +1 -1
  64. package/dist/inference/llm.d.cts +1 -1
  65. package/dist/inference/llm.d.ts +1 -1
  66. package/dist/inference/llm.d.ts.map +1 -1
  67. package/dist/inference/llm.js.map +1 -1
  68. package/dist/inference/stt.cjs +20 -12
  69. package/dist/inference/stt.cjs.map +1 -1
  70. package/dist/inference/stt.d.cts +3 -2
  71. package/dist/inference/stt.d.ts +3 -2
  72. package/dist/inference/stt.d.ts.map +1 -1
  73. package/dist/inference/stt.js +20 -12
  74. package/dist/inference/stt.js.map +1 -1
  75. package/dist/inference/stt.test.cjs +14 -0
  76. package/dist/inference/stt.test.cjs.map +1 -1
  77. package/dist/inference/stt.test.js +14 -0
  78. package/dist/inference/stt.test.js.map +1 -1
  79. package/dist/inference/tts.cjs +13 -4
  80. package/dist/inference/tts.cjs.map +1 -1
  81. package/dist/inference/tts.d.cts +8 -1
  82. package/dist/inference/tts.d.ts +8 -1
  83. package/dist/inference/tts.d.ts.map +1 -1
  84. package/dist/inference/tts.js +13 -4
  85. package/dist/inference/tts.js.map +1 -1
  86. package/dist/inference/tts.test.cjs +10 -0
  87. package/dist/inference/tts.test.cjs.map +1 -1
  88. package/dist/inference/tts.test.js +10 -0
  89. package/dist/inference/tts.test.js.map +1 -1
  90. package/dist/ipc/job_proc_lazy_main.cjs +41 -23
  91. package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
  92. package/dist/ipc/job_proc_lazy_main.js +41 -23
  93. package/dist/ipc/job_proc_lazy_main.js.map +1 -1
  94. package/dist/job.cjs +1 -1
  95. package/dist/job.cjs.map +1 -1
  96. package/dist/job.js +1 -1
  97. package/dist/job.js.map +1 -1
  98. package/dist/language.cjs +394 -0
  99. package/dist/language.cjs.map +1 -0
  100. package/dist/language.d.cts +15 -0
  101. package/dist/language.d.ts +15 -0
  102. package/dist/language.d.ts.map +1 -0
  103. package/dist/language.js +363 -0
  104. package/dist/language.js.map +1 -0
  105. package/dist/language.test.cjs +43 -0
  106. package/dist/language.test.cjs.map +1 -0
  107. package/dist/language.test.js +49 -0
  108. package/dist/language.test.js.map +1 -0
  109. package/dist/llm/index.cjs +2 -0
  110. package/dist/llm/index.cjs.map +1 -1
  111. package/dist/llm/index.d.cts +1 -1
  112. package/dist/llm/index.d.ts +1 -1
  113. package/dist/llm/index.d.ts.map +1 -1
  114. package/dist/llm/index.js +2 -0
  115. package/dist/llm/index.js.map +1 -1
  116. package/dist/stream/deferred_stream.cjs +6 -2
  117. package/dist/stream/deferred_stream.cjs.map +1 -1
  118. package/dist/stream/deferred_stream.d.ts.map +1 -1
  119. package/dist/stream/deferred_stream.js +6 -2
  120. package/dist/stream/deferred_stream.js.map +1 -1
  121. package/dist/stt/stt.cjs.map +1 -1
  122. package/dist/stt/stt.d.cts +2 -1
  123. package/dist/stt/stt.d.ts +2 -1
  124. package/dist/stt/stt.d.ts.map +1 -1
  125. package/dist/stt/stt.js.map +1 -1
  126. package/dist/utils.cjs +15 -0
  127. package/dist/utils.cjs.map +1 -1
  128. package/dist/utils.d.cts +8 -0
  129. package/dist/utils.d.ts +8 -0
  130. package/dist/utils.d.ts.map +1 -1
  131. package/dist/utils.js +13 -0
  132. package/dist/utils.js.map +1 -1
  133. package/dist/version.cjs +1 -1
  134. package/dist/version.js +1 -1
  135. package/dist/voice/agent.cjs +14 -17
  136. package/dist/voice/agent.cjs.map +1 -1
  137. package/dist/voice/agent.d.cts +10 -11
  138. package/dist/voice/agent.d.ts +10 -11
  139. package/dist/voice/agent.d.ts.map +1 -1
  140. package/dist/voice/agent.js +15 -18
  141. package/dist/voice/agent.js.map +1 -1
  142. package/dist/voice/agent.test.cjs +194 -0
  143. package/dist/voice/agent.test.cjs.map +1 -1
  144. package/dist/voice/agent.test.js +195 -1
  145. package/dist/voice/agent.test.js.map +1 -1
  146. package/dist/voice/agent_activity.cjs +116 -39
  147. package/dist/voice/agent_activity.cjs.map +1 -1
  148. package/dist/voice/agent_activity.d.cts +2 -0
  149. package/dist/voice/agent_activity.d.ts +2 -0
  150. package/dist/voice/agent_activity.d.ts.map +1 -1
  151. package/dist/voice/agent_activity.js +117 -40
  152. package/dist/voice/agent_activity.js.map +1 -1
  153. package/dist/voice/agent_activity.test.cjs +135 -0
  154. package/dist/voice/agent_activity.test.cjs.map +1 -0
  155. package/dist/voice/agent_activity.test.js +134 -0
  156. package/dist/voice/agent_activity.test.js.map +1 -0
  157. package/dist/voice/agent_session.cjs +38 -38
  158. package/dist/voice/agent_session.cjs.map +1 -1
  159. package/dist/voice/agent_session.d.cts +65 -56
  160. package/dist/voice/agent_session.d.ts +65 -56
  161. package/dist/voice/agent_session.d.ts.map +1 -1
  162. package/dist/voice/agent_session.js +37 -37
  163. package/dist/voice/agent_session.js.map +1 -1
  164. package/dist/voice/audio_recognition.cjs +106 -52
  165. package/dist/voice/audio_recognition.cjs.map +1 -1
  166. package/dist/voice/audio_recognition.d.cts +4 -2
  167. package/dist/voice/audio_recognition.d.ts +4 -2
  168. package/dist/voice/audio_recognition.d.ts.map +1 -1
  169. package/dist/voice/audio_recognition.js +106 -52
  170. package/dist/voice/audio_recognition.js.map +1 -1
  171. package/dist/voice/audio_recognition_span.test.cjs +84 -22
  172. package/dist/voice/audio_recognition_span.test.cjs.map +1 -1
  173. package/dist/voice/audio_recognition_span.test.js +90 -23
  174. package/dist/voice/audio_recognition_span.test.js.map +1 -1
  175. package/dist/voice/events.cjs +1 -1
  176. package/dist/voice/events.cjs.map +1 -1
  177. package/dist/voice/events.d.cts +4 -3
  178. package/dist/voice/events.d.ts +4 -3
  179. package/dist/voice/events.d.ts.map +1 -1
  180. package/dist/voice/events.js +1 -1
  181. package/dist/voice/events.js.map +1 -1
  182. package/dist/voice/index.cjs +9 -1
  183. package/dist/voice/index.cjs.map +1 -1
  184. package/dist/voice/index.d.cts +1 -1
  185. package/dist/voice/index.d.ts +1 -1
  186. package/dist/voice/index.d.ts.map +1 -1
  187. package/dist/voice/index.js +10 -1
  188. package/dist/voice/index.js.map +1 -1
  189. package/dist/voice/remote_session.cjs +922 -0
  190. package/dist/voice/remote_session.cjs.map +1 -0
  191. package/dist/voice/remote_session.d.cts +108 -0
  192. package/dist/voice/remote_session.d.ts +108 -0
  193. package/dist/voice/remote_session.d.ts.map +1 -0
  194. package/dist/voice/remote_session.js +887 -0
  195. package/dist/voice/remote_session.js.map +1 -0
  196. package/dist/voice/report.cjs +11 -10
  197. package/dist/voice/report.cjs.map +1 -1
  198. package/dist/voice/report.d.cts +5 -3
  199. package/dist/voice/report.d.ts +5 -3
  200. package/dist/voice/report.d.ts.map +1 -1
  201. package/dist/voice/report.js +11 -10
  202. package/dist/voice/report.js.map +1 -1
  203. package/dist/voice/report.test.cjs +15 -0
  204. package/dist/voice/report.test.cjs.map +1 -1
  205. package/dist/voice/report.test.js +15 -0
  206. package/dist/voice/report.test.js.map +1 -1
  207. package/dist/voice/room_io/room_io.cjs +39 -0
  208. package/dist/voice/room_io/room_io.cjs.map +1 -1
  209. package/dist/voice/room_io/room_io.d.cts +3 -1
  210. package/dist/voice/room_io/room_io.d.ts +3 -1
  211. package/dist/voice/room_io/room_io.d.ts.map +1 -1
  212. package/dist/voice/room_io/room_io.js +40 -1
  213. package/dist/voice/room_io/room_io.js.map +1 -1
  214. package/dist/voice/turn_config/interruption.cjs.map +1 -1
  215. package/dist/voice/turn_config/interruption.d.cts +1 -1
  216. package/dist/voice/turn_config/interruption.d.ts +1 -1
  217. package/dist/voice/turn_config/interruption.d.ts.map +1 -1
  218. package/dist/voice/turn_config/interruption.js.map +1 -1
  219. package/dist/voice/turn_config/utils.cjs +95 -35
  220. package/dist/voice/turn_config/utils.cjs.map +1 -1
  221. package/dist/voice/turn_config/utils.d.cts +17 -5
  222. package/dist/voice/turn_config/utils.d.ts +17 -5
  223. package/dist/voice/turn_config/utils.d.ts.map +1 -1
  224. package/dist/voice/turn_config/utils.js +93 -35
  225. package/dist/voice/turn_config/utils.js.map +1 -1
  226. package/dist/voice/turn_config/utils.test.cjs +83 -41
  227. package/dist/voice/turn_config/utils.test.cjs.map +1 -1
  228. package/dist/voice/turn_config/utils.test.js +84 -42
  229. package/dist/voice/turn_config/utils.test.js.map +1 -1
  230. package/dist/worker.cjs +6 -29
  231. package/dist/worker.cjs.map +1 -1
  232. package/dist/worker.d.ts.map +1 -1
  233. package/dist/worker.js +6 -19
  234. package/dist/worker.js.map +1 -1
  235. package/package.json +3 -2
  236. package/src/cli.ts +2 -0
  237. package/src/constants.ts +1 -0
  238. package/src/cpu.test.ts +239 -0
  239. package/src/cpu.ts +173 -0
  240. package/src/index.ts +13 -15
  241. package/src/inference/interruption/defaults.ts +1 -1
  242. package/src/inference/interruption/http_transport.ts +49 -30
  243. package/src/inference/interruption/interruption_detector.ts +22 -6
  244. package/src/inference/interruption/interruption_stream.ts +4 -4
  245. package/src/inference/interruption/types.ts +2 -2
  246. package/src/inference/interruption/ws_transport.ts +63 -59
  247. package/src/inference/llm.ts +3 -1
  248. package/src/inference/stt.test.ts +17 -0
  249. package/src/inference/stt.ts +22 -14
  250. package/src/inference/tts.test.ts +12 -0
  251. package/src/inference/tts.ts +22 -6
  252. package/src/ipc/job_proc_lazy_main.ts +44 -24
  253. package/src/job.ts +1 -1
  254. package/src/language.test.ts +62 -0
  255. package/src/language.ts +380 -0
  256. package/src/llm/index.ts +2 -0
  257. package/src/stream/deferred_stream.ts +5 -1
  258. package/src/stt/stt.ts +2 -1
  259. package/src/utils.ts +20 -0
  260. package/src/voice/agent.test.ts +208 -1
  261. package/src/voice/agent.ts +21 -22
  262. package/src/voice/agent_activity.test.ts +194 -0
  263. package/src/voice/agent_activity.ts +161 -43
  264. package/src/voice/agent_session.ts +103 -92
  265. package/src/voice/audio_recognition.ts +124 -61
  266. package/src/voice/audio_recognition_span.test.ts +115 -35
  267. package/src/voice/events.ts +4 -3
  268. package/src/voice/index.ts +10 -1
  269. package/src/voice/remote_session.ts +1083 -0
  270. package/src/voice/report.test.ts +22 -3
  271. package/src/voice/report.ts +31 -14
  272. package/src/voice/room_io/room_io.ts +52 -2
  273. package/src/voice/turn_config/interruption.ts +1 -1
  274. package/src/voice/turn_config/utils.test.ts +91 -43
  275. package/src/voice/turn_config/utils.ts +120 -56
  276. package/src/worker.ts +34 -50
  277. package/dist/voice/client_events.cjs +0 -554
  278. package/dist/voice/client_events.cjs.map +0 -1
  279. package/dist/voice/client_events.d.cts +0 -195
  280. package/dist/voice/client_events.d.ts +0 -195
  281. package/dist/voice/client_events.d.ts.map +0 -1
  282. package/dist/voice/client_events.js +0 -548
  283. package/dist/voice/client_events.js.map +0 -1
  284. package/dist/voice/wire_format.cjs +0 -798
  285. package/dist/voice/wire_format.cjs.map +0 -1
  286. package/dist/voice/wire_format.d.cts +0 -5503
  287. package/dist/voice/wire_format.d.ts +0 -5503
  288. package/dist/voice/wire_format.d.ts.map +0 -1
  289. package/dist/voice/wire_format.js +0 -728
  290. package/dist/voice/wire_format.js.map +0 -1
  291. package/src/voice/client_events.ts +0 -838
  292. package/src/voice/wire_format.ts +0 -827
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/voice/remote_session.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Timestamp } from '@bufbuild/protobuf';\nimport { AgentSession as pb } from '@livekit/protocol';\nimport type { ByteStreamReader, Room, TextStreamInfo } from '@livekit/rtc-node';\nimport type { TypedEventEmitter } from '@livekit/typed-emitter';\nimport EventEmitter from 'events';\nimport { TOPIC_SESSION_MESSAGES } from '../constants.js';\nimport type { OverlappingSpeechEvent } from '../inference/interruption/types.js';\nimport type {\n ChatItem,\n FunctionCall as FCItem,\n FunctionCallOutput as FCOItem,\n} from '../llm/chat_context.js';\nimport type { ToolContext } from '../llm/tool_context.js';\nimport { log } from '../log.js';\nimport type {\n InterruptionModelUsage,\n LLMModelUsage,\n STTModelUsage,\n TTSModelUsage,\n} from '../metrics/model_usage.js';\nimport { Future, Task, shortuuid } from '../utils.js';\nimport type { AgentSession, AgentSessionUsage } from './agent_session.js';\nimport {\n AgentSessionEventTypes,\n type AgentState,\n type AgentStateChangedEvent,\n type ConversationItemAddedEvent,\n type ErrorEvent,\n type FunctionToolsExecutedEvent,\n type MetricsCollectedEvent,\n type UserInputTranscribedEvent,\n type UserState,\n type UserStateChangedEvent,\n} from './events.js';\nimport type { RoomIO } from './room_io/room_io.js';\n\n// ===========================================================================\n// Shared types (TextInput, Client event types, wire format aliases)\n// ===========================================================================\n\nexport interface TextInputEvent {\n text: string;\n info?: TextStreamInfo;\n participantIdentity?: string;\n}\n\nexport type TextInputCallback = (session: AgentSession, ev: TextInputEvent) => void | Promise<void>;\n\n/** @experimental */\nexport type RemoteSessionEventTypes =\n | 'agent_state_changed'\n | 'user_state_changed'\n | 'conversation_item_added'\n | 'user_input_transcribed'\n | 'function_tools_executed'\n | 'overlapping_speech'\n | 'session_usage'\n | 'error';\n\n/** @experimental */\nexport type RemoteSessionCallbacks = {\n agent_state_changed: (ev: pb.AgentSessionEvent_AgentStateChanged) => void;\n user_state_changed: (ev: pb.AgentSessionEvent_UserStateChanged) => void;\n conversation_item_added: (ev: pb.AgentSessionEvent_ConversationItemAdded) => void;\n user_input_transcribed: (ev: pb.AgentSessionEvent_UserInputTranscribed) => void;\n function_tools_executed: (ev: pb.AgentSessionEvent_FunctionToolsExecuted) => void;\n overlapping_speech: (ev: pb.AgentSessionEvent_OverlappingSpeech) => void;\n session_usage: (ev: pb.AgentSessionEvent_SessionUsageUpdated) => void;\n error: (ev: pb.AgentSessionEvent_Error) => void;\n};\n\n// ===========================================================================\n// SessionTransport\n// ===========================================================================\n\nexport abstract class SessionTransport {\n async start(): Promise<void> {}\n abstract sendMessage(msg: pb.AgentSessionMessage): Promise<void>;\n abstract close(): Promise<void>;\n abstract [Symbol.asyncIterator](): AsyncIterator<pb.AgentSessionMessage>;\n}\n\nexport class RoomSessionTransport extends SessionTransport {\n private readonly room: Room;\n private handlerRegistered = false;\n private closed = false;\n private pendingMessages: pb.AgentSessionMessage[] = [];\n private waitingResolve: ((value: IteratorResult<pb.AgentSessionMessage>) => void) | null = null;\n private roomIO: RoomIO;\n\n constructor(room: Room, roomIO: RoomIO) {\n super();\n this.room = room;\n this.roomIO = roomIO;\n }\n\n private getRemoteIdentity() {\n return this.roomIO.linkedParticipant?.identity;\n }\n\n override async start(): Promise<void> {\n if (this.handlerRegistered) return;\n this.room.registerByteStreamHandler(TOPIC_SESSION_MESSAGES, this.onByteStream);\n this.handlerRegistered = true;\n }\n\n private onByteStream = (reader: ByteStreamReader, participantInfo: { identity: string }) => {\n if (this.getRemoteIdentity() && participantInfo.identity !== this.getRemoteIdentity()) {\n return;\n }\n this.readStream(reader).catch((e) => {\n log().warn({ error: e }, 'failed to read binary stream message');\n });\n };\n\n private async readStream(reader: ByteStreamReader): Promise<void> {\n try {\n const chunks = await reader.readAll();\n let totalLength = 0;\n for (const chunk of chunks) {\n totalLength += chunk.length;\n }\n const data = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n data.set(chunk, offset);\n offset += chunk.length;\n }\n const msg = pb.AgentSessionMessage.fromBinary(data);\n this.enqueue(msg);\n } catch (e) {\n if (!this.closed) {\n log().warn({ error: e }, 'failed to parse binary stream message');\n }\n }\n }\n\n override async sendMessage(msg: pb.AgentSessionMessage): Promise<void> {\n if (this.closed || !this.room.isConnected) return;\n\n try {\n const data = msg.toBinary();\n const opts: Record<string, unknown> = {\n topic: TOPIC_SESSION_MESSAGES,\n name: shortuuid('AS_'),\n };\n const remoteIdentity = this.getRemoteIdentity();\n if (remoteIdentity) {\n opts.destinationIdentities = [remoteIdentity];\n }\n const writer = await this.room.localParticipant!.streamBytes(opts);\n await writer.write(new Uint8Array(data));\n await writer.close();\n } catch (e) {\n log().warn({ error: e }, 'failed to send binary stream message');\n }\n }\n\n override async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n\n if (this.handlerRegistered) {\n try {\n this.room.unregisterByteStreamHandler(TOPIC_SESSION_MESSAGES);\n } catch (e) {\n log().debug({ error: e }, 'byte stream handler already unregistered');\n }\n this.handlerRegistered = false;\n }\n\n if (this.waitingResolve) {\n this.waitingResolve({\n value: undefined as unknown as pb.AgentSessionMessage,\n done: true,\n });\n this.waitingResolve = null;\n }\n }\n\n private enqueue(msg: pb.AgentSessionMessage): void {\n if (this.closed) return;\n\n if (this.waitingResolve) {\n const resolve = this.waitingResolve;\n this.waitingResolve = null;\n resolve({ value: msg, done: false });\n } else {\n this.pendingMessages.push(msg);\n }\n }\n\n override [Symbol.asyncIterator](): AsyncIterator<pb.AgentSessionMessage> {\n return {\n next: (): Promise<IteratorResult<pb.AgentSessionMessage>> => {\n if (this.closed && this.pendingMessages.length === 0) {\n return Promise.resolve({\n value: undefined as unknown as pb.AgentSessionMessage,\n done: true,\n });\n }\n\n const pending = this.pendingMessages.shift();\n if (pending) {\n return Promise.resolve({ value: pending, done: false });\n }\n\n return new Promise<IteratorResult<pb.AgentSessionMessage>>((resolve) => {\n this.waitingResolve = resolve;\n });\n },\n return: (): Promise<IteratorResult<pb.AgentSessionMessage>> => {\n this.close();\n return Promise.resolve({\n value: undefined as unknown as pb.AgentSessionMessage,\n done: true,\n });\n },\n };\n }\n}\n\n// ===========================================================================\n// Enum maps\n// ===========================================================================\nconst AGENT_STATE_MAP: Record<AgentState, pb.AgentState> = {\n initializing: pb.AgentState.AS_INITIALIZING,\n idle: pb.AgentState.AS_IDLE,\n listening: pb.AgentState.AS_LISTENING,\n thinking: pb.AgentState.AS_THINKING,\n speaking: pb.AgentState.AS_SPEAKING,\n};\n\nconst USER_STATE_MAP: Record<UserState, pb.UserState> = {\n speaking: pb.UserState.US_SPEAKING,\n listening: pb.UserState.US_LISTENING,\n away: pb.UserState.US_AWAY,\n};\n\n// ===========================================================================\n// Chat item / timestamp conversion helpers\n// ===========================================================================\nfunction msToTimestamp(ms: number): Timestamp {\n return Timestamp.fromDate(new Date(ms));\n}\n\nfunction nowTimestamp(): Timestamp {\n return Timestamp.fromDate(new Date());\n}\n\nfunction chatItemToProto(item: ChatItem): pb.ChatContext_ChatItem {\n switch (item.type) {\n case 'message': {\n const msg = item;\n const roleMap: Record<string, pb.ChatRole> = {\n developer: pb.ChatRole.DEVELOPER,\n system: pb.ChatRole.SYSTEM,\n user: pb.ChatRole.USER,\n assistant: pb.ChatRole.ASSISTANT,\n };\n const content: pb.ChatMessage_ChatContent[] = [];\n for (const c of msg.content) {\n if (typeof c === 'string') {\n content.push(new pb.ChatMessage_ChatContent({ payload: { case: 'text', value: c } }));\n }\n }\n\n const metricsReport = new pb.MetricsReport();\n if (msg.metrics.transcriptionDelay !== undefined)\n metricsReport.transcriptionDelay = msg.metrics.transcriptionDelay;\n if (msg.metrics.endOfTurnDelay !== undefined)\n metricsReport.endOfTurnDelay = msg.metrics.endOfTurnDelay;\n if (msg.metrics.onUserTurnCompletedDelay !== undefined)\n metricsReport.onUserTurnCompletedDelay = msg.metrics.onUserTurnCompletedDelay;\n if (msg.metrics.llmNodeTtft !== undefined)\n metricsReport.llmNodeTtft = msg.metrics.llmNodeTtft;\n if (msg.metrics.ttsNodeTtfb !== undefined)\n metricsReport.ttsNodeTtfb = msg.metrics.ttsNodeTtfb;\n if (msg.metrics.e2eLatency !== undefined) metricsReport.e2eLatency = msg.metrics.e2eLatency;\n\n const pbMsg = new pb.ChatMessage({\n id: msg.id,\n role: roleMap[msg.role] ?? pb.ChatRole.ASSISTANT,\n content,\n interrupted: msg.interrupted,\n metrics: metricsReport,\n createdAt: msToTimestamp(msg.createdAt),\n });\n if (msg.transcriptConfidence !== undefined) {\n pbMsg.transcriptConfidence = msg.transcriptConfidence;\n }\n return new pb.ChatContext_ChatItem({ item: { case: 'message', value: pbMsg } });\n }\n case 'function_call': {\n const fc = item;\n return new pb.ChatContext_ChatItem({\n item: {\n case: 'functionCall',\n value: new pb.FunctionCall({\n id: fc.id,\n callId: fc.callId,\n name: fc.name,\n arguments: fc.args,\n createdAt: msToTimestamp(fc.createdAt),\n }),\n },\n });\n }\n case 'function_call_output': {\n const fco = item;\n return new pb.ChatContext_ChatItem({\n item: {\n case: 'functionCallOutput',\n value: new pb.FunctionCallOutput({\n id: fco.id,\n callId: fco.callId,\n name: fco.name,\n output: fco.output,\n isError: fco.isError,\n createdAt: msToTimestamp(fco.createdAt),\n }),\n },\n });\n }\n case 'agent_handoff': {\n const ah = item;\n return new pb.ChatContext_ChatItem({\n item: {\n case: 'agentHandoff',\n value: new pb.AgentHandoff({\n id: ah.id,\n oldAgentId: ah.oldAgentId,\n newAgentId: ah.newAgentId,\n createdAt: msToTimestamp(ah.createdAt),\n }),\n },\n });\n }\n }\n}\n\n// ===========================================================================\n// Usage conversion helpers\n// ===========================================================================\nfunction sessionUsageToProto(usage: AgentSessionUsage): pb.AgentSessionUsage {\n const modelUsages: pb.ModelUsage[] = [];\n for (const mu of usage.modelUsage) {\n switch (mu.type) {\n case 'llm_usage': {\n const lu = mu as Partial<LLMModelUsage>;\n modelUsages.push(\n new pb.ModelUsage({\n usage: {\n case: 'llm',\n value: new pb.LLMModelUsage({\n provider: lu.provider ?? '',\n model: lu.model ?? '',\n inputTokens: lu.inputTokens ?? 0,\n inputCachedTokens: lu.inputCachedTokens ?? 0,\n inputAudioTokens: lu.inputAudioTokens ?? 0,\n inputCachedAudioTokens: lu.inputCachedAudioTokens ?? 0,\n inputTextTokens: lu.inputTextTokens ?? 0,\n inputCachedTextTokens: lu.inputCachedTextTokens ?? 0,\n inputImageTokens: lu.inputImageTokens ?? 0,\n inputCachedImageTokens: lu.inputCachedImageTokens ?? 0,\n outputTokens: lu.outputTokens ?? 0,\n outputAudioTokens: lu.outputAudioTokens ?? 0,\n outputTextTokens: lu.outputTextTokens ?? 0,\n sessionDuration: (lu.sessionDurationMs ?? 0) / 1000,\n }),\n },\n }),\n );\n break;\n }\n case 'tts_usage': {\n const tu = mu as Partial<TTSModelUsage>;\n modelUsages.push(\n new pb.ModelUsage({\n usage: {\n case: 'tts',\n value: new pb.TTSModelUsage({\n provider: tu.provider ?? '',\n model: tu.model ?? '',\n inputTokens: tu.inputTokens ?? 0,\n outputTokens: tu.outputTokens ?? 0,\n charactersCount: tu.charactersCount ?? 0,\n audioDuration: (tu.audioDurationMs ?? 0) / 1000,\n }),\n },\n }),\n );\n break;\n }\n case 'stt_usage': {\n const su = mu as Partial<STTModelUsage>;\n modelUsages.push(\n new pb.ModelUsage({\n usage: {\n case: 'stt',\n value: new pb.STTModelUsage({\n provider: su.provider ?? '',\n model: su.model ?? '',\n inputTokens: su.inputTokens ?? 0,\n outputTokens: su.outputTokens ?? 0,\n audioDuration: (su.audioDurationMs ?? 0) / 1000,\n }),\n },\n }),\n );\n break;\n }\n case 'interruption_usage': {\n const iu = mu as Partial<InterruptionModelUsage>;\n modelUsages.push(\n new pb.ModelUsage({\n usage: {\n case: 'interruption',\n value: new pb.InterruptionModelUsage({\n provider: iu.provider ?? '',\n model: iu.model ?? '',\n totalRequests: iu.totalRequests ?? 0,\n }),\n },\n }),\n );\n break;\n }\n }\n }\n return new pb.AgentSessionUsage({ modelUsage: modelUsages });\n}\n\nfunction toolNames(toolCtx: ToolContext | undefined): string[] {\n if (!toolCtx) return [];\n return Object.keys(toolCtx);\n}\n\nfunction protoSerializeOptions(opts: {\n turnHandling?: { endpointing?: unknown; interruption?: unknown };\n maxToolSteps?: number;\n userAwayTimeout?: number | null;\n preemptiveGeneration?: boolean;\n useTtsAlignedTranscript?: boolean;\n}): Record<string, string> {\n return {\n endpointing: JSON.stringify(opts.turnHandling?.endpointing ?? {}),\n interruption: JSON.stringify(opts.turnHandling?.interruption ?? {}),\n max_tool_steps: String(opts.maxToolSteps ?? 0),\n user_away_timeout: String(opts.userAwayTimeout ?? ''),\n preemptive_generation: String(opts.preemptiveGeneration ?? false),\n use_tts_aligned_transcript: String(opts.useTtsAlignedTranscript ?? false),\n };\n}\n\n// ===========================================================================\n// SessionHost (protobuf-based server-side handler)\n// ===========================================================================\nexport class SessionHost {\n private readonly transport: SessionTransport;\n private session: AgentSession | undefined;\n private started = false;\n private eventsRegistered = false;\n private recvTask: Task<void> | undefined;\n private readonly tasks = new Set<Task<void>>();\n private textInputCb: TextInputCallback | undefined;\n\n constructor(transport: SessionTransport) {\n this.transport = transport;\n }\n\n registerSession(session: AgentSession): void {\n this.session = session;\n if (!this.eventsRegistered) {\n this.eventsRegistered = true;\n session.on(AgentSessionEventTypes.AgentStateChanged, this.onAgentStateChanged);\n session.on(AgentSessionEventTypes.UserStateChanged, this.onUserStateChanged);\n session.on(AgentSessionEventTypes.ConversationItemAdded, this.onConversationItemAdded);\n session.on(AgentSessionEventTypes.UserInputTranscribed, this.onUserInputTranscribed);\n session.on(AgentSessionEventTypes.FunctionToolsExecuted, this.onFunctionToolsExecuted);\n session.on(AgentSessionEventTypes.MetricsCollected, this.onMetricsCollected);\n session.on(AgentSessionEventTypes.OverlappingSpeech, this.onOverlappingSpeech);\n session.on(AgentSessionEventTypes.Error, this.onHostError);\n }\n }\n\n registerTextInput(textInputCb: TextInputCallback): void {\n this.textInputCb = textInputCb;\n }\n\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n await this.transport.start();\n this.recvTask = Task.from(async () => this.recvLoop());\n }\n\n async close(): Promise<void> {\n if (!this.started) return;\n this.started = false;\n\n if (this.session && this.eventsRegistered) {\n this.eventsRegistered = false;\n this.session.off(AgentSessionEventTypes.AgentStateChanged, this.onAgentStateChanged);\n this.session.off(AgentSessionEventTypes.UserStateChanged, this.onUserStateChanged);\n this.session.off(AgentSessionEventTypes.ConversationItemAdded, this.onConversationItemAdded);\n this.session.off(AgentSessionEventTypes.UserInputTranscribed, this.onUserInputTranscribed);\n this.session.off(AgentSessionEventTypes.FunctionToolsExecuted, this.onFunctionToolsExecuted);\n this.session.off(AgentSessionEventTypes.MetricsCollected, this.onMetricsCollected);\n this.session.off(AgentSessionEventTypes.OverlappingSpeech, this.onOverlappingSpeech);\n this.session.off(AgentSessionEventTypes.Error, this.onHostError);\n }\n\n if (this.recvTask) {\n this.recvTask.cancel();\n }\n\n await Promise.allSettled([...this.tasks].map((task) => task.cancelAndWait()));\n this.tasks.clear();\n\n await this.transport.close();\n }\n\n private async recvLoop(): Promise<void> {\n try {\n for await (const msg of this.transport) {\n if (msg.message.case === 'request') {\n if (this.session) {\n this.trackTask(\n Task.from(async () => this.handleRequestSafe(msg.message.value as pb.SessionRequest)),\n );\n }\n }\n }\n } catch (e) {\n if (this.started) {\n log().warn({ error: e }, 'error processing session message');\n }\n }\n }\n\n private sendEvent(event: pb.AgentSessionEvent): void {\n const msg = new pb.AgentSessionMessage({\n message: { case: 'event', value: event },\n });\n this.trackTask(Task.from(async () => this.transport.sendMessage(msg)));\n }\n\n private emitEvent<Event extends pb.AgentSessionEvent['event']>(\n event: Event,\n createdAt?: number,\n ): void {\n this.sendEvent(\n new pb.AgentSessionEvent({\n createdAt: createdAt ? msToTimestamp(createdAt) : nowTimestamp(),\n event: event,\n }),\n );\n }\n\n private onAgentStateChanged = (event: AgentStateChangedEvent): void => {\n this.emitEvent(\n {\n case: 'agentStateChanged',\n value: new pb.AgentSessionEvent_AgentStateChanged({\n oldState: AGENT_STATE_MAP[event.oldState],\n newState: AGENT_STATE_MAP[event.newState],\n }),\n },\n event.createdAt,\n );\n };\n\n private onUserStateChanged = (event: UserStateChangedEvent): void => {\n this.emitEvent(\n {\n case: 'userStateChanged',\n value: new pb.AgentSessionEvent_UserStateChanged({\n oldState: USER_STATE_MAP[event.oldState],\n newState: USER_STATE_MAP[event.newState],\n }),\n },\n event.createdAt,\n );\n };\n\n private onUserInputTranscribed = (event: UserInputTranscribedEvent): void => {\n this.emitEvent(\n {\n case: 'userInputTranscribed',\n value: new pb.AgentSessionEvent_UserInputTranscribed({\n transcript: event.transcript,\n isFinal: event.isFinal,\n }),\n },\n event.createdAt,\n );\n };\n\n private onConversationItemAdded = (event: ConversationItemAddedEvent): void => {\n this.emitEvent(\n {\n case: 'conversationItemAdded',\n value: new pb.AgentSessionEvent_ConversationItemAdded({\n item: chatItemToProto(event.item),\n }),\n },\n event.createdAt,\n );\n };\n\n private onFunctionToolsExecuted = (event: FunctionToolsExecutedEvent): void => {\n const pbCalls = event.functionCalls.map(\n (fc: FCItem) => new pb.FunctionCall({ name: fc.name, arguments: fc.args, callId: fc.callId }),\n );\n const pbOutputs = event.functionCallOutputs\n .filter((fco): fco is FCOItem => fco != null)\n .map(\n (fco: FCOItem) =>\n new pb.FunctionCallOutput({\n callId: fco.callId,\n output: fco.output,\n isError: fco.isError,\n }),\n );\n this.emitEvent(\n {\n case: 'functionToolsExecuted',\n value: new pb.AgentSessionEvent_FunctionToolsExecuted({\n functionCalls: pbCalls,\n functionCallOutputs: pbOutputs,\n }),\n },\n event.createdAt,\n );\n };\n\n private onOverlappingSpeech = (event: OverlappingSpeechEvent): void => {\n const value = new pb.AgentSessionEvent_OverlappingSpeech({\n isInterruption: event.isInterruption,\n detectionDelay: event.detectionDelayInS,\n detectedAt: msToTimestamp(event.detectedAt),\n });\n if (event.overlapStartedAt != null) {\n value.overlapStartedAt = msToTimestamp(event.overlapStartedAt);\n }\n this.emitEvent({ case: 'overlappingSpeech', value });\n };\n\n private onMetricsCollected = (event: MetricsCollectedEvent): void => {\n if (!this.session) return;\n this.emitEvent(\n {\n case: 'sessionUsageUpdated',\n value: new pb.AgentSessionEvent_SessionUsageUpdated({\n usage: sessionUsageToProto(this.session.usage),\n }),\n },\n event.createdAt,\n );\n };\n\n private onHostError = (event: ErrorEvent): void => {\n this.emitEvent(\n {\n case: 'error',\n value: new pb.AgentSessionEvent_Error({\n message: event.error ? String(event.error) : 'Unknown error',\n }),\n },\n event.createdAt,\n );\n };\n\n private async handleRequestSafe(req: pb.SessionRequest): Promise<void> {\n try {\n await this.handleRequest(req);\n } catch (e) {\n log().warn({ error: e, requestId: req.requestId }, 'error handling session request');\n try {\n const resp = new pb.AgentSessionMessage({\n message: {\n case: 'response',\n value: new pb.SessionResponse({\n requestId: req.requestId,\n error: 'internal error',\n }),\n },\n });\n await this.transport.sendMessage(resp);\n } catch (e) {\n log().debug({ error: e }, 'failed to send error response');\n }\n }\n }\n\n private async handleRequest(req: pb.SessionRequest): Promise<void> {\n if (!this.session) return;\n\n switch (req.request.case) {\n case 'ping':\n return this.sendResponse(req.requestId, {\n case: 'pong',\n value: new pb.SessionResponse_Pong(),\n });\n case 'getChatHistory':\n return this.handleGetChatHistory(req.requestId);\n case 'getAgentInfo':\n return this.handleGetAgentInfo(req.requestId);\n case 'runInput':\n return this.handleRunInput(req.requestId, req.request.value);\n case 'getSessionState':\n return this.handleGetSessionState(req.requestId);\n case 'getRtcStats':\n return this.sendResponse(req.requestId, {\n case: 'getRtcStats',\n value: new pb.SessionResponse_GetRTCStatsResponse({\n publisherStats: [],\n subscriberStats: [],\n }),\n });\n case 'getSessionUsage':\n return this.handleGetSessionUsage(req.requestId);\n }\n }\n\n private async handleGetChatHistory(requestId: string): Promise<void> {\n const items = this.session!.history.items.map(chatItemToProto);\n return this.sendResponse(requestId, {\n case: 'getChatHistory',\n value: new pb.SessionResponse_GetChatHistoryResponse({ items }),\n });\n }\n\n private async handleGetAgentInfo(requestId: string): Promise<void> {\n const agent = this.session!.currentAgent;\n return this.sendResponse(requestId, {\n case: 'getAgentInfo',\n value: new pb.SessionResponse_GetAgentInfoResponse({\n id: agent.id,\n instructions: agent.instructions,\n tools: toolNames(agent.toolCtx),\n chatCtx: agent.chatCtx.items.map(chatItemToProto),\n }),\n });\n }\n\n private async handleRunInput(\n requestId: string,\n input: pb.SessionRequest_RunInput,\n ): Promise<void> {\n const text = input.text;\n let items: pb.ChatContext_ChatItem[] = [];\n let error: string | undefined;\n\n if (text) {\n if (this.textInputCb) {\n const cbResult = this.textInputCb(this.session!, { text });\n if (cbResult instanceof Promise) {\n await cbResult;\n }\n } else {\n try {\n await this.session!.interrupt({ force: true }).await;\n } catch {\n // ignore\n }\n\n const result = this.session!.run({ userInput: text });\n try {\n await result.wait();\n } catch (e) {\n error = e instanceof Error ? e.message : String(e);\n }\n items = result.events.map((ev) => chatItemToProto(ev.item));\n }\n }\n\n return this.sendResponse(\n requestId,\n {\n case: 'runInput',\n value: new pb.SessionResponse_RunInputResponse({ items }),\n },\n error,\n );\n }\n\n private async handleGetSessionState(requestId: string): Promise<void> {\n const agent = this.session!.currentAgent;\n const startedAt = this.session!._startedAt ?? Date.now();\n return this.sendResponse(requestId, {\n case: 'getSessionState',\n value: new pb.SessionResponse_GetSessionStateResponse({\n agentState: AGENT_STATE_MAP[this.session!.agentState],\n userState: USER_STATE_MAP[this.session!.userState],\n agentId: agent.id,\n options: protoSerializeOptions({\n turnHandling: this.session!.sessionOptions.turnHandling,\n maxToolSteps: this.session!.sessionOptions.maxToolSteps,\n userAwayTimeout: this.session!.sessionOptions.userAwayTimeout,\n preemptiveGeneration: this.session!.sessionOptions.preemptiveGeneration,\n useTtsAlignedTranscript: this.session!.sessionOptions.useTtsAlignedTranscript,\n }),\n createdAt: msToTimestamp(startedAt),\n }),\n });\n }\n\n private async handleGetSessionUsage(requestId: string): Promise<void> {\n return this.sendResponse(requestId, {\n case: 'getSessionUsage',\n value: new pb.SessionResponse_GetSessionUsageResponse({\n usage: sessionUsageToProto(this.session!.usage),\n createdAt: nowTimestamp(),\n }),\n });\n }\n\n private async sendResponse(\n requestId: string,\n response: pb.SessionResponse['response'],\n error?: string,\n ): Promise<void> {\n await this.transport.sendMessage(\n new pb.AgentSessionMessage({\n message: {\n case: 'response',\n value: new pb.SessionResponse({ requestId, response, error }),\n },\n }),\n );\n }\n\n private trackTask(task: Task<void>): void {\n this.tasks.add(task);\n task.addDoneCallback(() => {\n this.tasks.delete(task);\n });\n }\n}\n\n// ===========================================================================\n// RemoteSession (protobuf-based client-side interface)\n// ===========================================================================\n\n/** @experimental */\nexport class RemoteSession extends (EventEmitter as new () => TypedEventEmitter<RemoteSessionCallbacks>) {\n private readonly transport: SessionTransport;\n private started = false;\n\n private readonly tasks = new Set<Task<void>>();\n private readonly pendingRequests = new Map<string, Future<pb.SessionResponse>>();\n private recvTask: Task<void> | undefined;\n private readonly _logger = log();\n\n constructor(transport: SessionTransport) {\n super();\n this.transport = transport;\n }\n\n static fromRoom(room: Room, roomIO: RoomIO): RemoteSession {\n const transport = new RoomSessionTransport(room, roomIO);\n return new RemoteSession(transport);\n }\n\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n await this.transport.start();\n this.recvTask = Task.from(async () => this.recvLoop());\n }\n\n async close(): Promise<void> {\n if (!this.started) return;\n this.started = false;\n\n if (this.recvTask) {\n this.recvTask.cancel();\n }\n\n for (const pending of this.pendingRequests.values()) {\n pending.reject(new Error('RemoteSession closed'));\n }\n this.pendingRequests.clear();\n\n for (const task of this.tasks) {\n task.cancel();\n }\n this.tasks.clear();\n\n await this.transport.close();\n }\n\n private async recvLoop(): Promise<void> {\n try {\n for await (const msg of this.transport) {\n switch (msg.message.case) {\n case 'event':\n this.dispatchEvent(msg.message.value);\n break;\n case 'response':\n this.dispatchResponse(msg.message.value);\n break;\n }\n }\n } catch (e) {\n if (this.started) {\n this._logger.warn({ error: e }, 'error in RemoteSession recv loop');\n }\n }\n }\n\n private dispatchEvent(event: pb.AgentSessionEvent): void {\n const ev = event.event;\n switch (ev.case) {\n case 'agentStateChanged':\n this.emit('agent_state_changed', ev.value);\n break;\n case 'userStateChanged':\n this.emit('user_state_changed', ev.value);\n break;\n case 'userInputTranscribed':\n this.emit('user_input_transcribed', ev.value);\n break;\n case 'conversationItemAdded':\n this.emit('conversation_item_added', ev.value);\n break;\n case 'functionToolsExecuted':\n this.emit('function_tools_executed', ev.value);\n break;\n case 'overlappingSpeech':\n this.emit('overlapping_speech', ev.value);\n break;\n case 'sessionUsageUpdated':\n this.emit('session_usage', ev.value);\n break;\n case 'error':\n this.emit('error', ev.value);\n break;\n }\n }\n\n private dispatchResponse(response: pb.SessionResponse): void {\n const future = this.pendingRequests.get(response.requestId);\n this.pendingRequests.delete(response.requestId);\n if (future && !future.done) {\n future.resolve(response);\n }\n }\n\n private async sendRequest(\n buildReq: (requestId: string) => pb.SessionRequest,\n timeout = 60000,\n ): Promise<pb.SessionResponse> {\n const requestId = shortuuid('req_');\n const req = buildReq(requestId);\n req.requestId = requestId;\n\n const future = new Future<pb.SessionResponse>();\n this.pendingRequests.set(requestId, future);\n\n const msg = new pb.AgentSessionMessage({\n message: { case: 'request', value: req },\n });\n await this.transport.sendMessage(msg);\n\n const timer = setTimeout(() => {\n if (!future.done) {\n this.pendingRequests.delete(requestId);\n future.reject(new Error('RemoteSession request timed out'));\n }\n }, timeout);\n\n try {\n const response = await future.await;\n if (response.error) {\n throw new Error(response.error);\n }\n return response;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async fetchSessionState(): Promise<pb.SessionResponse_GetSessionStateResponse> {\n const resp = await this.sendRequest(\n (id) =>\n new pb.SessionRequest({\n requestId: id,\n request: { case: 'getSessionState', value: new pb.SessionRequest_GetSessionState() },\n }),\n );\n if (resp.response.case !== 'getSessionState') {\n throw new Error('unexpected response type');\n }\n return resp.response.value;\n }\n\n async fetchChatHistory(): Promise<pb.SessionResponse_GetChatHistoryResponse> {\n const resp = await this.sendRequest(\n (id) =>\n new pb.SessionRequest({\n requestId: id,\n request: { case: 'getChatHistory', value: new pb.SessionRequest_GetChatHistory() },\n }),\n );\n if (resp.response.case !== 'getChatHistory') {\n throw new Error('unexpected response type');\n }\n return resp.response.value;\n }\n\n async fetchAgentInfo(): Promise<pb.SessionResponse_GetAgentInfoResponse> {\n const resp = await this.sendRequest(\n (id) =>\n new pb.SessionRequest({\n requestId: id,\n request: { case: 'getAgentInfo', value: new pb.SessionRequest_GetAgentInfo() },\n }),\n );\n if (resp.response.case !== 'getAgentInfo') {\n throw new Error('unexpected response type');\n }\n return resp.response.value;\n }\n\n async sendMessage(\n text: string,\n responseTimeout = 60000,\n ): Promise<pb.SessionResponse_RunInputResponse> {\n const resp = await this.sendRequest(\n (id) =>\n new pb.SessionRequest({\n requestId: id,\n request: { case: 'runInput', value: new pb.SessionRequest_RunInput({ text }) },\n }),\n responseTimeout,\n );\n if (resp.response.case !== 'runInput') {\n throw new Error('unexpected response type');\n }\n return resp.response.value;\n }\n\n async fetchRtcStats(): Promise<pb.SessionResponse_GetRTCStatsResponse> {\n const resp = await this.sendRequest(\n (id) =>\n new pb.SessionRequest({\n requestId: id,\n request: { case: 'getRtcStats', value: new pb.SessionRequest_GetRTCStats() },\n }),\n );\n if (resp.response.case !== 'getRtcStats') {\n throw new Error('unexpected response type');\n }\n return resp.response.value;\n }\n\n async fetchSessionUsage(): Promise<pb.SessionResponse_GetSessionUsageResponse> {\n const resp = await this.sendRequest(\n (id) =>\n new pb.SessionRequest({\n requestId: id,\n request: { case: 'getSessionUsage', value: new pb.SessionRequest_GetSessionUsage() },\n }),\n );\n if (resp.response.case !== 'getSessionUsage') {\n throw new Error('unexpected response type');\n }\n return resp.response.value;\n }\n\n private trackTask(task: Task<void>): void {\n this.tasks.add(task);\n task.addDoneCallback(() => {\n this.tasks.delete(task);\n });\n }\n}\n"],"mappings":"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","names":["e"]}
@@ -43,16 +43,17 @@ function createSessionReport(opts) {
43
43
  };
44
44
  }
45
45
  function sessionReportToJSON(report) {
46
- var _a, _b;
46
+ var _a, _b, _c, _d, _e, _f, _g, _h;
47
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;
48
+ const options = report.options;
49
+ const interruptionConfig = (_a = options.turnHandling) == null ? void 0 : _a.interruption;
50
+ const endpointingConfig = (_b = options.turnHandling) == null ? void 0 : _b.endpointing;
51
+ const allowInterruptions = (interruptionConfig == null ? void 0 : interruptionConfig.enabled) !== void 0 ? interruptionConfig.enabled : (interruptionConfig == null ? void 0 : interruptionConfig.mode) !== void 0 ? true : options.allowInterruptions ?? ((_c = options.voiceOptions) == null ? void 0 : _c.allowInterruptions);
52
+ const discardAudioIfUninterruptible = (interruptionConfig == null ? void 0 : interruptionConfig.discardAudioIfUninterruptible) ?? options.discardAudioIfUninterruptible ?? ((_d = options.voiceOptions) == null ? void 0 : _d.discardAudioIfUninterruptible);
53
+ const minInterruptionDuration = (interruptionConfig == null ? void 0 : interruptionConfig.minDuration) ?? options.minInterruptionDuration ?? ((_e = options.voiceOptions) == null ? void 0 : _e.minInterruptionDuration);
54
+ const minInterruptionWords = (interruptionConfig == null ? void 0 : interruptionConfig.minWords) ?? options.minInterruptionWords ?? ((_f = options.voiceOptions) == null ? void 0 : _f.minInterruptionWords);
55
+ const minEndpointingDelay = (endpointingConfig == null ? void 0 : endpointingConfig.minDelay) ?? options.minEndpointingDelay ?? ((_g = options.voiceOptions) == null ? void 0 : _g.minEndpointingDelay);
56
+ const maxEndpointingDelay = (endpointingConfig == null ? void 0 : endpointingConfig.maxDelay) ?? options.maxEndpointingDelay ?? ((_h = options.voiceOptions) == null ? void 0 : _h.maxEndpointingDelay);
56
57
  for (const event of report.events) {
57
58
  if (event.type === "metrics_collected") {
58
59
  continue;
@@ -71,7 +72,7 @@ function sessionReportToJSON(report) {
71
72
  min_interruption_words: minInterruptionWords,
72
73
  min_endpointing_delay: minEndpointingDelay,
73
74
  max_endpointing_delay: maxEndpointingDelay,
74
- max_tool_steps: report.options.maxToolSteps
75
+ max_tool_steps: options.maxToolSteps
75
76
  },
76
77
  chat_history: report.chatHistory.toJSON({ excludeTimestamp: false }),
77
78
  enable_user_data_training: report.enableRecording,
@@ -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 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
+ {"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 { AgentSessionOptions, VoiceOptions } from './agent_session.js';\nimport type { AgentEvent } from './events.js';\n\ntype ReportOptions = AgentSessionOptions & Partial<VoiceOptions>;\n\nexport interface SessionReport {\n jobId: string;\n roomId: string;\n room: string;\n options: ReportOptions;\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: ReportOptions;\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 options = report.options;\n const interruptionConfig = options.turnHandling?.interruption;\n const endpointingConfig = options.turnHandling?.endpointing;\n\n // Keep backwards compatibility with deprecated fields\n const allowInterruptions =\n interruptionConfig?.enabled !== undefined\n ? interruptionConfig.enabled\n : interruptionConfig?.mode !== undefined\n ? true\n : options.allowInterruptions ?? options.voiceOptions?.allowInterruptions;\n const discardAudioIfUninterruptible =\n interruptionConfig?.discardAudioIfUninterruptible ??\n options.discardAudioIfUninterruptible ??\n options.voiceOptions?.discardAudioIfUninterruptible;\n const minInterruptionDuration =\n interruptionConfig?.minDuration ??\n options.minInterruptionDuration ??\n options.voiceOptions?.minInterruptionDuration;\n const minInterruptionWords =\n interruptionConfig?.minWords ??\n options.minInterruptionWords ??\n options.voiceOptions?.minInterruptionWords;\n const minEndpointingDelay =\n endpointingConfig?.minDelay ??\n options.minEndpointingDelay ??\n options.voiceOptions?.minEndpointingDelay;\n const maxEndpointingDelay =\n endpointingConfig?.maxDelay ??\n options.maxEndpointingDelay ??\n options.voiceOptions?.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: 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;AAgD3C,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;AA9EpF;AA+EE,QAAM,SAAoC,CAAC;AAC3C,QAAM,UAAU,OAAO;AACvB,QAAM,sBAAqB,aAAQ,iBAAR,mBAAsB;AACjD,QAAM,qBAAoB,aAAQ,iBAAR,mBAAsB;AAGhD,QAAM,sBACJ,yDAAoB,aAAY,SAC5B,mBAAmB,WACnB,yDAAoB,UAAS,SAC3B,OACA,QAAQ,wBAAsB,aAAQ,iBAAR,mBAAsB;AAC5D,QAAM,iCACJ,yDAAoB,kCACpB,QAAQ,mCACR,aAAQ,iBAAR,mBAAsB;AACxB,QAAM,2BACJ,yDAAoB,gBACpB,QAAQ,6BACR,aAAQ,iBAAR,mBAAsB;AACxB,QAAM,wBACJ,yDAAoB,aACpB,QAAQ,0BACR,aAAQ,iBAAR,mBAAsB;AACxB,QAAM,uBACJ,uDAAmB,aACnB,QAAQ,yBACR,aAAQ,iBAAR,mBAAsB;AACxB,QAAM,uBACJ,uDAAmB,aACnB,QAAQ,yBACR,aAAQ,iBAAR,mBAAsB;AAExB,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,QAAQ;AAAA,IAC1B;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,12 +1,13 @@
1
1
  import type { ChatContext } from '../llm/chat_context.js';
2
2
  import { type ModelUsage } from '../metrics/model_usage.js';
3
- import type { VoiceOptions } from './agent_session.js';
3
+ import type { AgentSessionOptions, VoiceOptions } from './agent_session.js';
4
4
  import type { AgentEvent } from './events.js';
5
+ type ReportOptions = AgentSessionOptions & Partial<VoiceOptions>;
5
6
  export interface SessionReport {
6
7
  jobId: string;
7
8
  roomId: string;
8
9
  room: string;
9
- options: VoiceOptions;
10
+ options: ReportOptions;
10
11
  events: AgentEvent[];
11
12
  chatHistory: ChatContext;
12
13
  enableRecording: boolean;
@@ -27,7 +28,7 @@ export interface SessionReportOptions {
27
28
  jobId: string;
28
29
  roomId: string;
29
30
  room: string;
30
- options: VoiceOptions;
31
+ options: ReportOptions;
31
32
  events: AgentEvent[];
32
33
  chatHistory: ChatContext;
33
34
  enableRecording?: boolean;
@@ -44,4 +45,5 @@ export interface SessionReportOptions {
44
45
  }
45
46
  export declare function createSessionReport(opts: SessionReportOptions): SessionReport;
46
47
  export declare function sessionReportToJSON(report: SessionReport): Record<string, unknown>;
48
+ export {};
47
49
  //# sourceMappingURL=report.d.ts.map
@@ -1,12 +1,13 @@
1
1
  import type { ChatContext } from '../llm/chat_context.js';
2
2
  import { type ModelUsage } from '../metrics/model_usage.js';
3
- import type { VoiceOptions } from './agent_session.js';
3
+ import type { AgentSessionOptions, VoiceOptions } from './agent_session.js';
4
4
  import type { AgentEvent } from './events.js';
5
+ type ReportOptions = AgentSessionOptions & Partial<VoiceOptions>;
5
6
  export interface SessionReport {
6
7
  jobId: string;
7
8
  roomId: string;
8
9
  room: string;
9
- options: VoiceOptions;
10
+ options: ReportOptions;
10
11
  events: AgentEvent[];
11
12
  chatHistory: ChatContext;
12
13
  enableRecording: boolean;
@@ -27,7 +28,7 @@ export interface SessionReportOptions {
27
28
  jobId: string;
28
29
  roomId: string;
29
30
  room: string;
30
- options: VoiceOptions;
31
+ options: ReportOptions;
31
32
  events: AgentEvent[];
32
33
  chatHistory: ChatContext;
33
34
  enableRecording?: boolean;
@@ -44,4 +45,5 @@ export interface SessionReportOptions {
44
45
  }
45
46
  export declare function createSessionReport(opts: SessionReportOptions): SessionReport;
46
47
  export declare function sessionReportToJSON(report: SessionReport): Record<string, unknown>;
48
+ export {};
47
49
  //# sourceMappingURL=report.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/voice/report.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,2BAA2B,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,wGAAwG;IACxG,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gEAAgE;IAChE,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gEAAgE;IAChE,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,0EAA0E;IAC1E,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,aAAa,CAoB7E;AAMD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA8ClF"}
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/voice/report.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,2BAA2B,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,KAAK,aAAa,GAAG,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,wGAAwG;IACxG,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gEAAgE;IAChE,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gEAAgE;IAChE,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,0EAA0E;IAC1E,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,aAAa,CAoB7E;AAMD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6DlF"}
@@ -19,16 +19,17 @@ function createSessionReport(opts) {
19
19
  };
20
20
  }
21
21
  function sessionReportToJSON(report) {
22
- var _a, _b;
22
+ var _a, _b, _c, _d, _e, _f, _g, _h;
23
23
  const events = [];
24
- const interruptionConfig = (_a = report.options.turnHandling) == null ? void 0 : _a.interruption;
25
- const endpointingConfig = (_b = report.options.turnHandling) == null ? void 0 : _b.endpointing;
26
- const allowInterruptions = (interruptionConfig == null ? void 0 : interruptionConfig.mode) !== void 0 ? interruptionConfig.mode !== false : report.options.allowInterruptions;
27
- const discardAudioIfUninterruptible = (interruptionConfig == null ? void 0 : interruptionConfig.discardAudioIfUninterruptible) ?? report.options.discardAudioIfUninterruptible;
28
- const minInterruptionDuration = (interruptionConfig == null ? void 0 : interruptionConfig.minDuration) ?? report.options.minInterruptionDuration;
29
- const minInterruptionWords = (interruptionConfig == null ? void 0 : interruptionConfig.minWords) ?? report.options.minInterruptionWords;
30
- const minEndpointingDelay = (endpointingConfig == null ? void 0 : endpointingConfig.minDelay) ?? report.options.minEndpointingDelay;
31
- const maxEndpointingDelay = (endpointingConfig == null ? void 0 : endpointingConfig.maxDelay) ?? report.options.maxEndpointingDelay;
24
+ const options = report.options;
25
+ const interruptionConfig = (_a = options.turnHandling) == null ? void 0 : _a.interruption;
26
+ const endpointingConfig = (_b = options.turnHandling) == null ? void 0 : _b.endpointing;
27
+ const allowInterruptions = (interruptionConfig == null ? void 0 : interruptionConfig.enabled) !== void 0 ? interruptionConfig.enabled : (interruptionConfig == null ? void 0 : interruptionConfig.mode) !== void 0 ? true : options.allowInterruptions ?? ((_c = options.voiceOptions) == null ? void 0 : _c.allowInterruptions);
28
+ const discardAudioIfUninterruptible = (interruptionConfig == null ? void 0 : interruptionConfig.discardAudioIfUninterruptible) ?? options.discardAudioIfUninterruptible ?? ((_d = options.voiceOptions) == null ? void 0 : _d.discardAudioIfUninterruptible);
29
+ const minInterruptionDuration = (interruptionConfig == null ? void 0 : interruptionConfig.minDuration) ?? options.minInterruptionDuration ?? ((_e = options.voiceOptions) == null ? void 0 : _e.minInterruptionDuration);
30
+ const minInterruptionWords = (interruptionConfig == null ? void 0 : interruptionConfig.minWords) ?? options.minInterruptionWords ?? ((_f = options.voiceOptions) == null ? void 0 : _f.minInterruptionWords);
31
+ const minEndpointingDelay = (endpointingConfig == null ? void 0 : endpointingConfig.minDelay) ?? options.minEndpointingDelay ?? ((_g = options.voiceOptions) == null ? void 0 : _g.minEndpointingDelay);
32
+ const maxEndpointingDelay = (endpointingConfig == null ? void 0 : endpointingConfig.maxDelay) ?? options.maxEndpointingDelay ?? ((_h = options.voiceOptions) == null ? void 0 : _h.maxEndpointingDelay);
32
33
  for (const event of report.events) {
33
34
  if (event.type === "metrics_collected") {
34
35
  continue;
@@ -47,7 +48,7 @@ function sessionReportToJSON(report) {
47
48
  min_interruption_words: minInterruptionWords,
48
49
  min_endpointing_delay: minEndpointingDelay,
49
50
  max_endpointing_delay: maxEndpointingDelay,
50
- max_tool_steps: report.options.maxToolSteps
51
+ max_tool_steps: options.maxToolSteps
51
52
  },
52
53
  chat_history: report.chatHistory.toJSON({ excludeTimestamp: false }),
53
54
  enable_user_data_training: report.enableRecording,
@@ -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 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":"AAIA,SAA0B,wBAAwB;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,gBAAgB,IAAI;AAAA,EACvE;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 { AgentSessionOptions, VoiceOptions } from './agent_session.js';\nimport type { AgentEvent } from './events.js';\n\ntype ReportOptions = AgentSessionOptions & Partial<VoiceOptions>;\n\nexport interface SessionReport {\n jobId: string;\n roomId: string;\n room: string;\n options: ReportOptions;\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: ReportOptions;\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 options = report.options;\n const interruptionConfig = options.turnHandling?.interruption;\n const endpointingConfig = options.turnHandling?.endpointing;\n\n // Keep backwards compatibility with deprecated fields\n const allowInterruptions =\n interruptionConfig?.enabled !== undefined\n ? interruptionConfig.enabled\n : interruptionConfig?.mode !== undefined\n ? true\n : options.allowInterruptions ?? options.voiceOptions?.allowInterruptions;\n const discardAudioIfUninterruptible =\n interruptionConfig?.discardAudioIfUninterruptible ??\n options.discardAudioIfUninterruptible ??\n options.voiceOptions?.discardAudioIfUninterruptible;\n const minInterruptionDuration =\n interruptionConfig?.minDuration ??\n options.minInterruptionDuration ??\n options.voiceOptions?.minInterruptionDuration;\n const minInterruptionWords =\n interruptionConfig?.minWords ??\n options.minInterruptionWords ??\n options.voiceOptions?.minInterruptionWords;\n const minEndpointingDelay =\n endpointingConfig?.minDelay ??\n options.minEndpointingDelay ??\n options.voiceOptions?.minEndpointingDelay;\n const maxEndpointingDelay =\n endpointingConfig?.maxDelay ??\n options.maxEndpointingDelay ??\n options.voiceOptions?.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: 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":"AAIA,SAA0B,wBAAwB;AAgD3C,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;AA9EpF;AA+EE,QAAM,SAAoC,CAAC;AAC3C,QAAM,UAAU,OAAO;AACvB,QAAM,sBAAqB,aAAQ,iBAAR,mBAAsB;AACjD,QAAM,qBAAoB,aAAQ,iBAAR,mBAAsB;AAGhD,QAAM,sBACJ,yDAAoB,aAAY,SAC5B,mBAAmB,WACnB,yDAAoB,UAAS,SAC3B,OACA,QAAQ,wBAAsB,aAAQ,iBAAR,mBAAsB;AAC5D,QAAM,iCACJ,yDAAoB,kCACpB,QAAQ,mCACR,aAAQ,iBAAR,mBAAsB;AACxB,QAAM,2BACJ,yDAAoB,gBACpB,QAAQ,6BACR,aAAQ,iBAAR,mBAAsB;AACxB,QAAM,wBACJ,yDAAoB,aACpB,QAAQ,0BACR,aAAQ,iBAAR,mBAAsB;AACxB,QAAM,uBACJ,uDAAmB,aACnB,QAAQ,yBACR,aAAQ,iBAAR,mBAAsB;AACxB,QAAM,uBACJ,uDAAmB,aACnB,QAAQ,yBACR,aAAQ,iBAAR,mBAAsB;AAExB,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,QAAQ;AAAA,IAC1B;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,gBAAgB,IAAI;AAAA,EACvE;AACF;","names":[]}
@@ -83,6 +83,21 @@ function serializeOptions(options) {
83
83
  max_tool_steps: 3
84
84
  });
85
85
  });
86
+ (0, import_vitest.it)("serializes allow_interruptions from interruption.enabled when present", () => {
87
+ const options = baseOptions();
88
+ options.allowInterruptions = true;
89
+ options.turnHandling = {
90
+ interruption: {
91
+ enabled: false,
92
+ mode: "adaptive"
93
+ }
94
+ };
95
+ const serialized = serializeOptions(options);
96
+ (0, import_vitest.expect)(serialized).toMatchObject({
97
+ allow_interruptions: false,
98
+ max_tool_steps: 3
99
+ });
100
+ });
86
101
  (0, import_vitest.it)("falls back to deprecated flat fields when turnHandling values are absent", () => {
87
102
  const options = baseOptions();
88
103
  options.allowInterruptions = false;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/voice/report.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { describe, expect, it } from 'vitest';\nimport { ChatContext } from '../llm/chat_context.js';\nimport type { VoiceOptions } from './agent_session.js';\nimport { createSessionReport, sessionReportToJSON } from './report.js';\n\nfunction baseOptions(): VoiceOptions {\n return {\n maxToolSteps: 3,\n preemptiveGeneration: false,\n userAwayTimeout: 15,\n useTtsAlignedTranscript: true,\n turnHandling: {},\n };\n}\n\nfunction serializeOptions(options: VoiceOptions) {\n const report = createSessionReport({\n jobId: 'job',\n roomId: 'room-id',\n room: 'room',\n options,\n events: [],\n chatHistory: ChatContext.empty(),\n enableRecording: false,\n timestamp: 0,\n startedAt: 0,\n });\n\n const payload = sessionReportToJSON(report);\n return payload.options as Record<string, unknown>;\n}\n\ndescribe('sessionReportToJSON', () => {\n it('serializes interruption and endpointing values from turnHandling', () => {\n const options = baseOptions();\n options.turnHandling = {\n interruption: {\n mode: 'adaptive',\n discardAudioIfUninterruptible: false,\n minDuration: 1200,\n minWords: 2,\n },\n endpointing: {\n minDelay: 900,\n maxDelay: 4500,\n },\n };\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: true,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 1200,\n min_interruption_words: 2,\n min_endpointing_delay: 900,\n max_endpointing_delay: 4500,\n max_tool_steps: 3,\n });\n });\n\n it('prefers turnHandling values over deprecated flat fields', () => {\n const options = baseOptions();\n options.allowInterruptions = false;\n options.discardAudioIfUninterruptible = true;\n options.minInterruptionDuration = 400;\n options.minInterruptionWords = 1;\n options.minEndpointingDelay = 500;\n options.maxEndpointingDelay = 2500;\n options.turnHandling = {\n interruption: {\n mode: 'vad',\n discardAudioIfUninterruptible: false,\n minDuration: 1400,\n minWords: 4,\n },\n endpointing: {\n minDelay: 700,\n maxDelay: 3900,\n },\n };\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: true,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 1400,\n min_interruption_words: 4,\n min_endpointing_delay: 700,\n max_endpointing_delay: 3900,\n max_tool_steps: 3,\n });\n });\n\n it('falls back to deprecated flat fields when turnHandling values are absent', () => {\n const options = baseOptions();\n options.allowInterruptions = false;\n options.discardAudioIfUninterruptible = false;\n options.minInterruptionDuration = 600;\n options.minInterruptionWords = 3;\n options.minEndpointingDelay = 1000;\n options.maxEndpointingDelay = 5000;\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: false,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 600,\n min_interruption_words: 3,\n min_endpointing_delay: 1000,\n max_endpointing_delay: 5000,\n max_tool_steps: 3,\n });\n });\n});\n"],"mappings":";AAGA,oBAAqC;AACrC,0BAA4B;AAE5B,oBAAyD;AAEzD,SAAS,cAA4B;AACnC,SAAO;AAAA,IACL,cAAc;AAAA,IACd,sBAAsB;AAAA,IACtB,iBAAiB;AAAA,IACjB,yBAAyB;AAAA,IACzB,cAAc,CAAC;AAAA,EACjB;AACF;AAEA,SAAS,iBAAiB,SAAuB;AAC/C,QAAM,aAAS,mCAAoB;AAAA,IACjC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,aAAa,gCAAY,MAAM;AAAA,IAC/B,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,WAAW;AAAA,EACb,CAAC;AAED,QAAM,cAAU,mCAAoB,MAAM;AAC1C,SAAO,QAAQ;AACjB;AAAA,IAEA,wBAAS,uBAAuB,MAAM;AACpC,wBAAG,oEAAoE,MAAM;AAC3E,UAAM,UAAU,YAAY;AAC5B,YAAQ,eAAe;AAAA,MACrB,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,+BAA+B;AAAA,QAC/B,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,MACA,aAAa;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,aAAa,iBAAiB,OAAO;AAC3C,8BAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,qBAAqB;AAAA,MACrB,kCAAkC;AAAA,MAClC,2BAA2B;AAAA,MAC3B,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AAED,wBAAG,2DAA2D,MAAM;AAClE,UAAM,UAAU,YAAY;AAC5B,YAAQ,qBAAqB;AAC7B,YAAQ,gCAAgC;AACxC,YAAQ,0BAA0B;AAClC,YAAQ,uBAAuB;AAC/B,YAAQ,sBAAsB;AAC9B,YAAQ,sBAAsB;AAC9B,YAAQ,eAAe;AAAA,MACrB,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,+BAA+B;AAAA,QAC/B,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,MACA,aAAa;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,aAAa,iBAAiB,OAAO;AAC3C,8BAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,qBAAqB;AAAA,MACrB,kCAAkC;AAAA,MAClC,2BAA2B;AAAA,MAC3B,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AAED,wBAAG,4EAA4E,MAAM;AACnF,UAAM,UAAU,YAAY;AAC5B,YAAQ,qBAAqB;AAC7B,YAAQ,gCAAgC;AACxC,YAAQ,0BAA0B;AAClC,YAAQ,uBAAuB;AAC/B,YAAQ,sBAAsB;AAC9B,YAAQ,sBAAsB;AAE9B,UAAM,aAAa,iBAAiB,OAAO;AAC3C,8BAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,qBAAqB;AAAA,MACrB,kCAAkC;AAAA,MAClC,2BAA2B;AAAA,MAC3B,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AACH,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../src/voice/report.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { describe, expect, it } from 'vitest';\nimport { ChatContext } from '../llm/chat_context.js';\nimport type { AgentSessionOptions, VoiceOptions } from './agent_session.js';\nimport { createSessionReport, sessionReportToJSON } from './report.js';\n\ntype ReportOptions = AgentSessionOptions & Partial<VoiceOptions>;\n\nfunction baseOptions(): ReportOptions {\n return {\n maxToolSteps: 3,\n preemptiveGeneration: false,\n userAwayTimeout: 15,\n useTtsAlignedTranscript: true,\n turnHandling: {},\n };\n}\n\nfunction serializeOptions(options: ReportOptions) {\n const report = createSessionReport({\n jobId: 'job',\n roomId: 'room-id',\n room: 'room',\n options,\n events: [],\n chatHistory: ChatContext.empty(),\n enableRecording: false,\n timestamp: 0,\n startedAt: 0,\n });\n\n const payload = sessionReportToJSON(report);\n return payload.options as Record<string, unknown>;\n}\n\ndescribe('sessionReportToJSON', () => {\n it('serializes interruption and endpointing values from turnHandling', () => {\n const options = baseOptions();\n options.turnHandling = {\n interruption: {\n mode: 'adaptive',\n discardAudioIfUninterruptible: false,\n minDuration: 1200,\n minWords: 2,\n },\n endpointing: {\n minDelay: 900,\n maxDelay: 4500,\n },\n };\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: true,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 1200,\n min_interruption_words: 2,\n min_endpointing_delay: 900,\n max_endpointing_delay: 4500,\n max_tool_steps: 3,\n });\n });\n\n it('prefers turnHandling values over deprecated flat fields', () => {\n const options = baseOptions();\n options.allowInterruptions = false;\n options.discardAudioIfUninterruptible = true;\n options.minInterruptionDuration = 400;\n options.minInterruptionWords = 1;\n options.minEndpointingDelay = 500;\n options.maxEndpointingDelay = 2500;\n options.turnHandling = {\n interruption: {\n mode: 'vad',\n discardAudioIfUninterruptible: false,\n minDuration: 1400,\n minWords: 4,\n },\n endpointing: {\n minDelay: 700,\n maxDelay: 3900,\n },\n };\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: true,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 1400,\n min_interruption_words: 4,\n min_endpointing_delay: 700,\n max_endpointing_delay: 3900,\n max_tool_steps: 3,\n });\n });\n\n it('serializes allow_interruptions from interruption.enabled when present', () => {\n const options = baseOptions();\n options.allowInterruptions = true;\n options.turnHandling = {\n interruption: {\n enabled: false,\n mode: 'adaptive',\n },\n };\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: false,\n max_tool_steps: 3,\n });\n });\n\n it('falls back to deprecated flat fields when turnHandling values are absent', () => {\n const options = baseOptions();\n options.allowInterruptions = false;\n options.discardAudioIfUninterruptible = false;\n options.minInterruptionDuration = 600;\n options.minInterruptionWords = 3;\n options.minEndpointingDelay = 1000;\n options.maxEndpointingDelay = 5000;\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: false,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 600,\n min_interruption_words: 3,\n min_endpointing_delay: 1000,\n max_endpointing_delay: 5000,\n max_tool_steps: 3,\n });\n });\n});\n"],"mappings":"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","names":[]}
@@ -82,6 +82,21 @@ describe("sessionReportToJSON", () => {
82
82
  max_tool_steps: 3
83
83
  });
84
84
  });
85
+ it("serializes allow_interruptions from interruption.enabled when present", () => {
86
+ const options = baseOptions();
87
+ options.allowInterruptions = true;
88
+ options.turnHandling = {
89
+ interruption: {
90
+ enabled: false,
91
+ mode: "adaptive"
92
+ }
93
+ };
94
+ const serialized = serializeOptions(options);
95
+ expect(serialized).toMatchObject({
96
+ allow_interruptions: false,
97
+ max_tool_steps: 3
98
+ });
99
+ });
85
100
  it("falls back to deprecated flat fields when turnHandling values are absent", () => {
86
101
  const options = baseOptions();
87
102
  options.allowInterruptions = false;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/voice/report.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { describe, expect, it } from 'vitest';\nimport { ChatContext } from '../llm/chat_context.js';\nimport type { VoiceOptions } from './agent_session.js';\nimport { createSessionReport, sessionReportToJSON } from './report.js';\n\nfunction baseOptions(): VoiceOptions {\n return {\n maxToolSteps: 3,\n preemptiveGeneration: false,\n userAwayTimeout: 15,\n useTtsAlignedTranscript: true,\n turnHandling: {},\n };\n}\n\nfunction serializeOptions(options: VoiceOptions) {\n const report = createSessionReport({\n jobId: 'job',\n roomId: 'room-id',\n room: 'room',\n options,\n events: [],\n chatHistory: ChatContext.empty(),\n enableRecording: false,\n timestamp: 0,\n startedAt: 0,\n });\n\n const payload = sessionReportToJSON(report);\n return payload.options as Record<string, unknown>;\n}\n\ndescribe('sessionReportToJSON', () => {\n it('serializes interruption and endpointing values from turnHandling', () => {\n const options = baseOptions();\n options.turnHandling = {\n interruption: {\n mode: 'adaptive',\n discardAudioIfUninterruptible: false,\n minDuration: 1200,\n minWords: 2,\n },\n endpointing: {\n minDelay: 900,\n maxDelay: 4500,\n },\n };\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: true,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 1200,\n min_interruption_words: 2,\n min_endpointing_delay: 900,\n max_endpointing_delay: 4500,\n max_tool_steps: 3,\n });\n });\n\n it('prefers turnHandling values over deprecated flat fields', () => {\n const options = baseOptions();\n options.allowInterruptions = false;\n options.discardAudioIfUninterruptible = true;\n options.minInterruptionDuration = 400;\n options.minInterruptionWords = 1;\n options.minEndpointingDelay = 500;\n options.maxEndpointingDelay = 2500;\n options.turnHandling = {\n interruption: {\n mode: 'vad',\n discardAudioIfUninterruptible: false,\n minDuration: 1400,\n minWords: 4,\n },\n endpointing: {\n minDelay: 700,\n maxDelay: 3900,\n },\n };\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: true,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 1400,\n min_interruption_words: 4,\n min_endpointing_delay: 700,\n max_endpointing_delay: 3900,\n max_tool_steps: 3,\n });\n });\n\n it('falls back to deprecated flat fields when turnHandling values are absent', () => {\n const options = baseOptions();\n options.allowInterruptions = false;\n options.discardAudioIfUninterruptible = false;\n options.minInterruptionDuration = 600;\n options.minInterruptionWords = 3;\n options.minEndpointingDelay = 1000;\n options.maxEndpointingDelay = 5000;\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: false,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 600,\n min_interruption_words: 3,\n min_endpointing_delay: 1000,\n max_endpointing_delay: 5000,\n max_tool_steps: 3,\n });\n });\n});\n"],"mappings":"AAGA,SAAS,UAAU,QAAQ,UAAU;AACrC,SAAS,mBAAmB;AAE5B,SAAS,qBAAqB,2BAA2B;AAEzD,SAAS,cAA4B;AACnC,SAAO;AAAA,IACL,cAAc;AAAA,IACd,sBAAsB;AAAA,IACtB,iBAAiB;AAAA,IACjB,yBAAyB;AAAA,IACzB,cAAc,CAAC;AAAA,EACjB;AACF;AAEA,SAAS,iBAAiB,SAAuB;AAC/C,QAAM,SAAS,oBAAoB;AAAA,IACjC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,aAAa,YAAY,MAAM;AAAA,IAC/B,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,WAAW;AAAA,EACb,CAAC;AAED,QAAM,UAAU,oBAAoB,MAAM;AAC1C,SAAO,QAAQ;AACjB;AAEA,SAAS,uBAAuB,MAAM;AACpC,KAAG,oEAAoE,MAAM;AAC3E,UAAM,UAAU,YAAY;AAC5B,YAAQ,eAAe;AAAA,MACrB,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,+BAA+B;AAAA,QAC/B,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,MACA,aAAa;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,aAAa,iBAAiB,OAAO;AAC3C,WAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,qBAAqB;AAAA,MACrB,kCAAkC;AAAA,MAClC,2BAA2B;AAAA,MAC3B,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AAED,KAAG,2DAA2D,MAAM;AAClE,UAAM,UAAU,YAAY;AAC5B,YAAQ,qBAAqB;AAC7B,YAAQ,gCAAgC;AACxC,YAAQ,0BAA0B;AAClC,YAAQ,uBAAuB;AAC/B,YAAQ,sBAAsB;AAC9B,YAAQ,sBAAsB;AAC9B,YAAQ,eAAe;AAAA,MACrB,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,+BAA+B;AAAA,QAC/B,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,MACA,aAAa;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,aAAa,iBAAiB,OAAO;AAC3C,WAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,qBAAqB;AAAA,MACrB,kCAAkC;AAAA,MAClC,2BAA2B;AAAA,MAC3B,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AAED,KAAG,4EAA4E,MAAM;AACnF,UAAM,UAAU,YAAY;AAC5B,YAAQ,qBAAqB;AAC7B,YAAQ,gCAAgC;AACxC,YAAQ,0BAA0B;AAClC,YAAQ,uBAAuB;AAC/B,YAAQ,sBAAsB;AAC9B,YAAQ,sBAAsB;AAE9B,UAAM,aAAa,iBAAiB,OAAO;AAC3C,WAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,qBAAqB;AAAA,MACrB,kCAAkC;AAAA,MAClC,2BAA2B;AAAA,MAC3B,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AACH,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../src/voice/report.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { describe, expect, it } from 'vitest';\nimport { ChatContext } from '../llm/chat_context.js';\nimport type { AgentSessionOptions, VoiceOptions } from './agent_session.js';\nimport { createSessionReport, sessionReportToJSON } from './report.js';\n\ntype ReportOptions = AgentSessionOptions & Partial<VoiceOptions>;\n\nfunction baseOptions(): ReportOptions {\n return {\n maxToolSteps: 3,\n preemptiveGeneration: false,\n userAwayTimeout: 15,\n useTtsAlignedTranscript: true,\n turnHandling: {},\n };\n}\n\nfunction serializeOptions(options: ReportOptions) {\n const report = createSessionReport({\n jobId: 'job',\n roomId: 'room-id',\n room: 'room',\n options,\n events: [],\n chatHistory: ChatContext.empty(),\n enableRecording: false,\n timestamp: 0,\n startedAt: 0,\n });\n\n const payload = sessionReportToJSON(report);\n return payload.options as Record<string, unknown>;\n}\n\ndescribe('sessionReportToJSON', () => {\n it('serializes interruption and endpointing values from turnHandling', () => {\n const options = baseOptions();\n options.turnHandling = {\n interruption: {\n mode: 'adaptive',\n discardAudioIfUninterruptible: false,\n minDuration: 1200,\n minWords: 2,\n },\n endpointing: {\n minDelay: 900,\n maxDelay: 4500,\n },\n };\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: true,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 1200,\n min_interruption_words: 2,\n min_endpointing_delay: 900,\n max_endpointing_delay: 4500,\n max_tool_steps: 3,\n });\n });\n\n it('prefers turnHandling values over deprecated flat fields', () => {\n const options = baseOptions();\n options.allowInterruptions = false;\n options.discardAudioIfUninterruptible = true;\n options.minInterruptionDuration = 400;\n options.minInterruptionWords = 1;\n options.minEndpointingDelay = 500;\n options.maxEndpointingDelay = 2500;\n options.turnHandling = {\n interruption: {\n mode: 'vad',\n discardAudioIfUninterruptible: false,\n minDuration: 1400,\n minWords: 4,\n },\n endpointing: {\n minDelay: 700,\n maxDelay: 3900,\n },\n };\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: true,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 1400,\n min_interruption_words: 4,\n min_endpointing_delay: 700,\n max_endpointing_delay: 3900,\n max_tool_steps: 3,\n });\n });\n\n it('serializes allow_interruptions from interruption.enabled when present', () => {\n const options = baseOptions();\n options.allowInterruptions = true;\n options.turnHandling = {\n interruption: {\n enabled: false,\n mode: 'adaptive',\n },\n };\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: false,\n max_tool_steps: 3,\n });\n });\n\n it('falls back to deprecated flat fields when turnHandling values are absent', () => {\n const options = baseOptions();\n options.allowInterruptions = false;\n options.discardAudioIfUninterruptible = false;\n options.minInterruptionDuration = 600;\n options.minInterruptionWords = 3;\n options.minEndpointingDelay = 1000;\n options.maxEndpointingDelay = 5000;\n\n const serialized = serializeOptions(options);\n expect(serialized).toMatchObject({\n allow_interruptions: false,\n discard_audio_if_uninterruptible: false,\n min_interruption_duration: 600,\n min_interruption_words: 3,\n min_endpointing_delay: 1000,\n max_endpointing_delay: 5000,\n max_tool_steps: 3,\n });\n });\n});\n"],"mappings":"AAGA,SAAS,UAAU,QAAQ,UAAU;AACrC,SAAS,mBAAmB;AAE5B,SAAS,qBAAqB,2BAA2B;AAIzD,SAAS,cAA6B;AACpC,SAAO;AAAA,IACL,cAAc;AAAA,IACd,sBAAsB;AAAA,IACtB,iBAAiB;AAAA,IACjB,yBAAyB;AAAA,IACzB,cAAc,CAAC;AAAA,EACjB;AACF;AAEA,SAAS,iBAAiB,SAAwB;AAChD,QAAM,SAAS,oBAAoB;AAAA,IACjC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,aAAa,YAAY,MAAM;AAAA,IAC/B,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,WAAW;AAAA,EACb,CAAC;AAED,QAAM,UAAU,oBAAoB,MAAM;AAC1C,SAAO,QAAQ;AACjB;AAEA,SAAS,uBAAuB,MAAM;AACpC,KAAG,oEAAoE,MAAM;AAC3E,UAAM,UAAU,YAAY;AAC5B,YAAQ,eAAe;AAAA,MACrB,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,+BAA+B;AAAA,QAC/B,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,MACA,aAAa;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,aAAa,iBAAiB,OAAO;AAC3C,WAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,qBAAqB;AAAA,MACrB,kCAAkC;AAAA,MAClC,2BAA2B;AAAA,MAC3B,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AAED,KAAG,2DAA2D,MAAM;AAClE,UAAM,UAAU,YAAY;AAC5B,YAAQ,qBAAqB;AAC7B,YAAQ,gCAAgC;AACxC,YAAQ,0BAA0B;AAClC,YAAQ,uBAAuB;AAC/B,YAAQ,sBAAsB;AAC9B,YAAQ,sBAAsB;AAC9B,YAAQ,eAAe;AAAA,MACrB,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,+BAA+B;AAAA,QAC/B,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,MACA,aAAa;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,aAAa,iBAAiB,OAAO;AAC3C,WAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,qBAAqB;AAAA,MACrB,kCAAkC;AAAA,MAClC,2BAA2B;AAAA,MAC3B,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AAED,KAAG,yEAAyE,MAAM;AAChF,UAAM,UAAU,YAAY;AAC5B,YAAQ,qBAAqB;AAC7B,YAAQ,eAAe;AAAA,MACrB,cAAc;AAAA,QACZ,SAAS;AAAA,QACT,MAAM;AAAA,MACR;AAAA,IACF;AAEA,UAAM,aAAa,iBAAiB,OAAO;AAC3C,WAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,qBAAqB;AAAA,MACrB,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AAED,KAAG,4EAA4E,MAAM;AACnF,UAAM,UAAU,YAAY;AAC5B,YAAQ,qBAAqB;AAC7B,YAAQ,gCAAgC;AACxC,YAAQ,0BAA0B;AAClC,YAAQ,uBAAuB;AAC/B,YAAQ,sBAAsB;AAC9B,YAAQ,sBAAsB;AAE9B,UAAM,aAAa,iBAAiB,OAAO;AAC3C,WAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,qBAAqB;AAAA,MACrB,kCAAkC;AAAA,MAClC,2BAA2B;AAAA,MAC3B,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AACH,CAAC;","names":[]}
@@ -74,6 +74,7 @@ class RoomIO {
74
74
  agentTranscriptOutput;
75
75
  transcriptionSynchronizer;
76
76
  participantIdentity = null;
77
+ textStreamHandlerRegistered = false;
77
78
  participantAvailableFuture = new import_utils.Future();
78
79
  roomConnectedFuture = new import_utils.Future();
79
80
  // Use stream API for transcript queue
@@ -179,6 +180,30 @@ class RoomIO {
179
180
  });
180
181
  }
181
182
  };
183
+ onUserTextInput = (reader, participantInfo) => {
184
+ if (this.participantIdentity && participantInfo.identity !== this.participantIdentity) {
185
+ return;
186
+ }
187
+ const participant = this.room.remoteParticipants.get(participantInfo.identity);
188
+ if (!participant) {
189
+ this.logger.warn("participant not found, ignoring text input");
190
+ return;
191
+ }
192
+ const readText = async () => {
193
+ const text = await reader.readAll();
194
+ const textInputResult = this.inputOptions.textInputCallback(this.agentSession, {
195
+ text,
196
+ info: reader.info,
197
+ participantIdentity: participantInfo.identity
198
+ });
199
+ if (textInputResult instanceof Promise) {
200
+ await textInputResult;
201
+ }
202
+ };
203
+ readText().catch((error) => {
204
+ this.logger.error({ error }, "Error reading text input");
205
+ });
206
+ };
182
207
  async forwardUserTranscript(signal) {
183
208
  var _a, _b;
184
209
  const reader = this.userTranscriptStream.readable.getReader();
@@ -281,6 +306,16 @@ class RoomIO {
281
306
  });
282
307
  }
283
308
  start() {
309
+ if (this.inputOptions.textEnabled) {
310
+ try {
311
+ this.room.registerTextStreamHandler(import_constants.TOPIC_CHAT, this.onUserTextInput);
312
+ this.textStreamHandlerRegistered = true;
313
+ } catch (error) {
314
+ if (this.inputOptions.textEnabled) {
315
+ this.logger.warn(`text stream handler for topic "${import_constants.TOPIC_CHAT}" already set, ignoring`);
316
+ }
317
+ }
318
+ }
284
319
  if (this.inputOptions.audioEnabled) {
285
320
  this.audioInput = new import_input.ParticipantAudioInputStream({
286
321
  room: this.room,
@@ -342,6 +377,10 @@ class RoomIO {
342
377
  this.room.off(import_rtc_node.RoomEvent.ParticipantDisconnected, this.onParticipantDisconnected);
343
378
  this.agentSession.off(import_events.AgentSessionEventTypes.UserInputTranscribed, this.onUserInputTranscribed);
344
379
  this.agentSession.off(import_events.AgentSessionEventTypes.AgentStateChanged, this.onAgentStateChanged);
380
+ if (this.textStreamHandlerRegistered) {
381
+ this.room.unregisterTextStreamHandler(import_constants.TOPIC_CHAT);
382
+ this.textStreamHandlerRegistered = false;
383
+ }
345
384
  await ((_a = this.initTask) == null ? void 0 : _a.cancelAndWait());
346
385
  this.userTranscriptWriter.close();
347
386
  await ((_b = this.forwardUserTranscriptTask) == null ? void 0 : _b.cancelAndWait());