Introduction¶
When using DSH for daily tasks, it is not intuitive where tokens are spent. Although session logs carry the usage reported by the provider for each model call, the data is scattered across all persistent sessions—including subagent sessions. To know “how much of a specific model was used in the last 7 days,” one can only manually go through logs or write a temporary script to aggregate. Historical data before plugin installation is even harder to cover.
dsh-plugin-token-usage turns this into a plugin: it aggregates by (date, provider, model) buckets, generates a report with a single /usage command, and includes a corresponding panel in the Web GUI. Below is an introduction to its positioning, design, and usage.
What is it¶
dsh-plugin-token-usage is maintained by lovedheart and is positioned as “DSH cross-session token usage statistics in the style of QwenPaw”: it aggregates the usage reported by the provider for each model call across all persistent sessions (including subagent sessions) into (date, provider, model) buckets, displaying them via the /usage command and the Token Usage panel in the Web GUI. Current version 0.2.0, license MIT.
Core Design¶
Session Logs as the Source of Truth¶
The plugin directly reads session logs under ~/.dsh/sessions as the persistent source of truth. This means two things:
- Historical data before plugin installation can also be counted;
- No additional accounting is needed on the write side; simply using DSH normally is sufficient, and aggregation is completed by the plugin through incremental scanning.
Preventing Duplicate Counts and Idempotency¶
Handling rules for the statistical metrics are as follows:
- Persisted
assistant/message.usageis prioritized; - For failed steps that did not generate a message, fall back to the last streaming usage chunk (persisted at
turn/end); - Each session file maintains a persistent watermark (
{hiSeq, framesIngested}), ensuring that incremental scanning remains idempotent across restarts, crash recovery, and re-encoding scenarios, preventing double accumulation.
Zero Runtime Dependencies¶
Runtime only uses Cordis’s ctx API and Node 22’s built-in node:zlib (zstd). @deepseek-ai/cordis ^4.0.1 is declared as an optional peer dependency.
Installation and Activation¶
The README does not provide an official installation command. The plugin is an out-of-tree module mounted via profile patch, following the same pattern as the telegram and thinking-mode plugins. The steps are as follows:
- Clone the GitHub repository locally;
- Edit
~/.dsh/profiles/web/cordis.patch.ymland add an insert block:
- insert:
- id: token-usage
name: '/path/to/dsh-plugin-token-usage/lib/index.js'
config:
defaultDays: 30
backfillIntervalSec: 30
enableCommand: true
verbose: true
name points to the absolute path of lib/index.js in the repository, and the four items in config come from the README examples and can be adjusted as needed.
Another detail: commands is an optional dependency (consumed via optional child fiber), so the plugin can be loaded in an assembly without command registration—it just won’t register interactive commands, but storage works as normal.
Usage: /usage Command¶
The query entry point is the single command /usage, supporting time ranges and model filtering:
/usage # Last 30 days (defaultDays is configurable)
/usage 7d # Last 7 days
/usage 7d qwen3.8 # Last 7 days, model filter (provider/model substring match)
/usage qwen3.6 # Default time range, model filter
When no time range is specified, defaultDays is used; the filter parameters perform substring matching on the provider/model strings.
The sample output provided in the README displays totals, models, and days in three sections:
📊 Token Usage 2026-07-17 → 2026-08-16
Total: 906.9M tokens · 4954 calls
input 473.3M · output 3.4M · cache read 430.1M
By model:
sglang/Qwen3.8-27B — 719.4M tokens · 3320 calls
in 337.7M · out 2.8M · cacheR 378.9M
sglang/Qwen3.6-27B — 187.4M tokens · 1634 calls
in 135.6M · out 669900 · cacheR 51.2M
By day:
2026-08-13 42.6M tokens · 481 calls
2026-08-14 195.7M tokens · 1587 calls
2026-08-15 380.5M tokens · 1513 calls
2026-08-16 288.1M tokens · 1373 calls
Numbers are displayed with abbreviations: M for millions (e.g., 1.2M), B for billions (e.g., 1.5B), and normal integers below; one decimal place is uniformly retained, and trailing .0 is removed.
Configuration¶
| Key | Default Value | Description |
|---|---|---|
defaultDays |
30 |
Lookback window for bare /usage |
backfillIntervalSec |
30 |
Incremental backfill interval (seconds) to keep state file updated |
sessionsRoot |
~/.dsh/sessions |
Session logs root directory; auto-derived from DSH_HOME if empty |
stateFile |
~/.dsh/token-usage.json |
Disk file for aggregated state and watermark |
flushDelayMs |
5000 |
Debounce delay for state writes |
enableCommand |
true |
Whether to register /usage |
verbose |
false |
Whether to output backfill progress logs |
Web GUI Panel¶
package.json provides the ./client export, dsh.client declares platform as web, and injects @deepseek-ai/dsh-client-runtime and @deepseek-ai/dsh-client-locale, corresponding to the Token Usage panel in the Web GUI.
Development and Testing¶
Code structure:
src/frames.js— zstd frame scanner (corresponds to DSH’sscanZstdFrames)src/store.js— bucket aggregation, deduplication, persistence,summarizesrc/backfill.js— incremental traversal of session logs +listSessionFilessrc/render.js—fmtTokens,renderUsageReport,parseUsageArgssrc/index.js— plugin entry point (name/inject/Config/apply)test/— unit and harness tests
Built-in development commands in the repository:
npm install # Install cordis peer for harness tests
npm test # node --test test/*.test.mjs
npm run prepare # Sync from src/ to lib/
npm run prepare copies src/*.js to lib/. Since the mount path points to lib/index.js, you need to sync once after modifying the source code.
Suitable Scenarios and Precautions¶
Suitable scenarios:
- DSH has many sessions and runs subagents frequently, and you want to see usage distribution by day or by model;
- Or you want to include historical data before plugin installation in the statistical metrics.
Precautions before use:
1. The plugin runs with the current dsh process permissions and can read/write the paths pointed to by sessionsRoot and stateFile (default ~/.dsh/sessions and ~/.dsh/token-usage.json), confirm directory permissions before enabling;
2. It is recommended to check the source code and license yourself before installation (currently MIT);
3. The statistical object is the usage reported by the provider, originating from the session logs themselves, so no changes to any write-path configuration are needed.
Conclusion¶
The approach of dsh-plugin-token-usage is very restrained: it doesn’t introduce new dependencies, doesn’t modify write paths, treats session logs as the sole source of truth, handles deduplication and idempotency well, and then delivers results via a single /usage command. If you have multi-session token usage statistics needs on DSH, it is worth a look.
- GitHub: https://github.com/lovedheart/dsh-plugin-token-usage
- Community Directory: https://www.skillhub.cn/plugins/lovedheart/dsh-plugin-token-usage
The community directory is an independent site and has no official affiliation with DeepSeek or Hanhui.