# app/rag_app.py import os import httpx from openai import OpenAI from .embeddings import EmbeddingManager from .store import VectorStore class RAGApp: def __init__(self): self.embedder = None self.vectorstore = None self.client = None try: # Initialize embedder and FAISS vectorstore self.embedder = EmbeddingManager() self.vectorstore = VectorStore() # Load Hugging Face token api_key = os.getenv("HF_TOKEN") if not api_key: raise ValueError("HF_TOKEN not found in environment variables") # Use Hugging Face OpenAI-compatible router self.client = OpenAI( base_url="https://router.huggingface.co/v1", api_key=api_key, http_client=httpx.Client(timeout=60.0), ) print("✅ RAGApp initialized successfully with Hugging Face router.") except Exception as e: print("❌ RAGApp init error:", e) self.client = None # 🧠 Add notes and store embeddings def add_notes(self, text): chunks = [text[i:i + 1000] for i in range(0, len(text), 800)] embeddings = self.embedder.generate_embeddings(chunks) self.vectorstore.add_documents(chunks, embeddings) return len(chunks) # 💬 Query the system def ask(self, query): try: if not self.client: return "Error: API client not initialized." # 1️⃣ Create embedding for query q_embed = self.embedder.generate_embeddings([query])[0] # 2️⃣ Retrieve similar chunks docs = self.vectorstore.retrieve_similar_docs(q_embed, top_k=3) context = "\n\n".join(docs) if docs else "No context found in notes." # 3️⃣ Prepare the conversation messages = [ { "role": "system", "content": ( "You are a world-class engineering tutor specializing in Electronics, Embedded Systems, and Programming.\n" "Your responses must be clear, technically accurate, and engaging.\n\n" "### Behavior:\n" "1. If the question is conceptual → explain with clarity and real-world relevance.\n" "2. If it involves code → analyze, correct, and explain fixes.\n" "3. If hardware-related → explain theory + circuit/signal behavior.\n" "4. If theory-based from uploaded notes → connect with practical examples.\n\n" "### Output Style:\n" "- Use Markdown.\n" "- Highlight key terms with bold text.\n" "- Use emojis and structured headings for readability.\n" "- Avoid phrases like 'as an AI model'." ), }, { "role": "user", "content": f"Context:\n{context}\n\nQuestion: {query}\nAnswer clearly and in detail below:", }, ] # 4️⃣ Call Hugging Face model via router completion = self.client.chat.completions.create( model="openai/gpt-oss-20b", # ✅ correct model route messages=messages, temperature=0.4, max_tokens=800, ) # 5️⃣ Return the model's response return completion.choices[0].message.content except Exception as e: print("❌ Error in ask():", e) return f"Error: {e}"