from playwright.async_api import Page from skyvern.exceptions import StepTerminationError from skyvern.forge import app from skyvern.forge.async_operations import AsyncOperation from skyvern.forge.sdk.models import Organization, Step, StepStatus from skyvern.forge.sdk.schemas.tasks import Task, TaskStatus class AgentFunction: async def validate_step_execution( self, task: Task, step: Step, ) -> None: """ Checks if the step can be executed. :return: A tuple of whether the step can be executed and a list of reasons why it can't be executed. """ reasons = [] # can't execute if task status is not running has_valid_task_status = task.status == TaskStatus.running if not has_valid_task_status: reasons.append(f"invalid_task_status:{task.status}") # can't execute if the step is already running or completed has_valid_step_status = step.status in [StepStatus.created, StepStatus.failed] if not has_valid_step_status: reasons.append(f"invalid_step_status:{step.status}") # can't execute if the task has another step that is running steps = await app.DATABASE.get_task_steps(task_id=task.task_id, organization_id=task.organization_id) has_no_running_steps = not any(step.status == StepStatus.running for step in steps) if not has_no_running_steps: reasons.append(f"another_step_is_running_for_task:{task.task_id}") can_execute = has_valid_task_status and has_valid_step_status and has_no_running_steps if not can_execute: raise StepTerminationError(step_id=step.step_id, reason="Cannot execute step. Reasons: {reasons}") def generate_async_operations( self, organization: Organization, task: Task, page: Page, ) -> list[AsyncOperation]: return []