@dan-ai-studio/dshopencodego 0.1.44 → 0.1.46
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 +11 -5
- package/README.md +11 -5
- package/lib/index.js +1 -34
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -6,12 +6,18 @@ Makes [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) work p
|
|
|
6
6
|
|
|
7
7
|
## Why it exists
|
|
8
8
|
|
|
9
|
-
A stock DSH route to OpenCode Go
|
|
9
|
+
A stock DSH route to OpenCode Go already works (`llm-pi-ai` ships the provider). What this plugin adds is what that route does **not** do:
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
| Capability | Stock DSH | This plugin |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| **Live model catalog** | A build-time snapshot: the fixed table pi-ai ships with, so a new gateway model waits for a pi-ai release | Reads the gateway catalog live, with multi-level fallback and TTL caching |
|
|
14
|
+
| **Quota windows** (5-hour / weekly / monthly) | None | ✅ |
|
|
15
|
+
| **Estimated spend** | None | ✅ |
|
|
16
|
+
| **Per-model switches** `modelVisibility` | None | ✅ |
|
|
17
|
+
|
|
18
|
+
This plugin serves the `opencode-go` route with its own adapter and adds the usage and settings surfaces.
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
> **On the session header**: Go requires a stable `x-opencode-session` on every request and answers `400 MissingSessionID` without it. That was one of this plugin's original reasons to exist, but pi-ai implemented the injection on 2026-09-09 (`561a2e06`) and `llm-pi-ai` carries it automatically, so a stock DSH route does not miss the header either. This plugin still keeps its own implementation — it falls back to a one-off UUID when a session id is missing — until that fallback lands upstream; the review is in [`docs/scope-review-2026-10.md`](docs/scope-review-2026-10.md).
|
|
15
21
|
|
|
16
22
|
## Install
|
|
17
23
|
|
|
@@ -241,7 +247,7 @@ npm test # contract tests against a real local HTTP mock gateway
|
|
|
241
247
|
|
|
242
248
|
**Order matters**: `npm run build` must come before `npm test` — `tests/pack-contents.spec.ts` walks every `exports` target, and whether `lib/` exists decides whether that check runs or is silently skipped (it does not fail, it just stops protecting you). `package.json` no longer carries `prepare`, so `npm ci` will not build for you; all three CI workflows run `npm run build` explicitly.
|
|
243
249
|
|
|
244
|
-
The suite covers configuration validation, the protocol ladder, gateway and online metadata, the catalog projection, the adapter on the wire (all three protocols), Remote contracts and services, session-header invariants, usage windows and the meter, the client controller and usage pill, both halves' mounting and registration, the error mapping for stream idle timeouts and aborts, the exit-code contract of the verification scripts, and several **structural invariants** (inject declarations match the source's reads, peer coverage holds both ways, the READMEs match the manifest). That is **
|
|
250
|
+
The suite covers configuration validation, the protocol ladder, gateway and online metadata, the catalog projection, the adapter on the wire (all three protocols), Remote contracts and services, session-header invariants, usage windows and the meter, the client controller and usage pill, both halves' mounting and registration, the error mapping for stream idle timeouts and aborts, the exit-code contract of the verification scripts, and several **structural invariants** (inject declarations match the source's reads, peer coverage holds both ways, the READMEs match the manifest, and the READMEs' claims about the upstream match the upstream actually installed). That is **44 test files** — a number `tests/readme-consistency.spec.ts` checks against the `tests/` directory, so it cannot drift.
|
|
245
251
|
|
|
246
252
|
## Releasing (maintainers)
|
|
247
253
|
|
package/README.md
CHANGED
|
@@ -6,12 +6,18 @@
|
|
|
6
6
|
|
|
7
7
|
## 为什么需要它
|
|
8
8
|
|
|
9
|
-
原生 DSH
|
|
9
|
+
原生 DSH 已经能连 OpenCode Go(`llm-pi-ai` 内置该 provider)。本插件补的是它**不提供**的那几件事:
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
| 能力 | 原生 DSH | 本插件 |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| **实时模型目录** | 构建期快照:pi-ai 打包时生成的固定表,网关新增模型要等 pi-ai 发版 | 实时读取网关目录,多级回退 + TTL 缓存 |
|
|
14
|
+
| **额度窗口**(5 小时 / 本周 / 本月) | 无 | ✅ |
|
|
15
|
+
| **花费估算** | 无 | ✅ |
|
|
16
|
+
| **逐模型开关** `modelVisibility` | 无 | ✅ |
|
|
17
|
+
|
|
18
|
+
本插件为 `opencode-go` 路由提供自己的适配器,并提供用量与设置界面。
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
> **关于会话头**:Go 要求每个请求带稳定的 `x-opencode-session`,缺失即 `400 MissingSessionID`。这一项曾是本插件的原始存在理由,但 pi-ai 已于 2026-09-09(`561a2e06`)实现注入、`llm-pi-ai` 自动携带,因此**原生 DSH 现在也不会缺会话头**。本插件当前仍保留自己的实现(为缺失会话 id 的请求提供一次性 UUID 兜底),待该兜底进入上游后再收缩——评估过程见 [`docs/scope-review-2026-10.md`](docs/scope-review-2026-10.md)。
|
|
15
21
|
|
|
16
22
|
## 安装
|
|
17
23
|
|
|
@@ -241,7 +247,7 @@ npm test # 契约测试:真实 HTTP mock 网关,断言请求头/
|
|
|
241
247
|
|
|
242
248
|
**顺序有讲究**:`npm run build` 要排在 `npm test` 之前——`tests/pack-contents.spec.ts` 会遍历 `exports` 的每个目标,`lib/` 存在与否决定这条检查是执行还是被跳过(不报错,但会少一层保护)。`package.json` 已移除 `prepare`,因此 `npm ci` 不会再替你隐式构建;三个 CI workflow 都显式跑了 `npm run build`。
|
|
243
249
|
|
|
244
|
-
测试覆盖配置校验、协议阶梯、网关与在线元数据、目录投影、适配器(三种协议的线上请求)、Remote 契约与服务、会话头不变量、用量窗口与计量、客户端控制器与用量组件、两半的挂载与登记、流空闲超时与中止的错误映射、验证脚本的退出码契约、以及几条**结构性不变量**(inject 声明与源码读取一致、peer 覆盖双向、README 与 manifest
|
|
250
|
+
测试覆盖配置校验、协议阶梯、网关与在线元数据、目录投影、适配器(三种协议的线上请求)、Remote 契约与服务、会话头不变量、用量窗口与计量、客户端控制器与用量组件、两半的挂载与登记、流空闲超时与中止的错误映射、验证脚本的退出码契约、以及几条**结构性不变量**(inject 声明与源码读取一致、peer 覆盖双向、README 与 manifest 一致、README 对上游的断言与实装的上游一致)。共 **44 个测试文件**——这个数字由 `tests/readme-consistency.spec.ts` 对着 `tests/` 目录校验,不会漂移。
|
|
245
251
|
|
|
246
252
|
## 发布(维护者)
|
|
247
253
|
|
package/lib/index.js
CHANGED
|
@@ -45707,7 +45707,7 @@ function createUpdateChecker(deps) {
|
|
|
45707
45707
|
}
|
|
45708
45708
|
|
|
45709
45709
|
// src/update/version.ts
|
|
45710
|
-
var PLUGIN_VERSION = true ? "0.1.
|
|
45710
|
+
var PLUGIN_VERSION = true ? "0.1.46" : "0.0.0-dev";
|
|
45711
45711
|
|
|
45712
45712
|
// src/update/service.ts
|
|
45713
45713
|
import { TypertRemoteService as TypertRemoteService2 } from "@deepseek-ai/dsh-typert-protocol";
|
|
@@ -45850,36 +45850,6 @@ function apply(ctx, raw) {
|
|
|
45850
45850
|
const current = () => live === void 0 ? constant : readConfig(live);
|
|
45851
45851
|
assertBaseURL(current().baseURL);
|
|
45852
45852
|
const settingsNs = ctx.fiber?.entry?.options.id ?? name;
|
|
45853
|
-
let directory;
|
|
45854
|
-
let directoryError;
|
|
45855
|
-
let directoryRetired = false;
|
|
45856
|
-
const directoryEntry = (error) => ({
|
|
45857
|
-
provider: PROVIDER_ID,
|
|
45858
|
-
displayName: DISPLAY_NAME,
|
|
45859
|
-
settingsNs,
|
|
45860
|
-
// This plugin's profile is the entry's whole `config:` mapping — the
|
|
45861
|
-
// bundled `cordis.patch.yml` inserts `id: dshopencodego` with the route's
|
|
45862
|
-
// fields directly under `config`, and `src/config.ts` owns exactly those
|
|
45863
|
-
// fields — so there is no path from the section root to a nested profile.
|
|
45864
|
-
settingsPath: [],
|
|
45865
|
-
defaultBaseURL: DEFAULT_BASE_URL,
|
|
45866
|
-
...error === void 0 ? {} : { error }
|
|
45867
|
-
});
|
|
45868
|
-
const publishDirectory = (error) => {
|
|
45869
|
-
if (directoryRetired || directory !== void 0 && error === directoryError) return;
|
|
45870
|
-
directoryError = error;
|
|
45871
|
-
const entry = directoryEntry(error);
|
|
45872
|
-
try {
|
|
45873
|
-
if (directory === void 0) directory = ctx.llm.registerConfigurableProviders([entry]);
|
|
45874
|
-
else directory.replace([entry]);
|
|
45875
|
-
} catch (failure) {
|
|
45876
|
-
directoryRetired = true;
|
|
45877
|
-
ctx.logger.error(
|
|
45878
|
-
`dshopencodego: could not publish the "${PROVIDER_ID}" configurable-provider entry; the Models page will not offer this route's model discovery (${String(failure)})`
|
|
45879
|
-
);
|
|
45880
|
-
}
|
|
45881
|
-
};
|
|
45882
|
-
publishDirectory(void 0);
|
|
45883
45853
|
const resolveApiKey = async () => {
|
|
45884
45854
|
const ref = current().apiKeyEnv;
|
|
45885
45855
|
const credentials = ctx.get("credentials");
|
|
@@ -45948,7 +45918,6 @@ function apply(ctx, raw) {
|
|
|
45948
45918
|
ctx.logger.info("dshopencodego: disabled by configuration; the route and its models are withdrawn");
|
|
45949
45919
|
}
|
|
45950
45920
|
}
|
|
45951
|
-
publishDirectory(enabled && !credentialConfigured ? `the route is withheld until ${current().apiKeyEnv} is stored through the credentials service` : void 0);
|
|
45952
45921
|
};
|
|
45953
45922
|
const syncRoute = () => {
|
|
45954
45923
|
try {
|
|
@@ -45990,8 +45959,6 @@ function apply(ctx, raw) {
|
|
|
45990
45959
|
ctx.effect(() => () => {
|
|
45991
45960
|
registration?.();
|
|
45992
45961
|
undiscover();
|
|
45993
|
-
directory?.();
|
|
45994
|
-
directoryRetired = true;
|
|
45995
45962
|
});
|
|
45996
45963
|
ctx.on("internal/config", function(_raw, next) {
|
|
45997
45964
|
const value = next();
|
package/package.json
CHANGED