Angelyeye/dsh-cost-tracker

Angelyeye/dsh-cost-tracker

统计 DeepSeek Harness 的 LLM Token 用量与花费(人民币、峰谷计价),提供设置面板、Agent 工具、HTTP 接口与持久化存储。

用量与计费cordiscost-trackingdeepseek-harness

icon DSH Cost Tracker · 花费统计

DEEPSEEK HARNESS LLM 花费与用量统计插件

简体中文 | English


一个为 DeepSeek Harness 打造的 LLM 花费统计插件:自动记录每一次 API 调用的 Token 用量与费用(人民币),原生支持 DeepSeek 官方峰值价格计费(高峰 / 闲时半价自动区分)与 Kimi Coding Plan 订阅套餐的用量及等效费用统计。设置页可视化仪表盘、图表悬停明细、对话内 Agent 查询、账户余额与订阅配额监控,数据全部本地持久化——重启不丢、卸载无痕。

An LLM cost-tracking plugin for DeepSeek Harness: records token usage and cost (CNY) for every API call, with native support for DeepSeek's official peak/off-peak pricing and Kimi Coding Plan subscription usage & equivalent-cost statistics. Visual settings dashboard with hover tooltips, in-chat agent queries, balance & quota monitoring — all persisted locally.

花费统计仪表盘:概览卡片 + 按峰谷分段的消费柱状图,悬停显示明细


它能做什么?

功能说明
💰花费统计每一次 API 调用自动记账:输入 / 输出 / 缓存命中 / 缓存写入 Tokens 与费用(缓存写入按缓存命中价计),按天、按模型聚合
⏰峰谷定价内置单价表,高峰时段(北京时间周一至周五 9:00–12:00、14:00–18:00,不含中国法定节假日)与闲时半价自动区分,周末与法定节假日全天计为闲时(节假日表 2026 全年 33 天,可在配置页覆盖/停用;调休补班的周六周日不计高峰),本地模型(ollama 等)计 0;单价表按「计费时代」分版(legacy / v41),北京时间 2026-09-10 12:00 起自动切换为 V4.1 Flash 新价(2.0 / 0.04 / 8.0 高峰),并按官方脚注把旧 V4-Flash 系请求路由到 V4.1 Flash 计费;deepseek-v4-pro 维持自有牌价 9.0 / 27.0 / 0.30 不做路由(官方 2026-09-14 撤销了下线计划)
🔔峰谷计价提示设置 → 花费统计 → 右上角齿轮 → 峰谷计价与提示(v1.9.0 起设置集中在此,改完即可预览;DSH 0.1.7-alpha.2 起入口在「花费统计」页头的齿轮,v1.9.3):当前档位/距下次切换倒计时时段条、样式切换(简洁单行·按24h比例 / 环形表盘·相位色点)、简洁样式可选双行紧凑(上下布局,条上文下/文上条下)、「显示时间」开关、峰/谷切换前弹窗提醒与浏览器系统通知、提前提醒分钟、弹窗位置(右下角/屏幕中心)、提醒类型;侧边栏底部常驻显示时段条(窄栏/展开自适应)。看板上的同名面板改为只读回显
📌六组概览卡设置页顶部六张卡:今日费用 / 本月费用 / 总花费 / API 请求次数 / Tokens / 总余额。前三个金额卡不含订阅会员等效费用,订阅以附注展示
👁️视觉模型支持 deepseek-v4-flash-vision-exp:legacy 时代单价与 flash 一致,2026-09-10 12:00 起随 V4.1 Flash 新价计费(该旧名已下线,请求由 V4.1 Flash 提供);图片按官方规则换算 token(每张上限 384 个,以接口用量计费)
🏷️官方模型名对齐计费支持官方现役名 deepseek-flash(价格卡脚注 (1):「模型名请使用 deepseek-flash」),旧写法 deepseek-v4.1-flash 等归一化后命中同一档价,避免因官方改名而落入兜底估算
📊可视化仪表盘设置页新增「花费统计」:概览卡片、消费柱状图(按峰谷/按模型)、分模型的请求次数与 Tokens 图表,全部支持鼠标悬停查看明细
🧭多机汇总(云端同步)可对接自建云端服务(独立仓库 dsh-cost-cloud,零运行时依赖):多台电脑的用量汇总到一处,看板顶部出现 本机 / 本机+云端 / 仅云端 三态开关,并支持设备 × Agent 矩阵(行合计 = 列合计 = 总计);上报内容仅 token 数、费用、时间戳与标识符,可选会话脱敏
🔥用量热力图设置页新增「Token 用量统计」:类 Codex 的 26 周日用量方格热图,按天着色(输入 / 缓存 / 输出 / 费用),悬停看当日明细、今天高亮描边,顶部显示全时段累计;跟随三态视图——「本机+云端 / 仅云端」下自动并入云端按天用量(卡片标题右侧标注当前口径)
📈订阅配额监控Kimi Coding Plan、火山方舟 Coding Plan 等订阅套餐:配额进度条、重置倒计时、等效按量费用参考。火山方舟走管控面 OpenAPI(HMAC 签名),需 AccessKeyID + SecretAccessKey
💳余额查询一键查询 DeepSeek 官方账户余额(总余额 / 充值 / 赠送 / 状态);已登录 DSH 账号时直接读 Platform 钱包(充值 / 赠金),不再需要 API Key(v1.9.6)
🤖Agent 工具直接在对话里问:"我现在花了多少钱?"——Agent 会调用 cost_stats / cost_prices 等工具回答
🔻状态栏聊天输入框下方实时显示:本会话花费(胶囊分段:本会话 / 订阅套餐 / 分模型),按会话实际用到的模型与订阅拆分,多模型默认折叠只显示 top2,点击展开全部明细;订阅显示具体套餐名,不再展示配额与调用次数
👁️界面显示开关输入框上方的花费胶囊、侧边栏峰谷时段条、设置页「花费统计」看板三个落点各自可关(设置 → 花费统计 → 右上角齿轮 → 数据与界面 → 界面显示),勾选即刻生效;只影响显示,记账、云端同步与 Agent 工具照常,配置入口(齿轮页)本身不受开关控制
💾本地持久化数据存本机 ~/.dsh/storages/cost-tracker-records.json,重启不丢、不上传;明细保留最近 180 天,更早自动压缩为永久日汇总,全时段统计永远精确且内存/磁盘有界
🕰️历史导入(v1.9.0)回放宿主会话日志,把装插件之前的对话调用补录进账本(按各自时间戳的旧价计费);只补插件不可能记到的部分(安装前 / 停机缺口),幂等可重复执行,导入记录标记 source=import 以便区分
🔄官方价格同步(v1.9.0)一键抓取官方定价页、解析各模型峰价并对比差异,应用后构建新的计费时代(只影响之后,历史口径不回改);每日可自动核对(只提示、不自动应用),页面改版时宁可不同步也绝不写错价
🌐多厂商价格目录(v1.9.0)内置 15 家厂商 / 141 个模型条目(USD→CNY 按可配汇率折算),OpenAI / Anthropic / Gemini / Qwen 等内置表之外的模型也能按精确价入账;支持宽松/严格匹配与手动覆盖价
⚖️Plan 与按量双轨(v1.9.0)工具栏「含 Plan 总额」开关一键切换口径:关闭只算按量真金白银、订阅以附注展示;打开则金额 = 按量 + 订阅等值,图表按天并入「订阅等值」段
🔐凭据零落盘(v1.9.0)云端令牌与火山 SecretAccessKey 只写 DSH 凭据库(配置文件零明文,旧版明文启动时自动迁移);任何响应只回显布尔;出站请求白名单 + 强制 https + 拒绝跟随重定向(防凭据外带)
📤CSV 导出一键导出明细 + 日汇总(purpose=rollup),方便用 Excel / Numbers 做进一步分析

