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

58 lines
1.9 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.

"""业务 checkpoint 的 JSON 存储与恢复工具。"""
from __future__ import annotations
import json
from dataclasses import asdict, fields, is_dataclass
from pathlib import Path
from typing import Any
from .constants import SENSITIVE_KEYS
from .models import AgentState
def redact_mapping(value: Any) -> Any:
"""递归脱敏 dict/list 中的敏感字段。"""
if isinstance(value, dict):
result = {}
for key, item in value.items():
if str(key) in SENSITIVE_KEYS:
result[key] = "***"
else:
result[key] = redact_mapping(item)
return result
if isinstance(value, list):
return [redact_mapping(item) for item in value]
return value
def save_checkpoint(state: Any, path: str | Path, *, redact: bool = True) -> Path:
"""保存 checkpoint真实续跑场景可关闭脱敏以保留必要参数。"""
checkpoint_path = Path(path)
checkpoint_path.parent.mkdir(parents=True, exist_ok=True)
payload = asdict(state) if is_dataclass(state) else state
if redact:
payload = redact_mapping(payload)
checkpoint_path.write_text(
json.dumps(payload, ensure_ascii=False, indent=2),
encoding="utf-8",
)
return checkpoint_path
def load_checkpoint(path: str | Path) -> dict[str, Any]:
"""从 JSON 文件读取原始 checkpoint 字典。"""
return json.loads(Path(path).read_text(encoding="utf-8"))
def agent_state_from_mapping(payload: dict[str, Any]) -> AgentState:
"""把 checkpoint 字典转换回 AgentState忽略未知字段。"""
allowed_fields = {item.name for item in fields(AgentState)}
state_payload = {key: value for key, value in payload.items() if key in allowed_fields}
return AgentState(**state_payload)
def load_agent_state(path: str | Path) -> AgentState:
"""读取 checkpoint 文件并恢复 AgentState。"""
return agent_state_from_mapping(load_checkpoint(path))