# Copyright (c) 2025 Patrick Motsch # All rights reserved. # executionState.py # Contains all execution state management logic import logging from typing import List, Optional from modules.datamodels.datamodelChat import TaskStep, ActionResult logger = logging.getLogger(__name__) class TaskExecutionState: """Manages execution state for a task with retry logic""" def __init__(self, taskStep: TaskStep): self.task_step = taskStep self.successful_actions: List[ActionResult] = [] self.failed_actions: List[ActionResult] = [] self.current_action_index = 0 self.retry_count = 0 self.max_retries = 3 self.current_step = 0 self.max_steps = 0 def addSuccessfulAction(self, action_result: ActionResult): """Add a successful action to the state""" self.successful_actions.append(action_result) self.current_action_index += 1 def addFailedAction(self, action_result: ActionResult): """Add a failed action to the state for analysis""" self.failed_actions.append(action_result) self.current_action_index += 1 def canRetry(self) -> bool: """Check if task can be retried""" return self.retry_count < self.max_retries def incrementRetryCount(self): """Increment retry count""" self.retry_count += 1 def getFailurePatterns(self) -> list: """Analyze failure patterns from failed actions""" patterns = [] for action in self.failed_actions: error = action.error.lower() if action.error else '' if "timeout" in error: patterns.append("timeout_issues") elif "document_not_found" in error or "file not found" in error: patterns.append("document_reference_issues") elif "empty_result" in error or "no content" in error: patterns.append("content_extraction_issues") elif "invalid_format" in error or "wrong format" in error: patterns.append("format_issues") elif "permission" in error or "access denied" in error: patterns.append("permission_issues") return list(set(patterns)) def shouldContinue(observation=None, review=None, current_step: int = 0, max_steps: int = 1) -> bool: """Helper to decide if the iterative loop should continue. Returns False if max steps reached or review indicates 'stop'/'success'. """ try: if current_step >= max_steps: logger.info(f"Stopping workflow: reached max_steps limit ({current_step} >= {max_steps})") return False if review: if hasattr(review, 'status'): if review.status in ('stop', 'success'): return False elif isinstance(review, dict): decision = review.get('decision') or review.get('status') if decision in ('stop', 'success'): return False return True except Exception as e: logger.warning(f"Error in shouldContinue: {e}") return False