From 6efb9afe0bf1ea620ee1f0e0983b8a89dbde6cbb Mon Sep 17 00:00:00 2001 From: sylvain Date: Sat, 7 Mar 2026 12:41:41 +0000 Subject: [PATCH] =?UTF-8?q?Ajouter=20skill=20EXEC=20(ex=C3=A9cution=20comm?= =?UTF-8?q?andes=20shell)=20+=20system=20prompt=20mis=20=C3=A0=20jour?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/system_prompt.txt | 17 +++++++++-- skills/shell_exec.py | 64 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 skills/shell_exec.py diff --git a/config/system_prompt.txt b/config/system_prompt.txt index 79f01ef..e3b962e 100644 --- a/config/system_prompt.txt +++ b/config/system_prompt.txt @@ -1,5 +1,6 @@ Tu es agent2_debian13, un agent autonome spécialisé dans l'administration de systèmes Debian. Tu travailles sous les ordres d'agent1 qui te délègue des tâches via MQTT. +Tu as accès au système réel et peux exécuter des commandes shell. Tes domaines de compétence : - Gestion des paquets : apt, dpkg, snap @@ -13,6 +14,14 @@ Tes domaines de compétence : Formats de commandes disponibles : +EXEC: + → Exécuter une commande sur le système et récupérer le résultat + → Exemples : + EXEC: systemctl status nginx + EXEC: apt install -y curl + EXEC: docker ps -a + EXEC: journalctl -u ssh --no-pager -n 20 + SEARCH: → Recherche web si besoin de documentation @@ -28,7 +37,9 @@ RECALL: ⚠ RÈGLES : - Tu reçois des tâches d'agent1 via MQTT et tu lui réponds via MQTT - Tu peux aussi recevoir des instructions directement de sylvain via XMPP -- Réponds de façon claire, concise et technique -- Si une commande shell est nécessaire, indique-la explicitement avec des blocs de code +- Pour toute tâche système : utilise EXEC: pour l'exécuter réellement, pas juste expliquer +- Enchaîne plusieurs EXEC: si nécessaire pour accomplir une tâche complexe +- Vérifie toujours le résultat d'une commande avant de passer à la suivante +- Si une commande échoue, analyse l'erreur et adapte-toi - Signale à agent1 si une tâche est hors de ton domaine Debian -- Réponds toujours en français +- Réponds toujours en français avec un résumé clair de ce qui a été fait diff --git a/skills/shell_exec.py b/skills/shell_exec.py new file mode 100644 index 0000000..bbc85c5 --- /dev/null +++ b/skills/shell_exec.py @@ -0,0 +1,64 @@ +""" +Skill : EXEC +Exécute une commande shell sur le système et retourne le résultat. + +Commande : + EXEC: + +Exemples : + EXEC: apt list --upgradable + EXEC: systemctl status nginx + EXEC: df -h + EXEC: docker ps -a +""" +import subprocess +from shlex import split as shlex_split + +SKILL_NAME = "shell_exec" +TRIGGER = "EXEC:" + +TIMEOUT = 30 # secondes max par commande +MAX_CHARS = 3000 # taille max de l'output retourné + +# Commandes interdites même en contexte de confiance +BLACKLIST = ["rm -rf /", "mkfs", ":(){:|:&};:", "dd if=/dev/zero of=/dev/sd"] + +def execute(args: str) -> str: + cmd = args.strip() + if not cmd: + return "Erreur : commande vide." + + # Vérification blacklist basique + for forbidden in BLACKLIST: + if forbidden in cmd: + return "Commande refusée pour des raisons de sécurité : {}".format(forbidden) + + try: + result = subprocess.run( + cmd, + shell=True, + capture_output=True, + text=True, + timeout=TIMEOUT + ) + stdout = result.stdout.strip() + stderr = result.stderr.strip() + + output = "" + if stdout: + output += stdout + if stderr: + output += ("\n[stderr] " + stderr) if output else "[stderr] " + stderr + if not output: + output = "(aucune sortie)" + + if len(output) > MAX_CHARS: + output = output[:MAX_CHARS] + "\n...[tronqué]" + + status = "OK" if result.returncode == 0 else "Erreur (code {})".format(result.returncode) + return "[{}] $ {}\n{}".format(status, cmd, output) + + except subprocess.TimeoutExpired: + return "Timeout : la commande a dépassé {}s : {}".format(TIMEOUT, cmd) + except Exception as e: + return "Erreur d'exécution : {}".format(e)