@goodandready/dsh-ollama-cloud-provider 0.1.10 → 0.1.11

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,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.11 — 2026-10-29
4
+
5
+ - Compatibility declarations now use the same-channel range
6
+ `0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0` in `engines.dsh`,
7
+ `compatibility.dsh` and all DSH peer dependencies. Future `0.2.1-rc.*`
8
+ releases are admitted without a new plugin release; `dshReleases` remains the
9
+ tested engine matrix. A compatibility test guards the range, release list and
10
+ devDependency versions.
11
+ - The model catalog is stale-while-revalidate: a cached catalog is returned
12
+ immediately after its TTL and refreshed in the background; only the first
13
+ load waits for the network. A failed background refresh keeps the cached rows.
14
+ - Tool schema normalization is memoized per `parameters` object with a
15
+ `WeakMap`, so large MCP tool lists are not re-normalized on every request.
16
+
3
17
  ## 0.1.10 — 2026-10-28
4
18
 
5
19
  - Stabilized the native stream parser tests: a referenced keep-alive holds the
package/README.md CHANGED
@@ -103,17 +103,17 @@ npm pack
103
103
  Install the published package:
104
104
 
105
105
  ```bash
106
- dsh plugin --profile web add @goodandready/dsh-ollama-cloud-provider@0.1.10
106
+ dsh plugin --profile web add @goodandready/dsh-ollama-cloud-provider@0.1.11
107
107
  # DSH Desktop:
108
- dsh plugin --profile desktop add @goodandready/dsh-ollama-cloud-provider@0.1.10
108
+ dsh plugin --profile desktop add @goodandready/dsh-ollama-cloud-provider@0.1.11
109
109
  ```
110
110
 
111
111
  Or install the packed tarball into a profile:
112
112
 
113
113
  ```bash
114
- dsh plugin --profile web add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.10.tgz
114
+ dsh plugin --profile web add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.11.tgz
115
115
  # DSH Desktop:
116
- dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.10.tgz
116
+ dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.11.tgz
117
117
  ```
118
118
 
119
119
  Restart dsh (or DSH Desktop), then pick **Ollama Cloud** in the model picker.
package/README.ru.md CHANGED
@@ -103,17 +103,17 @@ npm pack
103
103
  Установка опубликованного пакета из npm:
104
104
 
105
105
  ```bash
106
- dsh plugin --profile web add @goodandready/dsh-ollama-cloud-provider@0.1.10
106
+ dsh plugin --profile web add @goodandready/dsh-ollama-cloud-provider@0.1.11
107
107
  # DSH Desktop:
108
- dsh plugin --profile desktop add @goodandready/dsh-ollama-cloud-provider@0.1.10
108
+ dsh plugin --profile desktop add @goodandready/dsh-ollama-cloud-provider@0.1.11
109
109
  ```
110
110
 
111
111
  Либо установка из упакованного tarball:
112
112
 
113
113
  ```bash
114
- dsh plugin --profile web add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.10.tgz
114
+ dsh plugin --profile web add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.11.tgz
115
115
  # DSH Desktop:
116
- dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.10.tgz
116
+ dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.11.tgz
117
117
  ```
118
118
 
119
119
  После установки перезапустите dsh (или DSH Desktop) и выберите **Ollama Cloud** в списке моделей.
package/README.zh.md CHANGED
@@ -102,17 +102,17 @@ npm pack
102
102
  从 npm 安装已发布版本:
103
103
 
104
104
  ```bash
105
- dsh plugin --profile web add @goodandready/dsh-ollama-cloud-provider@0.1.10
105
+ dsh plugin --profile web add @goodandready/dsh-ollama-cloud-provider@0.1.11
106
106
  # DSH 桌面端:
107
- dsh plugin --profile desktop add @goodandready/dsh-ollama-cloud-provider@0.1.10
107
+ dsh plugin --profile desktop add @goodandready/dsh-ollama-cloud-provider@0.1.11
108
108
  ```
109
109
 
110
110
  或通过打包文件安装:
111
111
 
112
112
  ```bash
113
- dsh plugin --profile web add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.10.tgz
113
+ dsh plugin --profile web add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.11.tgz
114
114
  # DSH 桌面端:
115
- dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.10.tgz
115
+ dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-ollama-cloud-provider-0.1.11.tgz
116
116
  ```
117
117
 
118
118
  安装完成后重启 dsh 或 DSH 桌面端,在模型列表中选择 **Ollama Cloud** 即可。
