Spaces:
Sleeping
Sleeping
| import json | |
| from dataclasses import asdict, is_dataclass | |
| from datetime import UTC, datetime | |
| from pathlib import Path | |
| from utils.helpers import slugify | |
| def _serialise_message(message: dict[str, object]) -> dict[str, object]: | |
| payload: dict[str, object] = { | |
| "role": message["role"], | |
| "content": message["content"], | |
| } | |
| contrast = message.get("_contrast") | |
| if contrast is not None: | |
| payload["_contrast"] = asdict(contrast) if is_dataclass(contrast) else contrast | |
| return payload | |
| def save_chat_export( | |
| *, | |
| model_name: str, | |
| dataset_source: str, | |
| persona_id: str, | |
| persona_name: str | None, | |
| prompt_mode: str, | |
| system_prompt: str | None, | |
| messages: list[dict[str, str]], | |
| generation: dict[str, object], | |
| panel_label: str | None = None, | |
| ) -> Path: | |
| """Save the current chat session to ``artifacts/chats`` as JSON. | |
| Args: | |
| model_name: Model identifier used for the chat. | |
| dataset_source: Human-readable dataset source label. | |
| persona_id: Selected persona id. | |
| persona_name: Selected persona display name, if available. | |
| prompt_mode: Active system prompt mode. | |
| system_prompt: Current system prompt text, if any. | |
| messages: Conversation messages without the system prompt. | |
| generation: Generation settings used for the chat. | |
| panel_label: Optional side label (e.g. "left"/"right") for compare-mode exports. | |
| Returns: | |
| The path the export was written to. | |
| """ | |
| from persona_data.environment import get_artifacts_dir | |
| payload = { | |
| "model_name": model_name, | |
| "dataset_source": dataset_source, | |
| "persona": { | |
| "id": persona_id, | |
| "name": persona_name, | |
| }, | |
| "panel_label": panel_label, | |
| "prompt_mode": prompt_mode, | |
| "generation": generation, | |
| "messages": ( | |
| [{"role": "system", "content": system_prompt}] if system_prompt else [] | |
| ) | |
| + [_serialise_message(message) for message in messages], | |
| } | |
| export_dir = ( | |
| get_artifacts_dir() | |
| / "chats" | |
| / "__".join(slugify(part) for part in model_name.split("/")) | |
| / slugify(persona_id) | |
| ) | |
| export_dir.mkdir(parents=True, exist_ok=True) | |
| timestamp = datetime.now(UTC).strftime("%Y%m%dT%H%M%SZ") | |
| filename_parts = [ | |
| timestamp, | |
| slugify(persona_name or persona_id), | |
| slugify(prompt_mode), | |
| ] | |
| if panel_label: | |
| filename_parts.append(slugify(panel_label)) | |
| export_path = export_dir / f"{'__'.join(filename_parts)}.json" | |
| export_path.write_text( | |
| f"{json.dumps(payload, indent=2, ensure_ascii=False)}\n", | |
| encoding="utf-8", | |
| ) | |
| return export_path | |