@umituz/react-native-ai-generation-content 1.89.42 → 1.89.48
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 +1 -1
- package/src/domains/generation/infrastructure/appearance-analysis.ts +49 -3
- package/src/domains/generation/infrastructure/couple-generation-builder.ts +184 -4
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.ts +36 -6
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +113 -15
- package/src/infrastructure/utils/couple-input.util.ts +72 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.89.
|
|
3
|
+
"version": "1.89.48",
|
|
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",
|
|
@@ -16,9 +16,20 @@ import { refinePromptForCouple } from "../../../infrastructure/utils/couple-inpu
|
|
|
16
16
|
* @returns Appearance context string (şu an boş)
|
|
17
17
|
*/
|
|
18
18
|
export async function getAppearanceContext(
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
photoUris: string[],
|
|
20
|
+
isCoupleMode: boolean,
|
|
21
21
|
): Promise<string> {
|
|
22
|
+
const DEV = typeof __DEV__ !== "undefined" && __DEV__;
|
|
23
|
+
|
|
24
|
+
if (DEV) {
|
|
25
|
+
console.log("[AppearanceAnalysis] ===== ANALYSIS START =====");
|
|
26
|
+
console.log("[AppearanceAnalysis] Photo URIs:", photoUris.length);
|
|
27
|
+
console.log("[AppearanceAnalysis] Is couple mode:", isCoupleMode);
|
|
28
|
+
console.log("[AppearanceAnalysis] URIs:", photoUris.map((uri, i) => ` ${i + 1}. ${uri.substring(0, 60)}...`));
|
|
29
|
+
console.log("[AppearanceAnalysis] Vision analysis: DISABLED (returning empty context)");
|
|
30
|
+
console.log("[AppearanceAnalysis] ===== ANALYSIS END =====");
|
|
31
|
+
}
|
|
32
|
+
|
|
22
33
|
// Vision analysis temporarily disabled due to API limitations
|
|
23
34
|
// Future: Implement vision analysis to extract appearance features
|
|
24
35
|
return "";
|
|
@@ -39,15 +50,50 @@ export async function enhancePromptWithAnalysis(
|
|
|
39
50
|
photoUris: string[],
|
|
40
51
|
isCoupleMode: boolean,
|
|
41
52
|
): Promise<string> {
|
|
53
|
+
const DEV = typeof __DEV__ !== "undefined" && __DEV__;
|
|
54
|
+
|
|
55
|
+
if (DEV) {
|
|
56
|
+
console.log("[AppearanceAnalysis] ===== ENHANCE START =====");
|
|
57
|
+
console.log("[AppearanceAnalysis] Original prompt length:", originalPrompt.length);
|
|
58
|
+
console.log("[AppearanceAnalysis] Photo URIs:", photoUris.length);
|
|
59
|
+
console.log("[AppearanceAnalysis] Is couple mode:", isCoupleMode);
|
|
60
|
+
console.log("[AppearanceAnalysis] Original preview:", originalPrompt.substring(0, 200) + "...");
|
|
61
|
+
}
|
|
62
|
+
|
|
42
63
|
// Always apply basic couple refinement first
|
|
43
64
|
let finalPrompt = refinePromptForCouple(originalPrompt, isCoupleMode);
|
|
44
65
|
|
|
45
|
-
if (
|
|
66
|
+
if (DEV) {
|
|
67
|
+
console.log("[AppearanceAnalysis] After refinePromptForCouple length:", finalPrompt.length);
|
|
68
|
+
console.log("[AppearanceAnalysis] After refine preview:", finalPrompt.substring(0, 250) + "...");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (photoUris.length === 0) {
|
|
72
|
+
if (DEV) {
|
|
73
|
+
console.log("[AppearanceAnalysis] No photos - returning refined prompt");
|
|
74
|
+
console.log("[AppearanceAnalysis] ===== ENHANCE END =====");
|
|
75
|
+
}
|
|
76
|
+
return finalPrompt;
|
|
77
|
+
}
|
|
46
78
|
|
|
47
79
|
const appearanceContext = await getAppearanceContext(photoUris, isCoupleMode);
|
|
48
80
|
|
|
49
81
|
if (appearanceContext) {
|
|
50
82
|
finalPrompt = `${appearanceContext}\n\n${finalPrompt}`;
|
|
83
|
+
if (DEV) {
|
|
84
|
+
console.log("[AppearanceAnalysis] ✅ Appearance context prepended");
|
|
85
|
+
console.log("[AppearanceAnalysis] Context length:", appearanceContext.length);
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
if (DEV) {
|
|
89
|
+
console.log("[AppearanceAnalysis] ℹ️ No appearance context (vision disabled)");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (DEV) {
|
|
94
|
+
console.log("[AppearanceAnalysis] Final prompt length:", finalPrompt.length);
|
|
95
|
+
console.log("[AppearanceAnalysis] Final preview:", finalPrompt.substring(0, 300) + "...");
|
|
96
|
+
console.log("[AppearanceAnalysis] ===== ENHANCE END =====");
|
|
51
97
|
}
|
|
52
98
|
|
|
53
99
|
return finalPrompt;
|
|
@@ -73,6 +73,8 @@ export interface ScenarioGenerationInputParams {
|
|
|
73
73
|
export async function buildCoupleGenerationInput(
|
|
74
74
|
params: CoupleGenerationInputParams,
|
|
75
75
|
): Promise<CoupleGenerationInput> {
|
|
76
|
+
const DEV = typeof __DEV__ !== "undefined" && __DEV__;
|
|
77
|
+
|
|
76
78
|
const {
|
|
77
79
|
partner1PhotoUri,
|
|
78
80
|
partner2PhotoUri,
|
|
@@ -83,33 +85,122 @@ export async function buildCoupleGenerationInput(
|
|
|
83
85
|
strength,
|
|
84
86
|
} = params;
|
|
85
87
|
|
|
88
|
+
if (DEV) {
|
|
89
|
+
console.log("[CoupleBuilder] ========================================");
|
|
90
|
+
console.log("[CoupleBuilder] ===== BUILD COUPLE GENERATION START =====");
|
|
91
|
+
console.log("[CoupleBuilder] ========================================");
|
|
92
|
+
console.log("[CoupleBuilder] ===== INPUT PARAMS =====");
|
|
93
|
+
console.log("[CoupleBuilder] Is couple mode:", isCoupleMode);
|
|
94
|
+
console.log("[CoupleBuilder] Base prompt length:", basePrompt.length);
|
|
95
|
+
console.log("[CoupleBuilder] Base prompt preview:", basePrompt.substring(0, 200) + "...");
|
|
96
|
+
console.log("[CoupleBuilder] Aspect ratio:", aspectRatio);
|
|
97
|
+
console.log("[CoupleBuilder] Has partner 2:", !!partner2PhotoUri);
|
|
98
|
+
console.log("[CoupleBuilder] Has custom instructions:", !!customInstructions);
|
|
99
|
+
console.log("[CoupleBuilder] Has strength:", strength !== undefined);
|
|
100
|
+
if (strength !== undefined) {
|
|
101
|
+
console.log("[CoupleBuilder] Strength value:", strength);
|
|
102
|
+
}
|
|
103
|
+
console.log("[CoupleBuilder] Partner 1 URI:", partner1PhotoUri.substring(0, 80) + "...");
|
|
104
|
+
if (partner2PhotoUri) {
|
|
105
|
+
console.log("[CoupleBuilder] Partner 2 URI:", partner2PhotoUri.substring(0, 80) + "...");
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
86
109
|
// 1. GET PHOTO URIs - Couple mode kontrolü
|
|
87
110
|
const photoUris =
|
|
88
111
|
isCoupleMode && partner2PhotoUri
|
|
89
112
|
? [partner1PhotoUri, partner2PhotoUri]
|
|
90
113
|
: [partner1PhotoUri];
|
|
91
114
|
|
|
115
|
+
if (DEV) {
|
|
116
|
+
console.log("[CoupleBuilder] ===== STEP 1: PHOTO URIs =====");
|
|
117
|
+
console.log("[CoupleBuilder] Photo URIs count:", photoUris.length);
|
|
118
|
+
console.log("[CoupleBuilder] Photo 1:", photoUris[0].substring(0, 60) + "...");
|
|
119
|
+
if (photoUris.length > 1) {
|
|
120
|
+
console.log("[CoupleBuilder] Photo 2:", photoUris[1].substring(0, 60) + "...");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
92
124
|
// 2. ANALYZE APPEARANCE - Wardrobe'daki gibi
|
|
93
125
|
// Fotoğrafları analiz et ve context çıkar
|
|
126
|
+
if (DEV) {
|
|
127
|
+
console.log("[CoupleBuilder] ===== STEP 2: APPEARANCE ANALYSIS =====");
|
|
128
|
+
console.log("[CoupleBuilder] Calling getAppearanceContext with:", {
|
|
129
|
+
photoCount: photoUris.length,
|
|
130
|
+
isCoupleMode
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
94
134
|
const appearanceContext = await getAppearanceContext(
|
|
95
135
|
photoUris,
|
|
96
136
|
isCoupleMode,
|
|
97
137
|
);
|
|
98
138
|
|
|
139
|
+
if (DEV) {
|
|
140
|
+
console.log("[CoupleBuilder] Appearance context length:", appearanceContext.length);
|
|
141
|
+
if (appearanceContext.length > 0) {
|
|
142
|
+
console.log("[CoupleBuilder] Appearance context preview:", appearanceContext.substring(0, 150) + "...");
|
|
143
|
+
} else {
|
|
144
|
+
console.log("[CoupleBuilder] ℹ️ No appearance context returned (vision disabled)");
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
99
148
|
// 3. REFINE FOR COUPLE + PREPEND CONTEXT - Wardrobe mantığı
|
|
100
149
|
// Coupler modu için prompt'u iyileştir ve context'i ekle
|
|
150
|
+
if (DEV) {
|
|
151
|
+
console.log("[CoupleBuilder] ===== STEP 3: REFINE & PREPEND CONTEXT =====");
|
|
152
|
+
console.log("[CoupleBuilder] Calling refinePromptForCouple with:", {
|
|
153
|
+
basePromptLength: basePrompt.length,
|
|
154
|
+
isCoupleMode
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
101
158
|
const refinedPrompt = prependContext(
|
|
102
159
|
refinePromptForCouple(basePrompt, isCoupleMode),
|
|
103
160
|
appearanceContext,
|
|
104
161
|
);
|
|
105
162
|
|
|
163
|
+
if (DEV) {
|
|
164
|
+
console.log("[CoupleBuilder] After refinePromptForCouple + prependContext:");
|
|
165
|
+
console.log("[CoupleBuilder] Refined prompt length:", refinedPrompt.length);
|
|
166
|
+
console.log("[CoupleBuilder] Refined prompt preview:", refinedPrompt.substring(0, 300) + "...");
|
|
167
|
+
}
|
|
168
|
+
|
|
106
169
|
// 4. CREATE FINAL PROMPT - Photorealistic
|
|
170
|
+
if (DEV) {
|
|
171
|
+
console.log("[CoupleBuilder] ===== STEP 4: CREATE PHOTOREALISTIC PROMPT =====");
|
|
172
|
+
console.log("[CoupleBuilder] Calling createPhotorealisticPrompt with:", {
|
|
173
|
+
isCouple: isCoupleMode,
|
|
174
|
+
hasCustomInstructions: !!customInstructions
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
107
178
|
const prompt = createPhotorealisticPrompt(refinedPrompt, {
|
|
108
179
|
isCouple: isCoupleMode,
|
|
109
180
|
customInstructions,
|
|
110
181
|
});
|
|
111
182
|
|
|
183
|
+
if (DEV) {
|
|
184
|
+
console.log("[CoupleBuilder] Final prompt length:", prompt.length);
|
|
185
|
+
console.log("[CoupleBuilder] Final prompt preview:", prompt.substring(0, 500) + "...");
|
|
186
|
+
console.log("[CoupleBuilder] Has custom instructions:", !!customInstructions);
|
|
187
|
+
if (customInstructions) {
|
|
188
|
+
console.log("[CoupleBuilder] Custom instructions:", customInstructions);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
112
192
|
// 5. RESOLVE COUPLE INPUT - Doğru target ve image'lar
|
|
193
|
+
if (DEV) {
|
|
194
|
+
console.log("[CoupleBuilder] ===== STEP 5: RESOLVE COUPLE INPUT =====");
|
|
195
|
+
console.log("[CoupleBuilder] Calling resolveCoupleInput with:", {
|
|
196
|
+
partner1PhotoUri: partner1PhotoUri.substring(0, 50) + "...",
|
|
197
|
+
partner2PhotoUri: partner2PhotoUri ? partner2PhotoUri.substring(0, 50) + "..." : null,
|
|
198
|
+
isCoupleMode,
|
|
199
|
+
singleTarget: "p-image-edit/pruna",
|
|
200
|
+
coupleTarget: "p-image-edit/pruna"
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
113
204
|
const { target, imageUrls } = resolveCoupleInput(
|
|
114
205
|
partner1PhotoUri,
|
|
115
206
|
partner2PhotoUri,
|
|
@@ -118,7 +209,22 @@ export async function buildCoupleGenerationInput(
|
|
|
118
209
|
{ model: "p-image-edit", providerId: "pruna" }, // Couple target
|
|
119
210
|
);
|
|
120
211
|
|
|
212
|
+
if (DEV) {
|
|
213
|
+
console.log("[CoupleBuilder] Target resolution result:");
|
|
214
|
+
console.log("[CoupleBuilder] Target model:", target.model);
|
|
215
|
+
console.log("[CoupleBuilder] Target provider:", target.providerId);
|
|
216
|
+
console.log("[CoupleBuilder] Image URLs count:", imageUrls.length);
|
|
217
|
+
console.log("[CoupleBuilder] Image 1:", imageUrls[0]?.substring(0, 80) + "...");
|
|
218
|
+
if (imageUrls.length > 1) {
|
|
219
|
+
console.log("[CoupleBuilder] Image 2:", imageUrls[1]?.substring(0, 80) + "...");
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
121
223
|
// 6. BUILD PARAMS - Wardrobe formatında
|
|
224
|
+
if (DEV) {
|
|
225
|
+
console.log("[CoupleBuilder] ===== STEP 6: BUILD PARAMS =====");
|
|
226
|
+
}
|
|
227
|
+
|
|
122
228
|
const genParams: Record<string, unknown> = {
|
|
123
229
|
prompt,
|
|
124
230
|
image_urls: imageUrls,
|
|
@@ -130,6 +236,19 @@ export async function buildCoupleGenerationInput(
|
|
|
130
236
|
genParams.strength = strength;
|
|
131
237
|
}
|
|
132
238
|
|
|
239
|
+
if (DEV) {
|
|
240
|
+
console.log("[CoupleBuilder] Final params structure:");
|
|
241
|
+
console.log("[CoupleBuilder] Keys:", Object.keys(genParams).join(", "));
|
|
242
|
+
console.log("[CoupleBuilder] 'image_urls' count:", Array.isArray(genParams.image_urls) ? genParams.image_urls.length : "N/A");
|
|
243
|
+
console.log("[CoupleBuilder] 'aspect_ratio':", genParams.aspect_ratio);
|
|
244
|
+
console.log("[CoupleBuilder] 'strength':", genParams.strength ?? "not set");
|
|
245
|
+
console.log("[CoupleBuilder] ========================================");
|
|
246
|
+
console.log("[CoupleBuilder] ===== BUILD COUPLE GENERATION END =====");
|
|
247
|
+
console.log("[CoupleBuilder] ========================================");
|
|
248
|
+
console.log("[CoupleBuilder] Returning: { target, prompt, params }");
|
|
249
|
+
console.log("");
|
|
250
|
+
}
|
|
251
|
+
|
|
133
252
|
return {
|
|
134
253
|
target,
|
|
135
254
|
prompt,
|
|
@@ -146,6 +265,8 @@ export async function buildCoupleGenerationInput(
|
|
|
146
265
|
export async function buildScenarioGenerationInput(
|
|
147
266
|
params: ScenarioGenerationInputParams,
|
|
148
267
|
): Promise<CoupleGenerationInput> {
|
|
268
|
+
const DEV = typeof __DEV__ !== "undefined" && __DEV__;
|
|
269
|
+
|
|
149
270
|
const {
|
|
150
271
|
partner1PhotoUri,
|
|
151
272
|
partner2PhotoUri,
|
|
@@ -153,26 +274,71 @@ export async function buildScenarioGenerationInput(
|
|
|
153
274
|
scenarioPrompt,
|
|
154
275
|
} = params;
|
|
155
276
|
|
|
277
|
+
if (DEV) {
|
|
278
|
+
console.log("[ScenarioBuilder] ========================================");
|
|
279
|
+
console.log("[ScenarioBuilder] ===== BUILD SCENARIO GENERATION START =====");
|
|
280
|
+
console.log("[ScenarioBuilder] ========================================");
|
|
281
|
+
console.log("[ScenarioBuilder] ===== INPUT PARAMS =====");
|
|
282
|
+
console.log("[ScenarioBuilder] Is couple mode:", isCoupleMode);
|
|
283
|
+
console.log("[ScenarioBuilder] Scenario prompt length:", scenarioPrompt.length);
|
|
284
|
+
console.log("[ScenarioBuilder] Scenario prompt preview:", scenarioPrompt.substring(0, 200) + "...");
|
|
285
|
+
console.log("[ScenarioBuilder] Partner 1 URI:", partner1PhotoUri.substring(0, 80) + "...");
|
|
286
|
+
if (partner2PhotoUri) {
|
|
287
|
+
console.log("[ScenarioBuilder] Partner 2 URI:", partner2PhotoUri.substring(0, 80) + "...");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
156
291
|
// 1. GET PHOTO URIs
|
|
157
292
|
const photoUris =
|
|
158
293
|
isCoupleMode && partner2PhotoUri
|
|
159
294
|
? [partner1PhotoUri, partner2PhotoUri]
|
|
160
295
|
: [partner1PhotoUri];
|
|
161
296
|
|
|
297
|
+
if (DEV) {
|
|
298
|
+
console.log("[ScenarioBuilder] ===== STEP 1: PHOTO URIs =====");
|
|
299
|
+
console.log("[ScenarioBuilder] Photo URIs count:", photoUris.length);
|
|
300
|
+
}
|
|
301
|
+
|
|
162
302
|
// 2. ANALYZE APPEARANCE
|
|
303
|
+
if (DEV) {
|
|
304
|
+
console.log("[ScenarioBuilder] ===== STEP 2: APPEARANCE ANALYSIS =====");
|
|
305
|
+
}
|
|
306
|
+
|
|
163
307
|
const appearanceContext = await getAppearanceContext(
|
|
164
308
|
photoUris,
|
|
165
309
|
isCoupleMode,
|
|
166
310
|
);
|
|
167
311
|
|
|
312
|
+
if (DEV) {
|
|
313
|
+
console.log("[ScenarioBuilder] Appearance context length:", appearanceContext.length);
|
|
314
|
+
if (appearanceContext.length > 0) {
|
|
315
|
+
console.log("[ScenarioBuilder] Appearance context preview:", appearanceContext.substring(0, 150) + "...");
|
|
316
|
+
} else {
|
|
317
|
+
console.log("[ScenarioBuilder] ℹ️ No appearance context (vision disabled)");
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
168
321
|
// 3. REFINE FOR COUPLE + PREPEND CONTEXT
|
|
169
322
|
// Senaryo prompt'unu (zaten photorealistic) dynamic context ile birleştir
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
323
|
+
if (DEV) {
|
|
324
|
+
console.log("[ScenarioBuilder] ===== STEP 3: REFINE & PREPEND CONTEXT =====");
|
|
325
|
+
console.log("[ScenarioBuilder] Calling refinePromptForCouple...");
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const refinedPrompt = refinePromptForCouple(scenarioPrompt, isCoupleMode);
|
|
329
|
+
const finalPrompt = prependContext(refinedPrompt, appearanceContext);
|
|
330
|
+
|
|
331
|
+
if (DEV) {
|
|
332
|
+
console.log("[ScenarioBuilder] After refinePromptForCouple length:", refinedPrompt.length);
|
|
333
|
+
console.log("[ScenarioBuilder] After prependContext length:", finalPrompt.length);
|
|
334
|
+
console.log("[ScenarioBuilder] Final prompt preview:", finalPrompt.substring(0, 300) + "...");
|
|
335
|
+
}
|
|
174
336
|
|
|
175
337
|
// 4. RESOLVE COUPLE INPUT
|
|
338
|
+
if (DEV) {
|
|
339
|
+
console.log("[ScenarioBuilder] ===== STEP 4: RESOLVE COUPLE INPUT =====");
|
|
340
|
+
}
|
|
341
|
+
|
|
176
342
|
const { target, imageUrls } = resolveCoupleInput(
|
|
177
343
|
partner1PhotoUri,
|
|
178
344
|
partner2PhotoUri,
|
|
@@ -181,7 +347,21 @@ export async function buildScenarioGenerationInput(
|
|
|
181
347
|
{ model: "p-image-edit", providerId: "pruna" }, // Couple target
|
|
182
348
|
);
|
|
183
349
|
|
|
350
|
+
if (DEV) {
|
|
351
|
+
console.log("[ScenarioBuilder] Target:", target.model, "/", target.providerId);
|
|
352
|
+
console.log("[ScenarioBuilder] Image URLs count:", imageUrls.length);
|
|
353
|
+
}
|
|
354
|
+
|
|
184
355
|
// 5. BUILD PARAMS - Scenario formatında
|
|
356
|
+
if (DEV) {
|
|
357
|
+
console.log("[ScenarioBuilder] ===== STEP 5: BUILD PARAMS =====");
|
|
358
|
+
console.log("[ScenarioBuilder] Aspect ratio: 3:4");
|
|
359
|
+
console.log("[ScenarioBuilder] ========================================");
|
|
360
|
+
console.log("[ScenarioBuilder] ===== BUILD SCENARIO GENERATION END =====");
|
|
361
|
+
console.log("[ScenarioBuilder] ========================================");
|
|
362
|
+
console.log("");
|
|
363
|
+
}
|
|
364
|
+
|
|
185
365
|
return {
|
|
186
366
|
target,
|
|
187
367
|
prompt: finalPrompt,
|
package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.ts
CHANGED
|
@@ -58,6 +58,28 @@ export async function executeImageGeneration(
|
|
|
58
58
|
const mode = imageUrls.length > 0 ? "Photo-based" : "Text-to-image";
|
|
59
59
|
const totalImageSize = imageUrls.reduce((sum, url) => sum + url.length, 0);
|
|
60
60
|
|
|
61
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
62
|
+
console.log("[ImageExecutor] ===== EXECUTION START =====");
|
|
63
|
+
console.log("[ImageExecutor] Mode:", mode);
|
|
64
|
+
console.log("[ImageExecutor] Model:", model);
|
|
65
|
+
console.log("[ImageExecutor] Provider ID:", providerId);
|
|
66
|
+
console.log("[ImageExecutor] ===== INPUT DATA =====");
|
|
67
|
+
console.log("[ImageExecutor] Photo count:", imageUrls.length);
|
|
68
|
+
console.log("[ImageExecutor] Total image size:", Math.round(totalImageSize / 1024), "KB");
|
|
69
|
+
console.log("[ImageExecutor] Image sizes:", imageUrls.map((url, i) => ` Photo ${i + 1}: ${(url.length / 1024).toFixed(2)}KB`));
|
|
70
|
+
console.log("[ImageExecutor] Aspect ratio:", input.aspectRatio || MODEL_INPUT_DEFAULTS.aspectRatio);
|
|
71
|
+
console.log("[ImageExecutor] ===== PROMPT =====");
|
|
72
|
+
console.log("[ImageExecutor] Prompt length:", finalPrompt.length);
|
|
73
|
+
console.log("[ImageExecutor] Prompt preview:");
|
|
74
|
+
console.log(finalPrompt.substring(0, 400) + "...");
|
|
75
|
+
console.log("[ImageExecutor] ===== MODEL INPUT =====");
|
|
76
|
+
console.log("[ImageExecutor] Model:", model);
|
|
77
|
+
console.log("[ImageExecutor] Input keys:", Object.keys(MODEL_INPUT_DEFAULTS));
|
|
78
|
+
console.log("[ImageExecutor] Output format:", MODEL_INPUT_DEFAULTS.outputFormat);
|
|
79
|
+
console.log("[ImageExecutor] Num images:", MODEL_INPUT_DEFAULTS.numImages);
|
|
80
|
+
console.log("[ImageExecutor] Safety checker:", MODEL_INPUT_DEFAULTS.enableSafetyChecker);
|
|
81
|
+
}
|
|
82
|
+
|
|
61
83
|
addGenerationLog(sid, TAG, `${mode} generation starting`, 'info', {
|
|
62
84
|
model,
|
|
63
85
|
photoCount: imageUrls.length,
|
|
@@ -70,16 +92,24 @@ export async function executeImageGeneration(
|
|
|
70
92
|
const modelInput: Record<string, unknown> = {
|
|
71
93
|
prompt: finalPrompt,
|
|
72
94
|
aspect_ratio: input.aspectRatio || MODEL_INPUT_DEFAULTS.aspectRatio,
|
|
73
|
-
output_format: MODEL_INPUT_DEFAULTS.outputFormat,
|
|
74
|
-
num_images: MODEL_INPUT_DEFAULTS.numImages,
|
|
75
|
-
enable_safety_checker: MODEL_INPUT_DEFAULTS.enableSafetyChecker,
|
|
76
95
|
};
|
|
77
96
|
|
|
78
|
-
// p-image-edit (and typical multi-ref models) usually expect 'images' key
|
|
79
|
-
// supporting both 'images' and 'image_urls' for maximum compatibility
|
|
80
97
|
if (imageUrls.length > 0) {
|
|
81
|
-
modelInput.images = imageUrls;
|
|
82
98
|
modelInput.image_urls = imageUrls;
|
|
99
|
+
modelInput.images = imageUrls;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
103
|
+
console.log("[ImageExecutor] ===== MODEL INPUT CONSTRUCTED =====");
|
|
104
|
+
console.log("[ImageExecutor] Input keys:", Object.keys(modelInput));
|
|
105
|
+
console.log("[ImageExecutor] Has 'images':", "images" in modelInput, "(count:", Array.isArray(modelInput.images) ? modelInput.images.length : "N/A", ")");
|
|
106
|
+
console.log("[ImageExecutor] Has 'image_urls':", "image_urls" in modelInput, "(count:", Array.isArray(modelInput.image_urls) ? modelInput.image_urls.length : "N/A", ")");
|
|
107
|
+
console.log("[ImageExecutor] Images array length:", imageUrls.length);
|
|
108
|
+
if (imageUrls.length > 0) {
|
|
109
|
+
console.log("[ImageExecutor] First image preview:", imageUrls[0].substring(0, 80) + "...");
|
|
110
|
+
console.log("[ImageExecutor] Last image preview:", imageUrls[imageUrls.length - 1].substring(0, 80) + "...");
|
|
111
|
+
}
|
|
112
|
+
console.log("[ImageExecutor] ===== CALLING PROVIDER =====");
|
|
83
113
|
}
|
|
84
114
|
|
|
85
115
|
addGenerationLog(sid, TAG, 'Calling provider.subscribe()...');
|
package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { extractPhotosAsBase64, extractPhotoUris } from "./shared/photo-extracti
|
|
|
11
11
|
import { executeImageGeneration } from "./image-generation.executor";
|
|
12
12
|
import type { WizardImageInput, CreateImageStrategyOptions } from "./image-generation.types";
|
|
13
13
|
import { enhancePromptWithAnalysis } from "../../../infrastructure/appearance-analysis";
|
|
14
|
+
import { createPhotorealisticPrompt } from "../../../../prompts/domain/base/creators";
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
// ============================================================================
|
|
@@ -21,17 +22,65 @@ export async function buildImageInput(
|
|
|
21
22
|
wizardData: Record<string, unknown>,
|
|
22
23
|
scenario: WizardScenarioData,
|
|
23
24
|
): Promise<WizardImageInput | null> {
|
|
25
|
+
const DEV = typeof __DEV__ !== "undefined" && __DEV__;
|
|
26
|
+
|
|
27
|
+
if (DEV) {
|
|
28
|
+
console.log("[ImageStrategy] ===== BUILD IMAGE INPUT START =====");
|
|
29
|
+
console.log("[ImageStrategy] Scenario ID:", scenario.id);
|
|
30
|
+
console.log("[ImageStrategy] Scenario model:", scenario.model);
|
|
31
|
+
console.log("[ImageStrategy] Scenario provider:", scenario.providerId);
|
|
32
|
+
console.log("[ImageStrategy] ===== WIZARD DATA KEYS =====");
|
|
33
|
+
const wizardKeys = Object.keys(wizardData);
|
|
34
|
+
console.log("[ImageStrategy] Total keys:", wizardKeys.length);
|
|
35
|
+
console.log("[ImageStrategy] Keys:", wizardKeys.slice(0, 20).join(", ") + (wizardKeys.length > 20 ? "..." : ""));
|
|
36
|
+
|
|
37
|
+
// Log photo-related keys
|
|
38
|
+
const photoKeys = wizardKeys.filter(k => k.includes("photo"));
|
|
39
|
+
if (photoKeys.length > 0) {
|
|
40
|
+
console.log("[ImageStrategy] Photo-related keys:", photoKeys.join(", "));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Log selection/style keys
|
|
44
|
+
const selectionKeys = wizardKeys.filter(k => k.includes("selection") || k.includes("style"));
|
|
45
|
+
if (selectionKeys.length > 0) {
|
|
46
|
+
console.log("[ImageStrategy] Selection/style keys:", selectionKeys.join(", "));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
24
50
|
// Extract photo URIs first (for couple refinement)
|
|
25
51
|
const photoUris = extractPhotoUris(wizardData);
|
|
26
|
-
const photos = await extractPhotosAsBase64(wizardData);
|
|
52
|
+
const photos = await extractPhotosAsBase64(wizardData, DEV);
|
|
53
|
+
|
|
54
|
+
if (DEV) {
|
|
55
|
+
console.log("[ImageStrategy] ===== EXTRACTION COMPLETE =====");
|
|
56
|
+
console.log("[ImageStrategy] Photo URIs count:", photoUris.length);
|
|
57
|
+
console.log("[ImageStrategy] Base64 photos count:", photos.length);
|
|
58
|
+
}
|
|
27
59
|
|
|
28
60
|
// Extract prompt with fallback to default
|
|
29
61
|
let prompt = extractPrompt(wizardData, scenario.aiPrompt);
|
|
30
62
|
|
|
63
|
+
if (DEV) {
|
|
64
|
+
console.log("[ImageStrategy] ===== PROMPT EXTRACTION =====");
|
|
65
|
+
console.log("[ImageStrategy] Scenario aiPrompt type:", typeof scenario.aiPrompt);
|
|
66
|
+
console.log("[ImageStrategy] Scenario aiPrompt length:", typeof scenario.aiPrompt === "string" ? scenario.aiPrompt.length : "N/A");
|
|
67
|
+
if (typeof scenario.aiPrompt === "string") {
|
|
68
|
+
console.log("[ImageStrategy] Scenario aiPrompt preview:", scenario.aiPrompt.substring(0, 200) + "...");
|
|
69
|
+
}
|
|
70
|
+
console.log("[ImageStrategy] Extracted prompt type:", typeof prompt);
|
|
71
|
+
console.log("[ImageStrategy] Extracted prompt length:", prompt?.length ?? 0);
|
|
72
|
+
if (prompt) {
|
|
73
|
+
console.log("[ImageStrategy] Extracted prompt preview:", prompt.substring(0, 200) + "...");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
31
77
|
if (!prompt) {
|
|
32
78
|
const defaultPrompt = IMAGE_PROCESSING_PROMPTS[scenario.id];
|
|
33
79
|
if (defaultPrompt) {
|
|
34
80
|
prompt = defaultPrompt;
|
|
81
|
+
if (DEV) {
|
|
82
|
+
console.log("[ImageStrategy] Using default prompt for scenario:", scenario.id);
|
|
83
|
+
}
|
|
35
84
|
} else {
|
|
36
85
|
throw new Error("Prompt is required for image generation");
|
|
37
86
|
}
|
|
@@ -40,21 +89,49 @@ export async function buildImageInput(
|
|
|
40
89
|
// Apply style enhancements for photo-based generation
|
|
41
90
|
let finalPrompt = prompt;
|
|
42
91
|
if (photos.length > 0) {
|
|
43
|
-
finalPrompt = applyStyleEnhancements(prompt, wizardData);
|
|
44
|
-
|
|
45
|
-
// ✅ Apply couple refinement (same logic as Wardrobe)
|
|
46
|
-
// Note: Scenario prompts are already wrapped with createPhotorealisticPrompt
|
|
47
|
-
// in the data files, so we only apply couple refinement here
|
|
48
92
|
const isCoupleMode = photos.length >= 2;
|
|
49
|
-
|
|
93
|
+
const styleEnhanced = applyStyleEnhancements(prompt, wizardData);
|
|
94
|
+
|
|
95
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
96
|
+
console.log("[ImageStrategy] ===== STRATEGY START =====");
|
|
97
|
+
console.log("[ImageStrategy] Scenario:", scenario.id);
|
|
98
|
+
console.log("[ImageStrategy] Model:", scenario.model);
|
|
99
|
+
console.log("[ImageStrategy] Provider:", scenario.providerId);
|
|
100
|
+
console.log("[ImageStrategy] ===== PROMPT FLOW =====");
|
|
101
|
+
console.log("[ImageStrategy] [1/5] Original scenario prompt:");
|
|
102
|
+
console.log("[ImageStrategy] Length:", prompt.length);
|
|
103
|
+
console.log("[ImageStrategy] Preview:", prompt.substring(0, 150) + "...");
|
|
104
|
+
console.log("[ImageStrategy] [2/5] Style enhancements applied:", styleEnhanced !== prompt);
|
|
105
|
+
if (styleEnhanced !== prompt) {
|
|
106
|
+
console.log("[ImageStrategy] Enhanced preview:", styleEnhanced.substring(0, 150) + "...");
|
|
107
|
+
}
|
|
108
|
+
console.log("[ImageStrategy] [3/5] Couple mode:", isCoupleMode);
|
|
109
|
+
console.log("[ImageStrategy] Photo count:", photos.length);
|
|
110
|
+
console.log("[ImageStrategy] [4/5] Calling enhancePromptWithAnalysis...");
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const refinedPrompt = await enhancePromptWithAnalysis(styleEnhanced, photoUris, isCoupleMode);
|
|
114
|
+
|
|
115
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
116
|
+
console.log("[ImageStrategy] After enhancePromptWithAnalysis:");
|
|
117
|
+
console.log("[ImageStrategy] Length:", refinedPrompt.length);
|
|
118
|
+
console.log("[ImageStrategy] Preview:", refinedPrompt.substring(0, 200) + "...");
|
|
119
|
+
console.log("[ImageStrategy] [5/5] Calling createPhotorealisticPrompt (Wardrobe style)...");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
finalPrompt = createPhotorealisticPrompt(refinedPrompt, {
|
|
123
|
+
isCouple: isCoupleMode,
|
|
124
|
+
customInstructions: undefined,
|
|
125
|
+
});
|
|
50
126
|
|
|
51
127
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
52
|
-
console.log("[ImageStrategy]
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
128
|
+
console.log("[ImageStrategy] ===== STRATEGY END =====");
|
|
129
|
+
console.log("[ImageStrategy] Final prompt length:", finalPrompt.length);
|
|
130
|
+
console.log("[ImageStrategy] Final prompt preview:");
|
|
131
|
+
console.log(finalPrompt.substring(0, 600) + "...");
|
|
132
|
+
console.log("[ImageStrategy] ===== OUTPUT =====");
|
|
133
|
+
console.log("[ImageStrategy] Photo count:", photos.length);
|
|
134
|
+
console.log("[ImageStrategy] Photo sizes:", photos.map((p, i) => `Photo ${i + 1}: ${(p.length / 1024).toFixed(2)}KB`));
|
|
58
135
|
}
|
|
59
136
|
}
|
|
60
137
|
|
|
@@ -62,8 +139,29 @@ export async function buildImageInput(
|
|
|
62
139
|
const styleValue = extractSelection(wizardData.style);
|
|
63
140
|
const style = typeof styleValue === "string" ? styleValue : undefined;
|
|
64
141
|
|
|
65
|
-
|
|
66
|
-
|
|
142
|
+
let aspectRatio = typeof wizardData.aspect_ratio === "string" ? wizardData.aspect_ratio : undefined;
|
|
143
|
+
|
|
144
|
+
if (!aspectRatio && photos.length > 0) {
|
|
145
|
+
aspectRatio = "3:4"; // Wardrobe default
|
|
146
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
147
|
+
console.log("[ImageStrategy] No aspect_ratio in wizardData, using Wardrobe default: 3:4");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
152
|
+
console.log("[ImageStrategy] ===== STYLE & ASPECT RATIO =====");
|
|
153
|
+
console.log("[ImageStrategy] wizardData.style:", wizardData.style);
|
|
154
|
+
console.log("[ImageStrategy] Extracted styleValue:", styleValue);
|
|
155
|
+
console.log("[ImageStrategy] Final style:", style || "none");
|
|
156
|
+
console.log("[ImageStrategy] wizardData.aspect_ratio:", wizardData.aspect_ratio);
|
|
157
|
+
console.log("[ImageStrategy] Final aspectRatio:", aspectRatio || "default");
|
|
158
|
+
console.log("[ImageStrategy] ===== FINAL OUTPUT =====");
|
|
159
|
+
console.log("[ImageStrategy] Photos count:", photos.length);
|
|
160
|
+
console.log("[ImageStrategy] Prompt length:", finalPrompt.length);
|
|
161
|
+
console.log("[ImageStrategy] Aspect ratio:", aspectRatio || "default");
|
|
162
|
+
console.log("[ImageStrategy] Returning WizardImageInput");
|
|
163
|
+
console.log("[ImageStrategy] ===== STRATEGY COMPLETE =====");
|
|
164
|
+
}
|
|
67
165
|
|
|
68
166
|
return { photos, prompt: finalPrompt, style, aspectRatio };
|
|
69
167
|
}
|
|
@@ -20,16 +20,54 @@ export function resolveCoupleInput(
|
|
|
20
20
|
singleTarget: GenerationTargetLike,
|
|
21
21
|
coupleTarget: GenerationTargetLike,
|
|
22
22
|
): CoupleInputResult {
|
|
23
|
+
const DEV = typeof __DEV__ !== "undefined" && __DEV__;
|
|
24
|
+
|
|
25
|
+
if (DEV) {
|
|
26
|
+
console.log("[CoupleUtil] ===== RESOLVE COUPLE INPUT =====");
|
|
27
|
+
console.log("[CoupleUtil] Is couple mode:", isCoupleMode);
|
|
28
|
+
console.log("[CoupleUtil] Has partner 2:", !!partner2PhotoUri);
|
|
29
|
+
console.log("[CoupleUtil] Partner 1 URI:", partner1PhotoUri.substring(0, 60) + "...");
|
|
30
|
+
if (partner2PhotoUri) {
|
|
31
|
+
console.log("[CoupleUtil] Partner 2 URI:", partner2PhotoUri.substring(0, 60) + "...");
|
|
32
|
+
}
|
|
33
|
+
console.log("[CoupleUtil] Single target:", `${singleTarget.model}/${singleTarget.providerId}`);
|
|
34
|
+
console.log("[CoupleUtil] Couple target:", `${coupleTarget.model}/${coupleTarget.providerId}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
23
37
|
if (isCoupleMode && partner2PhotoUri) {
|
|
24
|
-
|
|
38
|
+
const result = {
|
|
25
39
|
target: coupleTarget,
|
|
26
40
|
imageUrls: [partner1PhotoUri, partner2PhotoUri],
|
|
27
41
|
};
|
|
42
|
+
|
|
43
|
+
if (DEV) {
|
|
44
|
+
console.log("[CoupleUtil] ===== COUPLE MODE SELECTED =====");
|
|
45
|
+
console.log("[CoupleUtil] Target model:", result.target.model);
|
|
46
|
+
console.log("[CoupleUtil] Target provider:", result.target.providerId);
|
|
47
|
+
console.log("[CoupleUtil] Image URLs:", result.imageUrls.length);
|
|
48
|
+
console.log("[CoupleUtil] Image 1:", result.imageUrls[0].substring(0, 60) + "...");
|
|
49
|
+
console.log("[CoupleUtil] Image 2:", result.imageUrls[1].substring(0, 60) + "...");
|
|
50
|
+
console.log("[CoupleUtil] ===== RESOLVE COMPLETE =====");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return result;
|
|
28
54
|
}
|
|
29
|
-
|
|
55
|
+
|
|
56
|
+
const result = {
|
|
30
57
|
target: singleTarget,
|
|
31
58
|
imageUrls: [partner1PhotoUri],
|
|
32
59
|
};
|
|
60
|
+
|
|
61
|
+
if (DEV) {
|
|
62
|
+
console.log("[CoupleUtil] ===== SINGLE MODE SELECTED =====");
|
|
63
|
+
console.log("[CoupleUtil] Target model:", result.target.model);
|
|
64
|
+
console.log("[CoupleUtil] Target provider:", result.target.providerId);
|
|
65
|
+
console.log("[CoupleUtil] Image URLs:", result.imageUrls.length);
|
|
66
|
+
console.log("[CoupleUtil] Image 1:", result.imageUrls[0].substring(0, 60) + "...");
|
|
67
|
+
console.log("[CoupleUtil] ===== RESOLVE COMPLETE =====");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return result;
|
|
33
71
|
}
|
|
34
72
|
|
|
35
73
|
/**
|
|
@@ -47,6 +85,13 @@ export function prependContext(
|
|
|
47
85
|
* Primarily used to fix "baked" prompts that were generated with a specific mode in mind.
|
|
48
86
|
*/
|
|
49
87
|
export function refinePromptForCouple(prompt: string, isCouple: boolean): string {
|
|
88
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
89
|
+
console.log("[CoupleUtil] ===== REFINE PROMPT START =====");
|
|
90
|
+
console.log("[CoupleUtil] Is couple mode:", isCouple);
|
|
91
|
+
console.log("[CoupleUtil] Original prompt length:", prompt.length);
|
|
92
|
+
console.log("[CoupleUtil] Original prompt preview:", prompt.substring(0, 200) + "...");
|
|
93
|
+
}
|
|
94
|
+
|
|
50
95
|
if (isCouple) {
|
|
51
96
|
// Ensure couple context is present
|
|
52
97
|
let refined = prompt
|
|
@@ -64,22 +109,36 @@ export function refinePromptForCouple(prompt: string, isCouple: boolean): string
|
|
|
64
109
|
refined = refined
|
|
65
110
|
.replace(/\b(dress|gown)\b/gi, "$1 (worn by Person 1)")
|
|
66
111
|
.replace(/\b(suit|tuxedo|linen trousers)\b/gi, "$1 (worn by Person 2)");
|
|
67
|
-
|
|
112
|
+
|
|
68
113
|
// Also add explicit mapping to the top if not already there
|
|
69
114
|
if (!refined.includes("DIRECTIVE: MAP PHOTO 1 TO PERSON 1")) {
|
|
70
115
|
refined = `DIRECTIVE: MAP PHOTO 1 TO PERSON 1, MAP PHOTO 2 TO PERSON 2\n\n${refined}`;
|
|
71
116
|
}
|
|
117
|
+
|
|
118
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
119
|
+
console.log("[CoupleUtil] ✅ Clothing mapping applied!");
|
|
120
|
+
console.log("[CoupleUtil] ✅ Directive added for photo mapping");
|
|
121
|
+
}
|
|
72
122
|
}
|
|
73
123
|
|
|
74
124
|
// If it doesn't already have couple-hints, add them at the start
|
|
75
125
|
if (!/\b(couple|both|matching|dual|two people)\b/i.test(refined) && !refined.includes("DIRECTIVE:")) {
|
|
76
126
|
refined = `A photo of a couple, ${refined}`;
|
|
127
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
128
|
+
console.log("[CoupleUtil] ✅ Added 'A photo of a couple' prefix");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
133
|
+
console.log("[CoupleUtil] Refined prompt length:", refined.length);
|
|
134
|
+
console.log("[CoupleUtil] Refined prompt preview:", refined.substring(0, 300) + "...");
|
|
135
|
+
console.log("[CoupleUtil] ===== REFINE PROMPT END =====");
|
|
77
136
|
}
|
|
78
137
|
return refined;
|
|
79
138
|
} else {
|
|
80
139
|
// Solo mode: AGGRESSIVELY remove plural references to prevent "ghost" people
|
|
81
|
-
|
|
82
|
-
// Instead of removing the clothing descriptions, just remove the gender labels
|
|
140
|
+
const soloRefined = prompt
|
|
141
|
+
// Instead of removing the clothing descriptions, just remove the gender labels
|
|
83
142
|
// so the AI can apply the relevant clothing to the single person it sees.
|
|
84
143
|
.replace(/\sfor women\b/gi, "")
|
|
85
144
|
.replace(/\sfor men\b/gi, "")
|
|
@@ -90,7 +149,7 @@ export function refinePromptForCouple(prompt: string, isCouple: boolean): string
|
|
|
90
149
|
.replace(/\bcoordinating\b/gi, "")
|
|
91
150
|
.replace(/\bcouple\b/gi, "person")
|
|
92
151
|
.replace(/\bduo\b/gi, "person")
|
|
93
|
-
.replace(/\bpair\b/gi, "person")
|
|
152
|
+
.replace(/\bpair\b/gi, "person")
|
|
94
153
|
.replace(/\bdoubles\b/gi, "")
|
|
95
154
|
.replace(/\bboth\b/gi, "the person")
|
|
96
155
|
.replace(/\bthey are\b/gi, "the person is")
|
|
@@ -109,6 +168,13 @@ export function refinePromptForCouple(prompt: string, isCouple: boolean): string
|
|
|
109
168
|
.replace(/\bhats\b/gi, "hat")
|
|
110
169
|
.replace(/\baccessories\b/gi, "accessory")
|
|
111
170
|
.replace(/\s+/g, ' ').trim();
|
|
171
|
+
|
|
172
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
173
|
+
console.log("[CoupleUtil] ✅ Solo mode - removed all plural references");
|
|
174
|
+
console.log("[CoupleUtil] Solo refined prompt length:", soloRefined.length);
|
|
175
|
+
console.log("[CoupleUtil] ===== REFINE PROMPT END =====");
|
|
176
|
+
}
|
|
177
|
+
return soloRefined;
|
|
112
178
|
}
|
|
113
179
|
}
|
|
114
180
|
|