@livekit/agents 1.0.34 → 1.0.36-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/inference/api_protos.d.cts +4 -4
- package/dist/inference/api_protos.d.ts +4 -4
- package/dist/inference/interruption/AdaptiveInterruptionDetector.cjs +152 -0
- package/dist/inference/interruption/AdaptiveInterruptionDetector.cjs.map +1 -0
- package/dist/inference/interruption/AdaptiveInterruptionDetector.d.cts +50 -0
- package/dist/inference/interruption/AdaptiveInterruptionDetector.d.ts +50 -0
- package/dist/inference/interruption/AdaptiveInterruptionDetector.d.ts.map +1 -0
- package/dist/inference/interruption/AdaptiveInterruptionDetector.js +125 -0
- package/dist/inference/interruption/AdaptiveInterruptionDetector.js.map +1 -0
- package/dist/inference/interruption/InterruptionStream.cjs +310 -0
- package/dist/inference/interruption/InterruptionStream.cjs.map +1 -0
- package/dist/inference/interruption/InterruptionStream.d.cts +57 -0
- package/dist/inference/interruption/InterruptionStream.d.ts +57 -0
- package/dist/inference/interruption/InterruptionStream.d.ts.map +1 -0
- package/dist/inference/interruption/InterruptionStream.js +288 -0
- package/dist/inference/interruption/InterruptionStream.js.map +1 -0
- package/dist/inference/interruption/defaults.cjs +76 -0
- package/dist/inference/interruption/defaults.cjs.map +1 -0
- package/dist/inference/interruption/defaults.d.cts +14 -0
- package/dist/inference/interruption/defaults.d.ts +14 -0
- package/dist/inference/interruption/defaults.d.ts.map +1 -0
- package/dist/inference/interruption/defaults.js +42 -0
- package/dist/inference/interruption/defaults.js.map +1 -0
- package/dist/inference/interruption/errors.cjs +2 -0
- package/dist/inference/interruption/errors.cjs.map +1 -0
- package/dist/inference/interruption/errors.d.cts +2 -0
- package/dist/inference/interruption/errors.d.ts +2 -0
- package/dist/inference/interruption/errors.d.ts.map +1 -0
- package/dist/inference/interruption/errors.js +1 -0
- package/dist/inference/interruption/errors.js.map +1 -0
- package/dist/inference/interruption/http_transport.cjs +57 -0
- package/dist/inference/interruption/http_transport.cjs.map +1 -0
- package/dist/inference/interruption/http_transport.d.cts +23 -0
- package/dist/inference/interruption/http_transport.d.ts +23 -0
- package/dist/inference/interruption/http_transport.d.ts.map +1 -0
- package/dist/inference/interruption/http_transport.js +33 -0
- package/dist/inference/interruption/http_transport.js.map +1 -0
- package/dist/inference/interruption/index.cjs +34 -0
- package/dist/inference/interruption/index.cjs.map +1 -0
- package/dist/inference/interruption/index.d.cts +5 -0
- package/dist/inference/interruption/index.d.ts +5 -0
- package/dist/inference/interruption/index.d.ts.map +1 -0
- package/dist/inference/interruption/index.js +7 -0
- package/dist/inference/interruption/index.js.map +1 -0
- package/dist/inference/interruption/interruption.cjs +85 -0
- package/dist/inference/interruption/interruption.cjs.map +1 -0
- package/dist/inference/interruption/interruption.d.cts +48 -0
- package/dist/inference/interruption/interruption.d.ts +48 -0
- package/dist/inference/interruption/interruption.d.ts.map +1 -0
- package/dist/inference/interruption/interruption.js +59 -0
- package/dist/inference/interruption/interruption.js.map +1 -0
- package/dist/inference/llm.cjs +30 -3
- package/dist/inference/llm.cjs.map +1 -1
- package/dist/inference/llm.d.cts +3 -1
- package/dist/inference/llm.d.ts +3 -1
- package/dist/inference/llm.d.ts.map +1 -1
- package/dist/inference/llm.js +30 -3
- package/dist/inference/llm.js.map +1 -1
- package/dist/inference/utils.cjs +15 -2
- package/dist/inference/utils.cjs.map +1 -1
- package/dist/inference/utils.d.cts +1 -0
- package/dist/inference/utils.d.ts +1 -0
- package/dist/inference/utils.d.ts.map +1 -1
- package/dist/inference/utils.js +13 -1
- package/dist/inference/utils.js.map +1 -1
- package/dist/inference/utils.test.cjs +20 -0
- package/dist/inference/utils.test.cjs.map +1 -0
- package/dist/inference/utils.test.js +19 -0
- package/dist/inference/utils.test.js.map +1 -0
- package/dist/ipc/inference_proc_executor.cjs.map +1 -1
- package/dist/ipc/job_proc_executor.cjs.map +1 -1
- package/dist/ipc/job_proc_lazy_main.cjs +1 -1
- package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
- package/dist/ipc/job_proc_lazy_main.js +1 -1
- package/dist/ipc/job_proc_lazy_main.js.map +1 -1
- package/dist/llm/chat_context.cjs +20 -2
- package/dist/llm/chat_context.cjs.map +1 -1
- package/dist/llm/chat_context.d.cts +9 -0
- package/dist/llm/chat_context.d.ts +9 -0
- package/dist/llm/chat_context.d.ts.map +1 -1
- package/dist/llm/chat_context.js +20 -2
- package/dist/llm/chat_context.js.map +1 -1
- package/dist/llm/llm.cjs.map +1 -1
- package/dist/llm/llm.d.cts +1 -0
- package/dist/llm/llm.d.ts +1 -0
- package/dist/llm/llm.d.ts.map +1 -1
- package/dist/llm/llm.js.map +1 -1
- package/dist/llm/provider_format/openai.cjs +43 -20
- package/dist/llm/provider_format/openai.cjs.map +1 -1
- package/dist/llm/provider_format/openai.d.ts.map +1 -1
- package/dist/llm/provider_format/openai.js +43 -20
- package/dist/llm/provider_format/openai.js.map +1 -1
- package/dist/llm/provider_format/openai.test.cjs +35 -0
- package/dist/llm/provider_format/openai.test.cjs.map +1 -1
- package/dist/llm/provider_format/openai.test.js +35 -0
- package/dist/llm/provider_format/openai.test.js.map +1 -1
- package/dist/llm/provider_format/utils.cjs +1 -1
- package/dist/llm/provider_format/utils.cjs.map +1 -1
- package/dist/llm/provider_format/utils.d.ts.map +1 -1
- package/dist/llm/provider_format/utils.js +1 -1
- package/dist/llm/provider_format/utils.js.map +1 -1
- package/dist/stream/stream_channel.cjs +3 -0
- package/dist/stream/stream_channel.cjs.map +1 -1
- package/dist/stream/stream_channel.d.cts +3 -2
- package/dist/stream/stream_channel.d.ts +3 -2
- package/dist/stream/stream_channel.d.ts.map +1 -1
- package/dist/stream/stream_channel.js +3 -0
- package/dist/stream/stream_channel.js.map +1 -1
- package/dist/telemetry/trace_types.cjs +15 -0
- package/dist/telemetry/trace_types.cjs.map +1 -1
- package/dist/telemetry/trace_types.d.cts +5 -0
- package/dist/telemetry/trace_types.d.ts +5 -0
- package/dist/telemetry/trace_types.d.ts.map +1 -1
- package/dist/telemetry/trace_types.js +10 -0
- package/dist/telemetry/trace_types.js.map +1 -1
- package/dist/utils/ws_transport.cjs +51 -0
- package/dist/utils/ws_transport.cjs.map +1 -0
- package/dist/utils/ws_transport.d.cts +9 -0
- package/dist/utils/ws_transport.d.ts +9 -0
- package/dist/utils/ws_transport.d.ts.map +1 -0
- package/dist/utils/ws_transport.js +17 -0
- package/dist/utils/ws_transport.js.map +1 -0
- package/dist/utils/ws_transport.test.cjs +212 -0
- package/dist/utils/ws_transport.test.cjs.map +1 -0
- package/dist/utils/ws_transport.test.js +211 -0
- package/dist/utils/ws_transport.test.js.map +1 -0
- package/dist/voice/agent_activity.cjs +49 -0
- package/dist/voice/agent_activity.cjs.map +1 -1
- package/dist/voice/agent_activity.d.cts +14 -0
- package/dist/voice/agent_activity.d.ts +14 -0
- package/dist/voice/agent_activity.d.ts.map +1 -1
- package/dist/voice/agent_activity.js +49 -0
- package/dist/voice/agent_activity.js.map +1 -1
- package/dist/voice/agent_session.cjs +12 -1
- package/dist/voice/agent_session.cjs.map +1 -1
- package/dist/voice/agent_session.d.cts +3 -0
- package/dist/voice/agent_session.d.ts +3 -0
- package/dist/voice/agent_session.d.ts.map +1 -1
- package/dist/voice/agent_session.js +12 -1
- package/dist/voice/agent_session.js.map +1 -1
- package/dist/voice/audio_recognition.cjs +124 -2
- package/dist/voice/audio_recognition.cjs.map +1 -1
- package/dist/voice/audio_recognition.d.cts +32 -1
- package/dist/voice/audio_recognition.d.ts +32 -1
- package/dist/voice/audio_recognition.d.ts.map +1 -1
- package/dist/voice/audio_recognition.js +127 -2
- package/dist/voice/audio_recognition.js.map +1 -1
- package/dist/voice/background_audio.cjs.map +1 -1
- package/dist/voice/generation.cjs +2 -1
- package/dist/voice/generation.cjs.map +1 -1
- package/dist/voice/generation.d.ts.map +1 -1
- package/dist/voice/generation.js +2 -1
- package/dist/voice/generation.js.map +1 -1
- package/package.json +2 -1
- package/src/index.ts +2 -0
- package/src/inference/interruption/AdaptiveInterruptionDetector.ts +166 -0
- package/src/inference/interruption/InterruptionStream.ts +397 -0
- package/src/inference/interruption/defaults.ts +33 -0
- package/src/inference/interruption/errors.ts +0 -0
- package/src/inference/interruption/http_transport.ts +61 -0
- package/src/inference/interruption/index.ts +4 -0
- package/src/inference/interruption/interruption.ts +88 -0
- package/src/inference/llm.ts +42 -3
- package/src/inference/utils.test.ts +31 -0
- package/src/inference/utils.ts +15 -0
- package/src/ipc/job_proc_lazy_main.ts +1 -1
- package/src/llm/chat_context.ts +32 -2
- package/src/llm/llm.ts +1 -0
- package/src/llm/provider_format/openai.test.ts +40 -0
- package/src/llm/provider_format/openai.ts +46 -19
- package/src/llm/provider_format/utils.ts +5 -1
- package/src/stream/stream_channel.ts +6 -2
- package/src/telemetry/trace_types.ts +7 -0
- package/src/utils/ws_transport.test.ts +282 -0
- package/src/utils/ws_transport.ts +22 -0
- package/src/voice/agent_activity.ts +61 -0
- package/src/voice/agent_session.ts +22 -2
- package/src/voice/audio_recognition.ts +161 -1
- package/src/voice/generation.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/inference/llm.ts"],"names":[],"mappings":"AAGA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAKL,KAAK,MAAM,EAEZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,YAAY,CAAC;AAI/D,MAAM,MAAM,YAAY,GACpB,cAAc,GACd,mBAAmB,GACnB,mBAAmB,GACnB,gBAAgB,GAChB,qBAAqB,GACrB,qBAAqB,GACrB,eAAe,GACf,oBAAoB,GACpB,qBAAqB,CAAC;AAE1B,MAAM,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/inference/llm.ts"],"names":[],"mappings":"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"}
|
package/dist/inference/llm.js
CHANGED
|
@@ -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
|
-
|
|
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":"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","names":["llm"]}
|
package/dist/inference/utils.cjs
CHANGED
|
@@ -19,7 +19,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var utils_exports = {};
|
|
20
20
|
__export(utils_exports, {
|
|
21
21
|
connectWs: () => connectWs,
|
|
22
|
-
createAccessToken: () => createAccessToken
|
|
22
|
+
createAccessToken: () => createAccessToken,
|
|
23
|
+
slidingWindowMinMax: () => slidingWindowMinMax
|
|
23
24
|
});
|
|
24
25
|
module.exports = __toCommonJS(utils_exports);
|
|
25
26
|
var import_livekit_server_sdk = require("livekit-server-sdk");
|
|
@@ -68,9 +69,21 @@ async function connectWs(url, headers, timeoutMs) {
|
|
|
68
69
|
socket.once("close", onClose);
|
|
69
70
|
});
|
|
70
71
|
}
|
|
72
|
+
function slidingWindowMinMax(probabilities, minWindow) {
|
|
73
|
+
if (probabilities.length < minWindow) {
|
|
74
|
+
return -Infinity;
|
|
75
|
+
}
|
|
76
|
+
let maxOfMins = -Infinity;
|
|
77
|
+
for (let i = 0; i <= probabilities.length - minWindow; i++) {
|
|
78
|
+
const windowMin = Math.min(...probabilities.slice(i, i + minWindow));
|
|
79
|
+
maxOfMins = Math.max(maxOfMins, windowMin);
|
|
80
|
+
}
|
|
81
|
+
return maxOfMins;
|
|
82
|
+
}
|
|
71
83
|
// Annotate the CommonJS export names for ESM import in node:
|
|
72
84
|
0 && (module.exports = {
|
|
73
85
|
connectWs,
|
|
74
|
-
createAccessToken
|
|
86
|
+
createAccessToken,
|
|
87
|
+
slidingWindowMinMax
|
|
75
88
|
});
|
|
76
89
|
//# sourceMappingURL=utils.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/inference/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AccessToken } from 'livekit-server-sdk';\nimport { WebSocket } from 'ws';\nimport { APIConnectionError, APIStatusError } from '../index.js';\n\nexport type AnyString = string & NonNullable<unknown>;\n\nexport async function createAccessToken(\n apiKey: string,\n apiSecret: string,\n ttl: number = 600,\n): Promise<string> {\n const token = new AccessToken(apiKey, apiSecret, { identity: 'agent', ttl });\n token.addInferenceGrant({ perform: true });\n\n return await token.toJwt();\n}\n\nexport async function connectWs(\n url: string,\n headers: Record<string, string>,\n timeoutMs: number,\n): Promise<WebSocket> {\n return new Promise<WebSocket>((resolve, reject) => {\n const socket = new WebSocket(url, { headers: headers });\n\n const timeout = setTimeout(() => {\n reject(new APIConnectionError({ message: 'Timeout connecting to LiveKit WebSocket' }));\n }, timeoutMs);\n\n const onOpen = () => {\n clearTimeout(timeout);\n resolve(socket);\n };\n\n const onError = (err: unknown) => {\n clearTimeout(timeout);\n if (err && typeof err === 'object' && 'code' in err && (err as any).code === 429) {\n reject(\n new APIStatusError({\n message: 'LiveKit gateway quota exceeded',\n options: { statusCode: 429 },\n }),\n );\n } else {\n reject(new APIConnectionError({ message: 'Error connecting to LiveKit WebSocket' }));\n }\n };\n\n const onClose = (code: number) => {\n clearTimeout(timeout);\n if (code !== 1000) {\n reject(\n new APIConnectionError({\n message: 'Connection closed unexpectedly',\n }),\n );\n }\n };\n socket.once('open', onOpen);\n socket.once('error', onError);\n socket.once('close', onClose);\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,gCAA4B;AAC5B,gBAA0B;AAC1B,eAAmD;AAInD,eAAsB,kBACpB,QACA,WACA,MAAc,KACG;AACjB,QAAM,QAAQ,IAAI,sCAAY,QAAQ,WAAW,EAAE,UAAU,SAAS,IAAI,CAAC;AAC3E,QAAM,kBAAkB,EAAE,SAAS,KAAK,CAAC;AAEzC,SAAO,MAAM,MAAM,MAAM;AAC3B;AAEA,eAAsB,UACpB,KACA,SACA,WACoB;AACpB,SAAO,IAAI,QAAmB,CAAC,SAAS,WAAW;AACjD,UAAM,SAAS,IAAI,oBAAU,KAAK,EAAE,QAAiB,CAAC;AAEtD,UAAM,UAAU,WAAW,MAAM;AAC/B,aAAO,IAAI,4BAAmB,EAAE,SAAS,0CAA0C,CAAC,CAAC;AAAA,IACvF,GAAG,SAAS;AAEZ,UAAM,SAAS,MAAM;AACnB,mBAAa,OAAO;AACpB,cAAQ,MAAM;AAAA,IAChB;AAEA,UAAM,UAAU,CAAC,QAAiB;AAChC,mBAAa,OAAO;AACpB,UAAI,OAAO,OAAO,QAAQ,YAAY,UAAU,OAAQ,IAAY,SAAS,KAAK;AAChF;AAAA,UACE,IAAI,wBAAe;AAAA,YACjB,SAAS;AAAA,YACT,SAAS,EAAE,YAAY,IAAI;AAAA,UAC7B,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,eAAO,IAAI,4BAAmB,EAAE,SAAS,wCAAwC,CAAC,CAAC;AAAA,MACrF;AAAA,IACF;AAEA,UAAM,UAAU,CAAC,SAAiB;AAChC,mBAAa,OAAO;AACpB,UAAI,SAAS,KAAM;AACjB;AAAA,UACE,IAAI,4BAAmB;AAAA,YACrB,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,MAAM;AAC1B,WAAO,KAAK,SAAS,OAAO;AAC5B,WAAO,KAAK,SAAS,OAAO;AAAA,EAC9B,CAAC;AACH;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/inference/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AccessToken } from 'livekit-server-sdk';\nimport { WebSocket } from 'ws';\nimport { APIConnectionError, APIStatusError } from '../index.js';\n\nexport type AnyString = string & NonNullable<unknown>;\n\nexport async function createAccessToken(\n apiKey: string,\n apiSecret: string,\n ttl: number = 600,\n): Promise<string> {\n const token = new AccessToken(apiKey, apiSecret, { identity: 'agent', ttl });\n token.addInferenceGrant({ perform: true });\n\n return await token.toJwt();\n}\n\nexport async function connectWs(\n url: string,\n headers: Record<string, string>,\n timeoutMs: number,\n): Promise<WebSocket> {\n return new Promise<WebSocket>((resolve, reject) => {\n const socket = new WebSocket(url, { headers: headers });\n\n const timeout = setTimeout(() => {\n reject(new APIConnectionError({ message: 'Timeout connecting to LiveKit WebSocket' }));\n }, timeoutMs);\n\n const onOpen = () => {\n clearTimeout(timeout);\n resolve(socket);\n };\n\n const onError = (err: unknown) => {\n clearTimeout(timeout);\n if (err && typeof err === 'object' && 'code' in err && (err as any).code === 429) {\n reject(\n new APIStatusError({\n message: 'LiveKit gateway quota exceeded',\n options: { statusCode: 429 },\n }),\n );\n } else {\n reject(new APIConnectionError({ message: 'Error connecting to LiveKit WebSocket' }));\n }\n };\n\n const onClose = (code: number) => {\n clearTimeout(timeout);\n if (code !== 1000) {\n reject(\n new APIConnectionError({\n message: 'Connection closed unexpectedly',\n }),\n );\n }\n };\n socket.once('open', onOpen);\n socket.once('error', onError);\n socket.once('close', onClose);\n });\n}\n\nexport function slidingWindowMinMax(probabilities: Float32Array, minWindow: number): number {\n if (probabilities.length < minWindow) {\n return -Infinity;\n }\n\n let maxOfMins = -Infinity;\n\n for (let i = 0; i <= probabilities.length - minWindow; i++) {\n const windowMin = Math.min(...probabilities.slice(i, i + minWindow));\n maxOfMins = Math.max(maxOfMins, windowMin);\n }\n\n return maxOfMins;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,gCAA4B;AAC5B,gBAA0B;AAC1B,eAAmD;AAInD,eAAsB,kBACpB,QACA,WACA,MAAc,KACG;AACjB,QAAM,QAAQ,IAAI,sCAAY,QAAQ,WAAW,EAAE,UAAU,SAAS,IAAI,CAAC;AAC3E,QAAM,kBAAkB,EAAE,SAAS,KAAK,CAAC;AAEzC,SAAO,MAAM,MAAM,MAAM;AAC3B;AAEA,eAAsB,UACpB,KACA,SACA,WACoB;AACpB,SAAO,IAAI,QAAmB,CAAC,SAAS,WAAW;AACjD,UAAM,SAAS,IAAI,oBAAU,KAAK,EAAE,QAAiB,CAAC;AAEtD,UAAM,UAAU,WAAW,MAAM;AAC/B,aAAO,IAAI,4BAAmB,EAAE,SAAS,0CAA0C,CAAC,CAAC;AAAA,IACvF,GAAG,SAAS;AAEZ,UAAM,SAAS,MAAM;AACnB,mBAAa,OAAO;AACpB,cAAQ,MAAM;AAAA,IAChB;AAEA,UAAM,UAAU,CAAC,QAAiB;AAChC,mBAAa,OAAO;AACpB,UAAI,OAAO,OAAO,QAAQ,YAAY,UAAU,OAAQ,IAAY,SAAS,KAAK;AAChF;AAAA,UACE,IAAI,wBAAe;AAAA,YACjB,SAAS;AAAA,YACT,SAAS,EAAE,YAAY,IAAI;AAAA,UAC7B,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,eAAO,IAAI,4BAAmB,EAAE,SAAS,wCAAwC,CAAC,CAAC;AAAA,MACrF;AAAA,IACF;AAEA,UAAM,UAAU,CAAC,SAAiB;AAChC,mBAAa,OAAO;AACpB,UAAI,SAAS,KAAM;AACjB;AAAA,UACE,IAAI,4BAAmB;AAAA,YACrB,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,MAAM;AAC1B,WAAO,KAAK,SAAS,OAAO;AAC5B,WAAO,KAAK,SAAS,OAAO;AAAA,EAC9B,CAAC;AACH;AAEO,SAAS,oBAAoB,eAA6B,WAA2B;AAC1F,MAAI,cAAc,SAAS,WAAW;AACpC,WAAO;AAAA,EACT;AAEA,MAAI,YAAY;AAEhB,WAAS,IAAI,GAAG,KAAK,cAAc,SAAS,WAAW,KAAK;AAC1D,UAAM,YAAY,KAAK,IAAI,GAAG,cAAc,MAAM,GAAG,IAAI,SAAS,CAAC;AACnE,gBAAY,KAAK,IAAI,WAAW,SAAS;AAAA,EAC3C;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -2,4 +2,5 @@ import { WebSocket } from 'ws';
|
|
|
2
2
|
export type AnyString = string & NonNullable<unknown>;
|
|
3
3
|
export declare function createAccessToken(apiKey: string, apiSecret: string, ttl?: number): Promise<string>;
|
|
4
4
|
export declare function connectWs(url: string, headers: Record<string, string>, timeoutMs: number): Promise<WebSocket>;
|
|
5
|
+
export declare function slidingWindowMinMax(probabilities: Float32Array, minWindow: number): number;
|
|
5
6
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -2,4 +2,5 @@ import { WebSocket } from 'ws';
|
|
|
2
2
|
export type AnyString = string & NonNullable<unknown>;
|
|
3
3
|
export declare function createAccessToken(apiKey: string, apiSecret: string, ttl?: number): Promise<string>;
|
|
4
4
|
export declare function connectWs(url: string, headers: Record<string, string>, timeoutMs: number): Promise<WebSocket>;
|
|
5
|
+
export declare function slidingWindowMinMax(probabilities: Float32Array, minWindow: number): number;
|
|
5
6
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/inference/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAG/B,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AAEtD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAY,GAChB,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,SAAS,CAAC,CAyCpB"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/inference/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAG/B,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AAEtD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAY,GAChB,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,SAAS,CAAC,CAyCpB;AAED,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAa1F"}
|
package/dist/inference/utils.js
CHANGED
|
@@ -44,8 +44,20 @@ async function connectWs(url, headers, timeoutMs) {
|
|
|
44
44
|
socket.once("close", onClose);
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
|
+
function slidingWindowMinMax(probabilities, minWindow) {
|
|
48
|
+
if (probabilities.length < minWindow) {
|
|
49
|
+
return -Infinity;
|
|
50
|
+
}
|
|
51
|
+
let maxOfMins = -Infinity;
|
|
52
|
+
for (let i = 0; i <= probabilities.length - minWindow; i++) {
|
|
53
|
+
const windowMin = Math.min(...probabilities.slice(i, i + minWindow));
|
|
54
|
+
maxOfMins = Math.max(maxOfMins, windowMin);
|
|
55
|
+
}
|
|
56
|
+
return maxOfMins;
|
|
57
|
+
}
|
|
47
58
|
export {
|
|
48
59
|
connectWs,
|
|
49
|
-
createAccessToken
|
|
60
|
+
createAccessToken,
|
|
61
|
+
slidingWindowMinMax
|
|
50
62
|
};
|
|
51
63
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/inference/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AccessToken } from 'livekit-server-sdk';\nimport { WebSocket } from 'ws';\nimport { APIConnectionError, APIStatusError } from '../index.js';\n\nexport type AnyString = string & NonNullable<unknown>;\n\nexport async function createAccessToken(\n apiKey: string,\n apiSecret: string,\n ttl: number = 600,\n): Promise<string> {\n const token = new AccessToken(apiKey, apiSecret, { identity: 'agent', ttl });\n token.addInferenceGrant({ perform: true });\n\n return await token.toJwt();\n}\n\nexport async function connectWs(\n url: string,\n headers: Record<string, string>,\n timeoutMs: number,\n): Promise<WebSocket> {\n return new Promise<WebSocket>((resolve, reject) => {\n const socket = new WebSocket(url, { headers: headers });\n\n const timeout = setTimeout(() => {\n reject(new APIConnectionError({ message: 'Timeout connecting to LiveKit WebSocket' }));\n }, timeoutMs);\n\n const onOpen = () => {\n clearTimeout(timeout);\n resolve(socket);\n };\n\n const onError = (err: unknown) => {\n clearTimeout(timeout);\n if (err && typeof err === 'object' && 'code' in err && (err as any).code === 429) {\n reject(\n new APIStatusError({\n message: 'LiveKit gateway quota exceeded',\n options: { statusCode: 429 },\n }),\n );\n } else {\n reject(new APIConnectionError({ message: 'Error connecting to LiveKit WebSocket' }));\n }\n };\n\n const onClose = (code: number) => {\n clearTimeout(timeout);\n if (code !== 1000) {\n reject(\n new APIConnectionError({\n message: 'Connection closed unexpectedly',\n }),\n );\n }\n };\n socket.once('open', onOpen);\n socket.once('error', onError);\n socket.once('close', onClose);\n });\n}\n"],"mappings":"AAGA,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,oBAAoB,sBAAsB;AAInD,eAAsB,kBACpB,QACA,WACA,MAAc,KACG;AACjB,QAAM,QAAQ,IAAI,YAAY,QAAQ,WAAW,EAAE,UAAU,SAAS,IAAI,CAAC;AAC3E,QAAM,kBAAkB,EAAE,SAAS,KAAK,CAAC;AAEzC,SAAO,MAAM,MAAM,MAAM;AAC3B;AAEA,eAAsB,UACpB,KACA,SACA,WACoB;AACpB,SAAO,IAAI,QAAmB,CAAC,SAAS,WAAW;AACjD,UAAM,SAAS,IAAI,UAAU,KAAK,EAAE,QAAiB,CAAC;AAEtD,UAAM,UAAU,WAAW,MAAM;AAC/B,aAAO,IAAI,mBAAmB,EAAE,SAAS,0CAA0C,CAAC,CAAC;AAAA,IACvF,GAAG,SAAS;AAEZ,UAAM,SAAS,MAAM;AACnB,mBAAa,OAAO;AACpB,cAAQ,MAAM;AAAA,IAChB;AAEA,UAAM,UAAU,CAAC,QAAiB;AAChC,mBAAa,OAAO;AACpB,UAAI,OAAO,OAAO,QAAQ,YAAY,UAAU,OAAQ,IAAY,SAAS,KAAK;AAChF;AAAA,UACE,IAAI,eAAe;AAAA,YACjB,SAAS;AAAA,YACT,SAAS,EAAE,YAAY,IAAI;AAAA,UAC7B,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,eAAO,IAAI,mBAAmB,EAAE,SAAS,wCAAwC,CAAC,CAAC;AAAA,MACrF;AAAA,IACF;AAEA,UAAM,UAAU,CAAC,SAAiB;AAChC,mBAAa,OAAO;AACpB,UAAI,SAAS,KAAM;AACjB;AAAA,UACE,IAAI,mBAAmB;AAAA,YACrB,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,MAAM;AAC1B,WAAO,KAAK,SAAS,OAAO;AAC5B,WAAO,KAAK,SAAS,OAAO;AAAA,EAC9B,CAAC;AACH;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/inference/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AccessToken } from 'livekit-server-sdk';\nimport { WebSocket } from 'ws';\nimport { APIConnectionError, APIStatusError } from '../index.js';\n\nexport type AnyString = string & NonNullable<unknown>;\n\nexport async function createAccessToken(\n apiKey: string,\n apiSecret: string,\n ttl: number = 600,\n): Promise<string> {\n const token = new AccessToken(apiKey, apiSecret, { identity: 'agent', ttl });\n token.addInferenceGrant({ perform: true });\n\n return await token.toJwt();\n}\n\nexport async function connectWs(\n url: string,\n headers: Record<string, string>,\n timeoutMs: number,\n): Promise<WebSocket> {\n return new Promise<WebSocket>((resolve, reject) => {\n const socket = new WebSocket(url, { headers: headers });\n\n const timeout = setTimeout(() => {\n reject(new APIConnectionError({ message: 'Timeout connecting to LiveKit WebSocket' }));\n }, timeoutMs);\n\n const onOpen = () => {\n clearTimeout(timeout);\n resolve(socket);\n };\n\n const onError = (err: unknown) => {\n clearTimeout(timeout);\n if (err && typeof err === 'object' && 'code' in err && (err as any).code === 429) {\n reject(\n new APIStatusError({\n message: 'LiveKit gateway quota exceeded',\n options: { statusCode: 429 },\n }),\n );\n } else {\n reject(new APIConnectionError({ message: 'Error connecting to LiveKit WebSocket' }));\n }\n };\n\n const onClose = (code: number) => {\n clearTimeout(timeout);\n if (code !== 1000) {\n reject(\n new APIConnectionError({\n message: 'Connection closed unexpectedly',\n }),\n );\n }\n };\n socket.once('open', onOpen);\n socket.once('error', onError);\n socket.once('close', onClose);\n });\n}\n\nexport function slidingWindowMinMax(probabilities: Float32Array, minWindow: number): number {\n if (probabilities.length < minWindow) {\n return -Infinity;\n }\n\n let maxOfMins = -Infinity;\n\n for (let i = 0; i <= probabilities.length - minWindow; i++) {\n const windowMin = Math.min(...probabilities.slice(i, i + minWindow));\n maxOfMins = Math.max(maxOfMins, windowMin);\n }\n\n return maxOfMins;\n}\n"],"mappings":"AAGA,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,oBAAoB,sBAAsB;AAInD,eAAsB,kBACpB,QACA,WACA,MAAc,KACG;AACjB,QAAM,QAAQ,IAAI,YAAY,QAAQ,WAAW,EAAE,UAAU,SAAS,IAAI,CAAC;AAC3E,QAAM,kBAAkB,EAAE,SAAS,KAAK,CAAC;AAEzC,SAAO,MAAM,MAAM,MAAM;AAC3B;AAEA,eAAsB,UACpB,KACA,SACA,WACoB;AACpB,SAAO,IAAI,QAAmB,CAAC,SAAS,WAAW;AACjD,UAAM,SAAS,IAAI,UAAU,KAAK,EAAE,QAAiB,CAAC;AAEtD,UAAM,UAAU,WAAW,MAAM;AAC/B,aAAO,IAAI,mBAAmB,EAAE,SAAS,0CAA0C,CAAC,CAAC;AAAA,IACvF,GAAG,SAAS;AAEZ,UAAM,SAAS,MAAM;AACnB,mBAAa,OAAO;AACpB,cAAQ,MAAM;AAAA,IAChB;AAEA,UAAM,UAAU,CAAC,QAAiB;AAChC,mBAAa,OAAO;AACpB,UAAI,OAAO,OAAO,QAAQ,YAAY,UAAU,OAAQ,IAAY,SAAS,KAAK;AAChF;AAAA,UACE,IAAI,eAAe;AAAA,YACjB,SAAS;AAAA,YACT,SAAS,EAAE,YAAY,IAAI;AAAA,UAC7B,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,eAAO,IAAI,mBAAmB,EAAE,SAAS,wCAAwC,CAAC,CAAC;AAAA,MACrF;AAAA,IACF;AAEA,UAAM,UAAU,CAAC,SAAiB;AAChC,mBAAa,OAAO;AACpB,UAAI,SAAS,KAAM;AACjB;AAAA,UACE,IAAI,mBAAmB;AAAA,YACrB,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,MAAM;AAC1B,WAAO,KAAK,SAAS,OAAO;AAC5B,WAAO,KAAK,SAAS,OAAO;AAAA,EAC9B,CAAC;AACH;AAEO,SAAS,oBAAoB,eAA6B,WAA2B;AAC1F,MAAI,cAAc,SAAS,WAAW;AACpC,WAAO;AAAA,EACT;AAEA,MAAI,YAAY;AAEhB,WAAS,IAAI,GAAG,KAAK,cAAc,SAAS,WAAW,KAAK;AAC1D,UAAM,YAAY,KAAK,IAAI,GAAG,cAAc,MAAM,GAAG,IAAI,SAAS,CAAC;AACnE,gBAAY,KAAK,IAAI,WAAW,SAAS;AAAA,EAC3C;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_vitest = require("vitest");
|
|
3
|
+
var import_utils = require("./utils.cjs");
|
|
4
|
+
(0, import_vitest.describe)("slidingWindowMinMax", () => {
|
|
5
|
+
(0, import_vitest.it)("returns -Infinity when array is shorter than window size", () => {
|
|
6
|
+
(0, import_vitest.expect)((0, import_utils.slidingWindowMinMax)([0.5, 0.6], 3)).toBe(-Infinity);
|
|
7
|
+
(0, import_vitest.expect)((0, import_utils.slidingWindowMinMax)([], 1)).toBe(-Infinity);
|
|
8
|
+
});
|
|
9
|
+
(0, import_vitest.it)("returns the max value when window size is 1", () => {
|
|
10
|
+
(0, import_vitest.expect)((0, import_utils.slidingWindowMinMax)([0.1, 0.5, 0.3, 0.8, 0.2], 1)).toBe(0.8);
|
|
11
|
+
});
|
|
12
|
+
(0, import_vitest.it)("finds the best sustained probability across windows", () => {
|
|
13
|
+
(0, import_vitest.expect)((0, import_utils.slidingWindowMinMax)([0.2, 0.8, 0.7, 0.3, 0.9], 3)).toBe(0.3);
|
|
14
|
+
});
|
|
15
|
+
(0, import_vitest.it)("returns the single element when array length equals window size", () => {
|
|
16
|
+
(0, import_vitest.expect)((0, import_utils.slidingWindowMinMax)([0.5, 0.9, 0.7], 3)).toBe(0.5);
|
|
17
|
+
(0, import_vitest.expect)((0, import_utils.slidingWindowMinMax)([0.8], 1)).toBe(0.8);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=utils.test.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/inference/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { describe, expect, it } from 'vitest';\nimport { slidingWindowMinMax } from './utils.js';\n\ndescribe('slidingWindowMinMax', () => {\n it('returns -Infinity when array is shorter than window size', () => {\n expect(slidingWindowMinMax([0.5, 0.6], 3)).toBe(-Infinity);\n expect(slidingWindowMinMax([], 1)).toBe(-Infinity);\n });\n\n it('returns the max value when window size is 1', () => {\n // With window size 1, min of each window is the element itself,\n // so max of mins is just the max of the array\n expect(slidingWindowMinMax([0.1, 0.5, 0.3, 0.8, 0.2], 1)).toBe(0.8);\n });\n\n it('finds the best sustained probability across windows', () => {\n // Windows of size 3: [0.2, 0.8, 0.7], [0.8, 0.7, 0.3], [0.7, 0.3, 0.9]\n // Mins: 0.2, 0.3, 0.3\n // Max of mins: 0.3\n expect(slidingWindowMinMax([0.2, 0.8, 0.7, 0.3, 0.9], 3)).toBe(0.3);\n });\n\n it('returns the single element when array length equals window size', () => {\n // Only one window covering the entire array, return min of that window\n expect(slidingWindowMinMax([0.5, 0.9, 0.7], 3)).toBe(0.5);\n expect(slidingWindowMinMax([0.8], 1)).toBe(0.8);\n });\n});\n"],"mappings":";AAGA,oBAAqC;AACrC,mBAAoC;AAAA,IAEpC,wBAAS,uBAAuB,MAAM;AACpC,wBAAG,4DAA4D,MAAM;AACnE,kCAAO,kCAAoB,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,SAAS;AACzD,kCAAO,kCAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,SAAS;AAAA,EACnD,CAAC;AAED,wBAAG,+CAA+C,MAAM;AAGtD,kCAAO,kCAAoB,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,EACpE,CAAC;AAED,wBAAG,uDAAuD,MAAM;AAI9D,kCAAO,kCAAoB,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,EACpE,CAAC;AAED,wBAAG,mEAAmE,MAAM;AAE1E,kCAAO,kCAAoB,CAAC,KAAK,KAAK,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG;AACxD,kCAAO,kCAAoB,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,EAChD,CAAC;AACH,CAAC;","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { slidingWindowMinMax } from "./utils.js";
|
|
3
|
+
describe("slidingWindowMinMax", () => {
|
|
4
|
+
it("returns -Infinity when array is shorter than window size", () => {
|
|
5
|
+
expect(slidingWindowMinMax([0.5, 0.6], 3)).toBe(-Infinity);
|
|
6
|
+
expect(slidingWindowMinMax([], 1)).toBe(-Infinity);
|
|
7
|
+
});
|
|
8
|
+
it("returns the max value when window size is 1", () => {
|
|
9
|
+
expect(slidingWindowMinMax([0.1, 0.5, 0.3, 0.8, 0.2], 1)).toBe(0.8);
|
|
10
|
+
});
|
|
11
|
+
it("finds the best sustained probability across windows", () => {
|
|
12
|
+
expect(slidingWindowMinMax([0.2, 0.8, 0.7, 0.3, 0.9], 3)).toBe(0.3);
|
|
13
|
+
});
|
|
14
|
+
it("returns the single element when array length equals window size", () => {
|
|
15
|
+
expect(slidingWindowMinMax([0.5, 0.9, 0.7], 3)).toBe(0.5);
|
|
16
|
+
expect(slidingWindowMinMax([0.8], 1)).toBe(0.8);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=utils.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/inference/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { describe, expect, it } from 'vitest';\nimport { slidingWindowMinMax } from './utils.js';\n\ndescribe('slidingWindowMinMax', () => {\n it('returns -Infinity when array is shorter than window size', () => {\n expect(slidingWindowMinMax([0.5, 0.6], 3)).toBe(-Infinity);\n expect(slidingWindowMinMax([], 1)).toBe(-Infinity);\n });\n\n it('returns the max value when window size is 1', () => {\n // With window size 1, min of each window is the element itself,\n // so max of mins is just the max of the array\n expect(slidingWindowMinMax([0.1, 0.5, 0.3, 0.8, 0.2], 1)).toBe(0.8);\n });\n\n it('finds the best sustained probability across windows', () => {\n // Windows of size 3: [0.2, 0.8, 0.7], [0.8, 0.7, 0.3], [0.7, 0.3, 0.9]\n // Mins: 0.2, 0.3, 0.3\n // Max of mins: 0.3\n expect(slidingWindowMinMax([0.2, 0.8, 0.7, 0.3, 0.9], 3)).toBe(0.3);\n });\n\n it('returns the single element when array length equals window size', () => {\n // Only one window covering the entire array, return min of that window\n expect(slidingWindowMinMax([0.5, 0.9, 0.7], 3)).toBe(0.5);\n expect(slidingWindowMinMax([0.8], 1)).toBe(0.8);\n });\n});\n"],"mappings":"AAGA,SAAS,UAAU,QAAQ,UAAU;AACrC,SAAS,2BAA2B;AAEpC,SAAS,uBAAuB,MAAM;AACpC,KAAG,4DAA4D,MAAM;AACnE,WAAO,oBAAoB,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,SAAS;AACzD,WAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,SAAS;AAAA,EACnD,CAAC;AAED,KAAG,+CAA+C,MAAM;AAGtD,WAAO,oBAAoB,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,EACpE,CAAC;AAED,KAAG,uDAAuD,MAAM;AAI9D,WAAO,oBAAoB,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,EACpE,CAAC;AAED,KAAG,mEAAmE,MAAM;AAE1E,WAAO,oBAAoB,CAAC,KAAK,KAAK,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG;AACxD,WAAO,oBAAoB,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,EAChD,CAAC;AACH,CAAC;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ipc/inference_proc_executor.ts","../../../node_modules/.pnpm/tsup@8.4.0_@microsoft+api-extractor@7.43.7_@types+node@22.15.30__postcss@8.
|
|
1
|
+
{"version":3,"sources":["../../src/ipc/inference_proc_executor.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: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { ChildProcess } from 'node:child_process';\nimport { fork } from 'node:child_process';\nimport { extname } from 'node:path';\nimport { log } from '../log.js';\nimport { shortuuid } from '../utils.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { IPCMessage } from './message.js';\nimport { SupervisedProc } from './supervised_proc.js';\n\nclass PendingInference {\n promise = new Promise<{ requestId: string; data: unknown; error?: Error }>((resolve) => {\n this.resolve = resolve;\n });\n resolve(arg: { requestId: string; data: unknown; error?: Error }) {\n arg;\n }\n}\n\nconst currentFileExtension = extname(import.meta.url);\n\nexport class InferenceProcExecutor extends SupervisedProc implements InferenceExecutor {\n #runners: { [id: string]: string };\n #activeRequests: { [id: string]: PendingInference } = {};\n #logger = log();\n\n constructor({\n runners,\n initializeTimeout,\n closeTimeout,\n memoryWarnMB,\n memoryLimitMB,\n pingInterval,\n pingTimeout,\n highPingThreshold,\n }: {\n runners: { [id: string]: string };\n initializeTimeout: number;\n closeTimeout: number;\n memoryWarnMB: number;\n memoryLimitMB: number;\n pingInterval: number;\n pingTimeout: number;\n highPingThreshold: number;\n }) {\n super(\n initializeTimeout,\n closeTimeout,\n memoryWarnMB,\n memoryLimitMB,\n pingInterval,\n pingTimeout,\n highPingThreshold,\n );\n this.#runners = runners;\n }\n\n createProcess(): ChildProcess {\n const forkUrl = new URL(`./inference_proc_lazy_main${currentFileExtension}`, import.meta.url);\n\n // When running via tsx/ts-node (TypeScript files), we need to inherit the parent's\n // execArgv so the child process can also execute TypeScript with the same loader\n const isTypeScript = currentFileExtension === '.ts';\n const forkOptions = isTypeScript ? { execArgv: process.execArgv } : undefined;\n\n return fork(forkUrl, [JSON.stringify(this.#runners)], forkOptions);\n }\n\n async mainTask(proc: ChildProcess) {\n proc.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceResponse':\n const res = this.#activeRequests[msg.value.requestId];\n delete this.#activeRequests[msg.value.requestId];\n if (!res) {\n this.#logger\n .child({ requestId: msg.value.requestId })\n .warn('received unexpected inference response');\n return;\n }\n\n res.resolve(msg.value);\n }\n });\n }\n\n async doInference(method: string, data: unknown): Promise<unknown> {\n const requestId = shortuuid('inference_req_');\n const fut = new PendingInference();\n this.proc!.send({ case: 'inferenceRequest', value: { requestId, method, data } });\n this.#activeRequests[requestId] = fut;\n\n const res = await fut.promise;\n if (res.error) {\n throw new Error(`inference of ${method} failed: ${res.error}`);\n }\n return res.data;\n }\n}\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () =>\n typeof document === 'undefined'\n ? new URL(`file:${__filename}`).href\n : (document.currentScript && document.currentScript.src) ||\n new URL('main.js', document.baseURI).href\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACKA,IAAM,mBAAmB,MACvB,OAAO,aAAa,cAChB,IAAI,IAAI,QAAQ,UAAU,EAAE,EAAE,OAC7B,SAAS,iBAAiB,SAAS,cAAc,OAClD,IAAI,IAAI,WAAW,SAAS,OAAO,EAAE;AAEpC,IAAM,gBAAgC,iCAAiB;ADP9D,gCAAqB;AACrB,uBAAwB;AACxB,iBAAoB;AACpB,mBAA0B;AAG1B,6BAA+B;AAE/B,MAAM,iBAAiB;AAAA,EACrB,UAAU,IAAI,QAA6D,CAAC,YAAY;AACtF,SAAK,UAAU;AAAA,EACjB,CAAC;AAAA,EACD,QAAQ,KAA0D;AAChE;AAAA,EACF;AACF;AAEA,MAAM,2BAAuB,0BAAQ,aAAe;AAE7C,MAAM,8BAA8B,sCAA4C;AAAA,EACrF;AAAA,EACA,kBAAsD,CAAC;AAAA,EACvD,cAAU,gBAAI;AAAA,EAEd,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GASG;AACD;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,gBAA8B;AAC5B,UAAM,UAAU,IAAI,IAAI,6BAA6B,oBAAoB,IAAI,aAAe;AAI5F,UAAM,eAAe,yBAAyB;AAC9C,UAAM,cAAc,eAAe,EAAE,UAAU,QAAQ,SAAS,IAAI;AAEpE,eAAO,gCAAK,SAAS,CAAC,KAAK,UAAU,KAAK,QAAQ,CAAC,GAAG,WAAW;AAAA,EACnE;AAAA,EAEA,MAAM,SAAS,MAAoB;AACjC,SAAK,GAAG,WAAW,CAAC,QAAoB;AACtC,cAAQ,IAAI,MAAM;AAAA,QAChB,KAAK;AACH,gBAAM,MAAM,KAAK,gBAAgB,IAAI,MAAM,SAAS;AACpD,iBAAO,KAAK,gBAAgB,IAAI,MAAM,SAAS;AAC/C,cAAI,CAAC,KAAK;AACR,iBAAK,QACF,MAAM,EAAE,WAAW,IAAI,MAAM,UAAU,CAAC,EACxC,KAAK,wCAAwC;AAChD;AAAA,UACF;AAEA,cAAI,QAAQ,IAAI,KAAK;AAAA,MACzB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,YAAY,QAAgB,MAAiC;AACjE,UAAM,gBAAY,wBAAU,gBAAgB;AAC5C,UAAM,MAAM,IAAI,iBAAiB;AACjC,SAAK,KAAM,KAAK,EAAE,MAAM,oBAAoB,OAAO,EAAE,WAAW,QAAQ,KAAK,EAAE,CAAC;AAChF,SAAK,gBAAgB,SAAS,IAAI;AAElC,UAAM,MAAM,MAAM,IAAI;AACtB,QAAI,IAAI,OAAO;AACb,YAAM,IAAI,MAAM,gBAAgB,MAAM,YAAY,IAAI,KAAK,EAAE;AAAA,IAC/D;AACA,WAAO,IAAI;AAAA,EACb;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ipc/job_proc_executor.ts","../../../node_modules/.pnpm/tsup@8.4.0_@microsoft+api-extractor@7.43.7_@types+node@22.15.30__postcss@8.
|
|
1
|
+
{"version":3,"sources":["../../src/ipc/job_proc_executor.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: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { ChildProcess } from 'node:child_process';\nimport { fork } from 'node:child_process';\nimport { extname } from 'node:path';\nimport type { RunningJobInfo } from '../job.js';\nimport { log } from '../log.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { JobExecutor } from './job_executor.js';\nimport { JobStatus } from './job_executor.js';\nimport type { IPCMessage } from './message.js';\nimport { SupervisedProc } from './supervised_proc.js';\n\nconst currentFileExtension = extname(import.meta.url);\n\nexport class JobProcExecutor extends SupervisedProc implements JobExecutor {\n #userArgs?: any; // eslint-disable-line @typescript-eslint/no-explicit-any\n #jobStatus?: JobStatus;\n #runningJob?: RunningJobInfo;\n #agent: string;\n #inferenceExecutor?: InferenceExecutor;\n #inferenceTasks: Promise<void>[] = [];\n #logger = log();\n\n constructor(\n agent: string,\n inferenceExecutor: InferenceExecutor | undefined,\n initializeTimeout: number,\n closeTimeout: number,\n memoryWarnMB: number,\n memoryLimitMB: number,\n pingInterval: number,\n pingTimeout: number,\n highPingThreshold: number,\n ) {\n super(\n initializeTimeout,\n closeTimeout,\n memoryWarnMB,\n memoryLimitMB,\n pingInterval,\n pingTimeout,\n highPingThreshold,\n );\n this.#agent = agent;\n this.#inferenceExecutor = inferenceExecutor;\n }\n\n get status(): JobStatus {\n if (this.#jobStatus) {\n return this.#jobStatus;\n }\n throw new Error('job status not available');\n }\n\n get userArguments(): any {\n return this.#userArgs;\n }\n\n set userArguments(args: any) {\n this.#userArgs = args;\n }\n\n get runningJob(): RunningJobInfo | undefined {\n return this.#runningJob;\n }\n\n createProcess(): ChildProcess {\n const forkUrl = new URL(`./job_proc_lazy_main${currentFileExtension}`, import.meta.url);\n\n // When running via tsx/ts-node (TypeScript files), we need to inherit the parent's\n // execArgv so the child process can also execute TypeScript with the same loader\n const isTypeScript = currentFileExtension === '.ts';\n const forkOptions = isTypeScript ? { execArgv: process.execArgv } : undefined;\n\n return fork(forkUrl, [this.#agent], forkOptions);\n }\n\n async mainTask(proc: ChildProcess) {\n proc.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceRequest':\n this.#inferenceTasks.push(this.#doInferenceTask(proc, msg.value));\n }\n });\n }\n\n async #doInferenceTask(\n proc: ChildProcess,\n req: { method: string; requestId: string; data: unknown },\n ) {\n if (!this.#inferenceExecutor) {\n this.#logger.warn('inference request received but no inference executor');\n proc.send({\n case: 'inferenceResponse',\n value: { requestId: req.requestId, error: new Error('no inference executor') },\n });\n return;\n }\n\n try {\n const data = await this.#inferenceExecutor.doInference(req.method, req.data);\n proc.send({ case: 'inferenceResponse', value: { requestId: req.requestId, data } });\n } catch (error) {\n proc.send({ case: 'inferenceResponse', value: { requestId: req.requestId, error } });\n }\n }\n\n async launchJob(info: RunningJobInfo) {\n if (this.#runningJob) {\n throw Error('process already has a running job');\n }\n if (!this.init.done) {\n throw Error('process not initialized');\n }\n this.#jobStatus = JobStatus.RUNNING;\n this.#runningJob = info;\n\n this.proc!.send({ case: 'startJobRequest', value: { runningJob: info } });\n }\n}\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () =>\n typeof document === 'undefined'\n ? new URL(`file:${__filename}`).href\n : (document.currentScript && document.currentScript.src) ||\n new URL('main.js', document.baseURI).href\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACKA,IAAM,mBAAmB,MACvB,OAAO,aAAa,cAChB,IAAI,IAAI,QAAQ,UAAU,EAAE,EAAE,OAC7B,SAAS,iBAAiB,SAAS,cAAc,OAClD,IAAI,IAAI,WAAW,SAAS,OAAO,EAAE;AAEpC,IAAM,gBAAgC,iCAAiB;ADP9D,gCAAqB;AACrB,uBAAwB;AAExB,iBAAoB;AAGpB,0BAA0B;AAE1B,6BAA+B;AAE/B,MAAM,2BAAuB,0BAAQ,aAAe;AAE7C,MAAM,wBAAwB,sCAAsC;AAAA,EACzE;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAmC,CAAC;AAAA,EACpC,cAAU,gBAAI;AAAA,EAEd,YACE,OACA,mBACA,mBACA,cACA,cACA,eACA,cACA,aACA,mBACA;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,SAAS;AACd,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEA,IAAI,SAAoB;AACtB,QAAI,KAAK,YAAY;AACnB,aAAO,KAAK;AAAA,IACd;AACA,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AAAA,EAEA,IAAI,gBAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,cAAc,MAAW;AAC3B,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,IAAI,aAAyC;AAC3C,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,gBAA8B;AAC5B,UAAM,UAAU,IAAI,IAAI,uBAAuB,oBAAoB,IAAI,aAAe;AAItF,UAAM,eAAe,yBAAyB;AAC9C,UAAM,cAAc,eAAe,EAAE,UAAU,QAAQ,SAAS,IAAI;AAEpE,eAAO,gCAAK,SAAS,CAAC,KAAK,MAAM,GAAG,WAAW;AAAA,EACjD;AAAA,EAEA,MAAM,SAAS,MAAoB;AACjC,SAAK,GAAG,WAAW,CAAC,QAAoB;AACtC,cAAQ,IAAI,MAAM;AAAA,QAChB,KAAK;AACH,eAAK,gBAAgB,KAAK,KAAK,iBAAiB,MAAM,IAAI,KAAK,CAAC;AAAA,MACpE;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBACJ,MACA,KACA;AACA,QAAI,CAAC,KAAK,oBAAoB;AAC5B,WAAK,QAAQ,KAAK,sDAAsD;AACxE,WAAK,KAAK;AAAA,QACR,MAAM;AAAA,QACN,OAAO,EAAE,WAAW,IAAI,WAAW,OAAO,IAAI,MAAM,uBAAuB,EAAE;AAAA,MAC/E,CAAC;AACD;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,mBAAmB,YAAY,IAAI,QAAQ,IAAI,IAAI;AAC3E,WAAK,KAAK,EAAE,MAAM,qBAAqB,OAAO,EAAE,WAAW,IAAI,WAAW,KAAK,EAAE,CAAC;AAAA,IACpF,SAAS,OAAO;AACd,WAAK,KAAK,EAAE,MAAM,qBAAqB,OAAO,EAAE,WAAW,IAAI,WAAW,MAAM,EAAE,CAAC;AAAA,IACrF;AAAA,EACF;AAAA,EAEA,MAAM,UAAU,MAAsB;AACpC,QAAI,KAAK,aAAa;AACpB,YAAM,MAAM,mCAAmC;AAAA,IACjD;AACA,QAAI,CAAC,KAAK,KAAK,MAAM;AACnB,YAAM,MAAM,yBAAyB;AAAA,IACvC;AACA,SAAK,aAAa,8BAAU;AAC5B,SAAK,cAAc;AAEnB,SAAK,KAAM,KAAK,EAAE,MAAM,mBAAmB,OAAO,EAAE,YAAY,KAAK,EAAE,CAAC;AAAA,EAC1E;AACF;","names":[]}
|
|
@@ -123,7 +123,7 @@ const startJob = (proc, func, info, closeEvent, logger, joinFuture) => {
|
|
|
123
123
|
shutdownTasks.push(callback());
|
|
124
124
|
}
|
|
125
125
|
await Promise.all(shutdownTasks).catch(
|
|
126
|
-
(error) => logger.error("error while shutting down the job"
|
|
126
|
+
(error) => logger.error({ error }, "error while shutting down the job")
|
|
127
127
|
);
|
|
128
128
|
process.send({ case: "done" });
|
|
129
129
|
joinFuture.resolve();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ipc/job_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Room, RoomEvent } from '@livekit/rtc-node';\nimport { EventEmitter, once } from 'node:events';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from 'pino';\nimport { type Agent, isAgent } from '../generator.js';\nimport { JobContext, JobProcess, type RunningJobInfo, runWithJobContextAsync } from '../job.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future, shortuuid } from '../utils.js';\nimport { defaultInitializeProcessFunc } from '../worker.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\ntype JobTask = {\n ctx: JobContext;\n task: Promise<void>;\n};\n\nclass PendingInference {\n promise = new Promise<{ requestId: string; data: unknown; error?: Error }>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: { requestId: string; data: unknown; error?: Error }) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\nclass InfClient implements InferenceExecutor {\n #requests: { [id: string]: PendingInference } = {};\n\n constructor() {\n process.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceResponse':\n const fut = this.#requests[msg.value.requestId];\n delete this.#requests[msg.value.requestId];\n if (!fut) {\n log().child({ resp: msg.value }).warn('received unexpected inference response');\n return;\n }\n fut.resolve(msg.value);\n break;\n }\n });\n }\n\n async doInference(method: string, data: unknown): Promise<unknown> {\n const requestId = shortuuid('inference_job_');\n process.send!({ case: 'inferenceRequest', value: { requestId, method, data } });\n this.#requests[requestId] = new PendingInference();\n const resp = await this.#requests[requestId]!.promise;\n if (resp.error) {\n throw new Error(`inference of ${method} failed: ${resp.error.message}`);\n }\n return resp.data;\n }\n}\n\nconst startJob = (\n proc: JobProcess,\n func: (ctx: JobContext) => Promise<void>,\n info: RunningJobInfo,\n closeEvent: EventEmitter,\n logger: Logger,\n joinFuture: Future,\n): JobTask => {\n let connect = false;\n let shutdown = false;\n\n const room = new Room();\n room.on(RoomEvent.Disconnected, () => {\n if (!shutdown) {\n closeEvent.emit('close', false);\n }\n });\n\n const onConnect = () => {\n connect = true;\n };\n const onShutdown = (reason: string) => {\n shutdown = true;\n closeEvent.emit('close', true, reason);\n };\n\n const ctx = new JobContext(proc, info, room, onConnect, onShutdown, new InfClient());\n\n const task = (async () => {\n const unconnectedTimeout = setTimeout(() => {\n if (!(connect || shutdown)) {\n logger.warn(\n 'room not connect after job_entry was called after 10 seconds, ',\n 'did you forget to call ctx.connect()?',\n );\n }\n }, 10000);\n\n // Run the job function within the AsyncLocalStorage context\n await runWithJobContextAsync(ctx, async () => {\n const { tracer, traceTypes } = await import('../telemetry/index.js');\n return tracer.startActiveSpan(\n async (span) => {\n span.setAttribute(traceTypes.ATTR_JOB_ID, info.job.id);\n span.setAttribute(traceTypes.ATTR_AGENT_NAME, info.job.agentName);\n span.setAttribute(traceTypes.ATTR_ROOM_NAME, info.job.room?.name ?? '');\n return func(ctx);\n },\n { name: 'job_entrypoint' },\n );\n }).finally(() => {\n clearTimeout(unconnectedTimeout);\n });\n\n await once(closeEvent, 'close').then((close) => {\n logger.debug('shutting down');\n shutdown = true;\n process.send!({ case: 'exiting', value: { reason: close[1] } });\n });\n\n // Close the primary agent session if it exists\n if (ctx._primaryAgentSession) {\n await ctx._primaryAgentSession.close();\n }\n\n // Generate and save/upload session report\n await ctx._onSessionEnd();\n\n await room.disconnect();\n logger.debug('disconnected from room');\n\n const shutdownTasks = [];\n for (const callback of ctx.shutdownCallbacks) {\n shutdownTasks.push(callback());\n }\n await Promise.all(shutdownTasks).catch((error) =>\n logger.error('error while shutting down the job', error),\n );\n\n process.send!({ case: 'done' });\n joinFuture.resolve();\n })();\n\n return { ctx, task };\n};\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // process.argv:\n // [0] `node'\n // [1] import.meta.filename\n // [2] import.meta.filename of function containing entry file\n const moduleFile = process.argv[2];\n const agent: Agent = await import(pathToFileURL(moduleFile!).pathname).then((module) => {\n const agent = module.default;\n if (agent === undefined || !isAgent(agent)) {\n throw new Error(`Unable to load agent: Missing or invalid default export in ${moduleFile}`);\n }\n return agent;\n });\n if (!agent.prewarm) {\n agent.prewarm = defaultInitializeProcessFunc;\n }\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.debug('SIGINT received in job proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.debug('SIGTERM received in job proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const proc = new JobProcess();\n let logger = log().child({ pid: proc.pid });\n\n process.on('unhandledRejection', (reason) => {\n logger.debug({ error: reason }, 'Unhandled promise rejection');\n });\n\n logger.debug('initializing job runner');\n await agent.prewarm(proc);\n logger.debug('job runner initialized');\n process.send({ case: 'initializeResponse' });\n\n let job: JobTask | undefined = undefined;\n const closeEvent = new EventEmitter();\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('job process orphaned, shutting down.');\n join.resolve();\n }, ORPHANED_TIMEOUT);\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest': {\n orphanedTimeout.refresh();\n process.send!({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n }\n case 'startJobRequest': {\n if (job) {\n throw new Error('job task already running');\n }\n\n logger = logger.child({ jobID: msg.value.runningJob.job.id });\n\n job = startJob(proc, agent.entry, msg.value.runningJob, closeEvent, logger, join);\n logger.debug('job started');\n break;\n }\n case 'shutdownRequest': {\n if (!job) {\n join.resolve();\n }\n closeEvent.emit('close', 'shutdownRequest');\n clearTimeout(orphanedTimeout);\n process.off('message', messageHandler);\n }\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n logger.debug('Job process shutdown');\n process.exit(0);\n }\n})();\n"],"mappings":"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","names":["module","agent"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ipc/job_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Room, RoomEvent } from '@livekit/rtc-node';\nimport { EventEmitter, once } from 'node:events';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from 'pino';\nimport { type Agent, isAgent } from '../generator.js';\nimport { JobContext, JobProcess, type RunningJobInfo, runWithJobContextAsync } from '../job.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future, shortuuid } from '../utils.js';\nimport { defaultInitializeProcessFunc } from '../worker.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\ntype JobTask = {\n ctx: JobContext;\n task: Promise<void>;\n};\n\nclass PendingInference {\n promise = new Promise<{ requestId: string; data: unknown; error?: Error }>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: { requestId: string; data: unknown; error?: Error }) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\nclass InfClient implements InferenceExecutor {\n #requests: { [id: string]: PendingInference } = {};\n\n constructor() {\n process.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceResponse':\n const fut = this.#requests[msg.value.requestId];\n delete this.#requests[msg.value.requestId];\n if (!fut) {\n log().child({ resp: msg.value }).warn('received unexpected inference response');\n return;\n }\n fut.resolve(msg.value);\n break;\n }\n });\n }\n\n async doInference(method: string, data: unknown): Promise<unknown> {\n const requestId = shortuuid('inference_job_');\n process.send!({ case: 'inferenceRequest', value: { requestId, method, data } });\n this.#requests[requestId] = new PendingInference();\n const resp = await this.#requests[requestId]!.promise;\n if (resp.error) {\n throw new Error(`inference of ${method} failed: ${resp.error.message}`);\n }\n return resp.data;\n }\n}\n\nconst startJob = (\n proc: JobProcess,\n func: (ctx: JobContext) => Promise<void>,\n info: RunningJobInfo,\n closeEvent: EventEmitter,\n logger: Logger,\n joinFuture: Future,\n): JobTask => {\n let connect = false;\n let shutdown = false;\n\n const room = new Room();\n room.on(RoomEvent.Disconnected, () => {\n if (!shutdown) {\n closeEvent.emit('close', false);\n }\n });\n\n const onConnect = () => {\n connect = true;\n };\n const onShutdown = (reason: string) => {\n shutdown = true;\n closeEvent.emit('close', true, reason);\n };\n\n const ctx = new JobContext(proc, info, room, onConnect, onShutdown, new InfClient());\n\n const task = (async () => {\n const unconnectedTimeout = setTimeout(() => {\n if (!(connect || shutdown)) {\n logger.warn(\n 'room not connect after job_entry was called after 10 seconds, ',\n 'did you forget to call ctx.connect()?',\n );\n }\n }, 10000);\n\n // Run the job function within the AsyncLocalStorage context\n await runWithJobContextAsync(ctx, async () => {\n const { tracer, traceTypes } = await import('../telemetry/index.js');\n return tracer.startActiveSpan(\n async (span) => {\n span.setAttribute(traceTypes.ATTR_JOB_ID, info.job.id);\n span.setAttribute(traceTypes.ATTR_AGENT_NAME, info.job.agentName);\n span.setAttribute(traceTypes.ATTR_ROOM_NAME, info.job.room?.name ?? '');\n return func(ctx);\n },\n { name: 'job_entrypoint' },\n );\n }).finally(() => {\n clearTimeout(unconnectedTimeout);\n });\n\n await once(closeEvent, 'close').then((close) => {\n logger.debug('shutting down');\n shutdown = true;\n process.send!({ case: 'exiting', value: { reason: close[1] } });\n });\n\n // Close the primary agent session if it exists\n if (ctx._primaryAgentSession) {\n await ctx._primaryAgentSession.close();\n }\n\n // Generate and save/upload session report\n await ctx._onSessionEnd();\n\n await room.disconnect();\n logger.debug('disconnected from room');\n\n const shutdownTasks = [];\n for (const callback of ctx.shutdownCallbacks) {\n shutdownTasks.push(callback());\n }\n await Promise.all(shutdownTasks).catch((error) =>\n logger.error({ error }, 'error while shutting down the job'),\n );\n\n process.send!({ case: 'done' });\n joinFuture.resolve();\n })();\n\n return { ctx, task };\n};\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // process.argv:\n // [0] `node'\n // [1] import.meta.filename\n // [2] import.meta.filename of function containing entry file\n const moduleFile = process.argv[2];\n const agent: Agent = await import(pathToFileURL(moduleFile!).pathname).then((module) => {\n const agent = module.default;\n if (agent === undefined || !isAgent(agent)) {\n throw new Error(`Unable to load agent: Missing or invalid default export in ${moduleFile}`);\n }\n return agent;\n });\n if (!agent.prewarm) {\n agent.prewarm = defaultInitializeProcessFunc;\n }\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.debug('SIGINT received in job proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.debug('SIGTERM received in job proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const proc = new JobProcess();\n let logger = log().child({ pid: proc.pid });\n\n process.on('unhandledRejection', (reason) => {\n logger.debug({ error: reason }, 'Unhandled promise rejection');\n });\n\n logger.debug('initializing job runner');\n await agent.prewarm(proc);\n logger.debug('job runner initialized');\n process.send({ case: 'initializeResponse' });\n\n let job: JobTask | undefined = undefined;\n const closeEvent = new EventEmitter();\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('job process orphaned, shutting down.');\n join.resolve();\n }, ORPHANED_TIMEOUT);\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest': {\n orphanedTimeout.refresh();\n process.send!({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n }\n case 'startJobRequest': {\n if (job) {\n throw new Error('job task already running');\n }\n\n logger = logger.child({ jobID: msg.value.runningJob.job.id });\n\n job = startJob(proc, agent.entry, msg.value.runningJob, closeEvent, logger, join);\n logger.debug('job started');\n break;\n }\n case 'shutdownRequest': {\n if (!job) {\n join.resolve();\n }\n closeEvent.emit('close', 'shutdownRequest');\n clearTimeout(orphanedTimeout);\n process.off('message', messageHandler);\n }\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n logger.debug('Job process shutdown');\n process.exit(0);\n }\n})();\n"],"mappings":"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","names":["module","agent"]}
|
|
@@ -100,7 +100,7 @@ const startJob = (proc, func, info, closeEvent, logger, joinFuture) => {
|
|
|
100
100
|
shutdownTasks.push(callback());
|
|
101
101
|
}
|
|
102
102
|
await Promise.all(shutdownTasks).catch(
|
|
103
|
-
(error) => logger.error("error while shutting down the job"
|
|
103
|
+
(error) => logger.error({ error }, "error while shutting down the job")
|
|
104
104
|
);
|
|
105
105
|
process.send({ case: "done" });
|
|
106
106
|
joinFuture.resolve();
|