@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
package/src/worker.ts CHANGED
@@ -13,8 +13,8 @@ import {
13
13
  import type { ParticipantInfo } from 'livekit-server-sdk';
14
14
  import { AccessToken, RoomServiceClient } from 'livekit-server-sdk';
15
15
  import { EventEmitter } from 'node:events';
16
- import os from 'node:os';
17
16
  import { WebSocket } from 'ws';
17
+ import { getCpuMonitor } from './cpu.js';
18
18
  import { HTTPServer } from './http_server.js';
19
19
  import { InferenceRunner } from './inference_runner.js';
20
20
  import { InferenceProcExecutor } from './ipc/inference_proc_executor.js';
@@ -79,32 +79,11 @@ const defaultRequestFunc = async (ctx: JobRequest) => {
79
79
  await ctx.accept();
80
80
  };
81
81
 
82
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
83
- const defaultCpuLoad = async (worker: AgentServer): Promise<number> => {
84
- return new Promise((resolve) => {
85
- const cpus1 = os.cpus();
86
-
87
- setTimeout(() => {
88
- const cpus2 = os.cpus();
89
-
90
- let idle = 0;
91
- let total = 0;
92
-
93
- for (let i = 0; i < cpus1.length; i++) {
94
- const cpu1 = cpus1[i]!.times;
95
- const cpu2 = cpus2[i]!.times;
96
-
97
- idle += cpu2.idle - cpu1.idle;
98
-
99
- const total1 = Object.values(cpu1).reduce((acc, i) => acc + i, 0);
100
- const total2 = Object.values(cpu2).reduce((acc, i) => acc + i, 0);
82
+ const cpuMonitor = getCpuMonitor();
101
83
 
102
- total += total2 - total1;
103
- }
104
-
105
- resolve(+(1 - idle / total).toFixed(2));
106
- }, UPDATE_LOAD_INTERVAL);
107
- });
84
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
85
+ const defaultCpuLoad = async (_worker: AgentServer): Promise<number> => {
86
+ return cpuMonitor.cpuPercent(UPDATE_LOAD_INTERVAL);
108
87
  };
109
88
 
110
89
  /** Participant permissions to pass to every agent spun up by this worker. */
@@ -651,33 +630,38 @@ export class AgentServer {
651
630
  if (closingWS) clearInterval(loadMonitor);
652
631
 
653
632
  const oldStatus = currentStatus;
654
- this.#opts.loadFunc(this).then((currentLoad: number) => {
655
- const isFull = currentLoad >= this.#opts.loadThreshold;
656
- const currentlyAvailable = !isFull;
657
- currentStatus = currentlyAvailable ? WorkerStatus.WS_AVAILABLE : WorkerStatus.WS_FULL;
658
-
659
- if (oldStatus != currentStatus) {
660
- const extra = { load: currentLoad, loadThreshold: this.#opts.loadThreshold };
661
- if (isFull) {
662
- this.#logger.child(extra).info('worker is at full capacity, marking as unavailable');
663
- } else {
664
- this.#logger.child(extra).info('worker is below capacity, marking as available');
633
+ this.#opts
634
+ .loadFunc(this)
635
+ .then((currentLoad: number) => {
636
+ const isFull = currentLoad >= this.#opts.loadThreshold;
637
+ const currentlyAvailable = !isFull;
638
+ currentStatus = currentlyAvailable ? WorkerStatus.WS_AVAILABLE : WorkerStatus.WS_FULL;
639
+
640
+ if (oldStatus != currentStatus) {
641
+ const extra = { load: currentLoad, loadThreshold: this.#opts.loadThreshold };
642
+ if (isFull) {
643
+ this.#logger.child(extra).info('worker is at full capacity, marking as unavailable');
644
+ } else {
645
+ this.#logger.child(extra).info('worker is below capacity, marking as available');
646
+ }
665
647
  }
666
- }
667
648
 
668
- this.event.emit(
669
- 'worker_msg',
670
- new WorkerMessage({
671
- message: {
672
- case: 'updateWorker',
673
- value: {
674
- load: currentLoad,
675
- status: currentStatus,
649
+ this.event.emit(
650
+ 'worker_msg',
651
+ new WorkerMessage({
652
+ message: {
653
+ case: 'updateWorker',
654
+ value: {
655
+ load: currentLoad,
656
+ status: currentStatus,
657
+ },
676
658
  },
677
- },
678
- }),
679
- );
680
- });
659
+ }),
660
+ );
661
+ })
662
+ .catch((e) => {
663
+ this.#logger.warn({ error: e }, 'failed to measure CPU load');
664
+ });
681
665
  }, UPDATE_LOAD_INTERVAL);
682
666
 
683
667
  await close;
@@ -1,554 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var client_events_exports = {};
30
- __export(client_events_exports, {
31
- ClientEventsHandler: () => ClientEventsHandler,
32
- RemoteSession: () => RemoteSession
33
- });
34
- module.exports = __toCommonJS(client_events_exports);
35
- var import_events = __toESM(require("events"), 1);
36
- var import_constants = require("../constants.cjs");
37
- var import_log = require("../log.cjs");
38
- var import_utils = require("../utils.cjs");
39
- var import_events2 = require("./events.cjs");
40
- var import_wire_format = require("./wire_format.cjs");
41
- function serializeOptions(opts) {
42
- var _a, _b;
43
- return {
44
- endpointing: ((_a = opts.turnHandling) == null ? void 0 : _a.endpointing) ?? {},
45
- interruption: ((_b = opts.turnHandling) == null ? void 0 : _b.interruption) ?? {},
46
- max_tool_steps: opts.maxToolSteps,
47
- user_away_timeout: opts.userAwayTimeout,
48
- preemptive_generation: opts.preemptiveGeneration,
49
- use_tts_aligned_transcript: opts.useTtsAlignedTranscript
50
- };
51
- }
52
- function toolNames(toolCtx) {
53
- if (!toolCtx) return [];
54
- return Object.keys(toolCtx);
55
- }
56
- class ClientEventsHandler {
57
- session;
58
- roomIO;
59
- textInputCb;
60
- textStreamHandlerRegistered = false;
61
- rpcHandlersRegistered = false;
62
- requestHandlerRegistered = false;
63
- eventHandlersRegistered = false;
64
- started = false;
65
- tasks = /* @__PURE__ */ new Set();
66
- logger = (0, import_log.log)();
67
- constructor(session, roomIO) {
68
- this.session = session;
69
- this.roomIO = roomIO;
70
- }
71
- get room() {
72
- return this.roomIO.rtcRoom;
73
- }
74
- async start() {
75
- if (this.started) return;
76
- this.started = true;
77
- this.registerRpcHandlers();
78
- this.registerRequestHandler();
79
- this.registerEventHandlers();
80
- }
81
- async close() {
82
- if (!this.started) return;
83
- this.started = false;
84
- if (this.textStreamHandlerRegistered) {
85
- this.room.unregisterTextStreamHandler(import_constants.TOPIC_CHAT);
86
- this.textStreamHandlerRegistered = false;
87
- }
88
- if (this.rpcHandlersRegistered) {
89
- const localParticipant = this.room.localParticipant;
90
- if (localParticipant) {
91
- localParticipant.unregisterRpcMethod(import_constants.RPC_GET_SESSION_STATE);
92
- localParticipant.unregisterRpcMethod(import_constants.RPC_GET_CHAT_HISTORY);
93
- localParticipant.unregisterRpcMethod(import_constants.RPC_GET_AGENT_INFO);
94
- localParticipant.unregisterRpcMethod(import_constants.RPC_SEND_MESSAGE);
95
- }
96
- this.rpcHandlersRegistered = false;
97
- }
98
- if (this.requestHandlerRegistered) {
99
- this.room.unregisterTextStreamHandler(import_constants.TOPIC_AGENT_REQUEST);
100
- this.requestHandlerRegistered = false;
101
- }
102
- if (this.eventHandlersRegistered) {
103
- this.session.off(import_events2.AgentSessionEventTypes.AgentStateChanged, this.onAgentStateChanged);
104
- this.session.off(import_events2.AgentSessionEventTypes.UserStateChanged, this.onUserStateChanged);
105
- this.session.off(import_events2.AgentSessionEventTypes.ConversationItemAdded, this.onConversationItemAdded);
106
- this.session.off(import_events2.AgentSessionEventTypes.FunctionToolsExecuted, this.onFunctionToolsExecuted);
107
- this.session.off(import_events2.AgentSessionEventTypes.MetricsCollected, this.onMetricsCollected);
108
- this.session.off(import_events2.AgentSessionEventTypes.UserInputTranscribed, this.onUserInputTranscribed);
109
- this.session.off(import_events2.AgentSessionEventTypes.UserOverlappingSpeech, this.onUserOverlapSpeech);
110
- this.session.off(import_events2.AgentSessionEventTypes.Error, this.onError);
111
- this.eventHandlersRegistered = false;
112
- }
113
- await (0, import_utils.cancelAndWait)([...this.tasks]);
114
- this.tasks.clear();
115
- }
116
- /**
117
- * Registers a callback to handle text input from clients.
118
- *
119
- * This callback will be called when a client sends a text message to the agent.
120
- * The callback should return a promise that resolves when the text input has been processed.
121
- *
122
- * @param textInputCb - The callback to handle text input.
123
- */
124
- registerTextInput(textInputCb) {
125
- this.textInputCb = textInputCb;
126
- if (this.textStreamHandlerRegistered) return;
127
- this.room.registerTextStreamHandler(import_constants.TOPIC_CHAT, this.onUserTextInput);
128
- this.textStreamHandlerRegistered = true;
129
- }
130
- registerRpcHandlers() {
131
- if (this.rpcHandlersRegistered) return;
132
- const localParticipant = this.room.localParticipant;
133
- if (!localParticipant) return;
134
- localParticipant.registerRpcMethod(import_constants.RPC_GET_SESSION_STATE, this.rpcGetSessionState);
135
- localParticipant.registerRpcMethod(import_constants.RPC_GET_CHAT_HISTORY, this.rpcGetChatHistory);
136
- localParticipant.registerRpcMethod(import_constants.RPC_GET_AGENT_INFO, this.rpcGetAgentInfo);
137
- localParticipant.registerRpcMethod(import_constants.RPC_SEND_MESSAGE, this.rpcSendMessage);
138
- this.rpcHandlersRegistered = true;
139
- }
140
- registerRequestHandler() {
141
- if (this.requestHandlerRegistered) return;
142
- this.room.registerTextStreamHandler(import_constants.TOPIC_AGENT_REQUEST, this.onStreamRequest);
143
- this.requestHandlerRegistered = true;
144
- }
145
- registerEventHandlers() {
146
- if (this.eventHandlersRegistered) return;
147
- this.session.on(import_events2.AgentSessionEventTypes.AgentStateChanged, this.onAgentStateChanged);
148
- this.session.on(import_events2.AgentSessionEventTypes.UserStateChanged, this.onUserStateChanged);
149
- this.session.on(import_events2.AgentSessionEventTypes.ConversationItemAdded, this.onConversationItemAdded);
150
- this.session.on(import_events2.AgentSessionEventTypes.FunctionToolsExecuted, this.onFunctionToolsExecuted);
151
- this.session.on(import_events2.AgentSessionEventTypes.MetricsCollected, this.onMetricsCollected);
152
- this.session.on(import_events2.AgentSessionEventTypes.UserInputTranscribed, this.onUserInputTranscribed);
153
- this.session.on(import_events2.AgentSessionEventTypes.UserOverlappingSpeech, this.onUserOverlapSpeech);
154
- this.session.on(import_events2.AgentSessionEventTypes.Error, this.onError);
155
- this.eventHandlersRegistered = true;
156
- }
157
- onStreamRequest = (reader, participantInfo) => {
158
- const task = import_utils.Task.from(async () => this.handleStreamRequest(reader, participantInfo.identity));
159
- this.trackTask(task);
160
- };
161
- async handleStreamRequest(reader, participantIdentity) {
162
- try {
163
- const data = await reader.readAll();
164
- const request = import_wire_format.streamRequestSchema.parse(JSON.parse(data));
165
- let responsePayload = "";
166
- let error = null;
167
- try {
168
- switch (request.method) {
169
- case "get_session_state":
170
- responsePayload = await this.streamGetSessionState();
171
- break;
172
- case "get_chat_history":
173
- responsePayload = await this.streamGetChatHistory();
174
- break;
175
- case "get_agent_info":
176
- responsePayload = await this.streamGetAgentInfo();
177
- break;
178
- case "send_message":
179
- responsePayload = await this.streamSendMessage(request.payload);
180
- break;
181
- case "get_rtc_stats":
182
- responsePayload = await this.streamGetRtcStats();
183
- break;
184
- case "get_session_usage":
185
- responsePayload = await this.streamGetSessionUsage();
186
- break;
187
- default:
188
- error = `Unknown method: ${request.method}`;
189
- }
190
- } catch (e) {
191
- error = e instanceof Error ? e.message : String(e);
192
- }
193
- const response = {
194
- request_id: request.request_id,
195
- payload: responsePayload,
196
- error
197
- };
198
- const localParticipant = this.room.localParticipant;
199
- await localParticipant.sendText(JSON.stringify(response), {
200
- topic: import_constants.TOPIC_AGENT_RESPONSE,
201
- destinationIdentities: [participantIdentity]
202
- });
203
- } catch (e) {
204
- this.logger.warn({ error: e }, "failed to handle stream request");
205
- }
206
- }
207
- async streamGetSessionState() {
208
- const agent = this.session.currentAgent;
209
- const response = {
210
- agent_state: this.session.agentState,
211
- user_state: this.session.userState,
212
- agent_id: agent.id,
213
- options: serializeOptions({
214
- turnHandling: this.session.options.turnHandling,
215
- maxToolSteps: this.session.options.maxToolSteps,
216
- userAwayTimeout: this.session.options.userAwayTimeout,
217
- preemptiveGeneration: this.session.options.preemptiveGeneration,
218
- useTtsAlignedTranscript: this.session.options.useTtsAlignedTranscript
219
- }),
220
- created_at: (0, import_wire_format.msToS)(this.session._startedAt ?? Date.now())
221
- };
222
- return JSON.stringify(response);
223
- }
224
- async streamGetChatHistory() {
225
- return JSON.stringify({
226
- items: this.session.history.items.map(import_wire_format.chatItemToWire)
227
- });
228
- }
229
- async streamGetAgentInfo() {
230
- const agent = this.session.currentAgent;
231
- return JSON.stringify({
232
- id: agent.id,
233
- instructions: agent.instructions,
234
- tools: toolNames(agent.toolCtx),
235
- chat_ctx: agent.chatCtx.items.map(import_wire_format.chatItemToWire)
236
- });
237
- }
238
- async streamSendMessage(payload) {
239
- const request = import_wire_format.sendMessageRequestSchema.parse(JSON.parse(payload));
240
- const runResult = this.session.run({ userInput: request.text });
241
- await runResult.wait();
242
- return JSON.stringify({
243
- items: runResult.events.map((ev) => (0, import_wire_format.chatItemToWire)(ev.item))
244
- });
245
- }
246
- async streamGetRtcStats() {
247
- return JSON.stringify({
248
- publisher_stats: [],
249
- subscriber_stats: []
250
- });
251
- }
252
- async streamGetSessionUsage() {
253
- return JSON.stringify({
254
- usage: (0, import_wire_format.agentSessionUsageToWire)(this.session.usage),
255
- created_at: (0, import_wire_format.msToS)(Date.now())
256
- });
257
- }
258
- onUserOverlapSpeech = (event) => {
259
- const clientEvent = {
260
- type: "user_overlapping_speech",
261
- is_interruption: event.isInterruption,
262
- created_at: (0, import_wire_format.msToS)(event.timestamp),
263
- overlap_started_at: event.overlapStartedAt != null ? (0, import_wire_format.msToS)(event.overlapStartedAt) : null,
264
- detection_delay: event.detectionDelayInS,
265
- sent_at: (0, import_wire_format.msToS)(Date.now())
266
- };
267
- this.streamClientEvent(clientEvent);
268
- };
269
- onAgentStateChanged = (event) => {
270
- const clientEvent = {
271
- type: "agent_state_changed",
272
- old_state: event.oldState,
273
- new_state: event.newState,
274
- created_at: (0, import_wire_format.msToS)(event.createdAt)
275
- };
276
- this.streamClientEvent(clientEvent);
277
- };
278
- onUserStateChanged = (event) => {
279
- const clientEvent = {
280
- type: "user_state_changed",
281
- old_state: event.oldState,
282
- new_state: event.newState,
283
- created_at: (0, import_wire_format.msToS)(event.createdAt)
284
- };
285
- this.streamClientEvent(clientEvent);
286
- };
287
- onConversationItemAdded = (event) => {
288
- if (event.item.type !== "message") {
289
- return;
290
- }
291
- this.streamClientEvent({
292
- type: "conversation_item_added",
293
- item: (0, import_wire_format.chatMessageToWire)(event.item),
294
- created_at: (0, import_wire_format.msToS)(event.createdAt)
295
- });
296
- };
297
- onUserInputTranscribed = (event) => {
298
- this.streamClientEvent({
299
- type: "user_input_transcribed",
300
- transcript: event.transcript,
301
- is_final: event.isFinal,
302
- language: event.language,
303
- created_at: (0, import_wire_format.msToS)(event.createdAt)
304
- });
305
- };
306
- onFunctionToolsExecuted = (event) => {
307
- this.streamClientEvent({
308
- type: "function_tools_executed",
309
- function_calls: event.functionCalls.map(
310
- import_wire_format.functionCallToWire
311
- ),
312
- function_call_outputs: event.functionCallOutputs.map(
313
- (o) => o ? (0, import_wire_format.functionCallOutputToWire)(o) : null
314
- ),
315
- created_at: (0, import_wire_format.msToS)(event.createdAt)
316
- });
317
- };
318
- onMetricsCollected = (event) => {
319
- this.streamClientEvent({
320
- type: "metrics_collected",
321
- metrics: (0, import_wire_format.agentMetricsToWire)(event.metrics),
322
- created_at: (0, import_wire_format.msToS)(event.createdAt)
323
- });
324
- this.streamClientEvent({
325
- type: "session_usage",
326
- usage: (0, import_wire_format.agentSessionUsageToWire)(this.session.usage),
327
- created_at: (0, import_wire_format.msToS)(Date.now())
328
- });
329
- };
330
- onError = (event) => {
331
- const clientEvent = {
332
- type: "error",
333
- message: event.error ? String(event.error) : "Unknown error",
334
- created_at: (0, import_wire_format.msToS)(event.createdAt)
335
- };
336
- this.streamClientEvent(clientEvent);
337
- };
338
- getTargetIdentities() {
339
- const linked = this.roomIO.linkedParticipant;
340
- return linked ? [linked.identity] : null;
341
- }
342
- streamClientEvent(event) {
343
- const task = import_utils.Task.from(async () => this.sendClientEvent(event));
344
- this.trackTask(task);
345
- }
346
- async sendClientEvent(event) {
347
- if (!this.room.isConnected) return;
348
- const destinationIdentities = this.getTargetIdentities();
349
- if (!destinationIdentities) return;
350
- try {
351
- const localParticipant = this.room.localParticipant;
352
- if (!localParticipant) return;
353
- const writer = await localParticipant.streamText({
354
- topic: import_constants.TOPIC_CLIENT_EVENTS,
355
- destinationIdentities
356
- });
357
- await writer.write(JSON.stringify(event));
358
- await writer.close();
359
- } catch (e) {
360
- this.logger.warn({ error: e }, "failed to stream event to clients");
361
- }
362
- }
363
- rpcGetSessionState = async () => {
364
- return this.streamGetSessionState();
365
- };
366
- rpcGetChatHistory = async () => {
367
- return this.streamGetChatHistory();
368
- };
369
- rpcGetAgentInfo = async () => {
370
- return this.streamGetAgentInfo();
371
- };
372
- rpcSendMessage = async (data) => {
373
- return this.streamSendMessage(data.payload);
374
- };
375
- onUserTextInput = (reader, participantInfo) => {
376
- const linkedParticipant = this.roomIO.linkedParticipant;
377
- if (linkedParticipant && participantInfo.identity !== linkedParticipant.identity) {
378
- return;
379
- }
380
- const participant = this.room.remoteParticipants.get(participantInfo.identity);
381
- if (!participant) {
382
- this.logger.warn("participant not found, ignoring text input");
383
- return;
384
- }
385
- if (!this.textInputCb) {
386
- this.logger.error("text input callback is not set, ignoring text input");
387
- return;
388
- }
389
- const task = import_utils.Task.from(async () => {
390
- const text = await reader.readAll();
391
- const result = this.textInputCb(this.session, {
392
- text,
393
- info: reader.info,
394
- participantIdentity: participantInfo.identity
395
- });
396
- if (result instanceof Promise) {
397
- await result;
398
- }
399
- });
400
- this.trackTask(task);
401
- };
402
- trackTask(task) {
403
- this.tasks.add(task);
404
- task.addDoneCallback(() => {
405
- this.tasks.delete(task);
406
- });
407
- }
408
- }
409
- class RemoteSession extends import_events.default {
410
- room;
411
- agentIdentity;
412
- started = false;
413
- tasks = /* @__PURE__ */ new Set();
414
- pendingRequests = /* @__PURE__ */ new Map();
415
- logger = (0, import_log.log)();
416
- constructor(room, agentIdentity) {
417
- super();
418
- this.room = room;
419
- this.agentIdentity = agentIdentity;
420
- }
421
- async start() {
422
- if (this.started) return;
423
- this.started = true;
424
- this.room.registerTextStreamHandler(import_constants.TOPIC_CLIENT_EVENTS, this.onEventStream);
425
- this.room.registerTextStreamHandler(import_constants.TOPIC_AGENT_RESPONSE, this.onResponseStream);
426
- }
427
- async close() {
428
- if (!this.started) return;
429
- this.started = false;
430
- this.room.unregisterTextStreamHandler(import_constants.TOPIC_CLIENT_EVENTS);
431
- this.room.unregisterTextStreamHandler(import_constants.TOPIC_AGENT_RESPONSE);
432
- for (const pending of this.pendingRequests.values()) {
433
- pending.reject(new Error("RemoteSession closed"));
434
- }
435
- this.pendingRequests.clear();
436
- await (0, import_utils.cancelAndWait)([...this.tasks]);
437
- this.tasks.clear();
438
- }
439
- onEventStream = (reader, participantInfo) => {
440
- if (participantInfo.identity !== this.agentIdentity) return;
441
- this.trackTask(import_utils.Task.from(async () => this.readEvent(reader)));
442
- };
443
- onResponseStream = (reader, participantInfo) => {
444
- if (participantInfo.identity !== this.agentIdentity) return;
445
- this.trackTask(import_utils.Task.from(async () => this.readResponse(reader)));
446
- };
447
- async readResponse(reader) {
448
- try {
449
- const data = await reader.readAll();
450
- const response = import_wire_format.streamResponseSchema.parse(JSON.parse(data));
451
- const future = this.pendingRequests.get(response.request_id);
452
- this.pendingRequests.delete(response.request_id);
453
- if (!future || future.done) return;
454
- future.resolve(response);
455
- } catch (e) {
456
- this.logger.warn({ error: e }, "failed to read stream response");
457
- }
458
- }
459
- async readEvent(reader) {
460
- try {
461
- const data = await reader.readAll();
462
- const event = this.parseEvent(data);
463
- if (event) {
464
- this.emit(event.type, event);
465
- }
466
- } catch (e) {
467
- this.logger.warn({ error: e }, "failed to parse client event");
468
- }
469
- }
470
- parseEvent(data) {
471
- try {
472
- const result = import_wire_format.clientEventSchema.safeParse(JSON.parse(data));
473
- if (!result.success) {
474
- this.logger.warn({ error: result.error }, "failed to validate event");
475
- return null;
476
- }
477
- return result.data;
478
- } catch (e) {
479
- this.logger.warn({ error: e }, "failed to parse event");
480
- return null;
481
- }
482
- }
483
- async sendRequest(method, payload, timeout = 6e4) {
484
- const requestId = (0, import_utils.shortuuid)("req_");
485
- const request = {
486
- request_id: requestId,
487
- method,
488
- payload
489
- };
490
- const future = new import_utils.Future();
491
- this.pendingRequests.set(requestId, future);
492
- const localParticipant = this.room.localParticipant;
493
- if (!localParticipant) {
494
- this.pendingRequests.delete(requestId);
495
- throw new Error("RemoteSession room has no local participant");
496
- }
497
- await localParticipant.sendText(JSON.stringify(request), {
498
- topic: import_constants.TOPIC_AGENT_REQUEST,
499
- destinationIdentities: [this.agentIdentity]
500
- });
501
- const timer = setTimeout(() => {
502
- if (!future.done) {
503
- this.pendingRequests.delete(requestId);
504
- future.reject(new Error(`RemoteSession request timed out: ${method}`));
505
- }
506
- }, timeout);
507
- try {
508
- const response = await future.await;
509
- if (response.error) {
510
- throw new Error(response.error);
511
- }
512
- return response.payload;
513
- } finally {
514
- clearTimeout(timer);
515
- }
516
- }
517
- async fetchSessionState() {
518
- const raw = JSON.parse(await this.sendRequest("get_session_state", "{}"));
519
- return import_wire_format.getSessionStateResponseSchema.parse(raw);
520
- }
521
- async fetchChatHistory() {
522
- const raw = JSON.parse(await this.sendRequest("get_chat_history", "{}"));
523
- return import_wire_format.getChatHistoryResponseSchema.parse(raw);
524
- }
525
- async fetchAgentInfo() {
526
- const raw = JSON.parse(await this.sendRequest("get_agent_info", "{}"));
527
- return import_wire_format.getAgentInfoResponseSchema.parse(raw);
528
- }
529
- async sendMessage(text, responseTimeout = 6e4) {
530
- const payload = JSON.stringify({ text });
531
- const raw = JSON.parse(await this.sendRequest("send_message", payload, responseTimeout));
532
- return import_wire_format.sendMessageResponseSchema.parse(raw);
533
- }
534
- async fetchRtcStats() {
535
- const raw = JSON.parse(await this.sendRequest("get_rtc_stats", "{}"));
536
- return import_wire_format.getRTCStatsResponseSchema.parse(raw);
537
- }
538
- async fetchSessionUsage() {
539
- const raw = JSON.parse(await this.sendRequest("get_session_usage", "{}"));
540
- return import_wire_format.getSessionUsageResponseSchema.parse(raw);
541
- }
542
- trackTask(task) {
543
- this.tasks.add(task);
544
- task.addDoneCallback(() => {
545
- this.tasks.delete(task);
546
- });
547
- }
548
- }
549
- // Annotate the CommonJS export names for ESM import in node:
550
- 0 && (module.exports = {
551
- ClientEventsHandler,
552
- RemoteSession
553
- });
554
- //# sourceMappingURL=client_events.cjs.map