@dsh-plus/llm-pi 0.1.12 → 0.1.14

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 CHANGED
@@ -6,6 +6,25 @@ window.__ModuleLoader__.load({
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
7
  let react_jsx_runtime = require("react/jsx-runtime");
8
8
  let react = require("react");
9
+ //#region ../shared/src/client/icons.tsx
10
+ /** 官方 IconChevronDownOutline14 的同构实现(path 数据逐字一致)。 */
11
+ function ChevronDownIcon(props) {
12
+ const size = props.size ?? 14;
13
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
14
+ width: size,
15
+ height: size,
16
+ className: props.className,
17
+ viewBox: "0 0 14 14",
18
+ fill: "none",
19
+ xmlns: "http://www.w3.org/2000/svg",
20
+ "aria-hidden": "true",
21
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
22
+ d: "M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z",
23
+ fill: "currentColor"
24
+ })
25
+ });
26
+ }
27
+ //#endregion
9
28
  //#region ../shared/src/client/card.tsx
10
29
  const IDLE_STATUS = {
11
30
  kind: "idle",
@@ -41,10 +60,7 @@ window.__ModuleLoader__.load({
41
60
  className: `${p}-pending`,
42
61
  children: props.dirtyLabel
43
62
  }) : null,
44
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
45
- className: `${p}-chevron${props.open ? ` ${p}-chevronOpen` : ""}`,
46
- children: "▾"
47
- })
63
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDownIcon, { className: `${p}-chevron${props.open ? ` ${p}-chevronOpen` : ""}` })
48
64
  ]
49
65
  }), props.open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
50
66
  className: `${p}-body`,
@@ -110,6 +126,11 @@ window.__ModuleLoader__.load({
110
126
  ]
111
127
  });
112
128
  }
