> ## 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.

# Tools

> Tools extend your agent's capabilities, allowing it to perform tasks like sending messages, making API calls, or executing commands.

<Note>
  Tools (also known as function calling) allow your AI agents to interact with
  external systems, APIs, and services, greatly expanding their capabilities
  beyond simple text generation.
</Note>

## Tool Configuration

Tools in LarAgent can be configured using these properties in your Agent class:

```php theme={null}
/** @var bool - Controls whether tools can be executed in parallel */
protected $parallelToolCalls;

/** @var array - List of tool classes to be registered with the agent */
protected $tools = [];
```

<Tip>
  You can set `$parallelToolCalls` to `null` if you want to remove it from the
  request, as some models (o1) do not support parallel tool calls.
</Tip>

## Creating Tools

There are three ways to create and register tools in your agent:

<CardGroup cols={3}>
  <Card title="#[Tool] Attribute" icon="wand-magic-sparkles" href="#1-using-the-tool-attribute">
    Best for service-based or static tools specific to a single agent.
  </Card>

  <Card title="registerTools Method" icon="code" href="#2-using-the-registerTools-method">
    Ideal for dynamically creating tools based on runtime conditions or user
    state.
  </Card>

  <Card title="Tool Classes" icon="puzzle-piece" href="#3-using-tool-classes">
    Perfect for complex tools that may be reused across multiple agents or
    require extensive logic.
  </Card>
</CardGroup>

### 1. Using the Tool Attribute

The simplest approach is using the `#[Tool]` attribute to transform your agent's methods into tools:

<CodeGroup>
  ```php Basic Tool theme={null}
  use LarAgent\Attributes\Tool;

  #[Tool('Get the current weather in a given location')]
  public function weatherTool($location, $unit = 'celsius')
  {
      return 'The weather in '.$location.' is '.'20'.' degrees '.$unit;
  }

  ```

  ```php Tool with Parameter Descriptions theme={null}
  use LarAgent\Attributes\Tool;

  #[Tool(
      'Get the current weather in a given location',
      [
          'location' => 'The city and state, e.g. San Francisco, CA',
          'unit' => 'Unit of temperature'
      ]
  )]
  public function weatherTool($location, $unit = 'celsius')
  {
      return 'The weather in '.$location.' is '.'20'.' degrees '.$unit;
  }
  ```
</CodeGroup>

The agent will automatically register the tool with the given description and extract method information, including parameter names and types.

<Warning>
  You can add tools without properties (= Method without parameters)
</Warning>

#### Using Enum Types with Tools

You can use PHP Enums to provide the AI with a specific set of options to choose from, as well as provide separate descriptions for each property (argument):

```php theme={null}
// app/Enums/Unit.php
namespace App\Enums;

enum Unit: string
{
    case CELSIUS = 'celsius';
    case FAHRENHEIT = 'fahrenheit';
}

// app/AiAgents/WeatherAgent.php
use LarAgent\Attributes\Tool;
use App\Enums\Unit;

// ...

#[Tool(
    'Get the current weather in a given location',
    [
        'unit' => 'Unit of temperature',
        'location' => 'The city and state, e.g. San Francisco, CA'
    ]
)]
public static function weatherToolForNewYork(Unit $unit, $location = 'New York')
{
    return WeatherService::getWeather($location, $unit->value);
}
```

<Tip>
  It's recommended to use the `#[Tool]` attribute with static methods if there's
  no need for the agent instance (`$this`).
</Tip>

### 2. Using the registerTools Method

This method allows you to programmatically create and register tools using the `LarAgent\Tool` class:

```php theme={null}
use LarAgent\Tool;

public function registerTools()
{
    $user = auth()->user();
    return [
        Tool::create("user_location", "Returns user's current location")
             ->setCallback(function () use ($user) {
                  return $user->location()->city;
             }),
        Tool::create("get_current_weather", "Returns the current weather in a given location")
             ->addProperty("location", "string", "The city and state, e.g. San Francisco, CA")
             ->setCallback("getWeather"),
    ];
}
```

