""" Goal/Task 异步任务 — Celery 任务定义 Main Agent 的目标分解、任务执行、自主循环等重量级操作通过 Celery 异步执行。 """ from app.core.tools_bootstrap import ensure_builtin_tools_registered ensure_builtin_tools_registered() from app.core.celery_app import celery_app from app.core.database import SessionLocal from app.models.goal import Goal from app.models.execution import Execution from app.services.main_agent_service import MainAgentService import asyncio import logging import time logger = logging.getLogger(__name__) @celery_app.task(bind=True) def decompose_goal_task(self, goal_id: str): """ 异步分解目标:使用 LLM 将 Goal 分解为 Task 树。 在 Celery Worker 中执行,避免 API 请求超时。 """ db = SessionLocal() try: service = MainAgentService(db) goal = asyncio.run(service.decompose_goal(goal_id)) return { "status": "completed", "goal_id": goal_id, "goal_title": goal.title, } except Exception as e: logger.error(f"Goal decomposition failed: {e}", exc_info=True) db.rollback() return {"status": "failed", "goal_id": goal_id, "error": str(e)} finally: db.close() @celery_app.task(bind=True) def execute_goal_task(self, goal_id: str): """ 异步执行 Goal:启动 Main Agent 管理目标全生命周期。 1. 分解目标(如果尚未分解) 2. 持续执行 task 直到完成或阻塞 3. 更新 Goal 状态 """ db = SessionLocal() start_time = time.time() try: goal = db.query(Goal).filter(Goal.id == goal_id).first() if not goal: return {"status": "failed", "goal_id": goal_id, "error": "目标不存在"} # 更新状态 goal.status = "active" db.commit() service = MainAgentService(db) result = asyncio.run(service.start_goal_execution(goal_id)) elapsed = int((time.time() - start_time) * 1000) return { "status": "completed", "goal_id": goal_id, "elapsed_ms": elapsed, **result, } except Exception as e: logger.error(f"Goal execution failed: {e}", exc_info=True) goal = db.query(Goal).filter(Goal.id == goal_id).first() if goal: goal.status = "failed" db.commit() return {"status": "failed", "goal_id": goal_id, "error": str(e)} finally: db.close() @celery_app.task(bind=True) def execute_task_celery(self, task_id: str): """ 异步执行单个 Task。 Main Agent 创建 Execution 记录后将任务交给 Celery Worker 执行。 """ db = SessionLocal() start_time = time.time() try: service = MainAgentService(db) result = asyncio.run(service.execute_task(task_id)) elapsed = int((time.time() - start_time) * 1000) return { "status": result.get("status", "completed"), "task_id": task_id, "elapsed_ms": elapsed, **result, } except Exception as e: logger.error(f"Task execution failed: {e}", exc_info=True) return {"status": "failed", "task_id": task_id, "error": str(e)} finally: db.close() @celery_app.task(bind=True) def autonomy_tick_task(self, goal_id: str): """ 自主循环单次心跳:检查进度 → 执行可运行任务 → 处理失败 → 通知。 由 Celery Beat 定时调度(根据 Goal.autonomy_config.check_interval_minutes)。 """ db = SessionLocal() try: service = MainAgentService(db) result = asyncio.run(service.autonomy_tick(goal_id)) logger.info(f"Autonomy tick for goal {goal_id}: {result.get('status', 'unknown')}") return {"status": "completed", "goal_id": goal_id, **result} except Exception as e: logger.error(f"Autonomy tick failed for goal {goal_id}: {e}", exc_info=True) return {"status": "failed", "goal_id": goal_id, "error": str(e)} finally: db.close()