jdesiree commited on
Commit
a14b74e
·
verified ·
1 Parent(s): 11e992c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +269 -291
app.py CHANGED
@@ -7,23 +7,20 @@ import time
7
  import logging
8
  import re
9
 
10
- # Set up logging for better debugging
11
  logging.basicConfig(level=logging.INFO)
12
  logger = logging.getLogger(__name__)
13
 
14
- # Set up LangChain model with conservative settings
15
  llm = HuggingFaceEndpoint(
16
- repo_id="HuggingFaceH4/zephyr-7b-beta",
17
- temperature=0.7,
18
- top_p=0.9,
19
- repetition_penalty=1.1,
20
- model_kwargs={"max_length": 1024},
21
- huggingfacehub_api_token=os.getenv("HUGGINGFACEHUB_API_TOKEN")
22
  )
23
 
24
- # Enhanced prompt templates that use system_message parameter
25
  math_template = ChatPromptTemplate.from_messages([
26
- ("system", """{system_message}
27
 
28
  You are an expert math tutor. For every math problem:
29
  1. Break it down into key concepts
@@ -31,11 +28,11 @@ You are an expert math tutor. For every math problem:
31
  3. Outline the process for solving a similar problem
32
 
33
  Be comprehensive and educational. Structure your response clearly."""),
34
- ("human", "{question}")
35
  ])
36
 
37
  research_template = ChatPromptTemplate.from_messages([
38
- ("system", """{system_message}
39
 
40
  You are a research skills mentor. Help students with:
41
  - Determining the validity of sources
@@ -46,11 +43,11 @@ You are a research skills mentor. Help students with:
46
  - Database navigation and search strategies
47
 
48
  Provide detailed, actionable advice with specific examples."""),
49
- ("human", "{question}")
50
  ])
51
 
52
  study_template = ChatPromptTemplate.from_messages([
53
- ("system", """{system_message}
54
 
55
  You are a study skills coach. Help students with:
56
  - Effective study methods for different learning styles
@@ -62,11 +59,11 @@ You are a study skills coach. Help students with:
62
  - Offer short quiz sessions where you pose one to two questions at a time, then provide feedback on the students answers.
63
 
64
  Provide comprehensive, personalized advice with practical examples."""),
65
- ("human", "{question}")
66
  ])
67
 
68
  general_template = ChatPromptTemplate.from_messages([
69
- ("system", """{system_message}
70
 
71
  You are EduBot, a comprehensive AI learning assistant. You help students with:
72
  📐 Mathematics (Concise explainations rooted in understanding the concepts and process rather than answering the math problem directly)
@@ -75,295 +72,276 @@ You are EduBot, a comprehensive AI learning assistant. You help students with:
75
  🛠️ Educational tools (guidance on learning resources and technologies)
76
 
77
  Always be encouraging, patient, thorough, and comprehensive."""),
78
- ("human", "{question}")
79
  ])
80
 
81
  def detect_subject(message):
82
- """Determine which prompt template to use based on the message"""
83
- message_lower = message.lower()
84
-
85
- math_keywords = ['math', 'solve', 'calculate', 'equation', 'formula', 'algebra', 'geometry', 'calculus', 'derivative', 'integral', 'theorem', 'proof']
86
- research_keywords = ['research', 'source', 'citation', 'bibliography', 'reference', 'academic', 'paper', 'essay', 'thesis', 'database', 'journal']
87
- study_keywords = ['study', 'memorize', 'exam', 'test', 'quiz', 'review', 'learn', 'remember', 'focus', 'motivation', 'notes']
88
-
89
- if any(keyword in message_lower for keyword in math_keywords):
90
- return math_template, "🧮 Math Mode"
91
- elif any(keyword in message_lower for keyword in research_keywords):
92
- return research_template, "🔍 Research Mode"
93
- elif any(keyword in message_lower for keyword in study_keywords):
94
- return study_template, "📚 Study Mode"
95
- else:
96
- return general_template, "🎓 General Mode"
97
 
98
  def smart_truncate(text, max_length=3000):