package/lib/index.js CHANGED
@@ -49,7 +49,7 @@ const DEFAULT_API_BASE = "https://ollama.com";
49
49
  const DEFAULT_OPENAI_BASE = "https://ollama.com/v1";
50
50
  const DEFAULT_USAGE_URL = "https://ollama.com/api/usage";
51
51
  const DEFAULT_BALANCE_URL = "https://ollama.com/api/balance";
52
- const DEFAULT_USER_AGENT = "dsh-ollama-cloud-provider/0.1.10";
52
+ const DEFAULT_USER_AGENT = "dsh-ollama-cloud-provider/0.1.11";
53
53
  const DEFAULT_CONTEXT_WINDOW = 131072;
54
54
  const DEFAULT_MAX_TOKENS = 32768;
55
55
  const DEFAULT_GENERATE_MAX_TOKENS = 131072;
@@ -772,6 +772,7 @@ const CATALOG_TTL_MS = 6e5;
772
772
  const CATALOG_TIMEOUT_MS = 15e3;
773
773
  const liveMeta = /* @__PURE__ */ new Map();
774
774
  const cache$1 = /* @__PURE__ */ new Map();
775
+ const inflight = /* @__PURE__ */ new Map();
775
776
  const FALLBACK_META = {
776
777
  id: "",
777
778
  name: "",
@@ -872,11 +873,21 @@ async function fetchJson(url, config, fetchImpl, signal) {
872
873
  * Refresh the live catalog (public, no key required) and return its ids.
873
874
  * Network failures keep the previous live metadata and fall back to the
874
875
  * generated snapshot, so the picker always has something to show.
876
+ *
877
+ * A cached catalog is served immediately, even after its TTL: the network
878
+ * refresh runs in the background so the picker never blocks on a stale entry.
879
+ * Only the first load (no cache) waits for the network.
875
880
  */
876
881
  async function refreshCatalog(config, fetchImpl = fetch, force = false) {
877
882
  const key = config.apiBase;
878
883
  const cached = cache$1.get(key);
879
- if (!force && cached !== void 0 && Date.now() - cached.at < CATALOG_TTL_MS) return cached.ids;
884
+ if (!force && cached !== void 0) {
885
+ if (Date.now() - cached.at >= CATALOG_TTL_MS) refreshInBackground(config, fetchImpl, key);
886
+ return cached.ids;
887
+ }
888
+ return refreshNow(config, fetchImpl, key, cached !== void 0);
889
+ }
890
+ async function refreshNow(config, fetchImpl, key, keepOnFailure) {
880
891
  const signal = AbortSignal.timeout(CATALOG_TIMEOUT_MS);
881
892
  const [modelsResult, tagsResult] = await Promise.allSettled([fetchJson(modelsUrlFor(config), config, fetchImpl, signal), fetchJson(tagsUrlFor(config), config, fetchImpl, signal)]);
882
893
  if (modelsResult.status === "fulfilled") {
@@ -902,6 +913,10 @@ async function refreshCatalog(config, fetchImpl = fetch, force = false) {
902
913
  return fromData;
903
914
  }
904
915
  }
916
+ if (keepOnFailure) {
917
+ const stale = cache$1.get(key);
918
+ if (stale !== void 0) return stale.ids;
919
+ }
905
920
  const fallback = Object.keys(GENERATED_MODELS);
906
921
  cache$1.set(key, {
907
922
  at: Date.now(),
@@ -909,8 +924,16 @@ async function refreshCatalog(config, fetchImpl = fetch, force = false) {
909
924
  });
910
925
  return fallback;
911
926
  }
927
+ function refreshInBackground(config, fetchImpl, key) {
928
+ if (inflight.has(key)) return;
929
+ const task = refreshNow(config, fetchImpl, key, true).catch(() => cache$1.get(key)?.ids ?? Object.keys(GENERATED_MODELS)).finally(() => {
930
+ inflight.delete(key);
931
+ });
932
+ inflight.set(key, task);
933
+ }
912
934
  function clearCatalogCache() {
913
935
  cache$1.clear();
936
+ inflight.clear();
914
937
  }
915
938
  function baseMeta(id) {
916
939
  const meta = liveMeta.get(id) ?? GENERATED_MODELS[id];
@@ -1245,6 +1268,15 @@ function toolArguments(raw) {
1245
1268
  return {};
1246
1269
  }
1247
1270
  }
1271
+ const normalizedParameterCache = /* @__PURE__ */ new WeakMap();
1272
+ function normalizedParameters(parameters) {
1273
+ if (typeof parameters !== "object" || parameters === null) return normalizeToolParameters(parameters);
1274
+ const cached = normalizedParameterCache.get(parameters);
1275
+ if (cached !== void 0) return cached.value;
1276
+ const value = normalizeToolParameters(parameters);
1277
+ normalizedParameterCache.set(parameters, { value });
1278
+ return value;
1279
+ }
1248
1280
  function buildTools(tools) {
1249
1281
  if (tools === void 0 || tools.length === 0) return void 0;
1250
1282
  return tools.map((tool) => ({
@@ -1252,7 +1284,7 @@ function buildTools(tools) {
1252
1284
  function: {
1253
1285
  name: tool.name,
1254
1286
  description: tool.description,
1255
- parameters: normalizeToolParameters(tool.parameters)
1287
+ parameters: normalizedParameters(tool.parameters)
1256
1288
  }
1257
1289
  }));
1258
1290
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-ollama-cloud-provider",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "Ollama Cloud LLM provider plugin for DeepSeek Harness (dsh).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -59,18 +59,18 @@
59
59
  "0.2.1-rc.3": "compatible",
60
60
  "0.2.1-rc.4": "compatible"
61
61
  },
62
- "dsh": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4"
62
+ "dsh": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0"
63
63
  }
64
64
  },
65
65
  "engines": {
66
66
  "node": ">=22",
67
- "dsh": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4"
67
+ "dsh": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0"
68
68
  },
69
69
  "scripts": {
70
70
  "build": "tsdown",
71
71
  "prepare": "tsdown 1>&2",
72
72
  "typecheck": "tsc --noEmit",
73
- "test": "node --import tsx --test tests/core.test.ts tests/usage.test.ts tests/adapter.test.ts tests/routes.test.ts tests/native.test.ts tests/commands.test.ts tests/tui-settings.test.ts tests/analytics.test.ts tests/apply.test.ts tests/account-rules.test.ts tests/request-log.test.ts tests/image-budget.test.ts tests/tool-schema.test.ts tests/tools.test.ts tests/plugin-updater.test.ts",
73
+ "test": "node --import tsx --test tests/core.test.ts tests/usage.test.ts tests/adapter.test.ts tests/routes.test.ts tests/native.test.ts tests/commands.test.ts tests/tui-settings.test.ts tests/analytics.test.ts tests/apply.test.ts tests/account-rules.test.ts tests/request-log.test.ts tests/image-budget.test.ts tests/tool-schema.test.ts tests/tools.test.ts tests/plugin-updater.test.ts tests/compat.test.ts",
74
74
  "check": "npm run typecheck && npm test && npm run build",
75
75
  "release": "npm run check && npm pack",
76
76
  "sync:models": "node scripts/sync-models.mjs"
@@ -85,17 +85,17 @@
85
85
  ],
86
86
  "peerDependencies": {
87
87
  "@deepseek-ai/cordis": "~4.0.4 || ~4.0.5",
88
- "@deepseek-ai/dsh-attachment": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
89
- "@deepseek-ai/dsh-client-locale": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
90
- "@deepseek-ai/dsh-client-ui-renderer": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
91
- "@deepseek-ai/dsh-client-ui-settings": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
92
- "@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
93
- "@deepseek-ai/dsh-commands": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
94
- "@deepseek-ai/dsh-credentials": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
95
- "@deepseek-ai/dsh-host-webserver": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
96
- "@deepseek-ai/dsh-launch-environment": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
97
- "@deepseek-ai/dsh-llm": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
98
- "@deepseek-ai/dsh-settings": "0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
88
+ "@deepseek-ai/dsh-attachment": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0",
89
+ "@deepseek-ai/dsh-client-locale": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0",
90
+ "@deepseek-ai/dsh-client-ui-renderer": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0",
91
+ "@deepseek-ai/dsh-client-ui-settings": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0",
92
+ "@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0",
93
+ "@deepseek-ai/dsh-commands": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0",
94
+ "@deepseek-ai/dsh-credentials": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0",
95
+ "@deepseek-ai/dsh-host-webserver": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0",
96
+ "@deepseek-ai/dsh-launch-environment": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0",
97
+ "@deepseek-ai/dsh-llm": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0",
98
+ "@deepseek-ai/dsh-settings": "0.2.0-rc.2 || >=0.2.1-rc.2 <0.2.2-0",
99
99
  "@deepseek-ai/schemastery": "~3.18.4 || ~3.18.5",
100
100
  "react": "^18.2.0"
101
101
  },