DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Deepseek Cost — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
D

dsh-deepseek-cost

Deepseek Cost

DSH plugin: DeepSeek-official cost accounting (session total + current turn) added to the built-in Token usage panel.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:wuenna/dsh-deepseek-cost#372b5e7c39d67f9808811adf496e584b6cd8446c
READMECompatibilityVersions

Compatibility and provenance

Deepseek Cost is published as dsh-deepseek-cost and currently resolves to version 0.1.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
9/23/2026

Versions

0.1.0stable
9/23/2026

Related plugins

Loading related plugins…

Latest
0.1.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
9/23/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in models-usage.

Usage@linxin666/dsh-usageUsage statistics plugin for the dsh web GUI: per-provider balance and coding-plan quota detection plus a live token usage ledger, with a compact price glance card above the sidebar's Settings rowCommandcode Provider@mars-sea/dsh-commandcode-providerUnofficial DeepSeek Harness LLM provider plugin for Command Code, ported from pi-commandcode-provider (MIT). Registers the 'commandcode' provider route with a Models-page card and live model catalog.Plugin Subscriptionsdsh-plugin-subscriptionsUse ChatGPT (Codex), Claude, Grok (X Premium), GitHub Copilot, and Google Antigravity subscriptions as DeepSeek Harness LLM providers, with OAuth login from the web Settings pageCodex Connectdsh-codex-connectChatGPT OAuth and Codex models for DeepSeek Harness.

README

dsh-deepseek-cost

A DeepSeek Harness (DSH) plugin that shows what the conversation has cost so far: a cost pill beside the built-in step/time and token statistics, with the session total and the current turn priced at DeepSeek's official peak/off-peak API rates, plus one 花费 row in the built-in 本轮用量 panel of every completed turn. Every non-DeepSeek route is counted as 0.

What it adds

One cost pill in the composer dock, inline beside the built-in step/time and token pills. The leading ¥ is the currency mark for the whole pill, so the amounts beside it stay bare — one symbol per pill:

[¥] 0.4321 · 本轮 0.0123

Clicking it opens its own details dialog, shaped like the built-in step and token dialogs (same panel, title, and rule — the same shipped useAnchoredPosition / useDismissOnOutsidePointer primitives position and dismiss it).

The panel itself is the grid: the cost category, then one column per scope. The two scope totals sit in the title bar, and because the grid starts at the panel edge they land exactly over the columns they summarize.

¥  花费                  ¥ 0.4321     ¥ 0.0123
──────────────────────────────────────────────
                          会话         本轮
输入未缓存               ¥ 0.0120     ¥ 0.0010
输入缓存                 ¥ 0.0988     ¥ 0.0028
输出                     ¥ 0.3213     ¥ 0.0085
──────────────────────────────────────────────
预估(按官方价)         ~¥ 0.1650    ~¥ 0.0165
──────────────────────────────────────────────
计费时段                              空闲时段
未计费调用            1 次 · 非 DeepSeek 官方,按 0 计
  • The three cost categories are the prompt-side split (输入未缓存 / 输入缓存) plus 输出, each priced per scope. The 会话 / 本轮 captions name the two value columns.
  • The title bar carries one total per scope, so no totals row is repeated below and neither total is printed twice.
  • 预估(按官方价) answers "what would the routes billed at 0 have cost at official rates?" — see Estimating the routes billed at 0. It reuses the two scope columns, is dimmed, and is tilde-marked so it is never read as part of the billed total. It appears only when some call was actually billed at 0.
  • Items that belong to neither scope own a whole line in the full-width footer below the grid — that is how "spans both columns" is expressed here, and it also keeps the divider above them continuous (a spanning grid row would break its hairline on the column gaps).

Nothing built in is replaced. The pill is a normal occupant of the composer's dock slot, and the dock lays its occupants out inline, so the pill simply sits beside the built-in pills. If the projection is absent the occupant renders null and nothing regresses.

The row in the built-in 本轮用量 panel

Opening a completed turn's built-in usage info shows the turn's tokens; this plugin appends the turn's cost as the last row of that same list, so the money is read where the tokens are:

本轮用量                     22,582.085 tok
──────────────────────────────────────────
提供方 / 模型   deepseek-official/deepseek-flash
缓存命中                            97.8%
未缓存输入                     487,432 tok
缓存读取                    22,070,784 tok
缓存写入                           0 tok
输出                            23,869 tok
花费                              ¥ 1.02

