CubeSandbox 提供方

View on GitHub ↗

CubeSandbox 提供方

CubeSandbox 是目录提供方,源码在 awesome-providers/cubesandbox,id 是 cubesandbox。用 abx provider install alibaba-agent-sandbox/awesome-providers//cubesandbox --allow-unpinned --yes(或 python -m agent_sandbox.providers install registry:cubesandbox --yes)安装。Sandbox.create(provider="cubesandbox") 和 abx --provider cubesandbox 用宿主里的 E2B 协议类,加上 provider.mjs 里的几处覆盖,访问 CubeAPI。

清单是 kind = "node":Node.js 宿主加载 provider.mjs,Python SDK 通过本机引擎(abx provider engine serve)使用它。自己的说明在 awesome-providers/cubesandbox/docs/README.md。

控制面路径来自 openapi.yml 和官方 Python SDK。单元测试不需要一台正在运行的 CubeSandbox。它在 127.0.0.1 上用本地 TCP 服务回答 POST /sandboxes。

真实创建需要 127.0.0.1:3000 上有 CubeAPI。一键安装在这台机器上停在预检:根文件系统是 overlay,不是 /data/cubelet 要求的 XFS,而且 init 是 tini,不是 systemd。端口 3000 没有进程,所以真实创建没有执行。

配置

字段 类型 环境变量 默认
base_url url ABX_CUBESANDBOX_BASE_URL http://127.0.0.1:3000
api_key 密钥,可选 ABX_CUBESANDBOX_API_KEY 不设置
domain 字符串 ABX_CUBESANDBOX_DOMAIN cube.app

默认源站用 3000 端口,因为 Cube Python SDK 的 README 把 CUBE_API_URL 写成 http://127.0.0.1:3000。用 provider_options={"base_url": "..."} 覆盖。这个值是 CubeAPI 的源站,不带路径前缀。请求打到 /sandboxes,不是 /cubeapi/v1/sandboxes。

设置了 api_key 时,客户端发送 X-API-Key。没设置时不发送认证头。本地 CubeAPI 允许这样。这个提供方不读 ABX_SANDBOX_API_KEY。那个变量是阿里云极速版的密钥。

domain 是端口主机名 {port}-{sandboxID}.{domain} 的后缀。

from agent_sandbox import Sandbox

sb = await Sandbox.create(
    provider="cubesandbox",
    provider_options={
        "base_url": "http://127.0.0.1:3000",
        "api_key": "...",
        "domain": "cube.app",
    },
    template="base",
    timeout=60,
)

这个适配器会调用的能力

能力 共享协议发出的 HTTP Cube 上是否有
sandbox.lifecycle POST /sandboxes、GET /sandboxes、GET /sandboxes/{id}、DELETE /sandboxes/{id}、GET /v2/sandboxes OpenAPI 和 SDK 都有
sandbox.timeout POST /sandboxes/{id}/timeout OpenAPI 和 SDK 都有
sandbox.pause POST /sandboxes/{id}/pause 和 POST /sandboxes/{id}/resume OpenAPI 和 SDK 都有
exec.run、exec.stream envd 端口 49983 上的 POST /process.Process/Start Cube Python SDK
files.rw envd 的 GET /files、POST /files,以及 POST /filesystem.Filesystem/{Stat,ListDir,MakeDir,Remove,Move}。用户名默认 root Cube Python SDK
files.watch envd POST /filesystem.Filesystem/WatchDir Cube Python SDK 的 files.watch_dir
code.interpret envd Connect POST /code.CodeInterpreter/Execute 不是 Cube SDK 的路径,见下
ports.url 本地计算 {port}-{sandboxID}.{domain} Cube SDK 的 get_host

connect 先发 POST /sandboxes/{id}/connect(Cube 用它恢复暂停的沙箱)。这个路径返回 4xx 时再退回 GET /sandboxes/{id}。进程和文件请求在调用方没写用户时带 root,因为 Cube envd 会拒绝空用户。

run_code 发到 http://49999-{id}.{domain}/execute,正文是 code、language、env_vars,响应按 ndjson 读。不在节点上时设置 ABX_CUBESANDBOX_PROXY=主机:80,TCP 打到代理,Host 仍是虚拟主机名。

会抛出 E8004 的调用

这些不在 features 里。feature_gate 在发出 HTTP 之前拒绝对应的协议方法。Provider.require 以同样的方式拒绝能力 id。

能力 被拒绝的内容
files.transfer 仅靠签名或 token 的文件 URL
pty 交互终端
templates.read、templates.build 模板列表和构建
sessions SandboxServer 上的具名命令
process.manage 进程列表、标准输入和信号。exec.run 仍然可以启动命令
ports.domain 单独的域名式能力 id。端口主机名仍然使用 domain
storage.mount 通用挂载能力
network.vpc VPC

扩展

OpenAPI 里有三项不属于 18 个固定能力、又是 Cube 自己的能力。它们登记为 implemented=False、when="sandbox"。这个适配器不会调用它们。

Id OpenAPI
volume.mounts NewSandbox.volumeMounts、/volumes
network.policy 创建体里的 network,以及 PUT /sandboxes/{id}/network
distribution.scope NewSandbox.distributionScope

extensions_for 在没有沙箱 id 时返回空。传入沙箱 id 后,这三项都会出现,因为 when 是 sandbox。它们的 implemented 是 false,所以 require_extension 抛出 E8004。没有沙箱时,describe()["extensions"] 仍然列出它们。

下面这些 OpenAPI 操作也存在,但没有登记。它们不是上面那三项 Cube 专有能力,这个适配器也不调用:GET /health、POST /sandboxes/{id}/refreshes、GET /sandboxes/{id}/logs、POST /sandboxes/{id}/snapshots、POST /sandboxes/{id}/rollback、GET /snapshots,以及 /templates 构建接口。