# 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]` 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 `MaxSubagentTimeoutMin` (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. A leg never gets `subagents`, `edit_file`, any `generate_*` tool, or the TUI-only tools; `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. Since v1.1.1 a request that names three or more steps counts as a complex task that opens a checklist, and a running Skill with three or more steps opens one built from its own steps before the first step — dropping the ones the request does not reach; single-pass Skills get none |
| `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. Every other origin (web, Telegram, Discord, API, scheduler) saves a pending snapshot — tool results clamped to 4 KiB and arguments to 1 KiB each — 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` |
