DeepSeek Harness Plugin

HaoyueQin/dsh-usage-statistics-panel

Stars ★ 19 Downloads (30d) 3,362 Category Usage & Billing Added 2026-08-23 npm dsh-usage-statistics-panel

Usage statistics settings panel: 26-week activity heatmap, daily token trend with a cache hit-rate curve, per-model donut and breakdown, time-range filters, summary cards, one-time historical backfill and lossless rebuild.

Install

# from npm (prebuilt)

dsh plugin --profile web add dsh-usage-statistics-panel

# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)

dsh plugin --profile web add github:HaoyueQin/dsh-usage-statistics-panel

Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).

README

English | 中文

A usage statistics panel plugin for the DSH web UI: per-day token trend, a GitHub-style activity heatmap, a cache hit-rate curve, and two breakdowns — by model and by provider (donut + detail list each) — living on the plugin's own page inside the Plugins page, with its own row in the left rail.

All charts are hand-drawn SVG with no chart library; the palette uses GitHub Primer's data-viz two-set tokens (the top ten models and the top five providers each get a distinct rank colour, everything else collapses into a gray "Other" bucket) and adapts to the DSH theme.

Preview

Features

  • Time ranges: last 7 / 14 / 30 / 90 days, or a custom from/to pair
  • Summary cards: token usage, sessions (completed turns), requests, active days, average cache hit-rate, top model
  • 52-week activity heatmap: GitHub-style day cells, hover for the day's detail; the data window is a fixed year and the column count adapts to the available width (a narrow pane shows fewer weeks), so the chart always spans its container edge to edge
  • Daily token trend: stacked bars with a smooth cache hit-rate curve (Catmull-Rom), hover for the per-model breakdown; the plot spans the container width at any size
  • Model usage: donut + detail list; the top ten models keep distinct colours, the tail collapses into an expandable "Other" row, and the ring's diameter adapts to the available width between 200 and 280px, centred against the list beside it
  • Provider usage: the same anatomy one dimension up — the top five providers keep distinct colours from their own palette, the tail collapses into a gray "Other" bucket, hovering either side lights the other, and the ring's hover tip lists every model that provider served. Each row expands (the Other bucket opens the providers it folded, and each of those opens its own models); expanding never resizes the ring
  • Bottom-bar enhancements: three switches at the bottom of the panel, all in the same framed style and applied instantly — "Precise cache hit rate" (two decimals, e.g. 85.25%), "Session token breakdown" (total, input, cached input, uncached input and output in place of the default input/output pair), and "Streaming throughput" (the speed reading refreshes to a live estimate on every stream delta and hands back to the session's exact figure once the step settles; the estimate starts from DeepSeek's published character density and is calibrated against the chars-per-token ratio measured from the session's own settled steps, and the live rate counts only the token growth actually observed inside the last 2 s and smooths it, so neither a backlog the UI delivered late nor one noisy frame moves the display, and a step that goes quiet holds its last reading instead of dropping back to the session average)
  • History backfill: on first enable, the plugin enumerates and replays existing session logs; for a live session the collector attached to mid-flight, its pre-attachment history is recovered on the next boot by replaying the log prefix below the recorded seq boundary, so historical usage is accounted from day one as faithfully as the logs allow
  • Local persistence: data lands in $DSH_HOME/storages/usage_history.json (storage-domain), fully local, no external services

Install

dsh plugin --profile <name> add dsh-usage-statistics-panel@latest

After mounting, hard-refresh the browser (Cmd/Ctrl+Shift+R): client-half changes hot-reload in DSH, no restart needed; only host-half updates (collector/storage/routes) require restarting DSH.

Once mounted there are two ways in: the Usage statistics row in the left rail under New Session, or Plugins → Installed → usage-statistics-panel on its detail page (the card and the detail page take their title, description, and icon from this package's locale/*.json and icon.svg, following the interface language across Simplified Chinese, Traditional Chinese, and English; the full package name is still listed there as a code line). Both render the same panel. The standalone panel also carries a back control in its top-left corner, returning to whatever was selected before it — the Conversation, the Plugins page, or another plugin's panel.

Compatibility: this plugin supports DeepSeek Harness >= 0.1.7-rc.1; dev dependencies and the verification target track host 0.1.7-rc.2, verified on 0.1.7-rc.2, with V3 / V4 session-log compatibility covered by unit tests. The dual-path backfill (list+inspect on 0.1.2-rc.1, list+open+paged read+close from 0.1.3-alpha.*) is retained.

The bottom-bar row adapts to the container it is rendered in: from 0.1.6-alpha.2 the host places it in a flex row beside the context-occupancy ring (which owns the centring, the gap, the top pad and the side clearance), while through 0.1.6-alpha.1 the row still owns its content width, its side gutters and its 4px top pad — one build stays aligned on both.

The @deepseek-ai/* peer declarations state the capability floor only (>=0.1.7-rc.1 is the earliest interface surface the plugin uses) and are all marked optional. Under semver's pre-release rule that range matches only the pre-release of the same tuple — 0.1.7-rc.2 satisfies it, while the next pre-release line (0.1.8-rc.1) does not — so the supported host versions are those stated in this section rather than npm peer validation.

Older-host users: on DeepSeek Harness 0.1.6-alpha.2 or earlier, install plugin version 0.3.0 or older. On the 0.1.7 line the host renamed the whole @deepseek-ai/dsh-client-ui-primitives icon export set to a weight-based scheme (*Outline16 → *OutlineRegular / *Medium) with zero overlap between the two generations: the old names resolve to undefined on 0.1.7+ and break the bottom info bar — one build cannot serve both.

Data source

The collector is observational: it subscribes to the session event stream (session/event), reads provider-reported TokenUsage from assistant/message and assistant/chunk (input / output / cache-read / cache-write), and dedupes by (turn, step) WITHIN one session (each call counts once, keeping the first report — the shipped adapters report identical values on the streaming sample and the final message; concurrent sessions never swallow each other's samples). Model attribution prefers the message's own source (stamped per call) and falls back to the session's route fold (request/context events or the session's requestContext()), so a host restart never drops samples into the "(unknown)" bucket. On first enable it also backfills by replaying persisted session logs.

Note: usage accumulates from the day the panel is enabled (including the backfill). Sessions whose logs predate the feature carry no provider-reported usage and cannot be reconstructed.

Token semantics: the headline token total on the cards and in the trend is PROVIDER-INCLUSIVE — uncached input + output + cache reads + cache writes, matching what a provider dashboard reports for the same calls (DeepSeek splits prompt tokens into disjoint input/cache-read buckets, so a naive input+output sum would hide the typically dominant cached share). The average cache hit-rate keeps an input-side-only denominator (hits + misses), and the hit-rate card also shows the absolute cached volume; the two denominators never mix.

Rebuilding stats: the Rebuild button in the toolbar, to the right of Refresh, is that action behind a two-press confirm — the first press turns it red and reads "Rebuild?", and only the second runs it (moving focus away, pressing Esc, or five seconds without a second press cancels it). It is the same as POST /usage/api/reset (behind the same trust fence as the panel): it wipes the local statistics and replays every persisted session log under the CURRENT attribution rules — the escape hatch for corrupted history or attribution-logic upgrades. Sessions still open at reset time are re-bounded at their wipe-time log length: everything below is rebuilt by the replay, everything after stays with the live collector, and nothing counts twice.

Development

pnpm install
pnpm typecheck   # tsc --noEmit
pnpm test        # vitest
pnpm build       # tsc declarations + tsdown (host ESM + dual-channel client bundles)

Design & implementation

  • Host half (src/): collector (event subscription + backfill fold), store (the usage_history storage domain), query (range aggregation, a TS translation of the reasonix query.go), routes (the fenced /usage/api JSON routes, same trust fence as the /api gateway)
  • Client half (src/client/): UsageStatsPanel.tsx (hand-drawn SVG charts ported from the reasonix panel + Primer palette), locales (en / zh / zh-TW), api (the /usage/api fetch wrapper)
  • Dual-channel bundles: lib/client.js (official profile channel, bundle id = package name) and lib/client-registry.js (plugin-registry channel, bundle id = manifest id)
  • Full design notes: docs/design.md

Acknowledgements

This panel is a port of the usage statistics feature the author originally built for DeepSeek-Reasonix (PR #7238 and #7503). The front-end charts are largely reused from that implementation; the data layer is rebuilt on DSH's session logs and storage-domain.

Activity

License

MIT

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →

Community comments

Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.