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:

  1. Historical data before plugin installation can also be counted;
  2. 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:

  1. Persisted assistant/message.usage is prioritized;
  2. For failed steps that did not generate a message, fall back to the last streaming usage chunk (persisted at turn/end);
  3. 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:

  1. Clone the GitHub repository locally;
  2. Edit ~/.dsh/profiles/web/cordis.patch.yml and 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’s scanZstdFrames)
  • src/store.js — bucket aggregation, deduplication, persistence, summarize
  • src/backfill.js — incremental traversal of session logs + listSessionFiles
  • src/render.jsfmtTokens, renderUsageReport, parseUsageArgs
  • src/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.