dsh-cost-lite
Verified@hualiong/dsh-cost-lite · v0.2.1 · MIT · Web UI
Real-money cost badges for DeepSeek Harness: a 「计费用量」 pill in the composer dock (or the session header on subagent pages whose composer is replaced; session scope, including all subagent descendants) and in each assistant message's action row (per turn),
Install
dsh plugin add @hualiong/dsh-cost-lite Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Readme
@hualiong/dsh-cost-lite
DSH 的真实花费徽标:把本会话的 token 用量按模型价目换算成金额,显示在内置「Token 用量」徽标的旁边。
| 位置 | 挂点 | 行 id | 文案 |
|---|---|---|---|
| 每条助手消息的操作行(显示该消息所属整轮的合计) | conversation.chat.assistant-actions |
cost-lite-turn(order 20) |
计费 0.01 元 |
| 输入框停靠栏 | conversation.composer.dock |
cost-lite-session(order 5) |
3.42 元 |
| 子智能体会话顶栏(仅当输入框被只读替代、停靠栏不存在时) | conversation.session.header.actions |
cost-lite-header(order 30) |
3.42 元 |
点开任一徽标是一个与内置统计弹窗同款的浮层:标题是 ¥ 金额,下面按桶列出金额与单价(未缓存输入 / 缓存读取 / 缓存写入 / 输出,单价以 ¥x.xx/M 表示)——金额按各桶分别计价后相加,与标题 6 位小数一致。操作行那个徽标的口径是整轮(一轮有多条助手消息,同一轮的每条消息显示同一个金额),因此它多一行「提供方 / 模型」,数字与内置「本轮用量」面板对齐;停靠栏/顶栏那个是整个会话的合计,不列模型行,但当会话派生了子智能体(subagent / teammate)时会在标题下方第一行列出「子智能体」,直接给出全部后代会话的合计金额(不带单价——后代可能混着模型和运行方式,没有单一价格可印)。会话徽标的两处挂点互斥(镜像内置只读输入框的接管条件),每个页面恰好一个;一次性子智能体或父会话已关闭的可续会话没有停靠栏,徽标改挂在顶栏动作区。
计费口径
- 供应商:只统计价目表里能精确匹配到的(provider, model)组合,没有任何 provider 级兜底价。官方提供方为
deepseek-account/deepseek-official;未登记的模型在折叠阶段整条跳过,所以整轮都没登记时该轮根本没有条目、不渲染任何徽标,而多模型会话只累计其中官方的那部分。 - 模型 key(精确 id,只有两个):
deepseek-flash、deepseek-v4-pro。旧 id(deepseek-v4-flash、deepseek-v4-flash-vision-exp)官方已不再提供,价格表里也不再登记——精确匹配不到就不计费,不会套用同 provider 的 Flash 价。要恢复某个组合,只能显式写进config.models(key 为<provider>/<model>)。 - 价目(CNY / 1M tokens,取自 https://api-docs.deepseek.com/zh-cn/quick_start/pricing,读取于 2026-10-11):Flash 空闲
缓存未命中 1 / 缓存命中 0.02 / 输出 4;V4 Pro4.5 / 0.15 / 13.5(DeepSeek 只公布三档,缓存写入记为 0)。 - 高峰时段:北京时间周一至周五
9:00-12:00、14:00-18:00为高峰,价目 ×2;周末与法定节假日全天按空闲价。时段按该条事件自己的time(epoch 毫秒,落盘后不再变)判定,所以同一个数不会在两次轮询之间漂移。节假日内置 2026 年列表(src/index.js的PEAK_HOLIDAYS),需要按年补充;未收录的工作日节假日会按高峰计价(只会高估,不会低估)。 - 未知组合:在折叠阶段就整条跳过(不计 token、不产生 message/turn 条目),响应里
priced: false,两端徽标都不渲染,绝不猜价。 - 子智能体:会话徽标与「子智能体」行统计整个后代树(subagent、teammate,含孙辈)。发现有两个通道:父会话日志里的
subagent/catalog事件,以及活会话登记表里header.parentSession指向本会话的项(teammate 这类不写目录行的子会话靠后者);两通道按 id 去重。每个后代只折叠它自己的事件段(live 用ownEvents(),冷会话经sessionQuery.readSession按inheritedEventCount切片),fork 继承的父前缀不会重复计费。被查询的会话本身也走同一条 live/冷读取路径(0.2.1 起):一次性子智能体或已关闭的会话即使不在活登记表里,也会按自己的日志计价。折叠遵守同一套价目与高峰规则;上限 128 个后代,超出部分不计。轮级徽标口径不变(仅本会话该轮)。
安装
dsh plugin --profile <profile> add @hualiong/dsh-cost-lite
dsh plugin --profile <name> <pnpm 参数> 是 DSH 自带的插件管理入口(参数转发给该 profile 目录下的 pnpm)。装完它会自动把新依赖里声明了 dsh.bundle 的包登记进 profile 的 dsh.profile.bundles——本包两者都具备,所以这一条命令就够了。等价的手工做法是改 ~/.dsh/profiles/<profile>/package.json:
{
"dependencies": { "@hualiong/dsh-cost-lite": "^0.1.2" },
"dsh": { "profile": { "bundles": [ /* …, */ "@hualiong/dsh-cost-lite" ] } }
}
本包自带 cordis.patch.yml,会插入下面这行:
- id: cost-lite
name: '@hualiong/dsh-cost-lite'
profile 自己的 patch 文件按 id: cost-lite 覆盖该行来传配置(config.models、config.currency)或启停。改 dependencies / bundles 后必须重启 DSH:运行时解析器拒绝热替换。
本包也可经
@hualiong/dsh-plugin-suite(1.3.0 起)随套件安装,套件里这一行默认disabled: true,按需在插件列表里打开即可;两种方式装的是同一份代码,只需其一。
开发
- 宿主半边(
src/index.js、src/pricing.js)改动需要重启 DSH:运行时按解析到的模块 URL 缓存,文件改了也不会重新 import。 - 浏览器半边(
src/client.js)由宿主按 mtime 生成rev提供,改完刷新页面即可。 - HTTP 接口:
GET /__cost-lite/usage?sessionId=<id>,返回{ ok, sessionId, currency, priced, allCost, session, messages, turns, subagents },响应头cache-control: no-store。messages以 MessageId 为键、turns以轮号为键。allCost= 本会话 + 全部后代的合计(会话徽标显示它);subagents={ count, priced, cost, totalTokens }。
许可
MIT