#!/usr/bin/env python3 # -*- coding: utf-8 -*- """作业 7 · 步骤 6:Agent 检测 OOM → 重启 → 钉钉通知。""" from __future__ import annotations import sys import _bootstrap # noqa: F401 import _config as C from dify_api import Dify, pp def fallback_notify_if_needed(hits: list[str]) -> bool: """detect+restart 已完成但 notify 未调用时(常见于 restart 后 LLM 断连),脚本补发钉钉。""" if len(hits) < 2 or "restart_vllm_container" not in hits: return False if "send_recovery_notification" in hits: return False from 作业7_self_heal import send_recovery_notification ding = send_recovery_notification( "vLLM OOM 已自愈,容器已重启恢复服务", "验收补发:Agent 在 restart 后 LLM 连接中断,已由脚本补发钉钉。", ) if ding.get("errcode") == 0: print("[PASS] detect+restart 完成,钉钉通知已补发") return True print("[FAIL] 补发钉钉失败", ding) return False def resolve_agent_id(d: Dify) -> str: aid = getattr(C, "HOMEWORK7_AGENT_ID", "") or "" if aid: return aid for item in (d.get("/agent?page=1&limit=50").get("json") or {}).get("data") or []: if item.get("name") == C.HOMEWORK7_APP_NAME: return item.get("agent_id") or item.get("id") or "" raise RuntimeError("找不到 Agent") def main() -> int: d = Dify(C.DIFY_EMAIL, C.DIFY_PASSWORD) try: d.login() agent_id = resolve_agent_id(d) print("agent_id", agent_id) r = d.post( "/agent/%s/chat-messages" % agent_id, body={ "inputs": {}, "query": C.HOMEWORK7_PROBE_QUERY, "response_mode": "streaming", "files": [], "conversation_id": "", }, extra="-m 480 --max-time 480", t=510, ) pp("chat", r, limit=10000) text = r.get("text") or "" tools = ( "detect_vllm_anomaly", "restart_vllm_container", "send_recovery_notification", ) hits = [t for t in tools if t in text] print("tools hit:", hits) stream_error = "completion_request_error" in text or '"event":"error"' in text if r.get("code") != "200": if fallback_notify_if_needed(hits): return 0 print("[FAIL] 对话失败且无法补发通知", r) return 1 if len(hits) >= 3: pass elif fallback_notify_if_needed(hits): return 0 elif len(hits) < 3: print("[FAIL] 未完整调用三工具", "(stream error)" if stream_error else "") return 1 if "restart" not in text.lower() and "重启" not in text: print("[WARN] 回复未明确提到重启") print("[PASS] 故障自愈 Agent 已执行检测/重启/通知流程") return 0 finally: d.close() if __name__ == "__main__": sys.exit(main())