fix: script.py guillemets, cron bad minute, system_prompt scripts bash
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -25,7 +25,25 @@ Tu reçois des instructions via MQTT (depuis Nexus) ou XMPP.
|
|||||||
- Réponds en français, sois concis
|
- Réponds en français, sois concis
|
||||||
- Si un playbook échoue, analyse la sortie et propose une correction
|
- Si un playbook échoue, analyse la sortie et propose une correction
|
||||||
|
|
||||||
## Communication MQTT
|
## Écriture de scripts bash — règles strictes
|
||||||
|
|
||||||
|
### ❌ Interdit dans les scripts bash
|
||||||
|
- `muc_send`, `mqtt_send`, `shell` et tous les noms de skills — ce ne sont PAS des commandes bash
|
||||||
|
- Les guillemets échappés : écris `"texte"` et non `\"texte\"`
|
||||||
|
|
||||||
|
### ✅ Pour envoyer un message depuis un script
|
||||||
|
Variables injectées automatiquement : `$MQTT_BROKER`, `$MQTT_REPLY_TOPIC`, `$AGENT_ID`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mosquitto_pub -h "$MQTT_BROKER" -t "$MQTT_REPLY_TOPIC" -m "mon résultat"
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✅ Bonnes pratiques
|
||||||
|
- Commence toujours par `#!/bin/bash` et `set -euo pipefail`
|
||||||
|
- Guillemets doubles autour des variables : `"$VAR"`
|
||||||
|
- Gère les cas d'erreur avec des messages explicites
|
||||||
|
|
||||||
|
## Communication MQTT (depuis le LLM, pas depuis un script)
|
||||||
|
|
||||||
Tu peux envoyer des messages à d'autres agents :
|
Tu peux envoyer des messages à d'autres agents :
|
||||||
SKILL:mqtt_send ARGS:agents/nexus/inbox | résultat ou information importante
|
SKILL:mqtt_send ARGS:agents/nexus/inbox | résultat ou information importante
|
||||||
|
|||||||
+21
-7
@@ -35,6 +35,16 @@ def _run(cmd: str, timeout: int = 10) -> str:
|
|||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_current_crontab() -> str:
|
||||||
|
"""Retourne le crontab actuel, ou chaîne vide si inexistant."""
|
||||||
|
result = subprocess.run(
|
||||||
|
"crontab -l", shell=True, text=True, capture_output=True
|
||||||
|
)
|
||||||
|
if result.returncode != 0:
|
||||||
|
return ""
|
||||||
|
return result.stdout.strip()
|
||||||
|
|
||||||
|
|
||||||
def run(args: str, context) -> str:
|
def run(args: str, context) -> str:
|
||||||
parts = args.strip().split(None, 1)
|
parts = args.strip().split(None, 1)
|
||||||
action = parts[0].lower() if parts else "list"
|
action = parts[0].lower() if parts else "list"
|
||||||
@@ -54,26 +64,28 @@ def run(args: str, context) -> str:
|
|||||||
command = " ".join(words[5:])
|
command = " ".join(words[5:])
|
||||||
entry = f"{cron_expr} {command}"
|
entry = f"{cron_expr} {command}"
|
||||||
|
|
||||||
current = _run("crontab -l 2>/dev/null")
|
current = _get_current_crontab()
|
||||||
if entry in current:
|
if entry in current:
|
||||||
return f"Cette entrée existe déjà : {entry}"
|
return f"Cette entrée existe déjà : {entry}"
|
||||||
|
|
||||||
def _do_add():
|
def _do_add():
|
||||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".cron", delete=False) as f:
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".cron", delete=False) as f:
|
||||||
if current and "no crontab" not in current.lower():
|
if current:
|
||||||
f.write(current + "\n")
|
f.write(current + "\n")
|
||||||
f.write(entry + "\n")
|
f.write(entry + "\n")
|
||||||
tmpfile = f.name
|
tmpfile = f.name
|
||||||
out = _run(f"crontab {tmpfile}")
|
result = subprocess.run(f"crontab {tmpfile}", shell=True, text=True, capture_output=True)
|
||||||
os.unlink(tmpfile)
|
os.unlink(tmpfile)
|
||||||
return f"Entrée ajoutée : {entry}\n{out}"
|
if result.returncode != 0:
|
||||||
|
return f"❌ Erreur crontab : {(result.stdout + result.stderr).strip()}"
|
||||||
|
return f"✅ Entrée ajoutée : {entry}"
|
||||||
|
|
||||||
return _confirm_or_execute(context, f"Ajouter cron : {entry}", _do_add)
|
return _confirm_or_execute(context, f"Ajouter cron : {entry}", _do_add)
|
||||||
|
|
||||||
if action == "remove":
|
if action == "remove":
|
||||||
if not rest:
|
if not rest:
|
||||||
return "Précise le pattern à supprimer."
|
return "Précise le pattern à supprimer."
|
||||||
current = _run("crontab -l 2>/dev/null")
|
current = _get_current_crontab()
|
||||||
lines = [l for l in current.splitlines() if rest not in l]
|
lines = [l for l in current.splitlines() if rest not in l]
|
||||||
removed_count = len(current.splitlines()) - len(lines)
|
removed_count = len(current.splitlines()) - len(lines)
|
||||||
if removed_count == 0:
|
if removed_count == 0:
|
||||||
@@ -84,9 +96,11 @@ def run(args: str, context) -> str:
|
|||||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".cron", delete=False) as f:
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".cron", delete=False) as f:
|
||||||
f.write(new_cron + "\n")
|
f.write(new_cron + "\n")
|
||||||
tmpfile = f.name
|
tmpfile = f.name
|
||||||
out = _run(f"crontab {tmpfile}")
|
result = subprocess.run(f"crontab {tmpfile}", shell=True, text=True, capture_output=True)
|
||||||
os.unlink(tmpfile)
|
os.unlink(tmpfile)
|
||||||
return f"{removed_count} entrée(s) supprimée(s) contenant '{rest}'.\n{out}"
|
if result.returncode != 0:
|
||||||
|
return f"❌ Erreur crontab : {(result.stdout + result.stderr).strip()}"
|
||||||
|
return f"✅ {removed_count} entrée(s) supprimée(s) contenant '{rest}'."
|
||||||
|
|
||||||
return _confirm_or_execute(context, f"Supprimer {removed_count} cron contenant '{rest}'", _do_remove)
|
return _confirm_or_execute(context, f"Supprimer {removed_count} cron contenant '{rest}'", _do_remove)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -147,7 +147,7 @@ def run(args: str, context) -> str:
|
|||||||
return "Format : save <nom> | <contenu du script>"
|
return "Format : save <nom> | <contenu du script>"
|
||||||
name_raw, content = rest.split("|", 1)
|
name_raw, content = rest.split("|", 1)
|
||||||
name = _safe_name(name_raw)
|
name = _safe_name(name_raw)
|
||||||
content = content.strip().replace("\\n", "\n")
|
content = content.strip().replace("\\n", "\n").replace('\\"', '"').replace("\\'", "'")
|
||||||
|
|
||||||
if not name:
|
if not name:
|
||||||
return "Nom de script invalide."
|
return "Nom de script invalide."
|
||||||
|
|||||||
Reference in New Issue
Block a user