@just-every/ensemble
Version:
LLM provider abstraction layer with unified streaming interface
140 lines • 5.3 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.ElevenLabsProvider = exports.elevenLabsProvider = exports.ELEVENLABS_VOICES = void 0;
const base_provider_js_1 = require("./base_provider.cjs");
const cost_tracker_js_1 = require("../utils/cost_tracker.cjs");
exports.ELEVENLABS_VOICES = {
rachel: '21m00Tcm4TlvDq8ikWAM',
domi: 'AZnzlk1XvdvUeBnXmlld',
bella: 'EXAVITQu4vr4xnSDxMaL',
antoni: 'ErXwobaYiN019PkySvjV',
elli: 'MF3mGyEYCl7XYWbV9V6O',
josh: 'TxGEqnHWrfWFTfGW9XjX',
arnold: 'VR6AewLTigWG4xSOukaG',
adam: 'pNInz6obpgDQGcFmaJgB',
sam: 'yoZ06aMxZJJ28mfd3POQ',
george: 'JBFqnCBsd6RMkjVDRZzb',
jessica: 'cgSgspJ2msm6clMCkdW9',
laura: 'FGY2WhTYpPnrIDTdsKH5',
callum: 'N2lVS1w4EtoT3dr4eOWO',
unreal: 'YOq2y2Up4RgXP2HyXjE5',
blondie: 'exsUS4vynmxd379XN4yO',
james: 'h0KXSKLMvNtfCIMB8I9L',
};
class ElevenLabsProvider extends base_provider_js_1.BaseModelProvider {
_apiKey;
baseUrl = 'https://api.elevenlabs.io/v1';
constructor() {
super('elevenlabs');
}
get apiKey() {
if (!this._apiKey) {
this._apiKey = process.env.ELEVENLABS_API_KEY;
if (!this._apiKey) {
throw new Error('ElevenLabs API key is required. Please set the ELEVENLABS_API_KEY environment variable.');
}
}
return this._apiKey;
}
supportsModel(model) {
return model.startsWith('eleven_') || model.startsWith('elevenlabs-');
}
getModelInfo() {
return undefined;
}
async request() {
throw new Error('ElevenLabs provider only supports voice generation');
}
async embed() {
throw new Error('ElevenLabs provider does not support embeddings');
}
async image() {
throw new Error('ElevenLabs provider does not support image generation');
}
async createVoice(text, model, opts) {
try {
const modelId = model;
let voiceId = opts?.voice || 'adam';
if (voiceId in exports.ELEVENLABS_VOICES) {
voiceId = exports.ELEVENLABS_VOICES[voiceId];
}
const outputFormat = this.mapOutputFormat(opts?.response_format || 'mp3_44100_128');
console.log(`[ElevenLabs] Generating speech with model ${modelId}, voice: ${voiceId}, format: ${outputFormat}, streaming: ${opts?.stream || false}`);
if (model === 'eleven_v3' && opts?.affect) {
text = `[${opts.affect.toUpperCase()}] ${text}`;
}
const requestBody = {
text,
model_id: modelId,
voice_settings: {
speed: 0.9,
stability: 0.4,
similarity_boost: 0.5,
use_speaker_boost: true,
...(opts?.voice_settings || {}),
},
};
if (opts?.speed !== undefined) {
requestBody.voice_settings.speed = opts.speed;
}
const endpoint = opts?.stream ? 'stream' : '';
const url = `${this.baseUrl}/text-to-speech/${voiceId}${endpoint ? '/stream' : ''}?output_format=${outputFormat}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'xi-api-key': this.apiKey,
'Content-Type': 'application/json',
Accept: opts?.stream ? 'application/octet-stream' : 'audio/mpeg',
},
body: JSON.stringify(requestBody),
});
if (!response.ok) {
const error = await response.text();
throw new Error(`ElevenLabs API error: ${response.status} - ${error}`);
}
const characterCount = text.length;
cost_tracker_js_1.costTracker.addUsage({
model,
input_tokens: Math.ceil(characterCount / 4),
output_tokens: 0,
metadata: {
character_count: characterCount,
voice: voiceId,
format: outputFormat,
},
});
if (opts?.stream && response.body) {
return response.body;
}
else {
const buffer = await response.arrayBuffer();
return buffer;
}
}
catch (error) {
console.error('[ElevenLabs] Error generating speech:', error);
throw error;
}
}
mapOutputFormat(format) {
const formatMap = {
mp3: 'mp3_44100_128',
mp3_low: 'mp3_22050_32',
mp3_high: 'mp3_44100_192',
pcm: 'pcm_24000',
pcm_16000: 'pcm_16000',
pcm_22050: 'pcm_22050',
pcm_24000: 'pcm_24000',
pcm_44100: 'pcm_44100',
ulaw: 'ulaw_8000',
};
return formatMap[format] || format;
}
async *createResponseStream() {
yield;
throw new Error('ElevenLabs provider only supports voice generation');
}
}
exports.ElevenLabsProvider = ElevenLabsProvider;
exports.elevenLabsProvider = new ElevenLabsProvider();
//# sourceMappingURL=elevenlabs.js.map
;