Spaces:
Sleeping
Sleeping
Commit
·
39ed2fb
1
Parent(s):
1d0cd2a
Limit explanations to 100 words + add audio checkbox
Browse files- Shorter explanations save TTS credits and make better demos
- Audio generation now OFF by default (checkbox to enable)
- Skips ElevenLabs call when audio unchecked
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- app.py +13 -7
- src/agent.py +1 -1
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, 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)
|
|
@@ -79,9 +79,9 @@ def explain_topic(topic: str, persona_name: str, audience: str = "", progress=gr
|
|
| 79 |
# Format the steps log
|
| 80 |
steps_md = "\n\n---\n\n".join(steps_log)
|
| 81 |
|
| 82 |
-
# Generate audio
|
| 83 |
audio_path = None
|
| 84 |
-
if explanation and voice_id:
|
| 85 |
progress(0.9, desc="Generating audio...")
|
| 86 |
try:
|
| 87 |
audio_bytes = generate_speech(explanation, voice_id)
|
|
@@ -94,6 +94,8 @@ def explain_topic(topic: str, persona_name: str, audience: str = "", progress=gr
|
|
| 94 |
steps_log.append(f"**⚠️ Audio generation failed**\n{str(e)}")
|
| 95 |
steps_md = "\n\n---\n\n".join(steps_log)
|
| 96 |
progress(1.0, desc="Done (no audio)")
|
|
|
|
|
|
|
| 97 |
|
| 98 |
# Format sources
|
| 99 |
sources_md = format_sources(sources)
|
|
@@ -138,6 +140,10 @@ def create_app():
|
|
| 138 |
value=persona_choices[0],
|
| 139 |
label="🎭 Choose your explainer",
|
| 140 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
|
| 142 |
with gr.Row():
|
| 143 |
audience_input = gr.Textbox(
|
|
@@ -204,21 +210,21 @@ def create_app():
|
|
| 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 |
|
|
|
|
| 32 |
return md
|
| 33 |
|
| 34 |
|
| 35 |
+
def explain_topic(topic: str, persona_name: str, audience: str = "", generate_audio: bool = False, 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)
|
|
|
|
| 79 |
# Format the steps log
|
| 80 |
steps_md = "\n\n---\n\n".join(steps_log)
|
| 81 |
|
| 82 |
+
# Generate audio only if checkbox is checked
|
| 83 |
audio_path = None
|
| 84 |
+
if generate_audio and explanation and voice_id:
|
| 85 |
progress(0.9, desc="Generating audio...")
|
| 86 |
try:
|
| 87 |
audio_bytes = generate_speech(explanation, voice_id)
|
|
|
|
| 94 |
steps_log.append(f"**⚠️ Audio generation failed**\n{str(e)}")
|
| 95 |
steps_md = "\n\n---\n\n".join(steps_log)
|
| 96 |
progress(1.0, desc="Done (no audio)")
|
| 97 |
+
else:
|
| 98 |
+
progress(1.0, desc="Done!")
|
| 99 |
|
| 100 |
# Format sources
|
| 101 |
sources_md = format_sources(sources)
|
|
|
|
| 140 |
value=persona_choices[0],
|
| 141 |
label="🎭 Choose your explainer",
|
| 142 |
)
|
| 143 |
+
audio_checkbox = gr.Checkbox(
|
| 144 |
+
label="🔊 Generate audio",
|
| 145 |
+
value=False,
|
| 146 |
+
)
|
| 147 |
|
| 148 |
with gr.Row():
|
| 149 |
audience_input = gr.Textbox(
|
|
|
|
| 210 |
)
|
| 211 |
|
| 212 |
# Event handler
|
| 213 |
+
def process_and_explain(topic, persona_with_emoji, gen_audio, audience):
|
| 214 |
# Extract persona name (remove emoji prefix)
|
| 215 |
persona_name = persona_with_emoji.split(" ", 1)[1] if " " in persona_with_emoji else persona_with_emoji
|
| 216 |
+
return explain_topic(topic, persona_name, audience, gen_audio)
|
| 217 |
|
| 218 |
explain_btn.click(
|
| 219 |
fn=process_and_explain,
|
| 220 |
+
inputs=[topic_input, persona_dropdown, audio_checkbox, audience_input],
|
| 221 |
outputs=[explanation_output, audio_output, sources_output, steps_output],
|
| 222 |
)
|
| 223 |
|
| 224 |
# Also trigger on Enter key in topic input
|
| 225 |
topic_input.submit(
|
| 226 |
fn=process_and_explain,
|
| 227 |
+
inputs=[topic_input, persona_dropdown, audio_checkbox, audience_input],
|
| 228 |
outputs=[explanation_output, audio_output, sources_output, steps_output],
|
| 229 |
)
|
| 230 |
|
src/agent.py
CHANGED
|
@@ -244,7 +244,7 @@ def run_agent(topic: str, persona_name: str, audience: str = "") -> Generator[di
|
|
| 244 |
You are explaining a topic to someone. Your explanation should be:
|
| 245 |
1. Entertaining and fully in character
|
| 246 |
2. Educational - actually explain the concept clearly
|
| 247 |
-
3.
|
| 248 |
4. Natural spoken language (will be read aloud)
|
| 249 |
5. Engaging and memorable{audience_context}
|
| 250 |
|
|
|
|
| 244 |
You are explaining a topic to someone. Your explanation should be:
|
| 245 |
1. Entertaining and fully in character
|
| 246 |
2. Educational - actually explain the concept clearly
|
| 247 |
+
3. MAXIMUM 100 words - be concise!
|
| 248 |
4. Natural spoken language (will be read aloud)
|
| 249 |
5. Engaging and memorable{audience_context}
|
| 250 |
|