mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-10 14:27:00 -04:00
fix(dashboard): deduplicate repeated savings metrics (#1804)
Some checks failed
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime name:]) (push) Waiting to run
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code name:code]) (push) Waiting to run
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Waiting to run
CI / changes (push) Failing after 38s
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-slim name:code-slim]) (push) Waiting to run
Docker / docker-manifest (map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Blocked by required conditions
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Waiting to run
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-nonroot name:nonroot]) (push) Waiting to run
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-slim name:slim]) (push) Waiting to run
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime name:]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code name:code]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-slim name:code-slim]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Waiting to run
CI / commitlint (push) Failing after 3s
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-nonroot name:nonroot]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-slim name:slim]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Waiting to run
Docker / docker-manifest (map[bake_target:runtime name:]) (push) Blocked by required conditions
Docker / docker-manifest (map[bake_target:runtime-code name:code]) (push) Blocked by required conditions
CI / build-wheel (push) Failing after 3s
CI / lint (push) Failing after 3s
Docker / docker-manifest (map[bake_target:runtime-code-slim name:code-slim]) (push) Blocked by required conditions
Docker / docker-manifest (map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Blocked by required conditions
Docker / docker-manifest (map[bake_target:runtime-nonroot name:nonroot]) (push) Blocked by required conditions
CI / prefetch-model (push) Failing after 4s
Docker / docker-manifest (map[bake_target:runtime-slim name:slim]) (push) Blocked by required conditions
Docker / docker-manifest (map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Blocked by required conditions
Docker / promote-latest (push) Blocked by required conditions
CI / build (push) Failing after 2s
CI / workflow-validation (push) Failing after 6s
CI / test-extras (push) Failing after 3s
CI / docker-native-e2e (push) Failing after 5s
CI / test-agno (push) Failing after 3s
CI / test (1) (push) Failing after 4s
CI / test (2) (push) Failing after 7s
CI / test (3) (push) Failing after 4s
CI / test-dashboard-ui (push) Failing after 4s
Deploy Documentation / validate (push) Failing after 5s
CI / test (4) (push) Failing after 3s
Deploy Documentation / deploy (push) Failing after 9s
Init E2E / docker-init-e2e (push) Failing after 8s
Init Native E2E / init-native (ubuntu-latest, claude) (push) Failing after 18s
Init Native E2E / init-native (ubuntu-latest, codex) (push) Failing after 16s
Init Native E2E / init-native (ubuntu-latest, copilot) (push) Failing after 18s
Install Native E2E / install-native (ubuntu-latest) (push) Failing after 12s
Merge Conflicts / merge-conflicts (push) Failing after 12s
Release Please / release-please (push) Failing after 17s
Security / CodeQL (javascript-typescript) (push) Failing after 51s
Security / CodeQL (python) (push) Failing after 46s
Wrap E2E / docker-wrap-e2e (push) Failing after 18s
Security / Dependency audit (pip-audit) (push) Failing after 1m27s
Wrap Native E2E / wrap-native (ubuntu-latest) (push) Failing after 7s
Security / Secret scan (gitleaks) (push) Failing after 9m1s
CI / windows-native-wrapper (push) Has been cancelled
CI / macos-native-wrapper (push) Has been cancelled
Init Native E2E / init-native (macos-latest, claude) (push) Has been cancelled
Init Native E2E / init-native (macos-latest, codex) (push) Has been cancelled
Init Native E2E / init-native (macos-latest, copilot) (push) Has been cancelled
Install Native E2E / install-native (macos-latest) (push) Has been cancelled
Wrap Native E2E / wrap-native (macos-latest) (push) Has been cancelled
Some checks failed
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime name:]) (push) Waiting to run
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code name:code]) (push) Waiting to run
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Waiting to run
CI / changes (push) Failing after 38s
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-slim name:code-slim]) (push) Waiting to run
Docker / docker-manifest (map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Blocked by required conditions
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Waiting to run
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-nonroot name:nonroot]) (push) Waiting to run
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-slim name:slim]) (push) Waiting to run
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime name:]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code name:code]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-slim name:code-slim]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Waiting to run
CI / commitlint (push) Failing after 3s
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-nonroot name:nonroot]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-slim name:slim]) (push) Waiting to run
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Waiting to run
Docker / docker-manifest (map[bake_target:runtime name:]) (push) Blocked by required conditions
Docker / docker-manifest (map[bake_target:runtime-code name:code]) (push) Blocked by required conditions
CI / build-wheel (push) Failing after 3s
CI / lint (push) Failing after 3s
Docker / docker-manifest (map[bake_target:runtime-code-slim name:code-slim]) (push) Blocked by required conditions
Docker / docker-manifest (map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Blocked by required conditions
Docker / docker-manifest (map[bake_target:runtime-nonroot name:nonroot]) (push) Blocked by required conditions
CI / prefetch-model (push) Failing after 4s
Docker / docker-manifest (map[bake_target:runtime-slim name:slim]) (push) Blocked by required conditions
Docker / docker-manifest (map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Blocked by required conditions
Docker / promote-latest (push) Blocked by required conditions
CI / build (push) Failing after 2s
CI / workflow-validation (push) Failing after 6s
CI / test-extras (push) Failing after 3s
CI / docker-native-e2e (push) Failing after 5s
CI / test-agno (push) Failing after 3s
CI / test (1) (push) Failing after 4s
CI / test (2) (push) Failing after 7s
CI / test (3) (push) Failing after 4s
CI / test-dashboard-ui (push) Failing after 4s
Deploy Documentation / validate (push) Failing after 5s
CI / test (4) (push) Failing after 3s
Deploy Documentation / deploy (push) Failing after 9s
Init E2E / docker-init-e2e (push) Failing after 8s
Init Native E2E / init-native (ubuntu-latest, claude) (push) Failing after 18s
Init Native E2E / init-native (ubuntu-latest, codex) (push) Failing after 16s
Init Native E2E / init-native (ubuntu-latest, copilot) (push) Failing after 18s
Install Native E2E / install-native (ubuntu-latest) (push) Failing after 12s
Merge Conflicts / merge-conflicts (push) Failing after 12s
Release Please / release-please (push) Failing after 17s
Security / CodeQL (javascript-typescript) (push) Failing after 51s
Security / CodeQL (python) (push) Failing after 46s
Wrap E2E / docker-wrap-e2e (push) Failing after 18s
Security / Dependency audit (pip-audit) (push) Failing after 1m27s
Wrap Native E2E / wrap-native (ubuntu-latest) (push) Failing after 7s
Security / Secret scan (gitleaks) (push) Failing after 9m1s
CI / windows-native-wrapper (push) Has been cancelled
CI / macos-native-wrapper (push) Has been cancelled
Init Native E2E / init-native (macos-latest, claude) (push) Has been cancelled
Init Native E2E / init-native (macos-latest, codex) (push) Has been cancelled
Init Native E2E / init-native (macos-latest, copilot) (push) Has been cancelled
Install Native E2E / install-native (macos-latest) (push) Has been cancelled
Wrap Native E2E / wrap-native (macos-latest) (push) Has been cancelled
## Description The session dashboard repeats the same savings and performance numbers in adjacent places. `proxy_compression_saved` appears in several captions and detail rows, and average overhead and TTFB appear both in the hero area and again in Performance without adding new context. This narrows the non-hero dashboard presentation so repeated session metrics have one visible home plus decomposition where it adds information. It leaves `/stats`, savings math, cache attribution, and the hero proxy savings card unchanged. Refs #960 ## Type of Change - [x] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - Removed redundant non-hero session-view captions that restated proxy-compression token counts without adding a new dimension. - Kept canonical homes for proxy compression and token usage details. - Preserved Performance range context while avoiding adjacent restatement of hero averages. - Added a static dashboard regression for repeated session metrics. ## Testing - [x] Unit tests pass (`uv run pytest tests/test_proxy_dashboard_stats_cache.py -q`) - [x] Linting passes (`uv run ruff check tests/test_proxy_dashboard_stats_cache.py`) - [ ] Type checking passes (`uv run mypy headroom`) - [x] New tests added for new functionality - [x] Manual testing performed ### Test Output ```text $ uv run pytest tests/test_proxy_dashboard_stats_cache.py -q 12 passed, 1 skipped, 1 warning in 19.24s $ uv run ruff check tests/test_proxy_dashboard_stats_cache.py All checks passed! ``` ## Real Behavior Proof - Environment: Windows, Python environment from `uv sync --extra dev`, browserless dashboard HTML inspection. - Exact command / steps: load `get_dashboard_html()` in the focused dashboard stats test and assert removed duplicate captions stay removed while canonical metric owners remain present. - Observed result: session-view repeated savings and performance labels no longer duplicate the same numbers without context. - Not tested: full browser screenshot and history-view de-duplication. ## Review Readiness - [x] I have performed a self-review - [x] This PR is ready for human review ## Checklist - [x] My code follows the project's style guidelines - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] I have updated the CHANGELOG.md if applicable ## Additional Notes No `CHANGELOG.md` edit: this repo generates changelog entries from conventional commits. This intentionally avoids the hero proxy savings card already covered by #927 and #1649, and it does not fold provider cache discount into Headroom-value savings.
This commit is contained in:
parent
451b9f0867
commit
88f935a1eb
2 changed files with 11 additions and 9 deletions
|
|
@ -433,7 +433,6 @@
|
|||
<div>
|
||||
<div class="text-xs text-gray-500 mb-1">Compression</div>
|
||||
<div class="text-2xl font-light tabular-nums text-emerald-400" x-text="'$' + formatCurrency(stats.cost?.compression_savings_usd || 0)"></div>
|
||||
<div class="text-xs text-gray-500" x-text="formatNumber(stats.tokens?.proxy_compression_saved || 0) + ' proxy tokens removed'"></div>
|
||||
</div>
|
||||
<template x-if="(stats.cost?.cache_savings_usd || 0) > 0">
|
||||
<div>
|
||||
|
|
@ -1079,18 +1078,10 @@
|
|||
<div class="bg-surface rounded-lg p-4 border border-border">
|
||||
<div class="text-sm font-medium mb-4 text-gray-300">Performance</div>
|
||||
<div class="space-y-3">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-sm text-gray-400">Headroom Overhead</span>
|
||||
<span class="font-mono text-sm" x-text="(stats.overhead?.average_ms || 0).toFixed(0) + 'ms avg'"></span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-sm text-gray-400">Overhead Range</span>
|
||||
<span class="font-mono text-sm" x-text="(stats.overhead?.min_ms || 0).toFixed(0) + ' - ' + (stats.overhead?.max_ms || 0).toFixed(0) + 'ms'"></span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-sm text-gray-400">TTFB (upstream)</span>
|
||||
<span class="font-mono text-sm" x-text="((stats.ttfb?.average_ms || 0) / 1000).toFixed(2) + 's avg'"></span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-sm text-gray-400">TTFB Range</span>
|
||||
<span class="font-mono text-sm" x-text="((stats.ttfb?.min_ms || 0) / 1000).toFixed(2) + ' - ' + ((stats.ttfb?.max_ms || 0) / 1000).toFixed(2) + 's'"></span>
|
||||
|
|
|
|||
|
|
@ -605,6 +605,17 @@ def test_dashboard_uses_cached_stats_and_lazy_history_feed_polling() -> None:
|
|||
assert "cliFilteringLabel + ' Filtered (lifetime)'" in html
|
||||
|
||||
|
||||
def test_dashboard_session_metrics_do_not_repeat_proxy_tokens_without_new_context() -> None:
|
||||
html = get_dashboard_html()
|
||||
|
||||
assert "proxy tokens removed" not in html
|
||||
assert '<span class="text-sm text-gray-400">Headroom Overhead</span>' not in html
|
||||
assert '<span class="text-sm text-gray-400">TTFB (upstream)</span>' not in html
|
||||
assert "Overhead Range" in html
|
||||
assert "TTFB Range" in html
|
||||
assert "Proxy Removed" in html
|
||||
|
||||
|
||||
def test_proxy_throughput_in_stats_endpoint(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""Verify that the /stats endpoint includes a 'throughput' key in the response.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue