Added plan.md with complete architecture for format-agnostic content generation: - Support for Markdown, HTML, Plain Text, JSON formats - New FormatExporter module with neutral data structure - Integration strategy with existing ContentAssembly and ArticleStorage - Bonus features: SEO metadata generation, readability scoring, WordPress Gutenberg format - Implementation roadmap with 4 phases (6h total estimated) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
452 lines
16 KiB
JavaScript
452 lines
16 KiB
JavaScript
// ========================================
|
|
// FICHIER: HumanSimulationLayers.js
|
|
// RESPONSABILITÉ: Stacks prédéfinis Human Simulation
|
|
// Compatible avec architecture modulaire existante
|
|
// ========================================
|
|
|
|
const { logSh } = require('../ErrorReporting');
|
|
const { tracer } = require('../trace');
|
|
const { applyHumanSimulationLayer } = require('./HumanSimulationCore');
|
|
|
|
/**
|
|
* STACKS PRÉDÉFINIS HUMAN SIMULATION
|
|
* Configuration par niveau d'intensité
|
|
*/
|
|
const HUMAN_SIMULATION_STACKS = {
|
|
|
|
// ========================================
|
|
// SIMULATION LÉGÈRE - Pour tests et développement
|
|
// ========================================
|
|
lightSimulation: {
|
|
name: 'lightSimulation',
|
|
description: 'Simulation humaine légère - développement et tests',
|
|
layersCount: 3,
|
|
config: {
|
|
fatigueEnabled: true,
|
|
personalityErrorsEnabled: true,
|
|
temporalStyleEnabled: false, // Désactivé en mode light
|
|
imperfectionIntensity: 0.3, // Faible intensité
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 0.8, // Seuil élevé
|
|
maxModificationsPerElement: 2 // Limité à 2 modifs par élément
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '1-2',
|
|
qualityPreservation: '95%',
|
|
detectionReduction: '10-15%',
|
|
executionTime: '+20%'
|
|
}
|
|
},
|
|
|
|
// ========================================
|
|
// SIMULATION STANDARD - Usage production normal
|
|
// ========================================
|
|
standardSimulation: {
|
|
name: 'standardSimulation',
|
|
description: 'Simulation humaine standard - équilibre performance/qualité',
|
|
layersCount: 3,
|
|
config: {
|
|
fatigueEnabled: true,
|
|
personalityErrorsEnabled: true,
|
|
temporalStyleEnabled: true, // Activé
|
|
imperfectionIntensity: 0.6, // Intensité moyenne
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 0.7, // Seuil normal
|
|
maxModificationsPerElement: 3 // 3 modifs max
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '2-3',
|
|
qualityPreservation: '85%',
|
|
detectionReduction: '25-35%',
|
|
executionTime: '+40%'
|
|
}
|
|
},
|
|
|
|
// ========================================
|
|
// SIMULATION INTENSIVE - Maximum anti-détection
|
|
// ========================================
|
|
heavySimulation: {
|
|
name: 'heavySimulation',
|
|
description: 'Simulation humaine intensive - anti-détection maximale',
|
|
layersCount: 3,
|
|
config: {
|
|
fatigueEnabled: true,
|
|
personalityErrorsEnabled: true,
|
|
temporalStyleEnabled: true,
|
|
imperfectionIntensity: 0.9, // Intensité élevée
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 0.6, // Seuil plus permissif
|
|
maxModificationsPerElement: 5 // Jusqu'à 5 modifs
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '3-5',
|
|
qualityPreservation: '75%',
|
|
detectionReduction: '40-50%',
|
|
executionTime: '+60%'
|
|
}
|
|
},
|
|
|
|
// ========================================
|
|
// SIMULATION ADAPTIVE - Intelligence contextuelle
|
|
// ========================================
|
|
adaptiveSimulation: {
|
|
name: 'adaptiveSimulation',
|
|
description: 'Simulation humaine adaptive - ajustement intelligent selon contexte',
|
|
layersCount: 3,
|
|
config: {
|
|
fatigueEnabled: true,
|
|
personalityErrorsEnabled: true,
|
|
temporalStyleEnabled: true,
|
|
imperfectionIntensity: 'adaptive', // Calculé dynamiquement
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 'adaptive', // Ajusté selon complexité
|
|
maxModificationsPerElement: 'adaptive', // Variable
|
|
adaptiveLogic: true // Flag pour logique adaptive
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '1-4',
|
|
qualityPreservation: '80-90%',
|
|
detectionReduction: '30-45%',
|
|
executionTime: '+45%'
|
|
}
|
|
},
|
|
|
|
// ========================================
|
|
// SIMULATION PERSONNALISÉE - Focus personnalité
|
|
// ========================================
|
|
personalityFocus: {
|
|
name: 'personalityFocus',
|
|
description: 'Focus erreurs personnalité - cohérence maximale',
|
|
layersCount: 2,
|
|
config: {
|
|
fatigueEnabled: false, // Désactivé
|
|
personalityErrorsEnabled: true,
|
|
temporalStyleEnabled: false, // Désactivé
|
|
imperfectionIntensity: 1.0, // Focus sur personnalité
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 0.75,
|
|
maxModificationsPerElement: 3
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '2-3',
|
|
qualityPreservation: '85%',
|
|
detectionReduction: '20-30%',
|
|
executionTime: '+25%'
|
|
}
|
|
},
|
|
|
|
// ========================================
|
|
// SIMULATION TEMPORELLE - Focus variations horaires
|
|
// ========================================
|
|
temporalFocus: {
|
|
name: 'temporalFocus',
|
|
description: 'Focus style temporel - variations selon heure',
|
|
layersCount: 2,
|
|
config: {
|
|
fatigueEnabled: false,
|
|
personalityErrorsEnabled: false,
|
|
temporalStyleEnabled: true, // Focus principal
|
|
imperfectionIntensity: 0.8,
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 0.75,
|
|
maxModificationsPerElement: 3
|
|
},
|
|
expectedImpact: {
|
|
modificationsPerElement: '1-3',
|
|
qualityPreservation: '85%',
|
|
detectionReduction: '15-25%',
|
|
executionTime: '+20%'
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* APPLICATION STACK PRÉDÉFINI
|
|
* @param {object} content - Contenu à simuler
|
|
* @param {string} stackName - Nom du stack
|
|
* @param {object} options - Options additionnelles
|
|
* @returns {object} - Résultat simulation
|
|
*/
|
|
async function applyPredefinedSimulation(content, stackName, options = {}) {
|
|
return await tracer.run(`HumanSimulationLayers.applyPredefinedSimulation(${stackName})`, async () => {
|
|
|
|
const stack = HUMAN_SIMULATION_STACKS[stackName];
|
|
if (!stack) {
|
|
throw new Error(`Stack Human Simulation non trouvé: ${stackName}`);
|
|
}
|
|
|
|
await tracer.annotate({
|
|
stackName,
|
|
stackDescription: stack.description,
|
|
layersCount: stack.layersCount,
|
|
contentElements: Object.keys(content).length
|
|
});
|
|
|
|
logSh(`🧠 APPLICATION STACK: ${stack.name}`, 'INFO');
|
|
logSh(` 📝 ${stack.description}`, 'DEBUG');
|
|
logSh(` ⚙️ ${stack.layersCount} couches actives`, 'DEBUG');
|
|
|
|
try {
|
|
// Configuration fusionnée
|
|
let finalConfig = { ...stack.config, ...options };
|
|
|
|
// ========================================
|
|
// LOGIQUE ADAPTIVE (si applicable)
|
|
// ========================================
|
|
if (stack.config.adaptiveLogic) {
|
|
finalConfig = await applyAdaptiveLogic(content, finalConfig, options);
|
|
logSh(` 🧠 Logique adaptive appliquée`, 'DEBUG');
|
|
}
|
|
|
|
// ========================================
|
|
// APPLICATION SIMULATION PRINCIPALE
|
|
// ========================================
|
|
const simulationOptions = {
|
|
...finalConfig,
|
|
elementIndex: options.elementIndex || 0,
|
|
totalElements: options.totalElements || Object.keys(content).length,
|
|
currentHour: options.currentHour || new Date().getHours(),
|
|
csvData: options.csvData,
|
|
stackName: stack.name
|
|
};
|
|
|
|
const result = await applyHumanSimulationLayer(content, simulationOptions);
|
|
|
|
// ========================================
|
|
// ENRICHISSEMENT RÉSULTAT
|
|
// ========================================
|
|
const enrichedResult = {
|
|
...result,
|
|
stackInfo: {
|
|
name: stack.name,
|
|
description: stack.description,
|
|
layersCount: stack.layersCount,
|
|
expectedImpact: stack.expectedImpact,
|
|
configUsed: finalConfig
|
|
}
|
|
};
|
|
|
|
logSh(`✅ STACK ${stack.name} terminé: ${result.stats.totalModifications} modifications`, 'INFO');
|
|
|
|
await tracer.event('Stack Human Simulation terminé', {
|
|
stackName,
|
|
success: !result.fallback,
|
|
modifications: result.stats.totalModifications,
|
|
qualityScore: result.qualityScore
|
|
});
|
|
|
|
return enrichedResult;
|
|
|
|
} catch (error) {
|
|
logSh(`❌ ERREUR STACK ${stack.name}: ${error.message}`, 'ERROR');
|
|
|
|
await tracer.event('Stack Human Simulation échoué', {
|
|
stackName,
|
|
error: error.message
|
|
});
|
|
|
|
// Fallback gracieux
|
|
return {
|
|
content,
|
|
stats: { fallbackUsed: true, error: error.message },
|
|
fallback: true,
|
|
stackInfo: { name: stack.name, error: error.message }
|
|
};
|
|
}
|
|
|
|
}, { stackName, contentElements: Object.keys(content).length });
|
|
}
|
|
|
|
/**
|
|
* LOGIQUE ADAPTIVE INTELLIGENTE
|
|
* Ajuste la configuration selon le contexte
|
|
*/
|
|
async function applyAdaptiveLogic(content, config, options) {
|
|
logSh('🧠 Application logique adaptive', 'DEBUG');
|
|
|
|
const adaptedConfig = { ...config };
|
|
|
|
// ========================================
|
|
// 1. ANALYSE COMPLEXITÉ CONTENU
|
|
// ========================================
|
|
const totalText = Object.values(content).join(' ');
|
|
const wordCount = totalText.split(/\s+/).length;
|
|
const avgElementLength = wordCount / Object.keys(content).length;
|
|
|
|
// ========================================
|
|
// 2. AJUSTEMENT INTENSITÉ SELON COMPLEXITÉ
|
|
// ========================================
|
|
if (avgElementLength > 200) {
|
|
// Contenu long = intensité réduite pour préserver qualité
|
|
adaptedConfig.imperfectionIntensity = 0.5;
|
|
adaptedConfig.qualityThreshold = 0.8;
|
|
logSh(' 📏 Contenu long détecté: intensité réduite', 'DEBUG');
|
|
} else if (avgElementLength < 50) {
|
|
// Contenu court = intensité augmentée
|
|
adaptedConfig.imperfectionIntensity = 1.0;
|
|
adaptedConfig.qualityThreshold = 0.6;
|
|
logSh(' 📏 Contenu court détecté: intensité augmentée', 'DEBUG');
|
|
} else {
|
|
// Contenu moyen = intensité équilibrée
|
|
adaptedConfig.imperfectionIntensity = 0.7;
|
|
adaptedConfig.qualityThreshold = 0.7;
|
|
}
|
|
|
|
// ========================================
|
|
// 3. AJUSTEMENT SELON PERSONNALITÉ
|
|
// ========================================
|
|
const personality = options.csvData?.personality;
|
|
if (personality) {
|
|
const personalityName = personality.nom.toLowerCase();
|
|
|
|
// Personnalités techniques = moins d'erreurs de personnalité
|
|
if (['marc', 'amara', 'fabrice'].includes(personalityName)) {
|
|
adaptedConfig.imperfectionIntensity *= 0.8;
|
|
logSh(' 🎭 Personnalité technique: intensité erreurs réduite', 'DEBUG');
|
|
}
|
|
|
|
// Personnalités créatives = plus d'erreurs stylistiques
|
|
if (['sophie', 'émilie', 'chloé'].includes(personalityName)) {
|
|
adaptedConfig.imperfectionIntensity *= 1.2;
|
|
logSh(' 🎭 Personnalité créative: intensité erreurs augmentée', 'DEBUG');
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
// 4. AJUSTEMENT SELON HEURE
|
|
// ========================================
|
|
const currentHour = options.currentHour || new Date().getHours();
|
|
|
|
if (currentHour >= 22 || currentHour <= 6) {
|
|
// Nuit = plus de fatigue, moins de complexité
|
|
adaptedConfig.fatigueEnabled = true;
|
|
adaptedConfig.temporalStyleEnabled = true;
|
|
adaptedConfig.imperfectionIntensity *= 1.3;
|
|
logSh(' 🌙 Période nocturne: simulation fatigue renforcée', 'DEBUG');
|
|
} else if (currentHour >= 6 && currentHour <= 10) {
|
|
// Matin = énergie, moins d'erreurs
|
|
adaptedConfig.imperfectionIntensity *= 0.7;
|
|
logSh(' 🌅 Période matinale: intensité réduite', 'DEBUG');
|
|
}
|
|
|
|
// ========================================
|
|
// 5. LIMITATION SÉCURITÉ
|
|
// ========================================
|
|
adaptedConfig.imperfectionIntensity = Math.max(0.2, Math.min(1.5, adaptedConfig.imperfectionIntensity));
|
|
adaptedConfig.qualityThreshold = Math.max(0.5, Math.min(0.9, adaptedConfig.qualityThreshold));
|
|
|
|
// Modifs max adaptées à la taille du contenu
|
|
adaptedConfig.maxModificationsPerElement = Math.min(6, Math.max(1, Math.ceil(avgElementLength / 50)));
|
|
|
|
logSh(` 🎯 Config adaptée: intensité=${adaptedConfig.imperfectionIntensity.toFixed(2)}, seuil=${adaptedConfig.qualityThreshold.toFixed(2)}`, 'DEBUG');
|
|
|
|
return adaptedConfig;
|
|
}
|
|
|
|
/**
|
|
* OBTENIR STACKS DISPONIBLES
|
|
* @returns {array} - Liste des stacks avec métadonnées
|
|
*/
|
|
function getAvailableSimulationStacks() {
|
|
return Object.values(HUMAN_SIMULATION_STACKS).map(stack => ({
|
|
name: stack.name,
|
|
description: stack.description,
|
|
layersCount: stack.layersCount,
|
|
expectedImpact: stack.expectedImpact,
|
|
configPreview: {
|
|
fatigueEnabled: stack.config.fatigueEnabled,
|
|
personalityErrorsEnabled: stack.config.personalityErrorsEnabled,
|
|
temporalStyleEnabled: stack.config.temporalStyleEnabled,
|
|
intensity: stack.config.imperfectionIntensity
|
|
}
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* VALIDATION STACK
|
|
* @param {string} stackName - Nom du stack à valider
|
|
* @returns {object} - Résultat validation
|
|
*/
|
|
function validateSimulationStack(stackName) {
|
|
const stack = HUMAN_SIMULATION_STACKS[stackName];
|
|
|
|
if (!stack) {
|
|
return {
|
|
valid: false,
|
|
error: `Stack '${stackName}' non trouvé`,
|
|
availableStacks: Object.keys(HUMAN_SIMULATION_STACKS)
|
|
};
|
|
}
|
|
|
|
// Validation configuration
|
|
const configIssues = [];
|
|
|
|
if (typeof stack.config.imperfectionIntensity === 'number' &&
|
|
(stack.config.imperfectionIntensity < 0 || stack.config.imperfectionIntensity > 2)) {
|
|
configIssues.push('intensité hors limites (0-2)');
|
|
}
|
|
|
|
if (typeof stack.config.qualityThreshold === 'number' &&
|
|
(stack.config.qualityThreshold < 0.3 || stack.config.qualityThreshold > 1)) {
|
|
configIssues.push('seuil qualité hors limites (0.3-1)');
|
|
}
|
|
|
|
return {
|
|
valid: configIssues.length === 0,
|
|
stack,
|
|
issues: configIssues,
|
|
recommendation: configIssues.length > 0 ?
|
|
'Corriger la configuration avant utilisation' :
|
|
'Stack prêt à utiliser'
|
|
};
|
|
}
|
|
|
|
/**
|
|
* RECOMMANDATION STACK AUTOMATIQUE
|
|
* @param {object} context - Contexte { contentLength, personality, hour, goal }
|
|
* @returns {string} - Nom du stack recommandé
|
|
*/
|
|
function recommendSimulationStack(context = {}) {
|
|
const { contentLength, personality, hour, goal } = context;
|
|
|
|
logSh('🤖 Recommandation stack automatique', 'DEBUG');
|
|
|
|
// Priorité 1: Objectif spécifique
|
|
if (goal === 'development') return 'lightSimulation';
|
|
if (goal === 'maximum_stealth') return 'heavySimulation';
|
|
if (goal === 'personality_focus') return 'personalityFocus';
|
|
if (goal === 'temporal_focus') return 'temporalFocus';
|
|
|
|
// Priorité 2: Complexité contenu
|
|
if (contentLength > 2000) return 'lightSimulation'; // Contenu long = prudent
|
|
if (contentLength < 300) return 'heavySimulation'; // Contenu court = intensif
|
|
|
|
// Priorité 3: Personnalité
|
|
if (personality) {
|
|
const personalityName = personality.toLowerCase();
|
|
if (['marc', 'amara', 'fabrice'].includes(personalityName)) {
|
|
return 'standardSimulation'; // Techniques = équilibré
|
|
}
|
|
if (['sophie', 'chloé', 'émilie'].includes(personalityName)) {
|
|
return 'personalityFocus'; // Créatives = focus personnalité
|
|
}
|
|
}
|
|
|
|
// Priorité 4: Heure
|
|
if (hour >= 22 || hour <= 6) return 'temporalFocus'; // Nuit = focus temporel
|
|
if (hour >= 6 && hour <= 10) return 'lightSimulation'; // Matin = léger
|
|
|
|
// Par défaut: adaptive pour intelligence contextuelle
|
|
logSh(' 🎯 Recommandation: adaptiveSimulation (par défaut)', 'DEBUG');
|
|
return 'adaptiveSimulation';
|
|
}
|
|
|
|
// ============= EXPORTS =============
|
|
module.exports = {
|
|
applyPredefinedSimulation,
|
|
getAvailableSimulationStacks,
|
|
validateSimulationStack,
|
|
recommendSimulationStack,
|
|
applyAdaptiveLogic,
|
|
HUMAN_SIMULATION_STACKS
|
|
}; |