symfony/ai-ovh-platform
Symfony AI bridge for OVHcloud AI Endpoints Platform. Connect Symfony AI to OVH’s managed AI endpoints and model catalog to run chat, embeddings, and other AI requests through OVH infrastructure, with links to OVH docs and main Symfony AI repo for issues/PRs.
Install Dependencies:
composer require symfony/ai symfony/ai-ovh-platform symfony/psr-http-message-bridge
Configure OVH API Key:
Add to .env:
OVH_AI_KEY=your_ovh_api_key_here
OVH_AI_ENDPOINT=https://your-ovh-ai-endpoint.com
Bind Symfony AI Client in Laravel:
Create a service provider (app/Providers/SymfonyServiceProvider.php):
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Symfony\AI\Client;
use Symfony\AI\Ovh\Provider;
class SymfonyServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Client::class, function ($app) {
return new Client(
new Provider(
$app['config']['services.ovh_ai.key'],
$app['config']['services.ovh_ai.endpoint']
)
);
});
}
}
Register in config/app.php:
'providers' => [
// ...
App\Providers\SymfonyServiceProvider::class,
],
First API Call:
use Symfony\AI\Client;
$client = app(Client::class);
$response = $client->generate('ovh-model-id', 'Your prompt here');
return response()->json($response);
Leverage the provider abstraction to route requests dynamically:
// config/ai.php
'providers' => [
'ovh' => [
'key' => env('OVH_AI_KEY'),
'endpoint' => env('OVH_AI_ENDPOINT'),
'models' => [
'text-generation' => 'ovh-model-id-1',
'embeddings' => 'ovh-model-id-2',
],
],
];
// In a service
$client = app(Client::class);
$response = $client->generate('text-generation', 'Write a blog post about Laravel AI');
Handle streaming responses (e.g., for chatbots) with Laravel’s events:
$client->stream('ovh-model-id', 'Your prompt')
->then(function ($chunk) {
event(new \App\Events\AIChunkReceived($chunk));
});
Offload AI calls to queues for async processing:
use Symfony\AI\Client;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
class GenerateContentJob implements ShouldQueue
{
use Queueable;
public function handle(Client $client)
{
$response = $client->generate('ovh-model-id', $this->prompt);
// Save to DB or notify user
}
}
Extend the provider abstraction for future flexibility:
// app/Providers/AIServiceProvider.php
public function register()
{
$this->app->bind(\Symfony\AI\ProviderInterface::class, function ($app) {
return new class($app['config']['services.ovh_ai.key']) implements ProviderInterface {
// Custom logic or fallback to OVH
};
});
}
DTOs for Responses: Convert Symfony responses to Laravel-friendly DTOs:
namespace App\DTO;
class AIResponse
{
public function __construct(
public string $text,
public array $metadata,
public float $usage
) {}
}
// Usage
$response = $client->generate(...);
return new AIResponse($response['text'], $response['metadata'], $response['usage']);
Form Request Validation: Validate AI prompts before sending:
use Illuminate\Foundation\Http\FormRequest;
class GenerateRequest extends FormRequest
{
public function rules()
{
return [
'prompt' => 'required|string|max:2000',
'model' => 'required|string|in:'.implode(',', config('ai.providers.ovh.models')),
];
}
}
Caching Strategies: Cache responses based on prompt hashing:
use Illuminate\Support\Facades\Cache;
$cacheKey = md5($prompt);
return Cache::remember("ovh_ai_{$cacheKey}", now()->addMinutes(10), function () use ($client, $prompt) {
return $client->generate('ovh-model-id', $prompt);
});
Global Exception Handler:
Catch Symfony AI exceptions in Laravel’s Handler:
use Symfony\AI\Exception\AIException;
public function render($request, Throwable $exception)
{
if ($exception instanceof AIException) {
return response()->json([
'error' => 'AI Service Unavailable',
'details' => $exception->getMessage(),
], 503);
}
return parent::render($request, $exception);
}
Retry Logic:
Use Laravel’s retry helper for transient failures:
$response = retry(5, function () use ($client, $prompt) {
return $client->generate('ovh-model-id', $prompt);
}, 100);
Symfony/Laravel Namespace Collisions:
HttpFoundation may conflict with Laravel’s.config/app.php:
'aliases' => [
'Symfony\Component\HttpFoundation\Response' => Illuminate\Http\JsonResponse::class,
],
Rate Limiting:
$kernel->pushMiddleware(function ($request, $next) {
$limit = config('ai.rate_limit', 60);
$key = $request->ip().':ovh_ai';
$remaining = Redis::decr($key);
if ($remaining < 0) {
throw new \Symfony\AI\Exception\RateLimitExceededException();
}
return $next($request);
});
Model Versioning:
$modelId = config('ai.providers.ovh.models.text-generation');
if (str_starts_with($modelId, 'deprecated_')) {
Log::warning("OVH model {$modelId} is deprecated. Update config/ai.php.");
}
Authentication Timeouts:
Cache to refresh tokens:
$token = Cache::remember('ovh_ai_token', now()->addHours(1), function () {
return $this->fetchNewTokenFromOVH();
});
Response Parsing:
$rawResponse = $client->generate(...);
$normalized = [
'text' => $rawResponse['choices'][0]['text'] ?? null,
'metadata' => $rawResponse['usage'] ?? [],
];
Enable Symfony Debug Mode:
Add to config/app.php:
'providers' => [
// ...
Symfony\Bundle\FrameworkBundle\Console\Application::class,
],
Run Symfony commands for debugging:
php artisan symfony:debug:ai
Log Raw API Responses: Wrap the client to log requests/responses:
$client = new class($originalClient) {
private $client;
public function __construct($client) { $this->client = $client; }
public function generate($model, $prompt)
{
Log::debug('OVH AI Request', ['model' => $model, 'prompt' => $prompt]);
$response = $this->client->generate($model, $prompt);
Log::debug('OVH AI Response', $response);
return $response;
}
};
Test with OVH’s Sandbox:
Use a sandbox endpoint in .env:
OVH_AI_ENDPOINT=https://sandbox-ovh-ai-endpoint.com
How can I help you explore Laravel packages today?