99
- """Intelligently truncate text at sentence boundaries"""
100
- if len(text) <= max_length:
101
- return text
102
-
103
- # Try to cut at last complete sentence
104
- sentences = re.split(r'(?<=[.!?]) +', text[:max_length])
105
- if len(sentences) > 1:
106
- # Remove the last incomplete sentence
107
- return ' '.join(sentences[:-1]) + "... [Response truncated - ask for continuation]"
108
- else:
109
- # Fallback to word boundary
110
- words = text[:max_length].split()
111
- return ' '.join(words[:-1]) + "... [Response truncated - ask for continuation]"
112
 
113
  def respond_with_enhanced_streaming(
114
- message,
115
- history,
116
- max_tokens=600,
117
- temperature=0.7,
118
- top_p=0.9,
119
  ):
120
- """Enhanced LangChain implementation with proper system message handling"""
121
-
122
- try:
123
- # Select template and get mode
124
- template, mode = detect_subject(message)
125
-
126
- # Create LangChain chain
127
- chain = template | llm
128
-
129
- # Show initial mode
130
- yield f"*{mode}*\n\nGenerating response..."
131
-
132
- # Get complete response from LangChain with system message
133
- logger.info(f"Processing {mode} query: {message[:50]}...")
134
-
135
- response = chain.invoke({
136
- "question": message,
137
- "system_message": "You are EduBot, an expert AI learning assistant. Provide comprehensive, educational responses that help students truly understand concepts."
138
- })
139
-
140
- # Smart truncation at sentence boundaries
141
- response = smart_truncate(response, max_length=3000)
142
-
143
- # Simulate streaming by chunking the response
144
- words = response.split()
145
- partial_response = f"*{mode}*\n\n"
146
-
147
- # Stream word by word for better UX
148
- for i, word in enumerate(words):
149
- partial_response += word + " "
150
-
151
- # Update every 4 words for smooth streaming effect
152
- if i % 4 == 0:
153
- yield partial_response
154
- time.sleep(0.03)
155
-
156
- # Final complete response
157
- final_response = f"*{mode}*\n\n{response}"
158
- logger.info(f"Response completed. Length: {len(response)} characters")
159
- yield final_response
160
-
161
- except Exception as e:
162
- logger.exception("Error in LangChain response generation")
163
- yield f"Sorry, I encountered an error: {str(e)[:150]}"
164
 
165
- # Your custom Glass theme with amber accent
166
  theme = gr.themes.Glass(
167
- primary_hue="amber",
168
- text_size="md",
169
- radius_size="md",
170
  ).set(
171
- shadow_drop='*shadow_drop_lg',
172
- shadow_drop_lg='*shadow_drop',
173
- shadow_spread='*shadow_drop_lg',
174
- block_info_text_weight='500',
175
- button_border_width='*block_border_width'
176
  )
177
 
