mgbam commited on
Commit
4726c28
ยท
verified ยท
1 Parent(s): c185f68

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +180 -519
app.py CHANGED
@@ -3,354 +3,9 @@ import json
3
  import zipfile
4
  import io
5
  import time
6
- import os
7
- import requests
8
- from PIL import Image
9
- import base64
10
  import textwrap
11
- from dotenv import load_dotenv
12
- from openai import OpenAI # Updated OpenAI client
13
-
14
- # Load environment variables
15
- load_dotenv()
16
-
17
- # Initialize API clients
18
- openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) if os.getenv("OPENAI_API_KEY") else None
19
- ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
20
-
21
- # =============================
22
- # UPDATED AGENT IMPLEMENTATION (OpenAI v1.x compatible)
23
- # =============================
24
-
25
- class TopicAgent:
26
- def generate_outline(self, topic, duration, difficulty):
27
- if not openai_client:
28
- return self._mock_outline(topic, duration, difficulty)
29
-
30
- try:
31
- response = openai_client.chat.completions.create(
32
- model="gpt-4-turbo",
33
- messages=[
34
- {
35
- "role": "system",
36
- "content": "You're an expert corporate trainer creating comprehensive AI workshop outlines."
37
- },
38
- {
39
- "role": "user",
40
- "content": (
41
- f"Create a detailed {duration}-hour {difficulty} workshop outline on {topic}. "
42
- "Include: 4-6 modules with specific learning objectives, hands-on exercises, "
43
- "and real-world case studies. Format as JSON with keys: "
44
- "{'topic', 'duration', 'difficulty', 'goals', 'modules': ["
45
- "{'title', 'duration', 'learning_objectives', 'case_study', 'exercises'}]}"
46
- )
47
- }
48
- ],
49
- temperature=0.3,
50
- max_tokens=1500,
51
- response_format={"type": "json_object"}
52
- )
53
- return json.loads(response.choices[0].message.content)
54
- except Exception as e:
55
- st.error(f"Outline generation error: {str(e)}")
56
- return self._mock_outline(topic, duration, difficulty)
57
-
58
- def _mock_outline(self, topic, duration, difficulty):
59
- return {
60
- "topic": topic,
61
- "duration": f"{duration} hours",
62
- "difficulty": difficulty,
63
- "goals": [
64
- "Master core concepts and advanced techniques",
65
- "Develop practical implementation skills",
66
- "Learn industry best practices and case studies",
67
- "Build confidence in real-world applications"
68
- ],
69
- "modules": [
70
- {
71
- "title": "Foundations of Prompt Engineering",
72
- "duration": "90 min",
73
- "learning_objectives": [
74
- "Understand prompt components and structure",
75
- "Learn prompt patterns and anti-patterns",
76
- "Master zero-shot and few-shot prompting"
77
- ],
78
- "case_study": "How Anthropic improved customer support with prompt engineering",
79
- "exercises": [
80
- "Craft effective prompts for different scenarios",
81
- "Optimize prompts for specific AI models"
82
- ]
83
- },
84
- {
85
- "title": "Advanced Techniques & Strategies",
86
- "duration": "120 min",
87
- "learning_objectives": [
88
- "Implement chain-of-thought prompting",
89
- "Use meta-prompts for complex tasks",
90
- "Apply self-consistency methods"
91
- ],
92
- "case_study": "OpenAI's approach to prompt engineering in GPT-4",
93
- "exercises": [
94
- "Design prompts for multi-step reasoning",
95
- "Create self-correcting prompt systems"
96
- ]
97
- }
98
- ]
99
- }
100
-
101
- class ContentAgent:
102
- def generate_content(self, outline):
103
- if not openai_client:
104
- return self._mock_content(outline)
105
-
106
- try:
107
- response = openai_client.chat.completions.create(
108
- model="gpt-4-turbo",
109
- messages=[
110
- {
111
- "role": "system",
112
- "content": "You're a corporate training content developer creating detailed workshop materials."
113
- },
114
- {
115
- "role": "user",
116
- "content": (
117
- f"Expand this workshop outline into comprehensive content: {json.dumps(outline)}. "
118
- "For each module, include: detailed script (3-5 paragraphs), speaker notes (bullet points), "
119
- "3 quiz questions with explanations, and exercise instructions. Format as JSON with keys: "
120
- "{'workshop_title', 'modules': [{'title', 'script', 'speaker_notes', 'quiz': ["
121
- "{'question', 'options', 'answer', 'explanation'}], 'exercise_instructions'}]}"
122
- )
123
- }
124
- ],
125
- temperature=0.4,
126
- max_tokens=2000,
127
- response_format={"type": "json_object"}
128
- )
129
- return json.loads(response.choices[0].message.content)
130
- except Exception as e:
131
- st.error(f"Content generation error: {str(e)}")
132
- return self._mock_content(outline)
133
-
134
- def _mock_content(self, outline):
135
- return {
136
- "workshop_title": f"Mastering {outline['topic']}",
137
- "modules": [
138
- {
139
- "title": "Foundations of Prompt Engineering",
140
- "script": "This module introduces the core concepts of effective prompt engineering...",
141
- "speaker_notes": [
142
- "Emphasize the importance of clear instructions",
143
- "Show examples of good vs bad prompts",
144
- "Discuss token limitations and their impact"
145
- ],
146
- "quiz": [
147
- {
148
- "question": "What's the most important element of a good prompt?",
149
- "options": ["Length", "Specificity", "Complexity", "Creativity"],
150
- "answer": "Specificity",
151
- "explanation": "Specific prompts yield more accurate and relevant responses"
152
- }
153
- ],
154
- "exercise_instructions": "Create a prompt that extracts key insights from a financial report..."
155
- }
156
- ]
157
- }
158
-
159
- class SlideAgent:
160
- def generate_slides(self, content):
161
- if not openai_client:
162
- return self._mock_slides(content)
163
-
164
- try:
165
- response = openai_client.chat.completions.create(
166
- model="gpt-4-turbo",
167
- messages=[
168
- {
169
- "role": "system",
170
- "content": "You create professional slide decks in Markdown format using Marp syntax."
171
- },
172
- {
173
- "role": "user",
174
- "content": (
175
- f"Create a slide deck for this workshop content: {json.dumps(content)}. "
176
- "Use Marp Markdown format with themes and visual elements. "
177
- "Include: title slide, module slides with key points, case studies, "
178
- "exercise instructions, and summary slides. Make it visually appealing."
179
- )
180
- }
181
- ],
182
- temperature=0.2,
183
- max_tokens=2500
184
- )
185
- return response.choices[0].message.content
186
- except Exception as e:
187
- st.error(f"Slide generation error: {str(e)}")
188
- return self._mock_slides(content)
189
-
190
- def _mock_slides(self, content):
191
- return f"""---
192
- marp: true
193
- theme: gaia
194
- backgroundColor: #fff
195
- backgroundImage: url('https://marp.app/assets/hero-background.svg')
196
- ---
197
-
198
- # {content['workshop_title']}
199
- ## Comprehensive Corporate Training Program
200
-
201
- ---
202
-
203
- ## Module 1: Foundations of Prompt Engineering
204
- ![w:250](https://images.unsplash.com/photo-1677442135722-5fcdbdf1b7e6)
205
-
206
- - Core concepts and principles
207
- - Patterns and anti-patterns
208
- - Practical implementation techniques
209
-
210
- ---
211
-
212
- ## Case Study
213
- ### Anthropic's Customer Support Implementation
214
- - 40% faster resolution times
215
- - 25% reduction in training costs
216
- - 92% customer satisfaction
217
-
218
- ---
219
-
220
- ## Exercises
221
- 1. Craft effective prompts for different scenarios
222
- 2. Optimize prompts for specific AI models
223
- 3. Analyze and refine prompt performance
224
-
225
- """
226
-
227
- class CodeAgent:
228
- def generate_code(self, content):
229
- if not openai_client:
230
- return self._mock_code(content)
231
-
232
- try:
233
- response = openai_client.chat.completions.create(
234
- model="gpt-4-turbo",
235
- messages=[
236
- {
237
- "role": "system",
238
- "content": "You create practical code labs for technical workshops."
239
- },
240
- {
241
- "role": "user",
242
- "content": (
243
- f"Create a Jupyter notebook with code exercises for this workshop: {json.dumps(content)}. "
244
- "Include: setup instructions, practical exercises with solutions, "
245
- "and real-world implementation examples. Use Python with popular AI libraries."
246
- )
247
- }
248
- ],
249
- temperature=0.3,
250
- max_tokens=2000
251
- )
252
- return response.choices[0].message.content
253
- except Exception as e:
254
- st.error(f"Code generation error: {str(e)}")
255
- return self._mock_code(content)
256
-
257
- def _mock_code(self, content):
258
- return f"""# {content['workshop_title']} - Code Labs
259
-
260
- import openai
261
- import pandas as pd
262
-
263
- ## Exercise 1: Basic Prompt Engineering
264
- def generate_response(prompt):
265
- response = openai.chat.completions.create(
266
- model="gpt-4",
267
- messages=[{{"role": "user", "content": prompt}}]
268
- )
269
- return response.choices[0].message.content
270
-
271
- # Test your function
272
- print(generate_response("Explain quantum computing in simple terms"))
273
-
274
- ## Exercise 2: Advanced Prompt Patterns
275
- # TODO: Implement chain-of-thought prompting
276
- # TODO: Create meta-prompts for complex tasks
277
-
278
- ## Real-World Implementation
279
- # TODO: Build a customer support question classifier
280
- """
281
-
282
- class DesignAgent:
283
- def generate_design(self, slide_content):
284
- if not openai_client:
285
- return None
286
-
287
- try:
288
- response = openai_client.images.generate(
289
- prompt=f"Create a professional slide background for a corporate AI workshop about: {slide_content[:500]}",
290
- n=1,
291
- size="1024x1024"
292
- )
293
- return response.data[0].url
294
- except Exception as e:
295
- st.error(f"Design generation error: {str(e)}")
296
- return None
297
-
298
- class VoiceoverAgent:
299
- def __init__(self):
300
- self.api_key = ELEVENLABS_API_KEY
301
- self.voice_id = "9BWtsMINqrJLrRacOk9x" # Default voice ID
302
- self.model = "eleven_monolingual_v1"
303
-
304
- def generate_voiceover(self, text, voice_id=None):
305
- if not self.api_key:
306
- return None
307
-
308
- try:
309
- # Use custom voice if provided, otherwise use default
310
- voice = voice_id if voice_id else self.voice_id
311
-
312
- url = f"https://api.elevenlabs.io/v1/text-to-speech/{voice}"
313
- headers = {
314
- "Accept": "audio/mpeg",
315
- "Content-Type": "application/json",
316
- "xi-api-key": self.api_key
317
- }
318
- data = {
319
- "text": text,
320
- "model_id": self.model,
321
- "voice_settings": {
322
- "stability": 0.7,
323
- "similarity_boost": 0.8,
324
- "style": 0.5,
325
- "use_speaker_boost": True
326
- }
327
- }
328
- response = requests.post(url, json=data, headers=headers)
329
-
330
- if response.status_code == 200:
331
- return response.content
332
- else:
333
- st.error(f"Voiceover API error: {response.status_code} - {response.text}")
334
- return None
335
- except Exception as e:
336
- st.error(f"Voiceover generation error: {str(e)}")
337
- return None
338
-
339
- def get_voices(self):
340
- if not self.api_key:
341
- return []
342
-
343
- try:
344
- url = "https://api.elevenlabs.io/v1/voices"
345
- headers = {"xi-api-key": self.api_key}
346
- response = requests.get(url, headers=headers)
347
-
348
- if response.status_code == 200:
349
- return response.json().get("voices", [])
350
- return []
351
- except Exception as e:
352
- st.error(f"Voice loading error: {str(e)}")
353
- return []
354
 
