dsh-plugin-billing-card 0.0.0-stage → 0.1.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/README.md CHANGED
@@ -1,3 +1,197 @@
1
- # Temporary Holding Version
1
+ # dsh-plugin-billing-card(计费卡片)
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 在 DeepSeek Harness 的输入框下方实时显示**当前会话**的 token 用量与估算费用,按模型分项统计,
4
+ 默认内置 DeepSeek 官方价格(含**峰谷分时计价**),并保留完整的扩展能力:价格表、峰谷规则、
5
+ 其他模型/提供商都可以在插件配置里追加,不需要改代码。
6
+
7
+ - **Host 半**:注册一个客户端可见的 Session 投影单元 `billingUsage`,在提交事件时折叠
8
+ `assistant/message` / `assistant/attempt` 中模型上报的 `usage`,按 `request/header` 归属模型路由,
9
+ 纯函数、可重放、不产生任何模型调用。
10
+ - **Client 半**:在 `conversation.composer.dock`(输入框下方的环境条目区)新增一个
11
+ `billing-card` 条目;平时是一枚小药丸(金额 + token 数),点开后是分模型明细卡片。
12
+
13
+ > 显示的是**按 token 数与价格表计算的估算值**,不是官方账单。实际扣费以 DeepSeek 账单为准。
14
+
15
+ ## 显示内容
16
+
17
+ 药丸(收起态):`¥0.0123 · 15.2K tok`,鼠标悬停/读屏可读到完整摘要(金额、token、缓存命中率)。
18
+
19
+ 卡片(展开态):
20
+
21
+ - 本会话估算总费用;若包含高峰时段计价的 token,会标注「含高峰计价」。
22
+ - token 汇总:缓存未命中输入、缓存命中输入(及命中率)、输出、合计。
23
+ - 按模型分项:模型名、token 数、估算费用;没有配置价格的模型显示「未配置价格」,
24
+ token 仍计入合计,但不计入费用。
25
+
26
+ 会话还没有任何已结算的 token 用量时,卡片不显示(不会占位、不会报错)。
27
+
28
+ ## 安装
29
+
30
+ 推荐先在一个**独立的开发 profile** 里安装与验证,不要装进你日常使用的 `desktop` profile:
31
+
32
+ ```bash
33
+ # 1. 从官方 web 模板新建一个独立 profile(只在不存在时创建;不会打开浏览器)
34
+ dsh --profile billing-dev --from-default-profile web --dump-config
35
+
36
+ # 2. 安装本插件(本地目录,link 方式;无需构建步骤)
37
+ dsh plugin --profile billing-dev add D:\program\dsh-plugins\dsh-plugin-billing-card
38
+
39
+ # 3. 启动 web profile(--no-open 不会抢占浏览器/桌面焦点;端口按需修改)
40
+ dsh --profile billing-dev --no-open --port 58121
41
+ ```
42
+
43
+ 启动日志会打印带一次性 `?token=` 的地址,用浏览器打开即可;插件行 id 为 `billing-card`,
44
+ 包名为 `dsh-plugin-billing-card`。验证完成后,也可以把它装进你自己的正式 profile:
45
+
46
+ ```bash
47
+ dsh plugin --profile <你的profile> add D:\program\dsh-plugins\dsh-plugin-billing-card
48
+ ```
49
+
50
+ > 新装的 Client 模块需要页面刷新一次才会加载;旧会话的投影基线也在刷新/重连后才会带上
51
+ > `billingUsage`,刷新后输入框下方就会出现计费药丸。
52
+
53
+ 如果是在当前会话里用 `plugin_manager` 安装(会让该 profile 的所有会话生效),写法是:
54
+
55
+ ```
56
+ plugin_manager install_bundle target = D:\program\dsh-plugins\dsh-plugin-billing-card
57
+ ```
58
+
59
+ 如手工维护 profile 的 `cordis.patch.yml`,等价写法是:
60
+
61
+ ```yaml
62
+ - insert:
63
+ - id: billing-card
64
+ name: dsh-plugin-billing-card
65
+ ```
66
+
67
+ ## 默认价格表(官方价格,绑定于 2026-10-17)
68
+
69
+ 计价口径:1) **缓存未命中输入** = `TokenUsage.inputTokens`;2) **缓存命中输入** =
70
+ `TokenUsage.cacheReadTokens`;3) **输出** = `TokenUsage.outputTokens`;4) `cacheWriteTokens`
71
+ 默认按 0 元计(DeepSeek 不单独收缓存写入费),可用规则覆盖。
72
+
73
+ 官方页面把**空闲时段价格**写成高峰时段的一半;本插件以空闲时段价格为基础价,
74
+ `peak.multiplier`(默认 2)在高峰时段生效。
75
+
76
+ ### 人民币(默认 `currency: CNY`,单位:元 / 百万 tokens,空闲时段基础价)
77
+
78
+ | 模型 | 输入(缓存未命中) | 输入(缓存命中) | 输出 |
79
+ |---|---|---|---|
80
+ | `deepseek-flash`(DeepSeek-V4.1-Flash) | 1 | 0.02 | 4 |
81
+ | `deepseek-v4-pro`(DeepSeek-V4-Pro) | 4.5 | 0.15 | 13.5 |
82
+ | `deepseek-v4-flash`、`deepseek-v4-flash-vision-exp`(旧名,按 Flash 计价) | 1 | 0.02 | 4 |
83
+
84
+ 高峰时段(北京时间,周一至周五,不含中国法定节假日):**09:00–12:00、14:00–18:00**;
85
+ 其余时间(含周末与法定节假日全天)为空闲时段。
86
+
87
+ ### 美元(`currency: USD`,单位:美元 / 百万 tokens,空闲时段基础价)
88
+
89
+ | 模型 | 输入(缓存未命中) | 输入(缓存命中) | 输出 |
90
+ |---|---|---|---|
91
+ | `deepseek-flash` | 0.15 | 0.003 | 0.6 |
92
+ | `deepseek-v4-pro` | 0.66 | 0.022 | 1.98 |
93
+ | `deepseek-v4-flash`、`deepseek-v4-flash-vision-exp` | 0.15 | 0.003 | 0.6 |
94
+
95
+ > 价格来源:DeepSeek 官方「模型 & 价格」页(中文 / 英文),核对时间 2026-10-17。
96
+ > 官方保留调价权利,请以官网与你的实际结算为准;调价后覆盖本插件配置即可。
97
+
98
+ ## 配置
99
+
100
+ 配置写在插件行 `billing-card` 的 `config` 里(profile 的 `cordis.patch.yml` 对整行 `config`
101
+ 的覆盖会整表替换,未写的可选项使用默认值)。所有字段都有严格校验:拼写错误、负数、
102
+ 非法时间窗口会直接报错并指出配置路径,不会静默忽略。
103
+
104
+ ```yaml
105
+ - id: billing-card
106
+ config:
107
+ currency: CNY # CNY | USD,默认 CNY
108
+
109
+ # 追加/覆盖价格规则;优先于内置默认表,按顺序取第一条命中的规则。
110
+ pricing:
111
+ - provider: '*' # 精确 provider 路由或 '*',默认 '*'
112
+ model: deepseek-flash
113
+ inputPerM: 1 # 缓存未命中输入,元/百万 tokens
114
+ cacheReadPerM: 0.02 # 缓存命中输入
115
+ cacheWritePerM: 0 # 可选,默认 0
116
+ outputPerM: 4
117
+ peakMultiplier: 2 # 可选,默认取 peak.multiplier
118
+
119
+ # 峰谷规则(默认即下方深色默认值,可整体调参或关闭)
120
+ peak:
121
+ enabled: true
122
+ utcOffsetMinutes: 480 # 北京时间 UTC+8
123
+ weekdays: [1, 2, 3, 4, 5] # 周一=1 … 周日=7
124
+ windows: [['09:00', '12:00'], ['14:00', '18:00']]
125
+ holidays: [] # 例:['2026-10-01', '2026-10-02'];列出的当地日期全天按空闲计价
126
+ multiplier: 2
127
+ ```
128
+
129
+ ### 支持其他提供商 / 模型
130
+
131
+ 规则的匹配优先级是:用户规则(精确 provider + 精确 model → 精确 provider + `model: '*'` →
132
+ `provider: '*'` + 精确 model → 全通配)→ 内置默认表。因此:
133
+
134
+ - 换用美元计价:`currency: USD`(内置美元表)。
135
+ - 给自建/第三方模型定价(例如经 OpenAI 兼容端点接入的 GLM):
136
+
137
+ ```yaml
138
+ - id: billing-card
139
+ config:
140
+ pricing:
141
+ - provider: llm-pi-ai
142
+ model: GLM/glm-5.3
143
+ inputPerM: 2
144
+ cacheReadPerM: 0.5
145
+ outputPerM: 8
146
+ - provider: llm-pi-ai # 该 provider 下未单独定价的模型统一兜底
147
+ model: '*'
148
+ inputPerM: 2
149
+ cacheReadPerM: 0.5
150
+ outputPerM: 8
151
+ ```
152
+
153
+ - 某提供商有自己的一套峰谷/折扣规则:给它的规则单独设置 `peakMultiplier`,
154
+ 或把全局 `peak.enabled` 设为 `false` 后按固定价计。
155
+
156
+ > 规则里的 `currency` 默认等于全局 `currency`;写别的币种会被忽略(不会混币种加总)。
157
+
158
+ ## 数据口径与已知限制
159
+
160
+ - token 数来自会话日志里模型**上报的 usage**(与 Harness 内置 token 统计同源),不是本地估算;
161
+ 失败重试的尝试(`assistant/attempt`)与成功回复都计费,重试会被识别为独立计费尝试。
162
+ - 费用 = token 数 × 价格表;高峰/空闲按**该条 usage 在日志中记录的时间**判定,
163
+ 事件时间是持久化的,因此重放、恢复、fork 后结果一致。
164
+ - **辅助调用暂不计量**:会话标题生成、压缩摘要等旁路模型调用的响应 usage 不写入会话日志,
165
+ 因此不计入本卡片;如后续 Harness 落盘这类 usage,只需扩展折叠的事件类型。
166
+ - **法定节假日不会自动识别**:官方规则里中国法定节假日按空闲计价,插件无法内置年年变化的
167
+ 节假日表,请在 `peak.holidays` 里按需填写;不填写时只按「周一至周五 + 时间窗口」判断。
168
+ - 金额为估算值,浮点计算后仅用于展示(保留 2–4 位小数);并发上限、搜索/抓取等按次计费的
169
+ 接口不在统计范围。
170
+
171
+ ## 结构
172
+
173
+ ```
174
+ dsh-plugin-billing-card/
175
+ ├── package.json # dsh.bundle(profile 补丁)+ dsh.client(浏览器模块)+ 导出元数据
176
+ ├── cordis.patch.yml # 插入 billing-card 行(不改动任何官方行)
177
+ ├── index.js # Host:校验配置并注册 billingUsage 投影
178
+ ├── billing-core.js # Host 纯逻辑:事件折叠、价格解析、峰谷判定、视图构建、结构校验
179
+ ├── client.js # Client:输入框下方药丸 + 展开卡片(手写浏览器模块,免构建)
180
+ ├── locale/{en,zh}.json # 插件管理器里的标题/描述
181
+ ├── icon.svg # 插件图标
182
+ └── tests/billing-core.test.mjs # node --test 单元测试
183
+ ```
184
+
185
+ Host 半零运行时依赖;Client 半只使用浏览器模块表里的 `react` / `react-dom`。
186
+
187
+ ## 开发
188
+
189
+ ```sh
190
+ cd dsh-plugin-billing-card
191
+ node --check index.js && node --check billing-core.js && node --check client.js
192
+ node --test tests/*.test.mjs
193
+ ```
194
+
195
+ ## License
196
+
197
+ MIT