Initial Commit
This commit is contained in:
143
packages/media/audio/voice-elevenlabs/README.md
Normal file
143
packages/media/audio/voice-elevenlabs/README.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# @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.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [factory](./src/factory/create-elevenlabs-voice.md) — Composition root for the `@suaveplan/voice` engine adapters that target ElevenLabs. One call, one shared transport, fiv…
|
||||
- [create-elevenlabs-voice](./src/factory/create-elevenlabs-voice.md) — Composition root for the `@suaveplan/voice` engine adapters that target ElevenLabs. One call, one shared transport, fiv…
|
||||
- [models](./src/models/models.md) — ElevenLabs model catalog. Lists every model the API key has access to, along with capability flags (TTS / voice convers…
|
||||
- [models](./src/models/models.md) — ElevenLabs model catalog. Lists every model the API key has access to, along with capability flags (TTS / voice convers…
|
||||
- [sound-effects](./src/sound-effects/sound-effects.md) — ElevenLabs implementation of `@suaveplan/voice`'s `SoundEffectEngine` interface. Posts a JSON body to `POST /v1/sound-g…
|
||||
- [sound-effects](./src/sound-effects/sound-effects.md) — ElevenLabs implementation of `@suaveplan/voice`'s `SoundEffectEngine` interface. Posts a JSON body to `POST /v1/sound-g…
|
||||
- [speech-to-speech](./src/speech-to-speech/speech-to-speech.md) — ElevenLabs Speech-to-Speech (voice conversion) adapter. Given source audio and a target `voiceId`, produces audio that…
|
||||
- [speech-to-speech](./src/speech-to-speech/speech-to-speech.md) — ElevenLabs Speech-to-Speech (voice conversion) adapter. Given source audio and a target `voiceId`, produces audio that…
|
||||
- [stt](./src/stt/stt.md) — ElevenLabs implementation of `@suaveplan/voice`'s `TranscriptionEngine` interface. Posts the audio as multipart form-da…
|
||||
- [stt](./src/stt/stt.md) — ElevenLabs implementation of `@suaveplan/voice`'s `TranscriptionEngine` interface. Posts the audio as multipart form-da…
|
||||
- [tts](./src/tts/tts.md) — ElevenLabs implementation of `@suaveplan/voice`'s `VoiceSynthesizer` interface. Posts to `/v1/text-to-speech/{voice_id}…
|
||||
- [tts](./src/tts/tts.md) — ElevenLabs implementation of `@suaveplan/voice`'s `VoiceSynthesizer` interface. Posts to `/v1/text-to-speech/{voice_id}…
|
||||
- [voice-isolation](./src/voice-isolation/voice-isolation.md) — ElevenLabs implementation of `@suaveplan/voice`'s `VoiceIsolationEngine` interface. Posts the audio as multipart form-d…
|
||||
- [voice-isolation](./src/voice-isolation/voice-isolation.md) — ElevenLabs implementation of `@suaveplan/voice`'s `VoiceIsolationEngine` interface. Posts the audio as multipart form-d…
|
||||
- [voices](./src/voices/voices.md) — ElevenLabs implementation of `@suaveplan/voice`'s `VoiceRepository` interface. Lists voices via `GET /v1/voices` and lo…
|
||||
- [voices](./src/voices/voices.md) — ElevenLabs implementation of `@suaveplan/voice`'s `VoiceRepository` interface. Lists voices via `GET /v1/voices` and lo…
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
bun add @suaveplan/voice-elevenlabs @suaveplan/voice
|
||||
```
|
||||
|
||||
## Quick start
|
||||
|
||||
```ts
|
||||
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:
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```sh
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user