Bundle
dsh-balance-meter
Official, proxy-compatible, or locally accounted balance and session-cost readout for the DSH web GUI.
- Source
- Ghost011118
- stars
- 19 stars
- License
- BSD-3-Clause
- Updated
- Updated 3 days ago
Readme
# dsh-balance-meter
English | [中文](README.zh.md)
DeepSeek account balance and session-cost readout for the DeepSeek Harness (DSH) Web GUI.
- Explicit balance sources: official API, proxy-compatible endpoint, or a
manual balance accounted and persisted locally
- Current session estimated spend (token usage x official pricing)
- Per-model pricing: reads the model actually driving each session from its
request header (flash vs pro), so the cost tracks the model you used instead
of a fixed default
- Auto-fetches the official pricing page every 6h, so price changes and the
2026-08-17 peak/off-peak pricing rollout never require a plugin update
- Peak-hour band (Beijing 09:00-12:00 / 14:00-18:00) applied automatically
once the peak pricing goes live
## Features
The composer dock shows a chip with the account total balance and the
current session's estimated cost:
```
Balance CNY 4.16 · This session CNY 2.57
```
Clicking the chip reveals the per-currency balance breakdown (granted +
top-up) and the per-bucket cost breakdown (input / cache read / output).
Clicking while an error is shown forces an immediate refresh.
## Requirements
- DeepSeek Harness `0.1.0-rc.6` or newer (web profile)
- A DeepSeek API key stored through the DSH credentials seam
(`DEEPSEEK_API_KEY` — the web Models page writes it)
## Installation
From a git URL (no npm account needed):
```sh
dsh plugin --profile web add https://github.com/Ghost011118/dsh-balance-meter
```
Or from a local checkout:
```sh
git clone https://github.com/Ghost011118/dsh-balance-meter.git
dsh plugin --profile web add link:$(pwd)/dsh-balance-meter
```
Restart `dsh web`, then refresh the page. The balance chip appears in the
composer dock next to the conversation stats line.
## Configuration
The plugin is zero-config by default (uses `DEEPSEEK_API_KEY` and the
official pricing page). Optional composition settings:
```yaml
- insert:
- id: balance
name: 'dsh-balance-meter'
config:
source: official # official (default) | proxy | manual
model: auto # 'auto' (default) | 'flash' | 'pro'
pricingRefreshHours: 6
```
| Key | Type | Default | Meaning |
|---|---|---|---|
| `source` | `'official' \| 'proxy' \| 'manual'` | `official` | Provenance of the displayed balance. A legacy custom `baseUrl` with no source is automatically classified as `proxy` |
| `balanceEndpoint` | `string` | `/user/balance` | Proxy balance path or absolute HTTP(S) URL |
| `proxyBalancePath` | `string` | unset | Dot path (for example `data.balance`) to a numeric balance when the proxy does not return DeepSeek-compatible `balance_infos` |
| `proxyCurrency` | `string` | `CNY` | Currency paired with `proxyBalancePath` |
| `manualBalance` | `number >= 0` | unset | Current balance entered by the user; changing it creates a new local accounting baseline |
| `manualCurrency` | `string` | `CNY` | Currency of the manual balance |
| `model` | `'auto' \| 'flash' \| 'pro'` | `auto` | `auto` detects each session's model from its request header (flash/pro); `flash`/`pro` force that preset regardless of auto-detection |
| `pricingRefreshHours` | `number` | `6` | Hours between automatic official-pricing refreshes |
| `apiKeyEnv` | `string` | `DEEPSEEK_API_KEY` | Credential ref storing the DeepSeek API key |
| `baseUrl` | `string` | `https://api.deepseek.com` | API base URL (gateway/compat override) |
| `refreshIntervalSeconds` | `number` | `30` | Minimum seconds between balance queries |
### Proxy and manual modes
`proxy` mode keeps the API key on the DSH host and sends it only as a Bearer
credential to the configured endpoint. A DeepSeek-compatible relay may return
`balance_infos` directly. Other relays must configure `proxyBalancePath`; a
missing or non-numeric value is reported as a proxy error and is never labelled
as an official balance.
`manual` mode requires a writable DSH settings provider. The hidden ledger is
stored inside the existing `balance` settings namespace, not in a separate
plaintext file and never in the browser response. It records a baseline,
remaining amount, locally charged spend, and per-session cumulative-token
checkpoints. Only positive token deltas after the last persisted checkpoint are
charged, so polling or restarting DSH cannot deduct the same cumulative session
usage twice. Changing `manualBalance` or `manualCurrency` intentionally creates
a new baseline and checkpoints all currently live sessions.
## How the cost is estimated
The plugin reads DSH's durable `tokenUsage` projection (the same accounting
the built-in stats line uses) and converts the four buckets — uncached
input, cache read, cache write, output — to money using prices parsed from
the official pricing page. Cache-write tokens are not billed separately by
DeepSeek and default to 0.
For the price set, in `auto` mode (the default) it uses the model actually
driving the session: each session's request header records the provider/model
of the most recent request, and the plugin maps that id (`deepseek-v4-flash`
→ flash, `deepseek-v4-pro` → pro) to the matching per-million prices. A
session is therefore priced at whatever model produced its usage, not a
hard-coded flash. When no header exists yet or the model id is unrecognized,
`auto` falls back to flash. Setting `model: flash` or `model: pro` explicitly
forces that preset and ignores auto-detection, so you can pin the estimate to
one model when you want to.
Before the 2026-08-17 peak-pricing rollout the current single prices stay
authoritative; after it, the peak/off-peak band for the current Beijing hour
is applied. If the pricing page cannot be fetched, built-in presets (flash:
0.02 / 1 / 2 CNY per 1M) are used. Explicit `cost.*` overrides in the
composition config take precedence over any preset. The cost JSON also
reports `pricingKey` and `model` so the chip can show which model was priced.
## Troubleshooting
### "no API key for provider route \`deepseek-official\`"
The host reads your key from the DSH credentials store — the file
`<harness home>/.credentials.yaml` (default `~/.dsh/.credentials.yaml`), the
same store the web **Models** page writes. This plugin's balance query and the
LLM route resolve through that same seam.
- If this error appears, make sure the document contains
`DEEPSEEK_API_KEY: sk-...` (a strict mapping of reference to non-empty
string). Editing it while DSH runs is fine — the provider hot-reloads and
re-reads the file.
- When a credentials seam is mounted, both the LLM route and this plugin read
the key *only* from the credential store; a plain `export DEEPSEEK_API_KEY`
is ignored in that case. Exporting still helps for the plugin's own fallback
when no seam is present.
- Prefer running `dsh web` through a single supervised instance (e.g.
`dsh-autostart`) instead of launching several ad-hoc `npx dsh web`
processes that can race on the same port and settle different credential
snapshots. If you encounter this right after killing a manual instance,
confirm the other (still-supervised) instance read the key — the balance
chip recovering to a live total means the key resolved.
- The error is transient-friendly: the balance chip auto-recovers, because an
error state is never cached as fresh — the next poll re-queries the
provider.
### Balance stuck on "unavailable" and only updates on click
An error/unavailable snapshot used to be served from the cache until it aged
out, so a transient failure could hold the chip on "unavailable" until you
clicked to force a refresh. Now an erroneous view is **never** reused as a
fresh cache: every poll re-queries the provider, so the chip recovers on its
own as soon as the underlying condition clears (balance reachable, network
back, key stored).
## License
BSD-3-Clause. Copyright (c) 2026, Ghost011118.
Install
dsh plugin --profile web add github:Ghost011118/dsh-balance-meter#1a277e8eb9ee5ebbf8589e6bbb96bfe9ac282c11
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-balance-meter from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.