← Back to home@averyzhoux

dsh-session-balance

⚖️ Quietly to display the balance.

Stars
0
Language
JavaScript
Created
Oct 5, 2026
Updated
Oct 5, 2026
GitHub repo

Introduction

dsh-session-balance

DSH Web GUI 的会话余额插件:在会话标题栏右侧(conversation.session.header.utilities)显示一个余额徽标,点开后展示 DeepSeek 账户余额、当前会话 token 用量、上下文占用和费用估算。

  • 账户余额:调用 DeepSeek GET /user/balance,展示总额、充值余额、赠送余额与是否可用。
  • 会话用量:读取会话投影 tokenUsage(未缓存输入 / 缓存读取 / 缓存写入 / 输出)与 sessionStats(轮次 / 步骤 / 模型耗时)。
  • 上下文:读取 contextPressure,显示已用 / 窗口 token 与占用百分比。
  • 费用估算:按当前模型单价(modelSelection 投影)在浏览器本地换算为 CNY(元) 估算值。

全程只读:插件不会修改会话、不会发起模型请求,也不会把 API Key 返回给浏览器。


界面

折叠态(标题栏):

◉ ¥110.00 · 12.3K tok · ~¥0.05

展开态面板分四段:账户余额、当前会话、上下文、费用估算。


安装

插件以「宿主插件 + 浏览器插件」两半组成,安装到正在使用 dsh web 的 profile(默认 web)。

1. 把包加入 profile

dsh plugin --profile web add link:/home/eimber/桌面/dev/x/dsh-session-balance
  • link: 直接软链到本目录,改代码后重启 dsh web 即生效,适合本地开发。
  • 想固定副本用 file:/home/eimber/桌面/dev/x/dsh-session-balance。
  • 发布到 npm 后可直接 add dsh-session-balance。

2. 在 profile 里挂载插件行

编辑 ~/.dsh/profiles/web/cordis.patch.yml,加入(该文件默认是 [],把内容替换为下面内容即可):

- insert:
    - id: session-balance
      name: 'dsh-session-balance'
      # 需要覆盖默认配置时写在这里,例如:
      # config:
      #   rate: peak
      #   refreshMs: 30000

也可以走 bundle 方式:把 dsh-session-balance 加进 ~/.dsh/profiles/web/package.json 的 dsh.profile.bundles,本包自带的 cordis.patch.yml 会自动插入插件行;此时配置覆盖写在 cordis.patch.yml 的 - id: session-balance 条目下。

3. 重启并验证

dsh web

