v1.3.11

待決任務與取消

最後更新


等待使用者的執行如何暫存,以及取消與暫停對執行中任務的影響。

Pending registry


internal/runtime/pending.go 是由 prefix 路由的 confirm/ask registry,由主 agent 與任何 in-process subagent 共用。Producer(toolCall confirm、ask_user handler、store_secret handler)呼叫 Ask(ctx, req) 並阻塞於 per-entry buffered=1 的 reply channel。每個前端透過 RegisterListener(prefix) 註冊 listener —— web 儀表板用 "chat-"、Telegram / Discord listener 用 "tg-" / "dc-"(空 prefix 匹配全部)—— 並只透過 PickNextMatch(prefix, accept) 認領匹配的 entry。v1.2.0 起 TUI 不再自行註冊 listener:daemon 的每條 socket 連線以 RegisterListenerMatch(prefix, match) 註冊 "cli-",只匹配 ctx 帶有該連線所發起視窗 window hash 的請求,並以 ask frame 轉送,因此 TUI 執行產生的確認或提問只會送到發起它的 TUI 視窗。受限路徑的確認會在 TUI 的密碼欄位要求系統密碼(sudo 憑證仍在快取期內則略過),由 daemon 以 sudo -S -v 驗證;有輸入密碼或驗證失敗時,以 verify frame 回報結果。連線關閉時,其尚未回答的問題一律以錯誤結束。ctx 取消會移除該 entry,使過期的 producer 絕不浪費一次人為互動。
Gate HasListener(origin) 檢查是否有 prefix 符合該 session 來源(OriginOf 辨識 cli-、chat-、tg-、dc-)的 listener 已註冊。帶 match 函式的 listener 只在請求的 ctx 通過時才算數,因此視窗已斷線的 TUI 執行會找不到 listener。這取代了舊的全域 pending.Active atomic.Bool,讓 TUI、web、Telegram、Discord 的 confirm 流程能並行運作而不互相阻塞。
自 v1.0.23 起 ask_user 依來源分流。來自 TUI 執行(來源 cli-)時,問題以 inline 請求經 Ask 送出,同一次執行拿到回答後繼續。來自其他來源時,先落地同一輪其他 tool 的結果,寫入 pending 快照(v1.1.2 起每筆 tool 結果截至 32 KiB、參數截至 4 KiB,先前為 4 KiB / 1 KiB;被截斷處留有 ...[N bytes elided]... 標記,恢復時的 prompt 會要求模型在缺漏內容有影響時重跑同一呼叫),結束本次執行,待回答後以新 turn 恢復。
v1.3.0 起 TUI 執行也能把工作留在背景,v1.3.2 起經由 background_command 與 background_subagents;僅限來源為 cli- 且沒有 deliver 目標的請求(不再取決於是否設定 decision model)。run_command_background 更名為 background_command(移除於 v1.3.2);run_websocket 與 subagents 的 background / timeout_min 參數已移除(移除於 v1.3.2),請改用 background_command 與 background_subagents。每次呼叫開一條 leg,id 為 cmd_ 或 sub_ 加 8 個十六進位字元。v1.3.8 起同一任務在同一回合開的 leg 組成一個 job,存為 ~/.config/agenvoy/sessions/<session>/background/job_<8 hex>.json,不再記錄在任務的 pending 快照中(移除於 v1.3.8);兩個工具都接受 objective(這組要達成什麼,需能獨立閱讀)與 next(拿到報告後要做什麼),整組取第一個非空值。同一 session 同時最多 MAX_BACKGROUND_TASKS 條 leg,由兩個工具共用(DEFAULT_CONCURRENCY:CPU 數的一半,至少 3)。leg 執行期間,輸出會附加到 ~/.config/agenvoy/sessions/<session>/background/<leg id>.log,結束即刪除。完成的結果最多保留 32 KiB;執行中的 background_command 每次監看回報最多 8 KiB、合計 32 KiB,較舊的以 ...[N reports elided]... 標記省略。v1.3.8 起發起的任務不再為了 leg 維持 pending:照常結束並寫入任務歷史,daemon 也不再於每份報告到達時以 [Resumed Task — background task finished] 訊息接回任務(移除於 v1.3.8)。報告的去向取決於發起的任務:
發起的任務報告
執行中在它下一輪開始時以 [Background Report — background task finished](或 ... update])訊息加入;在它即將結束時才送到的報告會讓它多跑一輪
暫停或等待 ask_user保留在 job 中,任務恢復時併入恢復訊息
已結束等該 job 的 leg 全部完成,才以新任務執行一次:隱藏的輸入以 [Resumed Task — background group finished] 開頭,帶 objective、next、所有報告與發起任務的 id(供 chat_history(mode=read) 讀取)。報告已全部被發起任務收走的 job 不會執行

