hamzad/laravel-ai-summary

A reusable Laravel package for AI-powered content summarization supporting OpenAI, Anthropic, Gemini, Mistral, Groq, and OpenRouter.

Maintainers

Package info

github.com/tmolavi/laravel-ai-summary

pkg:composer/hamzad/laravel-ai-summary

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-05-28 09:48 UTC

This package is auto-updated.

Last update: 2026-06-28 10:35:57 UTC


README

Latest Version on Packagist Tests Total Downloads PHP Version Laravel Version License

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 .env but 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.