aigenrec/luminabackend
0
1from typing import Dict, Any, List2from supabase import create_client, Client3from config.settings import settings4from utils.logger import logger5from uuid import uuid46from datetime import datetime7from services.llm_service import llm_service8from services.embedding_service import embedding_service9from services.qdrant_service import qdrant_service10 11class NotesService:12 def __init__(self):13 self.client: Client = create_client(14 settings.SUPABASE_URL,15 settings.SUPABASE_SERVICE_KEY16 )17 18 async def get_notes(self, project_id: str, user_id: str) -> Dict[str, Any]:19 """Get notes for a project"""20 try:21 response = self.client.table("notes").select("*").eq(22 "project_id", project_id23 ).eq("user_id", user_id).execute()24 25 if response.data:26 note = response.data[0]27 return {28 "id": note["id"],29 "project_id": note["project_id"],30 "user_id": note["user_id"],31 "content": note["content"],32 "created_at": note["created_at"],33 "updated_at": note["updated_at"]34 }35 36 return None37 38 except Exception as e:39 logger.error(f"Error getting notes: {str(e)}")40 raise41 42 async def create_or_update_notes(43 self,44 project_id: str,45 user_id: str,46 content: str47 ) -> Dict[str, Any]:48 """Create or update notes for a project"""49 try:50 # Check if notes exist51 existing = await self.get_notes(project_id, user_id)52 53 if existing:54 # Update existing notes55 response = self.client.table("notes").update({56 "content": content,57 "updated_at": datetime.utcnow().isoformat()58 }).eq("id", existing["id"]).execute()59 60 logger.info(f"Updated notes for project {project_id}")61 else:62 # Create new notes63 note_id = str(uuid4())64 response = self.client.table("notes").insert({65 "id": note_id,66 "project_id": project_id,67 "user_id": user_id,68 "content": content69 }).execute()70 71 logger.info(f"Created notes for project {project_id}")72 73 return response.data[0] if response.data else {}74 75 except Exception as e:76 logger.error(f"Error creating/updating notes: {str(e)}")77 raise78 79 async def generate_notes(80 self,81 project_id: str,82 note_type: str,83 topic: str = None,84 selected_documents: List[str] = None85 ) -> str:86 """Generate notes using AI"""87 try:88 logger.info(f"Generating notes ({note_type}) for project {project_id}, topic: {topic}")89 90 # 1. Retrieve Content91 queries = []92 if topic:93 # If topic is provided, prioritize it94 queries = [topic, f"{note_type} of {topic}"]95 elif "Summary" in note_type:96 queries = ["overview of the document", "main concepts and themes", "conclusion and results"]97 elif "Key Points" in note_type:98 queries = ["important definitions", "key takeaways", "critical points"]99 else:100 queries = [note_type]101 102 collection_name = f"project_{project_id}"103 all_hits = []104 seen_texts = set()105 106 for q in queries:107 embedding = await embedding_service.generate_embedding(q)108 results = await qdrant_service.search(109 collection_name=collection_name,110 query_vector=embedding,111 limit=10, # Fetch robust amount112 filter_conditions={"document_ids": selected_documents} if selected_documents else None113 )114 for hit in results:115 if hit["text"] not in seen_texts:116 all_hits.append(hit)117 seen_texts.add(hit["text"])118 119 if not all_hits:120 return "No content found to generate notes."121 122 # Combine content (limit to reasonable context window)123 context = "\n\n".join([hit["text"] for hit in all_hits[:20]])124 125 # 2. Generate Note126 prompt = f"""Generate a **{note_type}** based on the following content.127 128Content:129{context}130 131Requirements:132- Use clear, professional Markdown formatting.133- Use headers, bullet points, and bold text for readability.134- Be comprehensive but concise.135- Structure it as a study guide or note set.136 137Respond ONLY with the Markdown content."""138 139 messages = [{"role": "user", "content": prompt}]140 response = await llm_service.chat_completion(messages, temperature=0.5, max_tokens=2500)141 142 return response143 144 except Exception as e:145 logger.error(f"Error generating notes: {str(e)}")146 raise147 148notes_service = NotesService()149 