刷新 GUI(http://127.0.0.1:3080 )后,会话标题栏右侧应出现余额徽标。若徽标未出现,见下方「排查」。

4. 配置 API Key

账户余额需要一个可用的 DeepSeek API Key,解析顺序由 DSH 凭据层决定:

  1. 启动环境变量 DEEPSEEK_API_KEY(只读,优先级最高)
  2. ~/.dsh/.credentials.yaml 中的 DEEPSEEK_API_KEY(可在「模型设置」页保存)
  3. 项目 .env
  4. ~/.dsh/.env

Key 只在宿主进程内使用,不会写入前端响应。


配置参考

所有字段都可选,写入插件行(或 bundle 方式下的 - id: session-balance)的 config:

字段默认值说明
balanceEnabledtrue关闭后不再请求余额接口,徽标只显示本地用量与费用
apiKeyEnvDEEPSEEK_API_KEY凭据引用名
baseURL$DEEPSEEK_BASE_URL → https://api.deepseek.comDeepSeek API 基址(兼容 OpenAI 网关)
timeoutMs10000余额请求超时
cacheMs60000宿主侧余额缓存时长;前端自然刷新不会穿透缓存
refreshMs60000前端轮询间隔;0 表示只加载一次
rateoff-peakoff-peak 空闲时段 / peak 高峰时段;高峰按 ×2 计算
currencyCNY费用估算计价币种;仅影响单价表与费用显示(账户余额用它自己的币种)
pricing见下模型单价覆盖表,单位 元 / 1M tokens,按空闲时段基准,高峰时统一 ×2
showBalancetrue折叠态 / 面板是否显示账户余额
showTokenstrue是否显示 token 用量
showCosttrue是否显示费用估算
showContexttrue是否显示上下文占用

如果你在 dsh-llm-deepseek 里配了自定义 baseURL(自建网关),请在这里填同一个值,否则余额会去官方端点查询。

默认单价(元 / 1M tokens,空闲时段)

模型缓存命中输入缓存未命中输入输出
deepseek-flash0.0214
deepseek-v4-flash0.0214
deepseek-v4-flash-vision-exp0.0214
deepseek-v4-pro0.154.513.5

单价来自 DeepSeek 官方定价页(中文),会随时间调整;插件内置值只是默认,请按需覆盖:

config:
  rate: peak
  currency: CNY
  pricing:
    deepseek-v4-pro:
      cacheHitInput: 0.3
      cacheMissInput: 9
      cacheWriteInput: 9   # 可省略,默认等于缓存未命中输入
      output: 27

pricing 表里的数值按空闲时段基准填写,rate: peak 时程序会统一 ×2,因此无需手填高峰价。 未配置单价的模型只显示 token 数与上下文,不显示费用。 空闲时段为高峰时段价格的一半:北京时间周一至周五(不含中国法定节假日)9:00–12:00、14:00–18:00 为高峰,其余时段均为空闲。默认按空闲计,因此高峰期会低估,需要保守估计可设 rate: peak。


工作原理

浏览器 (lib/client.js)                        宿主 (lib/index.js)
────────────────────────                      ─────────────────────
conversation.session.header.utilities
  └─ BalanceBadge
      useProjection("tokenUsage")   ←── 会话投影(dsh-token-meter)
      useProjection("contextPressure") ← dsh-token-meter
      useProjection("modelSelection")  ← dsh-api-session-controller
      useProjection("sessionStats")    ← dsh-session-stats
      fetch /dsh-session-balance/api/overview ──► 读取凭据 → GET /user/balance
                                                  返回余额 + 单价表 + 展示开关
  • 会话用量全部来自宿主已有的会话投影,插件不新增任何宿主侧统计。
  • 费用估算发生在浏览器,仅用投影里的累计 token 数和宿主下发的单价表。
  • 余额接口带 TTL 缓存与并发合并(singleflight),轮询不会打爆上游。
  • 路由只接受同源 GET/HEAD,Origin 与 Host 不一致时返回 403。

实现要点

  • 浏览器半是手写的 window.__ModuleLoader__.load(...) bundle,只 require 基线模块表中的 react,因此不需要构建步骤;dsh.client.external 留空。
  • 宿主半不 import 任何 @deepseek-ai/* 包(凭据引用在运行时就是普通字符串,brandString 为恒等函数),所以 link: 安装时真实路径在 profile 之外也能正常解析。
  • 样式通过一次性注入 <style id="dsh-session-balance/styles"> 完成,并复用 DSH 主题变量(--dsw-alias-* / --dsw-specific-menu)以适配明暗主题。

排查

现象原因 / 处理
标题栏没有徽标确认第 2 步的插件行已写入并重启 dsh web;确认包已在 profile 的 node_modules 里(ls ~/.dsh/profiles/web/node_modules/dsh-session-balance)。
徽标显示「未配置 API Key」按上文第 4 步配置 DEEPSEEK_API_KEY。
显示「获取失败」悬停/展开面板看具体错误:HTTP 状态、超时或 baseURL 不可达。
费用显示「未配置该模型单价」在 pricing 里补上当前模型 id(面板「当前会话 → 模型」会显示 id)。
token 一直是 0该会话尚未产生带 usage 的请求;投影由 dsh-token-meter 注册,请在 web composition 中确认该包已启用。
余额与官网不一致官网可能含未结算费用;插件按缓存 TTL 刷新,可在面板点「刷新」强制更新。

卸载

# 1. 删除 cordis.patch.yml 里的 session-balance 条目(或 bundle 方式下从 bundles 移除)
# 2. 移除依赖
dsh plugin --profile web remove dsh-session-balance

兼容性

  • DSH:0.1.5-rc.1(Web composition 含 dsh-token-meter、dsh-session-stats、dsh-api-session-controller)。
  • Node:>=20(宿主使用全局 fetch 与 AbortSignal.timeout)。
  • 浏览器:需要 Intl.NumberFormat、可选链;现代 Chromium/Firefox/Safari 均可。

License

MIT