mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-11 00:58:30 +00:00
Fix: Update delegation tool handling in hierarchical mode for proper agent recognition
Co-Authored-By: Joe Moura <joao@crewai.com>
This commit is contained in:
@@ -232,7 +232,7 @@ class BaseAgent(ABC, BaseModel):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_delegation_tools(self, agents: List["BaseAgent"]) -> List[BaseTool]:
|
def get_delegation_tools(self, agents: List["BaseAgent"], task=None) -> List[BaseTool]:
|
||||||
"""Set the task tools that init BaseAgenTools class."""
|
"""Set the task tools that init BaseAgenTools class."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -798,6 +798,16 @@ class Crew(BaseModel):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def _prepare_tools(self, agent: BaseAgent, task: Task, tools: List[Tool]) -> List[Tool]:
|
def _prepare_tools(self, agent: BaseAgent, task: Task, tools: List[Tool]) -> List[Tool]:
|
||||||
|
"""Prepare tools for an agent, including delegation tools if allowed.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent: Agent that will receive the tools
|
||||||
|
task: Task being executed
|
||||||
|
tools: List of existing tools
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of tools with delegation and other tools added
|
||||||
|
"""
|
||||||
# Add delegation tools if agent allows delegation
|
# Add delegation tools if agent allows delegation
|
||||||
if agent.allow_delegation:
|
if agent.allow_delegation:
|
||||||
if self.process == Process.hierarchical:
|
if self.process == Process.hierarchical:
|
||||||
@@ -805,15 +815,14 @@ class Crew(BaseModel):
|
|||||||
# For hierarchical process, handle both manager and regular agent tools
|
# For hierarchical process, handle both manager and regular agent tools
|
||||||
if agent == self.manager_agent:
|
if agent == self.manager_agent:
|
||||||
# Manager can delegate to all regular agents
|
# Manager can delegate to all regular agents
|
||||||
tools = self._inject_delegation_tools(tools, agent, [a for a in self.agents if a != agent])
|
tools = self._inject_delegation_tools(tools, agent, [a for a in self.agents if a != agent], task=task)
|
||||||
|
elif task and task.async_execution and task.agent:
|
||||||
|
# For async tasks in hierarchical mode, only allow delegation to the task's assigned agent
|
||||||
|
tools = self._inject_delegation_tools(tools, agent, [task.agent], task=task)
|
||||||
else:
|
else:
|
||||||
# For async tasks, maintain original delegation behavior
|
# Regular agents can delegate to manager and other agents
|
||||||
if task and task.async_execution:
|
delegation_agents = [self.manager_agent] + [a for a in self.agents if a != agent]
|
||||||
tools = self._add_delegation_tools(task, tools)
|
tools = self._inject_delegation_tools(tools, agent, delegation_agents, task=task)
|
||||||
else:
|
|
||||||
# Regular agents can delegate to manager and other agents
|
|
||||||
delegation_agents = [self.manager_agent] + [a for a in self.agents if a != agent]
|
|
||||||
tools = self._inject_delegation_tools(tools, agent, delegation_agents)
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("Manager agent is required for hierarchical process.")
|
raise ValueError("Manager agent is required for hierarchical process.")
|
||||||
else:
|
else:
|
||||||
@@ -849,8 +858,19 @@ class Crew(BaseModel):
|
|||||||
|
|
||||||
return tools
|
return tools
|
||||||
|
|
||||||
def _inject_delegation_tools(self, tools: List[Tool], task_agent: BaseAgent, agents: List[BaseAgent]):
|
def _inject_delegation_tools(self, tools: List[Tool], task_agent: BaseAgent, agents: List[BaseAgent], task=None):
|
||||||
delegation_tools = task_agent.get_delegation_tools(agents)
|
"""Inject delegation tools for the given agent.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tools: List of existing tools
|
||||||
|
task_agent: Agent that will receive the delegation tools
|
||||||
|
agents: List of agents that can be delegated to
|
||||||
|
task: Optional task context for delegation
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of tools with delegation tools added
|
||||||
|
"""
|
||||||
|
delegation_tools = task_agent.get_delegation_tools(agents, task=task)
|
||||||
return self._merge_tools(tools, delegation_tools)
|
return self._merge_tools(tools, delegation_tools)
|
||||||
|
|
||||||
def _add_multimodal_tools(self, agent: BaseAgent, tools: List[Tool]):
|
def _add_multimodal_tools(self, agent: BaseAgent, tools: List[Tool]):
|
||||||
@@ -887,9 +907,9 @@ class Crew(BaseModel):
|
|||||||
def _update_manager_tools(self, task: Task, tools: List[Tool]):
|
def _update_manager_tools(self, task: Task, tools: List[Tool]):
|
||||||
if self.manager_agent:
|
if self.manager_agent:
|
||||||
if task.agent:
|
if task.agent:
|
||||||
# For async tasks, maintain original delegation behavior
|
# In hierarchical mode with async execution, only allow delegation to the task's assigned agent
|
||||||
if task.async_execution:
|
if task.async_execution and self.process == Process.hierarchical:
|
||||||
tools = self._add_delegation_tools(task, tools)
|
tools = self._inject_delegation_tools(tools, task.agent, [task.agent] if task.agent else [])
|
||||||
else:
|
else:
|
||||||
# In hierarchical mode, allow bidirectional delegation
|
# In hierarchical mode, allow bidirectional delegation
|
||||||
if self.process == Process.hierarchical:
|
if self.process == Process.hierarchical:
|
||||||
@@ -900,10 +920,10 @@ class Crew(BaseModel):
|
|||||||
else:
|
else:
|
||||||
# For manager, allow delegation to all agents
|
# For manager, allow delegation to all agents
|
||||||
tools = self._inject_delegation_tools(tools, task.agent, [a for a in self.agents if a != task.agent])
|
tools = self._inject_delegation_tools(tools, task.agent, [a for a in self.agents if a != task.agent])
|
||||||
else:
|
else:
|
||||||
tools = self._inject_delegation_tools(tools, task.agent, self.agents)
|
tools = self._inject_delegation_tools(tools, task.agent, self.agents, task=task)
|
||||||
else:
|
else:
|
||||||
tools = self._inject_delegation_tools(tools, self.manager_agent, self.agents)
|
tools = self._inject_delegation_tools(tools, self.manager_agent, self.agents, task=task)
|
||||||
return tools
|
return tools
|
||||||
|
|
||||||
def _get_context(self, task: Task, task_outputs: List[TaskOutput]):
|
def _get_context(self, task: Task, task_outputs: List[TaskOutput]):
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ writer = Agent(
|
|||||||
role="Senior Writer",
|
role="Senior Writer",
|
||||||
goal="Write the best content about AI and AI agents.",
|
goal="Write the best content about AI and AI agents.",
|
||||||
backstory="You're a senior writer, specialized in technology, software engineering, AI and startups. You work as a freelancer and are now working on writing content for a new customer.",
|
backstory="You're a senior writer, specialized in technology, software engineering, AI and startups. You work as a freelancer and are now working on writing content for a new customer.",
|
||||||
allow_delegation=False,
|
allow_delegation=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import pytest
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
import pytest
|
|
||||||
from langchain_core.language_models.base import BaseLanguageModel
|
from langchain_core.language_models.base import BaseLanguageModel
|
||||||
|
|
||||||
from crewai import Agent, Crew, Process, Task
|
from crewai import Agent, Crew, Process, Task
|
||||||
|
|||||||
Reference in New Issue
Block a user