@livekit/agents-plugin-deepgram 0.0.0-next-20260624041820

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 (75) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +17 -0
  3. package/dist/_utils.cjs +56 -0
  4. package/dist/_utils.cjs.map +1 -0
  5. package/dist/_utils.d.cts +12 -0
  6. package/dist/_utils.d.ts +12 -0
  7. package/dist/_utils.d.ts.map +1 -0
  8. package/dist/_utils.js +32 -0
  9. package/dist/_utils.js.map +1 -0
  10. package/dist/index.cjs +38 -0
  11. package/dist/index.cjs.map +1 -0
  12. package/dist/index.d.cts +4 -0
  13. package/dist/index.d.ts +4 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +15 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/models.cjs +17 -0
  18. package/dist/models.cjs.map +1 -0
  19. package/dist/models.d.cts +6 -0
  20. package/dist/models.d.ts +6 -0
  21. package/dist/models.d.ts.map +1 -0
  22. package/dist/models.js +1 -0
  23. package/dist/models.js.map +1 -0
  24. package/dist/stt.cjs +496 -0
  25. package/dist/stt.cjs.map +1 -0
  26. package/dist/stt.d.cts +53 -0
  27. package/dist/stt.d.ts +53 -0
  28. package/dist/stt.d.ts.map +1 -0
  29. package/dist/stt.js +483 -0
  30. package/dist/stt.js.map +1 -0
  31. package/dist/stt.test.cjs +28 -0
  32. package/dist/stt.test.cjs.map +1 -0
  33. package/dist/stt.test.d.cts +2 -0
  34. package/dist/stt.test.d.ts +2 -0
  35. package/dist/stt.test.d.ts.map +1 -0
  36. package/dist/stt.test.js +27 -0
  37. package/dist/stt.test.js.map +1 -0
  38. package/dist/stt_v2.cjs +413 -0
  39. package/dist/stt_v2.cjs.map +1 -0
  40. package/dist/stt_v2.d.cts +97 -0
  41. package/dist/stt_v2.d.ts +97 -0
  42. package/dist/stt_v2.d.ts.map +1 -0
  43. package/dist/stt_v2.js +387 -0
  44. package/dist/stt_v2.js.map +1 -0
  45. package/dist/stt_v2.test.cjs +17 -0
  46. package/dist/stt_v2.test.cjs.map +1 -0
  47. package/dist/stt_v2.test.d.cts +2 -0
  48. package/dist/stt_v2.test.d.ts +2 -0
  49. package/dist/stt_v2.test.d.ts.map +1 -0
  50. package/dist/stt_v2.test.js +16 -0
  51. package/dist/stt_v2.test.js.map +1 -0
  52. package/dist/tts.cjs +385 -0
  53. package/dist/tts.cjs.map +1 -0
  54. package/dist/tts.d.cts +43 -0
  55. package/dist/tts.d.ts +43 -0
  56. package/dist/tts.d.ts.map +1 -0
  57. package/dist/tts.js +369 -0
  58. package/dist/tts.js.map +1 -0
  59. package/dist/tts.test.cjs +17 -0
  60. package/dist/tts.test.cjs.map +1 -0
  61. package/dist/tts.test.d.cts +2 -0
  62. package/dist/tts.test.d.ts +2 -0
  63. package/dist/tts.test.d.ts.map +1 -0
  64. package/dist/tts.test.js +16 -0
  65. package/dist/tts.test.js.map +1 -0
  66. package/package.json +54 -0
  67. package/src/_utils.ts +50 -0
  68. package/src/index.ts +20 -0
  69. package/src/models.ts +93 -0
  70. package/src/stt.test.ts +36 -0
  71. package/src/stt.ts +612 -0
  72. package/src/stt_v2.test.ts +19 -0
  73. package/src/stt_v2.ts +560 -0
  74. package/src/tts.test.ts +19 -0
  75. package/src/tts.ts +450 -0
