"""一次性金标准生成器（Prompt 外置方案A · 步0）。

取每个内置 AgentSpec 的**运行时** `system_prompt` 值算 sha256，写入
`fixtures/prompt_hashes.json`。这是 prompt 外置「字节级零变化」的唯一金标准
（设计 docs/design/prompt-management.md §6 / 原则6）。

为何用 import 读 `spec.system_prompt` 而非源码文本：21 个 `*_SYSTEM_PROMPT`
常量大量使用反斜杠行延续（行尾 `\\`），源码物理换行 ≠ 运行时换行。Python 在
import 时已把 `\\<newline>` 求值塌缩——`spec.system_prompt` 即生产实际发送的
运行时字符串，等价于 AST literal_eval 且更直接。

用法（仅在步0 运行一次，之后**不要**再生成，否则会用新值覆盖金标准、掩盖漂移）：
    uv run python packages/agents/tests/_gen_golden.py
漂移防护靠 test_prompt_loader.py 比对 load_prompt 输出 vs 本文件产出的 json，
而非重跑本脚本。
"""

from __future__ import annotations

import hashlib
import json
from pathlib import Path

import ww_agents
from ww_agents.specs import AgentSpec

FIXTURE = Path(__file__).parent / "fixtures" / "prompt_hashes.json"


def _sha256(text: str) -> str:
    return hashlib.sha256(text.encode("utf-8")).hexdigest()


def collect_builtin_specs() -> dict[str, AgentSpec]:
    """ww_agents 命名空间里导出的全部内置 AgentSpec 实例（按 spec.name 去重）。"""
    found: dict[str, AgentSpec] = {}
    for value in vars(ww_agents).values():
        if isinstance(value, AgentSpec):
            found[value.name] = value
    return found


def main() -> None:
    specs = collect_builtin_specs()
    golden = {name: _sha256(spec.system_prompt) for name, spec in sorted(specs.items())}
    FIXTURE.parent.mkdir(parents=True, exist_ok=True)
    FIXTURE.write_text(
        json.dumps(golden, ensure_ascii=False, indent=2, sort_keys=True) + "\n",
        encoding="utf-8",
    )
    print(f"wrote {len(golden)} golden hashes -> {FIXTURE}")


if __name__ == "__main__":
    main()
