@juspay/neurolink 9.22.3 → 9.24.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +10 -13
  3. package/dist/adapters/video/directorPipeline.d.ts +31 -0
  4. package/dist/adapters/video/directorPipeline.js +516 -0
  5. package/dist/adapters/video/ffmpegAdapter.d.ts +78 -0
  6. package/dist/adapters/video/ffmpegAdapter.js +206 -0
  7. package/dist/adapters/video/frameExtractor.d.ts +28 -0
  8. package/dist/adapters/video/frameExtractor.js +143 -0
  9. package/dist/adapters/video/vertexVideoHandler.d.ts +25 -25
  10. package/dist/adapters/video/vertexVideoHandler.js +173 -42
  11. package/dist/adapters/video/videoMerger.d.ts +22 -0
  12. package/dist/adapters/video/videoMerger.js +171 -0
  13. package/dist/cli/factories/commandFactory.d.ts +34 -0
  14. package/dist/cli/factories/commandFactory.js +321 -130
  15. package/dist/constants/index.d.ts +1 -0
  16. package/dist/constants/index.js +2 -0
  17. package/dist/constants/videoErrors.d.ts +45 -0
  18. package/dist/constants/videoErrors.js +46 -0
  19. package/dist/core/baseProvider.js +42 -1
  20. package/dist/features/ppt/index.d.ts +1 -1
  21. package/dist/features/ppt/index.js +1 -1
  22. package/dist/lib/adapters/video/directorPipeline.d.ts +31 -0
  23. package/dist/lib/adapters/video/directorPipeline.js +517 -0
  24. package/dist/lib/adapters/video/ffmpegAdapter.d.ts +78 -0
  25. package/dist/lib/adapters/video/ffmpegAdapter.js +207 -0
  26. package/dist/lib/adapters/video/frameExtractor.d.ts +28 -0
  27. package/dist/lib/adapters/video/frameExtractor.js +144 -0
  28. package/dist/lib/adapters/video/vertexVideoHandler.d.ts +25 -25
  29. package/dist/lib/adapters/video/vertexVideoHandler.js +173 -42
  30. package/dist/lib/adapters/video/videoMerger.d.ts +22 -0
  31. package/dist/lib/adapters/video/videoMerger.js +172 -0
  32. package/dist/lib/constants/index.d.ts +1 -0
  33. package/dist/lib/constants/index.js +2 -0
  34. package/dist/lib/constants/videoErrors.d.ts +45 -0
  35. package/dist/lib/constants/videoErrors.js +47 -0
  36. package/dist/lib/core/baseProvider.js +42 -1
  37. package/dist/lib/features/ppt/index.d.ts +1 -1
  38. package/dist/lib/features/ppt/index.js +1 -1
  39. package/dist/lib/types/cli.d.ts +18 -2
  40. package/dist/lib/types/content.d.ts +1 -1
  41. package/dist/lib/types/generateTypes.d.ts +20 -3
  42. package/dist/lib/types/multimodal.d.ts +64 -4
  43. package/dist/lib/types/multimodal.js +36 -1
  44. package/dist/lib/utils/parameterValidation.d.ts +8 -1
  45. package/dist/lib/utils/parameterValidation.js +80 -1
  46. package/dist/types/cli.d.ts +18 -2
  47. package/dist/types/content.d.ts +1 -1
  48. package/dist/types/generateTypes.d.ts +20 -3
  49. package/dist/types/multimodal.d.ts +64 -4
  50. package/dist/types/multimodal.js +36 -1
  51. package/dist/utils/parameterValidation.d.ts +8 -1
  52. package/dist/utils/parameterValidation.js +80 -1
  53. package/package.json +1 -1
@@ -12,38 +12,17 @@
12
12
  import { readFile } from "node:fs/promises";
13
13
  import { ErrorCategory, ErrorSeverity } from "../../constants/enums.js";
