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 ( TaskStatus, UserInputRequest, ContentMetadata, ContentItem, ChatDocument, TaskDocument, ExtractedContent, TaskItem, TaskResult, ChatStat, ChatLog, 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