# 更新日志 本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/);每个版本对应一次 GitHub Release。 ## [1.8.0] — 2026-09-20 **价格设置改版:模型显示名精简 +「新建模型」改成下拉选择 / 自定义输入。** - 删掉价格设置下那排「已见模型:+ xxx」按钮,改成 **新增模型:下拉选择(已见模型,按精简名列出)或「自定义输入…」**, 页面省下一大块空间。 - 价格行标题不再直接摊开匹配键:显示精简名,需要改键时点「改键」才展开输入框(匹配键同时放在悬停提示里)。 - **显示名规则**(全站统一):`供应商短名-精简模型名` - 供应商短名:`volc-ark-coding`→火山方舟、`deepseek-official`→deepseek、`zai-coding-cn`→智谱、`kimi-coding`→kimi,其他用原 provider id - 精简模型名:去掉末尾日期串、版本段合并(`v4-1`→`v41`、`seed-2-1`→`seed21`)、`glm` 大写、小数点保留 - 例:`火山方舟-GLM5.3`、`火山方舟-deepseek-v41-flash`、`deepseek-deepseek-flash`、 `火山方舟-doubao-seed21-turbo`、`智谱-GLM5.3-flash` - **原始键永远不变**(匹配与存档都用原键),精简只发生在显示层;悬停任意名字可看原键 - 应用范围:新建下拉、价格行标题、按模型表、最近请求表、AFP 抵扣系数表。 - 自检 **257 项**(新增 6 项命名规则用例 + 6 项价格区改造用例)。 ## [1.7.1] — 2026-09-20 **修:AFP 系数改了、保存之后又变回默认。** 1.7.0 新增系数覆盖时,只把新字段接进了 `applyConfig`,**漏了另外两处白名单**: - 快照的 `config` 没带 `afpCoefs` → 设置页收到的永远是内置表,看着就像「我改了它自己变回去」 - 落盘的 `config` 也没带 → 覆盖值根本没写进账本,重启必丢 - 再加上设置页再点一次「保存」会回传空表 → 把内存里的覆盖值也一并清掉 修法:两处 `config` 都补上 `afpCoefs` / `afpDefaultCoef`(新增 `cloneAfpCoefs()`); 客户端在「宿主从未给过系数表」时**不回传空表**,避免误清;显式点「恢复内置」仍然能清空。 自检 **245 项**(新增 5 项回程用例:快照带得回、落盘存得住、二次保存不丢、显式清空仍有效)。 ### 顺带核对:deepseek-v4.1-flash 到底是 1.0 还是 1.25 官方文档写 2.5、活动五折 = **1.25**;但你账号**实扣的是 1.0**。两次真实数据对账(账本逐笔 token 对控制台 `used`,不是估算): | 窗口 | 账本 token | 按 1.0 算 | 按 1.25 算 | 控制台 used | |---|---|---|---|---| | 09-19 20:07–21:07(窗口内只有 v4.1-flash) | 832,517 | **83.2517** | 104.06 | **83.2517** | | 09-20 11:03–16:03(含 glm-5.3 / v4-flash) | 3,291,004 | **345.173** | 424.452 | **345.1733** | 两次都是 1.0 命中到小数点后三位、1.25 差 23%,所以内置表仍是 **1.0**(2.5 × 0.4)。 要按文档用 1.25 可以在设置页覆盖(现在能存住了),但数字会比账单高约 23%。 ## [1.7.0] — 2026-09-19 **方舟套餐额度改用官方 AFP 抵扣系数计算,不再靠观测比率估算。** 1.6.0 是「看控制台涨了多少、同期花了多少 token,除一下得到 AFP/Token 比率」。 那个做法有个根本问题:**每个模型的抵扣系数根本不一样**(官方表里从 0.25 到 10,差 40 倍), 用一个全局比率去乘所有模型,换个模型就错得离谱,而且控制台一延迟出账还会把比率带偏。 这一版照官方《套餐内 AFP 抵扣规则》直接算: ``` AFP = (输入 token × 输入系数 + 输出 token × 输出系数) / 10,000 ``` ### 新增 - **内置 AFP 抵扣系数表**(官方文档 2026-09-17 版):`doubao-seed-2.0-mini` 0.25、 `doubao-seed-2.0-lite` / `deepseek-v4-flash` / `glm-5.3-flash` 0.5、 `doubao-seed-2.1-turbo` / `doubao-seed-evolving` / `minimax-m3` 2.5、`kimi-k2.7-code` / `glm-5.3` 4.5、 `deepseek-v4-pro` 5.5、`kimi-k2.8-preview` 8、`kimi-k3` 10、`auto` 0.5、`doubao-embedding-vision` 0.5。 - **限时折扣按调用时刻生效**:`glm-5.3-flash` 8/28–9/11 五折、`kimi-k2.8-preview` 9/17–9/30 六折、 `deepseek-v4.1-flash` 9/15–9/28 折后 1.0(见下)。 - **系数可按模型覆盖**:设置页新增「AFP 抵扣系数」表,列出内置表 + 你改过的值 + 账本里出现过的 方舟模型及其已用 AFP;可改输入/输出系数、一键恢复内置,未知模型用可配置的默认系数兜底。 - **控制台对账**:每次拿到新快照都会把「控制台增量」和「本插件按系数算出来的 AFP」比一次, 写进快照与日志(`afp reconcile: 控制台 +x / 本插件 +y = 比值`),系数被官方改动时能立刻看出来。 - 徽标提示里直接写出当前模型用的系数与来源;「按模型」表的计价档一列对套餐模型改显示 `AFP ×系数`。 ### 实测(都是真实账号) - **同批调用逐笔对齐**:把账本里 2026-09-19 20 点那 20 笔 `deepseek-v4-1-flash` 回放给发布代码, 插件算出 **83.2517 AFP**,控制台 5h 快照就是 **83.2517**(832,517 token)。 - **整天 12 个模型对齐**:把控制台 09-18 的按模型 token 回放给发布代码,插件算出 **532.9309 AFP**, 控制台「weekly − 5h」= **532.9246 AFP**,比值 **1.0000**。 - 自检 **237 项**全过(新增系数分流、活动折扣、用户覆盖、对账、面板渲染 12 项)。 ### 说明 - 官方文档写 `deepseek-v4.1-flash` 是 2.5、活动五折(=1.25),但实测账号的有效系数**恰好是 1.0** (832,517 token ↔ 83.2517 AFP,且代进 weekly/monthly 两个窗口都能对上 0.07%),所以内置表按 2.5 × 0.4 = 1.0 记;对不上时用设置页的覆盖值改,或直接看对账比值。 - 输入 token 含缓存命中 / 未命中 / 写入三类 —— 已用控制台 `usage plan-details` 的 token 数 与账本 `hit+miss+write+out` 逐日核对过,完全一致。 ## [1.6.0] — 2026-09-16 **方舟套餐模型不再按钱统计,改成额度口径。** 1.5.0 让方舟的余额档位能读出 5h / weekly / monthly 三个窗口,但费用那一栏仍是拿 `default` 档的 DeepSeek 列表价算出来的「假钱」。套餐是预付费额度,本来就没有按 token 的 金额账单,所以这一版把套餐制的计量整个换成额度。 ### 新增 - **套餐制(`kind: ark-plan`)按额度计量**:这类 provider 的调用 `cost` 记 0(不再进「花费」), 改记 `quota`。额度口径下输入框徽标是 `单次 · 本对话 · 5小时 · 周额度 · 月额度`: 前两个是**已消耗**的额度(单次 = 上一轮,本对话 = 该会话含子会话累计), 后三个是各窗口的**剩余**额度;悬停提示给出每个窗口的 `已用/总额(占比)· 剩余 · 重置时间`。 - **额度消耗是估算值**:控制台只给窗口累计值,所以插件用「两次快照之间的额度增量 ÷ 同期 token 量」 估出 AFP/Token 比率,再按每次调用的 token 折算。首次快照只建基准,比率观测到之前记 0 (所以刚重启后的头几次调用可能显示 0.000)。**它一定会滞后于控制台**,界面与提示里都写明了。 - **控制台延迟出账不会把比率算飞**:只有真的用掉一次增量时才推进 token 基准,没看到增量就保留基准, 把这段 token 攒到下一次增量一起除。否则「一段时间的额度」会被摊到其中一小段 token 上,比率被高估 (实测过 2× 的偏差)。 - **账本新增 `quota` 字段**:桶、合计、子会话合并、存档读取全部同步, 设置页在额度口径下显示「单次消耗 / 本对话消耗 / 套餐额度剩余(5小时 / 周额度 / 月额度)」, 「最近请求」「按模型」的费用列对套餐调用显示额度而不是 `¥0.00`。 ### 修复 - 自检不再打真网络:宿主半边的外部 HTTP 一律拦住,本地假服务器留到进程退出 (`server.unref()`)。之前有一处用例把默认余额地址配成内置 DeepSeek 地址, 于是自检真的去请求了线上接口,网络抖动时会偶发 `fetch failed` 甚至让自检以 1 退出。 ### 实测 - 自检 **211 项**全过(新增额度计量 8 项、徽标渲染 19 项、延迟出账 2 项)。 - 真实账号(用发布代码直接跑真 `arkcli`):`agent-plan/personal/small`、 5h `19.1137/2000`、weekly `19.1137/7000`、monthly `118.2357/20000`; 方舟会话 `cost = 0`、三个窗口剩余 `1980.8863 / 6980.8863 / 19881.7643`; DeepSeek、智谱 GLM 仍走金额口径不受影响。 ## [1.5.0] — 2026-09-16 **火山方舟 Agent Plan 改为额度统计。** 你的方舟 provider 是 `volc-ark-coding`(baseURL `.../api/plan/v3` = Agent Plan 数据面), 账号是**预付费额度制**:没有金额余额可查,只有 5h / weekly / monthly 三个窗口的额度用量。 之前插件对任何供应商都只查 DeepSeek 的金额余额,切到方舟模型后显示的仍是 DeepSeek 的钱。 ### 新增 - **新增档位类型 `ark-plan`**:内置到 provider `volc-ark-coding`,执行本机 `arkcli usage plan --format json`(与 arkcli 共用同一份 SSO 登录),解析 `items[].periods[]` 的 `label / used / total / percent / reset_at`。 徽标显示**用量占比最高**的那个窗口,悬停与设置页列出全部窗口及重置时间。 - **档位支持外部命令**:档位可配 `command: { file, args }`;只有「裸命令名」在 Windows 上经 shell 执行(`arkcli` 是 `.cmd` 垫片),绝对路径交给 `execFile` 直接处理(避免空格问题)。 超时 30s、输出上限 4 MB。 - 命令失败 / 未订阅 / 输出无法解析都会如实报错(例如 `当前账号没有生效的套餐订阅`), 不拿别家数字顶替。 ### 修复 - 同一档位已有请求在飞时,`kickBalance` 现在**返回那个 promise**(等它完成),而不是立刻返回 旧快照 —— 否则手动「刷新余额」会读到上一次的值。 ### 实测 - 自检 **176 项**全过(含用真实子进程验证「起进程 → 解析 → 展示字段」,以及未订阅、命令失败两条路径)。 - 真实宿主里验证:插件在 DSH 进程内真的起 `arkcli`,取回 `agent-plan / personal / small`、 5h `19.1137/2000(0.96%)`、weekly `19.1137/7000(0.27%)`、monthly `118.2357/20000(0.59%)`, 徽标显示 `套餐额度 0.96%`。 > 说明:套餐制模型没有按 token 的金额账单。1.5.0 里费用(单次/本对话/…)仍是按 `default` 档 > 算出的「列表价参考」,与套餐额度的消耗不是同一口径;**1.6.0 起方舟套餐模型改走额度口径, > 不再显示金额。** ## [1.4.0] — 2026-09-16 **余额按供应商分流:切到 GLM 后显示的就是智谱的余额。** 在此之前插件只有一套余额配置(DeepSeek 的地址与凭据),所以不管用哪个模型, 徽标显示的都是 DeepSeek 的余额 —— 数字张冠李戴。 ### 新增 - **按供应商选余额档位**:按「该会话最近一次调用的 provider/model」解析档位, 顺序为 用户配置 → 内置 DeepSeek(provider 精确/前缀)→ 内置智谱 → 按模型名前缀 (`glm*` 归智谱、`deepseek*` 归 DeepSeek)。每个档位独立请求、独立缓存。 - **智谱 GLM 余额**:`GET https://open.bigmodel.cn/api/bigmodel/... ` 见下(实测可用): `GET https://open.bigmodel.cn/api/biz/account/query-customer-account-report` (`Authorization: `,裸 key 或 Bearer 均可) → `{ code: 200, data: { balance, rechargeAmount, giveAmount, totalSpendAmount } }`, 分别对应「余额 / 充值 / 赠金」。该接口是从智谱控制台财务页的 JS 里挖出来的,官方文档未列。 - **重启后回填**:载入账本时回填「每个会话最近一次调用的模型」, 否则重启后所有会话会先按全局最后一个模型取余额(又会短暂串号)。 - **智谱配额档位**(可选):`/api/monitor/usage/quota/limit` 仍支持, 把档位的 `kind` 设为 `zhipu-quota` 即按「配额 x/y」显示(Coding Plan 账号用)。 ### 修复 - 内置档位一度盖过用户配置的默认余额地址:现在若用户改过全局「默认余额接口」, **DeepSeek 系**供应商沿用该地址与凭据(兼容代理/换 key),其它供应商不受影响。 - `billing/balance` 路由此前不带档位调用 `kickBalance`,导致手动「刷新余额」查的是 「未知供应商」;现在带上该会话解析出的档位。 ### 实测(真实 key,2026-09-16) - GLM 会话(`zai-coding-cn/glm-5.3-flash`)→ `BigModel GLM`,**¥19.94012911** (充值 ¥20 / 赠金 ¥0 / 累计消费 ¥0.0599)。 - DeepSeek 会话 → `DeepSeek`,**¥112.95**。 - 未配置档位的供应商 → 不显示任何金额(`kind: none`)。 - 自检 **168 项**全过。 ## [1.3.1] — 2026-09-13 **修正 v1.3.0 里补错的模型:第二个档位应为 GLM-5.3,不是 GLM-4.7。** 按官方定价页截图核对,要补的是 **GLM-5.3** 与 **GLM-5.3-Flash** 两个模型, 两者都是 1M 上下文、单一价、**没有高峰 / 低谷之分**。 | 档位 | 输入·缓存命中 | 输入·缓存未命中 | 输出 | | --- | --- | --- | --- | | `glm-5.3` | 2 | 8 | 28 | | `glm-5.3-flash` | 0.23 | 0.8 | 2.8 | 单位:元 / 百万 tokens。两档的高峰与低谷单价写成相同值,时段不影响 GLM 计价。 - 新增 `glm-5.3`(v1.3.0 漏了它,误加了 `glm-4.7`)。 - `glm-5.3-flash` 的数值 v1.3.0 就是对的(0.8 / 2.8 / 命中 0.23),未改动。 - `glm-4.7` 作为同表附带的档位保留(官方按输入长度分三档,取输入 `[32K, 200K)` = ¥4 / ¥16 / 命中 ¥0.8), 不需要可在设置页新增同名档位覆盖。 ### 实测 自检扩到 **139 项**:新增 GLM-5.3 的内置解析(`priceMatch = builtin`)、三项单价, 以及「高峰与低谷单价必须相同」的显式断言(GLM 无分时价)。 ## [1.3.0] — 2026-09-13 **新增内置官方价目表,并补上智谱 GLM 两个模型的单价。** ### 新增 - **内置官方价目表 `BUILTIN_PRICES`**:查找顺序变为 `用户 provider/model → 用户 模型名 → 内置 provider/model → 内置 模型名 → default`。 这一层是必需的:账本里存过的 `config.prices` 会整体替换**用户档位**,直接改代码默认值 对已有安装无效(新模型仍会按 `default`,即 DeepSeek Flash 计价)。有了内置表, 新版本补充的模型单价对老存档立即生效,而用户在设置页新增的同名档位优先级更高、可随时覆盖。 - **GLM-5.3-Flash**:输入 ¥0.8 / 输出 ¥2.8 / 缓存命中 ¥0.23(元/百万 tokens)。 - **GLM-4.7**:输入 ¥4 / 输出 ¥16 / 缓存命中 ¥0.8 —— 官方按输入长度分三档,取 输入 `[32K, 200K)` 档;另两档(¥2/¥8/命中 ¥0.4、¥3/¥14/命中 ¥0.6)可在设置页新增同名档位覆盖。 - GLM 不分高峰 / 低谷,两套单价相同,所以时段不影响 GLM 计价。 - 设置页「按模型」的计价档一列,内置档显示为 `模型名(内置)`。 来源:(2026-09-13 核对)。 ### 实测 - 自检扩到 **134 项**:GLM 两档从内置表解析(`priceMatch = builtin`)、单价与费用算式、 低谷时段同价、以及「用户同名档位覆盖内置表」。 - 真实宿主实测(对着一份只有 DeepSeek 两档的旧存档): `zai-coding-cn/glm-5.3-flash`、`openai/glm-5.3-flash`、`openai/glm-4.7` 三条都正确解析到 `builtin` 档,单价分别为 0.23/0.8/2.8 与 0.8/4/16。 > 说明:历史记录里的费用是调用当时按旧档位算好存下的,不会被回溯重算;新发生的调用按新档位计价。 ## [1.2.0] — 2026-09-13 **侧边对话与子代理的花费并入所属主对话。** better-sidebar 的「侧边对话」和内置子代理都跑在**子会话**里:会话头写着 `parentSession`,而 `llm/stream` 上报的是子会话自己的会话 id,于是花费落在另一个桶里, 看起来「没算进主对话」。现在按会话血缘归并。 ### 新增 - **子会话归并**:读取时把「本会话 + 其全部子会话」合成「本对话」与「单次」。 归属有两条来源: 1. 运行中读宿主 `sessions` 服务的会话头 `parentSession`; 2. 调用时把归属记进账本的 `lineage`(子会话结束后依然有效)。 聚合本身仍按真实会话记录(`bySession` 语义不变),所以历史数据不受影响、也不会双重计数, `sessions` 明细里照样能看到每个子会话自己的花费。 - **历史子会话收养**:升级前就存在、如今已结束因而查不到归属的子会话,读它自己的会话日志 `/sessions/<工作区>/<会话 id>/session.v3.jsonl.zstd` 的**第一帧**, 只解析第一行(会话头)里的 `parentSession`,**不读对话内容**;有界(最多 60 个会话、 每个最多 4 帧),失败即跳过。 - **设置页**:新增「子会话:并入本对话 / 单独统计」开关,以及「本对话的子会话」明细表 (每个子会话的次数、token 与费用);徽标悬停提示也会列出子会话合计。 ### 实测 - 自检扩到 **119 项**:归并口径、开关切换、`lineage` 落档、会话消失后仍归并、 以及从会话日志收养历史子会话。 - 真实宿主(DSH Desktop)实测:主会话 `session-66113abe` 归并后 **643 次调用 / ¥4.77997596**,其中 4 个子会话合计 ¥2.01828156 —— 两个来自活会话注册表 (`session-a5c703b6`、`session-59462b22`),两个来自会话日志收养 (`263d927f`、`fdabed3b`,共 ¥1.81506736)。 ## [1.1.2] — 2026-09-11 修复输入框下方徽标里的「余额 …」永远不更新(设置页却能看到余额)。 ### 修复 - **徽标余额停在「…」**:`useBilling` 只在客户端提供 `timer` 服务时才轮询 (`ctx.get('timer')`),而真实客户端的启动清单里**没有 timer 模块** —— 于是徽标只渲染挂载那一帧,而那一帧的余额还在异步获取中,就永远显示「…」; 设置页因为会再次拉取所以正常。现在没有 timer 服务时退回浏览器 `setInterval` (仍随 effect 注销一并清理)。 ### 实测 `scripts/check.mjs` 扩到 **96 项**,新增一个真正的功能回归:用只实现 `useState`/`useEffect` 的迷你 React 渲染徽标、执行它的 effect,断言它自己起了 3000ms 轮询、挂载即拉一次、轮询回调会再拉、卸载时清理掉 interval。 同时确认服务端已经在提供修好的 bundle:启动清单里该插件的 URL `rev` 由 `d2132e10bdf01024-66` 变为 `23bad5ee4809`,取回内容与本地构建一致 —— 客户端半边是按请求从磁盘读的,所以**这一项只需刷新页面,不必重启**。 ## [1.1.1] — 2026-09-11 修复真实宿主里徽标显示「存档异常」的问题。1.1.0 虽然把插件改成了真实插件包, 但 I/O 层仍照搬动态沙箱的写法 —— 而那几个服务在根级插件里根本拿不到。 ### 修复 - **「存档异常」/ `fs 服务不可用`**:`fs`、`credentials`、`shell` 是由 `dsh-fs-local`、 `dsh-credentials-local`、`dsh-shell` 等**按作用域**提供的服务,挂在 profile 根级的插件 `ctx.get(...)` 拿到的是 `undefined`(动态沙箱那份 ctx 由 runner 包装过,所以那时能用)。 现在账本改用 `node:fs` 直接读写 `/token-billing-ledger.json`, **路径与旧版一致,历史账本继续沿用**。 - **余额**:不再起 PowerShell 子进程,改用 `fetch` 调 `/user/balance`(20 秒超时); 凭据按 `env` → `credentials` 服务 → `/.credentials.yaml` 的 `refs` 段依次尝试。 密钥只进请求头,不写日志、不下发前端。 ### 变更 - `scripts/build.mjs` 不再生成宿主半边:`lib/index.js` 成为**直接维护的来源文件** (真实插件要用 `node:fs`/`fetch` 并挂 HTTP 路由,无法从沙箱函数体变换得到)。 `src/host.js` 保留为动态包时代的历史参考,不再参与构建。 - `scripts/check.mjs` 扩到 **87 项**:新增 `node:fs` 落盘(在临时 `DSH_HOME` 下)、 `fetch` 取余额(本地假端点,并校验 `Authorization` 确实来自 `.credentials.yaml` 的 `refs` 值而非其它字段),以及「宿主半边不得再向 ctx 索要 `fs`/`settings`/`shell`」 的回归守卫。 ### 实测 真实宿主(DSH Desktop,`web` profile)验证通过:`store.error` 为空、`store.path` = `C:\Users\chen\.dsh\token-billing-ledger.json`、账本写入成功并读回历史(190 → 191/192 笔, 无重复计数),余额 `via=fetch:file` 取回 **¥27.59 CNY**。 ## [1.1.0] — 2026-09-11 **从动态 Cordis 包改造成真实插件包**,安装方式随之改变(见 [INSTALL.md](INSTALL.md))。 计费口径、价目表与界面行为与 1.0.0 一致。 ### 变更 - **改为真实插件包**:`src/host.js` / `src/client.js` 仍是人类可读的源码,`scripts/build.mjs` 把它们定点变换成 `lib/index.js`(宿主半边,`export name` / `export apply(ctx, rowConfig)`) 与 `lib/client.js`(客户端半边,`window.__ModuleLoader__` 工厂,导出 `name` / `inject` / `apply`)。 两者都提交进仓库,安装方无需构建。 - **宿主↔客户端通信换成 HTTP 路由**:5 个 `harness.handle('billing/*')` 方法改为 `webServer` 上的 `POST /dsh-token-feiyong/{state,save,store,balance,reset}`,由 `ctx.effect` 注销; 请求必须带 `x-dsh-token-feiyong: 1` 头(跨源页面无法在无预检的情况下伪造),非 POST 返回 405。 - **`styles.insert` 换成自建 `