@michelabboud/visual-forge-mcp 0.6.0 → 0.7.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/CHANGELOG.md +403 -2
- package/README.md +88 -5
- package/config/pricing.json +1 -1
- package/dist/parser/markdown-parser.d.ts +2 -0
- package/dist/parser/markdown-parser.d.ts.map +1 -1
- package/dist/parser/markdown-parser.js +23 -10
- package/dist/parser/markdown-parser.js.map +1 -1
- package/dist/placeholders/placeholder-manager.d.ts +8 -0
- package/dist/placeholders/placeholder-manager.d.ts.map +1 -1
- package/dist/placeholders/placeholder-manager.js +71 -18
- package/dist/placeholders/placeholder-manager.js.map +1 -1
- package/dist/providers/base-provider.d.ts +13 -0
- package/dist/providers/base-provider.d.ts.map +1 -1
- package/dist/providers/base-provider.js +263 -17
- package/dist/providers/base-provider.js.map +1 -1
- package/dist/providers/gemini/gemini-provider.d.ts.map +1 -1
- package/dist/providers/gemini/gemini-provider.js +3 -7
- package/dist/providers/gemini/gemini-provider.js.map +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +5 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/mcp-server.js +4 -1
- package/dist/server/mcp-server.js.map +1 -1
- package/dist/utils/filename-sanitizer.d.ts +85 -0
- package/dist/utils/filename-sanitizer.d.ts.map +1 -0
- package/dist/utils/filename-sanitizer.js +156 -0
- package/dist/utils/filename-sanitizer.js.map +1 -0
- package/dist/utils/image-metadata-manager.d.ts +151 -0
- package/dist/utils/image-metadata-manager.d.ts.map +1 -0
- package/dist/utils/image-metadata-manager.js +172 -0
- package/dist/utils/image-metadata-manager.js.map +1 -0
- package/dist/utils/index-manager.d.ts +38 -0
- package/dist/utils/index-manager.d.ts.map +1 -0
- package/dist/utils/index-manager.js +110 -0
- package/dist/utils/index-manager.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/multi-format-optimizer.d.ts +96 -0
- package/dist/utils/multi-format-optimizer.d.ts.map +1 -0
- package/dist/utils/multi-format-optimizer.js +423 -0
- package/dist/utils/multi-format-optimizer.js.map +1 -0
- package/dist/utils/pricing-checker.d.ts.map +1 -1
- package/dist/utils/pricing-checker.js +3 -5
- package/dist/utils/pricing-checker.js.map +1 -1
- package/dist/utils/prompt-enhancer.d.ts +48 -0
- package/dist/utils/prompt-enhancer.d.ts.map +1 -0
- package/dist/utils/prompt-enhancer.js +169 -0
- package/dist/utils/prompt-enhancer.js.map +1 -0
- package/dist/utils/quality-validator.d.ts +61 -0
- package/dist/utils/quality-validator.d.ts.map +1 -0
- package/dist/utils/quality-validator.js +386 -0
- package/dist/utils/quality-validator.js.map +1 -0
- package/dist/utils/source-metadata.d.ts +56 -0
- package/dist/utils/source-metadata.d.ts.map +1 -0
- package/dist/utils/source-metadata.js +122 -0
- package/dist/utils/source-metadata.js.map +1 -0
- package/dist/workflow/workflow-orchestrator.d.ts.map +1 -1
- package/dist/workflow/workflow-orchestrator.js +23 -0
- package/dist/workflow/workflow-orchestrator.js.map +1 -1
- package/dist/workflow/workflow-tools.d.ts.map +1 -1
- package/dist/workflow/workflow-tools.js +18 -0
- package/dist/workflow/workflow-tools.js.map +1 -1
- package/docs/guides/provider-setup.md +543 -0
- package/package.json +2 -2
- package/scripts/README.md +460 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Enhancer - Enhances prompts to minimize AI text rendering errors
|
|
3
|
+
* Adds specific instructions to reduce gibberish and improve quality
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from './logger.js';
|
|
6
|
+
/**
|
|
7
|
+
* Default enhancement configuration
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_CONFIG = {
|
|
10
|
+
preventText: true,
|
|
11
|
+
preventLabels: true,
|
|
12
|
+
addQualityInstructions: true,
|
|
13
|
+
addStyleInstructions: true,
|
|
14
|
+
customPrefix: '',
|
|
15
|
+
customSuffix: '',
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Text prevention instructions (prevent AI from adding text)
|
|
19
|
+
*/
|
|
20
|
+
const TEXT_PREVENTION_INSTRUCTIONS = [
|
|
21
|
+
'no text or labels',
|
|
22
|
+
'no watermarks',
|
|
23
|
+
'no captions',
|
|
24
|
+
'no written words',
|
|
25
|
+
'clean visual only',
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Quality enhancement keywords
|
|
29
|
+
*/
|
|
30
|
+
const QUALITY_KEYWORDS = [
|
|
31
|
+
'professional',
|
|
32
|
+
'high quality',
|
|
33
|
+
'detailed',
|
|
34
|
+
'crisp',
|
|
35
|
+
'clear',
|
|
36
|
+
'well-defined',
|
|
37
|
+
];
|
|
38
|
+
/**
|
|
39
|
+
* Style consistency keywords
|
|
40
|
+
*/
|
|
41
|
+
const STYLE_KEYWORDS = [
|
|
42
|
+
'consistent style',
|
|
43
|
+
'cohesive design',
|
|
44
|
+
'unified aesthetic',
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* Enhance a prompt to minimize text rendering errors
|
|
48
|
+
*
|
|
49
|
+
* @param originalPrompt - The original prompt
|
|
50
|
+
* @param config - Enhancement configuration
|
|
51
|
+
* @returns Enhanced prompt
|
|
52
|
+
*/
|
|
53
|
+
export function enhancePrompt(originalPrompt, config = {}) {
|
|
54
|
+
// Merge with defaults
|
|
55
|
+
const fullConfig = {
|
|
56
|
+
...DEFAULT_CONFIG,
|
|
57
|
+
...config,
|
|
58
|
+
};
|
|
59
|
+
const parts = [];
|
|
60
|
+
// Add custom prefix
|
|
61
|
+
if (fullConfig.customPrefix) {
|
|
62
|
+
parts.push(fullConfig.customPrefix);
|
|
63
|
+
}
|
|
64
|
+
// Add original prompt
|
|
65
|
+
parts.push(originalPrompt);
|
|
66
|
+
const enhancements = [];
|
|
67
|
+
// Add quality instructions
|
|
68
|
+
if (fullConfig.addQualityInstructions) {
|
|
69
|
+
enhancements.push(...QUALITY_KEYWORDS);
|
|
70
|
+
}
|
|
71
|
+
// Add style instructions
|
|
72
|
+
if (fullConfig.addStyleInstructions) {
|
|
73
|
+
enhancements.push(...STYLE_KEYWORDS);
|
|
74
|
+
}
|
|
75
|
+
// Add text prevention
|
|
76
|
+
if (fullConfig.preventText || fullConfig.preventLabels) {
|
|
77
|
+
enhancements.push(...TEXT_PREVENTION_INSTRUCTIONS);
|
|
78
|
+
}
|
|
79
|
+
// Add custom suffix
|
|
80
|
+
if (fullConfig.customSuffix) {
|
|
81
|
+
enhancements.push(fullConfig.customSuffix);
|
|
82
|
+
}
|
|
83
|
+
// Combine enhancements
|
|
84
|
+
if (enhancements.length > 0) {
|
|
85
|
+
parts.push(enhancements.join(', '));
|
|
86
|
+
}
|
|
87
|
+
const enhancedPrompt = parts.join(', ');
|
|
88
|
+
logger.debug('Prompt enhanced', {
|
|
89
|
+
originalLength: originalPrompt.length,
|
|
90
|
+
enhancedLength: enhancedPrompt.length,
|
|
91
|
+
addedKeywords: enhancements.length,
|
|
92
|
+
});
|
|
93
|
+
return enhancedPrompt;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Enhance prompt specifically for diagrams
|
|
97
|
+
*/
|
|
98
|
+
export function enhanceForDiagram(prompt) {
|
|
99
|
+
return enhancePrompt(prompt, {
|
|
100
|
+
preventText: true,
|
|
101
|
+
preventLabels: false, // Diagrams may need labels
|
|
102
|
+
addQualityInstructions: true,
|
|
103
|
+
addStyleInstructions: true,
|
|
104
|
+
customSuffix: 'technical diagram, clean lines, clear structure',
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Enhance prompt specifically for illustrations
|
|
109
|
+
*/
|
|
110
|
+
export function enhanceForIllustration(prompt) {
|
|
111
|
+
return enhancePrompt(prompt, {
|
|
112
|
+
preventText: true,
|
|
113
|
+
preventLabels: true,
|
|
114
|
+
addQualityInstructions: true,
|
|
115
|
+
addStyleInstructions: true,
|
|
116
|
+
customSuffix: 'artistic illustration, visual storytelling, no text overlay',
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Enhance prompt specifically for icons
|
|
121
|
+
*/
|
|
122
|
+
export function enhanceForIcon(prompt) {
|
|
123
|
+
return enhancePrompt(prompt, {
|
|
124
|
+
preventText: true,
|
|
125
|
+
preventLabels: true,
|
|
126
|
+
addQualityInstructions: true,
|
|
127
|
+
addStyleInstructions: true,
|
|
128
|
+
customSuffix: 'simple icon, minimalist design, scalable vector style',
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Enhance prompt specifically for screenshots
|
|
133
|
+
*/
|
|
134
|
+
export function enhanceForScreenshot(prompt) {
|
|
135
|
+
return enhancePrompt(prompt, {
|
|
136
|
+
preventText: false, // Screenshots may contain UI text
|
|
137
|
+
preventLabels: false,
|
|
138
|
+
addQualityInstructions: true,
|
|
139
|
+
addStyleInstructions: true,
|
|
140
|
+
customSuffix: 'realistic UI mockup, modern interface design',
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Enhance prompt based on image type
|
|
145
|
+
*/
|
|
146
|
+
export function enhanceByType(prompt, imageType) {
|
|
147
|
+
switch (imageType) {
|
|
148
|
+
case 'diagram':
|
|
149
|
+
case 'flowchart':
|
|
150
|
+
case 'architecture':
|
|
151
|
+
return enhanceForDiagram(prompt);
|
|
152
|
+
case 'illustration':
|
|
153
|
+
case 'hero':
|
|
154
|
+
return enhanceForIllustration(prompt);
|
|
155
|
+
case 'icon':
|
|
156
|
+
return enhanceForIcon(prompt);
|
|
157
|
+
case 'screenshot':
|
|
158
|
+
return enhanceForScreenshot(prompt);
|
|
159
|
+
default:
|
|
160
|
+
return enhancePrompt(prompt);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get default enhancement configuration
|
|
165
|
+
*/
|
|
166
|
+
export function getDefaultEnhancementConfig() {
|
|
167
|
+
return { ...DEFAULT_CONFIG };
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=prompt-enhancer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-enhancer.js","sourceRoot":"","sources":["../../src/utils/prompt-enhancer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quality Validator - Validates generated images for quality issues
|
|
3
|
+
* Uses OCR (Tesseract.js) to detect text rendering problems
|
|
4
|
+
* Analyzes sharpness, brightness, and other quality metrics
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Quality validation configuration
|
|
8
|
+
*/
|
|
9
|
+
export interface QualityValidationConfig {
|
|
10
|
+
enableOCR?: boolean;
|
|
11
|
+
maxGibberishRatio?: number;
|
|
12
|
+
minConfidence?: number;
|
|
13
|
+
minSharpness?: number;
|
|
14
|
+
minBrightness?: number;
|
|
15
|
+
maxBrightness?: number;
|
|
16
|
+
minQualityScore?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Quality validation result
|
|
20
|
+
*/
|
|
21
|
+
export interface QualityValidationResult {
|
|
22
|
+
passed: boolean;
|
|
23
|
+
score: number;
|
|
24
|
+
sharpness?: {
|
|
25
|
+
value: number;
|
|
26
|
+
passed: boolean;
|
|
27
|
+
threshold: number;
|
|
28
|
+
};
|
|
29
|
+
brightness?: {
|
|
30
|
+
value: number;
|
|
31
|
+
passed: boolean;
|
|
32
|
+
minThreshold: number;
|
|
33
|
+
maxThreshold: number;
|
|
34
|
+
};
|
|
35
|
+
ocr?: {
|
|
36
|
+
text: string;
|
|
37
|
+
confidence: number;
|
|
38
|
+
gibberishRatio: number;
|
|
39
|
+
passed: boolean;
|
|
40
|
+
issues: string[];
|
|
41
|
+
};
|
|
42
|
+
failureReasons: string[];
|
|
43
|
+
recommendations: string[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Validate image quality
|
|
47
|
+
*/
|
|
48
|
+
export declare function validateImageQuality(imagePath: string, config?: QualityValidationConfig): Promise<QualityValidationResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Check if quality validation is available
|
|
51
|
+
*/
|
|
52
|
+
export declare function isQualityValidationAvailable(): Promise<{
|
|
53
|
+
sharpAvailable: boolean;
|
|
54
|
+
tesseractAvailable: boolean;
|
|
55
|
+
fullyAvailable: boolean;
|
|
56
|
+
}>;
|
|
57
|
+
/**
|
|
58
|
+
* Get default quality validation configuration
|
|
59
|
+
*/
|
|
60
|
+
export declare function getDefaultQualityConfig(): Required<QualityValidationConfig>;
|
|
61
|
+
//# sourceMappingURL=quality-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-validator.d.ts","sourceRoot":"","sources":["../../src/utils/quality-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0DH;;GAEG;AACH,MAAM,WAAW,uBAAuB;IAEtC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IAGd,SAAS,CAAC,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAEF,UAAU,CAAC,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IAEF,GAAG,CAAC,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IAGF,cAAc,EAAE,MAAM,EAAE,CAAC;IAGzB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AA6PD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,uBAA4B,GACnC,OAAO,CAAC,uBAAuB,CAAC,CAoHlC;AAED;;GAEG;AACH,wBAAsB,4BAA4B,IAAI,OAAO,CAAC;IAC5D,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC,CASD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,QAAQ,CAAC,uBAAuB,CAAC,CAE3E"}
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quality Validator - Validates generated images for quality issues
|
|
3
|
+
* Uses OCR (Tesseract.js) to detect text rendering problems
|
|
4
|
+
* Analyzes sharpness, brightness, and other quality metrics
|
|
5
|
+
*/
|
|
6
|
+
import { logger } from './logger.js';
|
|
7
|
+
// Dynamic import of Sharp and Tesseract
|
|
8
|
+
let sharp = null;
|
|
9
|
+
let tesseract = null; // Use 'any' since tesseract.js might not be installed
|
|
10
|
+
let sharpAvailable = false;
|
|
11
|
+
let tesseractAvailable = false;
|
|
12
|
+
/**
|
|
13
|
+
* Initialize Sharp library
|
|
14
|
+
*/
|
|
15
|
+
async function initializeSharp() {
|
|
16
|
+
if (sharp !== null) {
|
|
17
|
+
return sharpAvailable;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
sharp = (await import('sharp')).default;
|
|
21
|
+
sharpAvailable = true;
|
|
22
|
+
logger.debug('Sharp library loaded for quality validation');
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
sharpAvailable = false;
|
|
27
|
+
logger.warn('Sharp not available - quality validation will be limited', {
|
|
28
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
29
|
+
});
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Initialize Tesseract library
|
|
35
|
+
*/
|
|
36
|
+
async function initializeTesseract() {
|
|
37
|
+
if (tesseract !== null) {
|
|
38
|
+
return tesseractAvailable;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
// Try to dynamically import tesseract.js (optional dependency)
|
|
42
|
+
// @ts-ignore - tesseract.js is an optional dependency
|
|
43
|
+
const tesseractModule = await import('tesseract.js');
|
|
44
|
+
tesseract = tesseractModule;
|
|
45
|
+
tesseractAvailable = true;
|
|
46
|
+
logger.info('Tesseract.js loaded - OCR text validation enabled');
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
tesseractAvailable = false;
|
|
51
|
+
logger.warn('Tesseract.js not available - OCR validation disabled', {
|
|
52
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
53
|
+
hint: 'Install with: npm install tesseract.js',
|
|
54
|
+
});
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Default quality validation configuration
|
|
60
|
+
*/
|
|
61
|
+
const DEFAULT_CONFIG = {
|
|
62
|
+
enableOCR: true,
|
|
63
|
+
maxGibberishRatio: 0.3,
|
|
64
|
+
minConfidence: 60,
|
|
65
|
+
minSharpness: 50,
|
|
66
|
+
minBrightness: 30,
|
|
67
|
+
maxBrightness: 240,
|
|
68
|
+
minQualityScore: 60,
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Detect gibberish in text using heuristics
|
|
72
|
+
*/
|
|
73
|
+
function detectGibberish(text) {
|
|
74
|
+
if (!text || text.trim().length === 0) {
|
|
75
|
+
return { isGibberish: false, ratio: 0 };
|
|
76
|
+
}
|
|
77
|
+
const words = text.split(/\s+/).filter(w => w.length > 0);
|
|
78
|
+
if (words.length === 0) {
|
|
79
|
+
return { isGibberish: false, ratio: 0 };
|
|
80
|
+
}
|
|
81
|
+
let gibberishCount = 0;
|
|
82
|
+
// Common gibberish patterns
|
|
83
|
+
const gibberishPatterns = [
|
|
84
|
+
/^[^aeiouAEIOU]{5,}$/, // Too many consonants
|
|
85
|
+
/(.)\1{3,}/, // Repeated characters (aaaa)
|
|
86
|
+
/^[a-zA-Z]{1,2}$/, // Single/double letter words (except common ones)
|
|
87
|
+
/[^a-zA-Z0-9\s\-'.,!?@#$%&*()]/, // Unusual characters
|
|
88
|
+
/^[0-9]+[a-zA-Z]+[0-9]+$/, // Numbers mixed with letters oddly
|
|
89
|
+
];
|
|
90
|
+
// Common short words that are OK
|
|
91
|
+
const commonShortWords = new Set([
|
|
92
|
+
'a', 'i', 'an', 'as', 'at', 'be', 'by', 'do', 'go', 'he', 'if', 'in', 'is', 'it',
|
|
93
|
+
'me', 'my', 'no', 'of', 'on', 'or', 'so', 'to', 'up', 'us', 'we',
|
|
94
|
+
]);
|
|
95
|
+
for (const word of words) {
|
|
96
|
+
const lowerWord = word.toLowerCase();
|
|
97
|
+
// Skip common short words
|
|
98
|
+
if (commonShortWords.has(lowerWord)) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
// Check for gibberish patterns
|
|
102
|
+
let isGibberishWord = false;
|
|
103
|
+
for (const pattern of gibberishPatterns) {
|
|
104
|
+
if (pattern.test(word)) {
|
|
105
|
+
isGibberishWord = true;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Check vowel ratio (real words usually have 20-60% vowels)
|
|
110
|
+
const vowels = word.match(/[aeiouAEIOU]/g);
|
|
111
|
+
const vowelRatio = vowels ? vowels.length / word.length : 0;
|
|
112
|
+
if (word.length > 3 && (vowelRatio < 0.1 || vowelRatio > 0.8)) {
|
|
113
|
+
isGibberishWord = true;
|
|
114
|
+
}
|
|
115
|
+
if (isGibberishWord) {
|
|
116
|
+
gibberishCount++;
|
|
117
|
+
logger.debug('Detected gibberish word', { word });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const ratio = gibberishCount / words.length;
|
|
121
|
+
const isGibberish = ratio > 0.3; // More than 30% gibberish
|
|
122
|
+
return { isGibberish, ratio };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Calculate sharpness using Laplacian variance
|
|
126
|
+
*/
|
|
127
|
+
async function calculateSharpness(imagePath) {
|
|
128
|
+
if (!sharp) {
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const image = sharp(imagePath);
|
|
133
|
+
const { data, info } = await image
|
|
134
|
+
.greyscale()
|
|
135
|
+
.raw()
|
|
136
|
+
.toBuffer({ resolveWithObject: true });
|
|
137
|
+
// Calculate Laplacian variance (edge detection)
|
|
138
|
+
const width = info.width;
|
|
139
|
+
const height = info.height;
|
|
140
|
+
let sum = 0;
|
|
141
|
+
let count = 0;
|
|
142
|
+
for (let y = 1; y < height - 1; y++) {
|
|
143
|
+
for (let x = 1; x < width - 1; x++) {
|
|
144
|
+
const idx = y * width + x;
|
|
145
|
+
const center = data[idx];
|
|
146
|
+
const top = data[(y - 1) * width + x];
|
|
147
|
+
const bottom = data[(y + 1) * width + x];
|
|
148
|
+
const left = data[y * width + (x - 1)];
|
|
149
|
+
const right = data[y * width + (x + 1)];
|
|
150
|
+
// Laplacian kernel
|
|
151
|
+
const laplacian = Math.abs(4 * center - top - bottom - left - right);
|
|
152
|
+
sum += laplacian * laplacian;
|
|
153
|
+
count++;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const variance = sum / count;
|
|
157
|
+
return variance;
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
logger.warn('Failed to calculate sharpness', {
|
|
161
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
162
|
+
});
|
|
163
|
+
return 0;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Calculate average brightness
|
|
168
|
+
*/
|
|
169
|
+
async function calculateBrightness(imagePath) {
|
|
170
|
+
if (!sharp) {
|
|
171
|
+
return 128;
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const image = sharp(imagePath);
|
|
175
|
+
const { data } = await image
|
|
176
|
+
.greyscale()
|
|
177
|
+
.raw()
|
|
178
|
+
.toBuffer({ resolveWithObject: true });
|
|
179
|
+
const sum = Array.from(data).reduce((acc, val) => acc + val, 0);
|
|
180
|
+
const average = sum / data.length;
|
|
181
|
+
return average;
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
logger.warn('Failed to calculate brightness', {
|
|
185
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
186
|
+
});
|
|
187
|
+
return 128;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Perform OCR text detection and validation
|
|
192
|
+
*/
|
|
193
|
+
async function performOCR(imagePath, config) {
|
|
194
|
+
if (!tesseract || !tesseractAvailable) {
|
|
195
|
+
logger.debug('OCR skipped - Tesseract not available');
|
|
196
|
+
return {
|
|
197
|
+
text: '',
|
|
198
|
+
confidence: 100,
|
|
199
|
+
gibberishRatio: 0,
|
|
200
|
+
passed: true,
|
|
201
|
+
issues: [],
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
logger.debug('Performing OCR text detection', { imagePath });
|
|
206
|
+
const worker = await tesseract.createWorker('eng');
|
|
207
|
+
const { data } = await worker.recognize(imagePath);
|
|
208
|
+
await worker.terminate();
|
|
209
|
+
const detectedText = data.text.trim();
|
|
210
|
+
const avgConfidence = data.confidence;
|
|
211
|
+
logger.debug('OCR completed', {
|
|
212
|
+
textLength: detectedText.length,
|
|
213
|
+
confidence: avgConfidence.toFixed(1),
|
|
214
|
+
});
|
|
215
|
+
const issues = [];
|
|
216
|
+
// Check if text was detected (might indicate unwanted text in image)
|
|
217
|
+
if (detectedText.length === 0) {
|
|
218
|
+
// No text detected - this is usually good for diagrams
|
|
219
|
+
return {
|
|
220
|
+
text: '',
|
|
221
|
+
confidence: 100,
|
|
222
|
+
gibberishRatio: 0,
|
|
223
|
+
passed: true,
|
|
224
|
+
issues: [],
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
// If text was detected, validate quality
|
|
228
|
+
const gibberishAnalysis = detectGibberish(detectedText);
|
|
229
|
+
// Low confidence
|
|
230
|
+
if (avgConfidence < config.minConfidence) {
|
|
231
|
+
issues.push(`Low OCR confidence: ${avgConfidence.toFixed(1)}% (min: ${config.minConfidence}%)`);
|
|
232
|
+
}
|
|
233
|
+
// High gibberish ratio
|
|
234
|
+
if (gibberishAnalysis.ratio > config.maxGibberishRatio) {
|
|
235
|
+
issues.push(`High gibberish ratio: ${(gibberishAnalysis.ratio * 100).toFixed(1)}% (max: ${config.maxGibberishRatio * 100}%)`);
|
|
236
|
+
}
|
|
237
|
+
const passed = issues.length === 0;
|
|
238
|
+
if (!passed) {
|
|
239
|
+
logger.warn('OCR quality issues detected', {
|
|
240
|
+
text: detectedText.substring(0, 100),
|
|
241
|
+
confidence: avgConfidence,
|
|
242
|
+
gibberishRatio: gibberishAnalysis.ratio,
|
|
243
|
+
issues,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
text: detectedText,
|
|
248
|
+
confidence: avgConfidence,
|
|
249
|
+
gibberishRatio: gibberishAnalysis.ratio,
|
|
250
|
+
passed,
|
|
251
|
+
issues,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
logger.warn('OCR failed', {
|
|
256
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
257
|
+
});
|
|
258
|
+
// On error, pass validation (don't block generation)
|
|
259
|
+
return {
|
|
260
|
+
text: '',
|
|
261
|
+
confidence: 0,
|
|
262
|
+
gibberishRatio: 0,
|
|
263
|
+
passed: true,
|
|
264
|
+
issues: ['OCR error - validation skipped'],
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Validate image quality
|
|
270
|
+
*/
|
|
271
|
+
export async function validateImageQuality(imagePath, config = {}) {
|
|
272
|
+
// Merge with defaults
|
|
273
|
+
const fullConfig = {
|
|
274
|
+
...DEFAULT_CONFIG,
|
|
275
|
+
...config,
|
|
276
|
+
};
|
|
277
|
+
// Initialize libraries
|
|
278
|
+
await initializeSharp();
|
|
279
|
+
if (fullConfig.enableOCR) {
|
|
280
|
+
await initializeTesseract();
|
|
281
|
+
}
|
|
282
|
+
logger.info('Starting quality validation', {
|
|
283
|
+
imagePath,
|
|
284
|
+
ocrEnabled: fullConfig.enableOCR && tesseractAvailable,
|
|
285
|
+
});
|
|
286
|
+
const failureReasons = [];
|
|
287
|
+
const recommendations = [];
|
|
288
|
+
// Calculate sharpness
|
|
289
|
+
let sharpnessResult;
|
|
290
|
+
if (sharpAvailable) {
|
|
291
|
+
const sharpnessValue = await calculateSharpness(imagePath);
|
|
292
|
+
const sharpnessPassed = sharpnessValue >= fullConfig.minSharpness;
|
|
293
|
+
sharpnessResult = {
|
|
294
|
+
value: sharpnessValue,
|
|
295
|
+
passed: sharpnessPassed,
|
|
296
|
+
threshold: fullConfig.minSharpness,
|
|
297
|
+
};
|
|
298
|
+
if (!sharpnessPassed) {
|
|
299
|
+
failureReasons.push(`Low sharpness: ${sharpnessValue.toFixed(1)} (min: ${fullConfig.minSharpness})`);
|
|
300
|
+
recommendations.push('Image appears blurry - may need higher resolution or better AI model');
|
|
301
|
+
}
|
|
302
|
+
logger.debug('Sharpness calculated', sharpnessResult);
|
|
303
|
+
}
|
|
304
|
+
// Calculate brightness
|
|
305
|
+
let brightnessResult;
|
|
306
|
+
if (sharpAvailable) {
|
|
307
|
+
const brightnessValue = await calculateBrightness(imagePath);
|
|
308
|
+
const brightnessPassed = brightnessValue >= fullConfig.minBrightness &&
|
|
309
|
+
brightnessValue <= fullConfig.maxBrightness;
|
|
310
|
+
brightnessResult = {
|
|
311
|
+
value: brightnessValue,
|
|
312
|
+
passed: brightnessPassed,
|
|
313
|
+
minThreshold: fullConfig.minBrightness,
|
|
314
|
+
maxThreshold: fullConfig.maxBrightness,
|
|
315
|
+
};
|
|
316
|
+
if (!brightnessPassed) {
|
|
317
|
+
if (brightnessValue < fullConfig.minBrightness) {
|
|
318
|
+
failureReasons.push(`Too dark: ${brightnessValue.toFixed(1)} (min: ${fullConfig.minBrightness})`);
|
|
319
|
+
recommendations.push('Image is too dark - adjust prompt or generation parameters');
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
failureReasons.push(`Too bright: ${brightnessValue.toFixed(1)} (max: ${fullConfig.maxBrightness})`);
|
|
323
|
+
recommendations.push('Image is too bright - adjust prompt or generation parameters');
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
logger.debug('Brightness calculated', brightnessResult);
|
|
327
|
+
}
|
|
328
|
+
// Perform OCR validation
|
|
329
|
+
let ocrResult;
|
|
330
|
+
if (fullConfig.enableOCR && tesseractAvailable) {
|
|
331
|
+
const ocr = await performOCR(imagePath, fullConfig);
|
|
332
|
+
ocrResult = ocr;
|
|
333
|
+
if (!ocr.passed) {
|
|
334
|
+
failureReasons.push(...ocr.issues);
|
|
335
|
+
recommendations.push('Text rendering issues detected - consider regenerating with enhanced prompt');
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Calculate overall quality score (0-100)
|
|
339
|
+
let score = 100;
|
|
340
|
+
if (sharpnessResult && !sharpnessResult.passed) {
|
|
341
|
+
score -= 30;
|
|
342
|
+
}
|
|
343
|
+
if (brightnessResult && !brightnessResult.passed) {
|
|
344
|
+
score -= 20;
|
|
345
|
+
}
|
|
346
|
+
if (ocrResult && !ocrResult.passed) {
|
|
347
|
+
score -= 30;
|
|
348
|
+
}
|
|
349
|
+
score = Math.max(0, Math.min(100, score));
|
|
350
|
+
// Overall pass/fail
|
|
351
|
+
const passed = score >= fullConfig.minQualityScore;
|
|
352
|
+
const result = {
|
|
353
|
+
passed,
|
|
354
|
+
score,
|
|
355
|
+
sharpness: sharpnessResult,
|
|
356
|
+
brightness: brightnessResult,
|
|
357
|
+
ocr: ocrResult,
|
|
358
|
+
failureReasons,
|
|
359
|
+
recommendations,
|
|
360
|
+
};
|
|
361
|
+
logger.info('Quality validation complete', {
|
|
362
|
+
passed,
|
|
363
|
+
score,
|
|
364
|
+
failureReasons: failureReasons.length,
|
|
365
|
+
});
|
|
366
|
+
return result;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Check if quality validation is available
|
|
370
|
+
*/
|
|
371
|
+
export async function isQualityValidationAvailable() {
|
|
372
|
+
const sharp = await initializeSharp();
|
|
373
|
+
const tesseract = await initializeTesseract();
|
|
374
|
+
return {
|
|
375
|
+
sharpAvailable: sharp,
|
|
376
|
+
tesseractAvailable: tesseract,
|
|
377
|
+
fullyAvailable: sharp && tesseract,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Get default quality validation configuration
|
|
382
|
+
*/
|
|
383
|
+
export function getDefaultQualityConfig() {
|
|
384
|
+
return { ...DEFAULT_CONFIG };
|
|
385
|
+
}
|
|
386
|
+
//# sourceMappingURL=quality-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-validator.js","sourceRoot":"","sources":["../../src/utils/quality-validator.ts"],"names":[],"mappings":"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"}
|