package/dist/stt.cjs ADDED
@@ -0,0 +1,496 @@
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 stt_exports = {};
20
+ __export(stt_exports, {
21
+ STT: () => STT,
22
+ SpeechStream: () => SpeechStream
23
+ });
24
+ module.exports = __toCommonJS(stt_exports);
25
+ var import_agents = require("@livekit/agents");
26
+ var import_ws = require("ws");
27
+ var import_utils = require("./_utils.cjs");
28
+ const defaultSTTOptions = {
29
+ apiKey: process.env.DEEPGRAM_API_KEY,
30
+ language: "en-US",
31
+ detectLanguage: false,
32
+ interimResults: true,
33
+ punctuate: true,
34
+ model: "nova-3",
35
+ smartFormat: true,
36
+ noDelay: true,
37
+ endpointing: 25,
38
+ fillerWords: false,
39
+ sampleRate: 16e3,
40
+ numChannels: 1,
41
+ keywords: [],
42
+ keyterm: [],
43
+ profanityFilter: false,
44
+ redact: [],
45
+ dictation: false,
46
+ diarize: false,
47
+ numerals: false,
48
+ mipOptOut: false,
49
+ baseUrl: "wss://api.deepgram.com"
50
+ };
51
+ class STT extends import_agents.stt.STT {
52
+ #opts;
53
+ #logger = (0, import_agents.log)();
54
+ label = "deepgram.STT";
55
+ abortController = new AbortController();
56
+ get model() {
57
+ return this.#opts.model;
58
+ }
59
+ get provider() {
60
+ return "Deepgram";
61
+ }
62
+ constructor(opts = defaultSTTOptions) {
63
+ super({
64
+ streaming: true,
65
+ interimResults: opts.interimResults ?? defaultSTTOptions.interimResults,
66
+ alignedTranscript: "word"
67
+ });
68
+ if (opts.apiKey === void 0 && defaultSTTOptions.apiKey === void 0) {
69
+ throw new Error(
70
+ "Deepgram API key is required, whether as an argument or as $DEEPGRAM_API_KEY"
71
+ );
72
+ }
73
+ this.#opts = {
74
+ ...defaultSTTOptions,
75
+ ...opts,
76
+ language: opts.language ? (0, import_agents.normalizeLanguage)(opts.language) : defaultSTTOptions.language
77
+ };
78
+ if (this.#opts.detectLanguage) {
79
+ this.#opts.language = void 0;
80
+ } else {
81
+ this.#opts.model = this.#validateModel(this.#opts.model, this.#opts.language);
82
+ }
83
+ }
84
+ async _recognize(buffer, abortSignal) {
85
+ const frame = (0, import_agents.mergeFrames)(buffer);
86
+ const listenURL = new URL(`${this.#opts.baseUrl.replace(/^ws/, "http")}/v1/listen`);
87
+ const params = {
88
+ model: this.#opts.model,
89
+ punctuate: this.#opts.punctuate,
90
+ detect_language: this.#opts.detectLanguage,
91
+ smart_format: this.#opts.smartFormat,
92
+ keywords: this.#opts.keywords.map((x) => x.join(":")),
93
+ profanity_filter: this.#opts.profanityFilter,
94
+ numerals: this.#opts.numerals,
95
+ mip_opt_out: this.#opts.mipOptOut,
96
+ language: this.#opts.language,
97
+ ...this.#opts.keyterm.length > 0 ? { keyterm: this.#opts.keyterm } : {},
98
+ ...this.#opts.redact.length > 0 ? { redact: this.#opts.redact } : {}
99
+ };
100
+ Object.entries(params).forEach(([k, v]) => {
101
+ if (v !== void 0) {
102
+ if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
103
+ listenURL.searchParams.append(k, String(v));
104
+ } else {
105
+ v.forEach((x) => listenURL.searchParams.append(k, String(x)));
106
+ }
107
+ }
108
+ });
109
+ if (this.#opts.diarize) {
110
+ this.#logger.warn("speaker diarization is not supported in non-streaming mode, ignoring");
111
+ }
112
+ const resp = await fetch(listenURL, {
113
+ method: "POST",
114
+ headers: {
115
+ Authorization: `Token ${this.#opts.apiKey}`,
116
+ Accept: "application/json",
117
+ "Content-Type": "audio/wav"
118
+ },
119
+ body: new Blob([new Uint8Array(createWav(frame))], { type: "audio/wav" }),
120
+ signal: abortSignal ?? null
121
+ });
122
+ if (!resp.ok) {
123
+ throw new Error(
124
+ `Deepgram STT REST request failed with status ${resp.status}: ${await resp.text()}`
125
+ );
126
+ }
127
+ return prerecordedTranscriptionToSpeechEvent(this.#opts.language, await resp.json());
128
+ }
129
+ updateOptions(opts) {
130
+ const language = opts.language !== void 0 ? (0, import_agents.normalizeLanguage)(opts.language) : this.#opts.language;
131
+ const model = opts.model !== void 0 || opts.language !== void 0 ? this.#validateModel(opts.model ?? this.#opts.model, language) : this.#opts.model;
132
+ this.#opts = {
133
+ ...this.#opts,
134
+ ...opts,
135
+ language,
136
+ model
137
+ };
138
+ }
139
+ #validateModel(model, language) {
140
+ if (language && (0, import_agents.getBaseLanguage)(language) !== "en" && [
141
+ "nova-2-meeting",
142
+ "nova-2-phonecall",
143
+ "nova-2-finance",
144
+ "nova-2-conversationalai",
145
+ "nova-2-voicemail",
146
+ "nova-2-video",
147
+ "nova-2-medical",
148
+ "nova-2-drivethru",
149
+ "nova-2-automotive",
150
+ "nova-3-general"
151
+ ].includes(model)) {
152
+ this.#logger.warn(
153
+ `${model} does not support language ${language}, falling back to nova-2-general`
154
+ );
155
+ return "nova-2-general";
156
+ }
157
+ return model;
158
+ }
159
+ stream(options) {
160
+ if (this.#opts.detectLanguage || this.#opts.language === void 0) {
161
+ throw new Error(
162
+ "language detection is not supported in streaming mode, please disable it and specify a language"
163
+ );
164
+ }
165
+ return new SpeechStream(this, this.#opts, options == null ? void 0 : options.connOptions);
166
+ }
167
+ async close() {
168
+ this.abortController.abort();
169
+ }
170
+ }
171
+ class SpeechStream extends import_agents.stt.SpeechStream {
172
+ #opts;
173
+ #audioEnergyFilter;
174
+ #logger = (0, import_agents.log)();
175
+ #speaking = false;
176
+ #resetWS = new import_agents.Future();
177
+ #requestId = "";
178
+ #audioDurationCollector;
179
+ label = "deepgram.SpeechStream";
180
+ constructor(stt2, opts, connOptions) {
181
+ super(stt2, opts.sampleRate, connOptions);
182
+ this.#opts = opts;
183
+ this.closed = false;
184
+ this.#audioEnergyFilter = new import_agents.AudioEnergyFilter();
185
+ this.#audioDurationCollector = new import_utils.PeriodicCollector(
186
+ (duration) => this.onAudioDurationReport(duration),
187
+ { duration: 5 }
188
+ );
189
+ }
190
+ async run() {
191
+ const maxRetry = 32;
192
+ let retries = 0;
193
+ let ws;
194
+ while (!this.input.closed && !this.closed) {
195
+ const streamURL = new URL(`${this.#opts.baseUrl}/v1/listen`);
196
+ const params = {
197
+ model: this.#opts.model,
198
+ punctuate: this.#opts.punctuate,
199
+ smart_format: this.#opts.smartFormat,
200
+ dictation: this.#opts.dictation,
201
+ diarize: this.#opts.diarize,
202
+ numerals: this.#opts.numerals,
203
+ no_delay: this.#opts.noDelay,
204
+ interim_results: this.#opts.interimResults,
205
+ encoding: "linear16",
206
+ vad_events: true,
207
+ sample_rate: this.#opts.sampleRate,
208
+ channels: this.#opts.numChannels,
209
+ endpointing: this.#opts.endpointing || false,
210
+ filler_words: this.#opts.fillerWords,
211
+ keywords: this.#opts.keywords.map((x) => x.join(":")),
212
+ keyterm: this.#opts.keyterm,
213
+ profanity_filter: this.#opts.profanityFilter,
214
+ redact: this.#opts.redact,
215
+ language: this.#opts.language,
216
+ mip_opt_out: this.#opts.mipOptOut
217
+ };
218
+ Object.entries(params).forEach(([k, v]) => {
219
+ if (v !== void 0) {
220
+ if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
221
+ streamURL.searchParams.append(k, String(v));
222
+ } else {
223
+ v.forEach((x) => streamURL.searchParams.append(k, String(x)));
224
+ }
225
+ }
226
+ });
227
+ ws = new import_ws.WebSocket(streamURL, {
228
+ headers: { Authorization: `Token ${this.#opts.apiKey}` }
229
+ });
230
+ try {
231
+ await new Promise((resolve, reject) => {
232
+ ws.on("open", resolve);
233
+ ws.on("error", (error) => reject(error));
234
+ ws.on("close", (code) => reject(`WebSocket returned ${code}`));
235
+ });
236
+ await this.#runWS(ws);
237
+ } catch (e) {
238
+ if (!this.closed && !this.input.closed) {
239
+ if (retries >= maxRetry) {
240
+ throw new Error(`failed to connect to Deepgram after ${retries} attempts: ${e}`);
241
+ }
242
+ const delay = Math.min(retries * 5, 10);
243
+ retries++;
244
+ this.#logger.warn(
245
+ `failed to connect to Deepgram, retrying in ${delay} seconds: ${e} (${retries}/${maxRetry})`
246
+ );
247
+ await new Promise((resolve) => setTimeout(resolve, delay * 1e3));
248
+ } else {
249
+ this.#logger.warn(
250
+ `Deepgram disconnected, connection is closed: ${e} (inputClosed: ${this.input.closed}, isClosed: ${this.closed})`
251
+ );
252
+ }
253
+ }
254
+ }
255
+ this.closed = true;
256
+ }
257
+ updateOptions(opts) {
258
+ this.#opts = { ...this.#opts, ...opts };
259
+ this.#resetWS.resolve();
260
+ }
261
+ async #runWS(ws) {
262
+ this.#resetWS = new import_agents.Future();
263
+ let closing = false;
264
+ const keepalive = setInterval(() => {
265
+ try {
266
+ ws.send(JSON.stringify({ type: "KeepAlive" }));
267
+ } catch {
268
+ clearInterval(keepalive);
269
+ return;
270
+ }
271
+ }, 5e3);
272
+ const wsMonitor = import_agents.Task.from(async (controller) => {
273
+ const closed = new Promise(async (_, reject) => {
274
+ ws.once("close", (code, reason) => {
275
+ if (!closing) {
276
+ this.#logger.error(`WebSocket closed with code ${code}: ${reason}`);
277
+ reject(new Error("WebSocket closed"));
278
+ }
279
+ });
280
+ });
281
+ await Promise.race([closed, (0, import_agents.waitForAbort)(controller.signal)]);
282
+ });
283
+ const sendTask = async () => {
284
+ const samples100Ms = Math.floor(this.#opts.sampleRate / 10);
285
+ const stream = new import_agents.AudioByteStream(
286
+ this.#opts.sampleRate,
287
+ this.#opts.numChannels,
288
+ samples100Ms
289
+ );
290
+ const abortPromise = (0, import_agents.waitForAbort)(this.abortSignal);
291
+ try {
292
+ while (!this.closed) {
293
+ const result = await Promise.race([this.input.next(), abortPromise]);
294
+ if (result === void 0) return;
295
+ if (result.done) {
296
+ break;
297
+ }
298
+ const data = result.value;
299
+ let frames;
300
+ if (data === SpeechStream.FLUSH_SENTINEL) {
301
+ frames = stream.flush();
302
+ this.#audioDurationCollector.flush();
303
+ } else if (data.sampleRate === this.#opts.sampleRate && data.channels === this.#opts.numChannels) {
304
+ frames = stream.write(data.data.buffer);
305
+ } else {
306
+ throw new Error(`sample rate or channel count of frame does not match`);
307
+ }
308
+ for await (const frame of frames) {
309
+ if (this.#audioEnergyFilter.pushFrame(frame)) {
310
+ const frameDuration = frame.samplesPerChannel / frame.sampleRate;
311
+ this.#audioDurationCollector.push(frameDuration);
312
+ ws.send(frame.data.buffer);
313
+ }
314
+ }
315
+ }
316
+ } finally {
317
+ closing = true;
318
+ ws.send(JSON.stringify({ type: "CloseStream" }));
319
+ wsMonitor.cancel();
320
+ }
321
+ };
322
+ const listenTask = import_agents.Task.from(async (controller) => {
323
+ const putMessage = (message) => {
324
+ if (!this.queue.closed) {
325
+ try {
326
+ this.queue.put(message);
327
+ } catch (e) {
328
+ }
329
+ }
330
+ };
331
+ const listenMessage = new Promise((resolve, reject) => {
332
+ ws.on("message", (msg) => {
333
+ try {
334
+ const json = JSON.parse(msg.toString());
335
+ switch (json["type"]) {
336
+ case "SpeechStarted": {
337
+ if (this.#speaking) return;
338
+ this.#speaking = true;
339
+ putMessage({ type: import_agents.stt.SpeechEventType.START_OF_SPEECH });
340
+ break;
341
+ }
342
+ // see this page:
343
+ // https://developers.deepgram.com/docs/understand-endpointing-interim-results#using-endpointing-speech_final
344
+ // for more information about the different types of events
345
+ case "Results": {
346
+ const metadata = json["metadata"];
347
+ const requestId = metadata["request_id"];
348
+ const isFinal = json["is_final"];
349
+ const isEndpoint = json["speech_final"];
350
+ this.#requestId = requestId;
351
+ const alternatives = liveTranscriptionToSpeechData(
352
+ this.#opts.language,
353
+ json,
354
+ this.startTimeOffset
355
+ );
356
+ if (alternatives[0] && alternatives[0].text) {
357
+ if (!this.#speaking) {
358
+ this.#speaking = true;
359
+ putMessage({
360
+ type: import_agents.stt.SpeechEventType.START_OF_SPEECH
361
+ });
362
+ }
363
+ if (isFinal) {
364
+ putMessage({
365
+ type: import_agents.stt.SpeechEventType.FINAL_TRANSCRIPT,
366
+ alternatives: [alternatives[0], ...alternatives.slice(1)]
367
+ });
368
+ } else {
369
+ putMessage({
370
+ type: import_agents.stt.SpeechEventType.INTERIM_TRANSCRIPT,
371
+ alternatives: [alternatives[0], ...alternatives.slice(1)]
372
+ });
373
+ }
374
+ }
375
+ if (isEndpoint && this.#speaking) {
376
+ this.#speaking = false;
377
+ putMessage({ type: import_agents.stt.SpeechEventType.END_OF_SPEECH });
378
+ }
379
+ break;
380
+ }
381
+ case "Metadata": {
382
+ break;
383
+ }
384
+ default: {
385
+ this.#logger.child({ msg: json }).warn("received unexpected message from Deepgram");
386
+ break;
387
+ }
388
+ }
389
+ if (this.closed || closing) {
390
+ resolve();
391
+ }
392
+ } catch (err) {
393
+ this.#logger.error(`STT: Error processing message: ${msg}`);
394
+ reject(err);
395
+ }
396
+ });
397
+ });
398
+ await Promise.race([listenMessage, (0, import_agents.waitForAbort)(controller.signal)]);
399
+ }, this.abortController);
400
+ await Promise.race([
401
+ this.#resetWS.await,
402
+ Promise.all([sendTask(), listenTask.result, wsMonitor])
403
+ ]);
404
+ closing = true;
405
+ ws.close();
406
+ clearInterval(keepalive);
407
+ }
408
+ onAudioDurationReport(duration) {
409
+ const usageEvent = {
410
+ type: import_agents.stt.SpeechEventType.RECOGNITION_USAGE,
411
+ requestId: this.#requestId,
412
+ recognitionUsage: {
413
+ audioDuration: duration
414
+ }
415
+ };
416
+ this.queue.put(usageEvent);
417
+ }
418
+ }
419
+ function createWav(frame) {
420
+ const bitsPerSample = 16;
421
+ const byteRate = frame.sampleRate * frame.channels * bitsPerSample / 8;
422
+ const blockAlign = frame.channels * bitsPerSample / 8;
423
+ const header = Buffer.alloc(44);
424
+ header.write("RIFF", 0);
425
+ header.writeUInt32LE(36 + frame.data.byteLength, 4);
426
+ header.write("WAVE", 8);
427
+ header.write("fmt ", 12);
428
+ header.writeUInt32LE(16, 16);
429
+ header.writeUInt16LE(1, 20);
430
+ header.writeUInt16LE(frame.channels, 22);
431
+ header.writeUInt32LE(frame.sampleRate, 24);
432
+ header.writeUInt32LE(byteRate, 28);
433
+ header.writeUInt16LE(blockAlign, 32);
434
+ header.writeUInt16LE(bitsPerSample, 34);
435
+ header.write("data", 36);
436
+ header.writeUInt32LE(frame.data.byteLength, 40);
437
+ const pcm = Buffer.from(frame.data.buffer, frame.data.byteOffset, frame.data.byteLength);
438
+ return Buffer.concat([header, pcm]);
439
+ }
440
+ const liveTranscriptionToSpeechData = (language, data, startTimeOffset = 0) => {
441
+ const alts = data["channel"]["alternatives"];
442
+ return alts.map((alt) => {
443
+ var _a;
444
+ const wordsData = alt["words"] ?? [];
445
+ const detectedLanguage = language === "multi" ? ((_a = alt["languages"]) == null ? void 0 : _a[0]) ?? language : alt["language"] ?? language;
446
+ return {
447
+ language: (0, import_agents.normalizeLanguage)(detectedLanguage),
448
+ startTime: wordsData.length ? wordsData[0]["start"] + startTimeOffset : startTimeOffset,
449
+ endTime: wordsData.length ? wordsData[wordsData.length - 1]["end"] + startTimeOffset : startTimeOffset,
450
+ confidence: alt["confidence"],
451
+ text: alt["transcript"],
452
+ words: wordsData.map(
453
+ (word) => (0, import_agents.createTimedString)({
454
+ text: word["word"] ?? "",
455
+ startTime: (word["start"] ?? 0) + startTimeOffset,
456
+ endTime: (word["end"] ?? 0) + startTimeOffset,
457
+ confidence: word["confidence"] ?? 0,
458
+ startTimeOffset
459
+ })
460
+ )
461
+ };
462
+ });
463
+ };
464
+ function prerecordedTranscriptionToSpeechEvent(language, data) {
465
+ const channel = data["results"]["channels"][0];
466
+ const detectedLanguage = channel["detected_language"] ?? "";
467
+ const alternatives = channel["alternatives"].map((alt) => {
468
+ const wordsData = alt["words"] ?? [];
469
+ return {
470
+ language: (0, import_agents.normalizeLanguage)(language ?? detectedLanguage),
471
+ startTime: wordsData.length ? wordsData[0]["start"] : 0,
472
+ endTime: wordsData.length ? wordsData[wordsData.length - 1]["end"] : 0,
473
+ confidence: alt["confidence"],
474
+ text: alt["transcript"],
475
+ words: wordsData.map(
476
+ (word) => (0, import_agents.createTimedString)({
477
+ text: word["word"] ?? "",
478
+ startTime: word["start"] ?? 0,
479
+ endTime: word["end"] ?? 0,
480
+ confidence: word["confidence"] ?? 0
481
+ })
482
+ )
483
+ };
484
+ });
485
+ return {
486
+ type: import_agents.stt.SpeechEventType.FINAL_TRANSCRIPT,
487
+ requestId: data["metadata"]["request_id"],
488
+ ...alternatives.length ? { alternatives } : {}
489
+ };
490
+ }
491
+ // Annotate the CommonJS export names for ESM import in node:
492
+ 0 && (module.exports = {
493
+ STT,
494
+ SpeechStream
495
+ });
496
+ //# sourceMappingURL=stt.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/stt.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport {\n type APIConnectOptions,\n type AudioBuffer,\n AudioByteStream,\n AudioEnergyFilter,\n Future,\n Task,\n createTimedString,\n getBaseLanguage,\n log,\n mergeFrames,\n normalizeLanguage,\n stt,\n waitForAbort,\n} from '@livekit/agents';\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport { WebSocket } from 'ws';\nimport { PeriodicCollector } from './_utils.js';\nimport type { STTLanguages, STTModels } from './models.js';\n\nexport interface STTOptions {\n apiKey?: string;\n language?: STTLanguages | string;\n detectLanguage: boolean;\n interimResults: boolean;\n punctuate: boolean;\n model: STTModels;\n smartFormat: boolean;\n noDelay: boolean;\n endpointing: number;\n fillerWords: boolean;\n sampleRate: number;\n numChannels: number;\n keywords: [string, number][];\n keyterm: string[];\n profanityFilter: boolean;\n /**\n * Redact sensitive information from the transcription. Accepts a single value or list of\n * values. Supported values: \"pci\", \"numbers\", \"ssn\", \"true\" (redact all).\n * See https://developers.deepgram.com/docs/redaction for details.\n */\n redact: string | string[];\n dictation: boolean;\n diarize: boolean;\n numerals: boolean;\n mipOptOut: boolean;\n baseUrl: string;\n}\n\nconst defaultSTTOptions: STTOptions = {\n apiKey: process.env.DEEPGRAM_API_KEY,\n language: 'en-US',\n detectLanguage: false,\n interimResults: true,\n punctuate: true,\n model: 'nova-3',\n smartFormat: true,\n noDelay: true,\n endpointing: 25,\n fillerWords: false,\n sampleRate: 16000,\n numChannels: 1,\n keywords: [],\n keyterm: [],\n profanityFilter: false,\n redact: [],\n dictation: false,\n diarize: false,\n numerals: false,\n mipOptOut: false,\n baseUrl: 'wss://api.deepgram.com',\n};\n\nexport class STT extends stt.STT {\n #opts: STTOptions;\n #logger = log();\n label = 'deepgram.STT';\n private abortController = new AbortController();\n\n get model(): string {\n return this.#opts.model;\n }\n\n get provider(): string {\n return 'Deepgram';\n }\n\n constructor(opts: Partial<STTOptions> = defaultSTTOptions) {\n super({\n streaming: true,\n interimResults: opts.interimResults ?? defaultSTTOptions.interimResults,\n alignedTranscript: 'word',\n });\n if (opts.apiKey === undefined && defaultSTTOptions.apiKey === undefined) {\n throw new Error(\n 'Deepgram API key is required, whether as an argument or as $DEEPGRAM_API_KEY',\n );\n }\n\n this.#opts = {\n ...defaultSTTOptions,\n ...opts,\n language: opts.language ? normalizeLanguage(opts.language) : defaultSTTOptions.language,\n };\n\n if (this.#opts.detectLanguage) {\n this.#opts.language = undefined;\n } else {\n this.#opts.model = this.#validateModel(this.#opts.model, this.#opts.language);\n }\n }\n\n async _recognize(buffer: AudioBuffer, abortSignal?: AbortSignal): Promise<stt.SpeechEvent> {\n const frame = mergeFrames(buffer);\n const listenURL = new URL(`${this.#opts.baseUrl.replace(/^ws/, 'http')}/v1/listen`);\n const params = {\n model: this.#opts.model,\n punctuate: this.#opts.punctuate,\n detect_language: this.#opts.detectLanguage,\n smart_format: this.#opts.smartFormat,\n keywords: this.#opts.keywords.map((x) => x.join(':')),\n profanity_filter: this.#opts.profanityFilter,\n numerals: this.#opts.numerals,\n mip_opt_out: this.#opts.mipOptOut,\n language: this.#opts.language,\n ...(this.#opts.keyterm.length > 0 ? { keyterm: this.#opts.keyterm } : {}),\n ...(this.#opts.redact.length > 0 ? { redact: this.#opts.redact } : {}),\n };\n\n Object.entries(params).forEach(([k, v]) => {\n if (v !== undefined) {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n listenURL.searchParams.append(k, String(v));\n } else {\n v.forEach((x) => listenURL.searchParams.append(k, String(x)));\n }\n }\n });\n\n if (this.#opts.diarize) {\n this.#logger.warn('speaker diarization is not supported in non-streaming mode, ignoring');\n }\n\n const resp = await fetch(listenURL, {\n method: 'POST',\n headers: {\n Authorization: `Token ${this.#opts.apiKey}`,\n Accept: 'application/json',\n 'Content-Type': 'audio/wav',\n },\n body: new Blob([new Uint8Array(createWav(frame))], { type: 'audio/wav' }),\n signal: abortSignal ?? null,\n });\n\n if (!resp.ok) {\n throw new Error(\n `Deepgram STT REST request failed with status ${resp.status}: ${await resp.text()}`,\n );\n }\n\n return prerecordedTranscriptionToSpeechEvent(this.#opts.language, await resp.json());\n }\n\n updateOptions(opts: Partial<STTOptions>) {\n const language =\n opts.language !== undefined ? normalizeLanguage(opts.language) : this.#opts.language;\n const model =\n opts.model !== undefined || opts.language !== undefined\n ? this.#validateModel(opts.model ?? this.#opts.model, language)\n : this.#opts.model;\n\n this.#opts = {\n ...this.#opts,\n ...opts,\n language,\n model,\n };\n }\n\n #validateModel(model: STTModels, language?: string) {\n if (\n language &&\n getBaseLanguage(language) !== 'en' &&\n [\n 'nova-2-meeting',\n 'nova-2-phonecall',\n 'nova-2-finance',\n 'nova-2-conversationalai',\n 'nova-2-voicemail',\n 'nova-2-video',\n 'nova-2-medical',\n 'nova-2-drivethru',\n 'nova-2-automotive',\n 'nova-3-general',\n ].includes(model)\n ) {\n this.#logger.warn(\n `${model} does not support language ${language}, falling back to nova-2-general`,\n );\n return 'nova-2-general';\n }\n\n return model;\n }\n\n stream(options?: { connOptions?: APIConnectOptions }): SpeechStream {\n // Deepgram only supports language detection for prerecorded audio, not streaming.\n if (this.#opts.detectLanguage || this.#opts.language === undefined) {\n throw new Error(\n 'language detection is not supported in streaming mode, please disable it and specify a language',\n );\n }\n return new SpeechStream(this, this.#opts, options?.connOptions);\n }\n\n async close() {\n this.abortController.abort();\n }\n}\n\nexport class SpeechStream extends stt.SpeechStream {\n #opts: STTOptions;\n #audioEnergyFilter: AudioEnergyFilter;\n #logger = log();\n #speaking = false;\n #resetWS = new Future();\n #requestId = '';\n #audioDurationCollector: PeriodicCollector<number>;\n label = 'deepgram.SpeechStream';\n\n constructor(stt: STT, opts: STTOptions, connOptions?: APIConnectOptions) {\n super(stt, opts.sampleRate, connOptions);\n this.#opts = opts;\n this.closed = false;\n this.#audioEnergyFilter = new AudioEnergyFilter();\n this.#audioDurationCollector = new PeriodicCollector(\n (duration) => this.onAudioDurationReport(duration),\n { duration: 5.0 },\n );\n }\n\n protected async run() {\n const maxRetry = 32;\n let retries = 0;\n let ws: WebSocket;\n\n while (!this.input.closed && !this.closed) {\n const streamURL = new URL(`${this.#opts.baseUrl}/v1/listen`);\n const params = {\n model: this.#opts.model,\n punctuate: this.#opts.punctuate,\n smart_format: this.#opts.smartFormat,\n dictation: this.#opts.dictation,\n diarize: this.#opts.diarize,\n numerals: this.#opts.numerals,\n no_delay: this.#opts.noDelay,\n interim_results: this.#opts.interimResults,\n encoding: 'linear16',\n vad_events: true,\n sample_rate: this.#opts.sampleRate,\n channels: this.#opts.numChannels,\n endpointing: this.#opts.endpointing || false,\n filler_words: this.#opts.fillerWords,\n keywords: this.#opts.keywords.map((x) => x.join(':')),\n keyterm: this.#opts.keyterm,\n profanity_filter: this.#opts.profanityFilter,\n redact: this.#opts.redact,\n language: this.#opts.language,\n mip_opt_out: this.#opts.mipOptOut,\n };\n Object.entries(params).forEach(([k, v]) => {\n if (v !== undefined) {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n streamURL.searchParams.append(k, String(v));\n } else {\n v.forEach((x) => streamURL.searchParams.append(k, String(x)));\n }\n }\n });\n\n ws = new WebSocket(streamURL, {\n headers: { Authorization: `Token ${this.#opts.apiKey}` },\n });\n\n try {\n await new Promise((resolve, reject) => {\n ws.on('open', resolve);\n ws.on('error', (error) => reject(error));\n ws.on('close', (code) => reject(`WebSocket returned ${code}`));\n });\n\n await this.#runWS(ws);\n } catch (e) {\n if (!this.closed && !this.input.closed) {\n if (retries >= maxRetry) {\n throw new Error(`failed to connect to Deepgram after ${retries} attempts: ${e}`);\n }\n\n const delay = Math.min(retries * 5, 10);\n retries++;\n\n this.#logger.warn(\n `failed to connect to Deepgram, retrying in ${delay} seconds: ${e} (${retries}/${maxRetry})`,\n );\n await new Promise((resolve) => setTimeout(resolve, delay * 1000));\n } else {\n this.#logger.warn(\n `Deepgram disconnected, connection is closed: ${e} (inputClosed: ${this.input.closed}, isClosed: ${this.closed})`,\n );\n }\n }\n }\n\n this.closed = true;\n }\n\n updateOptions(opts: Partial<STTOptions>) {\n this.#opts = { ...this.#opts, ...opts };\n this.#resetWS.resolve();\n }\n\n async #runWS(ws: WebSocket) {\n this.#resetWS = new Future();\n let closing = false;\n\n const keepalive = setInterval(() => {\n try {\n ws.send(JSON.stringify({ type: 'KeepAlive' }));\n } catch {\n clearInterval(keepalive);\n return;\n }\n }, 5000);\n\n // gets cancelled also when sendTask is complete\n const wsMonitor = Task.from(async (controller) => {\n const closed = new Promise<void>(async (_, reject) => {\n ws.once('close', (code, reason) => {\n if (!closing) {\n this.#logger.error(`WebSocket closed with code ${code}: ${reason}`);\n reject(new Error('WebSocket closed'));\n }\n });\n });\n\n await Promise.race([closed, waitForAbort(controller.signal)]);\n });\n\n const sendTask = async () => {\n const samples100Ms = Math.floor(this.#opts.sampleRate / 10);\n const stream = new AudioByteStream(\n this.#opts.sampleRate,\n this.#opts.numChannels,\n samples100Ms,\n );\n\n // waitForAbort internally sets up an abort listener on the abort signal\n // we need to put it outside loop to avoid constant re-registration of the listener\n const abortPromise = waitForAbort(this.abortSignal);\n\n try {\n while (!this.closed) {\n const result = await Promise.race([this.input.next(), abortPromise]);\n\n if (result === undefined) return; // aborted\n if (result.done) {\n break;\n }\n\n const data = result.value;\n\n let frames: AudioFrame[];\n if (data === SpeechStream.FLUSH_SENTINEL) {\n frames = stream.flush();\n this.#audioDurationCollector.flush();\n } else if (\n data.sampleRate === this.#opts.sampleRate &&\n data.channels === this.#opts.numChannels\n ) {\n frames = stream.write(data.data.buffer as ArrayBuffer);\n } else {\n throw new Error(`sample rate or channel count of frame does not match`);\n }\n\n for await (const frame of frames) {\n if (this.#audioEnergyFilter.pushFrame(frame)) {\n const frameDuration = frame.samplesPerChannel / frame.sampleRate;\n this.#audioDurationCollector.push(frameDuration);\n ws.send(frame.data.buffer);\n }\n }\n }\n } finally {\n closing = true;\n ws.send(JSON.stringify({ type: 'CloseStream' }));\n wsMonitor.cancel();\n }\n };\n\n const listenTask = Task.from(async (controller) => {\n const putMessage = (message: stt.SpeechEvent) => {\n if (!this.queue.closed) {\n try {\n this.queue.put(message);\n } catch (e) {\n // ignore\n }\n }\n };\n\n const listenMessage = new Promise<void>((resolve, reject) => {\n ws.on('message', (msg) => {\n try {\n const json = JSON.parse(msg.toString());\n switch (json['type']) {\n case 'SpeechStarted': {\n // This is a normal case. Deepgram's SpeechStarted events\n // are not correlated with speech_final or utterance end.\n // It's possible that we receive two in a row without an endpoint\n // It's also possible we receive a transcript without a SpeechStarted event.\n if (this.#speaking) return;\n this.#speaking = true;\n putMessage({ type: stt.SpeechEventType.START_OF_SPEECH });\n break;\n }\n // see this page:\n // https://developers.deepgram.com/docs/understand-endpointing-interim-results#using-endpointing-speech_final\n // for more information about the different types of events\n case 'Results': {\n const metadata = json['metadata'];\n const requestId = metadata['request_id'];\n const isFinal = json['is_final'];\n const isEndpoint = json['speech_final'];\n this.#requestId = requestId;\n\n const alternatives = liveTranscriptionToSpeechData(\n this.#opts.language!,\n json,\n this.startTimeOffset,\n );\n\n // If, for some reason, we didn't get a SpeechStarted event but we got\n // a transcript with text, we should start speaking. It's rare but has\n // been observed.\n if (alternatives[0] && alternatives[0].text) {\n if (!this.#speaking) {\n this.#speaking = true;\n putMessage({\n type: stt.SpeechEventType.START_OF_SPEECH,\n });\n }\n\n if (isFinal) {\n putMessage({\n type: stt.SpeechEventType.FINAL_TRANSCRIPT,\n alternatives: [alternatives[0], ...alternatives.slice(1)],\n });\n } else {\n putMessage({\n type: stt.SpeechEventType.INTERIM_TRANSCRIPT,\n alternatives: [alternatives[0], ...alternatives.slice(1)],\n });\n }\n }\n\n // if we receive an endpoint, only end the speech if\n // we either had a SpeechStarted event or we have a seen\n // a non-empty transcript (deepgram doesn't have a SpeechEnded event)\n if (isEndpoint && this.#speaking) {\n this.#speaking = false;\n putMessage({ type: stt.SpeechEventType.END_OF_SPEECH });\n }\n\n break;\n }\n case 'Metadata': {\n break;\n }\n default: {\n this.#logger.child({ msg: json }).warn('received unexpected message from Deepgram');\n break;\n }\n }\n\n if (this.closed || closing) {\n resolve();\n }\n } catch (err) {\n this.#logger.error(`STT: Error processing message: ${msg}`);\n reject(err);\n }\n });\n });\n\n await Promise.race([listenMessage, waitForAbort(controller.signal)]);\n }, this.abortController);\n\n await Promise.race([\n this.#resetWS.await,\n Promise.all([sendTask(), listenTask.result, wsMonitor]),\n ]);\n closing = true;\n ws.close();\n clearInterval(keepalive);\n }\n\n private onAudioDurationReport(duration: number) {\n const usageEvent: stt.SpeechEvent = {\n type: stt.SpeechEventType.RECOGNITION_USAGE,\n requestId: this.#requestId,\n recognitionUsage: {\n audioDuration: duration,\n },\n };\n this.queue.put(usageEvent);\n }\n}\n\nfunction createWav(frame: AudioFrame): Buffer {\n const bitsPerSample = 16;\n const byteRate = (frame.sampleRate * frame.channels * bitsPerSample) / 8;\n const blockAlign = (frame.channels * bitsPerSample) / 8;\n\n const header = Buffer.alloc(44);\n header.write('RIFF', 0);\n header.writeUInt32LE(36 + frame.data.byteLength, 4);\n header.write('WAVE', 8);\n header.write('fmt ', 12);\n header.writeUInt32LE(16, 16);\n header.writeUInt16LE(1, 20);\n header.writeUInt16LE(frame.channels, 22);\n header.writeUInt32LE(frame.sampleRate, 24);\n header.writeUInt32LE(byteRate, 28);\n header.writeUInt16LE(blockAlign, 32);\n header.writeUInt16LE(bitsPerSample, 34);\n header.write('data', 36);\n header.writeUInt32LE(frame.data.byteLength, 40);\n\n const pcm = Buffer.from(frame.data.buffer, frame.data.byteOffset, frame.data.byteLength);\n return Buffer.concat([header, pcm]);\n}\n\nconst liveTranscriptionToSpeechData = (\n language: STTLanguages | string,\n data: { [id: string]: any },\n startTimeOffset: number = 0,\n): stt.SpeechData[] => {\n const alts: any[] = data['channel']['alternatives'];\n\n return alts.map((alt) => {\n const wordsData: any[] = alt['words'] ?? [];\n const detectedLanguage =\n language === 'multi' ? alt['languages']?.[0] ?? language : alt['language'] ?? language;\n\n return {\n language: normalizeLanguage(detectedLanguage),\n startTime: wordsData.length ? wordsData[0]['start'] + startTimeOffset : startTimeOffset,\n endTime: wordsData.length\n ? wordsData[wordsData.length - 1]['end'] + startTimeOffset\n : startTimeOffset,\n confidence: alt['confidence'],\n text: alt['transcript'],\n words: wordsData.map((word) =>\n createTimedString({\n text: word['word'] ?? '',\n startTime: (word['start'] ?? 0) + startTimeOffset,\n endTime: (word['end'] ?? 0) + startTimeOffset,\n confidence: word['confidence'] ?? 0.0,\n startTimeOffset,\n }),\n ),\n };\n });\n};\n\nfunction prerecordedTranscriptionToSpeechEvent(\n language: STTLanguages | string | undefined,\n data: { [id: string]: any },\n): stt.SpeechEvent {\n const channel = data['results']['channels'][0];\n const detectedLanguage = channel['detected_language'] ?? '';\n const alternatives = channel['alternatives'].map((alt: { [id: string]: any }) => {\n const wordsData: any[] = alt['words'] ?? [];\n\n return {\n language: normalizeLanguage(language ?? detectedLanguage),\n startTime: wordsData.length ? wordsData[0]['start'] : 0,\n endTime: wordsData.length ? wordsData[wordsData.length - 1]['end'] : 0,\n confidence: alt['confidence'],\n text: alt['transcript'],\n words: wordsData.map((word) =>\n createTimedString({\n text: word['word'] ?? '',\n startTime: word['start'] ?? 0,\n endTime: word['end'] ?? 0,\n confidence: word['confidence'] ?? 0.0,\n }),\n ),\n };\n }) as stt.SpeechData[];\n\n return {\n type: stt.SpeechEventType.FINAL_TRANSCRIPT,\n requestId: data['metadata']['request_id'],\n ...(alternatives.length\n ? { alternatives: alternatives as [stt.SpeechData, ...stt.SpeechData[]] }\n : {}),\n };\n}\n"],"mappings":"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","names":["stt"]}
package/dist/stt.d.cts ADDED
@@ -0,0 +1,53 @@
1
+ import { type APIConnectOptions, type AudioBuffer, stt } from '@livekit/agents';
2
+ import type { STTLanguages, STTModels } from './models.js';
3
+ export interface STTOptions {
4
+ apiKey?: string;
5
+ language?: STTLanguages | string;
6
+ detectLanguage: boolean;
7
+ interimResults: boolean;
8
+ punctuate: boolean;
9
+ model: STTModels;
10
+ smartFormat: boolean;
11
+ noDelay: boolean;
12
+ endpointing: number;
13
+ fillerWords: boolean;
14
+ sampleRate: number;
15
+ numChannels: number;
16
+ keywords: [string, number][];
17
+ keyterm: string[];
18
+ profanityFilter: boolean;
19
+ /**
20
+ * Redact sensitive information from the transcription. Accepts a single value or list of
21
+ * values. Supported values: "pci", "numbers", "ssn", "true" (redact all).
22
+ * See https://developers.deepgram.com/docs/redaction for details.
23
+ */
24
+ redact: string | string[];
25
+ dictation: boolean;
26
+ diarize: boolean;
27
+ numerals: boolean;
28
+ mipOptOut: boolean;
29
+ baseUrl: string;
30
+ }
31
+ export declare class STT extends stt.STT {
32
+ #private;
33
+ label: string;
34
+ private abortController;
35
+ get model(): string;
36
+ get provider(): string;
37
+ constructor(opts?: Partial<STTOptions>);
38
+ _recognize(buffer: AudioBuffer, abortSignal?: AbortSignal): Promise<stt.SpeechEvent>;
39
+ updateOptions(opts: Partial<STTOptions>): void;
40
+ stream(options?: {
41
+ connOptions?: APIConnectOptions;
42
+ }): SpeechStream;
43
+ close(): Promise<void>;
44
+ }
45
+ export declare class SpeechStream extends stt.SpeechStream {
46
+ #private;
47
+ label: string;
48
+ constructor(stt: STT, opts: STTOptions, connOptions?: APIConnectOptions);
49
+ protected run(): Promise<void>;
50
+ updateOptions(opts: Partial<STTOptions>): void;
51
+ private onAudioDurationReport;
52
+ }
53
+ //# sourceMappingURL=stt.d.ts.map
package/dist/stt.d.ts ADDED
@@ -0,0 +1,53 @@
1
+ import { type APIConnectOptions, type AudioBuffer, stt } from '@livekit/agents';
2
+ import type { STTLanguages, STTModels } from './models.js';
3
+ export interface STTOptions {
4
+ apiKey?: string;
5
+ language?: STTLanguages | string;
6
+ detectLanguage: boolean;
7
+ interimResults: boolean;
8
+ punctuate: boolean;
9
+ model: STTModels;
10
+ smartFormat: boolean;
11
+ noDelay: boolean;
12
+ endpointing: number;
13
+ fillerWords: boolean;
14
+ sampleRate: number;
15
+ numChannels: number;
16
+ keywords: [string, number][];
17
+ keyterm: string[];
18
+ profanityFilter: boolean;
19
+ /**
20
+ * Redact sensitive information from the transcription. Accepts a single value or list of
21
+ * values. Supported values: "pci", "numbers", "ssn", "true" (redact all).
22
+ * See https://developers.deepgram.com/docs/redaction for details.
23
+ */
24
+ redact: string | string[];
25
+ dictation: boolean;
26
+ diarize: boolean;
27
+ numerals: boolean;
28
+ mipOptOut: boolean;
29
+ baseUrl: string;
30
+ }
31
+ export declare class STT extends stt.STT {
32
+ #private;
33
+ label: string;
34
+ private abortController;
35
+ get model(): string;
36
+ get provider(): string;
37
+ constructor(opts?: Partial<STTOptions>);
38
+ _recognize(buffer: AudioBuffer, abortSignal?: AbortSignal): Promise<stt.SpeechEvent>;
39
+ updateOptions(opts: Partial<STTOptions>): void;
40
+ stream(options?: {
41
+ connOptions?: APIConnectOptions;
42
+ }): SpeechStream;
43
+ close(): Promise<void>;
44
+ }
45
+ export declare class SpeechStream extends stt.SpeechStream {
46
+ #private;
47
+ label: string;
48
+ constructor(stt: STT, opts: STTOptions, connOptions?: APIConnectOptions);
49
+ protected run(): Promise<void>;
50
+ updateOptions(opts: Partial<STTOptions>): void;
51
+ private onAudioDurationReport;
52
+ }
53
+ //# sourceMappingURL=stt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stt.d.ts","sourceRoot":"","sources":["../src/stt.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAUhB,GAAG,EAEJ,MAAM,iBAAiB,CAAC;AAIzB,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IACjC,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AA0BD,qBAAa,GAAI,SAAQ,GAAG,CAAC,GAAG;;IAG9B,KAAK,SAAkB;IACvB,OAAO,CAAC,eAAe,CAAyB;IAEhD,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;gBAEW,IAAI,GAAE,OAAO,CAAC,UAAU,CAAqB;IAyBnD,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAmD1F,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC;IA0CvC,MAAM,CAAC,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,iBAAiB,CAAA;KAAE,GAAG,YAAY;IAU7D,KAAK;CAGZ;AAED,qBAAa,YAAa,SAAQ,GAAG,CAAC,YAAY;;IAQhD,KAAK,SAA2B;gBAEpB,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,iBAAiB;cAWvD,GAAG;IA2EnB,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC;IA8LvC,OAAO,CAAC,qBAAqB;CAU9B"}