ADR-0013 · ElevenLabs hors Gateway
title: ADR-0013 — ElevenLabs reste hors de l'AI Gateway description: ElevenLabs reste hors de l’AI Gateway : horodatage par caractère et voix clonées.
Statut
Proposé · 2026-09-27
Remplace ou amende : Rien. Écrit une exception que le code portait sans la nommer.
Origine : ADR 0003 du dépôt applicatif Orbit, renumérotée 0013 à l’intégration dans cette série (une seule série d’ADR vit désormais ici).
Statut dans Orbit (2026-10) : en vigueur. Décision reprise de l'ancien dépôt Studio ; l'exception vit dans
packages/engine(@orbit/engine) de ce dépôt.
Répond au constat G2-23 de l'audit de la phase 3. Source : la page texte-vers-parole de l'AI Gateway (
vercel.com/docs/ai-gateway), lue le 2026-09-27.
Contexte
Toute l'IA du studio passe par l'AI Gateway, avec des chaînes de modèle et
aucune clé de fournisseur (ADR 0012). Une seule exception : la voix off, qui
appelle ElevenLabs directement, avec la seule clé de fournisseur que le studio
détient (ELEVENLABS_API_KEY). Rien ne disait pourquoi.
La route de parole de la Gateway (experimental_generateSpeech avec des
modèles comme openai/tts-1) ne donne pas ce dont la voix off a besoin :
- Pas d'horodatage par caractère. Le studio lit
/with-timestampsd'ElevenLabs : l'alignement sert aux sous-titres et à la durée de la voix, qui dimensionne la réserve d'un lipsync. - Pas de voix clonées. Les voix du fondateur et de son équipe sont des voix de la bibliothèque ElevenLabs du compte, et la porte de consentement (E2E-09) lit leur catégorie dans cette bibliothèque.
Décision
ElevenLabs reste un appel direct, dans une frontière stricte :
- Un seul module, côté serveur.
packages/engine/src/generation/providers.ts(liveProviders().voiceetvoiceCategory), atteint seulement parrunGeneration, lui-même atteint par les fonctions serveur deapps/web/src/generation/(qui importentserver-only). La clé n'est lue que parapps/web/src/generation/deps.ts, jamais envoyée au navigateur. - Jamais réessayé. ElevenLabs n'a pas de clé d'idempotence : une requête
répétée est une seconde facture.
MAX_RETRIES.voicevaut 0 et le module ne boucle pas. Une panne rembourse la réserve ; le membre relance lui-même. - Un budget. La synthèse a 60 s (
PROVIDER_BUDGET_MS.voice), la lecture de la catégorie 10 s (voiceLookup) ; au-delà, l'appel est annulé et la réserve remboursée dans la requête. - Une clé
sk_. Le module refuse une clé qui ne commence pas parsk_(l'identifiant de clé collé à la place du secret rend un 400 trompeur). - Le prix est la formule du studio, par caractère envoyé
(
voiceoverQuote) : il n'y a pas de coût de Gateway à lire.
Conséquences
- Le rapport d'usage de la Gateway ne contient pas la voix : son
rapprochement se fait sur le tableau de bord ElevenLabs, contre les lignes
generateVoiceoverdu ledger (runbookrendus-et-generations.md). - Si la Gateway offre un jour l'horodatage et les voix du compte, cette ADR est à remplacer et la voix rejoint le constructeur d'options commun.
Vérification
providers.transport.test.ts : une synthèse qui répond 503 fait une seule
requête, porte un signal d'annulation, et la recherche de catégorie aussi.