That panel is shipped UI with no slot of its own, so this is the one place the plugin reads another package's DOM — deliberately, and through exactly two hooks:

  • dl[data-turn-usage-details] — the attribute DSH puts on the turn-usage panel's own row list (the neighbouring session-stats and performance panels use data-session-stats-details, so this one is unambiguous). The row is appended only while that panel is open, and only after checking it is not already there.
  • data-turn-tail — the turn number DSH stamps on a completed turn's footer, read from the clicked trigger's ancestors. A trigger click is the only way the panel opens, so a panel opened for an older turn shows that turn's cost, never the current turn's.

The append is idempotent, the observer watches only document.body's children (where the panel is portaled), and the whole watcher is one effect on the occupant that disconnects when the occupant unmounts. client.test.mjs asserts the selector inventory of the whole bundle, so a third hook cannot be added quietly.

A turn whose calls were billed at 0 still gets the row, carrying the same what-if as the dialog — 花费 ¥ 0.00(预估 ~¥ 0.98) — and a turn older than the plugin's own ledger was never priced at all, so its panel is left untouched.

Estimating the routes billed at 0

Only deepseek-official is billed, so every other provider shows a real cost of 0. The estimate says what those same requests would have cost at official rates.

Which rate. The model id picks the reference tier: an id naming a Pro model references deepseek-v4-pro, everything else references deepseek-flash — a Flash alias, a DeepSeek id of unknown version, or a model from another family entirely (Qwen, GLM, MiniCPM5-2B). Flash is the cheapest official rate and so the conservative choice for a what-if.

Which cache-hit rate. This is the one premise the estimate rests on, so it is stated rather than buried:

Route reportsRate used
no cache reads at all (0%)95% cache hit
any non-zero cache hit ratethat rate, as reported

Third-party routes frequently report no cache accounting at all, and an agent session re-sends almost its whole prompt every step. Reading a reported zero literally would price the entire prompt at the cache-miss rate — an order of magnitude too high. So the whole prompt is re-split by the hit rate rather than read bucket by bucket, and 95% is the shape a real session settles into.

The estimate follows the same rules as the real cost: the same peak/off-peak multiplier, the same in-step sample replacement, and the same retry accounting.

Pricing

Rates are CNY per 1,000,000 tokens, off-peak, with peak windows charged at exactly twice every rate. Source: https://api-docs.deepseek.com/zh-cn/quick_start/pricing/.

Model idsEffective from (Beijing)缓存命中缓存未命中输出
deepseek-flash, deepseek-v4-flash, deepseek-v4-flash-vision-exp2026-08-17 00:000.051.54.5
same2026-09-10 12:000.0214
deepseek-v4-pro2026-08-17 00:000.154.513.5
  • Peak windows are Beijing 09:00–12:00 and 14:00–18:00, Monday through Friday; everything else is off-peak, weekends included.
  • The two retired Flash aliases are still callable and are served — and billed — as deepseek-flash, so they share its tiers.
  • Cache writes are charged at the cache-miss rate.
  • Reasoning tokens are already part of the provider's outputTokens, so they need no separate row.
  • A model id with no published rate, and every provider other than deepseek-official / deepseek, is billed 0 while its tokens stay visible (freeCalls in the projection), so an unpriced call is never silently folded into a DeepSeek figure.

How it works

Host half (lib/index.js) registers the deepseekCost session projection on ctx.sessionProjections. A projection is a pure, synchronous fold over the whole durable session log, so the figures are complete regardless of transcript paging and compaction — the same seam tokenUsage and sessionStats use.

The fold mirrors token-meter's replacement rule: the last usage sample inside one (turn, step) replaces its predecessor, and llm/retry-started closes that slot so a retried attempt adds a second billed attempt. Route attribution prefers the settled assistant message's own source, then the last request/header / request/context snapshot.

Besides the session and current-turn totals, the fold keeps a per-turn ledger (turns, keyed by the turn number) of every turn's cost and estimate. A finished turn is never the current turn again — turn/start resets the current-turn figures at every boundary — yet its usage panel stays openable from the transcript, so the ledger is what makes that panel answerable. Replacement and retry rewrite only their own turn's entry.

Browser half (lib/client.js) registers one occupant on the conversation.composer.dock list slot, reads the projection with useProjection('deepseekCost'), and returns the pill as that occupant's element. The dock is a flex row (InputBar.module.css .dock), so the pill is laid out inline beside the built-in pills; the occupant owns no portal and no anchoring. The pill owns its dialog seat, replicating the built-in useStatDialog placement and dismissal from the shipped primitives. The occupant's one effect is the turn-usage row watcher described above.

The dock slot is the public contract, which is what makes the pill survive DSH upgrades: 0.1.6 dropped the statistics row's data-composer-stats hook that an inline portal would have needed. The pill never referenced a class name belonging to another package. The 本轮用量 row is the deliberate exception — that panel offers no slot — and it is confined to the two data- attributes above rather than any hashed class name.

