"""Validate query_prompts config structure (V2-M1D, paired with V2-M2). M2 will introduce product_documents/配置/query_prompts.v1.json. Until then this validator is a no-op (status=skip). Once the file exists, it checks each profile carries the required fields with sane sampling params. """ from __future__ import annotations import json import sys from pathlib import Path from typing import Any ROOT = Path(__file__).resolve().parents[1] QUERY_PROMPTS_PATH = Path("product_documents/配置/query_prompts.v1.json") _REQUIRED = ["system", "user", "temperature", "max_tokens", "evidence_fields", "variants_per_seed"] def validate_query_prompts_config(config: dict[str, Any]) -> list[dict[str, Any]]: findings: list[dict[str, Any]] = [] profiles = config.get("profiles") or {} if not profiles: findings.append({"level": "fail", "check_id": "profiles", "message": "no profiles defined"}) for name, profile in profiles.items(): for field in _REQUIRED: if field not in profile: findings.append({"level": "fail", "check_id": "missing_field", "message": f"{name} missing {field}"}) temp = profile.get("temperature") if isinstance(temp, (int, float)) and not 0 <= temp <= 2: findings.append({"level": "fail", "check_id": "temperature", "message": f"{name} temperature out of [0,2]: {temp}"}) if isinstance(profile.get("max_tokens"), int) and profile["max_tokens"] <= 0: findings.append({"level": "fail", "check_id": "max_tokens", "message": f"{name} max_tokens must be > 0"}) if isinstance(profile.get("variants_per_seed"), int) and profile["variants_per_seed"] < 1: findings.append({"level": "fail", "check_id": "variants_per_seed", "message": f"{name} variants_per_seed must be >= 1"}) return findings def main() -> int: path = ROOT / QUERY_PROMPTS_PATH if not path.exists(): print(json.dumps({"status": "skip", "config_path": str(QUERY_PROMPTS_PATH), "reason": "not built until V2-M2"}, ensure_ascii=False, indent=2)) return 0 findings = validate_query_prompts_config(json.loads(path.read_text(encoding="utf-8"))) status = "fail" if any(f["level"] == "fail" for f in findings) else "pass" print(json.dumps({"status": status, "config_path": str(QUERY_PROMPTS_PATH), "findings": findings}, ensure_ascii=False, indent=2)) return 1 if status == "fail" else 0 if __name__ == "__main__": sys.exit(main())