daemon 啟動時會清除所有背景 job,連同 background/ 目錄一併刪除,因此背景工作不會跨重啟延續。
background_command 一律監看輸出:新的一行含有錯誤關鍵字(keywords;預設 error、err!、fail、fatal、panic、exception、traceback、segmentation fault、core dumped、out of memory、permission denied、command not found、no such file)時,待輸出穩定(安靜 2 秒,最多等 10 秒)後,回報最新輸出(最多 8 KiB),指令則繼續執行;每 30 秒最多回報一次。設定 decision model 時,會先經 decision 檢查剔除無害的命中與跟上次報告重複的內容;檢查失敗則不經檢查直接回報,並註明檢查失敗;未設定 decision model 時每次命中都會回報。舊監看模式的 interval 與 prompt 參數已移除(移除於 v1.3.2)。background_subagents 的 leg 回報存檔報告的路徑;背景 leg 從不發起確認,而是回傳已蒐集的內容,並說明該呼叫仍需核准。
TUI 過去顯示 Waiting for background tasks 時,從該視窗送出的訊息會併入等待中的任務;此模式移除於 v1.3.8,因為發起的任務現在照常結束,新訊息就是一般請求。POST /v1/send 的 pending_task 指向仍 pending 且有背景 job 的任務時,仍視為該任務的後續輸入:接回該任務,任務執行中則改為 steer。恢復的任務若不是該 session 最新的任務、且沒有背景 job,會改用新的 task hash,避免回覆插進較舊的任務(v1.3.0)。

取消與暫停


自 v1.0.10 起取消帶有 cause(context.WithCancelCause)。只有標記 runtime.ErrUserCanceled 的取消 —— TUI 的 Ctrl+C、Esc popup 選 Yes,或確認框選 Cancel task(v1.3.3)—— 才會刪除 pending 任務;v1.3.9 起刪除前會先以 [Canceled] 回覆(任務原本失敗時附上最後的錯誤)寫入對話歷史,chat_history 仍查得到。其餘取消(含 popup 的 Pause,以及 v1.3.3 起確認框的 Abort task,即 runtime.ErrUserAborted)只結束該次執行,pending 紀錄保留,可由 /pending 或 GET /v1/session/:id/task 續接。v1.2.0 起 TUI 的 /pending 以 pending frame 經 daemon 續行;已存的問題透過 socket 以 inline 方式詢問,續行的執行串流回同一視窗。TUI 執行綁定其 socket 連線:關閉 TUI 會取消執行,但 cause 不是 runtime.ErrUserCanceled,因此 pending 任務保留。v1.3.0 起取消與暫停也會停止該任務的背景工作;取消接著刪除 pending 任務,暫停則保留。單一 leg 可從 TUI 背景任務選單取消(v1.3.8)。/pending 中讓背景工作仍在跑的任務無法選取的 [Active] 標記移除於 v1.3.8。恢復時若任務已被某個執行占用,回傳 [Conflict] pending task: running。
TUI 的 Ctrl+C 與 popup 選項以 cancel frame 送出(選 Pause 時帶 pause),daemon 只對該連線發起的任務以 exec.Cancel(taskHash, cause) 套用。v1.2.0 起 exec.Run(v1.2.1 前名為 exec.Start)在發出第一個事件前就產生 task hash 並登記取消函式,因此從第一個事件起即可取消;TUI 尚未收到任何 task hash 時要求的取消會先保留,待第一個 hash 到達再送出。不在 popup 中時,Esc 依序為:關閉開啟中的 / 指令面板 → 關閉提示框 → 取消執行(尚未顯示任何內容時直接取消,否則經由 popup)→ 清空輸入 → v1.3.8 起,session 有 leg 在跑時開啟背景任務選單:No、各 leg 與 All(兩條以上才有),選定後再確認一次;TUI 以 background_cancel frame 送出,daemon 取消該 leg、丟棄晚到的結果並結算其 job。ask_user 因非使用者取消的原因而失敗時,同樣不再丟棄 pending 任務。
EN