cryogenic22 commited on
Commit
67b024f
·
verified ·
1 Parent(s): debfc95

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +275 -344
app.py CHANGED
@@ -1,100 +1,13 @@
1
  # app.py
2
  import os
3
- from utils import ReportManager
 
 
4
  import streamlit as st
5
  from dotenv import load_dotenv
6
  from crewai import Agent, Crew, Process, Task
7
-
8
- # Initialize report manager
9
- report_manager = ReportManager()
10
-
11
- def create_research_crew(topic: str):
12
- researcher = Agent(
13
- role='Research Analyst',
14
- goal=f'Conduct thorough market research about {topic} with verifiable sources',
15
- backstory='You are an experienced market research analyst with expertise in data analysis and trend identification. You always provide specific numbers and data points with sources.',
16
- verbose=True
17
- )
18
-
19
- analyst = Agent(
20
- role='Data Analyst',
21
- goal='Create data-driven insights with specific metrics and visualizable data points',
22
- backstory='You are a skilled data analyst who specializes in turning research into actionable insights. You focus on quantifiable metrics and clear data points that can be visualized.',
23
- verbose=True
24
- )
25
-
26
- writer = Agent(
27
- role='Report Writer',
28
- goal='Create both executive summary and detailed reports with proper citations',
29
- backstory='You are a professional writer who creates clear, structured reports with both high-level summaries and detailed analysis. You always include sources and references.',
30
- verbose=True
31
- )
32
-
33
- # Define tasks with improved prompts
34
- research_task = Task(
35
- description=f"""
36
- Research {topic} with a focus on:
37
- 1. Market size (provide specific numbers)
38
- 2. Growth rates and projections
39
- 3. Key players and market share percentages
40
- 4. Competitive analysis
41
- 5. Find and verify credible sources for all data points
42
-
43
- Format data in a way that can be easily visualized.
44
- Include URLs and references for all sources.
45
- """,
46
- agent=researcher,
47
- expected_output="Detailed research data with sources and numerical data points"
48
- )
49
-
50
- analysis_task = Task(
51
- description=f"""
52
- Analyze the research findings and:
53
- 1. Create growth projections with specific percentages
54
- 2. Break down market share data
55
- 3. Identify key trends with supporting data
56
- 4. Analyze competitive landscape with market positions
57
-
58
- Present all data in a format suitable for charts and graphs.
59
- """,
60
- agent=analyst,
61
- expected_output="Analysis with specific metrics and visualization-ready data",
62
- context=[research_task]
63
- )
64
-
65
- report_task = Task(
66
- description=f"""
67
- Create two report versions:
68
- 1. Executive Summary (2-3 paragraphs)
69
- - Key findings and recommendations
70
- - Major metrics and insights
71
- - Strategic implications
72
-
73
- 2. Detailed Report
74
- - Comprehensive market analysis
75
- - Detailed data presentation
76
- - Competitive analysis
77
- - Future projections
78
- - Source citations and references
79
-
80
- Format the output as JSON with the following structure:
81
- {{
82
- "exec_summary": "executive summary text",
83
- "detailed_report": "detailed report text",
84
- "sources": ["source1", "source2", ...]
85
- }}
86
- """,
87
- agent=writer,
88
- expected_output="JSON containing exec summary, detailed report, and sources",
89
- context=[research_task, analysis_task]
90
- )
91
-
92
- return Crew(
93
- agents=[researcher, analyst, writer],
94
- tasks=[research_task, analysis_task, report_task],
95
- verbose=True,
96
- process=Process.sequential
97
- )
98
 
99
  # Load environment variables
100
  load_dotenv()
@@ -107,286 +20,343 @@ st.set_page_config(
107
  initial_sidebar_state="expanded"
108
  )
109
 
