chore: add deprecation notices to Task.max_retries (#3379)
Some checks failed
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled

This commit is contained in:
Lucas Gomide
2025-08-26 18:24:58 -03:00
committed by GitHub
parent 7addda9398
commit 88d2968fd5
6 changed files with 36 additions and 15 deletions

View File

@@ -59,6 +59,7 @@ crew = Crew(
| **Output Pydantic** _(optional)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | A Pydantic model for task output. | | **Output Pydantic** _(optional)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | A Pydantic model for task output. |
| **Callback** _(optional)_ | `callback` | `Optional[Any]` | Function/object to be executed after task completion. | | **Callback** _(optional)_ | `callback` | `Optional[Any]` | Function/object to be executed after task completion. |
| **Guardrail** _(optional)_ | `guardrail` | `Optional[Callable]` | Function to validate task output before proceeding to next task. | | **Guardrail** _(optional)_ | `guardrail` | `Optional[Callable]` | Function to validate task output before proceeding to next task. |
| **Guardrail Max Retries** _(optional)_ | `guardrail_max_retries` | `Optional[int]` | Maximum number of retries when guardrail validation fails. Defaults to 3. |
## Creating Tasks ## Creating Tasks
@@ -452,7 +453,7 @@ task = Task(
expected_output="A valid JSON object", expected_output="A valid JSON object",
agent=analyst, agent=analyst,
guardrail=validate_json_output, guardrail=validate_json_output,
max_retries=3 # Limit retry attempts guardrail_max_retries=3 # Limit retry attempts
) )
``` ```

View File

@@ -59,6 +59,7 @@ crew = Crew(
| **Pydantic 출력** _(선택 사항)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | 태스크 출력용 Pydantic 모델입니다. | | **Pydantic 출력** _(선택 사항)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | 태스크 출력용 Pydantic 모델입니다. |
| **콜백** _(선택 사항)_ | `callback` | `Optional[Any]` | 태스크 완료 후 실행할 함수/객체입니다. | | **콜백** _(선택 사항)_ | `callback` | `Optional[Any]` | 태스크 완료 후 실행할 함수/객체입니다. |
| **가드레일** _(선택 사항)_ | `guardrail` | `Optional[Callable]` | 다음 태스크로 진행하기 전에 태스크 출력을 검증하는 함수입니다. | | **가드레일** _(선택 사항)_ | `guardrail` | `Optional[Callable]` | 다음 태스크로 진행하기 전에 태스크 출력을 검증하는 함수입니다. |
| **가드레일 최대 재시도** _(선택 사항)_ | `guardrail_max_retries` | `Optional[int]` | 가드레일 검증 실패 시 최대 재시도 횟수입니다. 기본값은 3입니다. |
## 작업 생성하기 ## 작업 생성하기
@@ -448,7 +449,7 @@ task = Task(
expected_output="A valid JSON object", expected_output="A valid JSON object",
agent=analyst, agent=analyst,
guardrail=validate_json_output, guardrail=validate_json_output,
max_retries=3 # Limit retry attempts guardrail_max_retries=3 # 재시도 횟수 제한
) )
``` ```

View File

@@ -59,6 +59,7 @@ crew = Crew(
| **Output Pydantic** _(opcional)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | Um modelo Pydantic para a saída da tarefa. | | **Output Pydantic** _(opcional)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | Um modelo Pydantic para a saída da tarefa. |
| **Callback** _(opcional)_ | `callback` | `Optional[Any]` | Função/objeto a ser executado após a conclusão da tarefa. | | **Callback** _(opcional)_ | `callback` | `Optional[Any]` | Função/objeto a ser executado após a conclusão da tarefa. |
| **Guardrail** _(opcional)_ | `guardrail` | `Optional[Callable]` | Função para validar a saída da tarefa antes de prosseguir para a próxima tarefa. | | **Guardrail** _(opcional)_ | `guardrail` | `Optional[Callable]` | Função para validar a saída da tarefa antes de prosseguir para a próxima tarefa. |
| **Max Tentativas Guardrail** _(opcional)_ | `guardrail_max_retries` | `Optional[int]` | Número máximo de tentativas quando a validação do guardrail falha. Padrão é 3. |
## Criando Tarefas ## Criando Tarefas
@@ -450,7 +451,7 @@ task = Task(
expected_output="Um objeto JSON válido", expected_output="Um objeto JSON válido",
agent=analyst, agent=analyst,
guardrail=validate_json_output, guardrail=validate_json_output,
max_retries=3 # Limite de tentativas guardrail_max_retries=3 # Limite de tentativas
) )
``` ```
@@ -935,7 +936,7 @@ task = Task(
description="Gerar dados", description="Gerar dados",
expected_output="Dados válidos", expected_output="Dados válidos",
guardrail=validate_data, guardrail=validate_data,
max_retries=5 # Sobrescreve o limite padrão de tentativas guardrail_max_retries=5 # Sobrescreve o limite padrão de tentativas
) )
``` ```

