@umituz/react-native-ai-generation-content 1.90.2 → 1.90.3

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 (152) hide show
  1. package/package.json +1 -1
  2. package/src/domain/interfaces/app-services-auth.interface.ts +27 -0
  3. package/src/domain/interfaces/app-services-composite.interface.ts +29 -0
  4. package/src/domain/interfaces/app-services-optional.interface.ts +42 -0
  5. package/src/domain/interfaces/app-services.interface.ts +0 -79
  6. package/src/domains/background/infrastructure/services/job-poller-index.ts +7 -0
  7. package/src/domains/background/infrastructure/services/job-poller-utils.ts +130 -0
  8. package/src/domains/background/infrastructure/utils/polling-interval.util.ts +1 -1
  9. package/src/domains/background/presentation/hooks/use-background-generation.ts +1 -1
  10. package/src/domains/content-moderation/infrastructure/services/content-moderation.service.ts +1 -1
  11. package/src/domains/content-moderation/infrastructure/services/moderators/image.moderator.ts +34 -8
  12. package/src/domains/content-moderation/infrastructure/services/moderators/text.moderator.ts +15 -4
  13. package/src/domains/content-moderation/infrastructure/services/moderators/video.moderator.ts +34 -8
  14. package/src/domains/content-moderation/infrastructure/services/moderators/voice.moderator.ts +19 -8
  15. package/src/domains/creations/domain/types/creation-categories.constants.ts +57 -0
  16. package/src/domains/creations/domain/types/creation-categories.helpers.ts +67 -0
  17. package/src/domains/creations/domain/types/creation-categories.ts +5 -111
  18. package/src/domains/creations/presentation/hooks/creation-validators.ts +31 -29
  19. package/src/domains/creations/presentation/hooks/job-poller-index.ts +10 -0
  20. package/src/domains/creations/presentation/hooks/job-poller-utils.filters.ts +34 -0
  21. package/src/domains/creations/presentation/hooks/job-poller-utils.logger.ts +76 -0
  22. package/src/domains/creations/presentation/hooks/job-poller-utils.stale-handlers.ts +52 -0
  23. package/src/domains/creations/presentation/hooks/job-poller-utils.ts +8 -0
  24. package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +1 -1
  25. package/src/domains/creations/presentation-exports.ts +2 -2
  26. package/src/domains/face-detection/domain/entities/FaceDetection.ts +4 -3
  27. package/src/domains/face-detection/presentation/hooks/useFaceDetection.ts +24 -21
  28. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-preparation.ts +58 -0
  29. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-prompt.ts +69 -0
  30. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-resolution.ts +77 -0
  31. package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple.ts +54 -0
  32. package/src/domains/generation/infrastructure/couple-generation-builder/builder-index.ts +8 -0
  33. package/src/domains/generation/infrastructure/couple-generation-builder/builder-scenario.ts +113 -0
  34. package/src/domains/generation/infrastructure/couple-generation-builder/builder.ts +7 -0
  35. package/src/domains/generation/infrastructure/couple-generation-builder/index.ts +20 -0
  36. package/src/domains/generation/infrastructure/couple-generation-builder/types.ts +44 -0
  37. package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-end-logger.ts +18 -0
  38. package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-start-logger.ts +57 -0
  39. package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-step-logger.ts +106 -0
  40. package/src/domains/generation/infrastructure/couple-generation-builder/utils/index.ts +8 -0
  41. package/src/domains/generation/infrastructure/couple-generation-builder/utils/types.ts +49 -0
  42. package/src/domains/generation/infrastructure/couple-generation-builder/utils.ts +8 -0
  43. package/src/domains/generation/infrastructure/flow/flow-store-actions.ts +105 -0
  44. package/src/domains/generation/infrastructure/flow/flow-store-initial-state.ts +26 -0
  45. package/src/domains/generation/infrastructure/flow/useFlowStore.ts +4 -116
  46. package/src/domains/generation/presentation/useAIGeneration.hook.ts +1 -1
  47. package/src/domains/generation/wizard/infrastructure/strategies/image-generation-strategy-index.ts +7 -0
  48. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.ts +2 -12
  49. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.types.ts +11 -0
  50. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.utils.ts +12 -0
  51. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +1 -220
  52. package/src/domains/generation/wizard/infrastructure/strategies/image-input-builder.ts +66 -0
  53. package/src/domains/generation/wizard/infrastructure/strategies/image-input-extraction.ts +88 -0
  54. package/src/domains/generation/wizard/infrastructure/strategies/image-input-prompt-builder.ts +75 -0
  55. package/src/domains/generation/wizard/infrastructure/strategies/image-input-style-enhancements.ts +35 -0
  56. package/src/domains/generation/wizard/infrastructure/strategies/image-strategy-factory.ts +42 -0
  57. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor-index.ts +11 -0
  58. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor.ts +76 -0
  59. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-input-builder.ts +46 -0
  60. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-result-types.ts +17 -0
  61. package/src/domains/generation/wizard/infrastructure/strategies/video-generation-submission.ts +62 -0
  62. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.audio-extractor.ts +27 -0
  63. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.executor.ts +2 -175
  64. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.input-builder.ts +90 -0
  65. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +3 -108
  66. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.types.ts +0 -129
  67. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.validation.ts +136 -0
  68. package/src/domains/generation/wizard/presentation/hooks/photo-upload/index.ts +39 -0
  69. package/src/domains/generation/wizard/presentation/hooks/photo-upload/types.ts +37 -0
  70. package/src/domains/generation/wizard/presentation/hooks/photo-upload/usePhotoUploadStateLogic.ts +142 -0
  71. package/src/domains/generation/wizard/presentation/hooks/use-video-queue-utils.ts +103 -0
  72. package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.handlers.ts +97 -0
  73. package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.saver.ts +54 -0
  74. package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.ts +22 -87
  75. package/src/domains/generation/wizard/presentation/hooks/usePhotoUploadState.ts +8 -177
  76. package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +1 -295
  77. package/src/domains/generation/wizard/presentation/hooks/useWizardGeneration.ts +1 -1
  78. package/src/domains/generation/wizard/presentation/hooks/video-queue/index.ts +82 -0
  79. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationCallbacks.ts +120 -0
  80. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationPolling.ts +76 -0
  81. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationRefs.ts +65 -0
  82. package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationStart.ts +123 -0
  83. package/src/domains/generation/wizard/presentation/hooks/video-queue-index.ts +9 -0
  84. package/src/domains/image-to-video/domain/types/image-to-video-state.types.ts +11 -4
  85. package/src/domains/text-to-image/domain/types/text-to-image.types.ts +44 -22
  86. package/src/domains/text-to-video/domain/types/request.types.ts +33 -9
  87. package/src/domains/text-to-video/domain/types/state.types.ts +29 -9
  88. package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.handlers.ts +44 -0
  89. package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.ts +5 -51
  90. package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.types.ts +33 -0
  91. package/src/infrastructure/services/generation-orchestrator.service.ts +2 -2
  92. package/src/infrastructure/utils/couple-input-context.ts +13 -0
  93. package/src/infrastructure/utils/couple-input-index.ts +8 -0
  94. package/src/infrastructure/utils/couple-input-refiner.ts +101 -0
  95. package/src/infrastructure/utils/couple-input-resolver.ts +71 -0
  96. package/src/infrastructure/utils/couple-input-types.ts +14 -0
  97. package/src/infrastructure/utils/couple-input.util.ts +3 -176
  98. package/src/infrastructure/utils/photo-generation/photo-preparation.util.ts +1 -1
  99. package/src/infrastructure/validation/base-validator.ts +1 -27
  100. package/src/infrastructure/validation/base-validator.types.ts +32 -0
  101. package/src/presentation/hooks/generation/index.ts +1 -1
  102. package/src/presentation/hooks/generation/orchestrator-abort-logs.ts +48 -0
  103. package/src/presentation/hooks/generation/orchestrator-execution-logs.ts +67 -0
  104. package/src/presentation/hooks/generation/orchestrator-index.ts +14 -0
  105. package/src/presentation/hooks/generation/orchestrator-start-logs.ts +65 -0
  106. package/src/presentation/hooks/generation/orchestrator-state-utils.ts +17 -0
  107. package/src/presentation/hooks/generation/orchestrator-types.ts +55 -0
  108. package/src/presentation/hooks/generation/orchestrator-utils-index.ts +29 -0
  109. package/src/presentation/hooks/generation/orchestrator-utils.ts +25 -0
  110. package/src/presentation/hooks/generation/useDualImageGeneration.ts +1 -1
  111. package/src/presentation/hooks/generation/useImageGeneration.ts +1 -1
  112. package/src/presentation/hooks/generation/useVideoGeneration.ts +1 -1
  113. package/src/shared/hooks/factories/generation-hook-index.ts +12 -0
  114. package/src/shared/hooks/factories/generation-hook-types.ts +47 -0
  115. package/src/shared/hooks/factories/generation-hook-utils.ts +94 -0
  116. package/src/shared/hooks/factories/index.ts +1 -1
  117. package/src/shared/index.ts +1 -1
  118. package/src/shared/utils/calculations/aspect-ratio-calculations.ts +30 -0
  119. package/src/shared/utils/calculations/base64-calculations.ts +26 -0
  120. package/src/shared/utils/calculations/confidence-calculations.ts +21 -0
  121. package/src/shared/utils/calculations/cost-calculations-index.ts +43 -0
  122. package/src/shared/utils/calculations/cost-calculations.ts +25 -0
  123. package/src/shared/utils/calculations/credit-calculations.ts +37 -0
  124. package/src/shared/utils/calculations/index.ts +46 -0
  125. package/src/shared/utils/calculations/math-utilities.ts +32 -0
  126. package/src/shared/utils/calculations/memory-calculations.ts +33 -0
  127. package/src/shared/utils/calculations/pagination-calculations.ts +38 -0
  128. package/src/shared/utils/calculations/percentage-calculations.ts +33 -0
  129. package/src/shared/utils/calculations/time-calculations.ts +99 -0
  130. package/src/shared/utils/credit.ts +1 -1
  131. package/src/shared-kernel/application/hooks/index.ts +8 -0
  132. package/src/shared-kernel/application/hooks/use-feature-state.ts +107 -0
  133. package/src/shared-kernel/application/hooks/use-generation-handler.ts +110 -0
  134. package/src/shared-kernel/base-types/base-callbacks.types.ts +73 -0
  135. package/src/shared-kernel/base-types/base-feature-state.types.ts +77 -0
  136. package/src/shared-kernel/base-types/base-generation.types.ts +69 -0
  137. package/src/shared-kernel/base-types/index.ts +30 -0
  138. package/src/shared-kernel/domain/base-generation-strategy.ts +146 -0
  139. package/src/shared-kernel/domain/index.ts +7 -0
  140. package/src/shared-kernel/index.ts +17 -0
  141. package/src/shared-kernel/infrastructure/validation/common-validators.ts +126 -0
  142. package/src/shared-kernel/infrastructure/validation/common-validators.types.ts +33 -0
  143. package/src/shared-kernel/infrastructure/validation/error-handler.ts +52 -0
  144. package/src/shared-kernel/infrastructure/validation/error-handler.types.ts +38 -0
  145. package/src/shared-kernel/infrastructure/validation/error-handler.utils.ts +79 -0
  146. package/src/shared-kernel/infrastructure/validation/index.ts +28 -0
  147. package/src/domains/background/infrastructure/services/job-poller.service.ts +0 -234
  148. package/src/domains/creations/presentation/hooks/useProcessingJobsPoller.ts +0 -256
  149. package/src/domains/generation/infrastructure/couple-generation-builder.ts +0 -374
  150. package/src/presentation/hooks/generation/orchestrator.ts +0 -276
  151. package/src/shared/hooks/factories/createGenerationHook.ts +0 -253
  152. package/src/shared/utils/calculations.util.ts +0 -366
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Image Generation Strategy - Data Extraction
3
+ *
4
+ * Handles photo and prompt extraction from wizard data
5
+ */
6
+
7
+ import type { WizardScenarioData } from "../../presentation/hooks/useWizardGeneration";
8
+ import { IMAGE_PROCESSING_PROMPTS } from "./wizard-strategy.constants";
9
+ import { extractPrompt } from "../utils";
10
+ import { extractPhotosAsBase64, extractPhotoUris } from "./shared/photo-extraction.utils";
11
+
12
+ export interface ImageExtractionResult {
13
+ photoUris: string[];
14
+ photos: string[];
15
+ prompt: string;
16
+ }
17
+
18
+ /**
19
+ * Extract photos and prompt from wizard data
20
+ */
21
+ export async function extractImageData(
22
+ wizardData: Record<string, unknown>,
23
+ scenario: WizardScenarioData,
24
+ ): Promise<ImageExtractionResult> {
25
+ const DEV = typeof __DEV__ !== "undefined" && __DEV__;
26
+
27
+ if (DEV) {
28
+ console.log("[ImageStrategy] ===== EXTRACTION START =====");
29
+ console.log("[ImageStrategy] Scenario ID:", scenario.id);
30
+ console.log("[ImageStrategy] ===== WIZARD DATA KEYS =====");
31
+ const wizardKeys = Object.keys(wizardData);
32
+ console.log("[ImageStrategy] Total keys:", wizardKeys.length);
33
+ console.log("[ImageStrategy] Keys:", wizardKeys.slice(0, 20).join(", ") + (wizardKeys.length > 20 ? "..." : ""));
34
+
35
+ // Log photo-related keys
36
+ const photoKeys = wizardKeys.filter(k => k.includes("photo"));
37
+ if (photoKeys.length > 0) {
38
+ console.log("[ImageStrategy] Photo-related keys:", photoKeys.join(", "));
39
+ }
40
+
41
+ // Log selection/style keys
42
+ const selectionKeys = wizardKeys.filter(k => k.includes("selection") || k.includes("style"));
43
+ if (selectionKeys.length > 0) {
44
+ console.log("[ImageStrategy] Selection/style keys:", selectionKeys.join(", "));
45
+ }
46
+ }
47
+
48
+ // Extract photo URIs first (for couple refinement)
49
+ const photoUris = extractPhotoUris(wizardData);
50
+ const photos = await extractPhotosAsBase64(wizardData, DEV);
51
+
52
+ if (DEV) {
53
+ console.log("[ImageStrategy] ===== EXTRACTION COMPLETE =====");
54
+ console.log("[ImageStrategy] Photo URIs count:", photoUris.length);
55
+ console.log("[ImageStrategy] Base64 photos count:", photos.length);
56
+ }
57
+
58
+ // Extract prompt with fallback to default
59
+ let prompt = extractPrompt(wizardData, scenario.aiPrompt);
60
+
61
+ if (DEV) {
62
+ console.log("[ImageStrategy] ===== PROMPT EXTRACTION =====");
63
+ console.log("[ImageStrategy] Scenario aiPrompt type:", typeof scenario.aiPrompt);
64
+ console.log("[ImageStrategy] Scenario aiPrompt length:", typeof scenario.aiPrompt === "string" ? scenario.aiPrompt.length : "N/A");
65
+ if (typeof scenario.aiPrompt === "string") {
66
+ console.log("[ImageStrategy] Scenario aiPrompt preview:", scenario.aiPrompt.substring(0, 200) + "...");
67
+ }
68
+ console.log("[ImageStrategy] Extracted prompt type:", typeof prompt);
69
+ console.log("[ImageStrategy] Extracted prompt length:", prompt?.length ?? 0);
70
+ if (prompt) {
71
+ console.log("[ImageStrategy] Extracted prompt preview:", prompt.substring(0, 200) + "...");
72
+ }
73
+ }
74
+
75
+ if (!prompt) {
76
+ const defaultPrompt = IMAGE_PROCESSING_PROMPTS[scenario.id];
77
+ if (defaultPrompt) {
78
+ prompt = defaultPrompt;
79
+ if (DEV) {
80
+ console.log("[ImageStrategy] Using default prompt for scenario:", scenario.id);
81
+ }
82
+ } else {
83
+ throw new Error("Prompt is required for image generation");
84
+ }
85
+ }
86
+
87
+ return { photoUris, photos, prompt };
88
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Image Generation Strategy - Prompt Building
3
+ *
4
+ * Handles prompt enhancement and photorealistic prompt creation
5
+ */
6
+
7
+ import { enhancePromptWithAnalysis } from "../../../infrastructure/appearance-analysis";
8
+ import { createPhotorealisticPrompt } from "../../../../prompts/domain/base/creators";
9
+ import { applyStyleEnhancements } from "./image-input-style-enhancements";
10
+
11
+ export interface PromptBuildContext {
12
+ photos: string[];
13
+ photoUris: string[];
14
+ prompt: string;
15
+ wizardData: Record<string, unknown>;
16
+ }
17
+
18
+ /**
19
+ * Build final prompt with enhancements and photorealistic styling
20
+ */
21
+ export async function buildImagePrompt(
22
+ context: PromptBuildContext,
23
+ ): Promise<string> {
24
+ const { photos, photoUris, prompt, wizardData } = context;
25
+ const DEV = typeof __DEV__ !== "undefined" && __DEV__;
26
+
27
+ // Apply style enhancements for photo-based generation
28
+ if (photos.length === 0) {
29
+ return prompt;
30
+ }
31
+
32
+ const isCoupleMode = photos.length >= 2;
33
+ const styleEnhanced = applyStyleEnhancements(prompt, wizardData);
34
+
35
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
36
+ console.log("[ImageStrategy] ===== STRATEGY START =====");
37
+ console.log("[ImageStrategy] ===== PROMPT FLOW =====");
38
+ console.log("[ImageStrategy] [1/5] Original scenario prompt:");
39
+ console.log("[ImageStrategy] Length:", prompt.length);
40
+ console.log("[ImageStrategy] Preview:", prompt.substring(0, 150) + "...");
41
+ console.log("[ImageStrategy] [2/5] Style enhancements applied:", styleEnhanced !== prompt);
42
+ if (styleEnhanced !== prompt) {
43
+ console.log("[ImageStrategy] Enhanced preview:", styleEnhanced.substring(0, 150) + "...");
44
+ }
45
+ console.log("[ImageStrategy] [3/5] Couple mode:", isCoupleMode);
46
+ console.log("[ImageStrategy] Photo count:", photos.length);
47
+ console.log("[ImageStrategy] [4/5] Calling enhancePromptWithAnalysis...");
48
+ }
49
+
50
+ const refinedPrompt = await enhancePromptWithAnalysis(styleEnhanced, photoUris, isCoupleMode);
51
+
52
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
53
+ console.log("[ImageStrategy] After enhancePromptWithAnalysis:");
54
+ console.log("[ImageStrategy] Length:", refinedPrompt.length);
55
+ console.log("[ImageStrategy] Preview:", refinedPrompt.substring(0, 200) + "...");
56
+ console.log("[ImageStrategy] [5/5] Calling createPhotorealisticPrompt (Wardrobe style)...");
57
+ }
58
+
59
+ const finalPrompt = createPhotorealisticPrompt(refinedPrompt, {
60
+ isCouple: isCoupleMode,
61
+ customInstructions: undefined,
62
+ });
63
+
64
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
65
+ console.log("[ImageStrategy] ===== STRATEGY END =====");
66
+ console.log("[ImageStrategy] Final prompt length:", finalPrompt.length);
67
+ console.log("[ImageStrategy] Final prompt preview:");
68
+ console.log(finalPrompt.substring(0, 600) + "...");
69
+ console.log("[ImageStrategy] ===== OUTPUT =====");
70
+ console.log("[ImageStrategy] Photo count:", photos.length);
71
+ console.log("[ImageStrategy] Photo sizes:", photos.map((p, i) => `Photo ${i + 1}: ${(p.length / 1024).toFixed(2)}KB`));
72
+ }
73
+
74
+ return finalPrompt;
75
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Image Generation Strategy - Style Enhancements
3
+ *
4
+ * Applies style enhancements to the prompt
5
+ */
6
+
7
+ import { DEFAULT_STYLE_VALUE } from "./wizard-strategy.constants";
8
+ import { extractSelection } from "../utils";
9
+
10
+ /**
11
+ * Applies style enhancements to the prompt
12
+ */
13
+ export function applyStyleEnhancements(
14
+ prompt: string,
15
+ wizardData: Record<string, unknown>
16
+ ): string {
17
+ const enhancements: string[] = [];
18
+
19
+ const moodSelections = extractSelection(wizardData.selection_mood);
20
+ if (Array.isArray(moodSelections) && moodSelections.length > 0) {
21
+ enhancements.push(`Mood: ${moodSelections.join(", ")}`);
22
+ }
23
+
24
+ const artStyle = extractSelection(wizardData.selection_art_style);
25
+ if (typeof artStyle === "string" && artStyle !== DEFAULT_STYLE_VALUE) {
26
+ enhancements.push(`Art style: ${artStyle}`);
27
+ }
28
+
29
+ const artist = extractSelection(wizardData.selection_artist_style);
30
+ if (typeof artist === "string" && artist !== DEFAULT_STYLE_VALUE) {
31
+ enhancements.push(`Artist style: ${artist}`);
32
+ }
33
+
34
+ return enhancements.length > 0 ? `${prompt}. ${enhancements.join(", ")}` : prompt;
35
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Image Generation Strategy - Strategy Factory
3
+ */
4
+
5
+ import type { WizardScenarioData } from "../../presentation/hooks/useWizardGeneration";
6
+ import type { WizardStrategy } from "./wizard-strategy.types";
7
+ import type { CreateImageStrategyOptions } from "./image-generation.types";
8
+ import { executeImageGeneration } from "./image-generation.executor";
9
+ import type { WizardImageInput } from "./image-generation.types";
10
+
11
+ /**
12
+ * Create image generation strategy
13
+ */
14
+ export function createImageStrategy(options: CreateImageStrategyOptions): WizardStrategy {
15
+ const { scenario } = options;
16
+
17
+ // Validate model early - fail fast
18
+ if (!scenario.model) {
19
+ throw new Error("Model is required for image generation");
20
+ }
21
+
22
+ const model = scenario.model;
23
+ const providerId = scenario.providerId;
24
+
25
+ return {
26
+ execute: async (input: unknown) => {
27
+ if (!input || typeof input !== "object") {
28
+ throw new Error("Invalid input: expected WizardImageInput object");
29
+ }
30
+ const imageInput = input as WizardImageInput;
31
+ const result = await executeImageGeneration(imageInput, model, undefined, providerId);
32
+
33
+ if (!result.success || !result.imageUrl) {
34
+ const error = new Error(result.error || "Image generation failed");
35
+ (error as Error & { logSessionId?: string }).logSessionId = result.logSessionId;
36
+ throw error;
37
+ }
38
+
39
+ return { imageUrl: result.imageUrl, logSessionId: result.logSessionId };
40
+ },
41
+ };
42
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Video Generation Executor
3
+ * Handles the actual video generation execution.
4
+ * Model-agnostic: uses VideoModelConfig.buildInput() for model-specific parameters.
5
+ * Fallback: generic input builder when no modelConfig is provided.
6
+ */
7
+
8
+ export { executeVideoGeneration } from "./video-generation-executor";
9
+ export { submitVideoGenerationToQueue } from "./video-generation-submission";
10
+ export { buildGenericInput } from "./video-generation-input-builder";
11
+ export type { ExecutionResult, SubmissionResult } from "./video-generation-result-types";
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Video Generation Executor - Execution Functions
3
+ */
4
+
5
+ import type { WizardVideoInput } from "./video-generation.types";
6
+ import type { VideoModelConfig } from "../../../../../domain/interfaces/video-model-config.types";
7
+ import { VIDEO_GENERATION_TIMEOUT_MS } from "./wizard-strategy.constants";
8
+ import { createGenerationError, GenerationErrorType } from "../../../../../infrastructure/utils/error-factory";
9
+ import type { ExecutionResult } from "./video-generation.types";
10
+ import { buildGenericInput } from "./video-generation-input-builder";
11
+
12
+ /**
13
+ * Execute video generation using direct provider call
14
+ */
15
+ export async function executeVideoGeneration(
16
+ input: WizardVideoInput,
17
+ model: string,
18
+ onProgress?: (status: string) => void,
19
+ modelConfig?: VideoModelConfig,
20
+ providerId?: string,
21
+ ): Promise<ExecutionResult> {
22
+ const { resolveProvider } = await import("../../../../../infrastructure/services/provider-resolver");
23
+
24
+ let provider;
25
+ try {
26
+ provider = resolveProvider(providerId);
27
+ } catch {
28
+ const error = createGenerationError(
29
+ GenerationErrorType.VALIDATION,
30
+ "AI provider is not initialized. Please check your configuration."
31
+ );
32
+ return { success: false, error: error.message };
33
+ }
34
+
35
+ try {
36
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
37
+ console.log("[VideoExecutor] Generation starting", {
38
+ model,
39
+ hasModelConfig: !!modelConfig,
40
+ duration: input.duration,
41
+ resolution: input.resolution,
42
+ });
43
+ }
44
+
45
+ // Use modelConfig.buildInput() if available, otherwise generic fallback
46
+ const modelInput = modelConfig
47
+ ? modelConfig.buildInput(input)
48
+ : buildGenericInput(input);
49
+
50
+ let lastStatus = "";
51
+ const result = await provider.subscribe(model, modelInput, {
52
+ timeoutMs: VIDEO_GENERATION_TIMEOUT_MS,
53
+ onQueueUpdate: (status) => {
54
+ if (status.status !== lastStatus) {
55
+ lastStatus = status.status;
56
+ onProgress?.(status.status);
57
+ }
58
+ },
59
+ });
60
+
61
+ const rawResult = result as Record<string, unknown>;
62
+ const data = (rawResult?.data ?? rawResult) as { video?: { url: string }; video_url?: string; url?: string };
63
+ // FAL returns { video: { url } }, Pruna returns { url }, some return { video_url }
64
+ const videoUrl = data?.video?.url ?? data?.video_url ?? data?.url;
65
+
66
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
67
+ console.log("[VideoExecutor] Generation completed", { success: !!videoUrl });
68
+ }
69
+
70
+ return videoUrl
71
+ ? { success: true, videoUrl, requestId: (rawResult as { requestId?: string })?.requestId }
72
+ : { success: false, error: "No video generated" };
73
+ } catch (error) {
74
+ return { success: false, error: error instanceof Error ? error.message : "Generation failed" };
75
+ }
76
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Video Generation Executor - Input Builder
3
+ */
4
+
5
+ import type { WizardVideoInput } from "./video-generation.types";
6
+ import { BASE64_IMAGE_PREFIX } from "./wizard-strategy.constants";
7
+
8
+ /**
9
+ * Format base64 string with data URI prefix if needed
10
+ */
11
+ function formatBase64(base64: string | undefined): string | undefined {
12
+ if (!base64) return undefined;
13
+ return base64.startsWith("data:") ? base64 : `${BASE64_IMAGE_PREFIX}${base64}`;
14
+ }
15
+
16
+ /**
17
+ * Generic input builder - used when no modelConfig is provided.
18
+ * Sends standard parameters without model-specific logic.
19
+ */
20
+ export function buildGenericInput(input: WizardVideoInput): Record<string, unknown> {
21
+ const modelInput: Record<string, unknown> = { prompt: input.prompt };
22
+ const sourceImage = formatBase64(input.sourceImageBase64);
23
+
24
+ if (sourceImage && sourceImage.length > 0) {
25
+ modelInput.image_url = sourceImage;
26
+ }
27
+ if (input.duration) {
28
+ modelInput.duration = input.duration;
29
+ }
30
+ if (input.aspectRatio) {
31
+ modelInput.aspect_ratio = input.aspectRatio;
32
+ }
33
+ if (input.resolution) {
34
+ modelInput.resolution = input.resolution;
35
+ }
36
+ if (input.audioUrl) {
37
+ modelInput.audio = input.audioUrl;
38
+ }
39
+
40
+ // Quality mode: "draft" → draft=true (faster, cheaper), "normal" → draft=false (higher quality)
41
+ if (input.qualityMode === "draft" || input.qualityMode === "normal") {
42
+ modelInput.draft = input.qualityMode === "draft";
43
+ }
44
+
45
+ return modelInput;
46
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Video Generation Executor - Type Definitions
3
+ */
4
+
5
+ export interface ExecutionResult {
6
+ success: boolean;
7
+ videoUrl?: string;
8
+ requestId?: string;
9
+ error?: string;
10
+ }
11
+
12
+ export interface SubmissionResult {
13
+ success: boolean;
14
+ requestId?: string;
15
+ model?: string;
16
+ error?: string;
17
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Video Generation Executor - Queue Submission
3
+ */
4
+
5
+ import type { WizardVideoInput } from "./video-generation.types";
6
+ import type { VideoModelConfig } from "../../../../../domain/interfaces/video-model-config.types";
7
+ import { createGenerationError, GenerationErrorType } from "../../../../../infrastructure/utils/error-factory";
8
+ import type { SubmissionResult } from "./video-generation.types";
9
+ import { buildGenericInput } from "./video-generation-input-builder";
10
+
11
+ /**
12
+ * Submit video generation to queue
13
+ * For background processing of video generation
14
+ */
15
+ export async function submitVideoGenerationToQueue(
16
+ input: WizardVideoInput,
17
+ model: string,
18
+ modelConfig?: VideoModelConfig,
19
+ providerId?: string,
20
+ ): Promise<SubmissionResult> {
21
+ const { resolveProvider } = await import("../../../../../infrastructure/services/provider-resolver");
22
+
23
+ let provider;
24
+ try {
25
+ provider = resolveProvider(providerId);
26
+ } catch {
27
+ const error = createGenerationError(
28
+ GenerationErrorType.VALIDATION,
29
+ "AI provider is not initialized. Please check your configuration."
30
+ );
31
+ return { success: false, error: error.message };
32
+ }
33
+
34
+ try {
35
+ // Use modelConfig.buildInput() if available, otherwise generic fallback
36
+ const modelInput = modelConfig
37
+ ? modelConfig.buildInput(input)
38
+ : buildGenericInput(input);
39
+
40
+ const submission = await provider.submitJob(model, modelInput);
41
+
42
+ return { success: true, requestId: submission.requestId, model };
43
+ } catch (error) {
44
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
45
+ console.error("[VideoExecutor] Queue submission error:", error);
46
+ }
47
+
48
+ let errorMessage = "Failed to submit video generation to queue. Please try again.";
49
+
50
+ if (error instanceof Error) {
51
+ const message = error.message.toLowerCase();
52
+
53
+ if (message.includes("network") || message.includes("connection")) {
54
+ errorMessage = "Network error. Please check your internet connection and try again.";
55
+ } else {
56
+ errorMessage = `Queue submission failed: ${error.message}`;
57
+ }
58
+ }
59
+
60
+ return { success: false, error: errorMessage };
61
+ }
62
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Video Generation Strategy - Audio Extractor
3
+ * Extracts audio from wizard data for video generation
4
+ */
5
+
6
+ import { readFileAsBase64 } from "@umituz/react-native-design-system/filesystem";
7
+
8
+ /**
9
+ * Extract audio from wizardData and read as base64.
10
+ * Audio step stores data as { uri: "file:///..." }.
11
+ */
12
+ export async function extractAudioAsBase64(wizardData: Record<string, unknown>): Promise<string | undefined> {
13
+ const audioData = wizardData.background_audio as { uri?: string } | undefined;
14
+ if (!audioData?.uri) return undefined;
15
+
16
+ try {
17
+ const base64 = await readFileAsBase64(audioData.uri);
18
+ if (!base64) return undefined;
19
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
20
+ console.log("[VideoStrategy] Audio extracted as base64", { length: base64.length });
21
+ }
22
+ return base64;
23
+ } catch (error) {
24
+ console.warn("[VideoStrategy] Failed to read audio file:", error);
25
+ return undefined;
26
+ }
27
+ }
@@ -5,178 +5,5 @@
5
5
  * Fallback: generic input builder when no modelConfig is provided.
6
6
  */
7
7
 
8
- import type { WizardVideoInput } from "./video-generation.types";
9
- import type { VideoModelConfig } from "../../../../../domain/interfaces/video-model-config.types";
10
- import { VIDEO_GENERATION_TIMEOUT_MS, BASE64_IMAGE_PREFIX } from "./wizard-strategy.constants";
11
- import { createGenerationError, GenerationErrorType } from "../../../../../infrastructure/utils/error-factory";
12
-
13
-
14
- interface ExecutionResult {
15
- success: boolean;
16
- videoUrl?: string;
17
- requestId?: string;
18
- error?: string;
19
- }
20
-
21
- interface SubmissionResult {
22
- success: boolean;
23
- requestId?: string;
24
- model?: string;
25
- error?: string;
26
- }
27
-
28
- function formatBase64(base64: string | undefined): string | undefined {
29
- if (!base64) return undefined;
30
- return base64.startsWith("data:") ? base64 : `${BASE64_IMAGE_PREFIX}${base64}`;
31
- }
32
-
33
- /**
34
- * Generic input builder - used when no modelConfig is provided.
35
- * Sends standard parameters without model-specific logic.
36
- */
37
- function buildGenericInput(input: WizardVideoInput): Record<string, unknown> {
38
- const modelInput: Record<string, unknown> = { prompt: input.prompt };
39
- const sourceImage = formatBase64(input.sourceImageBase64);
40
-
41
- if (sourceImage && sourceImage.length > 0) {
42
- modelInput.image_url = sourceImage;
43
- }
44
- if (input.duration) {
45
- modelInput.duration = input.duration;
46
- }
47
- if (input.aspectRatio) {
48
- modelInput.aspect_ratio = input.aspectRatio;
49
- }
50
- if (input.resolution) {
51
- modelInput.resolution = input.resolution;
52
- }
53
- if (input.audioUrl) {
54
- modelInput.audio = input.audioUrl;
55
- }
56
-
57
- // Quality mode: "draft" → draft=true (faster, cheaper), "normal" → draft=false (higher quality)
58
- if (input.qualityMode === "draft" || input.qualityMode === "normal") {
59
- modelInput.draft = input.qualityMode === "draft";
60
- }
61
-
62
- return modelInput;
63
- }
64
-
65
- /**
66
- * Execute video generation using direct provider call
67
- */
68
- export async function executeVideoGeneration(
69
- input: WizardVideoInput,
70
- model: string,
71
- onProgress?: (status: string) => void,
72
- modelConfig?: VideoModelConfig,
73
- providerId?: string,
74
- ): Promise<ExecutionResult> {
75
- const { resolveProvider } = await import("../../../../../infrastructure/services/provider-resolver");
76
-
77
- let provider;
78
- try {
79
- provider = resolveProvider(providerId);
80
- } catch {
81
- const error = createGenerationError(
82
- GenerationErrorType.VALIDATION,
83
- "AI provider is not initialized. Please check your configuration."
84
- );
85
- return { success: false, error: error.message };
86
- }
87
-
88
- try {
89
- if (typeof __DEV__ !== "undefined" && __DEV__) {
90
- console.log("[VideoExecutor] Generation starting", {
91
- model,
92
- hasModelConfig: !!modelConfig,
93
- duration: input.duration,
94
- resolution: input.resolution,
95
- });
96
- }
97
-
98
- // Use modelConfig.buildInput() if available, otherwise generic fallback
99
- const modelInput = modelConfig
100
- ? modelConfig.buildInput(input)
101
- : buildGenericInput(input);
102
-
103
- let lastStatus = "";
104
- const result = await provider.subscribe(model, modelInput, {
105
- timeoutMs: VIDEO_GENERATION_TIMEOUT_MS,
106
- onQueueUpdate: (status) => {
107
- if (status.status !== lastStatus) {
108
- lastStatus = status.status;
109
- onProgress?.(status.status);
110
- }
111
- },
112
- });
113
-
114
- const rawResult = result as Record<string, unknown>;
115
- const data = (rawResult?.data ?? rawResult) as { video?: { url: string }; video_url?: string; url?: string };
116
- // FAL returns { video: { url } }, Pruna returns { url }, some return { video_url }
117
- const videoUrl = data?.video?.url ?? data?.video_url ?? data?.url;
118
-
119
- if (typeof __DEV__ !== "undefined" && __DEV__) {
120
- console.log("[VideoExecutor] Generation completed", { success: !!videoUrl });
121
- }
122
-
123
- return videoUrl
124
- ? { success: true, videoUrl, requestId: (rawResult as { requestId?: string })?.requestId }
125
- : { success: false, error: "No video generated" };
126
- } catch (error) {
127
- return { success: false, error: error instanceof Error ? error.message : "Generation failed" };
128
- }
129
- }
130
-
131
- /**
132
- * Submit video generation to queue
133
- * For background processing of video generation
134
- */
135
- export async function submitVideoGenerationToQueue(
136
- input: WizardVideoInput,
137
- model: string,
138
- modelConfig?: VideoModelConfig,
139
- providerId?: string,
140
- ): Promise<SubmissionResult> {
141
- const { resolveProvider } = await import("../../../../../infrastructure/services/provider-resolver");
142
-
143
- let provider;
144
- try {
145
- provider = resolveProvider(providerId);
146
- } catch {
147
- const error = createGenerationError(
148
- GenerationErrorType.VALIDATION,
149
- "AI provider is not initialized. Please check your configuration."
150
- );
151
- return { success: false, error: error.message };
152
- }
153
-
154
- try {
155
- // Use modelConfig.buildInput() if available, otherwise generic fallback
156
- const modelInput = modelConfig
157
- ? modelConfig.buildInput(input)
158
- : buildGenericInput(input);
159
-
160
- const submission = await provider.submitJob(model, modelInput);
161
-
162
- return { success: true, requestId: submission.requestId, model };
163
- } catch (error) {
164
- if (typeof __DEV__ !== "undefined" && __DEV__) {
165
- console.error("[VideoExecutor] Queue submission error:", error);
166
- }
167
-
168
- let errorMessage = "Failed to submit video generation to queue. Please try again.";
169
-
170
- if (error instanceof Error) {
171
- const message = error.message.toLowerCase();
172
-
173
- if (message.includes("network") || message.includes("connection")) {
174
- errorMessage = "Network error. Please check your internet connection and try again.";
175
- } else {
176
- errorMessage = `Queue submission failed: ${error.message}`;
177
- }
178
- }
179
-
180
- return { success: false, error: errorMessage };
181
- }
182
- }
8
+ export { executeVideoGeneration, submitVideoGenerationToQueue, buildGenericInput } from "./video-generation-executor-index";
9
+ export type { ExecutionResult, SubmissionResult } from "./video-generation-executor-index";