Rapports et gestion des erreurs
- skills/reporting.py : REPORT: / REPORT_ERRORS: avec historique SQLite - skills/delegate.py : log des exécutions + détection erreurs + notification MQTT - skills/schedule_tasks.py : log des tâches planifiées - agent1.py : abonnement agents/errors + agents/scheduler/notifications → alerte XMPP - cli.py : commandes /report et /errors - system_prompt.txt : REPORT: et REPORT_ERRORS: ajoutés Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+49
-10
@@ -1,12 +1,10 @@
|
||||
"""
|
||||
Skill : DELEGATE
|
||||
Délègue une tâche à un agent spécialisé via MQTT et attend sa réponse.
|
||||
Log le résultat et notifie agent1 en cas d'erreur.
|
||||
|
||||
Commande :
|
||||
DELEGATE: <agent_name> | <tâche>
|
||||
|
||||
Exemple :
|
||||
DELEGATE: agent2_debian13 | Comment installer Docker sur Debian 13 ?
|
||||
"""
|
||||
import json
|
||||
import time
|
||||
@@ -19,13 +17,39 @@ TRIGGER = "DELEGATE:"
|
||||
|
||||
CONFIG_FILE = Path("/opt/agent/config/config.json")
|
||||
REGISTRY_FILE = Path("/opt/agent/config/agents_registry.json")
|
||||
TIMEOUT = 120 # secondes max d'attente
|
||||
TIMEOUT = 120
|
||||
|
||||
# Mots-clés indiquant une erreur dans la réponse d'un agent
|
||||
ERROR_KEYWORDS = ["erreur", "error", "timeout", "échec", "failed", "cannot", "permission denied",
|
||||
"command not found", "no such file", "connexion refusée"]
|
||||
|
||||
def _load():
|
||||
cfg = json.loads(CONFIG_FILE.read_text())
|
||||
registry = json.loads(REGISTRY_FILE.read_text())
|
||||
return cfg, registry
|
||||
|
||||
def _is_error(result: str) -> bool:
|
||||
lower = result.lower()
|
||||
if "[erreur" in lower or "exit code" in lower:
|
||||
return True
|
||||
return any(kw in lower for kw in ERROR_KEYWORDS)
|
||||
|
||||
def _notify_error(host: str, port: int, agent: str, task: str, result: str):
|
||||
"""Publie l'erreur sur le topic d'erreurs pour que agent1 notifie l'utilisateur."""
|
||||
try:
|
||||
payload = json.dumps({
|
||||
"agent" : agent,
|
||||
"task" : task[:200],
|
||||
"error" : result[:500],
|
||||
"source" : "delegate"
|
||||
})
|
||||
pub = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="delegate_err_pub")
|
||||
pub.connect(host, port)
|
||||
pub.publish("agents/errors", payload)
|
||||
pub.disconnect()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def execute(args: str) -> str:
|
||||
if "|" not in args:
|
||||
return "Erreur : format attendu → DELEGATE: <agent> | <tâche>"
|
||||
@@ -44,21 +68,19 @@ def execute(args: str) -> str:
|
||||
host = cfg.get("mqtt_host", "localhost")
|
||||
port = int(cfg.get("mqtt_port", 1883))
|
||||
|
||||
response_received = threading.Event()
|
||||
response_received = threading.Event()
|
||||
response_container = []
|
||||
|
||||
def on_message(client, userdata, msg):
|
||||
response_container.append(msg.payload.decode(errors="replace"))
|
||||
response_received.set()
|
||||
|
||||
# Souscription à la réponse
|
||||
sub = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="agent1_delegate_sub")
|
||||
sub.on_message = on_message
|
||||
sub.connect(host, port)
|
||||
sub.subscribe(outbox)
|
||||
sub.loop_start()
|
||||
|
||||
# Envoi de la tâche
|
||||
pub = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="agent1_delegate_pub")
|
||||
pub.connect(host, port)
|
||||
pub.publish(inbox, task)
|
||||
@@ -66,11 +88,28 @@ def execute(args: str) -> str:
|
||||
|
||||
print("[DELEGATE] Tâche envoyée à {} : {}".format(agent_name, task[:80]))
|
||||
|
||||
# Attente de la réponse
|
||||
start = time.time()
|
||||
received = response_received.wait(timeout=TIMEOUT)
|
||||
duration = time.time() - start
|
||||
|
||||
sub.loop_stop()
|
||||
sub.disconnect()
|
||||
|
||||
from skills.reporting import log_execution
|
||||
|
||||
if received and response_container:
|
||||
return "[{}] {}".format(agent_name, response_container[0])
|
||||
return "Timeout : {} n'a pas répondu dans les {}s.".format(agent_name, TIMEOUT)
|
||||
result = response_container[0]
|
||||
status = "error" if _is_error(result) else "success"
|
||||
log_execution("delegate", agent_name, task, status, result, duration)
|
||||
|
||||
if status == "error":
|
||||
_notify_error(host, port, agent_name, task, result)
|
||||
print("[DELEGATE] Erreur détectée dans la réponse de {}".format(agent_name))
|
||||
|
||||
return "[{}] {}".format(agent_name, result)
|
||||
|
||||
# Timeout
|
||||
timeout_msg = "Timeout : {} n'a pas répondu dans les {}s.".format(agent_name, TIMEOUT)
|
||||
log_execution("delegate", agent_name, task, "timeout", timeout_msg, duration)
|
||||
_notify_error(host, port, agent_name, task, timeout_msg)
|
||||
return timeout_msg
|
||||
|
||||
Reference in New Issue
Block a user