View File

@@ -4,6 +4,7 @@ import json
import logging import logging
import threading import threading
import uuid import uuid
import warnings
from concurrent.futures import Future from concurrent.futures import Future
from copy import copy from copy import copy
from hashlib import md5 from hashlib import md5
@@ -157,8 +158,13 @@ class Task(BaseModel):
default=None, default=None,
description="Function or string description of a guardrail to validate task output before proceeding to next task", description="Function or string description of a guardrail to validate task output before proceeding to next task",
) )
max_retries: int = Field( max_retries: Optional[int] = Field(
default=3, description="Maximum number of retries when guardrail fails" default=None,
description="[DEPRECATED] Maximum number of retries when guardrail fails. Use guardrail_max_retries instead. Will be removed in v1.0.0"
)
guardrail_max_retries: int = Field(
default=3,
description="Maximum number of retries when guardrail fails"
) )
retry_count: int = Field(default=0, description="Current number of retries") retry_count: int = Field(default=0, description="Current number of retries")
start_time: Optional[datetime.datetime] = Field( start_time: Optional[datetime.datetime] = Field(
@@ -354,6 +360,18 @@ class Task(BaseModel):
) )
return self return self
@model_validator(mode="after")
def handle_max_retries_deprecation(self):
if self.max_retries is not None:
warnings.warn(
"The 'max_retries' parameter is deprecated and will be removed in CrewAI v1.0.0. "
"Please use 'guardrail_max_retries' instead.",
DeprecationWarning,
stacklevel=2
)
self.guardrail_max_retries = self.max_retries
return self
def execute_sync( def execute_sync(
self, self,
agent: Optional[BaseAgent] = None, agent: Optional[BaseAgent] = None,
@@ -450,9 +468,9 @@ class Task(BaseModel):
retry_count=self.retry_count, retry_count=self.retry_count,
) )
if not guardrail_result.success: if not guardrail_result.success:
if self.retry_count >= self.max_retries: if self.retry_count >= self.guardrail_max_retries:
raise Exception( raise Exception(
f"Task failed guardrail validation after {self.max_retries} retries. " f"Task failed guardrail validation after {self.guardrail_max_retries} retries. "
f"Last error: {guardrail_result.error}" f"Last error: {guardrail_result.error}"
) )

View File

@@ -4150,7 +4150,7 @@ def test_crew_with_failing_task_guardrails():
expected_output="A properly formatted report", expected_output="A properly formatted report",
agent=researcher, agent=researcher,
guardrail=strict_format_guardrail, guardrail=strict_format_guardrail,
max_retries=3, guardrail_max_retries=3,
) )
crew = Crew( crew = Crew(
@@ -4196,7 +4196,7 @@ def test_crew_guardrail_feedback_in_context():
expected_output="A response containing the keyword 'IMPORTANT'", expected_output="A response containing the keyword 'IMPORTANT'",
agent=researcher, agent=researcher,
guardrail=format_guardrail, guardrail=format_guardrail,
max_retries=2, guardrail_max_retries=2,
) )
crew = Crew(agents=[researcher], tasks=[task]) crew = Crew(agents=[researcher], tasks=[task])

View File

@@ -61,7 +61,7 @@ def test_task_with_failing_guardrail():
description="Test task", description="Test task",
expected_output="Output", expected_output="Output",
guardrail=guardrail, guardrail=guardrail,
max_retries=1, guardrail_max_retries=1,
) )
# First execution fails guardrail, second succeeds # First execution fails guardrail, second succeeds
@@ -88,7 +88,7 @@ def test_task_with_guardrail_retries():
description="Test task", description="Test task",
expected_output="Output", expected_output="Output",
guardrail=guardrail, guardrail=guardrail,
max_retries=2, guardrail_max_retries=2,
) )
with pytest.raises(Exception) as exc_info: with pytest.raises(Exception) as exc_info:
@@ -113,7 +113,7 @@ def test_guardrail_error_in_context():
description="Test task", description="Test task",
expected_output="Output", expected_output="Output",
guardrail=guardrail, guardrail=guardrail,
max_retries=1, guardrail_max_retries=1,
) )
# Mock execute_task to succeed on second attempt # Mock execute_task to succeed on second attempt
@@ -265,7 +265,7 @@ def test_guardrail_when_an_error_occurs(sample_agent, task_output):
agent=sample_agent, agent=sample_agent,
expected_output="A list of available books on the First World War", expected_output="A list of available books on the First World War",
guardrail="Ensure the authors are from Italy", guardrail="Ensure the authors are from Italy",
max_retries=0, guardrail_max_retries=0,
) )
task.execute_sync(agent=sample_agent) task.execute_sync(agent=sample_agent)