feat(cli): add /tokens slash command for system prompt token breakdown - #48470
feat(cli): add /tokens slash command for system prompt token breakdown#48470RemyFevry wants to merge 1 commit into
Conversation
Adds build_system_prompt_breakdown() in agent/system_prompt.py that returns labeled (label, text) pairs for each component of the system prompt. Mirrors the assembly logic of build_system_prompt_parts() but keeps segments individually labeled instead of merging into coarse tiers. Adds /tokens command in cli.py that displays a formatted table showing token counts per component (identity, skills, memory, user profile, tool schemas, environment hints, platform hints, etc.), sorted by size. Uses tiktoken (cl100k_base) for accurate counting when available, falls back to chars/4 estimate. No hard dependency added. Works in CLI, TUI, and gateway/messaging platforms (plain text output).
a355fa4 to
a23b4b7
Compare
teknium1
left a comment
There was a problem hiding this comment.
Thanks for the useful prompt-budget visibility proposal. Current main now has a shared context-breakdown engine, but this version needs rework before it can provide reliable component accounting.
Problems
agent/system_prompt.py:461adds a second prompt assembler. Current assembly has since gained blocks and resolution paths, includingPARALLEL_TOOL_CALL_GUIDANCEatagent/system_prompt.py:216and platform-hint resolution atagent/system_prompt.py:432; the copied helper will therefore report totals that can differ from the actual provider prompt.cli.py:8419returns whenself.agentis absent. The TUI slash worker has no live CLI agent (cli.py:9629-9637), so the claimed TUI support cannot produce a breakdown.- The diff adds no tests for the new accounting or either rendering path.
Suggested changes
- Extend the shared
agent/context_breakdown.pypath, or derive labelled output directly from the real prompt builder, so every reported component comes from the same assembly source. - Route TUI through its live gateway-session breakdown path, and add tests for conditional prompt blocks plus CLI, gateway, and TUI dispatch.
This is an automated hermes-sweeper review.
| return json.dumps(formatted_tools, ensure_ascii=False) | ||
|
|
||
|
|
||
| def build_system_prompt_breakdown(agent: Any, system_message: Optional[str] = None) -> list[tuple[str, str]]: |
There was a problem hiding this comment.
This duplicates the prompt assembler, so it will drift as soon as a new prompt block or resolution path lands. Current main already has additions such as parallel-tool-call guidance and configured platform-hint resolution that this copied path would not count. Please derive labelled segments from the same source used to build the emitted prompt.
| (identity, skills, memory, tools, etc.) so users can see exactly | ||
| where their context budget goes. Works in CLI, TUI, and gateway. | ||
| """ | ||
| if not self.agent: |
There was a problem hiding this comment.
This prevents the stated TUI support: the TUI slash worker invokes CLI command handling without a live self.agent (documented by the existing /usage implementation), so /tokens will only print the no-active-agent message. Use the TUI gateway session's live-agent path or scope this command away from TUI.
Extends the cherry-picked /context command (PR #52184) and prompt-size attribution helpers (PR #66656) into one visual context view across surfaces, and absorbs the per-component budget-visibility goal of the /tokens proposal (PR #48470): - agent/context_breakdown.py: pure renderers over the existing payload — a 5x20 glyph block grid (1 cell ~= 1% of the model window), an 'Estimated usage by category' table with free space, and expanded per-skill / per-toolset listings via compute_context_details(), which reuses the prompt-size attribution mechanism (skills index-line bytes + registry tool->toolset map) converted to the same chars/4 heuristic. - cli.py: /context [all] renders grid + category table (+ expanded listings) from the live agent and in-memory conversation history. - gateway/slash_commands.py: /context appends the plain-text category table (no grid — monospace not guaranteed on messaging platforms); /context all adds the expanded listings. Fail-open: breakdown errors never break the gauge. - hermes_cli/commands.py: /context gains the 'all' subcommand; /version demoted to /hermes version on Slack to keep the 50-slash cap. - tests: renderer unit tests against synthetic payloads, registry test, gateway /context + /context all + failure-degradation handler tests. - docs: slash-commands reference + CLI guide entries. Read-only and locally computed: no provider calls, no prompt-cache impact. Co-authored-by: RemyFevry <29257684+RemyFevry@users.noreply.github.com> Co-authored-by: joelbrilliant <joelbrilliant1@gmail.com> Co-authored-by: CharlesMcquade <6466275+CharlesMcquade@users.noreply.github.com>
Extends the cherry-picked /context command (PR #52184) and prompt-size attribution helpers (PR #66656) into one visual context view across surfaces, and absorbs the per-component budget-visibility goal of the /tokens proposal (PR #48470): - agent/context_breakdown.py: pure renderers over the existing payload — a 5x20 glyph block grid (1 cell ~= 1% of the model window), an 'Estimated usage by category' table with free space, and expanded per-skill / per-toolset listings via compute_context_details(), which reuses the prompt-size attribution mechanism (skills index-line bytes + registry tool->toolset map) converted to the same chars/4 heuristic. - cli.py: /context [all] renders grid + category table (+ expanded listings) from the live agent and in-memory conversation history. - gateway/slash_commands.py: /context appends the plain-text category table (no grid — monospace not guaranteed on messaging platforms); /context all adds the expanded listings. Fail-open: breakdown errors never break the gauge. - hermes_cli/commands.py: /context gains the 'all' subcommand; /version demoted to /hermes version on Slack to keep the 50-slash cap. - tests: renderer unit tests against synthetic payloads, registry test, gateway /context + /context all + failure-degradation handler tests. - docs: slash-commands reference + CLI guide entries. Read-only and locally computed: no provider calls, no prompt-cache impact. Co-authored-by: RemyFevry <29257684+RemyFevry@users.noreply.github.com> Co-authored-by: joelbrilliant <joelbrilliant1@gmail.com> Co-authored-by: CharlesMcquade <6466275+CharlesMcquade@users.noreply.github.com>
Extends the cherry-picked /context command (PR #52184) and prompt-size attribution helpers (PR #66656) into one visual context view across surfaces, and absorbs the per-component budget-visibility goal of the /tokens proposal (PR #48470): - agent/context_breakdown.py: pure renderers over the existing payload — a 5x20 glyph block grid (1 cell ~= 1% of the model window), an 'Estimated usage by category' table with free space, and expanded per-skill / per-toolset listings via compute_context_details(), which reuses the prompt-size attribution mechanism (skills index-line bytes + registry tool->toolset map) converted to the same chars/4 heuristic. - cli.py: /context [all] renders grid + category table (+ expanded listings) from the live agent and in-memory conversation history. - gateway/slash_commands.py: /context appends the plain-text category table (no grid — monospace not guaranteed on messaging platforms); /context all adds the expanded listings. Fail-open: breakdown errors never break the gauge. - hermes_cli/commands.py: /context gains the 'all' subcommand; /version demoted to /hermes version on Slack to keep the 50-slash cap. - tests: renderer unit tests against synthetic payloads, registry test, gateway /context + /context all + failure-degradation handler tests. - docs: slash-commands reference + CLI guide entries. Read-only and locally computed: no provider calls, no prompt-cache impact. Co-authored-by: RemyFevry <29257684+RemyFevry@users.noreply.github.com> Co-authored-by: joelbrilliant <joelbrilliant1@gmail.com> Co-authored-by: CharlesMcquade <6466275+CharlesMcquade@users.noreply.github.com>
|
The /tokens system-prompt breakdown idea landed via #72242 (now merged), folded into the unified /context command with credit. Thanks! |
Extends the cherry-picked /context command (PR NousResearch#52184) and prompt-size attribution helpers (PR NousResearch#66656) into one visual context view across surfaces, and absorbs the per-component budget-visibility goal of the /tokens proposal (PR NousResearch#48470): - agent/context_breakdown.py: pure renderers over the existing payload — a 5x20 glyph block grid (1 cell ~= 1% of the model window), an 'Estimated usage by category' table with free space, and expanded per-skill / per-toolset listings via compute_context_details(), which reuses the prompt-size attribution mechanism (skills index-line bytes + registry tool->toolset map) converted to the same chars/4 heuristic. - cli.py: /context [all] renders grid + category table (+ expanded listings) from the live agent and in-memory conversation history. - gateway/slash_commands.py: /context appends the plain-text category table (no grid — monospace not guaranteed on messaging platforms); /context all adds the expanded listings. Fail-open: breakdown errors never break the gauge. - hermes_cli/commands.py: /context gains the 'all' subcommand; /version demoted to /hermes version on Slack to keep the 50-slash cap. - tests: renderer unit tests against synthetic payloads, registry test, gateway /context + /context all + failure-degradation handler tests. - docs: slash-commands reference + CLI guide entries. Read-only and locally computed: no provider calls, no prompt-cache impact. Co-authored-by: RemyFevry <29257684+RemyFevry@users.noreply.github.com> Co-authored-by: joelbrilliant <joelbrilliant1@gmail.com> Co-authored-by: CharlesMcquade <6466275+CharlesMcquade@users.noreply.github.com>
feat: Add
/tokensslash command for system prompt token breakdownSummary
New
/tokenscommand that shows exactly how many tokens each component of the system prompt consumes — identity, skills index, memory, user profile, tool schemas, environment hints, platform hints, and more.This fills a visibility gap:
/usageshows aggregate session tokens, but not where the tokens go in the system prompt itself. Users optimizing context budgets (e.g., trimming skills, managing memory size) had no way to measure the cost of each component.What it does
Running
/tokensproduces a table like:Changes
agent/system_prompt.py(+242 lines)build_system_prompt_breakdown(agent, system_message)— returnslist[tuple[str, str]]of labeled components, mirroring the assembly logic ofbuild_system_prompt_parts()but keeping each segment individually labeledestimate_tokens(text)— usestiktoken(cl100k_base) when installed, falls back tochars // 4hermes_cli/commands.py(+1 line)CommandDef("tokens", ...)in the Info categorycli.py(+72 lines)_show_token_breakdown()method — builds the breakdown, counts tokens per component, formats and prints the tableprocess_command()aselif canonical == "tokens"Design decisions
tiktokenis optional. Falls back to character-based estimate when not installed.Testing
Verified with a mock agent containing 6 tools, memory enabled, skills enabled: