@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
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var datastream_io_exports = {};
20
+ __export(datastream_io_exports, {
21
+ DataStreamAudioOutput: () => DataStreamAudioOutput
22
+ });
23
+ module.exports = __toCommonJS(datastream_io_exports);
24
+ var import_mutex = require("@livekit/mutex");
25
+ var import_rtc_node = require("@livekit/rtc-node");
26
+ var import_log = require("../../log.cjs");
27
+ var import_utils = require("../../utils.cjs");
28
+ var import_io = require("../io.cjs");
29
+ const RPC_CLEAR_BUFFER = "lk.clear_buffer";
30
+ const RPC_PLAYBACK_FINISHED = "lk.playback_finished";
31
+ const AUDIO_STREAM_TOPIC = "lk.audio_stream";
32
+ class DataStreamAudioOutput extends import_io.AudioOutput {
33
+ static _playbackFinishedRpcRegistered = false;
34
+ static _playbackFinishedHandlers = {};
35
+ room;
36
+ destinationIdentity;
37
+ roomConnectedFuture;
38
+ waitRemoteTrack;
39
+ streamWriter;
40
+ pushedDuration = 0;
41
+ started = false;
42
+ lock = new import_mutex.Mutex();
43
+ startTask;
44
+ #logger = (0, import_log.log)();
45
+ constructor(opts) {
46
+ super(opts.sampleRate, void 0);
47
+ const { room, destinationIdentity, sampleRate, waitRemoteTrack } = opts;
48
+ this.room = room;
49
+ this.destinationIdentity = destinationIdentity;
50
+ this.sampleRate = sampleRate;
51
+ this.waitRemoteTrack = waitRemoteTrack;
52
+ const onRoomConnected = async () => {
53
+ if (this.startTask) return;
54
+ await this.roomConnectedFuture.await;
55
+ DataStreamAudioOutput.registerPlaybackFinishedRpc({
56
+ room,
57
+ callerIdentity: this.destinationIdentity,
58
+ handler: (data) => this.handlePlaybackFinished(data)
59
+ });
60
+ this.startTask = import_utils.Task.from(({ signal }) => this._start(signal));
61
+ };
62
+ this.roomConnectedFuture = new import_utils.Future();
63
+ this.room.on(import_rtc_node.RoomEvent.ConnectionStateChanged, (_) => {
64
+ if (room.isConnected && !this.roomConnectedFuture.done) {
65
+ this.roomConnectedFuture.resolve(void 0);
66
+ }
67
+ });
68
+ if (this.room.isConnected) {
69
+ this.roomConnectedFuture.resolve(void 0);
70
+ }
71
+ onRoomConnected();
72
+ }
73
+ async _start(_abortSignal) {
74
+ const unlock = await this.lock.lock();
75
+ try {
76
+ if (this.started) return;
77
+ await this.roomConnectedFuture.await;
78
+ this.#logger.debug(
79
+ {
80
+ identity: this.destinationIdentity
81
+ },
82
+ "waiting for the remote participant"
83
+ );
84
+ await (0, import_utils.waitForParticipant)({
85
+ room: this.room,
86
+ identity: this.destinationIdentity
87
+ });
88
+ if (this.waitRemoteTrack) {
89
+ this.#logger.debug(
90
+ {
91
+ identity: this.destinationIdentity,
92
+ kind: this.waitRemoteTrack
93
+ },
94
+ "waiting for the remote track"
95
+ );
96
+ await (0, import_utils.waitForTrackPublication)({
97
+ room: this.room,
98
+ identity: this.destinationIdentity,
99
+ kind: this.waitRemoteTrack
100
+ });
101
+ }
102
+ this.#logger.debug(
103
+ {
104
+ identity: this.destinationIdentity
105
+ },
106
+ "remote participant ready"
107
+ );
108
+ this.started = true;
109
+ } finally {
110
+ unlock();
111
+ }
112
+ }
113
+ async captureFrame(frame) {
114
+ if (!this.startTask) {
115
+ this.startTask = import_utils.Task.from(({ signal }) => this._start(signal));
116
+ }
117
+ await this.startTask.result;
118
+ await super.captureFrame(frame);
119
+ if (!this.streamWriter) {
120
+ this.streamWriter = await this.room.localParticipant.streamBytes({
121
+ name: (0, import_utils.shortuuid)("AUDIO_"),
122
+ topic: AUDIO_STREAM_TOPIC,
123
+ destinationIdentities: [this.destinationIdentity],
124
+ attributes: {
125
+ sample_rate: frame.sampleRate.toString(),
126
+ num_channels: frame.channels.toString()
127
+ }
128
+ });
129
+ this.pushedDuration = 0;
130
+ }
131
+ await this.streamWriter.write(new Uint8Array(frame.data.buffer));
132
+ this.pushedDuration += frame.samplesPerChannel / frame.sampleRate;
133
+ }
134
+ flush() {
135
+ super.flush();
136
+ if (this.streamWriter === void 0 || !this.started) {
137
+ return;
138
+ }
139
+ this.streamWriter.close().finally(() => {
140
+ this.streamWriter = void 0;
141
+ });
142
+ }
143
+ clearBuffer() {
144
+ if (!this.started) return;
145
+ this.room.localParticipant.performRpc({
146
+ destinationIdentity: this.destinationIdentity,
147
+ method: RPC_CLEAR_BUFFER,
148
+ payload: ""
149
+ });
150
+ }
151
+ handlePlaybackFinished(data) {
152
+ if (data.callerIdentity !== this.destinationIdentity) {
153
+ this.#logger.warn(
154
+ {
155
+ callerIdentity: data.callerIdentity,
156
+ destinationIdentity: this.destinationIdentity
157
+ },
158
+ "playback finished event received from unexpected participant"
159
+ );
160
+ return "reject";
161
+ }
162
+ this.#logger.info(
163
+ {
164
+ callerIdentity: data.callerIdentity
165
+ },
166
+ "playback finished event received"
167
+ );
168
+ const playbackFinishedEvent = JSON.parse(data.payload);
169
+ this.onPlaybackFinished(playbackFinishedEvent);
170
+ return "ok";
171
+ }
172
+ static registerPlaybackFinishedRpc({
173
+ room,
174
+ callerIdentity,
175
+ handler
176
+ }) {
177
+ var _a;
178
+ DataStreamAudioOutput._playbackFinishedHandlers[callerIdentity] = handler;
179
+ if (DataStreamAudioOutput._playbackFinishedRpcRegistered) {
180
+ return;
181
+ }
182
+ const rpcHandler = async (data) => {
183
+ const handler2 = DataStreamAudioOutput._playbackFinishedHandlers[data.callerIdentity];
184
+ if (!handler2) {
185
+ (0, import_log.log)().warn(
186
+ {
187
+ callerIdentity: data.callerIdentity,
188
+ expectedIdentities: Object.keys(DataStreamAudioOutput._playbackFinishedHandlers)
189
+ },
190
+ "playback finished event received from unexpected participant"
191
+ );
192
+ return "reject";
193
+ }
194
+ return handler2(data);
195
+ };
196
+ (_a = room.localParticipant) == null ? void 0 : _a.registerRpcMethod(RPC_PLAYBACK_FINISHED, rpcHandler);
197
+ DataStreamAudioOutput._playbackFinishedRpcRegistered = true;
198
+ }
199
+ }
200
+ // Annotate the CommonJS export names for ESM import in node:
201
+ 0 && (module.exports = {
202
+ DataStreamAudioOutput
203
+ });
204
+ //# sourceMappingURL=datastream_io.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/voice/avatar/datastream_io.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Mutex } from '@livekit/mutex';\nimport {\n type AudioFrame,\n type ByteStreamWriter,\n type Room,\n RoomEvent,\n type RpcInvocationData,\n type TrackKind,\n} from '@livekit/rtc-node';\nimport { log } from '../../log.js';\nimport {\n Future,\n Task,\n shortuuid,\n waitForParticipant,\n waitForTrackPublication,\n} from '../../utils.js';\nimport { AudioOutput, type PlaybackFinishedEvent } from '../io.js';\n\nconst RPC_CLEAR_BUFFER = 'lk.clear_buffer';\nconst RPC_PLAYBACK_FINISHED = 'lk.playback_finished';\nconst AUDIO_STREAM_TOPIC = 'lk.audio_stream';\n\nexport interface DataStreamAudioOutputOptions {\n room: Room;\n destinationIdentity: string;\n sampleRate?: number;\n waitRemoteTrack?: TrackKind;\n}\n\n/**\n * AudioOutput implementation that streams audio to a remote avatar worker using LiveKit DataStream.\n */\nexport class DataStreamAudioOutput extends AudioOutput {\n static _playbackFinishedRpcRegistered: boolean = false;\n static _playbackFinishedHandlers: Record<string, (data: RpcInvocationData) => string> = {};\n\n private room: Room;\n private destinationIdentity: string;\n private roomConnectedFuture: Future<void>;\n private waitRemoteTrack?: TrackKind;\n private streamWriter?: ByteStreamWriter;\n private pushedDuration: number = 0;\n private started: boolean = false;\n private lock = new Mutex();\n private startTask?: Task<void>;\n\n #logger = log();\n\n constructor(opts: DataStreamAudioOutputOptions) {\n super(opts.sampleRate, undefined);\n\n const { room, destinationIdentity, sampleRate, waitRemoteTrack } = opts;\n this.room = room;\n this.destinationIdentity = destinationIdentity;\n this.sampleRate = sampleRate;\n this.waitRemoteTrack = waitRemoteTrack;\n\n const onRoomConnected = async () => {\n if (this.startTask) return;\n\n await this.roomConnectedFuture.await;\n\n // register the rpc method right after the room is connected\n DataStreamAudioOutput.registerPlaybackFinishedRpc({\n room,\n callerIdentity: this.destinationIdentity,\n handler: (data) => this.handlePlaybackFinished(data),\n });\n\n this.startTask = Task.from(({ signal }) => this._start(signal));\n };\n\n this.roomConnectedFuture = new Future<void>();\n\n this.room.on(RoomEvent.ConnectionStateChanged, (_) => {\n if (room.isConnected && !this.roomConnectedFuture.done) {\n this.roomConnectedFuture.resolve(undefined);\n }\n });\n\n if (this.room.isConnected) {\n this.roomConnectedFuture.resolve(undefined);\n }\n\n onRoomConnected();\n }\n\n private async _start(_abortSignal: AbortSignal) {\n const unlock = await this.lock.lock();\n\n try {\n if (this.started) return;\n\n await this.roomConnectedFuture.await;\n\n this.#logger.debug(\n {\n identity: this.destinationIdentity,\n },\n 'waiting for the remote participant',\n );\n\n await waitForParticipant({\n room: this.room,\n identity: this.destinationIdentity,\n });\n\n if (this.waitRemoteTrack) {\n this.#logger.debug(\n {\n identity: this.destinationIdentity,\n kind: this.waitRemoteTrack,\n },\n 'waiting for the remote track',\n );\n\n await waitForTrackPublication({\n room: this.room,\n identity: this.destinationIdentity,\n kind: this.waitRemoteTrack,\n });\n }\n\n this.#logger.debug(\n {\n identity: this.destinationIdentity,\n },\n 'remote participant ready',\n );\n\n this.started = true;\n } finally {\n unlock();\n }\n }\n\n async captureFrame(frame: AudioFrame): Promise<void> {\n if (!this.startTask) {\n this.startTask = Task.from(({ signal }) => this._start(signal));\n }\n\n await this.startTask.result;\n await super.captureFrame(frame);\n\n if (!this.streamWriter) {\n this.streamWriter = await this.room.localParticipant!.streamBytes({\n name: shortuuid('AUDIO_'),\n topic: AUDIO_STREAM_TOPIC,\n destinationIdentities: [this.destinationIdentity],\n attributes: {\n sample_rate: frame.sampleRate.toString(),\n num_channels: frame.channels.toString(),\n },\n });\n this.pushedDuration = 0;\n }\n\n // frame.data is a Int16Array, write accepts a Uint8Array\n await this.streamWriter.write(new Uint8Array(frame.data.buffer));\n this.pushedDuration += frame.samplesPerChannel / frame.sampleRate;\n }\n\n flush(): void {\n super.flush();\n\n if (this.streamWriter === undefined || !this.started) {\n return;\n }\n\n this.streamWriter.close().finally(() => {\n this.streamWriter = undefined;\n });\n }\n\n clearBuffer(): void {\n if (!this.started) return;\n\n this.room.localParticipant!.performRpc({\n destinationIdentity: this.destinationIdentity,\n method: RPC_CLEAR_BUFFER,\n payload: '',\n });\n }\n\n private handlePlaybackFinished(data: RpcInvocationData): string {\n if (data.callerIdentity !== this.destinationIdentity) {\n this.#logger.warn(\n {\n callerIdentity: data.callerIdentity,\n destinationIdentity: this.destinationIdentity,\n },\n 'playback finished event received from unexpected participant',\n );\n return 'reject';\n }\n\n this.#logger.info(\n {\n callerIdentity: data.callerIdentity,\n },\n 'playback finished event received',\n );\n\n const playbackFinishedEvent = JSON.parse(data.payload) as PlaybackFinishedEvent;\n this.onPlaybackFinished(playbackFinishedEvent);\n return 'ok';\n }\n\n static registerPlaybackFinishedRpc({\n room,\n callerIdentity,\n handler,\n }: {\n room: Room;\n callerIdentity: string;\n handler: (data: RpcInvocationData) => string;\n }) {\n DataStreamAudioOutput._playbackFinishedHandlers[callerIdentity] = handler;\n\n if (DataStreamAudioOutput._playbackFinishedRpcRegistered) {\n return;\n }\n\n const rpcHandler = async (data: RpcInvocationData): Promise<string> => {\n const handler = DataStreamAudioOutput._playbackFinishedHandlers[data.callerIdentity];\n if (!handler) {\n log().warn(\n {\n callerIdentity: data.callerIdentity,\n expectedIdentities: Object.keys(DataStreamAudioOutput._playbackFinishedHandlers),\n },\n 'playback finished event received from unexpected participant',\n );\n\n return 'reject';\n }\n return handler(data);\n };\n\n room.localParticipant?.registerRpcMethod(RPC_PLAYBACK_FINISHED, rpcHandler);\n DataStreamAudioOutput._playbackFinishedRpcRegistered = true;\n }\n}\n"],"mappings":"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","names":["handler"]}
@@ -0,0 +1,37 @@
1
+ import { type AudioFrame, type Room, type RpcInvocationData, type TrackKind } from '@livekit/rtc-node';
2
+ import { AudioOutput } from '../io.js';
3
+ export interface DataStreamAudioOutputOptions {
4
+ room: Room;
5
+ destinationIdentity: string;
6
+ sampleRate?: number;
7
+ waitRemoteTrack?: TrackKind;
8
+ }
9
+ /**
10
+ * AudioOutput implementation that streams audio to a remote avatar worker using LiveKit DataStream.
11
+ */
12
+ export declare class DataStreamAudioOutput extends AudioOutput {
13
+ #private;
14
+ static _playbackFinishedRpcRegistered: boolean;
15
+ static _playbackFinishedHandlers: Record<string, (data: RpcInvocationData) => string>;
16
+ private room;
17
+ private destinationIdentity;
18
+ private roomConnectedFuture;
19
+ private waitRemoteTrack?;
20
+ private streamWriter?;
21
+ private pushedDuration;
22
+ private started;
23
+ private lock;
24
+ private startTask?;
25
+ constructor(opts: DataStreamAudioOutputOptions);
26
+ private _start;
27
+ captureFrame(frame: AudioFrame): Promise<void>;
28
+ flush(): void;
29
+ clearBuffer(): void;
30
+ private handlePlaybackFinished;
31
+ static registerPlaybackFinishedRpc({ room, callerIdentity, handler, }: {
32
+ room: Room;
33
+ callerIdentity: string;
34
+ handler: (data: RpcInvocationData) => string;
35
+ }): void;
36
+ }
37
+ //# sourceMappingURL=datastream_io.d.ts.map
@@ -0,0 +1,37 @@
1
+ import { type AudioFrame, type Room, type RpcInvocationData, type TrackKind } from '@livekit/rtc-node';
2
+ import { AudioOutput } from '../io.js';
3
+ export interface DataStreamAudioOutputOptions {
4
+ room: Room;
5
+ destinationIdentity: string;
6
+ sampleRate?: number;
7
+ waitRemoteTrack?: TrackKind;
8
+ }
9
+ /**
10
+ * AudioOutput implementation that streams audio to a remote avatar worker using LiveKit DataStream.
11
+ */
12
+ export declare class DataStreamAudioOutput extends AudioOutput {
13
+ #private;
14
+ static _playbackFinishedRpcRegistered: boolean;
15
+ static _playbackFinishedHandlers: Record<string, (data: RpcInvocationData) => string>;
16
+ private room;
17
+ private destinationIdentity;
18
+ private roomConnectedFuture;
19
+ private waitRemoteTrack?;
20
+ private streamWriter?;
21
+ private pushedDuration;
22
+ private started;
23
+ private lock;
24
+ private startTask?;
25
+ constructor(opts: DataStreamAudioOutputOptions);
26
+ private _start;
27
+ captureFrame(frame: AudioFrame): Promise<void>;
28
+ flush(): void;
29
+ clearBuffer(): void;
30
+ private handlePlaybackFinished;
31
+ static registerPlaybackFinishedRpc({ room, callerIdentity, handler, }: {
32
+ room: Room;
33
+ callerIdentity: string;
34
+ handler: (data: RpcInvocationData) => string;
35
+ }): void;
36
+ }
37
+ //# sourceMappingURL=datastream_io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datastream_io.d.ts","sourceRoot":"","sources":["../../../src/voice/avatar/datastream_io.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,IAAI,EAET,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAC;AAS3B,OAAO,EAAE,WAAW,EAA8B,MAAM,UAAU,CAAC;AAMnE,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,IAAI,CAAC;IACX,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,SAAS,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,WAAW;;IACpD,MAAM,CAAC,8BAA8B,EAAE,OAAO,CAAS;IACvD,MAAM,CAAC,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,MAAM,CAAC,CAAM;IAE3F,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,mBAAmB,CAAe;IAC1C,OAAO,CAAC,eAAe,CAAC,CAAY;IACpC,OAAO,CAAC,YAAY,CAAC,CAAmB;IACxC,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAa;gBAInB,IAAI,EAAE,4BAA4B;YAuChC,MAAM;IAiDd,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BpD,KAAK,IAAI,IAAI;IAYb,WAAW,IAAI,IAAI;IAUnB,OAAO,CAAC,sBAAsB;IAwB9B,MAAM,CAAC,2BAA2B,CAAC,EACjC,IAAI,EACJ,cAAc,EACd,OAAO,GACR,EAAE;QACD,IAAI,EAAE,IAAI,CAAC;QACX,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,MAAM,CAAC;KAC9C;CA0BF"}
@@ -0,0 +1,188 @@
1
+ import { Mutex } from "@livekit/mutex";
2
+ import {
3
+ RoomEvent
4
+ } from "@livekit/rtc-node";
5
+ import { log } from "../../log.js";
6
+ import {
7
+ Future,
8
+ Task,
9
+ shortuuid,
10
+ waitForParticipant,
11
+ waitForTrackPublication
12
+ } from "../../utils.js";
13
+ import { AudioOutput } from "../io.js";
14
+ const RPC_CLEAR_BUFFER = "lk.clear_buffer";
15
+ const RPC_PLAYBACK_FINISHED = "lk.playback_finished";
16
+ const AUDIO_STREAM_TOPIC = "lk.audio_stream";
17
+ class DataStreamAudioOutput extends AudioOutput {
18
+ static _playbackFinishedRpcRegistered = false;
19
+ static _playbackFinishedHandlers = {};
20
+ room;
21
+ destinationIdentity;
22
+ roomConnectedFuture;
23
+ waitRemoteTrack;
24
+ streamWriter;
25
+ pushedDuration = 0;
26
+ started = false;
27
+ lock = new Mutex();
28
+ startTask;
29
+ #logger = log();
30
+ constructor(opts) {
31
+ super(opts.sampleRate, void 0);
32
+ const { room, destinationIdentity, sampleRate, waitRemoteTrack } = opts;
33
+ this.room = room;
34
+ this.destinationIdentity = destinationIdentity;
35
+ this.sampleRate = sampleRate;
36
+ this.waitRemoteTrack = waitRemoteTrack;
37
+ const onRoomConnected = async () => {
38
+ if (this.startTask) return;
39
+ await this.roomConnectedFuture.await;
40
+ DataStreamAudioOutput.registerPlaybackFinishedRpc({
41
+ room,
42
+ callerIdentity: this.destinationIdentity,
43
+ handler: (data) => this.handlePlaybackFinished(data)
44
+ });
45
+ this.startTask = Task.from(({ signal }) => this._start(signal));
46
+ };
47
+ this.roomConnectedFuture = new Future();
48
+ this.room.on(RoomEvent.ConnectionStateChanged, (_) => {
49
+ if (room.isConnected && !this.roomConnectedFuture.done) {
50
+ this.roomConnectedFuture.resolve(void 0);
51
+ }
52
+ });
53
+ if (this.room.isConnected) {
54
+ this.roomConnectedFuture.resolve(void 0);
55
+ }
56
+ onRoomConnected();
57
+ }
58
+ async _start(_abortSignal) {
59
+ const unlock = await this.lock.lock();
60
+ try {
61
+ if (this.started) return;
62
+ await this.roomConnectedFuture.await;
63
+ this.#logger.debug(
64
+ {
65
+ identity: this.destinationIdentity
66
+ },
67
+ "waiting for the remote participant"
68
+ );
69
+ await waitForParticipant({
70
+ room: this.room,
71
+ identity: this.destinationIdentity
72
+ });
73
+ if (this.waitRemoteTrack) {
74
+ this.#logger.debug(
75
+ {
76
+ identity: this.destinationIdentity,
77
+ kind: this.waitRemoteTrack
78
+ },
79
+ "waiting for the remote track"
80
+ );
81
+ await waitForTrackPublication({
82
+ room: this.room,
83
+ identity: this.destinationIdentity,
84
+ kind: this.waitRemoteTrack
85
+ });
86
+ }
87
+ this.#logger.debug(
88
+ {
89
+ identity: this.destinationIdentity
90
+ },
91
+ "remote participant ready"
92
+ );
93
+ this.started = true;
94
+ } finally {
95
+ unlock();
96
+ }
97
+ }
98
+ async captureFrame(frame) {
99
+ if (!this.startTask) {
100
+ this.startTask = Task.from(({ signal }) => this._start(signal));
101
+ }
102
+ await this.startTask.result;
103
+ await super.captureFrame(frame);
104
+ if (!this.streamWriter) {
105
+ this.streamWriter = await this.room.localParticipant.streamBytes({
106
+ name: shortuuid("AUDIO_"),
107
+ topic: AUDIO_STREAM_TOPIC,
108
+ destinationIdentities: [this.destinationIdentity],
109
+ attributes: {
110
+ sample_rate: frame.sampleRate.toString(),
111
+ num_channels: frame.channels.toString()
112
+ }
113
+ });
114
+ this.pushedDuration = 0;
115
+ }
116
+ await this.streamWriter.write(new Uint8Array(frame.data.buffer));
117
+ this.pushedDuration += frame.samplesPerChannel / frame.sampleRate;
118
+ }
119
+ flush() {
120
+ super.flush();
121
+ if (this.streamWriter === void 0 || !this.started) {
122
+ return;
123
+ }
124
+ this.streamWriter.close().finally(() => {
125
+ this.streamWriter = void 0;
126
+ });
127
+ }
128
+ clearBuffer() {
129
+ if (!this.started) return;
130
+ this.room.localParticipant.performRpc({
131
+ destinationIdentity: this.destinationIdentity,
132
+ method: RPC_CLEAR_BUFFER,
133
+ payload: ""
134
+ });
135
+ }
136
+ handlePlaybackFinished(data) {
137
+ if (data.callerIdentity !== this.destinationIdentity) {
138
+ this.#logger.warn(
139
+ {
140
+ callerIdentity: data.callerIdentity,
141
+ destinationIdentity: this.destinationIdentity
142
+ },
143
+ "playback finished event received from unexpected participant"
144
+ );
145
+ return "reject";
146
+ }
147
+ this.#logger.info(
148
+ {
149
+ callerIdentity: data.callerIdentity
150
+ },
151
+ "playback finished event received"
152
+ );
153
+ const playbackFinishedEvent = JSON.parse(data.payload);
154
+ this.onPlaybackFinished(playbackFinishedEvent);
155
+ return "ok";
156
+ }
157
+ static registerPlaybackFinishedRpc({
158
+ room,
159
+ callerIdentity,
160
+ handler
161
+ }) {
162
+ var _a;
163
+ DataStreamAudioOutput._playbackFinishedHandlers[callerIdentity] = handler;
164
+ if (DataStreamAudioOutput._playbackFinishedRpcRegistered) {
165
+ return;
166
+ }
167
+ const rpcHandler = async (data) => {
168
+ const handler2 = DataStreamAudioOutput._playbackFinishedHandlers[data.callerIdentity];
169
+ if (!handler2) {
170
+ log().warn(
171
+ {
172
+ callerIdentity: data.callerIdentity,
173
+ expectedIdentities: Object.keys(DataStreamAudioOutput._playbackFinishedHandlers)
174
+ },
175
+ "playback finished event received from unexpected participant"
176
+ );
177
+ return "reject";
178
+ }
179
+ return handler2(data);
180
+ };
181
+ (_a = room.localParticipant) == null ? void 0 : _a.registerRpcMethod(RPC_PLAYBACK_FINISHED, rpcHandler);
182
+ DataStreamAudioOutput._playbackFinishedRpcRegistered = true;
183
+ }
184
+ }
185
+ export {
186
+ DataStreamAudioOutput
187
+ };
188
+ //# sourceMappingURL=datastream_io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/voice/avatar/datastream_io.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Mutex } from '@livekit/mutex';\nimport {\n type AudioFrame,\n type ByteStreamWriter,\n type Room,\n RoomEvent,\n type RpcInvocationData,\n type TrackKind,\n} from '@livekit/rtc-node';\nimport { log } from '../../log.js';\nimport {\n Future,\n Task,\n shortuuid,\n waitForParticipant,\n waitForTrackPublication,\n} from '../../utils.js';\nimport { AudioOutput, type PlaybackFinishedEvent } from '../io.js';\n\nconst RPC_CLEAR_BUFFER = 'lk.clear_buffer';\nconst RPC_PLAYBACK_FINISHED = 'lk.playback_finished';\nconst AUDIO_STREAM_TOPIC = 'lk.audio_stream';\n\nexport interface DataStreamAudioOutputOptions {\n room: Room;\n destinationIdentity: string;\n sampleRate?: number;\n waitRemoteTrack?: TrackKind;\n}\n\n/**\n * AudioOutput implementation that streams audio to a remote avatar worker using LiveKit DataStream.\n */\nexport class DataStreamAudioOutput extends AudioOutput {\n static _playbackFinishedRpcRegistered: boolean = false;\n static _playbackFinishedHandlers: Record<string, (data: RpcInvocationData) => string> = {};\n\n private room: Room;\n private destinationIdentity: string;\n private roomConnectedFuture: Future<void>;\n private waitRemoteTrack?: TrackKind;\n private streamWriter?: ByteStreamWriter;\n private pushedDuration: number = 0;\n private started: boolean = false;\n private lock = new Mutex();\n private startTask?: Task<void>;\n\n #logger = log();\n\n constructor(opts: DataStreamAudioOutputOptions) {\n super(opts.sampleRate, undefined);\n\n const { room, destinationIdentity, sampleRate, waitRemoteTrack } = opts;\n this.room = room;\n this.destinationIdentity = destinationIdentity;\n this.sampleRate = sampleRate;\n this.waitRemoteTrack = waitRemoteTrack;\n\n const onRoomConnected = async () => {\n if (this.startTask) return;\n\n await this.roomConnectedFuture.await;\n\n // register the rpc method right after the room is connected\n DataStreamAudioOutput.registerPlaybackFinishedRpc({\n room,\n callerIdentity: this.destinationIdentity,\n handler: (data) => this.handlePlaybackFinished(data),\n });\n\n this.startTask = Task.from(({ signal }) => this._start(signal));\n };\n\n this.roomConnectedFuture = new Future<void>();\n\n this.room.on(RoomEvent.ConnectionStateChanged, (_) => {\n if (room.isConnected && !this.roomConnectedFuture.done) {\n this.roomConnectedFuture.resolve(undefined);\n }\n });\n\n if (this.room.isConnected) {\n this.roomConnectedFuture.resolve(undefined);\n }\n\n onRoomConnected();\n }\n\n private async _start(_abortSignal: AbortSignal) {\n const unlock = await this.lock.lock();\n\n try {\n if (this.started) return;\n\n await this.roomConnectedFuture.await;\n\n this.#logger.debug(\n {\n identity: this.destinationIdentity,\n },\n 'waiting for the remote participant',\n );\n\n await waitForParticipant({\n room: this.room,\n identity: this.destinationIdentity,\n });\n\n if (this.waitRemoteTrack) {\n this.#logger.debug(\n {\n identity: this.destinationIdentity,\n kind: this.waitRemoteTrack,\n },\n 'waiting for the remote track',\n );\n\n await waitForTrackPublication({\n room: this.room,\n identity: this.destinationIdentity,\n kind: this.waitRemoteTrack,\n });\n }\n\n this.#logger.debug(\n {\n identity: this.destinationIdentity,\n },\n 'remote participant ready',\n );\n\n this.started = true;\n } finally {\n unlock();\n }\n }\n\n async captureFrame(frame: AudioFrame): Promise<void> {\n if (!this.startTask) {\n this.startTask = Task.from(({ signal }) => this._start(signal));\n }\n\n await this.startTask.result;\n await super.captureFrame(frame);\n\n if (!this.streamWriter) {\n this.streamWriter = await this.room.localParticipant!.streamBytes({\n name: shortuuid('AUDIO_'),\n topic: AUDIO_STREAM_TOPIC,\n destinationIdentities: [this.destinationIdentity],\n attributes: {\n sample_rate: frame.sampleRate.toString(),\n num_channels: frame.channels.toString(),\n },\n });\n this.pushedDuration = 0;\n }\n\n // frame.data is a Int16Array, write accepts a Uint8Array\n await this.streamWriter.write(new Uint8Array(frame.data.buffer));\n this.pushedDuration += frame.samplesPerChannel / frame.sampleRate;\n }\n\n flush(): void {\n super.flush();\n\n if (this.streamWriter === undefined || !this.started) {\n return;\n }\n\n this.streamWriter.close().finally(() => {\n this.streamWriter = undefined;\n });\n }\n\n clearBuffer(): void {\n if (!this.started) return;\n\n this.room.localParticipant!.performRpc({\n destinationIdentity: this.destinationIdentity,\n method: RPC_CLEAR_BUFFER,\n payload: '',\n });\n }\n\n private handlePlaybackFinished(data: RpcInvocationData): string {\n if (data.callerIdentity !== this.destinationIdentity) {\n this.#logger.warn(\n {\n callerIdentity: data.callerIdentity,\n destinationIdentity: this.destinationIdentity,\n },\n 'playback finished event received from unexpected participant',\n );\n return 'reject';\n }\n\n this.#logger.info(\n {\n callerIdentity: data.callerIdentity,\n },\n 'playback finished event received',\n );\n\n const playbackFinishedEvent = JSON.parse(data.payload) as PlaybackFinishedEvent;\n this.onPlaybackFinished(playbackFinishedEvent);\n return 'ok';\n }\n\n static registerPlaybackFinishedRpc({\n room,\n callerIdentity,\n handler,\n }: {\n room: Room;\n callerIdentity: string;\n handler: (data: RpcInvocationData) => string;\n }) {\n DataStreamAudioOutput._playbackFinishedHandlers[callerIdentity] = handler;\n\n if (DataStreamAudioOutput._playbackFinishedRpcRegistered) {\n return;\n }\n\n const rpcHandler = async (data: RpcInvocationData): Promise<string> => {\n const handler = DataStreamAudioOutput._playbackFinishedHandlers[data.callerIdentity];\n if (!handler) {\n log().warn(\n {\n callerIdentity: data.callerIdentity,\n expectedIdentities: Object.keys(DataStreamAudioOutput._playbackFinishedHandlers),\n },\n 'playback finished event received from unexpected participant',\n );\n\n return 'reject';\n }\n return handler(data);\n };\n\n room.localParticipant?.registerRpcMethod(RPC_PLAYBACK_FINISHED, rpcHandler);\n DataStreamAudioOutput._playbackFinishedRpcRegistered = true;\n }\n}\n"],"mappings":"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","names":["handler"]}
@@ -13,11 +13,11 @@ var __copyProps = (to, from, except, desc) => {
13
13
  };
