From 41a0a109145a19a057a805b035c6ea16f9c5c90e Mon Sep 17 00:00:00 2001 From: Brandon Hancock Date: Thu, 1 Aug 2024 16:55:38 -0400 Subject: [PATCH] WIP. --- .../cli/templates/pipeline/config/agents.yaml | 17 +++- .../cli/templates/pipeline/config/tasks.yaml | 26 +++++- .../templates/pipeline/crews/research_crew.py | 58 +++++++++++++ .../crews/{crew.py => write_linkedin_crew.py} | 6 +- .../templates/pipeline/crews/write_x_crew.py | 37 ++++++++ src/crewai/cli/templates/pipeline/main.py | 19 ++-- src/crewai/cli/templates/pipeline/pipeline.py | 87 ++++++++++++++++--- .../cli/templates/pipeline/pyproject.toml | 11 ++- 8 files changed, 232 insertions(+), 29 deletions(-) create mode 100644 src/crewai/cli/templates/pipeline/crews/research_crew.py rename src/crewai/cli/templates/pipeline/crews/{crew.py => write_linkedin_crew.py} (82%) create mode 100644 src/crewai/cli/templates/pipeline/crews/write_x_crew.py diff --git a/src/crewai/cli/templates/pipeline/config/agents.yaml b/src/crewai/cli/templates/pipeline/config/agents.yaml index 72ed6939e..f5ef4d818 100644 --- a/src/crewai/cli/templates/pipeline/config/agents.yaml +++ b/src/crewai/cli/templates/pipeline/config/agents.yaml @@ -16,4 +16,19 @@ reporting_analyst: 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. \ No newline at end of file + it easy for others to understand and act on the information you provide. + +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/pipeline/config/tasks.yaml b/src/crewai/cli/templates/pipeline/config/tasks.yaml index f30820855..c81d41db5 100644 --- a/src/crewai/cli/templates/pipeline/config/tasks.yaml +++ b/src/crewai/cli/templates/pipeline/config/tasks.yaml @@ -12,6 +12,28 @@ reporting_task: 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 the mains topics, each with a full section of information. - Formatted as markdown without '```' + A fully fledge reports with a title, mains topics, each with a full section of information. agent: reporting_analyst + +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: + {research} + + 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/pipeline/crews/research_crew.py b/src/crewai/cli/templates/pipeline/crews/research_crew.py new file mode 100644 index 000000000..07ade70ab --- /dev/null +++ b/src/crewai/cli/templates/pipeline/crews/research_crew.py @@ -0,0 +1,58 @@ +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 {{folder_name}}.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=2, + ) \ No newline at end of file diff --git a/src/crewai/cli/templates/pipeline/crews/crew.py b/src/crewai/cli/templates/pipeline/crews/write_linkedin_crew.py similarity index 82% rename from src/crewai/cli/templates/pipeline/crews/crew.py rename to src/crewai/cli/templates/pipeline/crews/write_linkedin_crew.py index 75b1b6c32..edeb1bf89 100644 --- a/src/crewai/cli/templates/pipeline/crews/crew.py +++ b/src/crewai/cli/templates/pipeline/crews/write_linkedin_crew.py @@ -8,8 +8,8 @@ from crewai.project import CrewBase, agent, crew, task # from crewai_tools import SerperDevTool @CrewBase -class {{crew_name}}Crew(): - """{{crew_name}} crew""" +class WriteLinkedInCrew(): + """Research Crew""" agents_config = '../config/agents.yaml' tasks_config = '../config/tasks.yaml' @@ -17,7 +17,6 @@ class {{crew_name}}Crew(): def researcher(self) -> Agent: return Agent( config=self.agents_config['researcher'], - # tools=[MyCustomTool()], # Example of custom tool, loaded on the beginning of file verbose=True ) @@ -49,5 +48,4 @@ class {{crew_name}}Crew(): tasks=self.tasks, # Automatically created by the @task decorator process=Process.sequential, verbose=2, - # process=Process.hierarchical, # In case you wanna use that instead https://docs.crewai.com/how-to/Hierarchical/ ) \ No newline at end of file diff --git a/src/crewai/cli/templates/pipeline/crews/write_x_crew.py b/src/crewai/cli/templates/pipeline/crews/write_x_crew.py new file mode 100644 index 000000000..bb8af2279 --- /dev/null +++ b/src/crewai/cli/templates/pipeline/crews/write_x_crew.py @@ -0,0 +1,37 @@ +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 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=2, + ) \ No newline at end of file diff --git a/src/crewai/cli/templates/pipeline/main.py b/src/crewai/cli/templates/pipeline/main.py index 82496156d..46649c592 100644 --- a/src/crewai/cli/templates/pipeline/main.py +++ b/src/crewai/cli/templates/pipeline/main.py @@ -1,17 +1,26 @@ #!/usr/bin/env python import asyncio -from {{folder_name}}.src.{{folder_name}}.pipeline import {{pipeline_name}}Pipeline - +from pipeline import {{pipeline_name}}Pipeline async def run(): """ Run the pipeline. """ inputs = [ - {"topic": "AI LLMs"}, + {"topic": "AI wearables"}, ] - await {{pipeline_name}}Pipeline().pipeline().kickoff(inputs=inputs) + pipeline = {{pipeline_name}}Pipeline().pipeline() + results = await pipeline.kickoff(inputs) + + # Process and print results + for result in results: + print(f"Raw output: {result.raw}") + if result.json_dict: + print(f"JSON output: {result.json_dict}") + print("\n") +def main(): + asyncio.run(run()) if __name__ == "__main__": - asyncio.run(run()) \ No newline at end of file + main() \ No newline at end of file diff --git a/src/crewai/cli/templates/pipeline/pipeline.py b/src/crewai/cli/templates/pipeline/pipeline.py index 178059552..69f6984dd 100644 --- a/src/crewai/cli/templates/pipeline/pipeline.py +++ b/src/crewai/cli/templates/pipeline/pipeline.py @@ -1,26 +1,91 @@ +""" +This pipeline file includes two different examples to demonstrate the flexibility of crewAI pipelines. + +Example 1: Two-Stage Pipeline +----------------------------- +This pipeline consists of two crews: +1. ResearchCrew: Performs research on a given topic. +2. WriteXCrew: Generates an X (Twitter) post based on the research findings. + +Key features: +- The ResearchCrew's final task uses output_json to store all research findings in a JSON object. +- This JSON object is then passed to the WriteXCrew, where tasks can access the research findings. + +Example 2: Three-Stage Pipeline with Parallel Execution +------------------------------------------------------- +This pipeline consists of three crews: +1. ResearchCrew: Performs research on a given topic. +2. WriteXCrew and WriteLinkedInCrew: Run in parallel, using the research findings to generate posts for X and LinkedIn, respectively. + +Key features: +- Demonstrates the ability to run multiple crews in parallel. +- Shows how to structure a pipeline with both sequential and parallel stages. + +Usage: +- To switch between examples, comment/uncomment the respective code blocks below. +- Ensure that you have implemented all necessary crew classes (ResearchCrew, WriteXCrew, WriteLinkedInCrew) before running. +""" + +# Common imports for both examples from crewai import Pipeline -from crewai.project import PipelineBase -from crews.crew import * +from crewai.project.pipeline_base import PipelineBase + + +from crewai.project.annotations import pipeline + +# Uncomment the crews you need for your chosen example +from .crews.research_crew import ResearchCrew +from .crews.write_x_crew import WriteXCrew +# from .crews.write_linkedin_crew import WriteLinkedInCrew # Uncomment for Example 2 + +# EXAMPLE 1: Two-Stage Pipeline +# ----------------------------- +# Uncomment the following code block to use Example 1 @PipelineBase -class {{pipeline_name}}Pipeline: +class ContentPipeline: def __init__(self): # Initialize crews - {% for crew_name in crew_names %} - self.{{crew_name.lower()}}_crew = {{crew_name}}Crew().crew() - {% endfor %} - + self.research_crew = ResearchCrew().crew() + self.write_x_crew = WriteXCrew().crew() + @pipeline def create_pipeline(self): return Pipeline( stages=[ - {% for crew_name in crew_names %} - self.{{crew_name.lower()}}_crew, - {% endfor %} + self.research_crew, + self.write_x_crew ] ) async def run(self, inputs): pipeline = self.create_pipeline() results = await pipeline.kickoff(inputs) - return results \ No newline at end of file + return results + + +# EXAMPLE 2: Three-Stage Pipeline with Parallel Execution +# ------------------------------------------------------- +# Uncomment the following code block to use Example 2 + +# @PipelineBase +# class ContentPipeline: +# def __init__(self): +# # Initialize crews +# self.research_crew = ResearchCrew().crew() +# self.write_x_crew = WriteXCrew().crew() +# self.write_linkedin_crew = WriteLinkedInCrew().crew() + +# @pipeline +# def create_pipeline(self): +# return Pipeline( +# stages=[ +# self.research_crew, +# [self.write_x_crew, self.write_linkedin_crew] # Parallel execution +# ] +# ) + +# async def run(self, inputs): +# pipeline = self.create_pipeline() +# results = await pipeline.kickoff(inputs) +# return results \ No newline at end of file diff --git a/src/crewai/cli/templates/pipeline/pyproject.toml b/src/crewai/cli/templates/pipeline/pyproject.toml index 048782d1c..bf0413ebd 100644 --- a/src/crewai/cli/templates/pipeline/pyproject.toml +++ b/src/crewai/cli/templates/pipeline/pyproject.toml @@ -6,14 +6,13 @@ authors = ["Your Name "] [tool.poetry.dependencies] python = ">=3.10,<=3.13" -crewai = { extras = ["tools"], version = "^0.46.0" } +#crewai = { extras = ["tools"], version = "^0.41.1" } +crewai = { extras = ["tools"], path = "/Users/brandonhancock/Code/crewai/crewAI" } +asyncio = "*" [tool.poetry.scripts] -{{folder_name}} = "{{folder_name}}.main:run" -train = "{{folder_name}}.main:train" -replay = "{{folder_name}}.main:replay" -test = "{{folder_name}}.main:test" +{{folder_name}} = "{{folder_name}}.src.{{folder_name}}.main:main" [build-system] requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" +build-backend = "poetry.core.masonry.api" \ No newline at end of file