Introduction¶
The Web client of DeepSeek Harness (DSH) provides an official stats row. This plugin merges “Session API Cost” and “Account Balance” into a pill placed in the official stats row. Clicking the pill expands a details panel to view amounts by time period, account balance, per-model breakdowns, and pricing sources.
Core Features¶
- Zero visual invention: every value and style in the pill and panel (color tokens, font size, spacing, border radius, hover state) is copied item by item from the official source code.
- Pure slot placement: the plugin uses the
conversation.composer.docklist slot and pins it to the far right of the row viaordersorting, without relying on DOM relocation. - Uses the official projection seam: on the host side, it registers a
costPillunit inctx.sessionProjections; on the browser side, it reads it viauseProjection('costPill'). - Online pricing refresh with a gate: at startup, pricing is refreshed in the background from the official pricing page, with TTL caching, multiple validations, and offline fallback.
- Subagent costs included: the entire subagent tree is collected based on
parentSession/originin the session header and priced together with the main session. - Zero model-visible surface: no prompts or model calls are injected.
Installation and Enablement¶
- Install the plugin:
dsh plugin --profile web add dsh-cost-pill
- Restart
dsh weband perform a hard refresh in the browser (Ctrl+Shift+R). - Open any session. A pill appears in the official stats row (for example:
Cost ¥2.033 · Balance ¥105.82 · Hit 99.5%). It is not displayed when the session has no billing samples. - Uninstall command:
dsh plugin --profile web remove dsh-cost-pill
Configuration¶
The plugin supports configuration in the profile’s cordis.patch.yml.
1. Override Pricing Table¶
Use the pricing section to override the pricing table; it takes precedence over built-in pricing:
- id: cost-pill
config:
pricing:
deepseek-flash: # 键 = 模型 id
offpeak: { input: 1, cacheRead: 0.02, cacheWrite: 1, output: 4 }
peak: { input: 2, cacheRead: 0.04, cacheWrite: 2, output: 8 }
acme/mystery-1: # 也可写完整 provider/model
input: 3
output: 6
Pricing selection order: exact full provider/model match → exact model id match → longest prefix match.
2. Enable Balance Display¶
Use the balance section to enable balance queries:
- id: cost-pill
config:
balance:
enabled: true # false 则完全不注册余额路由
lowThreshold: 10 # 低于该值标红
cacheMs: 120000 # 宿主侧 TTL 缓存
timeoutMs: 15000 # 上游超时
3. Online Pricing Refresh¶
Use the pricingRefresh section to control online refresh behavior:
- id: cost-pill
config:
pricingRefresh:
enabled: true # false = 只用内置价目,完全不联网
ttlMs: 86400000 # 缓存存活时间(默认 24 小时)
timeoutMs: 15000 # 单次抓取超时
url: 'https://api-docs.deepseek.com/zh-cn/quick_start/pricing/'
cachePath: '' # 默认 $DSH_HOME/storages/dsh-cost-pill-pricing.json
Billing and Data¶
- Data source: Only the
usagereported by the provider in theassistant/messageevent is recognized. - Subagent aggregation: On the host side, the derived tree is collected based on
parentSession/origin: 'subagent'in the session header, priced per session with the same collapse logic, and then merged. - Balance data path: The host registers a loopback-only exact route
/api/cost-pill/balanceand retrieves data using the provider’s account interface. The browser only receives the balance number; the API Key always remains in the host process.
Notes and Limitations¶
- No historical segmentation across price adjustments: all historical samples are recalculated using the current pricing table.
- Lag in online refresh: the projection registry is recalculated only when events are committed; the refresh is reflected in the next billing sample.
- Amounts are estimates: they are not bills; relay channels, contract discounts, etc., cannot be inferred from session tokens.
- Subagent discovery mechanism: it relies on logs under the
$DSH_HOME/sessionsdirectory and theparentSessionheader field. - Panel anchoring method: it uses
position: absoluterelative to the pill, instead of the official fixed + viewport-edge reflow. - Icon drawing: the icons are custom inline SVGs, to safely merge into the official row.
- Client limitation: rendered only in the Web interface; TUI/other clients do not have this slot.