""" gap_engine.library — 参数库与矩阵配置的读写 数据来源(都可直接编辑,改动即时生效): 09_ave/config/param_library.yaml 六层参数库(6层/38参数/177值) 09_ave/config/creative_matrix.yaml 矩阵配置(负面/正向/道具场景/生成参数) """ from __future__ import annotations import sys from pathlib import Path from typing import Optional import yaml _SCRIPTS = Path(__file__).resolve().parent.parent if str(_SCRIPTS) not in sys.path: sys.path.insert(0, str(_SCRIPTS)) from lib.logger import get_logger # noqa: E402 from gap_engine.models import ParamLibrary, CreativeConstraints # noqa: E402 log = get_logger("gap_engine") _AVE_DIR = _SCRIPTS.parent LIB_PATH = _AVE_DIR / "config" / "param_library.yaml" MATRIX_PATH = _AVE_DIR / "config" / "creative_matrix.yaml" # 简易缓存(按文件 mtime 失效) _cache: dict = {} def _load_yaml(path: Path) -> dict: try: return yaml.safe_load(path.read_text(encoding="utf-8")) or {} except Exception as e: log.warning("读取 %s 失败: %s", path.name, e) return {} def load_library(use_cache: bool = True) -> ParamLibrary: """加载六层参数库(按 mtime 自动失效缓存)""" key = "library" try: mtime = LIB_PATH.stat().st_mtime except Exception: mtime = 0 if use_cache and _cache.get(key, {}).get("mtime") == mtime: return _cache[key]["obj"] d = _load_yaml(LIB_PATH) lib = ParamLibrary(**d) if d.get("layers") else ParamLibrary(layers=[]) _cache[key] = {"mtime": mtime, "obj": lib} return lib def load_matrix(use_cache: bool = True) -> dict: """加载矩阵配置(原始 dict,含 generation / negative / positive / props / scenes / presets)""" key = "matrix" try: mtime = MATRIX_PATH.stat().st_mtime except Exception: mtime = 0 if use_cache and _cache.get(key, {}).get("mtime") == mtime: return _cache[key]["obj"] d = _load_yaml(MATRIX_PATH) _cache[key] = {"mtime": mtime, "obj": d} return d def save_matrix(data: dict) -> dict: """保存矩阵配置(前端 ②③④ 标签页的勾选结果)""" data = dict(data or {}) data["updated"] = __import__("datetime").date.today().isoformat() MATRIX_PATH.write_text( yaml.safe_dump(data, allow_unicode=True, sort_keys=False, width=100), encoding="utf-8") _cache.pop("matrix", None) log.info("矩阵配置已保存") return load_matrix(use_cache=False) def save_library_text(text: str) -> dict: """保存参数库(整份 YAML 文本;供高级编辑用)""" parsed = yaml.safe_load(text) if not parsed or not parsed.get("layers"): raise ValueError("参数库格式错误:缺少 layers") LIB_PATH.write_text(text, encoding="utf-8") _cache.pop("library", None) lib = load_library(use_cache=False) n_param = sum(len(L.params) for L in lib.layers) n_val = sum(len(p.values) for L in lib.layers for p in L.params) return {"layers": len(lib.layers), "params": n_param, "values": n_val} def constraints_from_matrix(matrix: Optional[dict] = None) -> CreativeConstraints: """矩阵 dict → CreativeConstraints(供过滤/加权使用)""" m = matrix or load_matrix() neg = m.get("negative") or {} return CreativeConstraints( negative_hard=neg.get("hard") or [], negative_soft=neg.get("soft") or [], positive=m.get("positive") or [], props=m.get("props") or [], scenes=m.get("scenes") or [], ) def generation_cfg(matrix: Optional[dict] = None) -> dict: m = matrix or load_matrix() return m.get("generation") or {}