界面展示

在对话中直接查询——Agent 自带花费/余额/单价工具,边聊边查:

对话中查询花费与余额,输入框下方显示实时花费状态栏

订阅套餐与账户余额——配额进度条、重置倒计时、余额一目了然:

Kimi Coding Plan 配额监控与 DeepSeek 账户余额

分模型明细——每个模型的请求趋势、Token 构成,悬停显示每日明细:

单个模型的请求次数面积图与 Tokens 堆叠图,悬停提示显示完整日期与分段数值

📸 截图取自 v1.8.x 的看板;v1.9.0 起工具栏多了「含 Plan 总额」开关、配置面板改为七个折叠分组(见「设置入口」一节),v1.9.3 起配置页由「花费统计」页头右上角齿轮进入(带返回键),概览卡与图表本身不变。


安装(三选一)

前提:你已经在用 dsh web(DSH 的 Web 模式)。~/.dsh 即 DSH 的数据目录(如设置了 DSH_HOME 环境变量则指向该目录)。

走方式一时请注意:插件市场本身要求 dsh web ≥ 0.1.0-rc.6,更旧的宿主里根本不会出现「插件市场」这一项——那种情况请用方式二或方式三。

方式一:从插件市场安装(推荐)

本插件已收录于 awesome-dsh-plugin 精选列表(分类 usage)。在 DSH 里打开 设置 → 插件市场,搜索 dsh-cost-tracker 点安装即可;市场展示的等价命令行是:

dsh plugin --profile web add @angelyeye/dsh-cost-tracker

也可以直接按仓库安装:dsh plugin --profile web add github:Angelyeye/dsh-cost-tracker。装出来是同一个包——包名以包自己声明的 package.json 为准,所以图行 id、以及随之而来的客户端注册要求,两种装法完全一致。

市场会把插件装进当前 profile 并自动写好 loader 配置,装的是市场上架的最新版本,装完按提示重启 dsh web、刷新浏览器,无需手工 git clone,也不用自己改 patch 文件。

方式二:让 DSH 帮你装(不懂命令行也能用)

打开 DSH 的任意会话,把下面这段话原样粘贴发送给 Agent 即可:

请帮我安装 DSH 插件 @angelyeye/dsh-cost-tracker:
1. git clone https://github.com/Angelyeye/dsh-cost-tracker.git 到 ~/.dsh/profiles/node_modules/@angelyeye/dsh-cost-tracker(目录名必须与包名一致)
2. 在 ~/.dsh/profiles/web/cordis.patch.yml 顶层数组追加一行:
   - insert:
       - id: dsh-cost-tracker
         name: "@angelyeye/dsh-cost-tracker"
3. 完成后告诉我,我自己重启 dsh web

看到提示后,在终端按 Ctrl+C 停掉 dsh web,再重新运行 dsh web,刷新浏览器即可。

方式三:手动安装(3 条命令)

# 1. 下载插件(目录名必须与包名一致)
mkdir -p ~/.dsh/profiles/node_modules/@angelyeye
git clone https://github.com/Angelyeye/dsh-cost-tracker.git ~/.dsh/profiles/node_modules/@angelyeye/dsh-cost-tracker

