@kidli1412/dsh-session-cost

usagetested: passnpmMIT

Session cost estimate in a status bar at the bottom of the conversation (per-model token pricing, CNY) plus the live DeepSeek account balance via the official balance API.

下载量 / Downloads
4,148
依赖体积 / node_modules
0.57 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add @kidli1412/dsh-session-cost

Sandbox test results

StageResult
1 install✓
2 list✓
3 mount✓
4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

README

dsh-session-cost

DSH(DeepSeek Harness)Web 插件:把本次会话的 Token 费用估算与 DeepSeek API 余额并入输入框下方的自带统计栏。

  • 费用估算:服务端按模型逐条计价——从会话事件日志折叠出每个模型的输入/输出/缓存命中 token(语义与 dsh-token-meter 的 tokenUsage 投影一致),再按 CNY 单价表(lib/cost.js)计算费用,混合多模型的会话也精确。
  • 余额查询:复用官方余额接口 GET {baseURL}/user/balance(参考插件 dsh-usage-stats 的余额方案),凭据经 DSH 的 credentials 缝解析,2 分钟内存缓存 + 单飞防抖;?refresh=1 可强制绕过缓存(状态栏的 ⟳ 手动刷新即用此参数)。
  • 每 30 秒刷新费用、每 5 分钟刷新余额;token 用量变化后自动触发费用刷新;点击统计栏里的费用 pill 展开分模型明细与余额构成(充值/赠送),面板内 ⟳ 手动刷新(强制查询上游,成功后短暂显示"已更新 HH:MM"),面板最后一行直接改低余额阈值。

界面

费用/余额是一个与自带统计项同款的可点击 pill,追加在自带统计栏同一行;若该会话自带统计栏整行都不存在(全新会话,或冷会话加载的头一秒),pill 会先独立显示在输入框上方(同一套字号/内边距/圆角),统计栏一出现就自动并回那一行:

  • 点击 pill 在统计栏上方展开明细面板,用的是自带两个 pill 点击展开时的同一套皮肤(圆角 12、--dsw-specific-menu 背景、标题 + 分隔线 + dt/dd 网格、12/18 字号):标题行左侧「费用」、右侧总额;网格里每个模型一行(输入/输出 tokens 与费用,跨峰谷时附 高峰/空闲 拆分),然后是余额与充值/赠送构成——读数网格只有数字;再往下是「更新于 HH:MM + ⟳ 手动刷新」一行,其下一行就是低余额阈值输入框(低余额阈值 [ 10 ] 元,见下);最底是计价说明。点击面板外或按 Esc 关闭。
  • 面板以 position:fixed 挂到 document.body 并做视口夹取(与原生 stat dialog 相同的 measure→place 流程、同样的 8px 间距 / 12px 边距),所以不会被任何祖先容器的 overflow 裁掉;数据更新走原地 patch(不重建节点),因此面板开着时刷新数值不会闪断、也不会丢焦点。
  • DSH 0.1.5 起自带统计栏改为 StatsPills:居中的 flex 行、由带图标的 pill 组成,取代了此前单行省略号文本的 StatsLine。本插件的 pill 因此按同一套字号层级、同一 1px 8px 内边距、同一 hover / aria-expanded 背景渲染,自带 ¥ 图标,视觉上与自带 pill 齐平。

> 0.2.1 把这一行拆了:原来一个 StatsPills 容器(data-composer-stats)装上全部读数,现在 activity(轮数/步数)与 usage(token/速度)是两个 composer-dock 条目,各自带单数 data-composer-stat;pill 圆角也从 999px 改成 --dsw-radius-sm(8px)。费用段依旧追加在同一行的末尾,只是这一行现在是 dock 容器(两个自带条目的公共父节点)——细节见下文「兼容性 0.3.2」。

  • 自带统计栏会"迟到":自带读数在会话有步骤或 token 之前渲染 null(整行都不存在;0.2.1 起是两个条目各自 null),所以插件必须能在统计栏之后挂载的情况下仍然接上去——见下文「兼容性」。
  • 数据也会迟到:刚重启 host 时首次费用/余额响应还在路上,组件却已经挂载(费用等第一次 summary、余额等上游查询或缓存)。所以观察器无条件安装:曾经在"暂时没东西可画"时干脆不装,结果没有任何人在等统计栏出现,费用段要等页面刷新(数据已被预热)才显示——这就是「每次重启后打开界面都要刷新一次」的原因。现在首个 payload 到达前 sync() 只是不画东西,观察器始终在岗。
  • 切换会话时整个输入区会被拆掉重建:打开一个没有客户端缓存的会话要等约 1 秒,这一秒里锚点处于已脱离文档的子树中。观察器过去只在"宿主仍然连在文档里"时才重新挂载自己——一次这样的回调就让它永久失效,费用段再也回不来,只能刷新页面(刷新等于重新挂载、装上新的观察器)。现在重新挂载是无条件的(脱离文档的节点依然会派发子树变更),另有一个 1 秒看门狗兜底:只要该显示的 pill 不在位(节点被 React 抹掉、统计栏被整体换掉、锚点换了父节点)就重新接回去。
  • 自带统计栏的布局一律不改:0.1.5 的统计栏是居中 flex 行(width:100%、max-width:748px、gap:12px,且不做 overflow 裁剪),追加的费用段只是这一组里的第三项,宽度本来就够——插件不写统计栏的任何行内样式。0.1.x 早期版本曾需要把统计行放宽才能显示追加段(≤ 0.1.4 的 StatsLine 有 748px 上限 + 省略号截断),那个补丁已在 0.2.3 删除。

