feat: commande /llm — switch LLM global local/cloud

- /llm : statut actuel + profils configurés
- /llm local|cloud : switch tous les agents
- /llm list : liste les modèles Ollama (local vs cloud)
- /llm set local|cloud <model> : définit un profil et l'active
- Broadcast via MQTT retained agents/llm/switch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 17:35:31 +00:00
parent 57fe04a6f8
commit 8626161883
+84
View File
@@ -244,6 +244,9 @@ class Nexus(BaseAgent):
self.mqtt.send_to(target, "/update", msg_type=MessageType.COMMAND) self.mqtt.send_to(target, "/update", msg_type=MessageType.COMMAND)
return f"Mise à jour demandée à {target}." return f"Mise à jour demandée à {target}."
if cmd == "llm":
return self._handle_llm_command(args)
if cmd == "admins": if cmd == "admins":
return self._handle_admins_command(args) return self._handle_admins_command(args)
@@ -252,6 +255,83 @@ class Nexus(BaseAgent):
return f"Commande inconnue : /{cmd}. Tape /help." return f"Commande inconnue : /{cmd}. Tape /help."
def _handle_llm_command(self, args: str) -> str:
"""
/llm → statut actuel
/llm local → switch tous les agents vers le profil local
/llm cloud → switch tous les agents vers le profil cloud
/llm list → liste les modèles Ollama disponibles
/llm set local <model> → définit + active le profil local
/llm set cloud <model> → définit + active le profil cloud
"""
args = args.strip()
if not args:
current = self.config["llm"]["model"]
profiles = self.config.get("llm_profiles", {})
local = profiles.get("local", "non configuré")
cloud = profiles.get("cloud", "non configuré")
tag = "cloud" if ":cloud" in current else "local"
return (
f"── LLM actif : {current} ({tag}) ──\n"
f" local : {local}\n"
f" cloud : {cloud}\n"
f"Commandes : /llm local | /llm cloud | /llm list\n"
f" /llm set local <model> | /llm set cloud <model>"
)
if args in ("local", "cloud"):
profiles = self.config.get("llm_profiles", {})
model = profiles.get(args)
if not model:
return f"Profil '{args}' non configuré. Utilise : /llm set {args} <model>"
return self._switch_all_llm(args, model)
if args == "list":
return self._list_ollama_models()
if args.startswith("set "):
rest = args[4:].strip().split(None, 1)
if len(rest) < 2:
return "Usage : /llm set local <model> | /llm set cloud <model>"
profile, model = rest[0].lower(), rest[1].strip()
if profile not in ("local", "cloud"):
return "Profil invalide : utilise 'local' ou 'cloud'."
return self._switch_all_llm(profile, model)
return "Usage : /llm | /llm local | /llm cloud | /llm list | /llm set local|cloud <model>"
def _switch_all_llm(self, profile: str, model: str) -> str:
"""Broadcast le switch LLM à tous les agents + applique localement."""
import json as _json
payload = _json.dumps({"profile": profile, "model": model})
self.mqtt.publish_raw("agents/llm/switch", payload, retain=True)
# Application locale immédiate
self.llm.model = model
self.config["llm"]["model"] = model
self.config.setdefault("llm_profiles", {})[profile] = model
self._save_config()
return f"✅ Switch LLM → {model} (profil {profile}) appliqué à tous les agents."
def _list_ollama_models(self) -> str:
"""Liste les modèles disponibles sur Ollama, séparés local/cloud."""
import requests as _req
base_url = self.config["llm"]["base_url"]
try:
resp = _req.get(f"{base_url}/api/tags", timeout=10)
resp.raise_for_status()
models = resp.json().get("models", [])
local = sorted(m["name"] for m in models if ":cloud" not in m["name"])
cloud = sorted(m["name"] for m in models if ":cloud" in m["name"])
lines = [f"── Modèles Ollama ({base_url}) ──"]
lines.append("Local :")
lines.extend(f" {m}" for m in local)
lines.append("Cloud :")
lines.extend(f" {m}" for m in cloud)
return "\n".join(lines)
except Exception as e:
return f"Erreur Ollama : {e}"
def _handle_admins_command(self, args: str) -> str: def _handle_admins_command(self, args: str) -> str:
""" """
/admins → liste les admins autorisés /admins → liste les admins autorisés
@@ -336,6 +416,10 @@ class Nexus(BaseAgent):
/schedule <freq> @a tâche — Planifier une tâche /schedule <freq> @a tâche — Planifier une tâche
/schedules — Voir les tâches planifiées /schedules — Voir les tâches planifiées
/update <agent> — Mettre à jour un agent (git pull) /update <agent> — Mettre à jour un agent (git pull)
/llm — Statut et gestion du LLM
/llm local|cloud — Switch le modèle pour tous les agents
/llm list — Lister les modèles Ollama disponibles
/llm set local|cloud <m> — Définir un profil et l'activer
/admins — Lister les utilisateurs autorisés /admins — Lister les utilisateurs autorisés
/admins add <jid> — Autoriser un nouvel utilisateur /admins add <jid> — Autoriser un nouvel utilisateur
/admins remove <jid> — Retirer un utilisateur /admins remove <jid> — Retirer un utilisateur