dsh-prime-memory 0.24.2 → 0.26.0
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.en.md +28 -0
- package/CHANGELOG.ja.md +29 -0
- package/CHANGELOG.ko.md +29 -0
- package/CHANGELOG.md +30 -0
- package/dist/client.js +907 -654
- package/dist/config.d.ts +47 -2
- package/dist/config.js +30 -2
- package/dist/contract.d.ts +107 -1
- package/dist/keyword-backfill.d.ts +75 -0
- package/dist/keyword-backfill.js +218 -0
- package/dist/metadata-validators.d.ts +9 -0
- package/dist/metadata-validators.js +31 -0
- package/dist/pipeline/relabel.d.ts +11 -12
- package/dist/pipeline/relabel.js +54 -66
- package/dist/pipeline/runner.js +24 -1
- package/dist/projection/recall.d.ts +3 -2
- package/dist/projection/recall.js +26 -5
- package/dist/projection/slots.d.ts +11 -0
- package/dist/projection/slots.js +13 -3
- package/dist/redistill-backfill.d.ts +133 -0
- package/dist/redistill-backfill.js +352 -0
- package/dist/room-review.d.ts +12 -13
- package/dist/room-review.js +37 -29
- package/dist/settings.js +13 -0
- package/dist/stats.js +126 -14
- package/dist/store/l1.d.ts +18 -0
- package/dist/store/l1.js +17 -0
- package/dist/store/memory-backend-worker.d.ts +1 -0
- package/dist/store/memory-backend-worker.js +3 -0
- package/dist/store/memory-backend.d.ts +3 -0
- package/dist/store/memory-backend.js +3 -0
- package/dist/store/memory-md.d.ts +8 -0
- package/dist/store/memory-md.js +13 -2
- package/dist/store/memory-worker.js +3 -0
- package/dist/store/sqlite.d.ts +28 -0
- package/dist/store/sqlite.js +66 -0
- package/dist/wing-backfill.d.ts +16 -14
- package/dist/wing-backfill.js +76 -96
- package/dsh.plugin.json +1 -1
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -32,7 +32,7 @@ var __defProp = Object.defineProperty;
|
|
|
32
32
|
module.exports = __toCommonJS(entry_exports);
|
|
33
33
|
|
|
34
34
|
// client/src/panel.tsx
|
|
35
|
-
var
|
|
35
|
+
var import_react24 = require("react");
|
|
36
36
|
|
|
37
37
|
// client/src/sidebar-icon.ts
|
|
38
38
|
var BOOK_ICON_SVG = '<svg data-mem-icon="1" viewBox="0 0 16 16" width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" style="flex-shrink:0"><path d="M8 3.4C6.6 2.5 4.6 2.4 2.9 3.1v9.3c1.7-.7 3.7-.6 5.1.3 1.4-.9 3.4-1 5.1-.3V3.1C11.4 2.4 9.4 2.5 8 3.4Z" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/><path d="M8 3.4v9.3" stroke="currentColor" stroke-width="1.2"/></svg>';
|
|
@@ -1243,29 +1243,6 @@ var __defProp = Object.defineProperty;
|
|
|
1243
1243
|
] })
|
|
1244
1244
|
] });
|
|
1245
1245
|
}
|
|
1246
|
-
function ActionButton(props) {
|
|
1247
|
-
const disabled = !!props.disabled;
|
|
1248
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1249
|
-
"button",
|
|
1250
|
-
{
|
|
1251
|
-
type: "button",
|
|
1252
|
-
title: props.disabled ? "" : props.title || "",
|
|
1253
|
-
"aria-disabled": disabled,
|
|
1254
|
-
onClick: () => {
|
|
1255
|
-
if (!disabled && props.onClick) props.onClick();
|
|
1256
|
-
},
|
|
1257
|
-
style: {
|
|
1258
|
-
...S.seg,
|
|
1259
|
-
...S.segBtn,
|
|
1260
|
-
fontFamily: "inherit",
|
|
1261
|
-
border: "1px solid var(--dsh-mem-border)",
|
|
1262
|
-
cursor: disabled ? "not-allowed" : "pointer",
|
|
1263
|
-
...disabled ? S.switchDisabled : null
|
|
1264
|
-
},
|
|
1265
|
-
children: props.label
|
|
1266
|
-
}
|
|
1267
|
-
);
|
|
1268
|
-
}
|
|
1269
1246
|
function Segmented(props) {
|
|
1270
1247
|
const value = props.value;
|
|
1271
1248
|
const disabled = !!props.disabled;
|
|
@@ -1637,7 +1614,7 @@ var __defProp = Object.defineProperty;
|
|
|
1637
1614
|
}
|
|
1638
1615
|
|
|
1639
1616
|
// client/src/tabs/OverviewTab.tsx
|
|
1640
|
-
var
|
|
1617
|
+
var import_react17 = require("react");
|
|
1641
1618
|
|
|
1642
1619
|
// client/src/pill/modes.ts
|
|
1643
1620
|
var MODES = [
|
|
@@ -2078,7 +2055,7 @@ var __defProp = Object.defineProperty;
|
|
|
2078
2055
|
const showInput = scope === "all" || scope === "input";
|
|
2079
2056
|
const effNote = layers.map((l) => eff[l[0]] || "?").join(" / ");
|
|
2080
2057
|
const rowLabel = (key) => key === "extract" ? "抽取输出" : key === "dedup" ? "去重输出" : key === "l2" ? "L2 输出" : "L3 输出";
|
|
2081
|
-
const
|
|
2058
|
+
const rowStyle = { display: "flex", alignItems: "center", gap: 8 };
|
|
2082
2059
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
|
|
2083
2060
|
showOutputs ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginTop: 12 }, children: [
|
|
2084
2061
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
@@ -2089,7 +2066,7 @@ var __defProp = Object.defineProperty;
|
|
|
2089
2066
|
children: "输出预算"
|
|
2090
2067
|
}
|
|
2091
2068
|
),
|
|
2092
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 4 }, children: layers.map((l) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style:
|
|
2069
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 4 }, children: layers.map((l) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: rowStyle, children: [
|
|
2093
2070
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { width: 68, flexShrink: 0, fontSize: 12, color: "var(--dsh-mem-text-2)" }, children: rowLabel(l[0]) }),
|
|
2094
2071
|
inputBox(
|
|
2095
2072
|
l[0],
|
|
@@ -2111,7 +2088,7 @@ var __defProp = Object.defineProperty;
|
|
|
2111
2088
|
children: "输入预算"
|
|
2112
2089
|
}
|
|
2113
2090
|
),
|
|
2114
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style:
|
|
2091
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: rowStyle, children: [
|
|
2115
2092
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { width: 68, flexShrink: 0, fontSize: 12, color: "var(--dsh-mem-text-2)" }, children: "单次输入" }),
|
|
2116
2093
|
inputBox(
|
|
2117
2094
|
"input",
|
|
@@ -3715,14 +3692,284 @@ var __defProp = Object.defineProperty;
|
|
|
3715
3692
|
] });
|
|
3716
3693
|
}
|
|
3717
3694
|
|
|
3718
|
-
// client/src/tabs/
|
|
3695
|
+
// client/src/tabs/BackfillSection.tsx
|
|
3696
|
+
var import_react16 = require("react");
|
|
3719
3697
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3698
|
+
function BackfillSection(props) {
|
|
3699
|
+
const rpc = props.rpc;
|
|
3700
|
+
const [overview, setOverview] = (0, import_react16.useState)(null);
|
|
3701
|
+
const [wingBusy, setWingBusy] = (0, import_react16.useState)(false);
|
|
3702
|
+
const [kwBusy, setKwBusy] = (0, import_react16.useState)(false);
|
|
3703
|
+
const [kwSummary, setKwSummary] = (0, import_react16.useState)(null);
|
|
3704
|
+
const [kwProgress, setKwProgress] = (0, import_react16.useState)(null);
|
|
3705
|
+
const [kwCounts, setKwCounts] = (0, import_react16.useState)(null);
|
|
3706
|
+
const [rdBusy, setRdBusy] = (0, import_react16.useState)(false);
|
|
3707
|
+
const [rdSummary, setRdSummary] = (0, import_react16.useState)(null);
|
|
3708
|
+
const [rdProgress, setRdProgress] = (0, import_react16.useState)(null);
|
|
3709
|
+
const [rdCounts, setRdCounts] = (0, import_react16.useState)(null);
|
|
3710
|
+
const [err, setErr] = (0, import_react16.useState)(null);
|
|
3711
|
+
const timersRef = (0, import_react16.useRef)([]);
|
|
3712
|
+
(0, import_react16.useEffect)(
|
|
3713
|
+
() => () => {
|
|
3714
|
+
for (const t of timersRef.current) window.clearTimeout(t);
|
|
3715
|
+
},
|
|
3716
|
+
[]
|
|
3717
|
+
);
|
|
3718
|
+
const refreshOverview = (0, import_react16.useCallback)(() => {
|
|
3719
|
+
rpc("dsh-memory/wing-overview", {}).then((r) => {
|
|
3720
|
+
if (r && r.ok) setOverview(r.value);
|
|
3721
|
+
}).catch(() => {
|
|
3722
|
+
});
|
|
3723
|
+
}, [rpc]);
|
|
3724
|
+
(0, import_react16.useEffect)(() => {
|
|
3725
|
+
refreshOverview();
|
|
3726
|
+
}, [refreshOverview]);
|
|
3727
|
+
ensureThemeStyle();
|
|
3728
|
+
const POLL_CAP = 400;
|
|
3729
|
+
const fmtProgress = (p, verb, counts) => {
|
|
3730
|
+
if (!p) return `${verb}中…`;
|
|
3731
|
+
if (p.scanning || p.candidates === 0) return `${verb}中:正在扫描存量、筛出需${verb}的记录…`;
|
|
3732
|
+
const parts = [
|
|
3733
|
+
`${verb}中:真目标 ${p.candidates} 条`,
|
|
3734
|
+
`已完成 ${p.processed} 条`,
|
|
3735
|
+
p.batchTotal > 0 ? `第 ${Math.min(p.batchesDone + 1, p.batchTotal)}/${p.batchTotal} 条` : "",
|
|
3736
|
+
p.concurrency > 1 ? `并行 ${p.concurrency}` : "串行",
|
|
3737
|
+
(counts?.failed ?? 0) > 0 ? `失败 ${counts.failed} 条` : ""
|
|
3738
|
+
].filter(Boolean);
|
|
3739
|
+
const outcome = counts ? `(写回 ${counts.updated ?? 0}${counts.skipped !== void 0 ? ` / 留原文 ${counts.skipped}` : ""})` : "";
|
|
3740
|
+
return parts.join(" · ") + outcome;
|
|
3741
|
+
};
|
|
3742
|
+
const tail = (p) => p && p.deferred > 0 ? `,本次未跑完、剩 ${p.deferred} 条待再点一次` : "";
|
|
3743
|
+
const wingBackfill = (mode = "start") => {
|
|
3744
|
+
if (wingBusy) return;
|
|
3745
|
+
if (mode === "start" && (!overview || overview.unlabeled === 0)) return;
|
|
3746
|
+
if (mode === "start") setWingBusy(true);
|
|
3747
|
+
setErr(null);
|
|
3748
|
+
let polls = 0;
|
|
3749
|
+
const finish = () => setWingBusy(false);
|
|
3750
|
+
const tick = () => {
|
|
3751
|
+
polls++;
|
|
3752
|
+
rpc("dsh-memory/wing-overview", {}).then((r) => {
|
|
3753
|
+
const v = r && r.ok ? r.value : null;
|
|
3754
|
+
if (v) setOverview(v);
|
|
3755
|
+
if (v && v.unlabeled === 0 || polls >= POLL_CAP) finish();
|
|
3756
|
+
else timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3757
|
+
}).catch(() => finish());
|
|
3758
|
+
};
|
|
3759
|
+
rpc("dsh-memory/wing-backfill", mode === "resume" ? { probe: true } : {}).then((r) => {
|
|
3760
|
+
if (!r || !r.ok) {
|
|
3761
|
+
if (mode === "resume") return finish();
|
|
3762
|
+
setErr(r && r.error ? "回填失败:" + r.error.message : "回填失败");
|
|
3763
|
+
finish();
|
|
3764
|
+
return;
|
|
3765
|
+
}
|
|
3766
|
+
if (mode === "resume") {
|
|
3767
|
+
if (!(r.value && r.value.running)) return;
|
|
3768
|
+
setWingBusy(true);
|
|
3769
|
+
}
|
|
3770
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3771
|
+
}).catch((e) => {
|
|
3772
|
+
if (mode === "resume") return finish();
|
|
3773
|
+
setErr("回填失败:" + String(e && e.message || e));
|
|
3774
|
+
finish();
|
|
3775
|
+
});
|
|
3776
|
+
};
|
|
3777
|
+
const keywordBackfill = (mode = "start") => {
|
|
3778
|
+
if (kwBusy) return;
|
|
3779
|
+
if (mode === "start") {
|
|
3780
|
+
setKwBusy(true);
|
|
3781
|
+
setKwSummary(null);
|
|
3782
|
+
setKwProgress(null);
|
|
3783
|
+
setKwCounts(null);
|
|
3784
|
+
}
|
|
3785
|
+
setErr(null);
|
|
3786
|
+
let polls = 0;
|
|
3787
|
+
let last = null;
|
|
3788
|
+
const finish = () => setKwBusy(false);
|
|
3789
|
+
const showResult = (v) => {
|
|
3790
|
+
const fail = v.failed ?? 0;
|
|
3791
|
+
setKwSummary(`关键词回填完成:成功 ${v.updated ?? 0} 条${fail > 0 ? `,失败 ${fail} 条` : ""}${tail(last)}`);
|
|
3792
|
+
};
|
|
3793
|
+
const failMsg = (m) => {
|
|
3794
|
+
setErr(m);
|
|
3795
|
+
finish();
|
|
3796
|
+
};
|
|
3797
|
+
const tick = () => {
|
|
3798
|
+
polls++;
|
|
3799
|
+
rpc("dsh-memory/keyword-backfill", {}).then((r) => {
|
|
3800
|
+
const v = r && r.ok ? r.value : null;
|
|
3801
|
+
if (!v) return failMsg("关键词回填失败");
|
|
3802
|
+
if (v.progress) {
|
|
3803
|
+
last = v.progress;
|
|
3804
|
+
setKwProgress(v.progress);
|
|
3805
|
+
setKwCounts({ updated: v.updated, failed: v.failed });
|
|
3806
|
+
}
|
|
3807
|
+
if (v.running) {
|
|
3808
|
+
if (polls >= POLL_CAP) {
|
|
3809
|
+
showResult(v);
|
|
3810
|
+
return finish();
|
|
3811
|
+
}
|
|
3812
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3813
|
+
return;
|
|
3814
|
+
}
|
|
3815
|
+
if (v.enabled) showResult(v);
|
|
3816
|
+
finish();
|
|
3817
|
+
}).catch(() => failMsg("关键词回填失败"));
|
|
3818
|
+
};
|
|
3819
|
+
rpc("dsh-memory/keyword-backfill", mode === "resume" ? { probe: true } : {}).then((r) => {
|
|
3820
|
+
if (!r || !r.ok) {
|
|
3821
|
+
if (mode === "resume") return;
|
|
3822
|
+
return failMsg(r && r.error ? "关键词回填失败:" + r.error.message : "关键词回填失败");
|
|
3823
|
+
}
|
|
3824
|
+
const v = r.value;
|
|
3825
|
+
if (!v) {
|
|
3826
|
+
if (mode === "resume") return;
|
|
3827
|
+
return failMsg("关键词回填失败");
|
|
3828
|
+
}
|
|
3829
|
+
if (mode === "resume") {
|
|
3830
|
+
if (!v.running) return;
|
|
3831
|
+
if (v.progress) {
|
|
3832
|
+
last = v.progress;
|
|
3833
|
+
setKwProgress(v.progress);
|
|
3834
|
+
setKwCounts({ updated: v.updated, failed: v.failed });
|
|
3835
|
+
}
|
|
3836
|
+
setKwBusy(true);
|
|
3837
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3838
|
+
return;
|
|
3839
|
+
}
|
|
3840
|
+
if (!v.enabled) return failMsg("关键词回填未开启:请先在概览开关组打开关键词回填");
|
|
3841
|
+
if (v.progress) {
|
|
3842
|
+
last = v.progress;
|
|
3843
|
+
setKwProgress(v.progress);
|
|
3844
|
+
setKwCounts({ updated: v.updated, failed: v.failed });
|
|
3845
|
+
}
|
|
3846
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3847
|
+
}).catch((e) => {
|
|
3848
|
+
if (mode === "resume") return;
|
|
3849
|
+
failMsg("关键词回填失败:" + String(e && e.message || e));
|
|
3850
|
+
});
|
|
3851
|
+
};
|
|
3852
|
+
const redistillBackfill = (mode = "start") => {
|
|
3853
|
+
if (rdBusy) return;
|
|
3854
|
+
if (mode === "start") {
|
|
3855
|
+
setRdBusy(true);
|
|
3856
|
+
setRdSummary(null);
|
|
3857
|
+
setRdProgress(null);
|
|
3858
|
+
setRdCounts(null);
|
|
3859
|
+
}
|
|
3860
|
+
setErr(null);
|
|
3861
|
+
let polls = 0;
|
|
3862
|
+
let last = null;
|
|
3863
|
+
const finish = () => setRdBusy(false);
|
|
3864
|
+
const showResult = (v) => {
|
|
3865
|
+
setRdSummary(`整形完成:写回 ${v.updated ?? 0} 条,留原文 ${v.skipped ?? 0} 条${(v.failed ?? 0) > 0 ? `,失败 ${v.failed} 条` : ""}${tail(last)}`);
|
|
3866
|
+
};
|
|
3867
|
+
const failMsg = (m) => {
|
|
3868
|
+
setErr(m);
|
|
3869
|
+
finish();
|
|
3870
|
+
};
|
|
3871
|
+
const tick = () => {
|
|
3872
|
+
polls++;
|
|
3873
|
+
rpc("dsh-memory/redistill-backfill", {}).then((r) => {
|
|
3874
|
+
const v = r && r.ok ? r.value : null;
|
|
3875
|
+
if (!v) return failMsg("重蒸馏整形失败");
|
|
3876
|
+
if (v.progress) {
|
|
3877
|
+
last = v.progress;
|
|
3878
|
+
setRdProgress(v.progress);
|
|
3879
|
+
setRdCounts({ updated: v.updated, skipped: v.skipped, failed: v.failed });
|
|
3880
|
+
}
|
|
3881
|
+
if (v.running) {
|
|
3882
|
+
if (polls >= POLL_CAP) {
|
|
3883
|
+
showResult(v);
|
|
3884
|
+
return finish();
|
|
3885
|
+
}
|
|
3886
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3887
|
+
return;
|
|
3888
|
+
}
|
|
3889
|
+
if (v.enabled) showResult(v);
|
|
3890
|
+
finish();
|
|
3891
|
+
}).catch(() => failMsg("重蒸馏整形失败"));
|
|
3892
|
+
};
|
|
3893
|
+
rpc("dsh-memory/redistill-backfill", mode === "resume" ? { probe: true } : {}).then((r) => {
|
|
3894
|
+
if (!r || !r.ok) {
|
|
3895
|
+
if (mode === "resume") return;
|
|
3896
|
+
return failMsg(r && r.error ? "重蒸馏整形失败:" + r.error.message : "重蒸馏整形失败");
|
|
3897
|
+
}
|
|
3898
|
+
const v = r.value;
|
|
3899
|
+
if (!v) {
|
|
3900
|
+
if (mode === "resume") return;
|
|
3901
|
+
return failMsg("重蒸馏整形失败");
|
|
3902
|
+
}
|
|
3903
|
+
if (mode === "resume") {
|
|
3904
|
+
if (!v.running) return;
|
|
3905
|
+
if (v.progress) {
|
|
3906
|
+
last = v.progress;
|
|
3907
|
+
setRdProgress(v.progress);
|
|
3908
|
+
setRdCounts({ updated: v.updated, skipped: v.skipped, failed: v.failed });
|
|
3909
|
+
}
|
|
3910
|
+
setRdBusy(true);
|
|
3911
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3912
|
+
return;
|
|
3913
|
+
}
|
|
3914
|
+
if (!v.enabled) return failMsg("重蒸馏整形未开启:请先在概览开关组打开重蒸馏整形");
|
|
3915
|
+
if (v.progress) {
|
|
3916
|
+
last = v.progress;
|
|
3917
|
+
setRdProgress(v.progress);
|
|
3918
|
+
setRdCounts({ updated: v.updated, skipped: v.skipped, failed: v.failed });
|
|
3919
|
+
}
|
|
3920
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3921
|
+
}).catch((e) => {
|
|
3922
|
+
if (mode === "resume") return;
|
|
3923
|
+
failMsg("重蒸馏整形失败:" + String(e && e.message || e));
|
|
3924
|
+
});
|
|
3925
|
+
};
|
|
3926
|
+
(0, import_react16.useEffect)(() => {
|
|
3927
|
+
keywordBackfill("resume");
|
|
3928
|
+
redistillBackfill("resume");
|
|
3929
|
+
wingBackfill("resume");
|
|
3930
|
+
}, []);
|
|
3931
|
+
const rowStyle = {
|
|
3932
|
+
display: "flex",
|
|
3933
|
+
alignItems: "center",
|
|
3934
|
+
gap: 10,
|
|
3935
|
+
flexWrap: "wrap",
|
|
3936
|
+
padding: "8px 0"
|
|
3937
|
+
};
|
|
3938
|
+
const hintStyle = { flex: 1, minWidth: 180, fontSize: 12, color: "var(--dsh-mem-text-3)" };
|
|
3939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "dsh-mem-rb-card", style: { padding: "4px 14px", marginTop: 12 }, children: [
|
|
3940
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { fontWeight: 600, padding: "8px 0 2px" }, children: "存量回填与整形" }),
|
|
3941
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: rowStyle, children: [
|
|
3942
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: hintStyle, children: overview ? `对存量未打标记忆批量补打 wing 标签 · 未打标 ${overview.unlabeled} 条` : "未打标计数加载中…" }),
|
|
3943
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3944
|
+
NButton,
|
|
3945
|
+
{
|
|
3946
|
+
disabled: !overview || overview.unlabeled === 0 || wingBusy,
|
|
3947
|
+
style: { color: "var(--dsh-mem-accent)" },
|
|
3948
|
+
onClick: () => wingBackfill(),
|
|
3949
|
+
children: wingBusy ? "回填中…" : "wing 回填"
|
|
3950
|
+
}
|
|
3951
|
+
)
|
|
3952
|
+
] }),
|
|
3953
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: rowStyle, children: [
|
|
3954
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: hintStyle, children: kwBusy ? fmtProgress(kwProgress, "回填", kwCounts ?? void 0) : kwSummary || "为缺 dsh_keywords 的存量记忆补检索关键词,喂 FTS 关键词轴(需先开关键词回填开关)" }),
|
|
3955
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(NButton, { disabled: kwBusy, style: { color: "var(--dsh-mem-accent)" }, onClick: () => keywordBackfill(), children: kwBusy ? "回填中…" : "关键词回填" })
|
|
3956
|
+
] }),
|
|
3957
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: rowStyle, children: [
|
|
3958
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: hintStyle, children: rdBusy ? fmtProgress(rdProgress, "整形", rdCounts ?? void 0) : rdSummary || "把“平”的存量记忆按类型重排成分节骨架,顺带产关键词/情景;只有严格更优才写回(需先开重蒸馏整形开关)" }),
|
|
3959
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(NButton, { disabled: rdBusy, style: { color: "var(--dsh-mem-accent)" }, onClick: () => redistillBackfill(), children: rdBusy ? "整形中…" : "重蒸馏整形" })
|
|
3960
|
+
] }),
|
|
3961
|
+
err ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { padding: "6px 0", fontSize: 12, color: "var(--dsh-mem-danger)" }, children: err }) : null
|
|
3962
|
+
] });
|
|
3963
|
+
}
|
|
3964
|
+
|
|
3965
|
+
// client/src/tabs/OverviewTab.tsx
|
|
3966
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3720
3967
|
function OverviewTab(props) {
|
|
3721
3968
|
const rpc = props.rpc;
|
|
3722
|
-
const [stats, setStats] = (0,
|
|
3723
|
-
const [settingsData, setSettingsData] = (0,
|
|
3724
|
-
const [error, setError] = (0,
|
|
3725
|
-
const load = (0,
|
|
3969
|
+
const [stats, setStats] = (0, import_react17.useState)(null);
|
|
3970
|
+
const [settingsData, setSettingsData] = (0, import_react17.useState)(null);
|
|
3971
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
3972
|
+
const load = (0, import_react17.useCallback)(() => {
|
|
3726
3973
|
rpc("dsh-memory/stats", {}).then((r) => {
|
|
3727
3974
|
if (r && r.ok) setStats(r.value);
|
|
3728
3975
|
else setError(r && r.error ? r.error.message : "RPC error");
|
|
@@ -3734,7 +3981,7 @@ var __defProp = Object.defineProperty;
|
|
|
3734
3981
|
}).catch(() => {
|
|
3735
3982
|
});
|
|
3736
3983
|
}, [rpc]);
|
|
3737
|
-
(0,
|
|
3984
|
+
(0, import_react17.useEffect)(() => {
|
|
3738
3985
|
load();
|
|
3739
3986
|
const timer = setInterval(load, 5e3);
|
|
3740
3987
|
return () => {
|
|
@@ -3759,6 +4006,23 @@ var __defProp = Object.defineProperty;
|
|
|
3759
4006
|
setError("开关写入失败:" + String(e && e.message || e));
|
|
3760
4007
|
});
|
|
3761
4008
|
};
|
|
4009
|
+
const setNum = (key, value) => {
|
|
4010
|
+
if (!settingsData) return;
|
|
4011
|
+
const prev = settingsData;
|
|
4012
|
+
const next = { ...prev, settings: { ...prev.settings, [key]: value } };
|
|
4013
|
+
setSettingsData(next);
|
|
4014
|
+
rpc("dsh-memory/settings-set", { [key]: value }).then((r) => {
|
|
4015
|
+
if (!r || !r.ok) {
|
|
4016
|
+
setSettingsData(prev);
|
|
4017
|
+
setError(r && r.error ? "并行度写入失败:" + r.error.message : "并行度写入失败");
|
|
4018
|
+
} else {
|
|
4019
|
+
setError(null);
|
|
4020
|
+
}
|
|
4021
|
+
}).catch((e) => {
|
|
4022
|
+
setSettingsData(prev);
|
|
4023
|
+
setError("并行度写入失败:" + String(e && e.message || e));
|
|
4024
|
+
});
|
|
4025
|
+
};
|
|
3762
4026
|
const tiles = [];
|
|
3763
4027
|
const infos = [];
|
|
3764
4028
|
if (stats) {
|
|
@@ -3796,10 +4060,15 @@ var __defProp = Object.defineProperty;
|
|
|
3796
4060
|
const toolConflict = settingsData && settingsData.settings ? settingsData.settings.toolConflict !== false : true;
|
|
3797
4061
|
const toolMutate = settingsData && settingsData.settings ? settingsData.settings.toolMutate !== false : true;
|
|
3798
4062
|
const skillsEnabled = settingsData && settingsData.settings ? settingsData.settings.skillsEnabled === true : false;
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
4063
|
+
const keywordEnabled = settingsData && settingsData.settings ? settingsData.settings.keywordEnabled === true : false;
|
|
4064
|
+
const redistillEnabled = settingsData && settingsData.settings ? settingsData.settings.redistillEnabled === true : false;
|
|
4065
|
+
const mdSyncEnabled = settingsData && settingsData.settings ? settingsData.settings.mdSyncEnabled === true : false;
|
|
4066
|
+
const memportEnabled = settingsData && settingsData.settings ? settingsData.settings.memportEnabled === true : false;
|
|
4067
|
+
const bfConcurrency = settingsData && settingsData.settings ? settingsData.settings.backfillConcurrency ?? 0 : 0;
|
|
4068
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
|
|
4069
|
+
settingsData && settingsData.supported === false ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: S.hint, children: "settings 服务不可用,记忆模式开关未启用(记忆保持全开)。" }) : settingsData ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: S.switchPanel, children: [
|
|
4070
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "记忆模式" }),
|
|
4071
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3803
4072
|
SwitchRow,
|
|
3804
4073
|
{
|
|
3805
4074
|
label: "记忆模式",
|
|
@@ -3810,7 +4079,7 @@ var __defProp = Object.defineProperty;
|
|
|
3810
4079
|
}
|
|
3811
4080
|
}
|
|
3812
4081
|
),
|
|
3813
|
-
/* @__PURE__ */ (0,
|
|
4082
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3814
4083
|
SwitchRow,
|
|
3815
4084
|
{
|
|
3816
4085
|
label: "捕获",
|
|
@@ -3822,7 +4091,7 @@ var __defProp = Object.defineProperty;
|
|
|
3822
4091
|
}
|
|
3823
4092
|
}
|
|
3824
4093
|
),
|
|
3825
|
-
/* @__PURE__ */ (0,
|
|
4094
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3826
4095
|
SwitchRow,
|
|
3827
4096
|
{
|
|
3828
4097
|
label: "蒸馏",
|
|
@@ -3834,7 +4103,7 @@ var __defProp = Object.defineProperty;
|
|
|
3834
4103
|
}
|
|
3835
4104
|
}
|
|
3836
4105
|
),
|
|
3837
|
-
/* @__PURE__ */ (0,
|
|
4106
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3838
4107
|
SwitchRow,
|
|
3839
4108
|
{
|
|
3840
4109
|
label: "召回",
|
|
@@ -3846,8 +4115,8 @@ var __defProp = Object.defineProperty;
|
|
|
3846
4115
|
}
|
|
3847
4116
|
}
|
|
3848
4117
|
),
|
|
3849
|
-
/* @__PURE__ */ (0,
|
|
3850
|
-
/* @__PURE__ */ (0,
|
|
4118
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "高权限模式" }),
|
|
4119
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3851
4120
|
SwitchRow,
|
|
3852
4121
|
{
|
|
3853
4122
|
label: "高权限模式",
|
|
@@ -3858,8 +4127,8 @@ var __defProp = Object.defineProperty;
|
|
|
3858
4127
|
}
|
|
3859
4128
|
}
|
|
3860
4129
|
),
|
|
3861
|
-
/* @__PURE__ */ (0,
|
|
3862
|
-
/* @__PURE__ */ (0,
|
|
4130
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "技能结晶" }),
|
|
4131
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3863
4132
|
SwitchRow,
|
|
3864
4133
|
{
|
|
3865
4134
|
label: "技能(程序性记忆)",
|
|
@@ -3870,8 +4139,8 @@ var __defProp = Object.defineProperty;
|
|
|
3870
4139
|
}
|
|
3871
4140
|
}
|
|
3872
4141
|
),
|
|
3873
|
-
/* @__PURE__ */ (0,
|
|
3874
|
-
/* @__PURE__ */ (0,
|
|
4142
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "工具封印" }),
|
|
4143
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3875
4144
|
SwitchRow,
|
|
3876
4145
|
{
|
|
3877
4146
|
label: "Room 管理工具",
|
|
@@ -3882,7 +4151,7 @@ var __defProp = Object.defineProperty;
|
|
|
3882
4151
|
}
|
|
3883
4152
|
}
|
|
3884
4153
|
),
|
|
3885
|
-
/* @__PURE__ */ (0,
|
|
4154
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3886
4155
|
SwitchRow,
|
|
3887
4156
|
{
|
|
3888
4157
|
label: "图谱工具",
|
|
@@ -3893,7 +4162,7 @@ var __defProp = Object.defineProperty;
|
|
|
3893
4162
|
}
|
|
3894
4163
|
}
|
|
3895
4164
|
),
|
|
3896
|
-
/* @__PURE__ */ (0,
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3897
4166
|
SwitchRow,
|
|
3898
4167
|
{
|
|
3899
4168
|
label: "反刍工具",
|
|
@@ -3904,7 +4173,7 @@ var __defProp = Object.defineProperty;
|
|
|
3904
4173
|
}
|
|
3905
4174
|
}
|
|
3906
4175
|
),
|
|
3907
|
-
/* @__PURE__ */ (0,
|
|
4176
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3908
4177
|
SwitchRow,
|
|
3909
4178
|
{
|
|
3910
4179
|
label: "冲突工具",
|
|
@@ -3915,7 +4184,7 @@ var __defProp = Object.defineProperty;
|
|
|
3915
4184
|
}
|
|
3916
4185
|
}
|
|
3917
4186
|
),
|
|
3918
|
-
/* @__PURE__ */ (0,
|
|
4187
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3919
4188
|
SwitchRow,
|
|
3920
4189
|
{
|
|
3921
4190
|
label: "写删工具",
|
|
@@ -3926,8 +4195,8 @@ var __defProp = Object.defineProperty;
|
|
|
3926
4195
|
}
|
|
3927
4196
|
}
|
|
3928
4197
|
),
|
|
3929
|
-
/* @__PURE__ */ (0,
|
|
3930
|
-
/* @__PURE__ */ (0,
|
|
4198
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "人工冲突裁决" }),
|
|
4199
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3931
4200
|
SwitchRow,
|
|
3932
4201
|
{
|
|
3933
4202
|
label: "人工冲突裁决",
|
|
@@ -3938,43 +4207,110 @@ var __defProp = Object.defineProperty;
|
|
|
3938
4207
|
}
|
|
3939
4208
|
}
|
|
3940
4209
|
),
|
|
3941
|
-
/* @__PURE__ */ (0,
|
|
3942
|
-
/* @__PURE__ */ (0,
|
|
3943
|
-
|
|
4210
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "存量回填与整形" }),
|
|
4211
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4212
|
+
SwitchRow,
|
|
4213
|
+
{
|
|
4214
|
+
label: "关键词回填",
|
|
4215
|
+
desc: keywordEnabled ? "已开启:可对存量记忆批量补检索关键词(下方「存量回填与整形」区点按钮)" : "默认关闭;开启后才能跑关键词回填(喂 FTS 关键词轴)",
|
|
4216
|
+
checked: keywordEnabled,
|
|
4217
|
+
onChange: (v) => {
|
|
4218
|
+
toggle("keywordEnabled", v);
|
|
4219
|
+
}
|
|
4220
|
+
}
|
|
4221
|
+
),
|
|
4222
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4223
|
+
SwitchRow,
|
|
4224
|
+
{
|
|
4225
|
+
label: "重蒸馏整形",
|
|
4226
|
+
desc: redistillEnabled ? "已开启:可把“平”的存量记忆按类型重排成分节骨架(仅动严格更优的)" : "默认关闭;开启后才能跑重蒸馏整形(改正文会重算向量+覆盖 .memory.md)",
|
|
4227
|
+
checked: redistillEnabled,
|
|
4228
|
+
onChange: (v) => {
|
|
4229
|
+
toggle("redistillEnabled", v);
|
|
4230
|
+
}
|
|
4231
|
+
}
|
|
4232
|
+
),
|
|
4233
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, padding: "6px 0", flexWrap: "wrap" }, children: [
|
|
4234
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontSize: 13 }, children: "回填并行度" }),
|
|
4235
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4236
|
+
"input",
|
|
4237
|
+
{
|
|
4238
|
+
type: "range",
|
|
4239
|
+
min: 0,
|
|
4240
|
+
max: 8,
|
|
4241
|
+
step: 1,
|
|
4242
|
+
value: Math.min(8, bfConcurrency),
|
|
4243
|
+
onChange: (e) => {
|
|
4244
|
+
setNum("backfillConcurrency", Number(e.target.value));
|
|
4245
|
+
},
|
|
4246
|
+
style: { width: 120 }
|
|
4247
|
+
}
|
|
4248
|
+
),
|
|
4249
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)" }, children: [
|
|
4250
|
+
bfConcurrency === 0 ? "0·跟随配置(默认 1=串行)" : bfConcurrency === 1 ? "1·串行逐条" : `${bfConcurrency} 路并发`,
|
|
4251
|
+
"· 对**下一次点击**生效(正在跑的那轮不会改道)"
|
|
4252
|
+
] })
|
|
4253
|
+
] }),
|
|
4254
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4255
|
+
SwitchRow,
|
|
4256
|
+
{
|
|
4257
|
+
label: "md 反向同步",
|
|
4258
|
+
desc: mdSyncEnabled ? "已开启:可将 .memory.md 文件侧修改回灌入库(需先开 md 投射 + 高权限)" : "默认关闭;风险高于导出(会写库),需先开 md 投射再开本项",
|
|
4259
|
+
checked: mdSyncEnabled,
|
|
4260
|
+
onChange: (v) => {
|
|
4261
|
+
toggle("mdSyncEnabled", v);
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
),
|
|
4265
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4266
|
+
SwitchRow,
|
|
4267
|
+
{
|
|
4268
|
+
label: "外部记忆来源 Connect",
|
|
4269
|
+
desc: memportEnabled ? "已开启:可登记/扫描外部记忆源并导入" : "默认关闭;开启后 memport 相关端点可用",
|
|
4270
|
+
checked: memportEnabled,
|
|
4271
|
+
onChange: (v) => {
|
|
4272
|
+
toggle("memportEnabled", v);
|
|
4273
|
+
}
|
|
4274
|
+
}
|
|
4275
|
+
),
|
|
4276
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "蒸馏参数" }),
|
|
4277
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DistillSettings, { rpc, disabled: !master, data: settingsData, setData: setSettingsData, onError: setError }),
|
|
4278
|
+
ceilingNote ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: S.hint, children: ceilingNote }) : null
|
|
3944
4279
|
] }) : null,
|
|
3945
|
-
/* @__PURE__ */ (0,
|
|
3946
|
-
/* @__PURE__ */ (0,
|
|
3947
|
-
/* @__PURE__ */ (0,
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
/* @__PURE__ */ (0,
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
/* @__PURE__ */ (0,
|
|
4280
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(EmbeddingSection, { rpc }),
|
|
4281
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RebuildPanel, { rpc }),
|
|
4282
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RuminatePanel, { rpc }),
|
|
4283
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(BackfillSection, { rpc }),
|
|
4284
|
+
degraded ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { ...S.error, marginBottom: 10 }, children: "⚠ " + stats.message + "。上方数据为最后一次成功读取的值,记忆功能当前未工作。" }) : null,
|
|
4285
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.error, children: "获取状态失败:" + error }) : !stats ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: S.intro, children: "正在读取记忆状态…" }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
|
|
4286
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "记忆概况" }),
|
|
4287
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.statGrid, children: tiles.map((t) => {
|
|
4288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "dsh-mem-card", style: S.statTile, children: [
|
|
4289
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.statNum, children: t.num }),
|
|
4290
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.statLabel, children: t.label })
|
|
3955
4291
|
] }, t.label);
|
|
3956
4292
|
}) }),
|
|
3957
|
-
/* @__PURE__ */ (0,
|
|
4293
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "运行状态" }),
|
|
3958
4294
|
infos.map((row2) => {
|
|
3959
|
-
return /* @__PURE__ */ (0,
|
|
3960
|
-
/* @__PURE__ */ (0,
|
|
3961
|
-
/* @__PURE__ */ (0,
|
|
4295
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: S.infoRow, children: [
|
|
4296
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: S.infoKey, children: row2[0] }),
|
|
4297
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: S.infoVal, children: row2[1] })
|
|
3962
4298
|
] }, row2[0]);
|
|
3963
4299
|
})
|
|
3964
4300
|
] }),
|
|
3965
|
-
/* @__PURE__ */ (0,
|
|
3966
|
-
/* @__PURE__ */ (0,
|
|
4301
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ArchiveSection, { rpc }),
|
|
4302
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: S.hint, children: "浏览各层记忆内容请切换上方 Tab;原始对话(L0)不入浏览器,可由模型侧 conversation_search 工具查询。" })
|
|
3967
4303
|
] });
|
|
3968
4304
|
}
|
|
3969
4305
|
|
|
3970
4306
|
// client/src/tabs/PersonaTab.tsx
|
|
3971
|
-
var
|
|
3972
|
-
var
|
|
4307
|
+
var import_react18 = require("react");
|
|
4308
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3973
4309
|
function PersonaTab(props) {
|
|
3974
4310
|
const rpc = props.rpc;
|
|
3975
|
-
const [content, setContent] = (0,
|
|
3976
|
-
const [error, setError] = (0,
|
|
3977
|
-
const load = (0,
|
|
4311
|
+
const [content, setContent] = (0, import_react18.useState)(null);
|
|
4312
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
4313
|
+
const load = (0, import_react18.useCallback)(() => {
|
|
3978
4314
|
setError(null);
|
|
3979
4315
|
rpc("dsh-memory/persona", {}).then((r) => {
|
|
3980
4316
|
if (r && r.ok) setContent(r.value.content);
|
|
@@ -3983,23 +4319,97 @@ var __defProp = Object.defineProperty;
|
|
|
3983
4319
|
setError(String(e && e.message || e));
|
|
3984
4320
|
});
|
|
3985
4321
|
}, [rpc]);
|
|
3986
|
-
(0,
|
|
4322
|
+
(0, import_react18.useEffect)(() => {
|
|
3987
4323
|
load();
|
|
3988
4324
|
}, [load]);
|
|
3989
|
-
return /* @__PURE__ */ (0,
|
|
3990
|
-
/* @__PURE__ */ (0,
|
|
3991
|
-
/* @__PURE__ */ (0,
|
|
3992
|
-
/* @__PURE__ */ (0,
|
|
3993
|
-
/* @__PURE__ */ (0,
|
|
4325
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
|
|
4326
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
4327
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: error ? "加载失败" : content === null ? "加载中…" : content ? content.length + " 字符" : "未生成画像" }),
|
|
4328
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
|
|
4329
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
3994
4330
|
] }),
|
|
3995
|
-
error ? /* @__PURE__ */ (0,
|
|
3996
|
-
content ? /* @__PURE__ */ (0,
|
|
4331
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { ...S.error, marginBottom: 10 }, children: "画像读取失败:" + error + "(点右上“刷新”重试)" }) : null,
|
|
4332
|
+
content ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("pre", { style: S.pre, children: content }) : content === null ? null : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: S.intro, children: "画像尚未生成;蒸馏若干记忆后 L3 会自动产出。" })
|
|
3997
4333
|
] });
|
|
3998
4334
|
}
|
|
3999
4335
|
|
|
4000
4336
|
// client/src/tabs/RecordsTab.tsx
|
|
4001
|
-
var
|
|
4002
|
-
|
|
4337
|
+
var import_react20 = require("react");
|
|
4338
|
+
|
|
4339
|
+
// client/src/ui/MarkdownBody.tsx
|
|
4340
|
+
var import_react19 = require("react");
|
|
4341
|
+
var H_STYLES = [
|
|
4342
|
+
{ fontSize: 15, fontWeight: 700, margin: "8px 0 4px", color: "var(--dsh-mem-text-1)" },
|
|
4343
|
+
{ fontSize: 14, fontWeight: 600, margin: "6px 0 3px", color: "var(--dsh-mem-text-1)" },
|
|
4344
|
+
{ fontSize: 13, fontWeight: 600, margin: "5px 0 2px", color: "var(--dsh-mem-text-1)" },
|
|
4345
|
+
{ fontSize: 12, fontWeight: 600, margin: "4px 0 2px", color: "var(--dsh-mem-text-2)" },
|
|
4346
|
+
{ fontSize: 12, fontWeight: 600, margin: "3px 0 1px", color: "var(--dsh-mem-text-2)" },
|
|
4347
|
+
{ fontSize: 11, fontWeight: 600, margin: "3px 0 1px", color: "var(--dsh-mem-text-2)" }
|
|
4348
|
+
];
|
|
4349
|
+
var P2 = { margin: "2px 0", whiteSpace: "pre-wrap", wordBreak: "break-word" };
|
|
4350
|
+
var LI = { margin: "1px 0 1px 12px", whiteSpace: "pre-wrap", wordBreak: "break-word" };
|
|
4351
|
+
var CODE = {
|
|
4352
|
+
fontFamily: "ui-monospace, monospace",
|
|
4353
|
+
fontSize: "0.92em",
|
|
4354
|
+
background: "var(--dsh-mem-bg-3)",
|
|
4355
|
+
padding: "0 3px",
|
|
4356
|
+
borderRadius: 3
|
|
4357
|
+
};
|
|
4358
|
+
function inline(text, key) {
|
|
4359
|
+
const nodes = [];
|
|
4360
|
+
const re = /\*\*(.+?)\*\*|`(.+?)`/;
|
|
4361
|
+
let rest = text;
|
|
4362
|
+
let i = 0;
|
|
4363
|
+
while (rest.length > 0) {
|
|
4364
|
+
const m = re.exec(rest);
|
|
4365
|
+
if (m === null) {
|
|
4366
|
+
nodes.push(rest);
|
|
4367
|
+
break;
|
|
4368
|
+
}
|
|
4369
|
+
if (m.index > 0) nodes.push(rest.slice(0, m.index));
|
|
4370
|
+
if (m[1] !== void 0) {
|
|
4371
|
+
nodes.push((0, import_react19.createElement)("strong", { key: `${key}-b${i++}` }, m[1]));
|
|
4372
|
+
} else {
|
|
4373
|
+
nodes.push((0, import_react19.createElement)("code", { key: `${key}-c${i++}`, style: CODE }, m[2]));
|
|
4374
|
+
}
|
|
4375
|
+
rest = rest.slice(m.index + m[0].length);
|
|
4376
|
+
}
|
|
4377
|
+
return nodes;
|
|
4378
|
+
}
|
|
4379
|
+
function MarkdownBody({ text }) {
|
|
4380
|
+
const lines = text.split("\n");
|
|
4381
|
+
const out = [];
|
|
4382
|
+
let idx = 0;
|
|
4383
|
+
for (const line of lines) {
|
|
4384
|
+
const t = line.trim();
|
|
4385
|
+
if (t.length === 0) continue;
|
|
4386
|
+
const h = /^(#{1,6})\s+(.+)/.exec(t);
|
|
4387
|
+
if (h) {
|
|
4388
|
+
const lv = h[1].length;
|
|
4389
|
+
out.push((0, import_react19.createElement)(`h${lv}`, { key: `h${idx}`, style: H_STYLES[lv - 1] }, ...inline(h[2], `h${idx}`)));
|
|
4390
|
+
idx++;
|
|
4391
|
+
continue;
|
|
4392
|
+
}
|
|
4393
|
+
const ul = /^[-*]\s+(.+)/.exec(t);
|
|
4394
|
+
if (ul) {
|
|
4395
|
+
out.push((0, import_react19.createElement)("div", { key: `li${idx}`, style: LI }, "• ", ...inline(ul[1], `li${idx}`)));
|
|
4396
|
+
idx++;
|
|
4397
|
+
continue;
|
|
4398
|
+
}
|
|
4399
|
+
const ol = /^\d+\.\s+(.+)/.exec(t);
|
|
4400
|
+
if (ol) {
|
|
4401
|
+
out.push((0, import_react19.createElement)("div", { key: `li${idx}`, style: LI }, t.slice(0, t.indexOf(".") + 2), ...inline(ol[1], `li${idx}`)));
|
|
4402
|
+
idx++;
|
|
4403
|
+
continue;
|
|
4404
|
+
}
|
|
4405
|
+
out.push((0, import_react19.createElement)("div", { key: `p${idx}`, style: P2 }, ...inline(t, `p${idx}`)));
|
|
4406
|
+
idx++;
|
|
4407
|
+
}
|
|
4408
|
+
return (0, import_react19.createElement)(import_react19.Fragment, null, ...out);
|
|
4409
|
+
}
|
|
4410
|
+
|
|
4411
|
+
// client/src/tabs/RecordsTab.tsx
|
|
4412
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4003
4413
|
function retiredSelOf(r) {
|
|
4004
4414
|
if (r === "active") return false;
|
|
4005
4415
|
if (r === "retired") return true;
|
|
@@ -4009,29 +4419,29 @@ var __defProp = Object.defineProperty;
|
|
|
4009
4419
|
function RecordsTab(props) {
|
|
4010
4420
|
const rpc = props.rpc;
|
|
4011
4421
|
const limit = 50;
|
|
4012
|
-
const [items, setItems] = (0,
|
|
4013
|
-
const [hasMore, setHasMore] = (0,
|
|
4014
|
-
const [total, setTotal] = (0,
|
|
4015
|
-
const [sceneOptions, setSceneOptions] = (0,
|
|
4016
|
-
const [loading, setLoading] = (0,
|
|
4017
|
-
const [truncated, setTruncated] = (0,
|
|
4018
|
-
const [error, setError] = (0,
|
|
4019
|
-
const [expandedId, setExpandedId] = (0,
|
|
4020
|
-
const [sel, setSel] = (0,
|
|
4021
|
-
const [hiPriv, setHiPriv] = (0,
|
|
4022
|
-
const [hiPrivBusy, setHiPrivBusy] = (0,
|
|
4023
|
-
const [query, setQuery] = (0,
|
|
4024
|
-
const [typeFilter, setTypeFilter] = (0,
|
|
4025
|
-
const [sceneFilter, setSceneFilter] = (0,
|
|
4026
|
-
const [hallFilter, setHallFilter] = (0,
|
|
4027
|
-
const [tagFilter, setTagFilter] = (0,
|
|
4028
|
-
const [untaggedOnly, setUntaggedOnly] = (0,
|
|
4029
|
-
const [orphanCount, setOrphanCount] = (0,
|
|
4030
|
-
const [retiredFilter, setRetiredFilter] = (0,
|
|
4031
|
-
const [wingCatalog, setHallCatalog] = (0,
|
|
4032
|
-
const [last, setLast] = (0,
|
|
4033
|
-
const seqRef = (0,
|
|
4034
|
-
const fetchPage = (0,
|
|
4422
|
+
const [items, setItems] = (0, import_react20.useState)([]);
|
|
4423
|
+
const [hasMore, setHasMore] = (0, import_react20.useState)(false);
|
|
4424
|
+
const [total, setTotal] = (0, import_react20.useState)(null);
|
|
4425
|
+
const [sceneOptions, setSceneOptions] = (0, import_react20.useState)([]);
|
|
4426
|
+
const [loading, setLoading] = (0, import_react20.useState)(false);
|
|
4427
|
+
const [truncated, setTruncated] = (0, import_react20.useState)(false);
|
|
4428
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
4429
|
+
const [expandedId, setExpandedId] = (0, import_react20.useState)(null);
|
|
4430
|
+
const [sel, setSel] = (0, import_react20.useState)(/* @__PURE__ */ new Set());
|
|
4431
|
+
const [hiPriv, setHiPriv] = (0, import_react20.useState)(false);
|
|
4432
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react20.useState)(false);
|
|
4433
|
+
const [query, setQuery] = (0, import_react20.useState)("");
|
|
4434
|
+
const [typeFilter, setTypeFilter] = (0, import_react20.useState)("");
|
|
4435
|
+
const [sceneFilter, setSceneFilter] = (0, import_react20.useState)("");
|
|
4436
|
+
const [hallFilter, setHallFilter] = (0, import_react20.useState)([]);
|
|
4437
|
+
const [tagFilter, setTagFilter] = (0, import_react20.useState)("");
|
|
4438
|
+
const [untaggedOnly, setUntaggedOnly] = (0, import_react20.useState)(false);
|
|
4439
|
+
const [orphanCount, setOrphanCount] = (0, import_react20.useState)(0);
|
|
4440
|
+
const [retiredFilter, setRetiredFilter] = (0, import_react20.useState)("");
|
|
4441
|
+
const [wingCatalog, setHallCatalog] = (0, import_react20.useState)(null);
|
|
4442
|
+
const [last, setLast] = (0, import_react20.useState)({ query: "", type: "", scene: "", halls: [], tag: "", untagged: false, retired: "" });
|
|
4443
|
+
const seqRef = (0, import_react20.useRef)(0);
|
|
4444
|
+
const fetchPage = (0, import_react20.useCallback)(
|
|
4035
4445
|
(conds, offset, append) => {
|
|
4036
4446
|
setLoading(true);
|
|
4037
4447
|
setError(null);
|
|
@@ -4081,23 +4491,23 @@ var __defProp = Object.defineProperty;
|
|
|
4081
4491
|
setLast(conds);
|
|
4082
4492
|
fetchPage(conds, 0, false);
|
|
4083
4493
|
};
|
|
4084
|
-
const loadRooms = (0,
|
|
4494
|
+
const loadRooms = (0, import_react20.useCallback)(() => {
|
|
4085
4495
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
4086
4496
|
if (r && r.ok) setOrphanCount(r.value.orphanCount ?? 0);
|
|
4087
4497
|
}).catch(() => {
|
|
4088
4498
|
});
|
|
4089
4499
|
}, [rpc]);
|
|
4090
|
-
(0,
|
|
4500
|
+
(0, import_react20.useEffect)(() => {
|
|
4091
4501
|
fetchPage({ query: "", type: "", scene: "", halls: [], tag: "", untagged: false, retired: "" }, 0, false);
|
|
4092
4502
|
loadRooms();
|
|
4093
4503
|
}, [fetchPage, loadRooms]);
|
|
4094
|
-
const loadHiPriv = (0,
|
|
4504
|
+
const loadHiPriv = (0, import_react20.useCallback)(() => {
|
|
4095
4505
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
4096
4506
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
4097
4507
|
}).catch(() => {
|
|
4098
4508
|
});
|
|
4099
4509
|
}, [rpc]);
|
|
4100
|
-
(0,
|
|
4510
|
+
(0, import_react20.useEffect)(() => {
|
|
4101
4511
|
loadHiPriv();
|
|
4102
4512
|
}, [loadHiPriv]);
|
|
4103
4513
|
const toggleHiPriv = () => {
|
|
@@ -4161,11 +4571,11 @@ var __defProp = Object.defineProperty;
|
|
|
4161
4571
|
} else if (r) setError(r.error ? r.error.message : "退场失败");
|
|
4162
4572
|
}).catch((e) => setError(String(e && e.message || e)));
|
|
4163
4573
|
};
|
|
4164
|
-
const [retired, setRetired] = (0,
|
|
4165
|
-
const [retiredTotal, setRetiredTotal] = (0,
|
|
4166
|
-
const [showRetired, setShowRetired] = (0,
|
|
4167
|
-
const [retiredBusy, setRetiredBusy] = (0,
|
|
4168
|
-
const loadRetired = (0,
|
|
4574
|
+
const [retired, setRetired] = (0, import_react20.useState)([]);
|
|
4575
|
+
const [retiredTotal, setRetiredTotal] = (0, import_react20.useState)(0);
|
|
4576
|
+
const [showRetired, setShowRetired] = (0, import_react20.useState)(false);
|
|
4577
|
+
const [retiredBusy, setRetiredBusy] = (0, import_react20.useState)(false);
|
|
4578
|
+
const loadRetired = (0, import_react20.useCallback)(() => {
|
|
4169
4579
|
setRetiredBusy(true);
|
|
4170
4580
|
rpc("dsh-memory/records-retired", { limit: 100, offset: 0 }).then((r) => {
|
|
4171
4581
|
if (r && r.ok) {
|
|
@@ -4174,7 +4584,7 @@ var __defProp = Object.defineProperty;
|
|
|
4174
4584
|
} else if (r) setError(r.error ? r.error.message : "已退场列表加载失败");
|
|
4175
4585
|
}).catch((e) => setError(String(e && e.message || e))).finally(() => setRetiredBusy(false));
|
|
4176
4586
|
}, [rpc]);
|
|
4177
|
-
(0,
|
|
4587
|
+
(0, import_react20.useEffect)(() => {
|
|
4178
4588
|
if (showRetired) loadRetired();
|
|
4179
4589
|
}, [showRetired, loadRetired]);
|
|
4180
4590
|
const restoreRecords = (ids) => {
|
|
@@ -4198,11 +4608,11 @@ var __defProp = Object.defineProperty;
|
|
|
4198
4608
|
unknown: "已退场"
|
|
4199
4609
|
};
|
|
4200
4610
|
const countText = total !== null ? "共 " + total + " 条" : items.length + " 条" + (hasMore ? "+" : "");
|
|
4201
|
-
const [usageSummary, setUsageSummary] = (0,
|
|
4611
|
+
const [usageSummary, setUsageSummary] = (0, import_react20.useState)(null);
|
|
4202
4612
|
const selCount = sel.size;
|
|
4203
|
-
return /* @__PURE__ */ (0,
|
|
4204
|
-
/* @__PURE__ */ (0,
|
|
4205
|
-
/* @__PURE__ */ (0,
|
|
4613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
|
|
4614
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: S.toolbar, children: [
|
|
4615
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4206
4616
|
NInput,
|
|
4207
4617
|
{
|
|
4208
4618
|
style: { flex: 1, minWidth: 160 },
|
|
@@ -4225,7 +4635,7 @@ var __defProp = Object.defineProperty;
|
|
|
4225
4635
|
}
|
|
4226
4636
|
}
|
|
4227
4637
|
),
|
|
4228
|
-
/* @__PURE__ */ (0,
|
|
4638
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4229
4639
|
NSel,
|
|
4230
4640
|
{
|
|
4231
4641
|
style: { maxWidth: 200 },
|
|
@@ -4238,7 +4648,7 @@ var __defProp = Object.defineProperty;
|
|
|
4238
4648
|
onChange: setTypeFilter
|
|
4239
4649
|
}
|
|
4240
4650
|
),
|
|
4241
|
-
/* @__PURE__ */ (0,
|
|
4651
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4242
4652
|
NSel,
|
|
4243
4653
|
{
|
|
4244
4654
|
style: { maxWidth: 220 },
|
|
@@ -4251,7 +4661,7 @@ var __defProp = Object.defineProperty;
|
|
|
4251
4661
|
onChange: setSceneFilter
|
|
4252
4662
|
}
|
|
4253
4663
|
),
|
|
4254
|
-
/* @__PURE__ */ (0,
|
|
4664
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4255
4665
|
WingMultiSelect,
|
|
4256
4666
|
{
|
|
4257
4667
|
options: wingCatalog ?? Array.from(new Set(items.map((m) => m.hall).filter((h) => !!h))).map((id) => ({ id, label: id })),
|
|
@@ -4259,8 +4669,8 @@ var __defProp = Object.defineProperty;
|
|
|
4259
4669
|
onChange: setHallFilter
|
|
4260
4670
|
}
|
|
4261
4671
|
),
|
|
4262
|
-
/* @__PURE__ */ (0,
|
|
4263
|
-
/* @__PURE__ */ (0,
|
|
4672
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(NButton, { onClick: search, children: "搜索" }),
|
|
4673
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4264
4674
|
NButton,
|
|
4265
4675
|
{
|
|
4266
4676
|
style: {
|
|
@@ -4274,8 +4684,8 @@ var __defProp = Object.defineProperty;
|
|
|
4274
4684
|
}
|
|
4275
4685
|
)
|
|
4276
4686
|
] }),
|
|
4277
|
-
/* @__PURE__ */ (0,
|
|
4278
|
-
/* @__PURE__ */ (0,
|
|
4687
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { marginBottom: 10, display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: [
|
|
4688
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4279
4689
|
"button",
|
|
4280
4690
|
{
|
|
4281
4691
|
type: "button",
|
|
@@ -4300,10 +4710,10 @@ var __defProp = Object.defineProperty;
|
|
|
4300
4710
|
children: "无绑定 · " + orphanCount
|
|
4301
4711
|
}
|
|
4302
4712
|
),
|
|
4303
|
-
(tagFilter || untaggedOnly) && /* @__PURE__ */ (0,
|
|
4713
|
+
(tagFilter || untaggedOnly) && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { style: S.muted, children: [
|
|
4304
4714
|
"筛选中:",
|
|
4305
4715
|
untaggedOnly ? "无绑定" : tagFilter,
|
|
4306
|
-
/* @__PURE__ */ (0,
|
|
4716
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4307
4717
|
"button",
|
|
4308
4718
|
{
|
|
4309
4719
|
type: "button",
|
|
@@ -4320,7 +4730,7 @@ var __defProp = Object.defineProperty;
|
|
|
4320
4730
|
}
|
|
4321
4731
|
)
|
|
4322
4732
|
] }),
|
|
4323
|
-
/* @__PURE__ */ (0,
|
|
4733
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4324
4734
|
"button",
|
|
4325
4735
|
{
|
|
4326
4736
|
type: "button",
|
|
@@ -4349,15 +4759,15 @@ var __defProp = Object.defineProperty;
|
|
|
4349
4759
|
children: "导出孤儿"
|
|
4350
4760
|
}
|
|
4351
4761
|
),
|
|
4352
|
-
/* @__PURE__ */ (0,
|
|
4762
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "Room 标签/分类管理:见「Hall」「Room」标签页。" })
|
|
4353
4763
|
] }),
|
|
4354
|
-
/* @__PURE__ */ (0,
|
|
4355
|
-
/* @__PURE__ */ (0,
|
|
4356
|
-
usageSummary ? /* @__PURE__ */ (0,
|
|
4357
|
-
/* @__PURE__ */ (0,
|
|
4764
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
4765
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: loading ? "加载中…" : countText }),
|
|
4766
|
+
usageSummary ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, title: "老化权重效果口径:参与召回尝试的记忆中,进 topN(被注入上下文)的比例", children: "召回使用 " + usageSummary.used + "/" + usageSummary.attempted + "(" + usageSummary.rate + "%)" }) : null,
|
|
4767
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "退场筛查" }),
|
|
4358
4768
|
[["", "全部"], ["active", "仅活跃"], ["retired", "仅退场"]].map(([val, label]) => {
|
|
4359
4769
|
const on = retiredFilter === val;
|
|
4360
|
-
return /* @__PURE__ */ (0,
|
|
4770
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4361
4771
|
"button",
|
|
4362
4772
|
{
|
|
4363
4773
|
type: "button",
|
|
@@ -4377,7 +4787,7 @@ var __defProp = Object.defineProperty;
|
|
|
4377
4787
|
val
|
|
4378
4788
|
);
|
|
4379
4789
|
}),
|
|
4380
|
-
/* @__PURE__ */ (0,
|
|
4790
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4381
4791
|
NButton,
|
|
4382
4792
|
{
|
|
4383
4793
|
style: selCount > 0 ? { color: "var(--dsh-mem-danger)" } : void 0,
|
|
@@ -4387,7 +4797,7 @@ var __defProp = Object.defineProperty;
|
|
|
4387
4797
|
children: "删除选中" + (selCount > 0 ? "(" + selCount + ")" : "")
|
|
4388
4798
|
}
|
|
4389
4799
|
),
|
|
4390
|
-
selCount > 0 ? /* @__PURE__ */ (0,
|
|
4800
|
+
selCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4391
4801
|
NButton,
|
|
4392
4802
|
{
|
|
4393
4803
|
onClick: () => {
|
|
@@ -4396,8 +4806,8 @@ var __defProp = Object.defineProperty;
|
|
|
4396
4806
|
children: "清空选择"
|
|
4397
4807
|
}
|
|
4398
4808
|
) : null,
|
|
4399
|
-
/* @__PURE__ */ (0,
|
|
4400
|
-
/* @__PURE__ */ (0,
|
|
4809
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
4810
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4401
4811
|
NButton,
|
|
4402
4812
|
{
|
|
4403
4813
|
onClick: () => {
|
|
@@ -4408,13 +4818,13 @@ var __defProp = Object.defineProperty;
|
|
|
4408
4818
|
}
|
|
4409
4819
|
)
|
|
4410
4820
|
] }),
|
|
4411
|
-
!hiPriv ? /* @__PURE__ */ (0,
|
|
4412
|
-
error ? /* @__PURE__ */ (0,
|
|
4413
|
-
truncated ? /* @__PURE__ */ (0,
|
|
4414
|
-
items.length === 0 && !loading && !error ? /* @__PURE__ */ (0,
|
|
4821
|
+
!hiPriv ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.hint, children: "提示:删除记忆需先开启高权限模式(右上开关或概览页「高权限模式」),关闭时删除按钮不可用。" }) : null,
|
|
4822
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.error, children: error }) : null,
|
|
4823
|
+
truncated ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.hint, children: "搜索分页已达检索上限(200 条),更早的结果未显示。请用更精确的关键词或类型/情境过滤。" }) : null,
|
|
4824
|
+
items.length === 0 && !loading && !error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: S.intro, children: "暂无记忆。对话几轮后,蒸馏管线会自动抽取记忆。" }) : items.map((m) => {
|
|
4415
4825
|
const open = expandedId === m.id;
|
|
4416
4826
|
const checked = sel.has(m.id);
|
|
4417
|
-
return /* @__PURE__ */ (0,
|
|
4827
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4418
4828
|
"div",
|
|
4419
4829
|
{
|
|
4420
4830
|
className: "dsh-mem-card dsh-mem-card-hover",
|
|
@@ -4423,8 +4833,8 @@ var __defProp = Object.defineProperty;
|
|
|
4423
4833
|
setExpandedId(open ? null : m.id);
|
|
4424
4834
|
},
|
|
4425
4835
|
children: [
|
|
4426
|
-
/* @__PURE__ */ (0,
|
|
4427
|
-
/* @__PURE__ */ (0,
|
|
4836
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: S.cardHead, children: [
|
|
4837
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4428
4838
|
"input",
|
|
4429
4839
|
{
|
|
4430
4840
|
type: "checkbox",
|
|
@@ -4439,9 +4849,9 @@ var __defProp = Object.defineProperty;
|
|
|
4439
4849
|
}
|
|
4440
4850
|
}
|
|
4441
4851
|
),
|
|
4442
|
-
/* @__PURE__ */ (0,
|
|
4443
|
-
m.hall ? /* @__PURE__ */ (0,
|
|
4444
|
-
m.retired ? /* @__PURE__ */ (0,
|
|
4852
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: tagClass(m.type), children: typeLabel(m.type) }),
|
|
4853
|
+
m.hall ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-tag dsh-mem-tag-work-fact", children: "Wing · " + (wingCatalog?.find((h) => h.id === m.hall)?.label || m.hall) }) : null,
|
|
4854
|
+
m.retired ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4445
4855
|
"span",
|
|
4446
4856
|
{
|
|
4447
4857
|
title: "该记忆已退场(软删):移出检索面但仍可恢复,并未真正删除",
|
|
@@ -4456,8 +4866,8 @@ var __defProp = Object.defineProperty;
|
|
|
4456
4866
|
children: "已退场" + (m.retiredReason ? " · " + (RETIRE_REASON_LABEL[m.retiredReason] || m.retiredReason) : "")
|
|
4457
4867
|
}
|
|
4458
4868
|
) : null,
|
|
4459
|
-
/* @__PURE__ */ (0,
|
|
4460
|
-
m.maturity ? /* @__PURE__ */ (0,
|
|
4869
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "优先级 " + m.priority }),
|
|
4870
|
+
m.maturity ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4461
4871
|
"span",
|
|
4462
4872
|
{
|
|
4463
4873
|
title: "成熟度(优先级 + 被用次数 + 新鲜度合成):" + m.maturity,
|
|
@@ -4472,7 +4882,7 @@ var __defProp = Object.defineProperty;
|
|
|
4472
4882
|
children: m.maturity === "high" ? "成熟·高" : m.maturity === "mid" ? "成熟·中" : "成熟·低"
|
|
4473
4883
|
}
|
|
4474
4884
|
) : null,
|
|
4475
|
-
m.agingWeight != null ? /* @__PURE__ */ (0,
|
|
4885
|
+
m.agingWeight != null ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4476
4886
|
"span",
|
|
4477
4887
|
{
|
|
4478
4888
|
style: {
|
|
@@ -4487,7 +4897,7 @@ var __defProp = Object.defineProperty;
|
|
|
4487
4897
|
children: "老化 " + Math.round(m.agingWeight * 100) + "%"
|
|
4488
4898
|
}
|
|
4489
4899
|
) : null,
|
|
4490
|
-
m.usage ? /* @__PURE__ */ (0,
|
|
4900
|
+
m.usage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4491
4901
|
"span",
|
|
4492
4902
|
{
|
|
4493
4903
|
style: S.muted,
|
|
@@ -4495,7 +4905,7 @@ var __defProp = Object.defineProperty;
|
|
|
4495
4905
|
children: "用 " + m.usage.used + "/" + m.usage.attempts
|
|
4496
4906
|
}
|
|
4497
4907
|
) : null,
|
|
4498
|
-
/* @__PURE__ */ (0,
|
|
4908
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4499
4909
|
"span",
|
|
4500
4910
|
{
|
|
4501
4911
|
title: m.name && m.name.length > 0 ? "名称(名称蒸馏产物;投射文件的命名取它):" + m.name : "尚未命名(名称蒸馏未产出);投射回落 mem-" + m.id.slice(-8),
|
|
@@ -4513,7 +4923,7 @@ var __defProp = Object.defineProperty;
|
|
|
4513
4923
|
children: "名称 " + (m.name && m.name.length > 0 ? m.name : "未命名")
|
|
4514
4924
|
}
|
|
4515
4925
|
),
|
|
4516
|
-
/* @__PURE__ */ (0,
|
|
4926
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4517
4927
|
"span",
|
|
4518
4928
|
{
|
|
4519
4929
|
title: m.scope === "workspace" ? "作用范围:指定工作区(仅归属工作区可见)" + (m.workspaceId ? ":" + m.workspaceId : "") : "作用范围:用户默认(global,任何工作区可见)",
|
|
@@ -4528,10 +4938,10 @@ var __defProp = Object.defineProperty;
|
|
|
4528
4938
|
children: m.scope === "workspace" ? "工作区" : "用户默认"
|
|
4529
4939
|
}
|
|
4530
4940
|
),
|
|
4531
|
-
m.score !== null && m.score !== void 0 ? /* @__PURE__ */ (0,
|
|
4532
|
-
/* @__PURE__ */ (0,
|
|
4533
|
-
/* @__PURE__ */ (0,
|
|
4534
|
-
m.retired ? /* @__PURE__ */ (0,
|
|
4941
|
+
m.score !== null && m.score !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "相关度 " + Number(m.score).toFixed(2) }) : null,
|
|
4942
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
4943
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: fmtTime(m.updatedAt) }),
|
|
4944
|
+
m.retired ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4535
4945
|
NButton,
|
|
4536
4946
|
{
|
|
4537
4947
|
style: { padding: "0 7px", minWidth: 26, height: 26, fontSize: 12, color: "var(--dsh-mem-accent)" },
|
|
@@ -4542,7 +4952,7 @@ var __defProp = Object.defineProperty;
|
|
|
4542
4952
|
},
|
|
4543
4953
|
children: "恢复"
|
|
4544
4954
|
}
|
|
4545
|
-
) : hiPriv ? /* @__PURE__ */ (0,
|
|
4955
|
+
) : hiPriv ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4546
4956
|
NButton,
|
|
4547
4957
|
{
|
|
4548
4958
|
style: { padding: "0 7px", minWidth: 26, height: 26, fontSize: 12, color: "var(--dsh-mem-danger)" },
|
|
@@ -4555,34 +4965,34 @@ var __defProp = Object.defineProperty;
|
|
|
4555
4965
|
}
|
|
4556
4966
|
) : null
|
|
4557
4967
|
] }),
|
|
4558
|
-
/* @__PURE__ */ (0,
|
|
4559
|
-
open ? /* @__PURE__ */ (0,
|
|
4968
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.content, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(MarkdownBody, { text: m.content }) }),
|
|
4969
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.detail, children: "id: " + m.id + "\n名称: " + (m.name && m.name.length > 0 ? m.name : "(未命名,投射回落 mem-" + m.id.slice(-8) + ")") + "\n情境: " + (m.scene || "-") + "\n关键词: " + (m.keywords && m.keywords.length > 0 ? m.keywords.join(",") : "(暂无 · 预留检索轴)") + "\n作用范围: " + (m.scope === "workspace" ? "指定工作区" + (m.workspaceId ? ":" + m.workspaceId : "(未记录路径)") : "用户默认(global,任何工作区可见)") + "\n版本: v" + m.version + "(去重合并次数 " + m.version + ")\n创建: " + fmtTime(m.createdAt) + "\n活跃时间: " + (m.timestamps && m.timestamps.length > 0 ? m.timestamps.map(fmtTime).join(" → ") : "-") + "\n" + (m.sourceAnchors && m.sourceAnchors.length > 0 ? "来源锚点: " + m.sourceAnchors.join(", ") : "来源锚点: -") }) : null
|
|
4560
4970
|
]
|
|
4561
4971
|
},
|
|
4562
4972
|
m.id
|
|
4563
4973
|
);
|
|
4564
4974
|
}),
|
|
4565
|
-
/* @__PURE__ */ (0,
|
|
4566
|
-
/* @__PURE__ */ (0,
|
|
4567
|
-
showRetired && retiredBusy ? /* @__PURE__ */ (0,
|
|
4568
|
-
showRetired && !retiredBusy && retiredTotal > 0 ? /* @__PURE__ */ (0,
|
|
4975
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { ...S.flexRow, marginTop: 12 }, children: [
|
|
4976
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(NButton, { onClick: () => setShowRetired((v) => !v), children: (showRetired ? "收起" : "展开") + "「已退场」(可恢复)" }),
|
|
4977
|
+
showRetired && retiredBusy ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "加载中…" }) : null,
|
|
4978
|
+
showRetired && !retiredBusy && retiredTotal > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "共 " + retiredTotal + " 条可恢复" }) : null
|
|
4569
4979
|
] }),
|
|
4570
|
-
showRetired ? /* @__PURE__ */ (0,
|
|
4571
|
-
retired.map((m) => /* @__PURE__ */ (0,
|
|
4572
|
-
/* @__PURE__ */ (0,
|
|
4573
|
-
/* @__PURE__ */ (0,
|
|
4574
|
-
m.verdict ? /* @__PURE__ */ (0,
|
|
4575
|
-
/* @__PURE__ */ (0,
|
|
4576
|
-
/* @__PURE__ */ (0,
|
|
4577
|
-
/* @__PURE__ */ (0,
|
|
4980
|
+
showRetired ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { marginTop: 8 }, children: retired.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: S.hint, children: retiredBusy ? " " : "没有已退场的记忆。" }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
|
|
4981
|
+
retired.map((m) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "dsh-mem-card", style: S.card, children: [
|
|
4982
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: S.cardHead, children: [
|
|
4983
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: RETIRE_REASON_LABEL[m.retiredReason] || m.retiredReason }),
|
|
4984
|
+
m.verdict ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "结论 " + m.verdict }) : null,
|
|
4985
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
4986
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: fmtTime(m.retiredAt) }),
|
|
4987
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(NButton, { disabled: retiredBusy, title: "恢复到检索面", onClick: () => restoreRecords([m.id]), children: "恢复" })
|
|
4578
4988
|
] }),
|
|
4579
|
-
/* @__PURE__ */ (0,
|
|
4989
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.content, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(MarkdownBody, { text: m.content }) })
|
|
4580
4990
|
] }, m.id)),
|
|
4581
|
-
retiredTotal > retired.length ? /* @__PURE__ */ (0,
|
|
4991
|
+
retiredTotal > retired.length ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: S.hint, children: "共 " + retiredTotal + " 条,此处显示 " + retired.length + " 条" }) : null
|
|
4582
4992
|
] }) }) : null,
|
|
4583
|
-
hasMore ? /* @__PURE__ */ (0,
|
|
4584
|
-
/* @__PURE__ */ (0,
|
|
4585
|
-
/* @__PURE__ */ (0,
|
|
4993
|
+
hasMore ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: S.flexRow, children: [
|
|
4994
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
4995
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4586
4996
|
NButton,
|
|
4587
4997
|
{
|
|
4588
4998
|
disabled: loading,
|
|
@@ -4596,9 +5006,9 @@ var __defProp = Object.defineProperty;
|
|
|
4596
5006
|
] });
|
|
4597
5007
|
}
|
|
4598
5008
|
function WingMultiSelect(props) {
|
|
4599
|
-
const [open, setOpen] = (0,
|
|
4600
|
-
const wrapRef = (0,
|
|
4601
|
-
(0,
|
|
5009
|
+
const [open, setOpen] = (0, import_react20.useState)(false);
|
|
5010
|
+
const wrapRef = (0, import_react20.useRef)(null);
|
|
5011
|
+
(0, import_react20.useEffect)(() => {
|
|
4602
5012
|
if (!open) return;
|
|
4603
5013
|
const onDown = (e) => {
|
|
4604
5014
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -4618,8 +5028,8 @@ var __defProp = Object.defineProperty;
|
|
|
4618
5028
|
const toggle = (id) => {
|
|
4619
5029
|
props.onChange(props.selected.includes(id) ? props.selected.filter((x) => x !== id) : [...props.selected, id]);
|
|
4620
5030
|
};
|
|
4621
|
-
return /* @__PURE__ */ (0,
|
|
4622
|
-
/* @__PURE__ */ (0,
|
|
5031
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { ref: wrapRef, style: { position: "relative", maxWidth: 150 }, children: [
|
|
5032
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4623
5033
|
"button",
|
|
4624
5034
|
{
|
|
4625
5035
|
type: "button",
|
|
@@ -4628,31 +5038,31 @@ var __defProp = Object.defineProperty;
|
|
|
4628
5038
|
"aria-expanded": open,
|
|
4629
5039
|
onClick: () => setOpen(!open),
|
|
4630
5040
|
children: [
|
|
4631
|
-
/* @__PURE__ */ (0,
|
|
4632
|
-
/* @__PURE__ */ (0,
|
|
5041
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-select-label", title: summary, children: summary }),
|
|
5042
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-sel-chev" + (open ? " dsh-mem-sel-chev-open" : "") })
|
|
4633
5043
|
]
|
|
4634
5044
|
}
|
|
4635
5045
|
),
|
|
4636
|
-
open ? /* @__PURE__ */ (0,
|
|
4637
|
-
props.options.length === 0 ? /* @__PURE__ */ (0,
|
|
5046
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "dsh-mem-pop", role: "listbox", style: { left: 0, right: "auto", minWidth: 150 }, children: [
|
|
5047
|
+
props.options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "dsh-mem-pop-empty", children: "暂无可筛 Hall" }) : null,
|
|
4638
5048
|
props.options.map((o) => {
|
|
4639
5049
|
const active = props.selected.includes(o.id);
|
|
4640
|
-
return /* @__PURE__ */ (0,
|
|
4641
|
-
/* @__PURE__ */ (0,
|
|
4642
|
-
/* @__PURE__ */ (0,
|
|
5050
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { type: "button", className: "dsh-mem-pop-opt", onClick: () => toggle(o.id), "aria-selected": active, children: [
|
|
5051
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-pop-check", children: active ? "✓" : "" }),
|
|
5052
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-pop-label", children: o.label })
|
|
4643
5053
|
] }, o.id);
|
|
4644
5054
|
}),
|
|
4645
|
-
props.selected.length > 0 ? /* @__PURE__ */ (0,
|
|
4646
|
-
/* @__PURE__ */ (0,
|
|
4647
|
-
/* @__PURE__ */ (0,
|
|
5055
|
+
props.selected.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { type: "button", className: "dsh-mem-pop-opt", onClick: () => props.onChange([]), children: [
|
|
5056
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-pop-check" }),
|
|
5057
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-pop-label", children: "清除筛选" })
|
|
4648
5058
|
] }) : null
|
|
4649
5059
|
] }) : null
|
|
4650
5060
|
] });
|
|
4651
5061
|
}
|
|
4652
5062
|
|
|
4653
5063
|
// client/src/tabs/RoomsTab.tsx
|
|
4654
|
-
var
|
|
4655
|
-
var
|
|
5064
|
+
var import_react21 = require("react");
|
|
5065
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4656
5066
|
function majorOf(slug) {
|
|
4657
5067
|
const i = slug.indexOf("/");
|
|
4658
5068
|
return i === -1 ? slug : slug.slice(0, i);
|
|
@@ -4681,26 +5091,26 @@ var __defProp = Object.defineProperty;
|
|
|
4681
5091
|
};
|
|
4682
5092
|
function RoomsTab(props) {
|
|
4683
5093
|
const rpc = props.rpc;
|
|
4684
|
-
const [registry, setRegistry] = (0,
|
|
4685
|
-
const [rooms, setRooms] = (0,
|
|
4686
|
-
const [orphanCount, setOrphanCount] = (0,
|
|
4687
|
-
const [busy, setBusy] = (0,
|
|
4688
|
-
const [msg, setMsg] = (0,
|
|
4689
|
-
const [error, setError] = (0,
|
|
4690
|
-
const [hiPriv, setHiPriv] = (0,
|
|
4691
|
-
const [hiPrivBusy, setHiPrivBusy] = (0,
|
|
4692
|
-
const [regSlug, setRegSlug] = (0,
|
|
4693
|
-
const [regLabel, setRegLabel] = (0,
|
|
4694
|
-
const [regDesc, setRegDesc] = (0,
|
|
4695
|
-
const [form, setForm] = (0,
|
|
4696
|
-
const [preview, setPreview] = (0,
|
|
4697
|
-
const [grownOpen, setGrownOpen] = (0,
|
|
4698
|
-
const [dragOverHall, setDragOverHall] = (0,
|
|
4699
|
-
const [picking, setPicking] = (0,
|
|
4700
|
-
const [editing, setEditing] = (0,
|
|
4701
|
-
const [expandedRooms, setExpandedRooms] = (0,
|
|
4702
|
-
const [roomRecords, setRoomRecords] = (0,
|
|
4703
|
-
const [expandedHalls, setExpandedHalls] = (0,
|
|
5094
|
+
const [registry, setRegistry] = (0, import_react21.useState)([]);
|
|
5095
|
+
const [rooms, setRooms] = (0, import_react21.useState)([]);
|
|
5096
|
+
const [orphanCount, setOrphanCount] = (0, import_react21.useState)(0);
|
|
5097
|
+
const [busy, setBusy] = (0, import_react21.useState)(false);
|
|
5098
|
+
const [msg, setMsg] = (0, import_react21.useState)(null);
|
|
5099
|
+
const [error, setError] = (0, import_react21.useState)(null);
|
|
5100
|
+
const [hiPriv, setHiPriv] = (0, import_react21.useState)(false);
|
|
5101
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react21.useState)(false);
|
|
5102
|
+
const [regSlug, setRegSlug] = (0, import_react21.useState)("");
|
|
5103
|
+
const [regLabel, setRegLabel] = (0, import_react21.useState)("");
|
|
5104
|
+
const [regDesc, setRegDesc] = (0, import_react21.useState)("");
|
|
5105
|
+
const [form, setForm] = (0, import_react21.useState)(null);
|
|
5106
|
+
const [preview, setPreview] = (0, import_react21.useState)(null);
|
|
5107
|
+
const [grownOpen, setGrownOpen] = (0, import_react21.useState)(false);
|
|
5108
|
+
const [dragOverHall, setDragOverHall] = (0, import_react21.useState)(null);
|
|
5109
|
+
const [picking, setPicking] = (0, import_react21.useState)(null);
|
|
5110
|
+
const [editing, setEditing] = (0, import_react21.useState)(null);
|
|
5111
|
+
const [expandedRooms, setExpandedRooms] = (0, import_react21.useState)(/* @__PURE__ */ new Set());
|
|
5112
|
+
const [roomRecords, setRoomRecords] = (0, import_react21.useState)({});
|
|
5113
|
+
const [expandedHalls, setExpandedHalls] = (0, import_react21.useState)(() => {
|
|
4704
5114
|
try {
|
|
4705
5115
|
const v = window.localStorage.getItem("dsh.memory.halls.open");
|
|
4706
5116
|
return v ? new Set(JSON.parse(v)) : /* @__PURE__ */ new Set();
|
|
@@ -4708,9 +5118,9 @@ var __defProp = Object.defineProperty;
|
|
|
4708
5118
|
return /* @__PURE__ */ new Set();
|
|
4709
5119
|
}
|
|
4710
5120
|
});
|
|
4711
|
-
const [filter, setFilter] = (0,
|
|
4712
|
-
const dragRef = (0,
|
|
4713
|
-
const [ghost, setGhost] = (0,
|
|
5121
|
+
const [filter, setFilter] = (0, import_react21.useState)("");
|
|
5122
|
+
const dragRef = (0, import_react21.useRef)(null);
|
|
5123
|
+
const [ghost, setGhost] = (0, import_react21.useState)(null);
|
|
4714
5124
|
const onDragLabelDown = (ev, slug) => {
|
|
4715
5125
|
if (!hiPriv || busy || ev.button !== 0) return;
|
|
4716
5126
|
ev.currentTarget.setPointerCapture(ev.pointerId);
|
|
@@ -4735,7 +5145,7 @@ var __defProp = Object.defineProperty;
|
|
|
4735
5145
|
setDragOverHall(null);
|
|
4736
5146
|
if (hall) beginReclass(d.from, hall);
|
|
4737
5147
|
};
|
|
4738
|
-
const loadAll = (0,
|
|
5148
|
+
const loadAll = (0, import_react21.useCallback)(() => {
|
|
4739
5149
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
4740
5150
|
if (r && r.ok) {
|
|
4741
5151
|
setRooms(r.value.rooms ?? []);
|
|
@@ -4744,13 +5154,13 @@ var __defProp = Object.defineProperty;
|
|
|
4744
5154
|
}
|
|
4745
5155
|
}).catch(() => void 0);
|
|
4746
5156
|
}, [rpc]);
|
|
4747
|
-
const loadHiPriv = (0,
|
|
5157
|
+
const loadHiPriv = (0, import_react21.useCallback)(() => {
|
|
4748
5158
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
4749
5159
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
4750
5160
|
}).catch(() => {
|
|
4751
5161
|
});
|
|
4752
5162
|
}, [rpc]);
|
|
4753
|
-
(0,
|
|
5163
|
+
(0, import_react21.useEffect)(() => {
|
|
4754
5164
|
loadAll();
|
|
4755
5165
|
loadHiPriv();
|
|
4756
5166
|
}, [loadAll, loadHiPriv]);
|
|
@@ -4905,7 +5315,7 @@ var __defProp = Object.defineProperty;
|
|
|
4905
5315
|
if (r.value.csv) downloadCsv(r.value.csv, `dsh-memory-room-${slug.replace(/\//g, "-")}-records.csv`);
|
|
4906
5316
|
else setError("导出为空");
|
|
4907
5317
|
});
|
|
4908
|
-
const groups = (0,
|
|
5318
|
+
const groups = (0, import_react21.useMemo)(() => {
|
|
4909
5319
|
const countOf = new Map(rooms.map((r) => [r.room, r.count]));
|
|
4910
5320
|
const byHall = /* @__PURE__ */ new Map();
|
|
4911
5321
|
for (const e of registry) {
|
|
@@ -4922,7 +5332,7 @@ var __defProp = Object.defineProperty;
|
|
|
4922
5332
|
total: entries.reduce((s2, e) => s2 + (countOf.get(e.slug) ?? 0), 0)
|
|
4923
5333
|
})).sort((a, b) => a.hall.localeCompare(b.hall));
|
|
4924
5334
|
}, [registry, rooms]);
|
|
4925
|
-
const grownOnly = (0,
|
|
5335
|
+
const grownOnly = (0, import_react21.useMemo)(() => rooms.filter((r) => !registry.some((e) => e.slug === r.room)), [rooms, registry]);
|
|
4926
5336
|
const persistHalls = (next) => {
|
|
4927
5337
|
try {
|
|
4928
5338
|
window.localStorage.setItem("dsh.memory.halls.open", JSON.stringify([...next]));
|
|
@@ -4942,7 +5352,7 @@ var __defProp = Object.defineProperty;
|
|
|
4942
5352
|
persistHalls(next);
|
|
4943
5353
|
};
|
|
4944
5354
|
const normFilter = filter.trim().toLowerCase();
|
|
4945
|
-
const visibleGroups = (0,
|
|
5355
|
+
const visibleGroups = (0, import_react21.useMemo)(() => {
|
|
4946
5356
|
if (!normFilter) return groups;
|
|
4947
5357
|
return groups.map((g) => {
|
|
4948
5358
|
const hallHit = g.hall.toLowerCase().includes(normFilter) || (g.label ?? "").toLowerCase().includes(normFilter);
|
|
@@ -4952,15 +5362,15 @@ var __defProp = Object.defineProperty;
|
|
|
4952
5362
|
return { ...g, entries };
|
|
4953
5363
|
}).filter((g) => g.entries.length > 0);
|
|
4954
5364
|
}, [groups, normFilter]);
|
|
4955
|
-
const visibleGrown = (0,
|
|
5365
|
+
const visibleGrown = (0, import_react21.useMemo)(
|
|
4956
5366
|
() => normFilter ? grownOnly.filter((r) => r.room.toLowerCase().includes(normFilter)) : grownOnly,
|
|
4957
5367
|
[grownOnly, normFilter]
|
|
4958
5368
|
);
|
|
4959
|
-
return /* @__PURE__ */ (0,
|
|
4960
|
-
/* @__PURE__ */ (0,
|
|
4961
|
-
/* @__PURE__ */ (0,
|
|
4962
|
-
/* @__PURE__ */ (0,
|
|
4963
|
-
/* @__PURE__ */ (0,
|
|
5369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
|
|
5370
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { ...S.flexRow, marginBottom: 8 }, children: [
|
|
5371
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "Hall = Room 大类 · 大类上限 200,小类「大类/小类」细分不占额度 · 与 Wing(域)筛选无关" }),
|
|
5372
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.grow }),
|
|
5373
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4964
5374
|
"button",
|
|
4965
5375
|
{
|
|
4966
5376
|
type: "button",
|
|
@@ -4977,7 +5387,7 @@ var __defProp = Object.defineProperty;
|
|
|
4977
5387
|
children: "导出词表"
|
|
4978
5388
|
}
|
|
4979
5389
|
),
|
|
4980
|
-
/* @__PURE__ */ (0,
|
|
5390
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
4981
5391
|
"button",
|
|
4982
5392
|
{
|
|
4983
5393
|
type: "button",
|
|
@@ -4997,7 +5407,7 @@ var __defProp = Object.defineProperty;
|
|
|
4997
5407
|
]
|
|
4998
5408
|
}
|
|
4999
5409
|
),
|
|
5000
|
-
/* @__PURE__ */ (0,
|
|
5410
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5001
5411
|
"button",
|
|
5002
5412
|
{
|
|
5003
5413
|
type: "button",
|
|
@@ -5012,10 +5422,10 @@ var __defProp = Object.defineProperty;
|
|
|
5012
5422
|
children: hiPriv ? "高权限:开" : "高权限:关"
|
|
5013
5423
|
}
|
|
5014
5424
|
),
|
|
5015
|
-
/* @__PURE__ */ (0,
|
|
5425
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn, onClick: loadAll, title: "重拉注册表与计数", children: "刷新" })
|
|
5016
5426
|
] }),
|
|
5017
|
-
/* @__PURE__ */ (0,
|
|
5018
|
-
/* @__PURE__ */ (0,
|
|
5427
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center", marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
5428
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5019
5429
|
"input",
|
|
5020
5430
|
{
|
|
5021
5431
|
value: filter,
|
|
@@ -5024,14 +5434,14 @@ var __defProp = Object.defineProperty;
|
|
|
5024
5434
|
style: { ...S.input, width: 250, fontSize: 12 }
|
|
5025
5435
|
}
|
|
5026
5436
|
),
|
|
5027
|
-
filter ? /* @__PURE__ */ (0,
|
|
5028
|
-
/* @__PURE__ */ (0,
|
|
5029
|
-
/* @__PURE__ */ (0,
|
|
5030
|
-
/* @__PURE__ */ (0,
|
|
5031
|
-
/* @__PURE__ */ (0,
|
|
5437
|
+
filter ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn, onClick: () => setFilter(""), children: "清除" }) : null,
|
|
5438
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: `匹配 ${visibleGroups.reduce((s2, g) => s2 + g.entries.length, 0)} room / ${visibleGroups.length} hall` }),
|
|
5439
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.grow }),
|
|
5440
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn, title: "展开全部 hall 的子 room", onClick: () => setAllHalls(true), children: "展开全部" }),
|
|
5441
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn, title: "收起全部 hall(只留 hall 头)", onClick: () => setAllHalls(false), children: "收起全部" })
|
|
5032
5442
|
] }),
|
|
5033
|
-
/* @__PURE__ */ (0,
|
|
5034
|
-
/* @__PURE__ */ (0,
|
|
5443
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginBottom: 10 }, children: [
|
|
5444
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5035
5445
|
"input",
|
|
5036
5446
|
{
|
|
5037
5447
|
value: regSlug,
|
|
@@ -5041,7 +5451,7 @@ var __defProp = Object.defineProperty;
|
|
|
5041
5451
|
style: { ...S.input, width: 210, fontSize: 12 }
|
|
5042
5452
|
}
|
|
5043
5453
|
),
|
|
5044
|
-
/* @__PURE__ */ (0,
|
|
5454
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5045
5455
|
"input",
|
|
5046
5456
|
{
|
|
5047
5457
|
value: regLabel,
|
|
@@ -5051,7 +5461,7 @@ var __defProp = Object.defineProperty;
|
|
|
5051
5461
|
style: { ...S.input, width: 110, fontSize: 12 }
|
|
5052
5462
|
}
|
|
5053
5463
|
),
|
|
5054
|
-
/* @__PURE__ */ (0,
|
|
5464
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5055
5465
|
"input",
|
|
5056
5466
|
{
|
|
5057
5467
|
value: regDesc,
|
|
@@ -5061,7 +5471,7 @@ var __defProp = Object.defineProperty;
|
|
|
5061
5471
|
style: { ...S.input, width: 170, fontSize: 12 }
|
|
5062
5472
|
}
|
|
5063
5473
|
),
|
|
5064
|
-
/* @__PURE__ */ (0,
|
|
5474
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5065
5475
|
"button",
|
|
5066
5476
|
{
|
|
5067
5477
|
type: "button",
|
|
@@ -5071,26 +5481,26 @@ var __defProp = Object.defineProperty;
|
|
|
5071
5481
|
children: "注册"
|
|
5072
5482
|
}
|
|
5073
5483
|
),
|
|
5074
|
-
!hiPriv && /* @__PURE__ */ (0,
|
|
5484
|
+
!hiPriv && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "管理操作需先开启高权限模式" })
|
|
5075
5485
|
] }),
|
|
5076
|
-
editing ? /* @__PURE__ */ (0,
|
|
5077
|
-
/* @__PURE__ */ (0,
|
|
5486
|
+
editing ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { position: "sticky", top: 0, zIndex: 5, background: "var(--dsh-mem-bg-inset)", display: "flex", alignItems: "center", gap: 6, marginBottom: 8, flexWrap: "wrap", padding: "6px 8px", border: "1px solid var(--dsh-mem-accent)", borderRadius: 8 }, children: [
|
|
5487
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: S.muted, children: [
|
|
5078
5488
|
"编辑 ",
|
|
5079
5489
|
editing.slug
|
|
5080
5490
|
] }),
|
|
5081
|
-
/* @__PURE__ */ (0,
|
|
5082
|
-
/* @__PURE__ */ (0,
|
|
5083
|
-
/* @__PURE__ */ (0,
|
|
5084
|
-
/* @__PURE__ */ (0,
|
|
5491
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { value: editing.label, onChange: (ev) => setEditing({ ...editing, label: ev.target.value }), placeholder: "显示名(可中文)", disabled: busy, style: { ...S.input, width: 140, fontSize: 12 } }),
|
|
5492
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { value: editing.description, onChange: (ev) => setEditing({ ...editing, description: ev.target.value }), placeholder: "归类说明(喂标注器)", disabled: busy, style: { ...S.input, width: 200, fontSize: 12 } }),
|
|
5493
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: saveEditing, style: { ...btn, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" }, children: "保存" }),
|
|
5494
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: () => setEditing(null), style: btn, children: "取消" })
|
|
5085
5495
|
] }) : null,
|
|
5086
|
-
form ? /* @__PURE__ */ (0,
|
|
5087
|
-
/* @__PURE__ */ (0,
|
|
5496
|
+
form ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { position: "sticky", top: 0, zIndex: 5, background: "var(--dsh-mem-bg-inset)", display: "flex", alignItems: "center", gap: 6, marginBottom: 8, flexWrap: "wrap", padding: "6px 8px", border: "1px solid var(--dsh-mem-accent)", borderRadius: 8 }, children: [
|
|
5497
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: S.muted, children: [
|
|
5088
5498
|
form.action === "merge" ? "合并" : "归类/改名",
|
|
5089
5499
|
" ",
|
|
5090
5500
|
form.from,
|
|
5091
5501
|
" →"
|
|
5092
5502
|
] }),
|
|
5093
|
-
/* @__PURE__ */ (0,
|
|
5503
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5094
5504
|
"input",
|
|
5095
5505
|
{
|
|
5096
5506
|
value: form.to,
|
|
@@ -5100,7 +5510,7 @@ var __defProp = Object.defineProperty;
|
|
|
5100
5510
|
style: { ...S.input, width: 190, fontSize: 12 }
|
|
5101
5511
|
}
|
|
5102
5512
|
),
|
|
5103
|
-
form.action === "rename" ? /* @__PURE__ */ (0,
|
|
5513
|
+
form.action === "rename" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { display: "inline-flex", gap: 4, flexWrap: "wrap" }, children: groups.filter((gg) => gg.hall !== majorOf(form.from)).map((gg) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5104
5514
|
"button",
|
|
5105
5515
|
{
|
|
5106
5516
|
type: "button",
|
|
@@ -5111,32 +5521,32 @@ var __defProp = Object.defineProperty;
|
|
|
5111
5521
|
},
|
|
5112
5522
|
gg.hall
|
|
5113
5523
|
)) }) : null,
|
|
5114
|
-
/* @__PURE__ */ (0,
|
|
5115
|
-
/* @__PURE__ */ (0,
|
|
5524
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: () => previewMerge(), style: { ...btn, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" }, children: "预览" }),
|
|
5525
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: () => {
|
|
5116
5526
|
setForm(null);
|
|
5117
5527
|
setPreview(null);
|
|
5118
5528
|
setPicking(null);
|
|
5119
5529
|
}, style: btn, children: "取消" }),
|
|
5120
|
-
picking ? /* @__PURE__ */ (0,
|
|
5121
|
-
/* @__PURE__ */ (0,
|
|
5530
|
+
picking ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "挑选中:点击目标 hall 头完成归类" }) : null,
|
|
5531
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "与反刍并发会互相覆盖,请在反刍空闲时执行。" })
|
|
5122
5532
|
] }) : null,
|
|
5123
|
-
preview ? /* @__PURE__ */ (0,
|
|
5124
|
-
/* @__PURE__ */ (0,
|
|
5125
|
-
/* @__PURE__ */ (0,
|
|
5126
|
-
/* @__PURE__ */ (0,
|
|
5533
|
+
preview ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { position: "sticky", top: 0, zIndex: 5, background: "var(--dsh-mem-bg-inset)", marginBottom: 8, padding: "6px 8px", border: "1px solid var(--dsh-mem-danger)", borderRadius: 8, fontSize: 12 }, children: [
|
|
5534
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { children: preview.notice }),
|
|
5535
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, marginTop: 4 }, children: [
|
|
5536
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { type: "button", disabled: busy, onClick: execMerge, style: { ...btn, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" }, children: [
|
|
5127
5537
|
"确认执行",
|
|
5128
5538
|
preview.action === "merge" ? "合并" : "归类/改名"
|
|
5129
5539
|
] }),
|
|
5130
|
-
/* @__PURE__ */ (0,
|
|
5540
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: () => setPreview(null), style: btn, children: "再改改" })
|
|
5131
5541
|
] })
|
|
5132
5542
|
] }) : null,
|
|
5133
|
-
msg ? /* @__PURE__ */ (0,
|
|
5134
|
-
error ? /* @__PURE__ */ (0,
|
|
5135
|
-
ghost ? /* @__PURE__ */ (0,
|
|
5136
|
-
visibleGroups.length === 0 ? /* @__PURE__ */ (0,
|
|
5543
|
+
msg ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.hint, children: msg }) : null,
|
|
5544
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.error, children: error }) : null,
|
|
5545
|
+
ghost ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { position: "fixed", left: ghost.x + 12, top: ghost.y + 12, zIndex: 9999, pointerEvents: "none", fontSize: 12, padding: "2px 10px", borderRadius: 999, border: "1px solid var(--dsh-mem-accent)", background: "var(--dsh-mem-bg-inset)", color: "var(--dsh-mem-accent)" }, children: ghost.text }) : null,
|
|
5546
|
+
visibleGroups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { style: S.intro, children: normFilter ? "无匹配的 hall/room。" : "注册表为空。在上方注册 Hall/Room(如 dsh-plugin),或把自生长 slug「收编」进词表 —— 之后候选标注器会优先把相关记忆挂到这些 slug 上。" }) : visibleGroups.map((g) => {
|
|
5137
5547
|
const hallOpen = !!normFilter || expandedHalls.has(g.hall);
|
|
5138
|
-
return /* @__PURE__ */ (0,
|
|
5139
|
-
/* @__PURE__ */ (0,
|
|
5548
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 10, border: "1px solid var(--dsh-mem-border)", borderRadius: 8, overflow: "hidden" }, children: [
|
|
5549
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5140
5550
|
"div",
|
|
5141
5551
|
{
|
|
5142
5552
|
"data-hall": g.hall,
|
|
@@ -5177,7 +5587,7 @@ var __defProp = Object.defineProperty;
|
|
|
5177
5587
|
},
|
|
5178
5588
|
title: picking ? "点击此 hall:把「" + picking + "」归入 " + g.hall + " 下(major/minor,预览后确认)" : hiPriv ? "拖入 room 归类到该 hall 下(major/minor;记录随迁,旧名进别名,预览后确认)" : void 0,
|
|
5179
5589
|
children: [
|
|
5180
|
-
/* @__PURE__ */ (0,
|
|
5590
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5181
5591
|
"button",
|
|
5182
5592
|
{
|
|
5183
5593
|
type: "button",
|
|
@@ -5190,13 +5600,13 @@ var __defProp = Object.defineProperty;
|
|
|
5190
5600
|
children: hallOpen ? "▾" : "▸"
|
|
5191
5601
|
}
|
|
5192
5602
|
),
|
|
5193
|
-
/* @__PURE__ */ (0,
|
|
5603
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 12, fontWeight: 600 }, children: [
|
|
5194
5604
|
g.hall,
|
|
5195
|
-
g.label ? /* @__PURE__ */ (0,
|
|
5605
|
+
g.label ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: " (" + g.label + ")" }) : null
|
|
5196
5606
|
] }),
|
|
5197
|
-
/* @__PURE__ */ (0,
|
|
5198
|
-
/* @__PURE__ */ (0,
|
|
5199
|
-
/* @__PURE__ */ (0,
|
|
5607
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: `合计 ${g.total} 条 · ${g.entries.length} 个 room` }),
|
|
5608
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.grow }),
|
|
5609
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5200
5610
|
"button",
|
|
5201
5611
|
{
|
|
5202
5612
|
type: "button",
|
|
@@ -5217,10 +5627,10 @@ var __defProp = Object.defineProperty;
|
|
|
5217
5627
|
const standalone = e.slug === g.hall;
|
|
5218
5628
|
const count = rooms.find((r) => r.room === e.slug)?.count ?? 0;
|
|
5219
5629
|
const retired = e.status === "retired";
|
|
5220
|
-
return /* @__PURE__ */ (0,
|
|
5221
|
-
/* @__PURE__ */ (0,
|
|
5222
|
-
/* @__PURE__ */ (0,
|
|
5223
|
-
/* @__PURE__ */ (0,
|
|
5630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { padding: "4px 10px", borderTop: "1px solid var(--dsh-mem-border)", opacity: retired ? 0.55 : 1 }, children: [
|
|
5631
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
5632
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { flex: 1, minWidth: 0, display: "flex", flexWrap: "wrap", gap: "2px 8px", alignItems: "baseline" }, children: [
|
|
5633
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5224
5634
|
"button",
|
|
5225
5635
|
{
|
|
5226
5636
|
type: "button",
|
|
@@ -5230,7 +5640,7 @@ var __defProp = Object.defineProperty;
|
|
|
5230
5640
|
children: expandedRooms.has(e.slug) ? "▾" : "▸"
|
|
5231
5641
|
}
|
|
5232
5642
|
),
|
|
5233
|
-
/* @__PURE__ */ (0,
|
|
5643
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5234
5644
|
"span",
|
|
5235
5645
|
{
|
|
5236
5646
|
style: { fontSize: 12, cursor: hiPriv && !busy ? "grab" : "default", touchAction: "none" },
|
|
@@ -5244,20 +5654,20 @@ var __defProp = Object.defineProperty;
|
|
|
5244
5654
|
]
|
|
5245
5655
|
}
|
|
5246
5656
|
),
|
|
5247
|
-
e.label ? /* @__PURE__ */ (0,
|
|
5248
|
-
/* @__PURE__ */ (0,
|
|
5249
|
-
retired ? /* @__PURE__ */ (0,
|
|
5250
|
-
(e.aliases ?? []).length > 0 ? /* @__PURE__ */ (0,
|
|
5657
|
+
e.label ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: e.label }) : null,
|
|
5658
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: count + " 条" }),
|
|
5659
|
+
retired ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "已退役" }) : null,
|
|
5660
|
+
(e.aliases ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { ...S.muted, wordBreak: "break-all" }, children: "别名: " + (e.aliases ?? []).join(", ") }) : null
|
|
5251
5661
|
] }),
|
|
5252
|
-
/* @__PURE__ */ (0,
|
|
5253
|
-
!hiPriv ? null : /* @__PURE__ */ (0,
|
|
5254
|
-
/* @__PURE__ */ (0,
|
|
5662
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, flexShrink: 0, alignItems: "center" }, children: [
|
|
5663
|
+
!hiPriv ? null : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
5664
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "编辑显示名/归类说明", onClick: () => {
|
|
5255
5665
|
setEditing({ slug: e.slug, label: e.label ?? "", description: e.description ?? "" });
|
|
5256
5666
|
setForm(null);
|
|
5257
5667
|
setPreview(null);
|
|
5258
5668
|
setPicking(null);
|
|
5259
5669
|
}, style: btn, children: "编辑" }),
|
|
5260
|
-
/* @__PURE__ */ (0,
|
|
5670
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5261
5671
|
"button",
|
|
5262
5672
|
{
|
|
5263
5673
|
type: "button",
|
|
@@ -5278,43 +5688,43 @@ var __defProp = Object.defineProperty;
|
|
|
5278
5688
|
children: picking === e.slug ? "选 hall…" : "归类"
|
|
5279
5689
|
}
|
|
5280
5690
|
),
|
|
5281
|
-
/* @__PURE__ */ (0,
|
|
5691
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: `改名(= merge 1:1 + 注册表改名)`, onClick: () => {
|
|
5282
5692
|
setForm({ action: "rename", from: e.slug, to: "" });
|
|
5283
5693
|
setPreview(null);
|
|
5284
5694
|
}, style: btn, children: "改名" }),
|
|
5285
|
-
/* @__PURE__ */ (0,
|
|
5695
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "合并到另一个 Room(dryRun 预览→确认实跑)", onClick: () => {
|
|
5286
5696
|
setForm({ action: "merge", from: e.slug, to: "" });
|
|
5287
5697
|
setPreview(null);
|
|
5288
5698
|
}, style: btn, children: "合并" }),
|
|
5289
|
-
/* @__PURE__ */ (0,
|
|
5290
|
-
!retired ? /* @__PURE__ */ (0,
|
|
5699
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: retired ? "恢复该 Room 到词表" : "退役该 Room(存量 tags 不动)", onClick: () => retire(e.slug, retired), style: { ...btn, ...retired ? { color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" } : { color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" } }, children: retired ? "恢复" : "退役" }),
|
|
5700
|
+
!retired ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "退役并退场该 Room 下全部记忆(软删,可在「已退场」区恢复)", onClick: () => retire(e.slug, false, true), style: { ...btn, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" }, children: "退场" }) : null
|
|
5291
5701
|
] }),
|
|
5292
|
-
/* @__PURE__ */ (0,
|
|
5702
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "导出该 Room 的记录清单 CSV", onClick: () => exportRecords(e.slug), style: btn, children: "导出" })
|
|
5293
5703
|
] })
|
|
5294
5704
|
] }),
|
|
5295
|
-
expandedRooms.has(e.slug) ? /* @__PURE__ */ (0,
|
|
5296
|
-
(roomRecords[e.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0,
|
|
5297
|
-
/* @__PURE__ */ (0,
|
|
5705
|
+
expandedRooms.has(e.slug) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { margin: "4px 0 2px", padding: "4px 8px", border: "1px dashed var(--dsh-mem-border)", borderRadius: 6 }, children: [
|
|
5706
|
+
(roomRecords[e.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 11, padding: "3px 0", borderBottom: "1px solid var(--dsh-mem-border)" }, children: [
|
|
5707
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: tagClass(it.type), children: typeLabel(it.type) }),
|
|
5298
5708
|
" ",
|
|
5299
|
-
/* @__PURE__ */ (0,
|
|
5300
|
-
/* @__PURE__ */ (0,
|
|
5709
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: it.updatedAt ? fmtTime(it.updatedAt) : "" }),
|
|
5710
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginTop: 2, wordBreak: "break-all", color: "var(--dsh-mem-text-2)" }, children: it.content.length > 120 ? it.content.slice(0, 120) + "…" : it.content })
|
|
5301
5711
|
] }, it.id)),
|
|
5302
|
-
(roomRecords[e.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0,
|
|
5303
|
-
(roomRecords[e.slug]?.total ?? 0) > (roomRecords[e.slug]?.items.length ?? 0) ? /* @__PURE__ */ (0,
|
|
5712
|
+
(roomRecords[e.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.muted, children: "该 Room 暂无记录。" }) : null,
|
|
5713
|
+
(roomRecords[e.slug]?.total ?? 0) > (roomRecords[e.slug]?.items.length ?? 0) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { ...S.muted, fontSize: 11 }, children: "共 " + roomRecords[e.slug].total + " 条,仅显示前 " + roomRecords[e.slug].items.length + " 条" }) : null
|
|
5304
5714
|
] }) : null
|
|
5305
5715
|
] }, e.slug);
|
|
5306
5716
|
}) : null
|
|
5307
5717
|
] }, g.hall);
|
|
5308
5718
|
}),
|
|
5309
|
-
visibleGrown.length > 0 ? /* @__PURE__ */ (0,
|
|
5310
|
-
/* @__PURE__ */ (0,
|
|
5719
|
+
visibleGrown.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginTop: 4 }, children: [
|
|
5720
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { type: "button", onClick: () => setGrownOpen(!grownOpen), style: btn, title: grownOpen ? "收起未注册自生长 Room" : "展开未注册自生长 Room", children: [
|
|
5311
5721
|
grownOpen ? "▾" : "▸",
|
|
5312
5722
|
" 自生长未注册 · 共 ",
|
|
5313
5723
|
visibleGrown.length
|
|
5314
5724
|
] }),
|
|
5315
|
-
/* @__PURE__ */ (0,
|
|
5316
|
-
grownOpen ? /* @__PURE__ */ (0,
|
|
5317
|
-
/* @__PURE__ */ (0,
|
|
5725
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "(只在 tags 里涌现,不在词表 —— 收编后标注器才会优先挂靠)" }),
|
|
5726
|
+
grownOpen ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginTop: 6 }, children: visibleGrown.map((r) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { display: "inline-flex", alignItems: "center", gap: 4 }, children: [
|
|
5727
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5318
5728
|
"span",
|
|
5319
5729
|
{
|
|
5320
5730
|
style: { ...btn, cursor: hiPriv && !busy ? "grab" : "default", borderRadius: 999, padding: "2px 8px", touchAction: "none" },
|
|
@@ -5325,8 +5735,8 @@ var __defProp = Object.defineProperty;
|
|
|
5325
5735
|
children: r.room + " · " + r.count
|
|
5326
5736
|
}
|
|
5327
5737
|
),
|
|
5328
|
-
/* @__PURE__ */ (0,
|
|
5329
|
-
/* @__PURE__ */ (0,
|
|
5738
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: !hiPriv || busy, title: "收编进注册表(source=grown,原地)", onClick: () => adopt(r.room), style: { ...btn, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)", opacity: !hiPriv || busy ? 0.5 : 1 }, children: "收编" }),
|
|
5739
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5330
5740
|
"button",
|
|
5331
5741
|
{
|
|
5332
5742
|
type: "button",
|
|
@@ -5353,8 +5763,8 @@ var __defProp = Object.defineProperty;
|
|
|
5353
5763
|
}
|
|
5354
5764
|
|
|
5355
5765
|
// client/src/tabs/RoomTab.tsx
|
|
5356
|
-
var
|
|
5357
|
-
var
|
|
5766
|
+
var import_react22 = require("react");
|
|
5767
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
5358
5768
|
var btn2 = {
|
|
5359
5769
|
cursor: "pointer",
|
|
5360
5770
|
fontSize: 12,
|
|
@@ -5375,22 +5785,22 @@ var __defProp = Object.defineProperty;
|
|
|
5375
5785
|
}
|
|
5376
5786
|
function RoomTab(props) {
|
|
5377
5787
|
const rpc = props.rpc;
|
|
5378
|
-
const [registry, setRegistry] = (0,
|
|
5379
|
-
const [counts, setCounts] = (0,
|
|
5380
|
-
const [orphanCount, setOrphanCount] = (0,
|
|
5381
|
-
const [busy, setBusy] = (0,
|
|
5382
|
-
const [msg, setMsg] = (0,
|
|
5383
|
-
const [error, setError] = (0,
|
|
5384
|
-
const [hiPriv, setHiPriv] = (0,
|
|
5385
|
-
const [hiPrivBusy, setHiPrivBusy] = (0,
|
|
5386
|
-
const [reg, setReg] = (0,
|
|
5387
|
-
const [editing, setEditing] = (0,
|
|
5388
|
-
const [renaming, setRenaming] = (0,
|
|
5389
|
-
const [expanded, setExpanded] = (0,
|
|
5390
|
-
const [retiredFilter, setRetiredFilter] = (0,
|
|
5391
|
-
const [filter, setFilter] = (0,
|
|
5392
|
-
const [records, setRecords] = (0,
|
|
5393
|
-
const loadAll = (0,
|
|
5788
|
+
const [registry, setRegistry] = (0, import_react22.useState)([]);
|
|
5789
|
+
const [counts, setCounts] = (0, import_react22.useState)([]);
|
|
5790
|
+
const [orphanCount, setOrphanCount] = (0, import_react22.useState)(0);
|
|
5791
|
+
const [busy, setBusy] = (0, import_react22.useState)(false);
|
|
5792
|
+
const [msg, setMsg] = (0, import_react22.useState)(null);
|
|
5793
|
+
const [error, setError] = (0, import_react22.useState)(null);
|
|
5794
|
+
const [hiPriv, setHiPriv] = (0, import_react22.useState)(false);
|
|
5795
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react22.useState)(false);
|
|
5796
|
+
const [reg, setReg] = (0, import_react22.useState)({ slug: "", label: "", description: "" });
|
|
5797
|
+
const [editing, setEditing] = (0, import_react22.useState)(null);
|
|
5798
|
+
const [renaming, setRenaming] = (0, import_react22.useState)(null);
|
|
5799
|
+
const [expanded, setExpanded] = (0, import_react22.useState)(/* @__PURE__ */ new Set());
|
|
5800
|
+
const [retiredFilter, setRetiredFilter] = (0, import_react22.useState)("");
|
|
5801
|
+
const [filter, setFilter] = (0, import_react22.useState)("");
|
|
5802
|
+
const [records, setRecords] = (0, import_react22.useState)({});
|
|
5803
|
+
const loadAll = (0, import_react22.useCallback)(() => {
|
|
5394
5804
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
5395
5805
|
if (r && r.ok) {
|
|
5396
5806
|
setCounts(r.value.rooms ?? []);
|
|
@@ -5399,13 +5809,13 @@ var __defProp = Object.defineProperty;
|
|
|
5399
5809
|
}
|
|
5400
5810
|
}).catch(() => void 0);
|
|
5401
5811
|
}, [rpc]);
|
|
5402
|
-
const loadHiPriv = (0,
|
|
5812
|
+
const loadHiPriv = (0, import_react22.useCallback)(() => {
|
|
5403
5813
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
5404
5814
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
5405
5815
|
}).catch(() => {
|
|
5406
5816
|
});
|
|
5407
5817
|
}, [rpc]);
|
|
5408
|
-
(0,
|
|
5818
|
+
(0, import_react22.useEffect)(() => {
|
|
5409
5819
|
loadAll();
|
|
5410
5820
|
loadHiPriv();
|
|
5411
5821
|
}, [loadAll, loadHiPriv]);
|
|
@@ -5547,11 +5957,11 @@ var __defProp = Object.defineProperty;
|
|
|
5547
5957
|
const visibleRows = normFilter ? rows.filter(
|
|
5548
5958
|
(row2) => row2.slug.toLowerCase().includes(normFilter) || (row2.entry?.label ?? "").toLowerCase().includes(normFilter) || (row2.entry?.aliases ?? []).some((a) => a.toLowerCase().includes(normFilter))
|
|
5549
5959
|
) : rows;
|
|
5550
|
-
return /* @__PURE__ */ (0,
|
|
5551
|
-
/* @__PURE__ */ (0,
|
|
5552
|
-
/* @__PURE__ */ (0,
|
|
5553
|
-
/* @__PURE__ */ (0,
|
|
5554
|
-
/* @__PURE__ */ (0,
|
|
5960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
5961
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { ...S.flexRow, marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
5962
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "Room 级管理:存在(注册/收编/退役)· 名称(显示名/说明/改名)· 条目(展开浏览) · 归类到 hall 请到「Hall」页" }),
|
|
5963
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.grow }),
|
|
5964
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { type: "button", style: btn2, title: "导出无 Room 绑定的孤儿清单(含候选)", onClick: () => run(async () => {
|
|
5555
5965
|
const r = await rpc("dsh-memory/rooms-export", { kind: "orphans" });
|
|
5556
5966
|
if (!r.ok) {
|
|
5557
5967
|
setError(r.error.message);
|
|
@@ -5562,7 +5972,7 @@ var __defProp = Object.defineProperty;
|
|
|
5562
5972
|
"导出孤儿 · ",
|
|
5563
5973
|
orphanCount
|
|
5564
5974
|
] }),
|
|
5565
|
-
/* @__PURE__ */ (0,
|
|
5975
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5566
5976
|
"button",
|
|
5567
5977
|
{
|
|
5568
5978
|
type: "button",
|
|
@@ -5573,35 +5983,35 @@ var __defProp = Object.defineProperty;
|
|
|
5573
5983
|
children: hiPriv ? "高权限:开" : "高权限:关"
|
|
5574
5984
|
}
|
|
5575
5985
|
),
|
|
5576
|
-
/* @__PURE__ */ (0,
|
|
5986
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", style: btn2, onClick: loadAll, children: "刷新" })
|
|
5577
5987
|
] }),
|
|
5578
|
-
editing ? /* @__PURE__ */ (0,
|
|
5579
|
-
/* @__PURE__ */ (0,
|
|
5988
|
+
editing ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { position: "sticky", top: 0, zIndex: 5, background: "var(--dsh-mem-bg-inset)", display: "flex", alignItems: "center", gap: 6, marginBottom: 8, flexWrap: "wrap", padding: "6px 8px", border: "1px solid var(--dsh-mem-accent)", borderRadius: 8 }, children: [
|
|
5989
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: S.muted, children: [
|
|
5580
5990
|
"编辑 ",
|
|
5581
5991
|
editing.slug
|
|
5582
5992
|
] }),
|
|
5583
|
-
/* @__PURE__ */ (0,
|
|
5584
|
-
/* @__PURE__ */ (0,
|
|
5585
|
-
/* @__PURE__ */ (0,
|
|
5586
|
-
/* @__PURE__ */ (0,
|
|
5993
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("input", { value: editing.label, onChange: (e) => setEditing({ ...editing, label: e.target.value }), placeholder: "显示名(可中文)", disabled: busy, style: { ...S.input, width: 140, fontSize: 12 } }),
|
|
5994
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("input", { value: editing.description, onChange: (e) => setEditing({ ...editing, description: e.target.value }), placeholder: "归类说明(喂标注器)", disabled: busy, style: { ...S.input, width: 200, fontSize: 12 } }),
|
|
5995
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, onClick: saveEditing, style: { ...btn2, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" }, children: "保存" }),
|
|
5996
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, onClick: () => setEditing(null), style: btn2, children: "取消" })
|
|
5587
5997
|
] }) : null,
|
|
5588
|
-
renaming ? /* @__PURE__ */ (0,
|
|
5589
|
-
/* @__PURE__ */ (0,
|
|
5998
|
+
renaming ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { position: "sticky", top: 0, zIndex: 5, background: "var(--dsh-mem-bg-inset)", display: "flex", alignItems: "center", gap: 6, marginBottom: 8, flexWrap: "wrap", padding: "6px 8px", border: "1px solid var(--dsh-mem-accent)", borderRadius: 8 }, children: [
|
|
5999
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: S.muted, children: [
|
|
5590
6000
|
"改名 ",
|
|
5591
6001
|
renaming.slug,
|
|
5592
6002
|
" →"
|
|
5593
6003
|
] }),
|
|
5594
|
-
/* @__PURE__ */ (0,
|
|
5595
|
-
/* @__PURE__ */ (0,
|
|
5596
|
-
/* @__PURE__ */ (0,
|
|
5597
|
-
/* @__PURE__ */ (0,
|
|
5598
|
-
/* @__PURE__ */ (0,
|
|
6004
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("input", { value: renaming.to, onChange: (e) => setRenaming({ ...renaming, to: e.target.value }), placeholder: "新 slug(可两级:hall/子类)", disabled: busy, style: { ...S.input, width: 200, fontSize: 12 } }),
|
|
6005
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, onClick: previewRename, style: { ...btn2, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" }, children: "预览" }),
|
|
6006
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, onClick: execRename, style: { ...btn2, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" }, children: "确认执行" }),
|
|
6007
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, onClick: () => setRenaming(null), style: btn2, children: "取消" }),
|
|
6008
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "记录随迁;与反刍并发会互相覆盖,请在反刍空闲时执行。" })
|
|
5599
6009
|
] }) : null,
|
|
5600
|
-
/* @__PURE__ */ (0,
|
|
5601
|
-
/* @__PURE__ */ (0,
|
|
6010
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
6011
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "退场筛选" }),
|
|
5602
6012
|
[["", "全部"], ["active", "活跃"], ["retired", "已退役"]].map(([val, label]) => {
|
|
5603
6013
|
const on = retiredFilter === val;
|
|
5604
|
-
return /* @__PURE__ */ (0,
|
|
6014
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5605
6015
|
"button",
|
|
5606
6016
|
{
|
|
5607
6017
|
type: "button",
|
|
@@ -5621,8 +6031,8 @@ var __defProp = Object.defineProperty;
|
|
|
5621
6031
|
val
|
|
5622
6032
|
);
|
|
5623
6033
|
}),
|
|
5624
|
-
/* @__PURE__ */ (0,
|
|
5625
|
-
/* @__PURE__ */ (0,
|
|
6034
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.grow }),
|
|
6035
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5626
6036
|
"input",
|
|
5627
6037
|
{
|
|
5628
6038
|
value: filter,
|
|
@@ -5631,24 +6041,24 @@ var __defProp = Object.defineProperty;
|
|
|
5631
6041
|
style: { ...S.input, width: 230, fontSize: 12 }
|
|
5632
6042
|
}
|
|
5633
6043
|
),
|
|
5634
|
-
filter ? /* @__PURE__ */ (0,
|
|
6044
|
+
filter ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", style: btn2, onClick: () => setFilter(""), children: "清除" }) : null
|
|
5635
6045
|
] }),
|
|
5636
|
-
/* @__PURE__ */ (0,
|
|
5637
|
-
/* @__PURE__ */ (0,
|
|
5638
|
-
/* @__PURE__ */ (0,
|
|
5639
|
-
/* @__PURE__ */ (0,
|
|
5640
|
-
/* @__PURE__ */ (0,
|
|
5641
|
-
!hiPriv && /* @__PURE__ */ (0,
|
|
6046
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginBottom: 10 }, children: [
|
|
6047
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("input", { value: reg.slug, onChange: (e) => setReg({ ...reg, slug: e.target.value }), placeholder: "slug(如 dsh-plugin 或 dsh-plugin/merge)", disabled: !hiPriv || busy, style: { ...S.input, width: 210, fontSize: 12 } }),
|
|
6048
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("input", { value: reg.label, onChange: (e) => setReg({ ...reg, label: e.target.value }), placeholder: "名称(可中文)", disabled: !hiPriv || busy, style: { ...S.input, width: 110, fontSize: 12 } }),
|
|
6049
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("input", { value: reg.description, onChange: (e) => setReg({ ...reg, description: e.target.value }), placeholder: "归类说明(喂标注器)", disabled: !hiPriv || busy, style: { ...S.input, width: 170, fontSize: 12 } }),
|
|
6050
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: !hiPriv || busy || !reg.slug.trim(), onClick: register, style: { ...btn2, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)", opacity: !hiPriv || busy || !reg.slug.trim() ? 0.5 : 1 }, children: "注册" }),
|
|
6051
|
+
!hiPriv && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "管理操作需先开启高权限模式" })
|
|
5642
6052
|
] }),
|
|
5643
|
-
msg ? /* @__PURE__ */ (0,
|
|
5644
|
-
error ? /* @__PURE__ */ (0,
|
|
5645
|
-
visibleRows.length === 0 ? normFilter ? /* @__PURE__ */ (0,
|
|
6053
|
+
msg ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.hint, children: msg }) : null,
|
|
6054
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.error, children: error }) : null,
|
|
6055
|
+
visibleRows.length === 0 ? normFilter ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: S.intro, children: "无匹配的 Room。" }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: S.intro, children: "暂无 Room:对话/反刍会从标签涌现,或在上方注册。" }) : visibleRows.map((row2) => {
|
|
5646
6056
|
const e = row2.entry;
|
|
5647
6057
|
const retired = e?.status === "retired";
|
|
5648
6058
|
const grownOnly = !e;
|
|
5649
|
-
return /* @__PURE__ */ (0,
|
|
5650
|
-
/* @__PURE__ */ (0,
|
|
5651
|
-
/* @__PURE__ */ (0,
|
|
6059
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 6, border: "1px solid var(--dsh-mem-border)", borderRadius: 8 }, children: [
|
|
6060
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "4px 10px" }, children: [
|
|
6061
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5652
6062
|
"button",
|
|
5653
6063
|
{
|
|
5654
6064
|
type: "button",
|
|
@@ -5658,28 +6068,28 @@ var __defProp = Object.defineProperty;
|
|
|
5658
6068
|
children: expanded.has(row2.slug) ? "▾" : "▸"
|
|
5659
6069
|
}
|
|
5660
6070
|
),
|
|
5661
|
-
/* @__PURE__ */ (0,
|
|
5662
|
-
/* @__PURE__ */ (0,
|
|
6071
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { flex: 1, minWidth: 0, display: "flex", flexWrap: "wrap", gap: "2px 8px", alignItems: "baseline" }, children: [
|
|
6072
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 12, opacity: retired ? 0.6 : 1 }, children: [
|
|
5663
6073
|
row2.slug,
|
|
5664
6074
|
e?.source === "pre-registered" ? " ⭐" : ""
|
|
5665
6075
|
] }),
|
|
5666
|
-
e?.label ? /* @__PURE__ */ (0,
|
|
5667
|
-
/* @__PURE__ */ (0,
|
|
5668
|
-
grownOnly ? /* @__PURE__ */ (0,
|
|
5669
|
-
retired ? /* @__PURE__ */ (0,
|
|
5670
|
-
(e?.aliases ?? []).length > 0 ? /* @__PURE__ */ (0,
|
|
6076
|
+
e?.label ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: e.label }) : null,
|
|
6077
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: row2.count + " 条" }),
|
|
6078
|
+
grownOnly ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "(自生长未注册)" }) : null,
|
|
6079
|
+
retired ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "已退役" }) : null,
|
|
6080
|
+
(e?.aliases ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { ...S.muted, wordBreak: "break-all" }, children: "别名: " + (e?.aliases ?? []).join(", ") }) : null
|
|
5671
6081
|
] }),
|
|
5672
|
-
/* @__PURE__ */ (0,
|
|
5673
|
-
!hiPriv || grownOnly ? null : /* @__PURE__ */ (0,
|
|
5674
|
-
/* @__PURE__ */ (0,
|
|
6082
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", gap: 6, flexShrink: 0, alignItems: "center" }, children: [
|
|
6083
|
+
!hiPriv || grownOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
6084
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, title: "编辑显示名/归类说明", onClick: () => {
|
|
5675
6085
|
setEditing({ slug: row2.slug, label: e?.label ?? "", description: e?.description ?? "" });
|
|
5676
6086
|
setRenaming(null);
|
|
5677
6087
|
}, style: btn2, children: "编辑" }),
|
|
5678
|
-
/* @__PURE__ */ (0,
|
|
6088
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, title: "改名(可两级 slug;记录随迁,旧名进别名)", onClick: () => {
|
|
5679
6089
|
setRenaming({ slug: row2.slug, to: "" });
|
|
5680
6090
|
setEditing(null);
|
|
5681
6091
|
}, style: btn2, children: "改名" }),
|
|
5682
|
-
/* @__PURE__ */ (0,
|
|
6092
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5683
6093
|
"button",
|
|
5684
6094
|
{
|
|
5685
6095
|
type: "button",
|
|
@@ -5690,29 +6100,29 @@ var __defProp = Object.defineProperty;
|
|
|
5690
6100
|
children: retired ? "恢复" : "退役"
|
|
5691
6101
|
}
|
|
5692
6102
|
),
|
|
5693
|
-
!retired ? /* @__PURE__ */ (0,
|
|
6103
|
+
!retired ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, title: "退役并退场该 Room 下全部记忆(软删,可在「已退场」区恢复)", onClick: () => retire(row2.slug, false, true), style: { ...btn2, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" }, children: "退场" }) : null
|
|
5694
6104
|
] }),
|
|
5695
|
-
grownOnly ? /* @__PURE__ */ (0,
|
|
5696
|
-
/* @__PURE__ */ (0,
|
|
5697
|
-
/* @__PURE__ */ (0,
|
|
6105
|
+
grownOnly ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
6106
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: !hiPriv || busy, title: "收编进注册表(source=grown)", onClick: () => adopt(row2.slug), style: { ...btn2, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)", opacity: !hiPriv || busy ? 0.5 : 1 }, children: "收编" }),
|
|
6107
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: !hiPriv || busy, title: "退场该 Room 下全部记忆(软删,可在「已退场」区恢复)", onClick: () => {
|
|
5698
6108
|
setRenaming(null);
|
|
5699
6109
|
retire(row2.slug, false, true);
|
|
5700
6110
|
}, style: { ...btn2, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)", opacity: !hiPriv || busy ? 0.5 : 1 }, children: "退场" })
|
|
5701
6111
|
] }) : null,
|
|
5702
|
-
/* @__PURE__ */ (0,
|
|
6112
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, title: "导出该 Room 的记录清单 CSV", onClick: () => exportRecords(row2.slug), style: btn2, children: "导出" })
|
|
5703
6113
|
] })
|
|
5704
6114
|
] }),
|
|
5705
|
-
expanded.has(row2.slug) ? /* @__PURE__ */ (0,
|
|
5706
|
-
(records[row2.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0,
|
|
5707
|
-
/* @__PURE__ */ (0,
|
|
6115
|
+
expanded.has(row2.slug) ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { margin: "0 10px 6px", padding: "4px 8px", border: "1px dashed var(--dsh-mem-border)", borderRadius: 6 }, children: [
|
|
6116
|
+
(records[row2.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { fontSize: 11, padding: "3px 0", borderBottom: "1px solid var(--dsh-mem-border)" }, children: [
|
|
6117
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: tagClass(it.type), children: typeLabel(it.type) }),
|
|
5708
6118
|
" ",
|
|
5709
|
-
it.retired ? /* @__PURE__ */ (0,
|
|
6119
|
+
it.retired ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "[已退场]" }) : null,
|
|
5710
6120
|
" ",
|
|
5711
|
-
/* @__PURE__ */ (0,
|
|
5712
|
-
/* @__PURE__ */ (0,
|
|
6121
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: it.updatedAt ? fmtTime(it.updatedAt) : "" }),
|
|
6122
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginTop: 2, wordBreak: "break-all", color: "var(--dsh-mem-text-2)", opacity: it.retired ? 0.55 : 1 }, children: it.content.length > 140 ? it.content.slice(0, 140) + "…" : it.content })
|
|
5713
6123
|
] }, it.id)),
|
|
5714
|
-
(records[row2.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0,
|
|
5715
|
-
(records[row2.slug]?.total ?? 0) > (records[row2.slug]?.items.length ?? 0) ? /* @__PURE__ */ (0,
|
|
6124
|
+
(records[row2.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.muted, children: "该 Room 暂无记忆条目。" }) : null,
|
|
6125
|
+
(records[row2.slug]?.total ?? 0) > (records[row2.slug]?.items.length ?? 0) ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { ...S.muted, fontSize: 11 }, children: "共 " + records[row2.slug].total + " 条,仅显示前 " + records[row2.slug].items.length + " 条" }) : null
|
|
5716
6126
|
] }) : null
|
|
5717
6127
|
] }, row2.slug);
|
|
5718
6128
|
})
|
|
@@ -5720,13 +6130,13 @@ var __defProp = Object.defineProperty;
|
|
|
5720
6130
|
}
|
|
5721
6131
|
|
|
5722
6132
|
// client/src/tabs/ScenesTab.tsx
|
|
5723
|
-
var
|
|
5724
|
-
var
|
|
6133
|
+
var import_react23 = require("react");
|
|
6134
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
5725
6135
|
function SceneCard(props) {
|
|
5726
6136
|
const s = props.s;
|
|
5727
|
-
const [open, setOpen] = (0,
|
|
5728
|
-
return /* @__PURE__ */ (0,
|
|
5729
|
-
/* @__PURE__ */ (0,
|
|
6137
|
+
const [open, setOpen] = (0, import_react23.useState)(false);
|
|
6138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "dsh-mem-card dsh-mem-card-hover", style: S.card, children: [
|
|
6139
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
5730
6140
|
"div",
|
|
5731
6141
|
{
|
|
5732
6142
|
style: { ...S.sceneHead, cursor: "pointer", userSelect: "none" },
|
|
@@ -5734,23 +6144,23 @@ var __defProp = Object.defineProperty;
|
|
|
5734
6144
|
setOpen(!open);
|
|
5735
6145
|
},
|
|
5736
6146
|
children: [
|
|
5737
|
-
/* @__PURE__ */ (0,
|
|
5738
|
-
/* @__PURE__ */ (0,
|
|
5739
|
-
s.heat ? /* @__PURE__ */ (0,
|
|
5740
|
-
/* @__PURE__ */ (0,
|
|
5741
|
-
/* @__PURE__ */ (0,
|
|
6147
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "dsh-mem-scene-chev", style: { transform: open ? "rotate(90deg)" : "none" }, children: "▸" }),
|
|
6148
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: S.sceneTitle, children: s.path }),
|
|
6149
|
+
s.heat ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: S.muted, children: "热度 " + s.heat }) : null,
|
|
6150
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: S.grow }),
|
|
6151
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: S.muted, children: "更新 " + fmtTime(s.updated) })
|
|
5742
6152
|
]
|
|
5743
6153
|
}
|
|
5744
6154
|
),
|
|
5745
|
-
s.summary ? /* @__PURE__ */ (0,
|
|
5746
|
-
open ? /* @__PURE__ */ (0,
|
|
6155
|
+
s.summary ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { ...S.muted, marginBottom: 6 }, children: s.summary }) : null,
|
|
6156
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { style: S.pre, children: s.content || "(空)" }) : null
|
|
5747
6157
|
] });
|
|
5748
6158
|
}
|
|
5749
6159
|
function ScenesTab(props) {
|
|
5750
6160
|
const rpc = props.rpc;
|
|
5751
|
-
const [items, setItems] = (0,
|
|
5752
|
-
const [error, setError] = (0,
|
|
5753
|
-
const load = (0,
|
|
6161
|
+
const [items, setItems] = (0, import_react23.useState)(null);
|
|
6162
|
+
const [error, setError] = (0, import_react23.useState)(null);
|
|
6163
|
+
const load = (0, import_react23.useCallback)(() => {
|
|
5754
6164
|
rpc("dsh-memory/scenes", {}).then((r) => {
|
|
5755
6165
|
if (r && r.ok) {
|
|
5756
6166
|
setItems(r.value.items);
|
|
@@ -5760,25 +6170,25 @@ var __defProp = Object.defineProperty;
|
|
|
5760
6170
|
setError(String(e && e.message || e));
|
|
5761
6171
|
});
|
|
5762
6172
|
}, [rpc]);
|
|
5763
|
-
(0,
|
|
6173
|
+
(0, import_react23.useEffect)(() => {
|
|
5764
6174
|
load();
|
|
5765
6175
|
}, [load]);
|
|
5766
|
-
return /* @__PURE__ */ (0,
|
|
5767
|
-
/* @__PURE__ */ (0,
|
|
5768
|
-
/* @__PURE__ */ (0,
|
|
5769
|
-
/* @__PURE__ */ (0,
|
|
5770
|
-
/* @__PURE__ */ (0,
|
|
6176
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
|
|
6177
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
6178
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: S.muted, children: items ? items.length + " 个场景块" : "加载中…" }),
|
|
6179
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: S.grow }),
|
|
6180
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
5771
6181
|
] }),
|
|
5772
|
-
error ? /* @__PURE__ */ (0,
|
|
5773
|
-
items && items.length === 0 ? /* @__PURE__ */ (0,
|
|
6182
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: S.error, children: error }) : null,
|
|
6183
|
+
items && items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { style: S.intro, children: "暂无场景块。累计 5 条新记忆后 L2 会自动整合出第一个场景。" }) : null,
|
|
5774
6184
|
(items || []).map((s) => {
|
|
5775
|
-
return /* @__PURE__ */ (0,
|
|
6185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SceneCard, { s }, s.path);
|
|
5776
6186
|
})
|
|
5777
6187
|
] });
|
|
5778
6188
|
}
|
|
5779
6189
|
|
|
5780
6190
|
// client/src/panel.tsx
|
|
5781
|
-
var
|
|
6191
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
5782
6192
|
var TABS = [
|
|
5783
6193
|
["overview", "概览"],
|
|
5784
6194
|
["records", "记忆"],
|
|
@@ -5799,10 +6209,10 @@ var __defProp = Object.defineProperty;
|
|
|
5799
6209
|
];
|
|
5800
6210
|
function MemoryPanel(props) {
|
|
5801
6211
|
const rpc = props.rpc;
|
|
5802
|
-
const [tab, setTab] = (0,
|
|
5803
|
-
const [skin, setSkinState] = (0,
|
|
6212
|
+
const [tab, setTab] = (0, import_react24.useState)("overview");
|
|
6213
|
+
const [skin, setSkinState] = (0, import_react24.useState)(() => getSkin());
|
|
5804
6214
|
ensureThemeStyle(skin);
|
|
5805
|
-
(0,
|
|
6215
|
+
(0, import_react24.useEffect)(() => {
|
|
5806
6216
|
applySkin(skin);
|
|
5807
6217
|
watchSidebarIcon();
|
|
5808
6218
|
}, [skin]);
|
|
@@ -5811,21 +6221,21 @@ var __defProp = Object.defineProperty;
|
|
|
5811
6221
|
setSkinState(next);
|
|
5812
6222
|
};
|
|
5813
6223
|
let body;
|
|
5814
|
-
if (tab === "overview") body = /* @__PURE__ */ (0,
|
|
5815
|
-
else if (tab === "records") body = /* @__PURE__ */ (0,
|
|
5816
|
-
else if (tab === "conflicts") body = /* @__PURE__ */ (0,
|
|
5817
|
-
else if (tab === "scenes") body = /* @__PURE__ */ (0,
|
|
5818
|
-
else if (tab === "rooms") body = /* @__PURE__ */ (0,
|
|
5819
|
-
else if (tab === "room") body = /* @__PURE__ */ (0,
|
|
5820
|
-
else if (tab === "persona") body = /* @__PURE__ */ (0,
|
|
5821
|
-
else if (tab === "cost") body = /* @__PURE__ */ (0,
|
|
5822
|
-
else if (tab === "connect") body = /* @__PURE__ */ (0,
|
|
5823
|
-
else if (tab === "skills") body = /* @__PURE__ */ (0,
|
|
5824
|
-
else body = /* @__PURE__ */ (0,
|
|
5825
|
-
return /* @__PURE__ */ (0,
|
|
5826
|
-
/* @__PURE__ */ (0,
|
|
5827
|
-
/* @__PURE__ */ (0,
|
|
5828
|
-
/* @__PURE__ */ (0,
|
|
6224
|
+
if (tab === "overview") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(OverviewTab, { rpc });
|
|
6225
|
+
else if (tab === "records") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(RecordsTab, { rpc });
|
|
6226
|
+
else if (tab === "conflicts") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ConflictsTab, { rpc });
|
|
6227
|
+
else if (tab === "scenes") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ScenesTab, { rpc });
|
|
6228
|
+
else if (tab === "rooms") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(RoomsTab, { rpc });
|
|
6229
|
+
else if (tab === "room") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(RoomTab, { rpc });
|
|
6230
|
+
else if (tab === "persona") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PersonaTab, { rpc });
|
|
6231
|
+
else if (tab === "cost") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CostTab, { rpc });
|
|
6232
|
+
else if (tab === "connect") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ConnectTab, { rpc });
|
|
6233
|
+
else if (tab === "skills") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SkillsTab, { rpc });
|
|
6234
|
+
else body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LogTab, { rpc });
|
|
6235
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "dsh-mem-root", style: S.section, children: [
|
|
6236
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { style: S.heading, children: "记忆 (Memory)" }),
|
|
6237
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: S.intro, children: "L0~L3 分层蒸馏记忆:浏览被记住的内容,控制记忆模式开关。" }),
|
|
6238
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
5829
6239
|
"div",
|
|
5830
6240
|
{
|
|
5831
6241
|
style: {
|
|
@@ -5837,8 +6247,8 @@ var __defProp = Object.defineProperty;
|
|
|
5837
6247
|
marginBottom: 10
|
|
5838
6248
|
},
|
|
5839
6249
|
children: [
|
|
5840
|
-
/* @__PURE__ */ (0,
|
|
5841
|
-
SKIN_OPTS.map((s) => /* @__PURE__ */ (0,
|
|
6250
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)", marginRight: 4 }, children: "皮肤" }),
|
|
6251
|
+
SKIN_OPTS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5842
6252
|
"button",
|
|
5843
6253
|
{
|
|
5844
6254
|
className: skin === s[0] ? "dsh-mem-tab dsh-mem-tab-on" : "dsh-mem-tab",
|
|
@@ -5851,8 +6261,8 @@ var __defProp = Object.defineProperty;
|
|
|
5851
6261
|
]
|
|
5852
6262
|
}
|
|
5853
6263
|
),
|
|
5854
|
-
/* @__PURE__ */ (0,
|
|
5855
|
-
return /* @__PURE__ */ (0,
|
|
6264
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: S.tabbar, children: TABS.map((t) => {
|
|
6265
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5856
6266
|
"button",
|
|
5857
6267
|
{
|
|
5858
6268
|
className: tab === t[0] ? "dsh-mem-tab dsh-mem-tab-on" : "dsh-mem-tab",
|
|
@@ -5869,7 +6279,7 @@ var __defProp = Object.defineProperty;
|
|
|
5869
6279
|
}
|
|
5870
6280
|
|
|
5871
6281
|
// client/src/pill/MemoryModePill.tsx
|
|
5872
|
-
var
|
|
6282
|
+
var import_react27 = require("react");
|
|
5873
6283
|
|
|
5874
6284
|
// src/util/context-occupancy.ts
|
|
5875
6285
|
var CONTEXT_METER_CIRCUMFERENCE = 34.55751918948772;
|
|
@@ -6185,23 +6595,23 @@ var __defProp = Object.defineProperty;
|
|
|
6185
6595
|
}
|
|
6186
6596
|
|
|
6187
6597
|
// client/src/pill/WingWheel.tsx
|
|
6188
|
-
var
|
|
6598
|
+
var import_react26 = require("react");
|
|
6189
6599
|
|
|
6190
6600
|
// client/src/pill/SessionInfoArea.tsx
|
|
6191
|
-
var
|
|
6192
|
-
var
|
|
6601
|
+
var import_react25 = require("react");
|
|
6602
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
6193
6603
|
function sinfoCell(val, label, title) {
|
|
6194
|
-
return /* @__PURE__ */ (0,
|
|
6195
|
-
/* @__PURE__ */ (0,
|
|
6196
|
-
/* @__PURE__ */ (0,
|
|
6604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { title: title || void 0, children: [
|
|
6605
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "dsh-mem-sinfo-val", children: val }),
|
|
6606
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "dsh-mem-sinfo-label", children: label })
|
|
6197
6607
|
] });
|
|
6198
6608
|
}
|
|
6199
6609
|
function SessionInfoArea(props) {
|
|
6200
6610
|
const rpc = props.rpc;
|
|
6201
6611
|
const sessionId = props.sessionId;
|
|
6202
|
-
const [stats, setStats] = (0,
|
|
6203
|
-
const busyRef = (0,
|
|
6204
|
-
(0,
|
|
6612
|
+
const [stats, setStats] = (0, import_react25.useState)(void 0);
|
|
6613
|
+
const busyRef = (0, import_react25.useRef)(false);
|
|
6614
|
+
(0, import_react25.useEffect)(() => {
|
|
6205
6615
|
if (!rpc || !sessionId) return void 0;
|
|
6206
6616
|
let alive = true;
|
|
6207
6617
|
let timer = null;
|
|
@@ -6234,7 +6644,7 @@ var __defProp = Object.defineProperty;
|
|
|
6234
6644
|
}, [rpc, sessionId]);
|
|
6235
6645
|
if (stats === null) return null;
|
|
6236
6646
|
if (stats === void 0) {
|
|
6237
|
-
return /* @__PURE__ */ (0,
|
|
6647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "dsh-mem-sinfo", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "dsh-mem-sinfo-grid", children: [
|
|
6238
6648
|
sinfoCell("…", "召回命中"),
|
|
6239
6649
|
sinfoCell("…", "攒批进度"),
|
|
6240
6650
|
sinfoCell("…", "本会话记忆"),
|
|
@@ -6283,111 +6693,18 @@ var __defProp = Object.defineProperty;
|
|
|
6283
6693
|
else if (stats.retrieval === "none") note = "检索不可用(FTS 与向量均失效)";
|
|
6284
6694
|
}
|
|
6285
6695
|
const ago = fmtAgo(gl.lastExtractAt);
|
|
6286
|
-
return /* @__PURE__ */ (0,
|
|
6287
|
-
warn ? /* @__PURE__ */ (0,
|
|
6288
|
-
/* @__PURE__ */ (0,
|
|
6696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "dsh-mem-sinfo", children: [
|
|
6697
|
+
warn ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "dsh-mem-sinfo-warn", children: warn }) : null,
|
|
6698
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "dsh-mem-sinfo-grid", children: [
|
|
6289
6699
|
sinfoCell(rcVal, rcLabel, rcTitle),
|
|
6290
6700
|
sinfoCell(dVal, dLabel, dTitle),
|
|
6291
6701
|
sinfoCell(String(di.producedRecords || 0), "本会话记忆", pTitle),
|
|
6292
6702
|
sinfoCell(stats.l0Count != null ? String(stats.l0Count) : "…", "会话消息")
|
|
6293
6703
|
] }),
|
|
6294
|
-
note ? /* @__PURE__ */ (0,
|
|
6295
|
-
/* @__PURE__ */ (0,
|
|
6296
|
-
] });
|
|
6297
|
-
}
|
|
6298
|
-
|
|
6299
|
-
// client/src/pill/SessionRecalledArea.tsx
|
|
6300
|
-
var import_react24 = require("react");
|
|
6301
|
-
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
6302
|
-
var SHOW_CAP = 6;
|
|
6303
|
-
var POLL_MS2 = 4e3;
|
|
6304
|
-
var MATURITY_LABEL = { high: "成熟·高", mid: "成熟·中", low: "成熟·低" };
|
|
6305
|
-
function SessionRecalledArea(props) {
|
|
6306
|
-
const rpc = props.rpc;
|
|
6307
|
-
const sessionId = props.sessionId;
|
|
6308
|
-
const [records, setRecords] = (0, import_react24.useState)(void 0);
|
|
6309
|
-
(0, import_react24.useEffect)(() => {
|
|
6310
|
-
if (!rpc || !sessionId) return void 0;
|
|
6311
|
-
let alive = true;
|
|
6312
|
-
let timer = null;
|
|
6313
|
-
let seq = 0;
|
|
6314
|
-
const tick = () => {
|
|
6315
|
-
const token = ++seq;
|
|
6316
|
-
rpc("dsh-memory/session-recalled", { sessionId }).then((r) => {
|
|
6317
|
-
if (!alive || token !== seq) return;
|
|
6318
|
-
if (r && r.ok && r.value) {
|
|
6319
|
-
registerTypeCatalog(r.value.typeCatalog);
|
|
6320
|
-
setRecords(r.value.records);
|
|
6321
|
-
}
|
|
6322
|
-
}).catch(() => {
|
|
6323
|
-
}).then(() => {
|
|
6324
|
-
if (alive) timer = setTimeout(tick, POLL_MS2);
|
|
6325
|
-
});
|
|
6326
|
-
};
|
|
6327
|
-
tick();
|
|
6328
|
-
return () => {
|
|
6329
|
-
alive = false;
|
|
6330
|
-
if (timer) clearTimeout(timer);
|
|
6331
|
-
};
|
|
6332
|
-
}, [rpc, sessionId]);
|
|
6333
|
-
if (records === void 0) return null;
|
|
6334
|
-
const rows = records.filter((r) => r.superseded !== true || r.retired === true);
|
|
6335
|
-
const recentFirst = [...rows].reverse();
|
|
6336
|
-
const shown = recentFirst.slice(0, SHOW_CAP);
|
|
6337
|
-
const hidden = recentFirst.length - shown.length;
|
|
6338
|
-
const allSuperseded = rows.length === 0 && records.length > 0;
|
|
6339
|
-
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "dsh-mem-sinfo", children: [
|
|
6340
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6341
|
-
"div",
|
|
6342
|
-
{
|
|
6343
|
-
style: { fontSize: 11, color: "var(--dsh-mem-text-3)", marginBottom: 6 },
|
|
6344
|
-
title: "本会话召回、且正文仍在上下文里的记忆(正文被摘要顶掉的已折叠不显示;清空会话才清除;不是常驻注入)",
|
|
6345
|
-
children: "本会话召回 " + rows.length + " 条"
|
|
6346
|
-
}
|
|
6347
|
-
),
|
|
6348
|
-
allSuperseded ? (
|
|
6349
|
-
// 不是“还没召回到”——那批确实注入过,只是正文已被摘要顶掉。说谎的空态比不显示更糟。
|
|
6350
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)", lineHeight: "16px" }, children: "本会话注入过的 " + records.length + " 条记忆正文已被摘要取代" })
|
|
6351
|
-
) : records.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)", lineHeight: "16px" }, children: "还没召回到记忆(聊几轮后按相关性自动浮现)" }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
6352
|
-
shown.map((r) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: rowStyle, title: rowTitle(r), children: [
|
|
6353
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6354
|
-
"span",
|
|
6355
|
-
{
|
|
6356
|
-
className: tagClass(r.type),
|
|
6357
|
-
style: { flexShrink: 0, whiteSpace: "nowrap" },
|
|
6358
|
-
children: typeLabel(r.type)
|
|
6359
|
-
}
|
|
6360
|
-
),
|
|
6361
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "dsh-mem-sinfo-val", style: r.retired === true ? STALE_TEXT_STYLE : textStyle, children: r.content }),
|
|
6362
|
-
r.retired === true ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 10, color: "var(--dsh-mem-text-3)", whiteSpace: "nowrap", flexShrink: 0 }, children: "已判过时" }) : null,
|
|
6363
|
-
r.maturity ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 10, color: "var(--dsh-mem-text-3)", whiteSpace: "nowrap", flexShrink: 0 }, children: MATURITY_LABEL[r.maturity] }) : null
|
|
6364
|
-
] }, r.id)),
|
|
6365
|
-
hidden > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: "+ " + hidden + " 条更早召回(详见面板「记忆」页)" }) : null
|
|
6366
|
-
] })
|
|
6704
|
+
note ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "dsh-mem-sinfo-note", children: note }) : null,
|
|
6705
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "dsh-mem-sinfo-sum", children: "待蒸馏 " + (gl.pendingTotal || 0) + " · 上次蒸馏 " + (ago || "尚未蒸馏") })
|
|
6367
6706
|
] });
|
|
6368
6707
|
}
|
|
6369
|
-
var rowStyle = {
|
|
6370
|
-
display: "flex",
|
|
6371
|
-
alignItems: "flex-start",
|
|
6372
|
-
gap: 6,
|
|
6373
|
-
lineHeight: "16px"
|
|
6374
|
-
};
|
|
6375
|
-
var textStyle = {
|
|
6376
|
-
fontSize: 12,
|
|
6377
|
-
lineHeight: "16px",
|
|
6378
|
-
fontWeight: 400,
|
|
6379
|
-
minWidth: 0,
|
|
6380
|
-
display: "-webkit-box",
|
|
6381
|
-
WebkitLineClamp: 2,
|
|
6382
|
-
WebkitBoxOrient: "vertical",
|
|
6383
|
-
overflow: "hidden"
|
|
6384
|
-
};
|
|
6385
|
-
var STALE_TEXT_STYLE = { ...textStyle, textDecoration: "line-through" };
|
|
6386
|
-
function rowTitle(r) {
|
|
6387
|
-
const head = "[" + typeLabel(r.type) + "] " + r.content;
|
|
6388
|
-
const sc = r.usageScenario && r.usageScenario.length > 0 ? "\n使用场景:" + r.usageScenario.join(";") : "";
|
|
6389
|
-
return head + sc;
|
|
6390
|
-
}
|
|
6391
6708
|
|
|
6392
6709
|
// client/src/pill/WingWheel.tsx
|
|
6393
6710
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
@@ -6433,17 +6750,8 @@ var __defProp = Object.defineProperty;
|
|
|
6433
6750
|
function WingWheel(props) {
|
|
6434
6751
|
ensureThemeStyle();
|
|
6435
6752
|
const isOff = props.mode === "off";
|
|
6436
|
-
const [overview, setOverview] = (0,
|
|
6437
|
-
|
|
6438
|
-
const [localError, setLocalError] = (0, import_react25.useState)(null);
|
|
6439
|
-
const timersRef = (0, import_react25.useRef)([]);
|
|
6440
|
-
(0, import_react25.useEffect)(
|
|
6441
|
-
() => () => {
|
|
6442
|
-
for (const t of timersRef.current) window.clearTimeout(t);
|
|
6443
|
-
},
|
|
6444
|
-
[]
|
|
6445
|
-
);
|
|
6446
|
-
(0, import_react25.useEffect)(() => {
|
|
6753
|
+
const [overview, setOverview] = (0, import_react26.useState)(null);
|
|
6754
|
+
(0, import_react26.useEffect)(() => {
|
|
6447
6755
|
let alive = true;
|
|
6448
6756
|
props.rpc("dsh-memory/wing-overview", {}).then((r) => {
|
|
6449
6757
|
if (!alive) return;
|
|
@@ -6459,58 +6767,28 @@ var __defProp = Object.defineProperty;
|
|
|
6459
6767
|
if (id === "general") return overview.general;
|
|
6460
6768
|
return overview.corners.find((c) => c.id === id)?.count ?? 0;
|
|
6461
6769
|
};
|
|
6462
|
-
const
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
const tick = () => {
|
|
6469
|
-
polls++;
|
|
6470
|
-
props.rpc("dsh-memory/wing-overview", {}).then((r) => {
|
|
6471
|
-
const v = r && r.ok ? r.value : null;
|
|
6472
|
-
if (v) setOverview(v);
|
|
6473
|
-
if (v && v.unlabeled === 0 || polls >= 20) finish();
|
|
6474
|
-
else {
|
|
6475
|
-
const t = window.setTimeout(tick, 3e3);
|
|
6476
|
-
timersRef.current.push(t);
|
|
6477
|
-
}
|
|
6478
|
-
}).catch(() => finish());
|
|
6479
|
-
};
|
|
6480
|
-
props.rpc("dsh-memory/wing-backfill", {}).then((r) => {
|
|
6481
|
-
if (!r || !r.ok) {
|
|
6482
|
-
setLocalError(r && r.error ? "回填失败:" + r.error.message : "回填失败");
|
|
6483
|
-
finish();
|
|
6484
|
-
return;
|
|
6485
|
-
}
|
|
6486
|
-
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
6487
|
-
}).catch((e) => {
|
|
6488
|
-
setLocalError("回填失败:" + String(e && e.message || e));
|
|
6489
|
-
finish();
|
|
6490
|
-
});
|
|
6491
|
-
};
|
|
6492
|
-
const boxRef = (0, import_react25.useRef)(null);
|
|
6493
|
-
const startRef = (0, import_react25.useRef)(null);
|
|
6494
|
-
const movedRef = (0, import_react25.useRef)(false);
|
|
6495
|
-
const downIndexRef = (0, import_react25.useRef)(null);
|
|
6496
|
-
const dragTargetRef = (0, import_react25.useRef)(null);
|
|
6497
|
-
const [drag, setDrag] = (0, import_react25.useState)(null);
|
|
6770
|
+
const boxRef = (0, import_react26.useRef)(null);
|
|
6771
|
+
const startRef = (0, import_react26.useRef)(null);
|
|
6772
|
+
const movedRef = (0, import_react26.useRef)(false);
|
|
6773
|
+
const downIndexRef = (0, import_react26.useRef)(null);
|
|
6774
|
+
const dragTargetRef = (0, import_react26.useRef)(null);
|
|
6775
|
+
const [drag, setDrag] = (0, import_react26.useState)(null);
|
|
6498
6776
|
const lockedIndex = (() => {
|
|
6499
6777
|
if (props.halls.length !== 1 || !overview) return null;
|
|
6500
6778
|
const i = overview.corners.findIndex((c) => c.id === props.halls[0]);
|
|
6501
6779
|
return i >= 0 ? i : null;
|
|
6502
6780
|
})();
|
|
6503
6781
|
const activeCorner = drag ? drag.index : lockedIndex;
|
|
6504
|
-
const blockPosRef = (0,
|
|
6782
|
+
const blockPosRef = (0, import_react26.useRef)(
|
|
6505
6783
|
activeCorner != null ? cornerXY(activeCorner) : { x: CENTER, y: CENTER }
|
|
6506
6784
|
);
|
|
6507
|
-
const blockTargetRef = (0,
|
|
6508
|
-
const [blockPos, setBlockPos] = (0,
|
|
6509
|
-
(0,
|
|
6785
|
+
const blockTargetRef = (0, import_react26.useRef)(blockPosRef.current);
|
|
6786
|
+
const [blockPos, setBlockPos] = (0, import_react26.useState)(blockPosRef.current);
|
|
6787
|
+
(0, import_react26.useEffect)(() => {
|
|
6510
6788
|
blockTargetRef.current = activeCorner != null ? cornerXY(activeCorner) : { x: CENTER, y: CENTER };
|
|
6511
6789
|
}, [activeCorner]);
|
|
6512
|
-
const reducedMotionRef = (0,
|
|
6513
|
-
(0,
|
|
6790
|
+
const reducedMotionRef = (0, import_react26.useRef)(false);
|
|
6791
|
+
(0, import_react26.useEffect)(() => {
|
|
6514
6792
|
const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
6515
6793
|
const apply2 = () => {
|
|
6516
6794
|
reducedMotionRef.current = mq.matches;
|
|
@@ -6519,7 +6797,7 @@ var __defProp = Object.defineProperty;
|
|
|
6519
6797
|
mq.addEventListener("change", apply2);
|
|
6520
6798
|
return () => mq.removeEventListener("change", apply2);
|
|
6521
6799
|
}, []);
|
|
6522
|
-
(0,
|
|
6800
|
+
(0, import_react26.useEffect)(() => {
|
|
6523
6801
|
let raf = 0;
|
|
6524
6802
|
const loop = () => {
|
|
6525
6803
|
const cur = blockPosRef.current;
|
|
@@ -6827,32 +7105,7 @@ var __defProp = Object.defineProperty;
|
|
|
6827
7105
|
onChange: (key) => props.onCommitRecall(key === "on" ? true : key === "off" ? false : null)
|
|
6828
7106
|
}
|
|
6829
7107
|
) }) : null,
|
|
6830
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.
|
|
6831
|
-
"div",
|
|
6832
|
-
{
|
|
6833
|
-
style: {
|
|
6834
|
-
display: "flex",
|
|
6835
|
-
justifyContent: "space-between",
|
|
6836
|
-
alignItems: "center",
|
|
6837
|
-
gap: 8,
|
|
6838
|
-
marginTop: 10
|
|
6839
|
-
},
|
|
6840
|
-
children: [
|
|
6841
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: overview ? `未打标 ${overview.unlabeled} 条` : "未打标计数加载中" }),
|
|
6842
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6843
|
-
ActionButton,
|
|
6844
|
-
{
|
|
6845
|
-
label: backfillBusy ? "回填中…" : "回填",
|
|
6846
|
-
title: "对存量未打标记忆批量补打 wing 标签",
|
|
6847
|
-
disabled: !overview || overview.unlabeled === 0 || backfillBusy,
|
|
6848
|
-
onClick: () => backfill()
|
|
6849
|
-
}
|
|
6850
|
-
)
|
|
6851
|
-
]
|
|
6852
|
-
}
|
|
6853
|
-
),
|
|
6854
|
-
props.error || localError ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-danger)", marginTop: 8 }, children: props.error || localError }) : null,
|
|
6855
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SessionRecalledArea, { rpc: props.rpc, sessionId: props.sessionId }),
|
|
7108
|
+
props.error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-danger)", marginTop: 8 }, children: props.error }) : null,
|
|
6856
7109
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SessionInfoArea, { rpc: props.rpc, sessionId: props.sessionId })
|
|
6857
7110
|
] });
|
|
6858
7111
|
}
|
|
@@ -6875,9 +7128,9 @@ var __defProp = Object.defineProperty;
|
|
|
6875
7128
|
}
|
|
6876
7129
|
var LABEL_FALLBACK = ["工作", "人际", "学习", "创作娱乐", "居家", "健康", "财务", "出行"];
|
|
6877
7130
|
function useViewportClamp(popRef) {
|
|
6878
|
-
const shiftRef = (0,
|
|
6879
|
-
const [shiftX, setShiftX] = (0,
|
|
6880
|
-
(0,
|
|
7131
|
+
const shiftRef = (0, import_react26.useRef)(0);
|
|
7132
|
+
const [shiftX, setShiftX] = (0, import_react26.useState)(0);
|
|
7133
|
+
(0, import_react26.useEffect)(() => {
|
|
6881
7134
|
const clamp = () => {
|
|
6882
7135
|
const el = popRef.current;
|
|
6883
7136
|
if (!el) return;
|
|
@@ -6911,20 +7164,20 @@ var __defProp = Object.defineProperty;
|
|
|
6911
7164
|
function MemoryModePill(props) {
|
|
6912
7165
|
const rpc = props.rpc;
|
|
6913
7166
|
const sessionId = props.sessionId || props.session && props.session.sessionId;
|
|
6914
|
-
const [mode, setMode] = (0,
|
|
6915
|
-
const [recall, setRecall] = (0,
|
|
6916
|
-
const [recallResolved, setRecallResolved] = (0,
|
|
6917
|
-
const [halls, setWings] = (0,
|
|
6918
|
-
const [hallIncludeUnlabeled, setWingIncludeUnlabeled] = (0,
|
|
6919
|
-
const [hallIncludeGeneral, setWingIncludeGeneral] = (0,
|
|
6920
|
-
const [wingLabels, setHallLabels] = (0,
|
|
6921
|
-
const [error, setError] = (0,
|
|
6922
|
-
const [open, setOpen] = (0,
|
|
6923
|
-
const wrapRef = (0,
|
|
6924
|
-
const popRef = (0,
|
|
7167
|
+
const [mode, setMode] = (0, import_react27.useState)(null);
|
|
7168
|
+
const [recall, setRecall] = (0, import_react27.useState)(null);
|
|
7169
|
+
const [recallResolved, setRecallResolved] = (0, import_react27.useState)(true);
|
|
7170
|
+
const [halls, setWings] = (0, import_react27.useState)([]);
|
|
7171
|
+
const [hallIncludeUnlabeled, setWingIncludeUnlabeled] = (0, import_react27.useState)(true);
|
|
7172
|
+
const [hallIncludeGeneral, setWingIncludeGeneral] = (0, import_react27.useState)(false);
|
|
7173
|
+
const [wingLabels, setHallLabels] = (0, import_react27.useState)({});
|
|
7174
|
+
const [error, setError] = (0, import_react27.useState)(null);
|
|
7175
|
+
const [open, setOpen] = (0, import_react27.useState)(false);
|
|
7176
|
+
const wrapRef = (0, import_react27.useRef)(null);
|
|
7177
|
+
const popRef = (0, import_react27.useRef)(null);
|
|
6925
7178
|
const shiftX = useViewportClamp(popRef);
|
|
6926
|
-
const seqRef = (0,
|
|
6927
|
-
const load = (0,
|
|
7179
|
+
const seqRef = (0, import_react27.useRef)(0);
|
|
7180
|
+
const load = (0, import_react27.useCallback)(() => {
|
|
6928
7181
|
if (!sessionId || !rpc) return;
|
|
6929
7182
|
const token = ++seqRef.current;
|
|
6930
7183
|
setError(null);
|
|
@@ -6949,13 +7202,13 @@ var __defProp = Object.defineProperty;
|
|
|
6949
7202
|
}).catch(() => {
|
|
6950
7203
|
});
|
|
6951
7204
|
}, [sessionId, rpc]);
|
|
6952
|
-
(0,
|
|
7205
|
+
(0, import_react27.useEffect)(() => {
|
|
6953
7206
|
load();
|
|
6954
7207
|
}, [load]);
|
|
6955
|
-
(0,
|
|
7208
|
+
(0, import_react27.useEffect)(() => {
|
|
6956
7209
|
watchSidebarIcon();
|
|
6957
7210
|
}, []);
|
|
6958
|
-
(0,
|
|
7211
|
+
(0, import_react27.useEffect)(() => {
|
|
6959
7212
|
initOccupancyIndicator(
|
|
6960
7213
|
(endpoint, payload) => rpc(endpoint, payload)
|
|
6961
7214
|
);
|
|
@@ -6963,7 +7216,7 @@ var __defProp = Object.defineProperty;
|
|
|
6963
7216
|
watchContextMeter();
|
|
6964
7217
|
noteOccupancySession(sessionId ?? null);
|
|
6965
7218
|
}, [sessionId, rpc]);
|
|
6966
|
-
(0,
|
|
7219
|
+
(0, import_react27.useEffect)(() => {
|
|
6967
7220
|
if (!open) return;
|
|
6968
7221
|
const onDown = (e) => {
|
|
6969
7222
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|