symfony/ai-failover-platform
Symfony AI Failover Platform bridge that adds resilient fallback behavior across AI providers. Integrates with Symfony AI to automatically switch to alternate platforms on errors or outages, improving availability and reliability in production deployments.
ClientInterface, ProviderRegistry, EventDispatcher), requiring significant adaptation to fit Laravel’s architecture. Laravel’s service container, event system, and HTTP client (Illuminate\Http) are not direct drop-ins for Symfony’s equivalents, necessitating custom adapters or facades.Autowire and CompilerPass are incompatible with Laravel’s container. Manual bindings or custom providers will be required.EventDispatcher must be bridged to Laravel’s Illuminate\Events, potentially requiring duplicate event listeners or custom event classes.HttpClient; Laravel’s Http facade or Guzzle will need adapters to conform to HttpClientInterface.Messenger for async failover). Laravel’s queue system (Illuminate\Queue) may not align.ProviderInterface?config/ai.php) replace Symfony’s YAML/XML configurations?App\Exceptions\Handler (e.g., custom error pages, logging)?Illuminate\Pipeline)?config/ai.php, or does it require Symfony-specific YAML?Messenger for async failover? If so, how can Laravel’s Illuminate\Queue replace it without breaking functionality?AiProviderFailedEvent) that require Laravel equivalents (e.g., custom events or service listeners)?Log facade or monitoring tools (e.g., Sentry, Datadog) out of the box?Illuminate\Http or Guzzle as adapters for HttpClientInterface).Illuminate\Events as a drop-in for EventDispatcher).config/ai.php to replace Symfony’s YAML/XML).class LaravelHttpClient implements \Symfony\Contracts\HttpClient\HttpClientInterface {
public function request(string $method, string $url, array $options = []): \Symfony\Contracts\HttpClient\ResponseInterface {
$response = Http::withOptions($options)->{$method}($url);
return new SymfonyHttpClientResponse($response);
}
}
class LaravelEventDispatcher implements \Symfony\Contracts\EventDispatcher\EventDispatcherInterface {
public function dispatch(object $event, ?string $eventName = null): object {
event($eventName ?? get_class($event), $event);
return $event;
}
}
class LaravelProviderRegistry implements \Symfony\Component\Ai\Provider\ProviderRegistryInterface {
public function getProviders(): iterable {
foreach (config('ai.providers') as $provider) {
yield $this->app->make($provider['class']);
}
}
}
AppServiceProvider:
public function register() {
$this->app->singleton(\Symfony\Component\Ai\Failover\FailoverClient::class, function ($app) {
return new \Symfony\Component\Ai\Failover\FailoverClient(
new LaravelProviderRegistry($app),
new LaravelEventDispatcher($app),
config('ai.failover.strategy')
);
});
}
composer require symfony/ai symfony/ai-failover-platform symfony/http-client
composer why-not symfony/http-client # Resolve conflicts with Laravel's Guzzle
HttpClient, EventDispatcher, and ProviderRegistry (as shown above).AppServiceProvider:
$this->app->singleton(\Symfony\Contracts\HttpClient\HttpClientInterface, function () {
return new LaravelHttpClient();
});
$this->app->singleton(\Symfony\Contracts\EventDispatcher\EventDispatcherInterface, function () {
return new LaravelEventDispatcher();
});
config/ai.php:
'ai' => [
'providers' => [
'openai' => [
'class' => \Symfony\Component\Ai\Provider\OpenAiProvider::class,
'api_key' => env('OPENAI_API_KEY'),
'priority' => 1,
],
'local_llm' => [
'class' => \App\Providers\LocalLlmProvider::class,
'priority' => 2,
],
],
'failover' => [
'strategy' => 'priority',
'max_attempts' => 3,
],
],
$response = app(\Symfony\Component\Ai\Failover\FailoverClient::class)
->complete('User:', 'Generate a summary...');
$response = Cache::remember('ai-response-key', now()->addHours(1), function () {
return app(\Symfony\Component\Ai\Failover\FailoverClient::class)
->complete('User:', 'Generate a summary...');
});
Http::fake([
'api.openai.com/*' => Http::response([], 500), // Simulate failure
]);
$response = app(\Symfony\Component\Ai\Failover\FailoverClient::class)
->complete('User:', 'Test fallback...');
$response->assertSuccess(); // Verify fallback worked
symfony/ai to a stable version (e.g., ^0.7.0) to avoid breaking changesHow can I help you explore Laravel packages today?