<Tip>
  `setCallback` method accepts any [php
  callable](https://www.php.net/manual/en/language.types.callable.php), such as
  a function name, a closure, or a class method.
</Tip>

### 3. Using Tool Classes

For complex tools, you can create dedicated tool classes and add them to the `$tools` property:

```php theme={null}
protected $tools = [
    WeatherTool::class,
    LocationTool::class
];
```

#### Example Tool Class

<Note>Tool creation artisan command is comming soon...</Note>

```php theme={null}
class WeatherTool extends LarAgent\Tool
{
    protected string $name = 'get_current_weather';

    protected string $description = 'Get the current weather in a given location';

    protected array $properties = [
        'location' => [
            'type' => 'string',
            'description' => 'The city and state, e.g. San Francisco, CA',
        ],
        'unit' => [
            'type' => 'string',
            'description' => 'The unit of temperature',
            'enum' => ['celsius', 'fahrenheit'],
        ],
    ];

    protected array $required = ['location'];

    protected array $metaData = ['sent_at' => '2024-01-01'];

    public function execute(array $input): mixed
    {
        // Call the weather API
        return 'The weather in '.$input['location'].' is '.rand(10, 60).' degrees '.$input['unit'];
    }
}
```

## Tool choice

You can set the tool choice for your agent using the following methods:

```php theme={null}
// Disable tools for this specific call:
WeatherAgent::for('test_chat')->toolNone()->respond('What is my name?');

// Require at least 1 tool call for this specific call:
WeatherAgent::for('test_chat')->toolRequired()->respond('Who is president of US?');

// Force specific tool to be used for this specific call:
WeatherAgent::for('test_chat')->forceTool('weatherToolForNewYork')->respond('What is weather in New York?');
```

<Note>
  `forceTool` method requires tool's name as a parameter.
</Note>

<Warning>
  `toolRequired` & `forceTool` is set only at the first call, after that it will automatically switched to 'auto' avoiding infinite loop.
</Warning>

If tools are registered, default value is 'auto', otherwise it's 'none'.

```php theme={null}
protected $toolChoice = 'auto';
```

## Phantom Tools 👻

Phantom Tools are dynamically registered tools that are not executed on the LarAgent side, but instead returns [`ToolCallMessage`](https://github.com/MaestroError/LarAgent/blob/ed4f0611f98ca93815443da3de6c987f0ee88450/src/Messages/ToolCallMessage.php#L7)

<CodeGroup>
  ```php at runtime theme={null}
  use LarAgent\PhantomTool;

  // ...

  // Create a Phantom tool with properties and custom callback
  $PhantomTool = PhantomTool::create('Phantom_tool', 'Get the current weather in a given location')
              ->addProperty('location', 'string', 'The city and state, e.g. San Francisco, CA')
              ->setRequired('location')
              ->setCallback("PhantomTool");

  // Register the Phantom tool with the agent
  $agent->withTool($PhantomTool);
  ```

  ```php in Agent class theme={null}
  use LarAgent\PhantomTool;

  // ...

  public function registerTools()
  {
      return [
          PhantomTool::create('Phantom_tool', 'Get the current weather in a given location')
              ->addProperty('location', 'string', 'The city and state, e.g. San Francisco, CA')
              ->setRequired('location')
              ->setCallback("PhantomTool"),
      ];
  }
  ```
</CodeGroup>

Phantom Tools are particularly useful when:

* You need to integrate with external services dynamically
* You want to handle tool execution outside of LarAgent
* You need to make tool registration/execution available from API

<Tip>
  Phantom Tools follow the same interface as regular tools but instead of automatical execution, they return [`ToolCallMessage`](https://github.com/MaestroError/LarAgent/blob/ed4f0611f98ca93815443da3de6c987f0ee88450/src/Messages/ToolCallMessage.php#L7) instance, providing more flexibility
  in terms of when and how they are executed.
</Tip>

## Chainable Tool Methods

You can dynamically add or remove tools during runtime using `withTool` and `removeTool` methods:

**Add tool with instance**

```php theme={null}
$tool = Tool::create('test_tool', 'Test tool')->setCallback(fn () => 'test');
$agent->withTool($tool);
```

**Add tool with predefined tool class**

```php theme={null}
$agent->withTool(WeatherTool::class);
```

**Remove tool by name**

```php theme={null}
$agent->removeTool('get_current_weather');
```

**Remove tool by instance**

```php theme={null}
$tool = Tool::create('test_tool', 'Test tool')->setCallback(fn () => 'test');
$agent->withTool($tool);
if (!$needsTool) {
    $agent->removeTool($tool);
}
```

**Remove tool by class name**

```php theme={null}
$agent->removeTool(WeatherTool::class);
```

**Set toolChoice property**

```php theme={null}
// @param  string|array|null  $toolChoice  Tool choice configuration
$agent->setToolChoice('none');
```

**Enable/Disable parallel tool calls**

```php theme={null}
// @param bool|null $parallel Parallel tool calls configuration
$agent->parallelToolCalls(true);
```

## Best Practices

<Check>
  **Do** create separate tool classes for complex functionality that might be
  reused
</Check>

<Check>
  **Do** provide clear, descriptive names and parameter descriptions
</Check>

<Check>
  **Do** use Enums when you need to restrict the AI to specific options
</Check>

<Icon icon="x" iconType="solid" color="red" /> **Don't** create tools with ambiguous
functionality or unclear parameter requirements

<Icon icon="x" iconType="solid" color="red" /> **Don't** expose sensitive operations
without proper validation and security checks
