@umituz/react-native-ai-generation-content 1.65.1 → 1.65.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 +1 -1
- package/src/domain/constants/processing-modes-catalog.constants.ts +97 -0
- package/src/domain/constants/processing-modes-filters.ts +34 -0
- package/src/domain/constants/processing-modes-getters.ts +20 -0
- package/src/domain/constants/processing-modes.constants.ts +8 -134
- package/src/domain/entities/feature-flow-config.types.ts +17 -0
- package/src/domain/entities/flow-actions.types.ts +26 -0
- package/src/domain/entities/flow-config-data.types.ts +41 -0
- package/src/domain/entities/flow-config.types.ts +17 -169
- package/src/domain/entities/flow-configuration.types.ts +44 -0
- package/src/domain/entities/flow-state.types.ts +30 -0
- package/src/domain/entities/flow-step.types.ts +56 -0
- package/src/domain/entities/scenario-step-config.types.ts +32 -0
- package/src/domain/entities/step-config.types.ts +14 -129
- package/src/domain/entities/step-definition.types.ts +50 -0
- package/src/domain/entities/step-input-config.types.ts +36 -0
- package/src/domain/entities/step-upload-config.types.ts +17 -0
- package/src/domain/interfaces/ai-provider-capabilities.types.ts +27 -0
- package/src/domain/interfaces/ai-provider-config.types.ts +30 -0
- package/src/domain/interfaces/ai-provider-feature-types.ts +22 -0
- package/src/domain/interfaces/ai-provider-input.types.ts +28 -0
- package/src/domain/interfaces/ai-provider-progress.types.ts +37 -0
- package/src/domain/interfaces/ai-provider-status.types.ts +41 -0
- package/src/domain/interfaces/ai-provider.interface.ts +32 -142
- package/src/domain/types/result-constructors.ts +20 -0
- package/src/domain/types/result-guards.ts +20 -0
- package/src/domain/types/result-transformers.ts +36 -0
- package/src/domain/types/result-type-definitions.ts +27 -0
- package/src/domain/types/result-unwrappers.ts +28 -0
- package/src/domain/types/result.types.ts +11 -100
- package/src/domains/background/infrastructure/utils/polling-interval.util.ts +3 -8
- package/src/domains/background/infrastructure/utils/result-validation-logic.ts +88 -0
- package/src/domains/background/infrastructure/utils/result-validator-constants.ts +18 -0
- package/src/domains/background/infrastructure/utils/result-validator.types.ts +16 -0
- package/src/domains/background/infrastructure/utils/result-validator.util.ts +8 -109
- package/src/domains/background/infrastructure/utils/status-checker.types.ts +11 -0
- package/src/domains/background/infrastructure/utils/status-checker.util.ts +9 -119
- package/src/domains/background/infrastructure/utils/status-error-detector.ts +61 -0
- package/src/domains/background/infrastructure/utils/status-extraction-helpers.ts +25 -0
- package/src/domains/background/infrastructure/utils/status-predicates.ts +37 -0
- package/src/domains/creations/domain-exports.ts +79 -0
- package/src/domains/creations/index.ts +9 -169
- package/src/domains/creations/infrastructure-exports.ts +9 -0
- package/src/domains/creations/presentation-exports.ts +59 -0
- package/src/domains/generation/infrastructure/executors/text-to-image-executor.helpers.ts +81 -0
- package/src/domains/generation/infrastructure/executors/text-to-image-executor.ts +4 -100
- package/src/domains/generation/infrastructure/executors/text-to-image-executor.types.ts +19 -0
- package/src/domains/generation/infrastructure/flow/use-flow-store.types.ts +19 -0
- package/src/domains/generation/infrastructure/flow/useFlowStore.ts +33 -65
- package/src/domains/generation/wizard/domain/entities/wizard-config-builder.ts +75 -0
- package/src/domains/generation/wizard/domain/entities/wizard-feature-config.types.ts +29 -0
- package/src/domains/generation/wizard/domain/entities/wizard-feature.types.ts +9 -114
- package/src/domains/generation/wizard/domain/entities/wizard-presets.constants.ts +23 -0
- package/src/domains/generation/wizard/infrastructure/strategies/shared/unified-prompt-builder.ts +1 -1
- package/src/domains/generation/wizard/infrastructure/utils/creation-persistence-factory.ts +33 -0
- package/src/domains/generation/wizard/infrastructure/utils/creation-persistence.types.ts +22 -0
- package/src/domains/generation/wizard/infrastructure/utils/creation-persistence.util.ts +11 -135
- package/src/domains/generation/wizard/infrastructure/utils/creation-save-operations.ts +48 -0
- package/src/domains/generation/wizard/infrastructure/utils/creation-update-operations.ts +72 -0
- package/src/domains/generation/wizard/presentation/hooks/use-video-queue-generation.types.ts +21 -0
- package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +14 -35
- package/src/domains/image-to-video/domain/types/image-to-video-callbacks.types.ts +33 -0
- package/src/domains/image-to-video/domain/types/image-to-video-config.types.ts +29 -0
- package/src/domains/image-to-video/domain/types/image-to-video-request.types.ts +31 -0
- package/src/domains/image-to-video/domain/types/image-to-video-result.types.ts +17 -0
- package/src/domains/image-to-video/domain/types/image-to-video-state.types.ts +24 -0
- package/src/domains/image-to-video/domain/types/image-to-video.types.ts +24 -114
- package/src/domains/image-to-video/infrastructure/services/image-to-video-executor.ts +26 -99
- package/src/domains/image-to-video/infrastructure/services/image-to-video-executor.types.ts +15 -0
- package/src/domains/prompts/domain/base/constants.ts +47 -0
- package/src/domains/prompts/domain/base/creators.ts +76 -0
- package/src/domains/prompts/domain/base/types.ts +10 -0
- package/src/domains/prompts/domain/entities/MultiPersonPromptStructure.ts +1 -1
- package/src/domains/prompts/index.ts +4 -2
- package/src/domains/prompts/infrastructure/services/ImagePromptBuilder.ts +2 -72
- package/src/domains/prompts/infrastructure/services/image-prompt-builder.types.ts +17 -0
- package/src/domains/result-preview/presentation/types/result-components.types.ts +47 -0
- package/src/domains/result-preview/presentation/types/result-creation.types.ts +14 -0
- package/src/domains/result-preview/presentation/types/result-data.types.ts +35 -0
- package/src/domains/result-preview/presentation/types/result-hooks.types.ts +35 -0
- package/src/domains/result-preview/presentation/types/result-preview.types.ts +19 -182
- package/src/domains/result-preview/presentation/types/result-screen.types.ts +69 -0
- package/src/domains/text-to-image/domain-exports.ts +50 -0
- package/src/domains/text-to-image/index.ts +11 -102
- package/src/domains/text-to-image/infrastructure-exports.ts +6 -0
- package/src/domains/text-to-image/presentation/hooks/useFormState.ts +39 -24
- package/src/domains/text-to-image/presentation/hooks/useGeneration.ts +5 -3
- package/src/domains/text-to-image/presentation-exports.ts +41 -0
- package/src/domains/text-to-video/domain/types/action-component.types.ts +15 -0
- package/src/domains/text-to-video/domain/types/component.types.ts +16 -103
- package/src/domains/text-to-video/domain/types/content-component.types.ts +30 -0
- package/src/domains/text-to-video/domain/types/panel-component.types.ts +24 -0
- package/src/domains/text-to-video/domain/types/selector-component.types.ts +31 -0
- package/src/domains/text-to-video/domain/types/tab-component.types.ts +26 -0
- package/src/index.ts +0 -10
- package/src/infrastructure/executors/base-executor.ts +40 -112
- package/src/infrastructure/executors/base-executor.types.ts +10 -0
- package/src/infrastructure/http/http-client-methods.ts +73 -0
- package/src/infrastructure/http/http-client.util.ts +8 -163
- package/src/infrastructure/http/http-fetch-handler.ts +53 -0
- package/src/infrastructure/http/http-methods.constants.ts +23 -0
- package/src/infrastructure/http/http-request-executor.ts +49 -0
- package/src/infrastructure/http/http-response-parser.ts +53 -0
- package/src/infrastructure/orchestration/GenerationOrchestrator.ts +8 -43
- package/src/infrastructure/utils/classifier-helpers.ts +36 -0
- package/src/infrastructure/utils/content-validators.ts +92 -0
- package/src/infrastructure/utils/domain-guards.ts +22 -0
- package/src/infrastructure/utils/error-classification.ts +122 -0
- package/src/infrastructure/utils/error-classifier.util.ts +8 -181
- package/src/infrastructure/utils/error-classifiers.ts +49 -0
- package/src/infrastructure/utils/error-extractors.ts +42 -0
- package/src/infrastructure/utils/error-factory.ts +25 -0
- package/src/infrastructure/utils/error-handlers.ts +51 -0
- package/src/infrastructure/utils/error-handling.util.ts +7 -186
- package/src/infrastructure/utils/error-message-extractor.util.ts +10 -172
- package/src/infrastructure/utils/error-retry.ts +44 -0
- package/src/infrastructure/utils/error-types.ts +23 -0
- package/src/infrastructure/utils/extraction-types.ts +37 -0
- package/src/infrastructure/utils/fal-error-checker.ts +44 -0
- package/src/infrastructure/utils/general-validators.ts +64 -0
- package/src/infrastructure/utils/id-validators.ts +39 -0
- package/src/infrastructure/utils/message-extractor.ts +89 -0
- package/src/infrastructure/utils/primitive-guards.ts +66 -0
- package/src/infrastructure/utils/result-polling.ts +39 -0
- package/src/infrastructure/utils/structure-guards.ts +75 -0
- package/src/infrastructure/utils/type-guards.util.ts +22 -149
- package/src/infrastructure/utils/validation-types.ts +8 -0
- package/src/infrastructure/utils/validation.util.ts +14 -184
- package/src/presentation/hooks/ai-feature-callbacks-auth.hooks.ts +43 -0
- package/src/presentation/hooks/ai-feature-callbacks-cost.hooks.ts +56 -0
- package/src/presentation/hooks/ai-feature-callbacks-execution.hooks.ts +66 -0
- package/src/presentation/hooks/ai-feature-callbacks.types.ts +69 -0
- package/src/presentation/hooks/generation/use-image-generation.types.ts +39 -0
- package/src/presentation/hooks/generation/useImageGeneration.ts +33 -99
- package/src/presentation/hooks/generation-flow-navigation.ts +58 -0
- package/src/presentation/hooks/generation-flow-updates.ts +67 -0
- package/src/presentation/hooks/generation-flow.types.ts +32 -0
- package/src/presentation/hooks/useAIFeatureCallbacks.ts +48 -138
- package/src/presentation/hooks/useGenerationFlow.ts +40 -136
- package/src/presentation/types/flow-config.types.ts +9 -140
- package/src/presentation/types/flow-generation-config.types.ts +25 -0
- package/src/presentation/types/flow-state.types.ts +16 -0
- package/src/presentation/types/flow-step-configs.types.ts +48 -0
- package/src/presentation/types/flow-step-data.types.ts +24 -0
- package/src/presentation/types/result-actions.types.ts +50 -0
- package/src/presentation/types/result-config.types.ts +22 -171
- package/src/presentation/types/result-header.types.ts +44 -0
- package/src/presentation/types/result-image.types.ts +29 -0
- package/src/presentation/types/result-layout.types.ts +26 -0
- package/src/presentation/types/result-story.types.ts +42 -0
- package/src/domains/prompts/domain/entities/BasePromptStructure.ts +0 -168
- package/src/exports/domains.ts +0 -149
|
@@ -1,118 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Image-to-Video Feature Types
|
|
2
|
+
* Image-to-Video Feature Types - Barrel Export
|
|
3
3
|
* Request, Result, Config types for image-to-video generation
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
animationStyle?: AnimationStyleId;
|
|
30
|
-
duration?: VideoDuration;
|
|
31
|
-
model?: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface ImageToVideoResult {
|
|
35
|
-
success: boolean;
|
|
36
|
-
videoUrl?: string;
|
|
37
|
-
thumbnailUrl?: string;
|
|
38
|
-
error?: string;
|
|
39
|
-
requestId?: string;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface ImageToVideoGenerationState {
|
|
43
|
-
isGenerating: boolean;
|
|
44
|
-
progress: number;
|
|
45
|
-
error: string | null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface ImageToVideoFeatureState {
|
|
49
|
-
imageUri: string | null;
|
|
50
|
-
motionPrompt: string;
|
|
51
|
-
videoUrl: string | null;
|
|
52
|
-
thumbnailUrl: string | null;
|
|
53
|
-
isProcessing: boolean;
|
|
54
|
-
progress: number;
|
|
55
|
-
error: string | null;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export interface ImageToVideoTranslations {
|
|
59
|
-
uploadTitle: string;
|
|
60
|
-
uploadSubtitle: string;
|
|
61
|
-
motionPromptPlaceholder: string;
|
|
62
|
-
generateButtonText: string;
|
|
63
|
-
processingText: string;
|
|
64
|
-
successText: string;
|
|
65
|
-
saveButtonText: string;
|
|
66
|
-
tryAnotherText: string;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export type ImageToVideoInputBuilder = (
|
|
70
|
-
imageBase64: string,
|
|
71
|
-
motionPrompt?: string,
|
|
72
|
-
options?: ImageToVideoOptions,
|
|
73
|
-
) => Record<string, unknown>;
|
|
74
|
-
|
|
75
|
-
export type ImageToVideoResultExtractor = (
|
|
76
|
-
result: unknown,
|
|
77
|
-
) => { videoUrl?: string; thumbnailUrl?: string } | undefined;
|
|
78
|
-
|
|
79
|
-
export interface ImageToVideoFeatureCallbacks {
|
|
80
|
-
onCreditCheck?: (cost: number) => Promise<boolean>;
|
|
81
|
-
onCreditDeduct?: (cost: number) => Promise<void>;
|
|
82
|
-
onAuthCheck?: () => boolean;
|
|
83
|
-
onShowPaywall?: (creditCost: number) => void;
|
|
84
|
-
onGenerationStart?: (data: ImageToVideoGenerationStartData) => Promise<void>;
|
|
85
|
-
onCreationSave?: (data: ImageToVideoCreationData) => Promise<void>;
|
|
86
|
-
onGenerate?: (result: ImageToVideoResult) => void;
|
|
87
|
-
onProgress?: (progress: number) => void;
|
|
88
|
-
onError?: (error: string) => void;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export interface ImageToVideoGenerationStartData {
|
|
92
|
-
creationId: string;
|
|
93
|
-
type: string;
|
|
94
|
-
imageUri: string;
|
|
95
|
-
metadata?: Record<string, unknown>;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export interface ImageToVideoCreationData {
|
|
99
|
-
creationId: string;
|
|
100
|
-
type: string;
|
|
101
|
-
videoUrl: string;
|
|
102
|
-
thumbnailUrl?: string;
|
|
103
|
-
imageUri: string;
|
|
104
|
-
metadata?: Record<string, unknown>;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export interface ImageToVideoFeatureConfig {
|
|
108
|
-
providerId?: string;
|
|
109
|
-
creditCost?: number;
|
|
110
|
-
model: string;
|
|
111
|
-
buildInput: ImageToVideoInputBuilder;
|
|
112
|
-
extractResult?: ImageToVideoResultExtractor;
|
|
113
|
-
prepareImage: (imageUri: string) => Promise<string>;
|
|
114
|
-
onImageSelect?: (uri: string) => void;
|
|
115
|
-
onProcessingStart?: () => void;
|
|
116
|
-
onProcessingComplete?: (result: ImageToVideoResult) => void;
|
|
117
|
-
onError?: (error: string) => void;
|
|
118
|
-
}
|
|
6
|
+
export type {
|
|
7
|
+
ImageToVideoOptions,
|
|
8
|
+
ImageToVideoGenerateParams,
|
|
9
|
+
ImageToVideoRequest,
|
|
10
|
+
} from "./image-to-video-request.types";
|
|
11
|
+
export type {
|
|
12
|
+
ImageToVideoResult,
|
|
13
|
+
ImageToVideoGenerationState,
|
|
14
|
+
} from "./image-to-video-result.types";
|
|
15
|
+
export type {
|
|
16
|
+
ImageToVideoFeatureState,
|
|
17
|
+
ImageToVideoTranslations,
|
|
18
|
+
} from "./image-to-video-state.types";
|
|
19
|
+
export type {
|
|
20
|
+
ImageToVideoGenerationStartData,
|
|
21
|
+
ImageToVideoCreationData,
|
|
22
|
+
ImageToVideoFeatureCallbacks,
|
|
23
|
+
} from "./image-to-video-callbacks.types";
|
|
24
|
+
export type {
|
|
25
|
+
ImageToVideoInputBuilder,
|
|
26
|
+
ImageToVideoResultExtractor,
|
|
27
|
+
ImageToVideoFeatureConfig,
|
|
28
|
+
} from "./image-to-video-config.types";
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Image-to-Video Executor
|
|
3
|
-
* Provider-agnostic image-to-video execution using Template Method pattern
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
5
|
import { BaseExecutor } from "../../../../infrastructure/executors/base-executor";
|
|
@@ -11,48 +10,18 @@ import {
|
|
|
11
10
|
type ExtractedVideoResult,
|
|
12
11
|
} from "../../../../infrastructure/utils/video-result-extractor.util";
|
|
13
12
|
import type { IAIProvider } from "../../../../domain/interfaces";
|
|
14
|
-
import type {
|
|
15
|
-
ImageToVideoRequest,
|
|
16
|
-
ImageToVideoResult,
|
|
17
|
-
ImageToVideoInputBuilder,
|
|
18
|
-
ImageToVideoResultExtractor,
|
|
19
|
-
} from "../../domain/types";
|
|
13
|
+
import type { ImageToVideoRequest, ImageToVideoResult } from "../../domain/types";
|
|
20
14
|
import { env } from "../../../../infrastructure/config/env.config";
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
onProgress?: (progress: number) => void;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Map job status to progress percentage
|
|
34
|
-
*/
|
|
35
|
-
const getProgressFromJobStatus = (status: string): number => {
|
|
36
|
-
switch (status.toLowerCase()) {
|
|
37
|
-
case "queued":
|
|
38
|
-
return 10;
|
|
39
|
-
case "in_queue":
|
|
40
|
-
return 15;
|
|
41
|
-
case "processing":
|
|
42
|
-
return 50;
|
|
43
|
-
case "in_progress":
|
|
44
|
-
return 60;
|
|
45
|
-
case "completed":
|
|
46
|
-
return 100;
|
|
47
|
-
default:
|
|
48
|
-
return 30;
|
|
49
|
-
}
|
|
15
|
+
import type { ExecuteImageToVideoOptions } from "./image-to-video-executor.types";
|
|
16
|
+
|
|
17
|
+
const STATUS_PROGRESS: Record<string, number> = {
|
|
18
|
+
queued: 10,
|
|
19
|
+
in_queue: 15,
|
|
20
|
+
processing: 50,
|
|
21
|
+
in_progress: 60,
|
|
22
|
+
completed: 100,
|
|
50
23
|
};
|
|
51
24
|
|
|
52
|
-
/**
|
|
53
|
-
* Image-to-Video Executor using Template Method pattern
|
|
54
|
-
* Eliminates code duplication through BaseExecutor
|
|
55
|
-
*/
|
|
56
25
|
class ImageToVideoExecutor extends BaseExecutor<
|
|
57
26
|
ImageToVideoRequest,
|
|
58
27
|
ImageToVideoResult,
|
|
@@ -62,13 +31,8 @@ class ImageToVideoExecutor extends BaseExecutor<
|
|
|
62
31
|
super("ImageToVideo");
|
|
63
32
|
}
|
|
64
33
|
|
|
65
|
-
protected validateRequest(
|
|
66
|
-
request:
|
|
67
|
-
): string | undefined {
|
|
68
|
-
if (!request.imageBase64) {
|
|
69
|
-
return "Image base64 is required";
|
|
70
|
-
}
|
|
71
|
-
return undefined;
|
|
34
|
+
protected validateRequest(request: ImageToVideoRequest): string | undefined {
|
|
35
|
+
return request.imageBase64 ? undefined : "Image base64 is required";
|
|
72
36
|
}
|
|
73
37
|
|
|
74
38
|
protected async executeProvider(
|
|
@@ -79,42 +43,24 @@ class ImageToVideoExecutor extends BaseExecutor<
|
|
|
79
43
|
): Promise<unknown> {
|
|
80
44
|
this.logInfo("Starting provider.subscribe()...");
|
|
81
45
|
|
|
82
|
-
// Use subscribe for video generation (long-running operation with queue)
|
|
83
|
-
// Provider reports real progress via onQueueUpdate callback
|
|
84
46
|
const result = await provider.subscribe(model, input, {
|
|
85
47
|
onQueueUpdate: (status: { status: string; queuePosition?: number }) => {
|
|
86
|
-
this.logInfo(
|
|
87
|
-
|
|
88
|
-
);
|
|
89
|
-
// Map provider status to progress
|
|
90
|
-
const progress = getProgressFromJobStatus(status.status);
|
|
91
|
-
onProgress?.(progress);
|
|
48
|
+
this.logInfo(`Queue: ${status.status}, pos: ${status.queuePosition}`);
|
|
49
|
+
onProgress?.(STATUS_PROGRESS[status.status.toLowerCase()] ?? 30);
|
|
92
50
|
},
|
|
93
51
|
timeoutMs: env.generationVideoTimeoutMs,
|
|
94
52
|
});
|
|
95
53
|
|
|
96
|
-
this.logInfo(
|
|
97
|
-
`Subscribe resolved, result keys: ${result ? Object.keys(result as object) : "null"}`,
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
// FAL can return errors with COMPLETED status - check for this
|
|
54
|
+
this.logInfo(`Complete, keys: ${result ? Object.keys(result as object) : "null"}`);
|
|
101
55
|
checkFalApiError(result);
|
|
102
|
-
|
|
103
56
|
return result;
|
|
104
57
|
}
|
|
105
58
|
|
|
106
|
-
protected validateExtractedResult(
|
|
107
|
-
extracted:
|
|
108
|
-
): string | undefined {
|
|
109
|
-
if (!extracted?.videoUrl) {
|
|
110
|
-
return "No video in response";
|
|
111
|
-
}
|
|
112
|
-
return undefined;
|
|
59
|
+
protected validateExtractedResult(extracted: ExtractedVideoResult | undefined): string | undefined {
|
|
60
|
+
return extracted?.videoUrl ? undefined : "No video in response";
|
|
113
61
|
}
|
|
114
62
|
|
|
115
|
-
protected transformResult(
|
|
116
|
-
extracted: ExtractedVideoResult,
|
|
117
|
-
): ImageToVideoResult {
|
|
63
|
+
protected transformResult(extracted: ExtractedVideoResult): ImageToVideoResult {
|
|
118
64
|
return {
|
|
119
65
|
success: true,
|
|
120
66
|
videoUrl: extracted.videoUrl,
|
|
@@ -122,46 +68,27 @@ class ImageToVideoExecutor extends BaseExecutor<
|
|
|
122
68
|
};
|
|
123
69
|
}
|
|
124
70
|
|
|
125
|
-
protected getDefaultExtractor(): (
|
|
126
|
-
result: unknown,
|
|
127
|
-
) => ExtractedVideoResult | undefined {
|
|
71
|
+
protected getDefaultExtractor(): (result: unknown) => ExtractedVideoResult | undefined {
|
|
128
72
|
return defaultExtractVideoResult;
|
|
129
73
|
}
|
|
130
74
|
}
|
|
131
75
|
|
|
132
|
-
// Singleton instance
|
|
133
76
|
const executor = new ImageToVideoExecutor();
|
|
134
77
|
|
|
135
|
-
/**
|
|
136
|
-
* Execute image-to-video generation
|
|
137
|
-
* Public API
|
|
138
|
-
*/
|
|
139
78
|
export async function executeImageToVideo(
|
|
140
79
|
request: ImageToVideoRequest,
|
|
141
80
|
options: ExecuteImageToVideoOptions,
|
|
142
81
|
): Promise<ImageToVideoResult> {
|
|
143
|
-
const result: Result<ImageToVideoResult, string> = await executor.execute(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
},
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
// Convert Result<T, E> to return format
|
|
155
|
-
if (isSuccess(result)) {
|
|
156
|
-
return result.value;
|
|
157
|
-
}
|
|
158
|
-
return { success: false, error: result.error };
|
|
82
|
+
const result: Result<ImageToVideoResult, string> = await executor.execute(request, {
|
|
83
|
+
model: options.model,
|
|
84
|
+
buildInput: (req) => options.buildInput(req.imageBase64!, req.motionPrompt, req.options),
|
|
85
|
+
extractResult: options.extractResult,
|
|
86
|
+
onProgress: options.onProgress,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
return isSuccess(result) ? result.value : { success: false, error: result.error };
|
|
159
90
|
}
|
|
160
91
|
|
|
161
|
-
/**
|
|
162
|
-
* Check if image-to-video is supported
|
|
163
|
-
* Public API
|
|
164
|
-
*/
|
|
165
92
|
export function hasImageToVideoSupport(): boolean {
|
|
166
93
|
return executor.hasSupport();
|
|
167
94
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image-to-Video Executor Types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
ImageToVideoInputBuilder,
|
|
7
|
+
ImageToVideoResultExtractor,
|
|
8
|
+
} from "../../domain/types";
|
|
9
|
+
|
|
10
|
+
export interface ExecuteImageToVideoOptions {
|
|
11
|
+
model: string;
|
|
12
|
+
buildInput: ImageToVideoInputBuilder;
|
|
13
|
+
extractResult?: ImageToVideoResultExtractor;
|
|
14
|
+
onProgress?: (progress: number) => void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Prompt Structure Constants
|
|
3
|
+
* Core prompt building blocks for AI image generation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const IDENTITY_PRESERVATION_CORE = `CRITICAL IDENTITY PRESERVATION (HIGHEST PRIORITY):
|
|
7
|
+
{
|
|
8
|
+
"policy": "PRESERVE 100% IDENTICAL FACIAL APPEARANCE FROM INPUT",
|
|
9
|
+
"mandatory_rules": [
|
|
10
|
+
"The face must be EXACTLY as it appears in the reference photo - 100% identical",
|
|
11
|
+
"Preserve every facial detail: bone structure, eye shape, eye color, nose shape, lip shape",
|
|
12
|
+
"Keep the person instantly recognizable - any deviation is NOT acceptable"
|
|
13
|
+
],
|
|
14
|
+
"forbidden_modifications": [
|
|
15
|
+
"Do NOT change face shape or facial proportions",
|
|
16
|
+
"Do NOT alter eye color, eye shape, or eye spacing",
|
|
17
|
+
"Do NOT modify nose shape, size, or position",
|
|
18
|
+
"Do NOT change lip shape, thickness, or natural expression",
|
|
19
|
+
"Do NOT remove natural features like freckles, moles, or wrinkles"
|
|
20
|
+
],
|
|
21
|
+
"verification": "Before output: confirm face matches reference photo with 100% accuracy"
|
|
22
|
+
}`;
|
|
23
|
+
|
|
24
|
+
export const PHOTOREALISTIC_RENDERING = `PHOTOREALISTIC RENDERING REQUIREMENTS:
|
|
25
|
+
{
|
|
26
|
+
"style": "PHOTOREALISTIC PHOTOGRAPH",
|
|
27
|
+
"quality": "high quality, professional photography",
|
|
28
|
+
"lighting": "Natural lighting with realistic shadows and highlights",
|
|
29
|
+
"prohibited": "STRICTLY NO anime, cartoons, illustrations, sketches, 3D renders, or non-photorealistic styles",
|
|
30
|
+
"output": "Must look like a real photograph"
|
|
31
|
+
}`;
|
|
32
|
+
|
|
33
|
+
export const NATURAL_POSE_GUIDELINES = `NATURAL POSE AND FRAMING:
|
|
34
|
+
{
|
|
35
|
+
"framing": "Medium-shot cinematic portrait (waist-up or full-body as appropriate)",
|
|
36
|
+
"pose": "Natural, relaxed pose - standing, sitting, or contextually appropriate position",
|
|
37
|
+
"eye_contact": "Looking directly at the camera with natural expression",
|
|
38
|
+
"body_language": "Confident, natural body language without exaggerated or awkward positions",
|
|
39
|
+
"interaction": "If multiple people: standing side-by-side, close together, or naturally interacting",
|
|
40
|
+
"avoid": "NO absurd poses, unnatural contortions, or physically impossible positions"
|
|
41
|
+
}`;
|
|
42
|
+
|
|
43
|
+
export const MASTER_BASE_PROMPT = `${IDENTITY_PRESERVATION_CORE}
|
|
44
|
+
|
|
45
|
+
${PHOTOREALISTIC_RENDERING}
|
|
46
|
+
|
|
47
|
+
${NATURAL_POSE_GUIDELINES}`;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Prompt Creators
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
IDENTITY_PRESERVATION_CORE,
|
|
7
|
+
PHOTOREALISTIC_RENDERING,
|
|
8
|
+
NATURAL_POSE_GUIDELINES,
|
|
9
|
+
} from "./constants";
|
|
10
|
+
import type { CreatePromptOptions } from "./types";
|
|
11
|
+
|
|
12
|
+
export const createPhotorealisticPrompt = (
|
|
13
|
+
scenarioPrompt: string,
|
|
14
|
+
options: CreatePromptOptions = {}
|
|
15
|
+
): string => {
|
|
16
|
+
const {
|
|
17
|
+
includeIdentityPreservation = true,
|
|
18
|
+
includePhotoRealism = true,
|
|
19
|
+
includePoseGuidelines = true,
|
|
20
|
+
customInstructions,
|
|
21
|
+
} = options;
|
|
22
|
+
|
|
23
|
+
const parts: string[] = [];
|
|
24
|
+
|
|
25
|
+
if (includeIdentityPreservation) {
|
|
26
|
+
parts.push(IDENTITY_PRESERVATION_CORE);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (includePhotoRealism) {
|
|
30
|
+
parts.push(PHOTOREALISTIC_RENDERING);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (includePoseGuidelines) {
|
|
34
|
+
parts.push(NATURAL_POSE_GUIDELINES);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (customInstructions) {
|
|
38
|
+
parts.push(customInstructions);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
parts.push(`\nSCENARIO DESCRIPTION:\n${scenarioPrompt}`);
|
|
42
|
+
|
|
43
|
+
return parts.join('\n\n');
|
|
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,4 +1,4 @@
|
|
|
1
|
-
import { IDENTITY_PRESERVATION_CORE, NATURAL_POSE_GUIDELINES, PHOTOREALISTIC_RENDERING } from "
|
|
1
|
+
import { IDENTITY_PRESERVATION_CORE, NATURAL_POSE_GUIDELINES, PHOTOREALISTIC_RENDERING } from "../base/constants";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Multi-person identity preservation rules
|
|
@@ -44,11 +44,13 @@ export {
|
|
|
44
44
|
PHOTOREALISTIC_RENDERING,
|
|
45
45
|
NATURAL_POSE_GUIDELINES,
|
|
46
46
|
MASTER_BASE_PROMPT,
|
|
47
|
+
} from './domain/base/constants';
|
|
48
|
+
export {
|
|
47
49
|
createPhotorealisticPrompt,
|
|
48
50
|
createTransformationPrompt,
|
|
49
51
|
enhanceExistingPrompt,
|
|
50
|
-
} from './domain/
|
|
51
|
-
export type { CreatePromptOptions } from './domain/
|
|
52
|
+
} from './domain/base/creators';
|
|
53
|
+
export type { CreatePromptOptions } from './domain/base/types';
|
|
52
54
|
|
|
53
55
|
export {
|
|
54
56
|
MULTI_PERSON_PRESERVATION_RULES,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ImagePromptBuilder - Fluent builder for
|
|
2
|
+
* ImagePromptBuilder - Fluent builder for AI image generation prompts
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import {
|
|
@@ -11,20 +11,7 @@ import {
|
|
|
11
11
|
ANTI_REALISM_SEGMENTS,
|
|
12
12
|
ANATOMY_NEGATIVE_SEGMENTS,
|
|
13
13
|
} from "../../domain/entities/image-prompt-segments";
|
|
14
|
-
|
|
15
|
-
export interface ImagePromptResult {
|
|
16
|
-
prompt: string;
|
|
17
|
-
negativePrompt: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface AnimeSelfiePromptResult {
|
|
21
|
-
prompt: string;
|
|
22
|
-
guidance_scale: number;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface ImagePromptBuilderOptions {
|
|
26
|
-
separator?: string;
|
|
27
|
-
}
|
|
14
|
+
import type { ImagePromptResult, ImagePromptBuilderOptions } from "./image-prompt-builder.types";
|
|
28
15
|
|
|
29
16
|
export class ImagePromptBuilder {
|
|
30
17
|
private positiveSegments: string[] = [];
|
|
@@ -35,99 +22,63 @@ export class ImagePromptBuilder {
|
|
|
35
22
|
this.separator = options?.separator ?? ", ";
|
|
36
23
|
}
|
|
37
24
|
|
|
38
|
-
/**
|
|
39
|
-
* Create a new ImagePromptBuilder instance
|
|
40
|
-
*/
|
|
41
25
|
static create(options?: ImagePromptBuilderOptions): ImagePromptBuilder {
|
|
42
26
|
return new ImagePromptBuilder(options);
|
|
43
27
|
}
|
|
44
28
|
|
|
45
|
-
/**
|
|
46
|
-
* Add identity preservation prompts - ensures AI preserves original person's features
|
|
47
|
-
*/
|
|
48
29
|
withIdentityPreservation(): this {
|
|
49
30
|
this.positiveSegments.push(...Object.values(IDENTITY_SEGMENTS));
|
|
50
31
|
this.negativeSegments.push(...Object.values(IDENTITY_NEGATIVE_SEGMENTS));
|
|
51
32
|
return this;
|
|
52
33
|
}
|
|
53
34
|
|
|
54
|
-
/**
|
|
55
|
-
* Add anime style prompts
|
|
56
|
-
*/
|
|
57
35
|
withAnimeStyle(): this {
|
|
58
36
|
this.positiveSegments.push(...Object.values(ANIME_STYLE_SEGMENTS));
|
|
59
37
|
this.negativeSegments.push(...Object.values(ANTI_REALISM_SEGMENTS));
|
|
60
38
|
return this;
|
|
61
39
|
}
|
|
62
40
|
|
|
63
|
-
/**
|
|
64
|
-
* Add quality enhancement prompts
|
|
65
|
-
*/
|
|
66
41
|
withQuality(): this {
|
|
67
42
|
this.positiveSegments.push(...Object.values(QUALITY_SEGMENTS));
|
|
68
43
|
this.negativeSegments.push(...Object.values(QUALITY_NEGATIVE_SEGMENTS));
|
|
69
44
|
return this;
|
|
70
45
|
}
|
|
71
46
|
|
|
72
|
-
/**
|
|
73
|
-
* Add anatomy safety negative prompts
|
|
74
|
-
*/
|
|
75
47
|
withAnatomySafety(): this {
|
|
76
48
|
this.negativeSegments.push(...Object.values(ANATOMY_NEGATIVE_SEGMENTS));
|
|
77
49
|
return this;
|
|
78
50
|
}
|
|
79
51
|
|
|
80
|
-
/**
|
|
81
|
-
* Add anti-realism prompts (for stylized outputs)
|
|
82
|
-
*/
|
|
83
52
|
withAntiRealism(): this {
|
|
84
53
|
this.negativeSegments.push(...Object.values(ANTI_REALISM_SEGMENTS));
|
|
85
54
|
return this;
|
|
86
55
|
}
|
|
87
56
|
|
|
88
|
-
/**
|
|
89
|
-
* Add custom positive segments
|
|
90
|
-
*/
|
|
91
57
|
withSegments(segments: string[]): this {
|
|
92
58
|
this.positiveSegments.push(...segments);
|
|
93
59
|
return this;
|
|
94
60
|
}
|
|
95
61
|
|
|
96
|
-
/**
|
|
97
|
-
* Add custom negative segments
|
|
98
|
-
*/
|
|
99
62
|
withNegativeSegments(segments: string[]): this {
|
|
100
63
|
this.negativeSegments.push(...segments);
|
|
101
64
|
return this;
|
|
102
65
|
}
|
|
103
66
|
|
|
104
|
-
/**
|
|
105
|
-
* Add a single custom segment
|
|
106
|
-
*/
|
|
107
67
|
withSegment(segment: string): this {
|
|
108
68
|
this.positiveSegments.push(segment);
|
|
109
69
|
return this;
|
|
110
70
|
}
|
|
111
71
|
|
|
112
|
-
/**
|
|
113
|
-
* Add a single negative segment
|
|
114
|
-
*/
|
|
115
72
|
withNegativeSegment(segment: string): this {
|
|
116
73
|
this.negativeSegments.push(segment);
|
|
117
74
|
return this;
|
|
118
75
|
}
|
|
119
76
|
|
|
120
|
-
/**
|
|
121
|
-
* Prepend segments (add to beginning)
|
|
122
|
-
*/
|
|
123
77
|
prependSegments(segments: string[]): this {
|
|
124
78
|
this.positiveSegments.unshift(...segments);
|
|
125
79
|
return this;
|
|
126
80
|
}
|
|
127
81
|
|
|
128
|
-
/**
|
|
129
|
-
* Create a new builder extending this one
|
|
130
|
-
*/
|
|
131
82
|
extend(): ImagePromptBuilder {
|
|
132
83
|
const builder = ImagePromptBuilder.create({ separator: this.separator });
|
|
133
84
|
builder.positiveSegments = [...this.positiveSegments];
|
|
@@ -135,11 +86,7 @@ export class ImagePromptBuilder {
|
|
|
135
86
|
return builder;
|
|
136
87
|
}
|
|
137
88
|
|
|
138
|
-
/**
|
|
139
|
-
* Build the final prompt strings
|
|
140
|
-
*/
|
|
141
89
|
build(): ImagePromptResult {
|
|
142
|
-
// Remove duplicates and filter empty values
|
|
143
90
|
const uniquePositive = [...new Set(this.positiveSegments)].filter(Boolean);
|
|
144
91
|
const uniqueNegative = [...new Set(this.negativeSegments)].filter(Boolean);
|
|
145
92
|
|
|
@@ -148,21 +95,4 @@ export class ImagePromptBuilder {
|
|
|
148
95
|
negativePrompt: uniqueNegative.join(this.separator),
|
|
149
96
|
};
|
|
150
97
|
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Get current positive segments (for debugging)
|
|
154
|
-
*/
|
|
155
|
-
getPositiveSegments(): string[] {
|
|
156
|
-
return [...this.positiveSegments];
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Get current negative segments (for debugging)
|
|
161
|
-
*/
|
|
162
|
-
getNegativeSegments(): string[] {
|
|
163
|
-
return [...this.negativeSegments];
|
|
164
|
-
}
|
|
165
98
|
}
|
|
166
|
-
|
|
167
|
-
// Re-export prompt creation utilities for backward compatibility
|
|
168
|
-
export { createAnimeSelfiePrompt, createStyleTransferPrompt } from "../utils/prompt-creators.util";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image Prompt Builder Types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface ImagePromptResult {
|
|
6
|
+
prompt: string;
|
|
7
|
+
negativePrompt: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface AnimeSelfiePromptResult {
|
|
11
|
+
prompt: string;
|
|
12
|
+
guidance_scale: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ImagePromptBuilderOptions {
|
|
16
|
+
separator?: string;
|
|
17
|
+
}
|