Reference
Laragents
Everything is optional and everything has a default. Call none of it and you get a package that talks to OpenAI, meters nothing, redacts nothing, and has the two memory tools.
Laragents::tools($classOrArray) |
Add tools to the catalogue. Class names resolve through the container. |
Laragents::skills($classOrArray) |
Add skills. Held as class names, resolved lazily. |
Laragents::talkWith($client) |
Which ChatClient answers by default. |
Laragents::meterWith($recorder) |
Who records what a run spends. Bound scoped. |
Laragents::redactWith($redactor) |
Who keeps personal data out of what leaves. |
Laragents::speakWith($speaker) |
Text to speech. Nothing in the package calls it. |
Laragents::drawWith($illustrator) |
Images. Nothing in the package calls it. |
AgentLoop
$loop->run( array $messages, string $model, ChatSession $session, ToolContext $context, array $tools = [], bool $persist = true, array $capabilities = [], ): Response
Override to change behaviour:
outbound(array $messages): array |
Messages on the way to the provider. |
inbound(string $content): string |
The model's text on the way back. |
inboundToolCalls(array $calls): array |
Tool arguments, before the tools run. |
arguments(string $tool, array $args, ToolContext $c): array |
Add caller data to every call. |
afterTool(string $tool, array $result, ToolContext $c): array |
Annotate a result. |
watchEmptyStreak(array $result): array |
The stop-searching guard. |
foundSomething(array $result): ?bool |
Whether a result found anything. Null = cannot say. |
Response
content, inputTokens, outputTokens, model, toolCalls, finishReason, cacheCreationTokens, cacheReadTokens, reasoning, citations, all readonly.
hasToolCalls(), totalTokens(), wasTruncated(), hasReasoning(), hasCitations().
Tools\Tool
name(): string |
abstract. snake_case, what the model calls it by. |
description(): string |
abstract. Written for the model, not for the reader. |
execute(array $args, ToolContext $c): array |
abstract. $args untrusted, $c trusted. |
schema(): array |
Override this. ['field' => JsonSchema::string()]. |
parameters(): array |
The JSON Schema. Built from schema() unless you override it. |
isAction(): bool |
A flag for your UI. Nothing in the package reads it. |
tags(): array |
Runtime tags. Beats the #[Tags] attribute. |
Tools\ToolContext
make(array), with($key, $value) (returns a new one), get($key, $default), has($key), require($key) (throws), all().
The loop adds session and model before any tool runs.
Tools\ToolRegistry
register(Tool), get($name), all(), for(?array $tags, ?array $whitelist), definitions(?array $tags, ?array $whitelist).
Models\Memory / Models\Rule
scopedTo(array $memorables, ?Model $context, ?Model $tenant) |
The three axes as a query. |
forSession(ChatSession $s) |
The same, resolved from a session. |
promptBlock(ChatSession $s, int $limit) |
Ready to paste. Empty string when there is nothing. |
Memory::search($session, $query, $limit) |
Similarity when embeddings are on, recency otherwise. |
Relations on both: tenant(), memorable(), holder() (the memory morph), createdBy().
Memory::SOURCE_DISTILLED, Memory::SOURCE_EXPLICIT.
Models\ChatSession
tenant(), actor(), sessionable(), messages(), addTokens(int), updateSummary(string, int).
Models\Agent
isActive(), Agent::activeStatus(), setting($key, $default), maxIterations(), listensTo($event), isDue(?DateTimeInterface), tasks(), logs(), tenant(), createdBy().
Models\AgentTask
markRunning(), markCompleted(array $output, int $in, int $out, int $credits), markFailed(string $error), agent(), taskable(), logs().
AgentTrigger
fire(string $event, Model $owner, ?Model $subject, array $context): int
due(?iterable $subjects): int
Both return how many tasks were dispatched.
Console commands
laragents:run-due-agents every minute
laragents:cleanup-stale-tasks every five minutes
laragents:distil-inactive-sessions [--limit=50] every thirty minutes
Registered on the scheduler automatically. Turn that off with agents.schedule => false.
Publish tags
laragents-config config/laragents.php
laragents-migrations the seven tables
laragents-optout-migration share_memories on your users table
Configuration
'chat' => [ 'max_tool_iterations' => 7, // ceiling on the loop 'max_tool_result_chars' => 16000, // truncation before a result goes back 'empty_streak_after' => 2, // consecutive empty searches before the hint 'result_keys' => ['items', 'results', 'matches', 'passages', 'data'], 'empty_streak_hint' => null, // ':count' is the streak 'max_history_tokens' => 6000, // budget for the replayed conversation 'recent_messages_min' => 4, // never compressed, whatever the budget says 'max_response_tokens' => null, ], 'openai' => [ 'api_key' => env('OPENAI_API_KEY'), 'transcription_model' => 'whisper-1', 'transcription_tokens_per_minute' => 1000, 'speech_model' => 'tts-1', 'voice' => 'alloy', 'image_model' => 'gpt-image-1', ], 'anthropic' => ['api_key' => env('ANTHROPIC_API_KEY')], 'failover' => [], // [['client' => AnthropicClient::class, 'model' => '...']] 'privacy' => [ 'enabled' => false, 'except' => ['person'], 'keys' => ['content', 'tool_calls.*.function.arguments'], ], 'memory' => [ 'model' => 'gpt-4o-mini', 'min_messages' => 4, 'existing_context' => 30, 'lock_seconds' => 120, 'prompt' => null, 'embeddings' => false, 'embedding_model' => 'text-embedding-3-small', 'candidate_pool' => 200, 'tools' => true, 'share_memories' => true, 'actor_table' => 'users', 'distil_on_compress' => true, 'sweep' => true, 'inactive_after_minutes'=> 30, 'queue' => 'default', ], 'agents' => [ 'active_status' => 'active', 'schedule' => true, 'queue' => 'default', 'debounce_seconds' => 30, 'stale_after_minutes' => 30, ], 'events' => [], // YourEvent::class => YourResolver::class 'rules' => ['headings' => []], 'usage_recorder' => null, // or 'larameter', or your class
built and maintained by Edu Lazaro · MIT license