Fix: Set crew attribute on planning agent to prevent EventBus errors

- Added crew parameter to CrewPlanner.__init__() to accept crew reference
- Modified _create_planning_agent() to set crew attribute on planning agent
- Updated Crew._handle_crew_planning() to pass crew reference to CrewPlanner
- Added test to verify planning agent has crew attribute set
- Renamed test class from InternalCrewPlanner to TestCrewPlanner for pytest compatibility

Fixes #3782

Co-Authored-By: João <joao@crewai.com>
This commit is contained in:
Devin AI
2025-10-23 09:59:40 +00:00
parent 9728388ea7
commit edfbec4740
3 changed files with 35 additions and 4 deletions

View File

@@ -779,7 +779,7 @@ class Crew(FlowTrackable, BaseModel):
"""Handles the Crew planning.""" """Handles the Crew planning."""
self._logger.log("info", "Planning the crew execution") self._logger.log("info", "Planning the crew execution")
result = CrewPlanner( result = CrewPlanner(
tasks=self.tasks, planning_agent_llm=self.planning_llm tasks=self.tasks, planning_agent_llm=self.planning_llm, crew=self
)._handle_crew_planning() )._handle_crew_planning()
for task, step_plan in zip( for task, step_plan in zip(

View File

@@ -37,19 +37,25 @@ class CrewPlanner:
Attributes: Attributes:
tasks: List of tasks to be planned. tasks: List of tasks to be planned.
planning_agent_llm: Optional LLM model for the planning agent. planning_agent_llm: Optional LLM model for the planning agent.
crew: Optional reference to the crew instance.
""" """
def __init__( def __init__(
self, tasks: list[Task], planning_agent_llm: str | BaseLLM | None = None self,
tasks: list[Task],
planning_agent_llm: str | BaseLLM | None = None,
crew: "Any" = None,
) -> None: ) -> None:
"""Initialize CrewPlanner with tasks and optional planning agent LLM. """Initialize CrewPlanner with tasks and optional planning agent LLM.
Args: Args:
tasks: List of tasks to be planned. tasks: List of tasks to be planned.
planning_agent_llm: Optional LLM model for the planning agent. Defaults to None. planning_agent_llm: Optional LLM model for the planning agent. Defaults to None.
crew: Optional reference to the crew instance. Defaults to None.
""" """
self.tasks = tasks self.tasks = tasks
self.planning_agent_llm = planning_agent_llm or "gpt-4o-mini" self.planning_agent_llm = planning_agent_llm or "gpt-4o-mini"
self.crew = crew
def _handle_crew_planning(self) -> PlannerTaskPydanticOutput: def _handle_crew_planning(self) -> PlannerTaskPydanticOutput:
"""Handles the Crew planning by creating detailed step-by-step plans for each task. """Handles the Crew planning by creating detailed step-by-step plans for each task.
@@ -80,7 +86,7 @@ class CrewPlanner:
Returns: Returns:
An Agent instance configured for planning tasks. An Agent instance configured for planning tasks.
""" """
return Agent( planning_agent = Agent(
role="Task Execution Planner", role="Task Execution Planner",
goal=( goal=(
"Your goal is to create an extremely detailed, step-by-step plan based on the tasks and tools " "Your goal is to create an extremely detailed, step-by-step plan based on the tasks and tools "
@@ -89,6 +95,9 @@ class CrewPlanner:
backstory="Planner agent for crew planning", backstory="Planner agent for crew planning",
llm=self.planning_agent_llm, llm=self.planning_agent_llm,
) )
if self.crew:
planning_agent.crew = self.crew
return planning_agent
@staticmethod @staticmethod
def _create_planner_task(planning_agent: Agent, tasks_summary: str) -> Task: def _create_planner_task(planning_agent: Agent, tasks_summary: str) -> Task:

View File

@@ -13,7 +13,7 @@ from crewai.utilities.planning_handler import (
) )
class InternalCrewPlanner: class TestCrewPlanner:
@pytest.fixture @pytest.fixture
def crew_planner(self): def crew_planner(self):
tasks = [ tasks = [
@@ -177,3 +177,25 @@ class InternalCrewPlanner:
crew_planner_different_llm.tasks crew_planner_different_llm.tasks
) )
execute.assert_called_once() execute.assert_called_once()
def test_planning_agent_has_crew_attribute(self):
"""Test that planning agent has crew attribute set to avoid EventBus errors."""
from crewai.crew import Crew
# Create a crew with planning enabled
agent = Agent(role="Test Agent", goal="Test Goal", backstory="Test Backstory")
task = Task(
description="Test task",
expected_output="Test output",
agent=agent,
)
crew = Crew(agents=[agent], tasks=[task], planning=True)
planner = CrewPlanner(tasks=[task], planning_agent_llm="gpt-4o-mini", crew=crew)
planning_agent = planner._create_planning_agent()
# Verify the planning agent has crew attribute set
assert planning_agent.crew is not None
assert planning_agent.crew == crew
# Verify that accessing agent.crew.key doesn't raise an error
assert planning_agent.crew.key is not None