110
- # Add custom CSS with darker text colors and better contrast
111
  st.markdown("""
112
  <style>
113
- /* Text colors */
114
- .stTabs [data-baseweb="tab"] {
115
- color: #1a1a1a !important;
116
- font-weight: 500;
117
- }
118
-
119
- .stMarkdown, .stText {
120
- color: #1a1a1a !important;
121
  }
122
 
123
- /* Main container styles */
124
- .main-container {
 
 
125
  padding: 20px;
126
- color: #1a1a1a;
 
 
 
 
127
  }
128
 
129
- /* Agent flow animation */
130
- .agent-flow {
131
  display: flex;
132
- align-items: center;
133
- justify-content: space-between;
134
- margin: 20px 0;
135
- position: relative;
 
 
 
 
 
 
 
 
136
  }
137
 
138
- .agent-node {
139
- background-color: #ffffff;
 
140
  border-radius: 50%;
141
- width: 80px;
142
- height: 80px;
143
  display: flex;
144
  align-items: center;
145
  justify-content: center;
146
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
147
- position: relative;
148
- z-index: 2;
149
- color: #1a1a1a;
150
- font-weight: 500;
151
- text-align: center;
152
- line-height: 1.2;
153
  }
154
 
155
- .agent-connector {
156
- height: 2px;
157
- background: #ddd;
158
- flex-grow: 1;
159
- margin: 0 10px;
 
 
 
 
 
 
 
160
  position: relative;
161
- overflow: hidden;
162
  }
163
 
164
- .data-particle {
165
- position: absolute;
166
- width: 10px;
167
- height: 10px;
168
- background: #4CAF50;
169
- border-radius: 50%;
170
- animation: moveParticle 2s linear infinite;
171
  }
172
 
173
- @keyframes moveParticle {
174
- 0% { transform: translateX(0); opacity: 0; }
175
- 50% { opacity: 1; }
176
- 100% { transform: translateX(100%); opacity: 0; }
 
177
  }
178
 
179
- /* Agent status indicators */
180
- .agent-status {
181
- padding: 15px;
182
- margin: 10px 0;
183
- border-radius: 8px;
184
- background: #ffffff;
185
- border-left: 4px solid #4CAF50;
186
- animation: slideIn 0.3s ease-out;
187
- color: #1a1a1a;
188
- font-weight: 400;
189
- box-shadow: 0 2px 4px rgba(0,0,0,0.05);
190
  }
191
 
192
- @keyframes slideIn {
193
- from { transform: translateX(-20px); opacity: 0; }
194
- to { transform: translateX(0); opacity: 1; }
 
 
 
195
  }
196
 
197
- /* Report sections */
198
- .report-section {
199
- background: #ffffff;
200
- padding: 20px;
201
- border-radius: 10px;
202
- margin: 15px 0;
203
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
204
- color: #1a1a1a;
205
- font-weight: 400;
206
- line-height: 1.6;
207
  }
208
-
209
- /* Progress bar */
210
- .stProgress > div > div {
211
- background-color: #4CAF50;
 
 
 
212
  }
213
 
214
- /* Button styles */
215
- .stButton > button {
216
- font-weight: 500;
217
- color: #1a1a1a;
 
 
 
 
 
 
 
 
 
 
218
  }
219
 
220
- /* Tab styling */
221
- .stTabs [data-baseweb="tab-list"] {
222
- gap: 24px;
223
- background-color: #f8f9fa;
224
- padding: 10px;
225
- border-radius: 10px;
226
  }
227
 
228
- .stTabs [data-baseweb="tab"] {
229
- height: 50px;
230
- white-space: pre-wrap;
231
- background-color: #ffffff;
232
- border-radius: 8px;
233
- padding: 10px 20px;
 
234
  font-weight: 500;
235
- box-shadow: 0 2px 4px rgba(0,0,0,0.05);
 
236
  }
237
 
238
- .stTabs [aria-selected="true"] {
239
- background-color: #e7f3ff;
240
- color: #0066cc !important;
241
  }
242
-
243
- /* Headers */
244
- h1, h2, h3, h4, h5, h6 {
245
- color: #1a1a1a !important;
246
- font-weight: 600;
247
  }
248
-
249
- /* Links */
250
- a {
251
- color: #0066cc !important;
252
- text-decoration: none;
253
  }
254
 
255
- /* Error messages */
256
- .stAlert {
257
- background-color: #ffebee;
258
- color: #c62828;
259
- padding: 10px;
260
- border-radius: 8px;
261
  }
262
  </style>
263
- """, unsafe_allow_html=True)
264
 
