feat(F): F-PROACTIVE consolidate proactive AI — trigger_dispatcher dispatches agents on context/UI events
Check Cross-Plugin Imports / check (push) Has been cancelled

This commit is contained in:
Agent Zero
2026-08-17 18:40:41 +02:00
parent 131d761936
commit 06b281ba74
7 changed files with 893 additions and 41 deletions
+73
View File
@@ -100,6 +100,13 @@ class TriggerDispatcher:
trigger_type=trigger_type,
payload=payload,
)
# F-PROACTIVE: Also check for matching agent definitions on context/UI events
if is_ui_event or event_name.startswith("context."):
await self._dispatch_matching_agents(
event_name=event_name,
trigger_type=trigger_type,
payload=payload,
)
except Exception:
logger.exception(
"TriggerDispatcher: error dispatching event '%s'", event_name
@@ -164,6 +171,72 @@ class TriggerDispatcher:
trigger_data=payload,
)
async def _dispatch_matching_agents(
self,
event_name: str,
trigger_type: str,
payload: dict[str, Any],
) -> None:
"""F-PROACTIVE: Query DB for active agents matching *event_name* and dispatch.
Checks AgentDefinition.trigger_config for matching context/UI events.
If match found, creates an AgentRun and dispatches via run_agent.
"""
from app.core.db import get_session_factory
from app.plugins.builtins.contracts import get_contract
automation_contract = get_contract("automation")
if automation_contract is None:
return
AgentDefinition = automation_contract.AgentDefinition # noqa: N806
if AgentDefinition is None:
return
factory = get_session_factory()
tenant_id = payload.get("tenant_id")
async with factory() as db:
query = (
select(AgentDefinition)
.where(AgentDefinition.is_active.is_(True))
.where(AgentDefinition.mode == "proactive")
)
if tenant_id is not None:
query = query.where(AgentDefinition.tenant_id == tenant_id)
result = await db.execute(query)
agents = list(result.scalars().all())
if not agents:
return
for agent in agents:
config = agent.trigger_config or {}
configured_event = config.get("event_name", "")
if configured_event != event_name:
continue
logger.info(
"TriggerDispatcher: dispatching agent '%s' (%s) for event '%s'",
agent.name,
agent.id,
event_name,
)
try:
await automation_contract.run_agent(
ctx={},
agent_id=str(agent.id),
trigger_type=trigger_type,
trigger_data=payload,
)
except Exception:
logger.exception(
"TriggerDispatcher: run_agent failed for agent_id=%s",
agent.id,
)
async def _enqueue_automation(
self,
automation_id: str,