from datetime import timedelta from celery import shared_task from celery.exceptions import SoftTimeLimitExceeded from django.conf import settings from django.utils import timezone from apps.agents.models import AgentRun from apps.agents.services import execute_agent_run as execute_agent_run_service from apps.audit.models import OperationAuditLog @shared_task( bind=True, name="apps.agents.tasks.execute_agent_run", soft_time_limit=600, time_limit=630, ) def execute_agent_run(self, run_id: int) -> None: try: execute_agent_run_service(run_id) except SoftTimeLimitExceeded: run = AgentRun.objects.get(id=run_id) run.status = "timed_out" run.error_code = "run_timeout" run.error_message = "Agent 运行超过 10 分钟限制" run.finished_at = timezone.now() run.save( update_fields=[ "status", "error_code", "error_message", "finished_at", ] ) @shared_task(name="apps.agents.tasks.cleanup_expired_agent_runs") def cleanup_expired_agent_runs() -> int: cutoff = timezone.now() - timedelta(days=settings.AI_RUN_RETENTION_DAYS) queryset = AgentRun.objects.filter(created_at__lt=cutoff) count = queryset.count() if count: OperationAuditLog.objects.create( module="agents", action="cleanup_runs", target_type="agent_run", request_snapshot={ "deleted_count": count, "retention_days": settings.AI_RUN_RETENTION_DAYS, }, result="success", ) queryset.delete() return count