jdesiree commited on
Commit
c6202c3
·
verified ·
1 Parent(s): 88f3203

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +299 -100
app.py CHANGED
@@ -1,102 +1,301 @@
1
- import os
2
- import openai
3
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
- openai.api_key = os.environ.get("OPENAI_API_KEY")
6
-
7
- # Gradio + OpenAI Chatbot
8
- def chat_with_openai(message, history):
9
- history_openai_format = [
10
- {"role": "user" if h["role"] == "user" else "assistant", "content": h["content"]}
11
- for h in history
12
- ]
13
-
14
- history_openai_format.append({"role": "user", "content": message})
15
-
16
- response = openai.chat.completions.create(
17
- model="gpt-4o-mini",
18
- messages=history_openai_format,
19
- )
20
-
21
- return response.choices[0].message["content"]
22
-
23
- # Custom CSS
24
- css = """
25
- /* Chat container */
26
- #chatbot {
27
- height: 600px !important;
28
- overflow-y: auto !important;
29
- border-radius: 16px !important;
30
- border: 1pt solid #d1d5db !important;
31
- padding: 15px !important;
32
- background: white !important;
33
- box-shadow: 0 2px 6px rgba(0,0,0,0.05) !important;
34
- }
35
-
36
- /* Messages */
37
- .message {
38
- border-radius: 12px !important;
39
- padding: 10px 15px !important;
40
- margin: 8px 0 !important;
41
- }
42
- .message.user {
43
- background: #f1f5f9 !important; /* light slate */
44
- color: #0f172a !important;
45
- }
46
- .message.assistant {
47
- background: #e0f2fe !important; /* light blue */
48
- color: #1e3a8a !important;
49
- }
50
-
51
- /* Textbox (force textarea style) */
52
- .custom-textbox textarea {
53
- border-radius: 12px !important;
54
- border: 1pt solid #64748b !important; /* slate border */
55
- padding: 15px 20px !important;
56
- font-size: 16px !important;
57
- background: white !important;
58
- outline: none !important;
59
- box-shadow: 0 2px 4px rgba(0,0,0,0.1) !important;
60
- transition: all 0.3s ease !important;
61
- min-height: 100px !important; /* rectangle instead of flat line */
62
- resize: vertical !important;
63
- }
64
- .custom-textbox textarea:focus {
65
- border-color: #3b82f6 !important; /* blue focus */
66
- box-shadow: 0 4px 8px rgba(59,130,246,0.2) !important;
67
- }
68
-
69
- /* Send button */
70
- button {
71
- border-radius: 12px !important;
72
- background: #3b82f6 !important;
73
- color: white !important;
74
- padding: 12px 18px !important;
75
- font-size: 16px !important;
76
- border: none !important;
77
- transition: background 0.3s ease !important;
78
- }
79
- button:hover {
80
- background: #2563eb !important;
81
- }
82
- """
83
-
84
- # Gradio UI
85
- with gr.Blocks(css=css) as demo:
86
- chatbot = gr.Chatbot(elem_id="chatbot", bubble_full_width=False, height=600)
87
-
88
- with gr.Row():
89
- msg = gr.Textbox(
90
- placeholder="Ask me about math, research, study strategies, or any educational topic...",
91
- container=False,
92
- show_label=False,
93
- elem_classes=["custom-textbox"],
94
- lines=3,
95
- max_lines=6
96
- )
97
- submit = gr.Button("Send", scale=0)
98
-
99
- msg.submit(chat_with_openai, [msg, chatbot], chatbot)
100
- submit.click(chat_with_openai, [msg, chatbot], chatbot)
101
-
102
- demo.launch()
 
 
 
1
  import gradio as gr
