@lingjingai/lj-awb-cli-pre 0.3.16 → 0.3.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -8
- package/package.json +1 -1
- package/packages/awb-cli/package.json +2 -2
- package/packages/awb-core/package.json +1 -1
- package/packages/awb-core/src/api.js +9 -2
- package/packages/awb-core/src/commands.js +40 -13
- package/packages/awb-core/src/common.js +2 -1
- package/packages/awb-core/src/output.js +4 -6
- package/packages/awb-core/src/services.js +118 -41
- package/packages/awb-core/src/standalone.js +41 -9
- package/skills/lj-awb/SKILL.md +1 -1
- package/skills/lj-awb/VERSION +1 -1
- package/skills/lj-awb/compat.json +3 -3
- package/skills/lj-awb/modules/asset.md +25 -18
- package/skills/lj-awb/modules/create.md +1 -0
- package/skills/lj-awb/modules/driver.md +5 -2
- package/skills/lj-awb/modules/model.md +2 -0
- package/skills/lj-awb/modules/subject.md +4 -4
- package/skills/lj-awb/modules/task-manual.md +1 -1
- package/skills/lj-awb/modules/upload.md +5 -3
- package/skills/lj-awb/modules/workflows.md +26 -21
- package/skills/lj-awb/references/output-fields.md +6 -5
package/README.md
CHANGED
|
@@ -22,12 +22,9 @@ CLI 本身只负责平台调用、参数校验、精简输出和安全确认;
|
|
|
22
22
|
| 积分 | `credits` | 可扣积分余额、项目组预算、任务用量统计 |
|
|
23
23
|
| 模型 | `model` | 生图 / 生视频模型发现、模型参数白名单 |
|
|
24
24
|
| 上传 | `upload` | 本地图片 / 视频 / 音频上传为平台可访问素材 |
|
|
25
|
-
|
|
|
26
|
-
| 视频 | `video` | 生视频估价、提交、批量提交、状态查询、去字幕 |
|
|
25
|
+
| 创建 | `create` | 生图、生视频、主体、音色、素材和去字幕提交 |
|
|
27
26
|
| 任务 | `task` | 任务列表、等待、任务台账和台账轮询 |
|
|
28
|
-
| 资产 | `asset` | 素材库匹配、素材组、素材注册 |
|
|
29
27
|
| 最终产物 | `artifact` | Workbench 剧本、资产、视频最终产物 CRUD 与本地 JSON 导入 |
|
|
30
|
-
| 主体 | `subject` | 可复用主体资产发布与查询 |
|
|
31
28
|
|
|
32
29
|
## 环境要求
|
|
33
30
|
|
|
@@ -114,7 +111,7 @@ lj-awb account info
|
|
|
114
111
|
lj-awb doctor
|
|
115
112
|
lj-awb doctor --verify
|
|
116
113
|
lj-awb schema -f json
|
|
117
|
-
lj-awb schema --domain
|
|
114
|
+
lj-awb schema --domain create -f json
|
|
118
115
|
lj-awb auth status
|
|
119
116
|
lj-awb auth verify
|
|
120
117
|
lj-awb account info
|
|
@@ -148,8 +145,8 @@ Agent 不应该靠记忆猜命令参数。进入任务前推荐先读取机器
|
|
|
148
145
|
|
|
149
146
|
```bash
|
|
150
147
|
lj-awb schema -f json
|
|
151
|
-
lj-awb schema --domain
|
|
152
|
-
lj-awb schema --domain
|
|
148
|
+
lj-awb schema --domain create -f json
|
|
149
|
+
lj-awb schema --domain create --command video -f json
|
|
153
150
|
```
|
|
154
151
|
|
|
155
152
|
正式创作前推荐做一次体检:
|
|
@@ -235,7 +232,7 @@ lj-awb create video \
|
|
|
235
232
|
如果参考图会复用,推荐先发布主体资产:
|
|
236
233
|
|
|
237
234
|
```bash
|
|
238
|
-
lj-awb create subject --name 女主 --primary
|
|
235
|
+
lj-awb create subject --model-code tx --name 女主 --resource primary:./actor.png --yes
|
|
239
236
|
lj-awb create subject-wait --element-id <elementId> --wait-seconds 300
|
|
240
237
|
lj-awb create video \
|
|
241
238
|
--model-group-code <modelGroupCode> \
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingjingai/lj-awb-cli-pre",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.17",
|
|
4
4
|
"description": "Lingjing AWB CLI monorepo with shared core, standalone CLI, and agent skills (pre-release build pointing to https://animeworkbench-pre.lingjingai.cn)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingjingai/awb-cli-bin",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.17",
|
|
4
4
|
"description": "Standalone CLI for Lingjing AWB",
|
|
5
5
|
"private": true,
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,6 +13,6 @@
|
|
|
13
13
|
"README.md"
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@lingjingai/awb-core": "0.3.
|
|
16
|
+
"@lingjingai/awb-core": "0.3.17"
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -177,6 +177,10 @@ export async function fetchModelGroupInfoAll(modelGroupCode) {
|
|
|
177
177
|
return await apiFetch(`/api/resource/model/info/group/${encodeURIComponent(modelGroupCode)}/all`, { method: 'GET' });
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
export async function fetchAssetReviewModels() {
|
|
181
|
+
return await apiFetch('/api/material/creation/model/asset-review/list', { method: 'GET' });
|
|
182
|
+
}
|
|
183
|
+
|
|
180
184
|
export async function fetchUploadSecret(payload = {}) {
|
|
181
185
|
return await apiFetch('/api/anime/workbench/TencentCloud/getSecret', { body: payload });
|
|
182
186
|
}
|
|
@@ -241,8 +245,11 @@ export async function listAssetGroups(payload = {}) {
|
|
|
241
245
|
return await apiFetch('/api/material/asset-groups/list', { body: payload });
|
|
242
246
|
}
|
|
243
247
|
|
|
244
|
-
export async function getAssetGroup(groupId) {
|
|
245
|
-
return await apiFetch(`/api/material/asset-groups/${encodeURIComponent(groupId)}`, {
|
|
248
|
+
export async function getAssetGroup(groupId, payload = {}) {
|
|
249
|
+
return await apiFetch(`/api/material/asset-groups/${encodeURIComponent(groupId)}`, {
|
|
250
|
+
method: 'GET',
|
|
251
|
+
query: payload,
|
|
252
|
+
});
|
|
246
253
|
}
|
|
247
254
|
|
|
248
255
|
export async function createAssetGroup(payload = {}) {
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
assetGroupList,
|
|
9
9
|
assetGroupUpdate,
|
|
10
10
|
assetMatchActor,
|
|
11
|
+
assetReviewModels,
|
|
11
12
|
assetRegister,
|
|
12
13
|
creditsBalance,
|
|
13
14
|
creditsUsageSummary,
|
|
@@ -74,6 +75,7 @@ const PROJECT_ID_ARG = { name: 'project-id', valueName: 'projectId', description
|
|
|
74
75
|
const PROJECT_GROUP_ARG = { name: 'project-group-no', valueName: 'no', description: '项目组编号;不传时读取当前项目组 / 环境变量 / 本地状态' };
|
|
75
76
|
const CUSTOM_BIZ_ARG = { name: 'custom-biz-id', valueName: 'id', description: '外部追踪 ID;不传则请求不携带 customBizId' };
|
|
76
77
|
const MODEL_GROUP_ARG = { name: 'model-group-code', valueName: 'code', description: '模型组编码;创建和参数查询只传这个字段' };
|
|
78
|
+
const ASSET_PLATFORM_ARG = { name: 'platform', valueName: 'platform', description: '素材加白平台,必须显式传 JIMENG 或 BYTEPLUS,不做别名推断' };
|
|
77
79
|
const MODEL_LIST_ARGS = [
|
|
78
80
|
{ name: 'model', valueName: 'keyword', description: '按模型名、编码、供应商或输入方式过滤;不传时查询全部' },
|
|
79
81
|
{ name: 'limit', valueName: 'n', description: '默认文本最多展示 N 条,默认 8;JSON 输出始终返回全部匹配' },
|
|
@@ -399,6 +401,24 @@ export function registerAwbCommands(cli) {
|
|
|
399
401
|
func: async (_ctx, kwargs) => listModels('video', kwargs),
|
|
400
402
|
});
|
|
401
403
|
|
|
404
|
+
cli({
|
|
405
|
+
name: 'model asset-review-models',
|
|
406
|
+
description: commandHelp('查询支持素材加白的模型组与平台平铺关系', {
|
|
407
|
+
examples: [
|
|
408
|
+
'lj-awb model asset-review-models',
|
|
409
|
+
'lj-awb model asset-review-models --platform JIMENG',
|
|
410
|
+
'lj-awb model asset-review-models --model-group-code <code>',
|
|
411
|
+
],
|
|
412
|
+
hint: '该命令只负责发现 modelGroupCode 与 platform 的关系;资产组和素材创建仍通过 create asset-group / create asset 显式传 --platform。',
|
|
413
|
+
}),
|
|
414
|
+
args: [
|
|
415
|
+
MODEL_GROUP_ARG,
|
|
416
|
+
ASSET_PLATFORM_ARG,
|
|
417
|
+
INCLUDE_RAW_ARG,
|
|
418
|
+
],
|
|
419
|
+
func: async (_ctx, kwargs) => assetReviewModels(kwargs),
|
|
420
|
+
});
|
|
421
|
+
|
|
402
422
|
cli({
|
|
403
423
|
name: 'model options',
|
|
404
424
|
description: commandHelp('查询指定模型支持的 CLI 参数、枚举值、素材约束和条件约束', {
|
|
@@ -448,7 +468,8 @@ export function registerAwbCommands(cli) {
|
|
|
448
468
|
description: commandHelp('上传本地图片 / 视频 / 音频到平台 COS,并返回 backendPath / URL', {
|
|
449
469
|
examples: [
|
|
450
470
|
'lj-awb upload files --files ./a.png,./b.mp4 --dry-run',
|
|
451
|
-
'lj-awb upload files --file ./ref.png
|
|
471
|
+
'lj-awb upload files --file ./ref.png',
|
|
472
|
+
'lj-awb upload files --file ./first-frame.png --scene-type material-video-create',
|
|
452
473
|
],
|
|
453
474
|
hint: '不会暴露 COS 临时密钥;skill 只使用返回的 backendPath / url。',
|
|
454
475
|
}),
|
|
@@ -456,7 +477,7 @@ export function registerAwbCommands(cli) {
|
|
|
456
477
|
{ name: 'file', valueName: 'path', description: '单个文件路径' },
|
|
457
478
|
{ name: 'files', valueName: 'paths', description: '多个文件路径,逗号分隔' },
|
|
458
479
|
{ name: 'files-json', valueName: 'path|json', description: '文件数组 JSON 或 JSON 文件路径' },
|
|
459
|
-
{ name: 'scene-type', valueName: 'scene', description: '
|
|
480
|
+
{ name: 'scene-type', valueName: 'scene', description: '上传场景;未传时图片默认 material-image-draw,音视频默认 material-video-create;图片用于视频 / 主体复用时显式传 material-video-create' },
|
|
460
481
|
{ name: 'project-no', valueName: 'no', description: '可选项目组编号;不传时读取当前项目组 / 环境变量 / 本地状态' },
|
|
461
482
|
DRY_RUN_ARG,
|
|
462
483
|
],
|
|
@@ -726,10 +747,11 @@ export function registerAwbCommands(cli) {
|
|
|
726
747
|
cli({
|
|
727
748
|
name: 'create asset-groups',
|
|
728
749
|
description: commandHelp('查询素材组', {
|
|
729
|
-
examples: ['lj-awb create asset-groups --name "女主"'],
|
|
750
|
+
examples: ['lj-awb create asset-groups --platform JIMENG --name "女主"'],
|
|
730
751
|
}),
|
|
731
752
|
args: [
|
|
732
753
|
{ name: 'name', valueName: 'keyword', description: '素材组名称关键词' },
|
|
754
|
+
ASSET_PLATFORM_ARG,
|
|
733
755
|
{ name: 'group-ids', valueName: 'ids', description: '素材组 ID,逗号分隔' },
|
|
734
756
|
{ name: 'page-number', valueName: 'n', description: '页码' },
|
|
735
757
|
{ name: 'page-size', valueName: 'n', description: '每页数量' },
|
|
@@ -741,9 +763,12 @@ export function registerAwbCommands(cli) {
|
|
|
741
763
|
cli({
|
|
742
764
|
name: 'create asset-group-get',
|
|
743
765
|
description: commandHelp('查看素材组详情', {
|
|
744
|
-
examples: ['lj-awb create asset-group-get --group-id <id>'],
|
|
766
|
+
examples: ['lj-awb create asset-group-get --group-id <id> --platform JIMENG'],
|
|
745
767
|
}),
|
|
746
|
-
args: [
|
|
768
|
+
args: [
|
|
769
|
+
{ name: 'group-id', valueName: 'id', description: '素材组 ID' },
|
|
770
|
+
ASSET_PLATFORM_ARG,
|
|
771
|
+
],
|
|
747
772
|
func: async (_ctx, kwargs) => assetGroupGet(kwargs),
|
|
748
773
|
});
|
|
749
774
|
|
|
@@ -751,13 +776,14 @@ export function registerAwbCommands(cli) {
|
|
|
751
776
|
name: 'create asset-group',
|
|
752
777
|
description: commandHelp('创建素材组(用于素材注册时作为命名空间)', {
|
|
753
778
|
examples: [
|
|
754
|
-
'lj-awb create asset-group --name "女主素材组" --dry-run',
|
|
755
|
-
'lj-awb create asset-group --name "女主素材组" --description "用于第二集女主相关素材" --yes',
|
|
779
|
+
'lj-awb create asset-group --name "女主素材组" --platform JIMENG --dry-run',
|
|
780
|
+
'lj-awb create asset-group --name "女主素材组" --platform JIMENG --description "用于第二集女主相关素材" --yes',
|
|
756
781
|
],
|
|
757
782
|
}),
|
|
758
783
|
args: [
|
|
759
784
|
{ name: 'name', valueName: 'name', description: '素材组名称' },
|
|
760
785
|
{ name: 'description', valueName: 'text', description: '素材组描述' },
|
|
786
|
+
ASSET_PLATFORM_ARG,
|
|
761
787
|
{ name: 'project-name', valueName: 'name', description: '项目名,默认 default' },
|
|
762
788
|
DRY_RUN_ARG,
|
|
763
789
|
YES_ARG,
|
|
@@ -768,12 +794,13 @@ export function registerAwbCommands(cli) {
|
|
|
768
794
|
cli({
|
|
769
795
|
name: 'create asset-group-update',
|
|
770
796
|
description: commandHelp('更新素材组名称 / 描述', {
|
|
771
|
-
examples: ['lj-awb create asset-group-update --group-id <id> --name "新名称" --dry-run'],
|
|
797
|
+
examples: ['lj-awb create asset-group-update --group-id <id> --platform JIMENG --name "新名称" --dry-run'],
|
|
772
798
|
}),
|
|
773
799
|
args: [
|
|
774
800
|
{ name: 'group-id', valueName: 'id', description: '素材组 ID' },
|
|
775
801
|
{ name: 'name', valueName: 'name', description: '新名称' },
|
|
776
802
|
{ name: 'description', valueName: 'text', description: '新描述' },
|
|
803
|
+
ASSET_PLATFORM_ARG,
|
|
777
804
|
{ name: 'project-name', valueName: 'name', description: '项目名' },
|
|
778
805
|
DRY_RUN_ARG,
|
|
779
806
|
YES_ARG,
|
|
@@ -784,7 +811,7 @@ export function registerAwbCommands(cli) {
|
|
|
784
811
|
cli({
|
|
785
812
|
name: 'create asset',
|
|
786
813
|
description: commandHelp('把 COS 路径 / URL / 本地文件注册成平台素材', {
|
|
787
|
-
examples: ['lj-awb create asset --group-id <id> --url "
|
|
814
|
+
examples: ['lj-awb create asset --group-id <id> --platform JIMENG --url "asset-review/upload/a.png" --name "女主正面" --dry-run'],
|
|
788
815
|
}),
|
|
789
816
|
args: [
|
|
790
817
|
{ name: 'group-id', valueName: 'id', description: '素材组 ID' },
|
|
@@ -792,7 +819,7 @@ export function registerAwbCommands(cli) {
|
|
|
792
819
|
{ name: 'file', valueName: 'path', description: '本地素材文件;会先上传' },
|
|
793
820
|
{ name: 'url', valueName: 'url', description: '素材 URL 或 COS 路径' },
|
|
794
821
|
{ name: 'backend-path', valueName: 'path', description: 'upload files 返回的 backendPath' },
|
|
795
|
-
|
|
822
|
+
ASSET_PLATFORM_ARG,
|
|
796
823
|
DRY_RUN_ARG,
|
|
797
824
|
YES_ARG,
|
|
798
825
|
],
|
|
@@ -1276,12 +1303,12 @@ export function registerAwbCommands(cli) {
|
|
|
1276
1303
|
'lj-awb create subject --model-code tx --name 女主 --resource primary:./three-view.png --dry-run',
|
|
1277
1304
|
'lj-awb create subject --model-code vidu --name 女主 --resource primary:material/assets/a.png --resource face:./face.png --yes',
|
|
1278
1305
|
],
|
|
1279
|
-
hint: '参考图 slot:primary | three-view | face | side | back。主体 modelCode:KeLing /
|
|
1306
|
+
hint: '参考图 slot:primary | three-view | face | side | back。主体 modelCode 只接受 tx / vidu:KeLing / 可灵主体明确传 tx,Vidu 主体明确传 vidu。无 primary 时 three-view 自动升为主图;本地路径(./ 或绝对路径)会自动上传,含 :// 或 material/ 前缀的视为已上传 URL。',
|
|
1280
1307
|
}),
|
|
1281
1308
|
args: [
|
|
1282
1309
|
{ name: 'name', valueName: 'name', description: '主体名称' },
|
|
1283
1310
|
{ name: 'description', valueName: 'text', description: '主体描述' },
|
|
1284
|
-
{ name: 'model-code', valueName: 'code', description: '
|
|
1311
|
+
{ name: 'model-code', valueName: 'code', description: '主体创建模型编码,仅 tx / vidu;KeLing / 可灵传 tx,Vidu 传 vidu' },
|
|
1285
1312
|
{ name: 'reference-type', valueName: 'type', description: '参考类型,默认 image_refer' },
|
|
1286
1313
|
{ name: 'voice-id', valueName: 'id', description: '参考音色 ID,可选' },
|
|
1287
1314
|
{ name: 'tags-json', valueName: 'json', description: '标签数组,例如 [{"tagId":"o_102"}]' },
|
|
@@ -1363,7 +1390,7 @@ export function registerAwbCommands(cli) {
|
|
|
1363
1390
|
}),
|
|
1364
1391
|
args: [
|
|
1365
1392
|
{ name: 'input-file', valueName: 'path', description: '批量输入文件' },
|
|
1366
|
-
{ name: 'model-code', valueName: 'code', description: '
|
|
1393
|
+
{ name: 'model-code', valueName: 'code', description: '默认主体创建模型编码,仅 tx / vidu;单条可覆盖' },
|
|
1367
1394
|
{ name: 'project-name', valueName: 'name', description: '默认项目名' },
|
|
1368
1395
|
{ name: 'concurrency', valueName: 'n', description: '并发数,默认 1' },
|
|
1369
1396
|
DRY_RUN_ARG,
|
|
@@ -21,7 +21,8 @@ export const TASK_UPLOAD_SCENE = {
|
|
|
21
21
|
VIDEO_CREATE: 'material-video-create',
|
|
22
22
|
VIDEO_GROUP: 'material-video-create',
|
|
23
23
|
SUBJECT: 'material-video-create',
|
|
24
|
-
|
|
24
|
+
ASSET_REVIEW: 'asset-review',
|
|
25
|
+
DEFAULT: 'material-image-draw',
|
|
25
26
|
};
|
|
26
27
|
export const TERMINAL_TASK_STATES = new Set([
|
|
27
28
|
'SUCCESS',
|
|
@@ -160,9 +160,6 @@ function normalizeDryRun(data = {}) {
|
|
|
160
160
|
localFiles,
|
|
161
161
|
results: Array.isArray(data.results) ? data.results.map((row) => normalizeDryRunResult(row)) : data.results,
|
|
162
162
|
nextRefSubject: data.nextRefSubject,
|
|
163
|
-
resolvedModelCode: data.resolvedModelCode,
|
|
164
|
-
resolvedFrom: data.resolvedFrom,
|
|
165
|
-
resolvedFromValue: data.resolvedFromValue,
|
|
166
163
|
});
|
|
167
164
|
}
|
|
168
165
|
|
|
@@ -338,6 +335,7 @@ function normalizeAsset(data = {}) {
|
|
|
338
335
|
registered: data.registered,
|
|
339
336
|
groupId: data.groupId,
|
|
340
337
|
assetId: data.assetId,
|
|
338
|
+
platform: data.platform,
|
|
341
339
|
name: data.name,
|
|
342
340
|
projectName: data.projectName,
|
|
343
341
|
assetPath: data.assetPath,
|
|
@@ -536,6 +534,7 @@ export function normalizeOutputData(commandName, data) {
|
|
|
536
534
|
return normalizeAsset(data);
|
|
537
535
|
case 'model image-models':
|
|
538
536
|
case 'model video-models':
|
|
537
|
+
case 'model asset-review-models':
|
|
539
538
|
return normalizeList(data, ['models', 'items', 'rows']);
|
|
540
539
|
case 'account teams':
|
|
541
540
|
return normalizeList(data, ['teams']);
|
|
@@ -699,6 +698,7 @@ function rowSummary(row) {
|
|
|
699
698
|
'remoteTaskId',
|
|
700
699
|
'taskType',
|
|
701
700
|
'modelGroupCode',
|
|
701
|
+
'platform',
|
|
702
702
|
'provider',
|
|
703
703
|
'displayName',
|
|
704
704
|
'modelDesc',
|
|
@@ -1117,10 +1117,8 @@ export function formatTextOutput(commandName, data, context = {}) {
|
|
|
1117
1117
|
'taskType',
|
|
1118
1118
|
'taskStatus',
|
|
1119
1119
|
'modelCode',
|
|
1120
|
-
'resolvedModelCode',
|
|
1121
|
-
'resolvedFrom',
|
|
1122
|
-
'resolvedFromValue',
|
|
1123
1120
|
'modelGroupCode',
|
|
1121
|
+
'platform',
|
|
1124
1122
|
'projectGroupNo',
|
|
1125
1123
|
'projectId',
|
|
1126
1124
|
'groupId',
|
|
@@ -58,6 +58,9 @@ const REMOTE_VOICE_MIME_TYPES = new Set([
|
|
|
58
58
|
'video/mp4',
|
|
59
59
|
]);
|
|
60
60
|
const REMOTE_VOICE_EXTENSIONS = new Set(['.mp3', '.wav', '.m4a', '.aac', '.ogg', '.mp4']);
|
|
61
|
+
const ASSET_PLATFORM_CODES = ['JIMENG', 'BYTEPLUS'];
|
|
62
|
+
const ASSET_PLATFORM_CODE_SET = new Set(ASSET_PLATFORM_CODES);
|
|
63
|
+
const ASSET_PLATFORM_HINT = ASSET_PLATFORM_CODES.join('|');
|
|
61
64
|
|
|
62
65
|
export function normalizeUserInfo(payload) {
|
|
63
66
|
const data = payload && typeof payload === 'object' ? payload : {};
|
|
@@ -732,6 +735,44 @@ export async function listModels(kind, kwargs = {}) {
|
|
|
732
735
|
return { usage, models };
|
|
733
736
|
}
|
|
734
737
|
|
|
738
|
+
function requireAssetPlatform(value, options = {}) {
|
|
739
|
+
const flag = options.flag || '--platform';
|
|
740
|
+
const platform = trimToNull(value);
|
|
741
|
+
if (!platform) {
|
|
742
|
+
throw argumentError(`缺少参数:${flag}`, `素材加白平台必须显式传入 ${ASSET_PLATFORM_HINT},不要依赖默认平台。`);
|
|
743
|
+
}
|
|
744
|
+
if (!ASSET_PLATFORM_CODE_SET.has(platform)) {
|
|
745
|
+
throw argumentError(`不支持的平台:${platform}`, `只接受 ${ASSET_PLATFORM_HINT};请使用 model asset-review-models 查看模型支持的平台。`);
|
|
746
|
+
}
|
|
747
|
+
return platform;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
function optionalAssetPlatform(value) {
|
|
751
|
+
if (value == null || value === '') return null;
|
|
752
|
+
return requireAssetPlatform(value);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
function normalizeAssetReviewModelRecord(item = {}) {
|
|
756
|
+
return compactRecord({
|
|
757
|
+
modelGroupCode: item?.modelGroupCode ?? item?.groupCode ?? null,
|
|
758
|
+
platform: item?.platform ?? null,
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
export async function assetReviewModels(kwargs = {}) {
|
|
763
|
+
const modelGroupCode = trimToNull(kwargs.modelGroupCode);
|
|
764
|
+
const platform = optionalAssetPlatform(kwargs.platform);
|
|
765
|
+
const payload = await awbApi.fetchAssetReviewModels();
|
|
766
|
+
const models = normalizeRows(payload)
|
|
767
|
+
.map((item) => normalizeAssetReviewModelRecord(item))
|
|
768
|
+
.filter((item) => !modelGroupCode || item.modelGroupCode === modelGroupCode)
|
|
769
|
+
.filter((item) => !platform || item.platform === platform);
|
|
770
|
+
return {
|
|
771
|
+
models,
|
|
772
|
+
...(toBool(kwargs.includeRaw) ? { raw: payload } : {}),
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
|
|
735
776
|
async function findModelGroup(modelGroupCode, options = {}) {
|
|
736
777
|
const includeRaw = Boolean(options.includeRaw);
|
|
737
778
|
const [imageResult, videoResult] = await Promise.allSettled([
|
|
@@ -2168,7 +2209,35 @@ async function readJsonMaybeFile(value, fallback) {
|
|
|
2168
2209
|
return JSON.parse(fileText);
|
|
2169
2210
|
}
|
|
2170
2211
|
|
|
2171
|
-
|
|
2212
|
+
const AUDIO_VIDEO_EXTENSIONS = new Set([
|
|
2213
|
+
'.aac',
|
|
2214
|
+
'.aiff',
|
|
2215
|
+
'.avi',
|
|
2216
|
+
'.flac',
|
|
2217
|
+
'.m4a',
|
|
2218
|
+
'.m4v',
|
|
2219
|
+
'.mkv',
|
|
2220
|
+
'.mov',
|
|
2221
|
+
'.mp3',
|
|
2222
|
+
'.mp4',
|
|
2223
|
+
'.mpeg',
|
|
2224
|
+
'.mpg',
|
|
2225
|
+
'.oga',
|
|
2226
|
+
'.ogg',
|
|
2227
|
+
'.ogv',
|
|
2228
|
+
'.wav',
|
|
2229
|
+
'.webm',
|
|
2230
|
+
]);
|
|
2231
|
+
|
|
2232
|
+
function defaultUploadSceneForFile(filePath, mimeType = '') {
|
|
2233
|
+
const normalizedMime = String(mimeType || '').toLowerCase();
|
|
2234
|
+
if (normalizedMime.startsWith('audio/') || normalizedMime.startsWith('video/')) return TASK_UPLOAD_SCENE.VIDEO_CREATE;
|
|
2235
|
+
const ext = path.extname(String(filePath || '')).toLowerCase();
|
|
2236
|
+
if (AUDIO_VIDEO_EXTENSIONS.has(ext)) return TASK_UPLOAD_SCENE.VIDEO_CREATE;
|
|
2237
|
+
return TASK_UPLOAD_SCENE.DEFAULT;
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
async function collectFileSpecs(kwargs = {}, defaultSceneType = null) {
|
|
2172
2241
|
const specs = [];
|
|
2173
2242
|
for (const file of parseListArg(kwargs.file)) specs.push({ file });
|
|
2174
2243
|
for (const file of parseListArg(kwargs.files)) specs.push({ file });
|
|
@@ -2181,11 +2250,14 @@ async function collectFileSpecs(kwargs = {}, defaultSceneType = TASK_UPLOAD_SCEN
|
|
|
2181
2250
|
}
|
|
2182
2251
|
}
|
|
2183
2252
|
return specs
|
|
2184
|
-
.map((item) =>
|
|
2185
|
-
file
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2253
|
+
.map((item) => {
|
|
2254
|
+
const file = trimToNull(item.file ?? item.path ?? item.filePath);
|
|
2255
|
+
return {
|
|
2256
|
+
file,
|
|
2257
|
+
sceneType: trimToNull(item.sceneType ?? kwargs.sceneType) ?? defaultSceneType ?? defaultUploadSceneForFile(file),
|
|
2258
|
+
projectNo: trimToNull(item.projectNo ?? kwargs.projectNo) ?? '',
|
|
2259
|
+
};
|
|
2260
|
+
})
|
|
2189
2261
|
.filter((item) => item.file);
|
|
2190
2262
|
}
|
|
2191
2263
|
|
|
@@ -2194,7 +2266,7 @@ function dryRunBackendPath(filePath, sceneType) {
|
|
|
2194
2266
|
}
|
|
2195
2267
|
|
|
2196
2268
|
export async function uploadFilesCommand(kwargs = {}) {
|
|
2197
|
-
const specs = await collectFileSpecs(kwargs, trimToNull(kwargs.sceneType)
|
|
2269
|
+
const specs = await collectFileSpecs(kwargs, trimToNull(kwargs.sceneType));
|
|
2198
2270
|
if (!specs.length) throw argumentError('缺少上传文件', '传 --file <path> 或 --files a.png,b.mp4。');
|
|
2199
2271
|
if (toBool(kwargs.dryRun)) {
|
|
2200
2272
|
const files = [];
|
|
@@ -2224,7 +2296,7 @@ export async function uploadLocalFile(filePath, options = {}) {
|
|
|
2224
2296
|
throw argumentError(`文件不存在:${filePath}`);
|
|
2225
2297
|
}
|
|
2226
2298
|
const buffer = await fs.readFile(inspected.filePath);
|
|
2227
|
-
const sceneType = options.sceneType ??
|
|
2299
|
+
const sceneType = options.sceneType ?? defaultUploadSceneForFile(inspected.filePath, inspected.mimeType);
|
|
2228
2300
|
const groupId = crypto.randomUUID().replaceAll('-', '');
|
|
2229
2301
|
const secret = await awbApi.fetchUploadSecret({
|
|
2230
2302
|
sceneType,
|
|
@@ -3433,6 +3505,7 @@ function normalizeAssetGroup(item = {}) {
|
|
|
3433
3505
|
groupId: item?.id ?? item?.groupId ?? item?.assetGroupsId ?? null,
|
|
3434
3506
|
name: item?.name ?? item?.groupName ?? null,
|
|
3435
3507
|
description: item?.description ?? null,
|
|
3508
|
+
platform: item?.platform ?? null,
|
|
3436
3509
|
projectName: item?.projectName ?? null,
|
|
3437
3510
|
};
|
|
3438
3511
|
}
|
|
@@ -3640,43 +3713,53 @@ export async function assetMatchActor(kwargs = {}) {
|
|
|
3640
3713
|
}
|
|
3641
3714
|
|
|
3642
3715
|
export async function assetGroupList(kwargs = {}) {
|
|
3716
|
+
const platform = requireAssetPlatform(kwargs.platform);
|
|
3643
3717
|
const payload = await awbApi.listAssetGroups({
|
|
3644
3718
|
name: kwargs.name ?? '',
|
|
3719
|
+
platform,
|
|
3645
3720
|
pageNumber: toInt(kwargs.pageNumber, 1),
|
|
3646
3721
|
pageSize: toInt(kwargs.pageSize, 20),
|
|
3647
3722
|
...(parseListArg(kwargs.groupIds).length ? { groupIds: parseListArg(kwargs.groupIds) } : {}),
|
|
3648
3723
|
});
|
|
3649
|
-
return { groups: extractAssetGroupRows(payload), raw: toBool(kwargs.includeRaw) ? payload : undefined };
|
|
3724
|
+
return { platform, groups: extractAssetGroupRows(payload), raw: toBool(kwargs.includeRaw) ? payload : undefined };
|
|
3650
3725
|
}
|
|
3651
3726
|
|
|
3652
3727
|
export async function assetGroupGet(kwargs = {}) {
|
|
3653
3728
|
const groupId = requireValue(kwargs, 'groupId', 'group-id');
|
|
3654
|
-
const
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3729
|
+
const platform = requireAssetPlatform(kwargs.platform);
|
|
3730
|
+
const payload = await awbApi.getAssetGroup(groupId, { platform });
|
|
3731
|
+
if (payload && typeof payload === 'object' && !Array.isArray(payload)) {
|
|
3732
|
+
const group = normalizeAssetGroup(payload);
|
|
3733
|
+
return { ...group, platform: group.platform ?? platform };
|
|
3734
|
+
}
|
|
3735
|
+
return extractAssetGroupRows(payload)[0] ?? { groupId, platform };
|
|
3658
3736
|
}
|
|
3659
3737
|
|
|
3660
3738
|
export async function assetGroupCreate(kwargs = {}) {
|
|
3661
3739
|
const name = requireValue(kwargs, 'name');
|
|
3740
|
+
const platform = requireAssetPlatform(kwargs.platform);
|
|
3662
3741
|
const body = {
|
|
3663
3742
|
name,
|
|
3664
3743
|
description: kwargs.description ?? '',
|
|
3744
|
+
platform,
|
|
3665
3745
|
projectName: kwargs.projectName ?? 'default',
|
|
3666
3746
|
};
|
|
3667
3747
|
if (toBool(kwargs.dryRun)) return { dryRun: true, action: 'create asset-group', request: body };
|
|
3668
3748
|
ensureConfirmed(kwargs, '创建素材组是云端写入动作,需要确认', { action: 'create asset-group', body });
|
|
3669
3749
|
const payload = await awbApi.createAssetGroup(body);
|
|
3670
|
-
return { created: true, groupId: payload?.id ?? payload?.groupId ?? payload ?? null, name, projectName: body.projectName };
|
|
3750
|
+
return { created: true, groupId: payload?.id ?? payload?.groupId ?? payload ?? null, name, platform, projectName: body.projectName };
|
|
3671
3751
|
}
|
|
3672
3752
|
|
|
3673
3753
|
export async function assetGroupUpdate(kwargs = {}) {
|
|
3674
3754
|
const groupId = requireValue(kwargs, 'groupId', 'group-id');
|
|
3675
|
-
const
|
|
3755
|
+
const platform = requireAssetPlatform(kwargs.platform);
|
|
3756
|
+
const body = { platform };
|
|
3676
3757
|
if (kwargs.name != null) body.name = kwargs.name;
|
|
3677
3758
|
if (kwargs.description != null) body.description = kwargs.description;
|
|
3678
3759
|
if (kwargs.projectName != null) body.projectName = kwargs.projectName;
|
|
3679
|
-
if (!
|
|
3760
|
+
if (!['name', 'description', 'projectName'].some((key) => Object.prototype.hasOwnProperty.call(body, key))) {
|
|
3761
|
+
throw argumentError('缺少素材组更新字段', '至少传 --name、--description 或 --project-name;--platform 只用于定位平台资产组。');
|
|
3762
|
+
}
|
|
3680
3763
|
if (toBool(kwargs.dryRun)) return { dryRun: true, action: 'create asset-group-update', groupId, request: body };
|
|
3681
3764
|
ensureConfirmed(kwargs, '更新素材组是云端写入动作,需要确认', { action: 'create asset-group-update', groupId, body });
|
|
3682
3765
|
await awbApi.updateAssetGroup(groupId, body);
|
|
@@ -3692,6 +3775,7 @@ function extractAssetId(payload) {
|
|
|
3692
3775
|
export async function assetRegister(kwargs = {}) {
|
|
3693
3776
|
const groupId = requireValue(kwargs, 'groupId', 'group-id');
|
|
3694
3777
|
const name = requireValue(kwargs, 'name');
|
|
3778
|
+
const platform = requireAssetPlatform(kwargs.platform);
|
|
3695
3779
|
const localFile = trimToNull(kwargs.file);
|
|
3696
3780
|
const assetPath = trimToNull(kwargs.backendPath) ?? normalizeCosAssetPath(kwargs.url);
|
|
3697
3781
|
if (!localFile && !assetPath) throw argumentError('缺少素材路径', '传 --file、--backend-path 或 --url。');
|
|
@@ -3701,20 +3785,20 @@ export async function assetRegister(kwargs = {}) {
|
|
|
3701
3785
|
action: 'create asset',
|
|
3702
3786
|
request: {
|
|
3703
3787
|
assetGroupsId: groupId,
|
|
3704
|
-
url: localFile ? normalizeCosAssetPath(dryRunBackendPath(localFile, TASK_UPLOAD_SCENE.
|
|
3788
|
+
url: localFile ? normalizeCosAssetPath(dryRunBackendPath(localFile, TASK_UPLOAD_SCENE.ASSET_REVIEW)) : assetPath,
|
|
3705
3789
|
name,
|
|
3706
|
-
|
|
3790
|
+
platform,
|
|
3707
3791
|
},
|
|
3708
3792
|
localFile: localFile ? await inspectLocalFile(localFile) : null,
|
|
3709
3793
|
};
|
|
3710
3794
|
}
|
|
3711
3795
|
ensureConfirmed(kwargs, '注册素材是云端写入动作,需要确认', { action: 'create asset', groupId, name });
|
|
3712
|
-
const uploaded = localFile ? await uploadLocalFile(localFile, { sceneType: TASK_UPLOAD_SCENE.
|
|
3796
|
+
const uploaded = localFile ? await uploadLocalFile(localFile, { sceneType: TASK_UPLOAD_SCENE.ASSET_REVIEW }) : null;
|
|
3713
3797
|
const body = {
|
|
3714
3798
|
assetGroupsId: groupId,
|
|
3715
3799
|
url: normalizeCosAssetPath(uploaded?.backendPath ?? assetPath),
|
|
3716
3800
|
name,
|
|
3717
|
-
|
|
3801
|
+
platform,
|
|
3718
3802
|
};
|
|
3719
3803
|
const payload = await awbApi.registerAsset(body);
|
|
3720
3804
|
return {
|
|
@@ -3722,6 +3806,7 @@ export async function assetRegister(kwargs = {}) {
|
|
|
3722
3806
|
assetId: extractAssetId(payload),
|
|
3723
3807
|
groupId,
|
|
3724
3808
|
name,
|
|
3809
|
+
platform,
|
|
3725
3810
|
assetPath: body.url,
|
|
3726
3811
|
...(uploaded ? { upload: uploaded } : {}),
|
|
3727
3812
|
};
|
|
@@ -4008,37 +4093,32 @@ function tagListFromArg(value) {
|
|
|
4008
4093
|
.filter((item) => item.tagId);
|
|
4009
4094
|
}
|
|
4010
4095
|
|
|
4011
|
-
|
|
4012
|
-
const text = trimToNull(value);
|
|
4013
|
-
if (!text) return null;
|
|
4014
|
-
const normalized = text.toLowerCase();
|
|
4015
|
-
if (normalized === 'tx' || normalized === 'vidu') return normalized;
|
|
4016
|
-
return null;
|
|
4017
|
-
}
|
|
4096
|
+
const SUBJECT_MODEL_CODE_HINT = '传 --model-code tx|vidu;KeLing / 可灵主体明确传 tx,Vidu 主体明确传 vidu。';
|
|
4018
4097
|
|
|
4019
4098
|
function resolveSubjectCreateModelCode(kwargs = {}) {
|
|
4020
4099
|
const explicitModelCode = trimToNull(kwargs.modelCode ?? kwargs.model_code);
|
|
4021
|
-
|
|
4022
|
-
|
|
4100
|
+
if (explicitModelCode === 'tx' || explicitModelCode === 'vidu') {
|
|
4101
|
+
return { modelCode: explicitModelCode };
|
|
4102
|
+
}
|
|
4023
4103
|
if (explicitModelCode) {
|
|
4024
4104
|
throw argumentError(
|
|
4025
4105
|
`主体 modelCode 不支持:${explicitModelCode}`,
|
|
4026
|
-
|
|
4106
|
+
SUBJECT_MODEL_CODE_HINT,
|
|
4027
4107
|
);
|
|
4028
4108
|
}
|
|
4029
4109
|
|
|
4030
4110
|
throw argumentError(
|
|
4031
4111
|
'缺少主体 modelCode',
|
|
4032
|
-
|
|
4112
|
+
SUBJECT_MODEL_CODE_HINT,
|
|
4033
4113
|
);
|
|
4034
4114
|
}
|
|
4035
4115
|
|
|
4036
|
-
function buildSubjectCreateBody(kwargs, specs, assets) {
|
|
4116
|
+
function buildSubjectCreateBody(kwargs, specs, assets, modelCodeResolution = resolveSubjectCreateModelCode(kwargs)) {
|
|
4037
4117
|
const name = requireValue(kwargs, 'name');
|
|
4038
4118
|
const description = trimToNull(kwargs.description ?? kwargs.elementDescription) ?? name;
|
|
4039
4119
|
const primary = assets.find((item) => item.isPrimary);
|
|
4040
4120
|
const referAssets = assets.filter((item) => item.assetPath);
|
|
4041
|
-
const { modelCode } =
|
|
4121
|
+
const { modelCode } = modelCodeResolution;
|
|
4042
4122
|
return compactRecord({
|
|
4043
4123
|
reqTaskId: trimToNull(kwargs.reqTaskId),
|
|
4044
4124
|
modelCode,
|
|
@@ -4117,10 +4197,7 @@ export async function subjectPublish(kwargs = {}) {
|
|
|
4117
4197
|
dryRun: true,
|
|
4118
4198
|
action: 'create subject',
|
|
4119
4199
|
name,
|
|
4120
|
-
|
|
4121
|
-
resolvedFrom: modelCodeResolution.resolvedFrom,
|
|
4122
|
-
resolvedFromValue: modelCodeResolution.resolvedFromValue,
|
|
4123
|
-
request: buildSubjectCreateBody(kwargs, specs, assets),
|
|
4200
|
+
request: buildSubjectCreateBody(kwargs, specs, assets, modelCodeResolution),
|
|
4124
4201
|
assets,
|
|
4125
4202
|
localFiles: await inspectLocalFiles(specs.map((item) => item.file).filter(Boolean)),
|
|
4126
4203
|
nextRefSubject: `${name}=<externalId>`,
|
|
@@ -4140,7 +4217,7 @@ export async function subjectPublish(kwargs = {}) {
|
|
|
4140
4217
|
...(uploaded ? { upload: uploaded } : {}),
|
|
4141
4218
|
});
|
|
4142
4219
|
}
|
|
4143
|
-
const body = buildSubjectCreateBody(kwargs, specs, assets);
|
|
4220
|
+
const body = buildSubjectCreateBody(kwargs, specs, assets, modelCodeResolution);
|
|
4144
4221
|
const payload = await awbApi.createElement(body);
|
|
4145
4222
|
const elementId = extractCreatedElementId(payload);
|
|
4146
4223
|
if (!elementId) throw new LingjingAwbCliError('主体创建完成但未拿到 elementId', { type: 'api_error', exitCode: 1, details: payload });
|
|
@@ -4229,14 +4306,14 @@ export async function subtitleRemove(kwargs = {}) {
|
|
|
4229
4306
|
});
|
|
4230
4307
|
await appendTaskRecord(kwargs, {
|
|
4231
4308
|
taskId: result.taskId,
|
|
4232
|
-
taskType: '
|
|
4309
|
+
taskType: 'VIDEO_SUBTITLE_REMOVAL',
|
|
4233
4310
|
projectGroupNo: built.projectGroupNo,
|
|
4234
4311
|
promptSummary: `去字幕 sourceTaskId=${built.sourceTaskId}`,
|
|
4235
4312
|
});
|
|
4236
4313
|
return {
|
|
4237
4314
|
...result,
|
|
4238
4315
|
nextCommand: result.taskId
|
|
4239
|
-
? `lj-awb task
|
|
4316
|
+
? `lj-awb task video-subtitle-status --task-id ${result.taskId}${built.projectGroupNo ? ` --project-group-no ${built.projectGroupNo}` : ''} -f json`
|
|
4240
4317
|
: null,
|
|
4241
4318
|
};
|
|
4242
4319
|
}
|
|
@@ -4270,6 +4347,6 @@ export async function subtitleStatus(kwargs = {}) {
|
|
|
4270
4347
|
return taskStatus({
|
|
4271
4348
|
...kwargs,
|
|
4272
4349
|
taskId,
|
|
4273
|
-
taskType: '
|
|
4350
|
+
taskType: 'VIDEO_SUBTITLE_REMOVAL',
|
|
4274
4351
|
});
|
|
4275
4352
|
}
|
|
@@ -217,6 +217,33 @@ const VIRTUAL_COMMANDS = [
|
|
|
217
217
|
];
|
|
218
218
|
|
|
219
219
|
const RENAMED_COMMAND_HINTS = {
|
|
220
|
+
image: 'create image',
|
|
221
|
+
'image fee': 'create image-fee',
|
|
222
|
+
'image create': 'create image',
|
|
223
|
+
'image create-batch': 'create image-batch',
|
|
224
|
+
'image status': 'task image-status',
|
|
225
|
+
video: 'create video',
|
|
226
|
+
'video fee': 'create video-fee',
|
|
227
|
+
'video create': 'create video',
|
|
228
|
+
'video create-batch': 'create video-batch',
|
|
229
|
+
'video status': 'task video-status',
|
|
230
|
+
'video subtitle-remove': 'create video-subtitle-removal',
|
|
231
|
+
'video subtitle-status': 'task video-subtitle-status',
|
|
232
|
+
asset: 'create asset',
|
|
233
|
+
'asset match-actor': 'create asset-match-actor',
|
|
234
|
+
'asset groups': 'create asset-groups',
|
|
235
|
+
'asset group': 'create asset-group-get',
|
|
236
|
+
'asset group-create': 'create asset-group',
|
|
237
|
+
'asset group-update': 'create asset-group-update',
|
|
238
|
+
'asset register': 'create asset',
|
|
239
|
+
subject: 'create subject',
|
|
240
|
+
'subject list': 'create subject-list',
|
|
241
|
+
'subject publish': 'create subject',
|
|
242
|
+
'subject wait': 'create subject-wait',
|
|
243
|
+
'subject publish-batch': 'create subject-batch',
|
|
244
|
+
'subject voice list': 'create subject-voice-list',
|
|
245
|
+
'subject voice create': 'create subject-voice',
|
|
246
|
+
'subject voice wait': 'create subject-voice-wait',
|
|
220
247
|
'workspace me': 'account info',
|
|
221
248
|
'workspace teams': 'account teams',
|
|
222
249
|
'workspace team-select': 'account switch-team',
|
|
@@ -367,6 +394,7 @@ const GROUP_EXAMPLES = {
|
|
|
367
394
|
model: [
|
|
368
395
|
'lj-awb model image-models --model Banana',
|
|
369
396
|
'lj-awb model video-models --model Seedance',
|
|
397
|
+
'lj-awb model asset-review-models --platform JIMENG',
|
|
370
398
|
'lj-awb model input-guide',
|
|
371
399
|
'lj-awb model options --model-group-code <code>',
|
|
372
400
|
'lj-awb model create-spec --model-group-code <code>',
|
|
@@ -381,8 +409,8 @@ const GROUP_EXAMPLES = {
|
|
|
381
409
|
'lj-awb create video-fee --model-group-code <code> --prompt "雨夜奔跑" --duration 5',
|
|
382
410
|
'lj-awb create subject --model-code tx --name 女主 --resource primary:./three-view.png --dry-run',
|
|
383
411
|
'lj-awb create subject-wait --element-id <elementId> --wait-seconds 300',
|
|
384
|
-
'lj-awb create asset --group-id <id> --file ./actor.png --name "女主正面" --dry-run',
|
|
385
|
-
'lj-awb create asset-groups --name "女主"',
|
|
412
|
+
'lj-awb create asset --group-id <id> --platform JIMENG --file ./actor.png --name "女主正面" --dry-run',
|
|
413
|
+
'lj-awb create asset-groups --platform JIMENG --name "女主"',
|
|
386
414
|
],
|
|
387
415
|
task: [
|
|
388
416
|
'lj-awb task list --task-type IMAGE_CREATE --project-group-no <no>',
|
|
@@ -417,10 +445,11 @@ const COMMAND_REQUIRED_OPTIONS = {
|
|
|
417
445
|
'task video-subtitle-status': ['taskId'],
|
|
418
446
|
'task wait': ['taskId', 'taskType'],
|
|
419
447
|
'create asset-match-actor': ['description'],
|
|
420
|
-
'create asset-
|
|
421
|
-
'create asset-group': ['
|
|
422
|
-
'create asset-group
|
|
423
|
-
'create asset': ['groupId', '
|
|
448
|
+
'create asset-groups': ['platform'],
|
|
449
|
+
'create asset-group-get': ['groupId', 'platform'],
|
|
450
|
+
'create asset-group': ['name', 'platform'],
|
|
451
|
+
'create asset-group-update': ['groupId', 'platform'],
|
|
452
|
+
'create asset': ['groupId', 'name', 'platform'],
|
|
424
453
|
'artifact script row': ['rowKind', 'entityKey'],
|
|
425
454
|
'artifact script children': ['parentKey'],
|
|
426
455
|
'artifact script delete-row': ['rowKind', 'entityKey'],
|
|
@@ -595,6 +624,7 @@ const OUTPUT_KIND_BY_COMMAND = {
|
|
|
595
624
|
'credits usage': 'credits_usage',
|
|
596
625
|
'model image-models': 'model_list',
|
|
597
626
|
'model video-models': 'model_list',
|
|
627
|
+
'model asset-review-models': 'asset_review_model_list',
|
|
598
628
|
'model options': 'model_options',
|
|
599
629
|
'model create-spec': 'model_create_spec',
|
|
600
630
|
'model input-guide': 'model_input_guide',
|
|
@@ -687,9 +717,9 @@ const PREFLIGHTS_BY_COMMAND = {
|
|
|
687
717
|
'create subject': ['doctor --verify', 'create subject --model-code tx|vidu --dry-run'],
|
|
688
718
|
'create subject-batch': ['doctor --verify', 'prepare JSONL input with modelCode', 'create subject-batch --dry-run'],
|
|
689
719
|
'create video-subtitle-removal': ['doctor --verify', 'create video-subtitle-removal --source-task-id <videoTaskId> --dry-run'],
|
|
690
|
-
'create asset-group': ['create asset-group --dry-run'],
|
|
691
|
-
'create asset-group-update': ['create asset-group-update --dry-run'],
|
|
692
|
-
'create asset': ['create asset --dry-run'],
|
|
720
|
+
'create asset-group': ['model asset-review-models', 'create asset-group --platform <platform> --dry-run'],
|
|
721
|
+
'create asset-group-update': ['create asset-group-update --platform <platform> --dry-run'],
|
|
722
|
+
'create asset': ['model asset-review-models', 'create asset --platform <platform> --dry-run'],
|
|
693
723
|
'upload files': ['upload files --dry-run'],
|
|
694
724
|
};
|
|
695
725
|
|
|
@@ -803,6 +833,7 @@ function buildAgentContract() {
|
|
|
803
833
|
'schema version / domains / commands',
|
|
804
834
|
'auth / account / team / current projectGroup',
|
|
805
835
|
'modelCandidates by taskKind + keyword',
|
|
836
|
+
'assetReviewModels by modelGroupCode / platform',
|
|
806
837
|
'modelOptions / modelCreateSpec by modelGroupCode',
|
|
807
838
|
'uploaded backendPath by local file path or remote URL',
|
|
808
839
|
'taskId -> taskType / projectGroupNo / resultUrls / errorMessage',
|
|
@@ -817,6 +848,7 @@ function buildAgentContract() {
|
|
|
817
848
|
'supportsDryRun=true 的写入 / 扣费命令先 dry-run,确认后 yes;不要把 dry-run 当参数探索工具反复跑。',
|
|
818
849
|
'用户给出多条同模型同参数任务时优先 batch + task-record-file,不要单条循环 create。',
|
|
819
850
|
'命令返回 nextCommand / nextRefSubject / nextVoiceArg 时优先复用返回值,不手拼等价命令。',
|
|
851
|
+
'素材加白平台先通过 model asset-review-models 或用户明确输入确定;create asset-* 必须显式传 --platform,不要依赖默认平台。',
|
|
820
852
|
'旧根域 image / video / asset / subject 已移除;只使用 create / task / artifact 等 schema 暴露的 domain。',
|
|
821
853
|
],
|
|
822
854
|
canonicalFields: {
|
package/skills/lj-awb/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lj-awb
|
|
3
|
-
version: 0.3.
|
|
3
|
+
version: 0.3.17
|
|
4
4
|
description: "灵境 AWB CLI skill。使用 `lj-awb` 命令调用动漫平台 / AWB 云端能力,覆盖认证、项目组、积分、模型发现、上传、统一 create 创建域、任务查询、最终产物 artifact CRUD 与本地 JSON 导入。用户说生图、生视频、主体、音色、素材加白、去字幕、artifact 写入或查询时使用。正式生成、切换项目组、清空认证、artifact 写入等写入或扣费动作前必须确认。"
|
|
5
5
|
metadata:
|
|
6
6
|
requires:
|
package/skills/lj-awb/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.3.
|
|
1
|
+
0.3.17
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
# Asset Module
|
|
2
2
|
|
|
3
|
-
资产模块负责素材库的"分组管理 + 素材注册 + 候选匹配"
|
|
3
|
+
资产模块负责素材库的"分组管理 + 素材注册 + 候选匹配",服务于生视频前需要平台素材加白 / 过审的流程。是否支持素材加白、支持哪个平台,以 `model asset-review-models` 返回为准;不要按模型名称硬编码推断。可灵 / KeLing 和 Vidu 的角色一致性通常走 [`subject.md`](subject.md) 的 `create subject`,不要把主体 `modelCode=tx|vidu` 和资产平台 `JIMENG|BYTEPLUS` 混用。
|
|
4
4
|
|
|
5
5
|
## 命令
|
|
6
6
|
|
|
7
7
|
| 命令 | 用途 |
|
|
8
8
|
|------|------|
|
|
9
|
-
| `lj-awb
|
|
10
|
-
| `lj-awb create asset-
|
|
11
|
-
| `lj-awb create asset-group --
|
|
12
|
-
| `lj-awb create asset-group --name "<name>" --
|
|
13
|
-
| `lj-awb create asset-group
|
|
14
|
-
| `lj-awb create asset --group-id <id> --
|
|
15
|
-
| `lj-awb create asset --group-id <id> --
|
|
9
|
+
| `lj-awb model asset-review-models --model-group-code <code>` | 查该模型是否支持素材加白及支持的平台 |
|
|
10
|
+
| `lj-awb create asset-groups --platform JIMENG --name "<keyword>"` | 按平台查素材组(按名搜,避免重建已有的) |
|
|
11
|
+
| `lj-awb create asset-group-get --group-id <id> --platform JIMENG` | 按平台查素材组详情 + 成员 |
|
|
12
|
+
| `lj-awb create asset-group --platform JIMENG --name "<name>" --dry-run` | 预览创建素材组 |
|
|
13
|
+
| `lj-awb create asset-group --platform JIMENG --name "<name>" --yes` | 创建素材组(云端写入) |
|
|
14
|
+
| `lj-awb create asset-group-update --group-id <id> --platform JIMENG --name "<name>" --yes` | 改指定平台素材组名 |
|
|
15
|
+
| `lj-awb create asset --group-id <id> --platform JIMENG --url "asset-review/a.png" --name "女主正面" --yes` | 注册已上传素材 |
|
|
16
|
+
| `lj-awb create asset --group-id <id> --platform JIMENG --file ./a.png --name "女主正面" --yes` | 先上传到 asset-review 场景再注册(一步完成) |
|
|
16
17
|
| `lj-awb create asset-match-actor --description "..." --tags-json '[{"tagId":"o_102"}]'` | 候选匹配(角色画风 / 标签) |
|
|
17
18
|
|
|
18
19
|
## 什么时候用 match-actor
|
|
@@ -22,32 +23,38 @@
|
|
|
22
23
|
## 完整加白流程
|
|
23
24
|
|
|
24
25
|
```bash
|
|
25
|
-
#
|
|
26
|
-
lj-awb
|
|
27
|
-
|
|
26
|
+
# 0. 确认模型是否支持素材加白,以及应使用哪个平台
|
|
27
|
+
lj-awb model asset-review-models --model-group-code <videoModelGroupCode>
|
|
28
|
+
|
|
29
|
+
# 1. 找/建分组;platform 必须来自上一步返回或用户明确指定
|
|
30
|
+
lj-awb create asset-groups --platform JIMENG --name "项目X-角色"
|
|
31
|
+
lj-awb create asset-group --platform JIMENG --name "项目X-角色" --yes
|
|
28
32
|
|
|
29
33
|
# 2. 注册(本地文件版,自动上传)
|
|
30
|
-
lj-awb create asset --group-id <id> --file ./hero.png --name "主角正面" --dry-run
|
|
31
|
-
lj-awb create asset --group-id <id> --file ./hero.png --name "主角正面" --yes
|
|
34
|
+
lj-awb create asset --group-id <id> --platform JIMENG --file ./hero.png --name "主角正面" --dry-run
|
|
35
|
+
lj-awb create asset --group-id <id> --platform JIMENG --file ./hero.png --name "主角正面" --yes
|
|
32
36
|
|
|
33
37
|
# 3. 等审核(create asset 返回 taskId 时)
|
|
34
38
|
lj-awb task wait --task-id <id> --task-type ASSET_REGISTER --wait-seconds 180
|
|
35
39
|
|
|
36
40
|
# 4. 终态后用于视频
|
|
37
|
-
lj-awb create video --model-group-code <
|
|
38
|
-
--resource image:reference=
|
|
41
|
+
lj-awb create video --model-group-code <videoModelGroupCode> \
|
|
42
|
+
--resource image:reference:hero=asset:<assetId> \
|
|
39
43
|
...
|
|
40
44
|
```
|
|
41
45
|
|
|
42
46
|
## 规则
|
|
43
47
|
|
|
44
48
|
- `create asset-group` / `create asset-group-update` / `create asset` 都是云端写入,**必须确认**后追加 `--yes`。
|
|
49
|
+
- `create asset-*` 平台必须显式传 `--platform JIMENG|BYTEPLUS`;不要依赖默认平台,不要传中文名、小写名或供应商别名。
|
|
50
|
+
- `model asset-review-models` 只做发现,不自动创建资产组或素材;不要把 `modelGroupCode` 塞进资产创建命令。
|
|
51
|
+
- 不使用 `/assets/submissions` 这类隐式自动补组流程;资产组是否复用、是否新建由当前任务显式决定。
|
|
45
52
|
- 主体 element(视频里的"同一个人"概念)优先走 `create subject`,不要把素材组 / 素材 ID 当 subjectId 用——两者对应平台不同业务实体。
|
|
46
|
-
- `create asset --file` 在 `--dry-run` 阶段不会真上传,只预览 backendPath 推断结果。
|
|
53
|
+
- `create asset --file` 在 `--dry-run` 阶段不会真上传,只预览 `asset-review/...` backendPath 推断结果。
|
|
47
54
|
- 输出字段速查见 [`../references/output-fields.md`](../references/output-fields.md) 的"素材"小节。
|
|
48
55
|
|
|
49
56
|
## 下一步
|
|
50
57
|
|
|
51
|
-
- 注册成功 →
|
|
52
|
-
- 想看 group 里有哪些素材 → `create asset-group-get --group-id <id>`。
|
|
58
|
+
- 注册成功 → 优先按模型 create-spec / options 要求使用返回的 `assetId` 或 `assetPath`;需要 asset_id 时写 `--resource image:reference:<key>=asset:<assetId>`。
|
|
59
|
+
- 想看 group 里有哪些素材 → `create asset-group-get --group-id <id> --platform <platform>`。
|
|
53
60
|
- 长期复用同一角色(可灵)→ 改走 [`subject.md`](subject.md)。
|
|
@@ -34,3 +34,4 @@
|
|
|
34
34
|
- 状态和等待仍在查询域:`task image-status` / `task video-status` / `task wait` / `create subject-wait` / `create subject-voice-wait` / `task video-subtitle-status`。
|
|
35
35
|
- 所有 `create` 写入或扣费命令正式执行前必须先 `--dry-run`,用户确认后再 `--yes`。
|
|
36
36
|
- 查询型 create 子命令(`subject-list`、`subject-voice-list`、`asset-groups`、`asset-group-get`、`asset-match-actor`)是为了避免重复创建;创建前优先查重。
|
|
37
|
+
- `asset-groups` / `asset-group-get` / `asset-group` / `asset-group-update` / `asset` 都必须显式传 `--platform`;平台先由 `model asset-review-models` 或用户选择确定。
|
|
@@ -20,6 +20,7 @@ Agent 在当前任务中记录这些值,后续直接复用:
|
|
|
20
20
|
| `auth/account/team` | `doctor --verify`、`account info` | 登录 / 团队切换 |
|
|
21
21
|
| `projectGroupNo` | `project current` 或用户指定 | 项目组切换 |
|
|
22
22
|
| `modelCandidates` | `model image-models` / `model video-models` | 任务类型或关键词变化 |
|
|
23
|
+
| `assetReviewModels` / `assetReviewPlatform` | `model asset-review-models` | `modelGroupCode` 或平台切换 |
|
|
23
24
|
| `modelOptions` / `createSpec` | `model options` / `model create-spec` | `modelGroupCode` 变化 |
|
|
24
25
|
| `backendPath` | `upload files` 或 create dry-run/yes 的 upload 输出 | 本地文件或远端 URL 变化 |
|
|
25
26
|
| `task` | create 返回的 `taskId` / `nextCommand` / wait 结果 | 任务终态后只追加结果 |
|
|
@@ -73,8 +74,9 @@ CLI 当前能力分为:
|
|
|
73
74
|
|
|
74
75
|
### 素材库与加白
|
|
75
76
|
|
|
76
|
-
-
|
|
77
|
-
-
|
|
77
|
+
- 素材预审是否可用先查 `model asset-review-models --model-group-code <code>`;不要按模型名硬编码判断,也不要把 `modelGroupCode` 传入资产创建命令。
|
|
78
|
+
- `create asset-*` 必须显式传 `--platform JIMENG|BYTEPLUS`,平台来自 `model asset-review-models` 或用户明确选择;不要依赖 material 默认平台。
|
|
79
|
+
- 创建素材组前先 `create asset-groups --platform <platform> --name` 查重;有可用组就复用。
|
|
78
80
|
- `create asset --file` 会在正式阶段自动上传并注册;同一文件多任务复用时,先 `upload files` 缓存 `backendPath`。
|
|
79
81
|
- 注册成功后优先使用 `assetPath`,不要重新上传同一文件。
|
|
80
82
|
|
|
@@ -103,4 +105,5 @@ CLI 当前能力分为:
|
|
|
103
105
|
- 不要把 `--need-audio` 当音频输入;音频输入只能是 `audio:reference`。
|
|
104
106
|
- 不要把主体 `elementId` 当 `externalId`。
|
|
105
107
|
- 不要用单条 create 循环处理明显批量任务。
|
|
108
|
+
- 不要调用 `/assets/submissions` 或其它自动补齐资产组的隐式接口;素材组和素材注册必须通过 CLI 显式步骤完成。
|
|
106
109
|
- 不要直连 material / asset / 外部服务;统一走 `lj-awb`。
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|------|------|
|
|
9
9
|
| `lj-awb model image-models --model "<keyword>"` | 查询生图候选模型 |
|
|
10
10
|
| `lj-awb model video-models --model "<keyword>"` | 查询生视频候选模型 |
|
|
11
|
+
| `lj-awb model asset-review-models --model-group-code <code>` | 查询支持素材加白的模型组与平台关系 |
|
|
11
12
|
| `lj-awb model input-guide -f json` | 查看统一创建参数、resources 字段和素材绑定规则 |
|
|
12
13
|
| `lj-awb model options --model-group-code <code> -f json` | 查看该模型支持的 CLI 参数、枚举值、默认值、素材约束和条件约束 |
|
|
13
14
|
| `lj-awb model create-spec --model-group-code <code> -f json` | 查看该模型如何创建任务:输入模式、素材绑定规则、示例和前置步骤 |
|
|
@@ -80,6 +81,7 @@ Agent 读取这些字段:
|
|
|
80
81
|
- `model options` 是参数和素材约束入口;`model create-spec` 是创建方式入口。判断用户需求能否满足,优先看 `create-spec.supportedIntents[]`;素材格式 / 数量 / 时长限制看 `options.resources[]`;参数 / 资源联动看 `options.constraints[]`(`effect=no_selectable_values` 表示触发后该目标参数没有可选枚举,不要追问或传入)。
|
|
81
82
|
- `supportLastFrameOnly` 只表示模型是否支持「仅尾帧」输入;首尾帧过渡能力看 frames 资源的 `usage` 是否包含 `last_frame` 和数量约束。
|
|
82
83
|
- 用户说「上传音频 / 使用音乐 / 配音 / 音频参考」是**素材输入**,先看 `options.resources[]` 有没有 `mediaType=AUDIO usage=reference`;**不要先去找 `needAudio`**(那是输出音效开关)。具体使用规则、`reference_key` / `<<<key>>>` 对齐和 `--need-audio` 不是音频入口等都见 [`create-contract.md`](create-contract.md) §素材组织 + §Prompt 组装原则。
|
|
84
|
+
- 用户要走素材加白 / 素材库过审时,先跑 `model asset-review-models --model-group-code <code>` 判断该模型是否支持以及平台值;不要根据模型名称猜平台,也不要把 `modelGroupCode` 放进资产组或素材创建命令。
|
|
83
85
|
- 关键参数选择、`fee` / `create --dry-run` 前的追问流程、`inputRequirement.visualInputRequired` 检查等创建前校验见 [`create-contract.md`](create-contract.md) §创建前校验。
|
|
84
86
|
- 输出字段速查见 [`../references/output-fields.md`](../references/output-fields.md) 的"模型"小节。
|
|
85
87
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
主体模块用于创建 / 查询平台主体 element。视频主体参考应使用主体的 `externalId`,通过 `--resource subject:reference:<key>=asset:<externalId>` 传给视频创建命令。
|
|
4
4
|
|
|
5
|
-
> **发布主体前必须传 `--model-code <tx|vidu>`**:KeLing /
|
|
5
|
+
> **发布主体前必须传 `--model-code <tx|vidu>`**:KeLing / 可灵主体明确传 `tx`,Vidu 主体明确传 `vidu`。CLI 不接受 `keling`、`可灵`、`tencent`、`vidu-q` 等别名;不传或传错都会报 `argument_error`。如果用户没说目标平台,先追问"这个主体将来主要用在 KeLing / 可灵 还是 Vidu?"
|
|
6
6
|
|
|
7
7
|
## 命令
|
|
8
8
|
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
| `lj-awb create subject-voice --name 女主音色 --file ./voice.mp3 --yes` | 创建主体音色并返回 voiceRecordId |
|
|
14
14
|
| `lj-awb create subject-voice-wait --voice-record-id <voiceRecordId> --wait-seconds 300` | 等待音色 externalId 回填 |
|
|
15
15
|
| `lj-awb create subject-voice-list --name "女主"` | 查询已创建音色 |
|
|
16
|
-
| `lj-awb create subject --model-code tx --name 女主 --resource primary:./three-view.png --dry-run` | 预览 KeLing 主体创建,request.modelCode
|
|
17
|
-
| `lj-awb create subject --model-code vidu --name 女主 --resource primary:./three-view.png --dry-run` | 预览 Vidu 主体创建,request.modelCode
|
|
16
|
+
| `lj-awb create subject --model-code tx --name 女主 --resource primary:./three-view.png --dry-run` | 预览 KeLing 主体创建,request.modelCode 为 `tx` |
|
|
17
|
+
| `lj-awb create subject --model-code vidu --name 女主 --resource primary:./three-view.png --dry-run` | 预览 Vidu 主体创建,request.modelCode 为 `vidu` |
|
|
18
18
|
| `lj-awb create subject --model-code tx --name 女主 --resource primary:./three-view.png --yes` | 创建主体并返回 elementId |
|
|
19
19
|
| `lj-awb create subject-wait --element-id <elementId> --wait-seconds 300` | 等待 externalId 回填 |
|
|
20
20
|
| `lj-awb create subject --model-code vidu --name 女主 --resource primary:material/assets/a.png --yes` | 用已上传素材创建主体 |
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
## 规则
|
|
25
25
|
|
|
26
26
|
- 发布前确认主体名称、主参考图、可选正脸 / 侧面 / 背面图、项目名。
|
|
27
|
-
- 必须传 `--model-code tx|vidu`:KeLing /
|
|
27
|
+
- 必须传 `--model-code tx|vidu`:KeLing / 可灵用 `tx`,Vidu 用 `vidu`。不要传平台名别名。
|
|
28
28
|
- 如主体需要参考音色,先用 `create subject-voice --file <audio>` 创建音色,再 `create subject-voice-wait` 拿到 `externalId`,最后把它作为 `create subject --voice-id <externalId>`。
|
|
29
29
|
- `create subject-voice` 的音色来源三选一:`--file` 本地音频、`--voice-url` / `--audio-url` 已上传 material 音频路径、`--video-id` 已有视频 ID。
|
|
30
30
|
- 参考图统一通过 `--resource <slot>:<file|url>` 传入,slot ∈ `primary | three-view | face | side | back`。无 `primary` 时 `three-view` 自动升为主图;本地路径(`./` 或绝对路径)会自动上传,含 `://` 或 `material/` 前缀的视为已上传 URL。
|
|
@@ -172,7 +172,7 @@ lj-awb create video \
|
|
|
172
172
|
判断要点:
|
|
173
173
|
|
|
174
174
|
- `create subject-wait` 成功后优先使用返回的 `nextRefSubject`。
|
|
175
|
-
- `--model-code` 只接受 `tx|vidu`;KeLing / 可灵用 `tx`,Vidu 用 `vidu
|
|
175
|
+
- `--model-code` 只接受 `tx|vidu`;KeLing / 可灵用 `tx`,Vidu 用 `vidu`。
|
|
176
176
|
- `subject:reference:<key>=asset:<subjectId>` 必须放主体 ID;普通图片素材资产 ID 只能用于 `image:reference=asset:<assetId>` 等素材引用。
|
|
177
177
|
- prompt 中出现 `<<<key>>>` 时必须有同名 reference 资源;不出现时不强制补。
|
|
178
178
|
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
| 命令 | 用途 |
|
|
8
8
|
|------|------|
|
|
9
9
|
| `lj-awb upload files --files ./a.png,./b.mp4 --dry-run` | 预览上传文件 |
|
|
10
|
-
| `lj-awb upload files --file ./ref.png
|
|
10
|
+
| `lj-awb upload files --file ./ref.png` | 上传图片创建参考素材,默认 `material-image-draw` |
|
|
11
|
+
| `lj-awb upload files --file ./first.png --scene-type material-video-create` | 上传生视频 / 主体复用素材 |
|
|
11
12
|
| `lj-awb upload files --files-json ./files.json` | 按 JSON 清单上传 |
|
|
12
13
|
|
|
13
14
|
## 规则
|
|
@@ -16,17 +17,18 @@
|
|
|
16
17
|
- 后续任务的 `source.value` 一律使用 `backendPath`(例如 `material/...` 或 `/material/...`),**不要使用回显的 `url` 字段**。`url` 只是用于人工预览,把完整 `https://*.myqcloud.com/...` 直接塞回任务请求会让请求体冗余,也会破坏请求一致性。
|
|
17
18
|
- 对 Agent 来说,优先使用返回的结构化字段,不要从自然语言输出里猜 URL。
|
|
18
19
|
- 生图 / 生视频命令传本地参考文件时,会在内部自动上传;只有需要复用素材时才单独调用 `upload files`。
|
|
20
|
+
- 单独预上传时按下游任务选择 scene:未传 `--scene-type` 时,图片默认 `material-image-draw`,音频 / 视频默认 `material-video-create`;图片若要作为生视频首帧 / 尾帧 / 参考图或主体图复用,必须显式传 `--scene-type material-video-create`;只有明确走图片编辑入口时才传 `material-image-edit`。
|
|
19
21
|
- 即使把平台 COS 完整 URL 当作 `source.value` 传入,CLI 会自动剥离 host 还原为 `backendPath`;但不要依赖该自愈,仍以传 `backendPath` 为准。
|
|
20
22
|
- 输出字段速查见 [`../references/output-fields.md`](../references/output-fields.md) 的"文件上传"小节;上传失败(exit 30 / `upload_failed`)见 [`../references/error-codes.md`](../references/error-codes.md) 场景 6。
|
|
21
23
|
|
|
22
24
|
## 下一步
|
|
23
25
|
|
|
24
|
-
拿到 `
|
|
26
|
+
拿到 `files[].backendPath`(形如 `material/...`)后立刻就近喂给下游命令,不要重复 upload:
|
|
25
27
|
|
|
26
28
|
- 生图参考图:`lj-awb create image ... --resource image:reference=material/...`
|
|
27
29
|
- 生视频首帧 / 尾帧 / 参考图:`lj-awb create video ... --resource image:first_frame=material/...`
|
|
28
30
|
- 视频参考音频:`lj-awb create video ... --resource audio:reference=material/...`
|
|
29
31
|
- 主体发布参考图:`lj-awb create subject ... --resource primary:material/...`
|
|
30
|
-
-
|
|
32
|
+
- 注册到素材库(素材加白):优先让 `lj-awb create asset --group-id <id> --platform <platform> --file ./a.png --name "..." --yes` 自动上传到 `asset-review` 场景;若已单独上传,使用 `--backend-path asset-review/...` 或 `--url asset-review/...`。
|
|
31
33
|
|
|
32
34
|
> `create image` / `create video` / `create subject` 传 `--file` / 本地路径时**会自动 upload**——只有需要"先看 backendPath / 跨任务复用同一份素材"时才单独跑 `upload files`。
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- [批量任务](#批量任务) — `create-batch --concurrency`
|
|
13
13
|
- [分镜流水线(分镜图 → 视频)](#分镜流水线分镜图--视频) — GPT Image 2 分镜 → 视频生成
|
|
14
14
|
- [预上传后批量复用](#预上传后批量复用) — `upload files` 一次,多任务复用 `backendPath`
|
|
15
|
-
- [素材库加白后生视频](#素材库加白后生视频) —
|
|
15
|
+
- [素材库加白后生视频](#素材库加白后生视频) — `model asset-review-models` → `create asset` → 视频
|
|
16
16
|
- [Artifact 流水线错误恢复](#artifact-流水线错误恢复) — `import-storyboard` / 批量写入失败的局部重试
|
|
17
17
|
|
|
18
18
|
## 通用启动流程
|
|
@@ -140,8 +140,8 @@ lj-awb task record-poll \
|
|
|
140
140
|
1. 准备 `image.jsonl`,每行一个镜头的 `prompt` 和共用参考图(人物、场景):
|
|
141
141
|
|
|
142
142
|
```json
|
|
143
|
-
{"prompt":"镜头1:徐然推开 502 户门,门缝透出暖光...","ratio":"9:16","quality":"2k","resources":[{"type":"image","usage":"reference","source":{"kind":"url","value":"material/image-
|
|
144
|
-
{"prompt":"镜头2:徐然侧身贴墙,听门外脚步声...","ratio":"9:16","quality":"2k","resources":[{"type":"image","usage":"reference","source":{"kind":"url","value":"material/image-
|
|
143
|
+
{"prompt":"镜头1:徐然推开 502 户门,门缝透出暖光...","ratio":"9:16","quality":"2k","resources":[{"type":"image","usage":"reference","source":{"kind":"url","value":"material/image-draw/<人物参考>"}},{"type":"image","usage":"reference","source":{"kind":"url","value":"material/image-draw/<场景参考>"}}]}
|
|
144
|
+
{"prompt":"镜头2:徐然侧身贴墙,听门外脚步声...","ratio":"9:16","quality":"2k","resources":[{"type":"image","usage":"reference","source":{"kind":"url","value":"material/image-draw/<人物参考>"}}]}
|
|
145
145
|
```
|
|
146
146
|
|
|
147
147
|
2. 批量生分镜图(GPT Image 2 通道,并行 4):
|
|
@@ -167,8 +167,8 @@ lj-awb task record-poll \
|
|
|
167
167
|
4. 把每条 `taskId` 的 `result` 图(COS 对象路径,**用 `backendPath` 形式**)作为视频任务的 `first_frame`,组装 `video.jsonl`:
|
|
168
168
|
|
|
169
169
|
```json
|
|
170
|
-
{"prompt":"镜头1 动起来:徐然缓慢推门,光线从门缝渐扩","duration":5,"ratio":"9:16","quality":"720","resources":[{"type":"image","usage":"first_frame","source":{"kind":"url","value":"material/image-
|
|
171
|
-
{"prompt":"镜头2 动起来:徐然贴墙呼吸起伏,听门外动静","duration":5,"ratio":"9:16","quality":"720","resources":[{"type":"image","usage":"first_frame","source":{"kind":"url","value":"material/image-
|
|
170
|
+
{"prompt":"镜头1 动起来:徐然缓慢推门,光线从门缝渐扩","duration":5,"ratio":"9:16","quality":"720","resources":[{"type":"image","usage":"first_frame","source":{"kind":"url","value":"material/image-draw/<镜头1结果>"}}]}
|
|
171
|
+
{"prompt":"镜头2 动起来:徐然贴墙呼吸起伏,听门外动静","duration":5,"ratio":"9:16","quality":"720","resources":[{"type":"image","usage":"first_frame","source":{"kind":"url","value":"material/image-draw/<镜头2结果>"}}]}
|
|
172
172
|
```
|
|
173
173
|
|
|
174
174
|
5. 批量生视频(视频模型通道,并行 3):
|
|
@@ -197,11 +197,10 @@ lj-awb task record-poll \
|
|
|
197
197
|
```bash
|
|
198
198
|
lj-awb upload files \
|
|
199
199
|
--files ./hero.png,./scene.png \
|
|
200
|
-
--scene-type material-video-create \
|
|
201
200
|
-f json
|
|
202
201
|
```
|
|
203
202
|
|
|
204
|
-
读取响应 `data.
|
|
203
|
+
读取响应 `data.files[].backendPath`(形如 `material/...`),把这个值(**不是 `url` 字段**)写入下游。上面是图片创建参考图,默认 scene 是 `material-image-draw`;如果预上传后要作为视频首帧 / 尾帧 / 参考图或主体素材复用,命令必须显式加 `--scene-type material-video-create`。
|
|
205
204
|
|
|
206
205
|
```bash
|
|
207
206
|
lj-awb create video-batch \
|
|
@@ -228,23 +227,28 @@ lj-awb create video-batch \
|
|
|
228
227
|
|
|
229
228
|
## 素材库加白后生视频
|
|
230
229
|
|
|
231
|
-
|
|
230
|
+
适用:`model asset-review-models` 返回支持素材加白的平台模型。不要按 Seedance / BytePlus / 即梦等名称硬编码判断;可灵 / KeLing 和 Vidu 的角色一致性通常走 [主体参考生成视频](#主体参考生成视频),不走 asset。
|
|
232
231
|
|
|
233
232
|
```bash
|
|
234
|
-
#
|
|
235
|
-
lj-awb
|
|
236
|
-
|
|
237
|
-
|
|
233
|
+
# 0. 先确认该视频模型支持哪个素材加白平台
|
|
234
|
+
lj-awb model asset-review-models --model-group-code <videoModelGroupCode>
|
|
235
|
+
|
|
236
|
+
# 1. 找/建分组;platform 必须来自上一步返回或用户明确指定
|
|
237
|
+
lj-awb create asset-groups --platform JIMENG --name "项目X-角色"
|
|
238
|
+
lj-awb create asset-group --platform JIMENG --name "项目X-角色" --dry-run
|
|
239
|
+
lj-awb create asset-group --platform JIMENG --name "项目X-角色" --yes
|
|
238
240
|
|
|
239
241
|
# 2. 注册参考图(本地文件版,--file 在 --yes 阶段自动上传 + 注册一步完成)
|
|
240
242
|
lj-awb create asset \
|
|
241
243
|
--group-id <groupId> \
|
|
244
|
+
--platform JIMENG \
|
|
242
245
|
--file ./hero.png \
|
|
243
246
|
--name "主角正面" \
|
|
244
247
|
--dry-run
|
|
245
248
|
|
|
246
249
|
lj-awb create asset \
|
|
247
250
|
--group-id <groupId> \
|
|
251
|
+
--platform JIMENG \
|
|
248
252
|
--file ./hero.png \
|
|
249
253
|
--name "主角正面" \
|
|
250
254
|
--yes
|
|
@@ -255,24 +259,24 @@ lj-awb task wait \
|
|
|
255
259
|
--task-type ASSET_REGISTER \
|
|
256
260
|
--wait-seconds 180
|
|
257
261
|
|
|
258
|
-
# 4.
|
|
262
|
+
# 4. 加白成功后按模型资源要求使用 assetId 或 assetPath 创建视频
|
|
259
263
|
lj-awb create video-fee \
|
|
260
|
-
--model-group-code <
|
|
264
|
+
--model-group-code <videoModelGroupCode> \
|
|
261
265
|
--prompt "<...>" \
|
|
262
|
-
--resource image:reference=
|
|
266
|
+
--resource image:reference:hero=asset:<assetId> \
|
|
263
267
|
--project-group-no <projectGroupNo>
|
|
264
268
|
|
|
265
269
|
lj-awb create video \
|
|
266
|
-
--model-group-code <
|
|
270
|
+
--model-group-code <videoModelGroupCode> \
|
|
267
271
|
--prompt "<...>" \
|
|
268
|
-
--resource image:reference=
|
|
272
|
+
--resource image:reference:hero=asset:<assetId> \
|
|
269
273
|
--project-group-no <projectGroupNo> \
|
|
270
274
|
--dry-run
|
|
271
275
|
|
|
272
276
|
lj-awb create video \
|
|
273
|
-
--model-group-code <
|
|
277
|
+
--model-group-code <videoModelGroupCode> \
|
|
274
278
|
--prompt "<...>" \
|
|
275
|
-
--resource image:reference=
|
|
279
|
+
--resource image:reference:hero=asset:<assetId> \
|
|
276
280
|
--project-group-no <projectGroupNo> \
|
|
277
281
|
--yes
|
|
278
282
|
```
|
|
@@ -281,8 +285,9 @@ lj-awb create video \
|
|
|
281
285
|
|
|
282
286
|
- 用户描述"我有这样一个角色,平台上有没有现成的"时,先跑 `create asset-match-actor --description ... --tags-json '...'`,命中合适候选就跳过 register。
|
|
283
287
|
- 加白未终态时直接拿 `assetPath` 喂给视频,平台会拒;必须先 `task wait` 到 `taskStatus=success`。
|
|
284
|
-
- 同一角色后续视频任务复用同一 `assetPath`,不要每次重新 register。
|
|
285
|
-
- asset
|
|
288
|
+
- 同一角色后续视频任务复用同一 `assetId` / `assetPath`,不要每次重新 register。
|
|
289
|
+
- asset 系列只服务于素材加白;**不要**把素材 `assetId` / `assetPath` 当成可灵的 `subject:reference` 用,反之亦然。
|
|
290
|
+
- 不要调用隐式 submissions 自动补组;素材组查重、创建、素材注册都用显式 CLI 步骤。
|
|
286
291
|
|
|
287
292
|
## Artifact 流水线错误恢复
|
|
288
293
|
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
|
|
48
48
|
| outputKind | 命令 | 必报给用户 | agent 内部用 | 可丢弃 |
|
|
49
49
|
|------------|------|-----------|--------------|--------|
|
|
50
|
-
| `upload_result` | `upload files` | 上传文件数、`
|
|
50
|
+
| `upload_result` | `upload files` | 上传文件数、`files[].backendPath` | `backendPath`(喂给 `--resource <type>:<usage>=<backendPath>`) | `files[].url`、mimeType |
|
|
51
51
|
|
|
52
52
|
## 生图 / 生视频
|
|
53
53
|
|
|
@@ -89,11 +89,12 @@
|
|
|
89
89
|
|
|
90
90
|
| outputKind | 命令 | 必报给用户 | agent 内部用 | 可丢弃 |
|
|
91
91
|
|------------|------|-----------|--------------|--------|
|
|
92
|
+
| `asset_review_model_list` | `model asset-review-models` | `modelGroupCode`、`platform` | `platform`(后续 create asset-* 必填) | — |
|
|
92
93
|
| `asset_match_list` | `create asset-match-actor` | 候选列表(名称 + 评分) | `assetId/groupId` | — |
|
|
93
|
-
| `asset_group_list` | `create asset-groups` | `count` + 组名 | `groupId`(下游 register 必填) | — |
|
|
94
|
-
| `asset_group_detail` | `create asset-group-get` |
|
|
95
|
-
| `asset_group_write_result` | `create asset-group / group-update` | `created/updated`、`groupId` | — | — |
|
|
96
|
-
| `asset_register_result` | `create asset` | `registered`、`assetId`、`assetPath` | `assetId`(下游引用) | upload 嵌套 |
|
|
94
|
+
| `asset_group_list` | `create asset-groups` | `platform`、`count` + 组名 | `groupId`(下游 register 必填) | — |
|
|
95
|
+
| `asset_group_detail` | `create asset-group-get` | `platform`、组名、成员数 | `groupId` | — |
|
|
96
|
+
| `asset_group_write_result` | `create asset-group / group-update` | `created/updated`、`groupId`、`platform` | — | — |
|
|
97
|
+
| `asset_register_result` | `create asset` | `registered`、`assetId`、`assetPath`、`platform` | `assetId`(下游引用) | upload 嵌套 |
|
|
97
98
|
|
|
98
99
|
## Artifact(产物 CRUD)
|
|
99
100
|
|