@fonlan/dsh-model-parameters 0.1.3 → 0.1.5
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.en.md +2 -0
- package/README.md +2 -0
- package/lib/client.js +63 -97
- package/lib/client.js.map +1 -1
- package/lib/index.js +2 -3
- package/package.json +15 -18
- package/src/client/index.tsx +22 -18
- package/src/client/locales.ts +2 -6
- package/src/client/{settings-card.css → settings-section.css} +24 -79
- package/src/client/{settings-card.tsx → settings-section.tsx} +41 -62
- package/src/server/service.ts +3 -7
package/README.en.md
CHANGED
|
@@ -77,6 +77,8 @@ An expandable "模型参数补全 / Model Parameters" card appears in DSH
|
|
|
77
77
|
settings → **Plugins → Plugin configuration** (styled like the built-in plugin
|
|
78
78
|
cards, collapsed by default):
|
|
79
79
|
|
|
80
|
+

|
|
81
|
+
|
|
80
82
|
- master enable switch plus per-field toggles (`fillName`, `fillContext`,
|
|
81
83
|
`fillMaxTokens`, `fillReasoning`, `fillInput`);
|
|
82
84
|
- catalog TTL in days;
|
package/README.md
CHANGED
|
@@ -50,6 +50,8 @@ models.dev 把同一模型挂在许多 provider 名下(`deepseek-v4-flash` 出
|
|
|
50
50
|
|
|
51
51
|
在 DSH 设置 → **插件 → 插件配置** 中会出现一张 "模型参数补全 / Model Parameters" 可展开卡片(样式与内置插件卡片一致,默认折叠):
|
|
52
52
|
|
|
53
|
+

|
|
54
|
+
|
|
53
55
|
- 总开关 + 逐字段开关(`fillName`、`fillContext`、`fillMaxTokens`、`fillReasoning`、`fillInput`);
|
|
54
56
|
- 目录 TTL(天);
|
|
55
57
|
- 可选的 `provider → models.dev provider` 映射覆盖;
|
package/lib/client.js
CHANGED
|
@@ -14,9 +14,7 @@ window.__ModuleLoader__.load({
|
|
|
14
14
|
const LOCALE_NS = "model-parameters";
|
|
15
15
|
const zh = {
|
|
16
16
|
settingsTitle: "模型参数补全",
|
|
17
|
-
|
|
18
|
-
collapse: "收起",
|
|
19
|
-
expand: "展开",
|
|
17
|
+
sectionSub: "补全字段、目录刷新、Provider 映射与补全报告。",
|
|
20
18
|
master: "启用自动补全",
|
|
21
19
|
masterDesc: "关闭后不再自动补全任何字段(已补全的值保留)。",
|
|
22
20
|
fields: "补全字段",
|
|
@@ -60,9 +58,7 @@ window.__ModuleLoader__.load({
|
|
|
60
58
|
};
|
|
61
59
|
const en = {
|
|
62
60
|
settingsTitle: "Model Parameters",
|
|
63
|
-
|
|
64
|
-
collapse: "Collapse",
|
|
65
|
-
expand: "Expand",
|
|
61
|
+
sectionSub: "Field toggles, catalog refresh, provider mapping and the fill report.",
|
|
66
62
|
master: "Enable auto-fill",
|
|
67
63
|
masterDesc: "When off, no fields are filled (already-filled values are kept).",
|
|
68
64
|
fields: "Fields to fill",
|
|
@@ -135,9 +131,9 @@ window.__ModuleLoader__.load({
|
|
|
135
131
|
setConfig: (patch) => call("set-config", { patch })
|
|
136
132
|
};
|
|
137
133
|
//#endregion
|
|
138
|
-
//#region \0dsh-css:/home/runner/work/dsh-model-parameters/dsh-model-parameters/src/client/settings-
|
|
139
|
-
const css = "/**\n * Styles for the Model Parameters
|
|
140
|
-
const tagId = "@fonlan/dsh-model-parameters/settings-
|
|
134
|
+
//#region \0dsh-css:/home/runner/work/dsh-model-parameters/dsh-model-parameters/src/client/settings-section.css.mjs
|
|
135
|
+
const css = "/**\n * Styles for the Model Parameters settings page.\n *\n * The page occupies the settings panel's content column: a header (title plus\n * a one-line summary) over divider-separated control groups. Inner controls\n * follow the built-in settings language: border-l2 inputs on bg-layer-3,\n * inverted primary buttons.\n */\n\n/* page layout */\n\n.mp-page {\n display: flex;\n flex-direction: column;\n gap: 16px;\n max-width: 720px;\n}\n\n.mp-page-head {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.mp-page-title {\n margin: 0;\n color: var(--dsw-alias-label-primary, #e6e6e6);\n font-size: 15px;\n font-weight: 600;\n line-height: 1.4;\n}\n\n.mp-page-sub {\n margin: 0;\n color: var(--dsw-alias-label-tertiary, #8b93a7);\n font-size: 13px;\n line-height: 1.5;\n}\n\n/* body layout */\n\n.mp-body {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.mp-group {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.mp-group-title {\n margin: 0;\n color: var(--dsw-alias-label-primary, #e6e6e6);\n font-size: 13px;\n font-weight: 600;\n line-height: 1.5;\n}\n\n.mp-divider {\n border: none;\n border-top: 1px solid var(--dsw-alias-border-l2, #2a3346);\n margin: 0;\n}\n\n.mp-desc {\n margin: 0;\n color: var(--dsw-alias-label-tertiary, #8b93a7);\n font-size: 12px;\n line-height: 1.6;\n}\n\n.mp-muted {\n margin: 0;\n color: var(--dsw-alias-label-tertiary, #8b93a7);\n font-size: 13px;\n line-height: 1.6;\n}\n\n.mp-error {\n margin: 0;\n color: var(--dsw-alias-label-error, #ff8f8f);\n font-size: 13px;\n line-height: 1.6;\n}\n\n/* toggles */\n\n.mp-toggle {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n cursor: pointer;\n}\n\n.mp-toggle input[type='checkbox'] {\n margin-top: 3px;\n accent-color: var(--dsw-alias-brand-primary, #4f8cff);\n}\n\n.mp-toggle-sub {\n padding-left: 22px;\n}\n\n.mp-toggle-body {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.mp-toggle-label {\n color: var(--dsw-alias-label-primary, #e6e6e6);\n font-size: 13px;\n line-height: 1.5;\n}\n\n.mp-toggle-desc {\n color: var(--dsw-alias-label-tertiary, #8b93a7);\n font-size: 12px;\n line-height: 1.5;\n}\n\n/* catalog meta / ttl */\n\n.mp-meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px 16px;\n color: var(--dsw-alias-label-secondary, #aab2c5);\n font-size: 13px;\n line-height: 1.6;\n}\n\n.mp-ttl {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n color: var(--dsw-alias-label-secondary, #aab2c5);\n font-size: 13px;\n line-height: 1.6;\n}\n\n/* inputs */\n\n.mp-input {\n border: 1px solid var(--dsw-alias-border-l2, #2a3346);\n background: var(--dsw-alias-bg-layer-3, #0d1017);\n color: var(--dsw-alias-label-primary, #e6e6e6);\n height: 34px;\n border-radius: 8px;\n padding: 0 12px;\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n}\n\n.mp-input:focus-visible {\n border-color: var(--dsw-alias-brand-primary, #4f8cff);\n outline: none;\n}\n\n.mp-input:disabled {\n color: var(--dsw-alias-label-tertiary, #8b93a7);\n cursor: default;\n}\n\n.mp-input-narrow {\n width: 72px;\n}\n\n/* mapping rows */\n\n.mp-map-row {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.mp-map-row .mp-input {\n flex: 1;\n min-width: 0;\n}\n\n.mp-map-arrow {\n color: var(--dsw-alias-label-tertiary, #8b93a7);\n flex: none;\n}\n\n/* buttons */\n\n.mp-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.mp-button {\n appearance: none;\n font: inherit;\n cursor: pointer;\n border: 1px solid transparent;\n border-radius: 8px;\n padding: 5px 14px;\n font-size: 13px;\n line-height: 1.5;\n background: var(--dsw-alias-label-primary, #e6e6e6);\n color: var(--dsw-alias-bg-layer-3, #0d1017);\n}\n\n.mp-button:hover:not(:disabled) {\n opacity: .9;\n}\n\n.mp-button:disabled {\n opacity: .4;\n cursor: default;\n}\n\n.mp-button:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4f8cff);\n outline-offset: 1px;\n}\n\n.mp-button-ghost {\n background: transparent;\n color: var(--dsw-alias-label-secondary, #aab2c5);\n border-color: var(--dsw-alias-border-l2, #2a3346);\n}\n\n.mp-button-ghost:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary, #e6e6e6);\n border-color: var(--dsw-alias-label-dimmed, #4a5468);\n}\n\n/* report / badges / code */\n\n.mp-report {\n margin: 0;\n padding-left: 18px;\n color: var(--dsw-alias-label-secondary, #aab2c5);\n font-size: 13px;\n line-height: 1.7;\n}\n\n.mp-code {\n background: var(--dsw-alias-bg-module-platform, rgba(128, 128, 128, 0.15));\n border-radius: 4px;\n padding: 1px 5px;\n font-size: 12px;\n word-break: break-all;\n}\n\n.mp-badge {\n white-space: nowrap;\n font-size: 11px;\n font-weight: 500;\n line-height: 17px;\n padding: 1px 8px;\n border-radius: 999px;\n margin-left: 4px;\n}\n\n.mp-badge-ok {\n background: rgba(52, 199, 89, 0.18);\n color: #34c759;\n}\n\n.mp-badge-warn {\n background: rgba(255, 149, 0, 0.18);\n color: #ff9500;\n}\n";
|
|
136
|
+
const tagId = "@fonlan/dsh-model-parameters/settings-section.css";
|
|
141
137
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
142
138
|
const tag = document.createElement("style");
|
|
143
139
|
tag.dataset.plugin = "@fonlan/dsh-model-parameters";
|
|
@@ -146,19 +142,15 @@ window.__ModuleLoader__.load({
|
|
|
146
142
|
document.head.appendChild(tag);
|
|
147
143
|
}
|
|
148
144
|
//#endregion
|
|
149
|
-
//#region src/client/settings-
|
|
145
|
+
//#region src/client/settings-section.tsx
|
|
150
146
|
/**
|
|
151
|
-
* The Model Parameters
|
|
152
|
-
* provider→models.dev mapping overrides, a manual refresh/fill action, the
|
|
153
|
-
* catalog freshness line, and the last fill report (filled / touched /
|
|
154
|
-
* unmatched).
|
|
147
|
+
* The Model Parameters settings page (设置 → 侧栏「模型参数补全」).
|
|
155
148
|
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
* that discloses the controls in place.
|
|
149
|
+
* Registers into the `settings.section` slot, so the page owns one entry in
|
|
150
|
+
* the settings sidebar and renders its content in the panel's content column.
|
|
151
|
+
* Content: master + per-field toggles, catalog TTL, provider→models.dev
|
|
152
|
+
* mapping overrides, a manual refresh/fill action, the catalog freshness line,
|
|
153
|
+
* and the last fill report (filled / touched / unmatched).
|
|
162
154
|
*
|
|
163
155
|
* All reads/mutations go through the plugin's fenced API; config persists into
|
|
164
156
|
* the `model-parameters` settings namespace (settings.yaml).
|
|
@@ -187,7 +179,7 @@ window.__ModuleLoader__.load({
|
|
|
187
179
|
return String(epochMs);
|
|
188
180
|
}
|
|
189
181
|
}
|
|
190
|
-
function
|
|
182
|
+
function makeSettingsSection(ctx) {
|
|
191
183
|
const t = (() => {
|
|
192
184
|
try {
|
|
193
185
|
return ctx.locale.bind(LOCALE_NS);
|
|
@@ -195,9 +187,8 @@ window.__ModuleLoader__.load({
|
|
|
195
187
|
return (key) => key;
|
|
196
188
|
}
|
|
197
189
|
})();
|
|
198
|
-
return function
|
|
190
|
+
return function ModelParametersSettingsSection() {
|
|
199
191
|
useLocaleRevision(ctx);
|
|
200
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
201
192
|
const [state, setState] = (0, react.useState)(null);
|
|
202
193
|
const [error, setError] = (0, react.useState)(null);
|
|
203
194
|
const [loading, setLoading] = (0, react.useState)(true);
|
|
@@ -272,78 +263,49 @@ window.__ModuleLoader__.load({
|
|
|
272
263
|
}
|
|
273
264
|
await patchConfig({ providerMap });
|
|
274
265
|
}, [mappingRows, patchConfig]);
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
"
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
286
|
-
className: "mp-card-headText",
|
|
287
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
288
|
-
className: "mp-card-title",
|
|
289
|
-
children: title
|
|
290
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
291
|
-
className: "mp-card-sub",
|
|
292
|
-
children: t("cardSub")
|
|
293
|
-
})]
|
|
294
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
295
|
-
className: "mp-card-chevron",
|
|
296
|
-
"data-open": open ? "" : void 0,
|
|
297
|
-
"aria-hidden": "true",
|
|
298
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
299
|
-
width: "14",
|
|
300
|
-
height: "14",
|
|
301
|
-
viewBox: "0 0 14 14",
|
|
302
|
-
fill: "none",
|
|
303
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
304
|
-
d: "M3.5 5.25L7 8.75L10.5 5.25",
|
|
305
|
-
stroke: "currentColor",
|
|
306
|
-
strokeWidth: "1.5",
|
|
307
|
-
strokeLinecap: "round",
|
|
308
|
-
strokeLinejoin: "round"
|
|
309
|
-
})
|
|
310
|
-
})
|
|
266
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
267
|
+
className: "mp-page",
|
|
268
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
269
|
+
className: "mp-page-head",
|
|
270
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
271
|
+
className: "mp-page-title",
|
|
272
|
+
children: t("settingsTitle")
|
|
273
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
274
|
+
className: "mp-page-sub",
|
|
275
|
+
children: t("sectionSub")
|
|
311
276
|
})]
|
|
312
|
-
}),
|
|
313
|
-
className: "mp-
|
|
314
|
-
children:
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
onReconcile: reconcileNow,
|
|
339
|
-
onApplyMappings: applyMappings
|
|
340
|
-
})
|
|
277
|
+
}), error !== null && state === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
278
|
+
className: "mp-error",
|
|
279
|
+
children: [
|
|
280
|
+
t("error"),
|
|
281
|
+
": ",
|
|
282
|
+
error
|
|
283
|
+
]
|
|
284
|
+
}) : loading || state === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
285
|
+
className: "mp-muted",
|
|
286
|
+
children: t("saving")
|
|
287
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelParametersBody, {
|
|
288
|
+
t,
|
|
289
|
+
state,
|
|
290
|
+
error,
|
|
291
|
+
saving,
|
|
292
|
+
busy,
|
|
293
|
+
mappingRows,
|
|
294
|
+
newFrom,
|
|
295
|
+
newTo,
|
|
296
|
+
setNewFrom,
|
|
297
|
+
setNewTo,
|
|
298
|
+
setMappingRows,
|
|
299
|
+
onPatchConfig: patchConfig,
|
|
300
|
+
onRefresh: refresh,
|
|
301
|
+
onReconcile: reconcileNow,
|
|
302
|
+
onApplyMappings: applyMappings
|
|
341
303
|
})]
|
|
342
304
|
});
|
|
343
305
|
};
|
|
344
306
|
}
|
|
345
|
-
/** The
|
|
346
|
-
function
|
|
307
|
+
/** The page body: divider-separated control groups. */
|
|
308
|
+
function ModelParametersBody(props) {
|
|
347
309
|
const { t, state, error, saving, busy, mappingRows, newFrom, newTo, setNewFrom, setNewTo, setMappingRows, onPatchConfig, onRefresh, onReconcile, onApplyMappings } = props;
|
|
348
310
|
const config = state.config;
|
|
349
311
|
const catalog = state.catalog;
|
|
@@ -633,8 +595,8 @@ window.__ModuleLoader__.load({
|
|
|
633
595
|
}
|
|
634
596
|
//#endregion
|
|
635
597
|
//#region src/client/index.tsx
|
|
636
|
-
/** The settings
|
|
637
|
-
const
|
|
598
|
+
/** The settings sidebar entry this page owns (must stay stable). */
|
|
599
|
+
const SECTION_ID = "model-parameters";
|
|
638
600
|
/** Services required before mounting (provided by the client runtime). */
|
|
639
601
|
const inject = ["slots", "locale"];
|
|
640
602
|
/** Client plugin body. */
|
|
@@ -646,12 +608,16 @@ window.__ModuleLoader__.load({
|
|
|
646
608
|
});
|
|
647
609
|
return () => off();
|
|
648
610
|
}, "model-parameters: dictionaries");
|
|
649
|
-
const
|
|
611
|
+
const t = ctx.locale.bind(LOCALE_NS);
|
|
612
|
+
const Section = makeSettingsSection(ctx);
|
|
650
613
|
const slots = ctx.slots;
|
|
651
|
-
slots.inject("settings.
|
|
652
|
-
name: "settings.
|
|
653
|
-
|
|
654
|
-
|
|
614
|
+
slots.inject("settings.section", () => slots.register({
|
|
615
|
+
name: "settings.section",
|
|
616
|
+
id: SECTION_ID,
|
|
617
|
+
order: 320,
|
|
618
|
+
label: () => t("settingsTitle"),
|
|
619
|
+
locale: LOCALE_NS
|
|
620
|
+
}, Section));
|
|
655
621
|
}
|
|
656
622
|
//#endregion
|
|
657
623
|
exports.apply = apply;
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["useCallback","useSyncExternalStore","useState"],"sources":["../../../src/client/locales.ts","../../../src/client/api.ts","../../../src/client/settings-card.tsx","../../../src/client/index.tsx"],"sourcesContent":["/**\n * Locale dictionaries for @fonlan/dsh-model-parameters settings page.\n * zh is the key source of truth; en must carry the exact same key set.\n */\nexport const LOCALE_NS = 'model-parameters'\n\nexport const zh = {\n settingsTitle: '模型参数补全',\n cardSub: '补全字段、目录刷新、Provider 映射与补全报告。',\n collapse: '收起',\n expand: '展开',\n master: '启用自动补全',\n masterDesc: '关闭后不再自动补全任何字段(已补全的值保留)。',\n fields: '补全字段',\n fillName: '显示名称',\n fillNameDesc: '模型条目缺 name 时写入目录中的显示名称。',\n fillContext: '最大上下文',\n fillContextDesc: '缺 contextWindow 时写入目录的上下文上限。',\n fillMaxTokens: '最大输出',\n fillMaxTokensDesc: '缺 maxTokens 时写入目录的输出上限。',\n fillReasoning: '推理强度',\n fillReasoningDesc: '缺 reasoningEfforts 时按目录 effort 档位写入 identity 字典(如 {high:\"high\", max:\"max\"})。',\n fillInput: '输入模态',\n fillInputDesc: '缺 input 时写入目录中的 text/image 模态。',\n ttl: '目录更新周期(天)',\n ttlDesc: '缓存的 models.dev 目录超过该天数后,在下次补全时自动刷新。',\n providerMap: 'Provider 映射',\n providerMapDesc: 'dsh provider → models.dev provider 的匹配覆盖(可选)。',\n addMapping: '添加映射',\n removeMapping: '移除',\n catalog: '模型目录',\n catalogEntries: '目录条目',\n catalogProviders: '覆盖 Provider',\n catalogFetched: '上次更新',\n catalogFresh: '新鲜',\n catalogStale: '已过期',\n catalogNever: '尚未获取',\n refresh: '立即更新目录并补全',\n refreshBusy: '更新中…',\n reconcileNow: '立即补全一次',\n report: '最近一次补全',\n reportNever: '尚未执行',\n reportFilled: '补全字段',\n reportTouched: '涉及 Provider',\n reportUnmatched: '未匹配模型',\n reportEmpty: '全部匹配,无未匹配项',\n reportAt: '时间',\n error: '加载失败',\n saving: '保存中…',\n officialProviders: '官方厂商优先级',\n officialProvidersDesc: '同一模型 id 在多处出现时,优先采用这些 models.dev provider 的条目。',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n settingsTitle: 'Model Parameters',\n cardSub: 'Field toggles, catalog refresh, provider mapping and the fill report.',\n collapse: 'Collapse',\n expand: 'Expand',\n master: 'Enable auto-fill',\n masterDesc: 'When off, no fields are filled (already-filled values are kept).',\n fields: 'Fields to fill',\n fillName: 'Display name',\n fillNameDesc: 'Write the catalog display name when a model entry lacks name.',\n fillContext: 'Context window',\n fillContextDesc: 'Write the catalog context limit when contextWindow is missing.',\n fillMaxTokens: 'Max output',\n fillMaxTokensDesc: 'Write the catalog output limit when maxTokens is missing.',\n fillReasoning: 'Reasoning efforts',\n fillReasoningDesc: 'Write an identity reasoningEfforts dict (e.g. {high:\"high\", max:\"max\"}) from catalog effort levels when missing.',\n fillInput: 'Input modalities',\n fillInputDesc: 'Write text/image modalities from the catalog when input is missing.',\n ttl: 'Catalog refresh interval (days)',\n ttlDesc: 'The cached models.dev catalog is refreshed on the next fill once older than this many days.',\n providerMap: 'Provider mapping',\n providerMapDesc: 'Optional dsh provider → models.dev provider matching overrides.',\n addMapping: 'Add mapping',\n removeMapping: 'Remove',\n catalog: 'Model catalog',\n catalogEntries: 'Catalog entries',\n catalogProviders: 'Providers covered',\n catalogFetched: 'Last updated',\n catalogFresh: 'fresh',\n catalogStale: 'stale',\n catalogNever: 'not fetched yet',\n refresh: 'Update catalog & fill now',\n refreshBusy: 'Updating…',\n reconcileNow: 'Fill now',\n report: 'Last fill',\n reportNever: 'never run',\n reportFilled: 'fields filled',\n reportTouched: 'providers touched',\n reportUnmatched: 'unmatched models',\n reportEmpty: 'all matched, nothing unmatched',\n reportAt: 'time',\n error: 'Failed to load',\n saving: 'Saving…',\n officialProviders: 'Official provider priority',\n officialProvidersDesc: 'When one model id appears under several providers, prefer entries from these models.dev providers.',\n}\n","/** Client transport for the model-parameters settings API. */\nimport type { ModelParametersConfig } from '../shared/config.js'\n\nexport interface CatalogView {\n entries: number\n providers: number\n fetchedAt: number\n fresh: boolean\n ttlDays: number\n}\n\nexport interface FillReportView {\n at: number\n filled: number\n touched: number\n unmatched: string[]\n}\n\nexport interface PluginState {\n config: ModelParametersConfig\n catalog: CatalogView\n report: FillReportView | null\n}\n\nexport class ModelParametersApiError extends Error {\n constructor(readonly code: string, message: string) {\n super(message)\n }\n}\n\nasync function call<T>(method: string, payload: Record<string, unknown> = {}): Promise<T> {\n let response: Response\n try {\n response = await fetch(`/plugins/@fonlan/dsh-model-parameters/api/${method}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n } catch (error) {\n throw new ModelParametersApiError('network', error instanceof Error ? error.message : String(error))\n }\n const parsed: { ok?: boolean; value?: unknown; error?: { code?: string; message?: string } } | null\n = await response.json().catch(() => null)\n if (!response.ok || parsed === null || parsed.ok !== true || parsed.value === undefined) {\n throw new ModelParametersApiError(\n parsed?.error?.code ?? 'http',\n parsed?.error?.message ?? `HTTP ${response.status}`,\n )\n }\n return parsed.value as T\n}\n\nexport const api = {\n state: () => call<PluginState>('state'),\n refresh: () => call<PluginState>('refresh'),\n reconcile: () => call<PluginState>('reconcile'),\n setConfig: (patch: Partial<ModelParametersConfig>) =>\n call<PluginState>('set-config', { patch }),\n}\n","/**\n * The Model Parameters Settings Card: master + per-field toggles, catalog TTL,\n * provider→models.dev mapping overrides, a manual refresh/fill action, the\n * catalog freshness line, and the last fill report (filled / touched /\n * unmatched).\n *\n * The card registers into the `settings.plugin.item` slot keyed by the\n * `model-parameters` settings namespace, so it renders inside\n * 设置 → 插件 → 插件配置, stacked with the built-in plugin cards. The chrome is\n * self-drawn (external plugins cannot import the built-in PluginCard) with\n * styles aligned to it: an expandable header (collapsed by default) and a body\n * that discloses the controls in place.\n *\n * All reads/mutations go through the plugin's fenced API; config persists into\n * the `model-parameters` settings namespace (settings.yaml).\n */\nimport { useCallback, useEffect, useState, useSyncExternalStore } from 'react'\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { Translate } from '@deepseek-ai/dsh-client-ui-slots'\nimport { LOCALE_NS } from './locales'\nimport { api, type PluginState } from './api'\nimport type { ModelParametersConfig } from '../shared/config.js'\nimport './settings-card.css'\n\nfunction useLocaleRevision(ctx: ClientContext): number {\n const subscribe = useCallback(\n (onChange: () => void) => {\n try {\n return ctx.locale.subscribe(onChange)\n } catch {\n return () => {}\n }\n },\n [ctx],\n )\n const getSnapshot = useCallback(() => {\n try {\n return ctx.locale.getLocale().revision\n } catch {\n return 0\n }\n }, [ctx])\n return useSyncExternalStore(subscribe, getSnapshot)\n}\n\nfunction formatTime(epochMs: number): string {\n try {\n return new Date(epochMs).toLocaleString()\n } catch {\n return String(epochMs)\n }\n}\n\nexport function makeSettingsCard(ctx: ClientContext): () => JSX.Element {\n const t: Translate = (() => {\n try {\n return ctx.locale.bind(LOCALE_NS) as unknown as Translate\n } catch {\n return (key: string) => key\n }\n })()\n\n return function ModelParametersCard(): JSX.Element {\n useLocaleRevision(ctx)\n // Card-local disclosure: collapsed by default, like the built-in plugin cards.\n const [open, setOpen] = useState(false)\n const [state, setState] = useState<PluginState | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState(false)\n const [saving, setSaving] = useState(false)\n const [mappingRows, setMappingRows] = useState<Array<{ from: string; to: string }>>([])\n const [newFrom, setNewFrom] = useState('')\n const [newTo, setNewTo] = useState('')\n\n const load = useCallback(async () => {\n setLoading(true)\n try {\n const next = await api.state()\n setState(next)\n setMappingRows(Object.entries(next.config.providerMap).map(([from, to]) => ({ from, to })))\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void load()\n }, [load])\n\n const patchConfig = useCallback(async (patch: Partial<ModelParametersConfig>) => {\n setSaving(true)\n try {\n const next = await api.setConfig(patch)\n setState(next)\n setMappingRows(Object.entries(next.config.providerMap).map(([from, to]) => ({ from, to })))\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setSaving(false)\n }\n }, [])\n\n const refresh = useCallback(async () => {\n setBusy(true)\n try {\n setState(await api.refresh())\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusy(false)\n }\n }, [])\n\n const reconcileNow = useCallback(async () => {\n setBusy(true)\n try {\n setState(await api.reconcile())\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusy(false)\n }\n }, [])\n\n const applyMappings = useCallback(async () => {\n const providerMap: Record<string, string> = {}\n for (const row of mappingRows) {\n const from = row.from.trim()\n const to = row.to.trim()\n if (from.length > 0 && to.length > 0) providerMap[from] = to\n }\n await patchConfig({ providerMap })\n }, [mappingRows, patchConfig])\n\n const title = t('settingsTitle')\n\n return (\n <li className=\"mp-card\" data-open={open ? '' : undefined}>\n <button type=\"button\" className=\"mp-card-head\" aria-expanded={open}\n aria-label={(open ? t('collapse') : t('expand')) + ':' + title}\n onClick={() => setOpen(!open)}>\n <span className=\"mp-card-headText\">\n <span className=\"mp-card-title\">{title}</span>\n <span className=\"mp-card-sub\">{t('cardSub')}</span>\n </span>\n <span className=\"mp-card-chevron\" data-open={open ? '' : undefined} aria-hidden=\"true\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\n <path d=\"M3.5 5.25L7 8.75L10.5 5.25\" stroke=\"currentColor\" strokeWidth=\"1.5\"\n strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </span>\n </button>\n {open && (\n <div className=\"mp-card-body\">\n {error !== null && state === null ? (\n <p className=\"mp-error\">{t('error')}: {error}</p>\n ) : loading || state === null ? (\n <p className=\"mp-muted\">{t('saving')}</p>\n ) : (\n <ModelParametersCardBody\n t={t}\n state={state}\n error={error}\n saving={saving}\n busy={busy}\n mappingRows={mappingRows}\n newFrom={newFrom}\n newTo={newTo}\n setNewFrom={setNewFrom}\n setNewTo={setNewTo}\n setMappingRows={setMappingRows}\n onPatchConfig={patchConfig}\n onRefresh={refresh}\n onReconcile={reconcileNow}\n onApplyMappings={applyMappings}\n />\n )}\n </div>\n )}\n </li>\n )\n }\n}\n\n/** The card body: divider-separated control groups, styled like the built-in cards. */\nfunction ModelParametersCardBody(props: {\n t: Translate\n state: PluginState\n error: string | null\n saving: boolean\n busy: boolean\n mappingRows: Array<{ from: string; to: string }>\n newFrom: string\n newTo: string\n setNewFrom: (value: string) => void\n setNewTo: (value: string) => void\n setMappingRows: (rows: Array<{ from: string; to: string }>) => void\n onPatchConfig: (patch: Partial<ModelParametersConfig>) => Promise<void>\n onRefresh: () => Promise<void>\n onReconcile: () => Promise<void>\n onApplyMappings: () => Promise<void>\n}): JSX.Element {\n const {\n t, state, error, saving, busy,\n mappingRows, newFrom, newTo,\n setNewFrom, setNewTo, setMappingRows,\n onPatchConfig, onRefresh, onReconcile, onApplyMappings,\n } = props\n\n const config = state.config\n const catalog = state.catalog\n const report = state.report\n\n return (\n <div className=\"mp-body\">\n <section className=\"mp-group\">\n <h4 className=\"mp-group-title\">{t('fields')}</h4>\n <label className=\"mp-toggle\">\n <input\n type=\"checkbox\"\n checked={config.enabled}\n disabled={saving}\n onChange={(event) => void onPatchConfig({ enabled: event.target.checked })}\n />\n <span className=\"mp-toggle-body\">\n <span className=\"mp-toggle-label\">{t('master')}</span>\n <span className=\"mp-toggle-desc\">{t('masterDesc')}</span>\n </span>\n </label>\n {([\n ['fillName', t('fillName'), t('fillNameDesc')],\n ['fillContext', t('fillContext'), t('fillContextDesc')],\n ['fillMaxTokens', t('fillMaxTokens'), t('fillMaxTokensDesc')],\n ['fillReasoning', t('fillReasoning'), t('fillReasoningDesc')],\n ['fillInput', t('fillInput'), t('fillInputDesc')],\n ] as const).map(([key, label, desc]) => (\n <label className=\"mp-toggle mp-toggle-sub\" key={key}>\n <input\n type=\"checkbox\"\n checked={config[key]}\n disabled={saving || !config.enabled}\n onChange={(event) => void onPatchConfig({ [key]: event.target.checked })}\n />\n <span className=\"mp-toggle-body\">\n <span className=\"mp-toggle-label\">{label}</span>\n <span className=\"mp-toggle-desc\">{desc}</span>\n </span>\n </label>\n ))}\n </section>\n\n <hr className=\"mp-divider\" />\n\n <section className=\"mp-group\">\n <h4 className=\"mp-group-title\">{t('catalog')}</h4>\n <div className=\"mp-meta\">\n <span>{t('catalogEntries')}: <strong>{catalog.entries.toLocaleString()}</strong></span>\n <span>{t('catalogProviders')}: <strong>{catalog.providers.toLocaleString()}</strong></span>\n <span>\n {t('catalogFetched')}:{' '}\n <strong>{catalog.fetchedAt > 0 ? formatTime(catalog.fetchedAt) : t('catalogNever')}</strong>{' '}\n {catalog.fetchedAt > 0 && (\n <span className={catalog.fresh ? 'mp-badge mp-badge-ok' : 'mp-badge mp-badge-warn'}>\n {catalog.fresh ? t('catalogFresh') : t('catalogStale')}\n </span>\n )}\n </span>\n <label className=\"mp-ttl\">\n {t('ttl')}\n <input\n className=\"mp-input mp-input-narrow\"\n type=\"number\"\n min={1}\n max={90}\n value={config.ttlDays}\n disabled={saving}\n onChange={(event) => {\n const days = Number(event.target.value)\n if (Number.isFinite(days) && days >= 1 && days <= 90) void onPatchConfig({ ttlDays: Math.round(days) })\n }}\n />\n </label>\n </div>\n <div className=\"mp-actions\">\n <button className=\"mp-button\" disabled={busy} onClick={() => void onRefresh()}>\n {busy ? t('refreshBusy') : t('refresh')}\n </button>\n <button className=\"mp-button mp-button-ghost\" disabled={busy} onClick={() => void onReconcile()}>\n {t('reconcileNow')}\n </button>\n </div>\n </section>\n\n <hr className=\"mp-divider\" />\n\n <section className=\"mp-group\">\n <h4 className=\"mp-group-title\">{t('providerMap')}</h4>\n <p className=\"mp-desc\">{t('providerMapDesc')}</p>\n {mappingRows.map((row, index) => (\n <div className=\"mp-map-row\" key={index}>\n <input\n className=\"mp-input\"\n value={row.from}\n disabled={saving}\n onChange={(event) => {\n const next = [...mappingRows]\n next[index] = { ...row, from: event.target.value }\n setMappingRows(next)\n }}\n />\n <span className=\"mp-map-arrow\">→</span>\n <input\n className=\"mp-input\"\n value={row.to}\n disabled={saving}\n onChange={(event) => {\n const next = [...mappingRows]\n next[index] = { ...row, to: event.target.value }\n setMappingRows(next)\n }}\n />\n <button\n className=\"mp-button mp-button-ghost\"\n disabled={saving}\n onClick={() => setMappingRows(mappingRows.filter((_, i) => i !== index))}\n >\n {t('removeMapping')}\n </button>\n </div>\n ))}\n <div className=\"mp-map-row\">\n <input\n className=\"mp-input\"\n placeholder=\"dsh provider\"\n value={newFrom}\n onChange={(event) => setNewFrom(event.target.value)}\n />\n <span className=\"mp-map-arrow\">→</span>\n <input\n className=\"mp-input\"\n placeholder=\"models.dev provider\"\n value={newTo}\n onChange={(event) => setNewTo(event.target.value)}\n />\n <button\n className=\"mp-button mp-button-ghost\"\n disabled={newFrom.trim().length === 0 || newTo.trim().length === 0}\n onClick={() => {\n setMappingRows([...mappingRows, { from: newFrom.trim(), to: newTo.trim() }])\n setNewFrom('')\n setNewTo('')\n }}\n >\n {t('addMapping')}\n </button>\n </div>\n <div className=\"mp-actions\">\n <button className=\"mp-button\" disabled={saving} onClick={() => void onApplyMappings()}>\n {saving ? t('saving') : '✓ ' + t('providerMap')}\n </button>\n </div>\n </section>\n\n <hr className=\"mp-divider\" />\n\n <section className=\"mp-group\">\n <h4 className=\"mp-group-title\">{t('report')}</h4>\n {report === null ? (\n <p className=\"mp-muted\">{t('reportNever')}</p>\n ) : (\n <ul className=\"mp-report\">\n <li>{t('reportAt')}: {formatTime(report.at)}</li>\n <li>{t('reportFilled')}: <strong>{report.filled}</strong></li>\n <li>{t('reportTouched')}: <strong>{report.touched}</strong></li>\n <li>\n {t('reportUnmatched')}:{' '}\n {report.unmatched.length === 0\n ? t('reportEmpty')\n : <code className=\"mp-code\">{report.unmatched.join(', ')}</code>}\n </li>\n </ul>\n )}\n </section>\n\n {error !== null && <p className=\"mp-error\">{error}</p>}\n </div>\n )\n}\n","/**\n * @fonlan/dsh-model-parameters client half: the plugin's own Settings Card.\n *\n * Registers into the `settings.plugin.item` slot keyed by the `model-parameters`\n * settings namespace (the same string the host half registers), so the card\n * appears inside 设置 → 插件 → 插件配置, paired with the namespace by the tab —\n * exactly like @fonlan/dsh-web-auth. The card draws its own expandable chrome\n * (external plugins cannot import the built-in PluginCard) with styles aligned\n * to the built-in plugin cards.\n *\n * Deps resolved from the browser module table: react only. The slots service\n * is reached through the cordis context; types come from devDependencies and\n * are erased at build time.\n */\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport { LOCALE_NS, zh, en } from './locales'\nimport { makeSettingsCard } from './settings-card'\n\n/** The settings namespace this card edits (must match the host half). */\nconst PLUGIN_NS = 'model-parameters'\n\n/** The slots service face (subset of @deepseek-ai/dsh-client-ui-slots). */\ninterface SlotEntry {\n name: string\n key?: string\n inject?: () => unknown\n}\n\ninterface Slots {\n inject(name: string, register: () => unknown): unknown\n register(def: SlotEntry, component: unknown): unknown\n}\n\n/** Services required before mounting (provided by the client runtime). */\nexport const inject = ['slots', 'locale']\n\n/** Client plugin body. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => {\n const off = ctx.locale.register(LOCALE_NS, { zh, en })\n return () => off()\n }, 'model-parameters: dictionaries')\n\n const Card = makeSettingsCard(ctx)\n const slots = (ctx as unknown as { slots: Slots }).slots\n slots.inject('settings.plugin.item', () =>\n slots.register({\n name: 'settings.plugin.item',\n key: PLUGIN_NS,\n }, Card),\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["useCallback","useSyncExternalStore","useState"],"sources":["../../../src/client/locales.ts","../../../src/client/api.ts","../../../src/client/settings-section.tsx","../../../src/client/index.tsx"],"sourcesContent":["/**\n * Locale dictionaries for @fonlan/dsh-model-parameters settings page.\n * zh is the key source of truth; en must carry the exact same key set.\n */\nexport const LOCALE_NS = 'model-parameters'\n\nexport const zh = {\n settingsTitle: '模型参数补全',\n sectionSub: '补全字段、目录刷新、Provider 映射与补全报告。',\n master: '启用自动补全',\n masterDesc: '关闭后不再自动补全任何字段(已补全的值保留)。',\n fields: '补全字段',\n fillName: '显示名称',\n fillNameDesc: '模型条目缺 name 时写入目录中的显示名称。',\n fillContext: '最大上下文',\n fillContextDesc: '缺 contextWindow 时写入目录的上下文上限。',\n fillMaxTokens: '最大输出',\n fillMaxTokensDesc: '缺 maxTokens 时写入目录的输出上限。',\n fillReasoning: '推理强度',\n fillReasoningDesc: '缺 reasoningEfforts 时按目录 effort 档位写入 identity 字典(如 {high:\"high\", max:\"max\"})。',\n fillInput: '输入模态',\n fillInputDesc: '缺 input 时写入目录中的 text/image 模态。',\n ttl: '目录更新周期(天)',\n ttlDesc: '缓存的 models.dev 目录超过该天数后,在下次补全时自动刷新。',\n providerMap: 'Provider 映射',\n providerMapDesc: 'dsh provider → models.dev provider 的匹配覆盖(可选)。',\n addMapping: '添加映射',\n removeMapping: '移除',\n catalog: '模型目录',\n catalogEntries: '目录条目',\n catalogProviders: '覆盖 Provider',\n catalogFetched: '上次更新',\n catalogFresh: '新鲜',\n catalogStale: '已过期',\n catalogNever: '尚未获取',\n refresh: '立即更新目录并补全',\n refreshBusy: '更新中…',\n reconcileNow: '立即补全一次',\n report: '最近一次补全',\n reportNever: '尚未执行',\n reportFilled: '补全字段',\n reportTouched: '涉及 Provider',\n reportUnmatched: '未匹配模型',\n reportEmpty: '全部匹配,无未匹配项',\n reportAt: '时间',\n error: '加载失败',\n saving: '保存中…',\n officialProviders: '官方厂商优先级',\n officialProvidersDesc: '同一模型 id 在多处出现时,优先采用这些 models.dev provider 的条目。',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n settingsTitle: 'Model Parameters',\n sectionSub: 'Field toggles, catalog refresh, provider mapping and the fill report.',\n master: 'Enable auto-fill',\n masterDesc: 'When off, no fields are filled (already-filled values are kept).',\n fields: 'Fields to fill',\n fillName: 'Display name',\n fillNameDesc: 'Write the catalog display name when a model entry lacks name.',\n fillContext: 'Context window',\n fillContextDesc: 'Write the catalog context limit when contextWindow is missing.',\n fillMaxTokens: 'Max output',\n fillMaxTokensDesc: 'Write the catalog output limit when maxTokens is missing.',\n fillReasoning: 'Reasoning efforts',\n fillReasoningDesc: 'Write an identity reasoningEfforts dict (e.g. {high:\"high\", max:\"max\"}) from catalog effort levels when missing.',\n fillInput: 'Input modalities',\n fillInputDesc: 'Write text/image modalities from the catalog when input is missing.',\n ttl: 'Catalog refresh interval (days)',\n ttlDesc: 'The cached models.dev catalog is refreshed on the next fill once older than this many days.',\n providerMap: 'Provider mapping',\n providerMapDesc: 'Optional dsh provider → models.dev provider matching overrides.',\n addMapping: 'Add mapping',\n removeMapping: 'Remove',\n catalog: 'Model catalog',\n catalogEntries: 'Catalog entries',\n catalogProviders: 'Providers covered',\n catalogFetched: 'Last updated',\n catalogFresh: 'fresh',\n catalogStale: 'stale',\n catalogNever: 'not fetched yet',\n refresh: 'Update catalog & fill now',\n refreshBusy: 'Updating…',\n reconcileNow: 'Fill now',\n report: 'Last fill',\n reportNever: 'never run',\n reportFilled: 'fields filled',\n reportTouched: 'providers touched',\n reportUnmatched: 'unmatched models',\n reportEmpty: 'all matched, nothing unmatched',\n reportAt: 'time',\n error: 'Failed to load',\n saving: 'Saving…',\n officialProviders: 'Official provider priority',\n officialProvidersDesc: 'When one model id appears under several providers, prefer entries from these models.dev providers.',\n}\n","/** Client transport for the model-parameters settings API. */\nimport type { ModelParametersConfig } from '../shared/config.js'\n\nexport interface CatalogView {\n entries: number\n providers: number\n fetchedAt: number\n fresh: boolean\n ttlDays: number\n}\n\nexport interface FillReportView {\n at: number\n filled: number\n touched: number\n unmatched: string[]\n}\n\nexport interface PluginState {\n config: ModelParametersConfig\n catalog: CatalogView\n report: FillReportView | null\n}\n\nexport class ModelParametersApiError extends Error {\n constructor(readonly code: string, message: string) {\n super(message)\n }\n}\n\nasync function call<T>(method: string, payload: Record<string, unknown> = {}): Promise<T> {\n let response: Response\n try {\n response = await fetch(`/plugins/@fonlan/dsh-model-parameters/api/${method}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n } catch (error) {\n throw new ModelParametersApiError('network', error instanceof Error ? error.message : String(error))\n }\n const parsed: { ok?: boolean; value?: unknown; error?: { code?: string; message?: string } } | null\n = await response.json().catch(() => null)\n if (!response.ok || parsed === null || parsed.ok !== true || parsed.value === undefined) {\n throw new ModelParametersApiError(\n parsed?.error?.code ?? 'http',\n parsed?.error?.message ?? `HTTP ${response.status}`,\n )\n }\n return parsed.value as T\n}\n\nexport const api = {\n state: () => call<PluginState>('state'),\n refresh: () => call<PluginState>('refresh'),\n reconcile: () => call<PluginState>('reconcile'),\n setConfig: (patch: Partial<ModelParametersConfig>) =>\n call<PluginState>('set-config', { patch }),\n}\n","/**\n * The Model Parameters settings page (设置 → 侧栏「模型参数补全」).\n *\n * Registers into the `settings.section` slot, so the page owns one entry in\n * the settings sidebar and renders its content in the panel's content column.\n * Content: master + per-field toggles, catalog TTL, provider→models.dev\n * mapping overrides, a manual refresh/fill action, the catalog freshness line,\n * and the last fill report (filled / touched / unmatched).\n *\n * All reads/mutations go through the plugin's fenced API; config persists into\n * the `model-parameters` settings namespace (settings.yaml).\n */\nimport { useCallback, useEffect, useState, useSyncExternalStore } from 'react'\nimport type { Context } from '@deepseek-ai/cordis'\ntype ClientContext = Context\nimport type { Translate } from '@deepseek-ai/dsh-client-ui-slots'\nimport { LOCALE_NS } from './locales'\nimport { api, type PluginState } from './api'\nimport type { ModelParametersConfig } from '../shared/config.js'\nimport './settings-section.css'\n\nfunction useLocaleRevision(ctx: ClientContext): number {\n const subscribe = useCallback(\n (onChange: () => void) => {\n try {\n return ctx.locale.subscribe(onChange)\n } catch {\n return () => {}\n }\n },\n [ctx],\n )\n const getSnapshot = useCallback(() => {\n try {\n return ctx.locale.getLocale().revision\n } catch {\n return 0\n }\n }, [ctx])\n return useSyncExternalStore(subscribe, getSnapshot)\n}\n\nfunction formatTime(epochMs: number): string {\n try {\n return new Date(epochMs).toLocaleString()\n } catch {\n return String(epochMs)\n }\n}\n\nexport function makeSettingsSection(ctx: ClientContext): () => JSX.Element {\n const t: Translate = (() => {\n try {\n return ctx.locale.bind(LOCALE_NS) as unknown as Translate\n } catch {\n return (key: string) => key\n }\n })()\n\n return function ModelParametersSettingsSection(): JSX.Element {\n useLocaleRevision(ctx)\n const [state, setState] = useState<PluginState | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState(false)\n const [saving, setSaving] = useState(false)\n const [mappingRows, setMappingRows] = useState<Array<{ from: string; to: string }>>([])\n const [newFrom, setNewFrom] = useState('')\n const [newTo, setNewTo] = useState('')\n\n const load = useCallback(async () => {\n setLoading(true)\n try {\n const next = await api.state()\n setState(next)\n setMappingRows(Object.entries(next.config.providerMap).map(([from, to]) => ({ from, to })))\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void load()\n }, [load])\n\n const patchConfig = useCallback(async (patch: Partial<ModelParametersConfig>) => {\n setSaving(true)\n try {\n const next = await api.setConfig(patch)\n setState(next)\n setMappingRows(Object.entries(next.config.providerMap).map(([from, to]) => ({ from, to })))\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setSaving(false)\n }\n }, [])\n\n const refresh = useCallback(async () => {\n setBusy(true)\n try {\n setState(await api.refresh())\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusy(false)\n }\n }, [])\n\n const reconcileNow = useCallback(async () => {\n setBusy(true)\n try {\n setState(await api.reconcile())\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusy(false)\n }\n }, [])\n\n const applyMappings = useCallback(async () => {\n const providerMap: Record<string, string> = {}\n for (const row of mappingRows) {\n const from = row.from.trim()\n const to = row.to.trim()\n if (from.length > 0 && to.length > 0) providerMap[from] = to\n }\n await patchConfig({ providerMap })\n }, [mappingRows, patchConfig])\n\n return (\n <div className=\"mp-page\">\n <header className=\"mp-page-head\">\n <h3 className=\"mp-page-title\">{t('settingsTitle')}</h3>\n <p className=\"mp-page-sub\">{t('sectionSub')}</p>\n </header>\n {error !== null && state === null ? (\n <p className=\"mp-error\">{t('error')}: {error}</p>\n ) : loading || state === null ? (\n <p className=\"mp-muted\">{t('saving')}</p>\n ) : (\n <ModelParametersBody\n t={t}\n state={state}\n error={error}\n saving={saving}\n busy={busy}\n mappingRows={mappingRows}\n newFrom={newFrom}\n newTo={newTo}\n setNewFrom={setNewFrom}\n setNewTo={setNewTo}\n setMappingRows={setMappingRows}\n onPatchConfig={patchConfig}\n onRefresh={refresh}\n onReconcile={reconcileNow}\n onApplyMappings={applyMappings}\n />\n )}\n </div>\n )\n }\n}\n\n/** The page body: divider-separated control groups. */\nfunction ModelParametersBody(props: {\n t: Translate\n state: PluginState\n error: string | null\n saving: boolean\n busy: boolean\n mappingRows: Array<{ from: string; to: string }>\n newFrom: string\n newTo: string\n setNewFrom: (value: string) => void\n setNewTo: (value: string) => void\n setMappingRows: (rows: Array<{ from: string; to: string }>) => void\n onPatchConfig: (patch: Partial<ModelParametersConfig>) => Promise<void>\n onRefresh: () => Promise<void>\n onReconcile: () => Promise<void>\n onApplyMappings: () => Promise<void>\n}): JSX.Element {\n const {\n t, state, error, saving, busy,\n mappingRows, newFrom, newTo,\n setNewFrom, setNewTo, setMappingRows,\n onPatchConfig, onRefresh, onReconcile, onApplyMappings,\n } = props\n\n const config = state.config\n const catalog = state.catalog\n const report = state.report\n\n return (\n <div className=\"mp-body\">\n <section className=\"mp-group\">\n <h4 className=\"mp-group-title\">{t('fields')}</h4>\n <label className=\"mp-toggle\">\n <input\n type=\"checkbox\"\n checked={config.enabled}\n disabled={saving}\n onChange={(event) => void onPatchConfig({ enabled: event.target.checked })}\n />\n <span className=\"mp-toggle-body\">\n <span className=\"mp-toggle-label\">{t('master')}</span>\n <span className=\"mp-toggle-desc\">{t('masterDesc')}</span>\n </span>\n </label>\n {([\n ['fillName', t('fillName'), t('fillNameDesc')],\n ['fillContext', t('fillContext'), t('fillContextDesc')],\n ['fillMaxTokens', t('fillMaxTokens'), t('fillMaxTokensDesc')],\n ['fillReasoning', t('fillReasoning'), t('fillReasoningDesc')],\n ['fillInput', t('fillInput'), t('fillInputDesc')],\n ] as const).map(([key, label, desc]) => (\n <label className=\"mp-toggle mp-toggle-sub\" key={key}>\n <input\n type=\"checkbox\"\n checked={config[key]}\n disabled={saving || !config.enabled}\n onChange={(event) => void onPatchConfig({ [key]: event.target.checked })}\n />\n <span className=\"mp-toggle-body\">\n <span className=\"mp-toggle-label\">{label}</span>\n <span className=\"mp-toggle-desc\">{desc}</span>\n </span>\n </label>\n ))}\n </section>\n\n <hr className=\"mp-divider\" />\n\n <section className=\"mp-group\">\n <h4 className=\"mp-group-title\">{t('catalog')}</h4>\n <div className=\"mp-meta\">\n <span>{t('catalogEntries')}: <strong>{catalog.entries.toLocaleString()}</strong></span>\n <span>{t('catalogProviders')}: <strong>{catalog.providers.toLocaleString()}</strong></span>\n <span>\n {t('catalogFetched')}:{' '}\n <strong>{catalog.fetchedAt > 0 ? formatTime(catalog.fetchedAt) : t('catalogNever')}</strong>{' '}\n {catalog.fetchedAt > 0 && (\n <span className={catalog.fresh ? 'mp-badge mp-badge-ok' : 'mp-badge mp-badge-warn'}>\n {catalog.fresh ? t('catalogFresh') : t('catalogStale')}\n </span>\n )}\n </span>\n <label className=\"mp-ttl\">\n {t('ttl')}\n <input\n className=\"mp-input mp-input-narrow\"\n type=\"number\"\n min={1}\n max={90}\n value={config.ttlDays}\n disabled={saving}\n onChange={(event) => {\n const days = Number(event.target.value)\n if (Number.isFinite(days) && days >= 1 && days <= 90) void onPatchConfig({ ttlDays: Math.round(days) })\n }}\n />\n </label>\n </div>\n <div className=\"mp-actions\">\n <button className=\"mp-button\" disabled={busy} onClick={() => void onRefresh()}>\n {busy ? t('refreshBusy') : t('refresh')}\n </button>\n <button className=\"mp-button mp-button-ghost\" disabled={busy} onClick={() => void onReconcile()}>\n {t('reconcileNow')}\n </button>\n </div>\n </section>\n\n <hr className=\"mp-divider\" />\n\n <section className=\"mp-group\">\n <h4 className=\"mp-group-title\">{t('providerMap')}</h4>\n <p className=\"mp-desc\">{t('providerMapDesc')}</p>\n {mappingRows.map((row, index) => (\n <div className=\"mp-map-row\" key={index}>\n <input\n className=\"mp-input\"\n value={row.from}\n disabled={saving}\n onChange={(event) => {\n const next = [...mappingRows]\n next[index] = { ...row, from: event.target.value }\n setMappingRows(next)\n }}\n />\n <span className=\"mp-map-arrow\">→</span>\n <input\n className=\"mp-input\"\n value={row.to}\n disabled={saving}\n onChange={(event) => {\n const next = [...mappingRows]\n next[index] = { ...row, to: event.target.value }\n setMappingRows(next)\n }}\n />\n <button\n className=\"mp-button mp-button-ghost\"\n disabled={saving}\n onClick={() => setMappingRows(mappingRows.filter((_, i) => i !== index))}\n >\n {t('removeMapping')}\n </button>\n </div>\n ))}\n <div className=\"mp-map-row\">\n <input\n className=\"mp-input\"\n placeholder=\"dsh provider\"\n value={newFrom}\n onChange={(event) => setNewFrom(event.target.value)}\n />\n <span className=\"mp-map-arrow\">→</span>\n <input\n className=\"mp-input\"\n placeholder=\"models.dev provider\"\n value={newTo}\n onChange={(event) => setNewTo(event.target.value)}\n />\n <button\n className=\"mp-button mp-button-ghost\"\n disabled={newFrom.trim().length === 0 || newTo.trim().length === 0}\n onClick={() => {\n setMappingRows([...mappingRows, { from: newFrom.trim(), to: newTo.trim() }])\n setNewFrom('')\n setNewTo('')\n }}\n >\n {t('addMapping')}\n </button>\n </div>\n <div className=\"mp-actions\">\n <button className=\"mp-button\" disabled={saving} onClick={() => void onApplyMappings()}>\n {saving ? t('saving') : '✓ ' + t('providerMap')}\n </button>\n </div>\n </section>\n\n <hr className=\"mp-divider\" />\n\n <section className=\"mp-group\">\n <h4 className=\"mp-group-title\">{t('report')}</h4>\n {report === null ? (\n <p className=\"mp-muted\">{t('reportNever')}</p>\n ) : (\n <ul className=\"mp-report\">\n <li>{t('reportAt')}: {formatTime(report.at)}</li>\n <li>{t('reportFilled')}: <strong>{report.filled}</strong></li>\n <li>{t('reportTouched')}: <strong>{report.touched}</strong></li>\n <li>\n {t('reportUnmatched')}:{' '}\n {report.unmatched.length === 0\n ? t('reportEmpty')\n : <code className=\"mp-code\">{report.unmatched.join(', ')}</code>}\n </li>\n </ul>\n )}\n </section>\n\n {error !== null && <p className=\"mp-error\">{error}</p>}\n </div>\n )\n}\n","/**\n * @fonlan/dsh-model-parameters client half: the plugin's own Settings section.\n *\n * Registers into the settings.section slot, so the page owns one entry in the\n * settings sidebar and renders in the panel's content column. The page itself\n * lives in ./settings-section.\n *\n * Deps resolved from the browser module table: react only. The slots service\n * is reached through the cordis context; types come from devDependencies and\n * are erased at build time.\n */\nimport type { Context } from '@deepseek-ai/cordis'\ntype ClientContext = Context\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport { LOCALE_NS, zh, en } from './locales'\nimport { makeSettingsSection } from './settings-section'\n\n/** The settings sidebar entry this page owns (must stay stable). */\nconst SECTION_ID = 'model-parameters'\n\n/** The slots service face (subset of @deepseek-ai/dsh-client-ui-slots). */\ninterface SlotEntry {\n name: string\n id?: string\n order?: number\n label?: () => string\n locale?: string\n}\n\ninterface Slots {\n inject(name: string, register: () => unknown): unknown\n register(def: SlotEntry, component: unknown): unknown\n}\n\n/** Services required before mounting (provided by the client runtime). */\nexport const inject = ['slots', 'locale']\n\n/** Client plugin body. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => {\n const off = ctx.locale.register(LOCALE_NS, { zh, en })\n return () => off()\n }, 'model-parameters: dictionaries')\n\n const t = ctx.locale.bind(LOCALE_NS) as unknown as (key: string) => string\n const Section = makeSettingsSection(ctx)\n const slots = (ctx as unknown as { slots: Slots }).slots\n slots.inject('settings.section', () =>\n slots.register({\n name: 'settings.section',\n id: SECTION_ID,\n order: 320,\n label: () => t('settingsTitle'),\n locale: LOCALE_NS,\n }, Section),\n )\n}\n"],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
|
-
import { settingsNamespace } from "@deepseek-ai/dsh-settings";
|
|
3
2
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
3
|
import { homedir } from "node:os";
|
|
5
4
|
import { join } from "node:path";
|
|
@@ -306,8 +305,8 @@ function acceptedInputModalities(entry) {
|
|
|
306
305
|
}
|
|
307
306
|
//#endregion
|
|
308
307
|
//#region src/server/service.ts
|
|
309
|
-
const TARGET =
|
|
310
|
-
const OWN =
|
|
308
|
+
const TARGET = TARGET_NS;
|
|
309
|
+
const OWN = PLUGIN_NS;
|
|
311
310
|
var ModelParametersService = class {
|
|
312
311
|
ctx;
|
|
313
312
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fonlan/dsh-model-parameters",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "DSH plugin: when a provider's model sync returns only ids, automatically fill display name, context window, max output tokens, reasoning efforts, and input modalities from the models.dev catalog (cached, TTL-refreshed), and surface a settings page with toggles, refresh, and a fill report.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -61,7 +61,6 @@
|
|
|
61
61
|
"client": {
|
|
62
62
|
"platform": "web",
|
|
63
63
|
"inject": [
|
|
64
|
-
"@deepseek-ai/dsh-client-runtime",
|
|
65
64
|
"@deepseek-ai/dsh-client-locale",
|
|
66
65
|
"@deepseek-ai/dsh-client-ui-slots",
|
|
67
66
|
"@deepseek-ai/dsh-client-ui-settings"
|
|
@@ -70,14 +69,13 @@
|
|
|
70
69
|
},
|
|
71
70
|
"peerDependencies": {
|
|
72
71
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
73
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
74
|
-
"@deepseek-ai/dsh-settings": "^0.1.
|
|
75
|
-
"@deepseek-ai/dsh-host-webserver": "^0.1.
|
|
76
|
-
"@deepseek-ai/dsh-llm-pi-ai": "^0.1.
|
|
77
|
-
"@deepseek-ai/dsh-client-
|
|
78
|
-
"@deepseek-ai/dsh-client-
|
|
79
|
-
"@deepseek-ai/dsh-client-ui-
|
|
80
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6",
|
|
72
|
+
"@deepseek-ai/schemastery": "^3.18.2",
|
|
73
|
+
"@deepseek-ai/dsh-settings": "^0.1.2-alpha.2",
|
|
74
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.2-alpha.2",
|
|
75
|
+
"@deepseek-ai/dsh-llm-pi-ai": "^0.1.2-alpha.2",
|
|
76
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.2-alpha.2",
|
|
77
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.2-alpha.2",
|
|
78
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.2-alpha.2",
|
|
81
79
|
"react": "^18.2.0",
|
|
82
80
|
"react-dom": "^18.2.0"
|
|
83
81
|
},
|
|
@@ -88,14 +86,13 @@
|
|
|
88
86
|
"tsdown": "^0.22.14",
|
|
89
87
|
"typescript": "^5.9.0",
|
|
90
88
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
91
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
92
|
-
"@deepseek-ai/dsh-settings": "^0.1.
|
|
93
|
-
"@deepseek-ai/dsh-host-webserver": "^0.1.
|
|
94
|
-
"@deepseek-ai/dsh-llm-pi-ai": "^0.1.
|
|
95
|
-
"@deepseek-ai/dsh-client-
|
|
96
|
-
"@deepseek-ai/dsh-client-
|
|
97
|
-
"@deepseek-ai/dsh-client-ui-
|
|
98
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6"
|
|
89
|
+
"@deepseek-ai/schemastery": "^3.18.2",
|
|
90
|
+
"@deepseek-ai/dsh-settings": "^0.1.2-alpha.2",
|
|
91
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.2-alpha.2",
|
|
92
|
+
"@deepseek-ai/dsh-llm-pi-ai": "^0.1.2-alpha.2",
|
|
93
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.2-alpha.2",
|
|
94
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.2-alpha.2",
|
|
95
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.2-alpha.2"
|
|
99
96
|
},
|
|
100
97
|
"packageManager": "pnpm@11.21.0"
|
|
101
98
|
}
|
package/src/client/index.tsx
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fonlan/dsh-model-parameters client half: the plugin's own Settings
|
|
2
|
+
* @fonlan/dsh-model-parameters client half: the plugin's own Settings section.
|
|
3
3
|
*
|
|
4
|
-
* Registers into the
|
|
5
|
-
* settings
|
|
6
|
-
*
|
|
7
|
-
* exactly like @fonlan/dsh-web-auth. The card draws its own expandable chrome
|
|
8
|
-
* (external plugins cannot import the built-in PluginCard) with styles aligned
|
|
9
|
-
* to the built-in plugin cards.
|
|
4
|
+
* Registers into the settings.section slot, so the page owns one entry in the
|
|
5
|
+
* settings sidebar and renders in the panel's content column. The page itself
|
|
6
|
+
* lives in ./settings-section.
|
|
10
7
|
*
|
|
11
8
|
* Deps resolved from the browser module table: react only. The slots service
|
|
12
9
|
* is reached through the cordis context; types come from devDependencies and
|
|
13
10
|
* are erased at build time.
|
|
14
11
|
*/
|
|
15
|
-
import type {
|
|
12
|
+
import type { Context } from '@deepseek-ai/cordis'
|
|
13
|
+
type ClientContext = Context
|
|
16
14
|
import type {} from '@deepseek-ai/dsh-client-locale/client'
|
|
17
15
|
import type {} from '@deepseek-ai/dsh-client-ui-slots'
|
|
18
16
|
import { LOCALE_NS, zh, en } from './locales'
|
|
19
|
-
import {
|
|
17
|
+
import { makeSettingsSection } from './settings-section'
|
|
20
18
|
|
|
21
|
-
/** The settings
|
|
22
|
-
const
|
|
19
|
+
/** The settings sidebar entry this page owns (must stay stable). */
|
|
20
|
+
const SECTION_ID = 'model-parameters'
|
|
23
21
|
|
|
24
22
|
/** The slots service face (subset of @deepseek-ai/dsh-client-ui-slots). */
|
|
25
23
|
interface SlotEntry {
|
|
26
24
|
name: string
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
id?: string
|
|
26
|
+
order?: number
|
|
27
|
+
label?: () => string
|
|
28
|
+
locale?: string
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
interface Slots {
|
|
@@ -43,12 +43,16 @@ export function apply(ctx: ClientContext): void {
|
|
|
43
43
|
return () => off()
|
|
44
44
|
}, 'model-parameters: dictionaries')
|
|
45
45
|
|
|
46
|
-
const
|
|
46
|
+
const t = ctx.locale.bind(LOCALE_NS) as unknown as (key: string) => string
|
|
47
|
+
const Section = makeSettingsSection(ctx)
|
|
47
48
|
const slots = (ctx as unknown as { slots: Slots }).slots
|
|
48
|
-
slots.inject('settings.
|
|
49
|
+
slots.inject('settings.section', () =>
|
|
49
50
|
slots.register({
|
|
50
|
-
name: 'settings.
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
name: 'settings.section',
|
|
52
|
+
id: SECTION_ID,
|
|
53
|
+
order: 320,
|
|
54
|
+
label: () => t('settingsTitle'),
|
|
55
|
+
locale: LOCALE_NS,
|
|
56
|
+
}, Section),
|
|
53
57
|
)
|
|
54
58
|
}
|
package/src/client/locales.ts
CHANGED
|
@@ -6,9 +6,7 @@ export const LOCALE_NS = 'model-parameters'
|
|
|
6
6
|
|
|
7
7
|
export const zh = {
|
|
8
8
|
settingsTitle: '模型参数补全',
|
|
9
|
-
|
|
10
|
-
collapse: '收起',
|
|
11
|
-
expand: '展开',
|
|
9
|
+
sectionSub: '补全字段、目录刷新、Provider 映射与补全报告。',
|
|
12
10
|
master: '启用自动补全',
|
|
13
11
|
masterDesc: '关闭后不再自动补全任何字段(已补全的值保留)。',
|
|
14
12
|
fields: '补全字段',
|
|
@@ -53,9 +51,7 @@ export const zh = {
|
|
|
53
51
|
|
|
54
52
|
export const en: Record<keyof typeof zh, string> = {
|
|
55
53
|
settingsTitle: 'Model Parameters',
|
|
56
|
-
|
|
57
|
-
collapse: 'Collapse',
|
|
58
|
-
expand: 'Expand',
|
|
54
|
+
sectionSub: 'Field toggles, catalog refresh, provider mapping and the fill report.',
|
|
59
55
|
master: 'Enable auto-fill',
|
|
60
56
|
masterDesc: 'When off, no fields are filled (already-filled values are kept).',
|
|
61
57
|
fields: 'Fields to fill',
|
|
@@ -1,98 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Styles for the Model Parameters
|
|
2
|
+
* Styles for the Model Parameters settings page.
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* field language (ValueField): border-l2 inputs on bg-layer-3, inverted
|
|
9
|
-
* primary buttons, divider-separated groups.
|
|
4
|
+
* The page occupies the settings panel's content column: a header (title plus
|
|
5
|
+
* a one-line summary) over divider-separated control groups. Inner controls
|
|
6
|
+
* follow the built-in settings language: border-l2 inputs on bg-layer-3,
|
|
7
|
+
* inverted primary buttons.
|
|
10
8
|
*/
|
|
11
9
|
|
|
12
|
-
/*
|
|
10
|
+
/* page layout */
|
|
13
11
|
|
|
14
|
-
.mp-
|
|
15
|
-
border: 1px solid var(--dsw-alias-border-l2, #2a3346);
|
|
16
|
-
background: var(--dsw-alias-bg-layer-3, #0d1017);
|
|
17
|
-
border-radius: 12px;
|
|
18
|
-
list-style: none;
|
|
19
|
-
transition: border-color .16s, background .16s;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.mp-card:hover {
|
|
23
|
-
border-color: var(--dsw-alias-label-dimmed, #4a5468);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.mp-card[data-open] {
|
|
27
|
-
background: var(--dsw-alias-bg-layer-2, #141a26);
|
|
28
|
-
border-color: var(--dsw-alias-label-dimmed, #4a5468);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.mp-card-head {
|
|
32
|
-
appearance: none;
|
|
33
|
-
width: 100%;
|
|
34
|
-
font: inherit;
|
|
35
|
-
color: inherit;
|
|
36
|
-
text-align: left;
|
|
37
|
-
cursor: pointer;
|
|
38
|
-
background: transparent;
|
|
39
|
-
border: 0;
|
|
40
|
-
border-radius: 12px;
|
|
41
|
-
align-items: center;
|
|
42
|
-
gap: 12px;
|
|
43
|
-
padding: 14px 16px;
|
|
12
|
+
.mp-page {
|
|
44
13
|
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
gap: 16px;
|
|
16
|
+
max-width: 720px;
|
|
45
17
|
}
|
|
46
18
|
|
|
47
|
-
.mp-
|
|
48
|
-
outline: 2px solid var(--dsw-alias-brand-primary, #4f8cff);
|
|
49
|
-
outline-offset: -2px;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.mp-card-headText {
|
|
53
|
-
flex-direction: column;
|
|
54
|
-
flex: 1;
|
|
55
|
-
gap: 4px;
|
|
56
|
-
min-width: 0;
|
|
19
|
+
.mp-page-head {
|
|
57
20
|
display: flex;
|
|
21
|
+
flex-direction: column;
|
|
22
|
+
gap: 6px;
|
|
58
23
|
}
|
|
59
24
|
|
|
60
|
-
.mp-
|
|
25
|
+
.mp-page-title {
|
|
26
|
+
margin: 0;
|
|
61
27
|
color: var(--dsw-alias-label-primary, #e6e6e6);
|
|
62
28
|
font-size: 15px;
|
|
63
29
|
font-weight: 600;
|
|
64
30
|
line-height: 1.4;
|
|
65
31
|
}
|
|
66
32
|
|
|
67
|
-
.mp-
|
|
33
|
+
.mp-page-sub {
|
|
34
|
+
margin: 0;
|
|
68
35
|
color: var(--dsw-alias-label-tertiary, #8b93a7);
|
|
69
36
|
font-size: 13px;
|
|
70
37
|
line-height: 1.5;
|
|
71
38
|
}
|
|
72
39
|
|
|
73
|
-
|
|
74
|
-
color: var(--dsw-alias-label-tertiary, #8b93a7);
|
|
75
|
-
flex: none;
|
|
76
|
-
transition: transform .16s;
|
|
77
|
-
display: flex;
|
|
78
|
-
align-items: center;
|
|
79
|
-
justify-content: center;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.mp-card-chevron[data-open] {
|
|
83
|
-
transform: rotate(180deg);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.mp-card-body {
|
|
87
|
-
border-top: 1px solid var(--dsw-alias-border-l2, #2a3346);
|
|
88
|
-
margin: 0 16px;
|
|
89
|
-
padding: 12px 0 8px;
|
|
90
|
-
display: flex;
|
|
91
|
-
flex-direction: column;
|
|
92
|
-
gap: 12px;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/* ── body layout ────────────────────────────────────────────────────────── */
|
|
40
|
+
/* body layout */
|
|
96
41
|
|
|
97
42
|
.mp-body {
|
|
98
43
|
display: flex;
|
|
@@ -141,7 +86,7 @@
|
|
|
141
86
|
line-height: 1.6;
|
|
142
87
|
}
|
|
143
88
|
|
|
144
|
-
/*
|
|
89
|
+
/* toggles */
|
|
145
90
|
|
|
146
91
|
.mp-toggle {
|
|
147
92
|
display: flex;
|
|
@@ -177,7 +122,7 @@
|
|
|
177
122
|
line-height: 1.5;
|
|
178
123
|
}
|
|
179
124
|
|
|
180
|
-
/*
|
|
125
|
+
/* catalog meta / ttl */
|
|
181
126
|
|
|
182
127
|
.mp-meta {
|
|
183
128
|
display: flex;
|
|
@@ -198,7 +143,7 @@
|
|
|
198
143
|
line-height: 1.6;
|
|
199
144
|
}
|
|
200
145
|
|
|
201
|
-
/*
|
|
146
|
+
/* inputs */
|
|
202
147
|
|
|
203
148
|
.mp-input {
|
|
204
149
|
border: 1px solid var(--dsw-alias-border-l2, #2a3346);
|
|
@@ -226,7 +171,7 @@
|
|
|
226
171
|
width: 72px;
|
|
227
172
|
}
|
|
228
173
|
|
|
229
|
-
/*
|
|
174
|
+
/* mapping rows */
|
|
230
175
|
|
|
231
176
|
.mp-map-row {
|
|
232
177
|
display: flex;
|
|
@@ -244,7 +189,7 @@
|
|
|
244
189
|
flex: none;
|
|
245
190
|
}
|
|
246
191
|
|
|
247
|
-
/*
|
|
192
|
+
/* buttons */
|
|
248
193
|
|
|
249
194
|
.mp-actions {
|
|
250
195
|
display: flex;
|
|
@@ -291,7 +236,7 @@
|
|
|
291
236
|
border-color: var(--dsw-alias-label-dimmed, #4a5468);
|
|
292
237
|
}
|
|
293
238
|
|
|
294
|
-
/*
|
|
239
|
+
/* report / badges / code */
|
|
295
240
|
|
|
296
241
|
.mp-report {
|
|
297
242
|
margin: 0;
|
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The Model Parameters
|
|
3
|
-
* provider→models.dev mapping overrides, a manual refresh/fill action, the
|
|
4
|
-
* catalog freshness line, and the last fill report (filled / touched /
|
|
5
|
-
* unmatched).
|
|
2
|
+
* The Model Parameters settings page (设置 → 侧栏「模型参数补全」).
|
|
6
3
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* that discloses the controls in place.
|
|
4
|
+
* Registers into the `settings.section` slot, so the page owns one entry in
|
|
5
|
+
* the settings sidebar and renders its content in the panel's content column.
|
|
6
|
+
* Content: master + per-field toggles, catalog TTL, provider→models.dev
|
|
7
|
+
* mapping overrides, a manual refresh/fill action, the catalog freshness line,
|
|
8
|
+
* and the last fill report (filled / touched / unmatched).
|
|
13
9
|
*
|
|
14
10
|
* All reads/mutations go through the plugin's fenced API; config persists into
|
|
15
11
|
* the `model-parameters` settings namespace (settings.yaml).
|
|
16
12
|
*/
|
|
17
13
|
import { useCallback, useEffect, useState, useSyncExternalStore } from 'react'
|
|
18
|
-
import type {
|
|
14
|
+
import type { Context } from '@deepseek-ai/cordis'
|
|
15
|
+
type ClientContext = Context
|
|
19
16
|
import type { Translate } from '@deepseek-ai/dsh-client-ui-slots'
|
|
20
17
|
import { LOCALE_NS } from './locales'
|
|
21
18
|
import { api, type PluginState } from './api'
|
|
22
19
|
import type { ModelParametersConfig } from '../shared/config.js'
|
|
23
|
-
import './settings-
|
|
20
|
+
import './settings-section.css'
|
|
24
21
|
|
|
25
22
|
function useLocaleRevision(ctx: ClientContext): number {
|
|
26
23
|
const subscribe = useCallback(
|
|
@@ -51,7 +48,7 @@ function formatTime(epochMs: number): string {
|
|
|
51
48
|
}
|
|
52
49
|
}
|
|
53
50
|
|
|
54
|
-
export function
|
|
51
|
+
export function makeSettingsSection(ctx: ClientContext): () => JSX.Element {
|
|
55
52
|
const t: Translate = (() => {
|
|
56
53
|
try {
|
|
57
54
|
return ctx.locale.bind(LOCALE_NS) as unknown as Translate
|
|
@@ -60,10 +57,8 @@ export function makeSettingsCard(ctx: ClientContext): () => JSX.Element {
|
|
|
60
57
|
}
|
|
61
58
|
})()
|
|
62
59
|
|
|
63
|
-
return function
|
|
60
|
+
return function ModelParametersSettingsSection(): JSX.Element {
|
|
64
61
|
useLocaleRevision(ctx)
|
|
65
|
-
// Card-local disclosure: collapsed by default, like the built-in plugin cards.
|
|
66
|
-
const [open, setOpen] = useState(false)
|
|
67
62
|
const [state, setState] = useState<PluginState | null>(null)
|
|
68
63
|
const [error, setError] = useState<string | null>(null)
|
|
69
64
|
const [loading, setLoading] = useState(true)
|
|
@@ -139,58 +134,42 @@ export function makeSettingsCard(ctx: ClientContext): () => JSX.Element {
|
|
|
139
134
|
await patchConfig({ providerMap })
|
|
140
135
|
}, [mappingRows, patchConfig])
|
|
141
136
|
|
|
142
|
-
const title = t('settingsTitle')
|
|
143
|
-
|
|
144
137
|
return (
|
|
145
|
-
<
|
|
146
|
-
<
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
<
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
{
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
busy={busy}
|
|
173
|
-
mappingRows={mappingRows}
|
|
174
|
-
newFrom={newFrom}
|
|
175
|
-
newTo={newTo}
|
|
176
|
-
setNewFrom={setNewFrom}
|
|
177
|
-
setNewTo={setNewTo}
|
|
178
|
-
setMappingRows={setMappingRows}
|
|
179
|
-
onPatchConfig={patchConfig}
|
|
180
|
-
onRefresh={refresh}
|
|
181
|
-
onReconcile={reconcileNow}
|
|
182
|
-
onApplyMappings={applyMappings}
|
|
183
|
-
/>
|
|
184
|
-
)}
|
|
185
|
-
</div>
|
|
138
|
+
<div className="mp-page">
|
|
139
|
+
<header className="mp-page-head">
|
|
140
|
+
<h3 className="mp-page-title">{t('settingsTitle')}</h3>
|
|
141
|
+
<p className="mp-page-sub">{t('sectionSub')}</p>
|
|
142
|
+
</header>
|
|
143
|
+
{error !== null && state === null ? (
|
|
144
|
+
<p className="mp-error">{t('error')}: {error}</p>
|
|
145
|
+
) : loading || state === null ? (
|
|
146
|
+
<p className="mp-muted">{t('saving')}</p>
|
|
147
|
+
) : (
|
|
148
|
+
<ModelParametersBody
|
|
149
|
+
t={t}
|
|
150
|
+
state={state}
|
|
151
|
+
error={error}
|
|
152
|
+
saving={saving}
|
|
153
|
+
busy={busy}
|
|
154
|
+
mappingRows={mappingRows}
|
|
155
|
+
newFrom={newFrom}
|
|
156
|
+
newTo={newTo}
|
|
157
|
+
setNewFrom={setNewFrom}
|
|
158
|
+
setNewTo={setNewTo}
|
|
159
|
+
setMappingRows={setMappingRows}
|
|
160
|
+
onPatchConfig={patchConfig}
|
|
161
|
+
onRefresh={refresh}
|
|
162
|
+
onReconcile={reconcileNow}
|
|
163
|
+
onApplyMappings={applyMappings}
|
|
164
|
+
/>
|
|
186
165
|
)}
|
|
187
|
-
</
|
|
166
|
+
</div>
|
|
188
167
|
)
|
|
189
168
|
}
|
|
190
169
|
}
|
|
191
170
|
|
|
192
|
-
/** The
|
|
193
|
-
function
|
|
171
|
+
/** The page body: divider-separated control groups. */
|
|
172
|
+
function ModelParametersBody(props: {
|
|
194
173
|
t: Translate
|
|
195
174
|
state: PluginState
|
|
196
175
|
error: string | null
|
package/src/server/service.ts
CHANGED
|
@@ -13,11 +13,7 @@
|
|
|
13
13
|
* second patch (the next event sees the fields present and produces no ops).
|
|
14
14
|
*/
|
|
15
15
|
import type { Context } from '@deepseek-ai/cordis'
|
|
16
|
-
import {
|
|
17
|
-
settingsNamespace,
|
|
18
|
-
type SettingsScope,
|
|
19
|
-
type SettingsPathOp,
|
|
20
|
-
} from '@deepseek-ai/dsh-settings'
|
|
16
|
+
import type { SettingsScope, SettingsPathOp } from '@deepseek-ai/dsh-settings'
|
|
21
17
|
import type { PiAiModelProfile } from '@deepseek-ai/dsh-llm-pi-ai'
|
|
22
18
|
import {
|
|
23
19
|
Config,
|
|
@@ -34,8 +30,8 @@ import {
|
|
|
34
30
|
type CatalogSnapshot,
|
|
35
31
|
} from './catalog.js'
|
|
36
32
|
|
|
37
|
-
const TARGET =
|
|
38
|
-
const OWN =
|
|
33
|
+
const TARGET = TARGET_NS
|
|
34
|
+
const OWN = PLUGIN_NS
|
|
39
35
|
|
|
40
36
|
/** One reconcile run's outcome, surfaced to the settings page. */
|
|
41
37
|
export interface FillReport {
|