464 lines
16 KiB
JavaScript
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
|
|
}; |