feat: 增加 AI Agent 自主诊断执行模式

This commit is contained in:
cnbugs
2026-07-25 12:21:54 +08:00
parent 26ae846501
commit 4f3a7833a0
8 changed files with 659 additions and 1 deletions
+49
View File
@@ -22,7 +22,9 @@ from backend.diagnosis import (
from backend.ai_agent import (
analyze_with_ai, chat_with_ai,
analyze_with_ai_stream, chat_with_ai_stream,
run_diagnostic_agent, take_pending_approval,
)
from backend.agent_tools import execute_kubectl
app = FastAPI(title="K8S 智能诊断平台", version="1.0.0")
@@ -64,6 +66,11 @@ class ChatRequest(BaseModel):
messages: list[dict]
class AgentApprovalRequest(BaseModel):
approval_id: str
approved: bool
@app.get("/api/health")
async def health():
return {"status": "ok", "time": datetime.now().isoformat()}
@@ -250,6 +257,48 @@ async def analyze_stream(question: str = ""):
)
@app.get("/api/agent/diagnose/stream")
async def agent_diagnose_stream(question: str = "", execution_mode: str = "ai"):
"""自主诊断 Agent:支持手动执行和安全 AI 执行模式。"""
if execution_mode not in {"ai", "manual"}:
raise HTTPException(status_code=400, detail="execution_mode 仅支持 ai 或 manual")
global _last_diagnosis, _last_report
if _last_diagnosis is None:
_last_diagnosis = await run_full_diagnosis()
_last_report = build_diagnosis_report(_last_diagnosis)
async def event_generator():
yield f"data: {json.dumps({'type': 'start', 'model': AI_MODEL, 'mode': execution_mode}, ensure_ascii=False)}\n\n"
try:
async for event in run_diagnostic_agent(
_last_report,
question=question,
execution_mode=execution_mode,
):
yield f"data: {json.dumps(event, ensure_ascii=False)}\n\n"
yield f"data: {json.dumps({'type': 'done'}, ensure_ascii=False)}\n\n"
except Exception as exc:
yield f"data: {json.dumps({'type': 'error', 'message': f'自主诊断失败: {exc}'}, ensure_ascii=False)}\n\n"
return StreamingResponse(
event_generator(),
media_type="text/event-stream",
headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"},
)
@app.post("/api/agent/approve")
async def execute_approved_agent_command(req: AgentApprovalRequest):
"""人工批准后执行一次待审批的修改命令。"""
pending = take_pending_approval(req.approval_id)
if pending is None:
raise HTTPException(status_code=404, detail="审批请求不存在或已经处理")
if not req.approved:
return {"approved": False, "command": pending["command"], "message": "用户已拒绝执行"}
result = await execute_kubectl(pending["command"])
return {"approved": True, "reason": pending["reason"], **result}
@app.post("/api/chat")
async def chat(req: ChatRequest):
"""AI 多轮对话 (非流式,兼容旧接口)"""