# `Condukt.Tool`
[🔗](https://github.com/tuist/condukt/blob/0.16.5/lib/condukt/tool.ex#L1)

Behaviour for defining tools that agents can use.

Tools are functions that agents can call to interact with the world:
reading files, running commands, making HTTP requests, etc.

## Defining a Tool

    defmodule MyApp.Tools.Weather do
      use Condukt.Tool

      @impl true
      def name, do: "get_weather"

      @impl true
      def description do
        "Gets the current weather for a location"
      end

      @impl true
      def parameters do
        %{
          type: "object",
          properties: %{
            location: %{
              type: "string",
              description: "City name, e.g. 'San Francisco, CA'"
            }
          },
          required: ["location"]
        }
      end

      @impl true
      def call(%{"location" => location}, _context) do
        case WeatherAPI.get(location) do
          {:ok, data} -> {:ok, format_weather(data)}
          {:error, reason} -> {:error, reason}
        end
      end
    end

## Tool Context

The `call/2` function receives a context map with:

- `:agent` - The agent PID
- `:agent_module` - The agent module for the session
- `:sandbox` - The active `Condukt.Sandbox` struct (use this for any
  filesystem or process-execution work)
- `:cwd` - Project working directory (kept for tools that need to refer to
  the host project root for non-sandbox concerns; tools that read/write
  files or run commands should go through `:sandbox`)
- `:secrets` - Resolved session secrets. Built-in command tools expose these
  as environment variables. Custom trusted tools can use
  `Condukt.Secrets.env/1` when they need the same values.
- `:opts` - Options passed when adding the tool to the agent

## Sandbox-aware tools

If your tool reads or writes files, or runs subprocesses, route through
`Condukt.Sandbox.read/2`, `Condukt.Sandbox.write/3`, `Condukt.Sandbox.exec/3`,
etc. Direct `File.*` or `MuonTrap.cmd/3` calls bypass the sandbox and break
the consumer's ability to swap one in (e.g. an in-memory virtual sandbox).
Tools that touch unrelated systems (HTTP APIs, databases, in-process state)
have nothing to sandbox and are unaffected.

## Parameterized Tools

Tools can be parameterized when added to an agent:

    defmodule MyApp.Tools.Database do
      use Condukt.Tool

      @impl true
      def name(opts), do: "query_#{opts[:table]}"

      @impl true
      def description(opts) do
        "Query the #{opts[:table]} table"
      end

      @impl true
      def call(args, context) do
        table = context.opts[:table]
        Repo.all(from r in table, where: ^build_where(args))
      end
    end

    # In agent:
    def tools do
      [
        {MyApp.Tools.Database, table: "users"},
        {MyApp.Tools.Database, table: "orders"}
      ]
    end

# `call`

```elixir
@callback call(args :: map(), context :: map()) :: {:ok, term()} | {:error, term()}
```

Executes the tool with the given arguments.

# `description`

```elixir
@callback description() :: String.t()
```

Returns a description of what the tool does.

# `description`
*optional* 

```elixir
@callback description(opts :: keyword()) :: String.t()
```

# `name`

```elixir
@callback name() :: String.t()
```

Returns the tool name as it will appear to the LLM.

# `name`
*optional* 

```elixir
@callback name(opts :: keyword()) :: String.t()
```

# `parameters`

```elixir
@callback parameters() :: map()
```

Returns the JSON Schema for the tool's parameters.

# `parameters`
*optional* 

```elixir
@callback parameters(opts :: keyword()) :: map()
```

# `execute`

Executes a tool by name with arguments.

# `name`

Gets the tool name for a tool spec.

# `to_spec`

Builds a tool specification for the LLM provider.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
