mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-04-11 13:32:34 +00:00
updating poem to content use case (#5286)
* updating poem to content use case * addressing CVE-2026-35030
This commit is contained in:
@@ -46,7 +46,7 @@ def create_flow(name: str) -> None:
|
||||
tools_template_files = ["tools/__init__.py", "tools/custom_tool.py"]
|
||||
|
||||
crew_folders = [
|
||||
"poem_crew",
|
||||
"content_crew",
|
||||
]
|
||||
|
||||
def process_file(src_file: Path, dst_file: Path) -> None:
|
||||
|
||||
@@ -120,11 +120,11 @@ my_crew/
|
||||
my_flow/
|
||||
├── src/my_flow/
|
||||
│ ├── crews/ # Multiple crew definitions
|
||||
│ │ └── poem_crew/
|
||||
│ │ └── content_crew/
|
||||
│ │ ├── config/
|
||||
│ │ │ ├── agents.yaml
|
||||
│ │ │ └── tasks.yaml
|
||||
│ │ └── poem_crew.py
|
||||
│ │ └── content_crew.py
|
||||
│ ├── tools/ # Custom tools
|
||||
│ ├── main.py # Flow orchestration
|
||||
│ └── ...
|
||||
|
||||
@@ -38,7 +38,7 @@ crewai run
|
||||
|
||||
This command initializes the {{name}} Flow as defined in your configuration.
|
||||
|
||||
This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root folder.
|
||||
This example, unmodified, will run a content creation flow on AI Agents and save the output to `output/post.md`.
|
||||
|
||||
## Understanding Your Crew
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
planner:
|
||||
role: >
|
||||
Content Planner
|
||||
goal: >
|
||||
Plan a detailed and engaging blog post outline on {topic}
|
||||
backstory: >
|
||||
You're an experienced content strategist who excels at creating
|
||||
structured outlines for blog posts. You know how to organize ideas
|
||||
into a logical flow that keeps readers engaged from start to finish.
|
||||
|
||||
writer:
|
||||
role: >
|
||||
Content Writer
|
||||
goal: >
|
||||
Write a compelling and well-structured blog post on {topic}
|
||||
based on the provided outline
|
||||
backstory: >
|
||||
You're a skilled writer with a talent for turning outlines into
|
||||
engaging, informative blog posts. Your writing is clear, conversational,
|
||||
and backed by solid reasoning. You adapt your tone to the subject matter
|
||||
while keeping things accessible to a broad audience.
|
||||
|
||||
editor:
|
||||
role: >
|
||||
Content Editor
|
||||
goal: >
|
||||
Review and polish the blog post on {topic} to ensure it is
|
||||
publication-ready
|
||||
backstory: >
|
||||
You're a meticulous editor with years of experience refining written
|
||||
content. You have an eye for clarity, flow, grammar, and consistency.
|
||||
You improve prose without changing the author's voice and ensure every
|
||||
piece you touch is polished and professional.
|
||||
@@ -0,0 +1,50 @@
|
||||
planning_task:
|
||||
description: >
|
||||
Create a detailed outline for a blog post about {topic}.
|
||||
|
||||
The outline should include:
|
||||
- A compelling title
|
||||
- An introduction hook
|
||||
- 3-5 main sections with key points to cover in each
|
||||
- A conclusion with a call to action
|
||||
|
||||
Make the outline detailed enough that a writer can produce
|
||||
a full blog post from it without additional research.
|
||||
expected_output: >
|
||||
A structured blog post outline with a title, introduction notes,
|
||||
detailed section breakdowns, and conclusion notes.
|
||||
agent: planner
|
||||
|
||||
writing_task:
|
||||
description: >
|
||||
Using the outline provided, write a full blog post about {topic}.
|
||||
|
||||
Requirements:
|
||||
- Follow the outline structure closely
|
||||
- Write in a clear, engaging, and conversational tone
|
||||
- Each section should be 2-3 paragraphs
|
||||
- Include a strong introduction and conclusion
|
||||
- Target around 800-1200 words
|
||||
expected_output: >
|
||||
A complete blog post in markdown format, ready for editing.
|
||||
The post should follow the outline and be well-written with
|
||||
clear transitions between sections.
|
||||
agent: writer
|
||||
|
||||
editing_task:
|
||||
description: >
|
||||
Review and edit the blog post about {topic}.
|
||||
|
||||
Focus on:
|
||||
- Fixing any grammar or spelling errors
|
||||
- Improving sentence clarity and flow
|
||||
- Ensuring consistent tone throughout
|
||||
- Strengthening the introduction and conclusion
|
||||
- Removing any redundancy
|
||||
|
||||
Do not rewrite the post — refine and polish it.
|
||||
expected_output: >
|
||||
The final, polished blog post in markdown format without '```'.
|
||||
Publication-ready with clean formatting and professional prose.
|
||||
agent: editor
|
||||
output_file: output/post.md
|
||||
@@ -8,8 +8,8 @@ from crewai.project import CrewBase, agent, crew, task
|
||||
|
||||
|
||||
@CrewBase
|
||||
class PoemCrew:
|
||||
"""Poem Crew"""
|
||||
class ContentCrew:
|
||||
"""Content Crew"""
|
||||
|
||||
agents: list[BaseAgent]
|
||||
tasks: list[Task]
|
||||
@@ -20,26 +20,50 @@ class PoemCrew:
|
||||
agents_config = "config/agents.yaml"
|
||||
tasks_config = "config/tasks.yaml"
|
||||
|
||||
# If you would lik to add tools to your crew, you can learn more about it here:
|
||||
# If you would like to add tools to your crew, you can learn more about it here:
|
||||
# https://docs.crewai.com/concepts/agents#agent-tools
|
||||
@agent
|
||||
def poem_writer(self) -> Agent:
|
||||
def planner(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config["poem_writer"], # type: ignore[index]
|
||||
config=self.agents_config["planner"], # type: ignore[index]
|
||||
)
|
||||
|
||||
@agent
|
||||
def writer(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config["writer"], # type: ignore[index]
|
||||
)
|
||||
|
||||
@agent
|
||||
def editor(self) -> Agent:
|
||||
return Agent(
|
||||
config=self.agents_config["editor"], # type: ignore[index]
|
||||
)
|
||||
|
||||
# To learn more about structured task outputs,
|
||||
# task dependencies, and task callbacks, check out the documentation:
|
||||
# https://docs.crewai.com/concepts/tasks#overview-of-a-task
|
||||
@task
|
||||
def write_poem(self) -> Task:
|
||||
def planning_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config["write_poem"], # type: ignore[index]
|
||||
config=self.tasks_config["planning_task"], # type: ignore[index]
|
||||
)
|
||||
|
||||
@task
|
||||
def writing_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config["writing_task"], # type: ignore[index]
|
||||
)
|
||||
|
||||
@task
|
||||
def editing_task(self) -> Task:
|
||||
return Task(
|
||||
config=self.tasks_config["editing_task"], # type: ignore[index]
|
||||
)
|
||||
|
||||
@crew
|
||||
def crew(self) -> Crew:
|
||||
"""Creates the Research Crew"""
|
||||
"""Creates the Content Crew"""
|
||||
# To learn how to add knowledge sources to your crew, check out the documentation:
|
||||
# https://docs.crewai.com/concepts/knowledge#what-is-knowledge
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
"""Poem crew template."""
|
||||
@@ -1,11 +0,0 @@
|
||||
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.
|
||||
@@ -1,7 +0,0 @@
|
||||
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
|
||||
@@ -1,59 +1,60 @@
|
||||
#!/usr/bin/env python
|
||||
from random import randint
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from crewai.flow import Flow, listen, start
|
||||
|
||||
from {{folder_name}}.crews.poem_crew.poem_crew import PoemCrew
|
||||
from {{folder_name}}.crews.content_crew.content_crew import ContentCrew
|
||||
|
||||
|
||||
class PoemState(BaseModel):
|
||||
sentence_count: int = 1
|
||||
poem: str = ""
|
||||
class ContentState(BaseModel):
|
||||
topic: str = ""
|
||||
outline: str = ""
|
||||
draft: str = ""
|
||||
final_post: str = ""
|
||||
|
||||
|
||||
class PoemFlow(Flow[PoemState]):
|
||||
class ContentFlow(Flow[ContentState]):
|
||||
|
||||
@start()
|
||||
def generate_sentence_count(self, crewai_trigger_payload: dict = None):
|
||||
print("Generating sentence count")
|
||||
def plan_content(self, crewai_trigger_payload: dict = None):
|
||||
print("Planning content")
|
||||
|
||||
# Use trigger payload if available
|
||||
if crewai_trigger_payload:
|
||||
# Example: use trigger data to influence sentence count
|
||||
self.state.sentence_count = crewai_trigger_payload.get('sentence_count', randint(1, 5))
|
||||
self.state.topic = crewai_trigger_payload.get("topic", "AI Agents")
|
||||
print(f"Using trigger payload: {crewai_trigger_payload}")
|
||||
else:
|
||||
self.state.sentence_count = randint(1, 5)
|
||||
self.state.topic = "AI Agents"
|
||||
|
||||
@listen(generate_sentence_count)
|
||||
def generate_poem(self):
|
||||
print("Generating poem")
|
||||
print(f"Topic: {self.state.topic}")
|
||||
|
||||
@listen(plan_content)
|
||||
def generate_content(self):
|
||||
print(f"Generating content on: {self.state.topic}")
|
||||
result = (
|
||||
PoemCrew()
|
||||
ContentCrew()
|
||||
.crew()
|
||||
.kickoff(inputs={"sentence_count": self.state.sentence_count})
|
||||
.kickoff(inputs={"topic": self.state.topic})
|
||||
)
|
||||
|
||||
print("Poem generated", result.raw)
|
||||
self.state.poem = result.raw
|
||||
print("Content generated")
|
||||
self.state.final_post = result.raw
|
||||
|
||||
@listen(generate_poem)
|
||||
def save_poem(self):
|
||||
print("Saving poem")
|
||||
with open("poem.txt", "w") as f:
|
||||
f.write(self.state.poem)
|
||||
@listen(generate_content)
|
||||
def save_content(self):
|
||||
print("Saving content")
|
||||
with open("output/post.md", "w") as f:
|
||||
f.write(self.state.final_post)
|
||||
print("Post saved to output/post.md")
|
||||
|
||||
|
||||
def kickoff():
|
||||
poem_flow = PoemFlow()
|
||||
poem_flow.kickoff()
|
||||
content_flow = ContentFlow()
|
||||
content_flow.kickoff()
|
||||
|
||||
|
||||
def plot():
|
||||
poem_flow = PoemFlow()
|
||||
poem_flow.plot()
|
||||
content_flow = ContentFlow()
|
||||
content_flow.plot()
|
||||
|
||||
|
||||
def run_with_trigger():
|
||||
@@ -74,10 +75,10 @@ def run_with_trigger():
|
||||
|
||||
# Create flow and kickoff with trigger payload
|
||||
# The @start() methods will automatically receive crewai_trigger_payload parameter
|
||||
poem_flow = PoemFlow()
|
||||
content_flow = ContentFlow()
|
||||
|
||||
try:
|
||||
result = poem_flow.kickoff({"crewai_trigger_payload": trigger_payload})
|
||||
result = content_flow.kickoff({"crewai_trigger_payload": trigger_payload})
|
||||
return result
|
||||
except Exception as e:
|
||||
raise Exception(f"An error occurred while running the flow with trigger: {e}")
|
||||
|
||||
Reference in New Issue
Block a user