@klarkxy/dsh-model-hub 0.1.3 → 0.1.4

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.md CHANGED
@@ -24,7 +24,7 @@ Open **Plugins → Model Hub**.
24
24
  ## Limits
25
25
 
26
26
  - Only plugins that expose model settings appear.
27
- - If a setting changed elsewhere, refresh and choose again.
27
+ - Changes made elsewhere update the page automatically. If an edit conflicts with a newer change, refresh and choose again.
28
28
  - If the model list cannot load, use **Retry**. The last available list stays visible; warnings identify providers that could not be loaded while other providers remain usable.
29
29
  - Model selection guidance requires host tools that support choosing a subagent model. Existing conversations retain their saved model lists; start a new conversation to use an updated list.
30
30
  - Guidance does not force a model choice or add extra subtasks solely for variety.
@@ -24,7 +24,7 @@ dsh plugin --profile web add @klarkxy/dsh-model-hub
24
24
  ## 限制
25
25
 
26
26
  - 只显示提供了模型设置的插件。
27
- - 设置在别处被改动时,刷新后重新选择。
27
+ - 设置在别处改动时,页面会自动更新。编辑与较新的改动冲突时,请刷新后重新选择。
28
28
  - 模型列表读取失败时,点击「重试」。上次可用的列表会保留;部分提供方读取失败时会显示提示,其他提供方仍可使用。
29
29
  - 选模引导需要宿主工具支持选择子代理模型。已有会话保留各自的模型名单;修改名单后,新建会话才能使用更新后的名单。
30
30
  - 引导不强制模型选择,也不要求仅为增加模型种类而新增子任务。
@@ -1,28 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- //#region \0rolldown/runtime.js
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
- get: ((k) => from[k]).bind(null, key),
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
20
- value: mod,
21
- enumerable: true
22
- }) : target, mod));
23
- //#endregion
24
2
  let react = require("react");
25
- react = __toESM(react, 1);
26
3
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
27
4
  let react_dom = require("react-dom");
28
5
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -1316,25 +1293,18 @@ ${scope} {
1316
1293
  }
1317
1294
  //#endregion
1318
1295
  //#region ../dsh-plugin-kit/src/contracts.ts
1319
- /**
1320
- * Remote contribution for model-settings change notifications.
1321
- * Provided by `@klarkxy/dsh-model-hub` (`ModelSettingsChangesController`);
1322
- * subscribers degrade silently when that package is not installed.
1323
- * The stream carries invalidations only — `ready` is never a settings snapshot.
1324
- */
1325
- const MODEL_SETTINGS_CHANGES_REMOTE = {
1326
- package: "@klarkxy/dsh-model-hub",
1327
- descriptors: [{
1328
- id: "modelSettingsChanges/watch",
1329
- service: "modelSettingsChangesController",
1330
- namespace: "modelSettingsChanges",
1331
- method: "watch",
1332
- mode: "stream",
1333
- invocation: { kind: "direct" },
1334
- parameters: [],
1335
- cancellation: { parameter: "signal" }
1336
- }]
1337
- };
1296
+ /** `@klarkxy/dsh-git-commit` becomes `KlarkxyDshGitCommitModelSettingsChanges`. */
1297
+ function modelSettingsChangesIdentity(packageName) {
1298
+ const scoped = /^@([^/]+)\/(.+)$/.exec(packageName);
1299
+ const parts = (scoped ? `${scoped[1]}/${scoped[2]}` : packageName).split(/[^A-Za-z0-9]+/).filter(Boolean);
1300
+ if (!parts.length) throw new Error("Model settings package name has no RPC segment");
1301
+ const segment = `${parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")}ModelSettingsChanges`;
1302
+ if (!/^[A-Z][A-Za-z0-9]*$/.test(segment)) throw new Error(`Model settings sync name is not an RPC segment: ${segment}`);
1303
+ return {
1304
+ service: segment,
1305
+ namespace: segment
1306
+ };
1307
+ }
1338
1308
  //#endregion
1339
1309
  //#region ../dsh-plugin-kit/src/model-settings-client.ts
1340
1310
  /** This stream carries invalidations only; ready is never a settings snapshot. */
@@ -1349,21 +1319,44 @@ function parseModelSettingsChangeFrame(value) {
1349
1319
  };
1350
1320
  throw new Error("Invalid model settings change frame");
1351
1321
  }
