# EONYX subagents: delegating work to the task tool


A **subagent** is a separate instance of the agent that EONYX hands part of the work to. It performs the task in its own context window, with a reduced set of tools, and returns only the result into the main conversation. This keeps the main context clean: the details of the research don't clutter the dialog. This article covers the `task` tool, the full list of built-in tools, and how the agent loop works.

<!--more-->

## The task tool

Delegation in EONYX is a single tool, `task`. The model calls it when something has to be researched in the codebase without bloating the main conversation:

```text
● task  find every place the Store interface is used
  ⎿ 12 call sites in 4 packages: session/jsonl.go, agent/agent.go, …
```

There is one argument — `description`: a self-contained statement of the task with all the context it needs. The subagent **cannot ask clarifying questions** — it works autonomously and returns a finished answer.

### What a subagent can and can't do

The child agent gets only the **read tools**: `read`, `ls`, `glob`, `grep`, `fetch`. It cannot write files, run commands, or delegate any further:

- **Context isolation.** The subagent will read dozens of files and return a short summary into the main conversation — the main context doesn't get filled up.
- **Safety.** Read-only: a delegated task will not change the project.
- **No recursion.** The subagent's tool set has no `task` tool, so subagents don't spawn subagents.

The child agent inherits the same model and step limit (`max_steps`) as the main one, and works with the same system prompt plus a note about its role: "you are a subagent, you work autonomously with read-only tools, at the end give a concise self-contained answer".

{{< admonition type="tip" title="When this is useful" >}}
- **Parallel research** — you hand "figure out how authorization works" to `task` while you keep going on the main line yourself.
- **Broad searches** — "find every call of the deprecated API" returns a list instead of hundreds of lines in the context.
- **Reconnaissance before an edit** — the subagent collects the facts, the main agent makes the changes based on them.
{{< /admonition >}}

## Built-in tools

Besides `task`, `load_skill`, and the MCP tools, EONYX registers **15 standard tools**. The registration order is the order in which they are offered to the model.

### Files

| Tool         | What it does                                                                |
| ------------ | --------------------------------------------------------------------------- |
| `read`       | reads a text file; optionally with a line offset and a limit                |
| `write`      | writes a file, creating directories and overwriting; `dry_run` shows a diff |
| `edit`       | replaces an exact substring; `replace_all` — every occurrence, `dry_run` — a preview |
| `multi_edit` | several replacements in one file atomically: either all of them, or the file is untouched |
| `ls`         | lists the contents of a directory (directories with a `/`)                  |
| `picker`     | navigation through the project tree — browse and pick paths                 |

### Search

| Tool       | What it does                                                     |
| ---------- | ---------------------------------------------------------------- |
| `glob`     | finds files by a glob pattern (`**` — recursive)                 |
| `grep`     | searches contents with a regex, `path:line:text`; skips binaries and `.git` |

### Execution and network

| Tool       | What it does                                                              |
| ---------- | ----------------------------------------------------------------------- |
| `bash`     | a command in a persistent shell session; the output is stdout+stderr, the exit code is in the text |
| `fetch`    | downloads a web page: HTML → markdown, other text as is, binaries are rejected |

### Git

| Tool         | What it does                                                  |
| ------------ | ----------------------------------------------------------- |
| `git_status` | the working tree status (`git status --short --branch`)     |
| `git_diff`   | the diff of uncommitted changes (or `staged=true`)          |
| `git_log`    | recent commits, one per line (`git log --oneline`)          |
| `git_commit` | a commit with a message; `all=true` stages tracked files first |

### Organizing the work

| Tool         | What it does                                                                  |
| ------------ | --------------------------------------------------------------------------- |
| `todo_write` | keeps a task list for multi-step work; the whole list is passed at once      |

{{< admonition type="note" title="Tool errors are data" >}}
A tool error is returned to the model as a result with an error flag, not as a fatal failure. That way the model sees what went wrong and adapts — fixing the path and retrying, for example.
{{< /admonition >}}

### An in-process shell

The `bash` tool (and the hooks) work through the embedded `mvdan.cc/sh` interpreter — **a system bash is not needed**, everything is cross-platform, Windows included. A single shell session **keeps the working directory and the exported variables** between calls: `cd` and `export` persist. A small set of dangerous commands is blocked at the policy level: `shutdown`, `reboot`, `halt`, `poweroff`, `mkfs`, `init`.

## How the agent loop works

A single agent turn (`Send`) is a loop of up to `max_steps` iterations (50 by default):

1. The user message is recorded.
2. The model's response is streamed (text + tool calls).
3. If there are no tool calls — this is the final answer, the turn is over.
4. Otherwise the tools are executed, the results are returned to the model, and the loop repeats.

A couple of optimizations and guarantees:

- **Parallel reads.** Consecutive read-only calls (`read`, `ls`, `glob`, `grep`, `git_status`, `git_diff`, `git_log`) are executed in parallel; everything else runs sequentially. Results are always returned in the original order.
- **The write is the source of truth.** Every new message is saved into the session; a save error aborts the turn.
- **A denial doesn't break the conversation.** A tool blocked by the gate is returned to the model as an error, not as a crash.
- **The step limit.** If `max_steps` is hit without a final answer, EONYX says so honestly and offers to raise the limit (in headless mode this is exit code `5`).

## Summary

{{< admonition type="abstract" title="Cheat sheet" >}}
- **task** — delegates a research task to a subagent with read-only tools (`read`, `ls`, `glob`, `grep`, `fetch`); returns a condensed result without cluttering the context.
- **No recursion** — the subagent has no `task`, so there will be no nesting; it inherits the parent's model and `max_steps`.
- **15 tools** — files (read/write/edit/multi_edit/ls/picker), search (glob/grep), execution (bash/fetch), git (status/diff/log/commit), tasks (todo_write).
- **An in-process shell** — `mvdan/sh`, no system bash; keeps cwd/env; blocks shutdown/reboot/mkfs and the like.
- **The loop** — up to `max_steps` rounds; parallel reads, the write as the source of truth, errors as data.
{{< /admonition >}}


