mirror of
https://github.com/modelstudioai/cli.git
synced 2026-09-14 19:49:23 +08:00
feat(sandbox): add official image presets and template image selection
This commit is contained in:
@@ -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。",
|
||||
|
||||
@@ -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 }),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user