178
- # Responsive interface with flexible height and custom styling
179
  with gr.Blocks(theme=theme, css="""
180
- .main-container {
181
- max-width: 900px;
182
- margin: 0 auto;
183
- padding: 1rem;
184
- height: 100vh;
185
- display: flex;
186
- flex-direction: column;
187
- }
188
- .title {
189
- text-align: center;
190
- font-size: clamp(1.8rem, 4vw, 2.5rem);
191
- font-weight: bold;
192
- color: #d97706;
193
- margin-bottom: 1rem;
194
- flex-shrink: 0;
195
- }
196
- .chat-container {
197
- flex: 1;
198
- display: flex;
199
- flex-direction: column;
200
- min-height: 0;
201
- margin-bottom: 1rem;
202
- }
203
- .gradio-chatbot {
204
- flex: 1 !important;
205
- height: auto !important;
206
- min-height: 400px;
207
- max-height: calc(100vh - 200px);
208
- }
209
-
210
- /* Hide the chat icon */
211
- .chat-bot .message-wrap .avatar-container {
212
- display: none !important;
213
- }
214
- .gradio-chatbot .message-wrap .avatar-container {
215
- display: none !important;
216
- }
217
- .gradio-chatbot .message.bot .avatar-container,
218
- .gradio-chatbot .message.user .avatar-container {
219
- display: none !important;
220
- }
221
-
222
- /* Style the input area */
223
- .input-row {
224
- flex-shrink: 0;
225
- margin-top: 0.5rem;
226
- display: flex;
227
- justify-content: center;
228
- align-items: center;
229
- gap: 10px;
230
- max-width: 700px;
231
- margin-left: auto;
232
- margin-right: auto;
233
- }
234
-
235
- /* Custom textbox styling */
236
- .custom-textbox input {
237
- border-radius: 25px !important;
238
- border: 2px solid #64748b !important;
239
- padding: 15px 20px !important;
240
- font-size: 16px !important;
241
- background: white !important;
242
- outline: none !important;
243
- box-shadow: 0 2px 4px rgba(0,0,0,0.1) !important;
244
- transition: all 0.3s ease !important;
245
- }
246
-
247
- .custom-textbox input:focus {
248
- border-color: #475569 !important;
249
- box-shadow: 0 0 0 3px rgba(100, 116, 139, 0.1) !important;
250
- }
251
-
252
- /* Remove textbox label */
253
- .custom-textbox label {
254
- display: none !important;
255
- }
256
-
257
- /* Center the send button */
258
- .send-button {
259
- border-radius: 50% !important;
260
- width: 50px !important;
261
- height: 50px !important;
262
- display: flex !important;
263
- align-items: center !important;
264
- justify-content: center !important;
265
- flex-shrink: 0 !important;
266
- }
267
-
268
- /* Mobile responsiveness */
269
- @media (max-width: 768px) {
270
- .main-container {
271
- padding: 0.5rem;
272
- }
273
- .title {
274
- font-size: 1.5rem;
275
- margin-bottom: 0.5rem;
276
- }
277
- .gradio-chatbot {
278
- min-height: 300px;
279
- max-height: calc(100vh - 150px);
280
- }
281
- .input-row {
282
- margin-top: 0.25rem;
283
- max-width: 100%;
284
- padding: 0 0.5rem;
285
- }
286
- .custom-textbox input {
287
- padding: 12px 15px !important;
288
- font-size: 14px !important;
289
- }
290
- }
291
-
292
- /* Tablet responsiveness */
293
- @media (min-width: 769px) and (max-width: 1024px) {
294
- .gradio-chatbot {
295
- min-height: 450px;
296
- max-height: calc(100vh - 180px);
297
- }
298
- }
299
-
300
- /* Large screens */
301
- @media (min-width: 1025px) {
302
- .gradio-chatbot {
303
- min-height: 500px;
304
- max-height: calc(100vh - 200px);
305
- }
306
- }
307
-
308
- /* Landscape mobile */
309
- @media (max-height: 500px) and (orientation: landscape) {
310
- .title {
311
- font-size: 1.2rem;
312
- margin-bottom: 0.25rem;
313
- }
314
- .gradio-chatbot {
315
- min-height: 200px;
316
- max-height: calc(100vh - 100px);
317
- }
318
- }
 
 
 
 
 
319
  """) as demo:
320
-
321
- with gr.Column(elem_classes=["main-container"]):
322
- # Just the chatbot name at the top
323
- gr.HTML("""
324
- <div class='title'>🎓 EduBot</div>
325
- """)
326
-
327
- # Flexible conversation viewing window
328
- with gr.Column(elem_classes=["chat-container"]):
329
- chatbot = gr.Chatbot(
330
- show_copy_button=True,
331
- avatar_images=[None, None], # Remove avatars
332
- placeholder="Hi! I'm EduBot. What would you like to learn today? 📚",
333
- container=True,
334
- elem_classes=["gradio-chatbot"]
335
- )
336
-
337
- # Centered textbox and send button
338
- with gr.Row(elem_classes=["input-row"]):
339
- msg = gr.Textbox(
340
- placeholder="Ask me about math, research, study strategies, or any educational topic...",
341
- container=False,
342
- show_label=False,
343
- scale=8,
344
- elem_classes=["custom-textbox"]
345
- )
346
- send_btn = gr.Button("📤", variant="primary", scale=1, elem_classes=["send-button"])
347
-
348
- # Enhanced response function
349
- def respond_and_update(message, history):
350
- for response in respond_with_enhanced_streaming(message, history):
351
- history.append([message, response])
352
- yield history, ""
353
-
354
- # Event handlers
355
- msg.submit(
356
- respond_and_update,
357
- [msg, chatbot],
358
- [chatbot, msg]
359
- )
360
-
361
- send_btn.click(
362
- respond_and_update,
363
- [msg, chatbot],
364
- [chatbot, msg]
365
- )
366
 
