dsh-opencode-go 0.1.12 → 0.1.13
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 +20 -6
- package/README.md +20 -7
- package/THIRD_PARTY_NOTICES.md +2 -0
- package/docs/verification.md +38 -0
- package/lib/client.js +286 -53
- package/lib/index.js +120 -20
- package/lib/types/adapter.d.ts +3 -3
- package/lib/types/catalog.d.ts +10 -2
- package/lib/types/client/SessionCache.d.ts +6 -0
- package/lib/types/client/UsagePill.d.ts +2 -0
- package/lib/types/client/locales.d.ts +22 -0
- package/lib/types/client/section-controller.d.ts +2 -0
- package/lib/types/client/session-cache.d.ts +18 -0
- package/lib/types/config.d.ts +1 -1
- package/lib/types/models-contract.d.ts +11 -1
- package/package.json +23 -22
package/README.en.md
CHANGED
|
@@ -8,7 +8,7 @@ The plugin automatically adds the session headers required by OpenCode Go, reads
|
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
-
- **Session headers**: Every request includes the Harness User-Agent and `x-opencode-session`. A session keeps
|
|
11
|
+
- **Session headers**: Every request includes the Harness User-Agent and `x-opencode-session`. A session keeps a stable ID to support gateway routing and prompt-cache optimization; actual cache hits depend on the upstream service.
|
|
12
12
|
- **Streaming and history**: Supports streaming output, tool calls, and history replay through pi-ai.
|
|
13
13
|
- **Image input**: Supports models that advertise image capability in the catalog.
|
|
14
14
|
- **Model capacity overrides**: Override the context window and maximum output per model, with blank values inheriting the online catalog.
|
|
@@ -17,7 +17,9 @@ The plugin automatically adds the session headers required by OpenCode Go, reads
|
|
|
17
17
|
|
|
18
18
|
## Installation and usage
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Supports DSH `0.1.5-rc.1` and later, including alpha, rc, and stable releases. Compatibility will be maintained as new host versions are released.
|
|
21
|
+
|
|
22
|
+
Verified versions: `0.1.5-rc.1`, `0.1.5-rc.2`, `0.1.6-alpha.1`, `0.1.6-alpha.2`, `0.1.7-alpha.1`, `0.1.7-alpha.2`, `0.1.7-rc.1`, and `0.1.7-rc.2`.
|
|
21
23
|
|
|
22
24
|
### Install from DSH (recommended)
|
|
23
25
|
|
|
@@ -34,7 +36,7 @@ If your DSH version does not have an **Add plugin** entry, use the command-line
|
|
|
34
36
|
### Command-line installation (alternative)
|
|
35
37
|
|
|
36
38
|
```sh
|
|
37
|
-
dsh plugin --profile web add dsh-opencode-go@0.1.
|
|
39
|
+
dsh plugin --profile web add dsh-opencode-go@0.1.13
|
|
38
40
|
```
|
|
39
41
|
|
|
40
42
|
Start or restart `dsh web`, then:
|
|
@@ -48,7 +50,7 @@ Start or restart `dsh web`, then:
|
|
|
48
50
|
Install the plugin into the Headless profile:
|
|
49
51
|
|
|
50
52
|
```sh
|
|
51
|
-
dsh plugin --profile headless add dsh-opencode-go@0.1.
|
|
53
|
+
dsh plugin --profile headless add dsh-opencode-go@0.1.13
|
|
52
54
|
```
|
|
53
55
|
|
|
54
56
|
Save the following as `headless.patch.yml` to select a default model:
|
|
@@ -75,7 +77,7 @@ To build from source and install a local package:
|
|
|
75
77
|
```sh
|
|
76
78
|
npm ci --legacy-peer-deps
|
|
77
79
|
npm pack
|
|
78
|
-
dsh plugin --profile web add ./dsh-opencode-go-0.1.
|
|
80
|
+
dsh plugin --profile web add ./dsh-opencode-go-0.1.13.tgz
|
|
79
81
|
```
|
|
80
82
|
|
|
81
83
|
The development dependencies include real test packages from multiple DSH generations, so installation requires `--legacy-peer-deps`. For Headless, replace `web` with `headless`.
|
|
@@ -94,6 +96,10 @@ Restart `dsh web` and refresh the browser afterwards. For Headless, replace `web
|
|
|
94
96
|
|
|
95
97
|
Usage refreshes every minute. Temporary network or service errors retain the last reading for the same account, with a failure notice, timestamp, and reason; the usage panel offers an immediate retry. Initial and authentication failures do not show old usage. Catalog, metadata, and usage JSON requests retry a transient connection reset once within the original timeout budget; this cannot guarantee recovery while the network is failing.
|
|
96
98
|
|
|
99
|
+
The usage panel also shows the current session's cached input share, cache read/write tokens, total input tokens, and measured response count. The formula is `cacheReadTokens / (inputTokens + cacheReadTokens + cacheWriteTokens)`, weighted by tokens and excluding output tokens. Statistics are derived from the Host's loaded session history, can be reconstructed after session restore, and add no network requests. The panel subscribes only while open. Account usage failures do not affect these statistics.
|
|
100
|
+
|
|
101
|
+
Only settled Go responses with an identifiable route and valid usage are counted. Unsettled attempts and inherited fork responses are excluded; missing route/usage and incomplete history are indicated. Older Hosts without a session event feed continue to show account usage. A stable `x-opencode-session` supports routing affinity but does not establish a cache hit; actual cache reads are reported by the gateway.
|
|
102
|
+
|
|
97
103
|

|
|
98
104
|
|
|
99
105
|
## Interface language
|
|
@@ -134,11 +140,19 @@ Models that are present in the gateway and have an entry using Anthropic Message
|
|
|
134
140
|
|
|
135
141
|
A gateway model ID with no usable protocol or capability configuration is marked “Configuration missing” in Settings, with its switch off and disabled, and is kept out of the conversation picker, so one unconfigured model cannot block the rest of the list. Direct requests report the reason. Refresh after the upstream configuration is corrected. A model ID alone is not enough to reliably infer its transport; new protocols or protocol-specific exceptions may still require adapter changes.
|
|
136
142
|
|
|
143
|
+
If online configuration cannot be loaded, models without usable cached or built-in configuration are marked “Configuration unavailable”, with the configuration source error shown on the page. Check access to `https://models.dev/api.json` from the machine running DSH and review the error details, then refresh. When retrying a retained model list, its previous failure stays visible until a successful refresh clears it; configured models remain usable.
|
|
144
|
+
|
|
137
145
|
A reasoning-capable model without adjustable reasoning levels (for example, `union-alpha`) remains selectable and usable; it simply has no reasoning-strength control.
|
|
138
146
|
|
|
139
147
|
A model that does offer adjustable levels also declares a default effort (`high` when the model offers it, otherwise the highest level it offers) whenever its transport would answer an unset effort with an explicit disable (`deepseek`, `zai`, `qwen`, `qwen-chat-template`). DSH uses that default when no level has been chosen, so leaving the control unset still sends a reasoning level instead of turning thinking off. Transports that leave the choice to the provider declare no default and are unchanged, and an explicitly chosen level always wins.
|
|
140
148
|
|
|
141
|
-
If the online configuration is temporarily unavailable, the plugin prefers a configuration fetched successfully earlier in the process and falls back to pi-ai's built-in metadata. If a gateway catalog refresh fails, ongoing requests and Settings retain the last successful list.
|
|
149
|
+
If the online configuration is temporarily unavailable, the plugin prefers a configuration fetched successfully earlier in the process and falls back to pi-ai's built-in metadata. If a gateway catalog refresh fails, ongoing requests and Settings retain the last successful list. A failure from either source shows a warning, its cause, and the last successful checks of the model listing and model configuration separately. An initial failure without a cache never invents a model list.
|
|
150
|
+
|
|
151
|
+
`refreshMinutes` controls the cache lifetime after a successful refresh. Failed refreshes become eligible for retry on the next read after 5, 10, 20, 40, then at most 60 seconds; there is no background polling when nothing reads the catalog. Explicit Settings refreshes and previously unknown model requests bypass this delay. Cancelling model resolution or generation immediately ends that caller's catalog wait while other callers can continue sharing the same refresh.
|
|
152
|
+
|
|
153
|
+
Verified model configurations can serve generation immediately for five minutes after their cache lifetime expires, while triggering one shared background refresh. This window is measured from each source's last successful check; failed retries do not extend it. Beyond that window, requests wait for the next due refresh, retaining the existing fallback behavior if it fails. Initial loads, unknown models, and manual refreshes wait for results. Listing requests have a 10-second deadline; the larger model metadata download has its own 30-second deadline.
|
|
154
|
+
|
|
155
|
+
Continuation, retries, and restored sessions reuse the Host's durable session ID. Forks and subagent sessions use their own IDs, separate from the parent. Standalone requests without a session ID receive a fresh random identifier each time.
|
|
142
156
|
|
|
143
157
|
## Uninstall
|
|
144
158
|
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
## 功能说明
|
|
10
10
|
|
|
11
|
-
- **会话请求头**:每次请求包含 Harness User-Agent 和 `x-opencode-session
|
|
11
|
+
- **会话请求头**:每次请求包含 Harness User-Agent 和 `x-opencode-session`。同一会话保持稳定 ID,支持网关路由和提示词缓存优化;实际命中率取决于上游服务。
|
|
12
12
|
- **流式与历史**:支持流式输出、工具调用及历史回放,协议请求由 pi-ai 执行。
|
|
13
13
|
- **图片输入**:支持目录中声明图片能力的模型。
|
|
14
14
|
- **模型容量覆盖**:可按模型覆盖上下文窗口和最大输出,空值继承在线目录。
|
|
@@ -17,8 +17,9 @@
|
|
|
17
17
|
|
|
18
18
|
## 安装与使用
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
支持 DSH `0.1.5-rc.1` 及以上版本,包括 alpha、rc 和正式版,并持续跟随宿主版本更新维护兼容性。
|
|
21
|
+
|
|
22
|
+
已验证版本:`0.1.5-rc.1`、`0.1.5-rc.2`、`0.1.6-alpha.1`、`0.1.6-alpha.2`、`0.1.7-alpha.1`、`0.1.7-alpha.2`、`0.1.7-rc.1` 和 `0.1.7-rc.2`。
|
|
22
23
|
|
|
23
24
|
### 在 DSH 中安装(推荐)
|
|
24
25
|
|
|
@@ -35,7 +36,7 @@
|
|
|
35
36
|
### 命令行安装(备选)
|
|
36
37
|
|
|
37
38
|
```sh
|
|
38
|
-
dsh plugin --profile web add dsh-opencode-go@0.1.
|
|
39
|
+
dsh plugin --profile web add dsh-opencode-go@0.1.13
|
|
39
40
|
```
|
|
40
41
|
|
|
41
42
|
安装后启动或重启 `dsh web`,然后:
|
|
@@ -49,7 +50,7 @@ dsh plugin --profile web add dsh-opencode-go@0.1.12
|
|
|
49
50
|
安装到 Headless profile:
|
|
50
51
|
|
|
51
52
|
```sh
|
|
52
|
-
dsh plugin --profile headless add dsh-opencode-go@0.1.
|
|
53
|
+
dsh plugin --profile headless add dsh-opencode-go@0.1.13
|
|
53
54
|
```
|
|
54
55
|
|
|
55
56
|
将以下内容保存为 `headless.patch.yml`,选择默认模型:
|
|
@@ -76,7 +77,7 @@ dsh --profile headless --patch ./headless.patch.yml "你好"
|
|
|
76
77
|
```sh
|
|
77
78
|
npm ci --legacy-peer-deps
|
|
78
79
|
npm pack
|
|
79
|
-
dsh plugin --profile web add ./dsh-opencode-go-0.1.
|
|
80
|
+
dsh plugin --profile web add ./dsh-opencode-go-0.1.13.tgz
|
|
80
81
|
```
|
|
81
82
|
|
|
82
83
|
开发依赖包含多代 DSH 的真实测试包,安装时需要 `--legacy-peer-deps`。Headless 用户将 `web` 换成 `headless`。
|
|
@@ -95,6 +96,10 @@ dsh plugin --profile web update dsh-opencode-go --latest
|
|
|
95
96
|
|
|
96
97
|
用量每分钟刷新。临时网络或服务错误会保留同一账号的上次数据,并标明刷新失败、更新时间和错误原因;可在用量弹层中立即重试。首次获取失败或鉴权失败时不显示旧额度。模型目录、模型配置和用量的 JSON 请求遇到短暂连接重置时会在原有超时范围内额外重试一次;这不能保证故障中的网络恢复可用。
|
|
97
98
|
|
|
99
|
+
用量弹层还会显示当前会话的缓存读取比例、缓存读取/写入 tokens、总输入 tokens 和已统计响应数。计算公式为 `cacheReadTokens / (inputTokens + cacheReadTokens + cacheWriteTokens)`,按 tokens 加权,不包含输出 tokens。数据来自宿主已加载的会话历史,恢复会话后可重新计算,不增加网络请求;仅打开弹层时订阅更新。账号额度读取失败不影响这些统计。
|
|
100
|
+
|
|
101
|
+
统计只包含可确定路由且有有效用量的 Go 已结算响应,排除未结算请求和分叉继承的响应;缺少路由或用量的响应会注明未统计,历史未加载完整时也会提示。不支持会话事件接口的旧宿主继续显示账号额度。稳定的 `x-opencode-session` 只支持路由保持一致,不能证明缓存命中;实际读取量由网关报告。
|
|
102
|
+
|
|
98
103
|

|
|
99
104
|
|
|
100
105
|
## 界面语言
|
|
@@ -135,11 +140,19 @@ modelVisibility:
|
|
|
135
140
|
|
|
136
141
|
网关已公布 ID 但尚无有效协议/能力配置的模型会在设置页标注“配置缺失”,开关保持关闭且不可操作,不进入对话模型选择器,避免一个未配置的模型阻断整个列表;直接调用时会说明原因。配置补齐后,刷新列表即可使用。仅凭模型 ID 无法可靠推断调用方式。上游新增全新协议或协议特例时,仍可能需要适配。
|
|
137
142
|
|
|
143
|
+
如果在线配置获取失败,没有可用缓存或内置配置的模型会标注“配置暂不可用”,页面会显示配置源错误。请检查运行 DSH 的设备能否访问 `https://models.dev/api.json`,并查看具体错误后刷新重试。已有模型列表在重试期间保留上次的失败提示,成功后自动清除;已配置的模型继续可用。
|
|
144
|
+
|
|
138
145
|
模型具有推理能力但没有可调节的推理档位时(如 `union-alpha`),仍可正常选择和使用,只是不显示推理强度选项。
|
|
139
146
|
|
|
140
147
|
提供可调节档位的模型,如果其传输协议在未选择档位时会显式关闭思考(`deepseek`、`zai`、`qwen`、`qwen-chat-template`),还会声明一个默认档位(模型支持 `high` 时用 `high`,否则用它提供的最高档位)。用户未选择档位时 DSH 使用该默认值,因此留空也会带上推理档位,而不是关闭思考。由服务商自行决定的协议不声明默认值,行为不变;显式选择的档位始终优先。
|
|
141
148
|
|
|
142
|
-
在线配置暂时不可达时,优先复用本次运行中成功获取的配置,以 pi-ai
|
|
149
|
+
在线配置暂时不可达时,优先复用本次运行中成功获取的配置,以 pi-ai 内置配置作为备用。网关目录刷新失败时,已有请求和设置页均保留上次成功获取的列表。任一来源刷新失败,设置页都会显示警告、失败原因,以及模型名单和模型配置各自上次成功检查的时间。首次读取就失败且没有缓存时,不会凭空生成模型列表。
|
|
150
|
+
|
|
151
|
+
`refreshMinutes` 控制成功刷新后的目录缓存时长。刷新失败后,下一次读取会按 5、10、20、40、60 秒的退避间隔尝试恢复,最长等待间隔为 60 秒;没有读取时不会后台轮询。设置页主动刷新和未知模型的即时发现不受这个间隔限制。取消模型解析或生成时,会立即结束当前调用的目录等待,其他调用仍可继续使用同一次共享刷新。
|
|
152
|
+
|
|
153
|
+
已验证的模型配置在缓存到期后的 5 分钟内可直接用于生成,同时触发一次共享后台刷新。这个窗口按两种来源各自上次成功检查的时间计算,失败重试不会延长它;超过窗口后,请求等待下一次到期刷新,刷新仍失败时保留已有回退行为。首次加载、未知模型和手动刷新会等待结果。模型名单请求限时 10 秒,体积更大的模型配置下载单独限时 30 秒。
|
|
154
|
+
|
|
155
|
+
同一会话继续、重试以及恢复后的请求沿用宿主保存的会话 ID。分叉和子会话使用各自的 ID,不复用父会话标识;没有会话 ID 的独立请求每次生成随机标识。
|
|
143
156
|
|
|
144
157
|
## 卸载
|
|
145
158
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
# Third-party notices
|
|
2
2
|
|
|
3
3
|
The adapter, settings UI, and `src/conversion/{context,stream,replay}.ts` derive from DeepSeek Harness, copyright (c) 2026 DeepSeek, under the MIT license included in LICENSE. The conversion modules are maintained in this package because the published DSH pi-ai package does not export its conversion helpers. Wire protocol implementations remain supplied by `@earendil-works/pi-ai`.
|
|
4
|
+
|
|
5
|
+
The GitHub icon in the settings footer comes from Simple Icons, distributed under CC0 1.0 Universal.
|
package/docs/verification.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Verification
|
|
2
2
|
|
|
3
|
+
## Issue #14: distinguish unavailable metadata from missing model configuration (2026-09-26)
|
|
4
|
+
|
|
5
|
+
The existing source diagnostics now drive a specific Settings warning when model configuration fails while the gateway listing succeeds, including an empty successful listing. Unconfigured models show “Configuration unavailable” during a metadata-source failure and explain how to check connectivity from the machine running DSH. A retained model list keeps its warning and source details visible while retrying. Successful metadata recovery clears the warning; models still absent from usable metadata return to “Configuration missing”, and models with newly usable configuration become selectable.
|
|
6
|
+
|
|
7
|
+
Two controller/component regressions failed before the UI changes and pass afterward. Four additional cases exercise the real Host RPC with cold-start HTTP 503, timeout, invalid JSON, and invalid configuration-document responses. They assert source-specific failures, continued availability of built-in models, and successful recovery of DeepSeek V4.1 Flash without restarting or changing credentials. Existing cached-data and legacy-response checks remain in place.
|
|
8
|
+
|
|
9
|
+
`npm test` passed the Host/Client type checks, production build, and **326 tests in 24 files**, including the existing host compatibility and distributed client fixtures. The installed upstream UI packages still emit their existing missing-source-map warnings. This verifies local fixture failures and recovery, not the issue reporter's network environment.
|
|
10
|
+
|
|
11
|
+
## Minimum-host compatibility policy (2026-09-25)
|
|
12
|
+
|
|
13
|
+
The compatibility policy is DSH `0.1.5-rc.1` and later, including alpha, rc, and stable releases, with continued maintenance as the host evolves. `engines.dsh` and all 19 DSH peers now use `>=0.1.5-rc.1`; the Cordis peer uses `>=4.0.2`. The eight existing host fixtures are verified versions, not an exhaustive allowlist. This supersedes the release-specific declaration limits recorded below.
|
|
14
|
+
|
|
15
|
+
DSH's published bundle gate and the market compare host ranges with `includePrerelease: true`. Declaration tests now follow that policy, rejecting hosts below the minimum and accepting later prereleases and stable releases. These checks do not use npm's default peer-range semantics. The published `0.1.7-rc.2` gate also accepted 16 current/future version strings and rejected three below the minimum; future strings check admission policy only. `npm test -- tests/package-compatibility.spec.ts tests/host-compatibility.spec.ts` passed the Host/Client build checks and all **31 tests**, including activation and streaming across the eight existing hosts and Web/Headless bundle admission on rc.1 and rc.2.
|
|
16
|
+
|
|
3
17
|
## Issue #9: usage progress bar painting (plugin 0.1.12, 2026-09-24)
|
|
4
18
|
|
|
5
19
|
The progress elements retained `appearance: auto`, preventing the custom WebKit fill from taking effect ([MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/::-webkit-progress-value)). The fix sets `appearance: none`, removes the native border, and gives the progress element the rounded track background. The WebKit track stays transparent to avoid applying the translucent track color twice; the existing WebKit and Firefox fill rules remain green. Percentage values and accessible progress semantics are unchanged.
|
|
@@ -284,3 +298,27 @@ Read-only JSON requests now retry connection reset/socket closure/temporary DNS
|
|
|
284
298
|
Usage failures now carry safe Host diagnostics through the Remote error contract. The UI retains a prior reading only when its opaque account/endpoint source matches the failed request, labels it as old data, and shows its original timestamp and a manual retry. Authentication failures and different/missing source identities clear old data. A source is a Host-generated random identifier, never a credential or credential hash. Polling and manual retries coalesce. These changes improve recovery and diagnostics; they cannot guarantee availability during a network outage.
|
|
285
299
|
|
|
286
300
|
Validation: 289 tests in 22 files and both Host/Client type checks passed, including the published-host compatibility fixtures and the real usage RPC codec.
|
|
301
|
+
|
|
302
|
+
## Catalog failure recovery, cancellation, and source diagnostics (2026-09-25)
|
|
303
|
+
|
|
304
|
+
The catalog previously cached an initial failed listing for the normal successful refresh lifetime (60 minutes by default), ignored caller cancellation during model discovery, and reported fresh Settings data when the gateway listing succeeded but models.dev failed. Five new regressions reproduced these behaviors before the fix: two retry/recovery cases, one metadata diagnostic case, and independent cancellation of model resolution and generation while a second caller shared the pending refresh.
|
|
305
|
+
|
|
306
|
+
Failed catalog refreshes now use demand-driven backoff of 5, 10, 20, 40, then at most 60 seconds. Successful refreshes reset the failure count and restore `refreshMinutes`. Manual discovery bypasses backoff; existing immediate discovery for unknown models is preserved. Repeated failures retain usable models without resurrecting retired entries. No timer polls in the absence of catalog reads.
|
|
307
|
+
|
|
308
|
+
Cancellation ends the individual model-resolution or generation wait before metadata completes. Shared HTTP reads retain their own bounded timeout so other callers still complete and populate the cache. A generation cancelled before discovery starts sends no catalog or inference request. The regression holds the metadata response pending, observes cancellation, then releases it and verifies that the other caller succeeds using the same single listing fetch.
|
|
309
|
+
|
|
310
|
+
Settings RPC responses now optionally carry separate listing/configuration diagnostics and timestamps of their last successful checks, including 304 revalidation. A metadata-only failure marks the catalog stale, retains usable configuration, and shows the failed source and its previous timestamp. The controller/component integration test verifies the warning, enabled model switches, clearing source status after a failed Host RPC, and recovery. Older responses without source fields remain accepted. Malformed source timestamps are rejected by the codec.
|
|
311
|
+
|
|
312
|
+
Validation: `npm test` rebuilt the Host and Client (including both TypeScript checks) and passed **309 tests in 22 files**. The existing missing-source-map warnings from the published Harness UI dependencies remain. `git diff --check` passed. These checks use local fixtures and mock HTTP gateways; no paid inference, installed-profile update, or package publication was performed.
|
|
313
|
+
|
|
314
|
+
## Background catalog refresh, session cache diagnostics, and session identity (2026-09-26)
|
|
315
|
+
|
|
316
|
+
Known, verified models can now use the cached configuration for five minutes after its normal lifetime while one shared refresh runs. A held metadata response regression confirms that generation lookup returns the known configuration before the response arrives, concurrent lookups coalesce, and manual/unknown-model reads still wait. Once the refresh completes, retired models are no longer routed from the old snapshot. Another regression checks that failed attempts do not extend the grace window. The model listing retains its 10-second deadline; metadata downloads have a separate 30-second deadline. The nonblocking lookup and independent-deadline regressions failed before the change and passed afterward.
|
|
317
|
+
|
|
318
|
+
The usage panel derives session cache statistics from the Host's existing loaded event window, with no new RPC or persistent counters. Cached input share is `cacheReadTokens / (inputTokens + cacheReadTokens + cacheWriteTokens)`; output tokens do not contribute. Durable Go responses are counted once by sequence. Transient chunks, attempts without a settled message, other providers, malformed usage, and inherited fork responses are excluded. Missing attribution/accounting and incomplete history are indicated. A zero denominator shows no ratio. Statistics can be reconstructed from restored history and remain available when account-usage reads fail. Hosts without the optional event feed retain the existing account panel.
|
|
319
|
+
|
|
320
|
+
The derived store preserves its snapshot for transient-only updates, recomputes on settlement/history replacement, and subscribes only while the details panel is open. Unit/component tests cover token weighting, cache writes, omitted cache counts, malformed and missing usage, duplicate events, fork boundaries, serialized restoration, history replacement, account failure, switching sessions, and subscription cleanup. Session statistics describe the loaded, settled responses, not all billable gateway attempts or an account-wide cache metric.
|
|
321
|
+
|
|
322
|
+
Lifecycle tests use the real `@deepseek-ai/dsh-session` 0.1.6-alpha.1 Session/SessionStore and a local HTTP gateway. Continuation, a 503 followed by a caller retry, serialized Host header/log restoration, and adapter recreation retain the same `x-opencode-session`. Real forks and subagent-marked child sessions have distinct identities during concurrent calls and keep their own IDs after restoration. These are persistence-boundary tests, not a full installed agent-loop process restart. Existing protocol and published-host compatibility fixtures remain part of the full suite.
|
|
323
|
+
|
|
324
|
+
Validation: `npm test` rebuilt both artifacts and passed **320 tests in 24 files**, including both TypeScript checks. An isolated browser fixture loaded the actual built `lib/client.js` usage slot with local Host-service data. Chinese and English panels displayed the expected 70% ratio and 7,000 / 10,000 input-token counts; a 320px viewport had no horizontal overflow, and account errors did not hide session statistics. Escape closed the dialog; captured browser errors were empty. This validates the shipped client artifact with fixture services, not a live installed Host or upstream cache-hit rate. No paid inference or installed-profile update was required.
|