@voice-kit/core 0.1.2 → 0.1.3

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 (53) hide show
  1. package/dist/index.cjs +2137 -0
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +1466 -4
  4. package/dist/index.d.ts +1466 -4
  5. package/dist/index.js +2102 -1
  6. package/dist/index.js.map +1 -1
  7. package/package.json +1 -31
  8. package/dist/audio.cjs +0 -533
  9. package/dist/audio.cjs.map +0 -1
  10. package/dist/audio.d.cts +0 -260
  11. package/dist/audio.d.ts +0 -260
  12. package/dist/audio.js +0 -514
  13. package/dist/audio.js.map +0 -1
  14. package/dist/compliance.cjs +0 -343
  15. package/dist/compliance.cjs.map +0 -1
  16. package/dist/compliance.d.cts +0 -163
  17. package/dist/compliance.d.ts +0 -163
  18. package/dist/compliance.js +0 -335
  19. package/dist/compliance.js.map +0 -1
  20. package/dist/errors.cjs +0 -284
  21. package/dist/errors.cjs.map +0 -1
  22. package/dist/errors.d.cts +0 -100
  23. package/dist/errors.d.ts +0 -100
  24. package/dist/errors.js +0 -262
  25. package/dist/errors.js.map +0 -1
  26. package/dist/index-D3KfRXMP.d.cts +0 -319
  27. package/dist/index-D3KfRXMP.d.ts +0 -319
  28. package/dist/memory.cjs +0 -121
  29. package/dist/memory.cjs.map +0 -1
  30. package/dist/memory.d.cts +0 -29
  31. package/dist/memory.d.ts +0 -29
  32. package/dist/memory.js +0 -115
  33. package/dist/memory.js.map +0 -1
  34. package/dist/observability.cjs +0 -229
  35. package/dist/observability.cjs.map +0 -1
  36. package/dist/observability.d.cts +0 -122
  37. package/dist/observability.d.ts +0 -122
  38. package/dist/observability.js +0 -222
  39. package/dist/observability.js.map +0 -1
  40. package/dist/stt.cjs +0 -828
  41. package/dist/stt.cjs.map +0 -1
  42. package/dist/stt.d.cts +0 -308
  43. package/dist/stt.d.ts +0 -308
  44. package/dist/stt.js +0 -815
  45. package/dist/stt.js.map +0 -1
  46. package/dist/telephony.errors-BQYr6-vl.d.cts +0 -80
  47. package/dist/telephony.errors-C0-nScrF.d.ts +0 -80
  48. package/dist/tts.cjs +0 -429
  49. package/dist/tts.cjs.map +0 -1
  50. package/dist/tts.d.cts +0 -151
  51. package/dist/tts.d.ts +0 -151
  52. package/dist/tts.js +0 -418
  53. package/dist/tts.js.map +0 -1
