🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

会话费用计 dsh-plugin-db/dsh-cost-meter

DeepSeek Harness
dsh-plugin-db15 天前有提交已提供中文文档扫描:无法判定

在输入框下实时显示会话花费与余额

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/17 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-plugin-db/dsh-cost-meter
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · model
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 15 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
⚪ 扫描:无法判定尚无人工评估
展开查看扫描说明与证据 ↓

已尝试扫描但取不到可分析的源码:仓库或包不存在、已删除,或为非 JS/TS 实现、未随包发布源码。无法判定,不代表安全。

  • · 取源不可用(Error: github tarball HTTP 404 @ https:
  • · api.github.com
  • · repos
  • · dsh-plugin-db
  • · dsh-cost-meter
  • · tarball)
扫描于 2026/11/1(0 天前)

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

会话开销与服务商余额显示在 DeepSeek Harness Web 输入框下方。

README

由 DeepSeek 最新模型翻译生成
dsh-cost-meter 一个 DeepSeek Harness 插件,在 Web 输入框下方显示一行常驻信息:当前会话以及它启动的每个子代理会话的预估模型费用,外加所用服务商路由的剩余余额。 [ Composer card ] Cost $0.1306 · Balance $12.50 把鼠标悬停在标签上,会显示明细:各模型路由的 token 分项、总额里有多少来自子代理会话、按请求计费的费用,以及余额中充值额度与赠送额度各占多少。 这个数字包含什么 - 当前会话,按服务商自己日志里上报的用量计价。 - 它委派出去的每个子代理会话,含传递关系。子代理作为独立 Session 运行,有自己的日志,所以父会话日志只记录子会话的名字(subagent/catalog),从不记录它们的用量;插件改为读取每个子会话自己投影出的费用——应用还持有该会话时从实时 Session 读,会话结束后从它的持久检查点读,没有检查点可用时则重新折叠该子会话自己的日志(见下文)。 - 按请求计费的费用,针对那些不走 token 用量计费的调用,目前是 DeepSeek Search/Fetch 请求,每 1,000 次成功请求 $0.75。请求事件只记录请求本身,不记录用量,所以这是一个明确标注的估算值。
展开完整文档(README 剩余 1 节)
dsh-cost-meter

一个 DeepSeek Harness 插件,在 Web 输入框下方显示一行常驻信息:当前会话以及它启动的每个子代理会话的预估模型费用,外加所用服务商路由的剩余余额。

[ Composer card ]
Cost $0.1306 · Balance $12.50

把鼠标悬停在标签上,会显示明细:各模型路由的 token 分项、总额里有多少来自子代理会话、按请求计费的费用,以及余额中充值额度与赠送额度各占多少。

这个数字包含什么

- 当前会话,按服务商自己日志里上报的用量计价。
- 它委派出去的每个子代理会话,含传递关系。子代理作为独立 Session 运行,有自己的日志,所以父会话日志只记录子会话的名字(subagent/catalog),从不记录它们的用量;插件改为读取每个子会话自己投影出的费用——应用还持有该会话时从实时 Session 读,会话结束后从它的持久检查点读,没有检查点可用时则重新折叠该子会话自己的日志(见下文)。
- 按请求计费的费用,针对那些不走 token 用量计费的调用,目前是 DeepSeek Search/Fetch 请求,每 1,000 次成功请求 $0.75。请求事件只记录请求本身,不记录用量,所以这是一个明确标注的估算值。

如果某个子会话完全读不到——既没有实时 Session,也没有生命周期匹配的检查点——插件不会假装它没花钱。它会把总额标为下限(at least $0.1306),并说明有多少会话读不到,而不是给出一个看起来精确的数字。

总额为什么仍可能与 <https://platform.deepseek.com> 的用量日志不一致:那个页面按账号计费,所以它也涵盖这台机器从未运行过的会话,以及用同一个 key 的其他客户端。有些辅助模型调用的用量从不记录(会话标题,以及搜索请求可能扇出到的 DeepSeek 侧搜索调用,每次请求最多 maxUses 次),DeepSeek 会为它们计费,但任何基于日志的读取都看不到。因此插件只根据日志记录的内容估算,并把这个结果标注为估算。

要求

- 带 Web 应用的 DeepSeek Harness(dsh web)。读取余额需要 connection 和 credentials 服务,随附的 Web 组合已提供。
- 余额标签需要一个钱包端点,以及为它存储的凭据;内置默认值是 DeepSeek 的 Platform 余额端点,凭据引用为 DEEPSEEK_API_KEY。费用不需要任何配置:价格随行配置一起发布。

