@lingjingai/lj-awb-cli-pre 0.4.7 → 0.4.9
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 +14 -5
- package/build/volta-pre.mjs +64 -0
- package/install.mjs +11 -3
- package/package.json +4 -3
- package/packages/awb-cli/package.json +2 -2
- package/packages/awb-core/package.json +1 -2
- package/packages/awb-core/src/commands.js +10 -460
- package/packages/awb-core/src/output.js +5 -287
- package/packages/awb-core/src/services.js +119 -12
- package/packages/awb-core/src/standalone.js +20 -184
- package/packages/awb-core/src/update.js +74 -3
- package/skills/lj-awb/SKILL.md +13 -7
- package/skills/lj-awb/VERSION +1 -1
- package/skills/lj-awb/compat.json +3 -3
- package/skills/lj-awb/modules/account.md +2 -2
- package/skills/lj-awb/modules/create-contract.md +10 -8
- package/skills/lj-awb/modules/driver.md +4 -10
- package/skills/lj-awb/modules/evals.md +2 -2
- package/skills/lj-awb/modules/image.md +3 -3
- package/skills/lj-awb/modules/model.md +50 -1
- package/skills/lj-awb/modules/project.md +2 -2
- package/skills/lj-awb/modules/task-manual.md +3 -3
- package/skills/lj-awb/modules/task.md +1 -1
- package/skills/lj-awb/modules/video.md +3 -3
- package/skills/lj-awb/modules/workflows.md +1 -76
- package/skills/lj-awb/references/error-codes.md +1 -1
- package/skills/lj-awb/references/output-fields.md +4 -11
- package/packages/awb-core/src/artifact.js +0 -936
- package/skills/lj-awb/modules/artifact/asset.md +0 -64
- package/skills/lj-awb/modules/artifact/clip.md +0 -65
- package/skills/lj-awb/modules/artifact/script.md +0 -37
- package/skills/lj-awb/modules/artifact/video.md +0 -65
- package/skills/lj-awb/modules/artifact.md +0 -65
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { LingjingAwbCliError, createEnvelope, toBool, toInt } from './common.js';
|
|
4
|
+
import { LingjingAwbCliError, createEnvelope, toBool, toInt, trimToNull } from './common.js';
|
|
5
5
|
import { registerAwbCommands } from './commands.js';
|
|
6
6
|
import { checkCliUpdate } from './update.js';
|
|
7
7
|
import {
|
|
@@ -196,7 +196,13 @@ function buildOutputContext(command, kwargs = {}, data = {}) {
|
|
|
196
196
|
confirmSet.autoConvert = true;
|
|
197
197
|
}
|
|
198
198
|
const isModelList = command.name === 'model image-models' || command.name === 'model video-models';
|
|
199
|
-
const
|
|
199
|
+
const hasModelFilter = isModelList && !toBool(kwargs.all) && Boolean(
|
|
200
|
+
trimToNull(kwargs.model) || trimToNull(kwargs.usage) || trimToNull(kwargs.provider)
|
|
201
|
+
|| trimToNull(kwargs.inputMode) || trimToNull(kwargs.supports)
|
|
202
|
+
|| trimToNull(kwargs.quality) || trimToNull(kwargs.ratio)
|
|
203
|
+
|| trimToNull(kwargs.duration) || toBool(kwargs.needAudio),
|
|
204
|
+
);
|
|
205
|
+
const modelListAll = isModelList && (toBool(kwargs.all) || hasModelFilter);
|
|
200
206
|
const modelListLimit = isModelList
|
|
201
207
|
? (modelListAll ? Number.POSITIVE_INFINITY : Math.max(1, toInt(kwargs.limit, 8)))
|
|
202
208
|
: undefined;
|
|
@@ -344,7 +350,7 @@ const VIRTUAL_COMMANDS = [
|
|
|
344
350
|
].join('\n'),
|
|
345
351
|
args: [
|
|
346
352
|
{ name: 'brief', description: '输出面向 Agent 的轻量能力摘要,不展开每个参数' },
|
|
347
|
-
{ name: 'domain', valueName: 'name', description: '按命令域过滤,如 create / task /
|
|
353
|
+
{ name: 'domain', valueName: 'name', description: '按命令域过滤,如 create / task / system' },
|
|
348
354
|
{ name: 'command', valueName: 'name', description: '按子命令过滤,如 image / video / wait / doctor' },
|
|
349
355
|
],
|
|
350
356
|
},
|
|
@@ -386,7 +392,8 @@ const RENAMED_COMMAND_HINTS = {
|
|
|
386
392
|
'workspace team-select': 'account switch-team',
|
|
387
393
|
'workspace project-groups': 'project list',
|
|
388
394
|
'workspace project-group-current': 'project current',
|
|
389
|
-
'workspace project-group-select': 'project
|
|
395
|
+
'workspace project-group-select': 'project switch',
|
|
396
|
+
'project use': 'project switch',
|
|
390
397
|
'workspace project-group-users': 'project users',
|
|
391
398
|
'workspace project-group-create': 'project create',
|
|
392
399
|
'workspace project-group-update': 'project update',
|
|
@@ -464,40 +471,11 @@ const GROUP_DESCRIPTIONS = {
|
|
|
464
471
|
create: '创建:统一提交图片、视频、主体、音色、素材和视频去字幕任务',
|
|
465
472
|
upload: '上传:把本地文件上传为平台可访问素材',
|
|
466
473
|
task: '任务:任务列表、等待和本地任务台账',
|
|
467
|
-
artifact: '最终产物:剧本、资产、视频、剪辑 CRUD 与本地 JSON 导入',
|
|
468
474
|
};
|
|
469
475
|
|
|
470
|
-
const SUBGROUP_DESCRIPTIONS = {
|
|
471
|
-
artifact: {
|
|
472
|
-
script: '剧本:document / asset / state / speaker / episode / scene / action 行 CRUD 与 script.json 批量导入',
|
|
473
|
-
asset: '资产:角色 / 道具 / 场景 及其状态 CRUD,actors/props/locations JSON 批量导入',
|
|
474
|
-
video: '视频:集 / 场 / clip 三级最终产物 CRUD 与 storyboard 批量导入',
|
|
475
|
-
clip: '剪辑:按集组织的剪辑宽表 CRUD 与状态更新',
|
|
476
|
-
},
|
|
477
|
-
};
|
|
476
|
+
const SUBGROUP_DESCRIPTIONS = {};
|
|
478
477
|
|
|
479
|
-
const SUBGROUP_EXAMPLES = {
|
|
480
|
-
'artifact script': [
|
|
481
|
-
'lj-awb artifact script import --project-id <projectId> --input-file 1_script/output/script.json --dry-run',
|
|
482
|
-
'lj-awb artifact script get --project-id <projectId>',
|
|
483
|
-
'lj-awb artifact script rows --project-id <projectId> --row-kind scene',
|
|
484
|
-
],
|
|
485
|
-
'artifact asset': [
|
|
486
|
-
'lj-awb artifact asset import --project-id <projectId> --input-dir 2_asset/output --dry-run',
|
|
487
|
-
'lj-awb artifact asset actors --project-id <projectId> --include-states true',
|
|
488
|
-
'lj-awb artifact asset props --project-id <projectId>',
|
|
489
|
-
],
|
|
490
|
-
'artifact video': [
|
|
491
|
-
'lj-awb artifact video import-storyboard --project-id <projectId> --input-file 3_footage/output/ep001/ep001_storyboard.json --dry-run',
|
|
492
|
-
'lj-awb artifact video episodes --project-id <projectId>',
|
|
493
|
-
'lj-awb artifact video clips --project-id <projectId> --episode-id ep_001 --scene-id scn_001',
|
|
494
|
-
],
|
|
495
|
-
'artifact clip': [
|
|
496
|
-
'lj-awb artifact clip upsert-episode --project-id <projectId> --input-file 4_clip/output/ep001_clip_output.json --dry-run',
|
|
497
|
-
'lj-awb artifact clip episodes --project-id <projectId>',
|
|
498
|
-
'lj-awb artifact clip episode-by-id --project-id <projectId> --episode-id ep_001',
|
|
499
|
-
],
|
|
500
|
-
};
|
|
478
|
+
const SUBGROUP_EXAMPLES = {};
|
|
501
479
|
|
|
502
480
|
const GROUP_EXAMPLES = {
|
|
503
481
|
system: [
|
|
@@ -528,7 +506,7 @@ const GROUP_EXAMPLES = {
|
|
|
528
506
|
project: [
|
|
529
507
|
'lj-awb project list',
|
|
530
508
|
'lj-awb project current',
|
|
531
|
-
'lj-awb project
|
|
509
|
+
'lj-awb project switch --project-group-no <no> --yes',
|
|
532
510
|
'lj-awb project create --name "CLI 测试项目" --point 1000 --yes',
|
|
533
511
|
],
|
|
534
512
|
credits: [
|
|
@@ -569,12 +547,6 @@ const GROUP_EXAMPLES = {
|
|
|
569
547
|
'lj-awb task wait --task-id <id> --task-type IMAGE_CREATE --wait-seconds 180',
|
|
570
548
|
'lj-awb task records --task-record-file .awb/tasks.jsonl',
|
|
571
549
|
],
|
|
572
|
-
artifact: [
|
|
573
|
-
'lj-awb artifact script import --project-id <projectId> --input-file 1_script/output/script.json --dry-run',
|
|
574
|
-
'lj-awb artifact asset import --project-id <projectId> --input-dir 2_asset/output --dry-run',
|
|
575
|
-
'lj-awb artifact video import-storyboard --project-id <projectId> --input-file 3_footage/output/ep001/ep001_storyboard.json --dry-run',
|
|
576
|
-
'lj-awb artifact clip upsert-episode --project-id <projectId> --input-file 4_clip/output/ep001_clip_output.json --dry-run',
|
|
577
|
-
],
|
|
578
550
|
};
|
|
579
551
|
|
|
580
552
|
const COMMAND_REQUIRED_OPTIONS = {
|
|
@@ -602,37 +574,6 @@ const COMMAND_REQUIRED_OPTIONS = {
|
|
|
602
574
|
'create asset-group': ['name', 'platform'],
|
|
603
575
|
'create asset-group-update': ['groupId', 'platform'],
|
|
604
576
|
'create asset': ['groupId', 'name', 'platform'],
|
|
605
|
-
'artifact script row': ['rowKind', 'entityKey'],
|
|
606
|
-
'artifact script children': ['parentKey'],
|
|
607
|
-
'artifact script delete-row': ['rowKind', 'entityKey'],
|
|
608
|
-
'artifact asset actor': ['actorKey'],
|
|
609
|
-
'artifact asset prop': ['propKey'],
|
|
610
|
-
'artifact asset location': ['locationKey'],
|
|
611
|
-
'artifact asset upsert-actor-state': ['actorKey'],
|
|
612
|
-
'artifact asset upsert-prop-state': ['propKey'],
|
|
613
|
-
'artifact asset upsert-location-state': ['locationKey'],
|
|
614
|
-
'artifact asset delete-actor': ['actorKey'],
|
|
615
|
-
'artifact asset delete-prop': ['propKey'],
|
|
616
|
-
'artifact asset delete-location': ['locationKey'],
|
|
617
|
-
'artifact asset delete-actor-state': ['actorKey', 'stateKey'],
|
|
618
|
-
'artifact asset delete-prop-state': ['propKey', 'stateKey'],
|
|
619
|
-
'artifact asset delete-location-state': ['locationKey', 'stateKey'],
|
|
620
|
-
'artifact video episode': ['episodeId'],
|
|
621
|
-
'artifact video scenes': ['episodeId'],
|
|
622
|
-
'artifact video scene': ['episodeId', 'sceneId'],
|
|
623
|
-
'artifact video clips': ['episodeId', 'sceneId'],
|
|
624
|
-
'artifact video clip': ['episodeId', 'sceneId', 'clipId'],
|
|
625
|
-
'artifact video upsert-scene': ['episodeId'],
|
|
626
|
-
'artifact video upsert-clip': ['episodeId', 'sceneId'],
|
|
627
|
-
'artifact video update-clip-urls': ['episodeId', 'sceneId', 'clipId', 'videoUrlsJson'],
|
|
628
|
-
'artifact video delete-episode': ['episodeId'],
|
|
629
|
-
'artifact video delete-scene': ['episodeId', 'sceneId'],
|
|
630
|
-
'artifact video delete-clip': ['episodeId', 'sceneId', 'clipId'],
|
|
631
|
-
'artifact video import-storyboard': ['inputFile'],
|
|
632
|
-
'artifact clip episode': ['videoEpisodeId'],
|
|
633
|
-
'artifact clip episode-by-id': ['episodeId'],
|
|
634
|
-
'artifact clip update-status': ['videoEpisodeId', 'status'],
|
|
635
|
-
'artifact clip delete-episode': ['videoEpisodeId'],
|
|
636
577
|
'create subject': ['name'],
|
|
637
578
|
'create subject-wait': ['elementId'],
|
|
638
579
|
'create subject-voice': ['name'],
|
|
@@ -649,61 +590,16 @@ const COMMAND_REQUIRED_ANY_OPTIONS = {
|
|
|
649
590
|
'create video-subtitle-removal': [['sourceTaskId']],
|
|
650
591
|
'create asset-group-update': [['name', 'description', 'projectName']],
|
|
651
592
|
'create asset': [['file', 'url', 'backendPath']],
|
|
652
|
-
'artifact script upsert-row': [['bodyJson', 'inputFile']],
|
|
653
|
-
'artifact asset upsert-actor': [['bodyJson', 'inputFile']],
|
|
654
|
-
'artifact asset upsert-prop': [['bodyJson', 'inputFile']],
|
|
655
|
-
'artifact asset upsert-location': [['bodyJson', 'inputFile']],
|
|
656
|
-
'artifact asset upsert-actor-state': [['bodyJson', 'inputFile']],
|
|
657
|
-
'artifact asset upsert-prop-state': [['bodyJson', 'inputFile']],
|
|
658
|
-
'artifact asset upsert-location-state': [['bodyJson', 'inputFile']],
|
|
659
|
-
'artifact video upsert-episode': [['bodyJson', 'inputFile']],
|
|
660
|
-
'artifact video upsert-scene': [['bodyJson', 'inputFile']],
|
|
661
|
-
'artifact video upsert-clip': [['bodyJson', 'inputFile']],
|
|
662
|
-
'artifact clip upsert-episode': [['bodyJson', 'inputFile']],
|
|
663
|
-
'artifact clip upsert-batch': [['bodyJson', 'inputFile']],
|
|
664
593
|
'create subject': [['resource'], ['modelCode']],
|
|
665
594
|
'create subject-batch': [['modelCode']],
|
|
666
595
|
'create subject-voice': [['file', 'voiceUrl', 'audioUrl', 'videoId']],
|
|
667
596
|
'create subject-voice-wait': [['voiceRecordId', 'reqTaskId']],
|
|
668
597
|
};
|
|
669
598
|
|
|
670
|
-
const ARTIFACT_WRITE_COMMANDS = [
|
|
671
|
-
'artifact script upsert-row',
|
|
672
|
-
'artifact script delete-row',
|
|
673
|
-
'artifact script import',
|
|
674
|
-
'artifact asset upsert-actor',
|
|
675
|
-
'artifact asset upsert-prop',
|
|
676
|
-
'artifact asset upsert-location',
|
|
677
|
-
'artifact asset upsert-actor-state',
|
|
678
|
-
'artifact asset upsert-prop-state',
|
|
679
|
-
'artifact asset upsert-location-state',
|
|
680
|
-
'artifact asset delete-actor',
|
|
681
|
-
'artifact asset delete-prop',
|
|
682
|
-
'artifact asset delete-location',
|
|
683
|
-
'artifact asset delete-actor-state',
|
|
684
|
-
'artifact asset delete-prop-state',
|
|
685
|
-
'artifact asset delete-location-state',
|
|
686
|
-
'artifact asset import',
|
|
687
|
-
'artifact video upsert-episode',
|
|
688
|
-
'artifact video upsert-scene',
|
|
689
|
-
'artifact video upsert-clip',
|
|
690
|
-
'artifact video update-clip-urls',
|
|
691
|
-
'artifact video delete-episode',
|
|
692
|
-
'artifact video delete-scene',
|
|
693
|
-
'artifact video delete-clip',
|
|
694
|
-
'artifact video import-storyboard',
|
|
695
|
-
'artifact clip upsert-episode',
|
|
696
|
-
'artifact clip upsert-batch',
|
|
697
|
-
'artifact clip update-status',
|
|
698
|
-
'artifact clip delete-episode',
|
|
699
|
-
];
|
|
700
|
-
|
|
701
|
-
const ARTIFACT_DELETE_COMMANDS = ARTIFACT_WRITE_COMMANDS.filter((name) => name.includes(' delete-'));
|
|
702
|
-
|
|
703
599
|
const CONFIRMATION_COMMANDS = new Set([
|
|
704
600
|
'auth clear',
|
|
705
601
|
'account switch-team',
|
|
706
|
-
'project
|
|
602
|
+
'project switch',
|
|
707
603
|
'project create',
|
|
708
604
|
'project update',
|
|
709
605
|
'project ensure',
|
|
@@ -716,7 +612,6 @@ const CONFIRMATION_COMMANDS = new Set([
|
|
|
716
612
|
'create asset-group',
|
|
717
613
|
'create asset-group-update',
|
|
718
614
|
'create asset',
|
|
719
|
-
...ARTIFACT_WRITE_COMMANDS,
|
|
720
615
|
'create subject',
|
|
721
616
|
'create subject-voice',
|
|
722
617
|
'create subject-batch',
|
|
@@ -733,7 +628,7 @@ const COST_COMMANDS = new Set([
|
|
|
733
628
|
|
|
734
629
|
const REMOTE_WRITE_COMMANDS = new Set([
|
|
735
630
|
'account switch-team',
|
|
736
|
-
'project
|
|
631
|
+
'project switch',
|
|
737
632
|
'project create',
|
|
738
633
|
'project update',
|
|
739
634
|
'project ensure',
|
|
@@ -748,7 +643,6 @@ const REMOTE_WRITE_COMMANDS = new Set([
|
|
|
748
643
|
'create asset-group',
|
|
749
644
|
'create asset-group-update',
|
|
750
645
|
'create asset',
|
|
751
|
-
...ARTIFACT_WRITE_COMMANDS,
|
|
752
646
|
'create subject',
|
|
753
647
|
'create subject-voice',
|
|
754
648
|
'create subject-batch',
|
|
@@ -759,12 +653,12 @@ const LOCAL_STATE_WRITE_COMMANDS = new Set([
|
|
|
759
653
|
'auth login',
|
|
760
654
|
'auth clear',
|
|
761
655
|
'auth logout',
|
|
762
|
-
'project
|
|
656
|
+
'project switch',
|
|
763
657
|
'project create',
|
|
764
658
|
'project ensure',
|
|
765
659
|
]);
|
|
766
660
|
|
|
767
|
-
const DESTRUCTIVE_COMMANDS = new Set(['auth clear'
|
|
661
|
+
const DESTRUCTIVE_COMMANDS = new Set(['auth clear']);
|
|
768
662
|
const LONG_RUNNING_COMMANDS = new Set(['auth login', 'credits redeem', 'task wait', 'task record-poll', 'create subject-wait', 'create subject-voice-wait']);
|
|
769
663
|
const NETWORK_NONE_COMMANDS = new Set(['schema', 'auth status', 'auth clear', 'auth logout', 'credits buy', 'model input-guide', 'task records']);
|
|
770
664
|
const NETWORK_CONDITIONAL_COMMANDS = new Set(['doctor', 'auth login']);
|
|
@@ -823,57 +717,6 @@ const OUTPUT_KIND_BY_COMMAND = {
|
|
|
823
717
|
'create subject-voice': 'subject_voice_create_result',
|
|
824
718
|
'create subject-voice-wait': 'subject_voice_status',
|
|
825
719
|
'create subject-batch': 'batch_subject_publish_result',
|
|
826
|
-
'artifact script get': 'artifact_full',
|
|
827
|
-
'artifact script document': 'artifact_record',
|
|
828
|
-
'artifact script rows': 'artifact_list',
|
|
829
|
-
'artifact script row': 'artifact_record',
|
|
830
|
-
'artifact script children': 'artifact_list',
|
|
831
|
-
'artifact script upsert-row': 'artifact_write_result',
|
|
832
|
-
'artifact script delete-row': 'artifact_delete_result',
|
|
833
|
-
'artifact script import': 'artifact_import_result',
|
|
834
|
-
'artifact asset get': 'artifact_full',
|
|
835
|
-
'artifact asset actors': 'artifact_list',
|
|
836
|
-
'artifact asset actor': 'artifact_record',
|
|
837
|
-
'artifact asset props': 'artifact_list',
|
|
838
|
-
'artifact asset prop': 'artifact_record',
|
|
839
|
-
'artifact asset locations': 'artifact_list',
|
|
840
|
-
'artifact asset location': 'artifact_record',
|
|
841
|
-
'artifact asset upsert-actor': 'artifact_write_result',
|
|
842
|
-
'artifact asset upsert-prop': 'artifact_write_result',
|
|
843
|
-
'artifact asset upsert-location': 'artifact_write_result',
|
|
844
|
-
'artifact asset upsert-actor-state': 'artifact_write_result',
|
|
845
|
-
'artifact asset upsert-prop-state': 'artifact_write_result',
|
|
846
|
-
'artifact asset upsert-location-state': 'artifact_write_result',
|
|
847
|
-
'artifact asset delete-actor': 'artifact_delete_result',
|
|
848
|
-
'artifact asset delete-prop': 'artifact_delete_result',
|
|
849
|
-
'artifact asset delete-location': 'artifact_delete_result',
|
|
850
|
-
'artifact asset delete-actor-state': 'artifact_delete_result',
|
|
851
|
-
'artifact asset delete-prop-state': 'artifact_delete_result',
|
|
852
|
-
'artifact asset delete-location-state': 'artifact_delete_result',
|
|
853
|
-
'artifact asset import': 'artifact_import_result',
|
|
854
|
-
'artifact video get': 'artifact_full',
|
|
855
|
-
'artifact video episodes': 'artifact_list',
|
|
856
|
-
'artifact video episode': 'artifact_record',
|
|
857
|
-
'artifact video scenes': 'artifact_list',
|
|
858
|
-
'artifact video scene': 'artifact_record',
|
|
859
|
-
'artifact video clips': 'artifact_list',
|
|
860
|
-
'artifact video clip': 'artifact_record',
|
|
861
|
-
'artifact video upsert-episode': 'artifact_write_result',
|
|
862
|
-
'artifact video upsert-scene': 'artifact_write_result',
|
|
863
|
-
'artifact video upsert-clip': 'artifact_write_result',
|
|
864
|
-
'artifact video update-clip-urls': 'artifact_write_result',
|
|
865
|
-
'artifact video delete-episode': 'artifact_delete_result',
|
|
866
|
-
'artifact video delete-scene': 'artifact_delete_result',
|
|
867
|
-
'artifact video delete-clip': 'artifact_delete_result',
|
|
868
|
-
'artifact video import-storyboard': 'artifact_import_result',
|
|
869
|
-
'artifact clip get': 'artifact_full',
|
|
870
|
-
'artifact clip episodes': 'artifact_list',
|
|
871
|
-
'artifact clip episode': 'artifact_record',
|
|
872
|
-
'artifact clip episode-by-id': 'artifact_record',
|
|
873
|
-
'artifact clip upsert-episode': 'artifact_write_result',
|
|
874
|
-
'artifact clip upsert-batch': 'artifact_import_result',
|
|
875
|
-
'artifact clip update-status': 'artifact_status_update',
|
|
876
|
-
'artifact clip delete-episode': 'artifact_delete_result',
|
|
877
720
|
};
|
|
878
721
|
|
|
879
722
|
const PREFLIGHTS_BY_COMMAND = {
|
|
@@ -1007,7 +850,7 @@ function buildCommandWorkflow(command) {
|
|
|
1007
850
|
}
|
|
1008
851
|
return {
|
|
1009
852
|
outputKind,
|
|
1010
|
-
recommendedPreflight: PREFLIGHTS_BY_COMMAND[command.name] ||
|
|
853
|
+
recommendedPreflight: PREFLIGHTS_BY_COMMAND[command.name] || [],
|
|
1011
854
|
nextActions: next,
|
|
1012
855
|
};
|
|
1013
856
|
}
|
|
@@ -1027,7 +870,6 @@ function buildDomainSummaries(commands) {
|
|
|
1027
870
|
|
|
1028
871
|
function requiredOptionsForCommand(command) {
|
|
1029
872
|
const requiredOptions = new Set();
|
|
1030
|
-
if (commandGroup(command) === 'artifact') requiredOptions.add('projectId');
|
|
1031
873
|
for (const key of COMMAND_REQUIRED_OPTIONS[command.name] || []) requiredOptions.add(key);
|
|
1032
874
|
return [...requiredOptions];
|
|
1033
875
|
}
|
|
@@ -1140,11 +982,6 @@ function buildAgentBrief(commands, version = 'unknown') {
|
|
|
1140
982
|
start: ['task wait', 'task record-poll', 'task records'],
|
|
1141
983
|
rule: '优先复用 create 返回的 nextCommand;批量任务使用 task-record-file,失败项单独重试。',
|
|
1142
984
|
},
|
|
1143
|
-
{
|
|
1144
|
-
intent: '最终产物 artifact',
|
|
1145
|
-
start: ['artifact script', 'artifact asset', 'artifact video', 'artifact clip'],
|
|
1146
|
-
rule: 'artifact 使用 project-id,不是 project-group-no;写入/删除/导入先 dry-run,再一次性确认写入面。',
|
|
1147
|
-
},
|
|
1148
985
|
],
|
|
1149
986
|
lookup: {
|
|
1150
987
|
preciseSchema: `${commandPrefix()} schema --domain <domain> --command <command> -f json`,
|
|
@@ -1185,7 +1022,6 @@ function buildAgentContract() {
|
|
|
1185
1022
|
'taskId -> taskType / projectGroupNo / resultUrls / errorMessage',
|
|
1186
1023
|
'subject name + modelCode -> elementId / externalId / nextRefSubject',
|
|
1187
1024
|
'subject voice name + source -> voiceRecordId / externalId / nextVoiceArg',
|
|
1188
|
-
'artifact projectId and imported file paths',
|
|
1189
1025
|
],
|
|
1190
1026
|
invalidation: '用户切换账号、团队、项目组、模型、素材、prompt 或关键参数后,只刷新受影响的缓存;不要重复跑未变化的 model options / create-spec / fee。',
|
|
1191
1027
|
},
|
|
@@ -1197,7 +1033,7 @@ function buildAgentContract() {
|
|
|
1197
1033
|
'用户给出多条同模型同参数任务时优先 batch + task-record-file,不要单条循环 create。',
|
|
1198
1034
|
'命令返回 nextCommand / nextRefSubject / nextVoiceArg 时优先复用返回值,不手拼等价命令。',
|
|
1199
1035
|
'素材加白平台先通过 model asset-review-models 或用户明确输入确定;create asset-* 必须显式传 --platform,不要依赖默认平台。create asset 会自动判断 assetType=Image/Video/Audio,本地文件会用 ffprobe 校验图片/视频尺寸、视频时长/FPS/像素数和音频时长;不合法素材正式执行时会询问是否转码,非交互场景可追加 --auto-convert;macOS + Homebrew 环境缺失时 CLI 会自动安装 ffmpeg。',
|
|
1200
|
-
'旧根域 image / video / asset / subject 已移除;只使用 create / task
|
|
1036
|
+
'旧根域 image / video / asset / subject 已移除;只使用 create / task 等 schema 暴露的 domain。',
|
|
1201
1037
|
],
|
|
1202
1038
|
canonicalFields: {
|
|
1203
1039
|
purpose: 'CLI 输出对上游平台多版本字段做了归一化。Agent 只识别 canonical 列,遇到 aliases 列出的旧字段名时说明是上游原始返回,CLI 已在 text / 归一化层做了 fallback。不要把旧名当成独立新字段对外报告。',
|
|
@@ -149,6 +149,32 @@ async function runNpm(args, options = {}) {
|
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
async function runVolta(args, options = {}) {
|
|
153
|
+
try {
|
|
154
|
+
const result = await execFileAsync('volta', args, {
|
|
155
|
+
cwd: currentRootDir(),
|
|
156
|
+
encoding: 'utf8',
|
|
157
|
+
timeout: options.timeoutMs || DEFAULT_NPM_TIMEOUT_MS,
|
|
158
|
+
maxBuffer: 1024 * 1024,
|
|
159
|
+
env: process.env,
|
|
160
|
+
});
|
|
161
|
+
return result;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
const stderr = String(error.stderr || '').trim();
|
|
164
|
+
const stdout = String(error.stdout || '').trim();
|
|
165
|
+
throw new LingjingAwbCliError('volta 命令执行失败', {
|
|
166
|
+
type: 'runtime_error',
|
|
167
|
+
exitCode: 30,
|
|
168
|
+
hint: stderr || stdout || error.message || '请确认 Volta 可用,或改用 npm 全局安装方式。',
|
|
169
|
+
details: {
|
|
170
|
+
command: `volta ${args.join(' ')}`,
|
|
171
|
+
code: error.code,
|
|
172
|
+
signal: error.signal,
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
152
178
|
export async function fetchLatestCliVersion(options = {}) {
|
|
153
179
|
const mocked = trimToNull(process.env.LINGJING_AWB_UPDATE_LATEST_VERSION);
|
|
154
180
|
if (mocked) return mocked;
|
|
@@ -258,6 +284,45 @@ function tailLines(value, limit = 8) {
|
|
|
258
284
|
return lines.slice(Math.max(0, lines.length - limit));
|
|
259
285
|
}
|
|
260
286
|
|
|
287
|
+
function isVoltaPackageImagePath(value) {
|
|
288
|
+
const normalized = String(value || '').replaceAll('\\', '/');
|
|
289
|
+
return normalized.includes('/.volta/tools/image/packages/');
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
async function isCurrentCommandVoltaManaged() {
|
|
293
|
+
try {
|
|
294
|
+
const result = await execFileAsync('volta', ['which', commandPrefix()], {
|
|
295
|
+
cwd: currentRootDir(),
|
|
296
|
+
encoding: 'utf8',
|
|
297
|
+
timeout: 5_000,
|
|
298
|
+
maxBuffer: 256 * 1024,
|
|
299
|
+
env: process.env,
|
|
300
|
+
});
|
|
301
|
+
return isVoltaPackageImagePath(result.stdout);
|
|
302
|
+
} catch {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async function resolveUpdateInstaller({ packageName, installVersion, installSpec, registry }) {
|
|
308
|
+
if (await isCurrentCommandVoltaManaged()) {
|
|
309
|
+
return {
|
|
310
|
+
name: 'volta',
|
|
311
|
+
args: ['install', npmInstallSpec(packageName, installVersion)],
|
|
312
|
+
command: `volta install ${npmInstallSpec(packageName, installVersion)}`,
|
|
313
|
+
run: () => runVolta(['install', npmInstallSpec(packageName, installVersion)], { timeoutMs: 120_000 }),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const args = npmArgsWithRegistry(['install', '-g', installSpec], registry);
|
|
318
|
+
return {
|
|
319
|
+
name: 'npm',
|
|
320
|
+
args,
|
|
321
|
+
command: `npm ${args.join(' ')}`,
|
|
322
|
+
run: () => runNpm(args, { timeoutMs: 120_000 }),
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
261
326
|
export async function runCliUpdate(kwargs = {}) {
|
|
262
327
|
const currentVersion = await readCurrentCliVersion().catch(() => 'unknown');
|
|
263
328
|
const packageName = resolveCliPackageName(kwargs);
|
|
@@ -268,7 +333,6 @@ export async function runCliUpdate(kwargs = {}) {
|
|
|
268
333
|
const force = toBool(kwargs.force);
|
|
269
334
|
const installVersion = latestVersion || 'latest';
|
|
270
335
|
const installSpec = npmInstallSpec(packageName, force ? 'latest' : installVersion);
|
|
271
|
-
const installArgs = npmArgsWithRegistry(['install', '-g', installSpec], registry);
|
|
272
336
|
|
|
273
337
|
if (checkOnly) {
|
|
274
338
|
return {
|
|
@@ -297,7 +361,13 @@ export async function runCliUpdate(kwargs = {}) {
|
|
|
297
361
|
};
|
|
298
362
|
}
|
|
299
363
|
|
|
300
|
-
const
|
|
364
|
+
const installer = await resolveUpdateInstaller({
|
|
365
|
+
packageName,
|
|
366
|
+
installVersion: force ? 'latest' : installVersion,
|
|
367
|
+
installSpec,
|
|
368
|
+
registry,
|
|
369
|
+
});
|
|
370
|
+
const result = await installer.run();
|
|
301
371
|
await saveState({
|
|
302
372
|
updateCheck: {
|
|
303
373
|
packageName,
|
|
@@ -314,10 +384,11 @@ export async function runCliUpdate(kwargs = {}) {
|
|
|
314
384
|
updated: true,
|
|
315
385
|
updateAvailable,
|
|
316
386
|
packageName,
|
|
387
|
+
installer: installer.name,
|
|
317
388
|
previousVersion: currentVersion,
|
|
318
389
|
currentVersion: latestVersion,
|
|
319
390
|
latestVersion,
|
|
320
|
-
command:
|
|
391
|
+
command: installer.command,
|
|
321
392
|
skillUpdated: true,
|
|
322
393
|
restartRecommended: true,
|
|
323
394
|
message: '更新完成。请退出并重新打开 AI Agent,以加载最新 CLI 和 skill。',
|
package/skills/lj-awb/SKILL.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lj-awb
|
|
3
|
-
version: 0.4.
|
|
4
|
-
description: "灵境 AWB CLI skill。使用 `lj-awb` 命令调用动漫平台 / AWB 云端能力,覆盖认证、项目组、积分(含充值购买与兑换码兑换)、模型发现、上传、统一 create
|
|
3
|
+
version: 0.4.9
|
|
4
|
+
description: "灵境 AWB CLI skill。使用 `lj-awb` 命令调用动漫平台 / AWB 云端能力,覆盖认证、项目组、积分(含充值购买与兑换码兑换)、模型发现、上传、统一 create 创建域、任务查询、视频超分。用户说生图、生视频、视频超分、主体、音色、素材加白、去字幕、充值、购买积分、兑换码时使用。正式生成、切换项目组、清空认证、兑换码等写入或扣费动作前必须确认。"
|
|
5
5
|
metadata:
|
|
6
6
|
bootstrap:
|
|
7
7
|
package: "@lingjingai/lj-awb-cli"
|
|
8
|
-
version: "0.4.
|
|
8
|
+
version: "0.4.9"
|
|
9
9
|
bin: "lj-awb"
|
|
10
10
|
cliHelp: "lj-awb --help"
|
|
11
11
|
---
|
|
@@ -15,13 +15,20 @@ metadata:
|
|
|
15
15
|
`lj-awb` 是确定性 CLI,skill 的职责是调度:少查、少问、少重跑,按 schema 和业务链条把命令串对。不要把本 skill 当成一堆命令片段来拼。
|
|
16
16
|
普通命令如果 JSON 输出里出现 `meta._notice.update`,先完成当前用户请求,再告诉用户当前版本和最新版本,并建议执行 `lj-awb update`;更新后提醒重新打开 AI Agent。
|
|
17
17
|
|
|
18
|
+
## 对话输出纪律
|
|
19
|
+
|
|
20
|
+
- 面向用户只汇报关键状态和确认点:候选模型摘要、需要用户选择的参数、费用 / dry-run 结果、任务 ID、最终产物链接或明确错误。
|
|
21
|
+
- 不主动暴露完整命令、长 JSON、schema 摘要、并行查询清单或内部调度过程;这些只在用户明确要求“展示命令 / 输出 / 日志”时给出。
|
|
22
|
+
- 中间更新保持短句,避免逐条复述每个只读查询。需要说明进度时,用“正在查询模型候选 / 正在估价 / 正在等待任务”这类概括表达。
|
|
23
|
+
- 最终答复聚焦结果和下一步,不把工具调用轨迹当作交付内容。
|
|
24
|
+
|
|
18
25
|
## 先读驱动器
|
|
19
26
|
|
|
20
27
|
任何非单条查询任务,都先加载 [`modules/driver.md`](modules/driver.md)。它定义:
|
|
21
28
|
|
|
22
29
|
- CLI 全部能力域和业务边界。
|
|
23
30
|
- Agent 状态账本,避免重复跑 `model options`、`model create-spec`、`fee`、`upload`。
|
|
24
|
-
-
|
|
31
|
+
- 创作、批量、主体、音色、素材加白的最短链条。
|
|
25
32
|
- 禁止清单:旧命令域、默认参数代决策、单条循环批量任务、直连后端等。
|
|
26
33
|
|
|
27
34
|
只在驱动器把你引到某个细节模块时才继续读该模块。不要为了“掌握全部功能”一次性加载所有模块。
|
|
@@ -77,7 +84,6 @@ schema 查询必须先返回,再组织业务命令;不要把 schema 查询
|
|
|
77
84
|
| 本地文件上传为 backendPath | `upload` | [`modules/upload.md`](modules/upload.md) |
|
|
78
85
|
| 图片 / 视频 / 去字幕 / 主体 / 音色 / 素材创建 | `create` | [`modules/create.md`](modules/create.md)、[`modules/create-contract.md`](modules/create-contract.md) |
|
|
79
86
|
| 异步任务等待与本地台账 | `task` | [`modules/task.md`](modules/task.md) |
|
|
80
|
-
| 剧本、资产、视频、剪辑最终产物 | `artifact` | [`modules/artifact.md`](modules/artifact.md) |
|
|
81
87
|
|
|
82
88
|
## 触发分流
|
|
83
89
|
|
|
@@ -95,15 +101,15 @@ schema 查询必须先返回,再组织业务命令;不要把 schema 查询
|
|
|
95
101
|
| “去字幕 / 擦掉英文字幕” | [`modules/video.md`](modules/video.md),只走 material 任务体系 |
|
|
96
102
|
| “批量 / 多镜头 / 分镜 / JSONL / 并行” | [`modules/workflows.md`](modules/workflows.md) 的批量链条 |
|
|
97
103
|
| “任务好了没 / 继续等 / 查状态” | [`modules/task.md`](modules/task.md) |
|
|
98
|
-
| “写入 AWB / 最终产物 / script / actor / storyboard / clip” | [`modules/artifact.md`](modules/artifact.md) |
|
|
99
104
|
|
|
100
|
-
歧义词先一句话澄清:`加白`
|
|
105
|
+
歧义词先一句话澄清:`加白` 是素材审核还是视觉白边;`角色一致` 是主体还是一次性参考图。
|
|
101
106
|
|
|
102
107
|
## 全局硬规则
|
|
103
108
|
|
|
104
109
|
- schema 中 `safety.requiresConfirmation=true` 的命令必须先向用户确认,再追加 `--yes`。
|
|
105
110
|
- schema 中 `safety.supportsDryRun=true` 的写入 / 扣费命令先 `--dry-run`,确认后再正式执行。
|
|
106
111
|
- 创作类命令在 fee / dry-run 前必须确认会影响价格或效果的关键参数;用户明确说“按默认”后才使用 defaultValue。
|
|
112
|
+
- Prompt 默认原文直出:用户提供明确 prompt / 创作描述时,禁止语义改写、润色、扩写或从参考图补画面细节;只有用户明确要求“优化 / 润色 / 扩写 / 你来写 prompt”时才允许改写,且改写后的最终 prompt 必须先展示并等待确认,之后才能 fee / dry-run / create。
|
|
107
113
|
- `fee` 是最终估价,不是参数探索工具。不要为多个 quality / duration / ratio / 渠道组合反复跑 fee。
|
|
108
114
|
- 正式图片 / 视频任务要带 `--project-group-no`,除非命令 schema 没有该参数。
|
|
109
115
|
- 命令返回 `nextCommand`、`nextRefSubject`、`nextVoiceArg` 时优先复用返回值,不手拼。
|
package/skills/lj-awb/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.4.
|
|
1
|
+
0.4.9
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
不该切换的场景:
|
|
21
21
|
|
|
22
|
-
- 用户只是要换"项目"——那是 [`project
|
|
22
|
+
- 用户只是要换"项目"——那是 [`project switch`](project.md),**不是 switch-team**。
|
|
23
23
|
- 用户没明确说要切——`account teams` 列出来给用户挑就够,别擅自切。
|
|
24
24
|
|
|
25
25
|
## 规则
|
|
@@ -27,6 +27,6 @@
|
|
|
27
27
|
- `account switch-team` 改变团队上下文,**必须确认**后追加 `--yes`。
|
|
28
28
|
- 切换原理:用当前用户 `userId` + 目标 `groupId` 调 `groupAccessKey` 换到该团队的 accessKey,再**写回本地认证文件**(等同重新登录到该团队)。
|
|
29
29
|
- 若用户是通过 `LINGJING_AWB_ACCESS_KEY` 环境变量登录的,写回文件**不生效**(env key 优先级高于文件);这种情况下要么 `unset LINGJING_AWB_ACCESS_KEY` 后再切,要么直接换该团队的 access key。
|
|
30
|
-
- 切换团队会**重置项目组上下文**:之后跑 `project current` 必然为空,需要让用户重新 `project
|
|
30
|
+
- 切换团队会**重置项目组上下文**:之后跑 `project current` 必然为空,需要让用户重新 `project switch --project-group-no <no>` 选一个。
|
|
31
31
|
- 不要把 `account info.groupName`(团队名)当作项目组名报告给用户。
|
|
32
32
|
- 输出字段速查见 [`../references/output-fields.md`](../references/output-fields.md) 的"账号与项目组"小节。
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
| CLI 参数 | 含义 | 组织方式 |
|
|
8
8
|
|----------|------|----------|
|
|
9
9
|
| `--model-group-code` | 模型组编码,决定使用哪个模型、计费方式和参数白名单 | 来自 `model image-models` / `model video-models` |
|
|
10
|
-
| `--prompt` | 提交给模型的最终提示词 |
|
|
10
|
+
| `--prompt` | 提交给模型的最终提示词 | 用户提供明确 prompt / 创作描述时默认原文直出,只做转义清理;禁止语义改写。只有用户明确要求优化 / 润色 / 扩写 / 代写 prompt 时才可改写,且必须先展示最终 prompt 等待确认 |
|
|
11
11
|
| `--ratio` | 画幅比例 | 只能从 `model options.params[key=ratio].values` 选择 |
|
|
12
12
|
| `--quality` | 清晰度 / 分辨率档位 | 只能从 `model options.params[key=quality].values` 选择 |
|
|
13
13
|
| `--generate-num` | 生图张数 | 仅图片模型支持时使用 |
|
|
@@ -67,14 +67,16 @@ JSON 语法:
|
|
|
67
67
|
|
|
68
68
|
## Prompt 组装原则
|
|
69
69
|
|
|
70
|
-
创建任务时,Prompt
|
|
70
|
+
创建任务时,Prompt 的核心原则是默认原文直出:
|
|
71
71
|
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
72
|
+
- 用户有明确创作描述或提示词时,`--prompt` 必须使用用户原文;只允许做 shell 转义、去掉包裹引号、首尾空白清理这类不改变语义的机械处理。
|
|
73
|
+
- 禁止把短 prompt 自动扩成更长描述;禁止主动补风格、镜头、剧情、光线、场景、情绪、动作细节;禁止为了“更适合模型”而润色。
|
|
74
|
+
- “使用某模型 / 参考生 / 生成视频 / 用这张图 / 用这个音频”等操作性指令只用于选择模型、资源和参数,不要改写成新的画面描述。
|
|
75
|
+
- 参考图已经作为资源输入时,不要从图片内容中推断“山谷、街道、室内、人物外观”等画面描述塞进 prompt;除非用户明确要求看图补充描述或根据图写 prompt。
|
|
75
76
|
- 用户只是描述任务目标时,不要默认补资源占位符;图片生图永远不用 `<<<key>>>`,视频只有用户明确要在 prompt 中绑定某个参考对象时才使用。
|
|
76
|
-
-
|
|
77
|
-
-
|
|
77
|
+
- 用户没有比较明确的创作需求或提示词时,先追问关键创作意图,或使用最小中性表达;不要为了让 prompt 好看而主动补内容。
|
|
78
|
+
- 只有用户明确要求“优化 / 润色 / 扩写 / 改写 / 帮我写 prompt / 你来写 prompt / 更适合生图或生视频”时,Agent 才能进行提示词创作。
|
|
79
|
+
- 一旦最终 prompt 与用户原文发生任何可见语义变化,必须先展示原始 prompt 和最终 prompt,等待用户确认;确认前不得运行 `fee`、`create --dry-run` 或正式 `create`。
|
|
78
80
|
|
|
79
81
|
规则:
|
|
80
82
|
|
|
@@ -122,7 +124,7 @@ Agent 必须按顺序做:
|
|
|
122
124
|
7. 用 `supportedIntents[]` 匹配用户意图;不要只看模型列表摘要就生成最终能力结论。
|
|
123
125
|
8. 参数枚举值只从 `model options.params[].values` 选择,素材限制只从 `model options.resources[]` 校验,参数 / 资源联动限制按 `model options.constraints[]` 收窄。新增通用参数只要在 `params[]` 中出现且带 `cliArg`,就通过 `--model-param` / `--model-params-json` 显式传入。
|
|
124
126
|
9. 不主动列举所有缺失控制项;只追问会影响价格 / 效果的关键参数。视频包括 `quality`、`duration`、约束后仍可选的 `ratio`,以及用户明确要求输出音效时的 `needAudio`;图片包括 `quality`、`ratio`、`generateNum`。
|
|
125
|
-
10. 组装最终 prompt
|
|
127
|
+
10. 组装最终 prompt;默认使用用户原文。若用户明确要求优化 / 代写且最终 prompt 与用户原文发生任何可见语义变化,先展示原始 prompt 和最终 prompt,等待用户确认。
|
|
126
128
|
11. 若用户上传或指定音频文件,必须先确认 `model options.resources[]` 中存在 `mediaType=AUDIO usage=reference` 后再组织 `audio:reference` 资源;只有用户明确要求“输出是否带模型生成音效/音频”时,才检查 `model options.params[]` 是否存在 `needAudio`。
|
|
127
129
|
12. 用户未提供关键参数时,把 `model options.params[].values` 和 `defaultValue` 转成候选问题;用户选择或确认“按默认”前,不跑 `create image-fee` / `create video-fee`,也不跑 `create --dry-run`。即使模型给了 `defaultValue`,也不要静默写入请求。
|
|
128
130
|
13. 跑 `create image-fee` / `create video-fee` 获取预估积分——**只跑一次,参数取用户已确认的那组**。`fee` 是"用户敲定参数后的最终估价",不是参数探索 / 候选比较工具:不要为了对比价格档跑 `fee` × 多个 `quality` / `duration` / `ratio` 组合,也不要为了横向比同款不同渠道跑 `fee` × 多个 `modelGroupCode`;价格档差异从 `model options.feeCalcType` + 参数取值表里就能口算/展示给用户,比较应该发生在 `model options` 阶段。
|