mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-06 22:58:30 +00:00
Compare commits
1 Commits
alert-auto
...
devin/1762
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
389d68efb4 |
@@ -1122,7 +1122,7 @@ class Crew(FlowTrackable, BaseModel):
|
||||
) -> list[BaseTool]:
|
||||
if self.manager_agent:
|
||||
if task.agent:
|
||||
tools = self._inject_delegation_tools(tools, task.agent, [task.agent])
|
||||
tools = self._inject_delegation_tools(tools, task.agent, self.agents)
|
||||
else:
|
||||
tools = self._inject_delegation_tools(
|
||||
tools, self.manager_agent, self.agents
|
||||
|
||||
@@ -517,4 +517,103 @@ interactions:
|
||||
- req_8a1b3f7a05a8699dfb93ea93be9788f9
|
||||
http_version: HTTP/1.1
|
||||
status_code: 200
|
||||
- request:
|
||||
body: '{"trace_id": "2a3bfdec-b59a-4ab1-8be2-3c07dd2457d9", "execution_type":
|
||||
"crew", "user_identifier": null, "execution_context": {"crew_fingerprint": null,
|
||||
"crew_name": "crew", "flow_name": null, "crewai_version": "1.4.1", "privacy_level":
|
||||
"standard"}, "execution_metadata": {"expected_duration_estimate": 300, "agent_count":
|
||||
0, "task_count": 0, "flow_method_count": 0, "execution_started_at": "2025-11-11T11:04:11.109473+00:00"},
|
||||
"ephemeral_trace_id": "2a3bfdec-b59a-4ab1-8be2-3c07dd2457d9"}'
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '488'
|
||||
Content-Type:
|
||||
- application/json
|
||||
User-Agent:
|
||||
- CrewAI-CLI/1.4.1
|
||||
X-Crewai-Version:
|
||||
- 1.4.1
|
||||
method: POST
|
||||
uri: https://app.crewai.com/crewai_plus/api/v1/tracing/ephemeral/batches
|
||||
response:
|
||||
body:
|
||||
string: '{"id":"ed5f3778-b549-4c32-b7b4-1c43eedb314e","ephemeral_trace_id":"2a3bfdec-b59a-4ab1-8be2-3c07dd2457d9","execution_type":"crew","crew_name":"crew","flow_name":null,"status":"running","duration_ms":null,"crewai_version":"1.4.1","total_events":0,"execution_context":{"crew_fingerprint":null,"crew_name":"crew","flow_name":null,"crewai_version":"1.4.1","privacy_level":"standard"},"created_at":"2025-11-11T11:04:11.451Z","updated_at":"2025-11-11T11:04:11.451Z","access_code":"TRACE-72181a84cb","user_identifier":null}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '515'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Tue, 11 Nov 2025 11:04:11 GMT
|
||||
cache-control:
|
||||
- no-store
|
||||
content-security-policy:
|
||||
- 'default-src ''self'' *.app.crewai.com app.crewai.com; script-src ''self''
|
||||
''unsafe-inline'' *.app.crewai.com app.crewai.com https://cdn.jsdelivr.net/npm/apexcharts
|
||||
https://www.gstatic.com https://run.pstmn.io https://apis.google.com https://apis.google.com/js/api.js
|
||||
https://accounts.google.com https://accounts.google.com/gsi/client https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css.map
|
||||
https://*.google.com https://docs.google.com https://slides.google.com https://js.hs-scripts.com
|
||||
https://js.sentry-cdn.com https://browser.sentry-cdn.com https://www.googletagmanager.com
|
||||
https://js-na1.hs-scripts.com https://js.hubspot.com http://js-na1.hs-scripts.com
|
||||
https://bat.bing.com https://cdn.amplitude.com https://cdn.segment.com https://d1d3n03t5zntha.cloudfront.net/
|
||||
https://descriptusercontent.com https://edge.fullstory.com https://googleads.g.doubleclick.net
|
||||
https://js.hs-analytics.net https://js.hs-banner.com https://js.hsadspixel.net
|
||||
https://js.hscollectedforms.net https://js.usemessages.com https://snap.licdn.com
|
||||
https://static.cloudflareinsights.com https://static.reo.dev https://www.google-analytics.com
|
||||
https://share.descript.com/; style-src ''self'' ''unsafe-inline'' *.app.crewai.com
|
||||
app.crewai.com https://cdn.jsdelivr.net/npm/apexcharts; img-src ''self'' data:
|
||||
*.app.crewai.com app.crewai.com https://zeus.tools.crewai.com https://dashboard.tools.crewai.com
|
||||
https://cdn.jsdelivr.net https://forms.hsforms.com https://track.hubspot.com
|
||||
https://px.ads.linkedin.com https://px4.ads.linkedin.com https://www.google.com
|
||||
https://www.google.com.br; font-src ''self'' data: *.app.crewai.com app.crewai.com;
|
||||
connect-src ''self'' *.app.crewai.com app.crewai.com https://zeus.tools.crewai.com
|
||||
https://connect.useparagon.com/ https://zeus.useparagon.com/* https://*.useparagon.com/*
|
||||
https://run.pstmn.io https://connect.tools.crewai.com/ https://*.sentry.io
|
||||
https://www.google-analytics.com https://edge.fullstory.com https://rs.fullstory.com
|
||||
https://api.hubspot.com https://forms.hscollectedforms.net https://api.hubapi.com
|
||||
https://px.ads.linkedin.com https://px4.ads.linkedin.com https://google.com/pagead/form-data/16713662509
|
||||
https://google.com/ccm/form-data/16713662509 https://www.google.com/ccm/collect
|
||||
https://worker-actionkit.tools.crewai.com https://api.reo.dev; frame-src ''self''
|
||||
*.app.crewai.com app.crewai.com https://connect.useparagon.com/ https://zeus.tools.crewai.com
|
||||
https://zeus.useparagon.com/* https://connect.tools.crewai.com/ https://docs.google.com
|
||||
https://drive.google.com https://slides.google.com https://accounts.google.com
|
||||
https://*.google.com https://app.hubspot.com/ https://td.doubleclick.net https://www.googletagmanager.com/
|
||||
https://www.youtube.com https://share.descript.com'
|
||||
etag:
|
||||
- W/"0108bfa1b1646d9b56d1c8bfafae33c3"
|
||||
expires:
|
||||
- '0'
|
||||
permissions-policy:
|
||||
- camera=(), microphone=(self), geolocation=()
|
||||
pragma:
|
||||
- no-cache
|
||||
referrer-policy:
|
||||
- strict-origin-when-cross-origin
|
||||
strict-transport-security:
|
||||
- max-age=63072000; includeSubDomains
|
||||
vary:
|
||||
- Accept
|
||||
x-content-type-options:
|
||||
- nosniff
|
||||
x-frame-options:
|
||||
- SAMEORIGIN
|
||||
x-permitted-cross-domain-policies:
|
||||
- none
|
||||
x-request-id:
|
||||
- 2bc7f5a5-7082-4864-8f9e-dafe6bff32b5
|
||||
x-runtime:
|
||||
- '0.070395'
|
||||
x-xss-protection:
|
||||
- 1; mode=block
|
||||
status:
|
||||
code: 201
|
||||
message: Created
|
||||
version: 1
|
||||
|
||||
@@ -1864,7 +1864,10 @@ def test_hierarchical_crew_creation_tasks_with_agents(researcher, writer):
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_hierarchical_crew_creation_tasks_with_async_execution(researcher, writer, ceo):
|
||||
"""
|
||||
Tests that async tasks in hierarchical crews are handled correctly with proper delegation tools
|
||||
Tests that async tasks in hierarchical crews are handled correctly with proper delegation tools.
|
||||
|
||||
After fix for issue #3887, the manager should be able to delegate to ALL crew agents,
|
||||
not just the task's assigned agent.
|
||||
"""
|
||||
task = Task(
|
||||
description="Write one amazing paragraph about AI.",
|
||||
@@ -1906,13 +1909,15 @@ def test_hierarchical_crew_creation_tasks_with_async_execution(researcher, write
|
||||
|
||||
# Verify the delegation tools were passed correctly
|
||||
assert len(tools) == 2
|
||||
|
||||
# After fix for issue #3887, manager can delegate to ALL crew agents
|
||||
assert any(
|
||||
"Delegate a specific task to one of the following coworkers: Senior Writer\n"
|
||||
"Delegate a specific task to one of the following coworkers: Senior Writer, Researcher, CEO"
|
||||
in tool.description
|
||||
for tool in tools
|
||||
)
|
||||
assert any(
|
||||
"Ask a specific question to one of the following coworkers: Senior Writer\n"
|
||||
"Ask a specific question to one of the following coworkers: Senior Writer, Researcher, CEO"
|
||||
in tool.description
|
||||
for tool in tools
|
||||
)
|
||||
@@ -4772,3 +4777,186 @@ def test_ensure_exchanged_messages_are_propagated_to_external_memory():
|
||||
assert "Researcher" in messages[0]["content"]
|
||||
assert messages[1]["role"] == "user"
|
||||
assert "Research a topic to teach a kid aged 6 about math" in messages[1]["content"]
|
||||
|
||||
|
||||
def test_hierarchical_manager_can_delegate_to_crew_agents_issue_3887():
|
||||
"""
|
||||
Test that reproduces and fixes issue #3887.
|
||||
|
||||
When using hierarchical process with a custom manager_agent and tasks assigned
|
||||
to that manager, the manager should be able to delegate to all agents in the
|
||||
crew's agents list, not just the task's assigned agent.
|
||||
|
||||
Bug scenario from issue #3887:
|
||||
- Crew has agents=[planner]
|
||||
- manager_agent=coordinator
|
||||
- Task is assigned to coordinator (the manager)
|
||||
- Manager tries to delegate to "planner"
|
||||
- Before fix: Error "coworker mentioned not found, it must be one of the following options: - coordinator"
|
||||
- After fix: Manager can successfully delegate to "planner"
|
||||
"""
|
||||
# Create agents matching the bug report scenario
|
||||
coordinator = Agent(
|
||||
role="Coordinator",
|
||||
goal="Coordinate the team to complete tasks",
|
||||
backstory="You're a coordinator who delegates work to team members.",
|
||||
allow_delegation=True,
|
||||
)
|
||||
|
||||
planner = Agent(
|
||||
role="Planner",
|
||||
goal="Create technical plans",
|
||||
backstory="You're a planner who creates detailed technical plans.",
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
# Create a task assigned to the coordinator (manager agent)
|
||||
task = Task(
|
||||
description="Create a technical plan for the project",
|
||||
expected_output="A detailed technical plan",
|
||||
agent=coordinator,
|
||||
)
|
||||
|
||||
# Create hierarchical crew with custom manager_agent
|
||||
crew = Crew(
|
||||
agents=[planner], # Only planner in crew agents
|
||||
tasks=[task],
|
||||
process=Process.hierarchical,
|
||||
manager_agent=coordinator, # Coordinator is the manager
|
||||
)
|
||||
|
||||
mock_task_output = TaskOutput(
|
||||
description="Mock description",
|
||||
raw="mocked output",
|
||||
agent="mocked agent",
|
||||
messages=[]
|
||||
)
|
||||
task.output = mock_task_output
|
||||
|
||||
with patch.object(
|
||||
Task, "execute_sync", return_value=mock_task_output
|
||||
) as mock_execute_sync:
|
||||
crew.kickoff()
|
||||
|
||||
# Verify execute_sync was called
|
||||
mock_execute_sync.assert_called_once()
|
||||
|
||||
# Get the tools argument from the call
|
||||
_, kwargs = mock_execute_sync.call_args
|
||||
tools = kwargs["tools"]
|
||||
|
||||
# Verify the delegation tools were passed correctly
|
||||
# The manager should be able to delegate to "planner" (from crew.agents)
|
||||
assert len(tools) == 2
|
||||
|
||||
# Check that the delegation tool includes "Planner" as a coworker
|
||||
delegation_tool = next(
|
||||
(tool for tool in tools if "Delegate" in tool.name), None
|
||||
)
|
||||
assert delegation_tool is not None
|
||||
assert "Planner" in delegation_tool.description, (
|
||||
f"Expected 'Planner' in delegation tool description, "
|
||||
f"but got: {delegation_tool.description}"
|
||||
)
|
||||
|
||||
# Verify the delegation tool has the planner agent in its agents list
|
||||
assert hasattr(delegation_tool, "agents")
|
||||
agent_roles = [agent.role for agent in delegation_tool.agents]
|
||||
assert "Planner" in agent_roles, (
|
||||
f"Expected 'Planner' in delegation tool agents, "
|
||||
f"but got: {agent_roles}"
|
||||
)
|
||||
|
||||
# Verify that "Coordinator" is NOT in the coworkers list
|
||||
# (manager should not delegate to itself)
|
||||
assert "Coordinator" not in delegation_tool.description or (
|
||||
"Coordinator" in delegation_tool.description and "Planner" in delegation_tool.description
|
||||
), "Manager should be able to delegate to crew agents"
|
||||
|
||||
|
||||
def test_hierarchical_manager_can_delegate_to_multiple_crew_agents():
|
||||
"""
|
||||
Test that the manager can delegate to multiple crew agents.
|
||||
|
||||
This extends the fix for issue #3887 to ensure it works with multiple agents.
|
||||
"""
|
||||
# Create manager agent
|
||||
manager = Agent(
|
||||
role="Manager",
|
||||
goal="Manage the team",
|
||||
backstory="You're a manager who coordinates team members.",
|
||||
allow_delegation=True,
|
||||
)
|
||||
|
||||
# Create multiple crew agents
|
||||
researcher = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="You're a researcher.",
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
role="Writer",
|
||||
goal="Write content",
|
||||
backstory="You're a writer.",
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
analyst = Agent(
|
||||
role="Analyst",
|
||||
goal="Analyze data",
|
||||
backstory="You're an analyst.",
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
# Create a task assigned to the manager
|
||||
task = Task(
|
||||
description="Coordinate the team to complete the project",
|
||||
expected_output="Project completed",
|
||||
agent=manager,
|
||||
)
|
||||
|
||||
# Create hierarchical crew with multiple agents
|
||||
crew = Crew(
|
||||
agents=[researcher, writer, analyst],
|
||||
tasks=[task],
|
||||
process=Process.hierarchical,
|
||||
manager_agent=manager,
|
||||
)
|
||||
|
||||
mock_task_output = TaskOutput(
|
||||
description="Mock description",
|
||||
raw="mocked output",
|
||||
agent="mocked agent",
|
||||
messages=[]
|
||||
)
|
||||
task.output = mock_task_output
|
||||
|
||||
with patch.object(
|
||||
Task, "execute_sync", return_value=mock_task_output
|
||||
) as mock_execute_sync:
|
||||
crew.kickoff()
|
||||
|
||||
# Get the tools argument from the call
|
||||
_, kwargs = mock_execute_sync.call_args
|
||||
tools = kwargs["tools"]
|
||||
|
||||
# Find the delegation tool
|
||||
delegation_tool = next(
|
||||
(tool for tool in tools if "Delegate" in tool.name), None
|
||||
)
|
||||
assert delegation_tool is not None
|
||||
|
||||
# Verify all crew agents are available for delegation
|
||||
assert hasattr(delegation_tool, "agents")
|
||||
agent_roles = [agent.role for agent in delegation_tool.agents]
|
||||
|
||||
assert "Researcher" in agent_roles
|
||||
assert "Writer" in agent_roles
|
||||
assert "Analyst" in agent_roles
|
||||
|
||||
# Verify all agents are mentioned in the description
|
||||
assert "Researcher" in delegation_tool.description
|
||||
assert "Writer" in delegation_tool.description
|
||||
assert "Analyst" in delegation_tool.description
|
||||
|
||||
Reference in New Issue
Block a user