feat(sandbox): add official image presets and template image selection

This commit is contained in:
chenanran555
2026-09-09 16:45:37 +08:00
parent e1eadad184
commit f4e479ce80
10 changed files with 484 additions and 53 deletions
+2
View File
@@ -207,6 +207,7 @@ import {
managedAgentFileDownload,
managedAgentFileDelete,
sandboxCreate,
sandboxOfficialImages,
sandboxList,
sandboxGet,
sandboxConnect,
@@ -437,6 +438,7 @@ export const commands: Record<string, AnyCommand> = {
"managed-agent file download": managedAgentFileDownload,
"managed-agent file delete": managedAgentFileDelete,
"sandbox create": sandboxCreate,
"sandbox official-images": sandboxOfficialImages,
"sandbox list": sandboxList,
"sandbox get": sandboxGet,
"sandbox connect": sandboxConnect,
@@ -0,0 +1,88 @@
import { defineCommand, detectOutputFormat, UsageError } from "bailian-cli-core";
import { emitBare, emitResult } from "bailian-cli-runtime";
/** Pinned CLI presets, not a live catalog or a guarantee of regional availability. */
export const SANDBOX_IMAGES = [
{
id: "code-interpreter",
imageName: "代码解释器",
imageUrl: "fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/code-interpreter-v1:v0.0.44",
icon: "https://img.alicdn.com/imgextra/i2/O1CN01iX8RH9ckFvC093x2_!!6000000000905-2-tps-72-72.png",
description: {
"en-US": "Python / Node.js runtimes with common data-processing libraries",
"zh-CN": "Python / Node.js 运行时+常用数据处理库",
},
},
{
id: "browser",
imageName: "浏览器",
imageUrl: "fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.44",
icon: "https://img.alicdn.com/imgextra/i4/O1CN01ShCbPEunrRI093x2_!!6000000000155-2-tps-72-72.png",
description: {
"en-US": "Chromium and a visual desktop for clicking, filling forms, and screenshots",
"zh-CN": "Chromium +可视化桌面,支持点击/ 填表/截图",
},
},
{
id: "all-in-one",
imageName: "全能型",
imageUrl: "fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/all-in-one:v0.0.44",
icon: "https://img.alicdn.com/imgextra/i1/O1CN01smhklUahsyE093x2_!!6000000006657-2-tps-72-72.png",
description: {
"en-US": "Code execution and browser capabilities together",
"zh-CN": "代码执行+浏览器双能力",
},
},
] as const;
export const SANDBOX_IMAGE_CHOICES = SANDBOX_IMAGES.flatMap((image) => [image.id, image.imageName]);
export const SANDBOX_IMAGE_NOTES = SANDBOX_IMAGES.map((image) => ({
"en-US": `${image.id} (${image.imageName}): ${image.description["en-US"]}. ${image.imageUrl}`,
"zh-CN": `${image.id}(${image.imageName}):${image.description["zh-CN"]}。${image.imageUrl}`,
}));
export function resolveSandboxImage(selector: string) {
const image = SANDBOX_IMAGES.find(
(candidate) => candidate.id === selector || candidate.imageName === selector,
);
if (!image) {
throw new UsageError(
`Unknown built-in image / 未知内置镜像: ${selector}. ${SANDBOX_IMAGE_CHOICES.join(", ")}`,
);
}
return image;
}
export const sandboxOfficialImages = defineCommand({
description: {
"en-US": "List the built-in Sandbox base images (offline)",
"zh-CN": "列出 CLI 内置的 Sandbox 基础镜像(离线)",
},
auth: "none",
exampleArgs: ["", "--output json", "--quiet"],
notes: [
{
"en-US":
"Use a preset ID or Chinese name with template create/update --image. These are pinned cn-beijing images; other environments may differ. Use --from-image for a custom image.",
"zh-CN":
"在 template create/update 中通过 --image 传入预设 ID 或中文名。这些是固定版本的 cn-beijing 镜像,其他环境可能不同;自定义镜像使用 --from-image。",
},
...SANDBOX_IMAGE_NOTES,
],
async run(ctx) {
if (ctx.settings.quiet) {
for (const image of SANDBOX_IMAGES) emitBare(image.id);
return;
}
if (detectOutputFormat(ctx.settings.output) === "json") {
emitResult(SANDBOX_IMAGES, "json");
return;
}
for (const image of SANDBOX_IMAGES) {
emitBare(`${image.id} (${image.imageName})`);
emitBare(` ${image.imageUrl}`);
emitBare(` ${image.description["en-US"]} / ${image.description["zh-CN"]}`);
}
},
});
@@ -13,6 +13,7 @@ import {
type Settings,
} from "bailian-cli-core";
import { createSpinner, emitBare, emitResult, formatTable } from "bailian-cli-runtime";
import { resolveSandboxImage, SANDBOX_IMAGE_CHOICES, SANDBOX_IMAGE_NOTES } from "./images.ts";
import {
BODY_FLAG,
displayValue,
@@ -69,6 +70,15 @@ const TEMPLATE_ID_FLAG = {
} satisfies FlagsDef;
const TEMPLATE_MUTATION_FIELDS = {
image: {
type: "string",
valueHint: "<preset>",
choices: SANDBOX_IMAGE_CHOICES,
description: {
"en-US": "Built-in image ID or Chinese name; fills fromImage and imageName",
"zh-CN": "内置镜像 ID 或中文名;自动填写 fromImage 和 imageName",
},
},
name: {
type: "string",
valueHint: "<name>",
@@ -198,6 +208,11 @@ const BUILD_STATUS_FLAGS = {
} satisfies FlagsDef;
function applyTemplateMutationFlags(body: JsonObject, flags: CreateFlags | UpdateFlags): void {
if (flags.image !== undefined) {
const image = resolveSandboxImage(flags.image);
body.fromImage = image.imageUrl;
body.imageName = image.imageName;
}
setDefined(body, "name", flags.name);
setDefined(body, "cpuCount", flags.cpuCount);
setDefined(body, "memoryMB", flags.memoryMb);
@@ -356,12 +371,20 @@ export const sandboxTemplateCreate = defineCommand({
usageArgs: "(--name <name> --cpu-count <cores> --memory-mb <mb> | --body <json|@path>) [flags]",
flags: CREATE_FLAGS,
exampleArgs: [
"--name browser --image browser --cpu-count 1 --memory-mb 2048",
"--name python --cpu-count 1 --memory-mb 2048",
"--body @template.json --async --output json",
"--name browser --cpu-count 4 --memory-mb 8192 --dry-run --output json",
],
notes: [
...SANDBOX_NOTES,
...SANDBOX_IMAGE_NOTES,
{
"en-US":
"--image overrides body fromImage/imageName; explicit --from-image/--image-name override the corresponding preset fields. Without --image, image behavior is unchanged.",
"zh-CN":
"--image 覆盖 body 中的 fromImage/imageName;显式 --from-image/--image-name 再覆盖对应预设字段。不传 --image 时保持原有镜像行为。",
},
{
"en-US": "File mounts and other complete nested structures can be supplied through --body.",
"zh-CN": "文件挂载等完整嵌套结构可通过 --body 提供。",
@@ -480,12 +503,20 @@ export const sandboxTemplateUpdate = defineCommand({
usageArgs: "--template-id <id> (--body <json|@path> | [fields])",
flags: UPDATE_FLAGS,
exampleArgs: [
"--template-id tpl-xxx --image all-in-one",
"--template-id tpl-xxx --cpu-count 4 --memory-mb 8192",
"--template-id tpl-xxx --body @template-update.json --async --output json",
"--template-id tpl-xxx --description updated --dry-run --output json",
],
notes: [
...SANDBOX_NOTES,
...SANDBOX_IMAGE_NOTES,
{
"en-US":
"--image overrides body fromImage/imageName; explicit --from-image/--image-name override the corresponding preset fields. Without --image, image behavior is unchanged.",
"zh-CN":
"--image 覆盖 body 中的 fromImage/imageName;显式 --from-image/--image-name 再覆盖对应预设字段。不传 --image 时保持原有镜像行为。",
},
{
"en-US": "Supplying envConfig or --env replaces the template's complete environment map.",
"zh-CN": "传入 envConfig 或 --env 会整体替换模版的环境变量 Map。",
+1
View File
@@ -223,6 +223,7 @@ export { default as skillUpdate } from "./commands/skill/update.ts";
export { default as skillRemove } from "./commands/skill/remove.ts";
export { default as skillList } from "./commands/skill/list.ts";
export { default as skillInit } from "./commands/skill/init.ts";
export { sandboxOfficialImages } from "./commands/sandbox/images.ts";
export {
sandboxConnect,
sandboxCreate,
@@ -27,6 +27,18 @@ function runCommandE2e(routes: typeof SANDBOX_ROUTES, args: string[]) {
}
describe("e2e: Sandbox command discovery", () => {
test("built-in images are discoverable without API Key authentication", async () => {
const { stderr, exitCode } = await runCommandHelp(SANDBOX_ROUTES, [
"sandbox",
"official-images",
"--help",
]);
expect(exitCode, stderr).toBe(0);
expect(stderr).toContain("Usage: bl sandbox official-images");
expect(stderr).not.toContain("Authentication: API Key");
expect(stderr).toContain("code-interpreter");
expect(stderr).toContain("all-in-one");
});
test.each([
["sandbox", "create"],
["sandbox", "list"],
@@ -69,6 +81,8 @@ describe("e2e: Sandbox command discovery", () => {
]);
expect(exitCode, stderr).toBe(0);
expect(stderr).toMatch(/--max-running-time <seconds>/);
expect(stderr).toMatch(/--image <[^>]*code-interpreter[^>]*browser[^>]*all-in-one[^>]*>/);
expect(stderr).toContain("browser:v0.0.44");
expect(stderr).toMatch(/--async/);
expect(stderr).toMatch(/--poll-interval <seconds>/);
expect(stderr).toMatch(/waits for build status ready/i);
@@ -76,6 +90,109 @@ describe("e2e: Sandbox command discovery", () => {
});
describe("e2e: Sandbox offline validation and dry-run", () => {
test("image catalog is available offline in JSON, text, and quiet output", async () => {
const jsonResult = await runCommandE2e(SANDBOX_ROUTES, [
"sandbox",
"official-images",
"--output",
"json",
]);
expect(jsonResult.exitCode, jsonResult.stderr).toBe(0);
const images = JSON.parse(jsonResult.stdout) as {
id: string;
imageName: string;
imageUrl: string;
}[];
expect(images.map((image) => image.id)).toEqual(["code-interpreter", "browser", "all-in-one"]);
expect(images[1]).toMatchObject({
imageName: "浏览器",
imageUrl: "fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.44",
});
const textResult = await runCommandE2e(SANDBOX_ROUTES, [
"sandbox",
"official-images",
"--output",
"text",
]);
expect(textResult.exitCode, textResult.stderr).toBe(0);
expect(textResult.stdout).toContain("代码解释器");
expect(textResult.stdout).toContain("browser:v0.0.44");
const quietResult = await runCommandE2e(SANDBOX_ROUTES, [
"sandbox",
"official-images",
"--quiet",
]);
expect(quietResult.exitCode, quietResult.stderr).toBe(0);
expect(quietResult.stdout.trim().split("\n")).toEqual([
"code-interpreter",
"browser",
"all-in-one",
]);
});
test.each([
{
operation: "create",
args: ["--name", "test", "--cpu-count", "1", "--memory-mb", "2048"],
selector: "browser",
method: "POST",
},
{
operation: "update",
args: ["--template-id", "template-test"],
selector: "浏览器",
method: "PUT",
},
])(
"template $operation resolves --image before dry-run output",
async ({ operation, args, selector, method }) => {
const { stdout, stderr, exitCode } = await runCommandE2e(SANDBOX_ROUTES, [
"sandbox",
"template",
operation,
...args,
"--image",
selector,
...AUTH_ARGS,
"--dry-run",
"--output",
"json",
]);
expect(exitCode, stderr).toBe(0);
expect(parseStdoutJson(stdout)).toMatchObject({
method,
request: {
fromImage: "fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.44",
imageName: "浏览器",
},
});
},
);
test("unknown image selector fails before a request", async () => {
const { stderr, exitCode } = await runCommandE2e(SANDBOX_ROUTES, [
"sandbox",
"template",
"create",
"--name",
"test",
"--cpu-count",
"1",
"--memory-mb",
"2048",
"--image",
"unknown",
...AUTH_ARGS,
"--dry-run",
"--output",
"json",
]);
expect(exitCode).toBe(2);
expect(JSON.parse(stderr)).toMatchObject({
error: { code: 2, message: expect.stringContaining("--image") },
});
});
test("create requires a template in flags or body", async () => {
const { stderr, exitCode } = await runCommandE2e(SANDBOX_ROUTES, [
"sandbox",
@@ -184,6 +184,7 @@ export const SKILL_ROUTES: E2eRouteExports = {
export const SANDBOX_ROUTES: E2eRouteExports = {
"sandbox create": "sandboxCreate",
"sandbox official-images": "sandboxOfficialImages",
"sandbox list": "sandboxList",
"sandbox get": "sandboxGet",
"sandbox connect": "sandboxConnect",
@@ -0,0 +1,134 @@
import { ExitCode } from "bailian-cli-core";
import { describe, expect, test } from "vite-plus/test";
import { resolveSandboxImage, SANDBOX_IMAGES } from "../src/commands/sandbox/images.ts";
import {
buildTemplateCreateBody,
buildTemplateUpdateBody,
} from "../src/commands/sandbox/template.ts";
const EXPECTED_IMAGES = [
["code-interpreter", "代码解释器", "code-interpreter-v1"],
["browser", "浏览器", "browser"],
["all-in-one", "全能型", "all-in-one"],
] as const;
describe("Sandbox built-in image presets", () => {
test("contains exactly the three pinned images with icons and bilingual descriptions", () => {
expect(SANDBOX_IMAGES.map((image) => image.id)).toEqual(EXPECTED_IMAGES.map(([id]) => id));
for (const image of SANDBOX_IMAGES) {
expect(image.icon).toMatch(/^https:\/\/img\.alicdn\.com\/.*\.png$/);
expect(image.description["en-US"]).not.toBe("");
expect(image.description["zh-CN"]).not.toBe("");
}
});
test.each(EXPECTED_IMAGES)(
"%s maps both selectors to the exact create/update payload",
async (id, imageName, repositoryName) => {
const fromImage = `fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/${repositoryName}:v0.0.44`;
for (const selector of [id, imageName]) {
expect(resolveSandboxImage(selector)).toMatchObject({ id, imageName, imageUrl: fromImage });
expect(
await buildTemplateCreateBody({
image: selector,
name: "test",
cpuCount: 1,
memoryMb: 2048,
async: false,
}),
).toEqual({ name: "test", cpuCount: 1, memoryMB: 2048, fromImage, imageName });
expect(
await buildTemplateUpdateBody({
image: selector,
templateId: "template-test",
async: false,
}),
).toEqual({ fromImage, imageName });
}
},
);
test("preset fields override body fields without sending catalog metadata", async () => {
expect(
await buildTemplateUpdateBody({
image: "browser",
templateId: "template-test",
async: false,
body: JSON.stringify({ fromImage: "body:latest", imageName: "body", description: "kept" }),
}),
).toEqual({
fromImage: "fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.44",
imageName: "浏览器",
description: "kept",
});
});
test("explicit custom image fields override the corresponding preset fields", async () => {
expect(
await buildTemplateUpdateBody({
image: "browser",
fromImage: "custom:v2",
imageName: "custom name",
templateId: "template-test",
async: false,
}),
).toEqual({ fromImage: "custom:v2", imageName: "custom name" });
expect(
await buildTemplateUpdateBody({
image: "browser",
imageName: "renamed",
templateId: "template-test",
async: false,
}),
).toEqual({
fromImage: "fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.44",
imageName: "renamed",
});
});
test("without --image, display names and custom URLs retain their previous behavior", async () => {
expect(
await buildTemplateUpdateBody({
imageName: "浏览器",
templateId: "template-test",
async: false,
}),
).toEqual({ imageName: "浏览器" });
expect(
await buildTemplateCreateBody({
name: "test",
cpuCount: 4,
memoryMb: 8192,
async: false,
body: '{"fromImage":"custom:latest","imageName":"custom"}',
}),
).toEqual({
name: "test",
cpuCount: 4,
memoryMB: 8192,
fromImage: "custom:latest",
imageName: "custom",
});
expect(
await buildTemplateCreateBody({
name: "test",
cpuCount: 1,
memoryMb: 2048,
async: false,
}),
).not.toHaveProperty("fromImage");
expect(
await buildTemplateUpdateBody({
description: "only description",
templateId: "template-test",
async: false,
}),
).toEqual({ description: "only description" });
});
test("rejects unknown presets locally", () => {
expect(() => resolveSandboxImage("unknown")).toThrowError(
expect.objectContaining({ exitCode: ExitCode.USAGE }),
);
});
});
+12 -9
View File
@@ -6,7 +6,7 @@ metadata:
bins: ["bl"]
description: >-
阿里云百炼 Sandbox 沙箱实例与模版生命周期管理入口:用户要创建、查询、连接、暂停、恢复或释放百炼沙箱,
或创建、更新、查询、删除沙箱模版、查看模版构建状态时,使用 `bl sandbox`。
或查看内置基础镜像、创建、更新、查询、删除沙箱模版、查看模版构建状态时,使用 `bl sandbox`。
仅覆盖百炼 Sandbox 管控面;不用于宿主执行沙箱设置、E2B 官方云资源或沙箱内命令执行与文件传输。
agents.yaml 托管 Agent / Session / Environment 管理交给 bailian-managed-agent。
官方安装:`bl skill init`(与共享协议 bailian-protocol 同装)。
@@ -25,19 +25,22 @@ Before running `bl`, read the shared [bailian-protocol](../bailian-protocol/SKIL
## Choose the operation
| User intent | Command family |
| ------------------------------------- | -------------------------------------------------------- |
| Inspect or create instances | `bl sandbox list` / `get` / `create` |
| Connect, pause, or resume an instance | `bl sandbox connect` / `pause` / `resume` |
| Release an instance | `bl sandbox delete` |
| Inspect or build templates | `bl sandbox template list` / `get` / `create` / `update` |
| Check a submitted template build | `bl sandbox template build-status` |
| Delete a template | `bl sandbox template delete` |
| User intent | Command family |
| ------------------------------------- | --------------------------------------------------------- |
| Discover built-in base image presets | `bl sandbox official-images` (offline, no authentication) |
| Inspect or create instances | `bl sandbox list` / `get` / `create` |
| Connect, pause, or resume an instance | `bl sandbox connect` / `pause` / `resume` |
| Release an instance | `bl sandbox delete` |
| Inspect or build templates | `bl sandbox template list` / `get` / `create` / `update` |
| Check a submitted template build | `bl sandbox template build-status` |
| Delete a template | `bl sandbox template delete` |
Read [reference/index.md](reference/index.md) and the relevant section of [reference/sandbox.md](reference/sandbox.md) for exact flags, usage, and examples, or run the matching command with `--help`. Do not guess flags.
To save the origin in an isolated Profile, use `bl auth login --config sandbox --api-key <key> --base-url <origin>`. For a one-command override, use `bl sandbox list --base-url <origin>`. Custom gateways also apply to template build-status polling.
For built-in template images, discover the preset ID or Chinese name through `sandbox official-images`, then pass it to template create/update with `--image`. This fills both `fromImage` and `imageName`; `--image-name` alone remains a display name, not an image selector. Presets override the body's image fields; explicit `--from-image` / `--image-name` override the corresponding preset fields. Presets are pinned cn-beijing image URLs, not a live catalog or an availability guarantee for other environments. Omitting `--image` does not change existing defaults or update a template's image implicitly. See the generated reference for the catalog and exact flags.
## Operational boundaries
- Mutating commands act on remote resources. Only perform the requested operation and scope; read-only discovery does not authorize creating, pausing, resuming, or deleting resources.
+4 -3
View File
@@ -16,6 +16,7 @@ Use this index for the skill-scoped quick index and global flags.
| `bl sandbox delete` | API Key | Release a Sandbox instance | [sandbox.md](sandbox.md) |
| `bl sandbox get` | API Key | Get Sandbox instance details | [sandbox.md](sandbox.md) |
| `bl sandbox list` | API Key | List Sandbox instances | [sandbox.md](sandbox.md) |
| `bl sandbox official-images` | No Auth | List the built-in Sandbox base images (offline) | [sandbox.md](sandbox.md) |
| `bl sandbox pause` | API Key | Pause a Sandbox instance | [sandbox.md](sandbox.md) |
| `bl sandbox resume` | API Key | Resume a Sandbox instance and return connection information | [sandbox.md](sandbox.md) |
| `bl sandbox template build-status` | API Key | Get Sandbox template build status | [sandbox.md](sandbox.md) |
@@ -27,9 +28,9 @@ Use this index for the skill-scoped quick index and global flags.
## By group
| Group | Commands | Reference |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| `sandbox` | `connect`, `create`, `delete`, `get`, `list`, `pause`, `resume`, `template build-status`, `template create`, `template delete`, `template get`, `template list`, `template update` | [sandbox.md](sandbox.md) |
| Group | Commands | Reference |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| `sandbox` | `connect`, `create`, `delete`, `get`, `list`, `official-images`, `pause`, `resume`, `template build-status`, `template create`, `template delete`, `template get`, `template list`, `template update` | [sandbox.md](sandbox.md) |
## Global flags
+94 -41
View File
@@ -14,6 +14,7 @@ Index: [index.md](index.md)
| `bl sandbox delete` | API Key | Release a Sandbox instance |
| `bl sandbox get` | API Key | Get Sandbox instance details |
| `bl sandbox list` | API Key | List Sandbox instances |
| `bl sandbox official-images` | No Auth | List the built-in Sandbox base images (offline) |
| `bl sandbox pause` | API Key | Pause a Sandbox instance |
| `bl sandbox resume` | API Key | Resume a Sandbox instance and return connection information |
| `bl sandbox template build-status` | API Key | Get Sandbox template build status |
@@ -241,6 +242,40 @@ bl sandbox list --state running --limit 20
bl sandbox list --template-id tpl-xxx --output json
```
### `bl sandbox official-images`
| Field | Value |
| ------------------ | ----------------------------------------------- |
| **Name** | `sandbox official-images` |
| **Description** | List the built-in Sandbox base images (offline) |
| **Authentication** | No Auth |
| **Usage** | `bl sandbox official-images` |
#### Flags
_No command-specific flags._
#### Notes
- Use a preset ID or Chinese name with template create/update --image. These are pinned cn-beijing images; other environments may differ. Use --from-image for a custom image.
- code-interpreter (代码解释器): Python / Node.js runtimes with common data-processing libraries. fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/code-interpreter-v1:v0.0.44
- browser (浏览器): Chromium and a visual desktop for clicking, filling forms, and screenshots. fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.44
- all-in-one (全能型): Code execution and browser capabilities together. fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/all-in-one:v0.0.44
#### Examples
```bash
bl sandbox official-images
```
```bash
bl sandbox official-images --output json
```
```bash
bl sandbox official-images --quiet
```
### `bl sandbox pause`
| Field | Value |
@@ -364,27 +399,28 @@ bl sandbox template build-status --template-id tpl-xxx --build-id build-xxx --ou
#### Flags
| Flag | Type | Required | Description |
| ------------------------------ | ------ | -------- | ---------------------------------------------------------------------------------- |
| `--workspace-id <id>` | string | no | Workspace ID for the default Sandbox endpoint; optional with a configured base URL |
| `--body <json\|@path>` | string | no | JSON request body, inline or loaded from an @file path; explicit flags override it |
| `--name <name>` | string | no | Template name |
| `--cpu-count <cores>` | number | no | vCPU count |
| `--memory-mb <mb>` | number | no | Memory in MB |
| `--from-image <image>` | string | no | Base image identifier |
| `--image-name <name>` | string | no | Base image display name |
| `--env <key=value>` | array | no | Template environment variable; repeat for multiple values |
| `--allow-out <address>` | array | no | Outbound allow-list entry; repeat for multiple values |
| `--deny-out <address>` | array | no | Outbound deny-list entry; repeat for multiple values |
| `--auto-pause-time <seconds>` | number | no | Automatically pause after 300-604800 seconds |
| `--max-running-time <seconds>` | number | no | Maximum running lifetime in seconds (300-604800) |
| `--description <text>` | string | no | Template description |
| `--tag <tag>` | array | no | E2B tag; repeat for multiple values |
| `--alias <alias>` | string | no | E2B template alias |
| `--async` | switch | no | Return the submitted templateID/buildID immediately without polling |
| `--poll-interval <seconds>` | number | no | Template build polling interval (default: 5 seconds) |
| `--api-key <key>` | string | no | API key |
| `--base-url <url>` | string | no | API base URL |
| Flag | Type | Required | Description |
| ----------------------------------------------------------------------------- | ------ | -------- | ---------------------------------------------------------------------------------- |
| `--workspace-id <id>` | string | no | Workspace ID for the default Sandbox endpoint; optional with a configured base URL |
| `--body <json\|@path>` | string | no | JSON request body, inline or loaded from an @file path; explicit flags override it |
| `--image <code-interpreter\|代码解释器\|browser\|浏览器\|all-in-one\|全能型>` | string | no | Built-in image ID or Chinese name; fills fromImage and imageName |
| `--name <name>` | string | no | Template name |
| `--cpu-count <cores>` | number | no | vCPU count |
| `--memory-mb <mb>` | number | no | Memory in MB |
| `--from-image <image>` | string | no | Base image identifier |
| `--image-name <name>` | string | no | Base image display name |
| `--env <key=value>` | array | no | Template environment variable; repeat for multiple values |
| `--allow-out <address>` | array | no | Outbound allow-list entry; repeat for multiple values |
| `--deny-out <address>` | array | no | Outbound deny-list entry; repeat for multiple values |
| `--auto-pause-time <seconds>` | number | no | Automatically pause after 300-604800 seconds |
| `--max-running-time <seconds>` | number | no | Maximum running lifetime in seconds (300-604800) |
| `--description <text>` | string | no | Template description |
| `--tag <tag>` | array | no | E2B tag; repeat for multiple values |
| `--alias <alias>` | string | no | E2B template alias |
| `--async` | switch | no | Return the submitted templateID/buildID immediately without polling |
| `--poll-interval <seconds>` | number | no | Template build polling interval (default: 5 seconds) |
| `--api-key <key>` | string | no | API key |
| `--base-url <url>` | string | no | API base URL |
#### Notes
@@ -393,11 +429,19 @@ bl sandbox template build-status --template-id tpl-xxx --build-id build-xxx --ou
- Without a configured base URL, workspace is required: --workspace-id > BAILIAN_WORKSPACE_ID > config workspace_id.
- Sandbox is currently available in cn-beijing only and requires prior SLR authorization.
- Global --timeout limits HTTP requests and total template-build polling; --instance-timeout maps to the Sandbox API lifetime field.
- code-interpreter (代码解释器): Python / Node.js runtimes with common data-processing libraries. fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/code-interpreter-v1:v0.0.44
- browser (浏览器): Chromium and a visual desktop for clicking, filling forms, and screenshots. fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.44
- all-in-one (全能型): Code execution and browser capabilities together. fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/all-in-one:v0.0.44
- --image overrides body fromImage/imageName; explicit --from-image/--image-name override the corresponding preset fields. Without --image, image behavior is unchanged.
- File mounts and other complete nested structures can be supplied through --body.
- By default the command waits for build status ready; --async returns the submitted build immediately.
#### Examples
```bash
bl sandbox template create --name browser --image browser --cpu-count 1 --memory-mb 2048
```
```bash
bl sandbox template create --name python --cpu-count 1 --memory-mb 2048
```
@@ -538,26 +582,27 @@ bl sandbox template list --limit 100 --output json
#### Flags
| Flag | Type | Required | Description |
| ------------------------------ | ------ | -------- | ---------------------------------------------------------------------------------- |
| `--workspace-id <id>` | string | no | Workspace ID for the default Sandbox endpoint; optional with a configured base URL |
| `--template-id <id>` | string | yes | Sandbox template ID |
| `--body <json\|@path>` | string | no | JSON request body, inline or loaded from an @file path; explicit flags override it |
| `--name <name>` | string | no | Template name |
| `--cpu-count <cores>` | number | no | vCPU count |
| `--memory-mb <mb>` | number | no | Memory in MB |
| `--from-image <image>` | string | no | Base image identifier |
| `--image-name <name>` | string | no | Base image display name |
| `--env <key=value>` | array | no | Template environment variable; repeat for multiple values |
| `--allow-out <address>` | array | no | Outbound allow-list entry; repeat for multiple values |
| `--deny-out <address>` | array | no | Outbound deny-list entry; repeat for multiple values |
| `--auto-pause-time <seconds>` | number | no | Automatically pause after 300-604800 seconds |
| `--max-running-time <seconds>` | number | no | Maximum running lifetime in seconds (300-604800) |
| `--description <text>` | string | no | Template description |
| `--async` | switch | no | Return the submitted templateID/buildID immediately without polling |
| `--poll-interval <seconds>` | number | no | Template build polling interval (default: 5 seconds) |
| `--api-key <key>` | string | no | API key |
| `--base-url <url>` | string | no | API base URL |
| Flag | Type | Required | Description |
| ----------------------------------------------------------------------------- | ------ | -------- | ---------------------------------------------------------------------------------- |
| `--workspace-id <id>` | string | no | Workspace ID for the default Sandbox endpoint; optional with a configured base URL |
| `--template-id <id>` | string | yes | Sandbox template ID |
| `--body <json\|@path>` | string | no | JSON request body, inline or loaded from an @file path; explicit flags override it |
| `--image <code-interpreter\|代码解释器\|browser\|浏览器\|all-in-one\|全能型>` | string | no | Built-in image ID or Chinese name; fills fromImage and imageName |
| `--name <name>` | string | no | Template name |
| `--cpu-count <cores>` | number | no | vCPU count |
| `--memory-mb <mb>` | number | no | Memory in MB |
| `--from-image <image>` | string | no | Base image identifier |
| `--image-name <name>` | string | no | Base image display name |
| `--env <key=value>` | array | no | Template environment variable; repeat for multiple values |
| `--allow-out <address>` | array | no | Outbound allow-list entry; repeat for multiple values |
| `--deny-out <address>` | array | no | Outbound deny-list entry; repeat for multiple values |
| `--auto-pause-time <seconds>` | number | no | Automatically pause after 300-604800 seconds |
| `--max-running-time <seconds>` | number | no | Maximum running lifetime in seconds (300-604800) |
| `--description <text>` | string | no | Template description |
| `--async` | switch | no | Return the submitted templateID/buildID immediately without polling |
| `--poll-interval <seconds>` | number | no | Template build polling interval (default: 5 seconds) |
| `--api-key <key>` | string | no | API key |
| `--base-url <url>` | string | no | API base URL |
#### Notes
@@ -566,11 +611,19 @@ bl sandbox template list --limit 100 --output json
- Without a configured base URL, workspace is required: --workspace-id > BAILIAN_WORKSPACE_ID > config workspace_id.
- Sandbox is currently available in cn-beijing only and requires prior SLR authorization.
- Global --timeout limits HTTP requests and total template-build polling; --instance-timeout maps to the Sandbox API lifetime field.
- code-interpreter (代码解释器): Python / Node.js runtimes with common data-processing libraries. fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/code-interpreter-v1:v0.0.44
- browser (浏览器): Chromium and a visual desktop for clicking, filling forms, and screenshots. fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/browser:v0.0.44
- all-in-one (全能型): Code execution and browser capabilities together. fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/all-in-one:v0.0.44
- --image overrides body fromImage/imageName; explicit --from-image/--image-name override the corresponding preset fields. Without --image, image behavior is unchanged.
- Supplying envConfig or --env replaces the template's complete environment map.
- By default the command waits for build status ready; --async returns the submitted build immediately.
#### Examples
```bash
bl sandbox template update --template-id tpl-xxx --image all-in-one
```
```bash
bl sandbox template update --template-id tpl-xxx --cpu-count 4 --memory-mb 8192
```