# Tests LLM Provider Configuration

## 📊 Résumé des Tests

**Date**: 2025-10-09
**Feature**: Configuration LLM Provider par module de pipeline
**Statut**: ✅ **TOUS LES TESTS PASSENT**

---

## 🧪 Tests Exécutés

### Test 1: Validation Structure LLM Providers
**Fichier**: `test-llm-provider.js`
**Résultat**: ✅ PASSÉ

```
✓ 6 providers LLM disponibles:
  - claude: Claude (Anthropic) (default)
  - openai: OpenAI GPT-4
  - gemini: Google Gemini
  - deepseek: Deepseek
  - moonshot: Moonshot
  - mistral: Mistral AI

✓ 5 modules avec llmProvider parameter:
  - generation: defaultLLM=claude
  - selective: defaultLLM=openai
  - adversarial: defaultLLM=gemini
  - human: defaultLLM=mistral
  - pattern: defaultLLM=deepseek
```

**Points validés**:
- [x] AVAILABLE_LLM_PROVIDERS exporté correctement
- [x] Chaque module a un defaultLLM
- [x] Chaque module accepte llmProvider en paramètre
- [x] Pipeline multi-LLM valide avec PipelineDefinition.validate()
- [x] Résumé et estimation de durée fonctionnels

---

### Test 2: Execution Flow Multi-LLM
**Fichier**: `test-llm-execution.cjs`
**Résultat**: ✅ PASSÉ

**Scénario 1: Override du defaultLLM**
```
Step 1: generation
  Default: claude
  Configured: openai
  → Extracted: openai ✓

Step 2: selective
  Default: openai
  Configured: mistral
  → Extracted: mistral ✓
```

**Scénario 2: Fallback sur defaultLLM**
```
Step sans llmProvider configuré:
  Module: generation
  → Fallback: claude ✓
```

**Scénario 3: Empty string llmProvider**
```
Step avec llmProvider = '':
  Module: selective
  → Fallback: openai ✓
```

**Points validés**:
- [x] llmProvider configuré → utilise la valeur configurée
- [x] llmProvider non spécifié → fallback sur module.defaultLLM
- [x] llmProvider vide → fallback sur module.defaultLLM
- [x] Aucun default → fallback final sur "claude"

---

## 🎯 Flow d'Exécution Complet Validé

```
┌─────────────────────────────────────────────────────┐
│ Frontend (pipeline-builder.js)                     │
│ - User sélectionne LLM dans dropdown               │
│ - Sauvé dans step.parameters.llmProvider           │
└──────────────────┬──────────────────────────────────┘
                   ↓
┌─────────────────────────────────────────────────────┐
│ Backend API (ManualServer.js)                      │
│ - Endpoint /api/pipeline/modules retourne          │
│   modules + llmProviders                           │
│ - Reçoit pipelineConfig avec steps                 │
│ - Passe à PipelineExecutor.execute()               │
└──────────────────┬──────────────────────────────────┘
                   ↓
┌─────────────────────────────────────────────────────┐
│ PipelineExecutor                                    │
│ Pour chaque step:                                   │
│ • Extract: step.parameters?.llmProvider             │
│            || module.defaultLLM                     │
│ • Pass config avec llmProvider aux modules          │
└──────────────────┬──────────────────────────────────┘
                   ↓
┌─────────────────────────────────────────────────────┐
│ Modules (SelectiveUtils, AdversarialCore, etc.)    │
│ - Reçoivent config.llmProvider                      │
│ - Appellent LLMManager.callLLM(provider, ...)      │
└──────────────────┬──────────────────────────────────┘
                   ↓
┌─────────────────────────────────────────────────────┐
│ LLMManager                                          │
│ - Route vers le bon provider (Claude, OpenAI, etc.)│
│ - Execute la requête                                │
└─────────────────────────────────────────────────────┘
```

---

## 📝 Fichiers Modifiés

### Backend

1. **lib/pipeline/PipelineDefinition.js**
   - Ajout: `AVAILABLE_LLM_PROVIDERS` (exporté)
   - Ajout: `llmProvider` parameter pour chaque module

