From 8c704f4e5d1e989faa4776871397d853b7868c20 Mon Sep 17 00:00:00 2001 From: Brandon Hancock Date: Tue, 11 Mar 2025 11:55:20 -0400 Subject: [PATCH] incorporate small improvements / changes --- src/crewai/agent.py | 4 - src/crewai/agents/agent_builder/base_agent.py | 4 - src/crewai/task.py | 9 +- tests/security/__init__.py | 1 - tests/security/test_examples.py | 114 +++++++++++++----- 5 files changed, 84 insertions(+), 48 deletions(-) diff --git a/src/crewai/agent.py b/src/crewai/agent.py index fa3630bb4..d10b768d4 100644 --- a/src/crewai/agent.py +++ b/src/crewai/agent.py @@ -482,8 +482,4 @@ class Agent(BaseAgent): Returns: Fingerprint: The agent's fingerprint """ - # Ensure we always return a valid Fingerprint - if not self.security_config.fingerprint: - self.security_config.fingerprint = Fingerprint() return self.security_config.fingerprint - diff --git a/src/crewai/agents/agent_builder/base_agent.py b/src/crewai/agents/agent_builder/base_agent.py index 0b9ecc9a9..47515d087 100644 --- a/src/crewai/agents/agent_builder/base_agent.py +++ b/src/crewai/agents/agent_builder/base_agent.py @@ -209,10 +209,6 @@ class BaseAgent(ABC, BaseModel): if self.security_config is None: self.security_config = SecurityConfig() - # Generate fingerprint using role as seed if not already set - if self.security_config.fingerprint is None: - self.security_config.fingerprint = SecurityConfig().fingerprint - return self @field_validator("id", mode="before") diff --git a/src/crewai/task.py b/src/crewai/task.py index 3369d57fb..be400e99a 100644 --- a/src/crewai/task.py +++ b/src/crewai/task.py @@ -441,9 +441,9 @@ class Task(BaseModel): content = ( json_output if json_output - else pydantic_output.model_dump_json() - if pydantic_output - else result + else ( + pydantic_output.model_dump_json() if pydantic_output else result + ) ) self._save_file(content) crewai_event_bus.emit(self, TaskCompletedEvent(output=task_output)) @@ -742,7 +742,4 @@ class Task(BaseModel): Returns: Fingerprint: The fingerprint of the task """ - # Ensure we always return a valid Fingerprint - if not self.security_config.fingerprint: - self.security_config.fingerprint = Fingerprint() return self.security_config.fingerprint diff --git a/tests/security/__init__.py b/tests/security/__init__.py index 960e783aa..e69de29bb 100644 --- a/tests/security/__init__.py +++ b/tests/security/__init__.py @@ -1 +0,0 @@ -"""Tests for the security module.""" \ No newline at end of file diff --git a/tests/security/test_examples.py b/tests/security/test_examples.py index 0d64f8e0b..c0eb14f6c 100644 --- a/tests/security/test_examples.py +++ b/tests/security/test_examples.py @@ -10,9 +10,7 @@ def test_basic_usage_examples(): """Test the basic usage examples from the documentation.""" # Creating components with automatic fingerprinting agent = Agent( - role="Data Scientist", - goal="Analyze data", - backstory="Expert in data analysis" + role="Data Scientist", goal="Analyze data", backstory="Expert in data analysis" ) # Verify the agent has a fingerprint @@ -21,10 +19,7 @@ def test_basic_usage_examples(): assert agent.fingerprint.uuid_str is not None # Create a crew and verify it has a fingerprint - crew = Crew( - agents=[agent], - tasks=[] - ) + crew = Crew(agents=[agent], tasks=[]) assert crew.fingerprint is not None assert isinstance(crew.fingerprint, Fingerprint) assert crew.fingerprint.uuid_str is not None @@ -33,7 +28,7 @@ def test_basic_usage_examples(): task = Task( description="Analyze customer data", expected_output="Insights from data analysis", - agent=agent + agent=agent, ) assert task.fingerprint is not None assert isinstance(task.fingerprint, Fingerprint) @@ -44,20 +39,15 @@ def test_accessing_fingerprints_example(): """Test the accessing fingerprints example from the documentation.""" # Create components agent = Agent( - role="Data Scientist", - goal="Analyze data", - backstory="Expert in data analysis" + role="Data Scientist", goal="Analyze data", backstory="Expert in data analysis" ) - crew = Crew( - agents=[agent], - tasks=[] - ) + crew = Crew(agents=[agent], tasks=[]) task = Task( description="Analyze customer data", expected_output="Insights from data analysis", - agent=agent + agent=agent, ) # Get and verify the agent's fingerprint @@ -82,9 +72,11 @@ def test_accessing_fingerprints_example(): fingerprints = [ agent_fingerprint.uuid_str, crew_fingerprint.uuid_str, - task_fingerprint.uuid_str + task_fingerprint.uuid_str, ] - assert len(fingerprints) == len(set(fingerprints)), "All fingerprints should be unique" + assert len(fingerprints) == len( + set(fingerprints) + ), "All fingerprints should be unique" def test_fingerprint_metadata_example(): @@ -98,7 +90,7 @@ def test_fingerprint_metadata_example(): role="Data Scientist", goal="Analyze data", backstory="Expert in data analysis", - security_config=security_config + security_config=security_config, ) # Verify the metadata is attached to the fingerprint @@ -115,7 +107,7 @@ def test_fingerprint_with_security_config(): role="Data Scientist", goal="Analyze data", backstory="Expert in data analysis", - security_config=security_config + security_config=security_config, ) # Verify the agent uses the same instance of SecurityConfig @@ -126,7 +118,7 @@ def test_fingerprint_with_security_config(): description="Analyze customer data", expected_output="Insights from data analysis", agent=agent, - security_config=security_config + security_config=security_config, ) # Verify the task uses the same instance of SecurityConfig @@ -137,34 +129,29 @@ def test_complete_workflow_example(): """Test the complete workflow example from the documentation.""" # Create agents with auto-generated fingerprints researcher = Agent( - role="Researcher", - goal="Find information", - backstory="Expert researcher" + role="Researcher", goal="Find information", backstory="Expert researcher" ) writer = Agent( - role="Writer", - goal="Create content", - backstory="Professional writer" + role="Writer", goal="Create content", backstory="Professional writer" ) # Create tasks with auto-generated fingerprints research_task = Task( description="Research the topic", expected_output="Research findings", - agent=researcher + agent=researcher, ) writing_task = Task( description="Write an article", expected_output="Completed article", - agent=writer + agent=writer, ) # Create a crew with auto-generated fingerprint content_crew = Crew( - agents=[researcher, writer], - tasks=[research_task, writing_task] + agents=[researcher, writer], tasks=[research_task, writing_task] ) # Verify everything has auto-generated fingerprints @@ -180,6 +167,67 @@ def test_complete_workflow_example(): writer.fingerprint.uuid_str, research_task.fingerprint.uuid_str, writing_task.fingerprint.uuid_str, - content_crew.fingerprint.uuid_str + content_crew.fingerprint.uuid_str, ] - assert len(fingerprints) == len(set(fingerprints)), "All fingerprints should be unique" \ No newline at end of file + assert len(fingerprints) == len( + set(fingerprints) + ), "All fingerprints should be unique" + + +def test_security_preservation_during_copy(): + """Test that security configurations are preserved when copying Crew and Agent objects.""" + # Create a SecurityConfig with custom metadata + security_config = SecurityConfig() + security_config.fingerprint.metadata = {"version": "1.0", "environment": "testing"} + + # Create an agent with the custom SecurityConfig + original_agent = Agent( + role="Security Tester", + goal="Verify security preservation", + backstory="Security expert", + security_config=security_config, + ) + + # Create a task with the agent + task = Task( + description="Test security preservation", + expected_output="Security verification", + agent=original_agent, + ) + + # Create a crew with the agent and task + original_crew = Crew( + agents=[original_agent], tasks=[task], security_config=security_config + ) + + # Copy the agent and crew + copied_agent = original_agent.copy() + copied_crew = original_crew.copy() + + # Verify the agent's security config is preserved during copy + assert copied_agent.security_config is not None + assert isinstance(copied_agent.security_config, SecurityConfig) + assert copied_agent.fingerprint is not None + assert isinstance(copied_agent.fingerprint, Fingerprint) + + # Verify the fingerprint metadata is preserved + assert copied_agent.fingerprint.metadata == { + "version": "1.0", + "environment": "testing", + } + + # Verify the crew's security config is preserved during copy + assert copied_crew.security_config is not None + assert isinstance(copied_crew.security_config, SecurityConfig) + assert copied_crew.fingerprint is not None + assert isinstance(copied_crew.fingerprint, Fingerprint) + + # Verify the fingerprint metadata is preserved + assert copied_crew.fingerprint.metadata == { + "version": "1.0", + "environment": "testing", + } + + # Verify that the fingerprints are the same between original and copied objects + assert original_agent.fingerprint.uuid_str == copied_agent.fingerprint.uuid_str + assert original_crew.fingerprint.uuid_str == copied_crew.fingerprint.uuid_str