@livekit/agents 1.0.0 → 1.0.2
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/ipc/job_proc_lazy_main.cjs +1 -2
- package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
- package/dist/ipc/job_proc_lazy_main.js +2 -3
- package/dist/ipc/job_proc_lazy_main.js.map +1 -1
- package/dist/ipc/proc_pool.cjs +14 -2
- package/dist/ipc/proc_pool.cjs.map +1 -1
- package/dist/ipc/proc_pool.d.ts.map +1 -1
- package/dist/ipc/proc_pool.js +14 -2
- package/dist/ipc/proc_pool.js.map +1 -1
- package/dist/ipc/supervised_proc.cjs +32 -10
- package/dist/ipc/supervised_proc.cjs.map +1 -1
- package/dist/ipc/supervised_proc.d.cts +2 -0
- package/dist/ipc/supervised_proc.d.ts +2 -0
- package/dist/ipc/supervised_proc.d.ts.map +1 -1
- package/dist/ipc/supervised_proc.js +22 -10
- package/dist/ipc/supervised_proc.js.map +1 -1
- package/dist/llm/llm.cjs +4 -1
- package/dist/llm/llm.cjs.map +1 -1
- package/dist/llm/llm.d.ts.map +1 -1
- package/dist/llm/llm.js +4 -1
- package/dist/llm/llm.js.map +1 -1
- package/dist/vad.cjs +3 -0
- package/dist/vad.cjs.map +1 -1
- package/dist/vad.d.ts.map +1 -1
- package/dist/vad.js +3 -0
- package/dist/vad.js.map +1 -1
- package/dist/voice/audio_recognition.cjs +3 -0
- package/dist/voice/audio_recognition.cjs.map +1 -1
- package/dist/voice/audio_recognition.d.ts.map +1 -1
- package/dist/voice/audio_recognition.js +3 -0
- package/dist/voice/audio_recognition.js.map +1 -1
- package/dist/worker.cjs +25 -4
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +25 -4
- package/dist/worker.js.map +1 -1
- package/package.json +4 -2
- package/src/ipc/job_proc_lazy_main.ts +2 -3
- package/src/ipc/proc_pool.ts +14 -2
- package/src/ipc/supervised_proc.ts +23 -10
- package/src/llm/llm.ts +4 -2
- package/src/vad.ts +3 -0
- package/src/voice/audio_recognition.ts +5 -0
- package/src/worker.ts +25 -4
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
import type { ChildProcess } from 'node:child_process';
|
|
5
5
|
import { once } from 'node:events';
|
|
6
|
+
import pidusage from 'pidusage';
|
|
6
7
|
import type { RunningJobInfo } from '../job.js';
|
|
7
8
|
import { log, loggerOptions } from '../log.js';
|
|
8
9
|
import { Future } from '../utils.js';
|
|
@@ -25,7 +26,7 @@ export abstract class SupervisedProc {
|
|
|
25
26
|
#runningJob?: RunningJobInfo = undefined;
|
|
26
27
|
proc?: ChildProcess;
|
|
27
28
|
#pingInterval?: ReturnType<typeof setInterval>;
|
|
28
|
-
#
|
|
29
|
+
#memoryMonitorInterval?: ReturnType<typeof setInterval>;
|
|
29
30
|
#pongTimeout?: ReturnType<typeof setTimeout>;
|
|
30
31
|
protected init = new Future();
|
|
31
32
|
#join = new Future();
|
|
@@ -90,8 +91,8 @@ export abstract class SupervisedProc {
|
|
|
90
91
|
this.#join.resolve();
|
|
91
92
|
}, this.#opts.pingTimeout);
|
|
92
93
|
|
|
93
|
-
this.#
|
|
94
|
-
const memoryMB =
|
|
94
|
+
this.#memoryMonitorInterval = setInterval(async () => {
|
|
95
|
+
const memoryMB = await this.getChildMemoryUsageMB();
|
|
95
96
|
if (this.#opts.memoryLimitMB > 0 && memoryMB > this.#opts.memoryLimitMB) {
|
|
96
97
|
this.#logger
|
|
97
98
|
.child({ memoryUsageMB: memoryMB, memoryLimitMB: this.#opts.memoryLimitMB })
|
|
@@ -104,9 +105,9 @@ export abstract class SupervisedProc {
|
|
|
104
105
|
memoryWarnMB: this.#opts.memoryWarnMB,
|
|
105
106
|
memoryLimitMB: this.#opts.memoryLimitMB,
|
|
106
107
|
})
|
|
107
|
-
.
|
|
108
|
+
.warn('process memory usage is high');
|
|
108
109
|
}
|
|
109
|
-
});
|
|
110
|
+
}, 5000);
|
|
110
111
|
|
|
111
112
|
const listener = (msg: IPCMessage) => {
|
|
112
113
|
switch (msg.case) {
|
|
@@ -135,9 +136,7 @@ export abstract class SupervisedProc {
|
|
|
135
136
|
this.#logger
|
|
136
137
|
.child({ err })
|
|
137
138
|
.warn('job process exited unexpectedly; this likely means the error above caused a crash');
|
|
138
|
-
|
|
139
|
-
clearInterval(this.#pingInterval);
|
|
140
|
-
clearInterval(this.#memoryWatch);
|
|
139
|
+
this.clearTimers();
|
|
141
140
|
this.#join.resolve();
|
|
142
141
|
});
|
|
143
142
|
|
|
@@ -196,8 +195,7 @@ export abstract class SupervisedProc {
|
|
|
196
195
|
}, this.#opts.closeTimeout);
|
|
197
196
|
await this.#join.await.then(() => {
|
|
198
197
|
clearTimeout(timer);
|
|
199
|
-
|
|
200
|
-
clearInterval(this.#pingInterval);
|
|
198
|
+
this.clearTimers();
|
|
201
199
|
});
|
|
202
200
|
}
|
|
203
201
|
|
|
@@ -208,4 +206,19 @@ export abstract class SupervisedProc {
|
|
|
208
206
|
this.#runningJob = info;
|
|
209
207
|
this.proc!.send({ case: 'startJobRequest', value: { runningJob: info } });
|
|
210
208
|
}
|
|
209
|
+
|
|
210
|
+
private async getChildMemoryUsageMB(): Promise<number> {
|
|
211
|
+
const pid = this.proc?.pid;
|
|
212
|
+
if (!pid) {
|
|
213
|
+
return 0;
|
|
214
|
+
}
|
|
215
|
+
const stats = await pidusage(pid);
|
|
216
|
+
return stats.memory / (1024 * 1024); // Convert bytes to MB
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private clearTimers() {
|
|
220
|
+
clearTimeout(this.#pongTimeout);
|
|
221
|
+
clearInterval(this.#pingInterval);
|
|
222
|
+
clearInterval(this.#memoryMonitorInterval);
|
|
223
|
+
}
|
|
211
224
|
}
|
package/src/llm/llm.ts
CHANGED
|
@@ -215,8 +215,10 @@ export abstract class LLMStream implements AsyncIterableIterator<ChatChunk> {
|
|
|
215
215
|
promptTokens: usage?.promptTokens || 0,
|
|
216
216
|
promptCachedTokens: usage?.promptCachedTokens || 0,
|
|
217
217
|
totalTokens: usage?.totalTokens || 0,
|
|
218
|
-
tokensPerSecond:
|
|
219
|
-
|
|
218
|
+
tokensPerSecond: (() => {
|
|
219
|
+
const durationSeconds = Math.trunc(Number(duration / BigInt(1000000000)));
|
|
220
|
+
return durationSeconds > 0 ? (usage?.completionTokens || 0) / durationSeconds : 0;
|
|
221
|
+
})(),
|
|
220
222
|
};
|
|
221
223
|
this.#llm.emit('metrics_collected', metrics);
|
|
222
224
|
}
|
package/src/vad.ts
CHANGED
|
@@ -167,6 +167,9 @@ export abstract class VADStream implements AsyncIterableIterator<VADEvent> {
|
|
|
167
167
|
}
|
|
168
168
|
break;
|
|
169
169
|
case VADEventType.INFERENCE_DONE:
|
|
170
|
+
inferenceDurationTotal += value.inferenceDuration;
|
|
171
|
+
this.#lastActivityTime = process.hrtime.bigint();
|
|
172
|
+
break;
|
|
170
173
|
case VADEventType.END_OF_SPEECH:
|
|
171
174
|
this.#lastActivityTime = process.hrtime.bigint();
|
|
172
175
|
break;
|
|
@@ -367,6 +367,11 @@ export class AudioRecognition {
|
|
|
367
367
|
this.hooks.onStartOfSpeech(ev);
|
|
368
368
|
this.speaking = true;
|
|
369
369
|
|
|
370
|
+
// Capture sample rate from the first VAD event if not already set
|
|
371
|
+
if (ev.frames.length > 0 && ev.frames[0]) {
|
|
372
|
+
this.sampleRate = ev.frames[0].sampleRate;
|
|
373
|
+
}
|
|
374
|
+
|
|
370
375
|
this.bounceEOUTask?.cancel();
|
|
371
376
|
break;
|
|
372
377
|
case VADEventType.INFERENCE_DONE:
|
package/src/worker.ts
CHANGED
|
@@ -190,7 +190,7 @@ export class WorkerOptions {
|
|
|
190
190
|
port = undefined,
|
|
191
191
|
logLevel = 'info',
|
|
192
192
|
production = false,
|
|
193
|
-
jobMemoryWarnMB =
|
|
193
|
+
jobMemoryWarnMB = 500,
|
|
194
194
|
jobMemoryLimitMB = 0,
|
|
195
195
|
}: {
|
|
196
196
|
/**
|
|
@@ -567,7 +567,14 @@ export class Worker {
|
|
|
567
567
|
if (!msg.message.value.job) return;
|
|
568
568
|
const task = this.#availability(msg.message.value);
|
|
569
569
|
this.#tasks.push(task);
|
|
570
|
-
task.finally(() =>
|
|
570
|
+
task.finally(() => {
|
|
571
|
+
const taskIndex = this.#tasks.indexOf(task);
|
|
572
|
+
if (taskIndex !== -1) {
|
|
573
|
+
this.#tasks.splice(taskIndex, 1);
|
|
574
|
+
} else {
|
|
575
|
+
throw new Error(`task ${task} not found in tasks`);
|
|
576
|
+
}
|
|
577
|
+
});
|
|
571
578
|
break;
|
|
572
579
|
}
|
|
573
580
|
case 'assignment': {
|
|
@@ -585,7 +592,14 @@ export class Worker {
|
|
|
585
592
|
case 'termination': {
|
|
586
593
|
const task = this.#termination(msg.message.value);
|
|
587
594
|
this.#tasks.push(task);
|
|
588
|
-
task.finally(() =>
|
|
595
|
+
task.finally(() => {
|
|
596
|
+
const taskIndex = this.#tasks.indexOf(task);
|
|
597
|
+
if (taskIndex !== -1) {
|
|
598
|
+
this.#tasks.splice(taskIndex, 1);
|
|
599
|
+
} else {
|
|
600
|
+
throw new Error(`task ${task} not found in tasks`);
|
|
601
|
+
}
|
|
602
|
+
});
|
|
589
603
|
break;
|
|
590
604
|
}
|
|
591
605
|
}
|
|
@@ -737,7 +751,14 @@ export class Worker {
|
|
|
737
751
|
|
|
738
752
|
const task = jobRequestTask();
|
|
739
753
|
this.#tasks.push(task);
|
|
740
|
-
task.finally(() =>
|
|
754
|
+
task.finally(() => {
|
|
755
|
+
const taskIndex = this.#tasks.indexOf(task);
|
|
756
|
+
if (taskIndex !== -1) {
|
|
757
|
+
this.#tasks.splice(taskIndex, 1);
|
|
758
|
+
} else {
|
|
759
|
+
throw new Error(`task ${task} not found in tasks`);
|
|
760
|
+
}
|
|
761
|
+
});
|
|
741
762
|
}
|
|
742
763
|
|
|
743
764
|
async #termination(msg: JobTermination) {
|