文件 v1.0.9

內建工具

25 個工具一律註冊,Linux 上另加 pkg_managefind_note 在至少存在一則 operator note 前不會出現在註冊表;還有 4 個僅在前置條件存在時才出現(generate_audiogenerate_imagelist_chatbotsend_to_chatbot),內建工具合計 31 個。涵蓋多個相關動作的工具改以 mode 參數區分,而非拆成多個名稱 —— edit_file 取代原本的 write_file / patch_file / remove_file / restore_filefind_files 取代 list_files / glob_files / search_files,其餘類推。

15 個工具附帶完整 schema —— ask_usercalculatechat_historyedit_filefetch_pagefind_filesfind_notefind_toolsread_filesreasoning_guiderun_commandrun_skillsearch_webwrite_reportwrite_todo。其餘工具先以名稱與描述載入,參數在首次使用時透過 find_tools(mode=search) 取得,讓初始工具 payload 遠小於完整註冊表。

檔案

工具 說明
find_files 尋找檔案(queries: [{dir, pattern, file_pattern, recursive}])。mode=list 回傳目錄內容,mode=glob 以檔名 pattern 比對路徑,mode=search 以 RE2 regex grep 檔案內容。省略 mode 時自動推斷:pattern + file_pattern → search、只有 pattern → glob、兩者皆無 → list。glob pattern 必須含字面字元,全萬用字元(**/*)會被拒絕。多筆 query 的結果會合併去重。結果上限為總計 100 KiB 與每檔 100 筆匹配;截斷時結尾會說明丟棄了幾個檔案、幾個檔案的匹配被截短,讓模型改為縮小查詢而非原樣重跑
read_files 批次讀取一個或多個檔案(files: [{path, offset, limit}]);支援文字、PDF、DOCX、PPTX、CSV/TSV、圖片,以及音訊 / 影片 —— 媒體檔會經由已設定的 speech-to-text 模型回傳逐字稿,因此不再有獨立的轉錄工具。預設讀整份(上限 1 MB),超過時以 offset/limit 分頁 —— PDF 以頁、PPTX 以投影片、CSV 以列為單位。文字行以 "<row>\t<line>" 形式回傳,行號由讀取端加上、不存在於檔案中,拿該行當 edit_file anchor 前必須先去除。除非本 session 已讀過,否則必須在 edit_file(mode=patch) 之前呼叫。敏感檔案防護:SSH keys、.pem.key.env 一律需要確認,無論是否處於 sudo 或 allowlist
edit_file 對磁碟上檔案的所有變更。mode=write 建立首版或刻意整份覆寫;mode=patch 透過 targets 陣列做區域編輯 —— 每個 target 為 {old_string, new_string} 加上選用的 replace_all,所有 anchor 都在套用任何變更前對原始檔案內容定位。兩個 target 覆蓋同一區域,或某 target 的 old_string 出現在較早 target 的 new_string 內時,整次呼叫被拒絕、不寫入任何內容。new_string 留空即為刪除;插入的寫法是把 old_string 原樣放在 new_string 開頭。以行號定位的 row / insert_string 形式已移除 —— 行號會把同一次呼叫中先前的 target 一併算入,而那些內容尚未寫入磁碟;mode=remove 將檔案移置一旁,仍可還原;mode=restoreversion id 還原單一版本,或以 task_id 回滾整個任務動過的所有檔案(current = 當前執行中的任務)。省略 mode 時:有 content → write、有 targets → patch;remove 與 restore 永不自動推斷。write 時 path 留空會落在 ~/Downloads
file_history 工具動過的每個檔案的版本紀錄 —— 何時變更、當時任務目標為何、內容是什麼。mode=list 由新到舊列出版本,可用 pathtask_idfrom/to 本地時間與 limit(上限 24)過濾;mode=read 將每個路徑的最新紀錄版本與磁碟現況做 diff。這是 edit_file(mode=restore) 還原時所依據的快照層
open_file 以 OS 預設應用程式開啟檔案(播放影片、檢視圖片、開啟 PDF 閱讀器)。取代沙箱無法觸及的 run_command open/xdg-open。上限 10 秒

工具與 Skill

工具 說明
find_tools 工具註冊表。mode=search 以關鍵字比對(需全部命中)或 select:<name>,<name> 精確啟用,並注入對應 schema;mode=list 僅回傳名稱與一行描述、不注入 schema —— mcp=true 限縮為 MCP 對外暴露的工具,另有旗標可一併列出內部記帳用的 system 工具。省略 mode 時:有 query → search,否則 list。看似缺少的能力一律先查這裡,再決定是否新建
edit_tool 工具定義本身。mode=write 建立或覆寫、mode=patchtest_tool 失敗後修正精確字串、mode=remove 將目錄丟進 .Trash(可回收)。tag 決定目標檔案:json = tool.json(schema)、script = script.py(執行內容)、api = <name>.json(API 工具)。名稱為 snake_case 且不帶 script_ 前綴 —— 前綴由 runtime 自動補上
test_tool 在沙箱中以 JSON 由 stdin 餵入並執行 script 工具的 script.py,回傳其輸出。這是每次 edit_tool write 或 patch 後的驗證步驟;失敗時的循環是 edit_tool(mode=patch) → 再測
run_skill 將指定 skill 的參考素材載入當前 turn。回傳內容屬建議性質 —— 是參考資料,不是逐行照做的腳本
edit_skill ~/.config/agenvoy/skills/ 底下的檔案。mode=write 以相對路徑建立或重寫檔案(my-skill/SKILL.md)、mode=patch 取代精確字串、mode=remove 以單層目錄名丟棄整個 skill(可從 .Trash 回收)

網路

工具 併發 說明
search_web 即時網路查詢,同時回傳 DuckDuckGo 結果與 Google News 標題,格式為 {"web":[...],"news":[...]}source 可選 all / web / newstime_range 對兩個來源套用回溯區間(新聞上限 7 天);edition 設定新聞地區(TW:zh-HantUS:en);cdp=true 強制以瀏覽器擷取(HTTP 202 時自動啟用);另有旗標可跳過結果快取。上限 90 秒
fetch_page 擷取單一網頁並以 markdownhtmljson 回傳(readability + 透過 ToriiDB 的 4xx/5xx skip cache)。預設帶上持久 Chrome profile 的 cookie,需登入的站台可透明存取;優先嘗試 headless,失敗才改用可見視窗重試。save=true 改為寫入本地檔案而非回傳內容;另有同網域連結選項支援遞迴文件研究。上限 90 秒
http_request 原始 HTTP 請求(GET/POST/PUT/DELETE/PATCH),回傳 status + headers + body。content_type 可選 json / form / multipart;multipart 接受 {"fields":{...},"files":[{"name","path","content_type"}]},路徑須為絕對路徑並以二進位讀入。timeout 上限 300 秒。內建 SSRF 防護(DNS 解析後比對 loopback / private / link-local),特定主機可透過 net_white_list 放行。會重複呼叫的端點應以 edit_tool 建成 api_* 工具
download_file 下載二進位檔案到本地(tar.gz、圖片、壓縮檔、安裝檔)。絕對 path 直接使用,相對路徑併入 ~/.config/agenvoy/download/,父目錄自動建立。timeout 上限 600 秒。JSON/HTML 請改用 http_requestfetch_page(save=true)

執行

工具 說明
run_command 以 argv 執行程式(argv-only schema,透過 go-pkg/sandbox 包裹沙箱)。不含 shell metacharacter(|&&>*~)的單純指令直接呼叫,不會被包進 sh;pipe、重導向與 globbing 需明確使用 ['sh','-c','...'],其腳本會被逐指令解析驗證 —— 每個執行檔都必須是裸指令名,列於 denied_command 者一律拒絕。['cd','<path>'] 為特例,驗證路徑後會變更 Executor.WorkDirrm 會改為移入垃圾桶而非刪除。唯讀清單上的指令(git statuslscatpwd...)跳過確認 gate。要寫到 $HOME 之外時,該次呼叫帶上 write_paths,經密碼驗證核准後才綁入。sudo 一律拒絕(無論單獨執行或在 sh -c 內),並提示去掉 sudo 改宣告 write_paths,由此觸發 sudo 確認
pkg_manage 在沙箱驅動 Linux 套件管理器(apt / dnf / yum / pacman / apk),讓 bwrap 無法授予的 root 操作仍可運作。actioninstall / remove / update / upgrade / search / infopackage 只接受裸套件名 —— 不帶旗標、不指定版本、不接受第二個套件 —— 除 updateupgrade 外皆為必填。僅在 Linux 註冊。run_command 無法取代:sudo 在 bwrap 內沒有作用。語言執行環境(node / python)→ 以 run_command 搭配 mise、fnm 或 uv;語言層套件(pip / npm / cargo)→ run_command

協作

工具 說明
subagents mode=invoke 在獨立 session 中執行子任務(in-process,不走 HTTP);mode=list 回傳可重用的具名 session 與其角色。任務描述必須自我完備 —— 子任務看不到母對話的任何內容。最多 3 條並行,第 4 條會在自己的 timeout 計時中排隊,因此大規模 fan-out 以 3 個為一批派送。結果帶有 [subagent · <model> · session=<id> · usage: in=X out=Y cached=Z] 前綴,並累計進母 session 的用量。self_id 用於原樣重用既有的非暫時 session,v0.35.0 起取代 name / session_id,且 mode=list 必須帶它 —— 現在是解析單一被指名的 agent,而非列出所有 session;modelreasoning 僅在落入暫時 session 時生效。Timeout 為 MaxSubagentTimeoutMin(30 分鐘)。暫時 leg 的 model 依該 leg 的工作類型從 S / A / B / C tier 挑選(collect → C>B>A>S、transform → B>C>A>S、review 與 reason → A>S>B>C、程式碼或高精度 → S>A>B>C);pass tier 的模型只在使用者指名時使用。完整派送協定與模型 tier → reasoning_guide(topic=subagent_dispatch)
schedules 綁定 scheduler skill 的排程執行。mode=list 顯示本 session 已排入的項目、mode=patch 調整時間、mode=remove 取消並丟棄其 skill、mode=writescheduler-skill-creator 流程的內部綁定步驟。targettask(單次)、cron(5 欄位表達式)或 all(僅 list 可用)。task 時間格式:+5m / +1h30m(相對)、15:04(今日時鐘)、2006-01-02 15:04(本地日期時間)或 RFC3339。skill_name 帶有生成的 hash 後綴 —— 手寫的名稱必定失敗
write_todo 使用者即時觀看的任務清單。每次呼叫都重送整份有序清單(狀態是取代而非合併);恰好一個步驟維持 in_progress。計畫執行期間步驟集合固定 —— 只推進狀態,不改寫、不重排。清單以 task hash 分開儲存,同一 session 的並行任務各自保有清單。最後一步完成且該任務尚未寫出 report-*.md 時,回傳結果會提示模型對長篇產出呼叫 write_report
ask_user 自由輸入 / 單選 / 複選 / 遮罩輸入的提問;執行暫停並在使用者回答後以完整脈絡於新 turn 恢復。每個問題可帶多行 hint 承載補充細節。有 listener 時走 pending registry,否則回退到 stdin(CLI)或非互動提示。憑證一律不從這裡問 → store_secret

狀態與記憶

工具 說明
chat_history 本 session 自己的行為紀錄。mode=list 列出近期執行,每筆一行並附 task_idmode=read 完整展開一或多次執行 —— 當時的任務、呼叫過的每個工具與其回傳、最後的回覆(scope=reference 只保留昂貴的 payload,scope=full 全留);mode=tool_list 把最近 16 次執行中值得重用的呼叫攤平,讓已付過成本的抓取在重跑前先被找到,mode=tool 則以 task_id + name 取回該次呼叫的原始輸出;mode=search 搜尋過往訊息,match=semantic 在近期訊息中比對語意、match=keyword 在含封存的完整歷史中比對文字(SQLite FTS5,trigram tokenizer),並以 time_range 限制範圍。這些紀錄存放於 daemon 自己的儲存層,檔案工具無法觸及
error_history 跨 session 保留的工具失敗紀錄。mode=search 以關鍵字查詢過往紀錄 —— 每筆都附有有效的修正方式;mode=read 以 8 碼 hash 讀取單筆(工具回傳 no data: {hash} 時使用);mode=write 記錄一筆錯誤,含 tool、關鍵字、觀察到的行為、根因、採取的作法與 outcome。只有 outcome=resolved 會被儲存 —— failedabandoned 可傳入但會被丟棄。search 上限 16 筆
find_note 操作者自己寫的筆記 —— 這個工作環境預設的規範、慣例與背景。mode=search 回傳名稱或內文命中關鍵字的筆記名稱,命中越多排越前(上限 20 筆);mode=read 以名稱讀取整篇。keywords 為必填 —— 原本會列出所有名稱的 mode=list 已於 v0.35.0 移除。search 只回名稱,判斷哪些相關後再以 mode=read 取內容。筆記存於 SQLite note 表(FTS5 trigram 索引,v0.35.3 自 ToriiDB 遷入),由 web 儀表板經本地 HTTP API 撰寫,agent 不寫入。v0.35.4 起由 find_knowledge 更名
reasoning_guide 取得單一 topic 的完整規則集 —— tool_generatetool_errorrag_webmarket_analysistargeted_readask_usersubagent_dispatchwrite_todohtml_renderoffice(建立或修改 .docx / .xlsx / .pptx 的規則,確保 Office 與 iWork 應用程式能開啟檔案)。取代原本各自獨立的 per-topic guide 工具
write_report v0.35.4 新增。把單一長篇產出寫成輸出目錄下的 report-YYYYMMDD-HHMMSS.md,並回傳含路徑的寫入回執 —— 也就是回覆只做摘要、不重印的研究 / 分析 / 比較本文。唯一參數是 content;原本的 path 參數已移除。輸出目錄為 config.jsonoutput_dir(以 /config 設定),未設定時用 ~/Downloads(存在時),否則為 ~/.config/agenvoy/download/。其他檔案或既有檔案的修改 → edit_file

輔助

工具 併發 說明
calculate 批次運算式求值(四則運算、單位換算、貨幣運算)。支援 sqrtpow、可變參數的 min/max%^。回傳 {expression: result};單一運算式失敗只回傳錯誤字串,不會讓整次呼叫失敗。它只計算不查詢 —— 匯率、價格等即時數字須先由對應工具取得,再以字面值傳入
store_secret 以遮罩輸入取得值並直接寫入 keychain —— 該值永不進入 LLM context、歷史或日誌。schema 不接受 value 參數,agent 只看得到 name 與描述。在認證失敗時觸發(缺少金鑰、401、403、token 過期):由錯誤訊息取得金鑰名稱、呼叫此工具、再重新執行失敗的工具。每個工具每 turn 上限 2 輪

條件註冊

以下工具僅在前置條件存在時註冊,否則 LLM 完全看不到它們。

工具 併發 說明
generate_audio 以已設定的 text-to-speech 模型朗讀文字,將 .wav 寫入 download 目錄;回傳存檔路徑而非音訊資料。voice 指定 provider 的聲音名稱(OpenAI 用 alloy、Gemini 用 Kore),留空則用 provider 預設。上限 5 分鐘。(未選擇 text-to-speech 模型時排除 —— 以 /model ttsPOST /v1/model {tts} 設定)
generate_image 由文字生成圖片並寫入磁碟;提供參考圖時亦可用於編修。回傳存檔路徑而非影像資料。上限 15 分鐘。(圖像產生器未設定時排除 —— 以 /modelPOST /v1/model {image} 設定;各 provider 的圖像模型固定在 go-llm-router 內,因此該欄位填的是 provider 端點而非模型名稱)
list_chatbot 列出指定平台的已授權對話(platform=telegramplatform=discord)。(需 telegram_enabled / discord_enabled 旗標與 keychain 憑證同時具備)
send_to_chatbot target_id 發送格式化訊息到已授權對話。Telegram:HTML + transient client。Discord:markdown + transient client。平台格式規則寫在 channel 的 system prompt,不透過工具取得

動態工具群組

除了內建註冊表,另有四種前綴在呼叫時才解析:

前綴 來源
script_* script 工具目錄下生成的工具 —— script.py 在沙箱中執行
api_* 生成的 API 工具 —— 每個端點一份 JSON 描述檔
ext_* 擴充工具,可為 API 或 script 實作
mcp__* 已連線 MCP 伺服器所暴露的工具

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

輸出標記(channel 專屬行為)

任何工具或 LLM 回應的輸出文字都會被後處理以下標記:

標記 行為
[SEND_FILE:<path>] Channel runtime 自動附加檔案(Telegram → 依副檔名分流 photo/document,Discord → 統一 SendFiles,每則 10 個為一批)

[SEND_VOICE:<text>] 已隨 channel 語音輸出一併移除 —— Telegram 與 Discord 不再合成語音回覆。語音合成改由 generate_audio 工具負責,產出檔案而非發送到對話。

標記 regex + 去重 + os.Stat 過濾位於 internal/utils/utils.go

排程 runtime

scheduler-skill-creator建立 scheduler skill 內容並呼叫 schedules(mode=write) 完成綁定的高階 skill。新的週期性 / 單次請求應啟動該 skill,而非直接呼叫低階工具。

Daemon 端 runtime 以 fsnotify 監看 ~/.config/agenvoy/{tasks,crons}.json,在 Write / Create / Rename 時熱重載。逾期任務會在啟動或重載時自動觸發並移除;觸發經由 runtime.SetRunner(app.RunSkill) → 以 scheduler skill 內容執行 in-process subagent。

TUI 的 /cron/task 指令已移除;改用 /schedule,它把 cron 與單次項目列在同一清單(enter 立即觸發、d 刪除,新增 / 編輯請直接交代 agent),另有 /sched-<name> 手動觸發既有 scheduler skill 內容。

EN