@livekit/agents 1.0.0-next.4 → 1.0.0-next.6
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/cli.cjs +5 -5
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +5 -5
- package/dist/cli.js.map +1 -1
- package/dist/http_server.cjs +1 -1
- package/dist/http_server.cjs.map +1 -1
- package/dist/http_server.js +1 -1
- package/dist/http_server.js.map +1 -1
- package/dist/ipc/inference_proc_lazy_main.cjs +5 -5
- package/dist/ipc/inference_proc_lazy_main.cjs.map +1 -1
- package/dist/ipc/inference_proc_lazy_main.js +5 -5
- package/dist/ipc/inference_proc_lazy_main.js.map +1 -1
- package/dist/ipc/job_proc_lazy_main.cjs +3 -3
- package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
- package/dist/ipc/job_proc_lazy_main.js +3 -3
- package/dist/ipc/job_proc_lazy_main.js.map +1 -1
- package/dist/worker.cjs +4 -4
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.cts +3 -3
- package/dist/worker.d.ts +3 -3
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +4 -4
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
- package/src/cli.ts +6 -6
- package/src/http_server.ts +1 -1
- package/src/ipc/inference_proc_lazy_main.ts +5 -5
- package/src/ipc/job_proc_lazy_main.ts +3 -3
- package/src/worker.ts +9 -7
package/dist/cli.cjs
CHANGED
|
@@ -40,25 +40,25 @@ const runWorker = async (args) => {
|
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
process.once("SIGINT", async () => {
|
|
43
|
-
logger.
|
|
43
|
+
logger.debug("SIGINT received in CLI");
|
|
44
44
|
process.once("SIGINT", () => {
|
|
45
|
-
|
|
45
|
+
console.log("Force exit (Ctrl+C pressed twice)");
|
|
46
46
|
process.exit(130);
|
|
47
47
|
});
|
|
48
48
|
if (args.production) {
|
|
49
49
|
await worker.drain();
|
|
50
50
|
}
|
|
51
51
|
await worker.close();
|
|
52
|
-
logger.
|
|
52
|
+
logger.debug("worker closed due to SIGINT.");
|
|
53
53
|
process.exit(130);
|
|
54
54
|
});
|
|
55
55
|
process.once("SIGTERM", async () => {
|
|
56
|
-
logger.
|
|
56
|
+
logger.debug("SIGTERM received in CLI.");
|
|
57
57
|
if (args.production) {
|
|
58
58
|
await worker.drain();
|
|
59
59
|
}
|
|
60
60
|
await worker.close();
|
|
61
|
-
logger.
|
|
61
|
+
logger.debug("worker closed due to SIGTERM.");
|
|
62
62
|
process.exit(143);
|
|
63
63
|
});
|
|
64
64
|
try {
|
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../../node_modules/.pnpm/tsup@8.4.0_@microsoft+api-extractor@7.43.7_@types+node@22.15.30__postcss@8.4.38_tsx@4.20.4_typescript@5.4.5/node_modules/tsup/assets/cjs_shims.js"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Command, Option } from 'commander';\nimport type { EventEmitter } from 'node:events';\nimport { initializeLogger, log } from './log.js';\nimport { Plugin } from './plugin.js';\nimport { version } from './version.js';\nimport { Worker, WorkerOptions } from './worker.js';\n\ntype CliArgs = {\n opts: WorkerOptions;\n production: boolean;\n watch: boolean;\n event?: EventEmitter;\n room?: string;\n participantIdentity?: string;\n};\n\nconst runWorker = async (args: CliArgs) => {\n initializeLogger({ pretty: !args.production, level: args.opts.logLevel });\n const logger = log();\n\n // though `production` is defined in WorkerOptions, it will always be overriddden by CLI.\n const { production: _, ...opts } = args.opts; // eslint-disable-line @typescript-eslint/no-unused-vars\n const worker = new Worker(new WorkerOptions({ production: args.production, ...opts }));\n\n if (args.room) {\n worker.event.once('worker_registered', () => {\n logger.info(`connecting to room ${args.room}`);\n worker.simulateJob(args.room!, args.participantIdentity);\n });\n }\n\n process.once('SIGINT', async () => {\n logger.info('SIGINT received in CLI');\n // allow C-c C-c for force interrupt\n process.once('SIGINT', () => {\n logger.info('worker closed forcefully due to SIGINT.');\n process.exit(130); // SIGINT exit code\n });\n if (args.production) {\n await worker.drain();\n }\n await worker.close();\n logger.info('worker closed due to SIGINT.');\n process.exit(130); // SIGINT exit code\n });\n\n process.once('SIGTERM', async () => {\n logger.info('SIGTERM received in CLI.');\n if (args.production) {\n await worker.drain();\n }\n await worker.close();\n logger.info('worker closed due to SIGTERM.');\n process.exit(143); // SIGTERM exit code\n });\n\n try {\n await worker.run();\n } catch {\n logger.fatal('closing worker due to error.');\n process.exit(1);\n }\n};\n\n/**\n * Exposes a CLI for creating a new worker, in development or production mode.\n *\n * @param opts - Options to launch the worker with\n * @example\n * ```\n * if (process.argv[1] === fileURLToPath(import.meta.url)) {\n * cli.runApp(new WorkerOptions({ agent: import.meta.filename }));\n * }\n * ```\n */\nexport const runApp = (opts: WorkerOptions) => {\n const program = new Command()\n .name('agents')\n .description('LiveKit Agents CLI')\n .version(version)\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('info')\n .env('LOG_LEVEL'),\n )\n .addOption(\n new Option('--url <string>', 'LiveKit server or Cloud project websocket URL').env(\n 'LIVEKIT_URL',\n ),\n )\n .addOption(\n new Option('--api-key <string>', \"LiveKit server or Cloud project's API key\").env(\n 'LIVEKIT_API_KEY',\n ),\n )\n .addOption(\n new Option('--api-secret <string>', \"LiveKit server or Cloud project's API secret\").env(\n 'LIVEKIT_API_SECRET',\n ),\n )\n .addOption(\n new Option('--worker-token <string>', 'Internal use only')\n .env('LIVEKIT_WORKER_TOKEN')\n .hideHelp(),\n )\n .action(() => {\n if (\n // do not run CLI if origin file is agents/ipc/job_main.js\n process.argv[1] !== new URL('ipc/job_main.js', import.meta.url).pathname &&\n process.argv.length < 3\n ) {\n program.help();\n }\n });\n\n program\n .command('start')\n .description('Start the worker in production mode')\n .action(() => {\n const options = program.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: true,\n watch: false,\n });\n });\n\n program\n .command('dev')\n .description('Start the worker in development mode')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action(() => {\n const options = program.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: false,\n watch: false,\n });\n });\n\n program\n .command('connect')\n .description('Connect to a specific room')\n .requiredOption('--room <string>', 'Room name to connect to')\n .option('--participant-identity <string>', 'Identity of user to listen to')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action((...[, command]) => {\n const options = command.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: false,\n watch: false,\n room: options.room,\n participantIdentity: options.participantIdentity,\n });\n });\n\n program\n .command('download-files')\n .description('Download plugin dependency files')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action(() => {\n const options = program.optsWithGlobals();\n initializeLogger({ pretty: true, level: options.logLevel });\n const logger = log();\n\n const downloadFiles = async () => {\n for (const plugin of Plugin.registeredPlugins) {\n logger.info(`Downloading files for ${plugin.title}`);\n try {\n await plugin.downloadFiles();\n logger.info(`Finished downloading files for ${plugin.title}`);\n } catch (error) {\n logger.error(`Failed to download files for ${plugin.title}: ${error}`);\n }\n }\n };\n\n downloadFiles()\n .catch((error) => {\n logger.fatal(`Error during file downloads: ${error}`);\n process.exit(1);\n })\n .finally(() => {\n process.exit(0);\n });\n });\n\n program.parse();\n};\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () =>\n typeof document === 'undefined'\n ? new URL(`file:${__filename}`).href\n : (document.currentScript && document.currentScript.src) ||\n new URL('main.js', document.baseURI).href\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACKA,IAAM,mBAAmB,MACvB,OAAO,aAAa,cAChB,IAAI,IAAI,QAAQ,UAAU,EAAE,EAAE,OAC7B,SAAS,iBAAiB,SAAS,cAAc,OAClD,IAAI,IAAI,WAAW,SAAS,OAAO,EAAE;AAEpC,IAAM,gBAAgC,iCAAiB;ADR9D,uBAAgC;AAEhC,iBAAsC;AACtC,oBAAuB;AACvB,qBAAwB;AACxB,oBAAsC;AAWtC,MAAM,YAAY,OAAO,SAAkB;AACzC,mCAAiB,EAAE,QAAQ,CAAC,KAAK,YAAY,OAAO,KAAK,KAAK,SAAS,CAAC;AACxE,QAAM,aAAS,gBAAI;AAGnB,QAAM,EAAE,YAAY,GAAG,GAAG,KAAK,IAAI,KAAK;AACxC,QAAM,SAAS,IAAI,qBAAO,IAAI,4BAAc,EAAE,YAAY,KAAK,YAAY,GAAG,KAAK,CAAC,CAAC;AAErF,MAAI,KAAK,MAAM;AACb,WAAO,MAAM,KAAK,qBAAqB,MAAM;AAC3C,aAAO,KAAK,sBAAsB,KAAK,IAAI,EAAE;AAC7C,aAAO,YAAY,KAAK,MAAO,KAAK,mBAAmB;AAAA,IACzD,CAAC;AAAA,EACH;AAEA,UAAQ,KAAK,UAAU,YAAY;AACjC,WAAO,KAAK,wBAAwB;AAEpC,YAAQ,KAAK,UAAU,MAAM;AAC3B,aAAO,KAAK,yCAAyC;AACrD,cAAQ,KAAK,GAAG;AAAA,IAClB,CAAC;AACD,QAAI,KAAK,YAAY;AACnB,YAAM,OAAO,MAAM;AAAA,IACrB;AACA,UAAM,OAAO,MAAM;AACnB,WAAO,KAAK,8BAA8B;AAC1C,YAAQ,KAAK,GAAG;AAAA,EAClB,CAAC;AAED,UAAQ,KAAK,WAAW,YAAY;AAClC,WAAO,KAAK,0BAA0B;AACtC,QAAI,KAAK,YAAY;AACnB,YAAM,OAAO,MAAM;AAAA,IACrB;AACA,UAAM,OAAO,MAAM;AACnB,WAAO,KAAK,+BAA+B;AAC3C,YAAQ,KAAK,GAAG;AAAA,EAClB,CAAC;AAED,MAAI;AACF,UAAM,OAAO,IAAI;AAAA,EACnB,QAAQ;AACN,WAAO,MAAM,8BAA8B;AAC3C,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAaO,MAAM,SAAS,CAAC,SAAwB;AAC7C,QAAM,UAAU,IAAI,yBAAQ,EACzB,KAAK,QAAQ,EACb,YAAY,oBAAoB,EAChC,QAAQ,sBAAO,EACf;AAAA,IACC,IAAI,wBAAO,uBAAuB,uBAAuB,EACtD,QAAQ,CAAC,SAAS,SAAS,QAAQ,QAAQ,SAAS,OAAO,CAAC,EAC5D,QAAQ,MAAM,EACd,IAAI,WAAW;AAAA,EACpB,EACC;AAAA,IACC,IAAI,wBAAO,kBAAkB,+CAA+C,EAAE;AAAA,MAC5E;AAAA,IACF;AAAA,EACF,EACC;AAAA,IACC,IAAI,wBAAO,sBAAsB,2CAA2C,EAAE;AAAA,MAC5E;AAAA,IACF;AAAA,EACF,EACC;AAAA,IACC,IAAI,wBAAO,yBAAyB,8CAA8C,EAAE;AAAA,MAClF;AAAA,IACF;AAAA,EACF,EACC;AAAA,IACC,IAAI,wBAAO,2BAA2B,mBAAmB,EACtD,IAAI,sBAAsB,EAC1B,SAAS;AAAA,EACd,EACC,OAAO,MAAM;AACZ;AAAA;AAAA,MAEE,QAAQ,KAAK,CAAC,MAAM,IAAI,IAAI,mBAAmB,aAAe,EAAE,YAChE,QAAQ,KAAK,SAAS;AAAA,MACtB;AACA,cAAQ,KAAK;AAAA,IACf;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,OAAO,EACf,YAAY,qCAAqC,EACjD,OAAO,MAAM;AACZ,UAAM,UAAU,QAAQ,gBAAgB;AACxC,SAAK,QAAQ,QAAQ,OAAO,KAAK;AACjC,SAAK,SAAS,QAAQ,UAAU,KAAK;AACrC,SAAK,YAAY,QAAQ,aAAa,KAAK;AAC3C,SAAK,WAAW,QAAQ,YAAY,KAAK;AACzC,SAAK,cAAc,QAAQ,eAAe,KAAK;AAC/C,cAAU;AAAA,MACR;AAAA,MACA,YAAY;AAAA,MACZ,OAAO;AAAA,IACT,CAAC;AAAA,EACH,CAAC;AAEH,UACG,QAAQ,KAAK,EACb,YAAY,sCAAsC,EAClD;AAAA,IACC,IAAI,wBAAO,uBAAuB,uBAAuB,EACtD,QAAQ,CAAC,SAAS,SAAS,QAAQ,QAAQ,SAAS,OAAO,CAAC,EAC5D,QAAQ,OAAO,EACf,IAAI,WAAW;AAAA,EACpB,EACC,OAAO,MAAM;AACZ,UAAM,UAAU,QAAQ,gBAAgB;AACxC,SAAK,QAAQ,QAAQ,OAAO,KAAK;AACjC,SAAK,SAAS,QAAQ,UAAU,KAAK;AACrC,SAAK,YAAY,QAAQ,aAAa,KAAK;AAC3C,SAAK,WAAW,QAAQ,YAAY,KAAK;AACzC,SAAK,cAAc,QAAQ,eAAe,KAAK;AAC/C,cAAU;AAAA,MACR;AAAA,MACA,YAAY;AAAA,MACZ,OAAO;AAAA,IACT,CAAC;AAAA,EACH,CAAC;AAEH,UACG,QAAQ,SAAS,EACjB,YAAY,4BAA4B,EACxC,eAAe,mBAAmB,yBAAyB,EAC3D,OAAO,mCAAmC,+BAA+B,EACzE;AAAA,IACC,IAAI,wBAAO,uBAAuB,uBAAuB,EACtD,QAAQ,CAAC,SAAS,SAAS,QAAQ,QAAQ,SAAS,OAAO,CAAC,EAC5D,QAAQ,OAAO,EACf,IAAI,WAAW;AAAA,EACpB,EACC,OAAO,IAAI,CAAC,EAAE,OAAO,MAAM;AAC1B,UAAM,UAAU,QAAQ,gBAAgB;AACxC,SAAK,QAAQ,QAAQ,OAAO,KAAK;AACjC,SAAK,SAAS,QAAQ,UAAU,KAAK;AACrC,SAAK,YAAY,QAAQ,aAAa,KAAK;AAC3C,SAAK,WAAW,QAAQ,YAAY,KAAK;AACzC,SAAK,cAAc,QAAQ,eAAe,KAAK;AAC/C,cAAU;AAAA,MACR;AAAA,MACA,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,MAAM,QAAQ;AAAA,MACd,qBAAqB,QAAQ;AAAA,IAC/B,CAAC;AAAA,EACH,CAAC;AAEH,UACG,QAAQ,gBAAgB,EACxB,YAAY,kCAAkC,EAC9C;AAAA,IACC,IAAI,wBAAO,uBAAuB,uBAAuB,EACtD,QAAQ,CAAC,SAAS,SAAS,QAAQ,QAAQ,SAAS,OAAO,CAAC,EAC5D,QAAQ,OAAO,EACf,IAAI,WAAW;AAAA,EACpB,EACC,OAAO,MAAM;AACZ,UAAM,UAAU,QAAQ,gBAAgB;AACxC,qCAAiB,EAAE,QAAQ,MAAM,OAAO,QAAQ,SAAS,CAAC;AAC1D,UAAM,aAAS,gBAAI;AAEnB,UAAM,gBAAgB,YAAY;AAChC,iBAAW,UAAU,qBAAO,mBAAmB;AAC7C,eAAO,KAAK,yBAAyB,OAAO,KAAK,EAAE;AACnD,YAAI;AACF,gBAAM,OAAO,cAAc;AAC3B,iBAAO,KAAK,kCAAkC,OAAO,KAAK,EAAE;AAAA,QAC9D,SAAS,OAAO;AACd,iBAAO,MAAM,gCAAgC,OAAO,KAAK,KAAK,KAAK,EAAE;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AAEA,kBAAc,EACX,MAAM,CAAC,UAAU;AAChB,aAAO,MAAM,gCAAgC,KAAK,EAAE;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC,EACA,QAAQ,MAAM;AACb,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC;AAAA,EACL,CAAC;AAEH,UAAQ,MAAM;AAChB;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../../node_modules/.pnpm/tsup@8.4.0_@microsoft+api-extractor@7.43.7_@types+node@22.15.30__postcss@8.4.38_tsx@4.20.4_typescript@5.4.5/node_modules/tsup/assets/cjs_shims.js"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Command, Option } from 'commander';\nimport type { EventEmitter } from 'node:events';\nimport { initializeLogger, log } from './log.js';\nimport { Plugin } from './plugin.js';\nimport { version } from './version.js';\nimport { Worker, WorkerOptions } from './worker.js';\n\ntype CliArgs = {\n opts: WorkerOptions;\n production: boolean;\n watch: boolean;\n event?: EventEmitter;\n room?: string;\n participantIdentity?: string;\n};\n\nconst runWorker = async (args: CliArgs) => {\n initializeLogger({ pretty: !args.production, level: args.opts.logLevel });\n const logger = log();\n\n // though `production` is defined in WorkerOptions, it will always be overridden by CLI.\n const { production: _, ...opts } = args.opts; // eslint-disable-line @typescript-eslint/no-unused-vars\n const worker = new Worker(new WorkerOptions({ production: args.production, ...opts }));\n\n if (args.room) {\n worker.event.once('worker_registered', () => {\n logger.info(`connecting to room ${args.room}`);\n worker.simulateJob(args.room!, args.participantIdentity);\n });\n }\n\n process.once('SIGINT', async () => {\n logger.debug('SIGINT received in CLI');\n // allow C-c C-c for force interrupt\n process.once('SIGINT', () => {\n console.log('Force exit (Ctrl+C pressed twice)');\n process.exit(130); // SIGINT exit code\n });\n if (args.production) {\n await worker.drain();\n }\n await worker.close();\n logger.debug('worker closed due to SIGINT.');\n process.exit(130); // SIGINT exit code\n });\n\n process.once('SIGTERM', async () => {\n logger.debug('SIGTERM received in CLI.');\n if (args.production) {\n await worker.drain();\n }\n await worker.close();\n logger.debug('worker closed due to SIGTERM.');\n process.exit(143); // SIGTERM exit code\n });\n\n try {\n await worker.run();\n } catch {\n logger.fatal('closing worker due to error.');\n process.exit(1);\n }\n};\n\n/**\n * Exposes a CLI for creating a new worker, in development or production mode.\n *\n * @param opts - Options to launch the worker with\n * @example\n * ```\n * if (process.argv[1] === fileURLToPath(import.meta.url)) {\n * cli.runApp(new WorkerOptions({ agent: import.meta.filename }));\n * }\n * ```\n */\nexport const runApp = (opts: WorkerOptions) => {\n const program = new Command()\n .name('agents')\n .description('LiveKit Agents CLI')\n .version(version)\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('info')\n .env('LOG_LEVEL'),\n )\n .addOption(\n new Option('--url <string>', 'LiveKit server or Cloud project websocket URL').env(\n 'LIVEKIT_URL',\n ),\n )\n .addOption(\n new Option('--api-key <string>', \"LiveKit server or Cloud project's API key\").env(\n 'LIVEKIT_API_KEY',\n ),\n )\n .addOption(\n new Option('--api-secret <string>', \"LiveKit server or Cloud project's API secret\").env(\n 'LIVEKIT_API_SECRET',\n ),\n )\n .addOption(\n new Option('--worker-token <string>', 'Internal use only')\n .env('LIVEKIT_WORKER_TOKEN')\n .hideHelp(),\n )\n .action(() => {\n if (\n // do not run CLI if origin file is agents/ipc/job_main.js\n process.argv[1] !== new URL('ipc/job_main.js', import.meta.url).pathname &&\n process.argv.length < 3\n ) {\n program.help();\n }\n });\n\n program\n .command('start')\n .description('Start the worker in production mode')\n .action(() => {\n const options = program.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: true,\n watch: false,\n });\n });\n\n program\n .command('dev')\n .description('Start the worker in development mode')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action(() => {\n const options = program.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: false,\n watch: false,\n });\n });\n\n program\n .command('connect')\n .description('Connect to a specific room')\n .requiredOption('--room <string>', 'Room name to connect to')\n .option('--participant-identity <string>', 'Identity of user to listen to')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action((...[, command]) => {\n const options = command.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: false,\n watch: false,\n room: options.room,\n participantIdentity: options.participantIdentity,\n });\n });\n\n program\n .command('download-files')\n .description('Download plugin dependency files')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action(() => {\n const options = program.optsWithGlobals();\n initializeLogger({ pretty: true, level: options.logLevel });\n const logger = log();\n\n const downloadFiles = async () => {\n for (const plugin of Plugin.registeredPlugins) {\n logger.info(`Downloading files for ${plugin.title}`);\n try {\n await plugin.downloadFiles();\n logger.info(`Finished downloading files for ${plugin.title}`);\n } catch (error) {\n logger.error(`Failed to download files for ${plugin.title}: ${error}`);\n }\n }\n };\n\n downloadFiles()\n .catch((error) => {\n logger.fatal(`Error during file downloads: ${error}`);\n process.exit(1);\n })\n .finally(() => {\n process.exit(0);\n });\n });\n\n program.parse();\n};\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () =>\n typeof document === 'undefined'\n ? new URL(`file:${__filename}`).href\n : (document.currentScript && document.currentScript.src) ||\n new URL('main.js', document.baseURI).href\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
|
@@ -15,25 +15,25 @@ const runWorker = async (args) => {
|
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
17
|
process.once("SIGINT", async () => {
|
|
18
|
-
logger.
|
|
18
|
+
logger.debug("SIGINT received in CLI");
|
|
19
19
|
process.once("SIGINT", () => {
|
|
20
|
-
|
|
20
|
+
console.log("Force exit (Ctrl+C pressed twice)");
|
|
21
21
|
process.exit(130);
|
|
22
22
|
});
|
|
23
23
|
if (args.production) {
|
|
24
24
|
await worker.drain();
|
|
25
25
|
}
|
|
26
26
|
await worker.close();
|
|
27
|
-
logger.
|
|
27
|
+
logger.debug("worker closed due to SIGINT.");
|
|
28
28
|
process.exit(130);
|
|
29
29
|
});
|
|
30
30
|
process.once("SIGTERM", async () => {
|
|
31
|
-
logger.
|
|
31
|
+
logger.debug("SIGTERM received in CLI.");
|
|
32
32
|
if (args.production) {
|
|
33
33
|
await worker.drain();
|
|
34
34
|
}
|
|
35
35
|
await worker.close();
|
|
36
|
-
logger.
|
|
36
|
+
logger.debug("worker closed due to SIGTERM.");
|
|
37
37
|
process.exit(143);
|
|
38
38
|
});
|
|
39
39
|
try {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Command, Option } from 'commander';\nimport type { EventEmitter } from 'node:events';\nimport { initializeLogger, log } from './log.js';\nimport { Plugin } from './plugin.js';\nimport { version } from './version.js';\nimport { Worker, WorkerOptions } from './worker.js';\n\ntype CliArgs = {\n opts: WorkerOptions;\n production: boolean;\n watch: boolean;\n event?: EventEmitter;\n room?: string;\n participantIdentity?: string;\n};\n\nconst runWorker = async (args: CliArgs) => {\n initializeLogger({ pretty: !args.production, level: args.opts.logLevel });\n const logger = log();\n\n // though `production` is defined in WorkerOptions, it will always be overriddden by CLI.\n const { production: _, ...opts } = args.opts; // eslint-disable-line @typescript-eslint/no-unused-vars\n const worker = new Worker(new WorkerOptions({ production: args.production, ...opts }));\n\n if (args.room) {\n worker.event.once('worker_registered', () => {\n logger.info(`connecting to room ${args.room}`);\n worker.simulateJob(args.room!, args.participantIdentity);\n });\n }\n\n process.once('SIGINT', async () => {\n logger.info('SIGINT received in CLI');\n // allow C-c C-c for force interrupt\n process.once('SIGINT', () => {\n logger.info('worker closed forcefully due to SIGINT.');\n process.exit(130); // SIGINT exit code\n });\n if (args.production) {\n await worker.drain();\n }\n await worker.close();\n logger.info('worker closed due to SIGINT.');\n process.exit(130); // SIGINT exit code\n });\n\n process.once('SIGTERM', async () => {\n logger.info('SIGTERM received in CLI.');\n if (args.production) {\n await worker.drain();\n }\n await worker.close();\n logger.info('worker closed due to SIGTERM.');\n process.exit(143); // SIGTERM exit code\n });\n\n try {\n await worker.run();\n } catch {\n logger.fatal('closing worker due to error.');\n process.exit(1);\n }\n};\n\n/**\n * Exposes a CLI for creating a new worker, in development or production mode.\n *\n * @param opts - Options to launch the worker with\n * @example\n * ```\n * if (process.argv[1] === fileURLToPath(import.meta.url)) {\n * cli.runApp(new WorkerOptions({ agent: import.meta.filename }));\n * }\n * ```\n */\nexport const runApp = (opts: WorkerOptions) => {\n const program = new Command()\n .name('agents')\n .description('LiveKit Agents CLI')\n .version(version)\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('info')\n .env('LOG_LEVEL'),\n )\n .addOption(\n new Option('--url <string>', 'LiveKit server or Cloud project websocket URL').env(\n 'LIVEKIT_URL',\n ),\n )\n .addOption(\n new Option('--api-key <string>', \"LiveKit server or Cloud project's API key\").env(\n 'LIVEKIT_API_KEY',\n ),\n )\n .addOption(\n new Option('--api-secret <string>', \"LiveKit server or Cloud project's API secret\").env(\n 'LIVEKIT_API_SECRET',\n ),\n )\n .addOption(\n new Option('--worker-token <string>', 'Internal use only')\n .env('LIVEKIT_WORKER_TOKEN')\n .hideHelp(),\n )\n .action(() => {\n if (\n // do not run CLI if origin file is agents/ipc/job_main.js\n process.argv[1] !== new URL('ipc/job_main.js', import.meta.url).pathname &&\n process.argv.length < 3\n ) {\n program.help();\n }\n });\n\n program\n .command('start')\n .description('Start the worker in production mode')\n .action(() => {\n const options = program.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: true,\n watch: false,\n });\n });\n\n program\n .command('dev')\n .description('Start the worker in development mode')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action(() => {\n const options = program.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: false,\n watch: false,\n });\n });\n\n program\n .command('connect')\n .description('Connect to a specific room')\n .requiredOption('--room <string>', 'Room name to connect to')\n .option('--participant-identity <string>', 'Identity of user to listen to')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action((...[, command]) => {\n const options = command.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: false,\n watch: false,\n room: options.room,\n participantIdentity: options.participantIdentity,\n });\n });\n\n program\n .command('download-files')\n .description('Download plugin dependency files')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action(() => {\n const options = program.optsWithGlobals();\n initializeLogger({ pretty: true, level: options.logLevel });\n const logger = log();\n\n const downloadFiles = async () => {\n for (const plugin of Plugin.registeredPlugins) {\n logger.info(`Downloading files for ${plugin.title}`);\n try {\n await plugin.downloadFiles();\n logger.info(`Finished downloading files for ${plugin.title}`);\n } catch (error) {\n logger.error(`Failed to download files for ${plugin.title}: ${error}`);\n }\n }\n };\n\n downloadFiles()\n .catch((error) => {\n logger.fatal(`Error during file downloads: ${error}`);\n process.exit(1);\n })\n .finally(() => {\n process.exit(0);\n });\n });\n\n program.parse();\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Command, Option } from 'commander';\nimport type { EventEmitter } from 'node:events';\nimport { initializeLogger, log } from './log.js';\nimport { Plugin } from './plugin.js';\nimport { version } from './version.js';\nimport { Worker, WorkerOptions } from './worker.js';\n\ntype CliArgs = {\n opts: WorkerOptions;\n production: boolean;\n watch: boolean;\n event?: EventEmitter;\n room?: string;\n participantIdentity?: string;\n};\n\nconst runWorker = async (args: CliArgs) => {\n initializeLogger({ pretty: !args.production, level: args.opts.logLevel });\n const logger = log();\n\n // though `production` is defined in WorkerOptions, it will always be overridden by CLI.\n const { production: _, ...opts } = args.opts; // eslint-disable-line @typescript-eslint/no-unused-vars\n const worker = new Worker(new WorkerOptions({ production: args.production, ...opts }));\n\n if (args.room) {\n worker.event.once('worker_registered', () => {\n logger.info(`connecting to room ${args.room}`);\n worker.simulateJob(args.room!, args.participantIdentity);\n });\n }\n\n process.once('SIGINT', async () => {\n logger.debug('SIGINT received in CLI');\n // allow C-c C-c for force interrupt\n process.once('SIGINT', () => {\n console.log('Force exit (Ctrl+C pressed twice)');\n process.exit(130); // SIGINT exit code\n });\n if (args.production) {\n await worker.drain();\n }\n await worker.close();\n logger.debug('worker closed due to SIGINT.');\n process.exit(130); // SIGINT exit code\n });\n\n process.once('SIGTERM', async () => {\n logger.debug('SIGTERM received in CLI.');\n if (args.production) {\n await worker.drain();\n }\n await worker.close();\n logger.debug('worker closed due to SIGTERM.');\n process.exit(143); // SIGTERM exit code\n });\n\n try {\n await worker.run();\n } catch {\n logger.fatal('closing worker due to error.');\n process.exit(1);\n }\n};\n\n/**\n * Exposes a CLI for creating a new worker, in development or production mode.\n *\n * @param opts - Options to launch the worker with\n * @example\n * ```\n * if (process.argv[1] === fileURLToPath(import.meta.url)) {\n * cli.runApp(new WorkerOptions({ agent: import.meta.filename }));\n * }\n * ```\n */\nexport const runApp = (opts: WorkerOptions) => {\n const program = new Command()\n .name('agents')\n .description('LiveKit Agents CLI')\n .version(version)\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('info')\n .env('LOG_LEVEL'),\n )\n .addOption(\n new Option('--url <string>', 'LiveKit server or Cloud project websocket URL').env(\n 'LIVEKIT_URL',\n ),\n )\n .addOption(\n new Option('--api-key <string>', \"LiveKit server or Cloud project's API key\").env(\n 'LIVEKIT_API_KEY',\n ),\n )\n .addOption(\n new Option('--api-secret <string>', \"LiveKit server or Cloud project's API secret\").env(\n 'LIVEKIT_API_SECRET',\n ),\n )\n .addOption(\n new Option('--worker-token <string>', 'Internal use only')\n .env('LIVEKIT_WORKER_TOKEN')\n .hideHelp(),\n )\n .action(() => {\n if (\n // do not run CLI if origin file is agents/ipc/job_main.js\n process.argv[1] !== new URL('ipc/job_main.js', import.meta.url).pathname &&\n process.argv.length < 3\n ) {\n program.help();\n }\n });\n\n program\n .command('start')\n .description('Start the worker in production mode')\n .action(() => {\n const options = program.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: true,\n watch: false,\n });\n });\n\n program\n .command('dev')\n .description('Start the worker in development mode')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action(() => {\n const options = program.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: false,\n watch: false,\n });\n });\n\n program\n .command('connect')\n .description('Connect to a specific room')\n .requiredOption('--room <string>', 'Room name to connect to')\n .option('--participant-identity <string>', 'Identity of user to listen to')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action((...[, command]) => {\n const options = command.optsWithGlobals();\n opts.wsURL = options.url || opts.wsURL;\n opts.apiKey = options.apiKey || opts.apiKey;\n opts.apiSecret = options.apiSecret || opts.apiSecret;\n opts.logLevel = options.logLevel || opts.logLevel;\n opts.workerToken = options.workerToken || opts.workerToken;\n runWorker({\n opts,\n production: false,\n watch: false,\n room: options.room,\n participantIdentity: options.participantIdentity,\n });\n });\n\n program\n .command('download-files')\n .description('Download plugin dependency files')\n .addOption(\n new Option('--log-level <level>', 'Set the logging level')\n .choices(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n .default('debug')\n .env('LOG_LEVEL'),\n )\n .action(() => {\n const options = program.optsWithGlobals();\n initializeLogger({ pretty: true, level: options.logLevel });\n const logger = log();\n\n const downloadFiles = async () => {\n for (const plugin of Plugin.registeredPlugins) {\n logger.info(`Downloading files for ${plugin.title}`);\n try {\n await plugin.downloadFiles();\n logger.info(`Finished downloading files for ${plugin.title}`);\n } catch (error) {\n logger.error(`Failed to download files for ${plugin.title}: ${error}`);\n }\n }\n };\n\n downloadFiles()\n .catch((error) => {\n logger.fatal(`Error during file downloads: ${error}`);\n process.exit(1);\n })\n .finally(() => {\n process.exit(0);\n });\n });\n\n program.parse();\n};\n"],"mappings":"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","names":[]}
|
package/dist/http_server.cjs
CHANGED
|
@@ -39,7 +39,7 @@ class HTTPServer {
|
|
|
39
39
|
if (req.url === "/") {
|
|
40
40
|
healthCheck(res);
|
|
41
41
|
} else if (req.url === "/worker") {
|
|
42
|
-
res.writeHead(200, { "
|
|
42
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
43
43
|
res.end(JSON.stringify(workerListener()));
|
|
44
44
|
} else {
|
|
45
45
|
res.writeHead(404);
|
package/dist/http_server.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/http_server.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { type IncomingMessage, type Server, type ServerResponse, createServer } from 'node:http';\nimport { log } from './log.js';\n\nconst healthCheck = async (res: ServerResponse) => {\n res.writeHead(200);\n res.end('OK');\n};\n\ninterface WorkerResponse {\n agent_name: string;\n worker_type: string;\n active_jobs: number;\n sdk_version: string;\n project_type: string;\n}\n\nexport class HTTPServer {\n host: string;\n port: number;\n app: Server;\n #logger = log();\n\n constructor(host: string, port: number, workerListener: () => WorkerResponse) {\n this.host = host;\n this.port = port;\n\n this.app = createServer((req: IncomingMessage, res: ServerResponse) => {\n if (req.url === '/') {\n healthCheck(res);\n } else if (req.url === '/worker') {\n res.writeHead(200, { '
|
|
1
|
+
{"version":3,"sources":["../src/http_server.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { type IncomingMessage, type Server, type ServerResponse, createServer } from 'node:http';\nimport { log } from './log.js';\n\nconst healthCheck = async (res: ServerResponse) => {\n res.writeHead(200);\n res.end('OK');\n};\n\ninterface WorkerResponse {\n agent_name: string;\n worker_type: string;\n active_jobs: number;\n sdk_version: string;\n project_type: string;\n}\n\nexport class HTTPServer {\n host: string;\n port: number;\n app: Server;\n #logger = log();\n\n constructor(host: string, port: number, workerListener: () => WorkerResponse) {\n this.host = host;\n this.port = port;\n\n this.app = createServer((req: IncomingMessage, res: ServerResponse) => {\n if (req.url === '/') {\n healthCheck(res);\n } else if (req.url === '/worker') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(workerListener()));\n } else {\n res.writeHead(404);\n res.end('not found');\n }\n });\n }\n\n async run(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.app.listen(this.port, this.host, (err?: Error) => {\n if (err) reject(err);\n const address = this.app.address();\n if (typeof address! !== 'string') {\n this.#logger.info(`Server is listening on port ${address!.port}`);\n }\n resolve();\n });\n });\n }\n\n async close(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.app.close((err?: Error) => {\n if (err) reject(err);\n resolve();\n });\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,uBAAqF;AACrF,iBAAoB;AAEpB,MAAM,cAAc,OAAO,QAAwB;AACjD,MAAI,UAAU,GAAG;AACjB,MAAI,IAAI,IAAI;AACd;AAUO,MAAM,WAAW;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAU,gBAAI;AAAA,EAEd,YAAY,MAAc,MAAc,gBAAsC;AAC5E,SAAK,OAAO;AACZ,SAAK,OAAO;AAEZ,SAAK,UAAM,+BAAa,CAAC,KAAsB,QAAwB;AACrE,UAAI,IAAI,QAAQ,KAAK;AACnB,oBAAY,GAAG;AAAA,MACjB,WAAW,IAAI,QAAQ,WAAW;AAChC,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,YAAI,IAAI,KAAK,UAAU,eAAe,CAAC,CAAC;AAAA,MAC1C,OAAO;AACL,YAAI,UAAU,GAAG;AACjB,YAAI,IAAI,WAAW;AAAA,MACrB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAqB;AACzB,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,WAAK,IAAI,OAAO,KAAK,MAAM,KAAK,MAAM,CAAC,QAAgB;AACrD,YAAI,IAAK,QAAO,GAAG;AACnB,cAAM,UAAU,KAAK,IAAI,QAAQ;AACjC,YAAI,OAAO,YAAa,UAAU;AAChC,eAAK,QAAQ,KAAK,+BAA+B,QAAS,IAAI,EAAE;AAAA,QAClE;AACA,gBAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,QAAuB;AAC3B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,WAAK,IAAI,MAAM,CAAC,QAAgB;AAC9B,YAAI,IAAK,QAAO,GAAG;AACnB,gBAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;","names":[]}
|
package/dist/http_server.js
CHANGED
|
@@ -16,7 +16,7 @@ class HTTPServer {
|
|
|
16
16
|
if (req.url === "/") {
|
|
17
17
|
healthCheck(res);
|
|
18
18
|
} else if (req.url === "/worker") {
|
|
19
|
-
res.writeHead(200, { "
|
|
19
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
20
20
|
res.end(JSON.stringify(workerListener()));
|
|
21
21
|
} else {
|
|
22
22
|
res.writeHead(404);
|
package/dist/http_server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/http_server.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { type IncomingMessage, type Server, type ServerResponse, createServer } from 'node:http';\nimport { log } from './log.js';\n\nconst healthCheck = async (res: ServerResponse) => {\n res.writeHead(200);\n res.end('OK');\n};\n\ninterface WorkerResponse {\n agent_name: string;\n worker_type: string;\n active_jobs: number;\n sdk_version: string;\n project_type: string;\n}\n\nexport class HTTPServer {\n host: string;\n port: number;\n app: Server;\n #logger = log();\n\n constructor(host: string, port: number, workerListener: () => WorkerResponse) {\n this.host = host;\n this.port = port;\n\n this.app = createServer((req: IncomingMessage, res: ServerResponse) => {\n if (req.url === '/') {\n healthCheck(res);\n } else if (req.url === '/worker') {\n res.writeHead(200, { '
|
|
1
|
+
{"version":3,"sources":["../src/http_server.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { type IncomingMessage, type Server, type ServerResponse, createServer } from 'node:http';\nimport { log } from './log.js';\n\nconst healthCheck = async (res: ServerResponse) => {\n res.writeHead(200);\n res.end('OK');\n};\n\ninterface WorkerResponse {\n agent_name: string;\n worker_type: string;\n active_jobs: number;\n sdk_version: string;\n project_type: string;\n}\n\nexport class HTTPServer {\n host: string;\n port: number;\n app: Server;\n #logger = log();\n\n constructor(host: string, port: number, workerListener: () => WorkerResponse) {\n this.host = host;\n this.port = port;\n\n this.app = createServer((req: IncomingMessage, res: ServerResponse) => {\n if (req.url === '/') {\n healthCheck(res);\n } else if (req.url === '/worker') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(workerListener()));\n } else {\n res.writeHead(404);\n res.end('not found');\n }\n });\n }\n\n async run(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.app.listen(this.port, this.host, (err?: Error) => {\n if (err) reject(err);\n const address = this.app.address();\n if (typeof address! !== 'string') {\n this.#logger.info(`Server is listening on port ${address!.port}`);\n }\n resolve();\n });\n });\n }\n\n async close(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.app.close((err?: Error) => {\n if (err) reject(err);\n resolve();\n });\n });\n }\n}\n"],"mappings":"AAGA,SAAiE,oBAAoB;AACrF,SAAS,WAAW;AAEpB,MAAM,cAAc,OAAO,QAAwB;AACjD,MAAI,UAAU,GAAG;AACjB,MAAI,IAAI,IAAI;AACd;AAUO,MAAM,WAAW;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU,IAAI;AAAA,EAEd,YAAY,MAAc,MAAc,gBAAsC;AAC5E,SAAK,OAAO;AACZ,SAAK,OAAO;AAEZ,SAAK,MAAM,aAAa,CAAC,KAAsB,QAAwB;AACrE,UAAI,IAAI,QAAQ,KAAK;AACnB,oBAAY,GAAG;AAAA,MACjB,WAAW,IAAI,QAAQ,WAAW;AAChC,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,YAAI,IAAI,KAAK,UAAU,eAAe,CAAC,CAAC;AAAA,MAC1C,OAAO;AACL,YAAI,UAAU,GAAG;AACjB,YAAI,IAAI,WAAW;AAAA,MACrB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAqB;AACzB,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,WAAK,IAAI,OAAO,KAAK,MAAM,KAAK,MAAM,CAAC,QAAgB;AACrD,YAAI,IAAK,QAAO,GAAG;AACnB,cAAM,UAAU,KAAK,IAAI,QAAQ;AACjC,YAAI,OAAO,YAAa,UAAU;AAChC,eAAK,QAAQ,KAAK,+BAA+B,QAAS,IAAI,EAAE;AAAA,QAClE;AACA,gBAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,QAAuB;AAC3B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,WAAK,IAAI,MAAM,CAAC,QAAgB;AAC9B,YAAI,IAAK,QAAO,GAAG;AACnB,gBAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;","names":[]}
|
|
@@ -7,10 +7,10 @@ const ORPHANED_TIMEOUT = 15 * 1e3;
|
|
|
7
7
|
if (process.send) {
|
|
8
8
|
const join = new import_utils.Future();
|
|
9
9
|
process.on("SIGINT", () => {
|
|
10
|
-
logger.
|
|
10
|
+
logger.debug("SIGINT received in inference proc");
|
|
11
11
|
});
|
|
12
12
|
process.on("SIGTERM", () => {
|
|
13
|
-
logger.
|
|
13
|
+
logger.debug("SIGTERM received in inference proc");
|
|
14
14
|
});
|
|
15
15
|
await (0, import_node_events.once)(process, "message").then(([msg]) => {
|
|
16
16
|
msg = msg;
|
|
@@ -62,11 +62,11 @@ const ORPHANED_TIMEOUT = 15 * 1e3;
|
|
|
62
62
|
});
|
|
63
63
|
break;
|
|
64
64
|
case "shutdownRequest":
|
|
65
|
-
logger.
|
|
65
|
+
logger.debug("inference process received shutdown request");
|
|
66
66
|
clearTimeout(orphanedTimeout);
|
|
67
67
|
process.off("message", messageHandler);
|
|
68
68
|
Promise.all(Object.values(runners).map((r) => r.close())).then(() => {
|
|
69
|
-
logger.
|
|
69
|
+
logger.debug("Inference runners closed");
|
|
70
70
|
process.send({ case: "done" });
|
|
71
71
|
join.resolve();
|
|
72
72
|
}).catch((err) => {
|
|
@@ -79,7 +79,7 @@ const ORPHANED_TIMEOUT = 15 * 1e3;
|
|
|
79
79
|
};
|
|
80
80
|
process.on("message", messageHandler);
|
|
81
81
|
await join.await;
|
|
82
|
-
logger.
|
|
82
|
+
logger.debug("Inference process shutdown");
|
|
83
83
|
return process.exitCode;
|
|
84
84
|
}
|
|
85
85
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ipc/inference_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { once } from 'node:events';\nimport type { InferenceRunner } from '../inference_runner.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future } from '../utils.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.
|
|
1
|
+
{"version":3,"sources":["../../src/ipc/inference_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { once } from 'node:events';\nimport type { InferenceRunner } from '../inference_runner.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future } from '../utils.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.debug('SIGINT received in inference proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.debug('SIGTERM received in inference proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const logger = log().child({ pid: process.pid });\n\n const runners: { [id: string]: InferenceRunner } = await Promise.all(\n Object.entries(JSON.parse(process.argv[2]!)).map(async ([k, v]) => {\n return [k, await import(v as string).then((m) => new m.default())];\n }),\n ).then(Object.fromEntries);\n\n await Promise.all(\n Object.entries(runners).map(async ([runner, v]) => {\n logger.child({ runner }).debug('initializing inference runner');\n await v.initialize();\n }),\n );\n logger.debug('all inference runners initialized');\n process.send({ case: 'initializeResponse' });\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('inference process orphaned, shutting down.');\n process.exit();\n }, ORPHANED_TIMEOUT);\n\n const handleInferenceRequest = async ({\n method,\n requestId,\n data,\n }: {\n method: string;\n requestId: string;\n data: unknown;\n }) => {\n if (!runners[method]) {\n logger.child({ method }).warn('unknown inference method');\n }\n\n try {\n const resp = await runners[method]!.run(data);\n process.send!({ case: 'inferenceResponse', value: { requestId, data: resp } });\n } catch (error) {\n process.send!({ case: 'inferenceResponse', value: { requestId, error } });\n }\n };\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest':\n orphanedTimeout.refresh();\n process.send!({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n case 'shutdownRequest':\n logger.debug('inference process received shutdown request');\n clearTimeout(orphanedTimeout);\n // Remove our message handler to stop processing new messages\n process.off('message', messageHandler);\n Promise.all(Object.values(runners).map((r) => r.close()))\n .then(() => {\n logger.debug('Inference runners closed');\n process.send!({ case: 'done' });\n join.resolve();\n })\n .catch((err) => {\n logger.error('Error closing inference runners:', err);\n });\n break;\n case 'inferenceRequest':\n handleInferenceRequest(msg.value);\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n logger.debug('Inference process shutdown');\n\n return process.exitCode;\n }\n})();\n"],"mappings":"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","names":[]}
|
|
@@ -6,10 +6,10 @@ const ORPHANED_TIMEOUT = 15 * 1e3;
|
|
|
6
6
|
if (process.send) {
|
|
7
7
|
const join = new Future();
|
|
8
8
|
process.on("SIGINT", () => {
|
|
9
|
-
logger.
|
|
9
|
+
logger.debug("SIGINT received in inference proc");
|
|
10
10
|
});
|
|
11
11
|
process.on("SIGTERM", () => {
|
|
12
|
-
logger.
|
|
12
|
+
logger.debug("SIGTERM received in inference proc");
|
|
13
13
|
});
|
|
14
14
|
await once(process, "message").then(([msg]) => {
|
|
15
15
|
msg = msg;
|
|
@@ -61,11 +61,11 @@ const ORPHANED_TIMEOUT = 15 * 1e3;
|
|
|
61
61
|
});
|
|
62
62
|
break;
|
|
63
63
|
case "shutdownRequest":
|
|
64
|
-
logger.
|
|
64
|
+
logger.debug("inference process received shutdown request");
|
|
65
65
|
clearTimeout(orphanedTimeout);
|
|
66
66
|
process.off("message", messageHandler);
|
|
67
67
|
Promise.all(Object.values(runners).map((r) => r.close())).then(() => {
|
|
68
|
-
logger.
|
|
68
|
+
logger.debug("Inference runners closed");
|
|
69
69
|
process.send({ case: "done" });
|
|
70
70
|
join.resolve();
|
|
71
71
|
}).catch((err) => {
|
|
@@ -78,7 +78,7 @@ const ORPHANED_TIMEOUT = 15 * 1e3;
|
|
|
78
78
|
};
|
|
79
79
|
process.on("message", messageHandler);
|
|
80
80
|
await join.await;
|
|
81
|
-
logger.
|
|
81
|
+
logger.debug("Inference process shutdown");
|
|
82
82
|
return process.exitCode;
|
|
83
83
|
}
|
|
84
84
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ipc/inference_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { once } from 'node:events';\nimport type { InferenceRunner } from '../inference_runner.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future } from '../utils.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.
|
|
1
|
+
{"version":3,"sources":["../../src/ipc/inference_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { once } from 'node:events';\nimport type { InferenceRunner } from '../inference_runner.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future } from '../utils.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.debug('SIGINT received in inference proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.debug('SIGTERM received in inference proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const logger = log().child({ pid: process.pid });\n\n const runners: { [id: string]: InferenceRunner } = await Promise.all(\n Object.entries(JSON.parse(process.argv[2]!)).map(async ([k, v]) => {\n return [k, await import(v as string).then((m) => new m.default())];\n }),\n ).then(Object.fromEntries);\n\n await Promise.all(\n Object.entries(runners).map(async ([runner, v]) => {\n logger.child({ runner }).debug('initializing inference runner');\n await v.initialize();\n }),\n );\n logger.debug('all inference runners initialized');\n process.send({ case: 'initializeResponse' });\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('inference process orphaned, shutting down.');\n process.exit();\n }, ORPHANED_TIMEOUT);\n\n const handleInferenceRequest = async ({\n method,\n requestId,\n data,\n }: {\n method: string;\n requestId: string;\n data: unknown;\n }) => {\n if (!runners[method]) {\n logger.child({ method }).warn('unknown inference method');\n }\n\n try {\n const resp = await runners[method]!.run(data);\n process.send!({ case: 'inferenceResponse', value: { requestId, data: resp } });\n } catch (error) {\n process.send!({ case: 'inferenceResponse', value: { requestId, error } });\n }\n };\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest':\n orphanedTimeout.refresh();\n process.send!({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n case 'shutdownRequest':\n logger.debug('inference process received shutdown request');\n clearTimeout(orphanedTimeout);\n // Remove our message handler to stop processing new messages\n process.off('message', messageHandler);\n Promise.all(Object.values(runners).map((r) => r.close()))\n .then(() => {\n logger.debug('Inference runners closed');\n process.send!({ case: 'done' });\n join.resolve();\n })\n .catch((err) => {\n logger.error('Error closing inference runners:', err);\n });\n break;\n case 'inferenceRequest':\n handleInferenceRequest(msg.value);\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n logger.debug('Inference process shutdown');\n\n return process.exitCode;\n }\n})();\n"],"mappings":"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","names":[]}
|
|
@@ -108,10 +108,10 @@ const startJob = (proc, func, info, closeEvent, logger, joinFuture) => {
|
|
|
108
108
|
agent.prewarm = import_worker.defaultInitializeProcessFunc;
|
|
109
109
|
}
|
|
110
110
|
process.on("SIGINT", () => {
|
|
111
|
-
logger.
|
|
111
|
+
logger.debug("SIGINT received in job proc");
|
|
112
112
|
});
|
|
113
113
|
process.on("SIGTERM", () => {
|
|
114
|
-
logger.
|
|
114
|
+
logger.debug("SIGTERM received in job proc");
|
|
115
115
|
});
|
|
116
116
|
await (0, import_node_events.once)(process, "message").then(([msg]) => {
|
|
117
117
|
msg = msg;
|
|
@@ -166,7 +166,7 @@ const startJob = (proc, func, info, closeEvent, logger, joinFuture) => {
|
|
|
166
166
|
};
|
|
167
167
|
process.on("message", messageHandler);
|
|
168
168
|
await join.await;
|
|
169
|
-
logger.
|
|
169
|
+
logger.debug("Job process shutdown");
|
|
170
170
|
process.exit(0);
|
|
171
171
|
}
|
|
172
172
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ipc/job_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Room, RoomEvent } from '@livekit/rtc-node';\nimport { randomUUID } from 'node:crypto';\nimport { EventEmitter, once } from 'node:events';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from 'pino';\nimport { type Agent, isAgent } from '../generator.js';\nimport { CurrentJobContext, JobContext, JobProcess, type RunningJobInfo } from '../job.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future } from '../utils.js';\nimport { defaultInitializeProcessFunc } from '../worker.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\ntype JobTask = {\n ctx: JobContext;\n task: Promise<void>;\n};\n\nclass PendingInference {\n promise = new Promise<{ requestId: string; data: unknown; error?: Error }>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: { requestId: string; data: unknown; error?: Error }) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\nclass InfClient implements InferenceExecutor {\n #requests: { [id: string]: PendingInference } = {};\n\n constructor() {\n process.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceResponse':\n const fut = this.#requests[msg.value.requestId];\n delete this.#requests[msg.value.requestId];\n if (!fut) {\n log().child({ resp: msg.value }).warn('received unexpected inference response');\n return;\n }\n fut.resolve(msg.value);\n break;\n }\n });\n }\n\n async doInference(method: string, data: unknown): Promise<unknown> {\n const requestId = 'inference_job_' + randomUUID;\n process.send!({ case: 'inferenceRequest', value: { requestId, method, data } });\n this.#requests[requestId] = new PendingInference();\n const resp = await this.#requests[requestId]!.promise;\n if (resp.error) {\n throw new Error(`inference of ${method} failed: ${resp.error.message}`);\n }\n return resp.data;\n }\n}\n\nconst startJob = (\n proc: JobProcess,\n func: (ctx: JobContext) => Promise<void>,\n info: RunningJobInfo,\n closeEvent: EventEmitter,\n logger: Logger,\n joinFuture: Future,\n): JobTask => {\n let connect = false;\n let shutdown = false;\n\n const room = new Room();\n room.on(RoomEvent.Disconnected, () => {\n if (!shutdown) {\n closeEvent.emit('close', false);\n }\n });\n\n const onConnect = () => {\n connect = true;\n };\n const onShutdown = (reason: string) => {\n shutdown = true;\n closeEvent.emit('close', true, reason);\n };\n\n const ctx = new JobContext(proc, info, room, onConnect, onShutdown, new InfClient());\n new CurrentJobContext(ctx);\n\n const task = new Promise<void>(async () => {\n const unconnectedTimeout = setTimeout(() => {\n if (!(connect || shutdown)) {\n logger.warn(\n 'room not connect after job_entry was called after 10 seconds, ',\n 'did you forget to call ctx.connect()?',\n );\n }\n }, 10000);\n func(ctx).finally(() => clearTimeout(unconnectedTimeout));\n\n await once(closeEvent, 'close').then((close) => {\n logger.debug('shutting down');\n shutdown = true;\n process.send!({ case: 'exiting', value: { reason: close[1] } });\n });\n\n await room.disconnect();\n logger.debug('disconnected from room');\n\n const shutdownTasks = [];\n for (const callback of ctx.shutdownCallbacks) {\n shutdownTasks.push(callback());\n }\n await Promise.all(shutdownTasks).catch((error) =>\n logger.error('error while shutting down the job', error),\n );\n\n process.send!({ case: 'done' });\n logger.info('job completed.');\n joinFuture.resolve();\n });\n\n return { ctx, task };\n};\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // process.argv:\n // [0] `node'\n // [1] import.meta.filename\n // [2] import.meta.filename of function containing entry file\n const moduleFile = process.argv[2];\n const agent: Agent = await import(pathToFileURL(moduleFile!).pathname).then((module) => {\n const agent = module.default;\n if (agent === undefined || !isAgent(agent)) {\n throw new Error(`Unable to load agent: Missing or invalid default export in ${moduleFile}`);\n }\n return agent;\n });\n if (!agent.prewarm) {\n agent.prewarm = defaultInitializeProcessFunc;\n }\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.info('SIGINT received in job proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.info('SIGTERM received in job proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const proc = new JobProcess();\n let logger = log().child({ pid: proc.pid });\n\n process.on('unhandledRejection', (reason) => {\n logger.error(reason);\n });\n\n logger.debug('initializing job runner');\n agent.prewarm(proc);\n logger.debug('job runner initialized');\n process.send({ case: 'initializeResponse' });\n\n let job: JobTask | undefined = undefined;\n const closeEvent = new EventEmitter();\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('job process orphaned, shutting down.');\n join.resolve();\n }, ORPHANED_TIMEOUT);\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest': {\n orphanedTimeout.refresh();\n process.send!({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n }\n case 'startJobRequest': {\n if (job) {\n throw new Error('job task already running');\n }\n\n logger = logger.child({ jobID: msg.value.runningJob.job.id });\n\n job = startJob(proc, agent.entry, msg.value.runningJob, closeEvent, logger, join);\n logger.debug('job started');\n break;\n }\n case 'shutdownRequest': {\n if (!job) {\n join.resolve();\n }\n closeEvent.emit('close', 'shutdownRequest');\n clearTimeout(orphanedTimeout);\n process.off('message', messageHandler);\n }\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n logger.info('Job process shutdown');\n process.exit(0);\n }\n})();\n"],"mappings":"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","names":["module","agent"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ipc/job_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Room, RoomEvent } from '@livekit/rtc-node';\nimport { randomUUID } from 'node:crypto';\nimport { EventEmitter, once } from 'node:events';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from 'pino';\nimport { type Agent, isAgent } from '../generator.js';\nimport { CurrentJobContext, JobContext, JobProcess, type RunningJobInfo } from '../job.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future } from '../utils.js';\nimport { defaultInitializeProcessFunc } from '../worker.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\ntype JobTask = {\n ctx: JobContext;\n task: Promise<void>;\n};\n\nclass PendingInference {\n promise = new Promise<{ requestId: string; data: unknown; error?: Error }>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: { requestId: string; data: unknown; error?: Error }) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\nclass InfClient implements InferenceExecutor {\n #requests: { [id: string]: PendingInference } = {};\n\n constructor() {\n process.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceResponse':\n const fut = this.#requests[msg.value.requestId];\n delete this.#requests[msg.value.requestId];\n if (!fut) {\n log().child({ resp: msg.value }).warn('received unexpected inference response');\n return;\n }\n fut.resolve(msg.value);\n break;\n }\n });\n }\n\n async doInference(method: string, data: unknown): Promise<unknown> {\n const requestId = 'inference_job_' + randomUUID;\n process.send!({ case: 'inferenceRequest', value: { requestId, method, data } });\n this.#requests[requestId] = new PendingInference();\n const resp = await this.#requests[requestId]!.promise;\n if (resp.error) {\n throw new Error(`inference of ${method} failed: ${resp.error.message}`);\n }\n return resp.data;\n }\n}\n\nconst startJob = (\n proc: JobProcess,\n func: (ctx: JobContext) => Promise<void>,\n info: RunningJobInfo,\n closeEvent: EventEmitter,\n logger: Logger,\n joinFuture: Future,\n): JobTask => {\n let connect = false;\n let shutdown = false;\n\n const room = new Room();\n room.on(RoomEvent.Disconnected, () => {\n if (!shutdown) {\n closeEvent.emit('close', false);\n }\n });\n\n const onConnect = () => {\n connect = true;\n };\n const onShutdown = (reason: string) => {\n shutdown = true;\n closeEvent.emit('close', true, reason);\n };\n\n const ctx = new JobContext(proc, info, room, onConnect, onShutdown, new InfClient());\n new CurrentJobContext(ctx);\n\n const task = new Promise<void>(async () => {\n const unconnectedTimeout = setTimeout(() => {\n if (!(connect || shutdown)) {\n logger.warn(\n 'room not connect after job_entry was called after 10 seconds, ',\n 'did you forget to call ctx.connect()?',\n );\n }\n }, 10000);\n func(ctx).finally(() => clearTimeout(unconnectedTimeout));\n\n await once(closeEvent, 'close').then((close) => {\n logger.debug('shutting down');\n shutdown = true;\n process.send!({ case: 'exiting', value: { reason: close[1] } });\n });\n\n await room.disconnect();\n logger.debug('disconnected from room');\n\n const shutdownTasks = [];\n for (const callback of ctx.shutdownCallbacks) {\n shutdownTasks.push(callback());\n }\n await Promise.all(shutdownTasks).catch((error) =>\n logger.error('error while shutting down the job', error),\n );\n\n process.send!({ case: 'done' });\n logger.info('job completed.');\n joinFuture.resolve();\n });\n\n return { ctx, task };\n};\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // process.argv:\n // [0] `node'\n // [1] import.meta.filename\n // [2] import.meta.filename of function containing entry file\n const moduleFile = process.argv[2];\n const agent: Agent = await import(pathToFileURL(moduleFile!).pathname).then((module) => {\n const agent = module.default;\n if (agent === undefined || !isAgent(agent)) {\n throw new Error(`Unable to load agent: Missing or invalid default export in ${moduleFile}`);\n }\n return agent;\n });\n if (!agent.prewarm) {\n agent.prewarm = defaultInitializeProcessFunc;\n }\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.debug('SIGINT received in job proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.debug('SIGTERM received in job proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const proc = new JobProcess();\n let logger = log().child({ pid: proc.pid });\n\n process.on('unhandledRejection', (reason) => {\n logger.error(reason);\n });\n\n logger.debug('initializing job runner');\n agent.prewarm(proc);\n logger.debug('job runner initialized');\n process.send({ case: 'initializeResponse' });\n\n let job: JobTask | undefined = undefined;\n const closeEvent = new EventEmitter();\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('job process orphaned, shutting down.');\n join.resolve();\n }, ORPHANED_TIMEOUT);\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest': {\n orphanedTimeout.refresh();\n process.send!({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n }\n case 'startJobRequest': {\n if (job) {\n throw new Error('job task already running');\n }\n\n logger = logger.child({ jobID: msg.value.runningJob.job.id });\n\n job = startJob(proc, agent.entry, msg.value.runningJob, closeEvent, logger, join);\n logger.debug('job started');\n break;\n }\n case 'shutdownRequest': {\n if (!job) {\n join.resolve();\n }\n closeEvent.emit('close', 'shutdownRequest');\n clearTimeout(orphanedTimeout);\n process.off('message', messageHandler);\n }\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n logger.debug('Job process shutdown');\n process.exit(0);\n }\n})();\n"],"mappings":"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","names":["module","agent"]}
|
|
@@ -107,10 +107,10 @@ const startJob = (proc, func, info, closeEvent, logger, joinFuture) => {
|
|
|
107
107
|
agent.prewarm = defaultInitializeProcessFunc;
|
|
108
108
|
}
|
|
109
109
|
process.on("SIGINT", () => {
|
|
110
|
-
logger.
|
|
110
|
+
logger.debug("SIGINT received in job proc");
|
|
111
111
|
});
|
|
112
112
|
process.on("SIGTERM", () => {
|
|
113
|
-
logger.
|
|
113
|
+
logger.debug("SIGTERM received in job proc");
|
|
114
114
|
});
|
|
115
115
|
await once(process, "message").then(([msg]) => {
|
|
116
116
|
msg = msg;
|
|
@@ -165,7 +165,7 @@ const startJob = (proc, func, info, closeEvent, logger, joinFuture) => {
|
|
|
165
165
|
};
|
|
166
166
|
process.on("message", messageHandler);
|
|
167
167
|
await join.await;
|
|
168
|
-
logger.
|
|
168
|
+
logger.debug("Job process shutdown");
|
|
169
169
|
process.exit(0);
|
|
170
170
|
}
|
|
171
171
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ipc/job_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Room, RoomEvent } from '@livekit/rtc-node';\nimport { randomUUID } from 'node:crypto';\nimport { EventEmitter, once } from 'node:events';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from 'pino';\nimport { type Agent, isAgent } from '../generator.js';\nimport { CurrentJobContext, JobContext, JobProcess, type RunningJobInfo } from '../job.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future } from '../utils.js';\nimport { defaultInitializeProcessFunc } from '../worker.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\ntype JobTask = {\n ctx: JobContext;\n task: Promise<void>;\n};\n\nclass PendingInference {\n promise = new Promise<{ requestId: string; data: unknown; error?: Error }>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: { requestId: string; data: unknown; error?: Error }) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\nclass InfClient implements InferenceExecutor {\n #requests: { [id: string]: PendingInference } = {};\n\n constructor() {\n process.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceResponse':\n const fut = this.#requests[msg.value.requestId];\n delete this.#requests[msg.value.requestId];\n if (!fut) {\n log().child({ resp: msg.value }).warn('received unexpected inference response');\n return;\n }\n fut.resolve(msg.value);\n break;\n }\n });\n }\n\n async doInference(method: string, data: unknown): Promise<unknown> {\n const requestId = 'inference_job_' + randomUUID;\n process.send!({ case: 'inferenceRequest', value: { requestId, method, data } });\n this.#requests[requestId] = new PendingInference();\n const resp = await this.#requests[requestId]!.promise;\n if (resp.error) {\n throw new Error(`inference of ${method} failed: ${resp.error.message}`);\n }\n return resp.data;\n }\n}\n\nconst startJob = (\n proc: JobProcess,\n func: (ctx: JobContext) => Promise<void>,\n info: RunningJobInfo,\n closeEvent: EventEmitter,\n logger: Logger,\n joinFuture: Future,\n): JobTask => {\n let connect = false;\n let shutdown = false;\n\n const room = new Room();\n room.on(RoomEvent.Disconnected, () => {\n if (!shutdown) {\n closeEvent.emit('close', false);\n }\n });\n\n const onConnect = () => {\n connect = true;\n };\n const onShutdown = (reason: string) => {\n shutdown = true;\n closeEvent.emit('close', true, reason);\n };\n\n const ctx = new JobContext(proc, info, room, onConnect, onShutdown, new InfClient());\n new CurrentJobContext(ctx);\n\n const task = new Promise<void>(async () => {\n const unconnectedTimeout = setTimeout(() => {\n if (!(connect || shutdown)) {\n logger.warn(\n 'room not connect after job_entry was called after 10 seconds, ',\n 'did you forget to call ctx.connect()?',\n );\n }\n }, 10000);\n func(ctx).finally(() => clearTimeout(unconnectedTimeout));\n\n await once(closeEvent, 'close').then((close) => {\n logger.debug('shutting down');\n shutdown = true;\n process.send!({ case: 'exiting', value: { reason: close[1] } });\n });\n\n await room.disconnect();\n logger.debug('disconnected from room');\n\n const shutdownTasks = [];\n for (const callback of ctx.shutdownCallbacks) {\n shutdownTasks.push(callback());\n }\n await Promise.all(shutdownTasks).catch((error) =>\n logger.error('error while shutting down the job', error),\n );\n\n process.send!({ case: 'done' });\n logger.info('job completed.');\n joinFuture.resolve();\n });\n\n return { ctx, task };\n};\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // process.argv:\n // [0] `node'\n // [1] import.meta.filename\n // [2] import.meta.filename of function containing entry file\n const moduleFile = process.argv[2];\n const agent: Agent = await import(pathToFileURL(moduleFile!).pathname).then((module) => {\n const agent = module.default;\n if (agent === undefined || !isAgent(agent)) {\n throw new Error(`Unable to load agent: Missing or invalid default export in ${moduleFile}`);\n }\n return agent;\n });\n if (!agent.prewarm) {\n agent.prewarm = defaultInitializeProcessFunc;\n }\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.info('SIGINT received in job proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.info('SIGTERM received in job proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const proc = new JobProcess();\n let logger = log().child({ pid: proc.pid });\n\n process.on('unhandledRejection', (reason) => {\n logger.error(reason);\n });\n\n logger.debug('initializing job runner');\n agent.prewarm(proc);\n logger.debug('job runner initialized');\n process.send({ case: 'initializeResponse' });\n\n let job: JobTask | undefined = undefined;\n const closeEvent = new EventEmitter();\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('job process orphaned, shutting down.');\n join.resolve();\n }, ORPHANED_TIMEOUT);\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest': {\n orphanedTimeout.refresh();\n process.send!({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n }\n case 'startJobRequest': {\n if (job) {\n throw new Error('job task already running');\n }\n\n logger = logger.child({ jobID: msg.value.runningJob.job.id });\n\n job = startJob(proc, agent.entry, msg.value.runningJob, closeEvent, logger, join);\n logger.debug('job started');\n break;\n }\n case 'shutdownRequest': {\n if (!job) {\n join.resolve();\n }\n closeEvent.emit('close', 'shutdownRequest');\n clearTimeout(orphanedTimeout);\n process.off('message', messageHandler);\n }\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n logger.info('Job process shutdown');\n process.exit(0);\n }\n})();\n"],"mappings":"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","names":["agent"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ipc/job_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Room, RoomEvent } from '@livekit/rtc-node';\nimport { randomUUID } from 'node:crypto';\nimport { EventEmitter, once } from 'node:events';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from 'pino';\nimport { type Agent, isAgent } from '../generator.js';\nimport { CurrentJobContext, JobContext, JobProcess, type RunningJobInfo } from '../job.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future } from '../utils.js';\nimport { defaultInitializeProcessFunc } from '../worker.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\ntype JobTask = {\n ctx: JobContext;\n task: Promise<void>;\n};\n\nclass PendingInference {\n promise = new Promise<{ requestId: string; data: unknown; error?: Error }>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: { requestId: string; data: unknown; error?: Error }) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\nclass InfClient implements InferenceExecutor {\n #requests: { [id: string]: PendingInference } = {};\n\n constructor() {\n process.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceResponse':\n const fut = this.#requests[msg.value.requestId];\n delete this.#requests[msg.value.requestId];\n if (!fut) {\n log().child({ resp: msg.value }).warn('received unexpected inference response');\n return;\n }\n fut.resolve(msg.value);\n break;\n }\n });\n }\n\n async doInference(method: string, data: unknown): Promise<unknown> {\n const requestId = 'inference_job_' + randomUUID;\n process.send!({ case: 'inferenceRequest', value: { requestId, method, data } });\n this.#requests[requestId] = new PendingInference();\n const resp = await this.#requests[requestId]!.promise;\n if (resp.error) {\n throw new Error(`inference of ${method} failed: ${resp.error.message}`);\n }\n return resp.data;\n }\n}\n\nconst startJob = (\n proc: JobProcess,\n func: (ctx: JobContext) => Promise<void>,\n info: RunningJobInfo,\n closeEvent: EventEmitter,\n logger: Logger,\n joinFuture: Future,\n): JobTask => {\n let connect = false;\n let shutdown = false;\n\n const room = new Room();\n room.on(RoomEvent.Disconnected, () => {\n if (!shutdown) {\n closeEvent.emit('close', false);\n }\n });\n\n const onConnect = () => {\n connect = true;\n };\n const onShutdown = (reason: string) => {\n shutdown = true;\n closeEvent.emit('close', true, reason);\n };\n\n const ctx = new JobContext(proc, info, room, onConnect, onShutdown, new InfClient());\n new CurrentJobContext(ctx);\n\n const task = new Promise<void>(async () => {\n const unconnectedTimeout = setTimeout(() => {\n if (!(connect || shutdown)) {\n logger.warn(\n 'room not connect after job_entry was called after 10 seconds, ',\n 'did you forget to call ctx.connect()?',\n );\n }\n }, 10000);\n func(ctx).finally(() => clearTimeout(unconnectedTimeout));\n\n await once(closeEvent, 'close').then((close) => {\n logger.debug('shutting down');\n shutdown = true;\n process.send!({ case: 'exiting', value: { reason: close[1] } });\n });\n\n await room.disconnect();\n logger.debug('disconnected from room');\n\n const shutdownTasks = [];\n for (const callback of ctx.shutdownCallbacks) {\n shutdownTasks.push(callback());\n }\n await Promise.all(shutdownTasks).catch((error) =>\n logger.error('error while shutting down the job', error),\n );\n\n process.send!({ case: 'done' });\n logger.info('job completed.');\n joinFuture.resolve();\n });\n\n return { ctx, task };\n};\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // process.argv:\n // [0] `node'\n // [1] import.meta.filename\n // [2] import.meta.filename of function containing entry file\n const moduleFile = process.argv[2];\n const agent: Agent = await import(pathToFileURL(moduleFile!).pathname).then((module) => {\n const agent = module.default;\n if (agent === undefined || !isAgent(agent)) {\n throw new Error(`Unable to load agent: Missing or invalid default export in ${moduleFile}`);\n }\n return agent;\n });\n if (!agent.prewarm) {\n agent.prewarm = defaultInitializeProcessFunc;\n }\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.debug('SIGINT received in job proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.debug('SIGTERM received in job proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const proc = new JobProcess();\n let logger = log().child({ pid: proc.pid });\n\n process.on('unhandledRejection', (reason) => {\n logger.error(reason);\n });\n\n logger.debug('initializing job runner');\n agent.prewarm(proc);\n logger.debug('job runner initialized');\n process.send({ case: 'initializeResponse' });\n\n let job: JobTask | undefined = undefined;\n const closeEvent = new EventEmitter();\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('job process orphaned, shutting down.');\n join.resolve();\n }, ORPHANED_TIMEOUT);\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest': {\n orphanedTimeout.refresh();\n process.send!({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n }\n case 'startJobRequest': {\n if (job) {\n throw new Error('job task already running');\n }\n\n logger = logger.child({ jobID: msg.value.runningJob.job.id });\n\n job = startJob(proc, agent.entry, msg.value.runningJob, closeEvent, logger, join);\n logger.debug('job started');\n break;\n }\n case 'shutdownRequest': {\n if (!job) {\n join.resolve();\n }\n closeEvent.emit('close', 'shutdownRequest');\n clearTimeout(orphanedTimeout);\n process.off('message', messageHandler);\n }\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n logger.debug('Job process shutdown');\n process.exit(0);\n }\n})();\n"],"mappings":"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","names":["agent"]}
|
package/dist/worker.cjs
CHANGED
|
@@ -92,7 +92,7 @@ const defaultInitializeProcessFunc = (_) => _;
|
|
|
92
92
|
const defaultRequestFunc = async (ctx) => {
|
|
93
93
|
await ctx.accept();
|
|
94
94
|
};
|
|
95
|
-
const defaultCpuLoad = async () => {
|
|
95
|
+
const defaultCpuLoad = async (worker) => {
|
|
96
96
|
return new Promise((resolve) => {
|
|
97
97
|
const cpus1 = import_node_os.default.cpus();
|
|
98
98
|
setTimeout(() => {
|
|
@@ -354,7 +354,7 @@ class Worker {
|
|
|
354
354
|
if (this.#draining) {
|
|
355
355
|
return;
|
|
356
356
|
}
|
|
357
|
-
this.#logger.
|
|
357
|
+
this.#logger.debug("draining worker");
|
|
358
358
|
this.#draining = true;
|
|
359
359
|
this.event.emit(
|
|
360
360
|
"worker_msg",
|
|
@@ -513,7 +513,7 @@ class Worker {
|
|
|
513
513
|
const loadMonitor = setInterval(() => {
|
|
514
514
|
if (closingWS) clearInterval(loadMonitor);
|
|
515
515
|
const oldStatus = currentStatus;
|
|
516
|
-
this.#opts.loadFunc().then((currentLoad) => {
|
|
516
|
+
this.#opts.loadFunc(this).then((currentLoad) => {
|
|
517
517
|
const isFull = currentLoad >= this.#opts.loadThreshold;
|
|
518
518
|
const currentlyAvailable = !isFull;
|
|
519
519
|
currentStatus = currentlyAvailable ? import_protocol.WorkerStatus.WS_AVAILABLE : import_protocol.WorkerStatus.WS_FULL;
|
|
@@ -629,7 +629,7 @@ class Worker {
|
|
|
629
629
|
await this.#close.await;
|
|
630
630
|
return;
|
|
631
631
|
}
|
|
632
|
-
this.#logger.
|
|
632
|
+
this.#logger.debug("shutting down worker");
|
|
633
633
|
this.#closed = true;
|
|
634
634
|
await ((_a = this.#inferenceExecutor) == null ? void 0 : _a.close());
|
|
635
635
|
await this.#procPool.close();
|