mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-10 00:28:31 +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)
|
setattr(self, key, value)
|
||||||
return self
|
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")
|
@model_validator(mode="after")
|
||||||
def check_output(self):
|
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():
|
def test_task_tools_preserve_code_execution_tools():
|
||||||
"""
|
"""
|
||||||
Test that task tools don't override code execution tools when allow_code_execution=True
|
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():
|
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
|
from crewai.tools import tool
|
||||||
|
|
||||||
@tool
|
@tool
|
||||||
def fake_tool() -> None:
|
def fake_tool() -> str:
|
||||||
"Fake tool"
|
"Fake tool"
|
||||||
|
return "result"
|
||||||
|
|
||||||
researcher = Agent(
|
researcher = Agent(
|
||||||
role="Researcher",
|
role="Researcher",
|
||||||
@@ -40,7 +42,9 @@ def test_task_tool_reflect_agent_tools():
|
|||||||
agent=researcher,
|
agent=researcher,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert task.tools == [fake_tool]
|
assert task.tools == []
|
||||||
|
|
||||||
|
assert researcher.tools == [fake_tool]
|
||||||
|
|
||||||
|
|
||||||
def test_task_tool_takes_precedence_over_agent_tools():
|
def test_task_tool_takes_precedence_over_agent_tools():
|
||||||
|
|||||||
Reference in New Issue
Block a user