slyfox / README.md
stevhliu's picture
stevhliu HF Staff
Simplify chat composer and add optional repo context.
d955ed8
metadata
title: Slyfox
emoji: 🦊
colorFrom: yellow
colorTo: red
sdk: docker
app_port: 7860
pinned: false

🦊 Slyfox

A minimal, framework-free chat UI for transformers serve β€” the OpenAI-compatible chat completions server shipped with πŸ€— Transformers.

The frontend is plain HTML/JS (no Gradio). A tiny FastAPI backend persists each conversation to a private HF Bucket β€” one JSON file per chat.

Configuration

Variable Default Description
SLYFOX_BUCKET HF-slyfox/slyfox-chats Private bucket id (<namespace>/<bucket>) used for persistence.
HF_TOKEN injected by Spaces Token used by huggingface_hub to read/write the bucket. Needs write access.

Frontend query params (browser-side):

Param Default Description
api http://localhost:8000/v1 OpenAI-compatible base URL for the inference server.
model Qwen/Qwen3-0.6B Model id sent in the chat completion request.
repo (empty) Default Hugging Face repo id for new chats (e.g. huggingface/transformers).

Example:

https://huggingface.co/spaces/HF-slyfox/slyfox?api=https://your-tunnel/v1&model=Qwen/Qwen3-0.6B

Bucket layout

users/<anon_user_id>/
  index.json          # [{id, title, topic, updated_at}, …] newest first
  chats/
    <chat_id>.json    # full conversation: {id, title, topic, history, updated_at}

<anon_user_id> is a UUID minted in the browser and stored in localStorage (slyfox.user_id). Each browser is effectively its own user. Swap for HF OAuth identity to bind to a Hugging Face account.

API

Method Path Description
GET /api/chats List the per-user index.
GET /api/chats/{id} Fetch a single chat.
PUT /api/chats/{id} Upsert a chat (also updates the index).
DELETE /api/chats/{id} Delete a chat.
GET /healthz Health check.

All calls require an X-User-Id header.

Local development

pip install -r requirements.txt
HF_TOKEN=hf_… uvicorn app:app --reload --port 7860

Then visit http://localhost:7860/?api=http://localhost:8000/v1.

Jobs page

A second route, /jobs, exposes two operations that submit Hugging Face Jobs on behalf of the user. Both run via HfApi.run_uv_job and report CI-style status back into the UI.

Operation Submits Output
Request a new model jobs_scripts/extract_vectors.py hf://buckets/HF-slyfox/emotion-vectors/<model_id>/
Analyze traces jobs_scripts/analyze_traces.py hf://buckets/<source>/trace-analysis/<run_id>/

API surface (additive β€” none of the existing /api/chats/* routes change):

POST /api/models/extract            { model_id, flavor? }
POST /api/analyses                  { source, prefix?, n_traces, model_id, flavor? }
GET  /api/jobs                      list slyfox-submitted jobs with live status
GET  /api/jobs/{job_id}             one job's record + live status
GET  /api/jobs/{job_id}/logs        tail of the job's stdout/stderr
POST /api/jobs/{job_id}/cancel      cancel a running/queued job

Bucket layout extension:

SLYFOX_BUCKET/
  ...existing chat layout...
  jobs/<job_id>.json     # sidecar record for each submitted job

Extra env vars:

Variable Default Description
SLYFOX_JOBS_REF main Git ref of huggingface/slyfox to pull UV scripts from.
SLYFOX_VECTORS_BUCKET HF-slyfox/emotion-vectors Where extracted vectors land.
SLYFOX_COMMUNITY_BUCKET HF-slyfox/community-index Public index of opt-in shared runs.

Community (v0)

A third route, /community, is a placeholder for the upcoming public catalog of opt-in shared analysis runs. The /api/community/runs endpoint already reads from SLYFOX_COMMUNITY_BUCKET; the publish-side flow (hf upload-traces --share community) is on the roadmap. See COMMUNITY.md for the full design.