@livekit/agents 1.0.39 → 1.0.40

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.
package/dist/worker.cjs CHANGED
@@ -278,13 +278,23 @@ class AgentServer {
278
278
  opts.jobMemoryLimitMB
279
279
  );
280
280
  this.#opts = opts;
281
- this.#httpServer = new import_http_server.HTTPServer(opts.host, opts.port, () => ({
281
+ const healthCheck = () => {
282
+ if (this.#inferenceExecutor && !this.#inferenceExecutor.isAlive) {
283
+ return { healthy: false, message: "inference process not running" };
284
+ }
285
+ if (this.#closed || this.#connecting || !this.#session || this.#session.readyState !== import_ws.WebSocket.OPEN) {
286
+ return { healthy: false, message: "not connected to livekit" };
287
+ }
288
+ return { healthy: true, message: "OK" };
289
+ };
290
+ const getWorkerInfo = () => ({
282
291
  agent_name: opts.agentName,
283
292
  worker_type: import_protocol.JobType[opts.serverType],
284
293
  active_jobs: this.activeJobs.length,
285
294
  sdk_version: import_version.version,
286
295
  project_type: PROJECT_TYPE
287
- }));
296
+ });
297
+ this.#httpServer = new import_http_server.HTTPServer(opts.host, opts.port, healthCheck, getWorkerInfo);
288
298
  }
289
299
  /** @throws {@link WorkerError} if worker failed to connect or already running */
