Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
CHANGED
|
@@ -98,30 +98,43 @@ class CurriculumChatbot:
|
|
| 98 |
device_map="auto" if torch.cuda.is_available() else None,
|
| 99 |
token=token,
|
| 100 |
# Performance optimizations
|
| 101 |
-
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
|
| 102 |
-
low_cpu_mem_usage=True
|
| 103 |
)
|
| 104 |
self.llm = HuggingFacePipeline(pipeline=pipe)
|
| 105 |
|
| 106 |
# Warm and engaging prompt templates
|
| 107 |
-
qa_template = """You are a friendly and encouraging programming tutor.
|
|
|
|
|
|
|
| 108 |
|
| 109 |
Here's the relevant curriculum content to help answer their question:
|
| 110 |
{filled_context}
|
| 111 |
|
|
|
|
|
|
|
| 112 |
Please provide a warm, encouraging answer that:
|
| 113 |
-
1.
|
| 114 |
-
2.
|
| 115 |
-
3.
|
| 116 |
-
4.
|
| 117 |
-
5.
|
| 118 |
-
6.
|
| 119 |
-
7.
|
| 120 |
-
8.
|
|
|
|
| 121 |
|
| 122 |
-
IMPORTANT:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
|
| 124 |
-
Your response should be educational and helpful, specifically
|
| 125 |
|
| 126 |
self.qa_prompt = PromptTemplate(
|
| 127 |
input_variables=["question", "filled_context"],
|
|
@@ -144,24 +157,41 @@ Please select the most relevant slide (filename.pdf - Page X) that would best he
|
|
| 144 |
self.slide_selection_chain = self.slide_selection_prompt | self.llm
|
| 145 |
|
| 146 |
# Warm and detailed focused QA template
|
| 147 |
-
focused_qa_template = """You are a friendly and encouraging programming tutor.
|
|
|
|
|
|
|
| 148 |
|
| 149 |
Here's the specific curriculum slide content that directly addresses their question:
|
| 150 |
{slide_content}
|
| 151 |
|
|
|
|
|
|
|
| 152 |
Please provide a warm, encouraging answer that:
|
| 153 |
-
1.
|
| 154 |
-
2.
|
| 155 |
-
3.
|
| 156 |
-
4.
|
| 157 |
-
5.
|
| 158 |
-
6.
|
| 159 |
-
7.
|
| 160 |
-
8.
|
|
|
|
| 161 |
|
| 162 |
-
IMPORTANT:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
|
| 164 |
-
Your response should be educational and helpful, specifically
|
| 165 |
|
| 166 |
self.focused_qa_prompt = PromptTemplate(
|
| 167 |
input_variables=["question", "slide_content"],
|
|
@@ -333,37 +363,16 @@ Your response should be educational and helpful, specifically explaining what th
|
|
| 333 |
if answer.startswith("Provide a clear, educational answer based on this slide:"):
|
| 334 |
answer = answer[58:].strip()
|
| 335 |
|
| 336 |
-
#
|
| 337 |
-
if
|
| 338 |
-
answer.lower().startswith("how does that work") or
|
| 339 |
-
"slide content provided" in answer.lower() or
|
| 340 |
-
"provide a clear" in answer.lower() or
|
| 341 |
-
"answer the question based on" in answer.lower() or
|
| 342 |
-
"slide content:" in answer.lower()):
|
| 343 |
-
|
| 344 |
-
# Generate a proper answer using the slide content
|
| 345 |
slide_info = f"π **Slide Reference:** {best_result.metadata['filename']} - Page {best_result.metadata['page_number']}"
|
| 346 |
-
|
| 347 |
-
if "loops" in query.lower():
|
| 348 |
-
answer = f"{slide_info}\n\n**Great question! Let me explain loops based on your curriculum:**\n\n{best_slide_content}\n\n**What are loops for?**\n\nLoops are programming constructs that solve the problem of repetition. As your curriculum explains, instead of writing hundreds of print statements to count from 1 to 100, loops allow you to accomplish the same task with just a few lines of code.\n\n**Key benefits of loops:**\nβ’ **Efficiency**: Reduce repetitive code\nβ’ **Scalability**: Handle large ranges (1 to 1000+) easily\nβ’ **Maintainability**: Easier to modify and debug\n\n**Types of loops:** Your curriculum covers two main types of loops that you'll learn about. Keep exploring - you're doing great! π"
|
| 349 |
-
elif "boolean" in query.lower():
|
| 350 |
-
answer = f"{slide_info}\n\n**Excellent question! Let me explain booleans based on your curriculum:**\n\n{best_slide_content}\n\n**What are booleans?**\n\nBooleans are a fundamental data type in programming that can only have two values: `True` or `False`. Think of them as simple yes/no answers to questions.\n\n**How do they work?**\n\nLooking at your slide, it's teaching you how to categorize statements as either True or False. For example:\nβ’ \"The sun is shining\" - This could be True or False depending on the weather\nβ’ \"I am using a computer\" - This is True when you're programming\nβ’ \"I like pizza\" - This is a personal preference (True or False)\n\n**Why are booleans important?**\n\nBooleans are the foundation of decision-making in programming. They help programs make choices and control the flow of execution. You'll use them in if statements, loops, and many other programming constructs.\n\n**Real-world example:**\n```python\nis_logged_in = True\nhas_permission = False\n\nif is_logged_in and has_permission:\n print(\"Welcome to the system!\")\nelse:\n print(\"Please log in or get permission.\")\n```\n\nKeep exploring booleans - they're essential for building smart programs! π"
|
| 351 |
-
else:
|
| 352 |
-
answer = f"{slide_info}\n\n**Excellent question! Let me explain this concept based on your curriculum:**\n\n{best_slide_content}\n\nThis slide is teaching you important programming concepts. The curriculum content you're studying is building a strong foundation for your programming journey! πͺ\n\n**What this means:** The slide is showing you how programming concepts work in practice. Each element has a specific purpose and helps you understand the bigger picture of programming.\n\n**Why this matters:** Understanding these fundamentals will make you a better programmer. You're learning the building blocks that will help you create amazing programs! π"
|
| 353 |
|
| 354 |
except Exception as e:
|
| 355 |
print(f"Error generating focused answer: {e}")
|
| 356 |
-
#
|
| 357 |
slide_info = f"π **Slide Reference:** {best_result.metadata['filename']} - Page {best_result.metadata['page_number']}"
|
| 358 |
-
|
| 359 |
-
if "loops" in query.lower():
|
| 360 |
-
answer = f"{slide_info}\n\n**Great question! Let me explain loops based on your curriculum:**\n\n{best_slide_content}\n\n**What are loops for?**\n\nLoops are programming constructs that solve the problem of repetition. As your curriculum explains, instead of writing hundreds of print statements to count from 1 to 100, loops allow you to accomplish the same task with just a few lines of code.\n\n**Key benefits of loops:**\nβ’ **Efficiency**: Reduce repetitive code\nβ’ **Scalability**: Handle large ranges (1 to 1000+) easily\nβ’ **Maintainability**: Easier to modify and debug\n\n**Types of loops:** Your curriculum covers two main types of loops that you'll learn about. Keep exploring - you're doing great! π"
|
| 361 |
-
elif "boolean" in query.lower():
|
| 362 |
-
answer = f"{slide_info}\n\n**Excellent question! Let me explain booleans based on your curriculum:**\n\n{best_slide_content}\n\n**What are booleans?**\n\nBooleans are a fundamental data type in programming that can only have two values: `True` or `False`. Think of them as simple yes/no answers to questions.\n\n**How do they work?**\n\nLooking at your slide, it's teaching you how to categorize statements as either True or False. For example:\nβ’ \"The sun is shining\" - This could be True or False depending on the weather\nβ’ \"I am using a computer\" - This is True when you're programming\nβ’ \"I like pizza\" - This is a personal preference (True or False)\n\n**Why are booleans important?**\n\nBooleans are the foundation of decision-making in programming. They help programs make choices and control the flow of execution. You'll use them in if statements, loops, and many other programming constructs.\n\n**Real-world example:**\n```python\nis_logged_in = True\nhas_permission = False\n\nif is_logged_in and has_permission:\n print(\"Welcome to the system!\")\nelse:\n print(\"Please log in or get permission.\")\n```\n\nKeep exploring booleans - they're essential for building smart programs! π"
|
| 363 |
-
elif "function" in query.lower():
|
| 364 |
-
answer = f"{slide_info}\n\n**Excellent question! Let me explain functions based on your curriculum:**\n\n{best_slide_content}\n\n**What are functions?**\n\nFunctions are reusable blocks of code that perform specific tasks. Think of them as mini-programs within your program that you can call whenever you need them.\n\n**Why use functions?**\n\nLooking at your slide, it explains that functions help you:\nβ’ **Reuse code** - Write once, use many times\nβ’ **Stay organized** - Break complex problems into smaller, manageable pieces\nβ’ **Save time** - Don't repeat yourself (DRY principle)\n\n**Real-world example from your slide:**\n\nThe birthday song example is perfect! Instead of writing a new song for each friend, you create one function that can be reused:\n\n```python\ndef sing_birthday_song(friend_name):\n print(f\"Happy Birthday, {friend_name}!\")\n print(\"May all your dreams come true!\")\n\n# Now you can use it for any friend\nsing_birthday_song(\"Bob\")\nsing_birthday_song(\"Alice\")\nsing_birthday_song(\"Charlie\")\n```\n\n**Key benefits:**\nβ’ **Efficiency**: Write once, use everywhere\nβ’ **Maintainability**: Change the song in one place, it updates everywhere\nβ’ **Readability**: Your code is cleaner and easier to understand\n\nKeep exploring functions - they're essential for building organized, efficient programs! π"
|
| 365 |
-
else:
|
| 366 |
-
answer = f"{slide_info}\n\n**Excellent question! Let me explain this concept based on your curriculum:**\n\n{best_slide_content}\n\nThis slide is teaching you important programming concepts. The curriculum content you're studying is building a strong foundation for your programming journey! πͺ\n\n**What this means:** The slide is showing you how programming concepts work in practice. Each element has a specific purpose and helps you understand the bigger picture of programming.\n\n**Why this matters:** Understanding these fundamentals will make you a better programmer. You're learning the building blocks that will help you create amazing programs! π"
|
| 367 |
|
| 368 |
elif self.qa_chain and not self.fast_mode:
|
| 369 |
# Fallback to general LLM if focused chain fails
|
|
@@ -388,11 +397,11 @@ Your response should be educational and helpful, specifically explaining what th
|
|
| 388 |
if answer.startswith("Provide a clear, educational answer explaining the concept:"):
|
| 389 |
answer = answer[58:].strip()
|
| 390 |
|
| 391 |
-
#
|
| 392 |
-
if len(answer.strip()) <
|
| 393 |
if curriculum_relevance_score > 0:
|
| 394 |
slide_info = f"π **Slide Reference:** {best_result.metadata['filename']} - Page {best_result.metadata['page_number']}"
|
| 395 |
-
answer = f"{slide_info}\n\n**
|
| 396 |
else:
|
| 397 |
answer = "I'm sorry, I couldn't generate a proper answer right now. Please try rephrasing your question - sometimes a different way of asking helps! π"
|
| 398 |
|
|
@@ -404,7 +413,7 @@ Your response should be educational and helpful, specifically explaining what th
|
|
| 404 |
print(f"Error generating answer: {e}")
|
| 405 |
if curriculum_relevance_score > 0:
|
| 406 |
slide_info = f"π **Slide Reference:** {best_result.metadata['filename']} - Page {best_result.metadata['page_number']}"
|
| 407 |
-
answer = f"{slide_info}\n\n**
|
| 408 |
else:
|
| 409 |
answer = "I'm sorry, I couldn't generate an answer at the moment. Please try rephrasing your question - sometimes a different approach helps! π"
|
| 410 |
else:
|
|
|
|
| 98 |
device_map="auto" if torch.cuda.is_available() else None,
|
| 99 |
token=token,
|
| 100 |
# Performance optimizations
|
| 101 |
+
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
|
|
|
|
| 102 |
)
|
| 103 |
self.llm = HuggingFacePipeline(pipeline=pipe)
|
| 104 |
|
| 105 |
# Warm and engaging prompt templates
|
| 106 |
+
qa_template = """You are a friendly and encouraging programming tutor.
|
| 107 |
+
|
| 108 |
+
STUDENT'S QUESTION: {question}
|
| 109 |
|
| 110 |
Here's the relevant curriculum content to help answer their question:
|
| 111 |
{filled_context}
|
| 112 |
|
| 113 |
+
CRITICAL: The student is specifically asking about "{question}". Make sure your answer directly addresses this exact question.
|
| 114 |
+
|
| 115 |
Please provide a warm, encouraging answer that:
|
| 116 |
+
1. DIRECTLY ANSWERS the student's specific question: "{question}"
|
| 117 |
+
2. ANALYZES and EXPLAINS the specific curriculum content shown
|
| 118 |
+
3. References the exact examples, code, or concepts from the curriculum
|
| 119 |
+
4. Explains what each part of the curriculum is teaching
|
| 120 |
+
5. Provides step-by-step breakdown of any code examples shown
|
| 121 |
+
6. Explains the "why" behind the concepts, not just the "what"
|
| 122 |
+
7. Makes connections to real-world programming scenarios
|
| 123 |
+
8. Acknowledges the student's curiosity and encourages them
|
| 124 |
+
9. Suggests how they can practice or explore further
|
| 125 |
|
| 126 |
+
IMPORTANT:
|
| 127 |
+
- Answer the EXACT question: "{question}"
|
| 128 |
+
- Focus on explaining the specific content shown in the curriculum, not generic concepts
|
| 129 |
+
- If there's code, explain what it does step by step
|
| 130 |
+
- If there are examples, break them down clearly
|
| 131 |
+
- If there are rules or concepts, explain them with concrete examples
|
| 132 |
+
- Use a conversational, friendly tone like you're explaining to a friend
|
| 133 |
+
- Structure your response with clear sections and bullet points where helpful
|
| 134 |
+
- Include short code examples (3-7 lines) ONLY if they help illustrate the concept clearly
|
| 135 |
+
- Don't force code examples if the concept doesn't need them
|
| 136 |
|
| 137 |
+
Your response should be educational and helpful, specifically answering: "{question}"."""
|
| 138 |
|
| 139 |
self.qa_prompt = PromptTemplate(
|
| 140 |
input_variables=["question", "filled_context"],
|
|
|
|
| 157 |
self.slide_selection_chain = self.slide_selection_prompt | self.llm
|
| 158 |
|
| 159 |
# Warm and detailed focused QA template
|
| 160 |
+
focused_qa_template = """You are a friendly and encouraging programming tutor.
|
| 161 |
+
|
| 162 |
+
STUDENT'S QUESTION: {question}
|
| 163 |
|
| 164 |
Here's the specific curriculum slide content that directly addresses their question:
|
| 165 |
{slide_content}
|
| 166 |
|
| 167 |
+
CRITICAL: The student is specifically asking about "{question}". Make sure your answer directly addresses this exact question.
|
| 168 |
+
|
| 169 |
Please provide a warm, encouraging answer that:
|
| 170 |
+
1. DIRECTLY ANSWERS the student's specific question: "{question}"
|
| 171 |
+
2. ANALYZES and EXPLAINS the specific content shown in the slide
|
| 172 |
+
3. References the exact examples, code, or concepts displayed
|
| 173 |
+
4. Explains what each part of the slide is teaching
|
| 174 |
+
5. Provides step-by-step breakdown of any code examples shown
|
| 175 |
+
6. Explains the "why" behind the concepts, not just the "what"
|
| 176 |
+
7. Makes connections to real-world programming scenarios
|
| 177 |
+
8. Acknowledges the student's curiosity and encourages them
|
| 178 |
+
9. Suggests how they can practice or explore further
|
| 179 |
|
| 180 |
+
IMPORTANT:
|
| 181 |
+
- Answer the EXACT question: "{question}"
|
| 182 |
+
- If they ask about "for loops", explain for loops specifically, not loops in general
|
| 183 |
+
- If they ask about "while loops", explain while loops specifically
|
| 184 |
+
- If they ask about "variables", explain variables specifically
|
| 185 |
+
- Focus on explaining the specific content shown in the slide, not generic concepts
|
| 186 |
+
- If there's code, explain what it does step by step
|
| 187 |
+
- If there are examples, break them down clearly
|
| 188 |
+
- If there are rules or concepts, explain them with concrete examples
|
| 189 |
+
- Use a conversational, friendly tone like you're explaining to a friend
|
| 190 |
+
- Structure your response with clear sections and bullet points where helpful
|
| 191 |
+
- Include short code examples (3-7 lines) ONLY if they help illustrate the concept clearly
|
| 192 |
+
- Don't force code examples if the concept doesn't need them
|
| 193 |
|
| 194 |
+
Your response should be educational and helpful, specifically answering: "{question}"."""
|
| 195 |
|
| 196 |
self.focused_qa_prompt = PromptTemplate(
|
| 197 |
input_variables=["question", "slide_content"],
|
|
|
|
| 363 |
if answer.startswith("Provide a clear, educational answer based on this slide:"):
|
| 364 |
answer = answer[58:].strip()
|
| 365 |
|
| 366 |
+
# If LLM response is too short or problematic, show slide content with explanation
|
| 367 |
+
if len(answer.strip()) < 30:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 368 |
slide_info = f"π **Slide Reference:** {best_result.metadata['filename']} - Page {best_result.metadata['page_number']}"
|
| 369 |
+
answer = f"{slide_info}\n\n**Slide Content:**\n{best_slide_content}\n\n*Note: Here's the relevant curriculum content to help answer your question.*"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 370 |
|
| 371 |
except Exception as e:
|
| 372 |
print(f"Error generating focused answer: {e}")
|
| 373 |
+
# Show slide content with explanation
|
| 374 |
slide_info = f"π **Slide Reference:** {best_result.metadata['filename']} - Page {best_result.metadata['page_number']}"
|
| 375 |
+
answer = f"{slide_info}\n\n**Slide Content:**\n{best_slide_content}\n\n*Note: Here's the relevant curriculum content to help answer your question.*"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 376 |
|
| 377 |
elif self.qa_chain and not self.fast_mode:
|
| 378 |
# Fallback to general LLM if focused chain fails
|
|
|
|
| 397 |
if answer.startswith("Provide a clear, educational answer explaining the concept:"):
|
| 398 |
answer = answer[58:].strip()
|
| 399 |
|
| 400 |
+
# If answer is too short, show slide content
|
| 401 |
+
if len(answer.strip()) < 30:
|
| 402 |
if curriculum_relevance_score > 0:
|
| 403 |
slide_info = f"π **Slide Reference:** {best_result.metadata['filename']} - Page {best_result.metadata['page_number']}"
|
| 404 |
+
answer = f"{slide_info}\n\n**Slide Content:**\n{best_slide_content}\n\n*Note: Here's the relevant curriculum content to help answer your question.*"
|
| 405 |
else:
|
| 406 |
answer = "I'm sorry, I couldn't generate a proper answer right now. Please try rephrasing your question - sometimes a different way of asking helps! π"
|
| 407 |
|
|
|
|
| 413 |
print(f"Error generating answer: {e}")
|
| 414 |
if curriculum_relevance_score > 0:
|
| 415 |
slide_info = f"π **Slide Reference:** {best_result.metadata['filename']} - Page {best_result.metadata['page_number']}"
|
| 416 |
+
answer = f"{slide_info}\n\n**Slide Content:**\n{best_slide_content}\n\n*Note: Here's the relevant curriculum content to help answer your question.*"
|
| 417 |
else:
|
| 418 |
answer = "I'm sorry, I couldn't generate an answer at the moment. Please try rephrasing your question - sometimes a different approach helps! π"
|
| 419 |
else:
|