@goodandready/dsh-opencode-provider 0.5.7 → 0.5.9

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,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.9
4
+
5
+ - **Analytics provider filter**: after the provider-id split, session model analytics includes only `opencode-direct`/`opencode-go-direct`. Legacy `opencode`/`opencode-go` sessions now belong to the built-in pi-ai catalog and are intentionally excluded, so the plugin no longer mixes built-in traffic into its model analytics.
6
+ - 90 tests.
7
+
8
+ ## 0.5.8
9
+
10
+ - **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.
11
+ - 90 tests.
12
+
3
13
  ## 0.5.7
4
14
 
5
15
  - **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.9.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.9.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.9
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.9.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.9.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.9
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.9.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.9.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.9
133
133
  ```
134
134
 
135
135
  安装完成后重启 dsh 或 DSH 桌面端,在模型选择器中选择 **OpenCode (plugin)** 或 **OpenCode Go (plugin)** 即可。
package/lib/client.js CHANGED
@@ -378,8 +378,6 @@ window.__ModuleLoader__.load({
378
378
  perMonth: "每月"
379
379
  }
380
380
  };
381
- //#endregion
382
- //#region src/provider-ids.ts
383
381
  const GO_PROVIDER = "opencode-go-direct";
384
382
  //#endregion
385
383
  //#region src/client/api.ts
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.9";
21
21
  const DEFAULT_CONTEXT_WINDOW = 262144;
22
22
  const DEFAULT_MAX_TOKENS = 32768;
23
23
  const DEFAULT_GENERATE_MAX_TOKENS = 32768;
@@ -799,12 +799,7 @@ const GENERATED_MODELS = {
799
799
  */
800
800
  const CONSOLE_PROVIDER = "opencode-direct";
801
801
  const GO_PROVIDER = "opencode-go-direct";
802
- const PLUGIN_AND_LEGACY_PROVIDERS = /* @__PURE__ */ new Set([
803
- CONSOLE_PROVIDER,
804
- GO_PROVIDER,
805
- "opencode",
806
- "opencode-go"
807
- ]);
802
+ const PLUGIN_PROVIDER_SET = /* @__PURE__ */ new Set([CONSOLE_PROVIDER, GO_PROVIDER]);
808
803
  //#endregion
809
804
  //#region src/routing.ts
810
805
  function isGoProvider(provider) {
@@ -1169,7 +1164,7 @@ function classifyResponseError(status, text, headers) {
1169
1164
  };
1170
1165
  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
1166
  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);
1167
+ 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
1168
  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
1169
  if (status === 402 || quota) return new LlmError(`OpenCode quota is exhausted: ${message}`, "QUOTA", options);
1175
1170
  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 +3500,14 @@ var OpenCodeAdapter = class extends LlmAdapter {
3505
3500
  const seconds = raw === null || raw === void 0 ? NaN : Number(raw);
3506
3501
  delayMs = Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : 6e5;
3507
3502
  reason = "quota";
3508
- } else if (status === 401 || status === 403) {
3509
- delayMs = 864e5;
3510
- reason = "invalid-credential";
3511
- } else if (status === 429) {
3503
+ } else if (code === "RATE_LIMIT" || status === 429) {
3512
3504
  const raw = headers?.get("retry-after");
3513
3505
  const seconds = raw === null || raw === void 0 ? NaN : Number(raw);
3514
3506
  delayMs = Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : 6e4;
3515
3507
  reason = "rate-limit";
3508
+ } else if (status === 401 || status === 403) {
3509
+ delayMs = 864e5;
3510
+ reason = "invalid-credential";
3516
3511
  }
3517
3512
  this.cooldowns.set(this.keyId(key), {
3518
3513
  until: Date.now() + delayMs,
@@ -4210,7 +4205,7 @@ function aggregateSessions(sessions, days, now = Date.now()) {
4210
4205
  for (const session of sessions) {
4211
4206
  const provider = session.lastUsed?.provider;
4212
4207
  const model = session.lastUsed?.model;
4213
- if (typeof provider !== "string" || !PLUGIN_AND_LEGACY_PROVIDERS.has(provider) || model === void 0 || model === "") continue;
4208
+ if (typeof provider !== "string" || !PLUGIN_PROVIDER_SET.has(provider) || model === void 0 || model === "") continue;
4214
4209
  const usage = session.usage;
4215
4210
  if (usage === void 0) continue;
4216
4211
  const input = count(usage.uncachedInputTokens);
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.9",
4
4
  "description": "OpenCode / OpenCode Go LLM provider plugin for DeepSeek Harness (dsh).",
5
5
  "license": "MIT",
6
6
  "type": "module",