Sandbox CLI 使用指南
Sandbox CLI 使用指南
使用 xapi-to 完成报价、创建、执行、文件、端口、生命周期、历史与审计。
xapi-to sandbox 为 Agent 和自动化脚本提供机器可读的 Sandbox 生命周期命令。
普通输出默认为 JSON,可使用 --format pretty 或 --format table 提高可读性。
安装与密钥
推荐从标准输入保存已有密钥,避免出现在 shell history:
CLI 按以下顺序读取密钥:XAPI_KEY → XAPI_API_KEY → ~/.xapi/config.json。
选择环境
生产 Sandbox Gateway 默认为 sandbox.xapi.to。测试 Sandbox 使用:
也可为单条命令传入:
test.xapi.to 是测试站 Console,Sandbox API 的实际主机是
sandbox.test.xapi.to。目前没有 test.xapi.ai 或 ai.test.xapi.to AI 网关;
详见测试环境与日志。
一键执行(推荐)
sandbox run 会依次执行:
也可把裸 -- 后的内容作为命令:
重点检查输出字段:
result.exitCode / stdout / stderr:远程执行结果;cleanup.operationStatus / state:清理操作和服务端终态;finalState:应为TERMINATED,或供应商终态FAILED;totalCost:服务端结算费用,不是客户端按墙钟时间估算的数字。
远程命令非零退出后,CLI 会先清理实例,再把非零状态映射为本地进程退出码。
SIGINT 和 SIGTERM 也会触发清理。
--keep 会跳过自动销毁,实例继续计费。只有明确需要保留工作区时才使用,并记录
实例 ID 和后续清理责任人。
JavaScript 全流程演示
CLI 源码仓库提供一个不依赖预先实例 ID 的独立演示脚本。它按顺序展示直接 HTTP API、
本地新版 CLI,以及 OpenAI Agents SDK + ai.xapi.to DeepSeek + xAPI Sandbox:
默认目标为生产 Sandbox。直接 API 和 CLI 场景使用 XAPI_SANDBOX_KEY;OpenAI 场景的
计算层仍使用该生产 Key,模型层使用 XAPI_AI_KEY 调用正式 ai.xapi.to。需要测试
Sandbox 时必须显式设置 XAPI_SANDBOX_HOST=sandbox.test.xapi.to 并改用测试 Key。最终报告分别显示
两项凭据的脱敏 preview 和来源。每套流程自行报价、创建、验证并终止实例;最终 JSON
验证 marker、TERMINATED、操作成功、用量/账单结清、服务端费用和账户活动实例为零。
先看目录,再报价
--format table 适合快速比较规格;被截断的单元格会以 … 结尾。复制完整的
quoteId、实例 ID 或嵌套费率信息时,请使用默认 JSON 或 --format pretty。
常用选型参数:
每个子命令都有独立帮助,例如 xapi-to sandbox create --help 和
xapi-to sandbox run --help。CLI 会在发起请求前拒绝未知参数,避免参数拼写错误被静默忽略。
--offering-id 是精确规格选择,不能与 --max-hourly-usd 同时使用。需要价格保护时,
请使用 requirements 参数触发受上限约束的报价,或者使用已经核对过价格的 quoteId。
固定供应商会派生受控主机,例如生产环境的 daytona-sandbox.sandbox.xapi.to。CLI 只会向
*.xapi.to 或显式 localhost 发送 Sandbox 密钥,不接受任意供应商 URL。生产环境中
--provider daytona / e2b 会分别解析到已部署的
daytona-sandbox.sandbox.xapi.to / e2b-sandbox.sandbox.xapi.to;测试环境仍使用
daytona.sandbox.test.xapi.to / e2b.sandbox.test.xapi.to。
多步骤生命周期
当 Agent 需要在多次文件和命令调用之间保留状态时,使用细粒度命令:
--idempotency-key 应来自稳定的业务任务 ID。响应丢失后不要随意生成新 key 重试创建;
第一次请求可能已经生成计费实例,应先查历史确认。
创建成功时,CLI 会返回 clientIdempotencyKey。如果实例已经创建,但 --wait 等待失败,
结构化错误会包含 instanceId、observedState、clientIdempotencyKey,以及对应的
get/terminate 恢复命令,避免实例失联后继续计费。
命令与工作目录
返回 exitCode、stdout、stderr 和耗时。不要只搜索 stdout 中的文本来判断成功;
同时检查退出码,并在必要时读取生成的产物。
文件与产物
CLI 会以 base64 传输本地二进制文件;--output 使用“只创建新文件”语义,拒绝覆盖
已有本地路径。
Web 预览与端口
先从 Offering 确认同时支持 backgroundExec 与 ports。实例内服务监听 0.0.0.0
后,可取得临时公网地址:
不要用 nohup ... & 模拟标准后台能力:部分供应商会在前台 exec 会话结束时回收子进程。
后台命令返回 session/command ID 只表示已接受;取得 URL 后仍应带上端口响应中的
headers(如有),从外部请求并验证预期 marker。返回 URL 不等于 DNS、TLS 和应用已经
就绪;使用有上限的重试,失败后仍要销毁实例。销毁后临时 URL 会失效。
挂起与恢复
先检查 Offering 的 lifecycle.suspension 声明:
文件系统、内存和进程是否保留由 Offering 分别声明。不要因为供应商支持“暂停”就假设 所有运行时状态都还在。挂起可能降低计算费,但仍需以实时账单为准。
GPU 与供应商扩展
管理型 GPU Offering 可能不暴露标准 Shell,而是通过扩展返回连接信息:
扩展 ID 必须来自 Offering 的 capabilities.extensionIds,不要猜测未声明的扩展。
历史、日志与账单
Console 中的统一入口是 Console → Sandboxes:
- 监控:并发、创建速率和消费;
- 实例列表:当前与历史实例;
- 调用日志:跨实例的 CREATE、EXEC、FILE、PORT 和状态操作。
测试环境入口和日志分流规则参见测试环境与日志。
中断后的恢复
SIGKILL、机器断电或网络分区无法执行本地 finally。恢复连接后:
若 terminate 返回状态冲突,说明另一个状态操作仍在进行;先读取服务端状态,再在转换结束后
重试。最终以 observedState 和账单终态为准。