# 2. 注册插件(往 patch 文件里追加配置)
cat >> ~/.dsh/profiles/web/cordis.patch.yml <<'EOF'
- insert:
    - id: dsh-cost-tracker
      name: "@angelyeye/dsh-cost-tracker"
EOF

# 3. 重启 DSH(先 Ctrl+C 停掉当前 dsh web,再执行)
dsh web

验证安装成功

  1. 浏览器打开 DSH Web GUI → 左下角 设置 → 侧边栏出现 「花费统计」;
  2. 聊天输入框下方出现一行花费状态条;
  3. 对 Agent 说一句"查一下我现在的花费",能正常回答即全部就绪。

⚠️ 如果 ~/.dsh/profiles/web/cordis.patch.yml 里已有其他内容,请保留原有行,只追加上面那段;该文件顶层必须是 YAML 数组(每行以 - 开头)。

⚠️ 插件市场安装过本插件的机器,不要用「手动拷文件」升级(v1.9.1 的真实踩坑): profile 用 pnpm 管理插件(~/.dsh/profiles/web/package.json 里记着 "@angelyeye/dsh-cost-tracker": "^1.8.15"),下次启动时市场对账会按依赖重装回旧版, 你拷进去的新文件会被覆盖 —— 现象是"升级了、重启后又变回旧版本"。 这类机器请用官方 dev 流程把目录链接进 profile(重启不会丢,改代码重启即生效):

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

发布版本则走正常升级:dsh plugin --profile web update(或市场里点更新)。

从旧包名迁移(仅 v1.6.0 及更早的安装需要)

v1.7.0 起包名由 dsh-cost-tracker 改为 @angelyeye/dsh-cost-tracker —— 因为 npm 上原名已被他人占用,而市场的 npm 映射要求「已发布的包名 = 仓库 package.json 的 name」。

⚠️ v1.7.0 的迁移指引已更正:v1.7.0 存在客户端注册名缺陷(详见 CHANGELOG.md 的 v1.7.1 条目),任何安装方式装出来的 v1.7.0 都无法加载客户端。请直接装 v1.7.1 或更高版本,不要用重装 v1.7.0 的方式排障 —— 按仓库装同样不行(包名一样,图行 id 一样,问题出在 bundle 内部)。

⚠️ 不要只是"再装一次新版":新旧两份的 cordis.patch.yml 用的是同一个 loader id(dsh-cost-tracker),叠加安装会让两份同时被加载 —— 表现为重复的 HTTP 路由、Agent 工具与 UI 插槽。必须先清掉旧的:

市场安装的(用 dsh plugin add 装的):

dsh plugin --profile web remove dsh-cost-tracker
dsh plugin --profile web add @angelyeye/dsh-cost-tracker

手工 clone 装的:

# 1. 编辑 ~/.dsh/profiles/web/cordis.patch.yml,删除 id 为 dsh-cost-tracker 的那段 - insert:(共 4 行)
# 2. 删除旧目录
rm -rf ~/.dsh/profiles/node_modules/dsh-cost-tracker
# 3. 再按上面的「方式一」重新安装一次

提示:清理旧目录后,如果 cordis.patch.yml 里那段 - insert: 没删掉,DSH 启动时会因为找不到模块名 dsh-cost-tracker 而解析失败。两者要一起处理。

数据不会丢:用量记录在 ~/.dsh/storages/cost-tracker-records.json,与插件目录、包名、安装方式全都无关。


使用说明

设置页「花费统计」

  • 时间范围:右上角可切换近 7 天 / 近 30 天 / 全部;
  • 六组概览卡:今日费用 / 本月费用 / 总花费 / API 请求次数 / Tokens / 总余额。前三个金额卡不含订阅会员等效费用,订阅以附注展示;
  • 消费金额图:支持「按峰谷」「按模型」两种分段方式,鼠标悬停查看当日明细;
  • 配色切换:「按模型」视图下,消费金额标题旁有三套装色款条(橙→黄 / 蓝→紫 / 蓝→浅蓝)可切换;模型按总消费降序排名取色(第 1 名最深夜底、逐级变浅,不循环不撞色),选择保存在浏览器本地;
  • 分模型区块:每个模型一张请求次数图 + 一张 Tokens 构成图(输入/缓存写入/输出/缓存命中);
  • Token 用量统计热力图:类 Codex 的 26 周每日用量方格,颜色深浅按当日 token 相对最大值分档;悬停任一格看该日明细(输入 / 缓存 / 输出 / 费用),今天高亮描边;口径跟随三态开关:「本机」只统计本机,「本机+云端」把云端按天用量并入(与上方卡片同一并集口径、不重复计数),「仅云端」只看云端,标题右侧标注当前口径。云端按天明细需要 dsh-cost-cloud ≥ v1.3.2,旧云端下自动退回本机口径;
  • 峰谷计价与提示:时段条样式可选(简洁单行·按 24h 比例(白色实时进度线) / 环形表盘·相位色点),简洁样式可选双行紧凑(条上文下 / 文上条下),可开关「显示时间」刻度(00:00–21:00),设置峰/谷切换前的弹窗提醒提前量(1–30 分钟)、提醒类型(两者 / 进入高峰 / 进入闲时)、弹窗位置(右下角 / 屏幕中心)与浏览器系统通知。v1.9.0 起这些设置统一在「设置 → 花费统计 → 右上角齿轮 → 峰谷计价与提示」里改(v1.9.3 起入口为页头齿轮;看板上的同名面板改为只读回显,只保留弹窗预览);侧边栏底部常驻时段条显示当前档位与下次切换倒计时;
  • 含 Plan 总额开关(v1.9.0):工具栏右侧一个开关,决定金额卡与图表的口径 —— 关闭(默认)只算按量真金白银、订阅以附注展示;打开则金额 = 按量 + 订阅等值,图表按天并入「订阅等值」一段。选择存浏览器本地并回写服务端配置(跨设备一致);
  • 导出 CSV:导出明细记录(近 180 天)+ 日汇总行(purpose=rollup)。

