vibefilter/filament
Filament integration for VibeFilter, bringing reusable, configurable filters to Filament resources and tables. Build cleaner Laravel admin listings, compose filter sets, and keep query logic organized in one place.
Architecture fit. Vibefilter is a Filament table filter that scores rows against a natural-language statement using an LLM, caches those scores, and then filters on a score threshold. That is a good fit for admin and back-office surfaces already built on Filament (support queues, CRM lists, moderation queues, catalogue triage) where users currently express intent through stacked where-clauses. It is a poor fit for customer-facing high-QPS paths, for anything requiring deterministic/auditable filtering, or for tables where row content cannot leave the application boundary. The v0.3.0 additions tighten the architecture in three useful places: the threshold tuner makes the score semantics inspectable in-product, vibefilter:prune acknowledges that the cache is a durable, growing store rather than a request-scoped artifact, and the OpenRouter attribution config makes the outbound provider relationship explicit rather than implicit.
Integration feasibility. Low-to-moderate. Installation is Composer plus a Filament plugin registration, a published config, and now a migration. v0.3.0's migration (last_used_at) is additive and explicitly non-blocking for existing filtering behaviour — only vibefilter:prune depends on it — which is the right failure ordering. The two upgrade friction points are config drift (previously published configs do not receive the new attribution block, so attribution silently stays off) and the pruning semantics for pre-migration rows, where last_used_at will be NULL unless backfilled.
Technical risk.
last_used_at could remove statements users still rely on. --dry-run must be mandatory in the runbook.HTTP-Referer and X-OpenRouter-Title are now sent by default; if left pointing at the package, usage and any embedded referer detail are credited externally. Trivial to fix, easy to forget.Key questions.
composer.json?vibefilter:prune treat NULL last_used_at as "old"? Is there a backfill or a safeguard?Stack fit. Native for Laravel + Filament shops; no separate infrastructure beyond a queue/HTTP client and the provider API key. The cache is a normal database table, so it inherits existing backup, retention, and access-control policy — a real advantage over an external vector store. Teams without Filament get little value; teams with it get a contained, single-table-scoped feature.
Migration path. Upgrade is two commands (vendor:publish --tag="vibefilter-migrations", migrate), and filtering continues to work if the migration is delayed, which makes this a safe, reversible-by-omission step. The one required manual action is merging the new attribution block into any previously published config; treat this as a tracked checklist item, not a note in release text. Before deploying, confirm whether existing cache rows need a last_used_at backfill so the first prune run is not destructive.
Compatibility. Additive schema change, no breaking API changes called out. Verify PHP/Laravel/Filament version constraints against our application matrix, and pin the package version in composer.json for the duration of the pilot. Config-file divergence is the main compatibility hazard across future releases; consider tracking the package config in version control with a diff review step on each upgrade.
Sequencing.
attribution; run vibefilter:prune --dry-run and inspect output before enabling the schedule.->thresholdTuner() in staging only, use it to choose per-table default thresholds, then disable it for production surfaces.vibefilter:prune --days=90 daily and add alerting on cache table size.Maintenance. Modest but non-zero: a daily prune job, a pinned version with a review step per upgrade, config diffing on each release, and periodic re-tuning of thresholds whenever the model, driver, or prompt changes. The last_used_at column adds write traffic on every filter use — negligible at admin-scale, worth checking if statements are shared broadly.
Support. Expect two classes of tickets: "the AI filter returns nothing" (usually threshold too high, provider error, or unscored rows) and "the filter forgot my saved query" (pruning, or a statement that aged out). The threshold tuner is the primary deflection tool — it lets a support engineer or power user see row counts per threshold without a model call, which converts a vague complaint into a self-service fix. Publish an internal one-pager on what the threshold means and that it is not a relevance guarantee.
Scaling. Scales well on read (cached scores are a plain indexed query); scaling pressure is concentrated in (a) initial scoring of large tables, which is token-bound and should be queued/batched, (b) cache table growth proportional to statements × rows, and (c) provider rate limits under concurrent use. Budget the provider spend explicitly and attribute it to the feature owner. OpenRouter attribution headers are irrelevant to scaling but relevant to cost visibility — point them at our app so usage is traceable in provider dashboards.
Failure modes.
vibefilter:prune fails; harmless to filtering but silent if the schedule swallows output.--dry-run.Ramp-up. A Laravel developer can complete the staging spike in one to three days. TPM-side effort is roughly a week of elapsed time: egress review, pilot scoping, cost/latency measurement, and a decision memo on eligible tables and default thresholds. Because the package is pre-1.0, position this as a bounded pilot on internal tooling with an explicit exit criterion (cost per query and empty-result rate within agreed bounds) before expanding to any user-facing or regulated data surface.
How can I help you explore Laravel packages today?