Quickstart
Start with creation of the listener:
php artisan make:listener AgentListener
Name AgentListener
is used as example, you can name it as you wish
Import LarAgent event of your choice (You can find a list below) and implement handle method:
namespace App\Listeners;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use LarAgent\Events\AgentInitialized;
class AgentListener
{
/**
* Create the event listener.
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle(AgentInitialized $event): void
{
// Just DD the event info as example
dd('Agent has been initialized:', $event);
}
}
Open the app\Providers\AppServiceProvider.php
and register event with listener:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Event;
use LarAgent\Events\AgentInitialized;
use App\Listeners\AgentListener;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Event::listen(
AgentInitialized::class,
AgentListener::class
);
// MCP Test per-second rate limiter
\Illuminate\Support\Facades\RateLimiter::for('mcp-test', function ($request) {
return \Illuminate\Cache\RateLimiting\Limit::perSecond(2)->by($request->user()?->id ?: $request->ip());
});
}
}
You are good to go! Anytime, when agent will be initialized, the handle
method will be executed.
Available Events
AgentDTO Structure
Each event that includes agentDto
uses the following Data Transfer Object
structure:
<?php
namespace LarAgent\Core\DTO;
class AgentDTO
{
public function __construct(
public readonly string $provider,
public readonly string $providerName,
public readonly ?string $message,
public readonly array $tools = [],
public readonly ?string $instructions = null,
public readonly ?array $responseSchema = [],
public readonly array $configuration = []
) {}
public function toArray(): array
{
return [
'provider' => $this->provider,
'providerName' => $this->providerName,
'message' => $this->message,
'tools' => $this->tools,
'instructions' => $this->instructions,
'responseSchema' => $this->responseSchema,
'configuration' => $this->configuration,
];
}
}
Lifecycle Events
These events track the main lifecycle stages of an agent conversation.
AgentInitialized
Dispatched when the agent completes its initialization process and is ready to handle conversations.
Namespace:
LarAgent\Events\AgentInitialized
Available Data:
Complete agent configuration including provider, tools, instructions, and
response schema.
Example:
public function handle(AgentInitialized $event): void
{
$provider = $event->agentDto->provider;
$tools = $event->agentDto->tools;
// Your logic here
}
ConversationStarted
Dispatched when the respond()
method begins execution, marking the start of a new conversation turn.
Namespace:
LarAgent\Events\ConversationStarted
Available Data:
Current agent configuration at the start of the conversation.
Example:
public function handle(ConversationStarted $event): void
{
$message = $event->agentDto->message;
// Log conversation start, initialize metrics, etc.
}
ConversationEnded
Dispatched when the respond()
method completes execution, indicating the end of a conversation turn.
Namespace:
LarAgent\Events\ConversationEnded
Available Data:
Final agent configuration at the end of the conversation.
message
MessageInterface|array|null
required
The final response message or null if no response was generated.
Message instance includes the token usage data. You can use toArrayWithMeta
to get it as an array
Example:
public function handle(ConversationEnded $event): void
{
$response = $event->message;
// Log conversation end, calculate metrics, cleanup, etc.
}
Dispatched when tools are dynamically added to or removed from the agent during runtime.
Namespace:
LarAgent\Events\ToolChanged
Available Data:
Current agent configuration.
The tool instance that was added or removed.
true
if the tool was added, false
if it was removed.
Example:
public function handle(ToolChanged $event): void
{
$toolName = $event->tool->getName();
$action = $event->added ? 'added' : 'removed';
// Log tool changes, update UI, etc.
}
AgentCleared
Dispatched when the agent’s state is cleared, typically resetting conversation history and context.
Namespace:
LarAgent\Events\AgentCleared
Available Data:
Agent configuration at the time of clearing.
Example:
public function handle(AgentCleared $event): void
{
// Clear related caches, reset session data, etc.
}
EngineError
Dispatched when an error occurs in the LLM engine during processing.
Namespace:
LarAgent\Events\EngineError
Available Data:
Agent configuration when the error occurred.
The exception that was thrown by the LLM engine.
Example:
public function handle(EngineError $event): void
{
$error = $event->exception->getMessage();
$provider = $event->agentDto->provider;
// Log error, send alerts, implement fallback logic, etc.
}
Hook Events (Before/After)
These events provide hooks before and after critical operations, allowing you to modify behavior or track execution flow.
BeforeReinjectingInstructions
Dispatched before instructions are reinjected into the conversation history.
Namespace:
LarAgent\Events\BeforeReinjectingInstructions
Available Data:
Current agent configuration.
chatHistory
ChatHistoryInterface
required
The chat history interface before instruction reinjection.
Example:
public function handle(BeforeReinjectingInstructions $event): void
{
$history = $event->chatHistory;
// Modify history, add context, etc.
}
BeforeSend
Dispatched just before adding message in chat history
Namespace:
LarAgent\Events\BeforeSend
Available Data:
Current agent configuration.
history
ChatHistoryInterface
required
The complete conversation history being sent.
message
MessageInterface|null
required
The message about to be sent, or null if sending history only.
Example:
public function handle(BeforeSend $event): void
{
$messageContent = $event->message?->getContent();
// Log outgoing messages, modify content, add tracking, etc.
}
AfterSend
Dispatched immediately after adding LLM response to Chat history.
Namespace:
LarAgent\Events\AfterSend
Available Data:
Current agent configuration.
history
ChatHistoryInterface
required
The conversation history that was sent.
The message that was successfully sent.
Example:
public function handle(AfterSend $event): void
{
$sentMessage = $event->message->getContent();
// Track message delivery, update metrics, etc.
}
BeforeSaveHistory
Dispatched before persisting the conversation history to storage.
Namespace:
LarAgent\Events\BeforeSaveHistory
Available Data:
Current agent configuration.
history
ChatHistoryInterface
required
The conversation history about to be saved.
Example:
public function handle(BeforeSaveHistory $event): void
{
$history = $event->history;
// Sanitize data, add metadata, validate before save, etc.
}
BeforeResponse
Dispatched before sending message to LLM
Namespace:
LarAgent\Events\BeforeResponse
Available Data:
Current agent configuration.
history
ChatHistoryInterface
required
Current conversation history including the new response.
message
MessageInterface|null
required
The message that is about to sent to the LLM API or null
.
Example:
public function handle(BeforeResponse $event): void
{
$response = $event->message?->getContent();
// Filter content, add formatting, validate response, etc.
}
AfterResponse
Dispatched right after receiving a message from LLM API
Namespace:
LarAgent\Events\AfterResponse
Available Data:
Current agent configuration.
Example:
public function handle(AfterResponse $event): void
{
$finalResponse = $event->message->getContent();
// Log final response, update analytics, cache result, etc.
}
Dispatched just before a tool is executed by the agent.
Namespace:
LarAgent\Events\BeforeToolExecution
Available Data:
Current agent configuration.
The tool instance about to be executed.
Example:
public function handle(BeforeToolExecution $event): void
{
$toolName = $event->tool->getName();
// Log tool execution start, validate permissions, start timer, etc.
}
Dispatched immediately after a tool completes execution.
Namespace:
LarAgent\Events\AfterToolExecution
Available Data:
Current agent configuration.
The tool instance that was executed.
The result returned by the tool execution.
Example:
public function handle(AfterToolExecution $event): void
{
$toolName = $event->tool->getName();
$result = $event->result;
// Log results, track performance, cache output, etc.
}
BeforeStructuredOutput
Dispatched before processing structured output from the LLM response.
Namespace:
LarAgent\Events\BeforeStructuredOutput
Available Data:
Current agent configuration including the response schema.
The raw structured response array before processing.
Example:
public function handle(BeforeStructuredOutput $event): void
{
$schema = $event->agentDto->responseSchema;
$response = $event->response;
// Validate structure, log details, etc.
}