Spaces:
Running
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.