From af1d14e2023b139a4c84b9d6c6445c31fa3c7b02 Mon Sep 17 00:00:00 2001 From: sylvain Date: Mon, 9 Mar 2026 17:35:13 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20LLM=20switch=20via=20MQTT=20=E2=80=94?= =?UTF-8?q?=20profils=20local/cloud=20synchronis=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Stocke _config_path dans BaseAgent pour la persistance - Souscription à agents/llm/switch (retained) sur tous les agents - _on_llm_switch : change self.llm.model + persiste dans config.json - _save_config : écrit la config en mémoire dans le fichier JSON Co-Authored-By: Claude Sonnet 4.6 --- agents_core/base_agent.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/agents_core/base_agent.py b/agents_core/base_agent.py index 6598974..cd83fb9 100644 --- a/agents_core/base_agent.py +++ b/agents_core/base_agent.py @@ -80,7 +80,8 @@ class BaseAgent(ABC): DEFAULT_CONFIG_PATH: str = "config/config.json" def __init__(self, config_path: Optional[str] = None): - self.config = self._load_config(config_path or self.DEFAULT_CONFIG_PATH) + self._config_path = config_path or self.DEFAULT_CONFIG_PATH + self.config = self._load_config(self._config_path) self.agent_id: str = self.config["agent_id"] logging.basicConfig( @@ -233,6 +234,7 @@ class BaseAgent(ABC): self.mqtt.subscribe_broadcast(self._on_mqtt_broadcast) self.mqtt.subscribe_all_capabilities(self._on_capabilities_update) self.mqtt.subscribe_all_status(self._on_status_update) + self.mqtt.subscribe("agents/llm/switch", self._on_llm_switch) # Souscriptions custom de l'agent self.setup_extra_subscriptions() @@ -284,6 +286,36 @@ class BaseAgent(ABC): except Exception as e: logger.debug(f"Erreur parsing capabilities: {e}") + def _on_llm_switch(self, msg: Message | str, topic: str): + """Reçoit un ordre de switch LLM depuis le topic agents/llm/switch.""" + try: + import json as _json + raw = msg if isinstance(msg, str) else (msg.payload if isinstance(msg, Message) else str(msg)) + data = _json.loads(raw) + model = data.get("model") + profile = data.get("profile", "") + if not model: + return + if self.llm.model == model: + return # Déjà sur ce modèle + self.llm.model = model + self.config["llm"]["model"] = model + profiles = self.config.setdefault("llm_profiles", {}) + if profile: + profiles[profile] = model + self._save_config() + logger.info(f"[LLM] Modèle changé → {model} (profil: {profile or 'direct'})") + except Exception as e: + logger.error(f"[LLM] Erreur switch: {e}") + + def _save_config(self): + """Persiste la config en mémoire dans le fichier JSON.""" + try: + with open(self._config_path, "w") as f: + json.dump(self.config, f, indent=2, ensure_ascii=False) + except Exception as e: + logger.error(f"Erreur sauvegarde config ({self._config_path}): {e}") + def _on_status_update(self, msg: Message | str, topic: str): """Mise à jour du statut d'un agent.""" try: