Initial commit
This commit is contained in:
49
.gitignore
vendored
Normal file
49
.gitignore
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# ── Node.js / React ───────────────────────────────────────────────────────────
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
.next/
|
||||||
|
.nuxt/
|
||||||
|
.vite/
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# ── Python ────────────────────────────────────────────────────────────────────
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
venv/
|
||||||
|
.venv/
|
||||||
|
env/
|
||||||
|
|
||||||
|
# ── Secrets ────────────────────────────────────────────────────────────────────
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
.env.local
|
||||||
|
.env.production
|
||||||
|
secret.env
|
||||||
|
*.secret
|
||||||
|
credentials.json
|
||||||
|
|
||||||
|
# ── Logs ──────────────────────────────────────────────────────────────────────
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
|
||||||
|
# ── Modèles IA (trop lourds) ──────────────────────────────────────────────────
|
||||||
|
*.gguf
|
||||||
|
*.bin
|
||||||
|
*.safetensors
|
||||||
|
models/
|
||||||
|
|
||||||
|
# ── Cache ─────────────────────────────────────────────────────────────────────
|
||||||
|
.cache/
|
||||||
|
.parcel-cache/
|
||||||
|
.pytest_cache/
|
||||||
|
.coverage
|
||||||
|
|
||||||
|
# ── IDE ───────────────────────────────────────────────────────────────────────
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
300
DEBUG.md
Normal file
300
DEBUG.md
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
# 🔍 Guide de Debug - AI Code Assistant
|
||||||
|
|
||||||
|
## 🛠️ Outils de debug intégrés
|
||||||
|
|
||||||
|
### 1. Console du navigateur (F12)
|
||||||
|
|
||||||
|
**Ouvrir la console :**
|
||||||
|
- Windows/Linux : `F12` ou `Ctrl+Shift+I`
|
||||||
|
- Mac : `Cmd+Option+I`
|
||||||
|
|
||||||
|
**Dans l'onglet Console, tu verras :**
|
||||||
|
|
||||||
|
#### Messages normaux ✅
|
||||||
|
```
|
||||||
|
🚀 Initialisation de l'application...
|
||||||
|
📡 Réponse /models: 200
|
||||||
|
✅ Modèles chargés: 2
|
||||||
|
🔌 Tentative de connexion WebSocket à: ws://localhost:9001/ws/chat
|
||||||
|
✅ WebSocket connecté
|
||||||
|
📨 Message WebSocket: stream
|
||||||
|
✅ Réponse complète reçue
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Messages d'erreur ❌
|
||||||
|
```
|
||||||
|
❌ Erreur chargement modèles: TypeError...
|
||||||
|
❌ Erreur WebSocket: ...
|
||||||
|
🔴 Erreur React: ...
|
||||||
|
❌ Erreur rendu message: ...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Bandeau d'erreur dans l'UI
|
||||||
|
|
||||||
|
Si une erreur se produit, un bandeau rouge apparaît en haut avec :
|
||||||
|
- Le message d'erreur
|
||||||
|
- Un bouton ✕ pour fermer
|
||||||
|
|
||||||
|
### 3. Message backend non accessible
|
||||||
|
|
||||||
|
Si le backend ne répond pas, un message s'affiche au centre :
|
||||||
|
- Instructions pour démarrer le backend
|
||||||
|
- Lien vers les logs (F12)
|
||||||
|
|
||||||
|
## 🐛 Problèmes courants et solutions
|
||||||
|
|
||||||
|
### Problème 1 : UI plante quand l'IA génère du code
|
||||||
|
|
||||||
|
**Symptômes :**
|
||||||
|
- Page devient blanche/bleue
|
||||||
|
- Erreur dans la console : `Cannot read properties of undefined`
|
||||||
|
|
||||||
|
**Causes possibles :**
|
||||||
|
1. Caractère spécial non échappé dans le code
|
||||||
|
2. Balise HTML mal fermée
|
||||||
|
3. Erreur Prism.js
|
||||||
|
|
||||||
|
**Solution :**
|
||||||
|
✅ **Corrigé dans cette version !**
|
||||||
|
- Échappement HTML complet
|
||||||
|
- Try/catch autour du rendu
|
||||||
|
- Message d'erreur au lieu de crash
|
||||||
|
|
||||||
|
**Si ça arrive quand même :**
|
||||||
|
1. Ouvrir F12 → Console
|
||||||
|
2. Copier l'erreur exacte
|
||||||
|
3. Rafraîchir la page (Ctrl+F5)
|
||||||
|
4. Relancer
|
||||||
|
|
||||||
|
### Problème 2 : WebSocket ne connecte pas
|
||||||
|
|
||||||
|
**Dans la console :**
|
||||||
|
```
|
||||||
|
❌ Erreur WebSocket: ...
|
||||||
|
🔌 WebSocket déconnecté, reconnexion dans 3s...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Vérifications :**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Le backend tourne-t-il ?
|
||||||
|
curl http://localhost:9001/health
|
||||||
|
|
||||||
|
# 2. Voir les logs backend
|
||||||
|
cat /tmp/fastapi.log
|
||||||
|
|
||||||
|
# 3. Processus Python actif ?
|
||||||
|
ps aux | grep "python main.py"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Solution :**
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
. venv/bin/activate
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Tu dois voir :
|
||||||
|
```
|
||||||
|
INFO: Uvicorn running on http://0.0.0.0:9001
|
||||||
|
```
|
||||||
|
|
||||||
|
### Problème 3 : Code ne s'affiche pas correctement
|
||||||
|
|
||||||
|
**Symptômes :**
|
||||||
|
- Blocs de code sans couleur
|
||||||
|
- Caractères bizarres (< >)
|
||||||
|
|
||||||
|
**Dans la console, chercher :**
|
||||||
|
```
|
||||||
|
❌ Erreur Prism.js: ...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Solution :**
|
||||||
|
1. Rafraîchir la page (Ctrl+F5)
|
||||||
|
2. Vider le cache navigateur
|
||||||
|
3. Vérifier connexion internet (Prism.js vient du CDN)
|
||||||
|
|
||||||
|
### Problème 4 : Boutons Copier/Tester ne marchent pas
|
||||||
|
|
||||||
|
**Dans la console :**
|
||||||
|
```
|
||||||
|
❌ Erreur copyCode: ...
|
||||||
|
Élément code introuvable: code-X-Y
|
||||||
|
```
|
||||||
|
|
||||||
|
**Solution :**
|
||||||
|
✅ **Corrigé !** Les boutons ont maintenant :
|
||||||
|
- Vérification que l'élément existe
|
||||||
|
- Try/catch pour éviter les crashes
|
||||||
|
- Logs détaillés
|
||||||
|
|
||||||
|
**Test manuel :**
|
||||||
|
```javascript
|
||||||
|
// Dans la console (F12)
|
||||||
|
window.copyCode('code-0-0')
|
||||||
|
// Doit afficher une erreur claire si l'ID n'existe pas
|
||||||
|
```
|
||||||
|
|
||||||
|
### Problème 5 : Messages ne s'affichent pas
|
||||||
|
|
||||||
|
**Dans la console :**
|
||||||
|
```
|
||||||
|
❌ Erreur rendu message: ...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ce que tu verras dans l'UI :**
|
||||||
|
- Avatar ⚠️
|
||||||
|
- "Erreur d'affichage du message"
|
||||||
|
- Début du message brut
|
||||||
|
|
||||||
|
**Solution :**
|
||||||
|
1. Noter l'erreur exacte dans la console
|
||||||
|
2. Copier le message qui cause problème
|
||||||
|
3. Relancer le chat
|
||||||
|
|
||||||
|
## 📊 Workflow de debug complet
|
||||||
|
|
||||||
|
### Étape 1 : Ouvrir la console (F12)
|
||||||
|
|
||||||
|
Avant même de tester, ouvre la console pour voir les logs en temps réel.
|
||||||
|
|
||||||
|
### Étape 2 : Envoyer un message test simple
|
||||||
|
|
||||||
|
```
|
||||||
|
Écris une fonction Python qui dit bonjour
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dans la console, tu devrais voir :**
|
||||||
|
```
|
||||||
|
📨 Message WebSocket: stream
|
||||||
|
📨 Message WebSocket: stream
|
||||||
|
...
|
||||||
|
✅ Réponse complète reçue
|
||||||
|
```
|
||||||
|
|
||||||
|
### Étape 3 : Si erreur, identifier le type
|
||||||
|
|
||||||
|
#### Type 1 : Backend (réseau)
|
||||||
|
```
|
||||||
|
❌ Erreur WebSocket: ...
|
||||||
|
ou
|
||||||
|
Failed to load resource: net::ERR_CONNECTION_REFUSED
|
||||||
|
```
|
||||||
|
→ Le backend n'est pas démarré
|
||||||
|
|
||||||
|
#### Type 2 : Rendu (React)
|
||||||
|
```
|
||||||
|
🔴 Erreur React: ...
|
||||||
|
ou
|
||||||
|
❌ Erreur rendu message: ...
|
||||||
|
```
|
||||||
|
→ Problème d'affichage du contenu
|
||||||
|
|
||||||
|
#### Type 3 : Fonctions (boutons)
|
||||||
|
```
|
||||||
|
❌ Erreur copyCode: ...
|
||||||
|
```
|
||||||
|
→ Problème avec les boutons d'action
|
||||||
|
|
||||||
|
### Étape 4 : Copier les logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Dans la console (F12), clic droit → Save as...
|
||||||
|
# Ou copier manuellement les erreurs
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔬 Tests avancés
|
||||||
|
|
||||||
|
### Test 1 : Vérifier que tout est chargé
|
||||||
|
|
||||||
|
Dans la console :
|
||||||
|
```javascript
|
||||||
|
// Vérifier React
|
||||||
|
console.log('React:', typeof React); // doit afficher "object"
|
||||||
|
|
||||||
|
// Vérifier Prism
|
||||||
|
console.log('Prism:', typeof Prism); // doit afficher "object"
|
||||||
|
|
||||||
|
// Vérifier l'API
|
||||||
|
fetch('http://localhost:9001/health')
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(d => console.log('Backend:', d));
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test 2 : Vérifier WebSocket manuellement
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const ws = new WebSocket('ws://localhost:9001/ws/chat');
|
||||||
|
ws.onopen = () => console.log('WS OK');
|
||||||
|
ws.onerror = (e) => console.error('WS Error:', e);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test 3 : Tester le rendu d'un message
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Dans la console
|
||||||
|
const testMsg = {
|
||||||
|
role: 'assistant',
|
||||||
|
content: 'Test ```python\nprint("hello")\n```'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Voir si ça plante
|
||||||
|
console.log('Test:', testMsg);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 Logs à envoyer si besoin d'aide
|
||||||
|
|
||||||
|
Si tu as un problème, copie et envoie :
|
||||||
|
|
||||||
|
### 1. Logs console navigateur
|
||||||
|
```
|
||||||
|
[Tous les messages rouges ❌ et 🔴]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Logs backend
|
||||||
|
```bash
|
||||||
|
cat /tmp/fastapi.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. État du système
|
||||||
|
```bash
|
||||||
|
# Processus actifs
|
||||||
|
ps aux | grep -E "python|ollama"
|
||||||
|
|
||||||
|
# Ports utilisés
|
||||||
|
netstat -tlnp | grep -E "9000|9001"
|
||||||
|
|
||||||
|
# Version Python
|
||||||
|
python3 --version
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 Checklist avant de demander de l'aide
|
||||||
|
|
||||||
|
- [ ] Console ouverte (F12) pour voir les logs
|
||||||
|
- [ ] Backend lancé et accessible (curl http://localhost:9001/health)
|
||||||
|
- [ ] WebSocket connecté (point vert en bas à droite)
|
||||||
|
- [ ] Copié les erreurs exactes de la console
|
||||||
|
- [ ] Testé avec un message simple d'abord
|
||||||
|
- [ ] Rafraîchi la page (Ctrl+F5)
|
||||||
|
- [ ] Vidé le cache si nécessaire
|
||||||
|
|
||||||
|
## 💡 Astuces
|
||||||
|
|
||||||
|
1. **Logs en temps réel** : Laisse toujours F12 ouvert quand tu utilises l'app
|
||||||
|
2. **Preserve log** : Dans F12, coche "Preserve log" pour garder les logs même après refresh
|
||||||
|
3. **Filtre console** : Tu peux filtrer par "Error" ou "Warning" dans la console
|
||||||
|
4. **Network tab** : Onglet Network dans F12 pour voir les requêtes HTTP/WebSocket
|
||||||
|
5. **React DevTools** : Installe React DevTools pour debug React spécifiquement
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**La nouvelle version a :**
|
||||||
|
✅ Échappement HTML complet
|
||||||
|
✅ Try/catch partout
|
||||||
|
✅ Logs détaillés avec émojis
|
||||||
|
✅ Messages d'erreur clairs
|
||||||
|
✅ Bandeau d'erreur visible
|
||||||
|
✅ Pas de crash, juste des erreurs visibles
|
||||||
|
|
||||||
|
**Plus d'écran bleu ! 🎉**
|
||||||
587
EXAMPLES.md
Normal file
587
EXAMPLES.md
Normal file
@@ -0,0 +1,587 @@
|
|||||||
|
# Exemples d'utilisation - AI Code Assistant
|
||||||
|
|
||||||
|
## 🔌 Intégrations API
|
||||||
|
|
||||||
|
### 1. Utiliser l'API depuis Python
|
||||||
|
|
||||||
|
```python
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
API_URL = "http://localhost:9001"
|
||||||
|
|
||||||
|
# Exemple 1: Chat simple
|
||||||
|
def ask_ai(question, model="qwen2.5-coder:7b"):
|
||||||
|
response = requests.post(
|
||||||
|
f"{API_URL}/chat",
|
||||||
|
json={
|
||||||
|
"messages": [{"role": "user", "content": question}],
|
||||||
|
"model": model,
|
||||||
|
"stream": False
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return response.json()["response"]
|
||||||
|
|
||||||
|
# Utilisation
|
||||||
|
result = ask_ai("Écris une fonction pour valider un email")
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
|
||||||
|
# Exemple 2: Exécuter du code
|
||||||
|
def run_code(code, language="python"):
|
||||||
|
response = requests.post(
|
||||||
|
f"{API_URL}/execute",
|
||||||
|
json={"code": code, "language": language}
|
||||||
|
)
|
||||||
|
result = response.json()
|
||||||
|
|
||||||
|
if result["success"]:
|
||||||
|
return result["stdout"]
|
||||||
|
else:
|
||||||
|
return f"Erreur: {result['stderr']}"
|
||||||
|
|
||||||
|
# Utilisation
|
||||||
|
code = """
|
||||||
|
def fibonacci(n):
|
||||||
|
if n <= 1:
|
||||||
|
return n
|
||||||
|
return fibonacci(n-1) + fibonacci(n-2)
|
||||||
|
|
||||||
|
print(fibonacci(10))
|
||||||
|
"""
|
||||||
|
|
||||||
|
output = run_code(code)
|
||||||
|
print(output)
|
||||||
|
|
||||||
|
|
||||||
|
# Exemple 3: Analyse de code
|
||||||
|
def analyze_code(code, language="python"):
|
||||||
|
response = requests.post(
|
||||||
|
f"{API_URL}/analyze-code",
|
||||||
|
json={"code": code, "language": language}
|
||||||
|
)
|
||||||
|
return response.json()["analysis"]
|
||||||
|
|
||||||
|
# Utilisation
|
||||||
|
code_to_analyze = """
|
||||||
|
def divide(a, b):
|
||||||
|
return a / b
|
||||||
|
"""
|
||||||
|
|
||||||
|
analysis = analyze_code(code_to_analyze)
|
||||||
|
print(analysis)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. WebSocket en Python
|
||||||
|
|
||||||
|
```python
|
||||||
|
import asyncio
|
||||||
|
import websockets
|
||||||
|
import json
|
||||||
|
|
||||||
|
async def chat_websocket():
|
||||||
|
uri = "ws://localhost:9001/ws/chat"
|
||||||
|
|
||||||
|
async with websockets.connect(uri) as websocket:
|
||||||
|
# Envoyer un message
|
||||||
|
message = {
|
||||||
|
"message": "Explique les decorators Python",
|
||||||
|
"model": "qwen2.5-coder:7b"
|
||||||
|
}
|
||||||
|
await websocket.send(json.dumps(message))
|
||||||
|
|
||||||
|
# Recevoir la réponse en streaming
|
||||||
|
full_response = ""
|
||||||
|
while True:
|
||||||
|
response = await websocket.recv()
|
||||||
|
data = json.loads(response)
|
||||||
|
|
||||||
|
if data["type"] == "stream":
|
||||||
|
full_response += data["content"]
|
||||||
|
print(data["content"], end="", flush=True)
|
||||||
|
|
||||||
|
elif data["type"] == "done":
|
||||||
|
print("\n\nRéponse complète reçue!")
|
||||||
|
break
|
||||||
|
|
||||||
|
elif data["type"] == "error":
|
||||||
|
print(f"\nErreur: {data['content']}")
|
||||||
|
break
|
||||||
|
|
||||||
|
# Exécuter
|
||||||
|
asyncio.run(chat_websocket())
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Intégration JavaScript/Node.js
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// chat.js - Utilisation depuis Node.js
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
const API_URL = 'http://localhost:9001';
|
||||||
|
|
||||||
|
// Chat simple
|
||||||
|
async function askAI(question, model = 'qwen2.5-coder:7b') {
|
||||||
|
const response = await axios.post(`${API_URL}/chat`, {
|
||||||
|
messages: [{ role: 'user', content: question }],
|
||||||
|
model: model,
|
||||||
|
stream: false
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.data.response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exécution de code
|
||||||
|
async function executeCode(code, language = 'python') {
|
||||||
|
const response = await axios.post(`${API_URL}/execute`, {
|
||||||
|
code: code,
|
||||||
|
language: language
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utilisation
|
||||||
|
(async () => {
|
||||||
|
// Question à l'IA
|
||||||
|
const answer = await askAI('Crée une fonction pour trier un array');
|
||||||
|
console.log(answer);
|
||||||
|
|
||||||
|
// Exécuter du code
|
||||||
|
const result = await executeCode('print("Hello from AI!")');
|
||||||
|
console.log(result.stdout);
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. WebSocket depuis le navigateur
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Dans votre page HTML
|
||||||
|
const ws = new WebSocket('ws://localhost:9001/ws/chat');
|
||||||
|
|
||||||
|
ws.onopen = () => {
|
||||||
|
console.log('Connecté au serveur');
|
||||||
|
|
||||||
|
// Envoyer un message
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
message: 'Explique les promises en JavaScript',
|
||||||
|
model: 'qwen2.5-coder:7b'
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
|
||||||
|
if (data.type === 'stream') {
|
||||||
|
// Afficher le contenu au fur et à mesure
|
||||||
|
document.getElementById('response').innerHTML += data.content;
|
||||||
|
} else if (data.type === 'done') {
|
||||||
|
console.log('Réponse complète');
|
||||||
|
} else if (data.type === 'error') {
|
||||||
|
console.error('Erreur:', data.content);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onerror = (error) => {
|
||||||
|
console.error('Erreur WebSocket:', error);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ Scripts utilitaires
|
||||||
|
|
||||||
|
### Script de génération automatique de tests
|
||||||
|
|
||||||
|
```python
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Génère automatiquement des tests unitaires pour un fichier Python
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
API_URL = "http://localhost:9001"
|
||||||
|
|
||||||
|
def generate_tests(code_file):
|
||||||
|
# Lire le code
|
||||||
|
with open(code_file, 'r') as f:
|
||||||
|
code = f.read()
|
||||||
|
|
||||||
|
# Demander à l'IA de générer les tests
|
||||||
|
prompt = f"""
|
||||||
|
Génère des tests unitaires complets avec pytest pour ce code:
|
||||||
|
|
||||||
|
```python
|
||||||
|
{code}
|
||||||
|
```
|
||||||
|
|
||||||
|
Inclus:
|
||||||
|
- Tests pour tous les cas normaux
|
||||||
|
- Tests pour les cas limites
|
||||||
|
- Tests pour les erreurs attendues
|
||||||
|
- Fixtures si nécessaire
|
||||||
|
"""
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
f"{API_URL}/chat",
|
||||||
|
json={
|
||||||
|
"messages": [{"role": "user", "content": prompt}],
|
||||||
|
"model": "code-expert",
|
||||||
|
"stream": False
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
tests = response.json()["response"]
|
||||||
|
|
||||||
|
# Sauvegarder les tests
|
||||||
|
test_file = f"test_{os.path.basename(code_file)}"
|
||||||
|
|
||||||
|
# Extraire le code des blocs markdown
|
||||||
|
import re
|
||||||
|
code_blocks = re.findall(r'```python\n(.*?)```', tests, re.DOTALL)
|
||||||
|
|
||||||
|
if code_blocks:
|
||||||
|
with open(test_file, 'w') as f:
|
||||||
|
f.write(code_blocks[0])
|
||||||
|
print(f"✅ Tests générés: {test_file}")
|
||||||
|
else:
|
||||||
|
print("❌ Impossible d'extraire les tests")
|
||||||
|
print(tests)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("Usage: python generate_tests.py <fichier.py>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
generate_tests(sys.argv[1])
|
||||||
|
```
|
||||||
|
|
||||||
|
### Script de revue de code automatique
|
||||||
|
|
||||||
|
```python
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Effectue une revue de code automatique sur un fichier
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
API_URL = "http://localhost:9001"
|
||||||
|
|
||||||
|
def review_file(filepath):
|
||||||
|
# Lire le fichier
|
||||||
|
code = Path(filepath).read_text()
|
||||||
|
language = filepath.split('.')[-1]
|
||||||
|
|
||||||
|
# Analyser avec l'IA
|
||||||
|
response = requests.post(
|
||||||
|
f"{API_URL}/analyze-code",
|
||||||
|
json={"code": code, "language": language}
|
||||||
|
)
|
||||||
|
|
||||||
|
analysis = response.json()["analysis"]
|
||||||
|
|
||||||
|
# Afficher la revue
|
||||||
|
print(f"\n{'='*60}")
|
||||||
|
print(f"📝 Revue de code: {filepath}")
|
||||||
|
print(f"{'='*60}\n")
|
||||||
|
print(analysis)
|
||||||
|
print(f"\n{'='*60}\n")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("Usage: python code_review.py <fichier>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
review_file(sys.argv[1])
|
||||||
|
```
|
||||||
|
|
||||||
|
### Script de documentation automatique
|
||||||
|
|
||||||
|
```python
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Génère automatiquement de la documentation pour un fichier de code
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import sys
|
||||||
|
|
||||||
|
API_URL = "http://localhost:9001"
|
||||||
|
|
||||||
|
def generate_docs(code_file):
|
||||||
|
with open(code_file, 'r') as f:
|
||||||
|
code = f.read()
|
||||||
|
|
||||||
|
prompt = f"""
|
||||||
|
Génère une documentation complète en français pour ce code:
|
||||||
|
|
||||||
|
```python
|
||||||
|
{code}
|
||||||
|
```
|
||||||
|
|
||||||
|
Inclus:
|
||||||
|
- Description générale du module
|
||||||
|
- Documentation de chaque fonction/classe
|
||||||
|
- Exemples d'utilisation
|
||||||
|
- Notes importantes
|
||||||
|
- Format: docstrings Google style
|
||||||
|
"""
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
f"{API_URL}/chat",
|
||||||
|
json={
|
||||||
|
"messages": [{"role": "user", "content": prompt}],
|
||||||
|
"model": "code-expert",
|
||||||
|
"stream": False
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
docs = response.json()["response"]
|
||||||
|
|
||||||
|
# Sauvegarder
|
||||||
|
doc_file = f"{code_file}.md"
|
||||||
|
with open(doc_file, 'w') as f:
|
||||||
|
f.write(f"# Documentation - {code_file}\n\n")
|
||||||
|
f.write(docs)
|
||||||
|
|
||||||
|
print(f"✅ Documentation générée: {doc_file}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("Usage: python generate_docs.py <fichier.py>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
generate_docs(sys.argv[1])
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 Intégration Git Hooks
|
||||||
|
|
||||||
|
### Pre-commit hook pour revue automatique
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# .git/hooks/pre-commit
|
||||||
|
|
||||||
|
# Revue automatique des fichiers Python modifiés
|
||||||
|
|
||||||
|
echo "🔍 Revue de code automatique..."
|
||||||
|
|
||||||
|
# Trouver les fichiers Python modifiés
|
||||||
|
PYTHON_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.py$')
|
||||||
|
|
||||||
|
if [ -z "$PYTHON_FILES" ]; then
|
||||||
|
echo "Aucun fichier Python à vérifier"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Analyser chaque fichier
|
||||||
|
for file in $PYTHON_FILES; do
|
||||||
|
echo "Analyse: $file"
|
||||||
|
|
||||||
|
# Appeler l'API d'analyse
|
||||||
|
CODE=$(cat "$file")
|
||||||
|
ANALYSIS=$(curl -s -X POST http://localhost:9001/analyze-code \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"code\": $(echo "$CODE" | jq -Rs .), \"language\": \"python\"}" \
|
||||||
|
| jq -r '.analysis')
|
||||||
|
|
||||||
|
# Vérifier si des problèmes critiques sont détectés
|
||||||
|
if echo "$ANALYSIS" | grep -qi "CRITIQUE\|ERREUR\|BUG"; then
|
||||||
|
echo "⚠️ Problèmes détectés dans $file:"
|
||||||
|
echo "$ANALYSIS"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
read -p "Voulez-vous continuer le commit ? (o/n) " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Oo]$ ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "✅ Revue terminée"
|
||||||
|
exit 0
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 Cas d'usage avancés
|
||||||
|
|
||||||
|
### 1. Assistant de refactoring
|
||||||
|
|
||||||
|
```python
|
||||||
|
def refactor_code(code, instructions):
|
||||||
|
prompt = f"""
|
||||||
|
Code actuel:
|
||||||
|
```python
|
||||||
|
{code}
|
||||||
|
```
|
||||||
|
|
||||||
|
Instructions de refactoring: {instructions}
|
||||||
|
|
||||||
|
Fournis le code refactoré en suivant les best practices.
|
||||||
|
"""
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
f"{API_URL}/chat",
|
||||||
|
json={
|
||||||
|
"messages": [{"role": "user", "content": prompt}],
|
||||||
|
"model": "code-expert",
|
||||||
|
"stream": False
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return response.json()["response"]
|
||||||
|
|
||||||
|
# Exemple
|
||||||
|
old_code = """
|
||||||
|
def calc(x, y, op):
|
||||||
|
if op == '+':
|
||||||
|
return x + y
|
||||||
|
elif op == '-':
|
||||||
|
return x - y
|
||||||
|
elif op == '*':
|
||||||
|
return x * y
|
||||||
|
elif op == '/':
|
||||||
|
return x / y
|
||||||
|
"""
|
||||||
|
|
||||||
|
refactored = refactor_code(old_code, "Utilise un dict avec des lambdas")
|
||||||
|
print(refactored)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Générateur de migrations DB
|
||||||
|
|
||||||
|
```python
|
||||||
|
def generate_migration(old_schema, new_schema):
|
||||||
|
prompt = f"""
|
||||||
|
Ancien schéma:
|
||||||
|
{old_schema}
|
||||||
|
|
||||||
|
Nouveau schéma:
|
||||||
|
{new_schema}
|
||||||
|
|
||||||
|
Génère une migration Alembic pour passer de l'ancien au nouveau schéma.
|
||||||
|
"""
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
f"{API_URL}/chat",
|
||||||
|
json={
|
||||||
|
"messages": [{"role": "user", "content": prompt}],
|
||||||
|
"model": "code-expert",
|
||||||
|
"stream": False
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return response.json()["response"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Détection de code dupliqué
|
||||||
|
|
||||||
|
```python
|
||||||
|
def find_duplicates(project_dir):
|
||||||
|
import os
|
||||||
|
|
||||||
|
files_content = {}
|
||||||
|
|
||||||
|
# Lire tous les fichiers Python
|
||||||
|
for root, dirs, files in os.walk(project_dir):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith('.py'):
|
||||||
|
filepath = os.path.join(root, file)
|
||||||
|
with open(filepath, 'r') as f:
|
||||||
|
files_content[filepath] = f.read()
|
||||||
|
|
||||||
|
# Demander à l'IA d'analyser
|
||||||
|
prompt = f"""
|
||||||
|
Analyse ces fichiers et identifie le code dupliqué:
|
||||||
|
|
||||||
|
{json.dumps(files_content, indent=2)}
|
||||||
|
|
||||||
|
Liste:
|
||||||
|
1. Les blocs de code dupliqués
|
||||||
|
2. Les fonctions similaires qui pourraient être mutualisées
|
||||||
|
3. Des suggestions de refactoring
|
||||||
|
"""
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
f"{API_URL}/chat",
|
||||||
|
json={
|
||||||
|
"messages": [{"role": "user", "content": prompt}],
|
||||||
|
"model": "code-expert",
|
||||||
|
"stream": False
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return response.json()["response"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📱 Intégration VS Code
|
||||||
|
|
||||||
|
### Extension VS Code custom
|
||||||
|
|
||||||
|
```json
|
||||||
|
// .vscode/tasks.json
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "AI Code Review",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "python",
|
||||||
|
"args": [
|
||||||
|
"${workspaceFolder}/scripts/code_review.py",
|
||||||
|
"${file}"
|
||||||
|
],
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "new"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Generate Tests",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "python",
|
||||||
|
"args": [
|
||||||
|
"${workspaceFolder}/scripts/generate_tests.py",
|
||||||
|
"${file}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔥 Performance Tips
|
||||||
|
|
||||||
|
### Batch processing de fichiers
|
||||||
|
|
||||||
|
```python
|
||||||
|
async def analyze_multiple_files(files):
|
||||||
|
import aiohttp
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
tasks = []
|
||||||
|
|
||||||
|
for filepath in files:
|
||||||
|
with open(filepath, 'r') as f:
|
||||||
|
code = f.read()
|
||||||
|
|
||||||
|
task = session.post(
|
||||||
|
f"{API_URL}/analyze-code",
|
||||||
|
json={"code": code, "language": "python"}
|
||||||
|
)
|
||||||
|
tasks.append(task)
|
||||||
|
|
||||||
|
results = await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
return [await r.json() for r in results]
|
||||||
|
|
||||||
|
# Utilisation
|
||||||
|
files = ['file1.py', 'file2.py', 'file3.py']
|
||||||
|
results = asyncio.run(analyze_multiple_files(files))
|
||||||
|
```
|
||||||
|
|
||||||
|
Bon coding avec votre assistant IA ! 🚀
|
||||||
53
FEATURES.md
Normal file
53
FEATURES.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# 🎨 Nouvelles fonctionnalités - Coloration syntaxique
|
||||||
|
|
||||||
|
## ✨ Améliorations apportées
|
||||||
|
|
||||||
|
### 1. 📋 Blocs de code colorés
|
||||||
|
Tous les langages sont supportés avec coloration :
|
||||||
|
- Python, JavaScript, TypeScript, JSX, TSX
|
||||||
|
- HTML, CSS, JSON, YAML, Markdown
|
||||||
|
- Bash, SQL, Java, C, C++, Go, Rust, PHP, Ruby
|
||||||
|
|
||||||
|
### 2. 🎯 Boutons sur chaque bloc
|
||||||
|
- **📋 Copier** : Copie dans le presse-papier
|
||||||
|
- **▶ Tester** : Ouvre l'éditeur avec le code
|
||||||
|
|
||||||
|
### 3. 💻 Éditeur amélioré
|
||||||
|
- Sélecteur de langage
|
||||||
|
- Bouton "Effacer"
|
||||||
|
- Meilleur design
|
||||||
|
- Sortie colorée (vert=succès, rouge=erreur)
|
||||||
|
|
||||||
|
## 🧪 Tester maintenant
|
||||||
|
|
||||||
|
### Prompt 1 : Python
|
||||||
|
```
|
||||||
|
Écris une fonction Python pour calculer Fibonacci
|
||||||
|
```
|
||||||
|
|
||||||
|
### Prompt 2 : React
|
||||||
|
```
|
||||||
|
Crée un compteur React avec hooks
|
||||||
|
```
|
||||||
|
|
||||||
|
### Prompt 3 : Multiple
|
||||||
|
```
|
||||||
|
Crée une todo list avec HTML, CSS et JavaScript
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎨 Couleurs
|
||||||
|
|
||||||
|
- **Violet** : Mots-clés (def, if, async)
|
||||||
|
- **Vert** : Strings
|
||||||
|
- **Bleu** : Fonctions
|
||||||
|
- **Rouge** : Nombres
|
||||||
|
- **Jaune** : Opérateurs
|
||||||
|
|
||||||
|
## 💡 Utilisation
|
||||||
|
|
||||||
|
1. Demander du code à l'IA
|
||||||
|
2. Code affiché avec coloration
|
||||||
|
3. Cliquer "📋 Copier" ou "▶ Tester"
|
||||||
|
4. Si "Tester" : modifier et exécuter
|
||||||
|
|
||||||
|
🎉 Profitez de votre éditeur coloré !
|
||||||
1079
IA-Locale-Code-WSL.md
Normal file
1079
IA-Locale-Code-WSL.md
Normal file
File diff suppressed because it is too large
Load Diff
338
INSTALL.md
Normal file
338
INSTALL.md
Normal file
@@ -0,0 +1,338 @@
|
|||||||
|
# 🤖 AI Code Assistant - Interface Web Complète
|
||||||
|
|
||||||
|
**Interface web locale style Claude avec FastAPI + React pour développement assisté par IA**
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 Contenu du package
|
||||||
|
|
||||||
|
```
|
||||||
|
ai-code-assistant/
|
||||||
|
├── 📖 README.md # Ce fichier
|
||||||
|
├── 📖 QUICKSTART.md # Guide de démarrage rapide
|
||||||
|
├── 📖 IA-Locale-Code-WSL.md # Guide complet d'installation Ollama sur WSL
|
||||||
|
├── 📖 EXAMPLES.md # Exemples d'utilisation avancée
|
||||||
|
│
|
||||||
|
├── 🔧 backend/
|
||||||
|
│ ├── main.py # Serveur FastAPI avec WebSocket
|
||||||
|
│ └── requirements.txt # Dépendances Python
|
||||||
|
│
|
||||||
|
├── 🎨 frontend/
|
||||||
|
│ └── index.html # Interface React complète (SPA)
|
||||||
|
│
|
||||||
|
├── 🚀 start.sh # Script de démarrage automatique
|
||||||
|
└── 🛑 stop.sh # Script d'arrêt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ Fonctionnalités principales
|
||||||
|
|
||||||
|
### 💬 Chat IA en temps réel
|
||||||
|
- Communication WebSocket avec streaming
|
||||||
|
- Réponses progressives token par token
|
||||||
|
- Support multi-modèles Ollama
|
||||||
|
- Historique des conversations
|
||||||
|
- Interface moderne style Claude
|
||||||
|
|
||||||
|
### 💻 Éditeur de code intégré
|
||||||
|
- Éditeur Python avec coloration syntaxique
|
||||||
|
- Exécution de code en temps réel
|
||||||
|
- Affichage des résultats et erreurs
|
||||||
|
- Copie facile des blocs de code
|
||||||
|
|
||||||
|
### 🎨 Design moderne
|
||||||
|
- Interface sombre avec effets de glassmorphisme
|
||||||
|
- Animations fluides et micro-interactions
|
||||||
|
- Typographie soignée (Space Grotesk + JetBrains Mono)
|
||||||
|
- Responsive design
|
||||||
|
- Grain texture overlay pour un aspect premium
|
||||||
|
|
||||||
|
### 🔌 API REST complète
|
||||||
|
- Chat synchrone et asynchrone
|
||||||
|
- Exécution de code (Python, JS, Bash)
|
||||||
|
- Analyse de code avec IA
|
||||||
|
- Correction automatique de bugs
|
||||||
|
- Liste des modèles disponibles
|
||||||
|
- Health check endpoint
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Installation ultra-rapide
|
||||||
|
|
||||||
|
### Prérequis
|
||||||
|
- **WSL2** avec Ubuntu 22.04+
|
||||||
|
- **Python 3.10+**
|
||||||
|
- **Ollama** installé
|
||||||
|
- **GPU NVIDIA** 8GB+ (optionnel mais recommandé)
|
||||||
|
|
||||||
|
### En 3 commandes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Extraire l'archive
|
||||||
|
unzip ai-code-assistant.zip
|
||||||
|
cd ai-code-assistant
|
||||||
|
|
||||||
|
# 2. Télécharger un modèle
|
||||||
|
ollama pull qwen2.5-coder:7b
|
||||||
|
|
||||||
|
# 3. Lancer l'application
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**C'est tout !** Ouvrez http://localhost:9000 dans votre navigateur 🎉
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Documentation
|
||||||
|
|
||||||
|
### 📖 Guides disponibles
|
||||||
|
|
||||||
|
1. **QUICKSTART.md** - Démarrage en 5 minutes
|
||||||
|
- Installation rapide
|
||||||
|
- Premiers tests
|
||||||
|
- Commandes essentielles
|
||||||
|
- Dépannage rapide
|
||||||
|
|
||||||
|
2. **README.md** (dans le dossier) - Documentation complète
|
||||||
|
- Architecture détaillée
|
||||||
|
- Configuration avancée
|
||||||
|
- API endpoints
|
||||||
|
- Personnalisation
|
||||||
|
|
||||||
|
3. **IA-Locale-Code-WSL.md** - Installation Ollama complète
|
||||||
|
- Configuration WSL2 + GPU
|
||||||
|
- Installation Ollama
|
||||||
|
- Création de modèles personnalisés
|
||||||
|
- Optimisations avancées
|
||||||
|
|
||||||
|
4. **EXAMPLES.md** - Exemples d'intégration
|
||||||
|
- Utilisation de l'API en Python
|
||||||
|
- WebSocket avancé
|
||||||
|
- Scripts utilitaires
|
||||||
|
- Intégration Git hooks
|
||||||
|
- VS Code integration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Utilisation
|
||||||
|
|
||||||
|
### Interface Web
|
||||||
|
|
||||||
|
1. **Lancer**: `./start.sh`
|
||||||
|
2. **Ouvrir**: http://localhost:9000
|
||||||
|
3. **Discuter** avec l'IA dans la zone de chat
|
||||||
|
4. **Cliquer sur "Code"** pour ouvrir l'éditeur
|
||||||
|
5. **Tester du code** directement dans le navigateur
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
|
```python
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# Chat simple
|
||||||
|
response = requests.post('http://localhost:9001/chat', json={
|
||||||
|
"messages": [{"role": "user", "content": "Écris une fonction de tri"}],
|
||||||
|
"model": "qwen2.5-coder:7b",
|
||||||
|
"stream": False
|
||||||
|
})
|
||||||
|
print(response.json()['response'])
|
||||||
|
|
||||||
|
# Exécuter du code
|
||||||
|
response = requests.post('http://localhost:9001/execute', json={
|
||||||
|
"code": "print('Hello AI!')",
|
||||||
|
"language": "python"
|
||||||
|
})
|
||||||
|
print(response.json()['stdout'])
|
||||||
|
```
|
||||||
|
|
||||||
|
### WebSocket (temps réel)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const ws = new WebSocket('ws://localhost:9001/ws/chat');
|
||||||
|
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
if (data.type === 'stream') {
|
||||||
|
console.log(data.content); // Affiche token par token
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
message: 'Explique les closures',
|
||||||
|
model: 'qwen2.5-coder:7b'
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Captures d'écran
|
||||||
|
|
||||||
|
L'interface offre:
|
||||||
|
- **Chat fluide** avec réponses en streaming
|
||||||
|
- **Syntaxe highlighting** pour le code
|
||||||
|
- **Boutons d'action** (Copier, Tester) sur les blocs de code
|
||||||
|
- **Éditeur latéral** qui s'ouvre en un clic
|
||||||
|
- **Design dark mode** avec accents violets
|
||||||
|
- **Animations subtiles** et professionnelles
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Configuration
|
||||||
|
|
||||||
|
### Changer le modèle par défaut
|
||||||
|
|
||||||
|
Éditer `frontend/index.html`:
|
||||||
|
```javascript
|
||||||
|
const [selectedModel, setSelectedModel] = useState('votre-modele');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Changer les couleurs
|
||||||
|
|
||||||
|
Éditer `frontend/index.html`, section CSS:
|
||||||
|
```css
|
||||||
|
:root {
|
||||||
|
--accent-primary: #7c3aed; /* Couleur principale */
|
||||||
|
--accent-secondary: #a78bfa; /* Couleur secondaire */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ajouter des langages
|
||||||
|
|
||||||
|
Éditer `backend/main.py`, fonction `execute_code`:
|
||||||
|
```python
|
||||||
|
elif request.language == "ruby":
|
||||||
|
result = subprocess.run(['ruby', temp_file], ...)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📡 Endpoints API
|
||||||
|
|
||||||
|
| Endpoint | Méthode | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `/` | GET | Info API |
|
||||||
|
| `/models` | GET | Liste des modèles |
|
||||||
|
| `/chat` | POST | Chat (streaming ou non) |
|
||||||
|
| `/ws/chat` | WebSocket | Chat temps réel |
|
||||||
|
| `/execute` | POST | Exécuter du code |
|
||||||
|
| `/analyze-code` | POST | Analyser du code |
|
||||||
|
| `/fix-code` | POST | Corriger du code |
|
||||||
|
| `/health` | GET | Health check |
|
||||||
|
|
||||||
|
Voir **EXAMPLES.md** pour des exemples détaillés.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐛 Dépannage
|
||||||
|
|
||||||
|
### Backend ne démarre pas
|
||||||
|
```bash
|
||||||
|
# Vérifier les logs
|
||||||
|
cat /tmp/fastapi.log
|
||||||
|
|
||||||
|
# Vérifier le port
|
||||||
|
lsof -i :8000
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ollama non accessible
|
||||||
|
```bash
|
||||||
|
# Redémarrer Ollama
|
||||||
|
pkill ollama
|
||||||
|
ollama serve &
|
||||||
|
```
|
||||||
|
|
||||||
|
### WebSocket déconnecté
|
||||||
|
```bash
|
||||||
|
# Vérifier la connexion
|
||||||
|
curl http://localhost:9001/health
|
||||||
|
```
|
||||||
|
|
||||||
|
Pour plus de détails, voir **QUICKSTART.md** section Dépannage.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Fonctionnalités à venir
|
||||||
|
|
||||||
|
- [ ] Sauvegarde des conversations
|
||||||
|
- [ ] Export markdown/PDF
|
||||||
|
- [ ] Support multi-langages (JS, Go, Rust)
|
||||||
|
- [ ] Debugger visuel
|
||||||
|
- [ ] Intégration Git
|
||||||
|
- [ ] Génération de tests automatique
|
||||||
|
- [ ] RAG sur votre codebase
|
||||||
|
- [ ] Thèmes personnalisables
|
||||||
|
- [ ] Mode collaboration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Performance
|
||||||
|
|
||||||
|
Sur un GPU NVIDIA 8GB:
|
||||||
|
- **Latence**: < 100ms première réponse
|
||||||
|
- **Débit**: 40-60 tokens/sec
|
||||||
|
- **RAM**: ~2-3 GB
|
||||||
|
- **VRAM**: ~5-6 GB (selon le modèle)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🤝 Contribution
|
||||||
|
|
||||||
|
Suggestions et améliorations bienvenues !
|
||||||
|
|
||||||
|
Structure claire:
|
||||||
|
- **Backend FastAPI** modulaire
|
||||||
|
- **Frontend React** en SPA (single file)
|
||||||
|
- **WebSocket** pour temps réel
|
||||||
|
- **API REST** standard
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Licence
|
||||||
|
|
||||||
|
Projet open source - Utilisation libre
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🙏 Crédits
|
||||||
|
|
||||||
|
- **Ollama** - Modèles LLM locaux
|
||||||
|
- **FastAPI** - Framework backend
|
||||||
|
- **React** - Interface utilisateur
|
||||||
|
- **Anthropic Claude** - Inspiration design
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📞 Support
|
||||||
|
|
||||||
|
Pour toute question:
|
||||||
|
1. Consulter **QUICKSTART.md** pour les problèmes courants
|
||||||
|
2. Vérifier **EXAMPLES.md** pour les cas d'usage
|
||||||
|
3. Lire la doc Ollama: https://ollama.ai/docs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Développé avec ❤️ pour le développement assisté par IA en local**
|
||||||
|
|
||||||
|
🚀 **Commencez maintenant**: `./start.sh` et ouvrez http://localhost:9000
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Checklist de démarrage
|
||||||
|
|
||||||
|
- [ ] WSL2 installé et fonctionnel
|
||||||
|
- [ ] Python 3.10+ disponible
|
||||||
|
- [ ] Ollama installé (`ollama --version`)
|
||||||
|
- [ ] Modèle téléchargé (`ollama list`)
|
||||||
|
- [ ] GPU NVIDIA détecté (`nvidia-smi`) - optionnel
|
||||||
|
- [ ] Fichiers extraits et scripts exécutables
|
||||||
|
- [ ] Port 8000 et 8080 libres
|
||||||
|
- [ ] `./start.sh` lancé avec succès
|
||||||
|
- [ ] Interface accessible sur http://localhost:9000
|
||||||
|
|
||||||
|
✅ **Tout est OK ?** Profitez de votre assistant IA local !
|
||||||
159
LANGUAGES.md
Normal file
159
LANGUAGES.md
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
# 🎨 Langages supportés - Coloration syntaxique
|
||||||
|
|
||||||
|
## ✅ Langages avec coloration complète
|
||||||
|
|
||||||
|
### Web Frontend
|
||||||
|
- ✅ **HTML** (`html`, `markup`)
|
||||||
|
- ✅ **CSS** (`css`)
|
||||||
|
- ✅ **JavaScript** (`js`, `javascript`)
|
||||||
|
- ✅ **TypeScript** (`ts`, `typescript`)
|
||||||
|
- ✅ **JSX** (`jsx`) - React
|
||||||
|
- ✅ **TSX** (`tsx`) - React TypeScript
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- ✅ **Python** (`python`, `py`)
|
||||||
|
- ✅ **Java** (`java`)
|
||||||
|
- ✅ **C** (`c`)
|
||||||
|
- ✅ **C++** (`cpp`, `c++`)
|
||||||
|
- ✅ **Go** (`go`)
|
||||||
|
- ✅ **Rust** (`rust`, `rs`)
|
||||||
|
|
||||||
|
### Database & Config
|
||||||
|
- ✅ **SQL** (`sql`)
|
||||||
|
- ✅ **JSON** (`json`)
|
||||||
|
- ✅ **YAML** (`yaml`, `yml`)
|
||||||
|
- ✅ **Markdown** (`markdown`, `md`)
|
||||||
|
|
||||||
|
### Scripting
|
||||||
|
- ✅ **Bash** (`bash`, `sh`, `shell`)
|
||||||
|
|
||||||
|
## ❌ Langages NON supportés (sans coloration)
|
||||||
|
|
||||||
|
- ❌ **PHP** - Retiré car cause des crashes
|
||||||
|
- ❌ **Ruby** - Retiré pour stabilité
|
||||||
|
|
||||||
|
**Note** : Ces langages s'afficheront quand même, mais sans coloration syntaxique.
|
||||||
|
|
||||||
|
## 🧪 Tester les langages
|
||||||
|
|
||||||
|
### Python
|
||||||
|
```
|
||||||
|
Écris une fonction Python pour calculer Fibonacci
|
||||||
|
```
|
||||||
|
|
||||||
|
### JavaScript
|
||||||
|
```
|
||||||
|
Crée une fonction async/await pour fetch des données
|
||||||
|
```
|
||||||
|
|
||||||
|
### React (JSX)
|
||||||
|
```
|
||||||
|
Crée un composant React avec useState
|
||||||
|
```
|
||||||
|
|
||||||
|
### TypeScript
|
||||||
|
```
|
||||||
|
Écris une interface TypeScript pour un User
|
||||||
|
```
|
||||||
|
|
||||||
|
### SQL
|
||||||
|
```
|
||||||
|
Écris une requête SQL pour les 10 meilleurs clients
|
||||||
|
```
|
||||||
|
|
||||||
|
### JSON
|
||||||
|
```
|
||||||
|
Crée un exemple de configuration JSON pour une API
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTML/CSS
|
||||||
|
```
|
||||||
|
Crée un bouton stylé en HTML et CSS
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bash
|
||||||
|
```
|
||||||
|
Écris un script bash pour sauvegarder des fichiers
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎨 Couleurs par langage
|
||||||
|
|
||||||
|
Tous les langages utilisent le même schéma de couleurs :
|
||||||
|
|
||||||
|
| Type | Couleur | Exemple |
|
||||||
|
|------|---------|---------|
|
||||||
|
| Mots-clés | 🟣 Violet | `def`, `if`, `const`, `async` |
|
||||||
|
| Strings | 🟢 Vert | `"hello"`, `'world'` |
|
||||||
|
| Fonctions | 🔵 Bleu | `print()`, `fetch()` |
|
||||||
|
| Nombres | 🔴 Rouge | `42`, `3.14` |
|
||||||
|
| Commentaires | ⚪ Gris | `# comment`, `// comment` |
|
||||||
|
| Opérateurs | 🟡 Jaune | `+`, `-`, `=`, `=>` |
|
||||||
|
|
||||||
|
## 💡 Astuces
|
||||||
|
|
||||||
|
### 1. Spécifier le langage
|
||||||
|
|
||||||
|
L'IA détecte automatiquement, mais tu peux préciser :
|
||||||
|
```
|
||||||
|
Écris en JavaScript pur (pas TypeScript) une fonction...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Multi-langages
|
||||||
|
|
||||||
|
Pour avoir plusieurs blocs :
|
||||||
|
```
|
||||||
|
Crée une todo app avec HTML, CSS et JavaScript séparés
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Code sans langage
|
||||||
|
|
||||||
|
Si pas de langage détecté, le code s'affiche sans coloration mais reste lisible.
|
||||||
|
|
||||||
|
## 🔧 Problèmes de coloration
|
||||||
|
|
||||||
|
### Code affiché mais pas coloré ?
|
||||||
|
|
||||||
|
**Console (F12) :**
|
||||||
|
```
|
||||||
|
⚠️ Prism.js non chargé
|
||||||
|
ou
|
||||||
|
❌ Erreur coloration bloc X: ...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Solutions :**
|
||||||
|
1. Rafraîchir (Ctrl+F5)
|
||||||
|
2. Vérifier connexion internet
|
||||||
|
3. Vider cache navigateur
|
||||||
|
|
||||||
|
### Crash lors de la coloration ?
|
||||||
|
|
||||||
|
**Symptôme :** WebSocket se déconnecte après génération de code
|
||||||
|
|
||||||
|
**Dans la console :**
|
||||||
|
```
|
||||||
|
❌ Erreur Prism.highlightElement: ...
|
||||||
|
🔌 WebSocket déconnecté
|
||||||
|
```
|
||||||
|
|
||||||
|
**Solution :**
|
||||||
|
✅ **Déjà corrigé !**
|
||||||
|
- Chaque bloc est colorié individuellement
|
||||||
|
- En cas d'erreur, le bloc reste visible sans coloration
|
||||||
|
- Le crash d'un bloc n'affecte pas les autres
|
||||||
|
|
||||||
|
## 📊 Statistiques
|
||||||
|
|
||||||
|
- **16 langages** avec coloration complète
|
||||||
|
- **20+ variantes** de syntaxe (py/python, js/javascript, etc.)
|
||||||
|
- **0 crash** même si un langage pose problème
|
||||||
|
- **Fallback automatique** si Prism.js ne charge pas
|
||||||
|
|
||||||
|
## 🚀 Performances
|
||||||
|
|
||||||
|
- Coloration en ~150ms
|
||||||
|
- Pas de ralentissement même avec plusieurs blocs
|
||||||
|
- Timeout de sécurité pour éviter le gel
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Si tu demandes du PHP ou Ruby, le code s'affichera sans coloration mais sera parfaitement lisible !**
|
||||||
214
QUICK-COMMANDS.md
Normal file
214
QUICK-COMMANDS.md
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
# 🚀 Commandes rapides - START ICI
|
||||||
|
|
||||||
|
## ⚡ Démarrage rapide (3 commandes)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Aller dans le dossier
|
||||||
|
cd /mnt/e/My\ IA
|
||||||
|
|
||||||
|
# 2. Tuer l'ancien processus sur le port 9001 (si existant)
|
||||||
|
fuser -k 9001/tcp 2>/dev/null
|
||||||
|
|
||||||
|
# 3. Tout lancer
|
||||||
|
bash start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ouvrir dans le navigateur** : http://localhost:9000
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔥 Si le script ne marche pas : Lancement manuel
|
||||||
|
|
||||||
|
### Terminal 1 : Backend
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /mnt/e/My\ IA/backend
|
||||||
|
|
||||||
|
# Créer venv si pas fait
|
||||||
|
python3 -m venv venv
|
||||||
|
|
||||||
|
# Activer
|
||||||
|
. venv/bin/activate
|
||||||
|
|
||||||
|
# Installer dépendances
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
# LANCER
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Tu verras :
|
||||||
|
```
|
||||||
|
INFO: Uvicorn running on http://0.0.0.0:9001
|
||||||
|
```
|
||||||
|
|
||||||
|
### Terminal 2 : Frontend
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /mnt/e/My\ IA/frontend
|
||||||
|
|
||||||
|
# LANCER
|
||||||
|
python3 -m http.server 9000
|
||||||
|
```
|
||||||
|
|
||||||
|
### Navigateur
|
||||||
|
|
||||||
|
Ouvrir : **http://localhost:9000**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛑 Arrêter tout
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Méthode 1 : Script
|
||||||
|
bash stop.sh
|
||||||
|
|
||||||
|
# Méthode 2 : Tuer les processus
|
||||||
|
pkill -f "python main.py"
|
||||||
|
pkill -f "http.server 9000"
|
||||||
|
pkill ollama
|
||||||
|
|
||||||
|
# Méthode 3 : Par port
|
||||||
|
fuser -k 9001/tcp # Backend
|
||||||
|
fuser -k 9000/tcp # Frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Vérifier que tout tourne
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Backend (doit retourner du JSON)
|
||||||
|
curl http://localhost:9001/health
|
||||||
|
|
||||||
|
# Frontend (doit retourner du HTML)
|
||||||
|
curl http://localhost:9000 | head -5
|
||||||
|
|
||||||
|
# Ollama
|
||||||
|
curl http://localhost:11434/api/tags
|
||||||
|
|
||||||
|
# Tout en un
|
||||||
|
cat > check.sh << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
echo "Backend (9001):"
|
||||||
|
curl -s http://localhost:9001/health | python3 -m json.tool 2>/dev/null || echo "❌ Non accessible"
|
||||||
|
echo -e "\nFrontend (9000):"
|
||||||
|
curl -s http://localhost:9000 | grep -q "<!DOCTYPE" && echo "✅ OK" || echo "❌ Non accessible"
|
||||||
|
echo -e "\nOllama (11434):"
|
||||||
|
curl -s http://localhost:11434/api/tags | python3 -m json.tool 2>/dev/null | head -3 || echo "❌ Non accessible"
|
||||||
|
EOF
|
||||||
|
chmod +x check.sh
|
||||||
|
bash check.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Ports utilisés
|
||||||
|
|
||||||
|
| Service | Port | URL |
|
||||||
|
|----------|------|-------------------------------|
|
||||||
|
| Backend | 9001 | http://localhost:9001 |
|
||||||
|
| Frontend | 9000 | http://localhost:9000 |
|
||||||
|
| Ollama | 11434| http://localhost:11434 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐛 Résolution de problèmes
|
||||||
|
|
||||||
|
### Erreur : Address already in use
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Trouver ce qui utilise le port
|
||||||
|
lsof -i :9001
|
||||||
|
|
||||||
|
# Tuer le processus
|
||||||
|
fuser -k 9001/tcp
|
||||||
|
|
||||||
|
# Ou tuer par PID
|
||||||
|
kill <PID>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backend ne démarre pas
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Voir les erreurs
|
||||||
|
cd backend
|
||||||
|
. venv/bin/activate
|
||||||
|
python main.py
|
||||||
|
|
||||||
|
# Réinstaller les dépendances
|
||||||
|
pip install --upgrade -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend affiche page blanche
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier que index.html existe
|
||||||
|
ls -la frontend/index.html
|
||||||
|
|
||||||
|
# Si non, retélécharger l'archive
|
||||||
|
```
|
||||||
|
|
||||||
|
### WebSocket ne connecte pas
|
||||||
|
|
||||||
|
Le backend doit tourner **avant** d'ouvrir le frontend.
|
||||||
|
|
||||||
|
1. Lancer le backend
|
||||||
|
2. Attendre le message "Uvicorn running"
|
||||||
|
3. Puis ouvrir http://localhost:9000
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Checklist avant de commencer
|
||||||
|
|
||||||
|
- [ ] WSL2 installé
|
||||||
|
- [ ] Python 3.10+ : `python3 --version`
|
||||||
|
- [ ] Ollama installé : `which ollama`
|
||||||
|
- [ ] Modèle téléchargé : `ollama list`
|
||||||
|
- [ ] Fichiers présents : `ls -la frontend/index.html`
|
||||||
|
- [ ] Ports libres : `lsof -i :9000` et `lsof -i :9001` → rien
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📱 Ouvrir dans le navigateur (Windows)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Depuis WSL
|
||||||
|
cmd.exe /c start http://localhost:9000
|
||||||
|
|
||||||
|
# Ou taper directement dans Windows :
|
||||||
|
# http://localhost:9000
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Si TOUT échoue : Réinstallation propre
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Tout arrêter
|
||||||
|
bash stop.sh
|
||||||
|
pkill -9 python
|
||||||
|
pkill -9 ollama
|
||||||
|
|
||||||
|
# 2. Nettoyer
|
||||||
|
rm -rf backend/venv
|
||||||
|
rm /tmp/*.log
|
||||||
|
rm /tmp/ai-assistant-*.pid
|
||||||
|
|
||||||
|
# 3. Retélécharger l'archive
|
||||||
|
# Télécharger ai-code-assistant.zip
|
||||||
|
|
||||||
|
# 4. Extraire proprement
|
||||||
|
unzip -o ai-code-assistant.zip
|
||||||
|
cd ai-code-assistant
|
||||||
|
|
||||||
|
# 5. Lancer
|
||||||
|
chmod +x *.sh
|
||||||
|
bash start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**EN CAS DE DOUTE : Lance les commandes du Lancement manuel (Terminal 1 + Terminal 2)**
|
||||||
|
|
||||||
|
C'est la méthode la plus fiable pour voir exactement ce qui se passe ! 🎉
|
||||||
210
QUICKSTART.md
Normal file
210
QUICKSTART.md
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
# 🚀 Guide de démarrage rapide - AI Code Assistant sur WSL
|
||||||
|
|
||||||
|
## Installation en 5 minutes
|
||||||
|
|
||||||
|
### Étape 1: Préparer l'environnement WSL
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ouvrir WSL Ubuntu
|
||||||
|
wsl
|
||||||
|
|
||||||
|
# Mettre à jour le système
|
||||||
|
sudo apt update && sudo apt upgrade -y
|
||||||
|
|
||||||
|
# Installer Python et dépendances
|
||||||
|
sudo apt install -y python3 python3-pip python3-venv
|
||||||
|
|
||||||
|
# Vérifier l'installation
|
||||||
|
python3 --version # Doit être 3.10+
|
||||||
|
```
|
||||||
|
|
||||||
|
### Étape 2: Créer la structure du projet
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Créer le dossier principal
|
||||||
|
mkdir -p ~/ai-code-assistant
|
||||||
|
cd ~/ai-code-assistant
|
||||||
|
|
||||||
|
# Créer la structure
|
||||||
|
mkdir -p backend frontend
|
||||||
|
|
||||||
|
# Copier les fichiers fournis:
|
||||||
|
# - Copier main.py dans backend/
|
||||||
|
# - Copier requirements.txt dans backend/
|
||||||
|
# - Copier index.html dans frontend/
|
||||||
|
# - Copier start.sh et stop.sh à la racine
|
||||||
|
```
|
||||||
|
|
||||||
|
### Étape 3: Installer et configurer
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Rendre les scripts exécutables
|
||||||
|
chmod +x start.sh stop.sh
|
||||||
|
|
||||||
|
# Vérifier qu'Ollama est installé
|
||||||
|
which ollama
|
||||||
|
|
||||||
|
# Si pas installé:
|
||||||
|
curl -fsSL https://ollama.com/install.sh | sh
|
||||||
|
|
||||||
|
# Télécharger les modèles
|
||||||
|
ollama pull qwen2.5-coder:7b
|
||||||
|
```
|
||||||
|
|
||||||
|
### Étape 4: Démarrer l'application
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lancer tout en une commande
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**C'est tout !** 🎉
|
||||||
|
|
||||||
|
L'interface s'ouvrira automatiquement sur **http://localhost:9000**
|
||||||
|
|
||||||
|
## ⚡ Commandes essentielles
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Démarrer
|
||||||
|
./start.sh
|
||||||
|
|
||||||
|
# Arrêter
|
||||||
|
./stop.sh
|
||||||
|
|
||||||
|
# Redémarrer
|
||||||
|
./stop.sh && ./start.sh
|
||||||
|
|
||||||
|
# Voir les logs en temps réel
|
||||||
|
tail -f /tmp/fastapi.log
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 Premier test
|
||||||
|
|
||||||
|
1. Ouvrir http://localhost:9000 dans votre navigateur
|
||||||
|
2. Taper: `"Écris une fonction Python pour calculer Fibonacci"`
|
||||||
|
3. Voir la réponse s'afficher en temps réel
|
||||||
|
4. Cliquer sur "Tester" pour exécuter le code
|
||||||
|
5. Modifier et réexécuter
|
||||||
|
|
||||||
|
## 🐛 Problèmes courants
|
||||||
|
|
||||||
|
### "Port 8000 déjà utilisé"
|
||||||
|
```bash
|
||||||
|
# Tuer le processus
|
||||||
|
kill $(lsof -t -i :8000)
|
||||||
|
```
|
||||||
|
|
||||||
|
### "Ollama non accessible"
|
||||||
|
```bash
|
||||||
|
# Redémarrer Ollama
|
||||||
|
pkill ollama
|
||||||
|
ollama serve &
|
||||||
|
sleep 3
|
||||||
|
```
|
||||||
|
|
||||||
|
### "Page blanche dans le navigateur"
|
||||||
|
```bash
|
||||||
|
# Vérifier que le frontend tourne
|
||||||
|
curl http://localhost:9000
|
||||||
|
|
||||||
|
# Si non, relancer
|
||||||
|
./stop.sh
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📱 Accès depuis Windows
|
||||||
|
|
||||||
|
L'application est accessible depuis Windows via:
|
||||||
|
- **http://localhost:9000** (WSL forward automatique)
|
||||||
|
- Ou **http://172.x.x.x:8080** (IP WSL, trouvez-la avec `ip addr`)
|
||||||
|
|
||||||
|
## 🎨 Personnalisation rapide
|
||||||
|
|
||||||
|
### Changer les couleurs
|
||||||
|
|
||||||
|
Éditer `frontend/index.html`, section `<style>`, modifier:
|
||||||
|
|
||||||
|
```css
|
||||||
|
:root {
|
||||||
|
--accent-primary: #7c3aed; /* Violet par défaut */
|
||||||
|
--accent-secondary: #a78bfa;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Exemples de couleurs:
|
||||||
|
- Bleu: `#3b82f6` / `#60a5fa`
|
||||||
|
- Vert: `#10b981` / `#34d399`
|
||||||
|
- Rouge: `#ef4444` / `#f87171`
|
||||||
|
- Orange: `#f59e0b` / `#fbbf24`
|
||||||
|
|
||||||
|
### Changer le modèle par défaut
|
||||||
|
|
||||||
|
Éditer `frontend/index.html`, ligne avec `selectedModel`:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const [selectedModel, setSelectedModel] = useState('qwen2.5-coder:7b');
|
||||||
|
```
|
||||||
|
|
||||||
|
## 💡 Astuces
|
||||||
|
|
||||||
|
1. **Raccourcis clavier**:
|
||||||
|
- `Entrée` = Envoyer le message
|
||||||
|
- `Shift + Entrée` = Nouvelle ligne
|
||||||
|
|
||||||
|
2. **Copier le code**: Cliquer sur "Copier" dans les blocs de code
|
||||||
|
|
||||||
|
3. **Tester rapidement**: Cliquer sur "Tester" pour ouvrir dans l'éditeur
|
||||||
|
|
||||||
|
4. **Nouvelle conversation**: Cliquer sur "✨ Nouvelle conversation"
|
||||||
|
|
||||||
|
## 🔄 Mises à jour
|
||||||
|
|
||||||
|
Pour mettre à jour les modèles Ollama:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ollama pull qwen2.5-coder:7b
|
||||||
|
```
|
||||||
|
|
||||||
|
Pour mettre à jour les dépendances Python:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install --upgrade -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Performance
|
||||||
|
|
||||||
|
Sur un GPU NVIDIA 8GB:
|
||||||
|
- Génération: ~40-60 tokens/sec
|
||||||
|
- Temps de réponse: < 1 seconde
|
||||||
|
- RAM utilisée: ~2-3 GB
|
||||||
|
- VRAM utilisée: ~5-6 GB
|
||||||
|
|
||||||
|
## 🎓 Exemples de prompts
|
||||||
|
|
||||||
|
**Code**:
|
||||||
|
- "Écris une API REST avec FastAPI pour gérer des tâches"
|
||||||
|
- "Crée un algorithme de recherche binaire en Python"
|
||||||
|
- "Implémente un decorator pour mesurer le temps d'exécution"
|
||||||
|
|
||||||
|
**Debug**:
|
||||||
|
- "Analyse ce code et trouve les bugs: [coller code]"
|
||||||
|
- "Pourquoi est-ce que j'ai cette erreur: [coller erreur]"
|
||||||
|
- "Optimise cette fonction pour la performance"
|
||||||
|
|
||||||
|
**Explication**:
|
||||||
|
- "Explique comment fonctionnent les closures en JavaScript"
|
||||||
|
- "Quelle est la différence entre async/await et promises?"
|
||||||
|
- "Comment fonctionne le GIL en Python?"
|
||||||
|
|
||||||
|
## 🌟 Prochaines étapes
|
||||||
|
|
||||||
|
Maintenant que c'est installé, essayez:
|
||||||
|
|
||||||
|
1. Créer votre propre Modelfile personnalisé
|
||||||
|
2. Intégrer le RAG pour votre codebase
|
||||||
|
3. Ajouter des fonctionnalités à l'interface
|
||||||
|
4. Créer des prompts spécialisés pour vos besoins
|
||||||
|
|
||||||
|
Bon coding ! 🚀
|
||||||
410
README.md
Normal file
410
README.md
Normal file
@@ -0,0 +1,410 @@
|
|||||||
|
# AI Code Assistant - Interface Web Style Claude
|
||||||
|
|
||||||
|
Interface web locale complète avec chat IA et éditeur de code intégré, similaire à Claude.
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
## ✨ Fonctionnalités
|
||||||
|
|
||||||
|
- 💬 **Chat en temps réel** avec WebSocket
|
||||||
|
- 💻 **Éditeur de code intégré** avec exécution Python
|
||||||
|
- 🎨 **Interface moderne** style Claude avec design soigné
|
||||||
|
- 🤖 **Support multi-modèles** Ollama
|
||||||
|
- 📝 **Syntaxe highlighting** pour code
|
||||||
|
- ⚡ **Streaming des réponses** en temps réel
|
||||||
|
- 🔄 **Historique des conversations**
|
||||||
|
- 🎯 **API REST complète**
|
||||||
|
|
||||||
|
## 🏗️ Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
ai-code-assistant/
|
||||||
|
├── backend/
|
||||||
|
│ ├── main.py # Backend FastAPI
|
||||||
|
│ └── requirements.txt # Dépendances Python
|
||||||
|
├── frontend/
|
||||||
|
│ └── index.html # Interface React (SPA)
|
||||||
|
├── start.sh # Script de démarrage
|
||||||
|
├── stop.sh # Script d'arrêt
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 Prérequis
|
||||||
|
|
||||||
|
### Système
|
||||||
|
- **WSL2** sur Windows (Ubuntu 22.04 recommandé)
|
||||||
|
- **Python 3.10+**
|
||||||
|
- **Node.js** (optionnel, pour serveur dev)
|
||||||
|
- **Ollama** installé et configuré
|
||||||
|
|
||||||
|
### GPU
|
||||||
|
- **NVIDIA GPU** avec 8GB+ VRAM
|
||||||
|
- **Drivers NVIDIA** pour WSL
|
||||||
|
- **CUDA** configuré
|
||||||
|
|
||||||
|
### Modèles Ollama requis
|
||||||
|
```bash
|
||||||
|
ollama pull qwen2.5-coder:7b
|
||||||
|
ollama pull code-expert # Si créé précédemment
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 Installation rapide
|
||||||
|
|
||||||
|
### 1. Cloner/Copier les fichiers
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Créer le dossier projet
|
||||||
|
mkdir -p ~/ai-code-assistant
|
||||||
|
cd ~/ai-code-assistant
|
||||||
|
|
||||||
|
# Copier tous les fichiers fournis dans cette structure:
|
||||||
|
# - backend/main.py
|
||||||
|
# - backend/requirements.txt
|
||||||
|
# - frontend/index.html
|
||||||
|
# - start.sh
|
||||||
|
# - stop.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Installer les dépendances
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Créer l'environnement virtuel Python
|
||||||
|
cd backend
|
||||||
|
python3 -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
# Installer les dépendances
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Vérifier Ollama
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier qu'Ollama tourne
|
||||||
|
curl http://localhost:11434/api/tags
|
||||||
|
|
||||||
|
# Si non, démarrer Ollama
|
||||||
|
ollama serve &
|
||||||
|
|
||||||
|
# Vérifier les modèles disponibles
|
||||||
|
ollama list
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Démarrer l'application
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Depuis la racine du projet
|
||||||
|
cd ~/ai-code-assistant
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
L'interface sera disponible sur **http://localhost:9000**
|
||||||
|
|
||||||
|
## 🎮 Utilisation
|
||||||
|
|
||||||
|
### Interface Chat
|
||||||
|
|
||||||
|
1. **Écrire un message** dans la zone de texte en bas
|
||||||
|
2. **Appuyer sur Entrée** ou cliquer sur ➤ pour envoyer
|
||||||
|
3. Les réponses s'affichent en **streaming temps réel**
|
||||||
|
4. **Cliquer sur "Copier"** dans les blocs de code pour copier
|
||||||
|
5. **Cliquer sur "Tester"** pour ouvrir le code dans l'éditeur
|
||||||
|
|
||||||
|
### Éditeur de Code
|
||||||
|
|
||||||
|
1. Cliquer sur **💻 Code** en haut à droite
|
||||||
|
2. Écrire du code Python dans l'éditeur
|
||||||
|
3. Cliquer sur **▶ Exécuter** pour lancer
|
||||||
|
4. Voir les résultats dans la zone de sortie
|
||||||
|
|
||||||
|
### Sélection du modèle
|
||||||
|
|
||||||
|
En bas de la sidebar, choisir le modèle à utiliser:
|
||||||
|
- `qwen2.5-coder:7b` - Rapide et performant
|
||||||
|
- `code-expert` - Optimisé pour le code (si créé)
|
||||||
|
- `deepseek-coder-v2:16b` - Meilleure qualité (plus lent)
|
||||||
|
|
||||||
|
## 🔧 Configuration
|
||||||
|
|
||||||
|
### Backend (main.py)
|
||||||
|
|
||||||
|
Modifier les variables selon vos besoins:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Port du backend
|
||||||
|
uvicorn.run("main:app", host="0.0.0.0", port=8000)
|
||||||
|
|
||||||
|
# Timeout d'exécution de code
|
||||||
|
timeout=10 # secondes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend (index.html)
|
||||||
|
|
||||||
|
Modifier les constantes:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// URLs de l'API
|
||||||
|
const API_URL = 'http://localhost:9001';
|
||||||
|
const WS_URL = 'ws://localhost:9001/ws/chat';
|
||||||
|
```
|
||||||
|
|
||||||
|
### Port du frontend
|
||||||
|
|
||||||
|
Le frontend est accessible sur le port **9000** par défaut.
|
||||||
|
|
||||||
|
## 🎨 Personnalisation du design
|
||||||
|
|
||||||
|
L'interface utilise des variables CSS pour faciliter la personnalisation:
|
||||||
|
|
||||||
|
```css
|
||||||
|
:root {
|
||||||
|
--bg-primary: #0a0a0f;
|
||||||
|
--accent-primary: #7c3aed;
|
||||||
|
--accent-secondary: #a78bfa;
|
||||||
|
/* ... autres variables */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Modifiez ces valeurs dans `frontend/index.html` pour changer les couleurs.
|
||||||
|
|
||||||
|
## 📡 API Endpoints
|
||||||
|
|
||||||
|
### Chat
|
||||||
|
|
||||||
|
**POST /chat**
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:9001/chat \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"messages": [{"role": "user", "content": "Bonjour"}],
|
||||||
|
"model": "qwen2.5-coder:7b",
|
||||||
|
"stream": true
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**WebSocket /ws/chat**
|
||||||
|
```javascript
|
||||||
|
const ws = new WebSocket('ws://localhost:9001/ws/chat');
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
message: "Écris un algorithme de tri",
|
||||||
|
model: "code-expert"
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exécution de code
|
||||||
|
|
||||||
|
**POST /execute**
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:9001/execute \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"code": "print(\"Hello World\")",
|
||||||
|
"language": "python"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Analyse de code
|
||||||
|
|
||||||
|
**POST /analyze-code**
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:9001/analyze-code \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"code": "def add(a,b): return a+b",
|
||||||
|
"language": "python"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Correction de code
|
||||||
|
|
||||||
|
**POST /fix-code**
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:9001/fix-code \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"code": "for i in range(10) print(i)",
|
||||||
|
"error": "SyntaxError: invalid syntax",
|
||||||
|
"language": "python"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Liste des modèles
|
||||||
|
|
||||||
|
**GET /models**
|
||||||
|
```bash
|
||||||
|
curl http://localhost:9001/models
|
||||||
|
```
|
||||||
|
|
||||||
|
### Health check
|
||||||
|
|
||||||
|
**GET /health**
|
||||||
|
```bash
|
||||||
|
curl http://localhost:9001/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🐛 Dépannage
|
||||||
|
|
||||||
|
### Backend ne démarre pas
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier les logs
|
||||||
|
cat /tmp/fastapi.log
|
||||||
|
|
||||||
|
# Vérifier que le port 9001 est libre
|
||||||
|
lsof -i :8000
|
||||||
|
|
||||||
|
# Tuer le processus si nécessaire
|
||||||
|
kill $(lsof -t -i :8000)
|
||||||
|
```
|
||||||
|
|
||||||
|
### WebSocket ne connecte pas
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier que le backend est lancé
|
||||||
|
curl http://localhost:9001/health
|
||||||
|
|
||||||
|
# Vérifier les logs WebSocket
|
||||||
|
grep -i websocket /tmp/fastapi.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ollama non accessible
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier le service
|
||||||
|
curl http://localhost:11434/api/tags
|
||||||
|
|
||||||
|
# Relancer Ollama
|
||||||
|
pkill ollama
|
||||||
|
ollama serve &
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code ne s'exécute pas
|
||||||
|
|
||||||
|
- Vérifier que Python 3 est installé: `python3 --version`
|
||||||
|
- Vérifier les permissions: `ls -la backend/`
|
||||||
|
- Augmenter le timeout dans `main.py` si code lent
|
||||||
|
|
||||||
|
### Frontend affiche une page blanche
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier les logs navigateur (F12 → Console)
|
||||||
|
# Vérifier que le serveur frontend tourne
|
||||||
|
curl http://localhost:9000
|
||||||
|
|
||||||
|
# Relancer
|
||||||
|
./stop.sh
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔐 Sécurité
|
||||||
|
|
||||||
|
⚠️ **ATTENTION**: Cette application est conçue pour un usage **local uniquement**.
|
||||||
|
|
||||||
|
**Limitations de sécurité actuelles**:
|
||||||
|
- Exécution de code sans sandbox
|
||||||
|
- Pas d'authentification
|
||||||
|
- CORS ouvert (`allow_origins=["*"]`)
|
||||||
|
|
||||||
|
**Pour une utilisation en production**:
|
||||||
|
1. Ajouter un système d'authentification
|
||||||
|
2. Utiliser un sandbox pour l'exécution de code (Docker, VM)
|
||||||
|
3. Limiter CORS aux origines autorisées
|
||||||
|
4. Ajouter rate limiting
|
||||||
|
5. Valider et sanitiser toutes les entrées
|
||||||
|
6. Utiliser HTTPS/WSS
|
||||||
|
|
||||||
|
## 📊 Monitoring
|
||||||
|
|
||||||
|
### Logs disponibles
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Backend FastAPI
|
||||||
|
tail -f /tmp/fastapi.log
|
||||||
|
|
||||||
|
# Frontend
|
||||||
|
tail -f /tmp/frontend.log
|
||||||
|
|
||||||
|
# Ollama
|
||||||
|
tail -f /tmp/ollama.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Surveiller les ressources
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# GPU
|
||||||
|
watch -n 1 nvidia-smi
|
||||||
|
|
||||||
|
# Processus Python
|
||||||
|
ps aux | grep python
|
||||||
|
|
||||||
|
# Ports utilisés
|
||||||
|
netstat -tlnp | grep -E '9001|9000|11434'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 Améliorations futures
|
||||||
|
|
||||||
|
- [ ] Historique persistant des conversations
|
||||||
|
- [ ] Support multi-langages (JS, Go, Rust, etc.)
|
||||||
|
- [ ] Système de plugins
|
||||||
|
- [ ] Thèmes personnalisables
|
||||||
|
- [ ] Export des conversations
|
||||||
|
- [ ] Intégration Git
|
||||||
|
- [ ] Debugger visuel
|
||||||
|
- [ ] Tests unitaires intégrés
|
||||||
|
- [ ] Support du RAG (documentation personnalisée)
|
||||||
|
- [ ] Mode collaboration (multi-utilisateurs)
|
||||||
|
|
||||||
|
## 📝 Commandes utiles
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Démarrer
|
||||||
|
./start.sh
|
||||||
|
|
||||||
|
# Arrêter
|
||||||
|
./stop.sh
|
||||||
|
|
||||||
|
# Redémarrer
|
||||||
|
./stop.sh && ./start.sh
|
||||||
|
|
||||||
|
# Voir tous les processus
|
||||||
|
ps aux | grep -E 'ollama|python|http.server'
|
||||||
|
|
||||||
|
# Nettoyer complètement
|
||||||
|
./stop.sh
|
||||||
|
rm /tmp/ai-assistant-*.pid
|
||||||
|
rm /tmp/*.log
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🤝 Contribution
|
||||||
|
|
||||||
|
Structure du code:
|
||||||
|
- **Backend**: FastAPI avec WebSocket pour temps réel
|
||||||
|
- **Frontend**: React 18 avec hooks
|
||||||
|
- **Styling**: CSS pur avec variables
|
||||||
|
- **Communication**: REST + WebSocket
|
||||||
|
|
||||||
|
Pour contribuer:
|
||||||
|
1. Fork le projet
|
||||||
|
2. Créer une branche (`git checkout -b feature/amelioration`)
|
||||||
|
3. Commit (`git commit -m 'Ajout fonctionnalité X'`)
|
||||||
|
4. Push (`git push origin feature/amelioration`)
|
||||||
|
5. Ouvrir une Pull Request
|
||||||
|
|
||||||
|
## 📄 Licence
|
||||||
|
|
||||||
|
Projet personnel - Usage libre
|
||||||
|
|
||||||
|
## 🙏 Remerciements
|
||||||
|
|
||||||
|
- **Ollama** pour les modèles LLM locaux
|
||||||
|
- **FastAPI** pour le backend performant
|
||||||
|
- **React** pour l'interface réactive
|
||||||
|
- **Anthropic** pour l'inspiration du design Claude
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Créé avec ❤️ pour le développement local d'IA**
|
||||||
|
|
||||||
|
Pour toute question, ouvrez une issue GitHub ou consultez la documentation Ollama.
|
||||||
238
TROUBLESHOOTING.md
Normal file
238
TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
# 🔧 Guide de dépannage rapide
|
||||||
|
|
||||||
|
## Problème : 404 sur l'interface web
|
||||||
|
|
||||||
|
### Cause
|
||||||
|
Le serveur HTTP démarre mais ne trouve pas `index.html`
|
||||||
|
|
||||||
|
### Solution
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Arrêter tout
|
||||||
|
bash stop.sh
|
||||||
|
|
||||||
|
# 2. Vérifier la structure des fichiers
|
||||||
|
cd /mnt/e/My\ IA # Ou ton chemin
|
||||||
|
ls -la
|
||||||
|
ls -la frontend/
|
||||||
|
|
||||||
|
# 3. Tu DOIS voir :
|
||||||
|
# frontend/
|
||||||
|
# └── index.html
|
||||||
|
|
||||||
|
# 4. Si index.html manque, télécharge à nouveau l'archive
|
||||||
|
|
||||||
|
# 5. Lancer correctement
|
||||||
|
bash start.sh
|
||||||
|
|
||||||
|
# 6. Ouvrir
|
||||||
|
# http://localhost:9000
|
||||||
|
```
|
||||||
|
|
||||||
|
## Problème : Permission denied avec source
|
||||||
|
|
||||||
|
### Cause
|
||||||
|
Utilisation de `sh` au lieu de `bash`
|
||||||
|
|
||||||
|
### Solution
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# ❌ PAS COMME ÇA :
|
||||||
|
sh start.sh
|
||||||
|
|
||||||
|
# ✅ COMME ÇA :
|
||||||
|
bash start.sh
|
||||||
|
|
||||||
|
# Ou directement :
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Problème : Backend ne démarre pas
|
||||||
|
|
||||||
|
### Diagnostic
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Voir les logs
|
||||||
|
cat /tmp/fastapi.log
|
||||||
|
|
||||||
|
# Vérifier Python
|
||||||
|
python3 --version # Doit être 3.10+
|
||||||
|
|
||||||
|
# Vérifier le port 8000
|
||||||
|
lsof -i :8000
|
||||||
|
```
|
||||||
|
|
||||||
|
### Solution
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Si le port est occupé
|
||||||
|
kill $(lsof -t -i :8000)
|
||||||
|
|
||||||
|
# Relancer
|
||||||
|
cd /mnt/e/My\ IA/backend
|
||||||
|
. venv/bin/activate
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Problème : Ollama non accessible
|
||||||
|
|
||||||
|
### Diagnostic
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:11434/api/tags
|
||||||
|
```
|
||||||
|
|
||||||
|
### Solution
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Démarrer Ollama
|
||||||
|
ollama serve &
|
||||||
|
|
||||||
|
# Attendre 3 secondes
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
# Vérifier
|
||||||
|
ollama list
|
||||||
|
```
|
||||||
|
|
||||||
|
## Lancement manuel complet (si scripts ne marchent pas)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Aller dans le dossier
|
||||||
|
cd /mnt/e/My\ IA
|
||||||
|
|
||||||
|
# 2. Terminal 1 : Ollama
|
||||||
|
ollama serve
|
||||||
|
|
||||||
|
# 3. Terminal 2 : Backend
|
||||||
|
cd backend
|
||||||
|
python3 -m venv venv
|
||||||
|
. venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
python main.py
|
||||||
|
|
||||||
|
# 4. Terminal 3 : Frontend
|
||||||
|
cd frontend
|
||||||
|
python3 -m http.server 9000
|
||||||
|
|
||||||
|
# 5. Ouvrir navigateur
|
||||||
|
# http://localhost:9000
|
||||||
|
```
|
||||||
|
|
||||||
|
## Vérification complète
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier tous les services
|
||||||
|
echo "=== Ollama ==="
|
||||||
|
curl -s http://localhost:11434/api/tags | head -5
|
||||||
|
|
||||||
|
echo -e "\n=== Backend ==="
|
||||||
|
curl -s http://localhost:9001/health
|
||||||
|
|
||||||
|
echo -e "\n=== Frontend ==="
|
||||||
|
curl -s http://localhost:9000 | head -5
|
||||||
|
|
||||||
|
echo -e "\n=== Processus ==="
|
||||||
|
ps aux | grep -E "ollama|python|http.server" | grep -v grep
|
||||||
|
```
|
||||||
|
|
||||||
|
## Checklist de debug
|
||||||
|
|
||||||
|
- [ ] Ollama installé : `which ollama`
|
||||||
|
- [ ] Python 3.10+ : `python3 --version`
|
||||||
|
- [ ] Structure correcte : `ls -la frontend/index.html`
|
||||||
|
- [ ] Scripts exécutables : `ls -la *.sh`
|
||||||
|
- [ ] Ports libres : `netstat -tlnp | grep -E "9001|9000"`
|
||||||
|
- [ ] Logs accessibles : `cat /tmp/fastapi.log`
|
||||||
|
|
||||||
|
## Réinstallation propre
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Tout arrêter
|
||||||
|
bash stop.sh
|
||||||
|
pkill ollama
|
||||||
|
pkill python
|
||||||
|
|
||||||
|
# 2. Nettoyer
|
||||||
|
rm -rf backend/venv
|
||||||
|
rm /tmp/*.log
|
||||||
|
rm /tmp/ai-assistant-*.pid
|
||||||
|
|
||||||
|
# 3. Retélécharger l'archive
|
||||||
|
# (télécharger ai-code-assistant.zip)
|
||||||
|
|
||||||
|
# 4. Extraire
|
||||||
|
unzip -o ai-code-assistant.zip
|
||||||
|
cd ai-code-assistant
|
||||||
|
|
||||||
|
# 5. Rendre exécutable
|
||||||
|
chmod +x start.sh stop.sh
|
||||||
|
|
||||||
|
# 6. Démarrer
|
||||||
|
bash start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Astuce : Vérifier que tout fonctionne
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ce script vérifie tout en une commande
|
||||||
|
cat > check.sh << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
echo "🔍 Vérification système..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "1. Ollama:"
|
||||||
|
if curl -s http://localhost:11434/api/tags > /dev/null 2>&1; then
|
||||||
|
echo " ✅ Actif"
|
||||||
|
else
|
||||||
|
echo " ❌ Inactif"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "2. Backend (port 8000):"
|
||||||
|
if curl -s http://localhost:9001/health > /dev/null 2>&1; then
|
||||||
|
echo " ✅ Actif"
|
||||||
|
else
|
||||||
|
echo " ❌ Inactif"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "3. Frontend (port 9000):"
|
||||||
|
if curl -s http://localhost:9000 > /dev/null 2>&1; then
|
||||||
|
echo " ✅ Actif"
|
||||||
|
else
|
||||||
|
echo " ❌ Inactif"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "4. Fichiers:"
|
||||||
|
if [ -f "frontend/index.html" ]; then
|
||||||
|
echo " ✅ index.html présent"
|
||||||
|
else
|
||||||
|
echo " ❌ index.html manquant"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "URL à ouvrir: http://localhost:9000"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x check.sh
|
||||||
|
bash check.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contact / Support
|
||||||
|
|
||||||
|
Si rien ne fonctionne :
|
||||||
|
|
||||||
|
1. Copie la sortie de :
|
||||||
|
```bash
|
||||||
|
bash check.sh
|
||||||
|
cat /tmp/fastapi.log
|
||||||
|
cat /tmp/frontend.log
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Vérifie ta structure de fichiers :
|
||||||
|
```bash
|
||||||
|
tree -L 2
|
||||||
|
# ou
|
||||||
|
find . -type f
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Partage ces informations pour obtenir de l'aide
|
||||||
341
backend/main.py
Normal file
341
backend/main.py
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, HTTPException
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
from fastapi.responses import StreamingResponse
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from typing import List, Optional, Dict, Any
|
||||||
|
import ollama
|
||||||
|
import asyncio
|
||||||
|
import json
|
||||||
|
import uvicorn
|
||||||
|
from datetime import datetime
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
import os
|
||||||
|
|
||||||
|
app = FastAPI(title="AI Code Assistant API")
|
||||||
|
|
||||||
|
# CORS pour permettre le frontend
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Models
|
||||||
|
class Message(BaseModel):
|
||||||
|
role: str
|
||||||
|
content: str
|
||||||
|
timestamp: Optional[str] = None
|
||||||
|
|
||||||
|
class ChatRequest(BaseModel):
|
||||||
|
messages: List[Message]
|
||||||
|
model: str = "code-expert"
|
||||||
|
stream: bool = True
|
||||||
|
|
||||||
|
class CodeExecutionRequest(BaseModel):
|
||||||
|
code: str
|
||||||
|
language: str = "python"
|
||||||
|
|
||||||
|
class ConversationHistory:
|
||||||
|
def __init__(self):
|
||||||
|
self.conversations: Dict[str, List[Message]] = {}
|
||||||
|
|
||||||
|
def add_message(self, conversation_id: str, message: Message):
|
||||||
|
if conversation_id not in self.conversations:
|
||||||
|
self.conversations[conversation_id] = []
|
||||||
|
self.conversations[conversation_id].append(message)
|
||||||
|
|
||||||
|
def get_conversation(self, conversation_id: str) -> List[Message]:
|
||||||
|
return self.conversations.get(conversation_id, [])
|
||||||
|
|
||||||
|
history = ConversationHistory()
|
||||||
|
|
||||||
|
# WebSocket manager
|
||||||
|
class ConnectionManager:
|
||||||
|
def __init__(self):
|
||||||
|
self.active_connections: List[WebSocket] = []
|
||||||
|
|
||||||
|
async def connect(self, websocket: WebSocket):
|
||||||
|
await websocket.accept()
|
||||||
|
self.active_connections.append(websocket)
|
||||||
|
|
||||||
|
def disconnect(self, websocket: WebSocket):
|
||||||
|
self.active_connections.remove(websocket)
|
||||||
|
|
||||||
|
async def send_message(self, message: str, websocket: WebSocket):
|
||||||
|
await websocket.send_text(message)
|
||||||
|
|
||||||
|
manager = ConnectionManager()
|
||||||
|
|
||||||
|
# Routes
|
||||||
|
@app.get("/")
|
||||||
|
async def root():
|
||||||
|
return {"message": "AI Code Assistant API", "version": "1.0"}
|
||||||
|
|
||||||
|
@app.get("/models")
|
||||||
|
async def list_models():
|
||||||
|
"""Liste tous les modèles Ollama disponibles."""
|
||||||
|
try:
|
||||||
|
models = ollama.list()
|
||||||
|
return {
|
||||||
|
"models": [
|
||||||
|
{
|
||||||
|
"name": m['name'],
|
||||||
|
"size": m.get('size', 0),
|
||||||
|
"modified": m.get('modified_at', '')
|
||||||
|
}
|
||||||
|
for m in models['models']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
|
@app.post("/chat")
|
||||||
|
async def chat(request: ChatRequest):
|
||||||
|
"""Endpoint de chat standard (non-streaming ou streaming)."""
|
||||||
|
try:
|
||||||
|
messages = [{"role": m.role, "content": m.content} for m in request.messages]
|
||||||
|
|
||||||
|
if request.stream:
|
||||||
|
async def generate():
|
||||||
|
stream = ollama.chat(
|
||||||
|
model=request.model,
|
||||||
|
messages=messages,
|
||||||
|
stream=True
|
||||||
|
)
|
||||||
|
|
||||||
|
for chunk in stream:
|
||||||
|
if 'message' in chunk and 'content' in chunk['message']:
|
||||||
|
content = chunk['message']['content']
|
||||||
|
yield f"data: {json.dumps({'content': content})}\n\n"
|
||||||
|
|
||||||
|
yield "data: [DONE]\n\n"
|
||||||
|
|
||||||
|
return StreamingResponse(generate(), media_type="text/event-stream")
|
||||||
|
else:
|
||||||
|
response = ollama.chat(
|
||||||
|
model=request.model,
|
||||||
|
messages=messages
|
||||||
|
)
|
||||||
|
return {"response": response['message']['content']}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
|
@app.websocket("/ws/chat")
|
||||||
|
async def websocket_chat(websocket: WebSocket):
|
||||||
|
"""WebSocket pour chat en temps réel."""
|
||||||
|
await manager.connect(websocket)
|
||||||
|
conversation_id = str(datetime.now().timestamp())
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
# Recevoir le message du client
|
||||||
|
data = await websocket.receive_text()
|
||||||
|
request_data = json.loads(data)
|
||||||
|
|
||||||
|
user_message = Message(
|
||||||
|
role="user",
|
||||||
|
content=request_data['message'],
|
||||||
|
timestamp=datetime.now().isoformat()
|
||||||
|
)
|
||||||
|
history.add_message(conversation_id, user_message)
|
||||||
|
|
||||||
|
# Récupérer l'historique de conversation
|
||||||
|
conversation = history.get_conversation(conversation_id)
|
||||||
|
messages = [{"role": m.role, "content": m.content} for m in conversation]
|
||||||
|
|
||||||
|
# Envoyer un accusé de réception
|
||||||
|
await manager.send_message(
|
||||||
|
json.dumps({
|
||||||
|
"type": "status",
|
||||||
|
"content": "Processing..."
|
||||||
|
}),
|
||||||
|
websocket
|
||||||
|
)
|
||||||
|
|
||||||
|
# Générer la réponse avec streaming
|
||||||
|
model = request_data.get('model', 'code-expert')
|
||||||
|
full_response = ""
|
||||||
|
|
||||||
|
stream = ollama.chat(
|
||||||
|
model=model,
|
||||||
|
messages=messages,
|
||||||
|
stream=True
|
||||||
|
)
|
||||||
|
|
||||||
|
for chunk in stream:
|
||||||
|
if 'message' in chunk and 'content' in chunk['message']:
|
||||||
|
content = chunk['message']['content']
|
||||||
|
full_response += content
|
||||||
|
|
||||||
|
await manager.send_message(
|
||||||
|
json.dumps({
|
||||||
|
"type": "stream",
|
||||||
|
"content": content
|
||||||
|
}),
|
||||||
|
websocket
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sauvegarder la réponse complète
|
||||||
|
assistant_message = Message(
|
||||||
|
role="assistant",
|
||||||
|
content=full_response,
|
||||||
|
timestamp=datetime.now().isoformat()
|
||||||
|
)
|
||||||
|
history.add_message(conversation_id, assistant_message)
|
||||||
|
|
||||||
|
# Signal de fin
|
||||||
|
await manager.send_message(
|
||||||
|
json.dumps({
|
||||||
|
"type": "done",
|
||||||
|
"content": full_response
|
||||||
|
}),
|
||||||
|
websocket
|
||||||
|
)
|
||||||
|
|
||||||
|
except WebSocketDisconnect:
|
||||||
|
manager.disconnect(websocket)
|
||||||
|
except Exception as e:
|
||||||
|
await manager.send_message(
|
||||||
|
json.dumps({
|
||||||
|
"type": "error",
|
||||||
|
"content": str(e)
|
||||||
|
}),
|
||||||
|
websocket
|
||||||
|
)
|
||||||
|
manager.disconnect(websocket)
|
||||||
|
|
||||||
|
@app.post("/execute")
|
||||||
|
async def execute_code(request: CodeExecutionRequest):
|
||||||
|
"""Exécute du code de manière sécurisée."""
|
||||||
|
try:
|
||||||
|
# Créer un fichier temporaire
|
||||||
|
with tempfile.NamedTemporaryFile(
|
||||||
|
mode='w',
|
||||||
|
suffix=f'.{request.language}',
|
||||||
|
delete=False
|
||||||
|
) as f:
|
||||||
|
f.write(request.code)
|
||||||
|
temp_file = f.name
|
||||||
|
|
||||||
|
# Exécuter selon le langage
|
||||||
|
if request.language == "python":
|
||||||
|
result = subprocess.run(
|
||||||
|
['python3', temp_file],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
elif request.language == "javascript":
|
||||||
|
result = subprocess.run(
|
||||||
|
['node', temp_file],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
elif request.language == "bash":
|
||||||
|
result = subprocess.run(
|
||||||
|
['bash', temp_file],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise HTTPException(status_code=400, detail=f"Language {request.language} not supported")
|
||||||
|
|
||||||
|
# Nettoyer
|
||||||
|
os.unlink(temp_file)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"stdout": result.stdout,
|
||||||
|
"stderr": result.stderr,
|
||||||
|
"returncode": result.returncode,
|
||||||
|
"success": result.returncode == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
os.unlink(temp_file)
|
||||||
|
raise HTTPException(status_code=408, detail="Code execution timeout")
|
||||||
|
except Exception as e:
|
||||||
|
if os.path.exists(temp_file):
|
||||||
|
os.unlink(temp_file)
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
|
@app.post("/analyze-code")
|
||||||
|
async def analyze_code(request: CodeExecutionRequest):
|
||||||
|
"""Analyse du code avec l'IA."""
|
||||||
|
try:
|
||||||
|
response = ollama.chat(
|
||||||
|
model='code-reviewer',
|
||||||
|
messages=[{
|
||||||
|
'role': 'user',
|
||||||
|
'content': f'''Analyse ce code {request.language}:
|
||||||
|
|
||||||
|
```{request.language}
|
||||||
|
{request.code}
|
||||||
|
```
|
||||||
|
|
||||||
|
Fournis:
|
||||||
|
1. Une brève description de ce que fait le code
|
||||||
|
2. Les problèmes potentiels (bugs, sécurité, performance)
|
||||||
|
3. Des suggestions d'amélioration
|
||||||
|
'''
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
|
||||||
|
return {"analysis": response['message']['content']}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
|
@app.post("/fix-code")
|
||||||
|
async def fix_code(code: str, error: str, language: str = "python"):
|
||||||
|
"""Corrige du code avec une erreur."""
|
||||||
|
try:
|
||||||
|
response = ollama.chat(
|
||||||
|
model='debugger',
|
||||||
|
messages=[{
|
||||||
|
'role': 'user',
|
||||||
|
'content': f'''Code {language} avec erreur:
|
||||||
|
|
||||||
|
```{language}
|
||||||
|
{code}
|
||||||
|
```
|
||||||
|
|
||||||
|
Erreur:
|
||||||
|
```
|
||||||
|
{error}
|
||||||
|
```
|
||||||
|
|
||||||
|
Identifie le problème et fournis le code corrigé.
|
||||||
|
'''
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
|
||||||
|
return {"fixed_code": response['message']['content']}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
|
@app.get("/health")
|
||||||
|
async def health_check():
|
||||||
|
"""Vérifie que Ollama est accessible."""
|
||||||
|
try:
|
||||||
|
ollama.list()
|
||||||
|
return {"status": "healthy", "ollama": "connected"}
|
||||||
|
except Exception as e:
|
||||||
|
return {"status": "unhealthy", "error": str(e)}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
uvicorn.run(
|
||||||
|
"main:app",
|
||||||
|
host="0.0.0.0",
|
||||||
|
port=9001,
|
||||||
|
reload=True,
|
||||||
|
ws_ping_interval=20,
|
||||||
|
ws_ping_timeout=20
|
||||||
|
)
|
||||||
6
backend/requirements.txt
Normal file
6
backend/requirements.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
fastapi==0.109.0
|
||||||
|
uvicorn[standard]==0.27.0
|
||||||
|
ollama==0.1.6
|
||||||
|
websockets==12.0
|
||||||
|
python-multipart==0.0.6
|
||||||
|
pydantic==2.5.3
|
||||||
1446
frontend/index.html
Normal file
1446
frontend/index.html
Normal file
File diff suppressed because it is too large
Load Diff
151
start.sh
Normal file
151
start.sh
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script de démarrage pour AI Code Assistant
|
||||||
|
# Compatible WSL
|
||||||
|
|
||||||
|
echo "🚀 Démarrage de AI Code Assistant..."
|
||||||
|
echo "========================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Couleurs
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Dossier du script
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Vérifier si Ollama tourne
|
||||||
|
echo "📦 Vérification d'Ollama..."
|
||||||
|
if ! curl -s http://localhost:11434/api/tags > /dev/null 2>&1; then
|
||||||
|
echo -e "${YELLOW}⚠️ Ollama n'est pas démarré. Démarrage...${NC}"
|
||||||
|
ollama serve > /tmp/ollama.log 2>&1 &
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
if curl -s http://localhost:11434/api/tags > /dev/null 2>&1; then
|
||||||
|
echo -e "${GREEN}✅ Ollama démarré${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ Erreur: Impossible de démarrer Ollama${NC}"
|
||||||
|
echo "Vérifiez les logs: /tmp/ollama.log"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}✅ Ollama déjà actif${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier les modèles
|
||||||
|
echo ""
|
||||||
|
echo "🤖 Vérification des modèles..."
|
||||||
|
MODELS=$(ollama list | grep -c "code-expert\|qwen2.5-coder")
|
||||||
|
if [ "$MODELS" -eq 0 ]; then
|
||||||
|
echo -e "${YELLOW}⚠️ Aucun modèle de code détecté${NC}"
|
||||||
|
echo "Téléchargement de qwen2.5-coder:7b..."
|
||||||
|
ollama pull qwen2.5-coder:7b
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Installer les dépendances python3 si nécessaire
|
||||||
|
echo ""
|
||||||
|
echo "📚 Vérification des dépendances python3..."
|
||||||
|
cd "$SCRIPT_DIR/backend"
|
||||||
|
|
||||||
|
if [ ! -d "venv" ]; then
|
||||||
|
echo "Création de l'environnement virtuel..."
|
||||||
|
python3 -m venv venv
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Utiliser . au lieu de source pour compatibilité sh
|
||||||
|
. venv/bin/activate
|
||||||
|
|
||||||
|
if ! pip show fastapi > /dev/null 2>&1; then
|
||||||
|
echo "Installation des dépendances..."
|
||||||
|
pip install -q -r requirements.txt
|
||||||
|
echo -e "${GREEN}✅ Dépendances installées${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}✅ Dépendances OK${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Démarrer le backend FastAPI
|
||||||
|
echo ""
|
||||||
|
echo "🔧 Démarrage du backend FastAPI..."
|
||||||
|
python3 main.py > /tmp/fastapi.log 2>&1 &
|
||||||
|
BACKEND_PID=$!
|
||||||
|
|
||||||
|
# Attendre que le backend soit prêt
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
if kill -0 $BACKEND_PID 2>/dev/null; then
|
||||||
|
echo -e "${GREEN}✅ Backend démarré (PID: $BACKEND_PID)${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ Erreur: Backend n'a pas démarré${NC}"
|
||||||
|
echo "Vérifiez les logs: /tmp/fastapi.log"
|
||||||
|
cat /tmp/fastapi.log
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Démarrer un serveur HTTP simple pour le frontend
|
||||||
|
echo ""
|
||||||
|
echo "🌐 Démarrage du frontend..."
|
||||||
|
cd "$SCRIPT_DIR/frontend"
|
||||||
|
|
||||||
|
# Vérifier que index.html existe
|
||||||
|
if [ ! -f "index.html" ]; then
|
||||||
|
echo -e "${RED}❌ Erreur: index.html introuvable dans $(pwd)${NC}"
|
||||||
|
echo "Contenu du dossier:"
|
||||||
|
ls -la
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tuer l'ancien serveur s'il existe
|
||||||
|
pkill -f "python3.*http.server.*9000" 2>/dev/null
|
||||||
|
|
||||||
|
python3 -m http.server 9000 > /tmp/frontend.log 2>&1 &
|
||||||
|
FRONTEND_PID=$!
|
||||||
|
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
if kill -0 $FRONTEND_PID 2>/dev/null; then
|
||||||
|
echo -e "${GREEN}✅ Frontend démarré (PID: $FRONTEND_PID)${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ Erreur: Frontend n'a pas démarré${NC}"
|
||||||
|
cat /tmp/frontend.log
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sauvegarder les PIDs
|
||||||
|
echo $BACKEND_PID > /tmp/ai-assistant-backend.pid
|
||||||
|
echo $FRONTEND_PID > /tmp/ai-assistant-frontend.pid
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "========================================"
|
||||||
|
echo -e "${GREEN}🎉 AI Code Assistant est prêt !${NC}"
|
||||||
|
echo "========================================"
|
||||||
|
echo ""
|
||||||
|
echo "📊 Informations:"
|
||||||
|
echo " - Backend API: http://localhost:9001"
|
||||||
|
echo " - Frontend: http://localhost:9000"
|
||||||
|
echo " - WebSocket: ws://localhost:9001/ws/chat"
|
||||||
|
echo ""
|
||||||
|
echo "🔗 Accès:"
|
||||||
|
echo " Ouvrez votre navigateur sur: ${GREEN}http://localhost:9000${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "📝 Logs:"
|
||||||
|
echo " - Backend: /tmp/fastapi.log"
|
||||||
|
echo " - Frontend: /tmp/frontend.log"
|
||||||
|
echo " - Ollama: /tmp/ollama.log"
|
||||||
|
echo ""
|
||||||
|
echo "🛑 Pour arrêter:"
|
||||||
|
echo " bash stop.sh"
|
||||||
|
echo ""
|
||||||
|
echo "📋 Modèles disponibles:"
|
||||||
|
ollama list | grep -v "NAME"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Ouvrir le navigateur automatiquement (si sur Windows WSL)
|
||||||
|
if grep -qi microsoft /proc/version; then
|
||||||
|
echo "💡 Ouverture automatique du navigateur..."
|
||||||
|
cmd.exe /c start http://localhost:9000 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Suivre les logs en temps réel (optionnel)
|
||||||
|
# tail -f /tmp/fastapi.log
|
||||||
40
stop.sh
Normal file
40
stop.sh
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script d'arrêt pour AI Code Assistant
|
||||||
|
|
||||||
|
echo "🛑 Arrêt de AI Code Assistant..."
|
||||||
|
|
||||||
|
# Couleurs
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# Arrêter le backend
|
||||||
|
if [ -f /tmp/ai-assistant-backend.pid ]; then
|
||||||
|
BACKEND_PID=$(cat /tmp/ai-assistant-backend.pid)
|
||||||
|
if kill -0 $BACKEND_PID 2>/dev/null; then
|
||||||
|
kill $BACKEND_PID
|
||||||
|
echo -e "${GREEN}✅ Backend arrêté${NC}"
|
||||||
|
fi
|
||||||
|
rm /tmp/ai-assistant-backend.pid
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Arrêter le frontend
|
||||||
|
if [ -f /tmp/ai-assistant-frontend.pid ]; then
|
||||||
|
FRONTEND_PID=$(cat /tmp/ai-assistant-frontend.pid)
|
||||||
|
if kill -0 $FRONTEND_PID 2>/dev/null; then
|
||||||
|
kill $FRONTEND_PID
|
||||||
|
echo -e "${GREEN}✅ Frontend arrêté${NC}"
|
||||||
|
fi
|
||||||
|
rm /tmp/ai-assistant-frontend.pid
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tuer tous les processus http.server sur le port 9000
|
||||||
|
pkill -f "python.*http.server.*9000" 2>/dev/null
|
||||||
|
|
||||||
|
# Optionnel: arrêter Ollama (décommenter si souhaité)
|
||||||
|
# pkill ollama
|
||||||
|
# echo -e "${GREEN}✅ Ollama arrêté${NC}"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ Tous les services sont arrêtés"
|
||||||
Reference in New Issue
Block a user