367
  if __name__ == "__main__":
368
- logger.info("Starting EduBot with custom styling...")
369
- demo.launch()
 
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
 
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
 
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
 
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)
 
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(
106
+ message,
107
+ history,
108
+ max_tokens=600,
109
+ temperature=0.7,
110
+ top_p=0.9,
111
  ):
112
+ try:
113
+ template, mode = detect_subject(message)
114
+ chain = template | llm
115
+
116
+ yield f"*{mode}*\n\nGenerating response..."
117
+
118
+ logger.info(f"Processing {mode} query: {message[:50]}...")
119
+
120
+ response = chain.invoke({
121
+ "question": message,
122
+ "system_message": "You are EduBot, an expert AI learning assistant. Provide comprehensive, educational responses that help students truly understand concepts."
123
+ })
124
+
125
+ response = smart_truncate(response, max_length=3000)
126
+
127
+ words = response.split()
128
+ partial_response = f"*{mode}*\n\n"
129
+
130
+ for i, word in enumerate(words):
131
+ partial_response += word + " "
132
+
133
+ if i % 4 == 0:
134
+ yield partial_response
135
+ time.sleep(0.03)
136
+
137
+ final_response = f"*{mode}*\n\n{response}"
138
+ logger.info(f"Response completed. Length: {len(response)} characters")
139
+ yield final_response
140
+
141
+ except Exception as e:
142
+ logger.exception("Error in LangChain response generation")
143
+ yield f"Sorry, I encountered an error: {str(e)[:150]}"
 
 
 
 
 
 
 
 
 
 
 
 
144
 
 
145
  theme = gr.themes.Glass(
146
+ primary_hue="amber",
147
+ text_size="md",
148
+ radius_size="md",
149
  ).set(
150
+ shadow_drop='*shadow_drop_lg',
151
+ shadow_drop_lg='*shadow_drop',
152
+ shadow_spread='*shadow_drop_lg',
153
+ block_info_text_weight='500',
154
+ button_border_width='*block_border_width'
155
  )
