# Copyright (c) 2025 Patrick Motsch # All rights reserved. """File context manager for CodeEditor feature. Loads text files from the database and provides them as context for AI calls.""" import logging from typing import List, Optional from modules.features.codeeditor.datamodelCodeeditor import FileContext, isTextFile logger = logging.getLogger(__name__) async def loadFileContexts(dbManagement, fileIds: List[str]) -> List[FileContext]: """Load text files from DB and return as FileContext list. Args: dbManagement: interfaceDbManagement instance with user context set fileIds: list of file IDs to load """ contexts = [] for fileId in fileIds: fileItem = dbManagement.getFile(fileId) if not fileItem: logger.warning(f"File {fileId} not found or no access") continue if not isTextFile(fileItem.mimeType, fileItem.fileName): logger.warning(f"File {fileItem.fileName} ({fileItem.mimeType}) is not a text file, skipping") continue fileData = dbManagement.getFileData(fileId) if not fileData: logger.warning(f"No data for file {fileId}") continue try: content = fileData.decode("utf-8") except UnicodeDecodeError: logger.warning(f"File {fileItem.fileName} is not valid UTF-8, skipping") continue contexts.append(FileContext( fileId=fileId, fileName=fileItem.fileName, content=content, mimeType=fileItem.mimeType, sizeBytes=fileItem.fileSize )) logger.info(f"Loaded {len(contexts)} file contexts from {len(fileIds)} requested") return contexts def listTextFiles(dbManagement) -> List[FileContext]: """List all text files accessible to the user (metadata only, no content).""" allFiles = dbManagement.getAllFiles() textFiles = [] if not allFiles: return textFiles for fileItem in allFiles: if isTextFile(fileItem.mimeType, fileItem.fileName): modifiedAt = getattr(fileItem, "_modifiedAt", None) or getattr(fileItem, "creationDate", None) textFiles.append(FileContext( fileId=fileItem.id, fileName=fileItem.fileName, content=None, mimeType=fileItem.mimeType, sizeBytes=fileItem.fileSize, modifiedAt=modifiedAt )) return textFiles def buildFileListContext(dbManagement) -> str: """Build a compact file list string for the agent prompt (no content, just metadata).""" textFiles = listTextFiles(dbManagement) if not textFiles: return "No text files available." lines = [f"- {f.fileName} (id: {f.fileId}, size: {f.sizeBytes}B)" for f in textFiles] return f"Total: {len(lines)} text files\n" + "\n".join(lines)