File size: 8,391 Bytes
109ed63 724d7e3 d65af72 724d7e3 d65af72 724d7e3 d65af72 724d7e3 d65af72 724d7e3 d65af72 724d7e3 d65af72 724d7e3 d65af72 109ed63 d65af72 724d7e3 d65af72 724d7e3 75bf844 724d7e3 59b654d 724d7e3 d65af72 724d7e3 d65af72 109ed63 75bf844 109ed63 724d7e3 109ed63 724d7e3 109ed63 75bf844 109ed63 d65af72 109ed63 724d7e3 75bf844 724d7e3 109ed63 724d7e3 109ed63 d65af72 75bf844 109ed63 75bf844 109ed63 75bf844 109ed63 75bf844 d65af72 75bf844 109ed63 724d7e3 109ed63 75bf844 109ed63 75bf844 109ed63 75bf844 109ed63 724d7e3 109ed63 92a7efa d65af72 92a7efa d65af72 92a7efa | 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 | import streamlit as st
from huggingface_hub import InferenceClient
st.set_page_config(page_title="JEE AI Mentor", page_icon="π", layout="centered")
# --- CUSTOM CSS: GEMINI-INSPIRED MINIMALIST UI ---
st.markdown("""
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
.stApp {
background-color: #131314;
color: #e3e3e3;
font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}
.main-title {
text-align: center;
font-size: 2rem;
font-weight: 500;
background: linear-gradient(45deg, #4285f4, #9b51e0);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 0.2rem;
}
.main-subtitle {
text-align: center;
font-size: 0.9rem;
color: #80868b;
margin-bottom: 1.5rem;
}
/* Minimalist Rounded Controls */
div[data-baseweb="select"] > div {
border-radius: 24px !important;
background-color: #1e1f20 !important;
border: 1px solid #303134 !important;
color: #e3e3e3 !important;
padding: 2px 8px !important;
}
div[data-baseweb="select"] span { color: #e3e3e3 !important; }
div[data-testid="stMarkdownContainer"] > p { color: #c4c7c5; font-size: 0.95rem; }
/* Message Bubbles Styling */
div[data-testid="stChatMessage"] {
background-color: transparent !important;
border: none !important;
padding: 0.5rem 0 !important;
}
div[data-testid="stChatMessage"]:has(div[data-testid="chatAvatar-user"]) { text-align: right; }
div[data-testid="stChatMessage"]:has(div[data-testid="chatAvatar-user"]) div[data-testid="stMarkdownContainer"] p {
display: inline-block;
background-color: #2b2a33;
padding: 10px 18px;
border-radius: 20px 20px 4px 20px;
color: #e3e3e3;
text-align: left;
max-width: 85%;
}
div[data-testid="stChatMessage"]:has(div[data-testid="chatAvatar-assistant"]) div[data-testid="stMarkdownContainer"] {
color: #e3e3e3; font-size: 1.05rem; line-height: 1.6; max-width: 95%;
}
div[data-testid="chatAvatar-user"], div[data-testid="chatAvatar-assistant"] { display: none !important; }
/* Chat Input Layout Configuration */
div[data-testid="stChatInput"] {
position: fixed;
bottom: 24px;
left: 50%;
transform: translateX(-50%);
width: 90% !important;
max-width: 700px;
z-index: 99;
}
div[data-testid="stChatInput"] textarea {
border-radius: 28px !important;
background-color: #1e1f20 !important;
border: 1px solid #303134 !important;
color: #e3e3e3 !important;
padding: 14px 20px !important;
}
.block-container { padding-bottom: 180px !important; }
</style>
""", unsafe_allow_html=True)
# --- HEADER ---
st.markdown('<div class="main-title">JEE Focus AI</div>', unsafe_allow_html=True)
st.markdown('<div class="main-subtitle">Your personalized Advanced preparation partner</div>', unsafe_allow_html=True)
# --- CONTROLS ---
col1, col2 = st.columns(2)
with col1:
target_class = st.selectbox("Class context", ["Class 12 Aspirant", "Dropper Batch", "Class 11"], label_visibility="collapsed")
with col2:
subject = st.selectbox("Subject focus", ["Physics", "Chemistry", "Mathematics"], label_visibility="collapsed")
query_type = st.radio(
"Select operational lens:",
["π Doubt", "β³ Backlog", "π₯ Motivation", "π§ Revision"],
horizontal=True,
label_visibility="collapsed"
)
# Initialize Chat History
if "messages" not in st.session_state:
st.session_state.messages = [
{"role": "assistant", "content": "Context established. Adjust constraints above whenever you switch tasks. What problem framework or chapter strategy are we evaluating?"}
]
# Display Chat History
for message in st.session_state.messages:
display_content = message["content"]
if "[CONTEXT:" in display_content and "]" in display_content:
display_content = display_content.split("]")[-1].strip()
with st.chat_message(message["role"]):
st.markdown(display_content)
# Input Execution Bar
if user_prompt := st.chat_input("Ask me anything..."):
context_injector = (
f"[CONTEXT: The student is dealing with a {query_type} query for {subject} relevant to {target_class} status. "
"Structure your response specifically through this operational lens.] "
)
with st.chat_message("user"):
st.markdown(user_prompt)
st.session_state.messages.append({"role": "user", "content": context_injector + user_prompt})
with st.chat_message("assistant"):
response_placeholder = st.empty()
full_response = ""
try:
client = InferenceClient()
system_instruction = (
"You are an elite, veteran JEE Advanced mentor who coached top 100 rankers. "
"You understand the exact pressures of Class 11/12/Dropper PCM, standard coaching modules, and PYQ weights.\n"
"CRITICAL: Tailor your response perfectly based on the hidden [CONTEXT] config data:\n"
"- If target is 'Class 12 Aspirant': Balance your tips around board management, school practicals, and running syllabus timelines.\n"
"- If target is 'Dropper Batch': Assume zero school restrictions, focus heavily on maximizing high-yield execution, rigorous test analysis, and handling drop-year mental pressure.\n"
"- If target is 'Class 11': Prioritize fundamental building blocks, tackling initial mechanics/organic shock, and long-term consistency.\n\n"
"Further segment by action lens:\n"
"- If 'Doubt': Break down the core mathematical or conceptual physics/chem mechanisms step-by-step.\n"
"- If 'Backlog': Give a high-yield micro-schedule prioritizing mandatory chapters before deep diving into sub-topics.\n"
"- If 'Motivation': Be blunt, realistic, highly encouraging, and cut through decision paralysis.\n"
"- If 'Revision': Detail how to make high-yield formula sheets and short notes trackers.\n"
"Keep responses concise, bolding critical terms, completely optimized for clean conversational mobile reading. Avoid generic greetings."
)
formatted_messages = [{"role": "system", "content": system_instruction}]
for msg in st.session_state.messages:
formatted_messages.append({"role": msg["role"], "content": msg["content"]})
# Using the ultra-stable, permanently supported serverless model text link
stream = client.chat.completions.create(
model="meta-llama/Meta-Llama-3-8B-Instruct",
messages=formatted_messages,
max_tokens=800,
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
full_response += chunk.choices[0].delta.content
response_placeholder.markdown(full_response + "β")
response_placeholder.markdown(full_response)
except Exception as e:
st.error(f"Transmission bottleneck: {e}")
full_response = "Hit a brief connection bump. Mind dropping that question in one more time?"
response_placeholder.markdown(full_response)
st.session_state.messages.append({"role": "assistant", "content": full_response})
# --- MINIMALIST FOOTER CREDIT ---
st.markdown("""
<div style="text-align: center; font-size: 0.75rem; color: #80868b; font-family: sans-serif; margin-top: 20px;">
Follow Me <a href="https://instagram.com/kosmos.cpp" style="color: #4285f4; text-decoration: none; font-weight: 500;" target="_blank">ig@kosmos.cpp</a>
</div>
""", unsafe_allow_html=True)
|