READMESource: main@65910e6b
简介
- 锚点而非读数:平台结算滞后 1~5 分钟,照抄读数会出现「干活时数字不动」。每次读数只当周期锚点,显示的是
锚点 − k × 本机已消耗,所以数字随 token 实时递减。 - 用量时钟:在
T取得的读数只反映T − settlementLagMs之前的用量,因此本地累计从那个截止时刻起算;不做这个位移,最后几分钟会被重复扣除。 - 分档计价 + 单一校正系数:按官方高峰价分档(缓存命中 / 未命中 / 输出),再用近期余额下降的中位数学一个标量
k,把过期价目表、未收录的模型、统一折扣一并吸收。 - 只累加下降:充值抬高钱包但不贡献任何数,所以不污染
k、不作废校准窗口;成块结算只计一次。没有本地用量的大额下降单列为「非用量调整」,不算你的花费。 - 峰谷按发生时刻判:高峰 = 北京时间周一至周五 09:00–12:00、14:00–18:00(不含法定节假日),其余时段半价;
ETA跨时段积分,否则 17:50 起算会漏掉 18:00 开始的半价,偏小最多 2×。 - 可被数据推翻的日历假设:调休补班日按官方字面口径算空闲;跨越它的样本进独立探针,与主系数稳定相差约两倍时面板给出提示,不自动改配置。
- 输入框下方的读数 pill:紧跟宿主自带的 token 统计,显示预估余额与可用时长,点开是明细面板。
host 半独占凭据与出网,只把一份快照经两条精确路由交给浏览器半:凭据从不进入浏览器,两条路由也都参与宿主的 Host/Origin 与 cookie 信任围栏。出网只有两个目标——余额端点,以及你显式启用时的节假日源。
安装
要求:DeepSeek Harness ≥ 0.2.0-rc.1,Node ^22.19.0 || >=24.0.0。
从 npm 装(推荐):
dsh plugin --profile <profile> add @zzxxxxxx/dsh-balance
从源码装 / 本地开发:
git clone https://github.com/zzzxxxxxxxxxx/dsh-balance && cd dsh-balance
npm install # 构建依赖,首次需要网络
npm run build # 产出 lib/(插件入口;仓库里不提交构建产物)
dsh plugin --profile <profile> add "$PWD"
从打好的 tarball 装(npm pack 的产物已含 lib/,无需构建):
dsh plugin --profile <profile> add ./zzxxxxxx-dsh-balance-0.1.0.tgz
装完后重启 dsh(profile 在启动时组合)。
- API Key 取自凭据引用
DEEPSEEK_API_KEY,与内置deepseek-officialprovider 是同一个引用——模型能用就说明它已配好;也可在 设置 → 模型、$DSH_HOME/.credentials.yaml或导出环境变量里设置。 - 更新:源码装则
git pull && npm install && npm run build,tarball 装则重新add一次。之后都要重启。 - 卸载:
dsh plugin --profile <p> remove @zzxxxxxx/dsh-balance,再重启。 - 浏览器半边(读数 pill)只在带 Web 界面的 profile 里出现;其他 profile 下 host 半照常轮询,只是没人看。
- ⚠️ npm 上无 scope 的
dsh-balance是另一个同类插件,请按 scope 安装。 - 开发:
npm run typecheck、npm test(87 个用例,不访问网络)、npm run build、npm run gen:holidays(重新生成节假日种子,唯一会真实出网的一步)。
用法
- pill:显示
¥36.35 · 2 天 4 小时——预估余额与估算可用时长。状态点平时绿,低于etaWarnMs转橙,低于etaCriticalMs或余额耗尽转红,未标定或连不上时灰。 - 面板:点 pill 向上展开,把三个数字分开呈现——平台读数、本机推算已消耗、当前预估余额——另有当前时段与下次切换、消耗速率及其来源、今日与最近一小时、非用量调整、校正系数与候选数、节假日日历来源。
- 立即刷新:面板右下角的按钮请 host 立刻轮询平台一次,再重读快照。
- 没有斜杠命令,也没有设置页:本插件只做读数,配置见下节。
- 服务端只有两条路径:
GET /dsh-balance/state(快照)与POST /dsh-balance/refresh(请求一次轮询)。
配置
全部字段都写在插件行的 config: 里(本插件没有设置页),改完需重启。下面是完整的默认值:
- insert:
- id: dsh-balance
name: '@zzxxxxxx/dsh-balance'
config:
apiKeyEnv: DEEPSEEK_API_KEY
apiOrigin: https://api.deepseek.com
balancePath: /user/balance
refreshIntervalMs: 60000 # 轮询平台的周期
requestTimeoutMs: 10000
settlementLagMs: 300000 # 平台读数滞后于用量的上界
rateWindowMs: 1800000 # 瞬时消耗速率的观测窗口
calibrationWindowMs: 21600000 # 校正系数 k 的学习窗口
correctionSamples: 9 # k 取中位数的近期候选数
probeSamples: 5 # 给出日历建议所需的探针数
retentionMs: 604800000
staleAfterMs: 180000
etaCapMs: 31536000000
minBurnPerHour: 0.01
minPredictedSpend: 0.01 # 量化步长,也是「大额下降」阈值
preferredCurrency: auto # auto | CNY | USD
priceCurrency: CNY
priceTable: # 高峰价,单位「币种 / 百万 token」
deepseek-flash: { input: 1, cacheRead: 0.02, output: 4 }
deepseek-v4-pro: { input: 4.5, cacheRead: 0.15, output: 13.5 }
offPeakFactor: 0.5
peakDays: [1, 2, 3, 4, 5]
peakWindows: ['09:00-12:00', '14:00-18:00']
priceTimeZone: Asia/Shanghai
holidays: [] # ['2027-01-01', ...]
makeupWorkdays: [] # ['2027-02-20', ...]
treatMakeupWorkdaysAsPeak: false
holidaySourceEnabled: false # 第二个出网目标,默认关闭
holidaySourceUrl: https://timor.tech/api/holiday/year/{year}
holidaySourceFormat: auto # auto | timor | holiday-cn
holidayRefreshIntervalMs: 604800000
holidayMissingYearRetryMs: 86400000
holidayTimeoutMs: 8000
weights: { uncachedInput: 1, cacheWrite: 1, cacheRead: 0.1, output: 4 }
etaIntegratesSchedule: true
etaWarnMs: 86400000
etaCriticalMs: 14400000
clientPollIntervalMs: 15000
persist: true
historyRoot: ''
allowLoopbackHttp: false
| 字段 | 默认 | 说明 |
|---|---|---|
apiKeyEnv |
DEEPSEEK_API_KEY |
取 API Key 的凭据引用(环境变量名) |
apiOrigin |
https://api.deepseek.com |
余额端点 origin;必须 https(loopback 例外) |
balancePath |
/user/balance |
余额端点路径 |
refreshIntervalMs |
60000 |
轮询平台的周期 |
requestTimeoutMs |
10000 |
单次余额请求超时 |
settlementLagMs |
300000 |
平台读数滞后于用量的上界;本地累计从此前移起算 |
rateWindowMs |
1800000 |
瞬时消耗速率的观测窗口 |
calibrationWindowMs |
21600000 |
校正系数 k 的学习窗口 |
correctionSamples |
9 |
取中位数的近期候选数 |
probeSamples |
5 |
给出日历建议所需的探针样本数 |
retentionMs |
604800000 |
读数与 token 桶的保留时长(7 天) |
staleAfterMs |
180000 |
多久没有新读数就把快照标为过期 |
etaCapMs |
31536000000 |
可用时长上限,超过显示 > 1 年 |
minBurnPerHour |
0.01 |
低于此速率视为闲置,不报 ETA |
minPredictedSpend |
0.01 |
量化步长;也是「大额下降」的判定阈值 |
preferredCurrency |
auto |
钱包偏好:auto 优先有余额的 CNY,其次 USD |
priceCurrency |
CNY |
价目表计价币种;与钱包不一致时退出价目表路径 |
priceTable |
deepseek-flash deepseek-v4-pro |
各路由的高峰价,单位「币种 / 百万 token」 |
offPeakFactor |
0.5 |
空闲时段相对高峰的倍率 |
peakDays |
[1,2,3,4,5] |
承载高峰时段的 ISO 星期 |
peakWindows |
09:00-12:00 14:00-18:00 |
高峰时段 |
priceTimeZone |
Asia/Shanghai |
高峰时段所用的时区 |
holidays |
[] |
法定节假日(YYYY-MM-DD),优先级最高 |
makeupWorkdays |
[] |
调休补班日,同样最高优先级 |
treatMakeupWorkdaysAsPeak |
false |
调休补班日是否按高峰计价 |
holidaySourceEnabled |
false |
是否启用远程节假日源 |
holidaySourceUrl |
timor.tech |
远程源 URL 模板,必须含 {year} |
holidaySourceFormat |
auto |
远程载荷结构:auto / timor / holiday-cn |
holidayRefreshIntervalMs |
604800000 |
远程源正常刷新周期 |
holidayMissingYearRetryMs |
86400000 |
当年日历尚未发布时的重试周期 |
holidayTimeoutMs |
8000 |
远程源请求超时 |
weights |
1 / 1 / 0.1 / 4 |
价目表未覆盖路由的相对权重 |
etaIntegratesSchedule |
true |
ETA 是否跨峰谷切换积分 |
etaWarnMs |
86400000 |
低于此可用时长状态点转橙 |
etaCriticalMs |
14400000 |
低于此转红 |
clientPollIntervalMs |
15000 |
浏览器读取快照的周期 |
persist |
true |
是否把读数与 token 桶落盘到 $DSH_HOME/dsh-balance/ |
historyRoot |
'' |
落盘目录覆盖,空表示用默认目录 |
allowLoopbackHttp |
false |
是否允许 http 的 loopback 端点(本地开发用) |
几条语义:
- 平台滞后与 ETA:ETA 的分子来自锚点,唯一残差是分子本身滞后,所以它恰好偏小
settlementLagMs(默认 5 分钟以内),不会随滞后漂移。 - 充值与用量撞在同一个轮询间隔:那一对读数净上升,隐藏的用量看不见——有界(≤ 一个间隔的花费),并被中位数摊薄。面板上的「非用量调整」只统计没有本地用量解释的大额下降。
- 校正系数需要几笔下降才稳定:在此之前速率退化为按余额差(6 小时窗口)估算,状态点转灰、面板标注「未标定」。价目表准的时候
k会在1.0附近——它本身就是最好的自检。 - 每个会话的第一轮不计入:首次观测只用来播种基线,否则恢复会话会把整段历史重新计费。
- 路由来自投影,不是会话事件:
session/event按 scope 过滤,挂在 profile 层的插件收不到request/context,所以模型是从modelSelection投影主动拉取的(对加载前就已固定的选择,变化事件永远不会触发)。 - 价目表币种必须与钱包一致(默认 CNY):不一致时退出价目表路径、按
weights计价,并在面板标出。 - 节假日日历需要年度维护:开
holidaySourceEnabled,或在新一年公布后重跑npm run gen:holidays重新生成种子。未发布的年份按未知处理(绝不记成「无节假日」——那会把整年工作日按高峰计价且不再重试),重试周期缩短为每天,并在面板提示。 - 调休日口径是对官方散文的解读:高峰的前置条件是「周一至周五」,而调休日按构造就是周六/周日,故默认算空闲;因为这是解读而非实测,才用探针把它变成可被数据推翻的假设,且提示不会自动改配置。
- 两条路由参与宿主信任围栏:自定义 host 路由不会自动进入闸门,所以本插件主动请求裁决(Host/Origin + cookie);
connection是必需注入,缺了插件就不加载,围栏不会静默失效——代价是服务短暂不可用时返回503,而不是不带围栏地照常作答。 - 本插件仍在早期,可能还有 bug。遇到问题请到 Issues 反馈,并附上面板上的读数与
$DSH_HOME/dsh-balance/history.json——它记录了读数与 token 桶,比截图清楚得多。
No comments yet. Be the first to write one.