dsh-advisor 0.5.1 → 0.5.3

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
@@ -30,11 +30,25 @@ __export(index_exports, {
30
30
  });
31
31
  module.exports = __toCommonJS(index_exports);
32
32
 
33
- // src/client/advisor-card.tsx
34
- var import_react = require("react");
35
- var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
33
+ // src/prompts.ts
34
+ var DEFAULT_ADVISOR_SYSTEM_PROMPT = `You are an independent reviewer attached to a coding-agent session. You observe the primary agent's work and surface concise, severity-ranked advice. You are advisory only: you never approve or reject the agent's actions, and you never issue commands as if you were the primary agent.
35
+
36
+ After each completed primary turn you receive an incremental transcript update prefixed with "### Session update" (a user message). Review only what changed in this update.
37
+
38
+ Severity levels:
39
+ - nit: a minor style, clarity, or quality suggestion; no course change is needed.
40
+ - concern: a material risk or a clearly better direction that the primary should weigh before continuing.
41
+ - blocker: continuing clearly wastes work \u2014 the primary contradicts an explicit user instruction, is going in circles, or the approach is fundamentally unsound.
36
42
 
37
- var css = `.kPHV8a_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;transition:border-color .16s,background .16s}.kPHV8a_card:hover{border-color:var(--dsw-alias-label-dimmed)}.kPHV8a_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.kPHV8a_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}.kPHV8a_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.kPHV8a_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.kPHV8a_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.kPHV8a_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.kPHV8a_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.kPHV8a_chevronOpen{transform:rotate(180deg)}.kPHV8a_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.kPHV8a_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.kPHV8a_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}.kPHV8a_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}.kPHV8a_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}.kPHV8a_discard,.kPHV8a_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.kPHV8a_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.kPHV8a_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.kPHV8a_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.kPHV8a_discard:disabled,.kPHV8a_save:disabled{opacity:.4;cursor:default}.kPHV8a_discard:focus-visible,.kPHV8a_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.kPHV8a_notice{color:var(--dsw-alias-state-warn-label);margin:12px 0 0;font-size:12px;line-height:18px}.kPHV8a_savedNotice{color:var(--dsw-alias-state-success-primary);margin:12px 0 0;font-size:12px;line-height:18px}.kPHV8a_error{color:var(--dsw-alias-state-error-primary);margin:12px 0 0;font-size:12px;line-height:18px}.kPHV8a_form{flex-direction:column;gap:12px;padding:12px 0 0;display:flex}.kPHV8a_checkboxRow{align-items:center;gap:8px;display:flex}.kPHV8a_checkLabel{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.kPHV8a_checkbox{width:16px;height:16px;accent-color:var(--dsw-alias-brand-primary);cursor:pointer;margin:0}.kPHV8a_checkbox:disabled{opacity:.4;cursor:default}.kPHV8a_checkbox:focus-visible{outline:2px solid var(--dsw-alias-border-l3);outline-offset:2px}.kPHV8a_fieldset{border:none;flex-direction:column;gap:12px;margin:0;padding:0;display:flex}.kPHV8a_field{flex-direction:column;gap:6px;display:flex}.kPHV8a_fieldLabel{color:var(--dsw-alias-label-secondary);align-items:center;gap:10px;font-size:12px;font-weight:500;line-height:18px;display:inline-flex}.kPHV8a_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 10px;font-size:14px;line-height:22px}select.kPHV8a_input{cursor:pointer;max-width:240px}.kPHV8a_input:focus{border-color:var(--dsw-alias-brand-primary);outline:none}.kPHV8a_input::placeholder{color:var(--dsw-alias-label-dimmed)}.kPHV8a_input:disabled{opacity:.6;cursor:default}.kPHV8a_selectInput{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-position:right 12px center;background-repeat:no-repeat;background-size:12px 12px;padding-right:32px}.kPHV8a_textarea{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:100%;min-height:96px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);resize:vertical;border-radius:8px;padding:8px 10px;font-size:14px;line-height:22px}.kPHV8a_textarea:focus{border-color:var(--dsw-alias-brand-primary);outline:none}.kPHV8a_textarea:disabled{opacity:.6;cursor:default}.kPHV8a_numberFields{grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;display:grid}.kPHV8a_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.kPHV8a_warnHint{color:var(--dsw-alias-state-warn-label);margin:0;font-size:12px;line-height:18px}`;
43
+ Reply with EXACTLY ONE JSON object and nothing else:
44
+ {"note": "<your note>", "severity": "nit"|"concern"|"blocker"}
45
+
46
+ - "severity" is optional; when omitted it means "nit".
47
+ - "note" must be a non-empty string: one concise, specific, actionable observation about this update. One note per update.
48
+ - If there is genuinely nothing worth advising, respond with {"note": "Nothing to add"}.
49
+ - Do not include prose, markdown fences, or anything outside the JSON object.`;
50
+
51
+ var css = `.kPHV8a_readOnly{color:var(--dsw-alias-label-tertiary);margin:0 0 12px;font-size:12px;line-height:1.5}.kPHV8a_notice{color:var(--dsw-alias-state-warn-label);margin:0 0 12px;font-size:12px;line-height:1.5}.kPHV8a_savedNotice{color:var(--dsw-alias-state-success-primary);margin:0 0 12px;font-size:12px;line-height:1.5}.kPHV8a_error{color:var(--dsw-alias-state-error-primary);margin:0 0 12px;font-size:12px;line-height:1.5}.kPHV8a_form{flex-direction:column;display:flex}.kPHV8a_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.kPHV8a_form>.kPHV8a_field+.kPHV8a_field{border-top:.5px solid var(--dsw-alias-border-l2)}.kPHV8a_fieldLabel{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:1.5}.kPHV8a_input{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);width:100%;height:34px;font:inherit;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);padding:0 12px;font-size:13px;line-height:1.5}select.kPHV8a_input{cursor:pointer;max-width:240px}.kPHV8a_input:focus-visible{border-color:var(--dsw-alias-state-business-primary);outline:none}.kPHV8a_input::placeholder{color:var(--dsw-alias-label-dimmed)}.kPHV8a_input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.kPHV8a_selectInput{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-position:right 12px center;background-repeat:no-repeat;background-size:12px 12px;padding-right:32px}.kPHV8a_textarea{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);width:100%;min-height:96px;font:inherit;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);resize:vertical;padding:8px 12px;font-size:13px;line-height:1.5}.kPHV8a_textarea:focus-visible{border-color:var(--dsw-alias-state-business-primary);outline:none}.kPHV8a_textarea::placeholder{color:var(--dsw-alias-label-dimmed)}.kPHV8a_textarea:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.kPHV8a_numberFields{border-top:.5px solid var(--dsw-alias-border-l2);grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;padding:12px 0;display:grid}.kPHV8a_numberFields .kPHV8a_field{padding:0}.kPHV8a_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}.kPHV8a_warnHint{color:var(--dsw-alias-state-warn-label);margin:0;font-size:12px;line-height:1.5}.kPHV8a_footer{align-items:center;gap:8px;padding-top:16px;display:flex}.kPHV8a_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}.kPHV8a_discard,.kPHV8a_save{appearance:none;border-radius:var(--dsw-radius-md);font:inherit;cursor:pointer;border:1px solid #0000;padding:5px 14px;font-size:13px;line-height:1.5}.kPHV8a_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.kPHV8a_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.kPHV8a_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.kPHV8a_discard:disabled,.kPHV8a_save:disabled{opacity:.4;cursor:default}.kPHV8a_discard:focus-visible,.kPHV8a_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}`;
38
52
  var tagId = "dsh-advisor/advisor-card.module.css";
