lazyBoy/docs/tool-packages.md

6.3 KiB
Raw Blame History

Computer 內 archive 套件 API

目前可透過 Tool Manager 的 archive 表單或已登入的 API 安裝預先放在 Computer workspace 的 tartar.gz。安裝器在 Computer 內讀取、驗證 SHA-256、解包並建立 bindingAPI 不下載或解包 task artifact。這是通用 stdio MCP 的 archive 入口,尚未包含遠端 URL 安裝、完整 V1 巢狀 manifest、安裝 hooks、帳戶 broker 或常駐 pool。

POST /api/bots/{botId}/tools/install

{
  "artifactPath": "uploads/server.tar.gz",
  "manifest": {
    "id": "example.mcp.server",
    "version": "1.0.0",
    "sha256": "替換成 archive 的 64 位 SHA-256",
    "entrypoint": ["python3", "./server.py"],
    "share_immutable_package": true
  }
}

artifactPath 使用 bot workspace 的相對路徑Team 模式由伺服器映射至該 bot 的 workspace。Manifest 欄位必須符合此 profile未支援的權限hook 欄位會被拒絕,不能藉此宣告尚未實作的隔離保證。

套件可使用預裝 PythonNode interpreter 或 archive 內的可執行檔。Interpreter 不存在會拒絕安裝;本輪容器驗證使用 Python不宣稱預設 image 已提供 Node。依賴需放在 archive 內,安裝器不執行 pip、npm 或任意系統 hook。

安裝成功回傳 bindingId 與 MCP schemas。模型透過 computer_mcp

{"action":"list"}
{"action":"discover","bindingId":"安裝回傳的 ID"}
{"action":"call","bindingId":"安裝回傳的 ID","tool":"工具名稱","arguments":{}}

每個 binding 有獨立 UID、私人 HOME/state程式碼唯讀。share_immutable_package=false 時,程式碼也使用該 binding UID 才可讀的副本。每次呼叫重新驗證檔案、manifest 版本與綁定,啟動真正的 MCP SDK client結束後清除該 UID 的子程序。state 保留,但目前沒有常駐 instance。

目前限制archive 8 MiB、解包 32 MiB512 members、32 個套件、64 個儲存中的 bindings拒絕 symlink、hardlink、特殊檔與路徑逃逸。呼叫有 45 秒 deadline、256 MiB address space、32 個該 UID 程序與 256 個 descriptors 的限制。這不是完整網路syscall sandboxgrants、broker、狀態磁碟 quota 與長期 GC 仍需補齊。

既有 revoke/remove API 會先關閉中央 admission再要求 Runner 關閉 binding 並清理程序;無法確認 drain 時回報未完成,不宣稱未知外部效果已回滾。通用套件可在版本切換表單輸入已安裝的目標版本來升級或回滾。已撤銷套件可在安裝表單勾選重新授權,或在安裝 API body 增加 "reauthorize": true:確認舊 runtime 已停止後,建立新 bindingUID私人狀態舊 ID 永不恢復權限。仍需提供同一版本與 digest 的 archive重試會沿用新的 installing intent。

驗證:設定 DATABASE_URL 指向拋棄式測試 PostgreSQL再執行 make test-runner-jobsSQLx 帳號須可建立測試資料庫)。此指令建立隔離容器,使用 Bookworm build stage 的 controld binary執行 Runner、HTTP MCP、archive/stdio MCP、Rust Docker transport 與 API dispatcher→真實 Supervisor→Computer 的檔案回應遺失恢復測試;結束後清除測試容器與 Supervisor 程序。

Tool Manager 可重新探索 schemas或輸入工具名稱與 JSON object 參數手動呼叫:

  • POST /api/bots/{botId}/tools/{bindingId}/discover:重新讀取工具 schemas。
  • POST /api/bots/{botId}/tools/{bindingId}/callbody 為 {"operationId":"UUID","tool":"工具名稱","arguments":{}}

手動呼叫沿用操作 journal。相同 IDpayload 回傳原結果;更改 payload 卻沿用 ID 會拒絕未知效果不重做。UI 在目前瀏覽器分頁保存最近操作 ID 與請求雜湊(不保存參數),重新整理後重新輸入相同請求仍重用該 ID。變更請求、建立新操作或關閉分頁後重新開啟會使用新 ID效果未知時需先查明狀態。

版本切換 APIPOST /api/bots/{botId}/tools/{bindingId}/switchbody 為 {"operationId":"UUID","version":"1.0.0"}。目標必須是同一 Computer 已安裝的同名套件版本。切換保留來源 binding 的 UID 與私人 state若該 bot 已有目標版本 binding先等待其現有呼叫完成再撤銷該目標 binding避免兩個 active authorization 混用。

中央先 durable reserve transition、關閉參與 bindings 的新呼叫,再執行 root retire/switch/schema discovery版本 pointer、ready 與 schemas 在同一 DB transaction 完成。忙碌或回應遺失時用同一 operation ID 重試UI 重新載入可恢復 pending operation。完成後舊請求只重放 receipt不重新切換。

撤銷任何參與 binding 會取消整筆 transition並關閉所有參與 bindings確認 runtime drain 後才結束 cancelling。跨 Computer generation 的 pending transition 會先讀取受保護的 root receipt並重新驗證目前套件 bytes。只有「沒有 receipt 且仍在來源版本」或「有 receipt 且仍在目標版本」可更新中央 generation 並繼續。root binding程式紀錄遺失或版本已被其他操作取代時保留 pending需撤銷清理後重新建立。這仍不是 full V1 manifest帳戶 schema grant registry常駐 pool 的完成宣告。

新建 Computer 將 Runner registry、package cache、private executables 與 tool state 分別掛載到 DATA_DIR/runtime/{homeKey} 的 root-owned 子目錄,與 task home 分離。已有持久掛載的 Computer 可在 remove/recreate 後保留這些內容。舊 Computer 在替換/刪除前會停止並將 writable-layer runtime 封存到受保護 staging驗證與持久發布全部完成後才移除來源未完成時保留來源並可重試。資料目錄搬移、非空目的地或快照不符會拒絕覆寫。

舊 runtime 遷移使用 Rust tar loader保留 numeric UID/GID、檔案權限、一般檔案、目錄及 symlink/hardlink不執行套件內容或外部解包程式。每個來源目錄限制 8 GiB100,000 archive entries拒絕特殊檔、路徑逃逸、重複成員、未宣告父目錄與不受保護的 root。檔案與目錄 fsync 後才發布發布中斷可恢復SHA-256 快照涵蓋實際內容、路徑、owner/mode 與 symlink target。限制或驗證失敗會保留停止中的舊容器不以成功回報掩蓋資料缺漏。