Install
Inside DeepSeek Harness, with dsh-market
dsh plugin --profile web add dshmarket
Or from the command line
dsh plugin --profile web add dsh-usage-chart
Installing runs third-party code with your own permissions — it can read your files, use your credentials and reach the network. Review the source first, and pin a commit (github:owner/repo#sha) when you can.
Screenshots
README
A usage, cost, and account-balance dashboard for DeepSeek Harness Web.
中文 · Report an issue · Changelog (EN) · 更新日志(中文)
Interface preview: light English on the left and dark Simplified Chinese on the right. Both variants follow the DSH theme and in-app language setting.
Both screenshots use fictional demo data only. They contain no real session content, token counts, costs, balances, or API keys.
The plugin adds a compact indicator below the conversation composer. It shows input/output tokens, cache-hit ratio, estimated cost, active model, a slim context-pressure bar, and DeepSeek account balance. Click it to open a zero-dependency SVG dashboard with per-turn usage history — including a cost view (every bar shows its own cost value, not just the current round), a duration overlay, anomaly markers, an explainer tooltip (tokens + cost + model + billing tier + duration/TTFT/TPS + end reason), horizontally scrollable per-round bars (all rounds, fixed slim bar width, auto-scroll to latest), a dismissible ≈ ¥/$0.00xx badge on each assistant message, peak/off-peak tiered billing with a live red/green billing-tier tag in the panel (red = peak, green = off-peak, v1.0.1), and official dual-currency pricing (CNY from the Chinese pricing page, USD from the English pricing page — no FX conversion, v1.0.1).
The interface supports Chinese and English and follows the DSH in-app language setting. Browser language seeds the initial display only when the Host has not exposed a setting yet. Language changes are applied without reloading the plugin.
Install
Prerequisites: DeepSeek Harness ≥ 0.1.0-rc.6 ·
Node.js ≥ 20 · pnpm on PATH (dsh plugin forwards installs to pnpm).
If you get
dsh: command not found(or PowerShell'sThe term 'dsh' is not recognized…), you only rannpx @deepseek-ai/dshtransiently — see FAQ item 1 (global install + new terminal, or prefix everydsh ...withnpx --yes @deepseek-ai/dsh).
Option 1: npm registry (recommended, prebuilt — no build tooling needed)
dsh plugin --profile web add dsh-usage-chart # installs and registers the profile plugin layer
dsh web --profile web # starts DSH Web (stop it first if already running)
To update (upgrade to a new version): pnpm may print Already up to date and skip the
upgrade when the dependency is already installed — use an explicit version (recommended)
or remove then re-add:
# Option ①: pin the target version explicitly
dsh plugin --profile web add dsh-usage-chart@0.3.0
# Option ②: remove, then re-add (back to latest)
dsh plugin --profile web remove dsh-usage-chart
dsh plugin --profile web add dsh-usage-chart
Then restart DSH Web.
⚠️ Restarting the
dsh webprocess is required after any upgrade. The Host caches plugin code in memory (no hot reload): new routes (e.g./pricing,/meta,/rate) are only served after a restart. See the Changelog.
⚠️ No global
dshinstalled (dsh: command not found/ PowerShellThe term 'dsh' is not recognized…)? Prefix everydshabove withnpx --yes @deepseek-ai/dsh, e.g.npx --yes @deepseek-ai/dsh plugin --profile web add dsh-usage-chart@0.3.0(see FAQ item 1).
Option 2: install from GitHub (source build)
dsh plugin --profile web add github:Max-Samson/dsh-usage-chart#<commit-sha>
Git installs run the package prepare script (node build.mjs) to build from source.
pnpm ≥ 10 blocks prepare scripts by default — allow this package once in the profile's
pnpm-workspace.yaml, then re-run:
allowBuilds:
dsh-usage-chart: true
Allowing a build script lets that package execute code on your machine during install. Only do this for sources you trust, and pin the commit (
#<sha>).
Option 3: local directory (development)
git clone https://github.com/Max-Samson/dsh-usage-chart.git
cd dsh-usage-chart
npm ci && npm run build
dsh plugin --profile web add "$PWD" # links the current checkout
dsh web --profile web
Verify the install
The composed profile should contain the plugin row:
dsh --profile web --dump-config | grep -A4 'id: dsh-usage-chart'Open DSH Web and enter any existing session: the "Usage" indicator (tokens / cost / model) appears below the composer, with the account balance on the right; click ▸ to open the dashboard.
The balance query needs a DeepSeek API key, resolved per request in this order (no restart needed):
- DSH Web settings (recommended, requires plugin ≥ 0.1.1): configure the DeepSeek API key
under Settings → Models. The plugin reads the same key through the DSH credentials service
(
.credentials.yamluser layer); no extra setup is required. - Environment variable:
DEEPSEEK_API_KEY=sk-...before startingdsh web(the credentials service'senvlayer resolves it the same way). - Plugin config: override
config.apiKeyin the profile'scordis.patch.yml(stored in plain text on disk — only recommended for a protected local profile).
Plugin versions < 0.1.1 do not read the web-UI key: use the environment variable or
config.apiKeyinstead.
The key stays in the Host process and is never sent to the browser.
export DEEPSEEK_API_KEY=sk-...
dsh web --profile web
Price overrides (optional, v0.2+ / v1.0.1 dual-currency, tiered)
Costs are resolved with priority user override file > builtin list price > fallback
estimate (prices are resolved only on the Host; the client consumes the
/dsh-usage-chart/pricing snapshot — a single source of truth, ADR 2). The default
override file is $DSH_HOME/data/dsh-usage-chart/pricing.json (or ~/.dsh/... without
DSH_HOME); both flat and { "models": { … } } shapes are accepted and changes are
picked up live:
{
"deepseek-v4-flash": {
"offPeak": {
"cny": { "cacheMissInput": 1.5, "cacheHitInput": 0.05, "output": 4.5 },
"usd": { "cacheMissInput": 0.22, "cacheHitInput": 0.007, "output": 0.66 }
},
"peak": {
"cny": { "cacheMissInput": 3.0, "cacheHitInput": 0.10, "output": 9.0 },
"usd": { "cacheMissInput": 0.44, "cacheHitInput": 0.014, "output": 1.32 }
},
"verifiedAt": 1755100800000
}
}
Unit prices are dual-currency (CNY + USD) per 1M tokens: peak covers the official
peak hours (Beijing time 09:00–12:00 and 14:00–18:00, i.e. UTC 01:00–04:00 and
06:00–10:00, charged at 2×), offPeak covers the rest. The legacy flat shape
{ "cacheMissInput": …, "cacheHitInput": …, "output": … } is still accepted and treated
as tier-independent, quoted in CNY (USD derived at the default rate 6.76). verifiedAt
(epoch ms) is optional and shown as the verification date in the panel. Models not
covered anywhere are explicitly marked "Unpriced model" in the UI — never silently billed
as zero. To point at another file, set config.pricingFile in cordis.patch.yml.
Display currency and live FX rate (v0.3+ / v1.0.1 official dual-currency)
Costs are computed with the official list price of the selected currency (CNY quote
from the Chinese pricing page, USD quote from the English pricing page — no FX
conversion, consistent with the official bill). The cost section has a one-click
CNY/USD toggle (remembered in the browser); the indicator, panel, chart and badge all
follow it. config.cnyPerUsd (default 6.76) and the "Refresh rate" button (via the Host
/dsh-usage-chart/rate proxy) are used only for the informational "1 USD ≈ X CNY" note:
- Multi-source fallback: when the custom source (
config.fxUrl) is unreachable, a built-in fallback source (frankfurter.dev) is tried; - Offline resilience: the last successful rate is persisted, so a refresh while offline keeps the last real rate instead of the fixed default;
- Config distribution: the Host
/dsh-usage-chart/metaroute sends the display currency and rate config to the client; price notes follow the display currency and show the applied rate.
Uninstall
⚠️ No global
dshinstalled (dsh: command not found/ PowerShellThe term 'dsh' is not recognized…)? Prefix everydshbelow withnpx --yes @deepseek-ai/dsh, e.g.npx --yes @deepseek-ai/dsh plugin --profile web remove dsh-usage-chart(see FAQ item 1).
dsh plugin --profile web remove dsh-usage-chart # removes the dependency and de-registers the layer
dsh web --profile web # restart; the indicator/dashboard disappear
remove also cleans the package out of node_modules and dsh.profile.bundles (no leftovers).
Optional thorough cleanup:
- Remove any
config.apiKey/baseUrloverride block you added to the profile'scordis.patch.yml; - Remove the
dsh-usage-chartentry underallowBuildsinpnpm-workspace.yaml(GitHub installs only); - The DeepSeek API key configured in the web UI lives in the DSH credentials file
(
~/.dsh/.credentials.yaml) — do not delete it: DSH's own model service still uses that key. Only remove it if you are sure you no longer use DSH with DeepSeek.
FAQ
Q: dsh is not found (command not found / PowerShell The term 'dsh' is not recognized)?
A: npx @deepseek-ai/dsh runs transiently and installs no global command. Run
npm install -g @deepseek-ai/dsh and open a new terminal (on Windows also make sure the
npm config get prefix directory is on PATH), or prefix every dsh ... with
npx --yes @deepseek-ai/dsh .... Missing pnpm is the same: npm install -g pnpm.
Q: Install shows WARN missing peer react@^18.2.0?
A: Harmless — react is provided by the DSH Web platform in the browser; the profile does not
need it. Plugin ≥ 0.1.1 marks react as an optional peer and stops warning; on 0.1.0 the warning
can be ignored.
Q: The balance still shows – / "not configured" after setting the API key in the web UI?
A: Make sure the plugin is ≥ 0.1.1 (balance queries read the web-UI key through the DSH
credentials service from 0.1.1 on), then restart dsh web. As a stopgap, set
DEEPSEEK_API_KEY or config.apiKey.
Q: add reports dsh-usage-chart is not in the npm registry?
A: The package is not published to npm yet. Use "Option 3: local directory" to test, or wait
for the maintainer to publish.
Data sources
| Value | Source | Notes |
|---|---|---|
| Token usage | DSH tokenUsage / contextPressure projections |
Session-scoped, updated by the adapter |
| Per-round history | DSH Host session event log (/usage fold) |
Duration / TTFT / TPS / model / end reason / per-round cost; falls back to page-observed deltas when unavailable |
| Cost | Published DeepSeek price (builtin + optional pricing.json override; dual-currency CNY/USD per 1M tokens, peak/off-peak tiers) × reported usage |
Estimate, not an invoice; resolved once on the Host, consumed via the /pricing snapshot |
| Display currency / FX rate | Host /meta config + /rate live-rate proxy |
Live rate with multi-source fallback and last-rate persistence |
| Balance | DeepSeek GET /user/balance |
Proxied by the Host with no-store responses |
Development
git clone https://github.com/Max-Samson/dsh-usage-chart.git
cd dsh-usage-chart
npm ci
npm run verify
npm pack --dry-run
The package contains two DSH halves: lib/index.js for the Node Host and lib/client.js for the Web client module loader. Type declarations are emitted to lib/types. lib/client-test.js is a small ESM bundle of client-side pure modules (e.g. the anomaly detector) consumed only by tests/*.test.mjs.
See CONTRIBUTING.md before opening a pull request. Please report vulnerabilities privately as described in SECURITY.md.
Maintainer releases
For the first release, complete npm account verification and run npm publish --access public locally. Once the package exists on npm, configure Trusted Publishing for this repository. Subsequent GitHub Releases publish new versions through the workflow. The workflow skips versions that already exist, so creating the initial v0.1.0 Release will not publish it twice.
Compatibility
| Component | Supported |
|---|---|
| DSH | ≥ 0.1.0-rc.6; built against the 0.1.x API |
| Node.js | ≥ 20 |
| Web UI | React 18, conversation.composer.dock and conversation.chat.assistant-actions |
| OS | macOS, Linux, Windows; no native dependencies |
Community and open source
License
MIT