import * as plugins from './plugins.js'; import { MultiModalModel } from './abstract.classes.multimodal.js'; import type { ChatOptions, ChatResponse, ResearchOptions, ResearchResponse, ImageGenerateOptions, ImageEditOptions, ImageResponse } from './abstract.classes.multimodal.js'; export interface IElevenLabsProviderOptions { elevenlabsToken: string; defaultVoiceId?: string; defaultModelId?: string; } export interface IElevenLabsVoiceSettings { stability?: number; similarity_boost?: number; style?: number; use_speaker_boost?: boolean; } export class ElevenLabsProvider extends MultiModalModel { private options: IElevenLabsProviderOptions; private baseUrl: string = 'https://api.elevenlabs.io/v1'; constructor(optionsArg: IElevenLabsProviderOptions) { super(); this.options = optionsArg; } public async start() { await super.start(); } public async stop() { await super.stop(); } public async chat(optionsArg: ChatOptions): Promise { throw new Error('ElevenLabs does not support chat functionality. This provider is specialized for text-to-speech only.'); } public async chatStream(input: ReadableStream): Promise> { throw new Error('ElevenLabs does not support chat streaming functionality. This provider is specialized for text-to-speech only.'); } public async audio(optionsArg: { message: string; voiceId?: string; modelId?: string; voiceSettings?: IElevenLabsVoiceSettings; }): Promise { // Use Samara voice as default fallback const voiceId = optionsArg.voiceId || this.options.defaultVoiceId || '19STyYD15bswVz51nqLf'; const modelId = optionsArg.modelId || this.options.defaultModelId || 'eleven_v3'; const url = `${this.baseUrl}/text-to-speech/${voiceId}`; const requestBody: any = { text: optionsArg.message, model_id: modelId, }; if (optionsArg.voiceSettings) { requestBody.voice_settings = optionsArg.voiceSettings; } const response = await plugins.smartrequest.SmartRequest.create() .url(url) .header('xi-api-key', this.options.elevenlabsToken) .json(requestBody) .autoDrain(false) .post(); if (!response.ok) { const errorText = await response.text(); throw new Error(`ElevenLabs API error: ${response.status} ${response.statusText} - ${errorText}`); } const nodeStream = response.streamNode(); return nodeStream; } public async vision(optionsArg: { image: Buffer; prompt: string }): Promise { throw new Error('ElevenLabs does not support vision functionality. This provider is specialized for text-to-speech only.'); } public async document(optionsArg: { systemMessage: string; userMessage: string; pdfDocuments: Uint8Array[]; messageHistory: any[]; }): Promise<{ message: any }> { throw new Error('ElevenLabs does not support document processing. This provider is specialized for text-to-speech only.'); } public async research(optionsArg: ResearchOptions): Promise { throw new Error('ElevenLabs does not support research capabilities. This provider is specialized for text-to-speech only.'); } public async imageGenerate(optionsArg: ImageGenerateOptions): Promise { throw new Error('ElevenLabs does not support image generation. This provider is specialized for text-to-speech only.'); } public async imageEdit(optionsArg: ImageEditOptions): Promise { throw new Error('ElevenLabs does not support image editing. This provider is specialized for text-to-speech only.'); } }