对话中的 Agent 工具

工具作用你可以这样问
cost_stats查询花费与用量统计(scope=local(默认,仅本机)/ cloud(云端多机汇总)/ both)"我今天花了多少钱?" · "我所有电脑加起来花了多少?"
cost_prices查看内置单价表与峰谷规则"现在 deepseek-v4-flash 什么价?"
cost_peak查询当前峰谷档位与下次切换倒计时"现在是不是高峰时段?"
cost_recompute按计费时代重算已入库记录的费用(一次性补账),默认只试算"把价格调整前的记录按新价重算一下"
cost_import历史导入:查看导入状态 / 执行一轮(补录装插件之前的对话)"把装插件之前的花费也统计进来"
cost_sync云端同步:查看状态 / 立即同步 / 测试连接 / 改配置"把花费同步到云端" · "云端同步正常吗?"
cost_reset清空全部统计数据(不可恢复)"把花费统计清零"

多机汇总(云端同步,v1.8.0)

在多台电脑上使用时,把用量汇总到自建云端服务,即可在任一机器上查看全网合计,并按「设备 × Agent」拆分。

部署云端服务(独立仓库,零运行时依赖):

git clone <你的仓库地址> dsh-cost-cloud && cd dsh-cost-cloud
cp .env.example .env      # 填 SESSION_SECRET 与 ADMIN_PASSWORD_HASH(node scripts/hash-password.js "口令")
docker compose up -d      # 打开 http://<服务器>:8787 ,在「设置」页生成共享引导令牌

在每台设备上配置:打开 设置 → 花费统计 → 右上角齿轮 → 「多机汇总(云端同步)」,填写:

字段说明
设备名该机器在看板上显示的名字(如「办公台式机」)
服务地址云端地址,如 https://cost.example.com
共享令牌云端「设置」页生成的 dshc_...
同步间隔默认 60 秒

然后点 测试连接 → 立即同步。回到 设置 → 花费统计,顶部会出现三态开关:

视图含义
本机只统计这台电脑(与未启用云端时完全一致)
本机+云端本机 + 其他整机的全部 + 本机上其它 agent(服务端并集口径,不重复计数)
仅云端以云端记录为准(含本机已同步部分)

「本机+云端」的服务端口径是并集:其他整机 ∪ 本机上的非 dsh 来源。 因此多机 + 多 agent 混用时,本机的 DSH 数字来自本地,本机上的 ZCode/Codex 等来自云端,其他电脑全部来自云端 —— 三者相加恰好等于全网,不重不漏。

配合「维度」下拉还能看 按机器 / 按 Agent / 按模型 的拆分,以及设备 × Agent 矩阵(行合计 = 列合计 = 总计)。

其它 agent 也能接入:云端的上报协议是开放的,任何 agent 的统计插件按 dsh-cost-cloud 仓库的 docs/INGEST-API.md 实现即可接入,云端无需改动,看板会自动出现新的 Agent 列。 关键约定:同一台机器上的所有 agent 必须共用同一个 machineId(共享文件 ~/.dsh-cost/device.json),否则会被统计成多台设备。

隐私:只上报 token 数量、费用、时间戳与标识符(不涉及 prompt / 回复 / 文件内容);可在配置页开启「会话脱敏」(sessionId 上报前替换为不可逆哈希)与「不含 purpose」。

界面显示(v1.8.12,可选)

不想在界面上看到插件?设置 → 花费统计 → 右上角齿轮 → 数据与界面 → 界面显示里三个开关各自独立、勾选即刻生效(无需点「保存」,也无需重启 dsh):

开关关掉之后
输入框上方的花费胶囊会话输入区不再显示本会话花费与模型明细
侧边栏峰谷时段条侧边栏底部的档位 / 倒计时消失(峰谷切换弹窗与系统通知一并停用;只想留提醒不想要时段条,请改用「峰谷计价与提示」里的提示开关)
设置页「花费统计」看板设置页左侧的该入口只留一句重新打开的指引(记账与云端同步照常)
  • 只影响显示:记账、落盘、云端同步与 Agent 工具(cost_stats 等)全部照常工作;
  • 配置入口本身不受这三个开关控制 —— 页头齿轮始终在(旧宿主还有插件配置卡片),否则关掉之后就没有入口能再打开了;
  • 取值为「只有显式 false 才隐藏」,缺省即显示。老配置文件里没有这几个键,升级后界面与升级前一致;
  • 落盘在同一份 ~/.dsh/storages/cost-tracker-config.json(键名 uiDockEnabled / uiPeakEnabled / uiDashboardEnabled),与峰谷、云端字段互不覆盖。

设置入口(v1.9.3:花费统计页头齿轮;新宿主上的唯一入口)

设置 → 花费统计 → 页头右上角齿轮(图标按钮,悬浮提示「花费统计设置」)→ 配置页,左上角返回键回到看板。

