Summary
Add a new /context slash command that shows the current prompt composition (system prompt / tools schema / messages / total vs. model context window) without waiting for the next API call, and extend /usage to report per-model cumulative token and cost breakdown for multi-model sessions.
Both are standard affordances in peer agents (Claude Code, OpenClaw) and would make Hermes's token efficiency — which is already a design strength — directly visible to users and contributors.
Motivation
While working with a ModelBox capture of a real Hermes request, I measured (tiktoken cl100k_base):
| Component |
Tokens |
Share |
tools schema |
9,712 |
51.3% |
| system prompt |
9,182 |
48.5% |
| messages |
~40 |
0.2% |
| total |
~18,934 |
— |
Two things stand out:
- The
tools schema alone is larger than the system prompt. It is also frozen for the lifetime of the agent process — self.tools = get_tool_definitions(...) is built once in run_agent.py __init__ and reused, which makes it an excellent prefix-cache anchor. Users should be able to see this.
- Hermes already has the data, it just isn't surfaced.
ContextEngine.get_status() (agent/context_engine.py:151) returns last_prompt_tokens, context_length, usage_percent, compression_count. Per-turn model usage is wired through /usage (gateway/run.py:6463). What is missing is the preflight breakdown (what the next prompt will look like, by component) and the session-cumulative per-model rollup.
Current state
| Command |
Shows |
Gap |
/status |
Session id, timestamps, session totals, connected platforms |
No prompt composition |
/usage |
Last-turn in/out/cache tokens, rate limits, current-model cost, usage_percent |
No per-component breakdown; not aggregated by model |
/compress |
Before/after token counts for manual compression |
Point-in-time only |
/insights |
30-day historical aggregate across sessions |
Cross-session; not current prompt |
None of these answer the question "What does my next API call actually look like, and why?"
Proposed UX
/context
Static, preflight breakdown of the prompt that would be sent on the next turn:
```
📊 Context composition (model: anthropic:claude-sonnet-4-5)
System prompt 9,182 tok ████████░░░░░░░░ 48.5%
Tools schema 9,712 tok █████████░░░░░░░ 51.3% (frozen, 30 tools)
Messages 40 tok ░░░░░░░░░░░░░░░░ 0.2% (4 messages)
─────────────────────────
Total 18,934 tok / 200,000 9.5% of context window
Threshold 160,000 tok (compression at 80%)
Compressions 0
Prefix cache ✓ warm (system + tools eligible)
```
Key design points:
- Computed locally. Uses
self.tools already cached on the AIAgent instance + current system_prompt + current message window. No extra API call.
- Tool count + frozen indicator nudges users toward toolset selection as a lever for efficiency.
- Cache eligibility hint teaches users why Hermes's frozen tools matter.
Enhanced /usage
Existing output stays; add a per-model section for sessions that span multiple models (e.g., fallbacks, /model switches):
```
💰 Session usage — breakdown by model
anthropic:claude-sonnet-4-5
Input: 142,310 Cached: 118,400 (83%)
Output: 18,902
API calls: 24 Est. cost: $0.73
openai:gpt-4o-mini
Input: 12,040 Cached: 800 (7%)
Output: 2,110
API calls: 3 Est. cost: $0.01
─────────────────────────
Session total: $0.74 (37 API calls, 175,362 tokens)
```
Implementation notes
- Register both commands in
hermes_cli/commands.py COMMAND_REGISTRY (alongside existing /usage at line 152).
/context handler can live next to /usage at gateway/run.py:6463; it mostly formats data already available on self:
self.system_prompt → token count via the existing tokenizer helper
self.tools → token count on the cached schema (computed once, memoized)
- current
self.messages window → per-message token count
ContextEngine.get_status() for context_length / threshold_tokens / compression_count
/usage enhancement: add a per-model dict alongside the existing session counters (session_input_tokens, session_output_tokens, etc.), keyed by provider:model. The aggregation point is wherever update_usage(...) is called after each API response.
- No new dependencies;
tiktoken is already in the tree for estimation fallbacks.
Alternatives considered
- Do nothing / rely on
/usage. /usage reports what happened, not what is about to happen, and does not decompose by prompt component — the main insight (tools schema is ~50% of cost and is frozen) stays invisible.
- Expose via logs or a debug flag. Higher friction; not discoverable for Gateway users who do not run the CLI.
- Piggyback on
/status. /status is session-scoped metadata; mixing in prompt composition muddies its purpose.
Why this matters for Hermes specifically
Hermes has unusually strong prefix-cache behavior compared to peers — tools are frozen for the process lifetime, system prompt is cached, compression is deliberate and observable. Making these visible via /context turns an internal engineering choice into a user-facing signal, and gives contributors a direct feedback loop when evaluating toolset or prompt changes.
Happy to send a PR if the direction is agreeable.
Summary
Add a new
/contextslash command that shows the current prompt composition (system prompt / tools schema / messages / total vs. model context window) without waiting for the next API call, and extend/usageto report per-model cumulative token and cost breakdown for multi-model sessions.Both are standard affordances in peer agents (Claude Code, OpenClaw) and would make Hermes's token efficiency — which is already a design strength — directly visible to users and contributors.
Motivation
While working with a ModelBox capture of a real Hermes request, I measured (tiktoken
cl100k_base):toolsschemaTwo things stand out:
toolsschema alone is larger than the system prompt. It is also frozen for the lifetime of the agent process —self.tools = get_tool_definitions(...)is built once inrun_agent.py__init__and reused, which makes it an excellent prefix-cache anchor. Users should be able to see this.ContextEngine.get_status()(agent/context_engine.py:151) returnslast_prompt_tokens,context_length,usage_percent,compression_count. Per-turn model usage is wired through/usage(gateway/run.py:6463). What is missing is the preflight breakdown (what the next prompt will look like, by component) and the session-cumulative per-model rollup.Current state
/status/usageusage_percent/compress/insightsNone of these answer the question "What does my next API call actually look like, and why?"
Proposed UX
/contextStatic, preflight breakdown of the prompt that would be sent on the next turn:
```
📊 Context composition (model: anthropic:claude-sonnet-4-5)
System prompt 9,182 tok ████████░░░░░░░░ 48.5%
Tools schema 9,712 tok █████████░░░░░░░ 51.3% (frozen, 30 tools)
Messages 40 tok ░░░░░░░░░░░░░░░░ 0.2% (4 messages)
─────────────────────────
Total 18,934 tok / 200,000 9.5% of context window
Threshold 160,000 tok (compression at 80%)
Compressions 0
Prefix cache ✓ warm (system + tools eligible)
```
Key design points:
self.toolsalready cached on theAIAgentinstance + currentsystem_prompt+ current message window. No extra API call.Enhanced
/usageExisting output stays; add a per-model section for sessions that span multiple models (e.g., fallbacks,
/modelswitches):```
💰 Session usage — breakdown by model
anthropic:claude-sonnet-4-5
Input: 142,310 Cached: 118,400 (83%)
Output: 18,902
API calls: 24 Est. cost: $0.73
openai:gpt-4o-mini
Input: 12,040 Cached: 800 (7%)
Output: 2,110
API calls: 3 Est. cost: $0.01
─────────────────────────
Session total: $0.74 (37 API calls, 175,362 tokens)
```
Implementation notes
hermes_cli/commands.pyCOMMAND_REGISTRY(alongside existing/usageat line 152)./contexthandler can live next to/usageatgateway/run.py:6463; it mostly formats data already available onself:self.system_prompt→ token count via the existing tokenizer helperself.tools→ token count on the cached schema (computed once, memoized)self.messageswindow → per-message token countContextEngine.get_status()forcontext_length/threshold_tokens/compression_count/usageenhancement: add a per-model dict alongside the existing session counters (session_input_tokens,session_output_tokens, etc.), keyed byprovider:model. The aggregation point is whereverupdate_usage(...)is called after each API response.tiktokenis already in the tree for estimation fallbacks.Alternatives considered
/usage./usagereports what happened, not what is about to happen, and does not decompose by prompt component — the main insight (tools schema is ~50% of cost and is frozen) stays invisible./status./statusis session-scoped metadata; mixing in prompt composition muddies its purpose.Why this matters for Hermes specifically
Hermes has unusually strong prefix-cache behavior compared to peers — tools are frozen for the process lifetime, system prompt is cached, compression is deliberate and observable. Making these visible via
/contextturns an internal engineering choice into a user-facing signal, and gives contributors a direct feedback loop when evaluating toolset or prompt changes.Happy to send a PR if the direction is agreeable.