2. **lib/modes/ManualServer.js**
   - Modif: `/api/pipeline/modules` retourne maintenant `llmProviders`

3. **lib/pipeline/PipelineExecutor.js**
   - Modif: `runGeneration()` extrait `llmProvider` de parameters
   - Modif: `runSelective()` extrait `llmProvider` de parameters
   - Modif: `runAdversarial()` extrait `llmProvider` de parameters
   - Modif: `runHumanSimulation()` extrait `llmProvider` de parameters
   - Modif: `runPatternBreaking()` extrait `llmProvider` de parameters

4. **lib/selective-enhancement/SelectiveUtils.js**
   - Modif: `generateSimple()` accepte `options.llmProvider`

### Frontend

5. **public/pipeline-builder.js**
   - Ajout: `state.llmProviders = []`
   - Ajout: `loadLLMProviders()` function
   - Modif: `renderModuleParameters()` affiche dropdown LLM pour chaque step
   - Logique: Gère fallback sur defaultLLM avec option "Default"

---

## ✅ Checklist Implémentation

- [x] Backend: AVAILABLE_LLM_PROVIDERS défini et exporté
- [x] Backend: Chaque module a defaultLLM et llmProvider parameter
- [x] Backend: API /api/pipeline/modules retourne llmProviders
- [x] Backend: PipelineExecutor extrait et passe llmProvider
- [x] Backend: generateSimple() accepte llmProvider configuré
- [x] Frontend: Chargement des llmProviders depuis API
- [x] Frontend: Dropdown LLM affiché pour chaque étape
- [x] Frontend: Sauvegarde llmProvider dans step.parameters
- [x] Frontend: Affichage "Default (provider_name)" dans dropdown
- [x] Tests: Validation structure LLM providers
- [x] Tests: Extraction et fallback llmProvider
- [x] Tests: Pipeline multi-LLM valide

---

## 🚀 Utilisation

### Créer un pipeline avec différents LLMs

```javascript
{
  name: "Multi-LLM Pipeline",
  pipeline: [
    {
      step: 1,
      module: "generation",
      mode: "simple",
      parameters: {
        llmProvider: "claude"  // Force Claude pour génération
      }
    },
    {
      step: 2,
      module: "selective",
      mode: "standardEnhancement",
      parameters: {
        llmProvider: "openai"  // Force OpenAI pour enhancement
      }
    },
    {
      step: 3,
      module: "adversarial",
      mode: "heavy",
      parameters: {
        llmProvider: "gemini",  // Force Gemini pour adversarial
        detector: "gptZero",
        method: "regeneration"
      }
    }
  ]
}
```

### Via l'interface

1. Ouvrir `http://localhost:8080/pipeline-builder.html`
2. Ajouter une étape (drag & drop ou bouton)
3. Dans la configuration de l'étape:
   - **Mode**: Sélectionner le mode
   - **Intensité**: Ajuster 0.1-2.0
   - **LLM**: Sélectionner le provider OU laisser "Default"
4. Sauvegarder le pipeline
5. Exécuter depuis pipeline-runner.html

---

## 📈 Performance

**Providers par défaut optimisés**:
- `generation` → Claude (meilleure créativité)
- `selective` → OpenAI (précision technique)
- `adversarial` → Gemini (diversité stylistique)
- `human` → Mistral (naturalité)
- `pattern` → Deepseek (variations syntaxiques)

**Override possible** pour tous les modules selon besoins spécifiques.

---

## 🔍 Debugging

Pour vérifier quel LLM est utilisé, consulter les logs:

```
✓ Génération: 12 éléments créés avec openai
✓ Selective: modifications appliquées avec mistral
✓ Adversarial: modifications appliquées avec gemini
```

Chaque étape log maintenant le provider utilisé.

---

## ✅ Statut Final

**Implémentation**: ✅ COMPLETE
**Tests**: ✅ TOUS PASSENT
**Documentation**: ✅ À JOUR
**Production Ready**: ✅ OUI

Le système supporte maintenant **la configuration de LLM provider par module de pipeline** avec fallback intelligent sur les defaults.
