mcp-image 0.1.0 → 0.2.0
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/README.md +41 -17
- package/dist/api/geminiClient.d.ts +2 -12
- package/dist/api/geminiClient.d.ts.map +1 -1
- package/dist/api/geminiClient.js +28 -56
- package/dist/api/geminiClient.js.map +1 -1
- package/dist/api/geminiTextClient.d.ts +42 -0
- package/dist/api/geminiTextClient.d.ts.map +1 -0
- package/dist/api/geminiTextClient.js +198 -0
- package/dist/api/geminiTextClient.js.map +1 -0
- package/dist/business/__tests__/mocks/mcpSamplingClient.mock.d.ts +84 -0
- package/dist/business/__tests__/mocks/mcpSamplingClient.mock.d.ts.map +1 -0
- package/dist/business/__tests__/mocks/mcpSamplingClient.mock.js +100 -0
- package/dist/business/__tests__/mocks/mcpSamplingClient.mock.js.map +1 -0
- package/dist/business/bestPracticesEngine.d.ts +149 -0
- package/dist/business/bestPracticesEngine.d.ts.map +1 -0
- package/dist/business/bestPracticesEngine.js +781 -0
- package/dist/business/bestPracticesEngine.js.map +1 -0
- package/dist/business/complexityAssessment.d.ts +132 -0
- package/dist/business/complexityAssessment.d.ts.map +1 -0
- package/dist/business/complexityAssessment.js +488 -0
- package/dist/business/complexityAssessment.js.map +1 -0
- package/dist/business/fallbackStrategies.d.ts +177 -0
- package/dist/business/fallbackStrategies.d.ts.map +1 -0
- package/dist/business/fallbackStrategies.js +368 -0
- package/dist/business/fallbackStrategies.js.map +1 -0
- package/dist/business/imageGenerator.d.ts.map +1 -1
- package/dist/business/imageGenerator.js +26 -5
- package/dist/business/imageGenerator.js.map +1 -1
- package/dist/business/multiImage/aspectRatioController.d.ts +77 -0
- package/dist/business/multiImage/aspectRatioController.d.ts.map +1 -0
- package/dist/business/multiImage/aspectRatioController.js +580 -0
- package/dist/business/multiImage/aspectRatioController.js.map +1 -0
- package/dist/business/multiImage/multiImageCoordinator.d.ts +142 -0
- package/dist/business/multiImage/multiImageCoordinator.d.ts.map +1 -0
- package/dist/business/multiImage/multiImageCoordinator.js +801 -0
- package/dist/business/multiImage/multiImageCoordinator.js.map +1 -0
- package/dist/business/pomlTemplateEngine.d.ts +206 -0
- package/dist/business/pomlTemplateEngine.d.ts.map +1 -0
- package/dist/business/pomlTemplateEngine.js +737 -0
- package/dist/business/pomlTemplateEngine.js.map +1 -0
- package/dist/business/promptOrchestrator.d.ts +173 -0
- package/dist/business/promptOrchestrator.d.ts.map +1 -0
- package/dist/business/promptOrchestrator.js +490 -0
- package/dist/business/promptOrchestrator.js.map +1 -0
- package/dist/business/responseBuilder.d.ts +2 -2
- package/dist/business/responseBuilder.d.ts.map +1 -1
- package/dist/business/responseBuilder.js +6 -1
- package/dist/business/responseBuilder.js.map +1 -1
- package/dist/business/structuredPromptGenerator.d.ts +54 -0
- package/dist/business/structuredPromptGenerator.d.ts.map +1 -0
- package/dist/business/structuredPromptGenerator.js +208 -0
- package/dist/business/structuredPromptGenerator.js.map +1 -0
- package/dist/business/templateNormalizer.d.ts +81 -0
- package/dist/business/templateNormalizer.d.ts.map +1 -0
- package/dist/business/templateNormalizer.js +659 -0
- package/dist/business/templateNormalizer.js.map +1 -0
- package/dist/documentation/apiContractValidation.d.ts +62 -0
- package/dist/documentation/apiContractValidation.d.ts.map +1 -0
- package/dist/documentation/apiContractValidation.js +305 -0
- package/dist/documentation/apiContractValidation.js.map +1 -0
- package/dist/infrastructure/concurrency/concurrencyManager.d.ts +101 -0
- package/dist/infrastructure/concurrency/concurrencyManager.d.ts.map +1 -0
- package/dist/infrastructure/concurrency/concurrencyManager.js +345 -0
- package/dist/infrastructure/concurrency/concurrencyManager.js.map +1 -0
- package/dist/infrastructure/config/secureConfigManager.d.ts +319 -0
- package/dist/infrastructure/config/secureConfigManager.d.ts.map +1 -0
- package/dist/infrastructure/config/secureConfigManager.js +600 -0
- package/dist/infrastructure/config/secureConfigManager.js.map +1 -0
- package/dist/infrastructure/errorHandling/orchestrationErrorHandler.d.ts +229 -0
- package/dist/infrastructure/errorHandling/orchestrationErrorHandler.d.ts.map +1 -0
- package/dist/infrastructure/errorHandling/orchestrationErrorHandler.js +61 -0
- package/dist/infrastructure/errorHandling/orchestrationErrorHandler.js.map +1 -0
- package/dist/infrastructure/errorHandling/orchestrationErrorHandlerImpl.d.ts +133 -0
- package/dist/infrastructure/errorHandling/orchestrationErrorHandlerImpl.d.ts.map +1 -0
- package/dist/infrastructure/errorHandling/orchestrationErrorHandlerImpl.js +569 -0
- package/dist/infrastructure/errorHandling/orchestrationErrorHandlerImpl.js.map +1 -0
- package/dist/infrastructure/mcp/MCPSamplingClient.d.ts +19 -0
- package/dist/infrastructure/mcp/MCPSamplingClient.d.ts.map +1 -0
- package/dist/infrastructure/mcp/MCPSamplingClient.js +31 -0
- package/dist/infrastructure/mcp/MCPSamplingClient.js.map +1 -0
- package/dist/infrastructure/mcp/RealMCPSamplingClient.d.ts +59 -0
- package/dist/infrastructure/mcp/RealMCPSamplingClient.d.ts.map +1 -0
- package/dist/infrastructure/mcp/RealMCPSamplingClient.js +271 -0
- package/dist/infrastructure/mcp/RealMCPSamplingClient.js.map +1 -0
- package/dist/infrastructure/metadata/generationMetadata.d.ts +72 -0
- package/dist/infrastructure/metadata/generationMetadata.d.ts.map +1 -0
- package/dist/infrastructure/metadata/generationMetadata.js +228 -0
- package/dist/infrastructure/metadata/generationMetadata.js.map +1 -0
- package/dist/infrastructure/monitoring/OrchestrationMetrics.d.ts +106 -0
- package/dist/infrastructure/monitoring/OrchestrationMetrics.d.ts.map +1 -0
- package/dist/infrastructure/monitoring/OrchestrationMetrics.js +456 -0
- package/dist/infrastructure/monitoring/OrchestrationMetrics.js.map +1 -0
- package/dist/infrastructure/monitoring/alertingSystem.d.ts +135 -0
- package/dist/infrastructure/monitoring/alertingSystem.d.ts.map +1 -0
- package/dist/infrastructure/monitoring/alertingSystem.js +549 -0
- package/dist/infrastructure/monitoring/alertingSystem.js.map +1 -0
- package/dist/infrastructure/optimization/performanceOptimizer.d.ts +89 -0
- package/dist/infrastructure/optimization/performanceOptimizer.d.ts.map +1 -0
- package/dist/infrastructure/optimization/performanceOptimizer.js +375 -0
- package/dist/infrastructure/optimization/performanceOptimizer.js.map +1 -0
- package/dist/infrastructure/security/AdvancedContentFilter.d.ts +99 -0
- package/dist/infrastructure/security/AdvancedContentFilter.d.ts.map +1 -0
- package/dist/infrastructure/security/AdvancedContentFilter.js +363 -0
- package/dist/infrastructure/security/AdvancedContentFilter.js.map +1 -0
- package/dist/infrastructure/security/MCPSecurityValidator.d.ts +62 -0
- package/dist/infrastructure/security/MCPSecurityValidator.d.ts.map +1 -0
- package/dist/infrastructure/security/MCPSecurityValidator.js +129 -0
- package/dist/infrastructure/security/MCPSecurityValidator.js.map +1 -0
- package/dist/infrastructure/security/OrchestrationSecurityMiddleware.d.ts +304 -0
- package/dist/infrastructure/security/OrchestrationSecurityMiddleware.d.ts.map +1 -0
- package/dist/infrastructure/security/OrchestrationSecurityMiddleware.js +61 -0
- package/dist/infrastructure/security/OrchestrationSecurityMiddleware.js.map +1 -0
- package/dist/infrastructure/security/OrchestrationSecurityMiddlewareImpl.d.ts +62 -0
- package/dist/infrastructure/security/OrchestrationSecurityMiddlewareImpl.d.ts.map +1 -0
- package/dist/infrastructure/security/OrchestrationSecurityMiddlewareImpl.js +591 -0
- package/dist/infrastructure/security/OrchestrationSecurityMiddlewareImpl.js.map +1 -0
- package/dist/infrastructure/security/SecureMCPClient.d.ts +154 -0
- package/dist/infrastructure/security/SecureMCPClient.d.ts.map +1 -0
- package/dist/infrastructure/security/SecureMCPClient.js +292 -0
- package/dist/infrastructure/security/SecureMCPClient.js.map +1 -0
- package/dist/infrastructure/security/SecurityIncidentManager.d.ts +142 -0
- package/dist/infrastructure/security/SecurityIncidentManager.d.ts.map +1 -0
- package/dist/infrastructure/security/SecurityIncidentManager.js +260 -0
- package/dist/infrastructure/security/SecurityIncidentManager.js.map +1 -0
- package/dist/infrastructure/security/apiKeyManager.d.ts +297 -0
- package/dist/infrastructure/security/apiKeyManager.d.ts.map +1 -0
- package/dist/infrastructure/security/apiKeyManager.js +254 -0
- package/dist/infrastructure/security/apiKeyManager.js.map +1 -0
- package/dist/infrastructure/security/dataSanitizer.d.ts +157 -0
- package/dist/infrastructure/security/dataSanitizer.d.ts.map +1 -0
- package/dist/infrastructure/security/dataSanitizer.js +525 -0
- package/dist/infrastructure/security/dataSanitizer.js.map +1 -0
- package/dist/infrastructure/validation/inputValidator.d.ts +54 -0
- package/dist/infrastructure/validation/inputValidator.d.ts.map +1 -0
- package/dist/infrastructure/validation/inputValidator.js +362 -0
- package/dist/infrastructure/validation/inputValidator.js.map +1 -0
- package/dist/integration/parameterOptimizer.d.ts +69 -0
- package/dist/integration/parameterOptimizer.d.ts.map +1 -0
- package/dist/integration/parameterOptimizer.js +317 -0
- package/dist/integration/parameterOptimizer.js.map +1 -0
- package/dist/integration/twoStageProcessor.d.ts +66 -0
- package/dist/integration/twoStageProcessor.d.ts.map +1 -0
- package/dist/integration/twoStageProcessor.js +348 -0
- package/dist/integration/twoStageProcessor.js.map +1 -0
- package/dist/server/handlers/structuredPromptHandler.d.ts +65 -0
- package/dist/server/handlers/structuredPromptHandler.d.ts.map +1 -0
- package/dist/server/handlers/structuredPromptHandler.js +314 -0
- package/dist/server/handlers/structuredPromptHandler.js.map +1 -0
- package/dist/server/mcpServer.d.ts +16 -35
- package/dist/server/mcpServer.d.ts.map +1 -1
- package/dist/server/mcpServer.js +111 -150
- package/dist/server/mcpServer.js.map +1 -1
- package/dist/server/mcpServerWithOrchestration.d.ts +98 -0
- package/dist/server/mcpServerWithOrchestration.d.ts.map +1 -0
- package/dist/server/mcpServerWithOrchestration.js +284 -0
- package/dist/server/mcpServerWithOrchestration.js.map +1 -0
- package/dist/types/mcpOrchestrationTypes.d.ts +135 -0
- package/dist/types/mcpOrchestrationTypes.d.ts.map +1 -0
- package/dist/types/mcpOrchestrationTypes.js +28 -0
- package/dist/types/mcpOrchestrationTypes.js.map +1 -0
- package/dist/types/multiImageTypes.d.ts +328 -0
- package/dist/types/multiImageTypes.d.ts.map +1 -0
- package/dist/types/multiImageTypes.js +27 -0
- package/dist/types/multiImageTypes.js.map +1 -0
- package/dist/types/performanceTypes.d.ts +300 -0
- package/dist/types/performanceTypes.d.ts.map +1 -0
- package/dist/types/performanceTypes.js +50 -0
- package/dist/types/performanceTypes.js.map +1 -0
- package/dist/types/twoStageTypes.d.ts +123 -0
- package/dist/types/twoStageTypes.d.ts.map +1 -0
- package/dist/types/twoStageTypes.js +7 -0
- package/dist/types/twoStageTypes.js.map +1 -0
- package/dist/utils/config.d.ts +1 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +1 -0
- package/dist/utils/config.js.map +1 -1
- package/package.json +11 -4
- package/vitest.config.mjs +0 -47
|
@@ -0,0 +1,801 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MultiImageCoordinator - Orchestrates multi-image processing with consistency and aspect ratio coordination
|
|
4
|
+
* Supports batch processing, parallel orchestration, and multi-prompt coordination
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.MultiImageCoordinatorImpl = void 0;
|
|
8
|
+
const multiImageTypes_1 = require("../../types/multiImageTypes");
|
|
9
|
+
const result_1 = require("../../types/result");
|
|
10
|
+
const errors_1 = require("../../utils/errors");
|
|
11
|
+
const aspectRatioController_1 = require("./aspectRatioController");
|
|
12
|
+
/**
|
|
13
|
+
* Default aspect ratio for fallbacks
|
|
14
|
+
*/
|
|
15
|
+
const DEFAULT_ASPECT_RATIO = { width: 4, height: 3, ratio: '4:3' };
|
|
16
|
+
/**
|
|
17
|
+
* Implementation of MultiImageCoordinator with complete workflow coordination
|
|
18
|
+
*/
|
|
19
|
+
class MultiImageCoordinatorImpl {
|
|
20
|
+
constructor(twoStageProcessor) {
|
|
21
|
+
this.twoStageProcessor = twoStageProcessor;
|
|
22
|
+
this.aspectRatioController = new aspectRatioController_1.AspectRatioControllerImpl();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Coordinate multiple image generation with consistency and aspect ratio optimization
|
|
26
|
+
*/
|
|
27
|
+
async coordinateMultipleImages(request) {
|
|
28
|
+
const sessionId = this.generateSessionId();
|
|
29
|
+
const startTime = Date.now();
|
|
30
|
+
try {
|
|
31
|
+
// Validate request
|
|
32
|
+
const validationResult = this.validateRequest(request);
|
|
33
|
+
if (!validationResult.success) {
|
|
34
|
+
return (0, result_1.Err)(validationResult.error);
|
|
35
|
+
}
|
|
36
|
+
// Step 1: Optimize aspect ratios for the image set
|
|
37
|
+
const aspectRatiosResult = await this.aspectRatioController.optimizeAspectRatios(request.imageRequirements, request.aspectRatioStrategy);
|
|
38
|
+
if (!aspectRatiosResult.success) {
|
|
39
|
+
return (0, result_1.Err)(aspectRatiosResult.error);
|
|
40
|
+
}
|
|
41
|
+
const aspectRatioOptimizations = aspectRatiosResult.data;
|
|
42
|
+
// Step 2: Generate consistency profile from base prompt
|
|
43
|
+
const consistencyProfile = await this.generateConsistencyProfile(request.basePrompt, request.consistencyLevel);
|
|
44
|
+
// Step 3: Create enhanced contexts for each image
|
|
45
|
+
const contextsResult = await this.createEnhancedContexts(request, aspectRatioOptimizations.optimizations, consistencyProfile);
|
|
46
|
+
if (!contextsResult.success) {
|
|
47
|
+
return (0, result_1.Err)(contextsResult.error);
|
|
48
|
+
}
|
|
49
|
+
const enhancedContexts = contextsResult.data;
|
|
50
|
+
// Step 4: Process images through 2-stage system (parallel or sequential)
|
|
51
|
+
const processedImagesResult = await this.processImages(enhancedContexts.contexts, request.processingOptions);
|
|
52
|
+
if (!processedImagesResult.success) {
|
|
53
|
+
return (0, result_1.Err)(processedImagesResult.error);
|
|
54
|
+
}
|
|
55
|
+
const processedImages = processedImagesResult.data;
|
|
56
|
+
// Step 5: Validate consistency across results
|
|
57
|
+
const generatedImages = processedImages.map((result) => result.twoStageResult.generatedImage);
|
|
58
|
+
const coherenceValidationResult = await this.validateImageSetCoherence(generatedImages);
|
|
59
|
+
if (!coherenceValidationResult.success) {
|
|
60
|
+
return (0, result_1.Err)(coherenceValidationResult.error);
|
|
61
|
+
}
|
|
62
|
+
const coherenceValidation = coherenceValidationResult.data;
|
|
63
|
+
// Step 6: Calculate consistency metrics
|
|
64
|
+
const consistencyMetrics = this.calculateConsistencyMetrics(processedImages, coherenceValidation);
|
|
65
|
+
// Step 7: Compile final result
|
|
66
|
+
const endTime = Date.now();
|
|
67
|
+
const totalProcessingTime = endTime - startTime;
|
|
68
|
+
const processingMetadata = {
|
|
69
|
+
sessionId,
|
|
70
|
+
originalPrompt: request.basePrompt,
|
|
71
|
+
stages: [], // Would be populated by actual processing stages
|
|
72
|
+
totalProcessingTime,
|
|
73
|
+
promptEnhancementTime: 0, // Would be calculated from actual processing
|
|
74
|
+
imageGenerationTime: 0, // Would be calculated from actual processing
|
|
75
|
+
appliedOptimizations: aspectRatioOptimizations.optimizations.map((opt) => opt.reasoning),
|
|
76
|
+
fallbackUsed: false,
|
|
77
|
+
timestamp: new Date(),
|
|
78
|
+
batchSize: request.imageRequirements.length,
|
|
79
|
+
parallelProcessingUsed: request.processingOptions.enableParallelProcessing,
|
|
80
|
+
concurrentImages: Math.min(request.processingOptions.maxConcurrentImages, request.imageRequirements.length),
|
|
81
|
+
consistencyValidationTime: 0, // Would be calculated from actual processing
|
|
82
|
+
aspectRatioOptimizationTime: 0, // Would be calculated from actual processing
|
|
83
|
+
imageCoordinationTime: totalProcessingTime,
|
|
84
|
+
};
|
|
85
|
+
const result = {
|
|
86
|
+
basePrompt: request.basePrompt,
|
|
87
|
+
processedImages,
|
|
88
|
+
consistencyMetrics,
|
|
89
|
+
processingMetadata,
|
|
90
|
+
aspectRatioSource: this.mapStrategyToSource(request.aspectRatioStrategy),
|
|
91
|
+
success: true,
|
|
92
|
+
};
|
|
93
|
+
return (0, result_1.Ok)(result);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
return (0, result_1.Err)(error instanceof errors_1.GeminiAPIError || error instanceof errors_1.NetworkError
|
|
97
|
+
? error
|
|
98
|
+
: new errors_1.GeminiAPIError(`Multi-image coordination failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'Check request parameters and processing configuration'));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Maintain consistency across multiple image generation contexts
|
|
103
|
+
*/
|
|
104
|
+
async maintainConsistencyAcrossImages(images, consistencyProfile) {
|
|
105
|
+
try {
|
|
106
|
+
if (!images || images.length === 0) {
|
|
107
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError('No images provided for consistency maintenance'));
|
|
108
|
+
}
|
|
109
|
+
// Extract common elements from all contexts
|
|
110
|
+
const commonElements = this.extractCommonElements(images);
|
|
111
|
+
// Generate consistency rules based on profile and common elements
|
|
112
|
+
const consistencyRules = this.generateConsistencyRules(commonElements, consistencyProfile);
|
|
113
|
+
// Apply consistency enhancements to each context
|
|
114
|
+
const enhancedContexts = await Promise.all(images.map((context) => this.applyConsistencyRules(context, consistencyRules)));
|
|
115
|
+
// Calculate overall consistency score
|
|
116
|
+
const consistencyScore = this.calculateConsistencyScore(enhancedContexts);
|
|
117
|
+
const result = {
|
|
118
|
+
contexts: enhancedContexts,
|
|
119
|
+
appliedRules: consistencyRules,
|
|
120
|
+
consistencyScore,
|
|
121
|
+
};
|
|
122
|
+
return (0, result_1.Ok)(result);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError(`Consistency maintenance failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'Check image contexts and consistency profile'));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Validate coherence across a set of generated images
|
|
130
|
+
*/
|
|
131
|
+
async validateImageSetCoherence(imageSet) {
|
|
132
|
+
try {
|
|
133
|
+
if (!imageSet || imageSet.length === 0) {
|
|
134
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError('No images provided for coherence validation'));
|
|
135
|
+
}
|
|
136
|
+
// Analyze each aspect of coherence
|
|
137
|
+
const validationDetails = [];
|
|
138
|
+
// Character coherence
|
|
139
|
+
const characterCoherence = this.validateCharacterCoherence(imageSet);
|
|
140
|
+
validationDetails.push(characterCoherence);
|
|
141
|
+
// Style coherence
|
|
142
|
+
const styleCoherence = this.validateStyleCoherence(imageSet);
|
|
143
|
+
validationDetails.push(styleCoherence);
|
|
144
|
+
// Environment coherence
|
|
145
|
+
const environmentCoherence = this.validateEnvironmentCoherence(imageSet);
|
|
146
|
+
validationDetails.push(environmentCoherence);
|
|
147
|
+
// Lighting coherence
|
|
148
|
+
const lightingCoherence = this.validateLightingCoherence(imageSet);
|
|
149
|
+
validationDetails.push(lightingCoherence);
|
|
150
|
+
// Mood coherence
|
|
151
|
+
const moodCoherence = this.validateMoodCoherence(imageSet);
|
|
152
|
+
validationDetails.push(moodCoherence);
|
|
153
|
+
// Calculate overall coherence score
|
|
154
|
+
const coherenceScore = validationDetails.reduce((sum, detail) => sum + detail.score, 0) / validationDetails.length;
|
|
155
|
+
// Determine if set is coherent (threshold: 0.7)
|
|
156
|
+
const isCoherent = coherenceScore >= 0.7;
|
|
157
|
+
// Generate recommendations based on validation details
|
|
158
|
+
const recommendations = this.generateCoherenceRecommendations(validationDetails);
|
|
159
|
+
const result = {
|
|
160
|
+
isCoherent,
|
|
161
|
+
coherenceScore,
|
|
162
|
+
validationDetails,
|
|
163
|
+
recommendations,
|
|
164
|
+
};
|
|
165
|
+
return (0, result_1.Ok)(result);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError(`Coherence validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'Check image set format and content'));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Validate the multi-image request
|
|
173
|
+
*/
|
|
174
|
+
validateRequest(request) {
|
|
175
|
+
if (!request) {
|
|
176
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError('Invalid request: request is null or undefined'));
|
|
177
|
+
}
|
|
178
|
+
if (!request.basePrompt || request.basePrompt.trim().length === 0) {
|
|
179
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError('Invalid request: base prompt is required'));
|
|
180
|
+
}
|
|
181
|
+
if (!request.imageRequirements || request.imageRequirements.length === 0) {
|
|
182
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError('Invalid request: at least one image requirement is needed'));
|
|
183
|
+
}
|
|
184
|
+
if (!request.processingOptions) {
|
|
185
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError('Invalid request: processing options are required'));
|
|
186
|
+
}
|
|
187
|
+
// Validate each image requirement
|
|
188
|
+
for (const requirement of request.imageRequirements) {
|
|
189
|
+
if (!requirement.id) {
|
|
190
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError('Invalid request: all image requirements must have an ID'));
|
|
191
|
+
}
|
|
192
|
+
if (!requirement.consistency) {
|
|
193
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError('Invalid request: all image requirements must have consistency settings'));
|
|
194
|
+
}
|
|
195
|
+
if (typeof requirement.priority !== 'number' || requirement.priority < 1) {
|
|
196
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError('Invalid request: all image requirements must have a valid priority (>= 1)'));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return (0, result_1.Ok)(true);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Generate consistency profile from base prompt and consistency level
|
|
203
|
+
*/
|
|
204
|
+
async generateConsistencyProfile(basePrompt, consistencyLevel) {
|
|
205
|
+
// Extract common elements that should be maintained across images
|
|
206
|
+
const commonElements = {
|
|
207
|
+
characters: this.extractCharacters(basePrompt),
|
|
208
|
+
style: this.extractStyle(basePrompt),
|
|
209
|
+
environment: this.extractEnvironment(basePrompt),
|
|
210
|
+
lighting: this.extractLighting(basePrompt),
|
|
211
|
+
mood: this.extractMood(basePrompt),
|
|
212
|
+
};
|
|
213
|
+
// Generate consistency rules based on level
|
|
214
|
+
const consistencyRules = [];
|
|
215
|
+
if (consistencyLevel === multiImageTypes_1.ConsistencyLevel.STRICT ||
|
|
216
|
+
consistencyLevel === multiImageTypes_1.ConsistencyLevel.MODERATE) {
|
|
217
|
+
if (commonElements.characters.length > 0) {
|
|
218
|
+
consistencyRules.push({
|
|
219
|
+
element: 'characters',
|
|
220
|
+
requirement: 'Maintain exact character appearance and features',
|
|
221
|
+
priority: 1,
|
|
222
|
+
validation: () => true, // Simplified validation for now
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
if (commonElements.style.length > 0) {
|
|
226
|
+
consistencyRules.push({
|
|
227
|
+
element: 'style',
|
|
228
|
+
requirement: 'Maintain consistent visual style and artistic approach',
|
|
229
|
+
priority: consistencyLevel === multiImageTypes_1.ConsistencyLevel.STRICT ? 1 : 2,
|
|
230
|
+
validation: () => true, // Simplified validation for now
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (consistencyLevel === multiImageTypes_1.ConsistencyLevel.STRICT) {
|
|
235
|
+
if (commonElements.environment.length > 0) {
|
|
236
|
+
consistencyRules.push({
|
|
237
|
+
element: 'environment',
|
|
238
|
+
requirement: 'Maintain consistent environmental elements and setting',
|
|
239
|
+
priority: 2,
|
|
240
|
+
validation: () => true, // Simplified validation for now
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
if (commonElements.lighting.length > 0) {
|
|
244
|
+
consistencyRules.push({
|
|
245
|
+
element: 'lighting',
|
|
246
|
+
requirement: 'Maintain consistent lighting conditions and atmosphere',
|
|
247
|
+
priority: 3,
|
|
248
|
+
validation: () => true, // Simplified validation for now
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
level: consistencyLevel,
|
|
254
|
+
commonElements,
|
|
255
|
+
consistencyRules,
|
|
256
|
+
enforcementPriority: 'balanced',
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Create enhanced contexts for each image requirement
|
|
261
|
+
*/
|
|
262
|
+
async createEnhancedContexts(request, aspectRatioOptimizations, consistencyProfile) {
|
|
263
|
+
try {
|
|
264
|
+
const contexts = [];
|
|
265
|
+
for (let i = 0; i < request.imageRequirements.length; i++) {
|
|
266
|
+
const requirement = request.imageRequirements[i];
|
|
267
|
+
if (!requirement)
|
|
268
|
+
continue; // Safety check
|
|
269
|
+
const aspectRatioOptimization = aspectRatioOptimizations[i]?.optimization;
|
|
270
|
+
// Generate enhanced prompt by combining base prompt with specific prompt
|
|
271
|
+
const enhancedPrompt = this.combinePrompts(request.basePrompt, requirement.specificPrompt || '', consistencyProfile);
|
|
272
|
+
// Find related contexts (for consistency)
|
|
273
|
+
const relatedContexts = request.imageRequirements
|
|
274
|
+
.filter((req) => req.id !== requirement.id)
|
|
275
|
+
.map((req) => req.id);
|
|
276
|
+
const context = {
|
|
277
|
+
basePrompt: request.basePrompt,
|
|
278
|
+
enhancedPrompt,
|
|
279
|
+
requirement,
|
|
280
|
+
consistencyProfile,
|
|
281
|
+
aspectRatioOptimization: aspectRatioOptimization || {
|
|
282
|
+
strategy: request.aspectRatioStrategy,
|
|
283
|
+
contentAnalysis: {
|
|
284
|
+
primarySubject: 'scene',
|
|
285
|
+
composition: 'horizontal',
|
|
286
|
+
elements: [],
|
|
287
|
+
rationale: 'Default analysis applied',
|
|
288
|
+
},
|
|
289
|
+
recommendedRatio: { width: 4, height: 3, ratio: '4:3' },
|
|
290
|
+
confidenceScore: 0.5,
|
|
291
|
+
},
|
|
292
|
+
relatedContexts,
|
|
293
|
+
};
|
|
294
|
+
contexts.push(context);
|
|
295
|
+
}
|
|
296
|
+
// Apply consistency maintenance across all contexts
|
|
297
|
+
return await this.maintainConsistencyAcrossImages(contexts, consistencyProfile);
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError(`Enhanced context creation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'Check image requirements and aspect ratio optimizations'));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Process images through 2-stage system (parallel or sequential)
|
|
305
|
+
*/
|
|
306
|
+
async processImages(contexts, processingOptions) {
|
|
307
|
+
try {
|
|
308
|
+
const processedImages = [];
|
|
309
|
+
if (processingOptions.enableParallelProcessing && contexts.length > 1) {
|
|
310
|
+
// Parallel processing
|
|
311
|
+
const batches = this.createBatches(contexts, processingOptions.maxConcurrentImages);
|
|
312
|
+
for (const batch of batches) {
|
|
313
|
+
const batchPromises = batch.map(async (context) => {
|
|
314
|
+
return await this.processSingleImage(context);
|
|
315
|
+
});
|
|
316
|
+
const batchResults = await Promise.allSettled(batchPromises);
|
|
317
|
+
for (const result of batchResults) {
|
|
318
|
+
if (result.status === 'fulfilled' && result.value.success) {
|
|
319
|
+
processedImages.push(result.value.data);
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
// Handle partial failures - create error result
|
|
323
|
+
const errorMessage = result.status === 'rejected'
|
|
324
|
+
? result.reason?.message || 'Unknown error'
|
|
325
|
+
: result.value.success === false
|
|
326
|
+
? result.value.error.message || 'Processing failed'
|
|
327
|
+
: 'Processing failed';
|
|
328
|
+
console.warn(`Image processing failed: ${errorMessage}`);
|
|
329
|
+
// Continue with other images - don't fail entire batch
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
// Sequential processing
|
|
336
|
+
for (const context of contexts) {
|
|
337
|
+
const result = await this.processSingleImage(context);
|
|
338
|
+
if (result.success) {
|
|
339
|
+
processedImages.push(result.data);
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
console.warn(`Image processing failed for ${context.requirement.id}: ${result.error.message}`);
|
|
343
|
+
// Continue with other images - don't fail entire sequence
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// Ensure we have at least one successful image
|
|
348
|
+
if (processedImages.length === 0) {
|
|
349
|
+
return (0, result_1.Err)(new errors_1.GeminiAPIError('All image processing attempts failed'));
|
|
350
|
+
}
|
|
351
|
+
return (0, result_1.Ok)(processedImages);
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
return (0, result_1.Err)(error instanceof errors_1.GeminiAPIError || error instanceof errors_1.NetworkError
|
|
355
|
+
? error
|
|
356
|
+
: new errors_1.GeminiAPIError(`Image processing failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'Check processing configuration and contexts'));
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Process a single image through the 2-stage system
|
|
361
|
+
*/
|
|
362
|
+
async processSingleImage(context) {
|
|
363
|
+
try {
|
|
364
|
+
// Create image generation request for 2-stage processor
|
|
365
|
+
const imageRequest = {
|
|
366
|
+
originalPrompt: context.enhancedPrompt,
|
|
367
|
+
imageParameters: {
|
|
368
|
+
...context.requirement.imageParameters,
|
|
369
|
+
aspectRatio: context.aspectRatioOptimization.recommendedRatio.ratio,
|
|
370
|
+
},
|
|
371
|
+
orchestrationOptions: {
|
|
372
|
+
enablePOML: true,
|
|
373
|
+
bestPracticesMode: 'complete',
|
|
374
|
+
maxProcessingTime: 15000,
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
const twoStageResult = await this.twoStageProcessor.generateImageWithStructuredPrompt(imageRequest);
|
|
378
|
+
if (!twoStageResult.success) {
|
|
379
|
+
return (0, result_1.Err)(twoStageResult.error);
|
|
380
|
+
}
|
|
381
|
+
// Calculate consistency score (simplified implementation)
|
|
382
|
+
const consistencyScore = this.calculateImageConsistencyScore(twoStageResult.data, context.consistencyProfile);
|
|
383
|
+
const processedResult = {
|
|
384
|
+
requirement: context.requirement,
|
|
385
|
+
twoStageResult: twoStageResult.data,
|
|
386
|
+
consistencyScore,
|
|
387
|
+
aspectRatioOptimization: {
|
|
388
|
+
originalRatio: context.requirement.aspectRatio || DEFAULT_ASPECT_RATIO,
|
|
389
|
+
optimizedRatio: context.aspectRatioOptimization.recommendedRatio,
|
|
390
|
+
optimization: context.aspectRatioOptimization,
|
|
391
|
+
reasoning: `Applied ${context.aspectRatioOptimization.strategy} strategy`,
|
|
392
|
+
},
|
|
393
|
+
};
|
|
394
|
+
return (0, result_1.Ok)(processedResult);
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
return (0, result_1.Err)(error instanceof errors_1.GeminiAPIError || error instanceof errors_1.NetworkError
|
|
398
|
+
? error
|
|
399
|
+
: new errors_1.GeminiAPIError(`Single image processing failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'Check image context and 2-stage processor configuration'));
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Create batches for parallel processing
|
|
404
|
+
*/
|
|
405
|
+
createBatches(items, batchSize) {
|
|
406
|
+
const batches = [];
|
|
407
|
+
for (let i = 0; i < items.length; i += batchSize) {
|
|
408
|
+
batches.push(items.slice(i, i + batchSize));
|
|
409
|
+
}
|
|
410
|
+
return batches;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Extract common elements from image generation contexts
|
|
414
|
+
*/
|
|
415
|
+
extractCommonElements(contexts) {
|
|
416
|
+
const allCharacters = [];
|
|
417
|
+
const allStyles = [];
|
|
418
|
+
const allEnvironments = [];
|
|
419
|
+
const allLighting = [];
|
|
420
|
+
const allMoods = [];
|
|
421
|
+
for (const context of contexts) {
|
|
422
|
+
allCharacters.push(...this.extractCharacters(context.enhancedPrompt));
|
|
423
|
+
allStyles.push(...this.extractStyle(context.enhancedPrompt));
|
|
424
|
+
allEnvironments.push(...this.extractEnvironment(context.enhancedPrompt));
|
|
425
|
+
allLighting.push(...this.extractLighting(context.enhancedPrompt));
|
|
426
|
+
allMoods.push(...this.extractMood(context.enhancedPrompt));
|
|
427
|
+
}
|
|
428
|
+
return {
|
|
429
|
+
characters: [...new Set(allCharacters)],
|
|
430
|
+
style: [...new Set(allStyles)],
|
|
431
|
+
environment: [...new Set(allEnvironments)],
|
|
432
|
+
lighting: [...new Set(allLighting)],
|
|
433
|
+
mood: [...new Set(allMoods)],
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Generate consistency rules based on common elements and profile
|
|
438
|
+
*/
|
|
439
|
+
generateConsistencyRules(commonElements, profile) {
|
|
440
|
+
const rules = [];
|
|
441
|
+
if (commonElements.characters.length > 0) {
|
|
442
|
+
rules.push({
|
|
443
|
+
element: 'characters',
|
|
444
|
+
requirement: `Maintain consistency for: ${commonElements.characters.join(', ')}`,
|
|
445
|
+
priority: 1,
|
|
446
|
+
validation: () => true, // Simplified validation
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
if (commonElements.style.length > 0) {
|
|
450
|
+
rules.push({
|
|
451
|
+
element: 'style',
|
|
452
|
+
requirement: `Maintain style consistency for: ${commonElements.style.join(', ')}`,
|
|
453
|
+
priority: profile.level === multiImageTypes_1.ConsistencyLevel.STRICT ? 1 : 2,
|
|
454
|
+
validation: () => true, // Simplified validation
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
if (profile.level === multiImageTypes_1.ConsistencyLevel.STRICT) {
|
|
458
|
+
if (commonElements.environment.length > 0) {
|
|
459
|
+
rules.push({
|
|
460
|
+
element: 'environment',
|
|
461
|
+
requirement: `Maintain environmental consistency for: ${commonElements.environment.join(', ')}`,
|
|
462
|
+
priority: 2,
|
|
463
|
+
validation: () => true, // Simplified validation
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
if (commonElements.lighting.length > 0) {
|
|
467
|
+
rules.push({
|
|
468
|
+
element: 'lighting',
|
|
469
|
+
requirement: `Maintain lighting consistency for: ${commonElements.lighting.join(', ')}`,
|
|
470
|
+
priority: 3,
|
|
471
|
+
validation: () => true, // Simplified validation
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return rules;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Apply consistency rules to an image generation context
|
|
479
|
+
*/
|
|
480
|
+
async applyConsistencyRules(context, rules) {
|
|
481
|
+
// Sort rules by priority
|
|
482
|
+
const sortedRules = rules.sort((a, b) => a.priority - b.priority);
|
|
483
|
+
let enhancedPrompt = context.enhancedPrompt;
|
|
484
|
+
// Apply each rule to enhance the prompt
|
|
485
|
+
for (const rule of sortedRules) {
|
|
486
|
+
enhancedPrompt = this.applyRuleToPrompt(enhancedPrompt, rule);
|
|
487
|
+
}
|
|
488
|
+
return {
|
|
489
|
+
...context,
|
|
490
|
+
enhancedPrompt,
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Apply a single consistency rule to a prompt
|
|
495
|
+
*/
|
|
496
|
+
applyRuleToPrompt(prompt, rule) {
|
|
497
|
+
// Simple implementation - add consistency keywords based on rule
|
|
498
|
+
const consistencyKeyword = this.getConsistencyKeyword(rule.element);
|
|
499
|
+
if (consistencyKeyword && !prompt.toLowerCase().includes(consistencyKeyword.toLowerCase())) {
|
|
500
|
+
return `${prompt}, maintaining ${consistencyKeyword}`;
|
|
501
|
+
}
|
|
502
|
+
return prompt;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Get consistency keyword for a rule element
|
|
506
|
+
*/
|
|
507
|
+
getConsistencyKeyword(element) {
|
|
508
|
+
const keywords = {
|
|
509
|
+
characters: 'character consistency',
|
|
510
|
+
style: 'visual style',
|
|
511
|
+
environment: 'environmental setting',
|
|
512
|
+
lighting: 'lighting conditions',
|
|
513
|
+
mood: 'mood and atmosphere',
|
|
514
|
+
};
|
|
515
|
+
return keywords[element] || 'consistency';
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Calculate consistency score for enhanced contexts
|
|
519
|
+
*/
|
|
520
|
+
calculateConsistencyScore(contexts) {
|
|
521
|
+
if (contexts.length === 0)
|
|
522
|
+
return 1.0;
|
|
523
|
+
// Simple implementation - based on common elements in prompts
|
|
524
|
+
const prompts = contexts.map((c) => c.enhancedPrompt.toLowerCase());
|
|
525
|
+
// Count common words across prompts
|
|
526
|
+
const allWords = prompts.flatMap((prompt) => prompt.split(' '));
|
|
527
|
+
const wordCounts = {};
|
|
528
|
+
for (const word of allWords) {
|
|
529
|
+
if (word.length > 3) {
|
|
530
|
+
// Only count meaningful words
|
|
531
|
+
wordCounts[word] = (wordCounts[word] || 0) + 1;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
// Calculate consistency based on shared vocabulary
|
|
535
|
+
const sharedWords = Object.values(wordCounts).filter((count) => count > 1);
|
|
536
|
+
const totalWords = Object.keys(wordCounts).length;
|
|
537
|
+
return totalWords > 0 ? sharedWords.length / totalWords : 0.5;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Calculate consistency metrics for processed images
|
|
541
|
+
*/
|
|
542
|
+
calculateConsistencyMetrics(_processedImages, coherenceValidation) {
|
|
543
|
+
const overallConsistencyScore = coherenceValidation.coherenceScore;
|
|
544
|
+
// Extract individual aspect scores from validation details
|
|
545
|
+
const getAspectScore = (aspect) => {
|
|
546
|
+
const detail = coherenceValidation.validationDetails.find((d) => d.aspect === aspect);
|
|
547
|
+
return detail?.score || 0;
|
|
548
|
+
};
|
|
549
|
+
return {
|
|
550
|
+
overallConsistencyScore,
|
|
551
|
+
characterConsistency: getAspectScore('character'),
|
|
552
|
+
styleConsistency: getAspectScore('style'),
|
|
553
|
+
environmentConsistency: getAspectScore('environment'),
|
|
554
|
+
lightingConsistency: getAspectScore('lighting'),
|
|
555
|
+
moodConsistency: getAspectScore('mood'),
|
|
556
|
+
failedValidations: coherenceValidation.validationDetails
|
|
557
|
+
.filter((detail) => detail.issues.length > 0)
|
|
558
|
+
.map((detail) => `${detail.aspect}: ${detail.issues.join(', ')}`),
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Validate character coherence across images
|
|
563
|
+
*/
|
|
564
|
+
validateCharacterCoherence(_imageSet) {
|
|
565
|
+
// Simplified implementation - would use actual image analysis in production
|
|
566
|
+
return {
|
|
567
|
+
aspect: 'character',
|
|
568
|
+
score: 0.85, // Mock score
|
|
569
|
+
issues: [],
|
|
570
|
+
suggestions: ['Maintain consistent character features across all images'],
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Validate style coherence across images
|
|
575
|
+
*/
|
|
576
|
+
validateStyleCoherence(_imageSet) {
|
|
577
|
+
return {
|
|
578
|
+
aspect: 'style',
|
|
579
|
+
score: 0.9, // Mock score
|
|
580
|
+
issues: [],
|
|
581
|
+
suggestions: ['Visual style is well maintained across the image set'],
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Validate environment coherence across images
|
|
586
|
+
*/
|
|
587
|
+
validateEnvironmentCoherence(_imageSet) {
|
|
588
|
+
return {
|
|
589
|
+
aspect: 'environment',
|
|
590
|
+
score: 0.8, // Mock score
|
|
591
|
+
issues: ['Minor inconsistencies in background elements'],
|
|
592
|
+
suggestions: ['Consider unified environmental context for better coherence'],
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Validate lighting coherence across images
|
|
597
|
+
*/
|
|
598
|
+
validateLightingCoherence(_imageSet) {
|
|
599
|
+
return {
|
|
600
|
+
aspect: 'lighting',
|
|
601
|
+
score: 0.75, // Mock score
|
|
602
|
+
issues: ['Lighting direction varies between images'],
|
|
603
|
+
suggestions: ['Establish consistent lighting direction and quality'],
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Validate mood coherence across images
|
|
608
|
+
*/
|
|
609
|
+
validateMoodCoherence(_imageSet) {
|
|
610
|
+
return {
|
|
611
|
+
aspect: 'mood',
|
|
612
|
+
score: 0.95, // Mock score
|
|
613
|
+
issues: [],
|
|
614
|
+
suggestions: ['Mood and atmosphere are excellently maintained'],
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Generate coherence recommendations based on validation details
|
|
619
|
+
*/
|
|
620
|
+
generateCoherenceRecommendations(details) {
|
|
621
|
+
const recommendations = [];
|
|
622
|
+
for (const detail of details) {
|
|
623
|
+
if (detail.score < 0.7) {
|
|
624
|
+
recommendations.push(`Improve ${detail.aspect} consistency: ${detail.suggestions.join(', ')}`);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (recommendations.length === 0) {
|
|
628
|
+
recommendations.push('Image set shows good overall coherence');
|
|
629
|
+
}
|
|
630
|
+
return recommendations;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Calculate consistency score for a single image
|
|
634
|
+
*/
|
|
635
|
+
calculateImageConsistencyScore(_twoStageResult, _consistencyProfile) {
|
|
636
|
+
// Simplified implementation - would analyze actual image content in production
|
|
637
|
+
return 0.85; // Mock score
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Combine base prompt with specific prompt and consistency elements
|
|
641
|
+
*/
|
|
642
|
+
combinePrompts(basePrompt, specificPrompt, consistencyProfile) {
|
|
643
|
+
let combined = basePrompt;
|
|
644
|
+
if (specificPrompt && specificPrompt.trim().length > 0) {
|
|
645
|
+
combined += `, ${specificPrompt}`;
|
|
646
|
+
}
|
|
647
|
+
// Add consistency elements
|
|
648
|
+
const consistencyElements = [];
|
|
649
|
+
if (consistencyProfile.commonElements.characters.length > 0) {
|
|
650
|
+
consistencyElements.push(`featuring ${consistencyProfile.commonElements.characters.join(', ')}`);
|
|
651
|
+
}
|
|
652
|
+
if (consistencyProfile.commonElements.style.length > 0) {
|
|
653
|
+
consistencyElements.push(`in ${consistencyProfile.commonElements.style.join(', ')} style`);
|
|
654
|
+
}
|
|
655
|
+
if (consistencyElements.length > 0) {
|
|
656
|
+
combined += `, ${consistencyElements.join(', ')}`;
|
|
657
|
+
}
|
|
658
|
+
return combined;
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Map aspect ratio strategy to source identifier
|
|
662
|
+
*/
|
|
663
|
+
mapStrategyToSource(strategy) {
|
|
664
|
+
switch (strategy) {
|
|
665
|
+
case 'adaptive':
|
|
666
|
+
return 'adaptive';
|
|
667
|
+
case 'uniform':
|
|
668
|
+
return 'uniform';
|
|
669
|
+
case 'content_driven':
|
|
670
|
+
return 'content_driven';
|
|
671
|
+
case 'last_image':
|
|
672
|
+
return 'last_image';
|
|
673
|
+
default:
|
|
674
|
+
return 'adaptive';
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Extract character references from prompt
|
|
679
|
+
*/
|
|
680
|
+
extractCharacters(prompt) {
|
|
681
|
+
const characters = [];
|
|
682
|
+
const lowerPrompt = prompt.toLowerCase();
|
|
683
|
+
const characterKeywords = [
|
|
684
|
+
'character',
|
|
685
|
+
'person',
|
|
686
|
+
'figure',
|
|
687
|
+
'warrior',
|
|
688
|
+
'knight',
|
|
689
|
+
'mage',
|
|
690
|
+
'hero',
|
|
691
|
+
'villain',
|
|
692
|
+
];
|
|
693
|
+
for (const keyword of characterKeywords) {
|
|
694
|
+
if (lowerPrompt.includes(keyword)) {
|
|
695
|
+
characters.push(keyword);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return characters;
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* Extract style references from prompt
|
|
702
|
+
*/
|
|
703
|
+
extractStyle(prompt) {
|
|
704
|
+
const styles = [];
|
|
705
|
+
const lowerPrompt = prompt.toLowerCase();
|
|
706
|
+
const styleKeywords = [
|
|
707
|
+
'realistic',
|
|
708
|
+
'artistic',
|
|
709
|
+
'cartoon',
|
|
710
|
+
'anime',
|
|
711
|
+
'photorealistic',
|
|
712
|
+
'illustration',
|
|
713
|
+
'painting',
|
|
714
|
+
];
|
|
715
|
+
for (const keyword of styleKeywords) {
|
|
716
|
+
if (lowerPrompt.includes(keyword)) {
|
|
717
|
+
styles.push(keyword);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
return styles;
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Extract environment references from prompt
|
|
724
|
+
*/
|
|
725
|
+
extractEnvironment(prompt) {
|
|
726
|
+
const environments = [];
|
|
727
|
+
const lowerPrompt = prompt.toLowerCase();
|
|
728
|
+
const envKeywords = [
|
|
729
|
+
'forest',
|
|
730
|
+
'castle',
|
|
731
|
+
'city',
|
|
732
|
+
'mountain',
|
|
733
|
+
'beach',
|
|
734
|
+
'desert',
|
|
735
|
+
'medieval',
|
|
736
|
+
'fantasy',
|
|
737
|
+
'modern',
|
|
738
|
+
];
|
|
739
|
+
for (const keyword of envKeywords) {
|
|
740
|
+
if (lowerPrompt.includes(keyword)) {
|
|
741
|
+
environments.push(keyword);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
return environments;
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Extract lighting references from prompt
|
|
748
|
+
*/
|
|
749
|
+
extractLighting(prompt) {
|
|
750
|
+
const lighting = [];
|
|
751
|
+
const lowerPrompt = prompt.toLowerCase();
|
|
752
|
+
const lightingKeywords = [
|
|
753
|
+
'dramatic',
|
|
754
|
+
'soft',
|
|
755
|
+
'bright',
|
|
756
|
+
'dark',
|
|
757
|
+
'natural',
|
|
758
|
+
'artificial',
|
|
759
|
+
'golden',
|
|
760
|
+
'sunset',
|
|
761
|
+
'sunrise',
|
|
762
|
+
];
|
|
763
|
+
for (const keyword of lightingKeywords) {
|
|
764
|
+
if (lowerPrompt.includes(keyword)) {
|
|
765
|
+
lighting.push(keyword);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return lighting;
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* Extract mood references from prompt
|
|
772
|
+
*/
|
|
773
|
+
extractMood(prompt) {
|
|
774
|
+
const moods = [];
|
|
775
|
+
const lowerPrompt = prompt.toLowerCase();
|
|
776
|
+
const moodKeywords = [
|
|
777
|
+
'heroic',
|
|
778
|
+
'dark',
|
|
779
|
+
'mysterious',
|
|
780
|
+
'cheerful',
|
|
781
|
+
'somber',
|
|
782
|
+
'epic',
|
|
783
|
+
'peaceful',
|
|
784
|
+
'intense',
|
|
785
|
+
];
|
|
786
|
+
for (const keyword of moodKeywords) {
|
|
787
|
+
if (lowerPrompt.includes(keyword)) {
|
|
788
|
+
moods.push(keyword);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
return moods;
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Generate unique session ID
|
|
795
|
+
*/
|
|
796
|
+
generateSessionId() {
|
|
797
|
+
return `multi-image-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
exports.MultiImageCoordinatorImpl = MultiImageCoordinatorImpl;
|
|
801
|
+
//# sourceMappingURL=multiImageCoordinator.js.map
|