@livekit/agents-plugin-deepgram 1.0.11 → 1.0.13

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("./tts.cjs"), module.exports);
20
21
  class DeepgramPlugin extends import_agents.Plugin {
21
22
  constructor() {
22
23
  super({
@@ -29,6 +30,7 @@ class DeepgramPlugin extends import_agents.Plugin {
29
30
  import_agents.Plugin.registerPlugin(new DeepgramPlugin());
30
31
  // Annotate the CommonJS export names for ESM import in node:
31
32
  0 && (module.exports = {
32
- ...require("./stt.cjs")
33
+ ...require("./stt.cjs"),
34
+ ...require("./tts.cjs")
33
35
  });
34
36
  //# 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';\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;AAOA,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 './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":[]}
package/dist/index.d.cts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './stt.js';
2
+ export * from './tts.js';
2
3
  //# sourceMappingURL=index.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './stt.js';
2
+ export * from './tts.js';
2
3
  //# 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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,UAAU,CAAC;AACzB,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 "./tts.js";
3
4
  class DeepgramPlugin extends Plugin {
4
5
  constructor() {
5
6
  super({
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';\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;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 './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 +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 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 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,3 +1,5 @@
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
+ export type TTSEncoding = 'linear16' | 'mulaw' | 'alaw' | 'mp3' | 'opus' | 'flac' | 'aac';
1
3
  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';
2
4
  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';
3
5
  //# sourceMappingURL=models.d.ts.map
package/dist/models.d.ts CHANGED
@@ -1,3 +1,5 @@
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
+ export type TTSEncoding = 'linear16' | 'mulaw' | 'alaw' | 'mp3' | 'opus' | 'flac' | 'aac';
1
3
  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';
2
4
  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';
3
5
  //# 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,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,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"}
package/dist/tts.cjs ADDED
@@ -0,0 +1,315 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var tts_exports = {};
20
+ __export(tts_exports, {
21
+ ChunkedStream: () => ChunkedStream,
22
+ SynthesizeStream: () => SynthesizeStream,
23
+ TTS: () => TTS
24
+ });
25
+ module.exports = __toCommonJS(tts_exports);
26
+ var import_agents = require("@livekit/agents");
27
+ var import_node_https = require("node:https");
28
+ var import_ws = require("ws");
29
+ const AUTHORIZATION_HEADER = "Authorization";
30
+ const NUM_CHANNELS = 1;
31
+ const MIN_SENTENCE_LENGTH = 8;
32
+ const defaultTTSOptions = {
33
+ model: "aura-asteria-en",
34
+ encoding: "linear16",
35
+ sampleRate: 24e3,
36
+ apiKey: process.env.DEEPGRAM_API_KEY,
37
+ baseUrl: "https://api.deepgram.com",
38
+ capabilities: {
39
+ streaming: true
40
+ },
41
+ sentenceTokenizer: new import_agents.tokenize.basic.SentenceTokenizer({
42
+ minSentenceLength: MIN_SENTENCE_LENGTH
43
+ })
44
+ };
45
+ class TTS extends import_agents.tts.TTS {
46
+ opts;
47
+ label = "deepgram.TTS";
48
+ constructor(opts = {}) {
49
+ var _a;
50
+ super(opts.sampleRate || defaultTTSOptions.sampleRate, NUM_CHANNELS, {
51
+ streaming: ((_a = opts.capabilities) == null ? void 0 : _a.streaming) ?? defaultTTSOptions.capabilities.streaming
52
+ });
53
+ this.opts = {
54
+ ...defaultTTSOptions,
55
+ ...opts
56
+ };
57
+ if (this.opts.apiKey === void 0) {
58
+ throw new Error(
59
+ "Deepgram API key is required, whether as an argument or as $DEEPGRAM_API_KEY"
60
+ );
61
+ }
62
+ }
63
+ synthesize(text) {
64
+ return new ChunkedStream(this, text, this.opts);
65
+ }
66
+ stream() {
67
+ return new SynthesizeStream(this, this.opts);
68
+ }
69
+ }
70
+ class ChunkedStream extends import_agents.tts.ChunkedStream {
71
+ label = "deepgram.ChunkedStream";
72
+ opts;
73
+ text;
74
+ constructor(tts2, text, opts) {
75
+ super(text, tts2);
76
+ this.text = text;
77
+ this.opts = opts;
78
+ }
79
+ async run() {
80
+ const requestId = (0, import_agents.shortuuid)();
81
+ const bstream = new import_agents.AudioByteStream(this.opts.sampleRate, NUM_CHANNELS);
82
+ const json = { text: this.text };
83
+ const url = new URL(`${this.opts.baseUrl}/v1/speak`);
84
+ url.searchParams.append("sample_rate", this.opts.sampleRate.toString());
85
+ url.searchParams.append("model", this.opts.model);
86
+ url.searchParams.append("encoding", this.opts.encoding);
87
+ await new Promise((resolve, reject) => {
88
+ const req = (0, import_node_https.request)(
89
+ {
90
+ hostname: url.hostname,
91
+ port: 443,
92
+ path: url.pathname + url.search,
93
+ method: "POST",
94
+ headers: {
95
+ [AUTHORIZATION_HEADER]: `Token ${this.opts.apiKey}`,
96
+ "Content-Type": "application/json"
97
+ }
98
+ },
99
+ (res) => {
100
+ if (res.statusCode !== 200) {
101
+ reject(
102
+ new Error(`Deepgram TTS HTTP request failed: ${res.statusCode} ${res.statusMessage}`)
103
+ );
104
+ return;
105
+ }
106
+ res.on("data", (chunk) => {
107
+ for (const frame of bstream.write(chunk)) {
108
+ if (!this.queue.closed) {
109
+ this.queue.put({
110
+ requestId,
111
+ frame,
112
+ final: false,
113
+ segmentId: requestId
114
+ });
115
+ }
116
+ }
117
+ });
118
+ res.on("error", (err) => {
119
+ reject(err);
120
+ });
121
+ res.on("close", () => {
122
+ for (const frame of bstream.flush()) {
123
+ if (!this.queue.closed) {
124
+ this.queue.put({
125
+ requestId,
126
+ frame,
127
+ final: false,
128
+ segmentId: requestId
129
+ });
130
+ }
131
+ }
132
+ if (!this.queue.closed) {
133
+ this.queue.close();
134
+ }
135
+ resolve();
136
+ });
137
+ }
138
+ );
139
+ req.on("error", (err) => {
140
+ reject(err);
141
+ });
142
+ req.write(JSON.stringify(json));
143
+ req.end();
144
+ });
145
+ }
146
+ }
147
+ class SynthesizeStream extends import_agents.tts.SynthesizeStream {
148
+ opts;
149
+ tokenizer;
150
+ label = "deepgram.SynthesizeStream";
151
+ static FLUSH_MSG = JSON.stringify({ type: "Flush" });
152
+ static CLOSE_MSG = JSON.stringify({ type: "Close" });
153
+ constructor(tts2, opts) {
154
+ super(tts2);
155
+ this.opts = opts;
156
+ this.tokenizer = opts.sentenceTokenizer.stream();
157
+ }
158
+ async closeWebSocket(ws) {
159
+ try {
160
+ if (ws.readyState === import_ws.WebSocket.OPEN) {
161
+ ws.send(SynthesizeStream.FLUSH_MSG);
162
+ ws.send(SynthesizeStream.CLOSE_MSG);
163
+ try {
164
+ await new Promise((resolve, _reject) => {
165
+ const timeout = setTimeout(() => {
166
+ resolve();
167
+ }, 1e3);
168
+ ws.once("message", () => {
169
+ clearTimeout(timeout);
170
+ resolve();
171
+ });
172
+ ws.once("close", () => {
173
+ clearTimeout(timeout);
174
+ resolve();
175
+ });
176
+ ws.once("error", () => {
177
+ clearTimeout(timeout);
178
+ resolve();
179
+ });
180
+ });
181
+ } catch (e) {
182
+ }
183
+ }
184
+ } catch (e) {
185
+ console.warn(`Error during WebSocket close sequence: ${e}`);
186
+ } finally {
187
+ if (ws.readyState === import_ws.WebSocket.OPEN || ws.readyState === import_ws.WebSocket.CONNECTING) {
188
+ ws.close();
189
+ }
190
+ }
191
+ }
192
+ async run() {
193
+ const requestId = (0, import_agents.shortuuid)();
194
+ const segmentId = (0, import_agents.shortuuid)();
195
+ const wsUrl = this.opts.baseUrl.replace(/^http/, "ws");
196
+ const url = new URL(`${wsUrl}/v1/speak`);
197
+ url.searchParams.append("sample_rate", this.opts.sampleRate.toString());
198
+ url.searchParams.append("model", this.opts.model);
199
+ url.searchParams.append("encoding", this.opts.encoding);
200
+ const ws = new import_ws.WebSocket(url, {
201
+ headers: {
202
+ [AUTHORIZATION_HEADER]: `Token ${this.opts.apiKey}`
203
+ }
204
+ });
205
+ await new Promise((resolve, reject) => {
206
+ ws.on("open", resolve);
207
+ ws.on("error", (error) => reject(error));
208
+ ws.on("close", (code) => reject(`WebSocket returned ${code}`));
209
+ });
210
+ const inputTask = async () => {
211
+ for await (const data of this.input) {
212
+ if (data === SynthesizeStream.FLUSH_SENTINEL) {
213
+ this.tokenizer.flush();
214
+ continue;
215
+ }
216
+ this.tokenizer.pushText(data);
217
+ }
218
+ this.tokenizer.endInput();
219
+ this.tokenizer.close();
220
+ };
221
+ const sendTask = async () => {
222
+ for await (const event of this.tokenizer) {
223
+ if (this.abortController.signal.aborted) break;
224
+ let text = event.token;
225
+ if (!text.endsWith(" ")) {
226
+ text += " ";
227
+ }
228
+ const message = JSON.stringify({
229
+ type: "Speak",
230
+ text
231
+ });
232
+ ws.send(message);
233
+ }
234
+ if (!this.abortController.signal.aborted) {
235
+ ws.send(SynthesizeStream.FLUSH_MSG);
236
+ }
237
+ };
238
+ const recvTask = async () => {
239
+ const bstream = new import_agents.AudioByteStream(this.opts.sampleRate, NUM_CHANNELS);
240
+ let finalReceived = false;
241
+ let timeout = null;
242
+ let lastFrame;
243
+ const sendLastFrame = (segmentId2, final) => {
244
+ if (lastFrame && !this.queue.closed) {
245
+ this.queue.put({ requestId, segmentId: segmentId2, frame: lastFrame, final });
246
+ lastFrame = void 0;
247
+ }
248
+ };
249
+ const clearMessageTimeout = () => {
250
+ if (timeout) {
251
+ clearTimeout(timeout);
252
+ timeout = null;
253
+ }
254
+ };
255
+ return new Promise((resolve, reject) => {
256
+ ws.on("message", (data, isBinary) => {
257
+ clearMessageTimeout();
258
+ if (!isBinary) {
259
+ const message = JSON.parse(data.toString());
260
+ if (message.type === "Flushed") {
261
+ finalReceived = true;
262
+ clearMessageTimeout();
263
+ for (const frame of bstream.flush()) {
264
+ sendLastFrame(segmentId, false);
265
+ lastFrame = frame;
266
+ }
267
+ sendLastFrame(segmentId, true);
268
+ if (!this.queue.closed) {
269
+ this.queue.put(SynthesizeStream.END_OF_STREAM);
270
+ }
271
+ resolve();
272
+ }
273
+ return;
274
+ }
275
+ const buffer = data instanceof Buffer ? data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) : data;
276
+ for (const frame of bstream.write(buffer)) {
277
+ sendLastFrame(segmentId, false);
278
+ lastFrame = frame;
279
+ }
280
+ });
281
+ ws.on("close", (_code, _reason) => {
282
+ if (!finalReceived) {
283
+ for (const frame of bstream.flush()) {
284
+ sendLastFrame(segmentId, false);
285
+ lastFrame = frame;
286
+ }
287
+ sendLastFrame(segmentId, true);
288
+ if (!this.queue.closed) {
289
+ this.queue.put(SynthesizeStream.END_OF_STREAM);
290
+ }
291
+ }
292
+ resolve();
293
+ });
294
+ ws.on("error", (error) => {
295
+ clearMessageTimeout();
296
+ reject(error);
297
+ });
298
+ });
299
+ };
300
+ try {
301
+ await Promise.all([inputTask(), sendTask(), recvTask()]);
302
+ } catch (e) {
303
+ throw new Error(`failed in main task: ${e}`);
304
+ } finally {
305
+ await this.closeWebSocket(ws);
306
+ }
307
+ }
308
+ }
309
+ // Annotate the CommonJS export names for ESM import in node:
310
+ 0 && (module.exports = {
311
+ ChunkedStream,
312
+ SynthesizeStream,
313
+ TTS
314
+ });
315
+ //# sourceMappingURL=tts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tts.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AudioByteStream, shortuuid, tokenize, tts } from '@livekit/agents';\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport { request } from 'node:https';\nimport { type RawData, WebSocket } from 'ws';\nimport type { TTSEncoding, TTSModels } from './models.js';\n\nconst AUTHORIZATION_HEADER = 'Authorization';\nconst NUM_CHANNELS = 1;\nconst MIN_SENTENCE_LENGTH = 8;\n\nexport interface TTSOptions {\n model: TTSModels | string;\n encoding: TTSEncoding;\n sampleRate: number;\n apiKey?: string;\n baseUrl?: string;\n sentenceTokenizer: tokenize.SentenceTokenizer;\n capabilities: tts.TTSCapabilities;\n}\n\nconst defaultTTSOptions: TTSOptions = {\n model: 'aura-asteria-en',\n encoding: 'linear16',\n sampleRate: 24000,\n apiKey: process.env.DEEPGRAM_API_KEY,\n baseUrl: 'https://api.deepgram.com',\n capabilities: {\n streaming: true,\n },\n sentenceTokenizer: new tokenize.basic.SentenceTokenizer({\n minSentenceLength: MIN_SENTENCE_LENGTH,\n }),\n};\n\nexport class TTS extends tts.TTS {\n private opts: TTSOptions;\n label = 'deepgram.TTS';\n\n constructor(opts: Partial<TTSOptions> = {}) {\n super(opts.sampleRate || defaultTTSOptions.sampleRate, NUM_CHANNELS, {\n streaming: opts.capabilities?.streaming ?? defaultTTSOptions.capabilities.streaming,\n });\n\n this.opts = {\n ...defaultTTSOptions,\n ...opts,\n };\n\n if (this.opts.apiKey === undefined) {\n throw new Error(\n 'Deepgram API key is required, whether as an argument or as $DEEPGRAM_API_KEY',\n );\n }\n }\n\n synthesize(text: string): tts.ChunkedStream {\n return new ChunkedStream(this, text, this.opts);\n }\n\n stream(): tts.SynthesizeStream {\n return new SynthesizeStream(this, this.opts);\n }\n}\n\nexport class ChunkedStream extends tts.ChunkedStream {\n label = 'deepgram.ChunkedStream';\n private opts: TTSOptions;\n private text: string;\n\n constructor(tts: TTS, text: string, opts: TTSOptions) {\n super(text, tts);\n this.text = text;\n this.opts = opts;\n }\n\n protected async run() {\n const requestId = shortuuid();\n const bstream = new AudioByteStream(this.opts.sampleRate, NUM_CHANNELS);\n const json = { text: this.text };\n const url = new URL(`${this.opts.baseUrl!}/v1/speak`);\n url.searchParams.append('sample_rate', this.opts.sampleRate.toString());\n url.searchParams.append('model', this.opts.model);\n url.searchParams.append('encoding', this.opts.encoding);\n\n await new Promise<void>((resolve, reject) => {\n const req = request(\n {\n hostname: url.hostname,\n port: 443,\n path: url.pathname + url.search,\n method: 'POST',\n headers: {\n [AUTHORIZATION_HEADER]: `Token ${this.opts.apiKey!}`,\n 'Content-Type': 'application/json',\n },\n },\n (res) => {\n if (res.statusCode !== 200) {\n reject(\n new Error(`Deepgram TTS HTTP request failed: ${res.statusCode} ${res.statusMessage}`),\n );\n return;\n }\n\n res.on('data', (chunk) => {\n for (const frame of bstream.write(chunk)) {\n if (!this.queue.closed) {\n this.queue.put({\n requestId,\n frame,\n final: false,\n segmentId: requestId,\n });\n }\n }\n });\n\n res.on('error', (err) => {\n reject(err);\n });\n\n res.on('close', () => {\n for (const frame of bstream.flush()) {\n if (!this.queue.closed) {\n this.queue.put({\n requestId,\n frame,\n final: false,\n segmentId: requestId,\n });\n }\n }\n if (!this.queue.closed) {\n this.queue.close();\n }\n resolve();\n });\n },\n );\n\n req.on('error', (err) => {\n reject(err);\n });\n\n req.write(JSON.stringify(json));\n req.end();\n });\n }\n}\n\nexport class SynthesizeStream extends tts.SynthesizeStream {\n private opts: TTSOptions;\n private tokenizer: tokenize.SentenceStream;\n label = 'deepgram.SynthesizeStream';\n\n private static readonly FLUSH_MSG = JSON.stringify({ type: 'Flush' });\n private static readonly CLOSE_MSG = JSON.stringify({ type: 'Close' });\n\n constructor(tts: TTS, opts: TTSOptions) {\n super(tts);\n this.opts = opts;\n this.tokenizer = opts.sentenceTokenizer.stream();\n }\n\n private async closeWebSocket(ws: WebSocket): Promise<void> {\n try {\n // Send Flush and Close messages to ensure Deepgram processes all remaining audio\n // and properly terminates the session, preventing lingering TTS sessions\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(SynthesizeStream.FLUSH_MSG);\n ws.send(SynthesizeStream.CLOSE_MSG);\n\n // Wait for server acknowledgment to prevent race conditions and ensure\n // proper cleanup, avoiding 429 Too Many Requests errors from lingering sessions\n try {\n await new Promise<void>((resolve, _reject) => {\n const timeout = setTimeout(() => {\n resolve();\n }, 1000);\n\n ws.once('message', () => {\n clearTimeout(timeout);\n resolve();\n });\n\n ws.once('close', () => {\n clearTimeout(timeout);\n resolve();\n });\n\n ws.once('error', () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n } catch (e) {\n // Ignore timeout or other errors during close sequence\n }\n }\n } catch (e) {\n console.warn(`Error during WebSocket close sequence: ${e}`);\n } finally {\n if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {\n ws.close();\n }\n }\n }\n\n protected async run() {\n const requestId = shortuuid();\n const segmentId = shortuuid();\n\n const wsUrl = this.opts.baseUrl!.replace(/^http/, 'ws');\n const url = new URL(`${wsUrl}/v1/speak`);\n url.searchParams.append('sample_rate', this.opts.sampleRate.toString());\n url.searchParams.append('model', this.opts.model);\n url.searchParams.append('encoding', this.opts.encoding);\n\n const ws = new WebSocket(url, {\n headers: {\n [AUTHORIZATION_HEADER]: `Token ${this.opts.apiKey!}`,\n },\n });\n\n await new Promise((resolve, reject) => {\n ws.on('open', resolve);\n ws.on('error', (error) => reject(error));\n ws.on('close', (code) => reject(`WebSocket returned ${code}`));\n });\n\n const inputTask = async () => {\n for await (const data of this.input) {\n if (data === SynthesizeStream.FLUSH_SENTINEL) {\n this.tokenizer.flush();\n continue;\n }\n this.tokenizer.pushText(data);\n }\n this.tokenizer.endInput();\n this.tokenizer.close();\n };\n\n const sendTask = async () => {\n for await (const event of this.tokenizer) {\n if (this.abortController.signal.aborted) break;\n\n let text = event.token;\n if (!text.endsWith(' ')) {\n text += ' ';\n }\n\n const message = JSON.stringify({\n type: 'Speak',\n text: text,\n });\n\n ws.send(message);\n }\n\n if (!this.abortController.signal.aborted) {\n ws.send(SynthesizeStream.FLUSH_MSG);\n }\n };\n\n const recvTask = async () => {\n const bstream = new AudioByteStream(this.opts.sampleRate, NUM_CHANNELS);\n let finalReceived = false;\n let timeout: NodeJS.Timeout | null = null;\n let lastFrame: AudioFrame | undefined;\n\n const sendLastFrame = (segmentId: string, final: boolean) => {\n if (lastFrame && !this.queue.closed) {\n this.queue.put({ requestId, segmentId, frame: lastFrame, final });\n lastFrame = undefined;\n }\n };\n\n const clearMessageTimeout = () => {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n };\n\n return new Promise<void>((resolve, reject) => {\n ws.on('message', (data: RawData, isBinary: boolean) => {\n clearMessageTimeout();\n\n if (!isBinary) {\n const message = JSON.parse(data.toString());\n if (message.type === 'Flushed') {\n finalReceived = true;\n clearMessageTimeout();\n for (const frame of bstream.flush()) {\n sendLastFrame(segmentId, false);\n lastFrame = frame;\n }\n sendLastFrame(segmentId, true);\n\n if (!this.queue.closed) {\n this.queue.put(SynthesizeStream.END_OF_STREAM);\n }\n resolve();\n }\n\n return;\n }\n\n const buffer =\n data instanceof Buffer\n ? data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength)\n : (data as ArrayBuffer);\n for (const frame of bstream.write(buffer as ArrayBuffer)) {\n sendLastFrame(segmentId, false);\n lastFrame = frame;\n }\n });\n\n ws.on('close', (_code, _reason) => {\n if (!finalReceived) {\n for (const frame of bstream.flush()) {\n sendLastFrame(segmentId, false);\n lastFrame = frame;\n }\n sendLastFrame(segmentId, true);\n\n if (!this.queue.closed) {\n this.queue.put(SynthesizeStream.END_OF_STREAM);\n }\n }\n resolve();\n });\n\n ws.on('error', (error) => {\n clearMessageTimeout();\n reject(error);\n });\n });\n };\n\n try {\n await Promise.all([inputTask(), sendTask(), recvTask()]);\n } catch (e) {\n throw new Error(`failed in main task: ${e}`);\n } finally {\n await this.closeWebSocket(ws);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,oBAA0D;AAE1D,wBAAwB;AACxB,gBAAwC;AAGxC,MAAM,uBAAuB;AAC7B,MAAM,eAAe;AACrB,MAAM,sBAAsB;AAY5B,MAAM,oBAAgC;AAAA,EACpC,OAAO;AAAA,EACP,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,QAAQ,QAAQ,IAAI;AAAA,EACpB,SAAS;AAAA,EACT,cAAc;AAAA,IACZ,WAAW;AAAA,EACb;AAAA,EACA,mBAAmB,IAAI,uBAAS,MAAM,kBAAkB;AAAA,IACtD,mBAAmB;AAAA,EACrB,CAAC;AACH;AAEO,MAAM,YAAY,kBAAI,IAAI;AAAA,EACvB;AAAA,EACR,QAAQ;AAAA,EAER,YAAY,OAA4B,CAAC,GAAG;AAzC9C;AA0CI,UAAM,KAAK,cAAc,kBAAkB,YAAY,cAAc;AAAA,MACnE,aAAW,UAAK,iBAAL,mBAAmB,cAAa,kBAAkB,aAAa;AAAA,IAC5E,CAAC;AAED,SAAK,OAAO;AAAA,MACV,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAEA,QAAI,KAAK,KAAK,WAAW,QAAW;AAClC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW,MAAiC;AAC1C,WAAO,IAAI,cAAc,MAAM,MAAM,KAAK,IAAI;AAAA,EAChD;AAAA,EAEA,SAA+B;AAC7B,WAAO,IAAI,iBAAiB,MAAM,KAAK,IAAI;AAAA,EAC7C;AACF;AAEO,MAAM,sBAAsB,kBAAI,cAAc;AAAA,EACnD,QAAQ;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAYA,MAAU,MAAc,MAAkB;AACpD,UAAM,MAAMA,IAAG;AACf,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAgB,MAAM;AACpB,UAAM,gBAAY,yBAAU;AAC5B,UAAM,UAAU,IAAI,8BAAgB,KAAK,KAAK,YAAY,YAAY;AACtE,UAAM,OAAO,EAAE,MAAM,KAAK,KAAK;AAC/B,UAAM,MAAM,IAAI,IAAI,GAAG,KAAK,KAAK,OAAQ,WAAW;AACpD,QAAI,aAAa,OAAO,eAAe,KAAK,KAAK,WAAW,SAAS,CAAC;AACtE,QAAI,aAAa,OAAO,SAAS,KAAK,KAAK,KAAK;AAChD,QAAI,aAAa,OAAO,YAAY,KAAK,KAAK,QAAQ;AAEtD,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,YAAM,UAAM;AAAA,QACV;AAAA,UACE,UAAU,IAAI;AAAA,UACd,MAAM;AAAA,UACN,MAAM,IAAI,WAAW,IAAI;AAAA,UACzB,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,CAAC,oBAAoB,GAAG,SAAS,KAAK,KAAK,MAAO;AAAA,YAClD,gBAAgB;AAAA,UAClB;AAAA,QACF;AAAA,QACA,CAAC,QAAQ;AACP,cAAI,IAAI,eAAe,KAAK;AAC1B;AAAA,cACE,IAAI,MAAM,qCAAqC,IAAI,UAAU,IAAI,IAAI,aAAa,EAAE;AAAA,YACtF;AACA;AAAA,UACF;AAEA,cAAI,GAAG,QAAQ,CAAC,UAAU;AACxB,uBAAW,SAAS,QAAQ,MAAM,KAAK,GAAG;AACxC,kBAAI,CAAC,KAAK,MAAM,QAAQ;AACtB,qBAAK,MAAM,IAAI;AAAA,kBACb;AAAA,kBACA;AAAA,kBACA,OAAO;AAAA,kBACP,WAAW;AAAA,gBACb,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF,CAAC;AAED,cAAI,GAAG,SAAS,CAAC,QAAQ;AACvB,mBAAO,GAAG;AAAA,UACZ,CAAC;AAED,cAAI,GAAG,SAAS,MAAM;AACpB,uBAAW,SAAS,QAAQ,MAAM,GAAG;AACnC,kBAAI,CAAC,KAAK,MAAM,QAAQ;AACtB,qBAAK,MAAM,IAAI;AAAA,kBACb;AAAA,kBACA;AAAA,kBACA,OAAO;AAAA,kBACP,WAAW;AAAA,gBACb,CAAC;AAAA,cACH;AAAA,YACF;AACA,gBAAI,CAAC,KAAK,MAAM,QAAQ;AACtB,mBAAK,MAAM,MAAM;AAAA,YACnB;AACA,oBAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAAA,MACF;AAEA,UAAI,GAAG,SAAS,CAAC,QAAQ;AACvB,eAAO,GAAG;AAAA,MACZ,CAAC;AAED,UAAI,MAAM,KAAK,UAAU,IAAI,CAAC;AAC9B,UAAI,IAAI;AAAA,IACV,CAAC;AAAA,EACH;AACF;AAEO,MAAM,yBAAyB,kBAAI,iBAAiB;AAAA,EACjD;AAAA,EACA;AAAA,EACR,QAAQ;AAAA,EAER,OAAwB,YAAY,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAAA,EACpE,OAAwB,YAAY,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAAA,EAEpE,YAAYA,MAAU,MAAkB;AACtC,UAAMA,IAAG;AACT,SAAK,OAAO;AACZ,SAAK,YAAY,KAAK,kBAAkB,OAAO;AAAA,EACjD;AAAA,EAEA,MAAc,eAAe,IAA8B;AACzD,QAAI;AAGF,UAAI,GAAG,eAAe,oBAAU,MAAM;AACpC,WAAG,KAAK,iBAAiB,SAAS;AAClC,WAAG,KAAK,iBAAiB,SAAS;AAIlC,YAAI;AACF,gBAAM,IAAI,QAAc,CAAC,SAAS,YAAY;AAC5C,kBAAM,UAAU,WAAW,MAAM;AAC/B,sBAAQ;AAAA,YACV,GAAG,GAAI;AAEP,eAAG,KAAK,WAAW,MAAM;AACvB,2BAAa,OAAO;AACpB,sBAAQ;AAAA,YACV,CAAC;AAED,eAAG,KAAK,SAAS,MAAM;AACrB,2BAAa,OAAO;AACpB,sBAAQ;AAAA,YACV,CAAC;AAED,eAAG,KAAK,SAAS,MAAM;AACrB,2BAAa,OAAO;AACpB,sBAAQ;AAAA,YACV,CAAC;AAAA,UACH,CAAC;AAAA,QACH,SAAS,GAAG;AAAA,QAEZ;AAAA,MACF;AAAA,IACF,SAAS,GAAG;AACV,cAAQ,KAAK,0CAA0C,CAAC,EAAE;AAAA,IAC5D,UAAE;AACA,UAAI,GAAG,eAAe,oBAAU,QAAQ,GAAG,eAAe,oBAAU,YAAY;AAC9E,WAAG,MAAM;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAgB,MAAM;AACpB,UAAM,gBAAY,yBAAU;AAC5B,UAAM,gBAAY,yBAAU;AAE5B,UAAM,QAAQ,KAAK,KAAK,QAAS,QAAQ,SAAS,IAAI;AACtD,UAAM,MAAM,IAAI,IAAI,GAAG,KAAK,WAAW;AACvC,QAAI,aAAa,OAAO,eAAe,KAAK,KAAK,WAAW,SAAS,CAAC;AACtE,QAAI,aAAa,OAAO,SAAS,KAAK,KAAK,KAAK;AAChD,QAAI,aAAa,OAAO,YAAY,KAAK,KAAK,QAAQ;AAEtD,UAAM,KAAK,IAAI,oBAAU,KAAK;AAAA,MAC5B,SAAS;AAAA,QACP,CAAC,oBAAoB,GAAG,SAAS,KAAK,KAAK,MAAO;AAAA,MACpD;AAAA,IACF,CAAC;AAED,UAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AACrC,SAAG,GAAG,QAAQ,OAAO;AACrB,SAAG,GAAG,SAAS,CAAC,UAAU,OAAO,KAAK,CAAC;AACvC,SAAG,GAAG,SAAS,CAAC,SAAS,OAAO,sBAAsB,IAAI,EAAE,CAAC;AAAA,IAC/D,CAAC;AAED,UAAM,YAAY,YAAY;AAC5B,uBAAiB,QAAQ,KAAK,OAAO;AACnC,YAAI,SAAS,iBAAiB,gBAAgB;AAC5C,eAAK,UAAU,MAAM;AACrB;AAAA,QACF;AACA,aAAK,UAAU,SAAS,IAAI;AAAA,MAC9B;AACA,WAAK,UAAU,SAAS;AACxB,WAAK,UAAU,MAAM;AAAA,IACvB;AAEA,UAAM,WAAW,YAAY;AAC3B,uBAAiB,SAAS,KAAK,WAAW;AACxC,YAAI,KAAK,gBAAgB,OAAO,QAAS;AAEzC,YAAI,OAAO,MAAM;AACjB,YAAI,CAAC,KAAK,SAAS,GAAG,GAAG;AACvB,kBAAQ;AAAA,QACV;AAEA,cAAM,UAAU,KAAK,UAAU;AAAA,UAC7B,MAAM;AAAA,UACN;AAAA,QACF,CAAC;AAED,WAAG,KAAK,OAAO;AAAA,MACjB;AAEA,UAAI,CAAC,KAAK,gBAAgB,OAAO,SAAS;AACxC,WAAG,KAAK,iBAAiB,SAAS;AAAA,MACpC;AAAA,IACF;AAEA,UAAM,WAAW,YAAY;AAC3B,YAAM,UAAU,IAAI,8BAAgB,KAAK,KAAK,YAAY,YAAY;AACtE,UAAI,gBAAgB;AACpB,UAAI,UAAiC;AACrC,UAAI;AAEJ,YAAM,gBAAgB,CAACC,YAAmB,UAAmB;AAC3D,YAAI,aAAa,CAAC,KAAK,MAAM,QAAQ;AACnC,eAAK,MAAM,IAAI,EAAE,WAAW,WAAAA,YAAW,OAAO,WAAW,MAAM,CAAC;AAChE,sBAAY;AAAA,QACd;AAAA,MACF;AAEA,YAAM,sBAAsB,MAAM;AAChC,YAAI,SAAS;AACX,uBAAa,OAAO;AACpB,oBAAU;AAAA,QACZ;AAAA,MACF;AAEA,aAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,WAAG,GAAG,WAAW,CAAC,MAAe,aAAsB;AACrD,8BAAoB;AAEpB,cAAI,CAAC,UAAU;AACb,kBAAM,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC;AAC1C,gBAAI,QAAQ,SAAS,WAAW;AAC9B,8BAAgB;AAChB,kCAAoB;AACpB,yBAAW,SAAS,QAAQ,MAAM,GAAG;AACnC,8BAAc,WAAW,KAAK;AAC9B,4BAAY;AAAA,cACd;AACA,4BAAc,WAAW,IAAI;AAE7B,kBAAI,CAAC,KAAK,MAAM,QAAQ;AACtB,qBAAK,MAAM,IAAI,iBAAiB,aAAa;AAAA,cAC/C;AACA,sBAAQ;AAAA,YACV;AAEA;AAAA,UACF;AAEA,gBAAM,SACJ,gBAAgB,SACZ,KAAK,OAAO,MAAM,KAAK,YAAY,KAAK,aAAa,KAAK,UAAU,IACnE;AACP,qBAAW,SAAS,QAAQ,MAAM,MAAqB,GAAG;AACxD,0BAAc,WAAW,KAAK;AAC9B,wBAAY;AAAA,UACd;AAAA,QACF,CAAC;AAED,WAAG,GAAG,SAAS,CAAC,OAAO,YAAY;AACjC,cAAI,CAAC,eAAe;AAClB,uBAAW,SAAS,QAAQ,MAAM,GAAG;AACnC,4BAAc,WAAW,KAAK;AAC9B,0BAAY;AAAA,YACd;AACA,0BAAc,WAAW,IAAI;AAE7B,gBAAI,CAAC,KAAK,MAAM,QAAQ;AACtB,mBAAK,MAAM,IAAI,iBAAiB,aAAa;AAAA,YAC/C;AAAA,UACF;AACA,kBAAQ;AAAA,QACV,CAAC;AAED,WAAG,GAAG,SAAS,CAAC,UAAU;AACxB,8BAAoB;AACpB,iBAAO,KAAK;AAAA,QACd,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAEA,QAAI;AACF,YAAM,QAAQ,IAAI,CAAC,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC,CAAC;AAAA,IACzD,SAAS,GAAG;AACV,YAAM,IAAI,MAAM,wBAAwB,CAAC,EAAE;AAAA,IAC7C,UAAE;AACA,YAAM,KAAK,eAAe,EAAE;AAAA,IAC9B;AAAA,EACF;AACF;","names":["tts","segmentId"]}
package/dist/tts.d.cts ADDED
@@ -0,0 +1,36 @@
1
+ import { tokenize, tts } from '@livekit/agents';
2
+ import type { TTSEncoding, TTSModels } from './models.js';
3
+ export interface TTSOptions {
4
+ model: TTSModels | string;
5
+ encoding: TTSEncoding;
6
+ sampleRate: number;
7
+ apiKey?: string;
8
+ baseUrl?: string;
9
+ sentenceTokenizer: tokenize.SentenceTokenizer;
10
+ capabilities: tts.TTSCapabilities;
11
+ }
12
+ export declare class TTS extends tts.TTS {
13
+ private opts;
14
+ label: string;
15
+ constructor(opts?: Partial<TTSOptions>);
16
+ synthesize(text: string): tts.ChunkedStream;
17
+ stream(): tts.SynthesizeStream;
18
+ }
19
+ export declare class ChunkedStream extends tts.ChunkedStream {
20
+ label: string;
21
+ private opts;
22
+ private text;
23
+ constructor(tts: TTS, text: string, opts: TTSOptions);
24
+ protected run(): Promise<void>;
25
+ }
26
+ export declare class SynthesizeStream extends tts.SynthesizeStream {
27
+ private opts;
28
+ private tokenizer;
29
+ label: string;
30
+ private static readonly FLUSH_MSG;
31
+ private static readonly CLOSE_MSG;
32
+ constructor(tts: TTS, opts: TTSOptions);
33
+ private closeWebSocket;
34
+ protected run(): Promise<void>;
35
+ }
36
+ //# sourceMappingURL=tts.d.ts.map
package/dist/tts.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ import { tokenize, tts } from '@livekit/agents';
2
+ import type { TTSEncoding, TTSModels } from './models.js';
3
+ export interface TTSOptions {
4
+ model: TTSModels | string;
5
+ encoding: TTSEncoding;
6
+ sampleRate: number;
7
+ apiKey?: string;
8
+ baseUrl?: string;
9
+ sentenceTokenizer: tokenize.SentenceTokenizer;
10
+ capabilities: tts.TTSCapabilities;
11
+ }
12
+ export declare class TTS extends tts.TTS {
13
+ private opts;
14
+ label: string;
15
+ constructor(opts?: Partial<TTSOptions>);
16
+ synthesize(text: string): tts.ChunkedStream;
17
+ stream(): tts.SynthesizeStream;
18
+ }
19
+ export declare class ChunkedStream extends tts.ChunkedStream {
20
+ label: string;
21
+ private opts;
22
+ private text;
23
+ constructor(tts: TTS, text: string, opts: TTSOptions);
24
+ protected run(): Promise<void>;
25
+ }
26
+ export declare class SynthesizeStream extends tts.SynthesizeStream {
27
+ private opts;
28
+ private tokenizer;
29
+ label: string;
30
+ private static readonly FLUSH_MSG;
31
+ private static readonly CLOSE_MSG;
32
+ constructor(tts: TTS, opts: TTSOptions);
33
+ private closeWebSocket;
34
+ protected run(): Promise<void>;
35
+ }
36
+ //# sourceMappingURL=tts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts.d.ts","sourceRoot":"","sources":["../src/tts.ts"],"names":[],"mappings":"AAGA,OAAO,EAA8B,QAAQ,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAI5E,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAM1D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB,CAAC;IAC9C,YAAY,EAAE,GAAG,CAAC,eAAe,CAAC;CACnC;AAgBD,qBAAa,GAAI,SAAQ,GAAG,CAAC,GAAG;IAC9B,OAAO,CAAC,IAAI,CAAa;IACzB,KAAK,SAAkB;gBAEX,IAAI,GAAE,OAAO,CAAC,UAAU,CAAM;IAiB1C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,aAAa;IAI3C,MAAM,IAAI,GAAG,CAAC,gBAAgB;CAG/B;AAED,qBAAa,aAAc,SAAQ,GAAG,CAAC,aAAa;IAClD,KAAK,SAA4B;IACjC,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,IAAI,CAAS;gBAET,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU;cAMpC,GAAG;CAyEpB;AAED,qBAAa,gBAAiB,SAAQ,GAAG,CAAC,gBAAgB;IACxD,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,SAAS,CAA0B;IAC3C,KAAK,SAA+B;IAEpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAqC;IACtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAqC;gBAE1D,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU;YAMxB,cAAc;cA4CZ,GAAG;CA4IpB"}