updating poem to content use case (#5286)

* updating poem to content use case

* addressing CVE-2026-35030
This commit is contained in:
Lorenze Jay
2026-04-05 22:05:02 -07:00
committed by GitHub
parent d039a075aa
commit d2e57e375b
11 changed files with 4351 additions and 4920 deletions

View File

@@ -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:

View File

@@ -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
│ └── ...

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -1 +0,0 @@
"""Poem crew template."""

View File

@@ -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.

View File

@@ -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

View File

@@ -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}")

9058
uv.lock generated

File diff suppressed because it is too large Load Diff