DrishtiSharma commited on
Commit
130fca2
·
verified ·
1 Parent(s): f6d8c6e

Create interim_v2.py

Browse files
Files changed (1) hide show
  1. interim_v2.py +517 -0
interim_v2.py ADDED
@@ -0,0 +1,517 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from crewai import Agent, Task, Crew
3
+ import os
4
+ from langchain_groq import ChatGroq
5
+ from langchain_openai import ChatOpenAI
6
+ from fpdf import FPDF
7
+ import pandas as pd
8
+ import plotly.express as px
9
+ import tempfile
10
+ import time
11
+ import ast
12
+ import logging
13
+ import traceback
14
+
15
+ # Setup logging
16
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
17
+
18
+ # Title and Application Introduction
19
+ st.title("Patent Strategy and Innovation Consultant")
20
+ st.sidebar.write(
21
+ "This application provides actionable insights and comprehensive analysis for patent-related strategies."
22
+ )
23
+
24
+ # User Input Section
25
+ st.sidebar.header("User Inputs")
26
+ patent_area = st.text_input("Enter Patent Technology Area", value="Transparent Antennas for Windshields")
27
+ stakeholder = st.text_input("Enter Stakeholder", value="Patent Attorneys")
28
+
29
+ # Initialize LLM
30
+ llm = None
31
+
32
+ # Model Selection
33
+ model_choice = st.radio("Select LLM", ["GPT-4o", "llama-3.3-70b"], index=0, horizontal=True)
34
+
35
+
36
+ # API Key Validation and LLM Initialization
37
+ groq_api_key = os.getenv("GROQ_API_KEY")
38
+ openai_api_key = os.getenv("OPENAI_API_KEY")
39
+
40
+ if model_choice == "llama-3.3-70b":
41
+ if not groq_api_key:
42
+ st.error("Groq API key is missing. Please set the GROQ_API_KEY environment variable.")
43
+ llm = None
44
+ else:
45
+ llm = ChatGroq(groq_api_key=groq_api_key, model="groq/llama-3.3-70b-versatile")
46
+ elif model_choice == "GPT-4o":
47
+ if not openai_api_key:
48
+ st.error("OpenAI API key is missing. Please set the OPENAI_API_KEY environment variable.")
49
+ llm = None
50
+ else:
51
+ llm = ChatOpenAI(api_key=openai_api_key, model="gpt-4o")
52
+
53
+
54
+ # Advanced Options
55
+ st.sidebar.header("Advanced Options")
56
+ enable_advanced_analysis = st.sidebar.checkbox("Enable Advanced Analysis", value=True)
57
+ enable_custom_visualization = st.sidebar.checkbox("Enable Custom Visualizations", value=True)
58
+
59
+ # Agent Customization
60
+ st.sidebar.header("Agent Customization")
61
+ with st.sidebar.expander("Customize Agent Goals", expanded=False):
62
+ enable_customization = st.checkbox("Enable Custom Goals")
63
+ if enable_customization:
64
+ planner_goal = st.text_area(
65
+ "Planner Goal",
66
+ value=(
67
+ "Conduct in-depth, data-driven research on leading companies' recent patent filings, technological innovation, R&D investments,"
68
+ "strategic partnerships and market dynamics strictly within the {topic} sector."
69
+ "Avoid unrelated or generic recommendations."
70
+ "Identify key players, emerging technologies, competitor strategies, and market gaps with factually accurate and verifiable data. "
71
+ "Develop a Competitor Benchmark Matrix highlighting leaders in material innovations vs. integration techniques."
72
+ "Summarize key market trends and shifts in competitive positioning with bullet-point insights."
73
+ "Strictly avoid hallucinated, fabricated, or speculative findings. "
74
+ "Develop a phased Patent Filing Roadmap targeting emerging technologies and high-growth regions tailored to the specific needs"
75
+ "and strategic goals of {stakeholder}. Conduct a Risk Assessment covering regulatory barriers, supply chain risks, and material"
76
+ "costs with mitigation strategies. Suggest Investment Opportunities by identifying startups or strategic partnerships in {topic}."
77
+ "Present findings using a Phased Patent Strategy Table (short-term, mid-term, long-term) and a Risk Matrix."
78
+ )
79
+ )
80
+ writer_goal = st.text_area(
81
+ "Writer Goal",
82
+ value=(
83
+ "Develop a high-impact, professionally structured insights report that integrates verified research data and strategic analysis"
84
+ "into a cohesive and compelling narrative. "
85
+ "Organize findings into well-defined, data-driven sections such as Market Trends, Competitive Landscape, Emerging Technologies,"
86
+ "Untapped Innovation Hotspots, and Strategic Opportunities -- providing actionable insights and prioritized recommendations"
87
+ "strictly aligned with {stakeholder}'s strategic objectives. "
88
+ "Ensure all insights, emerging technologies, and identified innovation gaps are fact-based, verifiable, and directly relevant to the {topic}. "
89
+ "Explicitly avoid hallucinated, fabricated, or speculative content throughout the report."
90
+ )
91
+ )
92
+ analyst_goal = st.text_area(
93
+ "Analyst Goal",
94
+ value=(
95
+ "Perform precise, data-driven statistical analysis of patent filings, growth trends, and innovation distribution strictly within the {topic} sector, "
96
+ "specifically customized to the strategic needs of {stakeholder}. "
97
+ "Identify top regions, leading assignees/companies, and emerging technologies that are explicitly and directly relevant to {topic}. "
98
+ "Strictly avoid hallucinated, fabricated, or speculative statistical data and patent numbers in the analysis. "
99
+ "Conduct a thorough market gap analysis, identifying 4-5 highly actionable and verifiable innovation opportunities aligned with {topic}, "
100
+ "emphasizing sustainability, emerging technology integration, industry collaboration, and competitor positioning. "
101
+ "Evaluate competitor patent strategies with factual data to uncover untapped opportunities and competitive advantages. "
102
+ "All innovation hotspots and emerging technology suggestions must be strictly aligned with {topic} - no generic or unrelated recommendations are allowed. "
103
+ "Deliver highly actionable, data-driven insights to support strategic decision-making and long-term growth. "
104
+ "Present findings in a structured, well-organized format using 'Category' and 'Values' keys for easy data interpretation."
105
+
106
+ )
107
+ )
108
+ else:
109
+ planner_goal = (
110
+ "Conduct comprehensive, data-driven research on patent filings, technological innovation, and market dynamics strictly within the {topic} sector."
111
+ "Avoid unrelated or generic recommendations."
112
+ "Identify key players, emerging technologies, competitor strategies, and market gaps with factually accurate and verifiable data. "
113
+ "Strictly avoid hallucinated, fabricated, or speculative findings. "
114
+ "Develop a phased Patent Filing Roadmap targeting emerging technologies and high-growth regions tailored to the specific needs"
115
+ "and strategic goals of {stakeholder}. Conduct a Risk Assessment covering regulatory barriers, supply chain risks, and"
116
+ "material costs with mitigation strategies. Suggest Investment Opportunities by identifying startups or strategic partnerships in {topic}."
117
+ "Present findings using a Phased Patent Strategy Table (short-term, mid-term, long-term) and a Risk Matrix."
118
+ )
119
+ writer_goal = (
120
+ "Develop a high-impact, professionally structured insights report that integrates verified research data and strategic analysis"
121
+ "into a cohesive and compelling narrative. "
122
+ "Organize findings into well-defined, data-driven sections such as Market Trends, Competitive Landscape, Emerging Technologies,"
123
+ "Untapped Innovation Hotspots, and Strategic Opportunities -- providing actionable insights and prioritized recommendations"
124
+ "strictly aligned with {stakeholder}'s strategic objectives. "
125
+ "Ensure all insights, emerging technologies, and identified innovation gaps are fact-based, verifiable, and directly relevant to the {topic}. "
126
+ "Explicitly avoid hallucinated, fabricated, or speculative content throughout the report."
127
+
128
+ )
129
+ analyst_goal = (
130
+ "Perform precise, data-driven statistical analysis of patent filings, growth trends, and innovation distribution strictly within the {topic} sector, "
131
+ "specifically customized to the strategic needs of {stakeholder}. "
132
+ "Identify top regions, leading assignees/companies, and emerging technologies that are explicitly and directly relevant to {topic}. "
133
+ "Identify 4-5 emerging technologies shaping the {topic} market with brief impact analyses."
134
+ "Highlight untapped markets and geographic regions with low patent activity but high growth potential."
135
+ "Provide Technology Spotlight Cards detailing each technology's name, description, development stage, and potential market impact."
136
+ "Strictly avoid hallucinated, fabricated, or speculative statistical data and patent numbers in the analysis. "
137
+ "Conduct a thorough market gap analysis, identifying 4-5 highly actionable and verifiable innovation opportunities aligned with {topic}, "
138
+ "emphasizing sustainability, emerging technology integration, industry collaboration, and competitor positioning. "
139
+ "Evaluate competitor patent strategies with factual data to uncover untapped opportunities and competitive advantages. "
140
+ "All innovation hotspots and emerging technology suggestions must be strictly aligned with {topic} - no generic or unrelated recommendations are allowed. "
141
+ "Deliver highly actionable, data-driven insights to support strategic decision-making and long-term growth. "
142
+ "Present findings in a structured, well-organized format using 'Category' and 'Values' keys for easy data interpretation."
143
+ )
144
+
145
+ # Agent Definitions
146
+ planner = Agent(
147
+ role="Patent Research Consultant",
148
+ goal=planner_goal,
149
+ backstory=(
150
+ "You're tasked with researching {topic} patents and identifying key trends and players. Your work supports the Patent Writer and Data Analyst."
151
+ ),
152
+ allow_delegation=False,
153
+ verbose=True,
154
+ llm=llm
155
+ )
156
+
157
+ writer = Agent(
158
+ role="Patent Insights Writer",
159
+ goal=writer_goal,
160
+ backstory=(
161
+ "Using the research from the Planner and data from the Analyst, craft a professional document summarizing patent insights for {stakeholder}."
162
+ ),
163
+ allow_delegation=False,
164
+ verbose=True,
165
+ llm=llm
166
+ )
167
+
168
+ analyst = Agent(
169
+ role="Patent Data Analyst",
170
+ goal=analyst_goal,
171
+ backstory=(
172
+ "Analyze patent filing data and innovation trends in {topic} to provide statistical insights. Your analysis will guide the Writer's final report."
173
+ ),
174
+ allow_delegation=False,
175
+ verbose=True,
176
+ llm=llm
177
+ )
178
+
179
+ # Task Definitions
180
+ plan = Task(
181
+ description=(
182
+ "1. Conduct comprehensive, fact-based research on recent trends in {topic} patent filings and innovation.\n"
183
+ "2. Identify key players, emerging technologies, and market gaps that are strictly relevant to {topic}.\n"
184
+ "3. Ensure all findings—especially emerging technologies and innovation hotspots—are explicitly aligned with {topic}.\n"
185
+ "4. Avoid speculative, fabricated, or unrelated content entirely.\n"
186
+ "5. Provide actionable, data-backed strategic recommendations aligned with {stakeholder}'s goals.\n"
187
+ "6. Limit the output to 600 words."
188
+ ),
189
+ expected_output="A fact-driven research document with strictly relevant insights, strategic recommendations, and key statistics.",
190
+ agent=planner
191
+ )
192
+
193
+ write = Task(
194
+ description=(
195
+ "1. Use the Planner's and Analyst's strictly topic-aligned outputs to craft a professional patent insights document.\n"
196
+ "2. Include key findings, visual aids, and actionable strategies strictly related to {topic}.\n"
197
+ "3. Highlight strategic directions and strictly relevant innovation opportunities.\n"
198
+ "4. Incorporate well-structured tables for key statistics and example inventions without using any fabricated data or fake patent numbers.\n"
199
+ "5. Avoid any speculative, fabricated, or unrelated content.\n"
200
+ "6. Limit the document to 600 words."
201
+ ),
202
+ expected_output="A polished, stakeholder-ready patent insights report with actionable, strictly relevant recommendations.",
203
+ agent=writer
204
+ )
205
+
206
+ analyse = Task(
207
+ description=(
208
+ "1. Conduct a comprehensive statistical analysis of patent filing trends, innovation hot spots, and future growth projections in the {topic} sector.\n"
209
+ "2. Identify and rank the top regions, leading assignees/companies driving innovation.\n"
210
+ "3. Highlight regional innovation trends and the distribution of emerging technologies across different geographies.\n"
211
+ "4. Provide actionable insights and strategic recommendations based on the data.\n"
212
+ "5. Categorize outputs as either:\n"
213
+ " - 'Data Insight' for visualizations and tables (quantitative data, trends, technologies).\n"
214
+ " - 'Key Insight' for strategic recommendations and innovation opportunities.\n"
215
+ "6. Example Output Format:\n"
216
+ "[\n"
217
+ " {{'Category': 'Top Regions', 'Type': 'Data Insight', 'Values': {{'North America': 120, 'Europe': 95}},\n"
218
+ " {{'Category': 'Emerging Technologies', 'Type': 'Data Insight', 'Values': ['Transparent Conductive Films']}},\n"
219
+ " {{'Category': 'Strategic Insights', 'Type': 'Key Insight', 'Values': 'Collaborate with material science companies to develop advanced transparent antennas.'}},\n"
220
+ " {{'Category': 'Innovation Gaps', 'Type': 'Key Insight', 'Values': 'Limited patents in self-healing transparent materials present a growth opportunity.'}}\n"
221
+ "]\n"
222
+ "7. Ensure all data is factually accurate, verifiable, and strictly aligned with {topic}."
223
+ ),
224
+ expected_output="A structured dataset combining Data Insights for comprehensive visualizations and table reporting, and Key Insights for strategic actions.",
225
+ agent=analyst
226
+ )
227
+
228
+ crew = Crew(
229
+ agents=[planner, analyst, writer],
230
+ tasks=[plan, analyse, write],
231
+ verbose=True
232
+ )
233
+
234
+ # PDF Report Generation
235
+ def generate_pdf_report(result, charts=None, table_data=None, metadata=None, key_insights=None):
236
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp_pdf:
237
+ pdf = FPDF()
238
+ pdf.add_page()
239
+
240
+ # Add DejaVu fonts (regular and bold)
241
+ pdf.add_font('DejaVu', '', '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', uni=True)
242
+ pdf.add_font('DejaVu', 'B', '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', uni=True)
243
+
244
+ pdf.set_font("DejaVu", size=12)
245
+ pdf.set_auto_page_break(auto=True, margin=15)
246
+
247
+ # Title (Bold)
248
+ pdf.set_font("DejaVu", size=16, style="B")
249
+ pdf.cell(200, 10, txt="Patent Strategy and Innovation Report", ln=True, align="C")
250
+ pdf.ln(10)
251
+
252
+ # Metadata Section
253
+ if metadata:
254
+ pdf.set_font("DejaVu", size=10)
255
+ for key, value in metadata.items():
256
+ pdf.cell(200, 10, txt=f"{key}: {value}", ln=True)
257
+
258
+ # Report Content
259
+ pdf.set_font("DejaVu", size=12)
260
+ pdf.multi_cell(0, 10, txt=result)
261
+
262
+ # Key Insights Section
263
+ if key_insights:
264
+ pdf.add_page()
265
+ pdf.set_font("DejaVu", size=14, style="B")
266
+ pdf.cell(200, 10, txt="Key Strategic Insights", ln=True)
267
+ pdf.ln(5)
268
+ pdf.set_font("DejaVu", size=12)
269
+ for insight in key_insights:
270
+ pdf.multi_cell(0, 10, txt=f"- {insight}")
271
+
272
+ # Insert Charts
273
+ if charts:
274
+ for chart_path in charts:
275
+ try:
276
+ pdf.add_page()
277
+ pdf.image(chart_path, x=10, y=20, w=180)
278
+ except Exception as e:
279
+ logging.error(f"Error including chart: {e}")
280
+
281
+ # Insert Tables
282
+ if table_data:
283
+ pdf.add_page()
284
+ pdf.set_font("DejaVu", size=10)
285
+ pdf.cell(200, 10, txt="Consolidated Data Table:", ln=True, align="L")
286
+ for row in table_data:
287
+ pdf.cell(200, 10, txt=str(row), ln=True)
288
+
289
+ pdf.output(temp_pdf.name)
290
+ return temp_pdf.name
291
+
292
+
293
+ # Data Validation
294
+ def validate_analyst_output(analyst_output):
295
+ if not analyst_output:
296
+ st.warning("No data available for analysis.")
297
+ return None
298
+ if not isinstance(analyst_output, list) or not all(isinstance(item, dict) for item in analyst_output):
299
+ st.warning("Analyst output must be a list of dictionaries.")
300
+ return None
301
+ required_keys = {'Category', 'Values'}
302
+ if not all(required_keys.issubset(item.keys()) for item in analyst_output):
303
+ st.warning(f"Each dictionary must contain keys: {required_keys}")
304
+ return None
305
+ return analyst_output
306
+
307
+ # Visualization and Table Display
308
+ def create_visualizations(analyst_output):
309
+ chart_paths = []
310
+ validated_data = validate_analyst_output(analyst_output)
311
+
312
+ if validated_data:
313
+ for item in validated_data:
314
+ category = item["Category"]
315
+ values = item["Values"]
316
+
317
+ try:
318
+ # Handle dictionary data
319
+ if isinstance(values, dict):
320
+ df = pd.DataFrame(list(values.items()), columns=["Label", "Count"])
321
+
322
+ # Choose Pie Chart for fewer categories, else Bar Chart
323
+ if len(df) <= 5:
324
+ chart = px.pie(df, names="Label", values="Count", title=f"{category} Distribution")
325
+ else:
326
+ chart = px.bar(df, x="Label", y="Count", title=f"{category} Analysis")
327
+
328
+ # Handle list data
329
+ elif isinstance(values, list):
330
+ # Convert the list into a frequency count without dummy values
331
+ df = pd.DataFrame(values, columns=["Label"])
332
+ df = df["Label"].value_counts().reset_index()
333
+ df.columns = ["Label", "Count"]
334
+
335
+ # Plot as a bar chart or pie chart
336
+ if len(df) <= 5:
337
+ chart = px.pie(df, names="Label", values="Count", title=f"{category} Distribution")
338
+ else:
339
+ chart = px.bar(df, x="Label", y="Count", title=f"{category} Frequency")
340
+
341
+ # Handle text data
342
+ elif isinstance(values, str):
343
+ st.subheader(f"{category} Insights")
344
+ st.table(pd.DataFrame({"Insights": [values]}))
345
+ continue # No chart for text data
346
+
347
+ else:
348
+ st.warning(f"Unsupported data format for category: {category}")
349
+ continue
350
+
351
+ # Display the chart in Streamlit
352
+ st.plotly_chart(chart)
353
+
354
+ # Save the chart for PDF export
355
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_chart:
356
+ chart.write_image(temp_chart.name)
357
+ chart_paths.append(temp_chart.name)
358
+
359
+ except Exception as e:
360
+ st.error(f"Failed to generate visualization for {category}: {e}")
361
+ logging.error(f"Error in {category} visualization: {e}")
362
+
363
+ return chart_paths
364
+
365
+ def display_table(analyst_output):
366
+ table_data = []
367
+ validated_data = validate_analyst_output(analyst_output)
368
+
369
+ if validated_data:
370
+ for item in validated_data:
371
+ category = item["Category"]
372
+ values = item["Values"]
373
+
374
+ # Error handling to prevent crashes
375
+ try:
376
+ # Handle dictionary data (Table View)
377
+ if isinstance(values, dict):
378
+ df = pd.DataFrame(list(values.items()), columns=["Label", "Count"])
379
+ st.subheader(f"{category} (Table View)")
380
+ st.dataframe(df)
381
+ table_data.extend(df.to_dict(orient="records"))
382
+
383
+ # Handle list data (List View)
384
+ elif isinstance(values, list):
385
+ df = pd.DataFrame(values, columns=["Items"])
386
+ st.subheader(f"{category} (List View)")
387
+ st.dataframe(df)
388
+ table_data.extend(df.to_dict(orient="records"))
389
+
390
+ # Handle text data (Summary View)
391
+ elif isinstance(values, str):
392
+ st.subheader(f"{category} (Summary)")
393
+ st.table(pd.DataFrame({"Insights": [values]}))
394
+ table_data.append({"Category": category, "Values": values})
395
+
396
+ else:
397
+ st.warning(f"Unsupported data format for category: {category}")
398
+
399
+ except Exception as e:
400
+ logging.error(f"Error processing {category}: {e}")
401
+ st.error(f"Failed to display {category} as a table due to an error.")
402
+
403
+ return table_data
404
+
405
+ def parse_analyst_output(raw_output):
406
+ key_insights = []
407
+ data_insights = []
408
+
409
+ try:
410
+ structured_data = ast.literal_eval(raw_output) if isinstance(raw_output, str) else raw_output
411
+
412
+ for item in structured_data:
413
+ if "Category" not in item:
414
+ logging.warning(f"Missing 'Category' in item: {item}")
415
+ continue
416
+
417
+ if item.get("Type") == "Key Insight":
418
+ key_insights.append(item["Values"])
419
+ elif item.get("Type") == "Data Insight":
420
+ data_insights.append(item)
421
+ else:
422
+ data_insights.append(item)
423
+ except Exception as e:
424
+ logging.error(f"Error parsing analyst output: {e}")
425
+
426
+ return key_insights, data_insights
427
+
428
+ # Main Execution Block
429
+ if st.button("Generate Patent Insights"):
430
+ with st.spinner('Processing...'):
431
+ try:
432
+ # Start the timer
433
+ start_time = time.time()
434
+
435
+ # Kick off the crew with user inputs
436
+ if not patent_area or not stakeholder:
437
+ st.error("Please provide both Patent Technology Area and Stakeholder.")
438
+ else:
439
+ logging.info(f"Starting analysis with Topic: {patent_area}, Stakeholder: {stakeholder}")
440
+ results = crew.kickoff(inputs={"topic": patent_area, "stakeholder": stakeholder})
441
+
442
+
443
+ # Calculate elapsed time
444
+ elapsed_time = time.time() - start_time
445
+
446
+ # Extract Writer's Output
447
+ writer_output = getattr(results.tasks_output[2], "raw", "No details available.")
448
+ if writer_output and writer_output.strip():
449
+ st.markdown("### Final Report")
450
+ st.write(writer_output)
451
+ else:
452
+ st.warning("No final report available.")
453
+
454
+ # Expandable section for detailed insights
455
+ with st.expander("Explore Detailed Insights"):
456
+ tab1, tab2 = st.tabs(["Planner's Insights", "Analyst's Analysis"])
457
+
458
+ # Planner's Insights
459
+ with tab1:
460
+ planner_output = getattr(results.tasks_output[0], "raw", "No details available.")
461
+ if planner_output and planner_output.strip():
462
+ st.write(planner_output)
463
+ else:
464
+ st.warning("No planner insights available.")
465
+
466
+ # Analyst's Analysis
467
+ with tab2:
468
+ analyst_output = getattr(results.tasks_output[1], "raw", "No details available.")
469
+ if analyst_output and analyst_output.strip():
470
+ st.write(analyst_output)
471
+
472
+ # Parse Analyst Output (Key Insights + Data Insights)
473
+ key_insights, data_insights = parse_analyst_output(analyst_output)
474
+ st.subheader("Structured Analyst Output")
475
+ st.write(data_insights)
476
+
477
+ # Create Visualizations if enabled
478
+ charts = []
479
+ if enable_advanced_analysis and data_insights:
480
+ charts = create_visualizations(data_insights)
481
+ else:
482
+ st.info("No data insights available for visualizations.")
483
+
484
+ # Display Data Tables
485
+ table_data = display_table(data_insights)
486
+
487
+ else:
488
+ st.warning("No analyst analysis available.")
489
+
490
+ # Notify user that the analysis is complete
491
+ st.success(f"Analysis completed in {elapsed_time:.2f} seconds.")
492
+
493
+ # Generate the PDF report with Key Insights and Data Insights
494
+ if writer_output:
495
+ pdf_path = generate_pdf_report(
496
+ result=writer_output,
497
+ charts=charts,
498
+ table_data=data_insights,
499
+ metadata={"Technology Area": patent_area, "Stakeholder": stakeholder},
500
+ key_insights=key_insights # Pass key insights to the PDF
501
+ )
502
+
503
+ # Download button for the generated PDF
504
+ with open(pdf_path, "rb") as report_file:
505
+ st.download_button(
506
+ label="📄 Download Report",
507
+ data=report_file,
508
+ file_name="Patent_Strategy_Report.pdf",
509
+ mime="application/pdf"
510
+ )
511
+ else:
512
+ st.warning("Report generation skipped due to missing content.")
513
+
514
+ except Exception as e:
515
+ error_message = traceback.format_exc()
516
+ logging.error(f"An error occurred during execution:\n{error_message}")
517
+ st.error(f"⚠️ An unexpected error occurred:\n{e}")