File size: 8,671 Bytes
352d473 c672d1b 35e8298 352d473 35e8298 f73c0d1 35e8298 f73c0d1 35e8298 352d473 f73c0d1 35e8298 c672d1b f73c0d1 473251f c672d1b 35e8298 f73c0d1 473251f f73c0d1 35e8298 f73c0d1 35e8298 f73c0d1 35e8298 f73c0d1 35e8298 f73c0d1 c672d1b 35e8298 f73c0d1 352d473 35e8298 f73c0d1 352d473 35e8298 f73c0d1 35e8298 f73c0d1 35e8298 f73c0d1 35e8298 f73c0d1 35e8298 f73c0d1 35e8298 f73c0d1 35e8298 f73c0d1 35e8298 f73c0d1 35e8298 f73c0d1 35e8298 352d473 35e8298 |
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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
import streamlit as st
import json
import time
# Page configuration
st.set_page_config(
page_title="Manyue's Portfolio Chatbot",
page_icon="π€",
layout="wide",
initial_sidebar_state="collapsed"
)
# Custom CSS for better UI
st.markdown("""
<style>
.chat-message {
padding: 1.5rem;
border-radius: 0.5rem;
margin-bottom: 1rem;
}
.user-message {
background-color: #e9ecef;
}
.bot-message {
background-color: #f8f9fa;
}
.stButton>button {
width: 100%;
}
</style>
""", unsafe_allow_html=True)
# Initialize session state
if 'messages' not in st.session_state:
st.session_state.messages = []
if 'knowledge_base' not in st.session_state:
st.session_state.knowledge_base = None
def load_knowledge_base():
"""Load the knowledge base from JSON file"""
if st.session_state.knowledge_base is None:
try:
with open('knowledge_base.json', 'r', encoding='utf-8') as f:
st.session_state.knowledge_base = json.load(f)
except Exception as e:
st.error(f"Error loading knowledge base: {str(e)}")
st.session_state.knowledge_base = {}
return st.session_state.knowledge_base
def get_enhanced_context(query: str, knowledge_base: dict) -> dict:
"""Get relevant context with improved retrieval"""
query_lower = query.lower()
context = {
"type": "general",
"content": [],
"relevant_sections": []
}
# Project-related queries
if any(word in query_lower for word in ["project", "build", "develop", "create", "make", "portfolio"]):
context["type"] = "project"
if "projects" in knowledge_base:
for name, project in knowledge_base["projects"].items():
context["content"].append({
"title": name,
"description": project.get("description", ""),
"skills_used": project.get("skills_used", []),
"status": project.get("status", "")
})
# Skills and experience
elif any(word in query_lower for word in ["skill", "experience", "know", "capable", "ability", "expert"]):
context["type"] = "skill"
if "skills" in knowledge_base.get("personal_details", {}):
context["content"] = knowledge_base["personal_details"]["skills"]
# Educational background
elif any(word in query_lower for word in ["education", "study", "learn", "degree", "college", "university"]):
context["type"] = "education"
context["content"] = knowledge_base.get("education", {})
# Career and goals
elif any(word in query_lower for word in ["goal", "plan", "future", "career", "aspiration"]):
context["type"] = "career"
context["content"] = {
"short_term": knowledge_base.get("goals_and_aspirations", {}).get("short_term", []),
"long_term": knowledge_base.get("goals_and_aspirations", {}).get("long_term", [])
}
# Personal background
elif any(word in query_lower for word in ["background", "journey", "story", "transition"]):
context["type"] = "background"
context["content"] = knowledge_base.get("personal_journey", {})
# Add FAQ matches if available
for qa in knowledge_base.get("frequently_asked_questions", []):
if any(word in qa["question"].lower() for word in query_lower.split()):
context["relevant_sections"].append({
"type": "faq",
"question": qa["question"],
"answer": qa["answer"]
})
return context
def generate_response(query: str, context: dict) -> str:
"""Generate natural response based on context"""
response_parts = []
# Handle different types of queries
if context["type"] == "project":
response_parts.append("Let me tell you about my projects.")
for project in context["content"]:
response_parts.append(f"\n\n**{project['title']}**")
response_parts.append(f"{project['description']}")
if project['skills_used']:
response_parts.append(f"\nSkills used: {', '.join(project['skills_used'])}")
if project['status']:
response_parts.append(f"\nStatus: {project['status']}")
elif context["type"] == "skill":
response_parts.append("Here are my key skills and experiences:")
for skill, desc in context["content"].items():
response_parts.append(f"\n\n**{skill}**:\n{desc}")
elif context["type"] == "education":
response_parts.append("Regarding my educational background:")
if "academic_background" in context["content"]:
response_parts.append(context["content"]["academic_background"])
if "academic_achievements" in context["content"]:
response_parts.append("\n\nAchievements:")
for achievement in context["content"]["academic_achievements"]:
response_parts.append(f"- {achievement}")
elif context["type"] == "career":
response_parts.append("Let me share my career goals:")
response_parts.append("\n\n**Short-term goals:**")
for goal in context["content"]["short_term"]:
response_parts.append(f"- {goal}")
response_parts.append("\n\n**Long-term goals:**")
for goal in context["content"]["long_term"]:
response_parts.append(f"- {goal}")
elif context["type"] == "background":
response_parts.append(context["content"].get("mindset", ""))
response_parts.append("\n\n" + context["content"].get("motto_or_vision", ""))
# Add any relevant FAQ information
if context["relevant_sections"]:
for section in context["relevant_sections"]:
if section["type"] == "faq":
response_parts.append(f"\n\n{section['answer']}")
# Default response if no specific context matched
if not response_parts:
response_parts = ["I am Manyue, an aspiring AI/ML engineer. I can tell you about my projects, skills, education, or career goals. What would you like to know?"]
return "\n".join(response_parts)
def main():
st.title("π¬ Chat with Manyue's Portfolio")
st.write("Ask me about my skills, projects, education, or career goals!")
# Load knowledge base
knowledge_base = load_knowledge_base()
# Create two columns for layout
col1, col2 = st.columns([3, 1])
with col1:
# Display chat messages
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# Chat input
if prompt := st.chat_input("What would you like to know?"):
# Add user message
st.session_state.messages.append({"role": "user", "content": prompt})
# Get context and generate response
context = get_enhanced_context(prompt, knowledge_base)
response = generate_response(prompt, context)
# Display response with typing effect
with st.chat_message("assistant"):
st.markdown(response)
# Add assistant response to history
st.session_state.messages.append({"role": "assistant", "content": response})
with col2:
st.subheader("Quick Questions")
if st.button("π Tell me about your projects"):
prompt = "What projects have you worked on?"
st.session_state.messages.append({"role": "user", "content": prompt})
st.experimental_rerun()
if st.button("π» What are your technical skills?"):
prompt = "What are your main technical skills?"
st.session_state.messages.append({"role": "user", "content": prompt})
st.experimental_rerun()
if st.button("π Educational background?"):
prompt = "Tell me about your education"
st.session_state.messages.append({"role": "user", "content": prompt})
st.experimental_rerun()
if st.button("π― What are your career goals?"):
prompt = "What are your career goals?"
st.session_state.messages.append({"role": "user", "content": prompt})
st.experimental_rerun()
st.markdown("---")
if st.button("ποΈ Clear Chat"):
st.session_state.messages = []
st.experimental_rerun()
if __name__ == "__main__":
main() |