crew-climate / app.py
poemsforaphrodite's picture
Update app.py
db301e1 verified
import os
from dotenv import load_dotenv
import streamlit as st
from crewai import Agent, Task, Crew
from crewai_tools import SerperDevTool, WebsiteSearchTool, FileReadTool
from openai import OpenAI
import tempfile
import time
# Load environment variables
load_dotenv()
# Get API keys from environment variables
SERPER_API_KEY = os.getenv("SERPER_API_KEY")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# Initialize OpenAI API
client = OpenAI(api_key=OPENAI_API_KEY)
# Create assistant
assistant = client.beta.assistants.create(
name="Climate Strategy Assistant",
instructions="You are an expert in climate strategy. Analyze climate strategy documents and provide relevant insights.",
model="gpt-4o",
tools=[{"type": "file_search"}],
)
# Instantiate tools
file_tool = FileReadTool(file_path='analysis.txt') # Adjusted to read analysis.txt
search_tool = SerperDevTool()
web_rag_tool = WebsiteSearchTool()
# Create agents
analyst = Agent(
role='Climate Strategy Analyst',
goal='Analyze the climate strategy plan to identify key requirements and objectives.',
backstory='An expert in climate strategy with experience in sustainable solutions.',
tools=[file_tool],
verbose=True
)
researcher = Agent(
role='Climate Tech Researcher',
goal='Find and list specific climate tech companies that provide solutions aligning with the strategy plan.',
backstory='A researcher specialized in identifying and evaluating climate technology solutions, with a focus on practical implementations.',
tools=[search_tool, web_rag_tool],
verbose=True
)
# Define tasks
analyze_strategy = Task(
description='Analyze the climate strategy plan from analysis.txt and extract key requirements.',
expected_output='A detailed list of key requirements and objectives from the climate strategy plan.',
agent=analyst
)
search_companies = Task(
description='Search for and list specific climate tech companies that offer solutions meeting the extracted strategy requirements. Provide company names, brief descriptions of their solutions, and how they align with the strategy needs.',
expected_output='A detailed list of climate tech companies, including company names, solution descriptions, and how they align with the strategy requirements.',
agent=researcher,
output_file='research_results/company_recommendations.md'
)
# Assemble a crew with planning enabled
crew = Crew(
agents=[analyst, researcher],
tasks=[analyze_strategy, search_companies],
verbose=True,
planning=True,
)
def process_file_with_assistant(file, file_type, category, reports_needed, user_feedback):
print(f"Starting {file_type} processing with Assistant")
try:
# Upload the file to OpenAI
uploaded_file = client.files.create(
file=file,
purpose='assistants'
)
print(f"File uploaded successfully. File ID: {uploaded_file.id}")
# Create an assistant
assistant = client.beta.assistants.create(
name=f"{file_type} Analyzer",
instructions=f"You are an expert in analyzing {file_type} files, focusing on {category}. Provide insights and summaries of the content based on the following reports: {', '.join(reports_needed)}. Consider the user's previous feedback: {user_feedback}. Provide your response in plain text format without any formatting, bullet points, numbering, or source citations. Do not use asterisks, hashes, or any other special characters for emphasis or structure.",
model="gpt-4o",
tools=[{"type": "file_search"}]
)
print(f"Assistant created. Assistant ID: {assistant.id}")
# Create a thread
thread = client.beta.threads.create()
print(f"Thread created. Thread ID: {thread.id}")
# Add a message to the thread
message = client.beta.threads.messages.create(
thread_id=thread.id,
role="user",
content=f"Please analyze this file and provide insights for the {category} category, focusing on the following reports: {', '.join(reports_needed)}.",
attachments=[
{"file_id": uploaded_file.id, "tools": [{"type": "file_search"}]}
]
)
print(f"Message added to thread. Message ID: {message.id}")
# Run the assistant
run = client.beta.threads.runs.create(
thread_id=thread.id,
assistant_id=assistant.id,
additional_instructions="Use the uploaded file to answer the question. Provide your response in plain text format without any formatting, bullet points, numbering, or source citations. Do not use asterisks, hashes, or any other special characters for emphasis or structure."
)
print(f"Run created. Run ID: {run.id}")
# Wait for the run to complete
while run.status != 'completed':
run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
print(f"Run status: {run.status}")
time.sleep(1)
# Retrieve the messages
messages = client.beta.threads.messages.list(thread_id=thread.id)
# Extract the assistant's response
analysis_result = next((msg.content[0].text.value for msg in messages if msg.role == 'assistant'), None)
print(f"{file_type} analysis completed successfully")
return analysis_result
except Exception as e:
print(f"Error in processing {file_type}: {str(e)}")
return None
# Update the existing process_pdf_with_assistant function
def process_pdf_with_assistant(uploaded_file):
"""Process the uploaded PDF using the Assistants API."""
return process_file_with_assistant(
file=uploaded_file,
file_type="PDF",
category="climate strategy",
reports_needed=["key points summary"],
user_feedback=""
)
def save_processed_content(content, filename='analysis.txt'):
"""Save the processed content to a text file."""
if content is not None:
with open(filename, 'w') as f:
f.write(content)
else:
print("No content to save.")
def run_crew():
# Create crew and execute tasks
result = crew.kickoff()
# Read and return the content of the output file
with open('research_results/company_recommendations.md', 'r') as f:
return f.read()
# Initialize session state variables
if 'pdf_processed' not in st.session_state:
st.session_state.pdf_processed = False
if 'processed_content' not in st.session_state:
st.session_state.processed_content = None
# Streamlit interface
st.title("Climate Tech Company Finder")
st.write("Upload a PDF to analyze climate strategy and find relevant companies.")
# PDF Upload
uploaded_pdf = st.file_uploader("Upload your climate strategy PDF", type=["pdf"])
if uploaded_pdf is not None:
# Button to trigger PDF analysis
if st.button("Run PDF Analysis") or st.session_state.pdf_processed:
if not st.session_state.pdf_processed:
with st.spinner("Processing PDF..."):
# Process PDF with Assistants API
st.session_state.processed_content = process_pdf_with_assistant(uploaded_pdf)
if st.session_state.processed_content:
# Save processed content to analysis.txt
save_processed_content(st.session_state.processed_content, 'analysis.txt')
st.session_state.pdf_processed = True
st.success("PDF processed successfully.")
else:
st.error("Failed to process the PDF. Please try again.")
if st.session_state.pdf_processed:
# Display the PDF analysis to the user
st.subheader("PDF Analysis")
st.text_area("Key Points Summary", st.session_state.processed_content, height=200)
# Only show the crew analysis button after PDF analysis is complete
if st.button("Run Crew Analysis"):
with st.spinner("Running crew analysis..."):
result = run_crew()
st.subheader("Company Recommendations")
st.markdown(result) # Use markdown to preserve formatting
else:
st.info("Please upload a climate strategy PDF to begin.")