14
14
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
15
15
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
- var multimodal_exports = {};
17
- module.exports = __toCommonJS(multimodal_exports);
18
- __reExport(multimodal_exports, require("./agent_playout.cjs"), module.exports);
16
+ var avatar_exports = {};
17
+ module.exports = __toCommonJS(avatar_exports);
18
+ __reExport(avatar_exports, require("./datastream_io.cjs"), module.exports);
19
19
  // Annotate the CommonJS export names for ESM import in node:
20
20
  0 && (module.exports = {
21
- ...require("./agent_playout.cjs")
21
+ ...require("./datastream_io.cjs")
22
22
  });
23
23
  //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/voice/avatar/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport * from './datastream_io.js';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAGA,2BAAc,+BAHd;","names":[]}
@@ -0,0 +1,2 @@
1
+ export * from './datastream_io.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export * from './datastream_io.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/voice/avatar/index.ts"],"names":[],"mappings":"AAGA,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./datastream_io.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/voice/avatar/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport * from './datastream_io.js';\n"],"mappings":"AAGA,cAAc;","names":[]}
@@ -27,6 +27,7 @@ __export(voice_exports, {
27
27
  module.exports = __toCommonJS(voice_exports);
28
28
  var import_agent = require("./agent.cjs");
29
29
  var import_agent_session = require("./agent_session.cjs");
30
+ __reExport(voice_exports, require("./avatar/index.cjs"), module.exports);
30
31
  __reExport(voice_exports, require("./events.cjs"), module.exports);
31
32
  var import_run_context = require("./run_context.cjs");
32
33
  // Annotate the CommonJS export names for ESM import in node:
@@ -35,6 +36,7 @@ var import_run_context = require("./run_context.cjs");
35
36
  AgentSession,
36
37
  RunContext,
37
38
  StopResponse,
39
+ ...require("./avatar/index.cjs"),
38
40
  ...require("./events.cjs")
39
41
  });