39
53
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
40
54
  const tag = document.createElement("style");
@@ -43,7 +57,7 @@ if (typeof document !== "undefined" && document.querySelector("style[data-plugin
43
57
  tag.textContent = css;
44
58
  document.head.appendChild(tag);
45
59
  }
46
- var advisor_card_module_css_default = { "body": "kPHV8a_body", "card": "kPHV8a_card", "cardOpen": "kPHV8a_cardOpen", "checkLabel": "kPHV8a_checkLabel", "checkbox": "kPHV8a_checkbox", "checkboxRow": "kPHV8a_checkboxRow", "chevron": "kPHV8a_chevron", "chevronOpen": "kPHV8a_chevronOpen", "description": "kPHV8a_description", "discard": "kPHV8a_discard", "error": "kPHV8a_error", "failed": "kPHV8a_failed", "field": "kPHV8a_field", "fieldLabel": "kPHV8a_fieldLabel", "fieldset": "kPHV8a_fieldset", "footer": "kPHV8a_footer", "form": "kPHV8a_form", "headText": "kPHV8a_headText", "header": "kPHV8a_header", "hint": "kPHV8a_hint", "input": "kPHV8a_input", "name": "kPHV8a_name", "notice": "kPHV8a_notice", "numberFields": "kPHV8a_numberFields", "pending": "kPHV8a_pending", "readOnly": "kPHV8a_readOnly", "save": "kPHV8a_save", "savedNotice": "kPHV8a_savedNotice", "selectInput": "kPHV8a_selectInput", "textarea": "kPHV8a_textarea", "warnHint": "kPHV8a_warnHint" };
60
+ var advisor_card_module_css_default = { "discard": "kPHV8a_discard", "error": "kPHV8a_error", "failed": "kPHV8a_failed", "field": "kPHV8a_field", "fieldLabel": "kPHV8a_fieldLabel", "footer": "kPHV8a_footer", "form": "kPHV8a_form", "hint": "kPHV8a_hint", "input": "kPHV8a_input", "notice": "kPHV8a_notice", "numberFields": "kPHV8a_numberFields", "readOnly": "kPHV8a_readOnly", "save": "kPHV8a_save", "savedNotice": "kPHV8a_savedNotice", "selectInput": "kPHV8a_selectInput", "textarea": "kPHV8a_textarea", "warnHint": "kPHV8a_warnHint" };
47
61
 
48
62
  // src/client/advisor-card.tsx
49
63
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -58,232 +72,184 @@ function failureCopy(failure, t) {
58
72
  function AdvisorCard(props) {
59
73
  const { controller, useSnapshot, t } = props;
60
74
  const state = useSnapshot((snapshot) => snapshot);
61
- const [userOpen, setUserOpen] = (0, import_react.useState)(false);
62
- const degraded = state.status === "ready" ? !state.advisorPresent : state.degraded;
63
- const open = userOpen || state.status === "error" || degraded;
64
75
  if (state.status === "idle") void controller.load();
65
- const title = t("title");
66
- const header = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
67
- "button",
68
- {
69
- type: "button",
70
- className: advisor_card_module_css_default["header"],
71
- "aria-expanded": open,
72
- "aria-label": `${t(open ? "collapse" : "expand")}: ${title}`,
73
- onClick: () => {
74
- if (!degraded && state.status !== "error") setUserOpen(!userOpen);
75
- },
76
- children: [
77
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: advisor_card_module_css_default["headText"], children: [
78
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: advisor_card_module_css_default["name"], children: title }),
79
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: advisor_card_module_css_default["description"], children: t("intro") })
80
- ] }),
81
- state.dirty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: advisor_card_module_css_default["pending"], children: t("unsaved") }) : null,
82
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
83
- import_dsh_client_ui_primitives.IconChevronDownOutlineRegular,
84
- {
85
- className: open ? `${advisor_card_module_css_default["chevron"]} ${advisor_card_module_css_default["chevronOpen"]}` : advisor_card_module_css_default["chevron"]
86
- }
87
- )
88
- ]
89
- }
90
- );
91
- let body;
92
76
  if (state.status === "error") {
93
- body = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["body"], children: [
77
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
94
78
  state.applyState.kind === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["savedNotice"], role: "status", children: t("saved") }) : null,
