Address GitHub review feedback for selective execution feature

- Enhanced error messages with specific action and available tags information
- Improved type safety by removing problematic TaskSelectorType alias
- Added comprehensive tag validation with normalization in Task class
- Fixed edge case handling for untagged tasks in tag selector
- Added test for invalid tag types validation
- Maintained backward compatibility while optimizing performance

Co-Authored-By: João <joao@crewai.com>
This commit is contained in:
Devin AI
2025-06-03 17:17:00 +00:00
parent 0e963b6de1
commit b262f05c97
6 changed files with 215 additions and 26 deletions

View File

@@ -848,7 +848,12 @@ class Crew(FlowTrackable, BaseModel):
if self.task_selector(self._inputs, task)
]
if not filtered_tasks:
raise ValueError("No tasks match the selection criteria. At least one task must be selected for execution.")
action = self._inputs.get('action', 'unknown')
available_tags = [task.tags for task in tasks if task.tags]
raise ValueError(
f"No tasks match the selection criteria for action '{action}'. "
f"Available tags: {available_tags}"
)
tasks = filtered_tasks
task_outputs: List[TaskOutput] = []
@@ -1553,13 +1558,14 @@ class Crew(FlowTrackable, BaseModel):
"""
def selector(inputs: Dict[str, Any], task: Task) -> bool:
action = inputs.get(action_key)
if not action or not task.tags:
if not action:
return True
if not task.tags:
return True # Execute untagged tasks when action is specified
if tag_mapping and action in tag_mapping:
required_tags = tag_mapping[action]
return any(tag in task.tags for tag in required_tags)
else:
return action in task.tags
return action in task.tags
return selector

View File

@@ -143,6 +143,17 @@ class Task(BaseModel):
default=None,
description="Tags to categorize this task for selective execution.",
)
@field_validator('tags')
@classmethod
def validate_tags(cls, v: Optional[List[str]]) -> Optional[List[str]]:
if v is not None:
if not all(isinstance(tag, str) for tag in v):
raise ValueError("All tags must be strings")
if not all(tag.strip() for tag in v):
raise ValueError("Tags cannot be empty strings")
return [tag.lower().strip() for tag in v] # Normalize tags
return v
converter_cls: Optional[Type[Converter]] = Field(
description="A converter class used to export structured output",
default=None,