40
42
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/voice/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport { Agent, StopResponse, type AgentOptions, type ModelSettings } from './agent.js';\nexport { AgentSession, type AgentSessionOptions } from './agent_session.js';\nexport * from './events.js';\nexport { RunContext } from './run_context.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAA2E;AAC3E,2BAAuD;AACvD,0BAAc,wBALd;AAMA,yBAA2B;","names":[]}
1
+ {"version":3,"sources":["../../src/voice/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport { Agent, StopResponse, type AgentOptions, type ModelSettings } from './agent.js';\nexport { AgentSession, type AgentSessionOptions } from './agent_session.js';\n\nexport * from './avatar/index.js';\nexport * from './events.js';\nexport { RunContext } from './run_context.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAA2E;AAC3E,2BAAuD;AAEvD,0BAAc,8BANd;AAOA,0BAAc,wBAPd;AAQA,yBAA2B;","names":[]}
@@ -1,5 +1,6 @@
1
1
  export { Agent, StopResponse, type AgentOptions, type ModelSettings } from './agent.js';
2
2
  export { AgentSession, type AgentSessionOptions } from './agent_session.js';
3
+ export * from './avatar/index.js';
3
4
  export * from './events.js';
4
5
  export { RunContext } from './run_context.js';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,6 @@
1
1
  export { Agent, StopResponse, type AgentOptions, type ModelSettings } from './agent.js';
2
2
  export { AgentSession, type AgentSessionOptions } from './agent_session.js';
3
+ export * from './avatar/index.js';
3
4
  export * from './events.js';
4
5
  export { RunContext } from './run_context.js';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/voice/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/voice/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE5E,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { Agent, StopResponse } from "./agent.js";
2
2
  import { AgentSession } from "./agent_session.js";
3
+ export * from "./avatar/index.js";
3
4
  export * from "./events.js";
4
5
  import { RunContext } from "./run_context.js";
5
6
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/voice/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport { Agent, StopResponse, type AgentOptions, type ModelSettings } from './agent.js';\nexport { AgentSession, type AgentSessionOptions } from './agent_session.js';\nexport * from './events.js';\nexport { RunContext } from './run_context.js';\n"],"mappings":"AAGA,SAAS,OAAO,oBAA2D;AAC3E,SAAS,oBAA8C;AACvD,cAAc;AACd,SAAS,kBAAkB;","names":[]}
1
+ {"version":3,"sources":["../../src/voice/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport { Agent, StopResponse, type AgentOptions, type ModelSettings } from './agent.js';\nexport { AgentSession, type AgentSessionOptions } from './agent_session.js';\n\nexport * from './avatar/index.js';\nexport * from './events.js';\nexport { RunContext } from './run_context.js';\n"],"mappings":"AAGA,SAAS,OAAO,oBAA2D;AAC3E,SAAS,oBAA8C;AAEvD,cAAc;AACd,cAAc;AACd,SAAS,kBAAkB;","names":[]}