待決任務與取消
等待使用者的執行如何暫存,以及取消與暫停對執行中任務的影響。
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 —— TUI 用 "cli-"、web 儀表板用 "chat-"、Telegram / Discord listener 用 "tg-" / "dc-"(空 prefix 匹配全部)—— 並只透過 PickNext(prefix) 或 PickNextMatch(prefix, accept) 認領匹配的 entry。PickNextFor 已移除,改用 PickNext / PickNextMatch。ctx 取消會移除該 entry,使過期的 producer 絕不浪費一次人為互動。
Gate HasListener(origin) 檢查是否有 prefix 符合該 session 來源(OriginOf 辨識 cli-、chat-、tg-、dc-)的 listener 已註冊。這取代了舊的全域 pending.Active atomic.Bool,讓 TUI、web、Telegram、Discord 的 confirm 流程能並行運作而不互相阻塞。
自 v1.0.23 起 ask_user 依來源分流。來自 TUI(cli-)時,問題以 inline 請求經 Ask 送出,同一次執行拿到回答後繼續。來自其他來源時,先落地同一輪其他 tool 的結果,寫入 pending 快照(每筆 tool 結果截至 4 KiB、參數截至 1 KiB),結束本次執行,待回答後以新 turn 恢復。
取消與暫停
自 v1.0.10 起取消帶有 cause(context.WithCancelCause)。只有標記 runtime.ErrUserCanceled 的取消 —— TUI 的 Ctrl+C,或 Esc popup 選 Yes —— 才會刪除 pending 任務。其餘取消(含 popup 的 Pause)只結束該次執行,pending 紀錄保留,可由 /pending 或 GET /v1/session/:id/task 續接。ask_user 因非使用者取消的原因而失敗時,同樣不再丟棄 pending 任務。