@dsh-plus/subagent-model 0.3.21 → 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 +56 -152
- package/package.json +2 -2
- package/src/client/card.tsx +8 -17
- package/src/client/client.ts +2 -2
- package/src/client/styles.ts +2 -7
- package/src/index.ts +3 -3
- package/src/service.ts +1 -1
package/lib/client.js
CHANGED
|
@@ -4,50 +4,18 @@ 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",
|
|
13
13
|
text: ""
|
|
14
14
|
};
|
|
15
|
-
/** 状态行 + 动作按钮(两种形态共用,类名随形态切换度量)。 */
|
|
16
|
-
function CardFoot(props) {
|
|
17
|
-
const p = props.prefix;
|
|
18
|
-
const section = props.variant === "section";
|
|
19
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
20
|
-
className: section ? `${p}-sectionFooter` : `${p}-footer`,
|
|
21
|
-
children: [props.status !== void 0 && props.status.kind !== "idle" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
22
|
-
className: `${p}-status${props.status.kind === "error" ? ` ${p}-statusError` : ""}`,
|
|
23
|
-
role: "status",
|
|
24
|
-
children: props.status.text
|
|
25
|
-
}) : null, props.actions.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
26
|
-
type: "button",
|
|
27
|
-
className: `${p}-btn ${action.variant === "primary" ? `${p}-btnPrimary` : `${p}-btnGhost`}`,
|
|
28
|
-
disabled: action.disabled === true,
|
|
29
|
-
onClick: action.onClick,
|
|
30
|
-
children: action.label
|
|
31
|
-
}, action.key))]
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
/** 只读提示 + 字段区 + 页脚(两种形态共用)。 */
|
|
35
|
-
function CardBody(props) {
|
|
36
|
-
const p = props.prefix;
|
|
37
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
38
|
-
props.readOnlyNotice !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
39
|
-
className: `${p}-readOnly`,
|
|
40
|
-
role: "status",
|
|
41
|
-
children: props.readOnlyNotice
|
|
42
|
-
}) : null,
|
|
43
|
-
props.children,
|
|
44
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardFoot, { ...props })
|
|
45
|
-
] });
|
|
46
|
-
}
|
|
47
15
|
function CardChrome(props) {
|
|
48
16
|
const p = props.prefix;
|
|
49
17
|
const badge = props.statusBadge;
|
|
50
|
-
|
|
18
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
51
19
|
className: `${p}-section`,
|
|
52
20
|
"aria-label": props.title,
|
|
53
21
|
children: [
|
|
@@ -72,50 +40,37 @@ window.__ModuleLoader__.load({
|
|
|
72
40
|
className: `${p}-sectionDesc`,
|
|
73
41
|
children: props.description
|
|
74
42
|
}),
|
|
75
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
43
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
76
44
|
className: `${p}-sectionBody`,
|
|
77
|
-
children:
|
|
45
|
+
children: [
|
|
46
|
+
props.readOnlyNotice !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
47
|
+
className: `${p}-readOnly`,
|
|
48
|
+
role: "status",
|
|
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
|
+
]
|
|
78
67
|
})
|
|
79
68
|
]
|
|
80
69
|
});
|
|
81
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
82
|
-
className: `${p}-card${props.open ? ` ${p}-cardOpen` : ""}`,
|
|
83
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
84
|
-
type: "button",
|
|
85
|
-
className: `${p}-header`,
|
|
86
|
-
"aria-expanded": props.open,
|
|
87
|
-
"aria-label": props.title,
|
|
88
|
-
onClick: () => props.onToggle(!props.open),
|
|
89
|
-
children: [
|
|
90
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
91
|
-
className: `${p}-headText`,
|
|
92
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
93
|
-
className: `${p}-name`,
|
|
94
|
-
children: props.title
|
|
95
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
96
|
-
className: `${p}-description`,
|
|
97
|
-
children: props.description
|
|
98
|
-
})]
|
|
99
|
-
}),
|
|
100
|
-
badge !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
101
|
-
className: `${p}-statusBadge ${badge.on ? `${p}-statusOn` : `${p}-statusOff`}`,
|
|
102
|
-
children: badge.text
|
|
103
|
-
}) : null,
|
|
104
|
-
props.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
105
|
-
className: `${p}-pending`,
|
|
106
|
-
children: props.dirtyLabel
|
|
107
|
-
}) : null,
|
|
108
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { className: `${p}-chevron${props.open ? ` ${p}-chevronOpen` : ""}` })
|
|
109
|
-
]
|
|
110
|
-
}), props.open ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
111
|
-
className: `${p}-body`,
|
|
112
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardBody, { ...props })
|
|
113
|
-
}) : null]
|
|
114
|
-
});
|
|
115
70
|
}
|
|
116
71
|
/** 取值未到达时的占位:与 CardChrome 同形态,避免宿主页里闪一次卡片外壳。 */
|
|
117
72
|
function CardLoading(props) {
|
|
118
|
-
|
|
73
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
119
74
|
className: `${props.prefix}-section`,
|
|
120
75
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
121
76
|
className: `${props.prefix}-readOnly`,
|
|
@@ -123,41 +78,20 @@ window.__ModuleLoader__.load({
|
|
|
123
78
|
children: props.text
|
|
124
79
|
})
|
|
125
80
|
});
|
|
126
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
|
|
127
|
-
className: `${props.prefix}-card`,
|
|
128
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
129
|
-
className: `${props.prefix}-readOnly`,
|
|
130
|
-
role: "status",
|
|
131
|
-
children: props.text
|
|
132
|
-
})
|
|
133
|
-
});
|
|
134
81
|
}
|
|
135
82
|
//#endregion
|
|
136
83
|
//#region ../shared/src/client/config-slots.ts
|
|
137
84
|
/** dsh-plus 聚合 bundle 的包名(各插件 row 均经其补丁层插入 profile)。 */
|
|
138
85
|
const DSH_PLUS_BUNDLE = "@dsh-plus/bundle-main";
|
|
139
86
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* 故用无边框分节;summary 与 legacy 槽位保持卡片形态。
|
|
143
|
-
*/
|
|
144
|
-
function cardVariantFor(view) {
|
|
145
|
-
return view === "page" ? "section" : "card";
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* 把一张配置卡片同时注册进 legacy 与新版三个槽位。
|
|
149
|
-
* 任一槽位在当前 dsh 版本未声明时对应 inject 挂起等待,版本不命中即 no-op。
|
|
87
|
+
* 把一张配置卡片注册进插件页的两个配置槽位。
|
|
88
|
+
* 两个槽位都由 0.2.1-alpha.1 的插件页声明,任一缺席即报错——不做版本探测。
|
|
150
89
|
*/
|
|
151
90
|
function injectPluginConfigCard(slots, reg) {
|
|
152
91
|
const base = {
|
|
153
92
|
locale: reg.ns,
|
|
154
93
|
inject: reg.inject
|
|
155
94
|
};
|
|
156
|
-
slots.inject("settings.plugin.item", () => slots.register({
|
|
157
|
-
name: "settings.plugin.item",
|
|
158
|
-
key: reg.ns,
|
|
159
|
-
...base
|
|
160
|
-
}, reg.component));
|
|
161
95
|
slots.inject("plugins.row.config", () => slots.register({
|
|
162
96
|
name: "plugins.row.config",
|
|
163
97
|
key: `${DSH_PLUS_BUNDLE}#${reg.rowId}`,
|
|
@@ -376,36 +310,33 @@ window.__ModuleLoader__.load({
|
|
|
376
310
|
//#endregion
|
|
377
311
|
//#region ../shared/src/client/styles.ts
|
|
378
312
|
/**
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
*
|
|
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 约定):
|
|
382
322
|
* - 窄屏 input/textarea 16px(防 iOS 聚焦缩放)、可点目标 ≥44px;
|
|
383
|
-
* -
|
|
384
|
-
* - 展开态 body 底部 sticky 保存栏(长表单滚动中始终可达)。
|
|
385
|
-
* - 分节形态(-section,插件页 page 视图内嵌宿主页面):无边框/背景、横向零
|
|
386
|
-
* 内边距,页脚不 sticky——官方插件页已提供页面级内边距,再叠一层卡片会
|
|
387
|
-
* 缩窄移动端可用宽度(卡片套卡片)。
|
|
323
|
+
* - 页脚按钮等宽换行、状态文字独占一行。
|
|
388
324
|
* 沿用官方 data-plugin / data-plugin-css 约定(HMR 据此卸载),不覆盖上游选择器。
|
|
389
325
|
* @module @dsh-plus/shared/client/styles
|
|
390
326
|
*/
|
|
391
|
-
/**
|
|
327
|
+
/** 生成全套分节 CSS;prefix 为插件类名前缀(如 'dne'),extra 为插件特有规则。 */
|
|
392
328
|
function cardCss(prefix, extra = "") {
|
|
393
329
|
return `
|
|
394
|
-
.${prefix}-
|
|
395
|
-
.${prefix}-
|
|
396
|
-
.${prefix}-
|
|
397
|
-
.${prefix}-
|
|
398
|
-
.${prefix}-
|
|
399
|
-
.${prefix}-
|
|
400
|
-
.${prefix}-
|
|
401
|
-
.${prefix}-description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}
|
|
402
|
-
.${prefix}-chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s;display:inline-flex}
|
|
403
|
-
.${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}
|
|
404
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}
|
|
405
|
-
.${prefix}-statusBadge{white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
|
|
406
338
|
.${prefix}-statusOn{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary)}
|
|
407
339
|
.${prefix}-statusOff{color:var(--dsw-alias-label-tertiary)}
|
|
408
|
-
.${prefix}-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}
|
|
409
340
|
.${prefix}-field{flex-direction:column;gap:6px;padding:12px 0;display:flex}
|
|
410
341
|
.${prefix}-field+.${prefix}-field{border-top:1px solid var(--dsw-alias-border-l2)}
|
|
411
342
|
.${prefix}-head{align-items:center;gap:8px;display:flex}
|
|
@@ -431,19 +362,9 @@ window.__ModuleLoader__.load({
|
|
|
431
362
|
.${prefix}-checkRow input:checked::after{left:16px;background:var(--dsw-alias-bg-base)}
|
|
432
363
|
.${prefix}-checkRow input:disabled{opacity:.4;cursor:default}
|
|
433
364
|
.${prefix}-checkRow input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}
|
|
434
|
-
/* 宿主内嵌分节形态(插件页 page 视图):官方设置页同构——无边框/背景,
|
|
435
|
-
横向零内边距(宽度交给宿主页面容器),小节标题 13px/600,页脚非 sticky。 */
|
|
436
|
-
.${prefix}-section{box-sizing:border-box;flex-direction:column;width:100%;min-width:0;padding:16px 0;display:flex}
|
|
437
|
-
.${prefix}-sectionHead{align-items:center;gap:8px;min-width:0;display:flex}
|
|
438
|
-
.${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}
|
|
439
|
-
.${prefix}-sectionBadge{white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
|
|
440
|
-
.${prefix}-sectionDesc{color:var(--dsw-alias-label-tertiary);margin:4px 0 0;font-size:12px;line-height:1.5}
|
|
441
|
-
.${prefix}-sectionBody{flex-direction:column;min-width:0;display:flex}
|
|
442
|
-
.${prefix}-sectionFooter{align-items:center;gap:8px;padding-top:16px;display:flex;flex-wrap:wrap}
|
|
443
365
|
.${prefix}-groupLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600;padding:12px 0 2px;margin:0}
|
|
444
366
|
.${prefix}-readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}
|
|
445
367
|
.${prefix}-warn{color:var(--dsw-alias-label-error);margin:12px 0 0;font-size:12px;line-height:1.5}
|
|
446
|
-
.${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}
|
|
447
368
|
.${prefix}-status{min-width:0;color:var(--dsw-alias-label-secondary);flex:1;margin:0;font-size:12px;line-height:1.5}
|
|
448
369
|
.${prefix}-statusError{color:var(--dsw-alias-label-error)}
|
|
449
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}
|
|
@@ -453,16 +374,10 @@ window.__ModuleLoader__.load({
|
|
|
453
374
|
.${prefix}-btn:disabled{opacity:.4;cursor:default}
|
|
454
375
|
.${prefix}-btn:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}
|
|
455
376
|
@media (max-width:767px){
|
|
456
|
-
.${prefix}-body{margin:0 10px}
|
|
457
|
-
.${prefix}-header{padding:12px 12px}
|
|
458
377
|
.${prefix}-input,.${prefix}-select{font-size:16px;height:40px}
|
|
459
378
|
.${prefix}-checkRow{min-height:44px;padding:8px 0}
|
|
460
|
-
.${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}
|
|
461
379
|
.${prefix}-status{flex-basis:100%;flex:none}
|
|
462
380
|
.${prefix}-btn{min-height:44px;flex:1;min-width:96px}
|
|
463
|
-
.${prefix}-statusBadge{display:none}
|
|
464
|
-
.${prefix}-sectionBadge{display:inline-block}
|
|
465
|
-
.${prefix}-sectionFooter{position:static}
|
|
466
381
|
}
|
|
467
382
|
@media (pointer:coarse){
|
|
468
383
|
.${prefix}-btn{min-height:44px}
|
|
@@ -549,8 +464,8 @@ ${extra}
|
|
|
549
464
|
//#endregion
|
|
550
465
|
//#region src/client/card.tsx
|
|
551
466
|
/**
|
|
552
|
-
* 「子代理模型配置」配置卡片:经 injectPluginConfigCard
|
|
553
|
-
*
|
|
467
|
+
* 「子代理模型配置」配置卡片:经 injectPluginConfigCard 注册(插件页 plugins.row.config /
|
|
468
|
+
* plugins.bundle.config,view 分发 summary/page)。
|
|
554
469
|
* 外壳与基础控件走 @dsh-plus/shared/client 套件(CardChrome/CheckRow/SelectField)。
|
|
555
470
|
* 配置读写经共享层 ctx.remote.settings 直连(0.1.7 起 settingsScope 已由 configForms
|
|
556
471
|
* 取代):value 为 schema 解析后的命名空间值
|
|
@@ -704,14 +619,14 @@ ${extra}
|
|
|
704
619
|
return null;
|
|
705
620
|
}
|
|
706
621
|
/**
|
|
707
|
-
* 子代理 provider
|
|
622
|
+
* 子代理 provider 目录(挂载后拉取一次;失败保留重试入口,重试即回到未加载态)。
|
|
708
623
|
* 与草稿播种共用同一个 catalog:目录到达后由调用方补缺失的空行。
|
|
709
624
|
*/
|
|
710
|
-
function useCatalog(
|
|
625
|
+
function useCatalog() {
|
|
711
626
|
const [catalog, setCatalog] = (0, react.useState)(null);
|
|
712
627
|
const [catalogFailed, setCatalogFailed] = (0, react.useState)(false);
|
|
713
628
|
(0, react.useEffect)(() => {
|
|
714
|
-
if (
|
|
629
|
+
if (catalog !== null) return;
|
|
715
630
|
let alive = true;
|
|
716
631
|
fetchCatalog().then((loaded) => {
|
|
717
632
|
if (!alive) return;
|
|
@@ -723,7 +638,7 @@ ${extra}
|
|
|
723
638
|
return () => {
|
|
724
639
|
alive = false;
|
|
725
640
|
};
|
|
726
|
-
}, [
|
|
641
|
+
}, [catalog]);
|
|
727
642
|
return {
|
|
728
643
|
catalog,
|
|
729
644
|
catalogFailed,
|
|
@@ -752,11 +667,10 @@ ${extra}
|
|
|
752
667
|
const { t, scope, api } = props;
|
|
753
668
|
const snapshot = (0, react.useSyncExternalStore)((listener) => scope.subscribe(listener), () => scope.getSnapshot());
|
|
754
669
|
const value = snapshot.value;
|
|
755
|
-
const [open, setOpen] = (0, react.useState)(props.view === "page");
|
|
756
670
|
const [draft, setDraft] = (0, react.useState)(null);
|
|
757
671
|
const [saving, setSaving] = (0, react.useState)(false);
|
|
758
672
|
const [status, setStatus] = (0, react.useState)(IDLE_STATUS);
|
|
759
|
-
const { catalog, catalogFailed, retry: retryCatalog } = useCatalog(
|
|
673
|
+
const { catalog, catalogFailed, retry: retryCatalog } = useCatalog();
|
|
760
674
|
(0, react.useEffect)(() => {
|
|
761
675
|
if (value === void 0) return;
|
|
762
676
|
setDraft((current) => {
|
|
@@ -782,10 +696,8 @@ ${extra}
|
|
|
782
696
|
]);
|
|
783
697
|
const invalid = (0, react.useMemo)(() => draft !== null && Object.values(draft.rows).some((row) => row.model.length > 0 && row.provider.length === 0), [draft]);
|
|
784
698
|
if (props.view === "summary") return t("summaryLine");
|
|
785
|
-
const variant = cardVariantFor(props.view);
|
|
786
699
|
if (value === void 0 || draft === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardLoading, {
|
|
787
700
|
prefix: "dsm",
|
|
788
|
-
variant,
|
|
789
701
|
text: t("loading")
|
|
790
702
|
});
|
|
791
703
|
const edit = (key, editValue) => {
|
|
@@ -827,9 +739,6 @@ ${extra}
|
|
|
827
739
|
prefix: "dsm",
|
|
828
740
|
title: t("title"),
|
|
829
741
|
description: t("description"),
|
|
830
|
-
open,
|
|
831
|
-
onToggle: setOpen,
|
|
832
|
-
variant,
|
|
833
742
|
statusBadge: {
|
|
834
743
|
text: t(draft.enabled ? "enabledOn" : "enabledOff"),
|
|
835
744
|
on: draft.enabled
|
|
@@ -951,21 +860,16 @@ ${extra}
|
|
|
951
860
|
*/
|
|
952
861
|
const PLUGIN_ID = "@dsh-plus/subagent-model";
|
|
953
862
|
const cardCssAll = cardCss("dsm", `
|
|
954
|
-
.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}
|
|
955
865
|
.dsm-rowHead{align-items:center;gap:8px;padding:8px 0 2px;display:flex}
|
|
956
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}
|
|
957
867
|
.dsm-rowHint{color:var(--dsw-alias-label-tertiary);margin:0 0 4px;font-size:12px;line-height:1.5}
|
|
958
868
|
.dsm-banner{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:8px;border-radius:8px;margin-top:12px;padding:7px 8px;font-size:12px;line-height:18px;display:flex}
|
|
959
869
|
.dsm-bannerRetry{color:inherit;font:inherit;cursor:pointer;background:0 0;border:none;flex:none;padding:0;font-weight:600}
|
|
960
870
|
.dsm-empty{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}
|
|
961
|
-
/* 分节形态(插件页 page 视图):provider 行块改为分隔线分组,去掉第二层内边距,
|
|
962
|
-
移动端可用宽度不再被卡片与行块两级内边距同时扣减。 */
|
|
963
|
-
.dsm-section .dsm-row{background:0 0;border:0;border-top:1px solid var(--dsw-alias-border-l2);border-radius:0;margin:0;padding:10px 0 2px}
|
|
964
|
-
.dsm-section .dsm-row:first-of-type{border-top:0}
|
|
965
871
|
@media (max-width:767px){
|
|
966
|
-
.dsm-row{padding:2px 8px 8px}
|
|
967
872
|
.dsm-rowHead{flex-wrap:wrap}
|
|
968
|
-
.dsm-section .dsm-row{padding:10px 0 2px}
|
|
969
873
|
}
|
|
970
874
|
`);
|
|
971
875
|
/** 幂等注入样式标签;返回标签(已存在或环境无 document 时为 null)。 */
|
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 解析后的命名空间值
|
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
CardLoading,
|
|
17
17
|
type CardStatusState,
|
|
18
18
|
CheckRow,
|
|
19
|
-
cardVariantFor,
|
|
20
19
|
IDLE_STATUS,
|
|
21
20
|
type NamespaceSettingsApi,
|
|
22
21
|
type PluginConfigViewProps,
|
|
@@ -186,10 +185,10 @@ function CatalogStatus(props: {
|
|
|
186
185
|
}
|
|
187
186
|
|
|
188
187
|
/**
|
|
189
|
-
* 子代理 provider
|
|
188
|
+
* 子代理 provider 目录(挂载后拉取一次;失败保留重试入口,重试即回到未加载态)。
|
|
190
189
|
* 与草稿播种共用同一个 catalog:目录到达后由调用方补缺失的空行。
|
|
191
190
|
*/
|
|
192
|
-
function useCatalog(
|
|
191
|
+
function useCatalog(): {
|
|
193
192
|
catalog: ModelCatalog | null
|
|
194
193
|
catalogFailed: boolean
|
|
195
194
|
retry(): void
|
|
@@ -197,7 +196,7 @@ function useCatalog(open: boolean): {
|
|
|
197
196
|
const [catalog, setCatalog] = useState<ModelCatalog | null>(null)
|
|
198
197
|
const [catalogFailed, setCatalogFailed] = useState(false)
|
|
199
198
|
useEffect(() => {
|
|
200
|
-
if (
|
|
199
|
+
if (catalog !== null) return
|
|
201
200
|
let alive = true
|
|
202
201
|
fetchCatalog()
|
|
203
202
|
.then((loaded) => {
|
|
@@ -211,7 +210,7 @@ function useCatalog(open: boolean): {
|
|
|
211
210
|
return () => {
|
|
212
211
|
alive = false
|
|
213
212
|
}
|
|
214
|
-
}, [
|
|
213
|
+
}, [catalog])
|
|
215
214
|
return {
|
|
216
215
|
catalog,
|
|
217
216
|
catalogFailed,
|
|
@@ -256,12 +255,10 @@ export function SubagentModelCard(props: CardProps): ReactElement | string | nul
|
|
|
256
255
|
() => scope.getSnapshot(),
|
|
257
256
|
)
|
|
258
257
|
const value = snapshot.value as ConfigValue | undefined
|
|
259
|
-
// 0.1.6-alpha.2 插件页 page 视图为表单落地页,默认展开;旧槽位无 view,保持折叠。
|
|
260
|
-
const [open, setOpen] = useState(props.view === 'page')
|
|
261
258
|
const [draft, setDraft] = useState<Draft | null>(null)
|
|
262
259
|
const [saving, setSaving] = useState(false)
|
|
263
260
|
const [status, setStatus] = useState<CardStatusState>(IDLE_STATUS)
|
|
264
|
-
const { catalog, catalogFailed, retry: retryCatalog } = useCatalog(
|
|
261
|
+
const { catalog, catalogFailed, retry: retryCatalog } = useCatalog()
|
|
265
262
|
|
|
266
263
|
// 播种草稿(行集 = 已配置条目);catalog 到达后只补缺失的 provider 空行,
|
|
267
264
|
// 不覆盖在途编辑;后续 Host 更新同样不覆盖。
|
|
@@ -298,11 +295,8 @@ export function SubagentModelCard(props: CardProps): ReactElement | string | nul
|
|
|
298
295
|
// 插件页 summary 视图只出一行简介(hooks 已全部落定,可安全提前返回)。
|
|
299
296
|
if (props.view === 'summary') return t('summaryLine')
|
|
300
297
|
|
|
301
|
-
// 插件页 page 视图内嵌宿主页面容器(已带页面级内边距与标题),用无边框分节。
|
|
302
|
-
const variant = cardVariantFor(props.view)
|
|
303
|
-
|
|
304
298
|
if (value === undefined || draft === null) {
|
|
305
|
-
return <CardLoading prefix="dsm"
|
|
299
|
+
return <CardLoading prefix="dsm" text={t('loading')} />
|
|
306
300
|
}
|
|
307
301
|
const edit = <K extends keyof Draft>(key: K, editValue: Draft[K]): void => {
|
|
308
302
|
setDraft({ ...draft, [key]: editValue })
|
|
@@ -340,9 +334,6 @@ export function SubagentModelCard(props: CardProps): ReactElement | string | nul
|
|
|
340
334
|
prefix="dsm"
|
|
341
335
|
title={t('title')}
|
|
342
336
|
description={t('description')}
|
|
343
|
-
open={open}
|
|
344
|
-
onToggle={setOpen}
|
|
345
|
-
variant={variant}
|
|
346
337
|
statusBadge={{ text: t(draft.enabled ? 'enabledOn' : 'enabledOff'), on: draft.enabled }}
|
|
347
338
|
dirty={dirty}
|
|
348
339
|
dirtyLabel={t('unsaved')}
|
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,21 +9,16 @@ 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}
|
|
16
17
|
.dsm-banner{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:8px;border-radius:8px;margin-top:12px;padding:7px 8px;font-size:12px;line-height:18px;display:flex}
|
|
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
|
-
/* 分节形态(插件页 page 视图):provider 行块改为分隔线分组,去掉第二层内边距,
|
|
20
|
-
移动端可用宽度不再被卡片与行块两级内边距同时扣减。 */
|
|
21
|
-
.dsm-section .dsm-row{background:0 0;border:0;border-top:1px solid var(--dsw-alias-border-l2);border-radius:0;margin:0;padding:10px 0 2px}
|
|
22
|
-
.dsm-section .dsm-row:first-of-type{border-top:0}
|
|
23
20
|
@media (max-width:767px){
|
|
24
|
-
.dsm-row{padding:2px 8px 8px}
|
|
25
21
|
.dsm-rowHead{flex-wrap:wrap}
|
|
26
|
-
.dsm-section .dsm-row{padding:10px 0 2px}
|
|
27
22
|
}
|
|
28
23
|
`
|
|
29
24
|
|
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'
|