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

# avatar.tools.base

Tool contracts: result shape, definition, registry, and runtime (§10).

Tools are narrow, typed, and self-describing. The runtime validates every call
(known name, well-formed input) before executing; model-correctable errors come
back as `ToolResult(success=False, error=...)` — recoverable feedback for the
model, never an exception thrown at the loop (§10 retry semantics).

## Classes

### `ToolDefinition`

A registered tool: its schema, handler, the phases it is active in, and tier (§10).

`paths` self-declares which of the tool's *validated* inputs are filesystem
paths (§11, Phase 2.5). The permission gate runs confinement + the sensitive-path
denylist over them centrally, so the policy can't drift across tools. The default
is a pass-through (no paths) — only path-bearing tools override it.

```python theme={null}
ToolDefinition(name: str, description: str, input_model: type[BaseModel], handler: Callable[[Any, RunDeps], ToolResult], phases: frozenset[str], permission_tier: int = 0, paths: Callable[[Any], Sequence[str]] = <function ToolDefinition.<lambda>>) -> None
```

#### `ToolDefinition.paths(_args)`

*No description.*

### `ToolRegistry`

The set of available tools, queryable by name and by active phase (§10).

```python theme={null}
ToolRegistry() -> None
```

#### `ToolRegistry.active_for_phase(self, phase: str) -> list[ToolDefinition]`

Return the tools enabled in the given phase (§10/§21 capability groups).

Args:
phase: The phase to filter active tools by.

Returns:
The tool definitions whose `phases` include `phase`.

#### `ToolRegistry.admitted_for(self, phase: str, task_kind: str) -> list[ToolDefinition]`

Return the tools the runner will admit in `phase` for `task_kind` (§2.6).

Like `active_for_phase`, but also includes the edit-intent bootstrap, so the
model is advertised *exactly* what the runner's gate would let it execute —
notably `str_replace` from `investigating` on an edit task.

Args:
phase: The phase to filter by.
task\_kind: The task's kind, gating the edit-intent bootstrap.

Returns:
The tool definitions admitted in `phase` for `task_kind`.

#### `ToolRegistry.get(self, name: str) -> ToolDefinition | None`

Return the tool registered under `name`, or None if unknown.

Args:
name: The tool name to look up.

Returns:
The matching `ToolDefinition`, or None if no tool is registered under `name`.

#### `ToolRegistry.register(self, tool: ToolDefinition) -> None`

Add (or replace) a tool definition by name.

Args:
tool: The tool definition to register, keyed by its `name`.

### `ToolResult`

The typed outcome of one tool call; the model only ever sees `content` (§10).

```python theme={null}
ToolResult(*, tool_name: str, success: bool, content: str = '', summary: str = '', error: str | None = None, files_read: list[str] = <factory>, files_changed: list[str] = <factory>, terminate: bool = False) -> None
```

**Fields**

| Field           | Type        | Required |    |
| --------------- | ----------- | -------- | -- |
| `tool_name`     | `str`       | yes      |    |
| `success`       | `bool`      | yes      |    |
| `content`       | `str`       | no       |    |
| `summary`       | `str`       | no       |    |
| `error`         | \`str       | None\`   | no |
| `files_read`    | `list[str]` | no       |    |
| `files_changed` | `list[str]` | no       |    |
| `terminate`     | `bool`      | no       |    |

### `ToolRuntime`

Validates and dispatches tool calls; never raises into the loop (§10).

Args:
registry: The registry to resolve tool calls against.
deps: The run-scoped `RunDeps` passed to every handler.

```python theme={null}
ToolRuntime(registry: ToolRegistry, deps: RunDeps) -> None
```

#### `ToolRuntime.execute(self, name: str, raw_input: dict) -> ToolResult`

Resolve, validate, and run a tool call; errors return as a failed `ToolResult`.

Args:
name: The registered name of the tool to invoke.
raw\_input: The unvalidated call arguments, validated against the tool's input model.

Returns:
The handler's `ToolResult`, or a failed one for an unknown name, invalid input,
or a handler that raised (isolated so a buggy tool never crashes the run).

## Functions

### `admits_transient_edit(task_kind: str, tool: ToolDefinition) -> bool`

Whether `tool` is admitted as a transient edit in an investigate task (ADR-0005).

Investigation sometimes *instruments*: add a debug print, run, observe, revert.
Tier-1 mutation is therefore legal in `investigate` tasks — the enforcement point is
the verifier's unchanged net-zero-diff contract (`no_unintended_diff`: the tree must
match the pinned baseline at verification), detection where prevention used to be.
An explicit rule, distinct from `is_edit_intent`, so the edit-intent phase bootstrap
stays edit-kinds-only and investigate's phase flow is unchanged.

Args:
task\_kind: The task's kind; only `investigate` rides this rule.
tool: The resolved tool definition.

Returns:
True when `tool` is the mutating tier (1) and the task is an investigation.

### `is_edit_intent(task_kind: str, tool: ToolDefinition) -> bool`

Whether `tool` is the model's edit intent: the mutating tier on an edit-shaped task.

Deliberately edit-kinds-only: an investigate task's transient edits (ADR-0005) are
admitted by `admits_transient_edit` instead, so they never ride this bootstrap and
never advance the phase.

Args:
task\_kind: The task's kind (only `edit`/`test_only` permit mutation, §7).
tool: The resolved tool definition.

Returns:
True when `tool` is the mutating tool (tier 1) and the task kind permits edits.

### `phase_admits_tool(phase: str, task_kind: str, tool: ToolDefinition) -> bool`

Whether `tool` may run *and* be advertised in `phase` for `task_kind` (§2.6).

The single source of truth shared by the runner's gate (what may execute) and the
`ContextBuilder` (what the model is told it may call) — keeping them in lockstep so
the model never loops blind on a tool the runner would have admitted. True when the
tool is active in the phase, or it is the edit-intent tool reachable from
`investigating` via the bootstrap exception, or it is a transient edit in an
investigate task (ADR-0005).

Args:
phase: The current control phase.
task\_kind: The task's kind, gating the edit-intent bootstrap and the
transient-edit rule.
tool: The resolved tool definition.

Returns:
True if `phase` is in the tool's phases, or `tool` is an edit-intent tool on an
edit-shaped task (the bootstrap that surfaces `str_replace` from `investigating`),
or `tool` is tier-1 on an investigate task (transient instrumentation, ADR-0005).
The escalation tool is the one *narrowing* rule: investigate-only (ADR-0048).
