@dan-ai-studio/dshopencodego 0.1.14 → 0.1.16
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 +4 -4
- package/README.md +4 -4
- package/lib/client.js +21 -4
- package/lib/index.js +203 -52
- package/lib/types/catalog/contract.js +7 -0
- package/lib/types/catalog/go-doc.d.ts +57 -0
- package/lib/types/catalog/go-doc.js +192 -0
- package/lib/types/catalog/index.d.ts +37 -7
- package/lib/types/catalog/index.js +50 -9
- package/lib/types/catalog/json-response.d.ts +6 -3
- package/lib/types/catalog/json-response.js +6 -5
- package/lib/types/catalog/protocol.d.ts +7 -2
- package/lib/types/catalog/reading.d.ts +5 -0
- package/lib/types/catalog/reading.js +3 -1
- package/lib/types/config.d.ts +7 -2
- package/lib/types/config.js +6 -1
- package/lib/types/go-limits.d.ts +23 -11
- package/lib/types/go-limits.js +24 -12
- package/package.json +4 -2
package/README.en.md
CHANGED
|
@@ -120,10 +120,10 @@ The gateway's `/v1/models` answers only *which* models exist, never *how* to cal
|
|
|
120
120
|
|
|
121
121
|
## The model list in the settings page
|
|
122
122
|
|
|
123
|
-
The "OpenCode Go" section shows the live gateway catalog (
|
|
123
|
+
The "OpenCode Go" section shows the live gateway catalog (the count follows the gateway) with, per model:
|
|
124
124
|
|
|
125
125
|
- **context / max input / max output**, **release date**, **price per 1M tokens** (from models.dev), and **Go allowance**;
|
|
126
|
-
- **Go allowance**
|
|
126
|
+
- **Go allowance** is fetched at runtime from the provider's own documentation — the "usage limits / estimated requests" tables, whose source is a markdown file in the provider's repository (GitHub first, jsDelivr second) — and refreshes with the catalog every 60 minutes. A failed fetch keeps the last successful parse; a process that never succeeded uses the **built-in snapshot** and the page says so, with the transcription date (`src/go-limits.ts`, frozen, not maintained by hand). A moved or restructured document counts as a failed fetch, never as an emptied column;
|
|
127
127
|
- **Input modalities**: a separate line lists the input modes models.dev declares (text / image / audio / video / PDF). These are the **model's own metadata**, not what the Harness can forward — the Harness sends text and images natively; audio/video/PDF travel as attachments and tool reads. The line is absent when the document declares none.
|
|
128
128
|
- filtering (by name/id, enabled-only, show-deprecated — **deprecated hidden by default**), sorting (newest first, monthly requests, input price, context, name, enabled first); the list is the only view, one model per row.
|
|
129
129
|
|
|
@@ -152,7 +152,7 @@ The `engines.dsh` field is informational for readers and package managers; **DSH
|
|
|
152
152
|
|
|
153
153
|
| Binding layer | Declared | Enforced by |
|
|
154
154
|
| --- | --- | --- |
|
|
155
|
-
| `peerDependencies` (
|
|
155
|
+
| `peerDependencies` (17 `@deepseek-ai/dsh-*` packages) | all `>=0.1.7-alpha.1 <0.1.8` | **DSH's gate, at plugin load time** |
|
|
156
156
|
| `@deepseek-ai/cordis` | `4.0.2 \|\| 4.0.3 \|\| 4.0.4` | the same gate |
|
|
157
157
|
| `engines.dsh` | `>=0.1.7-alpha.1 <0.1.8` | informational only; DSH never reads it |
|
|
158
158
|
| `engines.node` | `^22.19.0 \|\| >=24.0.0` | the package manager |
|
|
@@ -161,7 +161,7 @@ The `engines.dsh` field is informational for readers and package managers; **DSH
|
|
|
161
161
|
|
|
162
162
|
Things to keep in mind when maintaining this:
|
|
163
163
|
|
|
164
|
-
- **Required versus optional peers**: six of the
|
|
164
|
+
- **Required versus optional peers**: six of the eighteen are marked `optional` (`dsh-api-remotes`, `dsh-client-locale`, `dsh-client-store`, `dsh-client-ui-model-selection`, `dsh-client-ui-settings`, `dsh-client-ui-slots`). The twelve that actually block loading are `cordis`, `dsh-attachment`, `dsh-brand`, `dsh-client-ui-conversation`, `dsh-client-ui-renderer`, `dsh-credentials`, `dsh-fs`, `dsh-launch-environment`, `dsh-llm`, `dsh-timeout`, `dsh-typert-protocol`, and `dsh-typert-registry`. `dsh-llm` is the heaviest coupling — more than twenty imports across the source.
|
|
165
165
|
- **Declared range ≠ verified range**: `0.1.7-alpha.1` and `alpha.2` fall inside the declaration but were never verified here. What was verified is `0.1.7-rc.1` (the dev-dependency baseline) and `0.1.7-rc.2` (daily use).
|
|
166
166
|
- **The upper bound is a tracking line**: `<0.1.8` means that the moment DSH ships `0.1.8`, this plugin must ship a new release in the same window or every user loses the plugin. After changing a range, `npm test` is the verification (local mock gateway, no network, no tokens) — ranges follow what the interfaces declare, and are never "measured" with live probes.
|
|
167
167
|
- **Peer coverage is now guarded both ways**: `dsh-typert-registry`, `dsh-client-ui-conversation`, and `dsh-client-ui-renderer` were imported by the source but absent from `peerDependencies`, invisible to the gate; they are declared now, and `tests/peer-coverage.spec.ts` asserts both directions — anything the source imports must be declared, and anything declared but unreached must be removed (`dsh-settings` went that way: the settings form is actually provided by `dsh-client-ui-settings`).
|
package/README.md
CHANGED
|
@@ -120,10 +120,10 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
|
|
|
120
120
|
|
|
121
121
|
## 设置页里的模型列表
|
|
122
122
|
|
|
123
|
-
设置页的「OpenCode Go
|
|
123
|
+
设置页的「OpenCode Go」分区展示网关实时目录(数量随网关发布变化),并对每个模型给出:
|
|
124
124
|
|
|
125
125
|
- **上下文 / 输入 / 输出**(最大输入只有部分模型有官方数据)、**发布时间**、**单价 /1M**(来自 models.dev)、**Go 额度**;
|
|
126
|
-
- **Go
|
|
126
|
+
- **Go 额度**:运行时从 OpenCode 官方文档抓取「使用限制 / 预估请求数」两张表(数据源是官方仓库里的 markdown 文件,主源 GitHub、备用 jsDelivr),跟随目录每 60 分钟刷新一次;抓取失败时保留上次成功的数据,从未成功过则使用**内置快照**并在页面上标注其转写日期(`src/go-limits.ts`,已冻结、不再手工维护)。文档结构变化会被识别为抓取失败而不会清空显示。
|
|
127
127
|
- **输入模态**:单独一行列出 models.dev 声明的输入方式(文本 / 图像 / 音频 / 视频 / PDF)。这是**模型自身的元数据**,不等于 DSH 能直传:DSH 的模型输入只原生支持文本与图像,音视频/PDF 走附件与工具读取路径;文档未声明时该行不显示。
|
|
128
128
|
- 筛选(按名称/ID、仅已启用、显示已弃用——**默认隐藏已弃用**)、排序(新发布优先 / 每月预估次数 / 输入单价 / 上下文 / 名称 / 已启用优先);列表是唯一视图,逐模型纵向排列。
|
|
129
129
|
|
|
@@ -152,7 +152,7 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
|
|
|
152
152
|
|
|
153
153
|
| 绑定层 | 声明 | 谁在把关 |
|
|
154
154
|
| --- | --- | --- |
|
|
155
|
-
| `peerDependencies`(
|
|
155
|
+
| `peerDependencies`(17 个 `@deepseek-ai/dsh-*`) | 均为 `>=0.1.7-alpha.1 <0.1.8` | **DSH 加载时的真门禁** |
|
|
156
156
|
| `@deepseek-ai/cordis` | `4.0.2 \|\| 4.0.3 \|\| 4.0.4` | 同一门禁 |
|
|
157
157
|
| `engines.dsh` | `>=0.1.7-alpha.1 <0.1.8` | 仅信息字段,DSH 不读 |
|
|
158
158
|
| `engines.node` | `^22.19.0 \|\| >=24.0.0` | 包管理器 |
|
|
@@ -161,7 +161,7 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
|
|
|
161
161
|
|
|
162
162
|
维护时需要注意:
|
|
163
163
|
|
|
164
|
-
- **必选与可选之分**:
|
|
164
|
+
- **必选与可选之分**:18 个 peer(17 个 `dsh-*` 加框架 `cordis`)中 6 个标了 `optional`(`dsh-api-remotes`、`dsh-client-locale`、`dsh-client-store`、`dsh-client-ui-model-selection`、`dsh-client-ui-settings`、`dsh-client-ui-slots`);真正卡住加载的是 12 个——`cordis`、`dsh-attachment`、`dsh-brand`、`dsh-client-ui-conversation`、`dsh-client-ui-renderer`、`dsh-credentials`、`dsh-fs`、`dsh-launch-environment`、`dsh-llm`、`dsh-timeout`、`dsh-typert-protocol`、`dsh-typert-registry`。其中 `dsh-llm` 是最重的一处耦合(源码 import 二十余处)。
|
|
165
165
|
- **名义范围 ≠ 实测范围**:`0.1.7-alpha.1`、`alpha.2` 落在声明范围内,但本项目没有验证过;实际验证过的是 `0.1.7-rc.1`(开发依赖基线)与 `0.1.7-rc.2`(日常使用)。
|
|
166
166
|
- **上界就是跟版线**:`<0.1.8` 意味着 DSH 一旦发布 `0.1.8`,本插件必须同批发新版,否则所有用户加载失败。调整范围后用 `npm test` 验证即可(本地 mock 网关,零网络零 token)——范围以接口声明为准,不要用线上探测来"测"出一个范围。
|
|
167
167
|
- **peer 覆盖已双向守住**:`dsh-typert-registry`、`dsh-client-ui-conversation`、`dsh-client-ui-renderer` 曾被源码 import 却未声明、门禁管不到,现已补进 `peerDependencies`;`tests/peer-coverage.spec.ts` 双向断言——源码用到的必须声明,声明了却没人用的必须删(`dsh-settings` 就这样被移除:设置表单实际由 `dsh-client-ui-settings` 提供)。
|
package/lib/client.js
CHANGED
|
@@ -103,11 +103,16 @@ function parseCatalogReading(value) {
|
|
|
103
103
|
if (typeof entry !== "number" || !Number.isFinite(entry) || entry < 0) throw new Error(`invalid catalog count "${key}"`);
|
|
104
104
|
return entry;
|
|
105
105
|
};
|
|
106
|
+
const quotaSource = row["quotaSource"];
|
|
107
|
+
if (quotaSource !== void 0 && quotaSource !== "document" && quotaSource !== "seed") {
|
|
108
|
+
throw new Error("invalid catalog quota source");
|
|
109
|
+
}
|
|
106
110
|
return {
|
|
107
111
|
models: row["models"].map(parseModel),
|
|
108
112
|
stale: row["stale"],
|
|
109
113
|
...typeof row["error"] === "string" ? { error: row["error"] } : {},
|
|
110
114
|
fetchedAtMs: row["fetchedAtMs"],
|
|
115
|
+
quotaSource: quotaSource ?? "seed",
|
|
111
116
|
counts: {
|
|
112
117
|
total: count("total"),
|
|
113
118
|
enabled: count("enabled"),
|
|
@@ -253,6 +258,7 @@ var en = {
|
|
|
253
258
|
catalogAssumed: "default capacities",
|
|
254
259
|
catalogDeprecated: "deprecated",
|
|
255
260
|
catalogUnconfigured: "not configurable",
|
|
261
|
+
quotaSeed: "Allowances are the built-in snapshot, transcribed",
|
|
256
262
|
refreshLabel: "Catalog refresh (minutes)",
|
|
257
263
|
refreshHint: "How long requests and the model picker reuse one listing.",
|
|
258
264
|
writeRejected: "The settings write was rejected (the namespace was reloaded) \u2014 try again",
|
|
@@ -319,6 +325,7 @@ var zh = {
|
|
|
319
325
|
catalogAssumed: "\u5BB9\u91CF\u4E3A\u9ED8\u8BA4\u503C",
|
|
320
326
|
catalogDeprecated: "\u5DF2\u5F03\u7528",
|
|
321
327
|
catalogUnconfigured: "\u65E0\u6CD5\u914D\u7F6E",
|
|
328
|
+
quotaSeed: "\u989D\u5EA6\u6765\u81EA\u5185\u7F6E\u5FEB\u7167\uFF0C\u8F6C\u5199\u4E8E",
|
|
322
329
|
refreshLabel: "\u76EE\u5F55\u5237\u65B0\uFF08\u5206\u949F\uFF09",
|
|
323
330
|
refreshHint: "\u8BF7\u6C42\u4E0E\u6A21\u578B\u9009\u62E9\u5668\u590D\u7528\u540C\u4E00\u4EFD\u5217\u8868\u7684\u65F6\u957F\u3002",
|
|
324
331
|
writeRejected: "\u8BBE\u7F6E\u5199\u5165\u88AB\u62D2\u7EDD\uFF08\u5DF2\u91CD\u65B0\u8F7D\u5165\uFF09\uFF0C\u8BF7\u91CD\u8BD5",
|
|
@@ -369,6 +376,7 @@ var zh = {
|
|
|
369
376
|
var import_react = require("react");
|
|
370
377
|
|
|
371
378
|
// src/go-limits.ts
|
|
379
|
+
var SEED_TRANSCRIBED = "2026-09-25";
|
|
372
380
|
function monthlyRequestsRank(quota) {
|
|
373
381
|
if (quota === void 0) return -1;
|
|
374
382
|
const requests = quota.monthlyRequests;
|
|
@@ -454,7 +462,7 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id) + "]")
|
|
|
454
462
|
style.textContent = ".d7lz0W_root{color:var(--dsw-alias-label-primary);flex-direction:column;gap:1.25rem;display:flex}.d7lz0W_title{margin:0;font-size:1.05rem}.d7lz0W_hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:.8rem}.d7lz0W_warn{color:var(--dsw-alias-state-warn-primary);margin:0;font-size:.8rem}.d7lz0W_ok{color:var(--dsw-alias-state-success-primary);font-size:.8rem}.d7lz0W_block{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:.6rem;flex-direction:column;gap:.5rem;padding:.85rem;display:flex}.d7lz0W_row{flex-wrap:wrap;align-items:center;gap:.5rem;display:flex}.d7lz0W_row>strong{margin-right:auto}.d7lz0W_input{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);min-width:10rem;color:var(--dsw-alias-label-primary);font:inherit;border-radius:.35rem;flex:14rem;padding:.35rem .5rem;font-size:.85rem}.d7lz0W_button{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:.35rem;padding:.35rem .7rem;font-size:.8rem}.d7lz0W_button:disabled{color:var(--dsw-alias-state-idle-primary);cursor:default}.d7lz0W_number{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:5rem;color:var(--dsw-alias-label-primary);font:inherit;border-radius:.35rem;padding:.25rem .4rem;font-size:.8rem}.d7lz0W_select{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:auto;max-width:100%;color:var(--dsw-alias-label-primary);font:inherit;border-radius:.35rem;padding:.25rem .4rem;font-size:.8rem}.d7lz0W_list{flex-direction:column;display:flex}.d7lz0W_item{border-top:1px solid var(--dsw-alias-border-l1);align-items:flex-start;gap:.5rem;padding:.45rem .15rem;display:flex}.d7lz0W_item input[type=checkbox]{accent-color:var(--dsw-alias-brand-primary);margin-top:.15rem}.d7lz0W_itemBody{flex-direction:column;gap:.15rem;min-width:0;display:flex}.d7lz0W_itemMain{flex-wrap:wrap;align-items:baseline;gap:.6rem;display:flex}.d7lz0W_itemMeta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:.75rem;font-size:.75rem;display:flex}.d7lz0W_itemModalities{color:var(--dsw-alias-label-secondary);font-size:.75rem}.d7lz0W_name{color:var(--dsw-alias-label-primary)}.d7lz0W_mono{color:var(--dsw-alias-label-secondary);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.d7lz0W_badge{color:var(--dsw-alias-brand-primary)}";
|
|
455
463
|
document.head.appendChild(style);
|
|
456
464
|
}
|
|
457
|
-
var section_default = { "itemBody": "d7lz0W_itemBody", "
|
|
465
|
+
var section_default = { "itemBody": "d7lz0W_itemBody", "name": "d7lz0W_name", "warn": "d7lz0W_warn", "block": "d7lz0W_block", "button": "d7lz0W_button", "ok": "d7lz0W_ok", "title": "d7lz0W_title", "hint": "d7lz0W_hint", "list": "d7lz0W_list", "itemMain": "d7lz0W_itemMain", "item": "d7lz0W_item", "number": "d7lz0W_number", "mono": "d7lz0W_mono", "badge": "d7lz0W_badge", "itemMeta": "d7lz0W_itemMeta", "input": "d7lz0W_input", "row": "d7lz0W_row", "itemModalities": "d7lz0W_itemModalities", "select": "d7lz0W_select", "root": "d7lz0W_root" };
|
|
458
466
|
|
|
459
467
|
// src/client/Section.tsx
|
|
460
468
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -635,7 +643,7 @@ var SectionController = class {
|
|
|
635
643
|
this.set({ saving: false });
|
|
636
644
|
}
|
|
637
645
|
}
|
|
638
|
-
/** Narrow or reorder the model
|
|
646
|
+
/** Narrow or reorder the model list; a view preference, never a write. */
|
|
639
647
|
setFilter(patch) {
|
|
640
648
|
this.set({ filter: { ...this.state.filter, ...patch } });
|
|
641
649
|
}
|
|
@@ -811,6 +819,11 @@ function Section({ controller, t, getLocale }) {
|
|
|
811
819
|
state.failure
|
|
812
820
|
] }),
|
|
813
821
|
reading !== void 0 && reading.stale && state.failure === void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: section_default.warn, children: t("catalogStale") }),
|
|
822
|
+
reading !== void 0 && reading.quotaSource === "seed" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: section_default.hint, children: [
|
|
823
|
+
t("quotaSeed"),
|
|
824
|
+
" ",
|
|
825
|
+
SEED_TRANSCRIBED
|
|
826
|
+
] }),
|
|
814
827
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: section_default.row, children: [
|
|
815
828
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: section_default.hint, htmlFor: "dshopencodego-refresh", children: t("refreshLabel") }),
|
|
816
829
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -950,7 +963,7 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id2) + "]"
|
|
|
950
963
|
style.textContent = ".mMNkkW_root{align-items:center;display:inline-flex;position:relative}.mMNkkW_trigger{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;white-space:nowrap;border-radius:999px;padding:.35rem .6rem;font-size:.8rem;line-height:1}.mMNkkW_trigger:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l2)}.mMNkkW_panel{z-index:20;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-overlay);width:18rem;color:var(--dsw-alias-label-primary);border-radius:.6rem;flex-direction:column;gap:.6rem;padding:.75rem .85rem;display:flex;position:absolute;bottom:calc(100% + .5rem);right:0;box-shadow:0 8px 24px #0000002e}.mMNkkW_window{flex-direction:column;gap:.25rem;display:flex}.mMNkkW_row{justify-content:space-between;gap:.5rem;font-size:.85rem;display:flex}.mMNkkW_hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:.75rem}.mMNkkW_progress{width:100%;height:.35rem;accent-color:var(--dsw-alias-brand-primary)}.mMNkkW_limited{color:var(--dsw-alias-state-warn-primary);font-size:.75rem}.mMNkkW_warning{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-label-primary);border-radius:.4rem;padding:.4rem .5rem;font-size:.75rem}.mMNkkW_retry{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:.35rem;align-self:flex-start;padding:.25rem .5rem;font-size:.75rem}.mMNkkW_local{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:.2rem;padding-top:.5rem;display:flex}";
|
|
951
964
|
document.head.appendChild(style);
|
|
952
965
|
}
|
|
953
|
-
var pill_default = { "
|
|
966
|
+
var pill_default = { "window": "mMNkkW_window", "row": "mMNkkW_row", "retry": "mMNkkW_retry", "trigger": "mMNkkW_trigger", "progress": "mMNkkW_progress", "root": "mMNkkW_root", "panel": "mMNkkW_panel", "warning": "mMNkkW_warning", "local": "mMNkkW_local", "limited": "mMNkkW_limited", "hint": "mMNkkW_hint" };
|
|
954
967
|
|
|
955
968
|
// src/client/UsagePill.tsx
|
|
956
969
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
@@ -1133,7 +1146,11 @@ function apply(ctx) {
|
|
|
1133
1146
|
scope.slots.inject("settings.section", () => scope.slots.register({
|
|
1134
1147
|
name: "settings.section",
|
|
1135
1148
|
id: "dshopencodego",
|
|
1136
|
-
|
|
1149
|
+
// After the product rows. The built-ins run -10 (account) through 20
|
|
1150
|
+
// (agent presets); sharing 20 with `agent-presets` left the pair ordered
|
|
1151
|
+
// by registration timing, which drifts between boots. The host's own
|
|
1152
|
+
// tests use 1000 for "last".
|
|
1153
|
+
order: 1e3,
|
|
1137
1154
|
label: () => translate("nav"),
|
|
1138
1155
|
inject: () => ({
|
|
1139
1156
|
controller,
|