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 凭据层决定:
- 启动环境变量
DEEPSEEK_API_KEY(只读,优先级最高) ~/.dsh/.credentials.yaml中的DEEPSEEK_API_KEY(可在「模型设置」页保存)- 项目
.env ~/.dsh/.env
Key 只在宿主进程内使用,不会写入前端响应。
配置参考
所有字段都可选,写入插件行(或 bundle 方式下的 - id: session-balance)的 config:
| 字段 | 默认值 | 说明 |
|---|---|---|
balanceEnabled |
true |
关闭后不再请求余额接口,徽标只显示本地用量与费用 |
apiKeyEnv |
DEEPSEEK_API_KEY |
凭据引用名 |
baseURL |
$DEEPSEEK_BASE_URL → https://api.deepseek.com |
DeepSeek API 基址(兼容 OpenAI 网关) |
timeoutMs |
10000 |
余额请求超时 |
cacheMs |
60000 |
宿主侧余额缓存时长;前端自然刷新不会穿透缓存 |
refreshMs |
60000 |
前端轮询间隔;0 表示只加载一次 |
rate |
off-peak |
off-peak 空闲时段 / peak 高峰时段;高峰按 ×2 计算 |
currency |
CNY |
费用估算计价币种;仅影响单价表与费用显示(账户余额用它自己的币种) |
pricing |
见下 | 模型单价覆盖表,单位 元 / 1M tokens,按空闲时段基准,高峰时统一 ×2 |
showBalance |
true |
折叠态 / 面板是否显示账户余额 |
showTokens |
true |
是否显示 token 用量 |
showCost |
true |
是否显示费用估算 |
showContext |
true |
是否显示上下文占用 |
如果你在
dsh-llm-deepseek里配了自定义baseURL(自建网关),请在这里填同一个值,否则余额会去官方端点查询。
默认单价(元 / 1M tokens,空闲时段)
| 模型 | 缓存命中输入 | 缓存未命中输入 | 输出 |
|---|---|---|---|
deepseek-flash |
0.02 | 1 | 4 |
deepseek-v4-flash |
0.02 | 1 | 4 |
deepseek-v4-flash-vision-exp |
0.02 | 1 | 4 |
deepseek-v4-pro |
0.15 | 4.5 | 13.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
No comments yet. Be the first to write one.