# ========================================= # 1️⃣ Install imports # ========================================= import os import pickle import faiss import numpy as np import gradio as gr from sentence_transformers import SentenceTransformer from groq import Groq # ========================================= # 2️⃣ Load Groq API from HF Secrets # ========================================= client = Groq(api_key=os.environ.get("GROQ_API_KEY")) GROQ_MODEL = "llama-3.3-70b-versatile" # ========================================= # 3️⃣ Load FAISS + Chunks # ========================================= index = faiss.read_index("faiss_index.bin") with open("chunks.pkl", "rb") as f: all_chunks = pickle.load(f) # Load embedding model (only for query embedding) embedding_model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2") # ========================================= # 4️⃣ Groq Query Function # ========================================= def groq_query(prompt): completion = client.chat.completions.create( messages=[ {"role": "system", "content": "You are a strict university assistant. Answer ONLY using provided context."}, {"role": "user", "content": prompt} ], model=GROQ_MODEL, temperature=0, ) return completion.choices[0].message.content # ========================================= # 5️⃣ RAG Function # ========================================= def rag_answer(query, k=3): if not query.strip(): return "Please enter a valid question." query_embedding = embedding_model.encode([query]) query_embedding = query_embedding / np.linalg.norm(query_embedding, axis=1, keepdims=True) query_embedding = query_embedding.astype("float32") distances, indices = index.search(query_embedding, k) retrieved_texts = [all_chunks[i] for i in indices[0]] context = "\n\n".join(retrieved_texts) prompt = f""" Use ONLY information below to answer. If no answer is found, respond: "The information is not available in the provided documents. Please check the official University of Baltistan website for more information: https://uobs.edu.pk/" Context: {context} Question: {query} """ return groq_query(prompt) # ========================================= # Gradio UI # ========================================= # Sample mock questions mock_questions = [ "What is the focus of the Botany Department?", "Who is the Head of Chemistry Department?", "What programs does the Computer Science Department offer?", "What environmental challenges does the Earth & Environmental Science Dept address?", "Who is the Head of Mathematics Department?", "What is the goal of Educational Development Department?", "Who leads the Languages and Cultural Studies Department?" ] # Function to set mock question into input def set_question(q_text): return q_text # Function to respond via RAG def respond(message, history): if not history: history = [] user_entry = {"role": "user", "content": message} answer = rag_answer(message) # your RAG function assistant_entry = {"role": "assistant", "content": answer} history.append(user_entry) history.append(assistant_entry) return history, "" # update chat and clear input with gr.Blocks() as demo: # App title gr.Markdown( "

🎓 UoBs HoDs Insight AI Assistant

" ) # Description gr.Markdown( """
Welcome to the UoBs HoDs Insight AI Assistant – your trusted AI-powered guide to the University of Baltistan. This intelligent chatbot delivers accurate and verified information directly from the official messages of all department heads. Ask about academic programs, faculty, research initiatives, or departmental objectives, and receive instant, reliable answers strictly sourced from official university communications. For additional details or to explore further, all information is anchored to the official University of Baltistan website.
""" ) # Main layout: Left sidebar + Right chatbot with gr.Row(): # Left column: mock questions with gr.Column(scale=1): gr.Markdown("### 💡 Sample Questions") # create buttons for each question mock_buttons = [] for q in mock_questions: btn = gr.Button(q, elem_classes="mock-btn") mock_buttons.append(btn) # Right column: chatbot + input with gr.Column(scale=3): chatbot = gr.Chatbot() # Input row: 80% textbox + 20% send button with gr.Row(): user_input = gr.Textbox( placeholder="Type your question here...", lines=1, scale=8 # 80% width ) send_btn = gr.Button( "Send", variant="primary", elem_id="send-btn", scale=2 # 20% width ) # Bind send button to respond function send_btn.click( respond, inputs=[user_input, chatbot], outputs=[chatbot, user_input] ) # Bind each mock question button to input field for btn, q in zip(mock_buttons, mock_questions): btn.click( lambda q=q: q, outputs=user_input ) # Launch the app demo.launch()