DrishtiSharma commited on
Commit
488f45f
·
verified ·
1 Parent(s): fdd059c

Create interim.py

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