liyiersan/dsh-usage-monitor

dsh-usage-monitor

DSH plugin: show DeepSeek API pricing, token usage/cost and account balance inside DeepSeek Harness

Uncategorizedbalancedeepseekdeepseek-harness

dsh-usage-monitor

English | 简体中文

A DeepSeek Harness (DSH) plugin that shows DeepSeek API official pricing, session token usage/cost, cumulative cost, and account balance directly inside DSH.

DSH usage panel

Screenshots are rendered from the real DSH web page (Playwright driving a local Chrome); only the plugin endpoints are stubbed with demo data, so the UI structure, plugin DOM and styles are genuine while the balance, usage figures and session name are demo values.

Features

  • Account balance: queries GET https://api.deepseek.com/user/balance and shows total, topped-up, and granted balance. Cached for 60 seconds by default with manual refresh.
  • Current session cost: shows the already-priced amount from the host ledger — each increment is priced with the model and peak/off-peak tier in effect at that moment, so switching models never makes the number jump; when the ledger has no record yet it falls back to a local estimate and marks it as such in the UI.
  • Per-model breakdown: the ledger buckets tokens and cost per model, and the panel lists how much Flash and V4-Pro each used and cost.
  • Cumulative cost: a local ledger records usage across sessions, using incremental pricing so peak/off-peak changes are accounted for accurately; reporting rides the always-rendered dock strip, so the ledger keeps updating even while the panel stays closed.
  • Official pricing: built-in deepseek-flash and deepseek-v4-pro prices with automatic peak/off-peak tier selection.
  • Two UI entry points:
    • a full Usage tab in the conversation view;
    • an always-visible dock above the input box showing balance, current session cost, active model price, and price tier.
  • Privacy-friendly: no public listener, no stored API key. See Security & Privacy below.

Screenshots

Full usage panel

Usage panel

Input-box dock

Usage dock

Installation

Prerequisites

  • DSH installed, for example @deepseek-ai/dsh;
  • the web profile;
  • a usable DeepSeek API key, already configured in ~/.dsh/.credentials.yaml or supplied via the DEEPSEEK_API_KEY environment variable.

1. Install the plugin

dsh plugin --profile web add github:liyiersan/dsh-usage-monitor

You can also install from a local checkout:

dsh plugin --profile web add /path/to/dsh-usage-monitor

This repository declares dsh.bundle.patch. On DSH versions that support the manifest, the install command applies cordis.patch.yml automatically and inserts the plugin into the profile composition, so you normally do not need to edit the profile patch by hand.

2. Manual install / fallback

If your DSH version does not apply the bundle patch automatically, edit $DSH_HOME/profiles/web/cordis.patch.yml (default: ~/.dsh/profiles/web/cordis.patch.yml) and add:

- insert:
    - id: usage-monitor
      name: '@local/dsh-usage-monitor'

3. Make sure the API key is available

The plugin never stores the key itself. It resolves DEEPSEEK_API_KEY through the DSH credentials service, falling back to the process environment.

4. Restart DSH

dsh web

Open any conversation. You should see the Usage tab in the conversation view and the usage dock above the input box.

Uninstall

dsh plugin --profile web remove @local/dsh-usage-monitor

If you added the insert entry manually, remove it from cordis.patch.yml; a bundle install is normally cleaned up by dsh plugin remove. Optionally delete the local ledger:

rm -rf "$DSH_HOME/usage-monitor"

Pricing model

Unit: CNY / million tokens. Peak hours are Beijing time Monday-Friday 09:00-12:00 and 14:00-18:00; off-peak prices are half of peak prices.

ModelTierCache hitCache missOutput
DeepSeek-V4.1-FlashOff-peak0.0214
DeepSeek-V4.1-FlashPeak0.0428
DeepSeek-V4-ProOff-peak0.154.513.5
DeepSeek-V4-ProPeak0.3927

Billing rules:

  • cacheRead (cache-hit input) uses the cache-hit price;
  • uncachedInput (cache-miss input) uses the cache-miss price;
  • output uses the output price;
  • cacheWrite is not listed separately by the official docs, so this project conservatively charges it at the cache-miss price;
  • model names containing pro, chat, or reasoner are normalized to V4-Pro; names containing flash are normalized to Flash; unknown models fall back to Flash and are marked as an estimate in the UI.

Token counts come from the provider's exact usage; costs are derived by the local ledger with incremental pricing, matching the official billing model with only tiny rounding differences (tier attribution uses the moment of each report). DeepSeek prices may change; when updating, keep lib/pricing.js and the inline pricing copy in lib/client.js in sync.

How it works

DSH Host (Node)
  lib/index.js ── GET /user/balance ──> api.deepseek.com
       │
       ├─ GET  /usage-monitor/data   ──> browser client
       └─ POST /usage-monitor/report <── browser client
                                      │
                                      ├─ conversation.view "Usage" tab
                                      └─ conversation.input.dock bar
  • lib/index.js: host half. Resolves credentials, queries balance, maintains the local ledger, and exposes local HTTP endpoints.
  • lib/client.js: browser bundle. Registers the conversation.view and conversation.input.dock slots and reads/reports data.
  • lib/pricing.js: pure pricing engine used by the host and tests.
  • The client carries an inline copy of the pricing table because browser modules cannot import server modules directly. Update both copies when prices change.

Project layout

dsh-usage-monitor/
├── lib/
│   ├── client.js      # browser bundle
│   ├── index.js       # host plugin
│   └── pricing.js     # pricing engine
├── scripts/
│   ├── client-check.mjs
│   ├── inspect-session.mjs
│   └── smoke.mjs
├── test/
│   └── pricing.test.mjs
├── docs/screenshots/
├── package.json
├── README.md
├── README.en.md
└── LICENSE

Development & tests

npm test                 # pricing engine unit tests
npm run test:client      # offline client bundle checks
node scripts/smoke.mjs   # host smoke test (queries the real balance API)

scripts/smoke.mjs uses a temporary DSH_HOME, so it does not pollute your real ledger. It reads the key from the local DSH credentials file or the environment, but only prints the key length, never the key itself.

Restart DSH after changing the client half: /plugins/<id>/client.js is served from DSH's client module table, which is built and cached at startup — a browser refresh alone returns the copy from the last start. After editing lib/client.js, restart DSH before verifying, or you will misread a cached build as "the change did not work".

Compatibility

This version was verified against DSH 0.1.5-rc.1 with the web profile (September 2026) and also works on 0.1.1-rc.2 (client slots and model-resolution APIs are unchanged). DSH client APIs may still evolve; if slots or model-resolution APIs change after a DSH upgrade, please open an issue or a PR.

Security & Privacy

  • No telemetry is collected or uploaded.
  • The plugin does not store the API key; the key is provided only by the DSH credentials service or the process environment.
  • Balance queries run on the host side and only target https://api.deepseek.com/user/balance.
  • The local ledger lives at $DSH_HOME/usage-monitor/ledger.json and records only session IDs, token usage, and per-model cost buckets; it is not committed to this repository.
  • The /usage-monitor/* endpoints are served by the DSH web server on loopback. /usage-monitor/report requires Content-Type: application/json to reduce CSRF risk.
  • If you fork this project, do not commit your local ledger, credentials file, or logs containing personal paths.

Contributing

Issues and PRs are welcome. Before opening a PR, please run:

npm test
npm run test:client

License

MIT