-
Notifications
You must be signed in to change notification settings - Fork 3k
fix(feat/crewai): Use CrewAI flows to create an agentic workflow for ... #169
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?
fix(feat/crewai): Use CrewAI flows to create an agentic workflow for ... #169
Conversation
WalkthroughThis update transforms the AI News Generator into a modular, multi-phase CrewAI Flow system. It introduces specialized crews and agents for research, content creation, and editing, each defined via configuration files and orchestrated through a new flow class. The Streamlit UI, project structure, and state management are overhauled, with new tools, metrics, and documentation added throughout. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant StreamlitApp
participant NewsGeneratorFlow
participant ResearchCrew
participant ContentCrew
participant EditingCrew
User->>StreamlitApp: Enter topic & start generation
StreamlitApp->>NewsGeneratorFlow: Instantiate and kickoff flow
NewsGeneratorFlow->>ResearchCrew: Run research phase
ResearchCrew-->>NewsGeneratorFlow: Return research report
NewsGeneratorFlow->>ContentCrew: Run content creation phase
ContentCrew-->>NewsGeneratorFlow: Return content draft
NewsGeneratorFlow->>EditingCrew: Run editing phase
EditingCrew-->>NewsGeneratorFlow: Return edited content
NewsGeneratorFlow->>NewsGeneratorFlow: Finalize article, parse sections, compute metrics
NewsGeneratorFlow-->>StreamlitApp: Return article, metrics, and progress
StreamlitApp-->>User: Display results, progress, and download options
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 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: 13
♻️ Duplicate comments (1)
ai_news_generator/src/ai_news_flow/crews/research_crew/research_crew.py (1)
80-81
: Verify thatself.agents
andself.tasks
are properly initializedSame as in
EditingCrew
- these attributes are referenced but not explicitly defined.
🧹 Nitpick comments (18)
ai_news_generator/src/ai_news_flow/crews/editing_crew/config/agents.yaml (1)
1-32
: Fix YAML formatting issues while maintaining excellent agent definitions.The agent roles are well-defined and appropriate for the editing workflow. However, there are formatting issues that need to be addressed:
- Multiple lines have trailing spaces
- Missing newline at the end of the file
Apply this formatting fix:
You're an experienced copy editor with a keen eye for detail and excellent command of language. - You specialize in improving content clarity, fixing grammatical errors, ensuring consistent style, - and enhancing overall readability. You understand different writing styles and can adapt editing + You specialize in improving content clarity, fixing grammatical errors, ensuring consistent style, + and enhancing overall readability. You understand different writing styles and can adapt editing approaches to maintain the author's voice while improving quality. You're a technical editor with expertise in fact-checking and ensuring content accuracy. - You excel at verifying technical details, checking citation formats, ensuring consistency - in technical terms and concepts, and validating that all claims are properly supported. + You excel at verifying technical details, checking citation formats, ensuring consistency + in technical terms and concepts, and validating that all claims are properly supported. You have a systematic approach to technical review and quality assurance. You're a publishing editor who specializes in preparing content for final publication. - You focus on formatting consistency, content structure optimization, readability enhancement, - and ensuring the final product meets publishing standards. You have experience with various - content management systems and publishing workflows. + You focus on formatting consistency, content structure optimization, readability enhancement, + and ensuring the final product meets publishing standards. You have experience with various + content management systems and publishing workflows.ai_news_generator/src/ai_news_flow/crews/research_crew/config/agents.yaml (1)
1-35
: Fix YAML formatting issues while maintaining excellent research agent definitions.The research agent roles are well-structured with clear responsibilities that complement each other in the research workflow. However, there are formatting issues that need to be addressed:
- Multiple lines have trailing spaces
- Missing newline at the end of the file
Apply this formatting fix to remove trailing spaces and add the missing newline:
You're an expert research analyst with advanced web research skills. You excel at finding, - analyzing, and synthesizing information from across the internet using search tools. You're skilled at - distinguishing reliable sources from unreliable ones, fact-checking, cross-referencing information, and - identifying key patterns and insights. You provide well-organized research briefs with proper citations - and source verification. Your analysis includes both raw data and interpreted insights, making complex + analyzing, and synthesizing information from across the internet using search tools. You're skilled at + distinguishing reliable sources from unreliable ones, fact-checking, cross-referencing information, and + identifying key patterns and insights. You provide well-organized research briefs with proper citations + and source verification. Your analysis includes both raw data and interpreted insights, making complex information accessible and actionable. You're a meticulous fact-checker with extensive experience in verifying information accuracy. - You excel at cross-referencing multiple sources, identifying potential misinformation, and assessing - source credibility. You have a keen eye for detail and use systematic approaches to validate claims, - statistics, and statements. Your expertise includes evaluating publication dates, author credentials, + You excel at cross-referencing multiple sources, identifying potential misinformation, and assessing + source credibility. You have a keen eye for detail and use systematic approaches to validate claims, + statistics, and statements. Your expertise includes evaluating publication dates, author credentials, and institutional affiliations to ensure information reliability. - Data Synthesis Specialist + Data Synthesis Specialist goal: > Organize and structure research findings into coherent, well-categorized insights about {topic} backstory: > - You're a data synthesis expert who specializes in taking complex, multi-source research and - organizing it into clear, actionable insights. You excel at identifying patterns, themes, and - relationships across different pieces of information. Your strength lies in creating structured + You're a data synthesis expert who specializes in taking complex, multi-source research and + organizing it into clear, actionable insights. You excel at identifying patterns, themes, and + relationships across different pieces of information. Your strength lies in creating structured - summaries that highlight key findings, trends, and implications while maintaining source traceability. + summaries that highlight key findings, trends, and implications while maintaining source traceability.ai_news_generator/src/ai_news_flow/crews/content_crew/config/agents.yaml (1)
1-33
: Fix YAML formatting issues while maintaining excellent content agent definitions.The content creation agent roles are well-designed with clear separation between strategy, writing, and SEO optimization. However, there are formatting issues that need to be addressed:
- Multiple lines have trailing spaces
- Missing newline at the end of the file
Apply this formatting fix to remove trailing spaces and add the missing newline:
You're a content strategist with expertise in creating compelling narratives from research data. - You excel at identifying the most interesting angles, structuring information flow, and determining + You excel at identifying the most interesting angles, structuring information flow, and determining the best way to present complex information to engage readers. You understand audience psychology and know how to craft content that is both informative and captivating. You're a skilled content writer specialized in creating engaging, accessible content from technical - research. You excel at maintaining the perfect balance between informative and entertaining writing, - while ensuring all facts and citations from the research are properly incorporated. You have a talent - for making complex topics approachable without oversimplifying them. Your writing style is clear, + research. You excel at maintaining the perfect balance between informative and entertaining writing, + while ensuring all facts and citations from the research are properly incorporated. You have a talent + for making complex topics approachable without oversimplifying them. Your writing style is clear, engaging, and professional. You're an SEO expert who specializes in optimizing content for search engines without compromising - quality or readability. You understand keyword integration, content structure, meta descriptions, - and other SEO best practices. You work to ensure content reaches its intended audience through - organic search while maintaining engaging, valuable content. + quality or readability. You understand keyword integration, content structure, meta descriptions, + and other SEO best practices. You work to ensure content reaches its intended audience through + organic search while maintaining engaging, valuable content.ai_news_generator/src/ai_news_flow/crews/content_crew/content_crew.py (1)
1-1
: Remove unused import.The
os
module is imported but not used anywhere in the file.-import os
ai_news_generator/test_structure.py (1)
16-39
: Complete model instantiation tests for all imported modelsThe function imports
ResearchReport
,ContentDraft
, andEditedContent
but only tests instantiation ofNewsGeneratorState
andNewsArticle
. For comprehensive testing, instantiate all imported models.# Test basic instantiation state = NewsGeneratorState(topic="Test Topic") print(f" ✅ State created: {state.topic}") article = NewsArticle( title="Test Article", introduction="Test intro", conclusion="Test conclusion" ) print(f" ✅ Article created: {article.title}") + # Test other models + research = ResearchReport( + executive_summary="Test summary", + key_findings=["Finding 1", "Finding 2"] + ) + print(f" ✅ ResearchReport created") + + draft = ContentDraft( + raw_content="Test content", + sources_used=["Source 1"] + ) + print(f" ✅ ContentDraft created") + + edited = EditedContent( + final_content="Final test content", + readability_score=75.0 + ) + print(f" ✅ EditedContent created") + print("✅ Models test passed!")ai_news_generator/src/ai_news_flow/crews/content_crew/config/tasks.yaml (1)
10-62
: Fix YAML formatting issuesThe YAML file has formatting issues that should be corrected for consistency.
5. Create an outline with compelling headlines 6. Determine the overall tone and approach - + Consider the target audience and ensure the strategy maximizes engagement while maintaining accuracy.Also remove trailing spaces from lines 31 and 52, and add a newline at the end of the file (line 62).
ai_news_generator/src/ai_news_flow/tools/custom_tools.py (2)
109-111
: Improve readability score accuracyThe current implementation uses a simplified formula that only considers sentence length. The actual Flesch Reading Ease formula also requires syllable count:
206.835 - 1.015 * (total words/total sentences) - 84.6 * (total syllables/total words)
.Consider implementing a more accurate formula or documenting that this is an approximation. You could add a comment:
# Simple readability score (Flesch-like approximation) -# Lower scores = harder to read, higher scores = easier to read +# NOTE: This is a simplified approximation using only sentence length. +# A full implementation would also count syllables per word. +# Lower scores = harder to read, higher scores = easier to read
146-161
: Consider implementing the enhancement or removing placeholder codeThe
EnhancedSearchTool
class currently doesn't add any functionality beyond the parentSerperDevTool
class. The comment indicates this is placeholder code.Either implement the actual enhancements or remove this class until the functionality is ready. Placeholder code adds unnecessary complexity.
ai_news_generator/src/ai_news_flow/crews/editing_crew/config/tasks.yaml (1)
11-11
: Fix YAML formatting issuesRemove trailing spaces and add a newline at the end of the file for better consistency and to avoid linting warnings.
- Maintain the author's voice while improving quality - + Maintain the author's voice while improving quality +Apply similar fixes to lines 33 and 56, and add a newline after line 67.
Also applies to: 33-33, 56-56, 67-67
ai_news_generator/README.md (2)
36-50
: Add language specification to fenced code blockThe fenced code block should specify a language for proper syntax highlighting.
-``` +```text ai_news_generator/
236-236
: Use proper heading instead of emphasisUsing bold text for headings is not semantic markdown. Consider using a proper heading level.
-**Built with ❤️ using CrewAI Flows, Streamlit, and Cohere's Command R7B** +### Built with ❤️ using CrewAI Flows, Streamlit, and Cohere's Command R7Bai_news_generator/src/ai_news_flow/crews/research_crew/config/tasks.yaml (1)
9-9
: Fix YAML formatting issuesRemove trailing spaces on lines 9, 15, 21, 35, and 55, and add a newline at the end of the file (after line 65).
These formatting issues should be fixed to maintain consistency and avoid linting warnings.
Also applies to: 15-15, 21-21, 35-35, 55-55, 65-65
ai_news_generator/app.py (2)
275-276
: Consider safer JSON import placementImporting
json
inside the function works but is unconventional. Consider moving it to the top of the file with other imports.+import json import os import sys import streamlit as st
Then remove the import from line 275.
134-142
: Consider adding input validationThe topic string from user input is passed directly to the flow without validation. Consider adding basic validation for length and content.
def generate_content_with_flow(topic: str, temperature: float = 0.7, max_sources: int = 10): """Generate content using the CrewAI flow workflow.""" + # Basic input validation + if len(topic) > 500: + raise ValueError("Topic is too long (max 500 characters)") + if not topic.strip(): + raise ValueError("Topic cannot be empty") + try:ai_news_generator/CREWAI_FLOW_INTEGRATION_SUMMARY.md (2)
25-52
: Add language specifier to the code blockThe fenced code block should specify a language for better syntax highlighting.
-``` +```plaintext ai_news_generator/
151-151
: Remove redundant phrasing in "SEO Optimization""SEO" already stands for "Search Engine Optimization", making "SEO Optimization" redundant.
-- **SEO Optimization** increases discoverability +- **SEO** increases discoverabilityai_news_generator/src/ai_news_flow/main.py (2)
2-5
: Remove unused importsThe following imports are not used in the code and should be removed to keep the codebase clean.
-import os -import asyncio from datetime import datetime -from pydantic import BaseModel
47-47
: Consider making editing temperature configurableThe editing crew uses a hardcoded temperature of 0.5 while other crews use the user-provided temperature parameter. If this is intentional for editing precision, consider documenting it or making it a separate configurable parameter.
Option 1: Use consistent temperature:
-self.editing_crew = EditingCrew(llm=self.llm, temperature=0.5) # Lower temp for editing +self.editing_crew = EditingCrew(llm=self.llm, temperature=temperature)Option 2: Add a separate parameter:
-def __init__(self, topic: str = "", temperature: float = 0.7, max_sources: int = 10): +def __init__(self, topic: str = "", temperature: float = 0.7, max_sources: int = 10, editing_temperature: float = 0.5):And then:
-self.editing_crew = EditingCrew(llm=self.llm, temperature=0.5) # Lower temp for editing +self.editing_crew = EditingCrew(llm=self.llm, temperature=editing_temperature)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
ai_news_generator/src/ai_news_flow/__pycache__/__init__.cpython-311.pyc
is excluded by!**/*.pyc
ai_news_generator/src/ai_news_flow/__pycache__/models.cpython-311.pyc
is excluded by!**/*.pyc
ai_news_generator/src/ai_news_flow/tools/__pycache__/__init__.cpython-311.pyc
is excluded by!**/*.pyc
ai_news_generator/src/ai_news_flow/tools/__pycache__/custom_tools.cpython-311.pyc
is excluded by!**/*.pyc
📒 Files selected for processing (17)
ai_news_generator/CREWAI_FLOW_INTEGRATION_SUMMARY.md
(1 hunks)ai_news_generator/README.md
(1 hunks)ai_news_generator/app.py
(1 hunks)ai_news_generator/pyproject.toml
(1 hunks)ai_news_generator/src/ai_news_flow/crews/content_crew/config/agents.yaml
(1 hunks)ai_news_generator/src/ai_news_flow/crews/content_crew/config/tasks.yaml
(1 hunks)ai_news_generator/src/ai_news_flow/crews/content_crew/content_crew.py
(1 hunks)ai_news_generator/src/ai_news_flow/crews/editing_crew/config/agents.yaml
(1 hunks)ai_news_generator/src/ai_news_flow/crews/editing_crew/config/tasks.yaml
(1 hunks)ai_news_generator/src/ai_news_flow/crews/editing_crew/editing_crew.py
(1 hunks)ai_news_generator/src/ai_news_flow/crews/research_crew/config/agents.yaml
(1 hunks)ai_news_generator/src/ai_news_flow/crews/research_crew/config/tasks.yaml
(1 hunks)ai_news_generator/src/ai_news_flow/crews/research_crew/research_crew.py
(1 hunks)ai_news_generator/src/ai_news_flow/main.py
(1 hunks)ai_news_generator/src/ai_news_flow/models.py
(1 hunks)ai_news_generator/src/ai_news_flow/tools/custom_tools.py
(1 hunks)ai_news_generator/test_structure.py
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
ai_news_generator/app.py (1)
ai_news_generator/src/ai_news_flow/main.py (4)
NewsGeneratorFlow
(20-265)kickoff
(268-272)get_processing_summary
(256-265)get_final_content
(250-254)
ai_news_generator/src/ai_news_flow/crews/content_crew/config/tasks.yaml (1)
Youtube-trend-analysis/app.py (1)
create_agents_and_tasks
(35-76)
ai_news_generator/src/ai_news_flow/tools/custom_tools.py (1)
agentic_rag/src/agentic_rag/tools/custom_tool.py (1)
DocumentSearchTool
(13-66)
ai_news_generator/src/ai_news_flow/crews/research_crew/config/tasks.yaml (3)
book-writer-flow/book_flow/book_writing_flow/src/book_writing_flow/crews/Outline_crew/outline_crew.py (1)
research_task
(28-29)book-writer-flow/book_flow/book_writing_flow/src/book_writing_flow/crews/Writer_crew/writer_crew.py (1)
research_topic
(29-30)Multi-Agent-deep-researcher-mcp-windows-linux/agents.py (1)
create_research_crew
(58-126)
🪛 YAMLlint (1.37.1)
ai_news_generator/src/ai_news_flow/crews/research_crew/config/agents.yaml
[error] 7-7: trailing spaces
(trailing-spaces)
[error] 8-8: trailing spaces
(trailing-spaces)
[error] 9-9: trailing spaces
(trailing-spaces)
[error] 10-10: trailing spaces
(trailing-spaces)
[error] 11-11: trailing spaces
(trailing-spaces)
[error] 20-20: trailing spaces
(trailing-spaces)
[error] 21-21: trailing spaces
(trailing-spaces)
[error] 22-22: trailing spaces
(trailing-spaces)
[error] 23-23: trailing spaces
(trailing-spaces)
[error] 28-28: trailing spaces
(trailing-spaces)
[error] 32-32: trailing spaces
(trailing-spaces)
[error] 33-33: trailing spaces
(trailing-spaces)
[error] 34-34: trailing spaces
(trailing-spaces)
[error] 35-35: no new line character at the end of file
(new-line-at-end-of-file)
ai_news_generator/src/ai_news_flow/crews/content_crew/config/agents.yaml
[error] 7-7: trailing spaces
(trailing-spaces)
[error] 8-8: trailing spaces
(trailing-spaces)
[error] 9-9: trailing spaces
(trailing-spaces)
[error] 18-18: trailing spaces
(trailing-spaces)
[error] 19-19: trailing spaces
(trailing-spaces)
[error] 20-20: trailing spaces
(trailing-spaces)
[error] 21-21: trailing spaces
(trailing-spaces)
[error] 30-30: trailing spaces
(trailing-spaces)
[error] 31-31: trailing spaces
(trailing-spaces)
[error] 32-32: trailing spaces
(trailing-spaces)
[error] 33-33: no new line character at the end of file
(new-line-at-end-of-file)
ai_news_generator/src/ai_news_flow/crews/editing_crew/config/agents.yaml
[error] 7-7: trailing spaces
(trailing-spaces)
[error] 8-8: trailing spaces
(trailing-spaces)
[error] 9-9: trailing spaces
(trailing-spaces)
[error] 18-18: trailing spaces
(trailing-spaces)
[error] 19-19: trailing spaces
(trailing-spaces)
[error] 20-20: trailing spaces
(trailing-spaces)
[error] 29-29: trailing spaces
(trailing-spaces)
[error] 30-30: trailing spaces
(trailing-spaces)
[error] 31-31: trailing spaces
(trailing-spaces)
[error] 32-32: no new line character at the end of file
(new-line-at-end-of-file)
ai_news_generator/src/ai_news_flow/crews/content_crew/config/tasks.yaml
[error] 10-10: trailing spaces
(trailing-spaces)
[error] 31-31: trailing spaces
(trailing-spaces)
[error] 52-52: trailing spaces
(trailing-spaces)
[error] 62-62: no new line character at the end of file
(new-line-at-end-of-file)
ai_news_generator/src/ai_news_flow/crews/editing_crew/config/tasks.yaml
[error] 11-11: trailing spaces
(trailing-spaces)
[error] 33-33: trailing spaces
(trailing-spaces)
[error] 56-56: trailing spaces
(trailing-spaces)
[error] 67-67: no new line character at the end of file
(new-line-at-end-of-file)
ai_news_generator/src/ai_news_flow/crews/research_crew/config/tasks.yaml
[error] 9-9: trailing spaces
(trailing-spaces)
[error] 15-15: trailing spaces
(trailing-spaces)
[error] 21-21: trailing spaces
(trailing-spaces)
[error] 35-35: trailing spaces
(trailing-spaces)
[error] 55-55: trailing spaces
(trailing-spaces)
[error] 65-65: no new line character at the end of file
(new-line-at-end-of-file)
🪛 Ruff (0.12.2)
ai_news_generator/test_structure.py
18-18: ai_news_flow.models.ResearchReport
imported but unused
Remove unused import
(F401)
20-20: ai_news_flow.models.ContentDraft
imported but unused
Remove unused import
(F401)
21-21: ai_news_flow.models.EditedContent
imported but unused
Remove unused import
(F401)
ai_news_generator/src/ai_news_flow/crews/editing_crew/editing_crew.py
1-1: os
imported but unused
Remove unused import: os
(F401)
ai_news_generator/app.py
4-4: datetime.datetime
imported but unused
Remove unused import: datetime.datetime
(F401)
148-148: Local variable result
is assigned to but never used
Remove assignment to unused variable result
(F841)
ai_news_generator/src/ai_news_flow/tools/custom_tools.py
20-20: requests
imported but unused
Remove unused import: requests
(F401)
21-21: datetime.datetime
imported but unused
Remove unused import: datetime.datetime
(F401)
ai_news_generator/src/ai_news_flow/crews/content_crew/content_crew.py
1-1: os
imported but unused
Remove unused import: os
(F401)
ai_news_generator/src/ai_news_flow/crews/research_crew/research_crew.py
1-1: os
imported but unused
Remove unused import: os
(F401)
ai_news_generator/src/ai_news_flow/main.py
2-2: os
imported but unused
Remove unused import: os
(F401)
3-3: asyncio
imported but unused
Remove unused import: asyncio
(F401)
5-5: pydantic.BaseModel
imported but unused
Remove unused import: pydantic.BaseModel
(F401)
271-271: Local variable result
is assigned to but never used
Remove assignment to unused variable result
(F841)
🪛 markdownlint-cli2 (0.17.2)
ai_news_generator/README.md
36-36: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
236-236: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
ai_news_generator/CREWAI_FLOW_INTEGRATION_SUMMARY.md
25-25: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🪛 LanguageTool
ai_news_generator/CREWAI_FLOW_INTEGRATION_SUMMARY.md
[style] ~151-~151: This phrase is redundant (‘O’ stands for ‘Optimization’). Use simply “SEO”.
Context: ...onal Editing** enhances readability - SEO Optimization increases discoverability ### User E...
(ACRONYM_TAUTOLOGY)
🔇 Additional comments (10)
ai_news_generator/pyproject.toml (5)
1-7
: LGTM! Clean project metadata setup.The Poetry configuration follows best practices with the src layout and appropriate initial version.
18-22
: LGTM! Good selection of development tools.The development dependencies provide a solid foundation for code quality and testing.
24-29
: LGTM! Standard build system with useful CLI entry point.The script configuration provides a convenient
ai-news-flow
command for workflow execution.
31-47
: LGTM! Comprehensive black configuration.The formatting configuration follows black's standards with appropriate exclusions.
49-56
: LGTM! isort configuration properly aligned with black.The import sorting configuration is compatible with black and follows best practices.
ai_news_generator/src/ai_news_flow/crews/content_crew/content_crew.py (3)
17-42
: LGTM! Well-structured agent definitions.The agent methods follow consistent patterns with appropriate configuration from YAML files and shared LLM instance.
44-67
: LGTM! Excellent task orchestration with proper dependencies.The task definitions create a well-structured sequential workflow with appropriate context dependencies and typed outputs.
69-84
: LGTM! Comprehensive crew configuration with advanced features.The crew is properly configured with sequential processing, memory, and embeddings for enhanced context understanding.
ai_news_generator/src/ai_news_flow/crews/editing_crew/editing_crew.py (1)
77-78
: Confirmself.agents
andself.tasks
initialization
Although each crew class setsagents_config
andtasks_config
, the@CrewBase
decorator (from the externalcrewai.project
package) must populateself.agents
andself.tasks
at runtime. If it doesn’t, these lines will raise an AttributeError:• File: ai_news_generator/src/ai_news_flow/crews/editing_crew/editing_crew.py
Lines 77–78agents=self.agents, tasks=self.tasks,Please verify—via the
crewai
documentation or by inspecting a crew instance—thatCrewBase
reads the YAML configs and assigns the correspondingagents
andtasks
attributes before they’re referenced.ai_news_generator/src/ai_news_flow/tools/custom_tools.py (1)
106-107
: Prevent division by zero for empty contentThe calculation of
avg_sentence_length
could cause a division by zero error if the content has no valid sentences.-avg_sentence_length = len(words) / len(sentences) if sentences else 0 +avg_sentence_length = len(words) / len(sentences) if sentences and len(sentences) > 0 else 0Likely an incorrect or invalid review comment.
import streamlit as st | ||
from crewai import Agent, Task, Crew, LLM | ||
from crewai_tools import SerperDevTool | ||
from datetime import datetime |
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 datetime
import is not used in the code.
-from datetime import datetime
📝 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 datetime import datetime |
🧰 Tools
🪛 Ruff (0.12.2)
4-4: datetime.datetime
imported but unused
Remove unused import: datetime.datetime
(F401)
🤖 Prompt for AI Agents
In ai_news_generator/app.py at line 4, the import statement for datetime is
unused. Remove the line "from datetime import datetime" to clean up the code and
avoid unnecessary imports.
st.session_state.workflow_state = flow | ||
|
||
# Run the flow | ||
result = flow.kickoff() |
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 variable assignment
The result
variable is assigned but never used.
-result = flow.kickoff()
+flow.kickoff()
📝 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.
result = flow.kickoff() | |
flow.kickoff() |
🧰 Tools
🪛 Ruff (0.12.2)
148-148: Local variable result
is assigned to but never used
Remove assignment to unused variable result
(F841)
🤖 Prompt for AI Agents
In ai_news_generator/app.py at line 148, the variable 'result' is assigned the
output of flow.kickoff() but is never used afterward. Remove the assignment by
calling flow.kickoff() directly without assigning it to 'result' to eliminate
the unused variable.
streamlit = "^1.32.0" | ||
pydantic = "^2.6.0" | ||
python-dotenv = "^1.0.0" | ||
asyncio = "^3.4.3" |
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 unnecessary asyncio dependency.
The asyncio
module is part of Python's standard library since Python 3.4, so it shouldn't be listed as an external dependency. This could cause installation issues or conflicts.
-asyncio = "^3.4.3"
📝 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.
asyncio = "^3.4.3" |
🤖 Prompt for AI Agents
In ai_news_generator/pyproject.toml at line 16, remove the line specifying
asyncio as a dependency because asyncio is included in Python's standard library
from version 3.4 onward and does not need to be installed separately.
@@ -0,0 +1,88 @@ | |||
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 this file.
-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 |
🧰 Tools
🪛 Ruff (0.12.2)
1-1: os
imported but unused
Remove unused import: os
(F401)
🤖 Prompt for AI Agents
In ai_news_generator/src/ai_news_flow/crews/editing_crew/editing_crew.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 unused imports and improve code clarity.
agents_config = 'config/agents.yaml' | ||
tasks_config = 'config/tasks.yaml' | ||
|
||
def __init__(self, llm=None, temperature=0.5): | ||
# Lower temperature for editing tasks to ensure consistency | ||
self.llm = llm or LLM(model="command-r", temperature=temperature) | ||
self.readability_tool = ReadabilityAnalyzer() | ||
|
||
@agent | ||
def copy_editor(self) -> Agent: | ||
return Agent( | ||
config=self.agents_config['copy_editor'], | ||
tools=[self.readability_tool], | ||
llm=self.llm, | ||
verbose=True, | ||
allow_delegation=False | ||
) |
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.
Critical: Configuration loading is broken
The agents_config
and tasks_config
are defined as strings (file paths), but the code attempts to use dictionary access on them (e.g., self.agents_config['copy_editor']
). This will cause a TypeError
at runtime.
You need to load and parse the YAML files first. Apply this fix:
+import yaml
+from pathlib import Path
@CrewBase
class EditingCrew:
"""Editing crew for polishing and finalizing content."""
- agents_config = 'config/agents.yaml'
- tasks_config = 'config/tasks.yaml'
+ agents_config_path = 'config/agents.yaml'
+ tasks_config_path = 'config/tasks.yaml'
def __init__(self, llm=None, temperature=0.5):
# Lower temperature for editing tasks to ensure consistency
self.llm = llm or LLM(model="command-r", temperature=temperature)
self.readability_tool = ReadabilityAnalyzer()
+
+ # Load configuration files
+ base_path = Path(__file__).parent
+ with open(base_path / self.agents_config_path, 'r') as f:
+ self.agents_config = yaml.safe_load(f)
+ with open(base_path / self.tasks_config_path, 'r') as f:
+ self.tasks_config = yaml.safe_load(f)
📝 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.
agents_config = 'config/agents.yaml' | |
tasks_config = 'config/tasks.yaml' | |
def __init__(self, llm=None, temperature=0.5): | |
# Lower temperature for editing tasks to ensure consistency | |
self.llm = llm or LLM(model="command-r", temperature=temperature) | |
self.readability_tool = ReadabilityAnalyzer() | |
@agent | |
def copy_editor(self) -> Agent: | |
return Agent( | |
config=self.agents_config['copy_editor'], | |
tools=[self.readability_tool], | |
llm=self.llm, | |
verbose=True, | |
allow_delegation=False | |
) | |
import yaml | |
from pathlib import Path | |
@CrewBase | |
class EditingCrew: | |
"""Editing crew for polishing and finalizing content.""" | |
agents_config_path = 'config/agents.yaml' | |
tasks_config_path = 'config/tasks.yaml' | |
def __init__(self, llm=None, temperature=0.5): | |
# Lower temperature for editing tasks to ensure consistency | |
self.llm = llm or LLM(model="command-r", temperature=temperature) | |
self.readability_tool = ReadabilityAnalyzer() | |
# Load configuration files | |
base_path = Path(__file__).parent | |
with open(base_path / self.agents_config_path, 'r') as f: | |
self.agents_config = yaml.safe_load(f) | |
with open(base_path / self.tasks_config_path, 'r') as f: | |
self.tasks_config = yaml.safe_load(f) | |
@agent | |
def copy_editor(self) -> Agent: | |
return Agent( | |
config=self.agents_config['copy_editor'], | |
tools=[self.readability_tool], | |
llm=self.llm, | |
verbose=True, | |
allow_delegation=False | |
) |
🤖 Prompt for AI Agents
In ai_news_generator/src/ai_news_flow/crews/editing_crew/editing_crew.py around
lines 12 to 28, agents_config and tasks_config are currently string file paths
but are used as dictionaries, causing a TypeError. Fix this by importing a YAML
parser, loading the YAML files from these paths during initialization, and
storing the parsed content as dictionaries in self.agents_config and
self.tasks_config. Then use these dictionaries for configuration access.
# Prepare content context for editing crew | ||
editing_context = { | ||
"topic": self.state.topic, | ||
"content_draft": self.state.content_draft.dict() if self.state.content_draft else {}, |
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.
🛠️ Refactor suggestion
Update deprecated Pydantic method
The .dict()
method is deprecated in Pydantic v2. Use .model_dump()
instead.
-"content_draft": self.state.content_draft.dict() if self.state.content_draft else {},
+"content_draft": self.state.content_draft.model_dump() if self.state.content_draft else {},
📝 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.
"content_draft": self.state.content_draft.dict() if self.state.content_draft else {}, | |
"content_draft": self.state.content_draft.model_dump() if self.state.content_draft else {}, |
🤖 Prompt for AI Agents
In ai_news_generator/src/ai_news_flow/main.py at line 120, replace the
deprecated Pydantic method call .dict() with the new .model_dump() method on
self.state.content_draft. This means changing self.state.content_draft.dict() to
self.state.content_draft.model_dump() to comply with Pydantic v2 standards.
"""Convenience function to run the complete news generation flow.""" | ||
flow = NewsGeneratorFlow(topic=topic, temperature=temperature, max_sources=max_sources) | ||
result = flow.kickoff() | ||
return flow |
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 variable or restructure the function
The result
variable is assigned but never used. Either remove it or return the result if that was the intention.
Option 1 - Remove unused variable:
def kickoff(topic: str, temperature: float = 0.7, max_sources: int = 10):
"""Convenience function to run the complete news generation flow."""
flow = NewsGeneratorFlow(topic=topic, temperature=temperature, max_sources=max_sources)
- result = flow.kickoff()
+ flow.kickoff()
return flow
Option 2 - Return the result instead:
def kickoff(topic: str, temperature: float = 0.7, max_sources: int = 10):
"""Convenience function to run the complete news generation flow."""
flow = NewsGeneratorFlow(topic=topic, temperature=temperature, max_sources=max_sources)
result = flow.kickoff()
- return flow
+ return result
📝 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.
"""Convenience function to run the complete news generation flow.""" | |
flow = NewsGeneratorFlow(topic=topic, temperature=temperature, max_sources=max_sources) | |
result = flow.kickoff() | |
return flow | |
def kickoff(topic: str, temperature: float = 0.7, max_sources: int = 10): | |
"""Convenience function to run the complete news generation flow.""" | |
flow = NewsGeneratorFlow(topic=topic, temperature=temperature, max_sources=max_sources) | |
flow.kickoff() | |
return flow |
"""Convenience function to run the complete news generation flow.""" | |
flow = NewsGeneratorFlow(topic=topic, temperature=temperature, max_sources=max_sources) | |
result = flow.kickoff() | |
return flow | |
def kickoff(topic: str, temperature: float = 0.7, max_sources: int = 10): | |
"""Convenience function to run the complete news generation flow.""" | |
flow = NewsGeneratorFlow(topic=topic, temperature=temperature, max_sources=max_sources) | |
result = flow.kickoff() | |
return result |
🧰 Tools
🪛 Ruff (0.12.2)
271-271: Local variable result
is assigned to but never used
Remove assignment to unused variable result
(F841)
🤖 Prompt for AI Agents
In ai_news_generator/src/ai_news_flow/main.py around lines 269 to 272, the
variable 'result' is assigned the output of flow.kickoff() but never used. To
fix this, either remove the assignment to 'result' if it is unnecessary, or if
the intention was to return the result of kickoff(), change the return statement
to return 'result' instead of 'flow'.
generation_completed: bool = False | ||
|
||
# Metadata | ||
start_time: datetime = datetime.now() |
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.
Fix datetime default value - it's evaluated at class definition time
Using datetime.now()
as a default value is evaluated once when the class is defined, not when instances are created. All instances will share the same timestamp.
Use a factory function instead:
+from pydantic import Field
+
class NewsGeneratorState(BaseModel):
topic: str = ""
temperature: float = 0.7
max_sources: int = 10
# ... other fields ...
# Metadata
- start_time: datetime = datetime.now()
+ start_time: datetime = Field(default_factory=datetime.now)
end_time: Optional[datetime] = None
processing_duration: Optional[float] = None
📝 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.
start_time: datetime = datetime.now() | |
from pydantic import Field | |
class NewsGeneratorState(BaseModel): | |
topic: str = "" | |
temperature: float = 0.7 | |
max_sources: int = 10 | |
# ... other fields ... | |
# Metadata | |
start_time: datetime = Field(default_factory=datetime.now) | |
end_time: Optional[datetime] = None | |
processing_duration: Optional[float] = None |
🤖 Prompt for AI Agents
In ai_news_generator/src/ai_news_flow/models.py at line 66, the default value
for start_time is set using datetime.now(), which is evaluated once at class
definition and shared across instances. To fix this, replace the default value
with a factory function such as using field(default_factory=datetime.now) if
using dataclasses, or set the default in __post_init__ or the constructor to
ensure a fresh timestamp is generated for each instance.
import requests | ||
from datetime import datetime |
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 imports
The requests
and datetime
imports are not used anywhere in the code.
-import requests
-from datetime import datetime
📝 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 requests | |
from datetime import datetime |
🧰 Tools
🪛 Ruff (0.12.2)
20-20: requests
imported but unused
Remove unused import: requests
(F401)
21-21: datetime.datetime
imported but unused
Remove unused import: datetime.datetime
(F401)
🤖 Prompt for AI Agents
In ai_news_generator/src/ai_news_flow/tools/custom_tools.py around lines 20 to
21, the imports for 'requests' and 'datetime' are not used anywhere in the code.
Remove these two import statements to clean up the code and avoid unnecessary
dependencies.
domain = source_url.split('//')[1].split('/')[0] if '//' in source_url else source_url.split('/')[0] | ||
domain = domain.replace('www.', '') |
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.
Add error handling for URL parsing
The current URL parsing logic can fail with an IndexError for malformed URLs or empty strings.
-domain = source_url.split('//')[1].split('/')[0] if '//' in source_url else source_url.split('/')[0]
-domain = domain.replace('www.', '')
+try:
+ from urllib.parse import urlparse
+ parsed_url = urlparse(source_url)
+ domain = parsed_url.netloc or parsed_url.path.split('/')[0]
+ domain = domain.replace('www.', '')
+except Exception:
+ # Fallback for malformed URLs
+ domain = ""
You'll also need to add the import at the top of the file:
from urllib.parse import urlparse
🤖 Prompt for AI Agents
In ai_news_generator/src/ai_news_flow/tools/custom_tools.py around lines 56 to
57, the current URL parsing logic can raise an IndexError for malformed or empty
URLs. Replace the manual string splitting with the use of urllib.parse.urlparse
to safely extract the domain. Add the import statement "from urllib.parse import
urlparse" at the top of the file. Then, parse the source_url using urlparse,
extract the netloc, and remove the "www." prefix if present, ensuring robust
error handling for invalid URLs.
Summary
This PR transforms the ai_news_generator from a basic 2-agent system into a sophisticated multi-phase agentic workflow powered by CrewAI Flows. The integration introduces a 9-agent system organized across 3 specialized crews, enabling automated news generation with enhanced quality control, source verification, and professional content creation capabilities.
What Changed
Core Architecture:
@start()
and@listen()
decoratorsNew Features:
Technical Implementation:
Files Modified:
ai_news_generator/README.md
- Updated with comprehensive documentationai_news_generator/app.py
- Enhanced Streamlit interface with flow integrationWhy These Changes Matter
For Users:
For the Project:
The integration showcases how CrewAI Flows can orchestrate complex multi-agent workflows while maintaining clean separation of concerns and professional code standards.
Technical Details
Session Information
a59b1c26-2f93-48b7-a63a-231a991494a6
feat/crewai-flow-integration
Xpander Coding Agent • Model: Claude Sonnet 4 • GitHub
Autonomous agents run reliably on xpander.ai
Summary by CodeRabbit
New Features
Documentation
Chores