290
300
  async run() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/worker.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { JobAssignment, JobTermination, TrackSource } from '@livekit/protocol';\nimport {\n type AvailabilityRequest,\n JobType,\n ParticipantPermission,\n ServerMessage,\n WorkerMessage,\n WorkerStatus,\n} from '@livekit/protocol';\nimport type { ParticipantInfo } from 'livekit-server-sdk';\nimport { AccessToken, RoomServiceClient } from 'livekit-server-sdk';\nimport { EventEmitter } from 'node:events';\nimport os from 'node:os';\nimport { WebSocket } from 'ws';\nimport { HTTPServer } from './http_server.js';\nimport { InferenceRunner } from './inference_runner.js';\nimport { InferenceProcExecutor } from './ipc/inference_proc_executor.js';\nimport { ProcPool } from './ipc/proc_pool.js';\nimport type { JobAcceptArguments, JobProcess, RunningJobInfo } from './job.js';\nimport { JobRequest } from './job.js';\nimport { log } from './log.js';\nimport { Future } from './utils.js';\nimport { version } from './version.js';\n\nconst MAX_RECONNECT_ATTEMPTS = 10;\nconst ASSIGNMENT_TIMEOUT = 7.5 * 1000;\nconst UPDATE_LOAD_INTERVAL = 2.5 * 1000;\nconst PROJECT_TYPE = 'nodejs';\n\nclass Default {\n static loadThreshold(production: boolean): number {\n if (production) {\n return 0.7;\n } else {\n return Infinity;\n }\n }\n\n static numIdleProcesses(production: boolean): number {\n if (production) {\n // TODO: use number of cores\n return 3;\n } else {\n return 0;\n }\n }\n\n static port(production: boolean): number {\n if (production) {\n return 8081;\n } else {\n return 0;\n }\n }\n}\n\n/** Necessary credentials not provided and not found in an appropriate environment variable. */\nexport class MissingCredentialsError extends Error {\n constructor(msg?: string) {\n super(msg);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Worker did not run as expected. */\nexport class WorkerError extends Error {\n constructor(msg?: string) {\n super(msg);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** @internal */\nexport const defaultInitializeProcessFunc = (_: JobProcess) => _;\nconst defaultRequestFunc = async (ctx: JobRequest) => {\n await ctx.accept();\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst defaultCpuLoad = async (worker: AgentServer): Promise<number> => {\n return new Promise((resolve) => {\n const cpus1 = os.cpus();\n\n setTimeout(() => {\n const cpus2 = os.cpus();\n\n let idle = 0;\n let total = 0;\n\n for (let i = 0; i < cpus1.length; i++) {\n const cpu1 = cpus1[i]!.times;\n const cpu2 = cpus2[i]!.times;\n\n idle += cpu2.idle - cpu1.idle;\n\n const total1 = Object.values(cpu1).reduce((acc, i) => acc + i, 0);\n const total2 = Object.values(cpu2).reduce((acc, i) => acc + i, 0);\n\n total += total2 - total1;\n }\n\n resolve(+(1 - idle / total).toFixed(2));\n }, UPDATE_LOAD_INTERVAL);\n });\n};\n\n/** Participant permissions to pass to every agent spun up by this worker. */\nexport class WorkerPermissions {\n canPublish: boolean;\n canSubscribe: boolean;\n canPublishData: boolean;\n canUpdateMetadata: boolean;\n canPublishSources: TrackSource[];\n hidden: boolean;\n\n constructor(\n canPublish = true,\n canSubscribe = true,\n canPublishData = true,\n canUpdateMetadata = true,\n canPublishSources: TrackSource[] = [],\n hidden = false,\n ) {\n this.canPublish = canPublish;\n this.canSubscribe = canSubscribe;\n this.canPublishData = canPublishData;\n this.canUpdateMetadata = canUpdateMetadata;\n this.canPublishSources = canPublishSources;\n this.hidden = hidden;\n }\n}\n\n/**\n * Data class describing worker behaviour.\n *\n * @remarks\n * The Agents framework provides sane worker defaults, and works out-of-the-box with no tweaking\n * necessary. The only mandatory parameter is `agent`, which points to the entry function.\n *\n * This class is mostly useful in conjunction with {@link cli.runApp}.\n */\nexport class ServerOptions {\n agent: string;\n requestFunc: (job: JobRequest) => Promise<void>;\n loadFunc: (worker: AgentServer) => Promise<number>;\n loadThreshold: number;\n numIdleProcesses: number;\n shutdownProcessTimeout: number;\n initializeProcessTimeout: number;\n permissions: WorkerPermissions;\n agentName: string;\n serverType: JobType;\n maxRetry: number;\n wsURL: string;\n apiKey?: string;\n apiSecret?: string;\n workerToken?: string;\n host: string;\n port: number;\n logLevel: string;\n production: boolean;\n jobMemoryWarnMB: number;\n jobMemoryLimitMB: number;\n\n /** @param options - Worker options */\n constructor({\n agent,\n requestFunc = defaultRequestFunc,\n loadFunc = defaultCpuLoad,\n loadThreshold = undefined,\n numIdleProcesses = undefined,\n shutdownProcessTimeout = 60 * 1000,\n initializeProcessTimeout = 10 * 1000,\n permissions = new WorkerPermissions(),\n agentName = '',\n serverType = JobType.JT_ROOM,\n maxRetry = MAX_RECONNECT_ATTEMPTS,\n wsURL = 'ws://localhost:7880',\n apiKey = undefined,\n apiSecret = undefined,\n workerToken = undefined,\n host = '0.0.0.0',\n port = undefined,\n logLevel = 'info',\n production = false,\n jobMemoryWarnMB = 500,\n jobMemoryLimitMB = 0,\n }: {\n /**\n * Path to a file that has {@link Agent} as a default export, dynamically imported later for\n * entrypoint and prewarm functions\n */\n agent: string;\n requestFunc?: (job: JobRequest) => Promise<void>;\n /** Called to determine the current load of the worker. Should return a value between 0 and 1. */\n loadFunc?: (worker: AgentServer) => Promise<number>;\n /** When the load exceeds this threshold, the worker will be marked as unavailable. */\n loadThreshold?: number;\n numIdleProcesses?: number;\n shutdownProcessTimeout?: number;\n initializeProcessTimeout?: number;\n permissions?: WorkerPermissions;\n agentName?: string;\n serverType?: JobType;\n maxRetry?: number;\n wsURL?: string;\n apiKey?: string;\n apiSecret?: string;\n workerToken?: string;\n host?: string;\n port?: number;\n logLevel?: string;\n production?: boolean;\n jobMemoryWarnMB?: number;\n jobMemoryLimitMB?: number;\n }) {\n this.agent = agent;\n if (!this.agent) {\n throw new Error('No Agent file was passed to the worker');\n }\n this.requestFunc = requestFunc;\n this.loadFunc = loadFunc;\n this.loadThreshold = loadThreshold || Default.loadThreshold(production);\n this.numIdleProcesses = numIdleProcesses || Default.numIdleProcesses(production);\n this.shutdownProcessTimeout = shutdownProcessTimeout;\n this.initializeProcessTimeout = initializeProcessTimeout;\n this.permissions = permissions;\n this.agentName = agentName;\n this.serverType = serverType;\n this.maxRetry = maxRetry;\n this.wsURL = wsURL;\n this.apiKey = apiKey;\n this.apiSecret = apiSecret;\n this.workerToken = workerToken;\n this.host = host;\n this.port = port || Default.port(production);\n this.logLevel = logLevel;\n this.production = production;\n this.jobMemoryWarnMB = jobMemoryWarnMB;\n this.jobMemoryLimitMB = jobMemoryLimitMB;\n }\n}\n\nclass PendingAssignment {\n promise = new Promise<JobAssignment>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: JobAssignment) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\n/**\n * Central orchestrator for all processes and job requests.\n *\n * @remarks\n * For most usecases, Worker should not be initialized or handled directly; you should instead call\n * for its creation through {@link cli.runApp}. This could, however, be useful in situations where\n * you don't have access to a command line, such as a headless program, or one that uses Agents\n * behind a wrapper.\n */\nexport class AgentServer {\n #opts: ServerOptions;\n #procPool: ProcPool;\n\n #id = 'unregistered';\n #closed = true;\n #draining = false;\n #connecting = false;\n #tasks: Promise<void>[] = [];\n #pending: { [id: string]: PendingAssignment } = {};\n #close = new Future();\n\n event = new EventEmitter();\n #session: WebSocket | undefined = undefined;\n #httpServer: HTTPServer;\n #logger = log().child({ version });\n #inferenceExecutor?: InferenceProcExecutor;\n\n /* @throws {@link MissingCredentialsError} if URL, API key or API secret are missing */\n constructor(opts: ServerOptions) {\n opts.wsURL = opts.wsURL || process.env.LIVEKIT_URL || '';\n opts.apiKey = opts.apiKey || process.env.LIVEKIT_API_KEY || '';\n opts.apiSecret = opts.apiSecret || process.env.LIVEKIT_API_SECRET || '';\n\n if (opts.wsURL === '')\n throw new MissingCredentialsError(\n 'URL is required: Set LIVEKIT_URL, run with --url, or pass wsURL in ServerOptions',\n );\n if (opts.apiKey === '')\n throw new MissingCredentialsError(\n 'API Key is required: Set LIVEKIT_API_KEY, run with --api-key, or pass apiKey in ServerOptions',\n );\n if (opts.apiSecret === '')\n throw new MissingCredentialsError(\n 'API Secret is required: Set LIVEKIT_API_SECRET, run with --api-secret, or pass apiSecret in ServerOptions',\n );\n\n if (opts.workerToken) {\n if (opts.loadFunc !== defaultCpuLoad) {\n this.#logger.warn(\n 'custom loadFunc is not supported when deploying to Cloud, using defaults',\n );\n opts.loadFunc = defaultCpuLoad;\n }\n const loadThreshold = Default.loadThreshold(opts.production);\n if (opts.loadThreshold !== loadThreshold) {\n this.#logger.warn(\n 'custom loadThreshold is not supported when deploying to Cloud, using defaults',\n );\n opts.loadThreshold = loadThreshold;\n }\n }\n\n if (Object.entries(InferenceRunner.registeredRunners).length) {\n this.#inferenceExecutor = new InferenceProcExecutor({\n runners: InferenceRunner.registeredRunners,\n initializeTimeout: 30000,\n closeTimeout: 5000,\n memoryWarnMB: 2000,\n memoryLimitMB: 0,\n pingInterval: 5000,\n pingTimeout: 60000,\n highPingThreshold: 2500,\n });\n }\n\n this.#procPool = new ProcPool(\n opts.agent,\n opts.numIdleProcesses,\n opts.initializeProcessTimeout,\n opts.shutdownProcessTimeout,\n this.#inferenceExecutor,\n opts.jobMemoryWarnMB,\n opts.jobMemoryLimitMB,\n );\n\n this.#opts = opts;\n this.#httpServer = new HTTPServer(opts.host, opts.port, () => ({\n agent_name: opts.agentName,\n worker_type: JobType[opts.serverType],\n active_jobs: this.activeJobs.length,\n sdk_version: version,\n project_type: PROJECT_TYPE,\n }));\n }\n\n /** @throws {@link WorkerError} if worker failed to connect or already running */\n async run() {\n if (!this.#closed) {\n throw new WorkerError('worker is already running');\n }\n\n if (this.#inferenceExecutor) {\n await this.#inferenceExecutor.start();\n await this.#inferenceExecutor.initialize();\n }\n\n this.#logger.info('starting worker');\n this.#closed = false;\n this.#procPool.start();\n\n const workerWS = async () => {\n let retries = 0;\n this.#connecting = true;\n\n while (!this.#closed) {\n const url = new URL(this.#opts.wsURL);\n url.protocol = url.protocol.replace('http', 'ws');\n const token = new AccessToken(this.#opts.apiKey, this.#opts.apiSecret);\n token.addGrant({ agent: true });\n const jwt = await token.toJwt();\n const wsUrl = new URL(url + 'agent');\n if (this.#opts.workerToken) {\n wsUrl.searchParams.append('worker_token', this.#opts.workerToken);\n }\n this.#session = new WebSocket(wsUrl, {\n headers: { authorization: 'Bearer ' + jwt },\n });\n\n try {\n await new Promise((resolve, reject) => {\n this.#session!.on('open', resolve);\n this.#session!.on('error', (error) => reject(error));\n this.#session!.on('close', (code) => reject(`WebSocket returned ${code}`));\n });\n\n retries = 0;\n this.#logger.debug('connected to LiveKit server');\n await this.#runWS(this.#session);\n } catch (e: unknown) {\n if (this.#closed) return;\n if (retries >= this.#opts.maxRetry) {\n throw new WorkerError(\n `failed to connect to LiveKit server (${this.#opts.wsURL}) after ${retries} attempts: ${e}`,\n );\n }\n\n retries++;\n const delay = Math.min(retries * 2, 10);\n\n this.#logger.warn(\n e,\n `failed to connect to LiveKit server (${this.#opts.wsURL}), retrying in ${delay} seconds: (${retries}/${this.#opts.maxRetry})`,\n );\n\n await new Promise((resolve) => setTimeout(resolve, delay * 1000));\n }\n }\n };\n\n await Promise.all([workerWS(), this.#httpServer.run()]);\n this.#close.resolve();\n }\n\n get id(): string {\n return this.#id;\n }\n\n get activeJobs(): RunningJobInfo[] {\n return this.#procPool.processes\n .filter((proc) => proc.runningJob)\n .map((proc) => proc.runningJob!);\n }\n\n /** @throws {@link WorkerError} if worker did not drain in time */\n async drain(timeout?: number) {\n if (this.#draining) {\n return;\n }\n\n this.#logger.debug('draining worker');\n this.#draining = true;\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'updateWorker',\n value: {\n status: WorkerStatus.WS_FULL,\n },\n },\n }),\n );\n\n const joinJobs = async () => {\n return Promise.all(\n this.#procPool.processes.map((proc) => {\n if (!proc.runningJob) {\n proc.close();\n }\n return proc.join();\n }),\n );\n };\n\n let timer: NodeJS.Timeout | undefined;\n if (timeout) {\n timer = setTimeout(() => {\n throw new WorkerError('timed out draining');\n }, timeout);\n }\n await joinJobs().then(() => {\n if (timeout) {\n clearTimeout(timer);\n }\n });\n }\n\n async simulateJob(roomName: string, participantIdentity?: string) {\n const client = new RoomServiceClient(this.#opts.wsURL, this.#opts.apiKey, this.#opts.apiSecret);\n const room = await client.createRoom({ name: roomName });\n let participant: ParticipantInfo | undefined = undefined;\n if (participantIdentity) {\n try {\n // TODO(AJS-269): resolve compatibility issue with node-sdk to remove the forced type casting\n participant = (await client.getParticipant(\n roomName,\n participantIdentity,\n )) as unknown as ParticipantInfo;\n } catch (e) {\n this.#logger.fatal(\n `participant with identity ${participantIdentity} not found in room ${roomName}`,\n );\n throw e;\n }\n }\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'simulateJob',\n value: {\n type: JobType.JT_PUBLISHER,\n room,\n participant,\n },\n },\n }),\n );\n }\n\n async #runWS(ws: WebSocket) {\n let closingWS = false;\n\n const send = (msg: WorkerMessage) => {\n if (closingWS) {\n this.event.off('worker_msg', send);\n return;\n }\n ws.send(msg.toBinary());\n };\n this.event.on('worker_msg', send);\n\n const close = new Promise<void>((resolve) => {\n ws.addEventListener('close', () => {\n closingWS = true;\n if (!this.#closed) {\n this.#logger.error('worker connection closed unexpectedly');\n }\n resolve();\n });\n });\n\n ws.addEventListener('error', (event) => {\n this.#logger.error('worker error:', event.message);\n });\n\n ws.addEventListener('message', (event) => {\n if (event.type !== 'message') {\n this.#logger.warn('unexpected message type: ' + event.type);\n return;\n }\n\n const msg = new ServerMessage();\n msg.fromBinary(event.data as Uint8Array);\n\n // register is the only valid first message, and it is only valid as the\n // first message\n if (this.#connecting && msg.message.case !== 'register') {\n throw new WorkerError('expected register response as first message');\n }\n\n switch (msg.message.case) {\n case 'register': {\n this.#id = msg.message.value.workerId;\n this.#logger\n .child({ id: this.id, server_info: msg.message.value.serverInfo })\n .info('registered worker');\n this.event.emit(\n 'worker_registered',\n msg.message.value.workerId,\n msg.message.value.serverInfo,\n );\n this.#connecting = false;\n break;\n }\n case 'availability': {\n if (!msg.message.value.job) return;\n const task = this.#availability(msg.message.value);\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n break;\n }\n case 'assignment': {\n if (!msg.message.value.job) return;\n const job = msg.message.value.job;\n if (job.id in this.#pending) {\n const task = this.#pending[job.id];\n delete this.#pending[job.id];\n task?.resolve(msg.message.value);\n } else {\n this.#logger.child({ job }).warn('received assignment for unknown job ' + job.id);\n }\n break;\n }\n case 'termination': {\n const task = this.#termination(msg.message.value);\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n break;\n }\n }\n });\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'register',\n value: {\n type: this.#opts.serverType,\n agentName: this.#opts.agentName,\n allowedPermissions: new ParticipantPermission({\n canPublish: this.#opts.permissions.canPublish,\n canSubscribe: this.#opts.permissions.canSubscribe,\n canPublishData: this.#opts.permissions.canPublishData,\n canUpdateMetadata: this.#opts.permissions.canUpdateMetadata,\n hidden: this.#opts.permissions.hidden,\n agent: true,\n }),\n version,\n },\n },\n }),\n );\n\n let currentStatus = WorkerStatus.WS_AVAILABLE;\n const loadMonitor = setInterval(() => {\n if (closingWS) clearInterval(loadMonitor);\n\n const oldStatus = currentStatus;\n this.#opts.loadFunc(this).then((currentLoad: number) => {\n const isFull = currentLoad >= this.#opts.loadThreshold;\n const currentlyAvailable = !isFull;\n currentStatus = currentlyAvailable ? WorkerStatus.WS_AVAILABLE : WorkerStatus.WS_FULL;\n\n if (oldStatus != currentStatus) {\n const extra = { load: currentLoad, loadThreshold: this.#opts.loadThreshold };\n if (isFull) {\n this.#logger.child(extra).info('worker is at full capacity, marking as unavailable');\n } else {\n this.#logger.child(extra).info('worker is below capacity, marking as available');\n }\n }\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'updateWorker',\n value: {\n load: currentLoad,\n status: currentStatus,\n },\n },\n }),\n );\n });\n }, UPDATE_LOAD_INTERVAL);\n\n await close;\n ws.removeAllListeners();\n }\n\n async #availability(msg: AvailabilityRequest) {\n let answered = false;\n\n const onReject = async () => {\n answered = true;\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'availability',\n value: {\n jobId: msg.job!.id,\n available: false,\n },\n },\n }),\n );\n };\n\n const onAccept = async (args: JobAcceptArguments) => {\n answered = true;\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'availability',\n value: {\n jobId: msg.job!.id,\n available: true,\n participantIdentity: args.identity,\n participantName: args.name,\n participantMetadata: args.metadata,\n participantAttributes: args.attributes,\n },\n },\n }),\n );\n\n this.#pending[req.id] = new PendingAssignment();\n const timer = setTimeout(() => {\n this.#logger.child({ req }).warn(`assignment for job ${req.id} timed out`);\n return;\n }, ASSIGNMENT_TIMEOUT);\n const asgn = await this.#pending[req.id]?.promise.then(async (asgn) => {\n clearTimeout(timer);\n return asgn;\n });\n\n if (asgn) {\n await this.#procPool.launchJob({\n acceptArguments: args,\n job: msg.job!,\n url: asgn.url || this.#opts.wsURL,\n token: asgn.token,\n workerId: this.id,\n });\n } else {\n this.#logger.child({ requestId: req.id }).warn('pending assignment not found');\n }\n };\n\n const req = new JobRequest(msg.job!, onReject, onAccept);\n this.#logger\n .child({ jobId: msg.job?.id, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('received job request');\n\n const jobRequestTask = async () => {\n try {\n await this.#opts.requestFunc(req);\n } catch (e) {\n this.#logger\n .child({ job: msg.job, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('jobRequestFunc failed');\n await onReject();\n }\n\n if (!answered) {\n this.#logger\n .child({ job: msg.job, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('no answer was given inside the jobRequestFunc, automatically rejecting the job');\n }\n };\n\n const task = jobRequestTask();\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n }\n\n async #termination(msg: JobTermination) {\n const proc = this.#procPool.getByJobId(msg.jobId);\n if (proc === null) {\n // safe to ignore\n return;\n }\n await proc.close();\n }\n\n async close() {\n if (this.#closed) {\n await this.#close.await;\n return;\n }\n\n this.#logger.debug('shutting down worker');\n\n this.#closed = true;\n\n await this.#inferenceExecutor?.close();\n await this.#procPool.close();\n await this.#httpServer.close();\n await Promise.allSettled(this.#tasks);\n\n this.#session?.close();\n await this.#close.await;\n }\n}\n\n/**\n * @deprecated Use {@link AgentServer} instead. This alias is provided for backward compatibility.\n */\nexport const Worker = AgentServer;\n\n/**\n * @deprecated Use {@link ServerOptions} instead. This alias is provided for backward compatibility.\n */\nexport const WorkerOptions = ServerOptions;\n"],"mappings":"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","names":["os","i","_a","asgn"]}
1
+ {"version":3,"sources":["../src/worker.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { JobAssignment, JobTermination, TrackSource } from '@livekit/protocol';\nimport {\n type AvailabilityRequest,\n JobType,\n ParticipantPermission,\n ServerMessage,\n WorkerMessage,\n WorkerStatus,\n} from '@livekit/protocol';\nimport type { ParticipantInfo } from 'livekit-server-sdk';\nimport { AccessToken, RoomServiceClient } from 'livekit-server-sdk';\nimport { EventEmitter } from 'node:events';\nimport os from 'node:os';\nimport { WebSocket } from 'ws';\nimport { HTTPServer } from './http_server.js';\nimport { InferenceRunner } from './inference_runner.js';\nimport { InferenceProcExecutor } from './ipc/inference_proc_executor.js';\nimport { ProcPool } from './ipc/proc_pool.js';\nimport type { JobAcceptArguments, JobProcess, RunningJobInfo } from './job.js';\nimport { JobRequest } from './job.js';\nimport { log } from './log.js';\nimport { Future } from './utils.js';\nimport { version } from './version.js';\n\nconst MAX_RECONNECT_ATTEMPTS = 10;\nconst ASSIGNMENT_TIMEOUT = 7.5 * 1000;\nconst UPDATE_LOAD_INTERVAL = 2.5 * 1000;\nconst PROJECT_TYPE = 'nodejs';\n\nclass Default {\n static loadThreshold(production: boolean): number {\n if (production) {\n return 0.7;\n } else {\n return Infinity;\n }\n }\n\n static numIdleProcesses(production: boolean): number {\n if (production) {\n // TODO: use number of cores\n return 3;\n } else {\n return 0;\n }\n }\n\n static port(production: boolean): number {\n if (production) {\n return 8081;\n } else {\n return 0;\n }\n }\n}\n\n/** Necessary credentials not provided and not found in an appropriate environment variable. */\nexport class MissingCredentialsError extends Error {\n constructor(msg?: string) {\n super(msg);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Worker did not run as expected. */\nexport class WorkerError extends Error {\n constructor(msg?: string) {\n super(msg);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** @internal */\nexport const defaultInitializeProcessFunc = (_: JobProcess) => _;\nconst defaultRequestFunc = async (ctx: JobRequest) => {\n await ctx.accept();\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst defaultCpuLoad = async (worker: AgentServer): Promise<number> => {\n return new Promise((resolve) => {\n const cpus1 = os.cpus();\n\n setTimeout(() => {\n const cpus2 = os.cpus();\n\n let idle = 0;\n let total = 0;\n\n for (let i = 0; i < cpus1.length; i++) {\n const cpu1 = cpus1[i]!.times;\n const cpu2 = cpus2[i]!.times;\n\n idle += cpu2.idle - cpu1.idle;\n\n const total1 = Object.values(cpu1).reduce((acc, i) => acc + i, 0);\n const total2 = Object.values(cpu2).reduce((acc, i) => acc + i, 0);\n\n total += total2 - total1;\n }\n\n resolve(+(1 - idle / total).toFixed(2));\n }, UPDATE_LOAD_INTERVAL);\n });\n};\n\n/** Participant permissions to pass to every agent spun up by this worker. */\nexport class WorkerPermissions {\n canPublish: boolean;\n canSubscribe: boolean;\n canPublishData: boolean;\n canUpdateMetadata: boolean;\n canPublishSources: TrackSource[];\n hidden: boolean;\n\n constructor(\n canPublish = true,\n canSubscribe = true,\n canPublishData = true,\n canUpdateMetadata = true,\n canPublishSources: TrackSource[] = [],\n hidden = false,\n ) {\n this.canPublish = canPublish;\n this.canSubscribe = canSubscribe;\n this.canPublishData = canPublishData;\n this.canUpdateMetadata = canUpdateMetadata;\n this.canPublishSources = canPublishSources;\n this.hidden = hidden;\n }\n}\n\n/**\n * Data class describing worker behaviour.\n *\n * @remarks\n * The Agents framework provides sane worker defaults, and works out-of-the-box with no tweaking\n * necessary. The only mandatory parameter is `agent`, which points to the entry function.\n *\n * This class is mostly useful in conjunction with {@link cli.runApp}.\n */\nexport class ServerOptions {\n agent: string;\n requestFunc: (job: JobRequest) => Promise<void>;\n loadFunc: (worker: AgentServer) => Promise<number>;\n loadThreshold: number;\n numIdleProcesses: number;\n shutdownProcessTimeout: number;\n initializeProcessTimeout: number;\n permissions: WorkerPermissions;\n agentName: string;\n serverType: JobType;\n maxRetry: number;\n wsURL: string;\n apiKey?: string;\n apiSecret?: string;\n workerToken?: string;\n host: string;\n port: number;\n logLevel: string;\n production: boolean;\n jobMemoryWarnMB: number;\n jobMemoryLimitMB: number;\n\n /** @param options - Worker options */\n constructor({\n agent,\n requestFunc = defaultRequestFunc,\n loadFunc = defaultCpuLoad,\n loadThreshold = undefined,\n numIdleProcesses = undefined,\n shutdownProcessTimeout = 60 * 1000,\n initializeProcessTimeout = 10 * 1000,\n permissions = new WorkerPermissions(),\n agentName = '',\n serverType = JobType.JT_ROOM,\n maxRetry = MAX_RECONNECT_ATTEMPTS,\n wsURL = 'ws://localhost:7880',\n apiKey = undefined,\n apiSecret = undefined,\n workerToken = undefined,\n host = '0.0.0.0',\n port = undefined,\n logLevel = 'info',\n production = false,\n jobMemoryWarnMB = 500,\n jobMemoryLimitMB = 0,\n }: {\n /**\n * Path to a file that has {@link Agent} as a default export, dynamically imported later for\n * entrypoint and prewarm functions\n */\n agent: string;\n requestFunc?: (job: JobRequest) => Promise<void>;\n /** Called to determine the current load of the worker. Should return a value between 0 and 1. */\n loadFunc?: (worker: AgentServer) => Promise<number>;\n /** When the load exceeds this threshold, the worker will be marked as unavailable. */\n loadThreshold?: number;\n numIdleProcesses?: number;\n shutdownProcessTimeout?: number;\n initializeProcessTimeout?: number;\n permissions?: WorkerPermissions;\n agentName?: string;\n serverType?: JobType;\n maxRetry?: number;\n wsURL?: string;\n apiKey?: string;\n apiSecret?: string;\n workerToken?: string;\n host?: string;\n port?: number;\n logLevel?: string;\n production?: boolean;\n jobMemoryWarnMB?: number;\n jobMemoryLimitMB?: number;\n }) {\n this.agent = agent;\n if (!this.agent) {\n throw new Error('No Agent file was passed to the worker');\n }\n this.requestFunc = requestFunc;\n this.loadFunc = loadFunc;\n this.loadThreshold = loadThreshold || Default.loadThreshold(production);\n this.numIdleProcesses = numIdleProcesses || Default.numIdleProcesses(production);\n this.shutdownProcessTimeout = shutdownProcessTimeout;\n this.initializeProcessTimeout = initializeProcessTimeout;\n this.permissions = permissions;\n this.agentName = agentName;\n this.serverType = serverType;\n this.maxRetry = maxRetry;\n this.wsURL = wsURL;\n this.apiKey = apiKey;\n this.apiSecret = apiSecret;\n this.workerToken = workerToken;\n this.host = host;\n this.port = port || Default.port(production);\n this.logLevel = logLevel;\n this.production = production;\n this.jobMemoryWarnMB = jobMemoryWarnMB;\n this.jobMemoryLimitMB = jobMemoryLimitMB;\n }\n}\n\nclass PendingAssignment {\n promise = new Promise<JobAssignment>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: JobAssignment) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\n/**\n * Central orchestrator for all processes and job requests.\n *\n * @remarks\n * For most usecases, Worker should not be initialized or handled directly; you should instead call\n * for its creation through {@link cli.runApp}. This could, however, be useful in situations where\n * you don't have access to a command line, such as a headless program, or one that uses Agents\n * behind a wrapper.\n */\nexport class AgentServer {\n #opts: ServerOptions;\n #procPool: ProcPool;\n\n #id = 'unregistered';\n #closed = true;\n #draining = false;\n #connecting = false;\n #tasks: Promise<void>[] = [];\n #pending: { [id: string]: PendingAssignment } = {};\n #close = new Future();\n\n event = new EventEmitter();\n #session: WebSocket | undefined = undefined;\n #httpServer: HTTPServer;\n #logger = log().child({ version });\n #inferenceExecutor?: InferenceProcExecutor;\n\n /* @throws {@link MissingCredentialsError} if URL, API key or API secret are missing */\n constructor(opts: ServerOptions) {\n opts.wsURL = opts.wsURL || process.env.LIVEKIT_URL || '';\n opts.apiKey = opts.apiKey || process.env.LIVEKIT_API_KEY || '';\n opts.apiSecret = opts.apiSecret || process.env.LIVEKIT_API_SECRET || '';\n\n if (opts.wsURL === '')\n throw new MissingCredentialsError(\n 'URL is required: Set LIVEKIT_URL, run with --url, or pass wsURL in ServerOptions',\n );\n if (opts.apiKey === '')\n throw new MissingCredentialsError(\n 'API Key is required: Set LIVEKIT_API_KEY, run with --api-key, or pass apiKey in ServerOptions',\n );\n if (opts.apiSecret === '')\n throw new MissingCredentialsError(\n 'API Secret is required: Set LIVEKIT_API_SECRET, run with --api-secret, or pass apiSecret in ServerOptions',\n );\n\n if (opts.workerToken) {\n if (opts.loadFunc !== defaultCpuLoad) {\n this.#logger.warn(\n 'custom loadFunc is not supported when deploying to Cloud, using defaults',\n );\n opts.loadFunc = defaultCpuLoad;\n }\n const loadThreshold = Default.loadThreshold(opts.production);\n if (opts.loadThreshold !== loadThreshold) {\n this.#logger.warn(\n 'custom loadThreshold is not supported when deploying to Cloud, using defaults',\n );\n opts.loadThreshold = loadThreshold;\n }\n }\n\n if (Object.entries(InferenceRunner.registeredRunners).length) {\n this.#inferenceExecutor = new InferenceProcExecutor({\n runners: InferenceRunner.registeredRunners,\n initializeTimeout: 30000,\n closeTimeout: 5000,\n memoryWarnMB: 2000,\n memoryLimitMB: 0,\n pingInterval: 5000,\n pingTimeout: 60000,\n highPingThreshold: 2500,\n });\n }\n\n this.#procPool = new ProcPool(\n opts.agent,\n opts.numIdleProcesses,\n opts.initializeProcessTimeout,\n opts.shutdownProcessTimeout,\n this.#inferenceExecutor,\n opts.jobMemoryWarnMB,\n opts.jobMemoryLimitMB,\n );\n\n this.#opts = opts;\n\n const healthCheck = () => {\n // Check if inference executor exists and is not alive\n if (this.#inferenceExecutor && !this.#inferenceExecutor.isAlive) {\n return { healthy: false, message: 'inference process not running' };\n }\n\n // Only healthy when fully connected with an active WebSocket\n if (\n this.#closed ||\n this.#connecting ||\n !this.#session ||\n this.#session.readyState !== WebSocket.OPEN\n ) {\n return { healthy: false, message: 'not connected to livekit' };\n }\n\n return { healthy: true, message: 'OK' };\n };\n\n const getWorkerInfo = () => ({\n agent_name: opts.agentName,\n worker_type: JobType[opts.serverType],\n active_jobs: this.activeJobs.length,\n sdk_version: version,\n project_type: PROJECT_TYPE,\n });\n\n this.#httpServer = new HTTPServer(opts.host, opts.port, healthCheck, getWorkerInfo);\n }\n\n /** @throws {@link WorkerError} if worker failed to connect or already running */\n async run() {\n if (!this.#closed) {\n throw new WorkerError('worker is already running');\n }\n\n if (this.#inferenceExecutor) {\n await this.#inferenceExecutor.start();\n await this.#inferenceExecutor.initialize();\n }\n\n this.#logger.info('starting worker');\n this.#closed = false;\n this.#procPool.start();\n\n const workerWS = async () => {\n let retries = 0;\n this.#connecting = true;\n\n while (!this.#closed) {\n const url = new URL(this.#opts.wsURL);\n url.protocol = url.protocol.replace('http', 'ws');\n const token = new AccessToken(this.#opts.apiKey, this.#opts.apiSecret);\n token.addGrant({ agent: true });\n const jwt = await token.toJwt();\n const wsUrl = new URL(url + 'agent');\n if (this.#opts.workerToken) {\n wsUrl.searchParams.append('worker_token', this.#opts.workerToken);\n }\n this.#session = new WebSocket(wsUrl, {\n headers: { authorization: 'Bearer ' + jwt },\n });\n\n try {\n await new Promise((resolve, reject) => {\n this.#session!.on('open', resolve);\n this.#session!.on('error', (error) => reject(error));\n this.#session!.on('close', (code) => reject(`WebSocket returned ${code}`));\n });\n\n retries = 0;\n this.#logger.debug('connected to LiveKit server');\n await this.#runWS(this.#session);\n } catch (e: unknown) {\n if (this.#closed) return;\n if (retries >= this.#opts.maxRetry) {\n throw new WorkerError(\n `failed to connect to LiveKit server (${this.#opts.wsURL}) after ${retries} attempts: ${e}`,\n );\n }\n\n retries++;\n const delay = Math.min(retries * 2, 10);\n\n this.#logger.warn(\n e,\n `failed to connect to LiveKit server (${this.#opts.wsURL}), retrying in ${delay} seconds: (${retries}/${this.#opts.maxRetry})`,\n );\n\n await new Promise((resolve) => setTimeout(resolve, delay * 1000));\n }\n }\n };\n\n await Promise.all([workerWS(), this.#httpServer.run()]);\n this.#close.resolve();\n }\n\n get id(): string {\n return this.#id;\n }\n\n get activeJobs(): RunningJobInfo[] {\n return this.#procPool.processes\n .filter((proc) => proc.runningJob)\n .map((proc) => proc.runningJob!);\n }\n\n /** @throws {@link WorkerError} if worker did not drain in time */\n async drain(timeout?: number) {\n if (this.#draining) {\n return;\n }\n\n this.#logger.debug('draining worker');\n this.#draining = true;\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'updateWorker',\n value: {\n status: WorkerStatus.WS_FULL,\n },\n },\n }),\n );\n\n const joinJobs = async () => {\n return Promise.all(\n this.#procPool.processes.map((proc) => {\n if (!proc.runningJob) {\n proc.close();\n }\n return proc.join();\n }),\n );\n };\n\n let timer: NodeJS.Timeout | undefined;\n if (timeout) {\n timer = setTimeout(() => {\n throw new WorkerError('timed out draining');\n }, timeout);\n }\n await joinJobs().then(() => {\n if (timeout) {\n clearTimeout(timer);\n }\n });\n }\n\n async simulateJob(roomName: string, participantIdentity?: string) {\n const client = new RoomServiceClient(this.#opts.wsURL, this.#opts.apiKey, this.#opts.apiSecret);\n const room = await client.createRoom({ name: roomName });\n let participant: ParticipantInfo | undefined = undefined;\n if (participantIdentity) {\n try {\n // TODO(AJS-269): resolve compatibility issue with node-sdk to remove the forced type casting\n participant = (await client.getParticipant(\n roomName,\n participantIdentity,\n )) as unknown as ParticipantInfo;\n } catch (e) {\n this.#logger.fatal(\n `participant with identity ${participantIdentity} not found in room ${roomName}`,\n );\n throw e;\n }\n }\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'simulateJob',\n value: {\n type: JobType.JT_PUBLISHER,\n room,\n participant,\n },\n },\n }),\n );\n }\n\n async #runWS(ws: WebSocket) {\n let closingWS = false;\n\n const send = (msg: WorkerMessage) => {\n if (closingWS) {\n this.event.off('worker_msg', send);\n return;\n }\n ws.send(msg.toBinary());\n };\n this.event.on('worker_msg', send);\n\n const close = new Promise<void>((resolve) => {\n ws.addEventListener('close', () => {\n closingWS = true;\n if (!this.#closed) {\n this.#logger.error('worker connection closed unexpectedly');\n }\n resolve();\n });\n });\n\n ws.addEventListener('error', (event) => {\n this.#logger.error('worker error:', event.message);\n });\n\n ws.addEventListener('message', (event) => {\n if (event.type !== 'message') {\n this.#logger.warn('unexpected message type: ' + event.type);\n return;\n }\n\n const msg = new ServerMessage();\n msg.fromBinary(event.data as Uint8Array);\n\n // register is the only valid first message, and it is only valid as the\n // first message\n if (this.#connecting && msg.message.case !== 'register') {\n throw new WorkerError('expected register response as first message');\n }\n\n switch (msg.message.case) {\n case 'register': {\n this.#id = msg.message.value.workerId;\n this.#logger\n .child({ id: this.id, server_info: msg.message.value.serverInfo })\n .info('registered worker');\n this.event.emit(\n 'worker_registered',\n msg.message.value.workerId,\n msg.message.value.serverInfo,\n );\n this.#connecting = false;\n break;\n }\n case 'availability': {\n if (!msg.message.value.job) return;\n const task = this.#availability(msg.message.value);\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n break;\n }\n case 'assignment': {\n if (!msg.message.value.job) return;\n const job = msg.message.value.job;\n if (job.id in this.#pending) {\n const task = this.#pending[job.id];\n delete this.#pending[job.id];\n task?.resolve(msg.message.value);\n } else {\n this.#logger.child({ job }).warn('received assignment for unknown job ' + job.id);\n }\n break;\n }\n case 'termination': {\n const task = this.#termination(msg.message.value);\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n break;\n }\n }\n });\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'register',\n value: {\n type: this.#opts.serverType,\n agentName: this.#opts.agentName,\n allowedPermissions: new ParticipantPermission({\n canPublish: this.#opts.permissions.canPublish,\n canSubscribe: this.#opts.permissions.canSubscribe,\n canPublishData: this.#opts.permissions.canPublishData,\n canUpdateMetadata: this.#opts.permissions.canUpdateMetadata,\n hidden: this.#opts.permissions.hidden,\n agent: true,\n }),\n version,\n },\n },\n }),\n );\n\n let currentStatus = WorkerStatus.WS_AVAILABLE;\n const loadMonitor = setInterval(() => {\n if (closingWS) clearInterval(loadMonitor);\n\n const oldStatus = currentStatus;\n this.#opts.loadFunc(this).then((currentLoad: number) => {\n const isFull = currentLoad >= this.#opts.loadThreshold;\n const currentlyAvailable = !isFull;\n currentStatus = currentlyAvailable ? WorkerStatus.WS_AVAILABLE : WorkerStatus.WS_FULL;\n\n if (oldStatus != currentStatus) {\n const extra = { load: currentLoad, loadThreshold: this.#opts.loadThreshold };\n if (isFull) {\n this.#logger.child(extra).info('worker is at full capacity, marking as unavailable');\n } else {\n this.#logger.child(extra).info('worker is below capacity, marking as available');\n }\n }\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'updateWorker',\n value: {\n load: currentLoad,\n status: currentStatus,\n },\n },\n }),\n );\n });\n }, UPDATE_LOAD_INTERVAL);\n\n await close;\n ws.removeAllListeners();\n }\n\n async #availability(msg: AvailabilityRequest) {\n let answered = false;\n\n const onReject = async () => {\n answered = true;\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'availability',\n value: {\n jobId: msg.job!.id,\n available: false,\n },\n },\n }),\n );\n };\n\n const onAccept = async (args: JobAcceptArguments) => {\n answered = true;\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'availability',\n value: {\n jobId: msg.job!.id,\n available: true,\n participantIdentity: args.identity,\n participantName: args.name,\n participantMetadata: args.metadata,\n participantAttributes: args.attributes,\n },\n },\n }),\n );\n\n this.#pending[req.id] = new PendingAssignment();\n const timer = setTimeout(() => {\n this.#logger.child({ req }).warn(`assignment for job ${req.id} timed out`);\n return;\n }, ASSIGNMENT_TIMEOUT);\n const asgn = await this.#pending[req.id]?.promise.then(async (asgn) => {\n clearTimeout(timer);\n return asgn;\n });\n\n if (asgn) {\n await this.#procPool.launchJob({\n acceptArguments: args,\n job: msg.job!,\n url: asgn.url || this.#opts.wsURL,\n token: asgn.token,\n workerId: this.id,\n });\n } else {\n this.#logger.child({ requestId: req.id }).warn('pending assignment not found');\n }\n };\n\n const req = new JobRequest(msg.job!, onReject, onAccept);\n this.#logger\n .child({ jobId: msg.job?.id, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('received job request');\n\n const jobRequestTask = async () => {\n try {\n await this.#opts.requestFunc(req);\n } catch (e) {\n this.#logger\n .child({ job: msg.job, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('jobRequestFunc failed');\n await onReject();\n }\n\n if (!answered) {\n this.#logger\n .child({ job: msg.job, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('no answer was given inside the jobRequestFunc, automatically rejecting the job');\n }\n };\n\n const task = jobRequestTask();\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n }\n\n async #termination(msg: JobTermination) {\n const proc = this.#procPool.getByJobId(msg.jobId);\n if (proc === null) {\n // safe to ignore\n return;\n }\n await proc.close();\n }\n\n async close() {\n if (this.#closed) {\n await this.#close.await;\n return;\n }\n\n this.#logger.debug('shutting down worker');\n\n this.#closed = true;\n\n await this.#inferenceExecutor?.close();\n await this.#procPool.close();\n await this.#httpServer.close();\n await Promise.allSettled(this.#tasks);\n\n this.#session?.close();\n await this.#close.await;\n }\n}\n\n/**\n * @deprecated Use {@link AgentServer} instead. This alias is provided for backward compatibility.\n */\nexport const Worker = AgentServer;\n\n/**\n * @deprecated Use {@link ServerOptions} instead. This alias is provided for backward compatibility.\n */\nexport const WorkerOptions = ServerOptions;\n"],"mappings":"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","names":["os","i","_a","asgn"]}
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
package/dist/worker.js CHANGED
@@ -244,13 +244,23 @@ class AgentServer {
244
244
  opts.jobMemoryLimitMB
245
245
  );
246
246
  this.#opts = opts;
247
- this.#httpServer = new HTTPServer(opts.host, opts.port, () => ({
247
+ const healthCheck = () => {
248
+ if (this.#inferenceExecutor && !this.#inferenceExecutor.isAlive) {
249
+ return { healthy: false, message: "inference process not running" };
250
+ }
251
+ if (this.#closed || this.#connecting || !this.#session || this.#session.readyState !== WebSocket.OPEN) {
252
+ return { healthy: false, message: "not connected to livekit" };
253
+ }
254
+ return { healthy: true, message: "OK" };
255
+ };
256
+ const getWorkerInfo = () => ({
248
257
  agent_name: opts.agentName,
249
258
  worker_type: JobType[opts.serverType],
250
259
  active_jobs: this.activeJobs.length,
251
260
  sdk_version: version,
252
261
  project_type: PROJECT_TYPE
253
- }));
262
+ });
263
+ this.#httpServer = new HTTPServer(opts.host, opts.port, healthCheck, getWorkerInfo);
254
264
  }
