Multi-platform LLM balance and quota panel: configure DeepSeek, OpenRouter, Kimi, Zhipu GLM, MiniMax, NewApi or custom endpoints, poll on a schedule, draw balance and quota trend charts, and push threshold and window-reset notices through multiple channels.
Install
# from npm (prebuilt)
dsh plugin --profile web add @mzzsfy/dsh-usage-panel
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:mzzsfy/dsh-plugin#path:/packages/dsh-usage-panel
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
This plugin publishes its README in Chinese only.
DeepSeek Harness 双端插件:在「设置 → 账号余额」手动配置多组(上限 20 个)LLM 平台账号(API 地址 + Key),定期自动查询并展示每个账号的余额、额度与历史趋势;刷新评估越过逻辑点(用量阈值穿越 / 余额阈值穿越 / 额度窗口重置)时,经 webhook、dsh-im、页内 toast 三通道推送通知。无自动发现;配置持久化在本机 ~/.dsh/dsh-usage-panel/accounts.json,查询快照留存于同目录 history.json。
安装
dsh plugin --profile web add @mzzsfy/dsh-usage-panel
--profile 必填;本包为 web 平台向,建议 web profile。
或手动把以下条目加入 ~/.dsh/profiles/web/cordis.patch.yml 的 insert 列表(勿写入 profile 根 cordis.yml——该文件每次启动会被重写,手动行会静默丢失):
- insert:
- id: usage-panel
name: '@mzzsfy/dsh-usage-panel'
支持的平台
| 类型 | 默认地址 | 查询接口 | 展示 |
|---|---|---|---|
deepseek |
https://api.deepseek.com |
GET /user/balance |
各币种余额 + 可用性 |
openrouter |
https://openrouter.ai |
GET /api/v1/credits |
剩余/总额/已用(USD) |
kimi |
https://api.kimi.com/coding |
GET /v1/usages |
5小时/7天窗口进度条 |
zhipu |
https://open.bigmodel.cn |
GET /api/monitor/usage/quota/limit |
5小时/7天进度条;兼容 v3 CREDIT_LIMIT |
minimax |
https://api.minimaxi.com |
GET /v1/api/openplatform/coding_plan/remains |
5小时/7天进度条 |
newapi |
需填写站点地址 | GET {站点}/api/usage/token |
quota/500000 换算 USD |
custom |
需填写完整 URL | 任意 HTTP 端点 | 按 extract 规则提取 |
预设类型均可用「API 基础地址」覆盖默认(如中转站),Key 按平台要求以 Authorization: Bearer <key>(智谱为裸 key)发送。
读数展示
- 额度窗口(5小时/7天)渲染为进度条,绿/橙/红三档(70%/90% 阈值);余额账户有已用/总额时同样渲染
- 鼠标悬停读数行显示明细:余/总额、已用、赠送、充值、重置时间、账户可用性
- 卡片头部:账号名 + 平台类型徽章 + 套餐档位徽章(智谱
data.level/ Kimi membership)
定期查询与趋势(v2)
- 定期查询:时间驱动调度——全账号统一每 10 分钟查询一次(余额阈值等通知最长延迟约 10 分钟);上次尝试查询时刻随配置持久化,宿主重启后调度无缝衔接。定时轮询为软依赖:宿主 timer 服务不可用时仅停用自动轮询,面板显示降级提示,手动查询与全部配置能力不受影响
- 失败退避:单账号失败按指数退避(基期 = 统一查询间隔,×2 封顶 8 倍),成功即恢复。退避与到点判定独立叠加,二者皆过才发起查询。面板打开触发的自动查询同样受退避约束,手动刷新不受限
- 历史快照:按序列分档落盘
history.json(5 小时滚动 → 10 分钟粒度留 7 天;7 天 / 月 / 余额 → 小时粒度留 30 天),档内去重,超期修剪,硬点数上限兜底;删除账号时其历史序列同步清理 - 趋势视图:悬浮账号卡片弹出 sparkline(自绘 SVG),短 / 长窗口独立成图,绝对值 / 差值双视角;「详情」对话框可切时间范围(长窗口 / 月 / 余额:近 7 天 / 30 天 / 全部;5 小时短窗口仅近 7 天 / 全部),含区间摘要与明细表
- 历史文件解析失败时自动备份为
history.json.bak并暂停写入(防空数据覆盖);history.json被移除或恢复为可解析内容后自动恢复写入,.bak是损坏前的最后数据,删除前请确认不再需要。accounts.json同构守卫:损坏时备份为accounts.json.bak并拒绝一切写入(防账号 Key 被空配置覆盖),恢复后解除 - 月窗口序列
月由 host 侧按当月余额快照聚合产出
通知(v3)
刷新(自动轮询与手动查询)本身不是通知类型,而是评估时机:每次查询成功后评估读数,越过逻辑点才触发一个事件,通知关闭时评估短路零成本。
通知类型与沿触发
| 类型 | 触发逻辑点 | 防抖 |
|---|---|---|
| 用量阈值 | 窗口利用率上穿阈值(全局默认 90%,账号可覆盖) | 沿触发:触发一次即解除武装,窗口重置后恢复 |
| 余额阈值 | 可用余额下穿阈值(数值即启用,留空不评估;口径 remaining 优先、缺失回落 total,币种随读数) | 沿触发:充值回升到阈值上方后恢复武装 |
| 窗口重置 | 额度窗口 resetsAt 轮转(5小时/7天等) |
每窗口生命周期一次,内容为上一窗口峰值利用率 |
沿触发状态与窗口峰值基线随账号持久化在 accounts.json,宿主重启不重发。
规则模型
- 全局规则(host settings
usage-panel命名空间的notify键,面板与 settings.yaml 等价,热生效):
usage-panel:
notify:
enabled: false # 总开关,默认关闭
quotaThresholdPct: 90 # 用量窗口阈值百分比,(0,100]
balanceThreshold: null # 余额阈值,null 为不启用
resetNotice: true # 窗口重置时通知上一窗口峰值
toast: true # 页内 toast 通道
webhookUrl: '' # webhook 目标 URL,留空禁用;面板原文回显
imTargets: [] # dsh-im 投递目标 [{botId, targetId}]
- 账号覆盖:账号表单「通知规则覆盖」折叠区,仅
quotaThresholdPct/balanceThreshold/resetNotice三字段,字段级合并,留空继承全局;通道配置全局统一。
通知通道
- webhook:host 直发(Slack-compatible
{text}+ 结构化字段),超时 10 秒不重试,fire-and-forget;面板「保存并测试」返回真实投递结果 - dsh-im:安装 @xmanrui/dsh-im 后自动启用,面板粘贴 Bot ID 加载其已保存投递目标目录,勾选即自动保存;支持绑定多个 bot,已绑 bot 以标签展示,点标签加载该 bot 目录,× 一键取消注册(移除该 bot 全部目标);触发逻辑与 webhook 完全一致(fire-and-forget 不重试);目标的新建与平台测试仍在 dsh-im 设置页完成,此处仅选择;「测试 IM」逐目标返回真实结果
- 页内 toast:host 内存投影(环形 20 条 / 60 秒过期,version 单调递增),浏览器半区长轮询挂起等待增量并经公共依赖
@mzzsfy/dsh-toast展示(语义与 turn-notify 同构);localStorage 单元级认领锁保证多窗口只弹一次。toast 依赖由 session-manager 插件代挂,未安装 session-manager 时此通道静默不可用,其余通道不受影响
通知接口
GET /api/usage-panel/notifications:通知投影长轮询;cursor缺省=首拉立即返回全量,cursor等于当前版本时挂起至事件或超时,落后或超前(宿主重启版本回退)立即返回全量,客户端以响应 version 重置游标自愈;响应{units, version}GET|POST /api/usage-panel/notify-config:全局通知规则;webhookUrl原文随响应回显POST /api/usage-panel/test-webhook/POST /api/usage-panel/test-im:测试投递,返回真实结果GET /api/usage-panel/im-targets?botId=:列出 dsh-im 该 bot 已保存投递目标
全部路由统一经守卫样板:POST 带同源守卫(Origin 与 Host 不符 403)与 JSON content-type 校验(text/plain 等简单请求 400),阻断跨站 drive-by 改写账号配置(含注入指向攻击者端点的账号)、通知配置或借测试通道外发;非 GET/POST 方法一律 405;已知边界同 turn-notify:同源守卫不防 DNS rebinding,该暴露面属 host webserver 全部 /api 路由的存量问题,应在 host 层统一解决。
custom 提取规则
extract 是 JSON 对象,remaining 必填;读数按余额(balance)形态呈现并参与余额阈值通知、余额历史序列与月窗口聚合。取值支持四种形式:
- 点路径字符串:
"data.total_available" - 数字常量:
42 - 运算对象:
{"op": "add" | "subtract", "paths": ["a.b", "c"]}、{"op": "divide", "path": "a.b", "by": 500000} - 混合:
maxBudget/spend可选,unit指定币种(默认 USD)
数值提取为严格模式:空串/null/布尔/千分位字符串均视为提取失败,不会伪造成 0。
custom 端点支持自定义请求方法(GET/POST/PUT/DELETE/PATCH)、请求头(JSON)与请求体(非 GET 可选),并提供 NewApi 示例一键填入。
架构与依赖
- Host 半区(
src/index.js):Node ESM,fetch直连平台 API(超时 20s),通过webServer服务暴露/api/usage-panel/*路由(accounts / query / history / settings / notifications / notify-config / test-webhook / test-im / im-targets);需要 DSH 提供webServer服务与settings服务(通知规则持久化);timer服务(定期轮询)为软依赖,缺失时仅停用自动轮询 - Client 半区(
src/client.js):DSH client-modules 自注册格式(__ModuleLoader__.load),注册settings.section槽位;需要slots服务与react18;@mzzsfy/dsh-toast可选消费(动态 require,模块表缺失即页内通道停用,操作反馈降级console.warn) - 纯逻辑层(
src/parsers.mjs/src/poller.mjs/src/history.mjs/src/historyStore.mjs/src/notify.mjs):无 IO 数据变换,npm test覆盖解析、时间驱动调度与退避、快照留存、持久化守卫与规则合并 / 沿触发评估 / 投影认领 / 配置校验;趋势图 SVG 点位算法内联于 client.js(唯一实现)
安全提示
账号 Key 以明文保存在 ~/.dsh/dsh-usage-panel/accounts.json,注意不要分享该文件;Key 只存在与使用于宿主进程,任何接口响应都不回传 Key(仅带 hasKey 标志,保存时空值表示保持不变)。路由访问控制由 DSH web 鉴权层统一负责。
已知取舍
- spark / feebar 视图组件的前端渲染逻辑以内联方式维护,未做 host/client 双端 parity 测试,属已知技术债务(点位算法纯客户端消费,单一实现无漂移面)
- 早期版本允许无
id的账号(落盘时按索引一次性补齐);当前前端保存时总携带id,不再做旧数据特判 - 账号卡片渲染未做 memo 化、趋势浮层常挂载:数据规模受账号上限(20)与悬浮窗口点数(24)双重钳制,无可感知卡顿,后置观察
开发安装(仓库工作副本直挂,不经 npm 发布)
node scripts/dev-link.mjs dsh-usage-panel # 仓库根执行:归一 profile 依赖行 + 挂 junction
工作副本以 junction 挂进 profile,改代码保存即热重载(host 半区)或刷新页面生效(client 半区),无需发版;规约与全仓归一见仓库根 node scripts/dev-link.mjs all。
dsh 版本兼容
三版本全部通过:用量面板渲染、激活 live。
Links
More in this category
bowenliang123/dsh-context★ 1429
DSH context insight panel: Context dashboard + /context command + Context browser — one-stop context lifecycle management with categorized composition, content details, evolution trends, compaction/injection events, and stats.
Han-1413141/dsh-cost-meter★ 310
Per-session and daily API cost, budget with usage %, official balance, history dashboard, and one-click official price sync with peak/off-peak pricing.
zh667/TokenLedger★ 201
Sidebar usage panel that attributes tokens to the relay site that served each request, read from your existing provider config: today/month/all-time totals, per-site and per-model breakdowns, a year activity heatmap, and New API / Sub2API / DeepSeek balances.
wssfk12138/dsh-damage-pulse★ 180
Tracks DeepSeek token usage, per-call and session costs, and account balance with cache-aware charge animations in the DSH Web UI.
Ychris12138/dsh-usage-stats★ 159
Multi-provider usage dashboard with provider/model token breakdowns, calendar drill-downs, account balances, and OpenCode Go / Z.ai subscription quota tracking.
PolinniZhong/dsh-personal-center★ 120
Personal center for DeepSeek Harness: cross-session usage statistics, per-model cost estimation, global custom instructions, a global font-size adjuster, a data-driven desktop pet with bitmap & vector skins, and a conversation status overview, all local and offline.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.