Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Model Ai Laravel Package

postare/filament-model-ai

Postare Filament Model AI integrates AI-powered generation into Laravel Filament admin panels for Eloquent models. Add AI actions to resources so admins can create and improve content without leaving the panel, with configurable providers and prompts to fit your workflow.

View on GitHub
Deep Wiki
Context7

Getting Started

Add the package and its config in one pass:

composer require postare/filament-model-ai
php artisan vendor:publish --tag="filament-model-ai-config"

Then set the provider credentials in .env (the package config reads them, so don't hardcode keys in config/):

OPENAI_API_KEY=sk-...
OPENAI_ORGANIZATION=          # optional

Register the plugin on the panel you actually want the assistant on — not every panel:

// app/Providers/Filament/AdminPanelProvider.php
public function panel(Panel $panel): Panel
{
    return $panel
        ->plugin(\Postare\FilamentModelAi\FilamentModelAiPlugin::make());
}

Where to look first, in this order:

  1. config/filament-model-ai.php — this is the whole package. Read it before writing any code; the model/driver settings, context limits, and the list of Eloquent models exposed as "knowledge" all live here.
  2. The model trait (typically HasAi / InteractsWithAi) — you add it to the models you want the assistant to reason over.
  3. The published migration — chats and messages are persisted, so you need php artisan migrate.

A minimal working model:

use Postare\FilamentModelAi\Concerns\HasAi;      // verify exact namespace in README

class Product extends Model
{
    use HasAi;
}

First use case to validate end-to-end: open a Product record in the admin, ask the assistant "summarise this product's pricing history" and confirm it (a) answers, (b) only sees that record, (c) persists the conversation. If any of those three fail, stop and fix before rolling out to more models — the failure modes compound.

Implementation Patterns

Scope knowledge per model, not globally. The tempting mistake is to register ten models and let the assistant loose. Instead, attach the AI affordance to the resource where it's useful and let the trait define what's exposed:

class Product extends Model
{
    use HasAi;

    public function aiContext(): array
    {
        return [
            'name'        => $this->name,
            'price'       => $this->price,
            'category'    => $this->category?->name,
            'recent_orders_count' => $this->orders()->where('created_at', '>=', now()->subMonth())->count(),
        ];
    }
}

Returning a curated array beats dumping $this->toArray() — it keeps token usage predictable and stops accidental leakage of internal columns.

Treat the system prompt as application code. Put it in the config (or a dedicated prompts/ folder and reference a translation key), not inline in a resource. You want it version-controlled, diffable, and testable.

Gate it with policies. An AI panel is a data-access surface. Anything the assistant can read, the user can effectively read. Add an explicit ability and check it before rendering the chat:

public function useAi(User $user): bool
{
    return $user->hasPermissionTo('view products') && $user->is_staff;
}

Stream when the answer is long. For summarisation or "explain this customer's churn risk" prompts, streaming avoids 10–20 second blank screens. If the package exposes a streaming flag, use it on record pages and keep non-streaming for background/bulk use.

Queue anything that isn't interactive. Bulk actions over many records ("classify these 200 tickets") should dispatch a job that calls the same underlying service and writes results back to a column, rather than looping inside a Filament action and hitting timeout.

Keep a thin service layer. Wrap calls in app/Services/AiAssistant.php so your Filament resources and console commands share one entry point. This is your extension point when you outgrow the package defaults or want to swap providers.

Seed conversations for evaluation. Persisted chats are free regression fixtures: record a handful of representative prompts per model, and re-run them after changing the prompt or the context array.

Gotchas and Tips

  • Token blowups from relations. Eager-loading is easy to forget; a lazy $this->orders inside aiContext() on a model with thousands of rows is both an N+1 and a context-window overflow. Always ->limit() and ->select() in the context builder.
  • Prompt injection through user data. Any field a customer can edit (support ticket body, product description) is untrusted input reaching the model. Wrap user-supplied text in delimiters, instruct the model to treat it as data, and never let model output trigger a write without human confirmation.
  • Config caching. php artisan config:cache in deploy captures the key at build time. If you inject the key via a runtime secret, read it through env() only in config/ and clear/re-warm the cache in your deploy script — otherwise you get "invalid API key" in production but not locally.
  • Migration order. Publish and run migrations before enabling the plugin, or the panel throws on boot when it tries to resolve the chat table.
  • Cost visibility. The package will happily make one request per message. Add a rate limit per user (RateLimiter::for('ai')) and log token usage per call; a runaway loop in a Livewire component can quietly burn budget.
  • Testing. Use Http::fake() in Pest/PHPUnit rather than mocking internals — assert your prompt content and context array, not the HTTP client. This keeps tests stable across package minor versions.
  • Version pinning. Twenty stars means an active-but-small surface with breaking changes plausible between minors. Pin to ^1.0 (or the exact minor), read the changelog before upgrading, and write a small integration test that opens the chat page so an upgrade failure is loud rather than silent.
  • Multi-tenancy. If you use Filament tenancy, verify the chat records carry tenant_id and that the assistant can't pull context across tenants; the context builder must respect the current tenant scope explicitly.
  • Localisation and tone. Put the assistant's language instruction in the system prompt derived from app()->getLocale(), otherwise a Dutch admin user gets English answers over Dutch data.
  • Debugging empty answers. Nine times out of ten it's one of: missing trait, aiContext() returning an empty array, or a policy returning false. Log the assembled payload at debug level before blaming the model.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager