DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

liaimei /

liaimei/dsh-cost-breakdown

Verified

DSH 会话费用账单:账号余额 + 峰谷计价 + 每个会话(含子代理衍生会话)的消耗构成,输入框下方读数与右侧栏面板双入口。 DeepSeek Harness session cost breakdown: balance, peak/off-peak pricing, and how each session's spend is composed.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@98094ab4

dsh-cost-breakdown — 官方人民币费用统计

本插件基于 dsh-context 的源码(main@209169d, 即 v0.66.1 之后的 main)重构:src/ 是上游 dsh-context 的逐字源码,上游 2000+ 测试原样通过; 本仓库在其之上叠加两项自己的功能 —— **官方人民币价目表(峰谷 + 法定节假日)**与 输入框下方的常驻费用读数。

保留的上游能力

上游的代码逐行保留(除下文列出的接线文件)——注释与若干界面文案已按本仓库的 约定改写,但没有任何一条语句、表达式或类型被改动(改动范围见 NOTICE)。 因此下列上下文洞察能力全部保留:

  • 上下文仪表盘:组成(system / tools / user / assistant / tool-results)、趋势图、上下文浏览器、 事件列表、文件活动、Agent 网络;
  • 统计页(左侧栏,即重构后的「上下文洞察」页):跨会话 KPI 条、计费 Token 按平台四桶拆分、 上下文组成圆环、7 日用量图、活跃度热力图、技能加载、会话卡片、账户余额胶囊;
  • /context 命令与 Ctrl/⌘ 弹窗;
  • 每会话的 Token 卡与费用卡(含子 Agent 折叠),以及叠加的费用统计卡 (分桶成本 + 峰谷拆分 + 账户余额)。

本仓库叠加的功能

① 官方人民币价目表(src/shared/officialRates.ts)

上游只按 models.dev 的美元簿计价,并给 DeepSeek 的 peak 桶统一乘 PEAK_FACTOR = 2, 没有节假日表。本插件改为以官方人民币价目表为准:

模型 谷价(缓存命中 / 未命中 / 输出,元/百万 Token) 峰价
DeepSeek-V4.1-Flash 0.02 / 1 / 4 0.04 / 2 / 8
DeepSeek-V4-Pro 0.15 / 4.5 / 13.5 0.3 / 9 / 27
  • 峰谷判定:北京时间周一至周五 09:00–12:00、14:00–18:00 为高峰,其余为空闲;谷价恰为峰价一半。
  • 法定节假日:内置 2026 年国务院安排(31 天),节假日全天按谷价计费,与周末一致。 可用宿主配置 holidays: ['2026-10-01', ...](YYYY-MM-DD,北京时间)覆盖。
  • 安全回退:配置里给不出任何一个合法日期时退回内置表,而不是当成「没有节假日」—— 后者会把每个节假日按高峰价计费,静默翻倍。
  • 谁贵谁便宜看官方表:官方表收录的模型一律按官方价计(峰桶 = 谷价 × 2);其余模型仍走上游 models.dev 的分支与回退层级。因此 DeepSeek 的费用即使没有加载到 models.dev 也照常显示。
  • 峰谷按模型判定,不按 provider 路由:官方表收录的模型,无论请求走自家路由还是第三方代理 (workbuddy、镜像站等),都按上面的北京时段分桶——否则代理路由下的 DeepSeek 用量会被整套 记进「峰」桶却又不翻倍,峰谷既分错、峰时还少收一半。未收录的模型一律记「峰」桶且不翻倍。
  • 峰谷判定在宿主完成(src/host/foldMetering.ts 的 isPeakAt),所以落库的桶 携带的就是当时实际适用的费率;节假日真的会记进谷价桶。

② 输入框下方的常驻读数(src/client/components/composerDock.tsx)

