DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-deepseek-cost-watch

W

dsh-deepseek-cost-watch

Manifest valid

DeepSeek off-peak alert, account balance and live Session cost estimate for the DeepSeek Harness Web UI

UI (client)hasBundlePatch

dsh-deepseek-cost-watch

A DeepSeek Harness profile bundle that puts the DeepSeek off-peak schedule, the remaining account balance, and a live cost estimate into the Web UI.

It replaces two throw-away dynamic plugins with one permanent, installable package: no bundler, no build step, no dependencies, two small JavaScript files.


What it does

1. Off-peak badge (frame-wide overlay)

A floating card in the bottom-right corner of the app:

┌─────────────────────────────────────┐
│ ● DeepSeek off-peak              –  │
│ [−50%]  Discount active             │
│ Ends in 1h 42m 07s                  │
│ Balance                     $8.28   │
│ ─────────────────────────────────── │
│ Peak UTC: Mon–Fri 01:00–04:00 ·     │
│           06:00–10:00               │
│ Local time (UTC+02:00):             │
│           03:00–06:00 · 08:00–12:00 │
│ Outside those windows every model   │
│ costs half.                         │
└─────────────────────────────────────┘
  • Live state — green (−50%) during off-peak, amber (PEAK) during peak hours, refreshed once a second.
  • Countdown to the next peak/off-peak flip.
  • Balance — the credit left on the DeepSeek account, straight from the official GET /user/balance endpoint. Hover for the granted / topped-up split and the read time; click the row to refresh it on the spot.
  • Schedule in both zones — the fixed UTC windows plus the same windows shifted into your browser's timezone, including the (+1d) marker when a window crosses midnight locally.
  • Collapsible — press to shrink it into a PEAK · 18m 04s / OFF-PEAK −50% pill; click the pill to expand it again.

2. Cost estimate (under the composer)

Beside the shipped token counter, above the composer:

  • Collapsed: a coloured dot plus the estimated spend for the open Session — ● ≈ $0.1414. Green means the request you are about to make is billed off-peak, amber means peak.
  • Expanded (click): the full breakdown, in normal page flow, so nothing overlaps the composer or the badge:
Estimated total                     $0.1414
Balance                              $8.28
Peak (01-04, 06-10 UTC, Mon-Fri)   $0.1414 · 5.95M tok
Off-peak                            $0.00 · 0 tok
Uncached input                     114.46k tok
Cache read (hit)                   5.77M tok
Output                             60.35k tok
Model                    DeepSeek-V4.1-Flash · $0.1414
Right now              peak · changes at 10:00 UTC
Estimate from the official DeepSeek rates (2026-09-15): cache hit /
cache miss / output, with off-peak at half the peak rate. Not a billed amount.

The estimate is history-aware: every billed request in the Session log is priced with the card that was in force when that request happened, so a Session that spans a tier change is split correctly between peak and off-peak instead of being priced entirely at today's rate.

3. Balance

The same figure the DeepSeek platform shows on its top-up page, without leaving the app:

  • Read by the Host, never by the browser: the API key stays in the Host process and is sent only to api.deepseek.com.
  • Resolved exactly like the model route does — the stored credential (DEEPSEEK_API_KEY, the ref the Models page writes) and, failing that, the launching environment.
  • Refreshed once on plugin activation, every 5 minutes, and on demand when you click the row. The Host caches an answer for 60 seconds, so several browser tabs never multiply the calls.
  • Degrades instead of breaking: no credential renders no API key, an unreachable API renders unavailable, and both explain themselves in the tooltip. Low credit (is_available: false) turns the amount amber.

Requirements

  • DeepSeek Harness with the web profile (a version that ships dsh plugin and dsh.bundle profile bundles — 0.1.5-rc or later).
  • pnpm on PATH (dsh plugin forwards to it).
  • git on PATH when installing from GitHub.

Install

From GitHub:

dsh plugin --profile web add github:Webificio/dsh-deepseek-cost-watch

From a local checkout (after replacing owner/repo with your own fork, the same command works against your fork):

dsh plugin --profile web add /absolute/path/to/dsh-deepseek-cost-watch

