Skip to content

Conversation

xpander-ai-coding-agent
Copy link

@xpander-ai-coding-agent xpander-ai-coding-agent commented Aug 6, 2025

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:

  • Implemented CrewAI Flow orchestration with @start() and @listen() decorators
  • Added 4-phase workflow execution: Research → Content Creation → Editing → Finalization
  • Integrated 9 specialized agents across 3 crews (Research, Content, Editing)

New Features:

  • Real-time workflow progress tracking with Pydantic state management
  • Source credibility assessment and fact-checking tools
  • Readability analysis and scoring system
  • Enhanced Streamlit UI with professional design
  • Downloadable outputs (articles + processing summaries)
  • Comprehensive quality metrics and analytics

Technical Implementation:

  • YAML-based configuration system for agents and tasks
  • Custom tools for credibility checking and readability analysis
  • Modular crew architecture with specialized responsibilities
  • Modern dependency management via pyproject.toml

Files Modified:

  • ai_news_generator/README.md - Updated with comprehensive documentation
  • ai_news_generator/app.py - Enhanced Streamlit interface with flow integration

Why These Changes Matter

For Users:

  • Significantly improved content quality through multi-phase validation
  • Enhanced source verification and fact-checking capabilities
  • Professional-grade articles with SEO optimization and readability scoring
  • Intuitive progress tracking and comprehensive output analytics

For the Project:

  • Establishes a scalable, production-ready agentic workflow architecture
  • Demonstrates CrewAI Flow best practices for complex multi-agent systems
  • Provides a reference implementation for automated content creation
  • Enables future expansion with additional specialized agents and crews

The integration showcases how CrewAI Flows can orchestrate complex multi-agent workflows while maintaining clean separation of concerns and professional code standards.

Technical Details

  • Total files changed: 2
  • Lines added: 515
  • Lines removed: 145

Session Information

  • Session ID: a59b1c26-2f93-48b7-a63a-231a991494a6
  • Branch: feat/crewai-flow-integration
  • Timestamp: 2025-08-06 20:26:31 UTC

xpander.ai
Xpander Coding Agent • Model: Claude Sonnet 4 • GitHub
Autonomous agents run reliably on xpander.ai

Summary by CodeRabbit

  • New Features

    • Introduced a multi-phase, multi-agent workflow for AI-powered news generation, including dedicated research, content creation, and editing teams.
    • Added advanced quality metrics (source credibility, readability, processing time, word count) and real-time progress tracking in the user interface.
    • Enhanced Streamlit UI with improved controls, workflow visualization, and detailed output downloads.
  • Documentation

    • Completely overhauled and expanded the README with comprehensive setup, usage, architecture, and troubleshooting guidance.
    • Added detailed integration and workflow documentation.
  • Chores

    • Added configuration files for dependencies, agent/task definitions, and project structure validation scripts.
    • Introduced automated tests to verify project structure and integration correctness.

Copy link
Contributor

coderabbitai bot commented Aug 6, 2025

Walkthrough

This 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

Cohort / File(s) Change Summary
CrewAI Flow Orchestration & State Models
src/ai_news_flow/main.py, src/ai_news_flow/models.py
Introduces the main flow orchestrator class (NewsGeneratorFlow) coordinating all workflow phases, and Pydantic models for state, articles, and intermediate results.
Custom Tools
src/ai_news_flow/tools/custom_tools.py
Adds custom tools for source credibility, readability analysis, and enhanced search, with Pydantic input models and fallback stubs for external dependencies.
Research Crew
src/ai_news_flow/crews/research_crew/research_crew.py, .../config/agents.yaml, .../config/tasks.yaml
Implements the research crew with three agents and tasks, using YAML for configuration and integrating custom tools for research and fact-checking.
Content Crew
src/ai_news_flow/crews/content_crew/content_crew.py, .../config/agents.yaml, .../config/tasks.yaml
Implements the content crew with strategist, writer, and SEO specialist agents, and corresponding tasks, all configured via YAML files.
Editing Crew
src/ai_news_flow/crews/editing_crew/editing_crew.py, .../config/agents.yaml, .../config/tasks.yaml
Implements the editing crew with copy, technical, and publishing editors, and sequential editing tasks, all configured via YAML.
Streamlit UI & Integration
app.py
Refactors the UI to use the new flow, adds progress tracking, error handling, session management, and improved controls for user input and API key validation.
Project Documentation
README.md, CREWAI_FLOW_INTEGRATION_SUMMARY.md
Rewrites and expands documentation to detail the new architecture, features, setup, and workflow.
Testing & Validation
test_structure.py
Adds a test script verifying model imports, directory structure, config files, and Streamlit app integration.
Project Configuration
pyproject.toml
Introduces Poetry-based project configuration, dependency management, CLI entry point, and formatting tool settings.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • AI News generator app #10: Introduces the initial Streamlit app and basic two-agent Crew setup, which this PR refactors and extends into the new modular CrewAI Flow architecture.

Poem

In a warren of code, nine agents convene,
Research, write, and edit—each crew on the scene.
With YAML and models, the flow now takes flight,
Progress bars hopping from morning to night.
Rabbits rejoice—news is crafted anew,
Modular, readable, and SEO too!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 that self.agents and self.tasks are properly initialized

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

  1. Multiple lines have trailing spaces
  2. 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:

  1. Multiple lines have trailing spaces
  2. 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:

  1. Multiple lines have trailing spaces
  2. 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 models

The function imports ResearchReport, ContentDraft, and EditedContent but only tests instantiation of NewsGeneratorState and NewsArticle. 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 issues

The 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 accuracy

The 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 code

The EnhancedSearchTool class currently doesn't add any functionality beyond the parent SerperDevTool 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 issues

Remove 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 block

The fenced code block should specify a language for proper syntax highlighting.

-```
+```text
ai_news_generator/

236-236: Use proper heading instead of emphasis

Using 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 R7B
ai_news_generator/src/ai_news_flow/crews/research_crew/config/tasks.yaml (1)

9-9: Fix YAML formatting issues

Remove 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 placement

Importing 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 validation

The 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 block

The 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 discoverability
ai_news_generator/src/ai_news_flow/main.py (2)

2-5: Remove unused imports

The 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 configurable

The 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

📥 Commits

Reviewing files that changed from the base of the PR and between 67aa2f3 and 9acc0df.

⛔ 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: Confirm self.agents and self.tasks initialization
Although each crew class sets agents_config and tasks_config, the @CrewBase decorator (from the external crewai.project package) must populate self.agents and self.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–78

    agents=self.agents,
    tasks=self.tasks,

Please verify—via the crewai documentation or by inspecting a crew instance—that CrewBase reads the YAML configs and assigns the corresponding agents and tasks 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 content

The 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 0

Likely 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Suggested change
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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Suggested change
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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Suggested change
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Suggested change
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.

Comment on lines +12 to +28
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
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Suggested change
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 {},
Copy link
Contributor

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.

Suggested change
"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.

Comment on lines +269 to +272
"""Convenience function to run the complete news generation flow."""
flow = NewsGeneratorFlow(topic=topic, temperature=temperature, max_sources=max_sources)
result = flow.kickoff()
return flow
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Suggested change
"""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
Suggested change
"""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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Suggested change
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.

Comment on lines +20 to +21
import requests
from datetime import datetime
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Suggested change
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.

Comment on lines +56 to +57
domain = source_url.split('//')[1].split('/')[0] if '//' in source_url else source_url.split('/')[0]
domain = domain.replace('www.', '')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant