feat(F): F-PROACTIVE consolidate proactive AI — trigger_dispatcher dispatches agents on context/UI events
Check Cross-Plugin Imports / check (push) Has been cancelled
Check Cross-Plugin Imports / check (push) Has been cancelled
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user