Public Access
Initialisation ultra propre d'Aethas38
This commit is contained in:
commit
bc700dfb44
3 files changed
+127
No files matched your search
@@ -0,0 +1,4 @@
|
||||
__pycache__/
|
||||
venv/
|
||||
.env
|
||||
.sesskey
|
||||
@@ -0,0 +1,38 @@
|
||||
# Aethas38 - Multi-IA Orchestrator
|
||||
|
||||
Système d'IA modulaire avec orchestrateur local et routeur intelligent.
|
||||
|
||||
## 📋 To-Do List (Roadmap)
|
||||
|
||||
### Phase 1 : Infrastructure & Environnement ✅
|
||||
- [x] Désactiver interface graphique serveur (mode headless)
|
||||
- [x] Installation Docker, Compose et Nginx Proxy Manager
|
||||
- [x] Configuration réseau (Pare-feu / Ports)
|
||||
- [x] Initialisation dépôts Gitea/GitHub
|
||||
|
||||
### Phase 2 : Orchestrateur Local (Backend) ⏳
|
||||
- [x] Installation Ollama + Qwen 2.5 3B (Serveur)
|
||||
- [x] Développement de l'interface de base FastHTML
|
||||
- [x] Connexion réussie entre PC de dev et Serveur IA
|
||||
- [X] Développement du script de Routage (Gateway)
|
||||
- [ ] Intégration des APIs tierces (Groq, Gemini, etc.)
|
||||
- [ ] Système de gestion de file d'attente (Queue List)
|
||||
- [ ] Création du système d'interdiction automatique (Fichiers refusés)
|
||||
|
||||
### Phase 3 : Front-Office (FastHTML)
|
||||
- [ ] Création UI légère (Thème Aethas)
|
||||
- [ ] Implémentation du switch Gratuit/Payant
|
||||
- [ ] Dashboard Finance (Analyse consommation tokens)
|
||||
- [ ] Système d'inscription et validation Admin
|
||||
|
||||
### Phase 4 : Déploiement & Sécurité
|
||||
- [ ] Mise en conteneur Docker
|
||||
- [ ] Mise en production sur aethas38.duckdns.org
|
||||
- [ ] Tests de charge et vérification coûts
|
||||
|
||||
---
|
||||
## 💡 Informations Techniques
|
||||
* **Orchestrateur :** Local (Ollama / Qwen 2.5 3B)
|
||||
* **Framework Interface :** FastHTML
|
||||
* **Langage :** Python 3.12 (Environnement Virtuel)
|
||||
* **Serveur :** Debian (Headless, GTX 1650 4Go VRAM)
|
||||
@@ -0,0 +1,85 @@
|
||||
import os
|
||||
import json
|
||||
from dotenv import load_dotenv
|
||||
from fasthtml.common import *
|
||||
from openai import OpenAI
|
||||
|
||||
# Chargement du coffre-fort des clés API
|
||||
load_dotenv()
|
||||
|
||||
# Petit test pour vérifier que Python trouve bien les clés au démarrage
|
||||
print("Vérification des API :")
|
||||
print("- Groq chargée :", "✅" if os.getenv("GROQ_API_KEY") else "❌")
|
||||
print("- Gemini chargée :", "✅" if os.getenv("GEMINI_API_KEY") else "❌")
|
||||
|
||||
# Initialisation de l'application FastHTML
|
||||
app, rt = fast_app()
|
||||
|
||||
# Configuration du client local (Qwen)
|
||||
client = OpenAI(
|
||||
base_url="http://192.168.1.20:11434/v1",
|
||||
api_key="ollama"
|
||||
)
|
||||
|
||||
# Route principale : l'interface utilisateur
|
||||
@rt('/')
|
||||
def get():
|
||||
return Titled("Aethas38 - Orchestrateur",
|
||||
Main(
|
||||
H1("Interface de Test - Qwen 2.5 (3B)"),
|
||||
Form(
|
||||
Input(type="text", name="prompt", placeholder="Posez votre question à Qwen...", style="width: 100%; padding: 10px; margin-bottom: 10px;"),
|
||||
Button("Envoyer la requête", type="submit", style="padding: 10px 20px; cursor: pointer;"),
|
||||
hx_post="/chat", # Envoie la requête à la route /chat
|
||||
hx_target="#result", # Injecte la réponse dans la div "result"
|
||||
hx_indicator="#loading" # Affiche un indicateur de chargement
|
||||
),
|
||||
Div("Traitement en cours par le serveur Aethas38...", id="loading", cls="htmx-indicator", style="color: gray; font-style: italic; margin-top: 10px;"),
|
||||
Div(id="result", style="margin-top: 20px; padding: 15px; border: 1px solid #444; border-radius: 5px; background-color: #222; color: white;"),
|
||||
cls="container"
|
||||
)
|
||||
)
|
||||
|
||||
# Route API : Traitement de la requête par l'IA
|
||||
@rt('/chat')
|
||||
def post(prompt: str):
|
||||
try:
|
||||
# 1. Le Prompt Système amélioré pour éviter les pièges
|
||||
router_prompt = """Tu es l'Aiguilleur (Routeur) du projet Aethas38.
|
||||
Analyse la demande de l'utilisateur et choisis le fournisseur d'IA le plus adapté selon ces règles strictes :
|
||||
- "groq" : programmation, code, scripts, mathématiques, logique, informatique.
|
||||
- "gemini" : rédaction, recettes de cuisine, culture générale, histoire, résumés, art.
|
||||
- "local" : UNIQUEMENT pour les salutations (bonjour, test, coucou) ou les banalités très courtes.
|
||||
|
||||
Format de réponse obligatoire : un objet JSON strict. AUCUN texte d'accompagnement.
|
||||
Exemple 1 : {"intention": "créer un script", "fournisseur": "groq"}
|
||||
Exemple 2 : {"intention": "recette de gâteau", "fournisseur": "gemini"}
|
||||
"""
|
||||
|
||||
# 2. On interroge notre Qwen local (la GTX 1650 bosse !)
|
||||
response = client.chat.completions.create(
|
||||
model="qwen2.5:3b",
|
||||
messages=[
|
||||
{"role": "system", "content": router_prompt},
|
||||
{"role": "user", "content": prompt}
|
||||
],
|
||||
temperature=0.1 # Température basse pour qu'il soit très précis et formel
|
||||
)
|
||||
|
||||
# 3. On récupère et on lit sa décision brute
|
||||
raw_decision = response.choices[0].message.content
|
||||
|
||||
# 4. On l'affiche sur l'interface de test (temporaire, pour voir la magie opérer)
|
||||
return Div(
|
||||
P(f"🗣️ Votre question : {prompt}", style="color: #888;"),
|
||||
P("🧠 Décision de l'Orchestrateur (Qwen) :", style="color: #00d2ff; font-weight: bold; margin-top: 10px;"),
|
||||
Pre(raw_decision, style="background: #111; padding: 10px; border-radius: 5px; color: #0f0;"),
|
||||
style="border-left: 4px solid #00d2ff; padding-left: 15px; margin-top: 15px;"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return P(f"Erreur de l'orchestrateur : {e}", style="color: red; font-weight: bold;")
|
||||
|
||||
# Lancement du serveur local
|
||||
if __name__ == '__main__':
|
||||
serve(port=5001)
|
||||
Reference in new issue
Block a user