fix(gateway): read /status token totals from SessionDB (#17158)

/status was reading session_entry.total_tokens from the in-memory
SessionStore (gateway/session.py), which the agent never writes to —
so the token count was always 0.

The agent already persists token deltas to the SQLite SessionDB
(run_agent.py:11497) for every platform with a session_id. Route
/status through that single source of truth instead of duplicating
token writes into a second store.

Fix:
- gateway/run.py: _handle_status_command now calls
  self._session_db.get_session(session_id) and sums the five token
  component columns (input/output/cache_read/cache_write/reasoning).
  Falls back to 0 when no SessionDB is configured or no row exists.
- Two new regression tests covering the populated-row and
  missing-row paths.

Co-authored-by: Hermes <127238744+teknium1@users.noreply.github.com>
This commit is contained in:
Jezza Hehn
2026-04-30 20:26:54 -07:00
committed by Teknium
parent a178081468
commit 7abc9ce4df
2 changed files with 81 additions and 1 deletions

View File

@@ -6568,11 +6568,30 @@ class GatewayRunner:
queue_depth = self._queue_depth(session_key, adapter=adapter)
title = None
# Pull token totals from the SQLite session DB rather than the
# in-memory SessionStore. The agent's per-turn token deltas are
# persisted into sessions_db (run_agent.py), not into SessionEntry,
# so session_entry.total_tokens is always 0. SessionDB is the
# single source of truth; reading it here keeps /status accurate
# without duplicating token writes into two stores.
db_total_tokens = 0
if self._session_db:
try:
title = self._session_db.get_session_title(session_entry.session_id)
except Exception:
title = None
try:
row = self._session_db.get_session(session_entry.session_id)
if row:
db_total_tokens = (
(row.get("input_tokens") or 0)
+ (row.get("output_tokens") or 0)
+ (row.get("cache_read_tokens") or 0)
+ (row.get("cache_write_tokens") or 0)
+ (row.get("reasoning_tokens") or 0)
)
except Exception:
db_total_tokens = 0
lines = [
"📊 **Hermes Gateway Status**",
@@ -6584,7 +6603,7 @@ class GatewayRunner:
lines.extend([
f"**Created:** {session_entry.created_at.strftime('%Y-%m-%d %H:%M')}",
f"**Last Activity:** {session_entry.updated_at.strftime('%Y-%m-%d %H:%M')}",
f"**Tokens:** {session_entry.total_tokens:,}",
f"**Tokens:** {db_total_tokens:,}",
f"**Agent Running:** {'Yes ⚡' if is_running else 'No'}",
])
if queue_depth: