Navada25 commited on
Commit
beb208c
·
verified ·
1 Parent(s): cf39b2a

Update startup_coach_personas.py - Voice Streaming & AI Coaching Features

Browse files
Files changed (1) hide show
  1. startup_coach_personas.py +654 -0
startup_coach_personas.py ADDED
@@ -0,0 +1,654 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ AI-Powered Startup Coach Personas for NAVADA
3
+ Provides specialized coaching expertise across different startup domains
4
+ """
5
+
6
+ import json
7
+ import logging
8
+ import random
9
+ from typing import Dict, Any, List, Optional
10
+ from datetime import datetime
11
+ import openai
12
+ from openai import AsyncOpenAI
13
+ import os
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+ class StartupCoachPersonas:
18
+ """Manages AI-powered startup coaching personas with specialized expertise"""
19
+
20
+ def __init__(self):
21
+ self.client = AsyncOpenAI(api_key=os.getenv("OPENAI_API_KEY"))
22
+ self.current_session = None
23
+ self.persona_history = {}
24
+
25
+ def get_available_personas(self) -> Dict[str, Dict[str, Any]]:
26
+ """Get all available coaching personas with their specializations"""
27
+ return {
28
+ "sarah_strategic": {
29
+ "name": "Sarah Chen - Strategic Advisor",
30
+ "expertise": ["Business Strategy", "Market Entry", "Competitive Analysis", "Growth Planning"],
31
+ "background": "Former McKinsey consultant, 3 successful exits as startup founder",
32
+ "personality": "Analytical, direct, strategic thinker",
33
+ "speaking_style": "Data-driven with real-world examples",
34
+ "avatar": "👩‍💼",
35
+ "color": "#4F46E5"
36
+ },
37
+ "marcus_technical": {
38
+ "name": "Marcus Rodriguez - CTO Advisor",
39
+ "expertise": ["Technical Architecture", "MVP Development", "Tech Stack Selection", "Scalability"],
40
+ "background": "Ex-Google Principal Engineer, built platforms for 100M+ users",
41
+ "personality": "Pragmatic, detail-oriented, solution-focused",
42
+ "speaking_style": "Technical but accessible, focuses on implementation",
43
+ "avatar": "👨‍💻",
44
+ "color": "#059669"
45
+ },
46
+ "elena_financial": {
47
+ "name": "Elena Thompson - Finance Expert",
48
+ "expertise": ["Financial Modeling", "Fundraising", "Valuation", "Unit Economics"],
49
+ "background": "Former VC Partner at Sequoia, CFO at 2 unicorns",
50
+ "personality": "Meticulous, numbers-focused, investor mindset",
51
+ "speaking_style": "Precise financial language with clear metrics",
52
+ "avatar": "👩‍💰",
53
+ "color": "#DC2626"
54
+ },
55
+ "david_marketing": {
56
+ "name": "David Kim - Growth Hacker",
57
+ "expertise": ["Customer Acquisition", "Product Marketing", "Growth Strategies", "User Retention"],
58
+ "background": "VP Growth at Airbnb, scaled 3 startups from 0 to 10M users",
59
+ "personality": "Creative, experimental, customer-obsessed",
60
+ "speaking_style": "Energetic with growth hacks and case studies",
61
+ "avatar": "👨‍🚀",
62
+ "color": "#7C3AED"
63
+ },
64
+ "lisa_legal": {
65
+ "name": "Lisa Johnson - Legal & Compliance",
66
+ "expertise": ["Corporate Structure", "IP Protection", "Regulatory Compliance", "Contracts"],
67
+ "background": "Former startup lawyer at Wilson Sonsini, in-house counsel at Meta",
68
+ "personality": "Thorough, risk-aware, protective",
69
+ "speaking_style": "Clear legal guidance with practical implications",
70
+ "avatar": "👩‍⚖️",
71
+ "color": "#0891B2"
72
+ },
73
+ "alex_operations": {
74
+ "name": "Alex Chen - Operations Guru",
75
+ "expertise": ["Operations Scaling", "Process Optimization", "Team Building", "Efficiency"],
76
+ "background": "COO at 3 successful startups, operations consultant",
77
+ "personality": "Systematic, efficiency-focused, team-oriented",
78
+ "speaking_style": "Process-driven with actionable frameworks",
79
+ "avatar": "👨‍🔧",
80
+ "color": "#EA580C"
81
+ }
82
+ }
83
+
84
+ async def initialize_coaching_session(self, persona_id: str, startup_context: Dict[str, Any]) -> Dict[str, Any]:
85
+ """Initialize a coaching session with a specific persona"""
86
+ try:
87
+ personas = self.get_available_personas()
88
+ if persona_id not in personas:
89
+ return {"status": "error", "message": "Invalid persona ID"}
90
+
91
+ persona = personas[persona_id]
92
+
93
+ # Create coaching session context
94
+ session_id = f"session_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{persona_id}"
95
+
96
+ self.current_session = {
97
+ "session_id": session_id,
98
+ "persona_id": persona_id,
99
+ "persona": persona,
100
+ "startup_context": startup_context,
101
+ "conversation_history": [],
102
+ "created_at": datetime.now().isoformat(),
103
+ "focus_areas": [],
104
+ "action_items": []
105
+ }
106
+
107
+ # Initialize persona history if not exists
108
+ if persona_id not in self.persona_history:
109
+ self.persona_history[persona_id] = []
110
+
111
+ return {
112
+ "status": "success",
113
+ "session_id": session_id,
114
+ "persona": persona,
115
+ "welcome_message": await self._generate_welcome_message(persona, startup_context)
116
+ }
117
+
118
+ except Exception as e:
119
+ logger.error(f"Error initializing coaching session: {e}")
120
+ return {"status": "error", "message": str(e)}
121
+
122
+ async def _generate_welcome_message(self, persona: Dict[str, Any], startup_context: Dict[str, Any]) -> str:
123
+ """Generate personalized welcome message from the persona"""
124
+ try:
125
+ system_prompt = f"""
126
+ You are {persona['name']}, a startup advisor with expertise in {', '.join(persona['expertise'])}.
127
+
128
+ Background: {persona['background']}
129
+ Personality: {persona['personality']}
130
+ Speaking Style: {persona['speaking_style']}
131
+
132
+ Generate a warm, personalized welcome message for this startup founder. Keep it under 150 words.
133
+ Be specific about how you can help based on your expertise and their startup context.
134
+ """
135
+
136
+ user_prompt = f"""
137
+ Startup Context:
138
+ - Industry: {startup_context.get('industry', 'Not specified')}
139
+ - Stage: {startup_context.get('stage', 'Idea stage')}
140
+ - Team Size: {startup_context.get('team_size', 'Solo founder')}
141
+ - Current Challenge: {startup_context.get('current_challenge', 'General guidance needed')}
142
+ - Brief Description: {startup_context.get('description', 'Early stage startup')}
143
+
144
+ Generate a welcome message that shows you understand their situation and how you can specifically help.
145
+ """
146
+
147
+ response = await self.client.chat.completions.create(
148
+ model="gpt-4",
149
+ messages=[
150
+ {"role": "system", "content": system_prompt},
151
+ {"role": "user", "content": user_prompt}
152
+ ],
153
+ max_tokens=200,
154
+ temperature=0.7
155
+ )
156
+
157
+ return response.choices[0].message.content
158
+
159
+ except Exception as e:
160
+ logger.error(f"Error generating welcome message: {e}")
161
+ return f"Hi! I'm {persona['name']}. I'm excited to help you with your startup journey!"
162
+
163
+ async def get_coaching_advice(self, query: str, context: Dict[str, Any] = None) -> Dict[str, Any]:
164
+ """Get specialized coaching advice from the current persona"""
165
+ try:
166
+ if not self.current_session:
167
+ return {"status": "error", "message": "No active coaching session"}
168
+
169
+ persona = self.current_session["persona"]
170
+ startup_context = self.current_session["startup_context"]
171
+
172
+ # Build conversation context
173
+ conversation_history = self.current_session["conversation_history"][-5:] # Last 5 exchanges
174
+
175
+ system_prompt = f"""
176
+ You are {persona['name']}, a startup advisor specializing in {', '.join(persona['expertise'])}.
177
+
178
+ Background: {persona['background']}
179
+ Personality: {persona['personality']}
180
+ Speaking Style: {persona['speaking_style']}
181
+
182
+ Provide specific, actionable advice based on your expertise. Always include:
183
+ 1. Direct answer to their question
184
+ 2. Specific next steps
185
+ 3. Potential risks/considerations
186
+ 4. Resources or tools to help
187
+
188
+ Keep responses focused and under 300 words unless complex analysis is needed.
189
+ """
190
+
191
+ # Prepare context for the AI
192
+ context_text = f"""
193
+ Startup Context:
194
+ {json.dumps(startup_context, indent=2)}
195
+
196
+ Previous Conversation:
197
+ {json.dumps(conversation_history, indent=2) if conversation_history else "None"}
198
+
199
+ Current Question: {query}
200
+ """
201
+
202
+ if context:
203
+ context_text += f"\nAdditional Context: {json.dumps(context, indent=2)}"
204
+
205
+ response = await self.client.chat.completions.create(
206
+ model="gpt-4",
207
+ messages=[
208
+ {"role": "system", "content": system_prompt},
209
+ {"role": "user", "content": context_text}
210
+ ],
211
+ max_tokens=500,
212
+ temperature=0.7
213
+ )
214
+
215
+ advice = response.choices[0].message.content
216
+
217
+ # Update conversation history
218
+ self.current_session["conversation_history"].append({
219
+ "timestamp": datetime.now().isoformat(),
220
+ "query": query,
221
+ "advice": advice,
222
+ "context": context
223
+ })
224
+
225
+ # Extract action items if any
226
+ action_items = await self._extract_action_items(advice)
227
+ if action_items:
228
+ self.current_session["action_items"].extend(action_items)
229
+
230
+ return {
231
+ "status": "success",
232
+ "advice": advice,
233
+ "persona": persona["name"],
234
+ "expertise_areas": persona["expertise"],
235
+ "action_items": action_items,
236
+ "session_id": self.current_session["session_id"]
237
+ }
238
+
239
+ except Exception as e:
240
+ logger.error(f"Error getting coaching advice: {e}")
241
+ return {"status": "error", "message": str(e)}
242
+
243
+ async def _extract_action_items(self, advice_text: str) -> List[str]:
244
+ """Extract actionable items from coaching advice"""
245
+ try:
246
+ system_prompt = """
247
+ Extract specific, actionable items from this coaching advice.
248
+ Return only concrete next steps the founder should take.
249
+ Format as a JSON list of strings.
250
+ If no clear action items, return empty list.
251
+ """
252
+
253
+ response = await self.client.chat.completions.create(
254
+ model="gpt-3.5-turbo",
255
+ messages=[
256
+ {"role": "system", "content": system_prompt},
257
+ {"role": "user", "content": advice_text}
258
+ ],
259
+ max_tokens=200,
260
+ temperature=0.3
261
+ )
262
+
263
+ result = response.choices[0].message.content
264
+ try:
265
+ return json.loads(result)
266
+ except json.JSONDecodeError:
267
+ return []
268
+
269
+ except Exception as e:
270
+ logger.error(f"Error extracting action items: {e}")
271
+ return []
272
+
273
+ async def get_persona_handoff_recommendation(self, current_query: str) -> Dict[str, Any]:
274
+ """Recommend which persona would be best suited for the current query"""
275
+ try:
276
+ personas = self.get_available_personas()
277
+
278
+ system_prompt = """
279
+ Analyze the user's query and recommend the most suitable startup advisor persona.
280
+ Consider the expertise areas and which advisor would provide the most valuable insights.
281
+
282
+ Return your recommendation as JSON with:
283
+ {
284
+ "recommended_persona": "persona_id",
285
+ "confidence": 0.8,
286
+ "reasoning": "Why this persona is best suited",
287
+ "alternative": "backup_persona_id"
288
+ }
289
+ """
290
+
291
+ personas_info = {pid: {"name": p["name"], "expertise": p["expertise"]}
292
+ for pid, p in personas.items()}
293
+
294
+ user_prompt = f"""
295
+ Available Personas:
296
+ {json.dumps(personas_info, indent=2)}
297
+
298
+ User Query: {current_query}
299
+
300
+ Current Session: {self.current_session["persona"]["name"] if self.current_session else "None"}
301
+ """
302
+
303
+ response = await self.client.chat.completions.create(
304
+ model="gpt-4",
305
+ messages=[
306
+ {"role": "system", "content": system_prompt},
307
+ {"role": "user", "content": user_prompt}
308
+ ],
309
+ max_tokens=200,
310
+ temperature=0.3
311
+ )
312
+
313
+ result = json.loads(response.choices[0].message.content)
314
+ result["current_persona"] = self.current_session["persona_id"] if self.current_session else None
315
+
316
+ return {"status": "success", **result}
317
+
318
+ except Exception as e:
319
+ logger.error(f"Error getting handoff recommendation: {e}")
320
+ return {"status": "error", "message": str(e)}
321
+
322
+ async def switch_persona(self, new_persona_id: str, handoff_context: str = None) -> Dict[str, Any]:
323
+ """Switch to a different coaching persona with context handoff"""
324
+ try:
325
+ personas = self.get_available_personas()
326
+ if new_persona_id not in personas:
327
+ return {"status": "error", "message": "Invalid persona ID"}
328
+
329
+ # Prepare handoff summary if switching from another persona
330
+ handoff_summary = None
331
+ if self.current_session:
332
+ handoff_summary = await self._generate_handoff_summary()
333
+
334
+ # Store current session in history
335
+ if self.current_session:
336
+ persona_id = self.current_session["persona_id"]
337
+ self.persona_history[persona_id].append({
338
+ **self.current_session,
339
+ "ended_at": datetime.now().isoformat()
340
+ })
341
+
342
+ # Initialize new session
343
+ startup_context = self.current_session["startup_context"] if self.current_session else {}
344
+ if handoff_context:
345
+ startup_context["handoff_context"] = handoff_context
346
+
347
+ new_session = await self.initialize_coaching_session(new_persona_id, startup_context)
348
+
349
+ if new_session["status"] == "success":
350
+ # Add handoff summary to new session
351
+ if handoff_summary:
352
+ new_session["handoff_summary"] = handoff_summary
353
+
354
+ return new_session
355
+
356
+ except Exception as e:
357
+ logger.error(f"Error switching persona: {e}")
358
+ return {"status": "error", "message": str(e)}
359
+
360
+ async def _generate_handoff_summary(self) -> str:
361
+ """Generate a handoff summary for persona transitions"""
362
+ try:
363
+ if not self.current_session or not self.current_session["conversation_history"]:
364
+ return "No previous conversation context."
365
+
366
+ system_prompt = """
367
+ Create a concise handoff summary for transitioning between startup advisors.
368
+ Include key discussion points, decisions made, and context the new advisor needs.
369
+ Keep it under 150 words and focus on actionable insights.
370
+ """
371
+
372
+ conversation_summary = {
373
+ "persona": self.current_session["persona"]["name"],
374
+ "expertise": self.current_session["persona"]["expertise"],
375
+ "key_discussions": self.current_session["conversation_history"][-3:],
376
+ "action_items": self.current_session["action_items"]
377
+ }
378
+
379
+ response = await self.client.chat.completions.create(
380
+ model="gpt-3.5-turbo",
381
+ messages=[
382
+ {"role": "system", "content": system_prompt},
383
+ {"role": "user", "content": json.dumps(conversation_summary, indent=2)}
384
+ ],
385
+ max_tokens=200,
386
+ temperature=0.5
387
+ )
388
+
389
+ return response.choices[0].message.content
390
+
391
+ except Exception as e:
392
+ logger.error(f"Error generating handoff summary: {e}")
393
+ return "Error generating handoff summary."
394
+
395
+ def get_session_analytics(self) -> Dict[str, Any]:
396
+ """Get analytics about coaching sessions"""
397
+ try:
398
+ total_sessions = sum(len(sessions) for sessions in self.persona_history.values())
399
+
400
+ persona_usage = {
401
+ persona_id: len(sessions)
402
+ for persona_id, sessions in self.persona_history.items()
403
+ }
404
+
405
+ most_used_persona = max(persona_usage.items(), key=lambda x: x[1]) if persona_usage else None
406
+
407
+ return {
408
+ "total_sessions": total_sessions,
409
+ "active_session": bool(self.current_session),
410
+ "current_persona": self.current_session["persona"]["name"] if self.current_session else None,
411
+ "persona_usage": persona_usage,
412
+ "most_used_persona": most_used_persona[0] if most_used_persona else None,
413
+ "available_personas": len(self.get_available_personas())
414
+ }
415
+
416
+ except Exception as e:
417
+ logger.error(f"Error getting session analytics: {e}")
418
+ return {"status": "error", "message": str(e)}
419
+
420
+ class PersonaUIManager:
421
+ """Manages UI components for persona selection and interaction"""
422
+
423
+ def __init__(self):
424
+ self.coach_personas = StartupCoachPersonas()
425
+
426
+ def create_persona_selector(self) -> str:
427
+ """Create HTML interface for persona selection"""
428
+ personas = self.coach_personas.get_available_personas()
429
+
430
+ persona_cards = ""
431
+ for persona_id, persona in personas.items():
432
+ persona_cards += f"""
433
+ <div class="persona-card" data-persona="{persona_id}" style="border-left: 4px solid {persona['color']}">
434
+ <div class="persona-header">
435
+ <span class="persona-avatar">{persona['avatar']}</span>
436
+ <div class="persona-info">
437
+ <h3>{persona['name']}</h3>
438
+ <p class="persona-background">{persona['background']}</p>
439
+ </div>
440
+ </div>
441
+ <div class="persona-expertise">
442
+ <strong>Expertise:</strong>
443
+ <div class="expertise-tags">
444
+ {' '.join([f'<span class="expertise-tag">{exp}</span>' for exp in persona['expertise']])}
445
+ </div>
446
+ </div>
447
+ <div class="persona-style">
448
+ <strong>Style:</strong> {persona['speaking_style']}
449
+ </div>
450
+ <button class="select-persona-btn" onclick="selectPersona('{persona_id}')">
451
+ Choose {persona['name'].split(' ')[0]}
452
+ </button>
453
+ </div>
454
+ """
455
+
456
+ return f"""
457
+ <div id="persona-selector" class="persona-selector-container">
458
+ <div class="selector-header">
459
+ <h2>🎯 Choose Your Startup Coach</h2>
460
+ <p>Select an AI-powered advisor specialized in your specific needs</p>
461
+ </div>
462
+
463
+ <div class="personas-grid">
464
+ {persona_cards}
465
+ </div>
466
+
467
+ <div class="coaching-context">
468
+ <h3>Tell us about your startup:</h3>
469
+ <div class="context-form">
470
+ <input type="text" id="startup-name" placeholder="Startup name" />
471
+ <select id="startup-stage">
472
+ <option value="">Select stage</option>
473
+ <option value="idea">Idea Stage</option>
474
+ <option value="mvp">MVP Development</option>
475
+ <option value="launch">Pre-Launch</option>
476
+ <option value="growth">Growth Stage</option>
477
+ <option value="scale">Scaling</option>
478
+ </select>
479
+ <input type="text" id="industry" placeholder="Industry/Sector" />
480
+ <textarea id="challenge" placeholder="Current biggest challenge or question..."></textarea>
481
+ </div>
482
+ </div>
483
+ </div>
484
+
485
+ <style>
486
+ .persona-selector-container {{
487
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
488
+ border-radius: 20px;
489
+ padding: 30px;
490
+ margin: 20px 0;
491
+ font-family: 'Inter', sans-serif;
492
+ }}
493
+
494
+ .selector-header {{
495
+ text-align: center;
496
+ margin-bottom: 30px;
497
+ }}
498
+
499
+ .selector-header h2 {{
500
+ color: #2d3748;
501
+ margin-bottom: 10px;
502
+ }}
503
+
504
+ .personas-grid {{
505
+ display: grid;
506
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
507
+ gap: 20px;
508
+ margin-bottom: 30px;
509
+ }}
510
+
511
+ .persona-card {{
512
+ background: white;
513
+ border-radius: 15px;
514
+ padding: 20px;
515
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
516
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
517
+ cursor: pointer;
518
+ }}
519
+
520
+ .persona-card:hover {{
521
+ transform: translateY(-5px);
522
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
523
+ }}
524
+
525
+ .persona-header {{
526
+ display: flex;
527
+ align-items: flex-start;
528
+ margin-bottom: 15px;
529
+ }}
530
+
531
+ .persona-avatar {{
532
+ font-size: 2.5rem;
533
+ margin-right: 15px;
534
+ }}
535
+
536
+ .persona-info h3 {{
537
+ margin: 0 0 5px 0;
538
+ color: #2d3748;
539
+ font-size: 1.1rem;
540
+ }}
541
+
542
+ .persona-background {{
543
+ color: #718096;
544
+ font-size: 0.9rem;
545
+ margin: 0;
546
+ line-height: 1.4;
547
+ }}
548
+
549
+ .persona-expertise {{
550
+ margin-bottom: 15px;
551
+ }}
552
+
553
+ .expertise-tags {{
554
+ display: flex;
555
+ flex-wrap: wrap;
556
+ gap: 5px;
557
+ margin-top: 8px;
558
+ }}
559
+
560
+ .expertise-tag {{
561
+ background: #e2e8f0;
562
+ color: #4a5568;
563
+ padding: 4px 8px;
564
+ border-radius: 15px;
565
+ font-size: 0.8rem;
566
+ font-weight: 500;
567
+ }}
568
+
569
+ .persona-style {{
570
+ color: #718096;
571
+ font-size: 0.9rem;
572
+ margin-bottom: 15px;
573
+ }}
574
+
575
+ .select-persona-btn {{
576
+ width: 100%;
577
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
578
+ color: white;
579
+ border: none;
580
+ padding: 12px;
581
+ border-radius: 25px;
582
+ font-weight: 600;
583
+ cursor: pointer;
584
+ transition: opacity 0.3s ease;
585
+ }}
586
+
587
+ .select-persona-btn:hover {{
588
+ opacity: 0.9;
589
+ }}
590
+
591
+ .coaching-context {{
592
+ background: white;
593
+ border-radius: 15px;
594
+ padding: 25px;
595
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
596
+ }}
597
+
598
+ .context-form {{
599
+ display: grid;
600
+ gap: 15px;
601
+ margin-top: 15px;
602
+ }}
603
+
604
+ .context-form input,
605
+ .context-form select,
606
+ .context-form textarea {{
607
+ padding: 12px 15px;
608
+ border: 2px solid #e2e8f0;
609
+ border-radius: 10px;
610
+ font-size: 1rem;
611
+ transition: border-color 0.3s ease;
612
+ }}
613
+
614
+ .context-form input:focus,
615
+ .context-form select:focus,
616
+ .context-form textarea:focus {{
617
+ outline: none;
618
+ border-color: #667eea;
619
+ }}
620
+
621
+ .context-form textarea {{
622
+ min-height: 80px;
623
+ resize: vertical;
624
+ }}
625
+ </style>
626
+
627
+ <script>
628
+ function selectPersona(personaId) {{
629
+ const startupContext = {{
630
+ name: document.getElementById('startup-name').value,
631
+ stage: document.getElementById('startup-stage').value,
632
+ industry: document.getElementById('industry').value,
633
+ challenge: document.getElementById('challenge').value
634
+ }};
635
+
636
+ // Send to backend
637
+ if (window.chainlitAPI) {{
638
+ window.chainlitAPI.sendMessage({{
639
+ type: 'select_persona',
640
+ persona_id: personaId,
641
+ startup_context: startupContext
642
+ }});
643
+ }}
644
+
645
+ // Visual feedback
646
+ document.querySelectorAll('.persona-card').forEach(card => {{
647
+ card.style.opacity = '0.5';
648
+ }});
649
+
650
+ document.querySelector(`[data-persona="${{personaId}}"]`).style.opacity = '1';
651
+ document.querySelector(`[data-persona="${{personaId}}"]`).style.background = '#f0fff4';
652
+ }}
653
+ </script>
654
+ """