DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

BigFatFish4Wm /

BigFatFish4Wm/dsh-token-cost

Verified

DSH plugin: per-turn token usage, cost, session totals and account balance in the Harness Web UI, with a workspace-local ledger.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@b5949745

Token Cost & Balance (dsh-token-cost)

在 Harness Web UI 的每一轮已完成对话下方显示本轮 token 用量、费用、会话累计和当前余额。数据按“会话 + 轮次”持久化到工作区内的 JSON 账本,后续对话不会覆盖旧记录;刷新页面、重开 Harness 或重新打开历史会话后仍可还原。

功能

  • 每轮用量条:显示本轮总 tokens、费用、本会话累计和当前余额;可展开查看输入、输出、缓存读取、缓存写入、推理 tokens。
  • 精确到模型路由:按每条 Assistant 消息的 provider/model 选择单价;同轮混用多个模型时分别计价并汇总。每次 attempt 按其事件时间判断高峰/空闲价,跨时段也能正确拆分。
  • 余额三种来源:
    • account:通过 Host 的 deepseekAccount.getBalance() 读取 DeepSeek 账户余额,含充值钱包与赠送钱包;
    • budget:配置初始预算,显示“初始预算 − 工作区账本累计消费”;
    • manual:显示固定余额。
    • auto 会依次尝试 account → budget → manual。
  • 持久化:默认写入 <工作区>/.dsh-token-cost/ledger.json,按 Session 和 Turn 去重合并;插件重载时会回填当前存活会话中已完成的轮次。
  • 完整配置:单价、按模型覆盖单价、货币、显示密度、小数位、余额来源、刷新周期、账本目录/文件名、是否记录子代理等都可配置。
  • 双语:内置简体中文与英文界面;数字、时间和费用按当前 Harness 语言格式化。
  • 安全路由:Host 只暴露一个摘要路由,并复用 Harness 的 connection.requestRejection 鉴权;没有 connection 服务时仅允许回环地址与同源请求。

界面位置

注册在 conversation.chat.turnTail 槽位,order = 30,位于内置交付文件卡片、计划卡片之后、完成轮次操作行之前。条目 id 为 token-cost,不会替换任何内置条目。

展开后可以看到:

  • 本轮 token 分项与请求数、模型;
  • 本轮费用、会话累计、工作区账本累计;
  • 每个模型路由的 tokens、费用与每百万 token 单价;
  • 余额来源、钱包明细、更新时间;
  • 账本文件绝对路径和累计已保存轮数。

数据文件

默认:

<session workspace>/.dsh-token-cost/ledger.json

结构(节选):

{
  "version": 1,
  "updatedAt": 1760000000000,
  "sessions": {
    "<sessionId>": {
      "updatedAt": 1760000000000,
      "turns": {
        "3": {
          "turn": 3,
          "status": "completed",
          "inputTokens": 12000,
          "outputTokens": 800,
          "cacheReadTokens": 9000,
          "cacheWriteTokens": 0,
          "reasoningTokens": 200,
          "totalTokens": 21800,
          "cost": 0.0216,
          "currency": "CNY",
          "routes": [],
          "incomplete": false,
          "recordedAt": 1760000000000
        }
      }
    }
  }
}
  • 账本使用“临时文件 + rename”原子替换;写入按文件串行化。
  • 如果已有文件损坏,会先改名为 ledger.json.corrupt-<timestamp> 再重建,避免静默丢数据。
  • storage.dir 只会落在工作区内;配置成绝对路径或 .. 越界时回退到 .dsh-token-cost。
  • 费用是写入时的快照;之后修改单价不会重写历史账本,符合“账本”语义。界面上的本轮/会话费用会按当前配置实时重算,便于调价后对比。

配置

在 profile 的 cordis.patch.yml 中覆盖 token-cost 行,或在插件配置页中编辑。所有字段都有默认值。

