@umituz/react-native-ai-generation-content 1.75.3 → 1.75.4

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.75.3",
3
+ "version": "1.75.4",
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",
@@ -61,25 +61,41 @@ export async function executeVideoGeneration(
61
61
  });
62
62
  }
63
63
 
64
+ // Detect Minimax subject reference model
65
+ const isSubjectReference = model.includes("minimax") || model.includes("hailuo");
66
+
64
67
  const modelInput: Record<string, unknown> = {
65
68
  prompt: input.prompt,
66
69
  };
67
70
 
68
- // Add image for image-to-video (Sora 2, etc.)
69
- // Only add if sourceImage is defined and not empty
70
- if (sourceImage && sourceImage.length > 0) {
71
- modelInput.image_url = sourceImage;
72
- }
73
-
74
- // Add optional parameters
75
- if (input.duration) {
76
- modelInput.duration = input.duration;
77
- }
78
- if (input.aspectRatio) {
79
- modelInput.aspect_ratio = input.aspectRatio;
80
- }
81
- if (input.resolution) {
82
- modelInput.resolution = input.resolution;
71
+ if (isSubjectReference) {
72
+ // Minimax Hailuo: Use subject_reference_image_url for face/identity only
73
+ if (sourceImage && sourceImage.length > 0) {
74
+ modelInput.subject_reference_image_url = sourceImage;
75
+ }
76
+ modelInput.prompt_optimizer = true;
77
+ // Minimax expects duration as string
78
+ if (input.duration) {
79
+ modelInput.duration = String(input.duration);
80
+ }
81
+ // Minimax uses uppercase resolution format (512P, 768P)
82
+ if (input.resolution) {
83
+ modelInput.resolution = input.resolution;
84
+ }
85
+ } else {
86
+ // Standard models (Grok, etc.): Use image_url
87
+ if (sourceImage && sourceImage.length > 0) {
88
+ modelInput.image_url = sourceImage;
89
+ }
90
+ if (input.duration) {
91
+ modelInput.duration = input.duration;
92
+ }
93
+ if (input.aspectRatio) {
94
+ modelInput.aspect_ratio = input.aspectRatio;
95
+ }
96
+ if (input.resolution) {
97
+ modelInput.resolution = input.resolution;
98
+ }
83
99
  }
84
100
 
85
101
  let lastStatus = "";
@@ -131,25 +147,36 @@ export async function submitVideoGenerationToQueue(
131
147
  try {
132
148
  const sourceImage = formatBase64(input.sourceImageBase64);
133
149
 
150
+ const isSubjectReference = model.includes("minimax") || model.includes("hailuo");
151
+
134
152
  const modelInput: Record<string, unknown> = {
135
153
  prompt: input.prompt,
136
154
  };
137
155
 
138
- // Add image for image-to-video
139
- // Only add if sourceImage is defined and not empty
140
- if (sourceImage && sourceImage.length > 0) {
141
- modelInput.image_url = sourceImage;
142
- }
143
-
144
- // Add optional parameters
145
- if (input.duration) {
146
- modelInput.duration = input.duration;
147
- }
148
- if (input.aspectRatio) {
149
- modelInput.aspect_ratio = input.aspectRatio;
150
- }
151
- if (input.resolution) {
152
- modelInput.resolution = input.resolution;
156
+ if (isSubjectReference) {
157
+ if (sourceImage && sourceImage.length > 0) {
158
+ modelInput.subject_reference_image_url = sourceImage;
159
+ }
160
+ modelInput.prompt_optimizer = true;
161
+ if (input.duration) {
162
+ modelInput.duration = String(input.duration);
163
+ }
164
+ if (input.resolution) {
165
+ modelInput.resolution = input.resolution;
166
+ }
167
+ } else {
168
+ if (sourceImage && sourceImage.length > 0) {
169
+ modelInput.image_url = sourceImage;
170
+ }
171
+ if (input.duration) {
172
+ modelInput.duration = input.duration;
173
+ }
174
+ if (input.aspectRatio) {
175
+ modelInput.aspect_ratio = input.aspectRatio;
176
+ }
177
+ if (input.resolution) {
178
+ modelInput.resolution = input.resolution;
179
+ }
153
180
  }
154
181
 
155
182
  const submission = await provider.submitJob(model, modelInput);
@@ -55,10 +55,10 @@ export function extractDuration(value: unknown): number | undefined {
55
55
  * @param value - Raw value from customData
56
56
  * @returns Normalized resolution string, or undefined if invalid
57
57
  */
58
- export function extractResolution(value: unknown): "480p" | "720p" | undefined {
58
+ export function extractResolution(value: unknown): string | undefined {
59
59
  const unwrapped = unwrapSelection(value);
60
60
 
61
- if (unwrapped === "480p" || unwrapped === "720p") {
61
+ if (typeof unwrapped === "string" && unwrapped.length > 0) {
62
62
  return unwrapped;
63
63
  }
64
64
  return undefined;
@@ -43,12 +43,12 @@ export function validateDuration(
43
43
  */
44
44
  export function validateResolution(
45
45
  data: Record<string, unknown>,
46
- ): ValidationResult<"480p" | "720p"> {
46
+ ): ValidationResult<string> {
47
47
  const resolution = extractResolution(data.resolution);
48
48
 
49
49
  if (!resolution) {
50
50
  return {
51
- error: `Invalid resolution: ${JSON.stringify(data.resolution)}. Must be "480p" or "720p".`,
51
+ error: `Invalid resolution: ${JSON.stringify(data.resolution)}. Must be a valid resolution string.`,
52
52
  };
53
53
  }
54
54
 
@@ -98,7 +98,9 @@ export function useWizardFlowHandlers(props: UseWizardFlowHandlersProps) {
98
98
  const nextStepDef = flowSteps[currentStepIndex + 1];
99
99
  // Merge additionalData to avoid stale closure issue
100
100
  // When called from handlePhotoContinue, customData in closure may not include the just-set value
101
- const mergedData = additionalData ? { ...customData, ...additionalData } : customData;
101
+ // Guard: Only merge plain objects (ignore SyntheticEvents from onPress handlers)
102
+ const isPlainObject = additionalData && typeof additionalData === "object" && !("nativeEvent" in additionalData) && !Array.isArray(additionalData);
103
+ const mergedData = isPlainObject ? { ...customData, ...additionalData } : customData;
102
104
  if (typeof __DEV__ !== "undefined" && __DEV__) {
103
105
  console.log("[handleNextStep] Called", {
104
106
  currentStepIndex,