dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Live DeepSeek balance and per-hour token costing for DSH: two agent tools read the live balance and the ledger-observed daily charge, then write Markdown/HTML/JSON statements.
English | 中文
DeepSeek Harness(DSH)的实时 token 账单插件:实时账户余额、当日真实消费、按小时归集的 token 用量与金额柱状图,以及可归档的 Markdown / HTML / JSON 账单。
两个面向模型的工具,不需要任何界面,也不需要额外常驻进程:
token_status — 实时余额、今日账本实扣、今日 token 分桶。token_bill — 按小时柱状图、峰谷拆分、分时段明细表,并写出账单文件。📊 2026-09-28 token 账单
余额 ¥52.9100 · 今日消耗 ¥4.6900(账本实扣)
Token 合计 79.65M(输入 1.02M · 缓存命中 78.14M · 输出 492.7K) · 缓存命中率 98.1% · 716 次调用
最忙时段 15:00(29.00M tokens) · 最贵时段 15:00(¥2.3380)
按小时 token 消耗(6 个时段有用量)
00:00 │█████████▃ │ 9.89M
01:00 │███████▂ │ 7.72M
11:00 │██▆ │ 2.92M
12:00 │██████████████▇ │ 15.80M
13:00 │█████████████▄ │ 14.33M
15:00 │██████████████████████████│ 29.00M
按小时金额(已按账本实扣校准)
00:00 │██████▃ │ 0.5607
01:00 │██▅ │ 0.2259
...
DSH 有意把 token 数当作度量而不是账单:ctx.tokenMeter 只提供请求压力快照,整个 harness 里没有任何一处把 token 换算成钱,也完全不内置价目表。而你真想要的三个数字散落在三个互不相通的地方:
| 数据 | 位置 | 权威性 |
|---|---|---|
| 账户余额 | GET https://api.deepseek.com/user/balance(API key 鉴权) | 实时、权威 |
| 当日真实消费 | $DSH_HOME/.dshw-usage.json 余额记账本 | 已观测、权威 |
| 各时段 token 用量 | $DSH_HOME/sessions/**/session.v*.jsonl.zstd | 服务商上报、精确 |
本插件用一条规则把它们对齐:钱以观测为准,token 以计数为准。 当日金额取自账户自身的余额变动,价目表只用来把这份已观测的总额分摊到各小时。
inputTokens、cacheReadTokens、cacheWriteTokens、outputTokens),不是按字符数的启发式估算。sum(小时金额) === 当日金额 是恒等式,而不是四舍五入的巧合。# 已发布到 registry 后
dsh plugin --profile web add dsh-token-bill
# 从本地目录安装
dsh plugin --profile web add link:/绝对路径/dsh-token-bill
安装后,新会话即可让模型使用上面两个工具。若你的 profile 不会自动重载组合,请随后重启 DSH web 服务。
环境要求:Node ≥ 22.12(插件通过 require(esm) 解析 DSH 的 peer 依赖),以及挂载了 tools 服务的 DSH profile(任意标准 Web profile 均可)。
当日真实消费来自 $DSH_HOME/.dshw-usage.json。这个文件由优秀的 dsh-whale-widget 余额挂件写入,不是本插件写的。每个日期行记录期初余额、最后观测余额,以及累计的借(消费)与贷(充值):
{
"openingUnits": 760000000,
"lastUnits": 5525000000,
"debitUnits": 388000000,
"creditUnits": 5000000000,
"firstAt": 1790529962822,
"lastAt": 1790580387568
}
金额是整数 1e-8 元单位。已观测消费只统计余额下降,所以充值只累加到 creditUnits,永远不会虚增你的消费。如果该行同时能对上账(期初 − 消费 + 充值 = 期末),充值会作为说明信息给出;如果对不上,说明有账本无法归类的余额变动,插件会直接说明,而不是悄悄报一个错数字。
如果你没有装那个挂件,账本不存在,插件会干净地退化为按价目表估算并明确标注为估算 —— 余额仍然来自实时接口。
token_status| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
includeLedger | boolean | true | 附上账本路径、更新新鲜度与事件条数。 |
includePricing | boolean | false | 附上峰谷价目表。 |
返回 day、balance、currency、balanceSource(api 或 ledger)、balanceStale、todayObserved、todayTokenEstimate、totalTokens、inputTokens、cacheReadTokens、outputTokens、calls、ledgerPath、text。
token_bill| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
day | string | 今天 | 账期,YYYY-MM-DD,北京时间。 |
days | integer | 1 | 同时给出最近 N 天的按日汇总。 |
costMode | ledger | token | both | ledger | 见金额口径。 |
write | boolean | true | 是否把账单写到磁盘。 |
formats | html | md | json 数组 | ["html","md"] | 写出哪些账单文件。 |
返回 day、amount、amountSource(ledger 或 token-estimate)、currency、balance、totalTokens、calls、activeHourCount、peakTokens、valleyTokens、files,以及完整的 text 文本账单。
账单写出到 $DSH_HOME/token-bill/,文件名为 token-bill-<day>.{html,md,json}。宿主进程的工作目录就是 DSH 安装目录本身,所以默认值刻意不取 process.cwd();可用 DSH_TOKEN_BILL_DIR 环境变量或配置项 outDir 覆盖。
api.deepseek.com/user/balance ──► 实时余额 ──┐
├──► 报告 ──► 柱状图 + 账单
$DSH_HOME/.dshw-usage.json ─────► 已观测 ¥ ──┤
$DSH_HOME/sessions/**/*.zstd ───► 精确 token ─┘
余额 —— GET https://api.deepseek.com/user/balance,请求头 Authorization: Bearer <DEEPSEEK_API_KEY>,返回 balance_infos[],每币种含 total_balance / granted_balance / topped_up_balance。这不需要浏览器登录态。API key 依次从 DEEPSEEK_API_KEY(以及 DSH_DEEPSEEK_API_KEY、DEEPSEEK_KEY)环境变量,或 $DSH_HOME/.credentials.yaml 里的 refs.DEEPSEEK_API_KEY 读取。
token 用量 —— 每条持久化的 assistant/message 事件都同时带着适配器上报的 usage 和毫秒级 time,后者正是按小时归集得以成立的前提。四个桶严格按服务商口径互不重叠:
inputTokens —— 未命中缓存的输入(cache miss)cacheReadTokens —— 命中缓存的输入(cache hit)cacheWriteTokens —— 写入缓存的输入outputTokens —— 输出,reasoning 已包含在内会话日志位于 $DSH_HOME/sessions/<projectKey>/<sessionId>/,文件名 session.v<generation>.jsonl.zstd,首行是 header,之后每次追加写成一个独立的校验 Zstandard 帧。更早的未压缩 session.v<generation>.jsonl 同样可读。
costMode 决定金额数字的来源:
| 模式 | 当日金额 | 小时金额 | token 估算 列 |
|---|---|---|---|
ledger(默认) | 账本观测到的实扣 | 按 token 分摊并校准到该总额 | 显示 |
token | 价目表估算 | 价目表估算 | 不适用 |
both | 账本观测到的实扣 | 按 token 分摊并校准到该总额 | 显示 |
ledger 模式下,小时金额采用按账单自身精度的最大余额法分摊,因此账单打印出来的各小时金额之和,永远等于它打印出来的当日总额。当账本当天没有观测时,插件退化为价目表估算并如实标注 —— 它绝不会把估算当作实扣呈现。
北京时间。高峰(标准价)适用于周一至周五 09:00–12:00、14:00–18:00。其余所有小时,加上全部周末与法定节假日,按谷价(高峰价的一半)计费。价格为「元 / 百万 token」,下表为 谷价 / 峰价:
| 模型 | 缓存命中 | 缓存未命中 | 输出 |
|---|---|---|---|
deepseek-flash、deepseek-v4-flash、deepseek-v4-flash-vision-exp、deepseek-chat | 0.02 / 0.04 | 1 / 2 | 4 / 8 |
deepseek-pro、deepseek-v4-pro、deepseek-reasoner | 0.15 / 0.3 | 4.5 / 9 | 13.5 / 27 |
无法识别的模型名会回落到 Flash 系列计价,这样新模型上线时仍能给出可用的估算。法定节假日表(HOLIDAYS_2026,34 天)在 lib/pricing.mjs,新一年国务院放假安排公布后可通过配置扩充。
在 profile 的 cordis.patch.yml 里给插件那一行加 config:
- id: token-bill
name: dsh-token-bill
config:
costMode: ledger # ledger | token | both
decimals: 4 # 打印金额的小数位
chartWidth: 26 # 终端柱状图宽度
historyDays: 1 # 按日汇总包含的天数
writeFiles: true # 设为 false 则永不写账单文件
timeoutMs: 10000 # 实时余额请求超时
outDir: !!js dshHomePath('token-bill')
sessionsRoot: !!js dshHomePath('sessions')
# 覆盖或扩充价目表(元 / 百万 token):
# models:
# my-model: { hit: { off: 0.01, peak: 0.02 }, miss: { off: 1, peak: 2 }, out: { off: 4, peak: 8 } }
# 追加法定节假日(全天谷价):
# holidays: ['2027-01-01']
| 字段 | 默认 | 说明 |
|---|---|---|
dshHome | $DSH_HOME 或 ~/.dsh | DSH 主目录。 |
profile | $DSH_PROFILE 或 web | 同时检查哪个 profile 目录下的账本副本。 |
sessionsRoot | <dshHome>/sessions | 会话日志根目录。 |
outDir | $DSH_TOKEN_BILL_DIR 或 <dshHome>/token-bill | 账单输出目录。 |
decimals | 4 | 打印金额的小数位。 |
chartWidth | 26 | 终端柱状图宽度。 |
costMode | ledger | 金额来源,见上。 |
historyDays | 1 | 按日汇总包含的天数。 |
maxBytes | 134217728(128 MB) | 超过此大小的单个会话日志会被跳过。 |
timeoutMs | 10000 | 余额请求超时。 |
writeFiles | true | 是否允许写出账单文件。 |
models | 内置价目表 | 价目表覆盖。 |
holidays | HOLIDAYS_2026 | 全天按谷价计费的法定节假日日期。 |
lib/index.js 插件入口:name / inject / Config / apply,注册两个工具
lib/service.mjs 编排:解析配置 → 采集 → 折叠 → 生成报告 → 落盘
lib/account.mjs API key 解析、余额接口、实时到账本的降级策略
lib/ledger.mjs 只读读取 $DSH_HOME/.dshw-usage.json
lib/logs.mjs 会话枚举、多帧 zstd 解码、按小时/按日折叠
lib/pricing.mjs 峰谷时段判定与 DeepSeek 价目表
lib/money.mjs 精确十进制金额(整数 1e-8 单位)
lib/report.mjs 报告装配、终端柱状图、HTML 账单
lib/markdown.mjs Markdown 账单
lib/chart.mjs 终端柱状图
几个值得说明的实现决定:
zstdDecompressSync 只解第一帧且不返回消耗字节数,直接读会把日志悄悄截断成一行 header。decodeZstdFrames() 按帧魔数定位并逐片验证解码;末尾被截断的那一帧直接结束扫描 —— 对于一份正在被写入的日志,这正是想要的行为。全部数据留在本地。唯一的网络请求是向 api.deepseek.com 查询余额,用你自己的 API key 鉴权,由 DSH 宿主进程直接发出。账单写在 $DSH_HOME/token-bill/ 下。不会上传任何数据给插件作者,插件也不含任何遥测。
node test/unit.mjs # 21 项纯函数测试:金额精度、峰谷时段、zstd 多帧、账本行
node test/report.mjs # 8 项报告层测试:分摊恒等式、精度网格、HTML 转义
node test/smoke.mjs # 对真实账本 / 余额接口 / 会话日志跑端到端
node test/verify.mjs # 走真实 execute(),校验输出 schema 与 HTML 结构
npm test 只跑三个不依赖外部数据的单测集(docs、unit、report)。smoke 与 verify 会读取你真实的 DSH 数据,并把账单写到包内的 .dsh-token-bill/(已 gitignore),因此需要一个可用的 DSH 主目录,且建议在源码检出处运行 —— test/ 不在发布包内(files 只发布 lib/、patch、两份 README 与许可证)。
token_status 的新鲜度取决于日志与账本,而非瞬时值。models 配置。MIT。