@livekit/agents 0.3.4 → 0.4.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 (188) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +40 -0
  3. package/dist/audio.js +17 -30
  4. package/dist/audio.js.map +1 -1
  5. package/dist/cli.js +3 -14
  6. package/dist/cli.js.map +1 -1
  7. package/dist/http_server.d.ts +1 -1
  8. package/dist/http_server.js +5 -9
  9. package/dist/http_server.js.map +1 -1
  10. package/dist/index.d.ts +3 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +14 -2
  13. package/dist/index.js.map +1 -1
  14. package/dist/ipc/job_executor.js +3 -5
  15. package/dist/ipc/job_executor.js.map +1 -1
  16. package/dist/ipc/job_main.d.ts +1 -1
  17. package/dist/ipc/proc_job_executor.js +66 -80
  18. package/dist/ipc/proc_job_executor.js.map +1 -1
  19. package/dist/ipc/proc_pool.d.ts +3 -3
  20. package/dist/ipc/proc_pool.d.ts.map +1 -1
  21. package/dist/ipc/proc_pool.js +16 -11
  22. package/dist/ipc/proc_pool.js.map +1 -1
  23. package/dist/job.js +56 -73
  24. package/dist/job.js.map +1 -1
  25. package/dist/llm/chat_context.d.ts +66 -0
  26. package/dist/llm/chat_context.d.ts.map +1 -0
  27. package/dist/llm/chat_context.js +93 -0
  28. package/dist/llm/chat_context.js.map +1 -0
  29. package/dist/llm/function_context.d.ts +19 -1
  30. package/dist/llm/function_context.d.ts.map +1 -1
  31. package/dist/llm/function_context.js +54 -18
  32. package/dist/llm/function_context.js.map +1 -1
  33. package/dist/llm/function_context.test.d.ts +2 -0
  34. package/dist/llm/function_context.test.d.ts.map +1 -0
  35. package/dist/llm/function_context.test.js +218 -0
  36. package/dist/llm/function_context.test.js.map +1 -0
  37. package/dist/llm/index.d.ts +3 -2
  38. package/dist/llm/index.d.ts.map +1 -1
  39. package/dist/llm/index.js +3 -2
  40. package/dist/llm/index.js.map +1 -1
  41. package/dist/llm/llm.d.ts +53 -0
  42. package/dist/llm/llm.d.ts.map +1 -0
  43. package/dist/llm/llm.js +45 -0
  44. package/dist/llm/llm.js.map +1 -0
  45. package/dist/multimodal/agent_playout.d.ts +1 -1
  46. package/dist/multimodal/agent_playout.js +116 -153
  47. package/dist/multimodal/agent_playout.js.map +1 -1
  48. package/dist/multimodal/multimodal_agent.d.ts +4 -3
  49. package/dist/multimodal/multimodal_agent.d.ts.map +1 -1
  50. package/dist/multimodal/multimodal_agent.js +214 -237
  51. package/dist/multimodal/multimodal_agent.js.map +1 -1
  52. package/dist/pipeline/agent_output.d.ts +30 -0
  53. package/dist/pipeline/agent_output.d.ts.map +1 -0
  54. package/dist/pipeline/agent_output.js +155 -0
  55. package/dist/pipeline/agent_output.js.map +1 -0
  56. package/dist/pipeline/agent_playout.d.ts +38 -0
  57. package/dist/pipeline/agent_playout.d.ts.map +1 -0
  58. package/dist/pipeline/agent_playout.js +142 -0
  59. package/dist/pipeline/agent_playout.js.map +1 -0
  60. package/dist/pipeline/human_input.d.ts +28 -0
  61. package/dist/pipeline/human_input.d.ts.map +1 -0
  62. package/dist/pipeline/human_input.js +134 -0
  63. package/dist/pipeline/human_input.js.map +1 -0
  64. package/dist/pipeline/index.d.ts +2 -0
  65. package/dist/pipeline/index.d.ts.map +1 -0
  66. package/dist/pipeline/index.js +5 -0
  67. package/dist/pipeline/index.js.map +1 -0
  68. package/dist/pipeline/pipeline_agent.d.ts +134 -0
  69. package/dist/pipeline/pipeline_agent.d.ts.map +1 -0
  70. package/dist/pipeline/pipeline_agent.js +661 -0
  71. package/dist/pipeline/pipeline_agent.js.map +1 -0
  72. package/dist/pipeline/speech_handle.d.ts +27 -0
  73. package/dist/pipeline/speech_handle.d.ts.map +1 -0
  74. package/dist/pipeline/speech_handle.js +102 -0
  75. package/dist/pipeline/speech_handle.js.map +1 -0
  76. package/dist/plugin.js +7 -20
  77. package/dist/plugin.js.map +1 -1
  78. package/dist/stt/index.d.ts +1 -2
  79. package/dist/stt/index.d.ts.map +1 -1
  80. package/dist/stt/index.js +1 -2
  81. package/dist/stt/index.js.map +1 -1
  82. package/dist/stt/stt.d.ts +62 -24
  83. package/dist/stt/stt.d.ts.map +1 -1
  84. package/dist/stt/stt.js +77 -27
  85. package/dist/stt/stt.js.map +1 -1
  86. package/dist/tokenize/basic/basic.d.ts +16 -0
  87. package/dist/tokenize/basic/basic.d.ts.map +1 -0
  88. package/dist/tokenize/basic/basic.js +50 -0
  89. package/dist/tokenize/basic/basic.js.map +1 -0
  90. package/dist/tokenize/basic/hyphenator.d.ts +17 -0
  91. package/dist/tokenize/basic/hyphenator.d.ts.map +1 -0
  92. package/dist/tokenize/basic/hyphenator.js +420 -0
  93. package/dist/tokenize/basic/hyphenator.js.map +1 -0
  94. package/dist/tokenize/basic/index.d.ts +2 -0
  95. package/dist/tokenize/basic/index.d.ts.map +1 -0
  96. package/dist/tokenize/basic/index.js +5 -0
  97. package/dist/tokenize/basic/index.js.map +1 -0
  98. package/dist/tokenize/basic/paragraph.d.ts +5 -0
  99. package/dist/tokenize/basic/paragraph.d.ts.map +1 -0
  100. package/dist/tokenize/basic/paragraph.js +38 -0
  101. package/dist/tokenize/basic/paragraph.js.map +1 -0
  102. package/dist/tokenize/basic/sentence.d.ts +5 -0
  103. package/dist/tokenize/basic/sentence.d.ts.map +1 -0
  104. package/dist/tokenize/basic/sentence.js +60 -0
  105. package/dist/tokenize/basic/sentence.js.map +1 -0
  106. package/dist/tokenize/basic/word.d.ts +5 -0
  107. package/dist/tokenize/basic/word.d.ts.map +1 -0
  108. package/dist/tokenize/basic/word.js +23 -0
  109. package/dist/tokenize/basic/word.js.map +1 -0
  110. package/dist/tokenize/index.d.ts +5 -0
  111. package/dist/tokenize/index.d.ts.map +1 -0
  112. package/dist/tokenize/index.js +8 -0
  113. package/dist/tokenize/index.js.map +1 -0
  114. package/dist/tokenize/token_stream.d.ts +36 -0
  115. package/dist/tokenize/token_stream.d.ts.map +1 -0
  116. package/dist/tokenize/token_stream.js +136 -0
  117. package/dist/tokenize/token_stream.js.map +1 -0
  118. package/dist/tokenize/tokenizer.d.ts +55 -0
  119. package/dist/tokenize/tokenizer.d.ts.map +1 -0
  120. package/dist/tokenize/tokenizer.js +117 -0
  121. package/dist/tokenize/tokenizer.js.map +1 -0
  122. package/dist/transcription.js +78 -89
  123. package/dist/transcription.js.map +1 -1
  124. package/dist/tts/index.d.ts +1 -3
  125. package/dist/tts/index.d.ts.map +1 -1
  126. package/dist/tts/index.js +1 -3
  127. package/dist/tts/index.js.map +1 -1
  128. package/dist/tts/tts.d.ts +66 -37
  129. package/dist/tts/tts.d.ts.map +1 -1
  130. package/dist/tts/tts.js +79 -74
  131. package/dist/tts/tts.js.map +1 -1
  132. package/dist/utils.d.ts +21 -6
  133. package/dist/utils.d.ts.map +1 -1
  134. package/dist/utils.js +120 -76
  135. package/dist/utils.js.map +1 -1
  136. package/dist/vad.d.ts +43 -39
  137. package/dist/vad.d.ts.map +1 -1
  138. package/dist/vad.js +51 -4
  139. package/dist/vad.js.map +1 -1
  140. package/dist/worker.d.ts +1 -1
  141. package/dist/worker.js +257 -247
  142. package/dist/worker.js.map +1 -1
  143. package/package.json +4 -3
  144. package/src/index.ts +16 -2
  145. package/src/ipc/proc_pool.ts +4 -4
  146. package/src/llm/chat_context.ts +147 -0
  147. package/src/llm/function_context.test.ts +248 -0
  148. package/src/llm/function_context.ts +77 -18
  149. package/src/llm/index.ts +21 -2
  150. package/src/llm/llm.ts +102 -0
  151. package/src/multimodal/multimodal_agent.ts +19 -6
  152. package/src/pipeline/agent_output.ts +185 -0
  153. package/src/pipeline/agent_playout.ts +187 -0
  154. package/src/pipeline/human_input.ts +166 -0
  155. package/src/pipeline/index.ts +15 -0
  156. package/src/pipeline/pipeline_agent.ts +917 -0
  157. package/src/pipeline/speech_handle.ts +136 -0
  158. package/src/stt/index.ts +8 -2
  159. package/src/stt/stt.ts +98 -31
  160. package/src/tokenize/basic/basic.ts +73 -0
  161. package/src/tokenize/basic/hyphenator.ts +436 -0
  162. package/src/tokenize/basic/index.ts +5 -0
  163. package/src/tokenize/basic/paragraph.ts +43 -0
  164. package/src/tokenize/basic/sentence.ts +69 -0
  165. package/src/tokenize/basic/word.ts +27 -0
  166. package/src/tokenize/index.ts +16 -0
  167. package/src/tokenize/token_stream.ts +163 -0
  168. package/src/tokenize/tokenizer.ts +152 -0
  169. package/src/tts/index.ts +1 -20
  170. package/src/tts/tts.ts +110 -57
  171. package/src/utils.ts +95 -25
  172. package/src/vad.ts +86 -45
  173. package/tsconfig.tsbuildinfo +1 -1
  174. package/dist/stt/stream_adapter.d.ts +0 -19
  175. package/dist/stt/stream_adapter.d.ts.map +0 -1
  176. package/dist/stt/stream_adapter.js +0 -96
  177. package/dist/stt/stream_adapter.js.map +0 -1
  178. package/dist/tokenize.d.ts +0 -15
  179. package/dist/tokenize.d.ts.map +0 -1
  180. package/dist/tokenize.js +0 -12
  181. package/dist/tokenize.js.map +0 -1
  182. package/dist/tts/stream_adapter.d.ts +0 -19
  183. package/dist/tts/stream_adapter.d.ts.map +0 -1
  184. package/dist/tts/stream_adapter.js +0 -111
  185. package/dist/tts/stream_adapter.js.map +0 -1
  186. package/src/stt/stream_adapter.ts +0 -104
  187. package/src/tokenize.ts +0 -22
  188. package/src/tts/stream_adapter.ts +0 -93
package/dist/worker.js CHANGED
@@ -1,15 +1,3 @@
1
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
- if (kind === "m") throw new TypeError("Private method is not writable");
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
- };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _Worker_instances, _Worker_opts, _Worker_procPool, _Worker_id, _Worker_closed, _Worker_draining, _Worker_connecting, _Worker_tasks, _Worker_pending, _Worker_close, _Worker_session, _Worker_httpServer, _Worker_logger, _Worker_runWS, _Worker_availability, _Worker_termination;
13
1
  import { JobType, ParticipantPermission, ServerMessage, WorkerMessage, WorkerStatus, } from '@livekit/protocol';
14
2
  import { AccessToken, RoomServiceClient } from 'livekit-server-sdk';
15
3
  import { EventEmitter } from 'node:events';
@@ -90,6 +78,12 @@ const defaultCpuLoad = async () => {
90
78
  };
91
79
  /** Participant permissions to pass to every agent spun up by this worker. */
92
80
  export class WorkerPermissions {
81
+ canPublish;
82
+ canSubscribe;
83
+ canPublishData;
84
+ canUpdateMetadata;
85
+ canPublishSources;
86
+ hidden;
93
87
  constructor(canPublish = true, canSubscribe = true, canPublishData = true, canUpdateMetadata = true, canPublishSources = [], hidden = false) {
94
88
  this.canPublish = canPublish;
95
89
  this.canSubscribe = canSubscribe;
@@ -109,6 +103,24 @@ export class WorkerPermissions {
109
103
  * This class is mostly useful in conjunction with {@link cli.runApp}.
110
104
  */
111
105
  export class WorkerOptions {
106
+ agent;
107
+ requestFunc;
108
+ loadFunc;
109
+ loadThreshold;
110
+ numIdleProcesses;
111
+ shutdownProcessTimeout;
112
+ initializeProcessTimeout;
113
+ permissions;
114
+ agentName;
115
+ workerType;
116
+ maxRetry;
117
+ wsURL;
118
+ apiKey;
119
+ apiSecret;
120
+ host;
121
+ port;
122
+ logLevel;
123
+ production;
112
124
  /** @param options */
113
125
  constructor({ agent, requestFunc = defaultRequestFunc, loadFunc = defaultCpuLoad, loadThreshold = undefined, numIdleProcesses = undefined, shutdownProcessTimeout = 60 * 1000, initializeProcessTimeout = 10 * 1000, permissions = new WorkerPermissions(), agentName = '', workerType = JobType.JT_ROOM, maxRetry = MAX_RECONNECT_ATTEMPTS, wsURL = 'ws://localhost:7880', apiKey = undefined, apiSecret = undefined, host = 'localhost', port = undefined, logLevel = 'info', production = false, }) {
114
126
  this.agent = agent;
@@ -135,11 +147,9 @@ export class WorkerOptions {
135
147
  }
136
148
  }
137
149
  class PendingAssignment {
138
- constructor() {
139
- this.promise = new Promise((resolve) => {
140
- this.resolve = resolve; // this is how JavaScript lets you resolve promises externally
141
- });
142
- }
150
+ promise = new Promise((resolve) => {
151
+ this.resolve = resolve; // this is how JavaScript lets you resolve promises externally
152
+ });
143
153
  resolve(arg) {
144
154
  arg; // useless call to counteract TypeScript E6133
145
155
  }
@@ -154,22 +164,21 @@ class PendingAssignment {
154
164
  * behind a wrapper.
155
165
  */
156
166
  export class Worker {
167
+ #opts;
168
+ #procPool;
169
+ #id = 'unregistered';
170
+ #closed = true;
171
+ #draining = false;
172
+ #connecting = false;
173
+ #tasks = [];
174
+ #pending = {};
175
+ #close = new Future();
176
+ event = new EventEmitter();
177
+ #session = undefined;
178
+ #httpServer;
179
+ #logger = log().child({ version });
157
180
  /* @throws {@link MissingCredentialsError} if URL, API key or API secret are missing */
158
181
  constructor(opts) {
159
- _Worker_instances.add(this);
160
- _Worker_opts.set(this, void 0);
161
- _Worker_procPool.set(this, void 0);
162
- _Worker_id.set(this, 'unregistered');
163
- _Worker_closed.set(this, true);
164
- _Worker_draining.set(this, false);
165
- _Worker_connecting.set(this, false);
166
- _Worker_tasks.set(this, []);
167
- _Worker_pending.set(this, {});
168
- _Worker_close.set(this, new Future());
169
- this.event = new EventEmitter();
170
- _Worker_session.set(this, undefined);
171
- _Worker_httpServer.set(this, void 0);
172
- _Worker_logger.set(this, log().child({ version }));
173
182
  opts.wsURL = opts.wsURL || process.env.LIVEKIT_URL || '';
174
183
  opts.apiKey = opts.apiKey || process.env.LIVEKIT_API_KEY || '';
175
184
  opts.apiSecret = opts.apiSecret || process.env.LIVEKIT_API_SECRET || '';
@@ -179,72 +188,72 @@ export class Worker {
179
188
  throw new MissingCredentialsError('API Key is required: Set LIVEKIT_API_KEY, run with --api-key, or pass apiKey in WorkerOptions');
180
189
  if (opts.apiSecret === '')
181
190
  throw new MissingCredentialsError('API Secret is required: Set LIVEKIT_API_SECRET, run with --api-secret, or pass apiSecret in WorkerOptions');
182
- __classPrivateFieldSet(this, _Worker_procPool, new ProcPool(opts.agent, opts.numIdleProcesses, opts.initializeProcessTimeout, opts.shutdownProcessTimeout), "f");
183
- __classPrivateFieldSet(this, _Worker_opts, opts, "f");
184
- __classPrivateFieldSet(this, _Worker_httpServer, new HTTPServer(opts.host, opts.port), "f");
191
+ this.#procPool = new ProcPool(opts.agent, opts.numIdleProcesses, opts.initializeProcessTimeout, opts.shutdownProcessTimeout);
192
+ this.#opts = opts;
193
+ this.#httpServer = new HTTPServer(opts.host, opts.port);
185
194
  }
186
195
  /* @throws {@link WorkerError} if worker failed to connect or already running */
187
196
  async run() {
188
- if (!__classPrivateFieldGet(this, _Worker_closed, "f")) {
197
+ if (!this.#closed) {
189
198
  throw new WorkerError('worker is already running');
190
199
  }
191
- __classPrivateFieldGet(this, _Worker_logger, "f").info('starting worker');
192
- __classPrivateFieldSet(this, _Worker_closed, false, "f");
193
- __classPrivateFieldGet(this, _Worker_procPool, "f").start();
200
+ this.#logger.info('starting worker');
201
+ this.#closed = false;
202
+ this.#procPool.start();
194
203
  const workerWS = async () => {
195
204
  let retries = 0;
196
- __classPrivateFieldSet(this, _Worker_connecting, true, "f");
197
- while (!__classPrivateFieldGet(this, _Worker_closed, "f")) {
198
- const url = new URL(__classPrivateFieldGet(this, _Worker_opts, "f").wsURL);
205
+ this.#connecting = true;
206
+ while (!this.#closed) {
207
+ const url = new URL(this.#opts.wsURL);
199
208
  url.protocol = url.protocol.replace('http', 'ws');
200
- const token = new AccessToken(__classPrivateFieldGet(this, _Worker_opts, "f").apiKey, __classPrivateFieldGet(this, _Worker_opts, "f").apiSecret);
209
+ const token = new AccessToken(this.#opts.apiKey, this.#opts.apiSecret);
201
210
  token.addGrant({ agent: true });
202
211
  const jwt = await token.toJwt();
203
- __classPrivateFieldSet(this, _Worker_session, new WebSocket(url + 'agent', {
212
+ this.#session = new WebSocket(url + 'agent', {
204
213
  headers: { authorization: 'Bearer ' + jwt },
205
- }), "f");
214
+ });
206
215
  try {
207
216
  await new Promise((resolve, reject) => {
208
- __classPrivateFieldGet(this, _Worker_session, "f").on('open', resolve);
209
- __classPrivateFieldGet(this, _Worker_session, "f").on('error', (error) => reject(error));
210
- __classPrivateFieldGet(this, _Worker_session, "f").on('close', (code) => reject(new Error(`WebSocket returned ${code}`)));
217
+ this.#session.on('open', resolve);
218
+ this.#session.on('error', (error) => reject(error));
219
+ this.#session.on('close', (code) => reject(new Error(`WebSocket returned ${code}`)));
211
220
  });
212
221
  retries = 0;
213
- __classPrivateFieldGet(this, _Worker_logger, "f").debug('connected to LiveKit server');
214
- __classPrivateFieldGet(this, _Worker_instances, "m", _Worker_runWS).call(this, __classPrivateFieldGet(this, _Worker_session, "f"));
222
+ this.#logger.debug('connected to LiveKit server');
223
+ this.#runWS(this.#session);
215
224
  return;
216
225
  }
217
226
  catch (e) {
218
- if (__classPrivateFieldGet(this, _Worker_closed, "f"))
227
+ if (this.#closed)
219
228
  return;
220
- if (retries >= __classPrivateFieldGet(this, _Worker_opts, "f").maxRetry) {
229
+ if (retries >= this.#opts.maxRetry) {
221
230
  throw new WorkerError(`failed to connect to LiveKit server after ${retries} attempts: ${e}`);
222
231
  }
223
232
  retries++;
224
233
  const delay = Math.min(retries * 2, 10);
225
- __classPrivateFieldGet(this, _Worker_logger, "f").warn(`failed to connect to LiveKit server, retrying in ${delay} seconds: ${e} (${retries}/${__classPrivateFieldGet(this, _Worker_opts, "f").maxRetry})`);
234
+ this.#logger.warn(`failed to connect to LiveKit server, retrying in ${delay} seconds: ${e} (${retries}/${this.#opts.maxRetry})`);
226
235
  await new Promise((resolve) => setTimeout(resolve, delay * 1000));
227
236
  }
228
237
  }
229
238
  };
230
- await Promise.all([workerWS(), __classPrivateFieldGet(this, _Worker_httpServer, "f").run()]);
231
- __classPrivateFieldGet(this, _Worker_close, "f").resolve();
239
+ await Promise.all([workerWS(), this.#httpServer.run()]);
240
+ this.#close.resolve();
232
241
  }
233
242
  get id() {
234
- return __classPrivateFieldGet(this, _Worker_id, "f");
243
+ return this.#id;
235
244
  }
236
245
  get activeJobs() {
237
- return __classPrivateFieldGet(this, _Worker_procPool, "f").processes
246
+ return this.#procPool.processes
238
247
  .filter((proc) => proc.runningJob)
239
248
  .map((proc) => proc.runningJob);
240
249
  }
241
250
  /* @throws {@link WorkerError} if worker did not drain in time */
242
251
  async drain(timeout) {
243
- if (__classPrivateFieldGet(this, _Worker_draining, "f")) {
252
+ if (this.#draining) {
244
253
  return;
245
254
  }
246
- __classPrivateFieldGet(this, _Worker_logger, "f").info('draining worker');
247
- __classPrivateFieldSet(this, _Worker_draining, true, "f");
255
+ this.#logger.info('draining worker');
256
+ this.#draining = true;
248
257
  this.event.emit('worker_msg', new WorkerMessage({
249
258
  message: {
250
259
  case: 'updateWorker',
@@ -254,7 +263,7 @@ export class Worker {
254
263
  },
255
264
  }));
256
265
  const joinJobs = async () => {
257
- return Promise.all(__classPrivateFieldGet(this, _Worker_procPool, "f").processes.map((proc) => {
266
+ return Promise.all(this.#procPool.processes.map((proc) => {
258
267
  if (!proc.runningJob) {
259
268
  proc.close();
260
269
  }
@@ -271,7 +280,7 @@ export class Worker {
271
280
  });
272
281
  }
273
282
  async simulateJob(roomName, participantIdentity) {
274
- const client = new RoomServiceClient(__classPrivateFieldGet(this, _Worker_opts, "f").wsURL, __classPrivateFieldGet(this, _Worker_opts, "f").apiKey, __classPrivateFieldGet(this, _Worker_opts, "f").apiSecret);
283
+ const client = new RoomServiceClient(this.#opts.wsURL, this.#opts.apiKey, this.#opts.apiSecret);
275
284
  const room = await client.createRoom({ name: roomName });
276
285
  let participant = undefined;
277
286
  if (participantIdentity) {
@@ -279,7 +288,7 @@ export class Worker {
279
288
  participant = await client.getParticipant(roomName, participantIdentity);
280
289
  }
281
290
  catch (e) {
282
- __classPrivateFieldGet(this, _Worker_logger, "f").fatal(`participant with identity ${participantIdentity} not found in room ${roomName}`);
291
+ this.#logger.fatal(`participant with identity ${participantIdentity} not found in room ${roomName}`);
283
292
  throw e;
284
293
  }
285
294
  }
@@ -294,208 +303,209 @@ export class Worker {
294
303
  },
295
304
  }));
296
305
  }
297
- async close() {
298
- var _a;
299
- if (__classPrivateFieldGet(this, _Worker_closed, "f")) {
300
- await __classPrivateFieldGet(this, _Worker_close, "f").await;
301
- return;
302
- }
303
- __classPrivateFieldGet(this, _Worker_logger, "f").info('shutting down worker');
304
- __classPrivateFieldSet(this, _Worker_closed, true, "f");
305
- await __classPrivateFieldGet(this, _Worker_procPool, "f").close();
306
- await __classPrivateFieldGet(this, _Worker_httpServer, "f").close();
307
- await Promise.allSettled(__classPrivateFieldGet(this, _Worker_tasks, "f"));
308
- (_a = __classPrivateFieldGet(this, _Worker_session, "f")) === null || _a === void 0 ? void 0 : _a.close();
309
- await __classPrivateFieldGet(this, _Worker_close, "f").await;
310
- }
311
- }
312
- _Worker_opts = new WeakMap(), _Worker_procPool = new WeakMap(), _Worker_id = new WeakMap(), _Worker_closed = new WeakMap(), _Worker_draining = new WeakMap(), _Worker_connecting = new WeakMap(), _Worker_tasks = new WeakMap(), _Worker_pending = new WeakMap(), _Worker_close = new WeakMap(), _Worker_session = new WeakMap(), _Worker_httpServer = new WeakMap(), _Worker_logger = new WeakMap(), _Worker_instances = new WeakSet(), _Worker_runWS = function _Worker_runWS(ws) {
313
- let closingWS = false;
314
- const send = (msg) => {
315
- if (closingWS) {
316
- this.event.off('worker_msg', send);
317
- return;
318
- }
319
- ws.send(msg.toBinary());
320
- };
321
- this.event.on('worker_msg', send);
322
- ws.addEventListener('close', () => {
323
- closingWS = true;
324
- __classPrivateFieldGet(this, _Worker_logger, "f").error('worker connection closed unexpectedly');
325
- this.close();
326
- });
327
- ws.addEventListener('message', (event) => {
328
- if (event.type !== 'message') {
329
- __classPrivateFieldGet(this, _Worker_logger, "f").warn('unexpected message type: ' + event.type);
330
- return;
331
- }
332
- const msg = new ServerMessage();
333
- msg.fromBinary(event.data);
334
- // register is the only valid first message, and it is only valid as the
335
- // first message
336
- if (__classPrivateFieldGet(this, _Worker_connecting, "f") && msg.message.case !== 'register') {
337
- throw new WorkerError('expected register response as first message');
338
- }
339
- switch (msg.message.case) {
340
- case 'register': {
341
- __classPrivateFieldSet(this, _Worker_id, msg.message.value.workerId, "f");
342
- __classPrivateFieldGet(this, _Worker_logger, "f")
343
- .child({ id: this.id, server_info: msg.message.value.serverInfo })
344
- .info('registered worker');
345
- this.event.emit('worker_registered', msg.message.value.workerId, msg.message.value.serverInfo);
346
- __classPrivateFieldSet(this, _Worker_connecting, false, "f");
347
- break;
306
+ #runWS(ws) {
307
+ let closingWS = false;
308
+ const send = (msg) => {
309
+ if (closingWS) {
310
+ this.event.off('worker_msg', send);
311
+ return;
348
312
  }
349
- case 'availability': {
350
- if (!msg.message.value.job)
351
- return;
352
- const task = __classPrivateFieldGet(this, _Worker_instances, "m", _Worker_availability).call(this, msg.message.value);
353
- __classPrivateFieldGet(this, _Worker_tasks, "f").push(task);
354
- task.finally(() => __classPrivateFieldGet(this, _Worker_tasks, "f").splice(__classPrivateFieldGet(this, _Worker_tasks, "f").indexOf(task)));
355
- break;
313
+ ws.send(msg.toBinary());
314
+ };
315
+ this.event.on('worker_msg', send);
316
+ ws.addEventListener('close', () => {
317
+ closingWS = true;
318
+ this.#logger.error('worker connection closed unexpectedly');
319
+ this.close();
320
+ });
321
+ ws.addEventListener('message', (event) => {
322
+ if (event.type !== 'message') {
323
+ this.#logger.warn('unexpected message type: ' + event.type);
324
+ return;
356
325
  }
357
- case 'assignment': {
358
- if (!msg.message.value.job)
359
- return;
360
- const job = msg.message.value.job;
361
- if (job.id in __classPrivateFieldGet(this, _Worker_pending, "f")) {
362
- const task = __classPrivateFieldGet(this, _Worker_pending, "f")[job.id];
363
- delete __classPrivateFieldGet(this, _Worker_pending, "f")[job.id];
364
- task.resolve(msg.message.value);
326
+ const msg = new ServerMessage();
327
+ msg.fromBinary(event.data);
328
+ // register is the only valid first message, and it is only valid as the
329
+ // first message
330
+ if (this.#connecting && msg.message.case !== 'register') {
331
+ throw new WorkerError('expected register response as first message');
332
+ }
333
+ switch (msg.message.case) {
334
+ case 'register': {
335
+ this.#id = msg.message.value.workerId;
336
+ this.#logger
337
+ .child({ id: this.id, server_info: msg.message.value.serverInfo })
338
+ .info('registered worker');
339
+ this.event.emit('worker_registered', msg.message.value.workerId, msg.message.value.serverInfo);
340
+ this.#connecting = false;
341
+ break;
365
342
  }
366
- else {
367
- __classPrivateFieldGet(this, _Worker_logger, "f").child({ job }).warn('received assignment for unknown job ' + job.id);
343
+ case 'availability': {
344
+ if (!msg.message.value.job)
345
+ return;
346
+ const task = this.#availability(msg.message.value);
347
+ this.#tasks.push(task);
348
+ task.finally(() => this.#tasks.splice(this.#tasks.indexOf(task)));
349
+ break;
368
350
  }
369
- break;
370
- }
371
- case 'termination': {
372
- const task = __classPrivateFieldGet(this, _Worker_instances, "m", _Worker_termination).call(this, msg.message.value);
373
- __classPrivateFieldGet(this, _Worker_tasks, "f").push(task);
374
- task.finally(() => __classPrivateFieldGet(this, _Worker_tasks, "f").splice(__classPrivateFieldGet(this, _Worker_tasks, "f").indexOf(task)));
375
- break;
376
- }
377
- }
378
- });
379
- this.event.emit('worker_msg', new WorkerMessage({
380
- message: {
381
- case: 'register',
382
- value: {
383
- type: __classPrivateFieldGet(this, _Worker_opts, "f").workerType,
384
- agentName: __classPrivateFieldGet(this, _Worker_opts, "f").agentName,
385
- allowedPermissions: new ParticipantPermission({
386
- canPublish: __classPrivateFieldGet(this, _Worker_opts, "f").permissions.canPublish,
387
- canSubscribe: __classPrivateFieldGet(this, _Worker_opts, "f").permissions.canSubscribe,
388
- canPublishData: __classPrivateFieldGet(this, _Worker_opts, "f").permissions.canPublishData,
389
- canUpdateMetadata: __classPrivateFieldGet(this, _Worker_opts, "f").permissions.canUpdateMetadata,
390
- hidden: __classPrivateFieldGet(this, _Worker_opts, "f").permissions.hidden,
391
- agent: true,
392
- }),
393
- version,
394
- },
395
- },
396
- }));
397
- let currentStatus = WorkerStatus.WS_AVAILABLE;
398
- const loadMonitor = setInterval(() => {
399
- if (closingWS)
400
- clearInterval(loadMonitor);
401
- const oldStatus = currentStatus;
402
- __classPrivateFieldGet(this, _Worker_opts, "f").loadFunc().then((currentLoad) => {
403
- const isFull = currentLoad >= __classPrivateFieldGet(this, _Worker_opts, "f").loadThreshold;
404
- const currentlyAvailable = !isFull;
405
- currentStatus = currentlyAvailable ? WorkerStatus.WS_AVAILABLE : WorkerStatus.WS_FULL;
406
- if (oldStatus != currentStatus) {
407
- const extra = { load: currentLoad, loadThreshold: __classPrivateFieldGet(this, _Worker_opts, "f").loadThreshold };
408
- if (isFull) {
409
- __classPrivateFieldGet(this, _Worker_logger, "f").child(extra).info('worker is at full capacity, marking as unavailable');
351
+ case 'assignment': {
352
+ if (!msg.message.value.job)
353
+ return;
354
+ const job = msg.message.value.job;
355
+ if (job.id in this.#pending) {
356
+ const task = this.#pending[job.id];
357
+ delete this.#pending[job.id];
358
+ task.resolve(msg.message.value);
359
+ }
360
+ else {
361
+ this.#logger.child({ job }).warn('received assignment for unknown job ' + job.id);
362
+ }
363
+ break;
410
364
  }
411
- else {
412
- __classPrivateFieldGet(this, _Worker_logger, "f").child(extra).info('worker is below capacity, marking as available');
365
+ case 'termination': {
366
+ const task = this.#termination(msg.message.value);
367
+ this.#tasks.push(task);
368
+ task.finally(() => this.#tasks.splice(this.#tasks.indexOf(task)));
369
+ break;
413
370
  }
414
371
  }
415
- this.event.emit('worker_msg', new WorkerMessage({
416
- message: {
417
- case: 'updateWorker',
418
- value: {
419
- load: currentLoad,
420
- status: currentStatus,
421
- },
422
- },
423
- }));
424
372
  });
425
- }, UPDATE_LOAD_INTERVAL);
426
- }, _Worker_availability = async function _Worker_availability(msg) {
427
- let answered = false;
428
- const onReject = async () => {
429
- answered = true;
430
373
  this.event.emit('worker_msg', new WorkerMessage({
431
374
  message: {
432
- case: 'availability',
375
+ case: 'register',
433
376
  value: {
434
- jobId: msg.job.id,
435
- available: false,
377
+ type: this.#opts.workerType,
378
+ agentName: this.#opts.agentName,
379
+ allowedPermissions: new ParticipantPermission({
380
+ canPublish: this.#opts.permissions.canPublish,
381
+ canSubscribe: this.#opts.permissions.canSubscribe,
382
+ canPublishData: this.#opts.permissions.canPublishData,
383
+ canUpdateMetadata: this.#opts.permissions.canUpdateMetadata,
384
+ hidden: this.#opts.permissions.hidden,
385
+ agent: true,
386
+ }),
387
+ version,
436
388
  },
437
389
  },
438
390
  }));
439
- };
440
- const onAccept = async (args) => {
441
- answered = true;
442
- this.event.emit('worker_msg', new WorkerMessage({
443
- message: {
444
- case: 'availability',
445
- value: {
446
- jobId: msg.job.id,
447
- available: true,
448
- participantIdentity: args.identity,
449
- participantName: args.name,
450
- participantMetadata: args.metadata,
391
+ let currentStatus = WorkerStatus.WS_AVAILABLE;
392
+ const loadMonitor = setInterval(() => {
393
+ if (closingWS)
394
+ clearInterval(loadMonitor);
395
+ const oldStatus = currentStatus;
396
+ this.#opts.loadFunc().then((currentLoad) => {
397
+ const isFull = currentLoad >= this.#opts.loadThreshold;
398
+ const currentlyAvailable = !isFull;
399
+ currentStatus = currentlyAvailable ? WorkerStatus.WS_AVAILABLE : WorkerStatus.WS_FULL;
400
+ if (oldStatus != currentStatus) {
401
+ const extra = { load: currentLoad, loadThreshold: this.#opts.loadThreshold };
402
+ if (isFull) {
403
+ this.#logger.child(extra).info('worker is at full capacity, marking as unavailable');
404
+ }
405
+ else {
406
+ this.#logger.child(extra).info('worker is below capacity, marking as available');
407
+ }
408
+ }
409
+ this.event.emit('worker_msg', new WorkerMessage({
410
+ message: {
411
+ case: 'updateWorker',
412
+ value: {
413
+ load: currentLoad,
414
+ status: currentStatus,
415
+ },
416
+ },
417
+ }));
418
+ });
419
+ }, UPDATE_LOAD_INTERVAL);
420
+ }
421
+ async #availability(msg) {
422
+ let answered = false;
423
+ const onReject = async () => {
424
+ answered = true;
425
+ this.event.emit('worker_msg', new WorkerMessage({
426
+ message: {
427
+ case: 'availability',
428
+ value: {
429
+ jobId: msg.job.id,
430
+ available: false,
431
+ },
451
432
  },
452
- },
453
- }));
454
- __classPrivateFieldGet(this, _Worker_pending, "f")[req.id] = new PendingAssignment();
455
- const timer = setTimeout(() => {
456
- __classPrivateFieldGet(this, _Worker_logger, "f").child({ req }).warn(`assignment for job ${req.id} timed out`);
433
+ }));
434
+ };
435
+ const onAccept = async (args) => {
436
+ answered = true;
437
+ this.event.emit('worker_msg', new WorkerMessage({
438
+ message: {
439
+ case: 'availability',
440
+ value: {
441
+ jobId: msg.job.id,
442
+ available: true,
443
+ participantIdentity: args.identity,
444
+ participantName: args.name,
445
+ participantMetadata: args.metadata,
446
+ },
447
+ },
448
+ }));
449
+ this.#pending[req.id] = new PendingAssignment();
450
+ const timer = setTimeout(() => {
451
+ this.#logger.child({ req }).warn(`assignment for job ${req.id} timed out`);
452
+ return;
453
+ }, ASSIGNMENT_TIMEOUT);
454
+ const asgn = await this.#pending[req.id].promise.then(async (asgn) => {
455
+ clearTimeout(timer);
456
+ return asgn;
457
+ });
458
+ await this.#procPool.launchJob({
459
+ acceptArguments: args,
460
+ job: msg.job,
461
+ url: asgn.url || this.#opts.wsURL,
462
+ token: asgn.token,
463
+ });
464
+ };
465
+ const req = new JobRequest(msg.job, onReject, onAccept);
466
+ this.#logger
467
+ .child({ job: msg.job, resuming: msg.resuming, agentName: this.#opts.agentName })
468
+ .info('received job request');
469
+ const jobRequestTask = async () => {
470
+ try {
471
+ await this.#opts.requestFunc(req);
472
+ }
473
+ catch (e) {
474
+ this.#logger
475
+ .child({ job: msg.job, resuming: msg.resuming, agentName: this.#opts.agentName })
476
+ .info('jobRequestFunc failed');
477
+ await onReject();
478
+ }
479
+ if (!answered) {
480
+ this.#logger
481
+ .child({ job: msg.job, resuming: msg.resuming, agentName: this.#opts.agentName })
482
+ .info('no answer was given inside the jobRequestFunc, automatically rejecting the job');
483
+ }
484
+ };
485
+ const task = jobRequestTask();
486
+ this.#tasks.push(task);
487
+ task.finally(() => this.#tasks.splice(this.#tasks.indexOf(task)));
488
+ }
489
+ async #termination(msg) {
490
+ const proc = this.#procPool.getByJobId(msg.jobId);
491
+ if (proc === null) {
492
+ // safe to ignore
457
493
  return;
458
- }, ASSIGNMENT_TIMEOUT);
459
- const asgn = await __classPrivateFieldGet(this, _Worker_pending, "f")[req.id].promise.then(async (asgn) => {
460
- clearTimeout(timer);
461
- return asgn;
462
- });
463
- await __classPrivateFieldGet(this, _Worker_procPool, "f").launchJob({
464
- acceptArguments: args,
465
- job: msg.job,
466
- url: asgn.url || __classPrivateFieldGet(this, _Worker_opts, "f").wsURL,
467
- token: asgn.token,
468
- });
469
- };
470
- const req = new JobRequest(msg.job, onReject, onAccept);
471
- __classPrivateFieldGet(this, _Worker_logger, "f")
472
- .child({ job: msg.job, resuming: msg.resuming, agentName: __classPrivateFieldGet(this, _Worker_opts, "f").agentName })
473
- .info('received job request');
474
- const jobRequestTask = async () => {
475
- try {
476
- await __classPrivateFieldGet(this, _Worker_opts, "f").requestFunc(req);
477
494
  }
478
- catch (e) {
479
- __classPrivateFieldGet(this, _Worker_logger, "f")
480
- .child({ job: msg.job, resuming: msg.resuming, agentName: __classPrivateFieldGet(this, _Worker_opts, "f").agentName })
481
- .info('jobRequestFunc failed');
482
- await onReject();
483
- }
484
- if (!answered) {
485
- __classPrivateFieldGet(this, _Worker_logger, "f")
486
- .child({ job: msg.job, resuming: msg.resuming, agentName: __classPrivateFieldGet(this, _Worker_opts, "f").agentName })
487
- .info('no answer was given inside the jobRequestFunc, automatically rejecting the job');
495
+ await proc.close();
496
+ }
497
+ async close() {
498
+ if (this.#closed) {
499
+ await this.#close.await;
500
+ return;
488
501
  }
489
- };
490
- const task = jobRequestTask();
491
- __classPrivateFieldGet(this, _Worker_tasks, "f").push(task);
492
- task.finally(() => __classPrivateFieldGet(this, _Worker_tasks, "f").splice(__classPrivateFieldGet(this, _Worker_tasks, "f").indexOf(task)));
493
- }, _Worker_termination = async function _Worker_termination(msg) {
494
- const proc = __classPrivateFieldGet(this, _Worker_procPool, "f").getByJobId(msg.jobId);
495
- if (proc === null) {
496
- // safe to ignore
497
- return;
502
+ this.#logger.info('shutting down worker');
503
+ this.#closed = true;
504
+ await this.#procPool.close();
505
+ await this.#httpServer.close();
506
+ await Promise.allSettled(this.#tasks);
507
+ this.#session?.close();
508
+ await this.#close.await;
498
509
  }
499
- await proc.close();
500
- };
510
+ }
501
511
  //# sourceMappingURL=worker.js.map