symfony/ai-open-router-platform
Symfony AI bridge for the OpenRouter platform. Provides integration for chat completions (including streaming), model listing, and rerank requests via OpenRouter’s API, enabling Symfony apps to access multiple LLM providers through a single gateway.
AiClient, Provider interfaces), which may introduce unnecessary complexity in a Laravel-centric stack. However, its provider abstraction (v0.8.0) aligns well with Laravel’s strategy pattern for AI services, enabling dynamic model/provider switching without hardcoding dependencies.Client can be registered as a Laravel service with minimal glue code.Http facade or Guzzle can replace Symfony’s HttpClient, reducing dependency bloat.OpenRouter::chat()).Provider abstraction is a strong fit for Laravel’s modular AI strategy, but requires additional Laravel-specific routing logic.AiClient by injecting Laravel’s Http client. This avoids pulling in Symfony’s entire AI stack.use Symfony\Component\AI\OpenRouter\Client;
use Illuminate\Support\Facades\Http;
$client = new Client(Http::macroable());
^0.9): Optional if using direct HTTP calls. Required only for advanced features like provider routing.^7.3|^8.0): Can be replaced with Laravel’s Http or Guzzle.AiClient. Laravel can consume these as:
$client->chat()).OpenRouter::stream()).StreamingResponse → Laravel’s Events or Broadcasting).laravel-ai).replace to hide Symfony dependencies from vendor/ (if using direct HTTP calls).OpenRouterService).^0.9 is pre-1.0, with potential breaking changes.0.9.0).config('services.openrouter.api_key')).encrypt().$client->stream([new ChatMessage('Hello')])->then(function ($chunk) {
event(new OpenRouterChunkReceived($chunk));
});
Provider abstraction is Symfony-centric and may not integrate seamlessly with Laravel’s service container.OpenRouterProviderResolver) that extends Symfony’s logic.Provider abstraction or a custom Laravel resolver.laravel-ai providers)? Are there caching layers (e.g., Redis) for frequent calls?monolog) or monitoring (e.g., Laravel Horizon)?openrouter/free → paid tiers) based on cost or performance?| Integration Level | Approach | Pros | Cons |
|---|---|---|---|
| Direct API Calls | Use Laravel’s Http client with OpenRouter’s API. |
- No Symfony dependency.- Full control over requests/responses. | - Manual error handling.- No provider abstraction. |
| Lightweight Package | Use symfony/ai-open-router-platform with Laravel’s Http client. |
- Reuses OpenRouter client logic.- Minimal Symfony dependency. | - Limited to OpenRouter features.- No multi-provider support. |
| Full Symfony AI | Use symfony/ai-platform and symfony/ai for multi-provider support. |
- Provider abstraction.- Future-proof for other AI services. | - High Symfony dependency.- Complex setup. |
| Facade Wrapper | Create a Laravel facade (e.g., OpenRouter) around the Symfony client. |
- Laravel-friendly API.- Hides Symfony specifics. | - Adds abstraction layer.- Requires maintenance. |
Recommended Approach:
OpenRouterService class wrapping Http::post() calls.class OpenRouterService {
public function chat(string $message): array {
return Http::post('https://openrouter.ai/api/v1/chat/completions', [
'model' => 'openrouter/free',
'messages' => [['role' => 'user', 'content' => $message]],
])->json();
}
}
symfony/ai-open-router-platform.Client in Laravel’s container:
$this->app->singleton(\Symfony\Component\AI\OpenRouter\Client::class, fn($app) =>
new \Symfony\Component\AI\OpenRouter\Client(
$app['http.client'],
$app['config']['services.openrouter.api_key']
)
);
OpenRouter::chat()) for ergonomics.Events or Broadcasting to handle chunks.
$client->stream([new ChatMessage('Hello')])->then(function ($chunk) {
event(new OpenRouterChunkReceived($chunk));
});
How can I help you explore Laravel packages today?