Skip to content

Commit d2e57e3

Browse files
authored
updating poem to content use case (#5286)
* updating poem to content use case * addressing CVE-2026-35030
1 parent d039a07 commit d2e57e3

11 files changed

Lines changed: 4422 additions & 4991 deletions

File tree

lib/crewai/src/crewai/cli/create_flow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def create_flow(name: str) -> None:
4646
tools_template_files = ["tools/__init__.py", "tools/custom_tool.py"]
4747

4848
crew_folders = [
49-
"poem_crew",
49+
"content_crew",
5050
]
5151

5252
def process_file(src_file: Path, dst_file: Path) -> None:

lib/crewai/src/crewai/cli/templates/AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ my_crew/
120120
my_flow/
121121
├── src/my_flow/
122122
│ ├── crews/ # Multiple crew definitions
123-
│ │ └── poem_crew/
123+
│ │ └── content_crew/
124124
│ │ ├── config/
125125
│ │ │ ├── agents.yaml
126126
│ │ │ └── tasks.yaml
127-
│ │ └── poem_crew.py
127+
│ │ └── content_crew.py
128128
│ ├── tools/ # Custom tools
129129
│ ├── main.py # Flow orchestration
130130
│ └── ...

lib/crewai/src/crewai/cli/templates/flow/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ crewai run
3838

3939
This command initializes the {{name}} Flow as defined in your configuration.
4040

41-
This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root folder.
41+
This example, unmodified, will run a content creation flow on AI Agents and save the output to `output/post.md`.
4242

4343
## Understanding Your Crew
4444

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
planner:
2+
role: >
3+
Content Planner
4+
goal: >
5+
Plan a detailed and engaging blog post outline on {topic}
6+
backstory: >
7+
You're an experienced content strategist who excels at creating
8+
structured outlines for blog posts. You know how to organize ideas
9+
into a logical flow that keeps readers engaged from start to finish.
10+
11+
writer:
12+
role: >
13+
Content Writer
14+
goal: >
15+
Write a compelling and well-structured blog post on {topic}
16+
based on the provided outline
17+
backstory: >
18+
You're a skilled writer with a talent for turning outlines into
19+
engaging, informative blog posts. Your writing is clear, conversational,
20+
and backed by solid reasoning. You adapt your tone to the subject matter
21+
while keeping things accessible to a broad audience.
22+
23+
editor:
24+
role: >
25+
Content Editor
26+
goal: >
27+
Review and polish the blog post on {topic} to ensure it is
28+
publication-ready
29+
backstory: >
30+
You're a meticulous editor with years of experience refining written
31+
content. You have an eye for clarity, flow, grammar, and consistency.
32+
You improve prose without changing the author's voice and ensure every
33+
piece you touch is polished and professional.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
planning_task:
2+
description: >
3+
Create a detailed outline for a blog post about {topic}.
4+
5+
The outline should include:
6+
- A compelling title
7+
- An introduction hook
8+
- 3-5 main sections with key points to cover in each
9+
- A conclusion with a call to action
10+
11+
Make the outline detailed enough that a writer can produce
12+
a full blog post from it without additional research.
13+
expected_output: >
14+
A structured blog post outline with a title, introduction notes,
15+
detailed section breakdowns, and conclusion notes.
16+
agent: planner
17+
18+
writing_task:
19+
description: >
20+
Using the outline provided, write a full blog post about {topic}.
21+
22+
Requirements:
23+
- Follow the outline structure closely
24+
- Write in a clear, engaging, and conversational tone
25+
- Each section should be 2-3 paragraphs
26+
- Include a strong introduction and conclusion
27+
- Target around 800-1200 words
28+
expected_output: >
29+
A complete blog post in markdown format, ready for editing.
30+
The post should follow the outline and be well-written with
31+
clear transitions between sections.
32+
agent: writer
33+
34+
editing_task:
35+
description: >
36+
Review and edit the blog post about {topic}.
37+
38+
Focus on:
39+
- Fixing any grammar or spelling errors
40+
- Improving sentence clarity and flow
41+
- Ensuring consistent tone throughout
42+
- Strengthening the introduction and conclusion
43+
- Removing any redundancy
44+
45+
Do not rewrite the post — refine and polish it.
46+
expected_output: >
47+
The final, polished blog post in markdown format without '```'.
48+
Publication-ready with clean formatting and professional prose.
49+
agent: editor
50+
output_file: output/post.md

lib/crewai/src/crewai/cli/templates/flow/crews/poem_crew/poem_crew.py renamed to lib/crewai/src/crewai/cli/templates/flow/crews/content_crew/content_crew.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99

1010
@CrewBase
11-
class PoemCrew:
12-
"""Poem Crew"""
11+
class ContentCrew:
12+
"""Content Crew"""
1313

1414
agents: list[BaseAgent]
1515
tasks: list[Task]
@@ -20,26 +20,50 @@ class PoemCrew:
2020
agents_config = "config/agents.yaml"
2121
tasks_config = "config/tasks.yaml"
2222

23-
# If you would lik to add tools to your crew, you can learn more about it here:
23+
# If you would like to add tools to your crew, you can learn more about it here:
2424
# https://docs.crewai.com/concepts/agents#agent-tools
2525
@agent
26-
def poem_writer(self) -> Agent:
26+
def planner(self) -> Agent:
2727
return Agent(
28-
config=self.agents_config["poem_writer"], # type: ignore[index]
28+
config=self.agents_config["planner"], # type: ignore[index]
29+
)
30+
31+
@agent
32+
def writer(self) -> Agent:
33+
return Agent(
34+
config=self.agents_config["writer"], # type: ignore[index]
35+
)
36+
37+
@agent
38+
def editor(self) -> Agent:
39+
return Agent(
40+
config=self.agents_config["editor"], # type: ignore[index]
2941
)
3042

3143
# To learn more about structured task outputs,
3244
# task dependencies, and task callbacks, check out the documentation:
3345
# https://docs.crewai.com/concepts/tasks#overview-of-a-task
3446
@task
35-
def write_poem(self) -> Task:
47+
def planning_task(self) -> Task:
48+
return Task(
49+
config=self.tasks_config["planning_task"], # type: ignore[index]
50+
)
51+
52+
@task
53+
def writing_task(self) -> Task:
54+
return Task(
55+
config=self.tasks_config["writing_task"], # type: ignore[index]
56+
)
57+
58+
@task
59+
def editing_task(self) -> Task:
3660
return Task(
37-
config=self.tasks_config["write_poem"], # type: ignore[index]
61+
config=self.tasks_config["editing_task"], # type: ignore[index]
3862
)
3963

4064
@crew
4165
def crew(self) -> Crew:
42-
"""Creates the Research Crew"""
66+
"""Creates the Content Crew"""
4367
# To learn how to add knowledge sources to your crew, check out the documentation:
4468
# https://docs.crewai.com/concepts/knowledge#what-is-knowledge
4569

lib/crewai/src/crewai/cli/templates/flow/crews/poem_crew/__init__.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

lib/crewai/src/crewai/cli/templates/flow/crews/poem_crew/config/agents.yaml

Lines changed: 0 additions & 11 deletions
This file was deleted.

lib/crewai/src/crewai/cli/templates/flow/crews/poem_crew/config/tasks.yaml

Lines changed: 0 additions & 7 deletions
This file was deleted.

lib/crewai/src/crewai/cli/templates/flow/main.py

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,60 @@
11
#!/usr/bin/env python
2-
from random import randint
3-
42
from pydantic import BaseModel
53

64
from crewai.flow import Flow, listen, start
75

8-
from {{folder_name}}.crews.poem_crew.poem_crew import PoemCrew
6+
from {{folder_name}}.crews.content_crew.content_crew import ContentCrew
97

108

11-
class PoemState(BaseModel):
12-
sentence_count: int = 1
13-
poem: str = ""
9+
class ContentState(BaseModel):
10+
topic: str = ""
11+
outline: str = ""
12+
draft: str = ""
13+
final_post: str = ""
1414

1515

16-
class PoemFlow(Flow[PoemState]):
16+
class ContentFlow(Flow[ContentState]):
1717

1818
@start()
19-
def generate_sentence_count(self, crewai_trigger_payload: dict = None):
20-
print("Generating sentence count")
19+
def plan_content(self, crewai_trigger_payload: dict = None):
20+
print("Planning content")
2121

22-
# Use trigger payload if available
2322
if crewai_trigger_payload:
24-
# Example: use trigger data to influence sentence count
25-
self.state.sentence_count = crewai_trigger_payload.get('sentence_count', randint(1, 5))
23+
self.state.topic = crewai_trigger_payload.get("topic", "AI Agents")
2624
print(f"Using trigger payload: {crewai_trigger_payload}")
2725
else:
28-
self.state.sentence_count = randint(1, 5)
26+
self.state.topic = "AI Agents"
27+
28+
print(f"Topic: {self.state.topic}")
2929

30-
@listen(generate_sentence_count)
31-
def generate_poem(self):
32-
print("Generating poem")
30+
@listen(plan_content)
31+
def generate_content(self):
32+
print(f"Generating content on: {self.state.topic}")
3333
result = (
34-
PoemCrew()
34+
ContentCrew()
3535
.crew()
36-
.kickoff(inputs={"sentence_count": self.state.sentence_count})
36+
.kickoff(inputs={"topic": self.state.topic})
3737
)
3838

39-
print("Poem generated", result.raw)
40-
self.state.poem = result.raw
39+
print("Content generated")
40+
self.state.final_post = result.raw
4141

42-
@listen(generate_poem)
43-
def save_poem(self):
44-
print("Saving poem")
45-
with open("poem.txt", "w") as f:
46-
f.write(self.state.poem)
42+
@listen(generate_content)
43+
def save_content(self):
44+
print("Saving content")
45+
with open("output/post.md", "w") as f:
46+
f.write(self.state.final_post)
47+
print("Post saved to output/post.md")
4748

4849

4950
def kickoff():
50-
poem_flow = PoemFlow()
51-
poem_flow.kickoff()
51+
content_flow = ContentFlow()
52+
content_flow.kickoff()
5253

5354

5455
def plot():
55-
poem_flow = PoemFlow()
56-
poem_flow.plot()
56+
content_flow = ContentFlow()
57+
content_flow.plot()
5758

5859

5960
def run_with_trigger():
@@ -74,10 +75,10 @@ def run_with_trigger():
7475

7576
# Create flow and kickoff with trigger payload
7677
# The @start() methods will automatically receive crewai_trigger_payload parameter
77-
poem_flow = PoemFlow()
78+
content_flow = ContentFlow()
7879

7980
try:
80-
result = poem_flow.kickoff({"crewai_trigger_payload": trigger_payload})
81+
result = content_flow.kickoff({"crewai_trigger_payload": trigger_payload})
8182
return result
8283
except Exception as e:
8384
raise Exception(f"An error occurred while running the flow with trigger: {e}")

0 commit comments

Comments
 (0)