@livekit/agents 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/index.cjs +2 -5
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +2 -3
  4. package/dist/index.d.ts +2 -3
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +1 -3
  7. package/dist/index.js.map +1 -1
  8. package/dist/tokenize/basic/hyphenator.cjs.map +1 -1
  9. package/dist/tokenize/basic/hyphenator.js.map +1 -1
  10. package/dist/utils.cjs +77 -0
  11. package/dist/utils.cjs.map +1 -1
  12. package/dist/utils.d.cts +21 -0
  13. package/dist/utils.d.ts +21 -0
  14. package/dist/utils.d.ts.map +1 -1
  15. package/dist/utils.js +76 -1
  16. package/dist/utils.js.map +1 -1
  17. package/dist/voice/agent_activity.cjs +112 -71
  18. package/dist/voice/agent_activity.cjs.map +1 -1
  19. package/dist/voice/agent_activity.d.ts.map +1 -1
  20. package/dist/voice/agent_activity.js +112 -71
  21. package/dist/voice/agent_activity.js.map +1 -1
  22. package/dist/voice/avatar/datastream_io.cjs +204 -0
  23. package/dist/voice/avatar/datastream_io.cjs.map +1 -0
  24. package/dist/voice/avatar/datastream_io.d.cts +37 -0
  25. package/dist/voice/avatar/datastream_io.d.ts +37 -0
  26. package/dist/voice/avatar/datastream_io.d.ts.map +1 -0
  27. package/dist/voice/avatar/datastream_io.js +188 -0
  28. package/dist/voice/avatar/datastream_io.js.map +1 -0
  29. package/dist/{multimodal → voice/avatar}/index.cjs +4 -4
  30. package/dist/voice/avatar/index.cjs.map +1 -0
  31. package/dist/voice/avatar/index.d.cts +2 -0
  32. package/dist/voice/avatar/index.d.ts +2 -0
  33. package/dist/voice/avatar/index.d.ts.map +1 -0
  34. package/dist/voice/avatar/index.js +2 -0
  35. package/dist/voice/avatar/index.js.map +1 -0
  36. package/dist/voice/index.cjs +2 -0
  37. package/dist/voice/index.cjs.map +1 -1
  38. package/dist/voice/index.d.cts +1 -0
  39. package/dist/voice/index.d.ts +1 -0
  40. package/dist/voice/index.d.ts.map +1 -1
  41. package/dist/voice/index.js +1 -0
  42. package/dist/voice/index.js.map +1 -1
  43. package/dist/voice/io.cjs.map +1 -1
  44. package/dist/voice/io.d.cts +1 -1
  45. package/dist/voice/io.d.ts +1 -1
  46. package/dist/voice/io.d.ts.map +1 -1
  47. package/dist/voice/io.js.map +1 -1
  48. package/dist/voice/room_io/_input.cjs +2 -1
  49. package/dist/voice/room_io/_input.cjs.map +1 -1
  50. package/dist/voice/room_io/_input.d.ts.map +1 -1
  51. package/dist/voice/room_io/_input.js +2 -1
  52. package/dist/voice/room_io/_input.js.map +1 -1
  53. package/dist/voice/run_context.cjs +13 -0
  54. package/dist/voice/run_context.cjs.map +1 -1
  55. package/dist/voice/run_context.d.cts +10 -0
  56. package/dist/voice/run_context.d.ts +10 -0
  57. package/dist/voice/run_context.d.ts.map +1 -1
  58. package/dist/voice/run_context.js +13 -0
  59. package/dist/voice/run_context.js.map +1 -1
  60. package/dist/voice/speech_handle.cjs +152 -30
  61. package/dist/voice/speech_handle.cjs.map +1 -1
  62. package/dist/voice/speech_handle.d.cts +67 -16
  63. package/dist/voice/speech_handle.d.ts +67 -16
  64. package/dist/voice/speech_handle.d.ts.map +1 -1
  65. package/dist/voice/speech_handle.js +153 -31
  66. package/dist/voice/speech_handle.js.map +1 -1
  67. package/dist/worker.cjs +4 -1
  68. package/dist/worker.cjs.map +1 -1
  69. package/dist/worker.d.ts.map +1 -1
  70. package/dist/worker.js +4 -1
  71. package/dist/worker.js.map +1 -1
  72. package/package.json +2 -2
  73. package/src/index.ts +2 -3
  74. package/src/tokenize/basic/hyphenator.ts +1 -1
  75. package/src/utils.ts +121 -1
  76. package/src/voice/agent_activity.ts +128 -78
  77. package/src/voice/avatar/datastream_io.ts +247 -0
  78. package/src/voice/avatar/index.ts +4 -0
  79. package/src/voice/index.ts +2 -0
  80. package/src/voice/io.ts +1 -1
  81. package/src/voice/room_io/_input.ts +8 -3
  82. package/src/voice/run_context.ts +16 -2
  83. package/src/voice/speech_handle.ts +183 -38
  84. package/src/worker.ts +5 -1
  85. package/dist/multimodal/agent_playout.cjs +0 -233
  86. package/dist/multimodal/agent_playout.cjs.map +0 -1
  87. package/dist/multimodal/agent_playout.d.cts +0 -34
  88. package/dist/multimodal/agent_playout.d.ts +0 -34
  89. package/dist/multimodal/agent_playout.d.ts.map +0 -1
  90. package/dist/multimodal/agent_playout.js +0 -207
  91. package/dist/multimodal/agent_playout.js.map +0 -1
  92. package/dist/multimodal/index.cjs.map +0 -1
  93. package/dist/multimodal/index.d.cts +0 -2
  94. package/dist/multimodal/index.d.ts +0 -2
  95. package/dist/multimodal/index.d.ts.map +0 -1
  96. package/dist/multimodal/index.js +0 -2
  97. package/dist/multimodal/index.js.map +0 -1
  98. package/src/multimodal/agent_playout.ts +0 -266
  99. package/src/multimodal/index.ts +0 -4