156
 
 
157
  with gr.Blocks(theme=theme, css="""
158
+ .main-container {
159
+ max-width: 900px;
160
+ margin: 0 auto;
161
+ padding: 1rem;
162
+ height: 100vh;
163
+ display: flex;
164
+ flex-direction: column;
165
+ }
166
+ .title {
167
+ text-align: center;
168
+ font-size: clamp(1.8rem, 4vw, 2.5rem);
169
+ font-weight: bold;
170
+ color: #d97706;
171
+ margin-bottom: 1rem;
172
+ flex-shrink: 0;
173
+ }
174
+ .chat-container {
175
+ flex: 1;
176
+ display: flex;
177
+ flex-direction: column;
178
+ min-height: 0;
179
+ margin-bottom: 1rem;
180
+ }
181
+ .gradio-chatbot {
182
+ flex: 1 !important;
183
+ height: auto !important;
184
+ min-height: 400px;
185
+ max-height: calc(100vh - 200px);
186
+ }
187
+
188
+ .chat-bot .message-wrap .avatar-container {
189
+ display: none !important;
190
+ }
191
+ .gradio-chatbot .message-wrap .avatar-container {
192
+ display: none !important;
193
+ }
194
+ .gradio-chatbot .message.bot .avatar-container,
195
+ .gradio-chatbot .message.user .avatar-container {
196
+ display: none !important;
197
+ }
198
+
199
+ .input-row {
200
+ flex-shrink: 0;
201
+ margin-top: 0.5rem;
202
+ display: flex;
203
+ justify-content: center;
204
+ align-items: center;
205
+ gap: 10px;
206
+ max-width: 700px;
207
+ margin-left: auto;
208
+ margin-right: auto;
209
+ }
210
+
211
+ .custom-textbox {
212
+ min-width: 500px !important;
213
+ width: 100% !important;
214
+ }
215
+
216
+ .custom-textbox input {
217
+ border-radius: 25px !important;
218
+ border: 2px solid #64748b !important;
219
+ padding: 15px 20px !important;
220
+ font-size: 16px !important;
221
+ background: white !important;
222
+ outline: none !important;
223
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1) !important;
224
+ transition: all 0.3s ease !important;
225
+ min-width: 500px !important;
226
+ min-height: 50px !important;
227
+ height: 50px !important;
228
+ }
229
+
230
+ .custom-textbox input:focus {
231
+ border-color: #475569 !important;
232
+ box-shadow: 0 0 0 3px rgba(100, 116, 139, 0.1) !important;
233
+ }
234
+
235
+ .custom-textbox label {
236
+ display: none !important;
237
+ }
238
+
239
+ .send-button {
240
+ border-radius: 50% !important;
241
+ width: 50px !important;
242
+ height: 50px !important;
243
+ display: flex !important;
244
+ align-items: center !important;
245
+ justify-content: center !important;
246
+ flex-shrink: 0 !important;
247
+ }
248
+
249
+ @media (max-width: 768px) {
250
+ .main-container {
251
+ padding: 0.5rem;
252
+ }
253
+ .title {
254
+ font-size: 1.5rem;
255
+ margin-bottom: 0.5rem;
256
+ }
257
+ .gradio-chatbot {
258
+ min-height: 300px;
259
+ max-height: calc(100vh - 150px);
260
+ }
261
+ .input-row {
262
+ margin-top: 0.25rem;
263
+ max-width: 100%;
264
+ padding: 0 0.5rem;
265
+ }
266
+ .custom-textbox {
267
+ min-width: 300px !important;
268
+ }
269
+ .custom-textbox input {
270
+ padding: 12px 15px !important;
271
+ font-size: 14px !important;
272
+ min-width: 300px !important;
273
+ min-height: 45px !important;
274
+ height: 45px !important;
275
+ }
276
+ }
277
+
278
+ @media (min-width: 769px) and (max-width: 1024px) {
279
+ .gradio-chatbot {
280
+ min-height: 450px;
281
+ max-height: calc(100vh - 180px);
282
+ }
283
+ }
284
+
285
+ @media (min-width: 1025px) {
286
+ .gradio-chatbot {
287
+ min-height: 500px;
288
+ max-height: calc(100vh - 200px);
289
+ }
290
+ }
291
+
292
+ @media (max-height: 500px) and (orientation: landscape) {
293
+ .title {
294
+ font-size: 1.2rem;
295
+ margin-bottom: 0.25rem;
296
+ }
297
+ .gradio-chatbot {
298
+ min-height: 200px;
299
+ max-height: calc(100vh - 100px);
300
+ }
301
+ }
302
  """) as demo:
303
+
304
+ with gr.Column(elem_classes=["main-container"]):
305
+ gr.HTML("""
306
+ <div class='title'>🎓 EduBot</div>
307
+ """)
308
+
309
+ with gr.Column(elem_classes=["chat-container"]):
310
+ chatbot = gr.Chatbot(
311
+ show_copy_button=True,
312
+ avatar_images=[None, None],
313
+ placeholder="Hi! I'm EduBot. What would you like to learn today? 📚",
314
+ container=True,
315
+ elem_classes=["gradio-chatbot"]
316
+ )
317
+
318
+ with gr.Row(elem_classes=["input-row"]):
319
+ msg = gr.Textbox(
320
+ placeholder="Ask me about math, research, study strategies, or any educational topic...",
321
+ container=False,
322
+ show_label=False,
323
+ scale=8,
324
+ elem_classes=["custom-textbox"]
325
+ )
326
+ send_btn = gr.Button("📤", variant="primary", scale=1, elem_classes=["send-button"])
327
+
328
+ def respond_and_update(message, history):
329
+ for response in respond_with_enhanced_streaming(message, history):
330
+ history.append([message, response])
331
+ yield history, ""
332
+
333
+ msg.submit(
334
+ respond_and_update,
335
+ [msg, chatbot],
336
+ [chatbot, msg]
337
+ )
338
+
339
+ send_btn.click(
340
+ respond_and_update,
341
+ [msg, chatbot],
342
+ [chatbot, msg]
343
+ )
 
 
 
 
 
344
 
345
  if __name__ == "__main__":
346
+ logger.info("Starting EduBot with custom styling...")
347
+ demo.launch()