raunen

Sub-agents

The model can delegate a self-contained piece of investigation with the task tool. The sub-agent gets its own empty context, does the work, and returns only its final answer.

delegation
  โ—† task  find where the read tool is defined
      โบ bash  grep -rn "read" internal/tools
        โ†ณ 12 lines
      โบ read  internal/tools/tools.go
        โ†ณ 300 lines
    โ†ณ returned 180 chars after 3 steps

  The read tool is defined in internal/tools/tools.go
  and returns the file with line numbers.

What they buy

Room, first. A sub-agent spends its own window reading whatever it needs and hands back a short answer. The main conversation pays for the answer instead of for everything that produced it โ€” which is the difference between finishing a question and running out of context halfway through it.

Then time. When the model delegates more than one task in a turn, the siblings run concurrently. A sub-agent spends nearly all of its time waiting on a model rather than on your machine, so three against a hosted endpoint finish in roughly the time of the slowest instead of the sum.

Against a single local model there is nothing to win โ€” one GPU serves one request at a time โ€” but nothing to lose either: the requests queue at the server rather than in raunen.

What stays sequential

Only delegated tasks run in parallel. Ordinary tools do not: two edits racing on one file, or a build racing a write, is a worse failure than any saving is worth. Results are appended in the order the model asked for them however they finish, because a tool result that does not follow its call is rejected outright.

Approvals queue too. In accept edits mode, two children reaching a mutating tool at the same moment would otherwise issue two prompts, and a single y would land on whichever asked last โ€” approving something you were never shown.

Watching them

Their steps do not go into the transcript: you asked for an answer, not for a record of how it was found. While they run, the status row under the input says so.

status row
โ—† โ น 3 sub-agents ยท 15 steps  ctrl+o to watch

ctrl+o opens a panel on the first, pressing it again steps to the next, and the press after the last puts the panel away.

ctrl+o
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ โ—† โ น working on  search the agent package  2/3  โ”‚
โ”‚ โบ grep  dispatch internal/agent                  โ”‚
โ”‚   โ†ณ 7 matches                                    โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

A sub-agent nobody is watching costs no rows at all, so the transcript keeps its height whether one is running or three.

Talking while they work

Delegating long work is only worth it if you can carry on. Press enter while an answer is still arriving and the new question is answered beside it rather than queued behind it.

It cannot join the turn already running โ€” that one is blocked on a tool result it asked for โ€” so it gets a fork of the conversation: the same tools, everything said up to that moment, and its own transcript to answer into. The exchange is folded back when it finishes, so the conversation ends up holding every turn even though they were answered side by side.

Two answers arriving into one transcript have to be readable apart, so once a second turn starts every line carries a gutter mark naming the turn it belongs to โ€” by shape as well as colour, so a screenshot in black and white still reads.

two turns at once
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 14:02
โ”ƒ โ–Œ summarise every file in internal/

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 14:02
โ”† โ–Œ meanwhile, what does vcs.Branch do?

โ”† It shells out to git rev-parse.
โ”ƒ   โบ read  internal/ui/markdown.go

esc cancels the newest turn, so a question asked by mistake can be taken back without losing the long piece of work still running underneath it. ctrl+c stops everything. The commands that rewrite the conversation โ€” /compact, /clear, /resume โ€” wait for it to be quiet, since there would be nothing coherent to rewrite otherwise.

Bounds

  • They cannot delegate. A sub-agent simply does not have the task tool, so recursion is prevented structurally rather than by a depth counter.
  • They inherit the mode. Whatever a child does is gated by the same rules as the caller, so a sub-agent's edits are approved in the same place as any other.
  • They are bounded more tightly than a main turn โ€” 16 steps. A child that wanders is worse than one that gives up: the caller is waiting.
  • They share the health tracker with their caller, so what one learns about a failing endpoint spares the others from finding out again.

Turning them off

They cost one more tool schema on every request, which is worth having back on a very small window:

config.json
  "subagents": false