@umituz/react-native-ai-generation-content 1.83.86 → 1.83.88
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.executor.ts +12 -27
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +1 -4
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.types.ts +1 -7
- package/src/domains/generation/wizard/presentation/hooks/wizard-generation.types.ts +1 -3
- package/src/domains/prompts/domain/base/constants.ts +0 -6
- package/src/domains/prompts/domain/base/creators.ts +0 -32
- package/src/domains/prompts/index.ts +4 -62
- package/src/domains/scenarios/domain/Scenario.ts +0 -8
- package/src/domains/scenarios/index.ts +0 -1
- package/src/domains/generation/wizard/infrastructure/strategies/shared/unified-prompt-builder.ts +0 -76
- package/src/domains/prompts/domain/entities/AIPromptTemplate.ts +0 -48
- package/src/domains/prompts/domain/entities/GeneratedPrompt.ts +0 -31
- package/src/domains/prompts/domain/entities/MultiPersonPromptStructure.ts +0 -67
- package/src/domains/prompts/domain/entities/image-prompt-segments.ts +0 -95
- package/src/domains/prompts/domain/entities/types.ts +0 -27
- package/src/domains/prompts/domain/entities/value-objects.ts +0 -33
- package/src/domains/prompts/domain/repositories/IAIPromptServices.ts +0 -21
- package/src/domains/prompts/domain/repositories/IPromptHistoryRepository.ts +0 -10
- package/src/domains/prompts/domain/repositories/ITemplateRepository.ts +0 -11
- package/src/domains/prompts/infrastructure/builders/face-preservation-builder.ts +0 -116
- package/src/domains/prompts/infrastructure/builders/interaction-style-builder.ts +0 -146
- package/src/domains/prompts/infrastructure/repositories/PromptHistoryRepository.ts +0 -45
- package/src/domains/prompts/infrastructure/repositories/TemplateRepository.ts +0 -77
- package/src/domains/prompts/infrastructure/services/ImagePromptBuilder.ts +0 -104
- package/src/domains/prompts/infrastructure/services/PromptGenerationService.ts +0 -59
- package/src/domains/prompts/infrastructure/services/image-prompt-builder.types.ts +0 -17
- package/src/domains/prompts/infrastructure/utils/prompt-creators.util.ts +0 -41
- package/src/domains/prompts/presentation/hooks/useAsyncState.ts +0 -56
- package/src/domains/prompts/presentation/hooks/usePromptGeneration.ts +0 -143
- package/src/domains/prompts/presentation/hooks/useTemplateRepository.ts +0 -113
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.83.
|
|
3
|
+
"version": "1.83.88",
|
|
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.executor.ts
CHANGED
|
@@ -3,17 +3,15 @@
|
|
|
3
3
|
* Handles the actual image generation execution
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { buildUnifiedPrompt } from "./shared/unified-prompt-builder";
|
|
7
6
|
import type { WizardImageInput } from "./image-generation.types";
|
|
8
7
|
import {
|
|
9
8
|
GENERATION_TIMEOUT_MS,
|
|
10
9
|
BASE64_IMAGE_PREFIX,
|
|
11
|
-
DEFAULT_STYLE_VALUE,
|
|
12
10
|
MODEL_INPUT_DEFAULTS,
|
|
13
11
|
} from "./wizard-strategy.constants";
|
|
12
|
+
import { createPhotorealisticPrompt } from "../../../../prompts/domain/base/creators";
|
|
14
13
|
import { addGenerationLogs, addGenerationLog, startGenerationLogSession } from "../../../../../infrastructure/services/generation-log-store";
|
|
15
14
|
|
|
16
|
-
|
|
17
15
|
interface ExecutionResult {
|
|
18
16
|
success: boolean;
|
|
19
17
|
imageUrl?: string;
|
|
@@ -25,29 +23,6 @@ function formatBase64(base64: string): string {
|
|
|
25
23
|
return base64.startsWith("data:") ? base64 : `${BASE64_IMAGE_PREFIX}${base64}`;
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
function buildFinalPrompt(input: WizardImageInput, imageUrls: string[]): string {
|
|
29
|
-
const hasPhotos = imageUrls.length > 0;
|
|
30
|
-
|
|
31
|
-
if (hasPhotos) {
|
|
32
|
-
// Custom prompt type means app provides complete prompt - skip identity preservation
|
|
33
|
-
const skipIdentityPreservation = input.promptType === "custom";
|
|
34
|
-
|
|
35
|
-
return buildUnifiedPrompt({
|
|
36
|
-
basePrompt: input.prompt,
|
|
37
|
-
photoCount: imageUrls.length,
|
|
38
|
-
interactionStyle: input.interactionStyle,
|
|
39
|
-
skipIdentityPreservation,
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Text-to-image with optional style
|
|
44
|
-
if (input.style && input.style !== DEFAULT_STYLE_VALUE) {
|
|
45
|
-
return `${input.prompt}. Style: ${input.style}`;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return input.prompt;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
26
|
export async function executeImageGeneration(
|
|
52
27
|
input: WizardImageInput,
|
|
53
28
|
model: string,
|
|
@@ -66,7 +41,17 @@ export async function executeImageGeneration(
|
|
|
66
41
|
|
|
67
42
|
try {
|
|
68
43
|
const imageUrls = input.photos.map(formatBase64);
|
|
69
|
-
|
|
44
|
+
|
|
45
|
+
// Photo-based: prompt is already complete (app builds it with Gemini analysis + scenario)
|
|
46
|
+
// Text-only: wrap with photorealistic style
|
|
47
|
+
const finalPrompt = imageUrls.length > 0
|
|
48
|
+
? input.prompt
|
|
49
|
+
: createPhotorealisticPrompt(input.prompt, {
|
|
50
|
+
includeIdentityPreservation: false,
|
|
51
|
+
includePhotoRealism: true,
|
|
52
|
+
includePoseGuidelines: true,
|
|
53
|
+
});
|
|
54
|
+
|
|
70
55
|
const mode = imageUrls.length > 0 ? "Photo-based" : "Text-to-image";
|
|
71
56
|
const totalImageSize = imageUrls.reduce((sum, url) => sum + url.length, 0);
|
|
72
57
|
|
package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
import type { WizardScenarioData } from "../../presentation/hooks/useWizardGeneration";
|
|
7
7
|
import type { WizardStrategy } from "./wizard-strategy.types";
|
|
8
8
|
import { DEFAULT_STYLE_VALUE, IMAGE_PROCESSING_PROMPTS } from "./wizard-strategy.constants";
|
|
9
|
-
import type { InteractionStyle } from "../../../../prompts/infrastructure/builders/interaction-style-builder";
|
|
10
9
|
import { extractPrompt, extractSelection } from "../utils";
|
|
11
10
|
import { extractPhotosAsBase64 } from "./shared/photo-extraction.utils";
|
|
12
11
|
import { executeImageGeneration } from "./image-generation.executor";
|
|
@@ -44,10 +43,8 @@ export async function buildImageInput(
|
|
|
44
43
|
// Extract style for text-to-image
|
|
45
44
|
const styleValue = extractSelection(wizardData.style);
|
|
46
45
|
const style = typeof styleValue === "string" ? styleValue : undefined;
|
|
47
|
-
const interactionStyle = scenario.interactionStyle as InteractionStyle | undefined;
|
|
48
|
-
const promptType = scenario.promptType;
|
|
49
46
|
|
|
50
|
-
return { photos, prompt: finalPrompt, style
|
|
47
|
+
return { photos, prompt: finalPrompt, style };
|
|
51
48
|
}
|
|
52
49
|
|
|
53
50
|
/**
|
|
@@ -3,20 +3,14 @@
|
|
|
3
3
|
* Type definitions for wizard image generation strategy
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { InteractionStyle } from "../../../../prompts/infrastructure/builders/interaction-style-builder";
|
|
7
6
|
import type { WizardScenarioData } from "../../presentation/hooks/useWizardGeneration";
|
|
8
|
-
import type { ScenarioPromptType } from "../../../../scenarios/domain/Scenario";
|
|
9
7
|
|
|
10
8
|
export interface WizardImageInput {
|
|
11
9
|
/** Photos are optional for text-to-image */
|
|
12
10
|
readonly photos: readonly string[];
|
|
13
11
|
readonly prompt: string;
|
|
14
|
-
/** Optional
|
|
15
|
-
readonly interactionStyle?: InteractionStyle;
|
|
16
|
-
/** Optional style from wizard selection */
|
|
12
|
+
/** Optional style from wizard selection (text-to-image only) */
|
|
17
13
|
readonly style?: string;
|
|
18
|
-
/** Prompt type - identity preservation or genetic blend */
|
|
19
|
-
readonly promptType?: ScenarioPromptType;
|
|
20
14
|
}
|
|
21
15
|
|
|
22
16
|
export interface CreateImageStrategyOptions {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { AlertMessages } from "../../../../../presentation/hooks/generation/types";
|
|
7
|
-
import type { ScenarioInputType
|
|
7
|
+
import type { ScenarioInputType } from "../../../../scenarios/domain/Scenario";
|
|
8
8
|
import type { VideoModelConfig } from "../../../../../domain/interfaces/video-model-config.types";
|
|
9
9
|
|
|
10
10
|
export type WizardOutputType = "image" | "video";
|
|
@@ -15,8 +15,6 @@ export interface WizardScenarioData {
|
|
|
15
15
|
readonly outputType?: WizardOutputType;
|
|
16
16
|
/** Input type - determines required photo count. Default: "single" */
|
|
17
17
|
readonly inputType?: ScenarioInputType;
|
|
18
|
-
/** Prompt type - identity preservation or genetic blend */
|
|
19
|
-
readonly promptType?: ScenarioPromptType;
|
|
20
18
|
readonly model?: string;
|
|
21
19
|
readonly title?: string;
|
|
22
20
|
readonly description?: string;
|
|
@@ -14,9 +14,3 @@ PROHIBITED: No anime, cartoons, illustrations, sketches, 3D renders, paintings,
|
|
|
14
14
|
|
|
15
15
|
export const NATURAL_POSE_GUIDELINES = `POSE: Natural, relaxed body language appropriate to the scenario context.
|
|
16
16
|
AVOID: No absurd poses, unnatural contortions, or physically impossible positions.`;
|
|
17
|
-
|
|
18
|
-
export const MASTER_BASE_PROMPT = `${IDENTITY_PRESERVATION_CORE}
|
|
19
|
-
|
|
20
|
-
${PHOTOREALISTIC_RENDERING}
|
|
21
|
-
|
|
22
|
-
${NATURAL_POSE_GUIDELINES}`;
|
|
@@ -42,35 +42,3 @@ export const createPhotorealisticPrompt = (
|
|
|
42
42
|
|
|
43
43
|
return parts.join('\n\n');
|
|
44
44
|
};
|
|
45
|
-
|
|
46
|
-
export const createTransformationPrompt = (
|
|
47
|
-
styleName: string,
|
|
48
|
-
costume: string,
|
|
49
|
-
background: string,
|
|
50
|
-
): string => `
|
|
51
|
-
${IDENTITY_PRESERVATION_CORE}
|
|
52
|
-
|
|
53
|
-
${PHOTOREALISTIC_RENDERING}
|
|
54
|
-
|
|
55
|
-
TRANSFORMATION REQUEST:
|
|
56
|
-
{
|
|
57
|
-
"target_theme": "${styleName}",
|
|
58
|
-
"modifications": {
|
|
59
|
-
"clothing_update": "${costume.replace(/\n/g, ' ').trim()}",
|
|
60
|
-
"environment_update": "${background.replace(/\n/g, ' ').trim()}"
|
|
61
|
-
},
|
|
62
|
-
"visual_constraints": {
|
|
63
|
-
"style_matching": "Render as a premium photograph",
|
|
64
|
-
"face_preservation": "Maintain 100% identity of the person",
|
|
65
|
-
"lighting": "Realistic professional recording lighting",
|
|
66
|
-
"pose": "Natural, contextually appropriate pose"
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
FINAL COMMAND: Transform the input person into a photorealistic ${styleName}. The result MUST be a real-life looking person in high-quality ${styleName} attire, maintaining perfect facial identity.`;
|
|
71
|
-
|
|
72
|
-
export const enhanceExistingPrompt = (existingPrompt: string): string => {
|
|
73
|
-
return `${IDENTITY_PRESERVATION_CORE}
|
|
74
|
-
|
|
75
|
-
${existingPrompt}`;
|
|
76
|
-
};
|
|
@@ -1,74 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Prompts - Public API
|
|
3
|
+
* Core prompt building blocks for AI image generation
|
|
3
4
|
*/
|
|
4
5
|
|
|
5
|
-
export type { AIPromptCategory, AIPromptVariableType, AIPromptError, AIPromptResult } from './domain/entities/types';
|
|
6
|
-
export type { AIPromptVariable, AIPromptSafety, AIPromptVersion } from './domain/entities/value-objects';
|
|
7
|
-
export { createPromptVersion, formatVersion } from './domain/entities/value-objects';
|
|
8
|
-
|
|
9
|
-
export type { AIPromptTemplate, CreateAIPromptTemplateParams } from './domain/entities/AIPromptTemplate';
|
|
10
|
-
export { createAIPromptTemplate, updateTemplateVersion, getTemplateString } from './domain/entities/AIPromptTemplate';
|
|
11
|
-
|
|
12
|
-
export type { GeneratedPrompt, CreateGeneratedPromptParams } from './domain/entities/GeneratedPrompt';
|
|
13
|
-
export { createGeneratedPrompt, isPromptRecent } from './domain/entities/GeneratedPrompt';
|
|
14
|
-
|
|
15
|
-
// Repository interfaces and implementations
|
|
16
|
-
export type { ITemplateRepository } from './domain/repositories/ITemplateRepository';
|
|
17
|
-
export type { IPromptHistoryRepository } from './domain/repositories/IPromptHistoryRepository';
|
|
18
|
-
export type { IPromptGenerationService } from './domain/repositories/IAIPromptServices';
|
|
19
|
-
|
|
20
|
-
export { TemplateRepository } from './infrastructure/repositories/TemplateRepository';
|
|
21
|
-
export { PromptHistoryRepository } from './infrastructure/repositories/PromptHistoryRepository';
|
|
22
|
-
export { PromptGenerationService } from './infrastructure/services/PromptGenerationService';
|
|
23
|
-
|
|
24
|
-
// Async state hook
|
|
25
|
-
export type { AsyncState, AsyncActions } from './presentation/hooks/useAsyncState';
|
|
26
|
-
export { useAsyncState } from './presentation/hooks/useAsyncState';
|
|
27
|
-
|
|
28
|
-
// Template repository hook
|
|
29
|
-
export type { UseTemplateState, UseTemplateActions } from './presentation/hooks/useTemplateRepository';
|
|
30
|
-
export { useTemplateRepository } from './presentation/hooks/useTemplateRepository';
|
|
31
|
-
|
|
32
|
-
// Prompt generation hook
|
|
33
|
-
export type { UsePromptGenerationState, UsePromptGenerationActions } from './presentation/hooks/usePromptGeneration';
|
|
34
|
-
export { usePromptGeneration } from './presentation/hooks/usePromptGeneration';
|
|
35
|
-
|
|
36
|
-
export { IDENTITY_SEGMENTS, IDENTITY_NEGATIVE_SEGMENTS, ANIME_STYLE_SEGMENTS, QUALITY_SEGMENTS, QUALITY_NEGATIVE_SEGMENTS, ANTI_REALISM_SEGMENTS, ANATOMY_NEGATIVE_SEGMENTS, PRESET_COLLECTIONS } from './domain/entities/image-prompt-segments';
|
|
37
|
-
export type { IdentitySegment, AnimeStyleSegment, QualitySegment } from './domain/entities/image-prompt-segments';
|
|
38
|
-
|
|
39
|
-
export { ImagePromptBuilder, createAnimeSelfiePrompt, createStyleTransferPrompt } from './infrastructure/services/ImagePromptBuilder';
|
|
40
|
-
export type { ImagePromptResult, ImagePromptBuilderOptions, AnimeSelfiePromptResult } from './infrastructure/services/ImagePromptBuilder';
|
|
41
|
-
|
|
42
6
|
export {
|
|
43
7
|
IDENTITY_PRESERVATION_CORE,
|
|
44
8
|
PHOTOREALISTIC_RENDERING,
|
|
45
9
|
NATURAL_POSE_GUIDELINES,
|
|
46
|
-
MASTER_BASE_PROMPT,
|
|
47
10
|
} from './domain/base/constants';
|
|
11
|
+
|
|
48
12
|
export {
|
|
49
13
|
createPhotorealisticPrompt,
|
|
50
|
-
createTransformationPrompt,
|
|
51
|
-
enhanceExistingPrompt,
|
|
52
14
|
} from './domain/base/creators';
|
|
53
|
-
export type { CreatePromptOptions } from './domain/base/types';
|
|
54
|
-
|
|
55
|
-
export {
|
|
56
|
-
MULTI_PERSON_PRESERVATION_RULES,
|
|
57
|
-
createMultiPersonBlock,
|
|
58
|
-
createMultiPersonPrompt,
|
|
59
|
-
} from './domain/entities/MultiPersonPromptStructure';
|
|
60
|
-
export type { MultiPersonPreservationRules } from './domain/entities/MultiPersonPromptStructure';
|
|
61
15
|
|
|
62
|
-
export {
|
|
63
|
-
buildFacePreservationPrompt,
|
|
64
|
-
buildMinimalFacePreservationPrompt,
|
|
65
|
-
} from './infrastructure/builders/face-preservation-builder';
|
|
66
|
-
export type { FacePreservationOptions } from './infrastructure/builders/face-preservation-builder';
|
|
67
|
-
|
|
68
|
-
export {
|
|
69
|
-
buildInteractionStylePrompt,
|
|
70
|
-
buildMinimalInteractionStylePrompt,
|
|
71
|
-
getInteractionRules,
|
|
72
|
-
getInteractionForbidden,
|
|
73
|
-
} from './infrastructure/builders/interaction-style-builder';
|
|
74
|
-
export type { InteractionStyle, InteractionStyleOptions } from './infrastructure/builders/interaction-style-builder';
|
|
16
|
+
export type { CreatePromptOptions } from './domain/base/types';
|
|
@@ -8,13 +8,6 @@ export type ScenarioOutputType = "image" | "video";
|
|
|
8
8
|
|
|
9
9
|
export type ScenarioInputType = "single" | "dual" | "text";
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
* Prompt type determines how multi-person prompts are built
|
|
13
|
-
* - identity: Preserve exact facial features from input photos (default)
|
|
14
|
-
* - custom: Use aiPrompt as-is without adding identity preservation (for app-specific scenarios)
|
|
15
|
-
*/
|
|
16
|
-
export type ScenarioPromptType = "identity" | "custom";
|
|
17
|
-
|
|
18
11
|
export interface GeneratingMessages {
|
|
19
12
|
title?: string;
|
|
20
13
|
waitMessage?: string;
|
|
@@ -39,7 +32,6 @@ export interface Scenario {
|
|
|
39
32
|
hidden?: boolean;
|
|
40
33
|
outputType?: ScenarioOutputType;
|
|
41
34
|
inputType?: ScenarioInputType;
|
|
42
|
-
promptType?: ScenarioPromptType;
|
|
43
35
|
model?: string;
|
|
44
36
|
enabled?: boolean;
|
|
45
37
|
generatingMessages?: GeneratingMessages;
|
package/src/domains/generation/wizard/infrastructure/strategies/shared/unified-prompt-builder.ts
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified Prompt Builder
|
|
3
|
-
* Single prompt building logic for ALL generation types (image & video)
|
|
4
|
-
*
|
|
5
|
-
* For photo-based scenarios: the app's scenario already uses createPhotorealisticPrompt()
|
|
6
|
-
* to build a structured prompt. This builder only injects the MULTI-PERSON block
|
|
7
|
-
* into that existing structure — it does NOT re-wrap.
|
|
8
|
-
*
|
|
9
|
-
* For text-only scenarios: uses createPhotorealisticPrompt for wrapping.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { IDENTITY_PRESERVATION_CORE } from "../../../../../prompts/domain/base/constants";
|
|
13
|
-
import {
|
|
14
|
-
createMultiPersonBlock,
|
|
15
|
-
createMultiPersonPrompt,
|
|
16
|
-
} from "../../../../../prompts/domain/entities/MultiPersonPromptStructure";
|
|
17
|
-
import { createPhotorealisticPrompt } from "../../../../../prompts/domain/base/creators";
|
|
18
|
-
|
|
19
|
-
interface BuildPromptOptions {
|
|
20
|
-
/** Base scenario prompt (aiPrompt from scenario config) */
|
|
21
|
-
readonly basePrompt: string;
|
|
22
|
-
/** Number of photos/people in generation */
|
|
23
|
-
readonly photoCount: number;
|
|
24
|
-
/** Interaction style from scenario (optional - only if scenario specifies it) */
|
|
25
|
-
readonly interactionStyle?: string;
|
|
26
|
-
/** Skip identity preservation (for custom prompts like genetic blend) */
|
|
27
|
-
readonly skipIdentityPreservation?: boolean;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Build unified prompt for any generation type
|
|
32
|
-
* - Photo-based (already structured): Injects MULTI-PERSON block into existing prompt
|
|
33
|
-
* - Photo-based (raw text): Full wrapping with createMultiPersonPrompt
|
|
34
|
-
* - Text-only: Uses createPhotorealisticPrompt
|
|
35
|
-
* - Custom: Uses basePrompt directly when skipIdentityPreservation is true
|
|
36
|
-
*/
|
|
37
|
-
export function buildUnifiedPrompt(options: BuildPromptOptions): string {
|
|
38
|
-
const { basePrompt, photoCount, interactionStyle, skipIdentityPreservation } = options;
|
|
39
|
-
|
|
40
|
-
// Text-only generation (no photos)
|
|
41
|
-
if (photoCount === 0) {
|
|
42
|
-
return createPhotorealisticPrompt(basePrompt, {
|
|
43
|
-
includeIdentityPreservation: false,
|
|
44
|
-
includePhotoRealism: true,
|
|
45
|
-
includePoseGuidelines: true,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Custom prompt handling (app provides complete prompt)
|
|
50
|
-
if (skipIdentityPreservation) {
|
|
51
|
-
return basePrompt;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Photo-based: check if prompt is already structured by createPhotorealisticPrompt
|
|
55
|
-
const isAlreadyStructured = basePrompt.includes(IDENTITY_PRESERVATION_CORE);
|
|
56
|
-
|
|
57
|
-
let finalPrompt: string;
|
|
58
|
-
|
|
59
|
-
if (isAlreadyStructured) {
|
|
60
|
-
// Prompt already has IDENTITY + PHOTOREALISTIC + POSE from createPhotorealisticPrompt.
|
|
61
|
-
// Only inject the MULTI-PERSON block after IDENTITY_PRESERVATION_CORE.
|
|
62
|
-
const multiPersonBlock = createMultiPersonBlock(photoCount);
|
|
63
|
-
const insertPos = basePrompt.indexOf(IDENTITY_PRESERVATION_CORE) + IDENTITY_PRESERVATION_CORE.length;
|
|
64
|
-
finalPrompt = basePrompt.slice(0, insertPos) + "\n\n" + multiPersonBlock + basePrompt.slice(insertPos);
|
|
65
|
-
} else {
|
|
66
|
-
// Raw text prompt — apply full wrapping
|
|
67
|
-
finalPrompt = createMultiPersonPrompt(basePrompt, photoCount);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Add interaction style if specified by scenario (no defaults)
|
|
71
|
-
if (interactionStyle) {
|
|
72
|
-
finalPrompt = `${finalPrompt}\n\nINTERACTION STYLE: ${interactionStyle}`;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return finalPrompt;
|
|
76
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import type { AIPromptCategory } from './types';
|
|
2
|
-
import type { AIPromptVariable, AIPromptSafety, AIPromptVersion } from './value-objects';
|
|
3
|
-
import { createPromptVersion, formatVersion } from './value-objects';
|
|
4
|
-
|
|
5
|
-
export interface AIPromptTemplate {
|
|
6
|
-
readonly id: string;
|
|
7
|
-
readonly name: string;
|
|
8
|
-
readonly description: string;
|
|
9
|
-
readonly category: AIPromptCategory;
|
|
10
|
-
readonly template: string;
|
|
11
|
-
readonly variables: readonly AIPromptVariable[];
|
|
12
|
-
readonly safety: AIPromptSafety;
|
|
13
|
-
readonly version: AIPromptVersion;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface CreateAIPromptTemplateParams {
|
|
17
|
-
id: string;
|
|
18
|
-
name: string;
|
|
19
|
-
description: string;
|
|
20
|
-
category: AIPromptCategory;
|
|
21
|
-
template: string;
|
|
22
|
-
variables?: AIPromptVariable[];
|
|
23
|
-
safety: AIPromptSafety;
|
|
24
|
-
version: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const createAIPromptTemplate = (
|
|
28
|
-
params: CreateAIPromptTemplateParams
|
|
29
|
-
): AIPromptTemplate => ({
|
|
30
|
-
id: params.id,
|
|
31
|
-
name: params.name,
|
|
32
|
-
description: params.description,
|
|
33
|
-
category: params.category,
|
|
34
|
-
template: params.template,
|
|
35
|
-
variables: params.variables || [],
|
|
36
|
-
safety: params.safety,
|
|
37
|
-
version: createPromptVersion(params.version),
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
export const updateTemplateVersion = (
|
|
41
|
-
template: AIPromptTemplate,
|
|
42
|
-
newVersion: string
|
|
43
|
-
): AIPromptTemplate => ({
|
|
44
|
-
...template,
|
|
45
|
-
version: createPromptVersion(newVersion),
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
export const getTemplateString = (template: AIPromptTemplate): string => formatVersion(template.version);
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
export interface GeneratedPrompt {
|
|
3
|
-
readonly id: string;
|
|
4
|
-
readonly templateId: string;
|
|
5
|
-
readonly generatedText: string;
|
|
6
|
-
readonly variables: Record<string, unknown>;
|
|
7
|
-
readonly timestamp: Date;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface CreateGeneratedPromptParams {
|
|
11
|
-
templateId: string;
|
|
12
|
-
generatedText: string;
|
|
13
|
-
variables: Record<string, unknown>;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const createGeneratedPrompt = (
|
|
17
|
-
params: CreateGeneratedPromptParams
|
|
18
|
-
): GeneratedPrompt => ({
|
|
19
|
-
id: `prompt_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
20
|
-
templateId: params.templateId,
|
|
21
|
-
generatedText: params.generatedText,
|
|
22
|
-
variables: params.variables,
|
|
23
|
-
timestamp: new Date(),
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
export const isPromptRecent = (prompt: GeneratedPrompt, hours: number = 24): boolean => {
|
|
27
|
-
const now = new Date();
|
|
28
|
-
const promptTime = new Date(prompt.timestamp);
|
|
29
|
-
const diffInHours = (now.getTime() - promptTime.getTime()) / (1000 * 60 * 60);
|
|
30
|
-
return diffInHours <= hours;
|
|
31
|
-
};
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { IDENTITY_PRESERVATION_CORE, NATURAL_POSE_GUIDELINES, PHOTOREALISTIC_RENDERING } from "../base/constants";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Multi-person identity preservation rules
|
|
5
|
-
* Ensures all people maintain their identities with strict rules
|
|
6
|
-
*/
|
|
7
|
-
export interface MultiPersonPreservationRules {
|
|
8
|
-
requirement: string;
|
|
9
|
-
perPersonRule: string;
|
|
10
|
-
forbidden: string[];
|
|
11
|
-
positioning: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const MULTI_PERSON_PRESERVATION_RULES: MultiPersonPreservationRules = {
|
|
15
|
-
requirement: "ALL individuals must have 100% identical facial appearance to their reference photos",
|
|
16
|
-
perPersonRule: "Use EXACTLY the person from @imageN - preserve 100% identical facial features",
|
|
17
|
-
forbidden: [
|
|
18
|
-
"Do NOT swap, mix, or blend facial features between people",
|
|
19
|
-
"Do NOT idealize or beautify any face",
|
|
20
|
-
"Do NOT alter facial proportions or characteristics",
|
|
21
|
-
],
|
|
22
|
-
positioning: "Natural positioning, all looking at camera with natural expressions",
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Creates ONLY the multi-person identity block (no full wrapping).
|
|
27
|
-
* Used to inject into an already-structured prompt.
|
|
28
|
-
*/
|
|
29
|
-
export const createMultiPersonBlock = (personCount: number): string => {
|
|
30
|
-
const personRefs = Array.from({ length: personCount }, (_, i) =>
|
|
31
|
-
`Person ${i + 1}: @image${i + 1} - preserve 100% facial identity`
|
|
32
|
-
).join("\n ");
|
|
33
|
-
|
|
34
|
-
return `MULTI-PERSON IDENTITY PRESERVATION (${personCount} people):
|
|
35
|
-
{
|
|
36
|
-
"requirement": "${MULTI_PERSON_PRESERVATION_RULES.requirement}",
|
|
37
|
-
"references": [
|
|
38
|
-
${personRefs}
|
|
39
|
-
],
|
|
40
|
-
"forbidden": ${JSON.stringify(MULTI_PERSON_PRESERVATION_RULES.forbidden)},
|
|
41
|
-
"positioning": "${MULTI_PERSON_PRESERVATION_RULES.positioning}"
|
|
42
|
-
}`;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Creates a multi-person prompt dynamically
|
|
47
|
-
* Used as fallback when basePrompt is raw text (not already structured).
|
|
48
|
-
*
|
|
49
|
-
* @param scenarioPrompt - The scenario description
|
|
50
|
-
* @param personCount - Number of people (1, 2, 3, N)
|
|
51
|
-
* @returns Complete prompt with identity preservation for all people
|
|
52
|
-
*/
|
|
53
|
-
export const createMultiPersonPrompt = (
|
|
54
|
-
scenarioPrompt: string,
|
|
55
|
-
personCount: number,
|
|
56
|
-
): string => {
|
|
57
|
-
return `${IDENTITY_PRESERVATION_CORE}
|
|
58
|
-
|
|
59
|
-
${createMultiPersonBlock(personCount)}
|
|
60
|
-
|
|
61
|
-
${PHOTOREALISTIC_RENDERING}
|
|
62
|
-
|
|
63
|
-
${NATURAL_POSE_GUIDELINES}
|
|
64
|
-
|
|
65
|
-
SCENARIO DESCRIPTION:
|
|
66
|
-
${scenarioPrompt}`;
|
|
67
|
-
};
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Image Prompt Segments - Reusable building blocks for AI image prompts
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export const IDENTITY_SEGMENTS = {
|
|
6
|
-
samePerson: "same person",
|
|
7
|
-
preserveIdentity: "preserve identity",
|
|
8
|
-
preserveGender: "STRICTLY preserve original gender",
|
|
9
|
-
keepGender: "keep exact same gender as input",
|
|
10
|
-
maintainGender: "maintain original sex",
|
|
11
|
-
sameFeatures: "same facial features",
|
|
12
|
-
preserveFace: "preserve original face structure",
|
|
13
|
-
sameHairColor: "same hair color as original",
|
|
14
|
-
sameEyeColor: "same eye color as original",
|
|
15
|
-
} as const;
|
|
16
|
-
|
|
17
|
-
export const IDENTITY_NEGATIVE_SEGMENTS = {
|
|
18
|
-
genderSwap: "gender swap",
|
|
19
|
-
genderChange: "gender change",
|
|
20
|
-
sexChange: "sex change",
|
|
21
|
-
maleToFemale: "male to female",
|
|
22
|
-
femaleToMale: "female to male",
|
|
23
|
-
differentPerson: "different person",
|
|
24
|
-
wrongGender: "wrong gender",
|
|
25
|
-
changedIdentity: "changed identity",
|
|
26
|
-
differentFace: "different face",
|
|
27
|
-
changedGender: "changed gender",
|
|
28
|
-
} as const;
|
|
29
|
-
|
|
30
|
-
export const ANIME_STYLE_SEGMENTS = {
|
|
31
|
-
animePortrait: "anime style portrait",
|
|
32
|
-
base: "2D anime illustration",
|
|
33
|
-
japaneseStyle: "japanese anime art style",
|
|
34
|
-
celShaded: "cel-shaded anime character",
|
|
35
|
-
animeEyes: "large sparkling anime eyes with detailed iris",
|
|
36
|
-
animeSkin: "smooth cel-shaded skin with subtle anime blush",
|
|
37
|
-
animeHair: "stylized anime hair with highlights",
|
|
38
|
-
ghibli: "Studio Ghibli inspired",
|
|
39
|
-
vibrantColors: "vibrant anime colors",
|
|
40
|
-
cleanLineart: "clean anime lineart",
|
|
41
|
-
professionalPortrait: "professional anime portrait",
|
|
42
|
-
handDrawn: "hand drawn anime",
|
|
43
|
-
mangaStyle: "manga style",
|
|
44
|
-
} as const;
|
|
45
|
-
|
|
46
|
-
export const QUALITY_SEGMENTS = {
|
|
47
|
-
highQuality: "high quality",
|
|
48
|
-
detailed: "highly detailed",
|
|
49
|
-
sharp: "sharp focus",
|
|
50
|
-
professional: "professional",
|
|
51
|
-
masterpiece: "masterpiece",
|
|
52
|
-
bestQuality: "best quality",
|
|
53
|
-
} as const;
|
|
54
|
-
|
|
55
|
-
export const QUALITY_NEGATIVE_SEGMENTS = {
|
|
56
|
-
lowQuality: "low quality",
|
|
57
|
-
blurry: "blurry",
|
|
58
|
-
pixelated: "pixelated",
|
|
59
|
-
artifacts: "jpeg artifacts",
|
|
60
|
-
watermark: "watermark",
|
|
61
|
-
signature: "signature",
|
|
62
|
-
} as const;
|
|
63
|
-
|
|
64
|
-
export const ANTI_REALISM_SEGMENTS = {
|
|
65
|
-
photorealistic: "photorealistic",
|
|
66
|
-
realisticPhoto: "realistic photo",
|
|
67
|
-
render3D: "3D render",
|
|
68
|
-
hyperrealistic: "hyperrealistic",
|
|
69
|
-
realPerson: "real person",
|
|
70
|
-
naturalSkin: "natural skin texture",
|
|
71
|
-
pores: "pores",
|
|
72
|
-
wrinkles: "wrinkles",
|
|
73
|
-
} as const;
|
|
74
|
-
|
|
75
|
-
export const ANATOMY_NEGATIVE_SEGMENTS = {
|
|
76
|
-
deformedFace: "deformed face",
|
|
77
|
-
badAnatomy: "bad anatomy",
|
|
78
|
-
extraLimbs: "extra limbs",
|
|
79
|
-
mutatedHands: "mutated hands",
|
|
80
|
-
extraFingers: "extra fingers",
|
|
81
|
-
missingFingers: "missing fingers",
|
|
82
|
-
} as const;
|
|
83
|
-
|
|
84
|
-
export const PRESET_COLLECTIONS = {
|
|
85
|
-
identityPreservation: Object.values(IDENTITY_SEGMENTS),
|
|
86
|
-
animeStyle: Object.values(ANIME_STYLE_SEGMENTS),
|
|
87
|
-
highQuality: Object.values(QUALITY_SEGMENTS),
|
|
88
|
-
antiRealism: Object.values(ANTI_REALISM_SEGMENTS),
|
|
89
|
-
anatomyNegative: Object.values(ANATOMY_NEGATIVE_SEGMENTS),
|
|
90
|
-
identityNegative: Object.values(IDENTITY_NEGATIVE_SEGMENTS),
|
|
91
|
-
} as const;
|
|
92
|
-
|
|
93
|
-
export type IdentitySegment = keyof typeof IDENTITY_SEGMENTS;
|
|
94
|
-
export type AnimeStyleSegment = keyof typeof ANIME_STYLE_SEGMENTS;
|
|
95
|
-
export type QualitySegment = keyof typeof QUALITY_SEGMENTS;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export type AIPromptCategory =
|
|
2
|
-
| 'face-swap'
|
|
3
|
-
| 'photo-restoration'
|
|
4
|
-
| 'image-enhancement'
|
|
5
|
-
| 'style-transfer'
|
|
6
|
-
| 'background-removal'
|
|
7
|
-
| 'object-detection'
|
|
8
|
-
| 'text-generation'
|
|
9
|
-
| 'colorization'
|
|
10
|
-
| 'content-generation'
|
|
11
|
-
| 'text-processing'
|
|
12
|
-
| 'future-prediction';
|
|
13
|
-
|
|
14
|
-
export type AIPromptVariableType = 'string' | 'number' | 'boolean' | 'select' | 'array';
|
|
15
|
-
|
|
16
|
-
export type AIPromptError =
|
|
17
|
-
| 'TEMPLATE_NOT_FOUND'
|
|
18
|
-
| 'INVALID_VARIABLES'
|
|
19
|
-
| 'GENERATION_FAILED'
|
|
20
|
-
| 'STORAGE_ERROR'
|
|
21
|
-
| 'NETWORK_ERROR'
|
|
22
|
-
| 'VALIDATION_ERROR'
|
|
23
|
-
| 'SERVICE_UNAVAILABLE';
|
|
24
|
-
|
|
25
|
-
export type AIPromptResult<T> =
|
|
26
|
-
| { success: true; data: T }
|
|
27
|
-
| { success: false; error: AIPromptError; message?: string };
|