janschuri/eloquent-ai-tools

Give Eloquent models the ability to register themselves as AI tool sources.

Maintainers

Package info

github.com/Janschuri/EloquentAiTools

pkg:composer/janschuri/eloquent-ai-tools

Transparency log

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-08-12 20:27 UTC

This package is auto-updated.

Last update: 2026-08-12 20:33:35 UTC


README

Tests Latest Version License

Turn Eloquent models into safe, structured AI tools with a small, drop-in layer that stays inside normal Eloquent conventions.

The Problem

Giving an AI agent access to your application data usually pushes you into one of two bad options:

  • Let it generate SQL. Fast to prototype, but now you are validating and sandboxing arbitrary queries.
  • Hand-write tool classes around every model or operation. Safer, but full of boilerplate and easy to let drift away from your schema.

EloquentAiTools takes a third path. Instead of introducing a parallel query system, it plugs into the Eloquent models, scopes, casts, and relations you already have. You describe what a model should expose, and the package builds a read-only query tool from that config plus the model schema Laravel already knows about.

No generated SQL. No hand-maintained JSON schema. No separate tool class per model.

Installation

composer require janschuri/eloquent-ai-tools

Requirements

  • PHP ^8.3
  • Laravel ^13.0
  • Laravel AI SDK (laravel/ai) ^0.10

Quick Start

<?php

use EloquentAiTools\Concerns\HasToolModel;
use EloquentAiTools\Decision;
use EloquentAiTools\ToolBuilder;
use Illuminate\Database\Eloquent\Model;
use Laravel\Ai\Tools\Request;

class Article extends Model
{
    use HasToolModel;

    public static function toolConfig()
    {
        return static::newToolConfig([
            'title' => 'Article headline',
            'status' => 'Publication status',
            'views' => 'View count',
            'published_at' => 'Publish date',
        ])
            ->label('Articles')
            ->modelDescription('Articles from the CMS.')
            ->allowRead()
            ->maxLimit(50)
            ->whereMaxDepth(3)
            ->whereMaxConditionsPerGroup(10)
            ->scopes([
                'published' => 'Only published articles.',
            ])
            ->reading(function (Request $request, array $appliers) {
                return Decision::accept(); // or Decision::deny(...) / Decision::approve(...) / a bool
            });
    }
}

$tools = ToolBuilder::make()
    ->add(Article::toolConfig())
    ->build();

That exposes a read_articles tool. Its schema and description are generated from the Article config plus the active query resolvers, so the tool stays aligned with the model instead of becoming a second thing to maintain.

If you need a more specific or collision-resistant name, add a tool key:

->toolKey('cms')

That changes the tool name to read_cms_articles.

Out of the box, the tool supports:

  • an explain field for query intent
  • reusable numeric expressions
  • explicit select projections, including whole-result and grouped aggregates
  • required distinct control for duplicate-prone relation queries
  • typed where filters, including nested condition groups and relation existence checks
  • groupBy
  • orderBy
  • limit and offset
  • auto-derived relation joins for supported dotted relation paths
  • Eloquent scopes, so you can keep using Laravel's native way to restrict model queries
  • scoped eager loading for configured relations, including nested with paths
  • scoped direct relation aggregates through withAggregate
  • an optional per-model read policy callback

Documentation

The long-form docs now live in /wiki and are intended to be mirrored to the GitHub wiki on pushes to master:

Changelog

Releases are tagged automatically from Conventional Commits — see GitHub Releases for what changed in each version.

License

MIT