95
79
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["error"], children: `${t("loadFailed")}: ${state.error ?? ""}` }),
96
80
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: advisor_card_module_css_default["footer"], children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: advisor_card_module_css_default["discard"], onClick: () => {
97
81
  void controller.load();
98
82
  }, children: t("retry") }) })
99
83
  ] });
100
- } else if (degraded) {
101
- body = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["body"], children: [
84
+ }
85
+ const degraded = state.status === "ready" ? !state.advisorPresent : state.degraded;
86
+ if (degraded) {
87
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
102
88
  state.applyState.kind === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["savedNotice"], role: "status", children: t("saved") }) : null,
103
89
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["notice"], role: "status", children: t("namespaceUnavailable") }),
104
90
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: advisor_card_module_css_default["footer"], children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: advisor_card_module_css_default["discard"], onClick: () => {
105
91
  void controller.load();
106
92
  }, children: t("retry") }) })
107
93
  ] });
108
- } else if (state.status === "ready") {
109
- const { draft, providers, writable, applyState } = state;
110
- const providerEmpty = draft.provider === void 0;
111
- const modelEmpty = draft.model === void 0;
112
- const gateFailed = draft.enabled && (providerEmpty || modelEmpty);
113
- const saving = applyState.kind === "saving";
114
- const busy = !writable || saving;
115
- const selectedModels = draft.provider === void 0 ? [] : state.modelsByProvider[draft.provider] ?? [];
116
- const modelsEmpty = draft.provider !== void 0 && Object.hasOwn(state.modelsEmptyReason, draft.provider);
117
- const providerStale = draft.provider !== void 0 && !providers.some((option) => option.provider === draft.provider);
118
- const modelStale = !providerStale && draft.model !== void 0 && selectedModels.length > 0 && !selectedModels.some((option) => option.id === draft.model);
119
- const errorText = applyState.kind === "error" ? failureCopy(applyState.failure, t) : void 0;
120
- const saveDisabled = !state.dirty || gateFailed || saving || !writable;
121
- const discardDisabled = !state.dirty || saving;
122
- body = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["body"], children: [
123
- !writable ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["readOnly"], role: "status", children: t("readOnly") }) : null,
124
- applyState.kind === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["savedNotice"], role: "status", children: t("saved") }) : null,
125
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["form"], children: [
126
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["checkboxRow"], children: [
127
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "advisor-enabled", className: advisor_card_module_css_default["checkLabel"], children: t("enabled") }),
94
+ }
95
+ const refreshHold = state.status === "loading" && state.advisorPresent === true;
96
+ if (state.status !== "ready" && !refreshHold) {
97
+ return null;
98
+ }
99
+ const { draft, providers, writable, applyState } = state;
100
+ const providerEmpty = draft.provider === void 0;
101
+ const modelEmpty = draft.model === void 0;
102
+ const gateFailed = providerEmpty || modelEmpty;
103
+ const saving = applyState.kind === "saving";
104
+ const busy = !writable || saving || state.status === "loading";
105
+ const selectedModels = draft.provider === void 0 ? [] : state.modelsByProvider[draft.provider] ?? [];
106
+ const modelsEmpty = draft.provider !== void 0 && Object.hasOwn(state.modelsEmptyReason, draft.provider);
107
+ const providerStale = draft.provider !== void 0 && !providers.some((option) => option.provider === draft.provider);
108
+ const modelStale = !providerStale && draft.model !== void 0 && selectedModels.length > 0 && !selectedModels.some((option) => option.id === draft.model);
109
+ const errorText = applyState.kind === "error" ? failureCopy(applyState.failure, t) : void 0;
110
+ const saveDisabled = !state.dirty || gateFailed || saving || !writable;
111
+ const discardDisabled = !state.dirty || saving;
112
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
113
+ !writable ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["readOnly"], role: "status", children: t("readOnly") }) : null,
114
+ applyState.kind === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["savedNotice"], role: "status", children: t("saved") }) : null,
115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["form"], children: [
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["field"], children: [
117
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "advisor-provider", className: advisor_card_module_css_default["fieldLabel"], children: t("provider") }),
118
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
119
+ "select",
120
+ {
121
+ id: "advisor-provider",
122
+ "aria-label": t("provider"),
123
+ className: `${advisor_card_module_css_default["input"]} ${advisor_card_module_css_default["selectInput"]}`,
124
+ value: draft.provider ?? "",
125
+ disabled: busy,
126
+ onChange: (event) => {
127
+ controller.setProvider(event.target.value);
128
+ },
129
+ children: [
130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: t("providerPlaceholder") }),
131
+ providers.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: option.provider, children: option.displayName }, option.provider))
132
+ ]
133
+ }
134
+ ),
135
+ providers.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["hint"], children: t("noProviders") }) : null,
136
+ providerEmpty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["warnHint"], children: t("providerRequired") }) : null,
137
+ providerStale ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["hint"], children: t("staleProvider") }) : null
138
+ ] }),
139
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["field"], children: [
140
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "advisor-model", className: advisor_card_module_css_default["fieldLabel"], children: t("model") }),
141
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
142
+ "select",
143
+ {
144
+ id: "advisor-model",
145
+ "aria-label": t("model"),
146
+ className: `${advisor_card_module_css_default["input"]} ${advisor_card_module_css_default["selectInput"]}`,
147
+ value: draft.model ?? "",
148
+ disabled: busy || draft.provider === void 0 || selectedModels.length === 0,
149
+ onChange: (event) => {
150
+ controller.setModel(event.target.value);
151
+ },
152
+ children: [
153
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: t("modelPlaceholder") }),
154
+ selectedModels.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: option.id, children: option.name }, option.id))
155
+ ]
156
+ }
157
+ ),
158
+ modelsEmpty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["hint"], children: t("noModels") }) : null,
159
+ modelStale ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["hint"], children: t("staleModel") }) : null,
160
+ !providerEmpty && modelEmpty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["warnHint"], children: t("modelRequired") }) : null
161
+ ] }),
162
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["field"], children: [
163
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "advisor-system-prompt", className: advisor_card_module_css_default["fieldLabel"], children: t("systemPrompt") }),
164
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
165
+ "textarea",
166
+ {
167
+ id: "advisor-system-prompt",
168
+ "aria-label": t("systemPrompt"),
169
+ placeholder: DEFAULT_ADVISOR_SYSTEM_PROMPT,
170
+ className: advisor_card_module_css_default["textarea"],
171
+ value: draft.systemPrompt,
172
+ disabled: busy,
173
+ onChange: (event) => {
174
+ controller.setSystemPrompt(event.target.value);
175
+ }
176
+ }
177
+ ),
178
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["hint"], children: t("systemPromptHint") })
179
+ ] }),
180
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["numberFields"], children: [
181
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["field"], children: [
182
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "advisor-immune-turns", className: advisor_card_module_css_default["fieldLabel"], children: t("immuneTurns") }),
128
183
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
129
184
  "input",
