HERMES-GIELIE/static
nesquena-hermes 04066b4b43 feat(insights): surface prompt-cache hit rate (salvage of #3912)
Surfaces prompt-cache hit rate on the Insights page so cache-efficiency
(a key cost-optimisation signal) is visible at a glance.

Backend (api/routes.py, _handle_insights):
- Aggregate cache_read_tokens per model and per day, plus a total.
- Graceful fallback for older agent state.db schemas lacking the
  cache_read_tokens column (COALESCE + OperationalError second query).
- New response fields: total_cache_read_tokens, total_cache_hit_percent,
  per-model cache_read_tokens + cache_hit_percent, per-day cache_read_tokens.

Frontend:
- Models table gains a Cache column (panels.js + style.css 6-col grid).
- Daily bar tooltip includes the bounded cache hit rate.
- New i18n keys insights_model_cache / insights_cache_hit in all 13 locales.

Correctness fix (maintainer-flagged on #3912): the original computed
hit-rate as cache_read / input_tokens (reads-over-misses), which EXCEEDS
100% on cache-heavy sessions. This uses the FULL prompt total as the
denominator -- cache_read / (input_tokens + cache_read) -- via the shared
api.usage.prompt_cache_hit_percent helper, so it is bounded 0-100% and
means "% of the prompt served from cache". Returns None (rendered as a
muted dash) when there are no cache reads.

Tests (tests/test_insights.py):
- Updated existing assertions for the new response shape.
- Added a non-vacuous <=100% boundary test: a cache-heavy case
  (cache_read=9900, input=100) where the OLD formula reports 9900% but the
  bounded denominator yields 99%. Verified the test FAILS under the old
  formula and PASSES under the fix.

Salvage note: PR #3912's diff was ~99 releases stale (mostly re-derived old
code, illusory +5405). This ports ONLY the real ~190-line feature fresh
onto current master.

Closes #3911

Co-authored-by: TomBanksAU <TomBanksAU@users.noreply.github.com>
2026-06-28 08:11:22 +00:00
..
vendor fix: protect pipes inside backtick code spans in renderMd tables 2026-06-25 08:25:58 +00:00
apple-touch-icon.png
assistant_turn_anchors.js Add assistant turn anchor renderer snapshot adapter 2026-06-14 02:03:45 +08:00
boot.js Clear archived saved session on boot restore 2026-06-28 06:51:36 +00:00
commands.js fix(steer): rename typo, catch retry rejection, update JSDoc (#4749) 2026-06-25 03:23:36 +00:00
favicon-32.png
favicon-192.png
favicon-512.png
favicon-512.svg
favicon.ico
favicon.svg
i18n.js feat(insights): surface prompt-cache hit rate (salvage of #3912) 2026-06-28 08:11:22 +00:00
icons.js stage #4581 onto master (v0.51.556) — surface escape-target symlinks as display-only workspace rows 2026-06-21 09:15:22 +00:00
index.html theme-registration: preserve pending ext skin across reload + expand accent token allowlist 2026-06-28 05:22:26 +00:00
login.js
manifest.json
messages.js feat(moa): route /moa through WebUI via server-resolved MoA config (#5070, #5057) 2026-06-28 00:23:51 +00:00
onboarding.js fix(onboarding): rehydrate plain-select fallback so saved model isn't reset to option[0] 2026-06-27 04:33:02 +00:00
outline.js fix(outline): keep outline valid on the todos sidebar panel (Opus follow-up) 2026-06-10 23:55:05 +00:00
panels.js feat(insights): surface prompt-cache hit rate (salvage of #3912) 2026-06-28 08:11:22 +00:00
pwa-startup.js
sessions.js fix: skip archived saved session on boot 2026-06-28 06:51:36 +00:00
style.css feat(insights): surface prompt-cache hit rate (salvage of #3912) 2026-06-28 08:11:22 +00:00
sw.js fix: focus the existing chat tab when a notification is clicked instead of opening a new tab 2026-06-13 14:42:41 -07:00
terminal.js fix(#4313): guard EventSource.close() calls to suppress ERR_ABORTED noise 2026-06-18 17:25:18 +00:00
ui.js fix(workspace): live-sync active Workspace Todos tab 2026-06-28 07:28:30 +00:00
workspace.js fix(workspace): live-sync active Workspace Todos tab 2026-06-28 07:28:30 +00:00