> ## Documentation Index
> Fetch the complete documentation index at: https://docs.laragent.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agents

> Agents are the core of LarAgent. They represent an AI model that can be used to interact with users, systems, or any other source of input.

<Note>
  Agents are the foundation of LarAgent. They define how your AI assistant
  behaves, what tools it can use, and how it processes information.
</Note>

## Creating an Agent

You can create a new agent manually by extending the `LarAgent\Agent` class. This is the parent class for building your custom AI agent with specific capabilities and behaviors.

<Warning>
  Using `make:agent` command is a recommended way of creating agents.
</Warning>

```php theme={null}
namespace App\AiAgents;

use LarAgent\Agent;

class MyAgent extends Agent
{
    // Your agent implementation
}
```

For rapid development, you can use the artisan command to generate a new agent with a basic structure:

```bash theme={null}
php artisan make:agent MyAgent
```

This will create a new agent class in the `App\AiAgents` directory with all the necessary boilerplate code:

```php YourAgentName.php theme={null}
<?php

namespace App\AiAgents;

use LarAgent\Agent;

class YourAgentName extends Agent
{
    protected $model = 'gpt-4o-mini';

    protected $history = 'in_memory';

    protected $provider = 'default';

    protected $tools = [];

    public function instructions()
    {
        return "Define your agent's instructions here.";
    }

    public function prompt($message)
    {
        return $message;
    }
}
```

## Configuring an Agent

Agents can be configured through various properties and methods to customize their behavior. Here are the core configuration options:

### Core methods

The agent also provides several core methods that you can override to customize its behavior:

<CodeGroup>
  ```php Instructions Method theme={null}

  // Define the agent's system instructions
  // This sets the behavior, role, and capabilities of your agent
  // For simple textual instructions, use the `instructions` property
  // For more complex instructions or dynamic behavior, use the `instructions` method
  public function instructions()
  {
  return "Define your agent's instructions here.";
  }

  ```

  ```php Prompt Method theme={null}
  // Customize how messages are processed before sending to the AI
  // Useful for formatting, adding context (RAG), or standardizing input
  public function prompt(string $message)
  {
      return $message;
  }
  ```

  ```php Model Method theme={null}
  // Decide which model to use dynamically with custom logic
  // Or use property $model to statically set the model
  public function model()
  {
      return $this->model;
  }
  ```

  ```php API Key / URL theme={null}
  // Return API URL to Dynamically set it for the driver
  public function getApiUrl()
  {
      return $this->apiUrl;
  }

  // return API Key to Dynamically set for the driver
  public function getApiKey()
  {
      return $this->apiKey;
  }
  ```
</CodeGroup>

### Properties

#### Instructions

```php theme={null}
/** @var string - Define the agent's behavior and role */
protected $instructions;
```

This property sets the system instructions for your agent, defining its behavior, personality, and capabilities.

```php theme={null}
// Example
protected $instructions = "You are a helpful assistant specialized in weather forecasting.";
```

#### History

```php theme={null}
/** @var string - Choose from built-in chat history types */
protected $history;
```

Choose from built-in chat history implementations: "in\_memory", "session", "cache", "file", or "json".

```php theme={null}
// Example
protected $history = 'cache';

// Or use a class
protected $history = \LarAgent\History\CacheChatHistory::class;
```

#### Driver

```php theme={null}
/** @var string - Specify which LLM driver to use */
protected $driver;
```

The driver class that handles communication with the AI provider.

```php theme={null}
// Example
protected $driver = \LarAgent\Drivers\OpenAi\OpenAiDriver::class;
```

#### Provider

```php theme={null}
/** @var string - Select the AI provider configuration */
protected $provider = 'default';
```

References a provider configuration from your config file.

```php theme={null}
// Example
protected $provider = 'openai-gpt4';
```

#### Model

```php theme={null}
/** @var string - Choose which language model to use */
protected $model = 'gpt-4o-mini';
```

The specific model to use from your chosen provider.

```php theme={null}
// Example
protected $model = 'gpt-4o';
```

#### Other properties

