@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.
@@ -0,0 +1,334 @@
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 WebSocket from 'ws';
32
+ // ---------------------------------------------------------------------------
33
+ // Constants
34
+ // ---------------------------------------------------------------------------
35
+ /** ElevenLabs WebSocket API base URL. */
36
+ const ELEVENLABS_WS_BASE = 'wss://api.elevenlabs.io';
37
+ /** Default voice ID — Rachel (a neutral, clear English voice). */
38
+ const DEFAULT_VOICE_ID = '21m00Tcm4TlvDq8ikWAM';
39
+ /** Default model — ElevenLabs Turbo v2, optimized for low latency. */
40
+ const DEFAULT_MODEL_ID = 'eleven_turbo_v2';
41
+ /** MP3 output format at 44.1 kHz / 128 kbps. */
42
+ const OUTPUT_FORMAT = 'mp3_44100_128';
43
+ /** Sample rate that matches the OUTPUT_FORMAT specifier. */
44
+ const SAMPLE_RATE_HZ = 44_100;
45
+ /**
46
+ * Rough estimate of spoken word rate used to compute {@link EncodedAudioChunk.durationMs}.
47
+ * 150 words per minute.
48
+ */
49
+ const WORDS_PER_MS = 150 / 60_000;
50
+ /** Regex matching sentence-final punctuation. */
51
+ const SENTENCE_BOUNDARY_RE = /[.?!]/;
52
+ // ---------------------------------------------------------------------------
53
+ // Helpers
54
+ // ---------------------------------------------------------------------------
55
+ /**
56
+ * Estimate the spoken duration in milliseconds for a piece of text.
57
+ *
58
+ * Uses a simple word-count heuristic (150 WPM). Callers should treat the result
59
+ * as a hint rather than a precise measurement.
60
+ *
61
+ * @param text - The text to estimate duration for.
62
+ * @returns Estimated playback duration in milliseconds (minimum 200 ms).
63
+ */
64
+ function estimateDurationMs(text) {
65
+ const wordCount = text.trim().split(/\s+/).filter(Boolean).length;
66
+ return Math.max(200, Math.round(wordCount / WORDS_PER_MS));
67
+ }
68
+ // ---------------------------------------------------------------------------
69
+ // Main class
70
+ // ---------------------------------------------------------------------------
71
+ /**
72
+ * Active streaming TTS session backed by the ElevenLabs WebSocket Streaming API.
73
+ *
74
+ * Construct via {@link ElevenLabsStreamingTTS.startSession} rather than directly.
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * const session = new ElevenLabsTTSSession(
79
+ * { apiKey: process.env.ELEVENLABS_API_KEY! },
80
+ * {},
81
+ * );
82
+ *
83
+ * session.on('audio_chunk', (chunk) => audioPlayer.enqueue(chunk.audio));
84
+ * session.on('utterance_complete', ({ text, durationMs }) => {
85
+ * console.log(`Synthesis complete ~${durationMs} ms`);
86
+ * });
87
+ *
88
+ * llm.on('token', (tok) => session.pushTokens(tok));
89
+ * llm.on('end', () => session.flush());
90
+ * ```
91
+ */
92
+ export class ElevenLabsTTSSession extends EventEmitter {
93
+ providerConfig;
94
+ // -------------------------------------------------------------------------
95
+ // Resolved config
96
+ // -------------------------------------------------------------------------
97
+ /** ElevenLabs voice ID. */
98
+ voiceId;
99
+ /** ElevenLabs model ID. */
100
+ modelId;
101
+ /** Voice stability (0.0 – 1.0). */
102
+ stability;
103
+ /** Similarity boost (0.0 – 1.0). */
104
+ similarityBoost;
105
+ /** Style exaggeration (0.0 – 1.0). */
106
+ style;
107
+ /** Whether to enable speaker boost. */
108
+ useSpeakerBoost;
109
+ // -------------------------------------------------------------------------
110
+ // Internal state
111
+ // -------------------------------------------------------------------------
112
+ /** Live WebSocket connection to the ElevenLabs streaming endpoint. */
113
+ ws;
114
+ /**
115
+ * Text that has been pushed since the last sentence-boundary flush.
116
+ *
117
+ * Accumulated so that `cancel()` can report the remaining un-synthesised text.
118
+ */
119
+ pendingText = '';
120
+ /** `true` after {@link close} or {@link cancel} is called. */
121
+ closed = false;
122
+ /**
123
+ * Whether the BOS (beginning-of-stream) message has been sent.
124
+ *
125
+ * The BOS is sent once on `ws.open`; subsequent messages are plain text sends.
126
+ */
127
+ bosAcknowledged = false;
128
+ /**
129
+ * Queue of text segments that need to be sent once the WebSocket opens.
130
+ *
131
+ * If `pushTokens` or `flush` is called before the socket is open, messages
132
+ * are queued here and drained on `ws.open`.
133
+ */
134
+ sendQueue = [];
135
+ // -------------------------------------------------------------------------
136
+ // Constructor
137
+ // -------------------------------------------------------------------------
138
+ /**
139
+ * @param providerConfig - ElevenLabs-specific configuration (apiKey required).
140
+ * @param _sessionConfig - Generic voice-pipeline session config (reserved for
141
+ * future `language` forwarding).
142
+ */
143
+ constructor(providerConfig, _sessionConfig) {
144
+ super();
145
+ this.providerConfig = providerConfig;
146
+ // Apply defaults.
147
+ this.voiceId = providerConfig.voiceId ?? DEFAULT_VOICE_ID;
148
+ this.modelId = providerConfig.modelId ?? DEFAULT_MODEL_ID;
149
+ this.stability = providerConfig.stability ?? 0.5;
150
+ this.similarityBoost = providerConfig.similarityBoost ?? 0.75;
151
+ this.style = providerConfig.style ?? 0.0;
152
+ this.useSpeakerBoost = providerConfig.useSpeakerBoost ?? true;
153
+ // Build the WebSocket endpoint URL.
154
+ const wsUrl = `${ELEVENLABS_WS_BASE}/v1/text-to-speech/${this.voiceId}/stream-input` +
155
+ `?model_id=${this.modelId}&output_format=${OUTPUT_FORMAT}`;
156
+ this.ws = new WebSocket(wsUrl);
157
+ this._wireWebSocket();
158
+ }
159
+ // -------------------------------------------------------------------------
160
+ // StreamingTTSSession interface
161
+ // -------------------------------------------------------------------------
162
+ /**
163
+ * Push LLM output token(s) into the stream.
164
+ *
165
+ * Text is accumulated in an internal buffer. When a sentence boundary
166
+ * (`.`, `?`, `!`) is detected the accumulated segment is sent to ElevenLabs
167
+ * with `flush: true` so the server generates audio immediately. Mid-sentence
168
+ * tokens are sent with a trailing space continuation to avoid falling intonation
169
+ * on partial phrases.
170
+ *
171
+ * @param text - One or more LLM token characters to append.
172
+ */
173
+ pushTokens(text) {
174
+ if (this.closed)
175
+ return;
176
+ this.pendingText += text;
177
+ // Check for sentence-boundary punctuation.
178
+ const hasBoundary = SENTENCE_BOUNDARY_RE.test(text);
179
+ if (hasBoundary) {
180
+ // Send the accumulated text with flush: true so ElevenLabs generates audio.
181
+ const segment = this.pendingText;
182
+ this.pendingText = '';
183
+ this._send({ text: segment, flush: true });
184
+ }
185
+ else {
186
+ // Send the token chunk without flush; include a space continuation to hint
187
+ // that the phrase is mid-sentence (prevents falling prosody on partial text).
188
+ this._send({ text });
189
+ }
190
+ }
191
+ /**
192
+ * Flush any remaining buffered text and signal EOS to ElevenLabs.
193
+ *
194
+ * Call this when the LLM stream has ended. Sends an EOS (end-of-stream)
195
+ * message (`{ text: "" }`) which instructs ElevenLabs to finalise audio
196
+ * generation for all remaining buffered text and close the stream.
197
+ *
198
+ * @returns Promise that resolves when the EOS message is queued for sending.
199
+ */
200
+ async flush() {
201
+ if (this.closed)
202
+ return;
203
+ // If there is buffered text that has not been sent, send it with flush: true first.
204
+ if (this.pendingText.trim().length > 0) {
205
+ const segment = this.pendingText;
206
+ this.pendingText = '';
207
+ this._send({ text: segment, flush: true });
208
+ }
209
+ // Send EOS — empty string signals end of stream to ElevenLabs.
210
+ this._send({ text: '' });
211
+ }
212
+ /**
213
+ * Cancel the session immediately.
214
+ *
215
+ * Closes the WebSocket, discards any unsent text, and emits a `'cancelled'`
216
+ * event carrying the remaining un-synthesised text.
217
+ */
218
+ cancel() {
219
+ if (this.closed)
220
+ return;
221
+ this.closed = true;
222
+ const remaining = this.pendingText;
223
+ this.pendingText = '';
224
+ this.ws.close();
225
+ this.emit('cancelled', { remaining });
226
+ }
227
+ /**
228
+ * Close the session cleanly.
229
+ *
230
+ * Sends a WebSocket close frame and emits a `'close'` event.
231
+ * Idempotent — safe to call multiple times.
232
+ */
233
+ close() {
234
+ if (this.closed)
235
+ return;
236
+ this.closed = true;
237
+ this.ws.close();
238
+ this.emit('close');
239
+ }
240
+ // -------------------------------------------------------------------------
241
+ // Internal — WebSocket wiring
242
+ // -------------------------------------------------------------------------
243
+ /**
244
+ * Attach event listeners to the WebSocket instance and handle the full
245
+ * message lifecycle.
246
+ */
247
+ _wireWebSocket() {
248
+ this.ws.on('open', () => {
249
+ // Send BOS message immediately on connection open.
250
+ const bosMessage = {
251
+ text: ' ',
252
+ voice_settings: {
253
+ stability: this.stability,
254
+ similarity_boost: this.similarityBoost,
255
+ style: this.style,
256
+ use_speaker_boost: this.useSpeakerBoost,
257
+ },
258
+ xi_api_key: this.providerConfig.apiKey,
259
+ };
260
+ // Use the raw WS send to bypass the queue (BOS must be first).
261
+ this.ws.send(JSON.stringify(bosMessage));
262
+ this.bosAcknowledged = true;
263
+ // Drain any messages queued before the socket opened.
264
+ for (const queued of this.sendQueue) {
265
+ this.ws.send(JSON.stringify(queued));
266
+ }
267
+ this.sendQueue.length = 0;
268
+ });
269
+ this.ws.on('message', (data, isBinary) => {
270
+ if (this.closed)
271
+ return;
272
+ if (isBinary) {
273
+ // Binary message: MP3 audio chunk.
274
+ const audio = Buffer.isBuffer(data)
275
+ ? data
276
+ : Buffer.from(data);
277
+ const durationMs = estimateDurationMs(this.pendingText);
278
+ const chunk = {
279
+ audio,
280
+ format: 'mp3',
281
+ sampleRate: SAMPLE_RATE_HZ,
282
+ durationMs,
283
+ text: '',
284
+ };
285
+ this.emit('audio_chunk', chunk);
286
+ }
287
+ else {
288
+ // Text (JSON) message: parse for protocol signals.
289
+ try {
290
+ const msg = JSON.parse(data.toString());
291
+ if (msg['isFinal'] === true) {
292
+ // ElevenLabs has finished generating all audio for this stream.
293
+ const durationMs = estimateDurationMs(this.pendingText);
294
+ this.emit('utterance_complete', { text: this.pendingText, durationMs });
295
+ }
296
+ // Other JSON messages (e.g. alignment data) are silently ignored for now.
297
+ }
298
+ catch {
299
+ // Malformed JSON from the server — emit a non-fatal error.
300
+ this.emit('error', new Error(`ElevenLabs: unexpected non-JSON text message: ${String(data)}`));
301
+ }
302
+ }
303
+ });
304
+ this.ws.on('error', (err) => {
305
+ if (!this.closed) {
306
+ this.emit('error', err);
307
+ }
308
+ });
309
+ this.ws.on('close', () => {
310
+ if (!this.closed) {
311
+ this.closed = true;
312
+ this.emit('close');
313
+ }
314
+ });
315
+ }
316
+ /**
317
+ * Send a JSON message over the WebSocket.
318
+ *
319
+ * If the socket is not yet open, the message is queued and will be sent once
320
+ * the `open` event fires (after the BOS message is dispatched).
321
+ *
322
+ * @param msg - The message object to serialise and send.
323
+ */
324
+ _send(msg) {
325
+ if (this.bosAcknowledged && this.ws.readyState === WebSocket.OPEN) {
326
+ this.ws.send(JSON.stringify(msg));
327
+ }
328
+ else {
329
+ // Queue for post-open delivery.
330
+ this.sendQueue.push(msg);
331
+ }
332
+ }
333
+ }
334
+ //# sourceMappingURL=ElevenLabsTTSSession.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElevenLabsTTSSession.js","sourceRoot":"","sources":["../src/ElevenLabsTTSSession.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @file index.ts
3
+ * @description Pack factory for the ElevenLabs Streaming TTS extension pack.
4
+ *
5
+ * Exports the main {@link createElevenLabsStreamingTTS} factory function and the
6
+ * {@link createExtensionPack} bridge function conforming to the AgentOS manifest
7
+ * factory convention.
8
+ *
9
+ * ### Usage (direct)
10
+ * ```ts
11
+ * import { createElevenLabsStreamingTTS } from '@framers/agentos-ext-streaming-tts-elevenlabs';
12
+ *
13
+ * const tts = createElevenLabsStreamingTTS(process.env.ELEVENLABS_API_KEY!);
14
+ * const session = await tts.startSession();
15
+ *
16
+ * session.on('audio_chunk', (chunk) => audioPlayer.enqueue(chunk.audio));
17
+ * llm.on('token', (tok) => session.pushTokens(tok));
18
+ * llm.on('end', () => session.flush());
19
+ * ```
20
+ *
21
+ * ### Usage (manifest-driven)
22
+ * ```json
23
+ * { "packs": [{ "module": "@framers/agentos-ext-streaming-tts-elevenlabs" }] }
24
+ * ```
25
+ *
26
+ * @module streaming-tts-elevenlabs
27
+ */
28
+ import { ElevenLabsStreamingTTS } from './ElevenLabsStreamingTTS.js';
29
+ import type { ElevenLabsStreamingTTSConfig } from './types.js';
30
+ /** Subset of ExtensionDescriptor required by this pack. */
31
+ interface ExtensionDescriptor {
32
+ id: string;
33
+ kind: string;
34
+ payload: unknown;
35
+ enableByDefault?: boolean;
36
+ metadata?: Record<string, unknown>;
37
+ }
38
+ /** Subset of ExtensionPack required by this pack. */
39
+ interface ExtensionPack {
40
+ id: string;
41
+ descriptors: ExtensionDescriptor[];
42
+ }
43
+ /** Subset of ExtensionPackContext required by this pack. */
44
+ interface ExtensionPackContext {
45
+ getSecret?: (id: string) => string | undefined;
46
+ options?: Record<string, unknown>;
47
+ }
48
+ /**
49
+ * Create a standalone {@link ElevenLabsStreamingTTS} instance.
50
+ *
51
+ * Use this when composing the provider programmatically outside of the
52
+ * AgentOS extension system.
53
+ *
54
+ * @param apiKey - ElevenLabs API key.
55
+ * @param options - Optional provider configuration overrides.
56
+ * @returns Configured {@link ElevenLabsStreamingTTS}.
57
+ */
58
+ export declare function createElevenLabsStreamingTTS(apiKey: string, options?: Omit<ElevenLabsStreamingTTSConfig, 'apiKey'>): ElevenLabsStreamingTTS;
59
+ /**
60
+ * AgentOS manifest factory function.
61
+ *
62
+ * Reads the `ELEVENLABS_API_KEY` secret from the context and returns an
63
+ * {@link ExtensionPack} containing a single `streaming-tts-provider`
64
+ * descriptor backed by {@link ElevenLabsStreamingTTS}.
65
+ *
66
+ * Provider-level defaults can be overridden via `context.options`:
67
+ * - `voiceId` — ElevenLabs voice ID.
68
+ * - `modelId` — Model ID (default `'eleven_turbo_v2'`).
69
+ * - `stability` — Voice stability 0.0–1.0.
70
+ * - `similarityBoost`— Similarity boost 0.0–1.0.
71
+ * - `style` — Style exaggeration 0.0–1.0.
72
+ * - `useSpeakerBoost`— Speaker boost.
73
+ *
74
+ * @param context - Pack context supplied by the extension manager.
75
+ * @returns A fully configured {@link ExtensionPack}.
76
+ */
77
+ export declare function createExtensionPack(context: ExtensionPackContext): ExtensionPack;
78
+ export * from './types.js';
79
+ export { ElevenLabsStreamingTTS } from './ElevenLabsStreamingTTS.js';
80
+ export { ElevenLabsTTSSession } from './ElevenLabsTTSSession.js';
81
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAM/D,2DAA2D;AAC3D,UAAU,mBAAmB;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,qDAAqD;AACrD,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,mBAAmB,EAAE,CAAC;CACpC;AAED,4DAA4D;AAC5D,UAAU,oBAAoB;IAC5B,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AASD;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,IAAI,CAAC,4BAA4B,EAAE,QAAQ,CAAC,GACrD,sBAAsB,CAExB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAkBhF;AAMD,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAO,6BAA6B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAS,2BAA2B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @file index.ts
3
+ * @description Pack factory for the ElevenLabs Streaming TTS extension pack.
4
+ *
5
+ * Exports the main {@link createElevenLabsStreamingTTS} factory function and the
6
+ * {@link createExtensionPack} bridge function conforming to the AgentOS manifest
7
+ * factory convention.
8
+ *
9
+ * ### Usage (direct)
10
+ * ```ts
11
+ * import { createElevenLabsStreamingTTS } from '@framers/agentos-ext-streaming-tts-elevenlabs';
12
+ *
13
+ * const tts = createElevenLabsStreamingTTS(process.env.ELEVENLABS_API_KEY!);
14
+ * const session = await tts.startSession();
15
+ *
16
+ * session.on('audio_chunk', (chunk) => audioPlayer.enqueue(chunk.audio));
17
+ * llm.on('token', (tok) => session.pushTokens(tok));
18
+ * llm.on('end', () => session.flush());
19
+ * ```
20
+ *
21
+ * ### Usage (manifest-driven)
22
+ * ```json
23
+ * { "packs": [{ "module": "@framers/agentos-ext-streaming-tts-elevenlabs" }] }
24
+ * ```
25
+ *
26
+ * @module streaming-tts-elevenlabs
27
+ */
28
+ import { ElevenLabsStreamingTTS } from './ElevenLabsStreamingTTS.js';
29
+ /** Kind constant matching packages/agentos/src/extensions/types.ts. */
30
+ const EXTENSION_KIND_STREAMING_TTS = 'streaming-tts-provider';
31
+ // ---------------------------------------------------------------------------
32
+ // Factories
33
+ // ---------------------------------------------------------------------------
34
+ /**
35
+ * Create a standalone {@link ElevenLabsStreamingTTS} instance.
36
+ *
37
+ * Use this when composing the provider programmatically outside of the
38
+ * AgentOS extension system.
39
+ *
40
+ * @param apiKey - ElevenLabs API key.
41
+ * @param options - Optional provider configuration overrides.
42
+ * @returns Configured {@link ElevenLabsStreamingTTS}.
43
+ */
44
+ export function createElevenLabsStreamingTTS(apiKey, options) {
45
+ return new ElevenLabsStreamingTTS({ apiKey, ...options });
46
+ }
47
+ /**
48
+ * AgentOS manifest factory function.
49
+ *
50
+ * Reads the `ELEVENLABS_API_KEY` secret from the context and returns an
51
+ * {@link ExtensionPack} containing a single `streaming-tts-provider`
52
+ * descriptor backed by {@link ElevenLabsStreamingTTS}.
53
+ *
54
+ * Provider-level defaults can be overridden via `context.options`:
55
+ * - `voiceId` — ElevenLabs voice ID.
56
+ * - `modelId` — Model ID (default `'eleven_turbo_v2'`).
57
+ * - `stability` — Voice stability 0.0–1.0.
58
+ * - `similarityBoost`— Similarity boost 0.0–1.0.
59
+ * - `style` — Style exaggeration 0.0–1.0.
60
+ * - `useSpeakerBoost`— Speaker boost.
61
+ *
62
+ * @param context - Pack context supplied by the extension manager.
63
+ * @returns A fully configured {@link ExtensionPack}.
64
+ */
65
+ export function createExtensionPack(context) {
66
+ const apiKey = context.getSecret?.('ELEVENLABS_API_KEY') ?? '';
67
+ const opts = (context.options ?? {});
68
+ const tts = new ElevenLabsStreamingTTS({ apiKey, ...opts });
69
+ return {
70
+ id: 'streaming-tts-elevenlabs',
71
+ descriptors: [
72
+ {
73
+ id: 'elevenlabs-streaming-tts',
74
+ kind: EXTENSION_KIND_STREAMING_TTS,
75
+ payload: tts,
76
+ enableByDefault: true,
77
+ metadata: { providerId: 'elevenlabs-streaming-tts' },
78
+ },
79
+ ],
80
+ };
81
+ }
82
+ // ---------------------------------------------------------------------------
83
+ // Re-exports
84
+ // ---------------------------------------------------------------------------
85
+ export * from './types.js';
86
+ export { ElevenLabsStreamingTTS } from './ElevenLabsStreamingTTS.js';
87
+ export { ElevenLabsTTSSession } from './ElevenLabsTTSSession.js';
88
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AA4BrE,uEAAuE;AACvE,MAAM,4BAA4B,GAAG,wBAAwB,CAAC;AAE9D,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,UAAU,4BAA4B,CAC1C,MAAc,EACd,OAAsD;IAEtD,OAAO,IAAI,sBAAsB,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC/D,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC;IAC/D,MAAM,IAAI,GAAK,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAiD,CAAC;IAEvF,MAAM,GAAG,GAAG,IAAI,sBAAsB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;IAE5D,OAAO;QACL,EAAE,EAAE,0BAA0B;QAC9B,WAAW,EAAE;YACX;gBACE,EAAE,EAAe,0BAA0B;gBAC3C,IAAI,EAAa,4BAA4B;gBAC7C,OAAO,EAAU,GAAG;gBACpB,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAS,EAAE,UAAU,EAAE,0BAA0B,EAAE;aAC5D;SACF;KACF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAO,6BAA6B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAS,2BAA2B,CAAC"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * @file types.ts
3
+ * @description ElevenLabs-specific configuration types for the streaming TTS extension pack.
4
+ *
5
+ * These types define provider configuration for the ElevenLabs WebSocket Streaming API and
6
+ * the shared audio chunk shape emitted by the session.
7
+ *
8
+ * @module streaming-tts-elevenlabs/types
9
+ */
10
+ /**
11
+ * ElevenLabs-specific configuration for the streaming TTS session.
12
+ *
13
+ * All fields except `apiKey` are optional — sensible defaults are applied when omitted.
14
+ * The `apiKey` field is required and must be a valid ElevenLabs API key (xi-api-key).
15
+ */
16
+ export interface ElevenLabsStreamingTTSConfig {
17
+ /**
18
+ * ElevenLabs API key (xi-api-key). Must be set to a non-empty string; the pack reads
19
+ * this from the `ELEVENLABS_API_KEY` secret when constructed via {@link createExtensionPack}.
20
+ */
21
+ apiKey: string;
22
+ /**
23
+ * ElevenLabs voice ID to use for synthesis.
24
+ *
25
+ * Find voice IDs in the ElevenLabs voice library or via the Voices API.
26
+ * @defaultValue '21m00Tcm4TlvDq8ikWAM' (Rachel — a neutral English voice)
27
+ * @see {@link https://elevenlabs.io/voice-library}
28
+ */
29
+ voiceId?: string;
30
+ /**
31
+ * ElevenLabs model ID to use for synthesis.
32
+ *
33
+ * - `eleven_turbo_v2` — optimized for low latency (~250 ms to first chunk).
34
+ * - `eleven_multilingual_v2` — highest quality, supports 29 languages.
35
+ * - `eleven_monolingual_v1` — English-only, balanced latency/quality.
36
+ *
37
+ * @defaultValue 'eleven_turbo_v2'
38
+ * @see {@link https://elevenlabs.io/docs/speech-synthesis/models}
39
+ */
40
+ modelId?: string;
41
+ /**
42
+ * Voice stability (0.0 – 1.0).
43
+ *
44
+ * Lower values produce more expressive and varied speech; higher values are more
45
+ * consistent and monotone.
46
+ * @defaultValue 0.5
47
+ */
48
+ stability?: number;
49
+ /**
50
+ * Similarity boost (0.0 – 1.0).
51
+ *
52
+ * Higher values cause the output to sound more similar to the original voice clone.
53
+ * Too high a value can introduce artefacts.
54
+ * @defaultValue 0.75
55
+ */
56
+ similarityBoost?: number;
57
+ /**
58
+ * Style exaggeration (0.0 – 1.0).
59
+ *
60
+ * Amplifies the style of the original speaker. Increasing this setting may reduce
61
+ * overall generation speed. Only available for v2 models.
62
+ * @defaultValue 0.0
63
+ */
64
+ style?: number;
65
+ /**
66
+ * Speaker boost.
67
+ *
68
+ * Boosts similarity to the original speaker. Recommended when a cloned voice is
69
+ * used and maximum fidelity is needed.
70
+ * @defaultValue true
71
+ */
72
+ useSpeakerBoost?: boolean;
73
+ }
74
+ /**
75
+ * Generic streaming TTS session config forwarded from the voice pipeline.
76
+ *
77
+ * This is the provider-agnostic shape the AgentOS voice pipeline passes to
78
+ * {@link ElevenLabsStreamingTTS.startSession}.
79
+ */
80
+ export interface StreamingTTSConfig {
81
+ /** Language / locale hint (e.g. `'en-US'`). Currently informational only for ElevenLabs. */
82
+ language?: string;
83
+ /** Provider-specific options forwarded verbatim to the adapter. */
84
+ providerOptions?: Record<string, unknown>;
85
+ }
86
+ /**
87
+ * A single chunk of synthesized audio emitted by {@link ElevenLabsTTSSession}.
88
+ *
89
+ * The `audio` field holds raw MP3 bytes returned by the ElevenLabs WebSocket stream.
90
+ * The `format` field is always `'mp3'` for this provider.
91
+ */
92
+ export interface EncodedAudioChunk {
93
+ /** Raw audio bytes encoded as MP3. */
94
+ audio: Buffer;
95
+ /**
96
+ * Codec / container format. Always `'mp3'` for ElevenLabs streaming output.
97
+ */
98
+ format: string;
99
+ /**
100
+ * Nominal sample rate of the audio, in Hz.
101
+ *
102
+ * ElevenLabs streaming returns 44.1 kHz MP3 audio when `output_format=mp3_44100_128`.
103
+ */
104
+ sampleRate: number;
105
+ /**
106
+ * Rough estimated playback duration in milliseconds.
107
+ *
108
+ * Computed heuristically from the current text buffer word count (~150 WPM) rather than
109
+ * decoding the audio, so callers should treat this as a hint rather than a precise value.
110
+ */
111
+ durationMs: number;
112
+ /**
113
+ * The input text associated with this audio chunk.
114
+ *
115
+ * For mid-stream binary chunks this is an empty string; ElevenLabs does not embed
116
+ * alignment data in the binary WebSocket messages.
117
+ */
118
+ text: string;
119
+ }
120
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;GAKG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;CACd"}
package/dist/types.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @file types.ts
3
+ * @description ElevenLabs-specific configuration types for the streaming TTS extension pack.
4
+ *
5
+ * These types define provider configuration for the ElevenLabs WebSocket Streaming API and
6
+ * the shared audio chunk shape emitted by the session.
7
+ *
8
+ * @module streaming-tts-elevenlabs/types
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
package/manifest.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "@framers/agentos-ext-streaming-tts-elevenlabs",
3
+ "version": "0.1.0",
4
+ "description": "Streaming TTS via ElevenLabs WebSocket API",
5
+ "kind": "streaming-tts-provider",
6
+ "extensionId": "streaming-tts-elevenlabs",
7
+ "entryPoint": "./dist/index.js"
8
+ }