上游没有这个入口。收起时只占一行:本会话费用 · 余额 · 当前峰/谷; 尺寸与配色逐项对齐官方同排组件(ContextMeter.module.css 的 .trigger 与 StatsPills.module.css 的 .pill,它们就长在这一行两边):同一个 13px 字号、同一个 20px 行高、同一个 padding: 1px 8px,盒子因此同为 22px 高;基色同为 label-tertiary、 悬浮同为 label-secondary、分隔符用官方的 separator-primary,且都不加粗。 并排看不会一高一矮,也不会像外来控件。只有峰/谷保留语义红绿——那是这一行唯一要传达的信息。 峰谷本身是实时算出来的,不是写死的标签:徽标后面跟着距离下一次翻转的倒计时, 每秒走一格(usePricingPeriod 的一秒节拍,时段没变的帧不重渲染);悬停与展开卡里还写全 峰时是哪几段(09:00–12:00、14:00–18:00,由 PEAK_WINDOWS 派生,改表即改文案)。 周末与法定节假日全天谷时,此时不报一个会让人误以为「今天还有峰时」的倒计时, 而是直接说明原因。 状态栏放不下完整读数时自动改用图标:整句「6 小时 38 分 后进入峰时」 换成时钟图标 + 紧凑读数(6h38m,悬停仍给出整句),费用、余额与峰/谷徽标照常保留。 判据是「留给本行的空间」与「完整内容需要的宽度」之比,不是拿一个写死的断点比这一行的总宽: 官方那一行里还有用量读数与上下文环,它们先占掉一截,所以总宽够、留给本行的却可能不够 (线上正是如此:行宽约 860px,官方两块占掉约 260px,留给本行的约 570px,而整句需要约 600px)。 可用宽度由「父级内容宽 − 兄弟条目宽 − 间隔」算出,需要的宽度由一句始终渲染但移出可视区 的量宽探针给出——两者都与当前渲染的是整句还是紧凑形态无关,因此不会自激 (切紧凑 → 变窄 → 又判定够宽 → 切回去)。官方 StatsPills 依据的是同一个量 (min-width:0 + text-overflow:ellipsis,按实际可用宽度收缩)。 点一下展开详情卡。展开卡里嵌的就是汇总统计页的那两张卡—— Token 统计与费用统计——外加当前时段的官方价目表:同一份数据、同一种排版, 输入框下方与统计页读到的因此永远是同一回事(余额由费用卡自己那一行承担,不再重复一处)。 卡片用 position: fixed 并实测触发按钮位置,避开输入框自身的 overflow 裁剪。外观对齐 harness 官方面板(stat-dialog.module.css):同一层 --dsw-specific-menu、同一个 --dsw-radius-lg 圆角、同一道发丝描边 + --dsw-elevation-prominent 阴影、同一个 z-index: 1100,因此它与会话底部那个官方弹窗读作同一层。 宽度对齐官方面板的上限(440px,窄触发条也照此)并夹进视口,所以既不会裁掉右列数值, 也不会出现左右滚动条;卡内三块都显式声明 box-sizing: border-box,宽度因此逐块对齐 (基础 .lc-card 的 border-box 只声明在 .lc-root 之下,浮层里没有那个祖先)。 上方空间不足时自动翻到下方。峰谷徽标随本机时钟自动翻转。

余额由两个来源提供,按顺序尝试:① DSH 自身的账号登录(deepseekAccount 服务,不需要 API key —— 桌面端登录账号就用这个);② API-key 提供方(没有账号服务时)。读数先画上次记住的数字,再按 60 秒周期自动校正(这个数字随每次计费请求变化,长期挂载只读一次会显示过期值)。

③ 统计页:具体到平台的计费桶(src/client/components/overviewBilled.tsx)

两个入口各用其名:左侧栏那一页是账号级汇总,叫统计(英文 Statistics, 原「上下文洞察」);本会话视图(对话区标签栏,以及右侧栏的标签、面板与入口卡片) 是同一个组件、同一份本会话数据,因此两处共用一个名字,叫汇总统计 (英文 Summary Statistics)——同名是有意的,否则同一份视图在两处会像两件事。 本页新增一张计费 Token 卡 —— 按平台 实际计费的四个桶统计,全部是 provider 上报的精确值(不是估算):

桶 含义
缓存输入 cacheReadTokens:命中缓存的那部分输入
未缓存输入 inputTokens(含缓存写入):按未命中价计费
输出 outputTokens:已含思考 token

卡片下方是峰 / 谷费用拆分,直接回答「这笔钱有多少落在峰价上」。它与同排的 上下文组成圆环(同样口径的 token,按 system / tools / user / assistant / tool-results 拆分) 互为补充:一个说钱花在哪段时间,一个说 token 是什么内容。

④ 本会话的费用卡(src/client/components/statsCost.tsx)