<Warning>
  All config properties have relevant setter (chainable methods) you can use to
  set them at runtime. For example, `$maxCompletionTokens` ->
  `maxCompletionTokens(int $tokens)`, `$topP` -> `topP(float $topP)` and etc.
</Warning>

<Warning>
  All config properties can be defined by config file in provider settings. For
  example, `$maxCompletionTokens` -> `max_completion_tokens => 2000` and etc.
</Warning>

##### **Tokens**

```php theme={null}
/** @var int - Set the maximum number of tokens in the completion */
protected $maxCompletionTokens;
```

Limits the length of the AI's response.

```php theme={null}
// Example
protected $maxCompletionTokens = 2000;
```

##### **Temperature**

```php theme={null}
/** @var float - Control response creativity */
protected $temperature;
```

Controls randomness: 0.0 for focused responses, 2.0 for creative ones.

```php theme={null}
// Example
protected $temperature = 0.7; // Balanced
```

##### **Message**

```php theme={null}
/** @var string|null - Current message being processed */
protected $message;
```

##### **n**

```php theme={null}
/** @var int|null */
protected $n;
```

> How many chat completion choices to generate for each input message. Note that you will be charged based on the number of generated tokens across all of the choices. Keep n as 1 to minimize costs.

In case of \$n > 1, the agent will return an array of responses.

##### **top\_p**

```php theme={null}
/** @var float|null */
protected $topP;
```

> An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top\_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.

We generally recommend altering `$topP` or `$temperature` but not both.

##### **frequency\_penalty**

```php theme={null}
/** @var float|null */
protected $frequencyPenalty;
```

> Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim.

##### **presence\_penalty**

```php theme={null}
/** @var float|null */
protected $presencePenalty;
```

> Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics.

## Arbitrary Configuration

You can set custom configuration values on agents that will be passed through to the driver. This is useful for provider-specific settings or experimental features that aren't part of the standard agent configuration.

### Setting Configuration

<CodeGroup>
  ```php Property theme={null}
  // Set configuration in the agent class
  class MyAgent extends Agent
  {
      protected $configs = [
          'reasoning_effort' => 'minimal',
          'custom_header' => 'value',
      ];
  }
  ```

  ```php Individual Config theme={null}
  // Set a single configuration value
  $agent->setConfig('custom_key', 'value');

  // Get a single configuration value
  $value = $agent->getConfig('custom_key');
  ```

  ```php Multiple Configs theme={null}
  // Set multiple configs (merge with existing)
  $agent->withConfigs([
      'key1' => 'value1',
      'key2' => 'value2'
  ]);

  // Set multiple configs (replace all)
  $agent->setConfigs([
      'key1' => 'value1'
  ]);
  ```

  ```php Check and Remove theme={null}
  // Check if config exists
  if ($agent->hasConfig('custom_key')) {
      // Config exists
  }

  // Remove a specific config
  $agent->removeConfig('custom_key');

  // Clear all custom configs
  $agent->clearConfigs();

  // Get all custom configs
  $configs = $agent->getConfigs();
  ```
</CodeGroup>

### Usage Example

```php theme={null}
$agent = MyAgent::for('chat-123')
    ->withConfigs([
        'custom_header' => 'value',
        'timeout' => 60,
        'reasoning_effort' => 'high',
    ])
    ->message('Analyze this complex problem')
    ->respond();
```

<Info>
  Custom configurations are passed directly to the driver, allowing you to
  leverage provider-specific features without modifying the agent's core
  properties.
</Info>

## Using an Agent

There are two ways to interact with your agent: direct response or chainable methods.

### Direct Response

The simplest way is to use the `for()` method to specify a chat history name and get an immediate response:

```php theme={null}
// Using a specific chat history name
echo WeatherAgent::for('test_chat')->respond('What is the weather like?');
```

If you don't need to save / retrive chat history, because you are using "in\_memory" type or for any other reason, you can skip 'for' method:

```php theme={null}
// Using a random chat history name
echo WeatherAgent::ask('What is the weather like?');
```

### Using Chainable Methods

For more control over the interaction, you can use the chainable syntax:

