seogeneratorserver/lib/pattern-breaking/PatternBreakingLayers.js
StillHammer dbf1a3de8c Add technical plan for multi-format export system
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>
2025-11-18 16:14:29 +08:00

372 lines
12 KiB
JavaScript

// ========================================
// FICHIER: PatternBreakingLayers.js
// RESPONSABILITÉ: Stacks prédéfinis pour Pattern Breaking
// Configurations optimisées par cas d'usage
// ========================================
const { logSh } = require('../ErrorReporting');
/**
* CONFIGURATIONS PRÉDÉFINIES PATTERN BREAKING
* Optimisées pour différents niveaux et cas d'usage
*/
const PATTERN_BREAKING_STACKS = {
// ========================================
// STACK LÉGER - Usage quotidien
// ========================================
lightPatternBreaking: {
name: 'Light Pattern Breaking',
description: 'Anti-détection subtile pour usage quotidien',
intensity: 0.3,
config: {
syntaxVariationEnabled: true,
llmFingerprintReplacement: false, // Pas de remplacement mots
naturalConnectorsEnabled: true,
preserveReadability: true,
maxModificationsPerElement: 2,
qualityThreshold: 0.7
},
expectedReduction: '10-15%',
useCase: 'Articles standard, faible risque détection'
},
// ========================================
// STACK STANDARD - Équilibre optimal
// ========================================
standardPatternBreaking: {
name: 'Standard Pattern Breaking',
description: 'Équilibre optimal efficacité/naturalité',
intensity: 0.5,
config: {
syntaxVariationEnabled: true,
llmFingerprintReplacement: true,
naturalConnectorsEnabled: true,
preserveReadability: true,
maxModificationsPerElement: 4,
qualityThreshold: 0.6
},
expectedReduction: '20-25%',
useCase: 'Usage général recommandé'
},
// ========================================
// STACK INTENSIF - Anti-détection poussée
// ========================================
heavyPatternBreaking: {
name: 'Heavy Pattern Breaking',
description: 'Anti-détection intensive pour cas critiques',
intensity: 0.8,
config: {
syntaxVariationEnabled: true,
llmFingerprintReplacement: true,
naturalConnectorsEnabled: true,
preserveReadability: true,
maxModificationsPerElement: 6,
qualityThreshold: 0.5
},
expectedReduction: '30-35%',
useCase: 'Détection élevée, contenu critique'
},
// ========================================
// STACK ADAPTATIF - Selon contenu
// ========================================
adaptivePatternBreaking: {
name: 'Adaptive Pattern Breaking',
description: 'Adaptation intelligente selon détection patterns',
intensity: 0.6,
config: {
syntaxVariationEnabled: true,
llmFingerprintReplacement: true,
naturalConnectorsEnabled: true,
preserveReadability: true,
maxModificationsPerElement: 5,
qualityThreshold: 0.6,
adaptiveMode: true // Ajuste selon détection patterns
},
expectedReduction: '25-30%',
useCase: 'Adaptation automatique par contenu'
},
// ========================================
// STACK SYNTAXE FOCUS - Syntaxe uniquement
// ========================================
syntaxFocus: {
name: 'Syntax Focus',
description: 'Focus sur variations syntaxiques uniquement',
intensity: 0.7,
config: {
syntaxVariationEnabled: true,
llmFingerprintReplacement: false,
naturalConnectorsEnabled: false,
preserveReadability: true,
maxModificationsPerElement: 6,
qualityThreshold: 0.7
},
expectedReduction: '15-20%',
useCase: 'Préservation vocabulaire, syntaxe variable'
},
// ========================================
// STACK CONNECTEURS FOCUS - Connecteurs uniquement
// ========================================
connectorsFocus: {
name: 'Connectors Focus',
description: 'Humanisation connecteurs et transitions',
intensity: 0.8,
config: {
syntaxVariationEnabled: false,
llmFingerprintReplacement: false,
naturalConnectorsEnabled: true,
preserveReadability: true,
maxModificationsPerElement: 4,
qualityThreshold: 0.8,
connectorTone: 'casual' // casual, conversational, technical, commercial
},
expectedReduction: '12-18%',
useCase: 'Textes formels à humaniser'
}
};
/**
* APPLICATION STACK PATTERN BREAKING
* @param {string} stackName - Nom du stack à appliquer
* @param {object} content - Contenu à traiter
* @param {object} overrides - Options pour surcharger le stack
* @returns {object} - { content, stats, stackUsed }
*/
async function applyPatternBreakingStack(stackName, content, overrides = {}) {
const { applyPatternBreakingLayer } = require('./PatternBreakingCore');
logSh(`📦 Application Stack Pattern Breaking: ${stackName}`, 'INFO');
const stack = PATTERN_BREAKING_STACKS[stackName];
if (!stack) {
logSh(`❌ Stack Pattern Breaking inconnu: ${stackName}`, 'WARNING');
throw new Error(`Stack Pattern Breaking inconnu: ${stackName}`);
}
try {
// Configuration fusionnée (stack + overrides)
const finalConfig = {
...stack.config,
intensityLevel: stack.intensity,
...overrides
};
logSh(` 🎯 Configuration: ${stack.description}`, 'DEBUG');
logSh(` ⚡ Intensité: ${finalConfig.intensityLevel} | Réduction attendue: ${stack.expectedReduction}`, 'DEBUG');
// Mode adaptatif si activé
if (finalConfig.adaptiveMode) {
const adaptedConfig = await adaptConfigurationToContent(content, finalConfig);
Object.assign(finalConfig, adaptedConfig);
logSh(` 🧠 Mode adaptatif appliqué`, 'DEBUG');
}
// Application Pattern Breaking
const result = await applyPatternBreakingLayer(content, finalConfig);
logSh(`📦 Stack Pattern Breaking terminé: ${result.stats?.totalModifications || 0} modifications`, 'INFO');
return {
content: result.content,
stats: {
...result.stats,
stackUsed: stackName,
stackDescription: stack.description,
expectedReduction: stack.expectedReduction
},
fallback: result.fallback,
stackUsed: stackName
};
} catch (error) {
logSh(`❌ Erreur application Stack Pattern Breaking ${stackName}: ${error.message}`, 'ERROR');
throw error;
}
}
/**
* ADAPTATION CONFIGURATION SELON CONTENU
*/
async function adaptConfigurationToContent(content, baseConfig) {
const { detectLLMPatterns } = require('./LLMFingerprints');
const { detectFormalConnectors } = require('./NaturalConnectors');
logSh(`🧠 Adaptation configuration selon contenu...`, 'DEBUG');
const adaptations = { ...baseConfig };
try {
// Analyser patterns LLM
const llmDetection = detectLLMPatterns(content);
const formalDetection = detectFormalConnectors(content);
logSh(` 📊 Patterns LLM: ${llmDetection.count} (score: ${llmDetection.suspicionScore.toFixed(3)})`, 'DEBUG');
logSh(` 📊 Connecteurs formels: ${formalDetection.count} (score: ${formalDetection.suspicionScore.toFixed(3)})`, 'DEBUG');
// Adapter selon détection patterns LLM
if (llmDetection.suspicionScore > 0.06) {
adaptations.llmFingerprintReplacement = true;
adaptations.intensityLevel = Math.min(1.0, baseConfig.intensityLevel + 0.2);
logSh(` 🔧 Intensité augmentée pour patterns LLM élevés: ${adaptations.intensityLevel}`, 'DEBUG');
} else if (llmDetection.suspicionScore < 0.02) {
adaptations.llmFingerprintReplacement = false;
logSh(` 🔧 Remplacement LLM désactivé (faible détection)`, 'DEBUG');
}
// Adapter selon connecteurs formels
if (formalDetection.suspicionScore > 0.04) {
adaptations.naturalConnectorsEnabled = true;
adaptations.maxModificationsPerElement = Math.min(8, baseConfig.maxModificationsPerElement + 2);
logSh(` 🔧 Focus connecteurs activé: max ${adaptations.maxModificationsPerElement} modifications`, 'DEBUG');
}
// Adapter selon longueur texte
const wordCount = content.split(/\s+/).length;
if (wordCount > 500) {
adaptations.maxModificationsPerElement = Math.min(10, baseConfig.maxModificationsPerElement + 3);
logSh(` 🔧 Texte long détecté: max ${adaptations.maxModificationsPerElement} modifications`, 'DEBUG');
}
} catch (error) {
logSh(`⚠️ Erreur adaptation configuration: ${error.message}`, 'WARNING');
}
return adaptations;
}
/**
* RECOMMANDATION STACK AUTOMATIQUE
*/
function recommendPatternBreakingStack(content, context = {}) {
const { detectLLMPatterns } = require('./LLMFingerprints');
const { detectFormalConnectors } = require('./NaturalConnectors');
try {
const llmDetection = detectLLMPatterns(content);
const formalDetection = detectFormalConnectors(content);
const wordCount = content.split(/\s+/).length;
logSh(`🤖 Recommandation Stack Pattern Breaking...`, 'DEBUG');
// Critères de recommandation
const criteria = {
llmPatternsHigh: llmDetection.suspicionScore > 0.05,
formalConnectorsHigh: formalDetection.suspicionScore > 0.03,
longContent: wordCount > 300,
criticalContext: context.critical === true,
preserveQuality: context.preserveQuality === true
};
// Logique de recommandation
let recommendedStack = 'standardPatternBreaking';
let reason = 'Configuration équilibrée par défaut';
if (criteria.criticalContext) {
recommendedStack = 'heavyPatternBreaking';
reason = 'Contexte critique détecté';
} else if (criteria.llmPatternsHigh && criteria.formalConnectorsHigh) {
recommendedStack = 'heavyPatternBreaking';
reason = 'Patterns LLM et connecteurs formels élevés';
} else if (criteria.llmPatternsHigh) {
recommendedStack = 'adaptivePatternBreaking';
reason = 'Patterns LLM élevés détectés';
} else if (criteria.formalConnectorsHigh) {
recommendedStack = 'connectorsFocus';
reason = 'Connecteurs formels prédominants';
} else if (criteria.preserveQuality) {
recommendedStack = 'lightPatternBreaking';
reason = 'Préservation qualité prioritaire';
} else if (!criteria.llmPatternsHigh && !criteria.formalConnectorsHigh) {
recommendedStack = 'syntaxFocus';
reason = 'Faible détection patterns, focus syntaxe';
}
logSh(`🎯 Stack recommandé: ${recommendedStack} (${reason})`, 'DEBUG');
return {
recommendedStack,
reason,
criteria,
confidence: calculateRecommendationConfidence(criteria)
};
} catch (error) {
logSh(`⚠️ Erreur recommandation Stack: ${error.message}`, 'WARNING');
return {
recommendedStack: 'standardPatternBreaking',
reason: 'Fallback suite erreur analyse',
criteria: {},
confidence: 0.5
};
}
}
/**
* CALCUL CONFIANCE RECOMMANDATION
*/
function calculateRecommendationConfidence(criteria) {
let confidence = 0.5; // Base
// Augmenter confiance selon critères détectés
if (criteria.llmPatternsHigh) confidence += 0.2;
if (criteria.formalConnectorsHigh) confidence += 0.2;
if (criteria.criticalContext) confidence += 0.3;
if (criteria.longContent) confidence += 0.1;
return Math.min(1.0, confidence);
}
/**
* LISTE STACKS DISPONIBLES
*/
function listAvailableStacks() {
return Object.entries(PATTERN_BREAKING_STACKS).map(([key, stack]) => ({
name: key,
displayName: stack.name,
description: stack.description,
intensity: stack.intensity,
expectedReduction: stack.expectedReduction,
useCase: stack.useCase
}));
}
/**
* VALIDATION STACK
*/
function validateStack(stackName) {
const stack = PATTERN_BREAKING_STACKS[stackName];
if (!stack) {
return { valid: false, error: `Stack inconnu: ${stackName}` };
}
// Vérifications configuration
const config = stack.config;
const checks = {
hasIntensity: typeof stack.intensity === 'number',
hasConfig: typeof config === 'object',
hasValidThreshold: config.qualityThreshold >= 0 && config.qualityThreshold <= 1,
hasValidMaxMods: config.maxModificationsPerElement > 0
};
const valid = Object.values(checks).every(Boolean);
return {
valid,
checks,
error: valid ? null : 'Configuration stack invalide'
};
}
// ============= EXPORTS =============
module.exports = {
applyPatternBreakingStack,
recommendPatternBreakingStack,
adaptConfigurationToContent,
listAvailableStacks,
validateStack,
PATTERN_BREAKING_STACKS
};