Skip to content

Add /context slash command and enrich /usage to surface prompt composition and token efficiency #10617

Description

@cclank

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:

  1. 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.
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havearea/usage-costToken accounting, usage reporting, billing, cost trackingcomp/cliCLI entry point, hermes_cli/, setup wizardcomp/gatewayGateway runner, session dispatch, deliverytype/featureNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions