Skip to content

Commit 96eb327

Browse files
committed
Merge branch main of github.com:modelstudioai/cli into feat/native-mcp-agent-registration
2 parents 7d8dcb1 + 64b1e72 commit 96eb327

47 files changed

Lines changed: 4661 additions & 30 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.vite-hooks/pre-commit

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ git add \
1515
skills/bailian-finetune/reference \
1616
skills/bailian-managed-agent/SKILL.md \
1717
skills/bailian-managed-agent/reference \
18+
skills/bailian-sandbox/SKILL.md \
19+
skills/bailian-sandbox/reference \
1820
skills/bailian-web-search/SKILL.md
1921

2022
vp staged

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ packages/core/src/auth/ # apiKey / console credential 解析与落盘
3636
packages/core/src/client/ # HTTP client / endpoints / console gateway
3737
```
3838

39-
Skill / 命令手册随 `skills/bailian-*/``bl skill init` 安装(装齐 registry 中全部 `bailian-*`,含共享协议 `bailian-protocol`)。业务 skill(`bailian-cli` / `bailian-gen` / `bailian-finetune` / `bailian-managed-agent` / `bailian-web-search`)执行前读 `skills/bailian-protocol/`;不要依赖 frontmatter `companions`(安装器不强制)。`tools/generate-reference.ts`**`packages/cli/src/commands.ts`** 按一级命令归属表分流写入各 `skills/<skill>/reference/`(纳入 git);`tools/sync-skill-metadata.ts``packages/cli/package.json` 同步各 `skills/*/SKILL.md``metadata.version`。两者由根脚本 `pnpm run sync:skill-assets``.vite-hooks/pre-commit` 执行。hub `bailian-cli` 的路由表不复述领域命令明细;SKILL 文案 / 安装约定 / hand-off 见 [docs/agents/skill-change.md](docs/agents/skill-change.md)
39+
Skill / 命令手册随 `skills/bailian-*/``bl skill init` 安装(装齐 registry 中全部 `bailian-*`,含共享协议 `bailian-protocol`)。业务 skill(`bailian-cli` / `bailian-gen` / `bailian-finetune` / `bailian-managed-agent` / `bailian-sandbox` / `bailian-web-search`)执行前读 `skills/bailian-protocol/`;不要依赖 frontmatter `companions`(安装器不强制)。`tools/generate-reference.ts`**`packages/cli/src/commands.ts`** 按一级命令归属表分流写入各 `skills/<skill>/reference/`(纳入 git);`tools/sync-skill-metadata.ts``packages/cli/package.json` 同步各 `skills/*/SKILL.md``metadata.version`。两者由根脚本 `pnpm run sync:skill-assets``.vite-hooks/pre-commit` 执行。hub `bailian-cli` 的路由表不复述领域命令明细;SKILL 文案 / 安装约定 / hand-off 见 [docs/agents/skill-change.md](docs/agents/skill-change.md)
4040

4141
约定:
4242

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
66

77
[中文版](CHANGELOG.zh.md) · [README](README.md) · [Contributing](CONTRIBUTING.md)
88

9+
## [1.24.0] - 2026-09-11
10+
11+
### Added
12+
13+
- Sandbox instance and template lifecycle commands, with automatic build polling and `--async` submission.
14+
- `bl sandbox official-images` and template `--image` presets for Code Interpreter, Browser, and All-in-One.
15+
- `bl sandbox file upload` uploads template mount files with `source=sandbox_template`; use the returned File ID in `mntConfig`.
16+
- Sandbox supports shared `--base-url`, environment and Profile configuration, with workspace-based endpoint fallback.
17+
- Dedicated `bailian-sandbox` Skill with command references and instance connection guidance.
18+
19+
### Fixed
20+
21+
- Preserve submitted `templateID` and `buildID` when template-build polling fails, so users can check the existing build before resubmitting.
22+
23+
### Security
24+
25+
- Sandbox REST calls use Bailian Bearer authentication without an E2B SDK or E2B API key. Connection credentials and dry-run environment values are redacted by default.
26+
927
## [1.23.0] - 2026-09-10
1028

1129
### Added

CHANGELOG.zh.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@
66

77
[English](CHANGELOG.md) · [README](README.zh.md) · [参与贡献](CONTRIBUTING.zh.md)
88

9+
## [1.24.0] - 2026-09-11
10+
11+
### 新增
12+
13+
- Sandbox 实例与模版生命周期命令,支持自动轮询构建状态和 `--async` 异步提交。
14+
- `bl sandbox official-images` 与模版 `--image` 参数,内置代码解释器、浏览器和全能型镜像预设。
15+
- `bl sandbox file upload` 使用 `source=sandbox_template` 上传模版挂载文件,返回的 File ID 可用于 `mntConfig`
16+
- Sandbox 复用 `--base-url`、环境变量和 Profile 配置,未配置时通过工作空间拼接接入地址。
17+
- 独立的 `bailian-sandbox` Skill,提供命令参考和实例连接指南。
18+
19+
### 修复
20+
21+
- 模版构建轮询失败时保留已提交的 `templateID``buildID`,便于先查询已有构建,避免重复提交。
22+
23+
### 安全
24+
25+
- Sandbox REST 调用使用百炼 Bearer 鉴权,不依赖 E2B SDK 或 E2B API Key;连接凭据和 dry-run 环境变量默认脱敏。
26+
927
## [1.23.0] - 2026-09-10
1028

1129
### 新增

docs/agents/skill-change.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ bailian-gen bailian-finetune bailian-managed-agent bailian-web-search
5656
### C. 归属与生成
5757

5858
- [ ] 新一级命令组归属领域时:改 `tools/generate-reference.ts``GROUP_OWNER_SKILL`,并更新**拥有方** skill 的路由表;hub 最多加一行 hand-off
59+
- [ ] 新增领域目录时:补齐 `SKILL.md`(含 `metadata.version`),同步 `packages/cli/package.json` 的 reference 格式化路径、`.vite-hooks/pre-commit` 的生成物暂存清单、`tools/release/check.mjs` 的生成物校验清单;同步 hub 与共享协议的领域路由
5960
- [ ]`pnpm run sync:skill-assets`(或 commit 走 pre-commit),提交生成的 `reference/` 与 version 同步结果
6061
- [ ] 高风险命令生成的 reference 必须包含 `Risk` / `Risk message` 和简短 Agent safety 提示;带 `--yes` 的示例必须标注只能在确认后执行,不要手改生成物
6162
- [ ] 默认模型若写在领域路由表(如 `bailian-gen`):与命令 default / [model-add-remove.md](model-add-remove.md) 一并核对

packages/cli/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bailian-cli",
3-
"version": "1.23.0",
3+
"version": "1.24.0",
44
"description": "CLI for Aliyun Model Studio (DashScope) AI Platform.",
55
"keywords": [
66
"agent",
@@ -41,7 +41,7 @@
4141
"registry": "https://registry.npmjs.org/"
4242
},
4343
"scripts": {
44-
"generate:reference": "tsx ../../tools/generate-reference.ts && sh -c 'cd ../.. && vp check --fix skills/bailian-cli/reference skills/bailian-gen/reference skills/bailian-finetune/reference skills/bailian-managed-agent/reference'",
44+
"generate:reference": "tsx ../../tools/generate-reference.ts && sh -c 'cd ../.. && vp check --fix skills/bailian-cli/reference skills/bailian-gen/reference skills/bailian-finetune/reference skills/bailian-managed-agent/reference skills/bailian-sandbox/reference'",
4545
"sync:skill-version": "tsx ../../tools/sync-skill-metadata.ts",
4646
"build": "vp pack",
4747
"dev": "tsx src/main.ts",

packages/cli/src/commands.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,21 @@ import {
213213
managedAgentFileSearch,
214214
managedAgentFileDownload,
215215
managedAgentFileDelete,
216+
sandboxCreate,
217+
sandboxOfficialImages,
218+
sandboxFileUpload,
219+
sandboxList,
220+
sandboxGet,
221+
sandboxConnect,
222+
sandboxPause,
223+
sandboxResume,
224+
sandboxDelete,
225+
sandboxTemplateCreate,
226+
sandboxTemplateList,
227+
sandboxTemplateGet,
228+
sandboxTemplateUpdate,
229+
sandboxTemplateBuildStatus,
230+
sandboxTemplateDelete,
216231
} from "bailian-cli-commands";
217232

218233
// Full bailian-cli product: every command, exposed under the `bl` binary.
@@ -437,6 +452,21 @@ export const commands: Record<string, AnyCommand> = {
437452
"managed-agent file search": managedAgentFileSearch,
438453
"managed-agent file download": managedAgentFileDownload,
439454
"managed-agent file delete": managedAgentFileDelete,
455+
"sandbox create": sandboxCreate,
456+
"sandbox official-images": sandboxOfficialImages,
457+
"sandbox file upload": sandboxFileUpload,
458+
"sandbox list": sandboxList,
459+
"sandbox get": sandboxGet,
460+
"sandbox connect": sandboxConnect,
461+
"sandbox pause": sandboxPause,
462+
"sandbox resume": sandboxResume,
463+
"sandbox delete": sandboxDelete,
464+
"sandbox template create": sandboxTemplateCreate,
465+
"sandbox template list": sandboxTemplateList,
466+
"sandbox template get": sandboxTemplateGet,
467+
"sandbox template update": sandboxTemplateUpdate,
468+
"sandbox template build-status": sandboxTemplateBuildStatus,
469+
"sandbox template delete": sandboxTemplateDelete,
440470
};
441471

442472
/**
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { existsSync, readFileSync } from "node:fs";
2+
import { dirname, join } from "node:path";
3+
import { fileURLToPath } from "node:url";
4+
import { validateSkillDir } from "bailian-cli-core";
5+
import { expect, test } from "vite-plus/test";
6+
import { parse } from "yaml";
7+
import { commands } from "../src/commands.ts";
8+
9+
const repositoryRoot = join(dirname(fileURLToPath(import.meta.url)), "../../..");
10+
const sandboxSkillDirectory = join(repositoryRoot, "skills/bailian-sandbox");
11+
12+
test("Sandbox is a valid standalone skill aligned with the CLI version", () => {
13+
const metadata = validateSkillDir(sandboxSkillDirectory, "bailian-sandbox");
14+
expect(metadata.name).toBe("bailian-sandbox");
15+
16+
const skillMarkdown = readFileSync(join(sandboxSkillDirectory, "SKILL.md"), "utf8");
17+
const frontmatter = parse(skillMarkdown.split(/^---\s*$/m)[1]) as {
18+
metadata: { version: string };
19+
};
20+
const cliPackage = JSON.parse(
21+
readFileSync(join(repositoryRoot, "packages/cli/package.json"), "utf8"),
22+
) as { version: string };
23+
expect(frontmatter.metadata.version).toBe(cliPackage.version);
24+
25+
for (const link of skillMarkdown.matchAll(/\]\(([^)]+)\)/g)) {
26+
expect(existsSync(join(sandboxSkillDirectory, link[1]))).toBe(true);
27+
}
28+
});
29+
30+
test("Sandbox reference contains every registered Sandbox command only in its owning skill", () => {
31+
const expectedCommands = Object.keys(commands)
32+
.filter((commandPath) => commandPath.startsWith("sandbox "))
33+
.map((commandPath) => `bl ${commandPath}`)
34+
.sort();
35+
expect(expectedCommands.length).toBeGreaterThan(0);
36+
37+
const reference = readFileSync(join(sandboxSkillDirectory, "reference/sandbox.md"), "utf8");
38+
const documentedCommands = [...reference.matchAll(/^### `([^`]+)`/gm)]
39+
.map((match) => match[1])
40+
.sort();
41+
expect(documentedCommands).toEqual(expectedCommands);
42+
43+
const index = readFileSync(join(sandboxSkillDirectory, "reference/index.md"), "utf8");
44+
for (const commandPath of expectedCommands) {
45+
expect(index).toContain(`\`${commandPath}\``);
46+
}
47+
expect(existsSync(join(repositoryRoot, "skills/bailian-cli/reference/sandbox.md"))).toBe(false);
48+
const hubIndex = readFileSync(
49+
join(repositoryRoot, "skills/bailian-cli/reference/index.md"),
50+
"utf8",
51+
);
52+
expect(hubIndex).not.toContain("`bl sandbox ");
53+
});

packages/commands/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bailian-cli-commands",
3-
"version": "1.23.0",
3+
"version": "1.24.0",
44
"description": "Command library for bailian-cli products (knowledge, memory, media, …). See https://www.npmjs.com/package/bailian-cli for usage.",
55
"homepage": "https://bailian.console.aliyun.com/cli",
66
"bugs": {
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { readFile } from "node:fs/promises";
2+
import { basename } from "node:path";
3+
import {
4+
agentStudioFilesPath,
5+
BailianError,
6+
defineCommand,
7+
detectOutputFormat,
8+
ExitCode,
9+
sandboxBaseUrl,
10+
} from "bailian-cli-core";
11+
import { emitBare, emitResult } from "bailian-cli-runtime";
12+
import { redactConnectionCredentials, resolveWorkspaceId, WORKSPACE_FLAG } from "./shared.ts";
13+
14+
const UPLOAD_SOURCE = "sandbox_template";
15+
16+
export const sandboxFileUpload = defineCommand({
17+
description: {
18+
"en-US": "Upload a workspace file for Sandbox template mounts",
19+
"zh-CN": "上传工作空间文件,供 Sandbox 模版挂载使用",
20+
},
21+
auth: "apiKey",
22+
usageArgs: "--path <path> [--filename <name>] [--mime-type <type>]",
23+
flags: {
24+
...WORKSPACE_FLAG,
25+
path: {
26+
type: "string",
27+
valueHint: "<path>",
28+
required: true,
29+
description: { "en-US": "Local file path", "zh-CN": "本地文件路径" },
30+
},
31+
filename: {
32+
type: "string",
33+
valueHint: "<name>",
34+
description: { "en-US": "Remote filename override", "zh-CN": "覆盖远端文件名" },
35+
},
36+
mimeType: {
37+
type: "string",
38+
valueHint: "<type>",
39+
description: {
40+
"en-US": "Multipart file MIME type (default: application/octet-stream)",
41+
"zh-CN": "Multipart 文件部分的 MIME 类型(默认:application/octet-stream)",
42+
},
43+
},
44+
},
45+
exampleArgs: [
46+
"--path ./config.json --output json",
47+
"--path ./config.json --quiet",
48+
"--path ./notes.txt --filename notes.txt --mime-type text/plain --dry-run --output json",
49+
],
50+
notes: [
51+
{
52+
"en-US":
53+
"POST /api/v1/agentstudio/files with multipart fields file and source=sandbox_template. Uses a Bailian Bearer API Key, not Console authentication or an E2B key; no agents.yaml is needed.",
54+
"zh-CN":
55+
"向 /api/v1/agentstudio/files 发送 multipart 字段 file 和 source=sandbox_template。使用百炼 Bearer API Key,不使用 Console 鉴权或 E2B Key;无需 agents.yaml。",
56+
},
57+
{
58+
"en-US":
59+
"Base URL follows Sandbox: --base-url > DASHSCOPE_BASE_URL > login/profile base_url. Without one, --workspace-id > BAILIAN_WORKSPACE_ID > config workspace_id selects the cn-beijing origin. The upload path has no /sandbox prefix.",
60+
"zh-CN":
61+
"Base URL 沿用 Sandbox:--base-url > DASHSCOPE_BASE_URL > 登录/Profile 的 base_url。未配置时,按 --workspace-id > BAILIAN_WORKSPACE_ID > 配置项 workspace_id 选择 cn-beijing 地址。上传路径不带 /sandbox 前缀。",
62+
},
63+
{
64+
"en-US":
65+
"Returns the upload response immediately; --quiet prints only its id. Upload does not wait for security review: status=checking is not ready to mount. Use an available file's id as mntConfig[].originFileId in template create/update --body, together with mountPath and optional originFileName, in the same workspace. This does not transfer files into a running instance.",
66+
"zh-CN":
67+
"上传响应返回后立即输出,--quiet 仅输出 id。不会等待安全审核:status=checking 不代表已可挂载。在同一工作空间的 template create/update --body 中,将可用文件的 id 填入 mntConfig[].originFileId,同时传入 mountPath 和可选的 originFileName。此命令不向运行中的实例传文件。",
68+
},
69+
{
70+
"en-US":
71+
"--dry-run previews the endpoint, source, and local path without reading or uploading the file. The service detects the MIME type and enforces upload limits.",
72+
"zh-CN":
73+
"--dry-run 仅预览 Endpoint、source 和本地路径,不读取或上传文件。MIME 类型检测和上传限制由服务端执行。",
74+
},
75+
],
76+
async run(ctx) {
77+
const endpoint = ctx.client.url(agentStudioFilesPath(), () =>
78+
sandboxBaseUrl(resolveWorkspaceId(ctx)),
79+
);
80+
const filename = ctx.flags.filename ?? basename(ctx.flags.path);
81+
const mimeType = ctx.flags.mimeType ?? "application/octet-stream";
82+
const format = detectOutputFormat(ctx.settings.output);
83+
if (ctx.settings.dryRun) {
84+
emitResult(
85+
{
86+
method: "POST",
87+
endpoint,
88+
request: { source: UPLOAD_SOURCE, file: { path: ctx.flags.path, filename, mimeType } },
89+
},
90+
format,
91+
);
92+
return;
93+
}
94+
95+
const content = new Uint8Array(await readFile(ctx.flags.path));
96+
const form = new FormData();
97+
form.append("source", UPLOAD_SOURCE);
98+
form.append("file", new Blob([content], { type: mimeType }), filename);
99+
const file = await ctx.client.requestJson<Record<string, unknown>>({
100+
method: "POST",
101+
path: endpoint,
102+
body: form,
103+
});
104+
if (!file || typeof file.id !== "string" || !file.id.trim()) {
105+
throw new BailianError(
106+
"Upload response did not contain a File ID. / 上传响应未包含 File ID。",
107+
ExitCode.GENERAL,
108+
);
109+
}
110+
if (ctx.settings.quiet) emitBare(file.id);
111+
else emitResult(redactConnectionCredentials(file), format);
112+
},
113+
});

0 commit comments

Comments
 (0)