import logging import uuid from typing import Dict, Any, List, Optional from modules.datamodels.datamodelUam import User, UserConnection from modules.datamodels.datamodelChat import ChatDocument, ChatMessage, ChatStat, ChatLog from modules.security.tokenManager import TokenManager from modules.shared.progressLogger import ProgressLogger logger = logging.getLogger(__name__) class WorkflowService: """Service class containing methods for document processing, chat operations, and workflow management""" def __init__(self, serviceCenter): self.services = serviceCenter self.user = serviceCenter.user self.workflow = serviceCenter.workflow self.interfaceDbChat = serviceCenter.interfaceDbChat self.interfaceDbComponent = serviceCenter.interfaceDbComponent self.interfaceDbApp = serviceCenter.interfaceDbApp self._progressLogger = None async def summarizeChat(self, messages: List[ChatMessage]) -> str: """ Summarize chat messages from last to first message with status="first" Args: messages: List of chat messages to summarize Returns: str: Summary of the chat in user's language """ try: # Get messages from last to first, stopping at first message with status="first" relevantMessages = [] for msg in reversed(messages): relevantMessages.append(msg) if msg.status == "first": break # Create prompt for AI prompt = f""" You are an AI assistant providing a summary of a chat conversation. Please respond in '{self.user.language}' language. Chat History: {chr(10).join(f"- {msg.message}" for msg in reversed(relevantMessages))} Instructions: 1. Summarize the conversation's key points and outcomes 2. Be concise but informative 3. Use a professional but friendly tone 4. Focus on important decisions and next steps if any LOOP_INSTRUCTION Please provide a comprehensive summary of this conversation.""" # Get summary using AI service through proper main service interface return await self.services.ai.callAiDocuments( prompt=prompt, documents=None, options={ "process_type": "text", "operation_type": "generate", "priority": "speed", "compress_prompt": True, "compress_documents": False, "max_cost": 0.01 } ) except Exception as e: logger.error(f"Error summarizing chat: {str(e)}") return f"Error summarizing chat: {str(e)}" def getChatDocumentsFromDocumentList(self, documentList: List[str]) -> List[ChatDocument]: """Get ChatDocuments from a list of document references using all three formats.""" try: workflow = self.services.currentWorkflow logger.debug(f"getChatDocumentsFromDocumentList: input documentList = {documentList}") logger.debug(f"getChatDocumentsFromDocumentList: currentWorkflow.id = {workflow.id if workflow and hasattr(workflow, 'id') else 'NO_ID'}") # Debug: list available messages with their labels and document names try: if workflow and hasattr(workflow, 'messages') and workflow.messages: msg_lines = [] for message in workflow.messages: label = getattr(message, 'documentsLabel', None) doc_names = [] if getattr(message, 'documents', None): for doc in message.documents: name = getattr(doc, 'fileName', None) or getattr(doc, 'documentName', None) or 'Unnamed' doc_names.append(name) msg_lines.append( f"- id={getattr(message, 'id', None)}, label={label}, docs={doc_names}" ) if msg_lines: logger.debug("getChatDocumentsFromDocumentList: available messages:\n" + "\n".join(msg_lines)) else: logger.debug("getChatDocumentsFromDocumentList: no messages available on current workflow") except Exception as e: logger.debug(f"getChatDocumentsFromDocumentList: unable to enumerate messages for debug: {e}") all_documents = [] for doc_ref in documentList: if doc_ref.startswith("docItem:"): # docItem:: - extract ID and find document parts = doc_ref.split(':') if len(parts) >= 2: doc_id = parts[1] # Find the document by ID for message in workflow.messages: if message.documents: for doc in message.documents: if doc.id == doc_id: doc_name = getattr(doc, 'fileName', 'unknown') all_documents.append(doc) break elif doc_ref.startswith("docList:"): # docList::