From 0bd4f8056acf0bdf2b2bf9632126dde7ee759171 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Wed, 10 Dec 2025 01:25:40 +0100 Subject: [PATCH] feat(library-desk): add configuration for HybridRAG and enhance multi-tenancy Configuration: - Add HybridRAG settings (reranker model, search limits) - Change Wiki.js auth from API key to username/password - Configure vector, graph, and web search limits Multi-tenancy: - Add get_neo4j_user_base_label() for entity node labeling - Support title-cased labels following Neo4j conventions - Maintain namespace isolation for entities vs documents --- services/library-desk/src/config.py | 10 ++++++- .../library-desk/src/core/multi_tenancy.py | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/services/library-desk/src/config.py b/services/library-desk/src/config.py index bedd96b..60d5a14 100644 --- a/services/library-desk/src/config.py +++ b/services/library-desk/src/config.py @@ -32,7 +32,8 @@ class Settings(BaseSettings): # Wiki.js Configuration wikijs_url: str = Field(default="http://wiki:3000", description="Wiki.js URL") - wikijs_api_key: str = Field(..., description="Wiki.js API key") + wikijs_username: str = Field(..., description="Wiki.js username") + wikijs_password: str = Field(..., description="Wiki.js password") # SearXNG Configuration searxng_url: str = Field(default="http://searxng:8080", description="SearXNG URL") @@ -41,6 +42,13 @@ class Settings(BaseSettings): ollama_url: str = Field(default="http://ollama:11434", description="Ollama URL") ollama_model: str = Field(default="nomic-embed-text", description="Ollama embedding model") + # HybridRAG Configuration + reranker_model: str = Field(default="mistral-nemo", description="Model for LLM re-ranking") + reranker_enabled: bool = Field(default=True, description="Enable LLM re-ranking") + hybrid_rag_vector_limit: int = Field(default=10, ge=1, le=50, description="Vector search limit") + hybrid_rag_graph_limit: int = Field(default=10, ge=1, le=50, description="Graph search limit") + hybrid_rag_web_limit: int = Field(default=5, ge=1, le=20, description="Web search limit") + # Redis Configuration (for job tracking - separate DB from wiki) redis_host: str = Field(default="redis-shared", description="Redis host") redis_port: int = Field(default=6379, description="Redis port") diff --git a/services/library-desk/src/core/multi_tenancy.py b/services/library-desk/src/core/multi_tenancy.py index 228f5d3..8ca468c 100644 --- a/services/library-desk/src/core/multi_tenancy.py +++ b/services/library-desk/src/core/multi_tenancy.py @@ -99,6 +99,33 @@ def get_wikijs_namespace(user_id: str) -> str: return f"/users/{sanitized}" +def get_neo4j_user_base_label(user_id: str) -> str: + """ + Get Neo4j base label for user's nodes (entities, etc). + + Pattern: User_{Sanitized} + + Uses title case for Neo4j label convention. + + Args: + user_id: User identifier + + Returns: + Neo4j base label for user's nodes + + Examples: + >>> get_neo4j_user_base_label("jpmschweitzer") + 'User_Jpmschweitzer' + >>> get_neo4j_user_base_label("john@example.com") + 'User_John_At_Example_Com' + """ + sanitized = sanitize_user_id(user_id) + # Title case each segment for Neo4j label convention + parts = sanitized.split('_') + titled = '_'.join(part.capitalize() for part in parts if part) + return f"User_{titled}" + + def get_neo4j_user_label(user_id: str) -> str: """ Get Neo4j label for user's documents.