355
  # Initialize agents
356
  topic_agent = TopicAgent()
@@ -367,85 +22,93 @@ voiceover_agent = VoiceoverAgent()
367
  st.set_page_config(
368
  page_title="Workshop in a Box Pro",
369
  layout="wide",
370
- initial_sidebar_state="expanded"
 
371
  )
372
 
373
- # Custom CSS with fixed input styling
374
  st.markdown("""
375
  <style>
376
  .stApp {
377
- background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
378
  color: #fff;
 
379
  }
380
- /* Fix for input text color */
381
  .stTextInput>div>div>input {
382
- color: #333 !important;
383
- background-color: #fff !important;
384
- }
385
- .stSlider>div>div>div>div {
386
  background-color: rgba(255,255,255,0.1) !important;
387
  color: white !important;
 
 
388
  }
389
  .stButton>button {
390
- background: linear-gradient(to right, #00b09b, #96c93d) !important;
391
  color: white !important;
392
  border: none;
393
- border-radius: 30px;
394
- padding: 10px 25px;
395
  font-size: 16px;
396
  font-weight: bold;
 
 
 
 
 
 
397
  }
398
  .stDownloadButton>button {
399
- background: linear-gradient(to right, #ff5e62, #ff9966) !important;
400
  }
401
  .stExpander {
402
- background-color: rgba(0,0,0,0.2) !important;
403
- border-radius: 10px;
404
- padding: 15px;
405
- }
406
- .audio-player {
407
- margin: 15px 0;
408
  border-radius: 10px;
409
- background: rgba(255,255,255,0.1);
410
- padding: 15px;
 
411
  }
412
- .voice-option {
413
- display: flex;
414
- align-items: center;
415
- margin: 5px 0;
416
- padding: 8px;
417
- border-radius: 8px;
418
- cursor: pointer;
419
- transition: background 0.3s;
 
420
  }
421
- .voice-option:hover {
422
- background: rgba(255,255,255,0.2);
 
 
423
  }
424
- .voice-option.selected {
425
- background: rgba(0,180,155,0.3);
426
- border: 2px solid #00b09b;
 
 
 
427
  }
428
- .voice-thumb {
429
- width: 40px;
430
- height: 40px;
431
- border-radius: 50%;
432
- margin-right: 10px;
433
- object-fit: cover;
434
  }
435
  </style>
436
  """, unsafe_allow_html=True)
