stopperino/dsh-routerai-usage ↗★ 0

dsh-routerai-usage

RouterAI balance and per-request cost for the DeepSeek Harness Web UI: account balance plus what the current session really spent, subagents included. 使用RouterAI服务的用户必备,便于实时监控和分析每个会话的Token开销。

Package
dsh-routerai-usage
Compatibility
Unverified
Version
1.0.0
License
MIT
Last updated
Oct 24, 2026

Install

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:stopperino/dsh-routerai-usage

dsh-routerai-usage

Balance and per-request cost for RouterAI inside the DeepSeek Harness Web UI.

Shows the account balance plus what the current session has actually spent — including every subagent the session spawned — under the composer, with a hover panel breaking the spend down by provider and by model.

505,14 ₽   ◎ 147,04 ₽

Hover the figure to see the breakdown:

◈ routerai                                    505,14 ₽
всего 147,04 ₽ · 848 запросов
в т.ч. субагенты: 33,35 ₽ · 222 запроса
По провайдеру
  byteplus                       822 запроса · 141,27 ₽
По модели
  deepseek-v4.1-flash            848 запросов · 147,04 ₽

Why the cost is exact

RouterAI bills through a routed provider, which does not follow the public list price. For deepseek/deepseek-v4.1-flash the real charge was measured at a constant 2.793× the list-price estimate. A plugin that multiplies tokens by list prices is therefore wrong by a factor of ~3, so this one asks RouterAI for the settled amount instead:

GET https://routerai.ru/api/v1/generation?id=   →   data.total_cost   (rubles)

The generation id comes from the Harness session log itself (assistant/message → message.source.replayState.response.responseId), so no request has to be intercepted or replayed.

Traffic

Every settled charge is cached by generation id. A generation id names one immutable, already-billed request, so its cost never changes and the cache can never go stale. Reopening a session that is already cached costs no upstream request at all — measured: 848 rows resolved in ~12 ms, versus ~4 s and hundreds of requests when cold.

The cache stores only generationId → rubles. No tokens, no models, no prompts, no session content. It is written atomically and is ignored if unreadable.

Install


## Configuration

The row accepts these options in `cordis.patch.yml`:

```yaml
- id: routerai-usage
  name: dsh-routerai-usage
  config:
    pollSeconds: 30                          # balance refresh interval
    baseURL: https://routerai.ru/api/v1      # API root