265
- def create_agent_flow(container):
266
- """Create animated agent flow diagram"""
267
- container.markdown("""
268
- <div class="agent-flow">
269
- <div class="agent-node">🔍<br/>Research</div>
270
- <div class="agent-connector">
271
- <div class="data-particle"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  </div>
273
- <div class="agent-node">📊<br/>Analysis</div>
274
- <div class="agent-connector">
275
- <div class="data-particle"></div>
276
  </div>
277
- <div class="agent-node">✍️<br/>Report</div>
278
  </div>
279
- """, unsafe_allow_html=True)
 
280
 
281
- def run_market_research(topic: str, progress_bar, chat_container):
 
 
 
 
 
 
 
 
 
 
 
 
282
  try:
283
- # Create agents
284
  researcher = Agent(
285
  role='Research Analyst',
286
- goal=f'Conduct thorough market research about {topic}',
287
  backstory='You are an experienced market research analyst with expertise in data analysis and trend identification.',
288
  verbose=True
289
  )
290
 
291
  analyst = Agent(
292
  role='Data Analyst',
293
- goal='Analyze research findings and identify key insights',
294
- backstory='You are a skilled data analyst with expertise in interpreting market research and creating actionable insights.',
295
  verbose=True
296
  )
297
 
298
  writer = Agent(
299
  role='Report Writer',
300
- goal='Create comprehensive and engaging market research reports',
301
- backstory='You are a professional writer specializing in creating clear and compelling business reports.',
302
  verbose=True
303
  )
304
 
305
- # Update progress
306
- progress_bar.progress(0, "Initializing research...")
307
- chat_container.markdown("""
308
- <div class="agent-status">
309
- 🔍 Research Analyst: Starting market analysis...
310
- </div>
311
- """, unsafe_allow_html=True)
312
  time.sleep(1)
313
 
314
- # Research Phase
315
  research_task = Task(
316
  description=f"""
317
- Conduct comprehensive market research on {topic}.
318
- Focus on:
319
- 1. Current market size and growth projections
320
- 2. Key players and their market share
321
- 3. Consumer adoption trends
322
- 4. Regulatory environment
 
 
323
  """,
324
  agent=researcher,
325
- expected_output="A comprehensive research document with market analysis."
326
  )
327
-
328
- progress_bar.progress(33, "Analyzing data...")
329
- chat_container.markdown("""
330
- <div class="agent-status">
331
- 📊 Data Analyst: Processing research findings...
332
- </div>
333
- """, unsafe_allow_html=True)
334
  time.sleep(1)
335
 
336
- # Analysis Phase
337
  analysis_task = Task(
338
  description=f"""
339
- Analyze the research findings for {topic} and identify:
340
- 1. Key market opportunities
341
- 2. Potential challenges
342
- 3. Growth drivers
343
- 4. Competitive dynamics
 
 
344
  """,
345
  agent=analyst,
346
- expected_output="An analytical report with key insights.",
347
  context=[research_task]
348
  )
349
-
350
- progress_bar.progress(66, "Generating report...")
351
- chat_container.markdown("""
352
- <div class="agent-status">
353
- ✍️ Report Writer: Compiling final report...
354
- </div>
355
- """, unsafe_allow_html=True)
356
  time.sleep(1)
357
 
358
- # Report Phase
359
  report_task = Task(
360
  description=f"""
361
- Create a detailed market research report that includes:
362
- 1. Executive summary
363
- 2. Market overview
364
- 3. Key findings
365
- 4. Strategic recommendations
 
 
 
 
 
 
366
  """,
367
  agent=writer,
368
- expected_output="A complete market research report in markdown format.",
369
  context=[research_task, analysis_task]
370
  )
371
-
372
- # Create and run the crew
373
  crew = Crew(
374
  agents=[researcher, analyst, writer],
375
  tasks=[research_task, analysis_task, report_task],
376
  verbose=True,
377
  process=Process.sequential
378
  )
379
-
380
  result = crew.kickoff()
381
- progress_bar.progress(100, "Completed!")
382
 
383
- # Format the final result
384
- if hasattr(result, 'raw_output'):
385
- final_report = str(result.raw_output)
386
- else:
387
- final_report = str(result)
388
-
389
- return final_report
390
 
391
  except Exception as e:
392
  st.error(f"Error: {str(e)}")
