Add name and expected_output to TaskOutput (#1199)

* Add name and expected_output to TaskOutput

This commit adds task information to the TaskOutput class. This is
useful to provide extra context to callbacks.

* Populate task name from function names

This commit populates task name from function names when using
annotations.
This commit is contained in:
Vini Brasil
2024-08-15 22:24:41 +01:00
committed by GitHub
parent d0707fac91
commit dbf2570353
5 changed files with 43 additions and 2 deletions

View File

@@ -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):

View File

@@ -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,

View File

@@ -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(

View File

@@ -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"

View File

@@ -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