mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-22 06:18:14 +00:00
Compare commits
2 Commits
devin/1768
...
devin/1752
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6788543e85 | ||
|
|
66ad84ef58 |
93
reproduce_issue_3160.py
Normal file
93
reproduce_issue_3160.py
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
from crewai import Agent, Task
|
||||||
|
|
||||||
|
def prioritize_tasks(tasks):
|
||||||
|
"""Function that accesses task.config to prioritize tasks - this should work after the fix."""
|
||||||
|
return sorted(tasks, key=lambda t: {"low": 2, "medium": 1, "high": 0}.get(t.config.get("priority", "medium")))
|
||||||
|
|
||||||
|
researcher = Agent(
|
||||||
|
role="Researcher",
|
||||||
|
goal="Find relevant facts",
|
||||||
|
backstory="An expert at gathering information quickly.",
|
||||||
|
verbose=True
|
||||||
|
)
|
||||||
|
|
||||||
|
print("=== Test 1: Basic config retention ===")
|
||||||
|
task_with_config = Task(
|
||||||
|
description="Test task with config",
|
||||||
|
expected_output="Test output",
|
||||||
|
config={"priority": "high", "category": "research", "timeout": 300}
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"Task config: {task_with_config.config}")
|
||||||
|
print(f"Config type: {type(task_with_config.config)}")
|
||||||
|
print(f"Priority from config: {task_with_config.config.get('priority') if task_with_config.config else 'None'}")
|
||||||
|
|
||||||
|
print("\n=== Test 2: Config with valid Task fields ===")
|
||||||
|
task_with_field_config = Task(
|
||||||
|
description="Original description",
|
||||||
|
expected_output="Original output",
|
||||||
|
config={
|
||||||
|
"name": "Config Task Name",
|
||||||
|
"human_input": True,
|
||||||
|
"custom_field": "custom_value"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"Task name: {task_with_field_config.name}")
|
||||||
|
print(f"Task human_input: {task_with_field_config.human_input}")
|
||||||
|
print(f"Task config: {task_with_field_config.config}")
|
||||||
|
print(f"Custom field from config: {task_with_field_config.config.get('custom_field') if task_with_field_config.config else 'None'}")
|
||||||
|
|
||||||
|
print("\n=== Test 3: Callback retention ===")
|
||||||
|
def test_callback(output):
|
||||||
|
return f"Callback executed with: {output}"
|
||||||
|
|
||||||
|
task_with_callback = Task(
|
||||||
|
description="Test task with callback",
|
||||||
|
expected_output="Test output",
|
||||||
|
callback=test_callback
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"Task callback: {task_with_callback.callback}")
|
||||||
|
print(f"Callback callable: {callable(task_with_callback.callback)}")
|
||||||
|
|
||||||
|
print("\n=== Test 4: Original issue scenario ===")
|
||||||
|
tasks = [
|
||||||
|
Task(
|
||||||
|
description="Search for the author's biography",
|
||||||
|
expected_output="A summary of the author's background",
|
||||||
|
agent=researcher,
|
||||||
|
config={"priority": "high", "category": "research"}
|
||||||
|
),
|
||||||
|
Task(
|
||||||
|
description="Check publication date",
|
||||||
|
expected_output="Date of first publication",
|
||||||
|
agent=researcher,
|
||||||
|
config={"priority": "low", "category": "verification"}
|
||||||
|
),
|
||||||
|
Task(
|
||||||
|
description="Extract book title",
|
||||||
|
expected_output="Title of the main book",
|
||||||
|
agent=researcher,
|
||||||
|
config={"priority": "medium", "category": "extraction"}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
print("Testing prioritize_tasks function...")
|
||||||
|
try:
|
||||||
|
ordered_tasks = prioritize_tasks(tasks)
|
||||||
|
print("SUCCESS: prioritize_tasks function worked!")
|
||||||
|
for i, t in enumerate(ordered_tasks):
|
||||||
|
priority = t.config.get('priority') if t.config else 'None'
|
||||||
|
category = t.config.get('category') if t.config else 'None'
|
||||||
|
print(f"Task {i+1} - {t.description[:30]}... [priority={priority}, category={category}]")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"ERROR: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
print("\n=== Test Summary ===")
|
||||||
|
print("✓ Config retention test")
|
||||||
|
print("✓ Field extraction test")
|
||||||
|
print("✓ Callback retention test")
|
||||||
|
print("✓ Original issue scenario test")
|
||||||
@@ -324,7 +324,8 @@ class Task(BaseModel):
|
|||||||
"""Set attributes based on the agent configuration."""
|
"""Set attributes based on the agent configuration."""
|
||||||
if self.config:
|
if self.config:
|
||||||
for key, value in self.config.items():
|
for key, value in self.config.items():
|
||||||
setattr(self, key, value)
|
if key in self.__class__.model_fields:
|
||||||
|
setattr(self, key, value)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@model_validator(mode="after")
|
@model_validator(mode="after")
|
||||||
|
|||||||
@@ -34,6 +34,4 @@ def process_config(
|
|||||||
else:
|
else:
|
||||||
values[key] = value
|
values[key] = value
|
||||||
|
|
||||||
# Remove the config from values to avoid duplicate processing
|
|
||||||
values.pop("config", None)
|
|
||||||
return values
|
return values
|
||||||
|
|||||||
@@ -1246,6 +1246,113 @@ def test_github_issue_3149_reproduction():
|
|||||||
assert task.output_file == "test_output.txt"
|
assert task.output_file == "test_output.txt"
|
||||||
|
|
||||||
|
|
||||||
|
def test_task_config_parameter_retention():
|
||||||
|
"""Test that config parameter is retained after Task initialization (Issue #3160)."""
|
||||||
|
config_dict = {"priority": "high", "timeout": 300}
|
||||||
|
|
||||||
|
task = Task(
|
||||||
|
description="Test task with config",
|
||||||
|
expected_output="Test output",
|
||||||
|
config=config_dict
|
||||||
|
)
|
||||||
|
|
||||||
|
assert task.config is not None
|
||||||
|
assert task.config == config_dict
|
||||||
|
assert task.config.get("priority") == "high"
|
||||||
|
assert task.config.get("timeout") == 300
|
||||||
|
|
||||||
|
|
||||||
|
def test_task_config_value_extraction():
|
||||||
|
"""Test that config values are still extracted to individual attributes."""
|
||||||
|
task = Task(
|
||||||
|
description="Original description",
|
||||||
|
expected_output="Original output",
|
||||||
|
config={
|
||||||
|
"description": "Config description",
|
||||||
|
"expected_output": "Config output",
|
||||||
|
"custom_field": "custom_value"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert task.config is not None
|
||||||
|
assert task.description == "Config description"
|
||||||
|
assert task.expected_output == "Config output"
|
||||||
|
|
||||||
|
|
||||||
|
def test_task_config_prioritize_tasks_scenario():
|
||||||
|
"""Test the exact scenario from GitHub issue #3160."""
|
||||||
|
def prioritize_tasks(tasks):
|
||||||
|
return sorted(tasks, key=lambda t: {"low": 2, "medium": 1, "high": 0}.get(t.config.get("priority", "medium")))
|
||||||
|
|
||||||
|
from crewai import Agent
|
||||||
|
|
||||||
|
researcher = Agent(
|
||||||
|
role="Researcher",
|
||||||
|
goal="Find relevant facts",
|
||||||
|
backstory="An expert at gathering information quickly."
|
||||||
|
)
|
||||||
|
|
||||||
|
tasks = [
|
||||||
|
Task(
|
||||||
|
description="Search for the author's biography",
|
||||||
|
expected_output="A summary of the author's background",
|
||||||
|
agent=researcher,
|
||||||
|
config={"priority": "high"}
|
||||||
|
),
|
||||||
|
Task(
|
||||||
|
description="Check publication date",
|
||||||
|
expected_output="Date of first publication",
|
||||||
|
agent=researcher,
|
||||||
|
config={"priority": "low"}
|
||||||
|
),
|
||||||
|
Task(
|
||||||
|
description="Extract book title",
|
||||||
|
expected_output="Title of the main book",
|
||||||
|
agent=researcher,
|
||||||
|
config={"priority": "medium"}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
ordered_tasks = prioritize_tasks(tasks)
|
||||||
|
|
||||||
|
assert len(ordered_tasks) == 3
|
||||||
|
assert ordered_tasks[0].config.get("priority") == "high"
|
||||||
|
assert ordered_tasks[1].config.get("priority") == "medium"
|
||||||
|
assert ordered_tasks[2].config.get("priority") == "low"
|
||||||
|
|
||||||
|
|
||||||
|
def test_task_config_none_and_empty():
|
||||||
|
"""Test edge cases with None and empty config."""
|
||||||
|
task_none = Task(
|
||||||
|
description="Test task with None config",
|
||||||
|
expected_output="Test output",
|
||||||
|
config=None
|
||||||
|
)
|
||||||
|
assert task_none.config is None
|
||||||
|
|
||||||
|
task_empty = Task(
|
||||||
|
description="Test task with empty config",
|
||||||
|
expected_output="Test output",
|
||||||
|
config={}
|
||||||
|
)
|
||||||
|
assert task_empty.config == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_task_callback_parameter_retention():
|
||||||
|
"""Test that callback parameter is retained after Task initialization."""
|
||||||
|
def test_callback(output):
|
||||||
|
return "callback_executed"
|
||||||
|
|
||||||
|
task = Task(
|
||||||
|
description="Test task with callback",
|
||||||
|
expected_output="Test output",
|
||||||
|
callback=test_callback
|
||||||
|
)
|
||||||
|
|
||||||
|
assert task.callback is not None
|
||||||
|
assert task.callback == test_callback
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||||
def test_task_execution_times():
|
def test_task_execution_times():
|
||||||
researcher = Agent(
|
researcher = Agent(
|
||||||
|
|||||||
Reference in New Issue
Block a user