@matamt-dbg/dsh-studio 0.2.2 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -4
- package/client.js +281 -174
- package/index.js +193 -60
- package/package.json +1 -1
- package/policy.js +135 -12
- package/roles.js +25 -3
package/client.js
CHANGED
|
@@ -93,6 +93,8 @@ function parsePreviewRequest(value) {
|
|
|
93
93
|
if (row.providerConfigs !== void 0 && (!record2(row.providerConfigs) || Object.values(row.providerConfigs).some((v) => !record2(v)))) throw new Error("Invalid provider configs");
|
|
94
94
|
if (row.configOverrides !== void 0) validateConfigOverrides(row.configOverrides);
|
|
95
95
|
if (row.execution !== void 0) validateExecutionDefaults(row.execution);
|
|
96
|
+
const filter = row.subagentToolFilter;
|
|
97
|
+
if (filter !== void 0 && (!record2(filter) || !strings(filter.deny) || filter.deny.some((name) => !name))) throw new Error("Invalid subagent tool filter");
|
|
96
98
|
return {
|
|
97
99
|
...row.configOverrides !== void 0 ? { configOverrides: row.configOverrides } : {},
|
|
98
100
|
...row.execution !== void 0 ? { execution: row.execution } : {},
|
|
@@ -104,7 +106,8 @@ function parsePreviewRequest(value) {
|
|
|
104
106
|
...row.persona !== void 0 ? { persona: row.persona } : {},
|
|
105
107
|
...row.sections !== void 0 ? { sections: row.sections } : {},
|
|
106
108
|
...row.toolOverrides !== void 0 ? { toolOverrides: row.toolOverrides } : {},
|
|
107
|
-
...row.providerConfigs !== void 0 ? { providerConfigs: row.providerConfigs } : {}
|
|
109
|
+
...row.providerConfigs !== void 0 ? { providerConfigs: row.providerConfigs } : {},
|
|
110
|
+
...filter !== void 0 && filter.deny.length ? { subagentToolFilter: { deny: [...new Set(filter.deny)] } } : {}
|
|
108
111
|
};
|
|
109
112
|
}
|
|
110
113
|
|
|
@@ -733,15 +736,76 @@ function DetailDialog({ open, title, subtitle, onClose, closeLabel, footer, wide
|
|
|
733
736
|
}
|
|
734
737
|
|
|
735
738
|
// src/role-editor.tsx
|
|
739
|
+
var import_react3 = __toESM(require("react"), 1);
|
|
740
|
+
|
|
741
|
+
// src/item-picker.tsx
|
|
736
742
|
var import_react2 = __toESM(require("react"), 1);
|
|
737
743
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
738
|
-
function
|
|
744
|
+
function ItemPicker({ label, items, selected, onChange, labels, renderDetails, isModified, hasDetails }) {
|
|
745
|
+
const [query, setQuery] = import_react2.default.useState("");
|
|
746
|
+
const [filter, setFilter] = import_react2.default.useState("all");
|
|
747
|
+
const [detail, setDetail] = import_react2.default.useState();
|
|
748
|
+
const chosen = new Set(selected);
|
|
749
|
+
const isOn = (item) => item.lockedReason !== void 0 || chosen.has(item.name);
|
|
750
|
+
const modified = (name) => chosen.has(name) && (isModified?.(name) ?? false);
|
|
751
|
+
const text = query.trim().toLowerCase();
|
|
752
|
+
const visible = items.filter((item) => (filter === "all" || (filter === "selected" ? isOn(item) : modified(item.name))) && (!text || `${item.name}
|
|
753
|
+
${item.title ?? ""}
|
|
754
|
+
${item.description}
|
|
755
|
+
${item.searchText ?? ""}`.toLowerCase().includes(text)));
|
|
756
|
+
const counts = { all: items.length, selected: items.filter(isOn).length, modified: items.filter((item) => modified(item.name)).length };
|
|
757
|
+
const toggle = (name) => onChange(chosen.has(name) ? selected.filter((value) => value !== name) : [...selected, name]);
|
|
758
|
+
const open = items.find((item) => item.name === detail && chosen.has(item.name));
|
|
759
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "studio-picker", children: [
|
|
760
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "studio-picker-bar", children: [
|
|
761
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { type: "search", "aria-label": labels.search, placeholder: labels.searchHint, value: query, onChange: (event) => setQuery(event.target.value) }),
|
|
762
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "studio-picker-filters", role: "radiogroup", "aria-label": labels.filter, children: ["all", "selected", "modified"].map((value) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", role: "radio", "aria-checked": filter === value, className: "studio-picker-filter", onClick: () => setFilter(value), children: [
|
|
763
|
+
labels[value],
|
|
764
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "studio-count", children: counts[value] })
|
|
765
|
+
] }, value)) })
|
|
766
|
+
] }),
|
|
767
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("ul", { className: "studio-picker-list", "aria-label": label, children: [
|
|
768
|
+
visible.map((item) => {
|
|
769
|
+
const locked = item.lockedReason !== void 0;
|
|
770
|
+
const on = locked || chosen.has(item.name);
|
|
771
|
+
const blocked = locked || !on && item.disabledReason !== void 0;
|
|
772
|
+
const details = on && renderDetails !== void 0 && (hasDetails?.(item.name) ?? true);
|
|
773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("li", { className: "studio-picker-row", "data-selected": on, children: [
|
|
774
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", role: "switch", "aria-checked": on, disabled: blocked, className: "studio-picker-toggle", "aria-label": `${item.title ?? item.name}`, onClick: () => toggle(item.name), children: [
|
|
775
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "studio-picker-check", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 16 16", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M3.5 8.5l3 3 6-7", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
|
|
776
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "studio-picker-text", children: [
|
|
777
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "studio-picker-title", children: [
|
|
778
|
+
item.title ?? item.name,
|
|
779
|
+
item.subtitle && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "studio-picker-subtitle studio-mono", children: item.subtitle })
|
|
780
|
+
] }),
|
|
781
|
+
(locked ? item.lockedReason : item.disabledReason && !on ? item.disabledReason : item.description) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "studio-picker-description", children: locked ? item.lockedReason : item.disabledReason && !on ? item.disabledReason : item.description })
|
|
782
|
+
] })
|
|
783
|
+
] }),
|
|
784
|
+
modified(item.name) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "studio-badge", "data-tone": "info", "data-studio-modified": "true", children: labels.modifiedTag }),
|
|
785
|
+
details && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Button, { small: true, "aria-label": `${labels.settings}: ${item.name}`, "aria-haspopup": "dialog", onClick: () => setDetail(item.name), children: labels.settings })
|
|
786
|
+
] }, item.name);
|
|
787
|
+
}),
|
|
788
|
+
!visible.length && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("li", { className: "studio-picker-empty", role: "status", children: [
|
|
789
|
+
text ? labels.noResults : labels.empty,
|
|
790
|
+
(text || filter !== "all") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Button, { small: true, onClick: () => {
|
|
791
|
+
setQuery("");
|
|
792
|
+
setFilter("all");
|
|
793
|
+
}, children: labels.clear })
|
|
794
|
+
] })
|
|
795
|
+
] }),
|
|
796
|
+
renderDetails && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DetailDialog, { open: open !== void 0, title: open?.title ?? open?.name, subtitle: open?.subtitle, closeLabel: labels.done, onClose: () => setDetail(void 0), children: open && renderDetails(open.name) })
|
|
797
|
+
] });
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// src/role-editor.tsx
|
|
801
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
802
|
+
function RoleEditor({ locale, roles, onChange, loadModels, defaultPersona = "", tools, hiddenTools = [], onHiddenToolsChange, delegates = true }) {
|
|
739
803
|
const t = (ko2, en2, zh2) => locale.startsWith("ko") ? ko2 : locale.startsWith("zh") ? zh2 : en2;
|
|
740
|
-
const [selected, setSelected] =
|
|
741
|
-
const [catalog, setCatalog] =
|
|
742
|
-
const [error, setError] =
|
|
743
|
-
const [loading, setLoading] =
|
|
744
|
-
const refresh =
|
|
804
|
+
const [selected, setSelected] = import_react3.default.useState();
|
|
805
|
+
const [catalog, setCatalog] = import_react3.default.useState();
|
|
806
|
+
const [error, setError] = import_react3.default.useState("");
|
|
807
|
+
const [loading, setLoading] = import_react3.default.useState(false);
|
|
808
|
+
const refresh = import_react3.default.useCallback(async () => {
|
|
745
809
|
if (!loadModels) return;
|
|
746
810
|
setLoading(true);
|
|
747
811
|
setError("");
|
|
@@ -753,120 +817,179 @@ function RoleEditor({ locale, roles, onChange, loadModels, defaultPersona = "" }
|
|
|
753
817
|
setLoading(false);
|
|
754
818
|
}
|
|
755
819
|
}, [loadModels]);
|
|
756
|
-
|
|
820
|
+
import_react3.default.useEffect(() => {
|
|
757
821
|
void refresh();
|
|
758
822
|
}, [refresh]);
|
|
759
823
|
const models = (catalog?.groups ?? []).flatMap((group) => group.models.map((model2) => ({ ...model2, value: `${group.id}/${model2.id}`, label: `${group.name} \xB7 ${model2.name}` })));
|
|
760
824
|
const role = selected === void 0 ? void 0 : roles[selected];
|
|
761
825
|
const model = models.find((model2) => model2.value === role?.model);
|
|
762
|
-
const update2 = (patch) => onChange(roles.map((role2, index) =>
|
|
763
|
-
|
|
764
|
-
|
|
826
|
+
const update2 = (patch) => onChange(roles.map((role2, index) => {
|
|
827
|
+
if (index !== selected) return role2;
|
|
828
|
+
const next = { ...role2, ...patch };
|
|
829
|
+
if (next.toolFilter === void 0) delete next.toolFilter;
|
|
830
|
+
return next;
|
|
831
|
+
}));
|
|
832
|
+
const field2 = (label, content) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "studio-field", children: [
|
|
833
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: label }),
|
|
765
834
|
content
|
|
766
835
|
] });
|
|
767
836
|
const close = () => setSelected(void 0);
|
|
768
|
-
|
|
769
|
-
|
|
837
|
+
const defaultCount = hiddenTools.filter((name) => tools?.some((tool) => tool.name === name)).length;
|
|
838
|
+
const filterTitle = t("\uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8 Tool Filter", "Subagent Tool Filter", "\u5B50\u4EE3\u7406 Tool Filter");
|
|
839
|
+
const roleFilterLabel = t("\uC774 \uC5ED\uD560\uC758 Tool Filter", "Tool Filter for this role", "\u6B64\u89D2\u8272\u7684 Tool Filter");
|
|
840
|
+
const filterSummary = (item) => {
|
|
841
|
+
const own2 = item.toolFilter?.deny.filter((name) => tools?.some((tool) => tool.name === name) && !(item.toolFilter?.mode === "extend" && hiddenTools.includes(name))).length ?? 0;
|
|
842
|
+
return !item.toolFilter ? t("\uAE30\uBCF8\uAC12", "default", "\u9ED8\u8BA4") : item.toolFilter.mode === "extend" ? t(`\uAE30\uBCF8\uAC12 + ${own2}`, `default + ${own2}`, `\u9ED8\u8BA4 + ${own2}`) : t(`\uB530\uB85C ${own2}`, `own ${own2}`, `\u5355\u72EC ${own2}`);
|
|
843
|
+
};
|
|
844
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
845
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SectionHead, { title: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("h3", { className: "studio-panel-title", children: [
|
|
770
846
|
t("\uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8", "Subagents", "\u5B50\u4EE3\u7406"),
|
|
771
|
-
/* @__PURE__ */ (0,
|
|
772
|
-
] }), description: t("\uBC14\uAFBC \uB0B4\uC6A9\uC740 \uD504\uB9AC\uC14B\uC744 \uC800\uC7A5\uD558\uACE0 DSH\uC5D0 \uB2E4\uC2DC \uBC18\uC601\uD574\uC57C \uC801\uC6A9\uB429\uB2C8\uB2E4.", "Save the preset and reapply it to DSH after changes.", "\u4FEE\u6539\u540E\u9700\u4FDD\u5B58\u9884\u8BBE\u5E76\u91CD\u65B0\u5E94\u7528\u5230 DSH\u3002"), actions: /* @__PURE__ */ (0,
|
|
773
|
-
/* @__PURE__ */ (0,
|
|
774
|
-
/* @__PURE__ */ (0,
|
|
847
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "studio-count", children: roles.length })
|
|
848
|
+
] }), description: t("\uBC14\uAFBC \uB0B4\uC6A9\uC740 \uD504\uB9AC\uC14B\uC744 \uC800\uC7A5\uD558\uACE0 DSH\uC5D0 \uB2E4\uC2DC \uBC18\uC601\uD574\uC57C \uC801\uC6A9\uB429\uB2C8\uB2E4.", "Save the preset and reapply it to DSH after changes.", "\u4FEE\u6539\u540E\u9700\u4FDD\u5B58\u9884\u8BBE\u5E76\u91CD\u65B0\u5E94\u7528\u5230 DSH\u3002"), actions: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
849
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { small: true, disabled: loading || !loadModels, onClick: () => void refresh(), children: loading ? t("\uBAA8\uB378 \uBD88\uB7EC\uC624\uB294 \uC911\u2026", "Loading models\u2026", "\u6B63\u5728\u52A0\u8F7D\u6A21\u578B\u2026") : t("\uBAA8\uB378 \uBAA9\uB85D \uC0C8\uB85C\uACE0\uCE68", "Refresh models", "\u5237\u65B0\u6A21\u578B\u5217\u8868") }),
|
|
850
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { small: true, onClick: () => {
|
|
775
851
|
setSelected(roles.length);
|
|
776
852
|
onChange([...roles, { name: "", role: "", model: "inherit", reasoning: "inherit", spawn: "fresh", persona: "" }]);
|
|
777
853
|
}, children: t("\uC5ED\uD560 \uCD94\uAC00", "Add role", "\u6DFB\u52A0\u89D2\u8272") })
|
|
778
854
|
] }) }),
|
|
779
|
-
error && /* @__PURE__ */ (0,
|
|
780
|
-
catalog?.failures.map((failure) => /* @__PURE__ */ (0,
|
|
855
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Note, { children: error }),
|
|
856
|
+
catalog?.failures.map((failure) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Note, { children: [
|
|
781
857
|
failure.name,
|
|
782
858
|
": ",
|
|
783
859
|
failure.message
|
|
784
860
|
] }, failure.name)),
|
|
785
|
-
/* @__PURE__ */ (0,
|
|
861
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Note, { children: t(
|
|
786
862
|
"DSH\uC758 \uAE30\uBCF8 \uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8 \uB3C4\uAD6C(subagent, subagent_fork, list_subagent_models)\uB97C subagent_role \uD558\uB098\uB85C \uD1B5\uD569\uD574 \uC81C\uACF5\uD569\uB2C8\uB2E4. \uAE30\uBCF8 \uB3C4\uAD6C\uB294 \uC790\uB3D9\uC73C\uB85C \uBE60\uC9C0\uACE0, subagent_role\uC758 \uC124\uBA85\uACFC \uC778\uC790\uB294 \uD504\uB86C\uD504\uD2B8\xB7\uB3C4\uAD6C \uD0ED\uC758 \uB3C4\uAD6C \uBAA9\uB85D\uC5D0\uC11C \uD655\uC778\uD558\uACE0 \uC218\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
787
|
-
"Studio
|
|
863
|
+
"Studio replaces the DSH default subagent tools (subagent, subagent_fork, list_subagent_models) with a single subagent_role tool. The default tools are removed automatically; review or edit subagent_role in the tool list on the Prompts & tools tab.",
|
|
788
864
|
"\u5C06 DSH \u9ED8\u8BA4\u5B50\u4EE3\u7406\u5DE5\u5177\uFF08subagent\u3001subagent_fork\u3001list_subagent_models\uFF09\u5408\u5E76\u4E3A\u4E00\u4E2A subagent_role \u5DE5\u5177\u63D0\u4F9B\u3002\u9ED8\u8BA4\u5DE5\u5177\u4F1A\u88AB\u81EA\u52A8\u79FB\u9664\uFF1B\u53EF\u5728\u201C\u63D0\u793A\u8BCD\u4E0E\u5DE5\u5177\u201D\u9875\u7684\u5DE5\u5177\u5217\u8868\u4E2D\u67E5\u770B\u6216\u7F16\u8F91 subagent_role\u3002"
|
|
789
865
|
) }),
|
|
790
|
-
!roles.length && /* @__PURE__ */ (0,
|
|
791
|
-
/* @__PURE__ */ (0,
|
|
792
|
-
/* @__PURE__ */ (0,
|
|
793
|
-
/* @__PURE__ */ (0,
|
|
794
|
-
/* @__PURE__ */ (0,
|
|
866
|
+
!roles.length && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "studio-muted", role: "status", children: t("\uC815\uC758\uB41C \uC5ED\uD560\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC774 \uC0C1\uD0DC\uC5D0\uC11C\uB294 subagent_role\uC774 \uBD80\uBAA8\uC640 \uAC19\uC740 \uBAA8\uB378\xB7\uCD94\uB860\xB7\uC9C0\uCE68\uC73C\uB85C \uC0C8 \uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4.", "No roles defined. subagent_role then starts a new subagent with the same model, reasoning and instructions as the parent.", "\u5C1A\u672A\u5B9A\u4E49\u89D2\u8272\u3002\u6B64\u65F6 subagent_role \u4F1A\u4EE5\u4E0E\u7236\u4EE3\u7406\u76F8\u540C\u7684\u6A21\u578B\u3001\u63A8\u7406\u548C\u6307\u4EE4\u542F\u52A8\u65B0\u7684\u5B50\u4EE3\u7406\u3002") }),
|
|
867
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "studio-tool-cards studio-card-pair", children: roles.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("article", { className: "studio-role-card", children: [
|
|
868
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "studio-card-head", children: [
|
|
869
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: item.name || t("\uC774\uB984 \uC5C6\uC74C", "Untitled", "\u672A\u547D\u540D") }),
|
|
870
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Badge, { tone: "outline", children: item.spawn === "fork" ? t("\uBD80\uBAA8 \uB300\uD654 \uC774\uC5B4\uBC1B\uAE30", "Continue parent", "\u7EE7\u627F\u7236\u5BF9\u8BDD") : t("\uC0C8 \uB300\uD654", "New conversation", "\u65B0\u5BF9\u8BDD") })
|
|
795
871
|
] }),
|
|
796
|
-
item.role && /* @__PURE__ */ (0,
|
|
797
|
-
/* @__PURE__ */ (0,
|
|
872
|
+
item.role && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "studio-card-text studio-mono", children: item.role }),
|
|
873
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "studio-card-meta", children: [
|
|
798
874
|
item.model === "inherit" ? t("\uBD80\uBAA8 \uBAA8\uB378 \uC0AC\uC6A9", "Inherit parent model", "\u7EE7\u627F\u7236\u7EA7\u6A21\u578B") : models.find((model2) => model2.value === item.model)?.label ?? item.model,
|
|
799
875
|
" \xB7 ",
|
|
800
876
|
t("\uCD94\uB860", "Reasoning", "\u63A8\u7406"),
|
|
801
877
|
" ",
|
|
802
|
-
item.reasoning === "inherit" ? t("\uAE30\uBCF8", "
|
|
878
|
+
item.reasoning === "inherit" ? t("\uAE30\uBCF8\uAC12", "default", "\u9ED8\u8BA4") : item.reasoning,
|
|
879
|
+
tools && delegates && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
880
|
+
" \xB7 Tool Filter: ",
|
|
881
|
+
filterSummary(item)
|
|
882
|
+
] })
|
|
803
883
|
] }),
|
|
804
|
-
/* @__PURE__ */ (0,
|
|
884
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "studio-card-footer", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { small: true, "aria-haspopup": "dialog", onClick: () => setSelected(index), children: t("\uD3B8\uC9D1", "Edit", "\u7F16\u8F91") }) })
|
|
805
885
|
] }, index)) }),
|
|
806
|
-
/* @__PURE__ */ (0,
|
|
886
|
+
tools && onHiddenToolsChange && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "studio-form-section", children: [
|
|
887
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SectionHead, { title: filterTitle, description: t("Tool Filter\uC5D0 \uB4F1\uB85D\uD55C \uB3C4\uAD6C\uB294 \uC774 \uD504\uB9AC\uC14B\uC758 \uBAA8\uB4E0 \uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8\uC5D0\uC11C \uBE60\uC9D1\uB2C8\uB2E4. \uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8\uC758 \uC2DC\uC2A4\uD15C \uD504\uB86C\uD504\uD2B8\uC5D0\uC11C \uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8\uC5D0\uAC8C \uD544\uC694 \uC5C6\uB294 \uB3C4\uAD6C\uB97C \uC81C\uAC70\uD574 \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uAC00\uBCCD\uAC8C \uC720\uC9C0\uD574 \uBCF4\uC138\uC694. \uC5ED\uD560 \uD3B8\uC9D1\uC5D0\uC11C \uC5ED\uD560\uB9C8\uB2E4 \uB530\uB85C \uC815\uD560 \uC218\uB3C4 \uC788\uC2B5\uB2C8\uB2E4.", "Tools in the Tool Filter are removed from every subagent of this preset. Remove tools a subagent does not need from its system prompt to keep its context light. Each role can also set its own list in the role editor.", "\u52A0\u5165 Tool Filter \u7684\u5DE5\u5177\u4F1A\u4ECE\u6B64\u9884\u8BBE\u7684\u6240\u6709\u5B50\u4EE3\u7406\u4E2D\u79FB\u9664\u3002\u4ECE\u5B50\u4EE3\u7406\u7684\u7CFB\u7EDF\u63D0\u793A\u4E2D\u79FB\u9664\u5176\u4E0D\u9700\u8981\u7684\u5DE5\u5177\uFF0C\u8BA9\u4E0A\u4E0B\u6587\u4FDD\u6301\u7CBE\u7B80\u3002\u4E5F\u53EF\u4EE5\u5728\u89D2\u8272\u7F16\u8F91\u4E2D\u4E3A\u6BCF\u4E2A\u89D2\u8272\u5355\u72EC\u8BBE\u7F6E\u3002") }),
|
|
888
|
+
!delegates ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Note, { children: t("\uD504\uB86C\uD504\uD2B8\xB7\uB3C4\uAD6C \uD0ED\uC5D0\uC11C subagent_role\uC744 \uC120\uD0DD\uD558\uBA74 \uC4F8 \uC218 \uC788\uC2B5\uB2C8\uB2E4.", "Select subagent_role on the Prompts & tools tab to use the Tool Filter.", "\u5728\u201C\u63D0\u793A\u8BCD\u4E0E\u5DE5\u5177\u201D\u9875\u9009\u62E9 subagent_role \u540E\u5373\u53EF\u4F7F\u7528\u3002") }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ToolFilterPicker, { label: filterTitle, tools, selected: hiddenTools, onChange: onHiddenToolsChange, t })
|
|
889
|
+
] }),
|
|
890
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
807
891
|
DetailDialog,
|
|
808
892
|
{
|
|
809
893
|
open: role !== void 0,
|
|
810
894
|
title: role?.name || t("\uC0C8 \uC5ED\uD560", "New role", "\u65B0\u89D2\u8272"),
|
|
811
895
|
subtitle: t("\uC5ED\uD560 \uD3B8\uC9D1", "Edit role", "\u7F16\u8F91\u89D2\u8272"),
|
|
812
896
|
onClose: close,
|
|
813
|
-
footer: /* @__PURE__ */ (0,
|
|
814
|
-
/* @__PURE__ */ (0,
|
|
897
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
898
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { small: true, onClick: () => {
|
|
815
899
|
onChange(roles.filter((_, index) => index !== selected));
|
|
816
900
|
close();
|
|
817
901
|
}, children: t("\uC5ED\uD560 \uC0AD\uC81C", "Remove role", "\u79FB\u9664\u89D2\u8272") }),
|
|
818
|
-
/* @__PURE__ */ (0,
|
|
902
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { small: true, primary: true, onClick: close, children: t("\uC644\uB8CC", "Done", "\u5B8C\u6210") })
|
|
819
903
|
] }),
|
|
820
|
-
children: role && /* @__PURE__ */ (0,
|
|
821
|
-
/* @__PURE__ */ (0,
|
|
822
|
-
field2(t("\uC774\uB984", "Name", "\u540D\u79F0"), /* @__PURE__ */ (0,
|
|
823
|
-
field2(t("\uC5ED\uD560 ID", "Role", "\u89D2\u8272"), /* @__PURE__ */ (0,
|
|
904
|
+
children: role && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
905
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "studio-field-grid", children: [
|
|
906
|
+
field2(t("\uC774\uB984", "Name", "\u540D\u79F0"), /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { value: role.name, onChange: (e) => update2({ name: e.target.value }) })),
|
|
907
|
+
field2(t("\uC5ED\uD560 ID", "Role ID", "\u89D2\u8272 ID"), /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { className: "studio-mono", value: role.role, onChange: (e) => update2({ role: e.target.value }) }))
|
|
824
908
|
] }),
|
|
825
|
-
/* @__PURE__ */ (0,
|
|
826
|
-
field2(t("\uBAA8\uB378", "Model", "\u6A21\u578B"), /* @__PURE__ */ (0,
|
|
827
|
-
/* @__PURE__ */ (0,
|
|
828
|
-
role.model !== "inherit" && !model && /* @__PURE__ */ (0,
|
|
909
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "studio-field-grid", children: [
|
|
910
|
+
field2(t("\uBAA8\uB378", "Model", "\u6A21\u578B"), /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("select", { value: role.model, onChange: (e) => update2({ model: e.target.value, reasoning: "inherit" }), children: [
|
|
911
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "inherit", children: t("\uBD80\uBAA8 \uBAA8\uB378 \uC0AC\uC6A9", "Inherit parent model", "\u7EE7\u627F\u7236\u7EA7\u6A21\u578B") }),
|
|
912
|
+
role.model !== "inherit" && !model && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("option", { value: role.model, disabled: true, children: [
|
|
829
913
|
role.model,
|
|
830
914
|
" \xB7 ",
|
|
831
|
-
t("\uBAA9\uB85D\uC5D0 \uC5C6\uC74C \xB7 \uBC18\uC601\uD560 \uB54C \uD655\uC778", "Not
|
|
915
|
+
t("\uBAA9\uB85D\uC5D0 \uC5C6\uC74C \xB7 \uBC18\uC601\uD560 \uB54C \uD655\uC778", "Not in list \xB7 checked on apply", "\u76EE\u5F55\u4E2D\u672A\u786E\u8BA4 \xB7 \u5E94\u7528\u65F6\u9A8C\u8BC1")
|
|
832
916
|
] }),
|
|
833
|
-
models.map((model2) => /* @__PURE__ */ (0,
|
|
917
|
+
models.map((model2) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: model2.value, children: model2.label }, model2.value))
|
|
834
918
|
] })),
|
|
835
|
-
field2(t("\uCD94\uB860 \uC218\uC900", "Reasoning", "\u63A8\u7406\u7EA7\u522B"), /* @__PURE__ */ (0,
|
|
836
|
-
/* @__PURE__ */ (0,
|
|
837
|
-
role.reasoning !== "inherit" && !model?.reasoning?.efforts.some((e) => e.id === role.reasoning) && /* @__PURE__ */ (0,
|
|
919
|
+
field2(t("\uCD94\uB860 \uC218\uC900", "Reasoning", "\u63A8\u7406\u7EA7\u522B"), /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("select", { value: role.reasoning, disabled: !model, onChange: (e) => update2({ reasoning: e.target.value }), children: [
|
|
920
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "inherit", children: role.model === "inherit" ? t("\uBD80\uBAA8 \uC124\uC815 \uC0AC\uC6A9", "Inherit parent setting", "\u7EE7\u627F\u7236\u7EA7\u8BBE\u7F6E") : t("\uBAA8\uB378 \uAE30\uBCF8\uAC12", "Model default", "\u6A21\u578B\u9ED8\u8BA4\u503C") }),
|
|
921
|
+
role.reasoning !== "inherit" && !model?.reasoning?.efforts.some((e) => e.id === role.reasoning) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("option", { value: role.reasoning, disabled: true, children: [
|
|
838
922
|
role.reasoning,
|
|
839
923
|
" \xB7 ",
|
|
840
|
-
t("\uC9C0\uC6D0 \uC5EC\uBD80 \uD655\uC778 \uD544\uC694", "
|
|
924
|
+
t("\uC9C0\uC6D0 \uC5EC\uBD80 \uD655\uC778 \uD544\uC694", "Support unconfirmed", "\u9700\u786E\u8BA4\u652F\u6301")
|
|
841
925
|
] }),
|
|
842
|
-
model?.reasoning?.efforts.map((e) => /* @__PURE__ */ (0,
|
|
926
|
+
model?.reasoning?.efforts.map((e) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: e.id, children: e.name }, e.id))
|
|
843
927
|
] })),
|
|
844
|
-
field2(t("\uC2DC\uC791 \uBC29\uC2DD", "Spawn mode", "\u751F\u6210\u65B9\u5F0F"), /* @__PURE__ */ (0,
|
|
845
|
-
/* @__PURE__ */ (0,
|
|
846
|
-
/* @__PURE__ */ (0,
|
|
928
|
+
field2(t("\uC2DC\uC791 \uBC29\uC2DD", "Spawn mode", "\u751F\u6210\u65B9\u5F0F"), /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("select", { value: role.spawn, onChange: (e) => update2({ spawn: e.target.value }), children: [
|
|
929
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "fresh", children: t("\uC0C8 \uB300\uD654 (Fresh)", "New conversation (Fresh)", "\u65B0\u5BF9\u8BDD\uFF08Fresh\uFF09") }),
|
|
930
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "fork", children: t("\uBD80\uBAA8 \uB300\uD654 \uC774\uC5B4\uBC1B\uAE30 (Fork)", "Continue parent (Fork)", "\u7EE7\u627F\u7236\u5BF9\u8BDD\uFF08Fork\uFF09") })
|
|
847
931
|
] }))
|
|
848
932
|
] }),
|
|
849
|
-
|
|
850
|
-
|
|
933
|
+
tools && delegates && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "studio-field", children: [
|
|
934
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: filterTitle }),
|
|
935
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("select", { "aria-label": roleFilterLabel, value: role.toolFilter?.mode ?? "default", onChange: (e) => {
|
|
936
|
+
const mode = e.target.value;
|
|
937
|
+
update2({ toolFilter: mode === "extend" || mode === "replace" ? { mode, deny: [] } : void 0 });
|
|
938
|
+
}, children: [
|
|
939
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "default", children: t(`\uD504\uB9AC\uC14B \uAE30\uBCF8\uAC12 \uC0AC\uC6A9 (${defaultCount}\uAC1C)`, `Use preset default (${defaultCount})`, `\u4F7F\u7528\u9884\u8BBE\u9ED8\u8BA4\u503C\uFF08${defaultCount} \u4E2A\uFF09`) }),
|
|
940
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "extend", children: t("\uAE30\uBCF8\uAC12\uC5D0 \uCD94\uAC00", "Add to preset default", "\u5728\u9ED8\u8BA4\u503C\u57FA\u7840\u4E0A\u6DFB\u52A0") }),
|
|
941
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "replace", children: t("\uC774 \uC5ED\uD560\uB9CC \uB530\uB85C (\uAE30\uBCF8\uAC12 \uBB34\uC2DC)", "This role only (ignore default)", "\u4EC5\u6B64\u89D2\u8272\uFF08\u5FFD\u7565\u9ED8\u8BA4\u503C\uFF09") })
|
|
942
|
+
] }),
|
|
943
|
+
role.toolFilter?.mode === "extend" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "studio-muted studio-hint", children: t("\uD504\uB9AC\uC14B \uAE30\uBCF8\uAC12\uC758 \uB3C4\uAD6C\uB294 \uC7A0\uAE34 \uCC44\uB85C \uD568\uAED8 \uBE60\uC9D1\uB2C8\uB2E4. \uC774 \uC5ED\uD560\uC5D0\uC11C \uCD94\uAC00\uB85C \uBE84 \uB3C4\uAD6C\uB97C \uACE0\uB974\uC138\uC694. \uAE30\uBCF8\uAC12\uC744 \uBC14\uAFB8\uBA74 \uC774 \uC5ED\uD560\uC5D0\uB3C4 \uBC18\uC601\uB429\uB2C8\uB2E4.", "Preset default tools are locked and stay filtered. Choose the tools this role filters in addition. Changes to the default apply to this role too.", "\u9884\u8BBE\u9ED8\u8BA4\u503C\u4E2D\u7684\u5DE5\u5177\u5DF2\u9501\u5B9A\u5E76\u4E00\u5E76\u6392\u9664\u3002\u8BF7\u9009\u62E9\u6B64\u89D2\u8272\u989D\u5916\u6392\u9664\u7684\u5DE5\u5177\u3002\u9ED8\u8BA4\u503C\u7684\u66F4\u6539\u4E5F\u4F1A\u5E94\u7528\u5230\u6B64\u89D2\u8272\u3002") }),
|
|
944
|
+
role.toolFilter?.mode === "replace" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "studio-muted studio-hint", children: t("\uD504\uB9AC\uC14B \uAE30\uBCF8\uAC12\uC774 \uC774 \uC5ED\uD560\uC5D0\uB294 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC774 \uC5ED\uD560\uC5D0\uC11C \uBE84 \uB3C4\uAD6C\uB9CC \uACE0\uB974\uC138\uC694.", "The preset default does not apply to this role. Choose only the tools this role filters.", "\u9884\u8BBE\u9ED8\u8BA4\u503C\u4E0D\u9002\u7528\u4E8E\u6B64\u89D2\u8272\u3002\u8BF7\u4EC5\u9009\u62E9\u6B64\u89D2\u8272\u6392\u9664\u7684\u5DE5\u5177\u3002") }),
|
|
945
|
+
role.toolFilter && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
946
|
+
ToolFilterPicker,
|
|
947
|
+
{
|
|
948
|
+
label: roleFilterLabel,
|
|
949
|
+
tools,
|
|
950
|
+
selected: role.toolFilter.deny,
|
|
951
|
+
locked: role.toolFilter.mode === "extend" ? hiddenTools : [],
|
|
952
|
+
lockedReason: t("\uD504\uB9AC\uC14B \uAE30\uBCF8\uAC12", "Preset default", "\u9884\u8BBE\u9ED8\u8BA4\u503C"),
|
|
953
|
+
onChange: (deny) => update2({ toolFilter: { mode: role.toolFilter.mode, deny } }),
|
|
954
|
+
t
|
|
955
|
+
}
|
|
956
|
+
)
|
|
957
|
+
] }),
|
|
958
|
+
field2(t("\uC5ED\uD560 \uC9C0\uCE68 (persona)", "Role instructions (persona)", "\u89D2\u8272\u6307\u4EE4\uFF08persona\uFF09"), /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("textarea", { rows: 6, value: role.persona, placeholder: defaultPersona, onChange: (e) => update2({ persona: e.target.value }) })),
|
|
959
|
+
!role.persona && defaultPersona && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "studio-muted studio-hint", children: t("\uD750\uB9B0 \uAE00\uC528\uB294 \uD504\uB9AC\uC14B\uC758 \uAE30\uBCF8 persona\uC785\uB2C8\uB2E4. \uBE44\uC6CC \uB450\uBA74 \uC774 \uB0B4\uC6A9\uC774 \uADF8\uB300\uB85C \uC4F0\uC785\uB2C8\uB2E4.", "The dimmed text is the preset default persona; it is used while this field is empty.", "\u6D45\u8272\u6587\u5B57\u662F\u9884\u8BBE\u7684\u9ED8\u8BA4 persona\uFF0C\u7559\u7A7A\u65F6\u4F7F\u7528\u8BE5\u5185\u5BB9\u3002") })
|
|
851
960
|
] })
|
|
852
961
|
}
|
|
853
962
|
)
|
|
854
963
|
] });
|
|
855
964
|
}
|
|
965
|
+
function ToolFilterPicker({ label, tools, selected, onChange, t, locked = [], lockedReason }) {
|
|
966
|
+
const items = tools.map((tool) => locked.includes(tool.name) && lockedReason ? { ...tool, lockedReason } : tool);
|
|
967
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
968
|
+
ItemPicker,
|
|
969
|
+
{
|
|
970
|
+
label,
|
|
971
|
+
items,
|
|
972
|
+
selected: selected.filter((name) => tools.some((tool) => tool.name === name) && !locked.includes(name)),
|
|
973
|
+
onChange: (names2) => onChange(names2.filter((name) => !locked.includes(name))),
|
|
974
|
+
hasDetails: () => false,
|
|
975
|
+
labels: { filter: t("\uBCF4\uAE30", "Show", "\u663E\u793A"), search: t("\uB3C4\uAD6C \uAC80\uC0C9", "Search tools", "\u641C\u7D22\u5DE5\u5177"), searchHint: t("\uC774\uB984, \uC124\uBA85\uC73C\uB85C \uAC80\uC0C9", "Search names or descriptions", "\u6309\u540D\u79F0\u6216\u63CF\u8FF0\u641C\u7D22"), all: t("\uC804\uCCB4", "All", "\u5168\u90E8"), selected: t("\uC81C\uC678\uB428", "Filtered", "\u5DF2\u6392\u9664"), modified: t("\uBCC0\uACBD\uB428", "Modified", "\u5DF2\u4FEE\u6539"), settings: t("\uC124\uC815", "Details", "\u8BBE\u7F6E"), done: t("\uC644\uB8CC", "Close", "\u5B8C\u6210"), empty: t("\uC774 \uD504\uB9AC\uC14B\uC5D0\uC11C \uC120\uD0DD\uD55C \uB3C4\uAD6C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.", "This preset selects no tools.", "\u6B64\u9884\u8BBE\u672A\u9009\u62E9\u4EFB\u4F55\u5DE5\u5177\u3002"), noResults: t("\uAC80\uC0C9 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.", "No matching results.", "\u6CA1\u6709\u5339\u914D\u7ED3\u679C\u3002"), modifiedTag: t("\uBCC0\uACBD\uB428", "Modified", "\u5DF2\u4FEE\u6539"), clear: t("\uC804\uCCB4 \uBCF4\uAE30", "Show all", "\u663E\u793A\u5168\u90E8") }
|
|
976
|
+
}
|
|
977
|
+
);
|
|
978
|
+
}
|
|
856
979
|
|
|
857
980
|
// src/optimization-prototype.tsx
|
|
858
981
|
var import_react9 = __toESM(require("react"), 1);
|
|
859
982
|
|
|
860
983
|
// src/master-extensions-editor.tsx
|
|
861
|
-
var
|
|
862
|
-
var
|
|
984
|
+
var import_react4 = __toESM(require("react"), 1);
|
|
985
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
863
986
|
function MasterExtensionsEditor({ locale, actions }) {
|
|
864
987
|
const t = (ko2, en2, zh2) => locale.startsWith("ko") ? ko2 : locale.startsWith("zh") ? zh2 : en2;
|
|
865
|
-
const [text, setText] =
|
|
866
|
-
const [error, setError] =
|
|
867
|
-
const [busy, setBusy] =
|
|
868
|
-
const [loaded, setLoaded] =
|
|
869
|
-
|
|
988
|
+
const [text, setText] = import_react4.default.useState("[]");
|
|
989
|
+
const [error, setError] = import_react4.default.useState("");
|
|
990
|
+
const [busy, setBusy] = import_react4.default.useState(false);
|
|
991
|
+
const [loaded, setLoaded] = import_react4.default.useState(false);
|
|
992
|
+
import_react4.default.useEffect(() => {
|
|
870
993
|
let active = true;
|
|
871
994
|
if (actions) actions.read().then((value) => {
|
|
872
995
|
if (active) {
|
|
@@ -880,22 +1003,22 @@ function MasterExtensionsEditor({ locale, actions }) {
|
|
|
880
1003
|
active = false;
|
|
881
1004
|
};
|
|
882
1005
|
}, [actions]);
|
|
883
|
-
return /* @__PURE__ */ (0,
|
|
884
|
-
/* @__PURE__ */ (0,
|
|
885
|
-
/* @__PURE__ */ (0,
|
|
886
|
-
/* @__PURE__ */ (0,
|
|
887
|
-
/* @__PURE__ */ (0,
|
|
888
|
-
/* @__PURE__ */ (0,
|
|
889
|
-
/* @__PURE__ */ (0,
|
|
1006
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "studio-page-stack", children: [
|
|
1007
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PageHead, { title: t("\uB3C4\uAD6C \uC81C\uACF5\uC790", "Tool providers", "\u5DE5\u5177\u63D0\u4F9B\u8005"), description: t("\uC124\uCE58\uB41C \uD50C\uB7EC\uADF8\uC778\uC758 \uB3C4\uAD6C\uB97C Studio \uB3C4\uAD6C \uBAA9\uB85D\uC5D0 \uB4F1\uB85D\uD569\uB2C8\uB2E4. \uB4F1\uB85D\uD55C \uB3C4\uAD6C\uB294 \uD504\uB9AC\uC14B \uB9CC\uB4E4\uAE30\uC5D0\uC11C \uACE0\uB97C \uC218 \uC788\uC2B5\uB2C8\uB2E4.", "Register installed plugin tools in the Studio tool list so presets can select them.", "\u5C06\u5DF2\u5B89\u88C5\u63D2\u4EF6\u7684\u5DE5\u5177\u6CE8\u518C\u5230 Studio \u5DE5\u5177\u5217\u8868\uFF0C\u4F9B\u9884\u8BBE\u9009\u62E9") }),
|
|
1008
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Note, { children: t("\uB4F1\uB85D\uD558\uBA74 \uD50C\uB7EC\uADF8\uC778 \uCF54\uB4DC\uAC00 \uC2E4\uD589\uB418\uBBC0\uB85C \uC2E0\uB8B0\uD558\uB294 \uD50C\uB7EC\uADF8\uC778\uB9CC \uCD94\uAC00\uD558\uC138\uC694. \uD328\uD0A4\uC9C0\uB97C \uC124\uCE58\uD558\uC9C0\uB294 \uC54A\uC73C\uBA70, \uC124\uC815\uC740 \uC774 \uCEF4\uD4E8\uD130\uC5D0 \uD3C9\uBB38\uC73C\uB85C \uC800\uC7A5\uB429\uB2C8\uB2E4. \uC774\uBBF8 \uBC18\uC601\uD55C \uD504\uB9AC\uC14B\uC740 \uC790\uB3D9\uC73C\uB85C \uBC14\uB00C\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.", "Registering runs the plugin\u2019s code, so add only plugins you trust. Studio does not install packages, and these settings are stored on this computer in plain text. Presets you already applied do not change automatically.", "\u6CE8\u518C\u4F1A\u6267\u884C\u63D2\u4EF6\u4EE3\u7801\uFF0C\u8BF7\u4EC5\u6DFB\u52A0\u53EF\u4FE1\u63D2\u4EF6\u3002Studio \u4E0D\u4F1A\u5B89\u88C5\u8F6F\u4EF6\u5305\uFF0C\u8BBE\u7F6E\u4EE5\u660E\u6587\u4FDD\u5B58\u5728\u672C\u673A\u3002\u5DF2\u5E94\u7528\u7684\u9884\u8BBE\u4E0D\u4F1A\u81EA\u52A8\u6539\u53D8\u3002") }),
|
|
1009
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("ol", { className: "studio-steps", children: [
|
|
1010
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: t("\uD50C\uB7EC\uADF8\uC778\uC774 \uD604\uC7AC DSH \uD504\uB85C\uD544\uC5D0 \uC124\uCE58\uB418\uC5B4 \uC788\uB294\uC9C0 \uD655\uC778\uD569\uB2C8\uB2E4.", "Check that the plugin is installed in this DSH profile.", "\u786E\u8BA4\u63D2\u4EF6\u5DF2\u5B89\u88C5\u5728\u5F53\u524D DSH \u914D\u7F6E\u4E2D\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u5B89\u88C5\u3002") }),
|
|
1011
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: t("\uC544\uB798 \uBC30\uC5F4\uC5D0 id(\uACE0\uC720\uD55C \uC18C\uBB38\uC790 \uC2DD\uBCC4\uC790), name(\uD328\uD0A4\uC9C0 \uC774\uB984), config(\uD50C\uB7EC\uADF8\uC778 \uC124\uC815)\uB97C \uC785\uB825\uD569\uB2C8\uB2E4.", "Add an entry with id (unique lowercase identifier), name (exact package name), and config (public plugin settings).", "\u5728\u6570\u7EC4\u4E2D\u586B\u5199 id\uFF08\u552F\u4E00\u5C0F\u5199\u6807\u8BC6\u7B26\uFF09\u3001name\uFF08\u51C6\u786E\u7684\u8F6F\u4EF6\u5305\u540D\uFF09\u548C config\uFF08\u63D2\u4EF6\u516C\u5F00\u8BBE\u7F6E\uFF09\u3002") }),
|
|
1012
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: t("\uD655\uC778 \uD6C4 \uB4F1\uB85D\uC744 \uB204\uB974\uBA74 \uB3C4\uAD6C \uBAA9\uB85D\uC774 \uAC31\uC2E0\uB429\uB2C8\uB2E4. \uD544\uC694\uD55C \uB3C4\uAD6C\uB97C \uACE8\uB77C \uD504\uB9AC\uC14B\uC744 \uC800\uC7A5\uD558\uC138\uC694.", "Select Validate and update master to refresh the tool list, then choose the tools and save your preset.", "\u9A8C\u8BC1\u5E76\u66F4\u65B0\u4E3B\u9884\u8BBE\u540E\uFF0C\u9009\u62E9\u6240\u9700\u5DE5\u5177\u5E76\u4FDD\u5B58\u9884\u8BBE\u3002") })
|
|
890
1013
|
] }),
|
|
891
|
-
/* @__PURE__ */ (0,
|
|
892
|
-
/* @__PURE__ */ (0,
|
|
893
|
-
/* @__PURE__ */ (0,
|
|
894
|
-
/* @__PURE__ */ (0,
|
|
895
|
-
/* @__PURE__ */ (0,
|
|
896
|
-
/* @__PURE__ */ (0,
|
|
1014
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "studio-muted", children: t("\uC608\uC2DC: \uC124\uCE58\uB41C subagent \uD50C\uB7EC\uADF8\uC778\uC744 \uB2E4\uB978 \uB3C4\uAD6C \uC774\uB984\uC73C\uB85C \uB4F1\uB85D", "Example: register the installed subagent provider under a distinct tool name", "\u793A\u4F8B\uFF1A\u4F7F\u7528\u4E0D\u540C\u5DE5\u5177\u540D\u6CE8\u518C\u5DF2\u5B89\u88C5\u7684 subagent \u63D0\u4F9B\u8005") }),
|
|
1015
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("pre", { children: JSON.stringify([{ id: "extra-agent", name: "@deepseek-ai/dsh-tool-subagent", config: { provider: "spawn", toolName: "studio_extra_agent" } }], null, 2) }),
|
|
1016
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Note, { children: t("\uBAA9\uB85D \uC804\uCCB4\uAC00 \uC0C8 \uB0B4\uC6A9\uC73C\uB85C \uBC14\uB01D\uB2C8\uB2E4. \uAE30\uC874 \uD56D\uBAA9\uC744 \uC720\uC9C0\uD558\uB824\uBA74 \uBC30\uC5F4\uC5D0 \uB0A8\uACA8 \uB450\uACE0, \uBAA8\uB450 \uC9C0\uC6B0\uB824\uBA74 []\uB97C \uB4F1\uB85D\uD558\uC138\uC694. \uB3C4\uAD6C \uC774\uB984\uC774 \uACB9\uCE58\uC9C0 \uC54A\uAC8C \uD558\uC138\uC694. \uD544\uC694\uD55C \uC11C\uBE44\uC2A4\uAC00 \uC5C6\uB294 \uD50C\uB7EC\uADF8\uC778\uC740 \uD65C\uC131\uD654\uB418\uC9C0 \uC54A\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4.", "Registering replaces the whole list. Keep existing entries in the array to retain them, or register [] to remove them all. Avoid tool names that already exist. A plugin whose required services are missing may fail to activate.", "\u6CE8\u518C\u4F1A\u66FF\u6362\u6574\u4E2A\u5217\u8868\u3002\u4FDD\u7559\u5DF2\u6709\u6761\u76EE\u4EE5\u514D\u5220\u9664\uFF1B\u6CE8\u518C [] \u4F1A\u79FB\u9664\u5168\u90E8\u6761\u76EE\u3002\u907F\u514D\u5DE5\u5177\u91CD\u540D\uFF1B\u7F3A\u5C11\u4F9D\u8D56\u670D\u52A1\u7684\u63D2\u4EF6\u53EF\u80FD\u65E0\u6CD5\u6FC0\u6D3B\u3002") }),
|
|
1017
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "studio-field", children: [
|
|
1018
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: t("\uB4F1\uB85D \uBAA9\uB85D (JSON)", "Provider list (JSON)", "\u63D0\u4F9B\u8005\u5217\u8868\uFF08JSON\uFF09") }),
|
|
1019
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("textarea", { rows: 6, className: "studio-mono", value: text, disabled: !loaded || busy, onChange: (event) => setText(event.target.value) })
|
|
897
1020
|
] }),
|
|
898
|
-
/* @__PURE__ */ (0,
|
|
1021
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "studio-inline-actions", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { disabled: !loaded || busy, onClick: async () => {
|
|
899
1022
|
if (!actions) return;
|
|
900
1023
|
setBusy(true);
|
|
901
1024
|
setError("");
|
|
@@ -907,10 +1030,34 @@ function MasterExtensionsEditor({ locale, actions }) {
|
|
|
907
1030
|
setBusy(false);
|
|
908
1031
|
}
|
|
909
1032
|
}, children: t("\uD655\uC778 \uD6C4 \uB4F1\uB85D", "Validate and update master", "\u9A8C\u8BC1\u5E76\u66F4\u65B0\u4E3B\u9884\u8BBE") }) }),
|
|
910
|
-
error && /* @__PURE__ */ (0,
|
|
1033
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { role: "alert", children: error })
|
|
911
1034
|
] });
|
|
912
1035
|
}
|
|
913
1036
|
|
|
1037
|
+
// src/package-name.ts
|
|
1038
|
+
var PACKAGE_NAME = "@matamt-dbg/dsh-studio";
|
|
1039
|
+
var POLICY_PLUGIN = `${PACKAGE_NAME}/policy`;
|
|
1040
|
+
var ROLE_PLUGIN = `${PACKAGE_NAME}/roles`;
|
|
1041
|
+
var BATCH_PLUGIN = `${PACKAGE_NAME}/batch`;
|
|
1042
|
+
|
|
1043
|
+
// src/delegation.ts
|
|
1044
|
+
var ROLE_TOOL = "subagent_role";
|
|
1045
|
+
var LEGACY_ROLE_TOOL = "studio_role";
|
|
1046
|
+
var GENERIC_DELEGATION_TOOLS = ["subagent", "subagent_fork", "list_subagent_models"];
|
|
1047
|
+
var SUBAGENT_PLUGIN = "@deepseek-ai/dsh-tool-subagent";
|
|
1048
|
+
var isDelegationPlugin = (name) => name === SUBAGENT_PLUGIN || name === ROLE_PLUGIN;
|
|
1049
|
+
var WITHDRAWN_TOOLS = ["task_run"];
|
|
1050
|
+
function delegationTools(tools, hasRoles = false) {
|
|
1051
|
+
const delegates = hasRoles || tools.some((name) => name === ROLE_TOOL || name === LEGACY_ROLE_TOOL || GENERIC_DELEGATION_TOOLS.includes(name));
|
|
1052
|
+
const rest = tools.filter((name) => name !== ROLE_TOOL && name !== LEGACY_ROLE_TOOL && !GENERIC_DELEGATION_TOOLS.includes(name) && !WITHDRAWN_TOOLS.includes(name));
|
|
1053
|
+
return delegates ? [...rest, ROLE_TOOL] : rest;
|
|
1054
|
+
}
|
|
1055
|
+
function renameLegacyRoleKey(entries) {
|
|
1056
|
+
if (!entries || !Object.hasOwn(entries, LEGACY_ROLE_TOOL)) return entries;
|
|
1057
|
+
const { [LEGACY_ROLE_TOOL]: legacy, ...rest } = entries;
|
|
1058
|
+
return Object.hasOwn(rest, ROLE_TOOL) ? rest : { ...rest, [ROLE_TOOL]: legacy };
|
|
1059
|
+
}
|
|
1060
|
+
|
|
914
1061
|
// src/config-editor.tsx
|
|
915
1062
|
var import_react5 = __toESM(require("react"), 1);
|
|
916
1063
|
|
|
@@ -924,63 +1071,6 @@ function hasChangedOverride(base, override) {
|
|
|
924
1071
|
return JSON.stringify(base) !== JSON.stringify(override);
|
|
925
1072
|
}
|
|
926
1073
|
|
|
927
|
-
// src/item-picker.tsx
|
|
928
|
-
var import_react4 = __toESM(require("react"), 1);
|
|
929
|
-
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
930
|
-
function ItemPicker({ label, items, selected, onChange, labels, renderDetails, isModified, hasDetails }) {
|
|
931
|
-
const [query, setQuery] = import_react4.default.useState("");
|
|
932
|
-
const [filter, setFilter] = import_react4.default.useState("all");
|
|
933
|
-
const [detail, setDetail] = import_react4.default.useState();
|
|
934
|
-
const chosen = new Set(selected);
|
|
935
|
-
const modified = (name) => chosen.has(name) && (isModified?.(name) ?? false);
|
|
936
|
-
const text = query.trim().toLowerCase();
|
|
937
|
-
const visible = items.filter((item) => (filter === "all" || (filter === "selected" ? chosen.has(item.name) : modified(item.name))) && (!text || `${item.name}
|
|
938
|
-
${item.title ?? ""}
|
|
939
|
-
${item.description}
|
|
940
|
-
${item.searchText ?? ""}`.toLowerCase().includes(text)));
|
|
941
|
-
const counts = { all: items.length, selected: items.filter((item) => chosen.has(item.name)).length, modified: items.filter((item) => modified(item.name)).length };
|
|
942
|
-
const toggle = (name) => onChange(chosen.has(name) ? selected.filter((value) => value !== name) : [...selected, name]);
|
|
943
|
-
const open = items.find((item) => item.name === detail && chosen.has(item.name));
|
|
944
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "studio-picker", children: [
|
|
945
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "studio-picker-bar", children: [
|
|
946
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("input", { type: "search", "aria-label": labels.search, placeholder: labels.searchHint, value: query, onChange: (event) => setQuery(event.target.value) }),
|
|
947
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "studio-picker-filters", role: "radiogroup", "aria-label": labels.filter, children: ["all", "selected", "modified"].map((value) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { type: "button", role: "radio", "aria-checked": filter === value, className: "studio-picker-filter", onClick: () => setFilter(value), children: [
|
|
948
|
-
labels[value],
|
|
949
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "studio-count", children: counts[value] })
|
|
950
|
-
] }, value)) })
|
|
951
|
-
] }),
|
|
952
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("ul", { className: "studio-picker-list", "aria-label": label, children: [
|
|
953
|
-
visible.map((item) => {
|
|
954
|
-
const on = chosen.has(item.name);
|
|
955
|
-
const blocked = !on && item.disabledReason !== void 0;
|
|
956
|
-
const details = on && renderDetails !== void 0 && (hasDetails?.(item.name) ?? true);
|
|
957
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "studio-picker-row", "data-selected": on, children: [
|
|
958
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { type: "button", role: "switch", "aria-checked": on, disabled: blocked, className: "studio-picker-toggle", "aria-label": `${item.title ?? item.name}`, onClick: () => toggle(item.name), children: [
|
|
959
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "studio-picker-check", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 16 16", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M3.5 8.5l3 3 6-7", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
|
|
960
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "studio-picker-text", children: [
|
|
961
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "studio-picker-title", children: [
|
|
962
|
-
item.title ?? item.name,
|
|
963
|
-
item.subtitle && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "studio-picker-subtitle studio-mono", children: item.subtitle })
|
|
964
|
-
] }),
|
|
965
|
-
(item.disabledReason && !on ? item.disabledReason : item.description) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "studio-picker-description", children: item.disabledReason && !on ? item.disabledReason : item.description })
|
|
966
|
-
] })
|
|
967
|
-
] }),
|
|
968
|
-
modified(item.name) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "studio-badge", "data-tone": "info", "data-studio-modified": "true", children: labels.modifiedTag }),
|
|
969
|
-
details && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { small: true, "aria-label": `${labels.settings}: ${item.name}`, "aria-haspopup": "dialog", onClick: () => setDetail(item.name), children: labels.settings })
|
|
970
|
-
] }, item.name);
|
|
971
|
-
}),
|
|
972
|
-
!visible.length && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "studio-picker-empty", role: "status", children: [
|
|
973
|
-
text ? labels.noResults : labels.empty,
|
|
974
|
-
(text || filter !== "all") && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { small: true, onClick: () => {
|
|
975
|
-
setQuery("");
|
|
976
|
-
setFilter("all");
|
|
977
|
-
}, children: labels.clear })
|
|
978
|
-
] })
|
|
979
|
-
] }),
|
|
980
|
-
renderDetails && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DetailDialog, { open: open !== void 0, title: open?.title ?? open?.name, subtitle: open?.subtitle, closeLabel: labels.done, onClose: () => setDetail(void 0), children: open && renderDetails(open.name) })
|
|
981
|
-
] });
|
|
982
|
-
}
|
|
983
|
-
|
|
984
1074
|
// src/config-editor.tsx
|
|
985
1075
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
986
1076
|
var copy = {
|
|
@@ -988,10 +1078,11 @@ var copy = {
|
|
|
988
1078
|
list: "Configs",
|
|
989
1079
|
reset: "Reset override",
|
|
990
1080
|
unavailable: "Schema unavailable; editing is disabled.",
|
|
1081
|
+
delegated: "Merged into subagent_role. Configure subagents in the Subagent settings tab.",
|
|
991
1082
|
inherited: "Base value (not overridden)",
|
|
992
1083
|
overridden: "Override",
|
|
993
1084
|
unset: "Not set",
|
|
994
|
-
unsupported: "This schema type is not yet supported by the form. Existing values are preserved;
|
|
1085
|
+
unsupported: "This schema type is not yet supported by the form. Existing values are preserved; turn off the Config to reset them.",
|
|
995
1086
|
json: "Config",
|
|
996
1087
|
invalid: "Enter valid JSON.",
|
|
997
1088
|
object: "Enter a JSON object.",
|
|
@@ -1003,6 +1094,7 @@ var copy = {
|
|
|
1003
1094
|
list: "Config",
|
|
1004
1095
|
reset: "\uAE30\uBCF8\uAC12\uC73C\uB85C",
|
|
1005
1096
|
unavailable: "\uC2A4\uD0A4\uB9C8\uB97C \uC77D\uC744 \uC218 \uC5C6\uC5B4 \uD3B8\uC9D1\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
1097
|
+
delegated: "subagent_role\uB85C \uD1B5\uD569\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8 \uD0ED\uC5D0\uC11C \uC124\uC815\uD558\uC138\uC694.",
|
|
1006
1098
|
inherited: "\uAE30\uBCF8\uAC12",
|
|
1007
1099
|
overridden: "\uBCC0\uACBD\uB428",
|
|
1008
1100
|
unset: "\uBBF8\uC124\uC815",
|
|
@@ -1018,6 +1110,7 @@ var copy = {
|
|
|
1018
1110
|
list: "Config",
|
|
1019
1111
|
reset: "\u91CD\u7F6E\u8986\u76D6",
|
|
1020
1112
|
unavailable: "\u67B6\u6784\u4E0D\u53EF\u7528\uFF0C\u65E0\u6CD5\u7F16\u8F91",
|
|
1113
|
+
delegated: "\u5DF2\u5408\u5E76\u5230 subagent_role\u3002\u8BF7\u5728\u5B50\u4EE3\u7406\u8BBE\u7F6E\u9875\u4E2D\u914D\u7F6E\u3002",
|
|
1021
1114
|
inherited: "\u57FA\u7840\u503C\uFF08\u672A\u8986\u76D6\uFF09",
|
|
1022
1115
|
overridden: "\u8986\u76D6",
|
|
1023
1116
|
unset: "\u672A\u8BBE\u7F6E",
|
|
@@ -1339,7 +1432,7 @@ function ConfigEditor({ entries, value, onChange, locale }) {
|
|
|
1339
1432
|
subtitle: entry.id,
|
|
1340
1433
|
description: "",
|
|
1341
1434
|
searchText: JSON.stringify(entry.schema ?? {}),
|
|
1342
|
-
...entry.error || !entry.schema ? { disabledReason: entry.error || labels.unavailable } : {}
|
|
1435
|
+
...isDelegationPlugin(entry.name) ? { disabledReason: labels.delegated } : entry.error || !entry.schema ? { disabledReason: entry.error || labels.unavailable } : {}
|
|
1343
1436
|
})),
|
|
1344
1437
|
...Object.keys(value).filter((id) => !entries.some((entry) => entry.id === id)).map((id) => ({ name: id, title: id, description: labels.unavailable }))
|
|
1345
1438
|
];
|
|
@@ -1419,7 +1512,7 @@ function PresetList({ locale, api, revision, onEdit, onCopy }) {
|
|
|
1419
1512
|
const warnings = [...items.reduce((groups, item) => item.applyWarning ? groups.set(item.applyWarning, [...groups.get(item.applyWarning) ?? [], item.name]) : groups, /* @__PURE__ */ new Map())];
|
|
1420
1513
|
const retry = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { small: true, disabled: load.phase === "loading", onClick: () => void refresh(), children: t("\uB2E4\uC2DC \uC2DC\uB3C4", "Retry", "\u91CD\u8BD5") });
|
|
1421
1514
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1422
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PageHead, { title: t("\uD504\uB9AC\uC14B \uBAA9\uB85D", "Preset list", "\u9884\u8BBE\u5217\u8868"), description: t("\
|
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PageHead, { title: t("\uD504\uB9AC\uC14B \uBAA9\uB85D", "Preset list", "\u9884\u8BBE\u5217\u8868"), description: t("\uC0C8 \uC138\uC158\uC5D0 \uC801\uC6A9\uD558\uB824\uBA74 DSH\uC5D0 \uBC18\uC601\uD574 \uC8FC\uC138\uC694. \uC774\uBBF8 \uC2E4\uD589 \uC911\uC778 \uC138\uC158\uC5D0\uB294 \uBCC0\uACBD \uC0AC\uD56D\uC774 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.", "Apply to DSH to use these settings in new sessions. Changes do not affect sessions that are already running.", "\u8BF7\u5E94\u7528\u5230 DSH\uFF0C\u4EE5\u4FBF\u5728\u65B0\u4F1A\u8BDD\u4E2D\u4F7F\u7528\u8FD9\u4E9B\u8BBE\u7F6E\u3002\u66F4\u6539\u4E0D\u4F1A\u5F71\u54CD\u6B63\u5728\u8FD0\u884C\u7684\u4F1A\u8BDD\u3002"), actions: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { disabled: busy || !api || load.phase === "loading", onClick: () => void refresh(), children: load.phase === "loading" && load.items ? t("\uC0C8\uB85C\uACE0\uCE68 \uC911\u2026", "Refreshing\u2026", "\u5237\u65B0\u4E2D\u2026") : t("\uC0C8\uB85C\uACE0\uCE68", "Refresh", "\u5237\u65B0") }) }),
|
|
1423
1516
|
!api && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Notice, { children: t("Studio \uC11C\uBC84\uC5D0 \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC544 \uD504\uB9AC\uC14B\uC744 \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", "Presets are unavailable because the Studio Host API is not connected.", "Studio Host API \u672A\u8FDE\u63A5\uFF0C\u65E0\u6CD5\u52A0\u8F7D\u9884\u8BBE") }),
|
|
1424
1517
|
api && load.phase === "loading" && !load.items && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "status", className: "studio-muted", children: t("\uD504\uB9AC\uC14B\uC744 \uBD88\uB7EC\uC624\uB294 \uC911\u2026", "Loading presets\u2026", "\u6B63\u5728\u52A0\u8F7D\u9884\u8BBE\u2026") }),
|
|
1425
1518
|
load.phase === "failed" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Notice, { action: retry, children: load.items ? t(`\uBAA9\uB85D\uC744 \uC0C8\uB85C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD574 \uC774\uC804 \uBAA9\uB85D\uC744 \uD45C\uC2DC\uD569\uB2C8\uB2E4. (${load.error})`, `Could not reload the list. Showing the last loaded list. (${load.error})`, `\u65E0\u6CD5\u91CD\u65B0\u52A0\u8F7D\u5217\u8868\uFF0C\u6B63\u5728\u663E\u793A\u4E0A\u6B21\u52A0\u8F7D\u7684\u5217\u8868\uFF08${load.error}\uFF09`) : t(`\uD504\uB9AC\uC14B \uBAA9\uB85D\uC744 \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uC800\uC7A5\uB41C \uD504\uB9AC\uC14B\uC5D0\uB294 \uC601\uD5A5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. (${load.error})`, `Could not load presets. Saved presets were not changed. (${load.error})`, `\u65E0\u6CD5\u52A0\u8F7D\u9884\u8BBE\uFF0C\u5DF2\u4FDD\u5B58\u7684\u9884\u8BBE\u672A\u88AB\u66F4\u6539\uFF08${load.error}\uFF09`) }),
|
|
@@ -1429,7 +1522,7 @@ function PresetList({ locale, api, revision, onEdit, onCopy }) {
|
|
|
1429
1522
|
action.error,
|
|
1430
1523
|
")"
|
|
1431
1524
|
] }),
|
|
1432
|
-
load.phase === "ready" && !items.length && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "status", className: "studio-muted", children: t("\uC800\uC7A5\uB41C \uD504\uB9AC\uC14B\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uD504\uB9AC\uC14B \uB9CC\uB4E4\uAE30\uC5D0\uC11C \uC0C8\uB85C \uB9CC\uB4E4\uC5B4 \uBCF4\uC138\uC694.", "No saved presets. Create
|
|
1525
|
+
load.phase === "ready" && !items.length && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "status", className: "studio-muted", children: t("\uC800\uC7A5\uB41C \uD504\uB9AC\uC14B\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uD504\uB9AC\uC14B \uB9CC\uB4E4\uAE30\uC5D0\uC11C \uC0C8\uB85C \uB9CC\uB4E4\uC5B4 \uBCF4\uC138\uC694.", "No saved presets. Use Create preset to make one.", "\u6CA1\u6709\u5DF2\u4FDD\u5B58\u7684\u9884\u8BBE\u3002\u8BF7\u4ECE\u521B\u5EFA\u9884\u8BBE\u83DC\u5355\u5F00\u59CB\u3002") }),
|
|
1433
1526
|
warnings.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { className: "studio-preset-warnings", "aria-label": t("\uC8FC\uC758\uC0AC\uD56D", "Notices", "\u6CE8\u610F\u4E8B\u9879"), children: warnings.map(([text, names2]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { children: [
|
|
1434
1527
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Badge, { tone: "warning", children: t("\uC8FC\uC758", "Notice", "\u6CE8\u610F") }),
|
|
1435
1528
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
|
|
@@ -1437,7 +1530,7 @@ function PresetList({ locale, api, revision, onEdit, onCopy }) {
|
|
|
1437
1530
|
" ",
|
|
1438
1531
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "studio-card-meta", children: [
|
|
1439
1532
|
"(",
|
|
1440
|
-
t("\
|
|
1533
|
+
t("\uB300\uC0C1", "Affects", "\u6D89\u53CA"),
|
|
1441
1534
|
": ",
|
|
1442
1535
|
names2.join(", "),
|
|
1443
1536
|
")"
|
|
@@ -1451,7 +1544,7 @@ function PresetList({ locale, api, revision, onEdit, onCopy }) {
|
|
|
1451
1544
|
item.template && !item.readOnly && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Badge, { tone: "info", children: t("\uAE30\uBCF8 \uC81C\uACF5", "Built-in", "\u5185\u7F6E") }),
|
|
1452
1545
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Badge, { tone: tone[item.status], children: status(item) })
|
|
1453
1546
|
] }),
|
|
1454
|
-
item.template ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "studio-card-text", children: t("Studio\uAC00 \uAD8C\uC7A5\uD558\uB294 \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8\uC6A9 \
|
|
1547
|
+
item.template ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "studio-card-text", children: t("Studio\uAC00 \uAD8C\uC7A5\uD558\uB294 \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8\uC6A9 \uAD6C\uC131\uC785\uB2C8\uB2E4. \uACE0\uCE58\uB824\uBA74 \uBCF5\uC0AC\uD574\uC11C \uC4F0\uC138\uC694.", "Studio\u2019s recommended setup for coding agents. Create a copy to customize it.", "Studio \u63A8\u8350\u7684\u7F16\u7801\u4EE3\u7406\u914D\u7F6E\u3002\u5982\u9700\u4FEE\u6539\uFF0C\u8BF7\u521B\u5EFA\u526F\u672C") }) : item.description && !item.readOnly && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "studio-card-text", children: item.description }),
|
|
1455
1548
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "studio-card-meta", children: [
|
|
1456
1549
|
t("\uB3C4\uAD6C", "Tools", "\u5DE5\u5177"),
|
|
1457
1550
|
" ",
|
|
@@ -1461,7 +1554,7 @@ function PresetList({ locale, api, revision, onEdit, onCopy }) {
|
|
|
1461
1554
|
" ",
|
|
1462
1555
|
Array.isArray(item.agents) ? item.agents.length : 0
|
|
1463
1556
|
] }),
|
|
1464
|
-
item.readOnly ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "studio-card-meta studio-card-note", children: t("
|
|
1557
|
+
item.readOnly ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "studio-card-meta studio-card-note", children: t("\uC774 \uD504\uB85C\uD544\uC5D0\uC11C \uC4F8 \uC218 \uC788\uB294 \uBAA8\uB4E0 \uB3C4\uAD6C\uB97C \uB2F4\uC740 \uAE30\uC900 \uD504\uB9AC\uC14B\uC785\uB2C8\uB2E4. \uD3B8\uC9D1\uD558\uAC70\uB098 \uC0AD\uC81C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", "Reference preset with every tool available in this profile. It cannot be edited or deleted.", "\u5305\u542B\u6B64\u914D\u7F6E\u6587\u4EF6\u4E2D\u6240\u6709\u53EF\u7528\u5DE5\u5177\u7684\u57FA\u51C6\u9884\u8BBE\uFF0C\u65E0\u6CD5\u7F16\u8F91\u6216\u5220\u9664") }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "studio-card-footer", children: [
|
|
1465
1558
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { small: true, disabled: busy || item.readOnly || item.template || !onEdit, title: item.template ? t("\uAE30\uBCF8 \uC81C\uACF5 \uD504\uB9AC\uC14B\uC740 \uD3B8\uC9D1\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uBCF5\uC0AC\uD574\uC11C \uACE0\uCCD0 \uC4F0\uC138\uC694.", "Built-in presets cannot be edited. Create a copy to customize it.", "\u5185\u7F6E\u9884\u8BBE\u65E0\u6CD5\u7F16\u8F91\uFF0C\u8BF7\u521B\u5EFA\u526F\u672C\u540E\u4FEE\u6539") : void 0, onClick: () => onEdit?.(item), children: t("\uD3B8\uC9D1", "Edit", "\u7F16\u8F91") }),
|
|
1466
1559
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { small: true, disabled: busy || !onCopy, onClick: () => onCopy?.(item), children: t("\uBCF5\uC0AC", "Create copy", "\u521B\u5EFA\u526F\u672C") }),
|
|
1467
1560
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { small: true, disabled: busy || !api || item.readOnly || item.nonDeletable, title: item.nonDeletable ? t("\uAE30\uBCF8 \uC81C\uACF5 \uD504\uB9AC\uC14B\uC740 \uC0AD\uC81C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", "Built-in presets cannot be deleted.", "\u5185\u7F6E\u9884\u8BBE\u65E0\u6CD5\u5220\u9664") : void 0, onClick: () => {
|
|
@@ -1497,36 +1590,39 @@ function PresetList({ locale, api, revision, onEdit, onCopy }) {
|
|
|
1497
1590
|
void run(target.id, "delete", () => api.delete(target.id)).then(() => setDeleting(void 0));
|
|
1498
1591
|
}, children: t("\uC0AD\uC81C \uD655\uC778", "Confirm delete", "\u786E\u8BA4\u5220\u9664") })
|
|
1499
1592
|
] }),
|
|
1500
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "studio-muted", children: t("\uC800\uC7A5\uB41C \uD504\uB9AC\uC14B\uACFC DSH\uC5D0 \uBC18\uC601\uB41C \uD504\uB9AC\uC14B\uC744 \uD568\uAED8 \uC0AD\uC81C\uD569\uB2C8\uB2E4. \uAE30\uC874 \uB300\uD654\uB294 \uB0A8\uC544 \uC788\uC2B5\uB2C8\uB2E4.", "
|
|
1593
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "studio-muted", children: t("\uC800\uC7A5\uB41C \uD504\uB9AC\uC14B\uACFC DSH\uC5D0 \uBC18\uC601\uB41C \uD504\uB9AC\uC14B\uC744 \uD568\uAED8 \uC0AD\uC81C\uD569\uB2C8\uB2E4. \uAE30\uC874 \uB300\uD654\uB294 \uB0A8\uC544 \uC788\uC2B5\uB2C8\uB2E4.", "Deletes the saved preset and removes it from DSH. Existing conversations are kept.", "\u5220\u9664\u5DF2\u4FDD\u5B58\u9884\u8BBE\u53CA Studio \u6CE8\u518C\u7684 DSH \u9884\u8BBE\uFF0C\u4E0D\u5220\u9664\u73B0\u6709\u5BF9\u8BDD\u3002") })
|
|
1501
1594
|
}
|
|
1502
1595
|
)
|
|
1503
1596
|
] });
|
|
1504
1597
|
}
|
|
1505
1598
|
|
|
1506
|
-
// src/package-name.ts
|
|
1507
|
-
var PACKAGE_NAME = "@matamt-dbg/dsh-studio";
|
|
1508
|
-
var POLICY_PLUGIN = `${PACKAGE_NAME}/policy`;
|
|
1509
|
-
var ROLE_PLUGIN = `${PACKAGE_NAME}/roles`;
|
|
1510
|
-
var BATCH_PLUGIN = `${PACKAGE_NAME}/batch`;
|
|
1511
|
-
|
|
1512
|
-
// src/delegation.ts
|
|
1513
|
-
var ROLE_TOOL = "subagent_role";
|
|
1514
|
-
var LEGACY_ROLE_TOOL = "studio_role";
|
|
1515
|
-
var GENERIC_DELEGATION_TOOLS = ["subagent", "subagent_fork", "list_subagent_models"];
|
|
1516
|
-
var WITHDRAWN_TOOLS = ["task_run"];
|
|
1517
|
-
function delegationTools(tools, hasRoles = false) {
|
|
1518
|
-
const delegates = hasRoles || tools.some((name) => name === ROLE_TOOL || name === LEGACY_ROLE_TOOL || GENERIC_DELEGATION_TOOLS.includes(name));
|
|
1519
|
-
const rest = tools.filter((name) => name !== ROLE_TOOL && name !== LEGACY_ROLE_TOOL && !GENERIC_DELEGATION_TOOLS.includes(name) && !WITHDRAWN_TOOLS.includes(name));
|
|
1520
|
-
return delegates ? [...rest, ROLE_TOOL] : rest;
|
|
1521
|
-
}
|
|
1522
|
-
function renameLegacyRoleKey(entries) {
|
|
1523
|
-
if (!entries || !Object.hasOwn(entries, LEGACY_ROLE_TOOL)) return entries;
|
|
1524
|
-
const { [LEGACY_ROLE_TOOL]: legacy, ...rest } = entries;
|
|
1525
|
-
return Object.hasOwn(rest, ROLE_TOOL) ? rest : { ...rest, [ROLE_TOOL]: legacy };
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
1599
|
// src/optimized-preset.ts
|
|
1529
1600
|
var BUILTIN_TOOL_PRESETS = ["standard", "ptc", "minimal", "cordis"];
|
|
1601
|
+
var OPTIMIZED_TOOLS = [
|
|
1602
|
+
"read_batch",
|
|
1603
|
+
"read",
|
|
1604
|
+
"write",
|
|
1605
|
+
"edit",
|
|
1606
|
+
"glob",
|
|
1607
|
+
"grep",
|
|
1608
|
+
"job_output",
|
|
1609
|
+
"job_list",
|
|
1610
|
+
"job_kill",
|
|
1611
|
+
"skill",
|
|
1612
|
+
"ask_user_question",
|
|
1613
|
+
"web_search",
|
|
1614
|
+
"web_fetch",
|
|
1615
|
+
"present",
|
|
1616
|
+
"bash",
|
|
1617
|
+
"read_image",
|
|
1618
|
+
"exit_plan_mode",
|
|
1619
|
+
"send_message",
|
|
1620
|
+
"interrupt_agent",
|
|
1621
|
+
"list_agents",
|
|
1622
|
+
"workflow",
|
|
1623
|
+
"subagent_role"
|
|
1624
|
+
];
|
|
1625
|
+
var ALLOWED_TOOLS = /* @__PURE__ */ new Set([...OPTIMIZED_TOOLS, ...GENERIC_DELEGATION_TOOLS, LEGACY_ROLE_TOOL]);
|
|
1530
1626
|
|
|
1531
1627
|
// src/prompt-tools-prototype.tsx
|
|
1532
1628
|
var import_react7 = __toESM(require("react"), 1);
|
|
@@ -1568,7 +1664,8 @@ function PromptToolsPrototype({ locale, prompt, onPromptChange, provided, onProv
|
|
|
1568
1664
|
onRequestChange?.(request);
|
|
1569
1665
|
}, [requestKey, onRequestChange]);
|
|
1570
1666
|
const labels = { filter: t("\uBCF4\uAE30", "Show", "\u663E\u793A"), search: t("\uB3C4\uAD6C \uAC80\uC0C9", "Search tools", "\u641C\u7D22\u5DE5\u5177"), searchHint: t("\uC774\uB984, \uC124\uBA85, \uC778\uC790\uB85C \uAC80\uC0C9", "Search names, descriptions or parameters", "\u6309\u540D\u79F0\u3001\u63CF\u8FF0\u6216\u53C2\u6570\u641C\u7D22"), all: t("\uC804\uCCB4", "All", "\u5168\u90E8"), selected: t("\uC120\uD0DD\uB428", "Selected", "\u5DF2\u9009"), modified: t("\uBCC0\uACBD\uB428", "Modified", "\u5DF2\u4FEE\u6539"), settings: t("\uC124\uC815", "Details", "\u8BE6\u60C5"), done: t("\uC644\uB8CC", "Close", "\u5173\u95ED"), empty: t("\uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.", "No items", "\u65E0\u9879\u76EE"), noResults: t("\uAC80\uC0C9 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.", "No matching results.", "\u6CA1\u6709\u5339\u914D\u7ED3\u679C\u3002"), modifiedTag: t("\uBCC0\uACBD\uB428", "Modified", "\u5DF2\u4FEE\u6539"), clear: t("\uC804\uCCB4 \uBCF4\uAE30", "Show all", "\u663E\u793A\u5168\u90E8") };
|
|
1571
|
-
const
|
|
1667
|
+
const unsupportedToolReason = t("\uD604\uC7AC Studio\uC5D0\uC11C run_code\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. PTC\uB97C \uC0AC\uC6A9\uD558\uB824\uBA74 DSH\uC758 PTC \uD504\uB9AC\uC14B\uC73C\uB85C \uC0C8 \uC138\uC158\uC744 \uC2DC\uC791\uD574 \uC8FC\uC138\uC694. \uC774\uBBF8 \uC120\uD0DD\uB41C \uACBD\uC6B0\uC5D0\uB294 \uD574\uC81C\uD574 \uC8FC\uC138\uC694.", "Studio does not currently support run_code. To use PTC, start a new session with DSH\u2019s PTC preset. If run_code is already selected, deselect it.", "Studio \u76EE\u524D\u4E0D\u652F\u6301 run_code\u3002\u5982\u9700\u4F7F\u7528 PTC\uFF0C\u8BF7\u4F7F\u7528 DSH \u7684 PTC \u9884\u8BBE\u542F\u52A8\u65B0\u4F1A\u8BDD\u3002\u82E5\u5DF2\u9009\u62E9 run_code\uFF0C\u8BF7\u53D6\u6D88\u9009\u62E9\u3002");
|
|
1668
|
+
const presetTools = (presetId) => delegationTools(presets.find((p) => p.id === presetId)?.tools.map((tool) => tool.name) ?? []).filter((name) => name !== "run_code");
|
|
1572
1669
|
const togglePreset = (presetId) => {
|
|
1573
1670
|
const names2 = presetTools(presetId);
|
|
1574
1671
|
onProvidedChange(includesPreset(presetId) ? provided.filter((name) => !names2.includes(name)) : [.../* @__PURE__ */ new Set([...provided, ...names2])]);
|
|
@@ -1600,7 +1697,7 @@ function PromptToolsPrototype({ locale, prompt, onPromptChange, provided, onProv
|
|
|
1600
1697
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react7.default.Fragment, { children: [
|
|
1601
1698
|
catalogError ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Note, { children: catalogError }) : !catalog ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Note, { children: t("\uBD88\uB7EC\uC624\uB294 \uC911\u2026", "Loading\u2026", "\u6B63\u5728\u52A0\u8F7D\u2026") }) : null,
|
|
1602
1699
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "studio-form-section", children: [
|
|
1603
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SectionHead, { title: t("\uD504\uB86C\uD504\uD2B8", "Prompt composition", "\u63D0\u793A\u8BCD\u7EC4\u88C5"), description: t("\uC5D0\uC774\uC804\uD2B8\uC5D0\uAC8C \uC804\uB2EC\uD560 \uC9C0\uCE68\uC744 \uD3B8\uC9D1\uD569\uB2C8\uB2E4. \uBBF8\uB9AC\uBCF4\uAE30\uB85C \uC870\uB9BD \uACB0\uACFC\uB97C \uD655\uC778\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.", "Edit
|
|
1700
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SectionHead, { title: t("\uD504\uB86C\uD504\uD2B8", "Prompt composition", "\u63D0\u793A\u8BCD\u7EC4\u88C5"), description: t("\uC5D0\uC774\uC804\uD2B8\uC5D0\uAC8C \uC804\uB2EC\uD560 \uC9C0\uCE68\uC744 \uD3B8\uC9D1\uD569\uB2C8\uB2E4. \uBBF8\uB9AC\uBCF4\uAE30\uB85C \uC870\uB9BD \uACB0\uACFC\uB97C \uD655\uC778\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.", "Edit the instructions the agent receives, then preview the assembled result.", "\u7F16\u8F91 Persona \u4E0E Studio \u4E13\u7528\u6307\u4EE4\uFF0C\u5E76\u9884\u89C8\u7EC4\u88C5\u7ED3\u679C\u3002"), actions: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { small: true, disabled: !onPreview || !current || busy, onClick: () => void preview(), children: busy ? t("\uC870\uB9BD \uC911\u2026", "Assembling\u2026", "\u7EC4\u88C5\u4E2D\u2026") : t("\uD504\uB86C\uD504\uD2B8 \uBBF8\uB9AC\uBCF4\uAE30", "Preview prompt", "\u9884\u89C8\u63D0\u793A\u8BCD") }) }),
|
|
1604
1701
|
["prefix", "suffix"].map((key) => {
|
|
1605
1702
|
const name = providers[0];
|
|
1606
1703
|
const config = providerConfigs[name] ?? {};
|
|
@@ -1625,12 +1722,12 @@ function PromptToolsPrototype({ locale, prompt, onPromptChange, provided, onProv
|
|
|
1625
1722
|
] })
|
|
1626
1723
|
] }),
|
|
1627
1724
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "studio-form-section", children: [
|
|
1628
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SectionHead, { title: t("\uB3C4\uAD6C", "Provided tools", "\u63D0\u4F9B\u7684\u5DE5\u5177"), description: t("\uC5D0\uC774\uC804\uD2B8\uAC00 \uC4F8 \uB3C4\uAD6C\uB97C \uACE0\uB985\uB2C8\uB2E4. \uC124\uC815\uC5D0\uC11C \uBAA8\uB378\uC5D0 \uBCF4\uC774\uB294 \uC124\uBA85\uC744 \uBC14\uAFC0 \uC218 \uC788\uC73C\uBA70, \uB3C4\uAD6C \uB3D9\uC791\uC740 \uBC14\uB00C\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.", "Choose tools. Details
|
|
1725
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SectionHead, { title: t("\uB3C4\uAD6C", "Provided tools", "\u63D0\u4F9B\u7684\u5DE5\u5177"), description: t("\uC5D0\uC774\uC804\uD2B8\uAC00 \uC4F8 \uB3C4\uAD6C\uB97C \uACE0\uB985\uB2C8\uB2E4. \uC124\uC815\uC5D0\uC11C \uBAA8\uB378\uC5D0 \uBCF4\uC774\uB294 \uC124\uBA85\uC744 \uBC14\uAFC0 \uC218 \uC788\uC73C\uBA70, \uB3C4\uAD6C \uB3D9\uC791\uC740 \uBC14\uB00C\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.", "Choose the tools the agent can use. Details changes only the descriptions the model sees; tool behavior stays the same.", "\u9009\u62E9\u5DE5\u5177\u3002\u8BE6\u60C5\u53EA\u7F16\u8F91\u6A21\u578B\u53EF\u89C1\u7684\u63CF\u8FF0\uFF0C\u5DE5\u5177\u884C\u4E3A\u4E0D\u53D8\u3002") }),
|
|
1629
1726
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "studio-field", children: [
|
|
1630
1727
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: t("\uAE30\uBCF8 \uD504\uB9AC\uC14B\uC5D0\uC11C \uD55C \uBC88\uC5D0 \uCD94\uAC00", "Include a built-in preset tool set", "\u5F15\u5165\u5185\u7F6E\u9884\u8BBE\u5DE5\u5177\u96C6") }),
|
|
1631
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "studio-inline-actions", children: toolSources.map((p) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { small: true, disabled: !!p.error, "aria-pressed": includesPreset(p.id), onClick: () => togglePreset(p.id), children: p.id === "cordis" ? "creator (cordis)" : p.id }, p.id)) })
|
|
1728
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "studio-inline-actions", children: toolSources.map((p) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { small: true, disabled: !!p.error || !presetTools(p.id).length, "aria-pressed": includesPreset(p.id), onClick: () => togglePreset(p.id), children: p.id === "cordis" ? "creator (cordis)" : p.id }, p.id)) })
|
|
1632
1729
|
] }),
|
|
1633
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ItemPicker, { label: t("\uB3C4\uAD6C", "Provided tools", "\u63D0\u4F9B\u7684\u5DE5\u5177"), items: [...tools.map((tool) => ({ ...tool, searchText: JSON.stringify(tool.parameters), ...GENERIC_DELEGATION_TOOLS.includes(tool.name) ? { disabledReason: t(`${ROLE_TOOL}\uB85C \uD1B5\uD569\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8 \uC704\uC784\uC740 ${ROLE_TOOL}\uC744 \uC120\uD0DD\uD558\uC138\uC694.`, `Merged into ${ROLE_TOOL}. Select ${ROLE_TOOL} for subagent delegation.`, `\u5DF2\u5408\u5E76\u5230 ${ROLE_TOOL}\u3002\u8BF7\u9009\u62E9 ${ROLE_TOOL} \u8FDB\u884C\u5B50\u4EE3\u7406\u59D4\u6D3E\u3002`) } : {} })), ...provided.filter((name) => !tools.some((tool) => tool.name === name)).map((name) => ({ name, description: t("\uD604\uC7AC \
|
|
1730
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ItemPicker, { label: t("\uB3C4\uAD6C", "Provided tools", "\u63D0\u4F9B\u7684\u5DE5\u5177"), items: [...tools.map((tool) => ({ ...tool, searchText: JSON.stringify(tool.parameters), ...tool.name === "run_code" ? { description: unsupportedToolReason, disabledReason: unsupportedToolReason } : {}, ...GENERIC_DELEGATION_TOOLS.includes(tool.name) ? { disabledReason: t(`${ROLE_TOOL}\uB85C \uD1B5\uD569\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8 \uC704\uC784\uC740 ${ROLE_TOOL}\uC744 \uC120\uD0DD\uD558\uC138\uC694.`, `Merged into ${ROLE_TOOL}. Select ${ROLE_TOOL} for subagent delegation.`, `\u5DF2\u5408\u5E76\u5230 ${ROLE_TOOL}\u3002\u8BF7\u9009\u62E9 ${ROLE_TOOL} \u8FDB\u884C\u5B50\u4EE3\u7406\u59D4\u6D3E\u3002`) } : {} })), ...provided.filter((name) => !tools.some((tool) => tool.name === name)).map((name) => ({ name, description: name === "run_code" ? unsupportedToolReason : t("\uD604\uC7AC \uD504\uB85C\uD544\uC5D0 \uC5C6\uB294 \uB3C4\uAD6C\uC785\uB2C8\uB2E4. \uC774\uB300\uB85C \uBC18\uC601\uD558\uBA74 \uC2E4\uD328\uD569\uB2C8\uB2E4.", "Not available in this profile. Applying will fail.", "\u5F53\u524D\u914D\u7F6E\u6587\u4EF6\u4E2D\u6CA1\u6709\u6B64\u5DE5\u5177\uFF0C\u76F4\u63A5\u5E94\u7528\u4F1A\u5931\u8D25\u3002"), ...name === "run_code" ? { disabledReason: unsupportedToolReason } : {} }))], selected: provided, onChange: changeTools, labels, hasDetails: (name) => name !== "run_code", isModified: (name) => {
|
|
1634
1731
|
const tool = tools.find((item) => item.name === name);
|
|
1635
1732
|
const override = toolOverrides[name];
|
|
1636
1733
|
const parameters = parameterFields(tool?.parameters);
|
|
@@ -1676,7 +1773,7 @@ function PromptToolsPrototype({ locale, prompt, onPromptChange, provided, onProv
|
|
|
1676
1773
|
const next = { ...toolOverrides };
|
|
1677
1774
|
delete next[name];
|
|
1678
1775
|
setToolOverrides(next);
|
|
1679
|
-
}, children: t("\uC124\uBA85 \uBAA8\uB450 \uC6D0\uB798\uB300\uB85C", "
|
|
1776
|
+
}, children: t("\uC124\uBA85 \uBAA8\uB450 \uC6D0\uB798\uB300\uB85C", "Reset all descriptions", "\u5168\u90E8\u6062\u590D\u539F\u59CB\u63CF\u8FF0") })
|
|
1680
1777
|
] });
|
|
1681
1778
|
} })
|
|
1682
1779
|
] }),
|
|
@@ -1685,7 +1782,7 @@ function PromptToolsPrototype({ locale, prompt, onPromptChange, provided, onProv
|
|
|
1685
1782
|
{
|
|
1686
1783
|
wide: true,
|
|
1687
1784
|
open: previewOpen,
|
|
1688
|
-
title: t("\uD504\uB86C\uD504\uD2B8 \uBBF8\uB9AC\uBCF4\uAE30", "Prompt
|
|
1785
|
+
title: t("\uD504\uB86C\uD504\uD2B8 \uBBF8\uB9AC\uBCF4\uAE30", "Prompt preview", "\u63D0\u793A\u8BCD\u7ED3\u679C\u9884\u89C8"),
|
|
1689
1786
|
closeLabel: t("\uB2EB\uAE30", "Close preview", "\u5173\u95ED\u9884\u89C8"),
|
|
1690
1787
|
onClose: closePreview,
|
|
1691
1788
|
subtitle: result ? t(`\uC139\uC158 ${result.sections.length}\uAC1C \xB7 \uB3C4\uAD6C ${result.tools.length}\uAC1C`, `${result.sections.length} sections \xB7 ${result.tools.length} tools`, `${result.sections.length} \u4E2A\u7AE0\u8282 \xB7 ${result.tools.length} \u4E2A\u5DE5\u5177`) : void 0,
|
|
@@ -1786,6 +1883,10 @@ function DetailLayout({ title, subtitle, navigation, pages, selected, onSelect }
|
|
|
1786
1883
|
|
|
1787
1884
|
// src/optimization-prototype.tsx
|
|
1788
1885
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1886
|
+
var withoutSubagentFilter = (request) => {
|
|
1887
|
+
const { subagentToolFilter: _filter, ...rest } = request;
|
|
1888
|
+
return rest;
|
|
1889
|
+
};
|
|
1789
1890
|
var initial = { prompt: "Report evidence, uncertainty and remaining work.", tools: "read / grep / glob", spill: "2048", wait: "60000" };
|
|
1790
1891
|
var seeds = [
|
|
1791
1892
|
{ name: "Researcher", role: "research", model: "inherit", reasoning: "inherit", spawn: "fresh", persona: "Investigate primary sources and cite the evidence." },
|
|
@@ -1807,6 +1908,8 @@ function OptimizationPrototype({ locale, catalog, catalogError, onPreview, prese
|
|
|
1807
1908
|
const [configDraft, setConfigDraft] = import_react9.default.useState();
|
|
1808
1909
|
const configOverrides = configDraft ?? defaults;
|
|
1809
1910
|
const [request, setRequest] = import_react9.default.useState();
|
|
1911
|
+
const [hiddenFromSubagents, setHiddenFromSubagents] = import_react9.default.useState([]);
|
|
1912
|
+
const selectable = (names2) => names2.filter((name2) => provided.includes(name2) && name2 !== ROLE_TOOL);
|
|
1810
1913
|
const [saving, setSaving] = import_react9.default.useState(false);
|
|
1811
1914
|
const [saveError, setSaveError] = import_react9.default.useState("");
|
|
1812
1915
|
const save = async () => {
|
|
@@ -1814,7 +1917,7 @@ function OptimizationPrototype({ locale, catalog, catalogError, onPreview, prese
|
|
|
1814
1917
|
setSaving(true);
|
|
1815
1918
|
setSaveError("");
|
|
1816
1919
|
try {
|
|
1817
|
-
await presetActions.save(JSON.stringify({ ...editing?.id ? { id: editing.id } : {}, name: name.trim(), description, request: { ...request, configOverrides }, conveniences: { spill: common.spill }, agents }));
|
|
1920
|
+
await presetActions.save(JSON.stringify({ ...editing?.id ? { id: editing.id } : {}, name: name.trim(), description, request: { ...withoutSubagentFilter(request), configOverrides, ...selectable(hiddenFromSubagents).length ? { subagentToolFilter: { deny: selectable(hiddenFromSubagents) } } : {} }, conveniences: { spill: common.spill }, agents: agents.map((role) => role.toolFilter ? { ...role, toolFilter: { ...role.toolFilter, deny: selectable(role.toolFilter.deny) } } : role) }));
|
|
1818
1921
|
setRevision((n) => n + 1);
|
|
1819
1922
|
setPage("list");
|
|
1820
1923
|
setName("");
|
|
@@ -1823,6 +1926,7 @@ function OptimizationPrototype({ locale, catalog, catalogError, onPreview, prese
|
|
|
1823
1926
|
setCommon({ ...initial });
|
|
1824
1927
|
setProvided([]);
|
|
1825
1928
|
setAgents(seeds.map((a) => ({ ...a })));
|
|
1929
|
+
setHiddenFromSubagents([]);
|
|
1826
1930
|
setEditing(void 0);
|
|
1827
1931
|
setTab("tools");
|
|
1828
1932
|
setDraftKey((n) => n + 1);
|
|
@@ -1841,6 +1945,7 @@ function OptimizationPrototype({ locale, catalog, catalogError, onPreview, prese
|
|
|
1841
1945
|
setConfigDraft(item.request.configOverrides ?? {});
|
|
1842
1946
|
setAgents(item.agents.map((role) => ({ ...role })));
|
|
1843
1947
|
setRequest(item.request);
|
|
1948
|
+
setHiddenFromSubagents([...item.request.subagentToolFilter?.deny ?? []]);
|
|
1844
1949
|
setDraftKey((n) => n + 1);
|
|
1845
1950
|
setPage("create");
|
|
1846
1951
|
};
|
|
@@ -1848,7 +1953,9 @@ function OptimizationPrototype({ locale, catalog, catalogError, onPreview, prese
|
|
|
1848
1953
|
const presetPersona = request?.providerConfigs?.[persona]?.prefix;
|
|
1849
1954
|
const masterPersona = catalog?.presets?.find((p) => p.id === (request?.preset ?? "studio-master"))?.promptProviders?.find((p) => p.name === persona)?.fields?.find((f) => f.key === "prefix")?.value;
|
|
1850
1955
|
const defaultPersona = typeof presetPersona === "string" ? presetPersona : typeof masterPersona === "string" ? masterPersona : "";
|
|
1851
|
-
const
|
|
1956
|
+
const toolChoices = (catalog?.tools ?? []).filter((tool) => provided.includes(tool.name) && tool.name !== ROLE_TOOL).map((tool) => ({ name: tool.name, description: tool.description }));
|
|
1957
|
+
const delegates = provided.some((name2) => name2 === ROLE_TOOL || GENERIC_DELEGATION_TOOLS.includes(name2));
|
|
1958
|
+
const agentPage = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RoleEditor, { locale, roles: agents, onChange: setAgents, loadModels: presetActions?.models, defaultPersona, tools: toolChoices, hiddenTools: hiddenFromSubagents, onHiddenToolsChange: setHiddenFromSubagents, delegates }, draftKey);
|
|
1852
1959
|
const tabs = [
|
|
1853
1960
|
{ id: "tools", label: t("\uD504\uB86C\uD504\uD2B8\xB7\uB3C4\uAD6C", "Prompts & tools", "\u63D0\u793A\u8BCD\u4E0E\u5DE5\u5177"), content: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PromptToolsPrototype, { initialRequest: editing?.request, locale, catalog, catalogError, onPreview: onPreview ? (request2) => onPreview({ ...request2, configOverrides }) : void 0, onRequestChange: setRequest, prompt: common.prompt, onPromptChange: (value) => setCommon((c) => ({ ...c, prompt: value })), provided, onProvidedChange: setProvided }, draftKey) },
|
|
1854
1961
|
{ id: "convenience", label: t("\uC2E4\uD589 \uC124\uC815", "Execution settings", "\u6267\u884C\u8BBE\u7F6E"), content: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
@@ -1858,7 +1965,7 @@ function OptimizationPrototype({ locale, catalog, catalogError, onPreview, prese
|
|
|
1858
1965
|
{ id: "agents", label: t("\uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8", "Subagent settings", "\u5B50\u4EE3\u7406\u8BBE\u7F6E"), content: agentPage }
|
|
1859
1966
|
];
|
|
1860
1967
|
const tabId = import_react9.default.useId();
|
|
1861
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DetailLayout, { title: "DSH Studio", subtitle: t("\uC5D0\uC774\uC804\uD2B8 \uD504\uB9AC\uC14B \uD3B8\uC9D1\uAE30", "Agent preset editor", "\u4EE3\u7406\u9884\u8BBE\u7F16\u8F91\u5668"), navigation: t("Studio \uBA54\uB274", "
|
|
1968
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DetailLayout, { title: "DSH Studio", subtitle: t("\uC5D0\uC774\uC804\uD2B8 \uD504\uB9AC\uC14B \uD3B8\uC9D1\uAE30", "Agent preset editor", "\u4EE3\u7406\u9884\u8BBE\u7F16\u8F91\u5668"), navigation: t("Studio \uBA54\uB274", "Studio menu", "\u9884\u8BBE\u5BFC\u822A"), selected: page, onSelect: (next) => {
|
|
1862
1969
|
if (next === "create" && editing) {
|
|
1863
1970
|
setEditing(void 0);
|
|
1864
1971
|
setName("");
|
|
@@ -1873,7 +1980,7 @@ function OptimizationPrototype({ locale, catalog, catalogError, onPreview, prese
|
|
|
1873
1980
|
}, pages: [
|
|
1874
1981
|
{ id: "list", group: t("\uD504\uB9AC\uC14B", "Presets", "\u9884\u8BBE"), label: t("\uD504\uB9AC\uC14B \uBAA9\uB85D", "Preset list", "\u9884\u8BBE\u5217\u8868"), content: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PresetList, { locale, api: presetActions, revision, onEdit: (item) => editPreset(item), onCopy: (item) => editPreset(item, true) }) },
|
|
1875
1982
|
{ id: "create", group: t("\uD504\uB9AC\uC14B", "Presets", "\u9884\u8BBE"), label: editing ? t("\uD504\uB9AC\uC14B \uD3B8\uC9D1", "Edit preset", "\u7F16\u8F91\u9884\u8BBE") : t("\uD504\uB9AC\uC14B \uB9CC\uB4E4\uAE30", "Create preset", "\u521B\u5EFA\u9884\u8BBE"), content: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "studio-page-stack", children: [
|
|
1876
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PageHead, { title: editing ? t("\uD504\uB9AC\uC14B \uD3B8\uC9D1", "Edit preset", "\u7F16\u8F91\u9884\u8BBE") : t("\uD504\uB9AC\uC14B \uB9CC\uB4E4\uAE30", "Create preset", "\u521B\u5EFA\u9884\u8BBE"), description: editing ? t("\uC800\uC7A5\
|
|
1983
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PageHead, { title: editing ? t("\uD504\uB9AC\uC14B \uD3B8\uC9D1", "Edit preset", "\u7F16\u8F91\u9884\u8BBE") : t("\uD504\uB9AC\uC14B \uB9CC\uB4E4\uAE30", "Create preset", "\u521B\u5EFA\u9884\u8BBE"), description: editing ? t("\uC800\uC7A5 \uD6C4 \uC0C8 \uC138\uC158\uC5D0 \uC801\uC6A9\uD558\uB824\uBA74 \uD504\uB9AC\uC14B \uBAA9\uB85D\uC5D0\uC11C DSH\uC5D0 \uBC18\uC601\uD574 \uC8FC\uC138\uC694. \uC774\uBBF8 \uC2E4\uD589 \uC911\uC778 \uC138\uC158\uC5D0\uB294 \uBCC0\uACBD \uC0AC\uD56D\uC774 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.", "After saving, apply to DSH from the preset list to use these settings in new sessions. Changes do not affect sessions that are already running.", "\u4FDD\u5B58\u540E\uFF0C\u8BF7\u5728\u9884\u8BBE\u5217\u8868\u4E2D\u5E94\u7528\u5230 DSH\uFF0C\u4EE5\u4FBF\u5728\u65B0\u4F1A\u8BDD\u4E2D\u4F7F\u7528\u8FD9\u4E9B\u8BBE\u7F6E\u3002\u66F4\u6539\u4E0D\u4F1A\u5F71\u54CD\u6B63\u5728\u8FD0\u884C\u7684\u4F1A\u8BDD\u3002") : t("\uD504\uB86C\uD504\uD2B8, \uB3C4\uAD6C, \uC2E4\uD589 \uC124\uC815, \uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8\uB97C \uAD6C\uC131\uD574 \uC0C8 \uD504\uB9AC\uC14B\uC73C\uB85C \uC800\uC7A5\uD569\uB2C8\uB2E4.", "Configure prompts, tools, execution settings and subagents, then save a new preset.", "\u914D\u7F6E\u5DE5\u5177\u3001\u6267\u884C\u8BBE\u7F6E\u548C\u5B50\u4EE3\u7406\u89D2\u8272\uFF0C\u5E76\u4FDD\u5B58\u4E3A\u65B0\u9884\u8BBE"), actions: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Button, { primary: true, disabled: saving || !presetActions || !request || !name.trim(), onClick: () => void save(), children: saving ? t("\uC800\uC7A5 \uC911\u2026", "Saving\u2026", "\u4FDD\u5B58\u4E2D\u2026") : t("\uD504\uB9AC\uC14B \uC800\uC7A5", "Save preset", "\u4FDD\u5B58\u9884\u8BBE") }) }),
|
|
1877
1984
|
saveError && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Notice, { children: t(`\uD504\uB9AC\uC14B\uC744 \uC800\uC7A5\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uD3B8\uC9D1\uD55C \uB0B4\uC6A9\uC740 \uD654\uBA74\uC5D0 \uADF8\uB300\uB85C \uC788\uC2B5\uB2C8\uB2E4. (${saveError})`, `Could not save the preset. Your edits remain on this screen. (${saveError})`, `\u65E0\u6CD5\u4FDD\u5B58\u9884\u8BBE\uFF0C\u7F16\u8F91\u5185\u5BB9\u4ECD\u4FDD\u7559\u5728\u6B64\u9875\u9762\uFF08${saveError}\uFF09`) }),
|
|
1878
1985
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "studio-identity", children: [
|
|
1879
1986
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "studio-field studio-identity-name", children: [
|