dsh-model-params 0.1.4 → 0.1.6

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.
Files changed (3) hide show
  1. package/README.md +17 -1
  2. package/lib/client.js +57 -6
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## English
4
4
 
5
- **Current release: 0.1.4** — models.dev parameter assistant inside the official DeepSeek Harness Models settings page.
5
+ **Current release: 0.1.6** — Portable settings transport: the plugin now resolves the official pi-ai settings scope on both the `settingsScope` (≤ 0.1.5) and `configForms` (≥ 0.1.7-rc.1) hosts, so the provider card keeps working across the rename.
6
6
 
7
7
  For every configured `llm-pi-ai` provider card (custom OpenAI-compatible gateways such as the ones you add under Settings → Models), a `models.dev 参数` control fetches the official models.dev records for the provider's configured model ids and proposes the metadata pi-ai needs: context window, max output tokens, and reasoning-effort levels. One click writes the merged `models` array back to that provider profile through the official revision-aware Settings API.
8
8
 
@@ -25,6 +25,22 @@ models.dev model ids may collide across catalog providers; the matcher prefers t
25
25
  - Host 只负责拉取并缓存 models.dev 目录(6 小时,支持公共代理或 `HTTPS_PROXY` 回退),不接触任何 LLM 配置与凭据。
26
26
  - models.dev 未收录的模型 id 会明确标记,不写入。
27
27
 
28
+ ## Install
29
+
30
+ ```powershell
31
+ dsh plugin --profile web add dsh-model-params
32
+ ```
33
+
34
+ Restart the existing DSH Web process afterwards: the Host scans the browser plugin roster at startup, so the provider-card control appears only after that restart. Then open **Settings → Models** and look for `models.dev 参数` on a configured provider card.
35
+
36
+ Local development, from this package directory:
37
+
38
+ ```powershell
39
+ dsh plugin --profile web add .
40
+ ```
41
+
42
+ Either form records the package in the profile's `dsh.profile.bundles`, which is what mounts the Host lookup route and serves the client bundle.
43
+
28
44
  ## Development
29
45
 
30
46
  From this directory run:
package/lib/client.js CHANGED
@@ -22,6 +22,30 @@ window.__ModuleLoader__.load({
22
22
 
23
23
  const PI_NS = 'llm-pi-ai'
24
24
  const API = '/api/model-params/lookup'
25
+
26
+ // ── settings-scope portability (DSH 0.1.5 ↔ 0.1.7-rc.1) ──────────────────
27
+ //
28
+ // This plugin owns no settings namespace: it extends the OFFICIAL pi-ai
29
+ // Models page and writes that provider's own `llm-pi-ai` section. The two
30
+ // supported hosts expose the same scope CONTRACT under different names:
31
+ //
32
+ // ≤ 0.1.5 settingsScope.bind({ namespace }) → SettingsScope<T>
33
+ // ≥ 0.1.7 configForms.get(entryId) → ConfigForm<T>
34
+ //
35
+ // Both return getSnapshot()/subscribe()/set()/unset()/mutate() over the same
36
+ // { status, value, base, user, revision, writable, mode } snapshot, so the
37
+ // resolved object is used unchanged by the provider card. On 0.1.7-rc.1 a
38
+ // form's namespace IS the profile entry id, and the pi-ai LLM entry is
39
+ // mounted as `llm-pi-ai`, so the same key resolves on either host.
40
+ // `ctx.get` (never a direct property read) keeps the lookup safe when only
41
+ // one service is mounted: an uninjected property read throws.
42
+ function resolveSettingsScopeFrom(ctx, namespace) {
43
+ const binder = ctx.get('settingsScope')
44
+ if (binder && typeof binder.bind === 'function') return binder.bind({ namespace })
45
+ const forms = ctx.get('configForms')
46
+ if (forms && typeof forms.get === 'function') return forms.get(namespace)
47
+ return undefined
48
+ }
25
49
  const FETCH_TIMEOUT_MS = 20000
26
50
  const CSS_ID = 'dsh-model-params/style'
27
51
  const LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']
@@ -274,15 +298,42 @@ window.__ModuleLoader__.load({
274
298
  const api = remote && remote.settings
275
299
  ? { settings: { mutate: (payload) => remote.settings.mutate(payload.ns, payload.ops, payload.expectedRevision).then((result) => ({ result })) } }
276
300
  : undefined
277
- const scope = ctx.settingsScope.bind({ namespace: PI_NS })
278
- return ctx.slots.inject('settings.models.provider-card', () => ctx.slots.register(
279
- { name: 'settings.models.provider-card', key: PI_NS },
280
- (props) => e(ModelParamsExtension, { ...props, api, scope }),
281
- ))
301
+ // Version-portable scope on the official pi-ai namespace. Both transport
302
+ // names are awaited WITHOUT gating activation, and whichever this host
303
+ // mounts resolves; see resolveSettingsScopeFrom.
304
+ let scope
305
+ let cardRegistered = false
306
+ // The provider card MUST register from inside a context that has the
307
+ // settings transport, i.e. from the `ctx.inject([...], cb)` callback and on
308
+ // the CHILD context it hands us. Registering
309
+ // `settings.models.provider-card` from the bare apply context puts the
310
+ // entry where the Models page's ledger never sees it, so the extension
311
+ // never renders even though `register` returned normally. (dshmarket, an
312
+ // out-of-repo bundle that does render its card, uses this nested shape.)
313
+ const registerCard = (sctx) => {
314
+ if (cardRegistered) return
315
+ const resolved = resolveSettingsScopeFrom(sctx, PI_NS)
316
+ if (resolved === undefined) return
317
+ scope = resolved
318
+ cardRegistered = true
319
+ sctx.slots.inject('settings.models.provider-card', () => sctx.slots.register(
320
+ { name: 'settings.models.provider-card', key: PI_NS },
321
+ (props) => e(ModelParamsExtension, { ...props, api, scope }),
322
+ ))
323
+ }
324
+ // The first wait fires only when settingsScope exists; the second covers a
325
+ // host that renamed the transport, and its guard keeps the card from
326
+ // registering twice when both names exist.
327
+ ctx.inject(['settingsScope'], registerCard)
328
+ ctx.inject(['configForms'], (sctx) => { if (!cardRegistered) registerCard(sctx) })
282
329
  }
283
330
 
284
331
  exports.name = 'dsh-model-params'
285
- exports.inject = ['slots', 'settingsScope', 'remote', 'remote.settings']
332
+ // 'settingsScope' and 'configForms' are alternatives, not both-required:
333
+ // cordis resolves each inject name as its own gate, so activation succeeds on
334
+ // whichever settings transport the host mounts (0.1.5 vs 0.1.7-rc.1). The
335
+ // dotted remote names stay declared — dropping them fails the loader fiber.
336
+ exports.inject = ['slots', 'remote', 'remote.settings']
286
337
  exports.apply = apply
287
338
  return module.exports
288
339
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-model-params",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "EN: models.dev parameter assistant for the official DeepSeek Harness Models page: per-provider one-click context / max-output / reasoning-effort fill. ZH: 官方模型设置页的 models.dev 参数助手:按 provider 一键补全上下文、max 输出与推理档位。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",