dsh-opencode-go 0.1.10 → 0.1.12
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 +35 -8
- package/README.md +35 -8
- package/docs/verification.md +76 -2
- package/lib/client.js +258 -114
- package/lib/index.js +220 -70
- package/lib/types/catalog.d.ts +5 -3
- package/lib/types/client/ModelEditor.d.ts +6 -2
- package/lib/types/client/Section.d.ts +2 -0
- package/lib/types/client/UsagePill.d.ts +1 -0
- package/lib/types/client/locales.d.ts +14 -2
- package/lib/types/client/section-controller.d.ts +16 -11
- package/lib/types/config.d.ts +5 -5
- package/lib/types/json-response.d.ts +10 -1
- package/lib/types/models-contract.d.ts +12 -1
- package/lib/types/models.d.ts +3 -2
- package/lib/types/usage-contract.d.ts +9 -0
- package/lib/types/usage.d.ts +1 -0
- package/package.json +21 -21
package/README.en.md
CHANGED
|
@@ -12,11 +12,12 @@ The plugin automatically adds the session headers required by OpenCode Go, reads
|
|
|
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.
|
|
15
|
+
- **Per-model switches**: Control which models appear in conversations, with changes applied immediately. Ordinary models default to on and deprecated models default to off; any model can be enabled individually.
|
|
15
16
|
- **Prompt and caching**: The plugin does not add hidden system prompts; the session ID is used for gateway routing.
|
|
16
17
|
|
|
17
18
|
## Installation and usage
|
|
18
19
|
|
|
19
|
-
Supported DSH 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`, and `0.1.7-
|
|
20
|
+
Supported DSH 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`.
|
|
20
21
|
|
|
21
22
|
### Install from DSH (recommended)
|
|
22
23
|
|
|
@@ -33,7 +34,7 @@ If your DSH version does not have an **Add plugin** entry, use the command-line
|
|
|
33
34
|
### Command-line installation (alternative)
|
|
34
35
|
|
|
35
36
|
```sh
|
|
36
|
-
dsh plugin --profile web add dsh-opencode-go@0.1.
|
|
37
|
+
dsh plugin --profile web add dsh-opencode-go@0.1.12
|
|
37
38
|
```
|
|
38
39
|
|
|
39
40
|
Start or restart `dsh web`, then:
|
|
@@ -47,7 +48,7 @@ Start or restart `dsh web`, then:
|
|
|
47
48
|
Install the plugin into the Headless profile:
|
|
48
49
|
|
|
49
50
|
```sh
|
|
50
|
-
dsh plugin --profile headless add dsh-opencode-go@0.1.
|
|
51
|
+
dsh plugin --profile headless add dsh-opencode-go@0.1.12
|
|
51
52
|
```
|
|
52
53
|
|
|
53
54
|
Save the following as `headless.patch.yml` to select a default model:
|
|
@@ -74,7 +75,7 @@ To build from source and install a local package:
|
|
|
74
75
|
```sh
|
|
75
76
|
npm ci --legacy-peer-deps
|
|
76
77
|
npm pack
|
|
77
|
-
dsh plugin --profile web add ./dsh-opencode-go-0.1.
|
|
78
|
+
dsh plugin --profile web add ./dsh-opencode-go-0.1.12.tgz
|
|
78
79
|
```
|
|
79
80
|
|
|
80
81
|
The development dependencies include real test packages from multiple DSH generations, so installation requires `--legacy-peer-deps`. For Headless, replace `web` with `headless`.
|
|
@@ -91,8 +92,32 @@ Restart `dsh web` and refresh the browser afterwards. For Headless, replace `web
|
|
|
91
92
|
|
|
92
93
|
## Subscription usage display
|
|
93
94
|
|
|
95
|
+
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
|
+
|
|
94
97
|