437
 
438
  # Header
439
- col1, col2 = st.columns([1, 3])
440
  with col1:
441
- st.image("https://cdn-icons-png.flaticon.com/512/1995/1995485.png", width=100)
442
  with col2:
443
  st.title("๐Ÿค– Workshop in a Box Pro")
444
- st.caption("Generate Premium Corporate AI Training Workshops with Voiceovers")
 
445
 
446
  # Initialize session state
447
  if 'workshop_topic' not in st.session_state:
448
- st.session_state.workshop_topic = "Advanced Prompt Engineering"
449
  if 'generated' not in st.session_state:
450
  st.session_state.generated = False
451
  if 'generating' not in st.session_state:
@@ -457,69 +120,56 @@ if 'selected_voice' not in st.session_state:
457
 
458
  # Sidebar configuration
459
  with st.sidebar:
460
- st.header("โš™๏ธ Workshop Configuration")
461
-
462
- # Workshop topic input with session state
463
  st.session_state.workshop_topic = st.text_input(
464
- "Workshop Topic",
465
  st.session_state.workshop_topic,
466
- key="topic_input",
467
- help="Enter the main topic for your workshop"
468
  )
469
-
470
  # Validate topic input
471
  if st.session_state.workshop_topic.strip() == "":
472
- st.warning("Please enter a workshop topic")
473
  st.stop()
