@deepseek-ai/dsh-client-ui-settings-plugins 0.1.1-rc.2 → 0.1.2-alpha.2

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
@@ -8,15 +8,15 @@ window.__ModuleLoader__.load({
8
8
  let react_jsx_runtime = require("react/jsx-runtime");
9
9
  let react = require("react");
10
10
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
11
- let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
11
+ let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
12
12
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-settings-plugins/src/client/fields.module.css.mjs
13
- const css$2 = ".At1oFq_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.At1oFq_field+.At1oFq_field{border-top:1px solid var(--dsw-alias-border-l2)}.At1oFq_head{align-items:center;gap:8px;display:flex}.At1oFq_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.At1oFq_badges{align-items:center;gap:8px;display:inline-flex}.At1oFq_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.At1oFq_badgeMuted{white-space:nowrap;color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 8px;font-size:11px;line-height:17px}.At1oFq_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.At1oFq_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.At1oFq_reset:disabled{cursor:default}.At1oFq_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;line-height:1.5}.At1oFq_input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.At1oFq_input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.At1oFq_inputInvalid{border-color:var(--dsw-alias-label-error);}.At1oFq_invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.At1oFq_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}";
14
- const tagId$2 = "@deepseek-ai/dsh-client-ui-settings-plugins/fields.module.css";
15
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
13
+ const css$3 = ".At1oFq_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.At1oFq_field+.At1oFq_field{border-top:1px solid var(--dsw-alias-border-l2)}.At1oFq_head{align-items:center;gap:8px;display:flex}.At1oFq_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.At1oFq_badges{align-items:center;gap:8px;display:inline-flex}.At1oFq_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.At1oFq_badgeMuted{white-space:nowrap;color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 8px;font-size:11px;line-height:17px}.At1oFq_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.At1oFq_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.At1oFq_reset:disabled{cursor:default}.At1oFq_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;line-height:1.5}.At1oFq_input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.At1oFq_input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.At1oFq_inputInvalid{border-color:var(--dsw-alias-label-error);}.At1oFq_invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.At1oFq_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}";
14
+ const tagId$3 = "@deepseek-ai/dsh-client-ui-settings-plugins/fields.module.css";
15
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
16
16
  const tag = document.createElement("style");
17
17
  tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-settings-plugins";
18
- tag.dataset.pluginCss = tagId$2;
19
- tag.textContent = css$2;
18
+ tag.dataset.pluginCss = tagId$3;
19
+ tag.textContent = css$3;
20
20
  document.head.appendChild(tag);
21
21
  }
22
22
  var fields_module_css_default = {
@@ -152,13 +152,13 @@ window.__ModuleLoader__.load({
152
152
  }
153
153
  //#endregion
154
154
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-settings-plugins/src/client/PluginCard.module.css.mjs
155
- const css$1 = ".YyYd_a_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.YyYd_a_card:hover{border-color:var(--dsw-alias-label-dimmed)}.YyYd_a_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.YyYd_a_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.YyYd_a_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.YyYd_a_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.YyYd_a_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.YyYd_a_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.YyYd_a_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.YyYd_a_chevronOpen{transform:rotate(180deg)}.YyYd_a_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.YyYd_a_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.YyYd_a_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}.YyYd_a_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.YyYd_a_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}.YyYd_a_discard,.YyYd_a_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.YyYd_a_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.YyYd_a_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.YyYd_a_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.YyYd_a_discard:disabled,.YyYd_a_save:disabled{opacity:.4;cursor:default}.YyYd_a_discard:focus-visible,.YyYd_a_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}";
156
- const tagId$1 = "@deepseek-ai/dsh-client-ui-settings-plugins/PluginCard.module.css";
157
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
155
+ const css$2 = ".YyYd_a_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.YyYd_a_card:hover{border-color:var(--dsw-alias-label-dimmed)}.YyYd_a_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.YyYd_a_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.YyYd_a_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.YyYd_a_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.YyYd_a_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.YyYd_a_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.YyYd_a_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.YyYd_a_chevronOpen{transform:rotate(180deg)}.YyYd_a_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.YyYd_a_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.YyYd_a_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}.YyYd_a_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.YyYd_a_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}.YyYd_a_discard,.YyYd_a_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.YyYd_a_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.YyYd_a_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.YyYd_a_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.YyYd_a_discard:disabled,.YyYd_a_save:disabled{opacity:.4;cursor:default}.YyYd_a_discard:focus-visible,.YyYd_a_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}";
156
+ const tagId$2 = "@deepseek-ai/dsh-client-ui-settings-plugins/PluginCard.module.css";
157
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
158
158
  const tag = document.createElement("style");
159
159
  tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-settings-plugins";
160
- tag.dataset.pluginCss = tagId$1;
161
- tag.textContent = css$1;
160
+ tag.dataset.pluginCss = tagId$2;
161
+ tag.textContent = css$2;
162
162
  document.head.appendChild(tag);
163
163
  }
164
164
  var PluginCard_module_css_default = {
@@ -202,7 +202,21 @@ window.__ModuleLoader__.load({
202
202
  */
203
203
  function PluginCard(props) {
204
204
  const [open, setOpen] = (0, react.useState)(false);
205
+ const saveStarted = (0, react.useRef)(false);
205
206
  const { state } = props;
207
+ (0, react.useEffect)(() => {
208
+ if (state.saving) {
209
+ saveStarted.current = true;
210
+ return;
211
+ }
212
+ if (!saveStarted.current) return;
213
+ saveStarted.current = false;
214
+ if (!state.dirty && !state.failed) setOpen(false);
215
+ }, [
216
+ state.dirty,
217
+ state.failed,
218
+ state.saving
219
+ ]);
206
220
  if (!state.available) return null;
207
221
  const title = props.t(props.titleKey);
208
222
  const blocked = !state.dirty || state.invalid || state.saving;
@@ -361,13 +375,13 @@ window.__ModuleLoader__.load({
361
375
  }
362
376
  //#endregion
363
377
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-settings-plugins/src/client/PluginsSettingsSection.module.css.mjs
364
- const css = ".pbvGtq_section{max-width:760px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}.pbvGtq_heading{margin:0;font-size:18px;font-weight:600}.pbvGtq_intro{color:var(--dsw-alias-label-tertiary);margin:0;font-size:13px}.pbvGtq_tabs{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:flex-end;gap:22px;margin-top:2px;display:flex}.pbvGtq_tab{color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:0;padding:7px 1px 9px;font-size:13px;line-height:20px;position:relative}.pbvGtq_tab:hover,.pbvGtq_tab[data-active=true]{color:var(--dsw-alias-label-primary)}.pbvGtq_tab[data-active=true]:after,.pbvGtq_tab:focus-visible:after{background:var(--dsw-alias-label-primary);content:\"\";border-radius:2px 2px 0 0;height:2px;position:absolute;bottom:-1px;left:0;right:0}.pbvGtq_tab:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px;color:var(--dsw-alias-label-primary);border-radius:2px}.pbvGtq_panel{min-width:0;padding-top:2px}.pbvGtq_cards{flex-direction:column;gap:10px;margin:0;padding:0;list-style:none;display:flex}.pbvGtq_empty{color:var(--dsw-alias-label-tertiary);margin:0;font-size:13px}";
365
- const tagId = "@deepseek-ai/dsh-client-ui-settings-plugins/PluginsSettingsSection.module.css";
366
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
378
+ const css$1 = ".pbvGtq_section{max-width:760px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}.pbvGtq_heading{margin:0;font-size:18px;font-weight:600}.pbvGtq_intro{color:var(--dsw-alias-label-tertiary);margin:0;font-size:13px}.pbvGtq_tabs{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:flex-end;gap:22px;margin-top:2px;display:flex}.pbvGtq_tab{color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:0;padding:7px 1px 9px;font-size:13px;line-height:20px;position:relative}.pbvGtq_tab:hover,.pbvGtq_tab[data-active=true]{color:var(--dsw-alias-label-primary)}.pbvGtq_tab[data-active=true]:after,.pbvGtq_tab:focus-visible:after{background:var(--dsw-alias-label-primary);content:\"\";border-radius:2px 2px 0 0;height:2px;position:absolute;bottom:-1px;left:0;right:0}.pbvGtq_tab:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px;color:var(--dsw-alias-label-primary);border-radius:2px}.pbvGtq_panel{min-width:0;padding-top:2px}.pbvGtq_cards{flex-direction:column;gap:10px;margin:0;padding:0;list-style:none;display:flex}.pbvGtq_empty{color:var(--dsw-alias-label-tertiary);margin:0;font-size:13px}";
379
+ const tagId$1 = "@deepseek-ai/dsh-client-ui-settings-plugins/PluginsSettingsSection.module.css";
380
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
367
381
  const tag = document.createElement("style");
368
382
  tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-settings-plugins";
369
- tag.dataset.pluginCss = tagId;
370
- tag.textContent = css;
383
+ tag.dataset.pluginCss = tagId$1;
384
+ tag.textContent = css$1;
371
385
  document.head.appendChild(tag);
372
386
  }
373
387
  var PluginsSettingsSection_module_css_default = {
@@ -501,6 +515,176 @@ window.__ModuleLoader__.load({
501
515
  });
502
516
  }
503
517
  //#endregion
518
+ //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-settings-plugins/src/client/SubagentModelSelectionCard.module.css.mjs
519
+ const css = ".vCGm7G_permission{gap:6px;padding:12px 0;display:grid}.vCGm7G_toggleRow{color:var(--dsw-alias-label-primary);justify-content:space-between;align-items:flex-start;gap:16px;font-size:13px;line-height:1.5;display:flex}.vCGm7G_toggleLabel{flex:1;min-width:0}.vCGm7G_switch{box-sizing:border-box;background:var(--dsw-alias-border-l3);cursor:pointer;border:0;border-radius:10px;flex:none;width:36px;height:20px;padding:2px;position:relative}.vCGm7G_switchOn{background:var(--dsw-alias-brand-primary)}.vCGm7G_switch:disabled{cursor:default;opacity:.5}.vCGm7G_switch:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.vCGm7G_thumb{background:var(--dsw-alias-label-primary-foreground);border-radius:50%;width:16px;height:16px;transition:transform .12s;display:block}.vCGm7G_switchOn .vCGm7G_thumb{transform:translate(16px)}.vCGm7G_selection{gap:10px;display:grid}.vCGm7G_hint,.vCGm7G_notice,.vCGm7G_invalid,.vCGm7G_conflict{margin:0;font-size:12px;line-height:1.5}.vCGm7G_hint,.vCGm7G_notice{color:var(--dsw-alias-label-tertiary)}.vCGm7G_invalid,.vCGm7G_conflict{color:var(--dsw-alias-label-error)}.vCGm7G_catalogError{color:var(--dsw-alias-label-error);justify-content:space-between;align-items:center;gap:12px;font-size:12px;display:flex}.vCGm7G_catalogError button{color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border:0;padding:0}.vCGm7G_models{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;gap:6px;min-width:0;max-height:280px;margin:0;padding:10px;display:grid;overflow:auto}.vCGm7G_models legend{color:var(--dsw-alias-label-secondary);padding:0 4px;font-size:12px}.vCGm7G_modelGroup{gap:6px;display:grid}.vCGm7G_modelGroup+.vCGm7G_modelGroup{border-top:1px solid var(--dsw-alias-border-l3);margin-top:4px;padding-top:10px}.vCGm7G_providerName{color:var(--dsw-alias-label-tertiary);padding:0 6px;font-size:11px;font-weight:500}.vCGm7G_model{cursor:pointer;border-radius:6px;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px;min-width:0;padding:6px;display:grid}.vCGm7G_model:hover{background:var(--dsw-alias-bg-layer-4)}.vCGm7G_modelName,.vCGm7G_route{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.vCGm7G_modelName{color:var(--dsw-alias-label-primary);font-size:13px}.vCGm7G_route{color:var(--dsw-alias-label-tertiary);margin-top:2px;font-size:11px}.vCGm7G_unavailable{color:var(--dsw-alias-label-tertiary);font-size:11px}";
520
+ const tagId = "@deepseek-ai/dsh-client-ui-settings-plugins/SubagentModelSelectionCard.module.css";
521
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
522
+ const tag = document.createElement("style");
523
+ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-settings-plugins";
524
+ tag.dataset.pluginCss = tagId;
525
+ tag.textContent = css;
526
+ document.head.appendChild(tag);
527
+ }
528
+ var SubagentModelSelectionCard_module_css_default = {
529
+ "catalogError": "vCGm7G_catalogError",
530
+ "conflict": "vCGm7G_conflict",
531
+ "hint": "vCGm7G_hint",
532
+ "invalid": "vCGm7G_invalid",
533
+ "model": "vCGm7G_model",
534
+ "modelGroup": "vCGm7G_modelGroup",
535
+ "modelName": "vCGm7G_modelName",
536
+ "models": "vCGm7G_models",
537
+ "notice": "vCGm7G_notice",
538
+ "permission": "vCGm7G_permission",
539
+ "providerName": "vCGm7G_providerName",
540
+ "route": "vCGm7G_route",
541
+ "selection": "vCGm7G_selection",
542
+ "switch": "vCGm7G_switch",
543
+ "switchOn": "vCGm7G_switchOn",
544
+ "thumb": "vCGm7G_thumb",
545
+ "toggleLabel": "vCGm7G_toggleLabel",
546
+ "toggleRow": "vCGm7G_toggleRow",
547
+ "unavailable": "vCGm7G_unavailable"
548
+ };
549
+ //#endregion
550
+ //#region lib/types/client/SubagentModelSelectionCard.js
551
+ /** User control for model-selectable subagent delegation in new sessions. */
552
+ /**
553
+ * Render the default-off preference and its exact adapter-route choices.
554
+ * @param props - locale copy, the card snapshot, and its toggle action.
555
+ * @returns the preference card, or nothing when the namespace is unavailable.
556
+ */
557
+ function SubagentModelSelectionCard(props) {
558
+ const { t } = props;
559
+ const state = props.useSubagentModelSelectionCard((snapshot) => snapshot);
560
+ const availableGroups = /* @__PURE__ */ new Map();
561
+ const unavailable = [];
562
+ for (const candidate of state.candidates) {
563
+ if (!candidate.available) {
564
+ unavailable.push(candidate);
565
+ continue;
566
+ }
567
+ const group = availableGroups.get(candidate.provider);
568
+ if (group === void 0) availableGroups.set(candidate.provider, {
569
+ providerName: candidate.providerName,
570
+ candidates: [candidate]
571
+ });
572
+ else group.candidates.push(candidate);
573
+ }
574
+ const renderCandidate = (candidate) => (0, react_jsx_runtime.jsxs)("label", {
575
+ className: SubagentModelSelectionCard_module_css_default.model,
576
+ children: [
577
+ (0, react_jsx_runtime.jsx)("input", {
578
+ type: "checkbox",
579
+ checked: candidate.selected,
580
+ disabled: !state.writable || state.saving,
581
+ onChange: () => {
582
+ props.toggleModel(candidate.key);
583
+ }
584
+ }),
585
+ (0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsx)("span", {
586
+ className: SubagentModelSelectionCard_module_css_default.modelName,
587
+ children: candidate.modelName
588
+ }), (0, react_jsx_runtime.jsx)("span", {
589
+ className: SubagentModelSelectionCard_module_css_default.route,
590
+ children: `${candidate.providerName} · ${candidate.provider}/${candidate.model}`
591
+ })] }),
592
+ !candidate.available ? (0, react_jsx_runtime.jsx)("span", {
593
+ className: SubagentModelSelectionCard_module_css_default.unavailable,
594
+ children: t("subagentModelSelectionUnavailable")
595
+ }) : null
596
+ ]
597
+ }, candidate.key);
598
+ return (0, react_jsx_runtime.jsxs)(PluginCard, {
599
+ t,
600
+ titleKey: "subagentModelSelectionTitle",
601
+ descriptionKey: "subagentModelSelectionDescription",
602
+ state,
603
+ onSave: props.save,
604
+ onDiscard: props.discard,
605
+ children: [
606
+ (0, react_jsx_runtime.jsxs)("div", {
607
+ className: SubagentModelSelectionCard_module_css_default.permission,
608
+ children: [(0, react_jsx_runtime.jsxs)("div", {
609
+ className: SubagentModelSelectionCard_module_css_default.toggleRow,
610
+ children: [(0, react_jsx_runtime.jsx)("span", {
611
+ className: SubagentModelSelectionCard_module_css_default.toggleLabel,
612
+ children: t("subagentModelSelectionToggle")
613
+ }), (0, react_jsx_runtime.jsx)("button", {
614
+ type: "button",
615
+ role: "switch",
616
+ "aria-checked": state.enabled,
617
+ "aria-label": t("subagentModelSelectionToggle"),
618
+ className: clsx(SubagentModelSelectionCard_module_css_default.switch, state.enabled && SubagentModelSelectionCard_module_css_default.switchOn),
619
+ disabled: !state.writable || state.saving,
620
+ onClick: props.toggleEnabled,
621
+ children: (0, react_jsx_runtime.jsx)("span", { className: SubagentModelSelectionCard_module_css_default.thumb })
622
+ })]
623
+ }), (0, react_jsx_runtime.jsx)("p", {
624
+ className: SubagentModelSelectionCard_module_css_default.hint,
625
+ children: t(state.enabled ? "subagentModelSelectionChoose" : "subagentModelSelectionOff")
626
+ })]
627
+ }),
628
+ state.enabled ? (0, react_jsx_runtime.jsxs)("div", {
629
+ className: SubagentModelSelectionCard_module_css_default.selection,
630
+ children: [
631
+ state.catalogStatus === "loading" ? (0, react_jsx_runtime.jsx)("p", {
632
+ className: SubagentModelSelectionCard_module_css_default.notice,
633
+ role: "status",
634
+ children: t("subagentModelSelectionLoading")
635
+ }) : null,
636
+ state.catalogStatus === "error" ? (0, react_jsx_runtime.jsxs)("div", {
637
+ className: SubagentModelSelectionCard_module_css_default.catalogError,
638
+ role: "alert",
639
+ children: [(0, react_jsx_runtime.jsx)("span", { children: t("subagentModelSelectionLoadFailed") }), (0, react_jsx_runtime.jsx)("button", {
640
+ type: "button",
641
+ disabled: state.saving,
642
+ onClick: props.retryCatalog,
643
+ children: t("subagentModelSelectionRetry")
644
+ })]
645
+ }) : null,
646
+ state.catalogPartial ? (0, react_jsx_runtime.jsx)("p", {
647
+ className: SubagentModelSelectionCard_module_css_default.notice,
648
+ children: t("subagentModelSelectionPartial")
649
+ }) : null,
650
+ state.candidates.length > 0 ? (0, react_jsx_runtime.jsxs)("fieldset", {
651
+ className: SubagentModelSelectionCard_module_css_default.models,
652
+ children: [
653
+ (0, react_jsx_runtime.jsx)("legend", { children: t("subagentModelSelectionAllowed") }),
654
+ [...availableGroups].map(([provider, group]) => (0, react_jsx_runtime.jsxs)("div", {
655
+ className: SubagentModelSelectionCard_module_css_default.modelGroup,
656
+ children: [(0, react_jsx_runtime.jsx)("div", {
657
+ className: SubagentModelSelectionCard_module_css_default.providerName,
658
+ children: group.providerName
659
+ }), group.candidates.map(renderCandidate)]
660
+ }, provider)),
661
+ unavailable.length > 0 ? (0, react_jsx_runtime.jsxs)("div", {
662
+ className: SubagentModelSelectionCard_module_css_default.modelGroup,
663
+ children: [(0, react_jsx_runtime.jsx)("div", {
664
+ className: SubagentModelSelectionCard_module_css_default.providerName,
665
+ children: t("subagentModelSelectionUnavailableGroup")
666
+ }), unavailable.map(renderCandidate)]
667
+ }) : null
668
+ ]
669
+ }) : state.catalogStatus === "ready" ? (0, react_jsx_runtime.jsx)("p", {
670
+ className: SubagentModelSelectionCard_module_css_default.notice,
671
+ children: t("subagentModelSelectionEmpty")
672
+ }) : null,
673
+ state.invalid ? (0, react_jsx_runtime.jsx)("p", {
674
+ className: SubagentModelSelectionCard_module_css_default.invalid,
675
+ children: t("subagentModelSelectionRequired")
676
+ }) : null
677
+ ]
678
+ }) : null,
679
+ state.conflicted ? (0, react_jsx_runtime.jsx)("p", {
680
+ className: SubagentModelSelectionCard_module_css_default.conflict,
681
+ role: "status",
682
+ children: t("subagentModelSelectionConflict")
683
+ }) : null
684
+ ]
685
+ });
686
+ }
687
+ //#endregion
504
688
  //#region lib/types/client/WebSearchCard.js
505
689
  /**
506
690
  * Render the web-search card.
@@ -657,7 +841,7 @@ window.__ModuleLoader__.load({
657
841
  * @returns the store the card's component reads through its bound selector.
658
842
  */
659
843
  bind(project) {
660
- const store = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)(project());
844
+ const store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)(project());
661
845
  this.listeners.add(() => {
662
846
  store.set(project());
663
847
  });
@@ -924,7 +1108,7 @@ window.__ModuleLoader__.load({
924
1108
  var ConfigurablePluginsTabController = class {
925
1109
  describeFace;
926
1110
  entries;
927
- store = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)({
1111
+ store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({
928
1112
  loaded: false,
929
1113
  namespaces: []
930
1114
  });
@@ -976,6 +1160,281 @@ window.__ModuleLoader__.load({
976
1160
  }
977
1161
  };
978
1162
  //#endregion
1163
+ //#region lib/types/client/subagent-model-selection-card-controller.js
1164
+ /** Staged editor for the Host-owned subagent model allowlist. */
1165
+ /** Namespace of the Host-owned subagent model-selection preference. */
1166
+ const SUBAGENT_MODEL_SELECTION_NS = "subagent-model-selection";
1167
+ /**
1168
+ * Stable identity for one exact route; callers resolve it by lookup and never parse it.
1169
+ * @param route - Provider/model route to identify.
1170
+ * @returns Opaque key for lookup within the card.
1171
+ */
1172
+ function subagentModelKey(route) {
1173
+ return `${route.provider}\0${route.model}`;
1174
+ }
1175
+ /**
1176
+ * Join live adapter metadata with stored routes that remain removable after disappearance.
1177
+ * @param groups - Current model directory grouped by provider.
1178
+ * @param stored - Routes in the effective settings value.
1179
+ * @param selected - Opaque route keys selected in the current draft.
1180
+ * @returns Candidate rows for the card.
1181
+ */
1182
+ function subagentModelCandidates(groups, stored, selected) {
1183
+ const storedByKey = new Map(stored.map((route) => [subagentModelKey(route), route]));
1184
+ const candidates = groups.flatMap((group) => group.models.map((model) => {
1185
+ const route = {
1186
+ provider: group.id,
1187
+ model: model.id
1188
+ };
1189
+ const key = subagentModelKey(route);
1190
+ storedByKey.delete(key);
1191
+ return {
1192
+ ...route,
1193
+ key,
1194
+ providerName: group.name,
1195
+ modelName: model.name,
1196
+ available: true,
1197
+ selected: selected.has(key)
1198
+ };
1199
+ }));
1200
+ for (const route of storedByKey.values()) {
1201
+ const key = subagentModelKey(route);
1202
+ candidates.push({
1203
+ ...route,
1204
+ key,
1205
+ providerName: route.provider,
1206
+ modelName: route.model,
1207
+ available: false,
1208
+ selected: selected.has(key)
1209
+ });
1210
+ }
1211
+ return candidates;
1212
+ }
1213
+ function sameRoutes(left, right) {
1214
+ if (left.length !== right.length) return false;
1215
+ const rightKeys = new Set(right.map(subagentModelKey));
1216
+ return left.every((route) => rightKeys.has(subagentModelKey(route)));
1217
+ }
1218
+ /** Bridges one settings scope and the live adapter directory onto a staged card. */
1219
+ var SubagentModelSelectionCardController = class {
1220
+ scope;
1221
+ ctx;
1222
+ catalogGroups = [];
1223
+ catalogPartial = false;
1224
+ catalogStatus = "idle";
1225
+ draftEnabled;
1226
+ draftRoutes;
1227
+ draftRevision;
1228
+ saving = false;
1229
+ failed = false;
1230
+ conflicted = false;
1231
+ disposed = false;
1232
+ saveGeneration = 0;
1233
+ catalogGeneration = 0;
1234
+ store;
1235
+ unsubscribe;
1236
+ /**
1237
+ * @param scope - bound `subagent-model-selection` settings scope.
1238
+ * @param ctx - the card plugin's context, whose `remote.session` namespace
1239
+ * answers the Host model catalog.
1240
+ */
1241
+ constructor(scope, ctx) {
1242
+ this.scope = scope;
1243
+ this.ctx = ctx;
1244
+ this.store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)(this.projection());
1245
+ this.unsubscribe = scope.subscribe(() => {
1246
+ if (!this.saving && this.draftRoutes !== void 0 && this.scope.getSnapshot().revision !== this.draftRevision) if (this.currentEnabled() === this.enabled() && sameRoutes(this.currentRoutes(), this.desiredRoutes())) this.clearDraft();
1247
+ else this.conflicted = true;
1248
+ if (this.enabled() && this.catalogStatus === "idle") this.loadCatalog();
1249
+ this.publish();
1250
+ });
1251
+ if (this.enabled() && this.catalogStatus === "idle") this.loadCatalog();
1252
+ }
1253
+ /** Stop observing settings and suppress late directory/write settlements. */
1254
+ dispose() {
1255
+ this.disposed = true;
1256
+ this.saveGeneration += 1;
1257
+ this.catalogGeneration += 1;
1258
+ this.unsubscribe();
1259
+ }
1260
+ /**
1261
+ * Build the renderer face for this card.
1262
+ * @returns The snapshot and staged card actions injected into the renderer.
1263
+ */
1264
+ inject() {
1265
+ return {
1266
+ hooks: { subagentModelSelectionCard: this.store },
1267
+ toggleEnabled: () => {
1268
+ this.toggleEnabled();
1269
+ },
1270
+ toggleModel: (key) => {
1271
+ this.toggleModel(key);
1272
+ },
1273
+ retryCatalog: () => {
1274
+ this.loadCatalog();
1275
+ },
1276
+ save: () => {
1277
+ this.save();
1278
+ },
1279
+ discard: () => {
1280
+ this.discard();
1281
+ }
1282
+ };
1283
+ }
1284
+ currentRoutes() {
1285
+ return this.scope.getSnapshot().value?.allowedModels.map((route) => ({ ...route })) ?? [];
1286
+ }
1287
+ currentEnabled() {
1288
+ return this.scope.getSnapshot().value?.enabled ?? false;
1289
+ }
1290
+ selected() {
1291
+ return new Set(this.draftRoutes?.keys() ?? this.currentRoutes().map(subagentModelKey));
1292
+ }
1293
+ enabled() {
1294
+ return this.draftEnabled ?? this.currentEnabled();
1295
+ }
1296
+ beginDraft() {
1297
+ if (this.draftRoutes === void 0) {
1298
+ const snapshot = this.scope.getSnapshot();
1299
+ this.draftEnabled = snapshot.value?.enabled ?? false;
1300
+ this.draftRoutes = new Map(snapshot.value?.allowedModels.map((route) => [subagentModelKey(route), { ...route }]) ?? []);
1301
+ this.draftRevision = snapshot.revision;
1302
+ }
1303
+ return this.draftRoutes;
1304
+ }
1305
+ toggleEnabled() {
1306
+ const snapshot = this.scope.getSnapshot();
1307
+ if (this.disposed || snapshot.status !== "ready" || !snapshot.writable || this.saving) return;
1308
+ this.beginDraft();
1309
+ this.draftEnabled = !this.draftEnabled;
1310
+ this.failed = false;
1311
+ if (this.draftEnabled && this.catalogStatus === "idle") this.loadCatalog();
1312
+ this.publish();
1313
+ }
1314
+ toggleModel(key) {
1315
+ if (!this.enabled() || this.saving || !this.scope.getSnapshot().writable) return;
1316
+ const candidate = this.candidates().find((candidate) => candidate.key === key);
1317
+ if (candidate === void 0) return;
1318
+ const routes = this.beginDraft();
1319
+ if (routes.has(key)) routes.delete(key);
1320
+ else routes.set(key, {
1321
+ provider: candidate.provider,
1322
+ model: candidate.model
1323
+ });
1324
+ this.failed = false;
1325
+ this.publish();
1326
+ }
1327
+ clearDraft() {
1328
+ this.draftEnabled = void 0;
1329
+ this.draftRoutes = void 0;
1330
+ this.draftRevision = void 0;
1331
+ this.failed = false;
1332
+ this.conflicted = false;
1333
+ }
1334
+ discard() {
1335
+ if (this.saving) return;
1336
+ this.clearDraft();
1337
+ this.publish();
1338
+ }
1339
+ candidates() {
1340
+ const retained = new Map(this.currentRoutes().map((route) => [subagentModelKey(route), route]));
1341
+ for (const [key, route] of this.draftRoutes ?? []) retained.set(key, route);
1342
+ return subagentModelCandidates(this.catalogGroups, [...retained.values()], this.selected());
1343
+ }
1344
+ desiredRoutes() {
1345
+ return [...this.draftRoutes?.values() ?? this.currentRoutes()].map((route) => ({ ...route }));
1346
+ }
1347
+ async save() {
1348
+ const snapshot = this.scope.getSnapshot();
1349
+ const desiredEnabled = this.enabled();
1350
+ const desired = this.desiredRoutes();
1351
+ if (this.disposed || snapshot.status !== "ready" || !snapshot.writable || this.saving || this.currentEnabled() === desiredEnabled && sameRoutes(this.currentRoutes(), desired) || desiredEnabled && desired.length === 0) return;
1352
+ if (this.draftRoutes !== void 0 && snapshot.revision !== this.draftRevision) {
1353
+ this.conflicted = true;
1354
+ this.publish();
1355
+ return;
1356
+ }
1357
+ const generation = this.saveGeneration;
1358
+ this.saving = true;
1359
+ this.failed = false;
1360
+ this.conflicted = false;
1361
+ this.publish();
1362
+ await this.scope.mutate([{
1363
+ op: "set",
1364
+ path: ["enabled"],
1365
+ value: desiredEnabled
1366
+ }, {
1367
+ op: "set",
1368
+ path: ["allowedModels"],
1369
+ value: desired.map((route) => ({
1370
+ provider: route.provider,
1371
+ model: route.model
1372
+ }))
1373
+ }], this.draftRevision);
1374
+ if (generation !== this.saveGeneration) return;
1375
+ const landed = this.currentEnabled() === desiredEnabled && sameRoutes(this.currentRoutes(), desired);
1376
+ this.saving = false;
1377
+ this.failed = !landed;
1378
+ if (landed) this.clearDraft();
1379
+ this.publish();
1380
+ }
1381
+ /** Invalidate and reload model candidates after a Host model input changes. */
1382
+ refreshCatalog() {
1383
+ if (this.disposed) return;
1384
+ this.catalogGeneration += 1;
1385
+ this.catalogStatus = "idle";
1386
+ this.catalogPartial = false;
1387
+ if (this.enabled()) this.loadCatalog();
1388
+ else this.publish();
1389
+ }
1390
+ /** Drop Host-specific candidates and drafts, then reload after reconnecting. */
1391
+ resetConnection() {
1392
+ if (this.disposed) return;
1393
+ this.saveGeneration += 1;
1394
+ this.saving = false;
1395
+ this.clearDraft();
1396
+ this.catalogGroups = [];
1397
+ this.refreshCatalog();
1398
+ }
1399
+ async loadCatalog() {
1400
+ if (this.disposed || this.catalogStatus === "loading") return;
1401
+ const generation = this.catalogGeneration;
1402
+ this.catalogStatus = "loading";
1403
+ this.catalogPartial = false;
1404
+ this.publish();
1405
+ const response = await this.ctx.remote.session.modelCatalog();
1406
+ if (generation !== this.catalogGeneration) return;
1407
+ if (response.ok) {
1408
+ this.catalogGroups = response.value.groups;
1409
+ this.catalogPartial = response.value.failures.length > 0;
1410
+ this.catalogStatus = "ready";
1411
+ } else this.catalogStatus = "error";
1412
+ this.publish();
1413
+ }
1414
+ projection() {
1415
+ const snapshot = this.scope.getSnapshot();
1416
+ const current = this.currentRoutes();
1417
+ const desired = this.desiredRoutes();
1418
+ const enabled = this.enabled();
1419
+ return {
1420
+ available: snapshot.status === "ready",
1421
+ writable: snapshot.writable,
1422
+ dirty: this.currentEnabled() !== enabled || !sameRoutes(current, desired),
1423
+ invalid: enabled && desired.length === 0,
1424
+ saving: this.saving,
1425
+ failed: this.failed,
1426
+ enabled,
1427
+ candidates: this.candidates(),
1428
+ catalogStatus: this.catalogStatus,
1429
+ catalogPartial: this.catalogPartial,
1430
+ conflicted: this.conflicted
1431
+ };
1432
+ }
1433
+ publish() {
1434
+ this.store.set(this.projection());
1435
+ }
1436
+ };
1437
+ //#endregion
979
1438
  //#region lib/types/client/web-search-card-controller.js
980
1439
  /**
981
1440
  * The web-search card's staged form over the `web-search-deepseek` settings
@@ -999,7 +1458,7 @@ window.__ModuleLoader__.load({
999
1458
  /** Bridges the `web-search-deepseek` scope and the credentials domain onto the card. */
1000
1459
  var WebSearchCardController = class {
1001
1460
  scope;
1002
- api;
1461
+ ctx;
1003
1462
  form;
1004
1463
  store;
1005
1464
  credential = {
@@ -1009,11 +1468,12 @@ window.__ModuleLoader__.load({
1009
1468
  };
1010
1469
  /**
1011
1470
  * @param scope - the bound settings scope for the `web-search-deepseek` namespace.
1012
- * @param api - wire face used for the credential the section references.
1471
+ * @param ctx - the card plugin's context, whose `remote.credentials` namespace
1472
+ * answers for the credential the section references.
1013
1473
  */
1014
- constructor(scope, api) {
1474
+ constructor(scope, ctx) {
1015
1475
  this.scope = scope;
1016
- this.api = api;
1476
+ this.ctx = ctx;
1017
1477
  this.form = new CardForm(scope, [textField("baseURL"), numberField("maxUses")], [{
1018
1478
  field: API_KEY_FIELD,
1019
1479
  write: (text) => this.writeKey(text)
@@ -1052,14 +1512,9 @@ window.__ModuleLoader__.load({
1052
1512
  };
1053
1513
  this.store.set(this.projection());
1054
1514
  }
1055
- let response;
1056
- try {
1057
- response = await this.api.credentials.describe({ refs: [ref] });
1058
- } catch (_credentialReadFailure) {
1059
- return;
1060
- }
1061
- if (!response.result.ok || ref !== refOf(this.scope.getSnapshot())) return;
1062
- const view = response.result.value.credentials[ref];
1515
+ const response = await this.ctx.remote.credentials.describe([ref]);
1516
+ if (!response.ok || ref !== refOf(this.scope.getSnapshot())) return;
1517
+ const view = response.value[ref];
1063
1518
  const next = {
1064
1519
  ref,
1065
1520
  configured: view?.configured ?? false,
@@ -1097,12 +1552,7 @@ window.__ModuleLoader__.load({
1097
1552
  * @returns whether the Host reports a configured credential afterwards.
1098
1553
  */
1099
1554
  async writeKey(value) {
1100
- try {
1101
- await this.api.credentials.set({
1102
- ref: refOf(this.scope.getSnapshot()),
1103
- value
1104
- });
1105
- } catch (_credentialWriteFailure) {}
1555
+ await this.ctx.remote.credentials.set(refOf(this.scope.getSnapshot()), value);
1106
1556
  await this.readCredential();
1107
1557
  return this.credential.configured;
1108
1558
  }
@@ -1157,7 +1607,22 @@ window.__ModuleLoader__.load({
1157
1607
  webSearchBaseUrl: "Endpoint",
1158
1608
  webSearchBaseUrlHint: "Leave blank to use the provider default.",
1159
1609
  webSearchMaxUses: "Max searches per request",
1160
- webSearchMaxUsesHint: "How many times one request may search before it must answer."
1610
+ webSearchMaxUsesHint: "How many times one request may search before it must answer.",
1611
+ subagentModelSelectionTitle: "Subagent",
1612
+ subagentModelSelectionDescription: "Control which models agents may choose for subagents.",
1613
+ subagentModelSelectionToggle: "Allow agents to choose models for subagents",
1614
+ subagentModelSelectionChoose: "When enabled, agents can choose a provider, model, and reasoning effort for each subagent from the authorized models below. Applies only to new sessions.",
1615
+ subagentModelSelectionAllowed: "Models agents may choose",
1616
+ subagentModelSelectionLoading: "Loading models…",
1617
+ subagentModelSelectionLoadFailed: "Models could not be loaded.",
1618
+ subagentModelSelectionRetry: "Retry",
1619
+ subagentModelSelectionPartial: "Some model providers could not be loaded; saved choices remain removable.",
1620
+ subagentModelSelectionUnavailable: "Currently unavailable",
1621
+ subagentModelSelectionUnavailableGroup: "Saved but currently unavailable",
1622
+ subagentModelSelectionEmpty: "No model provider currently advertises a model.",
1623
+ subagentModelSelectionRequired: "Select at least one model before saving.",
1624
+ subagentModelSelectionConflict: "Settings changed elsewhere. Discard your draft and try again.",
1625
+ subagentModelSelectionOff: "Subagents use configured defaults or inherit the parent agent's model. Saved model choices are retained."
1161
1626
  };
1162
1627
  /** Simplified Chinese copy. */
1163
1628
  const zh = {
@@ -1197,7 +1662,22 @@ window.__ModuleLoader__.load({
1197
1662
  webSearchBaseUrl: "接口地址",
1198
1663
  webSearchBaseUrlHint: "留空则使用提供方默认地址。",
1199
1664
  webSearchMaxUses: "单次请求最多搜索次数",
1200
- webSearchMaxUsesHint: "一次请求在必须作答前最多可以搜索多少次。"
1665
+ webSearchMaxUsesHint: "一次请求在必须作答前最多可以搜索多少次。",
1666
+ subagentModelSelectionTitle: "Subagent",
1667
+ subagentModelSelectionDescription: "控制 Agent 为 Subagent 选择模型的权限。",
1668
+ subagentModelSelectionToggle: "允许 Agent 为 Subagent 选择模型",
1669
+ subagentModelSelectionChoose: "开启后,Agent 可以从下方授权模型中,为每个 Subagent 选择提供方、模型和推理强度。仅影响新会话。",
1670
+ subagentModelSelectionAllowed: "Agent 可选择的模型",
1671
+ subagentModelSelectionLoading: "正在加载模型…",
1672
+ subagentModelSelectionLoadFailed: "无法加载模型。",
1673
+ subagentModelSelectionRetry: "重试",
1674
+ subagentModelSelectionPartial: "部分模型提供方暂时无法加载;已保存的选择仍可移除。",
1675
+ subagentModelSelectionUnavailable: "当前不可用",
1676
+ subagentModelSelectionUnavailableGroup: "已保存但当前不可用",
1677
+ subagentModelSelectionEmpty: "当前没有模型提供方公布模型。",
1678
+ subagentModelSelectionRequired: "保存前请至少选择一个模型。",
1679
+ subagentModelSelectionConflict: "设置已在其他位置更新。请放弃修改后重试。",
1680
+ subagentModelSelectionOff: "关闭后,Subagent 使用配置的默认模型或继承父 Agent 的模型;已选模型会保留。"
1201
1681
  };
1202
1682
  //#endregion
1203
1683
  //#region lib/types/client/index.js
@@ -1207,7 +1687,7 @@ window.__ModuleLoader__.load({
1207
1687
  *
1208
1688
  * The section declares `settings.plugins.tab`; its own `configurable` tab then
1209
1689
  * declares `settings.plugin.item` and renders whatever cards were registered
1210
- * into it. The three cards this package ships are the host-plane sections the
1690
+ * into it. The cards this package ships are the host-plane sections the
1211
1691
  * deployment already exposes; each binds its namespace through the client
1212
1692
  * settings scope, which keeps them unaware of one another and of other tabs.
1213
1693
  */
@@ -1217,8 +1697,9 @@ window.__ModuleLoader__.load({
1217
1697
  const inject = [
1218
1698
  "slots",
1219
1699
  "locale",
1220
- "connection",
1221
1700
  "remote",
1701
+ "remote.credentials",
1702
+ "remote.session",
1222
1703
  "settingsScope"
1223
1704
  ];
1224
1705
  /**
@@ -1226,7 +1707,6 @@ window.__ModuleLoader__.load({
1226
1707
  * @param ctx - the browser plugin context.
1227
1708
  */
1228
1709
  function apply(ctx) {
1229
- const { api } = ctx.get("connection");
1230
1710
  const t = ctx.locale.bind(NS);
1231
1711
  ctx.effect(() => ctx.locale.register(NS, {
1232
1712
  zh,
@@ -1234,10 +1714,23 @@ window.__ModuleLoader__.load({
1234
1714
  }), "ui-settings-plugins: section dictionaries");
1235
1715
  const bash = new BashCardController(ctx.settingsScope.bind({ namespace: SHELL_NS }));
1236
1716
  const agentLoop = new AgentLoopCardController(ctx.settingsScope.bind({ namespace: AGENT_LOOP_NS }));
1237
- const webSearch = new WebSearchCardController(ctx.settingsScope.bind({ namespace: WEB_SEARCH_NS }), api);
1717
+ const webSearch = new WebSearchCardController(ctx.settingsScope.bind({ namespace: WEB_SEARCH_NS }), ctx);
1718
+ const subagentModelSelection = new SubagentModelSelectionCardController(ctx.settingsScope.bind({ namespace: SUBAGENT_MODEL_SELECTION_NS }), ctx);
1238
1719
  ctx.effect(() => ctx.remote.$on("credentials/reference-updated", (ref) => {
1239
1720
  webSearch.refreshCredential(ref);
1240
1721
  }), "ui-settings-plugins: credential invalidations");
1722
+ ctx.effect(() => ctx.remote.$on("llm/adapters-updated", () => {
1723
+ subagentModelSelection.refreshCatalog();
1724
+ }), "ui-settings-plugins: subagent adapter invalidations");
1725
+ ctx.effect(() => ctx.remote.$on("settings/document-updated", () => {
1726
+ subagentModelSelection.refreshCatalog();
1727
+ }), "ui-settings-plugins: subagent settings invalidations");
1728
+ ctx.effect(() => ctx.on("connection/reset", () => {
1729
+ subagentModelSelection.resetConnection();
1730
+ }), "ui-settings-plugins: subagent connection generation");
1731
+ ctx.effect(() => () => {
1732
+ subagentModelSelection.dispose();
1733
+ }, "ui-settings-plugins: subagent preference");
1241
1734
  const configurable = new ConfigurablePluginsTabController(ctx.settingsScope.describe(), () => ctx.slots.entries("settings.plugin.item"));
1242
1735
  ctx.effect(() => () => {
1243
1736
  configurable.dispose();
@@ -1310,6 +1803,12 @@ window.__ModuleLoader__.load({
1310
1803
  locale: NS,
1311
1804
  inject: () => agentLoop.inject()
1312
1805
  }, AgentLoopCard);
1806
+ yield ctx.slots.register({
1807
+ name: "settings.plugin.item",
1808
+ key: SUBAGENT_MODEL_SELECTION_NS,
1809
+ locale: NS,
1810
+ inject: () => subagentModelSelection.inject()
1811
+ }, SubagentModelSelectionCard);
1313
1812
  yield ctx.slots.register({
1314
1813
  name: "settings.plugin.item",
1315
1814
  key: WEB_SEARCH_NS,