@@ -395,8 +365,7 @@ def run_market_research(topic: str, progress_bar, chat_container):
395
  def main():
396
  st.title("🤖 AI Market Research Generator")
397
 
398
- # Create tabs
399
- tab1, tab2, tab3 = st.tabs(["Generate Report", "View Reports", "About"])
400
 
401
  with tab1:
402
  col1, col2 = st.columns([2, 3])
@@ -413,82 +382,44 @@ def main():
413
  st.error("Please enter a research topic")
414
  return
415
 
416
- with st.spinner("Generating report..."):
417
- # Create and run crew
418
- crew = create_research_crew(topic)
419
- result = crew.kickoff()
420
-
421
- # Process and save report
422
- try:
423
- report_data = json.loads(result)
424
- # Generate visualizations
425
- charts = report_manager.generate_visualizations(report_data['detailed_report'])
426
- report_data['charts'] = charts
427
-
428
- # Save report
429
- report_id = report_manager.save_report(topic, report_data)
430
- st.success("Report generated successfully!")
431
-
432
- # Switch to the view tab
433
- st.session_state.current_report = report_id
434
- st.rerun()
435
-
436
- except Exception as e:
437
- st.error(f"Error processing report: {str(e)}")
438
 
439
  with tab2:
440
- st.subheader("Saved Reports")
441
- reports = report_manager.get_all_reports()
442
-
443
- if not reports:
444
- st.info("No reports generated yet. Create your first report in the Generate tab!")
445
- return
446
-
447
- # Report selection
448
- report_options = {f"{data['topic']} ({data['timestamp']})": rid
449
- for rid, data in reports.items()}
450
- selected_report = st.selectbox(
451
- "Select a report to view",
452
- options=list(report_options.keys())
453
- )
454
-
455
- if selected_report:
456
- report_id = report_options[selected_report]
457
- report = report_manager.get_report(report_id)
458
 
459
- # Display report
460
- col1, col2 = st.columns([2, 1])
 
461
 
462
- with col1:
463
- st.subheader("Executive Summary")
464
- st.markdown(report['exec_summary'])
465
-
466
- st.subheader("Detailed Report")
467
- st.markdown(report['detailed_report'])
468
-
469
- st.subheader("Sources")
470
- for source in report['sources']:
471
- st.markdown(f"- {source}")
472
 
473
- with col2:
474
- st.subheader("Visualizations")
475
- for chart in report['charts']:
476
- st.plotly_chart(chart, use_container_width=True)
477
 
478
  # Download buttons
479
  col1, col2 = st.columns(2)
480
  with col1:
481
  st.download_button(
482
- "Download as PDF",
483
- data=report_manager.generate_pdf(report_id),
484
- file_name=f"{report['topic']}_report.pdf",
485
- mime="application/pdf"
486
- )
487
- with col2:
488
- st.download_button(
489
- "Download as Markdown",
490
- data=report['detailed_report'],
491
- file_name=f"{report['topic']}_report.md",
492
  mime="text/markdown"
493
  )
494
 
 
1
  # app.py
2
  import os
3
+ import time
4
+ import json
5
+ import random
6
  import streamlit as st
7
  from dotenv import load_dotenv
8
  from crewai import Agent, Crew, Process, Task
9
+ import plotly.graph_objects as go
10
+ import re
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  # Load environment variables
13
  load_dotenv()
 
20
  initial_sidebar_state="expanded"
21
  )
22
 
