Skip to main content

stop-ledger

❖ Communityv1.0.0★ 0

Local ledger of the turns you stopped while Hermes was still working (/stop, or /new and /reset during a running turn, on messaging platforms, the TUI and the desktop app): /stop-log shows how many running turns were stopped, how many by /stop and by /new, in how many sessions and how long ago the last one was, per platform or per day, for the last 24 hours, any number of hours or days, the latest session or everything recorded; /stop-log recent lists the newest stops (ten, or up to 100 with /stop-log recent 50).

Open in Hermes Desktop
hermes plugins install stop-ledger

What it adds

Hooks 1

agent_loop_stopped

README

From the reviewed commit 604940a ↗; it updates when the author re-pins.

stop-ledger

A local ledger of the turns you stopped while Hermes was still working, and a /stop-log command that shows how often that happens, on which platform, in how many sessions and how recently.

Stopping a turn halfway usually means something went wrong: the agent went off in the wrong direction, took too long, or was about to do something you did not want. stop-ledger subscribes to agent_loop_stopped, which Hermes fires when a running turn is interrupted, and keeps one row per stop. You can see afterwards that you stopped Hermes six times on Telegram today, that most of those were /new rather than /stop, or that the desktop app gets stopped far more than your phone.

Install

hermes plugins install stop-ledger --enable

Requires Hermes 0.21.5 or newer. No API key, no configuration, no dependencies.

Use

/stop-log             last 24 hours, by platform
/stop-log session     the most recent session you stopped
/stop-log all         everything in the ledger
/stop-log 7d          the last 7 days (any number of hours or days: 6h, 30d)
/stop-log days        add to any of the above to group by day, newest first
/stop-log recent      add to any of the above to list the newest 10 stops instead
/stop-log recent 25   the newest 25 instead (1 to 100)
/stop-log clear       delete the ledger

Example (/stop-log all, from the end-to-end test: on Telegram a running turn stopped with /stop and another cleared with /new, and one turn stopped from the TUI):

Stopped turns, all recorded:

platform  stops  by /stop  by /new  sessions    last
telegram      2         1        1         1  3s ago
tui           1         1        0         1  3s ago
total         3         2        1         2  3s ago

Only turns that were still running count: a /stop or /new between turns is not a stop.
  • platform is where the turn ran: a messaging platform (telegram, discord, ...) or tui for the TUI and the desktop app.
  • stops counts stopped turns. by /stop is a /stop (or the Stop button in the TUI or the desktop app); by /new is a /new or /reset that cleared a turn still running.
  • sessions is how many different sessions those stops were in, and last how long ago the newest one was. The platform with the most stops comes first.

/stop-log recent lists the newest ten stops of the chosen window, newest first (/stop-log recent 25 lists 25, up to 100). From the same run:

Stopped turns, all recorded, newest 3 of 3:

when    platform  cause             detail       session
3s ago       tui   stop  session_interrupt  504e634656fb
3s ago  telegram    new        new_command  5b8bb83e3f6b
3s ago  telegram   stop       stop_command  5b8bb83e3f6b

detail is Hermes's own label for the stop (stop_command, new_command, session_interrupt, ...), and session a short hash that tells sessions apart without naming them.

/stop-log days puts one day on each line, newest day first; days are your computer's local calendar days. A time window counts back from now (/stop-log 6h, /stop-log 7d days). The ledger keeps its newest 5,000 rows, so a long window on a busy install reaches back only as far as those rows do.

