chatbot / app.py
prabhu-nithin's picture
Update app.py
25e5898 verified
Raw
History Blame Contribute Delete
6.34 kB
import os
import streamlit as st
from dotenv import load_dotenv
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter, MarkdownHeaderTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_classic.chains import create_retrieval_chain
from langchain_classic.chains.combine_documents import create_stuff_documents_chain
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.documents import Document
from persona import get_enhanced_system_prompt, COMMON_RESPONSES, PERSONA
# Load environment variables
load_dotenv()
# Get the Google API key
api_key = os.getenv('GOOGLE_API_KEY')
if not api_key:
print("Google API key not found in .env file.")
exit(1)
# Streamlit app title
st.title("Chat with Prabhu Nithin Gollapudi")
intro_line = "AI/ML Engineer with 5 years of Industry and Research experience, currently freelancing in AI/ML, Data Engineering and Agentic Systems. Specializing in AI agents, LLMs, medical robotics research, and full-stack development. Master's in AI at FAU."
st.markdown(f"#### {intro_line}")
st.write(COMMON_RESPONSES["contact"])
# Add a profile image if available
try:
from PIL import Image
import base64
from pathlib import Path
# Check if a profile image exists
image_path = Path("profile_image.png")
if image_path.exists():
image = Image.open(image_path)
st.image(image, width=150)
except ImportError:
pass
st.markdown("---")
# Cache the vectorstore for efficiency (loads once)
@st.cache_resource
def load_vectorstore():
# Check for both markdown
markdown_path = "resume.md"
if os.path.exists(markdown_path):
return load_from_markdown(markdown_path)
else:
st.error("No resume file found! Add 'resume.md' to the project directory.")
return None
def load_from_markdown(file_path):
"""Load and process markdown resume file."""
with st.spinner("Loading resume from markdown..."):
try:
# Use MarkdownHeaderTextSplitter for better structure awareness
headers_to_split_on = [
("#", "Header 1"),
("##", "Header 2"),
("###", "Header 3"),
("####", "Header 4"),
]
markdown_splitter = MarkdownHeaderTextSplitter(
headers_to_split_on=headers_to_split_on,
strip_headers=False
)
# Read the markdown file
with open(file_path, 'r', encoding='utf-8') as file:
markdown_content = file.read()
# Split by headers first
md_header_splits = markdown_splitter.split_text(markdown_content)
# Further split if chunks are too large
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
separators=["\n\n", "\n", " ", ""]
)
# Process the documents
all_splits = []
for doc in md_header_splits:
if len(doc.page_content) > 1000:
# Split large sections further
sub_splits = text_splitter.split_documents([doc])
all_splits.extend(sub_splits)
else:
all_splits.append(doc)
# Create embeddings and vectorstore
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
vectorstore = FAISS.from_documents(all_splits, embeddings)
return vectorstore
except Exception as e:
st.error(f"Error loading markdown file: {str(e)}")
return None
# Load vectorstore
vectorstore = load_vectorstore()
# Session state for chat history
if "chat_history" not in st.session_state:
st.session_state.chat_history = []
# Set up RAG chain if vectorstore loaded
if vectorstore:
# Free HF LLM
llm = ChatGoogleGenerativeAI(
model="gemini-2.5-flash", # Trying gemini-2.5-flash
temperature=0.1,
max_output_tokens=512,
google_api_key=api_key
)
# Use the enhanced system prompt from persona module
system_prompt = get_enhanced_system_prompt()
prompt = ChatPromptTemplate.from_template(system_prompt)
# Create chains
question_answering_chain = create_stuff_documents_chain(llm, prompt)
rag_chain = create_retrieval_chain(vectorstore.as_retriever(), question_answering_chain)
# Display welcome message if chat history is empty
if not st.session_state.chat_history:
welcome_message = COMMON_RESPONSES["greeting"]
research_intro = f"\n\nI'm actively job hunting for full-time opportunities in 2026! Currently, I'm freelancing in AI/ML, Data Engineering and Agentic Systems, building AI agents and LLM applications. This chatbot is a hobby project I built to showcase my AI skills. What would you like to know about my journey, technical projects, research experience, or career goals?"
st.session_state.chat_history.append({"role": "assistant", "content": welcome_message + research_intro})
# Display chat history
for message in st.session_state.chat_history:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# User input
if prompt := st.chat_input("Ask me about my AI/ML experience, projects, freelance work, research, or career goals..."):
st.session_state.chat_history.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
with st.spinner("Thinking..."):
response = rag_chain.invoke({"input": prompt})
answer = response["answer"] if "answer" in response else COMMON_RESPONSES["not_in_resume"]
st.markdown(answer)
st.session_state.chat_history.append({"role": "assistant", "content": answer})
else:
st.info("Resume not loaded. Check the project setup.")