23
+ # Enhanced CSS with more animations
24
  st.markdown("""
25
  <style>
26
+ /* Animated background */
27
+ .stApp {
28
+ background: linear-gradient(135deg, #f5f7fa 0%, #e4e7eb 100%);
 
 
 
 
 
29
  }
30
 
31
+ /* Agent Chat Containers */
32
+ .chat-window {
33
+ height: 400px;
34
+ overflow-y: auto;
35
  padding: 20px;
36
+ background: rgba(255, 255, 255, 0.9);
37
+ border-radius: 15px;
38
+ box-shadow: 0 8px 32px rgba(31, 38, 135, 0.15);
39
+ margin: 20px 0;
40
+ border: 1px solid rgba(255, 255, 255, 0.18);
41
  }
42
 
43
+ .agent-message {
 
44
  display: flex;
45
+ align-items: flex-start;
46
+ margin: 15px 0;
47
+ animation: messageSlide 0.5s ease forwards;
48
+ opacity: 0;
49
+ transform: translateX(-20px);
50
+ }
51
+
52
+ @keyframes messageSlide {
53
+ to {
54
+ opacity: 1;
55
+ transform: translateX(0);
56
+ }
57
  }
58
 
59
+ .agent-avatar {
60
+ width: 45px;
61
+ height: 45px;
62
  border-radius: 50%;
 
 
63
  display: flex;
64
  align-items: center;
65
  justify-content: center;
66
+ font-size: 24px;
67
+ margin-right: 15px;
68
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
69
+ animation: avatarPop 0.3s ease forwards;
 
 
 
70
  }
71
 
72
+ @keyframes avatarPop {
73
+ 0% { transform: scale(0); }
74
+ 50% { transform: scale(1.2); }
75
+ 100% { transform: scale(1); }
76
+ }
77
+
78
+ .message-bubble {
79
+ background: white;
80
+ padding: 12px 20px;
81
+ border-radius: 18px;
82
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
83
+ max-width: 80%;
84
  position: relative;
85
+ animation: bubbleFade 0.3s ease forwards;
86
  }
87
 
88
+ @keyframes bubbleFade {
89
+ from { opacity: 0; transform: scale(0.9); }
90
+ to { opacity: 1; transform: scale(1); }
 
 
 
 
91
  }
92
 
93
+ /* Thinking animation */
94
+ .thinking-dots {
95
+ display: inline-flex;
96
+ gap: 4px;
97
+ margin-left: 8px;
98
  }
99
 
100
+ .dot {
101
+ width: 8px;
102
+ height: 8px;
103
+ background: #4CAF50;
104
+ border-radius: 50%;
105
+ animation: dotPulse 1.5s infinite;
 
 
 
 
 
106
  }
107
 
108
+ .dot:nth-child(2) { animation-delay: 0.2s; }
109
+ .dot:nth-child(3) { animation-delay: 0.4s; }
110
+
111
+ @keyframes dotPulse {
112
+ 0%, 100% { transform: scale(0.7); opacity: 0.5; }
113
+ 50% { transform: scale(1); opacity: 1; }
114
  }
115
 
116
+ /* Progress bar animation */
117
+ .progress-container {
118
+ width: 100%;
119
+ height: 8px;
120
+ background: #f0f0f0;
121
+ border-radius: 4px;
122
+ overflow: hidden;
123
+ margin: 20px 0;
 
 
124
  }
125
+
126
+ .progress-bar {
127
+ height: 100%;
128
+ background: linear-gradient(90deg, #4CAF50, #81C784);
129
+ transition: width 0.5s ease;
130
+ position: relative;
131
+ overflow: hidden;
132
  }
133
 
134
+ .progress-bar::after {
135
+ content: '';
136
+ position: absolute;
137
+ top: 0;
138
+ left: 0;
139
+ width: 100%;
140
+ height: 100%;
141
+ background: linear-gradient(
142
+ 90deg,
143
+ transparent,
144
+ rgba(255, 255, 255, 0.4),
145
+ transparent
146
+ );
147
+ animation: shimmer 2s infinite;
148
  }
149
 
150
+ @keyframes shimmer {
151
+ 0% { transform: translateX(-100%); }
152
+ 100% { transform: translateX(100%); }
 
 
 
153
  }
154
 
155
+ /* Status badges */
156
+ .status-badge {
157
+ display: inline-flex;
158
+ align-items: center;
159
+ padding: 6px 12px;
160
+ border-radius: 12px;
161
+ font-size: 14px;
162
  font-weight: 500;
163
+ margin: 4px;
164
+ animation: badgeFade 0.3s ease forwards;
165
  }
166
 
167
+ @keyframes badgeFade {
168
+ from { opacity: 0; transform: translateY(-10px); }
169
+ to { opacity: 1; transform: translateY(0); }
170
  }
171
+
172
+ /* Agent-specific styles */
173
+ .researcher {
174
+ background: linear-gradient(135deg, #E3F2FD 0%, #BBDEFB 100%);
 
175
  }
176
+
177
+ .analyst {
178
+ background: linear-gradient(135deg, #F3E5F5 0%, #E1BEE7 100%);
 
 
179
  }
180
 
181
+ .writer {
182
+ background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%);
 
 
 
 
183
  }
184
  </style>
185
+ """, unsafe_allow_html=True)
186
 
