@angelyeye/dsh-cost-tracker 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +142 -0
- package/LICENSE +21 -0
- package/README.en.md +319 -0
- package/README.md +335 -0
- package/client.js +1255 -0
- package/config.js +81 -0
- package/cordis.patch.yml +5 -0
- package/index.js +962 -0
- package/package.json +52 -0
- package/pricing.js +268 -0
- package/store.js +248 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# 更新记录
|
|
2
|
+
|
|
3
|
+
本文件用中文记录 dsh-cost-tracker 的版本变更。
|
|
4
|
+
|
|
5
|
+
## v1.7.0(2026-09-12)
|
|
6
|
+
|
|
7
|
+
**变更(破坏性,仅影响安装方式,不影响功能与数据)**
|
|
8
|
+
- **包名由 `dsh-cost-tracker` 改为 `@angelyeye/dsh-cost-tracker`**:npm 上原名已被他人占用,而插件市场的 npm 映射要求「已发布包名 = 仓库 `package.json` 的 `name`」并且该包的 `repository` 指回本仓库。改名后市场才能建立 npm 映射(下载量、宿主兼容徽章、版本化更新)。
|
|
9
|
+
- `cordis.patch.yml` 的 bundle 补丁同步改为新包名。**注意 scoped 名在 YAML 里必须加引号**(`name: "@angelyeye/dsh-cost-tracker"`)——`@` 是 YAML 的保留起始字符,不加引号会导致整个 bundle 层解析失败。
|
|
10
|
+
- **迁移**:旧安装必须**先清掉旧的、再装新的**,不能直接叠加安装 —— 新旧两份 `cordis.patch.yml` 用的是**同一个 loader id**(`dsh-cost-tracker`),叠加会让两份同时加载,表现为重复的 HTTP 路由、Agent 工具与 UI 插槽。
|
|
11
|
+
- 市场安装的(用 `dsh plugin add` 装的):`dsh plugin --profile web remove dsh-cost-tracker`,再 `dsh plugin --profile web add github:Angelyeye/dsh-cost-tracker`;
|
|
12
|
+
- 手工 clone 装的:删掉 `~/.dsh/profiles/web/cordis.patch.yml` 里 id 为 `dsh-cost-tracker` 的那段 `- insert:`,并 `rm -rf ~/.dsh/profiles/node_modules/dsh-cost-tracker`,然后重装一次。
|
|
13
|
+
- 按仓库安装的写法 `dsh plugin --profile web add github:Angelyeye/dsh-cost-tracker` 改名后依然可用(包名以包自己声明的为准)。详见 README「从旧包名迁移」。
|
|
14
|
+
- README(中/英)安装章节同步更新。
|
|
15
|
+
|
|
16
|
+
**不变**
|
|
17
|
+
- 功能与数据格式无变化;用量记录、日汇总、配置与存储路径均保持原样。
|
|
18
|
+
|
|
19
|
+
## v1.6.0(2026-09-10)
|
|
20
|
+
|
|
21
|
+
**新增**
|
|
22
|
+
- **适配 V4.1 Flash 新计费规则(北京时间 2026-09-10 12:00 起生效)**:单价表改为**按「计费时代」分版**(`PRICE_ERAS`),按**每条记录自身的时间戳**选版计费,因此历史记录口径不变、切换点自动生效,无需重启或改配置。
|
|
23
|
+
- 新增时代 `v41`(北京时间 2026-09-10 12:00 = `2026-09-10T04:00:00Z`):V4.1 Flash 高峰价 **输入(缓存命中)0.04 / 输入(缓存未命中)2 / 输出 8**(元/百万 tokens),空闲时段仍为高峰半价(0.02 / 1 / 4)。**峰谷窗口不变**,故时段条与倒计时逻辑无需调整。
|
|
24
|
+
- 新增**模型路由**(时代内的 `routes`):V4.1 Pro 上线前,V4-Pro 的请求全部路由到 V4.1 Flash 并按 V4.1 Flash 单价计费;旧 V4-Flash 系(含 `deepseek-v4-flash-vision-exp`)已被 V4.1 Flash 取代,一并按新价计费。**记录以实际计费模型名入账**(如 `deepseek-v4-pro` → `deepseek-v4.1-flash`),按模型聚合看到的就是真实计费口径。
|
|
25
|
+
- 新增导出 `V41_EFFECTIVE_AT` / `V41_FLASH_MODEL` / `PRICE_ERAS` / `eraAt()` / `exactModelsAt()` / `resolveModelInEra()` / `normalizeModelName()`。
|
|
26
|
+
- **模型名归一化匹配**:小写并剔除分隔符,使 `deepseek-v4.1-flash` / `deepseek-v4-1-flash` / `deepseek-v41-flash` / `DeepSeek-V4.1-Flash` 等等价写法命中同一档价,避免官方模型 ID 措辞变化导致漏计而落入兜底估算。
|
|
27
|
+
- `cost_prices` 工具与 HTTP `/prices` 接口改为**按版本渲染**:逐时代列出生效时刻、单价与路由规则,并标出当前生效版本(`era` / `eraLabel` / `eras` / `v41EffectiveAt`)。
|
|
28
|
+
|
|
29
|
+
- **新增 `cost_recompute` 一次性补账工具**(同时开放 HTTP `/api/cost-tracker/recompute`):按记录自身时间戳重算已入库记录的费用与计费模型名。用于「价格时代已切换、但宿主尚未重启」期间按旧价入库的记录;**默认只试算不落盘**,传 `apply: true` 才写回,幂等可重复执行。只重算明细(明细保留最近 180 天;更早的记录已折叠进日汇总,其时间段远早于任何价格切换窗口)。
|
|
30
|
+
|
|
31
|
+
**变更**
|
|
32
|
+
- `priceFor(np, model, ts)` 新增第三个参数 `ts`(调用发生时刻),缺省为当前时间;返回值新增 `model`(**计费模型规范名**,命中路由时为被路由到的模型)与 `era` 字段。记账链路改为传入记录时间戳。
|
|
33
|
+
- DeepSeek provider 兜底单价同步至 V4.1 Flash 档(`2.0 / 8.0 / 0.04`),未知 deepseek 模型不再按旧价高估。
|
|
34
|
+
- `EXACT_MODELS` 语义收敛为 **legacy(旧价)时代的单价表**,保留导出以兼容既有调用与历史口径。
|
|
35
|
+
|
|
36
|
+
**测试**
|
|
37
|
+
- `test/pricing.test.js` 新增计费时代分版与模型路由用例(切换边界 11:59:59 / 12:00:00、V4-Pro 路由、旧 V4-Flash 系路由、别名归一化、空闲半价、悬空路由防护)。
|
|
38
|
+
- 所有涉及单价的断言改为**显式传入时间戳**,不再随运行时刻漂移(否则跨 12:00 切换后必然误报)。
|
|
39
|
+
|
|
40
|
+
**计费影响(同一调用对比,高峰价)**
|
|
41
|
+
- V4-Pro(10 万输入未命中 + 6 千输出 + 2 万缓存命中):旧 **¥1.068** → 新 **¥0.2488**(约 **-76.7%**)。
|
|
42
|
+
- 旧 V4-Flash 同量:旧 **¥0.356** → 新 **¥0.2488**(约 **-30.1%**)。
|
|
43
|
+
|
|
44
|
+
## v1.5.2(2026-08-25)
|
|
45
|
+
|
|
46
|
+
### 新增
|
|
47
|
+
- **「简洁」时段条新增「双行紧凑(上下布局)」选项**:设置页当时段条样式为「简洁(单行紧凑)」时出现该复选项,勾选后时段条由左右单行改为上下两行布局,并可进一步选择「时段条在上·文字在下」(默认)或「文字在上·时段条在下」;侧边栏与设置页预览同步生效。
|
|
48
|
+
- 新增 `peakCompactStack`(默认 `false`)与 `peakCompactOrder`(`bar-first` / `text-first`,默认 `bar-first`)配置项,纳入 `defaultPeakConfig` / `normalizePeakConfig` 与配置层单元测试。
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## v1.5.1(2026-08-24)
|
|
53
|
+
|
|
54
|
+
### 修复
|
|
55
|
+
- **侧边栏底部(sidebar.footer.action)与多插件 UI 兼容**:DSH 渲染器把该槽锚点设为 `display:contents`(见 `dsh-client-ui-renderer` 的 `ANCHOR_STYLE`),导致多个往此槽注册内容的插件(如 `linxin666/dsh-web-ui-all`)被并进同一行、互相挤压。现通过覆盖样式把该锚点改为**纵向堆叠**(`display:flex; flex-direction:column`),使本插件的时段条与其它 footer 插件共存不重叠(思路与 `dsh-footer-order` 一致)。采用稳定 `data-slot` 选择器,收起(rail)态仅显示短词、天然不受影响。
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## v1.5.0(2026-08-24)
|
|
60
|
+
|
|
61
|
+
### 新增
|
|
62
|
+
- **峰谷「时段条样式」新增「环形表盘(24h 中空圆环)」**(替代原「经典(两行)」):
|
|
63
|
+
- 12 档「当前时刻」指针式样可选,默认采用**相位色点**(圆点颜色随相位变化:高峰橙 / 平价蓝 / 周末绿),不再使用从圆心连到边缘的长指针;
|
|
64
|
+
- 圆环按 24h 划分(0:00 顶部、6:00 右、12:00 底、18:00 左),橙色 = 高峰时段(9:00–12:00、14:00–18:00),蓝色 = 平价时段,周末整环无橙色(全天谷价);
|
|
65
|
+
- 圆心展示当前相位词 + 距下次切换倒计时;
|
|
66
|
+
- 新增「显示时间」开关(仅环形表盘)控制是否显示 00:00–21:00 小时刻度。
|
|
67
|
+
- **「简洁(单行紧凑)」时段条改为按 24h 比例划分**:蓝色平价底条铺满 24h,橙色高峰段按窗口比例定位(9:00–12:00 → 37.5%–50%,14:00–18:00 → 58.33%–75%),白色分割线标出「当前时间」实时进度;周末仅蓝底 + 白线。
|
|
68
|
+
|
|
69
|
+
### 改进
|
|
70
|
+
- 后端 `peakSnapshot()` 新增下发结构化窗口数组 `peakHours`(`PEAK_HOUR_WINDOWS`),前端据此绘制比例轨道 / 圆弧,与 `isPeak`/`peakPhaseAt` 计费口径一致;前端内置兜底窗口 `[9,12]`/`[14,18]`。
|
|
71
|
+
- 新增 `peakShowTickLabels` 配置项(默认 `true`),纳入 `defaultPeakConfig` / `normalizePeakConfig`。
|
|
72
|
+
- 新增设计文档 `docs/peak-dial-design.md` 与可交互预览页 `docs/peak-dial-preview.html`(含 12 档指针式样对比)。
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## v1.4.1(2026-08-23)
|
|
77
|
+
|
|
78
|
+
### 修复
|
|
79
|
+
- **修复缓存写入(cache write)计价 bug**:原先 `cacheWrite` 被按「缓存未命中价」计费(flash 3.0 / pro 9.0),导致缓存写入量大的会话费用被严重高估。官方规则(及 `dsh-cost-meter`)约定**缓存写入与缓存命中同价**,现统一为 `(cacheRead + cacheWrite) × 缓存命中价`(flash 0.10 / pro 0.30)。
|
|
80
|
+
- `computeCost()` 改为 `输入×未命中价 + 输出×输出价 + (缓存读+缓存写)×命中价`,与官方/参考口径完全一致。
|
|
81
|
+
- **补充 reasoning(推理)token 计费**:`normalizeTokens()` 新增 `reasoning` 桶(读 `usage.reasoningTokens`),模型单价含 `reasoning` 时按单独单价计费(DeepSeek 当前模型未单独列 reasoning 价,计 0)。
|
|
82
|
+
|
|
83
|
+
### 改进
|
|
84
|
+
- 同步 `EXACT_MODELS` / `SUBSCRIPTION_RATES` / `PROVIDER_RATES` / `GENERIC_RATES` 的 cacheWrite 值(均改为命中价)。
|
|
85
|
+
- 更新 `cost_prices` 工具文案与单元测试(新增「缓存写入按命中价」与「reasoning 计费」用例)。
|
|
86
|
+
|
|
87
|
+
> 说明:本版只修正**单模型计价规则**;不同插件间「调用次数 / 累计用量」的差异源自统计口径(实时 `llm/stream` 与 DSH 会话投影 `(turn,step)` 粒度不同),不属于计价 bug。
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## v1.4.0(2026-08-23)
|
|
92
|
+
|
|
93
|
+
### 新增
|
|
94
|
+
- **峰谷计价提示(对标 dsh-cost-meter)**:
|
|
95
|
+
- 设置页新增「峰谷计价与提示」面板:启用 DeepSeek 峰谷时段价格、峰时高价时段显著提示、时段条样式(简洁/经典)、峰/谷切换前弹窗提醒、提前提醒分钟(1–30)、提醒类型(峰和谷/进入峰/进入谷)、弹窗位置(右下角/屏幕中心)、同步发送系统通知;全部设置即时保存到 `~/.dsh/storages/cost-tracker-config.json`;
|
|
96
|
+
- 侧边栏底部常驻显示时段条(当前档位 + 距下次切换倒计时),窄栏(rail)自适应为短词;悬停可见完整说明;
|
|
97
|
+
- 峰/谷切换前弹窗:距下次切换不足设定提前量时弹出,同一切换点只提醒一次;可一键预览(进入峰 / 进入谷);
|
|
98
|
+
- 浏览器系统通知:开启且有通知授权时,同一切换点额外发一条;
|
|
99
|
+
- 新增 `POST /api/cost-tracker/peak`(峰谷相位快照)与 `POST /api/cost-tracker/peak-config`(保存配置),以及 Agent 工具 `cost_peak`。
|
|
100
|
+
- **六组概览卡**:设置页顶部改版为六张卡——今日费用 / 本月费用 / 总花费 / API 请求次数 / Tokens / **总余额**。今日、本月、总花费三个金额卡**不含订阅会员等效费用**(订阅以附注展示);本月按北京日历月统计;总花费为全时段累计(明细 + 永久日汇总,永远精确)。
|
|
101
|
+
|
|
102
|
+
### 改进
|
|
103
|
+
- **同步 DeepSeek 最新定价规则**:高峰时段限定为北京时间**周一至周五 9:00–12:00、14:00–18:00**,**周末全天计为闲时(闲时半价)**;`isPeak()` 不再忽略星期几,修复周末高峰窗口内被误判为高峰价的问题。
|
|
104
|
+
- 时段条对齐参考项目样式:两段轨道(左橙右蓝)+ 标记线 + 单行着色 chip,窄栏自适应;倒计时文案改为紧凑格式(`5小时56分后进入高峰`)。
|
|
105
|
+
|
|
106
|
+
### 修复
|
|
107
|
+
- 预览弹窗此前强制居中显示,现已**跟随用户配置的弹窗位置**(右下角/屏幕中心)。
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## v1.3.0(2026-08-23)
|
|
112
|
+
|
|
113
|
+
### 新增
|
|
114
|
+
- **Token 用量统计热力图**:
|
|
115
|
+
- 设置页新增「Token 用量统计」面板,类 Codex 的 **26 周每日用量方格热图**;
|
|
116
|
+
- 颜色深浅按当日 token 相对最大值分 4 档,网格自动铺满设置页宽度;
|
|
117
|
+
- 悬停任一格显示当日明细(日期 / 输入 / 缓存 / 输出 / 费用),今天高亮描边;
|
|
118
|
+
- 顶部显示全时段累计(`累计 X tokens · 输入 · 缓存 · 输出 · N 次调用`);
|
|
119
|
+
- 新增 `POST /api/cost-tracker/usage` 端点,返回全时段累计 + 按天 token 聚合;
|
|
120
|
+
- 日期键统一按北京时间(UTC+8)生成,与服务端口径完全一致。
|
|
121
|
+
- **本会话按模型拆分**:状态栏新增按会话实际使用的模型拆分,订阅与按量分开统计。
|
|
122
|
+
|
|
123
|
+
### 改进
|
|
124
|
+
- **状态栏改版**:改为**胶囊分段**布局(本会话 / 订阅套餐 / 分模型),信息清晰、竖线分隔、基线对齐。
|
|
125
|
+
- **只显示本会话花费**:不再显示累计金额,也不再显示当前峰/闲时价。
|
|
126
|
+
- **订阅去重**:订阅只显示一个着色徽标(具体套餐名 + 总等效费用),不再在模型区重复出现。
|
|
127
|
+
- **多模型折叠**:默认只显示消耗 top2 模型 + 数量,点击 `▸` 展开全部模型明细;订阅模型不再混入模型区。
|
|
128
|
+
- **显示精简**:去掉配额(周配额剩)与模型调用次数(`×N`)等噪音信息。
|
|
129
|
+
- **视觉统一**:金额字重与配色统一,与整体主题一致。
|
|
130
|
+
|
|
131
|
+
### 修复
|
|
132
|
+
- 状态栏不再依赖"当前选中的模型"判定显示,而是**按会话实际用到的模型 / 订阅**决定,修复多会话切换时显示错误、订阅会话显示为 ¥0 的问题。
|
|
133
|
+
- 热力图悬停浮层在格子靠近左 / 右 / 顶边界时自适应定位,不再被容器裁剪。
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## v1.2.0(此前)
|
|
138
|
+
|
|
139
|
+
- 支持视觉模型 (`deepseek-v4-flash-vision-exp`) 定价;
|
|
140
|
+
- 订阅计费修复;
|
|
141
|
+
- 新增启动日志开关;
|
|
142
|
+
- 新增三套图表配色(橙→黄 / 蓝→紫 / 蓝→浅蓝)。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Angelyeye
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.en.md
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# <img src="./docs/icon-mark.svg" width="30" valign="bottom" alt="icon"> DSH Cost Tracker
|
|
4
|
+
|
|
5
|
+
**LLM COST & USAGE TRACKING PLUGIN FOR DEEPSEEK HARNESS**
|
|
6
|
+
|
|
7
|
+
[简体中文](./README.md) | **English**
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+

