chore(agent): phase roadmap from TODO.md, 5 phases
The five UI items in TODO.md become an executable pipeline. Planning files only — no application code changed. - 01_severity_language: one Python threshold table + `severity` on the values the pages colour, plus the .hero style. Today the thresholds are magic numbers at six JS call sites (75/90 here, 80/92 there), which is exactly how "same colour, four meanings" happens. - 02_overview_fleet_and_alerts: /api/summary gains a derived `alerts` list; the page drops to fleet + warnings. Unconfigured sources must not alert — that is invariant 3, tested. - 03_system_per_host_panels: per-host hero cards, no per-core, shared multi-host charts and the detail picker deleted. The six card metrics already exist in the payload, so the first task pins them with tests instead of inventing fields. - 04_llm_chart_readability: charts.js already exports sparkline() and no page calls it — that is why the page reads flat. Port llm_monitor's drawSpark behaviour (fixed max, right growth, p95 foots) and keep the provenance tags. - 05_ups_hero_battery_glyph: charge/load/runtime hero + an SVG battery whose fill is the charge, verified against both real UPSes and the low-charge/on-battery states only the simulator can produce. PLAN.md records the ratified anchors and the deviation worth knowing: severity vocabulary is ok|warn|fail, matching dash.css and nut.py, not the "danger" wording in the proposal — one synonym for one colour. TODO.md cleared to a bare heading; the items are now phases. .gitignore stops ignoring all of .agents/ (the roadmap is project history) while keeping phase-sessions/ and pipeline.log out. deploy/nut-sudoers rewritten: its header still blamed a port mystery that is solved; the remaining need is reading upsd.users so adding a scoped dashboards user does not delete the accounts upsmon authenticates as. LLM-Generated: true
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
# Phase 04 — LLM page is readable again
|
||||
|
||||
**Source:** `TODO.md` L6 — "LLM usage drifed from initial request to copy Experimental/llm_monitor. The charts got less useful. Need simplified and more readable."
|
||||
**Story:** n/a
|
||||
**Context:** `.agents/PLAN.md` → *Anchors* (hand-rolled SVG only), `~/Projects/Experimental/llm_monitor/static/index.html` (the reference implementation), `src/dashboards/web/static/page-llm.js` (`CELLS`, `makeCharts`), `src/dashboards/web/static/charts.js` (`sparkline`, `LineChart`), `src/dashboards/sources/llm.py`
|
||||
|
||||
## Objective
|
||||
|
||||
The LLM page drifted into a 14-cell grid where everything is the same size and nothing shows
|
||||
recent shape. Bring back what made `llm_monitor` legible — big throughput numbers, a sparkline
|
||||
in each metric cell, percentiles as foot lines — without losing what this project added since:
|
||||
per-engine provenance tags, history windows, and severity colour.
|
||||
|
||||
`llm_monitor` is the design reference, not a dependency. It is a separate app on `:8095` and
|
||||
stays that way; nothing here imports from it.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `01_severity_language` (todo) — KV-cache pressure and queue depth get coloured from the
|
||||
API verdict, not a per-page threshold.
|
||||
- `03_system_per_host_panels` (todo) — touches `charts.js` first; this phase builds on the
|
||||
same shared helpers and must not fight it for them.
|
||||
|
||||
## Tasks
|
||||
|
||||
1. `01_chart_set_decision.md` — read both implementations side by side and write the decision note (which cells live, which get sparklines, what is demoted).
|
||||
2. `02_sparkline_upgrade.md` — bring `DashCharts.sparkline()` up to `llm_monitor`'s `drawSpark` behaviour: right-aligned growth, fixed max, current/max labels, severity colour.
|
||||
3. `03_llm_layout_simplified.md` — restructure `llm.html` + `page-llm.js`: hero throughput, compact sparkline cells, percentile foot lines, conditional alarm cells.
|
||||
4. `04_side_by_side_verification.md` — verify against `llm_monitor` on `:8095` with the same live engines.
|
||||
|
||||
## Testing & Quality
|
||||
|
||||
- Python: none expected beyond the phase-01 severity fields; `/api/llm/*` stays as-is
|
||||
(additive-only anchor).
|
||||
- `uv run pytest -m live --live` must stay green — `test_engine_still_publishes_the_series_we_parse`
|
||||
is the assertion that the numbers on screen are backed by resolved upstream series.
|
||||
- Browser: both engines live (gufo on `deskwork:8731`, vLLM on `driveripper:8000`), plus the
|
||||
single-engine case: with one `*_BASE_URL` unset the page must show one clean half rather
|
||||
than a red panel.
|
||||
- Coverage: ≥94% overall maintained.
|
||||
|
||||
## Completion Criteria
|
||||
|
||||
- [ ] decode and prompt throughput are the two largest numbers per engine, colour-coded
|
||||
- [ ] every remaining metric cell carries a sparkline showing the selected window
|
||||
- [ ] latency cells show mean **and** p95 without needing a hover
|
||||
- [ ] a source-provenance tag is still visible on every throughput number (`AGENTS.md`: never invent a number)
|
||||
- [ ] `/llm` with only one engine configured still renders cleanly
|
||||
- [ ] screenshots of this page and `llm_monitor` side by side in `data/logs/`, plus `NOTES-chart-set.md`
|
||||
- [ ] `uv run pytest` green, coverage ≥94%, `ruff` + `pyright` clean
|
||||
- [ ] no behavior change in completed phases
|
||||
Reference in New Issue
Block a user