Either command installs the package into the web profile and appends it to dsh.profile.bundles automatically (the package declares dsh.bundle.patch, so dsh plugin recognises it as a profile layer).

Then restart the profile — a bundle is composed at profile boot, so stop the running dsh web and start it again:

dsh web

Reload the browser page. You should see the off-peak card in the bottom-right corner, and the cost line appear in the composer dock as soon as the open Session has billed at least one request.

Verify the install

cat "${DSH_HOME:-$HOME/.dsh}/profiles/web/package.json"

dsh-deepseek-cost-watch must appear in dsh.profile.bundles. If it does not, the plugin was installed as a plain dependency; re-run the add command and read pnpm's output.

Uninstall

dsh plugin --profile web remove dsh-deepseek-cost-watch

Restart the profile afterwards. Both occupants and both Host routes disappear with the package.


How it works

One profile row, two halves of the same package:

| Half | Entry | What it contributes | | --- | --- | --- | | Host | lib/host.js (main) | Two read-only Fetch routes on the Connection carrier: GET /api/deepseek-cost-watch/report?sessionId=… (folds the live Session log into a cost estimate) and GET /api/deepseek-cost-watch/balance (reads the account credit with the stored key). | | Browser | lib/client.js (exports["./client"]) | A Cordis client plugin claiming two slots: shell.overlay (the badge with the balance row) and conversation.composer.dock (the cost line). |

browser (client.js)                    host (host.js)
────────────────────                   ──────────────
shell.overlay       ─┐
  off-peak badge      │  in-process: local peak/off-peak math (no round trip)
  balance row         │
conversation.        ─┤
  composer.dock       │
  cost line  ─────────┤ fetch ─────────▶ GET /api/deepseek-cost-watch/report
                                        │   ctx.sessions.get(id).snapshotEvents()
                                        │   → foldUsage() → JSON
                      └ fetch ─────────▶ GET /api/deepseek-cost-watch/balance
                                            ctx.credentials.resolve('DEEPSEEK_API_KEY')
                                            → api.deepseek.com/user/balance → JSON

The fold lives on the Host on purpose: only the Session log records when each request was billed, while the browser's tokenUsage projection carries aggregate token totals with no timestamps. The balance is read on the Host for a different reason: the API key must never reach the browser. The overlay's live clock needs no Host round trip at all, so it recomputes locally every second from the published schedule.

Everything the plugin registers — both Fetch routes, the stylesheet, the balance poll, and both Slot occupants — is owned by the plugin's fiber, so stopping, updating, or removing the package withdraws all of it.

Files

dsh-deepseek-cost-watch/
├── package.json        # name, exports, dsh.bundle.patch, dsh.client.platform
├── cordis.patch.yml    # the one profile row this bundle inserts
├── lib/host.js         # Host half: rates, schedule, session-log fold, balance, both routes
├── lib/client.js       # Browser half: hand-written module-loader bundle
├── test/smoke.mjs      # dependency-free checks for both halves
├── README.md
└── LICENSE

Balance, credentials and endpoints

| Setting | Default | Where | | --- | --- | --- | | Credential ref | DEEPSEEK_API_KEY | stored credential (Models page) or the launching environment | | API base URL | https://api.deepseek.com | DEEPSEEK_BASE_URL, the same variable the model adapter reads | | Balance endpoint | GET /user/balance | — | | Host cache | 60 s | BALANCE_TTL_MS in lib/host.js | | Browser poll | 5 min, plus click-to-refresh | BALANCE_REFRESH_MS in lib/client.js |

The key is used for exactly one request: Authorization: Bearer <key> against the configured base URL. It is never logged, never returned by the route, and never sent to the browser.


Prices, and how to update them

The rate tables live at the top of lib/host.js as USD per 1,000,000 tokens, written [off-peak, peak] per bucket (cache hit, cache miss, output):