|
|
11
|
+

|
|
12
|
+

|
|
13
|
+
[](https://github.com/Angelyeye/dsh-cost-tracker/stargazers)
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
> An LLM cost-tracking plugin for [DeepSeek Harness](https://github.com/deepseek-ai/dsh): automatically records token usage and cost (CNY) for every API call, with **native support for DeepSeek's official peak/off-peak pricing (half-price off-peak) 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, survives restarts, and uninstalls cleanly.
|
|
20
|
+
|
|
21
|
+
> 一个为 [DeepSeek Harness](https://github.com/deepseek-ai/dsh) 打造的 LLM 花费统计插件:自动记录每一次 API 调用的 Token 用量与费用,**原生支持 DeepSeek 官方峰值价格计费与 Kimi Coding Plan 订阅套餐的用量及等效费用统计**。设置页可视化仪表盘、对话内 Agent 查询、账户余额与订阅配额监控,数据全部本地持久化。
|
|
22
|
+
|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
| | Feature | Description |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| 💰 | **Cost tracking** | Every API call is recorded automatically: input / output / cache-hit / cache-write tokens and cost (cache write billed at the cache-hit price), aggregated by day and by model |
|
|
32
|
+
| ⏰ | **Peak/off-peak pricing** | Built-in price table; peak windows (Mon–Fri 9:00–12:00, 14:00–18:00 Beijing time) vs half-price off-peak handled automatically; **weekends are fully off-peak**; local models (e.g. ollama) count as 0; the table is **versioned by pricing era** and switches automatically to V4.1 Flash rates at 2026-09-10 12:00 Beijing time (peak 2.0 / 0.04 / 8.0), routing V4-Pro and the legacy V4-Flash family to V4.1 Flash billing per the official rules |
|
|
33
|
+
| 🔔 | **Peak-price notice** | A "Peak/off-peak pricing & notice" panel in Settings: current tier + countdown strip, style switch (**compact single-row · 24h-proportional** / **ring dial · phase dot**), an optional **two-row compact** stacked layout for the compact style (bar-above-text / text-above-bar), a "Show time" toggle, popup alert + browser notification before a tier switch, lead time, popup position (bottom-right/center), alert type; a persistent strip in the sidebar footer (adapts to rail/collapsed). Mirrors `dsh-cost-meter` |
|
|
34
|
+
| 📌 | **Six overview cards** | Six cards at the top of Settings: Today / This month / Total spend / API requests / Tokens / **Account balance**. The three spend cards **exclude subscription equivalent cost** (shown as an annotation instead) |
|
|
35
|
+
| 👁️ | **Vision model** | Supports `deepseek-v4-flash-vision-exp`: priced as flash in the legacy era, billed at V4.1 Flash rates from 2026-09-10 12:00; images are converted to tokens per the official rule (≤384 tokens each, billed per API usage) |
|
|
36
|
+
| 📊 | **Visual dashboard** | A new "Cost Statistics" page in Settings: overview cards, cost bar charts (by peak period / by model), per-model request & token charts — **all with hover tooltips** |
|
|
37
|
+
| 📈 | **Subscription quota** | Kimi Coding Plan and similar subscriptions: weekly quota, 5-hour rolling window limit, pay-as-you-go-equivalent cost for reference |
|
|
38
|
+
| 💳 | **Balance lookup** | One-click DeepSeek account balance (total / topped-up / granted / status) |
|
|
39
|
+
| 🤖 | **Agent tools** | Ask in any chat: "how much have I spent today?" — the agent answers via `cost_stats` / `cost_prices` |
|
|
40
|
+
| 🔻 | **Status line** | A live line under the chat input: **session cost** (segmented pills: session / subscription plan / per-model), split by the models actually used in the session; multi-model collapses to top2 by default, click to expand. Subscription shows the plan name; no quota or call-count clutter |
|
|
41
|
+
| 🔥 | **Usage heatmap** | A "Token Usage" panel in Settings: a Codex-style **26-week daily-usage grid**, colored per-day by input / cache / output / cost with hover details and a today outline; all-time totals shown on top |
|
|
42
|
+
| 💾 | **Local persistence** | Data lives in `~/.dsh/storages/cost-tracker-records.json`; survives restarts, never leaves your machine. **Details are kept for the last 180 days; older records are auto-compressed into permanent daily rollups, so all-time stats stay exact with bounded memory/disk** |
|
|
43
|
+
| 📤 | **CSV export** | One-click export of details + daily rollups (`purpose=rollup`) for further analysis in Excel / Numbers |
|
|
44
|
+
|
|
45
|
+
## Screenshots
|
|
46
|
+
|
|
47
|
+
**Ask the agent directly** — built-in cost/balance/price tools with a live status line under the input box:
|
|
48
|
+
|
|
49
|
+

|
|
50
|
+
|
|
51
|
+
**Subscription quota & account balance** — progress bars, reset countdowns and balance at a glance:
|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+
**Per-model details** — request trends and token composition per model, with hover tooltips:
|
|
56
|
+
|
|
57
|
+

|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Installation (choose one)
|
|
62
|
+
|
|
63
|
+
> Prerequisite: you already run DSH in web mode (`dsh web`). `~/.dsh` below means the DSH home directory (`${DSH_HOME:-$HOME/.dsh}`).
|
|
64
|
+
>
|
|
65
|
+
> One caveat for Option A: the plugin marketplace itself requires `dsh web ≥ 0.1.0-rc.6`. On an older host the **Plugin Marketplace** entry never appears at all — in that case use Option B or Option C.
|
|
66
|
+
|
|
67
|
+
### Option A: Install from the plugin marketplace (recommended)
|
|
68
|
+
|
|
69
|
+
This plugin is listed in the curated [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin) catalog (category `usage`). Open **Settings → Plugin Marketplace** inside DSH, search for `dsh-cost-tracker` and press install. The equivalent command line is:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
dsh plugin --profile web add @angelyeye/dsh-cost-tracker
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
> If you read this before the npm mapping is live, `dsh plugin --profile web add github:Angelyeye/dsh-cost-tracker` works too — it installs from the repository and yields the same package.
|
|
76
|
+
|
|
77
|
+
The marketplace installs the plugin into your profile and writes the loader config for you. It installs **the latest published version** — no manual `git clone`, no hand-editing the patch file. Restart `dsh web` and refresh the browser when prompted.
|
|
78
|
+
|
|
79
|
+
### Option B: Let DSH install it for you (no CLI knowledge needed)
|
|
80
|
+
|
|
81
|
+
Open any DSH session and paste this prompt verbatim to the agent:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Please install the DSH plugin @angelyeye/dsh-cost-tracker for me:
|
|
85
|
+
1. git clone https://github.com/Angelyeye/dsh-cost-tracker.git into ~/.dsh/profiles/node_modules/@angelyeye/dsh-cost-tracker (the directory MUST match the package name)
|
|
86
|
+
2. Append to the top-level array of ~/.dsh/profiles/web/cordis.patch.yml:
|
|
87
|
+
- insert:
|
|
88
|
+
- id: dsh-cost-tracker
|
|
89
|
+
name: "@angelyeye/dsh-cost-tracker"
|
|
90
|
+
3. Tell me when done — I will restart dsh web myself
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Then stop `dsh web` with `Ctrl+C`, start it again, and refresh your browser.
|
|
94
|
+
|
|
95
|
+
### Option C: Manual install (3 commands)
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# 1. Download the plugin (directory name must match the package name)
|
|
99
|
+
mkdir -p ~/.dsh/profiles/node_modules/@angelyeye
|
|
100
|
+
git clone https://github.com/Angelyeye/dsh-cost-tracker.git ~/.dsh/profiles/node_modules/@angelyeye/dsh-cost-tracker
|
|
101
|
+
|
|
102
|
+
# 2. Register the plugin (append to the patch file)
|
|
103
|
+
cat >> ~/.dsh/profiles/web/cordis.patch.yml <<'EOF'
|
|
104
|
+
- insert:
|
|
105
|
+
- id: dsh-cost-tracker
|
|
106
|
+
name: "@angelyeye/dsh-cost-tracker"
|
|
107
|
+
EOF
|
|
108
|
+
|
|
109
|
+
# 3. Restart DSH (Ctrl+C the running dsh web first)
|
|
110
|
+
dsh web
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Verify it works
|
|
114
|
+
|
|
115
|
+
1. Open the DSH Web GUI → **Settings** (bottom-left) → a **"Cost Statistics"** entry appears in the sidebar;
|
|
116
|
+
2. A cost status line shows up under the chat input;
|
|
117
|
+
3. Ask the agent "check my current spending" — a correct answer means everything is ready.
|
|
118
|
+
|
|
119
|
+
> ⚠️ If `~/.dsh/profiles/web/cordis.patch.yml` already contains entries, keep them and only append the block above; the file's top level must remain a YAML array.
|
|
120
|
+
|
|
121
|
+
### Migrating from the old package name (only installs of v1.6.0 or older)
|
|
122
|
+
|
|
123
|
+
As of v1.7.0 the package name changed from `dsh-cost-tracker` to `@angelyeye/dsh-cost-tracker` — the old name is held on npm by an unrelated package, and the marketplace's npm mapping requires the published name to equal the repository's `package.json` `name`.
|
|
124
|
+
|
|
125
|
+
⚠️ **Do not simply install the new version on top of the old one.** Both versions' `cordis.patch.yml` insert the **same loader id** (`dsh-cost-tracker`), so stacking them loads **both copies** — duplicated HTTP routes, agent tools and UI slots. Remove the old one first:
|
|
126
|
+
|
|
127
|
+
**Marketplace install** (installed via `dsh plugin add`):
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
dsh plugin --profile web remove dsh-cost-tracker
|
|
131
|
+
dsh plugin --profile web add github:Angelyeye/dsh-cost-tracker
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Manual clone install**:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# 1. Edit ~/.dsh/profiles/web/cordis.patch.yml and remove the - insert: block whose id is dsh-cost-tracker (4 lines)
|
|
138
|
+
# 2. Delete the old directory
|
|
139
|
+
rm -rf ~/.dsh/profiles/node_modules/dsh-cost-tracker
|
|
140
|
+
# 3. Reinstall once via Option A above
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**No data is lost**: usage records live in `~/.dsh/storages/cost-tracker-records.json`, independent of the plugin directory.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Usage
|
|
148
|
+
|
|
149
|
+
### The Settings dashboard
|
|
150
|
+
|
|
151
|
+
- **Time range**: switch between last 7 days / 30 days / all time (top-right);
|
|
152
|
+
- **Six overview cards**: Today / This month / Total spend / API requests / Tokens / Account balance. The three spend cards exclude subscription equivalent cost (shown as an annotation); month is by Beijing calendar month; total is all-time (details + permanent rollups, always exact);
|
|
153
|
+
- **Cost chart**: segment by peak period or by model; hover for daily breakdowns;
|
|
154
|
+
- **Color schemes**: in "by model" view, three swatches next to the title switch between 橙→黄 / 蓝→紫 / 蓝→浅蓝 palettes. Models are ranked by total spend and colored in a sequential gradient (rank 1 = darkest at the bottom, getting lighter upwards; no cycling, no collisions). The choice is remembered in the browser (localStorage);
|
|
155
|
+
- **Per-model sections**: one request-count chart and one token-composition chart (input / cache write / output / cache hit) per model;
|
|
156
|
+
- **Usage heatmap**: a Codex-style 26-week daily-usage grid; shade by the day's token count relative to the maximum; hover any cell for that day's breakdown (input / cache / output / cost), today outlined;
|
|
157
|
+
- **Peak/off-peak pricing & notice**: pick the tier strip style (**compact single-row — a 24h-proportional bar with a white real-time line** / **ring dial — a 24h hollow dial with a phase-colored dot**), optionally switch the compact strip to a **two-row compact** stacked layout (bar-above-text or text-above-bar), toggle the "Show time" tick labels (00:00–21:00), set the popup-alert lead time (1–30 min), alert type (both / entering peak / entering off-peak), popup position (bottom-right / center), and optional browser system notification; everything auto-saves. A persistent strip in the sidebar footer shows the current tier and countdown to the next switch;
|
|
158
|
+
- **CSV export**: exports detail records (last 180 days) plus daily rollup rows (`purpose=rollup`).
|
|
159
|
+
|
|
160
|
+
### Agent tools
|
|
161
|
+
|
|
162
|
+
| Tool | Purpose | Example prompt |
|
|
163
|
+
| --- | --- | --- |
|
|
164
|
+
| `cost_stats` | Query usage & cost statistics | "How much did I spend today?" |
|
|
165
|
+
| `cost_prices` | Show the built-in price table & peak rules | "What does deepseek-v4-flash cost right now?" |
|
|
166
|
+
| `cost_peak` | Show the current peak tier & next-switch countdown | "Is it peak hour right now?" |
|
|
167
|
+
| `cost_recompute` | **Re-price stored records by pricing era (one-off backfill)**, dry-run by default | "Re-price the records from before the price change" |
|
|
168
|
+
| `cost_reset` | **Erase ALL statistics (irreversible)** | "Reset my cost statistics" |
|
|
169
|
+
|
|
170
|
+
### HTTP API (for other tools)
|
|
171
|
+
|
|
172
|
+
All endpoints are `POST` + JSON and listen on the loopback address:
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
POST /api/cost-tracker/summary Overview
|
|
176
|
+
POST /api/cost-tracker/dashboard Dashboard data
|
|
177
|
+
POST /api/cost-tracker/usage Usage heatmap (all-time totals + daily token aggregation)
|
|
178
|
+
POST /api/cost-tracker/peak Peak-phase snapshot (current tier / next switch / config)
|
|
179
|
+
POST /api/cost-tracker/peak-config Save peak-price notice config
|
|
180
|
+
POST /api/cost-tracker/kimi-usage Kimi subscription quota
|
|
181
|
+
POST /api/cost-tracker/balance Account balance
|
|
182
|
+
POST /api/cost-tracker/prices Price table (versioned by pricing era)
|
|
183
|
+
POST /api/cost-tracker/recompute Re-price stored records by era (dry-run unless {"apply":true})
|
|
184
|
+
POST /api/cost-tracker/export CSV export
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Example: `curl -X POST http://127.0.0.1:3080/api/cost-tracker/summary -d '{}'`
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Changelog
|
|
192
|
+
|
|
193
|
+
### v1.6.0 (2026-09-10)
|
|
194
|
+
|
|
195
|
+
**Added**
|
|
196
|
+
- **Support for the V4.1 Flash pricing rules (effective 2026-09-10 12:00 Beijing time)**: the price table is now **versioned by pricing era** (`PRICE_ERAS`) and each record is priced with **its own timestamp**, so historical records keep their original basis and the switch happens automatically — no restart or config change needed.
|
|
197
|
+
- New era `v41` (2026-09-10 12:00 Beijing = `2026-09-10T04:00:00Z`): V4.1 Flash peak rates are **input (cache hit) 0.04 / input (cache miss) 2 / output 8** (CNY per 1M tokens); off-peak remains exactly half (0.02 / 1 / 4). **Peak windows are unchanged**, so the peak strip and countdown need no changes.
|
|
198
|
+
- New **model routing** (per-era `routes`): until V4.1 Pro ships, V4-Pro requests are routed to V4.1 Flash and billed at V4.1 Flash rates; the legacy V4-Flash family (including `deepseek-v4-flash-vision-exp`) is superseded by V4.1 Flash and billed the same way. **Records are booked under the model that was actually billed** (e.g. `deepseek-v4-pro` → `deepseek-v4.1-flash`), so per-model aggregation reflects the real billing basis.
|
|
199
|
+
- New exports: `V41_EFFECTIVE_AT` / `V41_FLASH_MODEL` / `PRICE_ERAS` / `eraAt()` / `exactModelsAt()` / `resolveModelInEra()` / `normalizeModelName()`.
|
|
200
|
+
- **Model-name normalization**: names are lowercased with separators stripped, so `deepseek-v4.1-flash` / `deepseek-v4-1-flash` / `deepseek-v41-flash` / `DeepSeek-V4.1-Flash` all resolve to the same rate, preventing a silently mis-priced fallback if the official model ID is spelled differently.
|
|
201
|
+
- `cost_prices` and the HTTP `/prices` endpoint now **render every era**: effective time, rates and routing rules, plus the currently effective era (`era` / `eraLabel` / `eras` / `v41EffectiveAt`).
|
|
202
|
+
|
|
203
|
+
- **New `cost_recompute` one-off backfill tool** (also exposed as HTTP `/api/cost-tracker/recompute`): re-prices stored records and rewrites the billed model name using the timestamp of each record. It targets records booked at the old price between the era switch and a host restart; it **dry-runs by default** and writes back only with `apply: true`, and it is idempotent. Only detail rows are recomputed (details cover the last 180 days; older records are already folded into daily rollups whose time range predates any pricing switch).
|
|
204
|
+
|
|
205
|
+
**Changed**
|
|
206
|
+
- `priceFor(np, model, ts)` gained a third `ts` argument (timestamp of the call, defaults to now) and now also returns `model` (the canonical **billed** model name) and `era`. The recording path passes the record timestamp.
|
|
207
|
+
- The DeepSeek provider fallback rate now matches V4.1 Flash (`2.0 / 8.0 / 0.04`) so unknown deepseek models are no longer over-estimated at the old price.
|
|
208
|
+
- `EXACT_MODELS` now means the **legacy era** table specifically; kept exported for compatibility.
|
|
209
|
+
|
|
210
|
+
**Tests**
|
|
211
|
+
- New era/routing cases in `test/pricing.test.js` (boundary 11:59:59 vs 12:00:00, V4-Pro routing, legacy V4-Flash routing, alias normalization, off-peak half price, dangling-route guard).
|
|
212
|
+
- All rate assertions now pass an **explicit timestamp** so results no longer drift with wall-clock time across the 12:00 switch.
|
|
213
|
+
|
|
214
|
+
**Cost impact (same call, peak)**
|
|
215
|
+
- V4-Pro (100k input miss + 6k output + 20k cache hit): **¥1.068 → ¥0.2488** (about **-76.7%**).
|
|
216
|
+
- Legacy V4-Flash, same volumes: **¥0.356 → ¥0.2488** (about **-30.1%**).
|
|
217
|
+
|
|
218
|
+
### v1.5.2 (2026-08-25)
|
|
219
|
+
|
|
220
|
+
**Added**
|
|
221
|
+
- **"Two-row compact (stacked layout)" option for the compact strip**: with the "Compact (single row)" style selected, a new checkbox switches the strip from left-right to a stacked two-row layout, with a further choice of "bar on top · text below" (default) or "text on top · bar below"; applies to both the sidebar footer and the settings preview.
|
|
222
|
+
- New `peakCompactStack` (default `false`) and `peakCompactOrder` (`bar-first` / `text-first`, default `bar-first`) config options, covered by `defaultPeakConfig` / `normalizePeakConfig` and the config unit tests.
|
|
223
|
+
|
|
224
|
+
**Fixed**
|
|
225
|
+
- In stacked mode the track's `flex-basis` (72px) landed on the vertical axis, stretching the strip to 72px tall; overridden with `flex: 0 0 auto` to keep the same 6px slim bar as the single-row layout.
|
|
226
|
+
|
|
227
|
+
### v1.5.1 (2026-08-24)
|
|
228
|
+
|
|
229
|
+
**Fixed**
|
|
230
|
+
- **Sidebar footer (`sidebar.footer.action`) UI compatibility with multiple plugins**: DSH's renderer sets that slot's anchor to `display: contents`, so several plugins registering there (e.g. `linxin666/dsh-web-ui-all`) get squeezed into one row and overlap. The anchor is now overridden to stack **vertically** (`display:flex; flex-direction:column`), so this plugin's tier strip coexists with other footer plugins without overlapping (same idea as `dsh-footer-order`); it uses the stable `data-slot` selector and is unaffected in the collapsed (rail) state.
|
|
231
|
+
|
|
232
|
+
### v1.5.0 (2026-08-24)
|
|
233
|
+
|
|
234
|
+
**Added**
|
|
235
|
+
- **Tier-strip "style" gains a "Ring dial (24h hollow)"** (replaces the old "Classic/ two rows"): divided by 24h (00:00 top, 06:00 right, 12:00 bottom, 18:00 left) — orange = peak hours (9:00–12:00, 14:00–18:00), blue = off-peak, weekend is all-blue (all-day off-peak). 12 selectable "current-time" pointer schemes (default: **phase-colored dot** — peak orange / off-peak blue / weekend green); no more long center-to-edge needle. The center shows the current phase + countdown to the next switch.
|
|
236
|
+
- **"Show time" toggle** (ring dial only): show/hide the 00:00–21:00 hour tick labels, default on.
|
|
237
|
+
- **"Compact (single-row)" strip is now 24h-proportional**: a blue off-peak base bar spanning 24h, with orange peak segments placed proportionally (9:00–12:00 → 37.5%–50%, 14:00–18:00 → 58.33%–75%), and a white divider line marking the real-time "current time"; weekends show only the blue base + white line.
|
|
238
|
+
|
|
239
|
+
**Improved**
|
|
240
|
+
- Backend `peakSnapshot()` now returns a structured `peakHours` array (`PEAK_HOUR_WINDOWS`); the frontend draws the proportional bar / arcs from it, keeping the same basis as `isPeak`/`peakPhaseAt`. A hardcoded fallback `[9,12]`/`[14,18]` is bundled as well.
|
|
241
|
+
- New `peakShowTickLabels` config option (default `true`), added to `defaultPeakConfig` / `normalizePeakConfig`.
|
|
242
|
+
- Added design doc `docs/peak-dial-design.md` and an interactive preview page `docs/peak-dial-preview.html` (with all 12 pointer schemes).
|
|
243
|
+
|
|
244
|
+
### v1.4.1 (2026-08-23)
|
|
245
|
+
|
|
246
|
+
**Fixed cache-write pricing and added reasoning billing (aligned with official rules & dsh-cost-meter)**
|
|
247
|
+
|
|
248
|
+
- **Fixed cache-write (cacheWrite) pricing bug**: previously `cacheWrite` was billed at the **cache-miss** price (flash 3.0 / pro 9.0), badly overcharging sessions with heavy cache writes. The official rule (and `dsh-cost-meter`) sets **cache write = cache-hit price**, now unified as `(cacheRead + cacheWrite) × cache-hit price` (flash 0.10 / pro 0.30).
|
|
249
|
+
- `computeCost()` is now `input×miss-price + output×output-price + (cacheRead+cacheWrite)×hit-price`, matching the official / reference formula exactly.
|
|
250
|
+
- **Added reasoning-token billing**: `normalizeTokens()` now has a `reasoning` bucket (reads `usage.reasoningTokens`); a model price containing `reasoning` bills it at its own unit price (DeepSeek current models list no separate reasoning price → 0).
|
|
251
|
+
- Synced `cacheWrite` to the hit price across `EXACT_MODELS` / `SUBSCRIPTION_RATES` / `PROVIDER_RATES` / `GENERIC_RATES`.
|
|
252
|
+
- Updated the `cost_prices` tool text and unit tests (added "cache write at hit price" and "reasoning billing" cases).
|
|
253
|
+
|
|
254
|
+
> Note: this release only fixes **per-model pricing**. Differences between plugins in "call counts / cumulative usage" stem from counting granularity (live `llm/stream` vs DSH session projection `(turn,step)`), which is not a pricing bug.
|
|
255
|
+
|
|
256
|
+
### v1.4.0 (2026-08-23)
|
|
257
|
+
|
|
258
|
+
**New**
|
|
259
|
+
- **Peak-price notice (mirrors `dsh-cost-meter`)**: a "Peak/off-peak pricing & notice" panel in Settings — enable peak/off-peak pricing, prominent peak notice, strip style (compact / classic), popup alert before a tier switch, lead time (1–30 min), alert type (both / peak / off-peak), popup position (bottom-right / center), and optional browser system notification. All settings auto-save to `~/.dsh/storages/cost-tracker-config.json`. A persistent strip in the sidebar footer shows the current tier + countdown to the next switch, and adapts to the collapsed (rail) state. Adds `POST /api/cost-tracker/peak` and `POST /api/cost-tracker/peak-config`, plus the `cost_peak` agent tool.
|
|
260
|
+
- **Six overview cards**: Today / This month / Total spend / API requests / Tokens / **Account balance**. The three spend cards **exclude subscription equivalent cost** (shown as an annotation); month is by Beijing calendar month; total is all-time (details + permanent rollups, always exact).
|
|
261
|
+
|
|
262
|
+
**Improved**
|
|
263
|
+
- **Synced with DeepSeek's latest pricing**: peak hours are now **Mon–Fri 9:00–12:00, 14:00–18:00 Beijing time**, with **weekends fully off-peak (half price)**; `isPeak()` no longer ignores the weekday, fixing weekends being wrongly billed at peak rates.
|
|
264
|
+
- The notice strip now matches the reference project: a two-segment track (orange left / blue right) + marker + single-line colored chip.
|
|
265
|
+
|
|
266
|
+
**Fixed**
|
|
267
|
+
- The preview popup was hardcoded to center; it now **follows your configured popup position** (bottom-right / center).
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## FAQ
|
|
272
|
+
|
|
273
|
+
**Q: Where is my data? Is it safe?**
|
|
274
|
+
Everything stays on your machine in `~/.dsh/storages/cost-tracker-records.json`; nothing is uploaded. The API binds to loopback but has no authentication — **do not expose the DSH port to the public internet**.
|
|
275
|
+
|
|
276
|
+
**Q: Do I lose data when DSH restarts?**
|
|
277
|
+
No. Records are flushed to disk with debounced atomic writes and restored on startup. A corrupted file is backed up as `.corrupt-<timestamp>` and tracking restarts cleanly.
|
|
278
|
+
|
|
279
|
+
**Q: How long is history kept? Is there a stats cap?**
|
|
280
|
+
Detail records are kept for the last **180 days**; older records are auto-compressed into **permanent daily rollups** (aggregates only: calls / token breakdown / cost — no per-call details). So all-time totals and per-model stats stay **exact forever**, while memory, disk and write volume stay bounded no matter how long you run. The daily chart axis spans up to 730 days. Old-format data files migrate automatically; set the `DSH_COST_TRACKER_STORE` env var to override the store path (default `$DSH_HOME/storages`, or `~/.dsh` when `DSH_HOME` is unset).
|
|
281
|
+
|
|
282
|
+
**Q: How do I enable/disable the startup logs?**
|
|
283
|
+
The plugin starts **silently by default**. Set the environment variable `DSH_COST_TRACKER_LOG=1` (or `true` / `yes` / `on`) to enable startup logs: nav-icon self-check results, the data-restore report (`restored N detail records ...`) and the ready marker. **Error logs** (persist failures, corrupted files, etc.) are always printed and are not affected by this switch.
|
|
284
|
+
|
|
285
|
+
**Q: What does "equivalent cost" mean for subscription models (kimi-coding)?**
|
|
286
|
+
Subscriptions are not billed per token. The plugin estimates what those calls *would* cost at pay-as-you-go prices so you can judge whether your subscription pays off — **it is not a real charge**.
|
|
287
|
+
|
|
288
|
+
**Q: The amounts don't exactly match my official bill?**
|
|
289
|
+
Costs are estimated locally from a built-in price table and may differ slightly from the official bill (price updates, tiered pricing, etc.). Treat official billing as authoritative; the balance shown is fetched live from the official API.
|
|
290
|
+
|
|
291
|
+
**Q: How do I uninstall?**
|
|
292
|
+
1. **Remove the loader entry first** — marketplace install: open **Settings → Plugin Marketplace → Installed** and uninstall there (it also cleans up the patch entry it wrote); manual install: open `~/.dsh/profiles/web/cordis.patch.yml` and remove the 4-line `- insert:` block for `dsh-cost-tracker` (or ask the DSH agent to do it);
|
|
293
|
+
2. Restart `dsh web`;
|
|
294
|
+
3. Optionally delete `~/.dsh/profiles/node_modules/@angelyeye/dsh-cost-tracker` and `~/.dsh/storages/cost-tracker-records.json`.
|
|
295
|
+
|
|
296
|
+
**Q: How do I update the plugin?**
|
|
297
|
+
- **Marketplace install:** open **Settings → Plugin Marketplace → Updates**, or re-run `dsh plugin --profile web add @angelyeye/dsh-cost-tracker`;
|
|
298
|
+
- **Manual install:** run `git pull` inside the plugin directory.
|
|
299
|
+
|
|
300
|
+
Either way: if only the UI (`client.js`) changed, a **hard browser refresh** (Cmd/Ctrl+Shift+R) is enough; if `index.js` changed, restart `dsh web`.
|
|
301
|
+
|
|
302
|
+
## Repository layout
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
├── index.js Host half: usage capture, aggregation, HTTP API, agent tools
|
|
306
|
+
├── store.js Storage layer: 180-day detail retention + permanent daily rollups + persistence (pure logic, unit-testable)
|
|
307
|
+
├── pricing.js Pricing & tokens: price tables, peak/off-peak billing, vision model, peak-phase math (pure logic, unit-testable)
|
|
308
|
+
├── config.js Config layer: defaults & normalization for the peak-price notice (pure logic, unit-testable)
|
|
309
|
+
├── client.js Client half: settings dashboard, status line & peak-price notice UI
|
|
310
|
+
├── package.json Plugin manifest: declares dsh.bundle (what makes it installable) and dsh.client (browser UI)
|
|
311
|
+
├── cordis.patch.yml Bundle patch: registers the plugin with DSH's loader, pointed at by dsh.bundle
|
|
312
|
+
├── screenshots.json Marketplace detail-page screenshot list (relative paths, 1-8 images)
|
|
313
|
+
├── test/ Unit tests (storage / pricing / config / recompute, node test/*.test.js)
|
|
314
|
+
└── docs/ README screenshots and design notes
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## License
|
|
318
|
+
|
|
319
|
+
[MIT](./LICENSE) · Issues and PRs welcome
|