# Coordination Tools

Tools for subagents, schedules, checklists, questions to the user and final results.

| Tool | Description |
|---|---|
| `subagents` | `mode=invoke` runs a subtask in its own session (in-process, no HTTP); `mode=list` returns the reusable named sessions and their roles. Written to stand alone — the leg sees none of the parent conversation. **At most 3 legs run concurrently**; a 4th queues while its own timeout runs, so wide fan-outs dispatch in batches of 3. Results carry a `[subagent · <model> · session=<id> · usage: in=X out=Y cached=Z write=W]` header that rolls up into parent-session usage. Since v1.0.22 the leg's report body no longer comes back inline: it is written to `~/.config/agenvoy/download/temp-<report_name>.md` and the result is that header plus the file path, which the caller reads with `read_files` before relaying or synthesizing. `report_name` is a short kebab-case name (job + entity, e.g. `nvda-news`); a taken name gets a random suffix, and a blank one uses a random name. `self_id` reuses an existing non-temp session verbatim — it replaced `name` / `session_id` in v0.35.0 and is now required for `mode=list`, which resolves one delegated name instead of dumping every session. Since v1.1.0 `model` is required on every `mode=invoke` call — the dispatcher fallback for a blank model was removed, and `model: "auto"` (hotfix after v1.1.0) hands the choice to the dispatcher, which picks from the task as for a normal request; when `self_id` resolves to a session pinned to its own model that model runs instead, and a session left on `auto` runs the given one. Timeout `MAX_SUBAGENT_TIMEOUT_MIN` (30 min). Since v1.0.21 each leg has one job — collect, analyze, compare, review, transform or code — mapped to a work kind; since v1.1.0 the leg's tier order runs one tier lower than the dispatcher's (collect → `fetch` C>B>A>S, transform → `chat` C>B>A>S, analyze / compare / review → `work` B>A>C>S, code or high-precision → `code` A>B>C>S). The former `reason` job was split into analyze, compare and code. `model` is checked against the live registry, so models added after startup work; an unregistered or `pass`-tier name is rejected with the list of usable models. `reasoning` defaults to `auto` (the leg's session setting, else the dispatcher's pick); a value that is not a reasoning level is rejected. Legs only gather: a leg never gets `subagents`, `edit_file`, `edit_tool`, `test_tool`, `edit_skill`, `write_result`, `html_template`, any `generate_*` tool, `open_file`, `schedules`, `store_secret`, `pkg_manage`, or the TUI-only tools, and code comes back as text for the main agent to apply; `exclude_tools` adds to that set. Full dispatch protocol and model tiers → `reasoning_guide(topics=["subagent_dispatch"])` |
| `schedules` | Scheduled runs bound to a scheduler skill. `mode=list` shows what this session has queued, `mode=patch` moves an entry to a new time, `mode=remove` cancels it and trashes its skill, `mode=write` is the internal binding step of the `scheduler-skill-creator` flow. `target` is `task` (one-shot), `cron` (5-field expression), or `all` (list only). Task time formats: `+5m` / `+1h30m` (relative), `15:04` (today), `2006-01-02 15:04` (local), or RFC3339. `skill_name` carries a generated hash suffix — hand-made values always fail |
| `write_todo` | Live task checklist the user watches in real time. The entire ordered list is resent on every call (state is replaced, not merged); exactly one step stays `in_progress`. While a plan runs the step set is fixed — only status advances. The checklist is stored per task hash, so concurrent tasks in one session keep separate lists. When the last step completes and no `report-*.md` or `report-*.html` was written in that task, the result tells the model to call `write_result` for a long-form deliverable. Since v1.0.26 it carries the `Concurrent` flag, so it runs alongside the other fan-out calls of the same round. A checklist opens whenever the answer takes more than one round of tool calls, and for any analysis or research request however short the plan looks; a running Skill whose steps take more than one round opens one built from its own steps before the first step — dropping the ones the request does not reach; single-pass Skills get none (v1.1.1 used a three-step threshold) |
| `ask_user` | Free-text / single-select / multi-select / masked-secret prompts. Each question carries an optional multi-line `hint` for supporting detail. Since v1.0.23 the TUI (`cli-` origin) asks inline: the question appears in place and the same run continues with the answer. Since v1.2.0 the daemon runs the agent and sends the question over its Unix socket only to the TUI window that started the run. Every other origin (web, Telegram, Discord, API, scheduler) saves a pending snapshot — tool results clamped to 32 KiB and arguments to 4 KiB each (4 KiB / 1 KiB before v1.1.2) — ends the run, and resumes in a new turn with full context once the user answers. The tool has no timeout. The description tells the model not to ask when an active Skill's `SKILL.md` or data a tool can fetch already settles the question. A credential is never asked for here → `store_secret` |
