# Agent Routing

The ways a request reaches an agent: automatic dispatch, the subagents tool, and external agents.

Two ways decide which agent handles a task:

**1. Automatic** — A dispatcher LLM analyzes the input and picks the best-fit provider via `exec/model.Route` (`ResolveAgent()` before v1.2.1). Since v1.1.0 `pass`-tier models are never picked or used as fallbacks; a session pinned to a model still uses it.

Startup order: `exec.Prepare` (TUI-only exclusions, `/skill-name` match) → `exec.Run` (named skill resolution, agent resolution, session load; `exec.Start` was renamed `exec.Run` in v1.2.1) → `Execute`. Subagents and schedules call `exec.Run` directly with `isSub=true` and skip `exec.Prepare`. A named skill that is excluded or not found fails the run.

The `:self-id` one-shot override prefix was removed; delegate to a named session with `subagents(self_id=...)`, or switch sessions with `/session`.

**2. `subagents` tool** — An agent calls another agent in-process (no HTTP) during execution, inheriting `AllowAll` and `WorkDir` from the parent ctx. Since v1.1.0 `mode=invoke` requires `model` — the dispatcher fallback for a blank model was dropped; pass `model: "auto"` (hotfix after v1.1.0) to let the dispatcher pick from the task — and the tier list the parent picks from in `reasoning_guide(topics=[subagent_dispatch])` starts one tier lower than for its own work (S → A, A → B, B → C). An explicitly named model overrides the model a `self_id` session is pinned to; `model: "auto"` reuses that pinned model and only lets the dispatcher pick when there is none. `reasoning` defaults to `auto`, and an invalid level returns an error listing the valid ones.

Subagents run under a **collection-only charter** — they gather and report, they don't nest or write. The exclusion set is built from three parts:

| Source | Excluded |
|---|---|
| Charter base | `subagents`, `edit_file`, `edit_tool`, `test_tool`, `edit_skill`, `write_result`, `html_template`, `generate*` (wildcard), `open_file`, `schedules`, `store_secret`, `pkg_manage` (since v1.2.1; before that only `subagents`, `edit_file`, `generate*`) |
| TUI-only tools / skills | Whatever `configs/jsons/tui_tools.json` lists, e.g. `extension-upload`, `extension-install` |
| Caller's `exclude_tools` | Anything the parent passes in |

`ask_user` is **not** excluded — subagents can ask the user through the shared pending registry. A subagent's pending question is also published to the owning (parent) session, and the leg waits for that resume and returns the answered result. At most three subagent legs execute concurrently (`MAX_CONCURRENT_SUBAGENTS`); a fourth waits for a slot while its own `MAX_SUBAGENT_TIMEOUT_MIN` (30 min) timeout is already running, so wide fan-outs should be dispatched in batches of three. Each result carries a usage header that rolls up into the parent session's totals; since v1.0.22 the report itself is saved to `~/.config/agenvoy/download/temp-<report_name>.md` and only its path comes back.
