subhashladumor1/laravel-ai-guard

Laravel AI Guard πŸ›‘οΈ β€” AI cost & budget control for Laravel AI SDK. Track token usage, control OpenAI & LLM spending, enforce AI budgets, and prevent unexpected billing spikes.

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/subhashladumor1/laravel-ai-guard

1.0.1 2026-02-08 17:21 UTC

This package is auto-updated.

Last update: 2026-02-08 17:31:42 UTC


README

Track costs β€’ Set budgets β€’ Never get surprised by the bill.

Laravel AI Guard is a powerful AI cost optimization package built for the Laravel AI SDK (12.x) πŸš€. It helps Laravel developers track OpenAI & LLM token usage πŸ“Š, estimate AI costs before execution ⚠️, enforce per-user or per-tenant AI budgets 🧾, and prevent unexpected AI billing spikes πŸ’₯ in production.

Designed for Laravel SaaS applications, APIs, and AI-powered platforms, Laravel AI Guard acts as a financial firewall πŸ›‘οΈ between your app and AI providersβ€”keeping AI usage safe, predictable, and cost-efficient πŸ’Έ.

---

πŸ“‘ Quick Navigation

Jump to Jump to
What's Inside How It Works
Quick Start Usage Examples
Configuration Package Structure

✨ What's Inside

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”‚
β”‚   β”‚   TRACK     β”‚  β”‚   BUDGET    β”‚  β”‚  ESTIMATE   β”‚  β”‚   BLOCK     β”‚           β”‚
β”‚   β”‚  Every call β”‚  β”‚ Per user/   β”‚  β”‚ Before you  β”‚  β”‚ Over-spend  β”‚           β”‚
β”‚   β”‚  in DB      β”‚  β”‚ tenant/app  β”‚  β”‚ call (free) β”‚  β”‚ requests    β”‚           β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β”‚
β”‚                                                                                  β”‚
β”‚                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                              β”‚
β”‚                        β”‚   🚨 KILL SWITCH        β”‚                              β”‚
β”‚                        β”‚   Disable all AI        β”‚                              β”‚
β”‚                        β”‚   in one config change  β”‚                              β”‚
β”‚                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                              β”‚
β”‚                                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Works with: Laravel AI SDK (12.x) β€’ OpenAI β€’ Anthropic β€’ Any AI API

πŸ”„ How It Works

Request Flow (Before β†’ During β†’ After)

flowchart TD
    subgraph BEFORE["πŸ›‘οΈ BEFORE"]
        A[Request arrives] --> B{Budget OK?}
        B -->|Yes| C[Optional: Estimate cost]
        B -->|No| D[❌ Block - 402]
        C --> E[Continue]
    end

    subgraph DURING["⚑ DURING"]
        E --> F[Your app calls AI]
        F --> G[Laravel AI SDK or any API]
    end

    subgraph AFTER["πŸ“Š AFTER"]
        G --> H[Record tokens, cost, user]
        H --> I[Save to ai_usages]
        I --> J[Update ai_budgets]
    end

    BEFORE --> DURING --> AFTER
Loading

Budget Hierarchy (Checked in Order)

flowchart LR
    subgraph layers["Budget layers checked top to bottom"]
        direction TB
        A["🌍 GLOBAL<br/>Whole app limit"]
        B["🏒 TENANT<br/>Org/team limit"]
        C["πŸ‘€ USER<br/>Per-user limit"]
    end

    A --> B --> C

    C --> D{All OK?}
    D -->|Yes βœ“| E[Allow request]
    D -->|Any exceeded βœ—| F[Block - 402]
Loading

TL;DR: Laravel AI SDK does the AI. Laravel AI Guard decides whether you're allowed to call and how much you spent. They work together.

πŸ€” Why Should I Care?

     WITHOUT AI GUARD                    WITH AI GUARD
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ’Έ Surprise bill       β”‚      β”‚  πŸ“Š Full visibility     β”‚
β”‚  πŸ› Runaway loop?       β”‚  β†’   β”‚  πŸ›‘ Budget limits       β”‚
β”‚  😰 Invoice shock       β”‚      β”‚  😌 Predictable costs   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

AI APIs charge by the token. One heavy user, one bugβ€”and your bill spikes. Most apps don't track until the invoice arrives. AI Guard gives you visibility, limits, and control.

πŸ“ Under the Hood

Cost Calculation

flowchart LR
    subgraph inputs["Inputs"]
        A[Input Tokens]
        B[Output Tokens]
        C[Model Pricing]
    end

    subgraph formula["Formula"]
        D["(Input Γ· 1000) Γ— Input Price"]
        E["(Output Γ· 1000) Γ— Output Price"]
        F["+"]
    end

    subgraph result["Result"]
        G["Total Cost $"]
    end

    A --> D
    B --> E
    C --> D
    C --> E
    D --> F
    E --> F
    F --> G
Loading

Example: 500 input + 200 output tokens (gpt-4o: $0.0025/1k in, $0.01/1k out)

