Skip to content
dsh.fish
Bundle

dsh-gauge

Accurate cache-hit rate, token usage, and cost estimates for the DeepSeek Harness Web UI: one-decimal hit rate, bucket breakdown, peak/off-peak pricing with auto price-switch, and a session usage panel.

Source
noone89A
stars
4 stars
License
MIT
Updated
Updated 5 days ago

Readme

# dsh-gauge

中文 | [English](README.en.md)

为 DeepSeek Harness Web UI 提供精确缓存命中率、token 用量与费用估算。

官方统计行把缓存命中率四舍五入成整数——`Math.round` 会把 99.8% 显示成误导性的 **100%**。
dsh-gauge 用一位小数(可配置)的精确数值顶替它,并补充分桶 token 明细、会话用量面板,以及自动跟随 DeepSeek 官方调价的会话费用估算(使用官方 API)。

## 功能

- **精确缓存命中率** — `cacheRead / (cacheRead + uncached + cacheWrite)`,小数位可配置(默认 1),99.8% 就是 99.8%。
- **分桶明细** — 命中 / 未命中输入 token 与输出 token。*写入*桶为 0 时自动隐藏(opencode-go/pi-ai 适配器从不报告 cache-write,实际恒为 0)。
- **费用估算 + 调价对比** — 按实际用量 × 模型单价估算(deepseek-v4-flash / deepseek-v4-pro,自动从会话推导)。官方新价生效前显示 **当前费用 + 新价费用 + 预计涨幅**;生效时刻自动切换到新价。
- **按请求时刻的峰谷计价** — 估算**不是**"当前时刻"快照:每条 assistant 消息按自己的时间戳计价,高峰时段消耗的 token 按高峰价、闲时按折扣价,最后求和。
- **高峰时段徽标** — 北京时间 09:00–12:00 / 14:00–18:00 为 DeepSeek 峰谷定价的高峰窗口。统计行尾按当前时段显示**高峰**/**闲时**状态(切换为新价后同样按当前时段显示)。
- **用量面板** — 会话页头 ⓘ 按钮弹出面板:模型、命中率、计费输入、各桶总数(默认完整数字)、上下文占用与费用估算(含调价后对比)。
- **两行统计(官方指标 + 精确用量)** — 第一行保留官方会话指标(轮/步、LLM/工具调用时长、首 token 平均、tok/s),复刻官方样式(行距刻意收紧,两行视为一个整体);第二行是插件的精确用量(命中率、分桶、输出、费用、高峰/闲时徽标)。`replaceNativeStatsLine: false` 时保留官方原生行(含原生用量段)。
- **双语 & 货币自适应** — UI 为英文时文案切英文、费用按国际价目表以 USD 估算。语言与货币实时跟随,无需重启。

## 截图

![统计行](https://raw.githubusercontent.com/noone89A/dsh-gauge/main/docs/images/stats-line.png)
![用量面板](https://raw.githubusercontent.com/noone89A/dsh-gauge/main/docs/images/usage-pane.png)

## 安装

```sh
# 一条命令(推荐):dsh plugin 会 pnpm add,
# 并自动把声明了 dsh.bundle 的包加进 dsh.profile.bundles
dsh plugin --profile web add dsh-gauge

# 手动方式:cd ~/.dsh/profiles/web && npm install dsh-gauge,
# 然后编辑 profiles/web/package.json,把 "dsh-gauge" 加进 dsh.profile.bundles

# 重启
dsh web
```

输入框下方应出现精确统计行,会话页头出现 ⓘ 用量入口。

> **本地开发/调试**:用源码安装替代——`pnpm add file:C:/Object/dsh-plugin/dsh-gauge`(源码改动后 `npm run build` 即生效,适合改 `src/config.ts` 的价格/高峰窗口)。

### 开箱即用 & 配置卡片

装完重启后**开箱即用**,无需任何配置:

- 输入框下方两行统计:精确缓存命中率(99.8% 就是 99.8%)、分桶明细、输出、预估费用、高峰/闲时徽标;
- 会话页头 ⓘ 用量面板:完整 token 数字、上下文占用、模型、费用与调价对比;
- 中英文文案与费用货币自动跟随界面语言。

**设置 → 插件 → 可配置插件**里的 dsh-gauge 配置卡片:由于当前 DSH 版本把可暴露给网页端的插件设置写死在白名单(`dsh-host-apiproxy` 的 `WEB_SETTINGS_NAMESPACES`),第三方插件需一次性把 `gauge` 加入白名单后卡片才会显示(步骤见"故障排查")。**不加入白名单不影响任何核心功能**——不想动白名单时,也可直接编辑 `cordis.patch.yml`(见"配置")。

## 工作原理

- 统计行注册进 `conversation.composer.dock` 槽位。`replaceNativeStatsLine: true`(默认)时以 `priority: -1` 注册进官方 `stats` cell,影子顶替原生行;`false` 时以 `order: 1` 追加为第二行。
- token 总量来自 `tokenUsage` 投影(`@deepseek-ai/dsh-token-meter`);上下文占用来自 `contextPressure`。
- 费用估算翻页拉取**全会话历史**(`sessions.history`):每条已定稿的 assistant 消息自带完成时间与 `usage`,按消息自己的时间戳套高峰/闲时费率(新方案)或平价(当前旧价),再求和——窗口外("加载更早"之前)的历史同样精确计价,不会出现"命中 2 亿 token 费用却只有几毛钱"。
- 当前模型从全量历史的最后一条 assistant 消息推导(`source.model`;无连接面时降级用 trajectory 视图的 `requestConfig.model`),或通过 `model` 配置固定。
- 上下文压缩(compaction)后旧事件被摘要替代:费用与官方 `tokenUsage` 投影基于相同的事件集合,两者保持一致(压缩丢弃的用量官方同样丢弃)。

## 配置

普通用户通常不需要做任何配置——插件开箱即用。以下键可通过官方**设置 → 插件 → 可配置插件**里的 dsh-gauge 卡片可视化开启/调整——**保存后立即生效,无需重启**(唯一例外:`replaceNativeStatsLine` 决定顶替注册,需重启),也可直接写进 `~/.dsh/profiles/web/cordis.patch.yml` 的 `gauge` 行:

| 键 | 默认 | 含义 |
|---|---|---|
| `showPrice` | `true` | 显示费用估算(统计行 + 面板) |
| `showPeakBadge` | `true` | 统计行显示北京高峰时段徽标 |
| `replaceNativeStatsLine` | `true` | 顶替官方统计行(`false` 保留官方原生行) |
| `hitRateDecimals` | `1` | 缓存命中率小数位(0–2) |
| `tokenDecimals` | `1` | K/M 缩写小数位(0–2) |
| `panelExactTokens` | `true` | 面板显示完整 token 总数(`false` 用 K/M 缩写) |
| `currency` | `auto` | `auto` 跟随 UI 语言(English → `$` + USD 价目,其余 → `¥` + CNY 价目);可显式写 `¥` / `$` |
| `model` | `auto` | `auto` 从会话推导模型;或显式写模型 id |

**高级项(开发者)**:高峰窗口 `peakHours`、CNY 价目 `pricePlans`、USD 价目 `usdPricePlans`、新价生效时刻 `nextFrom`、闲时系数 `offPeakFactor` 默认值内置在 `src/config.ts`,普通用户无需也不应在配置文件里改动;需要调整时直接改源码 `src/config.ts` 里的默认常量。

```yaml
# ~/.dsh/profiles/web/cordis.patch.yml — 扁平 loader 补丁条目
- id: gauge
  config:
    showPrice: true
    showPeakBadge: true
    hitRateDecimals: 1
    tokenDecimals: 1
    panelExactTokens: true
    currency: auto
```

**内置价目 & 调价**:当前价(8.17 前,平峰同价)与官方新价(2026-08-17 起,峰谷计价,闲时减半)已内置在 `src/config.ts`(CNY 用 `pricePlans`,USD 用 `usdPricePlans`),费用估算会按每条请求的时刻自动套用高峰/闲时价,并在 `nextFrom` 时刻自动切换到新价。官方价目如有调整,修改 `src/config.ts` 的默认常量即可;官方价目没有单独的"缓存写入"桶。

> 费用为**估算值**,以官方实际账单为准。补丁条目是**扁平** `{id, ...}` loader 条目——没有 `update:`/`disable:` 包装层,写 `- update:` 会被报错拒绝。若**配置卡片**不显示,见"故障排查"的白名单说明。

## 与 dsh-usage 的对比

[`dsh-usage`](https://www.npmjs.com/package/dsh-usage)(v0.1.0)与本插件同一天出现,这里基于源码做客观对比。

| 维度 | dsh-usage | dsh-gauge |
|---|---|---|
| 缓存命中**率**(%) | — 完全没有命中率指标,只有原始缓存 token | 精确命中率,小数位可配置(99.8% 就是 99.8%) |
| 峰谷计价 | — 无峰谷处理;内置价目为 **2026-04-24 的 USD 表**,2026-08-16 调价后费用估算会失真 | 按消息时间戳的峰谷计价、新旧价对比、生效时刻自动切换 |
| 粒度 | 每条 assistant 消息下的 per-turn 读数 + 设置页 **Usage** 页(52 周热力图、provider/模型汇总、跨会话) | 会话级统计行(顶替原生行)+ 页头 ⓘ 面板(模型、分桶、上下文占用、费用) |
| 成本核算 | replay 派生的 `modelCost` 投影、按生效日期计价、unpriced/无 usage 覆盖说明 | `tokenUsage` 投影 × 内置价目表(CNY + USD) |
| 数据源 | 持久日志 replay(跨分页/压缩) | `tokenUsage`/`contextPressure` 投影 |
| 语言 | 仅英文 | 中英双语 |
| 原生行 | 追加自己的行 | 默认**影子顶替**官方行 |
| 写入桶 | 单独计价 | 为 0 时隐藏 |

**总结:** dsh-gauge 是精度/效率仪表——官方 UI 舍掉的精确命中率、高峰时段感知、以及免维护地跟随新峰谷价的实时费用检查。两者**互补**,可共存安装——槽位不同、id 不同、无冲突。

## 故障排查

- **"写入"一直是 0** — 设计如此:一些适配器从不报告 cache-write token,为 0 时隐藏该桶。未来有提供方上报时自动恢复显示。
- **费用看起来不对** — 内置价目表(改 `src/config.ts` 的 `pricePlans`/`usdPricePlans`)或显式设置 `currency`/`model`;费用为估算值,以官方账单为准。
- **改动没反映** — 除 `replaceNativeStatsLine`(决定顶替注册)外,配置保存后**立即生效**;若改动的是 `cordis.patch.yml`,需重启 `dsh web`。
- **设置 → 插件 → 可配置插件 里没有 dsh-gauge 卡片** — 当前 DSH 版本把可暴露给网页端的插件设置写死在 `dsh-host-apiproxy` 的 `WEB_SETTINGS_NAMESPACES` 白名单里(官方注释标注"插件自行声明"为 deferred work),**不在白名单的命名空间即使已注册,describe 也不会返回**,卡片因此不显示。在宿主安装里把 `gauge` 加入白名单后重启 `dsh web`:
  
  ```js
  // <dsh 安装目录>/node_modules/@deepseek-ai/dsh-host-apiproxy/lib/index.js
  const WEB_SETTINGS_NAMESPACES = [
    "agent-loop", "shell", "locale", "permission",
    "ui-conversation", "ui-theme", "web-search-deepseek",
    "gauge", // ← 加这一行
  ];
  ```
  
  不加入白名单**不影响**统计行、面板等核心功能,只是配置卡片不显示(仍可用 `cordis.patch.yml` 配置)。等 DSH 开放插件自注册后此要求自动消失。
- **页面无法启动** — 确认 `lib/client.js` 是打包后的客户端产物(运行 `npm run build`,产出 `__ModuleLoader__.load` 格式;裸 tsc ESM 输出会导致页面白屏)。

## 开发

```sh
pnpm install
pnpm run typecheck
pnpm test
pnpm run build
```

`npm run build` 先用 tsc 编译,再用 `scripts/build-client.mjs` 把客户端入口打包成 DSH client-module loader 格式。

## License

MIT

Install

dsh plugin --profile web add github:noone89A/dsh-gauge

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source