The package declares both dsh.bundle.patch and dsh.client, so one install command wires the host row and the browser bundle.

Where things live

Two directories carry this plugin's name, and they hold different things:

PathWhat it is
~/.dsh/plugins/dsh-deepseek-cost/The plugin source: package.json, cordis.patch.yml, lib/, test/, README.md. Everything you edit lives here.
~/.dsh/dsh-deepseek-cost/The plugin's state dir, owned by the running plugin. It holds only boot.log.

boot.log is a one-line activation record the host half overwrites on every mount (2026-09-11T11:43:49.732Z host half mounted: projection "deepseekCost" registered). It is the quickest way to answer "did my restart actually load the plugin?" when the browser shows nothing. Its parent honours $DSH_HOME the way the rest of the harness does, so setting that variable moves it.

The name collision is the harness's own convention — a plugin owns ~/.dsh/<package-name>/ for state, next to ~/.dsh/dsh-usage/ from the community usage plugin — while plugins/ is where this one's source happens to sit. Nothing writes to the source tree at runtime, and the test suite redirects $DSH_HOME to a temp dir so running it never touches the real state dir.

Install

The package lives at ~/.dsh/plugins/dsh-deepseek-cost and is linked into the web profile's node_modules, with one row in the profile's own patch layer.

# 1. link the package into the profile (a junction keeps one source of truth)
cmd /c mklink /J "$env:USERPROFILE\.dsh\profiles\web\node_modules\dsh-deepseek-cost" "$env:USERPROFILE\.dsh\plugins\dsh-deepseek-cost"

Then ~/.dsh/profiles/web/cordis.patch.yml declares the row:

- insert:
    - id: deepseek-cost
      name: 'dsh-deepseek-cost'

The web profile is patchReload: live, so a running dsh web re-applies this file when it changes; refresh the page and the pill appears. A dsh web restart also picks it up. The host half writes a one-line activation record to ~/.dsh/dsh-deepseek-cost/boot.log on every mount, which is how you confirm it.

Declare the row once. insert appends, so listing dsh-deepseek-cost in both dsh.profile.bundles and the profile patch layer mounts it twice.

The idiomatic alternative

dsh plugin --profile web add <path> is the normal install path — it links the package, appends the name to dsh.profile.bundles, and lets the package's own dsh.bundle.patch own the row. It is blocked on this machine by a pnpm store mismatch:

ERR_PNPM_UNEXPECTED_STORE  node_modules is linked from
C:\Users\wuw\AppData\Local\pnpm\store\v11, pnpm now wants
C:\Users\wuw\.dsh\.pnpm-store\v11

To switch to it, reconcile the store first (pnpm config set store-dir C:\Users\wuw\AppData\Local\pnpm store --global), run pnpm install in ~/.dsh/profiles/web, then remove the row above before running dsh plugin --profile web add.

Tests

cd C:\Users\wuw\.dsh\plugins\dsh-deepseek-cost
node test/fold.test.mjs      # 23 pricing/fold cases
node test/client.test.mjs    # 20 browser-half render/wiring cases
node test/wiring.test.mjs    #  5 host-half + package-resolution cases

fold.test.mjs cases 1 and 2 reproduce two aggregates from a real DeepSeek console ledger (2026-09-10 off-peak, 2026-09-11 peak) to six decimals under the tier in force on those days, which pins the tier table, the peak windows, and the bucket mapping together. Case 2b shows the same token mix one week later priced under the current tier. client.test.mjs drives the bundle through the real window.__ModuleLoader__.load contract and renders the pill and its dialog against a minimal React stand-in, because React is a browser-side static module in DSH and is not installed as a Node package. It asserts the single visible currency mark, the clamped/measure placement, both dismissal paths, the dialog's rows, the absent-projection no-op, the appended 本轮用量 row (including which turn it answers for, its idempotence, and its teardown) — and, as a regression guard for the 0.1.6 breakage, the complete inventory of selectors the bundle evaluates, so the DOM surface cannot grow unnoticed.

Configuration

The price book lives at the top of lib/index.js (FLASH_TIERS, PRO_TIERS, PRICE_BOOK, OFFICIAL_PROVIDERS). Add a tier for a new model id, or a new { from, ... } entry when DeepSeek changes rates. stateVersion must be bumped whenever the fold's meaning changes, so persisted projection checkpoints are discarded instead of forward-applied — it is at 2, the version that added the per-turn ledger; a version-1 checkpoint also fails the state schema, so it is replayed from the session log either way.