Dashboard plugin for inspecting the outbound LLM request Hermes sends on each API call, with emphasis on request snapshots and usage totals.
Hermes Web turns the raw internals of a Hermes runtime into a focused operations workspace:
- usage pressure and cache efficiency
- skill activity, now filterable by profile
- exact upstream request bodies and token estimates
- group chat rooms, agents, and message flow
The existing on-disk session snapshots under ~/.hermes/sessions/ are useful
for reconstructing conversation state, but they are not request-accurate:
- they store the current conversation snapshot, not one row per API request
- they do not preserve transport-specific request envelopes such as:
systemforanthropic_messagesinstructionsforcodex_responses- Bedrock Converse
system
- they do not capture API-call-time injected context such as memory/plugin additions in the exact shape sent upstream
- they do not provide per-request token bucket estimates
Hermes Web fills that gap by persisting a dedicated request snapshot just before
the provider call is made, while also surfacing usage metrics from state.db.
run_agent.pybuildsapi_messagesandapi_kwargs.- Immediately before the provider call, Hermes persists a request snapshot.
- The snapshot is written into SQLite table
llm_request_snapshots. plugins/hermes-web/dashboard/plugin_api.pyreads request snapshots and usage totals directly fromstate.db.- The dashboard UI renders:
- usage totals and cache metrics
- by-model/provider and by-day usage breakdowns
- profile-aware skill analytics across
defaultandprofiles/* - prompt envelope (
system,instructions, etc.) - messages
- raw request JSON
- tool schemas
-
plugins/hermes-web/dashboard/manifest.json
- registers the
Hermes Webtab
- registers the
-
plugins/hermes-web/dashboard/plugin_api.py
- direct SQLite reads from
state.db GET /api/plugins/hermes-web/usage?days=7GET /api/plugins/hermes-web/profilesGET /api/plugins/hermes-web/skills?days=7GET /api/plugins/hermes-web/sessionsGET /api/plugins/hermes-web/sessions/{session_id}/requestsGET /api/plugins/hermes-web/requests/{snapshot_id}
- direct SQLite reads from
-
plugins/hermes-web/dashboard/dist/index.js
- plain IIFE dashboard UI
- internal
Usage,Skills, andRequeststabs Usagetab with1d / 7d / 30drange selectorSkillstab with1d / 7d / 30drange selector and profile filterRequeststab with session pagination and request drill-down
Each snapshot row records:
- session id / task id
- turn index / api call index
- provider / base URL / api mode / model
- whether this is the first turn
- approximate token buckets:
- total
- API messages
- restored history
- system
- prefill
- tools
- injected context
- exact serialized request payload
- summarized flags like:
- has system prompt
- has prefill
- has memory context
- has plugin context
The session list paginates at the plugin API layer:
- API accepts
limitandoffset - backend fetches
limit + 1rows to computehas_more - frontend currently shows 20 sessions per page
Requests within a session are currently loaded up to 200 rows without paging.
GET /api/plugins/hermes-web/usage?days=7 returns:
totalssessions_startedsessions_with_usageinput_tokensoutput_tokenscache_read_tokenscache_write_tokensreasoning_tokensapi_callsprompt_side_totalcache_hit_rate_pctcache_hit_rate_incl_write_pctcache_read_vs_input_ratio
by_model- grouped by
model + billing_provider
- grouped by
by_day- grouped by local calendar day
GET /api/plugins/hermes-web/skills?days=7 returns:
profile- current profile filter, for example
all,default,writer
- current profile filter, for example
profiles- discovered profile list from
~/.hermes/state.dband~/.hermes/profiles/*/state.db
- discovered profile list from
summarytotal_skill_loadstotal_skill_editstotal_skill_actionsdistinct_skills_used
by_day- grouped by local calendar day
- each day includes nested
skillsrows withview_count,manage_count, andtotal_count
top_skills- grouped by skill name
- includes
view_count,manage_count,total_count,percentage,last_used_at - each skill also carries per-profile breakdowns when multiple profile DBs are included
- This plugin intentionally uses SQLite, not extra JSON files, because request
inspection and usage aggregation both need direct indexed reads from
state.db. - The dashboard tab includes local UI i18n in
dist/index.js, usingSDK.useI18n()locale detection withen/zh/zh-hantsupport and English fallback. - The plugin backend does not depend on
SessionDBread helpers. It queries SQLite directly so the dashboard keeps working across core helper drift. - The plugin is read-only. It does not mutate sessions or request data.
- Historical sessions created before this feature landed will not have request snapshots. Only new requests are captured.
Use these after changes:
python3 -m py_compile \
plugins/hermes-web/dashboard/plugin_api.py
node --check plugins/hermes-web/dashboard/dist/index.js
# FastAPI TestClient smoke test against /api/plugins/hermes-web/usage

