@livekit/agents 1.0.41 → 1.0.43

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 (84) hide show
  1. package/dist/inference/index.cjs +8 -0
  2. package/dist/inference/index.cjs.map +1 -1
  3. package/dist/inference/index.d.cts +2 -2
  4. package/dist/inference/index.d.ts +2 -2
  5. package/dist/inference/index.d.ts.map +1 -1
  6. package/dist/inference/index.js +8 -0
  7. package/dist/inference/index.js.map +1 -1
  8. package/dist/inference/stt.cjs +51 -10
  9. package/dist/inference/stt.cjs.map +1 -1
  10. package/dist/inference/stt.d.cts +33 -0
  11. package/dist/inference/stt.d.ts +33 -0
  12. package/dist/inference/stt.d.ts.map +1 -1
  13. package/dist/inference/stt.js +48 -9
  14. package/dist/inference/stt.js.map +1 -1
  15. package/dist/inference/stt.test.cjs +204 -0
  16. package/dist/inference/stt.test.cjs.map +1 -0
  17. package/dist/inference/stt.test.js +203 -0
  18. package/dist/inference/stt.test.js.map +1 -0
  19. package/dist/inference/tts.cjs +52 -10
  20. package/dist/inference/tts.cjs.map +1 -1
  21. package/dist/inference/tts.d.cts +22 -0
  22. package/dist/inference/tts.d.ts +22 -0
  23. package/dist/inference/tts.d.ts.map +1 -1
  24. package/dist/inference/tts.js +49 -9
  25. package/dist/inference/tts.js.map +1 -1
  26. package/dist/inference/tts.test.cjs +223 -0
  27. package/dist/inference/tts.test.cjs.map +1 -0
  28. package/dist/inference/tts.test.js +222 -0
  29. package/dist/inference/tts.test.js.map +1 -0
  30. package/dist/ipc/inference_proc_lazy_main.cjs +13 -1
  31. package/dist/ipc/inference_proc_lazy_main.cjs.map +1 -1
  32. package/dist/ipc/inference_proc_lazy_main.js +13 -1
  33. package/dist/ipc/inference_proc_lazy_main.js.map +1 -1
  34. package/dist/ipc/job_proc_lazy_main.cjs +2 -1
  35. package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
  36. package/dist/ipc/job_proc_lazy_main.js +2 -1
  37. package/dist/ipc/job_proc_lazy_main.js.map +1 -1
  38. package/dist/ipc/supervised_proc.cjs.map +1 -1
  39. package/dist/ipc/supervised_proc.d.cts +7 -0
  40. package/dist/ipc/supervised_proc.d.ts +7 -0
  41. package/dist/ipc/supervised_proc.d.ts.map +1 -1
  42. package/dist/ipc/supervised_proc.js.map +1 -1
  43. package/dist/stt/stt.cjs.map +1 -1
  44. package/dist/stt/stt.d.cts +7 -0
  45. package/dist/stt/stt.d.ts +7 -0
  46. package/dist/stt/stt.d.ts.map +1 -1
  47. package/dist/stt/stt.js.map +1 -1
  48. package/dist/transcription.cjs.map +1 -1
  49. package/dist/transcription.d.cts +6 -0
  50. package/dist/transcription.d.ts +6 -0
  51. package/dist/transcription.d.ts.map +1 -1
  52. package/dist/transcription.js.map +1 -1
  53. package/dist/vad.cjs +1 -1
  54. package/dist/vad.cjs.map +1 -1
  55. package/dist/vad.d.cts +3 -2
  56. package/dist/vad.d.ts +3 -2
  57. package/dist/vad.d.ts.map +1 -1
  58. package/dist/vad.js +1 -1
  59. package/dist/vad.js.map +1 -1
  60. package/dist/voice/agent_activity.cjs +1 -2
  61. package/dist/voice/agent_activity.cjs.map +1 -1
  62. package/dist/voice/agent_activity.js +1 -2
  63. package/dist/voice/agent_activity.js.map +1 -1
  64. package/dist/voice/audio_recognition.cjs +1 -1
  65. package/dist/voice/audio_recognition.cjs.map +1 -1
  66. package/dist/voice/audio_recognition.d.cts +14 -0
  67. package/dist/voice/audio_recognition.d.ts +14 -0
  68. package/dist/voice/audio_recognition.d.ts.map +1 -1
  69. package/dist/voice/audio_recognition.js +1 -1
  70. package/dist/voice/audio_recognition.js.map +1 -1
  71. package/package.json +1 -1
  72. package/src/inference/index.ts +8 -0
  73. package/src/inference/stt.test.ts +236 -0
  74. package/src/inference/stt.ts +95 -17
  75. package/src/inference/tts.test.ts +255 -0
  76. package/src/inference/tts.ts +81 -15
  77. package/src/ipc/inference_proc_lazy_main.ts +13 -1
  78. package/src/ipc/job_proc_lazy_main.ts +5 -1
  79. package/src/ipc/supervised_proc.ts +7 -0
  80. package/src/stt/stt.ts +7 -0
  81. package/src/transcription.ts +6 -0
  82. package/src/vad.ts +4 -3
  83. package/src/voice/agent_activity.ts +1 -1
  84. package/src/voice/audio_recognition.ts +16 -1
@@ -33,6 +33,10 @@ __export(inference_exports, {
33
33
  STT: () => import_stt.STT,
34
34
  TTS: () => import_tts.TTS,
35
35
  llm: () => llm,
36
+ normalizeSTTFallback: () => import_stt.normalizeSTTFallback,
37
+ normalizeTTSFallback: () => import_tts.normalizeTTSFallback,
38
+ parseSTTModelString: () => import_stt.parseSTTModelString,
39
+ parseTTSModelString: () => import_tts.parseTTSModelString,
36
40
  stt: () => stt,
37
41
  tts: () => tts
38
42
  });
@@ -50,6 +54,10 @@ var import_tts = require("./tts.cjs");
50
54
  STT,
51
55
  TTS,
52
56
  llm,
57
+ normalizeSTTFallback,
58
+ normalizeTTSFallback,
59
+ parseSTTModelString,
60
+ parseTTSModelString,
53
61
  stt,
54
62
  tts
