const express = require('express'); const router = express.Router(); require('dotenv').config({ path: './config/.env' }); // Configuration Mistral AI const MISTRAL_API_KEY = process.env.MISTRAL_API_KEY; const MISTRAL_BASE_URL = process.env.MISTRAL_BASE_URL || 'https://api.mistral.ai/v1'; const MISTRAL_MODEL = process.env.MISTRAL_MODEL || 'mistral-large-latest'; const AI_ENABLED = process.env.AI_ENABLED === 'true'; // Middleware de vérification function checkAIEnabled(req, res, next) { if (!AI_ENABLED) { return res.status(503).json({ success: false, error: 'Les fonctionnalités IA sont désactivées' }); } if (!MISTRAL_API_KEY) { return res.status(500).json({ success: false, error: 'Clé API Mistral non configurée' }); } next(); } // Fonction pour appeler l'API Mistral async function callMistralAPI(messages, temperature = 0.7) { try { const response = await fetch(`${MISTRAL_BASE_URL}/chat/completions`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${MISTRAL_API_KEY}` }, body: JSON.stringify({ model: MISTRAL_MODEL, messages: messages, temperature: temperature, max_tokens: parseInt(process.env.AI_MAX_TOKENS) || 4000, top_p: parseFloat(process.env.AI_TOP_P) || 0.95 }) }); if (!response.ok) { const error = await response.text(); throw new Error(`Erreur API Mistral: ${response.status} - ${error}`); } const data = await response.json(); return data.choices[0].message.content; } catch (error) { console.error('Erreur Mistral API:', error); throw error; } } // POST /api/ai/rephrase - Reformuler du texte router.post('/rephrase', checkAIEnabled, async (req, res) => { try { const { text, context = '' } = req.body; if (!text || text.trim().length === 0) { return res.status(400).json({ success: false, error: 'Texte à reformuler requis' }); } const messages = [ { role: 'system', content: `Tu es un assistant spécialisé dans la reformulation de textes techniques et de conception. RÈGLES STRICTES : 1. Reformule le texte pour améliorer la clarté, le style et la fluidité 2. Conserve le niveau technique et tous les détails importants 3. Ne réponds QUE avec le texte reformulé final 4. Aucune introduction, conclusion, explication ou commentaire 5. Ne commence pas par "Voici", "Le texte reformulé" ou autre préambule 6. Commence directement par le contenu reformulé ${context ? `Contexte du document: ${context}` : ''}` }, { role: 'user', content: `Reformule ce texte: "${text}"` } ]; const result = await callMistralAPI(messages, 0.7); res.json({ success: true, data: { original: text, rephrased: result } }); } catch (error) { console.error('Erreur reformulation:', error); res.status(500).json({ success: false, error: 'Erreur lors de la reformulation: ' + error.message }); } }); // POST /api/ai/check-inconsistencies - Vérifier les incohérences router.post('/check-inconsistencies', checkAIEnabled, async (req, res) => { try { const { content } = req.body; if (!content || content.trim().length === 0) { return res.status(400).json({ success: false, error: 'Contenu à analyser requis' }); } const messages = [ { role: 'system', content: `Tu es un expert en analyse de documents de conception technique. Analyse le document suivant et identifie toutes les incohérences potentielles : - Contradictions dans les informations - Décisions qui se contredisent - Incohérences dans la terminologie - Problèmes logiques dans l'architecture ou les choix Réponds directement avec ton analyse détaillée des incohérences trouvées.` }, { role: 'user', content: `Analyse ce document pour détecter les incohérences:\n\n${content}` } ]; const result = await callMistralAPI(messages, 0.3); res.json({ success: true, data: { analysis: result } }); } catch (error) { console.error('Erreur analyse incohérences:', error); res.status(500).json({ success: false, error: 'Erreur lors de l\'analyse: ' + error.message }); } }); // POST /api/ai/check-duplications - Vérifier les doublons router.post('/check-duplications', checkAIEnabled, async (req, res) => { try { const { content } = req.body; if (!content || content.trim().length === 0) { return res.status(400).json({ success: false, error: 'Contenu à analyser requis' }); } const messages = [ { role: 'system', content: `Tu es un expert en analyse de contenu. Analyse le document suivant pour identifier : - Les informations répétées ou redondantes - Les sections qui traitent du même sujet - Les explications dupliquées - Les concepts présentés plusieurs fois Propose des suggestions pour éliminer ces duplications tout en préservant les informations importantes. Réponds directement avec ton analyse et tes suggestions.` }, { role: 'user', content: `Analyse ce document pour détecter les duplications:\n\n${content}` } ]; const result = await callMistralAPI(messages, 0.3); res.json({ success: true, data: { analysis: result } }); } catch (error) { console.error('Erreur analyse duplications:', error); res.status(500).json({ success: false, error: 'Erreur lors de l\'analyse: ' + error.message }); } }); // POST /api/ai/give-advice - Donner des conseils router.post('/give-advice', checkAIEnabled, async (req, res) => { try { const { content, domain = 'général' } = req.body; if (!content || content.trim().length === 0) { return res.status(400).json({ success: false, error: 'Contenu à analyser requis' }); } const messages = [ { role: 'system', content: `Tu es un consultant expert en conception et architecture technique dans le domaine: ${domain}. Analyse le document de conception fourni et donne des conseils constructifs pour l'améliorer. Concentre-toi sur : - La complétude de la documentation - La clarté des explications - L'organisation du contenu - Les bonnes pratiques du domaine - Les points manquants importants - Les suggestions d'amélioration concrètes Sois constructif et pratique dans tes recommandations. Réponds directement avec tes conseils et suggestions d'amélioration.` }, { role: 'user', content: `Analyse ce document de conception et donne des conseils pour l'améliorer:\n\n${content}` } ]; const result = await callMistralAPI(messages, 0.6); res.json({ success: true, data: { advice: result } }); } catch (error) { console.error('Erreur conseils:', error); res.status(500).json({ success: false, error: 'Erreur lors de l\'analyse: ' + error.message }); } }); // POST /api/ai/liberty-mode - Mode liberté (génération créative) router.post('/liberty-mode', checkAIEnabled, async (req, res) => { try { const { content, iterations = 1, focus = 'général' } = req.body; if (!content || content.trim().length === 0) { return res.status(400).json({ success: false, error: 'Contenu de base requis' }); } const maxIterations = Math.min(parseInt(iterations), 5); // Limite à 5 itérations const results = []; for (let i = 0; i < maxIterations; i++) { const messages = [ { role: 'system', content: `Tu es un assistant créatif spécialisé en conception technique. IMPORTANT: Montre ton raisonnement en suivant cette structure: ## 🧠 Raisonnement (Itération ${i + 1}/${maxIterations}) [Explique ton processus de création et ta logique] ## 🚀 Contenu généré [Ton contenu créatif complémentaire] Basé sur le contenu existant, génère de nouvelles idées et sections qui complètent naturellement le document. Focus: ${focus} Propose des extensions créatives mais pertinentes : - Nouvelles sections logiques - Détails techniques manquants - Alternatives à considérer - Implications et conséquences - Améliorations possibles Reste cohérent avec le style et le niveau technique du document existant.` }, { role: 'user', content: `Génère du contenu complémentaire pour ce document:\n\n${content}` } ]; const result = await callMistralAPI(messages, 0.8); results.push({ iteration: i + 1, content: result }); } res.json({ success: true, data: { iterations: maxIterations, results: results } }); } catch (error) { console.error('Erreur mode liberté:', error); res.status(500).json({ success: false, error: 'Erreur lors de la génération: ' + error.message }); } }); // GET /api/ai/status - Statut de l'IA router.get('/status', (req, res) => { res.json({ success: true, data: { enabled: AI_ENABLED, model: MISTRAL_MODEL, configured: !!MISTRAL_API_KEY } }); }); module.exports = router;