安装

1. install the package into a profile
dsh plugin --profile web add github:dsh-plugin-db/dsh-cost-meter

…or from a local checkout
dsh plugin --profile web add link:/path/to/dsh-cost-meter

2. 启用该 bundle:Settings → Plugins → Installed → dsh-cost-meter → on。(由智能体驱动插件管理器时,用 install_bundle 一步完成这两步。)
这个包附带一个 bundle 补丁,启用后会插入一行,带上内置默认值。费用立即生效;余额胶囊要等钱包数据源返回后才出现。凭据引用在 Host 上解析,所以密钥永远不会到达浏览器。

配置

所有值都放在行配置里,因此能随 DSH 升级保留在配置档自己的 cordis.patch.yml 中(最高优先级层):

- id: dsh-cost-meter
name: 'dsh-cost-meter'
config:
prices:
- provider: '' # '' matches any route; a literal provider wins over ''
model: deepseek-flash
currency: USD
input: 0.3 # per 1M cache-miss input tokens
output: 1.2 # per 1M output tokens
cacheRead: 0.006 # per 1M cache-hit input tokens
cacheWrite: 0.3 # optional; defaults to input
offPeak: # optional; used outside peakWindows
input: 0.15
output: 0.6
cacheRead: 0.003
cacheWrite: 0.15
peakWindows: # optional; defaults to DeepSeek's published windows
- { startHourUtc: 1, endHourUtc: 4, weekdaysOnly: true }
- { startHourUtc: 6, endHourUtc: 10, weekdaysOnly: true }
balances: # optional; provider route → wallet endpoint
- provider: deepseek-official
url: https://api.deepseek.com/user/balance
credential: DEEPSEEK_API_KEY # credential reference resolved in the Host
auth: bearer # or x-api-key
timeoutMs: 10000
fees: # optional; Session events that are billed per request
- event: web/deepseek-search-llm-request
label: Search
per1kRequests: 0.75 # DeepSeek Search/Fetch list price, USD
currency: USD

查找优先级是 provider+model → provider+ → +model → +。没有匹配行的路由仍会显示 token 数;只要还有未定价的调用,费用胶囊就会带上「at least」前缀,估算值绝不假装完整。

fees 行统计该确切类型的 Session 事件,按每 1,000 次请求计费,独立于 token 定价——DeepSeek 就是这样给 Search 和 Fetch 调用计费的。默认行覆盖 web/deepseek-search-llm-request,也就是 Web 应用的 DeepSeek 搜索功能为每次搜索请求记录的事件。设 fees: [] 就只给 token 定价。

随包附带的默认值是 DeepSeek 公布的 deepseek-flash 和 deepseek-v4-pro 列表价(每 1M token,USD),以及它们的峰谷时段和 Search/Fetch 按次费用。价格会变,请在配置档补丁里改。

余额

Client 分两步读取余额,并报告结果:

1. 通过 ctx.remote.account.getBalance 读取已登录的 DeepSeek 账号,适用于 provider 以 deepseek 开头的路由。
2. 询问本插件的 Host 路由,要它给出会话正在消费的确切路由 on。Host 拿这个服务商去匹配 balances(精确匹配的服务商优先于 ),通过 ctx.credentials 解析指定的凭据,调用端点,然后只返回钱包金额。

如果某条路由 Host 没有为它定价任何钱包(unsupported-provider),就什么都不显示,所以对于根本没有 balances 行的服务商,这个胶囊永远不会出现。其他所有结果都可见:钱包读取成功时显示金额,凭据缺失、端点失败或路由完全不响应时显示 Balance —,并在 tooltip 里给出原因。这个原因会带上 HTTP 状态码和响应体,正好区分两种静默失败:当这个构建的路由没有挂载时,浏览器看到 404 not found;当请求根本没到达路由时,看到 401 unauthorized。

密钥永远不会到达浏览器,端点就是普通配置:另一个服务商的 API 返回钱包时,需要新增一行 balances,再在 index.js 里加一个解析器类型。金额每分钟重新读取一次;每个胶囊自带货币,所以 USD 成本和 CNY 余额永远不会混淆。

它是怎么构建的