14
14
  import { TIMEOUTS } from "../../constants/timeouts.js";
15
+ import { VIDEO_ERROR_CODES } from "../../constants/videoErrors.js";
15
16
  import { isAbortError, NeuroLinkError, withTimeout, } from "../../utils/errorHandling.js";
16
17
  import { logger } from "../../utils/logger.js";
17
18
  // ============================================================================
18
- // VIDEO ERROR CODES
19
+ // VIDEO ERROR CODES (Re-exported for backward compatibility)
19
20
  // ============================================================================
20
21
  /**
21
- * Video generation runtime error codes
22
- *
23
- * These are for runtime/execution errors during video generation.
24
- * Pure option/shape validation (missing image option, invalid config values, etc.)
25
- * is handled by parameterValidation.ts using ERROR_CODES from errorHandling.ts.
26
- *
27
- * Error categorization:
28
- * - INVALID_INPUT → ErrorCategory.execution (runtime I/O failures)
29
- * - parameterValidation errors → ErrorCategory.validation (schema/option issues)
30
- *
31
- * Following TTS pattern (TTS_ERROR_CODES + TTSError in ttsProcessor.ts)
22
+ * Video error codes - re-exported from constants module for backward compatibility.
23
+ * @see {@link VIDEO_ERROR_CODES} in constants/videoErrors.ts for definitions
32
24
  */
33
- export const VIDEO_ERROR_CODES = {
34
- /** Video generation API call failed */
35
- GENERATION_FAILED: "VIDEO_GENERATION_FAILED",
36
- /** Provider (Vertex AI) not properly configured */
37
- PROVIDER_NOT_CONFIGURED: "VIDEO_PROVIDER_NOT_CONFIGURED",
38
- /** Polling for video completion timed out */
39
- POLL_TIMEOUT: "VIDEO_POLL_TIMEOUT",
40
- /**
41
- * Runtime I/O error during input processing.
42
- * Used for: failed URL fetch, failed file read, corrupt/unreadable buffer.
43
- * NOT for: missing options or invalid config shapes (use parameterValidation).
44
- */
45
- INVALID_INPUT: "VIDEO_INVALID_INPUT",
46
- };
25
+ export { VIDEO_ERROR_CODES };
47
26
  /**
48
27
  * Video generation error class
49
28
  * Extends NeuroLinkError for consistent error handling across the SDK
@@ -71,6 +50,8 @@ const VIDEO_GENERATION_TIMEOUT_MS = 180000;
71
50
  const POLL_INTERVAL_MS = 5000;
72
51
  /** Full model name for Veo 3.1 (IMPORTANT: not just "veo-3.1") */
73
52
  const VEO_MODEL = "veo-3.1-generate-001";
53
+ /** Full model name for Veo 3.1 Fast (used for transitions) */
54
+ const VEO_FAST_MODEL = "veo-3.1-fast-generate-001";
74
55
  /** Default location for Vertex AI */
75
56
  const DEFAULT_LOCATION = "us-central1";
76
57
  // ============================================================================
