
如何构建并发布自定义的 Fleet 兼容 OCI 来宾镜像再从 Sandbox SDK 引用它【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua当内置的 Ubuntu 24.04 或 Windows Server 2022 VM 镜像不包含你的负载所需的软件或启动配置时就需要为 Cua Fleet 池准备自己的来宾镜像先在 SDK 的 claim 路径之外构建可启动来宾把它发布为带不可变摘要digest的 OCI 构件再从 Sandbox SDK 用Image.from_registry(...)引用它。本文基于cua-sandbox0.4.3由cua0.1.6 导出的 Python 接口。先明确一个边界Fleet 不从 SDK 的 image-builder 全套能力构建沙箱环境。SDK 不会替你构建构件、转换磁盘文件也不会在 claim 时套用 SDK 层。在 0.4.3 中Fleet 会拒绝携带 setup 层apt_install、pip_install、uv_install、run、copy、env、快照来源或本地磁盘路径的镜像输入只接受发布在先的注册表构件。因此这是一条先构建、先发布、再引用的已发布镜像工作流而不是在Image构造器上叠加配置层。开始之前Fleet 凭据与访问校验Fleet 池需要独立的凭据cua auth login保存的是交互式 CLI 会话不能用于 SDK。SDK 接受两类凭据创建与撤销流程见 Set up Fleet credentialsOAuth 用户 API keyCUA_CLIENT_IDCUA_CLIENT_SECRET在 Fleet 控制台创建密钥只显示一次已有的 Fleet bearer tokenFLEETS_TOKEN。FLEETS_TOKEN的优先级高于客户端凭据改用用户 key 时要先unset FLEETS_TOKEN。下方 token endpoint 是run.cua.ai的默认值export CUA_CLIENT_IDyour-client-id export CUA_CLIENT_SECRETyour-client-secret export CUA_TOKEN_URLhttps://auth.cua.ai/realms/cyclops-cs/protocol/openid-connect/token unset FLEETS_TOKENyour-client-id/your-client-secret需替换为你创建的 API key 的 Client ID 与 Client Secret文档建议通过 secret manager 注入不要提交到源码或粘贴进共享日志。在同一 shell 中运行下面的只读访问检查需要已安装uv。它用用户 key 换取短期 access token发送GET /api/namespaces只打印返回的 namespace 数量不创建 pool 或 claimuv run --with httpx0.27,1 python - PY import os import httpx with httpx.Client(timeout30) as client: token_response client.post( os.environ[CUA_TOKEN_URL], auth(os.environ[CUA_CLIENT_ID], os.environ[CUA_CLIENT_SECRET]), data{grant_type: client_credentials}, ) token_response.raise_for_status() access_token token_response.json()[access_token] response client.get( https://run.cua.ai/api/namespaces, headers{Authorization: fBearer {access_token}}, ) response.raise_for_status() print(fFleet access verified: {len(response.json())} namespace(s).) PY成功返回 0 个 namespace 是合法状态尚无池的账号。token 请求失败时检查 client ID、secret 与 token endpointFleet 请求返回401或403时先解决账号访问问题。注意这个检查只验证认证与 namespace 列表池创建仍取决于账号权限、准入规则和可用资源。1. 在 claim 路径之外构建来宾镜像在请求 Fleet 启动它之前先准备好操作系统、已安装软件、启动行为和服务布局。发布出去的 OCI 构件必须已经携带 Fleet 期望的可启动来宾镜像Sandbox SDK 的 Fleet VM 模板引用一个 containerDisk 构件来宾磁盘位于/disk/disk.img。普通应用容器不是它的替代品。选镜像时以你的 Fleet 部署为约束选择一个来宾构件与部署兼容、且部署能拉取的注册表。SDK 接受引用不代表它验证了注册表访问、guest 支持或就绪状态这些需要单独的验证。如果只需要内置镜像可以直接使用 OS and image catalog 中记录的 Ubuntu 24.04 与 Windows Server 2022 注册表映射无需发布自己的构件本文覆盖自定义场景。2. 以不可变方式发布 OCI 构件把完成的构件推送到一个 Fleet 部署能够拉取的注册表并优先使用不可变 digest 而不是可变 tag文档给出的引用形式示例为registry.example/fleet/workspacesha256:...上面的引用是文档中的示例形式运行前替换为你实际发布的构件引用。固定 digest 让你能说清一个池到底启动了哪份 boot 镜像可变 tag 会削弱这一保证因为同一个池规格可能随时间解析到不同的来宾镜像。同时注意验证边界digest 只标识了注册表内容它不证明 Fleet 能拉取该构件、guest 架构与运行时匹配、或服务可以工作——这些都要另行验证。3. 从 Sandbox SDK 引用已发布镜像用Image.from_registry(...)引用构件用.expose(...)声明镜像额外启动的 Fleet 服务import asyncio from cua import Image, Sandbox async def main(): image ( Image.from_registry( registry.example/fleet/workspacesha256:..., os_typelinux, kindvm, ) .expose(3000) ) async with Sandbox.ephemeral(image) as sb: result await sb.shell.run(uname -a) print(result.stdout) asyncio.run(main())示例中的注册表引用需要替换为你发布的 Linux VM 构件。几个直接约束执行行为的点Image.from_registry()默认os_typelinux、kindNone不会检查磁盘来推断操作系统。Windows VM 构件要显式传os_typewindows, kindvmOS 提示控制生成的固件配置0.4.3 的FleetCloudTransport会为 Windows 生成Firmware.EFI。使用 SDK 默认服务配置时你发布的镜像必须已经在端口8000上启动 computer-server 服务。生成的模板声明server服务并探测该端口的就绪状态SDK 还会等待其/statusendpoint 后才返回已连接的沙箱。示例中的Sandbox.ephemeral(image)创建临时池和 claim与Pool.claim()、Sandbox.create(pool...)使用同一个FleetTransport它不创建 localhost listener且该 transport 在 0.4.3 中不实现tunnel.forward()。0.4.3 的镜像版Sandbox.ephemeral()只接受默认区域us-east-1Pool.apply()没有区域参数。.expose(3000)把端口声明为命名服务port-3000。声明只告知池模板暴露该端口不会安装或启动任何服务——guest 必须自己在该端口上运行应用。如果只需要默认的8000computer-server endpoint就不需要额外的 expose。显式池配置可以用不同的服务布局参数契约见 Pool reference。4. 向命名服务发送认证请求在沙箱上下文内用sb.services.request()向命名服务发送认证 HTTP 请求。示例中的/healthz要替换成你的服务实际实现的路由response await sb.services.request(port-3000, methodGET, path/healthz) response.raise_for_status() print(response.text)服务 URL 标识的是 Fleet 代理内的 endpoint本身不授予访问权限请求使用 Fleet 连接的认证租约。5. 完整示例用 digest 固定的公开镜像走通引用路径Omarchy Fleet 配方演示了与自定义镜像完全相同的引用 claim 验证模式对象是一个真实已发布、digest 固定的 amd64 KubeVirt containerDisk 镜像其内来宾磁盘同样在/disk/disk.img。其前置条件Python3.11,3.14、uv、cua-sandbox0.4.3以及一组可以管理池的 Fleet 凭据。镜像引用为public.ecr.aws/k5j5w0x5/cua-omarchy-workspacesha256:dc448dcc986f443980dfb3586f1b91d8699091ad96a74b369016535f0dbb0342下面摘录自配方的run_omarchy_fleet.py省略了配方中的截图、剪贴板与 MCP 连接演示完整脚本以原文档为准# /// script # requires-python 3.11,3.14 # dependencies [ # cua-sandbox0.4.3, # ] # /// import asyncio import os from cua_sandbox import Image, Pool IMAGE os.environ.get( OMARCHY_IMAGE, public.ecr.aws/k5j5w0x5/cua-omarchy-workspace sha256:dc448dcc986f443980dfb3586f1b91d8699091ad96a74b369016535f0dbb0342, ) POOL_NAME os.environ[CUA_POOL_NAME] async def main() - None: image Image.from_registry(IMAGE, os_typelinux, kindvm) pool await Pool.apply( image, namePOOL_NAME, replicas1, cpu4, memory_mb6144, services{server: 8000, mcp: 3000}, ttl_seconds_after_created21600, ) try: async with pool.claim(serviceserver, time_to_start1800) as sandbox: print(fSandbox: {sandbox.name}) result await sandbox.shell.run(pgrep -a Hyprland) if not result.success: raise RuntimeError(result.stderr) print(result.stdout.strip()) finally: await pool.delete() asyncio.run(main())运行前设置一个全局唯一、小写 DNS-label 的池名池名跨 Cua 账号全局唯一重名就换一个再跑export CUA_POOL_NAMEmy-team-omarchy-pool uv run run_omarchy_fleet.pyPool.apply()创建或协调命名池及其模板services中server: 8000承载截图、shell、键盘、鼠标、剪贴板操作mcp: 3000承载 Cua Driver MCP endpoint/mcp。await pool.claim()等待绑定与服务就绪后才返回已连接的Sandboxasync with形式在退出时调用close()释放 claim。finally中的pool.delete()删除池及其模板仅当作用于Pool.apply()的返回值时同时删除对应沙箱——claim 和池删除前保存你需要的截图或文件。示例中的ttl_seconds_after_created21600六小时是配方为任务型负载选的默认值想要可复用热池就省略finally删除、只在结束后显式删除池。成功标志claim 在服务就绪后返回沙箱pgrep -a Hyprland输出进程行说明 guest 已完成无人值守启动并运行目标桌面。6. 排查与限制配方文档给出的启动排查顺序Pool.apply()期间出现 HTTP 403确认镜像仓库包含在 Fleet 准入策略内且你的凭据能在所选 namespace 中创建池。claim 超时确认镜像是 amd64 KubeVirt containerDisk、引用包含精确 digest、server服务配置在端口8000。截图黑屏或空白先检查镜像的无人值守启动和cua-computer-server服务再调试 Fleet transport。MCP 连接失败以暴露了mcp服务端口3000的方式 claim并通过sandbox.services向/mcp发请求。其余版本限制被接受的镜像规格或生成的 Fleet 模板只证明 SDK 行为不证明 guest 会在所有宿主或部署上启动注册表访问、账号权限、资源上限、容量和就绪状态属于部署侧要求。默认模板探测只检查 server 端口不检查每个附加服务server 就绪不代表 MCP endpoint 或应用服务可用。Windows 镜像不包含 Windows 许可证使用前需确认自己的许可证覆盖目标用途含托管与虚拟化权利。镜像版Sandbox.ephemeral()在 0.4.3 只接受regionus-east-1。延伸阅读How Fleet images workFleet 镜像与 SDKImage的分层、身份与兼容性边界。Sandbox runtime support0.4.3 的版本化接受规则、镜像定制矩阵与 transport 契约。Choose a Fleet image在已发布目录中选镜像、判断何时才需要自定义构件。Create a sandbox pool with Python池创建与 claim 的完整操作路径。【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考