狀態機與輪詢
沒有 streaming。 前端用輪詢(GET 狀態)追蹤進度。以下是各資源的狀態值(取自 src/schemas/enums.py)與轉換。
環境版本 SandboxEnvironmentVersionState
draft → build_queued → building → quarantined → verifying → verified
→ regional_provisioning → ready ← 可被 Task Version 引用分支/失敗狀態:retryable_failed、rejected、abandoned、blocked、superseded、archived、provisioning_blocked。quarantined 不是失敗狀態——它是成功路徑上的必經一站:compose(建置)成功後版本一定先進 quarantined,掃描階段開始才轉 verifying。
retryable_failed→POST /.../retry-build。provisioning_blocked/ provisioning 失敗 →POST /.../retry-provisioning。
建置嘗試 SandboxBuildAttemptState
validation_queued → validating → build_queued → building → verifying → completed
取消:cancel_requested → cancelling → cancelled
失敗:customer_failed / platform_failedterminal_class∈completed/customer_failed/platform_failed/cancelled。error_code/stage_code/phase提供細節;report_total_bytes > 0表示有建置報告。常見error_code:policy_reject(客戶)、identity_config、tenant_cancel(CVE 掃描結果自 2026-08-25 起只是參考——vulnerability_reject已經不會再出現)。- 取消不是同一請求內結算。
POST .../builds/{id}/cancel圍欄 attempt(cancel_requested)並寫入可持久化的 provider-cancel intent,即使 attempt 還在排隊。輪詢到terminal_class=cancelled。在cancel_requested/cancelling再取消一次是冪等。
執行 SandboxRunState
queued → starting → running → completed
取消:cancel_requested → cancelled
失敗:customer_failed / platform_failed- 終態以
terminal_at標記。 error_code提供失敗原因。
任務版本 SandboxTaskVersionState
draft → published → archived另有 content_state:active(可跑)或 scrubbed(保留期/offboarding 後內容被清掉)。選單/可執行判斷要求 state == "published" 且 content_state == "active"。
環境父層 state:active → archived。Binding 活著的 state:enabled(選單還要 authority_applicable)。Share grant 退休:revoked。
Agent 提案 SandboxProposalState(Agent 確認流程)
prepared → committing → committed
其他:superseded(被更新提案取代)/ cancelled / expired / failed詳見 Agent 確認流程。
輪詢建議
- 建置:輪詢
GET /environments/{id}/versions/{vid}/builds/{attempt_id},直到terminal_class有值。 - 執行:輪詢
GET /chatrooms/{id}/runs/{run_id},直到terminal_at有值。 - REST 建議間隔:2 秒,約 30 秒後退避到 10 秒,看到
terminal_at/terminal_class就停。MAX_STATUS_WAIT_SECONDS = 60只是 agent 工具sandbox_job_status.wait_seconds上限,不是 REST long-poll。 - 通知:
SandboxNotificationEvent(見 通知)可以叫醒 UI;不改變上面的輪詢模型。一定要再 GET。
取消(runs)
- 未認領(
queued/尚未派送):POST .../cancel立刻設成cancelled,釋放定價 hold,佇列 lease 標released——自 2026-08-30 起,佇列/併發容量 slot 也會立刻釋放(之前若碰上競態的併發派工,可能讓已取消的 run 卡住佔著 slot)。 - 已認領/執行中:設成
cancel_requested,寫入耐久 cancel outbox;runner 再走到cancelled。 - 租戶取消圍欄贏過 runner
executions/complete時,公開error_code是cancelled_by_request(PR #951)。不要把已取消 run 上的空error_code當成「未知」。 cancel_requested_at有持久化,但不在SandboxRunDetailResponse。看status+error_code。can_cancel_run == can_read_run。受限 key 仍只能看自己的 run。- 極少數情況下,若控制面在派工中途掛掉,run 可能卡在
starting。背景 reaper 會自動自癒(重新派送同一次 dispatch,剛好一次)——不需要租戶動作,這期間取消照樣可用。
Last updated on