dark a11904b7c5 docs/build: 补齐中文注释、流程图和 Linux 解压即用打包脚本
- 为 pam_deploy_graph 生产代码补充中文模块、类、函数/方法文档字符串
- 将原有英文说明和主要英文异常提示改为中文
- 新增当前整体逻辑结构流程图文档,覆盖模块结构、执行链路、action 路由、人工确认和 checkpoint 续跑
- 新增 Linux 自带运行环境打包脚本,使用 PyInstaller 生成解压即用目录和 tar.gz
- 新增 Linux 打包说明,包含构建命令、运行方式、依赖说明和包大小评估
- 同步 README,补充流程图、打包方式、产物路径和大小预估
- 更新相关测试断言以匹配中文错误提示
2026-06-01 11:21:42 +08:00

73 lines
2.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""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