This document is the detailed, structured guide for integrating Laravel AI SDK into Evolution CMS using the eAi package. It expands on the README with deeper configuration and operational details.
- eAi is a thin Evo‑native wrapper around
laravel/ai. - No
illuminate/foundationis required; minimal shims are provided for SDK compatibility. - sTask is the primary queue backend;
syncis a fallback. - AI actions run under a dedicated AI manager role (service account), not by end‑users.
- Evolution CMS 3.5.2+
- PHP 8.4+
- Composer 2.2+
Optional:
- sTask for async execution (currently
dev-mainfrom the main repo)
cd core
php artisan package:installrequire evolution-cms/eai "*"Auto‑publish is enabled, but you may force it:
php artisan vendor:publish --provider="EvolutionCMS\\eAi\\eAiServiceProvider" --tag=eai-config
php artisan vendor:publish --provider="EvolutionCMS\\eAi\\eAiServiceProvider" --tag=eai-ai-config
php artisan vendor:publish --provider="EvolutionCMS\\eAi\\eAiServiceProvider" --tag=eai-stubsMigrations:
php artisan migrateThis is the Laravel AI SDK config. Common values:
return [
'default' => 'openai',
'providers' => [
'openai' => [
'driver' => 'openai',
'key' => env('OPENAI_API_KEY'),
],
'ollama' => [
'driver' => 'ollama',
'key' => env('OLLAMA_API_KEY', ''),
'url' => env('OLLAMA_BASE_URL', 'http://localhost:11434'),
],
],
];Notes:
default_*keys define provider defaults for images, audio, etc.- Provider keys can be in
.envor directly in config.
Evo integration settings:
return [
'enable' => true,
'queue_driver' => 'stask',
'queue_failover' => 'sync',
'context' => 'auto',
'ai_actor_mode' => 'service',
'ai_actor_email' => null,
'ai_actor_autocreate' => true,
'ai_actor_block_login' => true,
'ai_actor_role' => 'AI',
'ai_actor_role_autocreate' => true,
];Field notes:
queue_driver:stask(primary) orsync(fallback).queue_failover: used whenstaskis missing.context:mgr|web|auto(execution context).ai_actor_*: controls the AI service account (manager user + role AI).
conversation_user_id: real user in history. If unknown (CLI/no session), fallback is1.actor_user_id: AI service account when enabled (role AI).initiated_by_user_id: who triggered the action (for auditing).
Rules:
- Write actions are only allowed via manager ACL, never via direct DB writes.
- AI user is a standard manager user with role AI (ApiUser‑style, no extra columns).
- Interactive login is blocked (
user_attributes.blocked=1). - The AI role is read‑only by default; to allow saving/publishing, elevate manually.
- If you need access to package interfaces, grant permissions
staskand/orsapi(groupsPackages).
- sTask is the primary backend.
syncis a fallback for missing sTask or local smoke‑tests. - eAi does not implement Laravel Queue; it provides SDK‑compatible dispatching only.
Visible workers:
eai_smoke— fixed prompt, quick smoke test.eai_prompt— custom prompt from widget.
Internal worker:
eai— used only for queued SDK jobs (not for manual execution).
Process tasks:
php artisan stask:workerQueued jobs contain:
job_classjob_payload(serialized)attempts,max_attemptsactor_user_id,conversation_user_id,initiated_by_user_idcontext(mgr|web|cli)
then/catch are treated as minimal metadata; Laravel Bus compatibility is not guaranteed.
php artisan ai:testOptions:
--provider=openai|ollama|...--model=...--prompt="..."
php artisan make:agent SalesCoach
php artisan make:agent SalesCoach --structured
php artisan make:tool RandomNumberGeneratorGenerated classes:
core/custom/app/Ai/Agents/*core/custom/app/Ai/Tools/*
If autoloading is stale:
composer dumpautoloaduse App\Ai\Agents\SupportAgent;
$agent = new SupportAgent();
$response = $agent->prompt('Hello from Evo');
echo $response->text;use function Laravel\Ai\agent;
$response = agent(
instructions: 'You are a helpful assistant.',
messages: [],
tools: []
)->prompt('Summarize this page');
echo $response->text;use App\Ai\Agents\SalesCoach;
$response = (new SalesCoach())->prompt('Analyze this sales transcript...');
echo $response['score'];use App\Ai\Tools\RandomNumberGenerator;
class SupportAgent implements \Laravel\Ai\Contracts\Agent, \Laravel\Ai\Contracts\HasTools
{
use \Laravel\Ai\Promptable;
public function instructions(): string { return 'You are helpful.'; }
public function tools(): iterable { return [new RandomNumberGenerator]; }
}use App\Ai\Agents\SalesCoach;
(new SalesCoach)
->queue('Analyze this transcript...')
->then(function ($response) {
// handle response
});use Laravel\Ai\Image;
$image = Image::of('A donut on the table')->generate();
$path = $image->storePubliclyAs('ai/donut.png');use Laravel\Ai\Audio;
$audio = Audio::of('Hello from Evo')->generate();
$path = $audio->storePubliclyAs('ai/hello.mp3');use Laravel\Ai\Transcription;
$text = Transcription::fromPath('/path/to/audio.mp3')->generate();use Laravel\Ai\Embeddings;
$response = Embeddings::for(['Napa Valley has great wine.'])->generate();
$vector = $response->embeddings[0];use Laravel\Ai\Reranking;
$response = Reranking::of([
'Django is a Python web framework.',
'Laravel is a PHP web application framework.',
])->rerank('PHP frameworks');
echo $response->first()->document;use Laravel\Ai\Files\Document;
use App\Ai\Agents\SupportAgent;
$stored = Document::fromPath('/path/to/report.pdf')->put();
$response = (new SupportAgent())->prompt(
'Summarize this report.',
[Document::fromId($stored->id)]
);-
Target class [prism] does not existEnsure dependencies are installed and autoload is rebuilt (composer dumpautoload). This error happens when the container binding for Prism is missing. -
Rate limited by provider The provider returned a rate limit error. Try another model/provider or wait.
-
No provider with configured API key Set a key in
.envor incore/custom/config/ai.php.
- Config:
core/custom/config/ai.php - Evo settings:
core/custom/config/cms/settings/eAi.php - Agents:
core/custom/app/Ai/Agents/* - Tools:
core/custom/app/Ai/Tools/* - Stubs:
core/stubs/*