129
+ /**
130
+ * 勾选行:自绘圆角扁平开关(switch),对齐官方 WebUI 无原生 checkbox 的
131
+ * 设计语言(官方选择类控件全走胶囊/菜单,见 cardCss 的 -switch 规则)。
132
+ * 语义保持 checkbox(无障碍树与表单语义不变),视觉自绘。
133
+ */
113
134
  function CheckRow(props) {
114
135
  const p = props.prefix ?? "dshp";
115
136
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -117,6 +138,8 @@ window.__ModuleLoader__.load({
117
138
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
118
139
  id: props.id,
119
140
  type: "checkbox",
141
+ role: "switch",
142
+ "aria-checked": props.checked,
120
143
  checked: props.checked,
121
144
  disabled: props.disabled === true,
122
145
  onChange: (event) => props.onEdit(event.target.checked)
@@ -173,14 +196,15 @@ window.__ModuleLoader__.load({
173
196
  //#endregion
174
197
  //#region ../shared/src/client/scope.ts
175
198
  /**
176
- * api 直连实现的命名空间 scope(官方配置页 tab 同款模式)。
199
+ * remote.settings 直连实现的命名空间 scope(官方配置页 tab 同款模式)。
177
200
  * 读:describe 取命名空间视图(脱敏 value/revision + 顶层 writable);
178
201
  * 刷新:remote `settings/document-updated`(按命名空间过滤)与
179
202
  * `connection/reset`;generation 防旧读覆盖新发布。任何页面 origin
180
203
  * (loopback 或 tailnet 信任域名)下行为一致。
181
204
  * effect 归属调用方 fiber(label 需含插件名以便诊断)。
182
205
  */
183
- function createApiScope(api, ns, c, label) {
206
+ function createSettingsScope(c, ns, label) {
207
+ const remote = c.get("remote");
184
208
  let state = {
185
209
  status: "loading",
186
210
  value: void 0,
@@ -195,36 +219,37 @@ window.__ModuleLoader__.load({
195
219
  };
196
220
  const load = async () => {
197
221
  const gen = ++generation;
198
- let response;
222
+ let view;
199
223
  try {
200
- response = await api.describe({});
224
+ const response = await remote.settings.describe();
225
+ if (!response.ok) return;
226
+ view = response.value;
201
227
  } catch {
202
228
  return;
203
229
  }
204
- if (gen !== generation || !response.result.ok) return;
205
- const writable = response.result.value?.writable ?? false;
206
- const view = response.result.value?.namespaces.find((candidate) => candidate.ns === ns);
207
- if (view === void 0) {
230
+ if (gen !== generation) return;
231
+ const namespace = view.namespaces.find((candidate) => candidate.ns === ns);
232
+ if (namespace === void 0) {
208
233
  publish({
209
234
  status: "unavailable",
210
235
  value: void 0,
211
236
  revision: void 0,
212
- writable
237
+ writable: view.writable
213
238
  });
214
239
  return;
215
240
  }
216
241
  publish({
217
242
  status: "ready",
218
- value: view.value,
219
- revision: view.revision,
220
- writable
243
+ value: namespace.value,
244
+ revision: namespace.revision,
245
+ writable: view.writable
221
246
  });
222
247
  };
223
248
  const refresh = (namespace) => {
224
249
  if (namespace !== void 0 && namespace !== ns) return;
225
250
  load();
226
251
  };
227
- const disposers = [c.get("remote").$on("settings/document-updated", refresh), c.on("connection/reset", () => {
252
+ const disposers = [remote.$on("settings/document-updated", refresh), c.on("connection/reset", () => {
228
253
  load();
229
254
  })];
230
255
  c.effect(() => () => {
@@ -242,6 +267,20 @@ window.__ModuleLoader__.load({
242
267
  load
243
268
  };
244
269
  }
270
+ /** 以 remote.settings 构造命名空间绑定的 api 面。 */
271
+ function createNamespaceApi(remote, ns) {
272
+ return {
273
+ update: async (patch, expectedRevision) => {
274
+ const response = await remote.update(ns, patch, expectedRevision);
275
+ if (!response.ok) throw new Error(response.error.message ?? "settings update failed");
276
+ },
277
+ describe: async () => {
278
+ const response = await remote.describe();
279
+ if (!response.ok) throw new Error(response.error.message ?? "settings describe failed");
280
+ return response.value;
281
+ }
282
+ };
283
+ }
245
284
  //#endregion
246
285
  //#region ../shared/src/client/styles.ts
247
286
  /**
@@ -265,7 +304,7 @@ window.__ModuleLoader__.load({
265
304
  .${prefix}-headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}
266
305
  .${prefix}-name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}
267
306
  .${prefix}-description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}
268
- .${prefix}-chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s;font-size:12px}
307
+ .${prefix}-chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s;display:inline-flex}
269
308
  .${prefix}-chevronOpen{transform:rotate(180deg)}
270
309
  .${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}
271
310
  .${prefix}-statusBadge{white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
@@ -279,16 +318,24 @@ window.__ModuleLoader__.load({
279
318
  .${prefix}-badge{white-space:nowrap;border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
280
319
  .${prefix}-badgeSet{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary)}
281
320
  .${prefix}-badgeUnset{color:var(--dsw-alias-label-tertiary)}
282
- .${prefix}-input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px}
321
+ .${prefix}-input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;transition:border-color .18s,background .18s}
322
+ .${prefix}-input:hover:not(:disabled):not(:focus-visible){border-color:var(--dsw-alias-label-dimmed)}
283
323
  .${prefix}-input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}
284
324
  .${prefix}-input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}
285
325
  .${prefix}-inputInvalid{border-color:var(--dsw-alias-label-error)}
286
- .${prefix}-select{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--dsw-alias-label-tertiary) 50%),linear-gradient(135deg,var(--dsw-alias-label-tertiary) 50%,transparent 50%);background-position:calc(100% - 16px) 50%,calc(100% - 11px) 50%;background-size:5px 5px;background-repeat:no-repeat;padding-right:28px}
326
+ .${prefix}-select{appearance:none;background:var(--dsw-alias-bg-module-platform);border:none;cursor:pointer;background-image:linear-gradient(45deg,transparent 50%,var(--dsw-alias-label-secondary) 50%),linear-gradient(135deg,var(--dsw-alias-label-secondary) 50%,transparent 50%);background-position:calc(100% - 16px) 50%,calc(100% - 11px) 50%;background-size:5px 5px;background-repeat:no-repeat;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;height:34px;box-sizing:border-box;border-radius:8px;padding:0 30px 0 12px;transition:background-color .18s}
327
+ .${prefix}-select:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover)}
287
328
  .${prefix}-hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}
288
329
  .${prefix}-invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}
289
- .${prefix}-checkRow{align-items:center;gap:8px;display:flex;padding:6px 0}
290
- .${prefix}-checkRow input{accent-color:var(--dsw-alias-brand-primary)}
291
- .${prefix}-checkRow label{color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.5;cursor:pointer}
330
+ .${prefix}-checkRow{align-items:center;gap:10px;display:flex;padding:6px 0}
331
+ .${prefix}-checkRow label{color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.5;cursor:pointer;flex:1;min-width:0}
332
+ /* 自绘圆角扁平开关(官方 UI 无可见原生 checkbox,选择类全走胶囊/菜单) */
333
+ .${prefix}-checkRow input{appearance:none;-webkit-appearance:none;position:relative;box-sizing:border-box;background:var(--dsw-alias-bg-module-platform);border:none;border-radius:999px;width:34px;height:20px;flex:none;cursor:pointer;transition:background .18s;margin:0}
334
+ .${prefix}-checkRow input::after{content:"";position:absolute;top:2px;left:2px;background:var(--dsw-alias-label-primary);border-radius:999px;width:16px;height:16px;transition:left .18s cubic-bezier(.4,0,.2,1)}
335
+ .${prefix}-checkRow input:checked{background:var(--dsw-alias-brand-primary)}
336
+ .${prefix}-checkRow input:checked::after{left:16px;background:var(--dsw-alias-bg-base)}
337
+ .${prefix}-checkRow input:disabled{opacity:.4;cursor:default}
338
+ .${prefix}-checkRow input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}
292
339
  .${prefix}-groupLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600;padding:12px 0 2px;margin:0}
293
340
  .${prefix}-readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}
294
341
  .${prefix}-warn{color:var(--dsw-alias-label-error);margin:12px 0 0;font-size:12px;line-height:1.5}
@@ -306,7 +353,6 @@ window.__ModuleLoader__.load({
306
353
  .${prefix}-header{padding:12px 12px}
307
354
  .${prefix}-input,.${prefix}-select{font-size:16px;height:40px}
308
355
  .${prefix}-checkRow{min-height:44px;padding:8px 0}
309
- .${prefix}-checkRow input{width:18px;height:18px;flex:none}
310
356
  .${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}
311
357
  .${prefix}-status{flex-basis:100%;flex:none}
312
358
  .${prefix}-btn{min-height:44px;flex:1;min-width:96px}
@@ -341,7 +387,7 @@ ${extra}
341
387
  * settings 命名空间字面量(纯常量,零依赖,浏览器半可安全引入)。
342
388
  * 服务端经 settingsNamespace() 品牌化后使用(config.ts),浏览器半将其作为
343
389
  * settings.plugin.item keyed 槽位的 key —— 同一字面量两处共用,防止漂移。
344
- * 契约:dsh rc7 起该槽位按「卡片编辑的 settings 命名空间」作 key 分发,
390
+ * 契约:0.1.2-alpha.1 起该槽位按「卡片编辑的 settings 命名空间」作 key 分发,
345
391
  * 官方配置页只渲染 key 命中 Host 已注册命名空间的卡片。
346
392
  * @module llm-pi/ns
347
393
  */
@@ -663,10 +709,7 @@ ${extra}
663
709
  id: props.id,
664
710
  "aria-expanded": open,
665
711
  onClick: () => setOpen(!open),
666
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
667
- className: `lpc-chevron${open ? " lpc-chevronOpen" : ""}`,
668
- children: "▾"
669
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
712
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDownIcon, { className: `lpc-chevron${open ? " lpc-chevronOpen" : ""}` }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
670
713
  className: "lpc-collapseTitle",
671
714
  children: props.title
672
715
  })]
@@ -909,13 +952,18 @@ ${extra}
909
952
  "medium",
910
953
  "high"
911
954
  ];
912
- /** 逐协议 compat 字段表(来源:compat.ts FIELDS_BY_PROTOCOL)。 */
955
+ /**
956
+ * 逐协议 compat 字段表(来源:compat.ts,逐字段镜像官方 catalog.ts COMPAT_GATES)。
957
+ * 只列 offer 字段(withhold 字段官方写时拒绝,UI 不提供);取值约束对齐官方
958
+ * config.ts compatProfile schema。
959
+ */
913
960
  const COMPAT_FIELDS = {
914
961
  "openai-completions": {
915
962
  supportsStore: "boolean",
916
963
  supportsDeveloperRole: "boolean",
917
964
  supportsReasoningEffort: "boolean",
918
965
  supportsUsageInStreaming: "boolean",
966
+ supportsFinishReason: "boolean",
919
967
  maxTokensField: ["max_completion_tokens", "max_tokens"],
920
968
  requiresToolResultName: "boolean",
921
969
  requiresAssistantAfterToolResult: "boolean",
@@ -923,9 +971,10 @@ ${extra}
923
971
  requiresReasoningContentOnAssistantMessages: "boolean",
924
972
  thinkingFormat: [
925
973
  "openai",
926
- "openrouter",
927
974
  "deepseek",
975
+ "openrouter",
928
976
  "together",
977
+ "baseten",
929
978
  "zai",
930
979
  "qwen",
931
980
  "chat-template",
@@ -934,44 +983,25 @@ ${extra}
934
983
  "ant-ling"
935
984
  ],
936
985
  chatTemplateKwargs: "object",
937
- openRouterRouting: "object",
938
- vercelGatewayRouting: "object",
939
- zaiToolStream: "boolean",
940
- supportsOpenAIGrammarTools: "boolean",
986
+ chatTemplateArgs: "object",
987
+ supportsThinkingTokenBudget: "boolean",
941
988
  supportsStrictMode: "boolean",
942
989
  cacheControlFormat: ["anthropic"],
943
- sendSessionAffinityHeaders: "boolean",
944
- deferredToolsMode: ["kimi"],
945
- sessionAffinityFormat: [
946
- "openai",
947
- "openai-nosession",
948
- "openrouter"
949
- ],
950
990
  supportsLongCacheRetention: "boolean"
951
991
  },
952
992
  "openai-responses": {
953
993
  supportsDeveloperRole: "boolean",
954
- sessionAffinityFormat: [
955
- "openai",
956
- "openai-nosession",
957
- "openrouter"
958
- ],
959
- supportsLongCacheRetention: "boolean",
960
994
  supportsStrictMode: "boolean",
961
- supportsOpenAIGrammarTools: "boolean",
962
- supportsToolSearch: "boolean",
963
- supportsExplicitPromptCacheMode: "boolean"
995
+ supportsLongCacheRetention: "boolean"
964
996
  },
965
997
  "anthropic-messages": {
966
998
  supportsEagerToolInputStreaming: "boolean",
967
999
  supportsLongCacheRetention: "boolean",
968
- sendSessionAffinityHeaders: "boolean",
969
1000
  supportsCacheControlOnTools: "boolean",
970
1001
  supportsTemperature: "boolean",
971
1002
  forceAdaptiveThinking: "boolean",
972
1003
  allowEmptySignature: "boolean",
973
- supportsStrictTools: "boolean",
974
- supportsToolReferences: "boolean"
1004
+ supportsStrictTools: "boolean"
975
1005
  }
976
1006
  };
977
1007
  /** 某协议的全部合法 compat 键(与服务端 compatFieldsOf 一致)。 */
@@ -1612,10 +1642,7 @@ ${extra}
1612
1642
  "aria-expanded": open,
1613
1643
  onClick: () => setOpen(!open),
1614
1644
  children: [
1615
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1616
- className: `lpc-chevron${open ? " lpc-chevronOpen" : ""}`,
1617
- children: "▾"
1618
- }),
1645
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDownIcon, { className: `lpc-chevron${open ? " lpc-chevronOpen" : ""}` }),
1619
1646
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1620
1647
  className: "lpc-routeKey",
1621
1648
  children: route
@@ -1697,7 +1724,7 @@ ${extra}
1697
1724
  /**
1698
1725
  * 「LLM 路由」配置卡片:注册进 settings.plugin.item 插槽(官方插件配置页)。
1699
1726
  * 顶部:enabled / catalogUrl / catalogRefreshHours / 只读状态行(kitSource、
1700
- * modelsDevStatus,来自模型目录端点)+ 保存(settings.replace 全量)与
1727
+ * modelsDevStatus,来自模型目录端点)+ 保存(settings.update 全量深合并)与
1701
1728
  * 错误/成功提示;下方为 providers 路由列表(新增/删除/字段编辑/compat/模型
1702
1729
  * 目录,见 views/)。外壳与基础控件走 @dsh-plus/shared/client 套件。
1703
1730
  * @module llm-pi/client/card
@@ -1783,12 +1810,7 @@ ${extra}
1783
1810
  const onSave = () => {
1784
1811
  setSaving(true);
1785
1812
  const revision = scope.getSnapshot().revision;
1786
- api.replace({
1787
- ns: SETTINGS_NS,
1788
- section: toPatch(draft),
1789
- ...revision !== void 0 ? { expectedRevision: revision } : {}
1790
- }).then(async (response) => {
1791
- if (!response.result.ok) throw new Error(response.result.error?.message ?? t("saveFailed"));
1813
+ api.update(toPatch(draft), revision).then(async () => {
1792
1814
  await scope.load();
1793
1815
  const next = scope.getSnapshot().value;
1794
1816
  if (next !== void 0) setDraft(draftFromValue(next));
@@ -2136,7 +2158,7 @@ ${extra}
2136
2158
  const PLUGIN_ID = "@dsh-plus/llm-pi";
2137
2159
  const cardCssAll = cardCss("lpc", `
2138
2160
  .lpc-input{width:100%;box-sizing:border-box}
2139
- .lpc-select{appearance:none}
2161
+ .lpc-select{appearance:none;cursor:pointer;background-image:linear-gradient(45deg,transparent 50%,var(--dsw-alias-label-secondary) 50%),linear-gradient(135deg,var(--dsw-alias-label-secondary) 50%,transparent 50%);background-position:calc(100% - 16px) 50%,calc(100% - 11px) 50%;background-size:5px 5px;background-repeat:no-repeat;padding-right:30px}
2140
2162
  .lpc-textarea{height:auto;min-height:72px;padding:8px 12px;line-height:1.5;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;resize:vertical}
2141
2163
  .lpc-checkRow{padding:3px 0}
2142
2164
  .lpc-statusRow{color:var(--dsw-alias-label-tertiary);margin:6px 0 0;font-size:12px;line-height:1.6;word-break:break-all}
@@ -2194,8 +2216,8 @@ ${extra}
2194
2216
  const inject = [
2195
2217
  "slots",
2196
2218
  "locale",
2197
- "connection",
2198
- "remote"
2219
+ "remote",
2220
+ "remote.settings"
2199
2221
  ];
2200
2222
  function apply(ctx) {
2201
2223
  const c = ctx;
@@ -2207,8 +2229,8 @@ ${extra}
2207
2229
  zh,
2208
2230
  en
2209
2231
  }), "llm-pi: locale");
2210
- const api = c.get("connection").api.settings;
2211
- const scope = createApiScope(api, SETTINGS_NS, c, "llm-pi: settings scope");
2232
+ const scope = createSettingsScope(c, SETTINGS_NS, "llm-pi: settings scope");
2233
+ const api = createNamespaceApi(c.get("remote").settings, SETTINGS_NS);
2212
2234
  c.slots.inject("settings.plugin.item", () => c.slots.register({
2213
2235
  name: "settings.plugin.item",
2214
2236
  key: SETTINGS_NS,
package/lib/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import z from "@deepseek-ai/schemastery";
2
2
  import { Context } from "@deepseek-ai/cordis";
3
3
  //#region src/config.d.ts
4
4
  /** settings 命名空间;webui 配置卡片与插件运行期读取同一份(字面量见 ./ns.ts)。 */
5
- declare const SETTINGS_NS: import("@deepseek-ai/dsh-settings").SettingsNamespace;
5
+ declare const SETTINGS_NS: Branded<"SettingsNamespace">;
6
6
  /** 本插件可为手写 route 提供的协议实现(与官方 PROTOCOLS 表一致)。 */
7
7
  declare const PROTOCOL_IDS: readonly ["openai-completions", "openai-responses", "anthropic-messages"];
8
8
  type ProtocolId = (typeof PROTOCOL_IDS)[number];
@@ -28,7 +28,6 @@ interface ModelEntryConfig {
28
28
  /** 以下仅 adapter: deepseek 的 route 有效(官方 llm-deepseek 目录字段)。 */
29
29
  imagePixelBudget?: number;
30
30
  imageMaxBytes?: number;
31
- imageDetail?: 'auto' | 'low';
32
31
  }
33
32
  /** 单个 provider route 配置(providers 字典的值)。 */
34
33
  interface ProviderProfileConfig {
@@ -56,6 +55,8 @@ interface ProviderProfileConfig {
56
55
  websocketConnectTimeoutMs?: number;
57
56
  streamIdleTimeoutMs?: number;
58
57
  maxRequestImageBytes?: number;
58
+ requestImagePixelBudget?: number;
59
+ requestImageMaxBytes?: number;
59
60
  retryPolicy?: unknown;
60
61
  models?: ModelEntryConfig[];
61
62
  /** 以下仅 adapter: deepseek 的 route 有效(透传官方 llm-deepseek 同名策略)。 */