@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 +10 -0
- package/README.md +3 -3
- package/README.ru.md +3 -3
- package/README.zh.md +3 -3
- package/lib/client.js +0 -2
- package/lib/index.js +8 -13
- package/package.json +1 -1
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
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.
|
|
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
|
|
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.`, "
|
|
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 (
|
|
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" || !
|
|
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);
|