Spaces:
Sleeping
Sleeping
File size: 4,134 Bytes
84fd9b2 d774b6e 9a0258d d774b6e 201e468 d774b6e 020aa2d 2198301 d774b6e 020aa2d d774b6e 2198301 d774b6e 2198301 020aa2d 9a0258d 0182ed6 9a0258d 2198301 f76308d 2198301 d774b6e 388c8ae d774b6e 388c8ae d774b6e 020aa2d d774b6e 020aa2d 2198301 d774b6e 020aa2d d774b6e 9a0258d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | import os
from functools import lru_cache
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_community.vectorstores import FAISS
from dotenv import load_dotenv
load_dotenv()
# Use absolute path relative to this file's location
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
DB_FAISS_PATH = os.path.join(SCRIPT_DIR, "vectorstore", "db_faiss")
# Global cache for embeddings and database
_embeddings = None
_db = None
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
@lru_cache(maxsize=1)
def get_embeddings():
"""Load embeddings model once and cache it"""
try:
from langchain_huggingface import HuggingFaceEmbeddings
return HuggingFaceEmbeddings(
model_name='sentence-transformers/all-MiniLM-L6-v2',
model_kwargs={'device': 'cpu'}
)
except Exception as e:
raise ImportError(f"Failed to load HuggingFaceEmbeddings: {e}")
def get_vector_db():
"""Load vector database once and cache it"""
global _db
if _db is None:
try:
embeddings = get_embeddings()
_db = FAISS.load_local(DB_FAISS_PATH, embeddings, allow_dangerous_deserialization=True)
except Exception as e:
raise RuntimeError(f"Error loading FAISS index: {e}\n(Did you run ingest.py?)")
return _db
def get_answer(query, status_placeholder=None):
"""Get answer for query. status_placeholder is an optional st.empty() for status updates."""
def update_status(text):
if status_placeholder:
status_placeholder.markdown(text)
# Load cached embeddings and database
try:
update_status("π *Searching knowledge base...*")
db = get_vector_db()
except Exception as e:
return f"β Database error: {str(e)}"
# Setup LLM
try:
update_status("π€ *Connecting to AI...*")
llm = ChatOpenAI(
model="google/gemini-2.5-flash",
api_key=os.getenv("OPENROUTER_API_KEY"),
base_url="https://openrouter.ai/api/v1",
temperature=0.7,
timeout=30,
max_tokens=2000,
)
except Exception as e:
return f"β LLM init error: {str(e)}"
# Define Prompt
template = """You are Sagar's personal assistant! π You're a friendly, warm, and always helpful AI assistant.
Your personality traits:
- You're enthusiastic and positive! π
- You use emojis naturally in your responses to make conversations more engaging π
- You're helpful and always try your best to assist
- You speak in a warm, conversational tone like a good friend would
- You're supportive and encouraging πͺ
Answer questions based on the following context about Sagar:
{context}
Guidelines:
1. Answer based on the provided context about Sagar.
2. Be friendly, warm, and use emojis naturally throughout your response! π
3. Keep your responses conversational and engaging.
4. If the answer is not in the context, say something like: "Hmm, I don't have that info yet! π€ But you can always reach out to Sagar directly at sagar_rathi@zohomail.in π§"
5. Do not make up facts - only share what's in the context.
6. Make the person feel welcome and helped! β¨
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
# Create LCEL Chain
update_status("π *Finding relevant info...*")
retriever = db.as_retriever()
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
update_status("οΏ½ *Thinking...*")
try:
response = rag_chain.invoke(query)
# Clear the status when done
if status_placeholder:
status_placeholder.empty()
return response
except Exception as e:
return f"β API call error: {str(e)}"
|