diff --git a/game-builder-crew/agents.py b/game-builder-crew/agents.py index 9bd3e0030..3fa3f4b84 100644 --- a/game-builder-crew/agents.py +++ b/game-builder-crew/agents.py @@ -1,7 +1,18 @@ +import os + +from langchain_openai.chat_models import ChatOpenAI from textwrap import dedent from crewai import Agent +from dotenv import load_dotenv() +load_dotenv() + +api_key = os.getenv("OPENAI_API_KEY") + class GameAgents(): + def __init__(self): + self.llm = ChatOpenAI(api_key = api_key) + def senior_engineer_agent(self): return Agent( role='Senior Software Engineer', @@ -11,6 +22,7 @@ def senior_engineer_agent(self): Your expertise in programming in python. and do your best to produce perfect code"""), allow_delegation=False, + llm= self.llm, verbose=True ) @@ -26,7 +38,8 @@ def qa_engineer_agent(self): brackets and syntax errors. You also check for security vulnerabilities, and logic errors"""), allow_delegation=False, - verbose=True + verbose=True, + llm = self.llm ) def chief_qa_engineer_agent(self): @@ -37,5 +50,6 @@ def chief_qa_engineer_agent(self): You feel that programmers always do only half the job, so you are super dedicate to make high quality code."""), allow_delegation=True, - verbose=True + verbose=True, + llm = self.llm ) \ No newline at end of file diff --git a/game-builder-crew/tasks.py b/game-builder-crew/tasks.py index c4be40fbb..667462e77 100644 --- a/game-builder-crew/tasks.py +++ b/game-builder-crew/tasks.py @@ -11,6 +11,7 @@ def code_task(self, agent, game): Your Final answer must be the full python code, only the python code and nothing else. """), + expected_output="Full python code of required function", agent=agent ) @@ -28,6 +29,7 @@ def review_task(self, agent, game): Your Final answer must be the full python code, only the python code and nothing else. """), + expected_output= "Fully functional python code of the required functions", agent=agent ) @@ -44,5 +46,6 @@ def evaluate_task(self, agent, game): Your Final answer must be the full python code, only the python code and nothing else. """), + expected_output= "Fully functional code of the required function", agent=agent ) \ No newline at end of file diff --git a/instagram_post/tools/browser_tools.py b/instagram_post/tools/browser_tools.py index cfc72d36a..6caae490c 100644 --- a/instagram_post/tools/browser_tools.py +++ b/instagram_post/tools/browser_tools.py @@ -34,7 +34,8 @@ def scrape_and_summarize_website(website): task = Task( agent=agent, description= - f'Analyze and make a LONG summary the content bellow, make sure to include the ALL relevant information in the summary, return only the summary nothing else.\n\nCONTENT\n----------\n{chunk}' + f'Analyze and make a LONG summary the content bellow, make sure to include the ALL relevant information in the summary, return only the summary nothing else.\n\nCONTENT\n----------\n{chunk}', + expected_output= "A detailed summary of the content" ) summary = task.execute() summaries.append(summary) diff --git a/job-posting/main.py b/job-posting/main.py index f381b32b2..9474afb35 100644 --- a/job-posting/main.py +++ b/job-posting/main.py @@ -1,7 +1,12 @@ +import os + from dotenv import load_dotenv load_dotenv() +api_key = os.getenv("OPENAI_API_KEY") + -from crewai import Crew +from crewai import Crew, Process +from langchain_openai.chat_models import ChatOpenAI from tasks import Tasks from agents import Agents @@ -9,6 +14,8 @@ tasks = Tasks() agents = Agents() +llm = ChatOpenAI(api_key=api_key) + company_description = input("What is the company description?\n") company_domain = input("What is the company domain?\n") hiring_needs = input("What are the hiring needs?\n") @@ -35,7 +42,9 @@ research_role_requirements_task, draft_job_posting_task, review_and_edit_job_posting_task - ] + ], + process = Process.sequential, + manager_llm = llm ) # Kick off the process diff --git a/landing_page_generator/main.py b/landing_page_generator/main.py index 30a2868c1..780c7b81c 100644 --- a/landing_page_generator/main.py +++ b/landing_page_generator/main.py @@ -3,7 +3,9 @@ import shutil from textwrap import dedent -from crewai import Agent, Crew, Task +from langchain_openai.chat_models import ChatOpenAI +from langchain_community.chat_models import ChatOllama +from crewai import Agent, Crew, Task, Process from langchain.agents.agent_toolkits import FileManagementToolkit from tasks import TaskPrompts @@ -15,11 +17,14 @@ from dotenv import load_dotenv load_dotenv() +api_key = os.getenv("OPENAI_API_KEY") + class LandingPageCrew(): def __init__(self, idea): self.agents_config = json.loads(open("config/agents.json", "r").read()) self.idea = idea self.__create_agents() + self.openai = ChatOpenAI(api_key= api_key) def run(self): expanded_idea = self.__expand_idea() @@ -29,16 +34,20 @@ def run(self): def __expand_idea(self): expand_idea_task = Task( description=TaskPrompts.expand().format(idea=self.idea), + expected_output="A detailed and correct output", agent=self.idea_analyst ) refine_idea_task = Task( description=TaskPrompts.refine_idea(), + expected_output = "A detailed and correct output", agent=self.communications_strategist ) crew = Crew( agents=[self.idea_analyst, self.communications_strategist], tasks=[expand_idea_task, refine_idea_task], - verbose=True + verbose=True, + process = Process.sequential, + manager_llm = self.openai ) expanded_idea = crew.kickoff() return expanded_idea @@ -48,18 +57,22 @@ def __choose_template(self, expanded_idea): description=TaskPrompts.choose_template().format( idea=self.idea ), - agent=self.react_developer + agent=self.react_developer, + expected_output = "A detailed and relevant output" ) update_page = Task( description=TaskPrompts.update_page().format( idea=self.idea ), - agent=self.react_developer + agent=self.react_developer, + expected_output = " A detailed and correct output" ) crew = Crew( agents=[self.react_developer], tasks=[choose_template_task, update_page], - verbose=True + verbose=True, + process = Process.sequential, + manager_llm = self.openai ) components = crew.kickoff() return components @@ -79,6 +92,7 @@ def __update_components(self, components, expanded_idea): file_content=file_content, component=component ), + expected_output = "A detailed and correct output", agent=self.content_editor_agent ) update_component = Task( @@ -86,18 +100,23 @@ def __update_components(self, components, expanded_idea): component=component, file_content=file_content ), + expected_output = "A detailed and correct output" agent=self.react_developer ) qa_component = Task( description=TaskPrompts.qa_component().format( component=component ), - agent=self.react_developer + agent=self.react_developer, + expected_output= "A detailed and correct output" ) crew = Crew( agents=[self.content_editor_agent, self.react_developer], tasks=[create_content, update_component, qa_component], - verbose=True + verbose=True, + process = Process.sequential, + manager_llm = self.openai + ) crew.kickoff() @@ -118,7 +137,8 @@ def __create_agents(self): tools=[ SearchTools.search_internet, BrowserTools.scrape_and_summarize_website - ] + ], + llm = self.openai ) self.communications_strategist = Agent( @@ -127,12 +147,14 @@ def __create_agents(self): tools=[ SearchTools.search_internet, BrowserTools.scrape_and_summarize_website, - ] + ], + llm= self.openai ) self.react_developer = Agent( **developer_config, verbose=True, + llm= self.openai, tools=[ SearchTools.search_internet, BrowserTools.scrape_and_summarize_website, @@ -140,6 +162,7 @@ def __create_agents(self): TemplateTools.copy_landing_page_template_to_project_folder, FileTools.write_file ] + toolkit.get_tools() + ) self.content_editor_agent = Agent( @@ -147,7 +170,8 @@ def __create_agents(self): tools=[ SearchTools.search_internet, BrowserTools.scrape_and_summarize_website, - ] + ], + llm = self.openai ) if __name__ == "__main__": diff --git a/landing_page_generator/tools/browser_tools.py b/landing_page_generator/tools/browser_tools.py index 36a10a9f2..36e9bac45 100644 --- a/landing_page_generator/tools/browser_tools.py +++ b/landing_page_generator/tools/browser_tools.py @@ -4,8 +4,12 @@ import requests from crewai import Agent, Task from langchain.tools import tool +from langchain_openai.chat_models import ChatOpenAI from unstructured.partition.html import partition_html +from dotenv import load_dotenv +load_dotenv() +api_key = os.getenv('OPENAI_API_KEY') class BrowserTools(): @@ -27,11 +31,14 @@ def scrape_and_summarize_website(website): 'Do amazing researches and summaries based on the content you are working with', backstory= "You're a Principal Researcher at a big company and you need to do a research about a given topic.", - allow_delegation=False) + allow_delegation=False, + llm = ChatOpenAI(api_key = api_key) + ) task = Task( agent=agent, description= - f'Analyze and summarize the content bellow, make sure to include the most relevant information in the summary, return only the summary nothing else.\n\nCONTENT\n----------\n{chunk}' + f'Analyze and summarize the content bellow, make sure to include the most relevant information in the summary, return only the summary nothing else.\n\nCONTENT\n----------\n{chunk}', + expected_output = "A detailed summary of the content" ) summary = task.execute() summaries.append(summary) diff --git a/markdown_validator/main.py b/markdown_validator/main.py index a86caeba5..3604a3b66 100644 --- a/markdown_validator/main.py +++ b/markdown_validator/main.py @@ -1,5 +1,5 @@ import sys -from crewai import Agent, Task +from crewai import Agent, Task, Process import os from dotenv import load_dotenv from langchain.tools import tool @@ -70,6 +70,7 @@ def process_markdown_document(filename): If you already know the answer or if you do not need to use a tool, return it as your Final Answer.""", + expected_output = "Valid markdown script", agent=general_agent) updated_markdown = syntax_review_task.execute() diff --git a/ollama_setup/gemmaModelfile b/ollama_setup/gemmaModelfile new file mode 100644 index 000000000..bb931cae4 --- /dev/null +++ b/ollama_setup/gemmaModelfile @@ -0,0 +1,13 @@ +FROM gemma + +# Set parementers + +PARAMETER temperature 0.3 +PARAMETER stop Result + +# Sets a custom system message to specify the behavior of +# the chat assistant + +# Leaving it blank for now. + +SYSTEM """You are an expert in any required domain""" \ No newline at end of file diff --git a/ollama_setup/gemma_crewai_setup.sh b/ollama_setup/gemma_crewai_setup.sh new file mode 100644 index 000000000..b9ff5f6c1 --- /dev/null +++ b/ollama_setup/gemma_crewai_setup.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Variables +model_name="gemma" +custom_model_name="crewai-gemma" + +# Get the base model +ollama pull $model_name + +# Create the model file +ollama create $custom_model_name -f ./gemmaModelfile + +# enter "chmod +x " to make file executable \ No newline at end of file diff --git a/ollama_setup/llama2Modelfile b/ollama_setup/llama2Modelfile new file mode 100644 index 000000000..32b2fd2b1 --- /dev/null +++ b/ollama_setup/llama2Modelfile @@ -0,0 +1,13 @@ +FROM llama2 + +# Set parementers + +PARAMETER temperature 0.3 +PARAMETER stop Result + +# Sets a custom system message to specify the behavior of +# the chat assistant + +# Leaving it blank for now. + +SYSTEM """You are an expert in any required domain""" \ No newline at end of file diff --git a/ollama_setup/llama_crewai_setup.sh b/ollama_setup/llama_crewai_setup.sh new file mode 100644 index 000000000..499c222da --- /dev/null +++ b/ollama_setup/llama_crewai_setup.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Variables +model_name="llama2" +custom_model_name="crewai-llama2" + +# Get the base model +ollama pull $model_name + +# Create the model file +ollama create $custom_model_name -f ./llama2Modelfile + +# enter "chmod +x " to make file executable \ No newline at end of file diff --git a/ollama_setup/mistralModelfile b/ollama_setup/mistralModelfile new file mode 100644 index 000000000..b53eae499 --- /dev/null +++ b/ollama_setup/mistralModelfile @@ -0,0 +1,13 @@ +FROM mistral + +# Set parementers + +PARAMETER temperature 0.3 +PARAMETER stop Result + +# Sets a custom system message to specify the behavior of +# the chat assistant + +# Leaving it blank for now. + +SYSTEM """You are an expert in any required domain""" \ No newline at end of file diff --git a/ollama_setup/mistral_crewai_setup.sh b/ollama_setup/mistral_crewai_setup.sh new file mode 100644 index 000000000..b2ad6a16e --- /dev/null +++ b/ollama_setup/mistral_crewai_setup.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Variables +model_name="mistral" +custom_model_name="crewai-mistral" + +# Get the base model +ollama pull $model_name + +# Create the model file +ollama create $custom_model_name -f ./mistralModelfile + +# enter "chmod +x " to make file executable \ No newline at end of file diff --git a/ollama_setup/setup_readme.md b/ollama_setup/setup_readme.md new file mode 100644 index 000000000..36af887b0 --- /dev/null +++ b/ollama_setup/setup_readme.md @@ -0,0 +1,32 @@ +# Ollama Configuration Repository +This repository helps you get started with setting up and configuring Ollama. Please find below the steps for successful completion: + +## Steps: +### 1. Install Ollama + **For Ubuntu**: Use the following command in your terminal: +curl -fsSL https://ollama.com/install.sh | sh + + **For Windows and MacOS**: Please refer the following link: +https://ollama.com/download + +### 2. Start Server + Enter the following command to see how to start the server: +ollama --help + + Usually, the server can be started using: +ollama serve + + or +ollama start + + +### 3. Model Configuration + Create a `Modelfile` for each of the models you are using. The `Modelfile` helps to configure the system message. + +### 4. Modelname Crewai setup + Run the `_crewai_setup.sh` file using the following command: +chmod +x `` + + Here, replace `` with the name of your setup file. + +For any issues, you can view the [documentation](https://ollama.com/docs) or open a GitHub issue in this repository. \ No newline at end of file diff --git a/prep-for-a-meeting/agents.py b/prep-for-a-meeting/agents.py index 1e5c96c34..846988a5e 100644 --- a/prep-for-a-meeting/agents.py +++ b/prep-for-a-meeting/agents.py @@ -1,9 +1,17 @@ from textwrap import dedent from crewai import Agent +from lanchain_openai.chat_models import ChatOpenAI +from langchain_community.chat_models import ChatOllama from tools.ExaSearchTool import ExaSearchTool class MeetingPreparationAgents(): + + def __init__(self): + self.mistral = ChatOllama(model="crewai-mistral") + self.llama2 = ChatOllama(model="crewai-llama2") + self.openai = ChatOpenAI(api_key = api_key, temperature=0) + def research_agent(self): return Agent( role='Research Specialist', @@ -13,7 +21,8 @@ def research_agent(self): As a Research Specialist, your mission is to uncover detailed information about the individuals and entities participating in the meeting. Your insights will lay the groundwork for strategic meeting preparation."""), - verbose=True + verbose=True, + llm = self.openai ) def industry_analysis_agent(self): @@ -25,7 +34,8 @@ def industry_analysis_agent(self): As an Industry Analyst, your analysis will identify key trends, challenges facing the industry, and potential opportunities that could be leveraged during the meeting for strategic advantage."""), - verbose=True + verbose=True, + llm = self.openai ) def meeting_strategy_agent(self): @@ -37,7 +47,8 @@ def meeting_strategy_agent(self): As a Strategy Advisor, your expertise will guide the development of talking points, insightful questions, and strategic angles to ensure the meeting's objectives are achieved."""), - verbose=True + verbose=True, + llm = self.openai ) def summary_and_briefing_agent(self): @@ -48,5 +59,7 @@ def summary_and_briefing_agent(self): backstory=dedent("""\ As the Briefing Coordinator, your role is to consolidate the research, analysis, and strategic insights."""), - verbose=True + verbose=True, + llm = self.openai + ) diff --git a/prep-for-a-meeting/main.py b/prep-for-a-meeting/main.py index eb5705153..88621fd67 100644 --- a/prep-for-a-meeting/main.py +++ b/prep-for-a-meeting/main.py @@ -1,7 +1,7 @@ from dotenv import load_dotenv load_dotenv() -from crewai import Crew +from crewai import Crew, Process from tasks import MeetingPreparationTasks from agents import MeetingPreparationAgents @@ -43,7 +43,9 @@ industry_analysis, meeting_strategy, summary_and_briefing - ] + ], + process = Process.sequential, + manager_llm = self.openai ) game = crew.kickoff() diff --git a/screenplay_writer/screenplay_writer.py b/screenplay_writer/screenplay_writer.py index 47b318f44..b9cf119c8 100644 --- a/screenplay_writer/screenplay_writer.py +++ b/screenplay_writer/screenplay_writer.py @@ -15,7 +15,7 @@ import re from crewai import Agent, Task, Crew, Process from langchain.agents import AgentType, initialize_agent, load_tools -from langchain.chat_models import openai +from langchain_openai.chat_models import ChatOpenAI #endpoint specific imports import langchain_mistralai from langchain_mistralai.chat_models import ChatMistralAI @@ -43,7 +43,7 @@ elif endpoint == 'togetherai': #i get timeouts using Together() , so i use ChatOpenAI() instead #mixtral = Together(model="mistralai/Mistral-7B-Instruct-v0.2", together_api_key=togetherai_key ) #or mistralai/Mixtral-8x7B-Instruct-v0.1 - mixtral= openai.ChatOpenAI(base_url="https://api.together.xyz/v1", api_key=togetherai_key, temperature=0.5, model="mistralai/Mistral-7B-Instruct-v0.2") + mixtral= ChatOpenAI(base_url="https://api.together.xyz/v1", api_key=togetherai_key, temperature=0.5, model="mistralai/Mistral-7B-Instruct-v0.2") elif endpoint == 'anyscale': mixtral = ChatAnyscale(model='mistralai/Mistral-7B-Instruct-v0.1', api_key=anyscale_key, streaming=False) @@ -174,15 +174,17 @@ ''' # Filter out spam and vulgar posts -task0 = Task(description='Read the following newsgroup post. If this contains vulgar language reply with STOP . If this is spam reply with STOP.\n### NEWGROUP POST:\n' + discussion, agent=spamfilter) +task0 = Task(description='Read the following newsgroup post. If this contains vulgar language reply with STOP . If this is spam reply with STOP.\n### NEWGROUP POST:\n' + discussion, + expected_output = "A valid response based on the newsgroup post", + agent=spamfilter) result = task0.execute() if "STOP" in result: #stop here and proceed to next post print('This spam message will be filtered out') # process post with a crew of agents, ultimately delivering a well formatted dialogue -task1 = Task(description='Analyse in much detail the following discussion:\n### DISCUSSION:\n' + discussion, agent=analyst) -task2 = Task(description='Create a dialogue heavy screenplay from the discussion, between two persons. Do NOT write parentheticals. Leave out wrylies. You MUST SKIP directional notes.', agent=scriptwriter) +task1 = Task(description='Analyse in much detail the following discussion:\n### DISCUSSION:\n' + discussion,expected_output="Detailed analysis of the discussion", agent=analyst) +task2 = Task(description='Create a dialogue heavy screenplay from the discussion, between two persons. Do NOT write parentheticals. Leave out wrylies. You MUST SKIP directional notes.', expected_output="A comprehensive dialogue from the discussion", context = [task1], agent=scriptwriter) task3 = Task(description='''Format the script exactly like this: ## (person 1): (first text line from person 1) @@ -196,7 +198,9 @@ ## (person 2): (second text line from person 2) - ''', agent=formatter) + ''', expected_output='An output with the required formatting', + context = [tast2], + agent=formatter) crew = Crew( agents=[analyst, scriptwriter,formatter], tasks=[task1, task2, task3], diff --git a/starter_template/main.py b/starter_template/main.py index 403b98eeb..ebf704657 100644 --- a/starter_template/main.py +++ b/starter_template/main.py @@ -25,6 +25,7 @@ class CustomCrew: def __init__(self, var1, var2): self.var1 = var1 self.var2 = var2 + self.openai = ChatOpenAI() def run(self): # Define your custom agents and tasks in agents.py and tasks.py @@ -51,6 +52,9 @@ def run(self): agents=[custom_agent_1, custom_agent_2], tasks=[custom_task_1, custom_task_2], verbose=True, + process = Process.hierarchical, # or Process.Sequential + manager_llm = self.openai + ) result = crew.kickoff() diff --git a/starter_template/tasks.py b/starter_template/tasks.py index d59214fee..14298f859 100644 --- a/starter_template/tasks.py +++ b/starter_template/tasks.py @@ -23,6 +23,7 @@ def task_1_name(self, agent, var1, var2): And also this variable: {var2} """ ), + expected_output = "Expected output", agent=agent, ) @@ -37,5 +38,6 @@ def task_2_name(self, agent): Make sure to do something else. """ ), + expected_output = "Expected Output" agent=agent, ) diff --git a/stock_analysis/main.py b/stock_analysis/main.py index 353a0c305..a51e28529 100644 --- a/stock_analysis/main.py +++ b/stock_analysis/main.py @@ -1,4 +1,4 @@ -from crewai import Crew +from crewai import Crew, Process from textwrap import dedent from stock_analysis_agents import StockAnalysisAgents @@ -7,9 +7,13 @@ from dotenv import load_dotenv load_dotenv() +api_key = os.getenv("OPENAI_API_KEY") + class FinancialCrew: def __init__(self, company): self.company = company + self.mistral = ChatOllama(model="mistral") + self.openai = ChatOpenAI(api_key=api_key, temperature=0) def run(self): agents = StockAnalysisAgents() @@ -20,9 +24,9 @@ def run(self): investment_advisor_agent = agents.investment_advisor() research_task = tasks.research(research_analyst_agent, self.company) - financial_task = tasks.financial_analysis(financial_analyst_agent) - filings_task = tasks.filings_analysis(financial_analyst_agent) - recommend_task = tasks.recommend(investment_advisor_agent) + financial_task = tasks.financial_analysis(financial_analyst_agent, [research_task]) + filings_task = tasks.filings_analysis(financial_analyst_agent, [research_task, financial_task]) + recommend_task = tasks.recommend(investment_advisor_agent, [research_task, financial_task, filings_task]) crew = Crew( agents=[ @@ -36,7 +40,9 @@ def run(self): filings_task, recommend_task ], - verbose=True + process = Process.sequential, # Another option is Hierarichical process + verbose=True, + manager_llm = self.openai ) result = crew.kickoff() diff --git a/stock_analysis/stock_analysis_agents.py b/stock_analysis/stock_analysis_agents.py index b7ba5b9e2..91b48b3e9 100644 --- a/stock_analysis/stock_analysis_agents.py +++ b/stock_analysis/stock_analysis_agents.py @@ -1,13 +1,25 @@ +import os from crewai import Agent +from langchain_community.chat_models import ChatOllama +from langchain_openai.chat_models import ChatOpenAI +from langchain.tools.yahoo_finance_news import YahooFinanceNewsTool from tools.browser_tools import BrowserTools from tools.calculator_tools import CalculatorTools from tools.search_tools import SearchTools from tools.sec_tools import SECTools -from langchain.tools.yahoo_finance_news import YahooFinanceNewsTool +from dotenv import load_dotenv +load_dotenv + +api_key = os.getenv("OPENAI_API_KEY") class StockAnalysisAgents(): + def __init__(self): + self.mistral = ChatOllama(model="crewai-mistral") + self.llama2 = ChatOllama(model= "crewai-llama2") + self.openai = ChatOpenAI(api_key=api_key) + def financial_analyst(self): return Agent( role='The Best Financial Analyst', @@ -23,7 +35,9 @@ def financial_analyst(self): CalculatorTools.calculate, SECTools.search_10q, SECTools.search_10k - ] + ], + max_iter = 15, + llm = self.openai ) def research_analyst(self): @@ -43,7 +57,9 @@ def research_analyst(self): YahooFinanceNewsTool(), SECTools.search_10q, SECTools.search_10k - ] + ], + allow_delegation = True, + llm = self.openai ) def investment_advisor(self): @@ -62,5 +78,6 @@ def investment_advisor(self): SearchTools.search_news, CalculatorTools.calculate, YahooFinanceNewsTool() - ] + ], + llm = self.openai ) \ No newline at end of file diff --git a/stock_analysis/stock_analysis_tasks.py b/stock_analysis/stock_analysis_tasks.py index 86dd0d4c8..dded565bb 100644 --- a/stock_analysis/stock_analysis_tasks.py +++ b/stock_analysis/stock_analysis_tasks.py @@ -23,10 +23,15 @@ def research(self, agent, company): Selected company by the customer: {company} """), + expected_output= f"""A detailed summary of news articles, press releases + and market analyses related to the stock and the financial industry guided + by the market sentiment. + """, + async_execution = True, agent=agent ) - def financial_analysis(self, agent): + def financial_analysis(self, agent, context): return Task(description=dedent(f""" Conduct a thorough analysis of the stock's financial health and market performance. @@ -44,10 +49,14 @@ def financial_analysis(self, agent): Make sure to use the most recent data possible. """), + expected_output=f"""An output of a detailed financial analysis + for the stock, containing P/E ratio, EPS growth, revenue trends + debt-to-equity ratio and any other information you find relevant""", + context = context, agent=agent ) - def filings_analysis(self, agent): + def filings_analysis(self, agent, context): return Task(description=dedent(f""" Analyze the latest 10-Q and 10-K filings from EDGAR for the stock in question. @@ -63,10 +72,14 @@ def filings_analysis(self, agent): your customer. {self.__tip_section()} """), + expected_output= f"A detailed filings analysis containing Management's + Discussion and Analysis, financial statements, insider trading activity, + and any other disclosed risks that you find relevant", + context = context, agent=agent ) - def recommend(self, agent): + def recommend(self, agent, context): return Task(description=dedent(f""" Review and synthesize the analyses provided by the Financial Analyst and the Research Analyst. @@ -86,6 +99,10 @@ def recommend(self, agent): Make it pretty and well formatted for your customer. {self.__tip_section()} """), + expected_output = f'A comprehensive investment recommendation based on + the context provided by the financial analyst, research analyst and + filing analyst', + context = context, agent=agent ) diff --git a/stock_analysis/tools/browser_tools.py b/stock_analysis/tools/browser_tools.py index 2e8343e3b..5469e69e0 100644 --- a/stock_analysis/tools/browser_tools.py +++ b/stock_analysis/tools/browser_tools.py @@ -5,6 +5,12 @@ from crewai import Agent, Task from langchain.tools import tool from unstructured.partition.html import partition_html +from langchain_openai.chat_models import ChatOpenAI + +from dotenv import load_dotenv +load_dotenv() + +api_key = os.getenv("OPENAI_API_KEY") class BrowserTools(): @@ -27,9 +33,11 @@ def scrape_and_summarize_website(website): 'Do amazing research and summaries based on the content you are working with', backstory= "You're a Principal Researcher at a big company and you need to do research about a given topic.", - allow_delegation=False) + allow_delegation=False, + llm = ChatOpenAI(api_key = api_key)) task = Task( agent=agent, + expected_output="detailed summary of the provided content" description= f'Analyze and summarize the content below, make sure to include the most relevant information in the summary, return only the summary nothing else.\n\nCONTENT\n----------\n{chunk}' ) diff --git a/stock_analysis/tools/calculator_tools.py b/stock_analysis/tools/calculator_tools.py index fbe764798..5fd9f1e28 100644 --- a/stock_analysis/tools/calculator_tools.py +++ b/stock_analysis/tools/calculator_tools.py @@ -5,9 +5,12 @@ class CalculatorTools(): @tool("Make a calculation") def calculate(operation): - """Useful to perform any mathematical calculations, - like sum, minus, multiplication, division, etc. - The input to this tool should be a mathematical - expression, a couple examples are `200*7` or `5000/2*10` + """This tool is useful for performing various mathematical + calculations such as addition, subtraction, multiplication, + division, etc. Input to the tool should be a mathematical + expression. Examples include 200*7 or 5000/2*10. """ - return eval(operation) + try: + return eval(operation) + except SyntaxError: + return "Error: Invalid syntax in mathematical expression" diff --git a/trip_planner/main.py b/trip_planner/main.py index 2bdde48f9..96fc828a5 100644 --- a/trip_planner/main.py +++ b/trip_planner/main.py @@ -1,11 +1,18 @@ -from crewai import Crew +import os + +from crewai import Crew, Process from textwrap import dedent from trip_agents import TripAgents from trip_tasks import TripTasks +from langchain_openai.chat_models import ChatOpenAI +from langchain_community.chat_models import chatOllama + from dotenv import load_dotenv load_dotenv() +api_key = os.getenv("OPENAI_API_KEY") #pulled from .env file + class TripCrew: def __init__(self, origin, cities, date_range, interests): @@ -13,6 +20,9 @@ def __init__(self, origin, cities, date_range, interests): self.origin = origin self.interests = interests self.date_range = date_range + self.openai = ChatOpenAI(api_key = api_key, temperature = 0.3) + #change model name to one of the available ollama model. (Performance will vary based on the model) + self.mistral = ChatOllama(model = "crewai-mistral") def run(self): agents = TripAgents() @@ -22,33 +32,39 @@ def run(self): local_expert_agent = agents.local_expert() travel_concierge_agent = agents.travel_concierge() - identify_task = tasks.identify_task( - city_selector_agent, - self.origin, - self.cities, - self.interests, - self.date_range - ) - gather_task = tasks.gather_task( - local_expert_agent, - self.origin, - self.interests, - self.date_range - ) - plan_task = tasks.plan_task( - travel_concierge_agent, - self.origin, - self.interests, - self.date_range - ) - - crew = Crew( - agents=[ - city_selector_agent, local_expert_agent, travel_concierge_agent - ], - tasks=[identify_task, gather_task, plan_task], - verbose=True - ) + identify_task = tasks.identify_task( + agent=city_selector_agent, + origin=self.origin, + cities=self.cities, + interests=self.interests, + range=self.date_range + ) + + gather_task = tasks.gather_task( + agent=local_expert_agent, + origin=self.origin, + interests=self.interests, + range=self.date_range, + context=[identify_task] # can take in a list of context + + ) + + plan_task = tasks.plan_task( + agent=travel_concierge_agent, + origin=self.origin, + interests=self.interests, + range=self.date_range, + context=[gather_task] + ) + + crew = Crew( + agents=[city_selector_agent, local_expert_agent, travel_concierge_agent], + tasks=[identify_task, gather_task, plan_task], + process= Process.sequential, #try out the previous Hierarchical process + manager_llm=self.openai + #manager_llm = self.mistral + ) + result = crew.kickoff() return result diff --git a/trip_planner/tools/browser_tools.py b/trip_planner/tools/browser_tools.py index 36a10a9f2..2803b6b47 100644 --- a/trip_planner/tools/browser_tools.py +++ b/trip_planner/tools/browser_tools.py @@ -1,11 +1,16 @@ -import json import os - +import json import requests + from crewai import Agent, Task from langchain.tools import tool from unstructured.partition.html import partition_html +from dotenv import load_dotenv +load_dotenv() + +api_key = os.getenv("OPENAI_API_KEY") #pulled from .env file + class BrowserTools(): @@ -24,14 +29,17 @@ def scrape_and_summarize_website(website): agent = Agent( role='Principal Researcher', goal= - 'Do amazing researches and summaries based on the content you are working with', + 'Perform thorough research and generate insightful summaries based on the content at hand.', backstory= "You're a Principal Researcher at a big company and you need to do a research about a given topic.", - allow_delegation=False) + allow_delegation=False, + llm = ChatOpenAI(api_key = api_key, temperature = 0)) task = Task( agent=agent, - description= - f'Analyze and summarize the content bellow, make sure to include the most relevant information in the summary, return only the summary nothing else.\n\nCONTENT\n----------\n{chunk}' + expected_output="Detailed summary of the content information", + description= f'Analyze and summarize the content below, making sure to include the most relevant + information in the summary. Return only the summary, nothing else.\n\nCONTENT\n---- + ------\n{chunk}' ) summary = task.execute() summaries.append(summary) diff --git a/trip_planner/tools/calculator_tools.py b/trip_planner/tools/calculator_tools.py index 51f00666c..b70f6035c 100644 --- a/trip_planner/tools/calculator_tools.py +++ b/trip_planner/tools/calculator_tools.py @@ -4,10 +4,10 @@ class CalculatorTools(): @tool("Make a calculation") def calculate(operation): - """Useful to perform any mathematical calculations, - like sum, minus, multiplication, division, etc. - The input to this tool should be a mathematical - expression, a couple examples are `200*7` or `5000/2*10` + """This tool is useful for performing various mathematical + calculations such as addition, subtraction, multiplication, + division, etc. Input to the tool should be a mathematical + expression. Examples include 200*7 or 5000/2*10. """ try: return eval(operation) diff --git a/trip_planner/trip_agents.py b/trip_planner/trip_agents.py index 577cd7be8..8b9c9d319 100644 --- a/trip_planner/trip_agents.py +++ b/trip_planner/trip_agents.py @@ -1,47 +1,67 @@ +import os + from crewai import Agent -from langchain.llms import OpenAI +from langchain_openai.chat_models import ChatOpenAI +from langchain_community.chat_models import ChatOllama from tools.browser_tools import BrowserTools from tools.calculator_tools import CalculatorTools from tools.search_tools import SearchTools +from dotenv import load_dotenv +load_dotenv() + +api_key = os.getenv("OPENAI_API_KEY") + class TripAgents(): - def city_selection_agent(self): - return Agent( - role='City Selection Expert', - goal='Select the best city based on weather, season, and prices', - backstory= - 'An expert in analyzing travel data to pick ideal destinations', - tools=[ - SearchTools.search_internet, - BrowserTools.scrape_and_summarize_website, - ], - verbose=True) - - def local_expert(self): - return Agent( - role='Local Expert at this city', - goal='Provide the BEST insights about the selected city', - backstory="""A knowledgeable local guide with extensive information - about the city, it's attractions and customs""", - tools=[ - SearchTools.search_internet, - BrowserTools.scrape_and_summarize_website, - ], - verbose=True) - - def travel_concierge(self): - return Agent( - role='Amazing Travel Concierge', - goal="""Create the most amazing travel itineraries with budget and - packing suggestions for the city""", - backstory="""Specialist in travel planning and logistics with - decades of experience""", - tools=[ - SearchTools.search_internet, - BrowserTools.scrape_and_summarize_website, - CalculatorTools.calculate, - ], - verbose=True) + def __init__(self): + self.mistral = ChatOllama(model = "crewai-mistral") #check model file + self.llama2 = ChatOllama(model = "crewai-llama2") + self.gemma = ChatOllama(model = "crewai-gemma") + self.openai = ChatOpenAI(api_key = api_key, temperature=0) + + def city_selection_agent(self): + return Agent( + role='City Selection Expert', + goal='Select the best city based on weather, season, and prices', + backstory= + 'An expert in analyzing travel data to pick ideal destinations', + tools=[ + SearchTools.search_internet, + BrowserTools.scrape_and_summarize_website, + ], + verbose=True, + allow_delegation=False, + max_iter= 15, + llm = self.openai, + #llm = self.mistral) + + def local_expert(self): + return Agent( + role='Local Expert at this city', + goal='Provide the BEST insights about the selected city', + backstory="""A knowledgeable local guide with extensive information + about the city, it's attractions and customs""", + tools=[ + SearchTools.search_internet, + BrowserTools.scrape_and_summarize_website, + ], + verbose=True, + llm = self.openai) + + def travel_concierge(self): + return Agent( + role='Amazing Travel Concierge', + goal="""Create the most amazing travel itineraries with budget and + packing suggestions for the city""", + backstory="""Specialist in travel planning and logistics with + decades of experience""", + tools=[ + SearchTools.search_internet, + BrowserTools.scrape_and_summarize_website, + CalculatorTools.calculate, + ], + verbose=True, + llm = self.openai) diff --git a/trip_planner/trip_tasks.py b/trip_planner/trip_tasks.py index b71931164..22be969e5 100644 --- a/trip_planner/trip_tasks.py +++ b/trip_planner/trip_tasks.py @@ -7,40 +7,66 @@ class TripTasks(): def identify_task(self, agent, origin, cities, interests, range): return Task(description=dedent(f""" - Analyze and select the best city for the trip based - on specific criteria such as weather patterns, seasonal - events, and travel costs. This task involves comparing - multiple cities, considering factors like current weather - conditions, upcoming cultural or seasonal events, and - overall travel expenses. - - Your final answer must be a detailed - report on the chosen city, and everything you found out - about it, including the actual flight costs, weather - forecast and attractions. - {self.__tip_section()} + Analyze and select the best city for the trip based + on specific criteria such as weather patterns, seasonal + events, and travel costs. This task involves comparing + multiple cities, considering factors like current weather + conditions, upcoming cultural or seasonal events, and + overall travel expenses. - Traveling from: {origin} - City Options: {cities} - Trip Date: {range} - Traveler Interests: {interests} - """), - agent=agent) + Your final answer must be a detailed + report on the chosen city, and everything you found out + about it, including the actual flight costs, weather + forecast and attractions. + {self.__tip_section()} + + Traveling from: {origin} + City Options: {cities} + Trip Date: {range} + Traveler Interests: {interests} + """ +), + expected_output =f""" + After careful analysis and consideration of your preferences and requirements, + I have selected Paris as the best city for your upcoming trip. Here are the details: + + Flight Costs: + - Round-trip ticket from {origin} to Paris: $500 + - Estimated accommodation cost: $100 per night + + Weather Forecast: + - Average temperature during your trip: 18°C (64°F) + - Mostly sunny with occasional clouds + + Attractions: + 1. Eiffel Tower: A must-visit iconic landmark offering breathtaking views of the city. + 2. Louvre Museum: Home to thousands of works of art, including the Mona Lisa. + 3. Notre-Dame Cathedral: A masterpiece of French Gothic architecture. + + Cultural Events: + - Paris Fashion Week: Scheduled during your trip dates, offering a glimpse into the latest trends in fashion. + + Feel free to make any necessary changes to this structure. + """, + agent = agent, + async_execution = False - def gather_task(self, agent, origin, interests, range): + ) + + def gather_task(self, agent, origin, interests, range, context): return Task(description=dedent(f""" - As a local expert on this city you must compile an + As a local expert on this city, you must compile an in-depth guide for someone traveling there and wanting to have THE BEST trip ever! - Gather information about key attractions, local customs, + Gather information about key attractions, local customs, special events, and daily activity recommendations. Find the best spots to go to, the kind of place only a local would know. This guide should provide a thorough overview of what the city has to offer, including hidden gems, cultural hotspots, must-visit landmarks, weather forecasts, and - high level costs. - + high-level costs. + The final answer must be a comprehensive city guide, rich in cultural insights and practical tips, tailored to enhance the travel experience. @@ -49,35 +75,117 @@ def gather_task(self, agent, origin, interests, range): Trip Date: {range} Traveling from: {origin} Traveler Interests: {interests} - """), - agent=agent) + """ + ), + expected_output=f""" + Key Attractions: + - Eiffel Tower: Iconic landmark offering stunning views of the city. + - Louvre Museum: Home to famous works of art like the Mona Lisa. + - Notre-Dame Cathedral: Magnificent example of French Gothic architecture. + + Local Customs: + - Embrace the French greeting of kissing on the cheeks. + - Respect dining etiquette, such as keeping your hands on the table. + + Special Events: + - Bastille Day Parade: Experience French national pride on July 14th. + - Paris Fashion Week: Witness the latest trends in fashion. + + Daily Activity Recommendations: + - Morning: Enjoy a croissant and coffee at a local café. + - Afternoon: Explore the charming streets of Montmartre. + - Evening: Indulge in a gourmet dinner overlooking the Seine River. + + Best Spots: + - Le Marais: Discover trendy boutiques and cozy cafés. + - Canal Saint-Martin: Relax by the water with a picnic. + + Hidden Gems: + - Shakespeare and Company Bookstore: Literary haven near Notre-Dame. + + Weather Forecast: + - Average temperature during your trip: 20°C (68°F) + - Mostly sunny with occasional showers. + + High-Level Costs: + - Accommodation: $150 per night (average) + - Dining: $30-$50 per meal (average) - def plan_task(self, agent, origin, interests, range): + Feel free to make any necessary changes to this structure. + """, + agent=agent, + context = context, + async_execution=False) + + def plan_task(self, agent, origin, interests, range, context): return Task(description=dedent(f""" - Expand this guide into a a full 7-day travel - itinerary with detailed per-day plans, including - weather forecasts, places to eat, packing suggestions, - and a budget breakdown. - - You MUST suggest actual places to visit, actual hotels - to stay and actual restaurants to go to. - - This itinerary should cover all aspects of the trip, - from arrival to departure, integrating the city guide - information with practical travel logistics. - - Your final answer MUST be a complete expanded travel plan, - formatted as markdown, encompassing a daily schedule, - anticipated weather conditions, recommended clothing and - items to pack, and a detailed budget, ensuring THE BEST - TRIP EVER, Be specific and give it a reason why you picked - # up each place, what make them special! {self.__tip_section()} + Expand this guide into a full 7-day travel itinerary with detailed + per-day plans including weather forecasts, places to eat, packing suggestions + and a budget breakdown. - Trip Date: {range} - Traveling from: {origin} - Traveler Interests: {interests} - """), - agent=agent) + You MUST suggest actual places to visit, actual hotels to stay + and actual restaurants to go to. + + This itinerary should cover all aspects of the trip, + from arrival to departure, integrating the city guide information with + practical travel logistics. + + Your final answer MUST be a complete expanded travel plan, formatted as + markdown, encompassing a daily schedule, anticipated weather conditions, recommended clothings + items to pack, and a detailed budget ensuring THE BEST TRIP EVER. Be specific + and give reasons why you picked a specific place, what makes the place special. + + {self.__tip_selection()} + + Trip Date: {range} + Traveling from: {origin} + Traveler Interests: {interests} + """ + ), + expected_output=f""" + + **Day 1: Arrival and Exploration** + - Morning: Arrival at Charles de Gaulle Airport and transfer to Hotel Le Meurice. + - Afternoon: Visit the iconic Eiffel Tower for panoramic views of Paris. + - Evening: Enjoy a traditional French dinner at Le Relais de l'Entrecôte. + + **Weather Forecast:** + - Average temperature: 22°C (72°F) + - Sunny with clear skies + + **Packing Suggestions:** + - Lightweight clothing, comfortable shoes + - Camera for capturing breathtaking views + + **Budget Breakdown:** + - Hotel: $250 per night + - Dinner: $50 per person + + **Day 2: Cultural Immersion** + - Morning: Breakfast at Café de Flore, a historic café frequented by artists and writers. + - Afternoon: Explore the Louvre Museum, home to the famous Mona Lisa. + - Evening: Attend a performance at the Palais Garnier, the renowned opera house. + + **Weather Forecast:** + - Average temperature: 20°C (68°F) + - Partly cloudy with a chance of light rain + + **Packing Suggestions:** + - Umbrella, comfortable walking shoes + - Dressier attire for the opera + + **Budget Breakdown:** + - Breakfast: $20 per person + - Museum entrance fee: $20 per person + - Opera ticket: $100 per person + + **Total Cost Compilation per person + - #### + + Feel free to make any necessary changes to this structure. + """, +context = context, +agent=agent) def __tip_section(self): return "If you do your BEST WORK, I'll tip you $100!"