# 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. **Foreground legs run at most `min(MAX_CONCURRENT_TOOLS, MAX_CONCURRENT_SUBAGENTS)` at a time** — half the CPU cores, at least 3, since v1.3.0 (a fixed 3 before) — and the next one queues while its own timeout runs, so wide fan-outs dispatch in batches of that size. 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. Foreground legs are capped at `MAX_SUBAGENT_TIMEOUT_MIN` (30 min). The `background` and `timeout_min` parameters (added in v1.3.0) were Removed in v1.3.2; use `background_subagents` instead, and the description sends legs very likely over 5 minutes, or a request such as "take your time" / "let me know when it's done" / "run it in the background" (English-only trigger phrases since v1.3.7), there. 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`, `background_subagents`, `edit_file`, `remove_file`, `restore_file`, `edit_tool`, `test_tool`, `edit_skill`, `write_result`, `html_template`, any `generate_*` tool, `open_file`, `schedules`, `store_secret`, or the TUI-only tools (`configs/jsons/tui_tools.json`, whose tool list is empty in v1.3.2), 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"])` |
| `background_subagents` | Added in v1.3.2. Starts one leg in the background and returns a task id at once, so the turn continues. Takes the `subagents` `mode=invoke` parameters (`task` and `model` required; `report_name`, `self_id`, `reasoning`, `new`, `system_prompt`, `exclude_tools`) plus `timeout_min` (1-60, default 60) in place of the 30-minute cap, and since v1.3.8 `objective` and `next`. Legs started in the same turn form one group (v1.3.8). When a leg finishes, its saved report path goes to the starting task while that task is running or pending; once it has ended, the group waits for all its legs and runs `objective` + `next` + every report as a new task, which can read the starting task through `chat_history`. Before v1.3.8 each report resumed the original task on its own. A background leg never raises a confirmation: a call that would need one is not run and the leg is told to report that it still needs approval; it also gets no `ask_user`. Each leg's progress (model, tool calls and results, text, errors) is written to `~/.config/agenvoy/sessions/<session>/background/<task id>.log`, removed when the leg ends. The leg takes a background task slot instead of a foreground one: at most `MAX_BACKGROUND_TASKS` per session (half the CPU cores, at least 3), shared with `background_command`. The description reserves it for legs very likely over 5 minutes, or a request such as "take your time" / "let me know when it's done" / "run it in the background"; an action the user wants after the gathering goes into `next`, and a request that finishes in a few minutes stays in the foreground (v1.3.8). Every leg of a group is started in the same turn. Excluded unless the request comes from the TUI (`cli-` origin with no deliver target) |
| `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` (later today only, no rollover to tomorrow), `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 `detail` for supporting context (named `hint` before v1.3.5). Since v1.3.8 Telegram and Discord send the question, its detail and `question n/m` (only with several questions) on separate lines, and the web card shows the same progress; the tool-call line reads `Ask(...)` with the first line of the first question's `detail` (or its question), up to 128 characters. 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` |