1352
- /** One contribution mounted by Model Hub; consumers only inject its service. */
1353
- const modelSettingsChangesRemote = {
1354
- package: MODEL_SETTINGS_CHANGES_REMOTE.package,
1355
- descriptors: MODEL_SETTINGS_CHANGES_REMOTE.descriptors.map((descriptor) => ({
1356
- ...descriptor,
1357
- result: {
1358
- mode: "strict",
1359
- typeSymbol: "ModelSettings.ChangeFrame",
1360
- create: () => ({ parse: parseModelSettingsChangeFrame })
1361
- }
1362
- }))
1363
- };
1322
+ /** One owner's contribution. Each package mounts only its own endpoint. */
1323
+ function modelSettingsChangesRemote(packageName, identity = modelSettingsChangesIdentity(packageName)) {
1324
+ return {
1325
+ package: packageName,
1326
+ descriptors: [{
1327
+ id: `${identity.namespace}/watch`,
1328
+ service: identity.service,
1329
+ namespace: identity.namespace,
1330
+ method: "watch",
1331
+ mode: "stream",
1332
+ invocation: { kind: "direct" },
1333
+ parameters: [],
1334
+ cancellation: { parameter: "signal" },
1335
+ result: {
1336
+ mode: "strict",
1337
+ typeSymbol: "ModelSettings.ChangeFrame",
1338
+ create: () => ({ parse: parseModelSettingsChangeFrame })
1339
+ }
1340
+ }]
1341
+ };
1342
+ }
1343
+ /** Mount from a synchronous apply. Disposal waits for an in-flight mount and
1344
+ * then withdraws it, so the contribution cannot outlive the plugin. */
1345
+ function mountModelSettingsChanges(ctx, packageName) {
1346
+ const contribution = modelSettingsChangesRemote(packageName);
1347
+ ctx.inject(["remote"], (injected) => {
1348
+ const scope = injected;
1349
+ const mounting = scope.remote.$mount(contribution);
1350
+ mounting.catch(() => {});
1351
+ scope.effect(() => async () => {
1352
+ await (await mounting.catch(() => void 0))?.();
1353
+ });
1354
+ });
1355
+ }
1364
1356
  /** Native RemoteStream owns carrier reconnects; no timers or browser transport.
1365
1357
  * A factory shares one logical stream while at least one subscriber remains. */
1366
- function createModelSettingsSubscriber(ctx, namespace) {
1358
+ function createModelSettingsSubscriber(ctx, packageName, identity = modelSettingsChangesIdentity(packageName), accept = (ns) => ns === packageName) {
1359
+ const endpoint = identity;
1367
1360
  const listeners = /* @__PURE__ */ new Set();
1368
1361
  let injection;
1369
1362
  let current;
@@ -1389,12 +1382,18 @@ function createModelSettingsSubscriber(ctx, namespace) {
1389
1382
  };
1390
1383
  const start = () => {
1391
1384
  const life = ++lifecycle;
1392
- injection = ctx.inject(["remote", "remote.modelSettingsChanges"], (injected) => {
1385
+ injection = ctx.inject(["remote", `remote.${endpoint.namespace}`], (injected) => {
1393
1386
  if (life !== lifecycle || !listeners.size) return;
1394
1387
  const scope = injected;
1388
+ const service = scope.remote[endpoint.namespace];
1389
+ if (!service || !("watch" in service) || !service.watch) {
1390
+ report("Model settings sync service unavailable");
1391
+ return;
1392
+ }
1393
+ const watch = service.watch;
1395
1394
  const stream = scope.remote.$stream({
1396
1395
  name: "Model settings sync",
1397
- open: (signal) => scope.remote.modelSettingsChanges.watch(signal),
1396
+ open: (signal) => watch(signal),
1398
1397
  ended: (accepted) => /* @__PURE__ */ new Error(`Model settings sync stream ended ${accepted ? "after" : "before"} ready; refresh or reopen the page`)
1399
1398
  });
1400
1399
  const session = {
@@ -1429,7 +1428,7 @@ function createModelSettingsSubscriber(ctx, namespace) {
1429
1428
  invalidate();
1430
1429
  } else {
1431
1430
  if (!ready) throw new Error("Model settings sync change arrived before ready");
1432
- if (namespace === "*" || frame.ns === namespace) invalidate();
1431
+ if (accept(frame.ns)) invalidate();
1433
1432
  }
1434
1433
  }
1435
1434
  } catch (error) {
@@ -2588,11 +2587,10 @@ function HubPage({ view, api, locale, initialEntries = null, initialCatalog = nu
2588
2587
  ]
2589
2588
  });
2590
2589
  }
2591
- async function apply(ctx) {
2590
+ function apply(ctx) {
2592
2591
  const client = ctx;
2593
- const disposeRemote = await client.remote.$mount(modelSettingsChangesRemote);
2594
- client.effect(() => disposeRemote);
2595
- const changes = createModelSettingsSubscriber(ctx, "*");
2592
+ mountModelSettingsChanges(ctx, BUNDLE);
2593
+ const changes = createModelSettingsSubscriber(ctx, BUNDLE, modelSettingsChangesIdentity(BUNDLE), () => true);
2596
2594
  const call = async (endpoint, payload) => {
2597
2595
  const result = await client.connection.rpc.call(CHANNEL, endpoint, payload);
2598
2596
  if (!result?.ok) throw new Error(result?.error?.message || "Request failed");