Agent 確認流程
重點:Agent 的 sandbox 提交是一個 LangGraph 工具(
src/components/tools/custom/sandbox/factory.py的sandbox_submit_job),由 Agent 在對話回合中呼叫。前端沒有專屬的 confirm/reject REST 端點。前端的角色是呈現提案、觀察結果,實際確認發生在後續的對話回合。另外四個工具(sandbox_job_menu、sandbox_submitted_jobs、sandbox_job_status、sandbox_cancel_job)與ChatroomJobType.sandbox寫在 Agent toolkit。
為什麼有這個流程
當任務 requires_confirmation = true——或宣告了表格 writeback 的 output_policy(custom_table_writeback,即使 requires_confirmation 是 false 也視為需確認等級)——Agent 不能在同一回合直接執行:它先提案,經過人為確認(下一回合)才提交執行。這是防止 Agent 未經同意就跑有副作用的任務。Command 輸出的版本(custom_table_command)且 requires_confirmation = false 是例外:它直接提交(見任務輸出交給自訂表格 Command)。
兩段式(工具內部語意)
- 提案
mode="request":Agent 帶task_version_id+input呼叫工具。後端建立一個prepared提案,回:{ "kind": "prepared", "proposal_id": "...", "proposal_receipt": "<簽章 token>", "summary": "...", "requires_confirmation": true, "task_id": "...", "task_version_id": "..." }- 會取代同一 principal 其他 pending 提案(
superseded)。 proposal_receipt是簽章多段 token(含 4 個點;只給不透明 id 會被判forged_receipt)。
- 會取代同一 principal 其他 pending 提案(
- 提交
mode="commit":必須是後續回合(不允許同回合繞過)。Agent 只帶proposal_receipt。後端驗證提案 receipt + 帶外的 turn receipt(綁定 company/chatroom/principal/human-message),才建立 run(submission_source="agent"),回:{ "status": "ok", "run_id": "...", "proposal_id": "..." }- 回應遺失重送:回
{ "kind": "replay", "run_id": "..." }。
- 回應遺失重送:回
提案狀態 SandboxProposalState
prepared → committing → committed
其他:superseded / cancelled / expired / failedTTL:PROPOSAL_TTL_SECONDS = 1800、TURN_RECEIPT_TTL_SECONDS = 600。同一輪 commit 會被拒,錯誤碼是 same_turn(確認回合與提案回合相同);若確認訊息時間不晚於提案訊息則是 not_later;同一則確認訊息重複用在另一個提案是 receipt_reused。不帶 run_id 的 sandbox_cancel_job 取消此 principal 的待確認提案(cancelled)。
前端要做什麼
前端不呼叫工具,但要把「有一個待確認的提案」呈現給使用者,並在確認後觀察結果:
- menu 上的
requires_confirmation: true告訴你這個任務會走確認流程。 - 提案的
summary/requires_confirmation透過對話/助理頻道呈現給使用者。 - 工具的
list_submitted會回該 principal 自己的proposals[](各帶proposal_receipt)與runs[],讓後續回合能接續處理。 - 確認提交後,前端就照 執行與取回結果 用 run 狀態端點觀察那個
run_id。
錯誤碼(工具層)
工具錯誤信封:{ "status": "error", "error": "<code>", "message": "..." },碼為 validation_error/forged_receipt/not_found/unauthorized/retryable/confirmation_input_unavailable/internal_error/provider_unavailable/same_turn/not_later/receipt_reused/already_committed/proposal_not_pending/forbidden/hidden/reauth_failed;job-contract 422 的 validation_error 會另外帶 code(input_schema_violation/job_contract_invalid)與 errors[]。過期的 receipt 回 forged_receipt(TTL 檢查在簽章驗證裡),同一輪回 same_turn;只有「別人的/不存在的提案」才是 not_found。後一輪已驗證但耐久 input 無法重放 → confirmation_input_unavailable(提案仍 pending)。mode=commit 用 sandbox_submitted_jobs 重簽的 proposal_receipt,不要用快取的準備收據。完整表:Agent toolkit。
人類使用者的提交走
POST /chatrooms/{id}/runs(見 執行流程);Agent 提交走這個工具。兩者最終都產生一個可用 run 狀態端點觀察的 run。