入口适用宿主形态
页头齿轮 → 配置页(v1.9.3 起,推荐)全部版本设置 → 花费统计 → 齿轮;配置页整页常驻展开,左上角返回键
插件配置卡片(v1.9.0,兼容保留)仅仍声明 settings.plugin.item 的旧宿主(dsh < 0.1.7-alpha.2)设置 → 插件 → 插件配置 → 花费统计;卡片默认收起,点标题展开

DSH 0.1.7-alpha.2 删除了 settings.plugin.item 插槽(「内置插件」分区改为只读清单),卡片在新宿主上不显示; 插件侧的注册保留(插槽不存在时回调不触发,零成本),旧宿主照旧可用。两个入口共用同一个配置组件, 字段、校验、写接口完全一致,只是外壳不同;未保存草稿各自独立,就近改一处即可。

配置页承载全部设置,按折叠分组排列,顶部一条状态摘要(云端同步 / 已记账条数 / 待上报 / 上次同步 / 计价时代 / 历史导入 / 金额口径):

分组内容
多机汇总(云端同步)设备名、启用开关、服务地址、共享令牌、同步间隔、单批条数、会话脱敏、上报 purpose、上报日汇总、补传窗口、默认视图 + 保存 / 测试连接 / 立即同步 / 全量补传 + 设备 ID / 水位 / 最近错误
峰谷计价与提示峰谷开关、显著提示、时段条样式(简洁 / 环形表盘)、时间刻度 / 双行紧凑、切换提醒(提前量 / 类型 / 位置 / 系统通知)+ 改完即可预览(时段条与弹窗预览)
订阅套餐与配额火山方舟 AccessKeyID / SecretAccessKey(后者只进凭据库)、配额查询与百分比条、订阅归类覆盖表(provider/* 或 provider/model → 订阅 / 按量)
计价与价格目录「含 Plan 总额」、目录匹配模式(宽松 / 严格)、USD→CNY 汇率、手动覆盖价表、官方价格同步(核对 / 应用 / 上次差异 / 当前时代 / 已同步时代)、多厂商目录概览(厂商与条目数、数据日期、指纹)
历史导入自动导入开关、立即导入、累计导入条数与已处理日志数、三条口径说明
数据与界面界面显示三开关(勾选即刻生效)、导出 CSV、重算费用(试算 / 写回)、清空数据(两步确认)
安全与凭据云端令牌 / 火山 SK 的「是否已配置 + 存储位置」徽章、旧版明文迁移状态、清除按钮与出站防护说明

约定:只有「界面显示」三开关是勾选即刻生效(要立刻看到显隐结果),其余分组都是「改草稿 → 点该组保存」,避免误触即写盘;分组折叠只切显隐、不卸载内容,展开任一分组都不会重新取数或丢草稿。从配置页点「返回」会丢弃未点保存的草稿(点该组「保存」即落盘),各组之间互不影响。

历史导入(v1.9.0)

装上插件之前的对话也能补进账本:插件回放宿主会话日志($DSH_HOME/sessions/<项目>/<会话>/session[.vN].jsonl[.zstd],多 zstd frame 逐帧解压、逐帧切片;v1.9.6 起按 vN 自动识别版本,v4/v5 无需改代码),把其中的模型调用按当时时间戳的计费口径入账。

  • 默认开机自动导入(延迟 8 秒,不阻塞启动),也可在配置页点「立即导入」或关掉自动(autoImport);
  • 只补「插件不可能记到」的调用:早于本机最早一条实时记录,或所在日完全没有实时覆盖(停机缺口);
  • 跨安装点的会话按切割线截断:安装前那段补录,安装后那段以实时记录为准;
  • 幂等三保险:清单按文件 mtime + size 快跳、逐调用键 (sessionId, 时间戳, 五桶 tokens) 去重、已被实时覆盖的日子宁可不导入也不重复计数;
  • 导入记录标记 source=import(实时记录 source=live);fork 出的子会话只计 createdAt 之后的部分,标题生成等辅路请求不计。

官方价格同步与多厂商目录(v1.9.0)

  • 官方价格同步:配置页里点「核对官方价」抓取官方定价页(中文页直接给出人民币价),解析出各模型峰价并与当前生效价对比;点「应用新价」把结果构建为新的计费时代 —— 只对生效时刻之后的记录生效,历史记录按各自时间戳选版,口径不回改。每日可自动核对(默认开,只提示差异,绝不自动应用)。解析器对页面改版 / 数字缺失 / 「空闲价 ≠ 高峰一半」一律抛错,宁可不同步也绝不写错价;
  • 多厂商模型价格目录:内置 15 家厂商 / 141 个模型条目(OpenAI / Anthropic / Google / Moonshot / z-ai / xAI / Alibaba / MiniMax / Tencent / Xiaomi / Upstage / NVIDIA / Mistral / Meta / OpenCode;数据改编自 dsh-cost-meter 的初始目录,MIT,2026-10-25 起按各厂商官方定价页逐条复核),按 USD→CNY 汇率(默认 7.2,可改)折算。内置表之外的模型命中目录即记精确价(不再标「估算」);匹配模式可选宽松(归一化包含)或严格(名称全等);
  • 手动覆盖价:provider/model → 输入 / 输出 / 缓存价,优先级最高,用于自建端点或议价套餐;
  • 计费优先级:手动覆盖价 > 订阅归类(Plan)> 内置 / 同步时代精确价 > 多厂商目录 > provider 兜底 > 通用兜底。cost_prices 工具与 /api/cost-tracker/prices 会一并回显当前时代、同步时代、目录指纹与覆盖价;
  • 云端(dsh-cost-cloud ≥ v1.4.0)有同源实现与对应的管理端点,两边口径可对照(/api/v1/protocol 回显云端实际使用的价格版本与目录指纹)。

凭据安全(v1.9.0)

  • 密钥零落盘:云端共享令牌与火山 SecretAccessKey 只写入 DSH 凭据库(~/.dsh/.credentials.yaml,由宿主凭据服务托管),配置文件里只保留「是否已配置」。老版本(≤ v1.8.15)写在 cost-tracker-config.json 里的明文会在启动时自动迁移进凭据库并从配置清除(幂等;凭据库已有值时不覆盖)。安全边界:只有凭据库确实可写时才清除配置里的明文 —— 宿主没有凭据服务、或凭据服务只读时,明文会原样保留并在启动日志里提示,因为密钥若只留在内存里,重启后就永久丢了;
  • 任何响应都不回显密钥:状态接口只给布尔与「存储位置」(凭据库 / 进程内存),AccessKeyID 属非敏感标识才会回显以便预填;
  • 出站防护:携带凭据的请求必须命中主机白名单(DeepSeek / Kimi / 火山管控面 / 配置的云端地址 / 定价页主机),非本机地址强制 https,redirect: 'manual' —— 3xx 一律按失败处理,防止重定向把 Authorization 头带去别处。

余额来源与账号登录(v1.9.6)

余额查询按以下优先级选来源,账号登录不需要也不接受 API Key:

  1. 面板手填 API Key(最高优先,用户显式动作)→ 请求 https://api.deepseek.com/user/balance;
  2. DSH 账号登录态 → 调宿主服务 deepseekAccount.getBalance(),读 Platform 钱包 (normal_wallets = 充值钱包、bonus_wallets = 赠金钱包,币种 CNY / USD), 与官方「设置 → 账号与余额」同源;
  3. 配置 / 环境里的 API Key(DEEPSEEK_API_KEY)→ 同 1。

为什么必须分两条:DSH 的账号登录用 PKCE 授权把 token 写进凭据库的 record (deepseek-account-platform/default),不会下发 API Key;账号态推理用 x-dsh-auth-token 走 Platform 网关、API Key 态用 x-api-key,运行时文档明确两条路由 互不回退。因此「登录后拿 key 去查 api.deepseek.com」这条路在 0.2.x 里不存在。

口径差异:账号态展示的是 Platform 钱包(充值 / 赠金分开列示,总额 = 同币种两者之和, 精确十进制相加);API Key 态沿用 total_balance / granted_balance / topped_up_balance 与 is_available。没有 deepseekAccount 服务的旧宿主自动走原路径, 行为与 v1.9.5 一致。

HTTP API(供其他工具调用)

全部为 POST + JSON,监听本机地址:

POST /api/cost-tracker/summary      概览(含本会话按模型拆分 / 订阅)
POST /api/cost-tracker/dashboard    仪表盘数据
POST /api/cost-tracker/usage        用量热力图(全时段累计 + 按天 token 聚合)
POST /api/cost-tracker/peak         峰谷相位快照(当前档位/下次切换/配置/界面显示开关)
POST /api/cost-tracker/peak-config  保存峰谷计价提示配置
POST /api/cost-tracker/ui-config    保存界面显示开关(胶囊/时段条/看板,可只传要改的键)
POST /api/cost-tracker/sync         云端同步状态(设备 ID/水位/待上报/最近错误/界面显示开关)
POST /api/cost-tracker/sync-now     立即同步(传 {"full":true} 全量补传)
POST /api/cost-tracker/sync-test    测试云端连接
POST /api/cost-tracker/sync-config  保存云端同步配置
POST /api/cost-tracker/cloud        云端只读聚合(route/days/excludeSelf/devices/sources)
POST /api/cost-tracker/kimi-usage   Kimi 订阅配额
POST /api/cost-tracker/volcengine-usage  火山方舟 Coding Plan 配额(5 小时/周/月窗口)
POST /api/cost-tracker/volcengine-config 保存火山方舟 AK/SK(只回显「是否已配置」,不回显密钥)
POST /api/cost-tracker/balance      账户余额(账号登录态优先;传 {"apiKey":"sk-…"} 可手填覆盖)
POST /api/cost-tracker/prices       单价表(按计费时代分版 + 同步时代 + 多厂商目录 + 覆盖价)
POST /api/cost-tracker/recompute    按计费时代重算已入库记录(默认只试算,传 {"apply":true} 落盘)
POST /api/cost-tracker/billing-config  双轨计费与目录配置(金额口径/订阅归类/匹配与汇率/覆盖价)
POST /api/cost-tracker/prices-sync  官方价格同步(默认只核对,传 {"apply":true} 应用新价)
POST /api/cost-tracker/prices-config 价格同步设置(定价页地址 / 每日自动核对开关)
POST /api/cost-tracker/import-status 历史导入状态
POST /api/cost-tracker/import-run   执行一轮历史导入(幂等)
POST /api/cost-tracker/import-config 历史导入设置(开机自动开关)
POST /api/cost-tracker/reset        清空全部记录(配置页两步确认后调用)
POST /api/cost-tracker/export       导出 CSV

示例:curl -X POST http://127.0.0.1:3080/api/cost-tracker/summary -d '{}'


更新记录

这里只列重要版本;逐版完整记录见 CHANGELOG.md。

v1.9.6(2026-10-17)

新增:余额查询兼容 DSH「DeepSeek 账号登录」—— 账号态改走宿主 deepseekAccount.getBalance() 读 Platform 钱包(充值 / 赠金),API Key 路径原样保留

  • 为什么之前查不到:0.1.7 起 DSH 支持浏览器 PKCE 账号登录,授权只写进凭据库的 record deepseek-account-platform/default({version, token, issuer}),从不写 ref,而 credentials.resolve() 只查 refs 半区 —— 账号 token 没有 ref 名;同时账号态推理用 x-dsh-auth-token、API Key 态用 x-api-key,运行时文档明确两者「互不回退」,且整个运行时里 api.deepseek.com/user/balance 零命中。于是只认 DEEPSEEK_API_KEY 的旧实现,在纯账号态下 必然报「未找到 DeepSeek API Key」;
  • 新优先级:面板手填 Key > 账号登录态 > 配置/环境 API Key。账号态失败不回退 API Key (回退会显示另一个账户的数字),错误信息直接给出「手动填 Key」的出路;
  • 必填契约:getBalance(client) 的 client 三字段(version / locale / timezoneOffsetSeconds)会被运行时直接拼进 x-client-* 头,缺一个就抛 TypeError; 宿主侧一律补齐,浏览器半端再用 navigator.language 与本机时区覆盖;
  • 口径:账号钱包「总余额 = 同币种充值 + 同币种赠金」,用 BigInt 精确十进制相加; 账号态 available 为 null(Platform 摘要没有 is_available,不把未知渲染成不可用); 多币种按 CNY > USD 选主币种,符号与标题跟随币种;
  • 零影响:没有 deepseekAccount 服务的旧宿主自动走原路径,文案与 v1.9.5 逐字一致;
  • 顺带修复(同一轮 0.2.x 兼容审计):① 历史导入现在识别 session[.vN].jsonl[.zstd] —— 0.2.x 起新会话写成 session.v4.jsonl.zstd,旧实现只认 v3/legacy 名字,导致新会话被静默跳过 (本机 68 个 v4 会话全部漏掉;内容层其实兼容);② 账号态 provider deepseek-account 补上 DeepSeek 兜底价,精确价表之外的新模型不再落到 generic 缓存价(0.5 → 0.04)且保留峰谷半价; ③ 设置读取迁移到 0.2.x 的 settings.describe()(get() 已被移除):新增 settings.js 做 「describe 优先、get 兜底」的兼容读,自定义 apiKeyEnv 的部署不再取错 Key 名;
  • 测试:新增 test/balance-account.test.js、test/session-log-v4.test.js、 test/settings-compat.test.js;全仓 22 个测试文件逐文件运行全绿,npm test(CI 用的 && 链) 同样全绿(同时修掉了 test/import.test.js 里因固定日期 fixture 造成的既有假失败 —— 它正是 npm test 变红、挡住发布的根因)。

v1.9.5(2026-10-07)

修复「桌面端(Electron 外壳)花费统计整块看板变成无样式原生控件」:自建 <style> 缺 data-plugin 归属标记,被别的模块认领后在 HMR 清理时连带删除

  • 根因(已复现):DSH 0.2 的 @deepseek-ai/dsh-client-modules 用 claimStyles(ownerId) 把所有没带 data-plugin 的 <style> 认领给当时正在物化的模块, 再用 removeOwnedStyles(id) 在该模块 HMR 失效 / 重载 / 剪枝时整片删除。 插件旧实现只打了 data-plugin-css,实测样式表被 @deepseek-ai/dsh-api-remotes 认领, 该模块一被清理就带走看板的 170 条 CSS 规则 —— 卡片边框、控件皮肤、图表网格全部消失, 界面退化成浏览器默认的 <select>/<button> 排版;
  • 为什么只在桌面端:Electron 外壳把 apps/web 的原始 vite dist 从 dsh-app://app/ 提供, 启动图(ModuleLoader 引导、插件 preload、contact config)改由 IPC 取回后在运行期注入, 随后 dsh-client-hmr 推送的清单让非托管行的 rev 与初始值不一致,正好命中那条清理路径; 浏览器里的 dsh web 把启动图内联在 index.html 里,物化顺序与 rev 都不同,所以看不到;
  • 修法:client.js 新增模块 id 单一事实源 DSH_BUNDLE_ID,applyStyles() 改为 先 setAttribute("data-plugin", DSH_BUNDLE_ID) 再插入(与宿主自带包 tag.dataset.plugin = "<包名>" 的约定逐字对齐),并补上宿主同款去重护栏;
  • 验证:桌面端等价宿主 + 无头 Edge/CDP(与用户截图同视口)—— 修复前模拟该模块清理后样式表被删、 看板变原生控件;修复后同样清理,标签存活、cssRules.length = 170、6 张卡片样式完好。 新增 client-render [11] 与 client-registration [3b] 共 12 条断言,全量 19 个测试文件通过;
  • 生效条件:只改客户端半端,浏览器硬刷新即可;宿主半端版本号同步升到 1.9.5。

v1.9.4(2026-09-24)

修复「火山方舟配额响应不是合法 JSON」:宿主全局 fetch 被 undici 包污染后不解压 gzip,插件改为自带解压兜底

  • 根因(本机复现):宿主进程里只要有插件 import 了 npm 的 undici 包(本机是 dshmarket 静态引入,另有 dsh-http-proxy / dsh-web-fetch-http),Node 内置 fetch 就不再解压 gzip —— 响应既没有 content-encoding,正文也是原始压缩字节 (实测:未 import 时 560B 明文 JSON;import 后 326B 且以 1f 8b 开头)。于是 JSON.parse(await res.text()) 必然失败,面板报「配额查询不可用:火山方舟配额响应不是合法 JSON」; 插件市场把所有包的新版本读成 null 也是同一个根因(它无代理时回退用的同样是全局 fetch);
  • 修法(两层,对调用方透明):safeFetch 默认补 accept-encoding: identity 从源头要未压缩正文; 收到正文后按字节判断(gzip 1f8b / zlib 78xx / 响应头明说的 br、deflate)自行解压, 解压异常一律原样返回。插件所有出站请求(火山/Kimi 配额、云端同步与读取、官方定价页抓取) 都走这里,因此一并兜住;
  • 验证:真机端到端 —— 先 import('undici') 污染进程,旧路径复现同一条错误, 修复后 GetCodingPlanUsage 正常返回三档窗口(实测 100% / 27.08% / 14.77%); 新增 credstore [5] 与 volcengine-host [6] 两组回归,全量 18 个测试文件通过;
  • 生效条件:改动在宿主半端,需重启 dsh web。

v1.9.3(2026-09-24)

适配 DSH 0.1.7-alpha.2:配置入口内迁到「花费统计」页头齿轮(旧卡片入口保留兼容)

  • 背景:DSH 0.1.7-alpha.2 删除了 settings.plugin.item 插槽(原来的「设置 → 插件 → 插件配置」), 「内置插件」分区改成只读清单(只显示完整名称 / 配置状态 / 启用于),dsh-settings 的 installSection 也一并下线 —— 本插件原先挂在那里的配置卡片在新宿主上永远不会显示;
  • 改法:配置 UI 内迁到本插件自己的设置分区 —— 设置 → 花费统计 → 页头右上角齿轮(齿轮为图标按钮, 带 花费统计设置 可访问名)→ 配置页,左上角返回键回到看板。七个折叠分组、顶部状态摘要、 各分组的保存 / 测试连接 / 立即同步 / 用价同步 / 历史导入等动作逐项不变;
  • 为什么是「页内跳转」而不是第二个左侧导航项:宿主设置外壳渲染分区时只传入 close (renderSlot('settings.section', { close }, { only: active })),分区没有任何程序化切换导航的能力;
  • 兼容:settings.plugin.item 注册保留。0.1.7+ 上该插槽不存在 → 回调不触发即自动失效(零成本); 仍声明它的旧宿主照旧显示卡片。两种入口共用同一个 ConfigPanel(只有外壳不同),字段、校验、 写接口完全一致 —— 就近改一处即可,两处的未保存草稿互相独立;
  • 不再可能关掉后打不开:看板被关掉时页头与齿轮仍在,只有统计内容换成一句「点右上角齿轮 → 数据与界面 → 打开」的指引(原「插件配置」入口在新宿主上已经不存在,这条护栏是必须的);
  • 文案:插件内所有指引(峰谷只读面板、云端同步只读卡、令牌失效提示、云端未配置提示)与 Agent 工具 / HTTP 错误里的路径统一改为「设置 → 花费统计 → 右上角齿轮 → 分组名」。

v1.9.2(2026-09-20)

定价口径修正:V4-Pro 不再路由到 Flash(官方撤销下线计划)+ 新增「法定节假日全天闲时」

  • 修正:官方现行价目页仍为 deepseek-v4-pro 单列价格(高峰 9 / 27 / 0.30,闲时半价,并发 500), 更新日志也已改为「决定在 2026-09-14 之后继续提供 V4 Pro 服务,计费方式保持不变」。 内置表此前按 09-10 新闻稿的预告(「9-14 12:00 后 pro 全部路由到 Flash」)实现了 v41pro 时代, 会把 pro 调用按 Flash 价计(输入 2 / 输出 8),低估约 3.4~4.5 倍。现删除该时代与路由, V4-Pro 一律按自有牌价计费(PRICE_ERAS 回到 legacy / v41 两版)。 本机账本零影响(4393 次调用中 deepseek-v4-pro 0 次);注意:路由期已入库的 pro 记录模型名 已被改写为 deepseek-flash,补账无法反推,需重放会话日志才能订正。
  • 新增:官方把中国法定节假日全天计入闲时(此前只排除了周末,节假日落在工作日会多计 1 倍)。 内置 2026 全年 33 天(国办发明电〔2025〕7 号), 配置卡「峰谷计价与提示」新增 peakHolidays:空 = 内置表、none = 停用、也可自定列表; 调休补班的周六/周日不计高峰;相位文案区分「周末全谷」与「节假日全谷」。

v1.9.1(2026-09-20)

修复:云端同步报「方法不允许」(405)—— safeFetch 丢掉 fetch 原生签名,POST 退化成 GET

  • 反代日志显示插件发出的是 GET /api/v1/ingest/records(应为 POST)→ 云端 405,同步全废、水位不前进;
  • 根因:index.js 以 fetch 原生签名接线 (url, init) => safeFetch(url, {...init}),而 safeFetch 只读 opts.init,method / body 全部丢失;
  • 修复:safeFetch 同时接受两种入参形状(opts.init 优先),安全策略不变;并补两层回归护栏(单测接线形状 + 引擎集成 runOnce 断言真的发出 POST);
  • 另修:凭据服务晚就绪时明文迁移不再只试一次 —— 用 ctx.inject(['credentials']) 等它就绪后自动重迁,secretsMigrated 不会永远停在 false;
  • 安装提醒:DSH 的 profile 用 pnpm 管理插件,**手动拷文件会在下次启