# `Rho.ToolRegistry`
[🔗](https://github.com/GenericJam/rho/blob/v0.1.0/lib/rho/tool_registry.ex#L1)

The tools the agent can call, by name, from three places:

  * the host's **core tools**, given when the registry starts (the
    `:tools` option, else `config :rho, :tools`, else
    `builtin_tools/0`), and
  * tools **registered at runtime** (`register/1`, `unregister/1`); both
    live in one ETS table owned by this process;
  * **sources** (`Rho.ToolRegistry.Source`, the `:tool_sources` option or
    `config :rho, :tool_sources`): modules asked on every call, so a
    source whose tool set changes (a generation of agent-written tools
    switching) changes what is offered at once, with nothing to
    register or unregister. This is where agent-written (Dyn) tools
    plug in.

A name in the table always wins over a source's, and an earlier source
over a later one. The loop reads the list at the start of every model
call, so a new tool is offered from the next call on.

# `builtin_tools`

```elixir
@spec builtin_tools() :: [module()]
```

rho's own tools: `read_artifact` (paging a cut tool output) and `todo`.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `core_tools`

```elixir
@spec core_tools() :: [module()]
```

The core tools the registry started with (a source's tool may not take their names).

# `list`

```elixir
@spec list() :: [module()]
```

All tool modules (the table's, then the sources'), sorted by name.

# `lookup`

```elixir
@spec lookup(String.t()) :: {:ok, module()} | :error
```

The tool module offered as `name`: the table's, else the first source's that has it.

# `register`

```elixir
@spec register(module()) :: :ok | {:error, :not_a_tool}
```

Adds `module` under its `c:Rho.Tool.name/0`, replacing a tool of that name.
`{:error, :not_a_tool}` if it doesn't implement `Rho.Tool`.

# `sources`

```elixir
@spec sources() :: [module()]
```

The registry's sources, in order (none while the registry isn't running).

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Started by `Rho.Supervisor`. Options: `:tools`, `:tool_sources` (see the moduledoc).

# `unregister`

```elixir
@spec unregister(String.t()) :: :ok
```

Removes the tool named `name` from the table (a source's tools aren't affected).

# `watch`

```elixir
@spec watch(pid(), module()) :: :ok
```

Tells every source a tool call of `module` is about to run in `pid`
(`Rho.ToolRunner` calls it), so a source can watch its own tools' calls
(crashes, timeouts) through `c:Rho.ToolRegistry.Source.watch/2`.

---

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