@lingjingai/lj-awb-cli-pre 0.3.15 → 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.
@@ -28,6 +28,8 @@ const OPTION_SYNONYMS = {
28
28
  in: ['inputFile'],
29
29
  dry: ['dryRun'],
30
30
  force: ['yes'],
31
+ remoteTaskId: ['taskId'],
32
+ publicId: ['taskId'],
31
33
  };
32
34
 
33
35
  function levenshtein(a, b) {
@@ -202,19 +204,46 @@ const VIRTUAL_COMMANDS = [
202
204
  '',
203
205
  'Examples:',
204
206
  ' lj-awb schema -f json',
205
- ' lj-awb schema --domain video -f json',
206
- ' lj-awb schema --domain image --command create -f json',
207
+ ' lj-awb schema --domain create -f json',
208
+ ' lj-awb schema --domain create --command image -f json',
207
209
  '',
208
210
  'Hint: Agent 应优先读取 schema,而不是解析自然语言 help。',
209
211
  ].join('\n'),
210
212
  args: [
211
- { name: 'domain', valueName: 'name', description: '按命令域过滤,如 image / video / task / system' },
212
- { name: 'command', valueName: 'name', description: '按子命令过滤,如 create / wait / doctor' },
213
+ { name: 'domain', valueName: 'name', description: '按命令域过滤,如 create / task / artifact / system' },
214
+ { name: 'command', valueName: 'name', description: '按子命令过滤,如 image / video / wait / doctor' },
213
215
  ],
214
216
  },
215
217
  ];
216
218
 
217
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',
218
247
  'workspace me': 'account info',
219
248
  'workspace teams': 'account teams',
220
249
  'workspace team-select': 'account switch-team',
@@ -295,13 +324,10 @@ const GROUP_DESCRIPTIONS = {
295
324
  project: '项目:查看、切换、创建和更新项目组',
296
325
  credits: '积分:查询可扣积分余额、项目组预算和用量统计',
297
326
  model: '模型:查询生图 / 生视频模型、参数约束和创建用法',
327
+ create: '创建:统一提交图片、视频、主体、音色、素材和视频去字幕任务',
298
328
  upload: '上传:把本地文件上传为平台可访问素材',
299
- image: '图片:估价、提交、批量提交和查询生图任务',
300
- video: '视频:估价、提交、批量提交、查询和去字幕',
301
329
  task: '任务:任务列表、等待和本地任务台账',
302
- asset: '资产:素材库匹配、素材组和素材注册',
303
330
  artifact: '最终产物:剧本、资产、视频、剪辑 CRUD 与本地 JSON 导入',
304
- subject: '主体:发布和查询可复用主体资产',
305
331
  };
306
332
 