187
+ def format_json_output(raw_output):
188
+ """Format agent output into proper JSON"""
189
+ try:
190
+ # Try direct JSON parsing
191
+ return json.loads(raw_output)
192
+ except json.JSONDecodeError:
193
+ # If direct parsing fails, try to extract JSON block
194
+ json_pattern = r"\{[\s\S]*\}"
195
+ match = re.search(json_pattern, raw_output)
196
+ if match:
197
+ try:
198
+ return json.loads(match.group())
199
+ except:
200
+ pass
201
+
202
+ # If JSON extraction fails, create structured format
203
+ return {
204
+ "exec_summary": "Error formatting report",
205
+ "detailed_report": raw_output,
206
+ "sources": []
207
+ }
208
+
209
+ def display_thinking_animation():
210
+ """Display thinking animation dots"""
211
+ return """
212
+ <div class="thinking-dots">
213
+ <div class="dot"></div>
214
+ <div class="dot"></div>
215
+ <div class="dot"></div>
216
+ </div>
217
+ """
218
+
219
+ def display_agent_message(container, agent_type: str, message: str, thinking: bool = False):
220
+ """Display an animated agent message"""
221
+ icons = {
222
+ "researcher": "🔍",
223
+ "analyst": "📊",
224
+ "writer": "✍️"
225
+ }
226
+
227
+ message_html = f"""
228
+ <div class="agent-message">
229
+ <div class="agent-avatar {agent_type}">
230
+ {icons.get(agent_type, "👤")}
231
  </div>
232
+ <div class="message-bubble">
233
+ {message}
234
+ {display_thinking_animation() if thinking else ""}
235
  </div>
 
236
  </div>
237
+ """
238
+ container.markdown(message_html, unsafe_allow_html=True)
239
 
240
+ def update_progress(container, progress, message=""):
241
+ """Update progress bar with animation"""
242
+ progress_html = f"""
243
+ <div class="progress-container">
244
+ <div class="progress-bar" style="width: {progress}%"></div>
245
+ </div>
246
+ <div class="status-badge">
247
+ {message}
248
+ </div>
249
+ """
250
+ container.markdown(progress_html, unsafe_allow_html=True)
251
+
252
+ def run_market_research(topic: str, progress_container, chat_container):
253
  try:
 
254
  researcher = Agent(
255
  role='Research Analyst',
256
+ goal=f'Conduct thorough market research about {topic} with verifiable sources',
257
  backstory='You are an experienced market research analyst with expertise in data analysis and trend identification.',
258
  verbose=True
259
  )
260
 
261
  analyst = Agent(
262
  role='Data Analyst',
263
+ goal='Create data-driven insights with specific metrics',
264
+ backstory='You are a skilled data analyst who specializes in turning research into actionable insights.',
265
  verbose=True
266
  )
267
 
268
  writer = Agent(
269
  role='Report Writer',
270
+ goal='Create both executive summary and detailed reports with citations',
271
+ backstory='You are a professional writer who creates clear, structured reports.',
272
  verbose=True
273
  )
274
 
275
+ # Research Phase
276
+ display_agent_message(chat_container, "researcher",
277
+ f"👋 Hello! I'll be researching the {topic} market thoroughly.", False)
278
+ time.sleep(1)
279
+
280
+ update_progress(progress_container, 20, "🔍 Gathering market data...")
281
+ display_agent_message(chat_container, "researcher", "Processing market information...", True)
282
  time.sleep(1)
283
 
 
284
  research_task = Task(
285
  description=f"""
286
+ Research {topic} with focus on:
287
+ 1. Market size and growth projections (with specific numbers)
288
+ 2. Key players and market share percentages
289
+ 3. Competitive analysis
290
+ 4. Future trends
291
+ 5. Include verifiable sources
292
+
293
+ Format the output as clear sections with numerical data points.
294
  """,
295
  agent=researcher,
296
+ expected_output="Detailed market research with data points and sources"
297
  )
