Suivi temps réel des agents : MQTT status/retain + injection dynamique dans le prompt

- on_mqtt_status : dict AGENTS_ONLINE + agents_online.json + notif XMPP si changement
- _get_agents_context() : liste agents avec statut [EN LIGNE/hors ligne] à chaque LLM call
- system_prompt : retrait liste hardcodée, agents injectés dynamiquement

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 21:24:25 +00:00
parent dbda0787a2
commit 576caa2621
2 changed files with 60 additions and 10 deletions
+53 -3
View File
@@ -40,7 +40,26 @@ SYSTEM_PROMPT = load_system_prompt()
load_skills()
conversation_history = []
xmpp_bot = None # référence globale pour répondre via XMPP depuis MQTT
xmpp_bot = None # référence globale pour répondre via XMPP depuis MQTT
AGENTS_ONLINE = {} # {agent_name: {status, jid, mqtt_inbox, last_seen}}
REGISTRY_FILE = CONFIG_DIR / "agents_registry.json"
AGENTS_ONLINE_FILE = CONFIG_DIR / "agents_online.json"
def _get_agents_context() -> str:
"""Construit dynamiquement la liste des agents (registre + statut en ligne)."""
try:
registry = json.loads(REGISTRY_FILE.read_text(encoding="utf-8"))
except Exception:
registry = {}
if not registry:
return "Aucun agent enregistré."
lines = ["Agents disponibles :"]
for name, info in registry.items():
online = name in AGENTS_ONLINE and AGENTS_ONLINE[name].get("status") == "online"
status = "[EN LIGNE]" if online else "[hors ligne]"
lines.append("- {} {} : {}".format(name, status, info.get("speciality", "")))
return "\n".join(lines)
# ── LLM ──────────────────────────────────────────────────────────────────
def call_ollama(messages: list) -> str:
@@ -57,7 +76,8 @@ def ask_llm(user_message: str, history: list = None) -> str:
if history is None:
history = conversation_history
history.append({"role": "user", "content": user_message})
messages = [{"role": "system", "content": SYSTEM_PROMPT}] + history
full_prompt = SYSTEM_PROMPT + "\n\n" + _get_agents_context()
messages = [{"role": "system", "content": full_prompt}] + history
try:
MAX_STEPS = 10
for _ in range(MAX_STEPS):
@@ -133,6 +153,34 @@ def on_mqtt_notification(client, userdata, msg):
except Exception as e:
print("[MQTT] Erreur parsing notification scheduler : {}".format(e))
def on_mqtt_status(client, userdata, msg):
"""Suit le statut en ligne/hors-ligne des agents (LWT + retain)."""
import time
try:
data = json.loads(msg.payload.decode(errors="replace"))
agent = data.get("agent", "?")
status = data.get("status", "?")
was_online = AGENTS_ONLINE.get(agent, {}).get("status") == "online"
AGENTS_ONLINE[agent] = {**data, "last_seen": time.time()}
# Sauvegarder pour la skill agents_online
AGENTS_ONLINE_FILE.write_text(
json.dumps(AGENTS_ONLINE, indent=2, ensure_ascii=False), encoding="utf-8")
# Notifier sylvain uniquement si le statut change
is_online = status == "online"
if is_online == was_online:
return
emoji = "[EN LIGNE]" if is_online else "[HORS LIGNE]"
print("[STATUS] {}{}".format(agent, status))
if xmpp_bot:
xmpp_bot.send_message(mto=ADMIN_JID,
mbody="{} {}".format(emoji, agent),
mtype='chat')
except Exception as e:
print("[MQTT] Erreur parsing status : {}".format(e))
def on_mqtt_register(client, userdata, msg):
"""Reçoit les déclarations de mise en ligne des agents et met à jour le registre."""
try:
@@ -183,6 +231,7 @@ def start_mqtt_listener():
sub.message_callback_add("agents/errors", on_mqtt_error)
sub.message_callback_add("agents/scheduler/notifications", on_mqtt_notification)
sub.message_callback_add("agents/register", on_mqtt_register)
sub.message_callback_add("agents/status/+", on_mqtt_status)
sub.on_message = on_mqtt_message # fallback
sub.connect(MQTT_HOST, MQTT_PORT)
sub.subscribe([
@@ -190,8 +239,9 @@ def start_mqtt_listener():
("agents/errors", 0),
("agents/scheduler/notifications", 0),
("agents/register", 0),
("agents/status/+", 0),
])
print("[MQTT] Agent1 écoute sur {}, agents/errors, agents/scheduler/notifications, agents/register".format(MQTT_INBOX))
print("[MQTT] Agent1 écoute sur {}, agents/errors, agents/status/+, agents/register".format(MQTT_INBOX))
sub.loop_forever()
# ── BOT XMPP ─────────────────────────────────────────────────────────────