Spaces:
Sleeping
Sleeping
Commit
·
0627d63
1
Parent(s):
d871be8
Add audience input field
Browse filesUsers can now specify who they are (e.g., "a college student",
"my grandmother") to get tailored explanations for their level.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
- app.py +14 -6
- src/agent.py +8 -3
app.py
CHANGED
|
@@ -32,7 +32,7 @@ def format_sources(sources: list[dict]) -> str:
|
|
| 32 |
return md
|
| 33 |
|
| 34 |
|
| 35 |
-
def explain_topic(topic: str, persona_name: str, progress=gr.Progress()):
|
| 36 |
"""Main function to explain a topic in a persona's voice.
|
| 37 |
|
| 38 |
Returns: (explanation_text, audio_path, sources_md, steps_md)
|
|
@@ -56,7 +56,7 @@ def explain_topic(topic: str, persona_name: str, progress=gr.Progress()):
|
|
| 56 |
# Run the agent pipeline
|
| 57 |
progress(0, desc="Starting...")
|
| 58 |
|
| 59 |
-
for update in run_agent(topic, persona_name):
|
| 60 |
if update["type"] == "step":
|
| 61 |
step_text = f"**{update['title']}**\n{update['content']}"
|
| 62 |
steps_log.append(step_text)
|
|
@@ -139,6 +139,14 @@ def create_app():
|
|
| 139 |
label="🎭 Choose your explainer",
|
| 140 |
)
|
| 141 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
explain_btn = gr.Button(
|
| 143 |
"✨ Explain it to me!",
|
| 144 |
variant="primary",
|
|
@@ -196,21 +204,21 @@ def create_app():
|
|
| 196 |
)
|
| 197 |
|
| 198 |
# Event handler
|
| 199 |
-
def process_and_explain(topic, persona_with_emoji):
|
| 200 |
# Extract persona name (remove emoji prefix)
|
| 201 |
persona_name = persona_with_emoji.split(" ", 1)[1] if " " in persona_with_emoji else persona_with_emoji
|
| 202 |
-
return explain_topic(topic, persona_name)
|
| 203 |
|
| 204 |
explain_btn.click(
|
| 205 |
fn=process_and_explain,
|
| 206 |
-
inputs=[topic_input, persona_dropdown],
|
| 207 |
outputs=[explanation_output, audio_output, sources_output, steps_output],
|
| 208 |
)
|
| 209 |
|
| 210 |
# Also trigger on Enter key in topic input
|
| 211 |
topic_input.submit(
|
| 212 |
fn=process_and_explain,
|
| 213 |
-
inputs=[topic_input, persona_dropdown],
|
| 214 |
outputs=[explanation_output, audio_output, sources_output, steps_output],
|
| 215 |
)
|
| 216 |
|
|
|
|
| 32 |
return md
|
| 33 |
|
| 34 |
|
| 35 |
+
def explain_topic(topic: str, persona_name: str, audience: str = "", progress=gr.Progress()):
|
| 36 |
"""Main function to explain a topic in a persona's voice.
|
| 37 |
|
| 38 |
Returns: (explanation_text, audio_path, sources_md, steps_md)
|
|
|
|
| 56 |
# Run the agent pipeline
|
| 57 |
progress(0, desc="Starting...")
|
| 58 |
|
| 59 |
+
for update in run_agent(topic, persona_name, audience):
|
| 60 |
if update["type"] == "step":
|
| 61 |
step_text = f"**{update['title']}**\n{update['content']}"
|
| 62 |
steps_log.append(step_text)
|
|
|
|
| 139 |
label="🎭 Choose your explainer",
|
| 140 |
)
|
| 141 |
|
| 142 |
+
with gr.Row():
|
| 143 |
+
audience_input = gr.Textbox(
|
| 144 |
+
label="👤 Who are you? (optional)",
|
| 145 |
+
placeholder="e.g., a college student, a CEO, my grandmother, a 10-year-old...",
|
| 146 |
+
lines=1,
|
| 147 |
+
max_lines=1,
|
| 148 |
+
)
|
| 149 |
+
|
| 150 |
explain_btn = gr.Button(
|
| 151 |
"✨ Explain it to me!",
|
| 152 |
variant="primary",
|
|
|
|
| 204 |
)
|
| 205 |
|
| 206 |
# Event handler
|
| 207 |
+
def process_and_explain(topic, persona_with_emoji, audience):
|
| 208 |
# Extract persona name (remove emoji prefix)
|
| 209 |
persona_name = persona_with_emoji.split(" ", 1)[1] if " " in persona_with_emoji else persona_with_emoji
|
| 210 |
+
return explain_topic(topic, persona_name, audience)
|
| 211 |
|
| 212 |
explain_btn.click(
|
| 213 |
fn=process_and_explain,
|
| 214 |
+
inputs=[topic_input, persona_dropdown, audience_input],
|
| 215 |
outputs=[explanation_output, audio_output, sources_output, steps_output],
|
| 216 |
)
|
| 217 |
|
| 218 |
# Also trigger on Enter key in topic input
|
| 219 |
topic_input.submit(
|
| 220 |
fn=process_and_explain,
|
| 221 |
+
inputs=[topic_input, persona_dropdown, audience_input],
|
| 222 |
outputs=[explanation_output, audio_output, sources_output, steps_output],
|
| 223 |
)
|
| 224 |
|
src/agent.py
CHANGED
|
@@ -198,7 +198,7 @@ Now explain "{topic}" in your unique voice and style. Make it fun and educationa
|
|
| 198 |
}
|
| 199 |
|
| 200 |
|
| 201 |
-
def run_agent(topic: str, persona_name: str) -> Generator[dict, None, None]:
|
| 202 |
"""Run the full agent pipeline.
|
| 203 |
|
| 204 |
Yields progress updates and final results.
|
|
@@ -224,11 +224,16 @@ def run_agent(topic: str, persona_name: str) -> Generator[dict, None, None]:
|
|
| 224 |
# Step 2: Generate explanation
|
| 225 |
persona = get_persona(persona_name)
|
| 226 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
yield {
|
| 228 |
"type": "step",
|
| 229 |
"step": "generating",
|
| 230 |
"title": f"{persona['emoji']} Channeling {persona_name}",
|
| 231 |
-
"content": "Transforming research into persona voice...",
|
| 232 |
}
|
| 233 |
|
| 234 |
messages = [
|
|
@@ -241,7 +246,7 @@ You are explaining a topic to someone. Your explanation should be:
|
|
| 241 |
2. Educational - actually explain the concept clearly
|
| 242 |
3. About 150-200 words (suitable for text-to-speech)
|
| 243 |
4. Natural spoken language (will be read aloud)
|
| 244 |
-
5. Engaging and memorable
|
| 245 |
|
| 246 |
Do NOT break character. Do NOT use markdown, bullet points, or special formatting.
|
| 247 |
Just speak naturally as your character would.""",
|
|
|
|
| 198 |
}
|
| 199 |
|
| 200 |
|
| 201 |
+
def run_agent(topic: str, persona_name: str, audience: str = "") -> Generator[dict, None, None]:
|
| 202 |
"""Run the full agent pipeline.
|
| 203 |
|
| 204 |
Yields progress updates and final results.
|
|
|
|
| 224 |
# Step 2: Generate explanation
|
| 225 |
persona = get_persona(persona_name)
|
| 226 |
|
| 227 |
+
# Build audience context
|
| 228 |
+
audience_context = ""
|
| 229 |
+
if audience and audience.strip():
|
| 230 |
+
audience_context = f"\nYou are explaining this to: {audience.strip()}. Tailor your explanation appropriately for them."
|
| 231 |
+
|
| 232 |
yield {
|
| 233 |
"type": "step",
|
| 234 |
"step": "generating",
|
| 235 |
"title": f"{persona['emoji']} Channeling {persona_name}",
|
| 236 |
+
"content": f"Transforming research into persona voice{' for ' + audience if audience else ''}...",
|
| 237 |
}
|
| 238 |
|
| 239 |
messages = [
|
|
|
|
| 246 |
2. Educational - actually explain the concept clearly
|
| 247 |
3. About 150-200 words (suitable for text-to-speech)
|
| 248 |
4. Natural spoken language (will be read aloud)
|
| 249 |
+
5. Engaging and memorable{audience_context}
|
| 250 |
|
| 251 |
Do NOT break character. Do NOT use markdown, bullet points, or special formatting.
|
| 252 |
Just speak naturally as your character would.""",
|