Files
ducoterra 219d7a7c3b phase: 34_radiance_llm_engine
Everything is verified and green. Final report:

**Phase 34 final verification pass — complete**

- Verified all 6 completed tasks' work against the live fleet and hermetic suite: `llm:radiance` job registered, `llm_engines()` registry drives 404 gate / history defaults / `/api/config` (additive, byte-identical gufo/vllm keys), radiance field map + `/stats` sidecar + 7-position spec curve, `/llm` strip/curve/rows.
- **Defect found & fixed (pre-existing, task 05):** the vLLM-only sentence "vLLM exposes no per-slot JSON…" rendered on the **radiance** panel (`slotSection`'s non-gufo branch). Fix: vLLM line gated to `engine === 'vllm'`; radiance's panel slot section renders nothing (its session home is the strip) — `page-llm.js` + the served-byte pin in `tests/test_api.py` (now asserts the radiance branch is empty and the sentence can't leak). Browser-verified; re-shot `data/logs/34-llm-radiance-rest.png` (the 4.5-min wait found no in-flight request, so the busy shot remains the earlier pass's — its strip rows still stand; only the panel text predates the fix).
- Tests: `uv run pytest` → **2031 passed, 19 skipped** (100%); `uv run pytest --cov` → **98.73%** (floor 94%; config 100%, llm 99%, collectors 98%, api 99%); `uv run ruff check src tests agent && uv run pyright` → clean; `node --check` OK; `uv pip list --outdated` → empty.
- `uv run pytest -m live --live` → **13 passed, 2 skipped** (vLLM unset — correct; live-write opt-in — correct); the read-only radiance test passed.
- Completion criteria: (1) engines `gufo`+`radiance`, `fleet.engines_live` 2, `config.llm.radiance.enabled` true — **pass (live curl)**; (2) unset → 404 no-dial + no job — **pass (spy-pinned, green)**; (3) fixtures present, both families (79 `radiance:` / 198 `vllm:` lines), drift pin — **pass**; (4) panel/curve/rows — **pass (re-shot rest screenshot)**; (5) live radiance test — **pass**; (6) suite/coverage/lint/`bash .agents/validate.sh` (exit 0) — **pass**; (7) docs — below; (8) gufo/vLLM behaviour unchanged — **pass (existing pins untouched)**.
- Documentation: **README.md** full review — env table, LLM-engines section, architecture diagram, capture-script and `/llm` section all name radiance correctly; no inconsistencies found, no changes needed. **AGENTS.md** — the three task-06 fixes (fleet line, route row, module bullets) are in place and all other statements match reality; no changes needed.
- Dev server healthy (`./scripts/dev-server.sh status`: all sources ok, `llm:radiance` answering); all changes left in the working tree for the harness.
- Next pending phase: none — 34 was the last phase in `todo/`.
2026-11-01 18:53:46 -05:00

134 lines
5.6 KiB
Python

"""The hand-rolled Prometheus parser, tested against real engine expositions.
This parser exists so the app has no Prometheus dependency for the two upstreams that
already speak the format. That makes it load-bearing on text we do not control: llama.cpp
emits names with colons, vLLM emits label sets and histograms, and both are free to change
them. Fixtures are captured verbatim (scripts/capture-fixtures.sh --with-llm).
"""
from __future__ import annotations
import math
from dashboards.prom import Prom
def test_parses_counters_and_gauges_from_a_real_capture(metrics_text) -> None:
prom = Prom(metrics_text("gufo"))
# the capture's counters and gauges are live numbers (volatile between
# re-captures): the pin is that they parse at all, in a sane range
generated = prom.scalar(["llamacpp:tokens_predicted_total"])
assert generated is not None and generated >= 0
usage = prom.scalar(["llamacpp:kv_cache_usage_ratio"])
assert usage is not None and 0.0 <= usage <= 1.0
assert prom.parse_errors == 0
def test_help_and_type_comments_are_not_samples(metrics_text) -> None:
prom = Prom(metrics_text("gufo"))
assert not any(name.startswith("#") for name in prom.series)
assert "# HELP llamacpp:prompt_tokens_total" not in prom.series
def test_labels_are_parsed_and_filterable(metrics_text) -> None:
prom = Prom(metrics_text("vllm"))
running = prom.values(["vllm:num_requests_running"])
assert running, "vLLM exposes num_requests_running"
by_model = prom.by_label(["vllm:generation_tokens_total"], "model_name")
assert by_model and all(model for model in by_model)
def test_values_by_series_keeps_the_label_sets_apart() -> None:
"""Counter deltas diff per label set; the summed view would let a joining series
lend its carried value to one interval (phase 13). This is the accessor that view."""
prom = Prom('x{a="1"} 5.0\nx{a="2"} 7.0\ny 1.0\n')
assert prom.values_by_series(["x"]) == [({"a": "1"}, 5.0), ({"a": "2"}, 7.0)]
assert prom.values_by_series(["y"]) == [({}, 1.0)]
assert prom.values_by_series(["x"], {"a": "2"}) == [({"a": "2"}, 7.0)]
assert prom.values_by_series(["nope"]) == []
def test_values_by_series_on_a_real_labelled_capture(metrics_text) -> None:
prom = Prom(metrics_text("vllm"))
series = prom.values_by_series(["vllm:generation_tokens_total"])
assert series, "vLLM exposes generation_tokens_total"
assert all(labels.get("model_name") for labels, _v in series), "the capture lost its labels"
def test_aggregations(metrics_text) -> None:
prom = Prom(metrics_text("vllm"))
total = prom.scalar(["vllm:prompt_tokens_total"], agg="sum")
assert total is not None and total > 1e6
# ratios must never be summed across label sets — a 3-way sum would read as 300% used
usage = prom.scalar(["vllm:kv_cache_usage_perc"], agg="max")
assert usage is not None and 0.0 <= usage <= 1.0
def test_missing_series_is_none_not_zero(metrics_text) -> None:
prom = Prom(metrics_text("gufo"))
assert prom.scalar(["vllm:does_not_exist"]) is None
assert prom.values(["vllm:does_not_exist"]) == []
assert prom.by_label(["nope"], "model_name") == {}
def test_histogram_mean_and_p95(metrics_text) -> None:
hist = Prom(metrics_text("vllm")).histogram(["vllm:time_to_first_token_seconds"])
assert hist is not None
assert hist["count"] and hist["count"] > 0
assert hist["mean"] and hist["mean"] > 0
assert hist["p95"] is not None
assert hist["p95"] >= hist["mean"], "p95 below the mean means the interpolation is wrong"
assert math.isfinite(hist["p95"])
def test_histogram_resolves_through_suffixes(metrics_text) -> None:
prom = Prom(metrics_text("vllm"))
# the bare name never appears in the exposition; only _bucket/_sum/_count do
assert "vllm:time_to_first_token_seconds" not in prom.series
assert prom.resolve_hist(["vllm:time_to_first_token_seconds"]) == "vllm:time_to_first_token_seconds"
assert prom.resolve(["vllm:time_to_first_token_seconds"]) is None
def test_resolve_returns_the_first_present_name() -> None:
prom = Prom('a_total 5\nb_total 7\n')
assert prom.resolve(["missing_total", "b_total", "a_total"]) == "b_total"
assert prom.resolve(["nope"]) is None
def test_label_match_narrows_the_series() -> None:
prom = Prom('x{engine="0"} 1\nx{engine="1"} 2\n')
assert prom.scalar(["x"], agg="sum") == 3
assert prom.scalar(["x"], label_match={"engine": "1"}) == 2
assert prom.scalar(["x"], label_match={"engine": "9"}) is None
def test_malformed_lines_are_counted_not_fatal() -> None:
prom = Prom("good_metric 1\nthis is not prometheus\nalso_bad{unclosed 2\n")
assert prom.scalar(["good_metric"]) == 1.0
assert prom.parse_errors >= 1
def test_empty_exposition_is_harmless() -> None:
prom = Prom("")
assert prom.series == {}
assert prom.scalar(["anything"]) is None
assert prom.histogram(["anything"]) is None
def test_quantile_ignores_non_finite_values() -> None:
prom = Prom('m_sum 10\ncount 2\nm{le="1"} NaN\n')
assert prom.scalar(["m"], label_match={"le": "1"}) is None
def test_multiple_histogram_label_sets_do_not_invent_a_p95(metrics_text) -> None:
"""Mixing per-DP-rank buckets into one cumulative curve would fabricate a percentile."""
two = (
'h_sum{dp="0"} 10\nh_sum{dp="1"} 10\n'
'h_count{dp="0"} 2\nh_count{dp="1"} 2\n'
'h_bucket{dp="0",le="1"} 1\nh_bucket{dp="0",le="+Inf"} 2\n'
'h_bucket{dp="1",le="1"} 1\nh_bucket{dp="1",le="+Inf"} 2\n'
)
hist = Prom(two).histogram(["h"])
assert hist is not None
assert hist["mean"] == 5.0
assert hist["p95"] is None, "p95 across mixed label sets is a made-up number"