dsh-cost-meter
Manifest validDeepSeek Harness Plugin: Displays this session's token usage and RMB cost to the right of the context usage (converted according to DeepSeek's official pricing)
@max/dsh-cost-meter
在 DeepSeek Harness Web 界面里,把本次会话的 token 用量和人民币费用显示在对话框下方、上下文用量的右侧。
零依赖、零构建:client.js 就是浏览器直接加载的产物,index.js 是空的 Host 半侧。
安装(给拿到这个包的人)
先拿到包含 cordis.patch.yml 的整个包(.tgz / git 仓库 / 本地目录都行),再让 DSH 把它装进当前 profile。
方式一:压缩包或本地目录
dsh plugin add "D:\下载\max-dsh-cost-meter-<版本>.tgz"
dsh plugin add "D:\下载\dsh-cost-meter"
方式二:git
仓库地址 https://github.com/PennChong95/dsh-cost-meter(已打上 GitHub topic dsh-plugin,社区插件市场大多按这个 topic 自动收录):
dsh plugin add "github:PennChong95/dsh-cost-meter"
- 仓库里必须包含已构建的产物:本包没有构建步骤,
client.js就是产物,直接提交即可。 - git 安装会拉取整棵仓库,
package.json的files白名单不生效——别把node_modules之类的东西提交上去。 - 国内使用者的可达性是个变量:DSH 安装前会用
git ls-remote探一次 GitHub(默认 5 秒超时),不通时界面会提示「无法访问 GitHub」,而 npm 镜像只能替代 npm 源、替代不了 GitHub 下载。给国内用户分发时,.tgz直发最稳。
Desktop 应用用户:desktop profile 由应用独占,命令行会被拒绝,请走界面 —— 侧边栏 插件 → 添加插件,把上面的 spec(.tgz 或目录的绝对路径、git 地址)粘进输入框 → 安装。安装对话框里能看 pnpm 输出,装完默认启用。
装好后界面上应该出现一个 ¥ 胶囊,位于输入框下方、上下文用量环的右侧;点开是明细面板。
注意事项
- 本包在 DSH
0.2.0-rc.2(Desktop 版)上验证通过。它依赖conversation.composer.dock插槽与tokenUsage、modelSelection两个会话投影;更早的 DSH 版本若没有这些,插件会加载失败(插件列表里能看到原因)。 - 安装后请刷新一次页面:运行中的页面持有已求值的旧模块。
- 目前 DSH 的插件不支持自动更新:升级要先卸载再装新版。
- 本包没有
dependencies,也没有prepare脚本,因此安装时不会触发任何依赖构建;通过 git 安装也不会遇到 pnpm 的构建脚本拦截。 - 改名要改三处:
package.json的name、client.js的id(必须是同一个字符串,客户端模块靠它注册自己)、cordis.patch.yml的name:(YAML 里以@开头的值必须加引号)。顺带把client.js的NS、STYLE_ID、STORAGE_PREFIX也换掉,避免与同名插件撞命名空间。dsh.bundle.patch、exports不用动。
它显示什么
- 胶囊按钮:
¥0.1234—— 本次会话按 DeepSeek 官方价目折算的花费。 - 点击后展开明细(不会超出视口):
- 输入·缓存命中 / 输入·缓存未命中 / 输入·缓存写入 / 输出 的 token 数与各自金额;
- 总 tokens;
- 高峰时段 / 空闲时段 分别累计的金额(
mode: ledger); - 计价模型、当前时段、当前费率(元/百万 tokens)。
胶囊元素的 CSS order 为 1,而 composer dock 中上下文用量环排在插槽之后,因此本插件始终落在上下文用量的右边。
定价口径
价目取自 DeepSeek 官方「模型 & 价格」页(人民币 / 百万 tokens):
| 模型 | 输入·缓存命中 | 输入·缓存未命中 | 输入·缓存写入 | 输出 |
|---|---|---|---|---|
deepseek-flash 高峰 | 0.04 | 2 | 2 | 8 |
deepseek-flash 空闲 | 0.02 | 1 | 1 | 4 |
deepseek-v4-pro 高峰 | 0.30 | 9 | 9 | 27 |
deepseek-v4-pro 空闲 | 0.15 | 4.5 | 4.5 | 13.5 |
时段规则(官方说明:「北京时间周一至周五(不含中国法定节假日)9:00 - 12:00、14:00 - 18:00 为高峰时段;其余时段,包括周末及中国法定节假日全天均为空闲时段」):
- 高峰 = 北京时间周一至周五 ∧ 不是中国法定节假日 ∧ 落在 9:00–12:00 或 14:00–18:00。
- 其余全部空闲,价格为高峰的一半,具体包括:
- 每个周六、周日;
- 调休上班的周末(例如 2026-01-04 周日、2026-02-14 周六、2026-05-09 周六、2026-09-20 周日、2026-10-10 周六)——按官方口径,周末即使被调休成工作日也按空闲计费,插件不做“调休补班按高峰”的处理;
- 中国法定节假日全天,即使落在周一至周五(例如 2026-10-01 周四、2026-02-17 周二、2026-06-19 周五)。
节假日表按国务院办公厅年度通知内置,当前含 2026 年(国办发明电〔2025〕7 号,2025-11-04:元旦 1/1–1/3,春节 2/15–2/23,清明 4/4–4/6,劳动节 5/1–5/5,端午 6/19–6/21,中秋 9/25–9/27,国庆 10/1–10/7,共 33 天)。表里没有的年份,面板会提示“该年节假日安排尚未内置”,此时可用 extraHolidays 临时补上;内置表写错时用 extraWorkdays 把某天改回工作日规则(该日期优先于节假日判断)。
其它:
cacheWrite按缓存未命中价计:DeepSeek 的 usage 把提示缓存写入计入普通输入,官方没有单独的缓存写入单价。- 已下线的
deepseek-v4-flash、deepseek-v4-flash-vision-exp按 Flash 价计费,deepseek-v4-pro-0813按 Pro 价计费。 - 官方口径以「中国法定节假日」为准;插件内置的是国务院办公厅通知里的全部放假日(含调休连休日),这比严格意义的 11 天法定节假日更宽,与“全国都放假”的实际计费场景一致。若你只想按 11 天法定节假日算,用
extraWorkdays把多出来的连休日改回工作日即可。
这些数字是估算:它由本会话持久化的 usage 折叠得出,不含子会话、其他会话,也不含任何非 token 计费项。实际扣费以 DeepSeek 开放平台账单为准。
已知限制
- 首次观察到的历史用量按当时费率一次性计入。
tokenUsage只给会话总量、没有逐请求时间戳,所以插件首次挂载(安装后、刷新后第一次进入某会话)时,会把当时已有的全部用量按当下的时段费率计入。安装前跨过 09:00、18:00 或节假日边界的会话,首次数字可能偏高或偏低;此后每次增量都按发生时刻的费率计。 - 节假日表随插件版本走。 国务院办公厅通常在每年 11 月发布次年的安排;内置表更新前,次年的节假日会被当成普通工作日(面板会提示)。跨年时请留意更新插件或临时补
extraHolidays。 - 作用域是当前会话。 子代理会话、其他并行会话的用量不在其中。
- 账本存在浏览器 localStorage(键
max-dsh-cost-meter:v2:<sessionId>)。键里的版本随计价规则变更递增:规则变化后不会与旧账本混算,而是按新的规则重新对现存总量计价。清理浏览器数据会把累计金额清零(随后从当前总量重新起算)。 - 显示为
—表示当前模型不在官方价目表中(可用unknownModel: defaultModel改为按默认模型估算)。
修改后如何生效
profile 里的插件是 file: 依赖的副本(nodeLinker: hoisted),改动本目录的源码不会自动同步;而且 pnpm 只看依赖声明,直接 pnpm add 常常回一句 Already up to date 而不刷新副本。可靠的做法是先删再加:
cd "$env:USERPROFILE\.dsh\profiles\desktop"
$pnpm = "$env:LOCALAPPDATA\Programs\DeepSeek Harness\resources\runtime\pnpm\bin\pnpm.mjs"
node $pnpm remove "@max/dsh-cost-meter"
node $pnpm add "file:<本目录的绝对路径>" --offline
改完核对一下副本与源码是否一致(Get-FileHash),然后在界面上刷新一次页面:运行中的页面持有的是已经求值过的旧模块,不刷新就不会执行新代码。若刷新后仍未变化,重启 DeepSeek Harness。
发布语义上的版本号要一并提高(package.json 的 version):客户端模块按版本区分代次,只改文件内容而不改版本,宿主不一定会推送新的模块代次。
配置
cordis.patch.yml:
- insert:
- id: cost-meter
name: '@max/dsh-cost-meter'
config:
tier: auto # auto | peak | offPeak
mode: ledger # ledger | estimate
defaultModel: deepseek-flash
unknownModel: unpriced # unpriced | defaultModel
extraHolidays: [] # 额外按空闲(节假日)处理的日期 YYYY-MM-DD
extraWorkdays: [] # 额外按工作日规则处理的日期(覆盖内置表)
rates: # 可选:只写要覆盖的字段
deepseek-flash:
peak: { output: 8 }
| 字段 | 默认值 | 含义 |
|---|---|---|
tier | auto | 按北京时间自动判断高峰/空闲;也可固定为 peak 或 offPeak。 |
mode | ledger | ledger:把每次观察到的用量增量按当时费率计价并累计到 localStorage(跨时段、跨模型更准,seen 只增不减,不会重复计费)。estimate:用当前时段单价直接乘会话总量。 |
defaultModel | deepseek-flash | 会话还没有 modelSelection 记录时使用的模型。 |
unknownModel | unpriced | 价目表里没有的模型:unpriced 显示 — 并不计价;defaultModel 用 defaultModel 的价格估算。 |
extraHolidays | [] | 追加到内置节假日表的日期(YYYY-MM-DD),用于内置表还没覆盖的年份。 |
extraWorkdays | [] | 强制按工作日规则处理的日期,用于修正内置表;优先级高于 extraHolidays。 |
rates | 无 | 覆盖官方价目,按模型 id 合并。 |
实现
- Host 半侧(
index.js)是空实现:插件没有 Host 状态,行存在的意义是让config有归属。 - Client 半侧(
client.js)读取两个持久投影:tokenUsage→cacheReadTokens/uncachedInputTokens/cacheWriteTokens/outputTokens;modelSelection→ 会话真正的路由模型。
- 注册到
conversation.composer.dock(list插槽,session 作用域),自身实现样式与浮层,只依赖react、react-dom和--dsw-*主题变量。 - 文案走 Client locale 服务(命名空间
@max/dsh-cost-meter),语言服务缺失时退回内置词典。 - 时段判定用一张按年组织的节假日表(
STATUTORY_HOLIDAYS)加两个集合:holidays(当天全天空闲)与workdays(强制按工作日规则,用于纠错)。判定顺序是 workdays → holidays → 周六周日 → 两个时段窗口,全部在换算到北京时间后比较。
数据来源
- 价目:DeepSeek API 文档 · 模型 & 价格
- 节假日:国务院办公厅关于2026年部分节假日安排的通知(国办发明电〔2025〕7号)
测试
node --test test/pricing.test.mjs
测试直接加载 client.js 本体(用桩替换 window.__ModuleLoader__),覆盖价目表、时段判断、费用换算、账本增量与存储容错、格式化;另有三项渲染回归测试,用一个最小的 React 桩把真组件渲染出来,断言胶囊的金额文本、货币符号只出现一次、以及面板的明细行。
Comments
Loading…