130
185
  {
131
- id: "advisor-enabled",
132
- type: "checkbox",
133
- className: advisor_card_module_css_default["checkbox"],
134
- checked: draft.enabled,
186
+ id: "advisor-immune-turns",
187
+ "aria-label": t("immuneTurns"),
188
+ className: advisor_card_module_css_default["input"],
189
+ type: "number",
190
+ min: 0,
191
+ step: 1,
192
+ value: draft.immuneTurns ?? "",
135
193
  disabled: busy,
136
194
  onChange: (event) => {
137
- controller.setEnabled(event.target.checked);
195
+ controller.setImmuneTurns(event.target.value === "" ? void 0 : Number(event.target.value));
138
196
  }
139
197
  }
140
198
  )
141
199
  ] }),
142
- draft.enabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", { className: advisor_card_module_css_default["fieldset"], children: [
143
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["field"], children: [
144
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "advisor-provider", className: advisor_card_module_css_default["fieldLabel"], children: t("provider") }),
145
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
146
- "select",
147
- {
148
- id: "advisor-provider",
149
- "aria-label": t("provider"),
150
- className: `${advisor_card_module_css_default["input"]} ${advisor_card_module_css_default["selectInput"]}`,
151
- value: draft.provider ?? "",
152
- disabled: busy,
153
- onChange: (event) => {
154
- controller.setProvider(event.target.value);
155
- },
156
- children: [
157
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: t("providerPlaceholder") }),
158
- providers.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: option.provider, children: option.displayName }, option.provider))
159
- ]
160
- }
161
- ),
162
- providers.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["hint"], children: t("noProviders") }) : null,
163
- providerEmpty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["warnHint"], children: t("providerRequired") }) : null,
164
- providerStale ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["hint"], children: t("staleProvider") }) : null
165
- ] }),
166
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["field"], children: [
167
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "advisor-model", className: advisor_card_module_css_default["fieldLabel"], children: t("model") }),
168
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
169
- "select",
170
- {
171
- id: "advisor-model",
172
- "aria-label": t("model"),
173
- className: `${advisor_card_module_css_default["input"]} ${advisor_card_module_css_default["selectInput"]}`,
174
- value: draft.model ?? "",
175
- disabled: busy || draft.provider === void 0 || selectedModels.length === 0,
176
- onChange: (event) => {
177
- controller.setModel(event.target.value);
178
- },
179
- children: [
180
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: t("modelPlaceholder") }),
181
- selectedModels.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: option.id, children: option.name }, option.id))
182
- ]
183
- }
184
- ),
185
- modelsEmpty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["hint"], children: t("noModels") }) : null,
186
- modelStale ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["hint"], children: t("staleModel") }) : null,
187
- !providerEmpty && modelEmpty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["warnHint"], children: t("modelRequired") }) : null
188
- ] })
189
- ] }) : null,
190
200
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["field"], children: [
191
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "advisor-system-prompt", className: advisor_card_module_css_default["fieldLabel"], children: t("systemPrompt") }),
201
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "advisor-max-delta-messages", className: advisor_card_module_css_default["fieldLabel"], children: t("maxDeltaMessages") }),
192
202
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
193
- "textarea",
203
+ "input",
194
204
  {
195
- id: "advisor-system-prompt",
196
- "aria-label": t("systemPrompt"),
197
- placeholder: t("systemPromptPlaceholder"),
198
- className: advisor_card_module_css_default["textarea"],
199
- value: draft.systemPrompt,
205
+ id: "advisor-max-delta-messages",
206
+ "aria-label": t("maxDeltaMessages"),
207
+ className: advisor_card_module_css_default["input"],
208
+ type: "number",
209
+ min: 0,
210
+ step: 1,
211
+ value: draft.maxDeltaMessages ?? "",
200
212
  disabled: busy,
201
213
  onChange: (event) => {
202
- controller.setSystemPrompt(event.target.value);
214
+ controller.setMaxDeltaMessages(event.target.value === "" ? void 0 : Number(event.target.value));
203
215
  }
204
216
  }
