@livekit/agents 1.0.15 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/cli.cjs +12 -12
  2. package/dist/cli.cjs.map +1 -1
  3. package/dist/cli.d.cts +3 -3
  4. package/dist/cli.d.ts +3 -3
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +13 -13
  7. package/dist/cli.js.map +1 -1
  8. package/dist/inference/stt.cjs.map +1 -1
  9. package/dist/inference/stt.d.ts.map +1 -1
  10. package/dist/inference/stt.js +1 -1
  11. package/dist/inference/stt.js.map +1 -1
  12. package/dist/inference/tts.cjs.map +1 -1
  13. package/dist/inference/tts.d.cts +2 -1
  14. package/dist/inference/tts.d.ts +2 -1
  15. package/dist/inference/tts.d.ts.map +1 -1
  16. package/dist/inference/tts.js +1 -5
  17. package/dist/inference/tts.js.map +1 -1
  18. package/dist/llm/chat_context.cjs +78 -0
  19. package/dist/llm/chat_context.cjs.map +1 -1
  20. package/dist/llm/chat_context.d.cts +16 -0
  21. package/dist/llm/chat_context.d.ts +16 -0
  22. package/dist/llm/chat_context.d.ts.map +1 -1
  23. package/dist/llm/chat_context.js +78 -0
  24. package/dist/llm/chat_context.js.map +1 -1
  25. package/dist/llm/chat_context.test.cjs +531 -0
  26. package/dist/llm/chat_context.test.cjs.map +1 -1
  27. package/dist/llm/chat_context.test.js +531 -0
  28. package/dist/llm/chat_context.test.js.map +1 -1
  29. package/dist/llm/tool_context.cjs +40 -0
  30. package/dist/llm/tool_context.cjs.map +1 -1
  31. package/dist/llm/tool_context.d.cts +2 -0
  32. package/dist/llm/tool_context.d.ts +2 -0
  33. package/dist/llm/tool_context.d.ts.map +1 -1
  34. package/dist/llm/tool_context.js +38 -0
  35. package/dist/llm/tool_context.js.map +1 -1
  36. package/dist/metrics/base.cjs.map +1 -1
  37. package/dist/metrics/base.d.cts +7 -0
  38. package/dist/metrics/base.d.ts +7 -0
  39. package/dist/metrics/base.d.ts.map +1 -1
  40. package/dist/stt/stt.cjs +1 -1
  41. package/dist/stt/stt.cjs.map +1 -1
  42. package/dist/stt/stt.d.cts +7 -1
  43. package/dist/stt/stt.d.ts +7 -1
  44. package/dist/stt/stt.d.ts.map +1 -1
  45. package/dist/stt/stt.js +1 -1
  46. package/dist/stt/stt.js.map +1 -1
  47. package/dist/tts/tts.cjs +2 -4
  48. package/dist/tts/tts.cjs.map +1 -1
  49. package/dist/tts/tts.d.ts.map +1 -1
  50. package/dist/tts/tts.js +3 -5
  51. package/dist/tts/tts.js.map +1 -1
  52. package/dist/voice/agent_activity.cjs +83 -8
  53. package/dist/voice/agent_activity.cjs.map +1 -1
  54. package/dist/voice/agent_activity.d.cts +6 -2
  55. package/dist/voice/agent_activity.d.ts +6 -2
  56. package/dist/voice/agent_activity.d.ts.map +1 -1
  57. package/dist/voice/agent_activity.js +83 -8
  58. package/dist/voice/agent_activity.js.map +1 -1
  59. package/dist/voice/agent_session.cjs +3 -2
  60. package/dist/voice/agent_session.cjs.map +1 -1
  61. package/dist/voice/agent_session.d.cts +2 -1
  62. package/dist/voice/agent_session.d.ts +2 -1
  63. package/dist/voice/agent_session.d.ts.map +1 -1
  64. package/dist/voice/agent_session.js +3 -2
  65. package/dist/voice/agent_session.js.map +1 -1
  66. package/dist/voice/audio_recognition.cjs +138 -16
  67. package/dist/voice/audio_recognition.cjs.map +1 -1
  68. package/dist/voice/audio_recognition.d.cts +11 -0
  69. package/dist/voice/audio_recognition.d.ts +11 -0
  70. package/dist/voice/audio_recognition.d.ts.map +1 -1
  71. package/dist/voice/audio_recognition.js +138 -16
  72. package/dist/voice/audio_recognition.js.map +1 -1
  73. package/dist/voice/room_io/_input.cjs.map +1 -1
  74. package/dist/voice/room_io/_input.d.ts.map +1 -1
  75. package/dist/voice/room_io/_input.js +0 -1
  76. package/dist/voice/room_io/_input.js.map +1 -1
  77. package/dist/worker.cjs +17 -11
  78. package/dist/worker.cjs.map +1 -1
  79. package/dist/worker.d.cts +16 -9
  80. package/dist/worker.d.ts +16 -9
  81. package/dist/worker.d.ts.map +1 -1
  82. package/dist/worker.js +16 -12
  83. package/dist/worker.js.map +1 -1
  84. package/package.json +1 -1
  85. package/src/cli.ts +17 -17
  86. package/src/inference/stt.ts +2 -1
  87. package/src/inference/tts.ts +2 -5
  88. package/src/llm/chat_context.test.ts +607 -0
  89. package/src/llm/chat_context.ts +106 -0
  90. package/src/llm/tool_context.ts +44 -0
  91. package/src/metrics/base.ts +7 -0
  92. package/src/stt/stt.ts +8 -1
  93. package/src/tts/tts.ts +7 -5
  94. package/src/voice/agent_activity.ts +119 -9
  95. package/src/voice/agent_session.ts +3 -1
  96. package/src/voice/audio_recognition.ts +235 -57
  97. package/src/voice/room_io/_input.ts +1 -1
  98. package/src/worker.ts +29 -18
package/dist/cli.cjs CHANGED
@@ -28,15 +28,15 @@ var import_log = require("./log.cjs");
28
28
  var import_plugin = require("./plugin.cjs");
29
29
  var import_version = require("./version.cjs");
30
30
  var import_worker = require("./worker.cjs");
