@suaveplan/voice-elevenlabs - ElevenLabs domain adapter for @suaveplan/voice: TTS, STT, voice repository, sound effects, and voice isolation engines implemented by delegating to @suaveplan/third-party-elevenlabs.
ElevenLabs domain adapter for the @suaveplan/voice interface family.
This package implements every @suaveplan/voice engine contract —
VoiceSynthesizer, TranscriptionEngine, VoiceRepository,
SoundEffectEngine, VoiceIsolationEngine — by delegating to the typed
HTTP/WebSocket transport in @suaveplan/third-party-elevenlabs. It owns
DTO ↔ domain mapping, ElevenLabs-specific error remapping into the
VOICE.* namespace, multipart/stream plumbing for the voice surface,
and a composite factory that wires every engine against a shared
transport.
Documentation tree
- factory — Composition root for the
@suaveplan/voiceengine adapters that target ElevenLabs. One call, one shared transport, fiv…- create-elevenlabs-voice — Composition root for the
@suaveplan/voiceengine adapters that target ElevenLabs. One call, one shared transport, fiv…
- create-elevenlabs-voice — Composition root for the
- models — ElevenLabs model catalog. Lists every model the API key has access to, along with capability flags (TTS / voice convers…
- models — ElevenLabs model catalog. Lists every model the API key has access to, along with capability flags (TTS / voice convers…
- sound-effects — ElevenLabs implementation of
@suaveplan/voice'sSoundEffectEngineinterface. Posts a JSON body to `POST /v1/sound-g…- sound-effects — ElevenLabs implementation of
@suaveplan/voice'sSoundEffectEngineinterface. Posts a JSON body to `POST /v1/sound-g…
- sound-effects — ElevenLabs implementation of
- speech-to-speech — ElevenLabs Speech-to-Speech (voice conversion) adapter. Given source audio and a target
voiceId, produces audio that…- speech-to-speech — ElevenLabs Speech-to-Speech (voice conversion) adapter. Given source audio and a target
voiceId, produces audio that…
- speech-to-speech — ElevenLabs Speech-to-Speech (voice conversion) adapter. Given source audio and a target
- stt — ElevenLabs implementation of
@suaveplan/voice'sTranscriptionEngineinterface. Posts the audio as multipart form-da…- stt — ElevenLabs implementation of
@suaveplan/voice'sTranscriptionEngineinterface. Posts the audio as multipart form-da…
- stt — ElevenLabs implementation of
- tts — ElevenLabs implementation of
@suaveplan/voice'sVoiceSynthesizerinterface. Posts to `/v1/text-to-speech/{voice_id}…- tts — ElevenLabs implementation of
@suaveplan/voice'sVoiceSynthesizerinterface. Posts to `/v1/text-to-speech/{voice_id}…
- tts — ElevenLabs implementation of
- voice-isolation — ElevenLabs implementation of
@suaveplan/voice'sVoiceIsolationEngineinterface. Posts the audio as multipart form-d…- voice-isolation — ElevenLabs implementation of
@suaveplan/voice'sVoiceIsolationEngineinterface. Posts the audio as multipart form-d…
- voice-isolation — ElevenLabs implementation of
- voices — ElevenLabs implementation of
@suaveplan/voice'sVoiceRepositoryinterface. Lists voices viaGET /v1/voicesand lo…- voices — ElevenLabs implementation of
@suaveplan/voice'sVoiceRepositoryinterface. Lists voices viaGET /v1/voicesand lo…
- voices — ElevenLabs implementation of
Install
bun add @suaveplan/voice-elevenlabs @suaveplan/voice
Quick start
import { createElevenLabsVoice } from "@suaveplan/voice-elevenlabs";
const { tts, voices } = createElevenLabsVoice({
apiKey: process.env.ELEVENLABS_KEY!,
});
const all = await voices.list();
const result = await tts.synthesize({
text: "hello",
voiceId: all.voices[0]!.id,
});
Modules
| Subpath | Engine | @suaveplan/voice contract |
|---|---|---|
./tts/tts |
ElevenLabsVoiceSynthesizer |
VoiceSynthesizer |
./stt/stt |
ElevenLabsTranscriptionEngine |
TranscriptionEngine |
./voices/voices |
ElevenLabsVoiceRepository |
VoiceRepository |
./sound-effects/sound-effects |
ElevenLabsSoundEffectEngine |
SoundEffectEngine |
./voice-isolation/voice-isolation |
ElevenLabsVoiceIsolationEngine |
VoiceIsolationEngine |
./factory/create-elevenlabs-voice |
createElevenLabsVoice |
bundle factory |
Composing with other ElevenLabs surfaces
The factory accepts a pre-constructed ElevenLabsClient from
@suaveplan/third-party-elevenlabs so the same transport (with its
retry, rate-limit, OTel, base URL, and event-bus configuration) can be
shared with ElevenLabs-specific surfaces that are not part of the
voice domain — for example the model catalogue or the
speech-to-speech (voice-conversion) endpoint:
import {
ElevenLabsClient,
ElevenLabsModelCatalog,
ElevenLabsSpeechToSpeech,
} from "@suaveplan/third-party-elevenlabs";
import { createElevenLabsVoice } from "@suaveplan/voice-elevenlabs";
const client = new ElevenLabsClient({
apiKey: process.env.ELEVENLABS_KEY!,
baseUrl: "https://eu.api.elevenlabs.io",
});
const voice = createElevenLabsVoice({ client });
const models = new ElevenLabsModelCatalog(client);
const s2s = new ElevenLabsSpeechToSpeech(client);
Error remapping
Every ElevenLabsApiError subclass raised by the underlying transport
is remapped into a VoiceError from @suaveplan/voice, preserving the
original via .cause. The full table is documented inline at the call
sites; a representative subset:
| Third-party error | Voice domain error |
|---|---|
UnauthorizedError, ForbiddenError |
ProviderNotConfiguredError |
RequestNotFoundError (from voices.get) |
resolves to null (no throw) |
RequestValidationFailedError, RequestInvalidError |
VoiceValidationError |
RateLimitExceededError, RateLimitQuotaExhaustedError |
ProviderRateLimitedError (with retryAfterMs) |
ServerTransientError / ServerUnavailableError (TTS) |
TtsSynthesisFailedError |
ServerTransientError (STT) |
SttTranscriptionFailedError |
StreamInterruptedError |
TtsStreamInterruptedError |
ResponseUnsupportedFormatError |
AudioFormatUnsupportedError |
voices.get(voiceId) follows the VoiceRepository null-on-not-found
contract: any upstream 404 is mapped to null rather than thrown.
Architecture
@suaveplan/voice abstract engine interfaces
▲
│ implements
│
@suaveplan/voice-elevenlabs domain adapter (this package)
│
│ delegates HTTP / WebSocket / multipart
▼
@suaveplan/third-party-elevenlabs typed transport, retry, OTel,
rate-limit headers, raw DTOs
Future ElevenLabs surfaces (music, dubbing, conversational AI) compose
against the same @suaveplan/third-party-elevenlabs client; they do not
fan out from this package. This keeps each surface's domain-mapping
concerns isolated.
Verification
bunx turbo lint typecheck test --filter=@suaveplan/voice-elevenlabs
bunx turbo test:coverage --filter=@suaveplan/voice-elevenlabs
Coverage gate: 100/100/100/100 statements/branches/functions/lines.