from typing import Dict, Any import logging from datetime import datetime, UTC import uuid from modules.interfaces.serviceAppClass import User from modules.interfaces.serviceChatModel import (UserInputRequest, ChatMessage, ChatWorkflow) from modules.interfaces.serviceChatClass import ChatInterface from modules.workflow.managerChat import ChatManager logger = logging.getLogger(__name__) class WorkflowStoppedException(Exception): """Exception raised when workflow is stopped by user""" pass class WorkflowManager: """Manager for workflow processing and coordination""" def __init__(self, chatInterface: ChatInterface, currentUser: User): self.chatInterface = chatInterface self.chatManager = ChatManager(currentUser) self.currentUser = currentUser def _checkWorkflowStopped(self, workflow: ChatWorkflow) -> None: """Check if workflow has been stopped""" if workflow.status == "stopped": raise WorkflowStoppedException("Workflow was stopped by user") async def workflowProcess(self, userInput: UserInputRequest, workflow: ChatWorkflow) -> None: """Process a workflow with user input""" try: # Initialize chat manager await self.chatManager.initialize(workflow) # Set user language self.chatManager.setUserLanguage(userInput.userLanguage) # Send first message message = await self._sendFirstMessage(userInput, workflow) # Create initial task task = await self.chatManager.createInitialTask(workflow, message) # Process workflow while True: # Check if workflow is stopped self._checkWorkflowStopped(workflow) # Execute task result = await self.chatManager.executeTask(task) # Process result await self.chatManager.parseTaskResult(workflow, result) # Check if workflow should continue if not await self.chatManager.shouldContinue(workflow): break # Identify next task nextTaskResult = await self.chatManager.identifyNextTask(workflow) # Create next task task = await self.chatManager.createNextTask(workflow, nextTaskResult) if not task: break # Send last message await self._sendLastMessage(workflow) except WorkflowStoppedException: logger.info("Workflow stopped by user") except Exception as e: logger.error(f"Workflow processing error: {str(e)}") raise async def _sendFirstMessage(self, userInput: UserInputRequest, workflow: ChatWorkflow) -> ChatMessage: """Send first message to start workflow""" try: # Create initial message message = ChatMessage( id=str(uuid.uuid4()), workflowId=workflow.id, role="user", message=userInput.prompt, status="first", sequenceNr=1, publishedAt=datetime.now(UTC).isoformat() ) # Add documents if any if userInput.listFileId: message.documents = await self.chatManager.processFileIds(userInput.listFileId) # Add message to workflow workflow.messages.append(message) return message except Exception as e: logger.error(f"Error sending first message: {str(e)}") raise async def _sendLastMessage(self, workflow: ChatWorkflow) -> None: """Send last message to complete workflow""" try: # Generate feedback feedback = await self.chatManager.generateWorkflowFeedback(workflow) # Create last message message = ChatMessage( id=str(uuid.uuid4()), workflowId=workflow.id, role="assistant", message=feedback, status="last", sequenceNr=len(workflow.messages) + 1, publishedAt=datetime.now(UTC).isoformat() ) # Add message to workflow workflow.messages.append(message) except Exception as e: logger.error(f"Error sending last message: {str(e)}") raise