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.
Files changed (178) hide show
  1. package/README.md +41 -17
  2. package/dist/api/geminiClient.d.ts +2 -12
  3. package/dist/api/geminiClient.d.ts.map +1 -1
  4. package/dist/api/geminiClient.js +28 -56
  5. package/dist/api/geminiClient.js.map +1 -1
  6. package/dist/api/geminiTextClient.d.ts +42 -0
  7. package/dist/api/geminiTextClient.d.ts.map +1 -0
  8. package/dist/api/geminiTextClient.js +198 -0
  9. package/dist/api/geminiTextClient.js.map +1 -0
  10. package/dist/business/__tests__/mocks/mcpSamplingClient.mock.d.ts +84 -0
  11. package/dist/business/__tests__/mocks/mcpSamplingClient.mock.d.ts.map +1 -0
  12. package/dist/business/__tests__/mocks/mcpSamplingClient.mock.js +100 -0
  13. package/dist/business/__tests__/mocks/mcpSamplingClient.mock.js.map +1 -0
  14. package/dist/business/bestPracticesEngine.d.ts +149 -0
  15. package/dist/business/bestPracticesEngine.d.ts.map +1 -0
  16. package/dist/business/bestPracticesEngine.js +781 -0
  17. package/dist/business/bestPracticesEngine.js.map +1 -0
  18. package/dist/business/complexityAssessment.d.ts +132 -0
  19. package/dist/business/complexityAssessment.d.ts.map +1 -0
  20. package/dist/business/complexityAssessment.js +488 -0
  21. package/dist/business/complexityAssessment.js.map +1 -0
  22. package/dist/business/fallbackStrategies.d.ts +177 -0
  23. package/dist/business/fallbackStrategies.d.ts.map +1 -0
  24. package/dist/business/fallbackStrategies.js +368 -0
  25. package/dist/business/fallbackStrategies.js.map +1 -0
  26. package/dist/business/imageGenerator.d.ts.map +1 -1
  27. package/dist/business/imageGenerator.js +26 -5
  28. package/dist/business/imageGenerator.js.map +1 -1
  29. package/dist/business/multiImage/aspectRatioController.d.ts +77 -0
  30. package/dist/business/multiImage/aspectRatioController.d.ts.map +1 -0
  31. package/dist/business/multiImage/aspectRatioController.js +580 -0
  32. package/dist/business/multiImage/aspectRatioController.js.map +1 -0
  33. package/dist/business/multiImage/multiImageCoordinator.d.ts +142 -0
  34. package/dist/business/multiImage/multiImageCoordinator.d.ts.map +1 -0
  35. package/dist/business/multiImage/multiImageCoordinator.js +801 -0
  36. package/dist/business/multiImage/multiImageCoordinator.js.map +1 -0
  37. package/dist/business/pomlTemplateEngine.d.ts +206 -0
  38. package/dist/business/pomlTemplateEngine.d.ts.map +1 -0
  39. package/dist/business/pomlTemplateEngine.js +737 -0
  40. package/dist/business/pomlTemplateEngine.js.map +1 -0
  41. package/dist/business/promptOrchestrator.d.ts +173 -0
  42. package/dist/business/promptOrchestrator.d.ts.map +1 -0
  43. package/dist/business/promptOrchestrator.js +490 -0
  44. package/dist/business/promptOrchestrator.js.map +1 -0
  45. package/dist/business/responseBuilder.d.ts +2 -2
  46. package/dist/business/responseBuilder.d.ts.map +1 -1
  47. package/dist/business/responseBuilder.js +6 -1
  48. package/dist/business/responseBuilder.js.map +1 -1
  49. package/dist/business/structuredPromptGenerator.d.ts +54 -0
  50. package/dist/business/structuredPromptGenerator.d.ts.map +1 -0
  51. package/dist/business/structuredPromptGenerator.js +208 -0
  52. package/dist/business/structuredPromptGenerator.js.map +1 -0
  53. package/dist/business/templateNormalizer.d.ts +81 -0
  54. package/dist/business/templateNormalizer.d.ts.map +1 -0
  55. package/dist/business/templateNormalizer.js +659 -0
  56. package/dist/business/templateNormalizer.js.map +1 -0
  57. package/dist/documentation/apiContractValidation.d.ts +62 -0
  58. package/dist/documentation/apiContractValidation.d.ts.map +1 -0
  59. package/dist/documentation/apiContractValidation.js +305 -0
  60. package/dist/documentation/apiContractValidation.js.map +1 -0
  61. package/dist/infrastructure/concurrency/concurrencyManager.d.ts +101 -0
  62. package/dist/infrastructure/concurrency/concurrencyManager.d.ts.map +1 -0
  63. package/dist/infrastructure/concurrency/concurrencyManager.js +345 -0
  64. package/dist/infrastructure/concurrency/concurrencyManager.js.map +1 -0
  65. package/dist/infrastructure/config/secureConfigManager.d.ts +319 -0
  66. package/dist/infrastructure/config/secureConfigManager.d.ts.map +1 -0
  67. package/dist/infrastructure/config/secureConfigManager.js +600 -0
  68. package/dist/infrastructure/config/secureConfigManager.js.map +1 -0
  69. package/dist/infrastructure/errorHandling/orchestrationErrorHandler.d.ts +229 -0
  70. package/dist/infrastructure/errorHandling/orchestrationErrorHandler.d.ts.map +1 -0
  71. package/dist/infrastructure/errorHandling/orchestrationErrorHandler.js +61 -0
  72. package/dist/infrastructure/errorHandling/orchestrationErrorHandler.js.map +1 -0
  73. package/dist/infrastructure/errorHandling/orchestrationErrorHandlerImpl.d.ts +133 -0
  74. package/dist/infrastructure/errorHandling/orchestrationErrorHandlerImpl.d.ts.map +1 -0
  75. package/dist/infrastructure/errorHandling/orchestrationErrorHandlerImpl.js +569 -0
  76. package/dist/infrastructure/errorHandling/orchestrationErrorHandlerImpl.js.map +1 -0
  77. package/dist/infrastructure/mcp/MCPSamplingClient.d.ts +19 -0
  78. package/dist/infrastructure/mcp/MCPSamplingClient.d.ts.map +1 -0
  79. package/dist/infrastructure/mcp/MCPSamplingClient.js +31 -0
  80. package/dist/infrastructure/mcp/MCPSamplingClient.js.map +1 -0
  81. package/dist/infrastructure/mcp/RealMCPSamplingClient.d.ts +59 -0
  82. package/dist/infrastructure/mcp/RealMCPSamplingClient.d.ts.map +1 -0
  83. package/dist/infrastructure/mcp/RealMCPSamplingClient.js +271 -0
  84. package/dist/infrastructure/mcp/RealMCPSamplingClient.js.map +1 -0
  85. package/dist/infrastructure/metadata/generationMetadata.d.ts +72 -0
  86. package/dist/infrastructure/metadata/generationMetadata.d.ts.map +1 -0
  87. package/dist/infrastructure/metadata/generationMetadata.js +228 -0
  88. package/dist/infrastructure/metadata/generationMetadata.js.map +1 -0
  89. package/dist/infrastructure/monitoring/OrchestrationMetrics.d.ts +106 -0
  90. package/dist/infrastructure/monitoring/OrchestrationMetrics.d.ts.map +1 -0
  91. package/dist/infrastructure/monitoring/OrchestrationMetrics.js +456 -0
  92. package/dist/infrastructure/monitoring/OrchestrationMetrics.js.map +1 -0
  93. package/dist/infrastructure/monitoring/alertingSystem.d.ts +135 -0
  94. package/dist/infrastructure/monitoring/alertingSystem.d.ts.map +1 -0
  95. package/dist/infrastructure/monitoring/alertingSystem.js +549 -0
  96. package/dist/infrastructure/monitoring/alertingSystem.js.map +1 -0
  97. package/dist/infrastructure/optimization/performanceOptimizer.d.ts +89 -0
  98. package/dist/infrastructure/optimization/performanceOptimizer.d.ts.map +1 -0
  99. package/dist/infrastructure/optimization/performanceOptimizer.js +375 -0
  100. package/dist/infrastructure/optimization/performanceOptimizer.js.map +1 -0
  101. package/dist/infrastructure/security/AdvancedContentFilter.d.ts +99 -0
  102. package/dist/infrastructure/security/AdvancedContentFilter.d.ts.map +1 -0
  103. package/dist/infrastructure/security/AdvancedContentFilter.js +363 -0
  104. package/dist/infrastructure/security/AdvancedContentFilter.js.map +1 -0
  105. package/dist/infrastructure/security/MCPSecurityValidator.d.ts +62 -0
  106. package/dist/infrastructure/security/MCPSecurityValidator.d.ts.map +1 -0
  107. package/dist/infrastructure/security/MCPSecurityValidator.js +129 -0
  108. package/dist/infrastructure/security/MCPSecurityValidator.js.map +1 -0
  109. package/dist/infrastructure/security/OrchestrationSecurityMiddleware.d.ts +304 -0
  110. package/dist/infrastructure/security/OrchestrationSecurityMiddleware.d.ts.map +1 -0
  111. package/dist/infrastructure/security/OrchestrationSecurityMiddleware.js +61 -0
  112. package/dist/infrastructure/security/OrchestrationSecurityMiddleware.js.map +1 -0
  113. package/dist/infrastructure/security/OrchestrationSecurityMiddlewareImpl.d.ts +62 -0
  114. package/dist/infrastructure/security/OrchestrationSecurityMiddlewareImpl.d.ts.map +1 -0
  115. package/dist/infrastructure/security/OrchestrationSecurityMiddlewareImpl.js +591 -0
  116. package/dist/infrastructure/security/OrchestrationSecurityMiddlewareImpl.js.map +1 -0
  117. package/dist/infrastructure/security/SecureMCPClient.d.ts +154 -0
  118. package/dist/infrastructure/security/SecureMCPClient.d.ts.map +1 -0
  119. package/dist/infrastructure/security/SecureMCPClient.js +292 -0
  120. package/dist/infrastructure/security/SecureMCPClient.js.map +1 -0
  121. package/dist/infrastructure/security/SecurityIncidentManager.d.ts +142 -0
  122. package/dist/infrastructure/security/SecurityIncidentManager.d.ts.map +1 -0
  123. package/dist/infrastructure/security/SecurityIncidentManager.js +260 -0
  124. package/dist/infrastructure/security/SecurityIncidentManager.js.map +1 -0
  125. package/dist/infrastructure/security/apiKeyManager.d.ts +297 -0
  126. package/dist/infrastructure/security/apiKeyManager.d.ts.map +1 -0
  127. package/dist/infrastructure/security/apiKeyManager.js +254 -0
  128. package/dist/infrastructure/security/apiKeyManager.js.map +1 -0
  129. package/dist/infrastructure/security/dataSanitizer.d.ts +157 -0
  130. package/dist/infrastructure/security/dataSanitizer.d.ts.map +1 -0
  131. package/dist/infrastructure/security/dataSanitizer.js +525 -0
  132. package/dist/infrastructure/security/dataSanitizer.js.map +1 -0
  133. package/dist/infrastructure/validation/inputValidator.d.ts +54 -0
  134. package/dist/infrastructure/validation/inputValidator.d.ts.map +1 -0
  135. package/dist/infrastructure/validation/inputValidator.js +362 -0
  136. package/dist/infrastructure/validation/inputValidator.js.map +1 -0
  137. package/dist/integration/parameterOptimizer.d.ts +69 -0
  138. package/dist/integration/parameterOptimizer.d.ts.map +1 -0
  139. package/dist/integration/parameterOptimizer.js +317 -0
  140. package/dist/integration/parameterOptimizer.js.map +1 -0
  141. package/dist/integration/twoStageProcessor.d.ts +66 -0
  142. package/dist/integration/twoStageProcessor.d.ts.map +1 -0
  143. package/dist/integration/twoStageProcessor.js +348 -0
  144. package/dist/integration/twoStageProcessor.js.map +1 -0
  145. package/dist/server/handlers/structuredPromptHandler.d.ts +65 -0
  146. package/dist/server/handlers/structuredPromptHandler.d.ts.map +1 -0
  147. package/dist/server/handlers/structuredPromptHandler.js +314 -0
  148. package/dist/server/handlers/structuredPromptHandler.js.map +1 -0
  149. package/dist/server/mcpServer.d.ts +16 -35
  150. package/dist/server/mcpServer.d.ts.map +1 -1
  151. package/dist/server/mcpServer.js +111 -150
  152. package/dist/server/mcpServer.js.map +1 -1
  153. package/dist/server/mcpServerWithOrchestration.d.ts +98 -0
  154. package/dist/server/mcpServerWithOrchestration.d.ts.map +1 -0
  155. package/dist/server/mcpServerWithOrchestration.js +284 -0
  156. package/dist/server/mcpServerWithOrchestration.js.map +1 -0
  157. package/dist/types/mcpOrchestrationTypes.d.ts +135 -0
  158. package/dist/types/mcpOrchestrationTypes.d.ts.map +1 -0
  159. package/dist/types/mcpOrchestrationTypes.js +28 -0
  160. package/dist/types/mcpOrchestrationTypes.js.map +1 -0
  161. package/dist/types/multiImageTypes.d.ts +328 -0
  162. package/dist/types/multiImageTypes.d.ts.map +1 -0
  163. package/dist/types/multiImageTypes.js +27 -0
  164. package/dist/types/multiImageTypes.js.map +1 -0
  165. package/dist/types/performanceTypes.d.ts +300 -0
  166. package/dist/types/performanceTypes.d.ts.map +1 -0
  167. package/dist/types/performanceTypes.js +50 -0
  168. package/dist/types/performanceTypes.js.map +1 -0
  169. package/dist/types/twoStageTypes.d.ts +123 -0
  170. package/dist/types/twoStageTypes.d.ts.map +1 -0
  171. package/dist/types/twoStageTypes.js +7 -0
  172. package/dist/types/twoStageTypes.js.map +1 -0
  173. package/dist/utils/config.d.ts +1 -0
  174. package/dist/utils/config.d.ts.map +1 -1
  175. package/dist/utils/config.js +1 -0
  176. package/dist/utils/config.js.map +1 -1
  177. package/package.json +11 -4
  178. package/vitest.config.mjs +0 -47