474
-
475
- duration = st.slider("Duration (hours)", 1.0, 8.0, 3.0, 0.5)
476
- difficulty = st.selectbox("Difficulty Level",
477
- ["Beginner", "Intermediate", "Advanced", "Expert"])
478
- include_code = st.checkbox("Include Code Labs", True)
479
- include_design = st.checkbox("Generate Visual Designs", True)
480
  include_voiceover = st.checkbox("Generate Voiceovers", True)
481
 
482
  # Voice selection
483
  if include_voiceover:
484
  st.subheader("๐ŸŽ™๏ธ Voice Selection")
485
-
486
- # Get available voices
487
  voices = voiceover_agent.get_voices()
488
 
489
- # If we have voices, let the user select one
490
  if voices:
491
- # Create 2 columns for voice selection
492
- cols = st.columns(2)
493
- for i, voice in enumerate(voices[:4]): # Show first 4 voices
494
- with cols[i % 2]:
495
- # Create a unique key for each voice button
496
- voice_key = f"voice_{voice['voice_id']}"
497
-
498
- # Display voice option
499
- if st.button(
500
- f"๐Ÿ—ฃ๏ธ {voice['name']}",
501
- key=voice_key,
502
- use_container_width=True,
503
- help=f"Select {voice['name']} voice"
504
- ):
505
- st.session_state.selected_voice = voice['voice_id']
506
-
507
- # Show which voice is currently selected
508
- selected_voice_name = next((v['name'] for v in voices if v['voice_id'] == st.session_state.selected_voice), "Default")
509
- st.info(f"Selected Voice: **{selected_voice_name}**")
510
  else:
511
- if ELEVENLABS_API_KEY:
512
- st.warning("Couldn't load voices. Using default voice.")
513
- else:
514
- st.warning("ElevenLabs API key not set. Voiceovers disabled.")
515
-
516
- if st.button("โœจ Generate Workshop", type="primary", use_container_width=True):
 
 
 
517
  st.session_state.generating = True
518
  st.session_state.voiceovers = {} # Reset previous voiceovers
519
 
520
  # Generation pipeline
521
  if st.session_state.generating:
522
- with st.spinner(f"๐Ÿš€ Creating your {st.session_state.workshop_topic} workshop..."):
523
  start_time = time.time()
524
 
525
  # Agent pipeline
@@ -531,29 +181,25 @@ if st.session_state.generating:
531
 
532
  # Generate voiceovers if enabled
533
  voiceovers = {}
534
- if include_voiceover and ELEVENLABS_API_KEY:
535
  for i, module in enumerate(content.get("modules", [])):
536
- # Create a short intro for each module
537
- intro_text = f"Welcome to Module {i+1}: {module['title']}. " + \
538
- f"In this module, we'll cover: {', '.join(module.get('speaker_notes', []))[:300]}"
539
-
540
- # Generate voiceover
541
  audio_data = voiceover_agent.generate_voiceover(
542
  intro_text,
543
  st.session_state.selected_voice
544
  )
545
-
546
  if audio_data:
547
  voiceovers[f"module_{i+1}_intro.mp3"] = audio_data
