config['voice_id'] ?? null; if (! $voiceId) { throw new AiGenerationException("AI provider '{$provider->name}' has no voice_id configured for text-to-speech."); } $modelId = $options['model_id'] ?? $provider->config['model_id'] ?? 'eleven_multilingual_v2'; try { $response = Http::withHeaders(['xi-api-key' => $provider->api_key]) ->post("https://api.elevenlabs.io/v1/text-to-speech/{$voiceId}", [ 'text' => $prompt, 'model_id' => $modelId, ]); } catch (ConnectionException $e) { throw new AiGenerationException("could not connect to ElevenLabs: {$e->getMessage()}"); } if ($response->failed()) { $error = $response->json('detail.message') ?? $response->json('detail') ?? 'unexpected response from ElevenLabs'; throw new AiGenerationException(is_string($error) ? $error : 'unexpected response from ElevenLabs'); } return new AiGenerationResult($response->body(), 'audio/mpeg'); } }