汇总统计页的头部那一排,在 Token 统计与耗时统计之间插了一张费用统计卡, 与两侧的环形卡同款排版:

  • 计费分桶成本:把本会话的钱按四个桶拆开——缓存输入 / 未缓存输入 / 缓存写入 / 输出; 环图给份额,图例每一行的次行给出该桶的真实金额。费率与 Token 卡同源, 因此「用得多」与「花得多」是同一批数字的两面。
  • 峰 / 谷拆分:这笔钱分别落在峰价与谷价上的金额与占比。零值的一段仍然列出 (环图跳过零弧,图例不该跟着消失)。
  • 账户余额:与 Insights 页那颗胶囊同两个来源——先画上次记住的数字,再由宿主路由 后台校正;取不到时整行不出现,绝不用一个零蒙混。

三处的费率与峰谷判定共用 client/cost.ts 的同一个入口 (estimateSessionCostByBucket),所以这张卡、Token 卡、输入框下方的读数 以及统计页的计费桶卡之间不会互相漂移。

与上游的关系

本仓库 上游
官方人民币价目表 + 峰谷 + 法定节假日 models.dev 美元簿 + 固定 PEAK_FACTOR = 2,无节假日表
输入框下方常驻读数 无
汇总统计页的费用统计卡(分桶成本 + 峰谷 + 余额) 无
host/config.ts 新增 holidays 字段 无
contextTimeline stateVersion 29、contextActivity 6 27 / 4

详细改动清单见 NOTICE,fork 说明见 FORK.md。

数据来源

数据 来源
余额 上游 host/balance.ts:读 settings + credentials 后请求 api.deepseek.com/user/balance(插件不接触令牌)
用量 会话日志里 assistant/message 自带的 usage,由宿主投影折叠为每(provider, model, 时段)的累计桶
价格 本插件的官方人民币价目表(src/shared/officialRates.ts);官方表未收录的模型走 models.dev
时段 北京时间周一至周五 09:00–12:00、14:00–18:00(法定节假日与周末除外)为高峰

计价口径(重要)

DSH 记录的 inputTokens 是缓存未命中的输入,cacheReadTokens 才是缓存命中的输入, 两者与 outputTokens 是互不重叠的桶。实测一条真实记录:

{inputTokens: 192, outputTokens: 238, totalTokens: 13102, cacheReadTokens: 12672}
      192 +        12672       +        238      = 13102

若把 inputTokens 当成整个 prompt,就会把已缓存的 12672 tokens 按未命中价计费, 费用会被高估一个数量级。本插件按三个桶分别计价(缓存写入不单独计价,按未命中价计)。

费用为估算值,按 DSH 记录的 token 用量与官方价目表计算;实际扣费以平台账单为准。 官方表与 models.dev 都未收录的模型会计入请求数但不计费,并在界面标注,绝不会被当成免费。

衍生会话只计一次(避免重复计费)

这部分是上游行为,本仓库原样保留:fork / 摘要重建出来的会话是带种子的, 日志开头是祖先事件的一份拷贝,而那些请求在祖先会话里已经计过费。 宿主折叠在 session/end-seed { inherited: true } 标记处截断继承前缀, 因此子会话只计自己真实发生的调用。

安装

本仓库的包名是 dsh-cost-breakdown,与上游 dsh-context 不同名,两者可以并存 (不建议同时启用:两套上下文入口会在界面上重复)。

从 GitHub 源安装(仓库自带编译产物,安装时不需要构建):

dsh plugin --profile web add github:liaimei/dsh-cost-breakdown

不要在 package.json 里加 prepare/postinstall 之类的生命周期脚本。 lib/ 是入库的产物,安装时无需构建;而 pnpm 从 git 拉依赖时会执行这些脚本, 一旦存在就会被 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 拦下——消费端只能把 带 commit SHA 的包名加进 allowBuilds,等于每推一次改一次白名单。 构建请走显式的 pnpm run build。

从本地检出安装(开发时用,link: 让改完 lib/ 刷新页面即生效):

dsh plugin --profile web add "dsh-cost-breakdown@link:/path/to/dsh-usage-meter"

装完重启 DSH(宿主半区不热生效),然后输入框下方会出现常驻费用读数。

