|
|
import os |
|
|
import re |
|
|
import streamlit as st |
|
|
from openai import OpenAI |
|
|
from dotenv import load_dotenv |
|
|
|
|
|
load_dotenv() |
|
|
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def default_prompt_builder( |
|
|
math_subject: str, |
|
|
topic: str, |
|
|
difficulty: str, |
|
|
speaking_style: str, |
|
|
example1: str, |
|
|
problem1: str, |
|
|
wordproblem: str, |
|
|
prev_lecture: str |
|
|
) -> str: |
|
|
""" |
|
|
Builds the base lecture prompt. |
|
|
""" |
|
|
return f""" |
|
|
You are a math teacher. Create a comprehensive lecture script for a lesson in "{math_subject}" on the topic "{topic}" |
|
|
that transitions seamlessly from start to finish. Deliver the lecture in a {speaking_style} style, |
|
|
appropriate for a(n) {difficulty} audience, using English only. |
|
|
|
|
|
The script must be fluent with smooth transitions and detailed explanations of the concepts. |
|
|
|
|
|
1. **Hook :** |
|
|
Provide a concise, empowering introduction that engages the learners and clearly introduces the subject and topic. |
|
|
If any relevant material from a previous lecture should be mentioned, briefly reference it here: |
|
|
"{prev_lecture}" |
|
|
|
|
|
2. **Topic Intro :** |
|
|
Present a concise background or interesting fact about the topic. |
|
|
|
|
|
3. **Core Concept Definition :** |
|
|
Provide a clear definition of the core concepts. Explain their importance and mention any |
|
|
fundamental equations, theorems, or limit definitions that underlie them. Include mathematical equations if necessary. |
|
|
|
|
|
4. **Detailed Explanation :** |
|
|
Offer a detailed, step-by-step explanation of the topic. Incorporate deeper theoretical underpinnings— |
|
|
such as derivations from first principles or explanations of common misconceptions and how to avoid them. |
|
|
|
|
|
5. **Example Problem :** |
|
|
Use the following example problem for a thorough walkthrough: |
|
|
"{example1}" |
|
|
- Provide a step-by-step solution (e.g., Step1, Step2, Step3, etc.). |
|
|
- Reference relevant theorems or limit definitions. |
|
|
- Mention common mistakes with transitions and how to correct them. |
|
|
- Summarize the final result clearly. |
|
|
|
|
|
6. **Problem 1 :** |
|
|
Use the following second problem: |
|
|
"{problem1}" |
|
|
Provide a detailed solution with numbered steps and transitions, referencing theorems/definitions, and summarizing the result. |
|
|
|
|
|
7. **Word Problem :** |
|
|
Use the following word problem: |
|
|
"{wordproblem}" |
|
|
Solve it thoroughly with numbered steps and transitions, referencing key theorems, discussing pitfalls, and offering alternative approaches. |
|
|
|
|
|
8. **Engagement, Reinforcement, and Conclusion :** |
|
|
Summarize the key points and offer additional tips or alternative approaches for deeper understanding. |
|
|
End with a motivational wrap-up, leaving the audience with a final thought or question. |
|
|
|
|
|
Begin your response now. |
|
|
""" |
|
|
|
|
|
def call_openai_chat(prompt: str, max_tokens: int = 2000, temperature: float = 0.4) -> str: |
|
|
""" |
|
|
Calls the OpenAI chat completions API with the provided prompt. |
|
|
""" |
|
|
response = client.chat.completions.create( |
|
|
model="gpt-4o-2024-08-06", |
|
|
messages=[{"role": "user", "content": prompt}], |
|
|
max_tokens=max_tokens, |
|
|
temperature=temperature |
|
|
) |
|
|
return response.choices[0].message.content.strip() |
|
|
|
|
|
def check_transitions(lecture_script: str) -> str: |
|
|
prompt = f""" |
|
|
Review the following lecture script and identify any sections that lack smooth transitions. |
|
|
Point out where transitions are missing and suggest improvements. |
|
|
|
|
|
Lecture Script: |
|
|
\"\"\"{lecture_script}\"\"\" |
|
|
|
|
|
Return only your feedback and suggestions. |
|
|
""" |
|
|
return call_openai_chat(prompt) |
|
|
|
|
|
def check_errors(lecture_script: str) -> str: |
|
|
prompt = f""" |
|
|
Review the following lecture script for any errors including grammar, mathematical inaccuracies, or formatting issues. |
|
|
List the errors and provide suggestions for corrections. |
|
|
|
|
|
Lecture Script: |
|
|
\"\"\"{lecture_script}\"\"\" |
|
|
|
|
|
Return only your feedback and suggestions. |
|
|
""" |
|
|
return call_openai_chat(prompt) |
|
|
|
|
|
def check_step_organization(lecture_script: str) -> str: |
|
|
prompt = f""" |
|
|
Analyze the following lecture script and check whether all problem solutions have their steps clearly enumerated (e.g., Step1, Step2, Step3, etc.). |
|
|
If any solutions are missing this clear organization, list those sections and suggest improvements. |
|
|
|
|
|
Lecture Script: |
|
|
\"\"\"{lecture_script}\"\"\" |
|
|
|
|
|
Return only your feedback and suggestions. |
|
|
""" |
|
|
return call_openai_chat(prompt) |
|
|
|
|
|
def refine_lecture_manual(lecture_script: str, transitions_feedback: str, errors_feedback: str, steps_feedback: str) -> str: |
|
|
""" |
|
|
Produces a refined version of the lecture script using agent feedback. |
|
|
This version may include a separate **Common Mistakes:** section. |
|
|
""" |
|
|
prompt = f""" |
|
|
You are an expert in educational content design. Below is the original lecture script along with feedback from three specialized agents: |
|
|
|
|
|
--- Original Lecture Script --- |
|
|
\"\"\"{lecture_script}\"\"\" |
|
|
|
|
|
--- Feedback --- |
|
|
Transitions Feedback: |
|
|
{transitions_feedback} |
|
|
|
|
|
Errors Feedback: |
|
|
{errors_feedback} |
|
|
|
|
|
Step Organization Feedback: |
|
|
{steps_feedback} |
|
|
|
|
|
Using this feedback, provide a refined version of the lecture script that addresses all the issues mentioned. |
|
|
Ensure that transitions between sections are smooth, all errors are corrected, and all problem solutions have clearly enumerated steps. |
|
|
Include a section labeled **Common Mistakes:** if necessary. |
|
|
Return only the refined lecture script. |
|
|
""" |
|
|
return call_openai_chat(prompt) |
|
|
|
|
|
def add_extra_transitions(lecture_script: str) -> str: |
|
|
""" |
|
|
Enhances the refined lecture script by integrating transitions, summaries, and commentary on common mistakes seamlessly into the narrative. |
|
|
This function checks if the refined script contains integrated commentary on common mistakes (e.g., "Common Mistake:" or "**Pitfall:**") |
|
|
and summary insights (e.g., "Summary:"). If such elements are missing or not well integrated, it weaves them naturally into the text. |
|
|
""" |
|
|
prompt = f""" |
|
|
You are provided with a refined lecture script. Your task is to enhance it by: |
|
|
1. Adding explicit transitions between steps and sections. |
|
|
2. Seamlessly integrating key conclusions, summary insights, and commentary on common mistakes directly into the narrative. |
|
|
3. Checking whether the lecture script includes integrated remarks on common mistakes (e.g., "Common Mistake:" or "**Pitfall:**") and summaries (e.g., "Summary:"); if not, embed these elements naturally into the content. |
|
|
4. Avoid appending these as separate sections—instead, ensure the final output reads as a unified, continuous lecture script. |
|
|
|
|
|
Return only the enhanced lecture script. |
|
|
|
|
|
Lecture Script: |
|
|
\"\"\"{lecture_script}\"\"\" |
|
|
""" |
|
|
return call_openai_chat(prompt) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.sidebar.header("Input Parameters") |
|
|
|
|
|
math_subject = st.sidebar.text_input("Math Subject", value="Algebra") |
|
|
topic = st.sidebar.text_input("Topic", value="Quadratic Equations") |
|
|
difficulty = st.sidebar.selectbox("Difficulty", options=["beginner", "intermediate", "advanced"], index=1) |
|
|
speaking_style = st.sidebar.text_input("Speaking Style", value="engaging and clear") |
|
|
example1 = st.sidebar.text_area("Example Problem", value="Solve x^2 - 5x + 6 = 0") |
|
|
problem1 = st.sidebar.text_area("Problem 1", value="Find the roots of 2x^2 - 4x - 6 = 0") |
|
|
wordproblem = st.sidebar.text_area("Word Problem", value="A projectile is launched with a height given by h(t) = -4.9t^2 + 20t + 5. Determine when it reaches the ground.") |
|
|
prev_lecture = st.sidebar.text_area("Previous Lecture Reference", value="We covered linear equations and basic factoring techniques.") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.title("Lecture Script Generator and Refinement Interface") |
|
|
|
|
|
|
|
|
default_prompt = default_prompt_builder( |
|
|
math_subject, topic, difficulty, speaking_style, example1, problem1, wordproblem, prev_lecture |
|
|
) |
|
|
|
|
|
|
|
|
if "custom_prompt" not in st.session_state: |
|
|
st.session_state.custom_prompt = default_prompt |
|
|
|
|
|
st.subheader("Lecture Prompt Template (Editable)") |
|
|
st.write("This is the template with numbered sections and placeholders. Use the button below to update it based on the current input parameters, or edit it directly.") |
|
|
if st.button("Update Prompt Template with current placeholder values"): |
|
|
st.session_state.custom_prompt = default_prompt |
|
|
|
|
|
|
|
|
custom_prompt = st.text_area("Edit Lecture Prompt Template", value=st.session_state.custom_prompt, height=400, key="custom_prompt_main") |
|
|
st.session_state.custom_prompt = custom_prompt |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if st.button("Generate Lecture Script"): |
|
|
with st.spinner("Generating lecture script and running agent checks..."): |
|
|
|
|
|
lecture_script = call_openai_chat(custom_prompt) |
|
|
|
|
|
transitions_feedback = check_transitions(lecture_script) |
|
|
errors_feedback = check_errors(lecture_script) |
|
|
steps_feedback = check_step_organization(lecture_script) |
|
|
|
|
|
refined_script = refine_lecture_manual(lecture_script, transitions_feedback, errors_feedback, steps_feedback) |
|
|
|
|
|
scriptified_script = add_extra_transitions(refined_script) |
|
|
|
|
|
st.session_state['lecture_script'] = lecture_script |
|
|
st.session_state['transitions_feedback'] = transitions_feedback |
|
|
st.session_state['errors_feedback'] = errors_feedback |
|
|
st.session_state['steps_feedback'] = steps_feedback |
|
|
st.session_state['refined_script'] = refined_script |
|
|
st.session_state['scriptified_script'] = scriptified_script |
|
|
st.success("Lecture script, agent feedback, and both refined scripts generated!") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if "lecture_script" in st.session_state: |
|
|
st.subheader("Generated Lecture Script (Editable)") |
|
|
lecture_script = st.text_area("Lecture Script", value=st.session_state['lecture_script'], height=300) |
|
|
st.session_state['lecture_script'] = lecture_script |
|
|
|
|
|
if st.button("Update Agent Feedback"): |
|
|
with st.spinner("Fetching updated agent feedback..."): |
|
|
transitions_feedback = check_transitions(lecture_script) |
|
|
errors_feedback = check_errors(lecture_script) |
|
|
steps_feedback = check_step_organization(lecture_script) |
|
|
st.session_state['transitions_feedback'] = transitions_feedback |
|
|
st.session_state['errors_feedback'] = errors_feedback |
|
|
st.session_state['steps_feedback'] = steps_feedback |
|
|
st.success("Agent feedback updated!") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if "lecture_script" in st.session_state and st.session_state.get("transitions_feedback") is not None: |
|
|
if st.button("Regenerate Refined Lecture Scripts"): |
|
|
with st.spinner("Regenerating refined lecture scripts..."): |
|
|
refined_script = refine_lecture_manual( |
|
|
st.session_state["lecture_script"], |
|
|
st.session_state.get('transitions_feedback', ''), |
|
|
st.session_state.get('errors_feedback', ''), |
|
|
st.session_state.get('steps_feedback', '') |
|
|
) |
|
|
scriptified_script = add_extra_transitions(refined_script) |
|
|
st.session_state['refined_script'] = refined_script |
|
|
st.session_state['scriptified_script'] = scriptified_script |
|
|
st.success("Both refined lecture scripts regenerated!") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if "refined_script" in st.session_state and "scriptified_script" in st.session_state: |
|
|
st.subheader("Refined and Scriptified Lectures") |
|
|
col1, col2 = st.columns(2) |
|
|
with col1: |
|
|
st.text_area("Refined Lecture Script", value=st.session_state['refined_script'], height=300) |
|
|
with col2: |
|
|
st.text_area("Scriptified Lecture Script", value=st.session_state['scriptified_script'], height=300) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if "transitions_feedback" in st.session_state: |
|
|
st.subheader("Agent Feedback") |
|
|
st.markdown("**Transitions Feedback:**") |
|
|
st.text_area("", value=st.session_state.get('transitions_feedback', ''), height=150) |
|
|
st.markdown("**Errors Feedback:**") |
|
|
st.text_area("", value=st.session_state.get('errors_feedback', ''), height=150) |
|
|
st.markdown("**Step Organization Feedback:**") |
|
|
st.text_area("", value=st.session_state.get('steps_feedback', ''), height=150) |
|
|
|