c3c073fe5a
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.3 KiB
5.3 KiB
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>, exec <nom> [args], run | <inline>, delete <nom>
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/requestavant d'appeler le LLM - Il attend le grant sur
agents/{id}/llm/grant/{uuid}(timeout 90s) - Il publie sur
agents/llm/releaseaprès
Dépendances
- Python ≥ 3.10
- paho-mqtt ≥ 1.6
- slixmpp ≥ 1.13
- slixmpp-omemo ≥ 2.1.0
- requests ≥ 2.28