设置项就在明细面板里、「更新于 / ⟳」的下一行:低余额阈值 [ 10 ] 元,改完按回车或点开别处即生效。从 0.3.0 起这个值作为本插件的 profile 配置保存(DSH 0.2.0 的设置模型:Config → 以 entry id session-cost 为键的表单 → 写进 profile patch),旧的 ~/.dsh/settings.yaml 阈值会被 Host 在升级后一次性抢救回配置;0.1.1 及更早版本的 localStorage 配置也会在首次加载时自动迁移。

  • 低余额阈值(默认 10 元):余额低于该值时显示为红色,达到或高于时显示为黑色。变红同时作用于明细面板里的「账户余额」和统计栏 pill 的余额读数:
0.2.6 起不再有「设置 → 插件 → 插件配置 → 会话费用显示」那张卡片:这个阈值只影响本面板与 pill 的颜色,所以编辑器搬进了面板本身(持久化的 namespace 没变,旧值原样沿用)。
0.1.5 起移除了「独立状态栏」显示方式(统计栏下方单独一行),只保留并入统计栏;旧配置里的 displayMode 键会被忽略。

展开面板内容(示例):

费用                                    ¥1.9400
────────────────────────────────────────────────
deepseek-v4-flash     输入 169,013 · 输出 46,512 · ¥1.8900
deepseek-v4-pro       输入 1,000 · 输出 500 · ¥0.0500 · 高峰 ¥0.02 · 空闲 ¥0.03
余额                                    ¥36.44
充值余额                                ¥30.00
赠送余额                                 ¥6.44
更新于 10:32                                 ⟳
低余额阈值                              [ 10 ] 元
费用为估算值:token 用量来自会话日志,单价见官方定价页(…)。

安装

从 npm 安装:

dsh plugin --profile web add @kidli1412/dsh-session-cost

从 GitHub 安装:

dsh plugin --profile web add github:KIDLi1412/dsh-session-cost

本地开发(链接安装,改动即时生效):

dsh plugin --profile web add link:path/to/dsh-session-cost

安装后重启 dsh web,浏览器硬刷新(Ctrl+Shift+R)。打开任意会话即可在自带统计行末尾看到费用与余额。

移除:

dsh plugin --profile web remove @kidli1412/dsh-session-cost

兼容性 / Compatibility

  • DSH 版本线:官方 npm 的 latest 已从 0.2.0-rc.2 移到 0.2.1-rc.5(alpha 是 0.2.2-alpha.2),0.2.0 与 0.2.1 两条线都支持;manifest 通过 dsh.compatibility.dshReleases 把 0.2.0-rc.2、0.2.1-rc.2、0.2.1-rc.5 声明为 compatible(DSH STORE 取 latest 及其前两个发行版做窗口,rc.5 就是当前窗口内的那条精确记录;仅范围声明不会恢复上架)。插件使用的客户端注入(dsh-api-remotes / dsh-client-connection / dsh-client-locale / dsh-client-ui-conversation / dsh-client-ui-settings)、客户端服务(slots / locale / configForms)与 Host 服务(webServer 精确路由、settings.describe / settings.update、credentials.resolve、session.seq + session.eventAt)在两条版本线上均已在真实安装中逐项核对(客户端注入的 5 个包在 0.2.1 的客户端模块图里、slots/locale/configForms 三个服务名、conversation.composer.dock 槽位、credentials.resolve 的 {value, source}、webServer.register 的 kind 分表与精确表优先,均逐条复核通过)。0.2.1-rc.5 上另做过一次端到端实测:插件路由返回自己的 JSON(404 unknown-session)、GET /api/session-cost/balance 返回 200 与真实余额、外站 Host 被 403 拒绝、未匹配的 /api/... 仍 401。
  • Node:^22.19.0 || >=24.0.0(与 DSH 一致)。
  • 宿主要求(dsh-market 显示):engines.dsh: ^0.2.0-rc.2 || ^0.2.1-rc.2,并将运行时依赖的 lockstep 宿主包声明为 peerDependencies(dsh-host-webserver / dsh-session / dsh-credentials / dsh-settings 与客户端模块 dsh-api-remotes / dsh-client-connection / dsh-client-locale / dsh-client-ui-conversation / dsh-client-ui-settings,均为 ^0.2.0-rc.2 || ^0.2.1-rc.2);插件市场会据此显示"宿主要求"并判断与当前 DSH 是否匹配(市场读的就是 engines.dsh 与 peerDependencies 里 @deepseek-ai/dsh* 这两处,官方市场索引则把 engines.dsh 交给同一个 evaluatePluginCompatibility)。这些包由 DSH 运行时提供、本插件从不 import,所以同时标为 peerDependenciesMeta.optional——npm/pnpm 不再把它们装进依赖树(0.2.0 起它们彼此还有 peer 关系,沿用旧的自动安装会直接解析冲突),而"宿主要求"的语义不受影响。

> 为什么是"并集"而不是单个 caret:^0.2.0-rc.2 在带 includePrerelease 的判定(DSH 挂载闸门与 dsh-market 都用它)下已经覆盖 0.2.1-rc.2,但在普通 semver 下不覆盖——semver 规定"带先行版本号的版本,只有当比较器集合里有同一个 [major,minor,patch] 元组且自身带先行版本号的比较器时才可能满足",而 ^0.2.0-rc.2 只点名了 0.2.0。npm/pnpm 的 peer

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::23,最后更新 2026-11-04

Links

GitHub · Homepage · npm

Same category