Skip to main content
M

dsh-cost-dashboard

mike-lee0120/dsh-cost-dashboard

Cost dashboard for DeepSeek Harness: aggregates model input/output/cache tokens across all local sessions, prices them with a builtin table (including DeepSeek peak/off-peak), and shows daily trends plus per-model and per-session tables.

Install

dsh plugin --profile web add github:mike-lee0120/dsh-cost-dashboard

README

dsh-cost-dashboard

English | 中文

A cost-dashboard plugin for DeepSeek Harness (dsh): aggregates model input / output / cache token usage across all local sessions, prices it with a built-in table (including DeepSeek peak/off-peak time-of-day pricing), and renders a dashboard under Settings -> Cost Dashboard.

What you get

  • Two entry points: Settings -> Cost Dashboard (the settings nav icons are hardcoded by the dsh settings shell, so plugins cannot customize them), plus a sidebar footer icon button (data-grid style) that opens the same dashboard in an anchored panel
  • Currency switch: displays in USD by default with a one-click CNY toggle; converts between CNY- and USD-listed prices at the configurable fx.cnyPerUsd rate (default 6.79)
  • Summary cards: total cost, today's cost, input (cache-miss) / cache-read / cache-write / output tokens, session count
  • Daily trend chart: ECharts smooth line charts (gradient area fill and hover tooltips); cost mode is a single unified-currency series, tokens mode splits into "input / cache write / output" and "cache read" charts on independent scales; selectable 1W / 1M / 3M ranges (default 1W)
  • By-model table: tokens, cost, share per model
  • By-session table: sorted by cost, one row per session-model pair (a session that used several models appears on several rows, each with its own model, tokens and cost), with title, project directory, subagent badge
  • Pricing editor: edit the pricing JSON (including the FX rate) in-page; saves to ~/.dsh/cost-dashboard.json, effective immediately
  • Auto-synced catalog: fills in models missing from builtin/overrides from the LiteLLM price JSON (24h TTL + disk cache, degrades on network failure); never overrides builtin or hand-written prices
  • Actual billing (optional): with read-only provider keys configured, shows DeepSeek/OpenRouter real balances and OpenAI/Anthropic real spend next to the estimate; domestic cloud vendors (Volcengine/Alibaba/Tencent) are not integrated - prices come from the config file
  • Auto refresh: polls every 15s while open; the host re-reads only changed log files (mtime + size validated)

Cost dashboard - trend & summary Cost dashboard - model & session breakdown

Install

dsh plugin --profile web add <spec>

<spec> may be a local path, an npm name, or a GitHub repo:

dsh plugin --profile web add /path/to/dsh-cost-dashboard
dsh plugin --profile web add github:mike-lee0120/dsh-cost-dashboard

dsh plugin add runs pnpm in the profile directory and automatically appends any dsh.bundle-declaring package to dsh.profile.bundles. Restart dsh web and refresh the page, then open Settings -> Cost Dashboard.

Remove with dsh plugin --profile web remove dsh-cost-dashboard.

Requires dsh 0.1.0-rc.7+ and Node >= 22.15 (the node:zlib zstd API the host itself relies on for session logs).

Data source and accounting

  • Read-only scan of $DSH_HOME/sessions/*/*/session.jsonl.zstd (or plaintext .jsonl); nothing is written, no projection touched.
  • Accounting mirrors the official @deepseek-ai/dsh-token-meter tokenUsage projection:
    • assistant/chunk {type:'usage'} is an early sample that survives a later request failure;
    • assistant/message usage is the final sample for the same (turn, step) and replaces it instead of double counting;
    • four disjoint buckets: uncached input (DeepSeek prompt_tokens with cache hits subtracted), cache read, cache write, output.
  • Model attribution: assistant/message carries message.source.provider/model; a bare usage chunk (failed request) is attributed to the latest request/header model.
  • Mid-session model switches are split correctly.
  • Run node scripts/verify-totals.mjs to reconcile against the official session_projcache.json (verified session-by-session in development; an actively-writing session may drift by a live-write race, which is expected).

Pricing

Built-in pricing for 21 mainstream models (per 1M tokens, checked 2026-08-18; "hit" = cache-read rate, "write" = cache-write rate, defaults to the cache-miss input rate when unset):

CNY-listed models

