hayderhatem/filament-natural-language-filter
A Filament plugin that lets users filter tables with natural-language queries. It translates plain-English requests into structured filters, making complex data tables easier to search without building manual filter forms. Useful for admin panels and dashboards.
The package turns a free-text search box into Filament table filters, so users can type things like "active users created last week" instead of clicking through filter dropdowns.
Minimal setup:
composer require hayderhatem/filament-natural-language-filter
php artisan vendor:publish --tag="filament-natural-language-filter-config"
config/filament-natural-language-filter.php. Expect fields for provider/model/API key; source the key from env() (e.g. OPENAI_API_KEY) rather than hardcoding.table() method — typically a ->filters([...]) entry or a header action/search component. Check src/ for the actual Filament component/action class name, since README coverage is thin at 13 stars.Look here first, in order:
README.md — install + usage snippet (short).config/filament-natural-language-filter.php — reveals provider, model, prompt, and allowed-column config.src/ — the Filament filter/action class and the prompt-building logic; this is where you'll debug.First use case: add it to one low-risk resource (e.g. OrderResource or UserResource) alongside your existing filters. Try a query, inspect storage/logs/laravel.log, and confirm the generated filter array matches what your table expects before rolling it out panel-wide.
Drop-in on a table. The dominant pattern is instantiating the filter inside table():
->filters([
\HayderHatem\NaturalLanguageFilter\...::make(),
// existing filters...
])
The exact namespace/class depends on the release — copy from the README or src/.
Coexist with manual filters. Don't replace your SelectFilter/DateFilters. Keep them so users have a deterministic fallback when the LLM misparses. The NL filter is an accelerant, not a replacement.
Scope the vocabulary. Most implementations rely on a schema describing filterable columns and their operators. Review the config's column whitelist and restrict it to columns that actually have filters defined; unconstrained prompts produce filters Filament silently ignores.
Resource-level vs panel-level. Prefer applying per-resource so you can tune allowed columns per model (a TeamResource and InvoiceResource need very different vocab). Avoid a global enable until you've validated a couple of resources.
Prompt/schema customization. If the config exposes the system prompt or a "filter map", treat it as code: version it in config, test representative phrasings ("last 7 days", "bigger than 100", "status is pending"), and iterate.
Chaining with the table query. If the package exposes a generated query array, you can also call it from a custom header action or Livewire method — useful for building "saved NL searches" or dashboards that accept a text query string.
Testing workflow. Write a Pest/PHPUnit test that feeds fixed phrases into the prompt-builder (not the live API) and asserts the resulting filter array. Mock the LLM client so CI doesn't depend on a paid endpoint.
wire:model.live without debounce — or you'll burn API tokens.temperature: 0 if configurable, and always show the user which filters were applied (a "chips" or applied-filter display) so surprises are visible.customer.name) or nonexistent columns are silently dropped by Filament. Log the raw model output during development.$this->tableFilters after submission. Most "it doesn't work" reports are malformed JSON or wrong filter key names.src/ before production, pin the version in composer.json, and be prepared to fork if the maintainer goes quiet.How can I help you explore Laravel packages today?