@umituz/react-native-ai-generation-content 1.26.64 → 1.26.66
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/wizard/infrastructure/strategies/image-generation.strategy.ts +10 -1
- package/src/domains/prompts/domain/entities/BasePromptStructure.ts +53 -24
- package/src/domains/prompts/index.ts +12 -6
- package/src/domains/prompts/infrastructure/builders/face-preservation-builder.ts +162 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.26.
|
|
3
|
+
"version": "1.26.66",
|
|
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/image-generation.strategy.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
DEFAULT_STYLE_VALUE,
|
|
15
15
|
MODEL_INPUT_DEFAULTS,
|
|
16
16
|
} from "./wizard-strategy.constants";
|
|
17
|
+
import { buildFacePreservationPrompt } from "../../../../prompts/infrastructure/builders/face-preservation-builder";
|
|
17
18
|
|
|
18
19
|
declare const __DEV__: boolean;
|
|
19
20
|
|
|
@@ -86,7 +87,15 @@ async function executeImageGeneration(
|
|
|
86
87
|
return { success: false, error: "At least one image required" };
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
|
|
90
|
+
// Build face preservation prompt dynamically based on number of people
|
|
91
|
+
const enhancedPrompt = buildFacePreservationPrompt({
|
|
92
|
+
scenarioPrompt: input.prompt,
|
|
93
|
+
personCount: imageUrls.length,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
97
|
+
console.log("[ImageStrategy] Face preservation prompt for", imageUrls.length, "person(s)");
|
|
98
|
+
}
|
|
90
99
|
|
|
91
100
|
const modelInput = {
|
|
92
101
|
image_urls: imageUrls,
|
|
@@ -12,15 +12,26 @@
|
|
|
12
12
|
/**
|
|
13
13
|
* Core identity preservation instruction
|
|
14
14
|
* This is the foundation for maintaining facial consistency
|
|
15
|
+
* Updated with stricter rules based on AI image generation best practices
|
|
15
16
|
*/
|
|
16
|
-
export const IDENTITY_PRESERVATION_CORE = `CRITICAL IDENTITY PRESERVATION:
|
|
17
|
+
export const IDENTITY_PRESERVATION_CORE = `CRITICAL IDENTITY PRESERVATION (HIGHEST PRIORITY):
|
|
17
18
|
{
|
|
18
|
-
"policy": "
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
"policy": "PRESERVE 100% IDENTICAL FACIAL APPEARANCE FROM INPUT",
|
|
20
|
+
"mandatory_rules": [
|
|
21
|
+
"The face must be EXACTLY as it appears in the reference photo - 100% identical",
|
|
22
|
+
"Preserve every facial detail: bone structure, eye shape, eye color, nose shape, lip shape",
|
|
23
|
+
"Maintain natural skin texture with pores, marks, and realistic details",
|
|
24
|
+
"Keep the person instantly recognizable - any deviation is NOT acceptable"
|
|
25
|
+
],
|
|
26
|
+
"forbidden_modifications": [
|
|
27
|
+
"Do NOT change face shape or facial proportions",
|
|
28
|
+
"Do NOT alter eye color, eye shape, or eye spacing",
|
|
29
|
+
"Do NOT modify nose shape, size, or position",
|
|
30
|
+
"Do NOT change lip shape, thickness, or natural expression",
|
|
31
|
+
"Do NOT alter skin tone or smooth skin texture",
|
|
32
|
+
"Do NOT remove natural features like freckles, moles, or wrinkles"
|
|
33
|
+
],
|
|
34
|
+
"verification": "Before output: confirm face matches reference photo with 100% accuracy"
|
|
24
35
|
}`;
|
|
25
36
|
|
|
26
37
|
/**
|
|
@@ -162,29 +173,47 @@ ${existingPrompt}`;
|
|
|
162
173
|
};
|
|
163
174
|
|
|
164
175
|
/**
|
|
165
|
-
*
|
|
166
|
-
* Ensures
|
|
176
|
+
* Multi-person identity preservation rules
|
|
177
|
+
* Ensures all people maintain their identities with strict rules
|
|
178
|
+
* Supports any number of people (1, 2, 3, N)
|
|
167
179
|
*/
|
|
168
|
-
export const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
180
|
+
export const MULTI_PERSON_PRESERVATION_RULES = {
|
|
181
|
+
requirement: "ALL individuals must have 100% identical facial appearance to their reference photos",
|
|
182
|
+
perPersonRule: "Use EXACTLY the person from @imageN - preserve 100% identical facial features",
|
|
183
|
+
forbidden: [
|
|
184
|
+
"Do NOT swap, mix, or blend facial features between people",
|
|
185
|
+
"Do NOT idealize or beautify any face",
|
|
186
|
+
"Do NOT alter facial proportions or characteristics",
|
|
187
|
+
],
|
|
188
|
+
positioning: "Natural positioning, all looking at camera with natural expressions",
|
|
189
|
+
} as const;
|
|
177
190
|
|
|
178
191
|
/**
|
|
179
|
-
* Creates a
|
|
180
|
-
*
|
|
181
|
-
* @param scenarioPrompt - The scenario description
|
|
182
|
-
* @
|
|
192
|
+
* Creates a multi-person prompt dynamically
|
|
193
|
+
*
|
|
194
|
+
* @param scenarioPrompt - The scenario description
|
|
195
|
+
* @param personCount - Number of people (1, 2, 3, N)
|
|
196
|
+
* @returns Complete prompt with identity preservation for all people
|
|
183
197
|
*/
|
|
184
|
-
export const
|
|
198
|
+
export const createMultiPersonPrompt = (
|
|
199
|
+
scenarioPrompt: string,
|
|
200
|
+
personCount: number,
|
|
201
|
+
): string => {
|
|
202
|
+
const personRefs = Array.from({ length: personCount }, (_, i) =>
|
|
203
|
+
`Person ${i + 1}: @image${i + 1} - preserve 100% facial identity`
|
|
204
|
+
).join("\n ");
|
|
205
|
+
|
|
185
206
|
return `${IDENTITY_PRESERVATION_CORE}
|
|
186
207
|
|
|
187
|
-
${
|
|
208
|
+
MULTI-PERSON IDENTITY PRESERVATION (${personCount} people):
|
|
209
|
+
{
|
|
210
|
+
"requirement": "${MULTI_PERSON_PRESERVATION_RULES.requirement}",
|
|
211
|
+
"references": [
|
|
212
|
+
${personRefs}
|
|
213
|
+
],
|
|
214
|
+
"forbidden": ${JSON.stringify(MULTI_PERSON_PRESERVATION_RULES.forbidden)},
|
|
215
|
+
"positioning": "${MULTI_PERSON_PRESERVATION_RULES.positioning}"
|
|
216
|
+
}
|
|
188
217
|
|
|
189
218
|
${PHOTOREALISTIC_RENDERING}
|
|
190
219
|
|
|
@@ -84,15 +84,21 @@ export type { IdentitySegment, AnimeStyleSegment, QualitySegment } from './domai
|
|
|
84
84
|
export { ImagePromptBuilder, createAnimeSelfiePrompt, createStyleTransferPrompt } from './infrastructure/services/ImagePromptBuilder';
|
|
85
85
|
export type { ImagePromptResult, ImagePromptBuilderOptions, AnimeSelfiePromptResult } from './infrastructure/services/ImagePromptBuilder';
|
|
86
86
|
|
|
87
|
-
export {
|
|
88
|
-
IDENTITY_PRESERVATION_CORE,
|
|
89
|
-
PHOTOREALISTIC_RENDERING,
|
|
90
|
-
NATURAL_POSE_GUIDELINES,
|
|
87
|
+
export {
|
|
88
|
+
IDENTITY_PRESERVATION_CORE,
|
|
89
|
+
PHOTOREALISTIC_RENDERING,
|
|
90
|
+
NATURAL_POSE_GUIDELINES,
|
|
91
91
|
MASTER_BASE_PROMPT,
|
|
92
|
-
|
|
92
|
+
MULTI_PERSON_PRESERVATION_RULES,
|
|
93
93
|
createEnhancedPrompt,
|
|
94
94
|
createTransformationPrompt,
|
|
95
95
|
enhanceExistingPrompt,
|
|
96
|
-
|
|
96
|
+
createMultiPersonPrompt,
|
|
97
97
|
} from './domain/entities/BasePromptStructure';
|
|
98
98
|
export type { CreatePromptOptions } from './domain/entities/BasePromptStructure';
|
|
99
|
+
|
|
100
|
+
export {
|
|
101
|
+
buildFacePreservationPrompt,
|
|
102
|
+
buildMinimalFacePreservationPrompt,
|
|
103
|
+
} from './infrastructure/builders/face-preservation-builder';
|
|
104
|
+
export type { FacePreservationOptions } from './infrastructure/builders/face-preservation-builder';
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Face Preservation Prompt Builder
|
|
3
|
+
* Dynamic prompt builder for AI image generation with strict face identity preservation
|
|
4
|
+
* Supports any number of people (1, 2, 3, N) and interaction styles
|
|
5
|
+
*
|
|
6
|
+
* Based on best practices:
|
|
7
|
+
* - Face identity lock techniques
|
|
8
|
+
* - @imageN reference anchors
|
|
9
|
+
* - Interaction style rules (romantic, friendly, etc.)
|
|
10
|
+
* - Explicit preservation and negative constraints
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// Types
|
|
15
|
+
// =============================================================================
|
|
16
|
+
|
|
17
|
+
/** Interaction style between people in the image */
|
|
18
|
+
export type InteractionStyle = "romantic" | "friendly" | "professional" | "neutral";
|
|
19
|
+
|
|
20
|
+
export interface FacePreservationOptions {
|
|
21
|
+
/** The scenario/scene description */
|
|
22
|
+
scenarioPrompt: string;
|
|
23
|
+
/** Number of people in the generation */
|
|
24
|
+
personCount: number;
|
|
25
|
+
/** Interaction style between people (default: neutral) */
|
|
26
|
+
interactionStyle?: InteractionStyle;
|
|
27
|
+
/** Optional custom preservation rules from main app */
|
|
28
|
+
customRules?: string[];
|
|
29
|
+
/** Optional custom forbidden actions from main app */
|
|
30
|
+
customForbidden?: string[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// =============================================================================
|
|
34
|
+
// Constants
|
|
35
|
+
// =============================================================================
|
|
36
|
+
|
|
37
|
+
const FACE_LOCK_RULES = [
|
|
38
|
+
"Face identity locked - exact facial structure must be preserved",
|
|
39
|
+
"Same jawline, eye shape, eye color, nose, lips, skin tone",
|
|
40
|
+
"No facial morphing, no face swap, no face modification",
|
|
41
|
+
"Identity consistency enabled - high facial similarity required",
|
|
42
|
+
] as const;
|
|
43
|
+
|
|
44
|
+
const FORBIDDEN_ACTIONS = [
|
|
45
|
+
"Do NOT generate a new face",
|
|
46
|
+
"Do NOT modify facial structure or proportions",
|
|
47
|
+
"Do NOT alter skin tone, texture, or natural marks",
|
|
48
|
+
"Do NOT smooth skin or remove natural features",
|
|
49
|
+
"Do NOT change eye color or shape",
|
|
50
|
+
] as const;
|
|
51
|
+
|
|
52
|
+
/** Interaction style rules - what TO DO for each style */
|
|
53
|
+
const INTERACTION_RULES: Record<InteractionStyle, readonly string[]> = {
|
|
54
|
+
romantic: [
|
|
55
|
+
"Close physical proximity - touching, holding hands, arms around each other",
|
|
56
|
+
"Warm, genuine, loving smiles showing happiness",
|
|
57
|
+
"Affectionate eye contact or looking at camera together happily",
|
|
58
|
+
"Natural romantic body language - leaning into each other",
|
|
59
|
+
"Intimate connection visible between the two people",
|
|
60
|
+
],
|
|
61
|
+
friendly: [
|
|
62
|
+
"Casual comfortable proximity",
|
|
63
|
+
"Genuine friendly smiles",
|
|
64
|
+
"Relaxed natural poses",
|
|
65
|
+
"Warm friendly body language",
|
|
66
|
+
],
|
|
67
|
+
professional: [
|
|
68
|
+
"Appropriate professional distance",
|
|
69
|
+
"Confident pleasant expressions",
|
|
70
|
+
"Professional posture and positioning",
|
|
71
|
+
],
|
|
72
|
+
neutral: [],
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** Interaction style forbidden - what NOT to do for each style */
|
|
76
|
+
const INTERACTION_FORBIDDEN: Record<InteractionStyle, readonly string[]> = {
|
|
77
|
+
romantic: [
|
|
78
|
+
"Do NOT position people far apart or distant from each other",
|
|
79
|
+
"Do NOT use cold, serious, stern, or angry expressions",
|
|
80
|
+
"Do NOT create stiff, awkward, or unnatural poses",
|
|
81
|
+
"Do NOT have people looking away from each other coldly",
|
|
82
|
+
"Do NOT show disconnection or emotional distance between people",
|
|
83
|
+
],
|
|
84
|
+
friendly: [
|
|
85
|
+
"Do NOT use cold or unfriendly expressions",
|
|
86
|
+
"Do NOT create awkward distancing",
|
|
87
|
+
],
|
|
88
|
+
professional: [
|
|
89
|
+
"Do NOT use overly casual or intimate positioning",
|
|
90
|
+
],
|
|
91
|
+
neutral: [],
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// =============================================================================
|
|
95
|
+
// Builder Functions
|
|
96
|
+
// =============================================================================
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Generate person reference instructions for N people
|
|
100
|
+
*/
|
|
101
|
+
function buildPersonReferences(count: number): string {
|
|
102
|
+
if (count === 1) {
|
|
103
|
+
return "Use @image1 as the ONLY reference. The face must remain 100% identical to this image.";
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const refs = Array.from({ length: count }, (_, i) => {
|
|
107
|
+
const num = i + 1;
|
|
108
|
+
return `Person ${num}: Use @image${num} - preserve 100% identical facial appearance`;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return refs.join("\n");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Build face preservation prompt dynamically
|
|
116
|
+
* Supports any number of people (1, 2, 3, N)
|
|
117
|
+
*/
|
|
118
|
+
export function buildFacePreservationPrompt(options: FacePreservationOptions): string {
|
|
119
|
+
const { scenarioPrompt, personCount, customRules, customForbidden } = options;
|
|
120
|
+
|
|
121
|
+
const rules = [...FACE_LOCK_RULES, ...(customRules ?? [])];
|
|
122
|
+
const forbidden = [...FORBIDDEN_ACTIONS, ...(customForbidden ?? [])];
|
|
123
|
+
|
|
124
|
+
const personRefs = buildPersonReferences(personCount);
|
|
125
|
+
const personWord = personCount === 1 ? "person" : "people";
|
|
126
|
+
|
|
127
|
+
return `CRITICAL FACE PRESERVATION: Create a photorealistic image of EXACTLY the ${personCount} ${personWord} from the provided reference photo${personCount > 1 ? "s" : ""}.
|
|
128
|
+
|
|
129
|
+
REFERENCE IMAGES:
|
|
130
|
+
${personRefs}
|
|
131
|
+
|
|
132
|
+
FACE LOCK RULES:
|
|
133
|
+
${rules.map((r) => `- ${r}`).join("\n")}
|
|
134
|
+
|
|
135
|
+
FORBIDDEN:
|
|
136
|
+
${forbidden.map((f) => `- ${f}`).join("\n")}
|
|
137
|
+
|
|
138
|
+
SCENARIO:
|
|
139
|
+
${scenarioPrompt}
|
|
140
|
+
|
|
141
|
+
OUTPUT REQUIREMENTS:
|
|
142
|
+
- Photorealistic photograph quality (professional DSLR)
|
|
143
|
+
- Natural expressions and poses
|
|
144
|
+
- High resolution, detailed textures
|
|
145
|
+
- Each person's face must be 100% identical to their reference photo
|
|
146
|
+
|
|
147
|
+
FINAL VERIFICATION: Before output, confirm all faces match reference images exactly.`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Build a minimal face preservation prompt (for API character limits)
|
|
152
|
+
*/
|
|
153
|
+
export function buildMinimalFacePreservationPrompt(options: FacePreservationOptions): string {
|
|
154
|
+
const { scenarioPrompt, personCount } = options;
|
|
155
|
+
const personRefs = buildPersonReferences(personCount);
|
|
156
|
+
|
|
157
|
+
return `FACE IDENTITY LOCK: ${personCount} person(s) from reference photos.
|
|
158
|
+
${personRefs}
|
|
159
|
+
RULES: Preserve 100% facial identity, no modifications.
|
|
160
|
+
SCENARIO: ${scenarioPrompt}
|
|
161
|
+
OUTPUT: Photorealistic, faces identical to references.`;
|
|
162
|
+
}
|