cerevox 2.30.6 → 2.32.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.
@@ -152,8 +152,13 @@ function createErrorResponse(error, operation) {
152
152
  }
153
153
  // Session 状态检查
154
154
  async function validateSession(operation) {
155
+ if (closeSessionTimerId) {
156
+ clearTimeout(closeSessionTimerId);
157
+ closeSessionTimerId = null;
158
+ }
155
159
  if (!session || !(await session.isRunning())) {
156
- throw new Error(`Session not initialized. Please call 'zerocut-project-open' first before using ${operation}.`);
160
+ session = null;
161
+ throw new Error(`Session not initialized. Please call 'project-open' first before using ${operation}.`);
157
162
  }
158
163
  return session;
159
164
  }
@@ -409,6 +414,7 @@ let projectLocalDir = '.';
409
414
  let checkStoryboardFlag = false;
410
415
  let checkAudioVideoDurationFlag = false;
411
416
  let checkStoryboardSubtitlesFlag = false;
417
+ let closeSessionTimerId = null;
412
418
  // 注册 ZeroCut 指导规范 Prompt
413
419
  server.registerPrompt('zerocut-guideline', {
414
420
  title: 'ZeroCut 短视频创作指导规范',
@@ -443,15 +449,25 @@ server.registerTool('retrieve-rules-context', {
443
449
  'general-video',
444
450
  'music-video',
445
451
  'stage-play',
446
- 'anime-series',
447
452
  'story-telling',
448
453
  'creative-ad',
449
454
  'professional',
455
+ 'material-creation',
450
456
  'freeform',
451
457
  'custom',
452
458
  ])
453
459
  .default('general-video')
454
- .describe('The purpose of the rules context to retrieve.'),
460
+ .describe(`The purpose of the rules context to retrieve.
461
+
462
+ - general-video 创建通用视频
463
+ - music-video 创建音乐视频
464
+ - stage-play 创建舞台播放视频
465
+ - story-telling 创建故事讲述视频
466
+ - creative-ad 创建创意广告视频
467
+ - professional 创建专业视频
468
+ - material-creation 素材创作模式
469
+ - freeform 自由创作模式
470
+ - custom 自定义模式`),
455
471
  },
456
472
  }, async ({ purpose }) => {
457
473
  const projectRulesFile = (0, node_path_1.resolve)(projectLocalDir, '.trae', 'rules', `project_rules.md`);
@@ -474,10 +490,10 @@ server.registerTool('retrieve-rules-context', {
474
490
  if (purpose !== 'general-video' &&
475
491
  purpose !== 'music-video' &&
476
492
  purpose !== 'stage-play' &&
477
- purpose !== 'anime-series' &&
478
493
  purpose !== 'story-telling' &&
479
494
  purpose !== 'creative-ad' &&
480
495
  purpose !== 'professional' &&
496
+ purpose !== 'material-creation' &&
481
497
  purpose !== 'freeform') {
482
498
  return createErrorResponse(`Project rules file not found: ${projectRulesFile}`, 'retrieve-rules-context');
483
499
  }
@@ -548,7 +564,7 @@ server.registerTool('retrieve-rules-context', {
548
564
  return createErrorResponse(`Failed to load rules context prompt for ${purpose}: ${error}`, 'retrieve-rules-context');
549
565
  }
550
566
  });
551
- server.registerTool('zerocut-project-open', {
567
+ server.registerTool('project-open', {
552
568
  title: 'Open Project',
553
569
  description: 'Launch a new Cerevox session with a Chromium browser instance and open a new project context. Supports smart file filtering to optimize upload performance.',
554
570
  inputSchema: {
@@ -570,15 +586,32 @@ server.registerTool('zerocut-project-open', {
570
586
  },
571
587
  }, async ({ localDir, uploadAllFiles, tosFiles }, context) => {
572
588
  try {
589
+ if (closeSessionTimerId) {
590
+ clearTimeout(closeSessionTimerId);
591
+ closeSessionTimerId = null;
592
+ }
573
593
  // 检查是否已有活跃session
574
594
  if (session) {
575
595
  console.warn('Session already exists, closing previous session');
576
- try {
577
- await session.close();
578
- }
579
- catch (closeError) {
580
- console.warn('Failed to close previous session:', closeError);
581
- }
596
+ // try {
597
+ // await session.close();
598
+ // } catch (closeError) {
599
+ // console.warn('Failed to close previous session:', closeError);
600
+ // }
601
+ const result = {
602
+ success: true,
603
+ sessionId: session.id,
604
+ workDir: `/home/user/cerevox-zerocut/projects/${session.terminal.id}`,
605
+ projectLocalDir,
606
+ };
607
+ return {
608
+ content: [
609
+ {
610
+ type: 'text',
611
+ text: JSON.stringify(result),
612
+ },
613
+ ],
614
+ };
582
615
  }
583
616
  const apiKey = process.env.CEREVOX_API_KEY;
584
617
  // 验证API密钥
@@ -678,19 +711,29 @@ server.registerTool('zerocut-project-open', {
678
711
  }
679
712
  catch (error) {
680
713
  // 不自动关闭session,让agent根据异常信息自行处理
681
- return createErrorResponse(error, 'zerocut-project-open');
714
+ return createErrorResponse(error, 'project-open');
682
715
  }
683
716
  });
684
- server.registerTool('zerocut-project-close', {
717
+ server.registerTool('project-close', {
685
718
  title: 'Close Project',
686
719
  description: 'Close the current Cerevox session and release all resources.',
687
- inputSchema: {},
688
- }, async () => {
720
+ inputSchema: {
721
+ inMinutes: zod_1.z
722
+ .number()
723
+ .int()
724
+ .min(0)
725
+ .max(20)
726
+ .default(5)
727
+ .describe('Close the session after the specified number of minutes. Default is 5 minutes. 如果用户要求立即关闭会话,请将该参数设置为0!'),
728
+ },
729
+ }, async ({ inMinutes }) => {
689
730
  try {
690
731
  if (session) {
691
- console.log('Closing Cerevox session...');
692
- await session.close();
693
- session = null;
732
+ closeSessionTimerId = setTimeout(() => {
733
+ console.log('Closing Cerevox session...');
734
+ session?.close();
735
+ session = null;
736
+ }, inMinutes * 60 * 1000);
694
737
  console.log('Session closed successfully');
695
738
  }
696
739
  else {
@@ -712,7 +755,7 @@ server.registerTool('zerocut-project-close', {
712
755
  catch (error) {
713
756
  // 即使关闭失败,也要清理session引用
714
757
  session = null;
715
- return createErrorResponse(error, 'zerocut-project-close');
758
+ return createErrorResponse(error, 'project-close');
716
759
  }
717
760
  });
718
761
  // 列出项目下的所有文件
@@ -1427,7 +1470,7 @@ server.registerTool('generate-image', {
1427
1470
  }
1428
1471
  }
1429
1472
  const turnaroundMessage = hasTurnaround
1430
- ? '⚠️ 注意**三视图**是指**同一个**人或物体的不同视角合成图,三部分都表示同一个人或物体,只能参考其信息画出**一个人或一个物体**,不要画成多个人或多个物体!\n'
1473
+ ? '⚠️ 注意**三视图**是指**同一个**人或物体的不同视角合成图,三部分都表示同一个人或物体,只能参考其信息画出**一个人或一个物体**,不要画成多个人或多个物体!\n\n'
1431
1474
  : '';
1432
1475
  if (objectPrefix.length > 0) {
1433
1476
  processedPrompt = `${objectPrefix.join('\n')}
@@ -1769,7 +1812,7 @@ server.registerTool('generate-video', {
1769
1812
  scene.dialog)) {
1770
1813
  if (!checkAudioVideoDurationFlag) {
1771
1814
  checkAudioVideoDurationFlag = true;
1772
- return createErrorResponse('请先自我检查 media_logs 中的查音频时长,确保匹配音频时长来生成视频', 'generate-video');
1815
+ return createErrorResponse('请先自我检查 media_logs 中的查音频时长,确保音频时长不大于duration指定的视频时长', 'generate-video');
1773
1816
  }
1774
1817
  }
1775
1818
  }
@@ -2666,8 +2709,8 @@ server.registerTool('compile-and-run', {
2666
2709
  success: false,
2667
2710
  exitCode: result.exitCode,
2668
2711
  outputPath,
2669
- command: compiled.cmd,
2670
- stderr: result.stderr?.substring(0, 1000), // 限制错误输出长度
2712
+ // command: compiled.cmd,
2713
+ stderr: result.stderr,
2671
2714
  message: `FFmpeg exited with code ${result.exitCode}`,
2672
2715
  timestamp: new Date().toISOString(),
2673
2716
  };
@@ -3524,11 +3567,7 @@ server.registerTool('generate-video-by-ref', {
3524
3567
  .optional()
3525
3568
  .default(5)
3526
3569
  .describe('The duration of the video in seconds.'),
3527
- size: zod_1.z
3528
- .enum(['720x1280', '1280x720'])
3529
- .optional()
3530
- .default('720x1280')
3531
- .describe('The size of the video.'),
3570
+ size: zod_1.z.enum(['720x1280', '1280x720']).describe('The size of the video.'),
3532
3571
  watermark: zod_1.z
3533
3572
  .boolean()
3534
3573
  .optional()
@@ -3916,11 +3955,16 @@ server.registerTool('run-ffmpeg-command', {
3916
3955
  command: zod_1.z
3917
3956
  .string()
3918
3957
  .describe('The ffmpeg or ffprobe command to execute. Only ffmpeg and ffprobe commands are allowed.'),
3958
+ dir: zod_1.z
3959
+ .string()
3960
+ .optional()
3961
+ .default('materials')
3962
+ .describe('The working directory for the command execution. Default is the materials directory.'),
3919
3963
  saveToFileName: zod_1.z
3920
3964
  .string()
3921
3965
  .describe('The filename that matches the output file specified in the ffmpeg command. This file will be downloaded to the local materials directory after command execution.'),
3922
3966
  },
3923
- }, async ({ command, saveToFileName }) => {
3967
+ }, async ({ command, dir, saveToFileName }) => {
3924
3968
  try {
3925
3969
  // 验证session状态
3926
3970
  const currentSession = await validateSession('run-ffmpeg-command');
@@ -3944,7 +3988,7 @@ server.registerTool('run-ffmpeg-command', {
3944
3988
  }
3945
3989
  console.log(`Running command: ${finalCommand}`);
3946
3990
  // 构建工作目录路径 - materials 目录
3947
- const workDir = `/home/user/cerevox-zerocut/projects/${terminal.id}/materials`;
3991
+ const workDir = `/home/user/cerevox-zerocut/projects/${terminal.id}/${dir}`;
3948
3992
  // 执行命令,用一个独立的命令行以免影响当前会话的cwd
3949
3993
  const response = await terminal.create().run(finalCommand, {
3950
3994
  cwd: workDir,