import os import yaml import time from pathlib import Path from typing import Dict, Any, Optional, List from pydantic import BaseModel, Field from app.config import PERSONAS_DIR, CLONES_DIR, get_universe class PersonaModel(BaseModel): universe_id: str name: str tagline: str tone: str style: str principles: List[str] = Field(default_factory=list) system_prompt: str = "" skills_active: List[str] = Field(default_factory=list) version: int = 1 updated_at: str = Field(default_factory=lambda: time.strftime("%Y-%m-%d %H:%M:%S")) def ensure_dirs(): PERSONAS_DIR.mkdir(parents=True, exist_ok=True) CLONES_DIR.mkdir(parents=True, exist_ok=True) def get_persona_path(universe_id: str) -> Path: ensure_dirs() cfg = get_universe(universe_id) return PERSONAS_DIR / cfg.persona_file def load_persona(universe_id: str) -> Dict[str, Any]: path = get_persona_path(universe_id) if not path.exists(): return { "universe_id": universe_id, "name": universe_id.upper(), "tagline": "Profil standard", "tone": "Professionnel et concis", "style": "Direct", "principles": [], "system_prompt": "", "skills_active": [], "version": 1, "updated_at": time.strftime("%Y-%m-%d %H:%M:%S") } with open(path, "r", encoding="utf-8") as f: return yaml.safe_load(f) or {} def save_persona(universe_id: str, data: Dict[str, Any]) -> None: path = get_persona_path(universe_id) data["updated_at"] = time.strftime("%Y-%m-%d %H:%M:%S") with open(path, "w", encoding="utf-8") as f: yaml.safe_dump(data, f, allow_unicode=True, sort_keys=False) def list_clones() -> List[Dict[str, Any]]: ensure_dirs() clones = [] for p in CLONES_DIR.glob("*.yaml"): try: with open(p, "r", encoding="utf-8") as f: data = yaml.safe_load(f) if data: data["clone_file"] = p.name clones.append(data) except Exception: continue return clones def clone_persona(universe_id: str, clone_name: str, overrides: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: ensure_dirs() base_data = load_persona(universe_id) clone_id = f"{universe_id}-clone-{int(time.time())}" clone_data = { **base_data, "clone_id": clone_id, "clone_name": clone_name, "parent_universe": universe_id, "created_at": time.strftime("%Y-%m-%d %H:%M:%S"), "version": base_data.get("version", 1) + 1 } if overrides: clone_data.update(overrides) clone_file = CLONES_DIR / f"{clone_id}.yaml" with open(clone_file, "w", encoding="utf-8") as f: yaml.safe_dump(clone_data, f, allow_unicode=True, sort_keys=False) return clone_data