"""프롬프트 레지스트리 - 버전 관리 및 재현 가능성 보장.""" from __future__ import annotations from pathlib import Path import yaml class PromptRegistry: """프롬프트 템플릿 버전을 관리하고 변경 이력을 추적한다.""" def __init__(self, templates_dir: Path): self.templates_dir = templates_dir def list_versions(self) -> list[str]: """사용 가능한 템플릿 버전 목록을 반환한다 (최신순).""" yamls = sorted(self.templates_dir.glob("prompt_v*.yaml"), reverse=True) return [p.stem for p in yamls] def latest_version(self) -> str | None: versions = self.list_versions() return versions[0] if versions else None def load_template(self, version: str) -> dict: path = self.templates_dir / f"{version}.yaml" if not path.exists(): raise FileNotFoundError(f"템플릿 버전 {version}이 없습니다.") with open(path, encoding="utf-8") as f: return yaml.safe_load(f) def compare(self, version_a: str, version_b: str) -> dict: """두 버전의 차이점을 반환한다.""" a = self.load_template(version_a) b = self.load_template(version_b) diff = {} all_keys = set(a) | set(b) for key in all_keys: va, vb = a.get(key), b.get(key) if va != vb: diff[key] = {"old": va, "new": vb} return diff def save_new_version(self, new_version: str, template: dict) -> Path: """새 버전 템플릿을 저장한다.""" path = self.templates_dir / f"{new_version}.yaml" if path.exists(): raise FileExistsError(f"버전 {new_version}이 이미 존재합니다.") with open(path, "w", encoding="utf-8") as f: yaml.dump(template, f, allow_unicode=True, default_flow_style=False) return path def get_version_for_hash(self, prompt_hash: str, db_session) -> str | None: """프롬프트 해시로 사용된 버전을 역조회한다.""" from harness.logger import JobRecord record = db_session.query(JobRecord).filter_by(prompt_hash=prompt_hash).first() return record.prompt_version if record else None