# Agent 路由

請求抵達 agent 的途徑：自動分派、subagents 工具與外部 agent。

兩種方式決定由哪個 agent 處理任務：

**1. 自動** — dispatcher LLM 分析輸入，並透過 `exec/model.Route`（v1.2.1 前為 `ResolveAgent()`）挑選最合適的 provider。v1.1.0 起 `pass` tier 模型不會被選中、也不作為 fallback；綁定該模型的 session 仍照用。

啟動順序：`exec.Prepare`（TUI 專屬排除、`/skill-name` 匹配）→ `exec.Run`（具名 skill 解析、agent 解析、載入 session；`exec.Start` 於 v1.2.1 改名為 `exec.Run`）→ `Execute`。Subagent 與排程以 `isSub=true` 直接呼叫 `exec.Run`，略過 `exec.Prepare`。具名 skill 被排除或找不到時，該次執行直接失敗。

`:self-id` 一次性覆寫前綴已移除；要交給具名 session 請用 `subagents(self_id=...)`，或以 `/session` 切換 session。

**2. `subagents` 工具** — agent 於執行期間 in-process（無 HTTP）呼叫另一個 agent，從 parent ctx 繼承 `AllowAll` 與 `WorkDir`。v1.1.0 起 `mode=invoke` 必須帶 `model` —— 空白 model 改由 dispatcher 補選的 fallback 已移除；傳 `model: "auto"`（v1.1.0 後的 hotfix）則交由 dispatcher 依任務挑選 —— 且母 agent 在 `reasoning_guide(topics=[subagent_dispatch])` 取用的 tier 清單比自身工作低一級（S → A、A → B、B → C）。明確指定的 model 會覆蓋 `self_id` session 綁定的模型；`model: "auto"` 沿用該 session 綁定的模型，沒有綁定時才交由 dispatcher 挑選。`reasoning` 預設 `auto`，不合法的等級會回傳列出可用等級的錯誤。

Subagent 在**只收集（collection-only）憲章**下執行——負責蒐集與回報，不巢狀、不寫入。排除集由三部分組成：

| 來源 | 排除項目 |
|---|---|
| 憲章基礎 | `subagents`、`edit_file`、`edit_tool`、`test_tool`、`edit_skill`、`write_result`、`html_template`、`generate*`（萬用字元）、`open_file`、`schedules`、`store_secret`、`pkg_manage`（v1.2.1 起；先前只有 `subagents`、`edit_file`、`generate*`） |
| TUI 專屬 tool / skill | `configs/jsons/tui_tools.json` 所列項目，例如 `extension-upload`、`extension-install` |
| 呼叫端的 `exclude_tools` | 母 agent 傳入的任何項目 |

`ask_user` **不**被排除——subagent 可透過共用的 pending registry 向使用者提問。Subagent 的待決提問也會發布到所屬的母 session，leg 會等待該次續行並回傳已回答後的結果。同時最多 3 條 subagent 並行執行（`MAX_CONCURRENT_SUBAGENTS`）；第 4 條在等待空位時，自身的 `MAX_SUBAGENT_TIMEOUT_MIN`（30 分鐘）timeout 已在倒數，因此大量 fan-out 應以 3 為單位分批派送。每筆結果帶有用量標頭，並匯總進母 session 的總計；自 v1.0.22 起報告本身存入 `~/.config/agenvoy/download/temp-<report_name>.md`，只回傳其路徑。