@@ -1,266 +0,0 @@
1
- // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
- //
3
- // SPDX-License-Identifier: Apache-2.0
4
- import type { AudioFrame } from '@livekit/rtc-node';
5
- import { type AudioSource } from '@livekit/rtc-node';
6
- import { EventEmitter } from 'node:events';
7
- import { AudioByteStream } from '../audio.js';
8
- import type { TextAudioSynchronizer } from '../transcription.js';
9
- import { type AsyncIterableQueue, CancellablePromise, Future, gracefullyCancel } from '../utils.js';
10
-
11
- export const proto = {};
12
-
13
- export class PlayoutHandle extends EventEmitter {
14
- #audioSource: AudioSource;
15
- #sampleRate: number;
16
- #itemId: string;
17
- #contentIndex: number;
18
- /** @internal */
19
- synchronizer: TextAudioSynchronizer;
20
- /** @internal */
21
- doneFut: Future;
22
- /** @internal */
23
- intFut: Future;
24
- /** @internal */
25
- #interrupted: boolean;
26
- /** @internal */
27
- pushedDuration: number;
28
- /** @internal */
29
- totalPlayedTime: number | undefined; // Set when playout is done
30
-
31
- constructor(
32
- audioSource: AudioSource,
33
- sampleRate: number,
34
- itemId: string,
35
- contentIndex: number,
36
- synchronizer: TextAudioSynchronizer,
37
- ) {
38
- super();
39
- this.#audioSource = audioSource;
40
- this.#sampleRate = sampleRate;
41
- this.#itemId = itemId;
42
- this.#contentIndex = contentIndex;
43
- this.synchronizer = synchronizer;
44
- this.doneFut = new Future();
45
- this.intFut = new Future();
46
- this.#interrupted = false;
47
- this.pushedDuration = 0;
48
- this.totalPlayedTime = undefined;
49
- }
50
-
51
- get itemId(): string {
52
- return this.#itemId;
53
- }
54
-
55
- get audioSamples(): number {
56
- if (this.totalPlayedTime !== undefined) {
57
- return Math.floor(this.totalPlayedTime * this.#sampleRate);
58
- }
59
-
60
- return Math.max(
61
- 0,
62
- Math.floor(
63
- (this.pushedDuration - this.#audioSource.queuedDuration) * (this.#sampleRate / 1000),
64
- ),
65
- );
66
- }
67
-
68
- get textChars(): number {
69
- return this.synchronizer.playedText.length;
70
- }
71
-
72
- get contentIndex(): number {
73
- return this.#contentIndex;
74
- }
75
-
76
- get interrupted(): boolean {
77
- return this.#interrupted;
78
- }
79
-
80
- get done(): boolean {
81
- return this.doneFut.done || this.#interrupted;
82
- }
83
-
84
- interrupt() {
85
- if (this.doneFut.done) return;
86
- this.intFut.resolve();
87
- this.#interrupted = true;
88
- }
89
- }
90
-
91
- export class AgentPlayout extends EventEmitter {
92
- #audioSource: AudioSource;
93
- #playoutTask: CancellablePromise<void> | null;
94
- #sampleRate: number;
95
- #numChannels: number;
96
- #inFrameSize: number;
97
- #outFrameSize: number;
98
- constructor(
99
- audioSource: AudioSource,
100
- sampleRate: number,
101
- numChannels: number,
102
- inFrameSize: number,
103
- outFrameSize: number,
104
- ) {
105
- super();
106
- this.#audioSource = audioSource;
107
- this.#playoutTask = null;
108
- this.#sampleRate = sampleRate;
109
- this.#numChannels = numChannels;
110
- this.#inFrameSize = inFrameSize;
111
- this.#outFrameSize = outFrameSize;
112
- }
113
-
114
- play(
115
- itemId: string,
116
- contentIndex: number,
117
- synchronizer: TextAudioSynchronizer,
118
- textStream: AsyncIterableQueue<string>,
119
- audioStream: AsyncIterableQueue<AudioFrame>,
120
- ): PlayoutHandle {
121
- const handle = new PlayoutHandle(
122
- this.#audioSource,
123
- this.#sampleRate,
124
- itemId,
125
- contentIndex,
126
- synchronizer,
127
- );
128
- this.#playoutTask = this.#makePlayoutTask(this.#playoutTask, handle, textStream, audioStream);
129
- return handle;
130
- }
131
-
132
- #makePlayoutTask(
133
- oldTask: CancellablePromise<void> | null,
134
- handle: PlayoutHandle,
135
- textStream: AsyncIterableQueue<string>,
136
- audioStream: AsyncIterableQueue<AudioFrame>,
137
- ): CancellablePromise<void> {
138
- return new CancellablePromise<void>((resolve, reject, onCancel) => {
139
- let cancelled = false;
140
- onCancel(() => {
141
- cancelled = true;
142
- });
143
-
144
- (async () => {
145
- try {
146
- if (oldTask) {
147
- await gracefullyCancel(oldTask);
148
- }
149
-
150
- let firstFrame = true;
151
-
152
- const readText = () =>
153
- new CancellablePromise<void>((resolveText, rejectText, onCancelText) => {
154
- let cancelledText = false;
155
- onCancelText(() => {
156
- cancelledText = true;
157
- });
158
-
159
- (async () => {
160
- try {
161
- for await (const text of textStream) {
162
- if (cancelledText || cancelled) {
163
- break;
164
- }
165
- handle.synchronizer.pushText(text);
166
- }
167
- if (!cancelled) {
168
- handle.synchronizer.markTextSegmentEnd();
169
- }
170
- resolveText();
171
- } catch (error) {
172
- rejectText(error);
173
- }
174
- })();
175
- });
176
-
177
- const capture = () =>
178
- new CancellablePromise<void>((resolveCapture, rejectCapture, onCancelCapture) => {
179
- let cancelledCapture = false;
180
- onCancelCapture(() => {
181
- cancelledCapture = true;
182
- });
183
-
184
- (async () => {
185
- try {
186
- const samplesPerChannel = this.#outFrameSize;
187
- const bstream = new AudioByteStream(
188
- this.#sampleRate,
189
- this.#numChannels,
190
- samplesPerChannel,
191
- );
192
-
193
- for await (const frame of audioStream) {
194
- if (cancelledCapture || cancelled) {
195
- break;
196
- }
197
- if (firstFrame) {
198
- handle.synchronizer.segmentPlayoutStarted();
199
- this.emit('playout_started');
200
- firstFrame = false;
201
- }
202
-
203
- handle.synchronizer.pushAudio(frame);
204
-
205
- for (const f of bstream.write(frame.data.buffer)) {
206
- handle.pushedDuration += (f.samplesPerChannel / f.sampleRate) * 1000;
207
- await this.#audioSource.captureFrame(f);
208
- }
209
- }
210
-
211
- if (!cancelledCapture && !cancelled) {
212
- for (const f of bstream.flush()) {
213
- handle.pushedDuration += (f.samplesPerChannel / f.sampleRate) * 1000;
214
- await this.#audioSource.captureFrame(f);
215
- }
216
-
217
- handle.synchronizer.markAudioSegmentEnd();
218
-
219
- await this.#audioSource.waitForPlayout();
220
- }
221
-
222
- resolveCapture();
223
- } catch (error) {
224
- rejectCapture(error);
225
- }
226
- })();
227
- });
228
-
229
- const readTextTask = readText();
230
- const captureTask = capture();
231
-
232
- try {
233
- await Promise.race([captureTask, handle.intFut.await]);
234
- } finally {
235
- if (!captureTask.isCancelled) {
236
- await gracefullyCancel(captureTask);
237
- }
238
-
239
- if (!readTextTask.isCancelled) {
240
- await gracefullyCancel(readTextTask);
241
- }
242
-
243
- handle.totalPlayedTime = handle.pushedDuration - this.#audioSource.queuedDuration;
244
-
245
- if (handle.interrupted || captureTask.error) {
246
- this.#audioSource.clearQueue(); // make sure to remove any queued frames
247
- }
248
-
249
- if (!firstFrame) {
250
- this.emit('playout_stopped', handle.interrupted);
251
- }
252
-
253
- handle.doneFut.resolve();
254
-
255
- const isInterrupted = handle.interrupted || !!captureTask.error;
256
- await handle.synchronizer.close(isInterrupted);
257
- }
258
-
259
- resolve();
260
- } catch (error) {
261
- reject(error);
262
- }
263
- })();
264
- });
265
- }
266
- }
@@ -1,4 +0,0 @@
1
- // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
- //
3
- // SPDX-License-Identifier: Apache-2.0
4
- export * from './agent_playout.js';