Skip to content

Commit 7e3b814

Browse files
committed
feat: replace Streamlit with a React (Vite+TS+Tailwind) SPA; add CORS; deploy web as a Render static site
1 parent e010585 commit 7e3b814

45 files changed

Lines changed: 4222 additions & 773 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/keepalive.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ jobs:
2121
echo
2222
echo "Pinging dashboard..."
2323
curl -sS --retry 3 --retry-all-errors -m 120 -o /dev/null \
24-
https://agentwatch-dashboard-zner.onrender.com/ || true
24+
https://agentwatch-web.onrender.com/ || true
2525
echo "done"

.streamlit/config.toml

Lines changed: 0 additions & 10 deletions
This file was deleted.

Dockerfile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ WORKDIR /app
55

66
COPY pyproject.toml README.md ./
77
COPY agentwatch ./agentwatch
8-
COPY dashboard ./dashboard
98
COPY migrations ./migrations
109
COPY alembic.ini ./
1110
COPY scripts ./scripts
12-
COPY .streamlit ./.streamlit
1311

14-
RUN pip install --upgrade pip && pip install ".[dashboard]" && chmod +x scripts/*.sh
12+
RUN pip install --upgrade pip && pip install "." && chmod +x scripts/*.sh
1513

1614
# Default command is the API entrypoint (migrate + serve). Compose / Render override
1715
# with a single-token script path per service so no shell quoting is involved.

README.md

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
| | |
1212
|---|---|
13-
| 🖥️ **Dashboard** | <https://agentwatch-dashboard-zner.onrender.com> |
13+
| 🖥️ **Dashboard** | <https://agentwatch-web.onrender.com> |
1414
| 📡 **API docs** | <https://agentwatch-api-7mhz.onrender.com/docs> |
1515
| 📖 **Documentation** | <https://kohsheen1234.github.io/Open-source-AI-Incident-Observatory/> |
1616

@@ -112,7 +112,7 @@ complete and tested — provides:
112112
| **Abstain-capable taxonomy** | Ten incident types plus an explicit *insufficient_evidence* outcome, so the system distinguishes "no incident" from "not enough evidence". |
113113
| **Measured quality** | A labelled evaluation set with precision / recall / macro-F1 / confusion matrix / abstention rate, and a regression test that fails if macro-F1 drops below a committed floor. |
114114
| **Documented HTTP API** | A FastAPI service (list / filter / detail / review / stats / CSV export) with auto-generated OpenAPI docs and optional API-key auth on writes. |
115-
| **Review dashboard** | A Streamlit app (overview, incident explorer, review queue) that consumes the API — reviewers accept, override, or flag classifications. |
115+
| **Review dashboard** | A React single-page app (overview, incident explorer, review queue) that consumes the API — reviewers accept, override, or flag classifications. |
116116
| **Metrics & dashboards** | The API exposes Prometheus metrics; Prometheus scrapes them and a provisioned Grafana dashboard visualises incidents, classifications, abstention rate, and collection-run health. |
117117
| **One-command stack** | `docker compose up` brings up db, API, dashboard, Prometheus, Grafana, and a Caddy reverse proxy (auto-HTTPS in production) on one network. |
118118
| **Test suite** | Every component is covered by tests that run in under a second. |
@@ -260,21 +260,23 @@ Reads are public. If `AGENTWATCH_API_KEY` is set, writes (review) and CSV export
260260
require an `X-API-Key` header — so a reviewer can run it locally with zero config,
261261
while production can lock it down.
262262

263-
## The dashboard
263+
## The web dashboard
264264

265-
The Streamlit dashboard consumes the API (it never touches the database directly):
265+
The dashboard is a **React single-page app** (Vite + TypeScript + Tailwind, charts with
266+
Recharts) in [`frontend/`](frontend/). It only ever talks to the HTTP API. Run it locally:
266267

267268
```bash
268-
# In one terminal: run the API
269-
agentwatch serve
270-
# In another: run the dashboard (install the extra first)
271-
pip install -e ".[dashboard]"
272-
AGENTWATCH_API_URL=http://localhost:8000 streamlit run dashboard/app.py
269+
cd frontend
270+
npm install
271+
VITE_API_URL=http://localhost:8000 npm run dev # dev server on http://localhost:5173
273272
```
274273

275-
Pages: **Overview** (headline metrics + incidents-by-type chart), **Incident Explorer**
276-
(filterable table), and **Review Queue** (open an incident, see its evidence and
277-
classification, and submit a review).
274+
The whole stack (API + web behind Caddy) also comes up with `make up` — see
275+
[Run the whole system](#run-the-whole-system).
276+
277+
Pages: **Overview** (mission, pipeline, KPIs, and interactive charts), **Incident
278+
Explorer** (filterable table with colored type/severity badges and per-incident evidence),
279+
and **Review Queue** (accept / override / flag a classification).
278280

279281
## Configuration
280282

@@ -291,11 +293,13 @@ All configuration is read from environment variables prefixed `AGENTWATCH_`
291293
| `AGENTWATCH_REDDIT_CLIENT_ID` | _(unset)_ | Enables the opt-in Reddit source |
292294
| `AGENTWATCH_REDDIT_CLIENT_SECRET` | _(unset)_ | Enables the opt-in Reddit source |
293295
| `AGENTWATCH_API_KEY` | _(unset)_ | If set, required (`X-API-Key`) for API writes and export |
294-
| `AGENTWATCH_API_URL` | `http://localhost:8000` | API base URL the dashboard talks to |
296+
297+
The web app is configured at build time with `VITE_API_URL` (the API base URL it calls).
295298

296299
## Tech stack
297300

298-
Python 3.12 · SQLAlchemy 2.0 · Alembic · Pydantic · FastAPI · uvicorn · Streamlit ·
301+
Python 3.12 · SQLAlchemy 2.0 · Alembic · Pydantic · FastAPI · uvicorn ·
302+
React + Vite + TypeScript + Tailwind + Recharts (frontend) ·
299303
httpx · tenacity · APScheduler · structlog · PostgreSQL 16 · Docker Compose ·
300304
pytest · ruff.
301305

@@ -344,7 +348,7 @@ agentwatch/ # the package
344348
cli.py # `agentwatch` command-line interface
345349
scheduler.py # APScheduler-based recurring collection
346350
db/ # SQLAlchemy models, base, portable types, session management
347-
dashboard/ # Streamlit dashboard + API client
351+
frontend/ # React + Vite + TypeScript + Tailwind single-page app (the web UI)
348352
migrations/ # Alembic migration environment and versions
349353
deploy/ # docker-compose service definitions
350354
docs/ # MkDocs documentation site

agentwatch/api/app.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from fastapi import Depends, FastAPI, HTTPException, Query
2+
from fastapi.middleware.cors import CORSMiddleware
23

34
from agentwatch.api import queries
45
from agentwatch.api.auth import require_api_key
@@ -60,6 +61,14 @@ def create_app() -> FastAPI:
6061
version="0.1.0",
6162
root_path=get_settings().api_root_path,
6263
)
64+
# Allow the browser SPA (served from a different origin) to call the API. Reads are
65+
# public; write routes remain gated by the optional API key.
66+
app.add_middleware(
67+
CORSMiddleware,
68+
allow_origins=["*"],
69+
allow_methods=["*"],
70+
allow_headers=["*"],
71+
)
6372

6473
@app.get("/health")
6574
def health() -> dict:

dashboard/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)