105 lines
2.7 KiB
Python
105 lines
2.7 KiB
Python
|
|
"""
|
|||
|
|
审批服务 - 处理工具执行的审批流程
|
|||
|
|
"""
|
|||
|
|
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
|
|||
|
|
]
|