Fabella / DATASET.md
OpenCode
docs: point all dataset references at build-small-hackathon/fabella-traces
d2ed801
|
Raw
History Blame Contribute Delete
5.56 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade

Fabella Anonymized Agent Traces

When the public publisher is enabled, one anonymized row per request lands at build-small-hackathon/fabella-traces. The dataset repo is public and contains the live card, the publisher schema, and 5 seed rows for the data viewer. The Space publishes to it only when FABELLA_SHARE_TRACES=1 is set on the Space (default 0); with the flag off, rows only live in the per-parent bucket and are exportable via the Space's Settings β†’ Download my history button.

This file is a local copy of the Hugging Face dataset card for Fabella's anonymized agent-trace publication. The live card on the Hub is the source of truth; this file is a convenience for reviewers reading the source repo.

Why this exists

Fabella is a small Hugging Face Space that drafts short, kind, age-appropriate explanations a parent can use to talk to their child about a hard thing (a hospitalization, a move, a pet dying). The first version is generated by google/gemma-4-E4B-it; a nvidia/NVIDIA-Nemotron-3-Nano-4B-BF16 judge scores it against a six-criterion rubric; the drafter revises if needed. An optional read-aloud uses openbmb/VoxCPM2.

The dataset captures the full ReAct loop for every successful generation, with PII removed before the row leaves the Space. It's the Sharing is Caring merit-badge artifact for the Build Small Hackathon submission.

Where it lives

  • Live dataset (when enabled): https://huggingface.co/datasets/build-small-hackathon/fabella-traces (default)
  • Personal-namespace fallback: set FABELLA_TRACE_REPO=Kiy-K/fabella-traces to publish to the maker's personal dataset instead. Used for local dev where the Space's HF_TOKEN can't create in the org namespace.
  • Default for this demo: the publisher is OFF (FABELLA_SHARE_TRACES=0); data lives in the per-parent bucket and is exportable via the Space's Settings β†’ Download my history button.

The dataset repo is created on first publish by trace.py::_ensure_repo via HfApi.create_repo(exist_ok=True), so a fresh deployment does not require a one-time setup step.

Schema (one row per request, when publishing is enabled)

{
  "trace_id": "<uuid>",
  "created_at": "2026-06-14T14:04:05+00:00",
  "schema_version": 1,
  "app_version": "fabella-1",
  "model_versions": {
    "drafter": "google/gemma-4-E4B-it",
    "judge": "nvidia/NVIDIA-Nemotron-3-Nano-4B-BF16"
  },
  "request": {
    "age": 7,
    "tone": "gentle",
    "child_name_present": true,
    "child_name_redacted": "[name]",
    "situation_hash": "sha256:9a3ba115d57a3789",
    "situation_preview": "My 7yo's grandma is in the hospital.",
    "situation_length": 36,
    "history_turns": 0
  },
  "agent": {
    "system_prompt": "<static, public, in-repo>",
    "user_prompt": "A parent needs help...\n\nThe latest thing the parent is asking about: <redacted, see request.situation_length>",
    "messages": [ /* full LangChain ReAct trace */ ],
    "final_draft": { "opener": "...", "body": "...", "closer": "...", "followup": "..." }
  },
  "judge": {
    "ok": true,
    "issues": [],
    "score": 0.92,
    "verdict": "approve",
    "reasoning": "good"
  },
  "latency_ms": 1234,
  "tool_calls": 1
}

Anonymization

The publisher in trace.py runs every row through five anonymization passes before the row leaves the Space:

  1. Child name is dropped from the request and replaced with "[name]" in the final draft.
  2. Raw situation is never stored. Only its SHA-256 hash, the first 60 chars as a topic preview, and its character length are kept.
  3. Freeform history turns are replaced with role + length counts. The drafter's user prompt additionally replaces the embedded situation with a length-only marker.
  4. System prompt is shipped in full (it's a static string in this repo, not user input).
  5. LangChain 1.x content lists are normalized so list-of-blocks content is joined to its text.

Self-export

Every parent can pull their own data via Settings β†’ Download my history in the running Space. The downloaded JSON bundle contains:

  • All chat turns stored under the parent's owner key (full, not redacted β€” the parent already has this in their browser).
  • The durable memory summary.
  • A trace_publication section that says exactly which dataset the redacted rows go to, the URL, the per-session row estimate, and the same five anonymization passes above.

The download path exists for two reasons: (1) the parent can verify that what we ship to the public dataset does not include raw situation text, child name, or anything that would link a row back to them; and (2) for a 3-day hackathon demo, it sidesteps the cold-start tax of the Hub push entirely.

Opt-out

  • Set FABELLA_SHARE_TRACES=0 on the Space to kill the publisher (this is the default).
  • Or pass share_trace=False on make_explanation to opt out per request.

The default for this demo is off: rows only live in the per-parent bucket, accessible via the Download button.

Source code

  • trace.py β€” the source of truth for the schema and the anonymization rules.
  • agent.py::_maybe_publish_trace β€” the call site that builds and submits each row.
  • app.py β€” calls _trace.publisher.start() at import time, exposes GET /api/history/download for the parent self-export.
  • app.py INDEX_HTML β€” wires the Download my history button in the settings dialog.