|
|
|
```python |
|
|
|
import os |
|
import json |
|
import tempfile |
|
from zipfile import ZipFile |
|
|
|
import gradio as gr |
|
from agents import Agent, AgentRunner, handoff |
|
from agents.extensions.handoff_prompt import RECOMMENDED_PROMPT_PREFIX |
|
|
|
|
|
from your_tts_module import generate_tts_audio |
|
|
|
|
|
|
|
topic_agent = Agent( |
|
name="Topic Agent", |
|
instructions=( |
|
f"{RECOMMENDED_PROMPT_PREFIX}\n" |
|
"You are given a workshop topic and audience. Draft a structured learning path: goals, 4 modules, and a hands-on exercise for each." |
|
) |
|
) |
|
|
|
|
|
content_agent = Agent( |
|
name="Content Agent", |
|
instructions=( |
|
f"{RECOMMENDED_PROMPT_PREFIX}\n" |
|
"Convert the outline into detailed module scripts, speaker notes, and 3 quiz questions per module." |
|
) |
|
) |
|
|
|
|
|
slide_agent = Agent( |
|
name="Slide Agent", |
|
instructions=( |
|
f"{RECOMMENDED_PROMPT_PREFIX}\n" |
|
"Given module content, produce slide JSON with title, bullet points, and design hints." |
|
) |
|
) |
|
|
|
|
|
code_agent = Agent( |
|
name="Code Agent", |
|
instructions=( |
|
f"{RECOMMENDED_PROMPT_PREFIX}\n" |
|
"Generate runnable Python code snippets or a Colab notebook for hands-on labs in each module." |
|
) |
|
) |
|
|
|
|
|
voice_agent = Agent( |
|
name="Voiceover Agent", |
|
instructions=( |
|
f"{RECOMMENDED_PROMPT_PREFIX}\n" |
|
"Create a 1-2 minute voiceover script. Return JSON with keys 'script' and optionally 'audio_url'." |
|
) |
|
) |
|
|
|
|
|
document_orchestrator = Agent( |
|
name="Workshop Orchestrator", |
|
instructions=( |
|
"Invoke sub-agents: topic_agent, content_agent, slide_agent, code_agent, voice_agent (optional); collect outputs." |
|
), |
|
handoffs=[ |
|
handoff(topic_agent, name="outline"), |
|
handoff(content_agent, name="content"), |
|
handoff(slide_agent, name="slides"), |
|
handoff(code_agent, name="code_labs"), |
|
handoff(voice_agent, name="voiceover", optional=True), |
|
] |
|
) |
|
|
|
runner = AgentRunner() |
|
|
|
|
|
def build_workshop_bundle(topic: str, audience: str): |
|
prompt = f"Create a {topic} workshop for {audience}." |
|
results = runner.run(document_orchestrator, prompt).outputs |
|
|
|
|
|
voice_info = results.get('voiceover', {}) |
|
audio_path = None |
|
if 'script' in voice_info: |
|
audio_path = generate_tts_audio(voice_info['script']) |
|
|
|
|
|
slides_json = results.get('slides', {}) |
|
with open('static/slides_template.html') as f: |
|
template = f.read() |
|
slide_html = template.replace('{{SLIDES_JSON}}', json.dumps(slides_json)) |
|
|
|
|
|
tmp = tempfile.mkdtemp() |
|
zipf_path = os.path.join(tmp, 'workshop_bundle.zip') |
|
with ZipFile(zipf_path, 'w') as z: |
|
for name, data in [ |
|
('workshop_outputs.json', json.dumps(results, indent=2)), |
|
('slides.json', json.dumps(slides_json, indent=2)), |
|
('slides.html', slide_html), |
|
('code_labs.py', results.get('code_labs', '')) |
|
]: |
|
p = os.path.join(tmp, name) |
|
with open(p, 'w') as f: f.write(data) |
|
z.write(p, arcname=name) |
|
if audio_path and os.path.exists(audio_path): |
|
z.write(audio_path, arcname=os.path.basename(audio_path)) |
|
return slide_html, audio_path, zipf_path |
|
|
|
|
|
def run_app(topic, audience): |
|
slide_html, audio_path, zip_path = build_workshop_bundle(topic, audience) |
|
return slide_html, audio_path, zip_path |
|
|
|
with gr.Blocks(title='Workshop in a Box') as demo: |
|
gr.Markdown('# π Workshop in a Box') |
|
topic = gr.Textbox(label='Workshop Topic') |
|
audience = gr.Textbox(label='Audience') |
|
btn = gr.Button('Generate Workshop') |
|
slide_preview = gr.HTML() |
|
audio_player = gr.Audio(interactive=True) |
|
download = gr.File() |
|
btn.click(run_app, [topic, audience], [slide_preview, audio_player, download]) |
|
|
|
if __name__ == '__main__': |
|
demo.launch() |