@chenlongapps/opencode-token-usage 0.4.14 → 0.4.16

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,6 +1,6 @@
1
1
  <h1 align="center">opencode-token-usage</h1>
2
2
 
3
- <p align="center">A session-tree token usage monitor for OpenCode 2.</p>
3
+ <p align="center">Token usage, context window, estimated cost and live performance for OpenCode 2.</p>
4
4
 
5
5
  <p align="center">
6
6
  <a href="https://www.npmjs.com/package/@chenlongapps/opencode-token-usage" target="_blank" rel="noopener noreferrer"><img alt="npm" src="https://img.shields.io/npm/v/%40chenlongapps%2Fopencode-token-usage?style=flat-square&logo=npm" /></a>
@@ -15,30 +15,61 @@
15
15
  <a href="https://github.com/chenlongapps/opencode-token-usage/blob/main/README.zh-CN.md">简体中文</a>
16
16
  </p>
17
17
 
18
+ ### Overview
19
+
20
+ **opencode-token-usage** is a community plugin that brings token usage, context window occupancy, estimated cost and performance metrics into OpenCode 2's terminal interface.
21
+
22
+ Use it to see how many tokens a session and its subagents consume, how full the current context window is, and how estimated costs are distributed across models—without leaving your conversation.
23
+
24
+ ### Features
25
+
26
+ - **Session-tree totals:** Track input, output, reasoning and cache tokens across the session tree, including unopened subagents, without double-counting inherited fork history.
27
+ - **Context visibility:** See the viewed session's context usage, latest reported request and estimated prompt composition.
28
+ - **Estimated cost by model:** Price recorded calls using their actual models, with a built-in first-party price snapshot as a fallback. Estimates are not provider bills.
29
+ - **Performance at a glance:** Monitor tokens per second (TPS), time to first token (TTFT) and the viewed session's own elapsed response time. Live TPS and elapsed-time estimates are marked with `~`.
30
+ - **Native terminal UI:** Keep a sidebar panel in the main session and a single-line summary in subagent views; open details only when needed.
31
+ - **On-demand details:** Use `/usage` for compact or detailed statistics, including per-model usage and rates, without sending a prompt to the model.
32
+
18
33
  [![OpenCode Token Usage plugin preview](https://raw.githubusercontent.com/chenlongapps/opencode-token-usage/main/docs/assets/opencode-token-usage-preview.webp)](https://www.npmjs.com/package/@chenlongapps/opencode-token-usage)
19
34
 
20
35
  ---
21
36
 
22
37
  ### Installation
23
38
 
39
+ Requires **OpenCode 2** and **Node.js 22+**. See [Compatibility](#compatibility) for verified host versions and the OpenTUI engine caveat.
40
+
24
41
  ```bash
25
42
  opencode plugin add @chenlongapps/opencode-token-usage
26
43
  ```
27
44
 
28
- Alternatively, add the package to your project's `opencode.json` or `opencode.jsonc`:
45
+ Restart OpenCode after installation.
46
+
47
+ ### Quick start
48
+
49
+ 1. **View usage:** Open a session. The **Token Usage** panel appears in the native sidebar when `session.sidebar` is set to `auto` and the terminal is wide enough.
50
+ 2. **Explore details:** Enter `/usage` or left-click the panel's **Token Usage** title. Press `d` to toggle compact/detailed mode and Escape to close. Opening details does not send a prompt to the model.
51
+ 3. **Inspect subagents:** In subagent views, click the live summary above the composer to open the full panel. Closing it does not interrupt the subagent.
52
+
53
+ For exact definitions and edge cases, see [Detailed usage](#detailed-usage), [Metrics](#metrics) and [price sources and limitations](docs/pricing.md).
54
+
55
+ Questions about setup, costs, subagents, reasoning speed or privacy? See the [FAQ](docs/faq.md).
56
+
57
+ ### Other installation options
58
+
59
+ Instead of the command above, add the package to your project's `opencode.json` or `opencode.jsonc`:
29
60
 
30
61
  ```json
31
62
  {
63
+ "$schema": "https://opencode.ai/config.json",
32
64
  "plugins": ["@chenlongapps/opencode-token-usage"]
33
65
  }
34
66
  ```
35
67
 
36
- > [!NOTE]
37
- > Requires Node.js 22+ (see the OpenTUI engine note under [Development](#development)). OpenCode 2.0.9 and 2.0.10 have been verified in earlier releases. SDK 2.0.24 integration checks have passed on OpenCode 2.0.11, 2.0.22, 2.0.24, 2.0.26, and 2.0.28. Native turn durations and sidebar title clicks were integration-tested on 2.0.26 and 2.0.28; the other listed host checks predate these additions.
68
+ For remote sessions, add the package name to `plugins` in your local `~/.config/opencode/cli.json` to load only the terminal entry point. The configuration path follows `XDG_CONFIG_HOME`.
38
69
 
39
- Restart OpenCode after installation. The panel appears in the native sidebar when `session.sidebar` is set to `auto` and the terminal is wide enough. Click its **Token Usage** title to open the detailed usage dialog. OpenCode hides the sidebar in subagent views, so the plugin keeps one live summary line above the composer with Context, Total, Cost, Time, and TPS. Click the line to open the full statistics in a centered dialog. Press Escape or click **esc** to close it; closing the dialog does not interrupt the subagent.
70
+ ### Compatibility
40
71
 
41
- For remote sessions, add the package name to `plugins` in your local `~/.config/opencode/cli.json` to load only the terminal entry point. The configuration path follows `XDG_CONFIG_HOME`.
72
+ Requires Node.js 22+ (see the OpenTUI engine note under [Development](#development)). OpenCode 2.0.9 and 2.0.10 have been verified in earlier releases. SDK 2.0.24 integration checks have passed on OpenCode 2.0.11, 2.0.22, 2.0.24, 2.0.26, and 2.0.28. Native turn durations and sidebar title clicks were integration-tested on 2.0.26 and 2.0.28; the other listed host checks predate these additions. See the [verification record](docs/verification.md) for tested combinations.
42
73
 
43
74
  ### Detailed usage
44
75
 
@@ -77,7 +108,7 @@ Costs follow the sidebar's pricing and `partial`/unavailable/free conventions. I
77
108
  | `Steps` | Assistant message count across the session tree, including subagents; follows OpenCode's own stats definition, so compaction and user messages are not steps |
78
109
  | `Est. Cost` | Estimated cost across the tree, pricing each assistant and compaction call with its actual model |
79
110
  | `Run Time` | The viewed session's cumulative native per-turn response duration; while running, includes a display-only estimate of the current turn's elapsed time marked with `~`; never adds child-session durations |
80
- | `TPS` | Provider-reported average throughput for `Output + Reasoning` across the tree. While streaming, a valid recent observable text, reasoning-summary and tool-input estimate (UTF-8 bytes / 4) takes precedence and is marked with `~`. It needs at least 500 ms of observation after an initial baseline batch, excluding pre-first-token waiting. APIs such as OpenAI Responses do not expose complete hidden reasoning tokens in real time, so live values cannot represent hidden reasoning throughput. Completion restores provider-reported throughput without `~` |
111
+ | `TPS` | Provider-reported average throughput for `Output + Reasoning` across the tree. While streaming, a valid recent observable text, reasoning-summary and tool-input estimate (UTF-8 bytes / 4) takes precedence and is marked with `~`. It requires at least 20 estimated tokens accumulated in that response, three merged batches in the current window and a span of at least 500 ms, excluding pre-first-token waiting. APIs such as OpenAI Responses do not expose complete hidden reasoning tokens in real time, so live values cannot represent hidden reasoning throughput. Completion restores provider-reported throughput without `~` |
81
112
  | `TTFT` | Average time to first token across measurable assistant steps in the tree |
82
113
 
83
114
  #### Behavior
@@ -95,7 +126,7 @@ Costs follow the sidebar's pricing and `partial`/unavailable/free conventions. I
95
126
  - `Est. Cost` prices every message with its recorded model. A complete non-zero price resolved by OpenCode takes precedence. If OpenCode reports a complete zero price, a complete first-party snapshot price overrides it; incomplete prices fall back for the whole message without mixing rates.
96
127
  - The checked-in fallback snapshot is generated from [models.dev](https://models.dev/api.json) using only reviewed first-party provider/model families; a small set of manufacturer-verified exceptions is kept separately. It covers priced text models, without downloading prices while the plugin runs. Gateway models match exact manufacturer IDs, documented aliases, and known wrappers; only a terminal `-free` or `:free` can be removed for a second exact lookup.
97
128
  - Confirmed free usage displays `$0.00`; positive estimates below `$0.001` display `<$0.001`, estimates through and including `$0.01` use three decimal places, and larger estimates use two. Unavailable prices display `—`; known subtotals with unpriced messages are marked `partial`. The snapshot excludes gateway markups, regional premiums, unlisted discounts, non-text billing, tool fees, and taxes, so Est. Cost is not a provider bill. See [price sources and limitations](docs/pricing.md).
98
- - Live `TPS` uses a ~2s sliding window, batches deliveries within 100 ms and requires a span of at least 500 ms. The first batch is only a baseline: its bytes are not counted as output generated after its timestamp. Smoothing follows elapsed time rather than delta count. After 2s without a new delta, a shared in-memory timeout expires the estimate without reading history; historical TPS takes over, or the row is hidden if unavailable. Resuming output after expiry starts a fresh baseline and smoothing state.
129
+ - Live `TPS` uses a ~2s sliding window and batches deliveries within 100 ms. It starts calculating and displaying only when all three conditions hold: that response has accumulated at least 20 estimated tokens (80 UTF-8 bytes), the current window contains at least three merged batches, and those batches span at least 500 ms. The first batch counts toward the response-wide threshold but is only a speed baseline: its bytes are not counted as output generated after its timestamp. Token readiness is separate for each response, never pooled across responses or subagents. Smoothing follows elapsed time rather than delta count. Before readiness, historical TPS takes over, or the row is hidden if unavailable. After 2s without a new delta, a shared in-memory timeout expires the estimate without reading history. Resuming output after expiry starts a fresh baseline and smoothing state and must satisfy the batch/span conditions again; the same response's accumulated token count is retained.
99
130
  - Reconnection resets live TPS windows and reconciles all tracked sessions, including offscreen sessions, with the server's active-session set. Quiet unfinished streams get a shared activity check after 60s, without reading message history. Confirmed inactive streams and their TTFT observations expire after a further 60s. Running tools, retries and pre-first-token waits have no hard lifetime; failed activity reads retain state and retry. Provider `streamed` metadata alone never means that tools have finished. Checks stop when no unfinished streams remain.
100
131
  - Live TPS measures observable delivery, not the model's internal token-generation clock. Responses summary bursts, done-only content and transport buffering can still affect estimates; complete hidden reasoning cannot be reconstructed. Without `~`, TPS is `Σ(Output + Reasoning) ÷ Σ(time.streamed − time.created)` in seconds across valid assistant samples in the tree, not just the last request. This historical denominator includes pre-first-token waiting, so it is not the same metric as the recent live estimate. No model-specific multipliers, hard TPS caps or hidden-reasoning guesses are applied.
101
132
  - Initial read failures display `Unavailable`. Later failures retain the last complete snapshot, display `Not updated`, and retry automatically.
@@ -136,6 +167,7 @@ To load the plugin from source, build the project and add the repository's absol
136
167
 
137
168
  ### Documentation
138
169
 
170
+ - [FAQ](docs/faq.md) · [简体中文](docs/faq.zh-CN.md)
139
171
  - [Roadmap](ROADMAP.md)
140
172
  - [Verification record](docs/verification.md)
141
173
  - [Release guide](docs/releasing.md)
package/README.zh-CN.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <h1 align="center">opencode-token-usage</h1>
2
2
 
3
- <p align="center">面向 OpenCode 2 的会话树 token 用量监视器。</p>
3
+ <p align="center">在 OpenCode 2 中查看 token 用量、上下文窗口、估算费用与实时性能。</p>
4
4
 
5
5
  <p align="center">
6
6
  <a href="https://www.npmjs.com/package/@chenlongapps/opencode-token-usage" target="_blank" rel="noopener noreferrer"><img alt="npm" src="https://img.shields.io/npm/v/%40chenlongapps%2Fopencode-token-usage?style=flat-square&logo=npm" /></a>
@@ -15,30 +15,61 @@
15
15
  <strong>简体中文</strong>
16
16
  </p>
17
17
 
18
+ ### 项目简介
19
+
20
+ **opencode-token-usage** 是一个面向 OpenCode 2 的社区插件,在终端界面中展示 token 用量、上下文窗口占用、估算费用和性能指标。
21
+
22
+ 无需离开当前对话,就能了解:当前会话及其子代理消耗了多少 token、上下文窗口还剩多少空间,以及各模型的估算费用分布。
23
+
24
+ ### 主要特点
25
+
26
+ - **会话树用量汇总:** 统计整棵会话树的输入、输出、推理和缓存 token,包含未打开的子代理,避免重复计算分叉继承历史。
27
+ - **上下文可见:** 查看当前会话的上下文占用、最近一次已上报请求及提示词构成估算。
28
+ - **按模型估算费用:** 按每次调用实际使用的模型计价,以内置原厂价格快照作为回退。估算费用不等于提供商账单。
29
+ - **性能一目了然:** 查看每秒 token 数(TPS)、首 token 时间(TTFT)及当前会话自身的对话耗时。实时 TPS 与已耗时估算以 `~` 标记。
30
+ - **原生终端界面:** 主会话使用侧边栏,子代理视图保留单行摘要,按需打开完整面板。
31
+ - **按需查看详情:** 通过 `/usage` 切换紧凑/详细统计,查看各模型的用量与费率,不向模型发送提示词。
32
+
18
33
  [![OpenCode Token Usage 插件预览](https://raw.githubusercontent.com/chenlongapps/opencode-token-usage/main/docs/assets/opencode-token-usage-preview.webp)](https://www.npmjs.com/package/@chenlongapps/opencode-token-usage)
19
34
 
20
35
  ---
21
36
 
22
37
  ### 安装
23
38
 
39
+ 需要 **OpenCode 2** 和 **Node.js 22+**。已验证宿主版本及 OpenTUI 引擎限制见[兼容性](#兼容性)。
40
+
24
41
  ```bash
25
42
  opencode plugin add @chenlongapps/opencode-token-usage
26
43
  ```
27
44
 
28
- 也可以在项目的 `opencode.json` 或 `opencode.jsonc` 中配置:
45
+ 安装后重启 OpenCode。
46
+
47
+ ### 快速上手
48
+
49
+ 1. **查看用量:** 打开会话。终端足够宽且 `session.sidebar` 设为 `auto` 时,原生侧边栏会显示 **Token Usage** 面板。
50
+ 2. **展开详情:** 输入 `/usage`,或左键点击面板的 **Token Usage** 标题。按 `d` 切换紧凑/详细模式,按 Escape 关闭;打开详情不会向模型发送提示词。
51
+ 3. **查看子代理:** 在子代理视图中,点击输入区上方的实时摘要可打开完整面板,关闭面板不会中断子代理。
52
+
53
+ 精确统计口径及边界情况见[详细用量](#详细用量)、[指标](#指标)和[价格来源与限制](docs/pricing.md)。
54
+
55
+ 关于安装、费用、子代理、推理速度及隐私的常见问题,见 [FAQ](docs/faq.zh-CN.md)。
56
+
57
+ ### 其他安装方式
58
+
59
+ 除了上述命令,也可以在项目的 `opencode.json` 或 `opencode.jsonc` 中配置:
29
60
 
30
61
  ```json
31
62
  {
63
+ "$schema": "https://opencode.ai/config.json",
32
64
  "plugins": ["@chenlongapps/opencode-token-usage"]
33
65
  }
34
66
  ```
35
67
 
36
- > [!NOTE]
37
- > 需要 Node.js 22+(见[开发](#开发)中的 OpenTUI 引擎说明)。此前发布已验证 OpenCode 2.0.9 和 2.0.10;SDK 2.0.24 集成检查已在 OpenCode 2.0.11、2.0.22、2.0.24、2.0.26 和 2.0.28 上通过。原生对话耗时与侧边栏标题点击的集成验证使用 2.0.26 和 2.0.28,其余列出的宿主检查早于这些功能加入。
68
+ 连接远程服务器时,可将包名加入本机 `~/.config/opencode/cli.json` 的 `plugins`,仅加载终端入口;配置路径遵循 `XDG_CONFIG_HOME`。
38
69
 
39
- 安装后重启 OpenCode。终端足够宽且 `session.sidebar` 设为 `auto` 时,面板会显示在原生侧边栏中。点击面板的 **Token Usage** 标题可打开用量详情弹窗。OpenCode 在子代理视图中隐藏侧边栏,因此插件会在输入区上方保留一行实时摘要,显示 Context、Total、Cost、Time 和 TPS。点击摘要可在居中弹窗中查看完整统计;按 Escape 或点击 **esc** 即可关闭,关闭弹窗不会中断子代理。
70
+ ### 兼容性
40
71
 
41
- 连接远程服务器时,可将包名加入本机 `~/.config/opencode/cli.json` 的 `plugins`,仅加载终端入口;配置路径遵循 `XDG_CONFIG_HOME`。
72
+ 需要 Node.js 22+(见[开发](#开发)中的 OpenTUI 引擎说明)。此前发布已验证 OpenCode 2.0.9 和 2.0.10;SDK 2.0.24 集成检查已在 OpenCode 2.0.11、2.0.22、2.0.24、2.0.26 和 2.0.28 上通过。原生对话耗时与侧边栏标题点击的集成验证使用 2.0.26 和 2.0.28,其余列出的宿主检查早于这些功能加入。已测试组合见[验证记录](docs/verification.md)。
42
73
 
43
74
  ### 详细用量
44
75
 
@@ -77,7 +108,7 @@ opencode plugin add @chenlongapps/opencode-token-usage
77
108
  | `Steps` | 全树(含子代理)的 assistant 消息数,口径与 OpenCode 自带统计一致,compaction 与用户消息不计为 step |
78
109
  | `Est. Cost` | 按每条 assistant 与 compaction 消息实际模型估算的全树费用 |
79
110
  | `Run Time` | 被查看会话自身的累计原生对话耗时;运行中包含仅用于显示的当前轮已耗时估算,以 `~` 标记;不额外叠加子会话耗时 |
80
- | `TPS` | 服务端已上报的全树 `Output + Reasoning` 平均吞吐。流式进行中时,优先显示有效的近期可观察文本、reasoning summary 和工具输入估算(UTF-8 字节数 / 4),以 `~` 标记;首批增量仅作基线,之后至少观察 500ms,不计首 token 前等待时间。OpenAI Responses 等 API 不会实时暴露完整的隐藏 reasoning token,因此实时值不能表示隐藏推理吞吐。完成后恢复不带 `~` 的服务端上报吞吐 |
111
+ | `TPS` | 服务端已上报的全树 `Output + Reasoning` 平均吞吐。流式进行中时,优先显示有效的近期可观察文本、reasoning summary 和工具输入估算(UTF-8 字节数 / 4),以 `~` 标记;需单次响应累计至少 20 个估算 Token、当前窗口至少 3 个合并批次且跨度至少 500ms,不计首 token 前等待时间。OpenAI Responses 等 API 不会实时暴露完整的隐藏 reasoning token,因此实时值不能表示隐藏推理吞吐。完成后恢复不带 `~` 的服务端上报吞吐 |
81
112
  | `TTFT` | 全树中可测 assistant step 的平均首 token 时间 |
82
113
 
83
114
  #### 行为
@@ -95,7 +126,7 @@ opencode plugin add @chenlongapps/opencode-token-usage
95
126
  - `Est. Cost` 按每条消息记录的实际模型分别计算。OpenCode 当前解析出的完整非零价格优先;若 OpenCode 给出完整零价,且内置价格快照可以完整计价,则采用快照价格。价格不完整时整条消息回退,不混用两套费率。
96
127
  - 内置回退快照从 [models.dev](https://models.dev/api.json) 生成,只采用审核过的原厂 Provider 与自家模型系列;少量经原厂核实的例外单独维护。快照覆盖有价格的文本模型,插件运行时不下载价格。网关模型通过精确原厂 ID、明确别名和已知包装格式匹配;只有终尾 `-free` 或 `:free` 会在再次精确查找前移除。
97
128
  - 确认免费时显示 `$0.00`;正费用低于 `$0.001` 时显示 `<$0.001`,不超过 `$0.01` 的费用保留三位小数,更高费用保留两位。价格不可用时显示 `—`;只有部分消息可计算时在已知小计后标注 `partial`。快照不含网关加价、区域溢价、未列明的折扣、非文本计费、工具费和税费;Est. Cost 是估算而非账单。覆盖范围、来源和限制见[价格来源与限制](docs/pricing.md)。
98
- - 实时 `TPS` 使用约 2 秒滑动窗口,合并 100ms 内的增量,要求至少 500ms 的有效跨度。首批增量仅作基线,其字节不计为该时间戳之后生成的输出;平滑按经过时间而非 delta 条数推进。2 秒没有新增量时,共享的内存超时任务使估算过期,不读取历史;回退到历史 TPS,没有可用历史值则隐藏该行。过期后恢复输出时,重新建立基线与平滑状态。
129
+ - 实时 `TPS` 使用约 2 秒滑动窗口,合并 100ms 内的增量。只有同时满足三项条件才开始计算和显示:单次响应累计至少 20 个估算 Token(80 个 UTF-8 字节)、当前窗口至少 3 个合并批次、这些批次的有效跨度至少 500ms。首批增量计入响应累计门槛,但仅作测速基线,其字节不计为该时间戳之后生成的输出。各响应独立累计,不跨响应或子代理合并门槛。平滑按经过时间而非 delta 条数推进。门槛未满足时回退到历史 TPS,没有可用历史值则隐藏该行。2 秒没有新增量时,共享的内存超时任务使估算过期,不读取历史。过期后恢复输出时,重新建立基线与平滑状态,并重新满足批次数和跨度条件;同一响应的累计 Token 数保留。
99
130
  - 重连时重置实时 TPS 窗口,并通过服务端活动会话列表对账全部已跟踪会话,包括离屏会话。未结束的流静默 60 秒后进行共享活动检查,不读取消息历史;确认会话已停止后,再保留 60 秒并回收流及其 TTFT 观察。仍在运行的工具、重试及首 token 前等待没有硬性寿命上限;活动查询失败时保留状态并重试。仅有提供商的 `streamed` 元数据不代表工具已结束。没有未结束流时停止检查。
100
131
  - 实时 TPS 测量可观察的内容交付,而非模型内部生成 token 的时钟。Responses 摘要突发、仅在 done 中返回的内容和传输缓冲仍可能影响估算,不能还原完整隐藏推理。不带 `~` 时,TPS 为全树有效 assistant 样本的 `Σ(Output + Reasoning) ÷ Σ(time.streamed − time.created)`(换算为秒),不是仅取最近请求;该历史分母包含首 token 前等待,与近期实时估算口径不同。不做模型专属倍率、TPS 硬上限或隐藏 reasoning token 猜测。
101
132
  - 首次读取失败显示 `Unavailable`;后续失败保留上次完整快照、标注 `Not updated` 并自动重试。
@@ -136,6 +167,7 @@ OPENCODE_BIN=/absolute/path/to/opencode-2.0.11 npm run test:smoke
136
167
 
137
168
  ### 文档
138
169
 
170
+ - [常见问题 FAQ](docs/faq.zh-CN.md)
139
171
  - [路线图](ROADMAP.md)
140
172
  - [验证记录](docs/verification.md)
141
173
  - [发布说明](docs/releasing.md)
package/ROADMAP.md CHANGED
@@ -116,7 +116,7 @@ Steps 1,234
116
116
  * [x] 时间缺失显示不可用,读取失败保留旧值并标注未更新;分叉副本不继承耗时,已提交回退随删除历史扣除
117
117
  * [x] 移除动画后通过类型检查、205 项测试、构建及真实 OpenCode 2.0.26 完整打包集成复验
118
118
  * [x] 首轮尚无 idle 消息时依据原生会话时间保持起点,synthetic/steer 不误重置;重连校时期间保留同一开放轮次的可信显示,247 项测试及真实 OpenCode 2.0.28 完整打包验证通过
119
- * [ ] macOS 物理多屏切换导致耗时倒退的实机复验(终端焦点事件、视图重建与模拟重连已覆盖,不代表已验证物理切屏、App Nap 或睡眠/唤醒)
119
+ * [x] macOS 物理多屏切换导致耗时倒退的实机复验(终端焦点事件、视图重建与模拟重连已覆盖,不代表已验证物理切屏、App Nap 或睡眠/唤醒)
120
120
 
121
121
  ## 后续评估
122
122
 
@@ -24,6 +24,8 @@ export interface StreamSample {
24
24
  export declare const LIVE_WINDOW_MS = 2000;
25
25
  export declare const LIVE_MIN_SPAN_MS = 500;
26
26
  export declare const LIVE_SAMPLE_MS = 100;
27
+ export declare const LIVE_MIN_TOKENS = 20;
28
+ export declare const LIVE_MIN_BATCHES = 3;
27
29
  export declare const LIVE_EWMA_ALPHA = 0.35;
28
30
  export declare const LIVE_BYTES_PER_TOKEN = 4;
29
31
  /** Quiet streams need a server liveness check, not a maximum tool-wait duration. */
@@ -34,7 +36,7 @@ export interface PerformanceOptions {
34
36
  monotonic?: () => number;
35
37
  active?: ReadActiveSessions | undefined;
36
38
  }
37
- /** The first batch is a counter baseline, not bytes generated after its timestamp. */
39
+ /** Requires three merged batches; the first is a baseline, not newly generated bytes. */
38
40
  export declare function estimatedLiveTps(samples: readonly StreamSample[]): number | undefined;
39
41
  /** Time-based EWMA: elapsed time determines the weight, never delta count. */
40
42
  export declare function smoothLiveTps(previous: number | undefined, raw: number, elapsed?: number): number;
@@ -2,13 +2,15 @@ import { normalize } from "./usage.js";
2
2
  export const LIVE_WINDOW_MS = 2_000;
3
3
  export const LIVE_MIN_SPAN_MS = 500;
4
4
  export const LIVE_SAMPLE_MS = 100;
5
+ export const LIVE_MIN_TOKENS = 20;
6
+ export const LIVE_MIN_BATCHES = 3;
5
7
  export const LIVE_EWMA_ALPHA = 0.35;
6
8
  export const LIVE_BYTES_PER_TOKEN = 4;
7
9
  /** Quiet streams need a server liveness check, not a maximum tool-wait duration. */
8
10
  export const ACTIVITY_CHECK_MS = 60_000;
9
- /** The first batch is a counter baseline, not bytes generated after its timestamp. */
11
+ /** Requires three merged batches; the first is a baseline, not newly generated bytes. */
10
12
  export function estimatedLiveTps(samples) {
11
- if (samples.length < 2)
13
+ if (samples.length < LIVE_MIN_BATCHES)
12
14
  return undefined;
13
15
  const first = samples[0];
14
16
  const last = samples[samples.length - 1];
@@ -464,7 +466,8 @@ export class PerformanceMonitor {
464
466
  const cutoff = event.created - LIVE_WINDOW_MS;
465
467
  while (step.samples.length > 0 && step.samples[0].time < cutoff)
466
468
  step.samples.shift();
467
- const raw = estimatedLiveTps(step.samples);
469
+ // The response-wide threshold includes the baseline and survives window resets.
470
+ const raw = step.bytes >= LIVE_MIN_TOKENS * LIVE_BYTES_PER_TOKEN ? estimatedLiveTps(step.samples) : undefined;
468
471
  if (raw === undefined) {
469
472
  delete step.liveTps;
470
473
  delete step.liveDuration;
@@ -1,5 +1,5 @@
1
1
  export declare const GENERATED_PRICE_SNAPSHOT: {
2
- readonly verified: "2026-10-21";
2
+ readonly verified: "2026-10-23";
3
3
  readonly source: "https://models.dev/api.json";
4
4
  readonly entries: readonly [{
5
5
  readonly providerID: "ai21";
@@ -1266,10 +1266,10 @@ export declare const GENERATED_PRICE_SNAPSHOT: {
1266
1266
  readonly providerID: "inception";
1267
1267
  readonly id: "mercury-2.5";
1268
1268
  readonly prices: readonly [{
1269
- readonly input: 0.04;
1270
- readonly output: 0.15;
1269
+ readonly input: 0.2;
1270
+ readonly output: 0.75;
1271
1271
  readonly cache: {
1272
- readonly read: 0.004;
1272
+ readonly read: 0.02;
1273
1273
  };
1274
1274
  }];
1275
1275
  readonly released: "2026-09-08";
@@ -1299,13 +1299,24 @@ export declare const GENERATED_PRICE_SNAPSHOT: {
1299
1299
  readonly providerID: "longcat";
1300
1300
  readonly id: "longcat-2.0";
1301
1301
  readonly prices: readonly [{
1302
- readonly input: 0.75;
1303
- readonly output: 2.95;
1302
+ readonly input: 0.3;
1303
+ readonly output: 1.2;
1304
1304
  readonly cache: {
1305
- readonly read: 0.015;
1305
+ readonly read: 0.006;
1306
1306
  };
1307
1307
  }];
1308
1308
  readonly released: "2026-06-30";
1309
+ }, {
1310
+ readonly providerID: "longcat";
1311
+ readonly id: "longcat-2.5-preview";
1312
+ readonly prices: readonly [{
1313
+ readonly input: 0.3;
1314
+ readonly output: 1.2;
1315
+ readonly cache: {
1316
+ readonly read: 0.006;
1317
+ };
1318
+ }];
1319
+ readonly released: "2026-09-25";
1309
1320
  }, {
1310
1321
  readonly providerID: "meta";
1311
1322
  readonly id: "muse-spark-1.1";
@@ -1636,10 +1647,10 @@ export declare const GENERATED_PRICE_SNAPSHOT: {
1636
1647
  readonly providerID: "mistral";
1637
1648
  readonly id: "mistral-large-4";
1638
1649
  readonly prices: readonly [{
1639
- readonly input: 0.68;
1640
- readonly output: 2.09;
1650
+ readonly input: 1.36;
1651
+ readonly output: 4.18;
1641
1652
  readonly cache: {
1642
- readonly read: 0.07;
1653
+ readonly read: 0.14;
1643
1654
  };
1644
1655
  }];
1645
1656
  readonly released: "2026-10-06";
@@ -1823,22 +1834,6 @@ export declare const GENERATED_PRICE_SNAPSHOT: {
1823
1834
  readonly output: 0;
1824
1835
  }];
1825
1836
  readonly released: "2025-04-15";
1826
- }, {
1827
- readonly providerID: "nvidia";
1828
- readonly id: "nvidia/llama-3.1-nemotron-nano-8b-v1";
1829
- readonly prices: readonly [{
1830
- readonly input: 0;
1831
- readonly output: 0;
1832
- }];
1833
- readonly released: "2025-03-18";
1834
- }, {
1835
- readonly providerID: "nvidia";
1836
- readonly id: "nvidia/llama-3.1-nemotron-nano-vl-8b-v1";
1837
- readonly prices: readonly [{
1838
- readonly input: 0;
1839
- readonly output: 0;
1840
- }];
1841
- readonly released: "2025-04-10";
1842
1837
  }, {
1843
1838
  readonly providerID: "nvidia";
1844
1839
  readonly id: "nvidia/llama-3.1-nemotron-safety-guard-8b-v3";
@@ -1855,37 +1850,6 @@ export declare const GENERATED_PRICE_SNAPSHOT: {
1855
1850
  readonly output: 0;
1856
1851
  }];
1857
1852
  readonly released: "2025-04-07";
1858
- }, {
1859
- readonly providerID: "nvidia";
1860
- readonly id: "nvidia/llama-3.3-nemotron-super-49b-v1";
1861
- readonly prices: readonly [{
1862
- readonly input: 0;
1863
- readonly output: 0;
1864
- }];
1865
- readonly released: "2025-03-18";
1866
- }, {
1867
- readonly providerID: "nvidia";
1868
- readonly id: "nvidia/llama-3.3-nemotron-super-49b-v1.5";
1869
- readonly prices: readonly [{
1870
- readonly input: 0;
1871
- readonly output: 0;
1872
- }];
1873
- readonly released: "2025-07-25";
1874
- }, {
1875
- readonly providerID: "nvidia";
1876
- readonly id: "nvidia/nemotron-3-content-safety";
1877
- readonly prices: readonly [{
1878
- readonly input: 0;
1879
- readonly output: 0;
1880
- }];
1881
- readonly released: "2026-04-16";
1882
- }, {
1883
- readonly providerID: "nvidia";
1884
- readonly id: "nvidia/nemotron-3-nano-30b-a3b";
1885
- readonly prices: readonly [{
1886
- readonly input: 0;
1887
- readonly output: 0;
1888
- }];
1889
1853
  }, {
1890
1854
  readonly providerID: "nvidia";
1891
1855
  readonly id: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning";
@@ -1898,11 +1862,8 @@ export declare const GENERATED_PRICE_SNAPSHOT: {
1898
1862
  readonly providerID: "nvidia";
1899
1863
  readonly id: "nvidia/nemotron-3-ultra-550b-a55b";
1900
1864
  readonly prices: readonly [{
1901
- readonly input: 0.5;
1902
- readonly output: 2.5;
1903
- readonly cache: {
1904
- readonly read: 0.15;
1905
- };
1865
+ readonly input: 0;
1866
+ readonly output: 0;
1906
1867
  }];
1907
1868
  readonly released: "2026-06-04";
1908
1869
  }, {
@@ -1929,30 +1890,6 @@ export declare const GENERATED_PRICE_SNAPSHOT: {
1929
1890
  readonly output: 0;
1930
1891
  }];
1931
1892
  readonly released: "2026-10-15";
1932
- }, {
1933
- readonly providerID: "nvidia";
1934
- readonly id: "nvidia/nemotron-content-safety-reasoning-4b";
1935
- readonly prices: readonly [{
1936
- readonly input: 0;
1937
- readonly output: 0;
1938
- }];
1939
- readonly released: "2026-01-22";
1940
- }, {
1941
- readonly providerID: "nvidia";
1942
- readonly id: "nvidia/nemotron-mini-4b-instruct";
1943
- readonly prices: readonly [{
1944
- readonly input: 0;
1945
- readonly output: 0;
1946
- }];
1947
- readonly released: "2024-08-21";
1948
- }, {
1949
- readonly providerID: "nvidia";
1950
- readonly id: "nvidia/nemotron-nano-12b-v2-vl";
1951
- readonly prices: readonly [{
1952
- readonly input: 0;
1953
- readonly output: 0;
1954
- }];
1955
- readonly released: "2025-10-28";
1956
1893
  }, {
1957
1894
  readonly providerID: "nvidia";
1958
1895
  readonly id: "nvidia/nemotron-voicechat";
@@ -3016,10 +2953,10 @@ export declare const GENERATED_PRICE_SNAPSHOT: {
3016
2953
  readonly providerID: "stepfun-ai";
3017
2954
  readonly id: "step-3.7-flash";
3018
2955
  readonly prices: readonly [{
3019
- readonly input: 0.185;
3020
- readonly output: 1.11;
2956
+ readonly input: 0.2;
2957
+ readonly output: 1.15;
3021
2958
  readonly cache: {
3022
- readonly read: 0.037;
2959
+ readonly read: 0.04;
3023
2960
  };
3024
2961
  }];
3025
2962
  readonly released: "2026-05-29";
@@ -3030,7 +2967,7 @@ export declare const GENERATED_PRICE_SNAPSHOT: {
3030
2967
  readonly input: 1;
3031
2968
  readonly output: 2.7;
3032
2969
  readonly cache: {
3033
- readonly read: 0.05;
2970
+ readonly read: 0.1;
3034
2971
  };
3035
2972
  }];
3036
2973
  readonly released: "2026-09-16";
@@ -3079,6 +3016,7 @@ export declare const GENERATED_PRICE_SNAPSHOT: {
3079
3016
  readonly input: 0.25;
3080
3017
  readonly output: 0.25;
3081
3018
  }];
3019
+ readonly released: "2026-01-26";
3082
3020
  }, {
3083
3021
  readonly providerID: "upstage";
3084
3022
  readonly id: "solar-pro4";
@@ -1,5 +1,5 @@
1
1
  export const GENERATED_PRICE_SNAPSHOT = {
2
- verified: "2026-10-21",
2
+ verified: "2026-10-23",
3
3
  source: "https://models.dev/api.json",
4
4
  entries: [
5
5
  { "providerID": "ai21", "id": "jamba-large", "prices": [{ "input": 2, "output": 8 }], "released": "2025-07-03" },
@@ -111,10 +111,11 @@ export const GENERATED_PRICE_SNAPSHOT = {
111
111
  { "providerID": "google", "id": "gemini-flash-lite-latest", "prices": [{ "input": 0.3, "output": 2.5, "cache": { "read": 0.03 } }], "released": "2026-07-21" },
112
112
  { "providerID": "google", "id": "gemini-pro-latest", "prices": [{ "input": 2, "output": 12, "cache": { "read": 0.2 } }, { "input": 4, "output": 18, "cache": { "read": 0.4 }, "tier": { "type": "context", "size": 200000 } }], "released": "2026-02-19" },
113
113
  { "providerID": "inception", "id": "mercury-2", "prices": [{ "input": 0.25, "output": 0.75, "cache": { "read": 0.025 } }], "released": "2026-02-24" },
114
- { "providerID": "inception", "id": "mercury-2.5", "prices": [{ "input": 0.04, "output": 0.15, "cache": { "read": 0.004 } }], "released": "2026-09-08" },
114
+ { "providerID": "inception", "id": "mercury-2.5", "prices": [{ "input": 0.2, "output": 0.75, "cache": { "read": 0.02 } }], "released": "2026-09-08" },
115
115
  { "providerID": "inception", "id": "mercury-3", "prices": [{ "input": 0.1, "output": 0.35, "cache": { "read": 0.01 } }], "released": "2026-10-16" },
116
116
  { "providerID": "inception", "id": "mercury-edit-2", "prices": [{ "input": 0.25, "output": 0.75, "cache": { "read": 0.025 } }], "released": "2026-03-30" },
117
- { "providerID": "longcat", "id": "longcat-2.0", "prices": [{ "input": 0.75, "output": 2.95, "cache": { "read": 0.015 } }], "released": "2026-06-30" },
117
+ { "providerID": "longcat", "id": "longcat-2.0", "prices": [{ "input": 0.3, "output": 1.2, "cache": { "read": 0.006 } }], "released": "2026-06-30" },
118
+ { "providerID": "longcat", "id": "longcat-2.5-preview", "prices": [{ "input": 0.3, "output": 1.2, "cache": { "read": 0.006 } }], "released": "2026-09-25" },
118
119
  { "providerID": "meta", "id": "muse-spark-1.1", "prices": [{ "input": 1.25, "output": 4.25, "cache": { "read": 0.15 } }], "released": "2026-04-08" },
119
120
  { "providerID": "meta", "id": "muse-spark-1.2", "prices": [{ "input": 1.25, "output": 4.25, "cache": { "read": 0.15 } }], "released": "2026-08-05" },
120
121
  { "providerID": "meta", "id": "muse-spark-1.2-contributor", "prices": [{ "input": 0.1, "output": 0.2, "cache": { "read": 0.002 } }], "released": "2026-08-05" },
@@ -146,7 +147,7 @@ export const GENERATED_PRICE_SNAPSHOT = {
146
147
  { "providerID": "mistral", "id": "ministral-8b-latest", "prices": [{ "input": 0.15, "output": 0.15, "cache": { "read": 0.015 } }], "released": "2024-10-01" },
147
148
  { "providerID": "mistral", "id": "mistral-large-2411", "prices": [{ "input": 2, "output": 6 }], "released": "2024-11-18" },
148
149
  { "providerID": "mistral", "id": "mistral-large-2512", "prices": [{ "input": 0.5, "output": 1.5, "cache": { "read": 0.05 } }], "released": "2024-11-01" },
149
- { "providerID": "mistral", "id": "mistral-large-4", "prices": [{ "input": 0.68, "output": 2.09, "cache": { "read": 0.07 } }], "released": "2026-10-06" },
150
+ { "providerID": "mistral", "id": "mistral-large-4", "prices": [{ "input": 1.36, "output": 4.18, "cache": { "read": 0.14 } }], "released": "2026-10-06" },
150
151
  { "providerID": "mistral", "id": "mistral-large-latest", "prices": [{ "input": 0.5, "output": 1.5, "cache": { "read": 0.05 } }], "released": "2024-11-01" },
151
152
  { "providerID": "mistral", "id": "mistral-medium-2505", "prices": [{ "input": 0.4, "output": 2 }], "released": "2025-05-07" },
152
153
  { "providerID": "mistral", "id": "mistral-medium-2508", "prices": [{ "input": 0.4, "output": 2 }], "released": "2025-08-12" },
@@ -166,22 +167,13 @@ export const GENERATED_PRICE_SNAPSHOT = {
166
167
  { "providerID": "moonshotai", "id": "kimi-k2.7-code-highspeed", "prices": [{ "input": 1.9, "output": 8, "cache": { "read": 0.38 } }], "released": "2026-06-12" },
167
168
  { "providerID": "moonshotai", "id": "kimi-k3", "prices": [{ "input": 3, "output": 15, "cache": { "read": 0.3, "write": 3 } }], "released": "2026-07-16" },
168
169
  { "providerID": "nvidia", "id": "nvidia/llama-3.1-nemotron-70b-instruct", "prices": [{ "input": 0, "output": 0 }], "released": "2025-04-15" },
169
- { "providerID": "nvidia", "id": "nvidia/llama-3.1-nemotron-nano-8b-v1", "prices": [{ "input": 0, "output": 0 }], "released": "2025-03-18" },
170
- { "providerID": "nvidia", "id": "nvidia/llama-3.1-nemotron-nano-vl-8b-v1", "prices": [{ "input": 0, "output": 0 }], "released": "2025-04-10" },
171
170
  { "providerID": "nvidia", "id": "nvidia/llama-3.1-nemotron-safety-guard-8b-v3", "prices": [{ "input": 0, "output": 0 }], "released": "2025-10-28" },
172
171
  { "providerID": "nvidia", "id": "nvidia/llama-3.1-nemotron-ultra-253b-v1", "prices": [{ "input": 0, "output": 0 }], "released": "2025-04-07" },
173
- { "providerID": "nvidia", "id": "nvidia/llama-3.3-nemotron-super-49b-v1", "prices": [{ "input": 0, "output": 0 }], "released": "2025-03-18" },
174
- { "providerID": "nvidia", "id": "nvidia/llama-3.3-nemotron-super-49b-v1.5", "prices": [{ "input": 0, "output": 0 }], "released": "2025-07-25" },
175
- { "providerID": "nvidia", "id": "nvidia/nemotron-3-content-safety", "prices": [{ "input": 0, "output": 0 }], "released": "2026-04-16" },
176
- { "providerID": "nvidia", "id": "nvidia/nemotron-3-nano-30b-a3b", "prices": [{ "input": 0, "output": 0 }] },
177
172
  { "providerID": "nvidia", "id": "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", "prices": [{ "input": 0, "output": 0 }], "released": "2026-04-28" },
178
- { "providerID": "nvidia", "id": "nvidia/nemotron-3-ultra-550b-a55b", "prices": [{ "input": 0.5, "output": 2.5, "cache": { "read": 0.15 } }], "released": "2026-06-04" },
173
+ { "providerID": "nvidia", "id": "nvidia/nemotron-3-ultra-550b-a55b", "prices": [{ "input": 0, "output": 0 }], "released": "2026-06-04" },
179
174
  { "providerID": "nvidia", "id": "nvidia/nemotron-3.5-content-safety", "prices": [{ "input": 0, "output": 0 }], "released": "2026-06-02" },
180
175
  { "providerID": "nvidia", "id": "nvidia/nemotron-3.5-lightning-30b-a3b", "prices": [{ "input": 0, "output": 0 }], "released": "2026-08-11" },
181
176
  { "providerID": "nvidia", "id": "nvidia/nemotron-3.5-super-vl-120b-a12b", "prices": [{ "input": 0, "output": 0 }], "released": "2026-10-15" },
182
- { "providerID": "nvidia", "id": "nvidia/nemotron-content-safety-reasoning-4b", "prices": [{ "input": 0, "output": 0 }], "released": "2026-01-22" },
183
- { "providerID": "nvidia", "id": "nvidia/nemotron-mini-4b-instruct", "prices": [{ "input": 0, "output": 0 }], "released": "2024-08-21" },
184
- { "providerID": "nvidia", "id": "nvidia/nemotron-nano-12b-v2-vl", "prices": [{ "input": 0, "output": 0 }], "released": "2025-10-28" },
185
177
  { "providerID": "nvidia", "id": "nvidia/nemotron-voicechat", "prices": [{ "input": 0, "output": 0 }], "released": "2026-03-16" },
186
178
  { "providerID": "openai", "id": "gpt-3.5-turbo", "prices": [{ "input": 0.5, "output": 1.5, "cache": { "read": 0 } }], "released": "2023-03-01" },
187
179
  { "providerID": "openai", "id": "gpt-4", "prices": [{ "input": 30, "output": 60 }], "released": "2023-11-06" },
@@ -260,13 +252,13 @@ export const GENERATED_PRICE_SNAPSHOT = {
260
252
  { "providerID": "stepfun-ai", "id": "step-2-16k", "prices": [{ "input": 5.21, "output": 16.44, "cache": { "read": 1.04 } }], "released": "2025-01-01" },
261
253
  { "providerID": "stepfun-ai", "id": "step-3.5-flash", "prices": [{ "input": 0.1, "output": 0.3, "cache": { "read": 0.02 } }], "released": "2026-01-29" },
262
254
  { "providerID": "stepfun-ai", "id": "step-3.5-flash-2603", "prices": [{ "input": 0.1, "output": 0.3, "cache": { "read": 0.02 } }], "released": "2026-04-02" },
263
- { "providerID": "stepfun-ai", "id": "step-3.7-flash", "prices": [{ "input": 0.185, "output": 1.11, "cache": { "read": 0.037 } }], "released": "2026-05-29" },
264
- { "providerID": "stepfun-ai", "id": "step-5-preview", "prices": [{ "input": 1, "output": 2.7, "cache": { "read": 0.05 } }], "released": "2026-09-16" },
255
+ { "providerID": "stepfun-ai", "id": "step-3.7-flash", "prices": [{ "input": 0.2, "output": 1.15, "cache": { "read": 0.04 } }], "released": "2026-05-29" },
256
+ { "providerID": "stepfun-ai", "id": "step-5-preview", "prices": [{ "input": 1, "output": 2.7, "cache": { "read": 0.1 } }], "released": "2026-09-16" },
265
257
  { "providerID": "tencent-tokenhub", "id": "hy4-preview", "prices": [{ "input": 0.834, "output": 2.501, "cache": { "read": 0.042 } }], "released": "2026-08-28" },
266
258
  { "providerID": "upstage", "id": "solar-mini", "prices": [{ "input": 0.15, "output": 0.15 }], "released": "2024-06-12" },
267
259
  { "providerID": "upstage", "id": "solar-mini4", "prices": [{ "input": 0.1, "output": 0.4, "cache": { "read": 0.01 } }], "released": "2026-09-22" },
268
260
  { "providerID": "upstage", "id": "solar-pro2", "prices": [{ "input": 0.25, "output": 0.25 }], "released": "2025-05-20" },
269
- { "providerID": "upstage", "id": "solar-pro3", "prices": [{ "input": 0.25, "output": 0.25 }] },
261
+ { "providerID": "upstage", "id": "solar-pro3", "prices": [{ "input": 0.25, "output": 0.25 }], "released": "2026-01-26" },
270
262
  { "providerID": "upstage", "id": "solar-pro4", "prices": [{ "input": 0.3, "output": 1.2, "cache": { "read": 0.06 } }], "released": "2026-08-06" },
271
263
  { "providerID": "volcengine", "id": "doubao-seed-1-6-251015", "prices": [{ "input": 0.11875, "output": 1.18747, "cache": { "read": 0.02375 } }, { "input": 0.17812, "output": 2.37494, "cache": { "read": 0.02375 }, "tier": { "type": "context", "size": 32000 } }, { "input": 0.35624, "output": 3.56241, "cache": { "read": 0.02375 }, "tier": { "type": "context", "size": 128000 } }], "released": "2025-10-15" },
272
264
  { "providerID": "volcengine", "id": "doubao-seed-1-6-flash-250828", "prices": [{ "input": 0.02227, "output": 0.22265, "cache": { "read": 0.00445 } }, { "input": 0.04453, "output": 0.4453, "cache": { "read": 0.00445 }, "tier": { "type": "context", "size": 32000 } }, { "input": 0.08906, "output": 0.8906, "cache": { "read": 0.00445 }, "tier": { "type": "context", "size": 128000 } }], "released": "2025-08-28" },
package/dist/pricing.d.ts CHANGED
@@ -14,7 +14,7 @@ export interface OfficialPriceEntry {
14
14
  /** Checked-in data: updating prices is explicit, not a network request at
15
15
  * startup, during a refresh, or during an npm build. */
16
16
  export declare const OFFICIAL_PRICE_SNAPSHOT: {
17
- verified: "2026-10-21";
17
+ verified: "2026-10-23";
18
18
  source: "https://models.dev/api.json";
19
19
  entries: OfficialPriceEntry[];
20
20
  };
@@ -1,5 +1,17 @@
1
1
  # 验证记录
2
2
 
3
+ ## 2026-10-21 · 实时 TPS 显示门槛(未发布)
4
+
5
+ `src/performance.ts` 的实时估算仅在三项条件同时满足时开始计算和显示:单条 assistant 响应累计可观察增量至少 20 个估算 Token(UTF-8 字节数 / 4,即至少 80 字节)、当前约 2 秒窗口中至少 3 个按 100ms 合并的独立批次、有效观察跨度至少 500ms。首批内容计入累计门槛,但仍只作测速基线,不进入速度分子;不跨响应或子代理合并门槛。原有时间加权平滑、历史 TPS、TTFT 和 2000ms 静默过期规则不变。
6
+
7
+ 窗口淘汰、静默过期和重连不清空同一响应的累计字节数,但恢复输出仍需重新满足当前窗口的批次和跨度条件。未就绪时保留历史 TPS,无历史则隐藏;增量和过期处理不新增历史读取或 API 调用。中英文 README 与产品约定已同步。
8
+
9
+ 环境:macOS、Node.js v22.23.2、npm 10.9.8,插件包 0.4.14、SDK 2.0.24、真实 OpenCode 2.1.2。类型检查、256 项自动化测试、构建、冒烟脚本语法检查及 `git diff --check` 通过。新增 8 项测试覆盖 79/80/81 字节边界、UTF-8 与各类增量、100ms 合并边界、三批但不足 500ms、窗口淘汰、静默后恢复、跨响应/子代理隔离、重复/空增量,以及侧边栏和详情共享门槛且不读取历史。原有测速夹具拆分为三个有效批次,保持原吞吐和平滑断言;打包冒烟的受控流改为超过 80 字节,以继续验证实时显示。
10
+
11
+ `npm run test:smoke` 完整通过,涵盖打包/隔离安装后的实时显示、完成后回归服务端吞吐、Responses 摘要突发/done-only/静默过期,以及既有侧边栏、详情、子代理、耗时、真实分叉副本和已完成 compaction/消息排序检查。2.1.2 不在既有验证版本列表中,脚本按设计发出兼容性警告后继续;本次通过不代表重跑了旧宿主,也未调整该列表。Node 22 的既有 OpenTUI 引擎警告保留。本地模拟提供商未调用付费模型,未修改现有 OpenCode 配置。产物:`/var/folders/rw/bmx6c8hd737brl55m0_ff_b80000gn/T/token-usage-smoke-vb4kHD`。
12
+
13
+ 本次未升级版本、提交、推送或发布。
14
+
3
15
  ## 2026-10-21 · 自动价格更新的分档测试修复(未发布)
4
16
 
5
17
  [价格工作流 39519970473](https://github.com/chenlongapps/opencode-token-usage/actions/runs/39519970473) 在 `npm test` 阶段失败,尚未升级版本或发布。models.dev 为 `alibaba/qwen-plus` 新增超过 256,000 incoming tokens 的分档;测试请求的 1,000,000 input tokens 正确选中推理费率 12,但旧断言固定读取 `prices[0]` 的基础费率 4,导致普通测试及其嵌套重定价测试同时失败。生产定价算法无需修改。
package/package.json CHANGED
@@ -1,15 +1,18 @@
1
1
  {
2
2
  "name": "@chenlongapps/opencode-token-usage",
3
- "version": "0.4.14",
4
- "description": "Session-tree token usage, live performance, context window and estimated cost for OpenCode 2",
3
+ "version": "0.4.16",
4
+ "description": "OpenCode 2 plugin for session-tree token usage, context window monitoring, estimated costs, and performance metrics (TPS, TTFT, run time).",
5
5
  "keywords": [
6
6
  "opencode",
7
7
  "opencode-plugin",
8
8
  "token-usage",
9
9
  "context-window",
10
+ "cost-tracking",
10
11
  "tps",
11
12
  "ttft",
12
- "cost"
13
+ "subagents",
14
+ "terminal-ui",
15
+ "llm"
13
16
  ],
14
17
  "homepage": "https://github.com/chenlongapps/opencode-token-usage#readme",
15
18
  "bugs": {