dsh-gateway-billing · Per-Conversation Model Billing Display
What is this
A per-conversation model billing display skill. Generalized from an internal gateway-billing dashboard, it shows the running cost of the current conversation's model calls right below the DSH Web composer — for anyone self-hosting an LLM gateway that exposes a New API / One API-compatible /pricing endpoint.
Core Capabilities
| Module | Content |
|---|---|
| Pricing fetch | Fetches a New API / One API-format price table from your configured gateway URL, auto-refreshing every 10 minutes |
| Dual billing modes | Supports both token-based pricing (quota_type=0) and fixed per-call pricing (quota_type=1) |
| Per-conversation folding | Walks every model-call node in the current conversation and folds usage (input/output/cache tokens) against the price table |
| Composer dock display | One-line entry: 💰 total cost · most recent model×calls · input/output/cache tokens; multi-model conversations expand to per-model rows |
| Distinct not-configured / failed states | An unconfigured pricing URL and a failed fetch (network error, etc.) render different messages; the former has no "click to retry" — retrying can't fix a missing config |
| Unpriced-model surfacing | A model call with no matching price-table entry is counted and highlighted separately, never silently treated as $0 |
Install
Via profile (recommended)
# 1. Clone the repo
git clone https://github.com/LeslieWylie/dsh-gateway-billing.git ~/Desktop/01-Projects/dsh-gateway-billing
# 2. Add to your profile
cd ~/.dsh/profiles/<your-profile>
# Edit package.json: add to dependencies:
# "dsh-gateway-billing": "link:~/Desktop/01-Projects/dsh-gateway-billing"
# 3. Edit cordis.patch.yml, add an entry pointing at your own gateway's pricing endpoint:
# - id: gateway-billing
# name: 'dsh-gateway-billing'
# config:
# pricingUrl: 'https://your-gateway.example.com/api/pricing'
# 4. Install
pnpm install
# 5. Restart dshVia dsh plugin add (once published to npm)
dsh plugin add dsh-gateway-billingRequired Configuration
This skill requires a config block on its own gateway-billing entry in your profile's cordis.patch.yml:
| Config | Description | Example |
|---|---|---|
pricingUrl | Your gateway's pricing endpoint. Must return New API / One API-format {data: [{model_name, quota_type, model_ratio, completion_ratio, model_price}, ...]} | https://your-gateway.example.com/api/pricing |
Without pricingUrl set, the composer dock clearly shows "not configured" — it never errors out or displays a misleading cost figure.
Design Principles
- Gateway-agnostic: no gateway URL is baked in; the price table source is entirely user-configured
- Failure is visible: a failed fetch and a missing config are distinct states with distinct messages — neither is swallowed silently
- Fetch once, read many: the price table refreshes and caches server-side every 10 minutes; the composer dock reads a snapshot over RPC rather than re-fetching per conversation
Sanitization Notice
This plugin was generalized from an internal gateway-billing dashboard. The original implementation hardcoded its pricing endpoint in source and had no "not configured" state — sanitization turned the endpoint into a required config.pricingUrl and added the distinct not-configured/failed rendering. All internal institution names and internal gateway domains have been removed.
Changelog
See [CHANGELOG.md](CHANGELOG.md).
License
MIT