Skip to content

Commit 9600f06

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/profile-capability-fallback
# Conflicts: # skills/bailian-gen/reference/index.md
2 parents fc3ac36 + fe11227 commit 9600f06

18 files changed

Lines changed: 583 additions & 178 deletions

File tree

INSTALL.md

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,25 @@ npm install -g bailian-cli
1313
```
1414

1515
4. 校验:`bl --version`
16+
5. 按下方「安装 skills」安装。
1617

17-
安装 skills(CLI 内置,无需 Git / npx skills):
18+
### 安装 skills
19+
20+
**Supported(优先):** 用 CLI 内置命令一次装齐 registry 中全部 `bailian-*`(含共享协议 `bailian-protocol`):
1821

1922
```bash
2023
bl skill init
2124
```
2225

23-
**Supported:** `bl skill init` 一次装齐 registry 中全部 `bailian-*`(含共享协议 `bailian-protocol`)。
24-
25-
**Advanced / 按需子集:**
26+
**降级:**`bl skill init` 失败,先确认本机同时满足两个条件:`node -v` / `npm -v` 成功,**** `git --version` 成功。两个条件都成立时,再回退到:
2627

2728
```bash
28-
bl skill add --name bailian-protocol,bailian-gen
29+
npx skills@1.5.18 add modelstudioai/cli --all -g
2930
```
3031

31-
安装成功后,用中文简要说明已安装的 skills 及用户可做什么。
32+
> 必须使用 `skills@1.5.18`:这是最后兼容 Node ≥18 的版本(与 Bailian CLI 的 Node ≥18.17.0 一致);
33+
34+
安装成功后,按第 5 节向用户说明语言切换与能力 tip(若也装了 skills,一并简要说明)。
3235

3336
## 2. 备选:二进制安装(无需 Node)
3437

@@ -67,8 +70,6 @@ bl --version
6770
which bl # Windows: where.exe bl
6871
```
6972

