Skip to content

Repository files navigation

omdsh-usage

English | 中文

What this conversation cost, what this project has cost, and what is left on the account — three figures in the row of the DeepSeek Harness web GUI you are already reading.

 Help   ⚙ Code mode   💬 0.023 ¥   📁 1.03 ¥   👛 964.15 ¥          Files  Terminal

In Chat and Work the badge sits in the session header, immediately right of the Chat Mode / Code mode chip. In Code the whole conversation column is a terminal and there is no header to sit in, so it moves to the opposite corner, just left of Files. (Files and Terminal at that end of the row belong to omdsh-sidepanel, not to this plugin; they are drawn here because they are what the corner has to sit inboard of.)

Under a configurable floor — 10 by default, in whatever currency the account is denominated in — all three icons turn red, and so they do when the provider reports the account itself unavailable, whatever the figure beside it says. Red therefore means two things rather than one. Above the floor nothing is tinted at all, and a balance that could not be read is not an alarm either: no key stored, or a network blip, leaves every icon its ordinary colour and puts the reason in the tooltip.

What it adds

Surface Where it comes from
The three-figure badge in the session header conversation.session.header.actions, ui-conversation's action row
The same badge in the frame's corner, whenever nothing is drawing a header shell.overlay, ui-layout's frame-wide floating layer
The omdshUsage per-model token fold sessionProjections.register — a projection unit the harness drives once per committed event and checkpoints
GET /omdsh-usage/summary webServer, behind the same browser-trust check the /api gateway applies
The omdsh-usage settings namespace settings.register, which is the whole of what the plugin hub needs to render this plugin a configuration page

The figures

Readout What it is
Session Every model call in the conversation on screen, priced.
Project The same, summed over every conversation whose working directory is this one.
Balance What the provider says is left on the account, in the provider's own currency.

Hover any of them for the tokens behind it, the directory a project total is for, how much of the balance is promotional credit, or — when a figure is missing — why.

Prices are yours to state

The shipped rate table is a placeholder. The harness carries no prices, and no rate for deepseek-v4-flash or deepseek-v4-pro is knowable from this plugin; the defaults are DeepSeek's published list rates, seeded so the badge shows a number on the first run rather than a dash. Replace them with the numbers on your own invoice, in Settings → Plugins → OMDSH Plugins → Usage. The namespace holds this shape — the panel renders it as a form rather than as text, and a deployment that wants to state its own rates writes the same shape into its profile's cordis.yml:

omdsh-usage:
  currency: CNY
  rates:
    default: 0.5/2/8            # <cache hit>/<cache miss>/<output>, per MILLION tokens
    deepseek-v4-flash: 0.5/2/8
    deepseek-v4-pro: 1/4/16
  lowBalance: 10

Every field is live: a repriced table reaches the next poll, a few seconds later, with nothing to restart.

Field Meaning
currency CNY or USD. The two spend figures are stated in it and the rates are read in it. The balance always reports the provider's own currency.
rates One line per model, "<cache hit>/<cache miss>/<output>" per million tokens. The default row prices any model the table does not list. A key may be a bare model id or a full provider/model.
lowBalance The floor under which all three icons turn red.
apiKeyEnv Which stored credential the balance call uses — the credential's name, not the key. Defaults to DEEPSEEK_API_KEY.
baseURL Where the balance is read from. Point it at the same gateway your model requests use.

A rate line that is not three non-negative numbers is refused at the moment it is written, rather than stored and failed on afterwards.

How it works

Almost none of the accounting is this plugin's. The session log already records provider usage on every assembled assistant message, and the harness's projection seam already folds and checkpoints per-session state. So:

  • The fold is a projection unit. omdshUsage accumulates billed tokens per provider/model over the complete durable log. The harness drives it once per committed event and checkpoints it, so the figures survive paging, compaction, and restarts — and a conversation using two models is priced at two rates rather than one blended average.
  • "This project" is the checkpoint table. Every session's checkpoint is stored with its working directory, so a project total is a read of a few kilobytes of JSON rather than a walk through a directory of compressed logs.
  • The balance is one provider call, behind the credential seam, cached for a minute and shared across every open tab.
  • The money is computed on the host. The browser receives numbers to format and never a rate to multiply, so there is one implementation of the arithmetic and a stale page cannot render spend at last week's prices.

Two seats, both slots the harness already publishes: conversation.session.header.actions for the header, and shell.overlay for the understudy that holds the row's place when nothing is drawing one. The understudy decides its corner by measuring the frame — if the conversation column still holds a session header it takes the leading corner, and if something else has taken the column it takes the trailing one, inboard of whatever furniture is already there.

What it does without

Every service either half injects — webServer, webRuntime, sessions, and sessionProjections on the host, slots, sessions, and locale in the page — is the harness's own, and both seats are taken through slots.inject. So no other plugin in this collection is a precondition: a profile carrying only this one boots, and the badge is there. What is missing is reported rather than waited for.

  • No credential store, or no key in it. The two spend figures are unaffected; the balance is a dash and its tooltip says which of the two it was.
  • No session persistence or projection cache. The project total covers the conversations this host has open rather than every conversation that ever ran in the directory.
  • No omdsh-code. Code mode is what replaces the conversation column with a terminal, and the trailing corner exists for that. Without it the header is always there to hold the badge, and the understudy only ever stands in for a blank conversation. Which corner is a measurement of the frame either way — nothing here asks who is installed.

Install

dsh plugin --profile web add @omdsh-plugins/omdsh-usage

Or from a checkout, which is what an unpublished build wants:

pnpm install && pnpm run build   # a local checkout never runs `prepare` — build it yourself first
dsh plugin --profile web add /path/to/omdsh-usage
dsh web

Nothing else. The balance is read with the DEEPSEEK_API_KEY the harness already holds for model requests, so there is no second key to store — and if no key is stored, the two spend figures still work and the balance says why it is absent.

Remove it the same way:

dsh plugin --profile web remove @omdsh-plugins/omdsh-usage

Both halves go with it, and the header row closes back over the seat. Nothing in this collection is a precondition in either direction — see what it does without for what each absence costs.

Commands

pnpm install
pnpm run build
pnpm run typecheck
pnpm run test

The committed manifest pins the published harness. To build against a sibling checkout instead:

pnpm run harness:local ../../deepseek-harness   # that checkout must be built first
pnpm install
pnpm run harness:npm                            # before committing — a link: is one machine's layout
pnpm run check:harness-pin

Every spec runs from a bare clone on the committed pin: the pure modules import the harness type-only, and the two that need a snapshot store are handed one rather than importing the browser bundle a test runner cannot load.

Known limitations

  • Conversations older than this plugin have no per-model fold, because nothing was folding one when they ran. They fall back to the harness's own tokenUsage projection and are priced at the default row. The tooltip says when a figure includes an estimate. Without this fallback a project total would read as "you have spent almost nothing here", which is a worse error.
  • Cold conversations lag by up to a turn. A checkpoint is written at turn/end; the conversation on screen is live and is recomputed on every poll.
  • Cache writes are billed as cache misses. DeepSeek prices them that way and its adapter reports no separate bucket; a provider that charged separately would be priced conservatively.

About

API spend at a glance for the DeepSeek Harness web GUI: this conversation, this project, and the account balance, beside the mode chip in Chat and Work and in the corner in Code

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages