script / app.py
sik247's picture
agentic update
a79b809
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"))
# --------------------------------------------
# Core Functions
# --------------------------------------------
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)
# --------------------------------------------
# Sidebar: Input Parameters
# --------------------------------------------
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.")
# --------------------------------------------
# Main Area: Editable Lecture Prompt Template
# --------------------------------------------
st.title("Lecture Script Generator and Refinement Interface")
# Build the default prompt based on current sidebar inputs.
default_prompt = default_prompt_builder(
math_subject, topic, difficulty, speaking_style, example1, problem1, wordproblem, prev_lecture
)
# Initialize session state for custom prompt if not set.
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
# Editable text area for the prompt template.
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
# --------------------------------------------
# Lecture Script Generation, Agent Feedback, and Refinement
# --------------------------------------------
if st.button("Generate Lecture Script"):
with st.spinner("Generating lecture script and running agent checks..."):
# 1. Generate the initial lecture script.
lecture_script = call_openai_chat(custom_prompt)
# 2. Run all agent feedback functions.
transitions_feedback = check_transitions(lecture_script)
errors_feedback = check_errors(lecture_script)
steps_feedback = check_step_organization(lecture_script)
# 3. Produce the refined lecture script using the agent feedback.
refined_script = refine_lecture_manual(lecture_script, transitions_feedback, errors_feedback, steps_feedback)
# 4. Produce the scriptified lecture script by further processing the refined script with extra transitions.
scriptified_script = add_extra_transitions(refined_script)
# Save all results in session state.
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!")
# --------------------------------------------
# Editable Lecture Script and Update Agent Feedback
# --------------------------------------------
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!")
# --------------------------------------------
# Regenerate Refined Scripts if Needed
# --------------------------------------------
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!")
# --------------------------------------------
# Display Refined and Scriptified Lectures Side by Side
# --------------------------------------------
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)
# --------------------------------------------
# Display Agent Feedback Below
# --------------------------------------------
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)