feat(overview): live fleet dashboard — online / offered / busy + usage + endpoints - #52
Conversation
…ints) `model overview` was a static description; `model overview --live` now probes the running deployment and shows what it's actually doing: - online — per-backend health - offered — served + candidate models, task families, the endpoint list - busy — in-flight / queued requests (vLLM num_requests_running/waiting) - usage — cumulative prompt/generation tokens + finished requests by reason - endpoints Read-only and HTTP-only, so it works against a local deployment or a `model tunnel` hostname alike, and degrades gracefully when a backend/metrics is down. The fleet's backends are internal-only, so the gateway grows a model-gear-native `GET /status` that fans out to each backend's /health + /metrics and returns one JSON aggregate (`object: model-gear.fleet_status`); a bare single-model server is read directly from its /metrics + /health. New stdlib `model_gear._metrics` parses vLLM's Prometheus exposition + best-effort HTTP probes that never raise. Pure section builders + an injected probe seam → fully unit-tested without sockets (verified live against the running :8001 backend: real token/usage counts). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NnDfFkZkXz8C68hr3AA9Qa
PR Summary by QodoAdd live fleet dashboard to Description
Diagram
High-Level Assessment
Files changed (9)
|
Code Review by Qodo
Context used✅ Compliance rules (platform):
35 rules✅ Skills:
|
- _metrics.parse_metrics: skip non-finite (NaN/inf) values — int() would raise and break the best-effort contract (Qodo #1). - _metrics.http_get_text: cap the body at 5 MiB (read max_bytes+1, treat overflow as unavailable) so a misbehaving backend can't stress memory (Qodo #2). - gateway /status: drop base_url from the payload — it's internal-only routing detail and /status may be reached over a public tunnel; matches the documented schema (Qodo #3). - gateway fleet_status_payload: probe backends in parallel (ThreadPoolExecutor) with a bounded 3s timeout, so /status can't hang for timeout × N on a slow backend (Qodo #4); and probe_backend short-circuits /metrics when /health fails (colleague review). Order preserved. Tests for each; 345 pass; black/isort/flake8/bandit clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NnDfFkZkXz8C68hr3AA9Qa
|
Addressed all 4 Qodo findings + the colleague review in
Tests added for each; 345 pass; black/isort/flake8/bandit/markdownlint/rubric-gate clean.
|
- _metrics.parse_metrics (S3776, complexity 24>15): extract `_iter_samples` for the line parsing and dict-dispatch the four summed series via `_SUM_FIELDS`, so the function body is a flat accumulate loop well under the threshold. - _metrics.http_get_text (S5713): drop `urllib.error.URLError` from the except — it is an `OSError` subclass already caught; removed the now-unused import. - cmd_overview (S3516, always returns same value): pick subject+sections in the branch, emit + `return 0` once. 345 tests pass; black/isort/flake8 clean. No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NnDfFkZkXz8C68hr3AA9Qa
|



What
model overviewwas a static description of the tool.model overview --livenowprobes the running deployment and answers the five "what is the fleet doing
right now" questions:
num_requests_running/waiting)It is read-only and HTTP-only, so it works against a local deployment or a
model tunnelhostname alike, and degrades gracefully when a backend or itsmetrics is unreachable.
How
The fleet's backends are internal-only (only the gateway port is published), so
the host CLI can't reach them directly. The gateway therefore grows a
model-gear-native
GET /statusthat fans out to each backend's/health+/metricsand returns one JSON aggregate:{"object":"model-gear.fleet_status","default_model":"…","busy":{"running":1,"waiting":0}, "backends":[{"name":"primary","task":"generate","served_name":"…","health":"ok","metrics":{…}}], "endpoints":[…]}A bare single-model server has no
/status, so--livereads it directly from its/metrics+/health. New stdlibmodel_gear._metricsparses vLLM'sPrometheus exposition (running/waiting, prompt/generation tokens,
request_success_totalby finish reason, KV-cache usage) with best-effort HTTPprobes that never raise.
Pure section builders + an injected probe seam → fully unit-tested without sockets.
Tests / validation
tests/test_overview_live.py(metrics parsing, sectionbuilders,
live_sectionsfleet/single/nothing discrimination, the CLI verb) +tests/test_gateway_status.py(the/statusfan-out + endpoint-by-task-family,unreachable backends).
:8001backend — real token/usage countsabove came straight from it (read-only
/metrics+/health; no tool calls, nodisruption to the mesh).
Builds on #51 (durable logs), now merged.
🤖 Generated with Claude Code