mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-25 08:08:14 +00:00
Fix issue #2530: Multiple conditional tasks using correct previous output
Co-Authored-By: Joe Moura <joao@crewai.com>
This commit is contained in:
@@ -783,7 +783,26 @@ class Crew(BaseModel):
|
|||||||
task_outputs = self._process_async_tasks(futures, was_replayed)
|
task_outputs = self._process_async_tasks(futures, was_replayed)
|
||||||
futures.clear()
|
futures.clear()
|
||||||
|
|
||||||
previous_output = task_outputs[task_index - 1] if task_outputs else None
|
if task.context and len(task.context) > 0:
|
||||||
|
context_task_outputs = []
|
||||||
|
for context_task in task.context:
|
||||||
|
context_task_index = self._find_task_index(context_task)
|
||||||
|
if context_task_index != -1 and context_task_index < task_index:
|
||||||
|
for output in task_outputs:
|
||||||
|
if output.description == context_task.description:
|
||||||
|
context_task_outputs.append(output)
|
||||||
|
break
|
||||||
|
previous_output = context_task_outputs[-1] if context_task_outputs else None
|
||||||
|
else:
|
||||||
|
non_conditional_outputs = []
|
||||||
|
for i in range(task_index):
|
||||||
|
if i < len(self.tasks) and not isinstance(self.tasks[i], ConditionalTask):
|
||||||
|
for output in task_outputs:
|
||||||
|
if output.description == self.tasks[i].description:
|
||||||
|
non_conditional_outputs.append(output)
|
||||||
|
break
|
||||||
|
previous_output = non_conditional_outputs[-1] if non_conditional_outputs else (task_outputs[task_index - 1] if task_outputs and task_index > 0 and task_index <= len(task_outputs) else None)
|
||||||
|
|
||||||
if previous_output is not None and not task.should_execute(previous_output):
|
if previous_output is not None and not task.should_execute(previous_output):
|
||||||
self._logger.log(
|
self._logger.log(
|
||||||
"debug",
|
"debug",
|
||||||
|
|||||||
116
tests/test_multiple_conditional_tasks.py
Normal file
116
tests/test_multiple_conditional_tasks.py
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
"""Test for multiple conditional tasks."""
|
||||||
|
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from crewai.agent import Agent
|
||||||
|
from crewai.crew import Crew
|
||||||
|
from crewai.task import Task
|
||||||
|
from crewai.tasks.conditional_task import ConditionalTask
|
||||||
|
from crewai.tasks.output_format import OutputFormat
|
||||||
|
from crewai.tasks.task_output import TaskOutput
|
||||||
|
|
||||||
|
|
||||||
|
def test_multiple_conditional_tasks():
|
||||||
|
"""Test that multiple conditional tasks are evaluated correctly."""
|
||||||
|
# Create agents for the tasks
|
||||||
|
agent1 = Agent(
|
||||||
|
role="Research Analyst",
|
||||||
|
goal="Find information",
|
||||||
|
backstory="You're a researcher",
|
||||||
|
verbose=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
agent2 = Agent(
|
||||||
|
role="Data Analyst",
|
||||||
|
goal="Process information",
|
||||||
|
backstory="You process data",
|
||||||
|
verbose=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
agent3 = Agent(
|
||||||
|
role="Report Writer",
|
||||||
|
goal="Write reports",
|
||||||
|
backstory="You write reports",
|
||||||
|
verbose=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create tasks
|
||||||
|
task1 = Task(
|
||||||
|
description="Task 1",
|
||||||
|
expected_output="Output 1",
|
||||||
|
agent=agent1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# First conditional task should check task1's output
|
||||||
|
condition1_mock = MagicMock()
|
||||||
|
task2 = ConditionalTask(
|
||||||
|
description="Conditional Task 2",
|
||||||
|
expected_output="Output 2",
|
||||||
|
agent=agent2,
|
||||||
|
condition=condition1_mock,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Second conditional task should check task1's output, not task2's
|
||||||
|
condition2_mock = MagicMock()
|
||||||
|
task3 = ConditionalTask(
|
||||||
|
description="Conditional Task 3",
|
||||||
|
expected_output="Output 3",
|
||||||
|
agent=agent3,
|
||||||
|
condition=condition2_mock,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create crew with the tasks
|
||||||
|
crew = Crew(
|
||||||
|
agents=[agent1, agent2, agent3],
|
||||||
|
tasks=[task1, task2, task3],
|
||||||
|
verbose=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test the first conditional task
|
||||||
|
task1_output = TaskOutput(
|
||||||
|
description="Task 1",
|
||||||
|
raw="Task 1 output",
|
||||||
|
agent=agent1.role,
|
||||||
|
output_format=OutputFormat.RAW,
|
||||||
|
)
|
||||||
|
|
||||||
|
condition1_mock.return_value = True # Task should execute
|
||||||
|
result1 = crew._handle_conditional_task(
|
||||||
|
task=task2,
|
||||||
|
task_outputs=[task1_output],
|
||||||
|
futures=[],
|
||||||
|
task_index=1,
|
||||||
|
was_replayed=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify the condition was called with task1's output
|
||||||
|
condition1_mock.assert_called_once()
|
||||||
|
args1 = condition1_mock.call_args[0][0]
|
||||||
|
assert args1.raw == "Task 1 output"
|
||||||
|
assert result1 is None # Task should execute, so no skipped output
|
||||||
|
|
||||||
|
# Test the second conditional task
|
||||||
|
task2_output = TaskOutput(
|
||||||
|
description="Conditional Task 2",
|
||||||
|
raw="Task 2 output",
|
||||||
|
agent=agent2.role,
|
||||||
|
output_format=OutputFormat.RAW,
|
||||||
|
)
|
||||||
|
|
||||||
|
condition2_mock.return_value = True # Task should execute
|
||||||
|
result2 = crew._handle_conditional_task(
|
||||||
|
task=task3,
|
||||||
|
task_outputs=[task1_output, task2_output],
|
||||||
|
futures=[],
|
||||||
|
task_index=2,
|
||||||
|
was_replayed=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify the condition was called with task1's output, not task2's
|
||||||
|
condition2_mock.assert_called_once()
|
||||||
|
args2 = condition2_mock.call_args[0][0]
|
||||||
|
assert args2.raw == "Task 1 output" # Should be task1's output
|
||||||
|
assert args2.raw != "Task 2 output" # Should not be task2's output
|
||||||
|
assert result2 is None # Task should execute, so no skipped output
|
||||||
Reference in New Issue
Block a user