seo-generator-server/lib/human-simulation/PersonalityErrors.js

464 lines
16 KiB
JavaScript

// ========================================
// FICHIER: PersonalityErrors.js
// RESPONSABILITÉ: Erreurs cohérentes par personnalité
// 15 profils d'erreurs basés sur les personnalités système
// ========================================
const { logSh } = require('../ErrorReporting');
/**
* PATTERNS D'ERREURS PAR PERSONNALITÉ
* Basé sur les 15 personnalités du BrainConfig
* Chaque personnalité a ses tics linguistiques et erreurs typiques
*/
const PERSONALITY_ERROR_PATTERNS = {
// ========================================
// PERSONNALITÉS TECHNIQUES
// ========================================
marc: {
name: 'Marc - Expert Technique',
tendencies: ['sur-technicisation', 'anglicismes techniques', 'jargon professionnel'],
repetitions: ['précis', 'efficace', 'optimal', 'performant', 'système'],
syntaxErrors: [
'phrases techniques non finies',
'parenthèses explicatives excessives',
'abréviations sans développement'
],
vocabularyTics: ['niveau technique', 'en termes de', 'au niveau de'],
anglicisms: ['upgrade', 'process', 'workflow', 'pipeline'],
errorFrequency: 0.7 // Probabilité base
},
amara: {
name: 'Amara - Ingénieure Système',
tendencies: ['méthodologie rigide', 'références normes', 'vocabulaire industriel'],
repetitions: ['conforme', 'standard', 'spécifications', 'protocole'],
syntaxErrors: ['énumérations lourdes', 'références normatives'],
vocabularyTics: ['selon les normes', 'conformément à', 'dans le respect de'],
anglicisms: ['compliance', 'standard', 'guidelines'],
errorFrequency: 0.6
},
yasmine: {
name: 'Yasmine - GreenTech',
tendencies: ['éco-vocabulaire répétitif', 'superlatifs environnementaux'],
repetitions: ['durable', 'écologique', 'responsable', 'vert', 'bio'],
syntaxErrors: ['accumulation adjectifs éco', 'phrases militantes'],
vocabularyTics: ['respectueux de l\'environnement', 'développement durable'],
anglicisms: ['green', 'eco-friendly', 'sustainable'],
errorFrequency: 0.8
},
fabrice: {
name: 'Fabrice - Métallurgie',
tendencies: ['vocabulaire métier spécialisé', 'références techniques'],
repetitions: ['résistant', 'robuste', 'solide', 'qualité', 'finition'],
syntaxErrors: ['termes techniques sans explication'],
vocabularyTics: ['en terme de résistance', 'question de solidité'],
anglicisms: ['coating', 'finish', 'design'],
errorFrequency: 0.5
},
// ========================================
// PERSONNALITÉS CRÉATIVES
// ========================================
sophie: {
name: 'Sophie - Déco Design',
tendencies: ['vocabulaire déco répétitif', 'superlatifs esthétiques'],
repetitions: ['magnifique', 'élégant', 'harmonieux', 'raffiné', 'style'],
syntaxErrors: ['accord couleurs/matières', 'accumulation adjectifs'],
vocabularyTics: ['en terme de style', 'au niveau esthétique', 'côté design'],
anglicisms: ['design', 'style', 'trendy', 'vintage'],
errorFrequency: 0.9
},
émilie: {
name: 'Émilie - Digital Native',
tendencies: ['anglicismes numériques', 'vocabulaire web'],
repetitions: ['digital', 'online', 'connecté', 'smart', 'moderne'],
syntaxErrors: ['néologismes numériques'],
vocabularyTics: ['au niveau digital', 'côté technologique'],
anglicisms: ['user-friendly', 'responsive', 'digital', 'smart'],
errorFrequency: 1.0
},
chloé: {
name: 'Chloé - Content Creator',
tendencies: ['ton familier', 'expressions actuelles', 'anglicismes réseaux'],
repetitions: ['super', 'génial', 'top', 'incontournable', 'tendance'],
syntaxErrors: ['familiarités', 'expressions jeunes'],
vocabularyTics: ['c\'est vraiment', 'on va dire que', 'du coup'],
anglicisms: ['content', 'trending', 'viral', 'lifestyle'],
errorFrequency: 1.1
},
minh: {
name: 'Minh - Designer Industriel',
tendencies: ['références design', 'vocabulaire forme/fonction'],
repetitions: ['fonctionnel', 'ergonomique', 'esthétique', 'innovant'],
syntaxErrors: ['descriptions techniques design'],
vocabularyTics: ['en terme de design', 'niveau ergonomie'],
anglicisms: ['design', 'user experience', 'ergonomic'],
errorFrequency: 0.7
},
// ========================================
// PERSONNALITÉS COMMERCIALES
// ========================================
laurent: {
name: 'Laurent - Commercial BtoB',
tendencies: ['vocabulaire vente', 'superlatifs commerciaux'],
repetitions: ['excellent', 'exceptionnel', 'unique', 'incontournable'],
syntaxErrors: ['promesses excessives', 'superlatifs empilés'],
vocabularyTics: ['c\'est vraiment', 'je vous garantis', 'sans aucun doute'],
anglicisms: ['business', 'deal', 'top niveau'],
errorFrequency: 1.2
},
julie: {
name: 'Julie - Architecture Commerciale',
tendencies: ['vocabulaire technique commercial', 'références projets'],
repetitions: ['projet', 'réalisation', 'conception', 'sur-mesure'],
syntaxErrors: ['énumérations projets'],
vocabularyTics: ['dans le cadre de', 'au niveau projet'],
anglicisms: ['design', 'custom', 'high-end'],
errorFrequency: 0.8
},
// ========================================
// PERSONNALITÉS TERRAIN
// ========================================
kévin: {
name: 'Kévin - Homme de Terrain',
tendencies: ['expressions familières', 'vocabulaire pratique'],
repetitions: ['pratique', 'concret', 'simple', 'direct', 'efficace'],
syntaxErrors: ['tournures familières', 'expressions populaires'],
vocabularyTics: ['franchement', 'concrètement', 'dans les faits'],
anglicisms: ['basique', 'standard'],
errorFrequency: 0.6
},
mamadou: {
name: 'Mamadou - Artisan Expérimenté',
tendencies: ['références tradition', 'vocabulaire métier'],
repetitions: ['traditionnel', 'artisanal', 'savoir-faire', 'qualité'],
syntaxErrors: ['expressions métier', 'références tradition'],
vocabularyTics: ['comme on dit', 'dans le métier', 'selon l\'expérience'],
anglicisms: [], // Évite les anglicismes
errorFrequency: 0.4
},
linh: {
name: 'Linh - Production Industrielle',
tendencies: ['vocabulaire production', 'références process'],
repetitions: ['production', 'fabrication', 'process', 'qualité', 'série'],
syntaxErrors: ['termes production techniques'],
vocabularyTics: ['au niveau production', 'côté fabrication'],
anglicisms: ['process', 'manufacturing', 'quality'],
errorFrequency: 0.5
},
// ========================================
// PERSONNALITÉS PATRIMOINE
// ========================================
'pierre-henri': {
name: 'Pierre-Henri - Patrimoine Classique',
tendencies: ['vocabulaire soutenu', 'références historiques'],
repetitions: ['traditionnel', 'authentique', 'noble', 'raffinement', 'héritage'],
syntaxErrors: ['formulations recherchées', 'références culturelles'],
vocabularyTics: ['il convient de', 'il est à noter que', 'dans la tradition'],
anglicisms: [], // Évite complètement
errorFrequency: 0.3
},
thierry: {
name: 'Thierry - Créole Authentique',
tendencies: ['expressions créoles', 'tournures locales'],
repetitions: ['authentique', 'local', 'tradition', 'racines'],
syntaxErrors: ['tournures créoles', 'expressions locales'],
vocabularyTics: ['comme on dit chez nous', 'dans nos traditions'],
anglicisms: [], // Privilégie le français local
errorFrequency: 0.8
}
};
/**
* OBTENIR PROFIL D'ERREURS PAR PERSONNALITÉ
* @param {string} personalityName - Nom personnalité
* @returns {object} - Profil d'erreurs
*/
function getPersonalityErrorPatterns(personalityName) {
const normalizedName = personalityName?.toLowerCase() || 'default';
const profile = PERSONALITY_ERROR_PATTERNS[normalizedName];
if (!profile) {
logSh(`⚠️ Profil erreurs non trouvé pour ${personalityName}, utilisation profil générique`, 'WARNING');
return createGenericErrorProfile();
}
logSh(`🎭 Profil erreurs sélectionné pour ${personalityName}: ${profile.name}`, 'DEBUG');
return profile;
}
/**
* PROFIL D'ERREURS GÉNÉRIQUE
*/
function createGenericErrorProfile() {
return {
name: 'Profil Générique',
tendencies: ['répétitions standard', 'vocabulaire neutre'],
repetitions: ['bien', 'bon', 'intéressant', 'important'],
syntaxErrors: ['phrases standards'],
vocabularyTics: ['en effet', 'par ailleurs', 'de plus'],
anglicisms: [],
errorFrequency: 0.5
};
}
/**
* INJECTION ERREURS PERSONNALITÉ
* @param {string} content - Contenu à modifier
* @param {object} personalityProfile - Profil personnalité
* @param {number} intensity - Intensité (0-2.0)
* @returns {object} - { content, modifications }
*/
function injectPersonalityErrors(content, personalityProfile, intensity = 1.0) {
if (!content || !personalityProfile) {
return { content, modifications: 0 };
}
logSh(`🎭 Injection erreurs personnalité: ${personalityProfile.name}`, 'DEBUG');
let modifiedContent = content;
let modifications = 0;
// Probabilité d'application basée sur l'intensité et la fréquence du profil
const baseFrequency = personalityProfile.errorFrequency || 0.5;
const adjustedProbability = Math.min(1.0, baseFrequency * intensity);
logSh(`🎯 Probabilité erreurs: ${adjustedProbability.toFixed(2)} (base: ${baseFrequency}, intensité: ${intensity})`, 'DEBUG');
// ========================================
// 1. RÉPÉTITIONS CARACTÉRISTIQUES
// ========================================
const repetitionResult = injectRepetitions(modifiedContent, personalityProfile, adjustedProbability);
modifiedContent = repetitionResult.content;
modifications += repetitionResult.count;
// ========================================
// 2. TICS VOCABULAIRE
// ========================================
const vocabularyResult = injectVocabularyTics(modifiedContent, personalityProfile, adjustedProbability);
modifiedContent = vocabularyResult.content;
modifications += vocabularyResult.count;
// ========================================
// 3. ANGLICISMES (SI APPLICABLE)
// ========================================
if (personalityProfile.anglicisms && personalityProfile.anglicisms.length > 0) {
const anglicismResult = injectAnglicisms(modifiedContent, personalityProfile, adjustedProbability * 0.3);
modifiedContent = anglicismResult.content;
modifications += anglicismResult.count;
}
// ========================================
// 4. ERREURS SYNTAXIQUES TYPIQUES
// ========================================
const syntaxResult = injectSyntaxErrors(modifiedContent, personalityProfile, adjustedProbability * 0.2);
modifiedContent = syntaxResult.content;
modifications += syntaxResult.count;
logSh(`🎭 Erreurs personnalité injectées: ${modifications} modifications`, 'DEBUG');
return {
content: modifiedContent,
modifications
};
}
/**
* INJECTION RÉPÉTITIONS CARACTÉRISTIQUES
*/
function injectRepetitions(content, profile, probability) {
let modified = content;
let count = 0;
if (!profile.repetitions || profile.repetitions.length === 0) {
return { content: modified, count };
}
// Sélectionner 1-3 mots répétitifs pour ce contenu - FIXÉ: Plus de mots
const selectedWords = profile.repetitions
.sort(() => 0.5 - Math.random())
.slice(0, Math.random() < 0.5 ? 2 : 3); // FIXÉ: Au moins 2 mots sélectionnés
selectedWords.forEach(word => {
if (Math.random() < probability) {
// Chercher des endroits appropriés pour injecter le mot
const sentences = modified.split('. ');
const targetSentenceIndex = Math.floor(Math.random() * sentences.length);
if (sentences[targetSentenceIndex] &&
sentences[targetSentenceIndex].length > 30 &&
!sentences[targetSentenceIndex].toLowerCase().includes(word.toLowerCase())) {
// Injecter le mot de façon naturelle
const words = sentences[targetSentenceIndex].split(' ');
const insertIndex = Math.floor(words.length * (0.3 + Math.random() * 0.4)); // 30-70% de la phrase
// Adaptations contextuelles
const adaptedWord = adaptWordToContext(word, words[insertIndex] || '');
words.splice(insertIndex, 0, adaptedWord);
sentences[targetSentenceIndex] = words.join(' ');
modified = sentences.join('. ');
count++;
logSh(` 📝 Répétition injectée: "${adaptedWord}" dans phrase ${targetSentenceIndex + 1}`, 'DEBUG');
}
}
});
return { content: modified, count };
}
/**
* INJECTION TICS VOCABULAIRE
*/
function injectVocabularyTics(content, profile, probability) {
let modified = content;
let count = 0;
if (!profile.vocabularyTics || profile.vocabularyTics.length === 0) {
return { content: modified, count };
}
const selectedTics = profile.vocabularyTics.slice(0, 1); // Un seul tic par contenu
selectedTics.forEach(tic => {
if (Math.random() < probability * 0.8) { // Probabilité réduite pour les tics
// Remplacer des connecteurs standards par le tic
const standardConnectors = ['par ailleurs', 'de plus', 'également', 'aussi'];
standardConnectors.forEach(connector => {
const regex = new RegExp(`\\b${connector}\\b`, 'gi');
if (modified.match(regex) && Math.random() < 0.4) {
modified = modified.replace(regex, tic);
count++;
logSh(` 🗣️ Tic vocabulaire: "${connector}" → "${tic}"`, 'DEBUG');
}
});
}
});
return { content: modified, count };
}
/**
* INJECTION ANGLICISMES
*/
function injectAnglicisms(content, profile, probability) {
let modified = content;
let count = 0;
if (!profile.anglicisms || profile.anglicisms.length === 0) {
return { content: modified, count };
}
// Remplacements français → anglais
const replacements = {
'processus': 'process',
'conception': 'design',
'flux de travail': 'workflow',
'mise à jour': 'upgrade',
'contenu': 'content',
'tendance': 'trending',
'intelligent': 'smart',
'numérique': 'digital'
};
Object.entries(replacements).forEach(([french, english]) => {
if (profile.anglicisms.includes(english) && Math.random() < probability) {
const regex = new RegExp(`\\b${french}\\b`, 'gi');
if (modified.match(regex)) {
modified = modified.replace(regex, english);
count++;
logSh(` 🇬🇧 Anglicisme: "${french}" → "${english}"`, 'DEBUG');
}
}
});
return { content: modified, count };
}
/**
* INJECTION ERREURS SYNTAXIQUES
*/
function injectSyntaxErrors(content, profile, probability) {
let modified = content;
let count = 0;
if (Math.random() > probability) {
return { content: modified, count };
}
// Erreurs syntaxiques légères selon la personnalité
if (profile.name.includes('Marc') || profile.name.includes('Technique')) {
// Parenthèses techniques excessives
if (Math.random() < 0.3) {
modified = modified.replace(/(\w+)/, '$1 (système)');
count++;
logSh(` 🔧 Erreur technique: parenthèses ajoutées`, 'DEBUG');
}
}
if (profile.name.includes('Sophie') || profile.name.includes('Déco')) {
// Accumulation d'adjectifs
if (Math.random() < 0.3) {
modified = modified.replace(/élégant/gi, 'élégant et raffiné');
count++;
logSh(` 🎨 Erreur déco: adjectifs accumulés`, 'DEBUG');
}
}
if (profile.name.includes('Laurent') || profile.name.includes('Commercial')) {
// Superlatifs empilés
if (Math.random() < 0.3) {
modified = modified.replace(/excellent/gi, 'vraiment excellent');
count++;
logSh(` 💼 Erreur commerciale: superlatifs empilés`, 'DEBUG');
}
}
return { content: modified, count };
}
/**
* ADAPTATION CONTEXTUELLE DES MOTS
*/
function adaptWordToContext(word, contextWord) {
// Accords basiques
const contextLower = contextWord.toLowerCase();
// Accords féminins simples
if (contextLower.includes('la ') || contextLower.endsWith('e')) {
if (word === 'bon') return 'bonne';
if (word === 'précis') return 'précise';
}
return word;
}
// ============= EXPORTS =============
module.exports = {
getPersonalityErrorPatterns,
injectPersonalityErrors,
injectRepetitions,
injectVocabularyTics,
injectAnglicisms,
injectSyntaxErrors,
createGenericErrorProfile,
adaptWordToContext,
PERSONALITY_ERROR_PATTERNS
};