| 一半 | 文件 | 作用 |
| Host | index.js | 两个 sessionProjections 单元 —— costMeter(为服务商上报的用量和每请求费用定价)和 costMeterFamily(本会话加上它委派出去的所有会话)—— 外加 Connection 的 /api 通道上的一条余额路由 |
| Client | client.js | 一个 conversation.composer.dock 条目,渲染 family 线上值,回退到会话值,在投影还不完整时向 Host 请求 family 读取,并读取余额 |

Host 折叠持久化的 Session 日志,发布两个客户端可见的投影;Client 通过 useProjection 插槽 prop 渲染它们。两半都只针对有文档的接缝编写:

- ctx.sessionProjections.register({key, stateVersion, stateSchema, init, apply, wire}) —— 投影单元;注册表只调用 schema.parse,所以这里的 schema 是手写的小型规范化器,不依赖任何 schema 库。
- SessionEvent 信封和载荷:request/header(路由)、assistant/message / assistant/attempt(用量,来自 data.usage 或紧凑流的最后一个 usage chunk)、llm/retry-started(重试替换槽位)、compaction/summary(它自己的路由和用量)、subagent/catalog(这个会话启动了哪些子会话,附带检查点身份所需的创建时间)以及 web/-llm-request(每请求费用)。无法识别的事件返回同一个状态引用,注册表的 Object.is 门控会把它变成零下游工作。
- ctx.slots.inject(key, () => ctx.slots.register(options, Component)) 以及插槽标准的 useProjection prop。
- ctx.locale.register(ns, dicts),并在插槽注册时带上 locale: ns。
- 行 Config 是一个 Standard Schema 对象(~standard.validate),它正是 Cordis resolveConfig 读取的内容,所以不需要导入 schemastery。(Config 检查器会把这种 schema 报告为 unsupported,因此 Plugins 页面不会生成表单;请改为在 YAML 中编辑这些值。)
- 两条精确 Fetch 路由位于 Connection 的 /api 通道上: /api/dsh-cost-meter.balance 和 /api/dsh-cost-meter.family。第二条之所以存在,是因为投影视图是同步的,而已结算的子代理会话只能异步重新折叠;当投影仍报告未解析的子项时,Client 就会请求它,因此页面加载后一秒内就会出现精确总计,而不是等到该会话的下一个事件。这次读取会填充投影视图所读取的缓存,所以从那时起推送的值就是完整的。
- 余额来自两条有文档记录的读取路径:已登录账户使用生成的 Client 命名空间 ctx.remote.account.getBalance(metadata),API-key 路由则使用本插件自己的精确 Fetch 路由,位于 Connection 的 /api 通道上(/api/dsh-cost-meter.balance)。该路由注册在一个单独的可选子 fiber 上,该 fiber 注入 connection 和 credentials,Client 用页面的普通 fetch 访问它——这与已发布的 UI 插件使用的模式相同(例如 dsh-client-ui-deliverables 中的 /api/present.open,dsh-session-log-export 中的 /api/session.export),也不需要解析任何 Client 服务。有两个细节被固定下来,因为弄错会悄无声息:
- 精确路由必须是直接位于 /api 下的一段(assertFetchRoute → endpointFromPath('/api', path)),这就是路径用点号而非嵌套的原因。
- 不使用 connection.rpc.handle:它把路由挂载在调用方的上下文上(owner.webServer.register(route)),所以除非该 fiber 也声明 webServer,否则它就会失效;而 connection.fetch.register 只写入 Connection 自己的路由表。verify.mjs 固定了依赖列表和路由形状。

两条读取路径在运行时都是可选的(ctx.get()),所以即使组合中没有它们,插件仍会激活并仍会显示成本。不导入任何 Harness Client 包,不写入组件之外的 DOM,不追加任何会话事件,也不会有任何凭据离开 Host 进程:余额路由只返回钱包金额。

读取子代理的花费

子代理是单独的会话,所以 family 单元必须读取另一个会话的投影。有三条约束决定了它的做法,每一条都至关重要:

