diff --git a/aria-brain/background.py b/aria-brain/background.py index a7d45e8..395c632 100644 --- a/aria-brain/background.py +++ b/aria-brain/background.py @@ -149,14 +149,23 @@ async def _fire(trigger: dict, agent_factory) -> None: ) try: - agent = agent_factory() - reply, _, _, _, _ = agent.chat(prompt, source="trigger") - events = agent.pop_events() + # WICHTIG: agent.chat() ist ein SYNCHRONER, blockierender Aufruf (Proxy- + # HTTP mit bis zu 24h Read-Timeout). NIEMALS direkt im async-Loop — + # sonst friert ein einziger getriggerter Turn den GESAMTEN Brain ein + # (kein /health, kein weiterer Request). Wie der /chat-Pfad in den + # Executor auslagern, damit der Event-Loop frei bleibt. + loop = asyncio.get_running_loop() + + def _run_turn(): + a = agent_factory() + rep, *_rest = a.chat(prompt, source="trigger") + return rep, a.pop_events() + + reply, events = await loop.run_in_executor(None, _run_turn) logger.info("[trigger] %s gefeuert → ARIA-Reply: %s", name, reply[:80]) triggers_mod.append_log(name, {"event": "reply", "text": reply[:500]}) # Reply an die Bridge pushen, damit App + Diagnostic + TTS sie kriegen. # Ohne diesen Push wuerde die Antwort nur im Brain-Log landen. - loop = asyncio.get_event_loop() await loop.run_in_executor(None, _push_to_bridge, reply, name, ttype, events) except Exception as e: logger.exception("Trigger %s feuern fehlgeschlagen: %s", name, e)