mirror of https://github.com/kortix-ai/suna.git
213 lines
7.5 KiB
Python
213 lines
7.5 KiB
Python
import uuid
|
|
from typing import List, Optional, Dict, Any
|
|
from datetime import datetime, timezone
|
|
|
|
from ..domain.entities import Trigger, TriggerEvent, TriggerResult
|
|
from ..domain.value_objects import TriggerIdentity, TriggerConfig, TriggerMetadata, TriggerType
|
|
from ..domain.services import TriggerDomainService, ProviderRegistryService
|
|
from ..repositories.interfaces import TriggerRepository, TriggerEventLogRepository
|
|
|
|
|
|
class TriggerService:
|
|
def __init__(
|
|
self,
|
|
trigger_repository: TriggerRepository,
|
|
event_log_repository: TriggerEventLogRepository,
|
|
domain_service: TriggerDomainService,
|
|
provider_registry: ProviderRegistryService
|
|
):
|
|
self._trigger_repo = trigger_repository
|
|
self._event_log_repo = event_log_repository
|
|
self._domain_service = domain_service
|
|
self._provider_registry = provider_registry
|
|
|
|
async def create_trigger(
|
|
self,
|
|
agent_id: str,
|
|
provider_id: str,
|
|
name: str,
|
|
config: Dict[str, Any],
|
|
description: Optional[str] = None
|
|
) -> Trigger:
|
|
validated_config = await self._domain_service.validate_trigger_configuration(
|
|
provider_id, config
|
|
)
|
|
|
|
provider = await self._provider_registry.get_provider(provider_id)
|
|
if not provider:
|
|
raise ValueError(f"Provider not found: {provider_id}")
|
|
|
|
trigger_config = TriggerConfig(
|
|
name=name,
|
|
description=description,
|
|
config={**validated_config, "provider_id": provider_id}
|
|
)
|
|
|
|
identity = TriggerIdentity(
|
|
trigger_id=str(uuid.uuid4()),
|
|
agent_id=agent_id
|
|
)
|
|
|
|
trigger = Trigger(
|
|
identity=identity,
|
|
provider_id=provider_id,
|
|
trigger_type=provider.trigger_type,
|
|
config=trigger_config
|
|
)
|
|
|
|
setup_success = await self._domain_service.setup_trigger(trigger)
|
|
if not setup_success:
|
|
raise ValueError(f"Failed to setup trigger: {name}")
|
|
|
|
await self._trigger_repo.save(trigger)
|
|
|
|
return trigger
|
|
|
|
async def get_trigger(self, trigger_id: str) -> Optional[Trigger]:
|
|
return await self._trigger_repo.find_by_id(trigger_id)
|
|
|
|
async def get_agent_triggers(self, agent_id: str) -> List[Trigger]:
|
|
return await self._trigger_repo.find_by_agent_id(agent_id)
|
|
|
|
async def get_active_triggers(self) -> List[Trigger]:
|
|
return await self._trigger_repo.find_active_triggers()
|
|
|
|
async def update_trigger(
|
|
self,
|
|
trigger_id: str,
|
|
config: Optional[Dict[str, Any]] = None,
|
|
name: Optional[str] = None,
|
|
description: Optional[str] = None,
|
|
is_active: Optional[bool] = None
|
|
) -> Trigger:
|
|
trigger = await self._trigger_repo.find_by_id(trigger_id)
|
|
if not trigger:
|
|
raise ValueError(f"Trigger not found: {trigger_id}")
|
|
|
|
if config is not None:
|
|
validated_config = await self._domain_service.validate_trigger_configuration(
|
|
trigger.provider_id, config
|
|
)
|
|
config = {**validated_config, "provider_id": trigger.provider_id}
|
|
|
|
updated_config = TriggerConfig(
|
|
name=name if name is not None else trigger.config.name,
|
|
description=description if description is not None else trigger.config.description,
|
|
config=config if config is not None else trigger.config.config,
|
|
is_active=is_active if is_active is not None else trigger.config.is_active
|
|
)
|
|
|
|
trigger.update_config(updated_config)
|
|
|
|
await self._domain_service.teardown_trigger(trigger)
|
|
if trigger.is_active:
|
|
setup_success = await self._domain_service.setup_trigger(trigger)
|
|
if not setup_success:
|
|
raise ValueError(f"Failed to update trigger setup: {trigger_id}")
|
|
|
|
await self._trigger_repo.update(trigger)
|
|
|
|
return trigger
|
|
|
|
async def delete_trigger(self, trigger_id: str) -> bool:
|
|
trigger = await self._trigger_repo.find_by_id(trigger_id)
|
|
if not trigger:
|
|
return False
|
|
|
|
await self._domain_service.teardown_trigger(trigger)
|
|
return await self._trigger_repo.delete(trigger_id)
|
|
|
|
async def activate_trigger(self, trigger_id: str) -> Trigger:
|
|
trigger = await self._trigger_repo.find_by_id(trigger_id)
|
|
if not trigger:
|
|
raise ValueError(f"Trigger not found: {trigger_id}")
|
|
|
|
if not trigger.is_active:
|
|
trigger.activate()
|
|
setup_success = await self._domain_service.setup_trigger(trigger)
|
|
if not setup_success:
|
|
raise ValueError(f"Failed to activate trigger: {trigger_id}")
|
|
|
|
await self._trigger_repo.update(trigger)
|
|
|
|
return trigger
|
|
|
|
async def deactivate_trigger(self, trigger_id: str) -> Trigger:
|
|
trigger = await self._trigger_repo.find_by_id(trigger_id)
|
|
if not trigger:
|
|
raise ValueError(f"Trigger not found: {trigger_id}")
|
|
|
|
if trigger.is_active:
|
|
await self._domain_service.teardown_trigger(trigger)
|
|
trigger.deactivate()
|
|
await self._trigger_repo.update(trigger)
|
|
|
|
return trigger
|
|
|
|
async def health_check_trigger(self, trigger_id: str) -> bool:
|
|
trigger = await self._trigger_repo.find_by_id(trigger_id)
|
|
if not trigger:
|
|
return False
|
|
|
|
return await self._domain_service.health_check_trigger(trigger)
|
|
|
|
async def health_check_agent_triggers(self, agent_id: str) -> Dict[str, bool]:
|
|
triggers = await self._trigger_repo.find_by_agent_id(agent_id)
|
|
results = {}
|
|
|
|
for trigger in triggers:
|
|
results[trigger.trigger_id] = await self._domain_service.health_check_trigger(trigger)
|
|
|
|
return results
|
|
|
|
async def process_trigger_event(
|
|
self,
|
|
trigger_id: str,
|
|
raw_data: Dict[str, Any]
|
|
) -> TriggerResult:
|
|
trigger = await self._trigger_repo.find_by_id(trigger_id)
|
|
if not trigger:
|
|
return TriggerResult(
|
|
success=False,
|
|
error_message=f"Trigger not found: {trigger_id}"
|
|
)
|
|
|
|
event = TriggerEvent(
|
|
trigger_id=trigger_id,
|
|
agent_id=trigger.agent_id,
|
|
trigger_type=trigger.trigger_type,
|
|
raw_data=raw_data
|
|
)
|
|
|
|
result = await self._domain_service.process_trigger_event(trigger, event)
|
|
return result
|
|
|
|
async def get_trigger_logs(
|
|
self,
|
|
trigger_id: str,
|
|
limit: int = 100,
|
|
offset: int = 0
|
|
) -> List[Dict[str, Any]]:
|
|
return await self._event_log_repo.find_logs_by_trigger_id(trigger_id, limit, offset)
|
|
|
|
async def get_agent_trigger_logs(
|
|
self,
|
|
agent_id: str,
|
|
limit: int = 100,
|
|
offset: int = 0
|
|
) -> List[Dict[str, Any]]:
|
|
return await self._event_log_repo.find_logs_by_agent_id(agent_id, limit, offset)
|
|
|
|
async def get_trigger_stats(
|
|
self,
|
|
trigger_id: str,
|
|
hours: int = 24
|
|
) -> Dict[str, Any]:
|
|
return await self._event_log_repo.get_execution_stats(trigger_id, hours)
|
|
|
|
async def get_failed_events(
|
|
self,
|
|
since: Optional[datetime] = None,
|
|
limit: int = 100
|
|
) -> List[Dict[str, Any]]:
|
|
return await self._event_log_repo.find_failed_events(since, limit) |