package/dist/tts.d.ts DELETED
@@ -1,151 +0,0 @@
1
- import { e as TTSProvider, f as TTSConfig } from './index-D3KfRXMP.js';
2
- import 'ai';
3
-
4
- /**
5
- * @voice-kit/core — Cartesia TTS Provider
6
- *
7
- * Ultra-low-latency streaming TTS via @cartesia/cartesia-js.
8
- * Target first chunk: < 90ms. Best for latency-critical applications.
9
- */
10
-
11
- /**
12
- * Cartesia ultra-low-latency TTS provider.
13
- * @internal — obtained via createTTS('cartesia', config)
14
- */
15
- declare class CartesiaTTSProvider implements TTSProvider {
16
- readonly name = "cartesia";
17
- readonly outputSampleRate = 22050;
18
- readonly outputFormat: "pcm";
19
- private readonly client;
20
- private readonly config;
21
- constructor(config: TTSConfig);
22
- /**
23
- * Stream audio from Cartesia. Typically delivers first chunk in < 90ms.
24
- *
25
- * @example
26
- * ```ts
27
- * const tts = createTTS('cartesia', { voiceId: 'your-voice-id' })
28
- * for await (const chunk of tts.synthesizeStream('Hello!')) {
29
- * sendToTelephony(chunk)
30
- * }
31
- * ```
32
- */
33
- synthesizeStream(text: string, config?: TTSConfig): AsyncIterable<Buffer>;
34
- /** Synthesize complete audio. */
35
- synthesizeFull(text: string, config?: TTSConfig): Promise<Buffer>;
36
- }
37
-
38
- /**
39
- * @voice-kit/core — ElevenLabs TTS Provider
40
- *
41
- * Streaming TTS using ElevenLabs SDK. Features:
42
- * - 100ms lookahead jitter buffer to smooth burst delivery
43
- * - Voice clone support
44
- * - Sub-300ms first chunk target
45
- */
46
-
47
- /**
48
- * ElevenLabs streaming TTS provider.
49
- * @internal — obtained via createTTS('elevenlabs', config)
50
- */
51
- declare class ElevenLabsTTSProvider implements TTSProvider {
52
- readonly name = "elevenlabs";
53
- readonly outputSampleRate = 24000;
54
- readonly outputFormat: "pcm";
55
- private readonly client;
56
- private readonly config;
57
- constructor(config: TTSConfig);
58
- /**
59
- * Stream synthesized audio from ElevenLabs.
60
- * First chunk target: < 300ms. Uses streaming API endpoint.
61
- *
62
- * A 100ms jitter buffer smooths burst packet delivery without adding
63
- * perceptible latency.
64
- *
65
- * @param text Text to synthesize (should be a sentence boundary chunk)
66
- * @param config Per-call config overrides
67
- *
68
- * @example
69
- * ```ts
70
- * const tts = createTTS('elevenlabs', { voiceId: 'your-voice-id' })
71
- * for await (const chunk of tts.synthesizeStream('Hello, how can I help?')) {
72
- * telephony.sendAudio(chunk)
73
- * }
74
- * ```
75
- */
76
- synthesizeStream(text: string, config?: TTSConfig): AsyncIterable<Buffer>;
77
- /**
78
- * Synthesize full audio (for pre-caching greetings, IVR prompts).
79
- * Collects all streaming chunks into a single buffer.
80
- *
81
- * @param text Text to synthesize
82
- * @param config Per-call config overrides
83
- */
84
- synthesizeFull(text: string, config?: TTSConfig): Promise<Buffer>;
85
- }
86
-
87
- /**
88
- * @voice-kit/core — Sarvam AI TTS Provider
89
- *
90
- * Sarvam AI TTS for Hindi/Hinglish and regional Indian languages.
91
- * Supports natural-sounding Indian voices with regional accents.
92
- */
93
-
94
- /**
95
- * Sarvam AI TTS provider for Indic languages.
96
- * @internal — obtained via createTTS('sarvam', config)
97
- */
98
- declare class SarvamTTSProvider implements TTSProvider {
99
- readonly name = "sarvam";
100
- readonly outputSampleRate = 22050;
101
- readonly outputFormat: "mp3";
102
- private readonly http;
103
- private readonly config;
104
- constructor(config: TTSConfig);
105
- /**
106
- * Synthesize text in an Indic language and stream audio chunks.
107
- * Sarvam returns full audio segments — we chunk them for streaming compatibility.
108
- *
109
- * @example
110
- * ```ts
111
- * const tts = createTTS('sarvam', { targetLanguage: 'hi-IN' })
112
- * for await (const chunk of tts.synthesizeStream('नमस्ते, मैं आपकी कैसे मदद कर सकता हूँ?')) {
113
- * telephony.sendAudio(chunk)
114
- * }
115
- * ```
116
- */
117
- synthesizeStream(text: string, config?: TTSConfig): AsyncIterable<Buffer>;
118
- /** Synthesize complete audio buffer. */
119
- synthesizeFull(text: string, config?: TTSConfig): Promise<Buffer>;
120
- }
121
-
122
- /**
123
- * @voice-kit/core — TTS factory
124
- *
125
- * createTTS() is the ONLY public API for text-to-speech.
126
- * Never instantiate provider classes directly.
127
- */
128
-
129
- /**
130
- * Create a TTS provider instance.
131
- *
132
- * Provider selection guide:
133
- * - 'elevenlabs' → Best voice quality, cloning support, en-IN
134
- * - 'cartesia' → Lowest latency (< 90ms TTFB), good for fast-paced agents
135
- * - 'sarvam' → Best for Indic languages (hi-IN, ta-IN, kn-IN, te-IN, mr-IN)
136
- *
137
- * @example
138
- * ```ts
139
- * // English with voice cloning
140
- * const tts = createTTS('elevenlabs', { voiceId: 'your-cloned-voice-id' })
141
- *
142
- * // Ultra-low latency English
143
- * const tts = createTTS('cartesia', { voiceId: 'your-voice-id' })
144
- *
145
- * // Hindi
146
- * const tts = createTTS('sarvam', { targetLanguage: 'hi-IN', voiceId: 'meera' })
147
- * ```
148
- */
149
- declare function createTTS(provider: 'elevenlabs' | 'cartesia' | 'sarvam', config?: TTSConfig): TTSProvider;
150
-
151
- export { CartesiaTTSProvider, ElevenLabsTTSProvider, SarvamTTSProvider, createTTS };
package/dist/tts.js DELETED
@@ -1,418 +0,0 @@
1
- import Cartesia from '@cartesia/cartesia-js';
2
- import pino from 'pino';
3
- import { ElevenLabsClient } from 'elevenlabs';
4
- import axios from 'axios';
5
-
6
- // src/tts/cartesia/index.ts
7
-
8
- // src/errors/base.ts
9
- var VoiceKitError = class extends Error {
10
- code;
11
- callId;
12
- provider;
13
- retryable;
14
- severity;
15
- cause;
16
- constructor(params) {
17
- super(params.message);
18
- this.name = this.constructor.name;
19
- this.code = params.code;
20
- this.callId = params.callId;
21
- this.provider = params.provider;
22
- this.retryable = params.retryable ?? false;
23
- this.severity = params.severity ?? "medium";
24
- this.cause = params.cause;
25
- Object.setPrototypeOf(this, new.target.prototype);
26
- }
27
- toJSON() {
28
- return {
29
- name: this.name,
30
- code: this.code,
31
- message: this.message,
32
- callId: this.callId,
33
- provider: this.provider,
34
- retryable: this.retryable,
35
- severity: this.severity
36
- };
37
- }
38
- };
39
-
40
- // src/errors/tts.errors.ts
41
- var TTSError = class extends VoiceKitError {
42
- };
43
- var TTSConnectionError = class extends TTSError {
44
- constructor(provider, cause, callId) {
45
- super({
46
- code: "TTS_CONNECTION_FAILED",
47
- message: `Failed to connect to ${provider} TTS service`,
48
- provider,
49
- callId,
50
- retryable: true,
51
- severity: "high",
52
- cause
53
- });
54
- }
55
- };
56
- var TTSStreamError = class extends TTSError {
57
- constructor(provider, cause, callId) {
58
- super({
59
- code: "TTS_STREAM_ERROR",
60
- message: `TTS stream error from ${provider}`,
61
- provider,
62
- callId,
63
- retryable: true,
64
- severity: "medium",
65
- cause
66
- });
67
- }
68
- };
69
- var TTSVoiceNotFoundError = class extends TTSError {
70
- constructor(provider, voiceId) {
71
- super({
72
- code: "TTS_VOICE_NOT_FOUND",
73
- message: `Voice '${voiceId}' not found on ${provider}`,
74
- provider,
75
- retryable: false,
76
- severity: "low"
77
- });
78
- }
79
- };
80
- var logger = pino({ name: "@voice-kit/core:tts:cartesia" });
81
- var DEFAULT_VOICE_ID = "a0e99841-438c-4a64-b679-ae501e7d6091";
82
- var CartesiaTTSProvider = class {
83
- name = "cartesia";
84
- outputSampleRate = 22050;
85
- // Cartesia default
86
- outputFormat = "pcm";
87
- client;
88
- config;
89
- constructor(config) {
90
- const apiKey = config.apiKey ?? process.env["CARTESIA_API_KEY"];
91
- if (!apiKey) throw new TTSConnectionError("cartesia", new Error("CARTESIA_API_KEY not set"));
92
- this.client = new Cartesia({ apiKey });
93
- this.config = {
94
- voiceId: config.voiceId ?? DEFAULT_VOICE_ID,
95
- sampleRate: config.sampleRate ?? 22050,
96
- speed: config.speed ?? 1,
97
- pitch: config.pitch ?? 0,
98
- apiKey,
99
- modelId: config.modelId ?? "sonic-english",
100
- emotion: config.emotion ?? "",
101
- targetLanguage: config.targetLanguage ?? "en"
102
- };
103
- }
104
- /**
105
- * Stream audio from Cartesia. Typically delivers first chunk in < 90ms.
106
- *
107
- * @example
108
- * ```ts
109
- * const tts = createTTS('cartesia', { voiceId: 'your-voice-id' })
110
- * for await (const chunk of tts.synthesizeStream('Hello!')) {
111
- * sendToTelephony(chunk)
112
- * }
113
- * ```
114
- */
115
- async *synthesizeStream(text, config) {
116
- const voiceId = config?.voiceId ?? this.config.voiceId;
117
- const startMs = Date.now();
118
- logger.debug({ voiceId, chars: text.length }, "Cartesia TTS stream start");
119
- try {
120
- const stream = await this.client.tts.generateSse({
121
- model_id: config?.modelId ?? this.config.modelId,
122
- transcript: text,
123
- voice: {
124
- mode: "id",
125
- id: voiceId,
126
- ...this.config.emotion && {
127
- __experimental_controls: {
128
- emotion: [this.config.emotion]
129
- }
130
- }
131
- },
132
- output_format: {
133
- container: "raw",
134
- encoding: "pcm_s16le",
135
- sample_rate: toValidSampleRate(config?.sampleRate ?? this.config.sampleRate)
136
- }
137
- });
138
- let firstChunk = true;
139
- for await (const event of stream) {
140
- if (!event.data || event.data === "[DONE]") continue;
141
- let payload;
142
- try {
143
- payload = JSON.parse(event.data);
144
- } catch {
145
- continue;
146
- }
147
- if (!payload.chunk?.audio) continue;
148
- const buf = Buffer.from(payload.chunk.audio, "base64");
149
- if (firstChunk) {
150
- firstChunk = false;
151
- logger.debug({ ttfb: Date.now() - startMs, voiceId }, "Cartesia first audio chunk");
152
- }
153
- yield buf;
154
- }
155
- } catch (err) {
156
- throw new TTSStreamError("cartesia", err);
157
- }
158
- }
159
- /** Synthesize complete audio. */
160
- async synthesizeFull(text, config) {
161
- const chunks = [];
162
- for await (const chunk of this.synthesizeStream(text, config)) {
163
- chunks.push(chunk);
164
- }
165
- return Buffer.concat(chunks);
166
- }
167
- };
168
- var VALID_SAMPLE_RATES = [22050, 8e3, 16e3, 24e3, 44100, 48e3];
169
- function toValidSampleRate(rate) {
170
- return VALID_SAMPLE_RATES.includes(rate) ? rate : 8e3;
171
- }
172
- var logger2 = pino({ name: "@voice-kit/core:tts:elevenlabs" });
173
- var DEFAULT_VOICE_ID2 = "21m00Tcm4TlvDq8ikWAM";
174
- var JITTER_BUFFER_MS = 100;
175
- var ElevenLabsTTSProvider = class {
176
- name = "elevenlabs";
177
- outputSampleRate = 24e3;
178
- // ElevenLabs default: 24kHz
179
- outputFormat = "pcm";
180
- client;
181
- config;
182
- constructor(config) {
183
- const apiKey = config.apiKey ?? process.env["ELEVENLABS_API_KEY"];
184
- if (!apiKey) throw new TTSConnectionError("elevenlabs", new Error("ELEVENLABS_API_KEY not set"));
185
- this.client = new ElevenLabsClient({ apiKey });
186
- this.config = {
187
- voiceId: config.voiceId ?? DEFAULT_VOICE_ID2,
188
- sampleRate: config.sampleRate ?? 24e3,
189
- speed: config.speed ?? 1,
190
- pitch: config.pitch ?? 0,
191
- apiKey,
192
- modelId: config.modelId ?? "eleven_turbo_v2_5",
193
- emotion: config.emotion ?? "",
194
- targetLanguage: config.targetLanguage ?? "en-IN"
195
- };
196
- }
197
- /**
198
- * Stream synthesized audio from ElevenLabs.
199
- * First chunk target: < 300ms. Uses streaming API endpoint.
200
- *
201
- * A 100ms jitter buffer smooths burst packet delivery without adding
202
- * perceptible latency.
203
- *
204
- * @param text Text to synthesize (should be a sentence boundary chunk)
205
- * @param config Per-call config overrides
206
- *
207
- * @example
208
- * ```ts
209
- * const tts = createTTS('elevenlabs', { voiceId: 'your-voice-id' })
210
- * for await (const chunk of tts.synthesizeStream('Hello, how can I help?')) {
211
- * telephony.sendAudio(chunk)
212
- * }
213
- * ```
214
- */
215
- async *synthesizeStream(text, config) {
216
- const voiceId = config?.voiceId ?? this.config.voiceId;
217
- const modelId = config?.modelId ?? this.config.modelId;
218
- const startMs = Date.now();
219
- logger2.debug({ voiceId, modelId, chars: text.length }, "ElevenLabs TTS stream start");
220
- try {
221
- const audioStream = await this.client.generate({
222
- voice: voiceId,
223
- text,
224
- model_id: modelId,
225
- voice_settings: {
226
- stability: 0.5,
227
- similarity_boost: 0.8,
228
- speed: config?.speed ?? this.config.speed
229
- },
230
- output_format: "pcm_24000",
231
- stream: true
232
- });
233
- let firstChunk = true;
234
- let jitterBuffer = [];
235
- let jitterTimer = null;
236
- const flushJitterBuffer = function* () {
237
- for (const chunk of jitterBuffer) {
238
- yield chunk;
239
- }
240
- jitterBuffer = [];
241
- };
242
- for await (const chunk of audioStream) {
243
- const buf = chunk instanceof Buffer ? chunk : Buffer.from(chunk);
244
- if (firstChunk) {
245
- firstChunk = false;
246
- const ttfb = Date.now() - startMs;
247
- logger2.debug({ ttfb, voiceId }, "ElevenLabs first audio chunk");
248
- }
249
- jitterBuffer.push(buf);
250
- if (jitterTimer === null) {
251
- jitterTimer = setTimeout(() => {
252
- }, JITTER_BUFFER_MS);
253
- }
254
- const totalBytes = jitterBuffer.reduce((sum, b) => sum + b.length, 0);
255
- if (totalBytes >= 4800) {
256
- if (jitterTimer !== null) {
257
- clearTimeout(jitterTimer);
258
- jitterTimer = null;
259
- }
260
- yield* flushJitterBuffer();
261
- }
262
- }
263
- if (jitterTimer !== null) {
264
- clearTimeout(jitterTimer);
265
- }
266
- yield* flushJitterBuffer();
267
- logger2.debug({ voiceId, totalMs: Date.now() - startMs }, "ElevenLabs TTS stream complete");
268
- } catch (err) {
269
- if (err.statusCode === 404) {
270
- throw new TTSVoiceNotFoundError("elevenlabs", voiceId);
271
- }
272
- throw new TTSStreamError("elevenlabs", err);
273
- }
274
- }
275
- /**
276
- * Synthesize full audio (for pre-caching greetings, IVR prompts).
277
- * Collects all streaming chunks into a single buffer.
278
- *
279
- * @param text Text to synthesize
280
- * @param config Per-call config overrides
281
- */
282
- async synthesizeFull(text, config) {
283
- const chunks = [];
284
- for await (const chunk of this.synthesizeStream(text, config)) {
285
- chunks.push(chunk);
286
- }
287
- return Buffer.concat(chunks);
288
- }
289
- };
290
- var logger3 = pino({ name: "@voice-kit/core:tts:sarvam" });
291
- var SARVAM_API_BASE = "https://api.sarvam.ai";
292
- var DEFAULT_VOICES = {
293
- "hi-IN": "meera",
294
- "kn-IN": "pavithra",
295
- "ta-IN": "pavithra",
296
- "te-IN": "pavithra",
297
- "mr-IN": "meera",
298
- "bn-IN": "meera",
299
- "gu-IN": "meera",
300
- "pa-IN": "meera"
301
- };
302
- var SarvamTTSProvider = class {
303
- name = "sarvam";
304
- outputSampleRate = 22050;
305
- // Sarvam default
306
- outputFormat = "mp3";
307
- http;
308
- config;
309
- constructor(config) {
310
- const apiKey = config.apiKey ?? process.env["SARVAM_API_KEY"];
311
- if (!apiKey) throw new TTSConnectionError("sarvam", new Error("SARVAM_API_KEY not set"));
312
- const targetLanguage = config.targetLanguage ?? "hi-IN";
313
- const defaultVoice = DEFAULT_VOICES[targetLanguage] ?? "meera";
314
- this.http = axios.create({
315
- baseURL: SARVAM_API_BASE,
316
- headers: {
317
- "API-Subscription-Key": apiKey,
318
- "Content-Type": "application/json"
319
- },
320
- timeout: 15e3
321
- });
322
- this.config = {
323
- voiceId: config.voiceId ?? defaultVoice,
324
- sampleRate: config.sampleRate ?? 22050,
325
- speed: config.speed ?? 1,
326
- pitch: config.pitch ?? 0,
327
- apiKey,
328
- modelId: config.modelId ?? "bulbul:v1",
329
- emotion: "",
330
- targetLanguage
331
- };
332
- }
333
- /**
334
- * Synthesize text in an Indic language and stream audio chunks.
335
- * Sarvam returns full audio segments — we chunk them for streaming compatibility.
336
- *
337
- * @example
338
- * ```ts
339
- * const tts = createTTS('sarvam', { targetLanguage: 'hi-IN' })
340
- * for await (const chunk of tts.synthesizeStream('नमस्ते, मैं आपकी कैसे मदद कर सकता हूँ?')) {
341
- * telephony.sendAudio(chunk)
342
- * }
343
- * ```
344
- */
345
- async *synthesizeStream(text, config) {
346
- const startMs = Date.now();
347
- const targetLanguage = config?.targetLanguage ?? this.config.targetLanguage;
348
- const speaker = config?.voiceId ?? this.config.voiceId;
349
- logger3.debug({ targetLanguage, speaker, chars: text.length }, "Sarvam TTS request");
350
- try {
351
- const response = await this.http.post("/text-to-speech", {
352
- inputs: [text],
353
- target_language_code: targetLanguage,
354
- speaker,
355
- model: config?.modelId ?? this.config.modelId,
356
- pitch: config?.pitch ?? this.config.pitch,
357
- pace: config?.speed ?? this.config.speed,
358
- loudness: 1,
359
- speech_sample_rate: config?.sampleRate ?? this.config.sampleRate,
360
- enable_preprocessing: true
361
- });
362
- const audioSegments = response.data.audios;
363
- if (!audioSegments || audioSegments.length === 0) {
364
- throw new TTSStreamError("sarvam", new Error("No audio returned from Sarvam TTS"));
365
- }
366
- logger3.debug(
367
- { segments: audioSegments.length, latencyMs: Date.now() - startMs },
368
- "Sarvam TTS response received"
369
- );
370
- for (const segment of audioSegments) {
371
- const buf = Buffer.from(segment, "base64");
372
- const CHUNK_SIZE = 4096;
373
- let offset = 0;
374
- while (offset < buf.length) {
375
- yield buf.subarray(offset, Math.min(offset + CHUNK_SIZE, buf.length));
376
- offset += CHUNK_SIZE;
377
- }
378
- }
379
- } catch (err) {
380
- if (axios.isAxiosError(err)) {
381
- throw new TTSStreamError(
382
- "sarvam",
383
- new Error(`Sarvam TTS API error: ${err.response?.status} ${JSON.stringify(err.response?.data)}`)
384
- );
385
- }
386
- throw new TTSStreamError("sarvam", err);
387
- }
388
- }
389
- /** Synthesize complete audio buffer. */
390
- async synthesizeFull(text, config) {
391
- const chunks = [];
392
- for await (const chunk of this.synthesizeStream(text, config)) {
393
- chunks.push(chunk);
394
- }
395
- return Buffer.concat(chunks);
396
- }
397
- };
398
-
399
- // src/tts/TTS-factory.ts
400
- function createTTS(provider, config) {
401
- const cfg = config ?? {};
402
- switch (provider) {
403
- case "elevenlabs":
404
- return new ElevenLabsTTSProvider(cfg);
405
- case "cartesia":
406
- return new CartesiaTTSProvider(cfg);
407
- case "sarvam":
408
- return new SarvamTTSProvider(cfg);
409
- default: {
410
- const _exhaustive = provider;
411
- throw new Error(`Unknown TTS provider: ${String(_exhaustive)}`);
412
- }
413
- }
414
- }
415
-
416
- export { CartesiaTTSProvider, ElevenLabsTTSProvider, SarvamTTSProvider, createTTS };
417
- //# sourceMappingURL=tts.js.map
418
- //# sourceMappingURL=tts.js.map
package/dist/tts.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/errors/base.ts","../src/errors/tts.errors.ts","../src/tts/cartesia/index.ts","../src/tts/elevenlabs/index.ts","../src/tts/sarvam/index.ts","../src/tts/TTS-factory.ts"],"names":["logger","pino","DEFAULT_VOICE_ID"],"mappings":"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","file":"tts.js","sourcesContent":["/**\r\n * @voice-kit/core — Typed error hierarchy\r\n *\r\n * All VoiceKit errors extend VoiceKitError. Never throw raw Error.\r\n * Every error carries: code, message, provider, callId, retryable, severity.\r\n */\r\n\r\nimport type { ErrorSeverity } from '../types'\r\n\r\n// ─── Base Error ───────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Base class for all VoiceKit errors. Provides structured context for\r\n * logging, alerting, and programmatic error handling.\r\n *\r\n * @example\r\n * ```ts\r\n * try {\r\n * await stt.transcribeBatch(audio)\r\n * } catch (err) {\r\n * if (err instanceof STTError) {\r\n * console.error(err.code, err.provider, err.retryable)\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport class VoiceKitError extends Error {\r\n readonly code: string\r\n readonly callId?: string\r\n readonly provider?: string\r\n readonly retryable: boolean\r\n readonly severity: ErrorSeverity\r\n override readonly cause?: unknown\r\n\r\n constructor(params: {\r\n code: string\r\n message: string\r\n callId?: string\r\n provider?: string\r\n retryable?: boolean\r\n severity?: ErrorSeverity\r\n cause?: unknown\r\n }) {\r\n super(params.message)\r\n this.name = this.constructor.name\r\n this.code = params.code\r\n this.callId = params.callId\r\n this.provider = params.provider\r\n this.retryable = params.retryable ?? false\r\n this.severity = params.severity ?? 'medium'\r\n this.cause = params.cause\r\n\r\n // Maintains proper prototype chain for `instanceof` in transpiled code\r\n Object.setPrototypeOf(this, new.target.prototype)\r\n }\r\n\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n code: this.code,\r\n message: this.message,\r\n callId: this.callId,\r\n provider: this.provider,\r\n retryable: this.retryable,\r\n severity: this.severity,\r\n }\r\n }\r\n}","\r\n// ─── TTS Errors ───────────────────────────────────────────────────────────────\r\n\r\nimport { VoiceKitError } from \"./base\"\r\n\r\n/**\r\n * Errors from text-to-speech providers.\r\n */\r\nexport class TTSError extends VoiceKitError { }\r\n\r\nexport class TTSConnectionError extends TTSError {\r\n constructor(provider: string, cause?: unknown, callId?: string) {\r\n super({\r\n code: 'TTS_CONNECTION_FAILED',\r\n message: `Failed to connect to ${provider} TTS service`,\r\n provider,\r\n callId,\r\n retryable: true,\r\n severity: 'high',\r\n cause,\r\n })\r\n }\r\n}\r\n\r\nexport class TTSStreamError extends TTSError {\r\n constructor(provider: string, cause?: unknown, callId?: string) {\r\n super({\r\n code: 'TTS_STREAM_ERROR',\r\n message: `TTS stream error from ${provider}`,\r\n provider,\r\n callId,\r\n retryable: true,\r\n severity: 'medium',\r\n cause,\r\n })\r\n }\r\n}\r\n\r\nexport class TTSVoiceNotFoundError extends TTSError {\r\n constructor(provider: string, voiceId: string) {\r\n super({\r\n code: 'TTS_VOICE_NOT_FOUND',\r\n message: `Voice '${voiceId}' not found on ${provider}`,\r\n provider,\r\n retryable: false,\r\n severity: 'low',\r\n })\r\n }\r\n}\r\n","/**\r\n * @voice-kit/core — Cartesia TTS Provider\r\n *\r\n * Ultra-low-latency streaming TTS via @cartesia/cartesia-js.\r\n * Target first chunk: < 90ms. Best for latency-critical applications.\r\n */\r\n\r\nimport Cartesia from '@cartesia/cartesia-js'\r\nimport { TTSConnectionError, TTSStreamError } from '../../errors'\r\nimport type { TTSProvider, TTSConfig } from '../../types'\r\nimport pino from 'pino'\r\n\r\nconst logger = pino({ name: '@voice-kit/core:tts:cartesia' })\r\n\r\n/** Cartesia default voice: Barbershop Man — clear and neutral */\r\nconst DEFAULT_VOICE_ID = 'a0e99841-438c-4a64-b679-ae501e7d6091'\r\n\r\n/**\r\n * Cartesia ultra-low-latency TTS provider.\r\n * @internal — obtained via createTTS('cartesia', config)\r\n */\r\nexport class CartesiaTTSProvider implements TTSProvider {\r\n readonly name = 'cartesia'\r\n readonly outputSampleRate = 22_050 // Cartesia default\r\n readonly outputFormat = 'pcm' as const\r\n\r\n private readonly client: Cartesia\r\n private readonly config: Required<TTSConfig>\r\n\r\n constructor(config: TTSConfig) {\r\n const apiKey = config.apiKey ?? process.env['CARTESIA_API_KEY']\r\n if (!apiKey) throw new TTSConnectionError('cartesia', new Error('CARTESIA_API_KEY not set'))\r\n\r\n this.client = new Cartesia({ apiKey })\r\n this.config = {\r\n voiceId: config.voiceId ?? DEFAULT_VOICE_ID,\r\n sampleRate: config.sampleRate ?? 22_050,\r\n speed: config.speed ?? 1.0,\r\n pitch: config.pitch ?? 0,\r\n apiKey,\r\n modelId: config.modelId ?? 'sonic-english',\r\n emotion: config.emotion ?? '',\r\n targetLanguage: config.targetLanguage ?? 'en',\r\n }\r\n }\r\n\r\n /**\r\n * Stream audio from Cartesia. Typically delivers first chunk in < 90ms.\r\n *\r\n * @example\r\n * ```ts\r\n * const tts = createTTS('cartesia', { voiceId: 'your-voice-id' })\r\n * for await (const chunk of tts.synthesizeStream('Hello!')) {\r\n * sendToTelephony(chunk)\r\n * }\r\n * ```\r\n */\r\n async *synthesizeStream(text: string, config?: TTSConfig): AsyncIterable<Buffer> {\r\n const voiceId = config?.voiceId ?? this.config.voiceId\r\n const startMs = Date.now()\r\n\r\n logger.debug({ voiceId, chars: text.length }, 'Cartesia TTS stream start')\r\n\r\n try {\r\n const stream = await this.client.tts.generateSse({\r\n model_id: config?.modelId ?? this.config.modelId,\r\n transcript: text,\r\n voice: {\r\n mode: 'id',\r\n id: voiceId,\r\n ...(this.config.emotion && {\r\n __experimental_controls: {\r\n emotion: [this.config.emotion as `${string}:${string}`],\r\n },\r\n }),\r\n },\r\n output_format: {\r\n container: 'raw',\r\n encoding: 'pcm_s16le',\r\n sample_rate: toValidSampleRate(config?.sampleRate ?? this.config.sampleRate),\r\n },\r\n })\r\n\r\n let firstChunk = true\r\n for await (const event of stream as any) {\r\n // v3 Stainless Stream yields ServerSentEvent objects: { data: string }\r\n // Parse the JSON payload and extract the base64 audio chunk\r\n if (!event.data || event.data === '[DONE]') continue\r\n\r\n let payload: { chunk?: { audio?: string }, type?: string }\r\n try {\r\n payload = JSON.parse(event.data)\r\n } catch {\r\n continue\r\n }\r\n\r\n // Skip non-audio events (e.g. { type: \"timestamps\" })\r\n if (!payload.chunk?.audio) continue\r\n\r\n const buf = Buffer.from(payload.chunk.audio, 'base64')\r\n\r\n if (firstChunk) {\r\n firstChunk = false\r\n logger.debug({ ttfb: Date.now() - startMs, voiceId }, 'Cartesia first audio chunk')\r\n }\r\n\r\n yield buf\r\n }\r\n } catch (err) {\r\n throw new TTSStreamError('cartesia', err)\r\n }\r\n }\r\n\r\n /** Synthesize complete audio. */\r\n async synthesizeFull(text: string, config?: TTSConfig): Promise<Buffer> {\r\n const chunks: Buffer[] = []\r\n for await (const chunk of this.synthesizeStream(text, config)) {\r\n chunks.push(chunk)\r\n }\r\n return Buffer.concat(chunks)\r\n }\r\n}\r\n\r\nconst VALID_SAMPLE_RATES = [22050, 8000, 16000, 24000, 44100, 48000] as const\r\ntype ValidSampleRate = typeof VALID_SAMPLE_RATES[number]\r\n\r\nfunction toValidSampleRate(rate: number): ValidSampleRate {\r\n return (VALID_SAMPLE_RATES as readonly number[]).includes(rate)\r\n ? rate as ValidSampleRate\r\n : 8000\r\n}","/**\r\n * @voice-kit/core — ElevenLabs TTS Provider\r\n *\r\n * Streaming TTS using ElevenLabs SDK. Features:\r\n * - 100ms lookahead jitter buffer to smooth burst delivery\r\n * - Voice clone support\r\n * - Sub-300ms first chunk target\r\n */\r\n\r\nimport { ElevenLabsClient } from 'elevenlabs'\r\nimport { TTSConnectionError, TTSStreamError, TTSVoiceNotFoundError } from '../../errors'\r\nimport type { TTSProvider, TTSConfig } from '../../types'\r\nimport pino from 'pino'\r\n\r\nconst logger = pino({ name: '@voice-kit/core:tts:elevenlabs' })\r\n\r\n/** Default voice: Rachel (neutral, clear, works well for en-IN) */\r\nconst DEFAULT_VOICE_ID = '21m00Tcm4TlvDq8ikWAM'\r\n\r\n/** Lookahead jitter buffer window in ms. Smooths burst packet delivery. */\r\nconst JITTER_BUFFER_MS = 100\r\n\r\n/**\r\n * ElevenLabs streaming TTS provider.\r\n * @internal — obtained via createTTS('elevenlabs', config)\r\n */\r\nexport class ElevenLabsTTSProvider implements TTSProvider {\r\n readonly name = 'elevenlabs'\r\n readonly outputSampleRate = 24_000 // ElevenLabs default: 24kHz\r\n readonly outputFormat = 'pcm' as const\r\n\r\n private readonly client: ElevenLabsClient\r\n private readonly config: Required<TTSConfig>\r\n\r\n constructor(config: TTSConfig) {\r\n const apiKey = config.apiKey ?? process.env['ELEVENLABS_API_KEY']\r\n if (!apiKey) throw new TTSConnectionError('elevenlabs', new Error('ELEVENLABS_API_KEY not set'))\r\n\r\n this.client = new ElevenLabsClient({ apiKey })\r\n this.config = {\r\n voiceId: config.voiceId ?? DEFAULT_VOICE_ID,\r\n sampleRate: config.sampleRate ?? 24_000,\r\n speed: config.speed ?? 1.0,\r\n pitch: config.pitch ?? 0,\r\n apiKey,\r\n modelId: config.modelId ?? 'eleven_turbo_v2_5',\r\n emotion: config.emotion ?? '',\r\n targetLanguage: config.targetLanguage ?? 'en-IN',\r\n }\r\n }\r\n\r\n /**\r\n * Stream synthesized audio from ElevenLabs.\r\n * First chunk target: < 300ms. Uses streaming API endpoint.\r\n *\r\n * A 100ms jitter buffer smooths burst packet delivery without adding\r\n * perceptible latency.\r\n *\r\n * @param text Text to synthesize (should be a sentence boundary chunk)\r\n * @param config Per-call config overrides\r\n *\r\n * @example\r\n * ```ts\r\n * const tts = createTTS('elevenlabs', { voiceId: 'your-voice-id' })\r\n * for await (const chunk of tts.synthesizeStream('Hello, how can I help?')) {\r\n * telephony.sendAudio(chunk)\r\n * }\r\n * ```\r\n */\r\n async *synthesizeStream(text: string, config?: TTSConfig): AsyncIterable<Buffer> {\r\n const voiceId = config?.voiceId ?? this.config.voiceId\r\n const modelId = config?.modelId ?? this.config.modelId\r\n const startMs = Date.now()\r\n\r\n logger.debug({ voiceId, modelId, chars: text.length }, 'ElevenLabs TTS stream start')\r\n\r\n try {\r\n const audioStream = await this.client.generate({\r\n voice: voiceId,\r\n text,\r\n model_id: modelId,\r\n voice_settings: {\r\n stability: 0.5,\r\n similarity_boost: 0.8,\r\n speed: config?.speed ?? this.config.speed,\r\n },\r\n output_format: 'pcm_24000',\r\n stream: true,\r\n })\r\n\r\n let firstChunk = true\r\n let jitterBuffer: Buffer[] = []\r\n let jitterTimer: ReturnType<typeof setTimeout> | null = null\r\n\r\n const flushJitterBuffer = function* () {\r\n for (const chunk of jitterBuffer) {\r\n yield chunk\r\n }\r\n jitterBuffer = []\r\n }\r\n\r\n for await (const chunk of audioStream) {\r\n const buf = chunk instanceof Buffer ? chunk : Buffer.from(chunk as ArrayBuffer)\r\n\r\n if (firstChunk) {\r\n firstChunk = false\r\n const ttfb = Date.now() - startMs\r\n logger.debug({ ttfb, voiceId }, 'ElevenLabs first audio chunk')\r\n }\r\n\r\n // Jitter buffer: collect for 100ms, then flush\r\n jitterBuffer.push(buf)\r\n\r\n if (jitterTimer === null) {\r\n jitterTimer = setTimeout(() => {\r\n // Flush is handled below in the generator — timer signals readiness\r\n }, JITTER_BUFFER_MS)\r\n }\r\n\r\n // Flush if buffer is large enough (avoid holding too much audio)\r\n const totalBytes = jitterBuffer.reduce((sum, b) => sum + b.length, 0)\r\n if (totalBytes >= 4_800) { // 100ms worth of 24kHz 16-bit PCM\r\n if (jitterTimer !== null) {\r\n clearTimeout(jitterTimer)\r\n jitterTimer = null\r\n }\r\n yield* flushJitterBuffer()\r\n }\r\n }\r\n\r\n // Final flush\r\n if (jitterTimer !== null) {\r\n clearTimeout(jitterTimer)\r\n }\r\n yield* flushJitterBuffer()\r\n\r\n logger.debug({ voiceId, totalMs: Date.now() - startMs }, 'ElevenLabs TTS stream complete')\r\n } catch (err) {\r\n if ((err as { statusCode?: number }).statusCode === 404) {\r\n throw new TTSVoiceNotFoundError('elevenlabs', voiceId)\r\n }\r\n throw new TTSStreamError('elevenlabs', err)\r\n }\r\n }\r\n\r\n /**\r\n * Synthesize full audio (for pre-caching greetings, IVR prompts).\r\n * Collects all streaming chunks into a single buffer.\r\n *\r\n * @param text Text to synthesize\r\n * @param config Per-call config overrides\r\n */\r\n async synthesizeFull(text: string, config?: TTSConfig): Promise<Buffer> {\r\n const chunks: Buffer[] = []\r\n for await (const chunk of this.synthesizeStream(text, config)) {\r\n chunks.push(chunk)\r\n }\r\n return Buffer.concat(chunks)\r\n }\r\n}","/**\r\n * @voice-kit/core — Sarvam AI TTS Provider\r\n *\r\n * Sarvam AI TTS for Hindi/Hinglish and regional Indian languages.\r\n * Supports natural-sounding Indian voices with regional accents.\r\n */\r\n\r\nimport axios, { type AxiosInstance } from 'axios'\r\nimport { TTSConnectionError, TTSStreamError } from '../../errors'\r\nimport type { TTSProvider, TTSConfig } from '../../types'\r\nimport pino from 'pino'\r\n\r\nconst logger = pino({ name: '@voice-kit/core:tts:sarvam' })\r\n\r\nconst SARVAM_API_BASE = 'https://api.sarvam.ai'\r\n\r\n/** Available Sarvam TTS voices per language. */\r\nconst SARVAM_VOICES: Record<string, string[]> = {\r\n 'hi-IN': ['meera', 'pavithra', 'maitreyi', 'arvind', 'amol', 'amartya'],\r\n 'kn-IN': ['pavithra', 'meera'],\r\n 'ta-IN': ['pavithra', 'meera'],\r\n 'te-IN': ['pavithra', 'meera'],\r\n 'mr-IN': ['pavithra', 'meera'],\r\n 'bn-IN': ['meera'],\r\n 'gu-IN': ['meera'],\r\n 'pa-IN': ['meera'],\r\n}\r\n\r\n/** Default voices per language. */\r\nconst DEFAULT_VOICES: Record<string, string> = {\r\n 'hi-IN': 'meera',\r\n 'kn-IN': 'pavithra',\r\n 'ta-IN': 'pavithra',\r\n 'te-IN': 'pavithra',\r\n 'mr-IN': 'meera',\r\n 'bn-IN': 'meera',\r\n 'gu-IN': 'meera',\r\n 'pa-IN': 'meera',\r\n}\r\n\r\ninterface SarvamTTSResponse {\r\n audios: string[] // base64 encoded audio segments\r\n}\r\n\r\n/**\r\n * Sarvam AI TTS provider for Indic languages.\r\n * @internal — obtained via createTTS('sarvam', config)\r\n */\r\nexport class SarvamTTSProvider implements TTSProvider {\r\n readonly name = 'sarvam'\r\n readonly outputSampleRate = 22_050 // Sarvam default\r\n readonly outputFormat = 'mp3' as const\r\n\r\n private readonly http: AxiosInstance\r\n private readonly config: Required<TTSConfig>\r\n\r\n constructor(config: TTSConfig) {\r\n const apiKey = config.apiKey ?? process.env['SARVAM_API_KEY']\r\n if (!apiKey) throw new TTSConnectionError('sarvam', new Error('SARVAM_API_KEY not set'))\r\n\r\n const targetLanguage = config.targetLanguage ?? 'hi-IN'\r\n const defaultVoice = DEFAULT_VOICES[targetLanguage] ?? 'meera'\r\n\r\n this.http = axios.create({\r\n baseURL: SARVAM_API_BASE,\r\n headers: {\r\n 'API-Subscription-Key': apiKey,\r\n 'Content-Type': 'application/json',\r\n },\r\n timeout: 15_000,\r\n })\r\n\r\n this.config = {\r\n voiceId: config.voiceId ?? defaultVoice,\r\n sampleRate: config.sampleRate ?? 22_050,\r\n speed: config.speed ?? 1.0,\r\n pitch: config.pitch ?? 0,\r\n apiKey,\r\n modelId: config.modelId ?? 'bulbul:v1',\r\n emotion: '',\r\n targetLanguage,\r\n }\r\n }\r\n\r\n /**\r\n * Synthesize text in an Indic language and stream audio chunks.\r\n * Sarvam returns full audio segments — we chunk them for streaming compatibility.\r\n *\r\n * @example\r\n * ```ts\r\n * const tts = createTTS('sarvam', { targetLanguage: 'hi-IN' })\r\n * for await (const chunk of tts.synthesizeStream('नमस्ते, मैं आपकी कैसे मदद कर सकता हूँ?')) {\r\n * telephony.sendAudio(chunk)\r\n * }\r\n * ```\r\n */\r\n async *synthesizeStream(text: string, config?: TTSConfig): AsyncIterable<Buffer> {\r\n const startMs = Date.now()\r\n const targetLanguage = config?.targetLanguage ?? this.config.targetLanguage\r\n const speaker = config?.voiceId ?? this.config.voiceId\r\n\r\n logger.debug({ targetLanguage, speaker, chars: text.length }, 'Sarvam TTS request')\r\n\r\n try {\r\n const response = await this.http.post<SarvamTTSResponse>('/text-to-speech', {\r\n inputs: [text],\r\n target_language_code: targetLanguage,\r\n speaker,\r\n model: config?.modelId ?? this.config.modelId,\r\n pitch: config?.pitch ?? this.config.pitch,\r\n pace: config?.speed ?? this.config.speed,\r\n loudness: 1.0,\r\n speech_sample_rate: config?.sampleRate ?? this.config.sampleRate,\r\n enable_preprocessing: true,\r\n })\r\n\r\n const audioSegments = response.data.audios\r\n if (!audioSegments || audioSegments.length === 0) {\r\n throw new TTSStreamError('sarvam', new Error('No audio returned from Sarvam TTS'))\r\n }\r\n\r\n logger.debug(\r\n { segments: audioSegments.length, latencyMs: Date.now() - startMs },\r\n 'Sarvam TTS response received'\r\n )\r\n\r\n // Decode base64 segments and stream as chunks\r\n for (const segment of audioSegments) {\r\n const buf = Buffer.from(segment, 'base64')\r\n\r\n // Stream in 4KB chunks for smooth playback\r\n const CHUNK_SIZE = 4_096\r\n let offset = 0\r\n while (offset < buf.length) {\r\n yield buf.subarray(offset, Math.min(offset + CHUNK_SIZE, buf.length))\r\n offset += CHUNK_SIZE\r\n }\r\n }\r\n } catch (err) {\r\n if (axios.isAxiosError(err)) {\r\n throw new TTSStreamError(\r\n 'sarvam',\r\n new Error(`Sarvam TTS API error: ${err.response?.status} ${JSON.stringify(err.response?.data)}`)\r\n )\r\n }\r\n throw new TTSStreamError('sarvam', err)\r\n }\r\n }\r\n\r\n /** Synthesize complete audio buffer. */\r\n async synthesizeFull(text: string, config?: TTSConfig): Promise<Buffer> {\r\n const chunks: Buffer[] = []\r\n for await (const chunk of this.synthesizeStream(text, config)) {\r\n chunks.push(chunk)\r\n }\r\n return Buffer.concat(chunks)\r\n }\r\n}","/**\r\n * @voice-kit/core — TTS factory\r\n *\r\n * createTTS() is the ONLY public API for text-to-speech.\r\n * Never instantiate provider classes directly.\r\n */\r\n\r\nimport type { TTSProvider, TTSConfig } from '../types'\r\nimport { ElevenLabsTTSProvider } from './elevenlabs'\r\nimport { CartesiaTTSProvider } from './cartesia'\r\nimport { SarvamTTSProvider } from './sarvam'\r\n\r\n/**\r\n * Create a TTS provider instance.\r\n *\r\n * Provider selection guide:\r\n * - 'elevenlabs' → Best voice quality, cloning support, en-IN\r\n * - 'cartesia' → Lowest latency (< 90ms TTFB), good for fast-paced agents\r\n * - 'sarvam' → Best for Indic languages (hi-IN, ta-IN, kn-IN, te-IN, mr-IN)\r\n *\r\n * @example\r\n * ```ts\r\n * // English with voice cloning\r\n * const tts = createTTS('elevenlabs', { voiceId: 'your-cloned-voice-id' })\r\n *\r\n * // Ultra-low latency English\r\n * const tts = createTTS('cartesia', { voiceId: 'your-voice-id' })\r\n *\r\n * // Hindi\r\n * const tts = createTTS('sarvam', { targetLanguage: 'hi-IN', voiceId: 'meera' })\r\n * ```\r\n */\r\nexport function createTTS(\r\n provider: 'elevenlabs' | 'cartesia' | 'sarvam',\r\n config?: TTSConfig\r\n): TTSProvider {\r\n const cfg = config ?? {}\r\n\r\n switch (provider) {\r\n case 'elevenlabs':\r\n return new ElevenLabsTTSProvider(cfg)\r\n case 'cartesia':\r\n return new CartesiaTTSProvider(cfg)\r\n case 'sarvam':\r\n return new SarvamTTSProvider(cfg)\r\n default: {\r\n const _exhaustive: never = provider\r\n throw new Error(`Unknown TTS provider: ${String(_exhaustive)}`)\r\n }\r\n }\r\n}"]}