<CodeGroup>
  ```php Basic Chaining theme={null}
  $response = WeatherAgent::for('test_chat')
      ->message('What is the weather like?')  // Set the message
      ->temperature(0.7)                      // Optional: Override temperature
      ->respond();                            // Get the response
  ```

  ```php Advanced Chaining theme={null}
  // Override default settings
  echo WeatherAgent::for('user_1_chat')
      ->message('What is the weather like?')
      ->withModel('gpt-4o')
      ->withTemperature(0.7)
      ->withMaxTokens(2000)
      ->withN(3)
      ->withTool(new WeatherTool())
      ->respond();
  ```
</CodeGroup>

If you don't need to maintain conversation histories, you can just replace `for` with `make` method:

```php theme={null}
echo WeatherAgent::make()
    ->message('What is the weather like?')  // Set the message
    ->temperature(0.7)                      // Optional: Override temperature
    ->respond();                            // Get the response
```

#### Ready made user message

Instead of passing a string as a message, you can build your own UserMessage instance.
It allows you to add metadata to the message, such as the user ID or request ID.
Also, using different methods associated with UserMessage instance.

```php theme={null}
$userMessage = Message::user($finalPrompt, ['userRequest' => $userRequestId]);

$response = WeatherAgent::for('test_chat')->message($userMessage)->respond();
```

<Warning>
  If you use UserMessage instance instead string, it will bypass the `prompt`
  method.
</Warning>

#### Return message

By default, `respond` method returns:

* `string` with regular request
* `array` of `string` if `$n` is greater than 1.
* `array` Associative array of defined structured output schema.

You can change the return type by using `returnMessage` method or setting `$returnMessage` property to `true`,
which will enforce `respond` method to return MessageInterface instance.

```php theme={null}
// Returns MessageInterface -> AssistantMessage instance
$response = WeatherAgent::for('test_chat')->returnMessage()->respond();
```

<Warning>
  If `returnMessage` is true and structured output is defined,
  `beforeStructuredOutput` hook will not happen, because structured output is
  not processed to array.
</Warning>

### Image input

You can pass publicly accessible image URLs to the agent as an array of strings.

```php theme={null}
$images = [
    'https://example.com/image.jpg',
    'https://example.com/image2.jpg',
];

$response = WeatherAgent::for('test_chat')->withImages($images)->respond();
```

Alternative way to pass images is to use base64 encoded data.

```php theme={null}
$imageUrls = [
    'data:image/jpeg;base64,' . base64_encode($img)
];

$response = ImageAgent::for('test')->withImages($imageUrls)->respond("Analyze images");
```

