ciaochris commited on
Commit
2af6b00
·
verified ·
1 Parent(s): bd3ead1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -39
app.py CHANGED
@@ -129,45 +129,53 @@ def generate_tutor_output(subject: str, difficulty: str, student_input: str) ->
129
  if enhanced_topic:
130
  break
131
 
 
132
  if enhanced_topic:
133
  logging.debug(f"Using enhanced topic: {enhanced_topic}")
134
  prompt = f"""
135
  You are an expert tutor specializing in {enhanced_topic} at the {difficulty} level. The student has asked about: "{student_input}"
136
- Please provide your response in the following format:
137
- 1. Lesson: A comprehensive lesson based on national educational standards on the topic (3-4 paragraphs), including its historical context.
138
- 2. Example: A detailed step-by-step example problem with a full solution. Structure it as follows:
139
- - Start with "Example Problem:" followed by the question.
140
- - Then, list the steps to solve the problem, each on a new line starting with "Step 1:", "Step 2:", etc.
141
- - Finally, provide the answer starting with "Answer:".
142
- 3. Real-World Application: A challenging real-world application of this concept, demonstrating its practical use.
143
- 4. Quiz: Create a short quiz (3 multiple-choice questions) to test the student's understanding.
144
- Format your entire response as a JSON object with keys: "lesson", "example", "real_world_problem", "quiz".
145
- Ensure that the content for each key is a single string, with line breaks where appropriate.
146
  """
147
  else:
148
  logging.debug(f"Using general subject: {subject_lower}")
149
  prompt = f"""
150
- You are an expert tutor in {subject_lower} at the {difficulty} level. The student has provided the following input: "{student_input}"
151
- Please generate your response in the following format:
152
- 1. Lesson: Provide a descriptive, long, and engaging lesson on the topic (3-4 paragraphs).
153
- 2. Example: Present an example problem related to the topic. Structure it as follows:
154
- - Start with "Example Problem:" followed by the question.
155
- - Then, list the steps to solve the problem, each on a new line starting with "Step 1:", "Step 2:", etc.
156
- - Finally, provide the answer starting with "Answer:".
157
- 3. Real-World Application: Describe a real-world problem that can be solved using the concepts from the lesson.
158
- 4. Quiz: Create a short quiz (3 multiple-choice questions) to test the student's understanding.
159
- Format your entire response as a JSON object with keys: "lesson", "example", "real_world_problem", "quiz".
160
- Ensure that the content for each key is a single string, with line breaks where appropriate.
161
  """
162
 
163
- target_model = "llama-3.3-70b-versatile"
 
 
 
 
 
 
 
 
 
164
  logging.debug(f"Sending prompt to model: {target_model}")
165
 
166
  completion = client.chat.completions.create(
167
  messages=[
168
  {
169
  "role": "system",
170
- "content": f"You are the world's best AI tutor, renowned for your ability to explain complex concepts in an engaging, clear, and memorable way. Your expertise in {subject_lower} is unparalleled, and you're adept at tailoring your teaching to {difficulty} level students. Your goal is to not just impart knowledge, but to inspire a love for learning and critical thinking.",
171
  },
172
  {
173
  "role": "user",
@@ -179,38 +187,62 @@ def generate_tutor_output(subject: str, difficulty: str, student_input: str) ->
179
  )
180
 
181
  response_content = completion.choices[0].message.content
182
- logging.debug(f"Received response: {response_content[:100]}...")
183
 
184
- try:
185
- result = json.loads(response_content)
186
- logging.debug("Successfully parsed JSON response")
187
- except json.JSONDecodeError:
188
- logging.warning("Failed to parse JSON, using fallback parsing")
 
 
 
 
 
 
 
 
 
 
 
 
189
  sections = {
190
- "lesson": "No lesson generated due to parsing error",
191
- "example": "No example generated due to parsing error",
192
- "real_world_problem": "No real-world application generated due to parsing error",
193
- "quiz": "No quiz generated due to parsing error"
194
  }
195
  lines = response_content.split('\n')
196
  current_section = None
197
  for line in lines:
198
  line = line.strip()
 
 
199
  if "Lesson:" in line or line.startswith("1."):
200
  current_section = "lesson"
201
- sections[current_section] = line.replace("Lesson:", "").replace("1.", "").strip() + "\n"
202
  elif "Example:" in line or line.startswith("2."):
203
  current_section = "example"
204
- sections[current_section] = line.replace("Example:", "").replace("2.", "").strip() + "\n"
205
- elif "Real-World Application:" in line or line.startswith("3."):
206
  current_section = "real_world_problem"
207
- sections[current_section] = line.replace("Real-World Application:", "").replace("3.", "").strip() + "\n"
208
  elif "Quiz:" in line or line.startswith("4."):
209
  current_section = "quiz"
210
- sections[current_section] = line.replace("Quiz:", "").replace("4.", "").strip() + "\n"
211
  elif current_section:
212
  sections[current_section] += line + "\n"
213
- result = sections
 
 
 
 
 
 
 
 
 
 
214
 
215
  # Ensure all keys are present
216
  for key in ["lesson", "example", "real_world_problem", "quiz"]:
 
129
  if enhanced_topic:
130
  break
131
 
132
+ # Enhanced prompt with explicit JSON requirement
133
  if enhanced_topic:
134
  logging.debug(f"Using enhanced topic: {enhanced_topic}")
135
  prompt = f"""
136
  You are an expert tutor specializing in {enhanced_topic} at the {difficulty} level. The student has asked about: "{student_input}"
137
+ Provide your response as a valid JSON object with the following keys and content:
138
+ - "lesson": A comprehensive lesson (3-4 paragraphs) based on national educational standards, including historical context.
139
+ - "example": A detailed step-by-step example problem with a full solution, formatted as:
140
+ - "Example Problem:" followed by the question
141
+ - "Step 1:", "Step 2:", etc., each on a new line
142
+ - "Answer:" with the final solution
143
+ - "real_world_problem": A challenging real-world application of this concept.
144
+ - "quiz": A short quiz with 3 multiple-choice questions (e.g., "1. Question text\n a) option1\n b) option2\n c) option3\nCorrect answer: a").
145
+ Return only the JSON object, enclosed in ```json``` markers, with no additional text outside the markers.
 
146
  """
147
  else:
148
  logging.debug(f"Using general subject: {subject_lower}")
149
  prompt = f"""
150
+ You are an expert tutor in {subject_lower} at the {difficulty} level. The student has provided: "{student_input}"
151
+ Provide your response as a valid JSON object with the following keys and content:
152
+ - "lesson": A descriptive, engaging lesson (3-4 paragraphs) on the topic.
153
+ - "example": An example problem with a full solution, formatted as:
154
+ - "Example Problem:" followed by the question
155
+ - "Step 1:", "Step 2:", etc., each on a new line
156
+ - "Answer:" with the final solution
157
+ - "real_world_problem": A real-world problem solvable using the lesson concepts.
158
+ - "quiz": A short quiz with 3 multiple-choice questions (e.g., "1. Question text\n a) option1\n b) option2\n c) option3\nCorrect answer: a").
159
+ Return only the JSON object, enclosed in ```json``` markers, with no additional text outside the markers.
 
160
  """
161
 
162
+ # Model selection with fallback
163
+ try:
164
+ models = client.models.list()
165
+ available_models = [m.id for m in models.data]
166
+ logging.debug(f"Available models: {available_models}")
167
+ target_model = "llama-3.3-70b-versatile" if "llama-3.3-70b-versatile" in available_models else available_models[0]
168
+ except Exception:
169
+ logging.warning("Could not fetch model list, using default model")
170
+ target_model = "llama-3.3-70b-versatile"
171
+
172
  logging.debug(f"Sending prompt to model: {target_model}")
173
 
174
  completion = client.chat.completions.create(
175
  messages=[
176
  {
177
  "role": "system",
178
+ "content": f"You are the world's best AI tutor, renowned for your ability to explain complex concepts clearly and engagingly. Your expertise in {subject_lower} is unparalleled, and you tailor your teaching to {difficulty} level students. Always return responses as valid JSON enclosed in ```json``` markers.",
179
  },
180
  {
181
  "role": "user",
 
187
  )
188
 
189
  response_content = completion.choices[0].message.content
190
+ logging.debug(f"Raw API response: {response_content}")
191
 
192
+ # Extract JSON from response
193
+ json_match = re.search(r'```json\s*([\s\S]*?)\s*```', response_content)
194
+ if json_match:
195
+ json_str = json_match.group(1)
196
+ try:
197
+ result = json.loads(json_str)
198
+ logging.debug("Successfully parsed JSON from response")
199
+ except json.JSONDecodeError as e:
200
+ logging.warning(f"JSON parsing failed: {e}")
201
+ result = None
202
+ else:
203
+ logging.warning("No JSON markers found in response")
204
+ result = None
205
+
206
+ # Fallback parsing if JSON extraction fails
207
+ if not result:
208
+ logging.debug("Falling back to text parsing")
209
  sections = {
210
+ "lesson": "",
211
+ "example": "",
212
+ "real_world_problem": "",
213
+ "quiz": ""
214
  }
215
  lines = response_content.split('\n')
216
  current_section = None
217
  for line in lines:
218
  line = line.strip()
219
+ if not line or line.startswith('```'):
220
+ continue
221
  if "Lesson:" in line or line.startswith("1."):
222
  current_section = "lesson"
223
+ sections[current_section] += line.replace("Lesson:", "").replace("1.", "").strip() + "\n"
224
  elif "Example:" in line or line.startswith("2."):
225
  current_section = "example"
226
+ sections[current_section] += line.replace("Example:", "").replace("2.", "").strip() + "\n"
227
+ elif "Real-World Application:" in line or "Real-World Problem:" in line or line.startswith("3."):
228
  current_section = "real_world_problem"
229
+ sections[current_section] += line.replace("Real-World Application:", "").replace("Real-World Problem:", "").replace("3.", "").strip() + "\n"
230
  elif "Quiz:" in line or line.startswith("4."):
231
  current_section = "quiz"
232
+ sections[current_section] += line.replace("Quiz:", "").replace("4.", "").strip() + "\n"
233
  elif current_section:
234
  sections[current_section] += line + "\n"
235
+
236
+ # Check if any section was populated
237
+ if any(sections.values()):
238
+ result = sections
239
+ else:
240
+ result = {
241
+ "lesson": "Failed to parse lesson content",
242
+ "example": "Failed to parse example content",
243
+ "real_world_problem": "Failed to parse real-world application content",
244
+ "quiz": "Failed to parse quiz content"
245
+ }
246
 
247
  # Ensure all keys are present
248
  for key in ["lesson", "example", "real_world_problem", "quiz"]: