cerevox 3.0.0-alpha.2 → 3.0.0-alpha.21
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/dist/core/ai.d.ts +36 -26
- package/dist/core/ai.d.ts.map +1 -1
- package/dist/core/ai.js +172 -14
- package/dist/core/ai.js.map +1 -1
- package/dist/mcp/servers/prompts/rules/anim.md +72 -0
- package/dist/mcp/servers/prompts/rules/creative-ad.md +2 -2
- package/dist/mcp/servers/prompts/rules/expert.md +2 -2
- package/dist/mcp/servers/prompts/rules/freeform.md +2 -2
- package/dist/mcp/servers/prompts/rules/general-video.md +2 -2
- package/dist/mcp/servers/prompts/rules/story-telling.md +2 -2
- package/dist/mcp/servers/prompts/skills/workflows/general-video.md +2 -2
- package/dist/mcp/servers/prompts/skills/workflows/music-video.md +2 -2
- package/dist/mcp/servers/zerocut.d.ts.map +1 -1
- package/dist/mcp/servers/zerocut.js +133 -81
- package/dist/mcp/servers/zerocut.js.map +1 -1
- package/dist/utils/coze.d.ts +8 -0
- package/dist/utils/coze.d.ts.map +1 -1
- package/dist/utils/coze.js +20 -0
- package/dist/utils/coze.js.map +1 -1
- package/package.json +1 -1
- package/dist/mcp/servers/prompts/rules/music-video.md +0 -164
- package/dist/mcp/servers/prompts/rules/stage-play.md +0 -269
|
@@ -55,7 +55,7 @@ const node_fs_1 = require("node:fs");
|
|
|
55
55
|
const coze_1 = require("../../utils/coze");
|
|
56
56
|
const mp3_duration_1 = __importDefault(require("mp3-duration"));
|
|
57
57
|
const image_size_1 = __importDefault(require("image-size"));
|
|
58
|
-
function createErrorResponse(error, operation) {
|
|
58
|
+
function createErrorResponse(error, operation, details) {
|
|
59
59
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
60
60
|
console.error(`[${operation}] Error:`, error);
|
|
61
61
|
return {
|
|
@@ -67,6 +67,7 @@ function createErrorResponse(error, operation) {
|
|
|
67
67
|
error: errorMessage,
|
|
68
68
|
operation,
|
|
69
69
|
timestamp: new Date().toISOString(),
|
|
70
|
+
details,
|
|
70
71
|
}),
|
|
71
72
|
},
|
|
72
73
|
],
|
|
@@ -359,12 +360,11 @@ server.registerTool('retrieve-rules-context', {
|
|
|
359
360
|
purpose: zod_1.z
|
|
360
361
|
.enum([
|
|
361
362
|
'general-video',
|
|
362
|
-
'music-video',
|
|
363
|
-
'stage-play',
|
|
364
363
|
'story-telling',
|
|
365
364
|
'creative-ad',
|
|
366
365
|
'expert',
|
|
367
366
|
'material-creation',
|
|
367
|
+
'anim',
|
|
368
368
|
'freeform',
|
|
369
369
|
'custom',
|
|
370
370
|
])
|
|
@@ -372,12 +372,11 @@ server.registerTool('retrieve-rules-context', {
|
|
|
372
372
|
.describe(`The purpose of the rules context to retrieve.
|
|
373
373
|
|
|
374
374
|
- general-video 创建通用视频
|
|
375
|
-
- music-video 创建音乐视频
|
|
376
|
-
- stage-play 创建舞台播放视频
|
|
377
375
|
- story-telling 创建故事讲述视频
|
|
378
376
|
- creative-ad 创建创意广告视频
|
|
379
377
|
- expert 以专家模式创建视频,必须用户主动要求才触发
|
|
380
378
|
- material-creation 素材创作模式,必须用户主动要求才触发
|
|
379
|
+
- anim 漫剧创作模式,必须用户主动要求才触发
|
|
381
380
|
- freeform 自由创作模式,必须用户主动要求才触发
|
|
382
381
|
- custom 自定义模式`),
|
|
383
382
|
},
|
|
@@ -400,12 +399,11 @@ server.registerTool('retrieve-rules-context', {
|
|
|
400
399
|
// 当 projectRulesFile 不存在时,设置 checkStoryboardSubtitlesFlag 为 false
|
|
401
400
|
checkStoryboardSubtitlesFlag = false;
|
|
402
401
|
if (purpose !== 'general-video' &&
|
|
403
|
-
purpose !== 'music-video' &&
|
|
404
|
-
purpose !== 'stage-play' &&
|
|
405
402
|
purpose !== 'story-telling' &&
|
|
406
403
|
purpose !== 'creative-ad' &&
|
|
407
404
|
purpose !== 'expert' &&
|
|
408
405
|
purpose !== 'material-creation' &&
|
|
406
|
+
purpose !== 'anim' &&
|
|
409
407
|
purpose !== 'freeform') {
|
|
410
408
|
return createErrorResponse(`Project rules file not found: ${projectRulesFile}`, 'retrieve-rules-context');
|
|
411
409
|
}
|
|
@@ -739,7 +737,10 @@ server.registerTool('generate-character-image', {
|
|
|
739
737
|
title: 'Generate Character Image',
|
|
740
738
|
description: 'Generate a turnaround image or portrait for any character.',
|
|
741
739
|
inputSchema: {
|
|
742
|
-
type: zod_1.z
|
|
740
|
+
type: zod_1.z
|
|
741
|
+
.enum(['banana', 'banana-pro', 'seedream'])
|
|
742
|
+
.optional()
|
|
743
|
+
.default('banana'),
|
|
743
744
|
name: zod_1.z.string().describe('The name of the character.'),
|
|
744
745
|
gender: zod_1.z
|
|
745
746
|
.enum(['male', 'female'])
|
|
@@ -1069,7 +1070,10 @@ server.registerTool('generate-image', {
|
|
|
1069
1070
|
title: 'Generate Image',
|
|
1070
1071
|
description: `生成图片`,
|
|
1071
1072
|
inputSchema: {
|
|
1072
|
-
type: zod_1.z
|
|
1073
|
+
type: zod_1.z
|
|
1074
|
+
.enum(['banana', 'banana-pro', 'seedream'])
|
|
1075
|
+
.optional()
|
|
1076
|
+
.default('seedream'),
|
|
1073
1077
|
prompt: zod_1.z
|
|
1074
1078
|
.string()
|
|
1075
1079
|
.describe('The prompt to generate. 一般要严格对应 storyboard 中当前场景的 start_frame 或 end_frame 中的字段描述'),
|
|
@@ -1434,6 +1438,11 @@ server.registerTool('edit-image', {
|
|
|
1434
1438
|
description: 'Edit the image.',
|
|
1435
1439
|
inputSchema: {
|
|
1436
1440
|
prompt: zod_1.z.string().describe('要编辑图片的中文提示词'),
|
|
1441
|
+
type: zod_1.z
|
|
1442
|
+
.enum(['banana-pro', 'banana', 'seedream'])
|
|
1443
|
+
.optional()
|
|
1444
|
+
.default('seedream')
|
|
1445
|
+
.describe('The type of image model to use.'),
|
|
1437
1446
|
sourceImageFileName: zod_1.z.string().describe('The source image file name.'),
|
|
1438
1447
|
saveToFileName: zod_1.z.string().describe('The filename to save.'),
|
|
1439
1448
|
size: zod_1.z
|
|
@@ -1477,7 +1486,7 @@ server.registerTool('edit-image', {
|
|
|
1477
1486
|
.default(false)
|
|
1478
1487
|
.describe('Whether to add watermark to the image.'),
|
|
1479
1488
|
},
|
|
1480
|
-
}, async ({ prompt, sourceImageFileName, saveToFileName, size, watermark }) => {
|
|
1489
|
+
}, async ({ prompt, type, sourceImageFileName, saveToFileName, size, watermark, }) => {
|
|
1481
1490
|
try {
|
|
1482
1491
|
// 验证session状态
|
|
1483
1492
|
const currentSession = await validateSession('edit-image');
|
|
@@ -1503,8 +1512,9 @@ server.registerTool('edit-image', {
|
|
|
1503
1512
|
const base64String = `data:${mimeType};base64,${imageBuffer.toString('base64')}`;
|
|
1504
1513
|
imageBase64Array.push(base64String);
|
|
1505
1514
|
const ai = currentSession.ai;
|
|
1506
|
-
const processedPrompt =
|
|
1515
|
+
const processedPrompt = `转绘我提供的参考图片,${prompt}`;
|
|
1507
1516
|
const res = await ai.generateImage({
|
|
1517
|
+
type,
|
|
1508
1518
|
prompt: processedPrompt,
|
|
1509
1519
|
size,
|
|
1510
1520
|
watermark,
|
|
@@ -2761,7 +2771,9 @@ server.registerTool('get-schema', {
|
|
|
2761
2771
|
title: 'Get Storyboard Schema or Draft Content Schema',
|
|
2762
2772
|
description: 'Get the complete Storyboard or Draft Content JSON Schema definition. Use this schema to validate storyboard.json or draft_content.json files.',
|
|
2763
2773
|
inputSchema: {
|
|
2764
|
-
type: zod_1.z
|
|
2774
|
+
type: zod_1.z
|
|
2775
|
+
.enum(['storyboard', 'draft_content'])
|
|
2776
|
+
.describe('The type of schema to retrieve. Must be either "storyboard" or "draft_content". 用 type: storyboard 的 schema 生成 storyboard.json;用 type: draft_content 的 schema 生成 draft_content.json'),
|
|
2765
2777
|
},
|
|
2766
2778
|
}, async ({ type }) => {
|
|
2767
2779
|
try {
|
|
@@ -2795,34 +2807,6 @@ server.registerTool('get-schema', {
|
|
|
2795
2807
|
return createErrorResponse(error, 'get-schema');
|
|
2796
2808
|
}
|
|
2797
2809
|
});
|
|
2798
|
-
server.registerTool('do-storyboard-optimization', {
|
|
2799
|
-
title: 'Do Storyboard Optimization',
|
|
2800
|
-
description: 'Get storyboard optimization guidelines and action instructions.',
|
|
2801
|
-
inputSchema: {},
|
|
2802
|
-
}, async () => {
|
|
2803
|
-
try {
|
|
2804
|
-
// 调用 do-storyboard-optimization 工具时,设置 checkStoryboardFlag 为 true
|
|
2805
|
-
checkStoryboardFlag = true;
|
|
2806
|
-
const guidelinePath = (0, node_path_1.resolve)(__dirname, './prompts/actions/storyboard_optimization.md');
|
|
2807
|
-
const storyboardOptimizationGuidelines = await (0, promises_1.readFile)(guidelinePath, 'utf-8');
|
|
2808
|
-
return {
|
|
2809
|
-
content: [
|
|
2810
|
-
{
|
|
2811
|
-
type: 'text',
|
|
2812
|
-
text: JSON.stringify({
|
|
2813
|
-
content: {
|
|
2814
|
-
guideline: storyboardOptimizationGuidelines,
|
|
2815
|
-
action: '你应当根据guideline优化storyboard.json',
|
|
2816
|
-
},
|
|
2817
|
-
}),
|
|
2818
|
-
},
|
|
2819
|
-
],
|
|
2820
|
-
};
|
|
2821
|
-
}
|
|
2822
|
-
catch (error) {
|
|
2823
|
-
return createErrorResponse(error, 'do-storyboard-optimization');
|
|
2824
|
-
}
|
|
2825
|
-
});
|
|
2826
2810
|
server.registerTool('search-voices', {
|
|
2827
2811
|
title: 'Search Voices',
|
|
2828
2812
|
description: 'Search voices from doubao_voices_full based on scenes, emotions, languages, and gender.',
|
|
@@ -3401,7 +3385,11 @@ server.registerTool('audio-video-sync', {
|
|
|
3401
3385
|
description: 'Generate audio-video-synced video by matching video with audio. 还可以对口型。',
|
|
3402
3386
|
inputSchema: {
|
|
3403
3387
|
lipSync: zod_1.z.boolean().default(false),
|
|
3404
|
-
lipSyncType: zod_1.z
|
|
3388
|
+
lipSyncType: zod_1.z
|
|
3389
|
+
.enum(['pixv', 'vidu', 'basic', 'lite'])
|
|
3390
|
+
.optional()
|
|
3391
|
+
.default('pixv'),
|
|
3392
|
+
lipSyncPadAudio: zod_1.z.boolean().optional().default(true),
|
|
3405
3393
|
videoFileName: zod_1.z
|
|
3406
3394
|
.string()
|
|
3407
3395
|
.describe('The video file name in materials directory.'),
|
|
@@ -3420,7 +3408,7 @@ server.registerTool('audio-video-sync', {
|
|
|
3420
3408
|
.string()
|
|
3421
3409
|
.describe('The filename to save the audio-video-synced video.'),
|
|
3422
3410
|
},
|
|
3423
|
-
}, async ({ lipSync, lipSyncType, videoFileName, audioFileName, audioInMs, refPhotoFileName, saveToFileName, }, context) => {
|
|
3411
|
+
}, async ({ lipSync, lipSyncType, lipSyncPadAudio, videoFileName, audioFileName, audioInMs, refPhotoFileName, saveToFileName, }, context) => {
|
|
3424
3412
|
try {
|
|
3425
3413
|
// 验证session状态
|
|
3426
3414
|
const currentSession = await validateSession('audio-video-sync');
|
|
@@ -3492,6 +3480,7 @@ server.registerTool('audio-video-sync', {
|
|
|
3492
3480
|
audioUrl,
|
|
3493
3481
|
audioInMs,
|
|
3494
3482
|
ref_photo_url: refPhotoUrl,
|
|
3483
|
+
pad_audio: lipSyncPadAudio,
|
|
3495
3484
|
onProgress: async (metaData) => {
|
|
3496
3485
|
console.log('Lip sync progress:', metaData);
|
|
3497
3486
|
try {
|
|
@@ -3551,6 +3540,11 @@ server.registerTool('generate-video-by-ref', {
|
|
|
3551
3540
|
prompt: zod_1.z
|
|
3552
3541
|
.string()
|
|
3553
3542
|
.describe('The prompt to generate video with or without reference images.'),
|
|
3543
|
+
rewritePrompt: zod_1.z
|
|
3544
|
+
.boolean()
|
|
3545
|
+
.optional()
|
|
3546
|
+
.default(true)
|
|
3547
|
+
.describe('Whether to rewrite the prompt.'),
|
|
3554
3548
|
referenceImages: zod_1.z
|
|
3555
3549
|
.array(zod_1.z.object({
|
|
3556
3550
|
name: zod_1.z
|
|
@@ -3571,7 +3565,12 @@ server.registerTool('generate-video-by-ref', {
|
|
|
3571
3565
|
.optional()
|
|
3572
3566
|
.default(5)
|
|
3573
3567
|
.describe('The duration of the video in seconds.'),
|
|
3574
|
-
|
|
3568
|
+
aspectRatio: zod_1.z
|
|
3569
|
+
.enum(['16:9', '9:16'])
|
|
3570
|
+
.describe('The aspect ratio of the video.'),
|
|
3571
|
+
resolution: zod_1.z
|
|
3572
|
+
.enum(['720p', '1080p'])
|
|
3573
|
+
.describe('The resolution of the video.'),
|
|
3575
3574
|
watermark: zod_1.z
|
|
3576
3575
|
.boolean()
|
|
3577
3576
|
.optional()
|
|
@@ -3614,7 +3613,7 @@ server.registerTool('generate-video-by-ref', {
|
|
|
3614
3613
|
.default(false)
|
|
3615
3614
|
.describe('Whether to optimize the prompt.'),
|
|
3616
3615
|
},
|
|
3617
|
-
}, async ({ prompt, referenceImages, duration,
|
|
3616
|
+
}, async ({ prompt, rewritePrompt, referenceImages, duration, aspectRatio, resolution, watermark, type, mute, saveToFileName, sceneIndex, storyBoardFile, skipConsistencyCheck, optimizePrompt, }, context) => {
|
|
3618
3617
|
try {
|
|
3619
3618
|
// 验证session状态
|
|
3620
3619
|
const currentSession = await validateSession('generate-video-by-ref');
|
|
@@ -3656,6 +3655,9 @@ server.registerTool('generate-video-by-ref', {
|
|
|
3656
3655
|
if (scene.is_continuous === true) {
|
|
3657
3656
|
return createErrorResponse('连续镜头应使用首尾帧,请修改连续镜头设置,或将本场景改为首尾帧方式实现', 'generate-video-by-ref');
|
|
3658
3657
|
}
|
|
3658
|
+
if (scene.video_type !== 'references') {
|
|
3659
|
+
return createErrorResponse(`场景 ${sceneIndex} 中的 video_type (${scene.video_type}) 未设置为 'references',不应当使用参考生视频,请使用图生视频 generate-video 方式生成`, 'generate-video-by-ref');
|
|
3660
|
+
}
|
|
3659
3661
|
// 检查 use_video_model 与 type 参数的一致性
|
|
3660
3662
|
if (scene.use_video_model &&
|
|
3661
3663
|
type &&
|
|
@@ -3704,15 +3706,15 @@ server.registerTool('generate-video-by-ref', {
|
|
|
3704
3706
|
}
|
|
3705
3707
|
// 检查 storyBoard.orientation 与 size 参数的一致性
|
|
3706
3708
|
if (storyBoard.orientation) {
|
|
3707
|
-
const isLandscapeSize =
|
|
3708
|
-
const isPortraitSize =
|
|
3709
|
+
const isLandscapeSize = aspectRatio === '16:9';
|
|
3710
|
+
const isPortraitSize = aspectRatio === '9:16';
|
|
3709
3711
|
if (storyBoard.orientation === 'landscape' &&
|
|
3710
3712
|
!isLandscapeSize) {
|
|
3711
|
-
return createErrorResponse(`故事板设定为横屏模式(orientation: landscape)
|
|
3713
|
+
return createErrorResponse(`故事板设定为横屏模式(orientation: landscape),但视频为竖屏格式,请使用横屏尺寸 1280x720`, 'generate-video-by-ref');
|
|
3712
3714
|
}
|
|
3713
3715
|
if (storyBoard.orientation === 'portrait' &&
|
|
3714
3716
|
!isPortraitSize) {
|
|
3715
|
-
return createErrorResponse(`故事板设定为竖屏模式(orientation: portrait)
|
|
3717
|
+
return createErrorResponse(`故事板设定为竖屏模式(orientation: portrait),但视频为横屏格式,请使用竖屏尺寸 720x1280`, 'generate-video-by-ref');
|
|
3716
3718
|
}
|
|
3717
3719
|
}
|
|
3718
3720
|
}
|
|
@@ -3781,17 +3783,21 @@ server.registerTool('generate-video-by-ref', {
|
|
|
3781
3783
|
url: imageUrl,
|
|
3782
3784
|
});
|
|
3783
3785
|
console.log(`Added reference image URL: ${imageUrl} (name: ${imageRef.name}, type: ${imageRef.type})`);
|
|
3784
|
-
|
|
3786
|
+
if (rewritePrompt) {
|
|
3787
|
+
promptPrefix += `参考“${imageRef.name}”(图${referenceImageUrls.length})${imageRef.type === 'subject' ? '主体形象' : '背景'}\n`;
|
|
3788
|
+
}
|
|
3785
3789
|
}
|
|
3786
3790
|
if (promptPrefix) {
|
|
3787
3791
|
promptPrefix += '\n';
|
|
3788
3792
|
}
|
|
3793
|
+
const finalPrompt = `${promptPrefix}${prompt}`;
|
|
3789
3794
|
// 调用 referencesToVideo 函数
|
|
3790
3795
|
const result = await currentSession.ai.referencesToVideo({
|
|
3791
|
-
prompt:
|
|
3796
|
+
prompt: finalPrompt,
|
|
3792
3797
|
reference_images: referenceImageUrls, // 使用URL数组而不是base64数组
|
|
3793
3798
|
duration,
|
|
3794
|
-
|
|
3799
|
+
aspect_ratio: aspectRatio,
|
|
3800
|
+
resolution,
|
|
3795
3801
|
watermark,
|
|
3796
3802
|
type,
|
|
3797
3803
|
mute,
|
|
@@ -3803,9 +3809,23 @@ server.registerTool('generate-video-by-ref', {
|
|
|
3803
3809
|
if (result.error) {
|
|
3804
3810
|
return createErrorResponse(result.error, 'generate-video-by-ref');
|
|
3805
3811
|
}
|
|
3806
|
-
if (!result.url) {
|
|
3812
|
+
if (!result.url && !result.taskUrl) {
|
|
3807
3813
|
return createErrorResponse('Video generation failed: no video URL returned', 'generate-video-by-ref');
|
|
3808
3814
|
}
|
|
3815
|
+
else if (result.taskUrl) {
|
|
3816
|
+
return {
|
|
3817
|
+
content: [
|
|
3818
|
+
{
|
|
3819
|
+
type: 'text',
|
|
3820
|
+
text: JSON.stringify({
|
|
3821
|
+
success: true,
|
|
3822
|
+
message: '该视频生成任务正在运行中,它是异步任务,且执行时间较长,你应立即调用工具 wait-for-task-finish 来等待任务结束,如该工具调用超时,你应立即再次重新调用直到任务结束。',
|
|
3823
|
+
taskUrl: result.taskUrl,
|
|
3824
|
+
}),
|
|
3825
|
+
},
|
|
3826
|
+
],
|
|
3827
|
+
};
|
|
3828
|
+
}
|
|
3809
3829
|
// 下载生成的视频
|
|
3810
3830
|
await saveMaterial(currentSession, result.url, validatedFileName);
|
|
3811
3831
|
// 更新媒体日志
|
|
@@ -3831,6 +3851,8 @@ server.registerTool('generate-video-by-ref', {
|
|
|
3831
3851
|
ratio: result.ratio,
|
|
3832
3852
|
url: result.url,
|
|
3833
3853
|
last_frame_url: result.last_frame_url,
|
|
3854
|
+
referenceImageUrls,
|
|
3855
|
+
prompt: finalPrompt,
|
|
3834
3856
|
}, null, 2),
|
|
3835
3857
|
},
|
|
3836
3858
|
],
|
|
@@ -3854,6 +3876,10 @@ server.registerTool('extend-video-duration', {
|
|
|
3854
3876
|
.max(7)
|
|
3855
3877
|
.default(3)
|
|
3856
3878
|
.describe('Duration to extend the video in seconds (1-7).'),
|
|
3879
|
+
resolution: zod_1.z
|
|
3880
|
+
.enum(['720p', '1080p'])
|
|
3881
|
+
.default('720p')
|
|
3882
|
+
.describe('The resolution of the video.'),
|
|
3857
3883
|
prompt: zod_1.z
|
|
3858
3884
|
.string()
|
|
3859
3885
|
.optional()
|
|
@@ -3870,7 +3896,7 @@ server.registerTool('extend-video-duration', {
|
|
|
3870
3896
|
.string()
|
|
3871
3897
|
.describe('The filename to save the extended video.'),
|
|
3872
3898
|
},
|
|
3873
|
-
}, async ({ videoFileName, duration, prompt, type = 'turbo', endFrame, saveToFileName, }, context) => {
|
|
3899
|
+
}, async ({ videoFileName, duration, resolution, prompt, type = 'turbo', endFrame, saveToFileName, }, context) => {
|
|
3874
3900
|
try {
|
|
3875
3901
|
await validateSession('extend-video');
|
|
3876
3902
|
validateFileName(videoFileName);
|
|
@@ -3899,6 +3925,7 @@ server.registerTool('extend-video-duration', {
|
|
|
3899
3925
|
video_url: videoUri,
|
|
3900
3926
|
prompt: finalPrompt,
|
|
3901
3927
|
duration,
|
|
3928
|
+
resolution,
|
|
3902
3929
|
end_frame: endFrameUri,
|
|
3903
3930
|
onProgress: async (metaData) => {
|
|
3904
3931
|
sendProgress(context, ++progress, undefined, `Extension progress: ${Math.round(progress * 100)}%`);
|
|
@@ -3952,49 +3979,46 @@ server.registerTool('extend-video-duration', {
|
|
|
3952
3979
|
return createErrorResponse(error, 'extend-video');
|
|
3953
3980
|
}
|
|
3954
3981
|
});
|
|
3955
|
-
server.registerTool('
|
|
3956
|
-
title: '
|
|
3957
|
-
description: '
|
|
3982
|
+
server.registerTool('use-template', {
|
|
3983
|
+
title: 'Use Template',
|
|
3984
|
+
description: 'Find a template that matches the user request, and use it to generate a new material.',
|
|
3958
3985
|
inputSchema: {
|
|
3959
|
-
|
|
3960
|
-
.string()
|
|
3961
|
-
.describe('The prompt to generate the video. 自动根据意图匹配模板'),
|
|
3962
|
-
text_prompts: zod_1.z
|
|
3963
|
-
.array(zod_1.z.string().describe('Text prompt for the template to build video.'))
|
|
3964
|
-
.optional()
|
|
3965
|
-
.describe('Optional text prompts to use in the template.'),
|
|
3986
|
+
user_request: zod_1.z.string().describe('用户请求,根据意图自动匹配模板'),
|
|
3966
3987
|
materials: zod_1.z
|
|
3967
3988
|
.array(zod_1.z.string().describe('Material file name in materials directory.'))
|
|
3968
3989
|
.optional()
|
|
3969
3990
|
.describe('Optional materials to use in the template.'),
|
|
3970
3991
|
saveToFileName: zod_1.z
|
|
3971
3992
|
.string()
|
|
3972
|
-
.describe('The filename to save the generated
|
|
3993
|
+
.describe('The filename to save the generated material.'),
|
|
3973
3994
|
},
|
|
3974
|
-
}, async ({
|
|
3995
|
+
}, async ({ user_request, saveToFileName, materials }) => {
|
|
3975
3996
|
try {
|
|
3976
|
-
const templates = {
|
|
3977
|
-
'7569583728302817331': '宠物唱歌',
|
|
3978
|
-
'7569605825011367976': '万圣节宠物弹吉他',
|
|
3979
|
-
};
|
|
3980
3997
|
const currentSession = await validateSession('generate-video-by-template');
|
|
3981
|
-
const validatedFileName = validateFileName(saveToFileName);
|
|
3982
3998
|
const ai = currentSession.ai;
|
|
3999
|
+
const data = await ai.listTemplates('all');
|
|
4000
|
+
const templates = data.map(item => ({
|
|
4001
|
+
id: item.workflow_id,
|
|
4002
|
+
name: item.details.name,
|
|
4003
|
+
description: item.details.description,
|
|
4004
|
+
trigger: item.details.trigger,
|
|
4005
|
+
}));
|
|
4006
|
+
const validatedFileName = validateFileName(saveToFileName);
|
|
3983
4007
|
let completion = await ai.getCompletions({
|
|
3984
|
-
model: 'Doubao-Seed-1.6
|
|
4008
|
+
model: 'Doubao-Seed-1.6',
|
|
3985
4009
|
messages: [
|
|
3986
4010
|
{
|
|
3987
4011
|
role: 'system',
|
|
3988
|
-
content: `你根据用户需求,从以下模板中选择一个匹配的模板,返回模板ID:\n\n${JSON.stringify(templates)}\n\n**约束**:只输出模板ID
|
|
4012
|
+
content: `你根据用户需求,从以下模板中选择一个匹配的模板,返回模板ID:\n\n${JSON.stringify(templates)}\n\n**约束**:只输出模板ID,不需要其他解释,如果没有匹配的模版,输出"无匹配模版"`,
|
|
3989
4013
|
},
|
|
3990
4014
|
{
|
|
3991
4015
|
role: 'user',
|
|
3992
|
-
content:
|
|
4016
|
+
content: user_request,
|
|
3993
4017
|
},
|
|
3994
4018
|
],
|
|
3995
4019
|
});
|
|
3996
4020
|
const templateId = completion.choices[0]?.message?.content.trim();
|
|
3997
|
-
if (!templateId) {
|
|
4021
|
+
if (!templateId || templateId === '无匹配模版') {
|
|
3998
4022
|
throw new Error('Failed to get template ID');
|
|
3999
4023
|
}
|
|
4000
4024
|
const workflowInfo = await ai.getCozeWorkflowInfo(templateId);
|
|
@@ -4012,16 +4036,17 @@ server.registerTool('generate-video-by-template', {
|
|
|
4012
4036
|
required: ['parameters'],
|
|
4013
4037
|
},
|
|
4014
4038
|
};
|
|
4015
|
-
const prompt =
|
|
4039
|
+
const prompt = `你根据模板工作流描述中的 input_schema、用户需求 prompt 和 materials 生成一个 JSON 对象,作为模板工作流的调用参数。
|
|
4016
4040
|
|
|
4017
|
-
##
|
|
4018
|
-
${
|
|
4041
|
+
## **工作流描述**:
|
|
4042
|
+
${workflowInfo.data.workflow_detail.description}
|
|
4019
4043
|
|
|
4020
|
-
##
|
|
4021
|
-
${
|
|
4044
|
+
## **用户需求 prompt**:
|
|
4045
|
+
${user_request}
|
|
4022
4046
|
|
|
4023
4047
|
## **materials**:
|
|
4024
4048
|
${JSON.stringify(materialUrls)}`;
|
|
4049
|
+
// console.log(prompt);
|
|
4025
4050
|
completion = await ai.getCompletions({
|
|
4026
4051
|
model: 'Doubao-Seed-1.6-flash',
|
|
4027
4052
|
messages: [
|
|
@@ -4043,7 +4068,6 @@ ${JSON.stringify(materialUrls)}`;
|
|
|
4043
4068
|
if (!parameters) {
|
|
4044
4069
|
throw new Error('Failed to get parameters');
|
|
4045
4070
|
}
|
|
4046
|
-
console.log(parameters);
|
|
4047
4071
|
const result = await ai.runCozeWorkflow(templateId, JSON.parse(parameters).parameters);
|
|
4048
4072
|
if (result.url) {
|
|
4049
4073
|
// 保存到项目材料目录
|
|
@@ -4075,7 +4099,7 @@ ${JSON.stringify(materialUrls)}`;
|
|
|
4075
4099
|
};
|
|
4076
4100
|
}
|
|
4077
4101
|
catch (error) {
|
|
4078
|
-
return createErrorResponse(error, '
|
|
4102
|
+
return createErrorResponse(error, 'use-template');
|
|
4079
4103
|
}
|
|
4080
4104
|
});
|
|
4081
4105
|
server.registerTool('run-ffmpeg-command', {
|
|
@@ -4172,6 +4196,34 @@ server.registerTool('run-ffmpeg-command', {
|
|
|
4172
4196
|
return createErrorResponse(error, 'run-ffmpeg-command');
|
|
4173
4197
|
}
|
|
4174
4198
|
});
|
|
4199
|
+
server.registerTool('do-storyboard-optimization', {
|
|
4200
|
+
title: 'Do Storyboard Optimization',
|
|
4201
|
+
description: 'Get storyboard optimization guidelines and action instructions.',
|
|
4202
|
+
inputSchema: {},
|
|
4203
|
+
}, async () => {
|
|
4204
|
+
try {
|
|
4205
|
+
// 调用 do-storyboard-optimization 工具时,设置 checkStoryboardFlag 为 true
|
|
4206
|
+
checkStoryboardFlag = true;
|
|
4207
|
+
const guidelinePath = (0, node_path_1.resolve)(__dirname, './prompts/actions/storyboard_optimization.md');
|
|
4208
|
+
const storyboardOptimizationGuidelines = await (0, promises_1.readFile)(guidelinePath, 'utf-8');
|
|
4209
|
+
return {
|
|
4210
|
+
content: [
|
|
4211
|
+
{
|
|
4212
|
+
type: 'text',
|
|
4213
|
+
text: JSON.stringify({
|
|
4214
|
+
content: {
|
|
4215
|
+
guideline: storyboardOptimizationGuidelines,
|
|
4216
|
+
action: '你应当根据guideline优化storyboard.json',
|
|
4217
|
+
},
|
|
4218
|
+
}),
|
|
4219
|
+
},
|
|
4220
|
+
],
|
|
4221
|
+
};
|
|
4222
|
+
}
|
|
4223
|
+
catch (error) {
|
|
4224
|
+
return createErrorResponse(error, 'do-storyboard-optimization');
|
|
4225
|
+
}
|
|
4226
|
+
});
|
|
4175
4227
|
server.registerTool('search-context', {
|
|
4176
4228
|
title: 'Search Context',
|
|
4177
4229
|
description: 'Search the context.',
|