@rayadesu/dsh-llm-billing 0.1.0 → 0.2.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.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # last confirmed-consistent state. Both languages carry equal authority; after
3
3
  # editing either side, bring the other along and re-record both hashes with:
4
4
  # git hash-object README.md README.zh.md
5
- README.md: c51e3f984ce4eca27bc3998068c6a068e5c8e617
6
- README.zh.md: bf1385e6414657c262e153c805ced50c04a2575a
5
+ README.md: 471bb8364f6229ce3a6c48287fe660a92ead0281
6
+ README.zh.md: 9346896747a389b4aaf80400b19df8e0ff12961e
package/README.md CHANGED
@@ -16,7 +16,18 @@ Add the plugin to a composition (a `cordis.yml` row) and give it a credential. I
16
16
  # baseURL: https://api.deepseek.com
17
17
  ```
18
18
 
19
- The plugin registers the `billing` Remote with three methods: `getBalance()` (the parsed `/user/balance` snapshot), `getSessionSpend(sessionId)` (one session's billed cost), and `getTodaySpend()` (every session's billed cost on the current Beijing-time calendar day). The spend prices each `assistant/message` event's billed tokens (cache-hit input, cache-miss input including cache writes, and output including reasoning) at the official rate of the event's own Beijing-time peak/off-peak classification — peak windows apply weekdays (Monday–Friday) only, and weekends are always off-peak — then sums per model.
19
+ The plugin registers the `billing` Remote with three methods: `getBalance()` (the parsed `/user/balance` snapshot), `getSessionSpend(sessionId)` (one session's billed cost), and `getTodaySpend(force?)` (every session's billed cost on the current Beijing-time calendar day; `force` bypasses the host-side cache, for the badge's manual refresh). The spend prices each `assistant/message` event's billed tokens (cache-hit input, cache-miss input including cache writes, and output including reasoning) at the official rate of the event's own Beijing-time peak/off-peak classification — peak windows apply weekdays (Monday–Friday) only, and weekends are always off-peak — then sums per model.
20
+
21
+ ### Today-spend read path (no full scans per message)
22
+
23
+ `getTodaySpend()` never scans every session log per request. A 60-second Beijing-day cache with in-flight coalescing serves message-triggered reads; only the manual refresh (`force`) bypasses the time window. Behind a miss, two revision-gated strategies compute the aggregate:
24
+
25
+ - **Projection path** (used when `@deepseek-ai/dsh-session-projection` is composed): the plugin registers the `billingTodaySpend` projection unit, which folds each session's spend eagerly as events commit. Live sessions are read from their eager cells with zero log I/O; cold sessions ride the projection-cache ladder (`coldSnapshot`) or, without the cache service, one detached fold per session. Only sessions whose persisted revision changed since the last resolution are touched.
26
+ - **Events path** (fallback without the registry): collects only today's events (Beijing-day filter during collection) with a 200 000-event cap, skipping sessions whose persisted revision is unchanged.
27
+
28
+ After the first resolution per process, steady-state reads cost only the sessions whose logs actually changed. A session whose log cannot be read is skipped with a warning instead of failing the whole day's total.
29
+
30
+ Note: the projection path prices a session's history once, at the rates in effect when its events were folded — changing `billing.models` re-prices only events folded after the change (the events path re-prices the whole log).
20
31
 
21
32
  ## Configuration
22
33
 
@@ -41,4 +52,5 @@ None; its only provider call is a credential-authenticated `/user/balance` read,
41
52
  ## Known Limitations and Deferred Work
42
53
 
43
54
  - **Priced rows only** — the session and today spends only price models that have a `billing.models` row; a model without a rate row is omitted.
44
- - **On-demand read** — the session spend reads the session's full event log on each call rather than maintaining an incremental aggregate, so cost grows with the per-session log size; `getTodaySpend()` reads every session's log, and a session whose log cannot be read is skipped with a warning instead of failing the whole day's total.
55
+ - **Up-to-60s staleness** — `getTodaySpend()` is served from the host-side cache for up to 60 seconds; only the manual refresh (`force`) recomputes immediately (still revision-gated, so an unchanged log costs nothing).
56
+ - **Projection pricing is history-frozen** — when the projection path is active, a pricing-table change prices only events folded after the change; restart (or the events fallback) re-prices the full log.
package/README.zh.md CHANGED
@@ -16,7 +16,18 @@
16
16
  # baseURL: https://api.deepseek.com
17
17
  ```
