commiting missing files

This commit is contained in:
2025-09-15 09:19:08 +02:00
parent cb0a9f216a
commit 8adb4775f8
5 changed files with 173 additions and 14 deletions

32
backend/.flake8 Normal file
View File

@@ -0,0 +1,32 @@
[flake8]
max-line-length = 88
extend-ignore =
# E203: whitespace before ':' (conflicts with black)
E203,
# E501: line too long (handled by black)
E501,
# W503: line break before binary operator (conflicts with black)
W503,
# F401: module imported but unused (handled by isort)
F401
exclude =
.git,
__pycache__,
.venv,
venv,
env,
.tox,
build,
dist,
*.egg-info,
.pytest_cache,
migrations,
alembic/versions
per-file-ignores =
# Allow unused imports in __init__.py files
__init__.py:F401,F403
# Allow long lines in test files for readability
tests/*.py:E501
# Allow specific test patterns
test_*.py:E501,F401,F811
max-complexity = 12

View File

@@ -0,0 +1,22 @@
# Migration container for running Alembic migrations
# Reuses the backend image but runs only database migrations
# Build from the backend image to reuse dependencies
FROM enclava-backend:latest
# Install PostgreSQL client for database health checks
USER root
RUN apt-get update && apt-get install -y \
postgresql-client \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Copy migration script (if not already present)
COPY scripts/migrate.sh /usr/local/bin/migrate.sh
RUN chmod +x /usr/local/bin/migrate.sh
# Switch back to app user
USER enclava
# Set default command to run migrations
CMD ["/usr/local/bin/migrate.sh"]

View File

@@ -405,7 +405,7 @@ class RAGService:
if os.path.exists(document.file_path): if os.path.exists(document.file_path):
os.remove(document.file_path) os.remove(document.file_path)
except Exception as e: except Exception as e:
print(f"Warning: Could not delete file {document.file_path}: {e}") logger.warning(f"Could not delete file {document.file_path}: {e}")
return True return True

View File

@@ -9,7 +9,6 @@ Provides AI chatbot capabilities with:
- UI-configurable settings - UI-configurable settings
""" """
import asyncio
import json import json
from pprint import pprint from pprint import pprint
import uuid import uuid
@@ -295,7 +294,9 @@ class ChatbotModule(BaseModule):
# Force the session to see the committed changes # Force the session to see the committed changes
db.expire_all() db.expire_all()
# Get conversation history for context - INCLUDING the message we just created # Get conversation history for context - includes the current message we just created
# Fetch up to memory_length pairs of messages (user + assistant)
# The +1 ensures we include the current message if we're at the limit
messages = db.query(DBMessage).filter( messages = db.query(DBMessage).filter(
DBMessage.conversation_id == conversation.id DBMessage.conversation_id == conversation.id
).order_by(DBMessage.timestamp.desc()).limit(chatbot_config.memory_length * 2 + 1).all() ).order_by(DBMessage.timestamp.desc()).limit(chatbot_config.memory_length * 2 + 1).all()
@@ -424,16 +425,11 @@ class ChatbotModule(BaseModule):
import traceback import traceback
logger.warning(f"RAG search traceback: {traceback.format_exc()}") logger.warning(f"RAG search traceback: {traceback.format_exc()}")
# Build conversation context # Build conversation context (includes the current message from db_messages)
messages = self._build_conversation_messages(db_messages, config, rag_context, context) messages = self._build_conversation_messages(db_messages, config, rag_context, context)
# CRITICAL: Add the current user message to the messages array # Note: Current user message is already included in db_messages from the query
# This ensures the LLM knows what the user is asking, not just the history logger.info(f"Built conversation context with {len(messages)} messages")
messages.append({
"role": "user",
"content": message
})
logger.info(f"Added current user message to messages array")
# LLM completion # LLM completion
logger.info(f"Attempting LLM completion with model: {config.model}") logger.info(f"Attempting LLM completion with model: {config.model}")
@@ -546,9 +542,7 @@ class ChatbotModule(BaseModule):
else: else:
logger.info(f"Skipped message with role {msg.role}") logger.info(f"Skipped message with role {msg.role}")
logger.info(f"Final messages array has {len(messages)} messages") logger.info(f"Final messages array has {len(messages)} messages") # For debugging, can be removed in production
from pprint import pprint
pprint(messages) # For debugging, can be removed in production
return messages return messages
async def _get_or_create_conversation(self, conversation_id: Optional[str], async def _get_or_create_conversation(self, conversation_id: Optional[str],

111
backend/pyproject.toml Normal file
View File

@@ -0,0 +1,111 @@
[tool.black]
line-length = 88
target-version = ['py311']
include = '\.pyi?$'
extend-exclude = '''
/(
# directories
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
| alembic/versions
)/
'''
[tool.isort]
profile = "black"
line_length = 88
known_first_party = ["app", "tests"]
known_third_party = ["fastapi", "sqlalchemy", "pydantic", "pytest", "httpx"]
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
ensure_newline_before_comments = true
skip = [
".git",
"__pycache__",
".venv",
"venv",
"env",
".tox",
"build",
"dist",
"*.egg-info",
".pytest_cache",
"alembic/versions"
]
[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_unreachable = true
strict_equality = true
[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false
disallow_incomplete_defs = false
disallow_untyped_decorators = false
[[tool.mypy.overrides]]
module = [
"alembic.*",
"qdrant_client.*",
"redis.*",
"uvicorn.*",
"factory.*",
"faker.*",
"locust.*",
"responses.*",
"aioresponses.*"
]
ignore_missing_imports = true
[tool.pytest.ini_options]
minversion = "7.0"
testpaths = ["tests"]
python_files = "test_*.py"
python_classes = "Test*"
python_functions = "test_*"
asyncio_mode = "auto"
addopts = """
-v
--strict-markers
--strict-config
--tb=short
--cov=app
--cov-report=term-missing
--cov-report=html
--cov-report=xml
--cov-fail-under=80
"""
markers = [
"unit: Unit tests",
"integration: Integration tests",
"e2e: End-to-end tests",
"slow: Slow tests",
"db: Tests that require database",
"redis: Tests that require redis",
"qdrant: Tests that require qdrant",
]
[build-system]
requires = ["setuptools>=45", "wheel"]
build-backend = "setuptools.build_meta"