- 投影 wire.view 在每次读取时都会被调用,包括没有活动会话的持久检查点路径(viewCheckpoint),而注册表没有重入保护。因此 family 视图从自己的状态计算自己的花费(同样的折叠,运行两次),并且从不读取自己会话的单元格——只读取子项的。
- 视图必须同步,这就排除了 sessionQuery.observeSession —— 它是唯一会重新折叠冷会话完整日志的读取方式。所以先实时读取子会话,再从缓存变冷时写入的持久检查点读取(与 dsh-session-reference 相同的先实时后缓存形态),最后才从异步填充的缓存读取。cachedSnapshot 以头部作为身份凭证,并匹配 version、createdAt、cwd 和 isSeeded;父会话自己的头部提供了除 createdAt 之外的所有字段,而 createdAt 由 subagent/catalog 记录为 childCreatedAt。
- 版本门控正是第三个来源无法避免的原因。在某个单元存在之前写入的检查点根本不会为它保留任何行,而注册表会丢弃 stateVersion 与注册值不符的行,因此一个在旧版本下完成并已稳定的会话,对任何键的检查点读取都不会有响应。插件因此通过 sessionQuery.observeSession 折叠这样的子会话(异步执行,所以无法在视图内运行),缓存结果,并在视图未命中时请求该折叠。已稳定会话的开销不会变化,所以每个子会话折叠一次就够了;再次运行的子会话会重新实时读取。
- 否则客户端要等到该会话的下一个事件才能看到填充后的值,因为宿主只在会话提交时推送投影 —— 已发布的载体中没有心跳,也没有轮询。这正是家族路由的用途:客户端在自己的值不完整时请求读取,并在两者中优先采用能看到更多的那一个。
- 每次读取都受控且有循环防护。缺失、不可读或生命周期检查失败的子会话保持未解析:它计入 unresolved,绝不算作零,胶囊显示 at least …。子会话自己的 costMeterFamily 值已经包含其后代,这让本次遍历保持一层深度,并且孙会话只被计数一次。

验证

node verify.mjs 运行 50 项无依赖检查,不需要浏览器,也不需要运行中的配置档:Config schema、余额路由的依赖列表与形态、折叠的定价与替换规则、按请求计费、家族折叠及其实时/持久/缓存的子会话解析(包括不可读的子会话和抛出异常的查找)、家族路由对已稳定子会话和孙会话的两阶段预热、投影的自愈未命中、余额路由的每种结果,以及客户端半部分的 fake-React 渲染,证明 dock 条目同时输出费用胶囊和余额胶囊,显示家族总计及其子代理和费用明细,在没有家族值时降级为会话值,将任何来源都无法读取的子代理标记为下界,仅在路由比投影看到更多时优先采用路由,在无法读取钱包时报告 Balance — 及上游原因,报告未挂载路由及其 HTTP 状态,并对以下情况保持静默:没有配置钱包的路由。它 stub 了框架,而不是导入框架,所以只有当这个插件自己对接缝的使用发生变化时,它才会失败。

折叠结果与真实会话中实际发布的 tokenUsage 投影做了交叉核对(桶总计完全一致),峰值/非峰值的选择也做了单元检查。上游钱包用存储的密钥调用了一次,返回 HTTP 200,钱包载荷符合预期。

插件自己的路由无法从 shell 里跑通:它位于 Connection 的 Host/Origin 围栏和浏览器 cookie 认证之后,无论 /api 路径是否注册,都会返回 401。shell 能* 证明的是,运行中的 Host 确实加载了这个构建——见下文。

给插件作者的话

Host 进程在启动时一次性导入插件模块,之后不再重新读取:harness 运行期间编辑 index.js 不会有任何变化,而「重启」如果并没有真正替换进程(第二次 dsh web 绑不上端口,或者刷新页面),旧构建会继续服务。Client 那一半是例外——它按请求提供,带一个由 mtime 推导出的修订号,所以刷新页面总能拿到 client.js。

因此 STATE_VERSION 同时也是构建代号。会话投影检查点($DSH_HOME/storages/session_projcache/sessions/<id>.json)会按行记录这个版本,所以 ver 是从外部判断运行中的进程实际加载了哪个构建的唯一办法:

python3 -c "import json,sys; print(json.load(open(sys.argv[1]))['record']['rows']['costMeter']['ver'])" \
"$DSH_HOME/storages/session_projcache/sessions/<session-id>.json"

第 2 代是第一个余额读取走精确 Fetch 路由的版本;第 3 代加入了按请求的费用累加器。family 单元和 spend 单元注册在同一版本下,所以旧构建写出的检查点没有 costMeterFamily 行,family 视图会直接回退到实时读取,或者在该子项再次运行之前把它报告为未解析。
预览分享卡片长什么样 ↓dsh-plugin-db/dsh-cost-meter
分享 · DeepSeek Harness Hub
dsh-plugin-db/dsh-cost-meter

在输入框下实时显示会话花费与余额

回到顶部