# 待決任務與取消

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

## 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 任務。
