@umituz/react-native-ai-generation-content 1.33.0 → 1.33.2
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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.33.
|
|
3
|
+
"version": "1.33.2",
|
|
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",
|
package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts
CHANGED
|
@@ -43,11 +43,24 @@ export interface VideoGenerationResult {
|
|
|
43
43
|
async function extractPhotosFromWizardData(
|
|
44
44
|
wizardData: Record<string, unknown>,
|
|
45
45
|
): Promise<string[]> {
|
|
46
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
47
|
+
console.log("[VideoStrategy:extractPhotos] Starting extraction", {
|
|
48
|
+
wizardDataKeys: Object.keys(wizardData),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
46
52
|
const photoKeys = Object.keys(wizardData)
|
|
47
53
|
.filter((k) => k.includes(PHOTO_KEY_PREFIX))
|
|
48
54
|
.sort();
|
|
49
55
|
|
|
56
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
57
|
+
console.log("[VideoStrategy:extractPhotos] Found photo keys", { photoKeys });
|
|
58
|
+
}
|
|
59
|
+
|
|
50
60
|
if (photoKeys.length === 0) {
|
|
61
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
62
|
+
console.log("[VideoStrategy:extractPhotos] No photo keys found");
|
|
63
|
+
}
|
|
51
64
|
return [];
|
|
52
65
|
}
|
|
53
66
|
|
|
@@ -56,15 +69,35 @@ async function extractPhotosFromWizardData(
|
|
|
56
69
|
const photo = wizardData[key] as { uri?: string };
|
|
57
70
|
if (photo?.uri) {
|
|
58
71
|
photoUris.push(photo.uri);
|
|
72
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
73
|
+
console.log("[VideoStrategy:extractPhotos] Found photo URI", { key, uri: photo.uri.substring(0, 50) + "..." });
|
|
74
|
+
}
|
|
59
75
|
}
|
|
60
76
|
}
|
|
61
77
|
|
|
62
78
|
if (photoUris.length === 0) {
|
|
79
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
80
|
+
console.log("[VideoStrategy:extractPhotos] No photo URIs found");
|
|
81
|
+
}
|
|
63
82
|
return [];
|
|
64
83
|
}
|
|
65
84
|
|
|
85
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
86
|
+
console.log("[VideoStrategy:extractPhotos] Converting to base64", { count: photoUris.length });
|
|
87
|
+
}
|
|
88
|
+
|
|
66
89
|
const photosBase64 = await Promise.all(photoUris.map((uri) => readFileAsBase64(uri)));
|
|
67
|
-
|
|
90
|
+
const validPhotos = photosBase64.filter(Boolean) as string[];
|
|
91
|
+
|
|
92
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
93
|
+
console.log("[VideoStrategy:extractPhotos] Converted photos", {
|
|
94
|
+
total: photoUris.length,
|
|
95
|
+
valid: validPhotos.length,
|
|
96
|
+
sizes: validPhotos.map((p) => `${(p.length / 1024).toFixed(1)}KB`),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return validPhotos;
|
|
68
101
|
}
|
|
69
102
|
|
|
70
103
|
// ============================================================================
|
|
@@ -91,20 +124,52 @@ export async function buildVideoInput(
|
|
|
91
124
|
wizardData: Record<string, unknown>,
|
|
92
125
|
scenario: WizardScenarioData,
|
|
93
126
|
): Promise<VideoGenerationInput | null> {
|
|
127
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
128
|
+
console.log("[VideoStrategy:buildInput] START", {
|
|
129
|
+
scenarioId: scenario.id,
|
|
130
|
+
outputType: scenario.outputType,
|
|
131
|
+
hasAiPrompt: !!scenario.aiPrompt,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
94
135
|
const photos = await extractPhotosFromWizardData(wizardData);
|
|
95
136
|
|
|
137
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
138
|
+
console.log("[VideoStrategy:buildInput] Photos extracted", {
|
|
139
|
+
count: photos.length,
|
|
140
|
+
hasSource: !!photos[0],
|
|
141
|
+
hasTarget: !!photos[1],
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
96
145
|
// Extract prompt using type-safe extractor with fallback
|
|
97
146
|
let prompt = extractPrompt(wizardData, scenario.aiPrompt);
|
|
98
147
|
|
|
148
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
149
|
+
console.log("[VideoStrategy:buildInput] Prompt from wizard", {
|
|
150
|
+
hasPrompt: !!prompt,
|
|
151
|
+
promptLength: prompt?.length ?? 0,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
99
155
|
// For video processing features, use default prompt if none provided
|
|
100
156
|
if (!prompt) {
|
|
101
157
|
const defaultPrompt = VIDEO_PROCESSING_PROMPTS[scenario.id];
|
|
102
158
|
if (defaultPrompt) {
|
|
103
159
|
prompt = defaultPrompt;
|
|
104
160
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
105
|
-
console.log("[VideoStrategy] Using default prompt
|
|
161
|
+
console.log("[VideoStrategy:buildInput] Using default prompt", {
|
|
162
|
+
scenarioId: scenario.id,
|
|
163
|
+
prompt: prompt.substring(0, 50) + "...",
|
|
164
|
+
});
|
|
106
165
|
}
|
|
107
166
|
} else {
|
|
167
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
168
|
+
console.log("[VideoStrategy:buildInput] ERROR: No prompt available", {
|
|
169
|
+
scenarioId: scenario.id,
|
|
170
|
+
availablePrompts: Object.keys(VIDEO_PROCESSING_PROMPTS),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
108
173
|
throw new Error("Prompt is required for video generation");
|
|
109
174
|
}
|
|
110
175
|
}
|
|
@@ -114,7 +179,7 @@ export async function buildVideoInput(
|
|
|
114
179
|
const aspectRatio = extractAspectRatio(wizardData);
|
|
115
180
|
const resolution = extractResolution(wizardData);
|
|
116
181
|
|
|
117
|
-
|
|
182
|
+
const input: VideoGenerationInput = {
|
|
118
183
|
sourceImageBase64: photos[0],
|
|
119
184
|
targetImageBase64: photos[1] || photos[0],
|
|
120
185
|
prompt,
|
|
@@ -122,6 +187,21 @@ export async function buildVideoInput(
|
|
|
122
187
|
aspectRatio,
|
|
123
188
|
resolution,
|
|
124
189
|
};
|
|
190
|
+
|
|
191
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
192
|
+
console.log("[VideoStrategy:buildInput] COMPLETE", {
|
|
193
|
+
hasSource: !!input.sourceImageBase64,
|
|
194
|
+
hasTarget: !!input.targetImageBase64,
|
|
195
|
+
sourceSize: input.sourceImageBase64 ? `${(input.sourceImageBase64.length / 1024).toFixed(1)}KB` : "N/A",
|
|
196
|
+
targetSize: input.targetImageBase64 ? `${(input.targetImageBase64.length / 1024).toFixed(1)}KB` : "N/A",
|
|
197
|
+
prompt: input.prompt.substring(0, 50) + "...",
|
|
198
|
+
duration: input.duration,
|
|
199
|
+
aspectRatio: input.aspectRatio,
|
|
200
|
+
resolution: input.resolution,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return input;
|
|
125
205
|
}
|
|
126
206
|
|
|
127
207
|
// ============================================================================
|
|
@@ -138,6 +218,14 @@ export function createVideoStrategy(options: CreateVideoStrategyOptions): Wizard
|
|
|
138
218
|
const repository = createCreationsRepository(collectionName);
|
|
139
219
|
const videoFeatureType = getVideoFeatureType(scenario.id);
|
|
140
220
|
|
|
221
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
222
|
+
console.log("[VideoStrategy:create] Created strategy", {
|
|
223
|
+
scenarioId: scenario.id,
|
|
224
|
+
videoFeatureType,
|
|
225
|
+
collectionName,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
141
229
|
let lastInputRef: VideoGenerationInput | null = null;
|
|
142
230
|
|
|
143
231
|
return {
|
|
@@ -145,6 +233,15 @@ export function createVideoStrategy(options: CreateVideoStrategyOptions): Wizard
|
|
|
145
233
|
const videoInput = input as VideoGenerationInput;
|
|
146
234
|
lastInputRef = videoInput;
|
|
147
235
|
|
|
236
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
237
|
+
console.log("[VideoStrategy:execute] START", {
|
|
238
|
+
featureType: videoFeatureType,
|
|
239
|
+
hasSource: !!videoInput.sourceImageBase64,
|
|
240
|
+
hasTarget: !!videoInput.targetImageBase64,
|
|
241
|
+
prompt: videoInput.prompt.substring(0, 50) + "...",
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
148
245
|
const result = await executeVideoFeature(
|
|
149
246
|
videoFeatureType,
|
|
150
247
|
{
|
|
@@ -159,10 +256,28 @@ export function createVideoStrategy(options: CreateVideoStrategyOptions): Wizard
|
|
|
159
256
|
},
|
|
160
257
|
);
|
|
161
258
|
|
|
259
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
260
|
+
console.log("[VideoStrategy:execute] RESULT", {
|
|
261
|
+
success: result.success,
|
|
262
|
+
hasVideoUrl: !!result.videoUrl,
|
|
263
|
+
error: result.error,
|
|
264
|
+
requestId: result.requestId,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
162
268
|
if (!result.success || !result.videoUrl) {
|
|
269
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
270
|
+
console.log("[VideoStrategy:execute] FAILED", { error: result.error });
|
|
271
|
+
}
|
|
163
272
|
throw new Error(result.error || "Video generation failed");
|
|
164
273
|
}
|
|
165
274
|
|
|
275
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
276
|
+
console.log("[VideoStrategy:execute] SUCCESS", {
|
|
277
|
+
videoUrl: result.videoUrl.substring(0, 80) + "...",
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
166
281
|
return { videoUrl: result.videoUrl };
|
|
167
282
|
},
|
|
168
283
|
|
|
@@ -69,10 +69,10 @@ const INPUT_PATTERNS: Record<WizardInputType, RegExp[]> = {
|
|
|
69
69
|
* Returns SINGLE_IMAGE as safe default
|
|
70
70
|
*/
|
|
71
71
|
export const detectWizardInputType = (scenarioId: string): WizardInputType => {
|
|
72
|
-
// Check patterns in priority order: TEXT_INPUT,
|
|
73
|
-
// DUAL_IMAGE has no patterns - must be explicitly specified
|
|
72
|
+
// Check patterns in priority order: TEXT_INPUT, DUAL_IMAGE, DUAL_IMAGE_FACE, SINGLE_IMAGE
|
|
74
73
|
const checkOrder: WizardInputType[] = [
|
|
75
74
|
WizardInputType.TEXT_INPUT,
|
|
75
|
+
WizardInputType.DUAL_IMAGE,
|
|
76
76
|
WizardInputType.DUAL_IMAGE_FACE,
|
|
77
77
|
WizardInputType.SINGLE_IMAGE,
|
|
78
78
|
];
|
|
@@ -26,13 +26,28 @@ export async function executeVideoFeature(
|
|
|
26
26
|
request: VideoFeatureRequest,
|
|
27
27
|
options?: ExecuteVideoFeatureOptions,
|
|
28
28
|
): Promise<VideoFeatureResult> {
|
|
29
|
+
if (__DEV__) {
|
|
30
|
+
console.log(`[VideoExecutor:${featureType}] START`, {
|
|
31
|
+
hasSource: !!request.sourceImageBase64,
|
|
32
|
+
hasTarget: !!request.targetImageBase64,
|
|
33
|
+
promptLength: request.prompt?.length ?? 0,
|
|
34
|
+
options: request.options,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
const provider = providerRegistry.getActiveProvider();
|
|
30
39
|
|
|
31
40
|
if (!provider) {
|
|
41
|
+
if (__DEV__) {
|
|
42
|
+
console.log(`[VideoExecutor:${featureType}] ERROR: No provider`);
|
|
43
|
+
}
|
|
32
44
|
return { success: false, error: "No AI provider configured" };
|
|
33
45
|
}
|
|
34
46
|
|
|
35
47
|
if (!provider.isInitialized()) {
|
|
48
|
+
if (__DEV__) {
|
|
49
|
+
console.log(`[VideoExecutor:${featureType}] ERROR: Provider not initialized`);
|
|
50
|
+
}
|
|
36
51
|
return { success: false, error: "AI provider not initialized" };
|
|
37
52
|
}
|
|
38
53
|
|
|
@@ -41,7 +56,7 @@ export async function executeVideoFeature(
|
|
|
41
56
|
const model = provider.getVideoFeatureModel(featureType);
|
|
42
57
|
|
|
43
58
|
if (__DEV__) {
|
|
44
|
-
console.log(`[
|
|
59
|
+
console.log(`[VideoExecutor:${featureType}] Provider: ${provider.providerId}, Model: ${model}`);
|
|
45
60
|
}
|
|
46
61
|
|
|
47
62
|
try {
|
|
@@ -52,31 +67,74 @@ export async function executeVideoFeature(
|
|
|
52
67
|
options: request.options,
|
|
53
68
|
};
|
|
54
69
|
|
|
70
|
+
if (__DEV__) {
|
|
71
|
+
console.log(`[VideoExecutor:${featureType}] InputData prepared`, {
|
|
72
|
+
sourceSize: inputData.sourceImageBase64 ? `${(inputData.sourceImageBase64.length / 1024).toFixed(1)}KB` : "N/A",
|
|
73
|
+
targetSize: inputData.targetImageBase64 ? `${(inputData.targetImageBase64.length / 1024).toFixed(1)}KB` : "N/A",
|
|
74
|
+
prompt: inputData.prompt?.substring(0, 50) + "...",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
55
78
|
const input = provider.buildVideoFeatureInput(featureType, inputData);
|
|
56
79
|
|
|
80
|
+
if (__DEV__) {
|
|
81
|
+
console.log(`[VideoExecutor:${featureType}] Built input for API`, {
|
|
82
|
+
inputKeys: Object.keys(input),
|
|
83
|
+
hasImageUrl: !!(input as Record<string, unknown>).image_url,
|
|
84
|
+
hasPrompt: !!(input as Record<string, unknown>).prompt,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let statusCount = 0;
|
|
57
89
|
const result = await provider.subscribe(model, input, {
|
|
58
90
|
timeoutMs: VIDEO_TIMEOUT_MS,
|
|
59
91
|
onQueueUpdate: (status) => {
|
|
60
|
-
|
|
61
|
-
|
|
92
|
+
statusCount++;
|
|
93
|
+
// Log every 10th status update to avoid spam
|
|
94
|
+
if (__DEV__ && statusCount % 10 === 1) {
|
|
95
|
+
console.log(`[VideoExecutor:${featureType}] Queue #${statusCount}:`, status.status);
|
|
62
96
|
}
|
|
63
97
|
onStatusChange?.(status.status);
|
|
64
98
|
},
|
|
65
99
|
});
|
|
66
100
|
|
|
101
|
+
if (__DEV__) {
|
|
102
|
+
console.log(`[VideoExecutor:${featureType}] API Response received`, {
|
|
103
|
+
totalStatusUpdates: statusCount,
|
|
104
|
+
resultKeys: result ? Object.keys(result as object) : "null",
|
|
105
|
+
resultType: typeof result,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
67
109
|
// Check for FAL API error in result (may return with COMPLETED status)
|
|
68
110
|
checkFalApiError(result);
|
|
69
111
|
|
|
70
112
|
const extractor = extractResult ?? extractVideoResult;
|
|
71
113
|
const videoUrl = extractor(result);
|
|
72
114
|
|
|
115
|
+
if (__DEV__) {
|
|
116
|
+
console.log(`[VideoExecutor:${featureType}] Extracted video URL`, {
|
|
117
|
+
hasVideoUrl: !!videoUrl,
|
|
118
|
+
urlPreview: videoUrl ? videoUrl.substring(0, 80) + "..." : "N/A",
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
73
122
|
if (!videoUrl) {
|
|
74
123
|
if (__DEV__) {
|
|
75
|
-
console.log(`[
|
|
124
|
+
console.log(`[VideoExecutor:${featureType}] FAILED: No video URL`, {
|
|
125
|
+
result: JSON.stringify(result).substring(0, 500),
|
|
126
|
+
});
|
|
76
127
|
}
|
|
77
128
|
return { success: false, error: "No video in response" };
|
|
78
129
|
}
|
|
79
130
|
|
|
131
|
+
if (__DEV__) {
|
|
132
|
+
console.log(`[VideoExecutor:${featureType}] SUCCESS`, {
|
|
133
|
+
videoUrl: videoUrl.substring(0, 80) + "...",
|
|
134
|
+
requestId: (result as { requestId?: string })?.requestId,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
80
138
|
return {
|
|
81
139
|
success: true,
|
|
82
140
|
videoUrl,
|
|
@@ -84,6 +142,12 @@ export async function executeVideoFeature(
|
|
|
84
142
|
};
|
|
85
143
|
} catch (error) {
|
|
86
144
|
const message = extractErrorMessage(error, "Processing failed", `Video:${featureType}`);
|
|
145
|
+
if (__DEV__) {
|
|
146
|
+
console.log(`[VideoExecutor:${featureType}] EXCEPTION`, {
|
|
147
|
+
error: message,
|
|
148
|
+
originalError: error instanceof Error ? error.message : String(error),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
87
151
|
return { success: false, error: message };
|
|
88
152
|
}
|
|
89
153
|
}
|