|
|
95
98
|
|
|
99
|
+
## Interface language
|
|
100
|
+
|
|
101
|
+
The plugin follows Harness and supplies Chinese and English copy without storing a separate language preference. With no explicit choice, the Web client matches the browser's preferred languages (usually inherited from the system); native shells with a system-language bridge supply their operating-system languages. English is used when no supported language matches.
|
|
102
|
+
|
|
103
|
+
A language explicitly selected in Harness takes precedence and updates the plugin immediately without discarding form drafts. Model names and IDs stay unchanged; usage dates and capacity numbers follow the active interface language. Automatic language detection runs at startup: reload the Web page after changing browser languages, or restart desktop Harness after changing system languages.
|
|
104
|
+
|
|
105
|
+
## Model switches
|
|
106
|
+
|
|
107
|
+
In **Settings → OpenCode Go**, the switch beside each model controls whether it appears in conversation model pickers. Switch changes are saved immediately; capacity and API key edits still require **Save**. Ordinary models default to on and deprecated models default to off. You can enable a deprecated model individually or disable an ordinary model. Newly discovered models follow the same defaults unless configured individually.
|
|
108
|
+
|
|
109
|
+
For manual configuration, add `modelVisibility` under the plugin's `config`, replacing the example placeholders with actual model IDs:
|
|
110
|
+
|
|
111
|
+
```yaml
|
|
112
|
+
modelVisibility:
|
|
113
|
+
your-model-id: false
|
|
114
|
+
your-deprecated-model-id: true
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Only the listed IDs receive explicit overrides. Switches affect model pickers only: existing conversations can still call hidden models served by the gateway, and Settings retains the complete model list.
|
|
118
|
+
|
|
119
|
+
The older `showDeprecatedModels` and `visibleModelIds` fields no longer control visibility. Use the individual switches or `modelVisibility`; retaining old fields does not prevent the plugin from loading.
|
|
120
|
+
|
|
96
121
|
## FAQ
|
|
97
122
|
|
|
98
123
|
### The `opencode-go` route is already in use
|
|
@@ -101,17 +126,19 @@ Only one adapter in a profile can provide the `opencode-go` route. If another pl
|
|
|
101
126
|
|
|
102
127
|
### An expected model is missing
|
|
103
128
|
|
|
104
|
-
|
|
129
|
+
Check that the model's switch is on in **Settings → OpenCode Go**. Deprecated models default to off; turning on an individual model makes it available in conversation pickers without another global option.
|
|
130
|
+
|
|
131
|
+
Confirm that the plugin is enabled and an API key is configured, then refresh the model list in Settings. Settings reads and refreshes request the gateway's `/models` endpoint and synchronize the OpenCode Go configuration from [models.dev](https://models.dev/api.json). Conversation pickers respect the catalog cache lifetime, so model switch changes do not force another gateway request. Protocol support, context length, output limit, and image capability come from the online configuration, so new models do not require a release of this plugin or pi-ai.
|
|
105
132
|
|
|
106
|
-
Models that are present in the gateway and have an entry using Anthropic Messages, OpenAI Chat Completions, or OpenAI Responses
|
|
133
|
+
Models that are present in the gateway and have an entry using Anthropic Messages, OpenAI Chat Completions, or OpenAI Responses are discovered on the next Settings refresh or after the catalog cache expires. A Settings refresh bypasses the cache and notifies open conversation pickers to use the same updated catalog; a direct request for a previously unseen model also triggers an immediate resynchronization. The Settings page shows the complete discovery result.
|
|
107
134
|
|
|
108
|
-
A gateway model ID with no usable protocol or capability configuration is
|
|
135
|
+
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.
|
|
109
136
|
|
|
110
137
|
A reasoning-capable model without adjustable reasoning levels (for example, `union-alpha`) remains selectable and usable; it simply has no reasoning-strength control.
|
|
111
138
|
|
|
112
139
|
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.
|
|
113
140
|
|
|
114
|
-
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
|
|
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. Settings also shows a warning and the failure cause, identifying the displayed list as cached. A first read that fails without a cache shows an error and does not invent a model list. `refreshMinutes` controls the catalog cache lifetime for ongoing model requests and conversation pickers; explicit Settings refreshes and previously unknown model requests still fetch immediately.
|
|
115
142
|
|
|
116
143
|
## Uninstall
|
|
117
144
|
|
package/README.md
CHANGED
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
- **流式与历史**:支持流式输出、工具调用及历史回放,协议请求由 pi-ai 执行。
|
|
13
13
|
- **图片输入**:支持目录中声明图片能力的模型。
|
|
14
14
|
- **模型容量覆盖**:可按模型覆盖上下文窗口和最大输出,空值继承在线目录。
|
|
15
|
+
- **逐模型开关**:每个模型独立控制会话中的显示状态,修改立即生效;普通模型默认开启,过时模型默认关闭,也可单独开启。
|
|
15
16
|
- **提示与缓存**:插件不增加隐藏系统提示;会话 ID 用于网关路由。
|
|
16
17
|
|
|
17
18
|
## 安装与使用
|
|
18
19
|
|
|
19
20
|
兼容清单:
|
|
20
|
-
`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-
|
|
21
|
+
`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`
|
|
21
22
|
|
|
22
23
|
### 在 DSH 中安装(推荐)
|
|
23
24
|
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
### 命令行安装(备选)
|
|
35
36
|
|
|
36
37
|
```sh
|
|
37
|
-
dsh plugin --profile web add dsh-opencode-go@0.1.
|
|
38
|
+
dsh plugin --profile web add dsh-opencode-go@0.1.12
|
|
38
39
|
```
|
|
39
40
|
|
|
40
41
|
安装后启动或重启 `dsh web`,然后:
|
|
@@ -48,7 +49,7 @@ dsh plugin --profile web add dsh-opencode-go@0.1.10
|
|
|
48
49
|
安装到 Headless profile:
|
|
49
50
|
|
|
50
51
|
```sh
|
|
51
|
-
dsh plugin --profile headless add dsh-opencode-go@0.1.
|
|
52
|
+
dsh plugin --profile headless add dsh-opencode-go@0.1.12
|
|
52
53
|
```
|
|
53
54
|
|
|
54
55
|
将以下内容保存为 `headless.patch.yml`,选择默认模型:
|
|
@@ -75,7 +76,7 @@ dsh --profile headless --patch ./headless.patch.yml "你好"
|
|
|
75
76
|
```sh
|
|
76
77
|
npm ci --legacy-peer-deps
|
|
77
78
|
npm pack
|
|
78
|
-
dsh plugin --profile web add ./dsh-opencode-go-0.1.
|
|
79
|
+
dsh plugin --profile web add ./dsh-opencode-go-0.1.12.tgz
|
|
79
80
|
```
|
|
80
81
|
|
|
81
82
|
开发依赖包含多代 DSH 的真实测试包,安装时需要 `--legacy-peer-deps`。Headless 用户将 `web` 换成 `headless`。
|
|
@@ -92,8 +93,32 @@ dsh plugin --profile web update dsh-opencode-go --latest
|
|
|
92
93
|
|
|
93
94
|
## 订阅用量显示
|
|
94
95
|
|
|
96
|
+
用量每分钟刷新。临时网络或服务错误会保留同一账号的上次数据,并标明刷新失败、更新时间和错误原因;可在用量弹层中立即重试。首次获取失败或鉴权失败时不显示旧额度。模型目录、模型配置和用量的 JSON 请求遇到短暂连接重置时会在原有超时范围内额外重试一次;这不能保证故障中的网络恢复可用。
|
|
97
|
+
|
|
95
98
|

