mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-09 08:08:32 +00:00
refactor: Move events module to crewai.events (#3425)
refactor(events): relocate events module & update imports - Move events from utilities/ to top-level events/ with types/, listeners/, utils/ structure - Update all source/tests/docs to new import paths - Add backwards compatibility stubs in crewai.utilities.events with deprecation warnings - Restore test mocks and fix related test imports
This commit is contained in:
@@ -19,8 +19,8 @@ from crewai.tools.tool_calling import InstructorToolCalling
|
||||
from crewai.tools.tool_usage import ToolUsage
|
||||
from crewai.utilities import RPMController
|
||||
from crewai.utilities.errors import AgentRepositoryError
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.utilities.events.tool_usage_events import ToolUsageFinishedEvent
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.tool_usage_events import ToolUsageFinishedEvent
|
||||
from crewai.process import Process
|
||||
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ from crewai import LLM, Agent
|
||||
from crewai.flow import Flow, start
|
||||
from crewai.lite_agent import LiteAgent, LiteAgentOutput
|
||||
from crewai.tools import BaseTool
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.utilities.events.agent_events import LiteAgentExecutionStartedEvent
|
||||
from crewai.utilities.events.tool_usage_events import ToolUsageStartedEvent
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.agent_events import LiteAgentExecutionStartedEvent
|
||||
from crewai.events.types.tool_usage_events import ToolUsageStartedEvent
|
||||
from crewai.llms.base_llm import BaseLLM
|
||||
from unittest.mock import patch
|
||||
|
||||
@@ -322,7 +322,7 @@ def test_sets_parent_flow_when_inside_flow():
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_guardrail_is_called_using_string():
|
||||
guardrail_events = defaultdict(list)
|
||||
from crewai.utilities.events import (
|
||||
from crewai.events.event_types import (
|
||||
LLMGuardrailCompletedEvent,
|
||||
LLMGuardrailStartedEvent,
|
||||
)
|
||||
@@ -359,7 +359,7 @@ def test_guardrail_is_called_using_string():
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_guardrail_is_called_using_callable():
|
||||
guardrail_events = defaultdict(list)
|
||||
from crewai.utilities.events import (
|
||||
from crewai.events.event_types import (
|
||||
LLMGuardrailCompletedEvent,
|
||||
LLMGuardrailStartedEvent,
|
||||
)
|
||||
@@ -392,7 +392,7 @@ def test_guardrail_is_called_using_callable():
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_guardrail_reached_attempt_limit():
|
||||
guardrail_events = defaultdict(list)
|
||||
from crewai.utilities.events import (
|
||||
from crewai.events.event_types import (
|
||||
LLMGuardrailCompletedEvent,
|
||||
LLMGuardrailStartedEvent,
|
||||
)
|
||||
|
||||
@@ -80,7 +80,7 @@ def auto_mock_telemetry(request):
|
||||
|
||||
with (
|
||||
patch(
|
||||
"crewai.utilities.events.event_listener.Telemetry",
|
||||
"crewai.events.event_listener.Telemetry",
|
||||
mock_telemetry_class,
|
||||
),
|
||||
patch("crewai.tools.tool_usage.Telemetry", mock_telemetry_class),
|
||||
|
||||
@@ -13,13 +13,18 @@ from crewai.experimental.evaluation import (
|
||||
ToolInvocationEvaluator,
|
||||
ReasoningEfficiencyEvaluator,
|
||||
MetricCategory,
|
||||
EvaluationScore
|
||||
EvaluationScore,
|
||||
)
|
||||
|
||||
from crewai.utilities.events.agent_events import AgentEvaluationStartedEvent, AgentEvaluationCompletedEvent, AgentEvaluationFailedEvent
|
||||
from crewai.utilities.events.crewai_event_bus import crewai_event_bus
|
||||
from crewai.events.types.agent_events import (
|
||||
AgentEvaluationStartedEvent,
|
||||
AgentEvaluationCompletedEvent,
|
||||
AgentEvaluationFailedEvent,
|
||||
)
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.experimental.evaluation import create_default_evaluator
|
||||
|
||||
|
||||
class TestAgentEvaluator:
|
||||
@pytest.fixture
|
||||
def mock_crew(self):
|
||||
@@ -28,19 +33,16 @@ class TestAgentEvaluator:
|
||||
goal="Complete test tasks successfully",
|
||||
backstory="An agent created for testing purposes",
|
||||
allow_delegation=False,
|
||||
verbose=False
|
||||
verbose=False,
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="Test task description",
|
||||
agent=agent,
|
||||
expected_output="Expected test output"
|
||||
expected_output="Expected test output",
|
||||
)
|
||||
|
||||
crew = Crew(
|
||||
agents=[agent],
|
||||
tasks=[task]
|
||||
)
|
||||
crew = Crew(agents=[agent], tasks=[task])
|
||||
return crew
|
||||
|
||||
def test_set_iteration(self):
|
||||
@@ -51,7 +53,9 @@ class TestAgentEvaluator:
|
||||
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_evaluate_current_iteration(self, mock_crew):
|
||||
agent_evaluator = AgentEvaluator(agents=mock_crew.agents, evaluators=[GoalAlignmentEvaluator()])
|
||||
agent_evaluator = AgentEvaluator(
|
||||
agents=mock_crew.agents, evaluators=[GoalAlignmentEvaluator()]
|
||||
)
|
||||
|
||||
mock_crew.kickoff()
|
||||
|
||||
@@ -59,20 +63,20 @@ class TestAgentEvaluator:
|
||||
|
||||
assert isinstance(results, dict)
|
||||
|
||||
agent, = mock_crew.agents
|
||||
task, = mock_crew.tasks
|
||||
(agent,) = mock_crew.agents
|
||||
(task,) = mock_crew.tasks
|
||||
|
||||
assert len(mock_crew.agents) == 1
|
||||
assert agent.role in results
|
||||
assert len(results[agent.role]) == 1
|
||||
|
||||
result, = results[agent.role]
|
||||
(result,) = results[agent.role]
|
||||
assert isinstance(result, AgentEvaluationResult)
|
||||
|
||||
assert result.agent_id == str(agent.id)
|
||||
assert result.task_id == str(task.id)
|
||||
|
||||
goal_alignment, = result.metrics.values()
|
||||
(goal_alignment,) = result.metrics.values()
|
||||
assert goal_alignment.score == 5.0
|
||||
|
||||
expected_feedback = "The agent's output demonstrates an understanding of the need for a comprehensive document outlining task"
|
||||
@@ -92,7 +96,7 @@ class TestAgentEvaluator:
|
||||
ToolSelectionEvaluator,
|
||||
ParameterExtractionEvaluator,
|
||||
ToolInvocationEvaluator,
|
||||
ReasoningEfficiencyEvaluator
|
||||
ReasoningEfficiencyEvaluator,
|
||||
]
|
||||
|
||||
assert len(agent_evaluator.evaluators) == len(expected_types)
|
||||
@@ -109,6 +113,7 @@ class TestAgentEvaluator:
|
||||
|
||||
with crewai_event_bus.scoped_handlers():
|
||||
events = {}
|
||||
|
||||
@crewai_event_bus.on(AgentEvaluationStartedEvent)
|
||||
def capture_started(source, event):
|
||||
events["started"] = event
|
||||
@@ -121,7 +126,9 @@ class TestAgentEvaluator:
|
||||
def capture_failed(source, event):
|
||||
events["failed"] = event
|
||||
|
||||
agent_evaluator = AgentEvaluator(agents=[agent], evaluators=[GoalAlignmentEvaluator()])
|
||||
agent_evaluator = AgentEvaluator(
|
||||
agents=[agent], evaluators=[GoalAlignmentEvaluator()]
|
||||
)
|
||||
|
||||
agent.kickoff(messages="Complete this task successfully")
|
||||
|
||||
@@ -143,13 +150,13 @@ class TestAgentEvaluator:
|
||||
|
||||
assert isinstance(results, dict)
|
||||
|
||||
result, = results[agent.role]
|
||||
(result,) = results[agent.role]
|
||||
assert isinstance(result, AgentEvaluationResult)
|
||||
|
||||
assert result.agent_id == str(agent.id)
|
||||
assert result.task_id == "lite_task"
|
||||
|
||||
goal_alignment, = result.metrics.values()
|
||||
(goal_alignment,) = result.metrics.values()
|
||||
assert goal_alignment.score == 2.0
|
||||
|
||||
expected_feedback = "The agent did not demonstrate a clear understanding of the task goal, which is to complete test tasks successfully"
|
||||
@@ -168,13 +175,14 @@ class TestAgentEvaluator:
|
||||
task = Task(
|
||||
description="Test task description",
|
||||
agent=agent,
|
||||
expected_output="Expected test output"
|
||||
expected_output="Expected test output",
|
||||
)
|
||||
mock_crew.agents.append(agent)
|
||||
mock_crew.tasks.append(task)
|
||||
|
||||
with crewai_event_bus.scoped_handlers():
|
||||
events = {}
|
||||
|
||||
@crewai_event_bus.on(AgentEvaluationStartedEvent)
|
||||
def capture_started(source, event):
|
||||
events["started"] = event
|
||||
@@ -187,7 +195,9 @@ class TestAgentEvaluator:
|
||||
def capture_failed(source, event):
|
||||
events["failed"] = event
|
||||
|
||||
agent_evaluator = AgentEvaluator(agents=[agent], evaluators=[GoalAlignmentEvaluator()])
|
||||
agent_evaluator = AgentEvaluator(
|
||||
agents=[agent], evaluators=[GoalAlignmentEvaluator()]
|
||||
)
|
||||
mock_crew.kickoff()
|
||||
|
||||
assert events.keys() == {"started", "completed"}
|
||||
@@ -208,13 +218,13 @@ class TestAgentEvaluator:
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert len(results.keys()) == 1
|
||||
result, = results[agent.role]
|
||||
(result,) = results[agent.role]
|
||||
assert isinstance(result, AgentEvaluationResult)
|
||||
|
||||
assert result.agent_id == str(agent.id)
|
||||
assert result.task_id == str(task.id)
|
||||
|
||||
goal_alignment, = result.metrics.values()
|
||||
(goal_alignment,) = result.metrics.values()
|
||||
assert goal_alignment.score == 5.0
|
||||
|
||||
expected_feedback = "The agent provided a thorough guide on how to conduct a test task but failed to produce specific expected output"
|
||||
@@ -223,11 +233,10 @@ class TestAgentEvaluator:
|
||||
assert goal_alignment.raw_response is not None
|
||||
assert '"score": 5' in goal_alignment.raw_response
|
||||
|
||||
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_failed_evaluation(self, mock_crew):
|
||||
agent, = mock_crew.agents
|
||||
task, = mock_crew.tasks
|
||||
(agent,) = mock_crew.agents
|
||||
(task,) = mock_crew.tasks
|
||||
|
||||
with crewai_event_bus.scoped_handlers():
|
||||
events = {}
|
||||
@@ -247,13 +256,16 @@ class TestAgentEvaluator:
|
||||
# Create a mock evaluator that will raise an exception
|
||||
from crewai.experimental.evaluation.base_evaluator import BaseEvaluator
|
||||
from crewai.experimental.evaluation import MetricCategory
|
||||
|
||||
class FailingEvaluator(BaseEvaluator):
|
||||
metric_category = MetricCategory.GOAL_ALIGNMENT
|
||||
|
||||
def evaluate(self, agent, task, execution_trace, final_output):
|
||||
raise ValueError("Forced evaluation failure")
|
||||
|
||||
agent_evaluator = AgentEvaluator(agents=[agent], evaluators=[FailingEvaluator()])
|
||||
agent_evaluator = AgentEvaluator(
|
||||
agents=[agent], evaluators=[FailingEvaluator()]
|
||||
)
|
||||
mock_crew.kickoff()
|
||||
|
||||
assert events.keys() == {"started", "failed"}
|
||||
@@ -269,7 +281,7 @@ class TestAgentEvaluator:
|
||||
assert events["failed"].error == "Forced evaluation failure"
|
||||
|
||||
results = agent_evaluator.get_evaluation_results()
|
||||
result, = results[agent.role]
|
||||
(result,) = results[agent.role]
|
||||
assert isinstance(result, AgentEvaluationResult)
|
||||
|
||||
assert result.agent_id == str(agent.id)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from unittest.mock import MagicMock, patch, ANY
|
||||
from collections import defaultdict
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.utilities.events.memory_events import (
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.memory_events import (
|
||||
MemorySaveStartedEvent,
|
||||
MemorySaveCompletedEvent,
|
||||
MemoryQueryStartedEvent,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import pytest
|
||||
from unittest.mock import ANY
|
||||
from collections import defaultdict
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.memory.long_term.long_term_memory import LongTermMemory
|
||||
from crewai.memory.long_term.long_term_memory_item import LongTermMemoryItem
|
||||
from crewai.utilities.events.memory_events import (
|
||||
from crewai.events.types.memory_events import (
|
||||
MemorySaveStartedEvent,
|
||||
MemorySaveCompletedEvent,
|
||||
MemoryQueryStartedEvent,
|
||||
|
||||
@@ -7,8 +7,8 @@ from crewai.crew import Crew
|
||||
from crewai.memory.short_term.short_term_memory import ShortTermMemory
|
||||
from crewai.memory.short_term.short_term_memory_item import ShortTermMemoryItem
|
||||
from crewai.task import Task
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.utilities.events.memory_events import (
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.memory_events import (
|
||||
MemorySaveStartedEvent,
|
||||
MemorySaveCompletedEvent,
|
||||
MemoryQueryStartedEvent,
|
||||
|
||||
@@ -27,19 +27,17 @@ from crewai.tasks.conditional_task import ConditionalTask
|
||||
from crewai.tasks.output_format import OutputFormat
|
||||
from crewai.tasks.task_output import TaskOutput
|
||||
from crewai.types.usage_metrics import UsageMetrics
|
||||
from crewai.utilities.events import (
|
||||
CrewTrainCompletedEvent,
|
||||
CrewTrainStartedEvent,
|
||||
crewai_event_bus,
|
||||
)
|
||||
from crewai.utilities.events.crew_events import (
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.crew_events import (
|
||||
CrewTestCompletedEvent,
|
||||
CrewTestStartedEvent,
|
||||
CrewTrainCompletedEvent,
|
||||
CrewTrainStartedEvent,
|
||||
)
|
||||
from crewai.utilities.rpm_controller import RPMController
|
||||
from crewai.utilities.task_output_storage_handler import TaskOutputStorageHandler
|
||||
|
||||
from crewai.utilities.events.memory_events import (
|
||||
from crewai.events.types.memory_events import (
|
||||
MemorySaveStartedEvent,
|
||||
MemorySaveCompletedEvent,
|
||||
MemorySaveFailedEvent,
|
||||
|
||||
@@ -7,14 +7,14 @@ import pytest
|
||||
from pydantic import BaseModel
|
||||
|
||||
from crewai.flow.flow import Flow, and_, listen, or_, router, start
|
||||
from crewai.utilities.events import (
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.flow_events import (
|
||||
FlowFinishedEvent,
|
||||
FlowStartedEvent,
|
||||
FlowPlotEvent,
|
||||
MethodExecutionFinishedEvent,
|
||||
MethodExecutionStartedEvent,
|
||||
crewai_event_bus,
|
||||
)
|
||||
from crewai.utilities.events.flow_events import FlowPlotEvent
|
||||
|
||||
|
||||
def test_simple_sequential_flow():
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
from crewai.utilities.events.event_listener import event_listener
|
||||
from crewai.events.event_listener import event_listener
|
||||
|
||||
|
||||
class TestFlowHumanInputIntegration:
|
||||
@@ -9,82 +9,90 @@ class TestFlowHumanInputIntegration:
|
||||
def test_console_formatter_pause_resume_methods(self):
|
||||
"""Test that ConsoleFormatter pause/resume methods work correctly."""
|
||||
formatter = event_listener.formatter
|
||||
|
||||
|
||||
original_paused_state = formatter._live_paused
|
||||
|
||||
|
||||
try:
|
||||
formatter._live_paused = False
|
||||
|
||||
|
||||
formatter.pause_live_updates()
|
||||
assert formatter._live_paused
|
||||
|
||||
|
||||
formatter.resume_live_updates()
|
||||
assert not formatter._live_paused
|
||||
finally:
|
||||
formatter._live_paused = original_paused_state
|
||||
|
||||
@patch('builtins.input', return_value='')
|
||||
@patch("builtins.input", return_value="")
|
||||
def test_human_input_pauses_flow_updates(self, mock_input):
|
||||
"""Test that human input pauses Flow status updates."""
|
||||
from crewai.agents.agent_builder.base_agent_executor_mixin import CrewAgentExecutorMixin
|
||||
|
||||
from crewai.agents.agent_builder.base_agent_executor_mixin import (
|
||||
CrewAgentExecutorMixin,
|
||||
)
|
||||
|
||||
executor = CrewAgentExecutorMixin()
|
||||
executor.crew = MagicMock()
|
||||
executor.crew._train = False
|
||||
executor._printer = MagicMock()
|
||||
|
||||
|
||||
formatter = event_listener.formatter
|
||||
|
||||
|
||||
original_paused_state = formatter._live_paused
|
||||
|
||||
|
||||
try:
|
||||
formatter._live_paused = False
|
||||
|
||||
with patch.object(formatter, 'pause_live_updates') as mock_pause, \
|
||||
patch.object(formatter, 'resume_live_updates') as mock_resume:
|
||||
|
||||
|
||||
with (
|
||||
patch.object(formatter, "pause_live_updates") as mock_pause,
|
||||
patch.object(formatter, "resume_live_updates") as mock_resume,
|
||||
):
|
||||
result = executor._ask_human_input("Test result")
|
||||
|
||||
|
||||
mock_pause.assert_called_once()
|
||||
mock_resume.assert_called_once()
|
||||
mock_input.assert_called_once()
|
||||
assert result == ''
|
||||
assert result == ""
|
||||
finally:
|
||||
formatter._live_paused = original_paused_state
|
||||
|
||||
@patch('builtins.input', side_effect=['feedback', ''])
|
||||
@patch("builtins.input", side_effect=["feedback", ""])
|
||||
def test_multiple_human_input_rounds(self, mock_input):
|
||||
"""Test multiple rounds of human input with Flow status management."""
|
||||
from crewai.agents.agent_builder.base_agent_executor_mixin import CrewAgentExecutorMixin
|
||||
|
||||
from crewai.agents.agent_builder.base_agent_executor_mixin import (
|
||||
CrewAgentExecutorMixin,
|
||||
)
|
||||
|
||||
executor = CrewAgentExecutorMixin()
|
||||
executor.crew = MagicMock()
|
||||
executor.crew._train = False
|
||||
executor._printer = MagicMock()
|
||||
|
||||
|
||||
formatter = event_listener.formatter
|
||||
|
||||
|
||||
original_paused_state = formatter._live_paused
|
||||
|
||||
|
||||
try:
|
||||
pause_calls = []
|
||||
resume_calls = []
|
||||
|
||||
|
||||
def track_pause():
|
||||
pause_calls.append(True)
|
||||
|
||||
|
||||
def track_resume():
|
||||
resume_calls.append(True)
|
||||
|
||||
with patch.object(formatter, 'pause_live_updates', side_effect=track_pause), \
|
||||
patch.object(formatter, 'resume_live_updates', side_effect=track_resume):
|
||||
|
||||
|
||||
with (
|
||||
patch.object(formatter, "pause_live_updates", side_effect=track_pause),
|
||||
patch.object(
|
||||
formatter, "resume_live_updates", side_effect=track_resume
|
||||
),
|
||||
):
|
||||
result1 = executor._ask_human_input("Test result 1")
|
||||
assert result1 == 'feedback'
|
||||
|
||||
assert result1 == "feedback"
|
||||
|
||||
result2 = executor._ask_human_input("Test result 2")
|
||||
assert result2 == ''
|
||||
|
||||
assert result2 == ""
|
||||
|
||||
assert len(pause_calls) == 2
|
||||
assert len(resume_calls) == 2
|
||||
finally:
|
||||
@@ -93,17 +101,17 @@ class TestFlowHumanInputIntegration:
|
||||
def test_pause_resume_with_no_live_session(self):
|
||||
"""Test pause/resume methods handle case when no Live session exists."""
|
||||
formatter = event_listener.formatter
|
||||
|
||||
|
||||
original_live = formatter._live
|
||||
original_paused_state = formatter._live_paused
|
||||
|
||||
|
||||
try:
|
||||
formatter._live = None
|
||||
formatter._live_paused = False
|
||||
|
||||
|
||||
formatter.pause_live_updates()
|
||||
formatter.resume_live_updates()
|
||||
|
||||
|
||||
assert not formatter._live_paused
|
||||
finally:
|
||||
formatter._live = original_live
|
||||
@@ -111,25 +119,30 @@ class TestFlowHumanInputIntegration:
|
||||
|
||||
def test_pause_resume_exception_handling(self):
|
||||
"""Test that resume is called even if exception occurs during human input."""
|
||||
from crewai.agents.agent_builder.base_agent_executor_mixin import CrewAgentExecutorMixin
|
||||
|
||||
from crewai.agents.agent_builder.base_agent_executor_mixin import (
|
||||
CrewAgentExecutorMixin,
|
||||
)
|
||||
|
||||
executor = CrewAgentExecutorMixin()
|
||||
executor.crew = MagicMock()
|
||||
executor.crew._train = False
|
||||
executor._printer = MagicMock()
|
||||
|
||||
|
||||
formatter = event_listener.formatter
|
||||
|
||||
|
||||
original_paused_state = formatter._live_paused
|
||||
|
||||
|
||||
try:
|
||||
with patch.object(formatter, 'pause_live_updates') as mock_pause, \
|
||||
patch.object(formatter, 'resume_live_updates') as mock_resume, \
|
||||
patch('builtins.input', side_effect=KeyboardInterrupt("Test exception")):
|
||||
|
||||
with (
|
||||
patch.object(formatter, "pause_live_updates") as mock_pause,
|
||||
patch.object(formatter, "resume_live_updates") as mock_resume,
|
||||
patch(
|
||||
"builtins.input", side_effect=KeyboardInterrupt("Test exception")
|
||||
),
|
||||
):
|
||||
with pytest.raises(KeyboardInterrupt):
|
||||
executor._ask_human_input("Test result")
|
||||
|
||||
|
||||
mock_pause.assert_called_once()
|
||||
mock_resume.assert_called_once()
|
||||
finally:
|
||||
@@ -137,31 +150,39 @@ class TestFlowHumanInputIntegration:
|
||||
|
||||
def test_training_mode_human_input(self):
|
||||
"""Test human input in training mode."""
|
||||
from crewai.agents.agent_builder.base_agent_executor_mixin import CrewAgentExecutorMixin
|
||||
|
||||
from crewai.agents.agent_builder.base_agent_executor_mixin import (
|
||||
CrewAgentExecutorMixin,
|
||||
)
|
||||
|
||||
executor = CrewAgentExecutorMixin()
|
||||
executor.crew = MagicMock()
|
||||
executor.crew._train = True
|
||||
executor._printer = MagicMock()
|
||||
|
||||
|
||||
formatter = event_listener.formatter
|
||||
|
||||
|
||||
original_paused_state = formatter._live_paused
|
||||
|
||||
|
||||
try:
|
||||
with patch.object(formatter, 'pause_live_updates') as mock_pause, \
|
||||
patch.object(formatter, 'resume_live_updates') as mock_resume, \
|
||||
patch('builtins.input', return_value='training feedback'):
|
||||
|
||||
with (
|
||||
patch.object(formatter, "pause_live_updates") as mock_pause,
|
||||
patch.object(formatter, "resume_live_updates") as mock_resume,
|
||||
patch("builtins.input", return_value="training feedback"),
|
||||
):
|
||||
result = executor._ask_human_input("Test result")
|
||||
|
||||
|
||||
mock_pause.assert_called_once()
|
||||
mock_resume.assert_called_once()
|
||||
assert result == 'training feedback'
|
||||
|
||||
assert result == "training feedback"
|
||||
|
||||
executor._printer.print.assert_called()
|
||||
call_args = [call[1]['content'] for call in executor._printer.print.call_args_list]
|
||||
training_prompt_found = any('TRAINING MODE' in content for content in call_args)
|
||||
call_args = [
|
||||
call[1]["content"]
|
||||
for call in executor._printer.print.call_args_list
|
||||
]
|
||||
training_prompt_found = any(
|
||||
"TRAINING MODE" in content for content in call_args
|
||||
)
|
||||
assert training_prompt_found
|
||||
finally:
|
||||
formatter._live_paused = original_paused_state
|
||||
|
||||
@@ -8,7 +8,7 @@ from pydantic import BaseModel
|
||||
|
||||
from crewai.agents.agent_builder.utilities.base_token_process import TokenProcess
|
||||
from crewai.llm import CONTEXT_WINDOW_USAGE_RATIO, LLM
|
||||
from crewai.utilities.events import (
|
||||
from crewai.events.event_types import (
|
||||
LLMCallCompletedEvent,
|
||||
LLMStreamChunkEvent,
|
||||
ToolUsageStartedEvent,
|
||||
@@ -563,7 +563,7 @@ def assert_event_count(
|
||||
|
||||
@pytest.fixture
|
||||
def mock_emit() -> MagicMock:
|
||||
from crewai.utilities.events.crewai_event_bus import CrewAIEventsBus
|
||||
from crewai.events.event_bus import CrewAIEventsBus
|
||||
|
||||
with patch.object(CrewAIEventsBus, "emit") as mock_emit:
|
||||
yield mock_emit
|
||||
|
||||
@@ -7,11 +7,11 @@ from crewai.llm import LLM
|
||||
from crewai.tasks.hallucination_guardrail import HallucinationGuardrail
|
||||
from crewai.tasks.llm_guardrail import LLMGuardrail
|
||||
from crewai.tasks.task_output import TaskOutput
|
||||
from crewai.utilities.events import (
|
||||
from crewai.events.event_types import (
|
||||
LLMGuardrailCompletedEvent,
|
||||
LLMGuardrailStartedEvent,
|
||||
)
|
||||
from crewai.utilities.events.crewai_event_bus import crewai_event_bus
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
|
||||
|
||||
def test_task_without_guardrail():
|
||||
|
||||
@@ -10,8 +10,8 @@ from pydantic import BaseModel, Field
|
||||
from crewai import Agent, Task
|
||||
from crewai.tools import BaseTool
|
||||
from crewai.tools.tool_usage import ToolUsage
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.utilities.events.tool_usage_events import (
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.tool_usage_events import (
|
||||
ToolSelectionErrorEvent,
|
||||
ToolUsageFinishedEvent,
|
||||
ToolValidateInputErrorEvent,
|
||||
|
||||
@@ -5,13 +5,13 @@ from unittest.mock import patch, MagicMock
|
||||
|
||||
from crewai import Agent, Task, Crew
|
||||
from crewai.flow.flow import Flow, start
|
||||
from crewai.utilities.events.listeners.tracing.trace_listener import (
|
||||
from crewai.events.listeners.tracing.trace_listener import (
|
||||
TraceCollectionListener,
|
||||
)
|
||||
from crewai.utilities.events.listeners.tracing.trace_batch_manager import (
|
||||
from crewai.events.listeners.tracing.trace_batch_manager import (
|
||||
TraceBatchManager,
|
||||
)
|
||||
from crewai.utilities.events.listeners.tracing.types import TraceEvent
|
||||
from crewai.events.listeners.tracing.types import TraceEvent
|
||||
|
||||
|
||||
class TestTraceListenerSetup:
|
||||
@@ -27,11 +27,11 @@ class TestTraceListenerSetup:
|
||||
return_value="mock_token_12345",
|
||||
),
|
||||
patch(
|
||||
"crewai.utilities.events.listeners.tracing.trace_listener.get_auth_token",
|
||||
"crewai.events.listeners.tracing.trace_listener.get_auth_token",
|
||||
return_value="mock_token_12345",
|
||||
),
|
||||
patch(
|
||||
"crewai.utilities.events.listeners.tracing.trace_batch_manager.get_auth_token",
|
||||
"crewai.events.listeners.tracing.trace_batch_manager.get_auth_token",
|
||||
return_value="mock_token_12345",
|
||||
),
|
||||
):
|
||||
@@ -40,7 +40,7 @@ class TestTraceListenerSetup:
|
||||
@pytest.fixture(autouse=True)
|
||||
def clear_event_bus(self):
|
||||
"""Clear event bus listeners before and after each test"""
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
|
||||
# Store original handlers
|
||||
original_handlers = crewai_event_bus._handlers.copy()
|
||||
@@ -123,7 +123,7 @@ class TestTraceListenerSetup:
|
||||
crew = Crew(agents=[agent], tasks=[task], verbose=True)
|
||||
|
||||
trace_listener = TraceCollectionListener()
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
|
||||
trace_listener.setup_listeners(crewai_event_bus)
|
||||
|
||||
@@ -162,7 +162,7 @@ class TestTraceListenerSetup:
|
||||
|
||||
crew = Crew(agents=[agent], tasks=[task], verbose=True)
|
||||
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
|
||||
trace_listener = None
|
||||
for handler_list in crewai_event_bus._handlers.values():
|
||||
@@ -207,7 +207,7 @@ class TestTraceListenerSetup:
|
||||
)
|
||||
crew = Crew(agents=[agent], tasks=[task], verbose=True)
|
||||
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
|
||||
# Create and setup trace listener explicitly
|
||||
trace_listener = TraceCollectionListener()
|
||||
@@ -262,7 +262,7 @@ class TestTraceListenerSetup:
|
||||
result = crew.kickoff()
|
||||
assert result is not None
|
||||
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
|
||||
trace_handlers = []
|
||||
for handlers in crewai_event_bus._handlers.values():
|
||||
@@ -281,9 +281,9 @@ class TestTraceListenerSetup:
|
||||
):
|
||||
trace_handlers.append(handler)
|
||||
|
||||
assert len(trace_handlers) == 0, (
|
||||
f"Found {len(trace_handlers)} trace handlers when tracing should be disabled"
|
||||
)
|
||||
assert (
|
||||
len(trace_handlers) == 0
|
||||
), f"Found {len(trace_handlers)} trace handlers when tracing should be disabled"
|
||||
|
||||
def test_trace_listener_setup_correctly_for_crew(self):
|
||||
"""Test that trace listener is set up correctly when enabled"""
|
||||
@@ -328,7 +328,7 @@ class TestTraceListenerSetup:
|
||||
with (
|
||||
patch.dict(os.environ, {"CREWAI_TRACING_ENABLED": "true"}),
|
||||
patch(
|
||||
"crewai.utilities.events.listeners.tracing.trace_listener.TraceCollectionListener._check_authenticated",
|
||||
"crewai.events.listeners.tracing.trace_listener.TraceCollectionListener._check_authenticated",
|
||||
return_value=False,
|
||||
),
|
||||
):
|
||||
@@ -357,7 +357,7 @@ class TestTraceListenerSetup:
|
||||
with (
|
||||
patch.dict(os.environ, {"CREWAI_TRACING_ENABLED": "true"}),
|
||||
patch(
|
||||
"crewai.utilities.events.listeners.tracing.trace_batch_manager.PlusAPI"
|
||||
"crewai.events.listeners.tracing.trace_batch_manager.PlusAPI"
|
||||
) as mock_plus_api_class,
|
||||
):
|
||||
mock_plus_api_instance = MagicMock()
|
||||
@@ -393,13 +393,13 @@ class TestTraceListenerSetup:
|
||||
# Helper method to ensure cleanup
|
||||
def teardown_method(self):
|
||||
"""Cleanup after each test method"""
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
|
||||
crewai_event_bus._handlers.clear()
|
||||
|
||||
@classmethod
|
||||
def teardown_class(cls):
|
||||
"""Final cleanup after all tests in this class"""
|
||||
from crewai.utilities.events import crewai_event_bus
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
|
||||
crewai_event_bus._handlers.clear()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from unittest.mock import Mock
|
||||
|
||||
from crewai.utilities.events.base_events import BaseEvent
|
||||
from crewai.utilities.events.crewai_event_bus import crewai_event_bus
|
||||
from crewai.events.base_events import BaseEvent
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
|
||||
|
||||
class TestEvent(BaseEvent):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
from rich.tree import Tree
|
||||
from rich.live import Live
|
||||
from crewai.utilities.events.utils.console_formatter import ConsoleFormatter
|
||||
from crewai.events.utils.console_formatter import ConsoleFormatter
|
||||
|
||||
|
||||
class TestConsoleFormatterPauseResume:
|
||||
@@ -10,78 +10,78 @@ class TestConsoleFormatterPauseResume:
|
||||
def test_pause_live_updates_with_active_session(self):
|
||||
"""Test pausing when Live session is active."""
|
||||
formatter = ConsoleFormatter()
|
||||
|
||||
|
||||
mock_live = MagicMock(spec=Live)
|
||||
formatter._live = mock_live
|
||||
formatter._live_paused = False
|
||||
|
||||
|
||||
formatter.pause_live_updates()
|
||||
|
||||
|
||||
mock_live.stop.assert_called_once()
|
||||
assert formatter._live_paused
|
||||
|
||||
def test_pause_live_updates_when_already_paused(self):
|
||||
"""Test pausing when already paused does nothing."""
|
||||
formatter = ConsoleFormatter()
|
||||
|
||||
|
||||
mock_live = MagicMock(spec=Live)
|
||||
formatter._live = mock_live
|
||||
formatter._live_paused = True
|
||||
|
||||
|
||||
formatter.pause_live_updates()
|
||||
|
||||
|
||||
mock_live.stop.assert_not_called()
|
||||
assert formatter._live_paused
|
||||
|
||||
def test_pause_live_updates_with_no_session(self):
|
||||
"""Test pausing when no Live session exists."""
|
||||
formatter = ConsoleFormatter()
|
||||
|
||||
|
||||
formatter._live = None
|
||||
formatter._live_paused = False
|
||||
|
||||
|
||||
formatter.pause_live_updates()
|
||||
|
||||
|
||||
assert formatter._live_paused
|
||||
|
||||
def test_resume_live_updates_when_paused(self):
|
||||
"""Test resuming when paused."""
|
||||
formatter = ConsoleFormatter()
|
||||
|
||||
|
||||
formatter._live_paused = True
|
||||
|
||||
|
||||
formatter.resume_live_updates()
|
||||
|
||||
|
||||
assert not formatter._live_paused
|
||||
|
||||
def test_resume_live_updates_when_not_paused(self):
|
||||
"""Test resuming when not paused does nothing."""
|
||||
formatter = ConsoleFormatter()
|
||||
|
||||
|
||||
formatter._live_paused = False
|
||||
|
||||
|
||||
formatter.resume_live_updates()
|
||||
|
||||
|
||||
assert not formatter._live_paused
|
||||
|
||||
def test_print_after_resume_restarts_live_session(self):
|
||||
"""Test that printing a Tree after resume creates new Live session."""
|
||||
formatter = ConsoleFormatter()
|
||||
|
||||
|
||||
formatter._live_paused = True
|
||||
formatter._live = None
|
||||
|
||||
|
||||
formatter.resume_live_updates()
|
||||
assert not formatter._live_paused
|
||||
|
||||
|
||||
tree = Tree("Test")
|
||||
|
||||
with patch('crewai.utilities.events.utils.console_formatter.Live') as mock_live_class:
|
||||
|
||||
with patch("crewai.events.utils.console_formatter.Live") as mock_live_class:
|
||||
mock_live_instance = MagicMock()
|
||||
mock_live_class.return_value = mock_live_instance
|
||||
|
||||
|
||||
formatter.print(tree)
|
||||
|
||||
|
||||
mock_live_class.assert_called_once()
|
||||
mock_live_instance.start.assert_called_once()
|
||||
assert formatter._live == mock_live_instance
|
||||
@@ -89,28 +89,28 @@ class TestConsoleFormatterPauseResume:
|
||||
def test_multiple_pause_resume_cycles(self):
|
||||
"""Test multiple pause/resume cycles work correctly."""
|
||||
formatter = ConsoleFormatter()
|
||||
|
||||
|
||||
mock_live = MagicMock(spec=Live)
|
||||
formatter._live = mock_live
|
||||
formatter._live_paused = False
|
||||
|
||||
|
||||
formatter.pause_live_updates()
|
||||
assert formatter._live_paused
|
||||
mock_live.stop.assert_called_once()
|
||||
assert formatter._live is None # Live session should be cleared
|
||||
|
||||
|
||||
formatter.resume_live_updates()
|
||||
assert not formatter._live_paused
|
||||
|
||||
|
||||
formatter.pause_live_updates()
|
||||
assert formatter._live_paused
|
||||
|
||||
|
||||
formatter.resume_live_updates()
|
||||
assert not formatter._live_paused
|
||||
|
||||
def test_pause_resume_state_initialization(self):
|
||||
"""Test that _live_paused is properly initialized."""
|
||||
formatter = ConsoleFormatter()
|
||||
|
||||
assert hasattr(formatter, '_live_paused')
|
||||
|
||||
assert hasattr(formatter, "_live_paused")
|
||||
assert not formatter._live_paused
|
||||
|
||||
@@ -11,12 +11,12 @@ from crewai.flow.flow import Flow, listen, start
|
||||
from crewai.llm import LLM
|
||||
from crewai.task import Task
|
||||
from crewai.tools.base_tool import BaseTool
|
||||
from crewai.utilities.events.agent_events import (
|
||||
from crewai.events.types.agent_events import (
|
||||
AgentExecutionCompletedEvent,
|
||||
AgentExecutionErrorEvent,
|
||||
AgentExecutionStartedEvent,
|
||||
)
|
||||
from crewai.utilities.events.crew_events import (
|
||||
from crewai.events.types.crew_events import (
|
||||
CrewKickoffCompletedEvent,
|
||||
CrewKickoffFailedEvent,
|
||||
CrewKickoffStartedEvent,
|
||||
@@ -24,28 +24,28 @@ from crewai.utilities.events.crew_events import (
|
||||
CrewTestResultEvent,
|
||||
CrewTestStartedEvent,
|
||||
)
|
||||
from crewai.utilities.events.crewai_event_bus import crewai_event_bus
|
||||
from crewai.utilities.events.event_listener import EventListener
|
||||
from crewai.utilities.events.event_types import ToolUsageFinishedEvent
|
||||
from crewai.utilities.events.flow_events import (
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.event_listener import EventListener
|
||||
from crewai.events.types.tool_usage_events import ToolUsageFinishedEvent
|
||||
from crewai.events.types.flow_events import (
|
||||
FlowCreatedEvent,
|
||||
FlowFinishedEvent,
|
||||
FlowStartedEvent,
|
||||
MethodExecutionFailedEvent,
|
||||
MethodExecutionStartedEvent,
|
||||
)
|
||||
from crewai.utilities.events.llm_events import (
|
||||
from crewai.events.types.llm_events import (
|
||||
LLMCallCompletedEvent,
|
||||
LLMCallFailedEvent,
|
||||
LLMCallStartedEvent,
|
||||
LLMStreamChunkEvent,
|
||||
)
|
||||
from crewai.utilities.events.task_events import (
|
||||
from crewai.events.types.task_events import (
|
||||
TaskCompletedEvent,
|
||||
TaskFailedEvent,
|
||||
TaskStartedEvent,
|
||||
)
|
||||
from crewai.utilities.events.tool_usage_events import (
|
||||
from crewai.events.types.tool_usage_events import (
|
||||
ToolUsageErrorEvent,
|
||||
)
|
||||
|
||||
@@ -114,9 +114,7 @@ def test_crew_emits_start_kickoff_event(
|
||||
mock_telemetry.task_ended = Mock(return_value=mock_span)
|
||||
|
||||
# Patch the Telemetry class to return our mock
|
||||
with patch(
|
||||
"crewai.utilities.events.event_listener.Telemetry", return_value=mock_telemetry
|
||||
):
|
||||
with patch("crewai.events.event_listener.Telemetry", return_value=mock_telemetry):
|
||||
# Now when Crew creates EventListener, it will use our mocked telemetry
|
||||
crew = Crew(agents=[base_agent], tasks=[base_task], name="TestCrew")
|
||||
crew.kickoff()
|
||||
@@ -241,9 +239,7 @@ def test_crew_emits_end_task_event(
|
||||
mock_telemetry.crew_execution_span = Mock()
|
||||
mock_telemetry.end_crew = Mock()
|
||||
|
||||
with patch(
|
||||
"crewai.utilities.events.event_listener.Telemetry", return_value=mock_telemetry
|
||||
):
|
||||
with patch("crewai.events.event_listener.Telemetry", return_value=mock_telemetry):
|
||||
crew = Crew(agents=[base_agent], tasks=[base_task], name="TestCrew")
|
||||
crew.kickoff()
|
||||
|
||||
@@ -455,9 +451,7 @@ def test_flow_emits_start_event(reset_event_listener_singleton):
|
||||
mock_telemetry.flow_creation_span = Mock()
|
||||
mock_telemetry.set_tracer = Mock()
|
||||
|
||||
with patch(
|
||||
"crewai.utilities.events.event_listener.Telemetry", return_value=mock_telemetry
|
||||
):
|
||||
with patch("crewai.events.event_listener.Telemetry", return_value=mock_telemetry):
|
||||
# Force creation of EventListener singleton with mocked telemetry
|
||||
_ = EventListener()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user