🚀 Version finale avec Mode Liberté Intelligent et fonctionnalités avancées
## ✨ Nouvelles fonctionnalités majeures - Mode Liberté intelligent avec 15 itérations max et analyse itérative - Bouton Visualiser pour prévisualisation Markdown complète - Navigation table des matières corrigée et optimisée - Formatage Markdown avancé (titres, listes, code, citations, liens) - Configuration IA optimisée pour précision maximale ## 🔧 Améliorations techniques - Correction parseMarkdown manquante dans les fonctions IA - Optimisation des températures par fonction (0.1-0.4) - Nettoyage configuration .env (35k tokens, paramètres intelligents) - Suppression des paramètres inutilisés (rate limiting) - Implémentation AI_TEMPERATURE dans le code ## 📖 Documentation - README complet avec guide d'installation et utilisation - Documentation Mode Liberté intelligent - Architecture technique détaillée - Guide de configuration avancée 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
45d6344b18
commit
39a2276c66
182
assets/js/app.js
182
assets/js/app.js
@ -6,6 +6,8 @@ class ConceptionAssistant {
|
|||||||
this.undoStack = [];
|
this.undoStack = [];
|
||||||
this.redoStack = [];
|
this.redoStack = [];
|
||||||
this.tocTimer = null;
|
this.tocTimer = null;
|
||||||
|
this.isPreviewMode = false;
|
||||||
|
this.originalContent = '';
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +68,7 @@ class ConceptionAssistant {
|
|||||||
// Boutons de contrôle des journaux
|
// Boutons de contrôle des journaux
|
||||||
document.getElementById('save-journal')?.addEventListener('click', () => this.saveJournal());
|
document.getElementById('save-journal')?.addEventListener('click', () => this.saveJournal());
|
||||||
document.getElementById('load-journal')?.addEventListener('click', () => this.showJournalSelector());
|
document.getElementById('load-journal')?.addEventListener('click', () => this.showJournalSelector());
|
||||||
|
document.getElementById('preview-toggle')?.addEventListener('click', () => this.togglePreview());
|
||||||
|
|
||||||
// Table des matières
|
// Table des matières
|
||||||
document.getElementById('refresh-toc')?.addEventListener('click', () => this.generateTOC());
|
document.getElementById('refresh-toc')?.addEventListener('click', () => this.generateTOC());
|
||||||
@ -445,31 +448,47 @@ class ConceptionAssistant {
|
|||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
const line = lines[i].trim();
|
const line = lines[i].trim();
|
||||||
if (line.startsWith('#') && line.replace(/^#+\s*/, '') === title) {
|
if (line.startsWith('#') && line.replace(/^#+\s*/, '') === title) {
|
||||||
// Créer un range temporaire pour scroller vers cette ligne
|
|
||||||
const range = document.createRange();
|
|
||||||
const selection = window.getSelection();
|
|
||||||
|
|
||||||
// Calculer la position approximative du caractère
|
|
||||||
const beforeLines = lines.slice(0, i).join('\n');
|
|
||||||
const charPosition = beforeLines.length;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Créer un range au début de la ligne trouvée
|
// Approche plus simple : utiliser un élément temporaire avec une position spécifique
|
||||||
range.setStart(this.editor.childNodes[0] || this.editor, Math.min(charPosition, this.editor.textContent.length));
|
const tempElement = document.createElement('div');
|
||||||
range.collapse(true);
|
tempElement.style.position = 'absolute';
|
||||||
|
tempElement.style.visibility = 'hidden';
|
||||||
|
tempElement.style.height = '1px';
|
||||||
|
|
||||||
// Créer un élément temporaire pour le scroll
|
// Calculer la position approximative en fonction de la ligne
|
||||||
const tempElement = document.createElement('span');
|
const editorRect = this.editor.getBoundingClientRect();
|
||||||
range.insertNode(tempElement);
|
const computedStyle = window.getComputedStyle(this.editor);
|
||||||
|
const lineHeight = parseInt(computedStyle.lineHeight) || 20;
|
||||||
|
|
||||||
tempElement.scrollIntoView({
|
// Insérer l'élément temporaire dans l'éditeur
|
||||||
behavior: 'smooth',
|
this.editor.appendChild(tempElement);
|
||||||
block: 'start',
|
|
||||||
inline: 'nearest'
|
// Calculer la position de scroll basée sur le numéro de ligne
|
||||||
|
const targetPosition = i * lineHeight;
|
||||||
|
|
||||||
|
// Scroller vers la position calculée
|
||||||
|
this.editor.scrollTo({
|
||||||
|
top: targetPosition,
|
||||||
|
behavior: 'smooth'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Si l'éditeur n'a pas de scroll, utiliser le parent
|
||||||
|
if (this.editor.scrollHeight <= this.editor.clientHeight) {
|
||||||
|
const scrollContainer = this.editor.parentElement || document.documentElement;
|
||||||
|
const editorTop = this.editor.offsetTop;
|
||||||
|
|
||||||
|
scrollContainer.scrollTo({
|
||||||
|
top: editorTop + targetPosition - 100, // -100 pour un padding
|
||||||
|
behavior: 'smooth'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Nettoyer l'élément temporaire
|
// Nettoyer l'élément temporaire
|
||||||
setTimeout(() => tempElement.remove(), 100);
|
setTimeout(() => {
|
||||||
|
if (tempElement.parentNode) {
|
||||||
|
tempElement.parentNode.removeChild(tempElement);
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
|
||||||
this.showNotification('Navigation vers la section', 'success');
|
this.showNotification('Navigation vers la section', 'success');
|
||||||
return;
|
return;
|
||||||
@ -618,23 +637,30 @@ class ConceptionAssistant {
|
|||||||
// Mode liberté utilise toujours le document complet
|
// Mode liberté utilise toujours le document complet
|
||||||
result = await this.callAI('/api/ai/liberty-mode', { content: fullContent, iterations: count, focus: 'conception' });
|
result = await this.callAI('/api/ai/liberty-mode', { content: fullContent, iterations: count, focus: 'conception' });
|
||||||
|
|
||||||
// Appliquer automatiquement chaque itération au document
|
// Utiliser le contenu final mis à jour par le backend
|
||||||
let updatedContent = fullContent;
|
if (result.finalContent) {
|
||||||
result.results.forEach(iteration => {
|
this.editor.innerText = result.finalContent;
|
||||||
updatedContent += '\n\n' + iteration.content;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Appliquer les changements directement
|
|
||||||
this.editor.innerText = updatedContent;
|
|
||||||
this.generateTOC();
|
this.generateTOC();
|
||||||
this.saveState();
|
this.saveState();
|
||||||
|
}
|
||||||
|
|
||||||
|
let libertyHTML = `<strong>🚀 Mode Liberté Intelligent (${result.iterations} itérations)</strong><br><br>`;
|
||||||
|
|
||||||
|
// Vérifier si l'IA s'est arrêtée prématurément
|
||||||
|
const lastIteration = result.results[result.results.length - 1];
|
||||||
|
if (lastIteration && lastIteration.stopped) {
|
||||||
|
libertyHTML += `<p>🛑 Analyse terminée après ${result.iterations} itérations - Aucune amélioration évidente supplémentaire détectée.</p>`;
|
||||||
|
} else {
|
||||||
|
libertyHTML += `<p>✅ Les ${result.iterations} itérations d'amélioration ont été automatiquement appliquées au document.</p>`;
|
||||||
|
}
|
||||||
|
|
||||||
let libertyHTML = `<strong>🚀 Mode Liberté appliqué (${result.iterations} itérations)</strong><br><br>`;
|
|
||||||
libertyHTML += `<p>✅ Les ${result.iterations} itérations ont été automatiquement ajoutées au document.</p>`;
|
|
||||||
result.results.forEach(iteration => {
|
result.results.forEach(iteration => {
|
||||||
|
const borderColor = iteration.stopped ? 'var(--warning-color)' : 'var(--success-color)';
|
||||||
|
const icon = iteration.stopped ? '🛑' : '🎯';
|
||||||
|
|
||||||
libertyHTML += `
|
libertyHTML += `
|
||||||
<div style="background: var(--background-color); padding: 1rem; border-radius: 8px; margin: 0.5rem 0; border-left: 4px solid var(--success-color);">
|
<div style="background: var(--background-color); padding: 1rem; border-radius: 8px; margin: 0.5rem 0; border-left: 4px solid ${borderColor};">
|
||||||
<strong>Itération ${iteration.iteration} ajoutée :</strong><br><br>
|
<strong>${icon} Itération ${iteration.iteration} ${iteration.stopped ? '(Arrêt)' : '(Appliquée)'} :</strong><br><br>
|
||||||
${this.formatAIResponse(iteration.content)}
|
${this.formatAIResponse(iteration.content)}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@ -673,20 +699,21 @@ class ConceptionAssistant {
|
|||||||
const sections = text.split('##');
|
const sections = text.split('##');
|
||||||
let formattedHTML = '';
|
let formattedHTML = '';
|
||||||
|
|
||||||
|
const self = this;
|
||||||
sections.forEach((section, index) => {
|
sections.forEach((section, index) => {
|
||||||
if (index === 0 && section.trim()) {
|
if (index === 0 && section.trim()) {
|
||||||
// Première section sans titre
|
// Première section sans titre
|
||||||
formattedHTML += `<div style="margin-bottom: 1rem;">${this.parseMarkdown(section.trim())}</div>`;
|
formattedHTML += `<div style="margin-bottom: 1rem;">${self.parseMarkdown(section.trim())}</div>`;
|
||||||
} else if (section.trim()) {
|
} else if (section.trim()) {
|
||||||
const lines = section.split('\n');
|
const lines = section.split('\n');
|
||||||
const title = lines[0].trim();
|
const title = lines[0].trim();
|
||||||
const content = lines.slice(1).join('\n').trim();
|
const content = lines.slice(1).join('\n').trim();
|
||||||
|
|
||||||
// Sections normales - pas de markdown
|
// Sections normales - avec markdown
|
||||||
formattedHTML += `
|
formattedHTML += `
|
||||||
<div style="margin: 1rem 0;">
|
<div style="margin: 1rem 0;">
|
||||||
<strong>${title}</strong><br><br>
|
<strong style="color: var(--primary-color); font-size: 1.1em;">${title}</strong><br><br>
|
||||||
${content}
|
<div style="margin-top: 0.5rem;">${self.parseMarkdown(content)}</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -695,6 +722,47 @@ class ConceptionAssistant {
|
|||||||
return formattedHTML || text;
|
return formattedHTML || text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseMarkdown(text) {
|
||||||
|
if (!text) return '';
|
||||||
|
|
||||||
|
return text
|
||||||
|
// Titres H1-H6 (#, ##, ###, etc.)
|
||||||
|
.replace(/^(#{1,6})\s+(.+)$/gm, (match, hashes, title) => {
|
||||||
|
const level = hashes.length;
|
||||||
|
return `<h${level} style="color: var(--primary-color); margin: 1rem 0 0.5rem 0; font-weight: bold;">${title}</h${level}>`;
|
||||||
|
})
|
||||||
|
// Listes à puces (- ou *)
|
||||||
|
.replace(/^[\s]*[-\*]\s+(.+)$/gm, '<li style="margin: 0.25rem 0;">$1</li>')
|
||||||
|
// Listes numérotées
|
||||||
|
.replace(/^[\s]*\d+\.\s+(.+)$/gm, '<li style="margin: 0.25rem 0;">$1</li>')
|
||||||
|
// Code blocks avec ```
|
||||||
|
.replace(/```([\s\S]*?)```/g, '<pre style="background: var(--background-color); padding: 1rem; border-radius: 6px; border-left: 4px solid var(--primary-color); margin: 1rem 0; overflow-x: auto;"><code>$1</code></pre>')
|
||||||
|
// Citations avec >
|
||||||
|
.replace(/^>\s+(.+)$/gm, '<blockquote style="border-left: 4px solid var(--primary-color); padding-left: 1rem; margin: 1rem 0; font-style: italic; color: var(--text-light);">$1</blockquote>')
|
||||||
|
// Gras **texte**
|
||||||
|
.replace(/\*\*(.*?)\*\*/g, '<strong style="color: var(--primary-color);">$1</strong>')
|
||||||
|
// Italique *texte*
|
||||||
|
.replace(/\*(.*?)\*/g, '<em style="color: var(--text-light);">$1</em>')
|
||||||
|
// Code inline `code`
|
||||||
|
.replace(/`([^`]+)`/g, '<code style="background: var(--surface-color); padding: 0.2rem 0.4rem; border-radius: 3px; font-family: monospace; font-size: 0.9em;">$1</code>')
|
||||||
|
// Liens [texte](url)
|
||||||
|
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" style="color: var(--primary-color); text-decoration: underline;">$1</a>')
|
||||||
|
// Séparer les listes en blocs <ul> ou <ol>
|
||||||
|
.replace(/(<li[^>]*>.*<\/li>)/gs, (match) => {
|
||||||
|
if (match.includes('<li')) {
|
||||||
|
return `<ul style="margin: 0.5rem 0; padding-left: 1.5rem;">${match}</ul>`;
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
})
|
||||||
|
// Sauts de ligne doubles pour paragraphes
|
||||||
|
.replace(/\n\n+/g, '\n\n')
|
||||||
|
.replace(/\n\n/g, '</p><p style="margin: 0.75rem 0; line-height: 1.6;">')
|
||||||
|
// Sauts de ligne simples
|
||||||
|
.replace(/\n/g, '<br>')
|
||||||
|
// Encapsuler dans un paragraphe si pas déjà fait
|
||||||
|
.replace(/^(?!<[h1-6|ul|ol|pre|blockquote])/i, '<p style="margin: 0.75rem 0; line-height: 1.6;">')
|
||||||
|
.replace(/$/i, '</p>');
|
||||||
|
}
|
||||||
|
|
||||||
showAIFeedback(message) {
|
showAIFeedback(message) {
|
||||||
const feedback = document.getElementById('ai-assistant-feedback');
|
const feedback = document.getElementById('ai-assistant-feedback');
|
||||||
@ -894,4 +962,48 @@ function initializeTemplateForm() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
togglePreview() {
|
||||||
|
const previewBtn = document.getElementById('preview-toggle');
|
||||||
|
|
||||||
|
if (!this.isPreviewMode) {
|
||||||
|
// Passer en mode prévisualisation
|
||||||
|
this.originalContent = this.editor.innerHTML;
|
||||||
|
const markdownContent = this.editor.innerText;
|
||||||
|
|
||||||
|
// Convertir le Markdown en HTML joliment formaté
|
||||||
|
const previewHTML = this.parseMarkdown(markdownContent);
|
||||||
|
|
||||||
|
// Désactiver l'édition et appliquer le style preview
|
||||||
|
this.editor.contentEditable = false;
|
||||||
|
this.editor.innerHTML = `<div style="max-width: 800px; margin: 0 auto; padding: 2rem; line-height: 1.8; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;">${previewHTML}</div>`;
|
||||||
|
this.editor.style.background = 'var(--background-color)';
|
||||||
|
this.editor.style.border = '1px solid var(--border-color)';
|
||||||
|
this.editor.style.borderRadius = '8px';
|
||||||
|
|
||||||
|
// Changer le bouton
|
||||||
|
previewBtn.innerHTML = '✏️ Éditer';
|
||||||
|
previewBtn.classList.remove('primary');
|
||||||
|
previewBtn.classList.add('secondary');
|
||||||
|
|
||||||
|
this.isPreviewMode = true;
|
||||||
|
this.showNotification('Mode prévisualisation activé', 'success');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Revenir en mode édition
|
||||||
|
this.editor.contentEditable = true;
|
||||||
|
this.editor.innerHTML = this.originalContent;
|
||||||
|
this.editor.style.background = '';
|
||||||
|
this.editor.style.border = '';
|
||||||
|
this.editor.style.borderRadius = '';
|
||||||
|
|
||||||
|
// Changer le bouton
|
||||||
|
previewBtn.innerHTML = '👁️ Visualiser';
|
||||||
|
previewBtn.classList.remove('secondary');
|
||||||
|
previewBtn.classList.add('primary');
|
||||||
|
|
||||||
|
this.isPreviewMode = false;
|
||||||
|
this.showNotification('Mode édition activé', 'success');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -8,10 +8,6 @@ MISTRAL_BASE_URL=https://api.mistral.ai/v1
|
|||||||
|
|
||||||
# AI Features Configuration
|
# AI Features Configuration
|
||||||
AI_ENABLED=false
|
AI_ENABLED=false
|
||||||
AI_MAX_TOKENS=4000
|
AI_MAX_TOKENS=35000
|
||||||
AI_TEMPERATURE=0.7
|
AI_TEMPERATURE=0.3
|
||||||
AI_TOP_P=0.95
|
AI_TOP_P=0.85
|
||||||
|
|
||||||
# Rate Limiting for AI
|
|
||||||
AI_RATE_LIMIT_REQUESTS=10
|
|
||||||
AI_RATE_LIMIT_WINDOW=60000
|
|
@ -1 +0,0 @@
|
|||||||
#Fait moi un texte sur le fairy
|
|
@ -1,88 +0,0 @@
|
|||||||
**Spécifications Techniques – Projet Informatique**
|
|
||||||
|
|
||||||
## 1. Cadre général du projet
|
|
||||||
|
|
||||||
### 1.1 Contexte
|
|
||||||
[Résumé synthétique du projet, incluant son périmètre et sa finalité]
|
|
||||||
|
|
||||||
### 1.2 Objectifs
|
|
||||||
**Objectif principal** :
|
|
||||||
- [Description concise et orientée résultats]
|
|
||||||
|
|
||||||
**Fonctionnalités clés** :
|
|
||||||
- [Liste des éléments critiques, formulés sous forme de livrables ou de capacités]
|
|
||||||
|
|
||||||
### Description du projet
|
|
||||||
[Résumé en quelques lignes]
|
|
||||||
|
|
||||||
### Objectifs
|
|
||||||
- Objectif principal :
|
|
||||||
- Fonctionnalités clés :
|
|
||||||
|
|
||||||
## 2. Spécifications techniques
|
|
||||||
|
|
||||||
### Technologies utilisées
|
|
||||||
- **Frontend** :
|
|
||||||
- **Backend** :
|
|
||||||
- **Base de données** :
|
|
||||||
- **Outils** :
|
|
||||||
|
|
||||||
### Architecture
|
|
||||||
[Description simple de l'architecture]
|
|
||||||
|
|
||||||
## 3. Fonctionnalités
|
|
||||||
|
|
||||||
### Fonctionnalités principales
|
|
||||||
- [ ] Feature 1
|
|
||||||
- [ ] Feature 2
|
|
||||||
- [ ] Feature 3
|
|
||||||
|
|
||||||
### Fonctionnalités secondaires
|
|
||||||
- [ ] Feature A
|
|
||||||
- [ ] Feature B
|
|
||||||
|
|
||||||
## 4. Interface utilisateur
|
|
||||||
|
|
||||||
### Pages principales
|
|
||||||
- Page d'accueil :
|
|
||||||
- Page utilisateur :
|
|
||||||
- Page admin :
|
|
||||||
|
|
||||||
## 5. Base de données
|
|
||||||
|
|
||||||
### Modèles principaux
|
|
||||||
- **Utilisateur** : id, nom, email
|
|
||||||
- **Contenu** : id, titre, description
|
|
||||||
- **Session** : id, token, user_id
|
|
||||||
|
|
||||||
## 6. Planning de développement
|
|
||||||
|
|
||||||
### Sprint 1 (2 semaines)
|
|
||||||
- [ ] Setup du projet
|
|
||||||
- [ ] Authentification
|
|
||||||
- [ ] Interface de base
|
|
||||||
|
|
||||||
### Sprint 2 (2 semaines)
|
|
||||||
- [ ] CRUD principal
|
|
||||||
- [ ] Tests unitaires
|
|
||||||
- [ ] Déploiement
|
|
||||||
|
|
||||||
### Sprint 3 (2 semaines)
|
|
||||||
- [ ] Fonctionnalités avancées
|
|
||||||
- [ ] Optimisation
|
|
||||||
- [ ] Documentation
|
|
||||||
|
|
||||||
## 7. Tests et déploiement
|
|
||||||
|
|
||||||
### Tests
|
|
||||||
- [ ] Tests unitaires
|
|
||||||
- [ ] Tests d'intégration
|
|
||||||
- [ ] Tests utilisateur
|
|
||||||
|
|
||||||
### Déploiement
|
|
||||||
- **Environnement dev** :
|
|
||||||
- **Environnement prod** :
|
|
||||||
|
|
||||||
## 8. Notes techniques
|
|
||||||
|
|
||||||
[Espace pour notes de développement]
|
|
@ -1,94 +0,0 @@
|
|||||||
# Journal de Conception - Projet Informatique
|
|
||||||
|
|
||||||
## 1. Introduction
|
|
||||||
Une calculatrice
|
|
||||||
|
|
||||||
**Idée principale :**
|
|
||||||
une calculatrice que je peux accéder sur mon pc
|
|
||||||
|
|
||||||
## 2. Objectifs du projet
|
|
||||||
**Objectifs principaux :**
|
|
||||||
- [ ] Objectif 1
|
|
||||||
- [ ] Objectif 2
|
|
||||||
- [ ] Objectif 3
|
|
||||||
|
|
||||||
**Fonctionnalités clés recherchées :**
|
|
||||||
- Fonctionnalité essentielle 1
|
|
||||||
- Fonctionnalité essentielle 2
|
|
||||||
|
|
||||||
## 3. Présentation et spécifications
|
|
||||||
**Description détaillée :**
|
|
||||||
[Expliquer ce que fait le projet et ses enjeux]
|
|
||||||
|
|
||||||
**Cahier des charges :**
|
|
||||||
- **Besoin général** : [Problème à résoudre]
|
|
||||||
- **Besoins spécifiques** : [Liste des exigences]
|
|
||||||
|
|
||||||
## 4. Fonctionnalités attendues
|
|
||||||
- [ ] **Module utilisateur** : Inscription, connexion, profil
|
|
||||||
- [ ] **Module principal** : [Fonctionnalité cœur du projet]
|
|
||||||
- [ ] **Module administration** : Gestion des données
|
|
||||||
- [ ] **Module sécurité** : Authentification, autorisation
|
|
||||||
|
|
||||||
## 5. Conception globale
|
|
||||||
**Vue utilisateur :**
|
|
||||||
```
|
|
||||||
Interface Web → Authentification → Dashboard → Modules fonctionnels
|
|
||||||
```
|
|
||||||
|
|
||||||
**Architecture technique :**
|
|
||||||
```
|
|
||||||
[Client] ↔ [API REST] ↔ [Logique métier] ↔ [Base de données]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Architecture logicielle :**
|
|
||||||
- **Frontend** : React/Vue.js + CSS Framework
|
|
||||||
- **Backend** : Node.js/Python + Framework web
|
|
||||||
- **Base de données** : PostgreSQL/MongoDB
|
|
||||||
- **API** : REST ou GraphQL
|
|
||||||
|
|
||||||
## 6. Problématiques et solutions
|
|
||||||
| Problématique | Solution technique |
|
|
||||||
|---------------|-------------------|
|
|
||||||
| Performance | Cache Redis + optimisation requêtes |
|
|
||||||
| Sécurité | HTTPS + JWT + validation inputs |
|
|
||||||
| Scalabilité | Architecture microservices |
|
|
||||||
|
|
||||||
## 7. Environnement et outils
|
|
||||||
**Outils de développement :**
|
|
||||||
- IDE : VS Code / IntelliJ
|
|
||||||
- Versioning : Git + GitHub/GitLab
|
|
||||||
- Gestion projet : Jira / Trello
|
|
||||||
|
|
||||||
**Stack technique :**
|
|
||||||
- Runtime : Node.js / Python
|
|
||||||
- Framework : Express / Django
|
|
||||||
- Tests : Jest / Pytest
|
|
||||||
|
|
||||||
## 8. Phases du projet
|
|
||||||
**Phase 1 - Conception (2 semaines) :**
|
|
||||||
- [ ] Finaliser l'architecture
|
|
||||||
- [ ] Mockups des interfaces
|
|
||||||
- [ ] Setup environnement dev
|
|
||||||
|
|
||||||
**Phase 2 - Développement (6 semaines) :**
|
|
||||||
- [ ] Backend et API
|
|
||||||
- [ ] Frontend et interfaces
|
|
||||||
- [ ] Intégration continue
|
|
||||||
|
|
||||||
**Phase 3 - Tests et déploiement (2 semaines) :**
|
|
||||||
- [ ] Tests automatisés
|
|
||||||
- [ ] Déploiement production
|
|
||||||
- [ ] Documentation utilisateur
|
|
||||||
|
|
||||||
## 9. Conclusion
|
|
||||||
**État d'avancement :**
|
|
||||||
[À compléter au fur et à mesure]
|
|
||||||
|
|
||||||
**Prochaines étapes :**
|
|
||||||
- [ ] Étape prioritaire 1
|
|
||||||
- [ ] Étape prioritaire 2
|
|
||||||
|
|
||||||
---
|
|
||||||
*Journal créé le : [DATE]*
|
|
||||||
*Dernière mise à jour : [DATE]*
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"0": "936a1104-7afa-438f-b352-aa1f9294132d",
|
|
||||||
"1": "cb853f57-e578-42b4-8d39-bd71319d4d47",
|
|
||||||
"2": "d8ec4a9b-4c0f-4ea8-b374-1c85c13fd954"
|
|
||||||
}
|
|
86
routes/ai.js
86
routes/ai.js
@ -28,7 +28,7 @@ function checkAIEnabled(req, res, next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fonction pour appeler l'API Mistral
|
// Fonction pour appeler l'API Mistral
|
||||||
async function callMistralAPI(messages, temperature = 0.7) {
|
async function callMistralAPI(messages, temperature = null) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${MISTRAL_BASE_URL}/chat/completions`, {
|
const response = await fetch(`${MISTRAL_BASE_URL}/chat/completions`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -39,9 +39,9 @@ async function callMistralAPI(messages, temperature = 0.7) {
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
model: MISTRAL_MODEL,
|
model: MISTRAL_MODEL,
|
||||||
messages: messages,
|
messages: messages,
|
||||||
temperature: temperature,
|
temperature: temperature !== null ? temperature : parseFloat(process.env.AI_TEMPERATURE) || 0.3,
|
||||||
max_tokens: parseInt(process.env.AI_MAX_TOKENS) || 4000,
|
max_tokens: parseInt(process.env.AI_MAX_TOKENS) || 35000,
|
||||||
top_p: parseFloat(process.env.AI_TOP_P) || 0.95
|
top_p: parseFloat(process.env.AI_TOP_P) || 0.85
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ router.post('/rephrase', checkAIEnabled, async (req, res) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const result = await callMistralAPI(messages, 0.7);
|
const result = await callMistralAPI(messages, 0.2); // Reformulation précise
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
@ -141,7 +141,7 @@ router.post('/check-inconsistencies', checkAIEnabled, async (req, res) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const result = await callMistralAPI(messages, 0.3);
|
const result = await callMistralAPI(messages, 0.1); // Analyse précise et factuelle
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
@ -191,7 +191,7 @@ router.post('/check-duplications', checkAIEnabled, async (req, res) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const result = await callMistralAPI(messages, 0.3);
|
const result = await callMistralAPI(messages, 0.1); // Analyse précise et factuelle
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
@ -245,7 +245,7 @@ router.post('/give-advice', checkAIEnabled, async (req, res) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const result = await callMistralAPI(messages, 0.6);
|
const result = await callMistralAPI(messages, 0.4); // Conseils équilibrés
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
@ -275,54 +275,82 @@ router.post('/liberty-mode', checkAIEnabled, async (req, res) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxIterations = Math.min(parseInt(iterations), 5); // Limite à 5 itérations
|
const maxIterations = Math.min(parseInt(iterations), 15); // Limite à 15 itérations
|
||||||
const results = [];
|
const results = [];
|
||||||
|
let currentContent = content;
|
||||||
|
|
||||||
for (let i = 0; i < maxIterations; i++) {
|
for (let i = 0; i < maxIterations; i++) {
|
||||||
const messages = [
|
const messages = [
|
||||||
{
|
{
|
||||||
role: 'system',
|
role: 'system',
|
||||||
content: `Tu es un assistant créatif spécialisé en conception technique.
|
content: `Tu es un assistant créatif spécialisé en conception technique avec une approche itérative intelligente.
|
||||||
|
|
||||||
IMPORTANT: Montre ton raisonnement en suivant cette structure:
|
MISSION: Analyse le document et identifie LE PREMIER point que tu peux compléter, créer ou modifier avec plus de 90% de confiance basé sur les informations existantes dans le texte.
|
||||||
|
|
||||||
## 🧠 Raisonnement (Itération ${i + 1}/${maxIterations})
|
RÈGLES STRICTES:
|
||||||
[Explique ton processus de création et ta logique]
|
1. Ne traite qu'UN SEUL point par itération
|
||||||
|
2. Choisis le point le plus évident et logique à améliorer
|
||||||
|
3. Utilise uniquement les informations déjà présentes dans le document
|
||||||
|
4. Si rien ne peut être amélioré avec 90%+ de confiance, indique "STOP"
|
||||||
|
|
||||||
## 🚀 Contenu généré
|
STRUCTURE OBLIGATOIRE:
|
||||||
[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.
|
## 🧠 Analyse (Itération ${i + 1}/${maxIterations})
|
||||||
|
[Identifie et explique le point le plus évident à améliorer]
|
||||||
|
|
||||||
Focus: ${focus}
|
## 🎯 Point identifié
|
||||||
|
[Le point spécifique que tu vas traiter]
|
||||||
|
|
||||||
Propose des extensions créatives mais pertinentes :
|
## ✅ Amélioration
|
||||||
- Nouvelles sections logiques
|
[Le contenu précis à ajouter/modifier, avec 90%+ de confiance]
|
||||||
- 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.`
|
OU si rien ne peut être amélioré avec assez de confiance:
|
||||||
|
|
||||||
|
## 🛑 STOP
|
||||||
|
[Explication pourquoi aucune amélioration évidente n'est possible]
|
||||||
|
|
||||||
|
Focus: ${focus}`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content: `Génère du contenu complémentaire pour ce document:\n\n${content}`
|
content: `Document à analyser (Itération ${i + 1}):\n\n${currentContent}`
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const result = await callMistralAPI(messages, 0.8);
|
const result = await callMistralAPI(messages, 0.2); // Mode itératif intelligent et précis
|
||||||
|
|
||||||
|
// Vérifier si l'IA indique qu'il faut s'arrêter
|
||||||
|
if (result.toLowerCase().includes('🛑 stop') || result.toLowerCase().includes('## 🛑 stop')) {
|
||||||
results.push({
|
results.push({
|
||||||
iteration: i + 1,
|
iteration: i + 1,
|
||||||
content: result
|
content: result,
|
||||||
|
stopped: true
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extraire l'amélioration de la réponse de l'IA
|
||||||
|
let improvement = '';
|
||||||
|
const improvementMatch = result.match(/## ✅ Amélioration\s*([\s\S]*?)(?=##|$)/i);
|
||||||
|
if (improvementMatch) {
|
||||||
|
improvement = improvementMatch[1].trim();
|
||||||
|
// Mettre à jour le contenu pour la prochaine itération
|
||||||
|
currentContent += '\n\n' + improvement;
|
||||||
|
}
|
||||||
|
|
||||||
|
results.push({
|
||||||
|
iteration: i + 1,
|
||||||
|
content: result,
|
||||||
|
improvement: improvement
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: {
|
||||||
iterations: maxIterations,
|
iterations: results.length,
|
||||||
results: results
|
results: results,
|
||||||
|
finalContent: currentContent
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ function getMain() {
|
|||||||
<div id="journal-controls" style="padding: 1rem; border-bottom: 1px solid var(--border-color); display: flex; gap: 1rem; align-items: center; justify-content: center;">
|
<div id="journal-controls" style="padding: 1rem; border-bottom: 1px solid var(--border-color); display: flex; gap: 1rem; align-items: center; justify-content: center;">
|
||||||
<button id="save-journal" class="btn success">💾 Sauvegarder</button>
|
<button id="save-journal" class="btn success">💾 Sauvegarder</button>
|
||||||
<button id="load-journal" class="btn">📂 Charger</button>
|
<button id="load-journal" class="btn">📂 Charger</button>
|
||||||
|
<button id="preview-toggle" class="btn primary">👁️ Visualiser</button>
|
||||||
<span id="save-status" class="text-light"></span>
|
<span id="save-status" class="text-light"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -62,6 +63,16 @@ function getMain() {
|
|||||||
<option value="3" selected>3</option>
|
<option value="3" selected>3</option>
|
||||||
<option value="4">4</option>
|
<option value="4">4</option>
|
||||||
<option value="5">5</option>
|
<option value="5">5</option>
|
||||||
|
<option value="6">6</option>
|
||||||
|
<option value="7">7</option>
|
||||||
|
<option value="8">8</option>
|
||||||
|
<option value="9">9</option>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="11">11</option>
|
||||||
|
<option value="12">12</option>
|
||||||
|
<option value="13">13</option>
|
||||||
|
<option value="14">14</option>
|
||||||
|
<option value="15">15</option>
|
||||||
</select>
|
</select>
|
||||||
<button id="liberty-mode" class="btn" style="flex: 1;" title="Génération créative">
|
<button id="liberty-mode" class="btn" style="flex: 1;" title="Génération créative">
|
||||||
🚀 Mode Liberté
|
🚀 Mode Liberté
|
||||||
|
Loading…
x
Reference in New Issue
Block a user