Fix tool propagation bug in hierarchical crews (#3679)

- Remove check_tools validator from task.py that was extending task.tools
  with agent.tools at creation time
- This caused manager agents in hierarchical crews to incorrectly inherit
  tools from task agents
- The crew.py execution logic already handles tool resolution correctly
  at execution time via fallback: task.tools or agent_to_use.tools or []
- Add reproduction test test_hierarchical_crew_does_not_propagate_agent_tools_to_manager
- Update test_task_tool_reflect_agent_tools to verify execution-time behavior

Fixes #3679

Co-Authored-By: João <joao@crewai.com>
This commit is contained in:
Devin AI
2025-10-09 15:32:45 +00:00
parent cb8bcfe214
commit 01114168df
3 changed files with 46 additions and 8 deletions

View File

@@ -336,12 +336,6 @@ class Task(BaseModel):
setattr(self, key, value)
return self
@model_validator(mode="after")
def check_tools(self):
"""Check if the tools are set."""
if not self.tools and self.agent and self.agent.tools:
self.tools.extend(self.agent.tools)
return self
@model_validator(mode="after")
def check_output(self):

View File

@@ -3814,6 +3814,46 @@ def test_fetch_inputs():
)
def test_hierarchical_crew_does_not_propagate_agent_tools_to_manager():
"""
Test that in hierarchical crews, manager agent doesn't inherit task agents' tools.
This verifies that the check_tools validator doesn't pollute task.tools at creation time.
Fixes issue #3679: https://github.com/crewAIInc/crewAI/issues/3679
"""
from crewai.tools import tool
@tool
def agent_specific_tool() -> str:
"""A tool that should only be available to the specific agent."""
return "agent specific result"
agent_with_tools = Agent(
role="Specialist",
goal="Do specialized work with custom tools",
backstory="You are a specialist with specific tools",
tools=[agent_specific_tool],
allow_delegation=False,
)
# Create a task with an agent that has tools, but don't assign tools to the task
task = Task(
description="Perform a specialized task",
expected_output="Task result",
agent=agent_with_tools,
)
crew = Crew(
agents=[agent_with_tools],
tasks=[task],
process=Process.hierarchical,
manager_llm="gpt-4o",
)
# Verify that task.tools is empty (not populated with agent's tools)
assert task.tools == []
assert len(task.tools) == 0
def test_task_tools_preserve_code_execution_tools():
"""
Test that task tools don't override code execution tools when allow_code_execution=True

View File

@@ -20,11 +20,13 @@ from crewai.utilities.string_utils import interpolate_only
def test_task_tool_reflect_agent_tools():
"""Test that agent tools are available during task execution via crew fallback logic."""
from crewai.tools import tool
@tool
def fake_tool() -> None:
def fake_tool() -> str:
"Fake tool"
return "result"
researcher = Agent(
role="Researcher",
@@ -40,7 +42,9 @@ def test_task_tool_reflect_agent_tools():
agent=researcher,
)
assert task.tools == [fake_tool]
assert task.tools == []
assert researcher.tools == [fake_tool]
def test_task_tool_takes_precedence_over_agent_tools():