mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-05-02 07:42:40 +00:00
style: Fix import sorting in crew_test.py
Co-Authored-By: Joe Moura <joao@crewai.com>
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
"""Test Agent creation and execution basic functionality."""
|
"""Test Agent creation and execution basic functionality."""
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
from concurrent.futures import Future
|
from concurrent.futures import Future
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
import hashlib
|
|
||||||
import instructor
|
import instructor
|
||||||
import json
|
|
||||||
import pydantic_core
|
import pydantic_core
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -15,7 +15,9 @@ from crewai.agent import Agent
|
|||||||
from crewai.agents.cache import CacheHandler
|
from crewai.agents.cache import CacheHandler
|
||||||
from crewai.crew import Crew
|
from crewai.crew import Crew
|
||||||
from crewai.crews.crew_output import CrewOutput
|
from crewai.crews.crew_output import CrewOutput
|
||||||
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
|
from crewai.knowledge.source.string_knowledge_source import (
|
||||||
|
StringKnowledgeSource,
|
||||||
|
)
|
||||||
from crewai.memory.contextual.contextual_memory import ContextualMemory
|
from crewai.memory.contextual.contextual_memory import ContextualMemory
|
||||||
from crewai.process import Process
|
from crewai.process import Process
|
||||||
from crewai.project import crew
|
from crewai.project import crew
|
||||||
@@ -27,7 +29,9 @@ from crewai.tools.base_tool import BaseTool
|
|||||||
from crewai.types.usage_metrics import UsageMetrics
|
from crewai.types.usage_metrics import UsageMetrics
|
||||||
from crewai.utilities import Logger
|
from crewai.utilities import Logger
|
||||||
from crewai.utilities.rpm_controller import RPMController
|
from crewai.utilities.rpm_controller import RPMController
|
||||||
from crewai.utilities.task_output_storage_handler import TaskOutputStorageHandler
|
from crewai.utilities.task_output_storage_handler import (
|
||||||
|
TaskOutputStorageHandler,
|
||||||
|
)
|
||||||
|
|
||||||
ceo = Agent(
|
ceo = Agent(
|
||||||
role="CEO",
|
role="CEO",
|
||||||
@@ -317,31 +321,35 @@ def test_sync_task_execution():
|
|||||||
assert mock_execute_sync.call_count == len(tasks)
|
assert mock_execute_sync.call_count == len(tasks)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.vcr(
|
@pytest.mark.vcr(filter_headers=["authorization"], record_mode="once")
|
||||||
filter_headers=["authorization"],
|
@pytest.mark.parametrize(
|
||||||
record_mode="once"
|
"tool_output,expected",
|
||||||
|
[
|
||||||
|
("test result```", "test result"),
|
||||||
|
("test result`", "test result"),
|
||||||
|
("test result``````", "test result"),
|
||||||
|
("test result", "test result"),
|
||||||
|
("test ```result```", "test ```result"), # Only strip trailing backticks
|
||||||
|
(None, "None"), # Test non-string input gets converted to string
|
||||||
|
(" ", " "), # Test whitespace string
|
||||||
|
(
|
||||||
|
"malformed`result```test",
|
||||||
|
"malformed`result```test",
|
||||||
|
), # Test non-trailing backticks
|
||||||
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.parametrize("tool_output,expected", [
|
|
||||||
("test result```", "test result"),
|
|
||||||
("test result`", "test result"),
|
|
||||||
("test result``````", "test result"),
|
|
||||||
("test result", "test result"),
|
|
||||||
("test ```result```", "test ```result"), # Only strip trailing backticks
|
|
||||||
(None, "None"), # Test non-string input gets converted to string
|
|
||||||
(" ", " "), # Test whitespace string
|
|
||||||
("malformed`result```test", "malformed`result```test"), # Test non-trailing backticks
|
|
||||||
])
|
|
||||||
def test_hierarchical_tool_output_formatting(tool_output, expected):
|
def test_hierarchical_tool_output_formatting(tool_output, expected):
|
||||||
"""Test that tool outputs in hierarchical mode don't have extra backticks.
|
"""Test that tool outputs in hierarchical mode don't have extra backticks.
|
||||||
|
|
||||||
This test verifies that the tool output cleaning functionality correctly handles
|
This test verifies that the tool output cleaning functionality correctly handles
|
||||||
various scenarios of backtick formatting, ensuring only trailing backticks are
|
various scenarios of backtick formatting, ensuring only trailing backticks are
|
||||||
removed while preserving any inline markdown formatting.
|
removed while preserving any inline markdown formatting.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class TestTool(BaseTool):
|
class TestTool(BaseTool):
|
||||||
name: str = "test_tool"
|
name: str = "test_tool"
|
||||||
description: str = "A test tool"
|
description: str = "A test tool"
|
||||||
|
|
||||||
def _run(self, *args: Any, **kwargs: Any) -> str:
|
def _run(self, *args: Any, **kwargs: Any) -> str:
|
||||||
return tool_output
|
return tool_output
|
||||||
|
|
||||||
@@ -358,15 +366,18 @@ def test_hierarchical_tool_output_formatting(tool_output, expected):
|
|||||||
tools=[TestTool()],
|
tools=[TestTool()],
|
||||||
)
|
)
|
||||||
|
|
||||||
with patch.object(Task, 'execute_sync', return_value=TaskOutput(
|
with patch.object(
|
||||||
description="Test task",
|
Task,
|
||||||
raw=expected,
|
"execute_sync",
|
||||||
agent="researcher"
|
return_value=TaskOutput(
|
||||||
)) as mock_execute_sync:
|
description="Test task", raw=expected, agent="researcher"
|
||||||
|
),
|
||||||
|
) as mock_execute_sync:
|
||||||
result = crew.kickoff()
|
result = crew.kickoff()
|
||||||
assert mock_execute_sync.called
|
assert mock_execute_sync.called
|
||||||
assert result.raw == expected
|
assert result.raw == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||||
def test_hierarchical_process():
|
def test_hierarchical_process():
|
||||||
task = Task(
|
task = Task(
|
||||||
@@ -643,12 +654,12 @@ def test_crew_with_delegating_agents_should_not_override_task_tools():
|
|||||||
_, kwargs = mock_execute_sync.call_args
|
_, kwargs = mock_execute_sync.call_args
|
||||||
tools = kwargs["tools"]
|
tools = kwargs["tools"]
|
||||||
|
|
||||||
assert any(
|
assert any(isinstance(tool, TestTool) for tool in tools), (
|
||||||
isinstance(tool, TestTool) for tool in tools
|
"TestTool should be present"
|
||||||
), "TestTool should be present"
|
)
|
||||||
assert any(
|
assert any("delegate" in tool.name.lower() for tool in tools), (
|
||||||
"delegate" in tool.name.lower() for tool in tools
|
"Delegation tool should be present"
|
||||||
), "Delegation tool should be present"
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||||
@@ -707,12 +718,12 @@ def test_crew_with_delegating_agents_should_not_override_agent_tools():
|
|||||||
_, kwargs = mock_execute_sync.call_args
|
_, kwargs = mock_execute_sync.call_args
|
||||||
tools = kwargs["tools"]
|
tools = kwargs["tools"]
|
||||||
|
|
||||||
assert any(
|
assert any(isinstance(tool, TestTool) for tool in new_ceo.tools), (
|
||||||
isinstance(tool, TestTool) for tool in new_ceo.tools
|
"TestTool should be present"
|
||||||
), "TestTool should be present"
|
)
|
||||||
assert any(
|
assert any("delegate" in tool.name.lower() for tool in tools), (
|
||||||
"delegate" in tool.name.lower() for tool in tools
|
"Delegation tool should be present"
|
||||||
), "Delegation tool should be present"
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||||
@@ -836,17 +847,17 @@ def test_task_tools_override_agent_tools_with_allow_delegation():
|
|||||||
used_tools = kwargs["tools"]
|
used_tools = kwargs["tools"]
|
||||||
|
|
||||||
# Confirm AnotherTestTool is present but TestTool is not
|
# Confirm AnotherTestTool is present but TestTool is not
|
||||||
assert any(
|
assert any(isinstance(tool, AnotherTestTool) for tool in used_tools), (
|
||||||
isinstance(tool, AnotherTestTool) for tool in used_tools
|
"AnotherTestTool should be present"
|
||||||
), "AnotherTestTool should be present"
|
)
|
||||||
assert not any(
|
assert not any(isinstance(tool, TestTool) for tool in used_tools), (
|
||||||
isinstance(tool, TestTool) for tool in used_tools
|
"TestTool should not be present among used tools"
|
||||||
), "TestTool should not be present among used tools"
|
)
|
||||||
|
|
||||||
# Confirm delegation tool(s) are present
|
# Confirm delegation tool(s) are present
|
||||||
assert any(
|
assert any("delegate" in tool.name.lower() for tool in used_tools), (
|
||||||
"delegate" in tool.name.lower() for tool in used_tools
|
"Delegation tool should be present"
|
||||||
), "Delegation tool should be present"
|
)
|
||||||
|
|
||||||
# Finally, make sure the agent's original tools remain unchanged
|
# Finally, make sure the agent's original tools remain unchanged
|
||||||
assert len(researcher_with_delegation.tools) == 1
|
assert len(researcher_with_delegation.tools) == 1
|
||||||
@@ -1647,9 +1658,9 @@ def test_code_execution_flag_adds_code_tool_upon_kickoff():
|
|||||||
|
|
||||||
# Verify that exactly one tool was used and it was a CodeInterpreterTool
|
# Verify that exactly one tool was used and it was a CodeInterpreterTool
|
||||||
assert len(used_tools) == 1, "Should have exactly one tool"
|
assert len(used_tools) == 1, "Should have exactly one tool"
|
||||||
assert isinstance(
|
assert isinstance(used_tools[0], CodeInterpreterTool), (
|
||||||
used_tools[0], CodeInterpreterTool
|
"Tool should be CodeInterpreterTool"
|
||||||
), "Tool should be CodeInterpreterTool"
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||||
@@ -3470,9 +3481,9 @@ def test_fetch_inputs():
|
|||||||
expected_placeholders = {"role_detail", "topic", "field"}
|
expected_placeholders = {"role_detail", "topic", "field"}
|
||||||
actual_placeholders = crew.fetch_inputs()
|
actual_placeholders = crew.fetch_inputs()
|
||||||
|
|
||||||
assert (
|
assert actual_placeholders == expected_placeholders, (
|
||||||
actual_placeholders == expected_placeholders
|
f"Expected {expected_placeholders}, but got {actual_placeholders}"
|
||||||
), f"Expected {expected_placeholders}, but got {actual_placeholders}"
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_task_tools_preserve_code_execution_tools():
|
def test_task_tools_preserve_code_execution_tools():
|
||||||
@@ -3545,20 +3556,20 @@ def test_task_tools_preserve_code_execution_tools():
|
|||||||
used_tools = kwargs["tools"]
|
used_tools = kwargs["tools"]
|
||||||
|
|
||||||
# Verify all expected tools are present
|
# Verify all expected tools are present
|
||||||
assert any(
|
assert any(isinstance(tool, TestTool) for tool in used_tools), (
|
||||||
isinstance(tool, TestTool) for tool in used_tools
|
"Task's TestTool should be present"
|
||||||
), "Task's TestTool should be present"
|
)
|
||||||
assert any(
|
assert any(isinstance(tool, CodeInterpreterTool) for tool in used_tools), (
|
||||||
isinstance(tool, CodeInterpreterTool) for tool in used_tools
|
"CodeInterpreterTool should be present"
|
||||||
), "CodeInterpreterTool should be present"
|
)
|
||||||
assert any(
|
assert any("delegate" in tool.name.lower() for tool in used_tools), (
|
||||||
"delegate" in tool.name.lower() for tool in used_tools
|
"Delegation tool should be present"
|
||||||
), "Delegation tool should be present"
|
)
|
||||||
|
|
||||||
# Verify the total number of tools (TestTool + CodeInterpreter + 2 delegation tools)
|
# Verify the total number of tools (TestTool + CodeInterpreter + 2 delegation tools)
|
||||||
assert (
|
assert len(used_tools) == 4, (
|
||||||
len(used_tools) == 4
|
"Should have TestTool, CodeInterpreter, and 2 delegation tools"
|
||||||
), "Should have TestTool, CodeInterpreter, and 2 delegation tools"
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||||
@@ -3602,9 +3613,9 @@ def test_multimodal_flag_adds_multimodal_tools():
|
|||||||
used_tools = kwargs["tools"]
|
used_tools = kwargs["tools"]
|
||||||
|
|
||||||
# Check that the multimodal tool was added
|
# Check that the multimodal tool was added
|
||||||
assert any(
|
assert any(isinstance(tool, AddImageTool) for tool in used_tools), (
|
||||||
isinstance(tool, AddImageTool) for tool in used_tools
|
"AddImageTool should be present when agent is multimodal"
|
||||||
), "AddImageTool should be present when agent is multimodal"
|
)
|
||||||
|
|
||||||
# Verify we have exactly one tool (just the AddImageTool)
|
# Verify we have exactly one tool (just the AddImageTool)
|
||||||
assert len(used_tools) == 1, "Should only have the AddImageTool"
|
assert len(used_tools) == 1, "Should only have the AddImageTool"
|
||||||
@@ -3830,9 +3841,9 @@ def test_crew_guardrail_feedback_in_context():
|
|||||||
assert len(execution_contexts) > 1, "Task should have been executed multiple times"
|
assert len(execution_contexts) > 1, "Task should have been executed multiple times"
|
||||||
|
|
||||||
# Verify that the second execution included the guardrail feedback
|
# Verify that the second execution included the guardrail feedback
|
||||||
assert (
|
assert "Output must contain the keyword 'IMPORTANT'" in execution_contexts[1], (
|
||||||
"Output must contain the keyword 'IMPORTANT'" in execution_contexts[1]
|
"Guardrail feedback should be included in retry context"
|
||||||
), "Guardrail feedback should be included in retry context"
|
)
|
||||||
|
|
||||||
# Verify final output meets guardrail requirements
|
# Verify final output meets guardrail requirements
|
||||||
assert "IMPORTANT" in result.raw, "Final output should contain required keyword"
|
assert "IMPORTANT" in result.raw, "Final output should contain required keyword"
|
||||||
|
|||||||
Reference in New Issue
Block a user