2
+ from langchain.prompts import ChatPromptTemplate
3
+ from langchain_huggingface import HuggingFaceEndpoint
4
+ from langchain.schema import HumanMessage, SystemMessage
5
+ import os
6
+ import time
7
+ import logging
8
+ import re
9
+
10
+ logging.basicConfig(level=logging.INFO)
11
+ logger = logging.getLogger(__name__)
12
+
13
+ llm = HuggingFaceEndpoint(
14
+ repo_id="HuggingFaceH4/zephyr-7b-beta",
15
+ temperature=0.7,
16
+ top_p=0.9,
17
+ repetition_penalty=1.1,
18
+ model_kwargs={"max_length": 1024},
19
+ huggingfacehub_api_token=os.getenv("HUGGINGFACEHUB_API_TOKEN")
20
+ )
21
+
22
+ math_template = ChatPromptTemplate.from_messages([
23
+ ("system", """{system_message}
24
+
25
+ You are an expert math tutor. For every math problem:
26
+ 1. Break it down into key concepts
27
+ 2. Breifly explain concepts
28
+ 3. Outline the process for solving a similar problem
29
+
30
+ Be comprehensive and educational. Structure your response clearly."""),
31
+ ("human", "{question}")
32
+ ])
33
+
34
+ research_template = ChatPromptTemplate.from_messages([
35
+ ("system", """{system_message}
36
+
37
+ You are a research skills mentor. Help students with:
38
+ - Determining the validity of sources
39
+ - Evaluating source credibility and bias if a source is mentioned
40
+ - Proper citation formats (APA, MLA, Chicago, etc.)
41
+ - Research strategies and methodologies
42
+ - Academic writing techniques and structure
43
+ - Database navigation and search strategies
44
+
45
+ Provide detailed, actionable advice with specific examples."""),
46
+ ("human", "{question}")
47
+ ])
48
+
49
+ study_template = ChatPromptTemplate.from_messages([
50
+ ("system", """{system_message}
51
+
52
+ You are a study skills coach. Help students with:
53
+ - Effective study methods for different learning styles
54
+ - Time management and scheduling techniques
55
+ - Memory techniques and retention strategies
56
+ - Test preparation and exam strategies
57
+ - Note-taking methods and organization
58
+ - Learning style optimization
59
+ - Offer short quiz sessions where you pose one to two questions at a time, then provide feedback on the students answers.
60
+
61
+ Provide comprehensive, personalized advice with practical examples."""),
62
+ ("human", "{question}")
63
+ ])
64
+
65
+ general_template = ChatPromptTemplate.from_messages([
66
+ ("system", """{system_message}
67
+
68
+ You are EduBot, a comprehensive AI learning assistant. You help students with:
69
+ 📐 Mathematics (Concise explainations rooted in understanding the concepts and process rather than answering the math problem directly)
70
+ 🔍 Research skills (source guidance, research advice, evaluation, and citation)
71
+ 📚 Study strategies (effective learning techniques and exam preparation)
72
+ 🛠️ Educational tools (guidance on learning resources and technologies)
73
+
74
+ Always be encouraging, patient, thorough, and comprehensive."""),
75
+ ("human", "{question}")
76
+ ])
77
+
78
+ def detect_subject(message):
79
+ message_lower = message.lower()
80
+
81
+ math_keywords = ['math', 'solve', 'calculate', 'equation', 'formula', 'algebra', 'geometry', 'calculus', 'derivative', 'integral', 'theorem', 'proof']
82
+ research_keywords = ['research', 'source', 'citation', 'bibliography', 'reference', 'academic', 'paper', 'essay', 'thesis', 'database', 'journal']
83
+ study_keywords = ['study', 'memorize', 'exam', 'test', 'quiz', 'review', 'learn', 'remember', 'focus', 'motivation', 'notes']
84
+
85
+ if any(keyword in message_lower for keyword in math_keywords):
86
+ return math_template, "🧮 Math Mode"
87
+ elif any(keyword in message_lower for keyword in research_keywords):
88
+ return research_template, "🔍 Research Mode"
89
+ elif any(keyword in message_lower for keyword in study_keywords):
90
+ return study_template, "📚 Study Mode"
91
+ else:
92
+ return general_template, "🎓 General Mode"
93
+
94
+ def smart_truncate(text, max_length=3000):
95
+ if len(text) <= max_length:
96
+ return text
97
+
98
+ sentences = re.split(r'(?<=[.!?]) +', text[:max_length])
99
+ if len(sentences) > 1:
100
+ return ' '.join(sentences[:-1]) + "... [Response truncated - ask for continuation]"
101
+ else:
102
+ words = text[:max_length].split()
103
+ return ' '.join(words[:-1]) + "... [Response truncated - ask for continuation]"
104
+
105
+ def respond_with_enhanced_streaming(message, history):
106
+ try:
107
+ template, mode = detect_subject(message)
108
+ chain = template | llm
109
+
110
+ yield f"*{mode}*\n\nGenerating response..."
111
+
112
+ logger.info(f"Processing {mode} query: {message[:50]}...")
113
+
114
+ response = chain.invoke({
115
+ "question": message,
116
+ "system_message": "You are EduBot, an expert AI learning assistant. Provide comprehensive, educational responses that help students truly understand concepts."
117
+ })
118
+
119
+ response = smart_truncate(response, max_length=3000)
120
+
121
+ words = response.split()
122
+ partial_response = f"*{mode}*\n\n"
123
+
124
+ for i, word in enumerate(words):
125
+ partial_response += word + " "
126
+
127
+ if i % 4 == 0:
128
+ yield partial_response
129
+ time.sleep(0.03)
130
+
131
+ final_response = f"*{mode}*\n\n{response}"
132
+ logger.info(f"Response completed. Length: {len(response)} characters")
133
+ yield final_response
134
+
135
+ except Exception as e:
136
+ logger.exception("Error in LangChain response generation")
137
+ yield f"Sorry, I encountered an error: {str(e)[:150]}"
138
+
139
+ theme = gr.themes.Glass(
140
+ primary_hue="amber",
141
+ text_size="md",
142
+ radius_size="md",
143
+ ).set(
144
+ shadow_drop='*shadow_drop_lg',
145
+ shadow_drop_lg='*shadow_drop',
146
+ shadow_spread='*shadow_drop_lg',
147
+ block_info_text_weight='500',
148
+ button_border_width='*block_border_width'
149
+ )
150
+
151
+ with gr.Blocks(theme=theme, css="""
152
+ .main-container {
153
+ max-width: 900px;
154
+ margin: 0 auto;
155
+ padding: 1rem;
156
+ height: 100vh;
157
+ display: flex;
158
+ flex-direction: column;
159
+ }
160
+ .title {
161
+ text-align: center;
162
+ font-size: clamp(1.8rem, 4vw, 2.5rem);
163
+ font-weight: bold;
164
+ color: #d97706;
165
+ margin-bottom: 1rem;
166
+ flex-shrink: 0;
167
+ }
168
+ .chat-container {
169
+ flex: 1;
170
+ display: flex;
171
+ flex-direction: column;
172
+ min-height: 0;
173
+ margin-bottom: 1rem;
174
+ }
175
+ .gradio-chatbot {
176
+ flex: 1 !important;
177
+ height: auto !important;
178
+ min-height: 400px;
179
+ max-height: calc(100vh - 250px);
180
+ }
181
+
182
+ .gradio-chatbot .message-wrap .avatar-container {
183
+ display: none !important;
184
+ }
185
+
186
+ .input-row {
187
+ flex-shrink: 0;
188
+ margin-top: 0.5rem;
189
+ display: flex;
190
+ justify-content: center;
191
+ align-items: flex-end;
192
+ gap: 10px;
193
+ max-width: 700px;
194
+ margin-left: auto;
195
+ margin-right: auto;
196
+ }
197
+
198
+ .custom-textarea textarea {
199
+ border-radius: 20px !important;
200
+ border: 2px solid #64748b !important;
201
+ padding: 15px 20px !important;
202
+ font-size: 16px !important;
203
+ background: white !important;
204
+ outline: none !important;
205
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1) !important;
206
+ transition: all 0.3s ease !important;
207
+ resize: vertical !important;
208
+ font-family: inherit !important;
209
+ }
210
+
211
+ .custom-textarea textarea:focus {
212
+ border-color: #475569 !important;
213
+ box-shadow: 0 0 0 3px rgba(100, 116, 139, 0.1) !important;
214
+ }
215
+
216
+ .custom-textarea label {
217
+ display: none !important;
218
+ }
219
+
220
+ .send-button {
221
+ border-radius: 50% !important;
222
+ width: 50px !important;
223
+ height: 50px !important;
224
+ display: flex !important;
225
+ align-items: center !important;
226
+ justify-content: center !important;
227
+ flex-shrink: 0 !important;
228
+ }
229
+
230
+ @media (max-width: 768px) {
231
+ .main-container {
232
+ padding: 0.5rem;
233
+ }
234
+ .title {
235
+ font-size: 1.5rem;
236
+ margin-bottom: 0.5rem;
237
+ }
238
+ .gradio-chatbot {
239
+ min-height: 300px;
240
+ max-height: calc(100vh - 200px);
241
+ }
242
+ .input-row {
243
+ margin-top: 0.25rem;
244
+ max-width: 100%;
245
+ padding: 0 0.5rem;
246
+ }
247
+ .custom-textarea textarea {
248
+ padding: 12px 15px !important;
249
+ font-size: 14px !important;
250
+ }
251
+ }
252
+
253
+ @media (min-width: 769px) and (max-width: 1024px) {
254
+ .gradio-chatbot {
255
+ min-height: 450px;
256
+ max-height: calc(100vh - 230px);
257
+ }
258
+ }
259
+
260
+ @media (min-width: 1025px) {
261
+ .gradio-chatbot {
262
+ min-height: 500px;
263
+ max-height: calc(100vh - 250px);
264
+ }
265
+ }
266
+ """) as demo:
267
+
268
+ with gr.Column(elem_classes=["main-container"]):
269
+ gr.HTML('<div class="title">🎓 EduBot</div>')
270
+
271
+ with gr.Column(elem_classes=["chat-container"]):
272
+ chatbot = gr.Chatbot(
273
+ show_copy_button=True,
274
+ avatar_images=[None, None],
275
+ placeholder="Hi! I'm EduBot. What would you like to learn today? 📚",
276
+ container=True,
277
+ elem_classes=["gradio-chatbot"]
278
+ )
279
+
280
+ with gr.Row(elem_classes=["input-row"]):
281
+ msg = gr.Textbox(
282
+ placeholder="Ask me about math, research, study strategies, or any educational topic...",
283
+ container=False,
284
+ show_label=False,
285
+ lines=4,
286
+ max_lines=8,
287
+ elem_classes=["custom-textarea"]
288
+ )
289
+ send_btn = gr.Button("📤", variant="primary", elem_classes=["send-button"])
290
+
291
+ def respond_and_update(message, history):
292
+ for response in respond_with_enhanced_streaming(message, history):
293
+ history.append([message, response])
294
+ yield history, ""
295
+
296
+ msg.submit(respond_and_update, [msg, chatbot], [chatbot, msg])
297
+ send_btn.click(respond_and_update, [msg, chatbot], [chatbot, msg])
298
 
299
+ if __name__ == "__main__":
300
+ logger.info("Starting EduBot...")
301
+ demo.launch()