@livekit/agents-plugin-deepgram 1.0.31 → 1.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -17,6 +17,7 @@ var index_exports = {};
17
17
  module.exports = __toCommonJS(index_exports);
18
18
  var import_agents = require("@livekit/agents");
19
19
  __reExport(index_exports, require("./stt.cjs"), module.exports);
20
+ __reExport(index_exports, require("./stt_v2.cjs"), module.exports);
20
21
  __reExport(index_exports, require("./tts.cjs"), module.exports);
21
22
  class DeepgramPlugin extends import_agents.Plugin {
22
23
  constructor() {
@@ -31,6 +32,7 @@ import_agents.Plugin.registerPlugin(new DeepgramPlugin());
31
32
  // Annotate the CommonJS export names for ESM import in node:
32
33
  0 && (module.exports = {
33
34
  ...require("./stt.cjs"),
35
+ ...require("./stt_v2.cjs"),
34
36
  ...require("./tts.cjs")
35
37
  });
36
38
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Plugin } from '@livekit/agents';\n\nexport * from './stt.js';\nexport * from './tts.js';\n\nclass DeepgramPlugin extends Plugin {\n constructor() {\n super({\n title: 'deepgram',\n version: '0.5.6',\n package: '@livekit/agents-plugin-deepgram',\n });\n }\n}\n\nPlugin.registerPlugin(new DeepgramPlugin());\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAGA,oBAAuB;AAEvB,0BAAc,qBALd;AAMA,0BAAc,qBANd;AAQA,MAAM,uBAAuB,qBAAO;AAAA,EAClC,cAAc;AACZ,UAAM;AAAA,MACJ,OAAO;AAAA,MACP,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAEA,qBAAO,eAAe,IAAI,eAAe,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Plugin } from '@livekit/agents';\n\nexport * from './stt.js';\nexport * from './stt_v2.js';\nexport * from './tts.js';\n\nclass DeepgramPlugin extends Plugin {\n constructor() {\n super({\n title: 'deepgram',\n version: '0.5.6',\n package: '@livekit/agents-plugin-deepgram',\n });\n }\n}\n\nPlugin.registerPlugin(new DeepgramPlugin());\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAGA,oBAAuB;AAEvB,0BAAc,qBALd;AAMA,0BAAc,wBANd;AAOA,0BAAc,qBAPd;AASA,MAAM,uBAAuB,qBAAO;AAAA,EAClC,cAAc;AACZ,UAAM;AAAA,MACJ,OAAO;AAAA,MACP,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAEA,qBAAO,eAAe,IAAI,eAAe,CAAC;","names":[]}
package/dist/index.d.cts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './stt.js';
2
+ export * from './stt_v2.js';
2
3
  export * from './tts.js';
3
4
  //# sourceMappingURL=index.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './stt.js';
2
+ export * from './stt_v2.js';
2
3
  export * from './tts.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Plugin } from "@livekit/agents";
2
2
  export * from "./stt.js";
3
+ export * from "./stt_v2.js";
3
4
  export * from "./tts.js";
4
5
  class DeepgramPlugin extends Plugin {
5
6
  constructor() {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Plugin } from '@livekit/agents';\n\nexport * from './stt.js';\nexport * from './tts.js';\n\nclass DeepgramPlugin extends Plugin {\n constructor() {\n super({\n title: 'deepgram',\n version: '0.5.6',\n package: '@livekit/agents-plugin-deepgram',\n });\n }\n}\n\nPlugin.registerPlugin(new DeepgramPlugin());\n"],"mappings":"AAGA,SAAS,cAAc;AAEvB,cAAc;AACd,cAAc;AAEd,MAAM,uBAAuB,OAAO;AAAA,EAClC,cAAc;AACZ,UAAM;AAAA,MACJ,OAAO;AAAA,MACP,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAEA,OAAO,eAAe,IAAI,eAAe,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Plugin } from '@livekit/agents';\n\nexport * from './stt.js';\nexport * from './stt_v2.js';\nexport * from './tts.js';\n\nclass DeepgramPlugin extends Plugin {\n constructor() {\n super({\n title: 'deepgram',\n version: '0.5.6',\n package: '@livekit/agents-plugin-deepgram',\n });\n }\n}\n\nPlugin.registerPlugin(new DeepgramPlugin());\n"],"mappings":"AAGA,SAAS,cAAc;AAEvB,cAAc;AACd,cAAc;AACd,cAAc;AAEd,MAAM,uBAAuB,OAAO;AAAA,EAClC,cAAc;AACZ,UAAM;AAAA,MACJ,OAAO;AAAA,MACP,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAEA,OAAO,eAAe,IAAI,eAAe,CAAC;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/models.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\nexport type TTSModels =\n | 'aura-asteria-en'\n | 'aura-luna-en'\n | 'aura-stella-en'\n | 'aura-athena-en'\n | 'aura-hera-en'\n | 'aura-orion-en'\n | 'aura-arcas-en'\n | 'aura-perseus-en'\n | 'aura-angus-en'\n | 'aura-orpheus-en'\n | 'aura-helios-en'\n | 'aura-zeus-en';\n\nexport type TTSEncoding = 'linear16' | 'mulaw' | 'alaw' | 'mp3' | 'opus' | 'flac' | 'aac';\n\nexport type STTModels =\n | 'nova-general'\n | 'nova-phonecall'\n | 'nova-meeting'\n | 'nova-2-general'\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'\n | 'nova-3-general'\n | 'nova-3-medical'\n | 'enhanced-general'\n | 'enhanced-meeting'\n | 'enhanced-phonecall'\n | 'enhanced-finance'\n | 'base'\n | 'meeting'\n | 'phonecall'\n | 'finance'\n | 'conversationalai'\n | 'voicemail'\n | 'video'\n | 'whisper-tiny'\n | 'whisper-base'\n | 'whisper-small'\n | 'whisper-medium'\n | 'whisper-large';\n\nexport type STTLanguages =\n | 'da'\n | 'de'\n | 'en'\n | 'en-AU'\n | 'en-GB'\n | 'en-IN'\n | 'en-NZ'\n | 'en-US'\n | 'es'\n | 'es-419'\n | 'es-LATAM'\n | 'fr'\n | 'fr-CA'\n | 'hi'\n | 'hi-Latn'\n | 'id'\n | 'it'\n | 'ja'\n | 'ko'\n | 'nl'\n | 'no'\n | 'pl'\n | 'pt'\n | 'pt-BR'\n | 'ru'\n | 'sv'\n | 'ta'\n | 'taq'\n | 'th'\n | 'tr'\n | 'uk'\n | 'zh'\n | 'zh-CN'\n | 'zh-TW'\n | 'multi';\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../src/models.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\nexport type TTSModels =\n | 'aura-asteria-en'\n | 'aura-luna-en'\n | 'aura-stella-en'\n | 'aura-athena-en'\n | 'aura-hera-en'\n | 'aura-orion-en'\n | 'aura-arcas-en'\n | 'aura-perseus-en'\n | 'aura-angus-en'\n | 'aura-orpheus-en'\n | 'aura-helios-en'\n | 'aura-zeus-en';\n\nexport type TTSEncoding = 'linear16' | 'mulaw' | 'alaw' | 'mp3' | 'opus' | 'flac' | 'aac';\n\nexport type V2Models = 'flux-general-en';\n\nexport type STTModels =\n | 'nova-general'\n | 'nova-phonecall'\n | 'nova-meeting'\n | 'nova-2-general'\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'\n | 'nova-3-general'\n | 'nova-3-medical'\n | 'enhanced-general'\n | 'enhanced-meeting'\n | 'enhanced-phonecall'\n | 'enhanced-finance'\n | 'base'\n | 'meeting'\n | 'phonecall'\n | 'finance'\n | 'conversationalai'\n | 'voicemail'\n | 'video'\n | 'whisper-tiny'\n | 'whisper-base'\n | 'whisper-small'\n | 'whisper-medium'\n | 'whisper-large';\n\nexport type STTLanguages =\n | 'da'\n | 'de'\n | 'en'\n | 'en-AU'\n | 'en-GB'\n | 'en-IN'\n | 'en-NZ'\n | 'en-US'\n | 'es'\n | 'es-419'\n | 'es-LATAM'\n | 'fr'\n | 'fr-CA'\n | 'hi'\n | 'hi-Latn'\n | 'id'\n | 'it'\n | 'ja'\n | 'ko'\n | 'nl'\n | 'no'\n | 'pl'\n | 'pt'\n | 'pt-BR'\n | 'ru'\n | 'sv'\n | 'ta'\n | 'taq'\n | 'th'\n | 'tr'\n | 'uk'\n | 'zh'\n | 'zh-CN'\n | 'zh-TW'\n | 'multi';\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
