# EONYX subagents: delegating work to the task tool


A **subagent** is a separate instance of the agent.
EONYX hands it a slice of the work.
It runs in its own context window, with a reduced tool set, and returns only the result.
So the main conversation stays clean: the research never clutters it.

<!--more-->

## 🎯 The task tool

Delegation is one tool: `task`.
The model reaches for it when something has to be dug out of the codebase without bloating the 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 a single argument, `description`.
It must be self-contained and carry all the context.
The subagent **cannot ask a clarifying question**.
It works alone and returns a finished answer.

### What a subagent can and cannot do

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

- **Context isolation.** It reads dozens of files and returns a short summary. The main context stays small.
- **Safety.** Read-only, so a delegated task changes nothing.
- **No recursion.** Its tool set has no `task`, so subagents never spawn subagents.

The child inherits the parent's model and `max_steps`.
It gets the same system prompt plus a note about its role: work autonomously, read-only tools, finish with a concise self-contained answer.

{{< admonition type="tip" title="When this is useful" >}}
- **Parallel research.** Hand "figure out how authorization works" to `task` and keep going on the main line.
- **Broad searches.** "Find every call of the deprecated API" returns a list, not hundreds of lines of context.
- **Reconnaissance before an edit.** The subagent collects facts, the main agent acts on them.
{{< /admonition >}}

## 🧰 Built-in tools

Beyond `task`, `load_skill` and the MCP tools, EONYX registers **15 standard ones**.
Registration order is the order the model sees them in.

### 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 comes back to the model as a result with an error flag.
It is never a fatal failure.
So the model sees what went wrong and adapts, for instance by fixing the path and retrying.
{{< /admonition >}}

### An in-process shell

`bash` and the hooks run on the embedded `mvdan.cc/sh` interpreter.
**No system bash is needed.**
Everything is cross-platform, Windows included.
One shell session **keeps the working directory and the exported variables** between calls, so `cd` and `export` persist.
A few dangerous commands are blocked at policy level: `shutdown`, `reboot`, `halt`, `poweroff`, `mkfs`, `init`.

## 🔄 How the agent loop works

A single turn is a loop of up to `max_steps` rounds, 50 by default:

1. The user message is recorded.
2. The model's response streams in, text and tool calls.
3. No tool calls means this is the final answer, and the turn ends.
4. Otherwise the tools run, the results go back, and the loop repeats.

A few guarantees along the way:

- **Parallel reads.** Consecutive read-only calls run in parallel: `read`, `ls`, `glob`, `grep`, `git_status`, `git_diff`, `git_log`. Everything else is sequential. Results always return in the original order.
- **The write is the source of truth.** Every new message is saved to the session, and a save error aborts the turn.
- **A denial does not break the conversation.** A blocked tool comes back as an error, not a crash.
- **The step limit.** Hitting `max_steps` without a final answer is reported honestly, with an offer to raise the limit. Headless, that 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 >}}

