inceptia-io / larabrain
Give your Laravel application self-awareness. Scans models, routes, controllers and migrations, builds a context graph, and answers natural-language questions about your codebase via OpenAI, Gemini, Anthropic or DeepSeek.
Requires
- php: ^8.1
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- larastan/larastan: ^2.0|^3.0
- laravel/pint: ^1.0
- orchestra/testbench: ^8.0|^9.0
- pestphp/pest: ^2.0
- pestphp/pest-plugin-laravel: ^2.0
- phpstan/phpstan: ^1.0|^2.0
This package is not auto-updated.
Last update: 2026-07-08 06:17:29 UTC
README
Give your Laravel application self-awareness. LaraBrain scans your codebase (models, migrations, routes, controllers), builds a structured context graph, and uses an AI provider to answer natural-language questions about how your application works — with clickable links to relevant pages.
Requirements
- PHP 8.1 or higher
- Laravel 10, 11, 12, or 13
Installation
1 — Install via Composer
composer require inceptia-io/larabrain
Laravel will auto-discover the service provider via the extra.laravel key in composer.json. No manual provider registration is required for Laravel 10+.
2 — Publish the config file
php artisan vendor:publish --tag=brain-config
This places config/app-brain.php in your application's config/ directory.
3 — (Optional) Publish migrations
php artisan vendor:publish --tag=brain-migrations php artisan migrate
4 — Configure environment variables
Add the variables below to your .env file. Only BRAIN_AI_DRIVER and its corresponding API key are required.
Environment Variables
All environment variables are optional unless marked required. The package reads from .env and falls back to config/app-brain.php.
AI Provider Configuration
| Variable | Default | Description |
|---|---|---|
BRAIN_AI_DRIVER |
openai |
Required. AI provider: openai, gemini, anthropic, or deepseek |
OPENAI_API_KEY |
— | OpenAI API key (e.g. sk-...). Required if BRAIN_AI_DRIVER=openai |
GEMINI_API_KEY |
— | Google Gemini API key. Required if BRAIN_AI_DRIVER=gemini |
ANTHROPIC_API_KEY |
— | Anthropic API key. Required if BRAIN_AI_DRIVER=anthropic |
DEEPSEEK_API_KEY |
— | DeepSeek API key. Required if BRAIN_AI_DRIVER=deepseek |
Provider-Specific Settings
| Variable | Default | Description |
|---|---|---|
BRAIN_OPENAI_MODEL |
gpt-4o |
OpenAI model to use (e.g. gpt-4-turbo, gpt-4) |
BRAIN_OPENAI_MAX_TOKENS |
2048 |
Maximum tokens for OpenAI responses |
BRAIN_OPENAI_TIMEOUT |
60 |
Request timeout in seconds for OpenAI |
BRAIN_GEMINI_MODEL |
gemini-1.5-pro |
Google Gemini model to use |
BRAIN_GEMINI_MAX_TOKENS |
2048 |
Maximum tokens for Gemini responses |
BRAIN_ANTHROPIC_MODEL |
claude-3-5-sonnet-20241022 |
Anthropic model to use |
BRAIN_ANTHROPIC_MAX_TOKENS |
2048 |
Maximum tokens for Anthropic responses |
BRAIN_DEEPSEEK_MODEL |
deepseek-chat |
DeepSeek model to use |
BRAIN_DEEPSEEK_MAX_TOKENS |
2048 |
Maximum tokens for DeepSeek responses |
Caching
| Variable | Default | Description |
|---|---|---|
BRAIN_CACHE_ENABLED |
true |
Enable/disable the cache layer entirely |
BRAIN_ASK_CACHE_CONTEXT |
false |
Cache context results per keyword to avoid re-scanning |
BRAIN_CACHE_CONTEXT_TTL |
3600 |
TTL in seconds for cached context results |
BRAIN_CACHE_PREFIX |
brain |
Cache key prefix to avoid conflicts |
Logging
| Variable | Default | Description |
|---|---|---|
BRAIN_ASK_LOG_QUERIES |
false |
Log every ask() call at DEBUG level with metadata |
BRAIN_LOG_CHANNEL |
null |
Log channel (uses app default if null) |
Web Interface
| Variable | Default | Description |
|---|---|---|
BRAIN_UI_ENABLED |
true |
Enable/disable the web chat interface |
BRAIN_UI_PREFIX |
brain |
URL prefix for chat page (e.g. /brain) |
Example .env
# Required BRAIN_AI_DRIVER=openai OPENAI_API_KEY=sk-your-key-here # Optional: customize model behavior BRAIN_OPENAI_MODEL=gpt-4o BRAIN_OPENAI_MAX_TOKENS=4096 # Optional: enable context caching BRAIN_CACHE_ENABLED=true BRAIN_ASK_CACHE_CONTEXT=true BRAIN_CACHE_CONTEXT_TTL=7200 # Optional: enable logging BRAIN_ASK_LOG_QUERIES=true BRAIN_LOG_CHANNEL=single # Optional: web interface BRAIN_UI_ENABLED=true BRAIN_UI_PREFIX=brain
Scanning Your Codebase
Before asking questions, scan your application to build the context index:
php artisan app-brain:scan
This scans your models, migrations, routes, and controllers and stores a snapshot. Options:
# Scan a specific path php artisan app-brain:scan --path=app/Models # Only run one type of scanner php artisan app-brain:scan --scanner=model # Preview files without scanning php artisan app-brain:scan --dry-run
Asking Questions
Use the Artisan command to ask a natural-language question:
php artisan app-brain:ask "How does the user registration flow work?"
Options:
# Provide an explicit keyword to focus context lookup php artisan app-brain:ask "Explain the checkout process" --keyword=order # Output the full response as JSON php artisan app-brain:ask "What routes does the user have?" --json
Web Interface
LaraBrain includes a built-in web UI for asking questions directly from your browser. Access is controlled by middleware (protected by auth by default).
Standalone Chat Page
Visit the chat interface at your configured URL:
https://your-app.test/brain
This is a full-page chat application with:
- Clean dark theme
- Markdown rendering for AI responses
- Clickable links to relevant routes in your application
- Request metadata (intent, driver, elapsed time)
Access control: Protected by auth middleware by default. Configure in config/app-brain.php:
'ui' => [ 'enabled' => true, 'prefix' => 'brain', // URL prefix 'middleware' => ['web', 'auth'], // Remove 'auth' to make public ],
To make it public:
'middleware' => ['web'],
Floating Widget
Drop the widget anywhere in your admin layout for quick access without leaving the page:
<!-- In your master layout (e.g. resources/views/layouts/app.blade.php) --> @include('brain::widget')
The widget appears as a fixed button in the bottom-right corner. Click to open a chat panel with the same features as the standalone page.
Example: Add to your admin panel footer:
<footer> <p>© {{ date('Y') }} Your App</p> @include('brain::widget') </footer>
The widget respects the same middleware configuration as the chat page.
Using the Facade
use AppBrain; $response = AppBrain::ask('How does the order placement flow work?'); echo $response->answer; echo $response->intent->label(); // e.g. "Explain Workflow" echo $response->driver; // e.g. "openai" echo $response->elapsedMs;
You can also override keyword detection:
$response = AppBrain::ask( question: 'Explain the payment process', keyword: 'payment', );
The AppBrainResponse object contains:
| Property | Type | Description |
|---|---|---|
query |
string | The original question |
keyword |
string | Extracted or overridden keyword |
intent |
Intent | Detected intent enum |
context |
ContextResult | The resolved context graph |
prompt |
string | The full prompt sent to the AI |
driver |
string | The AI driver used |
answer |
string | The AI response |
elapsedMs |
float | Total time in milliseconds |
Intent Detection
The package classifies each question into one of five intents before building the prompt. This focuses the AI's response on the relevant aspect of your codebase.
| Intent | Triggered by |
|---|---|
| Explain Workflow | "how does", "explain", "walk me through", "flow", "process", "lifecycle" |
| Show Routes | "routes", "endpoints", "url", "web route", "api route" |
| Describe Model | "model", "schema", "fields", "fillable", "casts", "relationships" |
| List Dependencies | "dependencies", "what uses", "what calls", "connected to", "references" |
| General | Everything else |
You can extend the keyword map at runtime:
use Arafat\Brain\AI\Intent; use Arafat\Brain\AI\IntentMap; IntentMap::extend(Intent::ExplainWorkflow, ['pipeline', 'journey', 'sequence']);
Context Building
The Brain facade provides direct access to the context layer:
use Brain; $context = Brain::context('order'); $context->models; // Collection of matched model data $context->tables; // Collection of matched table data $context->routes; // Collection of matched route data $context->controllerMethods; // Collection of matched controller method data $context->elapsedMs;
AI Providers
Four providers are built in. Switch between them with BRAIN_AI_DRIVER.
| Driver | Environment Key | Default Model |
|---|---|---|
openai |
OPENAI_API_KEY |
gpt-4o |
gemini |
GEMINI_API_KEY |
gemini-1.5-pro |
anthropic |
ANTHROPIC_API_KEY |
claude-3-5-sonnet-20241022 |
deepseek |
DEEPSEEK_API_KEY |
deepseek-chat |
Per-provider model and token settings can be overridden in config/app-brain.php or via environment variables:
BRAIN_OPENAI_MODEL=gpt-4-turbo BRAIN_OPENAI_MAX_TOKENS=4096 BRAIN_OPENAI_TIMEOUT=60
Custom Provider
Implement Arafat\Brain\AI\AppBrainAIInterface and register it in the config:
// config/app-brain.php 'ai' => [ 'default' => 'myprovider', 'drivers' => [ 'myprovider' => \App\AI\MyProvider::class, ], ],
Configuration Reference
The full config file at config/app-brain.php includes these top-level keys:
| Key | Default | Description |
|---|---|---|
enabled |
true |
Globally enable or disable the package |
cache.enabled |
true |
Enable the cache layer |
cache.ttl |
3600 |
Default cache TTL in seconds |
cache.context_ttl |
3600 |
TTL for context results specifically |
cache.prefix |
brain |
Cache key prefix |
ask.cache_context |
false |
Cache context results per keyword |
ask.log_queries |
false |
Log each ask() call at DEBUG level |
log_channel |
null |
Log channel (null uses app default) |
scan.exclude |
vendor, node_modules, storage, etc. | Paths excluded from file scanning |
scan.scanners |
all enabled | Per-scanner enable/disable flags |
ai.default |
openai |
Active AI driver |
ui.enabled |
true |
Enable/disable the web chat interface |
ui.prefix |
brain |
URL prefix for chat page (e.g. /brain) |
ui.middleware |
['web', 'auth'] |
Middleware stack for UI routes (remove auth to make public) |
Testing
composer test
With coverage:
composer test:coverage
Code quality:
# Style check + static analysis composer quality # Auto-fix style composer format # Static analysis only composer analyse
License
MIT BRAIN_CACHE_ENABLED=true BRAIN_CACHE_TTL=3600 BRAIN_CACHE_PREFIX=brain BRAIN_LOG_CHANNEL=null BRAIN_QUEUE_ENABLED=false BRAIN_QUEUE_CONNECTION=default BRAIN_QUEUE_NAME=brain
---
## Usage
### Via Facade
```php
use Arafat\Brain\Facades\Brain;
Brain::method();
Via Dependency Injection
use Arafat\Brain\Contracts\BrainInterface; class MyService { public function __construct( protected readonly BrainInterface $brain ) {} }
Folder Structure
laravel-brain/
├── composer.json
├── .gitignore
├── config/
│ └── app-brain.php # Package configuration
├── database/
│ └── migrations/
│ └── 2026_01_01_000000_create_brain_tables.php
├── src/
│ ├── Brain.php # Core implementation
│ ├── BrainServiceProvider.php # Laravel service provider
│ ├── Contracts/
│ │ └── BrainInterface.php # Public API contract
│ ├── Exceptions/
│ │ └── BrainException.php # Base package exception
│ └── Facades/
│ └── Brain.php # Laravel Facade
└── tests/
├── Pest.php # Pest bootstrap
├── TestCase.php # Testbench base case
├── Feature/ # Feature tests
└── Unit/ # Unit tests
Testing
composer test # with coverage composer test:coverage
License
The MIT License (MIT). See LICENSE for details.