- 为 pam_deploy_graph 生产代码补充中文模块、类、函数/方法文档字符串 - 将原有英文说明和主要英文异常提示改为中文 - 新增当前整体逻辑结构流程图文档,覆盖模块结构、执行链路、action 路由、人工确认和 checkpoint 续跑 - 新增 Linux 自带运行环境打包脚本,使用 PyInstaller 生成解压即用目录和 tar.gz - 新增 Linux 打包说明,包含构建命令、运行方式、依赖说明和包大小评估 - 同步 README,补充流程图、打包方式、产物路径和大小预估 - 更新相关测试断言以匹配中文错误提示
73 lines
2.6 KiB
Python
73 lines
2.6 KiB
Python
"""PAM 部署 Agent 的 LangGraph 集成入口。"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import Any, Literal
|
||
|
||
from .agent import PamDeployAgent
|
||
|
||
GraphFlow = Literal["global", "deploy"]
|
||
|
||
|
||
def build_langgraph(agent: PamDeployAgent | None = None, flow: GraphFlow = "deploy"):
|
||
"""把现有 Agent 节点组装成 LangGraph StateGraph。"""
|
||
try:
|
||
from langgraph.graph import END, START, StateGraph
|
||
except ImportError as exc: # pragma: no cover - 依赖可选安装状态
|
||
raise RuntimeError(
|
||
"未安装 langgraph。请先执行 `pip install -e .` 安装项目依赖。"
|
||
) from exc
|
||
|
||
runtime = agent or PamDeployAgent()
|
||
|
||
def create_state_node(state: dict[str, Any]) -> dict[str, Any]:
|
||
"""根据输入参数创建 AgentState。"""
|
||
agent_state = runtime.create_state(
|
||
params=state["params"],
|
||
execution_strategy=state.get("execution_strategy", "hybrid_node_mcp"),
|
||
run_id=state.get("run_id"),
|
||
script_entry=state.get("script_entry"),
|
||
config_path=state.get("config_path"),
|
||
trace_file_path=state.get("trace_file_path"),
|
||
target_ips=state.get("target_ips"),
|
||
)
|
||
return {"agent_state": agent_state}
|
||
|
||
def run_global_node(state: dict[str, Any]) -> dict[str, Any]:
|
||
"""运行全局部署阶段。"""
|
||
agent_state = runtime.run_global_flow(state["agent_state"])
|
||
return {"agent_state": agent_state}
|
||
|
||
def run_ip_node(state: dict[str, Any]) -> dict[str, Any]:
|
||
"""运行逐 IP 部署阶段。"""
|
||
agent_state = runtime.run_ip_flow(state["agent_state"])
|
||
return {"agent_state": agent_state}
|
||
|
||
def report_node(state: dict[str, Any]) -> dict[str, Any]:
|
||
"""渲染最终部署报告。"""
|
||
return {"report": runtime.render_report(state["agent_state"])}
|
||
|
||
graph = StateGraph(dict)
|
||
graph.add_node("create_state", create_state_node)
|
||
graph.add_node("run_global", run_global_node)
|
||
graph.add_node("run_ip", run_ip_node)
|
||
graph.add_node("report", report_node)
|
||
|
||
graph.add_edge(START, "create_state")
|
||
graph.add_edge("create_state", "run_global")
|
||
if flow == "global":
|
||
graph.add_edge("run_global", END)
|
||
else:
|
||
graph.add_edge("run_global", "run_ip")
|
||
graph.add_edge("run_ip", "report")
|
||
graph.add_edge("report", END)
|
||
return graph.compile()
|
||
|
||
|
||
def build_graph_or_none(agent: PamDeployAgent | None = None, flow: GraphFlow = "deploy"):
|
||
"""在未安装 LangGraph 时返回 None,便于调用方降级。"""
|
||
try:
|
||
return build_langgraph(agent=agent, flow=flow)
|
||
except RuntimeError:
|
||
return None
|