likeabas/filament-chatgpt-agent
Integrate a ChatGPT-powered agent directly into your Filament admin panels. This Laravel package adds an AI assistant that can answer questions and act on your data, giving you quick, natural-language access to your resources without leaving the dashboard.
1. Install and publish
composer require likeabas/filament-chatgpt-agent
php artisan vendor:publish --provider="Likeabas\FilamentChatgptAgent\FilamentChatgptAgentServiceProvider"
Publish only what exists — run php artisan vendor:publish without arguments first and look for the package's tags (typically a config tag and possibly migrations/views). At 26 stars and zero dependents, read the published config top to bottom before you rely on any default; that file is your real documentation.
2. Wire up credentials
The plugin talks to OpenAI server-side, so the key belongs in .env, never in a Filament form or front-end:
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4o-mini
Confirm the exact env keys against the config file — small plugins frequently hardcode OPENAI_API_KEY via the official openai-php/laravel client rather than defining their own.
3. Register the plugin on a panel
In your PanelProvider:
use Likeabas\FilamentChatgptAgent\FilamentChatgptAgentPlugin; // verify namespace in vendor/
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
FilamentChatgptAgentPlugin::make(),
]);
}
Then php artisan filament:assets && php artisan optimize:clear and log into /admin. The plugin should surface as a page (usually under a navigation group) or as an action/widget depending on how it's registered.
4. First use case
Start with the lowest-risk, highest-value one: an internal chat page for your own team — drafting admin copy, rewriting product descriptions, summarizing a support ticket — before you let it touch persisted data. Get a single prompt round-tripping end to end, then decide whether it earns a place in a resource form or table action.
Where to look first
config/filament-chatgpt-agent.php — model, temperature, token caps, auth gate, navigation.src/ — it's a small package; you can read the whole plugin in 15 minutes, and you should before shipping it.README for the exact plugin class name and any canAccess() hook.Separate panels, separate behavior. If you run an admin panel and a customer-facing panel, register the plugin only where it belongs, or gate it:
FilamentChatgptAgentPlugin::make()
->navigationGroup('AI Tools')
->visible(fn () => auth()->user()?->can('use-ai')),
Most Filament plugins expose canAccess()/visible() or a config-level gate. Pick one and make it a policy, not an is_admin flag scattered across the app.
Treat the chat page as a scratchpad, not a workflow. The packaged UI is good for exploration and prompt iteration. Real workflows usually want a narrower surface:
// A resource header action that drafts a summary into a form field
Textarea::make('summary')
->suffixAction(
Action::make('draft')
->icon('heroicon-o-sparkles')
->action(fn (Set $set, $record) => $set(
'summary',
app(OpenAiService::class)->summarize($record->body)
))
),
If the plugin doesn't expose a service you can inject, call the OpenAI client directly in your own action and use the plugin purely as the authenticated playground. Don't contort the chat page into a batch processor.
Centralize the prompt, not the call sites. Keep system prompts in config or a dedicated class so you can tune them without redeploying every action:
// config/filament-chatgpt-agent.php
'system_prompt' => env('AI_SYSTEM_PROMPT', 'You are an assistant for Acme internal staff.'),
'temperature' => 0.3,
'max_tokens' => 800,
Queue anything user-facing that could take more than a few seconds. Livewire requests have a hard timeout; long generations will 504 in the browser while the OpenAI call succeeds and bills you. For anything beyond a short completion, dispatch a job, store the result, and poll or notify.
Throttle per user. Wrap calls behind a rate limiter keyed on the user, independent of OpenAI's own limits — an authenticated admin panel with no throttle is an open wallet:
RateLimiter::attempt("ai:{$user->id}", 20, fn () => $call, 3600);
Mock it in tests. The package ultimately makes HTTP calls; point the OpenAI base URI at a fixture or use Http::fake() so CI never touches the real API and never needs a key.
Class and config names must be verified, not assumed. With a package this small, the README may lag the code. Run php artisan about or grep vendor/likeabas/filament-chatgpt-agent/src for the plugin class and config keys before pasting any snippet from a blog post (including this one).
Zero dependents is a signal, not a disqualifier. It means the package hasn't been battle-tested across many Filament versions. Pin the version in composer.json, read the source once, and be prepared to fork — it's small enough that forking is cheap. Check the release history against your Filament major version; a 2026 release implies Filament v3+ but confirm.
Key leakage is the number-one failure mode. If the plugin is registered on a panel that guests can reach, or if any prompt/config value gets serialized to the front-end, you've published your key. Verify the page returns 403 for a logged-out request before you announce the feature.
Watch the navigation. Plugins registered in PanelProvider inject navigation items into that panel. If you register in a shared provider, the item appears everywhere — including panels where the user has no business seeing an AI chat.
Model names rot. gpt-3.5-turbo and even gpt-4 get deprecated on OpenAI's schedule. Keep the model in env/config so a deprecation is a config change, not a deploy. Handle model_not_found explicitly and surface a readable error rather than a stack trace in the Livewire component.
Handle 429 and quota errors as first-class UI states. Insufficient quota, rate limits, and context-length overflow are normal operating conditions. Catch them, show a Filament notification, and log the response body — the default exception path is usually unhelpful and leaks nothing useful to the developer.
Data governance is on you, not the package. Whatever the plugin sends — chat text, and any context you pipe in from records — leaves your infrastructure. Before wiring it to real customer data, decide what's allowed to leave, strip PII where required, and confirm your OpenAI data-processing terms cover the use case. The plugin has no opinion on this and neither will your DPO.
Extension points to reach for before forking: the published config (model, temperature, tokens, system prompt), the panel-level visibility/auth hook, and view overrides if the chat UI ships publishable Blade. Only reach into vendor/ source after those three are exhausted — overriding a vendor class you don't control is how you end up maintaining a fork you never wanted.
How can I help you explore Laravel packages today?