eloquent-dsl/ai-query

Safe DSL-driven Eloquent query builder for AI agents.

Maintainers

Package info

github.com/VictorDevPHP/ai-query-laravel

pkg:composer/eloquent-dsl/ai-query

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-05-05 20:54 UTC

This package is auto-updated.

Last update: 2026-05-05 20:57:27 UTC


README

Laravel Logo

Latest Stable Version Total Downloads License PHP Version

About Eloquent DSL AI Query

eloquent-dsl/ai-query is a reusable Laravel package that allows AI agents to build safe, structured, and dynamic Eloquent queries from a DSL-like payload.

Instead of generating raw SQL or executing arbitrary code, AI clients can send constrained actions that are validated and executed with strict allow/block lists.

Features

  • Fluent API: AIQuery::for(Model::class)->fromArray($input)->get();
  • Structured actions (select, where, orWhere, whereIn, whereBetween, join, with, whereHas, orderBy, limit, paginate)
  • Runtime-extensible action registry
  • Safe join mapping (no dynamic ON conditions from AI)
  • Model-level security rules (allow list + block list)
  • Query complexity control (max_actions)
  • Optional logging for executed AI queries
  • Model introspection service

Requirements

  • PHP ^7.4 || ^8.0
  • Laravel 7+

Installation

1) Add package as path repository (without Packagist)

In your Laravel app composer.json:

{
  "repositories": [
    {
      "type": "path",
      "url": "../eloquent-dsl"
    }
  ],
  "require": {
    "eloquent-dsl/ai-query": "*"
  }
}

Then run:

composer update eloquent-dsl/ai-query

2) Publish config (optional)

php artisan vendor:publish --tag=ai-query-config

Configuration

config/ai-query.php:

return [
    'max_limit' => 100,
    'max_actions' => 20,

    'logging' => [
        'enabled' => true,
        'channel' => null,
    ],

    'models' => [
        App\Models\User::class => [
            'allowed_fields' => ['id', 'name', 'email', 'created_at'],
            'blocked_fields' => [],
            'allowed_relations' => ['posts'],
            'blocked_relations' => [],
            'allowed_joins' => ['posts'],
            'joins' => [
                'posts' => [
                    'table' => 'posts',
                    'first' => 'users.id',
                    'operator' => '=',
                    'second' => 'posts.user_id',
                    'type' => 'inner',
                ],
            ],
        ],
    ],
];

Basic Usage

use App\Models\User;
use EloquentDsl\AIQuery\AIQuery;

$input = [
    'model' => User::class,
    'actions' => [
        ['type' => 'select', 'fields' => ['id', 'name', 'email']],
        ['type' => 'where', 'field' => 'email', 'operator' => 'like', 'value' => '%gmail%'],
        ['type' => 'with', 'relation' => 'posts'],
        ['type' => 'join', 'table' => 'posts'],
        ['type' => 'orderBy', 'field' => 'created_at', 'direction' => 'desc'],
        ['type' => 'limit', 'value' => 10],
    ],
];

$users = AIQuery::for(User::class)
    ->fromArray($input)
    ->get();

Registering Custom Actions

use EloquentDsl\AIQuery\ActionRegistry;

ActionRegistry::register('customAction', function ($query, array $action): void {
    $query->whereNotNull($action['field'] ?? 'id');
});

Runtime Config Override

AIQuery::for(User::class)
    ->overrideConfig([
        'max_limit' => 50,
    ])
    ->fromArray($input)
    ->get();

Model Introspection

use EloquentDsl\AIQuery\ModelInspector;

$all = ModelInspector::getModelsStructure('*');
$specific = ModelInspector::getModelsStructure([
    App\Models\User::class,
]);

Example return:

[
    'User' => [
        'table' => 'users',
        'fields' => ['id', 'name', 'email'],
        'relations' => ['posts'],
    ],
]

Supported Actions

  • select
  • where
  • orWhere
  • whereIn
  • whereBetween
  • join (safe mapped joins only)
  • with
  • whereHas
  • orderBy
  • limit
  • paginate

Testing

Run package tests locally:

composer install
vendor/bin/phpunit

Security

This package is designed for constrained query generation, but secure behavior depends on proper configuration.

Always configure:

  • allowed_fields
  • allowed_relations
  • allowed_joins
  • sensible max_limit and max_actions

Never expose unrestricted model access to AI inputs.

Contributing

Thank you for considering contributing to this package.

License

This package is open-sourced software licensed under the MIT license.