mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-11 00:58:30 +00:00
template working
This commit is contained in:
@@ -34,9 +34,7 @@ def create_flow(name):
|
|||||||
tools_template_files = ["tools/__init__.py", "tools/custom_tool.py"]
|
tools_template_files = ["tools/__init__.py", "tools/custom_tool.py"]
|
||||||
|
|
||||||
crew_folders = [
|
crew_folders = [
|
||||||
"research_crew",
|
"poem_crew",
|
||||||
"write_linkedin_crew",
|
|
||||||
"write_x_crew",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def process_file(src_file, dst_file):
|
def process_file(src_file, dst_file):
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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
|
||||||
31
src/crewai/cli/templates/flow/crews/poem_crew/poem_crew.py
Normal file
31
src/crewai/cli/templates/flow/crews/poem_crew/poem_crew.py
Normal file
@@ -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,
|
||||||
|
)
|
||||||
@@ -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.
|
|
||||||
@@ -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
|
|
||||||
@@ -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,
|
|
||||||
)
|
|
||||||
@@ -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,
|
|
||||||
)
|
|
||||||
@@ -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.
|
|
||||||
@@ -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
|
|
||||||
@@ -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,
|
|
||||||
)
|
|
||||||
@@ -1,39 +1,55 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from random import randint
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from crewai.flow.flow import Flow, listen, start
|
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):
|
class PoemFlow(Flow[PoemState]):
|
||||||
counter: int = 0
|
initial_state = PoemState
|
||||||
message: str = ""
|
|
||||||
|
|
||||||
class ExampleFlow(Flow[ExampleState]):
|
|
||||||
initial_state = ExampleState
|
|
||||||
|
|
||||||
@start()
|
@start()
|
||||||
def start_method(self):
|
def generate_sentence_count(self):
|
||||||
print("Starting the structured flow")
|
print("Generating sentence count")
|
||||||
self.state.message = "Hello from structured flow"
|
# Generate a number between 1 and 5
|
||||||
|
self.state.sentence_count = randint(1, 5)
|
||||||
|
|
||||||
@listen(start_method)
|
@listen(generate_sentence_count)
|
||||||
def second_method(self, result):
|
def generate_poem(self):
|
||||||
print(f"Second method, received: {result}")
|
print("Generating poem")
|
||||||
print(f"State before increment: {self.state}")
|
print(f"State before poem: {self.state}")
|
||||||
self.state.counter += 1
|
poem_crew = PoemCrew().crew()
|
||||||
self.state.message += " - updated"
|
result = poem_crew.kickoff(inputs={"sentence_count": self.state.sentence_count})
|
||||||
print(f"State after second_method: {self.state}")
|
|
||||||
return "Second result"
|
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.
|
Run the flow.
|
||||||
"""
|
"""
|
||||||
example_flow = ExampleFlow()
|
poem_flow = PoemFlow()
|
||||||
await example_flow.run()
|
await poem_flow.kickoff()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
asyncio.run(run())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
asyncio.run(run())
|
main()
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ asyncio = "*"
|
|||||||
|
|
||||||
[tool.poetry.scripts]
|
[tool.poetry.scripts]
|
||||||
{{folder_name}} = "{{folder_name}}.main:main"
|
{{folder_name}} = "{{folder_name}}.main:main"
|
||||||
|
run_crew = "{{folder_name}}.main:main"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ class FlowMeta(type):
|
|||||||
setattr(cls, "_start_methods", start_methods)
|
setattr(cls, "_start_methods", start_methods)
|
||||||
setattr(cls, "_listeners", listeners)
|
setattr(cls, "_listeners", listeners)
|
||||||
|
|
||||||
# Inject the state type hint
|
|
||||||
if "initial_state" in dct:
|
if "initial_state" in dct:
|
||||||
initial_state = dct["initial_state"]
|
initial_state = dct["initial_state"]
|
||||||
if isinstance(initial_state, type) and issubclass(initial_state, BaseModel):
|
if isinstance(initial_state, type) and issubclass(initial_state, BaseModel):
|
||||||
@@ -89,7 +88,7 @@ class Flow(Generic[T], metaclass=FlowMeta):
|
|||||||
def state(self) -> T:
|
def state(self) -> T:
|
||||||
return self._state
|
return self._state
|
||||||
|
|
||||||
async def run(self):
|
async def kickoff(self):
|
||||||
if not self._start_methods:
|
if not self._start_methods:
|
||||||
raise ValueError("No start method defined")
|
raise ValueError("No start method defined")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user