298 lines
11 KiB
JavaScript
298 lines
11 KiB
JavaScript
// ========================================
|
|
// FICHIER: HumanSimulationCore.js
|
|
// RESPONSABILITÉ: Orchestrateur principal Human Simulation
|
|
// Niveau 5: Temporal & Personality Injection
|
|
// ========================================
|
|
|
|
const { logSh } = require('../ErrorReporting');
|
|
const { tracer } = require('../trace');
|
|
const { calculateFatigue, injectFatigueMarkers, getFatigueProfile } = require('./FatiguePatterns');
|
|
const { injectPersonalityErrors, getPersonalityErrorPatterns } = require('./PersonalityErrors');
|
|
const { applyTemporalStyle, getTemporalStyle } = require('./TemporalStyles');
|
|
const {
|
|
analyzeContentComplexity,
|
|
calculateReadabilityScore,
|
|
preserveKeywords,
|
|
validateSimulationQuality
|
|
} = require('./HumanSimulationUtils');
|
|
|
|
/**
|
|
* CONFIGURATION PAR DÉFAUT
|
|
*/
|
|
const DEFAULT_CONFIG = {
|
|
fatigueEnabled: true,
|
|
personalityErrorsEnabled: true,
|
|
temporalStyleEnabled: true,
|
|
imperfectionIntensity: 0.8, // FIXÉ: Plus d'intensité (était 0.3)
|
|
naturalRepetitions: true,
|
|
qualityThreshold: 0.4, // FIXÉ: Seuil plus bas (était 0.7)
|
|
maxModificationsPerElement: 5 // FIXÉ: Plus de modifs possibles (était 3)
|
|
};
|
|
|
|
/**
|
|
* ORCHESTRATEUR PRINCIPAL - Human Simulation Layer
|
|
* @param {object} content - Contenu généré à simuler
|
|
* @param {object} options - Options de simulation
|
|
* @returns {object} - { content, stats, fallback }
|
|
*/
|
|
async function applyHumanSimulationLayer(content, options = {}) {
|
|
return await tracer.run('HumanSimulationCore.applyHumanSimulationLayer()', async () => {
|
|
const startTime = Date.now();
|
|
|
|
await tracer.annotate({
|
|
contentKeys: Object.keys(content).length,
|
|
elementIndex: options.elementIndex,
|
|
totalElements: options.totalElements,
|
|
currentHour: options.currentHour,
|
|
personality: options.csvData?.personality?.nom
|
|
});
|
|
|
|
logSh(`🧠 HUMAN SIMULATION - Début traitement`, 'INFO');
|
|
logSh(` 📊 ${Object.keys(content).length} éléments | Position: ${options.elementIndex}/${options.totalElements}`, 'DEBUG');
|
|
|
|
try {
|
|
// Configuration fusionnée
|
|
const config = { ...DEFAULT_CONFIG, ...options };
|
|
|
|
// Stats de simulation
|
|
const simulationStats = {
|
|
elementsProcessed: 0,
|
|
fatigueModifications: 0,
|
|
personalityModifications: 0,
|
|
temporalModifications: 0,
|
|
totalModifications: 0,
|
|
qualityScore: 0,
|
|
fallbackUsed: false
|
|
};
|
|
|
|
// Contenu simulé
|
|
let simulatedContent = { ...content };
|
|
|
|
// ========================================
|
|
// 1. ANALYSE CONTEXTE GLOBAL
|
|
// ========================================
|
|
const globalContext = await analyzeGlobalContext(content, config);
|
|
logSh(` 🔍 Contexte: fatigue=${globalContext.fatigueLevel.toFixed(2)}, heure=${globalContext.currentHour}h, personnalité=${globalContext.personalityName}`, 'DEBUG');
|
|
|
|
// ========================================
|
|
// 2. TRAITEMENT PAR ÉLÉMENT
|
|
// ========================================
|
|
for (const [elementKey, elementContent] of Object.entries(content)) {
|
|
await tracer.run(`HumanSimulation.processElement(${elementKey})`, async () => {
|
|
|
|
logSh(` 🎯 Traitement élément: ${elementKey}`, 'DEBUG');
|
|
|
|
let processedContent = elementContent;
|
|
let elementModifications = 0;
|
|
|
|
try {
|
|
// 2a. Simulation Fatigue Cognitive
|
|
if (config.fatigueEnabled && globalContext.fatigueLevel > 0.1) { // FIXÉ: Seuil plus bas (était 0.3)
|
|
const fatigueResult = await applyFatigueSimulation(processedContent, globalContext, config);
|
|
processedContent = fatigueResult.content;
|
|
elementModifications += fatigueResult.modifications;
|
|
simulationStats.fatigueModifications += fatigueResult.modifications;
|
|
|
|
logSh(` 💤 Fatigue: ${fatigueResult.modifications} modifications (niveau: ${globalContext.fatigueLevel.toFixed(2)})`, 'DEBUG');
|
|
}
|
|
|
|
// 2b. Erreurs Personnalité
|
|
if (config.personalityErrorsEnabled && globalContext.personalityProfile) {
|
|
const personalityResult = await applyPersonalitySimulation(processedContent, globalContext, config);
|
|
processedContent = personalityResult.content;
|
|
elementModifications += personalityResult.modifications;
|
|
simulationStats.personalityModifications += personalityResult.modifications;
|
|
|
|
logSh(` 🎭 Personnalité: ${personalityResult.modifications} erreurs injectées`, 'DEBUG');
|
|
}
|
|
|
|
// 2c. Style Temporel
|
|
if (config.temporalStyleEnabled && globalContext.temporalStyle) {
|
|
const temporalResult = await applyTemporalSimulation(processedContent, globalContext, config);
|
|
processedContent = temporalResult.content;
|
|
elementModifications += temporalResult.modifications;
|
|
simulationStats.temporalModifications += temporalResult.modifications;
|
|
|
|
logSh(` ⏰ Temporel: ${temporalResult.modifications} ajustements (${globalContext.temporalStyle.period})`, 'DEBUG');
|
|
}
|
|
|
|
// 2d. Validation Qualité
|
|
const qualityCheck = validateSimulationQuality(elementContent, processedContent, config.qualityThreshold);
|
|
|
|
if (qualityCheck.acceptable) {
|
|
simulatedContent[elementKey] = processedContent;
|
|
simulationStats.elementsProcessed++;
|
|
simulationStats.totalModifications += elementModifications;
|
|
|
|
logSh(` ✅ Élément simulé: ${elementModifications} modifications totales`, 'DEBUG');
|
|
} else {
|
|
// Fallback: garder contenu original
|
|
simulatedContent[elementKey] = elementContent;
|
|
simulationStats.fallbackUsed = true;
|
|
|
|
logSh(` ⚠️ Qualité insuffisante, fallback vers contenu original`, 'WARNING');
|
|
}
|
|
|
|
} catch (elementError) {
|
|
logSh(` ❌ Erreur simulation élément ${elementKey}: ${elementError.message}`, 'WARNING');
|
|
simulatedContent[elementKey] = elementContent; // Fallback
|
|
simulationStats.fallbackUsed = true;
|
|
}
|
|
|
|
}, { elementKey, originalLength: elementContent?.length });
|
|
}
|
|
|
|
// ========================================
|
|
// 3. CALCUL SCORE QUALITÉ GLOBAL
|
|
// ========================================
|
|
simulationStats.qualityScore = calculateGlobalQualityScore(content, simulatedContent);
|
|
|
|
// ========================================
|
|
// 4. RÉSULTATS FINAUX
|
|
// ========================================
|
|
const duration = Date.now() - startTime;
|
|
const success = simulationStats.elementsProcessed > 0 && !simulationStats.fallbackUsed;
|
|
|
|
logSh(`🧠 HUMAN SIMULATION - Terminé (${duration}ms)`, 'INFO');
|
|
logSh(` ✅ ${simulationStats.elementsProcessed}/${Object.keys(content).length} éléments simulés`, 'INFO');
|
|
logSh(` 📊 ${simulationStats.fatigueModifications} fatigue | ${simulationStats.personalityModifications} personnalité | ${simulationStats.temporalModifications} temporel`, 'INFO');
|
|
logSh(` 🎯 Score qualité: ${simulationStats.qualityScore.toFixed(2)} | Fallback: ${simulationStats.fallbackUsed ? 'OUI' : 'NON'}`, 'INFO');
|
|
|
|
await tracer.event('Human Simulation terminée', {
|
|
success,
|
|
duration,
|
|
stats: simulationStats
|
|
});
|
|
|
|
return {
|
|
content: simulatedContent,
|
|
stats: simulationStats,
|
|
fallback: simulationStats.fallbackUsed,
|
|
qualityScore: simulationStats.qualityScore,
|
|
duration
|
|
};
|
|
|
|
} catch (error) {
|
|
const duration = Date.now() - startTime;
|
|
logSh(`❌ HUMAN SIMULATION ÉCHOUÉE (${duration}ms): ${error.message}`, 'ERROR');
|
|
|
|
await tracer.event('Human Simulation échouée', {
|
|
error: error.message,
|
|
duration,
|
|
contentKeys: Object.keys(content).length
|
|
});
|
|
|
|
// Fallback complet
|
|
return {
|
|
content,
|
|
stats: { fallbackUsed: true, error: error.message },
|
|
fallback: true,
|
|
qualityScore: 0,
|
|
duration
|
|
};
|
|
}
|
|
|
|
}, {
|
|
contentElements: Object.keys(content).length,
|
|
elementIndex: options.elementIndex,
|
|
personality: options.csvData?.personality?.nom
|
|
});
|
|
}
|
|
|
|
/**
|
|
* ANALYSE CONTEXTE GLOBAL
|
|
*/
|
|
async function analyzeGlobalContext(content, config) {
|
|
const elementIndex = config.elementIndex || 0;
|
|
const totalElements = config.totalElements || Object.keys(content).length;
|
|
const currentHour = config.currentHour || new Date().getHours();
|
|
const personality = config.csvData?.personality;
|
|
|
|
return {
|
|
fatigueLevel: calculateFatigue(elementIndex, totalElements),
|
|
fatigueProfile: personality ? getFatigueProfile(personality.nom) : null,
|
|
personalityName: personality?.nom || 'unknown',
|
|
personalityProfile: personality ? getPersonalityErrorPatterns(personality.nom) : null,
|
|
temporalStyle: getTemporalStyle(currentHour),
|
|
currentHour,
|
|
elementIndex,
|
|
totalElements,
|
|
contentComplexity: analyzeContentComplexity(content)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* APPLICATION SIMULATION FATIGUE
|
|
*/
|
|
async function applyFatigueSimulation(content, globalContext, config) {
|
|
const fatigueResult = injectFatigueMarkers(content, globalContext.fatigueLevel, {
|
|
profile: globalContext.fatigueProfile,
|
|
intensity: config.imperfectionIntensity
|
|
});
|
|
|
|
return {
|
|
content: fatigueResult.content,
|
|
modifications: fatigueResult.modifications || 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* APPLICATION SIMULATION PERSONNALITÉ
|
|
*/
|
|
async function applyPersonalitySimulation(content, globalContext, config) {
|
|
const personalityResult = injectPersonalityErrors(
|
|
content,
|
|
globalContext.personalityProfile,
|
|
config.imperfectionIntensity
|
|
);
|
|
|
|
return {
|
|
content: personalityResult.content,
|
|
modifications: personalityResult.modifications || 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* APPLICATION SIMULATION TEMPORELLE
|
|
*/
|
|
async function applyTemporalSimulation(content, globalContext, config) {
|
|
const temporalResult = applyTemporalStyle(content, globalContext.temporalStyle, {
|
|
intensity: config.imperfectionIntensity
|
|
});
|
|
|
|
return {
|
|
content: temporalResult.content,
|
|
modifications: temporalResult.modifications || 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* CALCUL SCORE QUALITÉ GLOBAL
|
|
*/
|
|
function calculateGlobalQualityScore(originalContent, simulatedContent) {
|
|
let totalScore = 0;
|
|
let elementCount = 0;
|
|
|
|
for (const [key, original] of Object.entries(originalContent)) {
|
|
const simulated = simulatedContent[key];
|
|
if (simulated) {
|
|
const elementScore = calculateReadabilityScore(simulated) * 0.7 +
|
|
preserveKeywords(original, simulated) * 0.3;
|
|
totalScore += elementScore;
|
|
elementCount++;
|
|
}
|
|
}
|
|
|
|
return elementCount > 0 ? totalScore / elementCount : 0;
|
|
}
|
|
|
|
// ============= EXPORTS =============
|
|
module.exports = {
|
|
applyHumanSimulationLayer,
|
|
analyzeGlobalContext,
|
|
applyFatigueSimulation,
|
|
applyPersonalitySimulation,
|
|
applyTemporalSimulation,
|
|
calculateGlobalQualityScore,
|
|
DEFAULT_CONFIG
|
|
}; |