ModelInput (miss)Input (hit)OutputNotes
deepseek-v4-pro4.50.1513.5peak doubles: 9 / 0.30 / 27 (09-12, 14-18)
deepseek-v4-flash1.50.054.5peak doubles: 3 / 0.10 / 9.0
kimi-k3202100Moonshot China list price
qwen3.8-max121.536Alibaba Bailian China price
doubao-seed-2.1-pro6-30Volcengine Ark
hy310.254Tencent Hunyuan
minimax-m33.150.6312.6≤512K input, half-price list rate

USD-listed models

ModelInput (miss)Input (hit)Cache writeOutputNotes
gpt-5.6-sol50.5-30
gpt-5.6-terra20.2-12
gpt-5.6-luna0.200.02-1.20
gpt-5.550.5-30
gpt-5.42.50.25-15
gpt-5.11.250.125-10
claude-opus-550.56.2525
claude-sonnet-520.22.510temporary rate through 2026-08-31, then $3/$15
claude-fable-510112.550
gemini-3.6-flash1.5--7.5
gemini-3.5-flash-lite0.3--2.5
grok-4.62--6
grok-4.6-fast41-12
glm-5.31.40--4.40Z.ai list price; override for the volcengine route
  • DeepSeek V4 peak/off-peak pricing effective 2026-08-17 (off-peak is half of peak; peak hours 09:00-12:00 and 14:00-18:00). Every usage record is timestamped, so the dashboard prices each sample by the host-local clock hour.
  • Unpriced models count tokens only.

Overrides

The in-dashboard Pricing config editor saves ~/.dsh/cost-dashboard.json (per-model whole-entry overrides plus the FX rate):

{
  "fx": { "cnyPerUsd": 6.79 },
  "models": {
    "glm-5.3": { "currency": "USD", "input": 1.4, "inputHit": 0.14, "output": 4.4 },
    "my-local-model": { "currency": "CNY", "input": 2, "output": 6,
                        "peak": { "input": 4, "output": 12 }, "peakHours": [[9, 12], [14, 18]] }
  }
}

Fields: fx.cnyPerUsd (USD->CNY, default 6.79, used for cross-currency display); per model currency (CNY|USD), input (cache-miss), inputHit (defaults to input), cacheWrite (defaults to input), output; optional peak and peakHours (host-local hours; peak hours use peak rates, unset peak fields fall back to flat). The dashboard displays USD by default and converts CNY-listed prices at the FX rate; switching to CNY converts USD-listed prices the other way.

Auto-synced catalog

  • Beyond the builtin table, the dashboard fills missing models from the LiteLLM price JSON (USD rates, converted for display via fx).
  • Priority: user override > builtin > catalog — the catalog only fills gaps and never overrides builtin peak pricing or your hand-written config.
  • Refreshed every 24h and cached at ~/.dsh/storages/cost-dashboard-catalog.json; on network failure it degrades to the cache, the status is visible in the dashboard footer, and a "Refresh prices" button retries manually.

Actual billing (optional)

  • Expand the Actual billing section and configure read-only provider keys to show real balances and spend alongside the estimate.
  • Supported: DeepSeek /user/balance (balance), OpenRouter /api/v1/key (credits), OpenAI Cost API (daily spend), Anthropic Cost Report (daily spend).
  • Credentials are stored at ~/.dsh/cost-dashboard-credentials.json (mode 0600):
{
  "providers": {
    "deepseek": { "apiKey": "sk-..." },
    "openrouter": { "apiKey": "sk-or-..." },
    "openai": { "adminKey": "sk-admin-..." },
    "anthropic": { "adminKey": "sk-ant-admin-..." }
  }
}
  • Use read-only/billing-scoped keys only; remove an entry to stop fetching it. Domestic cloud vendors (Volcengine/Alibaba/Tencent) are not integrated - their prices live in the pricing config.

Development

Plain .mjs, zero build step (host uses only Node builtins; the client is a hand-written module-loader bundle; charts use the vendored ECharts 5 build, Apache-2.0, served locally from /cost-dashboard/vendor/echarts - no CDN). Restart dsh web and refresh the page after any change.

Security

  • GET routes expose the same surface as other plugins' own routes (local data, no credentials).
  • The pricing write (POST) accepts same-origin requests only (Origin==Host).
  • Nothing is uploaded; the scan is read-only.

Known limitations

  • Costs are list-price estimates; no plans, discounts, or vouchers; peak hours use the host-local clock.
  • Deleting session logs removes their history (statistics are entirely log-derived).
  • Very large log corpora slow the cold scan; incremental caching keeps everyday refreshes fast.

Related plugins