<Note>
  Base64 image input Contributed by [havspect](https://github.com/havspect) in
  [issue #74](https://github.com/MaestroError/LarAgent/issues/74).
</Note>

### Audio input

You can pass base64 encoded audio data to the agent as an array of arrays containing the `format` and `data`.
Supported formats by OpenAI: "wav", "mp3", "ogg", "flac", "m4a", "webm"

```php theme={null}
$audios = [
    [
        'format' => 'mp3',
        'data' => $base64Audio
    ]
];

echo WeatherAgent::for('test_chat')->withAudios($audios)->respond();
```

## Agent Mutators Reference

Here are some chainable methods to modify the agent's behavior on the fly:

<AccordionGroup>
  <Accordion title="message() - Set the message">
    ```php theme={null}
    /**
     * Set the message for the agent to process
     */
    public function message(string|UserMessage $message);
    ```

    Sets the message that will be sent to the AI model.

    ```php theme={null}
    // Example
    $agent = WeatherAgent::for('test_chat');
    $agent->message('What is the weather like today?')->respond();
    ```
  </Accordion>

  <Accordion title="withImages() - Add images">
    ```php theme={null}
    /**
     * Add images to the agent's input (message)
     * @param array $imageUrls Array of image URLs
     */
    public function withImages(array $imageUrls);
    ```

    Adds images to the message for multimodal models.

    ```php theme={null}
    // Example
    $agent->message('What's in this image?')
          ->withImages(['https://example.com/image.jpg'])
          ->respond();
    ```
  </Accordion>

  <Accordion title="withAudios() - Add audios">
    ```php theme={null}
    /**
     * Add audios to the agent's input (message)
     * Array of arrays: ['data' => 'base64', 'format' => 'wav']
     * Possible formats: "wav", "mp3", "ogg", "flac", "m4a", "webm"
     * @param array $audioStrings Array of audio data
     */
    public function withAudios(array $audioStrings);
    ```

    Adds audios to the message, use for multimodal models.

    ```php theme={null}
    // Example
      $audios = [
          [
              'format' => 'mp3',
              'data' => $base64Audio
          ]
      ];
    $agent->message('What's in this audio?')
          ->withAudios($audios)
          ->respond();
    ```
  </Accordion>

  <Accordion title="withModel() - Change model">
    ```php theme={null}
    /**
     * Decide model dynamically in your controller
     * @param string $model Model identifier (e.g., 'gpt-4o', 'gpt-3.5-turbo')
     */
    public function withModel(string $model);
    ```

    Overrides the default model for this specific call.

    ```php theme={null}
    // Example
    $agent->message('Complex question')
          ->withModel('gpt-4o')
          ->respond();
    ```
  </Accordion>

  <Accordion title="addMessage() - Add custom message">
    ```php theme={null}
    /**
     * @param MessageInterface 
     */
    public function addMessage(MessageInterface $message);
    ```

    Adds a custom message to the chat history. MessageInterface: Easily created with Message class: `Message::system('Your message here')`
    Use with caution, as it is added directly to the chat history and keep in mind that history needs to keep certain structure defined by openai.

    ```php theme={null}
    // Example
    use LarAgent\Message;

    $agent->addMessage(Message::system('Remember to be concise'))
          ->message('Explain quantum computing')
          ->respond();
    ```
  </Accordion>

  <Accordion title="clear() - Clear history">
    ```php theme={null}
    public function clear();
    ```

    Clear the chat history. This removes all messages from the chat history

    ```php theme={null}
    // Example
    $agent->clear()->message("Let's start fresh")->respond();
    ```
  </Accordion>

  <Accordion title="setChatHistory() - Change history">
    ```php theme={null}
    /**
     * Set other chat history instance
     */
    public function setChatHistory(ChatHistoryInterface $chatHistory);
    ```

    Replaces the current chat history with a different instance.

    ```php theme={null}
    // Example
    $newHistory = new CacheChatHistory('backup-chat');
    $agent->setChatHistory($newHistory)->respond('Continue from backup');
    ```
  </Accordion>

  <Accordion title="withTool() - Add tool">
    ```php theme={null}
    /**
     * Add tool to the agent's registered tools
     */
    public function withTool(ToolInterface $tool);
    ```

    Adds a tool for this specific call.

    ```php theme={null}
    // Example
    $weatherTool = new WeatherTool();
    $agent->withTool($weatherTool)
          ->message("What's the weather in New York?")
          ->respond();
    ```
  </Accordion>

  <Accordion title="removeTool() - Remove tool">
    ```php theme={null}
    /**
     * Remove tool for this specific call
     */
    public function removeTool(string $name);
    ```

    Removes a tool for this specific call.

    ```php theme={null}
    // Example
    $agent->removeTool('get_weather')
          ->message('Tell me a story without checking the weather')
          ->respond();
    ```
  </Accordion>

  <Accordion title="temperature() - Adjust creativity">
    ```php theme={null}
    /**
     * Override the temperature for this specific call
     */
    public function temperature(float $temp);
    ```

    Controls the randomness of the response (0.0 for focused, 2.0 for creative).

    ```php theme={null}
    // Example
    $agent->temperature(1.5)  // More creative response
          ->message('Write a poem about AI')
          ->respond();
    ```
  </Accordion>
</AccordionGroup>

## Agent Accessors Reference

You can access the agent's properties using these methods on an instance of the agent:

<AccordionGroup>
  <Accordion title="getChatSessionId() - Get session ID">
    ```php theme={null}
    /**
     * Get the current chat session ID
     * String like "[AGENT_NAME]_[MODEL_NAME]_[CHAT_NAME]"
     * CHAT_NAME is defined by "for" method
     * Example: WeatherAgent_gtp-4o-mini_test-chat
     */
    public function getChatSessionId(): string;
    ```

    Returns the unique identifier for the current chat session.

    ```php theme={null}
    // Example
    $sessionId = $agent->getChatSessionId();
    // Returns: "WeatherAgent_gtp-4o-mini_user-123"
    ```
  </Accordion>

  <Accordion title="getProviderName() - Get provider">
    ```php theme={null}
    /**
     * Returns the provider name
     */
    public function getProviderName(): string;
    ```

    Returns the name of the AI provider being used.

    ```php theme={null}
    // Example
    $provider = $agent->getProviderName();
    // Returns: "openai" or other provider name
    ```
  </Accordion>

  <Accordion title="getTools() - Get tools">
    ```php theme={null}
    /**
     * Returns an array of registered tools
     */
    public function getTools(): array;
    ```

    Returns all tools registered with the agent.

    ```php theme={null}
    // Example
    $tools = $agent->getTools();
    foreach ($tools as $tool) {
        echo $tool->getName() . "\n";
    }
    ```
  </Accordion>

  <Accordion title="chatHistory() - Get history">
    ```php theme={null}
    /**
     * Returns current chat history instance
     */
    public function chatHistory(): ChatHistoryInterface;
    ```

    Returns the current chat history instance.

    ```php theme={null}
    // Example
    $history = $agent->chatHistory();
    $messageCount = $history->count();
    ```
  </Accordion>

  <Accordion title="currentMessage() - Get current message">
    ```php theme={null}
    /**
     * Returns the current message
     */
    public function currentMessage(): ?string;
    ```

    Returns the message currently being processed.

    ```php theme={null}
    // Example
    $message = $agent->currentMessage();
    if ($message) {
        echo "Processing: " . $message;
    }
    ```
  </Accordion>

  <Accordion title="lastMessage() - Get last message">
    ```php theme={null}
    /**
     * Returns the last message
     */
    public function lastMessage(): ?MessageInterface;
    ```

    Returns the last message in the chat history.

    ```php theme={null}
    // Example
    $lastMessage = $agent->lastMessage();
    if ($lastMessage) {
        echo "Last message role: " . $lastMessage->getRole();
        echo "Last message content: " . $lastMessage->getContent();
    }
    ```
  </Accordion>

  <Accordion title="getChatKeys() - Get all chat keys">
    ```php theme={null}
    /**
     * Get all chat keys associated with this agent class
     */
    public function getChatKeys(): array;
    ```

    Returns all chat keys associated with this agent class.

    ```php theme={null}
    // Example
    $chatKeys = $agent->getChatKeys();
    // Returns: ["user_1_chat", "user_2_chat", ...]

    // You can use this to list all active conversations
    foreach ($chatKeys as $key) {
        echo "Active chat: " . $key . "\n";
    }
    ```
  </Accordion>

  {" "}

  <Accordion title="getModalities() - Get modalities">
    ````php /** * Get all modalities associated with this agent class */ public theme={null}
    function getModalities(): array; ``` Returns all modalities associated with
    this agent class. ```php // Example $modalities = $agent->getModalities(); //
    Returns: ["text", "image", "audio"] ```
    </Accordion>

    <Accordion title="getAudio() - Get audio">
    ```php
    /**
     * Get all audio associated with this agent class
     */
    public function getAudio(): ?array;
    ````

    Returns all audio associated with this agent class.

    ```php theme={null}
    // Example
    $audio = $agent->getAudio();
    // Returns: null or array of audio data containing arrays of format and data
    // [
    //     [
    //         'format' => 'mp3',
    //         'data' => $base64Audio
    //     ]
    // ]
    ```
  </Accordion>
</AccordionGroup>

## Example Configuration

```php theme={null}
class WeatherAgent extends Agent
{
    protected $model = 'gpt-4o';
    protected $history = 'session';
    protected $temperature = 0.7;

    public function instructions()
    {
        return "You are a weather expert assistant. Provide accurate weather information.";
    }

    public function prompt(string $message)
    {
        return "Weather query: " . $message;
    }
}
```
