@dsh-external/dsh-deepseek-quota
August 26, 2026 · View on GitHub
一个 DeepSeek Harness bundle
插件:在聊天输入框上方的统计行(1 轮 · 14 步 | LLM … | 缓存命中 …)
正下方,显示一条 DeepSeek 额度行:
峰 | 余额:¥274.70 | 当前会话:¥0.0115 | 本轮对话:¥0.0038 | 子代理:¥0.0011
功能特性
会话额度行
-
注册在
conversation.composer.dock插槽(order 1,紧跟在内置统计行下方), 显示五段内容:- 峰谷:首列显示当前峰谷阶段(当前为高峰时段显示「峰」,低谷时段 显示「谷」;北京时间,含周末全天低谷规则——自 2026-08-23 00:00 起周六/ 周日全天按低谷价)。悬停打开计费规则卡片:价目表版本、峰谷时段、 周末规则与计价方式;其余明细卡片不再重复显示计费规则。
- 余额:DeepSeek 账户总剩余额度(5 分钟轮询)。每次刷新后在括号内显示
与上次刷新的变化量(
余额:¥274.70(-0.05)),余额减少显示红色-,增加显示绿色+;悬停打开多标签明细面板:每 5 分钟(逐次 刷新变化量)、每 1 小时/每 1 天(时间阈值固化——距上次记录 满 1 小时/1 天才固化一条,首行"截至当前"随每次 5 分钟刷新实时更新并 显示距上次固化点的变化),每个视图固定 10 行无滚动条,并显示赠金/充值 信息;明细表的变化量拆分为两列:变化量(总)(账户总余额的变化) 与变化量(当前API)(当前 API 的消耗变化,即该时间窗口内 DSH 所有 会话的 DeepSeek 用量消耗——由宿主端重放全部会话的持久日志、按同一峰谷 价目表计价,同一窗口内变化量(当前API)与变化量(总)的差额即 其他 API 的消耗与充值等非用量变化)。余额快照、三类历史与全局消耗曲线 持久化在浏览器 localStorage,刷新页面后 即时恢复; - 当前会话:整个会话日志累计消耗(跨轮次、跨工具步骤);
- 本轮对话:最新一轮(含该轮全部步骤)的消耗,流式输出期间实时增长;
新的一轮开启但尚无请求时显示
—,不回放上一轮的最终额度; - 子代理:本会话全部持久化后代子代理(含已完成、已冷存的)的累计消耗。
-
数据来自持久日志而非 API:宿主端重放会话事件,折叠提供方上报的用量桶 (未缓存输入 / 缓存读取 / 缓存写入 / 输出,与 token-meter 投影同一套语义), 并按 DeepSeek 官方峰谷分时价目表计价。会话刷新、重启、翻页、压缩后数字不变 ——用量随会话持久化,金额只是对持久数据的即时视图。
-
子代理不会重复计费:子代理日志开头的父会话继承前缀(seed)被跳过, 其用量只统计从
seedLength起的自有事件;非 DeepSeek 模型的子代理不计价。 -
官方峰谷分时定价(2026-08-17 起生效,北京时间,元/百万 tokens): 自 2026-08-23 00:00(北京时间)起,周末(周六/周日)全天不再区分峰谷, 统一按空闲(低谷)时段价格计费;生效前已产生的历史调用仍按原规则计价。
模型 时段 输入(缓存命中) 输入(缓存未命中) 输出 deepseek-chat(V4-Flash)高峰(工作日 09:00–12:00 / 14:00–18:00) 0.10 3.00 9.00 deepseek-chat(V4-Flash)空闲(其余时间,含周末全天) 0.05 1.50 4.50 deepseek-reasoner(V4-Pro)高峰(工作日 09:00–12:00 / 14:00–18:00) 0.30 9.00 27.00 deepseek-reasoner(V4-Pro)空闲(其余时间,含周末全天) 0.15 4.50 13.50 每个请求按请求发生时刻(事件时间戳,换算北京时间)选择高峰/空闲单价; 模型按 id 归入对应档位(
*chat*/*flash*→ V4-Flash,含deepseek-v4-flash-vision-exp;*reasoner*/*pro*→ V4-Pro,未知模型 回退到deepseek-chat档)。价格可通过行配置覆盖。 -
三段分别可悬停查看明细(悬浮面板,随主题样式渲染):
- 悬停当前会话:首列显示当前峰谷阶段(峰/谷,北京时间、含周末 全天低谷规则),其后按模型(Flash / Pro 等档位)细分的额度消耗—— 输入(未命中)、缓存输入、输出三个计费桶各自的折算金额与合计;
- 悬停本轮对话:本轮每一个请求(步骤)的时间、模型(超长截断,悬停 显示完整 id)、输入(未命中)、缓存输入、输出三个计费桶各自的折算金额 与合计(最多同时显示 5 行,超过内部滚动;超过 200 条请求截断显示);
- 悬停子代理:每个子代理的模型、三个计费桶的折算金额与合计;非
DeepSeek 模型的子代理显示
-占位,不计入总额。
-
零运行时依赖;额度计算不调用 DeepSeek API(仅余额段需要 API Key)。
环境要求
- DeepSeek Harness web profile(
dsh web)——该 bundle 只在 web profile 挂载。 - 余额段需要配置 DeepSeek API Key(额度计算不需要):
- Web 界面「设置 > 模型」页,或
~/.dsh/.credentials.yaml(DEEPSEEK_API_KEY),或DEEPSEEK_API_KEY环境变量。
安装
本插件是 bundle 插件:即 npm 包清单中声明了 dsh.bundle,其
cordis.patch.yml 层会被组合进 profile。
从 Git 仓库安装
dsh plugin --profile web add github:ErrorLst/dsh-deepseek-quota
(git+https://github.com/ErrorLst/dsh-deepseek-quota.git 同样有效。)
dsh 0.1.0-rc.7 及以后版本在 dsh plugin add 成功后会自动 reconcile,把声明了
dsh.bundle.patch 的包自动登记进 dsh.profile.bundles,无需手动编辑 profile 的
package.json;仅旧版本 dsh 才需要手动登记。重启 dsh web。
本地目录安装(开发调试)
dsh plugin --profile web add link:C:/path/to/dsh-deepseek-quota
本地开发请用 link:(符号链接)而不是 file::file: 会在安装时把插件
拷贝进 profile 的 node_modules,之后对插件目录的修改不会被 Web 服务读到
(表现为主机端新路由 404、界面没有新功能);link: 让 node_modules 直接指向
插件目录,改动即时可见——宿主端改动重启 dsh web 生效,浏览器端改动刷新页面即可。
rc.7 及以后版本同样会自动 reconcile 登记 bundle 层,无需手动编辑;重启 dsh web 即可。
从 npm 安装(发布后)
dsh plugin --profile web add @dsh-external/dsh-deepseek-quota
卸载
dsh plugin --profile web remove @dsh-external/dsh-deepseek-quota
rc.7 及以后版本会自动 reconcile,从 dsh.profile.bundles 中移除该名称,无需手动
编辑 profile 的 package.json;仅旧版本 dsh 才需要手动移除。
使用
打开 Web 界面:额度行位于聊天输入框上方统计行的正下方。悬停 「当前会话 / 本轮对话 / 子代理」查看明细面板;悬停「余额」查看赠金/充值明细。
也可以直接访问接口:
curl http://127.0.0.1:3080/api/deepseek-quota
curl http://127.0.0.1:3080/api/deepseek-quota?refresh=1
curl "http://127.0.0.1:3080/api/deepseek-quota/context?sessionId=<session-id>"
curl "http://127.0.0.1:3080/api/deepseek-quota/spend?boundaries=<ms1>,<ms2>"
HTTP API
GET /api/deepseek-quota(由宿主编通过 webServer 提供)
// 成功
{
"ok": true,
"isAvailable": true,
"balances": [
{ "currency": "CNY", "total": "123.45", "granted": "10.00", "toppedUp": "113.45" }
],
"fetchedAt": 1735689600000
}
// 失败 — code 取值:
// MISSING_KEY 未配置 API Key
// AUTH DeepSeek 拒绝该 Key(HTTP 401)
// HTTP_<status> 上游其他 HTTP 错误
// TRANSPORT 网络/超时错误
{ "ok": false, "code": "MISSING_KEY", "message": "DEEPSEEK_API_KEY 未配置:…" }
GET /api/deepseek-quota?refresh=1 绕过 TTL 缓存;非 GET 请求返回 405。
GET /api/deepseek-quota/spend?boundaries=<ms1,ms2,…>
跨 所有会话(在线 + 持久化,按 id 去重、子代理种子前缀不重复计费)的
DeepSeek 总消耗曲线:在每一个边界时间戳处返回自全部日志起始的累计消耗
(仅统计 DeepSeek 模型样本;其他提供方的用量永不按 DeepSeek 计价)。任意
窗口 (start, end] 的消耗 = boundaries[end].cost - boundaries[start].cost
(用于余额明细表的「变化量(当前API)」列)。结果按 spendCacheTtlMs
(默认 60 秒)缓存样本折叠,边界查询本身是 O(样本数 + 边界数);折叠预算
spendTimeoutMs(默认 30 秒,多会话持久化读取较重,别用 context 的 8 秒
预算——超时中断会让漏掉的会话用量在窗口里显示为 0)与 512 会话上限触发时
返回 partial: true(数字偏小但仍有意义,界面会提示)。边界最多 64 个,
非法/重复/负值边界会被丢弃。
{
"ok": true,
"currency": "CNY",
"pricingVersion": "deepseek-v4-2026-08-23",
"sessions": 12,
"samples": 341,
"boundaries": [
{ "at": 1755446400000, "cost": 0.01234, "costUncachedInput": 0.0045,
"costCacheRead": 0.0002, "costCacheWrite": 0, "costOutput": 0.00764,
"uncachedInputTokens": 3000, "cacheReadTokens": 2000,
"cacheWriteTokens": 0, "outputTokens": 1500, "steps": 3 }
],
"computedAt": 1755447000000
}
refresh=1 绕过折叠缓存;非 GET 请求返回 405。
GET /api/deepseek-quota/context?sessionId=<id>
{
"ok": true,
"currency": "CNY",
"pricingVersion": "deepseek-v4-2026-08-23",
"currentPeak": false,
"session": {
"cost": 0.01145,
"uncachedInputTokens": 2000,
"cacheReadTokens": 2000,
"cacheWriteTokens": 0,
"outputTokens": 1000,
"model": "deepseek-chat",
"provider": "deepseek",
"tier": "deepseek-chat",
"steps": 2
},
"turn": { "turn": 1, "cost": 0.00375, "uncachedInputTokens": 1000, "cacheReadTokens": 0, "cacheWriteTokens": 0, "outputTokens": 500, "steps": 1 },
"subagents": {
"cost": 0.001125,
"count": 2,
"children": [
{ "id": "…", "label": "…", "cost": 0.000375, "uncachedInputTokens": 100, "cacheReadTokens": 0, "cacheWriteTokens": 0, "outputTokens": 50, "model": "deepseek-chat", "provider": "deepseek" }
]
},
"computedAt": 1755446400000
}
// 失败 — code 取值:
// MISSING_SESSION 缺少 sessionId 查询参数
// SESSION_NOT_FOUND 会话既不在线也不在持久化存储中
// INTERNAL 计算过程异常(如子代理枚举超时/持久化读取失败)
{ "ok": false, "code": "MISSING_SESSION", "message": "缺少 sessionId 查询参数" }
说明:
session/turn/subagents.*的金额单位与currency一致(默认人民币元)。- 金额按当前价目表即时折算;token 桶才是持久化的真实数据,价格调整只会影响 展示金额,不会改变会话日志中的用量。
- 子代理枚举由
ctx.subagents.listDescendants提供(持久化优先合并在线会话), 子代理读取失败或超时不会影响主会话数字,仅以subagents.error标注。 - 结果按会话短缓存(
contextCacheTtlMs,默认 5 秒),切换会话时额度行秒出;GET /api/deepseek-quota/context?sessionId=<id>&refresh=1可绕过缓存取最新值。 - 浏览器端额度行在加载完成前先渲染等高的占位行(
…),数据到达后原位替换, 因此切换会话不会出现布局跳动;切回已看过的会话会先显示缓存值再刷新。
配置
| 配置项 | 设置方式 | 默认值 |
|---|---|---|
| API 地址 | DEEPSEEK_BASE_URL 环境变量,或行配置 baseURL | https://api.deepseek.com |
| 缓存 TTL | 行配置 ttlMs | 60000 |
| 请求超时 | 行配置 timeoutMs | 15000 |
| 额度计算预算 | 行配置 contextTimeoutMs | 8000 |
| 额度路由缓存 | 行配置 contextCacheTtlMs | 5000 |
| 全局消耗折叠缓存 | 行配置 spendCacheTtlMs | 60000 |
| 全局消耗折叠预算 | 行配置 spendTimeoutMs | 30000 |
| 价目表覆盖 | 行配置 pricing | 官方 DeepSeek-V4 峰谷价目表 |
行配置写在 profile 的 cordis.patch.yml
($DSH_HOME/profiles/web/cordis.patch.yml):
- id: deepseek-quota
config:
ttlMs: 30000
timeoutMs: 10000
pricing:
version: my-table-2026-09-01
tiers:
deepseek-chat:
peak:
cacheHit: 0.12
cacheMiss: 3.2
output: 9.5
offpeak:
cacheHit: 0.06
cacheMiss: 1.6
output: 4.75
fallbackTier: deepseek-chat
pricing.tiers 按档位名深合并进默认价目表;fallbackTier 决定未知模型按哪档计价。
仓库结构
dsh-deepseek-quota/
├── package.json # 清单:dsh.bundle.patch + dsh.client (web)
├── cordis.patch.yml # bundle 层:插入 deepseek-quota 宿主行
├── lib/
│ ├── index.js # 宿主编:余额路由 + 会话额度路由(持久日志 fold + 峰谷计价)
│ ├── client.js # 浏览器端:侧边栏余额 + composer 额度行(React.createElement)
│ └── types/ # 手写 .d.ts,描述公开接口
├── test/
│ └── index.test.js # 宿主编冒烟测试(node:test,零依赖)
├── README.md
├── CHANGELOG.md
└── LICENSE
开发
node test/index.test.js # 运行宿主编冒烟测试(node:test,零依赖)
客户端 bundle 是纯 JavaScript,由 client-modules 系统原样下发——无需构建步骤。
用本地目录(file: 依赖)加载插件并重启 dsh web 即可生效;浏览器端模块在
刷新页面后热更新。