What it does not see

  • The classic CLI: Hermes has no interrupt hook there (Ctrl+C in the CLI is not recorded).
  • A /stop when no turn is running yet, and a /new between turns: nothing was interrupted.
  • In the TUI and the desktop app, Hermes reports every interrupt of a running turn the same way, including one it makes itself (for example when a disconnected client's session is cleaned up), so those are counted as stops too.

What is recorded

One JSON line per stopped turn in <HERMES_HOME>/plugin-data/stop-ledger/stops.jsonl (per profile):

ts, session, platform, cause, detail.

session is the first 12 hex digits of a SHA-256 of the session key, not the key itself: a gateway session key names the chat and the user. Nothing said in the chat reaches the hook.

The file is bounded: once it passes 2 MB it is rewritten to its newest 5,000 rows.

Security and footprint

  • register() only registers one hook (agent_loop_stopped) and one command (/stop-log).
  • Observer only: it cannot delay or undo a stop. Each hook call appends one line to the ledger, and nothing else.
  • No network access, no subprocesses, no downloads, no credentials read.
  • Writes only stops.jsonl under its own plugin data directory. /stop-log clear deletes it.
  • The hook never raises: if the ledger cannot be written, the failure is logged at debug level and the stop goes ahead.
  • Standard library only.

Development

python -m pytest tests                                            # unit tests, no Hermes needed
PYTHONPATH=<hermes checkout> python tests/e2e/stop_ledger_e2e.py   # Hermes's own interrupt code
hermes plugins validate stop-ledger

Changes

  • 1.0.0: first release.

MIT licensed.

approval-ledger❖ Community★ 0

Local ledger of Hermes's approval prompts (dangerous commands, protected writes, MCP consent, smart-mode verdicts): /approval-log shows how often each rule asked, how many prompts were approved, denied or left unanswered, and how long a person took to answer, per rule, per surface or per day, for the last 24 hours, any number of hours or days, the latest session or everything recorded; /approval-log recent lists the newest decisions (ten, or up to 100 with /approval-log recent 50). Disclosure — writes decision metadata (session id, surface, rule label, answer, timings; no command, description or session key) to plugin-data/approval-ledger/approvals.jsonl, trimmed to 5,000 rows past 2 MB; observer only, cannot answer or change an approval; no network

Tools
aux-ledger❖ Community★ 0

Local ledger of Hermes's auxiliary LLM calls (titling, compression, vision, approval): /aux shows tokens, time and failures per task, model, provider or day, or lists the newest calls (ten, or up to 100 with /aux recent 50), for the last 24 hours, any number of hours or days, the latest session or everything recorded. Disclosure — writes auxiliary-call metadata (ids, models, timings, token counts, no prompt or response text) to plugin-data/aux-ledger/calls.jsonl, trimmed to 5,000 rows past 2 MB; no network

Tools
command-ledger❖ Community★ 0

Local ledger of the slash commands you run in Hermes (built-in commands in the CLI, built-in and plugin commands on messaging platforms): /command-log shows how often each command was used, its share, in how many sessions and when last, per command, platform, surface or day, for the last 24 hours, any number of hours or days, the latest session or everything recorded; /command-log recent lists the newest commands (ten, or up to 100 with /command-log recent 50) with the alias typed. Disclosure — writes command metadata (command name, alias typed, surface, platform, a 12-digit hash of the session key; no arguments, session key or user id) to plugin-data/command-ledger/commands.jsonl, trimmed to 5,000 rows past 2 MB; observer only, cannot block or change a command; no network

Tools
error-ledger❖ Community★ 0

Local ledger of failed provider calls (rate limits, overloads, timeouts, context overflows): /errors shows how many attempts failed per model, provider or cause, how many Hermes could retry, and the most common HTTP status, for the last 24 hours, any number of hours or days, the latest session or everything recorded; /errors days puts one day on each line, newest first; /errors recent lists the newest failures (ten, or up to 100 with /errors recent 50) and how long ago each happened. Disclosure — writes failed-attempt metadata (ids, provider, model, HTTP status, Hermes's failure class, exception class name, timings; no error message, request or prompt text) to plugin-data/error-ledger/errors.jsonl, trimmed to 5,000 rows past 2 MB; no network

Tools
stream-speed❖ Community★ 0

How fast each model starts answering and how fast it writes: /speed shows the median and p90 time to first text and the median characters per second per model, provider or day, or lists the newest streams (ten, or up to 100 with /speed recent 50), for the last 24 hours, any number of hours or days, the latest session or everything recorded, from the streaming hooks. Disclosure — writes per-response stream timings (ids, model, timings, character count, no text) to plugin-data/stream-speed/streams.jsonl, trimmed to 5,000 rows past 2 MB; atexit waits up to 1 s; no network

Tools
voice-ledger❖ Community★ 0

Local ledger of the voice messages and recordings Hermes transcribes (voice messages from messaging platforms, CLI voice mode): /voice-log shows how many recordings there were, how much audio in total and typically, and how long ago the last one was, per speech-to-text provider, model, source, language or day, for the last 24 hours, any number of hours or days or everything recorded; /voice-log recent lists the newest recordings (ten, or up to 100 with /voice-log recent 50). Disclosure — writes recording metadata (source, provider, model, language, file size read from the file system; no audio, file path, prompt or transcript) to plugin-data/voice-ledger/voice.jsonl, trimmed to 5,000 rows past 2 MB; observer only, always returns None so the transcription request is unchanged; no network

Tools

← Back to the catalog · catalog built Oct 17, 2026