dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
在每个已完成回合的下方单独一行显示这一轮的花费金额(人民币),点击展开明细,列出各 token 类别的数量、单价、命中的价格规则与计费时刻;单价可在 DSH 设置页里按模型维护,含四类 token 单价、每周循环的峰谷规则(系数自定)与绝对时间区间的限时优惠价。0.2.3 起还能看账户:读取 14 家 provider 的余额或剩余额度(DeepSeek、OpenRouter、智谱 GLM、月之暗面、MiniMax、Kimi Coding、OpenAI 兼容中转站等),在旁边显示今日 / 本月 / 本会话花费;花费记在本机日账里(原子写、按 API key 分本、保留 1-24 个月、可导出 JSON),另有一张按月日历,任何一天都能手动更正(包括没有余额观测的日子)并可加备注。用量与单价都在本机计算,余额用你自己的密钥直接向 provider 接口查询,不经过第三方。
在 DeepSeek Harness(dsh)的 Web 界面里,在每个已完成回合的下方单独一行显示这一轮花了多少钱,点击可展开明细(各 token 类别的数量 × 单价 = 金额、命中的价格规则、计费时刻)。
A DeepSeek Harness (dsh) web plugin that shows what each turn cost, in CNY, on its own row under the turn. Click the amount for a breakdown: tokens per category × unit rate = money, which price rule matched, and the billing instant.
金额按当前价格表实时计算:token 用量取自 dsh 会话日志里每个步骤的 usage,插件不做字符数估算,所以你事后修改价格,所有历史回合的金额会立刻跟着更正 —— 这正是「忘了提前改价」的补救方式。
界面上的金额是预估,不是账单:它等于 provider 上报的 token 数乘以你本地价格表的单价,实际结算以平台为准。
本插件是标准的 dsh 组合包(dsh.bundle.patch + dsh.client),三种地址形式等价:
| 地址形式 | 命令 |
|---|---|
| npm 包名 | dsh plugin --profile <profile> add dsh-turn-price |
| Git 仓库 | dsh plugin --profile <profile> add github:littlefish04/dsh-turn-price |
| 本地目录 / tarball | dsh plugin --profile <profile> add <绝对路径> |
也可以在应用内侧边栏的插件页用「添加插件」,填入上面任一形式的地址。
<profile> 换成目标 profile 名(桌面版是 desktop,dsh web 常见 web)。dsh web)。dsh plugin --profile <profile> remove dsh-turn-price。推荐 0.2.3 —— 本文档〈它是怎么记账的〉〈设置页的 4 张卡片〉里写的余额、日账、消费日历、
手工记账,都是 0.2.x 才有的(npm 上目前有 0.1.0 / 0.1.1 / 0.2.3):
dsh plugin --profile desktop add dsh-turn-price@0.2.3
| 想要 | 版本号写 | 说明 |
|---|---|---|
| 完整功能(推荐) | @0.2.3 | 余额 / 今日 / 本月 / 会话汇总、消费日历、手工记账、日账导出 |
| 只要最初那版:每轮花费 + 价格表 | @0.1.1 | 没有余额与日历;功能稳定,但不再更新 |
| —— | @0.1.0 | ⚠️ 不要装:它会让 dsh 起不来(客户端模块 id 与包名不一致),0.1.1 就是修这个的 |
| 从 git 仓库装 | 不写版本号:github:littlefish04/dsh-turn-price | 取 main 分支的当前内容(当前 = 0.2.3),不走 npm |
dsh-turn-price@0.2.3)。不写版本号会装 npm 上的 latest,
而国内镜像(npmmirror)同步有延迟,裸包名可能解析到旧版。核对官方源上的最新版:
npm view dsh-turn-price version --registry https://registry.npmjs.org
dsh plugin --profile desktop remove dsh-turn-price
dsh plugin --profile desktop add dsh-turn-price@0.2.3
>=0.2.0-rc.1 <0.3.0(见〈兼容性与边界〉);
每一版改了什么见〈版本更新〉。dsh plugin --profile desktop add "<本仓库的绝对路径>"
本插件没有构建步骤(lib/ 既是源码也是发布产物),所以 git 安装不需要 prepare 脚本、
也不需要用户在 pnpm-workspace.yaml 里批准构建脚本。
每个已完成回合的操作行上方多出一行金额(不占用 hover 才出现的操作行):
上图里那一行由四部分组成:
本轮花费+ 金额¥0.0874+ 徽标限时优惠+ 展开箭头▼。 徽标只在命中规则时出现,显示规则名,系数不是 1 时写成高峰×2这样。
点击金额展开明细:
| 显示项 | 内容 |
|---|---|
| 面板标题 | 本轮花费明细 + 合计金额 |
| 模型 | 模型:<provider> / <model>;一个回合换过模型时附注 (本轮经过 N 个路由,按路由表中的最后一个计价) |
| 计费时刻 | 计费时刻:2026-10-03 19:16(UTC+8,星期六) |
| token 来源 | token 来源:宿主折叠的会话事件,按每步 usage 容错求和(N 个样本);宿主不可用时写明「本页会话数据」 |
| 生效价格 | 生效价格:基础价(DeepSeek Flash),或 高峰 ×2 / 限时优惠 ×1 |
| 单价口径 | 单价口径:每 1,000,000 tokens |
| 明细表 | 类别 / tokens / 单价 / 金额 四列,之下是 合计 行 |
设置 → 每轮花费:按模型分页签维护价格表,改完保存,所有历史回合的金额立即重算。
按每个步骤的 usage 容错求和,而不是直接用 dsh 内置的严格折叠:
宿主(lib/session-usage.js)折会话事件 → 每轮 { buckets, routes, endSeq, endTime, reason }
桶 = { inputTokens, outputTokens, cacheReadTokens ?? 0, cacheWriteTokens ?? 0 }
为什么要换掉严格折叠(deriveTurnTokenUsage):它要求「有 totalTokens,或 cacheRead + cacheWrite 都有」,
否则整轮判为不可证、一个字都不显示。实测(本机 24 份真实会话日志 / 79 个回合)有 15 个回合因此
连金额都出不来 —— 它们的共同形状是 {inputTokens, outputTokens, cacheReadTokens}
(zai/glm-5.3-flash、deepseek-vision/deepseek-v4-flash 都这样:有缓存命中、缺缓存写入、缺 total)。
被手动停止的回合也一样会整轮消失。
容错求和的口径(与 dsh 的 tokenUsage 投影逐项相等,测试里拿官方定义对拍过):
cacheReadTokens / cacheWriteTokens → 记 0;usage 的步骤(中途被停止的那一步)→ 跳过,其余步骤照常计;totalTokens / reasoningTokens 不参与计价;llm/retry-started 之后的样本累加(重试的两次尝试都算钱);¥0.0000)。浏览器侧还有一条回退路径:宿主不可用时按页面上每步的 assistant-step.usage 同样容错求和。
回退路径拿不到路由时会借用严格折叠留下的 routes,明细里会注明数据来源。
金额 = Σ( 类别 token 数 ÷ 每单位 tokens × 该类别的生效单价 )
类别 = 未缓存输入 / 缓存命中 / 缓存写入 / 输出
按回合结束时间判定(时区用设置里的「时区偏移」,默认 +8 北京时间):
| 优先级 | 机制 | 说明 |
|---|---|---|
| ① 最高 | 限时特价 promos | 绝对时间区间。区间内自成一套价格:基础价 × 系数,再用各项「覆盖价」单独替换。不叠加峰谷系数。 |
| ② | 峰谷规则 rules | 一周内的循环时段(可选星期 + 起止时刻),价格 × 系数。支持跨零点(end < start)。 |
| ③ | 基础价 | 上面都没有命中时使用。 |
同类规则多条命中时,列表靠后的优先(便于后来追加例外)。
DeepSeek 的价格政策是「空闲时段价 = 高峰时段价的一半;高峰时段为北京时间周一至周五 09:00–12:00、14:00–18:00」。 所以本插件推荐的填法是:
周一~周五 09:00–12:00、周一~周五 14:00–18:00插件默认已按此预填 deepseek-flash 与 deepseek-v4-pro,设置页里也有「恢复 DeepSeek 官方价」按钮。
法定节假日整天都是空闲时段,无法用「星期几」表达;用限时特价把该日期区间的系数设为 1 (或直接写覆盖价)即可单独处理。
设置路径:设置 → 每轮花费,同一节内 4 张卡片:模型价格 → 账户与余额 → 消费记录 → 显示项。 逐项说明见下面的〈设置页的 4 张卡片〉一节;这里只列最常用的几个数:
| 项 | 默认 | 说明 |
|---|---|---|
| 显示每轮花费与汇总行 | 开 | 总开关,关闭后不渲染任何金额 |
| 货币符号 | ¥ | 估算金额用它(余额段用余额接口返回的币种) |
| 明细小数位 | 4 | 轮尾明细的位数 |
| 汇总行小数位 | 2 | 输入框下方汇总行的位数 |
| 时区偏移 | +8 | 判定峰谷/特价、以及日账归属哪一天都用它 |
| 每多少 tokens | 1000000 | 单价分母,与官方口径一致 |
| 未配置的模型 | 不显示金额 | 或「用兜底价计算」;默认不显示以免误导 |
| 兜底价 | 全 0 | 选择兜底时使用的四个单价 |
| 模型价格 | 见上 | 每个模型:模型 id / 提供方 / 显示名 / 四个基础单价 / 峰谷规则 / 限时特价 |
提供方留空 = 不限提供方:同一个模型在多个 provider 下价格相同时只写一条即可; 若某个 provider 价格不同,再单独加一条并填上 provider(精确匹配优先)。
价格表存在插件自己的 Cordis Config 里,由 dsh 的设置框架落盘到:
<DSH_HOME>/profiles/<profile>/cordis.patch.yml # 条目 id: turn-cost
跨窗口、跨会话、重启都不丢。若设置服务不可用(例如远端页面),插件自动退回浏览器
localStorage,并在设置页给出提示。
>=0.2.0-rc.1 <0.3.0(0.2 的设置模型与 conversation.chat.turnTail 槽位)。
安装器会读 peerDependencies 里的 @deepseek-ai/dsh-client-ui-settings 做版本闸门;
不兼容时 dsh plugin add 会拒绝,可用 dsh plugin allow-version 按精确版本放行。措辞说明:dsh 的折叠用
Map去重路由,重复写入不改变先后位置,所以「最后一个」 指的是最后一个不同的路由,不保证是"最后一次尝试"。这是既有行为,插件与之保持一致。
compact 会隐藏内置徽章,
但本插件的金额不受影响,始终显示。usage 样本的回合不显示金额,而不是给一个近似值。--dsw-alias-* 语义变量,且不写兜底值。
不写兜底值是有意的 —— 万一某个变量在你的主题里不存在,底色的退化结果是「透明」、
文字色的退化结果是「继承」,仍然可读;而写死浅色兜底会让深色模式下变成「浅字浅底」而糊掉。
深色下的原生控件(复选框、数字输入框)由插件自己按 body[data-ds-dark-theme] 声明
color-scheme,因为 dsh 主题包不设这个属性。
第三方主题只要实现了 dsh 文档化的 14 个核心语义变量,本插件就正常显示。/dsh-turn-price/* 读取,不发往任何第三方。dsh-turn-price/
├── package.json # dsh.bundle.patch / dsh.client / engines / peerDependencies
├── cordis.patch.yml # bundle 层:插入 id=turn-cost 的插件条目(id 即设置命名空间)
├── locale/{en,zh}.json # 插件市场里显示的标题与描述(meta.title / meta.description)
├── icon.svg # 插件卡片图标
├── screenshots.json # 市场详情页截图清单(仓库级约定,不进 npm 包)
├── assets/ # 上面那两张截图
└── lib/
├── index.js # 宿主半体:Config + 折叠装配 + /dsh-turn-price/* 路由
├── session-usage.js # 每轮 token 的容错折叠(与官方 tokenUsage 投影语义一致)
├── child-usage.js # 子代理会话枚举与用量投影(深度/数量/超时上限)
├── ledger.js # 真实日账(余额观测差值法)+ 估算账 + 保留期 + 原子写/损坏恢复
├── balance.js # 14 个余额/额度适配器(解析纯函数 + 取数 + 错误分类 + 智谱额度→余额改道)
├── balance-runtime.js # 余额管理器:凭据 → 指纹分本 → 取数 → 观测入账 → 定时刷新
├── http.js # 宿主侧 JSON-over-HTTP 小工具
└── client.js # 客户端半体:金额行 + 汇总行 + 设置页 4 卡片 + 价格引擎(唯一计价实现)
宿主与浏览器半体之间的协议(响应一律 JSON、都带 ok):
| 方法 | 路径 | 用途 |
|---|---|---|
| GET | /dsh-turn-price/usage.json?sessionId=<id> | 该会话每轮 { endSeq, endTime, route, routes, buckets } + 会话合计 + 子代理 + 折叠自查 |
| GET | /dsh-turn-price/state.json?sessionId=<id> | 余额 / 额度、本月、今日(真实)、今日与本月估算轮次、账本元信息 |
| POST | /dsh-turn-price/refresh?what=balance | 立刻刷新余额,返回新的 state |
| POST | /dsh-turn-price/test-connection | 用草稿参数测一次连接,不保存(密钥不回显) |
| POST | /dsh-turn-price/credentials | 凭据管理:describe / set / unset(永不回显密钥值) |
| POST | /dsh-turn-price/correction | 手动更改某一天的花费(填多少,那个来源当天就记多少,没有观测的日子也能填;note 可选备注;action:'reset' 撤销) |
| GET | /dsh-turn-price/ledger(?export=1) | 读账本 / 导出日账 JSON |
| POST | /dsh-turn-price/ledger/clear | 清空估算账(what=estimates)或全部记录(what=all) |
| GET | /dsh-turn-price/ping.json | 探活(宿主是否已带路由启动) |
设置路径:设置 → 每轮花费,同一节内 4 张卡片,顺序固定(模型价格在最上方)。
按模型分页签维护价格表:模型 id / 提供方 / 显示名 / 四个基础单价 / 峰谷规则 / 限时特价, 以及「恢复 DeepSeek 官方价」按钮。
余额来源列表(可增删),每行:启用开关、名称、适配器(14 个内置适配器 + none)、
匹配的 provider id(逗号分隔)、凭据名、Base URL,以及测试连接与替换密钥两个动作。
ctx.credentials),不写进配置文件、不进账本、
不出现在任何接口响应里;界面只显示「已配置 · 来源」。none 适配器表示该 provider 没有「用 API key 查余额」的接口(火山方舟、OpenAI、Anthropic、
Gemini、xAI…),界面显示 — 并只做探活 —— 不猜一个数字出来。/api/monitor/usage/quota/limit 只服务 Coding Plan 订阅账号(5h / 周额度),
其余账号一律回 HTTP 200 {"code":500,"msg":"当前用户不存在coding plan"};
现金余额在 /api/biz/account/query-customer-account-report(data.availableBalance)。
所以适配器里既有「额度」也有「余额」两档,额度档在遇到「没有 coding plan」时会自动改查余额
(鉴权失败 / 网络故障 / 超时不会回退 —— 那些是真问题),并在明细里写明这次改道。5 段的显示开关 + 上/下移动调整顺序、汇总行小数位(0–4,默认 2)、 是否显示「更新于 x 分钟前」、估算徽标与「数据不完整」徽标文案,以及一个用示例数字的预览行。
「更新于 x 分钟前」说的是余额的新鲜度(余额取数时刻),不是这一行数据的刷新时刻; 点它就会立刻催一次余额取数。「今日」「本月」这些账本金额是每轮结束就跟着会话估算一起刷新的 (2026-10-07 改:以前它们要等切会话或点按钮才更新,看起来比「会话」慢一拍)。
每次取到余额就记一次观测(默认 300 秒一次)。同一天的观测写成一行:
creditUnits 并标「待核对」,绝不算成负消费 ——
当天花费 = 期初 + 当天观测到的上升 − 期末,它与「逐次下降之和」恒等
(2026-10-07 修过一次真 bug:旧写法只看 期初 − 期末,用户充 ¥20 后「今日花费」显示 −¥17.96);action:'reset' 撤销,
回到余额差值算出来的数字。适合观测开始得晚的日子(早于观测的消费不在期初里)。openingUnits/lastUnits 仍是 null,
不动 book.lastAt),这一天标 manualOnly / sources[].manual,界面显示「手工填写」。
手填的日子算金额、不算观测天数:observedDays 与 manualDays 分开数,
hasObservation 仍是 false(手填不是观测),openingBalance 等观测事实一律 null(界面 —,不是 0)。
只能记在余额来源本上(估算本不是来源,宿主直接拒绝)。correction.note:宿主把它归一成单行、截断到 200 字符,
界面上显示在当天明细的「状态」列(已手工校正(备注:…)/手工填写(没有余额观测)· 备注:…)。
留空 = 这次修改没有备注。—),与「观测到当天消费 0 元(¥0.00)」是两种不同状态。只累计本插件运行期间发生的轮次,不回溯扫描历史会话。日归属用插件的时区偏移 (与轮尾计费时刻同一套逻辑)。「今日估算」是逐轮按各自的时刻计价再求和 —— 不能先把 token 桶合并再算一次,否则跨时段的轮次会算错峰谷价。
父会话逐轮计价 + 子会话按 tokenUsage 投影 × 单价。子会话那半边天生是近似
(投影只给会话级 4 桶、没有逐轮时刻),所以明细里会标注每个子代理按哪个模型计价;
列表被深度(5)/数量(200)/超时(3 秒)上限截断时,行内会挂「部分」标记。
按版本倒序,只列用户能感知的变化;该装哪一版见上面的〈装哪个版本〉。
| 版本 | 日期 | 一句话 |
|---|---|---|
| 0.2.3 | 2026-10-07 | 多来源余额聚合 + 手工记账改版 + 一批真 bug 修复(目前最新) |
| 0.2.0 | 2026-10-06 | 余额 / 今日 / 本月 / 会话汇总、日账与消费日历上线;密钥写入保护 |
| 0.1.1 | 2026-10-03 | 修 0.1.0「装完 dsh 起不来」 |
| 0.1.0 | 2026-10-03 | 首个版本:每轮花费 + 价格表(别装,见下) |
新增
observedDays 与
manualDays 分开数)。¥(多币种并排显示,不跨币种相加)。修复
—,还误报「没有配置密钥」;现在改成用的时候再取 +
有界重试(3 × 500 ms)+ 15 秒补试,并把「没有配置密钥」(no-key)与「宿主没拿到凭据服务」
(no-credentials-service)分开报;汇总行也不再被一条旧的失败结果一直压着。no-coding-plan 是独立分类;鉴权失败 / 网络故障 / 超时不会回退)。改版
detail 里,以前读错了字段);
「保存当天花费」按钮也不再因为宿主要求 confirmed 而永远失败。开发过程中记录的 0.2.1(智谱余额)与 0.2.2(多来源聚合)两批修复没有单独发布过, 都包含在这个 0.2.3 里。
usage 容错求和(与 dsh 内置 tokenUsage 投影逐项相等):
以前用严格折叠,「有缓存命中、缺缓存写入、缺 total」的模型(实测 79 个回合里有 15 个)
和被手动停止的回合会整轮不出金额。tokenUsage 投影,明细里标注按哪个模型计价)。DEEPSEEK_API_KEY 等),把模型密钥顶掉、整个 dsh 报 401;现在一律改道写成
TURN_COST_BALANCE_*(describe 不改道 —— 余额本来就该读模型那把密钥)。0.1.x 用户建议升级。—(四层根因叠加:显示币种被当成入账币种、Number(null) 变 0、
账本拒收 ¥ 这类符号、观测失败被吞成一行 warn)。—;— 与 ¥0.00 是两种状态)。12.85undefined(货币符号为空串时)。duplicate factory registration);这一版修掉它,请勿安装 0.1.0。raw.githubusercontent.com 在部分网络下不可达)。本仓库没有依赖也没有构建步骤,改完 lib/ 直接在本地 profile 里重启生效。
语法自检:
npm run check # node --check lib/*.js
⚠️ 本地源码改了不会自动生效:profile 里那份是从 npm 装的副本,
lib/是真实目录。 新增的lib/*.js必须同步过去(开发仓库里的tools/sync-to-profile.ps1会做这件事, 并且同步后自动跑发布清单校验)。宿主半体(lib/index.js、lib/session-usage.js、lib/http.js) 改动需要重启 dsh,只改lib/client.js刷新页面即可。
开发用的离线测试(价格引擎 / 折叠语义 / 配置 schema / 设置表单 / 主题变量纪律)在开发仓库里, 不随包发布,见 PUBLISHING.md。