Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
|
|
| 1 |
import os
|
| 2 |
import time
|
| 3 |
import json
|
|
@@ -14,14 +15,10 @@ load_dotenv()
|
|
| 14 |
# Function to get API keys from HF secrets
|
| 15 |
def get_api_keys():
|
| 16 |
"""Get API keys from environment or Hugging Face Secrets"""
|
| 17 |
-
# Try to get from HF secrets first
|
| 18 |
try:
|
| 19 |
serper_key = os.environ.get('SERPER_API_KEY')
|
| 20 |
openai_key = os.environ.get('OPENAI_API_KEY')
|
| 21 |
-
|
| 22 |
-
# Log for debugging (will appear in HF Space logs)
|
| 23 |
print("API Keys loaded successfully")
|
| 24 |
-
|
| 25 |
return serper_key, openai_key
|
| 26 |
except Exception as e:
|
| 27 |
st.error(f"Error loading API keys: {str(e)}")
|
|
@@ -159,7 +156,6 @@ def update_progress(progress_container, percentage, message=""):
|
|
| 159 |
</div>
|
| 160 |
"""
|
| 161 |
progress_container.markdown(progress_html, unsafe_allow_html=True)
|
| 162 |
-
|
| 163 |
def create_research_crew(topic: str):
|
| 164 |
"""Create the research crew with SerperDev tool integration"""
|
| 165 |
try:
|
|
@@ -203,7 +199,7 @@ def create_research_crew(topic: str):
|
|
| 203 |
)
|
| 204 |
|
| 205 |
research_task = Task(
|
| 206 |
-
description="""
|
| 207 |
Conduct exhaustive market research on {topic} with:
|
| 208 |
|
| 209 |
1. Comprehensive Market Overview:
|
|
@@ -248,8 +244,8 @@ def create_research_crew(topic: str):
|
|
| 248 |
""",
|
| 249 |
agent=researcher,
|
| 250 |
expected_output="Exhaustive research data with comprehensive analysis and verified sources"
|
| 251 |
-
)
|
| 252 |
-
|
| 253 |
description="""
|
| 254 |
Perform comprehensive analysis of the research findings:
|
| 255 |
|
|
@@ -400,8 +396,8 @@ def create_research_crew(topic: str):
|
|
| 400 |
expected_output="Comprehensive JSON containing detailed executive summary and full report",
|
| 401 |
context=[research_task, analysis_task]
|
| 402 |
)
|
| 403 |
-
|
| 404 |
-
|
| 405 |
agents=[researcher, analyst, writer],
|
| 406 |
tasks=[research_task, analysis_task, report_task],
|
| 407 |
verbose=True,
|
|
@@ -409,7 +405,7 @@ def create_research_crew(topic: str):
|
|
| 409 |
)
|
| 410 |
except Exception as e:
|
| 411 |
st.error(f"Error initializing research crew: {str(e)}")
|
| 412 |
-
|
| 413 |
def extract_section(text, section_name):
|
| 414 |
"""Extract a section from the text"""
|
| 415 |
pattern = f"{section_name}.*?\n(.*?)(?=\n\n|$)"
|
|
@@ -439,6 +435,62 @@ def extract_sources(text):
|
|
| 439 |
|
| 440 |
return sources if sources else ["Sources not explicitly mentioned in the report"]
|
| 441 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 442 |
def run_market_research(topic: str, progress_container, chat_container, log_container):
|
| 443 |
"""Run the market research process"""
|
| 444 |
try:
|
|
@@ -456,14 +508,17 @@ def run_market_research(topic: str, progress_container, chat_container, log_cont
|
|
| 456 |
# Research Phase
|
| 457 |
update_progress(progress_container, 25, "Gathering market data...")
|
| 458 |
log_agent_activity("Research Analyst", f"Beginning comprehensive research on {topic}")
|
|
|
|
| 459 |
|
| 460 |
# Analysis Phase
|
| 461 |
update_progress(progress_container, 50, "Analyzing findings...")
|
| 462 |
log_agent_activity("Data Analyst", "Processing research data...")
|
|
|
|
| 463 |
|
| 464 |
# Report Phase
|
| 465 |
update_progress(progress_container, 75, "Generating report...")
|
| 466 |
log_agent_activity("Report Writer", "Compiling final report...")
|
|
|
|
| 467 |
|
| 468 |
# Execute the crew
|
| 469 |
result = crew.kickoff()
|
|
@@ -508,21 +563,11 @@ def main():
|
|
| 508 |
st.error("Failed to load required API keys. Please check your Hugging Face Space secrets.")
|
| 509 |
return
|
| 510 |
|
| 511 |
-
# Initialize SerperDev tool with the key
|
| 512 |
-
try:
|
| 513 |
-
search_tool = SerperDevTool()
|
| 514 |
-
print("SerperDev tool initialized successfully") # Debug log
|
| 515 |
-
except Exception as e:
|
| 516 |
-
st.error(f"Error initializing SerperDev tool: {str(e)}")
|
| 517 |
-
return
|
| 518 |
-
|
| 519 |
# Initialize session states
|
| 520 |
if 'generating' not in st.session_state:
|
| 521 |
st.session_state.generating = False
|
| 522 |
-
if 'agent_logs' not in st.session_state:
|
| 523 |
-
st.session_state.agent_logs = []
|
| 524 |
|
| 525 |
-
# Create tabs
|
| 526 |
tab1, tab2, tab3, tab4 = st.tabs(["Generate Report", "View Reports", "Live Agent Log", "Agent Outputs"])
|
| 527 |
|
| 528 |
with tab1:
|
|
@@ -564,7 +609,7 @@ def main():
|
|
| 564 |
st.error(f"Error generating report: {str(e)}")
|
| 565 |
finally:
|
| 566 |
st.session_state.generating = False
|
| 567 |
-
|
| 568 |
# Show live agent activity in col2
|
| 569 |
with col2:
|
| 570 |
st.subheader("Live Agent Activity")
|
|
@@ -616,7 +661,7 @@ def main():
|
|
| 616 |
st.subheader("Detailed Report")
|
| 617 |
st.markdown(f"""
|
| 618 |
<div class="detailed-section">
|
| 619 |
-
|
| 620 |
</div>
|
| 621 |
""", unsafe_allow_html=True)
|
| 622 |
|
|
@@ -656,42 +701,5 @@ def main():
|
|
| 656 |
st.subheader("Agent Outputs")
|
| 657 |
display_agent_outputs()
|
| 658 |
|
| 659 |
-
def format_json_output(raw_output):
|
| 660 |
-
"""Format CrewOutput or raw string into proper JSON structure"""
|
| 661 |
-
try:
|
| 662 |
-
# Handle CrewOutput object
|
| 663 |
-
if hasattr(raw_output, 'raw_output'):
|
| 664 |
-
raw_text = str(raw_output.raw_output)
|
| 665 |
-
else:
|
| 666 |
-
raw_text = str(raw_output)
|
| 667 |
-
|
| 668 |
-
# Try to find and parse JSON structure
|
| 669 |
-
json_pattern = r"\{[\s\S]*\}"
|
| 670 |
-
match = re.search(json_pattern, raw_text)
|
| 671 |
-
if match:
|
| 672 |
-
try:
|
| 673 |
-
return json.loads(match.group())
|
| 674 |
-
except:
|
| 675 |
-
pass
|
| 676 |
-
|
| 677 |
-
# If no JSON found, create structured format
|
| 678 |
-
return {
|
| 679 |
-
"exec_summary": {
|
| 680 |
-
"summary": extract_section(raw_text, "Executive Summary"),
|
| 681 |
-
"market_size": extract_section(raw_text, "Market Size"),
|
| 682 |
-
"growth_rate": extract_section(raw_text, "Growth Rate"),
|
| 683 |
-
"key_players": extract_section(raw_text, "Key Players")
|
| 684 |
-
},
|
| 685 |
-
"detailed_report": raw_text,
|
| 686 |
-
"sources": extract_sources(raw_text),
|
| 687 |
-
"metrics": {
|
| 688 |
-
"market_size_data": [],
|
| 689 |
-
"growth_rates": [],
|
| 690 |
-
"market_shares": []
|
| 691 |
-
}
|
| 692 |
-
}
|
| 693 |
-
except Exception as e:
|
| 694 |
-
st.error(f"Error formatting output: {str(e)}")
|
| 695 |
-
|
| 696 |
if __name__ == "__main__":
|
| 697 |
main()
|
|
|
|
| 1 |
+
# app.py
|
| 2 |
import os
|
| 3 |
import time
|
| 4 |
import json
|
|
|
|
| 15 |
# Function to get API keys from HF secrets
|
| 16 |
def get_api_keys():
|
| 17 |
"""Get API keys from environment or Hugging Face Secrets"""
|
|
|
|
| 18 |
try:
|
| 19 |
serper_key = os.environ.get('SERPER_API_KEY')
|
| 20 |
openai_key = os.environ.get('OPENAI_API_KEY')
|
|
|
|
|
|
|
| 21 |
print("API Keys loaded successfully")
|
|
|
|
| 22 |
return serper_key, openai_key
|
| 23 |
except Exception as e:
|
| 24 |
st.error(f"Error loading API keys: {str(e)}")
|
|
|
|
| 156 |
</div>
|
| 157 |
"""
|
| 158 |
progress_container.markdown(progress_html, unsafe_allow_html=True)
|
|
|
|
| 159 |
def create_research_crew(topic: str):
|
| 160 |
"""Create the research crew with SerperDev tool integration"""
|
| 161 |
try:
|
|
|
|
| 199 |
)
|
| 200 |
|
| 201 |
research_task = Task(
|
| 202 |
+
description=f"""
|
| 203 |
Conduct exhaustive market research on {topic} with:
|
| 204 |
|
| 205 |
1. Comprehensive Market Overview:
|
|
|
|
| 244 |
""",
|
| 245 |
agent=researcher,
|
| 246 |
expected_output="Exhaustive research data with comprehensive analysis and verified sources"
|
| 247 |
+
)
|
| 248 |
+
analysis_task = Task(
|
| 249 |
description="""
|
| 250 |
Perform comprehensive analysis of the research findings:
|
| 251 |
|
|
|
|
| 396 |
expected_output="Comprehensive JSON containing detailed executive summary and full report",
|
| 397 |
context=[research_task, analysis_task]
|
| 398 |
)
|
| 399 |
+
|
| 400 |
+
return Crew(
|
| 401 |
agents=[researcher, analyst, writer],
|
| 402 |
tasks=[research_task, analysis_task, report_task],
|
| 403 |
verbose=True,
|
|
|
|
| 405 |
)
|
| 406 |
except Exception as e:
|
| 407 |
st.error(f"Error initializing research crew: {str(e)}")
|
| 408 |
+
raise e
|
| 409 |
def extract_section(text, section_name):
|
| 410 |
"""Extract a section from the text"""
|
| 411 |
pattern = f"{section_name}.*?\n(.*?)(?=\n\n|$)"
|
|
|
|
| 435 |
|
| 436 |
return sources if sources else ["Sources not explicitly mentioned in the report"]
|
| 437 |
|
| 438 |
+
def format_json_output(raw_output):
|
| 439 |
+
"""Format CrewOutput or raw string into proper JSON structure"""
|
| 440 |
+
try:
|
| 441 |
+
# Handle CrewOutput object
|
| 442 |
+
if hasattr(raw_output, 'raw_output'):
|
| 443 |
+
raw_text = str(raw_output.raw_output)
|
| 444 |
+
else:
|
| 445 |
+
raw_text = str(raw_output)
|
| 446 |
+
|
| 447 |
+
# Try to find and parse JSON structure
|
| 448 |
+
json_pattern = r"\{[\s\S]*\}"
|
| 449 |
+
match = re.search(json_pattern, raw_text)
|
| 450 |
+
if match:
|
| 451 |
+
try:
|
| 452 |
+
return json.loads(match.group())
|
| 453 |
+
except:
|
| 454 |
+
pass
|
| 455 |
+
|
| 456 |
+
# If no JSON found, create structured format
|
| 457 |
+
return {
|
| 458 |
+
"exec_summary": {
|
| 459 |
+
"summary": extract_section(raw_text, "Executive Summary"),
|
| 460 |
+
"market_size": extract_section(raw_text, "Market Size"),
|
| 461 |
+
"growth_rate": extract_section(raw_text, "Growth Rate"),
|
| 462 |
+
"key_players": extract_section(raw_text, "Key Players")
|
| 463 |
+
},
|
| 464 |
+
"detailed_report": raw_text,
|
| 465 |
+
"sources": extract_sources(raw_text),
|
| 466 |
+
"metrics": {
|
| 467 |
+
"market_size_data": [],
|
| 468 |
+
"growth_rates": [],
|
| 469 |
+
"market_shares": {},
|
| 470 |
+
"regional_distribution": [],
|
| 471 |
+
"segment_analysis": [],
|
| 472 |
+
"competitor_metrics": {},
|
| 473 |
+
"trend_indicators": []
|
| 474 |
+
}
|
| 475 |
+
}
|
| 476 |
+
except Exception as e:
|
| 477 |
+
st.error(f"Error formatting output: {str(e)}")
|
| 478 |
+
return {
|
| 479 |
+
"exec_summary": {
|
| 480 |
+
"summary": "Error formatting report",
|
| 481 |
+
"market_size": "N/A",
|
| 482 |
+
"growth_rate": "N/A",
|
| 483 |
+
"key_players": "N/A"
|
| 484 |
+
},
|
| 485 |
+
"detailed_report": raw_text if 'raw_text' in locals() else str(raw_output),
|
| 486 |
+
"sources": [],
|
| 487 |
+
"metrics": {
|
| 488 |
+
"market_size_data": [],
|
| 489 |
+
"growth_rates": [],
|
| 490 |
+
"market_shares": {}
|
| 491 |
+
}
|
| 492 |
+
}
|
| 493 |
+
|
| 494 |
def run_market_research(topic: str, progress_container, chat_container, log_container):
|
| 495 |
"""Run the market research process"""
|
| 496 |
try:
|
|
|
|
| 508 |
# Research Phase
|
| 509 |
update_progress(progress_container, 25, "Gathering market data...")
|
| 510 |
log_agent_activity("Research Analyst", f"Beginning comprehensive research on {topic}")
|
| 511 |
+
time.sleep(1)
|
| 512 |
|
| 513 |
# Analysis Phase
|
| 514 |
update_progress(progress_container, 50, "Analyzing findings...")
|
| 515 |
log_agent_activity("Data Analyst", "Processing research data...")
|
| 516 |
+
time.sleep(1)
|
| 517 |
|
| 518 |
# Report Phase
|
| 519 |
update_progress(progress_container, 75, "Generating report...")
|
| 520 |
log_agent_activity("Report Writer", "Compiling final report...")
|
| 521 |
+
time.sleep(1)
|
| 522 |
|
| 523 |
# Execute the crew
|
| 524 |
result = crew.kickoff()
|
|
|
|
| 563 |
st.error("Failed to load required API keys. Please check your Hugging Face Space secrets.")
|
| 564 |
return
|
| 565 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 566 |
# Initialize session states
|
| 567 |
if 'generating' not in st.session_state:
|
| 568 |
st.session_state.generating = False
|
|
|
|
|
|
|
| 569 |
|
| 570 |
+
# Create tabs
|
| 571 |
tab1, tab2, tab3, tab4 = st.tabs(["Generate Report", "View Reports", "Live Agent Log", "Agent Outputs"])
|
| 572 |
|
| 573 |
with tab1:
|
|
|
|
| 609 |
st.error(f"Error generating report: {str(e)}")
|
| 610 |
finally:
|
| 611 |
st.session_state.generating = False
|
| 612 |
+
|
| 613 |
# Show live agent activity in col2
|
| 614 |
with col2:
|
| 615 |
st.subheader("Live Agent Activity")
|
|
|
|
| 661 |
st.subheader("Detailed Report")
|
| 662 |
st.markdown(f"""
|
| 663 |
<div class="detailed-section">
|
| 664 |
+
{report['detailed_report']}
|
| 665 |
</div>
|
| 666 |
""", unsafe_allow_html=True)
|
| 667 |
|
|
|
|
| 701 |
st.subheader("Agent Outputs")
|
| 702 |
display_agent_outputs()
|
| 703 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 704 |
if __name__ == "__main__":
|
| 705 |
main()
|