Step Calculation Result
Input cost (500 Γ· 1000) Γ— 0.0025 $0.00125
Output cost (200 Γ· 1000) Γ— 0.01 $0.00200
Total $0.00325

Estimation (No API Call = No Cost)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  AIGuard::estimate($prompt)                               β”‚
β”‚                                                           β”‚
β”‚  Input tokens  β‰ˆ  characters Γ· 4    (configurable)       β”‚
β”‚  Output tokens β‰ˆ  input Γ— 0.5       (configurable)       β”‚
β”‚                                                           β”‚
β”‚  "Write a short poem" (18 chars) β†’ ~5 in, ~3 out β†’ 8     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Kill Switch

Method How
.env (recommended) AI_GUARD_DISABLED=true
Config 'ai_disabled' => true

Result: Middleware returns 503 Service Unavailable β€” no AI calls get through.

πŸ’‘ 5 Ways to Reduce AI Costs

    β‘  ESTIMATE         β‘‘ BUDGET          β‘’ TRACK           β‘£ KILL SWITCH      β‘€ TAG
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Show cost   β”‚   β”‚ Set limits   β”‚   β”‚ Run report  β”‚   β”‚ Emergency   β”‚   β”‚ Break down  β”‚
β”‚ before call β”‚   β”‚ per user/    β”‚   β”‚ to see      β”‚   β”‚ stop all    β”‚   β”‚ by feature  β”‚
β”‚             β”‚   β”‚ tenant       β”‚   β”‚ where $ goesβ”‚   β”‚ AI if neededβ”‚   β”‚ (chat, etc) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‹ Requirements

Requirement Version
PHP 8.1+
Laravel 10.x, 11.x, or 12.x
Laravel AI SDK Optional (for agents/streaming)

πŸš€ Quick Start (3 Steps)

flowchart LR
    subgraph step1["Step 1"]
        A[composer require]
    end

    subgraph step2["Step 2"]
        B[publish config<br/>& migrations]
    end

    subgraph step3["Step 3"]
        C[migrate]
    end

    A --> B --> C
Loading

1. Install

composer require subhashladumor1/laravel-ai-guard

2. Publish & migrate

php artisan vendor:publish --tag=ai-guard-config
php artisan vendor:publish --tag=ai-guard-migrations
php artisan migrate

3. Optional β€” translations

php artisan vendor:publish --tag=ai-guard-lang

Creates: ai_usages (every call) + ai_budgets (limits & usage)

βš™οΈ Configuration

Edit config/ai-guard.php after publishing:

Setting Purpose
ai_disabled Turn off all AI
pricing Cost per 1k tokens per model
default_model Fallback (e.g. gpt-4o)
default_provider Fallback (e.g. openai)
budgets Limits (global, user, tenant); period
estimation Chars per token, output multiplier

Example .env:

AI_GUARD_DISABLED=false
AI_GUARD_GLOBAL_LIMIT=100
AI_GUARD_USER_LIMIT=10
AI_GUARD_TENANT_LIMIT=50

πŸ“– Usage Examples

With Laravel AI SDK (12.x)

sequenceDiagram
    participant App
    participant AIGuard
    participant AI

    App->>AIGuard: checkAllBudgets()
    App->>AIGuard: estimate(prompt)
    App->>AI: prompt()
    AI-->>App: response
    App->>AIGuard: recordFromResponse()
Loading
// 1. Before β€” check budget
AIGuard::checkAllBudgets(auth()->id(), $tenantId);
$estimate = AIGuard::estimate($userPrompt);

// 2. Call AI (as normal)
$response = (new YourAgent)->prompt($userPrompt);

// 3. After β€” record usage
AIGuard::recordFromResponse($response, userId: auth()->id(), tenantId: $tenantId, tag: 'chat');

Multi-model: Pass model and provider so estimate and budgets use the right cost:

$estimate = AIGuard::estimate($userPrompt, model: 'gpt-4o-mini', provider: 'openai');
AIGuard::recordFromResponse($response, userId: auth()->id(), provider: 'openai', model: 'gpt-4o-mini');

Streaming: record in ->then() callback when stream finishes.

With Any Other AI API

// Before β€” same
AIGuard::checkAllBudgets(auth()->id(), $tenantId);

// After β€” record manually
AIGuard::recordAndApplyBudget([
    'provider' => 'openai',
    'model' => 'gpt-4o',
    'input_tokens' => 400,
    'output_tokens' => 250,
    'user_id' => auth()->id(),
    'tenant_id' => $tenantId,
    'tag' => 'chat',
]);

Multi-model and dynamic cost (no config change)

Cost is resolved in order: per-call override β†’ runtime pricing β†’ config. So you can support many models and change costs at runtime without editing config/ai-guard.php.

1. Per-call pricing override β€” pass pricing for a single estimate or record:

// Estimate with custom cost per 1k tokens (no config entry needed)
$estimate = AIGuard::estimate($userPrompt, 'my-model', 'my-provider', [
    'input' => 0.001,
    'output' => 0.002,
]);

