PHPackages                             backtik-ch/laravel-ai-usage - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. backtik-ch/laravel-ai-usage

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

backtik-ch/laravel-ai-usage
===========================

Track and log AI usage (tokens, cost, duration) for any Laravel application, with optional auto-discovery for laravel/ai SDK.

v1.0.7(2w ago)0219MITPHPPHP ^8.3

Since Jul 8Pushed 2w agoCompare

[ Source](https://github.com/backtik-ch/laravel-ai-usage)[ Packagist](https://packagist.org/packages/backtik-ch/laravel-ai-usage)[ RSS](/packages/backtik-ch-laravel-ai-usage/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (8)Dependencies (12)Versions (9)Used By (0)

Laravel AI Usage
================

[](#laravel-ai-usage)

[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)

Track and log AI usage (tokens, cost, duration) for any Laravel application, with optional auto-discovery for the `laravel/ai` SDK and an optional Filament panel integration.

Requirements
------------

[](#requirements)

- PHP 8.3+
- Laravel 12.x

Installation
------------

[](#installation)

```
composer require backtik-ch/laravel-ai-usage
```

Publish the config file and run the migrations:

```
php artisan vendor:publish --tag=ai-usage-config
php artisan migrate
```

How It Works
------------

[](#how-it-works)

This package hooks into the `laravel/ai` SDK lifecycle via two events:

1. **`PromptingAgent`** — fired when an agent starts. The package creates a **pending** record with the agent class, label, and an invocation ID.
2. **`AgentPrompted`** — fired when the agent completes. The package locates the pending record, fills in token counts, duration, model/driver info, and snapshots the token prices from your config.

The result is a complete, immutable log of every AI call — no manual code required if you use `laravel/ai`.

If you're not using `laravel/ai`, you can log calls manually via the fluent `AiUsage` facade (see [Manual logging](#manual-logging)).

Configuration
-------------

[](#configuration)

The config file (`config/ai-usage.php`) exposes the following options:

KeyDefaultDescription`table``ai_usage`Database table name`queue_logs``false`Dispatch log writes as queued jobs`log_system_prompt``false`Store system prompts in the log`log_response_text``true`Store AI response bodies`max_text_length``10_000`Truncate prompt/response text (chars); `null` disables`stale_timeout_minutes``60`Minutes before a `processing` record is considered stale`auto_discover``true`Auto-listen to `laravel/ai` events`attach_authenticated_user``false`Associate auto-discovered logs with the authenticated user`show_costs``true`Show estimated costs and pricing details in the Filament UI`prices`*(see below)*Token prices (USD / 1 M tokens) per driver &amp; model### Token prices

[](#token-prices)

Prices are snapshotted into each log row at write time so historical cost estimates remain accurate after you update the config.

```
// config/ai-usage.php
'prices' => [
    'openai' => [
        'gpt-4o' => ['prompt' => 2.50, 'completion' => 10.00],
        'gpt-4o-mini' => ['prompt' => 0.15, 'completion' => 0.60],
        // ...
    ],
    'anthropic' => [
        'claude-sonnet-4-5' => [
            'prompt' => 3.00, 'completion' => 15.00,
            'cache_read' => 0.30, 'cache_write' => 3.75,
        ],
        // ...
    ],
    'gemini' => [
        'gemini-2.0-flash' => ['prompt' => 0.10, 'completion' => 0.40],
        // ...
    ],
],
```

Supported price keys: `prompt`, `completion`, `cache_read`, `cache_write`, `reasoning`.

The package ships with indicative prices for common OpenAI, Anthropic and Gemini models. Always verify against your provider's current pricing page.

### Hide pricing in Filament

[](#hide-pricing-in-filament)

To hide estimated costs and price-related details from the package's Filament resource and summary widget, set:

```
// config/ai-usage.php
'show_costs' => false,
```

This only affects the UI. The package continues to snapshot configured or manually supplied prices into usage logs, so historical cost data remains available if you later re-enable the setting.

Usage
-----

[](#usage)

Tip

**Using `laravel/ai`? You're already done.** If auto-discovery is enabled (default) and `laravel/ai` is installed, every AI agent call is logged automatically — no code needed. The sections below are for **manual logging** or custom integrations.

### Auto-discovery mode

[](#auto-discovery-mode)

When `auto_discover` is `true` (default) and `laravel/ai` is installed, the package automatically listens for `Laravel\Ai\Events\PromptingAgent` and `Laravel\Ai\Events\AgentPrompted`. A pending record is created when the agent starts, then updated with tokens, duration, model info, and cost data when the agent finishes.

To disable auto-discovery, set `auto_discover` to `false` in `config/ai-usage.php`.

### Attach an owner automatically

[](#attach-an-owner-automatically)

To associate each automatically discovered log with the authenticated user, enable the following option:

```
// config/ai-usage.php
'attach_authenticated_user' => true,
```

The package uses the user from Laravel's default authentication guard. Numeric IDs, UUIDs, and ULIDs are supported. Guests and contexts without authentication, such as jobs and commands, are logged without an owner. If the authenticated user cannot be resolved, is not an Eloquent model, or has no primary key, the package writes a warning and creates the usage log without an owner.

### Manual logging

[](#manual-logging)

Use the `AiUsage` facade with a fluent builder:

```
use BacktikCh\LaravelAiUsage\Facades\AiUsage;

AiUsage::driver('openai')
    ->model('gpt-4o')
    ->label('summarize-article')
    ->agentClass(MyAgent::class)          // optional — FQCN of the agent
    ->tokens(
        prompt: 512,
        completion: 256,
        cacheWrite: 0,                    // optional
        cacheRead: 0,                     // optional
        reasoning: 0,                     // optional
    )
    ->duration(milliseconds: 1200)
    ->prompt('Summarize this article...')
    ->response('The article discusses...')
    ->status('completed')
    ->requestMeta(['temperature' => 0.7]) // optional arbitrary metadata
    ->responseMeta(['finish_reason' => 'stop'])
    ->log();
```

### Attach to a model (polymorphic owner)

[](#attach-to-a-model-polymorphic-owner)

```
AiUsage::driver('openai')
    ->model('gpt-4o')
    ->tokens(300, 150)
    ->owner($user) // any Eloquent model
    ->log();
```

### Override prices at log time

[](#override-prices-at-log-time)

```
AiUsage::driver('openai')
    ->model('gpt-4o')
    ->tokens(300, 150)
    ->costPrices(['prompt' => 2.50, 'completion' => 10.00])
    ->log();
```

If `costPrices()` is not called, prices are resolved automatically from `config('ai-usage.prices')`.

### How cost estimation works

[](#how-cost-estimation-works)

Token prices (USD per 1 million tokens) are **snapshotted from your config at log time** and stored alongside each record. This means historical cost data remains accurate even when you update prices later.

The `AiUsageLog` model exposes an `estimated_cost` computed attribute derived from the stored token counts and prices:

```
$log = AiUsageLog::find(1);
echo $log->estimated_cost; // e.g. 0.003450
```

Returns `null` when no price data is available (i.e., the model isn't listed in your `prices` config).

To add a new model, simply add its prices to `config('ai-usage.prices.{driver}.{model}')`. Supported price keys: `prompt`, `completion`, `cache_read`, `cache_write`, `reasoning`.

### Status values

[](#status-values)

Logs use the `AiUsageStatus` enum: `pending`, `processing`, `completed`, `failed`.

Filament integration
--------------------

[](#filament-integration)

Requires `filament/filament`. Register the plugin in your panel provider:

```
use BacktikCh\LaravelAiUsage\Filament\AiUsagePlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugin(AiUsagePlugin::make());
}
```

This registers:

- **`AiUsageResource`** — browsable, filterable list of all log entries with a detail view.
- **`AiUsageStatsWidget`** — stats overview: total calls, prompt/completion tokens, average duration, failed count.

### Summary widget (standalone)

[](#summary-widget-standalone)

`AiUsageSummaryWidget` is a full-width Livewire widget with a period selector and per-driver / per-model token breakdowns. Add it to any page:

```
use BacktikCh\LaravelAiUsage\Filament\Widgets\AiUsageSummaryWidget;

protected function getHeaderWidgets(): array
{
    return [AiUsageSummaryWidget::class];
}
```

Artisan Commands
----------------

[](#artisan-commands)

### Prune old records

[](#prune-old-records)

```
php artisan ai-usage:prune --days=90
```

### Mark stale records as failed

[](#mark-stale-records-as-failed)

If an AI call throws an exception, the `laravel/ai` SDK never fires `AgentPrompted`, so the record stays in `processing` status indefinitely. Run this command on a schedule to mark those stale records as `failed`:

```
php artisan ai-usage:mark-stale-failed
```

The timeout is controlled by `stale_timeout_minutes` in your config (default: `60`). You can also override it per-call:

```
php artisan ai-usage:mark-stale-failed --minutes=30
```

Add both commands to your scheduler in `routes/console.php`:

```
Schedule::command('ai-usage:mark-stale-failed')->hourly();
Schedule::command('ai-usage:prune')->daily();
```

Testing
-------

[](#testing)

```
composer test
```

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance97

Actively maintained with recent releases

Popularity16

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 64.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

8

Last Release

16d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/628599896df86349601b75966b4c5029a909c84fe94fb3d0c7006a744f826f92?d=identicon)[SimonMeia](/maintainers/SimonMeia)

![](https://www.gravatar.com/avatar/fdc6e03445e785399b36960d27ab22b0168e15d0478e81d7be162dd712ee6361?d=identicon)[emilevl](/maintainers/emilevl)

---

Top Contributors

[![emilevl](https://avatars.githubusercontent.com/u/17194604?v=4)](https://github.com/emilevl "emilevl (9 commits)")[![SimonMeia](https://avatars.githubusercontent.com/u/92148227?v=4)](https://github.com/SimonMeia "SimonMeia (5 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/backtik-ch-laravel-ai-usage/health.svg)

```
[![Health](https://phpackages.com/badges/backtik-ch-laravel-ai-usage/health.svg)](https://phpackages.com/packages/backtik-ch-laravel-ai-usage)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)[laravel/ai

The official AI SDK for Laravel.

1.1k4.6M341](/packages/laravel-ai)[spatie/laravel-health

Monitor the health of a Laravel application

88412.7M190](/packages/spatie-laravel-health)[mike-bronner/laravel-model-caching

Automatic caching for Eloquent models.

2.4k161.4k2](/packages/mike-bronner-laravel-model-caching)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

265.2k](/packages/aedart-athenaeum)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45844.8k1](/packages/pressbooks-pressbooks)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
