From 52e0a84829a0503ea09f87c3cf35c77cf7f3fc10 Mon Sep 17 00:00:00 2001 From: Vidit-Ostwal Date: Mon, 3 Mar 2025 20:57:41 +0530 Subject: [PATCH 1/6] Added .copy for manager agent and shallow copy for manager llm --- src/crewai/crew.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/crewai/crew.py b/src/crewai/crew.py index 9cecfed3a..c3acf4a80 100644 --- a/src/crewai/crew.py +++ b/src/crewai/crew.py @@ -1111,13 +1111,19 @@ class Crew(BaseModel): "_short_term_memory", "_long_term_memory", "_entity_memory", + "_telemetry", "agents", "tasks", "knowledge_sources", "knowledge", + "manager_agent", + "manager_llm", + } cloned_agents = [agent.copy() for agent in self.agents] + manager_agent = self.manager_agent.copy() if self.manager_agent else None + manager_llm = shallow_copy(self.manager_llm) if self.manager_llm else None task_mapping = {} @@ -1150,10 +1156,14 @@ class Crew(BaseModel): tasks=cloned_tasks, knowledge_sources=existing_knowledge_sources, knowledge=existing_knowledge, + manager_agent=manager_agent, + manager_llm=manager_llm, ) return copied_crew + + def _set_tasks_callbacks(self) -> None: """Sets callback for every task suing task_callback""" for task in self.tasks: From cf1864ce0fd02204f04c15e283e1b995a8b1acd4 Mon Sep 17 00:00:00 2001 From: Vidit-Ostwal Date: Mon, 3 Mar 2025 21:12:21 +0530 Subject: [PATCH 2/6] Added docstring --- src/crewai/crew.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/crewai/crew.py b/src/crewai/crew.py index c3acf4a80..b19eea20c 100644 --- a/src/crewai/crew.py +++ b/src/crewai/crew.py @@ -1099,7 +1099,16 @@ class Crew(BaseModel): return required_inputs def copy(self): - """Create a deep copy of the Crew.""" + """ + Creates a deep copy of the Crew instance. + + Handles copying of: + - Basic attributes + - Manager agent and LLM configurations + + Returns: + Crew: A new instance with copied components + """ exclude = { "id", From 1e49d1b5928c865670dafca7f4784d07f3c744ac Mon Sep 17 00:00:00 2001 From: Vidit-Ostwal Date: Thu, 20 Mar 2025 22:47:46 +0530 Subject: [PATCH 3/6] Fixed doc string of copy function --- src/crewai/crew.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/crewai/crew.py b/src/crewai/crew.py index 8fb56452a..57b3f07c3 100644 --- a/src/crewai/crew.py +++ b/src/crewai/crew.py @@ -1122,11 +1122,7 @@ class Crew(BaseModel): def copy(self): """ Creates a deep copy of the Crew instance. - - Handles copying of: - - Basic attributes - - Manager agent and LLM configurations - + Returns: Crew: A new instance with copied components """ From 6145331ee48ecff2e4c735dffea5c02f96f6e190 Mon Sep 17 00:00:00 2001 From: Vidit-Ostwal Date: Thu, 27 Mar 2025 00:12:38 +0530 Subject: [PATCH 4/6] Added test cases mentioned in the issue --- src/crewai/crew.py | 2 -- tests/crew_test.py | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/crewai/crew.py b/src/crewai/crew.py index 78429468b..0f6db8c4a 100644 --- a/src/crewai/crew.py +++ b/src/crewai/crew.py @@ -1224,8 +1224,6 @@ class Crew(BaseModel): return copied_crew - - def _set_tasks_callbacks(self) -> None: """Sets callback for every task suing task_callback""" for task in self.tasks: diff --git a/tests/crew_test.py b/tests/crew_test.py index 39a3e9a08..bc137a214 100644 --- a/tests/crew_test.py +++ b/tests/crew_test.py @@ -11,7 +11,9 @@ import pydantic_core import pytest from crewai.agent import Agent +from crewai.agents import CacheHandler from crewai.agents.cache import CacheHandler +from crewai.agents.crew_agent_executor import CrewAgentExecutor from crewai.crew import Crew from crewai.crews.crew_output import CrewOutput from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource @@ -4025,3 +4027,52 @@ def test_crew_with_knowledge_sources_works_with_copy(): assert len(crew_copy.tasks) == len(crew.tasks) assert len(crew_copy.tasks) == len(crew.tasks) + + +def test_crew_kickoff_for_each_works_with_manager_agent_copy(): + researcher = Agent( + role="Researcher", + goal="Conduct thorough research and analysis on AI and AI agents", + backstory="You're an expert researcher, specialized in technology, software engineering, AI, and startups. You work as a freelancer and are currently researching for a new client.", + allow_delegation=False + ) + + writer = Agent( + role="Senior Writer", + goal="Create compelling 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 currently writing content for a new client.", + allow_delegation=False + ) + + # Define task + task = Task( + description="Generate a list of 5 interesting ideas for an article, then write one captivating paragraph for each idea that showcases the potential of a full article on this topic. Return the list of ideas with their paragraphs and your notes.", + expected_output="5 bullet points, each with a paragraph and accompanying notes.", + ) + + # Define manager agent + manager = Agent( + role="Project Manager", + goal="Efficiently manage the crew and ensure high-quality task completion", + backstory="You're an experienced project manager, skilled in overseeing complex projects and guiding teams to success. Your role is to coordinate the efforts of the crew members, ensuring that each task is completed on time and to the highest standard.", + allow_delegation=True + ) + + # Instantiate crew with a custom manager + crew = Crew( + agents=[researcher, writer], + tasks=[task], + manager_agent=manager, + process=Process.hierarchical, + verbose=True + ) + + crew_copy = crew.copy() + assert crew_copy.manager_agent is not None + assert crew_copy.manager_agent.id != crew.manager_agent.id + assert crew_copy.manager_agent.role == crew.manager_agent.role + assert crew_copy.manager_agent.goal == crew.manager_agent.goal + assert crew_copy.manager_agent.backstory == crew.manager_agent.backstory + assert isinstance(crew_copy.manager_agent.agent_executor, CrewAgentExecutor) + assert isinstance(crew_copy.manager_agent.cache_handler, CacheHandler) + From af7983be43d34685d18a974c9df673880a32f587 Mon Sep 17 00:00:00 2001 From: Vidit-Ostwal Date: Thu, 27 Mar 2025 08:12:47 +0530 Subject: [PATCH 5/6] Fixed Intent --- tests/crew_test.py | 48 +++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/crew_test.py b/tests/crew_test.py index 694be09f4..43cb9f6ea 100644 --- a/tests/crew_test.py +++ b/tests/crew_test.py @@ -4069,41 +4069,41 @@ def test_crew_with_knowledge_sources_works_with_copy(): def test_crew_kickoff_for_each_works_with_manager_agent_copy(): researcher = Agent( - role="Researcher", - goal="Conduct thorough research and analysis on AI and AI agents", - backstory="You're an expert researcher, specialized in technology, software engineering, AI, and startups. You work as a freelancer and are currently researching for a new client.", - allow_delegation=False - ) + role="Researcher", + goal="Conduct thorough research and analysis on AI and AI agents", + backstory="You're an expert researcher, specialized in technology, software engineering, AI, and startups. You work as a freelancer and are currently researching for a new client.", + allow_delegation=False + ) writer = Agent( - role="Senior Writer", - goal="Create compelling 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 currently writing content for a new client.", - allow_delegation=False - ) + role="Senior Writer", + goal="Create compelling 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 currently writing content for a new client.", + allow_delegation=False + ) # Define task task = Task( - description="Generate a list of 5 interesting ideas for an article, then write one captivating paragraph for each idea that showcases the potential of a full article on this topic. Return the list of ideas with their paragraphs and your notes.", - expected_output="5 bullet points, each with a paragraph and accompanying notes.", - ) + description="Generate a list of 5 interesting ideas for an article, then write one captivating paragraph for each idea that showcases the potential of a full article on this topic. Return the list of ideas with their paragraphs and your notes.", + expected_output="5 bullet points, each with a paragraph and accompanying notes.", + ) # Define manager agent manager = Agent( - role="Project Manager", - goal="Efficiently manage the crew and ensure high-quality task completion", - backstory="You're an experienced project manager, skilled in overseeing complex projects and guiding teams to success. Your role is to coordinate the efforts of the crew members, ensuring that each task is completed on time and to the highest standard.", - allow_delegation=True - ) + role="Project Manager", + goal="Efficiently manage the crew and ensure high-quality task completion", + backstory="You're an experienced project manager, skilled in overseeing complex projects and guiding teams to success. Your role is to coordinate the efforts of the crew members, ensuring that each task is completed on time and to the highest standard.", + allow_delegation=True + ) # Instantiate crew with a custom manager crew = Crew( - agents=[researcher, writer], - tasks=[task], - manager_agent=manager, - process=Process.hierarchical, - verbose=True - ) + agents=[researcher, writer], + tasks=[task], + manager_agent=manager, + process=Process.hierarchical, + verbose=True + ) crew_copy = crew.copy() assert crew_copy.manager_agent is not None From 02f790ffcbc4e0d48e67d711b67415e71e841810 Mon Sep 17 00:00:00 2001 From: Vidit-Ostwal Date: Thu, 27 Mar 2025 08:14:07 +0530 Subject: [PATCH 6/6] Fixed Intent --- tests/crew_test.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/crew_test.py b/tests/crew_test.py index 43cb9f6ea..402e82d9b 100644 --- a/tests/crew_test.py +++ b/tests/crew_test.py @@ -4073,20 +4073,20 @@ def test_crew_kickoff_for_each_works_with_manager_agent_copy(): goal="Conduct thorough research and analysis on AI and AI agents", backstory="You're an expert researcher, specialized in technology, software engineering, AI, and startups. You work as a freelancer and are currently researching for a new client.", allow_delegation=False - ) + ) writer = Agent( role="Senior Writer", goal="Create compelling 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 currently writing content for a new client.", allow_delegation=False - ) + ) # Define task task = Task( description="Generate a list of 5 interesting ideas for an article, then write one captivating paragraph for each idea that showcases the potential of a full article on this topic. Return the list of ideas with their paragraphs and your notes.", expected_output="5 bullet points, each with a paragraph and accompanying notes.", - ) + ) # Define manager agent manager = Agent( @@ -4094,7 +4094,7 @@ def test_crew_kickoff_for_each_works_with_manager_agent_copy(): goal="Efficiently manage the crew and ensure high-quality task completion", backstory="You're an experienced project manager, skilled in overseeing complex projects and guiding teams to success. Your role is to coordinate the efforts of the crew members, ensuring that each task is completed on time and to the highest standard.", allow_delegation=True - ) + ) # Instantiate crew with a custom manager crew = Crew( @@ -4103,7 +4103,7 @@ def test_crew_kickoff_for_each_works_with_manager_agent_copy(): manager_agent=manager, process=Process.hierarchical, verbose=True - ) + ) crew_copy = crew.copy() assert crew_copy.manager_agent is not None