Batch 3 : commandes !agentON/OFF, mode veille, rapports journaliers
agent1.py : - !agentOFF/ON <nom> : pause/resume d'un agent via MQTT control - !agentsOFF/ON : mode veille agent1 + pause/resume tous les agents - Confirmation en attente pour modif config (PENDING_CONFIG) - !reports / !tasks / !blackout : afficher les configs - APScheduler : sollicitation rapports + rapport journalier automatique - Souscription agents/daily_report : stockage des rapports reçus - on_mqtt_register : préserve work_hours lors des mises à jour registre skills/daily_report.py : - DAILY_REPORT: [agent] : compile les rapports journaliers reçus - Formatage uptime, stats, taux de succès Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
"""
|
||||
Skill : DAILY_REPORT
|
||||
Compile et formate le rapport journalier de tous les agents.
|
||||
|
||||
Commande :
|
||||
DAILY_REPORT: → rapport du jour
|
||||
DAILY_REPORT: <agent> → rapport d'un agent spécifique
|
||||
"""
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
SKILL_NAME = "daily_report"
|
||||
TRIGGER = "DAILY_REPORT:"
|
||||
|
||||
|
||||
def _fmt_uptime(seconds: int) -> str:
|
||||
if seconds < 60:
|
||||
return "{}s".format(seconds)
|
||||
elif seconds < 3600:
|
||||
return "{}m{}s".format(seconds // 60, seconds % 60)
|
||||
else:
|
||||
h = seconds // 3600
|
||||
m = (seconds % 3600) // 60
|
||||
return "{}h{}m".format(h, m)
|
||||
|
||||
|
||||
def compile_report(daily_reports: dict, agent_filter: str = None) -> str:
|
||||
"""
|
||||
Compile les rapports reçus des agents en un texte formaté.
|
||||
daily_reports : {agent_name: {tasks_today, success, errors, avg_duration_s,
|
||||
last_error, pending, uptime_s, paused, timestamp}}
|
||||
"""
|
||||
now = datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||
lines = ["=== RAPPORT JOURNALIER — {} ===".format(now), ""]
|
||||
|
||||
if not daily_reports:
|
||||
lines.append("Aucun rapport reçu des agents.")
|
||||
return "\n".join(lines)
|
||||
|
||||
agents = {k: v for k, v in daily_reports.items()
|
||||
if agent_filter is None or k == agent_filter}
|
||||
|
||||
if not agents:
|
||||
return "Aucun rapport pour l'agent '{}'.".format(agent_filter)
|
||||
|
||||
total_tasks = 0
|
||||
total_errors = 0
|
||||
|
||||
for agent_name, data in sorted(agents.items()):
|
||||
tasks = data.get("tasks_today", 0)
|
||||
success = data.get("success", 0)
|
||||
errors = data.get("errors", 0)
|
||||
avg_dur = data.get("avg_duration_s", 0)
|
||||
pending = data.get("pending", 0)
|
||||
uptime = data.get("uptime_s", 0)
|
||||
paused = data.get("paused", False)
|
||||
last_err= data.get("last_error")
|
||||
ts = data.get("timestamp", "?")
|
||||
|
||||
total_tasks += tasks
|
||||
total_errors += errors
|
||||
|
||||
state = "[EN PAUSE]" if paused else "[ACTIF]"
|
||||
lines.append("── {} {} ──".format(agent_name, state))
|
||||
lines.append(" Rapport : {}".format(ts))
|
||||
lines.append(" Uptime : {}".format(_fmt_uptime(uptime)))
|
||||
lines.append(" Tâches : {} total, {} succès, {} erreurs".format(tasks, success, errors))
|
||||
if pending:
|
||||
lines.append(" En attente : {}".format(pending))
|
||||
if avg_dur:
|
||||
lines.append(" Durée moy : {:.1f}s".format(avg_dur))
|
||||
if last_err:
|
||||
lines.append(" Dernière erreur : {}".format(str(last_err)[:150]))
|
||||
lines.append("")
|
||||
|
||||
if len(agents) > 1:
|
||||
lines.append("── TOTAL ──")
|
||||
lines.append(" Tâches : {} | Erreurs : {}".format(total_tasks, total_errors))
|
||||
if total_tasks > 0:
|
||||
rate = round((total_tasks - total_errors) / total_tasks * 100, 1)
|
||||
lines.append(" Taux de succès : {}%".format(rate))
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def execute(args: str) -> str:
|
||||
"""
|
||||
Appelé par le LLM via DAILY_REPORT:.
|
||||
Lit les rapports stockés dans agent1.daily_reports.
|
||||
"""
|
||||
import sys
|
||||
# Accéder aux rapports stockés dans agent1 (module principal)
|
||||
agent_filter = args.strip() or None
|
||||
daily_reports = {}
|
||||
try:
|
||||
# agent1.py est le __main__, on récupère ses daily_reports via sys.modules
|
||||
main_mod = sys.modules.get("__main__")
|
||||
if main_mod and hasattr(main_mod, "daily_reports"):
|
||||
daily_reports = main_mod.daily_reports
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return compile_report(daily_reports, agent_filter)
|
||||
Reference in New Issue
Block a user