From 72f0b600b8fb5dfa0db27e08f7751680e080cb48 Mon Sep 17 00:00:00 2001 From: Brandon Hancock Date: Thu, 12 Sep 2024 11:33:46 -0400 Subject: [PATCH] template working --- src/crewai/cli/create_flow.py | 4 +- .../flow/crews/poem_crew/config/agents.yaml | 11 ++++ .../flow/crews/poem_crew/config/tasks.yaml | 7 +++ .../flow/crews/poem_crew/poem_crew.py | 31 ++++++++++ .../crews/research_crew/config/agents.yaml | 19 ------ .../crews/research_crew/config/tasks.yaml | 16 ----- .../flow/crews/research_crew/research_crew.py | 58 ------------------ .../write_linkedin_crew/config/agents.yaml | 0 .../write_linkedin_crew/config/tasks.yaml | 0 .../write_linkedin_crew.py | 51 ---------------- .../crews/write_x_crew/config/agents.yaml | 14 ----- .../flow/crews/write_x_crew/config/tasks.yaml | 22 ------- .../flow/crews/write_x_crew/write_x_crew.py | 36 ----------- src/crewai/cli/templates/flow/main.py | 60 ++++++++++++------- src/crewai/cli/templates/flow/pyproject.toml | 3 +- src/crewai/flow/flow.py | 3 +- 16 files changed, 91 insertions(+), 244 deletions(-) create mode 100644 src/crewai/cli/templates/flow/crews/poem_crew/config/agents.yaml create mode 100644 src/crewai/cli/templates/flow/crews/poem_crew/config/tasks.yaml create mode 100644 src/crewai/cli/templates/flow/crews/poem_crew/poem_crew.py delete mode 100644 src/crewai/cli/templates/flow/crews/research_crew/config/agents.yaml delete mode 100644 src/crewai/cli/templates/flow/crews/research_crew/config/tasks.yaml delete mode 100644 src/crewai/cli/templates/flow/crews/research_crew/research_crew.py delete mode 100644 src/crewai/cli/templates/flow/crews/write_linkedin_crew/config/agents.yaml delete mode 100644 src/crewai/cli/templates/flow/crews/write_linkedin_crew/config/tasks.yaml delete mode 100644 src/crewai/cli/templates/flow/crews/write_linkedin_crew/write_linkedin_crew.py delete mode 100644 src/crewai/cli/templates/flow/crews/write_x_crew/config/agents.yaml delete mode 100644 src/crewai/cli/templates/flow/crews/write_x_crew/config/tasks.yaml delete mode 100644 src/crewai/cli/templates/flow/crews/write_x_crew/write_x_crew.py diff --git a/src/crewai/cli/create_flow.py b/src/crewai/cli/create_flow.py index df0a4a6d7..6db5bd6a9 100644 --- a/src/crewai/cli/create_flow.py +++ b/src/crewai/cli/create_flow.py @@ -34,9 +34,7 @@ def create_flow(name): tools_template_files = ["tools/__init__.py", "tools/custom_tool.py"] crew_folders = [ - "research_crew", - "write_linkedin_crew", - "write_x_crew", + "poem_crew", ] def process_file(src_file, dst_file): diff --git a/src/crewai/cli/templates/flow/crews/poem_crew/config/agents.yaml b/src/crewai/cli/templates/flow/crews/poem_crew/config/agents.yaml new file mode 100644 index 000000000..4b461d50d --- /dev/null +++ b/src/crewai/cli/templates/flow/crews/poem_crew/config/agents.yaml @@ -0,0 +1,11 @@ +poem_writer: + role: > + CrewAI Poem Writer + goal: > + Generate a funny, light heartedpoem about how CrewAI + is awesome with a sentence count of {sentence_count} + backstory: > + You're a creative poet with a talent for capturing the essence of any topic + in a beautiful and engaging way. Known for your ability to craft poems that + resonate with readers, you bring a unique perspective and artistic flair to + every piece you write. diff --git a/src/crewai/cli/templates/flow/crews/poem_crew/config/tasks.yaml b/src/crewai/cli/templates/flow/crews/poem_crew/config/tasks.yaml new file mode 100644 index 000000000..2d8334fbb --- /dev/null +++ b/src/crewai/cli/templates/flow/crews/poem_crew/config/tasks.yaml @@ -0,0 +1,7 @@ +write_poem: + description: > + Write a poem about how CrewAI is awesome. + Ensure the poem is engaging and adheres to the specified sentence count of {sentence_count}. + expected_output: > + A beautifully crafted poem about CrewAI, with exactly {sentence_count} sentences. + agent: poem_writer diff --git a/src/crewai/cli/templates/flow/crews/poem_crew/poem_crew.py b/src/crewai/cli/templates/flow/crews/poem_crew/poem_crew.py new file mode 100644 index 000000000..cc3ce7150 --- /dev/null +++ b/src/crewai/cli/templates/flow/crews/poem_crew/poem_crew.py @@ -0,0 +1,31 @@ +from crewai import Agent, Crew, Process, Task +from crewai.project import CrewBase, agent, crew, task + +@CrewBase +class PoemCrew(): + """Poem Crew""" + + agents_config = 'config/agents.yaml' + tasks_config = 'config/tasks.yaml' + + @agent + def poem_writer(self) -> Agent: + return Agent( + config=self.agents_config['poem_writer'], + ) + + @task + def write_poem(self) -> Task: + return Task( + config=self.tasks_config['write_poem'], + ) + + @crew + def crew(self) -> Crew: + """Creates the Research Crew""" + return Crew( + agents=self.agents, # Automatically created by the @agent decorator + tasks=self.tasks, # Automatically created by the @task decorator + process=Process.sequential, + verbose=True, + ) diff --git a/src/crewai/cli/templates/flow/crews/research_crew/config/agents.yaml b/src/crewai/cli/templates/flow/crews/research_crew/config/agents.yaml deleted file mode 100644 index f8cf1f5c1..000000000 --- a/src/crewai/cli/templates/flow/crews/research_crew/config/agents.yaml +++ /dev/null @@ -1,19 +0,0 @@ -researcher: - role: > - {topic} Senior Data Researcher - goal: > - Uncover cutting-edge developments in {topic} - backstory: > - You're a seasoned researcher with a knack for uncovering the latest - developments in {topic}. Known for your ability to find the most relevant - information and present it in a clear and concise manner. - -reporting_analyst: - role: > - {topic} Reporting Analyst - goal: > - Create detailed reports based on {topic} data analysis and research findings - backstory: > - You're a meticulous analyst with a keen eye for detail. You're known for - your ability to turn complex data into clear and concise reports, making - it easy for others to understand and act on the information you provide. diff --git a/src/crewai/cli/templates/flow/crews/research_crew/config/tasks.yaml b/src/crewai/cli/templates/flow/crews/research_crew/config/tasks.yaml deleted file mode 100644 index e78091842..000000000 --- a/src/crewai/cli/templates/flow/crews/research_crew/config/tasks.yaml +++ /dev/null @@ -1,16 +0,0 @@ -research_task: - description: > - Conduct a thorough research about {topic} - Make sure you find any interesting and relevant information given - the current year is 2024. - expected_output: > - A list with 10 bullet points of the most relevant information about {topic} - agent: researcher - -reporting_task: - description: > - Review the context you got and expand each topic into a full section for a report. - Make sure the report is detailed and contains any and all relevant information. - expected_output: > - A fully fledge reports with a title, mains topics, each with a full section of information. - agent: reporting_analyst diff --git a/src/crewai/cli/templates/flow/crews/research_crew/research_crew.py b/src/crewai/cli/templates/flow/crews/research_crew/research_crew.py deleted file mode 100644 index f26ad712a..000000000 --- a/src/crewai/cli/templates/flow/crews/research_crew/research_crew.py +++ /dev/null @@ -1,58 +0,0 @@ -from pydantic import BaseModel -from crewai import Agent, Crew, Process, Task -from crewai.project import CrewBase, agent, crew, task - -# Uncomment the following line to use an example of a custom tool -# from demo_pipeline.tools.custom_tool import MyCustomTool - -# Check our tools documentations for more information on how to use them -# from crewai_tools import SerperDevTool - - -class ResearchReport(BaseModel): - """Research Report""" - title: str - body: str - -@CrewBase -class ResearchCrew(): - """Research Crew""" - agents_config = 'config/agents.yaml' - tasks_config = 'config/tasks.yaml' - - @agent - def researcher(self) -> Agent: - return Agent( - config=self.agents_config['researcher'], - verbose=True - ) - - @agent - def reporting_analyst(self) -> Agent: - return Agent( - config=self.agents_config['reporting_analyst'], - verbose=True - ) - - @task - def research_task(self) -> Task: - return Task( - config=self.tasks_config['research_task'], - ) - - @task - def reporting_task(self) -> Task: - return Task( - config=self.tasks_config['reporting_task'], - output_pydantic=ResearchReport - ) - - @crew - def crew(self) -> Crew: - """Creates the Research Crew""" - return Crew( - agents=self.agents, # Automatically created by the @agent decorator - tasks=self.tasks, # Automatically created by the @task decorator - process=Process.sequential, - verbose=True, - ) \ No newline at end of file diff --git a/src/crewai/cli/templates/flow/crews/write_linkedin_crew/config/agents.yaml b/src/crewai/cli/templates/flow/crews/write_linkedin_crew/config/agents.yaml deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/crewai/cli/templates/flow/crews/write_linkedin_crew/config/tasks.yaml b/src/crewai/cli/templates/flow/crews/write_linkedin_crew/config/tasks.yaml deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/crewai/cli/templates/flow/crews/write_linkedin_crew/write_linkedin_crew.py b/src/crewai/cli/templates/flow/crews/write_linkedin_crew/write_linkedin_crew.py deleted file mode 100644 index 4a40c3fb4..000000000 --- a/src/crewai/cli/templates/flow/crews/write_linkedin_crew/write_linkedin_crew.py +++ /dev/null @@ -1,51 +0,0 @@ -from crewai import Agent, Crew, Process, Task -from crewai.project import CrewBase, agent, crew, task - -# Uncomment the following line to use an example of a custom tool -# from {{folder_name}}.tools.custom_tool import MyCustomTool - -# Check our tools documentations for more information on how to use them -# from crewai_tools import SerperDevTool - -@CrewBase -class WriteLinkedInCrew(): - """Research Crew""" - agents_config = 'config/agents.yaml' - tasks_config = 'config/tasks.yaml' - - @agent - def researcher(self) -> Agent: - return Agent( - config=self.agents_config['researcher'], - verbose=True - ) - - @agent - def reporting_analyst(self) -> Agent: - return Agent( - config=self.agents_config['reporting_analyst'], - verbose=True - ) - - @task - def research_task(self) -> Task: - return Task( - config=self.tasks_config['research_task'], - ) - - @task - def reporting_task(self) -> Task: - return Task( - config=self.tasks_config['reporting_task'], - output_file='report.md' - ) - - @crew - def crew(self) -> Crew: - """Creates the {{crew_name}} crew""" - return Crew( - agents=self.agents, # Automatically created by the @agent decorator - tasks=self.tasks, # Automatically created by the @task decorator - process=Process.sequential, - verbose=True, - ) \ No newline at end of file diff --git a/src/crewai/cli/templates/flow/crews/write_x_crew/config/agents.yaml b/src/crewai/cli/templates/flow/crews/write_x_crew/config/agents.yaml deleted file mode 100644 index 1401dcbe0..000000000 --- a/src/crewai/cli/templates/flow/crews/write_x_crew/config/agents.yaml +++ /dev/null @@ -1,14 +0,0 @@ -x_writer_agent: - role: > - Expert Social Media Content Creator specializing in short form written content - goal: > - Create viral-worthy, engaging short form posts that distill complex {topic} information - into compelling 280-character messages - backstory: > - You're a social media virtuoso with a particular talent for short form content. Your posts - consistently go viral due to your ability to craft hooks that stop users mid-scroll. - You've studied the techniques of social media masters like Justin Welsh, Dickie Bush, - Nicolas Cole, and Shaan Puri, incorporating their best practices into your own unique style. - Your superpower is taking intricate {topic} concepts and transforming them into - bite-sized, shareable content that resonates with a wide audience. You know exactly - how to structure a post for maximum impact and engagement. diff --git a/src/crewai/cli/templates/flow/crews/write_x_crew/config/tasks.yaml b/src/crewai/cli/templates/flow/crews/write_x_crew/config/tasks.yaml deleted file mode 100644 index 1ffbc207a..000000000 --- a/src/crewai/cli/templates/flow/crews/write_x_crew/config/tasks.yaml +++ /dev/null @@ -1,22 +0,0 @@ -write_x_task: - description: > - Using the research report provided, create an engaging short form post about {topic}. - Your post should have a great hook, summarize key points, and be structured for easy - consumption on a digital platform. The post must be under 280 characters. - Follow these guidelines: - 1. Start with an attention-grabbing hook - 2. Condense the main insights from the research - 3. Use clear, concise language - 4. Include a call-to-action or thought-provoking question if space allows - 5. Ensure the post flows well and is easy to read quickly - - Here is the title of the research report you will be using - - Title: {title} - Research: - {body} - - expected_output: > - A compelling X post under 280 characters that effectively summarizes the key findings - about {topic}, starts with a strong hook, and is optimized for engagement on the platform. - agent: x_writer_agent diff --git a/src/crewai/cli/templates/flow/crews/write_x_crew/write_x_crew.py b/src/crewai/cli/templates/flow/crews/write_x_crew/write_x_crew.py deleted file mode 100644 index 454aafdc0..000000000 --- a/src/crewai/cli/templates/flow/crews/write_x_crew/write_x_crew.py +++ /dev/null @@ -1,36 +0,0 @@ -from crewai import Agent, Crew, Process, Task -from crewai.project import CrewBase, agent, crew, task - -# Uncomment the following line to use an example of a custom tool -# from demo_pipeline.tools.custom_tool import MyCustomTool - -# Check our tools documentations for more information on how to use them -# from crewai_tools import SerperDevTool - - -@CrewBase -class WriteXCrew: - """Research Crew""" - - agents_config = "config/agents.yaml" - tasks_config = "config/tasks.yaml" - - @agent - def x_writer_agent(self) -> Agent: - return Agent(config=self.agents_config["x_writer_agent"], verbose=True) - - @task - def write_x_task(self) -> Task: - return Task( - config=self.tasks_config["write_x_task"], - ) - - @crew - def crew(self) -> Crew: - """Creates the Write X Crew""" - return Crew( - agents=self.agents, # Automatically created by the @agent decorator - tasks=self.tasks, # Automatically created by the @task decorator - process=Process.sequential, - verbose=True, - ) diff --git a/src/crewai/cli/templates/flow/main.py b/src/crewai/cli/templates/flow/main.py index 2afd8f132..b486b7a4d 100644 --- a/src/crewai/cli/templates/flow/main.py +++ b/src/crewai/cli/templates/flow/main.py @@ -1,39 +1,55 @@ #!/usr/bin/env python import asyncio +from random import randint from pydantic import BaseModel from crewai.flow.flow import Flow, listen, start +from .crews.poem_crew.poem_crew import PoemCrew -# TODO: THERE SHOULD BE 3 FLOWS IN HERE: SIMPLE, ASYNC, BRANCHING (with router) +class PoemState(BaseModel): + sentence_count: int = 1 + poem: str = "" -class ExampleState(BaseModel): - counter: int = 0 - message: str = "" - -class ExampleFlow(Flow[ExampleState]): - initial_state = ExampleState +class PoemFlow(Flow[PoemState]): + initial_state = PoemState @start() - def start_method(self): - print("Starting the structured flow") - self.state.message = "Hello from structured flow" + def generate_sentence_count(self): + print("Generating sentence count") + # Generate a number between 1 and 5 + self.state.sentence_count = randint(1, 5) - @listen(start_method) - def second_method(self, result): - print(f"Second method, received: {result}") - print(f"State before increment: {self.state}") - self.state.counter += 1 - self.state.message += " - updated" - print(f"State after second_method: {self.state}") - return "Second result" + @listen(generate_sentence_count) + def generate_poem(self): + print("Generating poem") + print(f"State before poem: {self.state}") + poem_crew = PoemCrew().crew() + result = poem_crew.kickoff(inputs={"sentence_count": self.state.sentence_count}) + + print("Poem generated", result.raw) + self.state.poem = result.raw + + print(f"State after generate_poem: {self.state}") -async def run(): + @listen(generate_poem) + def save_poem(self): + print("Saving poem") + print(f"State before save_poem: {self.state}") + with open("poem.txt", "w") as f: + f.write(self.state.poem) + print(f"State after save_poem: {self.state}") + +async def run(): """ Run the flow. """ - example_flow = ExampleFlow() - await example_flow.run() + poem_flow = PoemFlow() + await poem_flow.kickoff() + + +def main(): + asyncio.run(run()) if __name__ == "__main__": - asyncio.run(run()) + main() diff --git a/src/crewai/cli/templates/flow/pyproject.toml b/src/crewai/cli/templates/flow/pyproject.toml index 8f8b72e23..0e7083c71 100644 --- a/src/crewai/cli/templates/flow/pyproject.toml +++ b/src/crewai/cli/templates/flow/pyproject.toml @@ -11,7 +11,8 @@ asyncio = "*" [tool.poetry.scripts] {{folder_name}} = "{{folder_name}}.main:main" +run_crew = "{{folder_name}}.main:main" [build-system] requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" \ No newline at end of file +build-backend = "poetry.core.masonry.api" diff --git a/src/crewai/flow/flow.py b/src/crewai/flow/flow.py index 95a25f335..ba50b21eb 100644 --- a/src/crewai/flow/flow.py +++ b/src/crewai/flow/flow.py @@ -50,7 +50,6 @@ class FlowMeta(type): setattr(cls, "_start_methods", start_methods) setattr(cls, "_listeners", listeners) - # Inject the state type hint if "initial_state" in dct: initial_state = dct["initial_state"] if isinstance(initial_state, type) and issubclass(initial_state, BaseModel): @@ -89,7 +88,7 @@ class Flow(Generic[T], metaclass=FlowMeta): def state(self) -> T: return self._state - async def run(self): + async def kickoff(self): if not self._start_methods: raise ValueError("No start method defined")