illuma-law / laravel-llm-router
A resilient AI routing and circuit-breaker system for LLM requests in Laravel.
Requires
- php: ^8.3
- illuminate/contracts: ^11.0||^12.0||^13.0
- illuminate/support: ^11.0||^12.0||^13.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.1
- laravel/ai: ^0.6.0
- laravel/pint: ^1.21
- mrpunyapal/peststan: ^0.2.12
- nunomaduro/collision: ^8.6
- orchestra/testbench: ^10.1
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-ray: ^1.39
Suggests
- laravel/ai: Required for the built-in prompt() integration; run() can use your own closure.
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-23 14:05:10 UTC
README
Route Laravel AI requests through ordered provider/model chains with retries, fallbacks, and tenant-aware overrides.
Requires PHP 8.3+ and Laravel 11, 12, or 13. Install Laravel AI and configure
its provider credentials to use the built-in prompt() method. You can use
the router without Laravel AI by providing your own request closure.
Install
composer require illuma-law/laravel-llm-router php artisan vendor:publish --tag=llm-router-config
For the built-in prompt integration:
composer require laravel/ai
Edit config/llm-router.php to set the provider/model order for each tier.
Route a request
Use a closure to run each provider/model attempt. The router returns the result and the provider/model that succeeded:
use IllumaLaw\LlmRouter\Enums\DefaultTier; use IllumaLaw\LlmRouter\Facades\LLMRouter; use Laravel\Ai\Facades\Ai; $response = LLMRouter::tier(DefaultTier::Large) ->run(fn (string $provider, string $model) => Ai::provider($provider) ->model($model) ->prompt('Summarize this report.')); $answer = $response['result']->text; $usedProvider = $response['provider'];
To pass a Laravel AI agent, provide its class name to forAgent() and the
instance to agent():
$response = LLMRouter::forAgent($agent::class) ->agent($agent) ->tier(DefaultTier::Large) ->run(fn (string $provider, string $model) => $agent->prompt( 'Review this report.', provider: $provider, model: $model, ));
Tenant and operation routing
Use forTenant() to apply the configured priority model when your resolver
marks that tenant as requiring it. Use operation() for a chain defined under
operations in the config:
LLMRouter::resolvePriorityUsing( fn ($tenant): bool => $tenant->requires_local_models, ); $response = LLMRouter::operation('image_generation') ->forTenant($tenant) ->run(fn (string $provider, string $model) => "Generated by {$provider}/{$model}");
Other reusable services include ProviderAvailability, ChainRowValidator,
and CooldownStore.
Test
composer test
composer analyse
vendor/bin/pint --test
MIT licensed. See LICENSE.