205
217
  )
206
- ] }),
207
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["numberFields"], children: [
208
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["field"], children: [
209
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "advisor-immune-turns", className: advisor_card_module_css_default["fieldLabel"], children: t("immuneTurns") }),
210
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
211
- "input",
212
- {
213
- id: "advisor-immune-turns",
214
- "aria-label": t("immuneTurns"),
215
- className: advisor_card_module_css_default["input"],
216
- type: "number",
217
- min: 0,
218
- step: 1,
219
- value: draft.immuneTurns ?? "",
220
- disabled: busy,
221
- onChange: (event) => {
222
- controller.setImmuneTurns(event.target.value === "" ? void 0 : Number(event.target.value));
223
- }
224
- }
225
- )
226
- ] }),
227
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["field"], children: [
228
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "advisor-max-delta-messages", className: advisor_card_module_css_default["fieldLabel"], children: t("maxDeltaMessages") }),
229
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
230
- "input",
231
- {
232
- id: "advisor-max-delta-messages",
233
- "aria-label": t("maxDeltaMessages"),
234
- className: advisor_card_module_css_default["input"],
235
- type: "number",
236
- min: 0,
237
- step: 1,
238
- value: draft.maxDeltaMessages ?? "",
239
- disabled: busy,
240
- onChange: (event) => {
241
- controller.setMaxDeltaMessages(event.target.value === "" ? void 0 : Number(event.target.value));
242
- }
243
- }
244
- )
245
- ] })
246
218
  ] })
247
- ] }),
248
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["footer"], children: [
249
- errorText === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["failed"], role: "status", children: errorText }),
250
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
251
- "button",
252
- {
253
- type: "button",
254
- className: advisor_card_module_css_default["discard"],
255
- disabled: discardDisabled,
256
- onClick: () => {
257
- controller.discard();
258
- },
259
- children: t("discard")
260
- }
261
- ),
262
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
263
- "button",
264
- {
265
- type: "button",
266
- className: advisor_card_module_css_default["save"],
267
- disabled: saveDisabled,
268
- onClick: () => {
269
- void controller.apply();
270
- },
271
- children: t(saving ? "saving" : "save")
272
- }
273
- )
274
219
  ] })
275
- ] });
276
- } else {
277
- body = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: advisor_card_module_css_default["body"] });
278
- }
279
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: open ? `${advisor_card_module_css_default["card"]} ${advisor_card_module_css_default["cardOpen"]}` : advisor_card_module_css_default["card"], children: [
280
- header,
281
- open ? body : null
220
+ ] }),
221
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: advisor_card_module_css_default["footer"], children: [
222
+ errorText === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: advisor_card_module_css_default["failed"], role: "status", children: errorText }),
223
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
224
+ "button",
225
+ {
226
+ type: "button",
227
+ className: advisor_card_module_css_default["discard"],
228
+ disabled: discardDisabled,
229
+ onClick: () => {
230
+ controller.discard();
231
+ },
232
+ children: t("discard")
233
+ }
234
+ ),
235
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
236
+ "button",
237
+ {
238
+ type: "button",
239
+ className: advisor_card_module_css_default["save"],
240
+ disabled: saveDisabled,
241
+ onClick: () => {
242
+ void controller.apply();
243
+ },
244
+ children: t(saving ? "saving" : "save")
245
+ }
246
+ )
247
+ ] })
282
248
  ] });
283
249
  }
284
250
 
285
251
  // src/client/advisor-session.tsx
286
- var import_react2 = require("react");
252
+ var import_react = require("react");
287
253
 
288
254
  var css2 = ".C5gNya_trigger{appearance:none;border:1px solid var(--dsw-alias-border-l2);font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap;background:0 0;border-radius:999px;padding:3px 12px;font-size:13px;line-height:20px}.C5gNya_trigger:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.C5gNya_trigger[aria-expanded=true]{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);border-color:var(--dsw-alias-label-dimmed)}.C5gNya_trigger:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.C5gNya_anchor{display:inline-flex;position:relative}.C5gNya_panel{z-index:30;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;flex-direction:column;gap:10px;width:300px;padding:12px 14px;display:flex;position:absolute;top:calc(100% + 6px);right:0;box-shadow:0 8px 24px #0000002e}.C5gNya_panelHeading{color:var(--dsw-alias-label-primary);margin:0;font-size:13px;font-weight:600;line-height:20px}.C5gNya_routeLine{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;margin:0;font-size:13px;line-height:20px}.C5gNya_sourceBadge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;margin-left:6px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.C5gNya_mutedLine{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.C5gNya_notice{color:var(--dsw-alias-state-warn-label);margin:0;font-size:12px;line-height:18px}.C5gNya_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}.C5gNya_controls{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:8px;padding-top:8px;display:flex}.C5gNya_selectRow{gap:8px;display:flex}.C5gNya_select{appearance:auto;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-width:0;color:var(--dsw-alias-label-primary);font:inherit;border-radius:8px;flex:1;padding:4px 6px;font-size:12px;line-height:18px}.C5gNya_select:disabled{opacity:.4;cursor:default}.C5gNya_select:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-1px}.C5gNya_actions{justify-content:flex-end;align-items:center;gap:8px;display:flex}.C5gNya_reset,.C5gNya_pin{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:4px 12px;font-size:12px;line-height:18px}.C5gNya_reset{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.C5gNya_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.C5gNya_pin{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.C5gNya_reset:disabled,.C5gNya_pin:disabled{opacity:.4;cursor:default}.C5gNya_reset:focus-visible,.C5gNya_pin:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}";
