lazyBoy/docs/tool-packages.md

64 lines
6.3 KiB
Markdown
Raw Permalink Normal View History

2026-09-11 02:47:43 +00:00
# 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`
```json
{
"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`
```json
{"action":"list"}
```
```json
{"action":"discover","bindingId":"安裝回傳的 ID"}
```
```json
{"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-jobs`SQLx 帳號須可建立測試資料庫)。此指令建立隔離容器,使用 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}/call`body 為 `{"operationId":"UUID","tool":"工具名稱","arguments":{}}`
手動呼叫沿用操作 journal。相同 IDpayload 回傳原結果;更改 payload 卻沿用 ID 會拒絕未知效果不重做。UI 在目前瀏覽器分頁保存最近操作 ID 與請求雜湊(不保存參數),重新整理後重新輸入相同請求仍重用該 ID。變更請求、建立新操作或關閉分頁後重新開啟會使用新 ID效果未知時需先查明狀態。
版本切換 API`POST /api/bots/{botId}/tools/{bindingId}/switch`body 為 `{"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。限制或驗證失敗會保留停止中的舊容器不以成功回報掩蓋資料缺漏。