package/dist/models.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  export type TTSModels = 'aura-asteria-en' | 'aura-luna-en' | 'aura-stella-en' | 'aura-athena-en' | 'aura-hera-en' | 'aura-orion-en' | 'aura-arcas-en' | 'aura-perseus-en' | 'aura-angus-en' | 'aura-orpheus-en' | 'aura-helios-en' | 'aura-zeus-en';
2
2
  export type TTSEncoding = 'linear16' | 'mulaw' | 'alaw' | 'mp3' | 'opus' | 'flac' | 'aac';
3
+ export type V2Models = 'flux-general-en';
3
4
  export type STTModels = 'nova-general' | 'nova-phonecall' | 'nova-meeting' | 'nova-2-general' | 'nova-2-meeting' | 'nova-2-phonecall' | 'nova-2-finance' | 'nova-2-conversationalai' | 'nova-2-voicemail' | 'nova-2-video' | 'nova-2-medical' | 'nova-2-drivethru' | 'nova-2-automotive' | 'nova-3' | 'nova-3-general' | 'nova-3-medical' | 'enhanced-general' | 'enhanced-meeting' | 'enhanced-phonecall' | 'enhanced-finance' | 'base' | 'meeting' | 'phonecall' | 'finance' | 'conversationalai' | 'voicemail' | 'video' | 'whisper-tiny' | 'whisper-base' | 'whisper-small' | 'whisper-medium' | 'whisper-large';
4
5
  export type STTLanguages = 'da' | 'de' | 'en' | 'en-AU' | 'en-GB' | 'en-IN' | 'en-NZ' | 'en-US' | 'es' | 'es-419' | 'es-LATAM' | 'fr' | 'fr-CA' | 'hi' | 'hi-Latn' | 'id' | 'it' | 'ja' | 'ko' | 'nl' | 'no' | 'pl' | 'pt' | 'pt-BR' | 'ru' | 'sv' | 'ta' | 'taq' | 'th' | 'tr' | 'uk' | 'zh' | 'zh-CN' | 'zh-TW' | 'multi';
5
6
  //# sourceMappingURL=models.d.ts.map
package/dist/models.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export type TTSModels = 'aura-asteria-en' | 'aura-luna-en' | 'aura-stella-en' | 'aura-athena-en' | 'aura-hera-en' | 'aura-orion-en' | 'aura-arcas-en' | 'aura-perseus-en' | 'aura-angus-en' | 'aura-orpheus-en' | 'aura-helios-en' | 'aura-zeus-en';
2
2
  export type TTSEncoding = 'linear16' | 'mulaw' | 'alaw' | 'mp3' | 'opus' | 'flac' | 'aac';
3
+ export type V2Models = 'flux-general-en';
3
4
  export type STTModels = 'nova-general' | 'nova-phonecall' | 'nova-meeting' | 'nova-2-general' | 'nova-2-meeting' | 'nova-2-phonecall' | 'nova-2-finance' | 'nova-2-conversationalai' | 'nova-2-voicemail' | 'nova-2-video' | 'nova-2-medical' | 'nova-2-drivethru' | 'nova-2-automotive' | 'nova-3' | 'nova-3-general' | 'nova-3-medical' | 'enhanced-general' | 'enhanced-meeting' | 'enhanced-phonecall' | 'enhanced-finance' | 'base' | 'meeting' | 'phonecall' | 'finance' | 'conversationalai' | 'voicemail' | 'video' | 'whisper-tiny' | 'whisper-base' | 'whisper-small' | 'whisper-medium' | 'whisper-large';
