File size: 13,377 Bytes
50ccedb
 
 
 
 
a08d5e1
50ccedb
 
 
a79b809
 
 
 
a08d5e1
 
 
 
 
 
 
 
 
 
 
a79b809
a08d5e1
 
50ccedb
 
 
 
 
 
 
 
 
 
 
 
 
 
a79b809
50ccedb
 
 
a79b809
50ccedb
 
 
a79b809
 
50ccedb
a79b809
50ccedb
a79b809
 
50ccedb
a79b809
50ccedb
 
a79b809
50ccedb
a79b809
50ccedb
 
a79b809
 
 
50ccedb
 
a08d5e1
50ccedb
 
 
a08d5e1
a79b809
 
 
50ccedb
 
a08d5e1
50ccedb
 
 
 
 
a79b809
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50ccedb
a79b809
 
50ccedb
a79b809
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a08d5e1
a79b809
 
 
a08d5e1
 
a79b809
 
 
 
 
a08d5e1
a79b809
50ccedb
a79b809
 
a08d5e1
a79b809
a08d5e1
a79b809
 
 
a08d5e1
a79b809
a08d5e1
a79b809
 
 
 
 
 
 
 
50ccedb
a79b809
 
 
a08d5e1
a79b809
a08d5e1
a79b809
 
 
a08d5e1
 
a79b809
 
 
a08d5e1
a79b809
 
 
 
a08d5e1
a79b809
 
 
a08d5e1
a79b809
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
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)