← 返回列表
未验证
在统计栏追加人民币金额药丸,展开查看分项费用明细
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/12 · 已提供中文文档
DSH Web 插件:按会话显示人民币费用胶囊,渲染到编辑器已发布的统计行中
综合分
29.5
GitHub 分
29.5
用户评分
—
★ Stars
0
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add aliensweety/dsh-usage-dock该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-usage-dock
在输入框下方那排统计药丸(官方 Session 信息 + Token 用量)后面并排追加一颗只显示金额的药丸,样式与官方药丸一致、三粒作为一组居中:
[ Session 信息 ] [ Token 用量 ] [¥ 0.47]
点开是明细:未缓存输入 / 缓存读取 / 缓存写入 / 输出 / 总计 / 高峰价与空闲价两档费用 / 缓存命中率。
官方那排已经在显示 Session 与 Token 用量了,所以这颗药丸不再重复这些数字:收起态只有一个金额,其余信息放在 tooltip 与展开面板里。
费用估算口径
- 价格来源:DeepSeek 官方定价页(人民币/百万 tokens,高峰价)——deepseek-flash 输入未命中 ¥2、缓存命中 ¥0.04、输出 ¥8;deepseek-v4-pro 未命中 ¥9、缓存命中 ¥0.30、输出 ¥27。空闲档一律为高峰价的一半。
- 模型匹配:读 modelSelection 投影的 lastUsed.model,id 含 pro 按 v4-pro 计价,其余按 flash 计价。
- 只对 deepseek-official 路由计价:lastUsed.provider 是别的路由时整颗药丸不渲染。用 DeepSeek 价目表去算 Claude/GPT 的 token 会得出一个“很确定的错数字”,宁可沉默。
- 药丸上的金额:按查看时刻所处时段自动取高峰或空闲档;面板里两档始终并列展示,所以跨时段的会话其真实费用介于两者之间。
- 缓存写入不计价:官方价格表没有单独的缓存写入价(本机数据里 cacheWrite 也恒为 0),字段保留、默认 0。
价格与时段(已核对,截至 2026-09-12)
lib/client.js 里的 PRICING / isPeakNow() 与官方口径一致:
| 模型 | 档位 | 缓存命中 | 未命中 | 输出 |
|---|---|---|---|---|
| deepseek-v4-pro | 高峰 | 0.30 | 9 | 27 |
| deepseek-v4-pro | 空闲 | 0.15 | 4.5 | 13.5 |
| deepseek-v4.1-flash(含 deepseek-flash) | 高峰 | 0.04 | 2 | 8 |
| deepseek-v4.1-flash | 空闲 | 0.02 | 1 | 4 |
单位:元/百万 tokens。峰谷时段:北京时间工作日 9:00–12:00、14:00–18:00 为高峰,其余(含夜间与周末)为空闲、按高峰价的一半计。
关键点:V4 Pro 独立计费——它继续调用 V4 Pro 本身,不会路由到 V4.1 Flash(原定 2026-09-14 12:00 的路由计划已于 09-11 取消),所以两者的价目表不会互相套用。这也是本插件按 modelSelection.lastUsed.model 取价、而不是按“当前默认模型”取价的原因。
价格调整后无需改代码,在 Web 控制台执行(对所有已计价模型生效,均填高峰价):
localStorage.setItem('dsh-usage-dock.pricing', JSON.stringify({ miss: 2, hit: 0.04, out: 8, write: 0 }))
删除该 key 即恢复内置价格。
数据来源
只读 DSH 内置的会话投影 tokenUsage 与 modelSelection,不读会话日志文件、不发网络请求、不碰任何凭证。
tokenUsage 由 provider 上报的用量累加而成,整段会话一个值,带 seq 单调保护,所以它是权威值而非本地估算;它的线上视图是扁平四桶:
{ uncachedInputTokens, outputTokens, cacheReadTokens, cacheWriteTokens }
样式、位置与“明细放哪”
样式:与官方药丸逐条对齐——padding:1px 8px、border-radius:24px、gap:6px、--dsw-alias-label-tertiary 文字色与 --dsw-alias-interactive-bg-hover 悬停底色、font:inherit / line-height:inherit;宽屏带一颗 14px 图标,窄屏(≤640px)图标让位给一个 ¥ 字符,把宽度留给三个药丸。
位置:composer 下方那个 dock 是一个 column flex 容器(flex-direction:column; align-items:center),slot outlet 自己带 display:contents,所以第二个条目天然会另起一行;slot 契约里也没有“加入官方那一行”的入口(官方那颗 StatsPills 是自带排版的完整条目,也不声明子 slot)。
所以本插件用 ReactDOM.createPortal 把药丸直接渲染进官方那一排的 DOM 里(官方药丸的浮层也是用同一个 API):
- 官方那排是 display:flex; gap:12px; justify-content:center,药丸进去后自动拿到同样的 12px 间距、并和它们一起居中——不需要平移、不需要改官方任何元素、不需要测量像素;
- 靠一个 display:none 的宿主节点留在 outlet 里,只用来找那一排(data-composer-stats 标记);每次提交都重新解析,composer 重挂载换了节点、或那一排消失时会自动跟上;
- 退化行为:找不到那一排(或宿主没提供 react-dom)时,药丸退回“自己一行居中”的原状。
- 药丸带 flex:none:窄屏上被压缩的是官方那两粒(它们本来就会 ellipsis),本插件这一粒金额始终完整可读。
明细放在官方 token 用量卡里:点官方那粒 21.1M tok · Cache hit 99% 打开的卡片,本来就已经列出四个 token 桶;本插件把那两行费用(高峰价 / 空闲价)和一个估算说明追加进那张卡的同一个 :
- 那张卡的行是 dt/dd 对,而它的样式是元素选择器(.xxx_details dt / .xxx_details dd{display:grid;…text-align:right}),所以追加进去的 / 自动拿到和官方行完全一致的排版与配色,不需要写任何上游类名;
- 检测方式:那一排里最后一颗 button[aria-haspopup="dialog"] 就是官方 token 用量药丸,它 aria-expanded="true" 时出现的 div[role="dialog"] 就是它自己的卡(官方一次只开一张卡);MutationObserver 盯 document.body 的 childList,卡片一出现就写入,卡片还开着时数值变化就地更新;
- 点本插件这颗药丸 = 直接打开那张官方卡片(没有自己的浮层,所以窄屏不会再溢出);
- 写入失败(上游改了结构、宿主没给 react-dom、或那一排/那粒药丸不存在)时:药丸的金额照常显示,明细退回自带的兜底面板(该面板只在对齐到屏幕外时才翻转贴边,max-width 也限制在视口内)。
安装
从 GitHub 安装(推荐锁定 tag 或 commit)
dsh plugin --profile web add github:aliensweety/dsh-usage-dock#v0.4.0
本地开发(link 安装,改完即生效)
dsh plugin --profile web add D:\Ai\dsh\dsh-usage-dock
dsh plugin add 会把该包写进 profile 的 dependencies 与 dsh.profile.bundles(CLI 内含 bundles 与已安装依赖的对账逻辑),无需手工编辑 package.json。
profile 的 patchReload 是 live,通常热挂载;若没生效,重启 dsh web 并强刷浏览器。
验证
必须在上装的浏览器里验证:DSH Web 有信任围栏,从别的 shell 直接请求 /、/api/、/plugins/ 会拿到 401(或鉴权后的 404),curl 只能确认服务活着、证不了插件对不对。
1. 强刷界面(Ctrl+F5)。
2. 看输入框下方那排统计药丸的右侧同一行是否出现 ¥0.xx(空白会话不渲染)。
3. 点开明细,用 DSH 自己的投影缓存核对四个桶与费用:
$s = Get-Content "$env:USERPROFILE\.dsh\storages\session_projcache\sessions\.json" -Raw | ConvertFrom-Json
$s.record.rows.tokenUsage.val.totals # uncachedInputTokens / outputTokens / cacheReadTokens / cacheWriteTokens
4. DevTools → Network:应看到 /plugins/dsh-usage-dock/client.js 为 200。
Console 若出现 [dsh-usage-dock] slots service unavailable,说明没拿到 slot 服务。
排查顺序:dsh --profile web --dump-config 看 dsh-usage-dock 是否在层栈里 → 不在就重跑 dsh plugin --profile web add。
卸载 / 回滚
dsh plugin --profile web remove dsh-usage-dock
设计要点与已知限制
- 失败安全:useProjection 缺席、投影未到达、四桶全为 0(空白会话)、或路由不是 deepseek-official 时渲染 null,不留空壳、不报错。
- 不改官方元素:药丸是 portal 进官方那排的,插件不移动、不重设官方那排的位置或样式,也不碰它的数据;找不到那排时退回自己一行,卸载即消失。
- 它是估算值:会话中途换过模型、或跨高峰/空闲时段时,真实账单介于面板两档之间;药丸只按当前时段显示其中一档。
- 档位不会自己刷新:金额在重渲染时计算(新用量到达即重算),没有定时器,所以闲置会话跨过时段边界后药丸会短暂停留在旧档位。
- 金额不谎报零:fmtMoney 自动加小数位,费用非零时绝不显示 ¥0.00。
- 药丸上的数字不带货币符号:¥ 只出现在那颗 14px 图标上(官方药丸也是"图标 + 数字"的排版);面板与 tooltip 里仍带 ¥,因为那里没有图标可依赖。
- 命中率口径:cacheRead / (uncachedInput + cacheRead + cacheWrite),与官方 cacheHitPercent 同一口径(分母是提示侧计费输入,不含输出);整数四舍五入到 100% 时会自动加精度,绝不把未命中说成 100%。
- 文案按浏览器语言(zh* → 中文,否则英文),没有走 DSH 的 locale seat。
- 只报消耗,不报余额:本地不存在剩余额度数据,会话投影里也没有。
- 数字口径:总计 = 四桶之和,含 cacheRead,所以它明显大于"计费输入"——看成本时别拿它乘输入价。
- 无 React 依赖打包:客户端 bundle 走宿主注入的虚拟 react(require('react'))。
开发自检
.verify/render-check.cjs 是一个零依赖的自检脚本(自带最小 React 垫片、DOM 桩与内联 fixture——一串真实会话投影值),会加载真实客户端 bundle、走真实 slot 注册路径:
node .verify\render-check.cjs # 期望 ALL GREEN (pass=86 fail=0)
覆盖:注册契约、纯金额收起态、展开面板、provider 守卫、价格覆盖(含坏 JSON)、按模型匹配价格、命中率取整护栏、空/缺字段/无 hook 的退化输入、portal 目标识别与退化(含官方那排消失时的回退)、中英双语文案。扫码进群