@@ -0,0 +1,659 @@
1
+ "use strict";
2
+ /**
3
+ * Template engine implementation with embedded best practice templates
4
+ * Provides static template loading and advanced processing capabilities
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.TemplateNormalizer = exports.BestPracticesTemplateNormalizer = void 0;
8
+ exports.createTemplateNormalizer = createTemplateNormalizer;
9
+ const mcp_1 = require("../types/mcp");
10
+ /**
11
+ * Static template engine with embedded best practice templates
12
+ * Templates are code-based for performance (no file I/O)
13
+ * Enhanced with pattern indexing for O(1) template lookup
14
+ */
15
+ class StaticTemplateEngine {
16
+ constructor() {
17
+ this.cachedTemplates = null;
18
+ this.templateIndex = new Map();
19
+ this.patternCache = new Map();
20
+ }
21
+ /**
22
+ * Build all 7 embedded templates for prompt normalization
23
+ * Each template targets specific prompt improvement patterns
24
+ * Templates are cached after first build for performance
25
+ * Creates pattern index for faster matching
26
+ */
27
+ buildStaticTemplates() {
28
+ if (this.cachedTemplates !== null) {
29
+ return this.cachedTemplates;
30
+ }
31
+ const templates = [
32
+ {
33
+ id: 'fantasy-armor-enhancement',
34
+ name: 'Fantasy Armor Enhancement',
35
+ category: mcp_1.BestPracticeCategory.STYLE_ENHANCEMENT,
36
+ pattern: /fantasy\s+armor|armor\s+fantasy|medieval\s+armor|knight.*armor/i,
37
+ enhancement: 'ornate elven plate armor with intricate engravings, polished metalwork, leather straps and buckles, weathered battle-worn details',
38
+ priority: 85,
39
+ metadata: {
40
+ tags: ['fantasy', 'armor', 'medieval', 'hyper-specific'],
41
+ author: 'StaticTemplateEngine',
42
+ version: '1.0.0',
43
+ },
44
+ },
45
+ {
46
+ id: 'beautiful-landscape-enhancement',
47
+ name: 'Beautiful Landscape Enhancement',
48
+ category: mcp_1.BestPracticeCategory.COMPOSITION_GUIDE,
49
+ pattern: /beautiful\s+landscape|scenic\s+view|nature\s+scene|landscape\s+photography/i,
50
+ enhancement: 'sweeping vista with dramatic lighting, rule of thirds composition, foreground elements creating depth, golden hour lighting, rich color palette',
51
+ priority: 80,
52
+ metadata: {
53
+ tags: ['landscape', 'nature', 'composition', 'hyper-specific'],
54
+ author: 'StaticTemplateEngine',
55
+ version: '1.0.0',
56
+ },
57
+ },
58
+ {
59
+ id: 'minimalist-logo-enhancement',
60
+ name: 'Minimalist Logo Enhancement',
61
+ category: mcp_1.BestPracticeCategory.TECHNICAL_DETAIL,
62
+ pattern: /minimalist\s+logo|simple\s+logo|clean\s+logo|logo\s+design/i,
63
+ enhancement: 'context: corporate branding, intent: memorable brand identity, clean geometric shapes, limited color palette, scalable vector design, negative space utilization',
64
+ priority: 75,
65
+ metadata: {
66
+ tags: ['logo', 'minimalist', 'branding', 'context-and-intent'],
67
+ author: 'StaticTemplateEngine',
68
+ version: '1.0.0',
69
+ },
70
+ },
71
+ {
72
+ id: 'character-consistency-person',
73
+ name: 'Character Consistency Person',
74
+ category: mcp_1.BestPracticeCategory.TECHNICAL_DETAIL,
75
+ pattern: /person|character|individual|human.*figure|portrait/i,
76
+ enhancement: 'consistent facial features, same eye color and shape, identical hair texture and style, matching skin tone, consistent body proportions',
77
+ priority: 70,
78
+ metadata: {
79
+ tags: ['character', 'consistency', 'person', 'portrait'],
80
+ author: 'StaticTemplateEngine',
81
+ version: '1.0.0',
82
+ },
83
+ },
84
+ {
85
+ id: 'no-cars-positive',
86
+ name: 'No Cars Positive Guidance',
87
+ category: mcp_1.BestPracticeCategory.COMPOSITION_GUIDE,
88
+ pattern: /no\s+cars|without\s+cars|car.*free|avoid.*cars/i,
89
+ enhancement: 'pedestrian-friendly environment, walking paths and bike lanes, public transportation, green spaces with trees and benches, outdoor café seating',
90
+ priority: 65,
91
+ metadata: {
92
+ tags: ['semantic-negatives', 'urban', 'pedestrian', 'alternative'],
93
+ author: 'StaticTemplateEngine',
94
+ version: '1.0.0',
95
+ },
96
+ },
97
+ {
98
+ id: 'default-camera-enhancement',
99
+ name: 'Default Camera Enhancement',
100
+ category: mcp_1.BestPracticeCategory.TECHNICAL_DETAIL,
101
+ pattern: /photo|photograph|image|shot|camera/i,
102
+ enhancement: 'professional camera settings, optimal lighting conditions, sharp focus with appropriate depth of field, balanced exposure, high resolution detail',
103
+ priority: 60,
104
+ metadata: {
105
+ tags: ['camera', 'photography', 'technical', 'default'],
106
+ author: 'StaticTemplateEngine',
107
+ version: '1.0.0',
108
+ },
109
+ },
110
+ {
111
+ id: 'artistic-style-enhancement',
112
+ name: 'Artistic Style Enhancement',
113
+ category: mcp_1.BestPracticeCategory.STYLE_ENHANCEMENT,
114
+ pattern: /artistic|art\s+style|creative|abstract.*art/i,
115
+ enhancement: 'distinctive artistic technique, expressive brushwork or digital artistry, cohesive color scheme, creative composition with visual impact',
116
+ priority: 55,
117
+ metadata: {
118
+ tags: ['artistic', 'style', 'creative', 'expression'],
119
+ author: 'StaticTemplateEngine',
120
+ version: '1.0.0',
121
+ },
122
+ },
123
+ {
124
+ id: 'animal-character-enhancement',
125
+ name: 'Animal Character Enhancement',
126
+ category: mcp_1.BestPracticeCategory.STYLE_ENHANCEMENT,
127
+ pattern: /\b(cat|dog|bird|horse|lion|tiger|elephant|bear|fox|wolf|rabbit|deer)\b/i,
128
+ enhancement: 'sweeping vista background with natural habitat, detailed fur/feather texture, expressive eyes, dynamic pose, professional wildlife photography lighting',
129
+ priority: 65,
130
+ metadata: {
131
+ tags: ['animal', 'wildlife', 'character', 'texture'],
132
+ author: 'StaticTemplateEngine',
133
+ version: '1.0.0',
134
+ },
135
+ },
136
+ ];
137
+ // Cache templates for performance on subsequent calls
138
+ this.cachedTemplates = templates;
139
+ // Build pattern index for O(1) template lookup
140
+ this.buildTemplateIndex(templates);
141
+ return templates;
142
+ }
143
+ /**
144
+ * Build indexed templates by extracting key terms from patterns
145
+ * Enables fast template lookup using word-based indexing
146
+ */
147
+ buildTemplateIndex(templates) {
148
+ this.templateIndex.clear();
149
+ for (const template of templates) {
150
+ // Extract key terms from regex pattern
151
+ const keyTerms = this.extractKeyTermsFromPattern(template.pattern);
152
+ for (const term of keyTerms) {
153
+ if (!this.templateIndex.has(term)) {
154
+ this.templateIndex.set(term, []);
155
+ }
156
+ this.templateIndex.get(term).push(template);
157
+ }
158
+ }
159
+ }
160
+ /**
161
+ * Extract searchable key terms from regex pattern
162
+ * Converts regex patterns to searchable keywords for indexing
163
+ */
164
+ extractKeyTermsFromPattern(pattern) {
165
+ const source = pattern.source.toLowerCase();
166
+ const terms = [];
167
+ // Extract literal words from regex (simple extraction)
168
+ const wordMatches = source.match(/[a-z]+/g);
169
+ if (wordMatches) {
170
+ terms.push(...wordMatches.filter((word) => word.length > 2)); // Only words longer than 2 chars
171
+ }
172
+ // Add some common pattern variations
173
+ if (source.includes('fantasy'))
174
+ terms.push('fantasy', 'medieval', 'knight');
175
+ if (source.includes('landscape'))
176
+ terms.push('landscape', 'nature', 'scenic');
177
+ if (source.includes('logo'))
178
+ terms.push('logo', 'brand', 'design');
179
+ if (source.includes('person'))
180
+ terms.push('person', 'character', 'human', 'portrait');
181
+ if (source.includes('car'))
182
+ terms.push('car', 'vehicle', 'automotive');
183
+ if (source.includes('photo'))
184
+ terms.push('photo', 'photograph', 'camera', 'image');
185
+ if (source.includes('artistic'))
186
+ terms.push('artistic', 'art', 'creative');
187
+ if (source.includes('cat|dog|bird'))
188
+ terms.push('cat', 'dog', 'bird', 'animal', 'pet');
189
+ return [...new Set(terms)]; // Remove duplicates
190
+ }
191
+ /**
192
+ * Find candidate templates using index-based lookup for improved performance
193
+ * Uses word-based indexing to reduce the number of regex evaluations needed
194
+ */
195
+ findCandidateTemplates(prompt) {
196
+ if (!prompt || typeof prompt !== 'string') {
197
+ return [];
198
+ }
199
+ const promptLower = prompt.toLowerCase();
200
+ const candidateTemplates = new Set();
201
+ // Extract words from prompt for index lookup
202
+ const words = promptLower.match(/[a-z]+/g) || [];
203
+ // Find templates using index
204
+ for (const word of words) {
205
+ const templates = this.templateIndex.get(word);
206
+ if (templates) {
207
+ for (const template of templates) {
208
+ candidateTemplates.add(template);
209
+ }
210
+ }
211
+ }
212
+ // If no candidates found via index, fall back to all templates
213
+ if (candidateTemplates.size === 0) {
214
+ return this.buildStaticTemplates();
215
+ }
216
+ return Array.from(candidateTemplates);
217
+ }
218
+ /**
219
+ * Check if a template pattern matches the given prompt
220
+ * Enhanced with caching for frequently tested patterns
221
+ */
222
+ matchPattern(prompt, template) {
223
+ if (!prompt || typeof prompt !== 'string') {
224
+ return false;
225
+ }
226
+ if (!template || !template.pattern || !(template.pattern instanceof RegExp)) {
227
+ return false;
228
+ }
229
+ // Create cache key for this prompt-template combination
230
+ const cacheKey = `${prompt.slice(0, 50)}:${template.id}`;
231
+ // Check pattern cache first
232
+ if (this.patternCache.has(cacheKey)) {
233
+ return this.patternCache.get(cacheKey);
234
+ }
235
+ try {
236
+ const result = template.pattern.test(prompt);
237
+ // Cache the result (limit cache size to prevent memory bloat)
238
+ if (this.patternCache.size < 1000) {
239
+ this.patternCache.set(cacheKey, result);
240
+ }
241
+ else {
242
+ // Clear cache when it gets too large
243
+ this.patternCache.clear();
244
+ this.patternCache.set(cacheKey, result);
245
+ }
246
+ return result;
247
+ }
248
+ catch (error) {
249
+ // Log error without exposing sensitive information
250
+ console.error('Template pattern matching failed:', {
251
+ templateId: template.id,
252
+ error: error instanceof Error ? error.message : 'Unknown error',
253
+ });
254
+ return false;
255
+ }
256
+ }
257
+ /**
258
+ * Apply template transformation to a prompt
259
+ * Enhanced with indexed template lookup for improved performance
260
+ * Includes comprehensive error handling and validation
261
+ */
262
+ applyTemplate(prompt) {
263
+ // Input validation
264
+ if (!prompt || typeof prompt !== 'string') {
265
+ return {
266
+ originalPrompt: prompt || '',
267
+ normalizedPrompt: prompt || '',
268
+ confidence: 0,
269
+ appliedRules: [],
270
+ };
271
+ }
272
+ try {
273
+ // Use optimized candidate template lookup instead of checking all templates
274
+ const candidateTemplates = this.findCandidateTemplates(prompt);
275
+ const matchingTemplates = candidateTemplates.filter((template) => this.matchPattern(prompt, template));
276
+ if (matchingTemplates.length === 0) {
277
+ return {
278
+ originalPrompt: prompt,
279
+ normalizedPrompt: prompt,
280
+ confidence: 0,
281
+ appliedRules: [],
282
+ };
283
+ }
284
+ // Use the highest priority template
285
+ const bestTemplate = matchingTemplates.reduce((best, current) => current.priority > best.priority ? current : best);
286
+ // Validate template has required properties
287
+ if (!bestTemplate.enhancement || !bestTemplate.id) {
288
+ return {
289
+ originalPrompt: prompt,
290
+ normalizedPrompt: prompt,
291
+ confidence: 0,
292
+ appliedRules: [],
293
+ };
294
+ }
295
+ const enhancedPrompt = `${prompt}, ${bestTemplate.enhancement}`;
296
+ return {
297
+ originalPrompt: prompt,
298
+ normalizedPrompt: enhancedPrompt,
299
+ confidence: 0.8, // Fixed confidence for now, will be improved in advanced processor
300
+ appliedRules: [bestTemplate.id],
301
+ };
302
+ }
303
+ catch (error) {
304
+ console.error('Template application failed:', {
305
+ error: error instanceof Error ? error.message : 'Unknown error',
306
+ prompt: prompt.substring(0, 50), // Only log first 50 chars for privacy
307
+ });
308
+ return {
309
+ originalPrompt: prompt,
310
+ normalizedPrompt: prompt,
311
+ confidence: 0,
312
+ appliedRules: [],
313
+ };
314
+ }
315
+ }
316
+ }
317
+ /**
318
+ * Advanced template processor with conflict resolution and confidence calculation
319
+ */
320
+ class AdvancedTemplateProcessor {
321
+ /**
322
+ * Resolve conflicts between competing templates based on priority
323
+ * Returns the highest priority templates only
324
+ * Includes comprehensive error handling and validation
325
+ */
326
+ resolveConflicts(templates, prompt) {
327
+ // Input validation
328
+ if (!Array.isArray(templates)) {
329
+ console.error('Templates must be an array');
330
+ return [];
331
+ }
332
+ if (templates.length <= 1) {
333
+ return templates;
334
+ }
335
+ if (typeof prompt !== 'string') {
336
+ console.error('Prompt must be a string');
337
+ return templates;
338
+ }
339
+ try {
340
+ // Filter out invalid templates
341
+ const validTemplates = templates.filter((template) => template && typeof template.priority === 'number' && !Number.isNaN(template.priority));
342
+ if (validTemplates.length === 0) {
343
+ return [];
344
+ }
345
+ // Sort by priority (highest first) and return only the highest priority ones
346
+ const sortedTemplates = validTemplates.sort((a, b) => b.priority - a.priority);
347
+ const highestPriority = sortedTemplates[0]?.priority;
348
+ if (highestPriority === undefined) {
349
+ return [];
350
+ }
351
+ return sortedTemplates.filter((template) => template.priority === highestPriority);
352
+ }
353
+ catch (error) {
354
+ console.error('Conflict resolution failed:', {
355
+ error: error instanceof Error ? error.message : 'Unknown error',
356
+ templateCount: templates.length,
357
+ });
358
+ return templates;
359
+ }
360
+ }
361
+ /**
362
+ * Calculate overall confidence based on multiple template matches
363
+ * Uses weighted average based on individual match confidences
364
+ * Includes comprehensive error handling and validation
365
+ */
366
+ calculateOverallConfidence(templateMatches) {
367
+ // Input validation
368
+ if (!Array.isArray(templateMatches)) {
369
+ console.error('Template matches must be an array');
370
+ return 0;
371
+ }
372
+ if (templateMatches.length === 0) {
373
+ return 0;
374
+ }
375
+ try {
376
+ // Filter out invalid matches
377
+ const validMatches = templateMatches.filter((match) => match &&
378
+ typeof match.confidence === 'number' &&
379
+ !Number.isNaN(match.confidence) &&
380
+ match.confidence >= 0 &&
381
+ match.confidence <= 1);
382
+ if (validMatches.length === 0) {
383
+ return 0;
384
+ }
385
+ if (validMatches.length === 1) {
386
+ return validMatches[0]?.confidence ?? 0;
387
+ }
388
+ // Calculate weighted average confidence
389
+ const totalWeight = validMatches.reduce((sum, match) => sum + match.confidence, 0);
390
+ if (totalWeight === 0) {
391
+ return 0;
392
+ }
393
+ const weightedSum = validMatches.reduce((sum, match) => sum + match.confidence * match.confidence, 0);
394
+ return Math.min(weightedSum / totalWeight, 1.0);
395
+ }
396
+ catch (error) {
397
+ console.error('Confidence calculation failed:', {
398
+ error: error instanceof Error ? error.message : 'Unknown error',
399
+ matchCount: templateMatches.length,
400
+ });
401
+ return 0;
402
+ }
403
+ }
404
+ }
405
+ /**
406
+ * BestPracticesTemplateNormalizer - orchestrates all 7 best practice templates
407
+ * Provides comprehensive prompt normalization with multiple rule application
408
+ */
409
+ class BestPracticesTemplateNormalizer {
410
+ constructor() {
411
+ this.engine = new StaticTemplateEngine();
412
+ this.processor = new AdvancedTemplateProcessor();
413
+ }
414
+ /**
415
+ * Normalize prompt by applying all matching best practice templates
416
+ * Applies templates sequentially based on priority and handles conflicts
417
+ */
418
+ normalize(prompt) {
419
+ if (!prompt || typeof prompt !== 'string') {
420
+ return {
421
+ originalPrompt: prompt || '',
422
+ normalizedPrompt: prompt || '',
423
+ confidence: 0,
424
+ appliedRules: [],
425
+ };
426
+ }
427
+ try {
428
+ // Step 1: Convert negative expressions to positive alternatives
429
+ const positivePrompt = this.convertNegativeToPositive(prompt);
430
+ // Step 2: Get candidate templates using optimized lookup
431
+ const candidateTemplates = this.engine.findCandidateTemplates(positivePrompt);
432
+ // Step 3: Find all matching templates using both original and positive prompts
433
+ const matchingTemplates = candidateTemplates.filter((template) => this.engine.matchPattern(prompt, template) ||
434
+ this.engine.matchPattern(positivePrompt, template));
435
+ if (matchingTemplates.length === 0) {
436
+ return {
437
+ originalPrompt: prompt,
438
+ normalizedPrompt: positivePrompt,
439
+ confidence: 0.1, // Small confidence for negative conversion
440
+ appliedRules: [],
441
+ };
442
+ }
443
+ // Step 4: Sort all matching templates by priority (no conflict resolution for comprehensive application)
444
+ const sortedTemplates = matchingTemplates.sort((a, b) => b.priority - a.priority);
445
+ // Step 5: Apply all matching templates sequentially
446
+ let normalizedPrompt = positivePrompt;
447
+ const appliedRules = [];
448
+ for (const template of sortedTemplates) {
449
+ if (template.enhancement && template.id) {
450
+ normalizedPrompt = `${normalizedPrompt}, ${template.enhancement}`;
451
+ appliedRules.push(template.id);
452
+ }
453
+ }
454
+ // Step 6: Automatically inject camera controls for photo-related prompts
455
+ const cameraEnhancedResult = this.injectCameraControls(normalizedPrompt, appliedRules);
456
+ // Step 7: Calculate overall confidence based on quality metrics
457
+ const templateMatches = sortedTemplates.map((template) => ({
458
+ template,
459
+ confidence: this.calculateTemplateConfidence(template, prompt),
460
+ matchedText: template.pattern.source,
461
+ position: { start: 0, end: normalizedPrompt.length },
462
+ }));
463
+ const confidence = Math.min(this.processor.calculateOverallConfidence(templateMatches), 1.0);
464
+ return {
465
+ originalPrompt: prompt,
466
+ normalizedPrompt: cameraEnhancedResult.prompt,
467
+ confidence: Math.max(confidence, 0.1),
468
+ appliedRules: cameraEnhancedResult.rules,
469
+ };
470
+ }
471
+ catch (error) {
472
+ console.error('BestPracticesTemplateNormalizer.normalize failed:', {
473
+ error: error instanceof Error ? error.message : 'Unknown error',
474
+ promptLength: prompt?.length || 0,
475
+ promptPreview: prompt?.substring(0, 50) || 'null/undefined',
476
+ stack: error instanceof Error ? error.stack : undefined,
477
+ });
478
+ // Return safe fallback result
479
+ return {
480
+ originalPrompt: prompt || '',
481
+ normalizedPrompt: prompt || '',
482
+ confidence: 0,
483
+ appliedRules: [],
484
+ };
485
+ }
486
+ }
487
+ /**
488
+ * Convert negative expressions to positive alternatives
489
+ * Transforms semantic negatives into constructive alternatives
490
+ */
491
+ convertNegativeToPositive(prompt) {
492
+ if (!prompt || typeof prompt !== 'string') {
493
+ return prompt;
494
+ }
495
+ let positivePrompt = prompt;
496
+ // Define negative to positive transformations
497
+ const transformations = [
498
+ { negative: /no\s+cars?/gi, positive: 'pedestrian-friendly environment' },
499
+ { negative: /avoid\s+people/gi, positive: 'peaceful solitary setting' },
500
+ { negative: /not\s+dark/gi, positive: 'well-lit bright atmosphere' },
501
+ { negative: /without\s+cars?/gi, positive: 'car-free zone with walking paths' },
502
+ { negative: /car.*free/gi, positive: 'pedestrian and cyclist friendly area' },
503
+ { negative: /avoid.*cars?/gi, positive: 'public transportation and walking infrastructure' },
504
+ ];
505
+ // Apply transformations
506
+ for (const { negative, positive } of transformations) {
507
+ if (negative.test(positivePrompt)) {
508
+ positivePrompt = positivePrompt.replace(negative, positive);
509
+ }
510
+ }
511
+ return positivePrompt;
512
+ }
513
+ /**
514
+ * Calculate confidence score for individual template matches
515
+ * Uses template priority and pattern specificity for scoring
516
+ */
517
+ calculateTemplateConfidence(template, prompt) {
518
+ try {
519
+ if (!template || !prompt) {
520
+ return 0;
521
+ }
522
+ // Base confidence from priority (0-100 normalized to 0-1)
523
+ const priorityScore = template.priority / 100;
524
+ // Pattern specificity bonus for more specific patterns
525
+ const patternLength = template.pattern.source.length;
526
+ const specificityBonus = Math.min(patternLength / 50, 0.2); // Max 0.2 bonus
527
+ // Calculate final confidence with bounds checking
528
+ const confidence = Math.min(priorityScore + specificityBonus, 1.0);
529
+ return Math.max(confidence, 0.1); // Minimum confidence for matched templates
530
+ }
531
+ catch (error) {
532
+ console.warn('Template confidence calculation failed:', {
533
+ templateId: template?.id || 'unknown',
534
+ error: error instanceof Error ? error.message : 'Unknown error',
535
+ });
536
+ return 0.5; // Fallback confidence
537
+ }
538
+ }
539
+ /**
540
+ * Automatically inject camera controls for photo-related prompts
541
+ * Ensures professional camera settings are included when appropriate
542
+ */
543
+ injectCameraControls(prompt, currentRules) {
544
+ try {
545
+ // Check if prompt is photo-related and camera enhancement not already applied
546
+ const photoKeywords = /photo|photograph|image|shot|camera|portrait/i;
547
+ const hasCameraRule = currentRules.includes('default-camera-enhancement');
548
+ if (photoKeywords.test(prompt) && !hasCameraRule) {
549
+ const cameraEnhancement = 'professional camera settings, optimal lighting conditions, sharp focus with appropriate depth of field, balanced exposure, high resolution detail';
550
+ return {
551
+ prompt: `${prompt}, ${cameraEnhancement}`,
552
+ rules: [...currentRules, 'default-camera-enhancement'],
553
+ };
554
+ }
555
+ return { prompt, rules: currentRules };
556
+ }
557
+ catch (error) {
558
+ console.error('Camera control injection failed:', {
559
+ error: error instanceof Error ? error.message : 'Unknown error',
560
+ ruleCount: currentRules?.length || 0,
561
+ });
562
+ return { prompt, rules: currentRules };
563
+ }
564
+ }
565
+ }
566
+ exports.BestPracticesTemplateNormalizer = BestPracticesTemplateNormalizer;
567
+ /**
568
+ * Unified TemplateNormalizer interface with Result pattern for safe error handling
569
+ * Provides comprehensive normalization with fallback capabilities
570
+ */
571
+ class TemplateNormalizer {
572
+ constructor() {
573
+ this.bestPracticesNormalizer = new BestPracticesTemplateNormalizer();
574
+ this.staticEngine = new StaticTemplateEngine();
575
+ this.processor = new AdvancedTemplateProcessor();
576
+ }
577
+ /**
578
+ * Normalize prompt using best practices with automatic fallback
579
+ * Uses Result pattern for safe error handling
580
+ */
581
+ normalize(prompt) {
582
+ try {
583
+ // Primary normalization using best practices
584
+ const result = this.bestPracticesNormalizer.normalize(prompt);
585
+ // Validate result quality
586
+ if (result.confidence > 0 && result.normalizedPrompt) {
587
+ return result;
588
+ }
589
+ // Fallback to static template engine if best practices fail
590
+ console.warn('Best practices normalization failed, falling back to static templates', {
591
+ originalPrompt: prompt?.substring(0, 50),
592
+ confidence: result.confidence,
593
+ });
594
+ return this.staticEngine.applyTemplate(prompt);
595
+ }
596
+ catch (error) {
597
+ console.error('All normalization methods failed, returning original prompt', {
598
+ error: error instanceof Error ? error.message : 'Unknown error',
599
+ prompt: prompt?.substring(0, 50),
600
+ });
601
+ // Ultimate fallback - return original prompt
602
+ return {
603
+ originalPrompt: prompt || '',
604
+ normalizedPrompt: prompt || '',
605
+ confidence: 0,
606
+ appliedRules: [],
607
+ };
608
+ }
609
+ }
610
+ /**
611
+ * Get all available templates
612
+ */
613
+ getAvailableTemplates() {
614
+ return this.staticEngine.buildStaticTemplates();
615
+ }
616
+ /**
617
+ * Calculate confidence score for template matches
618
+ */
619
+ calculateConfidence(matches) {
620
+ return this.processor.calculateOverallConfidence(matches);
621
+ }
622
+ /**
623
+ * Convert negative expressions to positive alternatives
624
+ * Exposes the convertNegativeToPositive functionality
625
+ */
626
+ convertNegativeToPositive(prompt) {
627
+ return this.bestPracticesNormalizer.convertNegativeToPositive(prompt);
628
+ }
629
+ }
630
+ exports.TemplateNormalizer = TemplateNormalizer;
631
+ /**
632
+ * Factory function to create a template normalizer with default configuration
633
+ * Provides a clean interface for prompt normalization using embedded templates
634
+ */
635
+ function createTemplateNormalizer() {
636
+ const engine = new StaticTemplateEngine();
637
+ const processor = new AdvancedTemplateProcessor();
638
+ return {
639
+ /**
640
+ * Normalize a prompt by applying the best matching template
641
+ */
642
+ normalizePrompt(prompt) {
643
+ return engine.applyTemplate(prompt);
644
+ },
645
+ /**
646
+ * Get all available templates
647
+ */
648
+ getAvailableTemplates() {
649
+ return engine.buildStaticTemplates();
650
+ },
651
+ /**
652
+ * Calculate confidence score for template matches
653
+ */
654
+ calculateConfidence(matches) {
655
+ return processor.calculateOverallConfidence(matches);
656
+ },
657
+ };
658
+ }
659
+ //# sourceMappingURL=templateNormalizer.js.map