Dashboard
Watch reward, KL, MFU, and response length live
rl ships a self-contained training dashboard that reads your run logs and renders live metric charts, a run comparison view, an agent-trajectory browser, and optional LLM analysis — open it locally, or publish it to Cloudflare Pages for remote viewing.
Live board (once published to Cloudflare Pages): swe-lego-rl-dashboard.pages.dev. For local viewing, serve it with dashboard/serve.sh (see below).
The app is vendored into the block at dashboard/webui/ (a React/Vite
frontend with a prebuilt dist/ committed, plus a pure-stdlib server.py
backend), copied out of the read-only harbor-verl-train submodule so the block
owns and versions it.
What it monitors
server.py discovers .log/.out files (non-recursively, skipping *_vllm.log)
as runs and parses the verl step:N - key:value - ... lines, cleaning numpy
wrappers like np.float64(...). The wrapper points it at:
| Source | Path |
|---|---|
| Background-launch wrapper logs | logs/launch_*.log |
| Upstream per-exp training logs | repos/harbor-verl-train/logs/*.log |
For each run it surfaces the full per-step metric set — reward (critic/score/mean),
actor/entropy, actor/ppo_kl, actor/pg_clipfrac, perf/mfu/*,
response_length/*, rollout_corr/kl, and val-* — plus a trajectory browser
over the per-trial harbor_trials/ logs.
Not the Harbor job dirs
Runs come from log files, not Harbor trial directories. Nested
outputs/<date>/<time>/main_ppo.log is intentionally not discovered — the same
step: lines appear in the launch logs.
Run it locally
Drive it with the block-level wrapper from subblock/rl/:
PORT=8090 bash dashboard/serve.sh start # background; prints URL + pid
bash dashboard/serve.sh status # probe http://127.0.0.1:8090/api/config
bash dashboard/serve.sh stopThen open http://<host-ip>:8090. The prebuilt dist/ ships in the repo, so no
npm build is needed to serve. Override PORT, HOST, LOG_DIR,
EXTRA_LOG_DIR, or WANDB_ENTITY/WANDB_PROJECT/WANDB_API_KEY via env.
For a quick public URL, add TUNNEL=true (uses cloudflared if installed); the
URL is printed into dashboard/.tunnel.log.
Publish to Cloudflare Pages
dashboard/run_cloudflare_pages_sync.sh deploys dashboard/webui/dist + the
Pages Functions to Cloudflare Pages:
bash dashboard/run_cloudflare_pages_sync.shConfiguration is read from ~/.config/rl_dashboard_cloudflare.env:
| Variable | How to fill it | Default |
|---|---|---|
CLOUDFLARE_API_TOKEN | API token with account-level Cloudflare Pages: Edit | required |
CLOUDFLARE_ACCOUNT_ID | 32-char Account ID from the dashboard | required |
PROJECT_NAME | Cloudflare Pages project (sets the public URL) | swe-lego-rl-dashboard |
WANDB_API_KEY / WANDB_ENTITY / WANDB_PROJECT | pushed as Pages secrets | optional |
Cloud is wandb-only
In the cloud the dashboard is served by webui/functions/api/[[path]].ts, which
reads runs/metrics straight from the wandb API — it does not see local log
files. So the published board reflects the configured wandb project, while the
local server reads your launch logs.
Via slash command
From inside subblock/rl/: /rl:dashboard start|status|stop|deploy — see the
dashboard skill under .claude/plugins/rl-plugin/skills/.