Download the PHP package sanjayacloud/ai-model-usage-tracker without Composer
On this page you can find all versions of the php package sanjayacloud/ai-model-usage-tracker. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download sanjayacloud/ai-model-usage-tracker
More information about sanjayacloud/ai-model-usage-tracker
Files in sanjayacloud/ai-model-usage-tracker
Package ai-model-usage-tracker
Short Description Accurately track AI model usage, tokens, and cost in Laravel with automatic instrumentation, reporting, and a Blade dashboard.
License MIT
Homepage https://github.com/sanjayacloud/ai-model-usage-tracker
Informations about the package ai-model-usage-tracker
AI Model Usage Tracker
Accurately track AI model usage in your Laravel app: token counts, computed cost, latency, success/failure, per-user attribution, and per-conversation attribution. Capture usage automatically from the first-party laravel/ai SDK (plus Prism and raw HTTP clients), or record it manually with a fluent API. Includes a headless reporting layer, budget alerts, auto-fetched pricing, and a dashboard that can sit inside the official Laravel Vue, React, or Livewire starter kits.
Features
- Automatic capture for the
laravel/aiSDK — no code changes required. - Computed cost from a configurable per-model pricing table (input, output, cache read/write, reasoning, per-image, per-second).
- Prefix matching so dated model ids (
gpt-4o-2024-11-20) resolve to catalog rates. - Auto-fetched pricing from LiteLLM (OpenRouter fallback) via
ai-usage:fetch-pricing— never on the request path. - Per-request, per-user, per-conversation, and feature-key attribution.
- Reporting API — totals, breakdowns by model/provider/operation, daily trends, top consumers.
- Budgets with threshold events, retention pruning, and a dashboard (Blade by default; Vue / React / Livewire starter-kit shells optional).
- Sync or queued persistence.
Requirements
- PHP 8.3+
- Laravel 12 or 13
- (Optional)
laravel/aifor automatic instrumentation - (Optional) Inertia + Vue or React, or the Livewire starter kit, to embed the dashboard in the app layout
How it works
Every AI request becomes one row in the ai_usage_records table, written through a single pipeline regardless of how it was captured:
Getting started
Step 1 — Install
The service provider and AiModelUsageTracker facade are auto-discovered (UsageTracker is an alias).
Step 2 — Run the migration
Package migrations load automatically. Publishing them is optional — do not vendor:publish --force later or you will duplicate the create-table migration.
Step 3 — Publish the config (recommended)
This writes config/ai-model-usage-tracker.php, where you control pricing, recording mode, instrumentation, budgets, retention, and the dashboard.
Step 4 — Capture your first usage
If you use laravel/ai, you're already done — the next agent prompt or embedding call is recorded automatically (see Automatic capture).
To record manually from anywhere:
Step 5 — Read it back
That's the full loop: capture → cost → report.
Upgrading from 1.0
Then schedule catalog refresh and reprice any rows that were recorded at $0:
If you already published migrations in 1.0, do not republish with --force. Package migrations load automatically and skip work when the table or columns already exist (so a second create will not fail). The new feature_key column is added on php artisan migrate.
The dashboard now defaults to Blade. Set AI_USAGE_DASHBOARD_DRIVER=inertia only if you already published the Vue page.
Capturing usage
Automatic capture (laravel/ai)
Enabled by default. The package listens to the SDK's events (AgentPrompted, AgentStreamed, EmbeddingsGenerated, ImageGenerated, AudioGenerated, TranscriptionGenerated, ProviderFailedOver) and records tokens, model, provider, latency, failures — and the conversation id when the call is part of a laravel/ai conversation.
Toggle it in config:
Manual API (fluent builder)
Available builder methods: provider(), model(), operation(), tokens(), latency(), status(), failed(), streamed(), for(), conversation(), feature(), invocation(), meta(), startedAt(), endedAt(), record().
Prism
Enable it in config (instrumentation.prism => true).
Raw HTTP clients
Set instrumentation.http => true to parse OpenAI/Anthropic-style usage blocks from outgoing HTTP responses automatically.
Attribution
Per-user (or any model)
Use for() on the manual builder, or set a global resolver so every recorded row is attributed automatically (great for auto-instrumentation):
Per-conversation
When you use laravel/ai conversations, the conversation id is captured automatically on each recorded row (conversation_id). You can then aggregate usage for a single conversation:
For manual records, pass the id explicitly with ->conversation($conversationId).
Per-request usage in your responses
Each request is recorded individually, so you can surface its cost inline:
$record->toUsageArray() returns a compact block of tokens, cost, currency, and latency.
Cost accuracy
Costs are computed from pricing.models in config, then from a fetched catalog if you run ai-usage:fetch-pricing. Bundled rates cover common OpenAI, Anthropic, and Gemini models, expressed per 1,000,000 tokens. Dated model ids match the longest catalog prefix (gpt-4o-2024-11-20 → gpt-4o). Provider prefixes like google/gemini-3.1-flash-lite are stripped.
Requests for models not in config or the catalog are recorded with a zero cost, a
pricing_missingflag inmetadata, and a warning log so gaps are auditable.
Published config always wins over fetched rates (use it for negotiated prices).
How cost is calculated
Each record stores input_cost, output_cost, and total_cost (input_cost + output_cost), rounded to 8 decimal places.
Prompt tokens are split so cache usage is not billed twice. Cache-read tokens are capped at prompt tokens; cache-write tokens are capped at the remainder; regular input is whatever is left:
Reasoning tokens are billed in addition to completion tokens (they are not subtracted from completion the way cache tokens are subtracted from prompt). If the catalog omits cache_write / cache_read, those fall back to input; omitted reasoning falls back to output.
Image and duration extras are added to input cost:
- Images:
metadata.images, ormetadata.n. Image operations default to 1 when neither is set; other operations default to 0. - Duration:
metadata.seconds, ormetadata.duration(seconds).
Auto-fetch (LiteLLM, then OpenRouter)
Fetch does not run during record(). Refresh the catalog on a schedule:
Disable with AI_USAGE_FETCH_PRICING=false. --force bypasses the cache TTL (default 24 hours).
Adding pricing for a model
If a model shows $0 cost, either fetch the catalog, or add an override:
Then reprice historical rows:
Supported rate keys: input, output, cache_write, cache_read, reasoning, per_image, per_second. See How cost is calculated for fallbacks and the formula.
Reporting
Every method except forConversation() accepts optional $from/$to DateTimeInterface bounds.
CLI summary:
Budgets
Define spending caps in config; a BudgetThresholdReached event fires the moment a threshold is crossed:
Listen for the event to send alerts:
Recording mode
Set recording.mode to sync (default, always exact) or queue to offload writes to a job for high-throughput apps:
Retention
Set retention_days in config and schedule the command in routes/console.php (or app/Console/Kernel.php):
Dashboard
/ai-usage is enabled by default. Define the gate:
Laravel starter kits (Vue, React, Livewire)
If the app was created with an official Laravel starter kit, install the dashboard into that shell so it uses the same sidebar / header as /dashboard:
That command will:
- Detect vue, react, or livewire from the kit’s layout files (or pass
--kit=). - Publish
resources/js/pages/AiUsage/Dashboard.vueor.tsxfor Inertia kits. - Add an AI Usage item to the starter-kit sidebar (or header). Skip with
--no-nav.
Then set the driver / layout to match the kit and rebuild assets for Inertia:
| Kit | Driver | What you get |
|---|---|---|
| Vue starter kit | inertia |
Inertia page inside AppLayout + sidebar item |
| React starter kit | inertia |
Same, with the published .tsx page |
| Livewire starter kit | blade + layout=starter-kit |
Blade view inside <x-layouts.app> + Flux sidebar item |
| No kit | blade (default) |
Standalone HTML at /ai-usage |
dashboard.driver=auto picks Inertia when a Vue/React kit is detected. dashboard.layout=auto uses the Livewire/Breeze app layout when that component exists, otherwise the standalone page.
Inertia kits also receive a shared aiUsageNavigation prop (visible, url, label, icon) so a custom sidebar can do:
Turn the shared item off with dashboard.navigation.enabled / AI_USAGE_DASHBOARD_NAV=false.
Publish pages without the install command:
Adjust dashboard.path and dashboard.middleware as needed (auth is recommended for starter-kit apps).
Testing
This runs static analysis (PHPStan/Larastan), code style (Pint), 100% type coverage, and the Pest test suite.
Changelog
Please see CHANGELOG for more information on what has changed recently.
When cutting a GitHub Release, paste that version’s notes only — not the whole changelog file (the updater action would nest Unreleased into the previous release).
License
AI Model Usage Tracker is open-sourced software licensed under the MIT license.