File size: 4,213 Bytes
9fef5b9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
## 1. `app.py`
```python
# app.py: Workshop-in-a-Box Hugging Face Space with TTS and Slide Previews
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

# Import your TTS/voice API module
from your_tts_module import generate_tts_audio  # implement to return path to .mp3/.wav

# --- Multi-Agent Scaffold ---
# 1. Topic Agent
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."
    )
)

# 2. Content Agent
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."
    )
)

# 3. Slide Agent
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."
    )
)

# 4. Code Agent
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."
    )
)

# 5. Voiceover Agent (Optional)
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'."
    )
)

# Orchestrator: sequences agents
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()

# --- Helper: Run pipeline and create outputs ---
def build_workshop_bundle(topic: str, audience: str):
    prompt = f"Create a {topic} workshop for {audience}."
    results = runner.run(document_orchestrator, prompt).outputs

    # TTS audio
    voice_info = results.get('voiceover', {})
    audio_path = None
    if 'script' in voice_info:
        audio_path = generate_tts_audio(voice_info['script'])

    # Render slides to HTML
    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))

    # Create ZIP
    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

# --- Gradio UI ---
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()