feat(agents): Phase 7-10 hook system, plugins, skills, orchestration
Phase 7: Built-in Hooks (audit_log, dangerous_confirmation, security_scan) Phase 8: Plugin system (PluginManager, PluginSandbox, PluginManifest) Phase 9: Skills registry (SkillRegistry, local/plugin/MCP loaders) Phase 10: TeamLeader, RemoteTransport, BackgroundTaskManager
This commit is contained in:
119
backend/app/agents/background/manager.py
Normal file
119
backend/app/agents/background/manager.py
Normal file
@@ -0,0 +1,119 @@
|
||||
"""后台任务系统 - Phase 10.4"""
|
||||
|
||||
import asyncio
|
||||
import uuid
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class BackgroundTaskStatus(Enum):
|
||||
PENDING = "pending"
|
||||
RUNNING = "running"
|
||||
COMPLETED = "completed"
|
||||
FAILED = "failed"
|
||||
CANCELLED = "cancelled"
|
||||
|
||||
|
||||
@dataclass
|
||||
class BackgroundTask:
|
||||
"""后台任务"""
|
||||
|
||||
id: str
|
||||
name: str
|
||||
status: BackgroundTaskStatus
|
||||
created_at: datetime
|
||||
started_at: datetime | None = None
|
||||
completed_at: datetime | None = None
|
||||
result: Any = None
|
||||
error: str | None = None
|
||||
|
||||
|
||||
class BackgroundTaskManager:
|
||||
"""后台任务管理器"""
|
||||
|
||||
def __init__(self):
|
||||
self._tasks: dict[str, BackgroundTask] = {}
|
||||
self._.coroutines: dict[str, asyncio.Task] = {}
|
||||
|
||||
def submit_task(self, name: str, coro: Any, *args, **kwargs) -> str:
|
||||
"""提交后台任务
|
||||
|
||||
Args:
|
||||
name: 任务名称
|
||||
coro: 协程函数
|
||||
*args: 位置参数
|
||||
**kwargs: 关键字参数
|
||||
|
||||
Returns:
|
||||
任务 ID
|
||||
"""
|
||||
task_id = str(uuid.uuid4())[:8]
|
||||
|
||||
# 创建任务记录
|
||||
self._tasks[task_id] = BackgroundTask(
|
||||
id=task_id,
|
||||
name=name,
|
||||
status=BackgroundTaskStatus.PENDING,
|
||||
created_at=datetime.now(),
|
||||
)
|
||||
|
||||
# 创建 asyncio task
|
||||
async def run_task():
|
||||
self._tasks[task_id].status = BackgroundTaskStatus.RUNNING
|
||||
self._tasks[task_id].started_at = datetime.now()
|
||||
try:
|
||||
result = await coro(*args, **kwargs)
|
||||
self._tasks[task_id].status = BackgroundTaskStatus.COMPLETED
|
||||
self._tasks[task_id].result = result
|
||||
except Exception as e:
|
||||
self._tasks[task_id].status = BackgroundTaskStatus.FAILED
|
||||
self._tasks[task_id].error = str(e)
|
||||
finally:
|
||||
self._tasks[task_id].completed_at = datetime.now()
|
||||
if task_id in self._coroutines:
|
||||
del self._coroutines[task_id]
|
||||
|
||||
self._coroutines[task_id] = asyncio.create_task(run_task())
|
||||
return task_id
|
||||
|
||||
def cancel_task(self, task_id: str) -> bool:
|
||||
"""取消任务
|
||||
|
||||
Args:
|
||||
task_id: 任务 ID
|
||||
|
||||
Returns:
|
||||
是否成功取消
|
||||
"""
|
||||
if task_id not in self._tasks:
|
||||
return False
|
||||
|
||||
if task_id in self._coroutines:
|
||||
self._coroutines[task_id].cancel()
|
||||
del self._coroutines[task_id]
|
||||
|
||||
self._tasks[task_id].status = BackgroundTaskStatus.CANCELLED
|
||||
self._tasks[task_id].completed_at = datetime.now()
|
||||
return True
|
||||
|
||||
def get_task_status(self, task_id: str) -> BackgroundTask | None:
|
||||
"""获取任务状态"""
|
||||
return self._tasks.get(task_id)
|
||||
|
||||
def list_tasks(self) -> list[BackgroundTask]:
|
||||
"""列出所有任务"""
|
||||
return list(self._tasks.values())
|
||||
|
||||
|
||||
# 全局单例
|
||||
_manager: BackgroundTaskManager | None = None
|
||||
|
||||
|
||||
def get_background_task_manager() -> BackgroundTaskManager:
|
||||
"""获取全局后台任务管理器"""
|
||||
global _manager
|
||||
if _manager is None:
|
||||
_manager = BackgroundTaskManager()
|
||||
return _manager
|
||||
Reference in New Issue
Block a user