Ghost011118/dsh-balance-meter 预览 preview

Ghost011118/dsh-balance-meter

DeepSeek 账户余额与会话费用读取,适用于 DeepSeek Harness Web GUI

项目介绍Project Overview

DSH 余额计量插件,面向 DeepSeek Harness Web 界面,在会话撰写区显示账户余额与本次会话估算花费。能力:支持官方、代理或手动三种余额来源,按请求头识别 flash 或 pro 模型计费,自动每 6 小时抓取官方定价并应用北京高峰时段。适用:需要实时掌控余额与单次会话成本的 DSH Web 用户。注意:需 DSH 0.1.0-rc.6 及以上,并通过凭据存储配置 DEEPSEEK_API_KEY,定价页获取失败时回退至内置 flash 预设。

dsh-balance-meter is a DSH web-UI plugin that shows DeepSeek account balance and current-session cost in the composer dock. It supports official, proxy, or manual balance sources, detects the session's actual model (flash or pro) from request headers, refreshes official pricing every 6 hours, and applies Beijing peak/off-peak bands once the 2026-08-17 peak pricing goes live. Use it when you need live balance and per-session spend visibility in DSH. Caveat: requires DSH 0.1.0-rc.6+ with DEEPSEEK_API_KEY stored via the credentials seam, and falls back to built-in flash presets when the pricing page is unreachable.

或使用命令行安装(适合开发者)Or use CLI install (for developers)

命令行安装CLI Install

dsh plugin --profile web add https://github.com/Ghost011118/dsh-balance-meter

Ghost011118/dsh-balance-meter 加入你的 DSH 配置(web profile)即可启用。

READMEREADME

dsh-balance-meter

English | 中文

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):

dsh plugin --profile web add https://github.com/Ghost011118/dsh-balance-meter

Or from a local checkout:

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:

- 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.

上一个 Prev deepspider 下一个 Next dsh-skin