289
255
  var tagId2 = "dsh-advisor/advisor-session.module.css";
@@ -303,9 +269,9 @@ function AdvisorSessionAction(props) {
303
269
  const state = useSnapshot((s) => s);
304
270
  const epoch = useRefreshSignal((s) => s.epoch);
305
271
  const directoryState = useDirectory((s) => s);
306
- const [open, setOpen] = (0, import_react2.useState)(false);
307
- const [provider, setProvider] = (0, import_react2.useState)("");
308
- const [model, setModel] = (0, import_react2.useState)("");
272
+ const [open, setOpen] = (0, import_react.useState)(false);
273
+ const [provider, setProvider] = (0, import_react.useState)("");
274
+ const [model, setModel] = (0, import_react.useState)("");
309
275
  const openAdvisor = () => {
310
276
  setOpen(true);
311
277
  controller.takeSignal(epoch);
@@ -427,7 +393,7 @@ function AdvisorSessionAction(props) {
427
393
  // src/client/advisor-store.ts
428
394
  var import_dsh_client_store = require("@deepseek-ai/dsh-client-store");
429
395
  function defaultDraft() {
430
- return { enabled: false, systemPrompt: "", immuneTurns: 3, maxDeltaMessages: 60 };
396
+ return { systemPrompt: "", immuneTurns: 3, maxDeltaMessages: 60 };
431
397
  }
432
398
  function stringField(value) {
433
399
  return typeof value === "string" && value.trim().length > 0 ? value : void 0;
@@ -437,7 +403,6 @@ function numberField(value, fallback) {
437
403
  }
438
404
  function draftOfConfig(config) {
439
405
  return {
440
- enabled: config?.enabled === true,
441
406
  provider: stringField(config?.provider),
442
407
  model: stringField(config?.model),
443
408
  systemPrompt: typeof config?.systemPrompt === "string" ? config.systemPrompt : "",
@@ -446,7 +411,6 @@ function draftOfConfig(config) {
446
411
  };
447
412
  }
448
413
  function gateFailure(draft) {
449
- if (!draft.enabled) return void 0;
450
414
  if (draft.provider === void 0) return "provider";
451
415
  if (draft.model === void 0) return "model";
452
416
  return void 0;
@@ -474,8 +438,8 @@ var AdvisorSettingsStore = class {
474
438
  namespaces: {},
475
439
  advisorPresent: false,
476
440
  // qc1 S-2: the degraded latch defaults false — a first mount / healthy
477
- // card is never degraded, so the healthy card stays collapsed through its
478
- // first load (the latch only flips on a settled degraded ready state).
441
+ // card is never degraded, so a healthy first load renders nothing (the
442
+ // latch only flips on a settled degraded ready state).
479
443
  degraded: false,
480
444
  // KD-U2: dirty derives from the patch diff against the seed
481
445
  // (recomputeDirty below — patchFor non-empty), recomputed on
@@ -687,10 +651,6 @@ var AdvisorSettingsStore = class {
687
651
  if (generation === this.catalogGeneration) this.catalog = void 0;
688
652
  }
689
653
  }
690
- /** Set the enabled switch (gate fields become required while on). */
691
- setEnabled(enabled) {
692
- this.setField("enabled", enabled);
693
- }
694
654
  /** Set or clear the provider ('' clears); switches invalidate the chosen model. */
695
655
  setProvider(provider) {
696
656
  const trimmed = provider.trim();
@@ -828,7 +788,7 @@ var AdvisorSettingsStore = class {
828
788
  */
829
789
  patchFor(draft) {
830
790
  const patch = {};
831
- const always = ["enabled", "systemPrompt", "immuneTurns", "maxDeltaMessages"];
791
+ const always = ["systemPrompt", "immuneTurns", "maxDeltaMessages"];
832
792
  for (const key of always) {
833
793
  const next = draft[key];
834
794
  if (next === void 0) continue;
@@ -1042,26 +1002,20 @@ var import_dsh_client_store2 = require("@deepseek-ai/dsh-client-store");
1042
1002
 
1043
1003
  // src/client/locales.ts
1044
1004
  var en = {
1045
- title: "Advisor",
1046
- intro: "Configure the advisor reviewer model that observes the primary transcript and injects severity-ranked advice.",
1047
- collapse: "Hide settings",
1048
- expand: "Show settings",
1049
- unsaved: "Unsaved",
1050
1005
  loadFailed: "Loading advisor settings failed",
1051
1006
  retry: "Retry",
1052
- enabled: "Enable the advisor",
1053
1007
  provider: "Provider",
1054
1008
  providerPlaceholder: "Select a provider",
1055
- providerRequired: "Provider is required when the advisor is enabled.",
1009
+ providerRequired: "Provider is required.",
1056
1010
  model: "Model",
1057
1011
  modelPlaceholder: "Select a model",
1058
- modelRequired: "Model is required when the advisor is enabled.",
1012
+ modelRequired: "Model is required.",
1059
1013
  noProviders: "No configured providers. Configure one on the Models page first.",
1060
1014
  noModels: "This provider has no available models. Configure models for it on the Models page.",
1061
1015
  staleProvider: "The stored provider is no longer configured. Reselect one or keep the stored value.",
1062
1016
  staleModel: "The stored model is no longer available for this provider. Reselect one or keep the stored value.",
1063
1017
  systemPrompt: "System prompt",
1064
- systemPromptPlaceholder: "Leave empty to use the default system prompt",
1018
+ systemPromptHint: "Leave empty to use the default system prompt",
1065
1019
  immuneTurns: "Immune turns",
1066
1020
  maxDeltaMessages: "Max delta messages",
1067
1021
  save: "Save",
@@ -1069,7 +1023,7 @@ var en = {
1069
1023
  discard: "Discard",
1070
1024
  saved: "Advisor settings saved. New sessions pick them up immediately.",
1071
1025
  readOnly: "Settings are read-only in this environment.",
1072
- namespaceUnavailable: "The advisor configuration channel is not available yet \u2014 the settings gateway is not ready on this host. Configure the advisor via the plugin config row \u2014 `- id: advisor` whose `config:` map sets `enabled`/`provider`/`model` (e.g. `config: { enabled: true, provider: \u2026, model: \u2026 }`) in `$DSH_HOME/profiles/<name>/cordis.patch.yml`. The advisor plugin runs fully from its plugin config row; the web settings form becomes available again on the next load once the gateway is reachable. Note: `/advisor` only toggles the advisor per session; it cannot supply provider/model.",
1026
+ namespaceUnavailable: "The advisor configuration channel is not available yet \u2014 the settings gateway is not ready on this host. Configure the advisor via the plugin config row \u2014 `- id: advisor` whose `config:` map sets `provider`/`model` (e.g. `config: { provider: \u2026, model: \u2026 }`) in `$DSH_HOME/profiles/<name>/cordis.patch.yml`. The advisor plugin runs fully from its plugin config row; the web settings form becomes available again on the next load once the gateway is reachable. Note: `/advisor` only toggles the advisor per session; it cannot supply provider/model.",
1073
1027
  // Session header action (B2): the control lives on the session header and
1074
1028
  // drives the live-session reviewer route only.
1075
1029
  sessionTrigger: "Advisor",
@@ -1089,26 +1043,20 @@ var en = {
1089
1043
  sessionUnavailable: "The advisor session control surface is not available on this host. Use /advisor model in the session, or configure the global defaults on the Plugins page."
1090
1044
  };
1091
1045
  var zh = {
1092
- title: "\u987E\u95EE",
1093
- intro: "\u914D\u7F6E\u987E\u95EE\u5BA1\u9605\u6A21\u578B\uFF1A\u5B83\u89C2\u5BDF\u4E3B\u4F1A\u8BDD\u8BB0\u5F55\uFF0C\u5E76\u6CE8\u5165\u6309\u4E25\u91CD\u7A0B\u5EA6\u6392\u5E8F\u7684\u5EFA\u8BAE\u3002",
1094
- collapse: "\u6536\u8D77\u8BBE\u7F6E",
1095
- expand: "\u5C55\u5F00\u8BBE\u7F6E",
1096
- unsaved: "\u672A\u4FDD\u5B58",
1097
1046
  loadFailed: "\u52A0\u8F7D\u987E\u95EE\u8BBE\u7F6E\u5931\u8D25",
1098
1047
  retry: "\u91CD\u8BD5",
1099
- enabled: "\u542F\u7528\u987E\u95EE",
1100
1048
  provider: "\u63D0\u4F9B\u5546",
1101
1049
  providerPlaceholder: "\u9009\u62E9\u63D0\u4F9B\u5546",
1102
- providerRequired: "\u542F\u7528\u987E\u95EE\u65F6\u5FC5\u987B\u9009\u62E9\u63D0\u4F9B\u5546\u3002",
1050
+ providerRequired: "\u63D0\u4F9B\u5546\u4E0D\u80FD\u4E3A\u7A7A\u3002",
1103
1051
  model: "\u6A21\u578B",
1104
1052
  modelPlaceholder: "\u9009\u62E9\u6A21\u578B",
1105
- modelRequired: "\u542F\u7528\u987E\u95EE\u65F6\u5FC5\u987B\u9009\u62E9\u6A21\u578B\u3002",
1053
+ modelRequired: "\u6A21\u578B\u4E0D\u80FD\u4E3A\u7A7A\u3002",
1106
1054
  noProviders: "\u6CA1\u6709\u5DF2\u914D\u7F6E\u7684\u63D0\u4F9B\u5546\u3002\u8BF7\u5148\u5728 Models \u9875\u9762\u914D\u7F6E\u3002",
1107
1055
  noModels: "\u8BE5\u63D0\u4F9B\u5546\u6CA1\u6709\u53EF\u7528\u6A21\u578B\u3002\u8BF7\u5230 Models \u9875\u9762\u4E3A\u5176\u914D\u7F6E\u6A21\u578B\u3002",
1108
1056
  staleProvider: "\u5B58\u50A8\u7684\u63D0\u4F9B\u5546\u5DF2\u4E0D\u5728\u914D\u7F6E\u4E2D\u3002\u8BF7\u91CD\u65B0\u9009\u62E9\uFF0C\u6216\u4FDD\u7559\u5B58\u50A8\u7684\u503C\u3002",
1109
1057
  staleModel: "\u5B58\u50A8\u7684\u6A21\u578B\u5728\u8BE5\u63D0\u4F9B\u5546\u4E0B\u5DF2\u4E0D\u53EF\u7528\u3002\u8BF7\u91CD\u65B0\u9009\u62E9\uFF0C\u6216\u4FDD\u7559\u5B58\u50A8\u7684\u503C\u3002",
1110
1058
  systemPrompt: "\u7CFB\u7EDF\u63D0\u793A\u8BCD",
1111
- systemPromptPlaceholder: "\u7559\u7A7A\u5219\u4F7F\u7528\u9ED8\u8BA4\u7CFB\u7EDF\u63D0\u793A\u8BCD",
1059
+ systemPromptHint: "\u7559\u7A7A\u5219\u4F7F\u7528\u9ED8\u8BA4\u7CFB\u7EDF\u63D0\u793A\u8BCD",
1112
1060
  immuneTurns: "\u514D\u75AB\u8F6E\u6B21",
1113
1061
  maxDeltaMessages: "\u6700\u5927\u589E\u91CF\u6D88\u606F\u6570",
1114
1062
  save: "\u4FDD\u5B58",
@@ -1116,7 +1064,7 @@ var zh = {
1116
1064
  discard: "\u653E\u5F03\u4FEE\u6539",
1117
1065
  saved: "\u987E\u95EE\u8BBE\u7F6E\u5DF2\u4FDD\u5B58\u3002\u65B0\u4F1A\u8BDD\u7ACB\u5373\u751F\u6548\u3002",
1118
1066
  readOnly: "\u5F53\u524D\u73AF\u5883\u4E2D\u7684\u8BBE\u7F6E\u4E3A\u53EA\u8BFB\u3002",
1119
- namespaceUnavailable: "\u987E\u95EE\u914D\u7F6E\u901A\u9053\u6682\u4E0D\u53EF\u7528\u2014\u2014\u672C\u5BBF\u4E3B\u4E0A\u7684\u8BBE\u7F6E\u7F51\u5173\u5C1A\u672A\u5C31\u7EEA\u3002\u8BF7\u901A\u8FC7\u63D2\u4EF6\u914D\u7F6E\u884C\u914D\u7F6E\u987E\u95EE\u2014\u2014\u5728 `$DSH_HOME/profiles/<name>/cordis.patch.yml` \u4E2D\u5199 `- id: advisor`\uFF0C\u5176 `config:` \u6620\u5C04\u4E2D\u8BBE\u7F6E `enabled`/`provider`/`model`\uFF08\u4F8B\u5982 `config: { enabled: true, provider: \u2026, model: \u2026 }`\uFF09\u3002\u987E\u95EE\u63D2\u4EF6\u5B8C\u5168\u901A\u8FC7\u63D2\u4EF6\u914D\u7F6E\u884C\u8FD0\u884C\uFF1B\u7F51\u5173\u53EF\u7528\u540E\uFF0Cweb \u8BBE\u7F6E\u8868\u5355\u5C06\u5728\u4E0B\u6B21\u52A0\u8F7D\u65F6\u91CD\u65B0\u663E\u793A\u3002\u6CE8\u610F\uFF1A`/advisor` \u4EC5\u5207\u6362\u5F53\u524D\u4F1A\u8BDD\u7684\u987E\u95EE\u5F00\u5173\uFF0C\u65E0\u6CD5\u63D0\u4F9B provider/model\u3002",
1067
+ namespaceUnavailable: "\u987E\u95EE\u914D\u7F6E\u901A\u9053\u6682\u4E0D\u53EF\u7528\u2014\u2014\u672C\u5BBF\u4E3B\u4E0A\u7684\u8BBE\u7F6E\u7F51\u5173\u5C1A\u672A\u5C31\u7EEA\u3002\u8BF7\u901A\u8FC7\u63D2\u4EF6\u914D\u7F6E\u884C\u914D\u7F6E\u987E\u95EE\u2014\u2014\u5728 `$DSH_HOME/profiles/<name>/cordis.patch.yml` \u4E2D\u5199 `- id: advisor`\uFF0C\u5176 `config:` \u6620\u5C04\u4E2D\u8BBE\u7F6E `provider`/`model`\uFF08\u4F8B\u5982 `config: { provider: \u2026, model: \u2026 }`\uFF09\u3002\u987E\u95EE\u63D2\u4EF6\u5B8C\u5168\u901A\u8FC7\u63D2\u4EF6\u914D\u7F6E\u884C\u8FD0\u884C\uFF1B\u7F51\u5173\u53EF\u7528\u540E\uFF0Cweb \u8BBE\u7F6E\u8868\u5355\u5C06\u5728\u4E0B\u6B21\u52A0\u8F7D\u65F6\u91CD\u65B0\u663E\u793A\u3002\u6CE8\u610F\uFF1A`/advisor` \u4EC5\u5207\u6362\u5F53\u524D\u4F1A\u8BDD\u7684\u987E\u95EE\u5F00\u5173\uFF0C\u65E0\u6CD5\u63D0\u4F9B provider/model\u3002",
1120
1068
  sessionTrigger: "\u987E\u95EE",
1121
1069
  sessionExpand: "\u6253\u5F00\u672C\u4F1A\u8BDD\u7684\u987E\u95EE\u63A7\u5236",
1122
1070
  sessionCollapse: "\u5173\u95ED\u672C\u4F1A\u8BDD\u7684\u987E\u95EE\u63A7\u5236",