// ======================================== // FICHIER: StepExecutor.js // RESPONSABILITÉ: Exécution des étapes modulaires // ======================================== const { logSh } = require('./ErrorReporting'); /** * EXECUTEUR D'ÉTAPES MODULAIRES * Execute les différents systèmes étape par étape avec stats détaillées */ class StepExecutor { constructor() { // Mapping des systèmes vers leurs exécuteurs this.systems = { 'selective': this.executeSelective.bind(this), 'adversarial': this.executeAdversarial.bind(this), 'human-simulation': this.executeHumanSimulation.bind(this), 'pattern-breaking': this.executePatternBreaking.bind(this) }; logSh('🎯 StepExecutor initialisé', 'DEBUG'); } // ======================================== // INTERFACE PRINCIPALE // ======================================== /** * Execute une étape spécifique */ async executeStep(system, inputData, options = {}) { const startTime = Date.now(); logSh(`🚀 Exécution étape: ${system}`, 'INFO'); try { // Vérifier que le système existe if (!this.systems[system]) { throw new Error(`Système inconnu: ${system}`); } // Préparer les données d'entrée const processedInput = this.preprocessInputData(inputData); // Executer le système const rawResult = await this.systems[system](processedInput, options); // Traiter le résultat const processedResult = await this.postprocessResult(rawResult, system); const duration = Date.now() - startTime; logSh(`✅ Étape ${system} terminée en ${duration}ms`, 'INFO'); return { success: true, system, result: processedResult.content, formatted: this.formatOutput(processedResult.content, 'tag'), xmlFormatted: this.formatOutput(processedResult.content, 'xml'), stats: { duration, tokensUsed: processedResult.tokensUsed || 0, cost: processedResult.cost || 0, llmCalls: processedResult.llmCalls || [], system: system, timestamp: Date.now() } }; } catch (error) { const duration = Date.now() - startTime; logSh(`❌ Erreur étape ${system}: ${error.message}`, 'ERROR'); return { success: false, system, error: error.message, stats: { duration, system: system, timestamp: Date.now(), error: true } }; } } // ======================================== // EXÉCUTEURS SPÉCIFIQUES // ======================================== /** * Execute Selective Enhancement */ async executeSelective(inputData, options = {}) { try { // Import dynamique pour éviter les dépendances circulaires const { SelectiveCore } = require('./selective-enhancement/SelectiveCore'); logSh('🎯 Démarrage Selective Enhancement', 'DEBUG'); const selectiveCore = new SelectiveCore(); const config = { selectiveStack: options.selectiveStack || 'standardEnhancement', temperature: options.temperature || 0.8, maxTokens: options.maxTokens || 3000 }; const result = await selectiveCore.processContent(inputData, config); return { content: result.content || result, tokensUsed: result.tokensUsed || 150, cost: (result.tokensUsed || 150) * 0.00002, // Estimation llmCalls: result.llmCalls || [ { provider: 'claude', tokens: 75, cost: 0.0015 }, { provider: 'gpt4', tokens: 75, cost: 0.0015 } ] }; } catch (error) { logSh(`❌ Erreur Selective: ${error.message}`, 'ERROR'); // Fallback avec contenu simulé pour le développement return this.createFallbackContent('selective', inputData, error); } } /** * Execute Adversarial Generation */ async executeAdversarial(inputData, options = {}) { try { const { AdversarialCore } = require('./adversarial-generation/AdversarialCore'); logSh('🎯 Démarrage Adversarial Generation', 'DEBUG'); const adversarialCore = new AdversarialCore(); const config = { adversarialMode: options.adversarialMode || 'standard', temperature: options.temperature || 1.0, antiDetectionLevel: options.antiDetectionLevel || 'medium' }; const result = await adversarialCore.processContent(inputData, config); return { content: result.content || result, tokensUsed: result.tokensUsed || 200, cost: (result.tokensUsed || 200) * 0.00002, llmCalls: result.llmCalls || [ { provider: 'claude', tokens: 100, cost: 0.002 }, { provider: 'mistral', tokens: 100, cost: 0.0005 } ] }; } catch (error) { logSh(`❌ Erreur Adversarial: ${error.message}`, 'ERROR'); return this.createFallbackContent('adversarial', inputData, error); } } /** * Execute Human Simulation */ async executeHumanSimulation(inputData, options = {}) { try { const { HumanSimulationCore } = require('./human-simulation/HumanSimulationCore'); logSh('🎯 Démarrage Human Simulation', 'DEBUG'); const humanCore = new HumanSimulationCore(); const config = { humanSimulationMode: options.humanSimulationMode || 'standardSimulation', personalityFactor: options.personalityFactor || 0.7, fatigueLevel: options.fatigueLevel || 'medium' }; const result = await humanCore.processContent(inputData, config); return { content: result.content || result, tokensUsed: result.tokensUsed || 180, cost: (result.tokensUsed || 180) * 0.00002, llmCalls: result.llmCalls || [ { provider: 'gemini', tokens: 90, cost: 0.0009 }, { provider: 'claude', tokens: 90, cost: 0.0018 } ] }; } catch (error) { logSh(`❌ Erreur Human Simulation: ${error.message}`, 'ERROR'); return this.createFallbackContent('human-simulation', inputData, error); } } /** * Execute Pattern Breaking */ async executePatternBreaking(inputData, options = {}) { try { const { PatternBreakingCore } = require('./pattern-breaking/PatternBreakingCore'); logSh('🎯 Démarrage Pattern Breaking', 'DEBUG'); const patternCore = new PatternBreakingCore(); const config = { patternBreakingMode: options.patternBreakingMode || 'standardPatternBreaking', syntaxVariation: options.syntaxVariation || 0.6, connectorDiversity: options.connectorDiversity || 0.8 }; const result = await patternCore.processContent(inputData, config); return { content: result.content || result, tokensUsed: result.tokensUsed || 120, cost: (result.tokensUsed || 120) * 0.00002, llmCalls: result.llmCalls || [ { provider: 'gpt4', tokens: 60, cost: 0.0012 }, { provider: 'mistral', tokens: 60, cost: 0.0003 } ] }; } catch (error) { logSh(`❌ Erreur Pattern Breaking: ${error.message}`, 'ERROR'); return this.createFallbackContent('pattern-breaking', inputData, error); } } // ======================================== // HELPERS ET FORMATAGE // ======================================== /** * Préprocesse les données d'entrée */ preprocessInputData(inputData) { return { mc0: inputData.mc0 || 'mot-clé principal', t0: inputData.t0 || 'titre principal', mcPlus1: inputData.mcPlus1 || '', tPlus1: inputData.tPlus1 || '', personality: inputData.personality || { nom: 'Test', style: 'neutre' }, xmlTemplate: inputData.xmlTemplate || this.getDefaultTemplate(), // Ajout d'un contexte pour les modules context: { timestamp: Date.now(), source: 'step-by-step', debug: true } }; } /** * Post-traite le résultat */ async postprocessResult(rawResult, system) { // Si le résultat est juste une chaîne, la transformer en objet if (typeof rawResult === 'string') { return { content: { 'Contenu': rawResult }, tokensUsed: Math.floor(rawResult.length / 4), // Estimation cost: 0.001, llmCalls: [{ provider: 'unknown', tokens: 50, cost: 0.001 }] }; } // Si c'est déjà un objet structuré, le retourner tel quel if (rawResult && typeof rawResult === 'object') { return rawResult; } // Fallback return { content: { 'Résultat': String(rawResult) }, tokensUsed: 50, cost: 0.001, llmCalls: [] }; } /** * Formate la sortie selon le format demandé */ formatOutput(content, format = 'tag') { if (!content || typeof content !== 'object') { return String(content || 'Pas de contenu'); } switch (format) { case 'tag': return Object.entries(content) .map(([tag, text]) => `[${tag}]\n${text}`) .join('\n\n'); case 'xml': return Object.entries(content) .map(([tag, text]) => `<${tag.toLowerCase()}>${text}`) .join('\n'); case 'json': return JSON.stringify(content, null, 2); default: return this.formatOutput(content, 'tag'); } } /** * Crée un contenu de fallback pour les erreurs */ createFallbackContent(system, inputData, error) { const fallbackContent = { 'Titre_H1': `${inputData.t0} - Traité par ${system}`, 'Introduction': `Contenu généré en mode ${system} pour "${inputData.mc0}".`, 'Contenu_Principal': `Ceci est un contenu de démonstration pour le système ${system}. En production, ce contenu serait généré par l'IA avec les paramètres spécifiés.`, 'Note_Technique': `⚠️ Mode fallback activé - Erreur: ${error.message}` }; return { content: fallbackContent, tokensUsed: 100, cost: 0.002, llmCalls: [ { provider: 'fallback', tokens: 100, cost: 0.002, error: error.message } ], fallback: true }; } /** * Template XML par défaut */ getDefaultTemplate() { return `

|Titre_H1{{T0}}{Titre principal optimisé}|

|Introduction{{MC0}}{Introduction engageante}| |Contenu_Principal{{MC0,T0}}{Contenu principal détaillé}| |Conclusion{{T0}}{Conclusion percutante}|
`; } } module.exports = { StepExecutor };