"""Auto-generate docs/LIVE_AI_PROMPTS.md for the v2 backend. Scans live prompt constants and builder functions under ``backend/prompts/``. Run as a script or import ``generate_prompt_inventory``. """ from __future__ import annotations import inspect import textwrap from datetime import datetime, timezone from pathlib import Path from backend.config import REPO_ROOT _PROMPTS_PKG = Path(__file__).resolve().parents[1] / "prompts" _OUTPUT = REPO_ROOT / "docs" / "LIVE_AI_PROMPTS_V2.md" _MODULES = ( ("discovery", "backend.prompts.discovery_prompt"), ("hybrid_discovery", "backend.models.hybrid_discovery"), ("mapping", "backend.prompts.mapping_prompt"), ("grounding", "backend.prompts.grounding_prompt"), ("notes_expander", "backend.prompts.notes_expander"), ) def _import_module(dotted: str): import importlib return importlib.import_module(dotted) def _collect_entries() -> list[tuple[str, str, str]]: """Return (module_label, name, content) for each live prompt artifact.""" entries: list[tuple[str, str, str]] = [] for label, dotted in _MODULES: mod = _import_module(dotted) for name, obj in sorted(vars(mod).items()): if name.startswith("_"): continue if isinstance(obj, str) and len(obj.strip()) > 40: entries.append((label, name, obj.strip())) elif callable(obj) and name.startswith("build_"): src = inspect.getsource(obj).strip() entries.append((label, f"{name}()", f"```python\n{src}\n```")) return entries def generate_markdown() -> str: entries = _collect_entries() ts = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC") lines = [ "# Live AI Prompts — v2 Backend", "", f"Auto-generated by `backend/utils/prompt_inventory.py` on {ts}.", "Do not hand-edit; re-run the generator after prompt changes.", "", "## Operator bundle context", "", "- **Report template (PDF)** drives schema/section order only.", "- **Standard paragraphs (Word)** supply MASTER RAG wording.", "- LLM calls: discovery enrichment, per-section mapping, grounding audit, optional notes expand.", "", ] current_label = "" for label, name, content in entries: if label != current_label: lines.extend(["", f"## {label}", ""]) current_label = label lines.append(f"### `{name}`") lines.append("") if content.startswith("```"): lines.append(content) else: lines.append(textwrap.indent(content, "")) lines.append("") return "\n".join(lines).strip() + "\n" def write_inventory(path: Path | None = None) -> Path: target = path or _OUTPUT target.parent.mkdir(parents=True, exist_ok=True) target.write_text(generate_markdown(), encoding="utf-8") return target if __name__ == "__main__": out = write_inventory() print(f"Wrote {out}")