18
18
 
19
- 插件注册 `billing` Remote,含三个方法:`getBalance()`(解析后的 `/user/balance` 快照)、`getSessionSpend(sessionId)`(单个会话的计费花费)与 `getTodaySpend()`(当前北京时间自然日内所有会话的计费花费合计)。会话花费把每条 `assistant/message` 事件的计费 token(缓存命中输入、含缓存写入的未命中输入、含推理的输出)按事件自身发生时刻(北京时间)所在的峰/谷单价计价——高峰窗口仅周一至周五适用,周末全天按低谷价——再按模型汇总。
19
+ 插件注册 `billing` Remote,含三个方法:`getBalance()`(解析后的 `/user/balance` 快照)、`getSessionSpend(sessionId)`(单个会话的计费花费)与 `getTodaySpend(force?)`(当前北京时间自然日内所有会话的计费花费合计;`force` 绕过宿主侧缓存,供徽标手动刷新使用)。会话花费把每条 `assistant/message` 事件的计费 token(缓存命中输入、含缓存写入的未命中输入、含推理的输出)按事件自身发生时刻(北京时间)所在的峰/谷单价计价——高峰窗口仅周一至周五适用,周末全天按低谷价——再按模型汇总。
20
+
21
+ ### 今日花费读取路径(消息触发不再全量扫描)
22
+
23
+ `getTodaySpend()` 每次请求都不会全量扫描所有会话日志。一个 60 秒的北京日缓存带 in-flight 合并,服务于消息触发的读取;只有手动刷新(`force`)绕过时间窗口。缓存未命中时,两种带 revision 门控的策略计算聚合:
24
+
25
+ - **投影路径**(当组合中装配了 `@deepseek-ai/dsh-session-projection` 时启用):插件注册 `billingTodaySpend` 投影单元,随事件提交增量折叠每个会话的花费。live 会话零日志 I/O 直读其 eager 单元;冷会话走投影缓存阶梯(`coldSnapshot`),没有缓存服务时对每个会话做一次 detached 折叠。只有持久化 revision 在上次解析后变化过的会话才会被读取。
26
+ - **事件路径**(无注册表时的回退):只收集今天的事件(收集时按北京日过滤),带 20 万事件上限,跳过持久化 revision 未变的会话。
27
+
28
+ 进程内首次解析之后,稳态读取只花在日志确实变化过的会话上。日志无法读取的会话带警告跳过,而不是让整日合计失败。
29
+
30
+ 注意:投影路径对每个会话的历史只计价一次,按事件被折叠时的费率——修改 `billing.models` 只影响变更后折叠的事件(事件路径会重算整个日志)。
20
31
 
21
32
  ## 配置
22
33
 
@@ -41,4 +52,5 @@
41
52
  ## 已知限制与暂缓事项
42
53
 
43
54
  - **有费率行才计价** —— 会话花费与今日花费只统计价目表(`billing.models`)里有的模型;没有费率行的模型不计入。
44
- - **按需读取** —— 会话花费在每次调用时读取该会话的完整事件日志,而非维护增量聚合,因此成本随单会话日志大小增长;`getTodaySpend()` 会读取每个会话的日志,日志无法读取的会话带警告跳过,而不是让整日合计失败。
55
+ - **最多 60 秒延迟** —— `getTodaySpend()` 由宿主侧缓存服务最多 60 秒;只有手动刷新(`force`)立即重算(仍受 revision 门控,日志未变则零成本)。
56
+ - **投影计价对历史冻结** —— 投影路径生效时,修改计价表只影响变更后折叠的事件;重启(或事件路径回退)才会重算整个日志。