@@ -592,35 +573,185 @@ async function makePollRequest(pollEndpoint, operationName, accessToken, timeout
592
573
  * @throws {VideoError} On API error, timeout, or missing video data
593
574
  */
594
575
  async function pollVideoOperation(operationName, accessToken, project, location, timeoutMs) {
576
+ return pollOperation(VEO_MODEL, operationName, accessToken, project, location, timeoutMs);
577
+ }
578
+ // ============================================================================
579
+ // TRANSITION GENERATION (Director Mode)
580
+ // ============================================================================
581
+ /**
582
+ * Generate a transition clip using Veo 3.1 Fast's first-and-last-frame interpolation.
583
+ *
584
+ * This calls the Veo API with both `image` (first frame) and `lastFrame` (last frame),
585
+ * producing a video that smoothly interpolates between the two frames.
586
+ *
587
+ * @param firstFrame - JPEG buffer of the first frame (last frame of clip N)
588
+ * @param lastFrame - JPEG buffer of the last frame (first frame of clip N+1)
589
+ * @param prompt - Transition prompt describing desired visual flow
590
+ * @param options - Video output options (resolution, aspect ratio, audio)
591
+ * @param durationSeconds - Duration of the transition clip (4, 6, or 8)
592
+ * @param region - Vertex AI region override
593
+ * @returns Video buffer of the transition clip
594
+ *
595
+ * @throws {VideoError} When API returns an error or polling times out
596
+ */
597
+ export async function generateTransitionWithVertex(firstFrame, lastFrame, prompt, options = {}, durationSeconds = 4, region) {
598
+ if (!isVertexVideoConfigured()) {
599
+ throw new VideoError({
600
+ code: VIDEO_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
601
+ message: "Vertex AI credentials not configured for transition generation.",
602
+ category: ErrorCategory.CONFIGURATION,
603
+ severity: ErrorSeverity.HIGH,
604
+ retriable: false,
605
+ });
606
+ }
607
+ const config = await getVertexConfig();
608
+ const project = config.project;
609
+ const location = region || config.location;
595
610
  const startTime = Date.now();
596
- // Use fetchPredictOperation endpoint - this is MODEL-SPECIFIC
597
- const pollEndpoint = `https://${location}-aiplatform.googleapis.com/v1/projects/${project}/locations/${location}/publishers/google/models/${VEO_MODEL}:fetchPredictOperation`;
611
+ const aspectRatio = options.aspectRatio || "16:9";
612
+ const resolution = options.resolution || "720p";
613
+ const generateAudio = options.audio ?? true;
614
+ logger.debug("Starting transition clip generation", {
615
+ model: VEO_FAST_MODEL,
616
+ durationSeconds,
617
+ firstFrameSize: firstFrame.length,
618
+ lastFrameSize: lastFrame.length,
619
+ promptLength: prompt.length,
620
+ });
621
+ try {
622
+ const firstFrameBase64 = firstFrame.toString("base64");
623
+ const lastFrameBase64 = lastFrame.toString("base64");
624
+ const firstMime = detectMimeType(firstFrame);
625
+ const lastMime = detectMimeType(lastFrame);
626
+ const accessToken = await getAccessToken();
627
+ // Use Veo 3.1 Fast for transitions (faster with minimal quality difference)
628
+ const endpoint = `https://${location}-aiplatform.googleapis.com/v1/projects/${project}/locations/${location}/publishers/google/models/${VEO_FAST_MODEL}:predictLongRunning`;
629
+ const requestBody = {
630
+ instances: [
631
+ {
632
+ prompt: prompt,
633
+ image: {
634
+ bytesBase64Encoded: firstFrameBase64,
635
+ mimeType: firstMime,
636
+ },
637
+ lastFrame: {
638
+ bytesBase64Encoded: lastFrameBase64,
639
+ mimeType: lastMime,
640
+ },
641
+ },
642
+ ],
643
+ parameters: {
644
+ sampleCount: 1,
645
+ durationSeconds: durationSeconds,
646
+ aspectRatio: aspectRatio,
647
+ resolution: resolution,
648
+ generateAudio: generateAudio,
649
+ },
650
+ };
651
+ const controller = new AbortController();
652
+ const requestTimeout = setTimeout(() => controller.abort(), 30000);
653
+ let response;
654
+ try {
655
+ response = await fetch(endpoint, {
656
+ method: "POST",
657
+ headers: {
658
+ Authorization: `Bearer ${accessToken}`,
659
+ "Content-Type": "application/json; charset=utf-8",
660
+ },
661
+ body: JSON.stringify(requestBody),
662
+ signal: controller.signal,
663
+ });
664
+ }
665
+ catch (error) {
666
+ clearTimeout(requestTimeout);
667
+ if (isAbortError(error)) {
668
+ throw new VideoError({
669
+ code: VIDEO_ERROR_CODES.DIRECTOR_TRANSITION_FAILED,
670
+ message: "Transition generation request timed out after 30 seconds",
671
+ category: ErrorCategory.EXECUTION,
672
+ severity: ErrorSeverity.MEDIUM,
673
+ retriable: true,
674
+ });
675
+ }
676
+ throw error;
677
+ }
678
+ clearTimeout(requestTimeout);
679
+ if (!response.ok) {
680
+ const errorText = await response.text();
681
+ throw new VideoError({
682
+ code: VIDEO_ERROR_CODES.DIRECTOR_TRANSITION_FAILED,
683
+ message: `Transition API error: ${response.status} - ${errorText}`,
684
+ category: ErrorCategory.EXECUTION,
685
+ severity: ErrorSeverity.MEDIUM,
686
+ retriable: response.status >= 500,
687
+ context: { status: response.status, error: errorText },
688
+ });
689
+ }
690
+ const operation = await response.json();
691
+ const operationName = operation.name;
692
+ if (!operationName) {
693
+ throw new VideoError({
694
+ code: VIDEO_ERROR_CODES.DIRECTOR_TRANSITION_FAILED,
695
+ message: "Transition API did not return an operation name",
696
+ category: ErrorCategory.EXECUTION,
697
+ severity: ErrorSeverity.MEDIUM,
698
+ retriable: false,
699
+ });
700
+ }
701
+ // Poll with Veo Fast model endpoint
702
+ const remainingTime = VIDEO_GENERATION_TIMEOUT_MS - (Date.now() - startTime);
703
+ const videoBuffer = await pollTransitionOperation(operationName, accessToken, project, location, Math.max(1000, remainingTime));
704
+ logger.debug("Transition clip generated", {
705
+ processingTime: Date.now() - startTime,
706
+ videoSize: videoBuffer.length,
707
+ });
708
+ return videoBuffer;
709
+ }
710
+ catch (error) {
711
+ if (error instanceof VideoError) {
712
+ throw error;
713
+ }
714
+ throw new VideoError({
715
+ code: VIDEO_ERROR_CODES.DIRECTOR_TRANSITION_FAILED,
716
+ message: `Transition generation failed: ${error instanceof Error ? error.message : String(error)}`,
717
+ category: ErrorCategory.EXECUTION,
718
+ severity: ErrorSeverity.MEDIUM,
719
+ retriable: true,
720
+ originalError: error instanceof Error ? error : undefined,
721
+ });
722
+ }
723
+ }
724
+ /**
725
+ * Common polling helper that handles both video and transition operations.
726
+ * Accepts a model name to construct the appropriate endpoint.
727
+ */
728
+ async function pollOperation(modelOrEndpoint, operationName, accessToken, project, location, timeoutMs) {
729
+ const startTime = Date.now();
730
+ const pollEndpoint = `https://${location}-aiplatform.googleapis.com/v1/projects/${project}/locations/${location}/publishers/google/models/${modelOrEndpoint}:fetchPredictOperation`;
598
731
  while (Date.now() - startTime < timeoutMs) {
599
732
  const result = await makePollRequest(pollEndpoint, operationName, accessToken);
600
733
  if (result.done) {
601
734
  return extractVideoFromResult(result, operationName);
602
735
  }
603
- const elapsed = Date.now() - startTime;
604
- logger.debug("Polling video operation...", {
736
+ logger.debug("Polling operation...", {
605
737
  operationName,
606
- elapsed,
607
- remainingMs: timeoutMs - elapsed,
738
+ elapsed: Date.now() - startTime,
608
739
  });
609
- // Wait before next poll
610
740
  await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
611
741
  }
612
- // Timeout reached
613
742
  throw new VideoError({
614
743
  code: VIDEO_ERROR_CODES.POLL_TIMEOUT,
615
- message: `Video generation timed out after ${Math.round(timeoutMs / 1000)}s while polling for completion`,
744
+ message: `Operation timed out after ${Math.round(timeoutMs / 1000)}s`,
616
745
  category: ErrorCategory.TIMEOUT,
617
- severity: ErrorSeverity.HIGH,
746
+ severity: ErrorSeverity.MEDIUM,
618
747
  retriable: true,
619
- context: {
620
- operationName,
621
- timeoutMs,
622
- provider: "vertex",
623
- suggestion: "Try again - video generation can take 1-3 minutes. Consider using a shorter duration or lower resolution.",
624
- },
748
+ context: { operationName, timeoutMs },
625
749
  });
626
750
  }
751
+ /**
752
+ * Poll Vertex AI operation for transition clip completion.
753
+ * Uses the Veo Fast model fetchPredictOperation endpoint.
754
+ */
755
+ async function pollTransitionOperation(operationName, accessToken, project, location, timeoutMs) {
756
+ return pollOperation(VEO_FAST_MODEL, operationName, accessToken, project, location, timeoutMs);
757
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Video Merger for Director Mode
3
+ *
4
+ * Concatenates multiple MP4 video buffers into a single MP4 using FFmpeg's
5
+ * concat demuxer for lossless concatenation when codecs match.
6
+ *
7
+ * Uses the shared FFmpeg adapter for binary resolution, temp file management,
8
+ * and process execution — following the adapter pattern in `adapters/tts/`.
9
+ *
10
+ * @module adapters/video/videoMerger
11
+ */
12
+ /**
13
+ * Merge multiple MP4 video buffers into a single MP4.
14
+ *
15
+ * Uses FFmpeg concat demuxer for lossless concatenation. If codecs don't match
16
+ * (unlikely since all clips come from Veo), falls back to re-encoding with H.264.
17
+ *
18
+ * @param videoBuffers - Array of MP4 video buffers to concatenate in order
19
+ * @returns Merged MP4 video buffer
20
+ * @throws {VideoError} If merge fails or no valid buffers provided
21
+ */
22
+ export declare function mergeVideoBuffers(videoBuffers: Buffer[]): Promise<Buffer>;
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Video Merger for Director Mode
3
+ *
4
+ * Concatenates multiple MP4 video buffers into a single MP4 using FFmpeg's
5
+ * concat demuxer for lossless concatenation when codecs match.
6
+ *
7
+ * Uses the shared FFmpeg adapter for binary resolution, temp file management,
8
+ * and process execution — following the adapter pattern in `adapters/tts/`.
9
+ *
10
+ * @module adapters/video/videoMerger
11
+ */
12
+ import { ErrorCategory, ErrorSeverity } from "../../constants/enums.js";
13
+ import { logger } from "../../utils/logger.js";
14
+ import { cleanupTempFiles, createTrackedTempDir, FFMPEG_MERGE_MAX_BUFFER, FFMPEG_MERGE_TIMEOUT_MS, isValidMp4Buffer, join, readFile, runFfmpeg, writeFile, } from "./ffmpegAdapter.js";
15
+ import { VIDEO_ERROR_CODES } from "../../constants/videoErrors.js";
16
+ import { VideoError } from "./vertexVideoHandler.js";
17
+ // ============================================================================
18
+ // INTERNAL HELPERS
19
+ // ============================================================================
20
+ /**
21
+ * Write clip buffers to temp files and build the FFmpeg concat list.
22
+ *
23
+ * @returns Paths of all written clip files
24
+ */
25
+ async function writeClipsAndBuildConcatList(videoBuffers, tempDir, concatListPath) {
26
+ const inputPaths = [];
27
+ const concatLines = [];
28
+ for (let i = 0; i < videoBuffers.length; i++) {
29
+ const inputPath = join(tempDir, `clip_${i}.mp4`);
30
+ await writeFile(inputPath, videoBuffers[i]);
31
+ inputPaths.push(inputPath);
32
+ // Normalize backslashes to forward slashes for FFmpeg, then escape single quotes
33
+ const safePath = inputPath.replace(/\\/g, "/").replace(/'/g, "'\\''");
34
+ concatLines.push(`file '${safePath}'`);
35
+ }
36
+ await writeFile(concatListPath, concatLines.join("\n"));
37
+ return inputPaths;
38
+ }
39
+ /**
40
+ * Attempt lossless concat, falling back to H.264 re-encode on failure.
41
+ */
42
+ async function concatWithFallback(concatListPath, outputPath) {
43
+ const ffmpegOpts = {
44
+ timeoutMs: FFMPEG_MERGE_TIMEOUT_MS,
45
+ maxBuffer: FFMPEG_MERGE_MAX_BUFFER,
46
+ };
47
+ try {
48
+ // Try lossless concat first (fastest — no re-encoding)
49
+ await runFfmpeg([
50
+ "-y",
51
+ "-f",
52
+ "concat",
53
+ "-safe",
54
+ "0",
55
+ "-i",
56
+ concatListPath,
57
+ "-c",
58
+ "copy",
59
+ outputPath,
60
+ ], ffmpegOpts);
61
+ }
62
+ catch (concatError) {
63
+ // Fallback: re-encode with H.264 if codecs mismatch
64
+ logger.warn("Lossless concat failed, falling back to H.264 re-encoding", {
65
+ error: concatError instanceof Error
66
+ ? concatError.message
67
+ : String(concatError),
68
+ });
69
+ await runFfmpeg([
70
+ "-y",
71
+ "-f",
72
+ "concat",
73
+ "-safe",
74
+ "0",
75
+ "-i",
76
+ concatListPath,
77
+ "-c:v",
78
+ "libx264",
79
+ "-preset",
80
+ "fast",
81
+ "-crf",
82
+ "18",
83
+ "-c:a",
84
+ "aac",
85
+ "-b:a",
86
+ "192k",
87
+ "-movflags",
88
+ "+faststart",
89
+ outputPath,
90
+ ], ffmpegOpts);
91
+ }
92
+ }
93
+ // ============================================================================
94
+ // PUBLIC API
95
+ // ============================================================================
96
+ /**
97
+ * Merge multiple MP4 video buffers into a single MP4.
98
+ *
99
+ * Uses FFmpeg concat demuxer for lossless concatenation. If codecs don't match
100
+ * (unlikely since all clips come from Veo), falls back to re-encoding with H.264.
101
+ *
102
+ * @param videoBuffers - Array of MP4 video buffers to concatenate in order
103
+ * @returns Merged MP4 video buffer
104
+ * @throws {VideoError} If merge fails or no valid buffers provided
105
+ */
106
+ export async function mergeVideoBuffers(videoBuffers) {
107
+ if (videoBuffers.length === 0) {
108
+ throw new VideoError({
109
+ code: VIDEO_ERROR_CODES.DIRECTOR_MERGE_FAILED,
110
+ message: "No video buffers provided to merge",
111
+ category: ErrorCategory.VALIDATION,
112
+ severity: ErrorSeverity.HIGH,
113
+ retriable: false,
114
+ });
115
+ }
116
+ // Validate each input buffer
117
+ for (let i = 0; i < videoBuffers.length; i++) {
118
+ if (!isValidMp4Buffer(videoBuffers[i])) {
119
+ throw new VideoError({
120
+ code: VIDEO_ERROR_CODES.DIRECTOR_MERGE_FAILED,
121
+ message: `Clip ${i} is not a valid MP4 buffer (missing ftyp header or too small)`,
122
+ category: ErrorCategory.VALIDATION,
123
+ severity: ErrorSeverity.HIGH,
124
+ retriable: false,
125
+ context: {
126
+ clipIndex: i,
127
+ bufferSize: videoBuffers[i].length,
128
+ headerHex: videoBuffers[i].subarray(0, 12).toString("hex"),
129
+ },
130
+ });
131
+ }
132
+ }
133
+ if (videoBuffers.length === 1) {
134
+ return videoBuffers[0];
135
+ }
136
+ const startTime = Date.now();
137
+ const tempDir = await createTrackedTempDir("merge");
138
+ const concatListPath = join(tempDir, "concat.txt");
139
+ const outputPath = join(tempDir, "merged.mp4");
140
+ let inputPaths = [];
141
+ try {
142
+ inputPaths = await writeClipsAndBuildConcatList(videoBuffers, tempDir, concatListPath);
143
+ await concatWithFallback(concatListPath, outputPath);
144
+ const mergedBuffer = await readFile(outputPath);
145
+ logger.info("Video merge complete", {
146
+ inputClips: videoBuffers.length,
147
+ totalInputSize: videoBuffers.reduce((sum, b) => sum + b.length, 0),
148
+ outputSize: mergedBuffer.length,
149
+ elapsedMs: Date.now() - startTime,
150
+ });
151
+ return mergedBuffer;
152
+ }
153
+ catch (error) {
154
+ // Re-throw VideoErrors as-is
155
+ if (error instanceof VideoError) {
156
+ throw error;
157
+ }
158
+ throw new VideoError({
159
+ code: VIDEO_ERROR_CODES.DIRECTOR_MERGE_FAILED,
160
+ message: `Video merge failed: ${error instanceof Error ? error.message : String(error)}`,
161
+ category: ErrorCategory.EXECUTION,
162
+ severity: ErrorSeverity.HIGH,
163
+ retriable: false,
164
+ context: { clipCount: videoBuffers.length },
165
+ originalError: error instanceof Error ? error : undefined,
166
+ });
167
+ }
168
+ finally {
169
+ await cleanupTempFiles(tempDir, concatListPath, outputPath, ...inputPaths);
170
+ }
171
+ }
@@ -28,11 +28,21 @@ export declare class CLICommandFactory {
28
28
  * Auto-configures provider, model, and tools settings for video generation
29
29
  */
30
30
  private static configureVideoMode;
31
+ /**
32
+ * Helper method to configure options for PPT generation mode
33
+ * Auto-configures provider, model, and tools settings for presentation generation
34
+ */
35
+ private static configurePPTMode;
31
36
  /**
32
37
  * Helper method to handle video file output
33
38
  * Saves generated video to file when --videoOutput flag is provided
34
39
  */
35
40
  private static handleVideoOutput;
41
+ /**
42
+ * Helper method to handle PPT file output
43
+ * Displays PPT generation result info
44
+ */
45
+ private static handlePPTOutput;
36
46
  private static isValidTokenUsage;
37
47
  private static normalizeTokenUsage;
38
48
  private static formatAnalyticsForTextMode;
@@ -111,6 +121,30 @@ export declare class CLICommandFactory {
111
121
  * Execute provider status command
112
122
  */
113
123
  private static executeProviderStatus;
124
+ /**
125
+ * Handle stdin input for generate command
126
+ */
127
+ private static handleGenerateStdinInput;
128
+ /**
129
+ * Detect output mode (video, ppt, or text) based on CLI arguments
130
+ */
131
+ private static detectGenerateOutputMode;
132
+ /**
133
+ * Process context for generation command
134
+ */
135
+ private static processGenerateContext;
136
+ /**
137
+ * Build multimodal input from CLI arguments
138
+ */
139
+ private static buildGenerateMultimodalInput;
140
+ /**
141
+ * Build output configuration for generate request
142
+ */
143
+ private static buildGenerateOutputConfig;
144
+ /**
145
+ * Handle successful generation result
146
+ */
147
+ private static handleGenerateSuccess;
114
148
  /**
115
149
  * Execute the generate command
116
150
  */