@livekit/agents 1.1.0-dev.0 → 1.2.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 +2 -0
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/constants.cjs +3 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -1
- package/dist/cpu.cjs +189 -0
- package/dist/cpu.cjs.map +1 -0
- package/dist/cpu.d.cts +24 -0
- package/dist/cpu.d.ts +24 -0
- package/dist/cpu.d.ts.map +1 -0
- package/dist/cpu.js +152 -0
- package/dist/cpu.js.map +1 -0
- package/dist/cpu.test.cjs +227 -0
- package/dist/cpu.test.cjs.map +1 -0
- package/dist/cpu.test.js +204 -0
- package/dist/cpu.test.js.map +1 -0
- package/dist/index.cjs +12 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -13
- package/dist/index.d.ts +13 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -10
- package/dist/index.js.map +1 -1
- package/dist/inference/interruption/defaults.cjs +1 -1
- package/dist/inference/interruption/defaults.cjs.map +1 -1
- package/dist/inference/interruption/defaults.d.cts +1 -1
- package/dist/inference/interruption/defaults.d.ts +1 -1
- package/dist/inference/interruption/defaults.d.ts.map +1 -1
- package/dist/inference/interruption/defaults.js +1 -1
- package/dist/inference/interruption/defaults.js.map +1 -1
- package/dist/inference/interruption/http_transport.cjs +44 -28
- package/dist/inference/interruption/http_transport.cjs.map +1 -1
- package/dist/inference/interruption/http_transport.d.ts.map +1 -1
- package/dist/inference/interruption/http_transport.js +45 -29
- package/dist/inference/interruption/http_transport.js.map +1 -1
- package/dist/inference/interruption/interruption_detector.cjs +22 -5
- package/dist/inference/interruption/interruption_detector.cjs.map +1 -1
- package/dist/inference/interruption/interruption_detector.d.cts +2 -2
- package/dist/inference/interruption/interruption_detector.d.ts +2 -2
- package/dist/inference/interruption/interruption_detector.d.ts.map +1 -1
- package/dist/inference/interruption/interruption_detector.js +22 -5
- package/dist/inference/interruption/interruption_detector.js.map +1 -1
- package/dist/inference/interruption/interruption_stream.cjs +4 -4
- package/dist/inference/interruption/interruption_stream.cjs.map +1 -1
- package/dist/inference/interruption/interruption_stream.js +4 -4
- package/dist/inference/interruption/interruption_stream.js.map +1 -1
- package/dist/inference/interruption/types.cjs.map +1 -1
- package/dist/inference/interruption/types.d.cts +2 -2
- package/dist/inference/interruption/types.d.ts +2 -2
- package/dist/inference/interruption/types.d.ts.map +1 -1
- package/dist/inference/interruption/ws_transport.cjs +60 -47
- package/dist/inference/interruption/ws_transport.cjs.map +1 -1
- package/dist/inference/interruption/ws_transport.d.ts.map +1 -1
- package/dist/inference/interruption/ws_transport.js +60 -47
- package/dist/inference/interruption/ws_transport.js.map +1 -1
- package/dist/inference/llm.cjs.map +1 -1
- package/dist/inference/llm.d.cts +1 -1
- package/dist/inference/llm.d.ts +1 -1
- package/dist/inference/llm.d.ts.map +1 -1
- package/dist/inference/llm.js.map +1 -1
- package/dist/inference/stt.cjs +20 -12
- package/dist/inference/stt.cjs.map +1 -1
- package/dist/inference/stt.d.cts +3 -2
- package/dist/inference/stt.d.ts +3 -2
- package/dist/inference/stt.d.ts.map +1 -1
- package/dist/inference/stt.js +20 -12
- package/dist/inference/stt.js.map +1 -1
- package/dist/inference/stt.test.cjs +14 -0
- package/dist/inference/stt.test.cjs.map +1 -1
- package/dist/inference/stt.test.js +14 -0
- package/dist/inference/stt.test.js.map +1 -1
- package/dist/inference/tts.cjs +13 -4
- package/dist/inference/tts.cjs.map +1 -1
- package/dist/inference/tts.d.cts +8 -1
- package/dist/inference/tts.d.ts +8 -1
- package/dist/inference/tts.d.ts.map +1 -1
- package/dist/inference/tts.js +13 -4
- package/dist/inference/tts.js.map +1 -1
- package/dist/inference/tts.test.cjs +10 -0
- package/dist/inference/tts.test.cjs.map +1 -1
- package/dist/inference/tts.test.js +10 -0
- package/dist/inference/tts.test.js.map +1 -1
- package/dist/ipc/job_proc_lazy_main.cjs +41 -23
- package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
- package/dist/ipc/job_proc_lazy_main.js +41 -23
- package/dist/ipc/job_proc_lazy_main.js.map +1 -1
- package/dist/job.cjs +1 -1
- package/dist/job.cjs.map +1 -1
- package/dist/job.js +1 -1
- package/dist/job.js.map +1 -1
- package/dist/language.cjs +394 -0
- package/dist/language.cjs.map +1 -0
- package/dist/language.d.cts +15 -0
- package/dist/language.d.ts +15 -0
- package/dist/language.d.ts.map +1 -0
- package/dist/language.js +363 -0
- package/dist/language.js.map +1 -0
- package/dist/language.test.cjs +43 -0
- package/dist/language.test.cjs.map +1 -0
- package/dist/language.test.js +49 -0
- package/dist/language.test.js.map +1 -0
- package/dist/llm/index.cjs +2 -0
- package/dist/llm/index.cjs.map +1 -1
- package/dist/llm/index.d.cts +1 -1
- package/dist/llm/index.d.ts +1 -1
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +2 -0
- package/dist/llm/index.js.map +1 -1
- package/dist/stream/deferred_stream.cjs +6 -2
- package/dist/stream/deferred_stream.cjs.map +1 -1
- package/dist/stream/deferred_stream.d.ts.map +1 -1
- package/dist/stream/deferred_stream.js +6 -2
- package/dist/stream/deferred_stream.js.map +1 -1
- package/dist/stt/stt.cjs.map +1 -1
- package/dist/stt/stt.d.cts +2 -1
- package/dist/stt/stt.d.ts +2 -1
- package/dist/stt/stt.d.ts.map +1 -1
- package/dist/stt/stt.js.map +1 -1
- package/dist/utils.cjs +15 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +8 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +13 -0
- package/dist/utils.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/dist/voice/agent.cjs +14 -17
- package/dist/voice/agent.cjs.map +1 -1
- package/dist/voice/agent.d.cts +10 -11
- package/dist/voice/agent.d.ts +10 -11
- package/dist/voice/agent.d.ts.map +1 -1
- package/dist/voice/agent.js +15 -18
- package/dist/voice/agent.js.map +1 -1
- package/dist/voice/agent.test.cjs +194 -0
- package/dist/voice/agent.test.cjs.map +1 -1
- package/dist/voice/agent.test.js +195 -1
- package/dist/voice/agent.test.js.map +1 -1
- package/dist/voice/agent_activity.cjs +116 -39
- package/dist/voice/agent_activity.cjs.map +1 -1
- package/dist/voice/agent_activity.d.cts +2 -0
- package/dist/voice/agent_activity.d.ts +2 -0
- package/dist/voice/agent_activity.d.ts.map +1 -1
- package/dist/voice/agent_activity.js +117 -40
- package/dist/voice/agent_activity.js.map +1 -1
- package/dist/voice/agent_activity.test.cjs +135 -0
- package/dist/voice/agent_activity.test.cjs.map +1 -0
- package/dist/voice/agent_activity.test.js +134 -0
- package/dist/voice/agent_activity.test.js.map +1 -0
- package/dist/voice/agent_session.cjs +38 -38
- package/dist/voice/agent_session.cjs.map +1 -1
- package/dist/voice/agent_session.d.cts +65 -56
- package/dist/voice/agent_session.d.ts +65 -56
- package/dist/voice/agent_session.d.ts.map +1 -1
- package/dist/voice/agent_session.js +37 -37
- package/dist/voice/agent_session.js.map +1 -1
- package/dist/voice/audio_recognition.cjs +106 -52
- package/dist/voice/audio_recognition.cjs.map +1 -1
- package/dist/voice/audio_recognition.d.cts +4 -2
- package/dist/voice/audio_recognition.d.ts +4 -2
- package/dist/voice/audio_recognition.d.ts.map +1 -1
- package/dist/voice/audio_recognition.js +106 -52
- package/dist/voice/audio_recognition.js.map +1 -1
- package/dist/voice/audio_recognition_span.test.cjs +84 -22
- package/dist/voice/audio_recognition_span.test.cjs.map +1 -1
- package/dist/voice/audio_recognition_span.test.js +90 -23
- package/dist/voice/audio_recognition_span.test.js.map +1 -1
- package/dist/voice/events.cjs +1 -1
- package/dist/voice/events.cjs.map +1 -1
- package/dist/voice/events.d.cts +4 -3
- package/dist/voice/events.d.ts +4 -3
- package/dist/voice/events.d.ts.map +1 -1
- package/dist/voice/events.js +1 -1
- package/dist/voice/events.js.map +1 -1
- package/dist/voice/index.cjs +9 -1
- package/dist/voice/index.cjs.map +1 -1
- package/dist/voice/index.d.cts +1 -1
- package/dist/voice/index.d.ts +1 -1
- package/dist/voice/index.d.ts.map +1 -1
- package/dist/voice/index.js +10 -1
- package/dist/voice/index.js.map +1 -1
- package/dist/voice/remote_session.cjs +922 -0
- package/dist/voice/remote_session.cjs.map +1 -0
- package/dist/voice/remote_session.d.cts +108 -0
- package/dist/voice/remote_session.d.ts +108 -0
- package/dist/voice/remote_session.d.ts.map +1 -0
- package/dist/voice/remote_session.js +887 -0
- package/dist/voice/remote_session.js.map +1 -0
- package/dist/voice/report.cjs +11 -10
- package/dist/voice/report.cjs.map +1 -1
- package/dist/voice/report.d.cts +5 -3
- package/dist/voice/report.d.ts +5 -3
- package/dist/voice/report.d.ts.map +1 -1
- package/dist/voice/report.js +11 -10
- package/dist/voice/report.js.map +1 -1
- package/dist/voice/report.test.cjs +15 -0
- package/dist/voice/report.test.cjs.map +1 -1
- package/dist/voice/report.test.js +15 -0
- package/dist/voice/report.test.js.map +1 -1
- package/dist/voice/room_io/room_io.cjs +39 -0
- package/dist/voice/room_io/room_io.cjs.map +1 -1
- package/dist/voice/room_io/room_io.d.cts +3 -1
- package/dist/voice/room_io/room_io.d.ts +3 -1
- package/dist/voice/room_io/room_io.d.ts.map +1 -1
- package/dist/voice/room_io/room_io.js +40 -1
- package/dist/voice/room_io/room_io.js.map +1 -1
- package/dist/voice/turn_config/interruption.cjs.map +1 -1
- package/dist/voice/turn_config/interruption.d.cts +1 -1
- package/dist/voice/turn_config/interruption.d.ts +1 -1
- package/dist/voice/turn_config/interruption.d.ts.map +1 -1
- package/dist/voice/turn_config/interruption.js.map +1 -1
- package/dist/voice/turn_config/utils.cjs +95 -35
- package/dist/voice/turn_config/utils.cjs.map +1 -1
- package/dist/voice/turn_config/utils.d.cts +17 -5
- package/dist/voice/turn_config/utils.d.ts +17 -5
- package/dist/voice/turn_config/utils.d.ts.map +1 -1
- package/dist/voice/turn_config/utils.js +93 -35
- package/dist/voice/turn_config/utils.js.map +1 -1
- package/dist/voice/turn_config/utils.test.cjs +83 -41
- package/dist/voice/turn_config/utils.test.cjs.map +1 -1
- package/dist/voice/turn_config/utils.test.js +84 -42
- package/dist/voice/turn_config/utils.test.js.map +1 -1
- package/dist/worker.cjs +6 -29
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +6 -19
- package/dist/worker.js.map +1 -1
- package/package.json +3 -2
- package/src/cli.ts +2 -0
- package/src/constants.ts +1 -0
- package/src/cpu.test.ts +239 -0
- package/src/cpu.ts +173 -0
- package/src/index.ts +13 -15
- package/src/inference/interruption/defaults.ts +1 -1
- package/src/inference/interruption/http_transport.ts +49 -30
- package/src/inference/interruption/interruption_detector.ts +22 -6
- package/src/inference/interruption/interruption_stream.ts +4 -4
- package/src/inference/interruption/types.ts +2 -2
- package/src/inference/interruption/ws_transport.ts +63 -59
- package/src/inference/llm.ts +3 -1
- package/src/inference/stt.test.ts +17 -0
- package/src/inference/stt.ts +22 -14
- package/src/inference/tts.test.ts +12 -0
- package/src/inference/tts.ts +22 -6
- package/src/ipc/job_proc_lazy_main.ts +44 -24
- package/src/job.ts +1 -1
- package/src/language.test.ts +62 -0
- package/src/language.ts +380 -0
- package/src/llm/index.ts +2 -0
- package/src/stream/deferred_stream.ts +5 -1
- package/src/stt/stt.ts +2 -1
- package/src/utils.ts +20 -0
- package/src/voice/agent.test.ts +208 -1
- package/src/voice/agent.ts +21 -22
- package/src/voice/agent_activity.test.ts +194 -0
- package/src/voice/agent_activity.ts +161 -43
- package/src/voice/agent_session.ts +103 -92
- package/src/voice/audio_recognition.ts +124 -61
- package/src/voice/audio_recognition_span.test.ts +115 -35
- package/src/voice/events.ts +4 -3
- package/src/voice/index.ts +10 -1
- package/src/voice/remote_session.ts +1083 -0
- package/src/voice/report.test.ts +22 -3
- package/src/voice/report.ts +31 -14
- package/src/voice/room_io/room_io.ts +52 -2
- package/src/voice/turn_config/interruption.ts +1 -1
- package/src/voice/turn_config/utils.test.ts +91 -43
- package/src/voice/turn_config/utils.ts +120 -56
- package/src/worker.ts +34 -50
- package/dist/voice/client_events.cjs +0 -554
- package/dist/voice/client_events.cjs.map +0 -1
- package/dist/voice/client_events.d.cts +0 -195
- package/dist/voice/client_events.d.ts +0 -195
- package/dist/voice/client_events.d.ts.map +0 -1
- package/dist/voice/client_events.js +0 -548
- package/dist/voice/client_events.js.map +0 -1
- package/dist/voice/wire_format.cjs +0 -798
- package/dist/voice/wire_format.cjs.map +0 -1
- package/dist/voice/wire_format.d.cts +0 -5503
- package/dist/voice/wire_format.d.ts +0 -5503
- package/dist/voice/wire_format.d.ts.map +0 -1
- package/dist/voice/wire_format.js +0 -728
- package/dist/voice/wire_format.js.map +0 -1
- package/src/voice/client_events.ts +0 -838
- package/src/voice/wire_format.ts +0 -827
package/src/inference/tts.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { WebSocket } from 'ws';
|
|
|
6
6
|
import { APIError, APIStatusError } from '../_exceptions.js';
|
|
7
7
|
import { AudioByteStream } from '../audio.js';
|
|
8
8
|
import { ConnectionPool } from '../connection_pool.js';
|
|
9
|
+
import { type LanguageCode, normalizeLanguage } from '../language.js';
|
|
9
10
|
import { log } from '../log.js';
|
|
10
11
|
import { createStreamChannel } from '../stream/stream_channel.js';
|
|
11
12
|
import { basic as tokenizeBasic } from '../tokenize/index.js';
|
|
@@ -62,7 +63,14 @@ export interface DeepgramTTSOptions {}
|
|
|
62
63
|
|
|
63
64
|
export interface RimeOptions {}
|
|
64
65
|
|
|
65
|
-
export interface InworldOptions {
|
|
66
|
+
export interface InworldOptions {
|
|
67
|
+
/** Controls how fast the voice speaks. 1.0 is normal speed, 0.5 is half, 1.5 is 1.5x. Default: 1.0. */
|
|
68
|
+
speaking_rate?: number;
|
|
69
|
+
/** Controls randomness in the output. Recommended between 0.6 and 1.1. Default: 1.1. */
|
|
70
|
+
temperature?: number;
|
|
71
|
+
/** Controls text normalization. "ON" expands numbers, dates, abbreviations. "OFF" reads text as written. Default: "ON". */
|
|
72
|
+
text_normalization?: 'ON' | 'OFF';
|
|
73
|
+
}
|
|
66
74
|
|
|
67
75
|
type _TTSModels =
|
|
68
76
|
| CartesiaModels
|
|
@@ -142,7 +150,7 @@ const DEFAULT_LANGUAGE = 'en';
|
|
|
142
150
|
export interface InferenceTTSOptions<TModel extends TTSModels> {
|
|
143
151
|
model?: TModel;
|
|
144
152
|
voice?: string;
|
|
145
|
-
language?:
|
|
153
|
+
language?: LanguageCode;
|
|
146
154
|
encoding: TTSEncoding;
|
|
147
155
|
sampleRate: number;
|
|
148
156
|
baseURL: string;
|
|
@@ -228,7 +236,7 @@ export class TTS<TModel extends TTSModels> extends BaseTTS {
|
|
|
228
236
|
this.opts = {
|
|
229
237
|
model: nextModel,
|
|
230
238
|
voice: nextVoice,
|
|
231
|
-
language,
|
|
239
|
+
language: normalizeLanguage(language),
|
|
232
240
|
encoding,
|
|
233
241
|
sampleRate,
|
|
234
242
|
baseURL: lkBaseURL,
|
|
@@ -267,9 +275,13 @@ export class TTS<TModel extends TTSModels> extends BaseTTS {
|
|
|
267
275
|
}
|
|
268
276
|
|
|
269
277
|
updateOptions(opts: Partial<Pick<InferenceTTSOptions<TModel>, 'model' | 'voice' | 'language'>>) {
|
|
270
|
-
this.opts = {
|
|
278
|
+
this.opts = {
|
|
279
|
+
...this.opts,
|
|
280
|
+
...opts,
|
|
281
|
+
language: opts.language !== undefined ? normalizeLanguage(opts.language) : this.opts.language,
|
|
282
|
+
};
|
|
271
283
|
for (const stream of this.streams) {
|
|
272
|
-
stream.updateOptions(opts);
|
|
284
|
+
stream.updateOptions(this.opts);
|
|
273
285
|
}
|
|
274
286
|
}
|
|
275
287
|
|
|
@@ -362,7 +374,11 @@ export class SynthesizeStream<TModel extends TTSModels> extends BaseSynthesizeSt
|
|
|
362
374
|
}
|
|
363
375
|
|
|
364
376
|
updateOptions(opts: Partial<Pick<InferenceTTSOptions<TModel>, 'model' | 'voice' | 'language'>>) {
|
|
365
|
-
this.opts = {
|
|
377
|
+
this.opts = {
|
|
378
|
+
...this.opts,
|
|
379
|
+
...opts,
|
|
380
|
+
language: opts.language !== undefined ? normalizeLanguage(opts.language) : this.opts.language,
|
|
381
|
+
};
|
|
366
382
|
}
|
|
367
383
|
|
|
368
384
|
protected async run(): Promise<void> {
|
|
@@ -16,11 +16,22 @@ import type { IPCMessage } from './message.js';
|
|
|
16
16
|
const ORPHANED_TIMEOUT = 15 * 1000;
|
|
17
17
|
|
|
18
18
|
const safeSend = (msg: IPCMessage): boolean => {
|
|
19
|
-
|
|
20
|
-
process.send
|
|
21
|
-
|
|
19
|
+
try {
|
|
20
|
+
if (process.connected && process.send) {
|
|
21
|
+
process.send(msg);
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
} catch (error) {
|
|
26
|
+
// Channel closed is expected during graceful shutdown
|
|
27
|
+
// Log at debug level to avoid noise in production logs
|
|
28
|
+
if (error instanceof Error && error.message.includes('Channel closed')) {
|
|
29
|
+
log().debug({ msgCase: msg.case }, 'IPC channel closed, message not sent');
|
|
30
|
+
} else {
|
|
31
|
+
log().error({ error, msgCase: msg.case }, 'IPC send failed unexpectedly');
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
22
34
|
}
|
|
23
|
-
return false;
|
|
24
35
|
};
|
|
25
36
|
|
|
26
37
|
type JobTask = {
|
|
@@ -109,27 +120,36 @@ const startJob = (
|
|
|
109
120
|
}
|
|
110
121
|
}, 10000);
|
|
111
122
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
span
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
123
|
+
try {
|
|
124
|
+
// Run the job function within the AsyncLocalStorage context
|
|
125
|
+
await runWithJobContextAsync(ctx, async () => {
|
|
126
|
+
const { tracer, traceTypes } = await import('../telemetry/index.js');
|
|
127
|
+
return tracer.startActiveSpan(
|
|
128
|
+
async (span) => {
|
|
129
|
+
span.setAttribute(traceTypes.ATTR_JOB_ID, info.job.id);
|
|
130
|
+
span.setAttribute(traceTypes.ATTR_AGENT_NAME, info.job.agentName);
|
|
131
|
+
span.setAttribute(traceTypes.ATTR_ROOM_NAME, info.job.room?.name ?? '');
|
|
132
|
+
return func(ctx);
|
|
133
|
+
},
|
|
134
|
+
{ name: 'job_entrypoint' },
|
|
135
|
+
);
|
|
136
|
+
}).finally(() => {
|
|
137
|
+
clearTimeout(unconnectedTimeout);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
await once(closeEvent, 'close').then((close) => {
|
|
141
|
+
logger.debug('shutting down');
|
|
142
|
+
shutdown = true;
|
|
143
|
+
safeSend({ case: 'exiting', value: { reason: close[1] } });
|
|
144
|
+
});
|
|
145
|
+
} catch (error) {
|
|
146
|
+
logger.error({ error }, 'error in entry function');
|
|
130
147
|
shutdown = true;
|
|
131
|
-
safeSend({
|
|
132
|
-
|
|
148
|
+
safeSend({
|
|
149
|
+
case: 'exiting',
|
|
150
|
+
value: { reason: error instanceof Error ? error.message : String(error) },
|
|
151
|
+
});
|
|
152
|
+
}
|
|
133
153
|
|
|
134
154
|
// Close the primary agent session if it exists
|
|
135
155
|
if (ctx._primaryAgentSession) {
|
package/src/job.ts
CHANGED
|
@@ -276,7 +276,7 @@ export class JobContext {
|
|
|
276
276
|
jobId: this.job.id,
|
|
277
277
|
roomId: this.job.room?.sid || '',
|
|
278
278
|
room: this.job.room?.name || '',
|
|
279
|
-
options: targetSession.
|
|
279
|
+
options: targetSession.sessionOptions,
|
|
280
280
|
events: targetSession._recordedEvents,
|
|
281
281
|
enableRecording: targetSession._enableRecording,
|
|
282
282
|
chatHistory: targetSession.history.copy(),
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import {
|
|
6
|
+
areLanguagesEquivalent,
|
|
7
|
+
getBaseLanguage,
|
|
8
|
+
getIsoLanguage,
|
|
9
|
+
getLanguageRegion,
|
|
10
|
+
normalizeLanguage,
|
|
11
|
+
toLanguageName,
|
|
12
|
+
} from './language.js';
|
|
13
|
+
|
|
14
|
+
describe('normalizeLanguage', () => {
|
|
15
|
+
it('normalizes language names', () => {
|
|
16
|
+
expect(normalizeLanguage('english')).toBe('en');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('normalizes iso 639-3 codes', () => {
|
|
20
|
+
expect(normalizeLanguage('eng')).toBe('en');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('normalizes bcp-47 casing and separators', () => {
|
|
24
|
+
expect(normalizeLanguage('en_us')).toBe('en-US');
|
|
25
|
+
expect(normalizeLanguage('zh_hans_cn')).toBe('zh-Hans-CN');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('preserves iso 639-3 in compound tags', () => {
|
|
29
|
+
expect(normalizeLanguage('cmn_hans_cn')).toBe('cmn-Hans-CN');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('passes unknown codes through in lowercase', () => {
|
|
33
|
+
expect(normalizeLanguage('MULTI')).toBe('multi');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('preserves empty string sentinel', () => {
|
|
37
|
+
expect(normalizeLanguage('')).toBe('');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('language helpers', () => {
|
|
42
|
+
it('extracts base language', () => {
|
|
43
|
+
expect(getBaseLanguage('cmn-Hans-CN')).toBe('zh');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('builds iso language tag', () => {
|
|
47
|
+
expect(getIsoLanguage('cmn-Hans-CN')).toBe('zh-CN');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('extracts region', () => {
|
|
51
|
+
expect(getLanguageRegion('en-US')).toBe('US');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('maps normalized code back to language name', () => {
|
|
55
|
+
expect(toLanguageName('eng')).toBe('english');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('compares equivalent representations', () => {
|
|
59
|
+
expect(areLanguagesEquivalent('english', 'en')).toBe(true);
|
|
60
|
+
expect(areLanguagesEquivalent('en_us', 'en-US')).toBe(true);
|
|
61
|
+
});
|
|
62
|
+
});
|
package/src/language.ts
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
export const KNOWN_LANGUAGE_CODES = [
|
|
6
|
+
'af',
|
|
7
|
+
'am',
|
|
8
|
+
'ar',
|
|
9
|
+
'as',
|
|
10
|
+
'az',
|
|
11
|
+
'be',
|
|
12
|
+
'bg',
|
|
13
|
+
'bn',
|
|
14
|
+
'bs',
|
|
15
|
+
'ca',
|
|
16
|
+
'cs',
|
|
17
|
+
'cy',
|
|
18
|
+
'da',
|
|
19
|
+
'de',
|
|
20
|
+
'el',
|
|
21
|
+
'en',
|
|
22
|
+
'es',
|
|
23
|
+
'et',
|
|
24
|
+
'eu',
|
|
25
|
+
'fa',
|
|
26
|
+
'ff',
|
|
27
|
+
'fi',
|
|
28
|
+
'fr',
|
|
29
|
+
'ga',
|
|
30
|
+
'gl',
|
|
31
|
+
'gu',
|
|
32
|
+
'ha',
|
|
33
|
+
'he',
|
|
34
|
+
'hi',
|
|
35
|
+
'hr',
|
|
36
|
+
'hu',
|
|
37
|
+
'hy',
|
|
38
|
+
'id',
|
|
39
|
+
'ig',
|
|
40
|
+
'is',
|
|
41
|
+
'it',
|
|
42
|
+
'ja',
|
|
43
|
+
'jv',
|
|
44
|
+
'ka',
|
|
45
|
+
'kk',
|
|
46
|
+
'km',
|
|
47
|
+
'kn',
|
|
48
|
+
'ko',
|
|
49
|
+
'ku',
|
|
50
|
+
'ky',
|
|
51
|
+
'lb',
|
|
52
|
+
'lg',
|
|
53
|
+
'ln',
|
|
54
|
+
'lo',
|
|
55
|
+
'lt',
|
|
56
|
+
'lv',
|
|
57
|
+
'mi',
|
|
58
|
+
'mk',
|
|
59
|
+
'ml',
|
|
60
|
+
'mn',
|
|
61
|
+
'mr',
|
|
62
|
+
'ms',
|
|
63
|
+
'mt',
|
|
64
|
+
'my',
|
|
65
|
+
'ne',
|
|
66
|
+
'nl',
|
|
67
|
+
'no',
|
|
68
|
+
'ny',
|
|
69
|
+
'oc',
|
|
70
|
+
'or',
|
|
71
|
+
'pa',
|
|
72
|
+
'pl',
|
|
73
|
+
'ps',
|
|
74
|
+
'pt',
|
|
75
|
+
'ro',
|
|
76
|
+
'ru',
|
|
77
|
+
'sd',
|
|
78
|
+
'sk',
|
|
79
|
+
'sl',
|
|
80
|
+
'sn',
|
|
81
|
+
'so',
|
|
82
|
+
'sq',
|
|
83
|
+
'sr',
|
|
84
|
+
'sv',
|
|
85
|
+
'sw',
|
|
86
|
+
'ta',
|
|
87
|
+
'te',
|
|
88
|
+
'tg',
|
|
89
|
+
'th',
|
|
90
|
+
'tl',
|
|
91
|
+
'tr',
|
|
92
|
+
'uk',
|
|
93
|
+
'ur',
|
|
94
|
+
'uz',
|
|
95
|
+
'vi',
|
|
96
|
+
'wo',
|
|
97
|
+
'xh',
|
|
98
|
+
'yo',
|
|
99
|
+
'zh',
|
|
100
|
+
'zu',
|
|
101
|
+
] as const;
|
|
102
|
+
|
|
103
|
+
export type KnownLanguageCode = (typeof KNOWN_LANGUAGE_CODES)[number];
|
|
104
|
+
|
|
105
|
+
declare const languageCodeBrand: unique symbol;
|
|
106
|
+
|
|
107
|
+
export type LanguageCode = string & { readonly [languageCodeBrand]: 'LanguageCode' };
|
|
108
|
+
|
|
109
|
+
export function asLanguageCode(language: string): LanguageCode {
|
|
110
|
+
return language as LanguageCode;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const ISO_639_3_TO_1: Record<string, string | undefined> = {
|
|
114
|
+
afr: 'af',
|
|
115
|
+
amh: 'am',
|
|
116
|
+
ara: 'ar',
|
|
117
|
+
hye: 'hy',
|
|
118
|
+
asm: 'as',
|
|
119
|
+
ast: undefined,
|
|
120
|
+
aze: 'az',
|
|
121
|
+
bel: 'be',
|
|
122
|
+
ben: 'bn',
|
|
123
|
+
bos: 'bs',
|
|
124
|
+
bul: 'bg',
|
|
125
|
+
mya: 'my',
|
|
126
|
+
yue: undefined,
|
|
127
|
+
cat: 'ca',
|
|
128
|
+
ceb: undefined,
|
|
129
|
+
cmn: 'zh',
|
|
130
|
+
nya: 'ny',
|
|
131
|
+
hrv: 'hr',
|
|
132
|
+
ces: 'cs',
|
|
133
|
+
dan: 'da',
|
|
134
|
+
nld: 'nl',
|
|
135
|
+
eng: 'en',
|
|
136
|
+
est: 'et',
|
|
137
|
+
fil: undefined,
|
|
138
|
+
fin: 'fi',
|
|
139
|
+
fra: 'fr',
|
|
140
|
+
ful: 'ff',
|
|
141
|
+
glg: 'gl',
|
|
142
|
+
lug: 'lg',
|
|
143
|
+
kat: 'ka',
|
|
144
|
+
deu: 'de',
|
|
145
|
+
ell: 'el',
|
|
146
|
+
guj: 'gu',
|
|
147
|
+
hau: 'ha',
|
|
148
|
+
heb: 'he',
|
|
149
|
+
hin: 'hi',
|
|
150
|
+
hun: 'hu',
|
|
151
|
+
isl: 'is',
|
|
152
|
+
ibo: 'ig',
|
|
153
|
+
ind: 'id',
|
|
154
|
+
gle: 'ga',
|
|
155
|
+
ita: 'it',
|
|
156
|
+
jpn: 'ja',
|
|
157
|
+
jav: 'jv',
|
|
158
|
+
kea: undefined,
|
|
159
|
+
kan: 'kn',
|
|
160
|
+
kaz: 'kk',
|
|
161
|
+
khm: 'km',
|
|
162
|
+
kor: 'ko',
|
|
163
|
+
kur: 'ku',
|
|
164
|
+
kir: 'ky',
|
|
165
|
+
lao: 'lo',
|
|
166
|
+
lav: 'lv',
|
|
167
|
+
lin: 'ln',
|
|
168
|
+
lit: 'lt',
|
|
169
|
+
luo: undefined,
|
|
170
|
+
ltz: 'lb',
|
|
171
|
+
mkd: 'mk',
|
|
172
|
+
msa: 'ms',
|
|
173
|
+
mal: 'ml',
|
|
174
|
+
mlt: 'mt',
|
|
175
|
+
zho: 'zh',
|
|
176
|
+
mri: 'mi',
|
|
177
|
+
mar: 'mr',
|
|
178
|
+
mon: 'mn',
|
|
179
|
+
nep: 'ne',
|
|
180
|
+
nso: undefined,
|
|
181
|
+
nor: 'no',
|
|
182
|
+
oci: 'oc',
|
|
183
|
+
ori: 'or',
|
|
184
|
+
pus: 'ps',
|
|
185
|
+
fas: 'fa',
|
|
186
|
+
pol: 'pl',
|
|
187
|
+
por: 'pt',
|
|
188
|
+
pan: 'pa',
|
|
189
|
+
ron: 'ro',
|
|
190
|
+
rus: 'ru',
|
|
191
|
+
srp: 'sr',
|
|
192
|
+
sna: 'sn',
|
|
193
|
+
snd: 'sd',
|
|
194
|
+
slk: 'sk',
|
|
195
|
+
slv: 'sl',
|
|
196
|
+
som: 'so',
|
|
197
|
+
spa: 'es',
|
|
198
|
+
swa: 'sw',
|
|
199
|
+
swe: 'sv',
|
|
200
|
+
tam: 'ta',
|
|
201
|
+
tgk: 'tg',
|
|
202
|
+
tel: 'te',
|
|
203
|
+
tha: 'th',
|
|
204
|
+
tur: 'tr',
|
|
205
|
+
ukr: 'uk',
|
|
206
|
+
umb: undefined,
|
|
207
|
+
urd: 'ur',
|
|
208
|
+
uzb: 'uz',
|
|
209
|
+
vie: 'vi',
|
|
210
|
+
cym: 'cy',
|
|
211
|
+
wol: 'wo',
|
|
212
|
+
xho: 'xh',
|
|
213
|
+
zul: 'zu',
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const LANGUAGE_NAMES_TO_CODE: Record<string, string> = {
|
|
217
|
+
afrikaans: 'af',
|
|
218
|
+
albanian: 'sq',
|
|
219
|
+
amharic: 'am',
|
|
220
|
+
arabic: 'ar',
|
|
221
|
+
armenian: 'hy',
|
|
222
|
+
azerbaijani: 'az',
|
|
223
|
+
basque: 'eu',
|
|
224
|
+
belarusian: 'be',
|
|
225
|
+
bengali: 'bn',
|
|
226
|
+
bosnian: 'bs',
|
|
227
|
+
bulgarian: 'bg',
|
|
228
|
+
burmese: 'my',
|
|
229
|
+
catalan: 'ca',
|
|
230
|
+
chinese: 'zh',
|
|
231
|
+
croatian: 'hr',
|
|
232
|
+
czech: 'cs',
|
|
233
|
+
danish: 'da',
|
|
234
|
+
dutch: 'nl',
|
|
235
|
+
english: 'en',
|
|
236
|
+
estonian: 'et',
|
|
237
|
+
finnish: 'fi',
|
|
238
|
+
french: 'fr',
|
|
239
|
+
galician: 'gl',
|
|
240
|
+
georgian: 'ka',
|
|
241
|
+
german: 'de',
|
|
242
|
+
greek: 'el',
|
|
243
|
+
gujarati: 'gu',
|
|
244
|
+
hausa: 'ha',
|
|
245
|
+
hebrew: 'he',
|
|
246
|
+
hindi: 'hi',
|
|
247
|
+
hungarian: 'hu',
|
|
248
|
+
icelandic: 'is',
|
|
249
|
+
indonesian: 'id',
|
|
250
|
+
irish: 'ga',
|
|
251
|
+
italian: 'it',
|
|
252
|
+
japanese: 'ja',
|
|
253
|
+
javanese: 'jv',
|
|
254
|
+
kannada: 'kn',
|
|
255
|
+
kazakh: 'kk',
|
|
256
|
+
khmer: 'km',
|
|
257
|
+
korean: 'ko',
|
|
258
|
+
kurdish: 'ku',
|
|
259
|
+
kyrgyz: 'ky',
|
|
260
|
+
lao: 'lo',
|
|
261
|
+
latvian: 'lv',
|
|
262
|
+
lingala: 'ln',
|
|
263
|
+
lithuanian: 'lt',
|
|
264
|
+
luxembourgish: 'lb',
|
|
265
|
+
macedonian: 'mk',
|
|
266
|
+
malay: 'ms',
|
|
267
|
+
malayalam: 'ml',
|
|
268
|
+
maltese: 'mt',
|
|
269
|
+
maori: 'mi',
|
|
270
|
+
marathi: 'mr',
|
|
271
|
+
mongolian: 'mn',
|
|
272
|
+
nepali: 'ne',
|
|
273
|
+
norwegian: 'no',
|
|
274
|
+
occitan: 'oc',
|
|
275
|
+
oriya: 'or',
|
|
276
|
+
pashto: 'ps',
|
|
277
|
+
persian: 'fa',
|
|
278
|
+
polish: 'pl',
|
|
279
|
+
portuguese: 'pt',
|
|
280
|
+
punjabi: 'pa',
|
|
281
|
+
romanian: 'ro',
|
|
282
|
+
russian: 'ru',
|
|
283
|
+
serbian: 'sr',
|
|
284
|
+
shona: 'sn',
|
|
285
|
+
sindhi: 'sd',
|
|
286
|
+
slovak: 'sk',
|
|
287
|
+
slovene: 'sl',
|
|
288
|
+
slovenian: 'sl',
|
|
289
|
+
somali: 'so',
|
|
290
|
+
spanish: 'es',
|
|
291
|
+
swahili: 'sw',
|
|
292
|
+
swedish: 'sv',
|
|
293
|
+
tagalog: 'tl',
|
|
294
|
+
tamil: 'ta',
|
|
295
|
+
tajik: 'tg',
|
|
296
|
+
telugu: 'te',
|
|
297
|
+
thai: 'th',
|
|
298
|
+
turkish: 'tr',
|
|
299
|
+
ukrainian: 'uk',
|
|
300
|
+
urdu: 'ur',
|
|
301
|
+
uzbek: 'uz',
|
|
302
|
+
vietnamese: 'vi',
|
|
303
|
+
welsh: 'cy',
|
|
304
|
+
wolof: 'wo',
|
|
305
|
+
xhosa: 'xh',
|
|
306
|
+
yoruba: 'yo',
|
|
307
|
+
zulu: 'zu',
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
const CODE_TO_LANGUAGE_NAME: Record<string, string> = Object.fromEntries(
|
|
311
|
+
Object.entries(LANGUAGE_NAMES_TO_CODE).map(([name, code]) => [code, name]),
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
CODE_TO_LANGUAGE_NAME.sl = 'slovene';
|
|
315
|
+
|
|
316
|
+
export function normalizeLanguage(language: string): LanguageCode {
|
|
317
|
+
const lowered = language.trim().toLowerCase();
|
|
318
|
+
if (lowered === '') {
|
|
319
|
+
return asLanguageCode('');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (lowered in LANGUAGE_NAMES_TO_CODE) {
|
|
323
|
+
return asLanguageCode(LANGUAGE_NAMES_TO_CODE[lowered]!);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (lowered in ISO_639_3_TO_1) {
|
|
327
|
+
return asLanguageCode(ISO_639_3_TO_1[lowered] ?? lowered);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const parts = lowered.replaceAll('_', '-').split('-');
|
|
331
|
+
if (parts.length >= 2) {
|
|
332
|
+
const [base, ...rest] = parts;
|
|
333
|
+
return asLanguageCode(
|
|
334
|
+
[
|
|
335
|
+
base,
|
|
336
|
+
...rest.map((part) => {
|
|
337
|
+
if (part.length === 4) {
|
|
338
|
+
return part.charAt(0).toUpperCase() + part.slice(1);
|
|
339
|
+
}
|
|
340
|
+
return part.toUpperCase();
|
|
341
|
+
}),
|
|
342
|
+
].join('-'),
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return asLanguageCode(lowered);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export function getBaseLanguage(language: string): string {
|
|
350
|
+
const normalized = normalizeLanguage(language);
|
|
351
|
+
const [base = ''] = normalized.split('-');
|
|
352
|
+
return ISO_639_3_TO_1[base] ?? base;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export function getIsoLanguage(language: string): string {
|
|
356
|
+
const normalized = normalizeLanguage(language);
|
|
357
|
+
const region = getLanguageRegion(normalized);
|
|
358
|
+
const baseLanguage = getBaseLanguage(normalized);
|
|
359
|
+
return region ? `${baseLanguage}-${region}` : baseLanguage;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
export function getLanguageRegion(language: string): string | undefined {
|
|
363
|
+
const normalized = normalizeLanguage(language);
|
|
364
|
+
const [, ...parts] = normalized.split('-');
|
|
365
|
+
return parts.find((part) => part.length === 2);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export function toLanguageName(language: string): string | undefined {
|
|
369
|
+
return CODE_TO_LANGUAGE_NAME[getBaseLanguage(language)];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export function areLanguagesEquivalent(
|
|
373
|
+
left: string | null | undefined,
|
|
374
|
+
right: string | null | undefined,
|
|
375
|
+
): boolean {
|
|
376
|
+
if (left == null || right == null) {
|
|
377
|
+
return left === right;
|
|
378
|
+
}
|
|
379
|
+
return normalizeLanguage(left) === normalizeLanguage(right);
|
|
380
|
+
}
|
package/src/llm/index.ts
CHANGED
|
@@ -25,9 +25,13 @@ export function isStreamReaderReleaseError(e: unknown) {
|
|
|
25
25
|
'Invalid state: The reader is not attached to a stream',
|
|
26
26
|
'Controller is already closed',
|
|
27
27
|
'WritableStream is closed',
|
|
28
|
+
// bun
|
|
29
|
+
'Stream reader cancelled via releaseLock()',
|
|
30
|
+
// deno
|
|
31
|
+
'The reader was released.',
|
|
28
32
|
];
|
|
29
33
|
|
|
30
|
-
if (e instanceof TypeError) {
|
|
34
|
+
if (e instanceof TypeError || (e instanceof Error && e.name === 'AbortError')) {
|
|
31
35
|
return allowedMessages.some((message) => e.message.includes(message));
|
|
32
36
|
}
|
|
33
37
|
|
package/src/stt/stt.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { EventEmitter } from 'node:events';
|
|
|
7
7
|
import type { ReadableStream } from 'node:stream/web';
|
|
8
8
|
import { APIConnectionError, APIError } from '../_exceptions.js';
|
|
9
9
|
import { calculateAudioDurationSeconds } from '../audio.js';
|
|
10
|
+
import type { LanguageCode } from '../language.js';
|
|
10
11
|
import { log } from '../log.js';
|
|
11
12
|
import type { STTMetrics } from '../metrics/base.js';
|
|
12
13
|
import { DeferredReadableStream } from '../stream/deferred_stream.js';
|
|
@@ -50,7 +51,7 @@ export enum SpeechEventType {
|
|
|
50
51
|
/** SpeechData contains metadata about this {@link SpeechEvent}. */
|
|
51
52
|
export interface SpeechData {
|
|
52
53
|
/** Language code of the speech. */
|
|
53
|
-
language:
|
|
54
|
+
language: LanguageCode;
|
|
54
55
|
/** Transcribed text. */
|
|
55
56
|
text: string;
|
|
56
57
|
/** Start time of the speech segment in seconds. */
|
package/src/utils.ts
CHANGED
|
@@ -846,7 +846,12 @@ export async function waitForParticipant({
|
|
|
846
846
|
}
|
|
847
847
|
};
|
|
848
848
|
|
|
849
|
+
const onDisconnected = () => {
|
|
850
|
+
fut.reject(new Error('Got disconnected from room while waiting for participant'));
|
|
851
|
+
};
|
|
852
|
+
|
|
849
853
|
room.on(RoomEvent.ParticipantConnected, onParticipantConnected);
|
|
854
|
+
room.on(RoomEvent.Disconnected, onDisconnected);
|
|
850
855
|
|
|
851
856
|
try {
|
|
852
857
|
for (const p of room.remoteParticipants.values()) {
|
|
@@ -859,6 +864,7 @@ export async function waitForParticipant({
|
|
|
859
864
|
return await fut.await;
|
|
860
865
|
} finally {
|
|
861
866
|
room.off(RoomEvent.ParticipantConnected, onParticipantConnected);
|
|
867
|
+
room.off(RoomEvent.Disconnected, onDisconnected);
|
|
862
868
|
}
|
|
863
869
|
}
|
|
864
870
|
|
|
@@ -953,3 +959,17 @@ export const isCloud = (url: URL) => {
|
|
|
953
959
|
const hostname = url.hostname;
|
|
954
960
|
return hostname.endsWith('.livekit.cloud') || hostname.endsWith('.livekit.run');
|
|
955
961
|
};
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* Whether the agent is running in development mode (launched via `dev` or `connect`).
|
|
965
|
+
*/
|
|
966
|
+
export const isDevMode = (): boolean => {
|
|
967
|
+
return process.env.LIVEKIT_DEV_MODE === '1';
|
|
968
|
+
};
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* Whether the agent is hosted on LiveKit Cloud.
|
|
972
|
+
*/
|
|
973
|
+
export const isHosted = (): boolean => {
|
|
974
|
+
return process.env.LIVEKIT_REMOTE_EOT_URL !== undefined;
|
|
975
|
+
};
|