dsh-prime-memory 0.25.0 → 0.26.1
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 +37 -0
- package/CHANGELOG.ja.md +38 -0
- package/CHANGELOG.ko.md +38 -0
- package/CHANGELOG.md +39 -0
- package/dist/client.js +991 -665
- package/dist/config.d.ts +44 -2
- package/dist/config.js +32 -2
- package/dist/contract.d.ts +108 -2
- package/dist/index.js +3 -3
- package/dist/keyword-backfill.d.ts +52 -7
- package/dist/keyword-backfill.js +204 -62
- package/dist/llm.d.ts +9 -0
- package/dist/llm.js +7 -4
- 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 +148 -0
- package/dist/redistill-backfill.js +420 -0
- package/dist/room-review.d.ts +12 -13
- package/dist/room-review.js +39 -29
- package/dist/settings.js +15 -0
- package/dist/stats.js +138 -21
- package/dist/store/l1.d.ts +12 -0
- package/dist/store/l1.js +9 -0
- package/dist/store/memory-md.d.ts +8 -0
- package/dist/store/memory-md.js +13 -2
- package/dist/store/sqlite.d.ts +17 -0
- package/dist/store/sqlite.js +33 -0
- package/dist/tools/index.d.ts +10 -1
- package/dist/tools/index.js +7 -1
- package/dist/tools/skills.d.ts +7 -4
- package/dist/tools/skills.js +9 -11
- package/dist/wing-backfill.d.ts +25 -14
- package/dist/wing-backfill.js +133 -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 = [
|
|
@@ -3715,14 +3692,329 @@ 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 [wingAborting, setWingAborting] = (0, import_react16.useState)(false);
|
|
3712
|
+
const [kwAborting, setKwAborting] = (0, import_react16.useState)(false);
|
|
3713
|
+
const [rdAborting, setRdAborting] = (0, import_react16.useState)(false);
|
|
3714
|
+
const wingStopRef = (0, import_react16.useRef)(false);
|
|
3715
|
+
const timersRef = (0, import_react16.useRef)([]);
|
|
3716
|
+
(0, import_react16.useEffect)(
|
|
3717
|
+
() => () => {
|
|
3718
|
+
for (const t of timersRef.current) window.clearTimeout(t);
|
|
3719
|
+
},
|
|
3720
|
+
[]
|
|
3721
|
+
);
|
|
3722
|
+
const refreshOverview = (0, import_react16.useCallback)(() => {
|
|
3723
|
+
rpc("dsh-memory/wing-overview", {}).then((r) => {
|
|
3724
|
+
if (r && r.ok) setOverview(r.value);
|
|
3725
|
+
}).catch(() => {
|
|
3726
|
+
});
|
|
3727
|
+
}, [rpc]);
|
|
3728
|
+
(0, import_react16.useEffect)(() => {
|
|
3729
|
+
refreshOverview();
|
|
3730
|
+
}, [refreshOverview]);
|
|
3731
|
+
ensureThemeStyle();
|
|
3732
|
+
const POLL_CAP = 400;
|
|
3733
|
+
const fmtProgress = (p, verb, counts, aborting = false) => {
|
|
3734
|
+
if (aborting) return `${verb}:正在中止——先等在跑的那条收工,超时即强行中断(已写回的保留)…`;
|
|
3735
|
+
if (!p) return `${verb}中…`;
|
|
3736
|
+
if (p.scanning) {
|
|
3737
|
+
return p.scanTotal > 0 ? `${verb}中:正在扫描存量 ${p.scanned}/${p.scanTotal} 行,筛出需${verb}的记录…` : `${verb}中:正在扫描活跃存量(已扫 ${p.scanned} 行),筛出需${verb}的记录…`;
|
|
3738
|
+
}
|
|
3739
|
+
if (p.candidates === 0) return `${verb}中:扫描完成,没有需要${verb}的记录…`;
|
|
3740
|
+
const parts = [
|
|
3741
|
+
`${verb}中:真目标 ${p.candidates} 条`,
|
|
3742
|
+
`已完成 ${p.processed} 条`,
|
|
3743
|
+
p.batchTotal > 0 ? `第 ${Math.min(p.batchesDone + 1, p.batchTotal)}/${p.batchTotal} 条` : "",
|
|
3744
|
+
p.concurrency > 1 ? `并行 ${p.concurrency}` : "串行",
|
|
3745
|
+
(counts?.failed ?? 0) > 0 ? `失败 ${counts.failed} 条` : ""
|
|
3746
|
+
].filter(Boolean);
|
|
3747
|
+
const outcome = counts ? `(写回 ${counts.updated ?? 0}${counts.skipped !== void 0 ? ` / 留原文 ${counts.skipped}` : ""})` : "";
|
|
3748
|
+
return parts.join(" · ") + outcome;
|
|
3749
|
+
};
|
|
3750
|
+
const tail = (p) => p && p.cancelled ? `,已中止、剩 ${p.deferred} 条待再点一次` : p && p.deferred > 0 ? `,本次未跑完、剩 ${p.deferred} 条待再点一次` : "";
|
|
3751
|
+
const wingBackfill = (mode = "start") => {
|
|
3752
|
+
if (wingBusy) return;
|
|
3753
|
+
if (mode === "start" && (!overview || overview.unlabeled === 0)) return;
|
|
3754
|
+
if (mode === "start") setWingBusy(true);
|
|
3755
|
+
setErr(null);
|
|
3756
|
+
wingStopRef.current = false;
|
|
3757
|
+
setWingAborting(false);
|
|
3758
|
+
let polls = 0;
|
|
3759
|
+
const finish = () => setWingBusy(false);
|
|
3760
|
+
const tick = () => {
|
|
3761
|
+
if (wingStopRef.current) return;
|
|
3762
|
+
polls++;
|
|
3763
|
+
rpc("dsh-memory/wing-overview", {}).then((r) => {
|
|
3764
|
+
const v = r && r.ok ? r.value : null;
|
|
3765
|
+
if (v) setOverview(v);
|
|
3766
|
+
if (v && v.unlabeled === 0 || polls >= POLL_CAP) finish();
|
|
3767
|
+
else timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3768
|
+
}).catch(() => finish());
|
|
3769
|
+
};
|
|
3770
|
+
rpc("dsh-memory/wing-backfill", mode === "resume" ? { probe: true } : {}).then((r) => {
|
|
3771
|
+
if (!r || !r.ok) {
|
|
3772
|
+
if (mode === "resume") return finish();
|
|
3773
|
+
setErr(r && r.error ? "回填失败:" + r.error.message : "回填失败");
|
|
3774
|
+
finish();
|
|
3775
|
+
return;
|
|
3776
|
+
}
|
|
3777
|
+
if (mode === "resume") {
|
|
3778
|
+
if (!(r.value && r.value.running)) return;
|
|
3779
|
+
setWingBusy(true);
|
|
3780
|
+
}
|
|
3781
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3782
|
+
}).catch((e) => {
|
|
3783
|
+
if (mode === "resume") return finish();
|
|
3784
|
+
setErr("回填失败:" + String(e && e.message || e));
|
|
3785
|
+
finish();
|
|
3786
|
+
});
|
|
3787
|
+
};
|
|
3788
|
+
const keywordBackfill = (mode = "start") => {
|
|
3789
|
+
if (kwBusy) return;
|
|
3790
|
+
if (mode === "start") {
|
|
3791
|
+
setKwBusy(true);
|
|
3792
|
+
setKwSummary(null);
|
|
3793
|
+
setKwProgress(null);
|
|
3794
|
+
setKwCounts(null);
|
|
3795
|
+
setKwAborting(false);
|
|
3796
|
+
}
|
|
3797
|
+
setErr(null);
|
|
3798
|
+
let polls = 0;
|
|
3799
|
+
let last = null;
|
|
3800
|
+
const finish = () => setKwBusy(false);
|
|
3801
|
+
const showResult = (v) => {
|
|
3802
|
+
const fail = v.failed ?? 0;
|
|
3803
|
+
if (last && !last.cancelled && last.candidates === 0) {
|
|
3804
|
+
setKwSummary("关键词回填:没有缺关键词的记录,无需回填");
|
|
3805
|
+
return;
|
|
3806
|
+
}
|
|
3807
|
+
const head = last?.cancelled ? "关键词回填已中止" : "关键词回填完成";
|
|
3808
|
+
setKwSummary(`${head}:成功 ${v.updated ?? 0} 条${fail > 0 ? `,失败 ${fail} 条` : ""}${tail(last)}`);
|
|
3809
|
+
};
|
|
3810
|
+
const failMsg = (m) => {
|
|
3811
|
+
setErr(m);
|
|
3812
|
+
finish();
|
|
3813
|
+
};
|
|
3814
|
+
const tick = () => {
|
|
3815
|
+
polls++;
|
|
3816
|
+
rpc("dsh-memory/keyword-backfill", { probe: true }).then((r) => {
|
|
3817
|
+
const v = r && r.ok ? r.value : null;
|
|
3818
|
+
if (!v) return failMsg("关键词回填失败");
|
|
3819
|
+
if (v.progress) {
|
|
3820
|
+
last = v.progress;
|
|
3821
|
+
setKwProgress(v.progress);
|
|
3822
|
+
setKwCounts({ updated: v.updated, failed: v.failed });
|
|
3823
|
+
}
|
|
3824
|
+
if (v.running) {
|
|
3825
|
+
if (polls >= POLL_CAP) {
|
|
3826
|
+
showResult(v);
|
|
3827
|
+
return finish();
|
|
3828
|
+
}
|
|
3829
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3830
|
+
return;
|
|
3831
|
+
}
|
|
3832
|
+
if (v.enabled) showResult(v);
|
|
3833
|
+
finish();
|
|
3834
|
+
}).catch(() => failMsg("关键词回填失败"));
|
|
3835
|
+
};
|
|
3836
|
+
rpc("dsh-memory/keyword-backfill", mode === "resume" ? { probe: true } : {}).then((r) => {
|
|
3837
|
+
if (!r || !r.ok) {
|
|
3838
|
+
if (mode === "resume") return;
|
|
3839
|
+
return failMsg(r && r.error ? "关键词回填失败:" + r.error.message : "关键词回填失败");
|
|
3840
|
+
}
|
|
3841
|
+
const v = r.value;
|
|
3842
|
+
if (!v) {
|
|
3843
|
+
if (mode === "resume") return;
|
|
3844
|
+
return failMsg("关键词回填失败");
|
|
3845
|
+
}
|
|
3846
|
+
if (mode === "resume") {
|
|
3847
|
+
if (!v.running) return;
|
|
3848
|
+
if (v.progress) {
|
|
3849
|
+
last = v.progress;
|
|
3850
|
+
setKwProgress(v.progress);
|
|
3851
|
+
setKwCounts({ updated: v.updated, failed: v.failed });
|
|
3852
|
+
}
|
|
3853
|
+
setKwBusy(true);
|
|
3854
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3855
|
+
return;
|
|
3856
|
+
}
|
|
3857
|
+
if (!v.enabled) return failMsg("关键词回填未开启:请先在概览开关组打开关键词回填");
|
|
3858
|
+
if (v.progress) {
|
|
3859
|
+
last = v.progress;
|
|
3860
|
+
setKwProgress(v.progress);
|
|
3861
|
+
setKwCounts({ updated: v.updated, failed: v.failed });
|
|
3862
|
+
}
|
|
3863
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3864
|
+
}).catch((e) => {
|
|
3865
|
+
if (mode === "resume") return;
|
|
3866
|
+
failMsg("关键词回填失败:" + String(e && e.message || e));
|
|
3867
|
+
});
|
|
3868
|
+
};
|
|
3869
|
+
const redistillBackfill = (mode = "start") => {
|
|
3870
|
+
if (rdBusy) return;
|
|
3871
|
+
if (mode === "start") {
|
|
3872
|
+
setRdBusy(true);
|
|
3873
|
+
setRdSummary(null);
|
|
3874
|
+
setRdProgress(null);
|
|
3875
|
+
setRdCounts(null);
|
|
3876
|
+
setRdAborting(false);
|
|
3877
|
+
}
|
|
3878
|
+
setErr(null);
|
|
3879
|
+
let polls = 0;
|
|
3880
|
+
let last = null;
|
|
3881
|
+
const finish = () => setRdBusy(false);
|
|
3882
|
+
const showResult = (v) => {
|
|
3883
|
+
if (last && !last.cancelled && last.candidates === 0) {
|
|
3884
|
+
setRdSummary("重蒸馏整形:没有需要整形的记录(骨架都已齐备),无需处理");
|
|
3885
|
+
return;
|
|
3886
|
+
}
|
|
3887
|
+
const head = last?.cancelled ? "整形已中止" : "整形完成";
|
|
3888
|
+
setRdSummary(`${head}:写回 ${v.updated ?? 0} 条,留原文 ${v.skipped ?? 0} 条${(v.failed ?? 0) > 0 ? `,失败 ${v.failed} 条` : ""}${tail(last)}`);
|
|
3889
|
+
};
|
|
3890
|
+
const failMsg = (m) => {
|
|
3891
|
+
setErr(m);
|
|
3892
|
+
finish();
|
|
3893
|
+
};
|
|
3894
|
+
const tick = () => {
|
|
3895
|
+
polls++;
|
|
3896
|
+
rpc("dsh-memory/redistill-backfill", { probe: true }).then((r) => {
|
|
3897
|
+
const v = r && r.ok ? r.value : null;
|
|
3898
|
+
if (!v) return failMsg("重蒸馏整形失败");
|
|
3899
|
+
if (v.progress) {
|
|
3900
|
+
last = v.progress;
|
|
3901
|
+
setRdProgress(v.progress);
|
|
3902
|
+
setRdCounts({ updated: v.updated, skipped: v.skipped, failed: v.failed });
|
|
3903
|
+
}
|
|
3904
|
+
if (v.running) {
|
|
3905
|
+
if (polls >= POLL_CAP) {
|
|
3906
|
+
showResult(v);
|
|
3907
|
+
return finish();
|
|
3908
|
+
}
|
|
3909
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3910
|
+
return;
|
|
3911
|
+
}
|
|
3912
|
+
if (v.enabled) showResult(v);
|
|
3913
|
+
finish();
|
|
3914
|
+
}).catch(() => failMsg("重蒸馏整形失败"));
|
|
3915
|
+
};
|
|
3916
|
+
rpc("dsh-memory/redistill-backfill", mode === "resume" ? { probe: true } : {}).then((r) => {
|
|
3917
|
+
if (!r || !r.ok) {
|
|
3918
|
+
if (mode === "resume") return;
|
|
3919
|
+
return failMsg(r && r.error ? "重蒸馏整形失败:" + r.error.message : "重蒸馏整形失败");
|
|
3920
|
+
}
|
|
3921
|
+
const v = r.value;
|
|
3922
|
+
if (!v) {
|
|
3923
|
+
if (mode === "resume") return;
|
|
3924
|
+
return failMsg("重蒸馏整形失败");
|
|
3925
|
+
}
|
|
3926
|
+
if (mode === "resume") {
|
|
3927
|
+
if (!v.running) return;
|
|
3928
|
+
if (v.progress) {
|
|
3929
|
+
last = v.progress;
|
|
3930
|
+
setRdProgress(v.progress);
|
|
3931
|
+
setRdCounts({ updated: v.updated, skipped: v.skipped, failed: v.failed });
|
|
3932
|
+
}
|
|
3933
|
+
setRdBusy(true);
|
|
3934
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3935
|
+
return;
|
|
3936
|
+
}
|
|
3937
|
+
if (!v.enabled) return failMsg("重蒸馏整形未开启:请先在概览开关组打开重蒸馏整形");
|
|
3938
|
+
if (v.progress) {
|
|
3939
|
+
last = v.progress;
|
|
3940
|
+
setRdProgress(v.progress);
|
|
3941
|
+
setRdCounts({ updated: v.updated, skipped: v.skipped, failed: v.failed });
|
|
3942
|
+
}
|
|
3943
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
3944
|
+
}).catch((e) => {
|
|
3945
|
+
if (mode === "resume") return;
|
|
3946
|
+
failMsg("重蒸馏整形失败:" + String(e && e.message || e));
|
|
3947
|
+
});
|
|
3948
|
+
};
|
|
3949
|
+
const cancelWing = () => {
|
|
3950
|
+
wingStopRef.current = true;
|
|
3951
|
+
setWingAborting(true);
|
|
3952
|
+
setWingBusy(false);
|
|
3953
|
+
rpc("dsh-memory/wing-backfill", { cancel: true }).catch((e) => {
|
|
3954
|
+
setErr("中止请求失败:" + String(e && e.message || e));
|
|
3955
|
+
});
|
|
3956
|
+
};
|
|
3957
|
+
const cancelKw = () => {
|
|
3958
|
+
setKwAborting(true);
|
|
3959
|
+
rpc("dsh-memory/keyword-backfill", { cancel: true }).catch((e) => {
|
|
3960
|
+
setKwAborting(false);
|
|
3961
|
+
setErr("中止请求失败:" + String(e && e.message || e));
|
|
3962
|
+
});
|
|
3963
|
+
};
|
|
3964
|
+
const cancelRd = () => {
|
|
3965
|
+
setRdAborting(true);
|
|
3966
|
+
rpc("dsh-memory/redistill-backfill", { cancel: true }).catch((e) => {
|
|
3967
|
+
setRdAborting(false);
|
|
3968
|
+
setErr("中止请求失败:" + String(e && e.message || e));
|
|
3969
|
+
});
|
|
3970
|
+
};
|
|
3971
|
+
(0, import_react16.useEffect)(() => {
|
|
3972
|
+
keywordBackfill("resume");
|
|
3973
|
+
redistillBackfill("resume");
|
|
3974
|
+
wingBackfill("resume");
|
|
3975
|
+
}, []);
|
|
3976
|
+
const rowStyle = {
|
|
3977
|
+
display: "flex",
|
|
3978
|
+
alignItems: "center",
|
|
3979
|
+
gap: 10,
|
|
3980
|
+
flexWrap: "wrap",
|
|
3981
|
+
padding: "8px 0"
|
|
3982
|
+
};
|
|
3983
|
+
const hintStyle = { flex: 1, minWidth: 180, fontSize: 12, color: "var(--dsh-mem-text-3)" };
|
|
3984
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "dsh-mem-rb-card", style: { padding: "4px 14px", marginTop: 12 }, children: [
|
|
3985
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { fontWeight: 600, padding: "8px 0 2px" }, children: "存量回填与整形" }),
|
|
3986
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: rowStyle, children: [
|
|
3987
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: hintStyle, children: wingAborting ? "回填:正在中止…" : overview ? `对存量未打标记忆批量补打 wing 标签 · 未打标 ${overview.unlabeled} 条` : "未打标计数加载中…" }),
|
|
3988
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3989
|
+
NButton,
|
|
3990
|
+
{
|
|
3991
|
+
disabled: !wingBusy && (!overview || overview.unlabeled === 0),
|
|
3992
|
+
style: { color: "var(--dsh-mem-accent)" },
|
|
3993
|
+
onClick: () => wingBusy ? cancelWing() : wingBackfill(),
|
|
3994
|
+
children: wingBusy ? "中止" : "wing 回填"
|
|
3995
|
+
}
|
|
3996
|
+
)
|
|
3997
|
+
] }),
|
|
3998
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: rowStyle, children: [
|
|
3999
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: hintStyle, children: kwBusy ? fmtProgress(kwProgress, "回填", kwCounts ?? void 0, kwAborting) : kwSummary || "为缺 dsh_keywords 的存量记忆补检索关键词,喂 FTS 关键词轴(需先开关键词回填开关)" }),
|
|
4000
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(NButton, { disabled: kwAborting, style: { color: "var(--dsh-mem-accent)" }, onClick: () => kwBusy ? cancelKw() : keywordBackfill(), children: kwBusy ? kwAborting ? "中止中…" : "中止" : "关键词回填" })
|
|
4001
|
+
] }),
|
|
4002
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: rowStyle, children: [
|
|
4003
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: hintStyle, children: rdBusy ? fmtProgress(rdProgress, "整形", rdCounts ?? void 0, rdAborting) : rdSummary || "把“平”的存量记忆按类型重排成分节骨架,顺带产关键词/情景;只有严格更优才写回(需先开重蒸馏整形开关)" }),
|
|
4004
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(NButton, { disabled: rdAborting, style: { color: "var(--dsh-mem-accent)" }, onClick: () => rdBusy ? cancelRd() : redistillBackfill(), children: rdBusy ? rdAborting ? "中止中…" : "中止" : "重蒸馏整形" })
|
|
4005
|
+
] }),
|
|
4006
|
+
err ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { padding: "6px 0", fontSize: 12, color: "var(--dsh-mem-danger)" }, children: err }) : null
|
|
4007
|
+
] });
|
|
4008
|
+
}
|
|
4009
|
+
|
|
4010
|
+
// client/src/tabs/OverviewTab.tsx
|
|
4011
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3720
4012
|
function OverviewTab(props) {
|
|
3721
4013
|
const rpc = props.rpc;
|
|
3722
|
-
const [stats, setStats] = (0,
|
|
3723
|
-
const [settingsData, setSettingsData] = (0,
|
|
3724
|
-
const [error, setError] = (0,
|
|
3725
|
-
const load = (0,
|
|
4014
|
+
const [stats, setStats] = (0, import_react17.useState)(null);
|
|
4015
|
+
const [settingsData, setSettingsData] = (0, import_react17.useState)(null);
|
|
4016
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
4017
|
+
const load = (0, import_react17.useCallback)(() => {
|
|
3726
4018
|
rpc("dsh-memory/stats", {}).then((r) => {
|
|
3727
4019
|
if (r && r.ok) setStats(r.value);
|
|
3728
4020
|
else setError(r && r.error ? r.error.message : "RPC error");
|
|
@@ -3734,7 +4026,7 @@ var __defProp = Object.defineProperty;
|
|
|
3734
4026
|
}).catch(() => {
|
|
3735
4027
|
});
|
|
3736
4028
|
}, [rpc]);
|
|
3737
|
-
(0,
|
|
4029
|
+
(0, import_react17.useEffect)(() => {
|
|
3738
4030
|
load();
|
|
3739
4031
|
const timer = setInterval(load, 5e3);
|
|
3740
4032
|
return () => {
|
|
@@ -3759,6 +4051,23 @@ var __defProp = Object.defineProperty;
|
|
|
3759
4051
|
setError("开关写入失败:" + String(e && e.message || e));
|
|
3760
4052
|
});
|
|
3761
4053
|
};
|
|
4054
|
+
const setNum = (key, value) => {
|
|
4055
|
+
if (!settingsData) return;
|
|
4056
|
+
const prev = settingsData;
|
|
4057
|
+
const next = { ...prev, settings: { ...prev.settings, [key]: value } };
|
|
4058
|
+
setSettingsData(next);
|
|
4059
|
+
rpc("dsh-memory/settings-set", { [key]: value }).then((r) => {
|
|
4060
|
+
if (!r || !r.ok) {
|
|
4061
|
+
setSettingsData(prev);
|
|
4062
|
+
setError(r && r.error ? "并行度写入失败:" + r.error.message : "并行度写入失败");
|
|
4063
|
+
} else {
|
|
4064
|
+
setError(null);
|
|
4065
|
+
}
|
|
4066
|
+
}).catch((e) => {
|
|
4067
|
+
setSettingsData(prev);
|
|
4068
|
+
setError("并行度写入失败:" + String(e && e.message || e));
|
|
4069
|
+
});
|
|
4070
|
+
};
|
|
3762
4071
|
const tiles = [];
|
|
3763
4072
|
const infos = [];
|
|
3764
4073
|
if (stats) {
|
|
@@ -3795,11 +4104,17 @@ var __defProp = Object.defineProperty;
|
|
|
3795
4104
|
const toolRuminate = settingsData && settingsData.settings ? settingsData.settings.toolRuminate !== false : true;
|
|
3796
4105
|
const toolConflict = settingsData && settingsData.settings ? settingsData.settings.toolConflict !== false : true;
|
|
3797
4106
|
const toolMutate = settingsData && settingsData.settings ? settingsData.settings.toolMutate !== false : true;
|
|
4107
|
+
const toolSkills = settingsData && settingsData.settings ? settingsData.settings.toolSkills !== false : true;
|
|
3798
4108
|
const skillsEnabled = settingsData && settingsData.settings ? settingsData.settings.skillsEnabled === true : false;
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
4109
|
+
const keywordEnabled = settingsData && settingsData.settings ? settingsData.settings.keywordEnabled === true : false;
|
|
4110
|
+
const redistillEnabled = settingsData && settingsData.settings ? settingsData.settings.redistillEnabled === true : false;
|
|
4111
|
+
const mdSyncEnabled = settingsData && settingsData.settings ? settingsData.settings.mdSyncEnabled === true : false;
|
|
4112
|
+
const memportEnabled = settingsData && settingsData.settings ? settingsData.settings.memportEnabled === true : false;
|
|
4113
|
+
const bfConcurrency = settingsData && settingsData.settings ? settingsData.settings.backfillConcurrency ?? 0 : 0;
|
|
4114
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
|
|
4115
|
+
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: [
|
|
4116
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "记忆模式" }),
|
|
4117
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3803
4118
|
SwitchRow,
|
|
3804
4119
|
{
|
|
3805
4120
|
label: "记忆模式",
|
|
@@ -3810,7 +4125,7 @@ var __defProp = Object.defineProperty;
|
|
|
3810
4125
|
}
|
|
3811
4126
|
}
|
|
3812
4127
|
),
|
|
3813
|
-
/* @__PURE__ */ (0,
|
|
4128
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3814
4129
|
SwitchRow,
|
|
3815
4130
|
{
|
|
3816
4131
|
label: "捕获",
|
|
@@ -3822,7 +4137,7 @@ var __defProp = Object.defineProperty;
|
|
|
3822
4137
|
}
|
|
3823
4138
|
}
|
|
3824
4139
|
),
|
|
3825
|
-
/* @__PURE__ */ (0,
|
|
4140
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3826
4141
|
SwitchRow,
|
|
3827
4142
|
{
|
|
3828
4143
|
label: "蒸馏",
|
|
@@ -3834,7 +4149,7 @@ var __defProp = Object.defineProperty;
|
|
|
3834
4149
|
}
|
|
3835
4150
|
}
|
|
3836
4151
|
),
|
|
3837
|
-
/* @__PURE__ */ (0,
|
|
4152
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3838
4153
|
SwitchRow,
|
|
3839
4154
|
{
|
|
3840
4155
|
label: "召回",
|
|
@@ -3846,8 +4161,8 @@ var __defProp = Object.defineProperty;
|
|
|
3846
4161
|
}
|
|
3847
4162
|
}
|
|
3848
4163
|
),
|
|
3849
|
-
/* @__PURE__ */ (0,
|
|
3850
|
-
/* @__PURE__ */ (0,
|
|
4164
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "高权限模式" }),
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3851
4166
|
SwitchRow,
|
|
3852
4167
|
{
|
|
3853
4168
|
label: "高权限模式",
|
|
@@ -3858,20 +4173,20 @@ var __defProp = Object.defineProperty;
|
|
|
3858
4173
|
}
|
|
3859
4174
|
}
|
|
3860
4175
|
),
|
|
3861
|
-
/* @__PURE__ */ (0,
|
|
3862
|
-
/* @__PURE__ */ (0,
|
|
4176
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "技能结晶" }),
|
|
4177
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3863
4178
|
SwitchRow,
|
|
3864
4179
|
{
|
|
3865
4180
|
label: "技能(程序性记忆)",
|
|
3866
|
-
desc: skillsEnabled ? "已开启:重复工作方法会结晶为技能候选,注入活跃技能,可在「技能」页审阅晋升" : "默认关闭;开启后注册 memory_skill_*
|
|
4181
|
+
desc: skillsEnabled ? "已开启:重复工作方法会结晶为技能候选,注入活跃技能,可在「技能」页审阅晋升" : "默认关闭;开启后注册 memory_skill_* 工具与注入(开关即时生效)",
|
|
3867
4182
|
checked: skillsEnabled,
|
|
3868
4183
|
onChange: (v) => {
|
|
3869
4184
|
toggle("skillsEnabled", v);
|
|
3870
4185
|
}
|
|
3871
4186
|
}
|
|
3872
4187
|
),
|
|
3873
|
-
/* @__PURE__ */ (0,
|
|
3874
|
-
/* @__PURE__ */ (0,
|
|
4188
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "工具封印" }),
|
|
4189
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3875
4190
|
SwitchRow,
|
|
3876
4191
|
{
|
|
3877
4192
|
label: "Room 管理工具",
|
|
@@ -3882,7 +4197,7 @@ var __defProp = Object.defineProperty;
|
|
|
3882
4197
|
}
|
|
3883
4198
|
}
|
|
3884
4199
|
),
|
|
3885
|
-
/* @__PURE__ */ (0,
|
|
4200
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3886
4201
|
SwitchRow,
|
|
3887
4202
|
{
|
|
3888
4203
|
label: "图谱工具",
|
|
@@ -3893,7 +4208,7 @@ var __defProp = Object.defineProperty;
|
|
|
3893
4208
|
}
|
|
3894
4209
|
}
|
|
3895
4210
|
),
|
|
3896
|
-
/* @__PURE__ */ (0,
|
|
4211
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3897
4212
|
SwitchRow,
|
|
3898
4213
|
{
|
|
3899
4214
|
label: "反刍工具",
|
|
@@ -3904,7 +4219,7 @@ var __defProp = Object.defineProperty;
|
|
|
3904
4219
|
}
|
|
3905
4220
|
}
|
|
3906
4221
|
),
|
|
3907
|
-
/* @__PURE__ */ (0,
|
|
4222
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3908
4223
|
SwitchRow,
|
|
3909
4224
|
{
|
|
3910
4225
|
label: "冲突工具",
|
|
@@ -3915,7 +4230,7 @@ var __defProp = Object.defineProperty;
|
|
|
3915
4230
|
}
|
|
3916
4231
|
}
|
|
3917
4232
|
),
|
|
3918
|
-
/* @__PURE__ */ (0,
|
|
4233
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3919
4234
|
SwitchRow,
|
|
3920
4235
|
{
|
|
3921
4236
|
label: "写删工具",
|
|
@@ -3926,8 +4241,19 @@ var __defProp = Object.defineProperty;
|
|
|
3926
4241
|
}
|
|
3927
4242
|
}
|
|
3928
4243
|
),
|
|
3929
|
-
/* @__PURE__ */ (0,
|
|
3930
|
-
|
|
4244
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4245
|
+
SwitchRow,
|
|
4246
|
+
{
|
|
4247
|
+
label: "技能工具",
|
|
4248
|
+
desc: toolSkills ? "已注册:memory_skill_list / _read / _pin / _archive(需先开启「技能结晶」)" : "已封印:技能四件从模型工具列表移除(技能功能关闭时本就零表面积)",
|
|
4249
|
+
checked: toolSkills,
|
|
4250
|
+
onChange: (v) => {
|
|
4251
|
+
toggle("toolSkills", v);
|
|
4252
|
+
}
|
|
4253
|
+
}
|
|
4254
|
+
),
|
|
4255
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "人工冲突裁决" }),
|
|
4256
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3931
4257
|
SwitchRow,
|
|
3932
4258
|
{
|
|
3933
4259
|
label: "人工冲突裁决",
|
|
@@ -3938,43 +4264,110 @@ var __defProp = Object.defineProperty;
|
|
|
3938
4264
|
}
|
|
3939
4265
|
}
|
|
3940
4266
|
),
|
|
3941
|
-
/* @__PURE__ */ (0,
|
|
3942
|
-
/* @__PURE__ */ (0,
|
|
3943
|
-
|
|
4267
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "存量回填与整形" }),
|
|
4268
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4269
|
+
SwitchRow,
|
|
4270
|
+
{
|
|
4271
|
+
label: "关键词回填",
|
|
4272
|
+
desc: keywordEnabled ? "已开启:可对存量记忆批量补检索关键词(下方「存量回填与整形」区点按钮)" : "默认关闭;开启后才能跑关键词回填(喂 FTS 关键词轴)",
|
|
4273
|
+
checked: keywordEnabled,
|
|
4274
|
+
onChange: (v) => {
|
|
4275
|
+
toggle("keywordEnabled", v);
|
|
4276
|
+
}
|
|
4277
|
+
}
|
|
4278
|
+
),
|
|
4279
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4280
|
+
SwitchRow,
|
|
4281
|
+
{
|
|
4282
|
+
label: "重蒸馏整形",
|
|
4283
|
+
desc: redistillEnabled ? "已开启:可把“平”的存量记忆按类型重排成分节骨架(仅动严格更优的)" : "默认关闭;开启后才能跑重蒸馏整形(改正文会重算向量+覆盖 .memory.md)",
|
|
4284
|
+
checked: redistillEnabled,
|
|
4285
|
+
onChange: (v) => {
|
|
4286
|
+
toggle("redistillEnabled", v);
|
|
4287
|
+
}
|
|
4288
|
+
}
|
|
4289
|
+
),
|
|
4290
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, padding: "6px 0", flexWrap: "wrap" }, children: [
|
|
4291
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontSize: 13 }, children: "回填并行度" }),
|
|
4292
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4293
|
+
"input",
|
|
4294
|
+
{
|
|
4295
|
+
type: "range",
|
|
4296
|
+
min: 0,
|
|
4297
|
+
max: 8,
|
|
4298
|
+
step: 1,
|
|
4299
|
+
value: Math.min(8, bfConcurrency),
|
|
4300
|
+
onChange: (e) => {
|
|
4301
|
+
setNum("backfillConcurrency", Number(e.target.value));
|
|
4302
|
+
},
|
|
4303
|
+
style: { width: 120 }
|
|
4304
|
+
}
|
|
4305
|
+
),
|
|
4306
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)" }, children: [
|
|
4307
|
+
bfConcurrency === 0 ? "0·跟随配置(默认 1=串行)" : bfConcurrency === 1 ? "1·串行逐条" : `${bfConcurrency} 路并发`,
|
|
4308
|
+
"· 对**下一次点击**生效(正在跑的那轮不会改道)"
|
|
4309
|
+
] })
|
|
4310
|
+
] }),
|
|
4311
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4312
|
+
SwitchRow,
|
|
4313
|
+
{
|
|
4314
|
+
label: "md 反向同步",
|
|
4315
|
+
desc: mdSyncEnabled ? "已开启:可将 .memory.md 文件侧修改回灌入库(需先开 md 投射 + 高权限)" : "默认关闭;风险高于导出(会写库),需先开 md 投射再开本项",
|
|
4316
|
+
checked: mdSyncEnabled,
|
|
4317
|
+
onChange: (v) => {
|
|
4318
|
+
toggle("mdSyncEnabled", v);
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
),
|
|
4322
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4323
|
+
SwitchRow,
|
|
4324
|
+
{
|
|
4325
|
+
label: "外部记忆来源 Connect",
|
|
4326
|
+
desc: memportEnabled ? "已开启:可登记/扫描外部记忆源并导入" : "默认关闭;开启后 memport 相关端点可用",
|
|
4327
|
+
checked: memportEnabled,
|
|
4328
|
+
onChange: (v) => {
|
|
4329
|
+
toggle("memportEnabled", v);
|
|
4330
|
+
}
|
|
4331
|
+
}
|
|
4332
|
+
),
|
|
4333
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "蒸馏参数" }),
|
|
4334
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DistillSettings, { rpc, disabled: !master, data: settingsData, setData: setSettingsData, onError: setError }),
|
|
4335
|
+
ceilingNote ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: S.hint, children: ceilingNote }) : null
|
|
3944
4336
|
] }) : null,
|
|
3945
|
-
/* @__PURE__ */ (0,
|
|
3946
|
-
/* @__PURE__ */ (0,
|
|
3947
|
-
/* @__PURE__ */ (0,
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
/* @__PURE__ */ (0,
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
/* @__PURE__ */ (0,
|
|
4337
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(EmbeddingSection, { rpc }),
|
|
4338
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RebuildPanel, { rpc }),
|
|
4339
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RuminatePanel, { rpc }),
|
|
4340
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(BackfillSection, { rpc }),
|
|
4341
|
+
degraded ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { ...S.error, marginBottom: 10 }, children: "⚠ " + stats.message + "。上方数据为最后一次成功读取的值,记忆功能当前未工作。" }) : null,
|
|
4342
|
+
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: [
|
|
4343
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "记忆概况" }),
|
|
4344
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.statGrid, children: tiles.map((t) => {
|
|
4345
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "dsh-mem-card", style: S.statTile, children: [
|
|
4346
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.statNum, children: t.num }),
|
|
4347
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.statLabel, children: t.label })
|
|
3955
4348
|
] }, t.label);
|
|
3956
4349
|
}) }),
|
|
3957
|
-
/* @__PURE__ */ (0,
|
|
4350
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.panelLabel, children: "运行状态" }),
|
|
3958
4351
|
infos.map((row2) => {
|
|
3959
|
-
return /* @__PURE__ */ (0,
|
|
3960
|
-
/* @__PURE__ */ (0,
|
|
3961
|
-
/* @__PURE__ */ (0,
|
|
4352
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: S.infoRow, children: [
|
|
4353
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: S.infoKey, children: row2[0] }),
|
|
4354
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: S.infoVal, children: row2[1] })
|
|
3962
4355
|
] }, row2[0]);
|
|
3963
4356
|
})
|
|
3964
4357
|
] }),
|
|
3965
|
-
/* @__PURE__ */ (0,
|
|
3966
|
-
/* @__PURE__ */ (0,
|
|
4358
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ArchiveSection, { rpc }),
|
|
4359
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: S.hint, children: "浏览各层记忆内容请切换上方 Tab;原始对话(L0)不入浏览器,可由模型侧 conversation_search 工具查询。" })
|
|
3967
4360
|
] });
|
|
3968
4361
|
}
|
|
3969
4362
|
|
|
3970
4363
|
// client/src/tabs/PersonaTab.tsx
|
|
3971
|
-
var
|
|
3972
|
-
var
|
|
4364
|
+
var import_react18 = require("react");
|
|
4365
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3973
4366
|
function PersonaTab(props) {
|
|
3974
4367
|
const rpc = props.rpc;
|
|
3975
|
-
const [content, setContent] = (0,
|
|
3976
|
-
const [error, setError] = (0,
|
|
3977
|
-
const load = (0,
|
|
4368
|
+
const [content, setContent] = (0, import_react18.useState)(null);
|
|
4369
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
4370
|
+
const load = (0, import_react18.useCallback)(() => {
|
|
3978
4371
|
setError(null);
|
|
3979
4372
|
rpc("dsh-memory/persona", {}).then((r) => {
|
|
3980
4373
|
if (r && r.ok) setContent(r.value.content);
|
|
@@ -3983,23 +4376,97 @@ var __defProp = Object.defineProperty;
|
|
|
3983
4376
|
setError(String(e && e.message || e));
|
|
3984
4377
|
});
|
|
3985
4378
|
}, [rpc]);
|
|
3986
|
-
(0,
|
|
4379
|
+
(0, import_react18.useEffect)(() => {
|
|
3987
4380
|
load();
|
|
3988
4381
|
}, [load]);
|
|
3989
|
-
return /* @__PURE__ */ (0,
|
|
3990
|
-
/* @__PURE__ */ (0,
|
|
3991
|
-
/* @__PURE__ */ (0,
|
|
3992
|
-
/* @__PURE__ */ (0,
|
|
3993
|
-
/* @__PURE__ */ (0,
|
|
4382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
|
|
4383
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
4384
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: error ? "加载失败" : content === null ? "加载中…" : content ? content.length + " 字符" : "未生成画像" }),
|
|
4385
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
|
|
4386
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
3994
4387
|
] }),
|
|
3995
|
-
error ? /* @__PURE__ */ (0,
|
|
3996
|
-
content ? /* @__PURE__ */ (0,
|
|
4388
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { ...S.error, marginBottom: 10 }, children: "画像读取失败:" + error + "(点右上“刷新”重试)" }) : null,
|
|
4389
|
+
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
4390
|
] });
|
|
3998
4391
|
}
|
|
3999
4392
|
|
|
4000
4393
|
// client/src/tabs/RecordsTab.tsx
|
|
4001
|
-
var
|
|
4002
|
-
|
|
4394
|
+
var import_react20 = require("react");
|
|
4395
|
+
|
|
4396
|
+
// client/src/ui/MarkdownBody.tsx
|
|
4397
|
+
var import_react19 = require("react");
|
|
4398
|
+
var H_STYLES = [
|
|
4399
|
+
{ fontSize: 15, fontWeight: 700, margin: "8px 0 4px", color: "var(--dsh-mem-text-1)" },
|
|
4400
|
+
{ fontSize: 14, fontWeight: 600, margin: "6px 0 3px", color: "var(--dsh-mem-text-1)" },
|
|
4401
|
+
{ fontSize: 13, fontWeight: 600, margin: "5px 0 2px", color: "var(--dsh-mem-text-1)" },
|
|
4402
|
+
{ fontSize: 12, fontWeight: 600, margin: "4px 0 2px", color: "var(--dsh-mem-text-2)" },
|
|
4403
|
+
{ fontSize: 12, fontWeight: 600, margin: "3px 0 1px", color: "var(--dsh-mem-text-2)" },
|
|
4404
|
+
{ fontSize: 11, fontWeight: 600, margin: "3px 0 1px", color: "var(--dsh-mem-text-2)" }
|
|
4405
|
+
];
|
|
4406
|
+
var P2 = { margin: "2px 0", whiteSpace: "pre-wrap", wordBreak: "break-word" };
|
|
4407
|
+
var LI = { margin: "1px 0 1px 12px", whiteSpace: "pre-wrap", wordBreak: "break-word" };
|
|
4408
|
+
var CODE = {
|
|
4409
|
+
fontFamily: "ui-monospace, monospace",
|
|
4410
|
+
fontSize: "0.92em",
|
|
4411
|
+
background: "var(--dsh-mem-bg-3)",
|
|
4412
|
+
padding: "0 3px",
|
|
4413
|
+
borderRadius: 3
|
|
4414
|
+
};
|
|
4415
|
+
function inline(text, key) {
|
|
4416
|
+
const nodes = [];
|
|
4417
|
+
const re = /\*\*(.+?)\*\*|`(.+?)`/;
|
|
4418
|
+
let rest = text;
|
|
4419
|
+
let i = 0;
|
|
4420
|
+
while (rest.length > 0) {
|
|
4421
|
+
const m = re.exec(rest);
|
|
4422
|
+
if (m === null) {
|
|
4423
|
+
nodes.push(rest);
|
|
4424
|
+
break;
|
|
4425
|
+
}
|
|
4426
|
+
if (m.index > 0) nodes.push(rest.slice(0, m.index));
|
|
4427
|
+
if (m[1] !== void 0) {
|
|
4428
|
+
nodes.push((0, import_react19.createElement)("strong", { key: `${key}-b${i++}` }, m[1]));
|
|
4429
|
+
} else {
|
|
4430
|
+
nodes.push((0, import_react19.createElement)("code", { key: `${key}-c${i++}`, style: CODE }, m[2]));
|
|
4431
|
+
}
|
|
4432
|
+
rest = rest.slice(m.index + m[0].length);
|
|
4433
|
+
}
|
|
4434
|
+
return nodes;
|
|
4435
|
+
}
|
|
4436
|
+
function MarkdownBody({ text }) {
|
|
4437
|
+
const lines = text.split("\n");
|
|
4438
|
+
const out = [];
|
|
4439
|
+
let idx = 0;
|
|
4440
|
+
for (const line of lines) {
|
|
4441
|
+
const t = line.trim();
|
|
4442
|
+
if (t.length === 0) continue;
|
|
4443
|
+
const h = /^(#{1,6})\s+(.+)/.exec(t);
|
|
4444
|
+
if (h) {
|
|
4445
|
+
const lv = h[1].length;
|
|
4446
|
+
out.push((0, import_react19.createElement)(`h${lv}`, { key: `h${idx}`, style: H_STYLES[lv - 1] }, ...inline(h[2], `h${idx}`)));
|
|
4447
|
+
idx++;
|
|
4448
|
+
continue;
|
|
4449
|
+
}
|
|
4450
|
+
const ul = /^[-*]\s+(.+)/.exec(t);
|
|
4451
|
+
if (ul) {
|
|
4452
|
+
out.push((0, import_react19.createElement)("div", { key: `li${idx}`, style: LI }, "• ", ...inline(ul[1], `li${idx}`)));
|
|
4453
|
+
idx++;
|
|
4454
|
+
continue;
|
|
4455
|
+
}
|
|
4456
|
+
const ol = /^\d+\.\s+(.+)/.exec(t);
|
|
4457
|
+
if (ol) {
|
|
4458
|
+
out.push((0, import_react19.createElement)("div", { key: `li${idx}`, style: LI }, t.slice(0, t.indexOf(".") + 2), ...inline(ol[1], `li${idx}`)));
|
|
4459
|
+
idx++;
|
|
4460
|
+
continue;
|
|
4461
|
+
}
|
|
4462
|
+
out.push((0, import_react19.createElement)("div", { key: `p${idx}`, style: P2 }, ...inline(t, `p${idx}`)));
|
|
4463
|
+
idx++;
|
|
4464
|
+
}
|
|
4465
|
+
return (0, import_react19.createElement)(import_react19.Fragment, null, ...out);
|
|
4466
|
+
}
|
|
4467
|
+
|
|
4468
|
+
// client/src/tabs/RecordsTab.tsx
|
|
4469
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4003
4470
|
function retiredSelOf(r) {
|
|
4004
4471
|
if (r === "active") return false;
|
|
4005
4472
|
if (r === "retired") return true;
|
|
@@ -4009,29 +4476,29 @@ var __defProp = Object.defineProperty;
|
|
|
4009
4476
|
function RecordsTab(props) {
|
|
4010
4477
|
const rpc = props.rpc;
|
|
4011
4478
|
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,
|
|
4479
|
+
const [items, setItems] = (0, import_react20.useState)([]);
|
|
4480
|
+
const [hasMore, setHasMore] = (0, import_react20.useState)(false);
|
|
4481
|
+
const [total, setTotal] = (0, import_react20.useState)(null);
|
|
4482
|
+
const [sceneOptions, setSceneOptions] = (0, import_react20.useState)([]);
|
|
4483
|
+
const [loading, setLoading] = (0, import_react20.useState)(false);
|
|
4484
|
+
const [truncated, setTruncated] = (0, import_react20.useState)(false);
|
|
4485
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
4486
|
+
const [expandedId, setExpandedId] = (0, import_react20.useState)(null);
|
|
4487
|
+
const [sel, setSel] = (0, import_react20.useState)(/* @__PURE__ */ new Set());
|
|
4488
|
+
const [hiPriv, setHiPriv] = (0, import_react20.useState)(false);
|
|
4489
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react20.useState)(false);
|
|
4490
|
+
const [query, setQuery] = (0, import_react20.useState)("");
|
|
4491
|
+
const [typeFilter, setTypeFilter] = (0, import_react20.useState)("");
|
|
4492
|
+
const [sceneFilter, setSceneFilter] = (0, import_react20.useState)("");
|
|
4493
|
+
const [hallFilter, setHallFilter] = (0, import_react20.useState)([]);
|
|
4494
|
+
const [tagFilter, setTagFilter] = (0, import_react20.useState)("");
|
|
4495
|
+
const [untaggedOnly, setUntaggedOnly] = (0, import_react20.useState)(false);
|
|
4496
|
+
const [orphanCount, setOrphanCount] = (0, import_react20.useState)(0);
|
|
4497
|
+
const [retiredFilter, setRetiredFilter] = (0, import_react20.useState)("");
|
|
4498
|
+
const [wingCatalog, setHallCatalog] = (0, import_react20.useState)(null);
|
|
4499
|
+
const [last, setLast] = (0, import_react20.useState)({ query: "", type: "", scene: "", halls: [], tag: "", untagged: false, retired: "" });
|
|
4500
|
+
const seqRef = (0, import_react20.useRef)(0);
|
|
4501
|
+
const fetchPage = (0, import_react20.useCallback)(
|
|
4035
4502
|
(conds, offset, append) => {
|
|
4036
4503
|
setLoading(true);
|
|
4037
4504
|
setError(null);
|
|
@@ -4081,23 +4548,23 @@ var __defProp = Object.defineProperty;
|
|
|
4081
4548
|
setLast(conds);
|
|
4082
4549
|
fetchPage(conds, 0, false);
|
|
4083
4550
|
};
|
|
4084
|
-
const loadRooms = (0,
|
|
4551
|
+
const loadRooms = (0, import_react20.useCallback)(() => {
|
|
4085
4552
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
4086
4553
|
if (r && r.ok) setOrphanCount(r.value.orphanCount ?? 0);
|
|
4087
4554
|
}).catch(() => {
|
|
4088
4555
|
});
|
|
4089
4556
|
}, [rpc]);
|
|
4090
|
-
(0,
|
|
4557
|
+
(0, import_react20.useEffect)(() => {
|
|
4091
4558
|
fetchPage({ query: "", type: "", scene: "", halls: [], tag: "", untagged: false, retired: "" }, 0, false);
|
|
4092
4559
|
loadRooms();
|
|
4093
4560
|
}, [fetchPage, loadRooms]);
|
|
4094
|
-
const loadHiPriv = (0,
|
|
4561
|
+
const loadHiPriv = (0, import_react20.useCallback)(() => {
|
|
4095
4562
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
4096
4563
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
4097
4564
|
}).catch(() => {
|
|
4098
4565
|
});
|
|
4099
4566
|
}, [rpc]);
|
|
4100
|
-
(0,
|
|
4567
|
+
(0, import_react20.useEffect)(() => {
|
|
4101
4568
|
loadHiPriv();
|
|
4102
4569
|
}, [loadHiPriv]);
|
|
4103
4570
|
const toggleHiPriv = () => {
|
|
@@ -4161,11 +4628,11 @@ var __defProp = Object.defineProperty;
|
|
|
4161
4628
|
} else if (r) setError(r.error ? r.error.message : "退场失败");
|
|
4162
4629
|
}).catch((e) => setError(String(e && e.message || e)));
|
|
4163
4630
|
};
|
|
4164
|
-
const [retired, setRetired] = (0,
|
|
4165
|
-
const [retiredTotal, setRetiredTotal] = (0,
|
|
4166
|
-
const [showRetired, setShowRetired] = (0,
|
|
4167
|
-
const [retiredBusy, setRetiredBusy] = (0,
|
|
4168
|
-
const loadRetired = (0,
|
|
4631
|
+
const [retired, setRetired] = (0, import_react20.useState)([]);
|
|
4632
|
+
const [retiredTotal, setRetiredTotal] = (0, import_react20.useState)(0);
|
|
4633
|
+
const [showRetired, setShowRetired] = (0, import_react20.useState)(false);
|
|
4634
|
+
const [retiredBusy, setRetiredBusy] = (0, import_react20.useState)(false);
|
|
4635
|
+
const loadRetired = (0, import_react20.useCallback)(() => {
|
|
4169
4636
|
setRetiredBusy(true);
|
|
4170
4637
|
rpc("dsh-memory/records-retired", { limit: 100, offset: 0 }).then((r) => {
|
|
4171
4638
|
if (r && r.ok) {
|
|
@@ -4174,7 +4641,7 @@ var __defProp = Object.defineProperty;
|
|
|
4174
4641
|
} else if (r) setError(r.error ? r.error.message : "已退场列表加载失败");
|
|
4175
4642
|
}).catch((e) => setError(String(e && e.message || e))).finally(() => setRetiredBusy(false));
|
|
4176
4643
|
}, [rpc]);
|
|
4177
|
-
(0,
|
|
4644
|
+
(0, import_react20.useEffect)(() => {
|
|
4178
4645
|
if (showRetired) loadRetired();
|
|
4179
4646
|
}, [showRetired, loadRetired]);
|
|
4180
4647
|
const restoreRecords = (ids) => {
|
|
@@ -4198,11 +4665,11 @@ var __defProp = Object.defineProperty;
|
|
|
4198
4665
|
unknown: "已退场"
|
|
4199
4666
|
};
|
|
4200
4667
|
const countText = total !== null ? "共 " + total + " 条" : items.length + " 条" + (hasMore ? "+" : "");
|
|
4201
|
-
const [usageSummary, setUsageSummary] = (0,
|
|
4668
|
+
const [usageSummary, setUsageSummary] = (0, import_react20.useState)(null);
|
|
4202
4669
|
const selCount = sel.size;
|
|
4203
|
-
return /* @__PURE__ */ (0,
|
|
4204
|
-
/* @__PURE__ */ (0,
|
|
4205
|
-
/* @__PURE__ */ (0,
|
|
4670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
|
|
4671
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: S.toolbar, children: [
|
|
4672
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4206
4673
|
NInput,
|
|
4207
4674
|
{
|
|
4208
4675
|
style: { flex: 1, minWidth: 160 },
|
|
@@ -4225,7 +4692,7 @@ var __defProp = Object.defineProperty;
|
|
|
4225
4692
|
}
|
|
4226
4693
|
}
|
|
4227
4694
|
),
|
|
4228
|
-
/* @__PURE__ */ (0,
|
|
4695
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4229
4696
|
NSel,
|
|
4230
4697
|
{
|
|
4231
4698
|
style: { maxWidth: 200 },
|
|
@@ -4238,7 +4705,7 @@ var __defProp = Object.defineProperty;
|
|
|
4238
4705
|
onChange: setTypeFilter
|
|
4239
4706
|
}
|
|
4240
4707
|
),
|
|
4241
|
-
/* @__PURE__ */ (0,
|
|
4708
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4242
4709
|
NSel,
|
|
4243
4710
|
{
|
|
4244
4711
|
style: { maxWidth: 220 },
|
|
@@ -4251,7 +4718,7 @@ var __defProp = Object.defineProperty;
|
|
|
4251
4718
|
onChange: setSceneFilter
|
|
4252
4719
|
}
|
|
4253
4720
|
),
|
|
4254
|
-
/* @__PURE__ */ (0,
|
|
4721
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4255
4722
|
WingMultiSelect,
|
|
4256
4723
|
{
|
|
4257
4724
|
options: wingCatalog ?? Array.from(new Set(items.map((m) => m.hall).filter((h) => !!h))).map((id) => ({ id, label: id })),
|
|
@@ -4259,8 +4726,8 @@ var __defProp = Object.defineProperty;
|
|
|
4259
4726
|
onChange: setHallFilter
|
|
4260
4727
|
}
|
|
4261
4728
|
),
|
|
4262
|
-
/* @__PURE__ */ (0,
|
|
4263
|
-
/* @__PURE__ */ (0,
|
|
4729
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(NButton, { onClick: search, children: "搜索" }),
|
|
4730
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4264
4731
|
NButton,
|
|
4265
4732
|
{
|
|
4266
4733
|
style: {
|
|
@@ -4274,8 +4741,8 @@ var __defProp = Object.defineProperty;
|
|
|
4274
4741
|
}
|
|
4275
4742
|
)
|
|
4276
4743
|
] }),
|
|
4277
|
-
/* @__PURE__ */ (0,
|
|
4278
|
-
/* @__PURE__ */ (0,
|
|
4744
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { marginBottom: 10, display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: [
|
|
4745
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4279
4746
|
"button",
|
|
4280
4747
|
{
|
|
4281
4748
|
type: "button",
|
|
@@ -4300,10 +4767,10 @@ var __defProp = Object.defineProperty;
|
|
|
4300
4767
|
children: "无绑定 · " + orphanCount
|
|
4301
4768
|
}
|
|
4302
4769
|
),
|
|
4303
|
-
(tagFilter || untaggedOnly) && /* @__PURE__ */ (0,
|
|
4770
|
+
(tagFilter || untaggedOnly) && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { style: S.muted, children: [
|
|
4304
4771
|
"筛选中:",
|
|
4305
4772
|
untaggedOnly ? "无绑定" : tagFilter,
|
|
4306
|
-
/* @__PURE__ */ (0,
|
|
4773
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4307
4774
|
"button",
|
|
4308
4775
|
{
|
|
4309
4776
|
type: "button",
|
|
@@ -4320,7 +4787,7 @@ var __defProp = Object.defineProperty;
|
|
|
4320
4787
|
}
|
|
4321
4788
|
)
|
|
4322
4789
|
] }),
|
|
4323
|
-
/* @__PURE__ */ (0,
|
|
4790
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4324
4791
|
"button",
|
|
4325
4792
|
{
|
|
4326
4793
|
type: "button",
|
|
@@ -4349,15 +4816,15 @@ var __defProp = Object.defineProperty;
|
|
|
4349
4816
|
children: "导出孤儿"
|
|
4350
4817
|
}
|
|
4351
4818
|
),
|
|
4352
|
-
/* @__PURE__ */ (0,
|
|
4819
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "Room 标签/分类管理:见「Hall」「Room」标签页。" })
|
|
4353
4820
|
] }),
|
|
4354
|
-
/* @__PURE__ */ (0,
|
|
4355
|
-
/* @__PURE__ */ (0,
|
|
4356
|
-
usageSummary ? /* @__PURE__ */ (0,
|
|
4357
|
-
/* @__PURE__ */ (0,
|
|
4821
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
4822
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: loading ? "加载中…" : countText }),
|
|
4823
|
+
usageSummary ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, title: "老化权重效果口径:参与召回尝试的记忆中,进 topN(被注入上下文)的比例", children: "召回使用 " + usageSummary.used + "/" + usageSummary.attempted + "(" + usageSummary.rate + "%)" }) : null,
|
|
4824
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "退场筛查" }),
|
|
4358
4825
|
[["", "全部"], ["active", "仅活跃"], ["retired", "仅退场"]].map(([val, label]) => {
|
|
4359
4826
|
const on = retiredFilter === val;
|
|
4360
|
-
return /* @__PURE__ */ (0,
|
|
4827
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4361
4828
|
"button",
|
|
4362
4829
|
{
|
|
4363
4830
|
type: "button",
|
|
@@ -4377,7 +4844,7 @@ var __defProp = Object.defineProperty;
|
|
|
4377
4844
|
val
|
|
4378
4845
|
);
|
|
4379
4846
|
}),
|
|
4380
|
-
/* @__PURE__ */ (0,
|
|
4847
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4381
4848
|
NButton,
|
|
4382
4849
|
{
|
|
4383
4850
|
style: selCount > 0 ? { color: "var(--dsh-mem-danger)" } : void 0,
|
|
@@ -4387,7 +4854,7 @@ var __defProp = Object.defineProperty;
|
|
|
4387
4854
|
children: "删除选中" + (selCount > 0 ? "(" + selCount + ")" : "")
|
|
4388
4855
|
}
|
|
4389
4856
|
),
|
|
4390
|
-
selCount > 0 ? /* @__PURE__ */ (0,
|
|
4857
|
+
selCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4391
4858
|
NButton,
|
|
4392
4859
|
{
|
|
4393
4860
|
onClick: () => {
|
|
@@ -4396,8 +4863,8 @@ var __defProp = Object.defineProperty;
|
|
|
4396
4863
|
children: "清空选择"
|
|
4397
4864
|
}
|
|
4398
4865
|
) : null,
|
|
4399
|
-
/* @__PURE__ */ (0,
|
|
4400
|
-
/* @__PURE__ */ (0,
|
|
4866
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
4867
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4401
4868
|
NButton,
|
|
4402
4869
|
{
|
|
4403
4870
|
onClick: () => {
|
|
@@ -4408,13 +4875,13 @@ var __defProp = Object.defineProperty;
|
|
|
4408
4875
|
}
|
|
4409
4876
|
)
|
|
4410
4877
|
] }),
|
|
4411
|
-
!hiPriv ? /* @__PURE__ */ (0,
|
|
4412
|
-
error ? /* @__PURE__ */ (0,
|
|
4413
|
-
truncated ? /* @__PURE__ */ (0,
|
|
4414
|
-
items.length === 0 && !loading && !error ? /* @__PURE__ */ (0,
|
|
4878
|
+
!hiPriv ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.hint, children: "提示:删除记忆需先开启高权限模式(右上开关或概览页「高权限模式」),关闭时删除按钮不可用。" }) : null,
|
|
4879
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.error, children: error }) : null,
|
|
4880
|
+
truncated ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.hint, children: "搜索分页已达检索上限(200 条),更早的结果未显示。请用更精确的关键词或类型/情境过滤。" }) : null,
|
|
4881
|
+
items.length === 0 && !loading && !error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: S.intro, children: "暂无记忆。对话几轮后,蒸馏管线会自动抽取记忆。" }) : items.map((m) => {
|
|
4415
4882
|
const open = expandedId === m.id;
|
|
4416
4883
|
const checked = sel.has(m.id);
|
|
4417
|
-
return /* @__PURE__ */ (0,
|
|
4884
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4418
4885
|
"div",
|
|
4419
4886
|
{
|
|
4420
4887
|
className: "dsh-mem-card dsh-mem-card-hover",
|
|
@@ -4423,8 +4890,8 @@ var __defProp = Object.defineProperty;
|
|
|
4423
4890
|
setExpandedId(open ? null : m.id);
|
|
4424
4891
|
},
|
|
4425
4892
|
children: [
|
|
4426
|
-
/* @__PURE__ */ (0,
|
|
4427
|
-
/* @__PURE__ */ (0,
|
|
4893
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: S.cardHead, children: [
|
|
4894
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4428
4895
|
"input",
|
|
4429
4896
|
{
|
|
4430
4897
|
type: "checkbox",
|
|
@@ -4439,9 +4906,9 @@ var __defProp = Object.defineProperty;
|
|
|
4439
4906
|
}
|
|
4440
4907
|
}
|
|
4441
4908
|
),
|
|
4442
|
-
/* @__PURE__ */ (0,
|
|
4443
|
-
m.hall ? /* @__PURE__ */ (0,
|
|
4444
|
-
m.retired ? /* @__PURE__ */ (0,
|
|
4909
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: tagClass(m.type), children: typeLabel(m.type) }),
|
|
4910
|
+
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,
|
|
4911
|
+
m.retired ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4445
4912
|
"span",
|
|
4446
4913
|
{
|
|
4447
4914
|
title: "该记忆已退场(软删):移出检索面但仍可恢复,并未真正删除",
|
|
@@ -4456,8 +4923,8 @@ var __defProp = Object.defineProperty;
|
|
|
4456
4923
|
children: "已退场" + (m.retiredReason ? " · " + (RETIRE_REASON_LABEL[m.retiredReason] || m.retiredReason) : "")
|
|
4457
4924
|
}
|
|
4458
4925
|
) : null,
|
|
4459
|
-
/* @__PURE__ */ (0,
|
|
4460
|
-
m.maturity ? /* @__PURE__ */ (0,
|
|
4926
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "优先级 " + m.priority }),
|
|
4927
|
+
m.maturity ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4461
4928
|
"span",
|
|
4462
4929
|
{
|
|
4463
4930
|
title: "成熟度(优先级 + 被用次数 + 新鲜度合成):" + m.maturity,
|
|
@@ -4472,7 +4939,7 @@ var __defProp = Object.defineProperty;
|
|
|
4472
4939
|
children: m.maturity === "high" ? "成熟·高" : m.maturity === "mid" ? "成熟·中" : "成熟·低"
|
|
4473
4940
|
}
|
|
4474
4941
|
) : null,
|
|
4475
|
-
m.agingWeight != null ? /* @__PURE__ */ (0,
|
|
4942
|
+
m.agingWeight != null ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4476
4943
|
"span",
|
|
4477
4944
|
{
|
|
4478
4945
|
style: {
|
|
@@ -4487,7 +4954,7 @@ var __defProp = Object.defineProperty;
|
|
|
4487
4954
|
children: "老化 " + Math.round(m.agingWeight * 100) + "%"
|
|
4488
4955
|
}
|
|
4489
4956
|
) : null,
|
|
4490
|
-
m.usage ? /* @__PURE__ */ (0,
|
|
4957
|
+
m.usage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4491
4958
|
"span",
|
|
4492
4959
|
{
|
|
4493
4960
|
style: S.muted,
|
|
@@ -4495,7 +4962,7 @@ var __defProp = Object.defineProperty;
|
|
|
4495
4962
|
children: "用 " + m.usage.used + "/" + m.usage.attempts
|
|
4496
4963
|
}
|
|
4497
4964
|
) : null,
|
|
4498
|
-
/* @__PURE__ */ (0,
|
|
4965
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4499
4966
|
"span",
|
|
4500
4967
|
{
|
|
4501
4968
|
title: m.name && m.name.length > 0 ? "名称(名称蒸馏产物;投射文件的命名取它):" + m.name : "尚未命名(名称蒸馏未产出);投射回落 mem-" + m.id.slice(-8),
|
|
@@ -4513,7 +4980,7 @@ var __defProp = Object.defineProperty;
|
|
|
4513
4980
|
children: "名称 " + (m.name && m.name.length > 0 ? m.name : "未命名")
|
|
4514
4981
|
}
|
|
4515
4982
|
),
|
|
4516
|
-
/* @__PURE__ */ (0,
|
|
4983
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4517
4984
|
"span",
|
|
4518
4985
|
{
|
|
4519
4986
|
title: m.scope === "workspace" ? "作用范围:指定工作区(仅归属工作区可见)" + (m.workspaceId ? ":" + m.workspaceId : "") : "作用范围:用户默认(global,任何工作区可见)",
|
|
@@ -4528,10 +4995,10 @@ var __defProp = Object.defineProperty;
|
|
|
4528
4995
|
children: m.scope === "workspace" ? "工作区" : "用户默认"
|
|
4529
4996
|
}
|
|
4530
4997
|
),
|
|
4531
|
-
m.score !== null && m.score !== void 0 ? /* @__PURE__ */ (0,
|
|
4532
|
-
/* @__PURE__ */ (0,
|
|
4533
|
-
/* @__PURE__ */ (0,
|
|
4534
|
-
m.retired ? /* @__PURE__ */ (0,
|
|
4998
|
+
m.score !== null && m.score !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "相关度 " + Number(m.score).toFixed(2) }) : null,
|
|
4999
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
5000
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: fmtTime(m.updatedAt) }),
|
|
5001
|
+
m.retired ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4535
5002
|
NButton,
|
|
4536
5003
|
{
|
|
4537
5004
|
style: { padding: "0 7px", minWidth: 26, height: 26, fontSize: 12, color: "var(--dsh-mem-accent)" },
|
|
@@ -4542,7 +5009,7 @@ var __defProp = Object.defineProperty;
|
|
|
4542
5009
|
},
|
|
4543
5010
|
children: "恢复"
|
|
4544
5011
|
}
|
|
4545
|
-
) : hiPriv ? /* @__PURE__ */ (0,
|
|
5012
|
+
) : hiPriv ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4546
5013
|
NButton,
|
|
4547
5014
|
{
|
|
4548
5015
|
style: { padding: "0 7px", minWidth: 26, height: 26, fontSize: 12, color: "var(--dsh-mem-danger)" },
|
|
@@ -4555,34 +5022,34 @@ var __defProp = Object.defineProperty;
|
|
|
4555
5022
|
}
|
|
4556
5023
|
) : null
|
|
4557
5024
|
] }),
|
|
4558
|
-
/* @__PURE__ */ (0,
|
|
4559
|
-
open ? /* @__PURE__ */ (0,
|
|
5025
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.content, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(MarkdownBody, { text: m.content }) }),
|
|
5026
|
+
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
5027
|
]
|
|
4561
5028
|
},
|
|
4562
5029
|
m.id
|
|
4563
5030
|
);
|
|
4564
5031
|
}),
|
|
4565
|
-
/* @__PURE__ */ (0,
|
|
4566
|
-
/* @__PURE__ */ (0,
|
|
4567
|
-
showRetired && retiredBusy ? /* @__PURE__ */ (0,
|
|
4568
|
-
showRetired && !retiredBusy && retiredTotal > 0 ? /* @__PURE__ */ (0,
|
|
5032
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { ...S.flexRow, marginTop: 12 }, children: [
|
|
5033
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(NButton, { onClick: () => setShowRetired((v) => !v), children: (showRetired ? "收起" : "展开") + "「已退场」(可恢复)" }),
|
|
5034
|
+
showRetired && retiredBusy ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "加载中…" }) : null,
|
|
5035
|
+
showRetired && !retiredBusy && retiredTotal > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "共 " + retiredTotal + " 条可恢复" }) : null
|
|
4569
5036
|
] }),
|
|
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,
|
|
5037
|
+
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: [
|
|
5038
|
+
retired.map((m) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "dsh-mem-card", style: S.card, children: [
|
|
5039
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: S.cardHead, children: [
|
|
5040
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: RETIRE_REASON_LABEL[m.retiredReason] || m.retiredReason }),
|
|
5041
|
+
m.verdict ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "结论 " + m.verdict }) : null,
|
|
5042
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
5043
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: fmtTime(m.retiredAt) }),
|
|
5044
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(NButton, { disabled: retiredBusy, title: "恢复到检索面", onClick: () => restoreRecords([m.id]), children: "恢复" })
|
|
4578
5045
|
] }),
|
|
4579
|
-
/* @__PURE__ */ (0,
|
|
5046
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.content, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(MarkdownBody, { text: m.content }) })
|
|
4580
5047
|
] }, m.id)),
|
|
4581
|
-
retiredTotal > retired.length ? /* @__PURE__ */ (0,
|
|
5048
|
+
retiredTotal > retired.length ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: S.hint, children: "共 " + retiredTotal + " 条,此处显示 " + retired.length + " 条" }) : null
|
|
4582
5049
|
] }) }) : null,
|
|
4583
|
-
hasMore ? /* @__PURE__ */ (0,
|
|
4584
|
-
/* @__PURE__ */ (0,
|
|
4585
|
-
/* @__PURE__ */ (0,
|
|
5050
|
+
hasMore ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: S.flexRow, children: [
|
|
5051
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
5052
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4586
5053
|
NButton,
|
|
4587
5054
|
{
|
|
4588
5055
|
disabled: loading,
|
|
@@ -4596,9 +5063,9 @@ var __defProp = Object.defineProperty;
|
|
|
4596
5063
|
] });
|
|
4597
5064
|
}
|
|
4598
5065
|
function WingMultiSelect(props) {
|
|
4599
|
-
const [open, setOpen] = (0,
|
|
4600
|
-
const wrapRef = (0,
|
|
4601
|
-
(0,
|
|
5066
|
+
const [open, setOpen] = (0, import_react20.useState)(false);
|
|
5067
|
+
const wrapRef = (0, import_react20.useRef)(null);
|
|
5068
|
+
(0, import_react20.useEffect)(() => {
|
|
4602
5069
|
if (!open) return;
|
|
4603
5070
|
const onDown = (e) => {
|
|
4604
5071
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -4618,8 +5085,8 @@ var __defProp = Object.defineProperty;
|
|
|
4618
5085
|
const toggle = (id) => {
|
|
4619
5086
|
props.onChange(props.selected.includes(id) ? props.selected.filter((x) => x !== id) : [...props.selected, id]);
|
|
4620
5087
|
};
|
|
4621
|
-
return /* @__PURE__ */ (0,
|
|
4622
|
-
/* @__PURE__ */ (0,
|
|
5088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { ref: wrapRef, style: { position: "relative", maxWidth: 150 }, children: [
|
|
5089
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4623
5090
|
"button",
|
|
4624
5091
|
{
|
|
4625
5092
|
type: "button",
|
|
@@ -4628,31 +5095,31 @@ var __defProp = Object.defineProperty;
|
|
|
4628
5095
|
"aria-expanded": open,
|
|
4629
5096
|
onClick: () => setOpen(!open),
|
|
4630
5097
|
children: [
|
|
4631
|
-
/* @__PURE__ */ (0,
|
|
4632
|
-
/* @__PURE__ */ (0,
|
|
5098
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-select-label", title: summary, children: summary }),
|
|
5099
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-sel-chev" + (open ? " dsh-mem-sel-chev-open" : "") })
|
|
4633
5100
|
]
|
|
4634
5101
|
}
|
|
4635
5102
|
),
|
|
4636
|
-
open ? /* @__PURE__ */ (0,
|
|
4637
|
-
props.options.length === 0 ? /* @__PURE__ */ (0,
|
|
5103
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "dsh-mem-pop", role: "listbox", style: { left: 0, right: "auto", minWidth: 150 }, children: [
|
|
5104
|
+
props.options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "dsh-mem-pop-empty", children: "暂无可筛 Hall" }) : null,
|
|
4638
5105
|
props.options.map((o) => {
|
|
4639
5106
|
const active = props.selected.includes(o.id);
|
|
4640
|
-
return /* @__PURE__ */ (0,
|
|
4641
|
-
/* @__PURE__ */ (0,
|
|
4642
|
-
/* @__PURE__ */ (0,
|
|
5107
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { type: "button", className: "dsh-mem-pop-opt", onClick: () => toggle(o.id), "aria-selected": active, children: [
|
|
5108
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-pop-check", children: active ? "✓" : "" }),
|
|
5109
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-pop-label", children: o.label })
|
|
4643
5110
|
] }, o.id);
|
|
4644
5111
|
}),
|
|
4645
|
-
props.selected.length > 0 ? /* @__PURE__ */ (0,
|
|
4646
|
-
/* @__PURE__ */ (0,
|
|
4647
|
-
/* @__PURE__ */ (0,
|
|
5112
|
+
props.selected.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { type: "button", className: "dsh-mem-pop-opt", onClick: () => props.onChange([]), children: [
|
|
5113
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-pop-check" }),
|
|
5114
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "dsh-mem-pop-label", children: "清除筛选" })
|
|
4648
5115
|
] }) : null
|
|
4649
5116
|
] }) : null
|
|
4650
5117
|
] });
|
|
4651
5118
|
}
|
|
4652
5119
|
|
|
4653
5120
|
// client/src/tabs/RoomsTab.tsx
|
|
4654
|
-
var
|
|
4655
|
-
var
|
|
5121
|
+
var import_react21 = require("react");
|
|
5122
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4656
5123
|
function majorOf(slug) {
|
|
4657
5124
|
const i = slug.indexOf("/");
|
|
4658
5125
|
return i === -1 ? slug : slug.slice(0, i);
|
|
@@ -4681,26 +5148,26 @@ var __defProp = Object.defineProperty;
|
|
|
4681
5148
|
};
|
|
4682
5149
|
function RoomsTab(props) {
|
|
4683
5150
|
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,
|
|
5151
|
+
const [registry, setRegistry] = (0, import_react21.useState)([]);
|
|
5152
|
+
const [rooms, setRooms] = (0, import_react21.useState)([]);
|
|
5153
|
+
const [orphanCount, setOrphanCount] = (0, import_react21.useState)(0);
|
|
5154
|
+
const [busy, setBusy] = (0, import_react21.useState)(false);
|
|
5155
|
+
const [msg, setMsg] = (0, import_react21.useState)(null);
|
|
5156
|
+
const [error, setError] = (0, import_react21.useState)(null);
|
|
5157
|
+
const [hiPriv, setHiPriv] = (0, import_react21.useState)(false);
|
|
5158
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react21.useState)(false);
|
|
5159
|
+
const [regSlug, setRegSlug] = (0, import_react21.useState)("");
|
|
5160
|
+
const [regLabel, setRegLabel] = (0, import_react21.useState)("");
|
|
5161
|
+
const [regDesc, setRegDesc] = (0, import_react21.useState)("");
|
|
5162
|
+
const [form, setForm] = (0, import_react21.useState)(null);
|
|
5163
|
+
const [preview, setPreview] = (0, import_react21.useState)(null);
|
|
5164
|
+
const [grownOpen, setGrownOpen] = (0, import_react21.useState)(false);
|
|
5165
|
+
const [dragOverHall, setDragOverHall] = (0, import_react21.useState)(null);
|
|
5166
|
+
const [picking, setPicking] = (0, import_react21.useState)(null);
|
|
5167
|
+
const [editing, setEditing] = (0, import_react21.useState)(null);
|
|
5168
|
+
const [expandedRooms, setExpandedRooms] = (0, import_react21.useState)(/* @__PURE__ */ new Set());
|
|
5169
|
+
const [roomRecords, setRoomRecords] = (0, import_react21.useState)({});
|
|
5170
|
+
const [expandedHalls, setExpandedHalls] = (0, import_react21.useState)(() => {
|
|
4704
5171
|
try {
|
|
4705
5172
|
const v = window.localStorage.getItem("dsh.memory.halls.open");
|
|
4706
5173
|
return v ? new Set(JSON.parse(v)) : /* @__PURE__ */ new Set();
|
|
@@ -4708,9 +5175,9 @@ var __defProp = Object.defineProperty;
|
|
|
4708
5175
|
return /* @__PURE__ */ new Set();
|
|
4709
5176
|
}
|
|
4710
5177
|
});
|
|
4711
|
-
const [filter, setFilter] = (0,
|
|
4712
|
-
const dragRef = (0,
|
|
4713
|
-
const [ghost, setGhost] = (0,
|
|
5178
|
+
const [filter, setFilter] = (0, import_react21.useState)("");
|
|
5179
|
+
const dragRef = (0, import_react21.useRef)(null);
|
|
5180
|
+
const [ghost, setGhost] = (0, import_react21.useState)(null);
|
|
4714
5181
|
const onDragLabelDown = (ev, slug) => {
|
|
4715
5182
|
if (!hiPriv || busy || ev.button !== 0) return;
|
|
4716
5183
|
ev.currentTarget.setPointerCapture(ev.pointerId);
|
|
@@ -4735,7 +5202,7 @@ var __defProp = Object.defineProperty;
|
|
|
4735
5202
|
setDragOverHall(null);
|
|
4736
5203
|
if (hall) beginReclass(d.from, hall);
|
|
4737
5204
|
};
|
|
4738
|
-
const loadAll = (0,
|
|
5205
|
+
const loadAll = (0, import_react21.useCallback)(() => {
|
|
4739
5206
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
4740
5207
|
if (r && r.ok) {
|
|
4741
5208
|
setRooms(r.value.rooms ?? []);
|
|
@@ -4744,13 +5211,13 @@ var __defProp = Object.defineProperty;
|
|
|
4744
5211
|
}
|
|
4745
5212
|
}).catch(() => void 0);
|
|
4746
5213
|
}, [rpc]);
|
|
4747
|
-
const loadHiPriv = (0,
|
|
5214
|
+
const loadHiPriv = (0, import_react21.useCallback)(() => {
|
|
4748
5215
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
4749
5216
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
4750
5217
|
}).catch(() => {
|
|
4751
5218
|
});
|
|
4752
5219
|
}, [rpc]);
|
|
4753
|
-
(0,
|
|
5220
|
+
(0, import_react21.useEffect)(() => {
|
|
4754
5221
|
loadAll();
|
|
4755
5222
|
loadHiPriv();
|
|
4756
5223
|
}, [loadAll, loadHiPriv]);
|
|
@@ -4905,7 +5372,7 @@ var __defProp = Object.defineProperty;
|
|
|
4905
5372
|
if (r.value.csv) downloadCsv(r.value.csv, `dsh-memory-room-${slug.replace(/\//g, "-")}-records.csv`);
|
|
4906
5373
|
else setError("导出为空");
|
|
4907
5374
|
});
|
|
4908
|
-
const groups = (0,
|
|
5375
|
+
const groups = (0, import_react21.useMemo)(() => {
|
|
4909
5376
|
const countOf = new Map(rooms.map((r) => [r.room, r.count]));
|
|
4910
5377
|
const byHall = /* @__PURE__ */ new Map();
|
|
4911
5378
|
for (const e of registry) {
|
|
@@ -4922,7 +5389,7 @@ var __defProp = Object.defineProperty;
|
|
|
4922
5389
|
total: entries.reduce((s2, e) => s2 + (countOf.get(e.slug) ?? 0), 0)
|
|
4923
5390
|
})).sort((a, b) => a.hall.localeCompare(b.hall));
|
|
4924
5391
|
}, [registry, rooms]);
|
|
4925
|
-
const grownOnly = (0,
|
|
5392
|
+
const grownOnly = (0, import_react21.useMemo)(() => rooms.filter((r) => !registry.some((e) => e.slug === r.room)), [rooms, registry]);
|
|
4926
5393
|
const persistHalls = (next) => {
|
|
4927
5394
|
try {
|
|
4928
5395
|
window.localStorage.setItem("dsh.memory.halls.open", JSON.stringify([...next]));
|
|
@@ -4942,7 +5409,7 @@ var __defProp = Object.defineProperty;
|
|
|
4942
5409
|
persistHalls(next);
|
|
4943
5410
|
};
|
|
4944
5411
|
const normFilter = filter.trim().toLowerCase();
|
|
4945
|
-
const visibleGroups = (0,
|
|
5412
|
+
const visibleGroups = (0, import_react21.useMemo)(() => {
|
|
4946
5413
|
if (!normFilter) return groups;
|
|
4947
5414
|
return groups.map((g) => {
|
|
4948
5415
|
const hallHit = g.hall.toLowerCase().includes(normFilter) || (g.label ?? "").toLowerCase().includes(normFilter);
|
|
@@ -4952,15 +5419,15 @@ var __defProp = Object.defineProperty;
|
|
|
4952
5419
|
return { ...g, entries };
|
|
4953
5420
|
}).filter((g) => g.entries.length > 0);
|
|
4954
5421
|
}, [groups, normFilter]);
|
|
4955
|
-
const visibleGrown = (0,
|
|
5422
|
+
const visibleGrown = (0, import_react21.useMemo)(
|
|
4956
5423
|
() => normFilter ? grownOnly.filter((r) => r.room.toLowerCase().includes(normFilter)) : grownOnly,
|
|
4957
5424
|
[grownOnly, normFilter]
|
|
4958
5425
|
);
|
|
4959
|
-
return /* @__PURE__ */ (0,
|
|
4960
|
-
/* @__PURE__ */ (0,
|
|
4961
|
-
/* @__PURE__ */ (0,
|
|
4962
|
-
/* @__PURE__ */ (0,
|
|
4963
|
-
/* @__PURE__ */ (0,
|
|
5426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
|
|
5427
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { ...S.flexRow, marginBottom: 8 }, children: [
|
|
5428
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "Hall = Room 大类 · 大类上限 200,小类「大类/小类」细分不占额度 · 与 Wing(域)筛选无关" }),
|
|
5429
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.grow }),
|
|
5430
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4964
5431
|
"button",
|
|
4965
5432
|
{
|
|
4966
5433
|
type: "button",
|
|
@@ -4977,7 +5444,7 @@ var __defProp = Object.defineProperty;
|
|
|
4977
5444
|
children: "导出词表"
|
|
4978
5445
|
}
|
|
4979
5446
|
),
|
|
4980
|
-
/* @__PURE__ */ (0,
|
|
5447
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
4981
5448
|
"button",
|
|
4982
5449
|
{
|
|
4983
5450
|
type: "button",
|
|
@@ -4997,7 +5464,7 @@ var __defProp = Object.defineProperty;
|
|
|
4997
5464
|
]
|
|
4998
5465
|
}
|
|
4999
5466
|
),
|
|
5000
|
-
/* @__PURE__ */ (0,
|
|
5467
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5001
5468
|
"button",
|
|
5002
5469
|
{
|
|
5003
5470
|
type: "button",
|
|
@@ -5012,10 +5479,10 @@ var __defProp = Object.defineProperty;
|
|
|
5012
5479
|
children: hiPriv ? "高权限:开" : "高权限:关"
|
|
5013
5480
|
}
|
|
5014
5481
|
),
|
|
5015
|
-
/* @__PURE__ */ (0,
|
|
5482
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn, onClick: loadAll, title: "重拉注册表与计数", children: "刷新" })
|
|
5016
5483
|
] }),
|
|
5017
|
-
/* @__PURE__ */ (0,
|
|
5018
|
-
/* @__PURE__ */ (0,
|
|
5484
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center", marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
5485
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5019
5486
|
"input",
|
|
5020
5487
|
{
|
|
5021
5488
|
value: filter,
|
|
@@ -5024,14 +5491,14 @@ var __defProp = Object.defineProperty;
|
|
|
5024
5491
|
style: { ...S.input, width: 250, fontSize: 12 }
|
|
5025
5492
|
}
|
|
5026
5493
|
),
|
|
5027
|
-
filter ? /* @__PURE__ */ (0,
|
|
5028
|
-
/* @__PURE__ */ (0,
|
|
5029
|
-
/* @__PURE__ */ (0,
|
|
5030
|
-
/* @__PURE__ */ (0,
|
|
5031
|
-
/* @__PURE__ */ (0,
|
|
5494
|
+
filter ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn, onClick: () => setFilter(""), children: "清除" }) : null,
|
|
5495
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: `匹配 ${visibleGroups.reduce((s2, g) => s2 + g.entries.length, 0)} room / ${visibleGroups.length} hall` }),
|
|
5496
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.grow }),
|
|
5497
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn, title: "展开全部 hall 的子 room", onClick: () => setAllHalls(true), children: "展开全部" }),
|
|
5498
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn, title: "收起全部 hall(只留 hall 头)", onClick: () => setAllHalls(false), children: "收起全部" })
|
|
5032
5499
|
] }),
|
|
5033
|
-
/* @__PURE__ */ (0,
|
|
5034
|
-
/* @__PURE__ */ (0,
|
|
5500
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginBottom: 10 }, children: [
|
|
5501
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5035
5502
|
"input",
|
|
5036
5503
|
{
|
|
5037
5504
|
value: regSlug,
|
|
@@ -5041,7 +5508,7 @@ var __defProp = Object.defineProperty;
|
|
|
5041
5508
|
style: { ...S.input, width: 210, fontSize: 12 }
|
|
5042
5509
|
}
|
|
5043
5510
|
),
|
|
5044
|
-
/* @__PURE__ */ (0,
|
|
5511
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5045
5512
|
"input",
|
|
5046
5513
|
{
|
|
5047
5514
|
value: regLabel,
|
|
@@ -5051,7 +5518,7 @@ var __defProp = Object.defineProperty;
|
|
|
5051
5518
|
style: { ...S.input, width: 110, fontSize: 12 }
|
|
5052
5519
|
}
|
|
5053
5520
|
),
|
|
5054
|
-
/* @__PURE__ */ (0,
|
|
5521
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5055
5522
|
"input",
|
|
5056
5523
|
{
|
|
5057
5524
|
value: regDesc,
|
|
@@ -5061,7 +5528,7 @@ var __defProp = Object.defineProperty;
|
|
|
5061
5528
|
style: { ...S.input, width: 170, fontSize: 12 }
|
|
5062
5529
|
}
|
|
5063
5530
|
),
|
|
5064
|
-
/* @__PURE__ */ (0,
|
|
5531
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5065
5532
|
"button",
|
|
5066
5533
|
{
|
|
5067
5534
|
type: "button",
|
|
@@ -5071,26 +5538,26 @@ var __defProp = Object.defineProperty;
|
|
|
5071
5538
|
children: "注册"
|
|
5072
5539
|
}
|
|
5073
5540
|
),
|
|
5074
|
-
!hiPriv && /* @__PURE__ */ (0,
|
|
5541
|
+
!hiPriv && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "管理操作需先开启高权限模式" })
|
|
5075
5542
|
] }),
|
|
5076
|
-
editing ? /* @__PURE__ */ (0,
|
|
5077
|
-
/* @__PURE__ */ (0,
|
|
5543
|
+
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: [
|
|
5544
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: S.muted, children: [
|
|
5078
5545
|
"编辑 ",
|
|
5079
5546
|
editing.slug
|
|
5080
5547
|
] }),
|
|
5081
|
-
/* @__PURE__ */ (0,
|
|
5082
|
-
/* @__PURE__ */ (0,
|
|
5083
|
-
/* @__PURE__ */ (0,
|
|
5084
|
-
/* @__PURE__ */ (0,
|
|
5548
|
+
/* @__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 } }),
|
|
5549
|
+
/* @__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 } }),
|
|
5550
|
+
/* @__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: "保存" }),
|
|
5551
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: () => setEditing(null), style: btn, children: "取消" })
|
|
5085
5552
|
] }) : null,
|
|
5086
|
-
form ? /* @__PURE__ */ (0,
|
|
5087
|
-
/* @__PURE__ */ (0,
|
|
5553
|
+
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: [
|
|
5554
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: S.muted, children: [
|
|
5088
5555
|
form.action === "merge" ? "合并" : "归类/改名",
|
|
5089
5556
|
" ",
|
|
5090
5557
|
form.from,
|
|
5091
5558
|
" →"
|
|
5092
5559
|
] }),
|
|
5093
|
-
/* @__PURE__ */ (0,
|
|
5560
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5094
5561
|
"input",
|
|
5095
5562
|
{
|
|
5096
5563
|
value: form.to,
|
|
@@ -5100,7 +5567,7 @@ var __defProp = Object.defineProperty;
|
|
|
5100
5567
|
style: { ...S.input, width: 190, fontSize: 12 }
|
|
5101
5568
|
}
|
|
5102
5569
|
),
|
|
5103
|
-
form.action === "rename" ? /* @__PURE__ */ (0,
|
|
5570
|
+
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
5571
|
"button",
|
|
5105
5572
|
{
|
|
5106
5573
|
type: "button",
|
|
@@ -5111,32 +5578,32 @@ var __defProp = Object.defineProperty;
|
|
|
5111
5578
|
},
|
|
5112
5579
|
gg.hall
|
|
5113
5580
|
)) }) : null,
|
|
5114
|
-
/* @__PURE__ */ (0,
|
|
5115
|
-
/* @__PURE__ */ (0,
|
|
5581
|
+
/* @__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: "预览" }),
|
|
5582
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: () => {
|
|
5116
5583
|
setForm(null);
|
|
5117
5584
|
setPreview(null);
|
|
5118
5585
|
setPicking(null);
|
|
5119
5586
|
}, style: btn, children: "取消" }),
|
|
5120
|
-
picking ? /* @__PURE__ */ (0,
|
|
5121
|
-
/* @__PURE__ */ (0,
|
|
5587
|
+
picking ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "挑选中:点击目标 hall 头完成归类" }) : null,
|
|
5588
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "与反刍并发会互相覆盖,请在反刍空闲时执行。" })
|
|
5122
5589
|
] }) : null,
|
|
5123
|
-
preview ? /* @__PURE__ */ (0,
|
|
5124
|
-
/* @__PURE__ */ (0,
|
|
5125
|
-
/* @__PURE__ */ (0,
|
|
5126
|
-
/* @__PURE__ */ (0,
|
|
5590
|
+
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: [
|
|
5591
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { children: preview.notice }),
|
|
5592
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, marginTop: 4 }, children: [
|
|
5593
|
+
/* @__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
5594
|
"确认执行",
|
|
5128
5595
|
preview.action === "merge" ? "合并" : "归类/改名"
|
|
5129
5596
|
] }),
|
|
5130
|
-
/* @__PURE__ */ (0,
|
|
5597
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: () => setPreview(null), style: btn, children: "再改改" })
|
|
5131
5598
|
] })
|
|
5132
5599
|
] }) : null,
|
|
5133
|
-
msg ? /* @__PURE__ */ (0,
|
|
5134
|
-
error ? /* @__PURE__ */ (0,
|
|
5135
|
-
ghost ? /* @__PURE__ */ (0,
|
|
5136
|
-
visibleGroups.length === 0 ? /* @__PURE__ */ (0,
|
|
5600
|
+
msg ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.hint, children: msg }) : null,
|
|
5601
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.error, children: error }) : null,
|
|
5602
|
+
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,
|
|
5603
|
+
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
5604
|
const hallOpen = !!normFilter || expandedHalls.has(g.hall);
|
|
5138
|
-
return /* @__PURE__ */ (0,
|
|
5139
|
-
/* @__PURE__ */ (0,
|
|
5605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 10, border: "1px solid var(--dsh-mem-border)", borderRadius: 8, overflow: "hidden" }, children: [
|
|
5606
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5140
5607
|
"div",
|
|
5141
5608
|
{
|
|
5142
5609
|
"data-hall": g.hall,
|
|
@@ -5177,7 +5644,7 @@ var __defProp = Object.defineProperty;
|
|
|
5177
5644
|
},
|
|
5178
5645
|
title: picking ? "点击此 hall:把「" + picking + "」归入 " + g.hall + " 下(major/minor,预览后确认)" : hiPriv ? "拖入 room 归类到该 hall 下(major/minor;记录随迁,旧名进别名,预览后确认)" : void 0,
|
|
5179
5646
|
children: [
|
|
5180
|
-
/* @__PURE__ */ (0,
|
|
5647
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5181
5648
|
"button",
|
|
5182
5649
|
{
|
|
5183
5650
|
type: "button",
|
|
@@ -5190,13 +5657,13 @@ var __defProp = Object.defineProperty;
|
|
|
5190
5657
|
children: hallOpen ? "▾" : "▸"
|
|
5191
5658
|
}
|
|
5192
5659
|
),
|
|
5193
|
-
/* @__PURE__ */ (0,
|
|
5660
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 12, fontWeight: 600 }, children: [
|
|
5194
5661
|
g.hall,
|
|
5195
|
-
g.label ? /* @__PURE__ */ (0,
|
|
5662
|
+
g.label ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: " (" + g.label + ")" }) : null
|
|
5196
5663
|
] }),
|
|
5197
|
-
/* @__PURE__ */ (0,
|
|
5198
|
-
/* @__PURE__ */ (0,
|
|
5199
|
-
/* @__PURE__ */ (0,
|
|
5664
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: `合计 ${g.total} 条 · ${g.entries.length} 个 room` }),
|
|
5665
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.grow }),
|
|
5666
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5200
5667
|
"button",
|
|
5201
5668
|
{
|
|
5202
5669
|
type: "button",
|
|
@@ -5217,10 +5684,10 @@ var __defProp = Object.defineProperty;
|
|
|
5217
5684
|
const standalone = e.slug === g.hall;
|
|
5218
5685
|
const count = rooms.find((r) => r.room === e.slug)?.count ?? 0;
|
|
5219
5686
|
const retired = e.status === "retired";
|
|
5220
|
-
return /* @__PURE__ */ (0,
|
|
5221
|
-
/* @__PURE__ */ (0,
|
|
5222
|
-
/* @__PURE__ */ (0,
|
|
5223
|
-
/* @__PURE__ */ (0,
|
|
5687
|
+
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: [
|
|
5688
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
5689
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { flex: 1, minWidth: 0, display: "flex", flexWrap: "wrap", gap: "2px 8px", alignItems: "baseline" }, children: [
|
|
5690
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5224
5691
|
"button",
|
|
5225
5692
|
{
|
|
5226
5693
|
type: "button",
|
|
@@ -5230,7 +5697,7 @@ var __defProp = Object.defineProperty;
|
|
|
5230
5697
|
children: expandedRooms.has(e.slug) ? "▾" : "▸"
|
|
5231
5698
|
}
|
|
5232
5699
|
),
|
|
5233
|
-
/* @__PURE__ */ (0,
|
|
5700
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5234
5701
|
"span",
|
|
5235
5702
|
{
|
|
5236
5703
|
style: { fontSize: 12, cursor: hiPriv && !busy ? "grab" : "default", touchAction: "none" },
|
|
@@ -5244,20 +5711,20 @@ var __defProp = Object.defineProperty;
|
|
|
5244
5711
|
]
|
|
5245
5712
|
}
|
|
5246
5713
|
),
|
|
5247
|
-
e.label ? /* @__PURE__ */ (0,
|
|
5248
|
-
/* @__PURE__ */ (0,
|
|
5249
|
-
retired ? /* @__PURE__ */ (0,
|
|
5250
|
-
(e.aliases ?? []).length > 0 ? /* @__PURE__ */ (0,
|
|
5714
|
+
e.label ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: e.label }) : null,
|
|
5715
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: count + " 条" }),
|
|
5716
|
+
retired ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "已退役" }) : null,
|
|
5717
|
+
(e.aliases ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { ...S.muted, wordBreak: "break-all" }, children: "别名: " + (e.aliases ?? []).join(", ") }) : null
|
|
5251
5718
|
] }),
|
|
5252
|
-
/* @__PURE__ */ (0,
|
|
5253
|
-
!hiPriv ? null : /* @__PURE__ */ (0,
|
|
5254
|
-
/* @__PURE__ */ (0,
|
|
5719
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, flexShrink: 0, alignItems: "center" }, children: [
|
|
5720
|
+
!hiPriv ? null : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
5721
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "编辑显示名/归类说明", onClick: () => {
|
|
5255
5722
|
setEditing({ slug: e.slug, label: e.label ?? "", description: e.description ?? "" });
|
|
5256
5723
|
setForm(null);
|
|
5257
5724
|
setPreview(null);
|
|
5258
5725
|
setPicking(null);
|
|
5259
5726
|
}, style: btn, children: "编辑" }),
|
|
5260
|
-
/* @__PURE__ */ (0,
|
|
5727
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5261
5728
|
"button",
|
|
5262
5729
|
{
|
|
5263
5730
|
type: "button",
|
|
@@ -5278,43 +5745,43 @@ var __defProp = Object.defineProperty;
|
|
|
5278
5745
|
children: picking === e.slug ? "选 hall…" : "归类"
|
|
5279
5746
|
}
|
|
5280
5747
|
),
|
|
5281
|
-
/* @__PURE__ */ (0,
|
|
5748
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: `改名(= merge 1:1 + 注册表改名)`, onClick: () => {
|
|
5282
5749
|
setForm({ action: "rename", from: e.slug, to: "" });
|
|
5283
5750
|
setPreview(null);
|
|
5284
5751
|
}, style: btn, children: "改名" }),
|
|
5285
|
-
/* @__PURE__ */ (0,
|
|
5752
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "合并到另一个 Room(dryRun 预览→确认实跑)", onClick: () => {
|
|
5286
5753
|
setForm({ action: "merge", from: e.slug, to: "" });
|
|
5287
5754
|
setPreview(null);
|
|
5288
5755
|
}, style: btn, children: "合并" }),
|
|
5289
|
-
/* @__PURE__ */ (0,
|
|
5290
|
-
!retired ? /* @__PURE__ */ (0,
|
|
5756
|
+
/* @__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 ? "恢复" : "退役" }),
|
|
5757
|
+
!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
5758
|
] }),
|
|
5292
|
-
/* @__PURE__ */ (0,
|
|
5759
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "导出该 Room 的记录清单 CSV", onClick: () => exportRecords(e.slug), style: btn, children: "导出" })
|
|
5293
5760
|
] })
|
|
5294
5761
|
] }),
|
|
5295
|
-
expandedRooms.has(e.slug) ? /* @__PURE__ */ (0,
|
|
5296
|
-
(roomRecords[e.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0,
|
|
5297
|
-
/* @__PURE__ */ (0,
|
|
5762
|
+
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: [
|
|
5763
|
+
(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: [
|
|
5764
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: tagClass(it.type), children: typeLabel(it.type) }),
|
|
5298
5765
|
" ",
|
|
5299
|
-
/* @__PURE__ */ (0,
|
|
5300
|
-
/* @__PURE__ */ (0,
|
|
5766
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: it.updatedAt ? fmtTime(it.updatedAt) : "" }),
|
|
5767
|
+
/* @__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
5768
|
] }, 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,
|
|
5769
|
+
(roomRecords[e.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.muted, children: "该 Room 暂无记录。" }) : null,
|
|
5770
|
+
(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
5771
|
] }) : null
|
|
5305
5772
|
] }, e.slug);
|
|
5306
5773
|
}) : null
|
|
5307
5774
|
] }, g.hall);
|
|
5308
5775
|
}),
|
|
5309
|
-
visibleGrown.length > 0 ? /* @__PURE__ */ (0,
|
|
5310
|
-
/* @__PURE__ */ (0,
|
|
5776
|
+
visibleGrown.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginTop: 4 }, children: [
|
|
5777
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { type: "button", onClick: () => setGrownOpen(!grownOpen), style: btn, title: grownOpen ? "收起未注册自生长 Room" : "展开未注册自生长 Room", children: [
|
|
5311
5778
|
grownOpen ? "▾" : "▸",
|
|
5312
5779
|
" 自生长未注册 · 共 ",
|
|
5313
5780
|
visibleGrown.length
|
|
5314
5781
|
] }),
|
|
5315
|
-
/* @__PURE__ */ (0,
|
|
5316
|
-
grownOpen ? /* @__PURE__ */ (0,
|
|
5317
|
-
/* @__PURE__ */ (0,
|
|
5782
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "(只在 tags 里涌现,不在词表 —— 收编后标注器才会优先挂靠)" }),
|
|
5783
|
+
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: [
|
|
5784
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5318
5785
|
"span",
|
|
5319
5786
|
{
|
|
5320
5787
|
style: { ...btn, cursor: hiPriv && !busy ? "grab" : "default", borderRadius: 999, padding: "2px 8px", touchAction: "none" },
|
|
@@ -5325,8 +5792,8 @@ var __defProp = Object.defineProperty;
|
|
|
5325
5792
|
children: r.room + " · " + r.count
|
|
5326
5793
|
}
|
|
5327
5794
|
),
|
|
5328
|
-
/* @__PURE__ */ (0,
|
|
5329
|
-
/* @__PURE__ */ (0,
|
|
5795
|
+
/* @__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: "收编" }),
|
|
5796
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5330
5797
|
"button",
|
|
5331
5798
|
{
|
|
5332
5799
|
type: "button",
|
|
@@ -5353,8 +5820,8 @@ var __defProp = Object.defineProperty;
|
|
|
5353
5820
|
}
|
|
5354
5821
|
|
|
5355
5822
|
// client/src/tabs/RoomTab.tsx
|
|
5356
|
-
var
|
|
5357
|
-
var
|
|
5823
|
+
var import_react22 = require("react");
|
|
5824
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
5358
5825
|
var btn2 = {
|
|
5359
5826
|
cursor: "pointer",
|
|
5360
5827
|
fontSize: 12,
|
|
@@ -5375,22 +5842,22 @@ var __defProp = Object.defineProperty;
|
|
|
5375
5842
|
}
|
|
5376
5843
|
function RoomTab(props) {
|
|
5377
5844
|
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,
|
|
5845
|
+
const [registry, setRegistry] = (0, import_react22.useState)([]);
|
|
5846
|
+
const [counts, setCounts] = (0, import_react22.useState)([]);
|
|
5847
|
+
const [orphanCount, setOrphanCount] = (0, import_react22.useState)(0);
|
|
5848
|
+
const [busy, setBusy] = (0, import_react22.useState)(false);
|
|
5849
|
+
const [msg, setMsg] = (0, import_react22.useState)(null);
|
|
5850
|
+
const [error, setError] = (0, import_react22.useState)(null);
|
|
5851
|
+
const [hiPriv, setHiPriv] = (0, import_react22.useState)(false);
|
|
5852
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react22.useState)(false);
|
|
5853
|
+
const [reg, setReg] = (0, import_react22.useState)({ slug: "", label: "", description: "" });
|
|
5854
|
+
const [editing, setEditing] = (0, import_react22.useState)(null);
|
|
5855
|
+
const [renaming, setRenaming] = (0, import_react22.useState)(null);
|
|
5856
|
+
const [expanded, setExpanded] = (0, import_react22.useState)(/* @__PURE__ */ new Set());
|
|
5857
|
+
const [retiredFilter, setRetiredFilter] = (0, import_react22.useState)("");
|
|
5858
|
+
const [filter, setFilter] = (0, import_react22.useState)("");
|
|
5859
|
+
const [records, setRecords] = (0, import_react22.useState)({});
|
|
5860
|
+
const loadAll = (0, import_react22.useCallback)(() => {
|
|
5394
5861
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
5395
5862
|
if (r && r.ok) {
|
|
5396
5863
|
setCounts(r.value.rooms ?? []);
|
|
@@ -5399,13 +5866,13 @@ var __defProp = Object.defineProperty;
|
|
|
5399
5866
|
}
|
|
5400
5867
|
}).catch(() => void 0);
|
|
5401
5868
|
}, [rpc]);
|
|
5402
|
-
const loadHiPriv = (0,
|
|
5869
|
+
const loadHiPriv = (0, import_react22.useCallback)(() => {
|
|
5403
5870
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
5404
5871
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
5405
5872
|
}).catch(() => {
|
|
5406
5873
|
});
|
|
5407
5874
|
}, [rpc]);
|
|
5408
|
-
(0,
|
|
5875
|
+
(0, import_react22.useEffect)(() => {
|
|
5409
5876
|
loadAll();
|
|
5410
5877
|
loadHiPriv();
|
|
5411
5878
|
}, [loadAll, loadHiPriv]);
|
|
@@ -5547,11 +6014,11 @@ var __defProp = Object.defineProperty;
|
|
|
5547
6014
|
const visibleRows = normFilter ? rows.filter(
|
|
5548
6015
|
(row2) => row2.slug.toLowerCase().includes(normFilter) || (row2.entry?.label ?? "").toLowerCase().includes(normFilter) || (row2.entry?.aliases ?? []).some((a) => a.toLowerCase().includes(normFilter))
|
|
5549
6016
|
) : rows;
|
|
5550
|
-
return /* @__PURE__ */ (0,
|
|
5551
|
-
/* @__PURE__ */ (0,
|
|
5552
|
-
/* @__PURE__ */ (0,
|
|
5553
|
-
/* @__PURE__ */ (0,
|
|
5554
|
-
/* @__PURE__ */ (0,
|
|
6017
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
6018
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { ...S.flexRow, marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
6019
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "Room 级管理:存在(注册/收编/退役)· 名称(显示名/说明/改名)· 条目(展开浏览) · 归类到 hall 请到「Hall」页" }),
|
|
6020
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.grow }),
|
|
6021
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { type: "button", style: btn2, title: "导出无 Room 绑定的孤儿清单(含候选)", onClick: () => run(async () => {
|
|
5555
6022
|
const r = await rpc("dsh-memory/rooms-export", { kind: "orphans" });
|
|
5556
6023
|
if (!r.ok) {
|
|
5557
6024
|
setError(r.error.message);
|
|
@@ -5562,7 +6029,7 @@ var __defProp = Object.defineProperty;
|
|
|
5562
6029
|
"导出孤儿 · ",
|
|
5563
6030
|
orphanCount
|
|
5564
6031
|
] }),
|
|
5565
|
-
/* @__PURE__ */ (0,
|
|
6032
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5566
6033
|
"button",
|
|
5567
6034
|
{
|
|
5568
6035
|
type: "button",
|
|
@@ -5573,35 +6040,35 @@ var __defProp = Object.defineProperty;
|
|
|
5573
6040
|
children: hiPriv ? "高权限:开" : "高权限:关"
|
|
5574
6041
|
}
|
|
5575
6042
|
),
|
|
5576
|
-
/* @__PURE__ */ (0,
|
|
6043
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", style: btn2, onClick: loadAll, children: "刷新" })
|
|
5577
6044
|
] }),
|
|
5578
|
-
editing ? /* @__PURE__ */ (0,
|
|
5579
|
-
/* @__PURE__ */ (0,
|
|
6045
|
+
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: [
|
|
6046
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: S.muted, children: [
|
|
5580
6047
|
"编辑 ",
|
|
5581
6048
|
editing.slug
|
|
5582
6049
|
] }),
|
|
5583
|
-
/* @__PURE__ */ (0,
|
|
5584
|
-
/* @__PURE__ */ (0,
|
|
5585
|
-
/* @__PURE__ */ (0,
|
|
5586
|
-
/* @__PURE__ */ (0,
|
|
6050
|
+
/* @__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 } }),
|
|
6051
|
+
/* @__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 } }),
|
|
6052
|
+
/* @__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: "保存" }),
|
|
6053
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, onClick: () => setEditing(null), style: btn2, children: "取消" })
|
|
5587
6054
|
] }) : null,
|
|
5588
|
-
renaming ? /* @__PURE__ */ (0,
|
|
5589
|
-
/* @__PURE__ */ (0,
|
|
6055
|
+
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: [
|
|
6056
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: S.muted, children: [
|
|
5590
6057
|
"改名 ",
|
|
5591
6058
|
renaming.slug,
|
|
5592
6059
|
" →"
|
|
5593
6060
|
] }),
|
|
5594
|
-
/* @__PURE__ */ (0,
|
|
5595
|
-
/* @__PURE__ */ (0,
|
|
5596
|
-
/* @__PURE__ */ (0,
|
|
5597
|
-
/* @__PURE__ */ (0,
|
|
5598
|
-
/* @__PURE__ */ (0,
|
|
6061
|
+
/* @__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 } }),
|
|
6062
|
+
/* @__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: "预览" }),
|
|
6063
|
+
/* @__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: "确认执行" }),
|
|
6064
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, onClick: () => setRenaming(null), style: btn2, children: "取消" }),
|
|
6065
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "记录随迁;与反刍并发会互相覆盖,请在反刍空闲时执行。" })
|
|
5599
6066
|
] }) : null,
|
|
5600
|
-
/* @__PURE__ */ (0,
|
|
5601
|
-
/* @__PURE__ */ (0,
|
|
6067
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
6068
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "退场筛选" }),
|
|
5602
6069
|
[["", "全部"], ["active", "活跃"], ["retired", "已退役"]].map(([val, label]) => {
|
|
5603
6070
|
const on = retiredFilter === val;
|
|
5604
|
-
return /* @__PURE__ */ (0,
|
|
6071
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5605
6072
|
"button",
|
|
5606
6073
|
{
|
|
5607
6074
|
type: "button",
|
|
@@ -5621,8 +6088,8 @@ var __defProp = Object.defineProperty;
|
|
|
5621
6088
|
val
|
|
5622
6089
|
);
|
|
5623
6090
|
}),
|
|
5624
|
-
/* @__PURE__ */ (0,
|
|
5625
|
-
/* @__PURE__ */ (0,
|
|
6091
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.grow }),
|
|
6092
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5626
6093
|
"input",
|
|
5627
6094
|
{
|
|
5628
6095
|
value: filter,
|
|
@@ -5631,24 +6098,24 @@ var __defProp = Object.defineProperty;
|
|
|
5631
6098
|
style: { ...S.input, width: 230, fontSize: 12 }
|
|
5632
6099
|
}
|
|
5633
6100
|
),
|
|
5634
|
-
filter ? /* @__PURE__ */ (0,
|
|
6101
|
+
filter ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", style: btn2, onClick: () => setFilter(""), children: "清除" }) : null
|
|
5635
6102
|
] }),
|
|
5636
|
-
/* @__PURE__ */ (0,
|
|
5637
|
-
/* @__PURE__ */ (0,
|
|
5638
|
-
/* @__PURE__ */ (0,
|
|
5639
|
-
/* @__PURE__ */ (0,
|
|
5640
|
-
/* @__PURE__ */ (0,
|
|
5641
|
-
!hiPriv && /* @__PURE__ */ (0,
|
|
6103
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginBottom: 10 }, children: [
|
|
6104
|
+
/* @__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 } }),
|
|
6105
|
+
/* @__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 } }),
|
|
6106
|
+
/* @__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 } }),
|
|
6107
|
+
/* @__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: "注册" }),
|
|
6108
|
+
!hiPriv && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "管理操作需先开启高权限模式" })
|
|
5642
6109
|
] }),
|
|
5643
|
-
msg ? /* @__PURE__ */ (0,
|
|
5644
|
-
error ? /* @__PURE__ */ (0,
|
|
5645
|
-
visibleRows.length === 0 ? normFilter ? /* @__PURE__ */ (0,
|
|
6110
|
+
msg ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.hint, children: msg }) : null,
|
|
6111
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.error, children: error }) : null,
|
|
6112
|
+
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
6113
|
const e = row2.entry;
|
|
5647
6114
|
const retired = e?.status === "retired";
|
|
5648
6115
|
const grownOnly = !e;
|
|
5649
|
-
return /* @__PURE__ */ (0,
|
|
5650
|
-
/* @__PURE__ */ (0,
|
|
5651
|
-
/* @__PURE__ */ (0,
|
|
6116
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: 6, border: "1px solid var(--dsh-mem-border)", borderRadius: 8 }, children: [
|
|
6117
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "4px 10px" }, children: [
|
|
6118
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5652
6119
|
"button",
|
|
5653
6120
|
{
|
|
5654
6121
|
type: "button",
|
|
@@ -5658,28 +6125,28 @@ var __defProp = Object.defineProperty;
|
|
|
5658
6125
|
children: expanded.has(row2.slug) ? "▾" : "▸"
|
|
5659
6126
|
}
|
|
5660
6127
|
),
|
|
5661
|
-
/* @__PURE__ */ (0,
|
|
5662
|
-
/* @__PURE__ */ (0,
|
|
6128
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { flex: 1, minWidth: 0, display: "flex", flexWrap: "wrap", gap: "2px 8px", alignItems: "baseline" }, children: [
|
|
6129
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontSize: 12, opacity: retired ? 0.6 : 1 }, children: [
|
|
5663
6130
|
row2.slug,
|
|
5664
6131
|
e?.source === "pre-registered" ? " ⭐" : ""
|
|
5665
6132
|
] }),
|
|
5666
|
-
e?.label ? /* @__PURE__ */ (0,
|
|
5667
|
-
/* @__PURE__ */ (0,
|
|
5668
|
-
grownOnly ? /* @__PURE__ */ (0,
|
|
5669
|
-
retired ? /* @__PURE__ */ (0,
|
|
5670
|
-
(e?.aliases ?? []).length > 0 ? /* @__PURE__ */ (0,
|
|
6133
|
+
e?.label ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: e.label }) : null,
|
|
6134
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: row2.count + " 条" }),
|
|
6135
|
+
grownOnly ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "(自生长未注册)" }) : null,
|
|
6136
|
+
retired ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "已退役" }) : null,
|
|
6137
|
+
(e?.aliases ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { ...S.muted, wordBreak: "break-all" }, children: "别名: " + (e?.aliases ?? []).join(", ") }) : null
|
|
5671
6138
|
] }),
|
|
5672
|
-
/* @__PURE__ */ (0,
|
|
5673
|
-
!hiPriv || grownOnly ? null : /* @__PURE__ */ (0,
|
|
5674
|
-
/* @__PURE__ */ (0,
|
|
6139
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", gap: 6, flexShrink: 0, alignItems: "center" }, children: [
|
|
6140
|
+
!hiPriv || grownOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
6141
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, title: "编辑显示名/归类说明", onClick: () => {
|
|
5675
6142
|
setEditing({ slug: row2.slug, label: e?.label ?? "", description: e?.description ?? "" });
|
|
5676
6143
|
setRenaming(null);
|
|
5677
6144
|
}, style: btn2, children: "编辑" }),
|
|
5678
|
-
/* @__PURE__ */ (0,
|
|
6145
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, title: "改名(可两级 slug;记录随迁,旧名进别名)", onClick: () => {
|
|
5679
6146
|
setRenaming({ slug: row2.slug, to: "" });
|
|
5680
6147
|
setEditing(null);
|
|
5681
6148
|
}, style: btn2, children: "改名" }),
|
|
5682
|
-
/* @__PURE__ */ (0,
|
|
6149
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5683
6150
|
"button",
|
|
5684
6151
|
{
|
|
5685
6152
|
type: "button",
|
|
@@ -5690,29 +6157,29 @@ var __defProp = Object.defineProperty;
|
|
|
5690
6157
|
children: retired ? "恢复" : "退役"
|
|
5691
6158
|
}
|
|
5692
6159
|
),
|
|
5693
|
-
!retired ? /* @__PURE__ */ (0,
|
|
6160
|
+
!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
6161
|
] }),
|
|
5695
|
-
grownOnly ? /* @__PURE__ */ (0,
|
|
5696
|
-
/* @__PURE__ */ (0,
|
|
5697
|
-
/* @__PURE__ */ (0,
|
|
6162
|
+
grownOnly ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
6163
|
+
/* @__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: "收编" }),
|
|
6164
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: !hiPriv || busy, title: "退场该 Room 下全部记忆(软删,可在「已退场」区恢复)", onClick: () => {
|
|
5698
6165
|
setRenaming(null);
|
|
5699
6166
|
retire(row2.slug, false, true);
|
|
5700
6167
|
}, style: { ...btn2, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)", opacity: !hiPriv || busy ? 0.5 : 1 }, children: "退场" })
|
|
5701
6168
|
] }) : null,
|
|
5702
|
-
/* @__PURE__ */ (0,
|
|
6169
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", disabled: busy, title: "导出该 Room 的记录清单 CSV", onClick: () => exportRecords(row2.slug), style: btn2, children: "导出" })
|
|
5703
6170
|
] })
|
|
5704
6171
|
] }),
|
|
5705
|
-
expanded.has(row2.slug) ? /* @__PURE__ */ (0,
|
|
5706
|
-
(records[row2.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0,
|
|
5707
|
-
/* @__PURE__ */ (0,
|
|
6172
|
+
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: [
|
|
6173
|
+
(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: [
|
|
6174
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: tagClass(it.type), children: typeLabel(it.type) }),
|
|
5708
6175
|
" ",
|
|
5709
|
-
it.retired ? /* @__PURE__ */ (0,
|
|
6176
|
+
it.retired ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "[已退场]" }) : null,
|
|
5710
6177
|
" ",
|
|
5711
|
-
/* @__PURE__ */ (0,
|
|
5712
|
-
/* @__PURE__ */ (0,
|
|
6178
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: it.updatedAt ? fmtTime(it.updatedAt) : "" }),
|
|
6179
|
+
/* @__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
6180
|
] }, 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,
|
|
6181
|
+
(records[row2.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.muted, children: "该 Room 暂无记忆条目。" }) : null,
|
|
6182
|
+
(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
6183
|
] }) : null
|
|
5717
6184
|
] }, row2.slug);
|
|
5718
6185
|
})
|
|
@@ -5720,13 +6187,13 @@ var __defProp = Object.defineProperty;
|
|
|
5720
6187
|
}
|
|
5721
6188
|
|
|
5722
6189
|
// client/src/tabs/ScenesTab.tsx
|
|
5723
|
-
var
|
|
5724
|
-
var
|
|
6190
|
+
var import_react23 = require("react");
|
|
6191
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
5725
6192
|
function SceneCard(props) {
|
|
5726
6193
|
const s = props.s;
|
|
5727
|
-
const [open, setOpen] = (0,
|
|
5728
|
-
return /* @__PURE__ */ (0,
|
|
5729
|
-
/* @__PURE__ */ (0,
|
|
6194
|
+
const [open, setOpen] = (0, import_react23.useState)(false);
|
|
6195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "dsh-mem-card dsh-mem-card-hover", style: S.card, children: [
|
|
6196
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
5730
6197
|
"div",
|
|
5731
6198
|
{
|
|
5732
6199
|
style: { ...S.sceneHead, cursor: "pointer", userSelect: "none" },
|
|
@@ -5734,23 +6201,23 @@ var __defProp = Object.defineProperty;
|
|
|
5734
6201
|
setOpen(!open);
|
|
5735
6202
|
},
|
|
5736
6203
|
children: [
|
|
5737
|
-
/* @__PURE__ */ (0,
|
|
5738
|
-
/* @__PURE__ */ (0,
|
|
5739
|
-
s.heat ? /* @__PURE__ */ (0,
|
|
5740
|
-
/* @__PURE__ */ (0,
|
|
5741
|
-
/* @__PURE__ */ (0,
|
|
6204
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "dsh-mem-scene-chev", style: { transform: open ? "rotate(90deg)" : "none" }, children: "▸" }),
|
|
6205
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: S.sceneTitle, children: s.path }),
|
|
6206
|
+
s.heat ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: S.muted, children: "热度 " + s.heat }) : null,
|
|
6207
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: S.grow }),
|
|
6208
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: S.muted, children: "更新 " + fmtTime(s.updated) })
|
|
5742
6209
|
]
|
|
5743
6210
|
}
|
|
5744
6211
|
),
|
|
5745
|
-
s.summary ? /* @__PURE__ */ (0,
|
|
5746
|
-
open ? /* @__PURE__ */ (0,
|
|
6212
|
+
s.summary ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { ...S.muted, marginBottom: 6 }, children: s.summary }) : null,
|
|
6213
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { style: S.pre, children: s.content || "(空)" }) : null
|
|
5747
6214
|
] });
|
|
5748
6215
|
}
|
|
5749
6216
|
function ScenesTab(props) {
|
|
5750
6217
|
const rpc = props.rpc;
|
|
5751
|
-
const [items, setItems] = (0,
|
|
5752
|
-
const [error, setError] = (0,
|
|
5753
|
-
const load = (0,
|
|
6218
|
+
const [items, setItems] = (0, import_react23.useState)(null);
|
|
6219
|
+
const [error, setError] = (0, import_react23.useState)(null);
|
|
6220
|
+
const load = (0, import_react23.useCallback)(() => {
|
|
5754
6221
|
rpc("dsh-memory/scenes", {}).then((r) => {
|
|
5755
6222
|
if (r && r.ok) {
|
|
5756
6223
|
setItems(r.value.items);
|
|
@@ -5760,25 +6227,25 @@ var __defProp = Object.defineProperty;
|
|
|
5760
6227
|
setError(String(e && e.message || e));
|
|
5761
6228
|
});
|
|
5762
6229
|
}, [rpc]);
|
|
5763
|
-
(0,
|
|
6230
|
+
(0, import_react23.useEffect)(() => {
|
|
5764
6231
|
load();
|
|
5765
6232
|
}, [load]);
|
|
5766
|
-
return /* @__PURE__ */ (0,
|
|
5767
|
-
/* @__PURE__ */ (0,
|
|
5768
|
-
/* @__PURE__ */ (0,
|
|
5769
|
-
/* @__PURE__ */ (0,
|
|
5770
|
-
/* @__PURE__ */ (0,
|
|
6233
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
|
|
6234
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
6235
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: S.muted, children: items ? items.length + " 个场景块" : "加载中…" }),
|
|
6236
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: S.grow }),
|
|
6237
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
5771
6238
|
] }),
|
|
5772
|
-
error ? /* @__PURE__ */ (0,
|
|
5773
|
-
items && items.length === 0 ? /* @__PURE__ */ (0,
|
|
6239
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: S.error, children: error }) : null,
|
|
6240
|
+
items && items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { style: S.intro, children: "暂无场景块。累计 5 条新记忆后 L2 会自动整合出第一个场景。" }) : null,
|
|
5774
6241
|
(items || []).map((s) => {
|
|
5775
|
-
return /* @__PURE__ */ (0,
|
|
6242
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SceneCard, { s }, s.path);
|
|
5776
6243
|
})
|
|
5777
6244
|
] });
|
|
5778
6245
|
}
|
|
5779
6246
|
|
|
5780
6247
|
// client/src/panel.tsx
|
|
5781
|
-
var
|
|
6248
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
5782
6249
|
var TABS = [
|
|
5783
6250
|
["overview", "概览"],
|
|
5784
6251
|
["records", "记忆"],
|
|
@@ -5799,10 +6266,10 @@ var __defProp = Object.defineProperty;
|
|
|
5799
6266
|
];
|
|
5800
6267
|
function MemoryPanel(props) {
|
|
5801
6268
|
const rpc = props.rpc;
|
|
5802
|
-
const [tab, setTab] = (0,
|
|
5803
|
-
const [skin, setSkinState] = (0,
|
|
6269
|
+
const [tab, setTab] = (0, import_react24.useState)("overview");
|
|
6270
|
+
const [skin, setSkinState] = (0, import_react24.useState)(() => getSkin());
|
|
5804
6271
|
ensureThemeStyle(skin);
|
|
5805
|
-
(0,
|
|
6272
|
+
(0, import_react24.useEffect)(() => {
|
|
5806
6273
|
applySkin(skin);
|
|
5807
6274
|
watchSidebarIcon();
|
|
5808
6275
|
}, [skin]);
|
|
@@ -5811,21 +6278,21 @@ var __defProp = Object.defineProperty;
|
|
|
5811
6278
|
setSkinState(next);
|
|
5812
6279
|
};
|
|
5813
6280
|
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,
|
|
6281
|
+
if (tab === "overview") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(OverviewTab, { rpc });
|
|
6282
|
+
else if (tab === "records") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(RecordsTab, { rpc });
|
|
6283
|
+
else if (tab === "conflicts") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ConflictsTab, { rpc });
|
|
6284
|
+
else if (tab === "scenes") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ScenesTab, { rpc });
|
|
6285
|
+
else if (tab === "rooms") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(RoomsTab, { rpc });
|
|
6286
|
+
else if (tab === "room") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(RoomTab, { rpc });
|
|
6287
|
+
else if (tab === "persona") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PersonaTab, { rpc });
|
|
6288
|
+
else if (tab === "cost") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CostTab, { rpc });
|
|
6289
|
+
else if (tab === "connect") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ConnectTab, { rpc });
|
|
6290
|
+
else if (tab === "skills") body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SkillsTab, { rpc });
|
|
6291
|
+
else body = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LogTab, { rpc });
|
|
6292
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "dsh-mem-root", style: S.section, children: [
|
|
6293
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { style: S.heading, children: "记忆 (Memory)" }),
|
|
6294
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: S.intro, children: "L0~L3 分层蒸馏记忆:浏览被记住的内容,控制记忆模式开关。" }),
|
|
6295
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
5829
6296
|
"div",
|
|
5830
6297
|
{
|
|
5831
6298
|
style: {
|
|
@@ -5837,8 +6304,8 @@ var __defProp = Object.defineProperty;
|
|
|
5837
6304
|
marginBottom: 10
|
|
5838
6305
|
},
|
|
5839
6306
|
children: [
|
|
5840
|
-
/* @__PURE__ */ (0,
|
|
5841
|
-
SKIN_OPTS.map((s) => /* @__PURE__ */ (0,
|
|
6307
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)", marginRight: 4 }, children: "皮肤" }),
|
|
6308
|
+
SKIN_OPTS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5842
6309
|
"button",
|
|
5843
6310
|
{
|
|
5844
6311
|
className: skin === s[0] ? "dsh-mem-tab dsh-mem-tab-on" : "dsh-mem-tab",
|
|
@@ -5851,8 +6318,8 @@ var __defProp = Object.defineProperty;
|
|
|
5851
6318
|
]
|
|
5852
6319
|
}
|
|
5853
6320
|
),
|
|
5854
|
-
/* @__PURE__ */ (0,
|
|
5855
|
-
return /* @__PURE__ */ (0,
|
|
6321
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: S.tabbar, children: TABS.map((t) => {
|
|
6322
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5856
6323
|
"button",
|
|
5857
6324
|
{
|
|
5858
6325
|
className: tab === t[0] ? "dsh-mem-tab dsh-mem-tab-on" : "dsh-mem-tab",
|
|
@@ -5869,7 +6336,7 @@ var __defProp = Object.defineProperty;
|
|
|
5869
6336
|
}
|
|
5870
6337
|
|
|
5871
6338
|
// client/src/pill/MemoryModePill.tsx
|
|
5872
|
-
var
|
|
6339
|
+
var import_react27 = require("react");
|
|
5873
6340
|
|
|
5874
6341
|
// src/util/context-occupancy.ts
|
|
5875
6342
|
var CONTEXT_METER_CIRCUMFERENCE = 34.55751918948772;
|
|
@@ -6185,23 +6652,23 @@ var __defProp = Object.defineProperty;
|
|
|
6185
6652
|
}
|
|
6186
6653
|
|
|
6187
6654
|
// client/src/pill/WingWheel.tsx
|
|
6188
|
-
var
|
|
6655
|
+
var import_react26 = require("react");
|
|
6189
6656
|
|
|
6190
6657
|
// client/src/pill/SessionInfoArea.tsx
|
|
6191
|
-
var
|
|
6192
|
-
var
|
|
6658
|
+
var import_react25 = require("react");
|
|
6659
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
6193
6660
|
function sinfoCell(val, label, title) {
|
|
6194
|
-
return /* @__PURE__ */ (0,
|
|
6195
|
-
/* @__PURE__ */ (0,
|
|
6196
|
-
/* @__PURE__ */ (0,
|
|
6661
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { title: title || void 0, children: [
|
|
6662
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "dsh-mem-sinfo-val", children: val }),
|
|
6663
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "dsh-mem-sinfo-label", children: label })
|
|
6197
6664
|
] });
|
|
6198
6665
|
}
|
|
6199
6666
|
function SessionInfoArea(props) {
|
|
6200
6667
|
const rpc = props.rpc;
|
|
6201
6668
|
const sessionId = props.sessionId;
|
|
6202
|
-
const [stats, setStats] = (0,
|
|
6203
|
-
const busyRef = (0,
|
|
6204
|
-
(0,
|
|
6669
|
+
const [stats, setStats] = (0, import_react25.useState)(void 0);
|
|
6670
|
+
const busyRef = (0, import_react25.useRef)(false);
|
|
6671
|
+
(0, import_react25.useEffect)(() => {
|
|
6205
6672
|
if (!rpc || !sessionId) return void 0;
|
|
6206
6673
|
let alive = true;
|
|
6207
6674
|
let timer = null;
|
|
@@ -6234,7 +6701,7 @@ var __defProp = Object.defineProperty;
|
|
|
6234
6701
|
}, [rpc, sessionId]);
|
|
6235
6702
|
if (stats === null) return null;
|
|
6236
6703
|
if (stats === void 0) {
|
|
6237
|
-
return /* @__PURE__ */ (0,
|
|
6704
|
+
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
6705
|
sinfoCell("…", "召回命中"),
|
|
6239
6706
|
sinfoCell("…", "攒批进度"),
|
|
6240
6707
|
sinfoCell("…", "本会话记忆"),
|
|
@@ -6283,21 +6750,21 @@ var __defProp = Object.defineProperty;
|
|
|
6283
6750
|
else if (stats.retrieval === "none") note = "检索不可用(FTS 与向量均失效)";
|
|
6284
6751
|
}
|
|
6285
6752
|
const ago = fmtAgo(gl.lastExtractAt);
|
|
6286
|
-
return /* @__PURE__ */ (0,
|
|
6287
|
-
warn ? /* @__PURE__ */ (0,
|
|
6288
|
-
/* @__PURE__ */ (0,
|
|
6753
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "dsh-mem-sinfo", children: [
|
|
6754
|
+
warn ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "dsh-mem-sinfo-warn", children: warn }) : null,
|
|
6755
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "dsh-mem-sinfo-grid", children: [
|
|
6289
6756
|
sinfoCell(rcVal, rcLabel, rcTitle),
|
|
6290
6757
|
sinfoCell(dVal, dLabel, dTitle),
|
|
6291
6758
|
sinfoCell(String(di.producedRecords || 0), "本会话记忆", pTitle),
|
|
6292
6759
|
sinfoCell(stats.l0Count != null ? String(stats.l0Count) : "…", "会话消息")
|
|
6293
6760
|
] }),
|
|
6294
|
-
note ? /* @__PURE__ */ (0,
|
|
6295
|
-
/* @__PURE__ */ (0,
|
|
6761
|
+
note ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "dsh-mem-sinfo-note", children: note }) : null,
|
|
6762
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "dsh-mem-sinfo-sum", children: "待蒸馏 " + (gl.pendingTotal || 0) + " · 上次蒸馏 " + (ago || "尚未蒸馏") })
|
|
6296
6763
|
] });
|
|
6297
6764
|
}
|
|
6298
6765
|
|
|
6299
6766
|
// client/src/pill/WingWheel.tsx
|
|
6300
|
-
var
|
|
6767
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
6301
6768
|
var SIZE = 196;
|
|
6302
6769
|
var CENTER = SIZE / 2;
|
|
6303
6770
|
var R = 64;
|
|
@@ -6340,19 +6807,8 @@ var __defProp = Object.defineProperty;
|
|
|
6340
6807
|
function WingWheel(props) {
|
|
6341
6808
|
ensureThemeStyle();
|
|
6342
6809
|
const isOff = props.mode === "off";
|
|
6343
|
-
const [overview, setOverview] = (0,
|
|
6344
|
-
|
|
6345
|
-
const [kwBusy, setKwBusy] = (0, import_react24.useState)(false);
|
|
6346
|
-
const [kwSummary, setKwSummary] = (0, import_react24.useState)(null);
|
|
6347
|
-
const [localError, setLocalError] = (0, import_react24.useState)(null);
|
|
6348
|
-
const timersRef = (0, import_react24.useRef)([]);
|
|
6349
|
-
(0, import_react24.useEffect)(
|
|
6350
|
-
() => () => {
|
|
6351
|
-
for (const t of timersRef.current) window.clearTimeout(t);
|
|
6352
|
-
},
|
|
6353
|
-
[]
|
|
6354
|
-
);
|
|
6355
|
-
(0, import_react24.useEffect)(() => {
|
|
6810
|
+
const [overview, setOverview] = (0, import_react26.useState)(null);
|
|
6811
|
+
(0, import_react26.useEffect)(() => {
|
|
6356
6812
|
let alive = true;
|
|
6357
6813
|
props.rpc("dsh-memory/wing-overview", {}).then((r) => {
|
|
6358
6814
|
if (!alive) return;
|
|
@@ -6368,110 +6824,28 @@ var __defProp = Object.defineProperty;
|
|
|
6368
6824
|
if (id === "general") return overview.general;
|
|
6369
6825
|
return overview.corners.find((c) => c.id === id)?.count ?? 0;
|
|
6370
6826
|
};
|
|
6371
|
-
const
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
const tick = () => {
|
|
6378
|
-
polls++;
|
|
6379
|
-
props.rpc("dsh-memory/wing-overview", {}).then((r) => {
|
|
6380
|
-
const v = r && r.ok ? r.value : null;
|
|
6381
|
-
if (v) setOverview(v);
|
|
6382
|
-
if (v && v.unlabeled === 0 || polls >= 20) finish();
|
|
6383
|
-
else {
|
|
6384
|
-
const t = window.setTimeout(tick, 3e3);
|
|
6385
|
-
timersRef.current.push(t);
|
|
6386
|
-
}
|
|
6387
|
-
}).catch(() => finish());
|
|
6388
|
-
};
|
|
6389
|
-
props.rpc("dsh-memory/wing-backfill", {}).then((r) => {
|
|
6390
|
-
if (!r || !r.ok) {
|
|
6391
|
-
setLocalError(r && r.error ? "回填失败:" + r.error.message : "回填失败");
|
|
6392
|
-
finish();
|
|
6393
|
-
return;
|
|
6394
|
-
}
|
|
6395
|
-
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
6396
|
-
}).catch((e) => {
|
|
6397
|
-
setLocalError("回填失败:" + String(e && e.message || e));
|
|
6398
|
-
finish();
|
|
6399
|
-
});
|
|
6400
|
-
};
|
|
6401
|
-
const keywordBackfill = () => {
|
|
6402
|
-
if (kwBusy) return;
|
|
6403
|
-
setKwBusy(true);
|
|
6404
|
-
setKwSummary(null);
|
|
6405
|
-
setLocalError(null);
|
|
6406
|
-
let polls = 0;
|
|
6407
|
-
const finish = () => setKwBusy(false);
|
|
6408
|
-
const showResult = (v) => {
|
|
6409
|
-
const fail = v.failed ?? 0;
|
|
6410
|
-
setKwSummary(`关键词回填完成:成功 ${v.updated ?? 0} 条${fail > 0 ? `,失败 ${fail} 条` : ""}`);
|
|
6411
|
-
};
|
|
6412
|
-
const failMsg = (m) => {
|
|
6413
|
-
setLocalError(m);
|
|
6414
|
-
finish();
|
|
6415
|
-
};
|
|
6416
|
-
const tick = () => {
|
|
6417
|
-
polls++;
|
|
6418
|
-
props.rpc("dsh-memory/keyword-backfill", {}).then((r) => {
|
|
6419
|
-
const v = r && r.ok ? r.value : null;
|
|
6420
|
-
if (!v) {
|
|
6421
|
-
failMsg("关键词回填失败");
|
|
6422
|
-
return;
|
|
6423
|
-
}
|
|
6424
|
-
if (!v.enabled) {
|
|
6425
|
-
failMsg("关键词回填未开启:请先在设置里打开 keyword.enabled");
|
|
6426
|
-
return;
|
|
6427
|
-
}
|
|
6428
|
-
if (!v.running) {
|
|
6429
|
-
showResult(v);
|
|
6430
|
-
finish();
|
|
6431
|
-
return;
|
|
6432
|
-
}
|
|
6433
|
-
if (polls >= 20) {
|
|
6434
|
-
showResult(v);
|
|
6435
|
-
finish();
|
|
6436
|
-
return;
|
|
6437
|
-
}
|
|
6438
|
-
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
6439
|
-
}).catch(() => failMsg("关键词回填失败"));
|
|
6440
|
-
};
|
|
6441
|
-
props.rpc("dsh-memory/keyword-backfill", {}).then((r) => {
|
|
6442
|
-
if (!r || !r.ok) {
|
|
6443
|
-
failMsg(r && r.error ? "关键词回填失败:" + r.error.message : "关键词回填失败");
|
|
6444
|
-
return;
|
|
6445
|
-
}
|
|
6446
|
-
if (!r.value || !r.value.enabled) {
|
|
6447
|
-
failMsg("关键词回填未开启:请先在设置里打开 keyword.enabled");
|
|
6448
|
-
return;
|
|
6449
|
-
}
|
|
6450
|
-
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
6451
|
-
}).catch((e) => failMsg("关键词回填失败:" + String(e && e.message || e)));
|
|
6452
|
-
};
|
|
6453
|
-
const boxRef = (0, import_react24.useRef)(null);
|
|
6454
|
-
const startRef = (0, import_react24.useRef)(null);
|
|
6455
|
-
const movedRef = (0, import_react24.useRef)(false);
|
|
6456
|
-
const downIndexRef = (0, import_react24.useRef)(null);
|
|
6457
|
-
const dragTargetRef = (0, import_react24.useRef)(null);
|
|
6458
|
-
const [drag, setDrag] = (0, import_react24.useState)(null);
|
|
6827
|
+
const boxRef = (0, import_react26.useRef)(null);
|
|
6828
|
+
const startRef = (0, import_react26.useRef)(null);
|
|
6829
|
+
const movedRef = (0, import_react26.useRef)(false);
|
|
6830
|
+
const downIndexRef = (0, import_react26.useRef)(null);
|
|
6831
|
+
const dragTargetRef = (0, import_react26.useRef)(null);
|
|
6832
|
+
const [drag, setDrag] = (0, import_react26.useState)(null);
|
|
6459
6833
|
const lockedIndex = (() => {
|
|
6460
6834
|
if (props.halls.length !== 1 || !overview) return null;
|
|
6461
6835
|
const i = overview.corners.findIndex((c) => c.id === props.halls[0]);
|
|
6462
6836
|
return i >= 0 ? i : null;
|
|
6463
6837
|
})();
|
|
6464
6838
|
const activeCorner = drag ? drag.index : lockedIndex;
|
|
6465
|
-
const blockPosRef = (0,
|
|
6839
|
+
const blockPosRef = (0, import_react26.useRef)(
|
|
6466
6840
|
activeCorner != null ? cornerXY(activeCorner) : { x: CENTER, y: CENTER }
|
|
6467
6841
|
);
|
|
6468
|
-
const blockTargetRef = (0,
|
|
6469
|
-
const [blockPos, setBlockPos] = (0,
|
|
6470
|
-
(0,
|
|
6842
|
+
const blockTargetRef = (0, import_react26.useRef)(blockPosRef.current);
|
|
6843
|
+
const [blockPos, setBlockPos] = (0, import_react26.useState)(blockPosRef.current);
|
|
6844
|
+
(0, import_react26.useEffect)(() => {
|
|
6471
6845
|
blockTargetRef.current = activeCorner != null ? cornerXY(activeCorner) : { x: CENTER, y: CENTER };
|
|
6472
6846
|
}, [activeCorner]);
|
|
6473
|
-
const reducedMotionRef = (0,
|
|
6474
|
-
(0,
|
|
6847
|
+
const reducedMotionRef = (0, import_react26.useRef)(false);
|
|
6848
|
+
(0, import_react26.useEffect)(() => {
|
|
6475
6849
|
const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
6476
6850
|
const apply2 = () => {
|
|
6477
6851
|
reducedMotionRef.current = mq.matches;
|
|
@@ -6480,7 +6854,7 @@ var __defProp = Object.defineProperty;
|
|
|
6480
6854
|
mq.addEventListener("change", apply2);
|
|
6481
6855
|
return () => mq.removeEventListener("change", apply2);
|
|
6482
6856
|
}, []);
|
|
6483
|
-
(0,
|
|
6857
|
+
(0, import_react26.useEffect)(() => {
|
|
6484
6858
|
let raf = 0;
|
|
6485
6859
|
const loop = () => {
|
|
6486
6860
|
const cur = blockPosRef.current;
|
|
@@ -6569,8 +6943,8 @@ var __defProp = Object.defineProperty;
|
|
|
6569
6943
|
}).join(" ");
|
|
6570
6944
|
const grayStyle = isOff ? { opacity: 0.45, pointerEvents: "none" } : {};
|
|
6571
6945
|
const boundariesDisabled = props.halls.length === 0 || isOff;
|
|
6572
|
-
return /* @__PURE__ */ (0,
|
|
6573
|
-
/* @__PURE__ */ (0,
|
|
6946
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { style: { width: SIZE }, children: [
|
|
6947
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6574
6948
|
"div",
|
|
6575
6949
|
{
|
|
6576
6950
|
ref: boxRef,
|
|
@@ -6580,7 +6954,7 @@ var __defProp = Object.defineProperty;
|
|
|
6580
6954
|
onPointerUp: onBoxUp,
|
|
6581
6955
|
onPointerCancel: onBoxUp,
|
|
6582
6956
|
children: [
|
|
6583
|
-
/* @__PURE__ */ (0,
|
|
6957
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6584
6958
|
"svg",
|
|
6585
6959
|
{
|
|
6586
6960
|
width: SIZE,
|
|
@@ -6588,7 +6962,7 @@ var __defProp = Object.defineProperty;
|
|
|
6588
6962
|
style: { position: "absolute", inset: 0, pointerEvents: "none" },
|
|
6589
6963
|
"aria-hidden": "true",
|
|
6590
6964
|
children: [
|
|
6591
|
-
/* @__PURE__ */ (0,
|
|
6965
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6592
6966
|
"polygon",
|
|
6593
6967
|
{
|
|
6594
6968
|
points: polyPoints,
|
|
@@ -6599,7 +6973,7 @@ var __defProp = Object.defineProperty;
|
|
|
6599
6973
|
opacity: 0.45
|
|
6600
6974
|
}
|
|
6601
6975
|
),
|
|
6602
|
-
/* @__PURE__ */ (0,
|
|
6976
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6603
6977
|
"polygon",
|
|
6604
6978
|
{
|
|
6605
6979
|
points: polyPoints,
|
|
@@ -6610,7 +6984,7 @@ var __defProp = Object.defineProperty;
|
|
|
6610
6984
|
),
|
|
6611
6985
|
[0, 1, 2, 3, 4, 5, 6, 7].map((i) => {
|
|
6612
6986
|
const p = cornerPos(i);
|
|
6613
|
-
return /* @__PURE__ */ (0,
|
|
6987
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6614
6988
|
"line",
|
|
6615
6989
|
{
|
|
6616
6990
|
x1: CENTER,
|
|
@@ -6626,7 +7000,7 @@ var __defProp = Object.defineProperty;
|
|
|
6626
7000
|
]
|
|
6627
7001
|
}
|
|
6628
7002
|
),
|
|
6629
|
-
/* @__PURE__ */ (0,
|
|
7003
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6630
7004
|
"div",
|
|
6631
7005
|
{
|
|
6632
7006
|
"aria-hidden": "true",
|
|
@@ -6645,7 +7019,7 @@ var __defProp = Object.defineProperty;
|
|
|
6645
7019
|
}
|
|
6646
7020
|
}
|
|
6647
7021
|
),
|
|
6648
|
-
/* @__PURE__ */ (0,
|
|
7022
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6649
7023
|
"button",
|
|
6650
7024
|
{
|
|
6651
7025
|
type: "button",
|
|
@@ -6679,7 +7053,7 @@ var __defProp = Object.defineProperty;
|
|
|
6679
7053
|
const dim = activeCorner != null && !active;
|
|
6680
7054
|
const empty = count === 0;
|
|
6681
7055
|
const p = cornerPos(i);
|
|
6682
|
-
return /* @__PURE__ */ (0,
|
|
7056
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6683
7057
|
"div",
|
|
6684
7058
|
{
|
|
6685
7059
|
title: id ? `「${label}」${count ?? 0} 条
|
|
@@ -6708,8 +7082,8 @@ var __defProp = Object.defineProperty;
|
|
|
6708
7082
|
zIndex: 2
|
|
6709
7083
|
},
|
|
6710
7084
|
children: [
|
|
6711
|
-
/* @__PURE__ */ (0,
|
|
6712
|
-
/* @__PURE__ */ (0,
|
|
7085
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: label }),
|
|
7086
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 8, opacity: 0.75, fontVariantNumeric: "tabular-nums" }, children: count === null ? " " : empty ? "空角" : `${count} 条` })
|
|
6713
7087
|
]
|
|
6714
7088
|
},
|
|
6715
7089
|
id ?? i
|
|
@@ -6718,7 +7092,7 @@ var __defProp = Object.defineProperty;
|
|
|
6718
7092
|
]
|
|
6719
7093
|
}
|
|
6720
7094
|
),
|
|
6721
|
-
/* @__PURE__ */ (0,
|
|
7095
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6722
7096
|
"div",
|
|
6723
7097
|
{
|
|
6724
7098
|
title: props.halls.length === 0 ? "选定某个角(单 Wing)后,这两项才生效" : "锁定 Wing 时两类无角记忆是否参与召回",
|
|
@@ -6732,9 +7106,9 @@ var __defProp = Object.defineProperty;
|
|
|
6732
7106
|
pointerEvents: boundariesDisabled ? "none" : void 0
|
|
6733
7107
|
},
|
|
6734
7108
|
children: [
|
|
6735
|
-
/* @__PURE__ */ (0,
|
|
6736
|
-
/* @__PURE__ */ (0,
|
|
6737
|
-
/* @__PURE__ */ (0,
|
|
7109
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: overview ? `另有 ${overview.unlabeled} 条未打标` : "未打标" }),
|
|
7110
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
7111
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6738
7112
|
Segmented,
|
|
6739
7113
|
{
|
|
6740
7114
|
value: props.hallIncludeUnlabeled ? "in" : "ex",
|
|
@@ -6745,7 +7119,7 @@ var __defProp = Object.defineProperty;
|
|
|
6745
7119
|
onChange: (key) => props.onCommitWingBoundaries({ includeUnlabeled: key === "in" })
|
|
6746
7120
|
}
|
|
6747
7121
|
),
|
|
6748
|
-
/* @__PURE__ */ (0,
|
|
7122
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6749
7123
|
Segmented,
|
|
6750
7124
|
{
|
|
6751
7125
|
value: props.hallIncludeGeneral ? "in" : "ex",
|
|
@@ -6760,7 +7134,7 @@ var __defProp = Object.defineProperty;
|
|
|
6760
7134
|
]
|
|
6761
7135
|
}
|
|
6762
7136
|
),
|
|
6763
|
-
/* @__PURE__ */ (0,
|
|
7137
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Row, { label: "会话", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6764
7138
|
Segmented,
|
|
6765
7139
|
{
|
|
6766
7140
|
value: isOff ? "off" : "on",
|
|
@@ -6775,7 +7149,7 @@ var __defProp = Object.defineProperty;
|
|
|
6775
7149
|
onChange: (key) => props.onCommit(key === "off" ? "off" : "auto")
|
|
6776
7150
|
}
|
|
6777
7151
|
) }),
|
|
6778
|
-
props.recall !== void 0 && props.onCommitRecall ? /* @__PURE__ */ (0,
|
|
7152
|
+
props.recall !== void 0 && props.onCommitRecall ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Row, { label: "注入", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6779
7153
|
Segmented,
|
|
6780
7154
|
{
|
|
6781
7155
|
value: props.recall === null ? "follow" : props.recall ? "on" : "off",
|
|
@@ -6788,60 +7162,12 @@ var __defProp = Object.defineProperty;
|
|
|
6788
7162
|
onChange: (key) => props.onCommitRecall(key === "on" ? true : key === "off" ? false : null)
|
|
6789
7163
|
}
|
|
6790
7164
|
) }) : null,
|
|
6791
|
-
/* @__PURE__ */ (0,
|
|
6792
|
-
|
|
6793
|
-
{
|
|
6794
|
-
style: {
|
|
6795
|
-
display: "flex",
|
|
6796
|
-
justifyContent: "space-between",
|
|
6797
|
-
alignItems: "center",
|
|
6798
|
-
gap: 8,
|
|
6799
|
-
marginTop: 10
|
|
6800
|
-
},
|
|
6801
|
-
children: [
|
|
6802
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: overview ? `未打标 ${overview.unlabeled} 条` : "未打标计数加载中" }),
|
|
6803
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6804
|
-
ActionButton,
|
|
6805
|
-
{
|
|
6806
|
-
label: backfillBusy ? "回填中…" : "回填",
|
|
6807
|
-
title: "对存量未打标记忆批量补打 wing 标签",
|
|
6808
|
-
disabled: !overview || overview.unlabeled === 0 || backfillBusy,
|
|
6809
|
-
onClick: () => backfill()
|
|
6810
|
-
}
|
|
6811
|
-
)
|
|
6812
|
-
]
|
|
6813
|
-
}
|
|
6814
|
-
),
|
|
6815
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
6816
|
-
"div",
|
|
6817
|
-
{
|
|
6818
|
-
style: {
|
|
6819
|
-
display: "flex",
|
|
6820
|
-
justifyContent: "space-between",
|
|
6821
|
-
alignItems: "center",
|
|
6822
|
-
gap: 8,
|
|
6823
|
-
marginTop: 10
|
|
6824
|
-
},
|
|
6825
|
-
children: [
|
|
6826
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: kwSummary || "为存量记忆补检索关键词" }),
|
|
6827
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6828
|
-
ActionButton,
|
|
6829
|
-
{
|
|
6830
|
-
label: kwBusy ? "回填中…" : "关键词回填",
|
|
6831
|
-
title: "对缺 dsh_keywords 的存量记忆批量补关键词,喂 FTS 关键词检索轴(需先开 keyword.enabled)",
|
|
6832
|
-
disabled: kwBusy,
|
|
6833
|
-
onClick: () => keywordBackfill()
|
|
6834
|
-
}
|
|
6835
|
-
)
|
|
6836
|
-
]
|
|
6837
|
-
}
|
|
6838
|
-
),
|
|
6839
|
-
props.error || localError ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-danger)", marginTop: 8 }, children: props.error || localError }) : null,
|
|
6840
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SessionInfoArea, { rpc: props.rpc, sessionId: props.sessionId })
|
|
7165
|
+
props.error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-danger)", marginTop: 8 }, children: props.error }) : null,
|
|
7166
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SessionInfoArea, { rpc: props.rpc, sessionId: props.sessionId })
|
|
6841
7167
|
] });
|
|
6842
7168
|
}
|
|
6843
7169
|
function Row(props) {
|
|
6844
|
-
return /* @__PURE__ */ (0,
|
|
7170
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6845
7171
|
"div",
|
|
6846
7172
|
{
|
|
6847
7173
|
style: {
|
|
@@ -6851,7 +7177,7 @@ var __defProp = Object.defineProperty;
|
|
|
6851
7177
|
marginTop: 10
|
|
6852
7178
|
},
|
|
6853
7179
|
children: [
|
|
6854
|
-
/* @__PURE__ */ (0,
|
|
7180
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)" }, children: props.label }),
|
|
6855
7181
|
props.children
|
|
6856
7182
|
]
|
|
6857
7183
|
}
|
|
@@ -6859,9 +7185,9 @@ var __defProp = Object.defineProperty;
|
|
|
6859
7185
|
}
|
|
6860
7186
|
var LABEL_FALLBACK = ["工作", "人际", "学习", "创作娱乐", "居家", "健康", "财务", "出行"];
|
|
6861
7187
|
function useViewportClamp(popRef) {
|
|
6862
|
-
const shiftRef = (0,
|
|
6863
|
-
const [shiftX, setShiftX] = (0,
|
|
6864
|
-
(0,
|
|
7188
|
+
const shiftRef = (0, import_react26.useRef)(0);
|
|
7189
|
+
const [shiftX, setShiftX] = (0, import_react26.useState)(0);
|
|
7190
|
+
(0, import_react26.useEffect)(() => {
|
|
6865
7191
|
const clamp = () => {
|
|
6866
7192
|
const el = popRef.current;
|
|
6867
7193
|
if (!el) return;
|
|
@@ -6891,24 +7217,24 @@ var __defProp = Object.defineProperty;
|
|
|
6891
7217
|
}
|
|
6892
7218
|
|
|
6893
7219
|
// client/src/pill/MemoryModePill.tsx
|
|
6894
|
-
var
|
|
7220
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
6895
7221
|
function MemoryModePill(props) {
|
|
6896
7222
|
const rpc = props.rpc;
|
|
6897
7223
|
const sessionId = props.sessionId || props.session && props.session.sessionId;
|
|
6898
|
-
const [mode, setMode] = (0,
|
|
6899
|
-
const [recall, setRecall] = (0,
|
|
6900
|
-
const [recallResolved, setRecallResolved] = (0,
|
|
6901
|
-
const [halls, setWings] = (0,
|
|
6902
|
-
const [hallIncludeUnlabeled, setWingIncludeUnlabeled] = (0,
|
|
6903
|
-
const [hallIncludeGeneral, setWingIncludeGeneral] = (0,
|
|
6904
|
-
const [wingLabels, setHallLabels] = (0,
|
|
6905
|
-
const [error, setError] = (0,
|
|
6906
|
-
const [open, setOpen] = (0,
|
|
6907
|
-
const wrapRef = (0,
|
|
6908
|
-
const popRef = (0,
|
|
7224
|
+
const [mode, setMode] = (0, import_react27.useState)(null);
|
|
7225
|
+
const [recall, setRecall] = (0, import_react27.useState)(null);
|
|
7226
|
+
const [recallResolved, setRecallResolved] = (0, import_react27.useState)(true);
|
|
7227
|
+
const [halls, setWings] = (0, import_react27.useState)([]);
|
|
7228
|
+
const [hallIncludeUnlabeled, setWingIncludeUnlabeled] = (0, import_react27.useState)(true);
|
|
7229
|
+
const [hallIncludeGeneral, setWingIncludeGeneral] = (0, import_react27.useState)(false);
|
|
7230
|
+
const [wingLabels, setHallLabels] = (0, import_react27.useState)({});
|
|
7231
|
+
const [error, setError] = (0, import_react27.useState)(null);
|
|
7232
|
+
const [open, setOpen] = (0, import_react27.useState)(false);
|
|
7233
|
+
const wrapRef = (0, import_react27.useRef)(null);
|
|
7234
|
+
const popRef = (0, import_react27.useRef)(null);
|
|
6909
7235
|
const shiftX = useViewportClamp(popRef);
|
|
6910
|
-
const seqRef = (0,
|
|
6911
|
-
const load = (0,
|
|
7236
|
+
const seqRef = (0, import_react27.useRef)(0);
|
|
7237
|
+
const load = (0, import_react27.useCallback)(() => {
|
|
6912
7238
|
if (!sessionId || !rpc) return;
|
|
6913
7239
|
const token = ++seqRef.current;
|
|
6914
7240
|
setError(null);
|
|
@@ -6933,13 +7259,13 @@ var __defProp = Object.defineProperty;
|
|
|
6933
7259
|
}).catch(() => {
|
|
6934
7260
|
});
|
|
6935
7261
|
}, [sessionId, rpc]);
|
|
6936
|
-
(0,
|
|
7262
|
+
(0, import_react27.useEffect)(() => {
|
|
6937
7263
|
load();
|
|
6938
7264
|
}, [load]);
|
|
6939
|
-
(0,
|
|
7265
|
+
(0, import_react27.useEffect)(() => {
|
|
6940
7266
|
watchSidebarIcon();
|
|
6941
7267
|
}, []);
|
|
6942
|
-
(0,
|
|
7268
|
+
(0, import_react27.useEffect)(() => {
|
|
6943
7269
|
initOccupancyIndicator(
|
|
6944
7270
|
(endpoint, payload) => rpc(endpoint, payload)
|
|
6945
7271
|
);
|
|
@@ -6947,7 +7273,7 @@ var __defProp = Object.defineProperty;
|
|
|
6947
7273
|
watchContextMeter();
|
|
6948
7274
|
noteOccupancySession(sessionId ?? null);
|
|
6949
7275
|
}, [sessionId, rpc]);
|
|
6950
|
-
(0,
|
|
7276
|
+
(0, import_react27.useEffect)(() => {
|
|
6951
7277
|
if (!open) return;
|
|
6952
7278
|
const onDown = (e) => {
|
|
6953
7279
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -7087,8 +7413,8 @@ var __defProp = Object.defineProperty;
|
|
|
7087
7413
|
pillStyle.boxShadow = "0 0 12px color-mix(in srgb, " + info.color + " 30%, transparent)";
|
|
7088
7414
|
pillStyle["--dsh-mem-pill-tint"] = info.color;
|
|
7089
7415
|
}
|
|
7090
|
-
return /* @__PURE__ */ (0,
|
|
7091
|
-
/* @__PURE__ */ (0,
|
|
7416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { ref: wrapRef, style: { position: "relative", display: "inline-flex" }, children: [
|
|
7417
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
7092
7418
|
"button",
|
|
7093
7419
|
{
|
|
7094
7420
|
type: "button",
|
|
@@ -7101,11 +7427,11 @@ var __defProp = Object.defineProperty;
|
|
|
7101
7427
|
style: pillStyle,
|
|
7102
7428
|
children: [
|
|
7103
7429
|
"记忆 · ",
|
|
7104
|
-
/* @__PURE__ */ (0,
|
|
7430
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: faceLabel })
|
|
7105
7431
|
]
|
|
7106
7432
|
}
|
|
7107
7433
|
),
|
|
7108
|
-
open ? /* @__PURE__ */ (0,
|
|
7434
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
7109
7435
|
"div",
|
|
7110
7436
|
{
|
|
7111
7437
|
ref: popRef,
|
|
@@ -7116,12 +7442,12 @@ var __defProp = Object.defineProperty;
|
|
|
7116
7442
|
transform: "translateX(calc(-50% + " + shiftX + "px))",
|
|
7117
7443
|
zIndex: 1e3
|
|
7118
7444
|
},
|
|
7119
|
-
children: /* @__PURE__ */ (0,
|
|
7445
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
7120
7446
|
"div",
|
|
7121
7447
|
{
|
|
7122
7448
|
className: "dsh-mem-popover",
|
|
7123
7449
|
style: { position: "relative", padding: "10px 12px" },
|
|
7124
|
-
children: /* @__PURE__ */ (0,
|
|
7450
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
7125
7451
|
WingWheel,
|
|
7126
7452
|
{
|
|
7127
7453
|
mode: mode || "auto",
|