// ======================================== // 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); }); }