255
265
  /** @throws {@link WorkerError} if worker failed to connect or already running */
256
266
  async run() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/worker.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { JobAssignment, JobTermination, TrackSource } from '@livekit/protocol';\nimport {\n type AvailabilityRequest,\n JobType,\n ParticipantPermission,\n ServerMessage,\n WorkerMessage,\n WorkerStatus,\n} from '@livekit/protocol';\nimport type { ParticipantInfo } from 'livekit-server-sdk';\nimport { AccessToken, RoomServiceClient } from 'livekit-server-sdk';\nimport { EventEmitter } from 'node:events';\nimport os from 'node:os';\nimport { WebSocket } from 'ws';\nimport { HTTPServer } from './http_server.js';\nimport { InferenceRunner } from './inference_runner.js';\nimport { InferenceProcExecutor } from './ipc/inference_proc_executor.js';\nimport { ProcPool } from './ipc/proc_pool.js';\nimport type { JobAcceptArguments, JobProcess, RunningJobInfo } from './job.js';\nimport { JobRequest } from './job.js';\nimport { log } from './log.js';\nimport { Future } from './utils.js';\nimport { version } from './version.js';\n\nconst MAX_RECONNECT_ATTEMPTS = 10;\nconst ASSIGNMENT_TIMEOUT = 7.5 * 1000;\nconst UPDATE_LOAD_INTERVAL = 2.5 * 1000;\nconst PROJECT_TYPE = 'nodejs';\n\nclass Default {\n static loadThreshold(production: boolean): number {\n if (production) {\n return 0.7;\n } else {\n return Infinity;\n }\n }\n\n static numIdleProcesses(production: boolean): number {\n if (production) {\n // TODO: use number of cores\n return 3;\n } else {\n return 0;\n }\n }\n\n static port(production: boolean): number {\n if (production) {\n return 8081;\n } else {\n return 0;\n }\n }\n}\n\n/** Necessary credentials not provided and not found in an appropriate environment variable. */\nexport class MissingCredentialsError extends Error {\n constructor(msg?: string) {\n super(msg);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Worker did not run as expected. */\nexport class WorkerError extends Error {\n constructor(msg?: string) {\n super(msg);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** @internal */\nexport const defaultInitializeProcessFunc = (_: JobProcess) => _;\nconst defaultRequestFunc = async (ctx: JobRequest) => {\n await ctx.accept();\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst defaultCpuLoad = async (worker: AgentServer): Promise<number> => {\n return new Promise((resolve) => {\n const cpus1 = os.cpus();\n\n setTimeout(() => {\n const cpus2 = os.cpus();\n\n let idle = 0;\n let total = 0;\n\n for (let i = 0; i < cpus1.length; i++) {\n const cpu1 = cpus1[i]!.times;\n const cpu2 = cpus2[i]!.times;\n\n idle += cpu2.idle - cpu1.idle;\n\n const total1 = Object.values(cpu1).reduce((acc, i) => acc + i, 0);\n const total2 = Object.values(cpu2).reduce((acc, i) => acc + i, 0);\n\n total += total2 - total1;\n }\n\n resolve(+(1 - idle / total).toFixed(2));\n }, UPDATE_LOAD_INTERVAL);\n });\n};\n\n/** Participant permissions to pass to every agent spun up by this worker. */\nexport class WorkerPermissions {\n canPublish: boolean;\n canSubscribe: boolean;\n canPublishData: boolean;\n canUpdateMetadata: boolean;\n canPublishSources: TrackSource[];\n hidden: boolean;\n\n constructor(\n canPublish = true,\n canSubscribe = true,\n canPublishData = true,\n canUpdateMetadata = true,\n canPublishSources: TrackSource[] = [],\n hidden = false,\n ) {\n this.canPublish = canPublish;\n this.canSubscribe = canSubscribe;\n this.canPublishData = canPublishData;\n this.canUpdateMetadata = canUpdateMetadata;\n this.canPublishSources = canPublishSources;\n this.hidden = hidden;\n }\n}\n\n/**\n * Data class describing worker behaviour.\n *\n * @remarks\n * The Agents framework provides sane worker defaults, and works out-of-the-box with no tweaking\n * necessary. The only mandatory parameter is `agent`, which points to the entry function.\n *\n * This class is mostly useful in conjunction with {@link cli.runApp}.\n */\nexport class ServerOptions {\n agent: string;\n requestFunc: (job: JobRequest) => Promise<void>;\n loadFunc: (worker: AgentServer) => Promise<number>;\n loadThreshold: number;\n numIdleProcesses: number;\n shutdownProcessTimeout: number;\n initializeProcessTimeout: number;\n permissions: WorkerPermissions;\n agentName: string;\n serverType: JobType;\n maxRetry: number;\n wsURL: string;\n apiKey?: string;\n apiSecret?: string;\n workerToken?: string;\n host: string;\n port: number;\n logLevel: string;\n production: boolean;\n jobMemoryWarnMB: number;\n jobMemoryLimitMB: number;\n\n /** @param options - Worker options */\n constructor({\n agent,\n requestFunc = defaultRequestFunc,\n loadFunc = defaultCpuLoad,\n loadThreshold = undefined,\n numIdleProcesses = undefined,\n shutdownProcessTimeout = 60 * 1000,\n initializeProcessTimeout = 10 * 1000,\n permissions = new WorkerPermissions(),\n agentName = '',\n serverType = JobType.JT_ROOM,\n maxRetry = MAX_RECONNECT_ATTEMPTS,\n wsURL = 'ws://localhost:7880',\n apiKey = undefined,\n apiSecret = undefined,\n workerToken = undefined,\n host = '0.0.0.0',\n port = undefined,\n logLevel = 'info',\n production = false,\n jobMemoryWarnMB = 500,\n jobMemoryLimitMB = 0,\n }: {\n /**\n * Path to a file that has {@link Agent} as a default export, dynamically imported later for\n * entrypoint and prewarm functions\n */\n agent: string;\n requestFunc?: (job: JobRequest) => Promise<void>;\n /** Called to determine the current load of the worker. Should return a value between 0 and 1. */\n loadFunc?: (worker: AgentServer) => Promise<number>;\n /** When the load exceeds this threshold, the worker will be marked as unavailable. */\n loadThreshold?: number;\n numIdleProcesses?: number;\n shutdownProcessTimeout?: number;\n initializeProcessTimeout?: number;\n permissions?: WorkerPermissions;\n agentName?: string;\n serverType?: JobType;\n maxRetry?: number;\n wsURL?: string;\n apiKey?: string;\n apiSecret?: string;\n workerToken?: string;\n host?: string;\n port?: number;\n logLevel?: string;\n production?: boolean;\n jobMemoryWarnMB?: number;\n jobMemoryLimitMB?: number;\n }) {\n this.agent = agent;\n if (!this.agent) {\n throw new Error('No Agent file was passed to the worker');\n }\n this.requestFunc = requestFunc;\n this.loadFunc = loadFunc;\n this.loadThreshold = loadThreshold || Default.loadThreshold(production);\n this.numIdleProcesses = numIdleProcesses || Default.numIdleProcesses(production);\n this.shutdownProcessTimeout = shutdownProcessTimeout;\n this.initializeProcessTimeout = initializeProcessTimeout;\n this.permissions = permissions;\n this.agentName = agentName;\n this.serverType = serverType;\n this.maxRetry = maxRetry;\n this.wsURL = wsURL;\n this.apiKey = apiKey;\n this.apiSecret = apiSecret;\n this.workerToken = workerToken;\n this.host = host;\n this.port = port || Default.port(production);\n this.logLevel = logLevel;\n this.production = production;\n this.jobMemoryWarnMB = jobMemoryWarnMB;\n this.jobMemoryLimitMB = jobMemoryLimitMB;\n }\n}\n\nclass PendingAssignment {\n promise = new Promise<JobAssignment>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: JobAssignment) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\n/**\n * Central orchestrator for all processes and job requests.\n *\n * @remarks\n * For most usecases, Worker should not be initialized or handled directly; you should instead call\n * for its creation through {@link cli.runApp}. This could, however, be useful in situations where\n * you don't have access to a command line, such as a headless program, or one that uses Agents\n * behind a wrapper.\n */\nexport class AgentServer {\n #opts: ServerOptions;\n #procPool: ProcPool;\n\n #id = 'unregistered';\n #closed = true;\n #draining = false;\n #connecting = false;\n #tasks: Promise<void>[] = [];\n #pending: { [id: string]: PendingAssignment } = {};\n #close = new Future();\n\n event = new EventEmitter();\n #session: WebSocket | undefined = undefined;\n #httpServer: HTTPServer;\n #logger = log().child({ version });\n #inferenceExecutor?: InferenceProcExecutor;\n\n /* @throws {@link MissingCredentialsError} if URL, API key or API secret are missing */\n constructor(opts: ServerOptions) {\n opts.wsURL = opts.wsURL || process.env.LIVEKIT_URL || '';\n opts.apiKey = opts.apiKey || process.env.LIVEKIT_API_KEY || '';\n opts.apiSecret = opts.apiSecret || process.env.LIVEKIT_API_SECRET || '';\n\n if (opts.wsURL === '')\n throw new MissingCredentialsError(\n 'URL is required: Set LIVEKIT_URL, run with --url, or pass wsURL in ServerOptions',\n );\n if (opts.apiKey === '')\n throw new MissingCredentialsError(\n 'API Key is required: Set LIVEKIT_API_KEY, run with --api-key, or pass apiKey in ServerOptions',\n );\n if (opts.apiSecret === '')\n throw new MissingCredentialsError(\n 'API Secret is required: Set LIVEKIT_API_SECRET, run with --api-secret, or pass apiSecret in ServerOptions',\n );\n\n if (opts.workerToken) {\n if (opts.loadFunc !== defaultCpuLoad) {\n this.#logger.warn(\n 'custom loadFunc is not supported when deploying to Cloud, using defaults',\n );\n opts.loadFunc = defaultCpuLoad;\n }\n const loadThreshold = Default.loadThreshold(opts.production);\n if (opts.loadThreshold !== loadThreshold) {\n this.#logger.warn(\n 'custom loadThreshold is not supported when deploying to Cloud, using defaults',\n );\n opts.loadThreshold = loadThreshold;\n }\n }\n\n if (Object.entries(InferenceRunner.registeredRunners).length) {\n this.#inferenceExecutor = new InferenceProcExecutor({\n runners: InferenceRunner.registeredRunners,\n initializeTimeout: 30000,\n closeTimeout: 5000,\n memoryWarnMB: 2000,\n memoryLimitMB: 0,\n pingInterval: 5000,\n pingTimeout: 60000,\n highPingThreshold: 2500,\n });\n }\n\n this.#procPool = new ProcPool(\n opts.agent,\n opts.numIdleProcesses,\n opts.initializeProcessTimeout,\n opts.shutdownProcessTimeout,\n this.#inferenceExecutor,\n opts.jobMemoryWarnMB,\n opts.jobMemoryLimitMB,\n );\n\n this.#opts = opts;\n this.#httpServer = new HTTPServer(opts.host, opts.port, () => ({\n agent_name: opts.agentName,\n worker_type: JobType[opts.serverType],\n active_jobs: this.activeJobs.length,\n sdk_version: version,\n project_type: PROJECT_TYPE,\n }));\n }\n\n /** @throws {@link WorkerError} if worker failed to connect or already running */\n async run() {\n if (!this.#closed) {\n throw new WorkerError('worker is already running');\n }\n\n if (this.#inferenceExecutor) {\n await this.#inferenceExecutor.start();\n await this.#inferenceExecutor.initialize();\n }\n\n this.#logger.info('starting worker');\n this.#closed = false;\n this.#procPool.start();\n\n const workerWS = async () => {\n let retries = 0;\n this.#connecting = true;\n\n while (!this.#closed) {\n const url = new URL(this.#opts.wsURL);\n url.protocol = url.protocol.replace('http', 'ws');\n const token = new AccessToken(this.#opts.apiKey, this.#opts.apiSecret);\n token.addGrant({ agent: true });\n const jwt = await token.toJwt();\n const wsUrl = new URL(url + 'agent');\n if (this.#opts.workerToken) {\n wsUrl.searchParams.append('worker_token', this.#opts.workerToken);\n }\n this.#session = new WebSocket(wsUrl, {\n headers: { authorization: 'Bearer ' + jwt },\n });\n\n try {\n await new Promise((resolve, reject) => {\n this.#session!.on('open', resolve);\n this.#session!.on('error', (error) => reject(error));\n this.#session!.on('close', (code) => reject(`WebSocket returned ${code}`));\n });\n\n retries = 0;\n this.#logger.debug('connected to LiveKit server');\n await this.#runWS(this.#session);\n } catch (e: unknown) {\n if (this.#closed) return;\n if (retries >= this.#opts.maxRetry) {\n throw new WorkerError(\n `failed to connect to LiveKit server (${this.#opts.wsURL}) after ${retries} attempts: ${e}`,\n );\n }\n\n retries++;\n const delay = Math.min(retries * 2, 10);\n\n this.#logger.warn(\n e,\n `failed to connect to LiveKit server (${this.#opts.wsURL}), retrying in ${delay} seconds: (${retries}/${this.#opts.maxRetry})`,\n );\n\n await new Promise((resolve) => setTimeout(resolve, delay * 1000));\n }\n }\n };\n\n await Promise.all([workerWS(), this.#httpServer.run()]);\n this.#close.resolve();\n }\n\n get id(): string {\n return this.#id;\n }\n\n get activeJobs(): RunningJobInfo[] {\n return this.#procPool.processes\n .filter((proc) => proc.runningJob)\n .map((proc) => proc.runningJob!);\n }\n\n /** @throws {@link WorkerError} if worker did not drain in time */\n async drain(timeout?: number) {\n if (this.#draining) {\n return;\n }\n\n this.#logger.debug('draining worker');\n this.#draining = true;\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'updateWorker',\n value: {\n status: WorkerStatus.WS_FULL,\n },\n },\n }),\n );\n\n const joinJobs = async () => {\n return Promise.all(\n this.#procPool.processes.map((proc) => {\n if (!proc.runningJob) {\n proc.close();\n }\n return proc.join();\n }),\n );\n };\n\n let timer: NodeJS.Timeout | undefined;\n if (timeout) {\n timer = setTimeout(() => {\n throw new WorkerError('timed out draining');\n }, timeout);\n }\n await joinJobs().then(() => {\n if (timeout) {\n clearTimeout(timer);\n }\n });\n }\n\n async simulateJob(roomName: string, participantIdentity?: string) {\n const client = new RoomServiceClient(this.#opts.wsURL, this.#opts.apiKey, this.#opts.apiSecret);\n const room = await client.createRoom({ name: roomName });\n let participant: ParticipantInfo | undefined = undefined;\n if (participantIdentity) {\n try {\n // TODO(AJS-269): resolve compatibility issue with node-sdk to remove the forced type casting\n participant = (await client.getParticipant(\n roomName,\n participantIdentity,\n )) as unknown as ParticipantInfo;\n } catch (e) {\n this.#logger.fatal(\n `participant with identity ${participantIdentity} not found in room ${roomName}`,\n );\n throw e;\n }\n }\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'simulateJob',\n value: {\n type: JobType.JT_PUBLISHER,\n room,\n participant,\n },\n },\n }),\n );\n }\n\n async #runWS(ws: WebSocket) {\n let closingWS = false;\n\n const send = (msg: WorkerMessage) => {\n if (closingWS) {\n this.event.off('worker_msg', send);\n return;\n }\n ws.send(msg.toBinary());\n };\n this.event.on('worker_msg', send);\n\n const close = new Promise<void>((resolve) => {\n ws.addEventListener('close', () => {\n closingWS = true;\n if (!this.#closed) {\n this.#logger.error('worker connection closed unexpectedly');\n }\n resolve();\n });\n });\n\n ws.addEventListener('error', (event) => {\n this.#logger.error('worker error:', event.message);\n });\n\n ws.addEventListener('message', (event) => {\n if (event.type !== 'message') {\n this.#logger.warn('unexpected message type: ' + event.type);\n return;\n }\n\n const msg = new ServerMessage();\n msg.fromBinary(event.data as Uint8Array);\n\n // register is the only valid first message, and it is only valid as the\n // first message\n if (this.#connecting && msg.message.case !== 'register') {\n throw new WorkerError('expected register response as first message');\n }\n\n switch (msg.message.case) {\n case 'register': {\n this.#id = msg.message.value.workerId;\n this.#logger\n .child({ id: this.id, server_info: msg.message.value.serverInfo })\n .info('registered worker');\n this.event.emit(\n 'worker_registered',\n msg.message.value.workerId,\n msg.message.value.serverInfo,\n );\n this.#connecting = false;\n break;\n }\n case 'availability': {\n if (!msg.message.value.job) return;\n const task = this.#availability(msg.message.value);\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n break;\n }\n case 'assignment': {\n if (!msg.message.value.job) return;\n const job = msg.message.value.job;\n if (job.id in this.#pending) {\n const task = this.#pending[job.id];\n delete this.#pending[job.id];\n task?.resolve(msg.message.value);\n } else {\n this.#logger.child({ job }).warn('received assignment for unknown job ' + job.id);\n }\n break;\n }\n case 'termination': {\n const task = this.#termination(msg.message.value);\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n break;\n }\n }\n });\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'register',\n value: {\n type: this.#opts.serverType,\n agentName: this.#opts.agentName,\n allowedPermissions: new ParticipantPermission({\n canPublish: this.#opts.permissions.canPublish,\n canSubscribe: this.#opts.permissions.canSubscribe,\n canPublishData: this.#opts.permissions.canPublishData,\n canUpdateMetadata: this.#opts.permissions.canUpdateMetadata,\n hidden: this.#opts.permissions.hidden,\n agent: true,\n }),\n version,\n },\n },\n }),\n );\n\n let currentStatus = WorkerStatus.WS_AVAILABLE;\n const loadMonitor = setInterval(() => {\n if (closingWS) clearInterval(loadMonitor);\n\n const oldStatus = currentStatus;\n this.#opts.loadFunc(this).then((currentLoad: number) => {\n const isFull = currentLoad >= this.#opts.loadThreshold;\n const currentlyAvailable = !isFull;\n currentStatus = currentlyAvailable ? WorkerStatus.WS_AVAILABLE : WorkerStatus.WS_FULL;\n\n if (oldStatus != currentStatus) {\n const extra = { load: currentLoad, loadThreshold: this.#opts.loadThreshold };\n if (isFull) {\n this.#logger.child(extra).info('worker is at full capacity, marking as unavailable');\n } else {\n this.#logger.child(extra).info('worker is below capacity, marking as available');\n }\n }\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'updateWorker',\n value: {\n load: currentLoad,\n status: currentStatus,\n },\n },\n }),\n );\n });\n }, UPDATE_LOAD_INTERVAL);\n\n await close;\n ws.removeAllListeners();\n }\n\n async #availability(msg: AvailabilityRequest) {\n let answered = false;\n\n const onReject = async () => {\n answered = true;\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'availability',\n value: {\n jobId: msg.job!.id,\n available: false,\n },\n },\n }),\n );\n };\n\n const onAccept = async (args: JobAcceptArguments) => {\n answered = true;\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'availability',\n value: {\n jobId: msg.job!.id,\n available: true,\n participantIdentity: args.identity,\n participantName: args.name,\n participantMetadata: args.metadata,\n participantAttributes: args.attributes,\n },\n },\n }),\n );\n\n this.#pending[req.id] = new PendingAssignment();\n const timer = setTimeout(() => {\n this.#logger.child({ req }).warn(`assignment for job ${req.id} timed out`);\n return;\n }, ASSIGNMENT_TIMEOUT);\n const asgn = await this.#pending[req.id]?.promise.then(async (asgn) => {\n clearTimeout(timer);\n return asgn;\n });\n\n if (asgn) {\n await this.#procPool.launchJob({\n acceptArguments: args,\n job: msg.job!,\n url: asgn.url || this.#opts.wsURL,\n token: asgn.token,\n workerId: this.id,\n });\n } else {\n this.#logger.child({ requestId: req.id }).warn('pending assignment not found');\n }\n };\n\n const req = new JobRequest(msg.job!, onReject, onAccept);\n this.#logger\n .child({ jobId: msg.job?.id, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('received job request');\n\n const jobRequestTask = async () => {\n try {\n await this.#opts.requestFunc(req);\n } catch (e) {\n this.#logger\n .child({ job: msg.job, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('jobRequestFunc failed');\n await onReject();\n }\n\n if (!answered) {\n this.#logger\n .child({ job: msg.job, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('no answer was given inside the jobRequestFunc, automatically rejecting the job');\n }\n };\n\n const task = jobRequestTask();\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n }\n\n async #termination(msg: JobTermination) {\n const proc = this.#procPool.getByJobId(msg.jobId);\n if (proc === null) {\n // safe to ignore\n return;\n }\n await proc.close();\n }\n\n async close() {\n if (this.#closed) {\n await this.#close.await;\n return;\n }\n\n this.#logger.debug('shutting down worker');\n\n this.#closed = true;\n\n await this.#inferenceExecutor?.close();\n await this.#procPool.close();\n await this.#httpServer.close();\n await Promise.allSettled(this.#tasks);\n\n this.#session?.close();\n await this.#close.await;\n }\n}\n\n/**\n * @deprecated Use {@link AgentServer} instead. This alias is provided for backward compatibility.\n */\nexport const Worker = AgentServer;\n\n/**\n * @deprecated Use {@link ServerOptions} instead. This alias is provided for backward compatibility.\n */\nexport const WorkerOptions = ServerOptions;\n"],"mappings":"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","names":["i","_a","asgn"]}
1
+ {"version":3,"sources":["../src/worker.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { JobAssignment, JobTermination, TrackSource } from '@livekit/protocol';\nimport {\n type AvailabilityRequest,\n JobType,\n ParticipantPermission,\n ServerMessage,\n WorkerMessage,\n WorkerStatus,\n} from '@livekit/protocol';\nimport type { ParticipantInfo } from 'livekit-server-sdk';\nimport { AccessToken, RoomServiceClient } from 'livekit-server-sdk';\nimport { EventEmitter } from 'node:events';\nimport os from 'node:os';\nimport { WebSocket } from 'ws';\nimport { HTTPServer } from './http_server.js';\nimport { InferenceRunner } from './inference_runner.js';\nimport { InferenceProcExecutor } from './ipc/inference_proc_executor.js';\nimport { ProcPool } from './ipc/proc_pool.js';\nimport type { JobAcceptArguments, JobProcess, RunningJobInfo } from './job.js';\nimport { JobRequest } from './job.js';\nimport { log } from './log.js';\nimport { Future } from './utils.js';\nimport { version } from './version.js';\n\nconst MAX_RECONNECT_ATTEMPTS = 10;\nconst ASSIGNMENT_TIMEOUT = 7.5 * 1000;\nconst UPDATE_LOAD_INTERVAL = 2.5 * 1000;\nconst PROJECT_TYPE = 'nodejs';\n\nclass Default {\n static loadThreshold(production: boolean): number {\n if (production) {\n return 0.7;\n } else {\n return Infinity;\n }\n }\n\n static numIdleProcesses(production: boolean): number {\n if (production) {\n // TODO: use number of cores\n return 3;\n } else {\n return 0;\n }\n }\n\n static port(production: boolean): number {\n if (production) {\n return 8081;\n } else {\n return 0;\n }\n }\n}\n\n/** Necessary credentials not provided and not found in an appropriate environment variable. */\nexport class MissingCredentialsError extends Error {\n constructor(msg?: string) {\n super(msg);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Worker did not run as expected. */\nexport class WorkerError extends Error {\n constructor(msg?: string) {\n super(msg);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** @internal */\nexport const defaultInitializeProcessFunc = (_: JobProcess) => _;\nconst defaultRequestFunc = async (ctx: JobRequest) => {\n await ctx.accept();\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst defaultCpuLoad = async (worker: AgentServer): Promise<number> => {\n return new Promise((resolve) => {\n const cpus1 = os.cpus();\n\n setTimeout(() => {\n const cpus2 = os.cpus();\n\n let idle = 0;\n let total = 0;\n\n for (let i = 0; i < cpus1.length; i++) {\n const cpu1 = cpus1[i]!.times;\n const cpu2 = cpus2[i]!.times;\n\n idle += cpu2.idle - cpu1.idle;\n\n const total1 = Object.values(cpu1).reduce((acc, i) => acc + i, 0);\n const total2 = Object.values(cpu2).reduce((acc, i) => acc + i, 0);\n\n total += total2 - total1;\n }\n\n resolve(+(1 - idle / total).toFixed(2));\n }, UPDATE_LOAD_INTERVAL);\n });\n};\n\n/** Participant permissions to pass to every agent spun up by this worker. */\nexport class WorkerPermissions {\n canPublish: boolean;\n canSubscribe: boolean;\n canPublishData: boolean;\n canUpdateMetadata: boolean;\n canPublishSources: TrackSource[];\n hidden: boolean;\n\n constructor(\n canPublish = true,\n canSubscribe = true,\n canPublishData = true,\n canUpdateMetadata = true,\n canPublishSources: TrackSource[] = [],\n hidden = false,\n ) {\n this.canPublish = canPublish;\n this.canSubscribe = canSubscribe;\n this.canPublishData = canPublishData;\n this.canUpdateMetadata = canUpdateMetadata;\n this.canPublishSources = canPublishSources;\n this.hidden = hidden;\n }\n}\n\n/**\n * Data class describing worker behaviour.\n *\n * @remarks\n * The Agents framework provides sane worker defaults, and works out-of-the-box with no tweaking\n * necessary. The only mandatory parameter is `agent`, which points to the entry function.\n *\n * This class is mostly useful in conjunction with {@link cli.runApp}.\n */\nexport class ServerOptions {\n agent: string;\n requestFunc: (job: JobRequest) => Promise<void>;\n loadFunc: (worker: AgentServer) => Promise<number>;\n loadThreshold: number;\n numIdleProcesses: number;\n shutdownProcessTimeout: number;\n initializeProcessTimeout: number;\n permissions: WorkerPermissions;\n agentName: string;\n serverType: JobType;\n maxRetry: number;\n wsURL: string;\n apiKey?: string;\n apiSecret?: string;\n workerToken?: string;\n host: string;\n port: number;\n logLevel: string;\n production: boolean;\n jobMemoryWarnMB: number;\n jobMemoryLimitMB: number;\n\n /** @param options - Worker options */\n constructor({\n agent,\n requestFunc = defaultRequestFunc,\n loadFunc = defaultCpuLoad,\n loadThreshold = undefined,\n numIdleProcesses = undefined,\n shutdownProcessTimeout = 60 * 1000,\n initializeProcessTimeout = 10 * 1000,\n permissions = new WorkerPermissions(),\n agentName = '',\n serverType = JobType.JT_ROOM,\n maxRetry = MAX_RECONNECT_ATTEMPTS,\n wsURL = 'ws://localhost:7880',\n apiKey = undefined,\n apiSecret = undefined,\n workerToken = undefined,\n host = '0.0.0.0',\n port = undefined,\n logLevel = 'info',\n production = false,\n jobMemoryWarnMB = 500,\n jobMemoryLimitMB = 0,\n }: {\n /**\n * Path to a file that has {@link Agent} as a default export, dynamically imported later for\n * entrypoint and prewarm functions\n */\n agent: string;\n requestFunc?: (job: JobRequest) => Promise<void>;\n /** Called to determine the current load of the worker. Should return a value between 0 and 1. */\n loadFunc?: (worker: AgentServer) => Promise<number>;\n /** When the load exceeds this threshold, the worker will be marked as unavailable. */\n loadThreshold?: number;\n numIdleProcesses?: number;\n shutdownProcessTimeout?: number;\n initializeProcessTimeout?: number;\n permissions?: WorkerPermissions;\n agentName?: string;\n serverType?: JobType;\n maxRetry?: number;\n wsURL?: string;\n apiKey?: string;\n apiSecret?: string;\n workerToken?: string;\n host?: string;\n port?: number;\n logLevel?: string;\n production?: boolean;\n jobMemoryWarnMB?: number;\n jobMemoryLimitMB?: number;\n }) {\n this.agent = agent;\n if (!this.agent) {\n throw new Error('No Agent file was passed to the worker');\n }\n this.requestFunc = requestFunc;\n this.loadFunc = loadFunc;\n this.loadThreshold = loadThreshold || Default.loadThreshold(production);\n this.numIdleProcesses = numIdleProcesses || Default.numIdleProcesses(production);\n this.shutdownProcessTimeout = shutdownProcessTimeout;\n this.initializeProcessTimeout = initializeProcessTimeout;\n this.permissions = permissions;\n this.agentName = agentName;\n this.serverType = serverType;\n this.maxRetry = maxRetry;\n this.wsURL = wsURL;\n this.apiKey = apiKey;\n this.apiSecret = apiSecret;\n this.workerToken = workerToken;\n this.host = host;\n this.port = port || Default.port(production);\n this.logLevel = logLevel;\n this.production = production;\n this.jobMemoryWarnMB = jobMemoryWarnMB;\n this.jobMemoryLimitMB = jobMemoryLimitMB;\n }\n}\n\nclass PendingAssignment {\n promise = new Promise<JobAssignment>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: JobAssignment) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\n/**\n * Central orchestrator for all processes and job requests.\n *\n * @remarks\n * For most usecases, Worker should not be initialized or handled directly; you should instead call\n * for its creation through {@link cli.runApp}. This could, however, be useful in situations where\n * you don't have access to a command line, such as a headless program, or one that uses Agents\n * behind a wrapper.\n */\nexport class AgentServer {\n #opts: ServerOptions;\n #procPool: ProcPool;\n\n #id = 'unregistered';\n #closed = true;\n #draining = false;\n #connecting = false;\n #tasks: Promise<void>[] = [];\n #pending: { [id: string]: PendingAssignment } = {};\n #close = new Future();\n\n event = new EventEmitter();\n #session: WebSocket | undefined = undefined;\n #httpServer: HTTPServer;\n #logger = log().child({ version });\n #inferenceExecutor?: InferenceProcExecutor;\n\n /* @throws {@link MissingCredentialsError} if URL, API key or API secret are missing */\n constructor(opts: ServerOptions) {\n opts.wsURL = opts.wsURL || process.env.LIVEKIT_URL || '';\n opts.apiKey = opts.apiKey || process.env.LIVEKIT_API_KEY || '';\n opts.apiSecret = opts.apiSecret || process.env.LIVEKIT_API_SECRET || '';\n\n if (opts.wsURL === '')\n throw new MissingCredentialsError(\n 'URL is required: Set LIVEKIT_URL, run with --url, or pass wsURL in ServerOptions',\n );\n if (opts.apiKey === '')\n throw new MissingCredentialsError(\n 'API Key is required: Set LIVEKIT_API_KEY, run with --api-key, or pass apiKey in ServerOptions',\n );\n if (opts.apiSecret === '')\n throw new MissingCredentialsError(\n 'API Secret is required: Set LIVEKIT_API_SECRET, run with --api-secret, or pass apiSecret in ServerOptions',\n );\n\n if (opts.workerToken) {\n if (opts.loadFunc !== defaultCpuLoad) {\n this.#logger.warn(\n 'custom loadFunc is not supported when deploying to Cloud, using defaults',\n );\n opts.loadFunc = defaultCpuLoad;\n }\n const loadThreshold = Default.loadThreshold(opts.production);\n if (opts.loadThreshold !== loadThreshold) {\n this.#logger.warn(\n 'custom loadThreshold is not supported when deploying to Cloud, using defaults',\n );\n opts.loadThreshold = loadThreshold;\n }\n }\n\n if (Object.entries(InferenceRunner.registeredRunners).length) {\n this.#inferenceExecutor = new InferenceProcExecutor({\n runners: InferenceRunner.registeredRunners,\n initializeTimeout: 30000,\n closeTimeout: 5000,\n memoryWarnMB: 2000,\n memoryLimitMB: 0,\n pingInterval: 5000,\n pingTimeout: 60000,\n highPingThreshold: 2500,\n });\n }\n\n this.#procPool = new ProcPool(\n opts.agent,\n opts.numIdleProcesses,\n opts.initializeProcessTimeout,\n opts.shutdownProcessTimeout,\n this.#inferenceExecutor,\n opts.jobMemoryWarnMB,\n opts.jobMemoryLimitMB,\n );\n\n this.#opts = opts;\n\n const healthCheck = () => {\n // Check if inference executor exists and is not alive\n if (this.#inferenceExecutor && !this.#inferenceExecutor.isAlive) {\n return { healthy: false, message: 'inference process not running' };\n }\n\n // Only healthy when fully connected with an active WebSocket\n if (\n this.#closed ||\n this.#connecting ||\n !this.#session ||\n this.#session.readyState !== WebSocket.OPEN\n ) {\n return { healthy: false, message: 'not connected to livekit' };\n }\n\n return { healthy: true, message: 'OK' };\n };\n\n const getWorkerInfo = () => ({\n agent_name: opts.agentName,\n worker_type: JobType[opts.serverType],\n active_jobs: this.activeJobs.length,\n sdk_version: version,\n project_type: PROJECT_TYPE,\n });\n\n this.#httpServer = new HTTPServer(opts.host, opts.port, healthCheck, getWorkerInfo);\n }\n\n /** @throws {@link WorkerError} if worker failed to connect or already running */\n async run() {\n if (!this.#closed) {\n throw new WorkerError('worker is already running');\n }\n\n if (this.#inferenceExecutor) {\n await this.#inferenceExecutor.start();\n await this.#inferenceExecutor.initialize();\n }\n\n this.#logger.info('starting worker');\n this.#closed = false;\n this.#procPool.start();\n\n const workerWS = async () => {\n let retries = 0;\n this.#connecting = true;\n\n while (!this.#closed) {\n const url = new URL(this.#opts.wsURL);\n url.protocol = url.protocol.replace('http', 'ws');\n const token = new AccessToken(this.#opts.apiKey, this.#opts.apiSecret);\n token.addGrant({ agent: true });\n const jwt = await token.toJwt();\n const wsUrl = new URL(url + 'agent');\n if (this.#opts.workerToken) {\n wsUrl.searchParams.append('worker_token', this.#opts.workerToken);\n }\n this.#session = new WebSocket(wsUrl, {\n headers: { authorization: 'Bearer ' + jwt },\n });\n\n try {\n await new Promise((resolve, reject) => {\n this.#session!.on('open', resolve);\n this.#session!.on('error', (error) => reject(error));\n this.#session!.on('close', (code) => reject(`WebSocket returned ${code}`));\n });\n\n retries = 0;\n this.#logger.debug('connected to LiveKit server');\n await this.#runWS(this.#session);\n } catch (e: unknown) {\n if (this.#closed) return;\n if (retries >= this.#opts.maxRetry) {\n throw new WorkerError(\n `failed to connect to LiveKit server (${this.#opts.wsURL}) after ${retries} attempts: ${e}`,\n );\n }\n\n retries++;\n const delay = Math.min(retries * 2, 10);\n\n this.#logger.warn(\n e,\n `failed to connect to LiveKit server (${this.#opts.wsURL}), retrying in ${delay} seconds: (${retries}/${this.#opts.maxRetry})`,\n );\n\n await new Promise((resolve) => setTimeout(resolve, delay * 1000));\n }\n }\n };\n\n await Promise.all([workerWS(), this.#httpServer.run()]);\n this.#close.resolve();\n }\n\n get id(): string {\n return this.#id;\n }\n\n get activeJobs(): RunningJobInfo[] {\n return this.#procPool.processes\n .filter((proc) => proc.runningJob)\n .map((proc) => proc.runningJob!);\n }\n\n /** @throws {@link WorkerError} if worker did not drain in time */\n async drain(timeout?: number) {\n if (this.#draining) {\n return;\n }\n\n this.#logger.debug('draining worker');\n this.#draining = true;\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'updateWorker',\n value: {\n status: WorkerStatus.WS_FULL,\n },\n },\n }),\n );\n\n const joinJobs = async () => {\n return Promise.all(\n this.#procPool.processes.map((proc) => {\n if (!proc.runningJob) {\n proc.close();\n }\n return proc.join();\n }),\n );\n };\n\n let timer: NodeJS.Timeout | undefined;\n if (timeout) {\n timer = setTimeout(() => {\n throw new WorkerError('timed out draining');\n }, timeout);\n }\n await joinJobs().then(() => {\n if (timeout) {\n clearTimeout(timer);\n }\n });\n }\n\n async simulateJob(roomName: string, participantIdentity?: string) {\n const client = new RoomServiceClient(this.#opts.wsURL, this.#opts.apiKey, this.#opts.apiSecret);\n const room = await client.createRoom({ name: roomName });\n let participant: ParticipantInfo | undefined = undefined;\n if (participantIdentity) {\n try {\n // TODO(AJS-269): resolve compatibility issue with node-sdk to remove the forced type casting\n participant = (await client.getParticipant(\n roomName,\n participantIdentity,\n )) as unknown as ParticipantInfo;\n } catch (e) {\n this.#logger.fatal(\n `participant with identity ${participantIdentity} not found in room ${roomName}`,\n );\n throw e;\n }\n }\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'simulateJob',\n value: {\n type: JobType.JT_PUBLISHER,\n room,\n participant,\n },\n },\n }),\n );\n }\n\n async #runWS(ws: WebSocket) {\n let closingWS = false;\n\n const send = (msg: WorkerMessage) => {\n if (closingWS) {\n this.event.off('worker_msg', send);\n return;\n }\n ws.send(msg.toBinary());\n };\n this.event.on('worker_msg', send);\n\n const close = new Promise<void>((resolve) => {\n ws.addEventListener('close', () => {\n closingWS = true;\n if (!this.#closed) {\n this.#logger.error('worker connection closed unexpectedly');\n }\n resolve();\n });\n });\n\n ws.addEventListener('error', (event) => {\n this.#logger.error('worker error:', event.message);\n });\n\n ws.addEventListener('message', (event) => {\n if (event.type !== 'message') {\n this.#logger.warn('unexpected message type: ' + event.type);\n return;\n }\n\n const msg = new ServerMessage();\n msg.fromBinary(event.data as Uint8Array);\n\n // register is the only valid first message, and it is only valid as the\n // first message\n if (this.#connecting && msg.message.case !== 'register') {\n throw new WorkerError('expected register response as first message');\n }\n\n switch (msg.message.case) {\n case 'register': {\n this.#id = msg.message.value.workerId;\n this.#logger\n .child({ id: this.id, server_info: msg.message.value.serverInfo })\n .info('registered worker');\n this.event.emit(\n 'worker_registered',\n msg.message.value.workerId,\n msg.message.value.serverInfo,\n );\n this.#connecting = false;\n break;\n }\n case 'availability': {\n if (!msg.message.value.job) return;\n const task = this.#availability(msg.message.value);\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n break;\n }\n case 'assignment': {\n if (!msg.message.value.job) return;\n const job = msg.message.value.job;\n if (job.id in this.#pending) {\n const task = this.#pending[job.id];\n delete this.#pending[job.id];\n task?.resolve(msg.message.value);\n } else {\n this.#logger.child({ job }).warn('received assignment for unknown job ' + job.id);\n }\n break;\n }\n case 'termination': {\n const task = this.#termination(msg.message.value);\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n break;\n }\n }\n });\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'register',\n value: {\n type: this.#opts.serverType,\n agentName: this.#opts.agentName,\n allowedPermissions: new ParticipantPermission({\n canPublish: this.#opts.permissions.canPublish,\n canSubscribe: this.#opts.permissions.canSubscribe,\n canPublishData: this.#opts.permissions.canPublishData,\n canUpdateMetadata: this.#opts.permissions.canUpdateMetadata,\n hidden: this.#opts.permissions.hidden,\n agent: true,\n }),\n version,\n },\n },\n }),\n );\n\n let currentStatus = WorkerStatus.WS_AVAILABLE;\n const loadMonitor = setInterval(() => {\n if (closingWS) clearInterval(loadMonitor);\n\n const oldStatus = currentStatus;\n this.#opts.loadFunc(this).then((currentLoad: number) => {\n const isFull = currentLoad >= this.#opts.loadThreshold;\n const currentlyAvailable = !isFull;\n currentStatus = currentlyAvailable ? WorkerStatus.WS_AVAILABLE : WorkerStatus.WS_FULL;\n\n if (oldStatus != currentStatus) {\n const extra = { load: currentLoad, loadThreshold: this.#opts.loadThreshold };\n if (isFull) {\n this.#logger.child(extra).info('worker is at full capacity, marking as unavailable');\n } else {\n this.#logger.child(extra).info('worker is below capacity, marking as available');\n }\n }\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'updateWorker',\n value: {\n load: currentLoad,\n status: currentStatus,\n },\n },\n }),\n );\n });\n }, UPDATE_LOAD_INTERVAL);\n\n await close;\n ws.removeAllListeners();\n }\n\n async #availability(msg: AvailabilityRequest) {\n let answered = false;\n\n const onReject = async () => {\n answered = true;\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'availability',\n value: {\n jobId: msg.job!.id,\n available: false,\n },\n },\n }),\n );\n };\n\n const onAccept = async (args: JobAcceptArguments) => {\n answered = true;\n\n this.event.emit(\n 'worker_msg',\n new WorkerMessage({\n message: {\n case: 'availability',\n value: {\n jobId: msg.job!.id,\n available: true,\n participantIdentity: args.identity,\n participantName: args.name,\n participantMetadata: args.metadata,\n participantAttributes: args.attributes,\n },\n },\n }),\n );\n\n this.#pending[req.id] = new PendingAssignment();\n const timer = setTimeout(() => {\n this.#logger.child({ req }).warn(`assignment for job ${req.id} timed out`);\n return;\n }, ASSIGNMENT_TIMEOUT);\n const asgn = await this.#pending[req.id]?.promise.then(async (asgn) => {\n clearTimeout(timer);\n return asgn;\n });\n\n if (asgn) {\n await this.#procPool.launchJob({\n acceptArguments: args,\n job: msg.job!,\n url: asgn.url || this.#opts.wsURL,\n token: asgn.token,\n workerId: this.id,\n });\n } else {\n this.#logger.child({ requestId: req.id }).warn('pending assignment not found');\n }\n };\n\n const req = new JobRequest(msg.job!, onReject, onAccept);\n this.#logger\n .child({ jobId: msg.job?.id, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('received job request');\n\n const jobRequestTask = async () => {\n try {\n await this.#opts.requestFunc(req);\n } catch (e) {\n this.#logger\n .child({ job: msg.job, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('jobRequestFunc failed');\n await onReject();\n }\n\n if (!answered) {\n this.#logger\n .child({ job: msg.job, resuming: msg.resuming, agentName: this.#opts.agentName })\n .info('no answer was given inside the jobRequestFunc, automatically rejecting the job');\n }\n };\n\n const task = jobRequestTask();\n this.#tasks.push(task);\n task.finally(() => {\n const taskIndex = this.#tasks.indexOf(task);\n if (taskIndex !== -1) {\n this.#tasks.splice(taskIndex, 1);\n } else {\n throw new Error(`task ${task} not found in tasks`);\n }\n });\n }\n\n async #termination(msg: JobTermination) {\n const proc = this.#procPool.getByJobId(msg.jobId);\n if (proc === null) {\n // safe to ignore\n return;\n }\n await proc.close();\n }\n\n async close() {\n if (this.#closed) {\n await this.#close.await;\n return;\n }\n\n this.#logger.debug('shutting down worker');\n\n this.#closed = true;\n\n await this.#inferenceExecutor?.close();\n await this.#procPool.close();\n await this.#httpServer.close();\n await Promise.allSettled(this.#tasks);\n\n this.#session?.close();\n await this.#close.await;\n }\n}\n\n/**\n * @deprecated Use {@link AgentServer} instead. This alias is provided for backward compatibility.\n */\nexport const Worker = AgentServer;\n\n/**\n * @deprecated Use {@link ServerOptions} instead. This alias is provided for backward compatibility.\n */\nexport const WorkerOptions = ServerOptions;\n"],"mappings":"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","names":["i","_a","asgn"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livekit/agents",
3
- "version": "1.0.39",
3
+ "version": "1.0.40",
4
4
  "description": "LiveKit Agents - Node.js",
5
5
  "main": "dist/index.js",
6
6
  "require": "dist/index.cjs",
@@ -4,10 +4,10 @@
4
4
  import { type IncomingMessage, type Server, type ServerResponse, createServer } from 'node:http';
5
5
  import { log } from './log.js';
6
6
 
7
- const healthCheck = async (res: ServerResponse) => {
8
- res.writeHead(200);
9
- res.end('OK');
10
- };
7
+ export interface HealthCheckResult {
8
+ healthy: boolean;
9
+ message: string;
10
+ }
11
11
 
12
12
  interface WorkerResponse {
13
13
  agent_name: string;
@@ -23,13 +23,25 @@ export class HTTPServer {
23
23
  app: Server;
24
24
  #logger = log();
25
25
 
26
- constructor(host: string, port: number, workerListener: () => WorkerResponse) {
26
+ constructor(
27
+ host: string,
28
+ port: number,
29
+ healthCheckListener: () => HealthCheckResult,
30
+ workerListener: () => WorkerResponse,
31
+ ) {
27
32
  this.host = host;
28
33
  this.port = port;
29
34
 
30
35
  this.app = createServer((req: IncomingMessage, res: ServerResponse) => {
31
36
  if (req.url === '/') {
32
- healthCheck(res);
37
+ const result = healthCheckListener();
38
+ if (result.healthy) {
39
+ res.writeHead(200);
40
+ res.end(result.message);
41
+ } else {
42
+ res.writeHead(503);
43
+ res.end(result.message);
44
+ }
33
45
  } else if (req.url === '/worker') {
34
46
  res.writeHead(200, { 'Content-Type': 'application/json' });
35
47
  res.end(JSON.stringify(workerListener()));
@@ -59,6 +59,10 @@ export abstract class SupervisedProc {
59
59
  return this.#started;
60
60
  }
61
61
 
62
+ get isAlive(): boolean {
63
+ return this.#started && !this.#closing && !!this.proc?.connected;
64
+ }
65
+
62
66
  get runningJob(): RunningJobInfo | undefined {
63
67
  return this.#runningJob;
64
68
  }
@@ -16,7 +16,7 @@ export const splitSentences = (
16
16
  const starters =
17
17
  /(Mr|Mrs|Ms|Dr|Prof|Capt|Cpt|Lt|He\s|She\s|It\s|They\s|Their\s|Our\s|We\s|But\s|However\s|That\s|This\s|Wherever)/g;
18
18
  const acronyms = /([A-Z][.][A-Z][.](?:[A-Z][.])?)/g;
19
- const websites = /[.](com|net|org|io|gov|edu|me)/g;
19
+ const websites = /(\w+\.)+(com|net|org|io|gov|edu|me)/g;
20
20
  const digits = /([0-9])/g;
21
21
  const dots = /\.{2,}/g;
22
22
 
@@ -27,7 +27,7 @@ export const splitSentences = (
27
27
  }
28
28
 
29
29
  text = text.replaceAll(prefixes, '$1<prd>');
30
- text = text.replaceAll(websites, '<prd>$2');
30
+ text = text.replace(websites, (match) => match.replaceAll('.', '<prd>'));
31
31
  text = text.replaceAll(new RegExp(`${digits.source}[.]${digits.source}`, 'g'), '$1<prd>$2');
32
32
  text = text.replaceAll(dots, (match) => '<prd>'.repeat(match.length));
33
33
  text = text.replaceAll('Ph.D.', 'Ph<prd>D<prd>');
@@ -51,7 +51,7 @@ export const splitSentences = (
51
51
  text = text.replaceAll('."', '".');
52
52
  text = text.replaceAll('!"', '"!');
53
53
  text = text.replaceAll('?"', '"?');
54
- text = text.replaceAll('.', '.<stop>');
54
+ text = text.replace(/\.(?=\s|$)/g, '.<stop>');
55
55
  text = text.replaceAll('?', '?<stop>');
56
56
  text = text.replaceAll('!', '!<stop>');
57
57
  text = text.replaceAll('<prd>', '.');
@@ -13,6 +13,8 @@ const TEXT =
13
13
  'This is a test. Another test. ' +
14
14
  'A short sentence. ' +
15
15
  'A longer sentence that is longer than the previous sentence. ' +
16
+ 'Find additional resources on livekit.com. ' +
17
+ 'Find additional resources on docs.livekit.com. ' +
16
18
  'f(x) = x * 2.54 + 42. ' +
17
19
  'Hey! Hi! Hello! ';
18
20
 
@@ -22,6 +24,8 @@ const EXPECTED_MIN_20 = [
22
24
  'Mr. Theo is testing the sentence tokenizer.',
23
25
  'This is a test. Another test.',
24
26
  'A short sentence. A longer sentence that is longer than the previous sentence.',
27
+ 'Find additional resources on livekit.com.',
28
+ 'Find additional resources on docs.livekit.com.',
25
29
  'f(x) = x * 2.54 + 42.',
26
30
  'Hey! Hi! Hello!',
27
31
  ];
package/src/worker.ts CHANGED
@@ -339,13 +339,35 @@ export class AgentServer {
339
339
  );
340
340
 
341
341
  this.#opts = opts;
342
- this.#httpServer = new HTTPServer(opts.host, opts.port, () => ({
342
+
343
+ const healthCheck = () => {
344
+ // Check if inference executor exists and is not alive
345
+ if (this.#inferenceExecutor && !this.#inferenceExecutor.isAlive) {
346
+ return { healthy: false, message: 'inference process not running' };
347
+ }
348
+
349
+ // Only healthy when fully connected with an active WebSocket
350
+ if (
351
+ this.#closed ||
352
+ this.#connecting ||
353
+ !this.#session ||
354
+ this.#session.readyState !== WebSocket.OPEN
355
+ ) {
356
+ return { healthy: false, message: 'not connected to livekit' };
357
+ }
358
+
359
+ return { healthy: true, message: 'OK' };
360
+ };
361
+
362
+ const getWorkerInfo = () => ({
343
363
  agent_name: opts.agentName,
344
364
  worker_type: JobType[opts.serverType],
345
365
  active_jobs: this.activeJobs.length,
346
366
  sdk_version: version,
347
367
  project_type: PROJECT_TYPE,
348
- }));
368
+ });
369
+
370
+ this.#httpServer = new HTTPServer(opts.host, opts.port, healthCheck, getWorkerInfo);
349
371
  }
350
372
 
351
373
  /** @throws {@link WorkerError} if worker failed to connect or already running */