sylvain 7d7f1052f9 feat: confirmations cron/systemd, renforcement script skill, éditeur de script
- base_agent: _pending_confirmations + intercepteur oui/non dans _on_xmpp_message
- cron: add/remove/clear demandent confirmation (requêtes XMPP directes)
- systemd: start/stop/restart/enable/disable/mask/unmask/daemon-reload demandent confirmation
- script: _safe_name strip toutes les extensions, extensions système interdites,
  contenu vide rejeté, nouvelle commande edit <nom> <ligne> | <contenu>
- README mis à jour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 07:18:47 +00:00
2026-03-09 13:05:44 +00:00

agents_core

Bibliothèque partagée pour le système multi-agents. Fournit toutes les briques communes : communication MQTT/XMPP (avec chiffrement OMEMO), LLM, coordination des appels Ollama, gestion des tâches, chargement des skills, et découverte des capacités entre agents.

Installation

pip install -e /opt/agents_core

Architecture

XMPP (slixmpp + OMEMO)   MQTT (Mosquitto local)
utilisateur  ←→  nexus  ←→  agents/nexus/inbox
                          ←→  agents/+/status      (retained)
                          ←→  agents/+/capabilities (retained)
                          ←→  agents/broadcast
                          ←→  agents/llm/switch     (retained)
                          ←→  agents/llm/request    (coordinateur)
                          ←→  agents/llm/release    (coordinateur)
                          ←→  agents/scripts/execution

Modules

Fichier Rôle
base_agent.py Classe abstraite BaseAgent — à hériter dans chaque agent
mqtt_client.py Client MQTT (paho), reconnexion auto, publish/subscribe/unsubscribe/reply
xmpp_client.py Client XMPP (slixmpp 1.13), reconnexion auto, MUC, OMEMO E2E, thread-safe
omemo_storage.py Backend SQLite pour les clés/sessions OMEMO (XEP-0384, BTBV)
llm_client.py Wrapper Ollama — chat, historique, extraction de skill calls
llm_coordinator.py Coordinateur MQTT — limite les appels Ollama simultanés (sémaphore)
message_bus.py Enveloppe Message standard (type, payload, sender, reply_to…)
skill_loader.py Auto-découverte et exécution des plugins .py dans skills/
task_queue.py Queue SQLite FIFO avec worker thread
capabilities.py AgentCapabilities + CapabilitiesRegistry — annuaire des agents
command_parser.py Parse /cmd, @agent msg, langage naturel

Créer un agent

from agents_core import BaseAgent, AgentContext

class MonAgent(BaseAgent):
    AGENT_TYPE = "mon_type"
    DESCRIPTION = "Description courte utilisée pour le routage LLM"
    DEFAULT_CONFIG_PATH = "/opt/mon_agent/config/config.json"

    def get_skills_dir(self) -> str:
        return "/opt/mon_agent/skills"

    def on_start(self):
        self.mqtt.send_to("nexus", f"{self.agent_id} en ligne.")

if __name__ == "__main__":
    MonAgent().run()

Format config.json

{
  "agent_id": "mon_agent",
  "xmpp": {
    "jid": "mon_agent@xmpp.ovh",
    "password": "...",
    "admin_jid": "sylvain@xmpp.ovh",
    "muc_room": "agents@muc.xmpp.ovh"
  },
  "mqtt": {
    "host": "localhost",
    "port": 1883
  },
  "llm": {
    "base_url": "http://192.168.7.119:11434",
    "model": "qwen3:8b",
    "temperature": 0.3
  },
  "llm_profiles": {
    "local": "qwen3:8b",
    "cloud": "gpt-oss:120b-cloud"
  },
  "queue_db": "/opt/mon_agent/data/queue.db",
  "use_omemo": true,
  "use_llm_coordinator": true
}

Créer un skill

Un skill est un fichier .py dans le dossier skills/ de l'agent :

# skills/mon_skill.py

NAME = "mon_skill"
DESCRIPTION = "Fait quelque chose d'utile. Args: <paramètre>"

def run(args: str, context) -> str:
    # context.agent, context.mqtt, context.xmpp, context.llm, context.config
    return f"Résultat pour : {args}"

Le LLM appelle le skill avec : SKILL:mon_skill ARGS:paramètre

Hooks disponibles dans BaseAgent

Méthode Déclencheur
on_start() Au démarrage, après connexion MQTT
on_xmpp_connected() Quand la connexion XMPP est établie
on_agent_status_change(agent_id, status) Quand un agent passe online/offline
on_broadcast(msg) Réception d'un message broadcast MQTT
handle_custom_command(cmd, args, msg) Commande /xxx non gérée par BaseAgent
setup_extra_subscriptions() Pour ajouter des souscriptions MQTT custom

Commandes système intégrées (BaseAgent)

Toutes les commandes suivantes sont disponibles sur chaque agent :

/status    — État de la queue de tâches
/pause     — Pause du traitement
/resume    — Reprise
/report    — Rapport de l'agent
/update    — Git pull + redémarrage du service
/script    — Gestion de la bibliothèque de scripts bash
  list, show <nom>, save <nom> | <contenu>, edit <nom> <ligne> | <contenu>, exec <nom> [args], run | <inline>, delete <nom>

Mécanisme de confirmation

Les actions destructives demandent confirmation avant d'être exécutées lorsqu'elles proviennent d'un message XMPP direct (pas d'une délégation MQTT).

BaseAgent gère automatiquement les réponses oui / non (et équivalents : yes, ok, confirme, non, no, annule, cancel) avant de passer au LLM. Les skills utilisent context.agent._pending_confirmations[sender] pour enregistrer l'action en attente.

Topics MQTT

Topic Usage
agents/{id}/inbox Tâches entrantes
agents/{id}/status Statut online/offline (retained + LWT)
agents/{id}/capabilities Skills déclarés (retained)
agents/broadcast Message à tous les agents
agents/llm/switch Changement de modèle LLM global (retained)
agents/llm/request Demande de slot LLM (coordinateur)
agents/llm/release Libération de slot LLM (coordinateur)
agents/{id}/llm/grant/{uuid} Accord de slot LLM
agents/scripts/execution Notification d'exécution de script

Coordinateur LLM

Pour éviter de surcharger Ollama, un sémaphore MQTT limite les appels concurrents :

  • Nexus instancie LLMCoordinator(max_concurrent=1)
  • Chaque agent publie sur agents/llm/request avant d'appeler le LLM
  • Il attend le grant sur agents/{id}/llm/grant/{uuid} (timeout 90s)
  • Il publie sur agents/llm/release après

Dépendances

  • Python ≥ 3.10
  • paho-mqtt ≥ 1.6
  • slixmpp ≥ 1.13
  • slixmpp-omemo ≥ 2.1.0
  • requests ≥ 2.28
S
Description
Système multi-agents — agents_core
Readme 169 KiB
Languages
Python 100%