70-
若自动 skill 安装失败,再手动执行:`bl skill init`
71-
7273
> CDN / GitHub Release 未就绪或下载失败时,若本机已有合格 Node,回退到上方 npm 安装。
7374
7475
---
@@ -99,12 +100,43 @@ which bl # Windows: where.exe bl
99100
bl auth status --output json
100101
```
101102

102-
## 5. 常见问题
103+
## 5. 安装成功后向用户说明(必做)
104+
105+
安装与校验完成后,**主动**用中文向用户说明下列两项;不要等用户追问。可执行 `bl`(已登录时)对照终端 tip,但以下列表为准,勿臆造。
106+
107+
### 5.1 界面语言
108+
109+
Bailian CLI 支持中英文界面(help / 欢迎语 / Quick Start 主次文案)。默认 `en-US`,可切换为 `zh-CN`
110+
111+
```bash
112+
bl config set --key language --value zh-CN
113+
bl config set --key language --value en-US
114+
```
103115

104-
| 现象 | 可能原因 | 建议动作 |
105-
| ------------------------ | ---------------------------- | ------------------------------------------------ |
106-
| `bl: command not found` | bin 不在 PATH | 检查 `~/.local/bin``npm prefix -g` |
107-
| curl 安装 404 | GitHub Release 资产未上传 | 改用 `npm install -g bailian-cli` |
108-
| Windows `bl update` 失败 | 旧布局 / 文件锁 / 网络 | 重跑 `irm .../install.ps1 \| iex` 迁移布局后重试 |
109-
| `plugin` 需要 npm | 二进制安装无本机 npm | 安装 Node,或改用 npm 版 CLI |
110-
| 安装报错 engines | Node 版本过低(仅 npm 路径) | 升级到 ≥ 18.17.0 |
116+
向用户说明:可随时用上述命令切换语言。
117+
118+
### 5.2 能力 tip(Quick Start)
119+
120+
向用户展示「试试使用Bailian CLI完成这些任务」及下列 5 条(中英各一行,与 `bl` 根帮助 tip 一致):
121+
122+
1. 帮我创建一个能够生成短片分镜和视频的 Managed Agent。
123+
Help me create a Managed Agent that can generate short-film storyboards and videos.
124+
2. 生成一张穿着太空服的猫站在火星上的图片,再把它制作成一段视频。
125+
Generate an image of a cat in a spacesuit standing on Mars, then turn it into a video.
126+
3. 查看最近的模型用量、免费额度和限流情况。
127+
Check my recent model usage, free quota, and rate limits.
128+
4. 推荐一个适合图片理解和智能客服的模型。
129+
Recommend a model suitable for image understanding and intelligent customer service.
130+
5. 介绍一下 Bailian CLI 能帮我完成哪些任务,并根据我的需求推荐使用方式。
131+
Explain what Bailian CLI can help me accomplish, and recommend how to use it based on my needs.
132+
133+
## 6. 常见问题
134+
135+
| 现象 | 可能原因 | 建议动作 |
136+
| ------------------------ | ---------------------------- | ---------------------------------------------------------------------------------------------- |
137+
| `bl: command not found` | bin 不在 PATH | 检查 `~/.local/bin``npm prefix -g` |
138+
| curl 安装 404 | GitHub Release 资产未上传 | 改用 `npm install -g bailian-cli` |
139+
| Windows `bl update` 失败 | 旧布局 / 文件锁 / 网络 | 重跑 `irm .../install.ps1 \| iex` 迁移布局后重试 |
140+
| `plugin` 需要 npm | 二进制安装无本机 npm | 安装 Node,或改用 npm 版 CLI |
141+
| 安装报错 engines | Node 版本过低(仅 npm 路径) | 升级到 ≥ 18.17.0 |
142+
| `bl skill init` 失败 | 网络 / registry 不可达等 | 有 Node 且有 Git 时降级 `npx skills@1.5.18 add modelstudioai/cli --all -g`;否则重试或告知用户 |

packages/cli/tests/stress/lib/fixtures.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ export async function ensurePrerequisites(ctx) {
178178
"video",
179179
"generate",
180180
"--model",
181-
"happyhorse-1.1-t2v",
181+
"wan3.0-video",
182182
"--prompt",
183183
"压测前置短视频:海浪与静态远景,无明显人物。",
184184
"--duration",

packages/cli/tests/stress/lib/suite-fixtures.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export async function generateCombinedFixtures({ suiteRoot, cliPackage }) {
130130
"video",
131131
"generate",
132132
"--model",
133-
"happyhorse-1.1-t2v",
133+
"wan3.0-video",
134134
"--prompt",
135135
"压测前置短视频:海浪与静态远景,无明显人物。",
136136
"--duration",

packages/cli/tests/stress/targets/video-i2v.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const motions = [
1616

1717
export const runStress = defineStressTarget({
1818
canonical: "video-i2v",
19-
defaultModel: "happyhorse-1.1-i2v",
19+
defaultModel: "wan3.0-video",
2020
batchDirPrefix: "video-i2v-batch",
2121
helpText: "pnpm run test:stress -- video-i2v [--reuse-fixtures] -- --count 5 -c 2",
2222

packages/cli/tests/stress/targets/video-ref.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const prompts = [
1616

1717
export const runStress = defineStressTarget({
1818
canonical: "video-ref",
19-
defaultModel: "happyhorse-1.1-r2v",
19+
defaultModel: "wan3.0-video",
2020
batchDirPrefix: "video-ref-batch",
2121
helpText: "pnpm run test:stress -- video-ref [--reuse-fixtures] -- --count 5 -c 2",
2222

packages/cli/tests/stress/targets/video-t2v.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const pick = (arr) => arr[Math.floor(Math.random() * arr.length)];
4545

4646
export const runStress = defineStressTarget({
4747
canonical: "video-t2v",
48-
defaultModel: "happyhorse-1.1-t2v",
48+
defaultModel: "wan3.0-video",
4949
batchDirPrefix: "video-t2v-batch",
5050
helpText: `用法:pnpm run test:stress -- video-t2v -- --concurrency 1 --count 3
5151
详见 docs/agents/stress-batch-tests.md`,

packages/commands/src/commands/config/shared.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ export const UI_BOOLEAN_KEYS = new Set<string>(["telemetry"]);
7373
export const UI_MODEL_DEFAULTS: Record<string, string> = {
7474
default_text_model: "qwen3.8-max",
7575
default_image_model: "qwen-image-3.0",
76-
default_video_model: "happyhorse-1.1-t2v",
76+
default_video_model: "wan3.0-video",
77+
default_image_to_video_model: "wan3.0-video",
78+
default_reference_to_video_model: "wan3.0-video",
7779
default_speech_model: "cosyvoice-v3-flash",
7880
default_speech_recognition_model: "fun-asr",
7981
default_omni_model: "qwen3.5-omni-plus",
@@ -105,8 +107,18 @@ export const UI_MODEL_CATALOG: Record<string, ModelOption[]> = {
105107
{ id: "wanx2.x", role: "image/generate · async series" },
106108
],
107109
default_video_model: [
108-
{ id: "happyhorse-1.1-t2v", role: "video/generate default · text-to-video" },
110+
{ id: "wan3.0-video", role: "video/generate · t2v / i2v / r2v default" },
111+
{ id: "happyhorse-1.1-t2v", role: "video/generate · text-to-video" },
109112
{ id: "happyhorse-1.1-i2v", role: "video/generate · image-to-video" },
113+
{ id: "happyhorse-1.1-r2v", role: "video/ref · reference-to-video" },
114+
],
115+
default_image_to_video_model: [
116+
{ id: "wan3.0-video", role: "video/generate default · image-to-video" },
117+
{ id: "happyhorse-1.1-i2v", role: "video/generate · image-to-video" },
118+
],
119+
default_reference_to_video_model: [
120+
{ id: "wan3.0-video", role: "video/ref default · reference-to-video" },
121+
{ id: "happyhorse-1.1-r2v", role: "video/ref · reference-to-video" },
110122
],
111123
default_speech_model: [
112124
{ id: "cosyvoice-v3-flash", role: "speech/synthesize (TTS) default" },

packages/commands/src/commands/video/generate.ts

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@ import { BOOL_FLAG_PROMPT_EXTEND_API_DEFAULT, BOOL_FLAG_WATERMARK } from "bailia
2424

2525
export default defineCommand({
2626
description: {
27-
"en-US":
28-
"Generate a video from text or image (happyhorse-1.1-t2v / happyhorse-1.1-i2v / wan2.6-t2v)",
29-
"zh-CN": "根据文本或图片生成视频(happyhorse-1.1-t2v / happyhorse-1.1-i2v / wan2.6-t2v)",
27+
"en-US": "Generate a video from text or image (wan3.0-video / wan2.6-t2v / happyhorse-1.1-i2v)",
28+
"zh-CN": "根据文本或图片生成视频(wan3.0-video / wan2.6-t2v / happyhorse-1.1-i2v)",
3029
},
3130
auth: "apiKey",
3231
usageArgs: "--prompt <text> [--image <url>] [flags]",
@@ -35,8 +34,8 @@ export default defineCommand({
3534
type: "string",
3635
valueHint: "<model>",
3736
description: {
38-
"en-US": "Model ID (default: happyhorse-1.1-t2v, or happyhorse-1.1-i2v with --image)",
39-
"zh-CN": "模型 ID(默认:happyhorse-1.1-t2v;使用 --image 时为 happyhorse-1.1-i2v)",
37+
"en-US": "Model ID (default: wan3.0-video)",
38+
"zh-CN": "模型 ID(默认:wan3.0-video)",
4039
},
4140
},
4241
prompt: {
@@ -119,6 +118,16 @@ export default defineCommand({
119118
"zh-CN": "完成后将视频保存到文件",
120119
},
121120
},
121+
file: {
122+
type: "string",
123+
valueHint: "<url-or-path>",
124+
description: {
125+
"en-US":
126+
"Reference file URL or local path for file-to-video (wan3.0-video only; mutually exclusive with --image/--last-frame)",
127+
"zh-CN":
128+
"参考文件 URL 或本地路径,用于文件生视频(仅 wan3.0-video;与 --image/--last-frame 互斥)",
129+
},
130+
},
122131
...ASYNC_FLAG,
123132
...CONCURRENT_FLAG,
124133
pollInterval: {
@@ -159,12 +168,20 @@ export default defineCommand({
159168
const model =
160169
flags.model ||
161170
(flags.image
162-
? settings.defaultImageToVideoModel || "happyhorse-1.1-i2v"
163-
: settings.defaultVideoModel || "happyhorse-1.1-t2v");
171+
? settings.defaultImageToVideoModel || "wan3.0-video"
172+
: settings.defaultVideoModel || "wan3.0-video");
164173
const format = detectOutputFormat(settings.output);
165174

166175
const imageUrl = flags.image;
167176
const lastFrameUrl = flags.lastFrame as string | undefined;
177+
const fileUrl = flags.file as string | undefined;
178+
179+
if (fileUrl && (imageUrl || lastFrameUrl)) {
180+
throw new BailianError(
181+
"--file is mutually exclusive with --image/--last-frame.",
182+
ExitCode.USAGE,
183+
);
184+
}
168185

169186
// Auto-upload local image file for i2v
170187
let resolvedImageUrl: string | undefined;
@@ -178,6 +195,18 @@ export default defineCommand({
178195

179196
// kf2v mode: both --image and --last-frame provided.
180197
const isKf2v = Boolean(resolvedImageUrl && resolvedLastFrameUrl);
198+
// 万相 3.x(All-in-One)首尾帧走 media[];旧 kf2v 仍走 image2video 平铺字段。
199+
// 与 video/ref.ts 的 useReferenceAudio 保持同一判定:忽略大小写、覆盖 wan3.x 系列。
200+
const isWan30 = /^wan3\./i.test(model);
201+
202+
if (fileUrl && !isWan30) {
203+
throw new BailianError("--file is only supported by wan3.0-video.", ExitCode.USAGE);
204+
}
205+
206+
let resolvedFileUrl: string | undefined;
207+
if (fileUrl) {
208+
resolvedFileUrl = await ctx.client.uploadFile(fileUrl, model);
209+
}
181210

182211
const watermark = resolveWatermark(flags.watermark);
183212
const promptExtend = resolveBooleanFlag(flags.promptExtend, undefined, "prompt-extend");
@@ -187,16 +216,26 @@ export default defineCommand({
187216
input: {
188217
prompt: prompt,
189218
negative_prompt: flags.negativePrompt || undefined,
190-
// kf2v: first+last frame flat fields via image2video endpoint.
219+
// wan3.0 kf2v: media[first_frame, last_frame] via video-generation endpoint.
220+
// legacy kf2v: first_frame_url/last_frame_url via image2video endpoint.
191221
// wan2.1~2.6 i2v: flat img_url via video-generation endpoint.
192222
// wan2.7+ / happyhorse i2v: media[] via video-generation endpoint.
193-
...(isKf2v
194-
? { first_frame_url: resolvedImageUrl, last_frame_url: resolvedLastFrameUrl }
195-
: resolvedImageUrl
196-
? /wan[x]?2\.[1-6]/i.test(model)
197-
? { img_url: resolvedImageUrl }
198-
: { media: [{ type: "first_frame" as const, url: resolvedImageUrl }] }
199-
: {}),
223+
...(resolvedFileUrl
224+
? { media: [{ type: "file" as const, url: resolvedFileUrl }] }
225+
: isKf2v
226+
? isWan30
227+
? {
228+
media: [
229+
{ type: "first_frame" as const, url: resolvedImageUrl! },
230+
{ type: "last_frame" as const, url: resolvedLastFrameUrl! },
231+
],
232+
}
233+
: { first_frame_url: resolvedImageUrl, last_frame_url: resolvedLastFrameUrl }
234+
: resolvedImageUrl
235+
? /wan[x]?2\.[1-6]/i.test(model)
236+
? { img_url: resolvedImageUrl }
237+
: { media: [{ type: "first_frame" as const, url: resolvedImageUrl }] }
238+
: {}),
200239
},
201240
parameters: {
202241
resolution: flags.resolution || undefined,
@@ -210,13 +249,29 @@ export default defineCommand({
210249

211250
if (settings.dryRun) {
212251
let previewBody = body;
213-
if (isKf2v) {
252+
if (resolvedFileUrl) {
253+
previewBody = {
254+
...body,
255+
input: {
256+
...body.input,
257+
media: [{ type: "file" as const, url: redactDataUri(resolvedFileUrl) }],
258+
},
259+
};
260+
} else if (isKf2v) {
261+
const redactedFirst = redactDataUri(resolvedImageUrl ?? "");
262+
const redactedLast = redactDataUri(resolvedLastFrameUrl ?? "");
214263
previewBody = {
215264
...body,
216265
input: {
217266
...body.input,
218-
first_frame_url: redactDataUri(resolvedImageUrl ?? ""),
219-
last_frame_url: redactDataUri(resolvedLastFrameUrl ?? ""),
267+
...(isWan30
268+
? {
269+
media: [
270+
{ type: "first_frame" as const, url: redactedFirst },
271+
{ type: "last_frame" as const, url: redactedLast },
272+
],
273+
}
274+
: { first_frame_url: redactedFirst, last_frame_url: redactedLast }),
220275
},
221276
};
222277
} else if (resolvedImageUrl) {
@@ -243,7 +298,7 @@ export default defineCommand({
243298
settings,
244299
() =>
245300
ctx.client.requestJson<DashScopeAsyncResponse>({
246-
path: isKf2v ? image2videoPath() : videoGeneratePath(),
301+
path: isKf2v && !isWan30 ? image2videoPath() : videoGeneratePath(),
247302
method: "POST",
248303
body,
249304
async: true,

0 commit comments

Comments
 (0)