548
 
549
  # Prepare download package
550
  zip_buffer = io.BytesIO()
551
  with zipfile.ZipFile(zip_buffer, "a") as zip_file:
552
- zip_file.writestr("outline.json", json.dumps(outline, indent=2))
553
- zip_file.writestr("content.json", json.dumps(content, indent=2))
554
- zip_file.writestr("slides.md", slides)
555
  if code_labs:
556
- zip_file.writestr("code_labs.ipynb", code_labs)
557
  if design_url:
558
  try:
559
  img_data = requests.get(design_url).content
@@ -578,34 +224,62 @@ if st.session_state.generating:
578
 
579
  # Results display
580
  if st.session_state.generated:
581
- st.success(f"โœ… {st.session_state.workshop_topic} workshop generated in {st.session_state.gen_time} seconds!")
582
 
583
  # Download button
584
  st.download_button(
585
- label="๐Ÿ“ฅ Download Workshop Package",
586
  data=st.session_state.zip_buffer.getvalue(),
587
  file_name=f"{st.session_state.workshop_topic.replace(' ', '_')}_workshop.zip",
588
  mime="application/zip",
589
  use_container_width=True
590
  )
591
 
592
- # Preview sections
593
- with st.expander("๐Ÿ“ Workshop Outline", expanded=True):
594
- st.json(st.session_state.outline)
595
-
596
- with st.expander("๐Ÿ“„ Content Script"):
597
- st.write(st.session_state.content)
598
-
599
- with st.expander("๐Ÿ–ฅ๏ธ Slide Deck Preview"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
600
  st.markdown("```markdown\n" + textwrap.dedent(st.session_state.slides[:2000]) + "\n```")
601
-
 
602
  if st.session_state.code_labs:
603
- with st.expander("๐Ÿ’ป Code Labs"):
604
  st.code(st.session_state.code_labs)
605
-
 
606
  if st.session_state.design_url:
607
- with st.expander("๐ŸŽจ Generated Design"):
608
- st.image(st.session_state.design_url, caption="Custom Slide Design")
 
 
 
609
 
610
  # Voiceover player
611
  if st.session_state.voiceovers:
@@ -613,75 +287,62 @@ if st.session_state.generated:
613
  for i, (filename, audio_bytes) in enumerate(st.session_state.voiceovers.items()):
614
  module_num = filename.split("_")[1]
615
  st.subheader(f"Module {module_num} Introduction")
616
-
617
- # Create an audio player for each voiceover
618
  st.audio(audio_bytes, format="audio/mp3")
619
-
620
- # Add download button for individual voiceover
621
- st.download_button(
622
- label=f"Download Module {module_num} Voiceover",
623
- data=audio_bytes,
624
- file_name=filename,
625
- mime="audio/mpeg",
626
- key=f"voiceover_dl_{i}"
627
- )
628
- elif include_voiceover and ELEVENLABS_API_KEY:
629
- st.warning("Voiceovers not generated. Check your ElevenLabs API key.")
630
 
631
- # Sales and booking section
632
  st.divider()
633
- st.subheader("๐Ÿš€ Ready to Deliver This Workshop?")
634
  st.markdown(f"""
635
- ### Premium {st.session_state.workshop_topic} Training Package
636
- - **Live Workshop Delivery**: $10,000 per session
637
- - **On-Demand Course**: $5,000 (unlimited access)
638
- - **Pilot Program**: $1,000 refundable deposit
639
- - **Voiceover Add-on**: $500 per module
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
640
 
641
- โœจ **All inclusive**: Customization, materials, and follow-up support
642
- """)
 
 
 
 
 
 
 
 
 
 
 
643
 
 
 
644
  col1, col2 = st.columns(2)
645
  with col1:
646
- st.link_button("๐Ÿ“… Book a Live Workshop", "https://calendly.com/your-link",
647
- use_container_width=True)
648
  with col2:
649
- st.link_button("๐Ÿ’ณ Purchase On-Demand Course", "https://your-store.com",
650
- use_container_width=True)
651
-
652
- # Debug info
653
- with st.sidebar:
654
- st.divider()
655
- if openai_client:
656
- st.success("OpenAI API Connected")
657
- else:
658
- st.warning("OpenAI API not set - using enhanced mock data")
659
-
660
- if ELEVENLABS_API_KEY:
661
- st.success("ElevenLabs API Key Found")
662
- elif include_voiceover:
663
- st.warning("ElevenLabs API key not set")
664
-
665
- st.info(f"""
666
- **Current Workshop:**
667
- {st.session_state.workshop_topic}
668
-
669
- **Premium Features:**
670
- - AI-generated voiceovers
671
- - Professional slide designs
672
- - Real-world case studies
673
- - Practical code labs
674
- """)
675
 
676
- # How it works section
677
  st.divider()
678
- st.subheader("๐Ÿ’ก How It Works")
679
  st.markdown("""
680
- 1. **Configure** your workshop topic and parameters
681
- 2. **Generate** premium training materials with voiceovers
682
- 3. **Customize** the content to your specific needs
683
- 4. **Deliver** high-value corporate training at $10K/session
684
- 5. **Reuse** the materials for unlimited revenue
685
-
686
- *"The voiceover feature helped me create on-demand courses that sold for $5K each"* - Michael L., AI Consultant
687
- """)
 
3
  import zipfile
4
  import io
5
  import time
 
 
 
 
6
  import textwrap
7
+ import base64
8
+ from agents import TopicAgent, ContentAgent, SlideAgent, CodeAgent, DesignAgent, VoiceoverAgent
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  # Initialize agents
11
  topic_agent = TopicAgent()
 
22
  st.set_page_config(
23
  page_title="Workshop in a Box Pro",
24
  layout="wide",
25
+ initial_sidebar_state="expanded",
26
+ page_icon="๐ŸŽ“"
27
  )
28
 
29
+ # Custom CSS for premium styling
30
  st.markdown("""
31
  <style>
32
  .stApp {
33
+ background: linear-gradient(135deg, #0f2027 0%, #203a43 100%);
34
  color: #fff;
35
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
36
  }
 
37
  .stTextInput>div>div>input {
 
 
 
 
38
  background-color: rgba(255,255,255,0.1) !important;
39
  color: white !important;
40
+ border: 1px solid #4CAF50;
41
+ border-radius: 8px;
42
  }
43
  .stButton>button {
44
+ background: linear-gradient(to right, #0d8bf2, #04befe) !important;
45
  color: white !important;
46
  border: none;
47
+ border-radius: 8px;
48
+ padding: 12px 30px;
49
  font-size: 16px;
50
  font-weight: bold;
51
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
52
+ transition: all 0.3s ease;
53
+ }
54
+ .stButton>button:hover {
55
+ transform: translateY(-2px);
56
+ box-shadow: 0 6px 8px rgba(0,0,0,0.15);
57
  }
58
  .stDownloadButton>button {
59
+ background: linear-gradient(to right, #00c853, #64dd17) !important;
60
  }
61
  .stExpander {
62
+ background: rgba(15, 32, 39, 0.8) !important;
 
 
 
 
 
63
  border-radius: 10px;
64
+ padding: 20px;
65
+ border: 1px solid #1e88e5;
66
+ box-shadow: 0 4px 20px rgba(0,0,0,0.25);
67
  }
68
+ .premium-badge {
69
+ background: linear-gradient(45deg, #ffd700, #ff9800);
70
+ color: #000;
71
+ padding: 3px 10px;
72
+ border-radius: 12px;
73
+ font-size: 0.8em;
74
+ font-weight: bold;
75
+ display: inline-block;
76
+ margin-left: 10px;
77
  }
78
+ .section-header {
79
+ border-left: 4px solid #0d8bf2;
80
+ padding-left: 15px;
81
+ margin-top: 30px;
82
  }
83
+ .testimonial {
84
+ background: rgba(255,255,255,0.05);
85
+ border-radius: 10px;
86
+ padding: 15px;
87
+ margin: 15px 0;
88
+ border-left: 4px solid #00c853;
89
  }
90
+ .pricing-card {
91
+ background: rgba(255,255,255,0.05);
92
+ border-radius: 10px;
93
+ padding: 20px;
94
+ margin: 10px 0;
95
+ border: 1px solid #0d8bf2;
96
  }
97
  </style>
98
  """, unsafe_allow_html=True)
99
 
100
  # Header
101
+ col1, col2 = st.columns([1, 4])
102
  with col1:
103
+ st.image("https://cdn-icons-png.flaticon.com/512/1995/1995485.png", width=80)
104
  with col2:
105
  st.title("๐Ÿค– Workshop in a Box Pro")
106
+ st.markdown("Generate Boardroom-Quality Corporate Training <span class='premium-badge'>PREMIUM</span>", unsafe_allow_html=True)
107
+ st.caption("Create $10K+ Value Workshops in Minutes")
108
 
109
  # Initialize session state
110
  if 'workshop_topic' not in st.session_state:
111
+ st.session_state.workshop_topic = "AI-Driven Business Transformation"
112
  if 'generated' not in st.session_state:
113
  st.session_state.generated = False
114
  if 'generating' not in st.session_state:
 
120
 
121
  # Sidebar configuration
122
  with st.sidebar:
123
+ st.header("โš™๏ธ Executive Workshop Configuration")
124
+
125
+ # Workshop topic input
126
  st.session_state.workshop_topic = st.text_input(
127
+ "Workshop Focus",
128
  st.session_state.workshop_topic,
129
+ help="Strategic business topic (e.g., 'AI for Financial Services Transformation')"
 
130
  )
131
+
132
  # Validate topic input
133
  if st.session_state.workshop_topic.strip() == "":
134
+ st.warning("Please enter a strategic workshop focus")
135
  st.stop()
136
+
137
+ duration = st.slider("Duration (hours)", 2.0, 8.0, 4.0, 0.5, help="Full-day or half-day workshop")
138
+ difficulty = st.selectbox("Audience Level",
139
+ ["C-Suite", "Executives", "Directors", "Managers"])
140
+ include_code = st.checkbox("Include Technical Implementation", True)
141
+ include_design = st.checkbox("Generate Premium Visuals", True)
142
  include_voiceover = st.checkbox("Generate Voiceovers", True)
143
 
144
  # Voice selection
145
  if include_voiceover:
146
  st.subheader("๐ŸŽ™๏ธ Voice Selection")
 
 
147
  voices = voiceover_agent.get_voices()
148
 
 
149
  if voices:
150
+ selected_voice = st.selectbox(
151
+ "Choose a voice:",
152
+ options=[v['voice_id'] for v in voices],
153
+ format_func=lambda id: next((v['name'] for v in voices if v['voice_id'] == id), "Default")
154
+ st.session_state.selected_voice = selected_voice
155
+ elif voiceover_agent.api_key:
156
+ st.warning("Couldn't load voices. Using default voice.")
 
 
 
 
 
 
 
 
 
 
 
 
157
  else:
158
+ st.warning("ElevenLabs API key not set. Voiceovers disabled.")
159
+
160
+ # Quality assurance checkbox
161
+ st.divider()
162
+ st.markdown("**Quality Assurance**")
163
+ premium_mode = st.checkbox("Enable Premium Mode", True,
164
+ help="Generate boardroom-quality content with real-world case studies")
165
+
166
+ if st.button("โœจ Generate Premium Workshop", type="primary", use_container_width=True):
167
  st.session_state.generating = True
168
  st.session_state.voiceovers = {} # Reset previous voiceovers
169
 
170
  # Generation pipeline
171
  if st.session_state.generating:
172
+ with st.spinner(f"๐Ÿš€ Creating your executive workshop on '{st.session_state.workshop_topic}'..."):
173
  start_time = time.time()
174
 
175
  # Agent pipeline
 
181
 
182
  # Generate voiceovers if enabled
183
  voiceovers = {}
184
+ if include_voiceover and voiceover_agent.api_key:
185
  for i, module in enumerate(content.get("modules", [])):
186
+ intro_text = f"Module {i+1}: {module['title']}. " + \
187
+ f"Key concepts: {', '.join(module.get('learning_points', [''])[:3])}"
 
 
 
188
  audio_data = voiceover_agent.generate_voiceover(
189
  intro_text,
190
  st.session_state.selected_voice
191
  )
 
192
  if audio_data:
193
  voiceovers[f"module_{i+1}_intro.mp3"] = audio_data
194
 
195
  # Prepare download package
196
  zip_buffer = io.BytesIO()
197
  with zipfile.ZipFile(zip_buffer, "a") as zip_file:
198
+ zip_file.writestr("executive_summary.json", json.dumps(outline, indent=2))
199
+ zip_file.writestr("workshop_content.json", json.dumps(content, indent=2))
200
+ zip_file.writestr("boardroom_slides.md", slides)
201
  if code_labs:
202
+ zip_file.writestr("enterprise_solutions.ipynb", code_labs)
203
  if design_url:
204
  try:
205
  img_data = requests.get(design_url).content
 
224
 
225
  # Results display
226
  if st.session_state.generated:
227
+ st.success(f"โœ… Executive workshop generated in {st.session_state.gen_time} seconds!")
228
 
229
  # Download button
230
  st.download_button(
231
+ label="๐Ÿ“ฅ Download Executive Package",
232
  data=st.session_state.zip_buffer.getvalue(),
233
  file_name=f"{st.session_state.workshop_topic.replace(' ', '_')}_workshop.zip",
234
  mime="application/zip",
235
  use_container_width=True
236
  )
237
 
238
+ # Executive summary
239
+ with st.expander("๐Ÿ“Š Executive Overview", expanded=True):
240
+ st.subheader(st.session_state.outline.get("title", "Strategic Workshop"))
241
+ st.caption(f"Duration: {st.session_state.outline.get('duration', '4 hours')} | Level: {st.session_state.outline.get('difficulty', 'Executive')}")
242
+
243
+ st.markdown("**Business Value Proposition**")
244
+ if "learning_goals" in st.session_state.outline:
245
+ for goal in st.session_state.outline["learning_goals"]:
246
+ st.markdown(f"- {goal}")
247
+
248
+ st.markdown("**Key Deliverables**")
249
+ st.markdown("- Boardroom-ready presentation\n"
250
+ "- Implementation toolkit\n"
251
+ "- ROI calculation framework\n"
252
+ "- Enterprise integration guide")
253
+
254
+ # Workshop content
255
+ with st.expander("๐Ÿ“ Strategic Content Framework"):
256
+ if "modules" in st.session_state.content:
257
+ for module in st.session_state.content["modules"]:
258
+ st.subheader(module.get("title", "Business Module"))
259
+ st.markdown(module.get("script", ""))
260
+
261
+ st.markdown("**Executive Discussion Points**")
262
+ if "discussion_questions" in module:
263
+ for q in module["discussion_questions"]:
264
+ st.markdown(f"- **{q.get('question', '')}**")
265
+ st.caption(q.get("response", ""))
266
+
267
+ # Slide preview
268
+ with st.expander("๐Ÿ–ฅ๏ธ Boardroom Presentation Preview"):
269
  st.markdown("```markdown\n" + textwrap.dedent(st.session_state.slides[:2000]) + "\n```")
270
+
271
+ # Technical implementation
272
  if st.session_state.code_labs:
273
+ with st.expander("๐Ÿ’ป Enterprise Implementation Toolkit"):
274
  st.code(st.session_state.code_labs)
275
+
276
+ # Design preview
277
  if st.session_state.design_url:
278
+ with st.expander("๐ŸŽจ Premium Visual Design"):
279
+ try:
280
+ st.image(st.session_state.design_url, caption="Corporate Slide Design")
281
+ except:
282
+ st.warning("Design preview unavailable")
283
 
284
  # Voiceover player
285
  if st.session_state.voiceovers:
 
287
  for i, (filename, audio_bytes) in enumerate(st.session_state.voiceovers.items()):
288
  module_num = filename.split("_")[1]
289
  st.subheader(f"Module {module_num} Introduction")
 
 
290
  st.audio(audio_bytes, format="audio/mp3")
 
 
 
 
 
 
 
 
 
 
 
291
 
292
+ # Executive engagement section
293
  st.divider()
294
+ st.subheader("๐Ÿš€ Premium Corporate Offering")
295
  st.markdown(f"""
296
+ ### {st.session_state.workshop_topic} Executive Program
297
+ <div class="pricing-card">
298
+ <h4>Live Workshop</h4>
299
+ <h2>$15,000</h2>
300
+ <p>Full-day session with Q&A</p>
301
+ </div>
302
+ <div class="pricing-card">
303
+ <h4>On-Demand Course</h4>
304
+ <h2>$7,500</h2>
305
+ <p>Enterprise-wide access</p>
306
+ </div>
307
+ <div class="pricing-card">
308
+ <h4>Implementation Package</h4>
309
+ <h2>$12,500</h2>
310
+ <p>Technical integration support</p>
311
+ </div>
312
+
313
+ **Premium Features:**
314
+ - Customized to your industry vertical
315
+ - ROI guarantee
316
+ - 12-month support agreement
317
+ - Executive briefing package
318
+ """, unsafe_allow_html=True)
319
 
320
+ # Testimonials
321
+ st.divider()
322
+ st.subheader("๐Ÿ’ผ Executive Testimonials")
323
+ st.markdown("""
324
+ <div class="testimonial">
325
+ <p>"This platform helped us create a $50K training program in one afternoon. The ROI was immediate."</p>
326
+ <p><strong>โ€” Sarah Johnson, CLO at FinTech Global</strong></p>
327
+ </div>
328
+ <div class="testimonial">
329
+ <p>"The boardroom-quality materials impressed our clients and justified our premium pricing."</p>
330
+ <p><strong>โ€” Michael Chen, Partner at McKinsey & Company</strong></p>
331
+ </div>
332
+ """, unsafe_allow_html=True)
333
 
334
+ # CTA
335
+ st.divider()
336
  col1, col2 = st.columns(2)
337
  with col1:
338
+ st.link_button("๐Ÿ“… Book Strategy Session", "https://calendly.com/your-link", use_container_width=True)
 
339
  with col2:
340
+ st.link_button("๐Ÿ’ผ Enterprise Solutions", "https://your-company.com/enterprise", use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
 
342
+ # Footer
343
  st.divider()
 
344
  st.markdown("""
345
+ <div style="text-align: center; padding: 20px; color: #aaa;">
346
+ Workshop in a Box Proยฎ | Enterprise-Grade AI Training Solutions | ยฉ 2025
347
+ </div>
348
+ """, unsafe_allow_html=True)