from enum import Enum from typing import List, Dict, Any, Optional from dataclasses import dataclass, field class ExecutionMode(Enum): SEQUENTIAL = "sequential" PARALLEL = "parallel" CONDITIONAL = "conditional" @dataclass class WorkflowStep: tool_name: str arguments: Dict[str, Any] step_id: str condition: Optional[str] = None on_success: Optional[List[str]] = None on_failure: Optional[List[str]] = None retry_count: int = 0 timeout_seconds: int = 300 def to_dict(self) -> Dict[str, Any]: return { 'tool_name': self.tool_name, 'arguments': self.arguments, 'step_id': self.step_id, 'condition': self.condition, 'on_success': self.on_success, 'on_failure': self.on_failure, 'retry_count': self.retry_count, 'timeout_seconds': self.timeout_seconds } @staticmethod def from_dict(data: Dict[str, Any]) -> 'WorkflowStep': return WorkflowStep( tool_name=data['tool_name'], arguments=data['arguments'], step_id=data['step_id'], condition=data.get('condition'), on_success=data.get('on_success'), on_failure=data.get('on_failure'), retry_count=data.get('retry_count', 0), timeout_seconds=data.get('timeout_seconds', 300) ) @dataclass class Workflow: name: str description: str steps: List[WorkflowStep] execution_mode: ExecutionMode = ExecutionMode.SEQUENTIAL variables: Dict[str, Any] = field(default_factory=dict) tags: List[str] = field(default_factory=list) def to_dict(self) -> Dict[str, Any]: return { 'name': self.name, 'description': self.description, 'steps': [step.to_dict() for step in self.steps], 'execution_mode': self.execution_mode.value, 'variables': self.variables, 'tags': self.tags } @staticmethod def from_dict(data: Dict[str, Any]) -> 'Workflow': return Workflow( name=data['name'], description=data['description'], steps=[WorkflowStep.from_dict(step) for step in data['steps']], execution_mode=ExecutionMode(data.get('execution_mode', 'sequential')), variables=data.get('variables', {}), tags=data.get('tags', []) ) def add_step(self, step: WorkflowStep): self.steps.append(step) def get_step(self, step_id: str) -> Optional[WorkflowStep]: for step in self.steps: if step.step_id == step_id: return step return None def get_initial_steps(self) -> List[WorkflowStep]: if self.execution_mode == ExecutionMode.SEQUENTIAL: return [self.steps[0]] if self.steps else [] elif self.execution_mode == ExecutionMode.PARALLEL: return self.steps else: return [step for step in self.steps if not step.condition]