298
+
299
+ # Analysis Phase
300
+ update_progress(progress_container, 40, "📊 Analyzing findings...")
301
+ display_agent_message(chat_container, "analyst",
302
+ "I've received the research data. Beginning analysis...", False)
 
 
303
  time.sleep(1)
304
 
 
305
  analysis_task = Task(
306
  description=f"""
307
+ Analyze the research findings and provide:
308
+ 1. Growth projections and trends
309
+ 2. Market share analysis
310
+ 3. Competitive landscape
311
+ 4. Key opportunities and challenges
312
+
313
+ Include specific metrics and percentages.
314
  """,
315
  agent=analyst,
316
+ expected_output="Market analysis with specific metrics",
317
  context=[research_task]
318
  )
319
+
320
+ # Report Phase
321
+ update_progress(progress_container, 70, "✍️ Generating report...")
322
+ display_agent_message(chat_container, "writer",
323
+ "Converting analysis into comprehensive report...", False)
 
 
324
  time.sleep(1)
325
 
 
326
  report_task = Task(
327
  description=f"""
328
+ Create a market research report with:
329
+ 1. Executive Summary (2-3 paragraphs)
330
+ 2. Detailed Report (full analysis)
331
+ 3. Sources and Citations
332
+
333
+ Format as a JSON with:
334
+ {{
335
+ "exec_summary": "summary text",
336
+ "detailed_report": "detailed text",
337
+ "sources": ["source1", "source2"]
338
+ }}
339
  """,
340
  agent=writer,
341
+ expected_output="JSON formatted report with summary and details",
342
  context=[research_task, analysis_task]
343
  )
344
+
 
345
  crew = Crew(
346
  agents=[researcher, analyst, writer],
347
  tasks=[research_task, analysis_task, report_task],
348
  verbose=True,
349
  process=Process.sequential
350
  )
351
+
352
  result = crew.kickoff()
 
353
 
354
+ # Update final progress
355
+ update_progress(progress_container, 100, "✨ Report completed!")
356
+ display_agent_message(chat_container, "writer",
357
+ "Report generation completed! You can now view the full report.", False)
358
+
359
+ return format_json_output(result)
 
360
 
361
  except Exception as e:
362
  st.error(f"Error: {str(e)}")
 
365
  def main():
366
  st.title("🤖 AI Market Research Generator")
367
 
368
+ tab1, tab2 = st.tabs(["Generate Report", "View Reports"])
 
369
 
370
  with tab1:
371
  col1, col2 = st.columns([2, 3])
 
382
  st.error("Please enter a research topic")
383
  return
384
 
385
+ # Create containers for progress and chat
386
+ progress_container = st.container()
387
+
388
+ with col2:
389
+ st.markdown('<div class="chat-window">', unsafe_allow_html=True)
390
+ chat_container = st.container()
391
+ st.markdown('</div>', unsafe_allow_html=True)
392
+
393
+ result = run_market_research(topic, progress_container, chat_container)
394
+
395
+ if result:
396
+ st.session_state.current_report = result
397
+ st.success("Report generated successfully! View it in the Reports tab.")
 
 
 
 
 
 
 
 
 
398
 
399
  with tab2:
400
+ if hasattr(st.session_state, 'current_report'):
401
+ st.subheader("📊 Generated Report")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
402
 
403
+ # Display Executive Summary
404
+ with st.expander("Executive Summary", expanded=True):
405
+ st.markdown(st.session_state.current_report['exec_summary'])
406
 
407
+ # Display Detailed Report
408
+ with st.expander("Detailed Report", expanded=True):
409
+ st.markdown(st.session_state.current_report['detailed_report'])
 
 
 
 
 
 
 
410
 
411
+ # Display Sources
412
+ with st.expander("Sources", expanded=True):
413
+ for source in st.session_state.current_report['sources']:
414
+ st.markdown(f"- {source}")
415
 
416
  # Download buttons
417
  col1, col2 = st.columns(2)
418
  with col1:
419
  st.download_button(
420
+ "Download Full Report",
421
+ data=st.session_state.current_report['detailed_report'],
422
+ file_name=f"{topic}_report.md",
 
 
 
 
 
 
 
423
  mime="text/markdown"
424
  )
425