gateway/modules/features/codeeditor/fileContextManager.py
2026-02-23 22:09:27 +01:00

82 lines
2.7 KiB
Python

# 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):
textFiles.append(FileContext(
fileId=fileItem.id,
fileName=fileItem.fileName,
content=None,
mimeType=fileItem.mimeType,
sizeBytes=fileItem.fileSize
))
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)