88 lines
2.8 KiB
Python
88 lines
2.8 KiB
Python
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
|