diff --git a/SELECTIVE_ENHANCEMENT_GUIDE.md b/SELECTIVE_ENHANCEMENT_GUIDE.md new file mode 100644 index 0000000..179816d --- /dev/null +++ b/SELECTIVE_ENHANCEMENT_GUIDE.md @@ -0,0 +1,239 @@ +# 📘 Guide du Selective Enhancement + +## 🎯 Qu'est-ce que c'est ? + +Le **Selective Enhancement** est un systĂšme modulaire qui amĂ©liore le contenu gĂ©nĂ©rĂ© en appliquant des **couches d'amĂ©lioration** successives. Chaque couche utilise un LLM diffĂ©rent spĂ©cialisĂ© pour un type d'amĂ©lioration. + +--- + +## đŸ—ïž Architecture en 3 niveaux + +### Niveau 1 : Les Stacks PrĂ©dĂ©finis +Ce sont des **"recettes"** qui dĂ©finissent quelles couches appliquer et dans quel ordre. + +```javascript +// Exemple de stack prĂ©dĂ©fini +{ + name: 'standardEnhancement', + description: 'AmĂ©lioration technique et style (OpenAI + Mistral)', + layers: [ + { type: 'technical', llm: 'gpt-4o-mini', intensity: 0.9 }, + { type: 'style', llm: 'mistral-small', intensity: 0.8 } + ], + layersCount: 2 +} +``` + +### Niveau 2 : Les Couches (Layers) +Chaque couche a 3 paramĂštres clĂ©s : + +- **type** : Ce que la couche amĂ©liore + - `technical` : PrĂ©cision technique, termes mĂ©tier + - `transitions` : FluiditĂ© entre phrases + - `style` : PersonnalitĂ©, ton, vocabulaire + +- **llm** : Le modĂšle utilisĂ© + - `gpt-4o-mini` : Excellent pour prĂ©cision technique + - `mistral-small` : Excellent pour style et personnalitĂ© + - `gemini-pro` : Bon pour fluiditĂ© (actuellement dĂ©sactivĂ©) + +- **intensity** : Force de l'amĂ©lioration (0.5 Ă  1.5) + - `0.6` : LĂ©gĂšre amĂ©lioration + - `1.0` : AmĂ©lioration normale + - `1.2` : AmĂ©lioration forte + +### Niveau 3 : L'ExĂ©cution +Quand vous choisissez un stack, voici ce qui se passe : + +``` +1. Charge la configuration du stack + └─> standardEnhancement = [technical + style] + +2. Applique Couche 1 : technical (gpt-4o-mini) + ├─ Avant : "Nos produits sont de qualitĂ©" + └─ AprĂšs : "Nos panneaux PMMA garantissent une durabilitĂ© optimale" + +3. Applique Couche 2 : style (mistral-small) + ├─ Avant : "Nos panneaux PMMA garantissent une durabilitĂ© optimale" + └─ AprĂšs : "Nos panneaux PMMA, c'est la garantie d'une durabilitĂ© qui tient dans le temps" + +4. RĂ©sultat final = contenu amĂ©liorĂ© par les 2 couches +``` + +--- + +## 📩 Stacks Disponibles + +### 1. `lightEnhancement` (Rapide) +- **1 couche** : Technique uniquement +- **DurĂ©e** : ~15-20s +- **Usage** : Tests rapides, contenu dĂ©jĂ  bon + +### 2. `standardEnhancement` (ÉquilibrĂ©) ⭐ RECOMMANDÉ +- **2 couches** : Technique + Style +- **DurĂ©e** : ~30-40s +- **Usage** : Production standard, bon compromis qualitĂ©/vitesse + +### 3. `fullEnhancement` (Complet) +- **2 couches** : Technique intense + Style +- **DurĂ©e** : ~35-45s +- **Usage** : Contenu premium, qualitĂ© maximale + +### 4. `personalityFocus` (Style prioritaire) +- **2 couches** : Style fort + Technique lĂ©gĂšre +- **DurĂ©e** : ~30-40s +- **Usage** : Quand la personnalitĂ© est importante + +### 5. `adaptive` (Intelligent) +- **Analyse automatique** du contenu +- **Couches variables** selon les besoins dĂ©tectĂ©s +- **DurĂ©e** : Variable +- **Usage** : Quand vous ne savez pas quoi choisir + +--- + +## 🚀 Comment l'utiliser ? + +### Dans le code (Main.js) +```javascript +await handleModularWorkflow({ + rowNumber: 2, + selectiveStack: 'standardEnhancement', // ← Choisir le stack ici + adversarialMode: 'light', + source: 'production' +}); +``` + +### Via API +```javascript +POST /api/workflow/execute +{ + "rowNumber": 2, + "selectiveStack": "standardEnhancement", // ← Choisir le stack ici + "adversarialMode": "light" +} +``` + +### Via Interface Web +``` +production-runner.html → SĂ©lection stack dans le dropdown +``` + +--- + +## 📊 Logs dĂ©taillĂ©s (aprĂšs modification) + +Voici ce que vous verrez maintenant dans les logs : + +``` +📩 APPLICATION STACK SELECTIVE: standardEnhancement (2 couches) + 📊 12 Ă©lĂ©ments | Description: AmĂ©lioration technique et style + 🔍 Configuration du stack: + Couche 1: technical | LLM: gpt-4o-mini | IntensitĂ©: 0.9 + Couche 2: style | LLM: mistral-small | IntensitĂ©: 0.8 + + 🔧 === COUCHE 1/2 === + Type: technical | LLM: gpt-4o-mini | IntensitĂ©: 0.9 + ÉlĂ©ments en entrĂ©e: 12 + 📝 Échantillon AVANT (t0): Nos produits sont de qualitĂ©... + đŸ€– LLM spĂ©cifiĂ©: gpt-4o-mini + 🔬 Branche: Technical Enhancement + 📝 Config technique: LLM=gpt-4o-mini, Intensity=0.9 + ✅ Technical enhancement terminĂ©: 8 modifications + 📝 Échantillon APRÈS (t0): Nos panneaux PMMA garantissent... + ✅ RÉSULTAT: 8 Ă©lĂ©ments modifiĂ©s (66.7% du total) + ⏱ DurĂ©e: 2340ms + + 🔧 === COUCHE 2/2 === + Type: style | LLM: mistral-small | IntensitĂ©: 0.8 + ÉlĂ©ments en entrĂ©e: 12 + 📝 Échantillon AVANT (t0): Nos panneaux PMMA garantissent... + đŸ€– LLM spĂ©cifiĂ©: mistral-small + 🎹 Branche: Style Enhancement + 📝 Config style: LLM=mistral-small, Intensity=0.8 + ✅ Style enhancement terminĂ©: 6 modifications + 📝 Échantillon APRÈS (t0): Nos panneaux PMMA, c'est la garantie... + ✅ RÉSULTAT: 6 Ă©lĂ©ments modifiĂ©s (50.0% du total) + ⏱ DurĂ©e: 1890ms + +✅ === STACK SELECTIVE standardEnhancement TERMINÉ === + 📊 Couches rĂ©ussies: 2/2 + 🔄 Modifications totales: 14 + ⏱ DurĂ©e totale: 4230ms + + 📋 RÉCAPITULATIF PAR COUCHE: + ✅ Couche 1: technical (gpt-4o-mini) - 8 modifs en 2340ms + ✅ Couche 2: style (mistral-small) - 6 modifs en 1890ms +``` + +--- + +## ❓ FAQ + +### Q: Pourquoi 2 couches dans standardEnhancement ? +**R:** Chaque LLM est spĂ©cialisĂ©. GPT-4o-mini excelle en prĂ©cision technique, Mistral en style. En combinant les deux, on obtient un contenu techniquement prĂ©cis ET bien Ă©crit. + +### Q: Quelle est la diffĂ©rence entre standardEnhancement et fullEnhancement ? +**R:** fullEnhancement utilise des intensitĂ©s plus fortes (1.0 au lieu de 0.9) donc des modifications plus poussĂ©es. Utile pour du contenu premium. + +### Q: Puis-je crĂ©er mes propres stacks ? +**R:** Oui ! Modifiez `PREDEFINED_STACKS` dans `lib/selective-enhancement/SelectiveLayers.js` + +### Q: Comment savoir quel stack choisir ? +**R:** +- **Production standard** → `standardEnhancement` +- **Tests rapides** → `lightEnhancement` +- **QualitĂ© max** → `fullEnhancement` +- **Pas sĂ»r** → `adaptive` (analyse automatique) + +### Q: Les modifications sont-elles cumulatives ? +**R:** Oui ! Couche 1 modifie le contenu → Couche 2 modifie le rĂ©sultat de Couche 1 → RĂ©sultat final = contenu doublement amĂ©liorĂ©. + +--- + +## 🔧 Configuration technique + +### Fichiers impliquĂ©s +``` +lib/selective-enhancement/ +├── SelectiveCore.js ← Moteur d'application des couches +├── SelectiveLayers.js ← DĂ©finition des stacks prĂ©dĂ©finis +├── TechnicalLayer.js ← ImplĂ©mentation couche technique +├── StyleLayer.js ← ImplĂ©mentation couche style +└── TransitionLayer.js ← ImplĂ©mentation couche transitions +``` + +### Mapping LLM → Type de couche +```javascript +{ + 'technical': 'gpt-4o-mini', // PrĂ©cision technique + 'transitions': 'gemini-pro', // FluiditĂ© (dĂ©sactivĂ©) + 'style': 'mistral-small', // PersonnalitĂ© + 'all': 'claude-sonnet-4-5' // Polyvalent +} +``` + +--- + +## 🎓 RĂ©sumĂ© + +**Configuration effective = Stack choisi** + +Quand vous faites : +```javascript +selectiveStack: 'standardEnhancement' +``` + +Cela charge automatiquement : +```javascript +{ + layers: [ + { type: 'technical', llm: 'gpt-4o-mini', intensity: 0.9 }, + { type: 'style', llm: 'mistral-small', intensity: 0.8 } + ] +} +``` + +Et applique les 2 couches **sĂ©quentiellement** sur votre contenu. + +**C'est aussi simple que ça !** 🎉 diff --git a/lib/selective-enhancement/SelectiveCore.js b/lib/selective-enhancement/SelectiveCore.js index ebcfa2d..d3f73fa 100644 --- a/lib/selective-enhancement/SelectiveCore.js +++ b/lib/selective-enhancement/SelectiveCore.js @@ -17,7 +17,7 @@ async function applySelectiveLayer(existingContent, config = {}) { return await tracer.run('SelectiveCore.applySelectiveLayer()', async () => { const { layerType = 'technical', // 'technical' | 'transitions' | 'style' | 'all' - llmProvider = 'auto', // 'claude' | 'gpt4' | 'gemini' | 'mistral' | 'auto' + llmProvider = 'auto', // 'claude-sonnet-4-5' | 'gpt4' | 'gemini-pro' | 'mistral-small' | 'auto' analysisMode = true, // Analyser avant d'appliquer preserveStructure = true, csvData = null, @@ -51,34 +51,50 @@ async function applySelectiveLayer(existingContent, config = {}) { // SĂ©lection automatique du LLM si 'auto' const selectedLLM = selectOptimalLLM(layerType, llmProvider); + + // 🆕 LOG: LLM sĂ©lectionnĂ© et pourquoi + if (llmProvider === 'auto') { + logSh(` đŸ€– Auto-sĂ©lection LLM: ${selectedLLM} (optimal pour ${layerType})`, 'INFO'); + } else { + logSh(` đŸ€– LLM spĂ©cifiĂ©: ${selectedLLM}`, 'DEBUG'); + } // Application selon type de couche avec configuration tendance switch (layerType) { case 'technical': + logSh(` 🔬 Branche: Technical Enhancement`, 'DEBUG'); const technicalConfig = activeTrendManager ? activeTrendManager.getLayerConfig('technical', { ...config, llmProvider: selectedLLM }) : { ...config, llmProvider: selectedLLM }; + logSh(` 📝 Config technique: LLM=${technicalConfig.llmProvider}, Intensity=${technicalConfig.intensity || 'default'}`, 'DEBUG'); const technicalResult = await applyTechnicalEnhancement(existingContent, technicalConfig); enhancedContent = technicalResult.content; layerStats = technicalResult.stats; + logSh(` ✅ Technical enhancement terminĂ©: ${layerStats.modificationsCount || 0} modifications`, 'DEBUG'); break; case 'transitions': + logSh(` 🔗 Branche: Transition Enhancement`, 'DEBUG'); const transitionConfig = activeTrendManager ? activeTrendManager.getLayerConfig('transitions', { ...config, llmProvider: selectedLLM }) : { ...config, llmProvider: selectedLLM }; + logSh(` 📝 Config transitions: LLM=${transitionConfig.llmProvider}, Intensity=${transitionConfig.intensity || 'default'}`, 'DEBUG'); const transitionResult = await applyTransitionEnhancement(existingContent, transitionConfig); enhancedContent = transitionResult.content; layerStats = transitionResult.stats; + logSh(` ✅ Transition enhancement terminĂ©: ${layerStats.modificationsCount || 0} modifications`, 'DEBUG'); break; case 'style': + logSh(` 🎹 Branche: Style Enhancement`, 'DEBUG'); const styleConfig = activeTrendManager ? activeTrendManager.getLayerConfig('style', { ...config, llmProvider: selectedLLM }) : { ...config, llmProvider: selectedLLM }; + logSh(` 📝 Config style: LLM=${styleConfig.llmProvider}, Intensity=${styleConfig.intensity || 'default'}`, 'DEBUG'); const styleResult = await applyStyleEnhancement(existingContent, styleConfig); enhancedContent = styleResult.content; layerStats = styleResult.stats; + logSh(` ✅ Style enhancement terminĂ©: ${layerStats.modificationsCount || 0} modifications`, 'DEBUG'); break; case 'all': @@ -108,6 +124,7 @@ async function applySelectiveLayer(existingContent, config = {}) { return { content: enhancedContent, stats, + modifications: stats.elementsEnhanced, // ✅ AJOUTÉ: Mapping pour PipelineExecutor original: existingContent, config: { ...config, llmProvider: selectedLLM } }; @@ -170,9 +187,9 @@ async function applyAllSelectiveLayers(content, config = {}) { }; const steps = [ - { name: 'technical', llm: 'gpt4' }, - { name: 'transitions', llm: 'gemini' }, - { name: 'style', llm: 'mistral' } + { name: 'technical', llm: 'gpt-4o-mini' }, + { name: 'transitions', llm: 'gemini-pro' }, + { name: 'style', llm: 'mistral-small' } ]; for (const step of steps) { @@ -289,13 +306,13 @@ function selectOptimalLLM(layerType, llmProvider) { if (llmProvider !== 'auto') return llmProvider; const optimalMapping = { - 'technical': 'openai', // OpenAI GPT-4 excellent pour prĂ©cision technique - 'transitions': 'gemini', // Gemini bon pour fluiditĂ© - 'style': 'mistral', // Mistral excellent pour style personnalitĂ© - 'all': 'claude' // Claude polyvalent pour tout + 'technical': 'gpt-4o-mini', // OpenAI GPT-4o Mini excellent pour prĂ©cision technique + 'transitions': 'gemini-pro', // Gemini bon pour fluiditĂ© + 'style': 'mistral-small', // Mistral excellent pour style personnalitĂ© + 'all': 'claude-sonnet-4-5' // Claude polyvalent pour tout }; - return optimalMapping[layerType] || 'claude'; + return optimalMapping[layerType] || 'claude-sonnet-4-5'; } /** diff --git a/lib/selective-enhancement/SelectiveLayers.js b/lib/selective-enhancement/SelectiveLayers.js index ff4dac3..0641960 100644 --- a/lib/selective-enhancement/SelectiveLayers.js +++ b/lib/selective-enhancement/SelectiveLayers.js @@ -17,51 +17,51 @@ const PREDEFINED_STACKS = { name: 'lightEnhancement', description: 'AmĂ©lioration technique lĂ©gĂšre avec OpenAI', layers: [ - { type: 'technical', llm: 'openai', intensity: 0.7 } + { type: 'technical', llm: 'gpt-4o-mini', intensity: 0.7 } ], layersCount: 1 }, - + // Stack standard - Technique + Transitions standardEnhancement: { name: 'standardEnhancement', description: 'AmĂ©lioration technique et style (OpenAI + Mistral)', layers: [ - { type: 'technical', llm: 'openai', intensity: 0.9 }, - { type: 'style', llm: 'mistral', intensity: 0.8 } + { type: 'technical', llm: 'gpt-4o-mini', intensity: 0.9 }, + { type: 'style', llm: 'mistral-small', intensity: 0.8 } ], layersCount: 2 }, - + // Stack complet - Toutes couches sĂ©quentielles fullEnhancement: { name: 'fullEnhancement', description: 'Enhancement complet multi-LLM (OpenAI + Mistral)', layers: [ - { type: 'technical', llm: 'openai', intensity: 1.0 }, - { type: 'style', llm: 'mistral', intensity: 0.8 } + { type: 'technical', llm: 'gpt-4o-mini', intensity: 1.0 }, + { type: 'style', llm: 'mistral-small', intensity: 0.8 } ], layersCount: 2 }, - + // Stack personnalitĂ© - Style prioritaire personalityFocus: { name: 'personalityFocus', description: 'Focus personnalitĂ© et style avec Mistral + technique lĂ©gĂšre', layers: [ - { type: 'style', llm: 'mistral', intensity: 1.2 }, - { type: 'technical', llm: 'openai', intensity: 0.6 } + { type: 'style', llm: 'mistral-small', intensity: 1.2 }, + { type: 'technical', llm: 'gpt-4o-mini', intensity: 0.6 } ], layersCount: 2 }, - + // Stack fluiditĂ© - Style prioritaire fluidityFocus: { name: 'fluidityFocus', description: 'Focus style et technique avec Mistral + OpenAI', layers: [ - { type: 'style', llm: 'mistral', intensity: 1.1 }, - { type: 'technical', llm: 'openai', intensity: 0.7 } + { type: 'style', llm: 'mistral-small', intensity: 1.1 }, + { type: 'technical', llm: 'gpt-4o-mini', intensity: 0.7 } ], layersCount: 2 } @@ -73,7 +73,7 @@ const PREDEFINED_STACKS = { async function applyPredefinedStack(content, stackName, config = {}) { return await tracer.run('SelectiveLayers.applyPredefinedStack()', async () => { const stack = PREDEFINED_STACKS[stackName]; - + if (!stack) { throw new Error(`Stack selective prĂ©dĂ©fini inconnu: ${stackName}. Disponibles: ${Object.keys(PREDEFINED_STACKS).join(', ')}`); } @@ -89,6 +89,12 @@ async function applyPredefinedStack(content, stackName, config = {}) { logSh(`📩 APPLICATION STACK SELECTIVE: ${stack.name} (${stack.layersCount} couches)`, 'INFO'); logSh(` 📊 ${Object.keys(content).length} Ă©lĂ©ments | Description: ${stack.description}`, 'INFO'); + // 🆕 LOG: DĂ©tail des couches configurĂ©es dans ce stack + logSh(` 🔍 Configuration du stack:`, 'INFO'); + stack.layers.forEach((layer, idx) => { + logSh(` Couche ${idx + 1}: ${layer.type} | LLM: ${layer.llm} | IntensitĂ©: ${layer.intensity}`, 'INFO'); + }); + try { let currentContent = content; const stackStats = { @@ -102,9 +108,16 @@ async function applyPredefinedStack(content, stackName, config = {}) { // Appliquer chaque couche sĂ©quentiellement for (let i = 0; i < stack.layers.length; i++) { const layer = stack.layers[i]; - + try { - logSh(` 🔧 Couche ${i + 1}/${stack.layersCount}: ${layer.type} (${layer.llm})`, 'DEBUG'); + logSh(`\n 🔧 === COUCHE ${i + 1}/${stack.layersCount} ===`, 'INFO'); + logSh(` Type: ${layer.type} | LLM: ${layer.llm} | IntensitĂ©: ${layer.intensity}`, 'INFO'); + logSh(` ÉlĂ©ments en entrĂ©e: ${Object.keys(currentContent).length}`, 'DEBUG'); + + // 🆕 LOG: Échantillon du contenu avant transformation + const sampleKey = Object.keys(currentContent)[0]; + const sampleBefore = currentContent[sampleKey]?.substring(0, 100) || 'N/A'; + logSh(` 📝 Échantillon AVANT (${sampleKey}): ${sampleBefore}...`, 'DEBUG'); // PrĂ©parer configuration avec support tendances const layerConfig = { @@ -118,26 +131,38 @@ async function applyPredefinedStack(content, stackName, config = {}) { // Ajouter tendance si prĂ©sente if (config.trendManager) { layerConfig.trendManager = config.trendManager; + logSh(` 🎯 Tendance active: ${config.trendManager.currentTrendId || 'none'}`, 'DEBUG'); } + const layerStartTime = Date.now(); const layerResult = await applySelectiveLayer(currentContent, layerConfig); - + const layerDuration = Date.now() - layerStartTime; + currentContent = layerResult.content; - + + // 🆕 LOG: Échantillon aprĂšs transformation + const sampleAfter = currentContent[sampleKey]?.substring(0, 100) || 'N/A'; + logSh(` 📝 Échantillon APRÈS (${sampleKey}): ${sampleAfter}...`, 'DEBUG'); + + // 🆕 LOG: RĂ©sultats dĂ©taillĂ©s de la couche + const modifications = layerResult.stats.elementsEnhanced; + const modificationRate = ((modifications / Object.keys(currentContent).length) * 100).toFixed(1); + stackStats.layers.push({ order: i + 1, type: layer.type, llm: layer.llm, intensity: layer.intensity, - elementsEnhanced: layerResult.stats.elementsEnhanced, - duration: layerResult.stats.duration, + elementsEnhanced: modifications, + duration: layerDuration, success: !layerResult.stats.fallback }); - - stackStats.totalModifications += layerResult.stats.elementsEnhanced; - stackStats.totalDuration += layerResult.stats.duration; - - logSh(` ✅ Couche ${layer.type}: ${layerResult.stats.elementsEnhanced} amĂ©liorations`, 'DEBUG'); + + stackStats.totalModifications += modifications; + stackStats.totalDuration += layerDuration; + + logSh(` ✅ RÉSULTAT: ${modifications} Ă©lĂ©ments modifiĂ©s (${modificationRate}% du total)`, 'INFO'); + logSh(` ⏱ DurĂ©e: ${layerDuration}ms`, 'DEBUG'); } catch (layerError) { logSh(` ❌ Couche ${layer.type} Ă©chouĂ©e: ${layerError.message}`, 'ERROR'); @@ -157,14 +182,25 @@ async function applyPredefinedStack(content, stackName, config = {}) { const duration = Date.now() - startTime; const successfulLayers = stackStats.layers.filter(l => l.success).length; - - logSh(`✅ STACK SELECTIVE ${stackName}: ${successfulLayers}/${stack.layersCount} couches | ${stackStats.totalModifications} modifications (${duration}ms)`, 'INFO'); - + + logSh(`\n✅ === STACK SELECTIVE ${stackName} TERMINÉ ===`, 'INFO'); + logSh(` 📊 Couches rĂ©ussies: ${successfulLayers}/${stack.layersCount}`, 'INFO'); + logSh(` 🔄 Modifications totales: ${stackStats.totalModifications}`, 'INFO'); + logSh(` ⏱ DurĂ©e totale: ${duration}ms`, 'INFO'); + + // 🆕 LOG: Tableau rĂ©capitulatif par couche + logSh(`\n 📋 RÉCAPITULATIF PAR COUCHE:`, 'INFO'); + stackStats.layers.forEach(layer => { + const status = layer.success ? '✅' : '❌'; + logSh(` ${status} Couche ${layer.order}: ${layer.type} (${layer.llm}) - ${layer.elementsEnhanced || 0} modifs en ${layer.duration}ms`, 'INFO'); + }); + await tracer.event('Stack selective appliquĂ©', { ...stackStats, totalDuration: duration }); return { content: currentContent, stats: { ...stackStats, totalDuration: duration }, + modifications: stackStats.totalModifications, // ✅ AJOUTÉ: Mapping pour PipelineExecutor original: content, stackApplied: stackName }; @@ -217,7 +253,7 @@ async function applyAdaptiveLayers(content, config = {}) { if (needsAnalysis.technical.needed && needsAnalysis.technical.score > analysisThreshold) { layersToApply.push({ type: 'technical', - llm: 'openai', + llm: 'gpt-4o-mini', intensity: Math.min(maxIntensity, needsAnalysis.technical.score * 1.2), priority: 1 }); @@ -228,7 +264,7 @@ async function applyAdaptiveLayers(content, config = {}) { if (needsAnalysis.style.needed && needsAnalysis.style.score > analysisThreshold) { layersToApply.push({ type: 'style', - llm: 'mistral', + llm: 'mistral-small', intensity: Math.min(maxIntensity, needsAnalysis.style.score), priority: 3 }); @@ -238,12 +274,13 @@ async function applyAdaptiveLayers(content, config = {}) { logSh(`✅ COUCHES ADAPTATIVES: Aucune amĂ©lioration nĂ©cessaire`, 'INFO'); return { content, - stats: { - adaptive: true, - layersApplied: 0, - analysisOnly: true, - duration: Date.now() - startTime - } + stats: { + adaptive: true, + layersApplied: 0, + analysisOnly: true, + duration: Date.now() - startTime + }, + modifications: 0 // ✅ AJOUTÉ: Mapping pour PipelineExecutor (pas de modifications) }; } @@ -306,6 +343,7 @@ async function applyAdaptiveLayers(content, config = {}) { return { content: currentContent, stats: { ...adaptiveStats, totalDuration: duration }, + modifications: adaptiveStats.totalModifications, // ✅ AJOUTÉ: Mapping pour PipelineExecutor original: content }; @@ -395,6 +433,7 @@ async function applyLayerPipeline(content, layerSequence, config = {}) { return { content: currentContent, stats: { ...pipelineStats, totalDuration: duration }, + modifications: pipelineStats.totalModifications, // ✅ AJOUTÉ: Mapping pour PipelineExecutor original: content };