@livekit/agents 1.0.34 → 1.0.35

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 (57) hide show
  1. package/dist/cli.cjs.map +1 -1
  2. package/dist/inference/api_protos.d.cts +4 -4
  3. package/dist/inference/api_protos.d.ts +4 -4
  4. package/dist/inference/llm.cjs +30 -3
  5. package/dist/inference/llm.cjs.map +1 -1
  6. package/dist/inference/llm.d.cts +3 -1
  7. package/dist/inference/llm.d.ts +3 -1
  8. package/dist/inference/llm.d.ts.map +1 -1
  9. package/dist/inference/llm.js +30 -3
  10. package/dist/inference/llm.js.map +1 -1
  11. package/dist/ipc/inference_proc_executor.cjs.map +1 -1
  12. package/dist/ipc/job_proc_executor.cjs.map +1 -1
  13. package/dist/ipc/job_proc_lazy_main.cjs +1 -1
  14. package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
  15. package/dist/ipc/job_proc_lazy_main.js +1 -1
  16. package/dist/ipc/job_proc_lazy_main.js.map +1 -1
  17. package/dist/llm/chat_context.cjs +20 -2
  18. package/dist/llm/chat_context.cjs.map +1 -1
  19. package/dist/llm/chat_context.d.cts +9 -0
  20. package/dist/llm/chat_context.d.ts +9 -0
  21. package/dist/llm/chat_context.d.ts.map +1 -1
  22. package/dist/llm/chat_context.js +20 -2
  23. package/dist/llm/chat_context.js.map +1 -1
  24. package/dist/llm/llm.cjs.map +1 -1
  25. package/dist/llm/llm.d.cts +1 -0
  26. package/dist/llm/llm.d.ts +1 -0
  27. package/dist/llm/llm.d.ts.map +1 -1
  28. package/dist/llm/llm.js.map +1 -1
  29. package/dist/llm/provider_format/openai.cjs +43 -20
  30. package/dist/llm/provider_format/openai.cjs.map +1 -1
  31. package/dist/llm/provider_format/openai.d.ts.map +1 -1
  32. package/dist/llm/provider_format/openai.js +43 -20
  33. package/dist/llm/provider_format/openai.js.map +1 -1
  34. package/dist/llm/provider_format/openai.test.cjs +35 -0
  35. package/dist/llm/provider_format/openai.test.cjs.map +1 -1
  36. package/dist/llm/provider_format/openai.test.js +35 -0
  37. package/dist/llm/provider_format/openai.test.js.map +1 -1
  38. package/dist/llm/provider_format/utils.cjs +1 -1
  39. package/dist/llm/provider_format/utils.cjs.map +1 -1
  40. package/dist/llm/provider_format/utils.d.ts.map +1 -1
  41. package/dist/llm/provider_format/utils.js +1 -1
  42. package/dist/llm/provider_format/utils.js.map +1 -1
  43. package/dist/voice/background_audio.cjs.map +1 -1
  44. package/dist/voice/generation.cjs +2 -1
  45. package/dist/voice/generation.cjs.map +1 -1
  46. package/dist/voice/generation.d.ts.map +1 -1
  47. package/dist/voice/generation.js +2 -1
  48. package/dist/voice/generation.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/inference/llm.ts +42 -3
  51. package/src/ipc/job_proc_lazy_main.ts +1 -1
  52. package/src/llm/chat_context.ts +32 -2
  53. package/src/llm/llm.ts +1 -0
  54. package/src/llm/provider_format/openai.test.ts +40 -0
  55. package/src/llm/provider_format/openai.ts +46 -19
  56. package/src/llm/provider_format/utils.ts +5 -1
  57. package/src/voice/generation.ts +1 -0
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 { 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":[]}
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.5.6_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":[]}
@@ -10,18 +10,18 @@ export declare const ttsSessionCreateEventSchema: z.ZodObject<{
10
10
  transcript: z.ZodOptional<z.ZodString>;
11
11
  }, "strip", z.ZodTypeAny, {
12
12
  type: "session.create";
13
+ extra: Record<string, unknown>;
13
14
  sample_rate: string;
14
15
  encoding: string;
15
- extra: Record<string, unknown>;
16
16
  language?: string | undefined;
17
17
  model?: string | undefined;
18
18
  transcript?: string | undefined;
19
19
  voice?: string | undefined;
20
20
  }, {
21
21
  type: "session.create";
22
+ extra: Record<string, unknown>;
22
23
  sample_rate: string;
23
24
  encoding: string;
24
- extra: Record<string, unknown>;
25
25
  language?: string | undefined;
26
26
  model?: string | undefined;
27
27
  transcript?: string | undefined;
@@ -118,18 +118,18 @@ export declare const ttsClientEventSchema: z.ZodDiscriminatedUnion<"type", [z.Zo
118
118
  transcript: z.ZodOptional<z.ZodString>;
119
119
  }, "strip", z.ZodTypeAny, {
120
120
  type: "session.create";
121
+ extra: Record<string, unknown>;
121
122
  sample_rate: string;
122
123
  encoding: string;
123
- extra: Record<string, unknown>;
124
124
  language?: string | undefined;
125
125
  model?: string | undefined;
126
126
  transcript?: string | undefined;
127
127
  voice?: string | undefined;
128
128
  }, {
129
129
  type: "session.create";
130
+ extra: Record<string, unknown>;
130
131
  sample_rate: string;
131
132
  encoding: string;
132
- extra: Record<string, unknown>;
133
133
  language?: string | undefined;
134
134
  model?: string | undefined;
135
135
  transcript?: string | undefined;
@@ -10,18 +10,18 @@ export declare const ttsSessionCreateEventSchema: z.ZodObject<{
10
10
  transcript: z.ZodOptional<z.ZodString>;
11
11
  }, "strip", z.ZodTypeAny, {
12
12
  type: "session.create";
13
+ extra: Record<string, unknown>;
13
14
  sample_rate: string;
14
15
  encoding: string;
15
- extra: Record<string, unknown>;
16
16
  language?: string | undefined;
17
17
  model?: string | undefined;
18
18
  transcript?: string | undefined;
19
19
  voice?: string | undefined;
20
20
  }, {
21
21
  type: "session.create";
22
+ extra: Record<string, unknown>;
22
23
  sample_rate: string;
23
24
  encoding: string;
24
- extra: Record<string, unknown>;
25
25
  language?: string | undefined;
26
26
  model?: string | undefined;
27
27
  transcript?: string | undefined;
@@ -118,18 +118,18 @@ export declare const ttsClientEventSchema: z.ZodDiscriminatedUnion<"type", [z.Zo
118
118
  transcript: z.ZodOptional<z.ZodString>;
119
119
  }, "strip", z.ZodTypeAny, {
120
120
  type: "session.create";
121
+ extra: Record<string, unknown>;
121
122
  sample_rate: string;
122
123
  encoding: string;
123
- extra: Record<string, unknown>;
124
124
  language?: string | undefined;
125
125
  model?: string | undefined;
126
126
  transcript?: string | undefined;
127
127
  voice?: string | undefined;
128
128
  }, {
129
129
  type: "session.create";
130
+ extra: Record<string, unknown>;
130
131
  sample_rate: string;
131
132
  encoding: string;
132
- extra: Record<string, unknown>;
133
133
  language?: string | undefined;
134
134
  model?: string | undefined;
135
135
  transcript?: string | undefined;
@@ -132,6 +132,7 @@ class LLMStream extends llm.LLMStream {
132
132
  toolIndex;
133
133
  fncName;
134
134
  fncRawArguments;
135
+ toolExtra;
135
136
  constructor(llm2, {
136
137
  model,
137
138
  provider,
@@ -157,6 +158,7 @@ class LLMStream extends llm.LLMStream {
157
158
  var _a;
158
159
  let retryable = true;
159
160
  this.toolCallId = this.fncName = this.fncRawArguments = this.toolIndex = void 0;
161
+ this.toolExtra = void 0;
160
162
  try {
161
163
  const messages = await this.chatCtx.toProviderFormat(
162
164
  this.providerFmt
@@ -265,12 +267,15 @@ class LLMStream extends llm.LLMStream {
265
267
  if (this.toolCallId && tool.id && tool.index !== this.toolIndex) {
266
268
  callChunk = this.createRunningToolCallChunk(id, delta);
267
269
  this.toolCallId = this.fncName = this.fncRawArguments = void 0;
270
+ this.toolExtra = void 0;
268
271
  }
269
272
  if (tool.function.name) {
270
273
  this.toolIndex = tool.index;
271
274
  this.toolCallId = tool.id;
272
275
  this.fncName = tool.function.name;
273
276
  this.fncRawArguments = tool.function.arguments || "";
277
+ this.toolExtra = // eslint-disable-next-line @typescript-eslint/no-explicit-any
278
+ tool.extra_content ?? void 0;
274
279
  } else if (tool.function.arguments) {
275
280
  this.fncRawArguments = (this.fncRawArguments || "") + tool.function.arguments;
276
281
  }
@@ -282,35 +287,57 @@ class LLMStream extends llm.LLMStream {
282
287
  if (choice.finish_reason && ["tool_calls", "stop"].includes(choice.finish_reason) && this.toolCallId !== void 0) {
283
288
  const callChunk = this.createRunningToolCallChunk(id, delta);
284
289
  this.toolCallId = this.fncName = this.fncRawArguments = void 0;
290
+ this.toolExtra = void 0;
285
291
  return callChunk;
286
292
  }
287
- if (!delta.content) {
293
+ const deltaExtra = (
294
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
295
+ delta.extra_content ?? void 0
296
+ );
297
+ if (!delta.content && !deltaExtra) {
288
298
  return void 0;
289
299
  }
290
300
  return {
291
301
  id,
292
302
  delta: {
293
303
  role: "assistant",
294
- content: delta.content
304
+ content: delta.content || void 0,
305
+ extra: deltaExtra
295
306
  }
296
307
  };
297
308
  }
298
309
  createRunningToolCallChunk(id, delta) {
310
+ const toolExtra = this.toolExtra ? { ...this.toolExtra } : {};
311
+ const thoughtSignature = this.extractThoughtSignature(toolExtra);
312
+ const deltaExtra = (
313
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
314
+ delta.extra_content ?? void 0
315
+ );
299
316
  return {
300
317
  id,
301
318
  delta: {
302
319
  role: "assistant",
303
320
  content: delta.content || void 0,
321
+ extra: deltaExtra,
304
322
  toolCalls: [
305
323
  llm.FunctionCall.create({
306
324
  callId: this.toolCallId || "",
307
325
  name: this.fncName || "",
308
- args: this.fncRawArguments || ""
326
+ args: this.fncRawArguments || "",
327
+ extra: toolExtra,
328
+ thoughtSignature
309
329
  })
310
330
  ]
311
331
  }
312
332
  };
313
333
  }
334
+ extractThoughtSignature(extra) {
335
+ const googleExtra = extra == null ? void 0 : extra.google;
336
+ if (googleExtra && typeof googleExtra === "object") {
337
+ return googleExtra.thoughtSignature || googleExtra.thought_signature;
338
+ }
339
+ return void 0;
340
+ }
314
341
  }
315
342
  // Annotate the CommonJS export names for ESM import in node:
316
343
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/inference/llm.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport OpenAI from 'openai';\nimport {\n APIConnectionError,\n APIStatusError,\n APITimeoutError,\n DEFAULT_API_CONNECT_OPTIONS,\n type Expand,\n toError,\n} from '../index.js';\nimport * as llm from '../llm/index.js';\nimport type { APIConnectOptions } from '../types.js';\nimport { type AnyString, createAccessToken } from './utils.js';\n\nconst DEFAULT_BASE_URL = 'https://agent-gateway.livekit.cloud/v1';\n\nexport type OpenAIModels =\n | 'openai/gpt-5'\n | 'openai/gpt-5-mini'\n | 'openai/gpt-5-nano'\n | 'openai/gpt-4.1'\n | 'openai/gpt-4.1-mini'\n | 'openai/gpt-4.1-nano'\n | 'openai/gpt-4o'\n | 'openai/gpt-4o-mini'\n | 'openai/gpt-oss-120b';\n\nexport type GoogleModels = 'google/gemini-2.0-flash-lite';\n\nexport type QwenModels = 'qwen/qwen3-235b-a22b-instruct';\n\nexport type KimiModels = 'moonshotai/kimi-k2-instruct';\n\nexport type DeepSeekModels = 'deepseek-ai/deepseek-v3';\n\ntype ChatCompletionPredictionContentParam =\n Expand<OpenAI.Chat.Completions.ChatCompletionPredictionContent>;\ntype WebSearchOptions = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams.WebSearchOptions>;\ntype ToolChoice = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams['tool_choice']>;\ntype Verbosity = 'low' | 'medium' | 'high';\n\nexport interface ChatCompletionOptions extends Record<string, unknown> {\n frequency_penalty?: number;\n logit_bias?: Record<string, number>;\n logprobs?: boolean;\n max_completion_tokens?: number;\n max_tokens?: number;\n metadata?: Record<string, string>;\n modalities?: Array<'text' | 'audio'>;\n n?: number;\n parallel_tool_calls?: boolean;\n prediction?: ChatCompletionPredictionContentParam | null;\n presence_penalty?: number;\n prompt_cache_key?: string;\n reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high';\n safety_identifier?: string;\n seed?: number;\n service_tier?: 'auto' | 'default' | 'flex' | 'scale' | 'priority';\n stop?: string | string[];\n store?: boolean;\n temperature?: number;\n top_logprobs?: number;\n top_p?: number;\n user?: string;\n verbosity?: Verbosity;\n web_search_options?: WebSearchOptions;\n\n // livekit-typed arguments\n tool_choice?: ToolChoice;\n // TODO(brian): support response format\n // response_format?: OpenAI.Chat.Completions.ChatCompletionCreateParams['response_format']\n}\n\nexport type LLMModels =\n | OpenAIModels\n | GoogleModels\n | QwenModels\n | KimiModels\n | DeepSeekModels\n | AnyString;\n\nexport interface InferenceLLMOptions {\n model: LLMModels;\n provider?: string;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: ChatCompletionOptions;\n strictToolSchema?: boolean;\n}\n\nexport interface GatewayOptions {\n apiKey: string;\n apiSecret: string;\n}\n\n/**\n * Livekit Cloud Inference LLM\n */\nexport class LLM extends llm.LLM {\n private client: OpenAI;\n private opts: InferenceLLMOptions;\n\n constructor(opts: {\n model: LLMModels;\n provider?: string;\n baseURL?: string;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: InferenceLLMOptions['modelOptions'];\n strictToolSchema?: boolean;\n }) {\n super();\n\n const {\n model,\n provider,\n baseURL,\n apiKey,\n apiSecret,\n modelOptions,\n strictToolSchema = false,\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 provider,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions: modelOptions || {},\n strictToolSchema,\n };\n\n this.client = new OpenAI({\n baseURL: this.opts.baseURL,\n apiKey: '', // leave a temporary empty string to avoid OpenAI complain about missing key\n });\n }\n\n label(): string {\n return 'inference.LLM';\n }\n\n get model(): string {\n return this.opts.model;\n }\n\n static fromModelString(modelString: string): LLM {\n return new LLM({ model: modelString });\n }\n\n chat({\n chatCtx,\n toolCtx,\n connOptions = DEFAULT_API_CONNECT_OPTIONS,\n parallelToolCalls,\n toolChoice,\n // TODO(AJS-270): Add response_format parameter support\n extraKwargs,\n }: {\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n connOptions?: APIConnectOptions;\n parallelToolCalls?: boolean;\n toolChoice?: llm.ToolChoice;\n // TODO(AJS-270): Add responseFormat parameter\n extraKwargs?: Record<string, unknown>;\n }): LLMStream {\n let modelOptions: Record<string, unknown> = { ...(extraKwargs || {}) };\n\n parallelToolCalls =\n parallelToolCalls !== undefined\n ? parallelToolCalls\n : this.opts.modelOptions.parallel_tool_calls;\n\n if (toolCtx && Object.keys(toolCtx).length > 0 && parallelToolCalls !== undefined) {\n modelOptions.parallel_tool_calls = parallelToolCalls;\n }\n\n toolChoice =\n toolChoice !== undefined\n ? toolChoice\n : (this.opts.modelOptions.tool_choice as llm.ToolChoice | undefined);\n\n if (toolChoice) {\n modelOptions.tool_choice = toolChoice as ToolChoice;\n }\n\n // TODO(AJS-270): Add response_format support here\n\n modelOptions = { ...modelOptions, ...this.opts.modelOptions };\n\n return new LLMStream(this, {\n model: this.opts.model,\n provider: this.opts.provider,\n client: this.client,\n chatCtx,\n toolCtx,\n connOptions,\n modelOptions,\n strictToolSchema: this.opts.strictToolSchema ?? false, // default to false if not set\n gatewayOptions: {\n apiKey: this.opts.apiKey,\n apiSecret: this.opts.apiSecret,\n },\n });\n }\n}\n\nexport class LLMStream extends llm.LLMStream {\n private model: LLMModels;\n private provider?: string;\n private providerFmt: llm.ProviderFormat;\n private client: OpenAI;\n private modelOptions: Record<string, unknown>;\n private strictToolSchema: boolean;\n\n private gatewayOptions?: GatewayOptions;\n private toolCallId?: string;\n private toolIndex?: number;\n private fncName?: string;\n private fncRawArguments?: string;\n\n constructor(\n llm: LLM,\n {\n model,\n provider,\n client,\n chatCtx,\n toolCtx,\n gatewayOptions,\n connOptions,\n modelOptions,\n providerFmt,\n strictToolSchema,\n }: {\n model: LLMModels;\n provider?: string;\n client: OpenAI;\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n gatewayOptions?: GatewayOptions;\n connOptions: APIConnectOptions;\n modelOptions: Record<string, unknown>;\n providerFmt?: llm.ProviderFormat;\n strictToolSchema: boolean;\n },\n ) {\n super(llm, { chatCtx, toolCtx, connOptions });\n this.client = client;\n this.gatewayOptions = gatewayOptions;\n this.provider = provider;\n this.providerFmt = providerFmt || 'openai';\n this.modelOptions = modelOptions;\n this.model = model;\n this.strictToolSchema = strictToolSchema;\n }\n\n protected async run(): Promise<void> {\n // current function call that we're waiting for full completion (args are streamed)\n // (defined inside the run method to make sure the state is reset for each run/attempt)\n let retryable = true;\n this.toolCallId = this.fncName = this.fncRawArguments = this.toolIndex = undefined;\n\n try {\n const messages = (await this.chatCtx.toProviderFormat(\n this.providerFmt,\n )) as OpenAI.ChatCompletionMessageParam[];\n\n const tools = this.toolCtx\n ? Object.entries(this.toolCtx).map(([name, func]) => {\n const oaiParams = {\n type: 'function' as const,\n function: {\n name,\n description: func.description,\n parameters: llm.toJsonSchema(\n func.parameters,\n true,\n this.strictToolSchema,\n ) as unknown as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function']['parameters'],\n } as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function'],\n };\n\n if (this.strictToolSchema) {\n oaiParams.function.strict = true;\n }\n\n return oaiParams;\n })\n : undefined;\n\n const requestOptions: Record<string, unknown> = { ...this.modelOptions };\n if (!tools) {\n delete requestOptions.tool_choice;\n }\n\n // Dynamically set the access token for the LiveKit Agent Gateway API\n if (this.gatewayOptions) {\n this.client.apiKey = await createAccessToken(\n this.gatewayOptions.apiKey,\n this.gatewayOptions.apiSecret,\n );\n }\n\n if (this.provider) {\n const extraHeaders = requestOptions.extra_headers\n ? (requestOptions.extra_headers as Record<string, string>)\n : {};\n extraHeaders['X-LiveKit-Inference-Provider'] = this.provider;\n requestOptions.extra_headers = extraHeaders;\n }\n\n const stream = await this.client.chat.completions.create(\n {\n model: this.model,\n messages,\n tools,\n stream: true,\n stream_options: { include_usage: true },\n ...requestOptions,\n },\n {\n timeout: this.connOptions.timeoutMs,\n },\n );\n\n for await (const chunk of stream) {\n for (const choice of chunk.choices) {\n if (this.abortController.signal.aborted) {\n break;\n }\n const chatChunk = this.parseChoice(chunk.id, choice);\n if (chatChunk) {\n retryable = false;\n this.queue.put(chatChunk);\n }\n }\n\n if (chunk.usage) {\n const usage = chunk.usage;\n retryable = false;\n this.queue.put({\n id: chunk.id,\n usage: {\n completionTokens: usage.completion_tokens,\n promptTokens: usage.prompt_tokens,\n promptCachedTokens: usage.prompt_tokens_details?.cached_tokens || 0,\n totalTokens: usage.total_tokens,\n },\n });\n }\n }\n } catch (error) {\n if (error instanceof OpenAI.APIConnectionTimeoutError) {\n throw new APITimeoutError({ options: { retryable } });\n } else if (error instanceof OpenAI.APIError) {\n throw new APIStatusError({\n message: error.message,\n options: {\n statusCode: error.status,\n body: error.error,\n requestId: error.requestID,\n retryable,\n },\n });\n } else {\n throw new APIConnectionError({\n message: toError(error).message,\n options: { retryable },\n });\n }\n }\n }\n\n private parseChoice(\n id: string,\n choice: OpenAI.ChatCompletionChunk.Choice,\n ): llm.ChatChunk | undefined {\n const delta = choice.delta;\n\n // https://github.com/livekit/agents/issues/688\n // the delta can be None when using Azure OpenAI (content filtering)\n if (delta === undefined) return undefined;\n\n if (delta.tool_calls) {\n // check if we have functions to calls\n for (const tool of delta.tool_calls) {\n if (!tool.function) {\n continue; // oai may add other tools in the future\n }\n\n /**\n * The way OpenAI streams tool calls is a bit tricky.\n *\n * For any new tool call, it first emits a delta tool call with id, and function name,\n * the rest of the delta chunks will only stream the remaining arguments string,\n * until a new tool call is started or the tool call is finished.\n * See below for an example.\n *\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role='assistant', tool_calls=None), finish_reason=None, index=0, logprobs=None)\n * [ChoiceDeltaToolCall(index=0, id='call_LaVeHWUHpef9K1sd5UO8TtLg', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"P', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='aris\\}', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id='call_ThU4OmMdQXnnVmpXGOCknXIB', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"T', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='okyo', name=None), type=None)]\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role=None, tool_calls=None), finish_reason='tool_calls', index=0, logprobs=None)\n */\n let callChunk: llm.ChatChunk | undefined;\n // If we have a previous tool call and this is a new one, emit the previous\n if (this.toolCallId && tool.id && tool.index !== this.toolIndex) {\n callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n }\n\n // Start or continue building the current tool call\n if (tool.function.name) {\n this.toolIndex = tool.index;\n this.toolCallId = tool.id;\n this.fncName = tool.function.name;\n this.fncRawArguments = tool.function.arguments || '';\n } else if (tool.function.arguments) {\n this.fncRawArguments = (this.fncRawArguments || '') + tool.function.arguments;\n }\n\n if (callChunk) {\n return callChunk;\n }\n }\n }\n\n // If we're done with tool calls, emit the final one\n if (\n choice.finish_reason &&\n ['tool_calls', 'stop'].includes(choice.finish_reason) &&\n this.toolCallId !== undefined\n ) {\n const callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n return callChunk;\n }\n\n // Regular content message\n if (!delta.content) {\n return undefined;\n }\n\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content,\n },\n };\n }\n\n private createRunningToolCallChunk(\n id: string,\n delta: OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta,\n ): llm.ChatChunk {\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content || undefined,\n toolCalls: [\n llm.FunctionCall.create({\n callId: this.toolCallId || '',\n name: this.fncName || '',\n args: this.fncRawArguments || '',\n }),\n ],\n },\n };\n }\n}\n"],"mappings":"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","names":["OpenAI","llm"]}
1
+ {"version":3,"sources":["../../src/inference/llm.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport OpenAI from 'openai';\nimport {\n APIConnectionError,\n APIStatusError,\n APITimeoutError,\n DEFAULT_API_CONNECT_OPTIONS,\n type Expand,\n toError,\n} from '../index.js';\nimport * as llm from '../llm/index.js';\nimport type { APIConnectOptions } from '../types.js';\nimport { type AnyString, createAccessToken } from './utils.js';\n\nconst DEFAULT_BASE_URL = 'https://agent-gateway.livekit.cloud/v1';\n\nexport type OpenAIModels =\n | 'openai/gpt-5'\n | 'openai/gpt-5-mini'\n | 'openai/gpt-5-nano'\n | 'openai/gpt-4.1'\n | 'openai/gpt-4.1-mini'\n | 'openai/gpt-4.1-nano'\n | 'openai/gpt-4o'\n | 'openai/gpt-4o-mini'\n | 'openai/gpt-oss-120b';\n\nexport type GoogleModels =\n | 'google/gemini-3-pro-preview'\n | 'google/gemini-3-flash-preview'\n | 'google/gemini-2.5-pro'\n | 'google/gemini-2.5-flash'\n | 'google/gemini-2.5-flash-lite'\n | 'google/gemini-2.0-flash'\n | 'google/gemini-2.0-flash-lite';\n\nexport type QwenModels = 'qwen/qwen3-235b-a22b-instruct';\n\nexport type KimiModels = 'moonshotai/kimi-k2-instruct';\n\nexport type DeepSeekModels = 'deepseek-ai/deepseek-v3';\n\ntype ChatCompletionPredictionContentParam =\n Expand<OpenAI.Chat.Completions.ChatCompletionPredictionContent>;\ntype WebSearchOptions = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams.WebSearchOptions>;\ntype ToolChoice = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams['tool_choice']>;\ntype Verbosity = 'low' | 'medium' | 'high';\n\nexport interface ChatCompletionOptions extends Record<string, unknown> {\n frequency_penalty?: number;\n logit_bias?: Record<string, number>;\n logprobs?: boolean;\n max_completion_tokens?: number;\n max_tokens?: number;\n metadata?: Record<string, string>;\n modalities?: Array<'text' | 'audio'>;\n n?: number;\n parallel_tool_calls?: boolean;\n prediction?: ChatCompletionPredictionContentParam | null;\n presence_penalty?: number;\n prompt_cache_key?: string;\n reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high';\n safety_identifier?: string;\n seed?: number;\n service_tier?: 'auto' | 'default' | 'flex' | 'scale' | 'priority';\n stop?: string | string[];\n store?: boolean;\n temperature?: number;\n top_logprobs?: number;\n top_p?: number;\n user?: string;\n verbosity?: Verbosity;\n web_search_options?: WebSearchOptions;\n\n // livekit-typed arguments\n tool_choice?: ToolChoice;\n // TODO(brian): support response format\n // response_format?: OpenAI.Chat.Completions.ChatCompletionCreateParams['response_format']\n}\n\nexport type LLMModels =\n | OpenAIModels\n | GoogleModels\n | QwenModels\n | KimiModels\n | DeepSeekModels\n | AnyString;\n\nexport interface InferenceLLMOptions {\n model: LLMModels;\n provider?: string;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: ChatCompletionOptions;\n strictToolSchema?: boolean;\n}\n\nexport interface GatewayOptions {\n apiKey: string;\n apiSecret: string;\n}\n\n/**\n * Livekit Cloud Inference LLM\n */\nexport class LLM extends llm.LLM {\n private client: OpenAI;\n private opts: InferenceLLMOptions;\n\n constructor(opts: {\n model: LLMModels;\n provider?: string;\n baseURL?: string;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: InferenceLLMOptions['modelOptions'];\n strictToolSchema?: boolean;\n }) {\n super();\n\n const {\n model,\n provider,\n baseURL,\n apiKey,\n apiSecret,\n modelOptions,\n strictToolSchema = false,\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 provider,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions: modelOptions || {},\n strictToolSchema,\n };\n\n this.client = new OpenAI({\n baseURL: this.opts.baseURL,\n apiKey: '', // leave a temporary empty string to avoid OpenAI complain about missing key\n });\n }\n\n label(): string {\n return 'inference.LLM';\n }\n\n get model(): string {\n return this.opts.model;\n }\n\n static fromModelString(modelString: string): LLM {\n return new LLM({ model: modelString });\n }\n\n chat({\n chatCtx,\n toolCtx,\n connOptions = DEFAULT_API_CONNECT_OPTIONS,\n parallelToolCalls,\n toolChoice,\n // TODO(AJS-270): Add response_format parameter support\n extraKwargs,\n }: {\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n connOptions?: APIConnectOptions;\n parallelToolCalls?: boolean;\n toolChoice?: llm.ToolChoice;\n // TODO(AJS-270): Add responseFormat parameter\n extraKwargs?: Record<string, unknown>;\n }): LLMStream {\n let modelOptions: Record<string, unknown> = { ...(extraKwargs || {}) };\n\n parallelToolCalls =\n parallelToolCalls !== undefined\n ? parallelToolCalls\n : this.opts.modelOptions.parallel_tool_calls;\n\n if (toolCtx && Object.keys(toolCtx).length > 0 && parallelToolCalls !== undefined) {\n modelOptions.parallel_tool_calls = parallelToolCalls;\n }\n\n toolChoice =\n toolChoice !== undefined\n ? toolChoice\n : (this.opts.modelOptions.tool_choice as llm.ToolChoice | undefined);\n\n if (toolChoice) {\n modelOptions.tool_choice = toolChoice as ToolChoice;\n }\n\n // TODO(AJS-270): Add response_format support here\n\n modelOptions = { ...modelOptions, ...this.opts.modelOptions };\n\n return new LLMStream(this, {\n model: this.opts.model,\n provider: this.opts.provider,\n client: this.client,\n chatCtx,\n toolCtx,\n connOptions,\n modelOptions,\n strictToolSchema: this.opts.strictToolSchema ?? false, // default to false if not set\n gatewayOptions: {\n apiKey: this.opts.apiKey,\n apiSecret: this.opts.apiSecret,\n },\n });\n }\n}\n\nexport class LLMStream extends llm.LLMStream {\n private model: LLMModels;\n private provider?: string;\n private providerFmt: llm.ProviderFormat;\n private client: OpenAI;\n private modelOptions: Record<string, unknown>;\n private strictToolSchema: boolean;\n\n private gatewayOptions?: GatewayOptions;\n private toolCallId?: string;\n private toolIndex?: number;\n private fncName?: string;\n private fncRawArguments?: string;\n private toolExtra?: Record<string, unknown>;\n\n constructor(\n llm: LLM,\n {\n model,\n provider,\n client,\n chatCtx,\n toolCtx,\n gatewayOptions,\n connOptions,\n modelOptions,\n providerFmt,\n strictToolSchema,\n }: {\n model: LLMModels;\n provider?: string;\n client: OpenAI;\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n gatewayOptions?: GatewayOptions;\n connOptions: APIConnectOptions;\n modelOptions: Record<string, unknown>;\n providerFmt?: llm.ProviderFormat;\n strictToolSchema: boolean;\n },\n ) {\n super(llm, { chatCtx, toolCtx, connOptions });\n this.client = client;\n this.gatewayOptions = gatewayOptions;\n this.provider = provider;\n this.providerFmt = providerFmt || 'openai';\n this.modelOptions = modelOptions;\n this.model = model;\n this.strictToolSchema = strictToolSchema;\n }\n\n protected async run(): Promise<void> {\n // current function call that we're waiting for full completion (args are streamed)\n // (defined inside the run method to make sure the state is reset for each run/attempt)\n let retryable = true;\n this.toolCallId = this.fncName = this.fncRawArguments = this.toolIndex = undefined;\n this.toolExtra = undefined;\n\n try {\n const messages = (await this.chatCtx.toProviderFormat(\n this.providerFmt,\n )) as OpenAI.ChatCompletionMessageParam[];\n\n const tools = this.toolCtx\n ? Object.entries(this.toolCtx).map(([name, func]) => {\n const oaiParams = {\n type: 'function' as const,\n function: {\n name,\n description: func.description,\n parameters: llm.toJsonSchema(\n func.parameters,\n true,\n this.strictToolSchema,\n ) as unknown as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function']['parameters'],\n } as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function'],\n };\n\n if (this.strictToolSchema) {\n oaiParams.function.strict = true;\n }\n\n return oaiParams;\n })\n : undefined;\n\n const requestOptions: Record<string, unknown> = { ...this.modelOptions };\n if (!tools) {\n delete requestOptions.tool_choice;\n }\n\n // Dynamically set the access token for the LiveKit Agent Gateway API\n if (this.gatewayOptions) {\n this.client.apiKey = await createAccessToken(\n this.gatewayOptions.apiKey,\n this.gatewayOptions.apiSecret,\n );\n }\n\n if (this.provider) {\n const extraHeaders = requestOptions.extra_headers\n ? (requestOptions.extra_headers as Record<string, string>)\n : {};\n extraHeaders['X-LiveKit-Inference-Provider'] = this.provider;\n requestOptions.extra_headers = extraHeaders;\n }\n\n const stream = await this.client.chat.completions.create(\n {\n model: this.model,\n messages,\n tools,\n stream: true,\n stream_options: { include_usage: true },\n ...requestOptions,\n },\n {\n timeout: this.connOptions.timeoutMs,\n },\n );\n\n for await (const chunk of stream) {\n for (const choice of chunk.choices) {\n if (this.abortController.signal.aborted) {\n break;\n }\n const chatChunk = this.parseChoice(chunk.id, choice);\n if (chatChunk) {\n retryable = false;\n this.queue.put(chatChunk);\n }\n }\n\n if (chunk.usage) {\n const usage = chunk.usage;\n retryable = false;\n this.queue.put({\n id: chunk.id,\n usage: {\n completionTokens: usage.completion_tokens,\n promptTokens: usage.prompt_tokens,\n promptCachedTokens: usage.prompt_tokens_details?.cached_tokens || 0,\n totalTokens: usage.total_tokens,\n },\n });\n }\n }\n } catch (error) {\n if (error instanceof OpenAI.APIConnectionTimeoutError) {\n throw new APITimeoutError({ options: { retryable } });\n } else if (error instanceof OpenAI.APIError) {\n throw new APIStatusError({\n message: error.message,\n options: {\n statusCode: error.status,\n body: error.error,\n requestId: error.requestID,\n retryable,\n },\n });\n } else {\n throw new APIConnectionError({\n message: toError(error).message,\n options: { retryable },\n });\n }\n }\n }\n\n private parseChoice(\n id: string,\n choice: OpenAI.ChatCompletionChunk.Choice,\n ): llm.ChatChunk | undefined {\n const delta = choice.delta;\n\n // https://github.com/livekit/agents/issues/688\n // the delta can be None when using Azure OpenAI (content filtering)\n if (delta === undefined) return undefined;\n\n if (delta.tool_calls) {\n // check if we have functions to calls\n for (const tool of delta.tool_calls) {\n if (!tool.function) {\n continue; // oai may add other tools in the future\n }\n\n /**\n * The way OpenAI streams tool calls is a bit tricky.\n *\n * For any new tool call, it first emits a delta tool call with id, and function name,\n * the rest of the delta chunks will only stream the remaining arguments string,\n * until a new tool call is started or the tool call is finished.\n * See below for an example.\n *\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role='assistant', tool_calls=None), finish_reason=None, index=0, logprobs=None)\n * [ChoiceDeltaToolCall(index=0, id='call_LaVeHWUHpef9K1sd5UO8TtLg', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"P', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='aris\\}', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id='call_ThU4OmMdQXnnVmpXGOCknXIB', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"T', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='okyo', name=None), type=None)]\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role=None, tool_calls=None), finish_reason='tool_calls', index=0, logprobs=None)\n */\n let callChunk: llm.ChatChunk | undefined;\n // If we have a previous tool call and this is a new one, emit the previous\n if (this.toolCallId && tool.id && tool.index !== this.toolIndex) {\n callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n this.toolExtra = undefined;\n }\n\n // Start or continue building the current tool call\n if (tool.function.name) {\n this.toolIndex = tool.index;\n this.toolCallId = tool.id;\n this.fncName = tool.function.name;\n this.fncRawArguments = tool.function.arguments || '';\n // Extract extra from tool call (e.g., Google thought signatures)\n this.toolExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((tool as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n } else if (tool.function.arguments) {\n this.fncRawArguments = (this.fncRawArguments || '') + tool.function.arguments;\n }\n\n if (callChunk) {\n return callChunk;\n }\n }\n }\n\n // If we're done with tool calls, emit the final one\n if (\n choice.finish_reason &&\n ['tool_calls', 'stop'].includes(choice.finish_reason) &&\n this.toolCallId !== undefined\n ) {\n const callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n this.toolExtra = undefined;\n return callChunk;\n }\n\n // Extract extra from delta (e.g., Google thought signatures on text parts)\n const deltaExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((delta as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n\n // Regular content message\n if (!delta.content && !deltaExtra) {\n return undefined;\n }\n\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content || undefined,\n extra: deltaExtra,\n },\n };\n }\n\n private createRunningToolCallChunk(\n id: string,\n delta: OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta,\n ): llm.ChatChunk {\n const toolExtra = this.toolExtra ? { ...this.toolExtra } : {};\n const thoughtSignature = this.extractThoughtSignature(toolExtra);\n const deltaExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((delta as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content || undefined,\n extra: deltaExtra,\n toolCalls: [\n llm.FunctionCall.create({\n callId: this.toolCallId || '',\n name: this.fncName || '',\n args: this.fncRawArguments || '',\n extra: toolExtra,\n thoughtSignature,\n }),\n ],\n },\n };\n }\n\n private extractThoughtSignature(extra?: Record<string, unknown>): string | undefined {\n const googleExtra = extra?.google;\n if (googleExtra && typeof googleExtra === 'object') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (googleExtra as any).thoughtSignature || (googleExtra as any).thought_signature;\n }\n return undefined;\n }\n}\n"],"mappings":"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","names":["OpenAI","llm"]}
@@ -4,7 +4,7 @@ import * as llm from '../llm/index.js';
4
4
  import type { APIConnectOptions } from '../types.js';
5
5
  import { type AnyString } from './utils.js';
6
6
  export type OpenAIModels = 'openai/gpt-5' | 'openai/gpt-5-mini' | 'openai/gpt-5-nano' | 'openai/gpt-4.1' | 'openai/gpt-4.1-mini' | 'openai/gpt-4.1-nano' | 'openai/gpt-4o' | 'openai/gpt-4o-mini' | 'openai/gpt-oss-120b';
7
- export type GoogleModels = 'google/gemini-2.0-flash-lite';
7
+ export type GoogleModels = 'google/gemini-3-pro-preview' | 'google/gemini-3-flash-preview' | 'google/gemini-2.5-pro' | 'google/gemini-2.5-flash' | 'google/gemini-2.5-flash-lite' | 'google/gemini-2.0-flash' | 'google/gemini-2.0-flash-lite';
8
8
  export type QwenModels = 'qwen/qwen3-235b-a22b-instruct';
9
9
  export type KimiModels = 'moonshotai/kimi-k2-instruct';
10
10
  export type DeepSeekModels = 'deepseek-ai/deepseek-v3';
@@ -92,6 +92,7 @@ export declare class LLMStream extends llm.LLMStream {
92
92
  private toolIndex?;
93
93
  private fncName?;
94
94
  private fncRawArguments?;
95
+ private toolExtra?;
95
96
  constructor(llm: LLM, { model, provider, client, chatCtx, toolCtx, gatewayOptions, connOptions, modelOptions, providerFmt, strictToolSchema, }: {
96
97
  model: LLMModels;
97
98
  provider?: string;
@@ -107,6 +108,7 @@ export declare class LLMStream extends llm.LLMStream {
107
108
  protected run(): Promise<void>;
108
109
  private parseChoice;
109
110
  private createRunningToolCallChunk;
111
+ private extractThoughtSignature;
110
112
  }
111
113
  export {};
112
114
  //# sourceMappingURL=llm.d.ts.map
@@ -4,7 +4,7 @@ import * as llm from '../llm/index.js';
4
4
  import type { APIConnectOptions } from '../types.js';
5
5
  import { type AnyString } from './utils.js';
6
6
  export type OpenAIModels = 'openai/gpt-5' | 'openai/gpt-5-mini' | 'openai/gpt-5-nano' | 'openai/gpt-4.1' | 'openai/gpt-4.1-mini' | 'openai/gpt-4.1-nano' | 'openai/gpt-4o' | 'openai/gpt-4o-mini' | 'openai/gpt-oss-120b';
7
- export type GoogleModels = 'google/gemini-2.0-flash-lite';
7
+ export type GoogleModels = 'google/gemini-3-pro-preview' | 'google/gemini-3-flash-preview' | 'google/gemini-2.5-pro' | 'google/gemini-2.5-flash' | 'google/gemini-2.5-flash-lite' | 'google/gemini-2.0-flash' | 'google/gemini-2.0-flash-lite';
8
8
  export type QwenModels = 'qwen/qwen3-235b-a22b-instruct';
9
9
  export type KimiModels = 'moonshotai/kimi-k2-instruct';
10
10
  export type DeepSeekModels = 'deepseek-ai/deepseek-v3';
@@ -92,6 +92,7 @@ export declare class LLMStream extends llm.LLMStream {
92
92
  private toolIndex?;
93
93
  private fncName?;
94
94
  private fncRawArguments?;
95
+ private toolExtra?;
95
96
  constructor(llm: LLM, { model, provider, client, chatCtx, toolCtx, gatewayOptions, connOptions, modelOptions, providerFmt, strictToolSchema, }: {
96
97
  model: LLMModels;
97
98
  provider?: string;
@@ -107,6 +108,7 @@ export declare class LLMStream extends llm.LLMStream {
107
108
  protected run(): Promise<void>;
108
109
  private parseChoice;
109
110
  private createRunningToolCallChunk;
111
+ private extractThoughtSignature;
110
112
  }
111
113
  export {};
112
114
  //# sourceMappingURL=llm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/inference/llm.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/inference/llm.ts"],"names":[],"mappings":"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"}
@@ -104,6 +104,7 @@ class LLMStream extends llm.LLMStream {
104
104
  toolIndex;
105
105
  fncName;
106
106
  fncRawArguments;
107
+ toolExtra;
107
108
  constructor(llm2, {
108
109
  model,
109
110
  provider,
@@ -129,6 +130,7 @@ class LLMStream extends llm.LLMStream {
129
130
  var _a;
130
131
  let retryable = true;
131
132
  this.toolCallId = this.fncName = this.fncRawArguments = this.toolIndex = void 0;
133
+ this.toolExtra = void 0;
132
134
  try {
133
135
  const messages = await this.chatCtx.toProviderFormat(
134
136
  this.providerFmt
@@ -237,12 +239,15 @@ class LLMStream extends llm.LLMStream {
237
239
  if (this.toolCallId && tool.id && tool.index !== this.toolIndex) {
238
240
  callChunk = this.createRunningToolCallChunk(id, delta);
239
241
  this.toolCallId = this.fncName = this.fncRawArguments = void 0;
242
+ this.toolExtra = void 0;
240
243
  }
241
244
  if (tool.function.name) {
242
245
  this.toolIndex = tool.index;
243
246
  this.toolCallId = tool.id;
244
247
  this.fncName = tool.function.name;
245
248
  this.fncRawArguments = tool.function.arguments || "";
249
+ this.toolExtra = // eslint-disable-next-line @typescript-eslint/no-explicit-any
250
+ tool.extra_content ?? void 0;
246
251
  } else if (tool.function.arguments) {
247
252
  this.fncRawArguments = (this.fncRawArguments || "") + tool.function.arguments;
248
253
  }
@@ -254,35 +259,57 @@ class LLMStream extends llm.LLMStream {
254
259
  if (choice.finish_reason && ["tool_calls", "stop"].includes(choice.finish_reason) && this.toolCallId !== void 0) {
255
260
  const callChunk = this.createRunningToolCallChunk(id, delta);
256
261
  this.toolCallId = this.fncName = this.fncRawArguments = void 0;
262
+ this.toolExtra = void 0;
257
263
  return callChunk;
258
264
  }
259
- if (!delta.content) {
265
+ const deltaExtra = (
266
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
267
+ delta.extra_content ?? void 0
268
+ );
269
+ if (!delta.content && !deltaExtra) {
260
270
  return void 0;
261
271
  }
262
272
  return {
263
273
  id,
264
274
  delta: {
265
275
  role: "assistant",
266
- content: delta.content
276
+ content: delta.content || void 0,
277
+ extra: deltaExtra
267
278
  }
268
279
  };
269
280
  }
270
281
  createRunningToolCallChunk(id, delta) {
282
+ const toolExtra = this.toolExtra ? { ...this.toolExtra } : {};
283
+ const thoughtSignature = this.extractThoughtSignature(toolExtra);
284
+ const deltaExtra = (
285
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
286
+ delta.extra_content ?? void 0
287
+ );
271
288
  return {
272
289
  id,
273
290
  delta: {
274
291
  role: "assistant",
275
292
  content: delta.content || void 0,
293
+ extra: deltaExtra,
276
294
  toolCalls: [
277
295
  llm.FunctionCall.create({
278
296
  callId: this.toolCallId || "",
279
297
  name: this.fncName || "",
280
- args: this.fncRawArguments || ""
298
+ args: this.fncRawArguments || "",
299
+ extra: toolExtra,
300
+ thoughtSignature
281
301
  })
282
302
  ]
283
303
  }
284
304
  };
285
305
  }
306
+ extractThoughtSignature(extra) {
307
+ const googleExtra = extra == null ? void 0 : extra.google;
308
+ if (googleExtra && typeof googleExtra === "object") {
309
+ return googleExtra.thoughtSignature || googleExtra.thought_signature;
310
+ }
311
+ return void 0;
312
+ }
286
313
  }
287
314
  export {
288
315
  LLM,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/inference/llm.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport OpenAI from 'openai';\nimport {\n APIConnectionError,\n APIStatusError,\n APITimeoutError,\n DEFAULT_API_CONNECT_OPTIONS,\n type Expand,\n toError,\n} from '../index.js';\nimport * as llm from '../llm/index.js';\nimport type { APIConnectOptions } from '../types.js';\nimport { type AnyString, createAccessToken } from './utils.js';\n\nconst DEFAULT_BASE_URL = 'https://agent-gateway.livekit.cloud/v1';\n\nexport type OpenAIModels =\n | 'openai/gpt-5'\n | 'openai/gpt-5-mini'\n | 'openai/gpt-5-nano'\n | 'openai/gpt-4.1'\n | 'openai/gpt-4.1-mini'\n | 'openai/gpt-4.1-nano'\n | 'openai/gpt-4o'\n | 'openai/gpt-4o-mini'\n | 'openai/gpt-oss-120b';\n\nexport type GoogleModels = 'google/gemini-2.0-flash-lite';\n\nexport type QwenModels = 'qwen/qwen3-235b-a22b-instruct';\n\nexport type KimiModels = 'moonshotai/kimi-k2-instruct';\n\nexport type DeepSeekModels = 'deepseek-ai/deepseek-v3';\n\ntype ChatCompletionPredictionContentParam =\n Expand<OpenAI.Chat.Completions.ChatCompletionPredictionContent>;\ntype WebSearchOptions = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams.WebSearchOptions>;\ntype ToolChoice = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams['tool_choice']>;\ntype Verbosity = 'low' | 'medium' | 'high';\n\nexport interface ChatCompletionOptions extends Record<string, unknown> {\n frequency_penalty?: number;\n logit_bias?: Record<string, number>;\n logprobs?: boolean;\n max_completion_tokens?: number;\n max_tokens?: number;\n metadata?: Record<string, string>;\n modalities?: Array<'text' | 'audio'>;\n n?: number;\n parallel_tool_calls?: boolean;\n prediction?: ChatCompletionPredictionContentParam | null;\n presence_penalty?: number;\n prompt_cache_key?: string;\n reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high';\n safety_identifier?: string;\n seed?: number;\n service_tier?: 'auto' | 'default' | 'flex' | 'scale' | 'priority';\n stop?: string | string[];\n store?: boolean;\n temperature?: number;\n top_logprobs?: number;\n top_p?: number;\n user?: string;\n verbosity?: Verbosity;\n web_search_options?: WebSearchOptions;\n\n // livekit-typed arguments\n tool_choice?: ToolChoice;\n // TODO(brian): support response format\n // response_format?: OpenAI.Chat.Completions.ChatCompletionCreateParams['response_format']\n}\n\nexport type LLMModels =\n | OpenAIModels\n | GoogleModels\n | QwenModels\n | KimiModels\n | DeepSeekModels\n | AnyString;\n\nexport interface InferenceLLMOptions {\n model: LLMModels;\n provider?: string;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: ChatCompletionOptions;\n strictToolSchema?: boolean;\n}\n\nexport interface GatewayOptions {\n apiKey: string;\n apiSecret: string;\n}\n\n/**\n * Livekit Cloud Inference LLM\n */\nexport class LLM extends llm.LLM {\n private client: OpenAI;\n private opts: InferenceLLMOptions;\n\n constructor(opts: {\n model: LLMModels;\n provider?: string;\n baseURL?: string;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: InferenceLLMOptions['modelOptions'];\n strictToolSchema?: boolean;\n }) {\n super();\n\n const {\n model,\n provider,\n baseURL,\n apiKey,\n apiSecret,\n modelOptions,\n strictToolSchema = false,\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 provider,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions: modelOptions || {},\n strictToolSchema,\n };\n\n this.client = new OpenAI({\n baseURL: this.opts.baseURL,\n apiKey: '', // leave a temporary empty string to avoid OpenAI complain about missing key\n });\n }\n\n label(): string {\n return 'inference.LLM';\n }\n\n get model(): string {\n return this.opts.model;\n }\n\n static fromModelString(modelString: string): LLM {\n return new LLM({ model: modelString });\n }\n\n chat({\n chatCtx,\n toolCtx,\n connOptions = DEFAULT_API_CONNECT_OPTIONS,\n parallelToolCalls,\n toolChoice,\n // TODO(AJS-270): Add response_format parameter support\n extraKwargs,\n }: {\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n connOptions?: APIConnectOptions;\n parallelToolCalls?: boolean;\n toolChoice?: llm.ToolChoice;\n // TODO(AJS-270): Add responseFormat parameter\n extraKwargs?: Record<string, unknown>;\n }): LLMStream {\n let modelOptions: Record<string, unknown> = { ...(extraKwargs || {}) };\n\n parallelToolCalls =\n parallelToolCalls !== undefined\n ? parallelToolCalls\n : this.opts.modelOptions.parallel_tool_calls;\n\n if (toolCtx && Object.keys(toolCtx).length > 0 && parallelToolCalls !== undefined) {\n modelOptions.parallel_tool_calls = parallelToolCalls;\n }\n\n toolChoice =\n toolChoice !== undefined\n ? toolChoice\n : (this.opts.modelOptions.tool_choice as llm.ToolChoice | undefined);\n\n if (toolChoice) {\n modelOptions.tool_choice = toolChoice as ToolChoice;\n }\n\n // TODO(AJS-270): Add response_format support here\n\n modelOptions = { ...modelOptions, ...this.opts.modelOptions };\n\n return new LLMStream(this, {\n model: this.opts.model,\n provider: this.opts.provider,\n client: this.client,\n chatCtx,\n toolCtx,\n connOptions,\n modelOptions,\n strictToolSchema: this.opts.strictToolSchema ?? false, // default to false if not set\n gatewayOptions: {\n apiKey: this.opts.apiKey,\n apiSecret: this.opts.apiSecret,\n },\n });\n }\n}\n\nexport class LLMStream extends llm.LLMStream {\n private model: LLMModels;\n private provider?: string;\n private providerFmt: llm.ProviderFormat;\n private client: OpenAI;\n private modelOptions: Record<string, unknown>;\n private strictToolSchema: boolean;\n\n private gatewayOptions?: GatewayOptions;\n private toolCallId?: string;\n private toolIndex?: number;\n private fncName?: string;\n private fncRawArguments?: string;\n\n constructor(\n llm: LLM,\n {\n model,\n provider,\n client,\n chatCtx,\n toolCtx,\n gatewayOptions,\n connOptions,\n modelOptions,\n providerFmt,\n strictToolSchema,\n }: {\n model: LLMModels;\n provider?: string;\n client: OpenAI;\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n gatewayOptions?: GatewayOptions;\n connOptions: APIConnectOptions;\n modelOptions: Record<string, unknown>;\n providerFmt?: llm.ProviderFormat;\n strictToolSchema: boolean;\n },\n ) {\n super(llm, { chatCtx, toolCtx, connOptions });\n this.client = client;\n this.gatewayOptions = gatewayOptions;\n this.provider = provider;\n this.providerFmt = providerFmt || 'openai';\n this.modelOptions = modelOptions;\n this.model = model;\n this.strictToolSchema = strictToolSchema;\n }\n\n protected async run(): Promise<void> {\n // current function call that we're waiting for full completion (args are streamed)\n // (defined inside the run method to make sure the state is reset for each run/attempt)\n let retryable = true;\n this.toolCallId = this.fncName = this.fncRawArguments = this.toolIndex = undefined;\n\n try {\n const messages = (await this.chatCtx.toProviderFormat(\n this.providerFmt,\n )) as OpenAI.ChatCompletionMessageParam[];\n\n const tools = this.toolCtx\n ? Object.entries(this.toolCtx).map(([name, func]) => {\n const oaiParams = {\n type: 'function' as const,\n function: {\n name,\n description: func.description,\n parameters: llm.toJsonSchema(\n func.parameters,\n true,\n this.strictToolSchema,\n ) as unknown as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function']['parameters'],\n } as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function'],\n };\n\n if (this.strictToolSchema) {\n oaiParams.function.strict = true;\n }\n\n return oaiParams;\n })\n : undefined;\n\n const requestOptions: Record<string, unknown> = { ...this.modelOptions };\n if (!tools) {\n delete requestOptions.tool_choice;\n }\n\n // Dynamically set the access token for the LiveKit Agent Gateway API\n if (this.gatewayOptions) {\n this.client.apiKey = await createAccessToken(\n this.gatewayOptions.apiKey,\n this.gatewayOptions.apiSecret,\n );\n }\n\n if (this.provider) {\n const extraHeaders = requestOptions.extra_headers\n ? (requestOptions.extra_headers as Record<string, string>)\n : {};\n extraHeaders['X-LiveKit-Inference-Provider'] = this.provider;\n requestOptions.extra_headers = extraHeaders;\n }\n\n const stream = await this.client.chat.completions.create(\n {\n model: this.model,\n messages,\n tools,\n stream: true,\n stream_options: { include_usage: true },\n ...requestOptions,\n },\n {\n timeout: this.connOptions.timeoutMs,\n },\n );\n\n for await (const chunk of stream) {\n for (const choice of chunk.choices) {\n if (this.abortController.signal.aborted) {\n break;\n }\n const chatChunk = this.parseChoice(chunk.id, choice);\n if (chatChunk) {\n retryable = false;\n this.queue.put(chatChunk);\n }\n }\n\n if (chunk.usage) {\n const usage = chunk.usage;\n retryable = false;\n this.queue.put({\n id: chunk.id,\n usage: {\n completionTokens: usage.completion_tokens,\n promptTokens: usage.prompt_tokens,\n promptCachedTokens: usage.prompt_tokens_details?.cached_tokens || 0,\n totalTokens: usage.total_tokens,\n },\n });\n }\n }\n } catch (error) {\n if (error instanceof OpenAI.APIConnectionTimeoutError) {\n throw new APITimeoutError({ options: { retryable } });\n } else if (error instanceof OpenAI.APIError) {\n throw new APIStatusError({\n message: error.message,\n options: {\n statusCode: error.status,\n body: error.error,\n requestId: error.requestID,\n retryable,\n },\n });\n } else {\n throw new APIConnectionError({\n message: toError(error).message,\n options: { retryable },\n });\n }\n }\n }\n\n private parseChoice(\n id: string,\n choice: OpenAI.ChatCompletionChunk.Choice,\n ): llm.ChatChunk | undefined {\n const delta = choice.delta;\n\n // https://github.com/livekit/agents/issues/688\n // the delta can be None when using Azure OpenAI (content filtering)\n if (delta === undefined) return undefined;\n\n if (delta.tool_calls) {\n // check if we have functions to calls\n for (const tool of delta.tool_calls) {\n if (!tool.function) {\n continue; // oai may add other tools in the future\n }\n\n /**\n * The way OpenAI streams tool calls is a bit tricky.\n *\n * For any new tool call, it first emits a delta tool call with id, and function name,\n * the rest of the delta chunks will only stream the remaining arguments string,\n * until a new tool call is started or the tool call is finished.\n * See below for an example.\n *\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role='assistant', tool_calls=None), finish_reason=None, index=0, logprobs=None)\n * [ChoiceDeltaToolCall(index=0, id='call_LaVeHWUHpef9K1sd5UO8TtLg', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"P', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='aris\\}', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id='call_ThU4OmMdQXnnVmpXGOCknXIB', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"T', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='okyo', name=None), type=None)]\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role=None, tool_calls=None), finish_reason='tool_calls', index=0, logprobs=None)\n */\n let callChunk: llm.ChatChunk | undefined;\n // If we have a previous tool call and this is a new one, emit the previous\n if (this.toolCallId && tool.id && tool.index !== this.toolIndex) {\n callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n }\n\n // Start or continue building the current tool call\n if (tool.function.name) {\n this.toolIndex = tool.index;\n this.toolCallId = tool.id;\n this.fncName = tool.function.name;\n this.fncRawArguments = tool.function.arguments || '';\n } else if (tool.function.arguments) {\n this.fncRawArguments = (this.fncRawArguments || '') + tool.function.arguments;\n }\n\n if (callChunk) {\n return callChunk;\n }\n }\n }\n\n // If we're done with tool calls, emit the final one\n if (\n choice.finish_reason &&\n ['tool_calls', 'stop'].includes(choice.finish_reason) &&\n this.toolCallId !== undefined\n ) {\n const callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n return callChunk;\n }\n\n // Regular content message\n if (!delta.content) {\n return undefined;\n }\n\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content,\n },\n };\n }\n\n private createRunningToolCallChunk(\n id: string,\n delta: OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta,\n ): llm.ChatChunk {\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content || undefined,\n toolCalls: [\n llm.FunctionCall.create({\n callId: this.toolCallId || '',\n name: this.fncName || '',\n args: this.fncRawArguments || '',\n }),\n ],\n },\n };\n }\n}\n"],"mappings":"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","names":["llm"]}
1
+ {"version":3,"sources":["../../src/inference/llm.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport OpenAI from 'openai';\nimport {\n APIConnectionError,\n APIStatusError,\n APITimeoutError,\n DEFAULT_API_CONNECT_OPTIONS,\n type Expand,\n toError,\n} from '../index.js';\nimport * as llm from '../llm/index.js';\nimport type { APIConnectOptions } from '../types.js';\nimport { type AnyString, createAccessToken } from './utils.js';\n\nconst DEFAULT_BASE_URL = 'https://agent-gateway.livekit.cloud/v1';\n\nexport type OpenAIModels =\n | 'openai/gpt-5'\n | 'openai/gpt-5-mini'\n | 'openai/gpt-5-nano'\n | 'openai/gpt-4.1'\n | 'openai/gpt-4.1-mini'\n | 'openai/gpt-4.1-nano'\n | 'openai/gpt-4o'\n | 'openai/gpt-4o-mini'\n | 'openai/gpt-oss-120b';\n\nexport type GoogleModels =\n | 'google/gemini-3-pro-preview'\n | 'google/gemini-3-flash-preview'\n | 'google/gemini-2.5-pro'\n | 'google/gemini-2.5-flash'\n | 'google/gemini-2.5-flash-lite'\n | 'google/gemini-2.0-flash'\n | 'google/gemini-2.0-flash-lite';\n\nexport type QwenModels = 'qwen/qwen3-235b-a22b-instruct';\n\nexport type KimiModels = 'moonshotai/kimi-k2-instruct';\n\nexport type DeepSeekModels = 'deepseek-ai/deepseek-v3';\n\ntype ChatCompletionPredictionContentParam =\n Expand<OpenAI.Chat.Completions.ChatCompletionPredictionContent>;\ntype WebSearchOptions = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams.WebSearchOptions>;\ntype ToolChoice = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams['tool_choice']>;\ntype Verbosity = 'low' | 'medium' | 'high';\n\nexport interface ChatCompletionOptions extends Record<string, unknown> {\n frequency_penalty?: number;\n logit_bias?: Record<string, number>;\n logprobs?: boolean;\n max_completion_tokens?: number;\n max_tokens?: number;\n metadata?: Record<string, string>;\n modalities?: Array<'text' | 'audio'>;\n n?: number;\n parallel_tool_calls?: boolean;\n prediction?: ChatCompletionPredictionContentParam | null;\n presence_penalty?: number;\n prompt_cache_key?: string;\n reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high';\n safety_identifier?: string;\n seed?: number;\n service_tier?: 'auto' | 'default' | 'flex' | 'scale' | 'priority';\n stop?: string | string[];\n store?: boolean;\n temperature?: number;\n top_logprobs?: number;\n top_p?: number;\n user?: string;\n verbosity?: Verbosity;\n web_search_options?: WebSearchOptions;\n\n // livekit-typed arguments\n tool_choice?: ToolChoice;\n // TODO(brian): support response format\n // response_format?: OpenAI.Chat.Completions.ChatCompletionCreateParams['response_format']\n}\n\nexport type LLMModels =\n | OpenAIModels\n | GoogleModels\n | QwenModels\n | KimiModels\n | DeepSeekModels\n | AnyString;\n\nexport interface InferenceLLMOptions {\n model: LLMModels;\n provider?: string;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: ChatCompletionOptions;\n strictToolSchema?: boolean;\n}\n\nexport interface GatewayOptions {\n apiKey: string;\n apiSecret: string;\n}\n\n/**\n * Livekit Cloud Inference LLM\n */\nexport class LLM extends llm.LLM {\n private client: OpenAI;\n private opts: InferenceLLMOptions;\n\n constructor(opts: {\n model: LLMModels;\n provider?: string;\n baseURL?: string;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: InferenceLLMOptions['modelOptions'];\n strictToolSchema?: boolean;\n }) {\n super();\n\n const {\n model,\n provider,\n baseURL,\n apiKey,\n apiSecret,\n modelOptions,\n strictToolSchema = false,\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 provider,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions: modelOptions || {},\n strictToolSchema,\n };\n\n this.client = new OpenAI({\n baseURL: this.opts.baseURL,\n apiKey: '', // leave a temporary empty string to avoid OpenAI complain about missing key\n });\n }\n\n label(): string {\n return 'inference.LLM';\n }\n\n get model(): string {\n return this.opts.model;\n }\n\n static fromModelString(modelString: string): LLM {\n return new LLM({ model: modelString });\n }\n\n chat({\n chatCtx,\n toolCtx,\n connOptions = DEFAULT_API_CONNECT_OPTIONS,\n parallelToolCalls,\n toolChoice,\n // TODO(AJS-270): Add response_format parameter support\n extraKwargs,\n }: {\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n connOptions?: APIConnectOptions;\n parallelToolCalls?: boolean;\n toolChoice?: llm.ToolChoice;\n // TODO(AJS-270): Add responseFormat parameter\n extraKwargs?: Record<string, unknown>;\n }): LLMStream {\n let modelOptions: Record<string, unknown> = { ...(extraKwargs || {}) };\n\n parallelToolCalls =\n parallelToolCalls !== undefined\n ? parallelToolCalls\n : this.opts.modelOptions.parallel_tool_calls;\n\n if (toolCtx && Object.keys(toolCtx).length > 0 && parallelToolCalls !== undefined) {\n modelOptions.parallel_tool_calls = parallelToolCalls;\n }\n\n toolChoice =\n toolChoice !== undefined\n ? toolChoice\n : (this.opts.modelOptions.tool_choice as llm.ToolChoice | undefined);\n\n if (toolChoice) {\n modelOptions.tool_choice = toolChoice as ToolChoice;\n }\n\n // TODO(AJS-270): Add response_format support here\n\n modelOptions = { ...modelOptions, ...this.opts.modelOptions };\n\n return new LLMStream(this, {\n model: this.opts.model,\n provider: this.opts.provider,\n client: this.client,\n chatCtx,\n toolCtx,\n connOptions,\n modelOptions,\n strictToolSchema: this.opts.strictToolSchema ?? false, // default to false if not set\n gatewayOptions: {\n apiKey: this.opts.apiKey,\n apiSecret: this.opts.apiSecret,\n },\n });\n }\n}\n\nexport class LLMStream extends llm.LLMStream {\n private model: LLMModels;\n private provider?: string;\n private providerFmt: llm.ProviderFormat;\n private client: OpenAI;\n private modelOptions: Record<string, unknown>;\n private strictToolSchema: boolean;\n\n private gatewayOptions?: GatewayOptions;\n private toolCallId?: string;\n private toolIndex?: number;\n private fncName?: string;\n private fncRawArguments?: string;\n private toolExtra?: Record<string, unknown>;\n\n constructor(\n llm: LLM,\n {\n model,\n provider,\n client,\n chatCtx,\n toolCtx,\n gatewayOptions,\n connOptions,\n modelOptions,\n providerFmt,\n strictToolSchema,\n }: {\n model: LLMModels;\n provider?: string;\n client: OpenAI;\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n gatewayOptions?: GatewayOptions;\n connOptions: APIConnectOptions;\n modelOptions: Record<string, unknown>;\n providerFmt?: llm.ProviderFormat;\n strictToolSchema: boolean;\n },\n ) {\n super(llm, { chatCtx, toolCtx, connOptions });\n this.client = client;\n this.gatewayOptions = gatewayOptions;\n this.provider = provider;\n this.providerFmt = providerFmt || 'openai';\n this.modelOptions = modelOptions;\n this.model = model;\n this.strictToolSchema = strictToolSchema;\n }\n\n protected async run(): Promise<void> {\n // current function call that we're waiting for full completion (args are streamed)\n // (defined inside the run method to make sure the state is reset for each run/attempt)\n let retryable = true;\n this.toolCallId = this.fncName = this.fncRawArguments = this.toolIndex = undefined;\n this.toolExtra = undefined;\n\n try {\n const messages = (await this.chatCtx.toProviderFormat(\n this.providerFmt,\n )) as OpenAI.ChatCompletionMessageParam[];\n\n const tools = this.toolCtx\n ? Object.entries(this.toolCtx).map(([name, func]) => {\n const oaiParams = {\n type: 'function' as const,\n function: {\n name,\n description: func.description,\n parameters: llm.toJsonSchema(\n func.parameters,\n true,\n this.strictToolSchema,\n ) as unknown as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function']['parameters'],\n } as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function'],\n };\n\n if (this.strictToolSchema) {\n oaiParams.function.strict = true;\n }\n\n return oaiParams;\n })\n : undefined;\n\n const requestOptions: Record<string, unknown> = { ...this.modelOptions };\n if (!tools) {\n delete requestOptions.tool_choice;\n }\n\n // Dynamically set the access token for the LiveKit Agent Gateway API\n if (this.gatewayOptions) {\n this.client.apiKey = await createAccessToken(\n this.gatewayOptions.apiKey,\n this.gatewayOptions.apiSecret,\n );\n }\n\n if (this.provider) {\n const extraHeaders = requestOptions.extra_headers\n ? (requestOptions.extra_headers as Record<string, string>)\n : {};\n extraHeaders['X-LiveKit-Inference-Provider'] = this.provider;\n requestOptions.extra_headers = extraHeaders;\n }\n\n const stream = await this.client.chat.completions.create(\n {\n model: this.model,\n messages,\n tools,\n stream: true,\n stream_options: { include_usage: true },\n ...requestOptions,\n },\n {\n timeout: this.connOptions.timeoutMs,\n },\n );\n\n for await (const chunk of stream) {\n for (const choice of chunk.choices) {\n if (this.abortController.signal.aborted) {\n break;\n }\n const chatChunk = this.parseChoice(chunk.id, choice);\n if (chatChunk) {\n retryable = false;\n this.queue.put(chatChunk);\n }\n }\n\n if (chunk.usage) {\n const usage = chunk.usage;\n retryable = false;\n this.queue.put({\n id: chunk.id,\n usage: {\n completionTokens: usage.completion_tokens,\n promptTokens: usage.prompt_tokens,\n promptCachedTokens: usage.prompt_tokens_details?.cached_tokens || 0,\n totalTokens: usage.total_tokens,\n },\n });\n }\n }\n } catch (error) {\n if (error instanceof OpenAI.APIConnectionTimeoutError) {\n throw new APITimeoutError({ options: { retryable } });\n } else if (error instanceof OpenAI.APIError) {\n throw new APIStatusError({\n message: error.message,\n options: {\n statusCode: error.status,\n body: error.error,\n requestId: error.requestID,\n retryable,\n },\n });\n } else {\n throw new APIConnectionError({\n message: toError(error).message,\n options: { retryable },\n });\n }\n }\n }\n\n private parseChoice(\n id: string,\n choice: OpenAI.ChatCompletionChunk.Choice,\n ): llm.ChatChunk | undefined {\n const delta = choice.delta;\n\n // https://github.com/livekit/agents/issues/688\n // the delta can be None when using Azure OpenAI (content filtering)\n if (delta === undefined) return undefined;\n\n if (delta.tool_calls) {\n // check if we have functions to calls\n for (const tool of delta.tool_calls) {\n if (!tool.function) {\n continue; // oai may add other tools in the future\n }\n\n /**\n * The way OpenAI streams tool calls is a bit tricky.\n *\n * For any new tool call, it first emits a delta tool call with id, and function name,\n * the rest of the delta chunks will only stream the remaining arguments string,\n * until a new tool call is started or the tool call is finished.\n * See below for an example.\n *\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role='assistant', tool_calls=None), finish_reason=None, index=0, logprobs=None)\n * [ChoiceDeltaToolCall(index=0, id='call_LaVeHWUHpef9K1sd5UO8TtLg', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"P', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='aris\\}', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id='call_ThU4OmMdQXnnVmpXGOCknXIB', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"T', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='okyo', name=None), type=None)]\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role=None, tool_calls=None), finish_reason='tool_calls', index=0, logprobs=None)\n */\n let callChunk: llm.ChatChunk | undefined;\n // If we have a previous tool call and this is a new one, emit the previous\n if (this.toolCallId && tool.id && tool.index !== this.toolIndex) {\n callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n this.toolExtra = undefined;\n }\n\n // Start or continue building the current tool call\n if (tool.function.name) {\n this.toolIndex = tool.index;\n this.toolCallId = tool.id;\n this.fncName = tool.function.name;\n this.fncRawArguments = tool.function.arguments || '';\n // Extract extra from tool call (e.g., Google thought signatures)\n this.toolExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((tool as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n } else if (tool.function.arguments) {\n this.fncRawArguments = (this.fncRawArguments || '') + tool.function.arguments;\n }\n\n if (callChunk) {\n return callChunk;\n }\n }\n }\n\n // If we're done with tool calls, emit the final one\n if (\n choice.finish_reason &&\n ['tool_calls', 'stop'].includes(choice.finish_reason) &&\n this.toolCallId !== undefined\n ) {\n const callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n this.toolExtra = undefined;\n return callChunk;\n }\n\n // Extract extra from delta (e.g., Google thought signatures on text parts)\n const deltaExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((delta as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n\n // Regular content message\n if (!delta.content && !deltaExtra) {\n return undefined;\n }\n\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content || undefined,\n extra: deltaExtra,\n },\n };\n }\n\n private createRunningToolCallChunk(\n id: string,\n delta: OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta,\n ): llm.ChatChunk {\n const toolExtra = this.toolExtra ? { ...this.toolExtra } : {};\n const thoughtSignature = this.extractThoughtSignature(toolExtra);\n const deltaExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((delta as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content || undefined,\n extra: deltaExtra,\n toolCalls: [\n llm.FunctionCall.create({\n callId: this.toolCallId || '',\n name: this.fncName || '',\n args: this.fncRawArguments || '',\n extra: toolExtra,\n thoughtSignature,\n }),\n ],\n },\n };\n }\n\n private extractThoughtSignature(extra?: Record<string, unknown>): string | undefined {\n const googleExtra = extra?.google;\n if (googleExtra && typeof googleExtra === 'object') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (googleExtra as any).thoughtSignature || (googleExtra as any).thought_signature;\n }\n return undefined;\n }\n}\n"],"mappings":"AAGA,OAAO,YAAY;AACnB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AACP,YAAY,SAAS;AAErB,SAAyB,yBAAyB;AAElD,MAAM,mBAAmB;AA4FlB,MAAM,YAAY,IAAI,IAAI;AAAA,EACvB;AAAA,EACA;AAAA,EAER,YAAY,MAQT;AACD,UAAM;AAEN,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,mBAAmB;AAAA,IACrB,IAAI;AAEJ,UAAM,YAAY,WAAW,QAAQ,IAAI,yBAAyB;AAClE,UAAM,WAAW,UAAU,QAAQ,IAAI,6BAA6B,QAAQ,IAAI;AAChF,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AAEA,UAAM,cACJ,aAAa,QAAQ,IAAI,gCAAgC,QAAQ,IAAI;AACvE,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,MAAM,iEAAiE;AAAA,IACnF;AAEA,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,cAAc,gBAAgB,CAAC;AAAA,MAC/B;AAAA,IACF;AAEA,SAAK,SAAS,IAAI,OAAO;AAAA,MACvB,SAAS,KAAK,KAAK;AAAA,MACnB,QAAQ;AAAA;AAAA,IACV,CAAC;AAAA,EACH;AAAA,EAEA,QAAgB;AACd,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,QAAgB;AAClB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,OAAO,gBAAgB,aAA0B;AAC/C,WAAO,IAAI,IAAI,EAAE,OAAO,YAAY,CAAC;AAAA,EACvC;AAAA,EAEA,KAAK;AAAA,IACH;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,EACF,GAQc;AACZ,QAAI,eAAwC,EAAE,GAAI,eAAe,CAAC,EAAG;AAErE,wBACE,sBAAsB,SAClB,oBACA,KAAK,KAAK,aAAa;AAE7B,QAAI,WAAW,OAAO,KAAK,OAAO,EAAE,SAAS,KAAK,sBAAsB,QAAW;AACjF,mBAAa,sBAAsB;AAAA,IACrC;AAEA,iBACE,eAAe,SACX,aACC,KAAK,KAAK,aAAa;AAE9B,QAAI,YAAY;AACd,mBAAa,cAAc;AAAA,IAC7B;AAIA,mBAAe,EAAE,GAAG,cAAc,GAAG,KAAK,KAAK,aAAa;AAE5D,WAAO,IAAI,UAAU,MAAM;AAAA,MACzB,OAAO,KAAK,KAAK;AAAA,MACjB,UAAU,KAAK,KAAK;AAAA,MACpB,QAAQ,KAAK;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAkB,KAAK,KAAK,oBAAoB;AAAA;AAAA,MAChD,gBAAgB;AAAA,QACd,QAAQ,KAAK,KAAK;AAAA,QAClB,WAAW,KAAK,KAAK;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,MAAM,kBAAkB,IAAI,UAAU;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACEA,MACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAYA;AACA,UAAMA,MAAK,EAAE,SAAS,SAAS,YAAY,CAAC;AAC5C,SAAK,SAAS;AACd,SAAK,iBAAiB;AACtB,SAAK,WAAW;AAChB,SAAK,cAAc,eAAe;AAClC,SAAK,eAAe;AACpB,SAAK,QAAQ;AACb,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,MAAgB,MAAqB;AA1RvC;AA6RI,QAAI,YAAY;AAChB,SAAK,aAAa,KAAK,UAAU,KAAK,kBAAkB,KAAK,YAAY;AACzE,SAAK,YAAY;AAEjB,QAAI;AACF,YAAM,WAAY,MAAM,KAAK,QAAQ;AAAA,QACnC,KAAK;AAAA,MACP;AAEA,YAAM,QAAQ,KAAK,UACf,OAAO,QAAQ,KAAK,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM;AACjD,cAAM,YAAY;AAAA,UAChB,MAAM;AAAA,UACN,UAAU;AAAA,YACR;AAAA,YACA,aAAa,KAAK;AAAA,YAClB,YAAY,IAAI;AAAA,cACd,KAAK;AAAA,cACL;AAAA,cACA,KAAK;AAAA,YACP;AAAA,UACF;AAAA,QACF;AAEA,YAAI,KAAK,kBAAkB;AACzB,oBAAU,SAAS,SAAS;AAAA,QAC9B;AAEA,eAAO;AAAA,MACT,CAAC,IACD;AAEJ,YAAM,iBAA0C,EAAE,GAAG,KAAK,aAAa;AACvE,UAAI,CAAC,OAAO;AACV,eAAO,eAAe;AAAA,MACxB;AAGA,UAAI,KAAK,gBAAgB;AACvB,aAAK,OAAO,SAAS,MAAM;AAAA,UACzB,KAAK,eAAe;AAAA,UACpB,KAAK,eAAe;AAAA,QACtB;AAAA,MACF;AAEA,UAAI,KAAK,UAAU;AACjB,cAAM,eAAe,eAAe,gBAC/B,eAAe,gBAChB,CAAC;AACL,qBAAa,8BAA8B,IAAI,KAAK;AACpD,uBAAe,gBAAgB;AAAA,MACjC;AAEA,YAAM,SAAS,MAAM,KAAK,OAAO,KAAK,YAAY;AAAA,QAChD;AAAA,UACE,OAAO,KAAK;AAAA,UACZ;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,gBAAgB,EAAE,eAAe,KAAK;AAAA,UACtC,GAAG;AAAA,QACL;AAAA,QACA;AAAA,UACE,SAAS,KAAK,YAAY;AAAA,QAC5B;AAAA,MACF;AAEA,uBAAiB,SAAS,QAAQ;AAChC,mBAAW,UAAU,MAAM,SAAS;AAClC,cAAI,KAAK,gBAAgB,OAAO,SAAS;AACvC;AAAA,UACF;AACA,gBAAM,YAAY,KAAK,YAAY,MAAM,IAAI,MAAM;AACnD,cAAI,WAAW;AACb,wBAAY;AACZ,iBAAK,MAAM,IAAI,SAAS;AAAA,UAC1B;AAAA,QACF;AAEA,YAAI,MAAM,OAAO;AACf,gBAAM,QAAQ,MAAM;AACpB,sBAAY;AACZ,eAAK,MAAM,IAAI;AAAA,YACb,IAAI,MAAM;AAAA,YACV,OAAO;AAAA,cACL,kBAAkB,MAAM;AAAA,cACxB,cAAc,MAAM;AAAA,cACpB,sBAAoB,WAAM,0BAAN,mBAA6B,kBAAiB;AAAA,cAClE,aAAa,MAAM;AAAA,YACrB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,OAAO,2BAA2B;AACrD,cAAM,IAAI,gBAAgB,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AAAA,MACtD,WAAW,iBAAiB,OAAO,UAAU;AAC3C,cAAM,IAAI,eAAe;AAAA,UACvB,SAAS,MAAM;AAAA,UACf,SAAS;AAAA,YACP,YAAY,MAAM;AAAA,YAClB,MAAM,MAAM;AAAA,YACZ,WAAW,MAAM;AAAA,YACjB;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH,OAAO;AACL,cAAM,IAAI,mBAAmB;AAAA,UAC3B,SAAS,QAAQ,KAAK,EAAE;AAAA,UACxB,SAAS,EAAE,UAAU;AAAA,QACvB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,YACN,IACA,QAC2B;AAC3B,UAAM,QAAQ,OAAO;AAIrB,QAAI,UAAU,OAAW,QAAO;AAEhC,QAAI,MAAM,YAAY;AAEpB,iBAAW,QAAQ,MAAM,YAAY;AACnC,YAAI,CAAC,KAAK,UAAU;AAClB;AAAA,QACF;AAmBA,YAAI;AAEJ,YAAI,KAAK,cAAc,KAAK,MAAM,KAAK,UAAU,KAAK,WAAW;AAC/D,sBAAY,KAAK,2BAA2B,IAAI,KAAK;AACrD,eAAK,aAAa,KAAK,UAAU,KAAK,kBAAkB;AACxD,eAAK,YAAY;AAAA,QACnB;AAGA,YAAI,KAAK,SAAS,MAAM;AACtB,eAAK,YAAY,KAAK;AACtB,eAAK,aAAa,KAAK;AACvB,eAAK,UAAU,KAAK,SAAS;AAC7B,eAAK,kBAAkB,KAAK,SAAS,aAAa;AAElD,eAAK;AAAA,UAED,KAAa,iBAAyD;AAAA,QAC5E,WAAW,KAAK,SAAS,WAAW;AAClC,eAAK,mBAAmB,KAAK,mBAAmB,MAAM,KAAK,SAAS;AAAA,QACtE;AAEA,YAAI,WAAW;AACb,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAGA,QACE,OAAO,iBACP,CAAC,cAAc,MAAM,EAAE,SAAS,OAAO,aAAa,KACpD,KAAK,eAAe,QACpB;AACA,YAAM,YAAY,KAAK,2BAA2B,IAAI,KAAK;AAC3D,WAAK,aAAa,KAAK,UAAU,KAAK,kBAAkB;AACxD,WAAK,YAAY;AACjB,aAAO;AAAA,IACT;AAGA,UAAM;AAAA;AAAA,MAEF,MAAc,iBAAyD;AAAA;AAG3E,QAAI,CAAC,MAAM,WAAW,CAAC,YAAY;AACjC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,MAAM,WAAW;AAAA,QAC1B,OAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,2BACN,IACA,OACe;AACf,UAAM,YAAY,KAAK,YAAY,EAAE,GAAG,KAAK,UAAU,IAAI,CAAC;AAC5D,UAAM,mBAAmB,KAAK,wBAAwB,SAAS;AAC/D,UAAM;AAAA;AAAA,MAEF,MAAc,iBAAyD;AAAA;AAE3E,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,MAAM,WAAW;AAAA,QAC1B,OAAO;AAAA,QACP,WAAW;AAAA,UACT,IAAI,aAAa,OAAO;AAAA,YACtB,QAAQ,KAAK,cAAc;AAAA,YAC3B,MAAM,KAAK,WAAW;AAAA,YACtB,MAAM,KAAK,mBAAmB;AAAA,YAC9B,OAAO;AAAA,YACP;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,wBAAwB,OAAqD;AACnF,UAAM,cAAc,+BAAO;AAC3B,QAAI,eAAe,OAAO,gBAAgB,UAAU;AAElD,aAAQ,YAAoB,oBAAqB,YAAoB;AAAA,IACvE;AACA,WAAO;AAAA,EACT;AACF;","names":["llm"]}