排查安装问题时注意

  • 只想读状态时别用 dsh plugin list:该子命令并非只读——它会触发一次 reconcile 并落盘(实测会移除 lock 里已不再声明的依赖)。直接看 ~/.dsh/profiles/<profile>/package.json 与 node_modules/ 更安全。
  • 确认宿主半区确实是新的:POST /api/dsh-cost-breakdown/skills(带会话 cookie) 应返回 200;返回 404 说明跑的还是旧代码,重启 DSH 即可。
  • 改路径或升级后检查 dsh.profile.bundles 里 dsh-cost-breakdown 只出现一次, 且 cordis.patch.yml 里没有指向已移除包的 - id: <旧包名> 死条目。

源码与构建

源码是 TypeScript(src/),产物是 lib/,由 tsdown 打包成两个入口:

源文件 产物 说明
src/host/index.ts lib/index.js + lib/index.d.ts 宿主半区(ESM)。改完需重启 DSH
src/client/index.ts lib/client.js 浏览器半区(CJS,包在 window.__ModuleLoader__.load 里)。改完刷新页面即可
pnpm install
pnpm run build      # tsdown -> lib/
pnpm run typecheck  # tsc --noEmit -p tsconfig.tests.json

浏览器半区的依赖有纯净性闸门(tsdown.config.ts):只有 react / react-dom / dsh-client-ui-primitives 可以留成运行时 require,其余必须内联;新增的可内联依赖要同时 加进 onlyBundle。

验证

NODE_OPTIONS=--localstorage-file=/tmp/ls.db pnpm exec vitest run --coverage
  • 2070 个测试通过,逐文件 100% 覆盖率是仓库门槛;
  • 其中 2000+ 个是上游原样的测试;另有 8 个上游 spec 只改了被新功能有意改变的断言 (官方价目表取代 models.dev 价、节假日不再按峰价、槽位从 5 个变 6 个、stateVersion 27→29 / 4→6), 没有放宽任何断言语义;
  • tests/compat/bundle.spec.ts 直接加载构建产物 lib/client.js,验证交接协议、 CSS 通道与槽位注册,所以跑之前要先 pnpm run build;
  • 本仓库新增的 spec:tests/shared/officialRates.spec.ts(价表 / 峰谷边界 / 节假日 / 回退)、 tests/client/components/composerDock.spec.ts(常驻读数与展开卡)、 tests/client/components/statsCost.spec.ts(费用统计卡:分桶 / 峰谷 / 余额 / 空状态)。

环境注意

  1. DSH 自带的 Node 跑不了 tsdown:macOS 会拒绝 app 签名内 rolldown 的原生 .node (different Team IDs)。用普通 Node(/opt/homebrew/bin/node)构建,运行时不受影响。
  2. Node 26 会盖掉 jsdom 的 localStorage:不给 --localstorage-file 时它是 undefined, 会让十个客户端 spec 失败(上游同样如此)。因此命令里带 NODE_OPTIONS=--localstorage-file=/tmp/ls.db。

已知边界

  • 法定节假日表:内置 2026 年安排。国务院每年公布新安排后,可用插件配置 holidays: ['2026-10-01', ...] 覆盖,或更新 src/shared/officialRates.ts 里的 DEFAULT_HOLIDAYS。
  • 官方表未收录的模型:按 models.dev 价(若已加载)估算;两者都没有则标注不计费。
  • 汇率显示:官方价目表是人民币;英文界面按 1 元 = 0.15 美元换算显示。
  • 仅计量 DSH 内的请求:直接调用 API 或使用其它客户端的消耗不在统计内。

权限与外部服务

项 说明
读会话日志 只读观测本机会话事件,用于统计 token 用量
读账户余额 通过上游 host/balance.ts 读 settings + credentials 后请求 api.deepseek.com(插件不接触令牌)
外部网络 前端 models.dev 价目表(官方表未收录的模型才需要)+ 余额查询;其余全部本地计算,不上报任何数据
本地存储 只存上次记住的余额(localStorage);不写文件、不建数据库
遥测 无
写操作 无。插件只读,不修改会话、配置或代码

许可

Apache-2.0 © 2026 liaimei(fork 自 Apache-2.0 的 dsh-context,见 NOTICE)

—/ 5

No ratings yet

Verified DSH bundle

Commit 98094ab4ef12

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout