@kenz1117/dsh-ui-usage-billing 1.6.7 → 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/README.en.md CHANGED
@@ -15,6 +15,7 @@
15
15
  <a href="https://github.com/kenz1117/dsh-ui-usage-billing"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/kenz1117/dsh-ui-usage-billing?logo=github"></a>
16
16
  <a href="https://github.com/kenz1117/dsh-ui-usage-billing/graphs/contributors"><img alt="GitHub contributors" src="https://img.shields.io/github/contributors/kenz1117/dsh-ui-usage-billing"></a>
17
17
  <a href="https://awesome-dsh-plugin.com"><img alt="Awesome DSH Plugin" src="https://awesome-dsh-plugin.com/badge.svg"></a>
18
+ <a href="https://dshfind.com/en/plugins/kenz1117/dsh-ui-usage-billing"><img alt="dshfind" src="https://dshfind.com/api/badge/kenz1117/dsh-ui-usage-billing"></a>
18
19
  </p>
19
20
 
20
21
  [English](README.en.md) · [中文](README.md)
@@ -53,13 +54,18 @@ The billing channel is detected from the current session's model: DeepSeek meter
53
54
  - A performance panel: per-model TTFT mean/P50/P90 and generation speed.
54
55
  - Uncatalogued models are explicitly marked and never silently billed 0; one alias entry prices an out-of-catalog model.
55
56
  - An optional `usage_stats` tool lets the model answer "what did I spend today" or "which site used the most".
56
- - A pure UI surface: no tools registered, no system-prompt injection, no model-visible log events.
57
+ - Zero tools registered by default: the single read-only `usage_stats` tool is registered **only** after the user explicitly turns on "inject usage query" in the settings (off by default). No system-prompt injection and no model-visible log events in any case.
57
58
  - Chinese / English and ¥ / ≈$ toggles; no chart library, no external CDN, offline & self-contained.
59
+ - **Jump from a session row**: click a session title in the dashboard to open that conversation in the host (both generations of the host's session-selection channel are probed; hosts without one show a readable notice instead of silently doing nothing).
60
+ - **Context occupancy**: the overview shows the current session's context occupancy, window capacity, and composition (system / tools / messages), read from the host's official context projections. Sessions without a projection hide the whole card — it never shows a fabricated 0.
61
+ - **In-conversation entry**: the `/usage` command opens the billing dashboard directly (hosts without that capability degrade silently and leave the dashboard untouched).
58
62
 
59
63
  ## 📊 Dashboard
60
64
 
61
65
  - **Sidebar trigger card**: persistent above the Settings button — a single headline figure (today / this week / this month, selectable in settings, optional day-over-day badge) with a 7-day sparkline mini-trend and a today-vs-average gauge needle; collapses to an icon button; hover reveals a quick-look card (updated-at + metric grid + top spenders / quota alerts).
62
- - **Six-tab dashboard**: Overview / Trends / Detail / Stats / Rates / Settings — hero figures + comparisons + month projection + KPIs (hover for the metric definition) + usage heatmap, 7/30-day trends switching cost / tokens, plus the model rate table, budget (global + per-model) and peak/off-peak alerts; the Settings tab has full-text search (keyword-filters sections in either language, empty state when nothing matches); restrained tones, dark/light adaptive.
66
+ - **Eight-tab dashboard**: Overview / Billing / Usage / Trends / Context / Agents / Rates / Settings — hero figures + comparisons + month projection + KPIs (hover for the metric definition) + usage heatmap, trends switchable between cost and tokens over 7/30 days, model price table, budgets (global + per model) and peak/off-peak alerts all live here; the settings page supports full-text search (zh/en keywords, empty state when nothing matches); tabs carry names only — no status badges.
67
+ - **Context section**: an occupancy bar plus next-request / last-request occupancy, window capacity and the composition split (system / tools / messages). The figures come from the host's official context projections; a session without one hides the whole section rather than showing a fabricated 0.
68
+ - **Agents section**: the agent network rebuilt from delegation relations — a parent conversation → sub-agent tree where each row carries its call count, own cost and **chain total** (itself + all descendants), which directly answers "which delegation was the most expensive".
63
69
 
64
70
  ![Overview: month cost hero, budget progress, KPIs and usage heatmap](screenshots/1.png)
65
71
  - **Live cost bar**: persistent "this turn / session" cost with three positions (composer toolbar row / above / below, toolbar by default); the peak/off-peak tier & countdown section appears only when the current model involves peak/off-peak pricing; subscription low-quota chips appear at ≤20% remaining, red at ≤10%; hideable via the settings-tab toggle (display-only preference persisted locally; stats and alerts unaffected).
@@ -109,7 +115,7 @@ The billing channel is detected from the current session's model: DeepSeek meter
109
115
  - **Multi-language + three currencies**: language (EN / 中) and currency (¥ CNY / $ USD / € EUR) switch **independently**, both plugin-only — neither leaks into the host UI. The rate table, the sidebar card and the composer capsule all convert to the selected currency, and both choices persist locally. On first upgrade the language is seeded once from the stored currency (“$” → English), so no existing user’s interface language changes silently.
110
116
  - **Security hardening**: every HTTP endpoint enforces loopback-only access via a dual check of the peer socket address and an exact Host-header match, rejecting `127.0.0.1.evil.com`-style DNS-rebinding names (reverse-proxy deployments can allow specific names with `trustedHosts`; the peer-socket check stays mandatory); write paths additionally validate a loopback Origin and Content-Type with a body-size cap against cross-site rewrites; balance / subscription / pricing fetches carry bounded retries with per-upstream circuit breaking (auth failures are config issues and do not trip the breaker).
111
117
  - **Export injection guard**: CSV cells starting with `=` / `+` / `-` / `@` get a leading single quote and full escaping, so they cannot execute as formulas in Excel / WPS.
112
- - **Privacy baseline**: a pure UI surface — registers no tools, injects no system prompt, writes no model-visible events; it only aggregates from existing session logs, whose content is owned by other packages.
118
+ - **Privacy baseline**: zero tools registered by default — no system-prompt injection, no model-visible events written to the session log; it only aggregates from existing session logs, whose content is owned by other packages. The sole exception is the read-only `usage_stats` tool registered after the user opts in (see "Model Experience"); it reads only this plugin's own aggregates, never session bodies, and never writes back to the log.
113
119
 
114
120
  ## 🚀 Quick start
115
121
 
@@ -137,6 +143,16 @@ Alternatively, add it to the host `cordis.patch.yml` by hand:
137
143
 
138
144
  After the host starts, the billing entry appears above the sidebar Settings. No extra configuration is needed; when `sessionPersistence` is available it aggregates real usage automatically.
139
145
 
146
+ ### 🛒 Install from the DSH Community Market
147
+
148
+ This plugin also publishes a catalog entry using the Market's **Path A standard source**. Paste the manifest URL below into *Settings → Plugins → Plugin Store → Source management → Add source*, then browse and install with one click:
149
+
150
+ ```
151
+ https://kenz1117.github.io/dsh-ui-usage-billing/catalog-source.json
152
+ ```
153
+
154
+ Market-hosted installs resolve an exact stable version from the npm registry (the Host resolves the install target from npm `latest`; the version listed in the catalog is display-only). The catalog files live in `catalog/` in this repository and are validated in CI before being published by GitHub Pages.
155
+
140
156
  ## ⚙️ How it works
141
157
 
142
158
  The plugin has a server side and a browser side:
@@ -264,7 +280,15 @@ The host discovers the browser side automatically via the `dsh.client` declarati
264
280
 
265
281
  ## 🤖 Model Experience
266
282
 
267
- None. This plugin is a pure UI surface: it registers no tools, injects no system prompt, writes no model-visible events to the session log, and touches no session KV cache; usage statistics are aggregated by the server from existing session logs, whose content is owned by other packages.
283
+ **None by default.** The plugin exposes no tool to the model out of the box: the "inject usage query" setting is off by default, and while it is off the model can neither see a tool nor read any data from this plugin.
284
+
285
+ After the user explicitly enables that setting, exactly **one** read-only tool is registered:
286
+
287
+ | Tool | Parameters | Behaviour |
288
+ | --- | --- | --- |
289
+ | `usage_stats` | `range`: `today` / `month` / `session` / `all` / `bySite` / `relay` | Queries the usage and estimated cost this plugin already aggregated (CNY, estimated from the official price catalog — not a bill); `session` requires an agent session context |
290
+
291
+ Boundaries: the tool reads only this plugin's own aggregates — never session bodies, never prompts, and it never writes back to the session log. The plugin injects no system prompt, writes no model-visible events to the session log, and touches no session KV cache in any case. Usage statistics are aggregated by the server from existing session logs, whose content is owned by other packages. The tool consumes context on every request, which is why it stays off by default.
268
292
 
269
293
  ## ⚠️ Known Limitations and Deferred Work
270
294
 
package/README.md CHANGED
@@ -15,6 +15,7 @@
15
15
  <a href="https://github.com/kenz1117/dsh-ui-usage-billing"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/kenz1117/dsh-ui-usage-billing?logo=github"></a>
16
16
  <a href="https://github.com/kenz1117/dsh-ui-usage-billing/graphs/contributors"><img alt="GitHub contributors" src="https://img.shields.io/github/contributors/kenz1117/dsh-ui-usage-billing"></a>
17
17
  <a href="https://awesome-dsh-plugin.com"><img alt="Awesome DSH Plugin" src="https://awesome-dsh-plugin.com/badge.svg"></a>
18
+ <a href="https://dshfind.com/zh/plugins/kenz1117/dsh-ui-usage-billing"><img alt="dshfind" src="https://dshfind.com/api/badge/kenz1117/dsh-ui-usage-billing"></a>
18
19
  </p>
19
20
 
20
21
  [中文](README.md) · [English](README.en.md)
@@ -54,13 +55,18 @@ DeepSeek / Kimi / 智谱 GLM / 腾讯云 TokenHub 等 7 家官方余额、Coding
54
55
  - 性能面板:各模型首字延时(TTFT)均值 / P50 / P90 与生成速度,同类少有。
55
56
  - 未收录模型显著标注「未收录」、绝不静默计 0;目录外模型配一条别名即完成识别与计价。
56
57
  - 可选的 `usage_stats` 工具让模型直接回答「今天花了多少」「哪个站点用得最多」。
57
- - 纯 UI surface:不注册工具、不注入系统提示、不写模型可见事件。
58
+ - 默认零工具注入:**仅**当用户在设置里显式开启「注入用量查询」后,才向模型注册 `usage_stats` 这一个只读工具(默认关闭);任何情况下都不注入系统提示、不写模型可见事件。
58
59
  - 中文 / English 语言切换,¥ / ≈$ / ≈€ 币种切换(二者独立);无图表库、无外部 CDN、离线自包含。
60
+ - **会话行可跳转**:面板里的会话标题点一下直接打开宿主对话(双代会话选择通道自动探测;宿主不支持时给出可读提示,不静默无反应)。
61
+ - **上下文占用维度**:概览页显示当前会话的上下文占用率、窗口上限与构成拆解(系统 / 工具 / 消息)——数据取自宿主官方的 context 投影,**没有投影的会话整块不显示**(不拿 0 冒充)。
62
+ - **对话内入口**:`/usage` 命令直接拉起计费仪表盘(宿主无该能力时静默降级,不影响面板)。
59
63
 
60
64
  ## 📊 仪表盘
61
65
 
62
66
  - **侧边栏触发卡**:设置按钮上方常驻单值主数字(今日 / 本周 / 本月统计范围在设置里选,可选涨跌徽章),配近 7 天 sparkline 迷你趋势与当日水位仪表指针;折叠栏自动切为图标钮,悬停浮现速览卡(更新时间 + 指标网格 + 主力消耗 / 额度提醒)。
63
- - **六区仪表盘**:概览 / 趋势 / 明细 / 统计 / 费率 / 设置——Hero 大数字 + 环比 + 本月预计 + KPI(悬停显示口径说明)+ 用量热力图,趋势 7/30 天可切费用 / Token,模型单价表、预算(全局 + 按模型)与峰谷提醒都在;设置页支持全文搜索(中英关键词过滤分区,全不命中显示空态);克制冷调、深浅主题自适应。
67
+ - **八区仪表盘**:概览 / 账单 / 用量 / 趋势 / 上下文 / 智能体 / 费率 / 设置——Hero 大数字 + 环比 + 本月预计 + KPI(悬停显示口径说明)+ 用量热力图,趋势 7/30 天可切费用 / Token,模型单价表、预算(全局 + 按模型)与峰谷提醒都在;设置页支持全文搜索(中英关键词过滤分区,全不命中显示空态);克制冷调、深浅主题自适应。Tab 只保留名称,不再挂状态徽标(信息都在各自分区里)。
68
+ - **上下文分区**:占用率进度条 + 下一次 / 最近一次请求占用 + 窗口上限 + 构成拆解(系统 / 工具 / 消息)。数据取自宿主官方 context 投影;**没有投影的会话整块不显示**,不拿 0 冒充。
69
+ - **智能体分区**:按委派关系还原的智能体网络——父对话 → 子智能体的层级树,每行给调用数、自身费用与**链合计**(自身 + 全部后代),直接回答「哪次委派最贵」。
64
70
 
65
71
  ![概览:本月费用 Hero、预算进度、KPI 与用量热力图](screenshots/1.png)
66
72
  - **即时代费用条**:常驻「本轮 / 会话」费用,位置三档可选(输入框内部工具行 / 上方 / 下方,默认工具行);峰谷档位与切换倒计时只在当前模型涉及峰谷时出现;订阅额度预警 chips 剩余 ≤20% 浮现、≤10% 标红;可在设置 Tab 整条隐藏(偏好本地持久化,统计与提醒不受影响)。
@@ -110,7 +116,7 @@ DeepSeek / Kimi / 智谱 GLM / 腾讯云 TokenHub 等 7 家官方余额、Coding
110
116
  - **多语种 + 三币种**:语言(EN / 中)与币种(¥ CNY / $ USD / € EUR)**各自独立切换**,均仅本插件生效、不影响宿主全局 UI;费率表、侧边栏卡片与输入框胶囊均按所选币种换算,两项选择均本地持久化。老用户首次升级时语言由已存币种播种一次(选 $ 即英文),界面语言不会静默改变。
111
117
  - **安全加固**:全部 HTTP 端点强制回环访问——peer socket 地址 + Host 头精确匹配双重校验,拒绝 `127.0.0.1.evil.com` 形式的 DNS rebinding(反向代理部署可用 `trustedHosts` 显式放行特定主机名,peer socket 校验仍为强制);写操作额外校验 Origin 回环与 Content-Type 并限制 body 上限,杜绝跨站改写;余额 / 订阅 / 定价拉取带有限重试与按上游维度熔断(鉴权失败属配置问题、不计入熔断)。
112
118
  - **导出防注入**:CSV 对 `=` / `+` / `-` / `@` 开头单元格前置单引号并完整转义,防止在 Excel / WPS 中被当作公式执行。
113
- - **隐私底线**:纯 UI surface,不注册工具、不注入系统提示、不向会话日志写模型可见事件;仅从既有会话日志聚合,日志内容由其他包负责。
119
+ - **隐私底线**:默认零工具注入——不注入系统提示、不向会话日志写模型可见事件;仅从既有会话日志聚合,日志内容由其他包负责。唯一的例外是用户显式开启后注册的 `usage_stats` 只读工具(见「Model Experience」),该工具只读本插件自己的聚合结果,不读会话正文、不写回日志。
114
120
 
115
121
  ## 🚀 快速开始
116
122
 
@@ -138,6 +144,20 @@ DeepSeek / Kimi / 智谱 GLM / 腾讯云 TokenHub 等 7 家官方余额、Coding
138
144
 
139
145
  启动宿主后,侧边栏设置上方即出现计费入口。无需额外配置;`sessionPersistence` 可用时自动聚合真实用量。
140
146
 
147
+ ### 🛒 从 DSH Community Market 安装
148
+
149
+ 本插件同时按 DSH Community Market 的 **Path A 标准来源**发布目录条目。在 DSH 的
150
+ 「设置 → 插件 → 插件商店 → 来源管理 → 添加来源」粘贴下面的 manifest URL,即可把本目录
151
+ 加为来源,随后在市场里浏览并一键安装:
152
+
153
+ ```
154
+ https://kenz1117.github.io/dsh-ui-usage-billing/catalog-source.json
155
+ ```
156
+
157
+ 市场托管安装只走 npm registry 的精确稳定版本(安装目标由 Host 解析 npm `latest` 决定,
158
+ 目录里列出的版本仅用于展示)。目录文件在本仓 `catalog/` 下,改动由 CI 校验后随
159
+ GitHub Pages 发布。
160
+
141
161
  ## ⚙️ 工作原理
142
162
 
143
163
  插件由服务端与浏览器端两部分组成:
@@ -269,7 +289,15 @@ npm dist-tag add @kenz1117/dsh-ui-usage-billing@<版本> alpha
269
289
 
270
290
  ## 🤖 Model Experience
271
291
 
272
- 无。本插件是纯 UI surface:不注册工具、不注入系统提示、不向会话日志写入模型可见事件,也不触及会话 KV 缓存;用量统计由服务端从既有会话日志聚合,日志内容由其他包各自负责。
292
+ **默认无**——插件默认不向模型暴露任何工具:设置里的「注入用量查询」默认关闭,关闭状态下模型既看不到工具、也读不到任何本插件数据。
293
+
294
+ 用户显式开启该开关后,注册**一个**只读工具:
295
+
296
+ | 工具 | 参数 | 行为 |
297
+ | --- | --- | --- |
298
+ | `usage_stats` | `range`:`today` / `month` / `session` / `all` / `bySite` / `relay` | 查询本插件已聚合的用量与估算费用(人民币,按官方目录价估算,非账单);`session` 需处于 agent 会话上下文 |
299
+
300
+ 边界声明:该工具只读本插件自己的聚合结果,**不读会话正文、不读提示词、不写回会话日志**;插件任何情况下都**不注入系统提示**、**不向会话日志写入模型可见事件**、不触及会话 KV 缓存。用量统计由服务端从既有会话日志聚合,日志内容由其他包各自负责。工具会占用每次请求的上下文,因此保持默认关闭。
273
301
 
274
302
  ## ⚠️ Known Limitations and Deferred Work
275
303