|
|
96
99
|
|
|
100
|
+
## 界面语言
|
|
101
|
+
|
|
102
|
+
插件跟随 Harness 的界面语言,提供中文和英文文案,不另存一套语言设置。未手动指定语言时,Web 版按浏览器语言列表匹配中英文(浏览器通常跟随系统);支持系统语言桥接的桌面版由宿主提供系统语言。没有匹配的语言时使用英文。
|
|
103
|
+
|
|
104
|
+
在 Harness 中手动选择的语言优先,切换后插件即时更新,保留未保存的表单内容。模型名称和 ID 保留原名;用量日期和容量数字按当前界面语言格式化。自动语言在启动时识别:Web 版更改浏览器语言后需刷新页面,桌面版更改系统语言后需重启 Harness。
|
|
105
|
+
|
|
106
|
+
## 模型开关
|
|
107
|
+
|
|
108
|
+
在 **设置 → OpenCode Go** 中,每个模型右侧的开关决定它是否出现在会话模型选择器中。开关立即保存,无需再点“保存”;容量和 API Key 的修改仍需保存。普通模型默认开启,过时模型默认关闭。你可以单独开启任意过时模型,也可以关闭普通模型。新出现且未单独配置的模型同样按此规则处理。
|
|
109
|
+
|
|
110
|
+
手动配置时,在插件的 `config` 下添加 `modelVisibility`,使用真实模型 ID 替换示例中的占位符:
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
modelVisibility:
|
|
114
|
+
your-model-id: false
|
|
115
|
+
your-deprecated-model-id: true
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
只有列出的 ID 被显式覆盖。开关只影响模型选择器;已有会话仍可调用网关提供的隐藏模型,设置页也保留完整模型列表。
|
|
119
|
+
|
|
120
|
+
旧配置中的 `showDeprecatedModels` 和 `visibleModelIds` 不再控制显示状态。请使用逐模型开关或 `modelVisibility`;旧字段可以保留,不会妨碍插件加载。
|
|
121
|
+
|
|
97
122
|
## 常见问题
|
|
98
123
|
|
|
99
124
|
### 提示 `opencode-go` 路由已被占用
|
|
@@ -102,17 +127,19 @@ dsh plugin --profile web update dsh-opencode-go --latest
|
|
|
102
127
|
|
|
103
128
|
### 没有出现预期的模型
|
|
104
129
|
|
|
105
|
-
|
|
130
|
+
先在 **设置 → OpenCode Go** 检查该模型的开关是否开启。过时模型默认关闭,单独打开它的开关后即可出现在会话模型选择器中,无需开启其他全局选项。
|
|
131
|
+
|
|
132
|
+
先确认插件已启用且 API Key 已配置,再刷新设置页中的模型列表。设置页读取或刷新列表时会请求网关 `/models`,并同步 [models.dev 的 OpenCode Go 配置](https://models.dev/api.json)。会话模型选择器遵守目录缓存时长,切换模型开关不会强制重新请求网关。模型的协议、上下文长度、输出上限和图片能力来自在线配置,新模型无需等待本插件或 pi-ai 发布新版本。
|
|
106
133
|
|
|
107
|
-
网关和在线配置已收录、且使用 Anthropic Messages、OpenAI Chat Completions 或 OpenAI Responses
|
|
134
|
+
网关和在线配置已收录、且使用 Anthropic Messages、OpenAI Chat Completions 或 OpenAI Responses 协议的新模型,在下次设置页刷新或目录缓存到期后即可被发现。设置页刷新会绕过已有缓存,并通知已打开的会话模型选择器使用同一份新目录;直接请求尚未缓存的新模型也会立即重新同步。设置页显示完整模型列表。
|
|
108
135
|
|
|
109
|
-
网关已公布 ID
|
|
136
|
+
网关已公布 ID 但尚无有效协议/能力配置的模型会在设置页标注“配置缺失”,开关保持关闭且不可操作,不进入对话模型选择器,避免一个未配置的模型阻断整个列表;直接调用时会说明原因。配置补齐后,刷新列表即可使用。仅凭模型 ID 无法可靠推断调用方式。上游新增全新协议或协议特例时,仍可能需要适配。
|
|
110
137
|
|
|
111
138
|
模型具有推理能力但没有可调节的推理档位时(如 `union-alpha`),仍可正常选择和使用,只是不显示推理强度选项。
|
|
112
139
|
|
|
113
140
|
提供可调节档位的模型,如果其传输协议在未选择档位时会显式关闭思考(`deepseek`、`zai`、`qwen`、`qwen-chat-template`),还会声明一个默认档位(模型支持 `high` 时用 `high`,否则用它提供的最高档位)。用户未选择档位时 DSH 使用该默认值,因此留空也会带上推理档位,而不是关闭思考。由服务商自行决定的协议不声明默认值,行为不变;显式选择的档位始终优先。
|
|
114
141
|
|
|
115
|
-
在线配置暂时不可达时,优先复用本次运行中成功获取的配置,以 pi-ai
|
|
142
|
+
在线配置暂时不可达时,优先复用本次运行中成功获取的配置,以 pi-ai 内置配置作为备用。网关目录刷新失败时,已有请求和设置页均保留上次成功获取的列表;设置页同时显示警告和失败原因,说明当前展示的是缓存结果。首次读取就失败且没有缓存时,只显示错误,不会凭空生成模型列表。`refreshMinutes` 控制已有模型请求和会话选择器的目录缓存时长,不阻止设置页主动刷新或未知模型的即时发现。
|
|
116
143
|
|
|
117
144
|
## 卸载
|
|
118
145
|
|
package/docs/verification.md
CHANGED
|
@@ -1,5 +1,55 @@
|
|
|
1
1
|
# Verification
|
|
2
2
|
|
|
3
|
+
## Issue #9: usage progress bar painting (plugin 0.1.12, 2026-09-24)
|
|
4
|
+
|
|
5
|
+
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.
|
|
6
|
+
|
|
7
|
+
An isolated browser fixture mounted the actual `lib/client.js` usage slot with local usage data. On macOS / Chrome 153, the original artifact drew a thin native line with a faint fill rather than the intended 5px custom bar; this is not a reproduction of the reporter's completely gray Windows rendering. A screenshot pixel check failed before the fix (zero pixels of the intended fill color) and passed afterward, measuring 59, 101, and 84 filled pixels for 24%, 41%, and 34% of a 246px track, with the expected fill height.
|
|
8
|
+
|
|
9
|
+
Browser checks also passed for light/dark themes, 0%, 50%, 100%, and a 120% usage reading clamped to a full bar, including a 320px viewport without horizontal overflow. The dialog opened and closed with Escape, and no browser errors were recorded. These checks used the production client artifact with fixture host services, not a full DSH installation; Windows, Firefox, and Safari were not exercised. The complete `npm test` run passed the Host/Client type checks, production build, and **295 tests in 22 files**.
|
|
10
|
+
|
|
11
|
+
## Issue #8: DSH 0.1.7-rc.1 / rc.2 bundle admission (plugin 0.1.12, 2026-09-24)
|
|
12
|
+
|
|
13
|
+
The published `@deepseek-ai/dsh-app-boot@0.1.7-rc.1` reproduced the reported `skipping profile bundle` diagnostic with the 0.1.11 manifest: all 19 DSH peer ranges exclude rc.1, so `loadProfileDirectory` removes the bundle before the provider or settings can load. The engine declaration also excluded rc.1. The subsequently published [rc.2](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.7-rc.2) still rejects a manifest that only declares through rc.1. Adding both exact versions to the engine and DSH peer ranges fixes admission without profile version exemptions; unverified rc.3 and 0.1.7 stable remain outside the declared range.
|
|
14
|
+
|
|
15
|
+
`node --expose-internals tests/fixtures/bundle-compatibility.mjs v017-rc1` and the corresponding `v017-rc2` command failed before their manifest changes and pass afterward. They use the real startup gates against temporary Web and Headless profiles, asserting that the bundle and provider insertion survive. The rc.2 gate now returns skipped bundles for later reporting; the fixture also checks that this list is empty. Independently pinned rc.1 and rc.2 workspaces extend the existing built Host/Client tests for provider activation, catalog and usage RPC, streaming, image resizing and tool results, default/explicit reasoning, live profile settings, and client settings registration/rendering. The rc.2 UI primitives additionally require the host's new `dsh-util-code-language` module, which is supplied by the rc.2 test workspace.
|
|
16
|
+
|
|
17
|
+
`npm test` passed Host/Client type checks, the production build, and **301 tests in 22 files**, covering all eight supported host fixtures on macOS / Node.js 24.14.1. The existing upstream UI source-map warnings remain. Tests use local gateways and fake credentials; they do not exercise a full running DSH Web/Desktop shell or make paid model requests.
|
|
18
|
+
|
|
19
|
+
## Individual model switches and cached Settings discovery (2026-09-23)
|
|
20
|
+
|
|
21
|
+
`modelVisibility` stores explicit booleans by model ID. An absent override enables an ordinary model and disables a model marked deprecated. A `true` override can enable a deprecated model without a second global condition; `false` can hide an ordinary model. The Host and Client share `isModelEnabled`, including own-property checks for IDs that match JavaScript prototype keys. Older `showDeprecatedModels` and `visibleModelIds` fields remain loadable as unknown configuration but no longer impose a visibility condition.
|
|
22
|
+
|
|
23
|
+
Each model has one switch that writes immediately and refreshes conversation pickers. Capacity and credential edits retain Save/Discard behavior. Hidden models stay available in Settings and existing conversations can continue requesting models the gateway serves. Newly discovered models follow their lifecycle default unless an override already exists for their ID.
|
|
24
|
+
|
|
25
|
+
Picker reads now reuse the catalog for `refreshMinutes`, so visibility changes do not trigger another network refresh while that snapshot is cached. `GoModelsService.read()` still forces discovery, then notifies any registered picker on both successful and failed refreshes. The picker consumes the same committed or retained snapshot; explicit Settings refreshes discover new and removed models, and direct requests for unknown IDs retain their immediate discovery behavior.
|
|
26
|
+
|
|
27
|
+
Settings discovery now returns `GoModelCatalog` with `models`, `stale`, and an optional safe error message. If a refresh fails after a successful listing, Settings keeps the cached entries and shows a warning with the failure cause. Client transport failures also retain the last successful view. A failure without any cached listing shows an error; a successful empty listing stays empty. Explicit generic discovery retains its strict failure behavior.
|
|
28
|
+
|
|
29
|
+
The final `npm test` run passed Host/Client type checks, the production build, and **246 tests in 20 files**. Coverage includes lifecycle defaults, individual overrides, returning and newly discovered models, non-boolean configuration rejection, unchanged existing-model requests, TTL expiry, and real Settings RPC notifications without redundant picker requests, including failed refreshes. The 0.1.7 profile fixtures verify the new switches and retained legacy fields without remounting; client tests verify immediate switches and cached-list warnings. The earlier browser result below predates this UI revision and does not establish its visual behavior in a live DSH installation.
|
|
30
|
+
|
|
31
|
+
## Issue #7: transport verification, usage, diagnostics and model selection (2026-09-23)
|
|
32
|
+
|
|
33
|
+
An isolated local HTTPS/HTTP2 reproduction used the reporter's exact Node 24.19.0 (bundled Undici 7.29.0) and npm Undici 8.11.0 global dispatcher. The server supplied correctly labeled compressed JSON. HTTP/1.1 worked; HTTP/2 lost all response headers and native `response.json()` failed on compressed bytes. The same failure occurred on Node 24.14.1 (bundled Undici 7.24.4). These tests ran on macOS, not WSL2, and used local fixtures without real credentials or paid requests.
|
|
34
|
+
|
|
35
|
+
Undici 8's HTTP/2 path passes a header object through the legacy dispatcher bridge where the older fetch expects an alternating header array ([request.js](https://github.com/nodejs/undici/blob/v8.11.0/lib/core/request.js#L328), [dispatcher1-wrapper.js](https://github.com/nodejs/undici/blob/v8.11.0/lib/dispatcher/dispatcher1-wrapper.js#L24)). The 0.1.10 reader was verified to recover this payload, but the final implementation adopts the issue reporter's simpler recommendation: `/models`, models.dev and `/usage` explicitly request `accept-encoding: identity`. The manual Brotli/gzip/deflate guessing loop has been removed. The reader only bounds delivered bytes and parses JSON; normally labeled compressed responses remain Fetch's responsibility. Requests keep using the host's global fetch and dispatcher.
|
|
36
|
+
|
|
37
|
+
The final identity implementation passed actual catalog and usage RPC reads through one unchanged Undici 8.11.0 global ProxyAgent and a CONNECT tunnel to a real TLS/HTTP2 server, under Node 24.19.0. The control request without identity failed; identity returned plain JSON and all three code paths succeeded. Public read-only identity requests also succeeded: `/models` returned HTTP 200, 3,309 bytes and 40 model IDs; models.dev returned HTTP 200, 4,884,187 bytes and valid metadata. Neither response was compressed. The tradeoff is the larger metadata transfer; identity does not fix the underlying loss of ETag headers. No observed endpoint required manually decoding compressed responses despite identity, so an artificial server ignoring the header is not used to justify that fallback.
|
|
38
|
+
|
|
39
|
+
Usage uses the shared reader with a 1 MiB limit on delivered bytes; listing and metadata limits remain 1 MiB and 16 MiB. Real HTTP regressions model an upstream that honors identity and a host that loses encoding headers: removing identity breaks the actual catalog/usage read, while identity succeeds. Correctly labeled Fetch-decoded compression and oversized responses remain covered. Model discovery retains the failure cause and gives both discovery entry points a URL plus HTTP status, network error code, JSON decoding failure or invalid listing shape. Public messages omit response bodies; a successful refresh clears the previous failure.
|
|
40
|
+
|
|
41
|
+
The initial picker-selection implementation used a saved allowlist and a separate deprecated-model option. It has been replaced by the individual switches described above.
|
|
42
|
+
|
|
43
|
+
Before the individual-switch and cached-discovery revision, the identity implementation passed `npm test`: Host/Client type checks, the production build and **240 tests in 19 files**, including all six supported host fixtures. Obsolete manual-decompression tests were replaced by request-negotiation and bounded JSON parsing coverage. Browser verification at that checkpoint used the actual settings component and controller with a local in-memory settings scope: selecting one model, saving, restoring all, and discarding behaved correctly; the 390 px viewport had no horizontal overflow and no browser errors were reported. This preview was not a live DSH Web deployment. The existing upstream missing-source-map warnings remain.
|
|
44
|
+
|
|
45
|
+
## Unknown profile fields during activation (2026-09-23)
|
|
46
|
+
|
|
47
|
+
A real Loader composition reproduced `TypeError: value.get is not a function` when the plugin entry contained an additional configuration field. Schemastery preserves fields outside the schema as plain values; the plugin incorrectly called `.get()` on every entry. Configuration reads now dereference only declared schema fields, preserving their live references and leaving stored profile data intact.
|
|
48
|
+
|
|
49
|
+
The regression failed before the fix and passes afterward, covering extra scalar, null, array, and object values alongside a working endpoint and model-capacity override. The built artifact also mounts with an extra field across all six supported host fixtures; both 0.1.7 fixtures verify live settings changes still work without remounting and retain the extra profile field. The build's Host/Client type checks and all **234 tests in 18 files** pass on macOS / Node.js 24.14.1. Upstream UI primitives still emit missing-source-map warnings. No live model requests were made during those tests.
|
|
50
|
+
|
|
51
|
+
The reported failure was subsequently reproduced by disabling and enabling the component in the user's running DSH Web process. A debugger breakpoint identified `showDeprecatedModels` as the failing field: its value was a boolean and its `get` property was undefined. The process's loaded plugin source matched the local `dsh-opencode-go-0.1.7.tgz` artifact byte for byte (SHA-256 `07422ad73df69896e2c3eafa1a07481cedd2945ed53dc59f09657abf1c8faa27`), including stack lines 1007 and 1305; that schema predates this field. The installed files were already 0.1.10 and recognized it. The process started at 18:30:41, before the replacement package directory was created at 18:31:45. Component toggles reimport the same cached module; the host's package manager requires a restart after replacing an installed dependency. Thus the actual trigger was a newer saved setting reaching an older module still loaded in memory, not a manually added invalid setting. A complete DSH restart loaded the existing 0.1.10 files with the same configuration: the component changed from failed to running, and the selected model and subscription usage became available. No package replacement or settings removal was needed, and no paid generation was sent.
|
|
52
|
+
|
|
3
53
|
## Default reasoning effort (plugin 0.1.10, 2026-09-23)
|
|
4
54
|
|
|
5
55
|
PR #6 declares a default effort for the pi-ai transports that explicitly disable thinking when the effort is unset: `deepseek`, `zai`, `qwen`, and `qwen-chat-template`. Models offering `high` default to it; otherwise the highest supported non-`off` effort is selected. Explicit choices, including `off`, still take precedence. Other transports and models without adjustable efforts retain their existing behavior.
|
|
@@ -10,7 +60,7 @@ Host/Client type checks, the build, and all **233 tests in 18 files** pass on ma
|
|
|
10
60
|
|
|
11
61
|
This release also includes PR #5's bounded compressed-response recovery described below, which was merged after the 0.1.9 release.
|
|
12
62
|
|
|
13
|
-
## Bounded model discovery responses (
|
|
63
|
+
## Bounded model discovery responses (0.1.10; superseded by identity requests above)
|
|
14
64
|
|
|
15
65
|
Model discovery accepts ordinary JSON and Brotli, gzip, or deflate JSON whose `Content-Encoding` header is missing. Correctly labeled responses continue through Fetch's automatic decoding. The shared reader counts actual streamed bytes and cancels oversized bodies; fallback decoders run asynchronously with `maxOutputLength`. Both delivered bytes and fallback output are limited to 1 MiB for the gateway listing and 16 MiB for models.dev metadata. These are payload limits, not total process-memory or CPU-time budgets. Failed recovery preserves the original JSON error and each decoder's cause.
|
|
16
66
|
|
|
@@ -38,7 +88,7 @@ Development dependencies are reproducible with `npm ci --legacy-peer-deps --igno
|
|
|
38
88
|
|
|
39
89
|
Host/client type checks, the build, and all **181 tests in 16 files** pass on macOS / Node.js 24.14.1. Coverage includes the five supported host versions, deprecated-model visibility, model remote injection, and CSS composition in the distributed client. The upstream UI primitives packages still emit missing-source-map warnings; all assertions pass. This release also synchronizes the English README with the simplified Chinese guide and updates installation examples to 0.1.8.
|
|
40
90
|
|
|
41
|
-
## Model settings layout and deprecated visibility (2026-09-22)
|
|
91
|
+
## Model settings layout and deprecated visibility (2026-09-22; superseded by individual switches above)
|
|
42
92
|
|
|
43
93
|
The settings page uses the selected list/detail layout, real gateway membership, models.dev release dates and deprecation flags, and a default-off `showDeprecatedModels` switch. Deprecated models stay configurable in settings; only conversation picker membership is filtered. Existing conversations can still call a hidden model that the gateway serves. Models found only in metadata or saved overrides are not displayed. Before any successful gateway response, a network failure does not advertise built-in models.
|
|
44
94
|
|
|
@@ -210,3 +260,27 @@ Total: four additional live completion requests and 3,092 reported tokens, inclu
|
|
|
210
260
|
The settings build was also loaded in the user's running local `0.1.7-alpha.1` Web profile. This exposed a missing `remote.opencodeGoModels` injection in the browser settings scope; both legacy and modern settings bindings now declare it, and the distributed-client regression checks exercise model loading under that injection requirement. After rebuilding and restarting the Host, the real settings page loaded 40 gateway models, including 3 recent releases and 8 deprecated entries, with the deprecated-model switch off. No completion request was sent during this check.
|
|
211
261
|
|
|
212
262
|
Local Web layout checks also cover the settings panel's independent scroll body and reserved save/discard footer. The model panel now uses the settings container's available height and stacks at narrow container widths. At a 600×780 viewport, browser geometry confirmed no footer overlap or horizontal overflow and a visible action row. The client artifact test checks inherited disclosure styles because the CSS-module build previously omitted `composes` entries.
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
## Per-model switches in the installed Web profile (2026-09-23)
|
|
266
|
+
|
|
267
|
+
The revised local package was installed into the user's Web profile and the source Harness restarted. Installed host and client JavaScript matched the local build byte for byte. In the authenticated page, settings displayed 40 gateway entries, including 8 deprecated entries whose switches were off by default. Disabling MiMo-V2.6-Pro removed it from both the live session model catalog and the actual conversation picker; enabling the deprecated MiniMax-M2.5 added it to both without pressing Save. The temporary overrides were then removed through the revision-fenced settings API, restoring normal-model visibility and deprecated-model defaults. No completion was submitted. Browser errors were empty, and the settings layout was visually checked at the user's 1077×1324 viewport.
|
|
268
|
+
|
|
269
|
+
Timeout retention was verified deterministically through the real Host RPC and component/controller tests: success, timeout with retained entries and an explicit warning, then recovery. The installed live check does not establish that upstream network timeouts can no longer occur.
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
## Missing model configuration (2026-09-23)
|
|
273
|
+
|
|
274
|
+
Settings now carries `configurationMissing` as structured model state. Models without usable Go configuration retain their raw names, show “配置缺失”, and have an unchecked, disabled switch even if an earlier visibility override is true. A real Host RPC regression covers missing configuration followed by metadata recovery, and the component regression covers the disabled switch and its recovery. The complete suite passed 248 tests in 20 files, along with the host and client type checks.
|
|
275
|
+
|
|
276
|
+
After installing and restarting the user's Web profile, the actual `deepseek-flash` and `hy3-preview` rows both displayed “配置缺失”, `aria-checked=false`, and a disabled switch. Neither name contained the previous English diagnostic. No user settings or model generations were changed during this check.
|
|
277
|
+
|
|
278
|
+
## Intermittent network resets and usage recovery (2026-09-23)
|
|
279
|
+
|
|
280
|
+
The subsequent `ECONNRESET` report is distinct from Issue #7's compressed JSON failure. Public `/models` probes with `accept-encoding: identity` reproduced resets before response headers, including in Node 24.14.1's unmodified built-in fetch without Harness or an Undici 8 dispatcher. Fifteen sequential native requests produced ten successes, one reset and four 10-second timeouts. A separate five-request probe through the configured local proxy with HTTP/2 disabled produced two successes, one reset and two timeouts. Successful responses were HTTP/1.1, HTTP 200 and 40 models. This rules out JSON parsing and HTTP/2 as necessary causes of this failure; it does not identify whether the local forwarding layer or the upstream path caused each reset. No proxy setting was changed and no completion was sent.
|
|
281
|
+
|
|
282
|
+
Read-only JSON requests now retry connection reset/socket closure/temporary DNS errors at most once after 150 ms, including failures during body reading. Both attempts and the delay share the original timeout signal. HTTP failures, malformed or oversized JSON, and TLS certificate errors are not automatically retried. Loopback HTTP tests exercise a dropped first connection followed by recovery, persistent failures, body truncation, HTTP failures, and cancellation during backoff. The real catalog and usage RPC paths also exercise recovery.
|
|
283
|
+
|
|
284
|
+
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
|
+
|
|
286
|
+
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.
|