dsh-model-switch 0.4.20 → 0.4.21
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/CHANGELOG.md +212 -203
- package/IMPLEMENTATION_PLAN.md +40 -40
- package/LICENSE +21 -21
- package/PRODUCT.md +33 -33
- package/README.md +214 -208
- package/README.zh.md +212 -206
- package/cordis.patch.yml +515 -30
- package/lib/client.js +245 -258
- package/lib/compaction.js +205 -0
- package/lib/index.js +12 -242
- package/lib/types/capabilities-rpc.d.ts +2 -3
- package/lib/types/client/ModelSwitchSettings.d.ts +2 -2
- package/lib/types/client/derived-settings-scope.d.ts +4 -4
- package/lib/types/client/locales.d.ts +4 -3
- package/lib/types/client/picker/PlanReviewCard.d.ts +0 -3
- package/lib/types/client/picker/locales.d.ts +0 -8
- package/lib/types/client/remote-settings-scope.d.ts +45 -45
- package/lib/types/client-contract.d.ts +10 -4
- package/lib/types/compaction.d.ts +56 -0
- package/lib/types/host-runtime.d.ts +8 -2
- package/lib/types/host-settings.d.ts +10 -5
- package/lib/types/picker/plan-goal.d.ts +29 -3
- package/package.json +360 -356
- package/lib/types/picker/plan-compact.d.ts +0 -48
- package/lib/types/plan-compact.d.ts +0 -82
package/lib/client.js
CHANGED
|
@@ -38,6 +38,11 @@ window.__ModuleLoader__.load({
|
|
|
38
38
|
provider: "autoReviewProvider",
|
|
39
39
|
model: "autoReviewModel"
|
|
40
40
|
});
|
|
41
|
+
/** Compaction summarization route for `/compact` and automatic compaction; both unset means the official default (the conversation target). */
|
|
42
|
+
const COMPACTION_SETTINGS_FIELDS = Object.freeze({
|
|
43
|
+
provider: "compactProvider",
|
|
44
|
+
model: "compactModel"
|
|
45
|
+
});
|
|
41
46
|
function deriveSubagentSettings(settings) {
|
|
42
47
|
return {
|
|
43
48
|
mode: settings.subagentMode,
|
|
@@ -64,8 +69,14 @@ window.__ModuleLoader__.load({
|
|
|
64
69
|
...settings.autoReviewModel === void 0 ? {} : { model: settings.autoReviewModel }
|
|
65
70
|
};
|
|
66
71
|
}
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
function deriveCompactionSettings(settings) {
|
|
73
|
+
return {
|
|
74
|
+
...settings.compactProvider === void 0 ? {} : { provider: settings.compactProvider },
|
|
75
|
+
...settings.compactModel === void 0 ? {} : { model: settings.compactModel }
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** Whether both fields of a model route form a complete pair; an incomplete pair stays off. */
|
|
79
|
+
function routePairConfigured(route) {
|
|
69
80
|
return route !== void 0 && (route.provider ?? "").trim() !== "" && (route.model ?? "").trim() !== "";
|
|
70
81
|
}
|
|
71
82
|
//#endregion
|
|
@@ -618,6 +629,19 @@ window.__ModuleLoader__.load({
|
|
|
618
629
|
return values.filter((value) => value !== void 0 && value !== "").join(" · ");
|
|
619
630
|
}
|
|
620
631
|
function RouteIcon({ kind }) {
|
|
632
|
+
if (kind === "compaction") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
633
|
+
width: "18",
|
|
634
|
+
height: "18",
|
|
635
|
+
viewBox: "0 0 18 18",
|
|
636
|
+
fill: "none",
|
|
637
|
+
"aria-hidden": "true",
|
|
638
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
639
|
+
d: "M5 3.5 9 7.5l4-4M5 14.5 9 10.5l4 4",
|
|
640
|
+
stroke: "currentColor",
|
|
641
|
+
strokeLinecap: "round",
|
|
642
|
+
strokeLinejoin: "round"
|
|
643
|
+
})
|
|
644
|
+
});
|
|
621
645
|
if (kind === "main") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
622
646
|
width: "18",
|
|
623
647
|
height: "18",
|
|
@@ -890,45 +914,18 @@ window.__ModuleLoader__.load({
|
|
|
890
914
|
const search = props.useSearchSettings((value) => value);
|
|
891
915
|
const image = props.useImageSettings((value) => value);
|
|
892
916
|
const autoReview = props.useAutoReviewSettings((value) => value);
|
|
917
|
+
const compaction = props.useCompactionSettings((value) => value);
|
|
893
918
|
const switchSettings = props.useSwitchSettings((value) => value);
|
|
894
919
|
const [open, setOpen] = (0, react.useState)();
|
|
895
920
|
const [subagentDraft, setSubagentDraft, resetSubagent] = useDraft(subagent);
|
|
896
921
|
const [searchDraft, setSearchDraft, resetSearch] = useDraft(search);
|
|
897
922
|
const [imageDraft, setImageDraft, resetImage] = useDraft(image);
|
|
898
923
|
const [autoReviewDraft, setAutoReviewDraft, resetAutoReview] = useDraft(autoReview);
|
|
924
|
+
const [compactionDraft, setCompactionDraft, resetCompaction] = useDraft(compaction);
|
|
899
925
|
const [busy, setBusy] = (0, react.useState)();
|
|
900
926
|
const [message, setMessage] = (0, react.useState)();
|
|
901
927
|
const [compactBusy, setCompactBusy] = (0, react.useState)(false);
|
|
902
928
|
const [compactError, setCompactError] = (0, react.useState)();
|
|
903
|
-
const planCompactValue = switchSettings.value?.planCompactThreshold ?? 2e5;
|
|
904
|
-
const [planCompactDraft, setPlanCompactDraft] = (0, react.useState)(() => String(planCompactValue));
|
|
905
|
-
const [planCompactBusy, setPlanCompactBusy] = (0, react.useState)(false);
|
|
906
|
-
const [planCompactError, setPlanCompactError] = (0, react.useState)();
|
|
907
|
-
(0, react.useEffect)(() => {
|
|
908
|
-
setPlanCompactDraft(String(planCompactValue));
|
|
909
|
-
setPlanCompactError(void 0);
|
|
910
|
-
}, [planCompactValue]);
|
|
911
|
-
/** Commit the threshold on blur/Enter only when it is a non-negative integer. */
|
|
912
|
-
const commitPlanCompactThreshold = () => {
|
|
913
|
-
const parsed = Number(planCompactDraft);
|
|
914
|
-
if (!Number.isInteger(parsed) || parsed < 0) {
|
|
915
|
-
setPlanCompactError(props.t("planCompactThresholdInvalid"));
|
|
916
|
-
return;
|
|
917
|
-
}
|
|
918
|
-
if (parsed === planCompactValue) {
|
|
919
|
-
setPlanCompactError(void 0);
|
|
920
|
-
return;
|
|
921
|
-
}
|
|
922
|
-
setPlanCompactBusy(true);
|
|
923
|
-
setPlanCompactError(void 0);
|
|
924
|
-
props.setPlanCompactThreshold(parsed).then(() => {
|
|
925
|
-
setPlanCompactBusy(false);
|
|
926
|
-
}, (error) => {
|
|
927
|
-
setPlanCompactBusy(false);
|
|
928
|
-
setPlanCompactDraft(String(planCompactValue));
|
|
929
|
-
setPlanCompactError(error instanceof Error ? error.message : props.t("requestFailed"));
|
|
930
|
-
});
|
|
931
|
-
};
|
|
932
929
|
const loadSearchCapabilities = props.loadCapabilities;
|
|
933
930
|
const [searchSnapshot, setSearchSnapshot] = (0, react.useState)(void 0);
|
|
934
931
|
const [searchError, setSearchError] = (0, react.useState)(void 0);
|
|
@@ -1020,13 +1017,16 @@ window.__ModuleLoader__.load({
|
|
|
1020
1017
|
const searchAvailable = searchLive?.searchProviderAdapters.available ?? false;
|
|
1021
1018
|
const imageChoices = capabilityChoices(groups, imageDraft, props.capabilities.imageProviderAdapters.providers ?? [], "image");
|
|
1022
1019
|
const autoReviewChoices = deriveRouteChoices(groups, autoReviewDraft);
|
|
1023
|
-
const autoReviewOn =
|
|
1020
|
+
const autoReviewOn = routePairConfigured(autoReview.value);
|
|
1021
|
+
const compactionChoices = deriveRouteChoices(groups, compactionDraft);
|
|
1022
|
+
const compactionOn = routePairConfigured(compaction.value);
|
|
1024
1023
|
const synced = [
|
|
1025
1024
|
main,
|
|
1026
1025
|
subagent,
|
|
1027
1026
|
search,
|
|
1028
1027
|
image,
|
|
1029
|
-
autoReview
|
|
1028
|
+
autoReview,
|
|
1029
|
+
compaction
|
|
1030
1030
|
].every((snapshot) => snapshot.status === "ready");
|
|
1031
1031
|
const run = async (route, operation) => {
|
|
1032
1032
|
if (busy !== void 0) return;
|
|
@@ -1092,6 +1092,13 @@ window.__ModuleLoader__.load({
|
|
|
1092
1092
|
if (autoReview.value?.model !== autoReviewDraft.model) await props.setCapability("autoReview", "model", autoReviewDraft.model);
|
|
1093
1093
|
});
|
|
1094
1094
|
};
|
|
1095
|
+
const saveCompaction = () => {
|
|
1096
|
+
if (compactionDraft === void 0) return;
|
|
1097
|
+
run("compaction", async () => {
|
|
1098
|
+
if (compaction.value?.provider !== compactionDraft.provider) await props.setCapability("compaction", "provider", compactionDraft.provider);
|
|
1099
|
+
if (compaction.value?.model !== compactionDraft.model) await props.setCapability("compaction", "model", compactionDraft.model);
|
|
1100
|
+
});
|
|
1101
|
+
};
|
|
1095
1102
|
/**
|
|
1096
1103
|
* The reviewer switch: Off unsets both stored fields (follow the session
|
|
1097
1104
|
* model); On seeds the route from Main so the pin takes effect immediately
|
|
@@ -1129,6 +1136,44 @@ window.__ModuleLoader__.load({
|
|
|
1129
1136
|
});
|
|
1130
1137
|
});
|
|
1131
1138
|
};
|
|
1139
|
+
/**
|
|
1140
|
+
* The compaction switch: Off unsets both stored fields (official default =
|
|
1141
|
+
* the conversation target); On seeds the route from Main so the pin takes
|
|
1142
|
+
* effect immediately and stays editable below. A failed write reports,
|
|
1143
|
+
* never flips silently.
|
|
1144
|
+
*/
|
|
1145
|
+
const persistCompactionEnabled = (enabled) => {
|
|
1146
|
+
if (busy === "compaction" || !compaction.writable || compaction.value === void 0) return;
|
|
1147
|
+
if (!enabled) {
|
|
1148
|
+
setOpen((current) => current === "compaction" ? void 0 : current);
|
|
1149
|
+
run("compaction", async () => {
|
|
1150
|
+
if (compaction.value?.provider !== void 0) await props.setCapability("compaction", "provider", void 0);
|
|
1151
|
+
if (compaction.value?.model !== void 0) await props.setCapability("compaction", "model", void 0);
|
|
1152
|
+
});
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
const seed = draft;
|
|
1156
|
+
if (seed === void 0 || seed.provider.trim() === "" || seed.model.trim() === "") return;
|
|
1157
|
+
setBusy("compaction");
|
|
1158
|
+
setMessage(void 0);
|
|
1159
|
+
(async () => {
|
|
1160
|
+
if (compaction.value?.provider !== seed.provider) await props.setCapability("compaction", "provider", seed.provider);
|
|
1161
|
+
if (compaction.value?.model !== seed.model) await props.setCapability("compaction", "model", seed.model);
|
|
1162
|
+
})().then(() => {
|
|
1163
|
+
setCompactionDraft({
|
|
1164
|
+
provider: seed.provider,
|
|
1165
|
+
model: seed.model
|
|
1166
|
+
});
|
|
1167
|
+
setBusy(void 0);
|
|
1168
|
+
setOpen("compaction");
|
|
1169
|
+
}, (error) => {
|
|
1170
|
+
setBusy(void 0);
|
|
1171
|
+
setMessage({
|
|
1172
|
+
route: "compaction",
|
|
1173
|
+
text: error instanceof Error ? error.message : props.t("requestFailed")
|
|
1174
|
+
});
|
|
1175
|
+
});
|
|
1176
|
+
};
|
|
1132
1177
|
const mainSummary = draft === void 0 ? props.t("loading") : compact(routeName(groups, draft), mainEffectiveEffort);
|
|
1133
1178
|
const subagentRole = subagentDraft?.mode === "fixed" && subagentDraft.provider !== void 0 && subagentDraft.provider !== "" ? props.providerRoleOf?.(subagentDraft.provider) : void 0;
|
|
1134
1179
|
const subagentOn = subagentDraft?.mode === "fixed";
|
|
@@ -1136,6 +1181,7 @@ window.__ModuleLoader__.load({
|
|
|
1136
1181
|
const subagentDisabled = subagent.status !== "ready" || !subagent.writable || subagentDraft === void 0 || busy === "subagent" || !subagentOn || (subagentDraft.provider ?? "").trim() === "" || (subagentDraft.model ?? "").trim() === "";
|
|
1137
1182
|
const capabilityDisabled = (route, snapshot, next) => snapshot.status !== "ready" || !snapshot.writable || next === void 0 || busy === route || (next.provider ?? "").trim() === "" || (next.model ?? "").trim() === "";
|
|
1138
1183
|
const autoReviewDisabled = autoReview.status !== "ready" || !autoReview.writable || autoReviewDraft === void 0 || busy === "autoReview" || !autoReviewOn || (autoReviewDraft.provider ?? "").trim() === "" || (autoReviewDraft.model ?? "").trim() === "";
|
|
1184
|
+
const compactionDisabled = compaction.status !== "ready" || !compaction.writable || compactionDraft === void 0 || busy === "compaction" || !compactionOn || (compactionDraft.provider ?? "").trim() === "" || (compactionDraft.model ?? "").trim() === "";
|
|
1139
1185
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("main", {
|
|
1140
1186
|
className: ModelSwitchSettings_module_css_default.section,
|
|
1141
1187
|
children: [
|
|
@@ -1153,129 +1199,66 @@ window.__ModuleLoader__.load({
|
|
|
1153
1199
|
}),
|
|
1154
1200
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1155
1201
|
className: ModelSwitchSettings_module_css_default.group,
|
|
1156
|
-
children: [
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
strokeLinejoin: "round"
|
|
1181
|
-
})]
|
|
1182
|
-
})
|
|
1183
|
-
}),
|
|
1184
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1185
|
-
className: ModelSwitchSettings_module_css_default.rowCopy,
|
|
1186
|
-
children: [
|
|
1187
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1188
|
-
className: ModelSwitchSettings_module_css_default.rowTitle,
|
|
1189
|
-
children: props.t("compactOnSwitch")
|
|
1190
|
-
}),
|
|
1191
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1192
|
-
className: ModelSwitchSettings_module_css_default.hint,
|
|
1193
|
-
children: props.t("compactOnSwitchHelp")
|
|
1194
|
-
}),
|
|
1195
|
-
compactError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1196
|
-
className: cx(ModelSwitchSettings_module_css_default.hint, ModelSwitchSettings_module_css_default.message),
|
|
1197
|
-
children: compactError
|
|
1198
|
-
})
|
|
1199
|
-
]
|
|
1200
|
-
}),
|
|
1201
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InstantSwitch, {
|
|
1202
|
-
checked: switchSettings.value?.compactOnSwitch !== false,
|
|
1203
|
-
disabled: !switchSettings.writable || compactBusy,
|
|
1204
|
-
label: props.t("compactOnSwitch"),
|
|
1205
|
-
onChange: (value) => {
|
|
1206
|
-
setCompactBusy(true);
|
|
1207
|
-
setCompactError(void 0);
|
|
1208
|
-
props.setCompactOnSwitch(value).then(() => {
|
|
1209
|
-
setCompactBusy(false);
|
|
1210
|
-
}, (error) => {
|
|
1211
|
-
setCompactBusy(false);
|
|
1212
|
-
setCompactError(error instanceof Error ? error.message : props.t("requestFailed"));
|
|
1213
|
-
});
|
|
1214
|
-
}
|
|
1202
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
1203
|
+
className: ModelSwitchSettings_module_css_default.groupLabel,
|
|
1204
|
+
children: props.t("sendProtection")
|
|
1205
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1206
|
+
className: ModelSwitchSettings_module_css_default.rowCard,
|
|
1207
|
+
children: [
|
|
1208
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1209
|
+
className: ModelSwitchSettings_module_css_default.routeIcon,
|
|
1210
|
+
"aria-hidden": "true",
|
|
1211
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
1212
|
+
width: "18",
|
|
1213
|
+
height: "18",
|
|
1214
|
+
viewBox: "0 0 18 18",
|
|
1215
|
+
fill: "none",
|
|
1216
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1217
|
+
d: "M4 5.5h10M4 9h7M4 12.5h5",
|
|
1218
|
+
stroke: "currentColor",
|
|
1219
|
+
strokeLinecap: "round"
|
|
1220
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1221
|
+
d: "M13 11.5v3.5l2-1.6",
|
|
1222
|
+
stroke: "currentColor",
|
|
1223
|
+
strokeLinecap: "round",
|
|
1224
|
+
strokeLinejoin: "round"
|
|
1225
|
+
})]
|
|
1215
1226
|
})
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
stroke: "currentColor",
|
|
1232
|
-
strokeLinecap: "round"
|
|
1233
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1234
|
-
d: "M13 11.5v3.5l2-1.6",
|
|
1235
|
-
stroke: "currentColor",
|
|
1236
|
-
strokeLinecap: "round",
|
|
1237
|
-
strokeLinejoin: "round"
|
|
1238
|
-
})]
|
|
1227
|
+
}),
|
|
1228
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1229
|
+
className: ModelSwitchSettings_module_css_default.rowCopy,
|
|
1230
|
+
children: [
|
|
1231
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1232
|
+
className: ModelSwitchSettings_module_css_default.rowTitle,
|
|
1233
|
+
children: props.t("compactOnSwitch")
|
|
1234
|
+
}),
|
|
1235
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1236
|
+
className: ModelSwitchSettings_module_css_default.hint,
|
|
1237
|
+
children: props.t("compactOnSwitchHelp")
|
|
1238
|
+
}),
|
|
1239
|
+
compactError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1240
|
+
className: cx(ModelSwitchSettings_module_css_default.hint, ModelSwitchSettings_module_css_default.message),
|
|
1241
|
+
children: compactError
|
|
1239
1242
|
})
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
className: ModelSwitchSettings_module_css_default.input,
|
|
1260
|
-
type: "number",
|
|
1261
|
-
min: 0,
|
|
1262
|
-
step: 1e3,
|
|
1263
|
-
inputMode: "numeric",
|
|
1264
|
-
"aria-label": props.t("planCompactThreshold"),
|
|
1265
|
-
value: planCompactDraft,
|
|
1266
|
-
disabled: !switchSettings.writable || planCompactBusy,
|
|
1267
|
-
onChange: (event) => {
|
|
1268
|
-
setPlanCompactDraft(event.target.value);
|
|
1269
|
-
setPlanCompactError(void 0);
|
|
1270
|
-
},
|
|
1271
|
-
onBlur: commitPlanCompactThreshold,
|
|
1272
|
-
onKeyDown: (event) => {
|
|
1273
|
-
if (event.key === "Enter") commitPlanCompactThreshold();
|
|
1274
|
-
}
|
|
1275
|
-
})
|
|
1276
|
-
]
|
|
1277
|
-
})
|
|
1278
|
-
]
|
|
1243
|
+
]
|
|
1244
|
+
}),
|
|
1245
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InstantSwitch, {
|
|
1246
|
+
checked: switchSettings.value?.compactOnSwitch !== false,
|
|
1247
|
+
disabled: !switchSettings.writable || compactBusy,
|
|
1248
|
+
label: props.t("compactOnSwitch"),
|
|
1249
|
+
onChange: (value) => {
|
|
1250
|
+
setCompactBusy(true);
|
|
1251
|
+
setCompactError(void 0);
|
|
1252
|
+
props.setCompactOnSwitch(value).then(() => {
|
|
1253
|
+
setCompactBusy(false);
|
|
1254
|
+
}, (error) => {
|
|
1255
|
+
setCompactBusy(false);
|
|
1256
|
+
setCompactError(error instanceof Error ? error.message : props.t("requestFailed"));
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
})
|
|
1260
|
+
]
|
|
1261
|
+
})]
|
|
1279
1262
|
}),
|
|
1280
1263
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1281
1264
|
className: ModelSwitchSettings_module_css_default.group,
|
|
@@ -1632,6 +1615,70 @@ window.__ModuleLoader__.load({
|
|
|
1632
1615
|
onSave: saveAutoReview
|
|
1633
1616
|
})
|
|
1634
1617
|
] })
|
|
1618
|
+
}),
|
|
1619
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RouteCard, {
|
|
1620
|
+
title: props.t("compaction"),
|
|
1621
|
+
summary: compactionDraft === void 0 ? props.t("loading") : compactionOn ? routeName(groups, compactionDraft) : props.t("compactionFollow"),
|
|
1622
|
+
hint: props.t("compactionHelp"),
|
|
1623
|
+
icon: "compaction",
|
|
1624
|
+
open: open === "compaction" && compactionOn,
|
|
1625
|
+
onToggle: () => {
|
|
1626
|
+
if (compactionOn) toggle("compaction");
|
|
1627
|
+
},
|
|
1628
|
+
expandable: compactionOn,
|
|
1629
|
+
trailing: compactionDraft === void 0 ? void 0 : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InstantSwitch, {
|
|
1630
|
+
checked: compactionOn,
|
|
1631
|
+
disabled: busy === "compaction" || !compaction.writable,
|
|
1632
|
+
label: props.t("compaction"),
|
|
1633
|
+
onChange: persistCompactionEnabled
|
|
1634
|
+
}),
|
|
1635
|
+
children: compactionDraft === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1636
|
+
className: ModelSwitchSettings_module_css_default.hint,
|
|
1637
|
+
children: props.t("loading")
|
|
1638
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1639
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1640
|
+
className: ModelSwitchSettings_module_css_default.hint,
|
|
1641
|
+
children: props.t("compactionRouteHelp")
|
|
1642
|
+
}),
|
|
1643
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1644
|
+
className: ModelSwitchSettings_module_css_default.formGrid,
|
|
1645
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
1646
|
+
label: props.t("provider"),
|
|
1647
|
+
value: compactionDraft.provider ?? "",
|
|
1648
|
+
disabled: busy === "compaction" || !compaction.writable,
|
|
1649
|
+
choices: compactionChoices.providers,
|
|
1650
|
+
onChange: (provider) => {
|
|
1651
|
+
const first = groups.find((group) => group.id === provider)?.models[0];
|
|
1652
|
+
setCompactionDraft({
|
|
1653
|
+
provider,
|
|
1654
|
+
...first === void 0 ? {} : { model: first.id }
|
|
1655
|
+
});
|
|
1656
|
+
}
|
|
1657
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
1658
|
+
label: props.t("model"),
|
|
1659
|
+
value: compactionDraft.model ?? "",
|
|
1660
|
+
disabled: busy === "compaction" || !compaction.writable,
|
|
1661
|
+
choices: compactionChoices.models,
|
|
1662
|
+
onChange: (model) => {
|
|
1663
|
+
setCompactionDraft({
|
|
1664
|
+
...compactionDraft,
|
|
1665
|
+
model
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1668
|
+
})]
|
|
1669
|
+
}),
|
|
1670
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Actions, {
|
|
1671
|
+
t: props.t,
|
|
1672
|
+
busy: busy === "compaction",
|
|
1673
|
+
disabled: compactionDisabled,
|
|
1674
|
+
...message?.route === "compaction" ? { message: message.text } : {},
|
|
1675
|
+
onCancel: () => {
|
|
1676
|
+
resetCompaction();
|
|
1677
|
+
setMessage(void 0);
|
|
1678
|
+
},
|
|
1679
|
+
onSave: saveCompaction
|
|
1680
|
+
})
|
|
1681
|
+
] })
|
|
1635
1682
|
})
|
|
1636
1683
|
]
|
|
1637
1684
|
})
|
|
@@ -1680,9 +1727,10 @@ window.__ModuleLoader__.load({
|
|
|
1680
1727
|
autoReviewFollow: "跟随会话模型",
|
|
1681
1728
|
autoReviewHelp: "为官方 auto-review(Auto 权限预设的逐调用审查)指定审查模型;需启用官方 auto-review 能力包。关闭时审查跟随当前会话模型。",
|
|
1682
1729
|
autoReviewRouteHelp: "审查请求固定使用这里的 Provider/模型,与会话模型无关;保存后对下一次审查立即生效。",
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1730
|
+
compaction: "压缩模型",
|
|
1731
|
+
compactionFollow: "跟随会话模型",
|
|
1732
|
+
compactionHelp: "为官方压缩(/compact 与官方自动压缩)指定摘要模型;关闭(两个字段都留空)时使用官方默认,即当前会话的目标模型。",
|
|
1733
|
+
compactionRouteHelp: "摘要请求固定使用这里的 Provider/模型,与会话目标模型无关;保存后对下一次压缩立即生效。保存时若恰有压缩进行中,可能被打断并在下次重试。",
|
|
1686
1734
|
"reason.central-subagent-routing": "Alpha.4 没有全局子代理启动路由接口。",
|
|
1687
1735
|
"reason.packaged-preset-roots": "Alpha.4 不支持插件提供额外 preset root。",
|
|
1688
1736
|
"reason.tool-owner-suppression": "Alpha.4 没有工具所有者或来源抑制接口。",
|
|
@@ -1730,9 +1778,10 @@ window.__ModuleLoader__.load({
|
|
|
1730
1778
|
autoReviewFollow: "Follows the session model",
|
|
1731
1779
|
autoReviewHelp: "Pin the reviewer model for the official auto-review gate (per-call review under the Auto permission preset). Requires the official auto-review bundle. When off, reviews follow the session model.",
|
|
1732
1780
|
autoReviewRouteHelp: "Review requests use exactly this provider/model regardless of the session model; saved changes apply to the very next review.",
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1781
|
+
compaction: "Compaction model",
|
|
1782
|
+
compactionFollow: "Follows the conversation model",
|
|
1783
|
+
compactionHelp: "Pick the summarization model for official compaction (/compact and official automatic compaction). When off (both fields empty), the official default applies: the conversation target model.",
|
|
1784
|
+
compactionRouteHelp: "Summarization requests use exactly this provider/model regardless of the conversation target; saved changes apply to the very next compaction. Saving while a compaction is running may interrupt it; it retries next time.",
|
|
1736
1785
|
"reason.central-subagent-routing": "Alpha.4 exposes no global Subagent start-routing seam.",
|
|
1737
1786
|
"reason.packaged-preset-roots": "Alpha.4 exposes no plugin-owned preset root.",
|
|
1738
1787
|
"reason.tool-owner-suppression": "Alpha.4 exposes no tool owner or provenance suppression seam.",
|
|
@@ -1826,14 +1875,6 @@ window.__ModuleLoader__.load({
|
|
|
1826
1875
|
return false;
|
|
1827
1876
|
}
|
|
1828
1877
|
}
|
|
1829
|
-
//#endregion
|
|
1830
|
-
//#region src/picker/plan-compact.ts
|
|
1831
|
-
/** Runtime guard for the wire value returned by the Host RPC. */
|
|
1832
|
-
function isPlanCompactOutcome(value) {
|
|
1833
|
-
if (value === null || typeof value !== "object") return false;
|
|
1834
|
-
const status = value.status;
|
|
1835
|
-
return status === "disabled" || status === "skipped" || status === "compacted" || status === "empty" || status === "error";
|
|
1836
|
-
}
|
|
1837
1878
|
const CONTEXT_SUFFIX = /-(\d+)(k|m)$/iu;
|
|
1838
1879
|
/** Peel Fast and `-<n>k` / `-<n>m` in either order. Product names like `-max` stay. */
|
|
1839
1880
|
function parsePickerId(id) {
|
|
@@ -3119,7 +3160,7 @@ window.__ModuleLoader__.load({
|
|
|
3119
3160
|
};
|
|
3120
3161
|
}
|
|
3121
3162
|
//#endregion
|
|
3122
|
-
//#region node_modules/.pnpm/dsh-llm-providers-ui@https+
|
|
3163
|
+
//#region node_modules/.pnpm/dsh-llm-providers-ui@https+++github.com+NOirBRight+dsh-llm-providers-ui+releases+downlo_f1dadb1b56406564fc1bb8f2d953b82d/node_modules/dsh-llm-providers-ui/lib/order.js
|
|
3123
3164
|
/** Display order for installed provider cards when the user has not saved one. */
|
|
3124
3165
|
const PROVIDER_ITEM_ORDER = [
|
|
3125
3166
|
"llm-cursor",
|
|
@@ -3407,7 +3448,28 @@ window.__ModuleLoader__.load({
|
|
|
3407
3448
|
};
|
|
3408
3449
|
}
|
|
3409
3450
|
/**
|
|
3410
|
-
*
|
|
3451
|
+
* Address the plan document exactly as the official opener does.
|
|
3452
|
+
*
|
|
3453
|
+
* A logged plan (`callId` present) resolves from `dsh-resource://plan/...`
|
|
3454
|
+
* for as long as the session log holds the call; before that the pending
|
|
3455
|
+
* review's own `dsh-resource://plan-review/...` address is the one that
|
|
3456
|
+
* opens its preview.
|
|
3457
|
+
*
|
|
3458
|
+
* @param sessionId - the session that owns the review.
|
|
3459
|
+
* @param ref - logged call identity plus the pending request key.
|
|
3460
|
+
* @returns The plan resource address.
|
|
3461
|
+
*/
|
|
3462
|
+
function planDocumentAddress(sessionId, ref) {
|
|
3463
|
+
const encode = encodeURIComponent;
|
|
3464
|
+
return ref.callId === void 0 ? `dsh-resource://plan-review/${encode(sessionId)}/${encode(ref.requestKey)}` : `dsh-resource://plan/${encode(sessionId)}/${encode(ref.callId)}`;
|
|
3465
|
+
}
|
|
3466
|
+
/**
|
|
3467
|
+
* Make this plan the session's armed goal, replacing any unfinished goal.
|
|
3468
|
+
*
|
|
3469
|
+
* The objective is a short instruction carrying the plan document's address,
|
|
3470
|
+
* not the plan's raw markdown: goal objectives are injected into every round,
|
|
3471
|
+
* and a full plan would be truncated by length limits mid-sentence. The round
|
|
3472
|
+
* driver reads the plan from the address instead.
|
|
3411
3473
|
*
|
|
3412
3474
|
* Ordering mirrors the card's own commit-then-answer rule: a refusal here keeps
|
|
3413
3475
|
* the Plan pending instead of approving work that no goal tracks. The replace
|
|
@@ -3416,17 +3478,18 @@ window.__ModuleLoader__.load({
|
|
|
3416
3478
|
*
|
|
3417
3479
|
* @param remote - the released goal remote, absent when no goal package is mounted.
|
|
3418
3480
|
* @param sessionId - the session that owns both the review and the goal.
|
|
3419
|
-
* @param plan - the plan markdown under review.
|
|
3481
|
+
* @param plan - the plan markdown under review (validated non-empty).
|
|
3482
|
+
* @param ref - the plan document identity used for its address.
|
|
3420
3483
|
* @returns Whether the goal now tracks this plan, or why it does not.
|
|
3421
3484
|
*/
|
|
3422
|
-
async function setPlanAsGoal(remote, sessionId, plan) {
|
|
3485
|
+
async function setPlanAsGoal(remote, sessionId, plan, ref) {
|
|
3423
3486
|
if (remote === void 0) return { kind: "unsupported" };
|
|
3424
|
-
|
|
3425
|
-
if (objective === "") return {
|
|
3487
|
+
if (plan.trim() === "") return {
|
|
3426
3488
|
kind: "failed",
|
|
3427
3489
|
code: "GOAL_INVALID_OBJECTIVE",
|
|
3428
3490
|
message: "goal objective must be a non-empty string"
|
|
3429
3491
|
};
|
|
3492
|
+
const objective = `持续推进当前plan直到完成(plan 文档:${planDocumentAddress(sessionId, ref)})`;
|
|
3430
3493
|
const created = await remote.create(sessionId, { objective });
|
|
3431
3494
|
if (created.ok) return { kind: "created" };
|
|
3432
3495
|
if (created.error.code !== "GOAL_ALREADY_EXISTS") return {
|
|
@@ -3624,12 +3687,11 @@ window.__ModuleLoader__.load({
|
|
|
3624
3687
|
t: props.t,
|
|
3625
3688
|
goalRemote: props.goalRemote,
|
|
3626
3689
|
planPreview: props.planPreview,
|
|
3627
|
-
...props.planCompact === void 0 ? {} : { planCompact: props.planCompact },
|
|
3628
3690
|
...props.resolveInteractionOperations === void 0 ? {} : { resolveInteractionOperations: props.resolveInteractionOperations },
|
|
3629
3691
|
...props.roleOf === void 0 ? {} : { roleOf: props.roleOf }
|
|
3630
3692
|
}, props.matched.key);
|
|
3631
3693
|
}
|
|
3632
|
-
function PlanReviewState({ matched, review, available, providerLock, agentLocked, lockFailed, settingsUnavailableReason, directory, t, goalRemote, planPreview,
|
|
3694
|
+
function PlanReviewState({ matched, review, available, providerLock, agentLocked, lockFailed, settingsUnavailableReason, directory, t, goalRemote, planPreview, resolveInteractionOperations, roleOf }) {
|
|
3633
3695
|
const { snapshot, getDirectorySnapshot, load, select } = directory;
|
|
3634
3696
|
const [execution, setExecution] = (0, react.useState)(snapshot.current ?? void 0);
|
|
3635
3697
|
const [feedback, setFeedback] = (0, react.useState)("");
|
|
@@ -3715,36 +3777,9 @@ window.__ModuleLoader__.load({
|
|
|
3715
3777
|
throw new Error(message === null ? t("plan.modelFailed") : t("error.action", { message }));
|
|
3716
3778
|
}
|
|
3717
3779
|
};
|
|
3718
|
-
/**
|
|
3719
|
-
* Compact the history before a switched approval commits anything.
|
|
3720
|
-
*
|
|
3721
|
-
* Only an approval that changes provider/model triggers the Host check —
|
|
3722
|
-
* effort-only changes and same-model approvals execute untouched. A failed
|
|
3723
|
-
* compaction keeps the Plan pending and retryable; `empty` announces that
|
|
3724
|
-
* nothing safe could be reduced and execution proceeds.
|
|
3725
|
-
*/
|
|
3726
|
-
const compactBeforeRun = async () => {
|
|
3727
|
-
if (execution === void 0) return;
|
|
3728
|
-
const current = snapshot.current;
|
|
3729
|
-
if (!(current === null || current === void 0 || current.provider !== execution.provider || current.model !== execution.model)) return;
|
|
3730
|
-
if (planCompact === void 0) {
|
|
3731
|
-
console.warn("dsh-model-switch: plan compaction seam absent; executing the switched Plan without it");
|
|
3732
|
-
return;
|
|
3733
|
-
}
|
|
3734
|
-
setNotice(t("plan.compacting", { model: execution.model }));
|
|
3735
|
-
let outcome;
|
|
3736
|
-
try {
|
|
3737
|
-
outcome = await planCompact(matched.sessionId, execution.provider, execution.model);
|
|
3738
|
-
} catch (cause) {
|
|
3739
|
-
throw new Error(t("plan.compactFailed", { message: cause instanceof Error ? cause.message : String(cause) }));
|
|
3740
|
-
}
|
|
3741
|
-
if (outcome.status === "error") throw new Error(t("plan.compactFailed", { message: outcome.message ?? "unknown failure" }));
|
|
3742
|
-
setNotice(outcome.status === "empty" ? t("plan.compactEmpty") : outcome.status === "compacted" ? t("plan.compacted") : null);
|
|
3743
|
-
};
|
|
3744
3780
|
const onApprove = () => {
|
|
3745
3781
|
if (execution === void 0 || !executionAllowed || !available || busy || blocked) return;
|
|
3746
3782
|
settle(async () => {
|
|
3747
|
-
await compactBeforeRun();
|
|
3748
3783
|
await approveWith(execution);
|
|
3749
3784
|
});
|
|
3750
3785
|
};
|
|
@@ -3759,8 +3794,10 @@ window.__ModuleLoader__.load({
|
|
|
3759
3794
|
const onRunAsGoal = () => {
|
|
3760
3795
|
if (execution === void 0 || !executionAllowed || !available || busy || blocked || goal === void 0) return;
|
|
3761
3796
|
settle(async () => {
|
|
3762
|
-
await
|
|
3763
|
-
|
|
3797
|
+
const handoff = await setPlanAsGoal(goal, matched.sessionId, review.plan, {
|
|
3798
|
+
...review.callId === void 0 ? {} : { callId: review.callId },
|
|
3799
|
+
requestKey: matched.key
|
|
3800
|
+
});
|
|
3764
3801
|
if (handoff.kind === "unsupported") throw new Error(t("plan.goalUnsupported"));
|
|
3765
3802
|
if (handoff.kind === "failed") {
|
|
3766
3803
|
const message = handoff.code === void 0 ? handoff.message : `${handoff.code}: ${handoff.message}`;
|
|
@@ -3998,10 +4035,6 @@ window.__ModuleLoader__.load({
|
|
|
3998
4035
|
"plan.goalUnsupported": "当前部署未挂载 goal 服务,无法把计划设为目标",
|
|
3999
4036
|
"plan.responseRejected": "计划答复已被另一客户端处理;已提交的模型切换无法由插件回滚。",
|
|
4000
4037
|
"plan.cancelRejected": "计划审查已被另一客户端处理,无法返回讨论。",
|
|
4001
|
-
"plan.compacting": "正在压缩上下文,将使用 {model}…",
|
|
4002
|
-
"plan.compacted": "上下文已压缩,开始执行。",
|
|
4003
|
-
"plan.compactEmpty": "没有可压缩的历史,继续执行。",
|
|
4004
|
-
"plan.compactFailed": "压缩上下文失败:{message}(计划仍待批准,可重试)",
|
|
4005
4038
|
"markdown.copy": "复制代码",
|
|
4006
4039
|
"markdown.copied": "已复制",
|
|
4007
4040
|
"markdown.footnotes": "脚注"
|
|
@@ -4058,10 +4091,6 @@ window.__ModuleLoader__.load({
|
|
|
4058
4091
|
"plan.goalUnsupported": "This deployment mounts no goal service, so the Plan cannot be set as a goal",
|
|
4059
4092
|
"plan.responseRejected": "Another client already handled this Plan response. A committed model change cannot be rolled back by this plugin.",
|
|
4060
4093
|
"plan.cancelRejected": "Another client already handled this Plan review, so it cannot return to discussion.",
|
|
4061
|
-
"plan.compacting": "Compacting context with {model}…",
|
|
4062
|
-
"plan.compacted": "Context compacted; starting execution.",
|
|
4063
|
-
"plan.compactEmpty": "No compactable history; continuing.",
|
|
4064
|
-
"plan.compactFailed": "Context compaction failed: {message} (the Plan stays pending and can be retried)",
|
|
4065
4094
|
"markdown.copy": "Copy code",
|
|
4066
4095
|
"markdown.copied": "Copied",
|
|
4067
4096
|
"markdown.footnotes": "Footnotes"
|
|
@@ -4084,45 +4113,6 @@ window.__ModuleLoader__.load({
|
|
|
4084
4113
|
}
|
|
4085
4114
|
const EMPTY_ORDER = [];
|
|
4086
4115
|
/**
|
|
4087
|
-
* Ask the Host to compact this session before a switched approval executes.
|
|
4088
|
-
*
|
|
4089
|
-
* An absent connection degrades to `skipped` (with a console note): the
|
|
4090
|
-
* mechanism protects against long-context timeouts, it must not brick plan
|
|
4091
|
-
* approvals in environments that expose no Host RPC at all.
|
|
4092
|
-
* @param rpcOf - resolves the live connection RPC.
|
|
4093
|
-
* @returns The card-facing runner bound to this seat's connection.
|
|
4094
|
-
*/
|
|
4095
|
-
function planCompactFrom(rpcOf) {
|
|
4096
|
-
return async (sessionId, provider, model) => {
|
|
4097
|
-
const rpc = rpcOf();
|
|
4098
|
-
if (rpc === void 0) {
|
|
4099
|
-
console.warn("dsh-model-switch: Host RPC unavailable; executing the Plan without a compaction check");
|
|
4100
|
-
return { status: "skipped" };
|
|
4101
|
-
}
|
|
4102
|
-
try {
|
|
4103
|
-
const response = await callPluginRpc(rpc, "plugin-rpc/model-switch", "plan-compact", {
|
|
4104
|
-
sessionId,
|
|
4105
|
-
provider,
|
|
4106
|
-
model
|
|
4107
|
-
});
|
|
4108
|
-
if (!response.ok) return {
|
|
4109
|
-
status: "error",
|
|
4110
|
-
message: "the Host rejected the plan compaction request"
|
|
4111
|
-
};
|
|
4112
|
-
if (!isPlanCompactOutcome(response.value)) return {
|
|
4113
|
-
status: "error",
|
|
4114
|
-
message: "the Host returned an unreadable plan compaction verdict"
|
|
4115
|
-
};
|
|
4116
|
-
return response.value;
|
|
4117
|
-
} catch (cause) {
|
|
4118
|
-
return {
|
|
4119
|
-
status: "error",
|
|
4120
|
-
message: cause instanceof Error ? cause.message : String(cause)
|
|
4121
|
-
};
|
|
4122
|
-
}
|
|
4123
|
-
};
|
|
4124
|
-
}
|
|
4125
|
-
/**
|
|
4126
4116
|
* Resolve the released goal remote without hard-depending on it.
|
|
4127
4117
|
*
|
|
4128
4118
|
* `remote.goals` exists only when the deployment mounts `@deepseek-ai/dsh-goal`,
|
|
@@ -4282,7 +4272,6 @@ window.__ModuleLoader__.load({
|
|
|
4282
4272
|
getMainDefaultsSnapshot: () => mainDefaults.getSnapshot(),
|
|
4283
4273
|
goalRemote: () => goalRemoteFrom(scope),
|
|
4284
4274
|
planPreview,
|
|
4285
|
-
planCompact: planCompactFrom(rpcOf),
|
|
4286
4275
|
hooks: {
|
|
4287
4276
|
directory: directory.store,
|
|
4288
4277
|
providerOrder: orderStore
|
|
@@ -4425,6 +4414,7 @@ window.__ModuleLoader__.load({
|
|
|
4425
4414
|
const search = deriveConfigForm(owned, deriveSearchSettings, SEARCH_SETTINGS_FIELDS);
|
|
4426
4415
|
const image = deriveConfigForm(owned, deriveImageSettings, IMAGE_SETTINGS_FIELDS);
|
|
4427
4416
|
const autoReview = deriveConfigForm(owned, deriveAutoReviewSettings, AUTO_REVIEW_SETTINGS_FIELDS);
|
|
4417
|
+
const compaction = deriveConfigForm(owned, deriveCompactionSettings, COMPACTION_SETTINGS_FIELDS);
|
|
4428
4418
|
const saveMain = async (next, expectedRevision) => {
|
|
4429
4419
|
if (!await mainForm.mutate([
|
|
4430
4420
|
{
|
|
@@ -4490,22 +4480,19 @@ window.__ModuleLoader__.load({
|
|
|
4490
4480
|
searchSettings: search,
|
|
4491
4481
|
imageSettings: image,
|
|
4492
4482
|
autoReviewSettings: autoReview,
|
|
4483
|
+
compactionSettings: compaction,
|
|
4493
4484
|
switchSettings: owned
|
|
4494
4485
|
},
|
|
4495
4486
|
capabilities: RUNTIME_CAPABILITIES,
|
|
4496
4487
|
saveMain,
|
|
4497
4488
|
setSubagent: (field, value) => value === void 0 ? subagent.unset(field) : subagent.set(field, value),
|
|
4498
4489
|
setCapability: (route, field, value) => {
|
|
4499
|
-
const scope = route === "search" ? search : route === "image" ? image : autoReview;
|
|
4490
|
+
const scope = route === "search" ? search : route === "image" ? image : route === "compaction" ? compaction : autoReview;
|
|
4500
4491
|
return value === void 0 ? scope.unset(field) : scope.set(field, value);
|
|
4501
4492
|
},
|
|
4502
4493
|
setCompactOnSwitch: async (value) => {
|
|
4503
4494
|
if (!await owned.set("compactOnSwitch", value)) throw new Error("settings-rejected");
|
|
4504
4495
|
},
|
|
4505
|
-
setPlanCompactThreshold: async (value) => {
|
|
4506
|
-
if (!Number.isInteger(value) || value < 0) throw new Error("settings-rejected");
|
|
4507
|
-
if (!await owned.set("planCompactThreshold", value)) throw new Error("settings-rejected");
|
|
4508
|
-
},
|
|
4509
4496
|
providerRoleOf,
|
|
4510
4497
|
loadCatalog: async () => {
|
|
4511
4498
|
const response = await remote.session.modelCatalog();
|