
🎯 Améliorations UX critiques : - Fix curseur qui revenait au début lors de la saisie - Suppression autosauvegarde automatique - Centrage flèche bouton scroll-to-top - Mode liberté applique automatiquement les itérations 🤖 IA optimisée : - Migration vers mistral-medium classique - Suppression raisonnement IA pour réponses directes - Prompt reformulation strict (texte seul) - Routes IA complètes fonctionnelles 📚 Templates professionnels complets : - Structure 12 sections selon standards académiques/industrie - 6 domaines : informatique, math, business, design, recherche, ingénierie - 3 niveaux : simple (9 sections), détaillé, complet (12 sections) - Méthodologies spécialisées par domaine ✨ Nouvelles fonctionnalités : - Debounce TOC pour performance saisie - Navigation sections améliorée - Sauvegarde/restauration position curseur 🧠 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
350 lines
9.6 KiB
JavaScript
350 lines
9.6 KiB
JavaScript
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; |