israrminhas / filament-aimonitor
AI API cost monitoring and key management plugin for Filament
Installs: 128
Dependents: 0
Suggesters: 0
Security: 0
Stars: 5
Watchers: 0
Forks: 2
Open Issues: 0
pkg:composer/israrminhas/filament-aimonitor
Requires
- php: ^8.2
- filament/filament: ^4.0
- illuminate/contracts: ^11.0|^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0
- pestphp/pest: ^2.0|^3.0
This package is auto-updated.
Last update: 2026-01-05 23:38:47 UTC
README
A Filament 4 plugin for monitoring AI API usage, costs, and managing API keys across multiple providers (OpenAI, Anthropic, Gemini, Perplexity).
Features
- Track AI API requests with token counts and automatic cost calculation
- Manage API keys for multiple providers with priority-based rotation
- Configure model-specific pricing with fallback support
- Dashboard with usage analytics and cost trends
- Per-user spending tracking and limits
- Multi-tenancy support (works with
tenant()helper)
Requirements
- PHP 8.2+
- Laravel 11+
- Filament 4.0+
Installation
composer require israrminhas/filament-aimonitor
Publish and run migrations:
php artisan vendor:publish --tag="ai-monitor-migrations"
php artisan migrate
Publish config (optional):
php artisan vendor:publish --tag="ai-monitor-config"
Register the Plugin
Add the plugin to your Filament panel in app/Providers/Filament/AdminPanelProvider.php:
use Filament\AiMonitor\AiMonitorPlugin; public function panel(Panel $panel): Panel { return $panel ->plugins([ AiMonitorPlugin::make(), ]); }
Helper Functions
The package provides three global helper functions:
ai_log() - Log AI Requests
// Log any AI request ai_log([ 'provider' => 'openai', 'model' => 'gpt-4o', 'request_type' => 'chat', 'prompt_tokens' => 150, 'completion_tokens' => 50, 'status' => 'success', 'user_id' => auth()->id(), ]);
Cost is automatically calculated from your pricing configuration. The total_tokens and occurred_at are auto-filled if not provided.
ai_key() - Get API Key
// Get the highest priority active API key for a provider $apiKey = ai_key('openai'); $apiKey = ai_key('anthropic'); $apiKey = ai_key('gemini');
ai_cost() - Calculate Cost
// Calculate cost for tokens without logging $cost = ai_cost('openai', 'gpt-4o', 1000, 500); // Returns cost in USD based on your pricing config
Using the Services
AiUsageLogger
use Filament\AiMonitor\Services\AiUsageLogger; $logger = app(AiUsageLogger::class); // Generic log $logger->log([ 'provider' => 'openai', 'model' => 'gpt-4o', 'prompt_tokens' => 100, 'completion_tokens' => 50, 'status' => 'success', 'user_id' => auth()->id(), 'meta' => ['conversation_id' => 123], ]); // Provider-specific shortcuts $logger->logOpenAi([...]); $logger->logAnthropic([...]); $logger->logGemini([...]); $logger->logPerplexity([...]);
AiKeyManager
use Filament\AiMonitor\Services\AiKeyManager; $keyManager = app(AiKeyManager::class); // Get single key (highest priority) $key = $keyManager->getKey('openai'); // Get all active keys for a provider $keys = $keyManager->getAllKeys('openai'); // Check if provider has any active keys if ($keyManager->hasProvider('anthropic')) { // ... }
AiPricingService
use Filament\AiMonitor\Services\AiPricingService; $pricing = app(AiPricingService::class); // Get pricing for a model $rates = $pricing->getPricing('openai', 'gpt-4o'); // Returns: ['input_per_1k' => 0.005, 'output_per_1k' => 0.015] // Check if pricing exists if ($pricing->hasPricing('anthropic', 'claude-3-opus')) { // ... } // Calculate cost $cost = $pricing->calculateCost('openai', 'gpt-4o', 1000, 500); // Get all configured providers $providers = $pricing->getProviders(); // Get models for a provider $models = $pricing->getModelsForProvider('openai');
AiUsageLimitService
use Filament\AiMonitor\Services\AiUsageLimitService; $limitService = app(AiUsageLimitService::class); // Get user's monthly spend $spent = $limitService->getUserMonthlySpend($userId); // Get full limit status $status = $limitService->getUserLimitStatus($user); // Returns: // [ // 'limit' => 100.00, // 'spent' => 45.50, // 'remaining' => 54.50, // 'percent_used' => 45.5, // 'state' => 'ok', // 'ok', 'warning', 'over', 'no-limit' // ]
Usage Examples
OpenAI Integration
use OpenAI\Laravel\Facades\OpenAI; $response = OpenAI::chat()->create([ 'model' => 'gpt-4o', 'messages' => [ ['role' => 'user', 'content' => 'Hello!'], ], ]); // Log the request ai_log([ 'provider' => 'openai', 'model' => $response->model, 'request_type' => 'chat', 'prompt_tokens' => $response->usage->promptTokens, 'completion_tokens' => $response->usage->completionTokens, 'status' => 'success', 'user_id' => auth()->id(), ]);
Anthropic Integration
$response = Http::withHeaders([ 'x-api-key' => ai_key('anthropic'), 'anthropic-version' => '2023-06-01', ])->post('https://api.anthropic.com/v1/messages', [ 'model' => 'claude-3-5-sonnet-20241022', 'max_tokens' => 1024, 'messages' => [['role' => 'user', 'content' => 'Hello!']], ]); $data = $response->json(); ai_log([ 'provider' => 'anthropic', 'model' => $data['model'], 'request_type' => 'chat', 'prompt_tokens' => $data['usage']['input_tokens'], 'completion_tokens' => $data['usage']['output_tokens'], 'status' => $response->successful() ? 'success' : 'failed', 'user_id' => auth()->id(), ]);
With Error Handling
try { $response = OpenAI::chat()->create([...]); ai_log([ 'provider' => 'openai', 'model' => 'gpt-4o', 'prompt_tokens' => $response->usage->promptTokens, 'completion_tokens' => $response->usage->completionTokens, 'status' => 'success', 'user_id' => auth()->id(), ]); } catch (\Exception $e) { ai_log([ 'provider' => 'openai', 'model' => 'gpt-4o', 'prompt_tokens' => 0, 'completion_tokens' => 0, 'status' => 'failed', 'user_id' => auth()->id(), 'meta' => ['error' => $e->getMessage()], ]); }
User Spending Limits
Add Columns to Users Table
php artisan make:migration add_ai_limits_to_users_table
Schema::table('users', function (Blueprint $table) { $table->decimal('ai_monthly_limit_usd', 10, 4)->nullable(); $table->integer('ai_alert_threshold_percent')->default(80); });
Check Limits Before AI Calls
use Filament\AiMonitor\Services\AiUsageLimitService; $limitService = app(AiUsageLimitService::class); $status = $limitService->getUserLimitStatus(auth()->user()); if ($status['state'] === 'over') { throw new \Exception('Monthly AI spending limit reached.'); } if ($status['state'] === 'warning') { // Notify user they're approaching limit }
Multi-Tenancy Support
The package automatically scopes data to the current tenant when tenant() helper is available (e.g., with Filament multi-tenancy or Stancl/Tenancy).
Configuration
// config/ai-monitor.php return [ 'tenant_support' => true, // Enable/disable tenant scoping ];
How It Works
- All models use the
IsTenantScopedtrait - When
tenant()returns a tenant,tenant_idis automatically set on create - Queries are automatically scoped to the current tenant
Dashboard Widgets
The plugin includes these dashboard widgets:
| Widget | Description |
|---|---|
| Stats Overview | Total requests, tokens, cost, success rate |
| Cost & Request Trends | 30-day line chart |
| Cost by Provider | Doughnut chart breakdown |
| Top Models by Cost | Table of most expensive models |
| Usage by User | Table of user spending |
| Recent Requests | Latest API calls with details |
License
MIT License. See LICENSE for details.