@umituz/react-native-ai-generation-content 1.90.11 → 1.90.13

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 (32) hide show
  1. package/package.json +1 -1
  2. package/src/domains/background/infrastructure/services/job-poller.service.ts +4 -4
  3. package/src/domains/creations/presentation/components/CreationImagePreview.tsx +0 -1
  4. package/src/domains/creations/presentation/hooks/useProcessingJobsPoller.ts +18 -7
  5. package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +0 -1
  6. package/src/domains/face-detection/domain/entities/FaceDetection.ts +1 -0
  7. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-preparation.ts +2 -2
  8. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-prompt.ts +1 -1
  9. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-resolution.ts +1 -1
  10. package/src/domains/generation/infrastructure/couple-generation-builder/builder-scenario.ts +3 -3
  11. package/src/domains/generation/presentation/useAIGeneration.hook.ts +1 -1
  12. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +24 -1
  13. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.types.ts +14 -0
  14. package/src/domains/generation/wizard/presentation/hooks/photo-upload/types.ts +8 -4
  15. package/src/domains/generation/wizard/presentation/hooks/photo-upload/usePhotoUploadStateLogic.ts +1 -1
  16. package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.ts +1 -1
  17. package/src/domains/generation/wizard/presentation/hooks/video-queue/use-video-queue-utils.ts +9 -0
  18. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationStart.ts +9 -1
  19. package/src/domains/image-to-video/domain/types/form.types.ts +1 -0
  20. package/src/domains/image-to-video/presentation/hooks/useGeneration.ts +1 -0
  21. package/src/domains/text-to-image/presentation/hooks/useGeneration.ts +1 -1
  22. package/src/domains/text-to-video/presentation/hooks/useTextToVideoFeature.ts +2 -2
  23. package/src/exports/infrastructure.ts +1 -1
  24. package/src/infrastructure/services/image-feature-executor.service.ts +1 -1
  25. package/src/infrastructure/services/multi-image-generation.executor.ts +3 -2
  26. package/src/infrastructure/services/video-feature-executor.service.ts +1 -1
  27. package/src/infrastructure/validation/ai-validator.ts +8 -4
  28. package/src/infrastructure/validation/entity-validator.ts +2 -2
  29. package/src/infrastructure/validation/input-validator.ts +1 -1
  30. package/src/presentation/hooks/generation/useDualImageGeneration.ts +1 -1
  31. package/src/presentation/hooks/generation/useImageGeneration.ts +2 -2
  32. package/src/presentation/hooks/generation/useVideoGeneration.ts +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-generation-content",
