Ajout !agentUPDATE/UPGRADE : mises à jour agents depuis git

- skills/agent_update.py : check_update (git fetch + log) et do_upgrade (git pull + systemctl restart)
- agent1.py : commandes !agentUPDATE <nom>, !agentsUPDATE, !agentUPGRADE <nom>, !agentsUPGRADE
  - _handle_agent_command retourne (handled, reply) pour gérer le self-upgrade agent1
  - !agentUPGRADE agent1 : envoie la réponse XMPP avant systemctl restart
  - !agentsUPGRADE : met à jour tous les agents puis agent1 en dernier
- agents_registry.json : ajout install_path, service_name, git_branch + entrée agent1
- README.md : documentation des nouvelles commandes
- TODO.md : tâches marquées comme terminées

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 15:55:31 +00:00
parent 1c951f46f1
commit 3575b391b6
5 changed files with 262 additions and 24 deletions
+101
View File
@@ -0,0 +1,101 @@
"""
Utilitaire : vérification et application des mises à jour git pour les agents.
Fonctions appelées directement depuis agent1.py (pas de trigger LLM).
check_update(name, install_path, branch) → rapport git fetch
do_upgrade(name, install_path, service, branch) → git pull + systemctl restart
"""
import subprocess
import shlex
from pathlib import Path
def _run(cmd: str, cwd: str = None, timeout: int = 30) -> tuple:
"""Lance une commande shell, retourne (stdout, stderr, returncode)."""
try:
result = subprocess.run(
shlex.split(cmd),
cwd=cwd,
capture_output=True,
text=True,
timeout=timeout
)
return result.stdout.strip(), result.stderr.strip(), result.returncode
except subprocess.TimeoutExpired:
return "", "Timeout ({} s)".format(timeout), -1
except Exception as e:
return "", str(e), -1
def check_update(agent_name: str, install_path: str, branch: str = "main") -> str:
"""
Vérifie si une mise à jour est disponible sur le dépôt distant.
Effectue un git fetch puis compare HEAD avec origin/<branch>.
"""
path = install_path
if not Path(path).is_dir():
return "[{}] Répertoire introuvable : {}".format(agent_name, path)
# git fetch
out, err, rc = _run("git fetch origin {}".format(branch), cwd=path, timeout=20)
if rc != 0:
return "[{}] Erreur git fetch : {}".format(agent_name, err or out)
# Compter les commits disponibles
out, err, rc = _run(
"git log HEAD..origin/{} --oneline".format(branch), cwd=path)
if rc != 0:
return "[{}] Erreur git log : {}".format(agent_name, err or out)
commits = [l for l in out.splitlines() if l.strip()]
if not commits:
return "[{}] Déjà à jour.".format(agent_name)
lines = ["[{}] {} commit(s) disponible(s) :".format(agent_name, len(commits))]
for c in commits[:10]:
lines.append(" {}".format(c))
if len(commits) > 10:
lines.append(" ... et {} autre(s)".format(len(commits) - 10))
lines.append("Lancez !agentUPGRADE {} pour appliquer.".format(agent_name))
return "\n".join(lines)
def do_upgrade(agent_name: str, install_path: str,
service_name: str, branch: str = "main",
self_upgrade: bool = False) -> str:
"""
Applique la mise à jour : git pull + systemctl restart.
Pour agent1 (self_upgrade=True), envoie la réponse AVANT le restart.
"""
path = install_path
if not Path(path).is_dir():
return "[{}] Répertoire introuvable : {}".format(agent_name, path)
# git pull
out, err, rc = _run(
"git pull origin {}".format(branch), cwd=path, timeout=60)
if rc != 0:
return "[{}] Erreur git pull : {}".format(agent_name, err or out)
pull_msg = out or "Déjà à jour."
if self_upgrade:
# On retourne le message AVANT le restart (agent1 l'envoie puis se redémarre)
return "[{}] {} \nRedémarrage en cours...".format(agent_name, pull_msg)
# systemctl restart
_, err, rc = _run("systemctl restart {}".format(service_name), timeout=15)
if rc != 0:
return "[{}] Pull OK mais restart échoué : {}".format(agent_name, err)
# Vérifier que le service est bien remonté
out, _, _ = _run("systemctl is-active {}".format(service_name), timeout=5)
state = out.strip()
if state == "active":
return "[{}] Mise à jour appliquée. Service actif.\n{}".format(agent_name, pull_msg)
else:
return "[{}] Pull OK, service état : {}. Vérifiez les logs.".format(
agent_name, state)