55
63
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/inference/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport * as llm from './llm.js';\nimport * as stt from './stt.js';\nimport * as tts from './tts.js';\n\nexport {\n LLM,\n LLMStream,\n type ChatCompletionOptions,\n type GatewayOptions,\n type InferenceLLMOptions,\n type LLMModels,\n} from './llm.js';\n\nexport {\n STT,\n type STTLanguages,\n type STTModels,\n type ModelWithLanguage as STTModelString,\n type STTOptions,\n} from './stt.js';\n\nexport {\n TTS,\n type TTSModels,\n type ModelWithVoice as TTSModelString,\n type TTSOptions,\n} from './tts.js';\n\nexport { llm, stt, tts };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,UAAqB;AACrB,UAAqB;AACrB,UAAqB;AAErB,iBAOO;AAEP,iBAMO;AAEP,iBAKO;","names":[]}
1
+ {"version":3,"sources":["../../src/inference/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport * as llm from './llm.js';\nimport * as stt from './stt.js';\nimport * as tts from './tts.js';\n\nexport {\n LLM,\n LLMStream,\n type ChatCompletionOptions,\n type GatewayOptions,\n type InferenceLLMOptions,\n type LLMModels,\n} from './llm.js';\n\nexport {\n normalizeSTTFallback,\n parseSTTModelString,\n STT,\n type STTFallbackModel,\n type STTFallbackModelType,\n type STTLanguages,\n type STTModels,\n type ModelWithLanguage as STTModelString,\n type STTOptions,\n} from './stt.js';\n\nexport {\n normalizeTTSFallback,\n parseTTSModelString,\n TTS,\n type TTSFallbackModel,\n type TTSFallbackModelType,\n type TTSModels,\n type ModelWithVoice as TTSModelString,\n type TTSOptions,\n} from './tts.js';\n\nexport { llm, stt, tts };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,UAAqB;AACrB,UAAqB;AACrB,UAAqB;AAErB,iBAOO;AAEP,iBAUO;AAEP,iBASO;","names":[]}
@@ -2,7 +2,7 @@ import * as llm from './llm.js';
2
2
  import * as stt from './stt.js';
3
3
  import * as tts from './tts.js';
4
4
  export { LLM, LLMStream, type ChatCompletionOptions, type GatewayOptions, type InferenceLLMOptions, type LLMModels, } from './llm.js';
5
- export { STT, type STTLanguages, type STTModels, type ModelWithLanguage as STTModelString, type STTOptions, } from './stt.js';
6
- export { TTS, type TTSModels, type ModelWithVoice as TTSModelString, type TTSOptions, } from './tts.js';
5
+ export { normalizeSTTFallback, parseSTTModelString, STT, type STTFallbackModel, type STTFallbackModelType, type STTLanguages, type STTModels, type ModelWithLanguage as STTModelString, type STTOptions, } from './stt.js';
6
+ export { normalizeTTSFallback, parseTTSModelString, TTS, type TTSFallbackModel, type TTSFallbackModelType, type TTSModels, type ModelWithVoice as TTSModelString, type TTSOptions, } from './tts.js';
7
7
  export { llm, stt, tts };
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -2,7 +2,7 @@ import * as llm from './llm.js';
2
2
  import * as stt from './stt.js';
3
3
  import * as tts from './tts.js';
4
4
  export { LLM, LLMStream, type ChatCompletionOptions, type GatewayOptions, type InferenceLLMOptions, type LLMModels, } from './llm.js';
5
- export { STT, type STTLanguages, type STTModels, type ModelWithLanguage as STTModelString, type STTOptions, } from './stt.js';
6
- export { TTS, type TTSModels, type ModelWithVoice as TTSModelString, type TTSOptions, } from './tts.js';
5
+ export { normalizeSTTFallback, parseSTTModelString, STT, type STTFallbackModel, type STTFallbackModelType, type STTLanguages, type STTModels, type ModelWithLanguage as STTModelString, type STTOptions, } from './stt.js';
6
+ export { normalizeTTSFallback, parseTTSModelString, TTS, type TTSFallbackModel, type TTSFallbackModelType, type TTSModels, type ModelWithVoice as TTSModelString, type TTSOptions, } from './tts.js';
7
7
  export { llm, stt, tts };
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inference/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,OAAO,EACL,GAAG,EACH,SAAS,EACT,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,SAAS,GACf,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,GAAG,EACH,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,iBAAiB,IAAI,cAAc,EACxC,KAAK,UAAU,GAChB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,GAAG,EACH,KAAK,SAAS,EACd,KAAK,cAAc,IAAI,cAAc,EACrC,KAAK,UAAU,GAChB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inference/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,OAAO,EACL,GAAG,EACH,SAAS,EACT,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,SAAS,GACf,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,GAAG,EACH,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,iBAAiB,IAAI,cAAc,EACxC,KAAK,UAAU,GAChB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,GAAG,EACH,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,SAAS,EACd,KAAK,cAAc,IAAI,cAAc,EACrC,KAAK,UAAU,GAChB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC"}
@@ -6,9 +6,13 @@ import {
6
6
  LLMStream
7
7
  } from "./llm.js";
8
8
  import {
9
+ normalizeSTTFallback,
10
+ parseSTTModelString,
9
11
  STT
10
12
  } from "./stt.js";
11
13
  import {
14
+ normalizeTTSFallback,
15
+ parseTTSModelString,
12
16
  TTS
13
17
  } from "./tts.js";
14
18
  export {
@@ -17,6 +21,10 @@ export {
17
21
  STT,
18
22
  TTS,
19
23
  llm,
24
+ normalizeSTTFallback,
25
+ normalizeTTSFallback,
26
+ parseSTTModelString,
27
+ parseTTSModelString,
20
28
  stt,
21
29
  tts
22
30
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/inference/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport * as llm from './llm.js';\nimport * as stt from './stt.js';\nimport * as tts from './tts.js';\n\nexport {\n LLM,\n LLMStream,\n type ChatCompletionOptions,\n type GatewayOptions,\n type InferenceLLMOptions,\n type LLMModels,\n} from './llm.js';\n\nexport {\n STT,\n type STTLanguages,\n type STTModels,\n type ModelWithLanguage as STTModelString,\n type STTOptions,\n} from './stt.js';\n\nexport {\n TTS,\n type TTSModels,\n type ModelWithVoice as TTSModelString,\n type TTSOptions,\n} from './tts.js';\n\nexport { llm, stt, tts };\n"],"mappings":"AAGA,YAAY,SAAS;AACrB,YAAY,SAAS;AACrB,YAAY,SAAS;AAErB;AAAA,EACE;AAAA,EACA;AAAA,OAKK;AAEP;AAAA,EACE;AAAA,OAKK;AAEP;AAAA,EACE;AAAA,OAIK;","names":[]}
1
+ {"version":3,"sources":["../../src/inference/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport * as llm from './llm.js';\nimport * as stt from './stt.js';\nimport * as tts from './tts.js';\n\nexport {\n LLM,\n LLMStream,\n type ChatCompletionOptions,\n type GatewayOptions,\n type InferenceLLMOptions,\n type LLMModels,\n} from './llm.js';\n\nexport {\n normalizeSTTFallback,\n parseSTTModelString,\n STT,\n type STTFallbackModel,\n type STTFallbackModelType,\n type STTLanguages,\n type STTModels,\n type ModelWithLanguage as STTModelString,\n type STTOptions,\n} from './stt.js';\n\nexport {\n normalizeTTSFallback,\n parseTTSModelString,\n TTS,\n type TTSFallbackModel,\n type TTSFallbackModelType,\n type TTSModels,\n type ModelWithVoice as TTSModelString,\n type TTSOptions,\n} from './tts.js';\n\nexport { llm, stt, tts };\n"],"mappings":"AAGA,YAAY,SAAS;AACrB,YAAY,SAAS;AACrB,YAAY,SAAS;AAErB;AAAA,EACE;AAAA,EACA;AAAA,OAKK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAOK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAMK;","names":[]}
@@ -19,7 +19,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var stt_exports = {};
20
20
  __export(stt_exports, {
21
21
  STT: () => STT,
22
- SpeechStream: () => SpeechStream
22
+ SpeechStream: () => SpeechStream,
23
+ normalizeSTTFallback: () => normalizeSTTFallback,
24
+ parseSTTModelString: () => parseSTTModelString
23
25
  });
24
26
  module.exports = __toCommonJS(stt_exports);
25
27
  var import_rtc_node = require("@livekit/rtc-node");
@@ -33,6 +35,26 @@ var import_utils = require("../utils.cjs");
33
35
  var import_io = require("../voice/io.cjs");
34
36
  var import_api_protos = require("./api_protos.cjs");
35
37
  var import_utils2 = require("./utils.cjs");
38
+ function parseSTTModelString(model) {
39
+ const idx = model.lastIndexOf(":");
40
+ if (idx !== -1) {
41
+ return [model.slice(0, idx), model.slice(idx + 1)];
42
+ }
43
+ return [model, void 0];
44
+ }
45
+ function normalizeSTTFallback(fallback) {
46
+ const makeFallback = (model) => {
47
+ if (typeof model === "string") {
48
+ const [name] = parseSTTModelString(model);
49
+ return { model: name };
50
+ }
51
+ return model;
52
+ };
53
+ if (Array.isArray(fallback)) {
54
+ return fallback.map(makeFallback);
55
+ }
56
+ return [makeFallback(fallback)];
57
+ }
36
58
  const DEFAULT_ENCODING = "pcm_s16le";
37
59
  const DEFAULT_SAMPLE_RATE = 16e3;
38
60
  const DEFAULT_BASE_URL = "wss://agent-gateway.livekit.cloud/v1";
@@ -51,7 +73,9 @@ class STT extends import_stt.STT {
51
73
  sampleRate = DEFAULT_SAMPLE_RATE,
52
74
  apiKey,
53
75
  apiSecret,
54
- modelOptions = {}
76
+ modelOptions = {},
77
+ fallback,
78
+ connOptions
55
79
  } = opts || {};
56
80
  const lkBaseURL = baseURL || process.env.LIVEKIT_INFERENCE_URL || DEFAULT_BASE_URL;
57
81
  const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY;
@@ -62,6 +86,7 @@ class STT extends import_stt.STT {
62
86
  if (!lkApiSecret) {
63
87
  throw new Error("apiSecret is required: pass apiSecret or set LIVEKIT_API_SECRET");
64
88
  }
89
+ const normalizedFallback = fallback ? normalizeSTTFallback(fallback) : void 0;
65
90
  this.opts = {
66
91
  model,
67
92
  language,
@@ -70,18 +95,17 @@ class STT extends import_stt.STT {
70
95
  baseURL: lkBaseURL,
71
96
  apiKey: lkApiKey,
72
97
  apiSecret: lkApiSecret,
73
- modelOptions
98
+ modelOptions,
99
+ fallback: normalizedFallback,
100
+ connOptions: connOptions ?? import_types.DEFAULT_API_CONNECT_OPTIONS
74
101
  };
75
102
  }
76
103
  get label() {
77
104
  return "inference.STT";
78
105
  }
79
106
  static fromModelString(modelString) {
80
- if (modelString.includes(":")) {
81
- const [model, language] = modelString.split(":");
82
- return new STT({ model, language });
83
- }
84
- return new STT({ model: modelString });
107
+ const [model, language] = parseSTTModelString(modelString);
108
+ return new STT({ model, language });
85
109
  }
86
110
  async _recognize(_) {
87
111
  throw new Error("LiveKit STT does not support batch recognition, use stream() instead");
@@ -93,7 +117,7 @@ class STT extends import_stt.STT {
93
117
  }
94
118
  }
95
119
  stream(options) {
96
- const { language, connOptions = import_types.DEFAULT_API_CONNECT_OPTIONS } = options || {};
120
+ const { language, connOptions = this.opts.connOptions ?? import_types.DEFAULT_API_CONNECT_OPTIONS } = options || {};
97
121
  const streamOpts = {
98
122
  ...this.opts,
99
123
  language: language ?? this.opts.language
@@ -103,6 +127,7 @@ class STT extends import_stt.STT {
103
127
  return stream;
104
128
  }
105
129
  async connectWs(timeout) {
130
+ var _a;
106
131
  const params = {
107
132
  settings: {
108
133
  sample_rate: String(this.opts.sampleRate),
@@ -116,6 +141,20 @@ class STT extends import_stt.STT {
116
141
  if (this.opts.language) {
117
142
  params.settings.language = this.opts.language;
118
143
  }
144
+ if ((_a = this.opts.fallback) == null ? void 0 : _a.length) {
145
+ params.fallback = {
146
+ models: this.opts.fallback.map((m) => ({
147
+ model: m.model,
148
+ extra: m.extraKwargs ?? {}
149
+ }))
150
+ };
151
+ }
152
+ if (this.opts.connOptions) {
153
+ params.connection = {
154
+ timeout: this.opts.connOptions.timeoutMs / 1e3,
155
+ retries: this.opts.connOptions.maxRetry
156
+ };
157
+ }
119
158
  let baseURL = this.opts.baseURL;
120
159
  if (baseURL.startsWith("http://") || baseURL.startsWith("https://")) {
121
160
  baseURL = baseURL.replace("http", "ws");
@@ -378,6 +417,8 @@ class SpeechStream extends import_stt.SpeechStream {
378
417
  // Annotate the CommonJS export names for ESM import in node:
379
418
  0 && (module.exports = {
380
419
  STT,
381
- SpeechStream
420
+ SpeechStream,
421
+ normalizeSTTFallback,
422
+ parseSTTModelString
382
423
  });
383
424
  //# sourceMappingURL=stt.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/inference/stt.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { type AudioFrame } from '@livekit/rtc-node';\nimport type { WebSocket } from 'ws';\nimport { APIError, APIStatusError } from '../_exceptions.js';\nimport { AudioByteStream } from '../audio.js';\nimport { log } from '../log.js';\nimport { createStreamChannel } from '../stream/stream_channel.js';\nimport {\n STT as BaseSTT,\n SpeechStream as BaseSpeechStream,\n type SpeechData,\n type SpeechEvent,\n SpeechEventType,\n} from '../stt/index.js';\nimport { type APIConnectOptions, DEFAULT_API_CONNECT_OPTIONS } from '../types.js';\nimport { type AudioBuffer, Event, Task, cancelAndWait, shortuuid, waitForAbort } from '../utils.js';\nimport { type TimedString, createTimedString } from '../voice/io.js';\nimport {\n type SttServerEvent,\n type SttTranscriptEvent,\n sttServerEventSchema,\n} from './api_protos.js';\nimport { type AnyString, connectWs, createAccessToken } from './utils.js';\n\nexport type DeepgramModels =\n | 'deepgram/flux-general'\n | 'deepgram/nova-3'\n | 'deepgram/nova-3-medical'\n | 'deepgram/nova-2'\n | 'deepgram/nova-2-medical'\n | 'deepgram/nova-2-conversationalai'\n | 'deepgram/nova-2-phonecall';\n\nexport type CartesiaModels = 'cartesia/ink-whisper';\n\nexport type AssemblyaiModels =\n | 'assemblyai/universal-streaming'\n | 'assemblyai/universal-streaming-multilingual';\n\nexport type ElevenlabsSTTModels = 'elevenlabs/scribe_v2_realtime';\n\nexport interface CartesiaOptions {\n min_volume?: number; // default: not specified\n max_silence_duration_secs?: number; // default: not specified\n}\n\nexport interface DeepgramOptions {\n filler_words?: boolean; // default: true\n interim_results?: boolean; // default: true\n endpointing?: number; // default: 25 (ms)\n punctuate?: boolean; // default: false\n smart_format?: boolean;\n keywords?: Array<[string, number]>;\n keyterms?: string[];\n profanity_filter?: boolean;\n numerals?: boolean;\n mip_opt_out?: boolean;\n}\n\nexport interface AssemblyAIOptions {\n format_turns?: boolean; // default: false\n end_of_turn_confidence_threshold?: number; // default: 0.01\n min_end_of_turn_silence_when_confident?: number; // default: 0\n max_turn_silence?: number; // default: not specified\n keyterms_prompt?: string[]; // default: not specified\n}\n\nexport type STTLanguages =\n | 'multi'\n | 'en'\n | 'de'\n | 'es'\n | 'fr'\n | 'ja'\n | 'pt'\n | 'zh'\n | 'hi'\n | AnyString;\n\ntype _STTModels = DeepgramModels | CartesiaModels | AssemblyaiModels | ElevenlabsSTTModels;\n\nexport type STTModels = _STTModels | 'auto' | AnyString;\n\nexport type ModelWithLanguage = `${_STTModels}:${STTLanguages}` | STTModels;\n\nexport type STTOptions<TModel extends STTModels> = TModel extends DeepgramModels\n ? DeepgramOptions\n : TModel extends CartesiaModels\n ? CartesiaOptions\n : TModel extends AssemblyaiModels\n ? AssemblyAIOptions\n : Record<string, unknown>;\n\nexport type STTEncoding = 'pcm_s16le';\n\nconst DEFAULT_ENCODING: STTEncoding = 'pcm_s16le';\nconst DEFAULT_SAMPLE_RATE = 16000;\nconst DEFAULT_BASE_URL = 'wss://agent-gateway.livekit.cloud/v1';\nconst DEFAULT_CANCEL_TIMEOUT = 5000;\n\nexport interface InferenceSTTOptions<TModel extends STTModels> {\n model?: TModel;\n language?: STTLanguages;\n encoding: STTEncoding;\n sampleRate: number;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: STTOptions<TModel>;\n}\n\n/**\n * Livekit Cloud Inference STT\n */\nexport class STT<TModel extends STTModels> extends BaseSTT {\n private opts: InferenceSTTOptions<TModel>;\n private streams: Set<SpeechStream<TModel>> = new Set();\n\n #logger = log();\n\n constructor(opts?: {\n model?: TModel;\n language?: STTLanguages;\n baseURL?: string;\n encoding?: STTEncoding;\n sampleRate?: number;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: STTOptions<TModel>;\n }) {\n super({ streaming: true, interimResults: true, alignedTranscript: 'word' });\n\n const {\n model,\n language,\n baseURL,\n encoding = DEFAULT_ENCODING,\n sampleRate = DEFAULT_SAMPLE_RATE,\n apiKey,\n apiSecret,\n modelOptions = {} as STTOptions<TModel>,\n } = opts || {};\n\n const lkBaseURL = baseURL || process.env.LIVEKIT_INFERENCE_URL || DEFAULT_BASE_URL;\n const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY;\n if (!lkApiKey) {\n throw new Error('apiKey is required: pass apiKey or set LIVEKIT_API_KEY');\n }\n\n const lkApiSecret =\n apiSecret || process.env.LIVEKIT_INFERENCE_API_SECRET || process.env.LIVEKIT_API_SECRET;\n if (!lkApiSecret) {\n throw new Error('apiSecret is required: pass apiSecret or set LIVEKIT_API_SECRET');\n }\n\n this.opts = {\n model,\n language,\n encoding,\n sampleRate,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions,\n };\n }\n\n get label(): string {\n return 'inference.STT';\n }\n\n static fromModelString(modelString: string): STT<AnyString> {\n if (modelString.includes(':')) {\n const [model, language] = modelString.split(':') as [AnyString, STTLanguages];\n return new STT({ model, language });\n }\n return new STT({ model: modelString });\n }\n\n protected async _recognize(_: AudioBuffer): Promise<SpeechEvent> {\n throw new Error('LiveKit STT does not support batch recognition, use stream() instead');\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n\n for (const stream of this.streams) {\n stream.updateOptions(opts);\n }\n }\n\n stream(options?: {\n language?: STTLanguages | string;\n connOptions?: APIConnectOptions;\n }): SpeechStream<TModel> {\n const { language, connOptions = DEFAULT_API_CONNECT_OPTIONS } = options || {};\n const streamOpts = {\n ...this.opts,\n language: language ?? this.opts.language,\n } as InferenceSTTOptions<TModel>;\n\n const stream = new SpeechStream(this, streamOpts, connOptions);\n this.streams.add(stream);\n\n return stream;\n }\n\n async connectWs(timeout: number): Promise<WebSocket> {\n const params = {\n settings: {\n sample_rate: String(this.opts.sampleRate),\n encoding: this.opts.encoding,\n extra: this.opts.modelOptions,\n },\n } as Record<string, unknown>;\n\n if (this.opts.model && this.opts.model !== 'auto') {\n params.model = this.opts.model;\n }\n\n if (this.opts.language) {\n (params.settings as Record<string, unknown>).language = this.opts.language;\n }\n\n let baseURL = this.opts.baseURL;\n if (baseURL.startsWith('http://') || baseURL.startsWith('https://')) {\n baseURL = baseURL.replace('http', 'ws');\n }\n\n const token = await createAccessToken(this.opts.apiKey, this.opts.apiSecret);\n const url = `${baseURL}/stt`;\n const headers = { Authorization: `Bearer ${token}` } as Record<string, string>;\n\n const socket = await connectWs(url, headers, timeout);\n const msg = { ...params, type: 'session.create' };\n socket.send(JSON.stringify(msg));\n\n return socket;\n }\n}\n\nexport class SpeechStream<TModel extends STTModels> extends BaseSpeechStream {\n private opts: InferenceSTTOptions<TModel>;\n private requestId = shortuuid('stt_request_');\n private speaking = false;\n private speechDuration = 0;\n private reconnectEvent = new Event();\n private stt: STT<TModel>;\n private connOptions: APIConnectOptions;\n\n #logger = log();\n\n constructor(\n sttImpl: STT<TModel>,\n opts: InferenceSTTOptions<TModel>,\n connOptions: APIConnectOptions,\n ) {\n super(sttImpl, opts.sampleRate, connOptions);\n this.opts = opts;\n this.stt = sttImpl;\n this.connOptions = connOptions;\n }\n\n get label(): string {\n return 'inference.SpeechStream';\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n this.reconnectEvent.set();\n }\n\n protected async run(): Promise<void> {\n while (true) {\n // Create fresh resources for each connection attempt\n let ws: WebSocket | null = null;\n let closing = false;\n let finalReceived = false;\n\n const eventChannel = createStreamChannel<SttServerEvent>();\n\n const resourceCleanup = () => {\n if (closing) return;\n closing = true;\n eventChannel.close();\n ws?.removeAllListeners();\n ws?.close();\n };\n\n const createWsListener = async (ws: WebSocket, signal: AbortSignal) => {\n return new Promise<void>((resolve, reject) => {\n const onAbort = () => {\n resourceCleanup();\n reject(new Error('WebSocket connection aborted'));\n };\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n ws.on('message', (data) => {\n const json = JSON.parse(data.toString()) as SttServerEvent;\n eventChannel.write(json);\n });\n\n ws.on('error', (e) => {\n this.#logger.error({ error: e }, 'WebSocket error');\n resourceCleanup();\n reject(e);\n });\n\n ws.on('close', (code: number) => {\n resourceCleanup();\n\n if (!closing) return this.#logger.error('WebSocket closed unexpectedly');\n if (finalReceived) return resolve();\n\n reject(\n new APIStatusError({\n message: 'LiveKit STT connection closed unexpectedly',\n options: { statusCode: code },\n }),\n );\n });\n });\n };\n\n const send = async (socket: WebSocket, signal: AbortSignal) => {\n const audioStream = new AudioByteStream(\n this.opts.sampleRate,\n 1,\n Math.floor(this.opts.sampleRate / 20), // 50ms\n );\n\n // Create abort promise once to avoid memory leak\n const abortPromise = new Promise<never>((_, reject) => {\n if (signal.aborted) {\n return reject(new Error('Send aborted'));\n }\n const onAbort = () => reject(new Error('Send aborted'));\n signal.addEventListener('abort', onAbort, { once: true });\n });\n\n // Manual iteration to support cancellation\n const iterator = this.input[Symbol.asyncIterator]();\n try {\n while (true) {\n const result = await Promise.race([iterator.next(), abortPromise]);\n\n if (result.done) break;\n const ev = result.value;\n\n let frames: AudioFrame[];\n if (ev === SpeechStream.FLUSH_SENTINEL) {\n frames = audioStream.flush();\n } else {\n const frame = ev as AudioFrame;\n frames = audioStream.write(new Int16Array(frame.data).buffer);\n }\n\n for (const frame of frames) {\n this.speechDuration += frame.samplesPerChannel / frame.sampleRate;\n const base64 = Buffer.from(frame.data.buffer).toString('base64');\n const msg = { type: 'input_audio', audio: base64 };\n socket.send(JSON.stringify(msg));\n }\n }\n\n closing = true;\n socket.send(JSON.stringify({ type: 'session.finalize' }));\n } catch (e) {\n if ((e as Error).message === 'Send aborted') {\n // Expected abort, don't log\n return;\n }\n throw e;\n }\n };\n\n const recv = async (signal: AbortSignal) => {\n const serverEventStream = eventChannel.stream();\n const reader = serverEventStream.getReader();\n\n try {\n while (!this.closed && !signal.aborted) {\n const result = await reader.read();\n if (signal.aborted) return;\n if (result.done) return;\n\n // Parse and validate with Zod schema\n const parseResult = await sttServerEventSchema.safeParseAsync(result.value);\n if (!parseResult.success) {\n this.#logger.warn(\n { error: parseResult.error, rawData: result.value },\n 'Failed to parse STT server event',\n );\n continue;\n }\n\n const event: SttServerEvent = parseResult.data;\n\n switch (event.type) {\n case 'session.created':\n case 'session.finalized':\n break;\n case 'session.closed':\n finalReceived = true;\n resourceCleanup();\n break;\n case 'interim_transcript':\n this.processTranscript(event, false);\n break;\n case 'final_transcript':\n this.processTranscript(event, true);\n break;\n case 'error':\n this.#logger.error({ error: event }, 'Received error from LiveKit STT');\n resourceCleanup();\n throw new APIError(`LiveKit STT returned error: ${JSON.stringify(event)}`);\n }\n }\n } finally {\n reader.releaseLock();\n try {\n await serverEventStream.cancel();\n } catch (e) {\n this.#logger.debug('Error cancelling serverEventStream (may already be cancelled):', e);\n }\n }\n };\n\n try {\n ws = await this.stt.connectWs(this.connOptions.timeoutMs);\n\n const controller = this.abortController; // Use base class abortController for proper cancellation\n const sendTask = Task.from(({ signal }) => send(ws!, signal), controller);\n const wsListenerTask = Task.from(({ signal }) => createWsListener(ws!, signal), controller);\n const recvTask = Task.from(({ signal }) => recv(signal), controller);\n const waitReconnectTask = Task.from(\n ({ signal }) => Promise.race([this.reconnectEvent.wait(), waitForAbort(signal)]),\n controller,\n );\n\n try {\n await Promise.race([\n Promise.all([sendTask.result, wsListenerTask.result, recvTask.result]),\n waitReconnectTask.result,\n ]);\n\n // If reconnect didn't trigger, tasks finished - exit loop\n if (!waitReconnectTask.done) break;\n\n // Reconnect triggered - clear event and continue loop\n this.reconnectEvent.clear();\n } finally {\n // Cancel all tasks to ensure cleanup\n await cancelAndWait(\n [sendTask, wsListenerTask, recvTask, waitReconnectTask],\n DEFAULT_CANCEL_TIMEOUT,\n );\n resourceCleanup();\n }\n } finally {\n // Ensure cleanup even if connectWs throws\n resourceCleanup();\n }\n }\n }\n\n private processTranscript(data: SttTranscriptEvent, isFinal: boolean) {\n // Check if queue is closed to avoid race condition during disconnect\n if (this.queue.closed) return;\n\n const requestId = data.session_id || this.requestId;\n const text = data.transcript;\n const language = data.language || this.opts.language || 'en';\n\n if (!text && !isFinal) return;\n\n try {\n // We'll have a more accurate way of detecting when speech started when we have VAD\n if (!this.speaking) {\n this.speaking = true;\n this.queue.put({ type: SpeechEventType.START_OF_SPEECH });\n }\n\n const speechData: SpeechData = {\n language,\n startTime: this.startTimeOffset + data.start,\n endTime: this.startTimeOffset + data.start + data.duration,\n confidence: data.confidence,\n text,\n words: data.words.map(\n (word): TimedString =>\n createTimedString({\n text: word.word,\n startTime: word.start + this.startTimeOffset,\n endTime: word.end + this.startTimeOffset,\n startTimeOffset: this.startTimeOffset,\n confidence: word.confidence,\n }),\n ),\n };\n\n if (isFinal) {\n if (this.speechDuration > 0) {\n this.queue.put({\n type: SpeechEventType.RECOGNITION_USAGE,\n requestId,\n recognitionUsage: { audioDuration: this.speechDuration },\n });\n this.speechDuration = 0;\n }\n\n this.queue.put({\n type: SpeechEventType.FINAL_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n\n if (this.speaking) {\n this.speaking = false;\n this.queue.put({ type: SpeechEventType.END_OF_SPEECH });\n }\n } else {\n this.queue.put({\n type: SpeechEventType.INTERIM_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n }\n } catch (e) {\n if (e instanceof Error && e.message.includes('Queue is closed')) {\n // Expected behavior on disconnect, log as warning\n this.#logger.warn(\n { err: e },\n 'Queue closed during transcript processing (expected during disconnect)',\n );\n } else {\n this.#logger.error({ err: e }, 'Error putting transcript to queue');\n }\n }\n }\n}\n"],"mappings":"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","names":["import_utils","BaseSTT","BaseSpeechStream","ws"]}
1
+ {"version":3,"sources":["../../src/inference/stt.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { type AudioFrame } from '@livekit/rtc-node';\nimport type { WebSocket } from 'ws';\nimport { APIError, APIStatusError } from '../_exceptions.js';\nimport { AudioByteStream } from '../audio.js';\nimport { log } from '../log.js';\nimport { createStreamChannel } from '../stream/stream_channel.js';\nimport {\n STT as BaseSTT,\n SpeechStream as BaseSpeechStream,\n type SpeechData,\n type SpeechEvent,\n SpeechEventType,\n} from '../stt/index.js';\nimport { type APIConnectOptions, DEFAULT_API_CONNECT_OPTIONS } from '../types.js';\nimport { type AudioBuffer, Event, Task, cancelAndWait, shortuuid, waitForAbort } from '../utils.js';\nimport { type TimedString, createTimedString } from '../voice/io.js';\nimport {\n type SttServerEvent,\n type SttTranscriptEvent,\n sttServerEventSchema,\n} from './api_protos.js';\nimport { type AnyString, connectWs, createAccessToken } from './utils.js';\n\nexport type DeepgramModels =\n | 'deepgram/flux-general'\n | 'deepgram/nova-3'\n | 'deepgram/nova-3-medical'\n | 'deepgram/nova-2'\n | 'deepgram/nova-2-medical'\n | 'deepgram/nova-2-conversationalai'\n | 'deepgram/nova-2-phonecall';\n\nexport type CartesiaModels = 'cartesia/ink-whisper';\n\nexport type AssemblyaiModels =\n | 'assemblyai/universal-streaming'\n | 'assemblyai/universal-streaming-multilingual';\n\nexport type ElevenlabsSTTModels = 'elevenlabs/scribe_v2_realtime';\n\nexport interface CartesiaOptions {\n /** Minimum volume threshold. Default: not specified. */\n min_volume?: number;\n /** Maximum silence duration in seconds. Default: not specified. */\n max_silence_duration_secs?: number;\n}\n\nexport interface DeepgramOptions {\n /** Enable filler words. Default: true. */\n filler_words?: boolean;\n /** Enable interim results. Default: true. */\n interim_results?: boolean;\n /** Endpointing timeout in milliseconds. Default: 25. */\n endpointing?: number;\n /** Enable punctuation. Default: false. */\n punctuate?: boolean;\n /** Enable smart formatting. */\n smart_format?: boolean;\n /** Keywords with boost values. */\n keywords?: Array<[string, number]>;\n /** Key terms for recognition. */\n keyterms?: string[];\n /** Enable profanity filter. */\n profanity_filter?: boolean;\n /** Convert spoken numbers to numerals. */\n numerals?: boolean;\n /** Opt out of model improvement program. */\n mip_opt_out?: boolean;\n}\n\nexport interface AssemblyAIOptions {\n /** Enable turn formatting. Default: false. */\n format_turns?: boolean;\n /** End of turn confidence threshold. Default: 0.01. */\n end_of_turn_confidence_threshold?: number;\n /** Minimum silence duration in milliseconds when confident about end of turn. Default: 0. */\n min_end_of_turn_silence_when_confident?: number;\n /** Maximum turn silence in milliseconds. Default: not specified. */\n max_turn_silence?: number;\n /** Key terms prompt for recognition. Default: not specified. */\n keyterms_prompt?: string[];\n}\n\nexport type STTLanguages =\n | 'multi'\n | 'en'\n | 'de'\n | 'es'\n | 'fr'\n | 'ja'\n | 'pt'\n | 'zh'\n | 'hi'\n | AnyString;\n\ntype _STTModels = DeepgramModels | CartesiaModels | AssemblyaiModels | ElevenlabsSTTModels;\n\nexport type STTModels = _STTModels | 'auto' | AnyString;\n\nexport type ModelWithLanguage = `${_STTModels}:${STTLanguages}` | STTModels;\n\nexport type STTOptions<TModel extends STTModels> = TModel extends DeepgramModels\n ? DeepgramOptions\n : TModel extends CartesiaModels\n ? CartesiaOptions\n : TModel extends AssemblyaiModels\n ? AssemblyAIOptions\n : Record<string, unknown>;\n\n/** A fallback model with optional extra configuration. Extra fields are passed through to the provider. */\nexport interface STTFallbackModel {\n /** Model name (e.g. \"deepgram/nova-3\", \"assemblyai/universal-streaming\", \"cartesia/ink-whisper\"). */\n model: string;\n /** Extra configuration for the model. */\n extraKwargs?: Record<string, unknown>;\n}\n\nexport type STTFallbackModelType = STTFallbackModel | string;\n\n/** Parse a model string into [model, language]. Language is undefined if not specified. */\nexport function parseSTTModelString(model: string): [string, string | undefined] {\n const idx = model.lastIndexOf(':');\n if (idx !== -1) {\n return [model.slice(0, idx), model.slice(idx + 1)];\n }\n return [model, undefined];\n}\n\n/** Normalize a single or list of FallbackModelType into STTFallbackModel[]. */\nexport function normalizeSTTFallback(\n fallback: STTFallbackModelType | STTFallbackModelType[],\n): STTFallbackModel[] {\n const makeFallback = (model: STTFallbackModelType): STTFallbackModel => {\n if (typeof model === 'string') {\n const [name] = parseSTTModelString(model);\n return { model: name };\n }\n return model;\n };\n\n if (Array.isArray(fallback)) {\n return fallback.map(makeFallback);\n }\n return [makeFallback(fallback)];\n}\n\nexport type STTEncoding = 'pcm_s16le';\n\nconst DEFAULT_ENCODING: STTEncoding = 'pcm_s16le';\nconst DEFAULT_SAMPLE_RATE = 16000;\nconst DEFAULT_BASE_URL = 'wss://agent-gateway.livekit.cloud/v1';\nconst DEFAULT_CANCEL_TIMEOUT = 5000;\n\nexport interface InferenceSTTOptions<TModel extends STTModels> {\n model?: TModel;\n language?: STTLanguages;\n encoding: STTEncoding;\n sampleRate: number;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: STTOptions<TModel>;\n fallback?: STTFallbackModel[];\n connOptions?: APIConnectOptions;\n}\n\n/**\n * Livekit Cloud Inference STT\n */\nexport class STT<TModel extends STTModels> extends BaseSTT {\n private opts: InferenceSTTOptions<TModel>;\n private streams: Set<SpeechStream<TModel>> = new Set();\n\n #logger = log();\n\n constructor(opts?: {\n model?: TModel;\n language?: STTLanguages;\n baseURL?: string;\n encoding?: STTEncoding;\n sampleRate?: number;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: STTOptions<TModel>;\n fallback?: STTFallbackModelType | STTFallbackModelType[];\n connOptions?: APIConnectOptions;\n }) {\n super({ streaming: true, interimResults: true, alignedTranscript: 'word' });\n\n const {\n model,\n language,\n baseURL,\n encoding = DEFAULT_ENCODING,\n sampleRate = DEFAULT_SAMPLE_RATE,\n apiKey,\n apiSecret,\n modelOptions = {} as STTOptions<TModel>,\n fallback,\n connOptions,\n } = opts || {};\n\n const lkBaseURL = baseURL || process.env.LIVEKIT_INFERENCE_URL || DEFAULT_BASE_URL;\n const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY;\n if (!lkApiKey) {\n throw new Error('apiKey is required: pass apiKey or set LIVEKIT_API_KEY');\n }\n\n const lkApiSecret =\n apiSecret || process.env.LIVEKIT_INFERENCE_API_SECRET || process.env.LIVEKIT_API_SECRET;\n if (!lkApiSecret) {\n throw new Error('apiSecret is required: pass apiSecret or set LIVEKIT_API_SECRET');\n }\n\n const normalizedFallback = fallback ? normalizeSTTFallback(fallback) : undefined;\n\n this.opts = {\n model,\n language,\n encoding,\n sampleRate,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions,\n fallback: normalizedFallback,\n connOptions: connOptions ?? DEFAULT_API_CONNECT_OPTIONS,\n };\n }\n\n get label(): string {\n return 'inference.STT';\n }\n\n static fromModelString(modelString: string): STT<AnyString> {\n const [model, language] = parseSTTModelString(modelString);\n return new STT({ model, language });\n }\n\n protected async _recognize(_: AudioBuffer): Promise<SpeechEvent> {\n throw new Error('LiveKit STT does not support batch recognition, use stream() instead');\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n\n for (const stream of this.streams) {\n stream.updateOptions(opts);\n }\n }\n\n stream(options?: {\n language?: STTLanguages | string;\n connOptions?: APIConnectOptions;\n }): SpeechStream<TModel> {\n const { language, connOptions = this.opts.connOptions ?? DEFAULT_API_CONNECT_OPTIONS } =\n options || {};\n const streamOpts = {\n ...this.opts,\n language: language ?? this.opts.language,\n } as InferenceSTTOptions<TModel>;\n\n const stream = new SpeechStream(this, streamOpts, connOptions);\n this.streams.add(stream);\n\n return stream;\n }\n\n async connectWs(timeout: number): Promise<WebSocket> {\n const params = {\n settings: {\n sample_rate: String(this.opts.sampleRate),\n encoding: this.opts.encoding,\n extra: this.opts.modelOptions,\n },\n } as Record<string, unknown>;\n\n if (this.opts.model && this.opts.model !== 'auto') {\n params.model = this.opts.model;\n }\n\n if (this.opts.language) {\n (params.settings as Record<string, unknown>).language = this.opts.language;\n }\n\n if (this.opts.fallback?.length) {\n params.fallback = {\n models: this.opts.fallback.map((m) => ({\n model: m.model,\n extra: m.extraKwargs ?? {},\n })),\n };\n }\n\n if (this.opts.connOptions) {\n params.connection = {\n timeout: this.opts.connOptions.timeoutMs / 1000,\n retries: this.opts.connOptions.maxRetry,\n };\n }\n\n let baseURL = this.opts.baseURL;\n if (baseURL.startsWith('http://') || baseURL.startsWith('https://')) {\n baseURL = baseURL.replace('http', 'ws');\n }\n\n const token = await createAccessToken(this.opts.apiKey, this.opts.apiSecret);\n const url = `${baseURL}/stt`;\n const headers = { Authorization: `Bearer ${token}` } as Record<string, string>;\n\n const socket = await connectWs(url, headers, timeout);\n const msg = { ...params, type: 'session.create' };\n socket.send(JSON.stringify(msg));\n\n return socket;\n }\n}\n\nexport class SpeechStream<TModel extends STTModels> extends BaseSpeechStream {\n private opts: InferenceSTTOptions<TModel>;\n private requestId = shortuuid('stt_request_');\n private speaking = false;\n private speechDuration = 0;\n private reconnectEvent = new Event();\n private stt: STT<TModel>;\n private connOptions: APIConnectOptions;\n\n #logger = log();\n\n constructor(\n sttImpl: STT<TModel>,\n opts: InferenceSTTOptions<TModel>,\n connOptions: APIConnectOptions,\n ) {\n super(sttImpl, opts.sampleRate, connOptions);\n this.opts = opts;\n this.stt = sttImpl;\n this.connOptions = connOptions;\n }\n\n get label(): string {\n return 'inference.SpeechStream';\n }\n\n updateOptions(opts: Partial<Pick<InferenceSTTOptions<TModel>, 'model' | 'language'>>): void {\n this.opts = { ...this.opts, ...opts };\n this.reconnectEvent.set();\n }\n\n protected async run(): Promise<void> {\n while (true) {\n // Create fresh resources for each connection attempt\n let ws: WebSocket | null = null;\n let closing = false;\n let finalReceived = false;\n\n const eventChannel = createStreamChannel<SttServerEvent>();\n\n const resourceCleanup = () => {\n if (closing) return;\n closing = true;\n eventChannel.close();\n ws?.removeAllListeners();\n ws?.close();\n };\n\n const createWsListener = async (ws: WebSocket, signal: AbortSignal) => {\n return new Promise<void>((resolve, reject) => {\n const onAbort = () => {\n resourceCleanup();\n reject(new Error('WebSocket connection aborted'));\n };\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n ws.on('message', (data) => {\n const json = JSON.parse(data.toString()) as SttServerEvent;\n eventChannel.write(json);\n });\n\n ws.on('error', (e) => {\n this.#logger.error({ error: e }, 'WebSocket error');\n resourceCleanup();\n reject(e);\n });\n\n ws.on('close', (code: number) => {\n resourceCleanup();\n\n if (!closing) return this.#logger.error('WebSocket closed unexpectedly');\n if (finalReceived) return resolve();\n\n reject(\n new APIStatusError({\n message: 'LiveKit STT connection closed unexpectedly',\n options: { statusCode: code },\n }),\n );\n });\n });\n };\n\n const send = async (socket: WebSocket, signal: AbortSignal) => {\n const audioStream = new AudioByteStream(\n this.opts.sampleRate,\n 1,\n Math.floor(this.opts.sampleRate / 20), // 50ms\n );\n\n // Create abort promise once to avoid memory leak\n const abortPromise = new Promise<never>((_, reject) => {\n if (signal.aborted) {\n return reject(new Error('Send aborted'));\n }\n const onAbort = () => reject(new Error('Send aborted'));\n signal.addEventListener('abort', onAbort, { once: true });\n });\n\n // Manual iteration to support cancellation\n const iterator = this.input[Symbol.asyncIterator]();\n try {\n while (true) {\n const result = await Promise.race([iterator.next(), abortPromise]);\n\n if (result.done) break;\n const ev = result.value;\n\n let frames: AudioFrame[];\n if (ev === SpeechStream.FLUSH_SENTINEL) {\n frames = audioStream.flush();\n } else {\n const frame = ev as AudioFrame;\n frames = audioStream.write(new Int16Array(frame.data).buffer);\n }\n\n for (const frame of frames) {\n this.speechDuration += frame.samplesPerChannel / frame.sampleRate;\n const base64 = Buffer.from(frame.data.buffer).toString('base64');\n const msg = { type: 'input_audio', audio: base64 };\n socket.send(JSON.stringify(msg));\n }\n }\n\n closing = true;\n socket.send(JSON.stringify({ type: 'session.finalize' }));\n } catch (e) {\n if ((e as Error).message === 'Send aborted') {\n // Expected abort, don't log\n return;\n }\n throw e;\n }\n };\n\n const recv = async (signal: AbortSignal) => {\n const serverEventStream = eventChannel.stream();\n const reader = serverEventStream.getReader();\n\n try {\n while (!this.closed && !signal.aborted) {\n const result = await reader.read();\n if (signal.aborted) return;\n if (result.done) return;\n\n // Parse and validate with Zod schema\n const parseResult = await sttServerEventSchema.safeParseAsync(result.value);\n if (!parseResult.success) {\n this.#logger.warn(\n { error: parseResult.error, rawData: result.value },\n 'Failed to parse STT server event',\n );\n continue;\n }\n\n const event: SttServerEvent = parseResult.data;\n\n switch (event.type) {\n case 'session.created':\n case 'session.finalized':\n break;\n case 'session.closed':\n finalReceived = true;\n resourceCleanup();\n break;\n case 'interim_transcript':\n this.processTranscript(event, false);\n break;\n case 'final_transcript':\n this.processTranscript(event, true);\n break;\n case 'error':\n this.#logger.error({ error: event }, 'Received error from LiveKit STT');\n resourceCleanup();\n throw new APIError(`LiveKit STT returned error: ${JSON.stringify(event)}`);\n }\n }\n } finally {\n reader.releaseLock();\n try {\n await serverEventStream.cancel();\n } catch (e) {\n this.#logger.debug('Error cancelling serverEventStream (may already be cancelled):', e);\n }\n }\n };\n\n try {\n ws = await this.stt.connectWs(this.connOptions.timeoutMs);\n\n const controller = this.abortController; // Use base class abortController for proper cancellation\n const sendTask = Task.from(({ signal }) => send(ws!, signal), controller);\n const wsListenerTask = Task.from(({ signal }) => createWsListener(ws!, signal), controller);\n const recvTask = Task.from(({ signal }) => recv(signal), controller);\n const waitReconnectTask = Task.from(\n ({ signal }) => Promise.race([this.reconnectEvent.wait(), waitForAbort(signal)]),\n controller,\n );\n\n try {\n await Promise.race([\n Promise.all([sendTask.result, wsListenerTask.result, recvTask.result]),\n waitReconnectTask.result,\n ]);\n\n // If reconnect didn't trigger, tasks finished - exit loop\n if (!waitReconnectTask.done) break;\n\n // Reconnect triggered - clear event and continue loop\n this.reconnectEvent.clear();\n } finally {\n // Cancel all tasks to ensure cleanup\n await cancelAndWait(\n [sendTask, wsListenerTask, recvTask, waitReconnectTask],\n DEFAULT_CANCEL_TIMEOUT,\n );\n resourceCleanup();\n }\n } finally {\n // Ensure cleanup even if connectWs throws\n resourceCleanup();\n }\n }\n }\n\n private processTranscript(data: SttTranscriptEvent, isFinal: boolean) {\n // Check if queue is closed to avoid race condition during disconnect\n if (this.queue.closed) return;\n\n const requestId = data.session_id || this.requestId;\n const text = data.transcript;\n const language = data.language || this.opts.language || 'en';\n\n if (!text && !isFinal) return;\n\n try {\n // We'll have a more accurate way of detecting when speech started when we have VAD\n if (!this.speaking) {\n this.speaking = true;\n this.queue.put({ type: SpeechEventType.START_OF_SPEECH });\n }\n\n const speechData: SpeechData = {\n language,\n startTime: this.startTimeOffset + data.start,\n endTime: this.startTimeOffset + data.start + data.duration,\n confidence: data.confidence,\n text,\n words: data.words.map(\n (word): TimedString =>\n createTimedString({\n text: word.word,\n startTime: word.start + this.startTimeOffset,\n endTime: word.end + this.startTimeOffset,\n startTimeOffset: this.startTimeOffset,\n confidence: word.confidence,\n }),\n ),\n };\n\n if (isFinal) {\n if (this.speechDuration > 0) {\n this.queue.put({\n type: SpeechEventType.RECOGNITION_USAGE,\n requestId,\n recognitionUsage: { audioDuration: this.speechDuration },\n });\n this.speechDuration = 0;\n }\n\n this.queue.put({\n type: SpeechEventType.FINAL_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n\n if (this.speaking) {\n this.speaking = false;\n this.queue.put({ type: SpeechEventType.END_OF_SPEECH });\n }\n } else {\n this.queue.put({\n type: SpeechEventType.INTERIM_TRANSCRIPT,\n requestId,\n alternatives: [speechData],\n });\n }\n } catch (e) {\n if (e instanceof Error && e.message.includes('Queue is closed')) {\n // Expected behavior on disconnect, log as warning\n this.#logger.warn(\n { err: e },\n 'Queue closed during transcript processing (expected during disconnect)',\n );\n } else {\n this.#logger.error({ err: e }, 'Error putting transcript to queue');\n }\n }\n }\n}\n"],"mappings":"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","names":["import_utils","BaseSTT","BaseSpeechStream","ws"]}
@@ -8,26 +8,43 @@ export type CartesiaModels = 'cartesia/ink-whisper';
8
8
  export type AssemblyaiModels = 'assemblyai/universal-streaming' | 'assemblyai/universal-streaming-multilingual';
9
9
  export type ElevenlabsSTTModels = 'elevenlabs/scribe_v2_realtime';
10
10
  export interface CartesiaOptions {
11
+ /** Minimum volume threshold. Default: not specified. */
11
12
  min_volume?: number;
13
+ /** Maximum silence duration in seconds. Default: not specified. */
12
14
  max_silence_duration_secs?: number;
13
15
  }
14
16
  export interface DeepgramOptions {
17
+ /** Enable filler words. Default: true. */
15
18
  filler_words?: boolean;
19
+ /** Enable interim results. Default: true. */
16
20
  interim_results?: boolean;
21
+ /** Endpointing timeout in milliseconds. Default: 25. */
17
22
  endpointing?: number;
23
+ /** Enable punctuation. Default: false. */
18
24
  punctuate?: boolean;
25
+ /** Enable smart formatting. */
19
26
  smart_format?: boolean;
27
+ /** Keywords with boost values. */
20
28
  keywords?: Array<[string, number]>;
29
+ /** Key terms for recognition. */
21
30
  keyterms?: string[];
31
+ /** Enable profanity filter. */
22
32
  profanity_filter?: boolean;
33
+ /** Convert spoken numbers to numerals. */
23
34
  numerals?: boolean;
35
+ /** Opt out of model improvement program. */
24
36
  mip_opt_out?: boolean;
25
37
  }
26
38
  export interface AssemblyAIOptions {
39
+ /** Enable turn formatting. Default: false. */
27
40
  format_turns?: boolean;
41
+ /** End of turn confidence threshold. Default: 0.01. */
28
42
  end_of_turn_confidence_threshold?: number;
43
+ /** Minimum silence duration in milliseconds when confident about end of turn. Default: 0. */
29
44
  min_end_of_turn_silence_when_confident?: number;
45
+ /** Maximum turn silence in milliseconds. Default: not specified. */
30
46
  max_turn_silence?: number;
47
+ /** Key terms prompt for recognition. Default: not specified. */
31
48
  keyterms_prompt?: string[];
32
49
  }
33
50
  export type STTLanguages = 'multi' | 'en' | 'de' | 'es' | 'fr' | 'ja' | 'pt' | 'zh' | 'hi' | AnyString;
@@ -35,6 +52,18 @@ type _STTModels = DeepgramModels | CartesiaModels | AssemblyaiModels | Elevenlab
35
52
  export type STTModels = _STTModels | 'auto' | AnyString;
36
53
  export type ModelWithLanguage = `${_STTModels}:${STTLanguages}` | STTModels;
37
54
  export type STTOptions<TModel extends STTModels> = TModel extends DeepgramModels ? DeepgramOptions : TModel extends CartesiaModels ? CartesiaOptions : TModel extends AssemblyaiModels ? AssemblyAIOptions : Record<string, unknown>;
55
+ /** A fallback model with optional extra configuration. Extra fields are passed through to the provider. */
56
+ export interface STTFallbackModel {
57
+ /** Model name (e.g. "deepgram/nova-3", "assemblyai/universal-streaming", "cartesia/ink-whisper"). */
58
+ model: string;
59
+ /** Extra configuration for the model. */
60
+ extraKwargs?: Record<string, unknown>;
61
+ }
62
+ export type STTFallbackModelType = STTFallbackModel | string;
63
+ /** Parse a model string into [model, language]. Language is undefined if not specified. */
64
+ export declare function parseSTTModelString(model: string): [string, string | undefined];
65
+ /** Normalize a single or list of FallbackModelType into STTFallbackModel[]. */
66
+ export declare function normalizeSTTFallback(fallback: STTFallbackModelType | STTFallbackModelType[]): STTFallbackModel[];
38
67
  export type STTEncoding = 'pcm_s16le';
39
68
  export interface InferenceSTTOptions<TModel extends STTModels> {
40
69
  model?: TModel;
@@ -45,6 +74,8 @@ export interface InferenceSTTOptions<TModel extends STTModels> {
45
74
  apiKey: string;
46
75
  apiSecret: string;
47
76
  modelOptions: STTOptions<TModel>;
77
+ fallback?: STTFallbackModel[];
78
+ connOptions?: APIConnectOptions;
48
79
  }
49
80
  /**
50
81
  * Livekit Cloud Inference STT
@@ -62,6 +93,8 @@ export declare class STT<TModel extends STTModels> extends BaseSTT {
62
93
  apiKey?: string;
63
94
  apiSecret?: string;
64
95
  modelOptions?: STTOptions<TModel>;
96
+ fallback?: STTFallbackModelType | STTFallbackModelType[];
97
+ connOptions?: APIConnectOptions;
65
98
  });
66
99
  get label(): string;
67
100
  static fromModelString(modelString: string): STT<AnyString>;
@@ -8,26 +8,43 @@ export type CartesiaModels = 'cartesia/ink-whisper';
8
8
  export type AssemblyaiModels = 'assemblyai/universal-streaming' | 'assemblyai/universal-streaming-multilingual';
9
9
  export type ElevenlabsSTTModels = 'elevenlabs/scribe_v2_realtime';
10
10
  export interface CartesiaOptions {
11
+ /** Minimum volume threshold. Default: not specified. */
11
12
  min_volume?: number;
13
+ /** Maximum silence duration in seconds. Default: not specified. */
12
14
  max_silence_duration_secs?: number;
13
15
  }
14
16
  export interface DeepgramOptions {
17
+ /** Enable filler words. Default: true. */
15
18
  filler_words?: boolean;
19
+ /** Enable interim results. Default: true. */
16
20
  interim_results?: boolean;
21
+ /** Endpointing timeout in milliseconds. Default: 25. */
17
22
  endpointing?: number;
23
+ /** Enable punctuation. Default: false. */
18
24
  punctuate?: boolean;
25
+ /** Enable smart formatting. */
19
26
  smart_format?: boolean;
27
+ /** Keywords with boost values. */
20
28
  keywords?: Array<[string, number]>;
29
+ /** Key terms for recognition. */
21
30
  keyterms?: string[];
31
+ /** Enable profanity filter. */
22
32
  profanity_filter?: boolean;
33
+ /** Convert spoken numbers to numerals. */
23
34
  numerals?: boolean;
35
+ /** Opt out of model improvement program. */
24
36
  mip_opt_out?: boolean;
25
37
  }
26
38
  export interface AssemblyAIOptions {
39
+ /** Enable turn formatting. Default: false. */
27
40
  format_turns?: boolean;
41
+ /** End of turn confidence threshold. Default: 0.01. */
28
42
  end_of_turn_confidence_threshold?: number;
43
+ /** Minimum silence duration in milliseconds when confident about end of turn. Default: 0. */
29
44
  min_end_of_turn_silence_when_confident?: number;
45
+ /** Maximum turn silence in milliseconds. Default: not specified. */
30
46
  max_turn_silence?: number;
47
+ /** Key terms prompt for recognition. Default: not specified. */
31
48
  keyterms_prompt?: string[];
32
49
  }
33
50
  export type STTLanguages = 'multi' | 'en' | 'de' | 'es' | 'fr' | 'ja' | 'pt' | 'zh' | 'hi' | AnyString;
@@ -35,6 +52,18 @@ type _STTModels = DeepgramModels | CartesiaModels | AssemblyaiModels | Elevenlab
35
52
  export type STTModels = _STTModels | 'auto' | AnyString;
36
53
  export type ModelWithLanguage = `${_STTModels}:${STTLanguages}` | STTModels;
37
54
  export type STTOptions<TModel extends STTModels> = TModel extends DeepgramModels ? DeepgramOptions : TModel extends CartesiaModels ? CartesiaOptions : TModel extends AssemblyaiModels ? AssemblyAIOptions : Record<string, unknown>;
55
+ /** A fallback model with optional extra configuration. Extra fields are passed through to the provider. */
56
+ export interface STTFallbackModel {
57
+ /** Model name (e.g. "deepgram/nova-3", "assemblyai/universal-streaming", "cartesia/ink-whisper"). */
58
+ model: string;
59
+ /** Extra configuration for the model. */
60
+ extraKwargs?: Record<string, unknown>;
61
+ }
62
+ export type STTFallbackModelType = STTFallbackModel | string;
63
+ /** Parse a model string into [model, language]. Language is undefined if not specified. */
64
+ export declare function parseSTTModelString(model: string): [string, string | undefined];
65
+ /** Normalize a single or list of FallbackModelType into STTFallbackModel[]. */
66
+ export declare function normalizeSTTFallback(fallback: STTFallbackModelType | STTFallbackModelType[]): STTFallbackModel[];
38
67
  export type STTEncoding = 'pcm_s16le';
39
68
  export interface InferenceSTTOptions<TModel extends STTModels> {
40
69
  model?: TModel;
@@ -45,6 +74,8 @@ export interface InferenceSTTOptions<TModel extends STTModels> {
45
74
  apiKey: string;
46
75
  apiSecret: string;
47
76
  modelOptions: STTOptions<TModel>;
77
+ fallback?: STTFallbackModel[];
78
+ connOptions?: APIConnectOptions;
48
79
  }
49
80
  /**
50
81
  * Livekit Cloud Inference STT
@@ -62,6 +93,8 @@ export declare class STT<TModel extends STTModels> extends BaseSTT {
62
93
  apiKey?: string;
63
94
  apiSecret?: string;
64
95
  modelOptions?: STTOptions<TModel>;
96
+ fallback?: STTFallbackModelType | STTFallbackModelType[];
97
+ connOptions?: APIConnectOptions;
65
98
  });
66
99
  get label(): string;
67
100
  static fromModelString(modelString: string): STT<AnyString>;
@@ -1 +1 @@
1
- {"version":3,"file":"stt.d.ts","sourceRoot":"","sources":["../../src/inference/stt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stt.d.ts","sourceRoot":"","sources":["../../src/inference/stt.ts"],"names":[],"mappings":"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"}