五分鐘跑一次
除非另註,範例省略前綴 {BASE}/private/module/sandbox。用 Authorization: Bearer 或 X-Api-Key 認證。公司擁有環境需要公司管理員;部門擁有環境與上傳需要該部門管理員,公司管理員可管理兩者。建立目錄任務是 部門或公司管理者 工作 — 不是聊天室擁有。房間啟用走 聊天室管理者階梯。提交執行是成員資格 + 適用的 share。見 角色與權限 與 任務受眾。
0. 確認目錄
GET /public/info/sandbox/regions # 沒有 /private 前綴;不必登入
GET /public/info/sandbox/profiles # 跳過 tenant_selectable=false 的 id(xlarge)1. 快路徑 — 釘 SCFG Standard(跳過上傳/建置)
GET /environments 含 owner_kind=system_curated。live 目錄名稱是 SCFG Standard。取一個 state=ready 的版本,跳到 步驟 5。一般使用者永遠不要建環境。
GET /environments?lifecycle=active&page_size=100
GET /environments/{environment_id}/versions?lifecycle=active&page_size=100
# 選 system_curated/名稱 "SCFG Standard"/version state == "ready"只有在你需要租戶自建映像時才做步驟 2–4。FROM 任何公開映像——沒有固定允許清單,scratch 也合法。CVE 掃描結果只是參考,不會讓建置失敗。
2. 建立自訂環境
POST /environments
{ "name": "my-runner", "description": "demo" }
# → SandboxEnvironmentResponse { id, state: "active", ... }3. 上傳 context 並釘版本
POST /environments/{environment_id}/context-uploads
{ "declared_bytes": 123456, "archive_format": "tar.gz" }
# → { upload_session_id, capability_token, put_header_name, put_content_type, ... }
PUT /environments/{environment_id}/context-uploads/{upload_session_id}
X-Sandbox-Upload-Capability: <capability_token>
Content-Type: application/octet-stream
<raw zip/tar/tar.gz bytes>
# → { bytes_received, digest }
POST /environments/{environment_id}/context-uploads/{upload_session_id}/complete
{ "expected_digest": "sha256:<hex from PUT>" }
# → { owned_object_id, digest, byte_size }
POST /environments/{environment_id}/versions
{ "owned_object_id": "<id>", "resource_profile": "standard", "source_ref": "demo.tar.gz" }
# → SandboxEnvironmentVersionResponse { id, state: "draft", ... }不要送 generic blob_id。單獨送 source_digest 只給重試用,而且該 digest 必須已經對應一個完成的 context 物件。resource_profile 必須租戶可選。
4. 觸發建置並輪詢到 ready
POST /environments/{environment_id}/versions/{version_id}/builds
{ "build_profile": "standard" }
# 可選 build_region:取自 GET /public/info/sandbox/regions 的代碼;省略則用該部署的預設值
GET /environments/{environment_id}/versions/{version_id}/builds/{attempt_id}
# 直到 terminal_class 有值
GET /environments/{environment_id}/versions/{version_id}
# 直到 version state == "ready"沒有 streaming。
5. 建立部門任務並發布版本
POST /tasks
{ "name": "hello", "owner_scope": "department", "owner_id": "{department_id}" }
# chatroom owner_scope → 422
POST /tasks/{task_id}/versions
{ "environment_version_id": "{version_id}", "work_script": "echo hi",
"timeout_seconds": 1800, "requires_confirmation": false }
POST /tasks/{task_id}/versions/{task_version_id}/publish6. 分享,然後房間啟用
POST /tasks/{task_id}/shares
{ "target_kind": "chatroom", "target_id": "{chatroom_id}" }
# 分享 ≠ Agent 選單
POST /chatrooms/{chatroom_id}/granted-jobs/{task_id}/enable
{ }
# 省略 task_version_id → 釘目前已發布版
GET /chatrooms/{chatroom_id}/menu
# 已授予且已啟用;每個呼叫者同一份清單7. 提交執行(帶 Idempotency-Key)
POST /chatrooms/{chatroom_id}/runs
Idempotency-Key: <a fresh UUID each time>
{ "task_version_id": "{task_version_id}", "input": { "any": "json" } }手動 REST 可以跑已授予、已發布的版本,即使房間尚未啟用。選單/Agent 只顯示已啟用的任務。產品 UI 應從選單提交。
8. 輪詢狀態並取產出物
GET /chatrooms/{chatroom_id}/runs/{run_id}
GET /chatrooms/{chatroom_id}/runs/{run_id}/content
GET /chatrooms/{chatroom_id}/runs/{run_id}/artifacts
POST /chatrooms/{chatroom_id}/runs/{run_id}/artifacts/{artifact_id}/download
POST /chatrooms/{chatroom_id}/runs/{run_id}/output/public-link # → { url, token }(也有 .../log/public-link)
GET <url> # = GET /public/sandbox/artifacts/{token},免登入,DELETE .../public-link 可撤銷
# artifacts/{artifact_id}/download 回的 capability_token 目前沒有兌換路由——output/log 請用 public-link。Company manager 歷史(可選)
GET /tasks/{task_id}/runs?offset=0&limit=10&order=desc
GET /tasks/{task_id}/runs/numOfData受限(Sandbox scope)金鑰打這兩條路由會在認證層被擋下,回 403(Access denied, restricted Sandbox key cannot use this route),不是 404 —— /private/module/sandbox/tasks 在受限金鑰的拒絕路徑清單裡,請求到不了 router。
想更快?Quick Run(只有管理者)
仍會鑄一個隱藏的聊天室擁有父任務給一次性腳本。不要把那個形狀抄到 POST /tasks。
POST /chatrooms/{chatroom_id}/quick-run
Idempotency-Key: <UUID>
{ "name": "adhoc", "environment_version_id": "{ready_version_id}",
"startup_script": "", "work_script": "echo hi", "ordinary_env": {},
"input": {}, "timeout_seconds": 600 }整個生命週期的參考實作(環境 → python/node/go 的 zip 任務包 → 9 次執行 → 下載輸出),零相依、Node ≥ 20:teamsync-backend 的 sandbox/e2e-js/。