export const RATE_TABLES = [
  {
    id: 'deepseek-flash',
    name: 'DeepSeek-V4.1-Flash',
    models: ['deepseek-flash', 'deepseek-v4-flash'],
    cacheHit: [0.003, 0.006],
    cacheMiss: [0.15, 0.3],
    output: [0.6, 1.2],
  },
]
  • RATE_AS_OF and RATE_SOURCE are printed in the expanded panel, so a stale table is visible in the UI rather than silent.
  • Update the numbers when DeepSeek publishes new pricing, then restart the profile.
  • Only deepseek-official routes are priced. Anything else is counted and reported as unpriced rather than guessed at.
  • The schedule (PEAK_WINDOWS) is UTC: Monday–Friday 01:00–04:00 and 06:00–10:00, with off-peak at half price at every other hour.
  • The number shown is an estimate, not an invoice: it uses the list price of the configured model, while credits, discounts, or a provider-side price change are invisible to it.

Development

There is no build step. Edit lib/host.js or lib/client.js and restart the profile.

npm test        # node test/smoke.mjs — no dependencies

The smoke test prices a synthetic Session log across both rate cards, exercises the report route (200 / 400 / 404), drives the balance route against a stubbed DeepSeek API (success, cache, ?refresh, HTTP error, unreachable, missing credential), then loads the browser bundle with a stub module loader and asserts that it registers the module id, claims both Slot occupants, injects the stylesheet, polls the balance, and renders the badge with the remaining credit.

lib/client.js is a hand-written bundle in the Harness's client module-loader format (window.__ModuleLoader__.load({ id, factory })), which is why the package needs no bundler. Two details are load-bearing:

  • the registered module id must equal the package name in package.json, and
  • the bundle must stay self-contained — React comes from the runtime's module table (require('react')), and nothing else is imported.

Limitations

  • The cost line appears only for Sessions the Host still holds in memory, i.e. the conversation you have open. Cold or archived Sessions are not re-read from disk.
  • The estimate covers billed assistant requests in the Session log; subagent Sessions are priced in their own conversation.
  • The browser half targets the Web profile (dsh.client.platform: "web"); TUI and headless profiles load the Host routes only.
  • The balance needs outbound network access to the DeepSeek API from the Host process; behind a proxy, set DEEPSEEK_BASE_URL to the reachable origin. When it cannot be read, the row says so and the rest of the plugin keeps working.
  • The balance is the account's credit, not a per-Session figure, and it is only as fresh as its last read (5 minutes, or one click).

License

MIT — see LICENSE.

Comments

Loading…

Similar plugins

dsh-agent-pricing

by Way2LOose4

Real-time session cost preview for DeepSeek Harness: live cost readout, today usage chart, price_estimate/session_cost tools, prices kept in sync with the DeepSeek official site (peak/off-peak aware)

Manifest valid

3

MIT

JavaScript

Aug 14, 2026

dsh plugin --profile web add dsh-agent-pricing

by LucienLL

DeepSeek Harness plugin: peak/off-peak price watch, live account balance with tiered low-balance alerts, and a top-up button for the main web UI

Models & ProvidersManifest valid

0

MIT

JavaScript

Aug 26, 2026

dsh plugin --profile web add dsh-peak-price-panel

by Ghost011118

DeepSeek account balance and session cost readout for the DeepSeek Harness Web GUI

Tools & CapabilitiesModels & ProvidersManifest valid

18

152/wk

BSD-3-Clause

JavaScript

Aug 20, 2026

dsh plugin --profile web add dsh-balance-meter

by davidgereb

Cost overview, peak/off-peak hours indicator, balance on dashboard, off-peak scheduling for DeepSeek Harness.

Manifest valid

0

MIT

JavaScript

Aug 21, 2026

dsh plugin --profile web add dsh-plugin-cost-lens

by TwotwoPiggy

dsh余额插件. A DeepSeek Harness plugin for real-time token tracking and highly accurate session cost estimation, featuring dynamic peak/off-peak pricing support.

Tools & CapabilitiesModels & ProvidersManifest valid

12

JavaScript

Sep 9, 2026

dsh plugin --profile web add dsh-balance

by Saikel-Orado-Liu

Cost tracking plugin for the DeepSeek Harness Web GUI — snapshot-anchored per-turn pricing, account balance, and live cost estimates.

Manifest valid

3

418/wk

MIT

TypeScript

Sep 10, 2026

dsh plugin --profile web add @gamegeek-saikel/dsh-cost-meter