31
- const runWorker = async (args) => {
31
+ const runServer = async (args) => {
32
32
  (0, import_log.initializeLogger)({ pretty: !args.production, level: args.opts.logLevel });
33
33
  const logger = (0, import_log.log)();
34
34
  const { production: _, ...opts } = args.opts;
35
- const worker = new import_worker.Worker(new import_worker.WorkerOptions({ production: args.production, ...opts }));
35
+ const server = new import_worker.AgentServer(new import_worker.ServerOptions({ production: args.production, ...opts }));
36
36
  if (args.room) {
37
- worker.event.once("worker_registered", () => {
37
+ server.event.once("worker_registered", () => {
38
38
  logger.info(`connecting to room ${args.room}`);
39
- worker.simulateJob(args.room, args.participantIdentity);
39
+ server.simulateJob(args.room, args.participantIdentity);
40
40
  });
41
41
  }
42
42
  process.once("SIGINT", async () => {
@@ -46,23 +46,23 @@ const runWorker = async (args) => {
46
46
  process.exit(130);
47
47
  });
48
48
  if (args.production) {
49
- await worker.drain();
49
+ await server.drain();
50
50
  }
51
- await worker.close();
51
+ await server.close();
52
52
  logger.debug("worker closed due to SIGINT.");
53
53
  process.exit(130);
54
54
  });
55
55
  process.once("SIGTERM", async () => {
56
56
  logger.debug("SIGTERM received in CLI.");
57
57
  if (args.production) {
58
- await worker.drain();
58
+ await server.drain();
59
59
  }
60
- await worker.close();
60
+ await server.close();
61
61
  logger.debug("worker closed due to SIGTERM.");
62
62
  process.exit(143);
63
63
  });
64
64
  try {
65
- await worker.run();
65
+ await server.run();
66
66
  } catch {
67
67
  logger.fatal("closing worker due to error.");
68
68
  process.exit(1);
@@ -100,7 +100,7 @@ const runApp = (opts) => {
100
100
  opts.apiSecret = options.apiSecret || opts.apiSecret;
101
101
  opts.logLevel = options.logLevel || opts.logLevel;
102
102
  opts.workerToken = options.workerToken || opts.workerToken;
103
- runWorker({
103
+ runServer({
104
104
  opts,
105
105
  production: true,
106
106
  watch: false
@@ -115,7 +115,7 @@ const runApp = (opts) => {
115
115
  opts.apiSecret = options.apiSecret || opts.apiSecret;
116
116
  opts.logLevel = options.logLevel || opts.logLevel;
117
117
  opts.workerToken = options.workerToken || opts.workerToken;
118
- runWorker({
118
+ runServer({
119
119
  opts,
120
120
  production: false,
121
121
  watch: false
@@ -130,7 +130,7 @@ const runApp = (opts) => {
130
130
  opts.apiSecret = options.apiSecret || opts.apiSecret;
131
131
  opts.logLevel = options.logLevel || opts.logLevel;
132
132
  opts.workerToken = options.workerToken || opts.workerToken;
133
- runWorker({
133
+ runServer({
134
134
  opts,
135
135
  production: false,
136
136
  watch: false,
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 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":[]}
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 { AgentServer, ServerOptions } from './worker.js';\n\ntype CliArgs = {\n opts: ServerOptions;\n production: boolean;\n watch: boolean;\n event?: EventEmitter;\n room?: string;\n participantIdentity?: string;\n};\n\nconst runServer = async (args: CliArgs) => {\n initializeLogger({ pretty: !args.production, level: args.opts.logLevel });\n const logger = log();\n\n // though `production` is defined in ServerOptions, it will always be overridden by CLI.\n const { production: _, ...opts } = args.opts; // eslint-disable-line @typescript-eslint/no-unused-vars\n const server = new AgentServer(new ServerOptions({ production: args.production, ...opts }));\n\n if (args.room) {\n server.event.once('worker_registered', () => {\n logger.info(`connecting to room ${args.room}`);\n server.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 server.drain();\n }\n await server.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 server.drain();\n }\n await server.close();\n logger.debug('worker closed due to SIGTERM.');\n process.exit(143); // SIGTERM exit code\n });\n\n try {\n await server.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 ServerOptions({ agent: import.meta.filename }));\n * }\n * ```\n */\nexport const runApp = (opts: ServerOptions) => {\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 runServer({\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 runServer({\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 runServer({\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.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { WorkerOptions } from './worker.js';
1
+ import { ServerOptions } from './worker.js';
2
2
  /**
3
3
  * Exposes a CLI for creating a new worker, in development or production mode.
4
4
  *
@@ -6,9 +6,9 @@ import { WorkerOptions } from './worker.js';
6
6
  * @example
7
7
  * ```
8
8
  * if (process.argv[1] === fileURLToPath(import.meta.url)) {
9
- * cli.runApp(new WorkerOptions({ agent: import.meta.filename }));
9
+ * cli.runApp(new ServerOptions({ agent: import.meta.filename }));
10
10
  * }
11
11
  * ```
12
12
  */
13
- export declare const runApp: (opts: WorkerOptions) => void;
13
+ export declare const runApp: (opts: ServerOptions) => void;
14
14
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { WorkerOptions } from './worker.js';
1
+ import { ServerOptions } from './worker.js';
2
2
  /**
3
3
  * Exposes a CLI for creating a new worker, in development or production mode.
4
4
  *
@@ -6,9 +6,9 @@ import { WorkerOptions } from './worker.js';
6
6
  * @example
7
7
  * ```
8
8
  * if (process.argv[1] === fileURLToPath(import.meta.url)) {
9
- * cli.runApp(new WorkerOptions({ agent: import.meta.filename }));
9
+ * cli.runApp(new ServerOptions({ agent: import.meta.filename }));
10
10
  * }
11
11
  * ```
12
12
  */
13
- export declare const runApp: (opts: WorkerOptions) => void;
13
+ export declare const runApp: (opts: ServerOptions) => void;
14
14
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAQA,OAAO,EAAU,aAAa,EAAE,MAAM,aAAa,CAAC;AA2DpD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM,SAAU,aAAa,SAiJzC,CAAC"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAQA,OAAO,EAAe,aAAa,EAAE,MAAM,aAAa,CAAC;AA2DzD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM,SAAU,aAAa,SAiJzC,CAAC"}
package/dist/cli.js CHANGED
@@ -2,16 +2,16 @@ import { Command, Option } from "commander";
2
2
  import { initializeLogger, log } from "./log.js";
3
3
  import { Plugin } from "./plugin.js";
4
4
  import { version } from "./version.js";
5
- import { Worker, WorkerOptions } from "./worker.js";
6
- const runWorker = async (args) => {
5
+ import { AgentServer, ServerOptions } from "./worker.js";
6
+ const runServer = async (args) => {
7
7
  initializeLogger({ pretty: !args.production, level: args.opts.logLevel });
8
8
  const logger = log();
9
9
  const { production: _, ...opts } = args.opts;
10
- const worker = new Worker(new WorkerOptions({ production: args.production, ...opts }));
10
+ const server = new AgentServer(new ServerOptions({ production: args.production, ...opts }));
11
11
  if (args.room) {
12
- worker.event.once("worker_registered", () => {
12
+ server.event.once("worker_registered", () => {
13
13
  logger.info(`connecting to room ${args.room}`);
14
- worker.simulateJob(args.room, args.participantIdentity);
14
+ server.simulateJob(args.room, args.participantIdentity);
15
15
  });
16
16
  }
17
17
  process.once("SIGINT", async () => {
@@ -21,23 +21,23 @@ const runWorker = async (args) => {
21
21
  process.exit(130);
22
22
  });
23
23
  if (args.production) {
24
- await worker.drain();
24
+ await server.drain();
25
25
  }
26
- await worker.close();
26
+ await server.close();
27
27
  logger.debug("worker closed due to SIGINT.");
28
28
  process.exit(130);
29
29
  });
30
30
  process.once("SIGTERM", async () => {
31
31
  logger.debug("SIGTERM received in CLI.");
32
32
  if (args.production) {
33
- await worker.drain();
33
+ await server.drain();
34
34
  }
35
- await worker.close();
35
+ await server.close();
36
36
  logger.debug("worker closed due to SIGTERM.");
37
37
  process.exit(143);
38
38
  });
39
39
  try {
40
- await worker.run();
40
+ await server.run();
41
41
  } catch {
42
42
  logger.fatal("closing worker due to error.");
43
43
  process.exit(1);
@@ -75,7 +75,7 @@ const runApp = (opts) => {
75
75
  opts.apiSecret = options.apiSecret || opts.apiSecret;
76
76
  opts.logLevel = options.logLevel || opts.logLevel;
77
77
  opts.workerToken = options.workerToken || opts.workerToken;
78
- runWorker({
78
+ runServer({
79
79
  opts,
80
80
  production: true,
81
81
  watch: false
@@ -90,7 +90,7 @@ const runApp = (opts) => {
90
90
  opts.apiSecret = options.apiSecret || opts.apiSecret;
91
91
  opts.logLevel = options.logLevel || opts.logLevel;
92
92
  opts.workerToken = options.workerToken || opts.workerToken;
93
- runWorker({
93
+ runServer({
94
94
  opts,
95
95
  production: false,
96
96
  watch: false
@@ -105,7 +105,7 @@ const runApp = (opts) => {
105
105
  opts.apiSecret = options.apiSecret || opts.apiSecret;
106
106
  opts.logLevel = options.logLevel || opts.logLevel;
107
107
  opts.workerToken = options.workerToken || opts.workerToken;
108
- runWorker({
108
+ runServer({
109
109
  opts,
110
110
  production: false,
111
111
  watch: false,
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 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":[]}
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 { AgentServer, ServerOptions } from './worker.js';\n\ntype CliArgs = {\n opts: ServerOptions;\n production: boolean;\n watch: boolean;\n event?: EventEmitter;\n room?: string;\n participantIdentity?: string;\n};\n\nconst runServer = async (args: CliArgs) => {\n initializeLogger({ pretty: !args.production, level: args.opts.logLevel });\n const logger = log();\n\n // though `production` is defined in ServerOptions, it will always be overridden by CLI.\n const { production: _, ...opts } = args.opts; // eslint-disable-line @typescript-eslint/no-unused-vars\n const server = new AgentServer(new ServerOptions({ production: args.production, ...opts }));\n\n if (args.room) {\n server.event.once('worker_registered', () => {\n logger.info(`connecting to room ${args.room}`);\n server.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 server.drain();\n }\n await server.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 server.drain();\n }\n await server.close();\n logger.debug('worker closed due to SIGTERM.');\n process.exit(143); // SIGTERM exit code\n });\n\n try {\n await server.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 ServerOptions({ agent: import.meta.filename }));\n * }\n * ```\n */\nexport const runApp = (opts: ServerOptions) => {\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 runServer({\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 runServer({\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 runServer({\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 +1 @@
1
- {"version":3,"sources":["../../src/inference/stt.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { type AudioFrame } from '@livekit/rtc-node';\nimport { type RawData, WebSocket } from 'ws';\nimport { APIError, APIStatusError } from '../_exceptions.js';\nimport { AudioByteStream } from '../audio.js';\nimport { log } from '../log.js';\nimport {\n STT as BaseSTT,\n SpeechStream as BaseSpeechStream,\n type SpeechData,\n type SpeechEvent,\n SpeechEventType,\n} from '../stt/index.js';\nimport { type APIConnectOptions, DEFAULT_API_CONNECT_OPTIONS } from '../types.js';\nimport { type AudioBuffer, Event, Task, cancelAndWait, shortuuid, waitForAbort } from '../utils.js';\nimport { type AnyString, connectWs, createAccessToken } from './utils.js';\n\nexport type DeepgramModels =\n | 'deepgram'\n | 'deepgram/nova-3'\n | 'deepgram/nova-3-general'\n | 'deepgram/nova-3-medical'\n | 'deepgram/nova-2-conversationalai'\n | 'deepgram/nova-2'\n | 'deepgram/nova-2-general'\n | 'deepgram/nova-2-medical'\n | 'deepgram/nova-2-phonecall';\n\nexport type CartesiaModels = 'cartesia' | 'cartesia/ink-whisper';\n\nexport type AssemblyaiModels = 'assemblyai' | 'assemblyai/universal-streaming';\n\nexport interface CartesiaOptions {\n min_volume?: number; // default: not specified\n max_silence_duration_secs?: number; // default: not specified\n}\n\nexport interface DeepgramOptions {\n filler_words?: boolean; // default: true\n interim_results?: boolean; // default: true\n endpointing?: number; // default: 25 (ms)\n punctuate?: boolean; // default: false\n smart_format?: boolean;\n keywords?: Array<[string, number]>;\n keyterms?: string[];\n profanity_filter?: boolean;\n numerals?: boolean;\n mip_opt_out?: boolean;\n}\n\nexport interface AssemblyAIOptions {\n format_turns?: boolean; // default: false\n end_of_turn_confidence_threshold?: number; // default: 0.01\n min_end_of_turn_silence_when_confident?: number; // default: 0\n max_turn_silence?: number; // default: not specified\n keyterms_prompt?: string[]; // default: not specified\n}\n\nexport type STTLanguages =\n | 'multi'\n | 'en'\n | 'de'\n | 'es'\n | 'fr'\n | 'ja'\n | 'pt'\n | 'zh'\n | 'hi'\n | AnyString;\n\ntype _STTModels = DeepgramModels | CartesiaModels | AssemblyaiModels;\n\nexport type STTModels = _STTModels | 'auto' | AnyString;\n\nexport type ModelWithLanguage = `${_STTModels}:${STTLanguages}` | STTModels;\n\nexport type STTOptions<TModel extends STTModels> = TModel extends DeepgramModels\n ? DeepgramOptions\n : TModel extends CartesiaModels\n ? CartesiaOptions\n : TModel extends AssemblyaiModels\n ? AssemblyAIOptions\n : Record<string, unknown>;\n\nexport type STTEncoding = 'pcm_s16le';\n\nconst DEFAULT_ENCODING: STTEncoding = 'pcm_s16le';\nconst DEFAULT_SAMPLE_RATE = 16000;\nconst DEFAULT_BASE_URL = 'wss://agent-gateway.livekit.cloud/v1';\nconst DEFAULT_CANCEL_TIMEOUT = 5000;\n\nexport interface InferenceSTTOptions<TModel extends STTModels> {\n model?: TModel;\n language?: STTLanguages;\n encoding: STTEncoding;\n sampleRate: number;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: STTOptions<TModel>;\n}\n\n/**\n * Livekit Cloud Inference STT\n */\nexport class STT<TModel extends STTModels> extends BaseSTT {\n private opts: InferenceSTTOptions<TModel>;\n private streams: Set<SpeechStream<TModel>> = new Set();\n\n #logger = log();\n\n constructor(opts?: {\n model?: TModel;\n language?: STTLanguages;\n baseURL?: string;\n encoding?: STTEncoding;\n sampleRate?: number;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: STTOptions<TModel>;\n }) {\n super({ streaming: true, interimResults: true });\n\n const {\n model,\n language,\n baseURL,\n encoding = DEFAULT_ENCODING,\n sampleRate = DEFAULT_SAMPLE_RATE,\n apiKey,\n apiSecret,\n modelOptions = {} as STTOptions<TModel>,\n } = opts || {};\n\n const lkBaseURL = baseURL || process.env.LIVEKIT_INFERENCE_URL || DEFAULT_BASE_URL;\n const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY;\n if (!lkApiKey) {\n throw new Error('apiKey is required: pass apiKey or set LIVEKIT_API_KEY');\n }\n\n const lkApiSecret =\n apiSecret || process.env.LIVEKIT_INFERENCE_API_SECRET || process.env.LIVEKIT_API_SECRET;\n if (!lkApiSecret) {\n throw new Error('apiSecret is required: pass apiSecret or set LIVEKIT_API_SECRET');\n }\n\n this.opts = {\n model,\n language,\n encoding,\n sampleRate,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions,\n };\n }\n\n get label(): string {\n return 'inference.STT';\n }\n\n static fromModelString(modelString: string): STT<AnyString> {\n if (modelString.includes(':')) {\n const [model, language] = modelString.split(':') as [AnyString, STTLanguages];\n return new STT({ model, language });\n }\n return new STT({ model: modelString });\n }\n\n protected async _recognize(_: AudioBuffer): Promise<SpeechEvent> {\n throw new Error('LiveKit STT does not support batch recognition, use stream() instead');\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n\n for (const stream of this.streams) {\n stream.updateOptions(opts);\n }\n }\n\n stream(options?: {\n language?: STTLanguages | string;\n connOptions?: APIConnectOptions;\n }): SpeechStream<TModel> {\n const { language, connOptions = DEFAULT_API_CONNECT_OPTIONS } = options || {};\n const streamOpts = {\n ...this.opts,\n language: language ?? this.opts.language,\n } as InferenceSTTOptions<TModel>;\n\n const stream = new SpeechStream(this, streamOpts, connOptions);\n this.streams.add(stream);\n\n return stream;\n }\n}\n\nexport class SpeechStream<TModel extends STTModels> extends BaseSpeechStream {\n private opts: InferenceSTTOptions<TModel>;\n private requestId = shortuuid('stt_request_');\n private speaking = false;\n private speechDuration = 0;\n private reconnectEvent = new Event();\n\n #logger = log();\n\n constructor(\n sttImpl: STT<TModel>,\n opts: InferenceSTTOptions<TModel>,\n connOptions: APIConnectOptions,\n ) {\n super(sttImpl, opts.sampleRate, connOptions);\n this.opts = opts;\n }\n\n get label(): string {\n return 'inference.SpeechStream';\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n }\n\n protected async run(): Promise<void> {\n let ws: WebSocket | null = null;\n let closingWs = false;\n\n this.reconnectEvent.set();\n\n const connect = async () => {\n const params = {\n settings: {\n sample_rate: String(this.opts.sampleRate),\n encoding: this.opts.encoding,\n extra: this.opts.modelOptions,\n },\n } as Record<string, unknown>;\n\n if (this.opts.model && this.opts.model !== 'auto') {\n params.model = this.opts.model;\n }\n\n if (this.opts.language) {\n (params.settings as Record<string, unknown>).language = this.opts.language;\n }\n\n let baseURL = this.opts.baseURL;\n if (baseURL.startsWith('http://') || baseURL.startsWith('https://')) {\n baseURL = baseURL.replace('http', 'ws');\n }\n\n const token = await createAccessToken(this.opts.apiKey, this.opts.apiSecret);\n const url = `${baseURL}/stt`;\n const headers = { Authorization: `Bearer ${token}` } as Record<string, string>;\n\n const socket = await connectWs(url, headers, 10000);\n const msg = { ...params, type: 'session.create' };\n socket.send(JSON.stringify(msg));\n\n return socket;\n };\n\n const send = async (socket: WebSocket, signal: AbortSignal) => {\n const audioStream = new AudioByteStream(\n this.opts.sampleRate,\n 1,\n Math.floor(this.opts.sampleRate / 20), // 50ms\n );\n\n for await (const ev of this.input) {\n if (signal.aborted) break;\n let frames: AudioFrame[];\n\n if (ev === SpeechStream.FLUSH_SENTINEL) {\n frames = audioStream.flush();\n } else {\n const frame = ev as AudioFrame;\n frames = audioStream.write(new Int16Array(frame.data).buffer);\n }\n\n for (const frame of frames) {\n this.speechDuration += frame.samplesPerChannel / frame.sampleRate;\n const base64 = Buffer.from(frame.data.buffer).toString('base64');\n const msg = { type: 'input_audio', audio: base64 };\n socket.send(JSON.stringify(msg));\n }\n }\n\n closingWs = true;\n socket.send(JSON.stringify({ type: 'session.finalize' }));\n };\n\n const recv = async (socket: WebSocket, signal: AbortSignal) => {\n while (!this.closed && !signal.aborted) {\n const dataPromise = new Promise<string>((resolve, reject) => {\n const messageHandler = (d: RawData) => {\n resolve(d.toString());\n removeListeners();\n };\n const errorHandler = (e: Error) => {\n reject(e);\n removeListeners();\n };\n const closeHandler = (code: number) => {\n if (closingWs) {\n resolve('');\n } else {\n reject(\n new APIStatusError({\n message: 'LiveKit STT connection closed unexpectedly',\n options: { statusCode: code },\n }),\n );\n }\n removeListeners();\n };\n const removeListeners = () => {\n socket.removeListener('message', messageHandler);\n socket.removeListener('error', errorHandler);\n socket.removeListener('close', closeHandler);\n };\n socket.once('message', messageHandler);\n socket.once('error', errorHandler);\n socket.once('close', closeHandler);\n });\n\n const data = await Promise.race([dataPromise, waitForAbort(signal)]);\n\n if (!data || signal.aborted) return;\n\n const json = JSON.parse(data);\n const type = json.type as string | undefined;\n\n switch (type) {\n case 'session.created':\n case 'session.finalized':\n case 'session.closed':\n break;\n case 'interim_transcript':\n this.processTranscript(json, false);\n break;\n case 'final_transcript':\n this.processTranscript(json, true);\n break;\n case 'error':\n this.#logger.error('received error from LiveKit STT: %o', json);\n throw new APIError(`LiveKit STT returned error: ${JSON.stringify(json)}`);\n default:\n this.#logger.warn('received unexpected message from LiveKit STT: %o', json);\n break;\n }\n }\n };\n\n while (true) {\n try {\n ws = await connect();\n\n const sendTask = Task.from(async ({ signal }) => {\n await send(ws!, signal);\n });\n\n const recvTask = Task.from(async ({ signal }) => {\n await recv(ws!, signal);\n });\n\n const tasks = [sendTask, recvTask];\n const waitReconnectTask = Task.from(async ({ signal }) => {\n await Promise.race([this.reconnectEvent.wait(), waitForAbort(signal)]);\n });\n\n try {\n await Promise.race([\n Promise.all(tasks.map((task) => task.result)),\n waitReconnectTask.result,\n ]);\n\n if (!waitReconnectTask.done) break;\n this.reconnectEvent.clear();\n } finally {\n await cancelAndWait([sendTask, recvTask, waitReconnectTask], DEFAULT_CANCEL_TIMEOUT);\n }\n } finally {\n try {\n if (ws) ws.close();\n } catch {}\n }\n }\n }\n\n private processTranscript(data: Record<string, any>, isFinal: boolean) {\n const requestId = data.request_id ?? this.requestId;\n const text = data.transcript ?? '';\n const language = data.language ?? this.opts.language ?? 'en';\n\n if (!text && !isFinal) return;\n\n // We'll have a more accurate way of detecting when speech started when we have VAD\n if (!this.speaking) {\n this.speaking = true;\n this.queue.put({ type: SpeechEventType.START_OF_SPEECH });\n }\n\n const speechData: SpeechData = {\n language,\n startTime: data.start ?? 0,\n endTime: data.duration ?? 0,\n confidence: data.confidence ?? 1.0,\n text,\n };\n\n if (isFinal) {\n if (this.speechDuration > 0) {\n this.queue.put({\n type: SpeechEventType.RECOGNITION_USAGE,\n requestId,\n recognitionUsage: { audioDuration: this.speechDuration },\n });\n this.speechDuration = 0;\n }\n\n this.queue.put({\n type: SpeechEventType.FINAL_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n\n if (this.speaking) {\n this.speaking = false;\n this.queue.put({ type: SpeechEventType.END_OF_SPEECH });\n }\n } else {\n this.queue.put({\n type: SpeechEventType.INTERIM_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n }\n }\n}\n"],"mappings":"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","names":["import_utils","BaseSTT","BaseSpeechStream"]}
1
+ {"version":3,"sources":["../../src/inference/stt.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { type AudioFrame } from '@livekit/rtc-node';\nimport type { WebSocket } from 'ws';\nimport { type RawData } from 'ws';\nimport { APIError, APIStatusError } from '../_exceptions.js';\nimport { AudioByteStream } from '../audio.js';\nimport { log } from '../log.js';\nimport {\n STT as BaseSTT,\n SpeechStream as BaseSpeechStream,\n type SpeechData,\n type SpeechEvent,\n SpeechEventType,\n} from '../stt/index.js';\nimport { type APIConnectOptions, DEFAULT_API_CONNECT_OPTIONS } from '../types.js';\nimport { type AudioBuffer, Event, Task, cancelAndWait, shortuuid, waitForAbort } from '../utils.js';\nimport { type AnyString, connectWs, createAccessToken } from './utils.js';\n\nexport type DeepgramModels =\n | 'deepgram'\n | 'deepgram/nova-3'\n | 'deepgram/nova-3-general'\n | 'deepgram/nova-3-medical'\n | 'deepgram/nova-2-conversationalai'\n | 'deepgram/nova-2'\n | 'deepgram/nova-2-general'\n | 'deepgram/nova-2-medical'\n | 'deepgram/nova-2-phonecall';\n\nexport type CartesiaModels = 'cartesia' | 'cartesia/ink-whisper';\n\nexport type AssemblyaiModels = 'assemblyai' | 'assemblyai/universal-streaming';\n\nexport interface CartesiaOptions {\n min_volume?: number; // default: not specified\n max_silence_duration_secs?: number; // default: not specified\n}\n\nexport interface DeepgramOptions {\n filler_words?: boolean; // default: true\n interim_results?: boolean; // default: true\n endpointing?: number; // default: 25 (ms)\n punctuate?: boolean; // default: false\n smart_format?: boolean;\n keywords?: Array<[string, number]>;\n keyterms?: string[];\n profanity_filter?: boolean;\n numerals?: boolean;\n mip_opt_out?: boolean;\n}\n\nexport interface AssemblyAIOptions {\n format_turns?: boolean; // default: false\n end_of_turn_confidence_threshold?: number; // default: 0.01\n min_end_of_turn_silence_when_confident?: number; // default: 0\n max_turn_silence?: number; // default: not specified\n keyterms_prompt?: string[]; // default: not specified\n}\n\nexport type STTLanguages =\n | 'multi'\n | 'en'\n | 'de'\n | 'es'\n | 'fr'\n | 'ja'\n | 'pt'\n | 'zh'\n | 'hi'\n | AnyString;\n\ntype _STTModels = DeepgramModels | CartesiaModels | AssemblyaiModels;\n\nexport type STTModels = _STTModels | 'auto' | AnyString;\n\nexport type ModelWithLanguage = `${_STTModels}:${STTLanguages}` | STTModels;\n\nexport type STTOptions<TModel extends STTModels> = TModel extends DeepgramModels\n ? DeepgramOptions\n : TModel extends CartesiaModels\n ? CartesiaOptions\n : TModel extends AssemblyaiModels\n ? AssemblyAIOptions\n : Record<string, unknown>;\n\nexport type STTEncoding = 'pcm_s16le';\n\nconst DEFAULT_ENCODING: STTEncoding = 'pcm_s16le';\nconst DEFAULT_SAMPLE_RATE = 16000;\nconst DEFAULT_BASE_URL = 'wss://agent-gateway.livekit.cloud/v1';\nconst DEFAULT_CANCEL_TIMEOUT = 5000;\n\nexport interface InferenceSTTOptions<TModel extends STTModels> {\n model?: TModel;\n language?: STTLanguages;\n encoding: STTEncoding;\n sampleRate: number;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: STTOptions<TModel>;\n}\n\n/**\n * Livekit Cloud Inference STT\n */\nexport class STT<TModel extends STTModels> extends BaseSTT {\n private opts: InferenceSTTOptions<TModel>;\n private streams: Set<SpeechStream<TModel>> = new Set();\n\n #logger = log();\n\n constructor(opts?: {\n model?: TModel;\n language?: STTLanguages;\n baseURL?: string;\n encoding?: STTEncoding;\n sampleRate?: number;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: STTOptions<TModel>;\n }) {\n super({ streaming: true, interimResults: true });\n\n const {\n model,\n language,\n baseURL,\n encoding = DEFAULT_ENCODING,\n sampleRate = DEFAULT_SAMPLE_RATE,\n apiKey,\n apiSecret,\n modelOptions = {} as STTOptions<TModel>,\n } = opts || {};\n\n const lkBaseURL = baseURL || process.env.LIVEKIT_INFERENCE_URL || DEFAULT_BASE_URL;\n const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY;\n if (!lkApiKey) {\n throw new Error('apiKey is required: pass apiKey or set LIVEKIT_API_KEY');\n }\n\n const lkApiSecret =\n apiSecret || process.env.LIVEKIT_INFERENCE_API_SECRET || process.env.LIVEKIT_API_SECRET;\n if (!lkApiSecret) {\n throw new Error('apiSecret is required: pass apiSecret or set LIVEKIT_API_SECRET');\n }\n\n this.opts = {\n model,\n language,\n encoding,\n sampleRate,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions,\n };\n }\n\n get label(): string {\n return 'inference.STT';\n }\n\n static fromModelString(modelString: string): STT<AnyString> {\n if (modelString.includes(':')) {\n const [model, language] = modelString.split(':') as [AnyString, STTLanguages];\n return new STT({ model, language });\n }\n return new STT({ model: modelString });\n }\n\n protected async _recognize(_: AudioBuffer): Promise<SpeechEvent> {\n throw new Error('LiveKit STT does not support batch recognition, use stream() instead');\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n\n for (const stream of this.streams) {\n stream.updateOptions(opts);\n }\n }\n\n stream(options?: {\n language?: STTLanguages | string;\n connOptions?: APIConnectOptions;\n }): SpeechStream<TModel> {\n const { language, connOptions = DEFAULT_API_CONNECT_OPTIONS } = options || {};\n const streamOpts = {\n ...this.opts,\n language: language ?? this.opts.language,\n } as InferenceSTTOptions<TModel>;\n\n const stream = new SpeechStream(this, streamOpts, connOptions);\n this.streams.add(stream);\n\n return stream;\n }\n}\n\nexport class SpeechStream<TModel extends STTModels> extends BaseSpeechStream {\n private opts: InferenceSTTOptions<TModel>;\n private requestId = shortuuid('stt_request_');\n private speaking = false;\n private speechDuration = 0;\n private reconnectEvent = new Event();\n\n #logger = log();\n\n constructor(\n sttImpl: STT<TModel>,\n opts: InferenceSTTOptions<TModel>,\n connOptions: APIConnectOptions,\n ) {\n super(sttImpl, opts.sampleRate, connOptions);\n this.opts = opts;\n }\n\n get label(): string {\n return 'inference.SpeechStream';\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n }\n\n protected async run(): Promise<void> {\n let ws: WebSocket | null = null;\n let closingWs = false;\n\n this.reconnectEvent.set();\n\n const connect = async () => {\n const params = {\n settings: {\n sample_rate: String(this.opts.sampleRate),\n encoding: this.opts.encoding,\n extra: this.opts.modelOptions,\n },\n } as Record<string, unknown>;\n\n if (this.opts.model && this.opts.model !== 'auto') {\n params.model = this.opts.model;\n }\n\n if (this.opts.language) {\n (params.settings as Record<string, unknown>).language = this.opts.language;\n }\n\n let baseURL = this.opts.baseURL;\n if (baseURL.startsWith('http://') || baseURL.startsWith('https://')) {\n baseURL = baseURL.replace('http', 'ws');\n }\n\n const token = await createAccessToken(this.opts.apiKey, this.opts.apiSecret);\n const url = `${baseURL}/stt`;\n const headers = { Authorization: `Bearer ${token}` } as Record<string, string>;\n\n const socket = await connectWs(url, headers, 10000);\n const msg = { ...params, type: 'session.create' };\n socket.send(JSON.stringify(msg));\n\n return socket;\n };\n\n const send = async (socket: WebSocket, signal: AbortSignal) => {\n const audioStream = new AudioByteStream(\n this.opts.sampleRate,\n 1,\n Math.floor(this.opts.sampleRate / 20), // 50ms\n );\n\n for await (const ev of this.input) {\n if (signal.aborted) break;\n let frames: AudioFrame[];\n\n if (ev === SpeechStream.FLUSH_SENTINEL) {\n frames = audioStream.flush();\n } else {\n const frame = ev as AudioFrame;\n frames = audioStream.write(new Int16Array(frame.data).buffer);\n }\n\n for (const frame of frames) {\n this.speechDuration += frame.samplesPerChannel / frame.sampleRate;\n const base64 = Buffer.from(frame.data.buffer).toString('base64');\n const msg = { type: 'input_audio', audio: base64 };\n socket.send(JSON.stringify(msg));\n }\n }\n\n closingWs = true;\n socket.send(JSON.stringify({ type: 'session.finalize' }));\n };\n\n const recv = async (socket: WebSocket, signal: AbortSignal) => {\n while (!this.closed && !signal.aborted) {\n const dataPromise = new Promise<string>((resolve, reject) => {\n const messageHandler = (d: RawData) => {\n resolve(d.toString());\n removeListeners();\n };\n const errorHandler = (e: Error) => {\n reject(e);\n removeListeners();\n };\n const closeHandler = (code: number) => {\n if (closingWs) {\n resolve('');\n } else {\n reject(\n new APIStatusError({\n message: 'LiveKit STT connection closed unexpectedly',\n options: { statusCode: code },\n }),\n );\n }\n removeListeners();\n };\n const removeListeners = () => {\n socket.removeListener('message', messageHandler);\n socket.removeListener('error', errorHandler);\n socket.removeListener('close', closeHandler);\n };\n socket.once('message', messageHandler);\n socket.once('error', errorHandler);\n socket.once('close', closeHandler);\n });\n\n const data = await Promise.race([dataPromise, waitForAbort(signal)]);\n\n if (!data || signal.aborted) return;\n\n const json = JSON.parse(data);\n const type = json.type as string | undefined;\n\n switch (type) {\n case 'session.created':\n case 'session.finalized':\n case 'session.closed':\n break;\n case 'interim_transcript':\n this.processTranscript(json, false);\n break;\n case 'final_transcript':\n this.processTranscript(json, true);\n break;\n case 'error':\n this.#logger.error('received error from LiveKit STT: %o', json);\n throw new APIError(`LiveKit STT returned error: ${JSON.stringify(json)}`);\n default:\n this.#logger.warn('received unexpected message from LiveKit STT: %o', json);\n break;\n }\n }\n };\n\n while (true) {\n try {\n ws = await connect();\n\n const sendTask = Task.from(async ({ signal }) => {\n await send(ws!, signal);\n });\n\n const recvTask = Task.from(async ({ signal }) => {\n await recv(ws!, signal);\n });\n\n const tasks = [sendTask, recvTask];\n const waitReconnectTask = Task.from(async ({ signal }) => {\n await Promise.race([this.reconnectEvent.wait(), waitForAbort(signal)]);\n });\n\n try {\n await Promise.race([\n Promise.all(tasks.map((task) => task.result)),\n waitReconnectTask.result,\n ]);\n\n if (!waitReconnectTask.done) break;\n this.reconnectEvent.clear();\n } finally {\n await cancelAndWait([sendTask, recvTask, waitReconnectTask], DEFAULT_CANCEL_TIMEOUT);\n }\n } finally {\n try {\n if (ws) ws.close();\n } catch {}\n }\n }\n }\n\n private processTranscript(data: Record<string, any>, isFinal: boolean) {\n const requestId = data.request_id ?? this.requestId;\n const text = data.transcript ?? '';\n const language = data.language ?? this.opts.language ?? 'en';\n\n if (!text && !isFinal) return;\n\n // We'll have a more accurate way of detecting when speech started when we have VAD\n if (!this.speaking) {\n this.speaking = true;\n this.queue.put({ type: SpeechEventType.START_OF_SPEECH });\n }\n\n const speechData: SpeechData = {\n language,\n startTime: data.start ?? 0,\n endTime: data.duration ?? 0,\n confidence: data.confidence ?? 1.0,\n text,\n };\n\n if (isFinal) {\n if (this.speechDuration > 0) {\n this.queue.put({\n type: SpeechEventType.RECOGNITION_USAGE,\n requestId,\n recognitionUsage: { audioDuration: this.speechDuration },\n });\n this.speechDuration = 0;\n }\n\n this.queue.put({\n type: SpeechEventType.FINAL_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n\n if (this.speaking) {\n this.speaking = false;\n this.queue.put({ type: SpeechEventType.END_OF_SPEECH });\n }\n } else {\n this.queue.put({\n type: SpeechEventType.INTERIM_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n }\n }\n}\n"],"mappings":"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","names":["import_utils","BaseSTT","BaseSpeechStream"]}
@@ -1 +1 @@
1
- {"version":3,"file":"stt.d.ts","sourceRoot":"","sources":["../../src/inference/stt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stt.d.ts","sourceRoot":"","sources":["../../src/inference/stt.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import {} from "@livekit/rtc-node";
2
- import { WebSocket } from "ws";
2
+ import {} from "ws";
3
3
  import { APIError, APIStatusError } from "../_exceptions.js";
4
4
  import { AudioByteStream } from "../audio.js";
5
5
  import { log } from "../log.js";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/inference/stt.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { type AudioFrame } from '@livekit/rtc-node';\nimport { type RawData, WebSocket } from 'ws';\nimport { APIError, APIStatusError } from '../_exceptions.js';\nimport { AudioByteStream } from '../audio.js';\nimport { log } from '../log.js';\nimport {\n STT as BaseSTT,\n SpeechStream as BaseSpeechStream,\n type SpeechData,\n type SpeechEvent,\n SpeechEventType,\n} from '../stt/index.js';\nimport { type APIConnectOptions, DEFAULT_API_CONNECT_OPTIONS } from '../types.js';\nimport { type AudioBuffer, Event, Task, cancelAndWait, shortuuid, waitForAbort } from '../utils.js';\nimport { type AnyString, connectWs, createAccessToken } from './utils.js';\n\nexport type DeepgramModels =\n | 'deepgram'\n | 'deepgram/nova-3'\n | 'deepgram/nova-3-general'\n | 'deepgram/nova-3-medical'\n | 'deepgram/nova-2-conversationalai'\n | 'deepgram/nova-2'\n | 'deepgram/nova-2-general'\n | 'deepgram/nova-2-medical'\n | 'deepgram/nova-2-phonecall';\n\nexport type CartesiaModels = 'cartesia' | 'cartesia/ink-whisper';\n\nexport type AssemblyaiModels = 'assemblyai' | 'assemblyai/universal-streaming';\n\nexport interface CartesiaOptions {\n min_volume?: number; // default: not specified\n max_silence_duration_secs?: number; // default: not specified\n}\n\nexport interface DeepgramOptions {\n filler_words?: boolean; // default: true\n interim_results?: boolean; // default: true\n endpointing?: number; // default: 25 (ms)\n punctuate?: boolean; // default: false\n smart_format?: boolean;\n keywords?: Array<[string, number]>;\n keyterms?: string[];\n profanity_filter?: boolean;\n numerals?: boolean;\n mip_opt_out?: boolean;\n}\n\nexport interface AssemblyAIOptions {\n format_turns?: boolean; // default: false\n end_of_turn_confidence_threshold?: number; // default: 0.01\n min_end_of_turn_silence_when_confident?: number; // default: 0\n max_turn_silence?: number; // default: not specified\n keyterms_prompt?: string[]; // default: not specified\n}\n\nexport type STTLanguages =\n | 'multi'\n | 'en'\n | 'de'\n | 'es'\n | 'fr'\n | 'ja'\n | 'pt'\n | 'zh'\n | 'hi'\n | AnyString;\n\ntype _STTModels = DeepgramModels | CartesiaModels | AssemblyaiModels;\n\nexport type STTModels = _STTModels | 'auto' | AnyString;\n\nexport type ModelWithLanguage = `${_STTModels}:${STTLanguages}` | STTModels;\n\nexport type STTOptions<TModel extends STTModels> = TModel extends DeepgramModels\n ? DeepgramOptions\n : TModel extends CartesiaModels\n ? CartesiaOptions\n : TModel extends AssemblyaiModels\n ? AssemblyAIOptions\n : Record<string, unknown>;\n\nexport type STTEncoding = 'pcm_s16le';\n\nconst DEFAULT_ENCODING: STTEncoding = 'pcm_s16le';\nconst DEFAULT_SAMPLE_RATE = 16000;\nconst DEFAULT_BASE_URL = 'wss://agent-gateway.livekit.cloud/v1';\nconst DEFAULT_CANCEL_TIMEOUT = 5000;\n\nexport interface InferenceSTTOptions<TModel extends STTModels> {\n model?: TModel;\n language?: STTLanguages;\n encoding: STTEncoding;\n sampleRate: number;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: STTOptions<TModel>;\n}\n\n/**\n * Livekit Cloud Inference STT\n */\nexport class STT<TModel extends STTModels> extends BaseSTT {\n private opts: InferenceSTTOptions<TModel>;\n private streams: Set<SpeechStream<TModel>> = new Set();\n\n #logger = log();\n\n constructor(opts?: {\n model?: TModel;\n language?: STTLanguages;\n baseURL?: string;\n encoding?: STTEncoding;\n sampleRate?: number;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: STTOptions<TModel>;\n }) {\n super({ streaming: true, interimResults: true });\n\n const {\n model,\n language,\n baseURL,\n encoding = DEFAULT_ENCODING,\n sampleRate = DEFAULT_SAMPLE_RATE,\n apiKey,\n apiSecret,\n modelOptions = {} as STTOptions<TModel>,\n } = opts || {};\n\n const lkBaseURL = baseURL || process.env.LIVEKIT_INFERENCE_URL || DEFAULT_BASE_URL;\n const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY;\n if (!lkApiKey) {\n throw new Error('apiKey is required: pass apiKey or set LIVEKIT_API_KEY');\n }\n\n const lkApiSecret =\n apiSecret || process.env.LIVEKIT_INFERENCE_API_SECRET || process.env.LIVEKIT_API_SECRET;\n if (!lkApiSecret) {\n throw new Error('apiSecret is required: pass apiSecret or set LIVEKIT_API_SECRET');\n }\n\n this.opts = {\n model,\n language,\n encoding,\n sampleRate,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions,\n };\n }\n\n get label(): string {\n return 'inference.STT';\n }\n\n static fromModelString(modelString: string): STT<AnyString> {\n if (modelString.includes(':')) {\n const [model, language] = modelString.split(':') as [AnyString, STTLanguages];\n return new STT({ model, language });\n }\n return new STT({ model: modelString });\n }\n\n protected async _recognize(_: AudioBuffer): Promise<SpeechEvent> {\n throw new Error('LiveKit STT does not support batch recognition, use stream() instead');\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n\n for (const stream of this.streams) {\n stream.updateOptions(opts);\n }\n }\n\n stream(options?: {\n language?: STTLanguages | string;\n connOptions?: APIConnectOptions;\n }): SpeechStream<TModel> {\n const { language, connOptions = DEFAULT_API_CONNECT_OPTIONS } = options || {};\n const streamOpts = {\n ...this.opts,\n language: language ?? this.opts.language,\n } as InferenceSTTOptions<TModel>;\n\n const stream = new SpeechStream(this, streamOpts, connOptions);\n this.streams.add(stream);\n\n return stream;\n }\n}\n\nexport class SpeechStream<TModel extends STTModels> extends BaseSpeechStream {\n private opts: InferenceSTTOptions<TModel>;\n private requestId = shortuuid('stt_request_');\n private speaking = false;\n private speechDuration = 0;\n private reconnectEvent = new Event();\n\n #logger = log();\n\n constructor(\n sttImpl: STT<TModel>,\n opts: InferenceSTTOptions<TModel>,\n connOptions: APIConnectOptions,\n ) {\n super(sttImpl, opts.sampleRate, connOptions);\n this.opts = opts;\n }\n\n get label(): string {\n return 'inference.SpeechStream';\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n }\n\n protected async run(): Promise<void> {\n let ws: WebSocket | null = null;\n let closingWs = false;\n\n this.reconnectEvent.set();\n\n const connect = async () => {\n const params = {\n settings: {\n sample_rate: String(this.opts.sampleRate),\n encoding: this.opts.encoding,\n extra: this.opts.modelOptions,\n },\n } as Record<string, unknown>;\n\n if (this.opts.model && this.opts.model !== 'auto') {\n params.model = this.opts.model;\n }\n\n if (this.opts.language) {\n (params.settings as Record<string, unknown>).language = this.opts.language;\n }\n\n let baseURL = this.opts.baseURL;\n if (baseURL.startsWith('http://') || baseURL.startsWith('https://')) {\n baseURL = baseURL.replace('http', 'ws');\n }\n\n const token = await createAccessToken(this.opts.apiKey, this.opts.apiSecret);\n const url = `${baseURL}/stt`;\n const headers = { Authorization: `Bearer ${token}` } as Record<string, string>;\n\n const socket = await connectWs(url, headers, 10000);\n const msg = { ...params, type: 'session.create' };\n socket.send(JSON.stringify(msg));\n\n return socket;\n };\n\n const send = async (socket: WebSocket, signal: AbortSignal) => {\n const audioStream = new AudioByteStream(\n this.opts.sampleRate,\n 1,\n Math.floor(this.opts.sampleRate / 20), // 50ms\n );\n\n for await (const ev of this.input) {\n if (signal.aborted) break;\n let frames: AudioFrame[];\n\n if (ev === SpeechStream.FLUSH_SENTINEL) {\n frames = audioStream.flush();\n } else {\n const frame = ev as AudioFrame;\n frames = audioStream.write(new Int16Array(frame.data).buffer);\n }\n\n for (const frame of frames) {\n this.speechDuration += frame.samplesPerChannel / frame.sampleRate;\n const base64 = Buffer.from(frame.data.buffer).toString('base64');\n const msg = { type: 'input_audio', audio: base64 };\n socket.send(JSON.stringify(msg));\n }\n }\n\n closingWs = true;\n socket.send(JSON.stringify({ type: 'session.finalize' }));\n };\n\n const recv = async (socket: WebSocket, signal: AbortSignal) => {\n while (!this.closed && !signal.aborted) {\n const dataPromise = new Promise<string>((resolve, reject) => {\n const messageHandler = (d: RawData) => {\n resolve(d.toString());\n removeListeners();\n };\n const errorHandler = (e: Error) => {\n reject(e);\n removeListeners();\n };\n const closeHandler = (code: number) => {\n if (closingWs) {\n resolve('');\n } else {\n reject(\n new APIStatusError({\n message: 'LiveKit STT connection closed unexpectedly',\n options: { statusCode: code },\n }),\n );\n }\n removeListeners();\n };\n const removeListeners = () => {\n socket.removeListener('message', messageHandler);\n socket.removeListener('error', errorHandler);\n socket.removeListener('close', closeHandler);\n };\n socket.once('message', messageHandler);\n socket.once('error', errorHandler);\n socket.once('close', closeHandler);\n });\n\n const data = await Promise.race([dataPromise, waitForAbort(signal)]);\n\n if (!data || signal.aborted) return;\n\n const json = JSON.parse(data);\n const type = json.type as string | undefined;\n\n switch (type) {\n case 'session.created':\n case 'session.finalized':\n case 'session.closed':\n break;\n case 'interim_transcript':\n this.processTranscript(json, false);\n break;\n case 'final_transcript':\n this.processTranscript(json, true);\n break;\n case 'error':\n this.#logger.error('received error from LiveKit STT: %o', json);\n throw new APIError(`LiveKit STT returned error: ${JSON.stringify(json)}`);\n default:\n this.#logger.warn('received unexpected message from LiveKit STT: %o', json);\n break;\n }\n }\n };\n\n while (true) {\n try {\n ws = await connect();\n\n const sendTask = Task.from(async ({ signal }) => {\n await send(ws!, signal);\n });\n\n const recvTask = Task.from(async ({ signal }) => {\n await recv(ws!, signal);\n });\n\n const tasks = [sendTask, recvTask];\n const waitReconnectTask = Task.from(async ({ signal }) => {\n await Promise.race([this.reconnectEvent.wait(), waitForAbort(signal)]);\n });\n\n try {\n await Promise.race([\n Promise.all(tasks.map((task) => task.result)),\n waitReconnectTask.result,\n ]);\n\n if (!waitReconnectTask.done) break;\n this.reconnectEvent.clear();\n } finally {\n await cancelAndWait([sendTask, recvTask, waitReconnectTask], DEFAULT_CANCEL_TIMEOUT);\n }\n } finally {\n try {\n if (ws) ws.close();\n } catch {}\n }\n }\n }\n\n private processTranscript(data: Record<string, any>, isFinal: boolean) {\n const requestId = data.request_id ?? this.requestId;\n const text = data.transcript ?? '';\n const language = data.language ?? this.opts.language ?? 'en';\n\n if (!text && !isFinal) return;\n\n // We'll have a more accurate way of detecting when speech started when we have VAD\n if (!this.speaking) {\n this.speaking = true;\n this.queue.put({ type: SpeechEventType.START_OF_SPEECH });\n }\n\n const speechData: SpeechData = {\n language,\n startTime: data.start ?? 0,\n endTime: data.duration ?? 0,\n confidence: data.confidence ?? 1.0,\n text,\n };\n\n if (isFinal) {\n if (this.speechDuration > 0) {\n this.queue.put({\n type: SpeechEventType.RECOGNITION_USAGE,\n requestId,\n recognitionUsage: { audioDuration: this.speechDuration },\n });\n this.speechDuration = 0;\n }\n\n this.queue.put({\n type: SpeechEventType.FINAL_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n\n if (this.speaking) {\n this.speaking = false;\n this.queue.put({ type: SpeechEventType.END_OF_SPEECH });\n }\n } else {\n this.queue.put({\n type: SpeechEventType.INTERIM_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/inference/stt.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { type AudioFrame } from '@livekit/rtc-node';\nimport type { WebSocket } from 'ws';\nimport { type RawData } from 'ws';\nimport { APIError, APIStatusError } from '../_exceptions.js';\nimport { AudioByteStream } from '../audio.js';\nimport { log } from '../log.js';\nimport {\n STT as BaseSTT,\n SpeechStream as BaseSpeechStream,\n type SpeechData,\n type SpeechEvent,\n SpeechEventType,\n} from '../stt/index.js';\nimport { type APIConnectOptions, DEFAULT_API_CONNECT_OPTIONS } from '../types.js';\nimport { type AudioBuffer, Event, Task, cancelAndWait, shortuuid, waitForAbort } from '../utils.js';\nimport { type AnyString, connectWs, createAccessToken } from './utils.js';\n\nexport type DeepgramModels =\n | 'deepgram'\n | 'deepgram/nova-3'\n | 'deepgram/nova-3-general'\n | 'deepgram/nova-3-medical'\n | 'deepgram/nova-2-conversationalai'\n | 'deepgram/nova-2'\n | 'deepgram/nova-2-general'\n | 'deepgram/nova-2-medical'\n | 'deepgram/nova-2-phonecall';\n\nexport type CartesiaModels = 'cartesia' | 'cartesia/ink-whisper';\n\nexport type AssemblyaiModels = 'assemblyai' | 'assemblyai/universal-streaming';\n\nexport interface CartesiaOptions {\n min_volume?: number; // default: not specified\n max_silence_duration_secs?: number; // default: not specified\n}\n\nexport interface DeepgramOptions {\n filler_words?: boolean; // default: true\n interim_results?: boolean; // default: true\n endpointing?: number; // default: 25 (ms)\n punctuate?: boolean; // default: false\n smart_format?: boolean;\n keywords?: Array<[string, number]>;\n keyterms?: string[];\n profanity_filter?: boolean;\n numerals?: boolean;\n mip_opt_out?: boolean;\n}\n\nexport interface AssemblyAIOptions {\n format_turns?: boolean; // default: false\n end_of_turn_confidence_threshold?: number; // default: 0.01\n min_end_of_turn_silence_when_confident?: number; // default: 0\n max_turn_silence?: number; // default: not specified\n keyterms_prompt?: string[]; // default: not specified\n}\n\nexport type STTLanguages =\n | 'multi'\n | 'en'\n | 'de'\n | 'es'\n | 'fr'\n | 'ja'\n | 'pt'\n | 'zh'\n | 'hi'\n | AnyString;\n\ntype _STTModels = DeepgramModels | CartesiaModels | AssemblyaiModels;\n\nexport type STTModels = _STTModels | 'auto' | AnyString;\n\nexport type ModelWithLanguage = `${_STTModels}:${STTLanguages}` | STTModels;\n\nexport type STTOptions<TModel extends STTModels> = TModel extends DeepgramModels\n ? DeepgramOptions\n : TModel extends CartesiaModels\n ? CartesiaOptions\n : TModel extends AssemblyaiModels\n ? AssemblyAIOptions\n : Record<string, unknown>;\n\nexport type STTEncoding = 'pcm_s16le';\n\nconst DEFAULT_ENCODING: STTEncoding = 'pcm_s16le';\nconst DEFAULT_SAMPLE_RATE = 16000;\nconst DEFAULT_BASE_URL = 'wss://agent-gateway.livekit.cloud/v1';\nconst DEFAULT_CANCEL_TIMEOUT = 5000;\n\nexport interface InferenceSTTOptions<TModel extends STTModels> {\n model?: TModel;\n language?: STTLanguages;\n encoding: STTEncoding;\n sampleRate: number;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: STTOptions<TModel>;\n}\n\n/**\n * Livekit Cloud Inference STT\n */\nexport class STT<TModel extends STTModels> extends BaseSTT {\n private opts: InferenceSTTOptions<TModel>;\n private streams: Set<SpeechStream<TModel>> = new Set();\n\n #logger = log();\n\n constructor(opts?: {\n model?: TModel;\n language?: STTLanguages;\n baseURL?: string;\n encoding?: STTEncoding;\n sampleRate?: number;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: STTOptions<TModel>;\n }) {\n super({ streaming: true, interimResults: true });\n\n const {\n model,\n language,\n baseURL,\n encoding = DEFAULT_ENCODING,\n sampleRate = DEFAULT_SAMPLE_RATE,\n apiKey,\n apiSecret,\n modelOptions = {} as STTOptions<TModel>,\n } = opts || {};\n\n const lkBaseURL = baseURL || process.env.LIVEKIT_INFERENCE_URL || DEFAULT_BASE_URL;\n const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY;\n if (!lkApiKey) {\n throw new Error('apiKey is required: pass apiKey or set LIVEKIT_API_KEY');\n }\n\n const lkApiSecret =\n apiSecret || process.env.LIVEKIT_INFERENCE_API_SECRET || process.env.LIVEKIT_API_SECRET;\n if (!lkApiSecret) {\n throw new Error('apiSecret is required: pass apiSecret or set LIVEKIT_API_SECRET');\n }\n\n this.opts = {\n model,\n language,\n encoding,\n sampleRate,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions,\n };\n }\n\n get label(): string {\n return 'inference.STT';\n }\n\n static fromModelString(modelString: string): STT<AnyString> {\n if (modelString.includes(':')) {\n const [model, language] = modelString.split(':') as [AnyString, STTLanguages];\n return new STT({ model, language });\n }\n return new STT({ model: modelString });\n }\n\n protected async _recognize(_: AudioBuffer): Promise<SpeechEvent> {\n throw new Error('LiveKit STT does not support batch recognition, use stream() instead');\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n\n for (const stream of this.streams) {\n stream.updateOptions(opts);\n }\n }\n\n stream(options?: {\n language?: STTLanguages | string;\n connOptions?: APIConnectOptions;\n }): SpeechStream<TModel> {\n const { language, connOptions = DEFAULT_API_CONNECT_OPTIONS } = options || {};\n const streamOpts = {\n ...this.opts,\n language: language ?? this.opts.language,\n } as InferenceSTTOptions<TModel>;\n\n const stream = new SpeechStream(this, streamOpts, connOptions);\n this.streams.add(stream);\n\n return stream;\n }\n}\n\nexport class SpeechStream<TModel extends STTModels> extends BaseSpeechStream {\n private opts: InferenceSTTOptions<TModel>;\n private requestId = shortuuid('stt_request_');\n private speaking = false;\n private speechDuration = 0;\n private reconnectEvent = new Event();\n\n #logger = log();\n\n constructor(\n sttImpl: STT<TModel>,\n opts: InferenceSTTOptions<TModel>,\n connOptions: APIConnectOptions,\n ) {\n super(sttImpl, opts.sampleRate, connOptions);\n this.opts = opts;\n }\n\n get label(): string {\n return 'inference.SpeechStream';\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n }\n\n protected async run(): Promise<void> {\n let ws: WebSocket | null = null;\n let closingWs = false;\n\n this.reconnectEvent.set();\n\n const connect = async () => {\n const params = {\n settings: {\n sample_rate: String(this.opts.sampleRate),\n encoding: this.opts.encoding,\n extra: this.opts.modelOptions,\n },\n } as Record<string, unknown>;\n\n if (this.opts.model && this.opts.model !== 'auto') {\n params.model = this.opts.model;\n }\n\n if (this.opts.language) {\n (params.settings as Record<string, unknown>).language = this.opts.language;\n }\n\n let baseURL = this.opts.baseURL;\n if (baseURL.startsWith('http://') || baseURL.startsWith('https://')) {\n baseURL = baseURL.replace('http', 'ws');\n }\n\n const token = await createAccessToken(this.opts.apiKey, this.opts.apiSecret);\n const url = `${baseURL}/stt`;\n const headers = { Authorization: `Bearer ${token}` } as Record<string, string>;\n\n const socket = await connectWs(url, headers, 10000);\n const msg = { ...params, type: 'session.create' };\n socket.send(JSON.stringify(msg));\n\n return socket;\n };\n\n const send = async (socket: WebSocket, signal: AbortSignal) => {\n const audioStream = new AudioByteStream(\n this.opts.sampleRate,\n 1,\n Math.floor(this.opts.sampleRate / 20), // 50ms\n );\n\n for await (const ev of this.input) {\n if (signal.aborted) break;\n let frames: AudioFrame[];\n\n if (ev === SpeechStream.FLUSH_SENTINEL) {\n frames = audioStream.flush();\n } else {\n const frame = ev as AudioFrame;\n frames = audioStream.write(new Int16Array(frame.data).buffer);\n }\n\n for (const frame of frames) {\n this.speechDuration += frame.samplesPerChannel / frame.sampleRate;\n const base64 = Buffer.from(frame.data.buffer).toString('base64');\n const msg = { type: 'input_audio', audio: base64 };\n socket.send(JSON.stringify(msg));\n }\n }\n\n closingWs = true;\n socket.send(JSON.stringify({ type: 'session.finalize' }));\n };\n\n const recv = async (socket: WebSocket, signal: AbortSignal) => {\n while (!this.closed && !signal.aborted) {\n const dataPromise = new Promise<string>((resolve, reject) => {\n const messageHandler = (d: RawData) => {\n resolve(d.toString());\n removeListeners();\n };\n const errorHandler = (e: Error) => {\n reject(e);\n removeListeners();\n };\n const closeHandler = (code: number) => {\n if (closingWs) {\n resolve('');\n } else {\n reject(\n new APIStatusError({\n message: 'LiveKit STT connection closed unexpectedly',\n options: { statusCode: code },\n }),\n );\n }\n removeListeners();\n };\n const removeListeners = () => {\n socket.removeListener('message', messageHandler);\n socket.removeListener('error', errorHandler);\n socket.removeListener('close', closeHandler);\n };\n socket.once('message', messageHandler);\n socket.once('error', errorHandler);\n socket.once('close', closeHandler);\n });\n\n const data = await Promise.race([dataPromise, waitForAbort(signal)]);\n\n if (!data || signal.aborted) return;\n\n const json = JSON.parse(data);\n const type = json.type as string | undefined;\n\n switch (type) {\n case 'session.created':\n case 'session.finalized':\n case 'session.closed':\n break;\n case 'interim_transcript':\n this.processTranscript(json, false);\n break;\n case 'final_transcript':\n this.processTranscript(json, true);\n break;\n case 'error':\n this.#logger.error('received error from LiveKit STT: %o', json);\n throw new APIError(`LiveKit STT returned error: ${JSON.stringify(json)}`);\n default:\n this.#logger.warn('received unexpected message from LiveKit STT: %o', json);\n break;\n }\n }\n };\n\n while (true) {\n try {\n ws = await connect();\n\n const sendTask = Task.from(async ({ signal }) => {\n await send(ws!, signal);\n });\n\n const recvTask = Task.from(async ({ signal }) => {\n await recv(ws!, signal);\n });\n\n const tasks = [sendTask, recvTask];\n const waitReconnectTask = Task.from(async ({ signal }) => {\n await Promise.race([this.reconnectEvent.wait(), waitForAbort(signal)]);\n });\n\n try {\n await Promise.race([\n Promise.all(tasks.map((task) => task.result)),\n waitReconnectTask.result,\n ]);\n\n if (!waitReconnectTask.done) break;\n this.reconnectEvent.clear();\n } finally {\n await cancelAndWait([sendTask, recvTask, waitReconnectTask], DEFAULT_CANCEL_TIMEOUT);\n }\n } finally {\n try {\n if (ws) ws.close();\n } catch {}\n }\n }\n }\n\n private processTranscript(data: Record<string, any>, isFinal: boolean) {\n const requestId = data.request_id ?? this.requestId;\n const text = data.transcript ?? '';\n const language = data.language ?? this.opts.language ?? 'en';\n\n if (!text && !isFinal) return;\n\n // We'll have a more accurate way of detecting when speech started when we have VAD\n if (!this.speaking) {\n this.speaking = true;\n this.queue.put({ type: SpeechEventType.START_OF_SPEECH });\n }\n\n const speechData: SpeechData = {\n language,\n startTime: data.start ?? 0,\n endTime: data.duration ?? 0,\n confidence: data.confidence ?? 1.0,\n text,\n };\n\n if (isFinal) {\n if (this.speechDuration > 0) {\n this.queue.put({\n type: SpeechEventType.RECOGNITION_USAGE,\n requestId,\n recognitionUsage: { audioDuration: this.speechDuration },\n });\n this.speechDuration = 0;\n }\n\n this.queue.put({\n type: SpeechEventType.FINAL_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n\n if (this.speaking) {\n this.speaking = false;\n this.queue.put({ type: SpeechEventType.END_OF_SPEECH });\n }\n } else {\n this.queue.put({\n type: SpeechEventType.INTERIM_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n }\n }\n}\n"],"mappings":"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","names":[]}