# `SuperPi.Tools`
[🔗](https://github.com/oleksandr/super-pi-beam/blob/v0.1.0/lib/super_pi/tools.ex#L1)

Built-in 3-Channel Tool Suite, 5 `ToolExposure` Modes, and Deferred `tool_search` Registry (`Step 8`).

## 3-Channel Tool Results (`Decision 06`)
Every tool execution returns a normalized map with:
- `"output"` — Concise string sent to the LLM context (`pi.message` role `tool`).
- `"structured_output"` — Typed JSON map for programmatic consumers and Codemode scripts.
- `"details"` — Rich metadata (`diff`, `line_count`, `spilled_path`, `duration_ms`) for UI inspectors.
- `"control"` (optional) — Control directives (`%{"add_tools" => [...]}`, `%{"handoff" => ...}`, `%{"terminate" => true}`).

## 5 `ToolExposure` Modes
- `:direct` — Exposed in the active LLM tool declarations and callable from Codemode.
- `:model_only` — Exposed in the LLM tool declarations only (e.g., `tool_search`).
- `:codemode` — Callable inside Codemode scripts only; omitted from top-level LLM declarations to save tokens.
- `:deferred` — Omitted from initial LLM declarations; discovered and activated dynamically via `tool_search`.
- `:hidden` — Internal/disabled tool.

# `exposure`

```elixir
@type exposure() :: :direct | :model_only | :codemode | :deferred | :hidden
```

# `active_llm_tools`

Returns all tools that should be declared in the initial LLM request (`:direct` and `:model_only`).

# `effect_vocabulary`

```elixir
@spec effect_vocabulary() :: [String.t()]
```

The effect vocabulary: `read`, `fs_write`, `exec`, `net_read`, `net_write`, `state_write`.

# `effects`

```elixir
@spec effects(String.t(), map() | nil) :: [String.t()] | nil
```

Effects of a tool: what a call changes or reaches.

| Effect | Meaning |
|---|---|
| `read` | Reads the workspace or answers from existing state. Changes nothing. |
| `fs_write` | Writes workspace files. |
| `exec` | Runs a command. |
| `net_read` | Reads from the network (a GET). |
| `net_write` | Sends data out or changes a remote system. |
| `state_write` | Changes Super-Pi state (artifacts, todos, memory, schedules), not the workspace. |

A tool states its effects in an `"effects"` list on its spec. The lookup order is: the spec in
`agent_cfg["tools"]` (plugin tools live there), the catalog, then the table for built-in tools.
`nil` means the tool is unknown, which every policy treats as the most dangerous kind.

# `ensure_catalog_ets!`

# `execute`

Executes one of the 7 built-in tools (`read`, `write`, `edit`, `bash`, `grep`, `find`, `ls`) or `tool_search`.
Supports common tool name aliases and argument variations with defensive parameter extraction.

# `not_implemented_result`

```elixir
@spec not_implemented_result(String.t()) :: map()
```

Builds the error result for a tool that is registered but has no implementation.

A tool that cannot do its job must report an error. It must never report success.

# `register_tool!`

Registers a tool specification in the ETS catalog with one of the 5 `ToolExposure` modes.

# `tool_entry`

The catalog form of a tool spec: one `"parameters"` key for the schema, whatever the source called it.

# `tool_search`

Searches `:deferred` (and `:direct`) tools by keyword query (`tool_search`) and returns matching
tool schemas along with a `control: %{"add_tools" => matches}` directive that activates them
in `pi.agent` (`Decision 06`).

---

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