Spaces:
Sleeping
Sleeping
UI Overhaul
Browse filesSelected a new font and refined the color palette. All components were moved to one Gradio block and organized using Gradio rows and columns.
app.py
CHANGED
|
@@ -25,22 +25,17 @@ client = InferenceClient(
|
|
| 25 |
|
| 26 |
metrics_tracker = EduBotMetrics(save_file="edu_metrics.json")
|
| 27 |
|
|
|
|
| 28 |
math_template = ChatPromptTemplate.from_messages([
|
| 29 |
("system", """{system_message}
|
| 30 |
Math Mode
|
| 31 |
-
|
| 32 |
LaTeX formatting is enabled for math. You must provide LaTeX formatting for all math, either as inline LaTeX or centered display LaTeX.
|
| 33 |
-
|
| 34 |
You will address requests to solve, aid in understanding, or explore mathematical context with minimal text content. Use a logical ordering fro content, providing necessary terms and definitions as well as concept explanations along with math to foster an understanding of core concepts. Rather than specifically answering the math problem provided, you will begin with solving a similar problem that requires the same steps and foundational mathematical knowledge, then prompt the user to work through the problem themselves. If the user insists you solve the problem, you should engage in a two-way conversation where you provide the steps but request the user to solve for the answer one step at a time. Prioritize guidance and learning over directly feeding the user answers.
|
| 35 |
-
|
| 36 |
LaTeC should always be used for math.
|
| 37 |
LaTeX Examples:
|
| 38 |
- Inline: "The slope is $m = \\frac{{y_2 - y_1}}{{x_2 - x_1}}$ in this case."
|
| 39 |
- Display: "The quadratic formula is: $$x = \\frac{{-b \\pm \\sqrt{{b^2-4ac}}}}{{2a}}$$"
|
| 40 |
-
|
| 41 |
Always use double backslashes (\\\\) for LaTeX commands like \\\\frac, \\\\sqrt, \\\\int, etc.
|
| 42 |
-
|
| 43 |
-
|
| 44 |
Be concise and direct with an overall friendly and engaging tone. Use minimal formatting, with markdown bolding reserved for **key terms** only."""),
|
| 45 |
("human", "{question}")
|
| 46 |
])
|
|
@@ -48,9 +43,7 @@ Be concise and direct with an overall friendly and engaging tone. Use minimal fo
|
|
| 48 |
research_template = ChatPromptTemplate.from_messages([
|
| 49 |
("system", """{system_message}
|
| 50 |
Research Mode
|
| 51 |
-
|
| 52 |
Your main goal is to help the user learn to research topics, a critical skill. Function as a partner rather than a search engine.
|
| 53 |
-
|
| 54 |
Over the course of the conversation, guide the user through a seven-step research process:
|
| 55 |
1) **Identifying a topic**
|
| 56 |
2) **Finding background information**
|
|
@@ -59,35 +52,23 @@ Over the course of the conversation, guide the user through a seven-step researc
|
|
| 59 |
5) **Analyzing data**
|
| 60 |
6) **Drawing conclusions**
|
| 61 |
7) **Disseminating findings**
|
| 62 |
-
|
| 63 |
You may also provide formatted citations if the user asks for them and provides the needed information. If not all information is provided but citations are requested, follow up with guidance on how to obtain the information to generate a citation. By default, you will not provide citations.
|
| 64 |
-
|
| 65 |
Exampel citations:
|
| 66 |
APA Style
|
| 67 |
-
|
| 68 |
In-text: (Smith, 2023, p. 45)
|
| 69 |
Reference: Smith, J. A. (2023). Book title. Publisher.
|
| 70 |
-
|
| 71 |
MLA Style
|
| 72 |
-
|
| 73 |
In-text: (Smith 45)
|
| 74 |
Works Cited: Smith, John A. Book Title. Publisher, 2023.
|
| 75 |
-
|
| 76 |
Chicago Style
|
| 77 |
-
|
| 78 |
Footnote: ¹John A. Smith, Book Title (Publisher, 2023), 45.
|
| 79 |
Bibliography: Smith, John A. Book Title. Publisher, 2023.
|
| 80 |
-
|
| 81 |
Harvard Style
|
| 82 |
-
|
| 83 |
In-text: (Smith 2023, p. 45)
|
| 84 |
Reference: Smith, J.A. (2023) Book title. Publisher.
|
| 85 |
-
|
| 86 |
IEEE Style
|
| 87 |
-
|
| 88 |
In-text: [1]
|
| 89 |
Reference: [1] J. A. Smith, Book Title. Publisher, 2023.
|
| 90 |
-
|
| 91 |
Be concise and direct with an overall friendly and engaging tone. Use minimal formatting, with markdown bolding reserved for **key terms** only. In this mode you may not use LaTeX formatting."""),
|
| 92 |
("human", "{question}")
|
| 93 |
])
|
|
@@ -95,18 +76,12 @@ Be concise and direct with an overall friendly and engaging tone. Use minimal fo
|
|
| 95 |
study_template = ChatPromptTemplate.from_messages([
|
| 96 |
("system", """{system_message}
|
| 97 |
Study Mode
|
| 98 |
-
|
| 99 |
Engage the user in a mix of two teaching styles: student-centered and inquiry-based learning.
|
| 100 |
-
|
| 101 |
Student Centered: Adjust to reflect the student's reading level and level of understanding of a topic as the conversation progresses. Do not assume the user is an expert but instead assume they may have familiarity but desire to learn more about the topic they are studying. Provide definitions for terms you use in a conversational way, gradually shifting to using just the terms without definitions as the user becomes more familiar with them.
|
| 102 |
-
|
| 103 |
Inquiry-based learning: Engage the user through questions that compel them to consider what they want to know and then explore the topics through guided conversation.
|
| 104 |
-
|
| 105 |
Over the course of the conversation, prompt the user with a question to gauge their growing knowledge or progress on the topic.
|
| 106 |
-
|
| 107 |
For example:
|
| 108 |
After two to three turns of conversation discussing a topic, pick a specific term or concept from the conversation history to craft either a multiple-choice or written answer question for the user with no other comments along with it. If the student is correct, congratulate them on their progress and inquire about their next learning goal on the topic. If the user fails the question, return with a short response that explains the correct answer in a kind tone.
|
| 109 |
-
|
| 110 |
Be concise and direct with an overall friendly and engaging tone. Use minimal formatting, with markdown bolding reserved for **key terms** only. In this mode you may not use LaTeX formatting."""),
|
| 111 |
("human", "{question}")
|
| 112 |
])
|
|
@@ -114,9 +89,7 @@ Be concise and direct with an overall friendly and engaging tone. Use minimal fo
|
|
| 114 |
general_template = ChatPromptTemplate.from_messages([
|
| 115 |
("system", """{system_message}
|
| 116 |
General Mode
|
| 117 |
-
|
| 118 |
You are EduBot, a comprehensive AI learning assistant. Help users leverage educational tools and resources to enrich their education. Offer yourself as a resource for the student, prompting them to request help with **math topics**, **research strategy**, or **studying a topic**.
|
| 119 |
-
|
| 120 |
Be concise and direct with an overall friendly and engaging tone. Use minimal formatting, with markdown bolding reserved for **key terms** only."""),
|
| 121 |
("human", "{question}")
|
| 122 |
])
|
|
@@ -233,7 +206,6 @@ def smart_truncate(text, max_length=3000):
|
|
| 233 |
words = text[:max_length].split()
|
| 234 |
return ' '.join(words[:-1]) + "... [Response truncated - ask for continuation]"
|
| 235 |
|
| 236 |
-
|
| 237 |
def respond_with_enhanced_streaming(message, history):
|
| 238 |
"""Streams the bot's response, detecting the subject and handling errors."""
|
| 239 |
|
|
@@ -336,68 +308,151 @@ def respond_with_enhanced_streaming(message, history):
|
|
| 336 |
error_message=error_message
|
| 337 |
)
|
| 338 |
|
| 339 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
| 340 |
custom_css = """
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 341 |
/* Main container styling */
|
| 342 |
.gradio-container {
|
| 343 |
background-color: rgb(240, 236, 230) !important;
|
| 344 |
-
font-family:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 345 |
}
|
| 346 |
|
| 347 |
/* Title styling */
|
| 348 |
.title-header {
|
| 349 |
background-color: rgb(240, 236, 230);
|
| 350 |
padding: 20px;
|
| 351 |
-
border-bottom:
|
| 352 |
text-align: left;
|
| 353 |
}
|
| 354 |
-
|
| 355 |
.title-header h1 {
|
| 356 |
font-size: 1.8rem;
|
| 357 |
-
font-weight:
|
| 358 |
-
color:
|
| 359 |
margin: 0;
|
| 360 |
max-height: 80;
|
|
|
|
| 361 |
}
|
| 362 |
|
| 363 |
/* Chat container */
|
| 364 |
.chat-container {
|
| 365 |
min-height: 900px;
|
| 366 |
-
background-color:
|
|
|
|
|
|
|
|
|
|
| 367 |
}
|
| 368 |
|
| 369 |
/* Chatbot styling */
|
| 370 |
.gradio-chatbot {
|
| 371 |
-
background-color:
|
| 372 |
-
border:
|
|
|
|
| 373 |
padding: 20px !important;
|
|
|
|
| 374 |
}
|
| 375 |
|
| 376 |
/* Message styling */
|
| 377 |
.gradio-chatbot .message.bot .markdown {
|
| 378 |
background-color: rgb(240, 185, 103) !important;
|
| 379 |
-
color:
|
| 380 |
border-radius: 18px !important;
|
| 381 |
padding: 12px 16px !important;
|
| 382 |
box-shadow: 0 1px 2px rgba(0,0,0,0.05) !important;
|
| 383 |
-
border:
|
| 384 |
max-width: 70%;
|
| 385 |
margin-left: 0;
|
| 386 |
margin-right: auto;
|
| 387 |
word-wrap: break-word;
|
|
|
|
|
|
|
| 388 |
}
|
| 389 |
|
| 390 |
.gradio-chatbot .message.user .markdown {
|
| 391 |
background-color: rgb(242, 238, 233) !important;
|
| 392 |
-
color:
|
| 393 |
border-radius: 18px !important;
|
| 394 |
padding: 12px 16px !important;
|
| 395 |
box-shadow: 0 1px 2px rgba(0,0,0,0.05) !important;
|
| 396 |
-
border:
|
| 397 |
max-width: 70%;
|
| 398 |
margin-left: auto;
|
| 399 |
margin-right: 0;
|
| 400 |
word-wrap: break-word;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 401 |
}
|
| 402 |
|
| 403 |
/* Hide avatars */
|
|
@@ -408,135 +463,186 @@ custom_css = """
|
|
| 408 |
/* Input section styling */
|
| 409 |
.input-section {
|
| 410 |
background-color: rgb(240, 236, 230);
|
| 411 |
-
border-top:
|
| 412 |
padding: 20px;
|
| 413 |
}
|
| 414 |
|
| 415 |
-
/* Button styling */
|
| 416 |
-
.clear-button
|
| 417 |
-
background-color:
|
| 418 |
-
color:
|
| 419 |
-
border:
|
| 420 |
border-radius: 10px !important;
|
| 421 |
padding: 8px 16px !important;
|
| 422 |
cursor: pointer !important;
|
| 423 |
margin: 5px !important;
|
|
|
|
|
|
|
|
|
|
| 424 |
}
|
| 425 |
|
| 426 |
-
.clear-button:hover
|
| 427 |
-
background-color: rgba(
|
| 428 |
}
|
| 429 |
|
| 430 |
.send-button {
|
| 431 |
-
background-color:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 432 |
}
|
| 433 |
|
| 434 |
.send-button:hover {
|
| 435 |
-
background-color: rgba(
|
| 436 |
}
|
| 437 |
|
| 438 |
-
/* Textbox styling
|
| 439 |
.input-textbox {
|
| 440 |
-
background-color:
|
| 441 |
-
border:
|
| 442 |
border-radius: 20px !important;
|
| 443 |
}
|
| 444 |
|
| 445 |
.input-textbox textarea {
|
| 446 |
-
background-color:
|
| 447 |
border: none !important;
|
| 448 |
-
color:
|
| 449 |
padding: 15px !important;
|
| 450 |
font-size: 16px !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 451 |
}
|
| 452 |
"""
|
| 453 |
|
| 454 |
-
#
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
|
| 476 |
-
|
| 477 |
-
|
| 478 |
-
|
| 479 |
-
|
| 480 |
-
|
| 481 |
-
|
| 482 |
-
|
| 483 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 484 |
|
| 485 |
-
#
|
| 486 |
-
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 494 |
|
| 495 |
-
|
| 496 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 497 |
with gr.Row():
|
| 498 |
-
|
| 499 |
-
send = gr.Button("Send", elem_classes=["send-button"])
|
| 500 |
-
msg = gr.Textbox(
|
| 501 |
-
placeholder="Ask me about math, research, study strategies, or any educational topic...",
|
| 502 |
-
show_label=False,
|
| 503 |
-
lines=3,
|
| 504 |
-
max_lines=8,
|
| 505 |
-
elem_classes=["input-textbox"]
|
| 506 |
-
)
|
| 507 |
-
|
| 508 |
-
def respond_and_update(message, history):
|
| 509 |
-
"""Main function to handle user submission."""
|
| 510 |
-
if not message.strip():
|
| 511 |
-
return history, ""
|
| 512 |
|
| 513 |
-
#
|
| 514 |
-
|
| 515 |
-
|
| 516 |
-
|
| 517 |
-
|
| 518 |
-
|
| 519 |
-
|
| 520 |
-
|
| 521 |
-
|
| 522 |
-
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 539 |
|
| 540 |
if __name__ == "__main__":
|
| 541 |
logger.info("Starting EduBot...")
|
|
|
|
| 542 |
demo.launch(debug=True, share=True)
|
|
|
|
| 25 |
|
| 26 |
metrics_tracker = EduBotMetrics(save_file="edu_metrics.json")
|
| 27 |
|
| 28 |
+
# --- LLM Templates ---
|
| 29 |
math_template = ChatPromptTemplate.from_messages([
|
| 30 |
("system", """{system_message}
|
| 31 |
Math Mode
|
|
|
|
| 32 |
LaTeX formatting is enabled for math. You must provide LaTeX formatting for all math, either as inline LaTeX or centered display LaTeX.
|
|
|
|
| 33 |
You will address requests to solve, aid in understanding, or explore mathematical context with minimal text content. Use a logical ordering fro content, providing necessary terms and definitions as well as concept explanations along with math to foster an understanding of core concepts. Rather than specifically answering the math problem provided, you will begin with solving a similar problem that requires the same steps and foundational mathematical knowledge, then prompt the user to work through the problem themselves. If the user insists you solve the problem, you should engage in a two-way conversation where you provide the steps but request the user to solve for the answer one step at a time. Prioritize guidance and learning over directly feeding the user answers.
|
|
|
|
| 34 |
LaTeC should always be used for math.
|
| 35 |
LaTeX Examples:
|
| 36 |
- Inline: "The slope is $m = \\frac{{y_2 - y_1}}{{x_2 - x_1}}$ in this case."
|
| 37 |
- Display: "The quadratic formula is: $$x = \\frac{{-b \\pm \\sqrt{{b^2-4ac}}}}{{2a}}$$"
|
|
|
|
| 38 |
Always use double backslashes (\\\\) for LaTeX commands like \\\\frac, \\\\sqrt, \\\\int, etc.
|
|
|
|
|
|
|
| 39 |
Be concise and direct with an overall friendly and engaging tone. Use minimal formatting, with markdown bolding reserved for **key terms** only."""),
|
| 40 |
("human", "{question}")
|
| 41 |
])
|
|
|
|
| 43 |
research_template = ChatPromptTemplate.from_messages([
|
| 44 |
("system", """{system_message}
|
| 45 |
Research Mode
|
|
|
|
| 46 |
Your main goal is to help the user learn to research topics, a critical skill. Function as a partner rather than a search engine.
|
|
|
|
| 47 |
Over the course of the conversation, guide the user through a seven-step research process:
|
| 48 |
1) **Identifying a topic**
|
| 49 |
2) **Finding background information**
|
|
|
|
| 52 |
5) **Analyzing data**
|
| 53 |
6) **Drawing conclusions**
|
| 54 |
7) **Disseminating findings**
|
|
|
|
| 55 |
You may also provide formatted citations if the user asks for them and provides the needed information. If not all information is provided but citations are requested, follow up with guidance on how to obtain the information to generate a citation. By default, you will not provide citations.
|
|
|
|
| 56 |
Exampel citations:
|
| 57 |
APA Style
|
|
|
|
| 58 |
In-text: (Smith, 2023, p. 45)
|
| 59 |
Reference: Smith, J. A. (2023). Book title. Publisher.
|
|
|
|
| 60 |
MLA Style
|
|
|
|
| 61 |
In-text: (Smith 45)
|
| 62 |
Works Cited: Smith, John A. Book Title. Publisher, 2023.
|
|
|
|
| 63 |
Chicago Style
|
|
|
|
| 64 |
Footnote: ¹John A. Smith, Book Title (Publisher, 2023), 45.
|
| 65 |
Bibliography: Smith, John A. Book Title. Publisher, 2023.
|
|
|
|
| 66 |
Harvard Style
|
|
|
|
| 67 |
In-text: (Smith 2023, p. 45)
|
| 68 |
Reference: Smith, J.A. (2023) Book title. Publisher.
|
|
|
|
| 69 |
IEEE Style
|
|
|
|
| 70 |
In-text: [1]
|
| 71 |
Reference: [1] J. A. Smith, Book Title. Publisher, 2023.
|
|
|
|
| 72 |
Be concise and direct with an overall friendly and engaging tone. Use minimal formatting, with markdown bolding reserved for **key terms** only. In this mode you may not use LaTeX formatting."""),
|
| 73 |
("human", "{question}")
|
| 74 |
])
|
|
|
|
| 76 |
study_template = ChatPromptTemplate.from_messages([
|
| 77 |
("system", """{system_message}
|
| 78 |
Study Mode
|
|
|
|
| 79 |
Engage the user in a mix of two teaching styles: student-centered and inquiry-based learning.
|
|
|
|
| 80 |
Student Centered: Adjust to reflect the student's reading level and level of understanding of a topic as the conversation progresses. Do not assume the user is an expert but instead assume they may have familiarity but desire to learn more about the topic they are studying. Provide definitions for terms you use in a conversational way, gradually shifting to using just the terms without definitions as the user becomes more familiar with them.
|
|
|
|
| 81 |
Inquiry-based learning: Engage the user through questions that compel them to consider what they want to know and then explore the topics through guided conversation.
|
|
|
|
| 82 |
Over the course of the conversation, prompt the user with a question to gauge their growing knowledge or progress on the topic.
|
|
|
|
| 83 |
For example:
|
| 84 |
After two to three turns of conversation discussing a topic, pick a specific term or concept from the conversation history to craft either a multiple-choice or written answer question for the user with no other comments along with it. If the student is correct, congratulate them on their progress and inquire about their next learning goal on the topic. If the user fails the question, return with a short response that explains the correct answer in a kind tone.
|
|
|
|
| 85 |
Be concise and direct with an overall friendly and engaging tone. Use minimal formatting, with markdown bolding reserved for **key terms** only. In this mode you may not use LaTeX formatting."""),
|
| 86 |
("human", "{question}")
|
| 87 |
])
|
|
|
|
| 89 |
general_template = ChatPromptTemplate.from_messages([
|
| 90 |
("system", """{system_message}
|
| 91 |
General Mode
|
|
|
|
| 92 |
You are EduBot, a comprehensive AI learning assistant. Help users leverage educational tools and resources to enrich their education. Offer yourself as a resource for the student, prompting them to request help with **math topics**, **research strategy**, or **studying a topic**.
|
|
|
|
| 93 |
Be concise and direct with an overall friendly and engaging tone. Use minimal formatting, with markdown bolding reserved for **key terms** only."""),
|
| 94 |
("human", "{question}")
|
| 95 |
])
|
|
|
|
| 206 |
words = text[:max_length].split()
|
| 207 |
return ' '.join(words[:-1]) + "... [Response truncated - ask for continuation]"
|
| 208 |
|
|
|
|
| 209 |
def respond_with_enhanced_streaming(message, history):
|
| 210 |
"""Streams the bot's response, detecting the subject and handling errors."""
|
| 211 |
|
|
|
|
| 308 |
error_message=error_message
|
| 309 |
)
|
| 310 |
|
| 311 |
+
# ===============================================================================
|
| 312 |
+
# UI CONFIGURATION SECTION - ALL UI RELATED CODE CENTRALIZED HERE
|
| 313 |
+
# ===============================================================================
|
| 314 |
+
|
| 315 |
+
# --- UI: Custom CSS Styles ---
|
| 316 |
custom_css = """
|
| 317 |
+
/* Import Oswald font - Google Fonts */
|
| 318 |
+
@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@200..700&display=swap');
|
| 319 |
+
|
| 320 |
+
/* Oswald font classes */
|
| 321 |
+
.oswald-light {
|
| 322 |
+
font-family: "Oswald", sans-serif;
|
| 323 |
+
font-optical-sizing: auto;
|
| 324 |
+
font-weight: 300;
|
| 325 |
+
font-style: normal;
|
| 326 |
+
}
|
| 327 |
+
.oswald-regular {
|
| 328 |
+
font-family: "Oswald", sans-serif;
|
| 329 |
+
font-optical-sizing: auto;
|
| 330 |
+
font-weight: 400;
|
| 331 |
+
font-style: normal;
|
| 332 |
+
}
|
| 333 |
+
.oswald-medium {
|
| 334 |
+
font-family: "Oswald", sans-serif;
|
| 335 |
+
font-optical-sizing: auto;
|
| 336 |
+
font-weight: 500;
|
| 337 |
+
font-style: normal;
|
| 338 |
+
}
|
| 339 |
+
.oswald-semibold {
|
| 340 |
+
font-family: "Oswald", sans-serif;
|
| 341 |
+
font-optical-sizing: auto;
|
| 342 |
+
font-weight: 600;
|
| 343 |
+
font-style: normal;
|
| 344 |
+
}
|
| 345 |
+
.oswald-bold {
|
| 346 |
+
font-family: "Oswald", sans-serif;
|
| 347 |
+
font-optical-sizing: auto;
|
| 348 |
+
font-weight: 700;
|
| 349 |
+
font-style: normal;
|
| 350 |
+
}
|
| 351 |
+
|
| 352 |
/* Main container styling */
|
| 353 |
.gradio-container {
|
| 354 |
background-color: rgb(240, 236, 230) !important;
|
| 355 |
+
font-family: "Oswald", sans-serif !important;
|
| 356 |
+
font-optical-sizing: auto !important;
|
| 357 |
+
font-weight: 400 !important;
|
| 358 |
+
font-style: normal !important;
|
| 359 |
+
color: #120f0e !important;
|
| 360 |
+
}
|
| 361 |
+
|
| 362 |
+
/* Apply Oswald to all text elements */
|
| 363 |
+
*, *::before, *::after {
|
| 364 |
+
font-family: "Oswald", sans-serif !important;
|
| 365 |
+
font-optical-sizing: auto !important;
|
| 366 |
+
color: #120f0e !important;
|
| 367 |
}
|
| 368 |
|
| 369 |
/* Title styling */
|
| 370 |
.title-header {
|
| 371 |
background-color: rgb(240, 236, 230);
|
| 372 |
padding: 20px;
|
| 373 |
+
border-bottom: 2pt solid #59524f;
|
| 374 |
text-align: left;
|
| 375 |
}
|
|
|
|
| 376 |
.title-header h1 {
|
| 377 |
font-size: 1.8rem;
|
| 378 |
+
font-weight: 600 !important;
|
| 379 |
+
color: #120f0e !important;
|
| 380 |
margin: 0;
|
| 381 |
max-height: 80;
|
| 382 |
+
font-family: "Oswald", sans-serif !important;
|
| 383 |
}
|
| 384 |
|
| 385 |
/* Chat container */
|
| 386 |
.chat-container {
|
| 387 |
min-height: 900px;
|
| 388 |
+
background-color: #d9d1ce !important;
|
| 389 |
+
border: 2pt solid #59524f !important;
|
| 390 |
+
border-radius: 10px;
|
| 391 |
+
padding: 20px;
|
| 392 |
}
|
| 393 |
|
| 394 |
/* Chatbot styling */
|
| 395 |
.gradio-chatbot {
|
| 396 |
+
background-color: #d9d1ce !important;
|
| 397 |
+
border: 2pt solid #59524f !important;
|
| 398 |
+
border-radius: 10px !important;
|
| 399 |
padding: 20px !important;
|
| 400 |
+
font-family: "Oswald", sans-serif !important;
|
| 401 |
}
|
| 402 |
|
| 403 |
/* Message styling */
|
| 404 |
.gradio-chatbot .message.bot .markdown {
|
| 405 |
background-color: rgb(240, 185, 103) !important;
|
| 406 |
+
color: #120f0e !important;
|
| 407 |
border-radius: 18px !important;
|
| 408 |
padding: 12px 16px !important;
|
| 409 |
box-shadow: 0 1px 2px rgba(0,0,0,0.05) !important;
|
| 410 |
+
border: 2pt solid #59524f !important;
|
| 411 |
max-width: 70%;
|
| 412 |
margin-left: 0;
|
| 413 |
margin-right: auto;
|
| 414 |
word-wrap: break-word;
|
| 415 |
+
font-family: "Oswald", sans-serif !important;
|
| 416 |
+
font-weight: 400 !important;
|
| 417 |
}
|
| 418 |
|
| 419 |
.gradio-chatbot .message.user .markdown {
|
| 420 |
background-color: rgb(242, 238, 233) !important;
|
| 421 |
+
color: #120f0e !important;
|
| 422 |
border-radius: 18px !important;
|
| 423 |
padding: 12px 16px !important;
|
| 424 |
box-shadow: 0 1px 2px rgba(0,0,0,0.05) !important;
|
| 425 |
+
border: 2pt solid #59524f !important;
|
| 426 |
max-width: 70%;
|
| 427 |
margin-left: auto;
|
| 428 |
margin-right: 0;
|
| 429 |
word-wrap: break-word;
|
| 430 |
+
font-family: "Oswald", sans-serif !important;
|
| 431 |
+
font-weight: 400 !important;
|
| 432 |
+
}
|
| 433 |
+
|
| 434 |
+
/* Apply Oswald to all markdown content */
|
| 435 |
+
.gradio-chatbot .markdown p,
|
| 436 |
+
.gradio-chatbot .markdown h1,
|
| 437 |
+
.gradio-chatbot .markdown h2,
|
| 438 |
+
.gradio-chatbot .markdown h3,
|
| 439 |
+
.gradio-chatbot .markdown h4,
|
| 440 |
+
.gradio-chatbot .markdown h5,
|
| 441 |
+
.gradio-chatbot .markdown h6,
|
| 442 |
+
.gradio-chatbot .markdown ul,
|
| 443 |
+
.gradio-chatbot .markdown ol,
|
| 444 |
+
.gradio-chatbot .markdown li,
|
| 445 |
+
.gradio-chatbot .markdown strong,
|
| 446 |
+
.gradio-chatbot .markdown em,
|
| 447 |
+
.gradio-chatbot .markdown code {
|
| 448 |
+
font-family: "Oswald", sans-serif !important;
|
| 449 |
+
color: #120f0e !important;
|
| 450 |
+
}
|
| 451 |
+
|
| 452 |
+
/* Mode indicators with Oswald */
|
| 453 |
+
.gradio-chatbot .markdown strong {
|
| 454 |
+
font-weight: 600 !important;
|
| 455 |
+
color: #120f0e !important;
|
| 456 |
}
|
| 457 |
|
| 458 |
/* Hide avatars */
|
|
|
|
| 463 |
/* Input section styling */
|
| 464 |
.input-section {
|
| 465 |
background-color: rgb(240, 236, 230);
|
| 466 |
+
border-top: 2pt solid #59524f;
|
| 467 |
padding: 20px;
|
| 468 |
}
|
| 469 |
|
| 470 |
+
/* Button styling with new colors */
|
| 471 |
+
.clear-button {
|
| 472 |
+
background-color: #ada3a0 !important;
|
| 473 |
+
color: #120f0e !important;
|
| 474 |
+
border: 2pt solid #59524f !important;
|
| 475 |
border-radius: 10px !important;
|
| 476 |
padding: 8px 16px !important;
|
| 477 |
cursor: pointer !important;
|
| 478 |
margin: 5px !important;
|
| 479 |
+
font-family: "Oswald", sans-serif !important;
|
| 480 |
+
font-weight: 500 !important;
|
| 481 |
+
font-optical-sizing: auto !important;
|
| 482 |
}
|
| 483 |
|
| 484 |
+
.clear-button:hover {
|
| 485 |
+
background-color: rgba(173, 163, 160, 0.8) !important;
|
| 486 |
}
|
| 487 |
|
| 488 |
.send-button {
|
| 489 |
+
background-color: #f09c7d !important;
|
| 490 |
+
color: #120f0e !important;
|
| 491 |
+
border: 2pt solid #59524f !important;
|
| 492 |
+
border-radius: 10px !important;
|
| 493 |
+
padding: 8px 16px !important;
|
| 494 |
+
cursor: pointer !important;
|
| 495 |
+
margin: 5px !important;
|
| 496 |
+
font-family: "Oswald", sans-serif !important;
|
| 497 |
+
font-weight: 500 !important;
|
| 498 |
+
font-optical-sizing: auto !important;
|
| 499 |
}
|
| 500 |
|
| 501 |
.send-button:hover {
|
| 502 |
+
background-color: rgba(240, 156, 125, 0.8) !important;
|
| 503 |
}
|
| 504 |
|
| 505 |
+
/* Textbox styling with new colors */
|
| 506 |
.input-textbox {
|
| 507 |
+
background-color: #d9d1ce !important;
|
| 508 |
+
border: 2pt solid #59524f !important;
|
| 509 |
border-radius: 20px !important;
|
| 510 |
}
|
| 511 |
|
| 512 |
.input-textbox textarea {
|
| 513 |
+
background-color: #d9d1ce !important;
|
| 514 |
border: none !important;
|
| 515 |
+
color: #120f0e !important;
|
| 516 |
padding: 15px !important;
|
| 517 |
font-size: 16px !important;
|
| 518 |
+
font-family: "Oswald", sans-serif !important;
|
| 519 |
+
font-weight: 400 !important;
|
| 520 |
+
font-optical-sizing: auto !important;
|
| 521 |
+
}
|
| 522 |
+
|
| 523 |
+
.input-textbox textarea::placeholder {
|
| 524 |
+
font-family: "Oswald", sans-serif !important;
|
| 525 |
+
font-weight: 300 !important;
|
| 526 |
+
color: rgba(18, 15, 14, 0.6) !important;
|
| 527 |
+
}
|
| 528 |
+
|
| 529 |
+
/* Ensure all input elements use Oswald and new colors */
|
| 530 |
+
input, textarea, button, select {
|
| 531 |
+
font-family: "Oswald", sans-serif !important;
|
| 532 |
+
font-optical-sizing: auto !important;
|
| 533 |
+
color: #120f0e !important;
|
| 534 |
}
|
| 535 |
"""
|
| 536 |
|
| 537 |
+
# --- UI: HTML Head Content ---
|
| 538 |
+
html_head_content = '''
|
| 539 |
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 540 |
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 541 |
+
<link href="https://fonts.googleapis.com/css2?family=Oswald:wght@200..700&display=swap" rel="stylesheet">
|
| 542 |
+
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
| 543 |
+
'''
|
| 544 |
+
|
| 545 |
+
# --- UI: MathJax Configuration ---
|
| 546 |
+
mathjax_config = '''
|
| 547 |
+
<script>
|
| 548 |
+
window.MathJax = {
|
| 549 |
+
tex: {
|
| 550 |
+
inlineMath: [['$', '$'], ['\\\\(', '\\\\)']],
|
| 551 |
+
displayMath: [['$$', '$$'], ['\\\\[', '\\\\]']],
|
| 552 |
+
packages: {'[+]': ['ams']}
|
| 553 |
+
},
|
| 554 |
+
svg: {fontCache: 'global'},
|
| 555 |
+
startup: {
|
| 556 |
+
ready: () => {
|
| 557 |
+
MathJax.startup.defaultReady();
|
| 558 |
+
// Re-render math when new content is added
|
| 559 |
+
const observer = new MutationObserver(function(mutations) {
|
| 560 |
+
MathJax.typesetPromise();
|
| 561 |
+
});
|
| 562 |
+
observer.observe(document.body, {childList: true, subtree: true});
|
| 563 |
+
}
|
| 564 |
+
}
|
| 565 |
+
};
|
| 566 |
+
</script>
|
| 567 |
+
'''
|
| 568 |
+
|
| 569 |
+
# --- UI: Event Handlers ---
|
| 570 |
+
def respond_and_update(message, history):
|
| 571 |
+
"""Main function to handle user submission."""
|
| 572 |
+
if not message.strip():
|
| 573 |
+
return history, ""
|
| 574 |
|
| 575 |
+
# Add user message to history
|
| 576 |
+
history.append({"role": "user", "content": message})
|
| 577 |
+
# Yield history to show the user message immediately, and clear the textbox
|
| 578 |
+
yield history, ""
|
| 579 |
+
|
| 580 |
+
# Stream the bot's response
|
| 581 |
+
full_response = ""
|
| 582 |
+
for response_chunk in respond_with_enhanced_streaming(message, history):
|
| 583 |
+
full_response = response_chunk
|
| 584 |
+
# Update the last message (bot's response)
|
| 585 |
+
if len(history) > 0 and history[-1]["role"] == "user":
|
| 586 |
+
history.append({"role": "assistant", "content": full_response})
|
| 587 |
+
else:
|
| 588 |
+
history[-1] = {"role": "assistant", "content": full_response}
|
| 589 |
+
yield history, ""
|
| 590 |
+
|
| 591 |
+
def clear_chat():
|
| 592 |
+
"""Clear the chat history."""
|
| 593 |
+
return [], ""
|
| 594 |
+
|
| 595 |
+
# --- UI: Interface Creation ---
|
| 596 |
+
def create_interface():
|
| 597 |
+
"""Creates and configures the complete Gradio interface."""
|
| 598 |
|
| 599 |
+
with gr.Blocks(css=custom_css, title="EduBot", fill_width=True, fill_height=True) as demo:
|
| 600 |
+
# Add head content and MathJax
|
| 601 |
+
gr.HTML(html_head_content)
|
| 602 |
+
gr.HTML('<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>')
|
| 603 |
+
gr.HTML(mathjax_config)
|
| 604 |
+
|
| 605 |
+
# Row 1: Title Section
|
| 606 |
with gr.Row():
|
| 607 |
+
gr.HTML('<div class="title-header"><h1>🎓 EduBot</h1></div>')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 608 |
|
| 609 |
+
# Row 2: Chat Section
|
| 610 |
+
with gr.Row():
|
| 611 |
+
chatbot = gr.Chatbot(
|
| 612 |
+
type="messages",
|
| 613 |
+
show_copy_button=True,
|
| 614 |
+
show_share_button=False,
|
| 615 |
+
avatar_images=None,
|
| 616 |
+
height=880,
|
| 617 |
+
elem_classes=["chat-container"]
|
| 618 |
+
)
|
| 619 |
+
|
| 620 |
+
# Row 3: Input Section
|
| 621 |
+
with gr.Row(elem_classes=["input-section"]):
|
| 622 |
+
with gr.Column(scale=4):
|
| 623 |
+
msg = gr.Textbox(
|
| 624 |
+
placeholder="Ask me about math, research, study strategies, or any educational topic...",
|
| 625 |
+
show_label=False,
|
| 626 |
+
lines=3,
|
| 627 |
+
max_lines=8,
|
| 628 |
+
elem_classes=["input-textbox"]
|
| 629 |
+
)
|
| 630 |
+
with gr.Column(scale=1):
|
| 631 |
+
send = gr.Button("Send", elem_classes=["send-button"])
|
| 632 |
+
clear = gr.Button("Clear", elem_classes=["clear-button"])
|
| 633 |
+
|
| 634 |
+
# Set up event handlers
|
| 635 |
+
msg.submit(respond_and_update, [msg, chatbot], [chatbot, msg])
|
| 636 |
+
send.click(respond_and_update, [msg, chatbot], [chatbot, msg])
|
| 637 |
+
clear.click(clear_chat, outputs=[chatbot, msg])
|
| 638 |
+
|
| 639 |
+
return demo
|
| 640 |
+
|
| 641 |
+
# ===============================================================================
|
| 642 |
+
# END UI CONFIGURATION SECTION
|
| 643 |
+
# ===============================================================================
|
| 644 |
|
| 645 |
if __name__ == "__main__":
|
| 646 |
logger.info("Starting EduBot...")
|
| 647 |
+
demo = create_interface()
|
| 648 |
demo.launch(debug=True, share=True)
|