-
Notifications
You must be signed in to change notification settings - Fork 3k
Refactor AI News Generator to use CrewAI Flows #178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Refactor AI News Generator to use CrewAI Flows #178
Conversation
- Replace traditional Crew orchestration with Flow-based approach - Implement NewsGeneratorFlow with @start and @listen decorators - Add modular two-phase workflow: research phase and writing phase - Create structured state management with Pydantic models - Add CLI interface through main.py for command-line usage - Update Streamlit app to use new Flow implementation - Enhance README with comprehensive Flow-based architecture documentation - Maintain backward compatibility with existing Streamlit interface 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
WalkthroughThis update introduces a major refactor of the AI News Generator, shifting from manual agent orchestration to a modular, flow-based architecture using CrewAI Flows. New modules and CLI entry points are added, and the README is extensively rewritten to document the new architecture, usage, and interfaces. The core logic is now encapsulated in a structured, stateful flow. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI/Web/API
participant NewsGeneratorFlow
participant ResearchAgent
participant ContentWriterAgent
User->>CLI/Web/API: Provide topic
CLI/Web/API->>NewsGeneratorFlow: kickoff(topic)
NewsGeneratorFlow->>ResearchAgent: research_phase(topic)
ResearchAgent-->>NewsGeneratorFlow: research_brief, sources, findings
NewsGeneratorFlow->>ContentWriterAgent: writing_phase(research_brief)
ContentWriterAgent-->>NewsGeneratorFlow: blog post (markdown)
NewsGeneratorFlow-->>CLI/Web/API: return blog post
CLI/Web/API-->>User: Display/save blog post
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (2)
ai_news_generator/app.py (2)
29-29
: Temperature setting is not being usedThe temperature slider is defined in the UI but never passed to the content generation flow. This means user adjustments have no effect.
Consider passing the temperature to the flow or removing the slider if it's not intended to be configurable:
-def generate_content(topic): +def generate_content(topic, temperature=0.7): """ Generate content using the new CrewAI Flow-based approach """ - return generate_content_with_flow(topic) + return generate_content_with_flow(topic, temperature)Then update the call on line 57:
- result = generate_content(topic) + result = generate_content(topic, temperature)Also applies to: 47-51
64-64
: Fix AttributeError when accessing result.rawThe
generate_content_with_flow
function returns a string, not an object with araw
attribute. This will cause anAttributeError
when users try to download content.- data=result.raw, + data=result,
🧹 Nitpick comments (6)
ai_news_generator/main.py (1)
15-94
: Add return type annotation for clarityThe
main()
function returns integer exit codes but lacks a return type annotation. This would improve code clarity and type safety.-def main(): +def main() -> int:ai_news_generator/README.md (3)
21-31
: Add language specifier to fenced code blockThe ASCII diagram code block should have a language specifier for proper markdown formatting.
-``` +```text ┌─────────────────┐ @start ┌─────────────────┐ │ Research Phase │──────────────▶│ Writing Phase │
43-44
: Fix list indentation for consistencyThe unordered list items have inconsistent indentation (3 spaces instead of standard 0 or 2).
- - [Serper API Key](https://serper.dev/) - - [Cohere API Key](https://dashboard.cohere.com/api-keys) +- [Serper API Key](https://serper.dev/) +- [Cohere API Key](https://dashboard.cohere.com/api-keys)
153-160
: Add language specifier to project structure code blockThe project structure display should have a language specifier.
-``` +```text ai_news_generator/ ├── app.py # Streamlit web interfaceai_news_generator/news_flow.py (2)
129-142
: Consider handling large research resultsEmbedding the entire research results directly in the task description (line 131) could exceed token limits for large research outputs. Consider implementing truncation or summarization for robustness.
writing_task = Task( description=f""" - Using the research brief provided: {research_results} + Using the research brief provided: {research_results[:5000] if len(research_results) > 5000 else research_results} + {f"... [truncated - full research available in context]" if len(research_results) > 5000 else ""} Create an engaging blog post that:Alternatively, pass the research through the inputs parameter instead of embedding it in the description.
181-193
: Add temperature parameter support for consistencyTo support the temperature slider in the Streamlit UI, consider adding a temperature parameter to this convenience function.
-def generate_content_with_flow(topic: str) -> str: +def generate_content_with_flow(topic: str, temperature: float = 0.7) -> str: """ Convenience function to generate content using the NewsGeneratorFlow Args: topic (str): The topic to research and write about + temperature (float): The temperature setting for the LLM (0.0-1.0) Returns: str: The generated blog post content """ flow = NewsGeneratorFlow() + # Override the default temperature if needed + flow.llm.temperature = temperature result = flow.kickoff(inputs={"topic": topic}) return str(result)Note: This assumes the LLM object allows temperature modification after initialization. Alternatively, pass temperature to the NewsGeneratorFlow constructor.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
ai_news_generator/__pycache__/app.cpython-311.pyc
is excluded by!**/*.pyc
ai_news_generator/__pycache__/main.cpython-311.pyc
is excluded by!**/*.pyc
ai_news_generator/__pycache__/news_flow.cpython-311.pyc
is excluded by!**/*.pyc
📒 Files selected for processing (4)
ai_news_generator/README.md
(1 hunks)ai_news_generator/app.py
(2 hunks)ai_news_generator/main.py
(1 hunks)ai_news_generator/news_flow.py
(1 hunks)
🧰 Additional context used
🪛 Ruff (0.12.2)
ai_news_generator/main.py
11-11: typing.Optional
imported but unused
Remove unused import: typing.Optional
(F401)
ai_news_generator/news_flow.py
1-1: os
imported but unused
Remove unused import: os
(F401)
🪛 markdownlint-cli2 (0.17.2)
ai_news_generator/README.md
21-21: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
43-43: Unordered list indentation
Expected: 0; Actual: 3
(MD007, ul-indent)
44-44: Unordered list indentation
Expected: 0; Actual: 3
(MD007, ul-indent)
153-153: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (1)
ai_news_generator/news_flow.py (1)
167-178
: Verify Flow base class state initialization
I couldn’t locate theFlow
implementation in the repo—it appears to be imported from an external package. Please confirm whetherFlow.kickoff()
already initializes or resetsself.state
. If it does, you can simplify the override here:def kickoff(self, inputs: Dict[str, Any]) -> Any: """ Initialize and run the flow with the given topic """ - # Initialize state with the topic - if not hasattr(self, 'state') or self.state is None: - self.state = ResearchState(topic=inputs.get("topic", "")) - else: - self.state.topic = inputs.get("topic", "") + # Ensure state is initialized (remove if handled by Flow base) + self.state = ResearchState(topic=inputs.get("topic", "")) # Start the flow execution return super().kickoff(inputs=inputs)
- Check the import in
ai_news_generator/news_flow.py
to see whereFlow
is coming from.- Verify if
Flow.kickoff()
already managesself.state
.- If it does not, keep or adjust this manual initialization.
|
||
import argparse | ||
import sys | ||
from typing import Optional |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused import
The Optional
type from typing
is imported but never used in the code.
-from typing import Optional
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
from typing import Optional |
🧰 Tools
🪛 Ruff (0.12.2)
11-11: typing.Optional
imported but unused
Remove unused import: typing.Optional
(F401)
🤖 Prompt for AI Agents
In ai_news_generator/main.py at line 11, the import statement for Optional from
typing is unused. Remove the import of Optional to clean up the code and avoid
unnecessary imports.
@@ -0,0 +1,193 @@ | |||
import os |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused import
The os
module is imported but never used in the code.
-import os
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import os | |
# (Removed the unused import `os`) |
🧰 Tools
🪛 Ruff (0.12.2)
1-1: os
imported but unused
Remove unused import: os
(F401)
🤖 Prompt for AI Agents
In ai_news_generator/news_flow.py at line 1, the 'os' module is imported but not
used anywhere in the file. Remove the import statement for 'os' to clean up the
code and avoid unnecessary imports.
Summary
This PR refactors the AI News Generator module to use CrewAI's new Flow-based architecture, replacing the traditional crew orchestration with a more modular and maintainable approach.
Key Changes
• Flow Implementation: Created
NewsGeneratorFlow
class using@start
and@listen
decorators• Two-Phase Architecture: Separated research and writing into distinct, coordinated phases
• State Management: Implemented structured state handling with Pydantic models
• CLI Interface: Added
main.py
for command-line usage with argument parsing• Modular Design: Refactored agents into reusable, specialized components
• Enhanced Documentation: Updated README with comprehensive Flow architecture details
Architecture Improvements
The new Flow-based approach provides:
@listen
decorators for phase coordinationFiles Changed
news_flow.py
- New Flow implementation with structured workflowmain.py
- New CLI interface for command-line usageapp.py
- Updated Streamlit interface to use FlowREADME.md
- Enhanced documentation with architecture detailsTesting
Usage
Command Line:
python main.py --topic "AI developments" --output article.md
Streamlit Web Interface:
Programmatic:
This refactoring aligns the AI News Generator with modern CrewAI Flow patterns while maintaining all existing functionality.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation