import logging from typing import Dict, Any, Optional, List, Union from datetime import datetime, UTC import json import uuid import time from modules.interfaces.interfaceAppModel import User from modules.interfaces.interfaceChatModel import ( TaskStatus, ChatDocument, TaskItem, TaskAction, TaskResult, ChatStat, ChatLog, ChatMessage, ChatWorkflow ) from modules.workflow.serviceContainer import ServiceContainer from modules.interfaces.interfaceChatObjects import ChatObjects logger = logging.getLogger(__name__) class ChatManager: """Chat manager with improved AI integration and method handling""" def __init__(self, currentUser: User, chatInterface: ChatObjects): self.currentUser = currentUser self.chatInterface = chatInterface self.service: ServiceContainer = None self.workflow: ChatWorkflow = None # ===== Initialization and Setup ===== async def initialize(self, workflow: ChatWorkflow) -> None: """Initialize chat manager with workflow""" self.workflow = workflow self.service = ServiceContainer(self.currentUser, self.workflow) # ===== Task Creation and Management ===== async def createInitialTask(self, workflow: ChatWorkflow, initialMessage: ChatMessage) -> Optional[TaskItem]: """Create the initial task from the first message""" try: # Create task definition prompt prompt = await self._createTaskDefinitionPrompt(initialMessage.message, workflow) # Get AI response response = await self.service.callAiTextAdvanced(prompt) # Parse response try: taskDef = json.loads(response) except json.JSONDecodeError: logger.error(f"Invalid JSON in task definition: {response}") return None # Validate task definition if not isinstance(taskDef, dict): logger.error("Task definition must be a JSON object") return None requiredFields = ["status", "feedback", "actions"] for field in requiredFields: if field not in taskDef: logger.error(f"Missing required field: {field}") return None if not isinstance(taskDef["actions"], list): logger.error("Actions must be a list") return None # Create task using interface taskData = { "workflowId": workflow.id, "userInput": initialMessage.message, "status": taskDef["status"], "feedback": taskDef["feedback"], "actionList": [] } # Add actions for actionDef in taskDef["actions"]: if not isinstance(actionDef, dict): continue requiredFields = ["method", "action", "parameters"] if not all(field in actionDef for field in requiredFields): continue action = TaskAction( id=str(uuid.uuid4()), execMethod=actionDef["method"], execAction=actionDef["action"], execParameters=actionDef["parameters"], execResultLabel=actionDef.get("resultLabel") ) taskData["actionList"].append(action) # Create task using interface task = self.chatInterface.createTask(taskData) return task except Exception as e: logger.error(f"Error creating initial task: {str(e)}") return None async def createNextTask(self, workflow: ChatWorkflow, previousResult: TaskResult) -> Optional[TaskItem]: """Create next task based on previous result""" try: # Check if previous result was successful if not previousResult.success: logger.error(f"Previous task failed: {previousResult.error}") return None # Create task definition prompt prompt = await self._createTaskDefinitionPrompt(previousResult.feedback, workflow) # Get AI response response = await self.service.callAiTextAdvanced(prompt) # Parse response try: taskDef = json.loads(response) except json.JSONDecodeError: logger.error(f"Invalid JSON in task definition: {response}") return None # Validate task definition if not isinstance(taskDef, dict): logger.error("Task definition must be a JSON object") return None requiredFields = ["status", "feedback", "actions"] for field in requiredFields: if field not in taskDef: logger.error(f"Missing required field: {field}") return None if not isinstance(taskDef["actions"], list): logger.error("Actions must be a list") return None # Create task using interface taskData = { "workflowId": workflow.id, "userInput": previousResult.feedback, "status": taskDef["status"], "feedback": taskDef["feedback"], "actionList": [] } # Add actions for actionDef in taskDef["actions"]: if not isinstance(actionDef, dict): continue requiredFields = ["method", "action", "parameters"] if not all(field in actionDef for field in requiredFields): continue action = TaskAction( id=str(uuid.uuid4()), execMethod=actionDef["method"], execAction=actionDef["action"], execParameters=actionDef["parameters"], execResultLabel=actionDef.get("resultLabel") ) taskData["actionList"].append(action) # Create task using interface task = self.chatInterface.createTask(taskData) return task except Exception as e: logger.error(f"Error creating next task: {str(e)}") return None async def executeTask(self, task: TaskItem) -> TaskItem: """Execute a task's actions""" try: # Execute each action for action in task.actionList: # Create action prompt prompt = f"""Execute the following action: Action: {action.execMethod}.{action.execAction} Parameters: {json.dumps(action.execParameters)} Please provide a JSON response with: 1. result: The result of the action 2. resultLabel: A label for the result (format: documentList__