@framers/agentos-ext-streaming-tts-elevenlabs 0.2.0
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/LICENSE +23 -0
- package/SKILL.md +65 -0
- package/dist/ElevenLabsStreamingTTS.d.ts +64 -0
- package/dist/ElevenLabsStreamingTTS.d.ts.map +1 -0
- package/dist/ElevenLabsStreamingTTS.js +91 -0
- package/dist/ElevenLabsStreamingTTS.js.map +1 -0
- package/dist/ElevenLabsTTSSession.d.ts +147 -0
- package/dist/ElevenLabsTTSSession.d.ts.map +1 -0
- package/dist/ElevenLabsTTSSession.js +334 -0
- package/dist/ElevenLabsTTSSession.js.map +1 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +120 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/manifest.json +8 -0
- package/package.json +45 -0
- package/src/ElevenLabsStreamingTTS.ts +100 -0
- package/src/ElevenLabsTTSSession.ts +385 -0
- package/src/index.ts +125 -0
- package/src/types.ts +132 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Framers
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: streaming-tts-elevenlabs
|
|
3
|
+
description: Streaming text-to-speech via ElevenLabs WebSocket API with real-time audio generation
|
|
4
|
+
category: voice
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ElevenLabs Streaming TTS
|
|
8
|
+
|
|
9
|
+
Low-latency streaming text-to-speech using the ElevenLabs WebSocket Streaming API. Maintains a
|
|
10
|
+
persistent WebSocket connection per session and streams audio chunks as MP3 data as soon as each
|
|
11
|
+
sentence boundary is reached, enabling near-instant audio playback.
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
|
|
15
|
+
Set `ELEVENLABS_API_KEY` in your environment or agent secrets store.
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- Persistent WebSocket connection per session (no per-request HTTP overhead)
|
|
20
|
+
- Real-time audio streaming: ElevenLabs generates and sends audio as tokens arrive
|
|
21
|
+
- Automatic sentence-boundary flushing (`.`, `?`, `!`) for low-latency output
|
|
22
|
+
- Configurable voice via ElevenLabs voice ID
|
|
23
|
+
- Configurable model (eleven_turbo_v2 for low latency, eleven_multilingual_v2 for quality)
|
|
24
|
+
- Voice settings: stability, similarity boost, style, speaker boost
|
|
25
|
+
- MP3 output at 44.1 kHz / 128 kbps
|
|
26
|
+
|
|
27
|
+
## Configuration
|
|
28
|
+
|
|
29
|
+
In `agent.config.json`:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"voice": {
|
|
34
|
+
"tts": "elevenlabs"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Provider-specific options via `providerOptions`:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"voice": {
|
|
44
|
+
"tts": "elevenlabs",
|
|
45
|
+
"providerOptions": {
|
|
46
|
+
"voiceId": "21m00Tcm4TlvDq8ikWAM",
|
|
47
|
+
"modelId": "eleven_turbo_v2",
|
|
48
|
+
"stability": 0.5,
|
|
49
|
+
"similarityBoost": 0.75,
|
|
50
|
+
"style": 0.0,
|
|
51
|
+
"useSpeakerBoost": true
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Events
|
|
58
|
+
|
|
59
|
+
| Event | Payload | Description |
|
|
60
|
+
|----------------------|-------------------------|----------------------------------------------------|
|
|
61
|
+
| `audio_chunk` | `EncodedAudioChunk` | MP3 audio buffer ready for playback |
|
|
62
|
+
| `utterance_complete` | `{ text, durationMs }` | ElevenLabs signalled final audio generation done |
|
|
63
|
+
| `cancelled` | `{ remaining: string }` | Session was cancelled; remaining text not rendered |
|
|
64
|
+
| `error` | `Error` | WebSocket or synthesis error |
|
|
65
|
+
| `close` | — | Session fully terminated |
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file ElevenLabsStreamingTTS.ts
|
|
3
|
+
* @description {@link IStreamingTTS}-compatible factory for ElevenLabs TTS sessions.
|
|
4
|
+
*
|
|
5
|
+
* {@link ElevenLabsStreamingTTS} is a thin factory that creates
|
|
6
|
+
* {@link ElevenLabsTTSSession} instances on demand. It holds no mutable state
|
|
7
|
+
* other than an active-session reference count used to implement {@link isStreaming}.
|
|
8
|
+
*
|
|
9
|
+
* @module streaming-tts-elevenlabs/ElevenLabsStreamingTTS
|
|
10
|
+
*/
|
|
11
|
+
import { ElevenLabsTTSSession } from './ElevenLabsTTSSession.js';
|
|
12
|
+
import type { ElevenLabsStreamingTTSConfig, StreamingTTSConfig } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Factory for ElevenLabs-backed streaming TTS sessions.
|
|
15
|
+
*
|
|
16
|
+
* Instantiate once per agent and reuse across voice turns. Each call to
|
|
17
|
+
* {@link startSession} creates an independent {@link ElevenLabsTTSSession} that
|
|
18
|
+
* owns its own WebSocket connection lifecycle.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const tts = new ElevenLabsStreamingTTS({ apiKey: process.env.ELEVENLABS_API_KEY! });
|
|
23
|
+
* const session = await tts.startSession();
|
|
24
|
+
*
|
|
25
|
+
* session.on('audio_chunk', (chunk) => audioPlayer.enqueue(chunk.audio));
|
|
26
|
+
*
|
|
27
|
+
* llm.on('token', (tok) => session.pushTokens(tok));
|
|
28
|
+
* llm.on('end', () => session.flush());
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class ElevenLabsStreamingTTS {
|
|
32
|
+
private readonly config;
|
|
33
|
+
/**
|
|
34
|
+
* Stable provider identifier used by the voice pipeline to select between
|
|
35
|
+
* registered TTS implementations.
|
|
36
|
+
*/
|
|
37
|
+
readonly providerId = "elevenlabs-streaming-tts";
|
|
38
|
+
/** `true` while at least one session is open and not yet closed. */
|
|
39
|
+
get isStreaming(): boolean;
|
|
40
|
+
/** Count of sessions opened but not yet closed or cancelled. */
|
|
41
|
+
private _activeSessions;
|
|
42
|
+
/**
|
|
43
|
+
* @param config - ElevenLabs provider configuration. `apiKey` is required;
|
|
44
|
+
* all other fields have sensible defaults.
|
|
45
|
+
*/
|
|
46
|
+
constructor(config: ElevenLabsStreamingTTSConfig);
|
|
47
|
+
/**
|
|
48
|
+
* Open a new streaming TTS session backed by a fresh WebSocket connection.
|
|
49
|
+
*
|
|
50
|
+
* Provider-specific options can be forwarded via `config.providerOptions`
|
|
51
|
+
* under the following keys:
|
|
52
|
+
* - `voiceId` — ElevenLabs voice ID (default Rachel).
|
|
53
|
+
* - `modelId` — Model ID (default `'eleven_turbo_v2'`).
|
|
54
|
+
* - `stability` — Voice stability 0.0–1.0 (default `0.5`).
|
|
55
|
+
* - `similarityBoost`— Similarity boost 0.0–1.0 (default `0.75`).
|
|
56
|
+
* - `style` — Style exaggeration 0.0–1.0 (default `0.0`).
|
|
57
|
+
* - `useSpeakerBoost`— Speaker boost enabled (default `true`).
|
|
58
|
+
*
|
|
59
|
+
* @param config - Generic session config merged with provider defaults.
|
|
60
|
+
* @returns A ready-to-use {@link ElevenLabsTTSSession}.
|
|
61
|
+
*/
|
|
62
|
+
startSession(config?: StreamingTTSConfig): Promise<ElevenLabsTTSSession>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=ElevenLabsStreamingTTS.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ElevenLabsStreamingTTS.d.ts","sourceRoot":"","sources":["../src/ElevenLabsStreamingTTS.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,4BAA4B,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAMnF;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,sBAAsB;IAmBrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAlBnC;;;OAGG;IACH,QAAQ,CAAC,UAAU,8BAA8B;IAEjD,oEAAoE;IACpE,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,gEAAgE;IAChE,OAAO,CAAC,eAAe,CAAK;IAE5B;;;OAGG;gBAC0B,MAAM,EAAE,4BAA4B;IAEjE;;;;;;;;;;;;;;OAcG;IACG,YAAY,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CA2B/E"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file ElevenLabsStreamingTTS.ts
|
|
3
|
+
* @description {@link IStreamingTTS}-compatible factory for ElevenLabs TTS sessions.
|
|
4
|
+
*
|
|
5
|
+
* {@link ElevenLabsStreamingTTS} is a thin factory that creates
|
|
6
|
+
* {@link ElevenLabsTTSSession} instances on demand. It holds no mutable state
|
|
7
|
+
* other than an active-session reference count used to implement {@link isStreaming}.
|
|
8
|
+
*
|
|
9
|
+
* @module streaming-tts-elevenlabs/ElevenLabsStreamingTTS
|
|
10
|
+
*/
|
|
11
|
+
import { ElevenLabsTTSSession } from './ElevenLabsTTSSession.js';
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Main class
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* Factory for ElevenLabs-backed streaming TTS sessions.
|
|
17
|
+
*
|
|
18
|
+
* Instantiate once per agent and reuse across voice turns. Each call to
|
|
19
|
+
* {@link startSession} creates an independent {@link ElevenLabsTTSSession} that
|
|
20
|
+
* owns its own WebSocket connection lifecycle.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const tts = new ElevenLabsStreamingTTS({ apiKey: process.env.ELEVENLABS_API_KEY! });
|
|
25
|
+
* const session = await tts.startSession();
|
|
26
|
+
*
|
|
27
|
+
* session.on('audio_chunk', (chunk) => audioPlayer.enqueue(chunk.audio));
|
|
28
|
+
*
|
|
29
|
+
* llm.on('token', (tok) => session.pushTokens(tok));
|
|
30
|
+
* llm.on('end', () => session.flush());
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export class ElevenLabsStreamingTTS {
|
|
34
|
+
config;
|
|
35
|
+
/**
|
|
36
|
+
* Stable provider identifier used by the voice pipeline to select between
|
|
37
|
+
* registered TTS implementations.
|
|
38
|
+
*/
|
|
39
|
+
providerId = 'elevenlabs-streaming-tts';
|
|
40
|
+
/** `true` while at least one session is open and not yet closed. */
|
|
41
|
+
get isStreaming() {
|
|
42
|
+
return this._activeSessions > 0;
|
|
43
|
+
}
|
|
44
|
+
/** Count of sessions opened but not yet closed or cancelled. */
|
|
45
|
+
_activeSessions = 0;
|
|
46
|
+
/**
|
|
47
|
+
* @param config - ElevenLabs provider configuration. `apiKey` is required;
|
|
48
|
+
* all other fields have sensible defaults.
|
|
49
|
+
*/
|
|
50
|
+
constructor(config) {
|
|
51
|
+
this.config = config;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Open a new streaming TTS session backed by a fresh WebSocket connection.
|
|
55
|
+
*
|
|
56
|
+
* Provider-specific options can be forwarded via `config.providerOptions`
|
|
57
|
+
* under the following keys:
|
|
58
|
+
* - `voiceId` — ElevenLabs voice ID (default Rachel).
|
|
59
|
+
* - `modelId` — Model ID (default `'eleven_turbo_v2'`).
|
|
60
|
+
* - `stability` — Voice stability 0.0–1.0 (default `0.5`).
|
|
61
|
+
* - `similarityBoost`— Similarity boost 0.0–1.0 (default `0.75`).
|
|
62
|
+
* - `style` — Style exaggeration 0.0–1.0 (default `0.0`).
|
|
63
|
+
* - `useSpeakerBoost`— Speaker boost enabled (default `true`).
|
|
64
|
+
*
|
|
65
|
+
* @param config - Generic session config merged with provider defaults.
|
|
66
|
+
* @returns A ready-to-use {@link ElevenLabsTTSSession}.
|
|
67
|
+
*/
|
|
68
|
+
async startSession(config) {
|
|
69
|
+
const provOpts = (config?.providerOptions ?? {});
|
|
70
|
+
// Session-level overrides take precedence over factory-level config.
|
|
71
|
+
const sessionProviderConfig = {
|
|
72
|
+
...this.config,
|
|
73
|
+
voiceId: provOpts.voiceId ?? this.config.voiceId,
|
|
74
|
+
modelId: provOpts.modelId ?? this.config.modelId,
|
|
75
|
+
stability: provOpts.stability ?? this.config.stability,
|
|
76
|
+
similarityBoost: provOpts.similarityBoost ?? this.config.similarityBoost,
|
|
77
|
+
style: provOpts.style ?? this.config.style,
|
|
78
|
+
useSpeakerBoost: provOpts.useSpeakerBoost ?? this.config.useSpeakerBoost,
|
|
79
|
+
};
|
|
80
|
+
const session = new ElevenLabsTTSSession(sessionProviderConfig, config ?? {});
|
|
81
|
+
this._activeSessions++;
|
|
82
|
+
// Decrement the counter when the session terminates for any reason.
|
|
83
|
+
const onDone = () => {
|
|
84
|
+
this._activeSessions = Math.max(0, this._activeSessions - 1);
|
|
85
|
+
};
|
|
86
|
+
session.once('close', onDone);
|
|
87
|
+
session.once('cancelled', onDone);
|
|
88
|
+
return session;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=ElevenLabsStreamingTTS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ElevenLabsStreamingTTS.js","sourceRoot":"","sources":["../src/ElevenLabsStreamingTTS.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGjE,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,sBAAsB;IAmBJ;IAlB7B;;;OAGG;IACM,UAAU,GAAG,0BAA0B,CAAC;IAEjD,oEAAoE;IACpE,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,gEAAgE;IACxD,eAAe,GAAG,CAAC,CAAC;IAE5B;;;OAGG;IACH,YAA6B,MAAoC;QAApC,WAAM,GAAN,MAAM,CAA8B;IAAG,CAAC;IAErE;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,YAAY,CAAC,MAA2B;QAC5C,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE,CAA0C,CAAC;QAE1F,qEAAqE;QACrE,MAAM,qBAAqB,GAAiC;YAC1D,GAAG,IAAI,CAAC,MAAM;YACd,OAAO,EAAS,QAAQ,CAAC,OAAO,IAAY,IAAI,CAAC,MAAM,CAAC,OAAO;YAC/D,OAAO,EAAS,QAAQ,CAAC,OAAO,IAAY,IAAI,CAAC,MAAM,CAAC,OAAO;YAC/D,SAAS,EAAO,QAAQ,CAAC,SAAS,IAAU,IAAI,CAAC,MAAM,CAAC,SAAS;YACjE,eAAe,EAAC,QAAQ,CAAC,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe;YACvE,KAAK,EAAW,QAAQ,CAAC,KAAK,IAAc,IAAI,CAAC,MAAM,CAAC,KAAK;YAC7D,eAAe,EAAC,QAAQ,CAAC,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe;SACxE,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,oBAAoB,CAAC,qBAAqB,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;QAE9E,IAAI,CAAC,eAAe,EAAE,CAAC;QAEvB,oEAAoE;QACpE,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,OAAO,EAAM,MAAM,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAElC,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file ElevenLabsTTSSession.ts
|
|
3
|
+
* @description Active TTS session backed by the ElevenLabs WebSocket Streaming API.
|
|
4
|
+
*
|
|
5
|
+
* {@link ElevenLabsTTSSession} implements the `StreamingTTSSession` interface
|
|
6
|
+
* (EventEmitter) and provides the following events:
|
|
7
|
+
*
|
|
8
|
+
* | Event | Payload | Description |
|
|
9
|
+
* |----------------------|----------------------------|------------------------------------------------------|
|
|
10
|
+
* | `'audio_chunk'` | `EncodedAudioChunk` | MP3 audio buffer from ElevenLabs, ready for playback |
|
|
11
|
+
* | `'utterance_complete'`| `{ text, durationMs }` | ElevenLabs signalled end of audio generation |
|
|
12
|
+
* | `'cancelled'` | `{ remaining: string }` | Session cancelled; remaining text not rendered |
|
|
13
|
+
* | `'error'` | `Error` | WebSocket or protocol error |
|
|
14
|
+
* | `'close'` | — | Session fully terminated |
|
|
15
|
+
*
|
|
16
|
+
* ### Protocol Overview
|
|
17
|
+
*
|
|
18
|
+
* The ElevenLabs WebSocket streaming protocol works as follows:
|
|
19
|
+
*
|
|
20
|
+
* 1. Open WSS connection to the voice/model endpoint.
|
|
21
|
+
* 2. Send a BOS (Beginning-Of-Stream) message: `{ text: " ", voice_settings: {...}, xi_api_key }`.
|
|
22
|
+
* 3. Stream text tokens as `{ text: "..." }` JSON messages.
|
|
23
|
+
* 4. To generate audio for accumulated text, include `flush: true` in the text message.
|
|
24
|
+
* 5. To end the stream, send an EOS (End-Of-Stream) message: `{ text: "" }`.
|
|
25
|
+
* 6. The server returns binary messages (MP3 audio chunks) and JSON status messages.
|
|
26
|
+
* 7. When all audio has been generated the server sends `{ isFinal: true }`.
|
|
27
|
+
*
|
|
28
|
+
* @module streaming-tts-elevenlabs/ElevenLabsTTSSession
|
|
29
|
+
*/
|
|
30
|
+
import { EventEmitter } from 'node:events';
|
|
31
|
+
import type { ElevenLabsStreamingTTSConfig, StreamingTTSConfig } from './types.js';
|
|
32
|
+
/**
|
|
33
|
+
* Active streaming TTS session backed by the ElevenLabs WebSocket Streaming API.
|
|
34
|
+
*
|
|
35
|
+
* Construct via {@link ElevenLabsStreamingTTS.startSession} rather than directly.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const session = new ElevenLabsTTSSession(
|
|
40
|
+
* { apiKey: process.env.ELEVENLABS_API_KEY! },
|
|
41
|
+
* {},
|
|
42
|
+
* );
|
|
43
|
+
*
|
|
44
|
+
* session.on('audio_chunk', (chunk) => audioPlayer.enqueue(chunk.audio));
|
|
45
|
+
* session.on('utterance_complete', ({ text, durationMs }) => {
|
|
46
|
+
* console.log(`Synthesis complete ~${durationMs} ms`);
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* llm.on('token', (tok) => session.pushTokens(tok));
|
|
50
|
+
* llm.on('end', () => session.flush());
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare class ElevenLabsTTSSession extends EventEmitter {
|
|
54
|
+
private readonly providerConfig;
|
|
55
|
+
/** ElevenLabs voice ID. */
|
|
56
|
+
private readonly voiceId;
|
|
57
|
+
/** ElevenLabs model ID. */
|
|
58
|
+
private readonly modelId;
|
|
59
|
+
/** Voice stability (0.0 – 1.0). */
|
|
60
|
+
private readonly stability;
|
|
61
|
+
/** Similarity boost (0.0 – 1.0). */
|
|
62
|
+
private readonly similarityBoost;
|
|
63
|
+
/** Style exaggeration (0.0 – 1.0). */
|
|
64
|
+
private readonly style;
|
|
65
|
+
/** Whether to enable speaker boost. */
|
|
66
|
+
private readonly useSpeakerBoost;
|
|
67
|
+
/** Live WebSocket connection to the ElevenLabs streaming endpoint. */
|
|
68
|
+
private readonly ws;
|
|
69
|
+
/**
|
|
70
|
+
* Text that has been pushed since the last sentence-boundary flush.
|
|
71
|
+
*
|
|
72
|
+
* Accumulated so that `cancel()` can report the remaining un-synthesised text.
|
|
73
|
+
*/
|
|
74
|
+
private pendingText;
|
|
75
|
+
/** `true` after {@link close} or {@link cancel} is called. */
|
|
76
|
+
private closed;
|
|
77
|
+
/**
|
|
78
|
+
* Whether the BOS (beginning-of-stream) message has been sent.
|
|
79
|
+
*
|
|
80
|
+
* The BOS is sent once on `ws.open`; subsequent messages are plain text sends.
|
|
81
|
+
*/
|
|
82
|
+
private bosAcknowledged;
|
|
83
|
+
/**
|
|
84
|
+
* Queue of text segments that need to be sent once the WebSocket opens.
|
|
85
|
+
*
|
|
86
|
+
* If `pushTokens` or `flush` is called before the socket is open, messages
|
|
87
|
+
* are queued here and drained on `ws.open`.
|
|
88
|
+
*/
|
|
89
|
+
private readonly sendQueue;
|
|
90
|
+
/**
|
|
91
|
+
* @param providerConfig - ElevenLabs-specific configuration (apiKey required).
|
|
92
|
+
* @param _sessionConfig - Generic voice-pipeline session config (reserved for
|
|
93
|
+
* future `language` forwarding).
|
|
94
|
+
*/
|
|
95
|
+
constructor(providerConfig: ElevenLabsStreamingTTSConfig, _sessionConfig: StreamingTTSConfig);
|
|
96
|
+
/**
|
|
97
|
+
* Push LLM output token(s) into the stream.
|
|
98
|
+
*
|
|
99
|
+
* Text is accumulated in an internal buffer. When a sentence boundary
|
|
100
|
+
* (`.`, `?`, `!`) is detected the accumulated segment is sent to ElevenLabs
|
|
101
|
+
* with `flush: true` so the server generates audio immediately. Mid-sentence
|
|
102
|
+
* tokens are sent with a trailing space continuation to avoid falling intonation
|
|
103
|
+
* on partial phrases.
|
|
104
|
+
*
|
|
105
|
+
* @param text - One or more LLM token characters to append.
|
|
106
|
+
*/
|
|
107
|
+
pushTokens(text: string): void;
|
|
108
|
+
/**
|
|
109
|
+
* Flush any remaining buffered text and signal EOS to ElevenLabs.
|
|
110
|
+
*
|
|
111
|
+
* Call this when the LLM stream has ended. Sends an EOS (end-of-stream)
|
|
112
|
+
* message (`{ text: "" }`) which instructs ElevenLabs to finalise audio
|
|
113
|
+
* generation for all remaining buffered text and close the stream.
|
|
114
|
+
*
|
|
115
|
+
* @returns Promise that resolves when the EOS message is queued for sending.
|
|
116
|
+
*/
|
|
117
|
+
flush(): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Cancel the session immediately.
|
|
120
|
+
*
|
|
121
|
+
* Closes the WebSocket, discards any unsent text, and emits a `'cancelled'`
|
|
122
|
+
* event carrying the remaining un-synthesised text.
|
|
123
|
+
*/
|
|
124
|
+
cancel(): void;
|
|
125
|
+
/**
|
|
126
|
+
* Close the session cleanly.
|
|
127
|
+
*
|
|
128
|
+
* Sends a WebSocket close frame and emits a `'close'` event.
|
|
129
|
+
* Idempotent — safe to call multiple times.
|
|
130
|
+
*/
|
|
131
|
+
close(): void;
|
|
132
|
+
/**
|
|
133
|
+
* Attach event listeners to the WebSocket instance and handle the full
|
|
134
|
+
* message lifecycle.
|
|
135
|
+
*/
|
|
136
|
+
private _wireWebSocket;
|
|
137
|
+
/**
|
|
138
|
+
* Send a JSON message over the WebSocket.
|
|
139
|
+
*
|
|
140
|
+
* If the socket is not yet open, the message is queued and will be sent once
|
|
141
|
+
* the `open` event fires (after the BOS message is dispatched).
|
|
142
|
+
*
|
|
143
|
+
* @param msg - The message object to serialise and send.
|
|
144
|
+
*/
|
|
145
|
+
private _send;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=ElevenLabsTTSSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ElevenLabsTTSSession.d.ts","sourceRoot":"","sources":["../src/ElevenLabsTTSSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,4BAA4B,EAAE,kBAAkB,EAAqB,MAAM,YAAY,CAAC;AAoDtG;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;IAiElD,OAAO,CAAC,QAAQ,CAAC,cAAc;IA5DjC,2BAA2B;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,2BAA2B;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,mCAAmC;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,oCAAoC;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,sCAAsC;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,uCAAuC;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;IAM1C,sEAAsE;IACtE,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAY;IAE/B;;;;OAIG;IACH,OAAO,CAAC,WAAW,CAAM;IAEzB,8DAA8D;IAC9D,OAAO,CAAC,MAAM,CAAS;IAEvB;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAS;IAEhC;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAM/C;;;;OAIG;gBAEgB,cAAc,EAAE,4BAA4B,EAC7D,cAAc,EAAE,kBAAkB;IA0BpC;;;;;;;;;;OAUG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAoB9B;;;;;;;;OAQG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;;;;OAKG;IACH,MAAM,IAAI,IAAI;IAWd;;;;;OAKG;IACH,KAAK,IAAI,IAAI;IAYb;;;OAGG;IACH,OAAO,CAAC,cAAc;IA8EtB;;;;;;;OAOG;IACH,OAAO,CAAC,KAAK;CAQd"}
|