hamzad / laravel-ai-summary
A reusable Laravel package for AI-powered content summarization supporting OpenAI, Anthropic, Gemini, Mistral, Groq, and OpenRouter.
Requires
- php: ^8.2
- illuminate/cache: ^10.0 || ^11.0 || ^12.0
- illuminate/events: ^10.0 || ^11.0 || ^12.0
- illuminate/http: ^10.0 || ^11.0 || ^12.0
- illuminate/support: ^10.0 || ^11.0 || ^12.0
Requires (Dev)
- orchestra/testbench: ^8.0 || ^9.0 || ^10.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.0 || ^11.0
This package is auto-updated.
Last update: 2026-06-28 10:35:57 UTC
README
A beautiful, provider-agnostic Laravel package for AI-powered content summarization. Extract high-quality summaries, SEO titles, meta descriptions, and semantic entities from any text using your favorite LLM.
Why this package?
Most AI packages tie you directly to OpenAI, forcing you to rewrite your codebase when you want to switch to cheaper/faster alternatives like Groq or Gemini.
Laravel AI Summary acts as an abstraction layer:
- Provider-Agnostic: Switch between OpenAI, Claude, Gemini, Mistral, Groq, or OpenRouter instantly.
- Auto-Fallbacks: If OpenAI is down or rate-limited, the package will automatically retry the prompt with Gemini or Claude.
- Cache-Ready: Saves API costs by automatically caching identical summaries.
- Zero Heavy Dependencies: Uses Laravel's native HTTP client. No bloated SDKs.
- Perfect for: Newsrooms, Blogs, CMS platforms, SaaS apps, and internal knowledge bases.
Warning
This package provides the architecture and API client logic. It does not provide free AI generation. You must obtain and provide your own API keys from the respective providers.
🏗 Architecture Diagram
graph TD
A[AiSummary Facade] --> B[AiSummaryManager]
B -->|Checks Cache| C{Cache Hit?}
C -->|Yes| D[Return Cached SummaryResponse]
C -->|No| E[Determine Provider Chain]
E --> F[Primary Provider e.g. OpenAI]
F -->|Success| G[Return & Cache SummaryResponse]
F -->|Rate Limit / Timeout| H[Fallback Provider e.g. Gemini]
H -->|Success| G
H -->|Fail| I[Throw SummaryGenerationException]
Loading
📊 Provider Comparison
| Provider | Speed | Intelligence | Best For | Native JSON Mode |
|---|---|---|---|---|
| Groq | ⚡️ Extremely Fast | High (Llama 3) | Real-time generation | Yes |
| OpenAI | 🚀 Fast | Very High (GPT-4o) | Complex SEO extraction | Yes |
| Anthropic | 🚀 Fast | Highest (Claude 3.5) | Nuanced analysis | Prompt-based |
| Gemini | 🚀 Fast | High (Gemini 1.5) | High-context windows | Yes |
🚀 Installation
Install the package via composer:
composer require hamzad/laravel-ai-summary
You can optionally publish the config file:
php artisan vendor:publish --tag="ai-summary-config"
⚙️ Configuration
Configure your .env with the default driver and keys:
AI_SUMMARY_DRIVER=openai AI_SUMMARY_LANGUAGE=en # API Keys OPENAI_API_KEY="sk-..." ANTHROPIC_API_KEY="sk-ant-..." GEMINI_API_KEY="AIza..." MISTRAL_API_KEY="mistral-..." GROQ_API_KEY="gsk_..." OPENROUTER_API_KEY="sk-or-..."
💡 Usage Examples
1. Basic Controller Usage
use Hamzad\AiSummary\Facades\AiSummary; class ArticleController extends Controller { public function show(Article $article) { $response = AiSummary::text($article->body) ->language('fa') // Generate Persian summary ->length('short') // 'short', 'medium', 'long' ->driver('gemini') // Override the default provider ->generate(); return view('article.show', [ 'article' => $article, 'aiSummary' => $response->summary, 'aiSeoTitle' => $response->seoTitle, ]); } }
2. Eloquent Model Usage
You can pass an Eloquent model directly. It will extract the content or body attribute automatically.
$summary = AiSummary::for($article)->generate();
3. Background Jobs (Recommended)
Since LLMs take 2-10 seconds to respond, you should dispatch summarization to the queue.
class GenerateSummaryJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; public function __construct(public Article $article) {} public function handle() { $response = AiSummary::for($this->article)->generate(); $this->article->update([ 'summary' => $response->summary, 'seo_title' => $response->seoTitle, ]); } }
4. Livewire Component
use Livewire\Component; use Hamzad\AiSummary\Facades\AiSummary; class AiAssistant extends Component { public string $content = ''; public string $summary = ''; public function generateSummary() { $this->summary = AiSummary::text($this->content) ->driver('groq') // Use Groq for instant UI feedback ->withoutCache() ->generate() ->summary; } }
🛡 Fallback Providers
In config/ai-summary.php, define a chain of fallbacks. If your primary driver hits a rate limit (429) or a 500 error, the package automatically retries using the next provider!
'default' => 'openai', 'fallbacks' => [ 'gemini', 'anthropic' ],
📦 Caching
Caching is enabled by default (TTL: 24h) to save API costs. The cache key is generated using an MD5 hash of the content, language, length, and provider.
// Disable cache for this specific request AiSummary::text($content)->withoutCache()->generate(); // Set custom TTL (in seconds) AiSummary::text($content)->cache(ttl: 3600)->generate();
🛠 Extending (Custom Providers)
You can easily register a custom provider (e.g. local LLM or custom endpoint) in your AppServiceProvider:
use Hamzad\AiSummary\Facades\AiSummary; use App\Services\LocalLlamaProvider; public function boot() { AiSummary::extend('llama', function ($app) { return new LocalLlamaProvider(config('services.llama')); }); }
Then use it seamlessly:
AiSummary::text('Hello')->driver('llama')->generate();
🩺 Troubleshooting
Error: ProviderNotConfiguredException: API Key is missing
- You selected a driver in your
.envbut forgot to provide the matching_API_KEY.
Error: SummaryGenerationException: All AI providers in the fallback chain failed
- Check your network connectivity to the provider. If using Iranian servers, you may need to configure proxy settings inside Laravel's HTTP client or route via a proxy endpoint.
License
The MIT License (MIT). Please see License File for more information.