Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ai Failover Platform Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install Dependencies

    composer require symfony/ai symfony/ai-failover-platform symfony/http-client
    

    Note: Resolve conflicts with Laravel’s guzzlehttp/guzzle or illuminate/http via composer why-not and use package aliases if needed.

  2. Configure Providers Define AI providers and failover strategy in config/ai.php:

    'ai' => [
        'providers' => [
            'openai' => [
                'class' => \Symfony\Component\Ai\Provider\OpenAiProvider::class,
                'api_key' => env('OPENAI_API_KEY'),
                'priority' => 1,
            ],
            'local' => [
                'class' => \App\Providers\LocalAiProvider::class, // Custom fallback
                'priority' => 2,
            ],
        ],
        'failover' => [
            'strategy' => 'priority', // or 'round-robin'
            'max_attempts' => 3,
        ],
    ],
    
  3. Bind Symfony Components Register a service provider to bind Symfony’s FailoverClient to Laravel’s container:

    // app/Providers/AiServiceProvider.php
    use Symfony\Component\Ai\Failover\FailoverClient;
    use Symfony\Component\Ai\Provider\ProviderRegistry;
    
    public function register()
    {
        $this->app->singleton(ProviderRegistry::class, function ($app) {
            return new ProviderRegistry($app['config']['ai.providers']);
        });
    
        $this->app->singleton(FailoverClient::class, function ($app) {
            return new FailoverClient(
                $app->make(ProviderRegistry::class),
                $app['config']['ai.failover']
            );
        });
    }
    
  4. First Use Case: AI Response with Failover Replace direct API calls with the failover client:

    use Symfony\Component\Ai\Failover\FailoverClient;
    
    $response = app(FailoverClient::class)
        ->complete('User:', 'Generate a summary of the document.');
    

Implementation Patterns

Core Workflows

1. Provider Registration

  • Dynamic Providers: Extend Symfony\Component\Ai\Provider\ProviderInterface for custom providers (e.g., local LLMs):
    class LocalAiProvider implements ProviderInterface
    {
        public function complete(string $prompt, string $model): string
        {
            // Local logic (e.g., PHP-ML, Ollama)
            return "Local response for: $prompt";
        }
    }
    
  • Laravel Configuration: Use config/ai.php to define providers with priorities:
    'providers' => [
        'openai' => ['class' => \Symfony\Component\Ai\Provider\OpenAiProvider::class, 'priority' => 1],
        'local' => ['class' => \App\Providers\LocalAiProvider::class, 'priority' => 2],
    ],
    

2. Failover Strategies

  • Priority-Based: Providers are tried in order until one succeeds.
    $client = new FailoverClient($registry, ['strategy' => 'priority']);
    
  • Round-Robin: Distribute requests across providers (useful for load balancing):
    $client = new FailoverClient($registry, ['strategy' => 'round-robin']);
    
  • Custom Strategies: Implement Symfony\Component\Ai\Failover\Strategy\StrategyInterface for advanced logic (e.g., cost-aware routing).

3. Integration with Laravel Services

  • Queue Failover Logic: Offload failover attempts to queues to avoid blocking requests:
    use Illuminate\Support\Facades\Bus;
    
    Bus::dispatch(new HandleAiRequest($prompt));
    
    // HandleAiRequest.php
    public function handle()
    {
        $response = app(FailoverClient::class)->complete($this->prompt, $this->model);
        // Process response...
    }
    
  • Event-Driven Fallbacks: Listen for failover events to trigger side effects (e.g., logging, alerts):
    // app/Providers/EventServiceProvider.php
    protected $listen = [
        \Symfony\Component\Ai\Failover\Event\ProviderFailedEvent::class => [
            \App\Listeners\LogFailover::class,
        ],
    ];
    

4. Caching Fallback Responses

  • Cache responses from successful providers to serve during outages:
    use Illuminate\Support\Facades\Cache;
    
    $response = Cache::remember("ai_{$prompt}_{$model}", now()->addHours(1), function () {
        return app(FailoverClient::class)->complete($prompt, $model);
    });
    

5. Testing Failover Scenarios

  • Mock provider failures in tests:
    use Symfony\Component\Ai\Provider\ProviderInterface;
    
    $mockProvider = $this->createMock(ProviderInterface::class);
    $mockProvider->method('complete')->willThrowException(new \RuntimeException('API Down'));
    
    $registry = new ProviderRegistry(['mock' => $mockProvider]);
    $client = new FailoverClient($registry, ['strategy' => 'priority']);
    

Laravel-Specific Patterns

1. HTTP Client Adapter

Replace Symfony’s HttpClient with Laravel’s Http facade:

// app/Adapters/LaravelHttpClient.php
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
use Illuminate\Support\Facades\Http;

class LaravelHttpClient implements HttpClientInterface
{
    public function request(string $method, string $url, array $options = []): ResponseInterface
    {
        $response = Http::withOptions($options)->{$method}($url);
        return new SymfonyHttpClientResponse($response);
    }
}

Bind it in AiServiceProvider:

$this->app->singleton(HttpClientInterface::class, function () {
    return new LaravelHttpClient();
});

2. Configuration-Driven Providers

Dynamically instantiate providers from config/ai.php:

// app/Providers/AiServiceProvider.php
public function register()
{
    foreach ($this->app['config']['ai.providers'] as $name => $config) {
        $this->app->singleton($name, function () use ($config) {
            return new $config['class']($this->app['config']['ai.' . $name]);
        });
    }
}

3. Exception Handling

Catch failover-specific exceptions and map them to Laravel’s error handler:

// app/Exceptions/Handler.php
public function render($request, Throwable $exception)
{
    if ($exception instanceof \Symfony\Component\Ai\Failover\Exception\NoProviderAvailable) {
        return response()->view('ai.fallback', [], 503);
    }
    return parent::render($request, $exception);
}

4. Command-Line Failover Testing

Create an Artisan command to simulate provider failures:

// app/Console/Commands/TestFailover.php
use Symfony\Component\Ai\Failover\FailoverClient;

public function handle()
{
    $client = app(FailoverClient::class);
    $response = $client->complete('Test prompt', 'gpt-3.5-turbo');
    $this->info("Failover response: {$response}");
}

Gotchas and Tips

Pitfalls

1. Symfony vs. Laravel DI Conflicts

  • Issue: Symfony’s ServiceLocator may clash with Laravel’s container. Fix: Use Laravel’s bind() method to override Symfony bindings:
    $this->app->bind(\Symfony\Component\Ai\Failover\FailoverClient::class, function ($app) {
        return new FailoverClient($app->make(\Symfony\Component\Ai\Provider\ProviderRegistry::class), $app['config']['ai.failover']);
    });
    

2. HTTP Client Incompatibility

  • Issue: Symfony’s HttpClient expects specific response formats; Laravel’s Http returns Illuminate\Http\Client\Response. Fix: Create a response adapter:
    class SymfonyHttpClientResponse implements \Symfony\Contracts\HttpClient\ResponseInterface
    {
        public function __construct(private \Illuminate\Http\Client\Response $response) {}
    
        public function getStatusCode(): int
        {
            return $this->response->status();
        }
    
        public function getContent(false $throw = true): string
        {
            return $this->response->body();
        }
    }
    

3. Provider Initialization Order

  • Issue: Providers may not initialize in priority order if dynamically bound. Fix: Sort providers by priority in the registry:
    $providers = collect($config['providers'])
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor