@dan-ai-studio/dshopencodego 0.1.13 → 0.1.15
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 +3 -4
- package/README.md +3 -4
- package/lib/client.js +8 -22
- package/lib/index.js +1 -18
- package/lib/types/catalog/contract.js +0 -3
- package/lib/types/catalog/index.js +0 -5
- package/lib/types/catalog/metadata.d.ts +0 -8
- package/lib/types/catalog/metadata.js +0 -7
- package/lib/types/catalog/reading.js +0 -3
- package/lib/types/config.d.ts +7 -2
- package/lib/types/config.js +6 -1
- package/lib/types/models.d.ts +0 -8
- package/package.json +4 -2
package/README.en.md
CHANGED
|
@@ -120,11 +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
126
|
- **Go allowance** comes from OpenCode's own documentation (the "usage limits / estimated requests" tables) — **no API exposes it**. It is a transcribed table (source URL and date in the `src/go-limits.ts` header); pricing or promotion changes require updating it and shipping a release;
|
|
127
|
-
- **Capability marks**: badges on each row label **structured output / temperature control / open weights** exactly as models.dev declares them. Only a declared "yes" is marked — an unstated or declared "no" stays unmarked, the same rule the reasoning levels follow.
|
|
128
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.
|
|
129
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.
|
|
130
129
|
|
|
@@ -153,7 +152,7 @@ The `engines.dsh` field is informational for readers and package managers; **DSH
|
|
|
153
152
|
|
|
154
153
|
| Binding layer | Declared | Enforced by |
|
|
155
154
|
| --- | --- | --- |
|
|
156
|
-
| `peerDependencies` (
|
|
155
|
+
| `peerDependencies` (17 `@deepseek-ai/dsh-*` packages) | all `>=0.1.7-alpha.1 <0.1.8` | **DSH's gate, at plugin load time** |
|
|
157
156
|
| `@deepseek-ai/cordis` | `4.0.2 \|\| 4.0.3 \|\| 4.0.4` | the same gate |
|
|
158
157
|
| `engines.dsh` | `>=0.1.7-alpha.1 <0.1.8` | informational only; DSH never reads it |
|
|
159
158
|
| `engines.node` | `^22.19.0 \|\| >=24.0.0` | the package manager |
|
|
@@ -162,7 +161,7 @@ The `engines.dsh` field is informational for readers and package managers; **DSH
|
|
|
162
161
|
|
|
163
162
|
Things to keep in mind when maintaining this:
|
|
164
163
|
|
|
165
|
-
- **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.
|
|
166
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).
|
|
167
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.
|
|
168
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,11 +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
126
|
- **Go 额度**来自 OpenCode 官方文档的「使用限制 / 预估请求数」表,**没有接口提供**,是本插件转写的数据表(见 `src/go-limits.ts` 的注释:来源 URL 与转写日期);文档调整价格或促销时需要更新该表并随发版发布。
|
|
127
|
-
- **能力标记**:按 models.dev 的声明给每个模型加**结构化输出 / 温度控制 / 开源权重**徽标。只标注声明为"支持"的项——**未声明或声明不支持都不加标记**,与推理档位同一口径:不替文档下结论。
|
|
128
127
|
- **输入模态**:单独一行列出 models.dev 声明的输入方式(文本 / 图像 / 音频 / 视频 / PDF)。这是**模型自身的元数据**,不等于 DSH 能直传:DSH 的模型输入只原生支持文本与图像,音视频/PDF 走附件与工具读取路径;文档未声明时该行不显示。
|
|
129
128
|
- 筛选(按名称/ID、仅已启用、显示已弃用——**默认隐藏已弃用**)、排序(新发布优先 / 每月预估次数 / 输入单价 / 上下文 / 名称 / 已启用优先);列表是唯一视图,逐模型纵向排列。
|
|
130
129
|
|
|
@@ -153,7 +152,7 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
|
|
|
153
152
|
|
|
154
153
|
| 绑定层 | 声明 | 谁在把关 |
|
|
155
154
|
| --- | --- | --- |
|
|
156
|
-
| `peerDependencies`(
|
|
155
|
+
| `peerDependencies`(17 个 `@deepseek-ai/dsh-*`) | 均为 `>=0.1.7-alpha.1 <0.1.8` | **DSH 加载时的真门禁** |
|
|
157
156
|
| `@deepseek-ai/cordis` | `4.0.2 \|\| 4.0.3 \|\| 4.0.4` | 同一门禁 |
|
|
158
157
|
| `engines.dsh` | `>=0.1.7-alpha.1 <0.1.8` | 仅信息字段,DSH 不读 |
|
|
159
158
|
| `engines.node` | `^22.19.0 \|\| >=24.0.0` | 包管理器 |
|
|
@@ -162,7 +161,7 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
|
|
|
162
161
|
|
|
163
162
|
维护时需要注意:
|
|
164
163
|
|
|
165
|
-
- **必选与可选之分**:
|
|
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 二十余处)。
|
|
166
165
|
- **名义范围 ≠ 实测范围**:`0.1.7-alpha.1`、`alpha.2` 落在声明范围内,但本项目没有验证过;实际验证过的是 `0.1.7-rc.1`(开发依赖基线)与 `0.1.7-rc.2`(日常使用)。
|
|
167
166
|
- **上界就是跟版线**:`<0.1.8` 意味着 DSH 一旦发布 `0.1.8`,本插件必须同批发新版,否则所有用户加载失败。调整范围后用 `npm test` 验证即可(本地 mock 网关,零网络零 token)——范围以接口声明为准,不要用线上探测来"测"出一个范围。
|
|
168
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
|
@@ -87,9 +87,6 @@ function parseModel(value) {
|
|
|
87
87
|
...row["protocolSource"] === "builtin" || row["protocolSource"] === "online" || row["protocolSource"] === "inferred" || row["protocolSource"] === "override" ? { protocolSource: row["protocolSource"] } : {},
|
|
88
88
|
...typeof row["assumedLimits"] === "boolean" ? { assumedLimits: row["assumedLimits"] } : {},
|
|
89
89
|
...parseModalities(row["inputModalities"]),
|
|
90
|
-
...typeof row["structuredOutput"] === "boolean" ? { structuredOutput: row["structuredOutput"] } : {},
|
|
91
|
-
...typeof row["temperature"] === "boolean" ? { temperature: row["temperature"] } : {},
|
|
92
|
-
...typeof row["openWeights"] === "boolean" ? { openWeights: row["openWeights"] } : {},
|
|
93
90
|
...typeof row["configurationMissing"] === "string" ? { configurationMissing: row["configurationMissing"] } : {}
|
|
94
91
|
};
|
|
95
92
|
}
|
|
@@ -278,9 +275,6 @@ var en = {
|
|
|
278
275
|
modalityAudio: "Audio",
|
|
279
276
|
modalityVideo: "Video",
|
|
280
277
|
modalityPdf: "PDF",
|
|
281
|
-
capStructured: "Structured",
|
|
282
|
-
capTemperature: "Temp",
|
|
283
|
-
capOpenWeights: "Open",
|
|
284
278
|
iosInput: "in",
|
|
285
279
|
iosOutput: "out",
|
|
286
280
|
iosContext: "ctx",
|
|
@@ -347,9 +341,6 @@ var zh = {
|
|
|
347
341
|
modalityAudio: "\u97F3\u9891",
|
|
348
342
|
modalityVideo: "\u89C6\u9891",
|
|
349
343
|
modalityPdf: "PDF",
|
|
350
|
-
capStructured: "\u7ED3\u6784\u5316",
|
|
351
|
-
capTemperature: "\u6E29\u5EA6",
|
|
352
|
-
capOpenWeights: "\u5F00\u6E90",
|
|
353
344
|
iosInput: "\u5165",
|
|
354
345
|
iosOutput: "\u51FA",
|
|
355
346
|
iosContext: "\u4E0A\u4E0B\u6587",
|
|
@@ -443,13 +434,6 @@ function visibleModels(models, filter, visibility, locale) {
|
|
|
443
434
|
});
|
|
444
435
|
return sortRows(rows, filter.sort, visibility, locale);
|
|
445
436
|
}
|
|
446
|
-
function capabilityLabels(model, t) {
|
|
447
|
-
const labels = [];
|
|
448
|
-
if (model.structuredOutput === true) labels.push(t("capStructured"));
|
|
449
|
-
if (model.temperature === true) labels.push(t("capTemperature"));
|
|
450
|
-
if (model.openWeights === true) labels.push(t("capOpenWeights"));
|
|
451
|
-
return labels;
|
|
452
|
-
}
|
|
453
437
|
var MODALITY_KEYS = {
|
|
454
438
|
text: "modalityText",
|
|
455
439
|
image: "modalityImage",
|
|
@@ -470,7 +454,7 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id) + "]")
|
|
|
470
454
|
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)}";
|
|
471
455
|
document.head.appendChild(style);
|
|
472
456
|
}
|
|
473
|
-
var section_default = { "
|
|
457
|
+
var section_default = { "warn": "d7lz0W_warn", "itemMeta": "d7lz0W_itemMeta", "hint": "d7lz0W_hint", "input": "d7lz0W_input", "badge": "d7lz0W_badge", "name": "d7lz0W_name", "itemBody": "d7lz0W_itemBody", "itemMain": "d7lz0W_itemMain", "mono": "d7lz0W_mono", "button": "d7lz0W_button", "row": "d7lz0W_row", "root": "d7lz0W_root", "list": "d7lz0W_list", "title": "d7lz0W_title", "item": "d7lz0W_item", "itemModalities": "d7lz0W_itemModalities", "ok": "d7lz0W_ok", "select": "d7lz0W_select", "block": "d7lz0W_block", "number": "d7lz0W_number" };
|
|
474
458
|
|
|
475
459
|
// src/client/Section.tsx
|
|
476
460
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -651,7 +635,7 @@ var SectionController = class {
|
|
|
651
635
|
this.set({ saving: false });
|
|
652
636
|
}
|
|
653
637
|
}
|
|
654
|
-
/** Narrow or reorder the model
|
|
638
|
+
/** Narrow or reorder the model list; a view preference, never a write. */
|
|
655
639
|
setFilter(patch) {
|
|
656
640
|
this.set({ filter: { ...this.state.filter, ...patch } });
|
|
657
641
|
}
|
|
@@ -918,7 +902,6 @@ function Section({ controller, t, getLocale }) {
|
|
|
918
902
|
] }),
|
|
919
903
|
reading !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: section_default.list, children: rows.map((model) => {
|
|
920
904
|
const badge = badgeFor(model, t);
|
|
921
|
-
const capabilities = capabilityLabels(model, t).join(" \xB7 ");
|
|
922
905
|
const modalities = inputModalityLabels(model, t).join(" \xB7 ");
|
|
923
906
|
const offered = isOffered(model, visibility);
|
|
924
907
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: section_default.item, children: [
|
|
@@ -939,7 +922,6 @@ function Section({ controller, t, getLocale }) {
|
|
|
939
922
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: section_default.name, children: model.name }),
|
|
940
923
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: section_default.mono, children: model.id }),
|
|
941
924
|
model.releaseDate !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: section_default.hint, children: model.releaseDate }),
|
|
942
|
-
capabilities.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: section_default.badge, children: capabilities }),
|
|
943
925
|
badge.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: section_default.badge, children: badge })
|
|
944
926
|
] }),
|
|
945
927
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: section_default.itemMeta, children: [
|
|
@@ -968,7 +950,7 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id2) + "]"
|
|
|
968
950
|
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}";
|
|
969
951
|
document.head.appendChild(style);
|
|
970
952
|
}
|
|
971
|
-
var pill_default = { "progress": "mMNkkW_progress", "
|
|
953
|
+
var pill_default = { "progress": "mMNkkW_progress", "window": "mMNkkW_window", "limited": "mMNkkW_limited", "retry": "mMNkkW_retry", "panel": "mMNkkW_panel", "local": "mMNkkW_local", "hint": "mMNkkW_hint", "warning": "mMNkkW_warning", "trigger": "mMNkkW_trigger", "root": "mMNkkW_root", "row": "mMNkkW_row" };
|
|
972
954
|
|
|
973
955
|
// src/client/UsagePill.tsx
|
|
974
956
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
@@ -1151,7 +1133,11 @@ function apply(ctx) {
|
|
|
1151
1133
|
scope.slots.inject("settings.section", () => scope.slots.register({
|
|
1152
1134
|
name: "settings.section",
|
|
1153
1135
|
id: "dshopencodego",
|
|
1154
|
-
|
|
1136
|
+
// After the product rows. The built-ins run -10 (account) through 20
|
|
1137
|
+
// (agent presets); sharing 20 with `agent-presets` left the pair ordered
|
|
1138
|
+
// by registration timing, which drifts between boots. The host's own
|
|
1139
|
+
// tests use 1000 for "last".
|
|
1140
|
+
order: 1e3,
|
|
1155
1141
|
label: () => translate("nav"),
|
|
1156
1142
|
inject: () => ({
|
|
1157
1143
|
controller,
|
package/lib/index.js
CHANGED
|
@@ -213,9 +213,6 @@ function positiveInteger(value) {
|
|
|
213
213
|
function nonEmptyString(value) {
|
|
214
214
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
215
215
|
}
|
|
216
|
-
function declaredBoolean(value) {
|
|
217
|
-
return typeof value === "boolean" ? value : void 0;
|
|
218
|
-
}
|
|
219
216
|
function readInputModalities(metadata) {
|
|
220
217
|
const declared = record(metadata["modalities"])["input"];
|
|
221
218
|
if (!Array.isArray(declared)) return void 0;
|
|
@@ -354,9 +351,6 @@ function readOnlineMetadata(body, sources) {
|
|
|
354
351
|
inputModalities: readInputModalities(metadata),
|
|
355
352
|
reasoning,
|
|
356
353
|
thinkingLevelMap: reasoning ? thinkingLevels(metadata, exact?.api === api ? exact : sibling) : void 0,
|
|
357
|
-
structuredOutput: declaredBoolean(metadata["structured_output"]),
|
|
358
|
-
temperature: declaredBoolean(metadata["temperature"]),
|
|
359
|
-
openWeights: declaredBoolean(metadata["open_weights"]),
|
|
360
354
|
compat: compatFor(api, metadata, exact, sibling),
|
|
361
355
|
cost,
|
|
362
356
|
deprecated: metadata["status"] === "deprecated",
|
|
@@ -551,11 +545,6 @@ var OpencodeGoCatalog = class {
|
|
|
551
545
|
inputModalities: void 0,
|
|
552
546
|
reasoning: exact?.reasoning ?? false,
|
|
553
547
|
thinkingLevelMap: exact?.thinkingLevelMap,
|
|
554
|
-
// No source describes these, so the page says nothing instead of
|
|
555
|
-
// guessing: the installed catalog knows wire shapes, not capabilities.
|
|
556
|
-
structuredOutput: void 0,
|
|
557
|
-
temperature: void 0,
|
|
558
|
-
openWeights: void 0,
|
|
559
548
|
compat: exact?.compat ?? {},
|
|
560
549
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
561
550
|
deprecated: false,
|
|
@@ -1539,9 +1528,6 @@ function parseModel(value) {
|
|
|
1539
1528
|
...row["protocolSource"] === "builtin" || row["protocolSource"] === "online" || row["protocolSource"] === "inferred" || row["protocolSource"] === "override" ? { protocolSource: row["protocolSource"] } : {},
|
|
1540
1529
|
...typeof row["assumedLimits"] === "boolean" ? { assumedLimits: row["assumedLimits"] } : {},
|
|
1541
1530
|
...parseModalities(row["inputModalities"]),
|
|
1542
|
-
...typeof row["structuredOutput"] === "boolean" ? { structuredOutput: row["structuredOutput"] } : {},
|
|
1543
|
-
...typeof row["temperature"] === "boolean" ? { temperature: row["temperature"] } : {},
|
|
1544
|
-
...typeof row["openWeights"] === "boolean" ? { openWeights: row["openWeights"] } : {},
|
|
1545
1531
|
...typeof row["configurationMissing"] === "string" ? { configurationMissing: row["configurationMissing"] } : {}
|
|
1546
1532
|
};
|
|
1547
1533
|
}
|
|
@@ -1732,10 +1718,7 @@ function catalogReading(snapshot, visibility, listingFailure) {
|
|
|
1732
1718
|
},
|
|
1733
1719
|
protocolSource: fact.protocolSource,
|
|
1734
1720
|
assumedLimits: fact.assumedLimits,
|
|
1735
|
-
...fact.
|
|
1736
|
-
...fact.inputModalities === void 0 ? {} : { inputModalities: fact.inputModalities },
|
|
1737
|
-
...fact.temperature === void 0 ? {} : { temperature: fact.temperature },
|
|
1738
|
-
...fact.openWeights === void 0 ? {} : { openWeights: fact.openWeights }
|
|
1721
|
+
...fact.inputModalities === void 0 ? {} : { inputModalities: fact.inputModalities }
|
|
1739
1722
|
};
|
|
1740
1723
|
}),
|
|
1741
1724
|
...[...snapshot.unavailable].map(([id, reason]) => ({ id, name: id, configurationMissing: reason }))
|
|
@@ -73,9 +73,6 @@ function parseModel(value) {
|
|
|
73
73
|
? { protocolSource: row['protocolSource'] } : {},
|
|
74
74
|
...typeof row['assumedLimits'] === 'boolean' ? { assumedLimits: row['assumedLimits'] } : {},
|
|
75
75
|
...parseModalities(row['inputModalities']),
|
|
76
|
-
...typeof row['structuredOutput'] === 'boolean' ? { structuredOutput: row['structuredOutput'] } : {},
|
|
77
|
-
...typeof row['temperature'] === 'boolean' ? { temperature: row['temperature'] } : {},
|
|
78
|
-
...typeof row['openWeights'] === 'boolean' ? { openWeights: row['openWeights'] } : {},
|
|
79
76
|
...typeof row['configurationMissing'] === 'string' ? { configurationMissing: row['configurationMissing'] } : {},
|
|
80
77
|
};
|
|
81
78
|
}
|
|
@@ -209,11 +209,6 @@ export class OpencodeGoCatalog {
|
|
|
209
209
|
inputModalities: undefined,
|
|
210
210
|
reasoning: exact?.reasoning ?? false,
|
|
211
211
|
thinkingLevelMap: exact?.thinkingLevelMap,
|
|
212
|
-
// No source describes these, so the page says nothing instead of
|
|
213
|
-
// guessing: the installed catalog knows wire shapes, not capabilities.
|
|
214
|
-
structuredOutput: undefined,
|
|
215
|
-
temperature: undefined,
|
|
216
|
-
openWeights: undefined,
|
|
217
212
|
compat: exact?.compat ?? {},
|
|
218
213
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
219
214
|
deprecated: false,
|
|
@@ -44,14 +44,6 @@ export interface ModelFacts {
|
|
|
44
44
|
readonly inputModalities: readonly InputModality[] | undefined;
|
|
45
45
|
readonly reasoning: boolean;
|
|
46
46
|
readonly thinkingLevelMap: ThinkingLevelMap | undefined;
|
|
47
|
-
/**
|
|
48
|
-
* Declared capability facts, exactly as models.dev states them. `undefined`
|
|
49
|
-
* means the document says nothing about the capability, which is not the
|
|
50
|
-
* same answer as `false` and must never be rendered as "unsupported".
|
|
51
|
-
*/
|
|
52
|
-
readonly structuredOutput: boolean | undefined;
|
|
53
|
-
readonly temperature: boolean | undefined;
|
|
54
|
-
readonly openWeights: boolean | undefined;
|
|
55
47
|
readonly compat: Model<Api>['compat'];
|
|
56
48
|
readonly cost: ModelCost;
|
|
57
49
|
readonly deprecated: boolean;
|
|
@@ -29,10 +29,6 @@ function positiveInteger(value) {
|
|
|
29
29
|
function nonEmptyString(value) {
|
|
30
30
|
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
31
31
|
}
|
|
32
|
-
/** A capability the document states as yes or no; silence stays silence. */
|
|
33
|
-
function declaredBoolean(value) {
|
|
34
|
-
return typeof value === 'boolean' ? value : undefined;
|
|
35
|
-
}
|
|
36
32
|
/**
|
|
37
33
|
* Input modalities exactly as the document declares them, in display order.
|
|
38
34
|
*
|
|
@@ -245,9 +241,6 @@ export function readOnlineMetadata(body, sources) {
|
|
|
245
241
|
inputModalities: readInputModalities(metadata),
|
|
246
242
|
reasoning,
|
|
247
243
|
thinkingLevelMap: reasoning ? thinkingLevels(metadata, exact?.api === api ? exact : sibling) : undefined,
|
|
248
|
-
structuredOutput: declaredBoolean(metadata['structured_output']),
|
|
249
|
-
temperature: declaredBoolean(metadata['temperature']),
|
|
250
|
-
openWeights: declaredBoolean(metadata['open_weights']),
|
|
251
244
|
compat: compatFor(api, metadata, exact, sibling),
|
|
252
245
|
cost,
|
|
253
246
|
deprecated: metadata['status'] === 'deprecated',
|
|
@@ -43,10 +43,7 @@ export function catalogReading(snapshot, visibility, listingFailure) {
|
|
|
43
43
|
},
|
|
44
44
|
protocolSource: fact.protocolSource,
|
|
45
45
|
assumedLimits: fact.assumedLimits,
|
|
46
|
-
...fact.structuredOutput === undefined ? {} : { structuredOutput: fact.structuredOutput },
|
|
47
46
|
...fact.inputModalities === undefined ? {} : { inputModalities: fact.inputModalities },
|
|
48
|
-
...fact.temperature === undefined ? {} : { temperature: fact.temperature },
|
|
49
|
-
...fact.openWeights === undefined ? {} : { openWeights: fact.openWeights },
|
|
50
47
|
};
|
|
51
48
|
}),
|
|
52
49
|
...[...snapshot.unavailable].map(([id, reason]) => ({ id, name: id, configurationMissing: reason })),
|
package/lib/types/config.d.ts
CHANGED
|
@@ -77,8 +77,13 @@ export interface OpencodeGoConfig {
|
|
|
77
77
|
*/
|
|
78
78
|
retryPolicy?: RetryPolicyConfig;
|
|
79
79
|
}
|
|
80
|
-
/**
|
|
81
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Plain resolved values used by the adapter.
|
|
82
|
+
*
|
|
83
|
+
* The input side is a partial on purpose: a profile writes only the fields it
|
|
84
|
+
* overrides, and the schema's own defaults fill the rest.
|
|
85
|
+
*/
|
|
86
|
+
export declare const PlainConfig: z<Partial<OpencodeGoConfig>, OpencodeGoConfig>;
|
|
82
87
|
/** 0.1.7's Loader retains these references when profile fields change. */
|
|
83
88
|
export type LiveConfig = {
|
|
84
89
|
[K in keyof OpencodeGoConfig]-?: {
|
package/lib/types/config.js
CHANGED
|
@@ -44,7 +44,12 @@ const fields = {
|
|
|
44
44
|
modelProtocols: z.dict(z.string()).default({}),
|
|
45
45
|
retryPolicy: RetryPolicySchema,
|
|
46
46
|
};
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Plain resolved values used by the adapter.
|
|
49
|
+
*
|
|
50
|
+
* The input side is a partial on purpose: a profile writes only the fields it
|
|
51
|
+
* overrides, and the schema's own defaults fill the rest.
|
|
52
|
+
*/
|
|
48
53
|
export const PlainConfig = z.object(fields);
|
|
49
54
|
/** Runtime schema for {@link OpencodeGoConfig}; every field stays live. */
|
|
50
55
|
export const Config = z.object(Object.fromEntries(Object.entries(fields).map(([key, schema]) => [key, schema.volatile()])));
|
package/lib/types/models.d.ts
CHANGED
|
@@ -42,14 +42,6 @@ export interface ModelSummary {
|
|
|
42
42
|
* document declares none this build can name.
|
|
43
43
|
*/
|
|
44
44
|
readonly inputModalities?: readonly InputModality[];
|
|
45
|
-
/**
|
|
46
|
-
* Capabilities models.dev declares, in its own words. Each is absent when the
|
|
47
|
-
* document is silent about it — absence is "unstated", never "unsupported",
|
|
48
|
-
* so the page leaves the cell empty instead of showing a negative.
|
|
49
|
-
*/
|
|
50
|
-
readonly structuredOutput?: boolean;
|
|
51
|
-
readonly temperature?: boolean;
|
|
52
|
-
readonly openWeights?: boolean;
|
|
53
45
|
/** True when a capacity came from the route default rather than a source. */
|
|
54
46
|
readonly assumedLimits?: boolean;
|
|
55
47
|
/** Advertised by the gateway but not configurable, with the reason. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dan-ai-studio/dshopencodego",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"description": "OpenCode Go provider for DeepSeek Harness: live gateway catalog, per-conversation session header, usage",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -55,8 +55,9 @@
|
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "node scripts/build.mjs",
|
|
58
|
-
"typecheck": "tsc -p tsconfig.host.json --noEmit && tsc -p tsconfig.client.json --noEmit",
|
|
58
|
+
"typecheck": "tsc -p tsconfig.host.json --noEmit && tsc -p tsconfig.client.json --noEmit && tsc -p tsconfig.tests.json --noEmit",
|
|
59
59
|
"test": "vitest run",
|
|
60
|
+
"test:coverage": "vitest run --coverage",
|
|
60
61
|
"test:watch": "vitest",
|
|
61
62
|
"prepare": "npm run build",
|
|
62
63
|
"prepack": "npm run build"
|
|
@@ -130,6 +131,7 @@
|
|
|
130
131
|
"@types/node": "^22.20.0",
|
|
131
132
|
"@types/react": "~18.3.1",
|
|
132
133
|
"@types/react-dom": "~18.3.0",
|
|
134
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
133
135
|
"esbuild": "^0.28.2",
|
|
134
136
|
"jsdom": "^29.0.0",
|
|
135
137
|
"lightningcss": "^1.32.0",
|