Files
X-Agents/agent/app/security/approval.py

105 lines
2.7 KiB
Python
Raw Normal View History

"""
审批服务 - 处理工具执行的审批流程
"""
import uuid
from datetime import datetime
from typing import Any, Dict, Optional
from enum import Enum
class ApprovalStatus(Enum):
"""审批状态"""
PENDING = "pending"
APPROVED = "approved"
REJECTED = "rejected"
class ApprovalService:
"""审批服务"""
def __init__(self):
# 待审批队列
self.pending: Dict[str, dict] = {}
# 审批结果
self.results: Dict[str, ApprovalStatus] = {}
async def request_approval(
self,
tool_name: str,
params: dict,
user_id: str,
agent_id: str,
reason: str
) -> str:
"""
请求审批
Returns:
request_id: 审批请求ID
"""
request_id = str(uuid.uuid4())
request = {
"request_id": request_id,
"tool_name": tool_name,
"params": params,
"user_id": user_id,
"agent_id": agent_id,
"reason": reason,
"status": ApprovalStatus.PENDING,
"created_at": datetime.now().isoformat()
}
self.pending[request_id] = request
self.results[request_id] = ApprovalStatus.PENDING
# TODO: 通知 Go 后端有新审批
return request_id
async def check_approval(self, request_id: str, timeout: int = 300) -> bool:
"""
检查审批状态
Args:
request_id: 审批请求ID
timeout: 超时时间
Returns:
是否已批准
"""
import asyncio
start = datetime.now()
while (datetime.now() - start).seconds < timeout:
status = self.results.get(request_id)
if status == ApprovalStatus.APPROVED:
return True
elif status == ApprovalStatus.REJECTED:
return False
await asyncio.sleep(1)
raise TimeoutError("Approval request timeout")
async def approve(self, request_id: str):
"""批准请求"""
if request_id in self.pending:
self.pending[request_id]["status"] = ApprovalStatus.APPROVED
self.results[request_id] = ApprovalStatus.APPROVED
async def reject(self, request_id: str):
"""拒绝请求"""
if request_id in self.pending:
self.pending[request_id]["status"] = ApprovalStatus.REJECTED
self.results[request_id] = ApprovalStatus.REJECTED
def get_pending(self) -> list[dict]:
"""获取待审批列表"""
return [
req for req in self.pending.values()
if req["status"] == ApprovalStatus.PENDING
]