// Record with custom pricing when cost isn't pre-calculated
AIGuard::recordFromResponse($response, auth()->id(), $tenantId, 'openai', 'gpt-4o', 'chat', [
    'input' => 0.0025,
    'output' => 0.01,
]);

// record() can omit 'cost' and use 'pricing' to calculate
AIGuard::record([
    'provider' => 'openai',
    'model' => 'gpt-4o',
    'input_tokens' => 400,
    'output_tokens' => 250,
    'pricing' => ['input' => 0.0025, 'output' => 0.01],
    'user_id' => auth()->id(),
]);

2. Runtime pricing registry β€” register models once (e.g. in a service provider or from DB); then estimate() and recording use them automatically:

$calc = AIGuard::getCostCalculator();

// Single model
$calc->setPricing('openai', 'gpt-4o-mini', ['input' => 0.00015, 'output' => 0.0006]);

// Many models at once
$calc->setPricingMap([
    'openai' => [
        'gpt-4o' => ['input' => 0.0025, 'output' => 0.01],
        'gpt-4o-mini' => ['input' => 0.00015, 'output' => 0.0006],
    ],
    'anthropic' => [
        'claude-3-5-sonnet' => ['input' => 0.003, 'output' => 0.015],
    ],
]);

// Now estimate/record use these models without config
$estimate = AIGuard::estimate($userPrompt, 'gpt-4o-mini', 'openai');
AIGuard::checkAllBudgets(auth()->id(), $tenantId);

Add, update or remove models at runtime:

$calc = AIGuard::getCostCalculator();

// Add or update a model
$calc->setPricing('openai', 'gpt-4o', ['input' => 0.0025, 'output' => 0.01]);

// Remove a model from runtime (falls back to config, or 0 if not in config)
$calc->removePricing('openai', 'gpt-4o');

// Clear all runtime pricing
$calc->clearRuntimePricing();

Config file β€” publish and edit config/ai-guard.php to add, remove or update models permanently:

'pricing' => [
    'openai' => [
        'gpt-4o' => ['input' => 0.0025, 'output' => 0.01],
        'gpt-4o-mini' => ['input' => 0.00015, 'output' => 0.0006],
        // Add new models here
    ],
    // Add new providers here
],

Budget checks use the same cost you record (per user/tenant), so multi-model costs and budgets work together.

Middleware

Route::post('/chat', ChatController::class)->middleware('ai.guard');
Condition Response
Over budget 402 + JSON
AI disabled 503

Artisan Commands

Command Purpose
php artisan ai-guard:report Usage & cost report
php artisan ai-guard:report --period=month Monthly report
php artisan ai-guard:report --days=7 Last 7 days
php artisan ai-guard:reset-budgets Reset when period ends
php artisan ai-guard:reset-budgets --dry-run Preview only

Schedule reset: $schedule->command('ai-guard:reset-budgets')->daily();

πŸ—‚οΈ Package Structure

flowchart TB
    subgraph entry["Entry Points"]
        F[AIGuard Facade]
        M[EnforceAIBudget Middleware]
        C1[ai-guard:report]
        C2[ai-guard:reset-budgets]
    end

    subgraph core["Core"]
        GM[GuardManager]
    end

    subgraph services["Services"]
        BR[BudgetResolver]
        BE[BudgetEnforcer]
        TE[TokenEstimator]
        CC[CostCalculator]
    end

    subgraph storage["Storage"]
        AU[AiUsage]
        AB[AiBudget]
    end

    F --> GM
    M --> GM
    C1 --> GM
    C2 --> GM
    GM --> BR
    GM --> BE
    GM --> TE
    GM --> CC
    BR --> AB
    BE --> AB
    CC --> AU
Loading
laravel-ai-guard/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ GuardManager.php          # Core logic
β”‚   β”œβ”€β”€ Facades/AIGuard.php
β”‚   β”œβ”€β”€ Budget/                   # BudgetResolver, BudgetEnforcer
β”‚   β”œβ”€β”€ Cost/                     # TokenEstimator, CostCalculator
β”‚   β”œβ”€β”€ Models/                   # AiUsage, AiBudget
β”‚   β”œβ”€β”€ Middleware/
β”‚   β”œβ”€β”€ Commands/
β”‚   └── Exceptions/
β”œβ”€β”€ database/migrations/
β”œβ”€β”€ lang/                         # 11 locales
└── tests/

🌍 Multi-Language

11 locales: en, ar, es, fr, de, zh, hi, bn, pt, ru, ja

App locale used automatically. Customize: php artisan vendor:publish --tag=ai-guard-lang

🏒 Multi-Tenant (SaaS)

  • Store tenant_id on each usage
  • Set tenant budgets in config
  • Middleware reads tenant from X-Tenant-ID header or request attribute

πŸ§ͺ Testing

composer install && php artisan test

πŸ“„ License

MIT. See LICENSE.