3
- "version": "1.90.11",
3
+ "version": "1.90.13",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -81,13 +81,13 @@ export async function pollJob<T = unknown>(
81
81
  try {
82
82
  // Check job status
83
83
  const statusResult = await withAbortSignal(
84
- provider.checkStatus(requestId, model),
84
+ provider.getJobStatus(model, requestId),
85
85
  signal,
86
86
  config.maxTotalTimeMs ? config.maxTotalTimeMs - (Date.now() - startTime) : undefined
87
87
  );
88
88
 
89
89
  // Notify status change
90
- if (onStatusChange && typeof statusResult === 'object' && 'status' in statusResult) {
90
+ if (onStatusChange && statusResult && typeof statusResult === 'object' && 'status' in statusResult) {
91
91
  onStatusChange(statusResult as JobStatus);
92
92
  }
93
93
 
@@ -96,7 +96,7 @@ export async function pollJob<T = unknown>(
96
96
  if (statusError) {
97
97
  return {
98
98
  success: false,
99
- error: statusError,
99
+ error: statusError instanceof Error ? statusError : new Error(String(statusError)),
100
100
  attempts: attempt + 1,
101
101
  elapsedMs: Date.now() - startTime,
102
102
  };
@@ -106,7 +106,7 @@ export async function pollJob<T = unknown>(
106
106
  consecutiveErrors = 0;
107
107
 
108
108
  // Check if job is complete
109
- if (isJobComplete(statusResult as JobStatus | Record<string, unknown>)) {
109
+ if (isJobComplete(statusResult as JobStatus | string)) {
110
110
  // Validate result
111
111
  const validationResult = validateResult(statusResult);
112
112
  if (!validationResult.isValid) {
@@ -125,7 +125,6 @@ export function CreationImagePreview({
125
125
  source={{ uri }}
126
126
  style={styles.image}
127
127
  contentFit="cover"
128
- transition={0}
129
128
  cachePolicy="disk"
130
129
  onError={handleImageError}
131
130
  onLoadEnd={handleLoadEnd}
@@ -4,8 +4,11 @@
4
4
  */
5
5
 
6
6
  import { useEffect } from 'react';
7
+ import type { Creation } from '../../../domain/entities/Creation';
7
8
 
8
9
  export interface UseProcessingJobsPollerConfig {
10
+ userId: string | null;
11
+ creations: Creation[];
9
12
  enabled?: boolean;
10
13
  interval?: number;
11
14
  }
@@ -16,24 +19,32 @@ export interface UseProcessingJobsPollerReturn {
16
19
 
17
20
  /**
18
21
  * Hook to poll processing jobs
19
- * TODO: Implement actual polling logic
20
22
  */
21
23
  export function useProcessingJobsPoller(
22
- config: UseProcessingJobsPollerConfig = {}
24
+ config: UseProcessingJobsPollerConfig
23
25
  ): UseProcessingJobsPollerReturn {
24
- const { enabled = false, interval = 5000 } = config;
26
+ const { userId, creations, enabled = false, interval = 5000 } = config;
25
27
 
26
28
  useEffect(() => {
27
- if (!enabled) return;
29
+ if (!enabled || !userId) return;
28
30
 
29
31
  const timer = setInterval(() => {
30
- // Polling logic here
32
+ // Polling logic here - check processing creations and update their status
33
+ const processingCreations = creations.filter(c => c.status === 'processing');
34
+ processingCreations.forEach(async (creation) => {
35
+ try {
36
+ // Check job status and update creation
37
+ // TODO: Implement actual polling logic
38
+ } catch (error) {
39
+ console.error('Error polling job status:', error);
40
+ }
41
+ });
31
42
  }, interval);
32
43
 
33
44
  return () => clearInterval(timer);
34
- }, [enabled, interval]);
45
+ }, [enabled, interval, userId, creations]);
35
46
 
36
47
  return {
37
- isPolling: enabled,
48
+ isPolling: enabled && !!userId,
38
49
  };
39
50
  }
@@ -46,7 +46,6 @@ export function CreationsGalleryScreen({
46
46
  useProcessingJobsPoller({
47
47
  userId,
48
48
  creations: creations ?? [],
49
- repository,
50
49
  enabled: !!userId && (creations?.length ?? 0) > 0,
51
50
  });
52
51
 
@@ -13,6 +13,7 @@ export interface FaceDetectionResult {
13
13
 
14
14
  export interface FaceValidationState extends BaseFeatureState<FaceDetectionResult> {
15
15
  isValidating: boolean;
16
+ result?: FaceDetectionResult;
16
17
  }
17
18
 
18
19
  export interface FaceDetectionConfig {
@@ -29,8 +29,8 @@ export async function prepareCoupleGeneration(
29
29
  // 1. GET PHOTO URIs - Couple mode kontrolü
30
30
  const photoUris =
31
31
  isCoupleMode && partner2PhotoUri
32
- ? [partner1PhotoUri, partner2PhotoUri]
33
- : [partner1PhotoUri];
32
+ ? [partner1PhotoUri || "", partner2PhotoUri]
33
+ : [partner1PhotoUri || ""];
34
34
 
35
35
  logBuilderStep(prefix, "STEP 1: PHOTO URIs", {
36
36
  photoUrisCount: photoUris.length,
@@ -49,7 +49,7 @@ export function processCouplePrompt(
49
49
 
50
50
  // 4. CREATE FINAL PROMPT - Photorealistic
51
51
  logBuilderStep(prefix, "STEP 4: CREATE PHOTOREALISTIC PROMPT", {
52
- isCouple: isCoupleMode,
52
+ isCoupleMode,
53
53
  hasCustomInstructions: !!customInstructions
54
54
  });
55
55
 
@@ -39,7 +39,7 @@ export function buildCoupleGenerationResult(
39
39
  });
40
40
 
41
41
  const { target, imageUrls } = resolveCoupleInput(
42
- partner1PhotoUri,
42
+ partner1PhotoUri || "",
43
43
  partner2PhotoUri,
44
44
  isCoupleMode,
45
45
  { model: "p-image-edit", providerId: "pruna" }, // Single target
@@ -44,8 +44,8 @@ export async function buildScenarioGenerationInput(
44
44
  // 1. GET PHOTO URIs
45
45
  const photoUris =
46
46
  isCoupleMode && partner2PhotoUri
47
- ? [partner1PhotoUri, partner2PhotoUri]
48
- : [partner1PhotoUri];
47
+ ? [partner1PhotoUri || "", partner2PhotoUri]
48
+ : [partner1PhotoUri || ""];
49
49
 
50
50
  logBuilderStep("[ScenarioBuilder]", "STEP 1: PHOTO URIs", {
51
51
  photoUrisCount: photoUris.length,
@@ -80,7 +80,7 @@ export async function buildScenarioGenerationInput(
80
80
  logBuilderStep("[ScenarioBuilder]", "STEP 4: RESOLVE COUPLE INPUT");
81
81
 
82
82
  const { target, imageUrls } = resolveCoupleInput(
83
- partner1PhotoUri,
83
+ partner1PhotoUri || "",
84
84
  partner2PhotoUri,
85
85
  isCoupleMode,
86
86
  { model: "p-image-edit", providerId: "pruna" }, // Single target
@@ -81,7 +81,7 @@ export function useAIGeneration(
81
81
  // Use orchestrator for lifecycle management
82
82
  const orchestrator = useGenerationOrchestrator(strategy, {
83
83
  userId,
84
- alertMessages: alertMessages || DEFAULT_ALERT_MESSAGES,
84
+ alertMessages: (alertMessages || DEFAULT_ALERT_MESSAGES) as typeof DEFAULT_ALERT_MESSAGES,
85
85
  onSuccess: async (result) => onSuccess?.(result),
86
86
  onError: onError ? async (error) => onError(error.message) : undefined,
87
87
  });
@@ -5,7 +5,8 @@
5
5
  */
6
6
 
7
7
  import type { WizardStrategy } from "./wizard-strategy.types";
8
- import type { CreateVideoStrategyOptions } from "./video-generation.types";
8
+ import type { CreateVideoStrategyOptions, WizardVideoInput } from "./video-generation.types";
9
+ import type { WizardScenarioData } from "../../presentation/hooks/useWizardGeneration";
9
10
  import { validateWizardVideoInput } from "./video-generation.validation";
10
11
  import { executeVideoGeneration, submitVideoGenerationToQueue } from "./video-generation.executor";
11
12
 
@@ -48,3 +49,25 @@ export function createVideoStrategy(options: CreateVideoStrategyOptions): Wizard
48
49
  };
49
50
  }
50
51
 
52
+ /**
53
+ * Build video input from wizard data and scenario
54
+ */
55
+ export async function buildVideoInput(
56
+ wizardData: Record<string, unknown>,
57
+ scenario: WizardScenarioData
58
+ ): Promise<WizardVideoInput> {
59
+ const prompt = (wizardData.prompt as string | undefined) || scenario.prompt || "";
60
+ const input: WizardVideoInput = {
61
+ prompt,
62
+ sourceImageBase64: typeof wizardData.sourceImageBase64 === 'string' ? wizardData.sourceImageBase64 : undefined,
63
+ targetImageBase64: typeof wizardData.targetImageBase64 === 'string' ? wizardData.targetImageBase64 : undefined,
64
+ duration: typeof wizardData.duration === 'number' ? wizardData.duration : undefined,
65
+ aspectRatio: typeof wizardData.aspectRatio === 'string' ? wizardData.aspectRatio : undefined,
66
+ resolution: typeof wizardData.resolution === 'string' ? wizardData.resolution : undefined,
67
+ audioUrl: typeof wizardData.audioUrl === 'string' ? wizardData.audioUrl : undefined,
68
+ qualityMode: wizardData.qualityMode === "draft" || wizardData.qualityMode === "normal" ? wizardData.qualityMode : undefined,
69
+ };
70
+
71
+ return input;
72
+ }
73
+
@@ -32,3 +32,17 @@ export interface CreateVideoStrategyOptions {
32
32
  /** Credit cost for this generation - REQUIRED, determined by the app */
33
33
  readonly creditCost: number;
34
34
  }
35
+
36
+ export interface ExecutionResult {
37
+ success: boolean;
38
+ videoUrl?: string;
39
+ requestId?: string;
40
+ error?: string;
41
+ }
42
+
43
+ export interface SubmissionResult {
44
+ success: boolean;
45
+ requestId?: string;
46
+ model?: string;
47
+ error?: string;
48
+ }
@@ -2,10 +2,14 @@
2
2
  * Generic Photo Upload State Hook - Type Definitions
3
3
  */
4
4
 
5
- import type { UploadedImage } from "../../../../../presentation/hooks/generation/useAIGenerateState";
6
-
7
- // Re-export for use in this module
8
- export type { UploadedImage };
5
+ export interface UploadedImage {
6
+ uri: string;
7
+ base64?: string;
8
+ width?: number;
9
+ height?: number;
10
+ previewUrl?: string;
11
+ fileSize?: number;
12
+ }
9
13
 
10
14
  export interface PhotoUploadConfig {
11
15
  readonly maxFileSizeMB?: number;
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { useCallback, useRef, useEffect } from "react";
6
6
  import { useMedia, MediaQuality, MediaValidationError, MEDIA_CONSTANTS } from "@umituz/react-native-design-system/media";
7
- import type { UploadedImage } from "../../../../../presentation/hooks/generation/useAIGenerateState";
7
+ import type { UploadedImage } from "./types";
8
8
  import type { PhotoUploadConfig, PhotoUploadError, PhotoUploadTranslations } from "./types";
9
9
 
10
10
  export function usePhotoUploadStateLogic(
@@ -76,7 +76,7 @@ export function usePhotoBlockingGeneration(
76
76
  );
77
77
 
78
78
  const { generate, isGenerating } = useGenerationOrchestrator(strategy, {
79
- userId,
79
+ userId: userId || null,
80
80
  alertMessages,
81
81
  onSuccess: handleSuccess,
82
82
  onError: handleError,
@@ -109,15 +109,24 @@ export function extractInputMetadata(params: {
109
109
  readonly model: string;
110
110
  readonly prompt: string;
111
111
  readonly imageUrls?: string[];
112
+ readonly duration?: number;
113
+ readonly resolution?: string;
114
+ readonly aspectRatio?: string;
112
115
  }): {
113
116
  readonly model: string;
114
117
  readonly prompt: string;
115
118
  readonly imageUrls: string[];
119
+ readonly duration?: number;
120
+ readonly resolution?: string;
121
+ readonly aspectRatio?: string;
116
122
  } {
117
123
  return {
118
124
  model: params.model,
119
125
  prompt: params.prompt,
120
126
  imageUrls: params.imageUrls || [],
127
+ duration: params.duration,
128
+ resolution: params.resolution,
129
+ aspectRatio: params.aspectRatio,
121
130
  };
122
131
  }
123
132
 
@@ -39,7 +39,15 @@ export function useStartGeneration(
39
39
  let creationId: string | null = null;
40
40
  if (userId && prompt) {
41
41
  try {
42
- const { duration, resolution, aspectRatio } = extractInputMetadata(input);
42
+ const inputRecord = input as Record<string, unknown>;
43
+ const { duration, resolution, aspectRatio } = extractInputMetadata({
44
+ model: scenario.model || "",
45
+ prompt,
46
+ imageUrls: (inputRecord.imageUrls || inputRecord.image_url) as string[] | undefined,
47
+ duration: inputRecord.duration as number | undefined,
48
+ resolution: inputRecord.resolution as string | undefined,
49
+ aspectRatio: inputRecord.aspectRatio as string | undefined,
50
+ });
43
51
 
44
52
  const result = await persistence.saveAsProcessing(userId, {
45
53
  scenarioId: scenario.id,
@@ -11,6 +11,7 @@ export interface ImageToVideoFormState {
11
11
  animationStyle: AnimationStyleId;
12
12
  duration: VideoDuration;
13
13
  motionPrompt: string;
14
+ onError?: (error: string) => void;
14
15
  }
15
16
 
16
17
  export interface ImageToVideoFormActions {
@@ -58,6 +58,7 @@ export function useGeneration(options: UseGenerationOptions): UseGenerationRetur
58
58
  setProgress,
59
59
  setError,
60
60
  } = useImageToVideoGenerationInternal({
61
+ ...formState,
61
62
  onError: callbacks.onError,
62
63
  });
63
64
 
@@ -70,7 +70,7 @@ export function useGeneration(options: UseGenerationOptions): UseGenerationRetur
70
70
 
71
71
  // Use orchestrator
72
72
  const { generate, isGenerating, error } = useGenerationOrchestrator(strategy, {
73
- userId: userId ?? undefined,
73
+ userId: userId ?? null,
74
74
  alertMessages: DEFAULT_ALERT_MESSAGES,
75
75
  onSuccess: async (result) => {
76
76
  const imageUrls = result as string[];
@@ -101,8 +101,8 @@ export function useTextToVideoFeature(props: UseTextToVideoFeatureProps): UseTex
101
101
  return {
102
102
  success: true,
103
103
  requestId,
104
- videoUrl: (result as TextToVideoResult)?.videoUrl || null,
105
- thumbnailUrl: (result as TextToVideoResult)?.thumbnailUrl || null,
104
+ videoUrl: (result as TextToVideoResult)?.videoUrl || undefined,
105
+ thumbnailUrl: (result as TextToVideoResult)?.thumbnailUrl || undefined,
106
106
  };
107
107
  } catch (error) {
108
108
  const message = error instanceof Error ? error.message : "Generation failed";
@@ -62,7 +62,7 @@ export {
62
62
  export type {
63
63
  ValidationResult,
64
64
  StringValidationOptions,
65
- NumericValidationOptions,
65
+ NumberValidationOptions,
66
66
  } from "../infrastructure/validation/input-validator";
67
67
 
68
68
  // Orchestration
@@ -68,7 +68,7 @@ export async function executeImageFeature(
68
68
  if (!urlValidation.isValid) {
69
69
  return {
70
70
  success: false,
71
- error: `Invalid image URL received: ${urlValidation.errors.join(", ")}`
71
+ error: `Invalid image URL received: ${Object.values(urlValidation.errors).join(", ")}`
72
72
  };
73
73
  }
74
74
 
@@ -100,10 +100,11 @@ export async function executeMultiImageGeneration(
100
100
  if (typeof imageUrl === "string" && imageUrl.length > 0) {
101
101
  const urlValidation = validateURL(imageUrl);
102
102
  if (!urlValidation.isValid) {
103
- addGenerationLog(sid, TAG, `Invalid URL in response: ${urlValidation.errors.join(", ")}`, 'error');
103
+ const errorMsg = Object.values(urlValidation.errors).join(", ");
104
+ addGenerationLog(sid, TAG, `Invalid URL in response: ${errorMsg}`, 'error');
104
105
  return {
105
106
  success: false,
106
- error: `Invalid image URL received: ${urlValidation.errors.join(", ")}`,
107
+ error: `Invalid image URL received: ${errorMsg}`,
107
108
  logSessionId: sid,
108
109
  };
109
110
  }
@@ -54,7 +54,7 @@ export async function executeVideoFeature(
54
54
  if (!urlValidation.isValid) {
55
55
  return {
56
56
  success: false,
57
- error: `Invalid video URL received: ${urlValidation.errors.join(", ")}`
57
+ error: `Invalid video URL received: ${Object.values(urlValidation.errors).join(", ")}`
58
58
  };
59
59
  }
60
60
 
@@ -13,6 +13,10 @@ import { validateString, validateURL, validateBase64, type ValidationResult, typ
13
13
  * Validates prompt/input text for AI generation
14
14
  */
15
15
  export function validateAIPrompt(input: unknown): ValidationResult {
16
+ if (typeof input !== "string") {
17
+ return { isValid: false, errors: { type: "Prompt must be a string" } };
18
+ }
19
+
16
20
  const options: StringValidationOptions = {
17
21
  minLength: MIN_PROMPT_LENGTH,
18
22
  maxLength: MAX_PROMPT_LENGTH,
@@ -26,7 +30,7 @@ export function validateAIPrompt(input: unknown): ValidationResult {
26
30
  */
27
31
  export function validateImageData(input: unknown): ValidationResult {
28
32
  if (typeof input !== "string") {
29
- return { isValid: false, errors: ["Image data must be a string"] };
33
+ return { isValid: false, errors: { type: "Image data must be a string" } };
30
34
  }
31
35
 
32
36
  const trimmed = input.trim();
@@ -40,11 +44,11 @@ export function validateImageData(input: unknown): ValidationResult {
40
44
  if (trimmed.startsWith("data:image/")) {
41
45
  const parts = trimmed.split(",");
42
46
  if (parts.length !== 2) {
43
- return { isValid: false, errors: ["Invalid data URI format"] };
47
+ return { isValid: false, errors: { format: "Invalid data URI format" } };
44
48
  }
45
49
  const base64Part = parts[1];
46
50
  if (!base64Part || base64Part.length === 0) {
47
- return { isValid: false, errors: ["Invalid data URI: missing base64 data"] };
51
+ return { isValid: false, errors: { data: "Invalid data URI: missing base64 data" } };
48
52
  }
49
53
  return validateBase64(base64Part);
50
54
  }
@@ -57,7 +61,7 @@ export function validateImageData(input: unknown): ValidationResult {
57
61
 
58
62
  return {
59
63
  isValid: false,
60
- errors: ["Image data must be a URL, base64 data URI, or valid base64 string"],
64
+ errors: { format: "Image data must be a URL, base64 data URI, or valid base64 string" },
61
65
  };
62
66
  }
63
67
 
@@ -14,7 +14,7 @@ export function validateUserId(input: unknown): ValidationResult {
14
14
  maxLength: 100,
15
15
  pattern: /^[a-zA-Z0-9_-]+$/,
16
16
  };
17
- return validateString(input, options);
17
+ return validateString(typeof input === "string" ? input : String(input), options);
18
18
  }
19
19
 
20
20
  /**
@@ -25,6 +25,6 @@ export function validateCreationId(input: unknown): ValidationResult {
25
25
  minLength: 1,
26
26
  maxLength: 100,
27
27
  };
28
- return validateString(input, options);
28
+ return validateString(typeof input === "string" ? input : String(input), options);
29
29
  }
30
30
 
@@ -12,7 +12,7 @@ export {
12
12
  validateBase64,
13
13
  type ValidationResult,
14
14
  type StringValidationOptions,
15
- type NumericValidationOptions,
15
+ type NumberValidationOptions,
16
16
  } from "./base-validator";
17
17
 
18
18
  // Sanitizers
@@ -69,7 +69,7 @@ export const useDualImageGeneration = (
69
69
 
70
70
  // Use orchestrator for credit/error handling
71
71
  const orchestrator = useGenerationOrchestrator(strategy, {
72
- userId,
72
+ userId: userId || null,
73
73
  alertMessages,
74
74
  onSuccess: async (result) => onSuccess?.(result as string),
75
75
  onError: async (error) => onError?.(error.message),
@@ -86,9 +86,9 @@ export const useImageGeneration = <TInput extends ImageGenerationInput, TResult>
86
86
  const handleError = useCallback((error: { message: string }) => onError?.(error.message), [onError]);
87
87
 
88
88
  return useGenerationOrchestrator(strategy, {
89
- userId,
89
+ userId: userId || null,
90
90
  alertMessages,
91
- onSuccess: onSuccess ? async (result) => onSuccess(result) : undefined,
91
+ onSuccess: onSuccess ? async (result) => onSuccess(result as TResult) : undefined,
92
92
  onError: async (error) => handleError(error),
93
93
  });
94
94
  };
@@ -101,9 +101,9 @@ export const useVideoGeneration = <TResult>(
101
101
  );
102
102
 
103
103
  return useGenerationOrchestrator(strategy, {
104
- userId,
104
+ userId: userId || null,
105
105
  alertMessages,
106
- onSuccess: onSuccess ? async (result) => onSuccess(result) : undefined,
106
+ onSuccess: onSuccess ? async (result) => onSuccess(result as TResult) : undefined,
107
107
  onError: async (error) => handleError(error),
108
108
  });
109
109
  };