cerevox 4.35.0 → 4.37.0

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.
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: 一键成片
3
+ description: 当用户要求创作某个主题的通用视频时,使用该技能,通过Zerocut MCP工具,根据用户需求创作多个分镜并合成通用视频
4
+ ---
5
+ ## 标准流水线
6
+
7
+ ### 全局配置和注意事项
8
+
9
+ 1. 音画同步:除非用户明确指定,否则生成视频时一律**不静音**(默认`silent=false`)
10
+ 2. 一致性检查
11
+ - ‼️ 除非用户明确要求不传,否则为分镜生成图(generate-image)和视频(generate-video)时,都务必传 `sceneIndex` 参数,从 1 开始编号
12
+ 3. 分镜自动化:在第一次创建视频时,根据用户需求,使用`generate-video-outlines`生成分镜草稿 storyboard.json,生成后直接使用,不需要进行任何修改。
13
+ 4. 故障排查和自动处理
14
+ - 一般的错误,除非用户明确许可,否则禁止自行跳过一致性检查,而是修改 storyboard.json 中的相关内容,以保持一致性
15
+ 5. 优先用 `audio-video-sync` 工具而**不是** `run-ffmpeg-command` 工具合成视频
16
+ 6. 调用 `audio-video-sync` 合成视频时,如有对话或旁白,同步合成字幕(参数`addSubtitles=true`)
17
+ 7. 在执行任务的过程中,任何工具返回`Not enough credits`错误时,必须暂停任务,等待用户充值后由用户手动触发继续执行
18
+
19
+ ### 新建
20
+
21
+ 1. 确保项目已正确开启:`project-open` 已被调用
22
+ 2. 使用`retrieve-rules-context`,召回规则上下文
23
+ 3. 分镜创作:根据用户需求,使用`generate-video-outlines`生成分镜草稿 storyboard.json
24
+ * 使用`generate-video-outlines`时,prompt 请直接转述用户描述,无需自行分析整理或创作
25
+ 4. 使用 `generate-image` 生成各分镜图片
26
+ - 生成图片时,除非用户人为指定,否则优先使用`seedream-5l`模型
27
+ - 生成图片时,必须用`referenceImages`参数引用`outline_sheet.png`这张图,这张图已经由`generate-video-outlines`生成
28
+ - 引用 `outline_sheet.png` 时,参考图片的类型(type)为 `normal`
29
+ - 生成图片时,必须用`sceneIndex`参数指定分镜编号,从 1 开始编号
30
+ 5. 使用 `generate-video` 生成各分镜视频
31
+ - 生成视频时,必须用`sceneIndex`参数指定分镜编号,从 1 开始编号
32
+ - 生成视频时,一律采用**首帧图生视频**(即参考图的 type 为 `first_frame`)
33
+ - 生成视频时,必须带声音(参数`silent=false`)
34
+ - 如分镜有旁白(narration),生成视频时必须带旁白(参数`narration={text, tone, voice_id}`)
35
+ 6. 使用 `generate-music` 生成背景音乐
36
+ - 背景音乐时长为分镜视频总时长,若不足30秒应补足30秒
37
+ 7. 合成视频:调用`audio-video-sync`输出视频并根据情况合成字幕(参数`addSubtitles=true`),自动下载到本地
38
+ - 视频如有对话或旁白,务必在调用`audio-video-sync`时设置参数`addSubtitles=true`,否则无需设置
39
+ 8. 关闭项目 → `project-close`
40
+
41
+ ### 修改
42
+
43
+ 1. 确保项目已启动 → `project-open`
44
+ 2. 修改脚本 → 按用户要求直接手动修改 storyboard.json (⚠️ 不再使用`generate-video-outlines`重新生成)
45
+ 3. 更新素材 → 重新生成需要修改的素材
46
+ 4. 重新合成视频 → `audio-video-sync` 输出视频并合成字幕(参数`addSubtitles=true`),自动下载到本地
47
+ 5. 关闭项目 → `project-close`
48
+
49
+ ---
50
+
51
+ ## 主体参考图
52
+ * 如需保持主体形象一致,你可以先用`generate-image`生成主体参考三视图,然后参考三视图创建分镜草稿 storyboard.json
53
+
54
+ ---
55
+
56
+ ## 质量建议
57
+
58
+ ### materials 资源命名规范
59
+
60
+ - 场景素材:`sc01_first_frame.png`、`sc01_motion.mp4`、`sc01_vo.mp3`
61
+ - 通用素材:`main_bgm_60s.mp3`
62
+ - 合成视频:`<主题名>.v<版本>.mp4`
63
+
64
+ ### 工作流管理
65
+ * 规划先行:先分析制定执行计划
66
+ * 工作流顺序:规划→搜索→分镜→图片→视频→BGM→合成视频
67
+ * 视频生成策略:
68
+ - 先使用`generate-image`生成首帧图片
69
+ - 再使用`generate-video`生成动态视频
70
+ * 统一命名:`scXX_*`、`main_bgm_*`、`*_vo.*`
71
+ * 时长控制:单镜头3-16s
72
+
73
+ ### 图生视频技巧
74
+ * 运动导向:提示词=主体运动+背景变化+镜头运动
75
+ * 特征定位:突出主体特征(老人、戴墨镜的女人)便于识别
76
+ * 环境一致性:确保场景间环境元素一致
77
+ - 时间:保持时间段一致(白天、夜晚),避免无故突变
78
+ - 天气:保持天气状况一致(晴天、雨天)
79
+ - 地点:场景转换符合空间逻辑
80
+ - 光线:保持光源方向和强度一致
81
+
82
+ ### BGM 音量控制
83
+ * 音量:默认BGM音量控制为-15db(`audioVolume=0.177`),通过设置`audio-video-async`的`audioVolume`参数可以调整BGM音量。
84
+
85
+ ---
86
+
87
+ ## 规划与搜索规则
88
+
89
+ ### 需求分析
90
+ - 理解核心需求:明确视频主题、目标受众、预期效果
91
+ - 确定视频类型:科普解说、产品介绍、故事叙述等
92
+ - 分析技术要求:视频时长、画幅比例、风格偏好
93
+ - 识别素材需求:需要的图片、视频、音频素材
94
+
95
+ ### 搜索内容
96
+ - 特定领域知识、热点话题、视觉参考、事实验证
97
+
98
+ ---
99
+
100
+ ## 故障排查
101
+
102
+ * `generate-video` 失败且失败原因是内容相关(如包含敏感信息)
103
+ - **禁止**轻易重新生成 outline,应手动编辑 `storyboard.json` 中的 video_prompt 删除或修改可能的敏感信息后重试;若还是失败,停下来询问用户如何处理
@@ -1 +1 @@
1
- {"version":3,"file":"zerocut.d.ts","sourceRoot":"","sources":["../../../src/mcp/servers/zerocut.ts"],"names":[],"mappings":";AAumGA,wBAAsB,GAAG,kBAKxB"}
1
+ {"version":3,"file":"zerocut.d.ts","sourceRoot":"","sources":["../../../src/mcp/servers/zerocut.ts"],"names":[],"mappings":";AAwmGA,wBAAsB,GAAG,kBAKxB"}
@@ -1042,143 +1042,180 @@ server.registerTool('generate-image', {
1042
1042
  return createErrorResponse(error, 'generate-image');
1043
1043
  }
1044
1044
  });