- id: token-cost
  name: 'dsh-token-cost'
  config:
    enabled: true
    currency: CNY
    currencySymbol: '¥'
    pricing:
      inputPerMillion: 1
      outputPerMillion: 4
      cacheReadPerMillion: 0.02
      cacheWritePerMillion: 1
      peak:
        inputPerMillion: 2
        outputPerMillion: 8
        cacheReadPerMillion: 0.04
        cacheWritePerMillion: 2
      offPeak:
        inputPerMillion: 1
        outputPerMillion: 4
        cacheReadPerMillion: 0.02
        cacheWritePerMillion: 1
    pricingSchedule:
      enabled: true
      timeZone: Asia/Shanghai
      peakWindows:
        - { start: '09:00', end: '12:00' }
        - { start: '14:00', end: '18:00' }
      weekdays: [1, 2, 3, 4, 5]
      holidays: []
    modelPricing:
      deepseek-account/deepseek-v4-pro:
        inputPerMillion: 4.5
        outputPerMillion: 13.5
        cacheReadPerMillion: 0.15
        cacheWritePerMillion: 4.5
        peak:
          inputPerMillion: 9
          outputPerMillion: 27
          cacheReadPerMillion: 0.3
          cacheWritePerMillion: 9
      'openai/*':
        inputPerMillion: 2.5
        outputPerMillion: 10
    display:
      showInput: true
      showOutput: true
      showCache: true
      showCost: true
      showSessionCost: true
      showBalance: true
      showDetails: true
      compact: false
      decimals: 4
    balance:
      mode: auto
      refreshSeconds: 60
      timeoutMs: 5000
      locale: zh
      budgetInitial: 100
      manualAmount: null
      showBonus: true
    storage:
      enabled: true
      dir: .dsh-token-cost
      file: ledger.json
      backfill: true
      includeSubagents: true

字段说明

