@goodandready/dsh-opencode-provider 0.5.7 → 0.5.8

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.8
4
+
5
+ - **Free-tier error cooldown**: a `FreeTierError` (free model used with a free/anonymous key) is now a short `RATE_LIMIT`, not `INVALID_CREDENTIAL`. The account rotates to the next key and is cooled for 60s instead of 24h; the key itself is not invalid. Added an adapter regression test.
6
+ - 90 tests.
7
+
3
8
  ## 0.5.7
4
9
 
5
10
  - **Provider-id conflict fix**: the plugin now registers `opencode-direct` and `opencode-go-direct` instead of `opencode`/`opencode-go`. The built-in `llm-pi-ai` catalog owns those ids; reusing them triggered `DUPLICATE_DIRECTORY`, dropped the built-in catalog, hid other providers and disabled the add button. Existing sessions recorded under the old ids stay on the built-in routes; select **OpenCode (plugin)** or **OpenCode Go (plugin)** for this plugin's features.
package/README.md CHANGED
@@ -130,12 +130,12 @@ npm pack
130
130
  Install the **packed tarball** into a profile:
131
131
 
132
132
  ```bash
133
- dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.7.tgz
133
+ dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.8.tgz
134
134
  # DSH Desktop:
135
- dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.7.tgz
135
+ dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.8.tgz
136
136
 
137
137
  # Or install the published package:
138
- dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.7
138
+ dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.8
139
139
  ```
140
140
 
141
141
  Restart dsh (or DSH Desktop), then pick **OpenCode (plugin)** or **OpenCode Go (plugin)** in the model picker.
package/README.ru.md CHANGED
@@ -129,12 +129,12 @@ npm pack
129
129
  Установка из **упакованного tarball**:
130
130
 
131
131
  ```bash
132
- dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.7.tgz
132
+ dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.8.tgz
133
133
  # DSH Desktop:
134
- dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.7.tgz
134
+ dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.8.tgz
135
135
 
136
136
  # Либо установка опубликованного пакета из npm:
137
- dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.7
137
+ dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.8
138
138
  ```
139
139
 
140
140
  После установки перезапустите dsh (или DSH Desktop) и выберите **OpenCode (plugin)** или **OpenCode Go (plugin)** в списке моделей.
package/README.zh.md CHANGED
@@ -124,12 +124,12 @@ npm pack
124
124
  通过**打包文件 (.tgz)**安装:
125
125
 
126
126
  ```bash
127
- dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.7.tgz
127
+ dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.8.tgz
128
128
  # DSH 桌面端:
129
- dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.7.tgz
129
+ dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.8.tgz
130
130
 
131
131
  # 或从 npm 安装已发布版本:
132
- dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.7
132
+ dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.8
133
133
  ```
134
134
 
135
135
  安装完成后重启 dsh 或 DSH 桌面端,在模型选择器中选择 **OpenCode (plugin)** 或 **OpenCode Go (plugin)** 即可。
package/lib/index.js CHANGED
@@ -17,7 +17,7 @@ const DEFAULT_GO_API_BASE = "https://opencode.ai/inference/go";
17
17
  const DEFAULT_GO_ZEN_BASE = "https://opencode.ai/zen/go/v1";
18
18
  const DEFAULT_USAGE_URL = "https://opencode.ai/zen/go/v1/usage";
19
19
  const DEFAULT_AUTH_ENTRY = "opencode-go";
20
- const DEFAULT_USER_AGENT = "dsh-opencode-provider/0.5.7";
20
+ const DEFAULT_USER_AGENT = "dsh-opencode-provider/0.5.8";
21
21
  const DEFAULT_CONTEXT_WINDOW = 262144;
22
22
  const DEFAULT_MAX_TOKENS = 32768;
23
23
  const DEFAULT_GENERATE_MAX_TOKENS = 32768;
@@ -1169,7 +1169,7 @@ function classifyResponseError(status, text, headers) {
1169
1169
  };
1170
1170
  const quota = /\bquota\b/.test(detail) || detail.includes("usage limit") || detail.includes("usage_limit") || detail.includes("monthly limit") || detail.includes("weekly limit") || detail.includes("5-hour limit") || detail.includes("limit reached") || detail.includes("insufficient credit") || detail.includes("insufficient balance") || detail.includes("insufficient funds") || detail.includes("credit balance") || detail.includes("out of credit");
1171
1171
  if (type === "MissingSessionID" || detail.includes("missing x-opencode-session")) return new LlmError(`OpenCode rejected the request: ${message}. The plugin always sends a stable x-opencode-session; a proxy in front of it may be stripping the header.`, "PROVIDER_HTTP_ERROR", options);
1172
- if (type === "FreeTierError" || detail.includes("free tier can only be used")) return new LlmError(`OpenCode refused the free tier: ${message}. Free models require a Go/paid key; an anonymous free key is only accepted inside the OpenCode client.`, "INVALID_CREDENTIAL", options);
1172
+ if (type === "FreeTierError" || detail.includes("free tier can only be used")) return new LlmError(`OpenCode refused the free tier: ${message}. Free models require a Go/paid key; an anonymous free key is only accepted inside the OpenCode client.`, "RATE_LIMIT", options);
1173
1173
  if (type === "ModelProtocolUnsupported" || detail.includes("does not support this protocol")) return new LlmError(`OpenCode model does not support the selected protocol: ${message}. Set config.modelTransports[model] to the protocol named in the model catalog.`, "UNSUPPORTED_MODEL", options);
1174
1174
  if (status === 402 || quota) return new LlmError(`OpenCode quota is exhausted: ${message}`, "QUOTA", options);
1175
1175
  if (status === 401 || status === 403 || detail.includes("invalid credential") || detail.includes("unauthorized")) return new LlmError(`OpenCode rejected the credential: ${message}. Check the key, the selected auth.json entry, or whether the account has an active subscription.`, "INVALID_CREDENTIAL", options);
@@ -3505,14 +3505,14 @@ var OpenCodeAdapter = class extends LlmAdapter {
3505
3505
  const seconds = raw === null || raw === void 0 ? NaN : Number(raw);
3506
3506
  delayMs = Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : 6e5;
3507
3507
  reason = "quota";
3508
- } else if (status === 401 || status === 403) {
3509
- delayMs = 864e5;
3510
- reason = "invalid-credential";
3511
- } else if (status === 429) {
3508
+ } else if (code === "RATE_LIMIT" || status === 429) {
3512
3509
  const raw = headers?.get("retry-after");
3513
3510
  const seconds = raw === null || raw === void 0 ? NaN : Number(raw);
3514
3511
  delayMs = Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : 6e4;
3515
3512
  reason = "rate-limit";
3513
+ } else if (status === 401 || status === 403) {
3514
+ delayMs = 864e5;
3515
+ reason = "invalid-credential";
3516
3516
  }
3517
3517
  this.cooldowns.set(this.keyId(key), {
3518
3518
  until: Date.now() + delayMs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-opencode-provider",
3
- "version": "0.5.7",
3
+ "version": "0.5.8",
4
4
  "description": "OpenCode / OpenCode Go LLM provider plugin for DeepSeek Harness (dsh).",
5
5
  "license": "MIT",
6
6
  "type": "module",