# 內建工具

31 個工具在所有 OS 上一律註冊，其中包含 `public_api_list`（v1.3.2 起為內建工具，原為 API 工具 `api_public_api_list`）；還有 6 個僅在前置條件存在時才出現（`generate_audio`、`generate_image`、`list_chatbot`、`send_to_chatbot`、`background_command` 與 `background_subagents`），內建工具合計 37 個。`run_command_background` 已更名為 `background_command`（移除於 v1.3.2）。`pkg_manage` 已移除於 v1.3.2；請改用帶 argv `['sudo', ...]` 或 `sandbox: false` 的 `run_command`。`run_websocket` 已移除於 v1.3.2，沒有替代工具。`find_note` 已於 v1.0.23 隨 operator notes 一併移除；session 的常駐指示改寫在該 session 的 role（`/role`）。涵蓋多個相關動作的工具改以 `mode` 參數區分，而非拆成多個名稱 —— `edit_file` 取代原本的 `write_file` / `patch_file`，`find_files` 取代 `list_files` / `glob_files` / `search_files`，其餘類推。刪除與還原檔案則是獨立工具：`edit_file(mode=remove)` 與 `edit_file(mode=restore)` 移除於 v1.3.11，改由 `remove_file` 與 `restore_file` 取代；`error_history(mode=write)` 移除於 v1.3.11，改由 `write_error` 取代。

自 v1.2.0 起，執行時不再一開始就送出所有 schema。除 `claude-code` 外的 provider，tools 陣列只放 `find_tools`、`run_tool`、`reasoning_guide`、`write_todo`、`chat_history`、`ask_user` 與 `write_result`（另加 client tools；`reasoning_guide` 於 v1.2.1、`write_todo` 於 v1.2.3、後三者於 v1.3.5 加入固定組）；其餘工具 —— 內建、`script_*`、`ext_*`、`mcp__*` —— 只以名稱列在每輪的 turn context（`Tools (call through run_tool; ...): ...`；v1.3.7 起 MCP 工具依 server 分組寫成 `mcp__<server>__{a, b}`）。模型以 `find_tools(names=["NAME", ...])` 取得 schema（以工具輸出回傳），再以 `run_tool(name, args)` 呼叫；runtime 會拆包成內層工具，因此確認、boundary 檢查與參數驗證仍依實際工具名套用。直接呼叫清單中的工具會被拒絕並指向 `run_tool`；尚未取得 schema 就經 `run_tool` 呼叫時，回傳該 schema 並要求重新呼叫；未註冊的工具名一律不執行。tools 陣列固定不變，provider 的 prompt cache 才能持續命中。`AlwaysLoad` 旗標已移除；改以 `find_tools` 載入 schema（移除於 v1.2.0）。`claude-code` provider（偵測到本機 `claude` binary 即可使用）取得除 `run_tool` 外的所有工具並直接以名稱呼叫，但只收到名稱：在 `find_tools` 取得該工具 schema 前的呼叫不會執行，改回傳 schema。

## 條件註冊

前置條件不存在時，以下工具會從該次執行中排除，LLM 看不到它們。auto mode 下的 headless `/v1/send` 執行（如 `agen -p` 送出的請求）另外排除 `background_command` 與 `background_subagents`，並拿掉平常一律註冊的 `ask_user` 與 `store_secret`。

| 工具 | 併發 | 說明 |
|---|---|---|
| `generate_audio` | | 以已設定的 text-to-speech 模型朗讀文字，寫入 output 目錄（`output_dir`，未設定則 `~/Downloads`，再不然 `~/.config/agenvoy/download/`）；回傳存檔路徑而非音訊資料。自 v1.0.13 起會向 provider 要求 `opus`，副檔名依回傳的 MIME 決定（opus/ogg 為 `.ogg`，另有 `.mp3`、`.aac`、`.flac`，預設回退 `.wav`）—— 附加到 Telegram 對話的 `.ogg` / `.oga` / `.opus` 會以語音訊息而非檔案送出。`voice` 指定 provider 的聲音名稱（OpenAI 用 `alloy`、Gemini 用 `Kore`），留空則用 provider 預設。上限 5 分鐘。*（未選擇 text-to-speech 模型時排除 —— 以 `/model tts` 或 `POST /v1/model` `{tts}` 設定）* |
| `generate_image` | | 由文字生成圖片並寫入磁碟；提供參考圖時亦可用於編修。回傳存檔路徑而非影像資料。上限 15 分鐘。*（圖像產生器未設定時排除 —— 以 `/model` 或 `POST /v1/model` `{image}` 設定。自 v1.0.13 起該設定填的是 `provider@model` 形式的圖像模型，由各個握有憑證的 provider 以 image-only filter 探查，v1.0.18 起快取 15 分鐘；`codex` 仍為裸 provider 名稱，舊版存下的裸 provider 名稱也仍可解析）* |
| `list_chatbot` | | 列出指定平台的已授權對話（`platform=telegram` 或 `platform=discord`）。*（僅在 daemon 啟動時 `telegram_enabled` / `discord_enabled` 已開啟且 keychain 有 bot token 才註冊；兩個平台都不符合時也會從該次執行排除）* |
| `send_to_chatbot` | | 以 `target_id` 發送格式化訊息到已授權對話。Telegram：HTML + transient client。Discord：markdown + transient client。平台格式規則寫在 channel 的 system prompt，不透過工具取得 |
| `background_command` | | 在背景啟動一個指令並立即回傳 task id；指令結束時回報輸出，執行中有新輸出行命中錯誤關鍵字時也會回報，指令繼續執行；同一回合開的 leg 組成一組，帶 `objective` 與 `next`（v1.3.8）。用於 file watcher 與預期超過 5 分鐘的工作，細節見「執行工具」頁。*（請求不是來自 TUI 時排除 —— 須為 `cli-` origin 且沒有 deliver target；v1.3.2 起不再取決於 decision model）* |
| `background_subagents` | ✓ | 在背景啟動一條 subagent leg 並立即回傳 task id；leg 完成時回報存好的報告路徑，送達方式與 `background_command` 相同。細節見「協作工具」頁。*（請求不是來自 TUI 時排除 —— 須為 `cli-` origin 且沒有 deliver target）* |

## 動態工具群組

除了內建註冊表，另有三種前綴在呼叫時才解析：

| 前綴 | 來源 |
|---|---|
| `script_*` | script 工具目錄下生成的工具 —— `script.py` 在沙箱中執行 |
| `ext_*` | 擴充工具，以 script 實作 |
| `mcp__*` | 已連線 MCP 伺服器所暴露的工具 |

使用者自訂的 API 工具（`api_*`）已移除於 v1.3.2：其 JSON 檔不再載入，殘留的檔案會逐一略過，並在 log 留下 `[Invalid] api tool` 警告；呼叫端點請用 `http_request`，或建成 script 工具。

RAG 是透過這個途徑而非內建工具接入：KuraDB 以一般 MCP 伺服器身分註冊，其 `list_rag` / `search_rag` 工具會以 `mcp__` 前綴出現，未註冊或未連線時則完全消失。
