ferarandrei1/filament-ai-chat-widget
Installation:
composer require ferarandrei1/filament-ai-chat-widget
php artisan vendor:publish --tag="filament-ai-chat-widget-migrations"
php artisan migrate
Add OpenAI credentials to .env:
OPENAI_API_KEY=your_key_here
OPENAI_ORGANIZATION=your_org
Register Plugin:
In your PanelProvider, add:
->plugins([
FilamentAiChatPlugin::make(),
])
->resources([
AiKnowledgeBaseResource::class,
])
Clear Caches:
php artisan optimize:clear
First Use Case:
gpt-4o-mini).config/filament-ai-chat-widget.php:
'widget' => [
'position' => 'right', // 'left' or 'right'
'width' => '350px',
'height' => '600px',
],
use Feraandrei1\FilamentAiChatWidget\Facades\AiChat;
// In a ServiceProvider or Resource class
AiChat::ask('User created: ' . $user->name . '. Suggest next steps.');
AiKnowledgeBaseResource to add context-specific entries (e.g., internal policies, FAQs). Example entry:
// Via Tinker or a Seeder
\Feraandrei1\FilamentAiChatWidget\Models\AiKnowledgeBase::create([
'title' => 'Filament User Roles',
'content' => 'Admins can manage all users. Editors can only edit their own content.',
'is_active' => true,
]);
config/filament-ai-chat-widget/mcp/ to enforce guidelines. Example (guidelines.md):
# Filament AI Guidelines
- Never suggest disabling security features like 2FA.
- Always reference the knowledge base for Filament-specific questions.
AiChat::ask('Explain this code:', $codeSnippet, [
'context' => ['model' => 'gpt-4', 'temperature' => 0.3],
]);
'chat_history_limit' => 50, // Max conversations per user
AiChat facade:
$deletedChat = AiChat::restoreConversation($id);
AiChat facade:
$usage = AiChat::getLastUsage();
// Returns: ['prompt_tokens' => 100, 'completion_tokens' => 200, 'total' => 300]
events to trigger alerts when usage exceeds thresholds:
// In EventServiceProvider
AiChat::onTokenLimitExceeded(function ($tokens) {
Log::warning("AI token limit exceeded: {$tokens}");
// Send Slack/email alert
});
Resource-Specific AI: Extend the widget to show resource-specific help. Example: Add a getAiHelp() method to a resource:
public static function getAiHelp(): string {
return "This resource manages " . static::getModelLabel() . ". Use the bulk actions to export data.";
}
Then pass this to the AI:
AiChat::ask('How do I use this page?', null, [
'context' => ['resource_help' => Post::getAiHelp()],
]);
Permissions: Restrict access to the chat widget or knowledge base via Filament’s gate system:
FilamentAiChatPlugin::make()->middleware([
\Feraandrei1\FilamentAiChatWidget\Middleware\RequireAdmin::class,
]);
'default_model' => 'gpt-4',
AiChat::ask('Write a test case for this:', $code, [
'parameters' => ['temperature' => 0.1, 'max_tokens' => 100],
]);
php artisan vendor:publish --tag="filament-ai-chat-widget-assets"
Then modify resources/views/vendor/filament-ai-chat-widget/....'messages' => [
'chat_placeholder' => 'Ask about Filament or your workflow...',
],
queue:work to process AI responses asynchronously:
AiChat::ask('Generate a report', null, [
'callback' => function ($response) {
Report::generate($response);
},
]);
AiKnowledgeBase model:
class TenantAiKnowledgeBase extends AiKnowledgeBase {
public function scopeForTenant($query, $tenantId) {
return $query->where('tenant_id', $tenantId);
}
}
OpenAI API Limits:
AiChat calls:
try {
AiChat::ask('...');
} catch (\GuzzleHttp\Exception\RequestException $e) {
if (str_contains($e->getMessage(), 'rate limit')) {
sleep(10); // Retry after 10 seconds
AiChat::ask('...'); // Retry
}
}
Knowledge Base Bloat:
// app/Console/Commands/ArchiveKnowledgeBase.php
public function handle() {
AiKnowledgeBase::where('is_active', false)
->where('updated_at', '<', now()->subDays(30))
->update(['is_archived' => true]);
}
MCP Misconfiguration:
public function handle($request, Closure $next) {
if (!file_exists(config('filament-ai-chat-widget.mcp_path') . '/guidelines.md')) {
throw new \Exception('MCP guidelines file missing!');
}
return $next($request);
}
Conversation History Growth:
'chat_history_limit' => 20, // Hard cap
Add a model observer to auto-delete:
AiChat::observe(function ($model) {
if ($model->conversations()->count() > config('filament-ai-chat-widget.chat_history_limit')) {
$model->conversations()->oldest()->delete();
}
});
Filament Caching:
How can I help you explore Laravel packages today?