Download the PHP package jake142/querai without Composer
On this page you can find all versions of the php package jake142/querai. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package querai
Querai
Let anyone on your team ask your database questions in plain language — safely.
Querai is a Laravel package that turns natural language into read-only SQL, runs it against your database, and returns answers a human can actually use. No SQL client, no BI tool, no ad-hoc queries in production.
What you can use it for
- Admin & support — "How many orders did customer X place last month?" without pinging a developer.
- Internal analytics — quick counts, lists, and breakdowns from real data, not exports.
- Multi-tenant SaaS — one isolated client per customer DB, with its own AI config and domain hints.
- Embedded in your app — use the facade in controllers, jobs, or the built-in chat UI behind your existing auth.
Why Querai
- Safe by default — only
SELECT, blocked DDL/DML, row limits, optional table exclusions. - Your schema, your rules — domain hints in config teach the AI how your tables relate.
- Production-ready — retries on bad SQL, paginated answers for large result sets, conversation context.
- Provider-agnostic — OpenAI, Azure OpenAI, Gemini, or Anthropic.
Ask in Swedish, English, or any language — answers follow the question.
MIT licensed.
How it works
If the SQL fails, Querai sends the error back to the AI and retries (configurable).
Without domain hints, the AI only sees table/column names and will often guess wrong JOINs (e.g. linking orders to the wrong user_id). Hints in config/querai.php tell it how your app actually works.
Requirements
- PHP 8.2+
- Laravel 11 or 12
- A database connection Laravel already uses
- An AI API key (OpenAI, Azure OpenAI, Gemini, or Anthropic)
Installation
Publish config:
Configure domain hints in config/querai.php — this is the most important step for accurate SQL:
Write short, factual rules: entity lookups, how tables relate, business terms, and tables to avoid. Paste a working SQL query from your app if a join is non-obvious.
Add to .env:
Extract and cache your schema once (recommended after migrations):
Usage
Facade / client
Conversation context
Pass the same conversation_id across calls to keep follow-up context (cached, TTL configurable):
Large results — continue / load more
When a query returns more rows than response.threshold (default 15), the full result set is cached and the answer is split into pages.
Response fields:
| Field | Description |
|---|---|
response_id |
Use with continue() while has_more is true |
has_more |
More pages available |
page / total_pages |
Current page of the formatted answer |
UI: a Load more button appears automatically when has_more is true.
Controller / API
Domain hints
Hints are sent to the AI on every question, together with a compact schema. They prevent wrong guesses when column names are ambiguous (e.g. users vs customers, or several foreign keys to the same table).
What to include
| Topic | Example hint |
|---|---|
| Lookups | find a customer by users.email |
| Relationships | orders.user_id → users.id |
| Business terms | "sale" = orders row with status = 'completed' |
| Anti-patterns | do not use legacy_orders — data lives in orders |
What to avoid
- Long prose or full API docs — keep under
hints.max_chars(default 8000) - Secrets or PII in hints
Per-tenant (different DB + hints per customer):
After changing hints: php artisan config:clear. No need to re-run querai:schema.
Isolated clients (multi-tenant / per-customer DB)
The default facade uses config/querai.php (one DB + one AI setup). For apps where each customer has their own database, build a dedicated client per tenant:
Use an existing Laravel connection (if you already register tenant connections in your app):
Store the client on a service, request attribute, or resolve per request — each instance only talks to its DB and its AI config. Cache keys are namespaced so tenants never share conversation or paginated results.
Optional per-tenant overrides:
AI providers
Set QUERAI_AI_PROVIDER to one of: openai, azure, gemini, anthropic.
| Provider | Env vars |
|---|---|
| OpenAI | OPENAI_API_KEY, optional QUERAI_OPENAI_MODEL, OPENAI_BASE_URL |
| Azure | AZURE_OPENAI_API_KEY, AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_DEPLOYMENT |
| Gemini | GEMINI_API_KEY, optional QUERAI_GEMINI_MODEL |
| Anthropic | ANTHROPIC_API_KEY, optional QUERAI_ANTHROPIC_MODEL |
Security (important)
Querai is designed for read-only analytics, not arbitrary SQL execution.
Built-in protections
- SqlGuard – Only
SELECTis allowed. BlocksINSERT,UPDATE,DELETE,DROP,TRUNCATE,ALTER, multiple statements, etc. - Row limit – Appends
LIMITif missing (QUERAI_MAX_ROWS, default 200). - Excluded tables – Tables never appear in schema or queries:
Recommended hardening
- Use a read-only database user for the Querai connection (MySQL:
GRANT SELECT ON db.* TO 'querai'@'%'). - Point
QUERAI_DB_CONNECTIONat a replica if you have one. - Never expose the UI without authentication (see below).
- Add rate limiting on
/querai/askin your app if the UI or API is used heavily. - Monitor AI API costs; each question uses at least two AI calls (SQL + formatting).
Admin UI
A minimal chat UI is included at /querai (prefix configurable).
It is not public by default. Routes use Laravel middleware from config:
Protect with your existing auth
Option A – middleware only (default web + auth):
Option B – Gate / policy (fine-grained):
In App\Providers\AuthServiceProvider:
Set in config:
The package registers a placeholder gate if missing; override it in your app.
Disable UI entirely:
Publish views to customize:
Configuration reference
| Key | Description |
|---|---|
connection |
Laravel DB connection name |
ai.provider |
openai, azure, gemini, anthropic |
security.excluded_tables |
Tables hidden from AI |
security.excluded_column_patterns |
Regex patterns for sensitive columns |
security.max_rows |
Max rows per query |
security.blocked_keywords |
Extra blocked SQL keywords |
retries.max_attempts |
SQL generation retries on error |
conversation.enabled |
Multi-turn context cache |
conversation.ttl_minutes |
Conversation cache TTL |
response.threshold |
Row count before paginating answers |
response.page_size |
Rows per page sent to AI |
response.ttl_minutes |
Cached result session TTL |
schema.cache |
Cache extracted schema |
schema.compact |
Compact schema format (fewer tokens) |
schema.path |
JSON schema file path |
hints.enabled |
Send hints to AI (default true) |
hints.text |
Domain knowledge for SQL generation — configure this |
hints.max_chars |
Max characters sent to AI |
ui.middleware |
Route middleware stack |
ui.gate |
Optional Gate ability |
Artisan commands
| Command | Description |
|---|---|
php artisan querai:schema |
Extract DB schema to cache |
php artisan querai:schema --fresh |
Force re-extraction |
Error handling & retries
When a generated query fails (syntax, unknown column, etc.), Querai:
- Captures the database error message
- Asks the AI to fix the SQL
- Retries up to
retries.max_attempts(default 3)
Disable retries:
Conversation cache
When enabled, user/assistant messages are stored in Laravel cache so follow-up questions understand prior context.
Things to consider in production
| Topic | Suggestion |
|---|---|
| DB access | Read-only DB user + optional replica |
| Secrets | Exclude users, tokens, payment tables |
| Auth | auth middleware + Gate for UI |
| Rate limits | throttle middleware on ask endpoint |
| Schema drift | Run querai:schema --fresh after migrations |
| AI costs | Cache schema; limit UI to admins |
| Compliance | Log questions/SQL if your policy requires audit trails (add in your app) |
License
MIT. See LICENSE.
All versions of querai with dependencies
illuminate/support Version ^11.0|^12.0
illuminate/database Version ^11.0|^12.0
illuminate/http Version ^11.0|^12.0
illuminate/routing Version ^11.0|^12.0
illuminate/view Version ^11.0|^12.0
illuminate/console Version ^11.0|^12.0
illuminate/cache Version ^11.0|^12.0
illuminate/contracts Version ^11.0|^12.0