"""Audit row builder + fail-soft HF Dataset append.""" from __future__ import annotations import json, os, threading def build_row(*, session, text, read, mood_before, mood_after, deltas, trace, mood_word, ts, source="space:chat") -> dict: return { "ts": ts, "session": session, "text": text, "source": source, "read": list(read), "mood_before": list(mood_before), "mood_after": list(mood_after), "deltas": list(deltas), "mood_word": mood_word, "structures": trace.get("structures", []), "unknown_tokens": trace.get("unknown_tokens", []), "suspected_gap": trace.get("suspected_gap", False), "words": trace.get("words", []), } class AuditLog: """Buffers rows to a local JSONL and flushes to a private HF Dataset. Fail-soft: any logging error is swallowed (never breaks /say).""" def __init__(self, repo_id: str, local_dir: str = "./data", flush_every: int = 25): self._repo = repo_id self._path = os.path.join(local_dir, "audit.jsonl") os.makedirs(local_dir, exist_ok=True) self._buf: list[dict] = [] self._flush_every = flush_every self._lock = threading.Lock() def append(self, row: dict) -> None: try: with self._lock: self._buf.append(row) with open(self._path, "a") as f: f.write(json.dumps(row) + "\n") if len(self._buf) >= self._flush_every: rows, self._buf = self._buf, [] self._commit(rows) except Exception: pass # fail-soft def pending(self) -> int: return len(self._buf) def _commit(self, rows: list[dict]) -> None: # Upload the cumulative JSONL to the HF Dataset. Requires HF_TOKEN. token = os.environ.get("HF_TOKEN") if not token: return from huggingface_hub import HfApi HfApi().upload_file( path_or_fileobj=self._path, path_in_repo="audit.jsonl", repo_id=self._repo, repo_type="dataset", token=token, )