224 lines
9.3 KiB
Python
224 lines
9.3 KiB
Python
import logging
|
|
import importlib
|
|
import pkgutil
|
|
import inspect
|
|
from typing import Dict, Any, List, Optional
|
|
from modules.interfaces.serviceAppClass import User
|
|
from modules.interfaces.serviceChatModel import (
|
|
TaskStatus, ChatDocument, TaskItem, TaskAction, TaskResult,
|
|
ChatStat, ChatLog, ChatMessage, ChatWorkflow, UserConnection
|
|
)
|
|
from modules.interfaces.interfaceAi import interfaceAi
|
|
from modules.interfaces.serviceChatClass import getInterface as getChatInterface
|
|
from modules.interfaces.serviceManagementClass import getInterface as getFileInterface
|
|
from modules.workflow.managerDocument import DocumentManager
|
|
from modules.methods.methodBase import MethodBase
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class ServiceContainer:
|
|
"""Service container that provides access to all services and their functions"""
|
|
|
|
def __init__(self, currentUser: User, workflow: ChatWorkflow):
|
|
# Core services
|
|
self.user = currentUser
|
|
self.workflow = workflow
|
|
self.tasks = workflow.tasks
|
|
self.statusEnums = TaskStatus
|
|
|
|
# Initialize managers
|
|
self.interfaceChat = getChatInterface(currentUser)
|
|
self.interfaceFiles = getFileInterface(currentUser)
|
|
self.interfaceAi = interfaceAi()
|
|
self.documentManager = DocumentManager(self)
|
|
|
|
# Initialize methods catalog
|
|
self.methods = None
|
|
# Discover additional methods
|
|
self._discoverMethods()
|
|
|
|
def _discoverMethods(self):
|
|
"""Dynamically discover all method classes in modules.methods package"""
|
|
try:
|
|
# Import the methods package
|
|
methodsPackage = importlib.import_module('modules.methods')
|
|
|
|
# Discover all modules in the package
|
|
for _, name, isPkg in pkgutil.iter_modules(methodsPackage.__path__):
|
|
if not isPkg and name.startswith('method'):
|
|
try:
|
|
# Import the module
|
|
module = importlib.import_module(f'modules.methods.{name}')
|
|
|
|
# Find all classes in the module that inherit from MethodBase
|
|
for itemName, item in inspect.getmembers(module):
|
|
if (inspect.isclass(item) and
|
|
issubclass(item, MethodBase) and
|
|
item != MethodBase):
|
|
# Instantiate the method and add to service
|
|
methodInstance = item()
|
|
self.methods[methodInstance.name] = methodInstance
|
|
logger.info(f"Discovered method: {methodInstance.name}")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error loading method module {name}: {str(e)}")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error discovering methods: {str(e)}")
|
|
|
|
# ===== Functions =====
|
|
|
|
def extractContent(self, prompt: str, document: ChatDocument) -> str:
|
|
"""Extract content from document using prompt"""
|
|
return self.documentManager.extractContent(prompt, document)
|
|
|
|
def getMethodsCatalog(self) -> Dict[str, Any]:
|
|
"""Get catalog of available methods"""
|
|
return self.methods
|
|
|
|
def getMethodsList(self) -> List[str]:
|
|
"""Get list of available methods"""
|
|
return list(self.methods.keys())
|
|
|
|
def getDocumentReferenceList(self) -> Dict[str, List[Dict[str, str]]]:
|
|
"""Get list of document references sorted by datetime"""
|
|
return {
|
|
"chat": self._getChatDocumentReferences(),
|
|
"history": self._getHistoryDocumentReferences()
|
|
}
|
|
|
|
def getDocumentReferenceFromChatDocument(self, document: ChatDocument) -> str:
|
|
"""Get document reference from ChatDocument"""
|
|
return f"document_{document.id}_{document.filename}"
|
|
|
|
def getDocumentReferenceFromTaskResult(self, result: TaskResult) -> str:
|
|
"""Get document reference from TaskResult"""
|
|
return f"documentList_{result.id}_{result.documentsLabel}"
|
|
|
|
def getChatDocumentsFromDocumentReference(self, documentReference: str) -> List[ChatDocument]:
|
|
"""Get ChatDocuments from document reference"""
|
|
return self.documentManager.getDocumentsByReference(documentReference)
|
|
|
|
def getConnectionReferenceList(self) -> List[Dict[str, str]]:
|
|
"""Get list of connection references sorted by authority"""
|
|
return self._getConnectionReferences()
|
|
|
|
def getConnectionReferenceFromUserConnection(self, connection: UserConnection) -> str:
|
|
"""Get connection reference from UserConnection"""
|
|
return f"connection_{connection.id}_{connection.authority}"
|
|
|
|
def getUserConnectionFromConnectionReference(self, reference: str) -> UserConnection:
|
|
"""Get UserConnection from connection reference"""
|
|
return self._getUserConnectionByReference(reference)
|
|
|
|
def getMessageSummary(self, message: ChatMessage) -> Dict[str, List[Dict[str, Any]]]:
|
|
"""Get message summary"""
|
|
return {
|
|
"chat": self._getChatMessageSummaries(),
|
|
"history": self._getHistoryMessageSummaries()
|
|
}
|
|
|
|
def getFileData(self, fileId: str) -> bytes:
|
|
"""Get file data by ID"""
|
|
return self.interfaceFiles.getFileData(fileId)
|
|
|
|
def callAiBasic(self, prompt: str, context: str = None, complexityFlag: bool = False) -> str:
|
|
"""Call basic AI service"""
|
|
return self.interfaceAi.callAiBasic(prompt, context, complexityFlag)
|
|
|
|
def callAiImage(self, imageData: bytes, mimeType: str, prompt: str) -> str:
|
|
"""Call AI image service"""
|
|
return self.interfaceAi.callAiImage(imageData, mimeType, prompt)
|
|
|
|
def createFile(self, fileName: str, mimeType: str, content: bytes, base64encoded: bool = False) -> Dict[str, Any]:
|
|
"""Create new file"""
|
|
return self.interfaceFiles.createFile(fileName, mimeType, content, base64encoded)
|
|
|
|
def getFileInfo(self, fileId: str) -> Dict[str, Any]:
|
|
"""Get file information"""
|
|
return self.interfaceFiles.getFileInfo(fileId)
|
|
|
|
# ===== Private Methods =====
|
|
|
|
def _executeMethodAction(self, parameters: Dict[str, Any]) -> Any:
|
|
"""Execute method action with parameters"""
|
|
method = parameters.get('method')
|
|
action = parameters.get('action')
|
|
if method in self.methods and action in self.methods[method]:
|
|
return self.methods[method][action](**parameters.get('parameters', {}))
|
|
raise ValueError(f"Unknown method or action: {method}.{action}")
|
|
|
|
def _executeForEach(self, items: List[Any], action: callable) -> List[Any]:
|
|
"""Execute forEach operation"""
|
|
results = []
|
|
for item in items:
|
|
try:
|
|
result = action(item)
|
|
results.append(result)
|
|
except Exception as e:
|
|
logger.error(f"Error executing forEach action: {str(e)}")
|
|
results.append(None)
|
|
return results
|
|
|
|
def _executeAiCall(self, prompt: str, documents: List[Dict[str, Any]]) -> List[Any]:
|
|
"""Execute AI call with documents"""
|
|
try:
|
|
# Process each document
|
|
results = []
|
|
for doc in documents:
|
|
content = self.extractContent(prompt, doc)
|
|
results.append(content)
|
|
return results
|
|
except Exception as e:
|
|
logger.error(f"Error executing AI call: {str(e)}")
|
|
return []
|
|
|
|
def _executeSharePointQuery(self, connection: str, site_query: str, file_query: str, content_query: str) -> List[Dict[str, str]]:
|
|
"""Execute SharePoint query"""
|
|
# TODO: Implement SharePoint query
|
|
return []
|
|
|
|
def _executeSharePointDownload(self, connection: str, filepath: str) -> str:
|
|
"""Execute SharePoint download"""
|
|
# TODO: Implement SharePoint download
|
|
return ""
|
|
|
|
def _getChatDocumentReferences(self) -> List[Dict[str, str]]:
|
|
"""Get chat document references"""
|
|
# TODO: Implement chat document references
|
|
return []
|
|
|
|
def _getHistoryDocumentReferences(self) -> List[Dict[str, str]]:
|
|
"""Get history document references"""
|
|
# TODO: Implement history document references
|
|
return []
|
|
|
|
def _getConnectionReferences(self) -> List[Dict[str, str]]:
|
|
"""Get connection references"""
|
|
# TODO: Implement connection references
|
|
return []
|
|
|
|
def _getUserConnectionByReference(self, reference: str) -> UserConnection:
|
|
"""Get user connection by reference"""
|
|
# TODO: Implement user connection lookup
|
|
pass
|
|
|
|
def _getChatMessageSummaries(self) -> List[Dict[str, Any]]:
|
|
"""Get chat message summaries"""
|
|
# TODO: Implement chat message summaries
|
|
return []
|
|
|
|
def _getHistoryMessageSummaries(self) -> List[Dict[str, Any]]:
|
|
"""Get history message summaries"""
|
|
# TODO: Implement history message summaries
|
|
return []
|
|
|
|
# Create singleton instance
|
|
serviceObject = None
|
|
|
|
def initializeServiceContainer(currentUser: User, workflow: ChatWorkflow) -> ServiceContainer:
|
|
"""Initialize the service container singleton"""
|
|
global serviceObject
|
|
if serviceObject is None:
|
|
serviceObject = ServiceContainer(currentUser, workflow)
|
|
return serviceObject
|