diff --git a/src/crewai/project/annotations.py b/src/crewai/project/annotations.py index 6b2c64fb3..030341c32 100644 --- a/src/crewai/project/annotations.py +++ b/src/crewai/project/annotations.py @@ -6,12 +6,20 @@ def task(func): task.registration_order = [] func.is_task = True - wrapped_func = memoize(func) + memoized_func = memoize(func) # Append the function name to the registration order list task.registration_order.append(func.__name__) - return wrapped_func + def wrapper(*args, **kwargs): + result = memoized_func(*args, **kwargs) + + if not result.name: + result.name = func.__name__ + + return result + + return wrapper def agent(func): diff --git a/src/crewai/task.py b/src/crewai/task.py index 9b5c598ce..3c8987b64 100644 --- a/src/crewai/task.py +++ b/src/crewai/task.py @@ -240,7 +240,9 @@ class Task(BaseModel): pydantic_output, json_output = self._export_output(result) task_output = TaskOutput( + name=self.name, description=self.description, + expected_output=self.expected_output, raw=result, pydantic=pydantic_output, json_dict=json_output, diff --git a/src/crewai/tasks/task_output.py b/src/crewai/tasks/task_output.py index 604dab6e8..b0e8aecd4 100644 --- a/src/crewai/tasks/task_output.py +++ b/src/crewai/tasks/task_output.py @@ -10,6 +10,10 @@ class TaskOutput(BaseModel): """Class that represents the result of a task.""" description: str = Field(description="Description of the task") + name: Optional[str] = Field(description="Name of the task", default=None) + expected_output: Optional[str] = Field( + description="Expected output of the task", default=None + ) summary: Optional[str] = Field(description="Summary of the task", default=None) raw: str = Field(description="Raw output of the task", default="") pydantic: Optional[BaseModel] = Field( diff --git a/tests/project_test.py b/tests/project_test.py index d487bdb33..188ba024d 100644 --- a/tests/project_test.py +++ b/tests/project_test.py @@ -14,6 +14,14 @@ class SimpleCrew: def simple_task(self): return Task(description="Simple Description", expected_output="Simple Output") + @task + def custom_named_task(self): + return Task( + description="Simple Description", + expected_output="Simple Output", + name="Custom", + ) + def test_agent_memoization(): crew = SimpleCrew() @@ -33,3 +41,15 @@ def test_task_memoization(): assert ( first_call_result is second_call_result ), "Task memoization is not working as expected" + + +def test_task_name(): + simple_task = SimpleCrew().simple_task() + assert ( + simple_task.name == "simple_task" + ), "Task name is not inferred from function name as expected" + + custom_named_task = SimpleCrew().custom_named_task() + assert ( + custom_named_task.name == "Custom" + ), "Custom task name is not being set as expected" diff --git a/tests/task_test.py b/tests/task_test.py index 5bfdaf4ac..e4ee23e9f 100644 --- a/tests/task_test.py +++ b/tests/task_test.py @@ -98,6 +98,7 @@ def test_task_callback(): task_completed = MagicMock(return_value="done") task = Task( + name="Brainstorm", description="Give me a list of 5 interesting ideas to explore for na article, what makes them unique and interesting.", expected_output="Bullet point list of 5 interesting ideas.", agent=researcher, @@ -109,6 +110,10 @@ def test_task_callback(): task.execute_sync(agent=researcher) task_completed.assert_called_once_with(task.output) + assert task.output.description == task.description + assert task.output.expected_output == task.expected_output + assert task.output.name == task.name + def test_task_callback_returns_task_output(): from crewai.tasks.output_format import OutputFormat @@ -149,6 +154,8 @@ def test_task_callback_returns_task_output(): "json_dict": None, "agent": researcher.role, "summary": "Give me a list of 5 interesting ideas to explore...", + "name": None, + "expected_output": "Bullet point list of 5 interesting ideas.", "output_format": OutputFormat.RAW, } assert output_dict == expected_output