thiru10/Coding_Assistant
0
1import streamlit as st2import os3import shutil4from dotenv import load_dotenv5from langchain_groq import ChatGroq6from langchain_community.embeddings import SentenceTransformerEmbeddings7from langchain_community.vectorstores import FAISS8from langchain.chains import RetrievalQA9from ingest import main as ingest_data10 11# --- Configuration ---12BASE_DIR = os.path.dirname(os.path.abspath(__file__))13load_dotenv(dotenv_path=os.path.join(BASE_DIR, ".env"))14PERSIST_DIR = os.path.join(BASE_DIR, "db")15 16# --- Caching Functions ---17 18from langchain.prompts import PromptTemplate19 20# --- Prompt Engineering ---21prompt_template = """""22 You are Python programmer, assisting a user in coding choosing algorithms explaining concepts as a assistant and tutor, confident, and concise.23 24 25 You said:26 You are PyTutor, an expert Python programmer and teaching assistant.27 Your role is to help users understand, design, and debug Python code confidently and clearly.28 29 Guidelines:30 31 Be concise, precise, and technically accurate.32 33 Always explain the reasoning behind your code or solution.34 35 When relevant, compare alternative approaches and explain why one is preferred.36 37 Use simple language when explaining complex algorithms.38 39 Prioritize clarity, correctness, and performance in code examples.40 41 Provide step-by-step explanations for concepts or algorithms.42 43 When teaching, use small, runnable Python snippets.44 45 Avoid unnecessary verbosity or overgeneralization — keep answers focused and confident.46 47 Always assume the user is learning Python actively and wants to understand, not just copy.48 49 Tone:50 51 Confident, concise, and instructive — like a skilled mentor guiding a student through real code.52 Context:53 {context}54 55 Question: {question}56 57 Interview Answer:58"""""59QA_CHAIN_PROMPT = PromptTemplate.from_template(prompt_template)60 61# --- Caching Functions ---62 63@st.cache_resource(show_spinner="Connecting to LLM...")64def llm_pipeline():65 """Initializes the Groq LLM pipeline."""66 token = os.getenv("GROQ_API_KEY")67 if not token:68 st.error("GROQ_API_KEY is not set. Please add it to your .env file.")69 st.stop()70 71 try:72 llm = ChatGroq(73 groq_api_key=token,74 model_name="llama-3.1-8b-instant",75 temperature=0.4,76 max_tokens=102477 )78 return llm79 except Exception as e:80 st.error(f"Failed to initialize Groq LLM: {e}")81 st.stop()82 83@st.cache_resource(show_spinner="Loading Knowledge Base...")84def qa_llm(_llm):85 """Initializes the RetrievalQA chain."""86 try:87 embeddings = SentenceTransformerEmbeddings(88 model_name="all-MiniLM-L6-v2",89 model_kwargs={"device": "cpu"}90 )91 92 if not os.path.exists(PERSIST_DIR):93 st.warning("Knowledge base not found. Please build it first.")94 return None95 96 db = FAISS.load_local(PERSIST_DIR, embeddings, allow_dangerous_deserialization=True)97 retriever = db.as_retriever(search_kwargs={'k': 5})98 99 qa = RetrievalQA.from_chain_type(100 llm=_llm,101 chain_type="stuff",102 retriever=retriever,103 return_source_documents=True,104 chain_type_kwargs={"prompt": QA_CHAIN_PROMPT}105 )106 return qa107 except Exception as e:108 st.error(f"Error initializing QA pipeline: {e}")109 return None110 111# --- Main App Logic ---112 113def main():114 st.set_page_config(page_title="Assistant", layout="centered")115 st.markdown("<h1 style='text-align:center;color:blue;'>Coding Assistant 🤖</h1>", unsafe_allow_html=True)116 st.markdown("### Ask me anything about Programming ")117 118 # --- Sidebar for Actions ---119 with st.sidebar:120 st.markdown("## Actions")121 if st.button("Build/Update Knowledge Base"):122 with st.spinner("Ingesting data from all sources... This may take a moment."):123 ingest_data() # Call the main function from ingest.py124 st.success("Knowledge Base is up to date!")125 st.cache_resource.clear() # Clear cache to reload QA chain126 st.rerun()127 128 st.markdown("---_")129 st.markdown("**Sources:**")130 st.markdown("- PDF(s) in `docs/` folder")131 132 # --- Main Chat Interface ---133 if not os.path.exists(PERSIST_DIR):134 st.info("Welcome! Please build the knowledge base using the button in the sidebar to get started.")135 st.stop()136 137 llm = llm_pipeline()138 qa = qa_llm(llm)139 140 if qa is None:141 st.warning("The QA system is not available. Please build the knowledge base.")142 st.stop()143 144 # Pre-defined questions145 example_prompts = [146 "Explain the difference between time and space complexity with examples.",147 "Write an optimized Python solution for the Two Sum problem and explain your approach.",148 "Can you walk me through how to solve a problem using dynamic programming?",149 "Show me how to implement binary search and analyze its complexity.",150 "Compare BFS and DFS in terms of use cases and efficiency.",151 "What are the most common sorting algorithms used in interviews?",152 "Explain how to detect a cycle in a linked list using Floyd’s algorithm.",153 "Give me the Python code for merging two sorted arrays efficiently.",154 "Walk me through solving a problem with recursion and then optimizing it with memoization.",155 "How do I explain my approach to an interviewer for a graph traversal problem?"156 ]157 158 cols = st.columns(2)159 for i, prompt in enumerate(example_prompts):160 if cols[i % 2].button(prompt):161 st.session_state["last_input"] = prompt162 163 # User input164 user_input = st.text_input("Your question:", key="user_input")165 user_question = st.session_state.pop("last_input", None) or user_input166 167 if user_question:168 with st.spinner("Thinking..."):169 try:170 response = qa({"query": user_question})171 answer = response.get("result", "No answer found.")172 173 st.markdown(f"**You:** {user_question}")174 st.markdown(f"**Assistant:** {answer}")175 176 # Display source documents177 with st.expander("See sources"):178 for doc in response.get("source_documents", []):179 st.info(f"**Source:** `{os.path.basename(doc.metadata.get('source', 'N/A'))}`")180 st.text(doc.page_content[:300] + "...")181 except Exception as e:182 st.error(f"An error occurred: {e}")183 184if __name__ == "__main__":185 main()186 