opscale-co / nova-genbi
Generative BI for Laravel Nova: chat with an AI that reads your database schema, writes read-only SQL, and builds native Nova dashboards and streamed exportable reports
Requires
- php: ^8.3
- butschster/dbml-parser: ^0.3
- laravel/ai: ^0.9.0
- openspout/openspout: ^4.24
- opscale-co/actions: ^5.0
- opscale-co/nova-package-tools: ^2.0
- opscale-co/validations: ^2.0
Requires (Dev)
- driftingly/rector-laravel: ^2.0
- larastan/larastan: ^3.9
- laravel/nova: ^5.10
- laravel/nova-devtool: ^1.0
- mockery/mockery: ^1.6
- opscale-co/strict-rules: ^1.3
- orchestra/testbench-dusk: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpunit/phpunit: ^12.0
- rector/rector: ^2.0
- tightenco/duster: ^3.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Generative BI for Laravel Nova. Chat with an AI that reads your database schema, writes read-only SQL, and builds:
- Dashboards — native Nova metric cards (Value, Trend, Partition, Progress, Table) generated from the metrics the assistant proposes.
- Reports — parametrized SQL templates you run and export to Excel / CSV (streamed with OpenSpout, memory-bounded over millions of rows).
The chat UI is built with the Vercel AI SDK (@ai-sdk/vue) and streams over the
UI Message Stream v1 protocol produced by laravel/ai.
How it works
- You open the Gen BI tool page and ask for a report or a metric in natural language.
- The agent is given your schema as DBML (via a
DomainResolver) and writes SQL. - It can preview a query with the
runQuerytool (read-only, auto-limited) to validate it. - It proposes a report or a metric as a streamed tool call; you review the SQL and Accept & save or Discard. Nothing is written until you accept.
- Accepted reports become
ReportTemplaterecords (run + export via Nova actions); accepted metrics become native cards on a Gen BI dashboard.
Every piece of AI-generated SQL passes the ReadOnlySqlGuard before it ever runs:
a single SELECT/WITH statement, no stacked statements, no DDL/DML keywords. Point
nova-genbi.connection at a least-privileged read-only database user in production.
Requirements
- PHP 8.3+, Laravel Nova 5.7+
laravel/ai ^0.9with a configured provider (OpenAI, Anthropic, …)
Protocol pin: keep
laravel/ai ^0.9↔@ai-sdk/vue 4.0.x/ai 7.0.xtogether; they share UI Message Stream v1. Bump both sides at once.
Installation
composer require opscale-co/nova-genbi php artisan vendor:publish --tag=nova-genbi-config
laravel/ai publishes its own migrations (conversation memory) — publish and migrate them too:
php artisan vendor:publish --tag=laravel-ai-migrations php artisan migrate
Set your AI provider credentials (e.g. OPENAI_API_KEY) and optionally:
NOVA_GENBI_AI_PROVIDER=anthropic NOVA_GENBI_AI_MODEL=claude-sonnet-5 NOVA_GENBI_CONNECTION=reporting_readonly
Register the tool in app/Providers/NovaServiceProvider.php:
public function tools(): array { return [new \Opscale\NovaGenbi\Tool\GenBI]; }
Schema context (required for good SQL)
The agent only writes SQL for the tables you describe. Bind a DomainResolver
that returns your domain as DBML:
use Opscale\NovaGenbi\Contracts\DomainResolver; $this->app->singleton(DomainResolver::class, MyDomainResolver::class);
final class MyDomainResolver implements DomainResolver { public function resolve(): string { return <<<'DBML' Table orders { id integer [primary key] customer_id integer [note: 'FK to customers.id'] total decimal [note: 'Order total in cents.'] created_at timestamp [note: 'When the order was placed.'] Note: 'One row per placed order.' } DBML; } }
Rich table/column notes matter: they carry the business meaning the model needs.
Without a resolver, the default reads the nova-genbi.schema config value.
Development
composer install npm install && npm run prod # compile the Vue chat bundle composer build # build the demo workbench Nova app (migrations + seed) composer serve # http://127.0.0.1:8000/nova (admin@laravel.com / password) composer test # Pest unit + feature tests
The workbench ships a demo DomainResolver, a seeded report template, and two metrics
on an "Overview" dashboard.
License
MIT