@dsh-plus/subagent-model 0.3.20 → 0.3.22
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/lib/client.js +187 -150
- package/package.json +2 -2
- package/src/client/card.tsx +123 -69
- package/src/client/client.ts +2 -2
- package/src/client/styles.ts +2 -2
- package/src/index.ts +3 -3
- package/src/service.ts +1 -1
package/lib/client.js
CHANGED
|
@@ -4,9 +4,9 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
-
let react = require("react");
|
|
8
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
|
-
let
|
|
8
|
+
let react = require("react");
|
|
9
|
+
require("@deepseek-ai/dsh-client-ui-primitives");
|
|
10
10
|
//#region ../shared/src/client/card.tsx
|
|
11
11
|
const IDLE_STATUS = {
|
|
12
12
|
kind: "idle",
|
|
@@ -15,60 +15,68 @@ window.__ModuleLoader__.load({
|
|
|
15
15
|
function CardChrome(props) {
|
|
16
16
|
const p = props.prefix;
|
|
17
17
|
const badge = props.statusBadge;
|
|
18
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
19
|
-
className: `${p}-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
28
|
-
className: `${p}-headText`,
|
|
29
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
30
|
-
className: `${p}-name`,
|
|
18
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
19
|
+
className: `${p}-section`,
|
|
20
|
+
"aria-label": props.title,
|
|
21
|
+
children: [
|
|
22
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
23
|
+
className: `${p}-sectionHead`,
|
|
24
|
+
children: [
|
|
25
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
26
|
+
className: `${p}-sectionTitle`,
|
|
31
27
|
children: props.title
|
|
32
|
-
}),
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
role: "status",
|
|
53
|
-
children: props.readOnlyNotice
|
|
54
|
-
}) : null,
|
|
55
|
-
props.children,
|
|
56
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57
|
-
className: `${p}-footer`,
|
|
58
|
-
children: [props.status !== void 0 && props.status.kind !== "idle" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
59
|
-
className: `${p}-status${props.status.kind === "error" ? ` ${p}-statusError` : ""}`,
|
|
28
|
+
}),
|
|
29
|
+
badge !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
30
|
+
className: `${p}-sectionBadge ${badge.on ? `${p}-statusOn` : `${p}-statusOff`}`,
|
|
31
|
+
children: badge.text
|
|
32
|
+
}) : null,
|
|
33
|
+
props.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
34
|
+
className: `${p}-pending`,
|
|
35
|
+
children: props.dirtyLabel
|
|
36
|
+
}) : null
|
|
37
|
+
]
|
|
38
|
+
}),
|
|
39
|
+
props.description === "" ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
40
|
+
className: `${p}-sectionDesc`,
|
|
41
|
+
children: props.description
|
|
42
|
+
}),
|
|
43
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
44
|
+
className: `${p}-sectionBody`,
|
|
45
|
+
children: [
|
|
46
|
+
props.readOnlyNotice !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
47
|
+
className: `${p}-readOnly`,
|
|
60
48
|
role: "status",
|
|
61
|
-
children: props.
|
|
62
|
-
}) : null,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
49
|
+
children: props.readOnlyNotice
|
|
50
|
+
}) : null,
|
|
51
|
+
props.children,
|
|
52
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
53
|
+
className: `${p}-sectionFooter`,
|
|
54
|
+
children: [props.status !== void 0 && props.status.kind !== "idle" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
55
|
+
className: `${p}-status${props.status.kind === "error" ? ` ${p}-statusError` : ""}`,
|
|
56
|
+
role: "status",
|
|
57
|
+
children: props.status.text
|
|
58
|
+
}) : null, props.actions.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
59
|
+
type: "button",
|
|
60
|
+
className: `${p}-btn ${action.variant === "primary" ? `${p}-btnPrimary` : `${p}-btnGhost`}`,
|
|
61
|
+
disabled: action.disabled === true,
|
|
62
|
+
onClick: action.onClick,
|
|
63
|
+
children: action.label
|
|
64
|
+
}, action.key))]
|
|
65
|
+
})
|
|
66
|
+
]
|
|
67
|
+
})
|
|
68
|
+
]
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/** 取值未到达时的占位:与 CardChrome 同形态,避免宿主页里闪一次卡片外壳。 */
|
|
72
|
+
function CardLoading(props) {
|
|
73
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
74
|
+
className: `${props.prefix}-section`,
|
|
75
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
76
|
+
className: `${props.prefix}-readOnly`,
|
|
77
|
+
role: "status",
|
|
78
|
+
children: props.text
|
|
79
|
+
})
|
|
72
80
|
});
|
|
73
81
|
}
|
|
74
82
|
//#endregion
|
|
@@ -76,19 +84,14 @@ window.__ModuleLoader__.load({
|
|
|
76
84
|
/** dsh-plus 聚合 bundle 的包名(各插件 row 均经其补丁层插入 profile)。 */
|
|
77
85
|
const DSH_PLUS_BUNDLE = "@dsh-plus/bundle-main";
|
|
78
86
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
87
|
+
* 把一张配置卡片注册进插件页的两个配置槽位。
|
|
88
|
+
* 两个槽位都由 0.2.1-alpha.1 的插件页声明,任一缺席即报错——不做版本探测。
|
|
81
89
|
*/
|
|
82
90
|
function injectPluginConfigCard(slots, reg) {
|
|
83
91
|
const base = {
|
|
84
92
|
locale: reg.ns,
|
|
85
93
|
inject: reg.inject
|
|
86
94
|
};
|
|
87
|
-
slots.inject("settings.plugin.item", () => slots.register({
|
|
88
|
-
name: "settings.plugin.item",
|
|
89
|
-
key: reg.ns,
|
|
90
|
-
...base
|
|
91
|
-
}, reg.component));
|
|
92
95
|
slots.inject("plugins.row.config", () => slots.register({
|
|
93
96
|
name: "plugins.row.config",
|
|
94
97
|
key: `${DSH_PLUS_BUNDLE}#${reg.rowId}`,
|
|
@@ -101,6 +104,17 @@ window.__ModuleLoader__.load({
|
|
|
101
104
|
}, reg.component));
|
|
102
105
|
}
|
|
103
106
|
//#endregion
|
|
107
|
+
//#region ../shared/src/client/draft.ts
|
|
108
|
+
/**
|
|
109
|
+
* 单命名空间 staged 草稿(简单配置卡片共用):读 scope 快照、播种草稿、
|
|
110
|
+
* 脏判定、保存(revision fencing + 重新装载)与状态行。
|
|
111
|
+
*
|
|
112
|
+
* 语义与官方 staged 表单一致:Host 更新不覆盖在途编辑,只有保存才写回;
|
|
113
|
+
* 保存成功后按 Host 解析值重置草稿。`from`/`patch` 参与 effect 与 useMemo
|
|
114
|
+
* 依赖,必须是模块级稳定函数(不要内联箭头函数)。
|
|
115
|
+
* @module @dsh-plus/shared/client/draft
|
|
116
|
+
*/
|
|
117
|
+
//#endregion
|
|
104
118
|
//#region ../shared/src/client/fields.tsx
|
|
105
119
|
/**
|
|
106
120
|
* 勾选行:自绘圆角扁平开关(switch),对齐官方 WebUI 无原生 checkbox 的
|
|
@@ -296,33 +310,33 @@ window.__ModuleLoader__.load({
|
|
|
296
310
|
//#endregion
|
|
297
311
|
//#region ../shared/src/client/styles.ts
|
|
298
312
|
/**
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
313
|
+
* 配置分节样式工厂(各插件 client 的公共收编版)。
|
|
314
|
+
*
|
|
315
|
+
* 目标宿主 dsh 0.2.1-alpha.1:插件页把配置视图放进已有页面级内边距的容器里
|
|
316
|
+
* (`div.detailSections[data-plugin-config]` 或 `section.detailSection[data-plugin-config]`),
|
|
317
|
+
* 外层无边框——故这里输出的是**无边框分节**(小节标题 13px/600、字段 12px 0、
|
|
318
|
+
* 横向零内边距、页脚非 sticky),度量对齐官方设置页
|
|
319
|
+
* (`@deepseek-ai/dsh-client-ui-primitives` 的 settings-form)。
|
|
320
|
+
*
|
|
321
|
+
* 移动端与可达性(767px 断点 + pointer:coarse,对齐 ui-mobile-fit 约定):
|
|
302
322
|
* - 窄屏 input/textarea 16px(防 iOS 聚焦缩放)、可点目标 ≥44px;
|
|
303
|
-
* -
|
|
304
|
-
* - 展开态 body 底部 sticky 保存栏(长表单滚动中始终可达)。
|
|
323
|
+
* - 页脚按钮等宽换行、状态文字独占一行。
|
|
305
324
|
* 沿用官方 data-plugin / data-plugin-css 约定(HMR 据此卸载),不覆盖上游选择器。
|
|
306
325
|
* @module @dsh-plus/shared/client/styles
|
|
307
326
|
*/
|
|
308
|
-
/**
|
|
327
|
+
/** 生成全套分节 CSS;prefix 为插件类名前缀(如 'dne'),extra 为插件特有规则。 */
|
|
309
328
|
function cardCss(prefix, extra = "") {
|
|
310
329
|
return `
|
|
311
|
-
.${prefix}-
|
|
312
|
-
.${prefix}-
|
|
313
|
-
.${prefix}-
|
|
314
|
-
.${prefix}-
|
|
315
|
-
.${prefix}-
|
|
316
|
-
.${prefix}-
|
|
317
|
-
.${prefix}-
|
|
318
|
-
.${prefix}-description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}
|
|
319
|
-
.${prefix}-chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s;display:inline-flex}
|
|
320
|
-
.${prefix}-chevronOpen{transform:rotate(180deg)}
|
|
330
|
+
.${prefix}-section{box-sizing:border-box;flex-direction:column;width:100%;min-width:0;padding:16px 0;display:flex}
|
|
331
|
+
.${prefix}-sectionHead{align-items:center;gap:8px;min-width:0;display:flex}
|
|
332
|
+
.${prefix}-sectionTitle{min-width:0;color:var(--dsw-alias-label-primary);flex:1;margin:0;font-size:13px;font-weight:600;line-height:1.5}
|
|
333
|
+
.${prefix}-sectionBadge{white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
|
|
334
|
+
.${prefix}-sectionDesc{color:var(--dsw-alias-label-tertiary);margin:4px 0 0;font-size:12px;line-height:1.5}
|
|
335
|
+
.${prefix}-sectionBody{flex-direction:column;min-width:0;display:flex}
|
|
336
|
+
.${prefix}-sectionFooter{align-items:center;gap:8px;padding-top:16px;display:flex;flex-wrap:wrap}
|
|
321
337
|
.${prefix}-pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
|
|
322
|
-
.${prefix}-statusBadge{white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
|
|
323
338
|
.${prefix}-statusOn{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary)}
|
|
324
339
|
.${prefix}-statusOff{color:var(--dsw-alias-label-tertiary)}
|
|
325
|
-
.${prefix}-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}
|
|
326
340
|
.${prefix}-field{flex-direction:column;gap:6px;padding:12px 0;display:flex}
|
|
327
341
|
.${prefix}-field+.${prefix}-field{border-top:1px solid var(--dsw-alias-border-l2)}
|
|
328
342
|
.${prefix}-head{align-items:center;gap:8px;display:flex}
|
|
@@ -351,7 +365,6 @@ window.__ModuleLoader__.load({
|
|
|
351
365
|
.${prefix}-groupLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600;padding:12px 0 2px;margin:0}
|
|
352
366
|
.${prefix}-readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}
|
|
353
367
|
.${prefix}-warn{color:var(--dsw-alias-label-error);margin:12px 0 0;font-size:12px;line-height:1.5}
|
|
354
|
-
.${prefix}-footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex;flex-wrap:wrap}
|
|
355
368
|
.${prefix}-status{min-width:0;color:var(--dsw-alias-label-secondary);flex:1;margin:0;font-size:12px;line-height:1.5}
|
|
356
369
|
.${prefix}-statusError{color:var(--dsw-alias-label-error)}
|
|
357
370
|
.${prefix}-btn{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}
|
|
@@ -361,14 +374,10 @@ window.__ModuleLoader__.load({
|
|
|
361
374
|
.${prefix}-btn:disabled{opacity:.4;cursor:default}
|
|
362
375
|
.${prefix}-btn:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}
|
|
363
376
|
@media (max-width:767px){
|
|
364
|
-
.${prefix}-body{margin:0 10px}
|
|
365
|
-
.${prefix}-header{padding:12px 12px}
|
|
366
377
|
.${prefix}-input,.${prefix}-select{font-size:16px;height:40px}
|
|
367
378
|
.${prefix}-checkRow{min-height:44px;padding:8px 0}
|
|
368
|
-
.${prefix}-footer{position:sticky;bottom:0;background:var(--dsw-alias-bg-layer-2);margin:0 -10px;padding:10px 10px 6px;border-top:1px solid var(--dsw-alias-border-l2);border-bottom-left-radius:12px;border-bottom-right-radius:12px}
|
|
369
379
|
.${prefix}-status{flex-basis:100%;flex:none}
|
|
370
380
|
.${prefix}-btn{min-height:44px;flex:1;min-width:96px}
|
|
371
|
-
.${prefix}-statusBadge{display:none}
|
|
372
381
|
}
|
|
373
382
|
@media (pointer:coarse){
|
|
374
383
|
.${prefix}-btn{min-height:44px}
|
|
@@ -455,8 +464,8 @@ ${extra}
|
|
|
455
464
|
//#endregion
|
|
456
465
|
//#region src/client/card.tsx
|
|
457
466
|
/**
|
|
458
|
-
* 「子代理模型配置」配置卡片:经 injectPluginConfigCard
|
|
459
|
-
*
|
|
467
|
+
* 「子代理模型配置」配置卡片:经 injectPluginConfigCard 注册(插件页 plugins.row.config /
|
|
468
|
+
* plugins.bundle.config,view 分发 summary/page)。
|
|
460
469
|
* 外壳与基础控件走 @dsh-plus/shared/client 套件(CardChrome/CheckRow/SelectField)。
|
|
461
470
|
* 配置读写经共享层 ctx.remote.settings 直连(0.1.7 起 settingsScope 已由 configForms
|
|
462
471
|
* 取代):value 为 schema 解析后的命名空间值
|
|
@@ -585,16 +594,83 @@ ${extra}
|
|
|
585
594
|
]
|
|
586
595
|
});
|
|
587
596
|
}
|
|
597
|
+
/** 目录状态行:拉取失败给重试入口,拉取中与空行集各给一行提示。 */
|
|
598
|
+
function CatalogStatus(props) {
|
|
599
|
+
if (props.catalogFailed) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
600
|
+
className: "dsm-banner",
|
|
601
|
+
role: "status",
|
|
602
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: props.t("catalogError") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
603
|
+
type: "button",
|
|
604
|
+
className: "dsm-bannerRetry",
|
|
605
|
+
onClick: props.onRetry,
|
|
606
|
+
children: props.t("catalogRetry")
|
|
607
|
+
})]
|
|
608
|
+
});
|
|
609
|
+
if (props.catalog === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
610
|
+
className: "dsm-empty",
|
|
611
|
+
role: "status",
|
|
612
|
+
children: props.t("catalogLoading")
|
|
613
|
+
});
|
|
614
|
+
if (props.rowCount === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
615
|
+
className: "dsm-empty",
|
|
616
|
+
role: "status",
|
|
617
|
+
children: props.t("noRows")
|
|
618
|
+
});
|
|
619
|
+
return null;
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* 子代理 provider 目录(挂载后拉取一次;失败保留重试入口,重试即回到未加载态)。
|
|
623
|
+
* 与草稿播种共用同一个 catalog:目录到达后由调用方补缺失的空行。
|
|
624
|
+
*/
|
|
625
|
+
function useCatalog() {
|
|
626
|
+
const [catalog, setCatalog] = (0, react.useState)(null);
|
|
627
|
+
const [catalogFailed, setCatalogFailed] = (0, react.useState)(false);
|
|
628
|
+
(0, react.useEffect)(() => {
|
|
629
|
+
if (catalog !== null) return;
|
|
630
|
+
let alive = true;
|
|
631
|
+
fetchCatalog().then((loaded) => {
|
|
632
|
+
if (!alive) return;
|
|
633
|
+
setCatalog(loaded);
|
|
634
|
+
setCatalogFailed(false);
|
|
635
|
+
}).catch(() => {
|
|
636
|
+
if (alive) setCatalogFailed(true);
|
|
637
|
+
});
|
|
638
|
+
return () => {
|
|
639
|
+
alive = false;
|
|
640
|
+
};
|
|
641
|
+
}, [catalog]);
|
|
642
|
+
return {
|
|
643
|
+
catalog,
|
|
644
|
+
catalogFailed,
|
|
645
|
+
retry: () => {
|
|
646
|
+
setCatalog(null);
|
|
647
|
+
setCatalogFailed(false);
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
/** 卡片动作:放弃(回到 Host 值)与保存(无效行或只读时禁用)。 */ function cardActions(options) {
|
|
652
|
+
const { t } = options;
|
|
653
|
+
return [{
|
|
654
|
+
key: "discard",
|
|
655
|
+
label: t("discard"),
|
|
656
|
+
disabled: !options.dirty || options.saving,
|
|
657
|
+
onClick: options.onDiscard
|
|
658
|
+
}, {
|
|
659
|
+
key: "save",
|
|
660
|
+
label: t(options.saving ? "saving" : "save"),
|
|
661
|
+
variant: "primary",
|
|
662
|
+
disabled: !options.dirty || options.invalid || options.saving || options.disabled,
|
|
663
|
+
onClick: options.onSave
|
|
664
|
+
}];
|
|
665
|
+
}
|
|
588
666
|
function SubagentModelCard(props) {
|
|
589
667
|
const { t, scope, api } = props;
|
|
590
668
|
const snapshot = (0, react.useSyncExternalStore)((listener) => scope.subscribe(listener), () => scope.getSnapshot());
|
|
591
669
|
const value = snapshot.value;
|
|
592
|
-
const [open, setOpen] = (0, react.useState)(props.view === "page");
|
|
593
670
|
const [draft, setDraft] = (0, react.useState)(null);
|
|
594
|
-
const [catalog, setCatalog] = (0, react.useState)(null);
|
|
595
|
-
const [catalogFailed, setCatalogFailed] = (0, react.useState)(false);
|
|
596
671
|
const [saving, setSaving] = (0, react.useState)(false);
|
|
597
672
|
const [status, setStatus] = (0, react.useState)(IDLE_STATUS);
|
|
673
|
+
const { catalog, catalogFailed, retry: retryCatalog } = useCatalog();
|
|
598
674
|
(0, react.useEffect)(() => {
|
|
599
675
|
if (value === void 0) return;
|
|
600
676
|
setDraft((current) => {
|
|
@@ -613,20 +689,6 @@ ${extra}
|
|
|
613
689
|
} : current;
|
|
614
690
|
});
|
|
615
691
|
}, [value, catalog]);
|
|
616
|
-
(0, react.useEffect)(() => {
|
|
617
|
-
if (!open || catalog !== null) return;
|
|
618
|
-
let alive = true;
|
|
619
|
-
fetchCatalog().then((loaded) => {
|
|
620
|
-
if (!alive) return;
|
|
621
|
-
setCatalog(loaded);
|
|
622
|
-
setCatalogFailed(false);
|
|
623
|
-
}).catch(() => {
|
|
624
|
-
if (alive) setCatalogFailed(true);
|
|
625
|
-
});
|
|
626
|
-
return () => {
|
|
627
|
-
alive = false;
|
|
628
|
-
};
|
|
629
|
-
}, [open, catalog]);
|
|
630
692
|
const dirty = (0, react.useMemo)(() => value !== void 0 && draft !== null && JSON.stringify(toPatch(draft)) !== JSON.stringify(toPatch(draftFrom(value, catalog))), [
|
|
631
693
|
value,
|
|
632
694
|
draft,
|
|
@@ -634,12 +696,9 @@ ${extra}
|
|
|
634
696
|
]);
|
|
635
697
|
const invalid = (0, react.useMemo)(() => draft !== null && Object.values(draft.rows).some((row) => row.model.length > 0 && row.provider.length === 0), [draft]);
|
|
636
698
|
if (props.view === "summary") return t("summaryLine");
|
|
637
|
-
if (value === void 0 || draft === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
className: "dsm-empty",
|
|
641
|
-
children: t("loading")
|
|
642
|
-
})
|
|
699
|
+
if (value === void 0 || draft === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardLoading, {
|
|
700
|
+
prefix: "dsm",
|
|
701
|
+
text: t("loading")
|
|
643
702
|
});
|
|
644
703
|
const edit = (key, editValue) => {
|
|
645
704
|
setDraft({
|
|
@@ -673,10 +732,6 @@ ${extra}
|
|
|
673
732
|
});
|
|
674
733
|
}).finally(() => setSaving(false));
|
|
675
734
|
};
|
|
676
|
-
const onRetryCatalog = () => {
|
|
677
|
-
setCatalog(null);
|
|
678
|
-
setCatalogFailed(false);
|
|
679
|
-
};
|
|
680
735
|
const disabled = !snapshot.writable;
|
|
681
736
|
const rowNames = Object.keys(draft.rows).sort();
|
|
682
737
|
const providerCount = (catalog?.providers ?? []).length;
|
|
@@ -684,8 +739,6 @@ ${extra}
|
|
|
684
739
|
prefix: "dsm",
|
|
685
740
|
title: t("title"),
|
|
686
741
|
description: t("description"),
|
|
687
|
-
open,
|
|
688
|
-
onToggle: setOpen,
|
|
689
742
|
statusBadge: {
|
|
690
743
|
text: t(draft.enabled ? "enabledOn" : "enabledOff"),
|
|
691
744
|
on: draft.enabled
|
|
@@ -694,21 +747,18 @@ ${extra}
|
|
|
694
747
|
dirtyLabel: t("unsaved"),
|
|
695
748
|
readOnlyNotice: disabled ? t("readOnly") : void 0,
|
|
696
749
|
status,
|
|
697
|
-
actions:
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
750
|
+
actions: cardActions({
|
|
751
|
+
t,
|
|
752
|
+
dirty,
|
|
753
|
+
invalid,
|
|
754
|
+
saving,
|
|
755
|
+
disabled,
|
|
756
|
+
onDiscard: () => {
|
|
702
757
|
setDraft(draftFrom(value, catalog));
|
|
703
758
|
setStatus(IDLE_STATUS);
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
label: t(saving ? "saving" : "save"),
|
|
708
|
-
variant: "primary",
|
|
709
|
-
disabled: !dirty || invalid || saving || disabled,
|
|
710
|
-
onClick: onSave
|
|
711
|
-
}],
|
|
759
|
+
},
|
|
760
|
+
onSave
|
|
761
|
+
}),
|
|
712
762
|
children: [
|
|
713
763
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckRow, {
|
|
714
764
|
prefix: "dsm",
|
|
@@ -718,26 +768,13 @@ ${extra}
|
|
|
718
768
|
disabled,
|
|
719
769
|
onEdit: (v) => edit("enabled", v)
|
|
720
770
|
}),
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
children: t("catalogRetry")
|
|
729
|
-
})]
|
|
730
|
-
}) : null,
|
|
731
|
-
catalog === null && !catalogFailed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
732
|
-
className: "dsm-empty",
|
|
733
|
-
role: "status",
|
|
734
|
-
children: t("catalogLoading")
|
|
735
|
-
}) : null,
|
|
736
|
-
rowNames.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
737
|
-
className: "dsm-empty",
|
|
738
|
-
role: "status",
|
|
739
|
-
children: t("noRows")
|
|
740
|
-
}) : null,
|
|
771
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CatalogStatus, {
|
|
772
|
+
t,
|
|
773
|
+
catalog,
|
|
774
|
+
catalogFailed,
|
|
775
|
+
rowCount: rowNames.length,
|
|
776
|
+
onRetry: retryCatalog
|
|
777
|
+
}),
|
|
741
778
|
rowNames.map((name) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowBlock, {
|
|
742
779
|
name,
|
|
743
780
|
row: draft.rows[name] ?? { ...EMPTY_ROW },
|
|
@@ -823,7 +860,8 @@ ${extra}
|
|
|
823
860
|
*/
|
|
824
861
|
const PLUGIN_ID = "@dsh-plus/subagent-model";
|
|
825
862
|
const cardCssAll = cardCss("dsm", `
|
|
826
|
-
.dsm-row{border:1px solid var(--dsw-alias-border-l2);
|
|
863
|
+
.dsm-row{border-top:1px solid var(--dsw-alias-border-l2);margin:0;padding:10px 0 2px}
|
|
864
|
+
.dsm-row:first-of-type{border-top:0}
|
|
827
865
|
.dsm-rowHead{align-items:center;gap:8px;padding:8px 0 2px;display:flex}
|
|
828
866
|
.dsm-rowName{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;font-weight:600;line-height:1.5}
|
|
829
867
|
.dsm-rowHint{color:var(--dsw-alias-label-tertiary);margin:0 0 4px;font-size:12px;line-height:1.5}
|
|
@@ -831,7 +869,6 @@ ${extra}
|
|
|
831
869
|
.dsm-bannerRetry{color:inherit;font:inherit;cursor:pointer;background:0 0;border:none;flex:none;padding:0;font-weight:600}
|
|
832
870
|
.dsm-empty{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}
|
|
833
871
|
@media (max-width:767px){
|
|
834
|
-
.dsm-row{padding:2px 8px 8px}
|
|
835
872
|
.dsm-rowHead{flex-wrap:wrap}
|
|
836
873
|
}
|
|
837
874
|
`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-plus/subagent-model",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.22",
|
|
4
4
|
"description": "dsh-plus service+ui plugin: 为 subagent/subagent_fork 等子代理按提供商配置模型与思考程度(或继承主代理)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"src"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@dsh-plus/shared": "0.1.
|
|
22
|
+
"@dsh-plus/shared": "0.1.32"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"@deepseek-ai/cordis": "^4.0.4",
|
package/src/client/card.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 「子代理模型配置」配置卡片:经 injectPluginConfigCard
|
|
3
|
-
*
|
|
2
|
+
* 「子代理模型配置」配置卡片:经 injectPluginConfigCard 注册(插件页 plugins.row.config /
|
|
3
|
+
* plugins.bundle.config,view 分发 summary/page)。
|
|
4
4
|
* 外壳与基础控件走 @dsh-plus/shared/client 套件(CardChrome/CheckRow/SelectField)。
|
|
5
5
|
* 配置读写经共享层 ctx.remote.settings 直连(0.1.7 起 settingsScope 已由 configForms
|
|
6
6
|
* 取代):value 为 schema 解析后的命名空间值
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import {
|
|
14
|
+
type CardAction,
|
|
14
15
|
CardChrome,
|
|
16
|
+
CardLoading,
|
|
15
17
|
type CardStatusState,
|
|
16
18
|
CheckRow,
|
|
17
19
|
IDLE_STATUS,
|
|
@@ -147,6 +149,105 @@ function RowBlock(props: RowBlockProps): ReactElement {
|
|
|
147
149
|
)
|
|
148
150
|
}
|
|
149
151
|
|
|
152
|
+
/** 目录状态行:拉取失败给重试入口,拉取中与空行集各给一行提示。 */
|
|
153
|
+
function CatalogStatus(props: {
|
|
154
|
+
t: Translate
|
|
155
|
+
catalog: ModelCatalog | null
|
|
156
|
+
catalogFailed: boolean
|
|
157
|
+
rowCount: number
|
|
158
|
+
onRetry(): void
|
|
159
|
+
}): ReactElement | null {
|
|
160
|
+
if (props.catalogFailed) {
|
|
161
|
+
return (
|
|
162
|
+
<div className="dsm-banner" role="status">
|
|
163
|
+
<span>{props.t('catalogError')}</span>
|
|
164
|
+
<button type="button" className="dsm-bannerRetry" onClick={props.onRetry}>
|
|
165
|
+
{props.t('catalogRetry')}
|
|
166
|
+
</button>
|
|
167
|
+
</div>
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
if (props.catalog === null) {
|
|
171
|
+
return (
|
|
172
|
+
<p className="dsm-empty" role="status">
|
|
173
|
+
{props.t('catalogLoading')}
|
|
174
|
+
</p>
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
if (props.rowCount === 0) {
|
|
178
|
+
return (
|
|
179
|
+
<p className="dsm-empty" role="status">
|
|
180
|
+
{props.t('noRows')}
|
|
181
|
+
</p>
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
return null
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* 子代理 provider 目录(挂载后拉取一次;失败保留重试入口,重试即回到未加载态)。
|
|
189
|
+
* 与草稿播种共用同一个 catalog:目录到达后由调用方补缺失的空行。
|
|
190
|
+
*/
|
|
191
|
+
function useCatalog(): {
|
|
192
|
+
catalog: ModelCatalog | null
|
|
193
|
+
catalogFailed: boolean
|
|
194
|
+
retry(): void
|
|
195
|
+
} {
|
|
196
|
+
const [catalog, setCatalog] = useState<ModelCatalog | null>(null)
|
|
197
|
+
const [catalogFailed, setCatalogFailed] = useState(false)
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
if (catalog !== null) return
|
|
200
|
+
let alive = true
|
|
201
|
+
fetchCatalog()
|
|
202
|
+
.then((loaded) => {
|
|
203
|
+
if (!alive) return
|
|
204
|
+
setCatalog(loaded)
|
|
205
|
+
setCatalogFailed(false)
|
|
206
|
+
})
|
|
207
|
+
.catch(() => {
|
|
208
|
+
if (alive) setCatalogFailed(true)
|
|
209
|
+
})
|
|
210
|
+
return () => {
|
|
211
|
+
alive = false
|
|
212
|
+
}
|
|
213
|
+
}, [catalog])
|
|
214
|
+
return {
|
|
215
|
+
catalog,
|
|
216
|
+
catalogFailed,
|
|
217
|
+
retry: () => {
|
|
218
|
+
setCatalog(null)
|
|
219
|
+
setCatalogFailed(false)
|
|
220
|
+
},
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** 卡片动作:放弃(回到 Host 值)与保存(无效行或只读时禁用)。 */ function cardActions(options: {
|
|
225
|
+
t: Translate
|
|
226
|
+
dirty: boolean
|
|
227
|
+
invalid: boolean
|
|
228
|
+
saving: boolean
|
|
229
|
+
disabled: boolean
|
|
230
|
+
onDiscard(): void
|
|
231
|
+
onSave(): void
|
|
232
|
+
}): CardAction[] {
|
|
233
|
+
const { t } = options
|
|
234
|
+
return [
|
|
235
|
+
{
|
|
236
|
+
key: 'discard',
|
|
237
|
+
label: t('discard'),
|
|
238
|
+
disabled: !options.dirty || options.saving,
|
|
239
|
+
onClick: options.onDiscard,
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
key: 'save',
|
|
243
|
+
label: t(options.saving ? 'saving' : 'save'),
|
|
244
|
+
variant: 'primary',
|
|
245
|
+
disabled: !options.dirty || options.invalid || options.saving || options.disabled,
|
|
246
|
+
onClick: options.onSave,
|
|
247
|
+
},
|
|
248
|
+
]
|
|
249
|
+
}
|
|
250
|
+
|
|
150
251
|
export function SubagentModelCard(props: CardProps): ReactElement | string | null {
|
|
151
252
|
const { t, scope, api } = props
|
|
152
253
|
const snapshot = useSyncExternalStore(
|
|
@@ -154,13 +255,10 @@ export function SubagentModelCard(props: CardProps): ReactElement | string | nul
|
|
|
154
255
|
() => scope.getSnapshot(),
|
|
155
256
|
)
|
|
156
257
|
const value = snapshot.value as ConfigValue | undefined
|
|
157
|
-
// 0.1.6-alpha.2 插件页 page 视图为表单落地页,默认展开;旧槽位无 view,保持折叠。
|
|
158
|
-
const [open, setOpen] = useState(props.view === 'page')
|
|
159
258
|
const [draft, setDraft] = useState<Draft | null>(null)
|
|
160
|
-
const [catalog, setCatalog] = useState<ModelCatalog | null>(null)
|
|
161
|
-
const [catalogFailed, setCatalogFailed] = useState(false)
|
|
162
259
|
const [saving, setSaving] = useState(false)
|
|
163
260
|
const [status, setStatus] = useState<CardStatusState>(IDLE_STATUS)
|
|
261
|
+
const { catalog, catalogFailed, retry: retryCatalog } = useCatalog()
|
|
164
262
|
|
|
165
263
|
// 播种草稿(行集 = 已配置条目);catalog 到达后只补缺失的 provider 空行,
|
|
166
264
|
// 不覆盖在途编辑;后续 Host 更新同样不覆盖。
|
|
@@ -180,23 +278,6 @@ export function SubagentModelCard(props: CardProps): ReactElement | string | nul
|
|
|
180
278
|
})
|
|
181
279
|
}, [value, catalog])
|
|
182
280
|
|
|
183
|
-
useEffect(() => {
|
|
184
|
-
if (!open || catalog !== null) return
|
|
185
|
-
let alive = true
|
|
186
|
-
fetchCatalog()
|
|
187
|
-
.then((loaded) => {
|
|
188
|
-
if (!alive) return
|
|
189
|
-
setCatalog(loaded)
|
|
190
|
-
setCatalogFailed(false)
|
|
191
|
-
})
|
|
192
|
-
.catch(() => {
|
|
193
|
-
if (alive) setCatalogFailed(true)
|
|
194
|
-
})
|
|
195
|
-
return () => {
|
|
196
|
-
alive = false
|
|
197
|
-
}
|
|
198
|
-
}, [open, catalog])
|
|
199
|
-
|
|
200
281
|
const dirty = useMemo(
|
|
201
282
|
() =>
|
|
202
283
|
value !== undefined &&
|
|
@@ -215,11 +296,7 @@ export function SubagentModelCard(props: CardProps): ReactElement | string | nul
|
|
|
215
296
|
if (props.view === 'summary') return t('summaryLine')
|
|
216
297
|
|
|
217
298
|
if (value === undefined || draft === null) {
|
|
218
|
-
return (
|
|
219
|
-
<li className="dsm-card">
|
|
220
|
-
<p className="dsm-empty">{t('loading')}</p>
|
|
221
|
-
</li>
|
|
222
|
-
)
|
|
299
|
+
return <CardLoading prefix="dsm" text={t('loading')} />
|
|
223
300
|
}
|
|
224
301
|
const edit = <K extends keyof Draft>(key: K, editValue: Draft[K]): void => {
|
|
225
302
|
setDraft({ ...draft, [key]: editValue })
|
|
@@ -248,10 +325,6 @@ export function SubagentModelCard(props: CardProps): ReactElement | string | nul
|
|
|
248
325
|
})
|
|
249
326
|
.finally(() => setSaving(false))
|
|
250
327
|
}
|
|
251
|
-
const onRetryCatalog = (): void => {
|
|
252
|
-
setCatalog(null)
|
|
253
|
-
setCatalogFailed(false)
|
|
254
|
-
}
|
|
255
328
|
|
|
256
329
|
const disabled = !snapshot.writable
|
|
257
330
|
const rowNames = Object.keys(draft.rows).sort()
|
|
@@ -261,31 +334,23 @@ export function SubagentModelCard(props: CardProps): ReactElement | string | nul
|
|
|
261
334
|
prefix="dsm"
|
|
262
335
|
title={t('title')}
|
|
263
336
|
description={t('description')}
|
|
264
|
-
open={open}
|
|
265
|
-
onToggle={setOpen}
|
|
266
337
|
statusBadge={{ text: t(draft.enabled ? 'enabledOn' : 'enabledOff'), on: draft.enabled }}
|
|
267
338
|
dirty={dirty}
|
|
268
339
|
dirtyLabel={t('unsaved')}
|
|
269
340
|
readOnlyNotice={disabled ? t('readOnly') : undefined}
|
|
270
341
|
status={status}
|
|
271
|
-
actions={
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
key: 'save',
|
|
283
|
-
label: t(saving ? 'saving' : 'save'),
|
|
284
|
-
variant: 'primary',
|
|
285
|
-
disabled: !dirty || invalid || saving || disabled,
|
|
286
|
-
onClick: onSave,
|
|
342
|
+
actions={cardActions({
|
|
343
|
+
t,
|
|
344
|
+
dirty,
|
|
345
|
+
invalid,
|
|
346
|
+
saving,
|
|
347
|
+
disabled,
|
|
348
|
+
onDiscard: () => {
|
|
349
|
+
setDraft(draftFrom(value, catalog))
|
|
350
|
+
setStatus(IDLE_STATUS)
|
|
287
351
|
},
|
|
288
|
-
|
|
352
|
+
onSave,
|
|
353
|
+
})}
|
|
289
354
|
>
|
|
290
355
|
<CheckRow
|
|
291
356
|
prefix="dsm"
|
|
@@ -295,24 +360,13 @@ export function SubagentModelCard(props: CardProps): ReactElement | string | nul
|
|
|
295
360
|
disabled={disabled}
|
|
296
361
|
onEdit={(v) => edit('enabled', v)}
|
|
297
362
|
/>
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
) : null}
|
|
306
|
-
{catalog === null && !catalogFailed ? (
|
|
307
|
-
<p className="dsm-empty" role="status">
|
|
308
|
-
{t('catalogLoading')}
|
|
309
|
-
</p>
|
|
310
|
-
) : null}
|
|
311
|
-
{rowNames.length === 0 ? (
|
|
312
|
-
<p className="dsm-empty" role="status">
|
|
313
|
-
{t('noRows')}
|
|
314
|
-
</p>
|
|
315
|
-
) : null}
|
|
363
|
+
<CatalogStatus
|
|
364
|
+
t={t}
|
|
365
|
+
catalog={catalog}
|
|
366
|
+
catalogFailed={catalogFailed}
|
|
367
|
+
rowCount={rowNames.length}
|
|
368
|
+
onRetry={retryCatalog}
|
|
369
|
+
/>
|
|
316
370
|
{rowNames.map((name) => (
|
|
317
371
|
<RowBlock
|
|
318
372
|
key={name}
|
package/src/client/client.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 浏览器半入口:注册 locale 字典 + 注册「子代理模型配置」卡片
|
|
3
|
-
* (injectPluginConfigCard
|
|
4
|
-
*
|
|
3
|
+
* (injectPluginConfigCard 两槽位:插件页 plugins.row.config /
|
|
4
|
+
* plugins.bundle.config)。
|
|
5
5
|
* 构建产物为 window.__ModuleLoader__.load({id, factory}) 形式的 CJS factory
|
|
6
6
|
* (包装见 tsdown.config.ts);样式沿用官方 data-plugin-css 约定,HMR 据此卸载。
|
|
7
7
|
*
|
package/src/client/styles.ts
CHANGED
|
@@ -9,7 +9,8 @@ import { cardCss, injectCardStyle } from '@dsh-plus/shared/client'
|
|
|
9
9
|
export const PLUGIN_ID = '@dsh-plus/subagent-model'
|
|
10
10
|
|
|
11
11
|
const extraCss = `
|
|
12
|
-
.dsm-row{border:1px solid var(--dsw-alias-border-l2);
|
|
12
|
+
.dsm-row{border-top:1px solid var(--dsw-alias-border-l2);margin:0;padding:10px 0 2px}
|
|
13
|
+
.dsm-row:first-of-type{border-top:0}
|
|
13
14
|
.dsm-rowHead{align-items:center;gap:8px;padding:8px 0 2px;display:flex}
|
|
14
15
|
.dsm-rowName{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;font-weight:600;line-height:1.5}
|
|
15
16
|
.dsm-rowHint{color:var(--dsw-alias-label-tertiary);margin:0 0 4px;font-size:12px;line-height:1.5}
|
|
@@ -17,7 +18,6 @@ const extraCss = `
|
|
|
17
18
|
.dsm-bannerRetry{color:inherit;font:inherit;cursor:pointer;background:0 0;border:none;flex:none;padding:0;font-weight:600}
|
|
18
19
|
.dsm-empty{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}
|
|
19
20
|
@media (max-width:767px){
|
|
20
|
-
.dsm-row{padding:2px 8px 8px}
|
|
21
21
|
.dsm-rowHead{flex-wrap:wrap}
|
|
22
22
|
}
|
|
23
23
|
`
|
package/src/index.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* 主代理显式选择的路由(官方 subagent-model-selection 的 model 字段)优先,
|
|
6
6
|
* 本插件只补"未选择时的强制默认"。
|
|
7
7
|
* 配置经 settings 用户层($DSH_HOME/settings.yaml)持久化并热生效;
|
|
8
|
-
* 配置 UI 位于 webui
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* 配置 UI 位于 webui 侧边栏「插件」页的 bundle 行配置页(plugins.row.config /
|
|
9
|
+
* plugins.bundle.config 两槽位,见 @dsh-plus/shared/client/config-slots);
|
|
10
|
+
* 模型目录经 host webServer 同源端点下发。
|
|
11
11
|
* @module @dsh-plus/subagent-model
|
|
12
12
|
*/
|
|
13
13
|
import type { Context } from '@deepseek-ai/cordis'
|
package/src/service.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - 委托挂钩:包装 ctx.subagents.start/startContinuable,按 provider 名
|
|
7
7
|
* (未命中回落 default 条目)注入 agentOptions(provider/model/effort)。
|
|
8
8
|
* - 自定义端点:ctx.webServer 仅注册模型目录路由(配置读写已走官方
|
|
9
|
-
* remote.settings
|
|
9
|
+
* remote.settings 直连,配置卡片(两槽位注册)见 client 半)。
|
|
10
10
|
* @module @dsh-plus/subagent-model
|
|
11
11
|
*/
|
|
12
12
|
import type { Context } from '@deepseek-ai/cordis'
|