4
5
  export type STTLanguages = 'da' | 'de' | 'en' | 'en-AU' | 'en-GB' | 'en-IN' | 'en-NZ' | 'en-US' | 'es' | 'es-419' | 'es-LATAM' | 'fr' | 'fr-CA' | 'hi' | 'hi-Latn' | 'id' | 'it' | 'ja' | 'ko' | 'nl' | 'no' | 'pl' | 'pt' | 'pt-BR' | 'ru' | 'sv' | 'ta' | 'taq' | 'th' | 'tr' | 'uk' | 'zh' | 'zh-CN' | 'zh-TW' | 'multi';
5
6
  //# sourceMappingURL=models.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GACjB,iBAAiB,GACjB,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,cAAc,GACd,eAAe,GACf,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,gBAAgB,GAChB,cAAc,CAAC;AAEnB,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE1F,MAAM,MAAM,SAAS,GACjB,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,yBAAyB,GACzB,kBAAkB,GAClB,cAAc,GACd,gBAAgB,GAChB,kBAAkB,GAClB,mBAAmB,GACnB,QAAQ,GACR,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,kBAAkB,GAClB,oBAAoB,GACpB,kBAAkB,GAClB,MAAM,GACN,SAAS,GACT,WAAW,GACX,SAAS,GACT,kBAAkB,GAClB,WAAW,GACX,OAAO,GACP,cAAc,GACd,cAAc,GACd,eAAe,GACf,gBAAgB,GAChB,eAAe,CAAC;AAEpB,MAAM,MAAM,YAAY,GACpB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,IAAI,GACJ,QAAQ,GACR,UAAU,GACV,IAAI,GACJ,OAAO,GACP,IAAI,GACJ,SAAS,GACT,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,OAAO,GACP,OAAO,GACP,OAAO,CAAC"}
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GACjB,iBAAiB,GACjB,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,cAAc,GACd,eAAe,GACf,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,gBAAgB,GAChB,cAAc,CAAC;AAEnB,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE1F,MAAM,MAAM,QAAQ,GAAG,iBAAiB,CAAC;AAEzC,MAAM,MAAM,SAAS,GACjB,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,yBAAyB,GACzB,kBAAkB,GAClB,cAAc,GACd,gBAAgB,GAChB,kBAAkB,GAClB,mBAAmB,GACnB,QAAQ,GACR,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,kBAAkB,GAClB,oBAAoB,GACpB,kBAAkB,GAClB,MAAM,GACN,SAAS,GACT,WAAW,GACX,SAAS,GACT,kBAAkB,GAClB,WAAW,GACX,OAAO,GACP,cAAc,GACd,cAAc,GACd,eAAe,GACf,gBAAgB,GAChB,eAAe,CAAC;AAEpB,MAAM,MAAM,YAAY,GACpB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,GACP,IAAI,GACJ,QAAQ,GACR,UAAU,GACV,IAAI,GACJ,OAAO,GACP,IAAI,GACJ,SAAS,GACT,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,OAAO,GACP,OAAO,GACP,OAAO,CAAC"}
@@ -0,0 +1,367 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var stt_v2_exports = {};
30
+ __export(stt_v2_exports, {
31
+ STTv2: () => STTv2
32
+ });
33
+ module.exports = __toCommonJS(stt_v2_exports);
34
+ var import_agents = require("@livekit/agents");
35
+ var queryString = __toESM(require("node:querystring"), 1);
36
+ var import_ws = require("ws");
37
+ var import_utils = require("./_utils.cjs");
38
+ const _CLOSE_MSG = JSON.stringify({ type: "CloseStream" });
39
+ const defaultSTTv2Options = {
40
+ model: "flux-general-en",
41
+ sampleRate: 16e3,
42
+ keyterms: [],
43
+ endpointUrl: "wss://api.deepgram.com/v2/listen",
44
+ language: "en",
45
+ mipOptOut: false
46
+ };
47
+ function validateTags(tags) {
48
+ for (const tag of tags) {
49
+ if (tag.length > 128) {
50
+ throw new Error("tag must be no more than 128 characters");
51
+ }
52
+ }
53
+ return tags;
54
+ }
55
+ class STTv2 extends import_agents.stt.STT {
56
+ label = "deepgram.STTv2";
57
+ #opts;
58
+ #apiKey;
59
+ #logger = (0, import_agents.log)();
60
+ /**
61
+ * Create a new Deepgram STTv2 instance.
62
+ *
63
+ * @param opts - Configuration options
64
+ * @param opts.apiKey - Deepgram API key (defaults to `DEEPGRAM_API_KEY` env var)
65
+ * @param opts.model - Model to use (default: `flux-general-en`)
66
+ * @param opts.eagerEotThreshold - Threshold (0.3-0.9) for preemptive generation
67
+ * @param opts.eotThreshold - End-of-turn detection threshold (default: 0.7)
68
+ * @param opts.eotTimeoutMs - End-of-turn timeout in ms (default: 3000)
69
+ * @param opts.keyterms - List of key terms to improve recognition
70
+ * @param opts.tags - Tags for usage reporting (max 128 chars each)
71
+ *
72
+ * @throws Error if no API key is provided
73
+ */
74
+ constructor(opts = {}) {
75
+ super({
76
+ streaming: true,
77
+ interimResults: true
78
+ });
79
+ this.#opts = { ...defaultSTTv2Options, ...opts };
80
+ const apiKey = opts.apiKey || process.env.DEEPGRAM_API_KEY;
81
+ if (!apiKey) {
82
+ throw new Error("Deepgram API key is required");
83
+ }
84
+ this.#apiKey = apiKey;
85
+ if (this.#opts.tags) {
86
+ this.#opts.tags = validateTags(this.#opts.tags);
87
+ }
88
+ }
89
+ /** The model being used for transcription */
90
+ get model() {
91
+ return this.#opts.model;
92
+ }
93
+ /** The STT provider name */
94
+ get provider() {
95
+ return "Deepgram";
96
+ }
97
+ async _recognize(_frame, _abortSignal) {
98
+ throw new Error("V2 API does not support non-streaming recognize. Use .stream()");
99
+ }
100
+ /**
101
+ * Create a new streaming transcription session.
102
+ *
103
+ * @param options - Stream options
104
+ * @returns A SpeechStream that emits transcription events
105
+ */
106
+ stream(options) {
107
+ const streamOpts = { ...this.#opts, apiKey: this.#apiKey };
108
+ return new SpeechStreamv2(this, streamOpts, options == null ? void 0 : options.connOptions);
109
+ }
110
+ /**
111
+ * Update STT options. Changes will take effect on the next stream.
112
+ *
113
+ * @param opts - Partial options to update
114
+ */
115
+ updateOptions(opts) {
116
+ this.#opts = { ...this.#opts, ...opts };
117
+ if (opts.tags) this.#opts.tags = validateTags(opts.tags);
118
+ this.#logger.debug("Updated STTv2 options");
119
+ }
120
+ }
121
+ class SpeechStreamv2 extends import_agents.stt.SpeechStream {
122
+ label = "deepgram.SpeechStreamv2";
123
+ #opts;
124
+ #logger = (0, import_agents.log)();
125
+ #ws = null;
126
+ #audioDurationCollector;
127
+ #requestId = "";
128
+ #speaking = false;
129
+ // Parity: _reconnect_event - using existing Event class from @livekit/agents
130
+ #reconnectEvent = new import_agents.Event();
131
+ constructor(sttInstance, opts, connOptions) {
132
+ super(sttInstance, opts.sampleRate, connOptions);
133
+ this.#opts = opts;
134
+ this.#audioDurationCollector = new import_utils.PeriodicCollector(
135
+ (duration) => this.#onAudioDurationReport(duration),
136
+ { duration: 5 }
137
+ );
138
+ }
139
+ updateOptions(opts) {
140
+ this.#logger.debug("Stream received option update", opts);
141
+ this.#opts = { ...this.#opts, ...opts };
142
+ if (opts.tags) this.#opts.tags = validateTags(opts.tags);
143
+ this.#reconnectEvent.set();
144
+ }
145
+ async run() {
146
+ var _a;
147
+ while (!this.closed) {
148
+ try {
149
+ this.#reconnectEvent.clear();
150
+ const url = this.#getDeepgramUrl();
151
+ this.#logger.debug(`Connecting to Deepgram: ${url}`);
152
+ this.#ws = new import_ws.WebSocket(url, {
153
+ headers: { Authorization: `Token ${this.#opts.apiKey}` }
154
+ });
155
+ await new Promise((resolve, reject) => {
156
+ if (!this.#ws) return reject(new Error("WebSocket not initialized"));
157
+ const onOpen = () => {
158
+ var _a2;
159
+ (_a2 = this.#ws) == null ? void 0 : _a2.off("error", onError);
160
+ resolve();
161
+ };
162
+ const onError = (err) => {
163
+ var _a2;
164
+ (_a2 = this.#ws) == null ? void 0 : _a2.off("open", onOpen);
165
+ reject(err);
166
+ };
167
+ this.#ws.once("open", onOpen);
168
+ this.#ws.once("error", onError);
169
+ });
170
+ const sendPromise = this.#sendTask();
171
+ const recvPromise = this.#recvTask();
172
+ const reconnectWait = this.#reconnectEvent.wait();
173
+ const result = await Promise.race([
174
+ Promise.all([sendPromise, recvPromise]),
175
+ reconnectWait.then(() => "RECONNECT")
176
+ ]);
177
+ if (result === "RECONNECT") {
178
+ this.#logger.debug("Reconnecting stream due to option update...");
179
+ this.#ws.close();
180
+ } else {
181
+ break;
182
+ }
183
+ } catch (error) {
184
+ this.#logger.error("Deepgram stream error", { error });
185
+ throw error;
186
+ } finally {
187
+ if (((_a = this.#ws) == null ? void 0 : _a.readyState) === import_ws.WebSocket.OPEN) {
188
+ this.#ws.close();
189
+ }
190
+ }
191
+ }
192
+ this.close();
193
+ }
194
+ async #sendTask() {
195
+ if (!this.#ws) return;
196
+ const samples50ms = Math.floor(this.#opts.sampleRate / 20);
197
+ const audioBstream = new import_agents.AudioByteStream(this.#opts.sampleRate, 1, samples50ms);
198
+ let hasEnded = false;
199
+ const iterator = this.input[Symbol.asyncIterator]();
200
+ while (true) {
201
+ const nextPromise = iterator.next();
202
+ const abortPromise = this.#reconnectEvent.wait().then(() => ({ abort: true }));
203
+ const result = await Promise.race([nextPromise, abortPromise]);
204
+ if ("abort" in result || result.done) {
205
+ if (!("abort" in result) && result.done) {
206
+ hasEnded = true;
207
+ } else {
208
+ break;
209
+ }
210
+ }
211
+ if (hasEnded && !("value" in result)) {
212
+ } else if ("value" in result) {
213
+ const data = result.value;
214
+ const frames = [];
215
+ if (data === SpeechStreamv2.FLUSH_SENTINEL) {
216
+ frames.push(...audioBstream.flush());
217
+ hasEnded = true;
218
+ } else {
219
+ frames.push(...audioBstream.write(data.data.buffer));
220
+ }
221
+ for (const frame of frames) {
222
+ this.#audioDurationCollector.push((0, import_agents.calculateAudioDurationSeconds)(frame));
223
+ if (this.#ws.readyState === import_ws.WebSocket.OPEN) {
224
+ this.#ws.send(frame.data);
225
+ }
226
+ if (hasEnded) {
227
+ this.#audioDurationCollector.flush();
228
+ hasEnded = false;
229
+ }
230
+ }
231
+ }
232
+ if (hasEnded) break;
233
+ }
234
+ if (!this.#reconnectEvent.isSet && this.#ws.readyState === import_ws.WebSocket.OPEN) {
235
+ this.#logger.debug("Sending CloseStream message to Deepgram");
236
+ this.#ws.send(_CLOSE_MSG);
237
+ }
238
+ }
239
+ async #recvTask() {
240
+ if (!this.#ws) return;
241
+ return new Promise((resolve) => {
242
+ if (!this.#ws) return resolve();
243
+ this.#ws.on("message", (data, isBinary) => {
244
+ if (isBinary) {
245
+ this.#logger.warn("Received unexpected binary message from Deepgram");
246
+ return;
247
+ }
248
+ try {
249
+ const msg = JSON.parse(data.toString());
250
+ this.#processStreamEvent(msg);
251
+ } catch (error) {
252
+ this.#logger.error("Failed to parse Deepgram message", { error });
253
+ }
254
+ });
255
+ this.#ws.on("close", (code, reason) => {
256
+ this.#logger.debug(`Deepgram WebSocket closed: ${code} ${reason}`);
257
+ resolve();
258
+ });
259
+ this.#ws.on("error", () => resolve());
260
+ });
261
+ }
262
+ #processStreamEvent(data) {
263
+ if (data.request_id) {
264
+ this.#requestId = data.request_id;
265
+ }
266
+ if (data.type === "TurnInfo") {
267
+ const eventType = data.event;
268
+ if (eventType === "StartOfTurn") {
269
+ if (this.#speaking) return;
270
+ this.#speaking = true;
271
+ this.queue.put({
272
+ type: import_agents.stt.SpeechEventType.START_OF_SPEECH,
273
+ requestId: this.#requestId
274
+ });
275
+ this.#sendTranscriptEvent(import_agents.stt.SpeechEventType.INTERIM_TRANSCRIPT, data);
276
+ } else if (eventType === "Update") {
277
+ if (!this.#speaking) return;
278
+ this.#sendTranscriptEvent(import_agents.stt.SpeechEventType.INTERIM_TRANSCRIPT, data);
279
+ } else if (eventType === "EagerEndOfTurn") {
280
+ if (!this.#speaking) return;
281
+ this.#sendTranscriptEvent(import_agents.stt.SpeechEventType.PREFLIGHT_TRANSCRIPT, data);
282
+ } else if (eventType === "TurnResumed") {
283
+ this.#sendTranscriptEvent(import_agents.stt.SpeechEventType.INTERIM_TRANSCRIPT, data);
284
+ } else if (eventType === "EndOfTurn") {
285
+ if (!this.#speaking) return;
286
+ this.#speaking = false;
287
+ this.#sendTranscriptEvent(import_agents.stt.SpeechEventType.FINAL_TRANSCRIPT, data);
288
+ this.queue.put({
289
+ type: import_agents.stt.SpeechEventType.END_OF_SPEECH,
290
+ requestId: this.#requestId
291
+ });
292
+ }
293
+ } else if (data.type === "Error") {
294
+ this.#logger.warn("deepgram sent an error", { data });
295
+ const desc = data.description || "unknown error from deepgram";
296
+ throw new Error(`Deepgram API Error: ${desc}`);
297
+ }
298
+ }
299
+ #sendTranscriptEvent(eventType, data) {
300
+ const alts = parseTranscription(this.#opts.language || "en", data, 0);
301
+ if (alts.length > 0) {
302
+ this.queue.put({
303
+ type: eventType,
304
+ requestId: this.#requestId,
305
+ alternatives: [alts[0], ...alts.slice(1)]
306
+ });
307
+ }
308
+ }
309
+ #onAudioDurationReport(duration) {
310
+ const usageEvent = {
311
+ type: import_agents.stt.SpeechEventType.RECOGNITION_USAGE,
312
+ requestId: this.#requestId,
313
+ recognitionUsage: {
314
+ audioDuration: duration
315
+ }
316
+ };
317
+ this.queue.put(usageEvent);
318
+ }
319
+ #getDeepgramUrl() {
320
+ const params = {
321
+ model: this.#opts.model,
322
+ sample_rate: this.#opts.sampleRate.toString(),
323
+ encoding: "linear16",
324
+ mip_opt_out: String(this.#opts.mipOptOut)
325
+ };
326
+ if (this.#opts.language) params.language = this.#opts.language;
327
+ if (this.#opts.eagerEotThreshold)
328
+ params.eager_eot_threshold = this.#opts.eagerEotThreshold.toString();
329
+ if (this.#opts.eotThreshold) params.eot_threshold = this.#opts.eotThreshold.toString();
330
+ if (this.#opts.eotTimeoutMs) params.eot_timeout_ms = this.#opts.eotTimeoutMs.toString();
331
+ if (this.#opts.keyterms.length > 0) params.keyterm = this.#opts.keyterms;
332
+ if (this.#opts.tags && this.#opts.tags.length > 0) params.tag = this.#opts.tags;
333
+ const baseUrl = this.#opts.endpointUrl.replace(/^http/, "ws");
334
+ const qs = queryString.stringify(params);
335
+ return `${baseUrl}?${qs}`;
336
+ }
337
+ close() {
338
+ var _a;
339
+ super.close();
340
+ (_a = this.#ws) == null ? void 0 : _a.close();
341
+ }
342
+ }
343
+ function parseTranscription(language, data, startTimeOffset) {
344
+ const transcript = data.transcript;
345
+ const words = data.words || [];
346
+ if (!words || words.length === 0) {
347
+ return [];
348
+ }
349
+ let confidence = 0;
350
+ if (words.length > 0) {
351
+ const sum = words.reduce((acc, w) => acc + (w.confidence || 0), 0);
352
+ confidence = sum / words.length;
353
+ }
354
+ const sd = {
355
+ language,
356
+ startTime: (data.audio_window_start || 0) + startTimeOffset,
357
+ endTime: (data.audio_window_end || 0) + startTimeOffset,
358
+ confidence,
359
+ text: transcript || ""
360
+ };
361
+ return [sd];
362
+ }
363
+ // Annotate the CommonJS export names for ESM import in node:
364
+ 0 && (module.exports = {
365
+ STTv2
366
+ });
367
+ //# sourceMappingURL=stt_v2.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/stt_v2.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport {\n type APIConnectOptions,\n AudioByteStream,\n Event,\n calculateAudioDurationSeconds,\n log,\n stt,\n} from '@livekit/agents';\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport * as queryString from 'node:querystring';\nimport { WebSocket } from 'ws';\nimport { PeriodicCollector } from './_utils.js';\nimport type { V2Models } from './models.js';\n\nconst _CLOSE_MSG = JSON.stringify({ type: 'CloseStream' });\n\n// --- Configuration ---\n\n/**\n * Configuration options for STTv2 (Deepgram Flux model).\n */\nexport interface STTv2Options {\n apiKey?: string;\n model: V2Models | string;\n sampleRate: number;\n keyterms: string[];\n endpointUrl: string;\n language?: string;\n eagerEotThreshold?: number;\n eotThreshold?: number;\n eotTimeoutMs?: number;\n mipOptOut?: boolean;\n tags?: string[];\n}\n\nconst defaultSTTv2Options: Omit<STTv2Options, 'apiKey'> = {\n model: 'flux-general-en',\n sampleRate: 16000,\n keyterms: [],\n endpointUrl: 'wss://api.deepgram.com/v2/listen',\n language: 'en',\n mipOptOut: false,\n};\n\nfunction validateTags(tags: string[]): string[] {\n for (const tag of tags) {\n if (tag.length > 128) {\n throw new Error('tag must be no more than 128 characters');\n }\n }\n return tags;\n}\n\n/**\n * Deepgram STTv2 using the Flux model for streaming speech-to-text.\n *\n * This uses Deepgram's V2 API (`/v2/listen`) which provides turn-based\n * transcription with support for preemptive generation.\n *\n * @remarks\n * Key differences from STT (V1):\n * - Uses `TurnInfo` events instead of `SpeechStarted`/`Results`\n * - Supports `eagerEotThreshold` for preemptive LLM generation\n * - Sends `PREFLIGHT_TRANSCRIPT` events when eager end-of-turn is detected\n *\n * @example\n * ```typescript\n * import { STTv2 } from '@livekit/agents-plugin-deepgram';\n *\n * const stt = new STTv2({\n * model: 'flux-general-en',\n * eagerEotThreshold: 0.5, // Enable preemptive generation\n * });\n *\n * const stream = stt.stream();\n * stream.pushFrame(audioFrame);\n *\n * for await (const event of stream) {\n * if (event.type === SpeechEventType.FINAL_TRANSCRIPT) {\n * console.log(event.alternatives?.[0]?.text);\n * }\n * }\n * ```\n */\nexport class STTv2 extends stt.STT {\n readonly label = 'deepgram.STTv2';\n #opts: STTv2Options;\n #apiKey: string;\n #logger = log();\n\n /**\n * Create a new Deepgram STTv2 instance.\n *\n * @param opts - Configuration options\n * @param opts.apiKey - Deepgram API key (defaults to `DEEPGRAM_API_KEY` env var)\n * @param opts.model - Model to use (default: `flux-general-en`)\n * @param opts.eagerEotThreshold - Threshold (0.3-0.9) for preemptive generation\n * @param opts.eotThreshold - End-of-turn detection threshold (default: 0.7)\n * @param opts.eotTimeoutMs - End-of-turn timeout in ms (default: 3000)\n * @param opts.keyterms - List of key terms to improve recognition\n * @param opts.tags - Tags for usage reporting (max 128 chars each)\n *\n * @throws Error if no API key is provided\n */\n constructor(opts: Partial<STTv2Options> = {}) {\n super({\n streaming: true,\n interimResults: true,\n });\n\n this.#opts = { ...defaultSTTv2Options, ...opts };\n\n const apiKey = opts.apiKey || process.env.DEEPGRAM_API_KEY;\n if (!apiKey) {\n throw new Error('Deepgram API key is required');\n }\n this.#apiKey = apiKey;\n\n if (this.#opts.tags) {\n this.#opts.tags = validateTags(this.#opts.tags);\n }\n }\n\n /** The model being used for transcription */\n get model(): string {\n return this.#opts.model;\n }\n\n /** The STT provider name */\n get provider(): string {\n return 'Deepgram';\n }\n\n protected async _recognize(\n _frame: AudioFrame | AudioFrame[],\n _abortSignal?: AbortSignal,\n ): Promise<stt.SpeechEvent> {\n throw new Error('V2 API does not support non-streaming recognize. Use .stream()');\n }\n\n /**\n * Create a new streaming transcription session.\n *\n * @param options - Stream options\n * @returns A SpeechStream that emits transcription events\n */\n stream(options?: { connOptions?: APIConnectOptions }): stt.SpeechStream {\n const streamOpts = { ...this.#opts, apiKey: this.#apiKey };\n return new SpeechStreamv2(this, streamOpts, options?.connOptions);\n }\n\n /**\n * Update STT options. Changes will take effect on the next stream.\n *\n * @param opts - Partial options to update\n */\n updateOptions(opts: Partial<STTv2Options>) {\n this.#opts = { ...this.#opts, ...opts };\n if (opts.tags) this.#opts.tags = validateTags(opts.tags);\n this.#logger.debug('Updated STTv2 options');\n }\n}\n\n// --- Stream Implementation ---\n\nclass SpeechStreamv2 extends stt.SpeechStream {\n readonly label = 'deepgram.SpeechStreamv2';\n #opts: STTv2Options & { apiKey: string };\n #logger = log();\n #ws: WebSocket | null = null;\n\n #audioDurationCollector: PeriodicCollector<number>;\n #requestId = '';\n #speaking = false;\n\n // Parity: _reconnect_event - using existing Event class from @livekit/agents\n #reconnectEvent = new Event();\n\n constructor(\n sttInstance: STTv2,\n opts: STTv2Options & { apiKey: string },\n connOptions?: APIConnectOptions,\n ) {\n super(sttInstance, opts.sampleRate, connOptions);\n this.#opts = opts;\n\n this.#audioDurationCollector = new PeriodicCollector(\n (duration) => this.#onAudioDurationReport(duration),\n { duration: 5.0 },\n );\n }\n\n updateOptions(opts: Partial<STTv2Options>) {\n this.#logger.debug('Stream received option update', opts);\n this.#opts = { ...this.#opts, ...opts };\n if (opts.tags) this.#opts.tags = validateTags(opts.tags);\n\n // Trigger reconnection loop\n this.#reconnectEvent.set();\n }\n\n protected async run() {\n // Outer Loop: Handles reconnections (Configuration updates)\n while (!this.closed) {\n try {\n this.#reconnectEvent.clear();\n\n const url = this.#getDeepgramUrl();\n this.#logger.debug(`Connecting to Deepgram: ${url}`);\n\n this.#ws = new WebSocket(url, {\n headers: { Authorization: `Token ${this.#opts.apiKey}` },\n });\n\n // 1. Wait for Connection Open\n await new Promise<void>((resolve, reject) => {\n if (!this.#ws) return reject(new Error('WebSocket not initialized'));\n\n const onOpen = () => {\n this.#ws?.off('error', onError);\n resolve();\n };\n const onError = (err: Error) => {\n this.#ws?.off('open', onOpen);\n reject(err);\n };\n\n this.#ws.once('open', onOpen);\n this.#ws.once('error', onError);\n });\n\n // 2. Run Concurrent Tasks (Send & Receive)\n const sendPromise = this.#sendTask();\n const recvPromise = this.#recvTask();\n const reconnectWait = this.#reconnectEvent.wait();\n\n // 3. Race: Normal Completion vs Reconnect Signal\n const result = await Promise.race([\n Promise.all([sendPromise, recvPromise]),\n reconnectWait.then(() => 'RECONNECT'),\n ]);\n\n if (result === 'RECONNECT') {\n this.#logger.debug('Reconnecting stream due to option update...');\n // Close current socket; loop will restart and open a new one\n this.#ws.close();\n } else {\n // Normal finish (Stream ended or Error thrown)\n break;\n }\n } catch (error) {\n this.#logger.error('Deepgram stream error', { error });\n throw error; // Let Base Class handle retry logic\n } finally {\n if (this.#ws?.readyState === WebSocket.OPEN) {\n this.#ws.close();\n }\n }\n }\n this.close();\n }\n\n async #sendTask() {\n if (!this.#ws) return;\n\n // Buffer audio into 50ms chunks (Parity)\n const samples50ms = Math.floor(this.#opts.sampleRate / 20);\n const audioBstream = new AudioByteStream(this.#opts.sampleRate, 1, samples50ms);\n\n let hasEnded = false;\n\n // Manual Iterator to allow racing against Reconnect Signal\n const iterator = this.input[Symbol.asyncIterator]();\n\n while (true) {\n const nextPromise = iterator.next();\n // If reconnect signal fires, abort the wait\n const abortPromise = this.#reconnectEvent.wait().then(() => ({ abort: true }) as const);\n\n const result = await Promise.race([nextPromise, abortPromise]);\n\n // Check if we need to abort (Reconnect) or if stream is done\n if ('abort' in result || result.done) {\n if (!('abort' in result) && result.done) {\n // Normal stream end\n hasEnded = true;\n } else {\n // Reconnect triggered - break loop immediately\n break;\n }\n }\n\n // If we broke above, we don't process data. If not, 'result' is IteratorResult\n if (hasEnded && !('value' in result)) {\n // Process flush below\n } else if ('value' in result) {\n const data = result.value;\n const frames: AudioFrame[] = [];\n\n if (data === SpeechStreamv2.FLUSH_SENTINEL) {\n frames.push(...audioBstream.flush());\n hasEnded = true;\n } else {\n frames.push(...audioBstream.write((data as AudioFrame).data.buffer as ArrayBuffer));\n }\n\n for (const frame of frames) {\n this.#audioDurationCollector.push(calculateAudioDurationSeconds(frame));\n\n if (this.#ws!.readyState === WebSocket.OPEN) {\n this.#ws!.send(frame.data);\n }\n\n if (hasEnded) {\n this.#audioDurationCollector.flush();\n hasEnded = false;\n }\n }\n }\n\n if (hasEnded) break;\n }\n\n // Only send CloseStream if we are exiting normally (not reconnecting)\n if (!this.#reconnectEvent.isSet && this.#ws!.readyState === WebSocket.OPEN) {\n this.#logger.debug('Sending CloseStream message to Deepgram');\n this.#ws!.send(_CLOSE_MSG);\n }\n }\n\n async #recvTask() {\n if (!this.#ws) return;\n\n return new Promise<void>((resolve) => {\n if (!this.#ws) return resolve();\n\n this.#ws.on('message', (data: Buffer, isBinary: boolean) => {\n if (isBinary) {\n this.#logger.warn('Received unexpected binary message from Deepgram');\n return;\n }\n try {\n const msg = JSON.parse(data.toString());\n this.#processStreamEvent(msg);\n } catch (error) {\n this.#logger.error('Failed to parse Deepgram message', { error });\n }\n });\n\n this.#ws.on('close', (code, reason) => {\n this.#logger.debug(`Deepgram WebSocket closed: ${code} ${reason}`);\n resolve();\n });\n\n // Errors are caught by run() listener, resolve here to clean up task\n this.#ws.on('error', () => resolve());\n });\n }\n\n #processStreamEvent(data: Record<string, unknown>) {\n if (data.request_id) {\n this.#requestId = data.request_id as string;\n }\n\n if (data.type === 'TurnInfo') {\n const eventType = data.event;\n\n if (eventType === 'StartOfTurn') {\n if (this.#speaking) return;\n\n this.#speaking = true;\n this.queue.put({\n type: stt.SpeechEventType.START_OF_SPEECH,\n requestId: this.#requestId,\n });\n\n this.#sendTranscriptEvent(stt.SpeechEventType.INTERIM_TRANSCRIPT, data);\n } else if (eventType === 'Update') {\n if (!this.#speaking) return;\n this.#sendTranscriptEvent(stt.SpeechEventType.INTERIM_TRANSCRIPT, data);\n } else if (eventType === 'EagerEndOfTurn') {\n if (!this.#speaking) return;\n this.#sendTranscriptEvent(stt.SpeechEventType.PREFLIGHT_TRANSCRIPT, data);\n } else if (eventType === 'TurnResumed') {\n this.#sendTranscriptEvent(stt.SpeechEventType.INTERIM_TRANSCRIPT, data);\n } else if (eventType === 'EndOfTurn') {\n if (!this.#speaking) return;\n\n this.#speaking = false;\n this.#sendTranscriptEvent(stt.SpeechEventType.FINAL_TRANSCRIPT, data);\n\n this.queue.put({\n type: stt.SpeechEventType.END_OF_SPEECH,\n requestId: this.#requestId,\n });\n }\n } else if (data.type === 'Error') {\n this.#logger.warn('deepgram sent an error', { data });\n const desc = (data.description as string) || 'unknown error from deepgram';\n throw new Error(`Deepgram API Error: ${desc}`);\n }\n }\n\n #sendTranscriptEvent(eventType: stt.SpeechEventType, data: Record<string, unknown>) {\n // Note: start_time_offset is not yet available in the TypeScript base class\n // Using 0.0 for now - full parity would require base class changes\n const alts = parseTranscription(this.#opts.language || 'en', data, 0.0);\n\n if (alts.length > 0) {\n this.queue.put({\n type: eventType,\n requestId: this.#requestId,\n alternatives: [alts[0]!, ...alts.slice(1)],\n });\n }\n }\n\n #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 #getDeepgramUrl(): string {\n const params: Record<string, string | string[]> = {\n model: this.#opts.model,\n sample_rate: this.#opts.sampleRate.toString(),\n encoding: 'linear16',\n mip_opt_out: String(this.#opts.mipOptOut),\n };\n\n if (this.#opts.language) params.language = this.#opts.language;\n if (this.#opts.eagerEotThreshold)\n params.eager_eot_threshold = this.#opts.eagerEotThreshold.toString();\n if (this.#opts.eotThreshold) params.eot_threshold = this.#opts.eotThreshold.toString();\n if (this.#opts.eotTimeoutMs) params.eot_timeout_ms = this.#opts.eotTimeoutMs.toString();\n\n if (this.#opts.keyterms.length > 0) params.keyterm = this.#opts.keyterms;\n if (this.#opts.tags && this.#opts.tags.length > 0) params.tag = this.#opts.tags;\n\n const baseUrl = this.#opts.endpointUrl.replace(/^http/, 'ws');\n const qs = queryString.stringify(params);\n return `${baseUrl}?${qs}`;\n }\n\n override close() {\n super.close();\n this.#ws?.close();\n }\n}\n\n// --- Helpers ---\n\nfunction parseTranscription(\n language: string,\n data: Record<string, unknown>,\n startTimeOffset: number,\n): stt.SpeechData[] {\n const transcript = data.transcript as string | undefined;\n const words = (data.words as Array<Record<string, unknown>>) || [];\n\n if (!words || words.length === 0) {\n return [];\n }\n\n let confidence = 0;\n if (words.length > 0) {\n const sum = words.reduce((acc: number, w) => acc + ((w.confidence as number) || 0), 0);\n confidence = sum / words.length;\n }\n\n const sd: stt.SpeechData = {\n language: language,\n startTime: ((data.audio_window_start as number) || 0) + startTimeOffset,\n endTime: ((data.audio_window_end as number) || 0) + startTimeOffset,\n confidence: confidence,\n text: transcript || '',\n };\n\n return [sd];\n}\n"],"mappings":"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","names":["_a"]}
@@ -0,0 +1,90 @@
1
+ import { type APIConnectOptions, stt } from '@livekit/agents';
2
+ import type { AudioFrame } from '@livekit/rtc-node';
3
+ import type { V2Models } from './models.js';
4
+ /**
5
+ * Configuration options for STTv2 (Deepgram Flux model).
6
+ */
7
+ export interface STTv2Options {
8
+ apiKey?: string;
9
+ model: V2Models | string;
10
+ sampleRate: number;
11
+ keyterms: string[];
12
+ endpointUrl: string;
13
+ language?: string;
14
+ eagerEotThreshold?: number;
15
+ eotThreshold?: number;
16
+ eotTimeoutMs?: number;
17
+ mipOptOut?: boolean;
18
+ tags?: string[];
19
+ }
20
+ /**
21
+ * Deepgram STTv2 using the Flux model for streaming speech-to-text.
22
+ *
23
+ * This uses Deepgram's V2 API (`/v2/listen`) which provides turn-based
24
+ * transcription with support for preemptive generation.
25
+ *
26
+ * @remarks
27
+ * Key differences from STT (V1):
28
+ * - Uses `TurnInfo` events instead of `SpeechStarted`/`Results`
29
+ * - Supports `eagerEotThreshold` for preemptive LLM generation
30
+ * - Sends `PREFLIGHT_TRANSCRIPT` events when eager end-of-turn is detected
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * import { STTv2 } from '@livekit/agents-plugin-deepgram';
35
+ *
36
+ * const stt = new STTv2({
37
+ * model: 'flux-general-en',
38
+ * eagerEotThreshold: 0.5, // Enable preemptive generation
39
+ * });
40
+ *
41
+ * const stream = stt.stream();
42
+ * stream.pushFrame(audioFrame);
43
+ *
44
+ * for await (const event of stream) {
45
+ * if (event.type === SpeechEventType.FINAL_TRANSCRIPT) {
46
+ * console.log(event.alternatives?.[0]?.text);
47
+ * }
48
+ * }
49
+ * ```
50
+ */
51
+ export declare class STTv2 extends stt.STT {
52
+ #private;
53
+ readonly label = "deepgram.STTv2";
54
+ /**
55
+ * Create a new Deepgram STTv2 instance.
56
+ *
57
+ * @param opts - Configuration options
58
+ * @param opts.apiKey - Deepgram API key (defaults to `DEEPGRAM_API_KEY` env var)
59
+ * @param opts.model - Model to use (default: `flux-general-en`)
60
+ * @param opts.eagerEotThreshold - Threshold (0.3-0.9) for preemptive generation
61
+ * @param opts.eotThreshold - End-of-turn detection threshold (default: 0.7)
62
+ * @param opts.eotTimeoutMs - End-of-turn timeout in ms (default: 3000)
63
+ * @param opts.keyterms - List of key terms to improve recognition
64
+ * @param opts.tags - Tags for usage reporting (max 128 chars each)
65
+ *
66
+ * @throws Error if no API key is provided
67
+ */
68
+ constructor(opts?: Partial<STTv2Options>);
69
+ /** The model being used for transcription */
70
+ get model(): string;
71
+ /** The STT provider name */
72
+ get provider(): string;
73
+ protected _recognize(_frame: AudioFrame | AudioFrame[], _abortSignal?: AbortSignal): Promise<stt.SpeechEvent>;
74
+ /**
75
+ * Create a new streaming transcription session.
76
+ *
77
+ * @param options - Stream options
78
+ * @returns A SpeechStream that emits transcription events
79
+ */
80
+ stream(options?: {
81
+ connOptions?: APIConnectOptions;
82
+ }): stt.SpeechStream;
83
+ /**
84
+ * Update STT options. Changes will take effect on the next stream.
85
+ *
86
+ * @param opts - Partial options to update
87
+ */
88
+ updateOptions(opts: Partial<STTv2Options>): void;
89
+ }
90
+ //# sourceMappingURL=stt_v2.d.ts.map