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