1045
- server.registerTool('generate-video-outlines', {
1046
- title: 'Generate Video Outlines',
1047
- description: `根据用户描述生成短视频的大纲;执行本工具会自动创建两个文件,一个是storyboard.json,一个是outline_sheet.png,前者是分镜设置,后者是分镜宫格图,其中outline_sheet.png生成于materials目录下,storyboard.json生成于materials的上级目录。`,
1048
- inputSchema: {
1049
- prompt: zod_1.z
1050
- .string()
1051
- .describe('⚠️你只须如实转述用户需求中有关分镜大纲的内容以及分镜数量和横竖屏设置,忽略其他无关内容,无需自行分析整理或加工,本工具会智能创作;'),
1052
- voiceType: zod_1.z
1053
- .enum(['slient', 'voiceover', 'dialogue'])
1054
- .optional()
1055
- .default('voiceover')
1056
- .describe(`语音类型,枚举:
1057
- - slient:视频只有BGM和音效,无任何语音
1058
- - voiceover:视频只有画外音,无任何对话
1059
- - dialogue:视频既有画外音,也有对话`),
1060
- language: zod_1.z.string().optional().default('中文').describe('语言'),
1061
- referenceImages: zod_1.z.array(zod_1.z.object({
1062
- name: zod_1.z.string().describe('图片名称,人物名、图片背景名或物品名'),
1063
- fileName: zod_1.z.string().describe('Reference image file name'),
1064
- })),
1065
- orientation: zod_1.z
1066
- .enum(['portrait', 'landscape'])
1067
- .optional()
1068
- .default('portrait')
1069
- .describe('视频方向,枚举:竖屏(portrait)、横屏(landscape)'),
1070
- model: zod_1.z
1071
- .enum([
1072
- 'seedance-1.5-pro',
1073
- 'vidu',
1074
- 'viduq2',
1075
- 'vidu-turbo',
1076
- 'vidu-pro',
1077
- 'kling',
1078
- 'wan-flash',
1079
- ])
1080
- .default('seedance-1.5-pro')
1081
- .describe('除非用户主动提出使用其他模型,否则一律用seedance-1.5-pro模型'),
1082
- },
1083
- }, async ({ prompt, voiceType, language, referenceImages, orientation, model }, context) => {
1084
- try {
1085
- // 验证session状态
1086
- const currentSession = await validateSession('generate-video-outlines');
1087
- let progress = 0;
1088
- const ai = currentSession.ai;
1089
- let images;
1090
- if (referenceImages) {
1091
- images = await Promise.all(referenceImages.map(async (image) => await getMaterialUri(currentSession, image.fileName, {
1092
- fileSizeLimit: 10,
1093
- })));
1094
- }
1095
- const res = await ai.generateShortVideoOutlines({
1096
- prompt,
1097
- voiceType,
1098
- language,
1099
- images,
1100
- videoModel: model,
1101
- aspectRatio: orientation === 'portrait' ? '9:16' : '16:9',
1102
- onProgress: async (metaData) => {
1103
- try {
1104
- await sendProgress(context, ++progress, undefined, JSON.stringify(metaData));
1105
- }
1106
- catch (progressError) {
1107
- console.warn('Failed to send progress update:', progressError);
1108
- }
1109
- },
1110
- });
1111
- if (!res) {
1112
- throw new Error('Failed to generate short video outlines: no response from AI service');
1113
- }
1114
- if (res.taskUrl) {
1115
- return {
1116
- content: [
1117
- {
1118
- type: 'text',
1119
- text: JSON.stringify({
1120
- success: true,
1121
- message: '该任务正在运行中,它是异步任务,且执行时间较长,你应立即调用工具 wait-for-task-finish (saveFileName=outline_sheet.png) 来等待任务结束,如 wait-for-task-finish 工具调用超时,你应立即再次重新调用直到任务结束。',
1122
- taskUrl: res.taskUrl,
1123
- }),
1124
- },
1125
- ],
1126
- };
1127
- }
1128
- else if (res.url) {
1129
- const url = res.url;
1130
- const { savedTo } = await saveMaterial(currentSession, url, 'outline_sheet.png');
1131
- const { scenes, video_type, voice_type, voiceover_tone, voice_id, bgm_prompt, video_model, } = res.data || {};
1132
- const seed = (0, seed_1.getRandomSeed)();
1133
- const storyboard = {
1134
- orientation,
1135
- video_type,
1136
- outline_sheet: savedTo,
1137
- bgm_prompt,
1138
- voice_type,
1139
- scenes: scenes.map((scene) => {
1140
- return {
1141
- ...scene,
1142
- narration_tone: voiceover_tone,
1143
- narration_voice_id: voice_id,
1144
- use_video_model: video_model,
1145
- seed,
1146
- };
1147
- }),
1148
- };
1149
- const saveLocalPath = (0, node_path_1.resolve)(projectLocalDir, 'storyboard.json');
1150
- await (0, promises_1.writeFile)(saveLocalPath, JSON.stringify(storyboard, null, 2));
1151
- return {
1152
- content: [
1153
- {
1154
- type: 'text',
1155
- text: JSON.stringify({
1156
- success: true,
1157
- message: '视频大纲生成成功',
1158
- storyboard,
1159
- }),
1160
- },
1161
- ],
1162
- };
1163
- }
1164
- return {
1165
- content: [
1166
- {
1167
- type: 'text',
1168
- text: JSON.stringify({
1169
- success: false,
1170
- error: 'No image URL returned from AI service',
1171
- response: res,
1172
- timestamp: new Date().toISOString(),
1173
- }),
1174
- },
1175
- ],
1176
- };
1177
- }
1178
- catch (error) {
1179
- return createErrorResponse(error, 'generate-video-outlines');
1180
- }
1181
- });
1045
+ // server.registerTool(
1046
+ // 'generate-video-outlines',
1047
+ // {
1048
+ // title: 'Generate Video Outlines',
1049
+ // description: `根据用户描述生成短视频的大纲;执行本工具会自动创建两个文件,一个是storyboard.json,一个是outline_sheet.png,前者是分镜设置,后者是分镜宫格图,其中outline_sheet.png生成于materials目录下,storyboard.json生成于materials的上级目录。`,
1050
+ // inputSchema: {
1051
+ // prompt: z
1052
+ // .string()
1053
+ // .describe(
1054
+ // '⚠️你只须如实转述用户需求中有关分镜大纲的内容以及分镜数量和横竖屏设置,忽略其他无关内容,无需自行分析整理或加工,本工具会智能创作;'
1055
+ // ),
1056
+ // voiceType: z
1057
+ // .enum(['slient', 'voiceover', 'dialogue'])
1058
+ // .optional()
1059
+ // .default('voiceover')
1060
+ // .describe(
1061
+ // `语音类型,枚举:
1062
+ // - slient:视频只有BGM和音效,无任何语音
1063
+ // - voiceover:视频只有画外音,无任何对话
1064
+ // - dialogue:视频既有画外音,也有对话`
1065
+ // ),
1066
+ // language: z.string().optional().default('中文').describe('语言'),
1067
+ // referenceImages: z.array(
1068
+ // z.object({
1069
+ // name: z.string().describe('图片名称,人物名、图片背景名或物品名'),
1070
+ // fileName: z.string().describe('Reference image file name'),
1071
+ // })
1072
+ // ),
1073
+ // orientation: z
1074
+ // .enum(['portrait', 'landscape'])
1075
+ // .optional()
1076
+ // .default('portrait')
1077
+ // .describe('视频方向,枚举:竖屏(portrait)、横屏(landscape)'),
1078
+ // model: z
1079
+ // .enum([
1080
+ // 'seedance-1.5-pro',
1081
+ // 'vidu',
1082
+ // 'viduq2',
1083
+ // 'vidu-turbo',
1084
+ // 'vidu-pro',
1085
+ // 'kling',
1086
+ // 'wan-flash',
1087
+ // ])
1088
+ // .default('seedance-1.5-pro')
1089
+ // .describe(
1090
+ // '除非用户主动提出使用其他模型,否则一律用seedance-1.5-pro模型'
1091
+ // ),
1092
+ // },
1093
+ // },
1094
+ // async (
1095
+ // { prompt, voiceType, language, referenceImages, orientation, model },
1096
+ // context
1097
+ // ) => {
1098
+ // try {
1099
+ // // 验证session状态
1100
+ // const currentSession = await validateSession('generate-video-outlines');
1101
+ // let progress = 0;
1102
+ // const ai = currentSession.ai;
1103
+ // let images;
1104
+ // if (referenceImages) {
1105
+ // images = await Promise.all(
1106
+ // referenceImages.map(
1107
+ // async image =>
1108
+ // await getMaterialUri(currentSession, image.fileName, {
1109
+ // fileSizeLimit: 10,
1110
+ // })
1111
+ // )
1112
+ // );
1113
+ // }
1114
+ // const res = await ai.generateShortVideoOutlines({
1115
+ // prompt,
1116
+ // voiceType,
1117
+ // language,
1118
+ // images,
1119
+ // videoModel: model as any,
1120
+ // aspectRatio: orientation === 'portrait' ? '9:16' : '16:9',
1121
+ // onProgress: async metaData => {
1122
+ // try {
1123
+ // await sendProgress(
1124
+ // context,
1125
+ // ++progress,
1126
+ // undefined,
1127
+ // JSON.stringify(metaData)
1128
+ // );
1129
+ // } catch (progressError) {
1130
+ // console.warn('Failed to send progress update:', progressError);
1131
+ // }
1132
+ // },
1133
+ // });
1134
+ // if (!res) {
1135
+ // throw new Error(
1136
+ // 'Failed to generate short video outlines: no response from AI service'
1137
+ // );
1138
+ // }
1139
+ // if (res.taskUrl) {
1140
+ // return {
1141
+ // content: [
1142
+ // {
1143
+ // type: 'text' as const,
1144
+ // text: JSON.stringify({
1145
+ // success: true,
1146
+ // message:
1147
+ // '该任务正在运行中,它是异步任务,且执行时间较长,你应立即调用工具 wait-for-task-finish (saveFileName=outline_sheet.png) 来等待任务结束,如 wait-for-task-finish 工具调用超时,你应立即再次重新调用直到任务结束。',
1148
+ // taskUrl: res.taskUrl,
1149
+ // }),
1150
+ // },
1151
+ // ],
1152
+ // };
1153
+ // } else if (res.url) {
1154
+ // const url = res.url;
1155
+ // const { savedTo } = await saveMaterial(
1156
+ // currentSession,
1157
+ // url,
1158
+ // 'outline_sheet.png'
1159
+ // );
1160
+ // const {
1161
+ // scenes,
1162
+ // video_type,
1163
+ // voice_type,
1164
+ // voiceover_tone,
1165
+ // voice_id,
1166
+ // bgm_prompt,
1167
+ // video_model,
1168
+ // } = res.data || {};
1169
+ // const seed = getRandomSeed();
1170
+ // const storyboard = {
1171
+ // orientation,
1172
+ // video_type,
1173
+ // outline_sheet: savedTo,
1174
+ // bgm_prompt,
1175
+ // voice_type,
1176
+ // scenes: scenes.map((scene: any) => {
1177
+ // return {
1178
+ // ...scene,
1179
+ // narration_tone: voiceover_tone,
1180
+ // narration_voice_id: voice_id,
1181
+ // use_video_model: video_model,
1182
+ // seed,
1183
+ // };
1184
+ // }),
1185
+ // };
1186
+ // const saveLocalPath = resolve(projectLocalDir, 'storyboard.json');
1187
+ // await writeFile(saveLocalPath, JSON.stringify(storyboard, null, 2));
1188
+ // return {
1189
+ // content: [
1190
+ // {
1191
+ // type: 'text' as const,
1192
+ // text: JSON.stringify({
1193
+ // success: true,
1194
+ // message: '视频大纲生成成功',
1195
+ // storyboard,
1196
+ // }),
1197
+ // },
1198
+ // ],
1199
+ // };
1200
+ // }
1201
+ // return {
1202
+ // content: [
1203
+ // {
1204
+ // type: 'text' as const,
1205
+ // text: JSON.stringify({
1206
+ // success: false,
1207
+ // error: 'No image URL returned from AI service',
1208
+ // response: res,
1209
+ // timestamp: new Date().toISOString(),
1210
+ // }),
1211
+ // },
1212
+ // ],
1213
+ // };
1214
+ // } catch (error) {
1215
+ // return createErrorResponse(error, 'generate-video-outlines');
1216
+ // }
1217
+ // }
1218
+ // );
1182
1219
  server.registerTool('generate-music', {
1183
1220
  title: '创作音乐(Music)',
1184
1221
  description: '生成音乐,包括 BGM 和 歌曲',
@@ -1381,7 +1418,7 @@ server.registerTool('text-to-speech', {
1381
1418
  });
1382
1419
  server.registerTool('generate-video', {
1383
1420
  title: 'Generate Video',
1384
- description: `首帧图和首尾帧生视频工具`,
1421
+ description: `全能参考视频创作工具`,
1385
1422
  inputSchema: {
1386
1423
  prompt: zod_1.z
1387
1424
  .string()
@@ -1416,6 +1453,7 @@ server.registerTool('generate-video', {
1416
1453
  'vidu-pro',
1417
1454
  'viduq3',
1418
1455
  'viduq3-turbo',
1456
+ 'viduq3-pro',
1419
1457
  'kling',
1420
1458
  'kling-v3',
1421
1459
  'wan',
@@ -1917,7 +1955,7 @@ server.registerTool('audio-video-sync', {
1917
1955
  audioVolume: zod_1.z
1918
1956
  .number()
1919
1957
  .optional()
1920
- .default(0.177) // -15db
1958
+ .default(0.316) // -10db
1921
1959
  .describe('0.0 to 2.0.'),
1922
1960
  videoAudioVolume: zod_1.z
1923
1961
  .number()