Kotoba

Where to start

What Kotoba isWho she is and where she runs, in one page
InstallingOne package, two commands
First runA key, a model, her first words
The approval gateHow she asks before she acts
The two voice modesLocal voice, or the agent tunnel
The soul fileChange who she is
RoadmapWhat grows next, and what was cut on purpose

Or a section

↑↓ move openesc close124 pages
All pages

The agent11 of 15

Subagents

About 5 minutes to read

On this page

One tool, delegate, in the subagent toolset. Work mode only.

A helper is another run of the same agentic loop with an isolated conversation, a restricted toolset, and no voice. It shares the parent's session, workspace, sandbox and approval gate — so a helper that runs a command asks you, on the same card, with the same grants.


What a helper gets

Takes: goal, toolset in research | web | file | code | browser (default research), and context.

Its conversation is two messages: a short system line, and goal + context. It cannot see the parent's history, which is the point — only its summary comes back, so the parent's context stays clean.

One exception travels anyway: the parent's own user utterances. The child's conversation carries only the goal paraphrase, so every guard anchored on your own words ran blind under a helper — cronjob's repeat guard read nothing, and the one-request-one-run key came back None.

The five toolset names map to four filters. Measured, with no MCP server connected:

toolsetFilterTools the helper is offered
research, webwebweb_search, web_extract
filefileread_file, write_file, patch, search_files, web_search
codecodeexecute_code, web_search
browserbrowserask_secret, request_credential, get_credential, web_searchplus every browser__* tool once the browser MCP is connected

web_search appears in all four because a built-in is never filtered out.

The filter also matches the mcp:<name> form, or delegate(toolset='browser') would get zero browsing tools.

Each toolset picks a model role, so a code or research helper can run on its own tuned model: code → the code model, research/web → the research model, everything else → the work model. Each falls back through the chain to the companion model when unset.


Its budget

Value
Iterations12
Tool calls11
Tool timeout, as seen by the parent420 s
Nesting depth1 — the parent may spawn, a helper may not
Helpers per parent turn3 (KOTOBA_DELEGATE_LIMIT)
Running at once2 (KOTOBA_DELEGATE_CONCURRENCY)

The 11-and-12 pairing is the same arithmetic the main loop uses: the gate that withdraws every tool fires on calls >= max_tool_calls and needs one tool-less iteration after it. Passing the iteration budget alone left that gate evaluating against work mode's cap of 40 — unreachable in twelve iterations — so a helper ran out mid-chain with empty text and was reported as a failure.

The 420-second timeout is not decoration either: a helper runs a full loop with rate-limit pacing and 429 backoff per iteration, and the default 30-second tool budget killed it.

A helper that tries to nest gets: "I can't nest helpers any deeper — I'll handle this part myself."


Running several at once

When the model issues more than one delegate in one step, they are selected before anything is spawned and then run in parallel.

Selection drops a call that duplicates another in the same batch, that exactly repeats one already run this turn, or that is past the remaining budget. Spawning them all and discarding the overflow — the old order — wasted whole subagent runs and burst the token budget.

Each spawned call is announced with its own card before the parallel gather, and each card closes the moment its helper returns, not when the whole batch does. Otherwise the cards appeared minutes late, all together.

Work mode carries an explicit instruction to go wide: issue every delegate call together, in a single step, as the first action — not one at a time, and not after researching part of it yourself. And it must not delegate the final synthesis; that is hers.


What comes back

A concise summary, capped at 6,000 characters on the wire — a tighter cap cuts mid-sentence and mid-Markdown. A helper that finished with no text gets "The helper finished without a written summary."

Its sources come back too. The helper's citations are merged into the parent in a finally, so a helper that raised still hands over the real URLs it fetched. That merge is guarded, because a raise there would replace the cancellation the turn's contract depends on.

Work mode is told to use them:

"after research helpers return, you'll receive an internal note listing the REAL URLs their searches surfaced — when the deliverable is a report, cite those exact URLs … Never invent, guess, or paraphrase a URL, and never copy the note itself."


When a helper dies

This is the one case where "the tool returned a string" is not the same as "the tool worked."

delegate catches its own exception on purpose — it has a card to close and citations to merge — and hands the parent "(helper failed: …)". That is a non-empty string, so the wrapper would grade it as a success: a green tick, an executed audit row, the duplicate guard's "it is DONE" branch, and the spoken COMPLETE line over a crash.

The witness lives in the loop, not in the tool, because swallowing the exception is the tool's legitimate business. A subagent run that dies is recorded as a tool call that ran and failed.

It is not recorded as a refusal: the helper really ran, and may have written files before it died.

A cancellation is told apart from a crash. If nobody asked for the cancel (Task.cancelling() == 0), the error was raised inside the helper — and that is the only place its frames still exist, because the loop's heartbeat shields replace them with a bare cancellation on the way out.

Every frame a helper emits carries the parent run's run_id, so a helper spawned by a detached background job never draws inside an interactive turn's reply.