字段 默认 说明
enabled true 总开关;关闭后不注册投影、路由和账本。
currency CNY 费用与预算使用的币种;账户余额钱包保留自己的币种。
currencySymbol 空 自定义符号;空值按币种推导(CNY/JPY ¥、USD $ 等)。
pricing.inputPerMillion 1 空闲时段未缓存输入,每百万 tokens 单价。
pricing.outputPerMillion 4 空闲时段输出(含推理)每百万 tokens 单价。
pricing.cacheReadPerMillion 0.02 空闲时段缓存命中读取每百万 tokens 单价。
pricing.cacheWritePerMillion 1 空闲时段缓存写入每百万 tokens 单价(DeepSeek 未单列写入价时按未命中输入价)。
pricing.peak 见上 高峰时段单价表;字段同平级四项,未填字段继承 pricing 平级值。
pricing.offPeak 见上 空闲时段单价表;字段同平级四项。
pricingSchedule.enabled true 是否按时间窗口选择 peak/offPeak。关闭后只使用 pricing 平级值。
pricingSchedule.timeZone Asia/Shanghai 高峰窗口所在 IANA 时区。
pricingSchedule.peakWindows 09:00–12:00、14:00–18:00 高峰窗口,含起点不含终点。
pricingSchedule.weekdays [1,2,3,4,5] 可能为高峰的 ISO 星期(1=周一,7=周日)。
pricingSchedule.holidays [] YYYY-MM-DD 节假日,全日按空闲价。
modelPricing {} 按键覆盖单价。匹配顺序:provider/model → provider::model → provider/* → model → * → 默认。每项可含平级字段、peak、offPeak;未提供的子字段继承该模型的平级值。
display.showInput true 明细中显示未缓存输入。
display.showOutput true 明细中显示输出。
display.showCache true 明细中显示缓存读取/写入。
display.showCost true 收起状态显示费用。
display.showSessionCost true 收起状态显示会话累计。
display.showBalance true 收起状态显示余额。
display.showDetails true 允许展开明细。
display.compact false 使用更紧凑的间距。
display.decimals 4 费用小数位(0–8)。
balance.mode auto auto / account / budget / manual / off。
balance.refreshSeconds 60 账户余额缓存时间;0 表示每次请求都重新读取。前端最短 15 秒刷新。
balance.timeoutMs 5000 单次账户余额读取超时。
balance.locale zh 传给账户 API 的语言元数据。
balance.budgetInitial 空 预算模式初始值;auto 下作为账户不可用时的回退。
balance.manualAmount 空 手动余额;auto 下作为最后回退。
balance.showBonus true 是否显示赠送钱包。
storage.enabled true 是否写工作区账本。
storage.dir .dsh-token-cost 工作区相对目录。
storage.file ledger.json 账本文件名(只取 basename)。
storage.backfill true 插件激活时回填当前存活会话的已完成轮次。
storage.includeSubagents true 是否把子代理会话写入账本。子代理仍会显示自己的用量条。

pricing.peak / pricing.offPeak 是可选对象。省略整个 profile 时:若平级单价仍是默认值,peak 使用官方高峰价、offPeak 使用官方空闲价;若平级单价已自定义,则二者继承平级值。显式字段优先。这样自定义固定单价时不会意外套用 DeepSeek 高峰价。

修改 cordis.patch.yml 后由 Loader 热重载;如果浏览器没有立即更新,刷新页面即可。修改客户端 UI 代码需要重启 Host 或重新加载插件。

计价口径

每条 Assistant 使用的 token 口径与 Harness 内置 token-meter 一致:

  • inputTokens:未缓存输入 tokens;
  • cacheReadTokens:缓存命中读取;
  • cacheWriteTokens:缓存写入;
  • outputTokens:输出 tokens(reasoningTokens 是其中的子集,不额外重复计费)。

每个 usage 样本记录在其 assistant/message / assistant/attempt 事件时间上;计价时用该时间判断高峰/空闲,再用对应单价:

window = isPeak(event.time, pricingSchedule) ? peak : offPeak
cost(attempt) =
  uncachedInput / 1e6 * window.inputRate
  + output / 1e6 * window.outputRate
  + cacheRead / 1e6 * window.cacheReadRate
  + cacheWrite / 1e6 * window.cacheWriteRate
turn.cost = Σ cost(attempt)

默认单价取自 DeepSeek 开放平台 2026-10-24 的公开价(deepseek-flash:空闲输入 1 元 / 输出 4 元 / 缓存命中 0.02 元,高峰翻倍;每百万 tokens,人民币)官方价格页。DeepSeek 的高峰时段为北京时间周一至周五(不含法定节假日)09:00–12:00、14:00–18:00;pricingSchedule.holidays 可补充当年法定节假日。价格会调整,部署时请以官方页面为准并覆盖配置;deepseek-v4-pro 等其它模型请在 modelPricing 中配置。

  • pricingSchedule.enabled: false 时忽略 peak/offPeak,只使用 pricing 平级值;适用于固定单价或其它供应商。
  • 同一轮内跨高峰/空闲,或跨多个模型时,费用会按每次 attempt 分别计算,详情按“模型 + 价格窗口”拆行。
  • 重试(llm/retry-started)会结束当前替换槽,重试尝试的用量会再次累加,避免只取最后一次而漏计费。若某条 Assistant 没有上报 usage,界面会标“部分未上报”,费用显示为下限(≥)。余额与费用都只用于展示,不参与 Harness 的上下文或压缩决策。

工作原理

Session event log
      │
      ▼
tokenCost 投影(Host)── 每轮 attempts / tokens / cost / session totals
      │                         │
      │                         └── turn/end → ledger.json(工作区)
      ▼
Web Client turnTail 条目 ── 订阅投影,显示每轮条
      │
      └── GET /api/token-cost/summary?sessionId=… → 余额 + 账本摘要
  • 投影:纯同步 fold,状态是 plain JSON;无关注事件返回同一引用,避免无谓刷新。状态被 Harness 的 projection cache 检查点化。
  • 客户端:不自己解析 Session 日志;通过 session.projections.faceOf('tokenCost') 读取 Host 计算好的视图。
  • 余额路由:只允许 GET;会话必须仍存活于 Host;返回 Cache-Control: no-store。账户余额在 Host 进程内缓存,避免多个浏览器标签重复打 Platform。
  • 持久化:投影是派生数据;账本是独立的工作区文件。即使投影缓存被清空,Session 日志仍可在下次打开时重新折叠出每轮数据。

安装

前置:DSH(DeepSeek Harness)本体、Node ≥ 22。

Web(dsh web)

dsh plugin --profile web add github:BigFatFish4Wm/dsh-token-cost

装完重启 dsh web,再按 Ctrl+F5 刷新浏览器。

克隆到本地后也可以用本地目录安装:

dsh plugin --profile web add link:<本目录绝对路径>

桌面端(官方 Electron 客户端)

dsh plugin 按设计不碰 desktop profile。在客户端的插件市场里,来源填:

https://github.com/BigFatFish4Wm/dsh-token-cost

装完若界面里没有出现,完全退出客户端(含托盘)再打开。

安装后在插件页启用(若未自动启用),或在 profile 的 cordis.patch.yml 中保留 token-cost 行。替换已安装包通常需要重启 Host 以加载新的 Host JavaScript。

故障排查

  • 条形条没有出现:确认 conversation.chat.turnTail 槽位有 token-cost 占用者;确认本轮至少有一条 Assistant 消息或未上报标记。空白会话不显示。
  • 余额显示“不可用”:账户未登录、deepseekAccount 未组合、Platform 请求失败,或 balance.mode 配置为 account 且没有可用钱包。切换到 auto 并配置 budgetInitial / manualAmount 作为回退。
  • 余额没有更新:前端最短 15 秒刷新一次;点开明细后点“刷新”可立即重读。Host 端还会按 refreshSeconds 缓存。
  • 账本没有写入:检查 storage.enabled、工作区是否只读、storage.dir 是否可写;展开明细查看 ledger.error。如果账本损坏,会在同目录留下 .corrupt-* 副本。
  • 费用不对:确认 currency 与 pricing 一致;用 modelPricing 覆盖具体模型。缓存读取/写入的单价是独立字段,不是“输入折扣”。若使用了高峰/空闲价,检查 pricingSchedule.timeZone、peakWindows、weekdays 和 holidays;当前 attempt 事件时间是否落在高峰窗口决定单价。关闭 pricingSchedule.enabled 可退回固定单价。

验证状态

  • Host fold / pricing / ledger 有独立单元测试:node test/core.test.mjs。
  • Client 组件有零依赖的渲染探针(mock React + mock Host 报告):node test/client-render.test.mjs。它覆盖收起态、展开态、余额钱包、账本路径和 Turn 定位。
  • 插件 JS 语法、JSON、patch YAML、manifest 和 SVG 在安装前校验。
  • 已安装到当前 profile 并激活;Cordis Inspect 确认 tokenCost 投影所在 Host 插件行 active、conversation.chat.turnTail 中 token-cost 占用者 active。
  • 已从真实会话日志回填并持续写入 .dsh-token-cost/ledger.json;跨轮次数据保留。
  • 余额摘要路由通过 Host mock 测试覆盖 200/403/账本/账户钱包;真实路由受 Harness 的 HttpOnly 会话 cookie 保护,外部 Invoke-WebRequest 正确返回 401。视觉渲染(不同主题、窄屏、真实浏览器控制台)仍以当前环境的浏览器控制能力为准;没有浏览器控制时只能给出注册级与组件级验证,不能声称已截图验证。
—/ 5

No ratings yet

Verified DSH bundle

Commit b59497459e97

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout