mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-09 08:08:32 +00:00
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:
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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():
|
||||
|
||||
Reference in New Issue
Block a user