422 lines
15 KiB
JavaScript
422 lines
15 KiB
JavaScript
// ========================================
|
|
// MAIN MODULAIRE - PIPELINE ARCHITECTURALE MODERNE
|
|
// Responsabilité: Orchestration workflow avec architecture modulaire complète
|
|
// Usage: node main_modulaire.js [rowNumber] [stackType]
|
|
// ========================================
|
|
|
|
const { logSh } = require('./lib/ErrorReporting');
|
|
const { tracer } = require('./lib/trace');
|
|
|
|
// Imports pipeline de base
|
|
const { readInstructionsData, selectPersonalityWithAI, getPersonalities } = require('./lib/BrainConfig');
|
|
const { extractElementsFromXML } = require('./lib/ElementExtraction');
|
|
const { generateMissingKeywords } = require('./lib/MissingKeywords');
|
|
const { generateDirectElements } = require('./lib/generation/DirectGeneration');
|
|
const { injectContentIntoTemplate } = require('./lib/ContentAssembly');
|
|
const { compileAndStoreArticle } = require('./lib/ArticleStorage');
|
|
|
|
// Imports modules modulaires
|
|
const { applySelectiveLayer } = require('./lib/selective-enhancement/SelectiveCore');
|
|
const {
|
|
applyPredefinedStack,
|
|
applyAdaptiveLayers,
|
|
getAvailableStacks
|
|
} = require('./lib/selective-enhancement/SelectiveLayers');
|
|
const {
|
|
applyAdversarialLayer
|
|
} = require('./lib/adversarial-generation/AdversarialCore');
|
|
const {
|
|
applyPredefinedStack: applyAdversarialStack
|
|
} = require('./lib/adversarial-generation/AdversarialLayers');
|
|
|
|
/**
|
|
* WORKFLOW MODULAIRE PRINCIPAL
|
|
*/
|
|
async function handleModularWorkflow(config = {}) {
|
|
return await tracer.run('MainModulaire.handleModularWorkflow()', async () => {
|
|
const {
|
|
rowNumber = 2,
|
|
selectiveStack = 'standardEnhancement', // lightEnhancement, standardEnhancement, fullEnhancement, personalityFocus, fluidityFocus, adaptive
|
|
adversarialMode = 'light', // none, light, standard, heavy, adaptive
|
|
source = 'main_modulaire'
|
|
} = config;
|
|
|
|
await tracer.annotate({
|
|
modularWorkflow: true,
|
|
rowNumber,
|
|
selectiveStack,
|
|
adversarialMode,
|
|
source
|
|
});
|
|
|
|
const startTime = Date.now();
|
|
logSh(`🚀 WORKFLOW MODULAIRE DÉMARRÉ`, 'INFO');
|
|
logSh(` 📊 Ligne: ${rowNumber} | Selective: ${selectiveStack} | Adversarial: ${adversarialMode}`, 'INFO');
|
|
|
|
try {
|
|
// ========================================
|
|
// PHASE 1: PRÉPARATION DONNÉES
|
|
// ========================================
|
|
logSh(`📋 PHASE 1: Préparation données`, 'INFO');
|
|
|
|
const csvData = await readInstructionsData(rowNumber);
|
|
if (!csvData) {
|
|
throw new Error(`Impossible de lire les données ligne ${rowNumber}`);
|
|
}
|
|
|
|
const personalities = await getPersonalities();
|
|
const selectedPersonality = await selectPersonalityWithAI(
|
|
csvData.mc0,
|
|
csvData.t0,
|
|
personalities
|
|
);
|
|
|
|
csvData.personality = selectedPersonality;
|
|
|
|
logSh(` ✅ Données: ${csvData.mc0} | Personnalité: ${selectedPersonality.nom}`, 'DEBUG');
|
|
|
|
// ========================================
|
|
// PHASE 2: EXTRACTION ÉLÉMENTS
|
|
// ========================================
|
|
logSh(`📝 PHASE 2: Extraction éléments XML`, 'INFO');
|
|
|
|
const elements = await extractElementsFromXML(csvData.xmlTemplate);
|
|
logSh(` ✅ ${Object.keys(elements).length} éléments extraits`, 'DEBUG');
|
|
|
|
// ========================================
|
|
// PHASE 3: GÉNÉRATION MOTS-CLÉS MANQUANTS
|
|
// ========================================
|
|
logSh(`🔍 PHASE 3: Génération mots-clés manquants`, 'INFO');
|
|
|
|
const enhancedCsvData = await generateMissingKeywords(csvData);
|
|
logSh(` ✅ Mots-clés complétés`, 'DEBUG');
|
|
|
|
// ========================================
|
|
// PHASE 4: GÉNÉRATION CONTENU DE BASE
|
|
// ========================================
|
|
logSh(`💫 PHASE 4: Génération contenu de base`, 'INFO');
|
|
|
|
const generatedContent = await generateDirectElements(elements, enhancedCsvData, {
|
|
source: 'main_modulaire',
|
|
usePersonality: true
|
|
});
|
|
|
|
logSh(` ✅ ${Object.keys(generatedContent).length} éléments générés`, 'DEBUG');
|
|
|
|
// ========================================
|
|
// PHASE 5: SELECTIVE ENHANCEMENT MODULAIRE
|
|
// ========================================
|
|
logSh(`🔧 PHASE 5: Selective Enhancement Modulaire (${selectiveStack})`, 'INFO');
|
|
|
|
let selectiveResult;
|
|
|
|
switch (selectiveStack) {
|
|
case 'adaptive':
|
|
selectiveResult = await applyAdaptiveLayers(generatedContent, {
|
|
maxIntensity: 1.1,
|
|
analysisThreshold: 0.3,
|
|
csvData: enhancedCsvData
|
|
});
|
|
break;
|
|
|
|
case 'technical':
|
|
case 'transitions':
|
|
case 'style':
|
|
selectiveResult = await applySelectiveLayer(generatedContent, {
|
|
layerType: selectiveStack,
|
|
llmProvider: 'auto',
|
|
intensity: 1.0,
|
|
csvData: enhancedCsvData
|
|
});
|
|
break;
|
|
|
|
default:
|
|
// Stack prédéfini
|
|
selectiveResult = await applyPredefinedStack(generatedContent, selectiveStack, {
|
|
csvData: enhancedCsvData,
|
|
analysisMode: true
|
|
});
|
|
}
|
|
|
|
const enhancedContent = selectiveResult.content;
|
|
|
|
logSh(` ✅ Selective: ${selectiveResult.stats.elementsEnhanced || selectiveResult.stats.totalModifications || 0} améliorations`, 'INFO');
|
|
|
|
// ========================================
|
|
// PHASE 6: ADVERSARIAL ENHANCEMENT (OPTIONNEL)
|
|
// ========================================
|
|
let finalContent = enhancedContent;
|
|
let adversarialStats = null;
|
|
|
|
if (adversarialMode !== 'none') {
|
|
logSh(`🎯 PHASE 6: Adversarial Enhancement (${adversarialMode})`, 'INFO');
|
|
|
|
let adversarialResult;
|
|
|
|
switch (adversarialMode) {
|
|
case 'adaptive':
|
|
// Utiliser adversarial adaptatif
|
|
adversarialResult = await applyAdversarialLayer(enhancedContent, {
|
|
detectorTarget: 'general',
|
|
method: 'hybrid',
|
|
intensity: 0.8,
|
|
analysisMode: true
|
|
});
|
|
break;
|
|
|
|
case 'light':
|
|
case 'standard':
|
|
case 'heavy':
|
|
// Utiliser stack adversarial prédéfini
|
|
const stackMapping = {
|
|
light: 'lightDefense',
|
|
standard: 'standardDefense',
|
|
heavy: 'heavyDefense'
|
|
};
|
|
|
|
adversarialResult = await applyAdversarialStack(enhancedContent, stackMapping[adversarialMode], {
|
|
csvData: enhancedCsvData
|
|
});
|
|
break;
|
|
}
|
|
|
|
if (adversarialResult && !adversarialResult.fallback) {
|
|
finalContent = adversarialResult.content;
|
|
adversarialStats = adversarialResult.stats;
|
|
|
|
logSh(` ✅ Adversarial: ${adversarialStats.elementsModified || adversarialStats.totalModifications || 0} modifications`, 'INFO');
|
|
} else {
|
|
logSh(` ⚠️ Adversarial fallback: contenu selective préservé`, 'WARNING');
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
// PHASE 7: ASSEMBLAGE ET STOCKAGE
|
|
// ========================================
|
|
logSh(`🔗 PHASE 7: Assemblage et stockage`, 'INFO');
|
|
|
|
const assembledContent = await injectContentIntoTemplate(finalContent, enhancedCsvData.xmlTemplate);
|
|
|
|
const storageResult = await compileAndStoreArticle(assembledContent, {
|
|
...enhancedCsvData,
|
|
source: `${source}_${selectiveStack}${adversarialMode !== 'none' ? `_${adversarialMode}` : ''}`
|
|
});
|
|
|
|
logSh(` ✅ Stocké: ${storageResult.compiledLength} caractères`, 'DEBUG');
|
|
|
|
// ========================================
|
|
// RÉSUMÉ FINAL
|
|
// ========================================
|
|
const totalDuration = Date.now() - startTime;
|
|
const finalStats = {
|
|
rowNumber,
|
|
selectiveStack,
|
|
adversarialMode,
|
|
totalDuration,
|
|
elementsGenerated: Object.keys(generatedContent).length,
|
|
selectiveEnhancements: selectiveResult.stats.elementsEnhanced || selectiveResult.stats.totalModifications || 0,
|
|
adversarialModifications: adversarialStats?.elementsModified || adversarialStats?.totalModifications || 0,
|
|
finalLength: storageResult.compiledLength,
|
|
personality: selectedPersonality.nom,
|
|
source
|
|
};
|
|
|
|
logSh(`✅ WORKFLOW MODULAIRE TERMINÉ (${totalDuration}ms)`, 'INFO');
|
|
logSh(` 📊 ${finalStats.elementsGenerated} générés | ${finalStats.selectiveEnhancements} selective | ${finalStats.adversarialModifications} adversarial`, 'INFO');
|
|
logSh(` 🎭 Personnalité: ${finalStats.personality} | Taille finale: ${finalStats.finalLength} chars`, 'INFO');
|
|
|
|
await tracer.event('Workflow modulaire terminé', finalStats);
|
|
|
|
return {
|
|
success: true,
|
|
stats: finalStats,
|
|
content: finalContent,
|
|
assembledContent,
|
|
storageResult,
|
|
selectiveResult,
|
|
adversarialResult: adversarialStats ? { stats: adversarialStats } : null
|
|
};
|
|
|
|
} catch (error) {
|
|
const duration = Date.now() - startTime;
|
|
logSh(`❌ WORKFLOW MODULAIRE ÉCHOUÉ après ${duration}ms: ${error.message}`, 'ERROR');
|
|
logSh(`Stack trace: ${error.stack}`, 'ERROR');
|
|
|
|
await tracer.event('Workflow modulaire échoué', {
|
|
error: error.message,
|
|
duration,
|
|
rowNumber,
|
|
selectiveStack,
|
|
adversarialMode
|
|
});
|
|
|
|
throw error;
|
|
}
|
|
}, { config });
|
|
}
|
|
|
|
/**
|
|
* BENCHMARK COMPARATIF STACKS
|
|
*/
|
|
async function benchmarkStacks(rowNumber = 2) {
|
|
console.log('\n⚡ === BENCHMARK STACKS MODULAIRES ===\n');
|
|
|
|
const stacks = getAvailableStacks();
|
|
const adversarialModes = ['none', 'light', 'standard'];
|
|
|
|
const results = [];
|
|
|
|
for (const stack of stacks.slice(0, 3)) { // Tester 3 stacks principaux
|
|
for (const advMode of adversarialModes.slice(0, 2)) { // 2 modes adversarial
|
|
|
|
console.log(`🧪 Test: ${stack.name} + adversarial ${advMode}`);
|
|
|
|
try {
|
|
const startTime = Date.now();
|
|
|
|
const result = await handleModularWorkflow({
|
|
rowNumber,
|
|
selectiveStack: stack.name,
|
|
adversarialMode: advMode,
|
|
source: 'benchmark'
|
|
});
|
|
|
|
const duration = Date.now() - startTime;
|
|
|
|
results.push({
|
|
stack: stack.name,
|
|
adversarial: advMode,
|
|
duration,
|
|
success: true,
|
|
selectiveEnhancements: result.stats.selectiveEnhancements,
|
|
adversarialModifications: result.stats.adversarialModifications,
|
|
finalLength: result.stats.finalLength
|
|
});
|
|
|
|
console.log(` ✅ ${duration}ms | ${result.stats.selectiveEnhancements} selective | ${result.stats.adversarialModifications} adversarial`);
|
|
|
|
} catch (error) {
|
|
results.push({
|
|
stack: stack.name,
|
|
adversarial: advMode,
|
|
success: false,
|
|
error: error.message
|
|
});
|
|
|
|
console.log(` ❌ Échoué: ${error.message}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Résumé benchmark
|
|
console.log('\n📊 RÉSUMÉ BENCHMARK:');
|
|
|
|
const successful = results.filter(r => r.success);
|
|
if (successful.length > 0) {
|
|
const avgDuration = successful.reduce((sum, r) => sum + r.duration, 0) / successful.length;
|
|
const bestPerf = successful.reduce((best, r) => r.duration < best.duration ? r : best);
|
|
const mostEnhancements = successful.reduce((best, r) =>
|
|
(r.selectiveEnhancements + r.adversarialModifications) > (best.selectiveEnhancements + best.adversarialModifications) ? r : best
|
|
);
|
|
|
|
console.log(` ⚡ Durée moyenne: ${avgDuration.toFixed(0)}ms`);
|
|
console.log(` 🏆 Meilleure perf: ${bestPerf.stack} + ${bestPerf.adversarial} (${bestPerf.duration}ms)`);
|
|
console.log(` 🔥 Plus d'améliorations: ${mostEnhancements.stack} + ${mostEnhancements.adversarial} (${mostEnhancements.selectiveEnhancements + mostEnhancements.adversarialModifications})`);
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* INTERFACE LIGNE DE COMMANDE
|
|
*/
|
|
async function main() {
|
|
const args = process.argv.slice(2);
|
|
const command = args[0] || 'workflow';
|
|
|
|
try {
|
|
switch (command) {
|
|
case 'workflow':
|
|
const rowNumber = parseInt(args[1]) || 2;
|
|
const selectiveStack = args[2] || 'standardEnhancement';
|
|
const adversarialMode = args[3] || 'light';
|
|
|
|
console.log(`\n🚀 Exécution workflow modulaire:`);
|
|
console.log(` 📊 Ligne: ${rowNumber}`);
|
|
console.log(` 🔧 Stack selective: ${selectiveStack}`);
|
|
console.log(` 🎯 Mode adversarial: ${adversarialMode}`);
|
|
|
|
const result = await handleModularWorkflow({
|
|
rowNumber,
|
|
selectiveStack,
|
|
adversarialMode
|
|
});
|
|
|
|
console.log('\n✅ WORKFLOW MODULAIRE RÉUSSI');
|
|
console.log(`📈 Stats: ${JSON.stringify(result.stats, null, 2)}`);
|
|
break;
|
|
|
|
case 'benchmark':
|
|
const benchRowNumber = parseInt(args[1]) || 2;
|
|
|
|
console.log(`\n⚡ Benchmark stacks (ligne ${benchRowNumber})`);
|
|
const benchResults = await benchmarkStacks(benchRowNumber);
|
|
|
|
console.log('\n📊 Résultats complets:');
|
|
console.table(benchResults);
|
|
break;
|
|
|
|
case 'stacks':
|
|
console.log('\n📦 STACKS SELECTIVE DISPONIBLES:');
|
|
const availableStacks = getAvailableStacks();
|
|
availableStacks.forEach(stack => {
|
|
console.log(`\n 🔧 ${stack.name}:`);
|
|
console.log(` 📝 ${stack.description}`);
|
|
console.log(` 📊 ${stack.layersCount} couches`);
|
|
console.log(` 🎯 Couches: ${stack.layers ? stack.layers.map(l => `${l.type}(${l.llm})`).join(' → ') : 'N/A'}`);
|
|
});
|
|
|
|
console.log('\n🎯 MODES ADVERSARIAL DISPONIBLES:');
|
|
console.log(' - none: Pas d\'adversarial');
|
|
console.log(' - light: Défense légère');
|
|
console.log(' - standard: Défense standard');
|
|
console.log(' - heavy: Défense intensive');
|
|
console.log(' - adaptive: Adaptatif intelligent');
|
|
break;
|
|
|
|
case 'help':
|
|
default:
|
|
console.log('\n🔧 === MAIN MODULAIRE - USAGE ===');
|
|
console.log('\nCommandes disponibles:');
|
|
console.log(' workflow [ligne] [stack] [adversarial] - Exécuter workflow complet');
|
|
console.log(' benchmark [ligne] - Benchmark stacks');
|
|
console.log(' stacks - Lister stacks disponibles');
|
|
console.log(' help - Afficher cette aide');
|
|
console.log('\nExemples:');
|
|
console.log(' node main_modulaire.js workflow 2 fullEnhancement standard');
|
|
console.log(' node main_modulaire.js workflow 3 adaptive light');
|
|
console.log(' node main_modulaire.js benchmark 2');
|
|
console.log(' node main_modulaire.js stacks');
|
|
break;
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('\n❌ ERREUR MAIN MODULAIRE:', error.message);
|
|
console.error(error.stack);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Export pour usage programmatique
|
|
module.exports = {
|
|
handleModularWorkflow,
|
|
benchmarkStacks
|
|
};
|
|
|
|
// Exécution CLI si appelé directement
|
|
if (require.main === module) {
|
|
main().catch(error => {
|
|
console.error('❌ ERREUR FATALE:', error.message);
|
|
process.exit(1);
|
|
});
|
|
} |