307
333
  const SUBGROUP_DESCRIPTIONS = {
@@ -341,7 +367,7 @@ const GROUP_EXAMPLES = {
341
367
  'lj-awb doctor',
342
368
  'lj-awb doctor --verify',
343
369
  'lj-awb schema -f json',
344
- 'lj-awb schema --domain video -f json',
370
+ 'lj-awb schema --domain create -f json',
345
371
  ],
346
372
  auth: [
347
373
  'lj-awb auth status',
@@ -368,6 +394,7 @@ const GROUP_EXAMPLES = {
368
394
  model: [
369
395
  'lj-awb model image-models --model Banana',
370
396
  'lj-awb model video-models --model Seedance',
397
+ 'lj-awb model asset-review-models --platform JIMENG',
371
398
  'lj-awb model input-guide',
372
399
  'lj-awb model options --model-group-code <code>',
373
400
  'lj-awb model create-spec --model-group-code <code>',
@@ -375,36 +402,30 @@ const GROUP_EXAMPLES = {
375
402
  upload: [
376
403
  'lj-awb upload files --files ./a.png,./b.mp4 --dry-run',
377
404
  ],
378
- image: [
379
- 'lj-awb image fee --model-group-code <code> --prompt "一只小狗"',
380
- 'lj-awb image create --model-group-code <code> --prompt "一只小狗" --dry-run',
381
- 'lj-awb image status --task-id <id>',
382
- ],
383
- video: [
384
- 'lj-awb video fee --model-group-code <code> --prompt "雨夜奔跑" --duration 5',
385
- 'lj-awb video create --model-group-code <code> --prompt "镜头推进" --resource image:first_frame=./actor.png --dry-run',
386
- 'lj-awb video create --model-group-code <code> --prompt "镜头推进" --resource image:first_frame=asset:<assetId> --dry-run',
387
- 'lj-awb video subtitle-status --remote-task-id <id>',
405
+ create: [
406
+ 'lj-awb create image --model-group-code <code> --prompt "一只小狗" --dry-run',
407
+ 'lj-awb create image-fee --model-group-code <code> --prompt "一只小狗"',
408
+ 'lj-awb create video --model-group-code <code> --prompt "镜头推进" --resource image:first_frame=./actor.png --dry-run',
409
+ 'lj-awb create video-fee --model-group-code <code> --prompt "雨夜奔跑" --duration 5',
410
+ 'lj-awb create subject --model-code tx --name 女主 --resource primary:./three-view.png --dry-run',
411
+ 'lj-awb create subject-wait --element-id <elementId> --wait-seconds 300',
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 "女主"',
388
414
  ],
389
415
  task: [
390
416
  'lj-awb task list --task-type IMAGE_CREATE --project-group-no <no>',
417
+ 'lj-awb task image-status --task-id <imageTaskId>',
418
+ 'lj-awb task video-status --task-id <videoTaskId>',
419
+ 'lj-awb task video-subtitle-status --task-id <subtitleTaskId>',
391
420
  'lj-awb task wait --task-id <id> --task-type IMAGE_CREATE --wait-seconds 180',
392
421
  'lj-awb task records --task-record-file .awb/tasks.jsonl',
393
422
  ],
394
- asset: [
395
- 'lj-awb asset match-actor --description "十八岁少女,古风" --tags-json \'{"gender":"女"}\'',
396
- 'lj-awb asset group-create --name "女主素材组" --dry-run',
397
- ],
398
423
  artifact: [
399
424
  'lj-awb artifact script import --project-id <projectId> --input-file 1_script/output/script.json --dry-run',
400
425
  'lj-awb artifact asset import --project-id <projectId> --input-dir 2_asset/output --dry-run',
401
426
  'lj-awb artifact video import-storyboard --project-id <projectId> --input-file 3_footage/output/ep001/ep001_storyboard.json --dry-run',
402
427
  'lj-awb artifact clip upsert-episode --project-id <projectId> --input-file 4_clip/output/ep001_clip_output.json --dry-run',
403
428
  ],
404
- subject: [
405
- 'lj-awb subject list --name "女主"',
406
- 'lj-awb subject publish --name 女主 --resource primary:./three-view.png --dry-run',
407
- ],
408
429
  };
409
430
 
410
431
  const COMMAND_REQUIRED_OPTIONS = {
@@ -413,21 +434,22 @@ const COMMAND_REQUIRED_OPTIONS = {
413
434
  'project ensure': ['name'],
414
435
  'model options': ['modelGroupCode'],
415
436
  'model create-spec': ['modelGroupCode'],
416
- 'image fee': ['modelGroupCode', 'prompt'],
417
- 'image create': ['modelGroupCode', 'prompt'],
418
- 'image create-batch': ['inputFile', 'modelGroupCode'],
419
- 'image status': ['taskId'],
420
- 'video fee': ['modelGroupCode'],
421
- 'video create': ['modelGroupCode'],
422
- 'video create-batch': ['inputFile', 'modelGroupCode'],
423
- 'video status': ['taskId'],
424
- 'video subtitle-remove': ['videoUrl'],
437
+ 'create image-fee': ['modelGroupCode', 'prompt'],
438
+ 'create image': ['modelGroupCode', 'prompt'],
439
+ 'create image-batch': ['inputFile', 'modelGroupCode'],
440
+ 'task image-status': ['taskId'],
441
+ 'create video-fee': ['modelGroupCode'],
442
+ 'create video': ['modelGroupCode'],
443
+ 'create video-batch': ['inputFile', 'modelGroupCode'],
444
+ 'task video-status': ['taskId'],
445
+ 'task video-subtitle-status': ['taskId'],
425
446
  'task wait': ['taskId', 'taskType'],
426
- 'asset match-actor': ['description'],
427
- 'asset group': ['groupId'],
428
- 'asset group-create': ['name'],
429
- 'asset group-update': ['groupId'],
430
- 'asset register': ['groupId', 'name'],
447
+ 'create asset-match-actor': ['description'],
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'],
431
453
  'artifact script row': ['rowKind', 'entityKey'],
432
454
  'artifact script children': ['parentKey'],
433
455
  'artifact script delete-row': ['rowKind', 'entityKey'],
@@ -459,18 +481,20 @@ const COMMAND_REQUIRED_OPTIONS = {
459
481
  'artifact clip episode-by-id': ['episodeId'],
460
482
  'artifact clip update-status': ['videoEpisodeId', 'status'],
461
483
  'artifact clip delete-episode': ['videoEpisodeId'],
462
- 'subject publish': ['name'],
463
- 'subject wait': ['elementId'],
464
- 'subject publish-batch': ['inputFile'],
484
+ 'create subject': ['name'],
485
+ 'create subject-wait': ['elementId'],
486
+ 'create subject-voice': ['name'],
487
+ 'create subject-batch': ['inputFile'],
465
488
  };
466
489
 
467
490
  const COMMAND_REQUIRED_ANY_OPTIONS = {
468
491
  'project update': [['name', 'point']],
469
492
  'upload files': [['file', 'files', 'filesJson']],
470
- 'video fee': [['prompt', 'resource', 'resourcesJson']],
471
- 'video create': [['prompt', 'resource', 'resourcesJson']],
472
- 'asset group-update': [['name', 'description', 'projectName']],
473
- 'asset register': [['file', 'url', 'backendPath']],
493
+ 'create video-fee': [['prompt', 'resource', 'resourcesJson']],
494
+ 'create video': [['prompt', 'resource', 'resourcesJson']],
495
+ 'create video-subtitle-removal': [['sourceTaskId']],
496
+ 'create asset-group-update': [['name', 'description', 'projectName']],
497
+ 'create asset': [['file', 'url', 'backendPath']],
474
498
  'artifact script upsert-row': [['bodyJson', 'inputFile']],
475
499
  'artifact asset upsert-actor': [['bodyJson', 'inputFile']],
476
500
  'artifact asset upsert-prop': [['bodyJson', 'inputFile']],
@@ -483,7 +507,10 @@ const COMMAND_REQUIRED_ANY_OPTIONS = {
483
507
  'artifact video upsert-clip': [['bodyJson', 'inputFile']],
484
508
  'artifact clip upsert-episode': [['bodyJson', 'inputFile']],
485
509
  'artifact clip upsert-batch': [['bodyJson', 'inputFile']],
486
- 'subject publish': [['resource']],
510
+ 'create subject': [['resource'], ['modelCode']],
511
+ 'create subject-batch': [['modelCode']],
512
+ 'create subject-voice': [['file', 'voiceUrl', 'audioUrl', 'videoId']],
513
+ 'create subject-voice-wait': [['voiceRecordId', 'reqTaskId']],
487
514
  };
488
515
 
489
516
  const ARTIFACT_WRITE_COMMANDS = [
@@ -526,24 +553,26 @@ const CONFIRMATION_COMMANDS = new Set([
526
553
  'project create',
527
554
  'project update',
528
555
  'project ensure',
529
- 'image create',
530
- 'image create-batch',
531
- 'video create',
532
- 'video create-batch',
533
- 'video subtitle-remove',
534
- 'asset group-create',
535
- 'asset group-update',
536
- 'asset register',
556
+ 'create image',
557
+ 'create image-batch',
558
+ 'create video',
559
+ 'create video-batch',
560
+ 'create video-subtitle-removal',
561
+ 'create asset-group',
562
+ 'create asset-group-update',
563
+ 'create asset',
537
564
  ...ARTIFACT_WRITE_COMMANDS,
538
- 'subject publish',
539
- 'subject publish-batch',
565
+ 'create subject',
566
+ 'create subject-voice',
567
+ 'create subject-batch',
540
568
  ]);
541
569
 
542
570
  const COST_COMMANDS = new Set([
543
- 'image create',
544
- 'image create-batch',
545
- 'video create',
546
- 'video create-batch',
571
+ 'create image',
572
+ 'create image-batch',
573
+ 'create video',
574
+ 'create video-batch',
575
+ 'create video-subtitle-removal',
547
576
  ]);
548
577
 
549
578
  const REMOTE_WRITE_COMMANDS = new Set([
@@ -553,17 +582,18 @@ const REMOTE_WRITE_COMMANDS = new Set([
553
582
  'project update',
554
583
  'project ensure',
555
584
  'upload files',
556
- 'image create',
557
- 'image create-batch',
558
- 'video create',
559
- 'video create-batch',
560
- 'video subtitle-remove',
561
- 'asset group-create',
562
- 'asset group-update',
563
- 'asset register',
585
+ 'create image',
586
+ 'create image-batch',
587
+ 'create video',
588
+ 'create video-batch',
589
+ 'create video-subtitle-removal',
590
+ 'create asset-group',
591
+ 'create asset-group-update',
592
+ 'create asset',
564
593
  ...ARTIFACT_WRITE_COMMANDS,
565
- 'subject publish',
566
- 'subject publish-batch',
594
+ 'create subject',
595
+ 'create subject-voice',
596
+ 'create subject-batch',
567
597
  ]);
568
598
 
569
599
  const LOCAL_STATE_WRITE_COMMANDS = new Set([
@@ -575,7 +605,7 @@ const LOCAL_STATE_WRITE_COMMANDS = new Set([
575
605
  ]);
576
606
 
577
607
  const DESTRUCTIVE_COMMANDS = new Set(['auth clear', ...ARTIFACT_DELETE_COMMANDS]);
578
- const LONG_RUNNING_COMMANDS = new Set(['task wait', 'task record-poll', 'subject wait']);
608
+ const LONG_RUNNING_COMMANDS = new Set(['task wait', 'task record-poll', 'create subject-wait', 'create subject-voice-wait']);
579
609
  const NETWORK_NONE_COMMANDS = new Set(['schema', 'auth status', 'auth clear', 'model input-guide', 'task records']);
580
610
  const NETWORK_CONDITIONAL_COMMANDS = new Set(['doctor', 'auth login']);
581
611
 
@@ -594,34 +624,38 @@ const OUTPUT_KIND_BY_COMMAND = {
594
624
  'credits usage': 'credits_usage',
595
625
  'model image-models': 'model_list',
596
626
  'model video-models': 'model_list',
627
+ 'model asset-review-models': 'asset_review_model_list',
597
628
  'model options': 'model_options',
598
629
  'model create-spec': 'model_create_spec',
599
630
  'model input-guide': 'model_input_guide',
600
631
  'upload files': 'upload_result',
601
- 'image fee': 'fee_estimate',
602
- 'image create': 'task_submission',
603
- 'image create-batch': 'batch_task_submission',
604
- 'image status': 'task_status',
605
- 'video fee': 'fee_estimate',
606
- 'video create': 'task_submission',
607
- 'video create-batch': 'batch_task_submission',
608
- 'video status': 'task_status',
609
- 'video subtitle-remove': 'subtitle_task_submission',
610
- 'video subtitle-status': 'subtitle_task_status',
632
+ 'create image-fee': 'fee_estimate',
633
+ 'create image': 'task_submission',
634
+ 'create image-batch': 'batch_task_submission',
635
+ 'task image-status': 'task_status',
636
+ 'create video-fee': 'fee_estimate',
637
+ 'create video': 'task_submission',
638
+ 'create video-batch': 'batch_task_submission',
639
+ 'task video-status': 'task_status',
640
+ 'create video-subtitle-removal': 'subtitle_task_submission',
641
+ 'task video-subtitle-status': 'subtitle_task_status',
611
642
  'task list': 'task_list',
612
643
  'task wait': 'task_status',
613
644
  'task records': 'local_task_records',
614
645
  'task record-poll': 'batch_task_status',
615
- 'asset match-actor': 'asset_match_list',
616
- 'asset groups': 'asset_group_list',
617
- 'asset group': 'asset_group_detail',
618
- 'asset group-create': 'asset_group_write_result',
619
- 'asset group-update': 'asset_group_write_result',
620
- 'asset register': 'asset_register_result',
621
- 'subject list': 'subject_list',
622
- 'subject publish': 'subject_publish_result',
623
- 'subject wait': 'subject_status',
624
- 'subject publish-batch': 'batch_subject_publish_result',
646
+ 'create asset-match-actor': 'asset_match_list',
647
+ 'create asset-groups': 'asset_group_list',
648
+ 'create asset-group-get': 'asset_group_detail',
649
+ 'create asset-group': 'asset_group_write_result',
650
+ 'create asset-group-update': 'asset_group_write_result',
651
+ 'create asset': 'asset_register_result',
652
+ 'create subject-list': 'subject_list',
653
+ 'create subject': 'subject_publish_result',
654
+ 'create subject-wait': 'subject_status',
655
+ 'create subject-voice-list': 'subject_voice_list',
656
+ 'create subject-voice': 'subject_voice_create_result',
657
+ 'create subject-voice-wait': 'subject_voice_status',
658
+ 'create subject-batch': 'batch_subject_publish_result',
625
659
  'artifact script get': 'artifact_full',
626
660
  'artifact script document': 'artifact_record',
627
661
  'artifact script rows': 'artifact_list',
@@ -676,16 +710,16 @@ const OUTPUT_KIND_BY_COMMAND = {
676
710
  };
677
711
 
678
712
  const PREFLIGHTS_BY_COMMAND = {
679
- 'image create': ['doctor --verify', 'model image-models', 'model options', 'model create-spec', 'confirm missing key params', 'image fee', 'image create --dry-run'],
680
- 'image create-batch': ['doctor --verify', 'model image-models', 'model options', 'model create-spec', 'prepare JSONL input', 'image create-batch --dry-run'],
681
- 'video create': ['doctor --verify', 'model video-models', 'model options', 'model create-spec', 'confirm missing key params', 'video fee', 'video create --dry-run'],
682
- 'video create-batch': ['doctor --verify', 'model video-models', 'model options', 'model create-spec', 'prepare JSONL input', 'video create-batch --dry-run'],
683
- 'subject publish': ['doctor --verify', 'subject publish --dry-run'],
684
- 'subject publish-batch': ['doctor --verify', 'prepare JSONL input', 'subject publish-batch --dry-run'],
685
- 'video subtitle-remove': ['doctor --verify', 'video subtitle-remove --dry-run'],
686
- 'asset group-create': ['asset group-create --dry-run'],
687
- 'asset group-update': ['asset group-update --dry-run'],
688
- 'asset register': ['asset register --dry-run'],
713
+ 'create image': ['doctor --verify', 'model image-models', 'model options', 'model create-spec', 'confirm missing key params', 'create image-fee', 'create image --dry-run'],
714
+ 'create image-batch': ['doctor --verify', 'model image-models', 'model options', 'model create-spec', 'prepare JSONL input', 'create image-batch --dry-run'],
715
+ 'create video': ['doctor --verify', 'model video-models', 'model options', 'model create-spec', 'confirm missing key params', 'create video-fee', 'create video --dry-run'],
716
+ 'create video-batch': ['doctor --verify', 'model video-models', 'model options', 'model create-spec', 'prepare JSONL input', 'create video-batch --dry-run'],
717
+ 'create subject': ['doctor --verify', 'create subject --model-code tx|vidu --dry-run'],
718
+ 'create subject-batch': ['doctor --verify', 'prepare JSONL input with modelCode', 'create subject-batch --dry-run'],
719
+ 'create video-subtitle-removal': ['doctor --verify', 'create video-subtitle-removal --source-task-id <videoTaskId> --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'],
689
723
  'upload files': ['upload files --dry-run'],
690
724
  };
691
725
 
@@ -760,13 +794,25 @@ function buildCommandSafety(command, optionKeys) {
760
794
  function buildCommandWorkflow(command) {
761
795
  const outputKind = OUTPUT_KIND_BY_COMMAND[command.name] || 'generic';
762
796
  const next = [];
763
- if (['image create', 'video create'].includes(command.name)) {
764
- next.push('读取 data.taskId 和 data.nextCommand', '运行 task wait 等待结果');
797
+ if (command.name === 'create image') {
798
+ next.push('读取 data.taskId 和 data.nextCommand', '立即运行响应里的 nextCommand,或 task wait --task-type IMAGE_CREATE 等待结果');
799
+ }
800
+ if (command.name === 'create video') {
801
+ next.push('读取 data.taskId 和 data.nextCommand', '立即运行响应里的 nextCommand,或 task wait --task-type VIDEO_GROUP 等待结果');
802
+ }
803
+ if (command.name === 'create video-subtitle-removal') {
804
+ next.push('读取 data.taskId 和 data.nextCommand', '运行 task video-subtitle-status 或响应里的 nextCommand 等待结果');
805
+ }
806
+ if (command.name === 'create subject') {
807
+ next.push('读取 data.elementId / data.externalId', 'externalId 为空时立刻运行 create subject-wait 获取 nextRefSubject');
808
+ }
809
+ if (command.name === 'create subject-voice') {
810
+ next.push('读取 data.voiceRecordId / data.externalId', 'externalId 为空时立刻运行 create subject-voice-wait 获取 nextVoiceArg');
765
811
  }
766
- if (command.name === 'subject publish') {
767
- next.push('读取 data.elementId', '运行 subject wait 获取 externalId / nextRefSubject');
812
+ if (command.name === 'create asset') {
813
+ next.push('读取 data.assetPath', '若后端返回审核 taskId,再运行 task wait --task-type ASSET_REGISTER');
768
814
  }
769
- if (['image create-batch', 'video create-batch', 'subject publish-batch'].includes(command.name)) {
815
+ if (['create image-batch', 'create video-batch', 'create subject-batch'].includes(command.name)) {
770
816
  next.push('读取每项 status / taskId / error', '使用 task record-poll 或对应 wait 命令恢复批量结果');
771
817
  }
772
818
  return {
@@ -781,6 +827,30 @@ function buildAgentContract() {
781
827
  defaultOutputFormat: 'compact-text',
782
828
  jsonFlag: '-f json',
783
829
  outputPolicy: '默认输出精简 key=value 文本,只保留决策字段;需要稳定 JSON、嵌套结构或脚本严格解析时显式传 -f json 或 --json。JSON envelope 字段已做归一化,见 canonicalFields。',
830
+ statePolicy: {
831
+ purpose: 'Agent 应在同一轮 / 同一项目中维护 AWB 上下文账本,减少重复查询和重复提交。',
832
+ cacheKeys: [
833
+ 'schema version / domains / commands',
834
+ 'auth / account / team / current projectGroup',
835
+ 'modelCandidates by taskKind + keyword',
836
+ 'assetReviewModels by modelGroupCode / platform',
837
+ 'modelOptions / modelCreateSpec by modelGroupCode',
838
+ 'uploaded backendPath by local file path or remote URL',
839
+ 'taskId -> taskType / projectGroupNo / resultUrls / errorMessage',
840
+ 'subject name + modelCode -> elementId / externalId / nextRefSubject',
841
+ 'subject voice name + source -> voiceRecordId / externalId / nextVoiceArg',
842
+ 'artifact projectId and imported file paths',
843
+ ],
844
+ invalidation: '用户切换账号、团队、项目组、模型、素材、prompt 或关键参数后,只刷新受影响的缓存;不要重复跑未变化的 model options / create-spec / fee。',
845
+ },
846
+ workflowPolicy: [
847
+ '模型探索阶段只读 model list / options / create-spec;fee 只在用户确认关键参数后跑一次。',
848
+ 'supportsDryRun=true 的写入 / 扣费命令先 dry-run,确认后 yes;不要把 dry-run 当参数探索工具反复跑。',
849
+ '用户给出多条同模型同参数任务时优先 batch + task-record-file,不要单条循环 create。',
850
+ '命令返回 nextCommand / nextRefSubject / nextVoiceArg 时优先复用返回值,不手拼等价命令。',
851
+ '素材加白平台先通过 model asset-review-models 或用户明确输入确定;create asset-* 必须显式传 --platform,不要依赖默认平台。',
852
+ '旧根域 image / video / asset / subject 已移除;只使用 create / task / artifact 等 schema 暴露的 domain。',
853
+ ],
784
854
  canonicalFields: {
785
855
  purpose: 'CLI 输出对上游平台多版本字段做了归一化。Agent 只识别 canonical 列,遇到 aliases 列出的旧字段名时说明是上游原始返回,CLI 已在 text / 归一化层做了 fallback。不要把旧名当成独立新字段对外报告。',
786
856
  fields: [
@@ -797,7 +867,7 @@ function buildAgentContract() {
797
867
  dryRunPolicy: 'schema.commands[].safety.supportsDryRun=true 的写入 / 扣费命令,正式执行前优先跑 --dry-run。',
798
868
  resourceShortcut: {
799
869
  flag: '--resource',
800
- syntax: 'type:usage[:reference_key]=path|url|asset:<id>; image create uses image:reference=... without key',
870
+ syntax: 'type:usage[:reference_key]=path|url|asset:<id>; create image uses image:reference=... without key',
801
871
  examples: [
802
872
  'image:reference=./ref.png',
803
873
  'image:first_frame=./hero.png',
@@ -811,7 +881,7 @@ function buildAgentContract() {
811
881
  {
812
882
  type: 'image|video|audio|subject',
813
883
  usage: 'reference|first_frame|last_frame|keyframe',
814
- reference_key: 'video reference placeholder key; not used by image create image:reference',
884
+ reference_key: 'video reference placeholder key; not used by create image image:reference',
815
885
  source: { kind: 'url|asset_id', value: '<local-file-or-http-url-or-material-backendPath-or-asset-id>' },
816
886
  },
817
887
  ],
@@ -820,14 +890,14 @@ function buildAgentContract() {
820
890
  command: `${commandPrefix()} model options --model-group-code <code>`,
821
891
  jsonCommand: `${commandPrefix()} model options --model-group-code <code> -f json`,
822
892
  purpose: '查询指定模型支持的 CLI 参数、枚举值、默认值、素材约束和条件约束。',
823
- useBefore: ['model create-spec', 'image fee', 'image create', 'video fee', 'video create'],
893
+ useBefore: ['model create-spec', 'create image-fee', 'create image', 'create video-fee', 'create video'],
824
894
  keyFields: ['params[].values', 'params[].defaultValue', 'resources[].mediaType', 'resources[].usage', 'resources[].fileTypes', 'resources[].maxFiles', 'resources[].supportLastFrameOnly', 'resources[].minDurationMs', 'resources[].maxDurationMs', 'constraints[].target', 'constraints[].conditions', 'constraints[].effect'],
825
895
  },
826
896
  modelCreateSpec: {
827
897
  command: `${commandPrefix()} model create-spec --model-group-code <code>`,
828
898
  jsonCommand: `${commandPrefix()} model create-spec --model-group-code <code> -f json`,
829
899
  purpose: '查看指定模型如何组织 create 命令:输入模式、素材绑定规则、示例和创建前检查项。',
830
- useBefore: ['image fee', 'image create', 'video fee', 'video create'],
900
+ useBefore: ['create image-fee', 'create image', 'create video-fee', 'create video'],
831
901
  keyFields: ['inputRequirement', 'supportedIntents', 'validationRules', 'agentGuidance', 'preflight', 'examples'],
832
902
  },
833
903
  modelInputGuide: {
@@ -839,6 +909,8 @@ function buildAgentContract() {
839
909
  taskTypes: {
840
910
  image: 'IMAGE_CREATE',
841
911
  video: 'VIDEO_GROUP',
912
+ subtitleRemoval: 'VIDEO_SUBTITLE_REMOVAL',
913
+ assetRegister: 'ASSET_REGISTER',
842
914
  },
843
915
  exitCodes: [
844
916
  { code: 0, type: 'success', meaning: '命令成功' },
@@ -846,8 +918,11 @@ function buildAgentContract() {
846
918
  { code: 2, type: 'argument_error|unknown_command|unknown_option', meaning: '参数或命令错误' },
847
919
  { code: 3, type: 'auth_required|auth_failed', meaning: '缺少认证或认证失败' },
848
920
  { code: 10, type: 'confirmation_required', meaning: '需要用户确认后追加 --yes' },
921
+ { code: 1, type: 'subject_failed', meaning: '主体创建任务已失败(error.type=subject_failed)。查看 error.details.errorMessage 后调整参考资源或模型重新创建。' },
922
+ { code: 1, type: 'subject_voice_failed', meaning: '主体音色创建任务已失败(error.type=subject_voice_failed)。查看 error.details.errorMessage 后调整音频或视频来源重新创建。' },
849
923
  { code: 20, type: 'task_still_running', meaning: '生图 / 生视频任务仍在运行,本轮等待窗口结束(error.type=task_still_running)。可继续 task wait 或 record-poll 续等。' },
850
- { code: 20, type: 'subject_still_pending', meaning: '主体 externalId 尚未回填,本轮等待窗口结束(error.type=subject_still_pending)。可继续 subject wait 续等。' },
924
+ { code: 20, type: 'subject_still_pending', meaning: '主体 externalId 尚未回填,本轮等待窗口结束(error.type=subject_still_pending)。可继续 create subject-wait 续等。' },
925
+ { code: 20, type: 'subject_voice_still_pending', meaning: '主体音色 externalId 尚未回填,本轮等待窗口结束(error.type=subject_voice_still_pending)。可继续 create subject-voice-wait 续等。' },
851
926
  { code: 30, type: 'network_error', meaning: '网络、TLS、HTTP 或外部平台不可用' },
852
927
  ],
853
928
  };
@@ -960,7 +1035,7 @@ function printRootHelp(commands, version) {
960
1035
  ` ${commandPrefix()} model input-guide`,
961
1036
  ` ${commandPrefix()} model options --model-group-code <code>`,
962
1037
  ` ${commandPrefix()} model create-spec --model-group-code <code>`,
963
- ` ${commandPrefix()} image create --model-group-code <code> --prompt "一只小狗" --dry-run`,
1038
+ ` ${commandPrefix()} create image --model-group-code <code> --prompt "一只小狗" --dry-run`,
964
1039
  '',
965
1040
  'Command groups:',
966
1041
  ];
@@ -988,6 +1063,7 @@ function printGroupHelp(group, commands, version) {
988
1063
  const items = commands.filter((command) => commandGroup(command) === group);
989
1064
  const subgroupMap = SUBGROUP_DESCRIPTIONS[group];
990
1065
  const hasSubgroups = Boolean(subgroupMap && Object.keys(subgroupMap).length);
1066
+ const directItems = hasSubgroups ? items.filter((command) => !commandSubgroupTokens(command)) : [];
991
1067
 
992
1068
  const lines = [
993
1069
  `lj-awb v${version}`,
@@ -999,6 +1075,7 @@ function printGroupHelp(group, commands, version) {
999
1075
  if (group === 'system') {
1000
1076
  lines.push(` ${commandPrefix()} <command> [options]`);
1001
1077
  } else if (hasSubgroups) {
1078
+ if (directItems.length) lines.push(` ${commandPrefix()} ${group} <command> [options]`);
1002
1079
  lines.push(` ${commandPrefix()} ${group} <subdomain> <command> [options]`);
1003
1080
  } else {
1004
1081
  lines.push(` ${commandPrefix()} ${group} <command> [options]`);
@@ -1025,6 +1102,13 @@ function printGroupHelp(group, commands, version) {
1025
1102
  if (!presentSubgroups.has(subgroup)) continue;
1026
1103
  lines.push(` ${subgroup.padEnd(10)} ${description}`);
1027
1104
  }
1105
+ if (directItems.length) {
1106
+ lines.push('', 'Commands:');
1107
+ for (const command of directItems) {
1108
+ const subcommand = commandSubcommand(command);
1109
+ lines.push(` ${subcommand.padEnd(28)} ${summaryOf(command)}`);
1110
+ }
1111
+ }
1028
1112
  } else {
1029
1113
  lines.push('Commands:');
1030
1114
  for (const command of items) {
@@ -1163,8 +1247,15 @@ export async function runStandaloneCli(argv = process.argv.slice(2)) {
1163
1247
  printSubgroupHelp(group, subgroup, commands, version);
1164
1248
  } else if (isCommandGroupName(parsed.commandName, commands)) {
1165
1249
  printGroupHelp(parsed.commandName, commands, version);
1166
- } else {
1250
+ } else if (!parsed.commandName) {
1167
1251
  printRootHelp(commands, version);
1252
+ } else {
1253
+ printError(new LingjingAwbCliError(`未知命令: ${parsed.commandName}`, {
1254
+ type: 'unknown_command',
1255
+ exitCode: 2,
1256
+ hint: unknownCommandHint(parsed.commandName),
1257
+ }), parsed.format, { command: parsed.commandName });
1258
+ process.exitCode = 2;
1168
1259
  }
1169
1260
  return;
1170
1261
  }