symfony/ai-cartesia-platform
Symfony AI bridge for the Cartesia Platform. Integrates Cartesia APIs for text-to-speech (bytes) and speech-to-text transcription, enabling easy API requests and usage within Symfony applications via the Symfony AI ecosystem.
Install Dependencies Require the package and Symfony AI:
composer require symfony/ai symfony/ai-cartesia-platform
Configure API Credentials
Add to config/services.php (Laravel) or .env:
CARTESIA_API_KEY=your_key_here
CARTESIA_API_URL=https://api.cartesia.ai
Basic TTS Usage
use Symfony\AI\Cartesia\Client;
use Symfony\Component\AI\Provider\CartesiaProvider;
$client = new Client();
$provider = new CartesiaProvider($client);
// Generate speech bytes
$speechBytes = $provider->tts()->bytes('Hello, world!')->getContent();
file_put_contents('speech.mp3', $speechBytes);
Basic STT Usage
$transcription = $provider->stt()->transcribe(file_get_contents('audio.wav'));
$text = $transcription->getText();
Laravel Facade (Optional) Create a facade for convenience:
// app/Providers/AppServiceProvider.php
public function boot()
{
$this->app->bind('cartesia', function () {
$client = new Client();
return new CartesiaProvider($client);
});
}
Usage:
$tts = app('cartesia')->tts()->bytes('Text')->getContent();
Provider-Based Routing
Leverage Symfony’s Provider abstraction to route requests:
// Route by model (if Cartesia supports multiple)
$provider->setModel('cartesia-pro');
$result = $provider->tts()->bytes('Text');
Async Processing with Queues Offload STT/TTS to background jobs:
// app/Jobs/ProcessSpeech.php
public function handle()
{
$provider = app('cartesia');
$transcription = $provider->stt()->transcribe($this->audioPath);
// Save to DB or process further
}
Middleware for Requests Add logging/retries via Symfony middleware:
use Symfony\Component\AI\Middleware\RetryMiddleware;
$client = new Client();
$client->addMiddleware(new RetryMiddleware());
Service Container Binding Bind the provider as a singleton:
$this->app->singleton('cartesia', function () {
$client = new Client();
$provider = new CartesiaProvider($client);
$provider->setApiKey(config('services.cartesia.key'));
return $provider;
});
Event Listeners Trigger events for STT/TTS completion:
// app/Listeners/SpeechProcessed.php
public function handle($event)
{
Log::info('Speech processed', ['text' => $event->text]);
}
Form Request Validation Validate audio inputs before STT:
use Illuminate\Validation\Rule;
$request->validate([
'audio' => ['required', 'file', 'mimes:wav,mp3'],
]);
$provider = new MultiProvider([
new CartesiaProvider($client),
new OpenAIProvider($openAiClient),
]);
$bytes = Cache::remember("tts_{$text}", now()->addHours(1), function () use ($provider, $text) {
return $provider->tts()->bytes($text)->getContent();
});
try {
$provider->stt()->transcribe($audio);
} catch (CartesiaException $e) {
report($e);
return back()->withError('Speech processing failed');
}
Authentication Quirks
$client->setHeaders(['Authorization' => 'Bearer ' . config('services.cartesia.key')]);
Audio Format Restrictions
.ogg)..wav or .mp3 before processing:
use FFMpeg\FFMpeg;
$ffmpeg = FFMpeg::create();
$ffmpeg->open($request->file('audio'))
->save('converted.wav');
Rate Limiting
use Symfony\Component\AI\Middleware\RetryMiddleware;
$client->addMiddleware(new RetryMiddleware(3, 100));
Provider Abstraction Gaps
Provider abstraction may not cover all Cartesia endpoints.class ExtendedCartesiaProvider extends CartesiaProvider {
public function customEndpoint(array $data) {
return $this->client->request('POST', '/custom', ['json' => $data]);
}
}
Laravel-Symfony HTTP Client Mismatch
HttpClient differs from Laravel’s Http.use Symfony\Component\HttpClient\HttpClient;
use Illuminate\Support\Facades\Http;
$symfonyClient = HttpClient::create();
$laravelResponse = Http::withOptions(['handler' => $symfonyClient->getHandler())->post(...);
Enable Verbose Logging
$client = new Client();
$client->setDebug(true); // Logs full request/response
Inspect Raw Responses
$response = $provider->stt()->transcribe($audio);
\Log::debug('Cartesia STT Response', [
'status' => $response->getStatusCode(),
'content' => $response->getContent(),
]);
Mock Cartesia for Testing
// tests/TestCase.php
protected function mockCartesia()
{
$client = $this->createMock(ClientInterface::class);
$client->method('request')
->willReturn(new Response(200, [], json_encode(['text' => 'Mocked'])));
$this->app->instance(ClientInterface::class, $client);
}
Environment Variables
.env variables are loaded in config/services.php:
'cartesia' => [
'key' => env('CARTESIA_API_KEY'),
'url' => env('CARTESIA_API_URL', 'https://api.cartesia.ai'),
],
Provider Initialization
CartesiaProvider requires a fully configured Client:
$client = new Client();
$client->setHeaders(['Authorization' => 'Bearer ' . $apiKey]);
$provider = new CartesiaProvider($client);
Model Routing
$provider->setModel('cartesia-pro');
$result = $provider->tts()->bytes('Text');
Custom Middleware
Add middleware to the Client:
$client->addMiddleware(function (Request $request, callable $next) {
$request = $request->withHeader('X-Custom-Header', 'value');
return $next($request);
});
Event Subscribers Subscribe to Symfony AI events:
use Symfony\Component\AI\Event\SpeechProcessedEvent;
$dispatcher->addListener(SpeechProcessedEvent::class, function ($event) {
// Handle event (e.g., update DB)
});
Response Transformers Override response handling:
class CustomCartesiaProvider extends CartesiaProvider {
protected function transformResponse(ResponseInterface $response): array {
$data = parent::transformResponse($response);
return array_merge($data, ['custom_field' => 'value']);
}
}
Fallback Providers Implement a fallback chain:
$provider = new CartesiaProvider($client);
$fallback = new OpenAIProvider($openAiClient);
$result = $provider->tts()->bytes('Text');
if ($result->failed()) {
$result =
How can I help you explore Laravel packages today?