Spaces:
Sleeping
title: Agent Dashboards
emoji: π
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: false
Agent Dashboards
A tiny, agent-updatable dashboard service. Agents create/update dashboards and push data over a REST API; each dashboard is served at its own URL as rendered HTML (and as JSON).
Mutations update an in-memory store immediately. The store is synced to durable backups once a day
at SYNC_HOUR (SYNC_TZ) β GitHub repo GITHUB_REPO (primary) + HF Dataset DATASET_REPO
(fallback) β and also on graceful shutdown or on demand via POST /api/sync. On boot it loads from
GitHub, falling back to the HF Dataset. Write endpoints require Authorization: Bearer <AGENT_KEY>.
Note: because remote sync is daily (not per-write), changes made since the last sync are lost if the
Space is killed ungracefully before the next sync β call POST /api/sync after important updates.
Endpoints
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | / |
public | HTML index of dashboards |
| GET | /d/{id} |
public | Rendered HTML dashboard |
| GET | /health |
public | Liveness + dashboard count |
| GET | /api/dashboards |
bearer | List dashboards (JSON) |
| GET | /api/dashboards/{id} |
bearer | One dashboard (JSON) |
| POST | /api/dashboards |
bearer | Create/replace a dashboard |
| PUT | /api/dashboards/{id} |
bearer | Update title/widgets (layout) |
| PUT | /api/dashboards/{id}/data |
bearer | Merge data values only |
| DELETE | /api/dashboards/{id} |
bearer | Delete a dashboard |
Dashboard shape
{
"id": "sales",
"title": "Sales",
"widgets": [
{"type": "metric", "title": "Revenue", "dataKey": "rev", "unit": "$"},
{"type": "chart", "title": "Weekly", "chart": "line", "dataKey": "weekly"},
{"type": "table", "title": "Top deals", "dataKey": "deals"}
],
"data": {
"rev": {"value": 42000, "delta": 5.2},
"weekly": {"labels": ["Mon","Tue","Wed"], "series": [{"name":"2026","data":[10,20,15]}]},
"deals": {"columns": ["Account","Amount"], "rows": [["Acme", 1200], ["Globex", 900]]}
}
}
Widget types: metric, chart (line/bar), table, text. A widget reads its values from
data[dataKey] (so you can define the layout once, then just PUT β¦/data to refresh numbers), or
you can inline the values directly on the widget.