dsh-prime-memory 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.js +842 -671
- package/dist/conflict-service.d.ts +27 -10
- package/dist/conflict-service.js +70 -0
- package/dist/contract.d.ts +75 -0
- package/dist/stats.d.ts +1 -1
- package/dist/stats.js +11 -2
- package/dist/tools/index.js +51 -1
- package/package.json +6 -6
package/dist/client.js
CHANGED
|
@@ -25,13 +25,14 @@ var __defProp = Object.defineProperty;
|
|
|
25
25
|
// client/src/entry.tsx
|
|
26
26
|
var entry_exports = {};
|
|
27
27
|
__export(entry_exports, {
|
|
28
|
+
SETTINGS_SEAT: () => SETTINGS_SEAT,
|
|
28
29
|
apply: () => apply,
|
|
29
30
|
inject: () => inject
|
|
30
31
|
});
|
|
31
32
|
module.exports = __toCommonJS(entry_exports);
|
|
32
33
|
|
|
33
34
|
// client/src/panel.tsx
|
|
34
|
-
var
|
|
35
|
+
var import_react17 = require("react");
|
|
35
36
|
|
|
36
37
|
// client/src/sidebar-icon.ts
|
|
37
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>';
|
|
@@ -501,59 +502,46 @@ var __defProp = Object.defineProperty;
|
|
|
501
502
|
document.head.appendChild(el);
|
|
502
503
|
}
|
|
503
504
|
|
|
504
|
-
// client/src/tabs/
|
|
505
|
+
// client/src/tabs/ConflictsTab.tsx
|
|
505
506
|
var import_react2 = require("react");
|
|
506
507
|
|
|
507
|
-
// client/src/
|
|
508
|
-
var
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
508
|
+
// client/src/format.ts
|
|
509
|
+
var TYPE_LABELS = {
|
|
510
|
+
persona: "画像偏好",
|
|
511
|
+
episodic: "客观事件",
|
|
512
|
+
instruction: "全局指令",
|
|
513
|
+
work_fact: "工作事实",
|
|
514
|
+
work_task: "工作任务",
|
|
515
|
+
work_method: "工作方法",
|
|
516
|
+
work_artifact: "工作资产"
|
|
517
|
+
};
|
|
518
|
+
function fmtTime(iso) {
|
|
519
|
+
if (!iso) return "-";
|
|
520
|
+
try {
|
|
521
|
+
return new Date(iso).toLocaleString();
|
|
522
|
+
} catch {
|
|
523
|
+
return String(iso);
|
|
524
|
+
}
|
|
523
525
|
}
|
|
524
|
-
function
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
526
|
+
function fmtAgo(iso) {
|
|
527
|
+
if (!iso) return null;
|
|
528
|
+
try {
|
|
529
|
+
const t = new Date(iso).getTime();
|
|
530
|
+
if (!t) return null;
|
|
531
|
+
let s = Math.floor((Date.now() - t) / 1e3);
|
|
532
|
+
if (s < 0) s = 0;
|
|
533
|
+
if (s < 45) return "刚刚";
|
|
534
|
+
if (s < 3600) return Math.floor(s / 60) + " 分钟前";
|
|
535
|
+
if (s < 86400) return Math.floor(s / 3600) + " 小时前";
|
|
536
|
+
return Math.floor(s / 86400) + " 天前";
|
|
537
|
+
} catch {
|
|
538
|
+
return null;
|
|
539
|
+
}
|
|
532
540
|
}
|
|
533
|
-
function
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
return
|
|
537
|
-
const on = opt.key === value;
|
|
538
|
-
const optDisabled = disabled || !!opt.disabled;
|
|
539
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
540
|
-
"span",
|
|
541
|
-
{
|
|
542
|
-
title: opt.disabledTitle || opt.title || "",
|
|
543
|
-
style: {
|
|
544
|
-
...S.segBtn,
|
|
545
|
-
...on ? S.segBtnOn : null,
|
|
546
|
-
...i === props.options.length - 1 ? { borderRight: "none" } : null,
|
|
547
|
-
...optDisabled ? { cursor: "not-allowed", opacity: 0.45 } : null
|
|
548
|
-
},
|
|
549
|
-
onClick: () => {
|
|
550
|
-
if (!optDisabled && !on && props.onChange) props.onChange(opt.key);
|
|
551
|
-
},
|
|
552
|
-
children: opt.label
|
|
553
|
-
},
|
|
554
|
-
opt.key
|
|
555
|
-
);
|
|
556
|
-
}) });
|
|
541
|
+
function fmtMB(bytes) {
|
|
542
|
+
if (!bytes || bytes <= 0) return "0MB";
|
|
543
|
+
if (bytes < 1024 * 1024) return Math.round(bytes / 1024) + "KB";
|
|
544
|
+
return (bytes / (1024 * 1024)).toFixed(bytes < 100 * 1024 * 1024 ? 1 : 0) + "MB";
|
|
557
545
|
}
|
|
558
546
|
|
|
559
547
|
// client/src/ui/primitives.tsx
|
|
@@ -615,8 +603,201 @@ var __defProp = Object.defineProperty;
|
|
|
615
603
|
);
|
|
616
604
|
}
|
|
617
605
|
|
|
606
|
+
// client/src/tabs/ConflictsTab.tsx
|
|
607
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
608
|
+
var POLL_MS = 1e4;
|
|
609
|
+
var GONE = "(该记录已不在检索库:被合并或删除掉了)";
|
|
610
|
+
function ConflictsTab(props) {
|
|
611
|
+
const rpc = props.rpc;
|
|
612
|
+
const [view, setView] = (0, import_react2.useState)(null);
|
|
613
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
|
614
|
+
const [note, setNote] = (0, import_react2.useState)(null);
|
|
615
|
+
const [busy, setBusy] = (0, import_react2.useState)(null);
|
|
616
|
+
const load = (0, import_react2.useCallback)(() => {
|
|
617
|
+
rpc("dsh-memory/conflicts", {}).then((r) => {
|
|
618
|
+
if (r && r.ok) {
|
|
619
|
+
setView(r.value);
|
|
620
|
+
setError(null);
|
|
621
|
+
} else setError(r && r.error ? r.error.message : "RPC error");
|
|
622
|
+
}).catch((e) => {
|
|
623
|
+
setError(String(e && e.message || e));
|
|
624
|
+
});
|
|
625
|
+
}, [rpc]);
|
|
626
|
+
(0, import_react2.useEffect)(() => {
|
|
627
|
+
load();
|
|
628
|
+
const timer = setInterval(load, POLL_MS);
|
|
629
|
+
return () => {
|
|
630
|
+
clearInterval(timer);
|
|
631
|
+
};
|
|
632
|
+
}, [load]);
|
|
633
|
+
const resolve = (pair, outcome) => {
|
|
634
|
+
const doomed = outcome === "winner" ? pair.loser_content || GONE : outcome === "loser" ? pair.winner_content || GONE : null;
|
|
635
|
+
if (doomed !== null) {
|
|
636
|
+
const ok = window.confirm(
|
|
637
|
+
`裁决这一对?
|
|
638
|
+
|
|
639
|
+
将要退场的记忆:
|
|
640
|
+
「${doomed}」
|
|
641
|
+
|
|
642
|
+
它会从检索库移除(事实源保留,可从 L0 重建找回)。本操作不可覆盖。`
|
|
643
|
+
);
|
|
644
|
+
if (!ok) return;
|
|
645
|
+
}
|
|
646
|
+
setBusy(pair.pair_id);
|
|
647
|
+
setNote(null);
|
|
648
|
+
rpc("dsh-memory/conflict-resolve", { pairId: pair.pair_id, outcome }).then((r) => {
|
|
649
|
+
if (r && r.ok) {
|
|
650
|
+
const v = r.value;
|
|
651
|
+
setNote(v.notice ?? `已裁决 ${v.pair_id}:${v.outcome}${v.removed_record_id ? ",退场 " + v.removed_record_id : ",未移除记录"}`);
|
|
652
|
+
load();
|
|
653
|
+
} else {
|
|
654
|
+
setError(r && r.error ? r.error.message : "裁决失败");
|
|
655
|
+
}
|
|
656
|
+
}).catch((e) => {
|
|
657
|
+
setError(String(e && e.message || e));
|
|
658
|
+
}).finally(() => {
|
|
659
|
+
setBusy(null);
|
|
660
|
+
});
|
|
661
|
+
};
|
|
662
|
+
const items = view?.items ?? [];
|
|
663
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
664
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
665
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: S.muted, children: view === null ? "加载中…" : view.enabled ? `待裁决 ${view.total} 对` : "矛盾冻结未开启" }),
|
|
666
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: S.grow }),
|
|
667
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
668
|
+
] }),
|
|
669
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: S.error, children: error }) : null,
|
|
670
|
+
note ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: S.hint, children: note }) : null,
|
|
671
|
+
view !== null && !view.enabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: S.intro, children: [
|
|
672
|
+
view.notice ?? "矛盾冻结未开启。",
|
|
673
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
674
|
+
"矛盾冻结是**opt-in**:它把裁决权交还给人,代价是冲突会一直停着等你处理。 确认要接手这些裁决,再去「概览」打开它 —— 打开后已停放的队列会立刻显示在这里。"
|
|
675
|
+
] }) : null,
|
|
676
|
+
view !== null && view.enabled && items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: S.intro, children: "没有待裁决的冲突对。新记忆入库时若与旧记忆矛盾且冻结已开启,那一对会停到这里。" }) : null,
|
|
677
|
+
items.map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConflictCard, { pair: p, busy: busy === p.pair_id, onResolve: resolve }, p.pair_id))
|
|
678
|
+
] });
|
|
679
|
+
}
|
|
680
|
+
function ConflictCard(props) {
|
|
681
|
+
const p = props.pair;
|
|
682
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-mem-card", style: S.card, children: [
|
|
683
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: S.cardHead, children: [
|
|
684
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: S.muted, children: "pair " + p.pair_id.slice(0, 12) }),
|
|
685
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: S.muted, children: fmtTime(p.created_at) }),
|
|
686
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: S.grow }),
|
|
687
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: S.muted, title: "产生该冻结的蒸馏批次 id(可用 memory_receipts 追这一轮判了什么)", children: "run " + p.run_id.slice(0, 12) })
|
|
688
|
+
] }),
|
|
689
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
690
|
+
Side,
|
|
691
|
+
{
|
|
692
|
+
label: "LLM 建议:胜方",
|
|
693
|
+
accent: true,
|
|
694
|
+
id: p.winner_id,
|
|
695
|
+
content: p.winner_content
|
|
696
|
+
}
|
|
697
|
+
),
|
|
698
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Side, { label: "LLM 建议:败方", id: p.loser_id, content: p.loser_content }),
|
|
699
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { ...S.flexRow, marginTop: 8 }, children: [
|
|
700
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
701
|
+
NButton,
|
|
702
|
+
{
|
|
703
|
+
disabled: props.busy,
|
|
704
|
+
title: "判 LLM 建议的胜方为真;败方从检索库退场",
|
|
705
|
+
onClick: () => {
|
|
706
|
+
props.onResolve(p, "winner");
|
|
707
|
+
},
|
|
708
|
+
children: props.busy ? "裁决中…" : "判胜方为真"
|
|
709
|
+
}
|
|
710
|
+
),
|
|
711
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
712
|
+
NButton,
|
|
713
|
+
{
|
|
714
|
+
disabled: props.busy,
|
|
715
|
+
title: "判败方为真;胜方从检索库退场",
|
|
716
|
+
onClick: () => {
|
|
717
|
+
props.onResolve(p, "loser");
|
|
718
|
+
},
|
|
719
|
+
children: "判败方为真"
|
|
720
|
+
}
|
|
721
|
+
),
|
|
722
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
723
|
+
NButton,
|
|
724
|
+
{
|
|
725
|
+
disabled: props.busy,
|
|
726
|
+
title: "判两者其实是各自独立的事实(LLM 判错了);两条都保留,不删除",
|
|
727
|
+
onClick: () => {
|
|
728
|
+
props.onResolve(p, "both");
|
|
729
|
+
},
|
|
730
|
+
children: "两者都保留"
|
|
731
|
+
}
|
|
732
|
+
)
|
|
733
|
+
] })
|
|
734
|
+
] });
|
|
735
|
+
}
|
|
736
|
+
function Side(props) {
|
|
737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginTop: 6 }, children: [
|
|
738
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...S.muted, fontWeight: props.accent ? 600 : void 0 }, children: props.label }),
|
|
739
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: S.content, children: props.content || GONE }),
|
|
740
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...S.muted, fontFamily: "ui-monospace, Consolas, monospace" }, children: props.id })
|
|
741
|
+
] });
|
|
742
|
+
}
|
|
743
|
+
|
|
618
744
|
// client/src/tabs/CostTab.tsx
|
|
745
|
+
var import_react3 = require("react");
|
|
746
|
+
|
|
747
|
+
// client/src/ui/controls.tsx
|
|
619
748
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
749
|
+
function Switch(props) {
|
|
750
|
+
const on = !!props.checked;
|
|
751
|
+
const disabled = !!props.disabled;
|
|
752
|
+
const base = { ...S.switch, ...on ? S.switchOn : S.switchOff, ...disabled ? S.switchDisabled : null };
|
|
753
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
754
|
+
"div",
|
|
755
|
+
{
|
|
756
|
+
style: base,
|
|
757
|
+
onClick: () => {
|
|
758
|
+
if (!disabled && props.onChange) props.onChange(!on);
|
|
759
|
+
},
|
|
760
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { ...S.knob, left: on ? 18 : 2 } })
|
|
761
|
+
}
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
function SwitchRow(props) {
|
|
765
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: S.switchRow, children: [
|
|
766
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Switch, { checked: props.checked, disabled: props.disabled, onChange: props.onChange }),
|
|
767
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
768
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: S.switchLabel, children: props.label }),
|
|
769
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: S.switchDesc, children: props.desc || "" })
|
|
770
|
+
] })
|
|
771
|
+
] });
|
|
772
|
+
}
|
|
773
|
+
function Segmented(props) {
|
|
774
|
+
const value = props.value;
|
|
775
|
+
const disabled = !!props.disabled;
|
|
776
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { ...S.seg, ...disabled ? S.switchDisabled : null }, children: props.options.map((opt, i) => {
|
|
777
|
+
const on = opt.key === value;
|
|
778
|
+
const optDisabled = disabled || !!opt.disabled;
|
|
779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
780
|
+
"span",
|
|
781
|
+
{
|
|
782
|
+
title: opt.disabledTitle || opt.title || "",
|
|
783
|
+
style: {
|
|
784
|
+
...S.segBtn,
|
|
785
|
+
...on ? S.segBtnOn : null,
|
|
786
|
+
...i === props.options.length - 1 ? { borderRight: "none" } : null,
|
|
787
|
+
...optDisabled ? { cursor: "not-allowed", opacity: 0.45 } : null
|
|
788
|
+
},
|
|
789
|
+
onClick: () => {
|
|
790
|
+
if (!optDisabled && !on && props.onChange) props.onChange(opt.key);
|
|
791
|
+
},
|
|
792
|
+
children: opt.label
|
|
793
|
+
},
|
|
794
|
+
opt.key
|
|
795
|
+
);
|
|
796
|
+
}) });
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
// client/src/tabs/CostTab.tsx
|
|
800
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
620
801
|
function renderCostChart(buckets, models, maxY, fmtDate, fmtInt, palette) {
|
|
621
802
|
const W = 600;
|
|
622
803
|
const H = 200;
|
|
@@ -631,17 +812,17 @@ var __defProp = Object.defineProperty;
|
|
|
631
812
|
const y = (v) => T + ih - v / maxY * ih;
|
|
632
813
|
const yTicks = [0, maxY / 2, maxY];
|
|
633
814
|
const xIdx = n > 2 ? [0, Math.floor((n - 1) / 2), n - 1] : n === 2 ? [0, 1] : [0];
|
|
634
|
-
return /* @__PURE__ */ (0,
|
|
635
|
-
/* @__PURE__ */ (0,
|
|
815
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { viewBox: "0 0 " + W + " " + H, style: { width: "100%", height: "auto", display: "block" }, children: [
|
|
816
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: L, y1: y(0), x2: W - R, y2: y(0), stroke: "var(--dsh-mem-border)", strokeWidth: 1 }),
|
|
636
817
|
yTicks.map((v) => {
|
|
637
|
-
return /* @__PURE__ */ (0,
|
|
818
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("text", { x: L - 6, y: y(v) + 4, textAnchor: "end", fontSize: 10, fill: "var(--dsh-mem-text-3)", children: fmtInt(v) }, "yt" + v);
|
|
638
819
|
}),
|
|
639
820
|
xIdx.map((i) => {
|
|
640
|
-
return /* @__PURE__ */ (0,
|
|
821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("text", { x: x(i), y: H - 8, textAnchor: "middle", fontSize: 10, fill: "var(--dsh-mem-text-3)", children: fmtDate(buckets[i] ? buckets[i].ts : 0) }, "xt" + i);
|
|
641
822
|
}),
|
|
642
823
|
models.map((m, mi) => {
|
|
643
824
|
const pts = buckets.map((b, i) => x(i) + "," + y(b.byModel[m] || 0)).join(" ");
|
|
644
|
-
return /* @__PURE__ */ (0,
|
|
825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
645
826
|
"polyline",
|
|
646
827
|
{
|
|
647
828
|
points: pts,
|
|
@@ -685,13 +866,13 @@ var __defProp = Object.defineProperty;
|
|
|
685
866
|
var tdStyle = { fontSize: 12.5, color: "var(--dsh-mem-text-1)", textAlign: "right", padding: "4px 10px", fontFamily: "ui-monospace, Consolas, monospace" };
|
|
686
867
|
function CostTab(props) {
|
|
687
868
|
const rpc = props.rpc;
|
|
688
|
-
const [data, setData] = (0,
|
|
689
|
-
const [error, setError] = (0,
|
|
690
|
-
const [granularity, setGranularity] = (0,
|
|
691
|
-
const [layer, setLayer] = (0,
|
|
692
|
-
const [rangeDays, setRangeDays] = (0,
|
|
693
|
-
const [rangeOpen, setRangeOpen] = (0,
|
|
694
|
-
const load = (0,
|
|
869
|
+
const [data, setData] = (0, import_react3.useState)(null);
|
|
870
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
871
|
+
const [granularity, setGranularity] = (0, import_react3.useState)("day");
|
|
872
|
+
const [layer, setLayer] = (0, import_react3.useState)("");
|
|
873
|
+
const [rangeDays, setRangeDays] = (0, import_react3.useState)(0);
|
|
874
|
+
const [rangeOpen, setRangeOpen] = (0, import_react3.useState)(false);
|
|
875
|
+
const load = (0, import_react3.useCallback)(() => {
|
|
695
876
|
setError(null);
|
|
696
877
|
rpc("dsh-memory/token-cost", {
|
|
697
878
|
granularity,
|
|
@@ -703,7 +884,7 @@ var __defProp = Object.defineProperty;
|
|
|
703
884
|
setError(String(e && e.message || e));
|
|
704
885
|
});
|
|
705
886
|
}, [rpc, granularity, rangeDays]);
|
|
706
|
-
(0,
|
|
887
|
+
(0, import_react3.useEffect)(() => {
|
|
707
888
|
load();
|
|
708
889
|
const timer = setInterval(load, 5e3);
|
|
709
890
|
return () => {
|
|
@@ -776,13 +957,13 @@ var __defProp = Object.defineProperty;
|
|
|
776
957
|
});
|
|
777
958
|
const cell = (lc, r, pick) => {
|
|
778
959
|
const w = lc.win[r];
|
|
779
|
-
return /* @__PURE__ */ (0,
|
|
960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: tdStyle, children: w ? fmtInt(pick(w)) : "0" }, r);
|
|
780
961
|
};
|
|
781
|
-
return /* @__PURE__ */ (0,
|
|
782
|
-
/* @__PURE__ */ (0,
|
|
783
|
-
/* @__PURE__ */ (0,
|
|
784
|
-
/* @__PURE__ */ (0,
|
|
785
|
-
/* @__PURE__ */ (0,
|
|
962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
963
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
964
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Segmented, { value: layer, options: LAYER_OPTS, onChange: setLayer }),
|
|
965
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Segmented, { value: granularity, options: GRAN_OPTS, onChange: setGranularity }),
|
|
966
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
786
967
|
NButton,
|
|
787
968
|
{
|
|
788
969
|
onClick: () => {
|
|
@@ -791,12 +972,12 @@ var __defProp = Object.defineProperty;
|
|
|
791
972
|
children: rangeDays > 0 ? "近 " + rangeDays + " 天" : "近N天"
|
|
792
973
|
}
|
|
793
974
|
),
|
|
794
|
-
/* @__PURE__ */ (0,
|
|
795
|
-
/* @__PURE__ */ (0,
|
|
975
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.grow }),
|
|
976
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
796
977
|
] }),
|
|
797
|
-
rangeOpen ? /* @__PURE__ */ (0,
|
|
798
|
-
/* @__PURE__ */ (0,
|
|
799
|
-
/* @__PURE__ */ (0,
|
|
978
|
+
rangeOpen ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
979
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: S.muted, children: "展示近 N 天(正整数,清空=默认窗口;超出保留期后端自动回退)" }),
|
|
980
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
800
981
|
NInput,
|
|
801
982
|
{
|
|
802
983
|
value: rangeDays === 0 ? "" : String(rangeDays),
|
|
@@ -814,100 +995,100 @@ var __defProp = Object.defineProperty;
|
|
|
814
995
|
}
|
|
815
996
|
)
|
|
816
997
|
] }) : null,
|
|
817
|
-
error ? /* @__PURE__ */ (0,
|
|
818
|
-
/* @__PURE__ */ (0,
|
|
819
|
-
buckets.length > 0 ? /* @__PURE__ */ (0,
|
|
998
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.error, children: "成本读取失败:" + error }) : null,
|
|
999
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.panelLabel, children: "成本趋势(按模型)" }),
|
|
1000
|
+
buckets.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
820
1001
|
renderCostChart(buckets, models, maxY, fmtDate, fmtInt, PALETTE),
|
|
821
|
-
/* @__PURE__ */ (0,
|
|
822
|
-
return /* @__PURE__ */ (0,
|
|
1002
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: "4px 12px", margin: "6px 0 14px" }, children: models.map((m, mi) => {
|
|
1003
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
823
1004
|
"span",
|
|
824
1005
|
{
|
|
825
1006
|
style: { display: "inline-flex", alignItems: "center", gap: 4, fontSize: 12, color: "var(--dsh-mem-text-2)" },
|
|
826
1007
|
children: [
|
|
827
|
-
/* @__PURE__ */ (0,
|
|
1008
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { width: 10, height: 10, borderRadius: 4, background: PALETTE[mi % PALETTE.length], display: "inline-block" } }),
|
|
828
1009
|
m
|
|
829
1010
|
]
|
|
830
1011
|
},
|
|
831
1012
|
"lg" + m
|
|
832
1013
|
);
|
|
833
1014
|
}) })
|
|
834
|
-
] }) : /* @__PURE__ */ (0,
|
|
835
|
-
/* @__PURE__ */ (0,
|
|
836
|
-
/* @__PURE__ */ (0,
|
|
837
|
-
/* @__PURE__ */ (0,
|
|
838
|
-
/* @__PURE__ */ (0,
|
|
1015
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: S.muted, children: data ? "暂无成本数据(触发一次蒸馏后这里会出现趋势)。" : "加载中…" }),
|
|
1016
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.panelLabel, children: "层级成本(输出 token)" }),
|
|
1017
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("table", { style: { width: "100%", borderCollapse: "collapse", marginBottom: 14 }, children: [
|
|
1018
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
|
|
1019
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: thFirst, children: "层级" }),
|
|
839
1020
|
RANGES.map((r) => {
|
|
840
|
-
return /* @__PURE__ */ (0,
|
|
1021
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: thStyle, children: RANGE_LABELS[r] }, r);
|
|
841
1022
|
})
|
|
842
1023
|
] }) }),
|
|
843
|
-
/* @__PURE__ */ (0,
|
|
844
|
-
return /* @__PURE__ */ (0,
|
|
845
|
-
/* @__PURE__ */ (0,
|
|
1024
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("tbody", { children: layerTable.map((lc) => {
|
|
1025
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
|
|
1026
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: tdFirst, children: lc.layer.toUpperCase() }),
|
|
846
1027
|
RANGES.map((r) => cell(lc, r, (w) => w.outputTokens))
|
|
847
1028
|
] }, lc.layer);
|
|
848
1029
|
}) })
|
|
849
1030
|
] }),
|
|
850
|
-
/* @__PURE__ */ (0,
|
|
851
|
-
/* @__PURE__ */ (0,
|
|
852
|
-
/* @__PURE__ */ (0,
|
|
853
|
-
/* @__PURE__ */ (0,
|
|
1031
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.panelLabel, children: "层级成本(单次 avg)" }),
|
|
1032
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("table", { style: { width: "100%", borderCollapse: "collapse", marginBottom: 14 }, children: [
|
|
1033
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
|
|
1034
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: thFirst, children: "层级" }),
|
|
854
1035
|
RANGES.map((r) => {
|
|
855
|
-
return /* @__PURE__ */ (0,
|
|
1036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: thStyle, children: RANGE_LABELS[r] + "-avg" }, r);
|
|
856
1037
|
})
|
|
857
1038
|
] }) }),
|
|
858
|
-
/* @__PURE__ */ (0,
|
|
859
|
-
return /* @__PURE__ */ (0,
|
|
860
|
-
/* @__PURE__ */ (0,
|
|
1039
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("tbody", { children: layerTable.map((lc) => {
|
|
1040
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
|
|
1041
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: tdFirst, children: lc.layer.toUpperCase() }),
|
|
861
1042
|
RANGES.map((r) => cell(lc, r, (w) => w.avgOutputTokens))
|
|
862
1043
|
] }, lc.layer);
|
|
863
1044
|
}) })
|
|
864
1045
|
] }),
|
|
865
|
-
/* @__PURE__ */ (0,
|
|
866
|
-
/* @__PURE__ */ (0,
|
|
867
|
-
/* @__PURE__ */ (0,
|
|
868
|
-
/* @__PURE__ */ (0,
|
|
1046
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.panelLabel, children: "层级成本(单次 median)" }),
|
|
1047
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("table", { style: { width: "100%", borderCollapse: "collapse", marginBottom: 14 }, children: [
|
|
1048
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
|
|
1049
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: thFirst, children: "层级" }),
|
|
869
1050
|
RANGES.map((r) => {
|
|
870
|
-
return /* @__PURE__ */ (0,
|
|
1051
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: thStyle, children: RANGE_LABELS[r] + "-median" }, r);
|
|
871
1052
|
})
|
|
872
1053
|
] }) }),
|
|
873
|
-
/* @__PURE__ */ (0,
|
|
874
|
-
return /* @__PURE__ */ (0,
|
|
875
|
-
/* @__PURE__ */ (0,
|
|
1054
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("tbody", { children: layerTable.map((lc) => {
|
|
1055
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
|
|
1056
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: tdFirst, children: lc.layer.toUpperCase() }),
|
|
876
1057
|
RANGES.map((r) => cell(lc, r, (w) => w.medianOutputTokens))
|
|
877
1058
|
] }, lc.layer);
|
|
878
1059
|
}) })
|
|
879
1060
|
] }),
|
|
880
|
-
/* @__PURE__ */ (0,
|
|
881
|
-
/* @__PURE__ */ (0,
|
|
882
|
-
return /* @__PURE__ */ (0,
|
|
883
|
-
/* @__PURE__ */ (0,
|
|
884
|
-
/* @__PURE__ */ (0,
|
|
885
|
-
/* @__PURE__ */ (0,
|
|
1061
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.panelLabel, children: "时间窗口总览" }),
|
|
1062
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.statGrid, children: windows.map((w) => {
|
|
1063
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-mem-card", style: S.statTile, children: [
|
|
1064
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.statNum, children: fmtInt(w.outputTokens + w.reasoningTokens) }),
|
|
1065
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.statLabel, children: RANGE_LABELS[w.range] + " · 总输出 token" }),
|
|
1066
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.muted, children: "文字 " + fmtInt(w.outputTokens) + " · 思考 " + fmtInt(w.reasoningTokens) + " · " + w.calls + " 次调用" })
|
|
886
1067
|
] }, w.range);
|
|
887
1068
|
}) }),
|
|
888
|
-
byModel.length > 0 ? /* @__PURE__ */ (0,
|
|
889
|
-
/* @__PURE__ */ (0,
|
|
1069
|
+
byModel.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
1070
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: S.panelLabel, children: "按模型(累计)" }),
|
|
890
1071
|
byModel.map((m) => {
|
|
891
1072
|
const label = fmtModel(m.provider, m.model);
|
|
892
|
-
return /* @__PURE__ */ (0,
|
|
893
|
-
/* @__PURE__ */ (0,
|
|
894
|
-
/* @__PURE__ */ (0,
|
|
1073
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: S.infoRow, children: [
|
|
1074
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: S.infoKey, children: label }),
|
|
1075
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: S.infoVal, children: m.calls + " 次 · 输出 " + fmtInt(m.outputTokens) + " · 思考 " + fmtInt(m.reasoningTokens) })
|
|
895
1076
|
] }, "m-" + label);
|
|
896
1077
|
})
|
|
897
1078
|
] }) : null,
|
|
898
|
-
data ? /* @__PURE__ */ (0,
|
|
1079
|
+
data ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: S.hint, children: "输入按字符、输出/思考按 token 计;趋势图 Y 轴为输出 token,上方可切换层级与颗粒度。" }) : null
|
|
899
1080
|
] });
|
|
900
1081
|
}
|
|
901
1082
|
|
|
902
1083
|
// client/src/tabs/LogTab.tsx
|
|
903
|
-
var
|
|
904
|
-
var
|
|
1084
|
+
var import_react4 = require("react");
|
|
1085
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
905
1086
|
function LogTab(props) {
|
|
906
1087
|
const rpc = props.rpc;
|
|
907
|
-
const [lines, setLines] = (0,
|
|
908
|
-
const [error, setError] = (0,
|
|
909
|
-
const preRef = (0,
|
|
910
|
-
const load = (0,
|
|
1088
|
+
const [lines, setLines] = (0, import_react4.useState)(null);
|
|
1089
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
1090
|
+
const preRef = (0, import_react4.useRef)(null);
|
|
1091
|
+
const load = (0, import_react4.useCallback)(() => {
|
|
911
1092
|
setError(null);
|
|
912
1093
|
rpc("dsh-memory/log-tail", { lines: 200 }).then((r) => {
|
|
913
1094
|
if (r && r.ok) setLines(r.value.lines);
|
|
@@ -916,63 +1097,24 @@ var __defProp = Object.defineProperty;
|
|
|
916
1097
|
setError(String(e && e.message || e));
|
|
917
1098
|
});
|
|
918
1099
|
}, [rpc]);
|
|
919
|
-
(0,
|
|
1100
|
+
(0, import_react4.useEffect)(() => {
|
|
920
1101
|
load();
|
|
921
1102
|
}, [load]);
|
|
922
|
-
(0,
|
|
1103
|
+
(0, import_react4.useEffect)(() => {
|
|
923
1104
|
if (lines && preRef.current) preRef.current.scrollTop = preRef.current.scrollHeight;
|
|
924
1105
|
}, [lines]);
|
|
925
|
-
return /* @__PURE__ */ (0,
|
|
926
|
-
/* @__PURE__ */ (0,
|
|
927
|
-
/* @__PURE__ */ (0,
|
|
928
|
-
/* @__PURE__ */ (0,
|
|
929
|
-
/* @__PURE__ */ (0,
|
|
1106
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
1107
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
1108
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: S.muted, children: error ? "加载失败" : lines === null ? "加载中…" : "最近 " + lines.length + " 行(memory.log)" }),
|
|
1109
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: S.grow }),
|
|
1110
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
930
1111
|
] }),
|
|
931
|
-
error ? /* @__PURE__ */ (0,
|
|
1112
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { ...S.error, marginBottom: 10 }, children: "日志读取失败:" + error + "(点右上“刷新”重试)" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("pre", { style: S.pre, ref: preRef, children: (lines || []).join("\n") || "(暂无日志)" })
|
|
932
1113
|
] });
|
|
933
1114
|
}
|
|
934
1115
|
|
|
935
1116
|
// client/src/tabs/OverviewTab.tsx
|
|
936
|
-
var
|
|
937
|
-
|
|
938
|
-
// client/src/format.ts
|
|
939
|
-
var TYPE_LABELS = {
|
|
940
|
-
persona: "画像偏好",
|
|
941
|
-
episodic: "客观事件",
|
|
942
|
-
instruction: "全局指令",
|
|
943
|
-
work_fact: "工作事实",
|
|
944
|
-
work_task: "工作任务",
|
|
945
|
-
work_method: "工作方法",
|
|
946
|
-
work_artifact: "工作资产"
|
|
947
|
-
};
|
|
948
|
-
function fmtTime(iso) {
|
|
949
|
-
if (!iso) return "-";
|
|
950
|
-
try {
|
|
951
|
-
return new Date(iso).toLocaleString();
|
|
952
|
-
} catch {
|
|
953
|
-
return String(iso);
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
function fmtAgo(iso) {
|
|
957
|
-
if (!iso) return null;
|
|
958
|
-
try {
|
|
959
|
-
const t = new Date(iso).getTime();
|
|
960
|
-
if (!t) return null;
|
|
961
|
-
let s = Math.floor((Date.now() - t) / 1e3);
|
|
962
|
-
if (s < 0) s = 0;
|
|
963
|
-
if (s < 45) return "刚刚";
|
|
964
|
-
if (s < 3600) return Math.floor(s / 60) + " 分钟前";
|
|
965
|
-
if (s < 86400) return Math.floor(s / 3600) + " 小时前";
|
|
966
|
-
return Math.floor(s / 86400) + " 天前";
|
|
967
|
-
} catch {
|
|
968
|
-
return null;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
function fmtMB(bytes) {
|
|
972
|
-
if (!bytes || bytes <= 0) return "0MB";
|
|
973
|
-
if (bytes < 1024 * 1024) return Math.round(bytes / 1024) + "KB";
|
|
974
|
-
return (bytes / (1024 * 1024)).toFixed(bytes < 100 * 1024 * 1024 ? 1 : 0) + "MB";
|
|
975
|
-
}
|
|
1117
|
+
var import_react13 = require("react");
|
|
976
1118
|
|
|
977
1119
|
// client/src/pill/modes.ts
|
|
978
1120
|
var MODES = [
|
|
@@ -1014,11 +1156,11 @@ var __defProp = Object.defineProperty;
|
|
|
1014
1156
|
}
|
|
1015
1157
|
|
|
1016
1158
|
// client/src/tabs/DistillSettings.tsx
|
|
1017
|
-
var
|
|
1159
|
+
var import_react9 = require("react");
|
|
1018
1160
|
|
|
1019
1161
|
// client/src/tabs/BudgetInputs.tsx
|
|
1020
|
-
var
|
|
1021
|
-
var
|
|
1162
|
+
var import_react5 = require("react");
|
|
1163
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1022
1164
|
var LAYERS = [
|
|
1023
1165
|
["extract", "抽取"],
|
|
1024
1166
|
["dedup", "去重"],
|
|
@@ -1039,7 +1181,7 @@ var __defProp = Object.defineProperty;
|
|
|
1039
1181
|
const onError = props.onError;
|
|
1040
1182
|
const scope = props.scope ?? "all";
|
|
1041
1183
|
const layers = scope === "all" || scope === "input" ? LAYERS : LAYERS.filter((l) => SCOPE_KEYS[scope].includes(l[0]));
|
|
1042
|
-
const [draft, setDraft] = (0,
|
|
1184
|
+
const [draft, setDraft] = (0, import_react5.useState)(null);
|
|
1043
1185
|
if (!data || !data.budgets) return null;
|
|
1044
1186
|
const cur = data.budgets.current || {};
|
|
1045
1187
|
const def = data.budgets.defaults || {};
|
|
@@ -1135,7 +1277,7 @@ var __defProp = Object.defineProperty;
|
|
|
1135
1277
|
return false;
|
|
1136
1278
|
};
|
|
1137
1279
|
const inputBox = (key, _label, title, width, placeholder, onCommit) => {
|
|
1138
|
-
return /* @__PURE__ */ (0,
|
|
1280
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1139
1281
|
NInput,
|
|
1140
1282
|
{
|
|
1141
1283
|
type: "number",
|
|
@@ -1167,9 +1309,9 @@ var __defProp = Object.defineProperty;
|
|
|
1167
1309
|
const effNote = layers.map((l) => eff[l[0]] || "?").join(" / ");
|
|
1168
1310
|
const rowLabel = (key) => key === "extract" ? "抽取输出" : key === "dedup" ? "去重输出" : key === "l2" ? "L2 输出" : "L3 输出";
|
|
1169
1311
|
const rowStyle = { display: "flex", alignItems: "center", gap: 8 };
|
|
1170
|
-
return /* @__PURE__ */ (0,
|
|
1171
|
-
showOutputs ? /* @__PURE__ */ (0,
|
|
1172
|
-
/* @__PURE__ */ (0,
|
|
1312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
1313
|
+
showOutputs ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { marginTop: 12 }, children: [
|
|
1314
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1173
1315
|
"div",
|
|
1174
1316
|
{
|
|
1175
1317
|
style: S.switchLabel,
|
|
@@ -1177,8 +1319,8 @@ var __defProp = Object.defineProperty;
|
|
|
1177
1319
|
children: "输出预算"
|
|
1178
1320
|
}
|
|
1179
1321
|
),
|
|
1180
|
-
/* @__PURE__ */ (0,
|
|
1181
|
-
/* @__PURE__ */ (0,
|
|
1322
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 4 }, children: layers.map((l) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: rowStyle, children: [
|
|
1323
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { width: 68, flexShrink: 0, fontSize: 12, color: "var(--dsh-mem-text-2)" }, children: rowLabel(l[0]) }),
|
|
1182
1324
|
inputBox(
|
|
1183
1325
|
l[0],
|
|
1184
1326
|
l[1],
|
|
@@ -1187,11 +1329,11 @@ var __defProp = Object.defineProperty;
|
|
|
1187
1329
|
def[l[0]],
|
|
1188
1330
|
commitOutputs
|
|
1189
1331
|
),
|
|
1190
|
-
/* @__PURE__ */ (0,
|
|
1332
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: "token" })
|
|
1191
1333
|
] }, l[0])) })
|
|
1192
1334
|
] }) : null,
|
|
1193
|
-
showInput ? /* @__PURE__ */ (0,
|
|
1194
|
-
/* @__PURE__ */ (0,
|
|
1335
|
+
showInput ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { marginTop: 12 }, children: [
|
|
1336
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1195
1337
|
"div",
|
|
1196
1338
|
{
|
|
1197
1339
|
style: S.switchLabel,
|
|
@@ -1199,8 +1341,8 @@ var __defProp = Object.defineProperty;
|
|
|
1199
1341
|
children: "输入预算"
|
|
1200
1342
|
}
|
|
1201
1343
|
),
|
|
1202
|
-
/* @__PURE__ */ (0,
|
|
1203
|
-
/* @__PURE__ */ (0,
|
|
1344
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: rowStyle, children: [
|
|
1345
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { width: 68, flexShrink: 0, fontSize: 12, color: "var(--dsh-mem-text-2)" }, children: "单次输入" }),
|
|
1204
1346
|
inputBox(
|
|
1205
1347
|
"input",
|
|
1206
1348
|
"输入",
|
|
@@ -1209,15 +1351,15 @@ var __defProp = Object.defineProperty;
|
|
|
1209
1351
|
ib.fallback,
|
|
1210
1352
|
commitInput
|
|
1211
1353
|
),
|
|
1212
|
-
/* @__PURE__ */ (0,
|
|
1354
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: "字符" })
|
|
1213
1355
|
] }) })
|
|
1214
1356
|
] }) : null
|
|
1215
1357
|
] });
|
|
1216
1358
|
}
|
|
1217
1359
|
|
|
1218
1360
|
// client/src/tabs/ChannelEditor.tsx
|
|
1219
|
-
var
|
|
1220
|
-
var
|
|
1361
|
+
var import_react6 = require("react");
|
|
1362
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1221
1363
|
var STY = {
|
|
1222
1364
|
block: { marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--dsh-mem-border)" },
|
|
1223
1365
|
head: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", marginBottom: 6 },
|
|
@@ -1248,14 +1390,14 @@ var __defProp = Object.defineProperty;
|
|
|
1248
1390
|
];
|
|
1249
1391
|
function ChannelEditor(props) {
|
|
1250
1392
|
const { channel, rpc, disabled } = props;
|
|
1251
|
-
const [baseText, setBaseText] = (0,
|
|
1252
|
-
const [keyText, setKeyText] = (0,
|
|
1253
|
-
const baseTimer = (0,
|
|
1254
|
-
const dirty = (0,
|
|
1255
|
-
(0,
|
|
1393
|
+
const [baseText, setBaseText] = (0, import_react6.useState)(channel.runtimeBaseURL);
|
|
1394
|
+
const [keyText, setKeyText] = (0, import_react6.useState)("");
|
|
1395
|
+
const baseTimer = (0, import_react6.useRef)(void 0);
|
|
1396
|
+
const dirty = (0, import_react6.useRef)(false);
|
|
1397
|
+
(0, import_react6.useEffect)(() => {
|
|
1256
1398
|
if (!dirty.current) setBaseText(channel.runtimeBaseURL);
|
|
1257
1399
|
}, [channel.runtimeBaseURL]);
|
|
1258
|
-
(0,
|
|
1400
|
+
(0, import_react6.useEffect)(() => () => clearTimeout(baseTimer.current), []);
|
|
1259
1401
|
const commit = (patch) => {
|
|
1260
1402
|
rpc("dsh-memory/settings-set", patch).catch(() => {
|
|
1261
1403
|
});
|
|
@@ -1284,17 +1426,17 @@ var __defProp = Object.defineProperty;
|
|
|
1284
1426
|
const deployedDirect = channel.deployed === "direct";
|
|
1285
1427
|
const apiKeySet = channel.runtimeApiKeySet || channel.deployedApiKeySet;
|
|
1286
1428
|
const showWarn = isDirect && !channel.directReady;
|
|
1287
|
-
return /* @__PURE__ */ (0,
|
|
1288
|
-
/* @__PURE__ */ (0,
|
|
1289
|
-
/* @__PURE__ */ (0,
|
|
1290
|
-
/* @__PURE__ */ (0,
|
|
1291
|
-
/* @__PURE__ */ (0,
|
|
1429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: STY.block, children: [
|
|
1430
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: STY.head, children: [
|
|
1431
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: STY.title, children: "蒸馏通道" }),
|
|
1432
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: isDirect ? STY.chipAccent : STY.chipMuted, children: isDirect ? "直连端点" : "复用宿主" }),
|
|
1433
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { title: "direct = 插件原生直连 OpenAI 兼容端点,与付费 API 解耦;失败自动回退宿主路由链。", style: { marginLeft: "auto", fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: [
|
|
1292
1434
|
"生效:",
|
|
1293
1435
|
runtime ? runtime === "direct" ? "运行时直连" : "运行时宿主" : "跟随部署配置"
|
|
1294
1436
|
] })
|
|
1295
1437
|
] }),
|
|
1296
|
-
/* @__PURE__ */ (0,
|
|
1297
|
-
/* @__PURE__ */ (0,
|
|
1438
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: STY.desc, children: "direct 通道走插件原生 HTTP,不依赖宿主 provider 注册表;direct 失败自动回退宿主路由链作兜底安全网。" }),
|
|
1439
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1298
1440
|
Segmented,
|
|
1299
1441
|
{
|
|
1300
1442
|
value: runtime,
|
|
@@ -1303,10 +1445,10 @@ var __defProp = Object.defineProperty;
|
|
|
1303
1445
|
onChange: (k) => commit({ distillMode: k })
|
|
1304
1446
|
}
|
|
1305
1447
|
),
|
|
1306
|
-
editing ? /* @__PURE__ */ (0,
|
|
1307
|
-
/* @__PURE__ */ (0,
|
|
1308
|
-
/* @__PURE__ */ (0,
|
|
1309
|
-
/* @__PURE__ */ (0,
|
|
1448
|
+
editing ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
|
|
1449
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: STY.fieldRow, children: [
|
|
1450
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: STY.fieldLabel, children: "端点 URL" }),
|
|
1451
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1310
1452
|
NInput,
|
|
1311
1453
|
{
|
|
1312
1454
|
style: STY.input,
|
|
@@ -1323,14 +1465,14 @@ var __defProp = Object.defineProperty;
|
|
|
1323
1465
|
}
|
|
1324
1466
|
}
|
|
1325
1467
|
),
|
|
1326
|
-
deployedDirect && !channel.runtimeBaseURL ? /* @__PURE__ */ (0,
|
|
1468
|
+
deployedDirect && !channel.runtimeBaseURL ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: [
|
|
1327
1469
|
"部署基线:",
|
|
1328
1470
|
channel.deployedBaseURL || "(空)"
|
|
1329
1471
|
] }) : null
|
|
1330
1472
|
] }),
|
|
1331
|
-
/* @__PURE__ */ (0,
|
|
1332
|
-
/* @__PURE__ */ (0,
|
|
1333
|
-
/* @__PURE__ */ (0,
|
|
1473
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: STY.fieldRow, children: [
|
|
1474
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: STY.fieldLabel, children: "API Key" }),
|
|
1475
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1334
1476
|
NInput,
|
|
1335
1477
|
{
|
|
1336
1478
|
style: STY.input,
|
|
@@ -1346,8 +1488,8 @@ var __defProp = Object.defineProperty;
|
|
|
1346
1488
|
onBlur: commitKey
|
|
1347
1489
|
}
|
|
1348
1490
|
),
|
|
1349
|
-
apiKeySet ? /* @__PURE__ */ (0,
|
|
1350
|
-
/* @__PURE__ */ (0,
|
|
1491
|
+
apiKeySet ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: STY.chipAccent, children: "已配置" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: STY.chipMuted, children: "未配置" }),
|
|
1492
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1351
1493
|
NButton,
|
|
1352
1494
|
{
|
|
1353
1495
|
disabled,
|
|
@@ -1357,30 +1499,30 @@ var __defProp = Object.defineProperty;
|
|
|
1357
1499
|
}
|
|
1358
1500
|
)
|
|
1359
1501
|
] }),
|
|
1360
|
-
showWarn ? /* @__PURE__ */ (0,
|
|
1361
|
-
] }) : /* @__PURE__ */ (0,
|
|
1502
|
+
showWarn ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: STY.warn, children: "⚠ direct 未配置完整:需同时有端点 URL 与模型(llm.model / 全局链主路由),否则会回退宿主路由。" }) : null
|
|
1503
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: STY.preview, children: isDirect ? "当前将直连端点:" + (channel.runtimeBaseURL || channel.deployedBaseURL || "(未配置端点)") + (apiKeySet ? " · 密钥已配置" : " · 未配置密钥") : "当前复用宿主 ctx.llm(" + (runtime === "host" ? "运行时锁定" : "跟随部署配置") + ")" })
|
|
1362
1504
|
] });
|
|
1363
1505
|
}
|
|
1364
1506
|
|
|
1365
1507
|
// client/src/tabs/RouteChainEditor.tsx
|
|
1366
|
-
var
|
|
1508
|
+
var import_react8 = require("react");
|
|
1367
1509
|
|
|
1368
1510
|
// client/src/ui/NSel.tsx
|
|
1369
|
-
var
|
|
1370
|
-
var
|
|
1511
|
+
var import_react7 = require("react");
|
|
1512
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1371
1513
|
function NSel(props) {
|
|
1372
1514
|
const options = props.options || [];
|
|
1373
1515
|
const value = props.value || "";
|
|
1374
1516
|
const disabled = !!props.disabled;
|
|
1375
|
-
const [open, setOpen] = (0,
|
|
1376
|
-
const [idx, setIdx] = (0,
|
|
1377
|
-
const wrapRef = (0,
|
|
1378
|
-
const listRef = (0,
|
|
1517
|
+
const [open, setOpen] = (0, import_react7.useState)(false);
|
|
1518
|
+
const [idx, setIdx] = (0, import_react7.useState)(-1);
|
|
1519
|
+
const wrapRef = (0, import_react7.useRef)(null);
|
|
1520
|
+
const listRef = (0, import_react7.useRef)(null);
|
|
1379
1521
|
let selectedLabel = "";
|
|
1380
1522
|
for (let si = 0; si < options.length; si++) {
|
|
1381
1523
|
if (options[si].id === value) selectedLabel = options[si].label;
|
|
1382
1524
|
}
|
|
1383
|
-
(0,
|
|
1525
|
+
(0, import_react7.useEffect)(() => {
|
|
1384
1526
|
if (!open) return void 0;
|
|
1385
1527
|
const onDown = (e) => {
|
|
1386
1528
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -1390,7 +1532,7 @@ var __defProp = Object.defineProperty;
|
|
|
1390
1532
|
document.removeEventListener("mousedown", onDown);
|
|
1391
1533
|
};
|
|
1392
1534
|
}, [open]);
|
|
1393
|
-
(0,
|
|
1535
|
+
(0, import_react7.useEffect)(() => {
|
|
1394
1536
|
if (!open || !listRef.current) return;
|
|
1395
1537
|
const el = listRef.current.querySelector('[data-active="1"]');
|
|
1396
1538
|
if (el && el.scrollIntoView) el.scrollIntoView({ block: "nearest" });
|
|
@@ -1453,8 +1595,8 @@ var __defProp = Object.defineProperty;
|
|
|
1453
1595
|
const to = e.relatedTarget;
|
|
1454
1596
|
if (!to || wrapRef.current && !wrapRef.current.contains(to)) setOpen(false);
|
|
1455
1597
|
};
|
|
1456
|
-
return /* @__PURE__ */ (0,
|
|
1457
|
-
/* @__PURE__ */ (0,
|
|
1598
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-mem-sel", style: props.style, ref: wrapRef, onKeyDown: onKey, onBlur, children: [
|
|
1599
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1458
1600
|
"button",
|
|
1459
1601
|
{
|
|
1460
1602
|
type: "button",
|
|
@@ -1470,13 +1612,13 @@ var __defProp = Object.defineProperty;
|
|
|
1470
1612
|
}
|
|
1471
1613
|
},
|
|
1472
1614
|
children: [
|
|
1473
|
-
/* @__PURE__ */ (0,
|
|
1474
|
-
/* @__PURE__ */ (0,
|
|
1615
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-mem-select-label", children: selectedLabel || props.placeholder || "(请选择)" }),
|
|
1616
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-mem-sel-chev" + (open ? " dsh-mem-sel-chev-open" : ""), "aria-hidden": true })
|
|
1475
1617
|
]
|
|
1476
1618
|
}
|
|
1477
1619
|
),
|
|
1478
|
-
open && !disabled ? /* @__PURE__ */ (0,
|
|
1479
|
-
return /* @__PURE__ */ (0,
|
|
1620
|
+
open && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-mem-pop", ref: listRef, role: "listbox", children: options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-mem-pop-empty", children: "无选项" }) : options.map((o, i) => {
|
|
1621
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1480
1622
|
"button",
|
|
1481
1623
|
{
|
|
1482
1624
|
type: "button",
|
|
@@ -1494,8 +1636,8 @@ var __defProp = Object.defineProperty;
|
|
|
1494
1636
|
if (idx !== i) setIdx(i);
|
|
1495
1637
|
},
|
|
1496
1638
|
children: [
|
|
1497
|
-
/* @__PURE__ */ (0,
|
|
1498
|
-
o.id === value ? /* @__PURE__ */ (0,
|
|
1639
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-mem-pop-opt-label", children: o.label }),
|
|
1640
|
+
o.id === value ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-mem-pop-check", children: "✓" }) : null
|
|
1499
1641
|
]
|
|
1500
1642
|
},
|
|
1501
1643
|
o.id
|
|
@@ -1505,7 +1647,7 @@ var __defProp = Object.defineProperty;
|
|
|
1505
1647
|
}
|
|
1506
1648
|
|
|
1507
1649
|
// client/src/tabs/RouteChainEditor.tsx
|
|
1508
|
-
var
|
|
1650
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1509
1651
|
var modelsCache = {};
|
|
1510
1652
|
var EFFORT_VOCAB = ["", "off", "none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
1511
1653
|
var STY2 = {
|
|
@@ -1534,26 +1676,26 @@ var __defProp = Object.defineProperty;
|
|
|
1534
1676
|
const disabled = !!props.disabled;
|
|
1535
1677
|
const scope = props.scope ?? "global";
|
|
1536
1678
|
const isLayer = scope !== "global";
|
|
1537
|
-
const [info, setInfo] = (0,
|
|
1538
|
-
const [rows, setRows] = (0,
|
|
1539
|
-
const [rowErrs, setRowErrs] = (0,
|
|
1540
|
-
const [err, setErr] = (0,
|
|
1541
|
-
const [manual, setManual] = (0,
|
|
1542
|
-
const pendingWrites = (0,
|
|
1679
|
+
const [info, setInfo] = (0, import_react8.useState)(null);
|
|
1680
|
+
const [rows, setRows] = (0, import_react8.useState)(null);
|
|
1681
|
+
const [rowErrs, setRowErrs] = (0, import_react8.useState)({});
|
|
1682
|
+
const [err, setErr] = (0, import_react8.useState)(null);
|
|
1683
|
+
const [manual, setManual] = (0, import_react8.useState)({ idx: -1, text: "" });
|
|
1684
|
+
const pendingWrites = (0, import_react8.useRef)(0);
|
|
1543
1685
|
function refreshInfo() {
|
|
1544
1686
|
rpc("dsh-memory/llm-providers", {}).then((r) => {
|
|
1545
1687
|
if (r && r.ok && pendingWrites.current === 0) setInfo(r.value);
|
|
1546
1688
|
}).catch(() => {
|
|
1547
1689
|
});
|
|
1548
1690
|
}
|
|
1549
|
-
(0,
|
|
1691
|
+
(0, import_react8.useEffect)(() => {
|
|
1550
1692
|
refreshInfo();
|
|
1551
1693
|
const timer = setInterval(refreshInfo, 5e3);
|
|
1552
1694
|
return () => {
|
|
1553
1695
|
clearInterval(timer);
|
|
1554
1696
|
};
|
|
1555
1697
|
}, [rpc]);
|
|
1556
|
-
(0,
|
|
1698
|
+
(0, import_react8.useEffect)(() => {
|
|
1557
1699
|
if (!info || !info.providers) return;
|
|
1558
1700
|
info.providers.forEach((p) => {
|
|
1559
1701
|
if (!p.id || modelsCache[p.id]) return;
|
|
@@ -1565,7 +1707,7 @@ var __defProp = Object.defineProperty;
|
|
|
1565
1707
|
}, [rpc, info]);
|
|
1566
1708
|
const layerView = isLayer && info && info.layerChains ? info.layerChains[scope] : null;
|
|
1567
1709
|
const savedRows = isLayer ? layerView?.runtime ?? [] : info && info.chain ? info.chain.current : [];
|
|
1568
|
-
(0,
|
|
1710
|
+
(0, import_react8.useEffect)(() => {
|
|
1569
1711
|
if (rows === null && info && savedRows.length) {
|
|
1570
1712
|
setRows(savedRows.map(copyRow));
|
|
1571
1713
|
}
|
|
@@ -1713,17 +1855,17 @@ var __defProp = Object.defineProperty;
|
|
|
1713
1855
|
providersById[p.id] = p;
|
|
1714
1856
|
});
|
|
1715
1857
|
function roRow(e, i) {
|
|
1716
|
-
return /* @__PURE__ */ (0,
|
|
1717
|
-
/* @__PURE__ */ (0,
|
|
1718
|
-
/* @__PURE__ */ (0,
|
|
1719
|
-
/* @__PURE__ */ (0,
|
|
1858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: STY2.roRow, children: [
|
|
1859
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: STY2.badge, children: i === 0 ? "主" : String(i + 1) }),
|
|
1860
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { ...STY2.mono, color: "var(--dsh-mem-text-2)" }, children: e.provider + " / " + e.model }),
|
|
1861
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { marginLeft: "auto", flexShrink: 0, fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: e.effort ? "档位 " + e.effort : "跟随部署配置" })
|
|
1720
1862
|
] }, "ro" + i);
|
|
1721
1863
|
}
|
|
1722
1864
|
if (info.pinned) {
|
|
1723
1865
|
const effPin = isLayer ? layerView?.effectiveChain ?? [] : info.chain && info.chain.effectiveChain || [];
|
|
1724
|
-
return /* @__PURE__ */ (0,
|
|
1866
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: STY2.wrap, children: [
|
|
1725
1867
|
effPin.map(roRow),
|
|
1726
|
-
/* @__PURE__ */ (0,
|
|
1868
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: STY2.note, children: "部署已锁定路由(pin),调整请修改 cordis.patch.yml 中 llm 的配置。" })
|
|
1727
1869
|
] });
|
|
1728
1870
|
}
|
|
1729
1871
|
if (rows === null) {
|
|
@@ -1731,21 +1873,21 @@ var __defProp = Object.defineProperty;
|
|
|
1731
1873
|
const lv = layerView;
|
|
1732
1874
|
const src = lv?.source ?? "global";
|
|
1733
1875
|
if (src === "static" && lv) {
|
|
1734
|
-
return /* @__PURE__ */ (0,
|
|
1876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: STY2.wrap, children: [
|
|
1735
1877
|
lv.static.map((e, i) => roRow({ provider: e.provider, model: e.model, effort: e.reasoningEffort || "" }, i)),
|
|
1736
|
-
/* @__PURE__ */ (0,
|
|
1878
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NButton, { onClick: forkStatic, disabled, children: "自定义本层链" }) })
|
|
1737
1879
|
] });
|
|
1738
1880
|
}
|
|
1739
1881
|
const previewRows = lv?.effectiveChain ?? [];
|
|
1740
|
-
return /* @__PURE__ */ (0,
|
|
1741
|
-
previewRows.length === 0 ? /* @__PURE__ */ (0,
|
|
1742
|
-
/* @__PURE__ */ (0,
|
|
1882
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: STY2.wrap, children: [
|
|
1883
|
+
previewRows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: S.switchDesc, children: "本层跟随全局链,暂无可用路由。" }) : previewRows.map(roRow),
|
|
1884
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NButton, { onClick: forkStatic, disabled, children: "自定义本层链" }) })
|
|
1743
1885
|
] });
|
|
1744
1886
|
}
|
|
1745
1887
|
const effFollow = info.chain && info.chain.effectiveChain || [];
|
|
1746
|
-
return /* @__PURE__ */ (0,
|
|
1747
|
-
effFollow.length === 0 ? /* @__PURE__ */ (0,
|
|
1748
|
-
/* @__PURE__ */ (0,
|
|
1888
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: STY2.wrap, children: [
|
|
1889
|
+
effFollow.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: S.switchDesc, children: "蒸馏跟随默认模型,未配置回退链。" }) : effFollow.map(roRow),
|
|
1890
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NButton, { onClick: forkStatic, disabled, children: "编辑为运行时链" }) })
|
|
1749
1891
|
] });
|
|
1750
1892
|
}
|
|
1751
1893
|
const capped = rows.length >= 8;
|
|
@@ -1786,10 +1928,10 @@ var __defProp = Object.defineProperty;
|
|
|
1786
1928
|
const effortOptions = [{ id: "", label: "跟随部署配置" }].concat(
|
|
1787
1929
|
curEfforts.filter((k) => EFFORT_VOCAB.indexOf(k) >= 0).map((k) => ({ id: k, label: k }))
|
|
1788
1930
|
);
|
|
1789
|
-
return /* @__PURE__ */ (0,
|
|
1790
|
-
/* @__PURE__ */ (0,
|
|
1791
|
-
/* @__PURE__ */ (0,
|
|
1792
|
-
/* @__PURE__ */ (0,
|
|
1931
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { ...STY2.row, ...rowErrs[i] ? STY2.rowErr : null }, children: [
|
|
1932
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: STY2.line, children: [
|
|
1933
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: STY2.badge, children: isPrimary ? "主" : String(i + 1) }),
|
|
1934
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1793
1935
|
NSel,
|
|
1794
1936
|
{
|
|
1795
1937
|
style: { flex: 1, minWidth: 150 },
|
|
@@ -1802,7 +1944,7 @@ var __defProp = Object.defineProperty;
|
|
|
1802
1944
|
}
|
|
1803
1945
|
}
|
|
1804
1946
|
),
|
|
1805
|
-
!row2.provider ? null : manualInput ? /* @__PURE__ */ (0,
|
|
1947
|
+
!row2.provider ? null : manualInput ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1806
1948
|
NInput,
|
|
1807
1949
|
{
|
|
1808
1950
|
style: { flex: 1, minWidth: 150 },
|
|
@@ -1821,7 +1963,7 @@ var __defProp = Object.defineProperty;
|
|
|
1821
1963
|
}
|
|
1822
1964
|
}
|
|
1823
1965
|
}
|
|
1824
|
-
) : /* @__PURE__ */ (0,
|
|
1966
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1825
1967
|
NSel,
|
|
1826
1968
|
{
|
|
1827
1969
|
style: { flex: 1, minWidth: 150 },
|
|
@@ -1834,7 +1976,7 @@ var __defProp = Object.defineProperty;
|
|
|
1834
1976
|
}
|
|
1835
1977
|
}
|
|
1836
1978
|
),
|
|
1837
|
-
/* @__PURE__ */ (0,
|
|
1979
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1838
1980
|
NSel,
|
|
1839
1981
|
{
|
|
1840
1982
|
style: { flexShrink: 0, width: 118 },
|
|
@@ -1848,8 +1990,8 @@ var __defProp = Object.defineProperty;
|
|
|
1848
1990
|
}
|
|
1849
1991
|
)
|
|
1850
1992
|
] }),
|
|
1851
|
-
/* @__PURE__ */ (0,
|
|
1852
|
-
/* @__PURE__ */ (0,
|
|
1993
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: STY2.actions, children: [
|
|
1994
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1853
1995
|
NButton,
|
|
1854
1996
|
{
|
|
1855
1997
|
style: STY2.ico,
|
|
@@ -1861,7 +2003,7 @@ var __defProp = Object.defineProperty;
|
|
|
1861
2003
|
children: "↑"
|
|
1862
2004
|
}
|
|
1863
2005
|
),
|
|
1864
|
-
/* @__PURE__ */ (0,
|
|
2006
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1865
2007
|
NButton,
|
|
1866
2008
|
{
|
|
1867
2009
|
style: STY2.ico,
|
|
@@ -1873,7 +2015,7 @@ var __defProp = Object.defineProperty;
|
|
|
1873
2015
|
children: "↓"
|
|
1874
2016
|
}
|
|
1875
2017
|
),
|
|
1876
|
-
/* @__PURE__ */ (0,
|
|
2018
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1877
2019
|
NButton,
|
|
1878
2020
|
{
|
|
1879
2021
|
style: STY2.ico,
|
|
@@ -1886,14 +2028,14 @@ var __defProp = Object.defineProperty;
|
|
|
1886
2028
|
}
|
|
1887
2029
|
)
|
|
1888
2030
|
] }),
|
|
1889
|
-
isPrimary && !row2.provider ? /* @__PURE__ */ (0,
|
|
1890
|
-
!known ? /* @__PURE__ */ (0,
|
|
1891
|
-
rowErrs[i] ? /* @__PURE__ */ (0,
|
|
2031
|
+
isPrimary && !row2.provider ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: STY2.note, children: "跟随默认模型" + (info.default ? ":" + info.default.provider + " / " + info.default.model : "") + "(档位跟随部署配置,选定模型后可单独设置)" }) : null,
|
|
2032
|
+
!known ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: STY2.warn, children: "⚠ 供应商 " + row2.provider + " 已不在已注册路由中:该路由调用会失败并被链跳过(不阻止保存)。" }) : null,
|
|
2033
|
+
rowErrs[i] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: STY2.warn, children: "✕ " + rowErrs[i] }) : null
|
|
1892
2034
|
] }, "row" + i);
|
|
1893
2035
|
});
|
|
1894
2036
|
const effChain = isLayer ? layerView?.effectiveChain ?? [] : info.chain && info.chain.effectiveChain || [];
|
|
1895
|
-
return /* @__PURE__ */ (0,
|
|
1896
|
-
/* @__PURE__ */ (0,
|
|
2037
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: STY2.wrap, children: [
|
|
2038
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1897
2039
|
"div",
|
|
1898
2040
|
{
|
|
1899
2041
|
style: { ...S.switchDesc, marginBottom: 8 },
|
|
@@ -1902,9 +2044,9 @@ var __defProp = Object.defineProperty;
|
|
|
1902
2044
|
}
|
|
1903
2045
|
),
|
|
1904
2046
|
rowEls,
|
|
1905
|
-
/* @__PURE__ */ (0,
|
|
1906
|
-
/* @__PURE__ */ (0,
|
|
1907
|
-
/* @__PURE__ */ (0,
|
|
2047
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NButton, { style: STY2.add, disabled: disabled || capped, onClick: addRow, children: capped ? "已达上限(8 条)" : "+ 添加回退路由" }),
|
|
2048
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 10 }, children: [
|
|
2049
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1908
2050
|
NButton,
|
|
1909
2051
|
{
|
|
1910
2052
|
style: isLayer ? { ...STY2.ghost, color: "var(--dsh-mem-danger)", border: "1px solid var(--dsh-mem-danger)" } : STY2.ghost,
|
|
@@ -1913,13 +2055,13 @@ var __defProp = Object.defineProperty;
|
|
|
1913
2055
|
children: isLayer ? "清除自定义 · 跟随全局" : "清空并跟随部署配置"
|
|
1914
2056
|
}
|
|
1915
2057
|
),
|
|
1916
|
-
/* @__PURE__ */ (0,
|
|
1917
|
-
/* @__PURE__ */ (0,
|
|
2058
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: S.grow }),
|
|
2059
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NButton, { variant: "primary", disabled, onClick: save, children: "保存" })
|
|
1918
2060
|
] }),
|
|
1919
|
-
err ? /* @__PURE__ */ (0,
|
|
1920
|
-
/* @__PURE__ */ (0,
|
|
1921
|
-
/* @__PURE__ */ (0,
|
|
1922
|
-
/* @__PURE__ */ (0,
|
|
2061
|
+
err ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { ...STY2.warn, marginTop: 8 }, children: "✕ " + err }) : null,
|
|
2062
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--dsh-mem-border)" }, children: [
|
|
2063
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)", marginBottom: 4 }, children: "实际链" + (dirty ? "(保存后更新;当前显示已保存值)" : "") }),
|
|
2064
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1923
2065
|
"div",
|
|
1924
2066
|
{
|
|
1925
2067
|
style: { fontSize: 12, color: "var(--dsh-mem-text-2)", wordBreak: "break-all", fontFamily: "ui-monospace, SFMono-Regular, Consolas, monospace" },
|
|
@@ -1931,7 +2073,7 @@ var __defProp = Object.defineProperty;
|
|
|
1931
2073
|
}
|
|
1932
2074
|
|
|
1933
2075
|
// client/src/tabs/DistillSettings.tsx
|
|
1934
|
-
var
|
|
2076
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1935
2077
|
var STY3 = {
|
|
1936
2078
|
hint: { fontSize: 11, color: "var(--dsh-mem-text-3)", margin: "0 0 8px" },
|
|
1937
2079
|
panelHead: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", marginBottom: 8 },
|
|
@@ -1960,9 +2102,9 @@ var __defProp = Object.defineProperty;
|
|
|
1960
2102
|
verticalAlign: "middle",
|
|
1961
2103
|
flexShrink: 0
|
|
1962
2104
|
};
|
|
1963
|
-
if (props.kind === "runtime") return /* @__PURE__ */ (0,
|
|
1964
|
-
if (props.kind === "static") return /* @__PURE__ */ (0,
|
|
1965
|
-
return /* @__PURE__ */ (0,
|
|
2105
|
+
if (props.kind === "runtime") return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { ...base, background: "var(--dsh-mem-accent)" } });
|
|
2106
|
+
if (props.kind === "static") return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { ...base, background: "transparent", border: "1.5px solid var(--dsh-mem-text-3)" } });
|
|
2107
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { ...base, background: "var(--dsh-mem-track)" } });
|
|
1966
2108
|
}
|
|
1967
2109
|
var LAYER_META = {
|
|
1968
2110
|
l1: { seg: "L1", title: "L1 · 抽取 / 去重" },
|
|
@@ -1972,9 +2114,9 @@ var __defProp = Object.defineProperty;
|
|
|
1972
2114
|
function DistillSettings(props) {
|
|
1973
2115
|
const rpc = props.rpc;
|
|
1974
2116
|
const disabled = !!props.disabled;
|
|
1975
|
-
const [info, setInfo] = (0,
|
|
1976
|
-
const [tab, setTab] = (0,
|
|
1977
|
-
(0,
|
|
2117
|
+
const [info, setInfo] = (0, import_react9.useState)(null);
|
|
2118
|
+
const [tab, setTab] = (0, import_react9.useState)("g");
|
|
2119
|
+
(0, import_react9.useEffect)(() => {
|
|
1978
2120
|
let alive = true;
|
|
1979
2121
|
const refresh = () => {
|
|
1980
2122
|
rpc("dsh-memory/llm-providers", {}).then((r) => {
|
|
@@ -1997,46 +2139,67 @@ var __defProp = Object.defineProperty;
|
|
|
1997
2139
|
...["l1", "l2", "l3"].map((k) => ({
|
|
1998
2140
|
key: k,
|
|
1999
2141
|
title: LAYER_META[k].title + " · " + (dotOf(k) === "runtime" ? "运行时自定义" : dotOf(k) === "static" ? "部署 YAML 层链(只读)" : "跟随全局"),
|
|
2000
|
-
label: /* @__PURE__ */ (0,
|
|
2001
|
-
/* @__PURE__ */ (0,
|
|
2142
|
+
label: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
2143
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Dot, { kind: dotOf(k) }),
|
|
2002
2144
|
LAYER_META[k].seg
|
|
2003
2145
|
] })
|
|
2004
2146
|
}))
|
|
2005
2147
|
];
|
|
2006
2148
|
const chipTitle = (k) => dotOf(k) === "runtime" ? "本层走设置页自定义链" : dotOf(k) === "static" ? "本层走部署 YAML 层链(UI 只读,自定义可覆盖)" : "本层未单独配置,走全局默认链";
|
|
2007
|
-
return /* @__PURE__ */ (0,
|
|
2008
|
-
/* @__PURE__ */ (0,
|
|
2009
|
-
/* @__PURE__ */ (0,
|
|
2010
|
-
/* @__PURE__ */ (0,
|
|
2149
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
2150
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Segmented, { value: tab, options: segOptions, onChange: (k) => setTab(k) }),
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: STY3.hint, children: [
|
|
2152
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Dot, { kind: "runtime" }),
|
|
2011
2153
|
" 自定义 · ",
|
|
2012
|
-
/* @__PURE__ */ (0,
|
|
2154
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Dot, { kind: "static" }),
|
|
2013
2155
|
" 部署 YAML · ",
|
|
2014
|
-
/* @__PURE__ */ (0,
|
|
2156
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Dot, { kind: "global" }),
|
|
2015
2157
|
" 跟随全局",
|
|
2016
|
-
/* @__PURE__ */ (0,
|
|
2158
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { title: "每层实际链:运行时自定义 → 部署 YAML 层链 → 全局默认链,逐级兜底;部署 pin 时运行时编辑只读", children: "(层链优先于全局)" })
|
|
2017
2159
|
] }),
|
|
2018
|
-
tab === "g" ? /* @__PURE__ */ (0,
|
|
2019
|
-
/* @__PURE__ */ (0,
|
|
2020
|
-
/* @__PURE__ */ (0,
|
|
2021
|
-
/* @__PURE__ */ (0,
|
|
2022
|
-
/* @__PURE__ */ (0,
|
|
2160
|
+
tab === "g" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
2161
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: STY3.panelHead, children: [
|
|
2162
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY3.panelTitle, children: "全局默认链" }),
|
|
2163
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { ...STY3.chip, ...STY3.chipAccent }, children: "运行时 · 可编辑" }),
|
|
2164
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { ...STY3.inUse, marginLeft: "auto" }, children: users.length ? "在用:" + users.map((k) => LAYER_META[k].seg).join("、") : "当前无层使用" })
|
|
2023
2165
|
] }),
|
|
2024
|
-
/* @__PURE__ */ (0,
|
|
2025
|
-
/* @__PURE__ */ (0,
|
|
2026
|
-
info?.channel ? /* @__PURE__ */ (0,
|
|
2027
|
-
] }) : /* @__PURE__ */ (0,
|
|
2028
|
-
/* @__PURE__ */ (0,
|
|
2029
|
-
/* @__PURE__ */ (0,
|
|
2030
|
-
/* @__PURE__ */ (0,
|
|
2166
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RouteChainEditor, { rpc, disabled }, "g"),
|
|
2167
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(BudgetInputs, { rpc, disabled, data: props.data, setData: props.setData, onError: props.onError, scope: "input" }, "g-budget"),
|
|
2168
|
+
info?.channel ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ChannelEditor, { channel: info.channel, rpc, disabled }) : null
|
|
2169
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
2170
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: STY3.panelHead, children: [
|
|
2171
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY3.panelTitle, children: LAYER_META[tab].title }),
|
|
2172
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { ...STY3.chip, ...dotOf(tab) === "runtime" ? STY3.chipAccent : STY3.chipMuted }, title: chipTitle(tab), children: dotOf(tab) === "runtime" ? "运行时自定义" : dotOf(tab) === "static" ? "静态 · YAML" : "跟随全局" })
|
|
2031
2173
|
] }),
|
|
2032
|
-
/* @__PURE__ */ (0,
|
|
2033
|
-
/* @__PURE__ */ (0,
|
|
2174
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RouteChainEditor, { rpc, disabled, scope: tab }, tab),
|
|
2175
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(BudgetInputs, { rpc, disabled, data: props.data, setData: props.setData, onError: props.onError, scope: tab }, tab + "-budget")
|
|
2034
2176
|
] })
|
|
2035
2177
|
] });
|
|
2036
2178
|
}
|
|
2037
2179
|
|
|
2038
2180
|
// client/src/tabs/EmbeddingSection.tsx
|
|
2039
|
-
var
|
|
2181
|
+
var import_react10 = require("react");
|
|
2182
|
+
|
|
2183
|
+
// client/src/dimensions.ts
|
|
2184
|
+
var DIMS_MIN = 1;
|
|
2185
|
+
var DIMS_MAX = 1e5;
|
|
2186
|
+
function dimsRangeMessage() {
|
|
2187
|
+
return `嵌入维度须为 ${DIMS_MIN}~${DIMS_MAX} 的整数(留空 = 跟随部署配置)`;
|
|
2188
|
+
}
|
|
2189
|
+
function commitDimensions(raw, deps) {
|
|
2190
|
+
deps.clearDirty();
|
|
2191
|
+
const trimmed = raw.trim();
|
|
2192
|
+
if (trimmed === "") {
|
|
2193
|
+
deps.submit(0);
|
|
2194
|
+
return;
|
|
2195
|
+
}
|
|
2196
|
+
const n = Number(trimmed);
|
|
2197
|
+
if (!Number.isInteger(n) || n < DIMS_MIN || n > DIMS_MAX) {
|
|
2198
|
+
deps.reject(dimsRangeMessage());
|
|
2199
|
+
return;
|
|
2200
|
+
}
|
|
2201
|
+
deps.submit(n);
|
|
2202
|
+
}
|
|
2040
2203
|
|
|
2041
2204
|
// client/src/rpc.ts
|
|
2042
2205
|
function shortMethod(endpoint) {
|
|
@@ -2063,7 +2226,7 @@ var __defProp = Object.defineProperty;
|
|
|
2063
2226
|
}
|
|
2064
2227
|
|
|
2065
2228
|
// client/src/tabs/EmbeddingSection.tsx
|
|
2066
|
-
var
|
|
2229
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2067
2230
|
var RSTY = {
|
|
2068
2231
|
block: { marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--dsh-mem-border)" },
|
|
2069
2232
|
title: { fontSize: 12, fontWeight: 600, color: "var(--dsh-mem-text-3)", margin: "0 0 2px" },
|
|
@@ -2087,17 +2250,17 @@ var __defProp = Object.defineProperty;
|
|
|
2087
2250
|
function EmbeddingSection(props) {
|
|
2088
2251
|
const rpc = props.rpc;
|
|
2089
2252
|
const loose = asLoose(rpc);
|
|
2090
|
-
const [st, setSt] = (0,
|
|
2091
|
-
const [err, setErr] = (0,
|
|
2092
|
-
const busyPollRef = (0,
|
|
2093
|
-
const [rBase, setRBase] = (0,
|
|
2094
|
-
const [rModel, setRModel] = (0,
|
|
2095
|
-
const [rDims, setRDims] = (0,
|
|
2096
|
-
const [rKey, setRKey] = (0,
|
|
2097
|
-
const remoteDirty = (0,
|
|
2098
|
-
const baseTimer = (0,
|
|
2099
|
-
const modelTimer = (0,
|
|
2100
|
-
const load = (0,
|
|
2253
|
+
const [st, setSt] = (0, import_react10.useState)(null);
|
|
2254
|
+
const [err, setErr] = (0, import_react10.useState)(null);
|
|
2255
|
+
const busyPollRef = (0, import_react10.useRef)(null);
|
|
2256
|
+
const [rBase, setRBase] = (0, import_react10.useState)("");
|
|
2257
|
+
const [rModel, setRModel] = (0, import_react10.useState)("");
|
|
2258
|
+
const [rDims, setRDims] = (0, import_react10.useState)("");
|
|
2259
|
+
const [rKey, setRKey] = (0, import_react10.useState)("");
|
|
2260
|
+
const remoteDirty = (0, import_react10.useRef)({ base: false, model: false, dims: false });
|
|
2261
|
+
const baseTimer = (0, import_react10.useRef)(void 0);
|
|
2262
|
+
const modelTimer = (0, import_react10.useRef)(void 0);
|
|
2263
|
+
const load = (0, import_react10.useCallback)(() => {
|
|
2101
2264
|
rpc("dsh-memory/embedding-state-get", {}).then((r) => {
|
|
2102
2265
|
if (r && r.ok && r.value && r.value.supported !== false) {
|
|
2103
2266
|
const v = r.value;
|
|
@@ -2116,10 +2279,10 @@ var __defProp = Object.defineProperty;
|
|
|
2116
2279
|
setErr(String(e && e.message || e));
|
|
2117
2280
|
});
|
|
2118
2281
|
}, [rpc]);
|
|
2119
|
-
(0,
|
|
2282
|
+
(0, import_react10.useEffect)(() => {
|
|
2120
2283
|
load();
|
|
2121
2284
|
}, [load]);
|
|
2122
|
-
(0,
|
|
2285
|
+
(0, import_react10.useEffect)(() => {
|
|
2123
2286
|
let stopped = false;
|
|
2124
2287
|
const busyFlag = { v: false };
|
|
2125
2288
|
busyPollRef.current = busyFlag;
|
|
@@ -2135,11 +2298,11 @@ var __defProp = Object.defineProperty;
|
|
|
2135
2298
|
busyPollRef.current = null;
|
|
2136
2299
|
};
|
|
2137
2300
|
}, [load]);
|
|
2138
|
-
(0,
|
|
2301
|
+
(0, import_react10.useEffect)(() => () => {
|
|
2139
2302
|
clearTimeout(baseTimer.current);
|
|
2140
2303
|
clearTimeout(modelTimer.current);
|
|
2141
2304
|
}, []);
|
|
2142
|
-
(0,
|
|
2305
|
+
(0, import_react10.useEffect)(() => {
|
|
2143
2306
|
if (!st || !st.remote) return;
|
|
2144
2307
|
if (!remoteDirty.current.base) setRBase(st.remote.baseURL || "");
|
|
2145
2308
|
if (!remoteDirty.current.model) setRModel(st.remote.model || "");
|
|
@@ -2172,21 +2335,16 @@ var __defProp = Object.defineProperty;
|
|
|
2172
2335
|
commitRemote({ embedRemoteModel: v.trim() });
|
|
2173
2336
|
}, 600);
|
|
2174
2337
|
};
|
|
2175
|
-
const commitRemoteDims = () => {
|
|
2176
|
-
|
|
2177
|
-
|
|
2338
|
+
const commitRemoteDims = () => commitDimensions(rDims, {
|
|
2339
|
+
// 复位脏标记由 commitDimensions 无条件执行(含失败路径)——**不要**在这里
|
|
2340
|
+
// 再加判断,那正是修复前的缺陷:失败时标记留在 true,轮询回填被永久门控,
|
|
2341
|
+
// 输入框卡死在非法值上。
|
|
2342
|
+
clearDirty: () => {
|
|
2178
2343
|
remoteDirty.current.dims = false;
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
if (!Number.isInteger(n) || n <= 0 || n > 1e5) {
|
|
2184
|
-
setErr("嵌入维度须为 1~100000 的整数(留空 = 跟随部署配置)");
|
|
2185
|
-
return;
|
|
2186
|
-
}
|
|
2187
|
-
remoteDirty.current.dims = false;
|
|
2188
|
-
commitRemote({ embedRemoteDimensions: n });
|
|
2189
|
-
};
|
|
2344
|
+
},
|
|
2345
|
+
submit: (n) => commitRemote({ embedRemoteDimensions: n }),
|
|
2346
|
+
reject: (message) => setErr(message)
|
|
2347
|
+
});
|
|
2190
2348
|
const commitRemoteKey = () => {
|
|
2191
2349
|
const v = rKey.trim();
|
|
2192
2350
|
if (v) commitRemote({ embedRemoteApiKey: v });
|
|
@@ -2205,15 +2363,15 @@ var __defProp = Object.defineProperty;
|
|
|
2205
2363
|
});
|
|
2206
2364
|
};
|
|
2207
2365
|
if (err === "__unsupported__") {
|
|
2208
|
-
return /* @__PURE__ */ (0,
|
|
2209
|
-
/* @__PURE__ */ (0,
|
|
2210
|
-
/* @__PURE__ */ (0,
|
|
2366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
2367
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: "语义检索(嵌入)" }),
|
|
2368
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-muted", children: "存储处于降级状态,嵌入管理不可用。" })
|
|
2211
2369
|
] });
|
|
2212
2370
|
}
|
|
2213
2371
|
if (!st) {
|
|
2214
|
-
return /* @__PURE__ */ (0,
|
|
2215
|
-
/* @__PURE__ */ (0,
|
|
2216
|
-
err ? /* @__PURE__ */ (0,
|
|
2372
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
2373
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-muted", children: err ? "嵌入状态读取失败:" + err : "嵌入状态读取中…" }),
|
|
2374
|
+
err ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(NButton, { style: { marginTop: 8 }, onClick: load, children: "重试" }) : null
|
|
2217
2375
|
] });
|
|
2218
2376
|
}
|
|
2219
2377
|
const switchConfirm = "切换嵌入源后将按新模型重建向量索引(期间语义检索暂退化为关键词匹配,不影响对话)。确定切换?";
|
|
@@ -2239,40 +2397,40 @@ var __defProp = Object.defineProperty;
|
|
|
2239
2397
|
const remote = st.remote;
|
|
2240
2398
|
let runtimeRow = null;
|
|
2241
2399
|
if (rt.phase === "installing") {
|
|
2242
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
2243
|
-
/* @__PURE__ */ (0,
|
|
2244
|
-
/* @__PURE__ */ (0,
|
|
2245
|
-
/* @__PURE__ */ (0,
|
|
2246
|
-
/* @__PURE__ */ (0,
|
|
2400
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { marginTop: 8, fontSize: 12 }, children: [
|
|
2401
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: S.flexRow, children: [
|
|
2402
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "安装推理运行时中… 已耗时 " + Math.round(rt.elapsedMs / 1e3) + "s(约 100~200MB,视网络)" }),
|
|
2403
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: S.grow }),
|
|
2404
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(NButton, { onClick: () => call("dsh-memory/embedding-runtime-cancel", {}), children: "取消" })
|
|
2247
2405
|
] }),
|
|
2248
|
-
/* @__PURE__ */ (0,
|
|
2406
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { style: { ...S.pre, maxHeight: 68, marginTop: 6, fontSize: 11, opacity: 0.85 }, children: (rt.lastLines || []).join("\n") || "等待 npm 输出…" })
|
|
2249
2407
|
] });
|
|
2250
2408
|
} else if (rt.phase === "error") {
|
|
2251
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
2409
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: "运行时安装失败:" + (rt.error || "未知") + "(重新切换嵌入源可重试)" });
|
|
2252
2410
|
} else if (rt.phase === "ready") {
|
|
2253
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
2411
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "推理运行时就绪(transformers.js v" + rt.installedVersion + ")" });
|
|
2254
2412
|
} else if (st.source === "local") {
|
|
2255
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
2413
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "首次启用本地嵌入时会自动安装推理运行时(约 100~200MB)。" });
|
|
2256
2414
|
}
|
|
2257
2415
|
let applyRow = null;
|
|
2258
2416
|
if (ap.phase === "warming") {
|
|
2259
|
-
applyRow = /* @__PURE__ */ (0,
|
|
2417
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "加载嵌入模型中…(首次需数秒)" });
|
|
2260
2418
|
} else if (ap.phase === "switching") {
|
|
2261
|
-
applyRow = /* @__PURE__ */ (0,
|
|
2419
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "切换嵌入源中…" });
|
|
2262
2420
|
} else if (ap.phase === "error") {
|
|
2263
|
-
applyRow = /* @__PURE__ */ (0,
|
|
2421
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: "切换失败:" + ap.message + "(已保存的嵌入源不变,重启后仍按原源运行)" });
|
|
2264
2422
|
} else if (st.reindex && st.reindex.running) {
|
|
2265
2423
|
const rj = st.reindex;
|
|
2266
2424
|
const rDone = rj.l1Done + rj.l0Done;
|
|
2267
2425
|
const rTotal = rj.l1Total + rj.l0Total;
|
|
2268
2426
|
const rPct = rTotal > 0 ? Math.round(rDone / rTotal * 100) : 0;
|
|
2269
|
-
applyRow = /* @__PURE__ */ (0,
|
|
2270
|
-
/* @__PURE__ */ (0,
|
|
2271
|
-
/* @__PURE__ */ (0,
|
|
2272
|
-
/* @__PURE__ */ (0,
|
|
2273
|
-
/* @__PURE__ */ (0,
|
|
2427
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { marginTop: 8 }, children: [
|
|
2428
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: S.flexRow, children: [
|
|
2429
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-rb-muted", children: "重嵌入中 L1 " + rj.l1Done + "/" + rj.l1Total + " · L0 " + rj.l0Done + "/" + rj.l0Total + "(" + rPct + "%)" }),
|
|
2430
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: S.grow }),
|
|
2431
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(NButton, { onClick: () => call("dsh-memory/embedding-reindex-cancel", {}), children: "取消" })
|
|
2274
2432
|
] }),
|
|
2275
|
-
/* @__PURE__ */ (0,
|
|
2433
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { ...S.flexRow, marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-bar", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-fill", style: { width: rPct + "%" } }) }) })
|
|
2276
2434
|
] });
|
|
2277
2435
|
}
|
|
2278
2436
|
const modelCards = st.models.map((m) => {
|
|
@@ -2281,24 +2439,24 @@ var __defProp = Object.defineProperty;
|
|
|
2281
2439
|
const pct = mDl && dl.overallTotal > 0 ? Math.round(dl.overallReceived / dl.overallTotal * 100) : 0;
|
|
2282
2440
|
let action;
|
|
2283
2441
|
if (mDl) {
|
|
2284
|
-
action = /* @__PURE__ */ (0,
|
|
2285
|
-
/* @__PURE__ */ (0,
|
|
2286
|
-
/* @__PURE__ */ (0,
|
|
2287
|
-
/* @__PURE__ */ (0,
|
|
2288
|
-
/* @__PURE__ */ (0,
|
|
2442
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { flex: 1, minWidth: 200 }, children: [
|
|
2443
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: S.flexRow, children: [
|
|
2444
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-rb-muted", style: { whiteSpace: "nowrap" }, children: (dl.phase === "verifying" ? "校验中 " : "") + fmtMB(dl.overallReceived) + " / " + fmtMB(dl.overallTotal) + "(文件 " + dl.fileIndex + "/" + dl.fileCount + "," + pct + "%" + (dl.speedBps > 0 && dl.phase === "downloading" ? "," + fmtMB(dl.speedBps) + "/s" : "") + ")" }),
|
|
2445
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: S.grow }),
|
|
2446
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(NButton, { onClick: () => call("dsh-memory/embedding-download-cancel", {}), children: "取消" })
|
|
2289
2447
|
] }),
|
|
2290
|
-
/* @__PURE__ */ (0,
|
|
2448
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { ...S.flexRow, marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-bar", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-fill", style: { width: pct + "%" } }) }) })
|
|
2291
2449
|
] });
|
|
2292
2450
|
} else if (isActive) {
|
|
2293
|
-
action = /* @__PURE__ */ (0,
|
|
2294
|
-
/* @__PURE__ */ (0,
|
|
2295
|
-
localInfo && localInfo.state === "loading" ? /* @__PURE__ */ (0,
|
|
2296
|
-
localInfo && localInfo.state === "failed" ? /* @__PURE__ */ (0,
|
|
2297
|
-
localInfo && localInfo.state === "ready" ? /* @__PURE__ */ (0,
|
|
2451
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: S.flexRow, children: [
|
|
2452
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-tag dsh-mem-tag-work-task", children: "使用中" }),
|
|
2453
|
+
localInfo && localInfo.state === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-rb-muted", children: "模型加载中…" }) : null,
|
|
2454
|
+
localInfo && localInfo.state === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-danger)" }, children: "加载失败:" + (localInfo.error || "") }) : null,
|
|
2455
|
+
localInfo && localInfo.state === "ready" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-rb-muted", children: "已就绪" }) : null
|
|
2298
2456
|
] });
|
|
2299
2457
|
} else if (m.state === "downloaded") {
|
|
2300
|
-
action = /* @__PURE__ */ (0,
|
|
2301
|
-
/* @__PURE__ */ (0,
|
|
2458
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: S.flexRow, children: [
|
|
2459
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2302
2460
|
NButton,
|
|
2303
2461
|
{
|
|
2304
2462
|
disabled: ap.busy,
|
|
@@ -2306,7 +2464,7 @@ var __defProp = Object.defineProperty;
|
|
|
2306
2464
|
children: "启用"
|
|
2307
2465
|
}
|
|
2308
2466
|
),
|
|
2309
|
-
/* @__PURE__ */ (0,
|
|
2467
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2310
2468
|
NButton,
|
|
2311
2469
|
{
|
|
2312
2470
|
disabled: dlActive,
|
|
@@ -2316,7 +2474,7 @@ var __defProp = Object.defineProperty;
|
|
|
2316
2474
|
)
|
|
2317
2475
|
] });
|
|
2318
2476
|
} else {
|
|
2319
|
-
action = /* @__PURE__ */ (0,
|
|
2477
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2320
2478
|
NButton,
|
|
2321
2479
|
{
|
|
2322
2480
|
disabled: dlActive || !st.ceilings.local,
|
|
@@ -2326,27 +2484,27 @@ var __defProp = Object.defineProperty;
|
|
|
2326
2484
|
}
|
|
2327
2485
|
);
|
|
2328
2486
|
}
|
|
2329
|
-
return /* @__PURE__ */ (0,
|
|
2487
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2330
2488
|
"div",
|
|
2331
2489
|
{
|
|
2332
2490
|
style: { ...S.flexRow, padding: "8px 0", borderBottom: "1px solid var(--dsh-mem-border)", flexWrap: "wrap" },
|
|
2333
2491
|
children: [
|
|
2334
|
-
/* @__PURE__ */ (0,
|
|
2335
|
-
/* @__PURE__ */ (0,
|
|
2336
|
-
/* @__PURE__ */ (0,
|
|
2492
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { minWidth: 150 }, children: [
|
|
2493
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { fontWeight: 600 }, children: m.name }),
|
|
2494
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-muted", children: m.tags.join(" · ") + " · " + m.dims + " 维 · 上下文 " + m.contextTokens })
|
|
2337
2495
|
] }),
|
|
2338
|
-
/* @__PURE__ */ (0,
|
|
2496
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { flex: 1, minWidth: 180, fontSize: 12, color: "var(--dsh-mem-text-2)" }, children: m.description }),
|
|
2339
2497
|
action
|
|
2340
2498
|
]
|
|
2341
2499
|
},
|
|
2342
2500
|
m.id
|
|
2343
2501
|
);
|
|
2344
2502
|
});
|
|
2345
|
-
return /* @__PURE__ */ (0,
|
|
2346
|
-
/* @__PURE__ */ (0,
|
|
2347
|
-
/* @__PURE__ */ (0,
|
|
2348
|
-
/* @__PURE__ */ (0,
|
|
2349
|
-
/* @__PURE__ */ (0,
|
|
2503
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
2504
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: S.flexRow, children: [
|
|
2505
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { fontWeight: 600, whiteSpace: "nowrap" }, children: "语义检索(嵌入源)" }),
|
|
2506
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: S.grow }),
|
|
2507
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2350
2508
|
Segmented,
|
|
2351
2509
|
{
|
|
2352
2510
|
value: st.source,
|
|
@@ -2359,18 +2517,18 @@ var __defProp = Object.defineProperty;
|
|
|
2359
2517
|
}
|
|
2360
2518
|
)
|
|
2361
2519
|
] }),
|
|
2362
|
-
/* @__PURE__ */ (0,
|
|
2363
|
-
st.activeNote ? /* @__PURE__ */ (0,
|
|
2364
|
-
err && err !== "__unsupported__" ? /* @__PURE__ */ (0,
|
|
2365
|
-
dl && dl.phase === "error" ? /* @__PURE__ */ (0,
|
|
2520
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 4 }, children: st.source === "off" ? "当前:关键词(BM25)检索,不做向量嵌入" : st.source === "remote" ? "当前:远程嵌入(" + (remote.model || "未配置模型") + (remote.baseURL ? " · " + remote.baseURL : "") + ")" : "当前:本地嵌入" + (st.activeModel ? "(" + st.activeModel + ")" : "") }),
|
|
2521
|
+
st.activeNote ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { marginTop: 4, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: st.activeNote }) : null,
|
|
2522
|
+
err && err !== "__unsupported__" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { marginTop: 6, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: err }) : null,
|
|
2523
|
+
dl && dl.phase === "error" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { marginTop: 6, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: "下载失败:" + (dl.error || "") }) : null,
|
|
2366
2524
|
runtimeRow,
|
|
2367
2525
|
applyRow,
|
|
2368
|
-
/* @__PURE__ */ (0,
|
|
2369
|
-
/* @__PURE__ */ (0,
|
|
2370
|
-
/* @__PURE__ */ (0,
|
|
2371
|
-
/* @__PURE__ */ (0,
|
|
2372
|
-
/* @__PURE__ */ (0,
|
|
2373
|
-
/* @__PURE__ */ (0,
|
|
2526
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: RSTY.block, children: [
|
|
2527
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: RSTY.title, children: "远程连接(生效值;运行时覆盖优先于部署 YAML)" }),
|
|
2528
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: RSTY.note, children: "生效端点 " + (remote.baseURL || "(未配置)") + " · 模型 " + (remote.model || "(未配置)") + " · " + (remote.dimensions > 0 ? remote.dimensions + " 维" : "维度跟随部署") + (remote.apiKeySet ? " · 密钥已设置" : " · 密钥未设置") }),
|
|
2529
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: RSTY.row, children: [
|
|
2530
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: RSTY.label, children: "端点 URL" }),
|
|
2531
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2374
2532
|
NInput,
|
|
2375
2533
|
{
|
|
2376
2534
|
style: RSTY.input,
|
|
@@ -2387,9 +2545,9 @@ var __defProp = Object.defineProperty;
|
|
|
2387
2545
|
}
|
|
2388
2546
|
)
|
|
2389
2547
|
] }),
|
|
2390
|
-
/* @__PURE__ */ (0,
|
|
2391
|
-
/* @__PURE__ */ (0,
|
|
2392
|
-
/* @__PURE__ */ (0,
|
|
2548
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: RSTY.row, children: [
|
|
2549
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: RSTY.label, children: "模型名" }),
|
|
2550
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2393
2551
|
NInput,
|
|
2394
2552
|
{
|
|
2395
2553
|
style: RSTY.input,
|
|
@@ -2405,8 +2563,8 @@ var __defProp = Object.defineProperty;
|
|
|
2405
2563
|
}
|
|
2406
2564
|
}
|
|
2407
2565
|
),
|
|
2408
|
-
/* @__PURE__ */ (0,
|
|
2409
|
-
/* @__PURE__ */ (0,
|
|
2566
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: RSTY.label, children: "维度" }),
|
|
2567
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2410
2568
|
NInput,
|
|
2411
2569
|
{
|
|
2412
2570
|
style: { width: 90, minWidth: 0, flex: "0 1 90px" },
|
|
@@ -2426,9 +2584,9 @@ var __defProp = Object.defineProperty;
|
|
|
2426
2584
|
}
|
|
2427
2585
|
)
|
|
2428
2586
|
] }),
|
|
2429
|
-
/* @__PURE__ */ (0,
|
|
2430
|
-
/* @__PURE__ */ (0,
|
|
2431
|
-
/* @__PURE__ */ (0,
|
|
2587
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: RSTY.row, children: [
|
|
2588
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: RSTY.label, children: "API Key" }),
|
|
2589
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2432
2590
|
NInput,
|
|
2433
2591
|
{
|
|
2434
2592
|
style: RSTY.input,
|
|
@@ -2443,8 +2601,8 @@ var __defProp = Object.defineProperty;
|
|
|
2443
2601
|
onBlur: commitRemoteKey
|
|
2444
2602
|
}
|
|
2445
2603
|
),
|
|
2446
|
-
remote.apiKeySet ? /* @__PURE__ */ (0,
|
|
2447
|
-
/* @__PURE__ */ (0,
|
|
2604
|
+
remote.apiKeySet ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: RSTY.chipAccent, children: "已设置" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: RSTY.chipMuted, children: "未设置" }),
|
|
2605
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2448
2606
|
NButton,
|
|
2449
2607
|
{
|
|
2450
2608
|
title: "写入空串清除运行时密钥(部署 YAML 的密钥不受影响)",
|
|
@@ -2454,14 +2612,14 @@ var __defProp = Object.defineProperty;
|
|
|
2454
2612
|
)
|
|
2455
2613
|
] })
|
|
2456
2614
|
] }),
|
|
2457
|
-
/* @__PURE__ */ (0,
|
|
2615
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: S.panelLabel, children: "本地模型目录(下载后离线可用,不随插件分发)" }),
|
|
2458
2616
|
modelCards
|
|
2459
2617
|
] });
|
|
2460
2618
|
}
|
|
2461
2619
|
|
|
2462
2620
|
// client/src/tabs/RebuildPanel.tsx
|
|
2463
|
-
var
|
|
2464
|
-
var
|
|
2621
|
+
var import_react11 = require("react");
|
|
2622
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2465
2623
|
var RB_PHASE_LABEL = {
|
|
2466
2624
|
preparing: "准备中(归档旧数据 · 清空检索库)",
|
|
2467
2625
|
distilling: "分块蒸馏中",
|
|
@@ -2469,21 +2627,21 @@ var __defProp = Object.defineProperty;
|
|
|
2469
2627
|
};
|
|
2470
2628
|
function RebuildPanel(props) {
|
|
2471
2629
|
const rpc = props.rpc;
|
|
2472
|
-
const [rbRaw, setRb] = (0,
|
|
2473
|
-
const [confirmOpen, setConfirmOpen] = (0,
|
|
2474
|
-
const [busy, setBusy] = (0,
|
|
2475
|
-
const [rbError, setRbError] = (0,
|
|
2476
|
-
const refresh = (0,
|
|
2630
|
+
const [rbRaw, setRb] = (0, import_react11.useState)(null);
|
|
2631
|
+
const [confirmOpen, setConfirmOpen] = (0, import_react11.useState)(false);
|
|
2632
|
+
const [busy, setBusy] = (0, import_react11.useState)(false);
|
|
2633
|
+
const [rbError, setRbError] = (0, import_react11.useState)(null);
|
|
2634
|
+
const refresh = (0, import_react11.useCallback)(() => {
|
|
2477
2635
|
rpc("dsh-memory/rebuild-status", {}).then((r) => {
|
|
2478
2636
|
if (r && r.ok) setRb(r.value);
|
|
2479
2637
|
}).catch(() => {
|
|
2480
2638
|
});
|
|
2481
2639
|
}, [rpc]);
|
|
2482
|
-
(0,
|
|
2640
|
+
(0, import_react11.useEffect)(() => {
|
|
2483
2641
|
refresh();
|
|
2484
2642
|
}, [refresh]);
|
|
2485
2643
|
const running = !!(rbRaw && rbRaw.running);
|
|
2486
|
-
(0,
|
|
2644
|
+
(0, import_react11.useEffect)(() => {
|
|
2487
2645
|
if (!running) return;
|
|
2488
2646
|
const timer = setInterval(refresh, 1500);
|
|
2489
2647
|
return () => {
|
|
@@ -2528,11 +2686,11 @@ var __defProp = Object.defineProperty;
|
|
|
2528
2686
|
} else if (!running && rb.phase === "failed") {
|
|
2529
2687
|
lastNote = "上次重建:失败:" + (rb.error || "未知错误");
|
|
2530
2688
|
}
|
|
2531
|
-
return /* @__PURE__ */ (0,
|
|
2532
|
-
/* @__PURE__ */ (0,
|
|
2533
|
-
/* @__PURE__ */ (0,
|
|
2534
|
-
/* @__PURE__ */ (0,
|
|
2535
|
-
running ? /* @__PURE__ */ (0,
|
|
2689
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
2690
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }, children: [
|
|
2691
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { fontWeight: 600, whiteSpace: "nowrap" }, children: "重建记忆" }),
|
|
2692
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-mem-rb-muted", style: { flex: 1, minWidth: 180 }, children: running ? (RB_PHASE_LABEL[rb.phase] || rb.phase) + " · " + rb.done + "/" + rb.total + " 会话(" + pct + "%)" : "从 L0 原始对话重新蒸馏 L1/L2/L3;旧数据先归档(不删除)" }),
|
|
2693
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { disabled: busy || rb.cancelRequested, onClick: cancel, children: rb.cancelRequested ? "取消中…" : "取消重建" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2536
2694
|
NButton,
|
|
2537
2695
|
{
|
|
2538
2696
|
disabled: busy || empty,
|
|
@@ -2545,13 +2703,13 @@ var __defProp = Object.defineProperty;
|
|
|
2545
2703
|
}
|
|
2546
2704
|
)
|
|
2547
2705
|
] }),
|
|
2548
|
-
running ? /* @__PURE__ */ (0,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2550
|
-
/* @__PURE__ */ (0,
|
|
2706
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, marginTop: 10 }, children: [
|
|
2707
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-mem-rb-bar", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-mem-rb-fill", style: { width: pct + "%" } }) }),
|
|
2708
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dsh-mem-rb-muted", style: { whiteSpace: "nowrap" }, children: "产出 " + rb.recordsBuilt + " 条" })
|
|
2551
2709
|
] }) : null,
|
|
2552
|
-
lastNote ? /* @__PURE__ */ (0,
|
|
2553
|
-
rbError ? /* @__PURE__ */ (0,
|
|
2554
|
-
confirmOpen ? /* @__PURE__ */ (0,
|
|
2710
|
+
lastNote ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: lastNote }) : null,
|
|
2711
|
+
rbError ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: rbError }) : null,
|
|
2712
|
+
confirmOpen ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2555
2713
|
NModal,
|
|
2556
2714
|
{
|
|
2557
2715
|
open: true,
|
|
@@ -2560,7 +2718,7 @@ var __defProp = Object.defineProperty;
|
|
|
2560
2718
|
},
|
|
2561
2719
|
title: "确认重建全部记忆?",
|
|
2562
2720
|
footer: [
|
|
2563
|
-
/* @__PURE__ */ (0,
|
|
2721
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2564
2722
|
NButton,
|
|
2565
2723
|
{
|
|
2566
2724
|
onClick: () => {
|
|
@@ -2570,15 +2728,15 @@ var __defProp = Object.defineProperty;
|
|
|
2570
2728
|
},
|
|
2571
2729
|
"cancel"
|
|
2572
2730
|
),
|
|
2573
|
-
/* @__PURE__ */ (0,
|
|
2731
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { variant: "primary", disabled: busy, onClick: start, children: busy ? "启动中…" : "开始重建" }, "confirm")
|
|
2574
2732
|
],
|
|
2575
2733
|
children: [
|
|
2576
|
-
/* @__PURE__ */ (0,
|
|
2734
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
|
|
2577
2735
|
"将以 L0 原始对话为事实源重新蒸馏:",
|
|
2578
|
-
/* @__PURE__ */ (0,
|
|
2736
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("b", { children: rb.sessionCount + " 个会话 · " + rb.messageCount + " 条消息" }),
|
|
2579
2737
|
",预计 ≥" + rb.estCalls + " 次蒸馏调用。"
|
|
2580
2738
|
] }),
|
|
2581
|
-
/* @__PURE__ */ (0,
|
|
2739
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { marginTop: 8 }, children: "现有 L1 记忆 / L2 场景 / L3 画像会整体归档(*.bak.时间戳,可手工找回),随后清空重建;重建期间可正常对话,新对话的蒸馏优先进行;中途可取消,已重建部分保留。" })
|
|
2582
2740
|
]
|
|
2583
2741
|
}
|
|
2584
2742
|
) : null
|
|
@@ -2586,8 +2744,8 @@ var __defProp = Object.defineProperty;
|
|
|
2586
2744
|
}
|
|
2587
2745
|
|
|
2588
2746
|
// client/src/tabs/RuminatePanel.tsx
|
|
2589
|
-
var
|
|
2590
|
-
var
|
|
2747
|
+
var import_react12 = require("react");
|
|
2748
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2591
2749
|
var RM_PHASE_LABEL = {
|
|
2592
2750
|
refreshing: "轻量刷新中",
|
|
2593
2751
|
distilling: "L1 蒸馏中",
|
|
@@ -2597,27 +2755,27 @@ var __defProp = Object.defineProperty;
|
|
|
2597
2755
|
var RM_RUNNING_PHASES = ["refreshing", "distilling", "consolidating", "updating"];
|
|
2598
2756
|
function RuminatePanel(props) {
|
|
2599
2757
|
const rpc = props.rpc;
|
|
2600
|
-
const [rmRaw, setRm] = (0,
|
|
2601
|
-
const [confirmOpen, setConfirmOpen] = (0,
|
|
2602
|
-
const [busy, setBusy] = (0,
|
|
2603
|
-
const [rmError, setRmError] = (0,
|
|
2604
|
-
const refresh = (0,
|
|
2758
|
+
const [rmRaw, setRm] = (0, import_react12.useState)(null);
|
|
2759
|
+
const [confirmOpen, setConfirmOpen] = (0, import_react12.useState)(false);
|
|
2760
|
+
const [busy, setBusy] = (0, import_react12.useState)(false);
|
|
2761
|
+
const [rmError, setRmError] = (0, import_react12.useState)(null);
|
|
2762
|
+
const refresh = (0, import_react12.useCallback)(() => {
|
|
2605
2763
|
rpc("dsh-memory/ruminate-status", {}).then((r) => {
|
|
2606
2764
|
if (r && r.ok) setRm(r.value);
|
|
2607
2765
|
}).catch(() => {
|
|
2608
2766
|
});
|
|
2609
2767
|
}, [rpc]);
|
|
2610
|
-
(0,
|
|
2768
|
+
(0, import_react12.useEffect)(() => {
|
|
2611
2769
|
refresh();
|
|
2612
2770
|
}, [refresh]);
|
|
2613
2771
|
const running = !!(rmRaw && (rmRaw.running || RM_RUNNING_PHASES.indexOf(rmRaw.phase) >= 0));
|
|
2614
|
-
(0,
|
|
2772
|
+
(0, import_react12.useEffect)(() => {
|
|
2615
2773
|
if (!running) return;
|
|
2616
2774
|
const timer = setInterval(refresh, 1500);
|
|
2617
2775
|
return () => clearInterval(timer);
|
|
2618
2776
|
}, [running, refresh]);
|
|
2619
|
-
const [, setTick] = (0,
|
|
2620
|
-
(0,
|
|
2777
|
+
const [, setTick] = (0, import_react12.useState)(0);
|
|
2778
|
+
(0, import_react12.useEffect)(() => {
|
|
2621
2779
|
if (!running) return;
|
|
2622
2780
|
const timer = setInterval(() => setTick((n) => n + 1), 1e3);
|
|
2623
2781
|
return () => clearInterval(timer);
|
|
@@ -2664,11 +2822,11 @@ var __defProp = Object.defineProperty;
|
|
|
2664
2822
|
}
|
|
2665
2823
|
const unit = rm.phase === "refreshing" ? "步" : "会话";
|
|
2666
2824
|
const progressText = rm.total > 0 ? rm.done + "/" + rm.total + " " + unit + "(" + pct + "%)" : "进行中…";
|
|
2667
|
-
return /* @__PURE__ */ (0,
|
|
2668
|
-
/* @__PURE__ */ (0,
|
|
2669
|
-
/* @__PURE__ */ (0,
|
|
2670
|
-
/* @__PURE__ */ (0,
|
|
2671
|
-
running ? /* @__PURE__ */ (0,
|
|
2825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
2826
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }, children: [
|
|
2827
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { fontWeight: 600, whiteSpace: "nowrap" }, children: "反刍整理" }),
|
|
2828
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "dsh-mem-rb-muted", style: { flex: 1, minWidth: 180 }, children: running ? (RM_PHASE_LABEL[rm.phase] || rm.phase) + " · " + progressText + (elapsedText ? " · 已用 " + elapsedText : "") : "冲刷未蒸馏缓冲,跑一轮 L1→L2→L3 消化;不清库不改 L0" }),
|
|
2829
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NButton, { disabled: busy || rm.cancelRequested, onClick: cancel, children: rm.cancelRequested ? "取消中…" : "取消整理" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2672
2830
|
NButton,
|
|
2673
2831
|
{
|
|
2674
2832
|
disabled: busy,
|
|
@@ -2681,21 +2839,21 @@ var __defProp = Object.defineProperty;
|
|
|
2681
2839
|
}
|
|
2682
2840
|
)
|
|
2683
2841
|
] }),
|
|
2684
|
-
running ? /* @__PURE__ */ (0,
|
|
2685
|
-
/* @__PURE__ */ (0,
|
|
2686
|
-
/* @__PURE__ */ (0,
|
|
2842
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, marginTop: 10 }, children: [
|
|
2843
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "dsh-mem-rb-bar", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "dsh-mem-rb-fill", style: { width: (rm.total > 0 ? pct : 100) + "%" } }) }),
|
|
2844
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "dsh-mem-rb-muted", style: { whiteSpace: "nowrap" }, children: "产出 " + rm.recordsBuilt + " 条" })
|
|
2687
2845
|
] }) : null,
|
|
2688
|
-
running && rm.detail ? /* @__PURE__ */ (0,
|
|
2689
|
-
lastNote ? /* @__PURE__ */ (0,
|
|
2690
|
-
rmError ? /* @__PURE__ */ (0,
|
|
2691
|
-
confirmOpen ? /* @__PURE__ */ (0,
|
|
2846
|
+
running && rm.detail ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 6, whiteSpace: "normal" }, children: "当前:" + rm.detail }) : null,
|
|
2847
|
+
lastNote ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: lastNote }) : null,
|
|
2848
|
+
rmError ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: rmError }) : null,
|
|
2849
|
+
confirmOpen ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2692
2850
|
NModal,
|
|
2693
2851
|
{
|
|
2694
2852
|
open: true,
|
|
2695
2853
|
onClose: () => setConfirmOpen(false),
|
|
2696
2854
|
title: "确认反刍整理?",
|
|
2697
2855
|
footer: [
|
|
2698
|
-
/* @__PURE__ */ (0,
|
|
2856
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2699
2857
|
NButton,
|
|
2700
2858
|
{
|
|
2701
2859
|
onClick: () => setConfirmOpen(false),
|
|
@@ -2703,11 +2861,11 @@ var __defProp = Object.defineProperty;
|
|
|
2703
2861
|
},
|
|
2704
2862
|
"cancel"
|
|
2705
2863
|
),
|
|
2706
|
-
/* @__PURE__ */ (0,
|
|
2864
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NButton, { variant: "primary", disabled: busy, onClick: start, children: busy ? "启动中…" : "反刍整理" }, "confirm")
|
|
2707
2865
|
],
|
|
2708
2866
|
children: [
|
|
2709
|
-
/* @__PURE__ */ (0,
|
|
2710
|
-
/* @__PURE__ */ (0,
|
|
2867
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: "将扫描未蒸馏缓冲,按会话逐个跑蒸馏管线,完成后强制 L2 场景整合与 L3 画像更新。" }),
|
|
2868
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { marginTop: 8 }, children: "与重建不同:不清空 L1 检索库、不归档旧产物、不改 L0;仅消化攒而未蒸馏的切片,无缓冲时做轻量 L2/L3 刷新。" })
|
|
2711
2869
|
]
|
|
2712
2870
|
}
|
|
2713
2871
|
) : null
|
|
@@ -2715,13 +2873,13 @@ var __defProp = Object.defineProperty;
|
|
|
2715
2873
|
}
|
|
2716
2874
|
|
|
2717
2875
|
// client/src/tabs/OverviewTab.tsx
|
|
2718
|
-
var
|
|
2876
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2719
2877
|
function OverviewTab(props) {
|
|
2720
2878
|
const rpc = props.rpc;
|
|
2721
|
-
const [stats, setStats] = (0,
|
|
2722
|
-
const [settingsData, setSettingsData] = (0,
|
|
2723
|
-
const [error, setError] = (0,
|
|
2724
|
-
const load = (0,
|
|
2879
|
+
const [stats, setStats] = (0, import_react13.useState)(null);
|
|
2880
|
+
const [settingsData, setSettingsData] = (0, import_react13.useState)(null);
|
|
2881
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
2882
|
+
const load = (0, import_react13.useCallback)(() => {
|
|
2725
2883
|
rpc("dsh-memory/stats", {}).then((r) => {
|
|
2726
2884
|
if (r && r.ok) setStats(r.value);
|
|
2727
2885
|
else setError(r && r.error ? r.error.message : "RPC error");
|
|
@@ -2733,7 +2891,7 @@ var __defProp = Object.defineProperty;
|
|
|
2733
2891
|
}).catch(() => {
|
|
2734
2892
|
});
|
|
2735
2893
|
}, [rpc]);
|
|
2736
|
-
(0,
|
|
2894
|
+
(0, import_react13.useEffect)(() => {
|
|
2737
2895
|
load();
|
|
2738
2896
|
const timer = setInterval(load, 5e3);
|
|
2739
2897
|
return () => {
|
|
@@ -2788,10 +2946,10 @@ var __defProp = Object.defineProperty;
|
|
|
2788
2946
|
if (off.length > 0) ceilingNote = "注意:部署配置已停用 " + off.join("、") + "(运行时开关无法开启)";
|
|
2789
2947
|
}
|
|
2790
2948
|
const mutate = settingsData && settingsData.settings ? !!settingsData.settings.memoryMutate : false;
|
|
2791
|
-
return /* @__PURE__ */ (0,
|
|
2792
|
-
settingsData && settingsData.supported === false ? /* @__PURE__ */ (0,
|
|
2793
|
-
/* @__PURE__ */ (0,
|
|
2794
|
-
/* @__PURE__ */ (0,
|
|
2949
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
|
|
2950
|
+
settingsData && settingsData.supported === false ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { style: S.hint, children: "settings 服务不可用,记忆模式开关未启用(记忆保持全开)。" }) : settingsData ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.switchPanel, children: [
|
|
2951
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.panelLabel, children: "记忆模式" }),
|
|
2952
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2795
2953
|
SwitchRow,
|
|
2796
2954
|
{
|
|
2797
2955
|
label: "记忆模式",
|
|
@@ -2802,7 +2960,7 @@ var __defProp = Object.defineProperty;
|
|
|
2802
2960
|
}
|
|
2803
2961
|
}
|
|
2804
2962
|
),
|
|
2805
|
-
/* @__PURE__ */ (0,
|
|
2963
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2806
2964
|
SwitchRow,
|
|
2807
2965
|
{
|
|
2808
2966
|
label: "捕获",
|
|
@@ -2814,7 +2972,7 @@ var __defProp = Object.defineProperty;
|
|
|
2814
2972
|
}
|
|
2815
2973
|
}
|
|
2816
2974
|
),
|
|
2817
|
-
/* @__PURE__ */ (0,
|
|
2975
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2818
2976
|
SwitchRow,
|
|
2819
2977
|
{
|
|
2820
2978
|
label: "蒸馏",
|
|
@@ -2826,7 +2984,7 @@ var __defProp = Object.defineProperty;
|
|
|
2826
2984
|
}
|
|
2827
2985
|
}
|
|
2828
2986
|
),
|
|
2829
|
-
/* @__PURE__ */ (0,
|
|
2987
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2830
2988
|
SwitchRow,
|
|
2831
2989
|
{
|
|
2832
2990
|
label: "召回",
|
|
@@ -2838,8 +2996,8 @@ var __defProp = Object.defineProperty;
|
|
|
2838
2996
|
}
|
|
2839
2997
|
}
|
|
2840
2998
|
),
|
|
2841
|
-
/* @__PURE__ */ (0,
|
|
2842
|
-
/* @__PURE__ */ (0,
|
|
2999
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.panelLabel, children: "高权限模式" }),
|
|
3000
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2843
3001
|
SwitchRow,
|
|
2844
3002
|
{
|
|
2845
3003
|
label: "高权限模式",
|
|
@@ -2850,42 +3008,42 @@ var __defProp = Object.defineProperty;
|
|
|
2850
3008
|
}
|
|
2851
3009
|
}
|
|
2852
3010
|
),
|
|
2853
|
-
/* @__PURE__ */ (0,
|
|
2854
|
-
/* @__PURE__ */ (0,
|
|
2855
|
-
ceilingNote ? /* @__PURE__ */ (0,
|
|
3011
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.panelLabel, children: "蒸馏参数" }),
|
|
3012
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DistillSettings, { rpc, disabled: !master, data: settingsData, setData: setSettingsData, onError: setError }),
|
|
3013
|
+
ceilingNote ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { style: S.hint, children: ceilingNote }) : null
|
|
2856
3014
|
] }) : null,
|
|
2857
|
-
/* @__PURE__ */ (0,
|
|
2858
|
-
/* @__PURE__ */ (0,
|
|
2859
|
-
/* @__PURE__ */ (0,
|
|
2860
|
-
degraded ? /* @__PURE__ */ (0,
|
|
2861
|
-
error ? /* @__PURE__ */ (0,
|
|
2862
|
-
/* @__PURE__ */ (0,
|
|
2863
|
-
/* @__PURE__ */ (0,
|
|
2864
|
-
return /* @__PURE__ */ (0,
|
|
2865
|
-
/* @__PURE__ */ (0,
|
|
2866
|
-
/* @__PURE__ */ (0,
|
|
3015
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EmbeddingSection, { rpc }),
|
|
3016
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RebuildPanel, { rpc }),
|
|
3017
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RuminatePanel, { rpc }),
|
|
3018
|
+
degraded ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { ...S.error, marginBottom: 10 }, children: "⚠ " + stats.message + "。上方数据为最后一次成功读取的值,记忆功能当前未工作。" }) : null,
|
|
3019
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.error, children: "获取状态失败:" + error }) : !stats ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { style: S.intro, children: "正在读取记忆状态…" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
|
|
3020
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.panelLabel, children: "记忆概况" }),
|
|
3021
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.statGrid, children: tiles.map((t) => {
|
|
3022
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "dsh-mem-card", style: S.statTile, children: [
|
|
3023
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.statNum, children: t.num }),
|
|
3024
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.statLabel, children: t.label })
|
|
2867
3025
|
] }, t.label);
|
|
2868
3026
|
}) }),
|
|
2869
|
-
/* @__PURE__ */ (0,
|
|
3027
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.panelLabel, children: "运行状态" }),
|
|
2870
3028
|
infos.map((row2) => {
|
|
2871
|
-
return /* @__PURE__ */ (0,
|
|
2872
|
-
/* @__PURE__ */ (0,
|
|
2873
|
-
/* @__PURE__ */ (0,
|
|
3029
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.infoRow, children: [
|
|
3030
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: S.infoKey, children: row2[0] }),
|
|
3031
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: S.infoVal, children: row2[1] })
|
|
2874
3032
|
] }, row2[0]);
|
|
2875
3033
|
})
|
|
2876
3034
|
] }),
|
|
2877
|
-
/* @__PURE__ */ (0,
|
|
3035
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { style: S.hint, children: "浏览各层记忆内容请切换上方 Tab;原始对话(L0)不入浏览器,可由模型侧 conversation_search 工具查询。" })
|
|
2878
3036
|
] });
|
|
2879
3037
|
}
|
|
2880
3038
|
|
|
2881
3039
|
// client/src/tabs/PersonaTab.tsx
|
|
2882
|
-
var
|
|
2883
|
-
var
|
|
3040
|
+
var import_react14 = require("react");
|
|
3041
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2884
3042
|
function PersonaTab(props) {
|
|
2885
3043
|
const rpc = props.rpc;
|
|
2886
|
-
const [content, setContent] = (0,
|
|
2887
|
-
const [error, setError] = (0,
|
|
2888
|
-
const load = (0,
|
|
3044
|
+
const [content, setContent] = (0, import_react14.useState)(null);
|
|
3045
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
3046
|
+
const load = (0, import_react14.useCallback)(() => {
|
|
2889
3047
|
setError(null);
|
|
2890
3048
|
rpc("dsh-memory/persona", {}).then((r) => {
|
|
2891
3049
|
if (r && r.ok) setContent(r.value.content);
|
|
@@ -2894,23 +3052,23 @@ var __defProp = Object.defineProperty;
|
|
|
2894
3052
|
setError(String(e && e.message || e));
|
|
2895
3053
|
});
|
|
2896
3054
|
}, [rpc]);
|
|
2897
|
-
(0,
|
|
3055
|
+
(0, import_react14.useEffect)(() => {
|
|
2898
3056
|
load();
|
|
2899
3057
|
}, [load]);
|
|
2900
|
-
return /* @__PURE__ */ (0,
|
|
2901
|
-
/* @__PURE__ */ (0,
|
|
2902
|
-
/* @__PURE__ */ (0,
|
|
2903
|
-
/* @__PURE__ */ (0,
|
|
2904
|
-
/* @__PURE__ */ (0,
|
|
3058
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3059
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
3060
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: S.muted, children: error ? "加载失败" : content === null ? "加载中…" : content ? content.length + " 字符" : "未生成画像" }),
|
|
3061
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: S.grow }),
|
|
3062
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
2905
3063
|
] }),
|
|
2906
|
-
error ? /* @__PURE__ */ (0,
|
|
2907
|
-
content ? /* @__PURE__ */ (0,
|
|
3064
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { ...S.error, marginBottom: 10 }, children: "画像读取失败:" + error + "(点右上“刷新”重试)" }) : null,
|
|
3065
|
+
content ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("pre", { style: S.pre, children: content }) : content === null ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { style: S.intro, children: "画像尚未生成;蒸馏若干记忆后 L3 会自动产出。" })
|
|
2908
3066
|
] });
|
|
2909
3067
|
}
|
|
2910
3068
|
|
|
2911
3069
|
// client/src/tabs/RecordsTab.tsx
|
|
2912
|
-
var
|
|
2913
|
-
var
|
|
3070
|
+
var import_react15 = require("react");
|
|
3071
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2914
3072
|
var TYPE_CHOICES = [
|
|
2915
3073
|
"persona",
|
|
2916
3074
|
"episodic",
|
|
@@ -2932,24 +3090,24 @@ var __defProp = Object.defineProperty;
|
|
|
2932
3090
|
function RecordsTab(props) {
|
|
2933
3091
|
const rpc = props.rpc;
|
|
2934
3092
|
const limit = 50;
|
|
2935
|
-
const [items, setItems] = (0,
|
|
2936
|
-
const [hasMore, setHasMore] = (0,
|
|
2937
|
-
const [total, setTotal] = (0,
|
|
2938
|
-
const [sceneOptions, setSceneOptions] = (0,
|
|
2939
|
-
const [loading, setLoading] = (0,
|
|
2940
|
-
const [truncated, setTruncated] = (0,
|
|
2941
|
-
const [error, setError] = (0,
|
|
2942
|
-
const [expandedId, setExpandedId] = (0,
|
|
2943
|
-
const [sel, setSel] = (0,
|
|
2944
|
-
const [hiPriv, setHiPriv] = (0,
|
|
2945
|
-
const [hiPrivBusy, setHiPrivBusy] = (0,
|
|
2946
|
-
const [query, setQuery] = (0,
|
|
2947
|
-
const [typeFilter, setTypeFilter] = (0,
|
|
2948
|
-
const [sceneFilter, setSceneFilter] = (0,
|
|
2949
|
-
const [hallFilter, setHallFilter] = (0,
|
|
2950
|
-
const [last, setLast] = (0,
|
|
2951
|
-
const seqRef = (0,
|
|
2952
|
-
const fetchPage = (0,
|
|
3093
|
+
const [items, setItems] = (0, import_react15.useState)([]);
|
|
3094
|
+
const [hasMore, setHasMore] = (0, import_react15.useState)(false);
|
|
3095
|
+
const [total, setTotal] = (0, import_react15.useState)(null);
|
|
3096
|
+
const [sceneOptions, setSceneOptions] = (0, import_react15.useState)([]);
|
|
3097
|
+
const [loading, setLoading] = (0, import_react15.useState)(false);
|
|
3098
|
+
const [truncated, setTruncated] = (0, import_react15.useState)(false);
|
|
3099
|
+
const [error, setError] = (0, import_react15.useState)(null);
|
|
3100
|
+
const [expandedId, setExpandedId] = (0, import_react15.useState)(null);
|
|
3101
|
+
const [sel, setSel] = (0, import_react15.useState)(/* @__PURE__ */ new Set());
|
|
3102
|
+
const [hiPriv, setHiPriv] = (0, import_react15.useState)(false);
|
|
3103
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react15.useState)(false);
|
|
3104
|
+
const [query, setQuery] = (0, import_react15.useState)("");
|
|
3105
|
+
const [typeFilter, setTypeFilter] = (0, import_react15.useState)("");
|
|
3106
|
+
const [sceneFilter, setSceneFilter] = (0, import_react15.useState)("");
|
|
3107
|
+
const [hallFilter, setHallFilter] = (0, import_react15.useState)("");
|
|
3108
|
+
const [last, setLast] = (0, import_react15.useState)({ query: "", type: "", scene: "", hall: "" });
|
|
3109
|
+
const seqRef = (0, import_react15.useRef)(0);
|
|
3110
|
+
const fetchPage = (0, import_react15.useCallback)(
|
|
2953
3111
|
(conds, offset, append) => {
|
|
2954
3112
|
setLoading(true);
|
|
2955
3113
|
setError(null);
|
|
@@ -2986,16 +3144,16 @@ var __defProp = Object.defineProperty;
|
|
|
2986
3144
|
setLast(conds);
|
|
2987
3145
|
fetchPage(conds, 0, false);
|
|
2988
3146
|
};
|
|
2989
|
-
(0,
|
|
3147
|
+
(0, import_react15.useEffect)(() => {
|
|
2990
3148
|
fetchPage({ query: "", type: "", scene: "", hall: "" }, 0, false);
|
|
2991
3149
|
}, [fetchPage]);
|
|
2992
|
-
const loadHiPriv = (0,
|
|
3150
|
+
const loadHiPriv = (0, import_react15.useCallback)(() => {
|
|
2993
3151
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
2994
3152
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
2995
3153
|
}).catch(() => {
|
|
2996
3154
|
});
|
|
2997
3155
|
}, [rpc]);
|
|
2998
|
-
(0,
|
|
3156
|
+
(0, import_react15.useEffect)(() => {
|
|
2999
3157
|
loadHiPriv();
|
|
3000
3158
|
}, [loadHiPriv]);
|
|
3001
3159
|
const toggleHiPriv = () => {
|
|
@@ -3056,9 +3214,9 @@ var __defProp = Object.defineProperty;
|
|
|
3056
3214
|
};
|
|
3057
3215
|
const countText = total !== null ? "共 " + total + " 条" : items.length + " 条" + (hasMore ? "+" : "");
|
|
3058
3216
|
const selCount = sel.size;
|
|
3059
|
-
return /* @__PURE__ */ (0,
|
|
3060
|
-
/* @__PURE__ */ (0,
|
|
3061
|
-
/* @__PURE__ */ (0,
|
|
3217
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
|
|
3218
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.toolbar, children: [
|
|
3219
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3062
3220
|
NInput,
|
|
3063
3221
|
{
|
|
3064
3222
|
style: { flex: 1, minWidth: 160 },
|
|
@@ -3072,7 +3230,7 @@ var __defProp = Object.defineProperty;
|
|
|
3072
3230
|
}
|
|
3073
3231
|
}
|
|
3074
3232
|
),
|
|
3075
|
-
/* @__PURE__ */ (0,
|
|
3233
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3076
3234
|
NSel,
|
|
3077
3235
|
{
|
|
3078
3236
|
style: { maxWidth: 200 },
|
|
@@ -3085,7 +3243,7 @@ var __defProp = Object.defineProperty;
|
|
|
3085
3243
|
onChange: setTypeFilter
|
|
3086
3244
|
}
|
|
3087
3245
|
),
|
|
3088
|
-
/* @__PURE__ */ (0,
|
|
3246
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3089
3247
|
NSel,
|
|
3090
3248
|
{
|
|
3091
3249
|
style: { maxWidth: 220 },
|
|
@@ -3098,7 +3256,7 @@ var __defProp = Object.defineProperty;
|
|
|
3098
3256
|
onChange: setSceneFilter
|
|
3099
3257
|
}
|
|
3100
3258
|
),
|
|
3101
|
-
/* @__PURE__ */ (0,
|
|
3259
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3102
3260
|
NSel,
|
|
3103
3261
|
{
|
|
3104
3262
|
style: { maxWidth: 150 },
|
|
@@ -3111,8 +3269,8 @@ var __defProp = Object.defineProperty;
|
|
|
3111
3269
|
onChange: setHallFilter
|
|
3112
3270
|
}
|
|
3113
3271
|
),
|
|
3114
|
-
/* @__PURE__ */ (0,
|
|
3115
|
-
/* @__PURE__ */ (0,
|
|
3272
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(NButton, { onClick: search, children: "搜索" }),
|
|
3273
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3116
3274
|
NButton,
|
|
3117
3275
|
{
|
|
3118
3276
|
style: {
|
|
@@ -3126,9 +3284,9 @@ var __defProp = Object.defineProperty;
|
|
|
3126
3284
|
}
|
|
3127
3285
|
)
|
|
3128
3286
|
] }),
|
|
3129
|
-
/* @__PURE__ */ (0,
|
|
3130
|
-
/* @__PURE__ */ (0,
|
|
3131
|
-
/* @__PURE__ */ (0,
|
|
3287
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
3288
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: S.muted, children: loading ? "加载中…" : countText }),
|
|
3289
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3132
3290
|
NButton,
|
|
3133
3291
|
{
|
|
3134
3292
|
style: selCount > 0 ? { color: "var(--dsh-mem-danger)" } : void 0,
|
|
@@ -3138,7 +3296,7 @@ var __defProp = Object.defineProperty;
|
|
|
3138
3296
|
children: "删除选中" + (selCount > 0 ? "(" + selCount + ")" : "")
|
|
3139
3297
|
}
|
|
3140
3298
|
),
|
|
3141
|
-
selCount > 0 ? /* @__PURE__ */ (0,
|
|
3299
|
+
selCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3142
3300
|
NButton,
|
|
3143
3301
|
{
|
|
3144
3302
|
onClick: () => {
|
|
@@ -3147,8 +3305,8 @@ var __defProp = Object.defineProperty;
|
|
|
3147
3305
|
children: "清空选择"
|
|
3148
3306
|
}
|
|
3149
3307
|
) : null,
|
|
3150
|
-
/* @__PURE__ */ (0,
|
|
3151
|
-
/* @__PURE__ */ (0,
|
|
3308
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.grow }),
|
|
3309
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3152
3310
|
NButton,
|
|
3153
3311
|
{
|
|
3154
3312
|
onClick: () => {
|
|
@@ -3158,13 +3316,13 @@ var __defProp = Object.defineProperty;
|
|
|
3158
3316
|
}
|
|
3159
3317
|
)
|
|
3160
3318
|
] }),
|
|
3161
|
-
!hiPriv ? /* @__PURE__ */ (0,
|
|
3162
|
-
error ? /* @__PURE__ */ (0,
|
|
3163
|
-
truncated ? /* @__PURE__ */ (0,
|
|
3164
|
-
items.length === 0 && !loading && !error ? /* @__PURE__ */ (0,
|
|
3319
|
+
!hiPriv ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.hint, children: "提示:删除记忆需先开启高权限模式(右上开关或概览页「高权限模式」),关闭时删除按钮不可用。" }) : null,
|
|
3320
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.error, children: error }) : null,
|
|
3321
|
+
truncated ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.hint, children: "搜索分页已达检索上限(200 条),更早的结果未显示。请用更精确的关键词或类型/情境过滤。" }) : null,
|
|
3322
|
+
items.length === 0 && !loading && !error ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { style: S.intro, children: "暂无记忆。对话几轮后,蒸馏管线会自动抽取记忆。" }) : items.map((m) => {
|
|
3165
3323
|
const open = expandedId === m.id;
|
|
3166
3324
|
const checked = sel.has(m.id);
|
|
3167
|
-
return /* @__PURE__ */ (0,
|
|
3325
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
3168
3326
|
"div",
|
|
3169
3327
|
{
|
|
3170
3328
|
className: "dsh-mem-card dsh-mem-card-hover",
|
|
@@ -3173,8 +3331,8 @@ var __defProp = Object.defineProperty;
|
|
|
3173
3331
|
setExpandedId(open ? null : m.id);
|
|
3174
3332
|
},
|
|
3175
3333
|
children: [
|
|
3176
|
-
/* @__PURE__ */ (0,
|
|
3177
|
-
/* @__PURE__ */ (0,
|
|
3334
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.cardHead, children: [
|
|
3335
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3178
3336
|
"input",
|
|
3179
3337
|
{
|
|
3180
3338
|
type: "checkbox",
|
|
@@ -3189,13 +3347,13 @@ var __defProp = Object.defineProperty;
|
|
|
3189
3347
|
}
|
|
3190
3348
|
}
|
|
3191
3349
|
),
|
|
3192
|
-
/* @__PURE__ */ (0,
|
|
3193
|
-
m.hall ? /* @__PURE__ */ (0,
|
|
3194
|
-
/* @__PURE__ */ (0,
|
|
3195
|
-
m.score !== null && m.score !== void 0 ? /* @__PURE__ */ (0,
|
|
3196
|
-
/* @__PURE__ */ (0,
|
|
3197
|
-
/* @__PURE__ */ (0,
|
|
3198
|
-
hiPriv ? /* @__PURE__ */ (0,
|
|
3350
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "dsh-mem-tag dsh-mem-tag-" + m.type, children: TYPE_LABELS[m.type] || m.type }),
|
|
3351
|
+
m.hall ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "dsh-mem-tag dsh-mem-tag-work-fact", children: "Hall · " + (HALL_LABEL[m.hall] || m.hall) }) : null,
|
|
3352
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: S.muted, children: "优先级 " + m.priority }),
|
|
3353
|
+
m.score !== null && m.score !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: S.muted, children: "相关度 " + Number(m.score).toFixed(2) }) : null,
|
|
3354
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.grow }),
|
|
3355
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: S.muted, children: fmtTime(m.updatedAt) }),
|
|
3356
|
+
hiPriv ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3199
3357
|
NButton,
|
|
3200
3358
|
{
|
|
3201
3359
|
style: { padding: "0 7px", minWidth: 26, height: 26, fontSize: 12, color: "var(--dsh-mem-danger)" },
|
|
@@ -3208,16 +3366,16 @@ var __defProp = Object.defineProperty;
|
|
|
3208
3366
|
}
|
|
3209
3367
|
) : null
|
|
3210
3368
|
] }),
|
|
3211
|
-
/* @__PURE__ */ (0,
|
|
3212
|
-
open ? /* @__PURE__ */ (0,
|
|
3369
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.content, children: m.content }),
|
|
3370
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.detail, children: "id: " + m.id + "\n情境: " + (m.scene || "-") + "\n版本: v" + m.version + "(去重合并次数 " + m.version + ")\n创建: " + fmtTime(m.createdAt) + "\n活跃时间: " + (m.timestamps && m.timestamps.length > 0 ? m.timestamps.map(fmtTime).join(" → ") : "-") + "\n" + (m.sourceMessageIds && m.sourceMessageIds.length > 0 ? "来源消息: " + m.sourceMessageIds.join(", ") : "来源消息: -") }) : null
|
|
3213
3371
|
]
|
|
3214
3372
|
},
|
|
3215
3373
|
m.id
|
|
3216
3374
|
);
|
|
3217
3375
|
}),
|
|
3218
|
-
hasMore ? /* @__PURE__ */ (0,
|
|
3219
|
-
/* @__PURE__ */ (0,
|
|
3220
|
-
/* @__PURE__ */ (0,
|
|
3376
|
+
hasMore ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.flexRow, children: [
|
|
3377
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.grow }),
|
|
3378
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3221
3379
|
NButton,
|
|
3222
3380
|
{
|
|
3223
3381
|
disabled: loading,
|
|
@@ -3232,13 +3390,13 @@ var __defProp = Object.defineProperty;
|
|
|
3232
3390
|
}
|
|
3233
3391
|
|
|
3234
3392
|
// client/src/tabs/ScenesTab.tsx
|
|
3235
|
-
var
|
|
3236
|
-
var
|
|
3393
|
+
var import_react16 = require("react");
|
|
3394
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3237
3395
|
function SceneCard(props) {
|
|
3238
3396
|
const s = props.s;
|
|
3239
|
-
const [open, setOpen] = (0,
|
|
3240
|
-
return /* @__PURE__ */ (0,
|
|
3241
|
-
/* @__PURE__ */ (0,
|
|
3397
|
+
const [open, setOpen] = (0, import_react16.useState)(false);
|
|
3398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "dsh-mem-card dsh-mem-card-hover", style: S.card, children: [
|
|
3399
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3242
3400
|
"div",
|
|
3243
3401
|
{
|
|
3244
3402
|
style: { ...S.sceneHead, cursor: "pointer", userSelect: "none" },
|
|
@@ -3246,23 +3404,23 @@ var __defProp = Object.defineProperty;
|
|
|
3246
3404
|
setOpen(!open);
|
|
3247
3405
|
},
|
|
3248
3406
|
children: [
|
|
3249
|
-
/* @__PURE__ */ (0,
|
|
3250
|
-
/* @__PURE__ */ (0,
|
|
3251
|
-
s.heat ? /* @__PURE__ */ (0,
|
|
3252
|
-
/* @__PURE__ */ (0,
|
|
3253
|
-
/* @__PURE__ */ (0,
|
|
3407
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "dsh-mem-scene-chev", style: { transform: open ? "rotate(90deg)" : "none" }, children: "▸" }),
|
|
3408
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.sceneTitle, children: s.path }),
|
|
3409
|
+
s.heat ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: "热度 " + s.heat }) : null,
|
|
3410
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.grow }),
|
|
3411
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: "更新 " + fmtTime(s.updated) })
|
|
3254
3412
|
]
|
|
3255
3413
|
}
|
|
3256
3414
|
),
|
|
3257
|
-
s.summary ? /* @__PURE__ */ (0,
|
|
3258
|
-
open ? /* @__PURE__ */ (0,
|
|
3415
|
+
s.summary ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { ...S.muted, marginBottom: 6 }, children: s.summary }) : null,
|
|
3416
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("pre", { style: S.pre, children: s.content || "(空)" }) : null
|
|
3259
3417
|
] });
|
|
3260
3418
|
}
|
|
3261
3419
|
function ScenesTab(props) {
|
|
3262
3420
|
const rpc = props.rpc;
|
|
3263
|
-
const [items, setItems] = (0,
|
|
3264
|
-
const [error, setError] = (0,
|
|
3265
|
-
const load = (0,
|
|
3421
|
+
const [items, setItems] = (0, import_react16.useState)(null);
|
|
3422
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
3423
|
+
const load = (0, import_react16.useCallback)(() => {
|
|
3266
3424
|
rpc("dsh-memory/scenes", {}).then((r) => {
|
|
3267
3425
|
if (r && r.ok) {
|
|
3268
3426
|
setItems(r.value.items);
|
|
@@ -3272,28 +3430,29 @@ var __defProp = Object.defineProperty;
|
|
|
3272
3430
|
setError(String(e && e.message || e));
|
|
3273
3431
|
});
|
|
3274
3432
|
}, [rpc]);
|
|
3275
|
-
(0,
|
|
3433
|
+
(0, import_react16.useEffect)(() => {
|
|
3276
3434
|
load();
|
|
3277
3435
|
}, [load]);
|
|
3278
|
-
return /* @__PURE__ */ (0,
|
|
3279
|
-
/* @__PURE__ */ (0,
|
|
3280
|
-
/* @__PURE__ */ (0,
|
|
3281
|
-
/* @__PURE__ */ (0,
|
|
3282
|
-
/* @__PURE__ */ (0,
|
|
3436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
3437
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
3438
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: items ? items.length + " 个场景块" : "加载中…" }),
|
|
3439
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.grow }),
|
|
3440
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
3283
3441
|
] }),
|
|
3284
|
-
error ? /* @__PURE__ */ (0,
|
|
3285
|
-
items && items.length === 0 ? /* @__PURE__ */ (0,
|
|
3442
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.error, children: error }) : null,
|
|
3443
|
+
items && items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { style: S.intro, children: "暂无场景块。累计 5 条新记忆后 L2 会自动整合出第一个场景。" }) : null,
|
|
3286
3444
|
(items || []).map((s) => {
|
|
3287
|
-
return /* @__PURE__ */ (0,
|
|
3445
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SceneCard, { s }, s.path);
|
|
3288
3446
|
})
|
|
3289
3447
|
] });
|
|
3290
3448
|
}
|
|
3291
3449
|
|
|
3292
3450
|
// client/src/panel.tsx
|
|
3293
|
-
var
|
|
3451
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3294
3452
|
var TABS = [
|
|
3295
3453
|
["overview", "概览"],
|
|
3296
3454
|
["records", "记忆"],
|
|
3455
|
+
["conflicts", "冲突"],
|
|
3297
3456
|
["scenes", "场景"],
|
|
3298
3457
|
["persona", "画像"],
|
|
3299
3458
|
["cost", "成本"],
|
|
@@ -3301,23 +3460,24 @@ var __defProp = Object.defineProperty;
|
|
|
3301
3460
|
];
|
|
3302
3461
|
function MemoryPanel(props) {
|
|
3303
3462
|
const rpc = props.rpc;
|
|
3304
|
-
const [tab, setTab] = (0,
|
|
3463
|
+
const [tab, setTab] = (0, import_react17.useState)("overview");
|
|
3305
3464
|
ensureThemeStyle();
|
|
3306
|
-
(0,
|
|
3465
|
+
(0, import_react17.useEffect)(() => {
|
|
3307
3466
|
watchSidebarIcon();
|
|
3308
3467
|
}, []);
|
|
3309
3468
|
let body;
|
|
3310
|
-
if (tab === "overview") body = /* @__PURE__ */ (0,
|
|
3311
|
-
else if (tab === "records") body = /* @__PURE__ */ (0,
|
|
3312
|
-
else if (tab === "
|
|
3313
|
-
else if (tab === "
|
|
3314
|
-
else if (tab === "
|
|
3315
|
-
else body = /* @__PURE__ */ (0,
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
/* @__PURE__ */ (0,
|
|
3319
|
-
/* @__PURE__ */ (0,
|
|
3320
|
-
|
|
3469
|
+
if (tab === "overview") body = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(OverviewTab, { rpc });
|
|
3470
|
+
else if (tab === "records") body = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RecordsTab, { rpc });
|
|
3471
|
+
else if (tab === "conflicts") body = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ConflictsTab, { rpc });
|
|
3472
|
+
else if (tab === "scenes") body = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ScenesTab, { rpc });
|
|
3473
|
+
else if (tab === "persona") body = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(PersonaTab, { rpc });
|
|
3474
|
+
else if (tab === "cost") body = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CostTab, { rpc });
|
|
3475
|
+
else body = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(LogTab, { rpc });
|
|
3476
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "dsh-mem-root", style: S.section, children: [
|
|
3477
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { style: S.heading, children: "记忆 (Memory)" }),
|
|
3478
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: S.intro, children: "L0~L3 分层蒸馏记忆:浏览被记住的内容,控制记忆模式开关。" }),
|
|
3479
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.tabbar, children: TABS.map((t) => {
|
|
3480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3321
3481
|
"button",
|
|
3322
3482
|
{
|
|
3323
3483
|
className: tab === t[0] ? "dsh-mem-tab dsh-mem-tab-on" : "dsh-mem-tab",
|
|
@@ -3334,7 +3494,7 @@ var __defProp = Object.defineProperty;
|
|
|
3334
3494
|
}
|
|
3335
3495
|
|
|
3336
3496
|
// client/src/pill/MemoryModePill.tsx
|
|
3337
|
-
var
|
|
3497
|
+
var import_react20 = require("react");
|
|
3338
3498
|
|
|
3339
3499
|
// src/util/context-occupancy.ts
|
|
3340
3500
|
var CONTEXT_METER_CIRCUMFERENCE = 34.55751918948772;
|
|
@@ -3650,23 +3810,23 @@ var __defProp = Object.defineProperty;
|
|
|
3650
3810
|
}
|
|
3651
3811
|
|
|
3652
3812
|
// client/src/pill/ModeSlider.tsx
|
|
3653
|
-
var
|
|
3813
|
+
var import_react19 = require("react");
|
|
3654
3814
|
|
|
3655
3815
|
// client/src/pill/SessionInfoArea.tsx
|
|
3656
|
-
var
|
|
3657
|
-
var
|
|
3816
|
+
var import_react18 = require("react");
|
|
3817
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3658
3818
|
function sinfoCell(val, label, title) {
|
|
3659
|
-
return /* @__PURE__ */ (0,
|
|
3660
|
-
/* @__PURE__ */ (0,
|
|
3661
|
-
/* @__PURE__ */ (0,
|
|
3819
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { title: title || void 0, children: [
|
|
3820
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "dsh-mem-sinfo-val", children: val }),
|
|
3821
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "dsh-mem-sinfo-label", children: label })
|
|
3662
3822
|
] });
|
|
3663
3823
|
}
|
|
3664
3824
|
function SessionInfoArea(props) {
|
|
3665
3825
|
const rpc = props.rpc;
|
|
3666
3826
|
const sessionId = props.sessionId;
|
|
3667
|
-
const [stats, setStats] = (0,
|
|
3668
|
-
const busyRef = (0,
|
|
3669
|
-
(0,
|
|
3827
|
+
const [stats, setStats] = (0, import_react18.useState)(void 0);
|
|
3828
|
+
const busyRef = (0, import_react18.useRef)(false);
|
|
3829
|
+
(0, import_react18.useEffect)(() => {
|
|
3670
3830
|
if (!rpc || !sessionId) return void 0;
|
|
3671
3831
|
let alive = true;
|
|
3672
3832
|
let timer = null;
|
|
@@ -3699,7 +3859,7 @@ var __defProp = Object.defineProperty;
|
|
|
3699
3859
|
}, [rpc, sessionId]);
|
|
3700
3860
|
if (stats === null) return null;
|
|
3701
3861
|
if (stats === void 0) {
|
|
3702
|
-
return /* @__PURE__ */ (0,
|
|
3862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "dsh-mem-sinfo", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "dsh-mem-sinfo-grid", children: [
|
|
3703
3863
|
sinfoCell("…", "召回命中"),
|
|
3704
3864
|
sinfoCell("…", "攒批进度"),
|
|
3705
3865
|
sinfoCell("…", "本会话记忆"),
|
|
@@ -3748,27 +3908,27 @@ var __defProp = Object.defineProperty;
|
|
|
3748
3908
|
else if (stats.retrieval === "none") note = "检索不可用(FTS 与向量均失效)";
|
|
3749
3909
|
}
|
|
3750
3910
|
const ago = fmtAgo(gl.lastExtractAt);
|
|
3751
|
-
return /* @__PURE__ */ (0,
|
|
3752
|
-
warn ? /* @__PURE__ */ (0,
|
|
3753
|
-
/* @__PURE__ */ (0,
|
|
3911
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "dsh-mem-sinfo", children: [
|
|
3912
|
+
warn ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "dsh-mem-sinfo-warn", children: warn }) : null,
|
|
3913
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "dsh-mem-sinfo-grid", children: [
|
|
3754
3914
|
sinfoCell(rcVal, rcLabel, rcTitle),
|
|
3755
3915
|
sinfoCell(dVal, dLabel, dTitle),
|
|
3756
3916
|
sinfoCell(String(di.producedRecords || 0), "本会话记忆", pTitle),
|
|
3757
3917
|
sinfoCell(stats.l0Count != null ? String(stats.l0Count) : "…", "会话消息")
|
|
3758
3918
|
] }),
|
|
3759
|
-
note ? /* @__PURE__ */ (0,
|
|
3760
|
-
/* @__PURE__ */ (0,
|
|
3919
|
+
note ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "dsh-mem-sinfo-note", children: note }) : null,
|
|
3920
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "dsh-mem-sinfo-sum", children: "待蒸馏 " + (gl.pendingTotal || 0) + " · 上次蒸馏 " + (ago || "尚未蒸馏") })
|
|
3761
3921
|
] });
|
|
3762
3922
|
}
|
|
3763
3923
|
|
|
3764
3924
|
// client/src/pill/ModeSlider.tsx
|
|
3765
|
-
var
|
|
3925
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3766
3926
|
function ModeSlider(props) {
|
|
3767
3927
|
ensureThemeStyle();
|
|
3768
|
-
const trackRef = (0,
|
|
3769
|
-
const [drag, setDrag] = (0,
|
|
3770
|
-
const canvasRef = (0,
|
|
3771
|
-
const geoRef = (0,
|
|
3928
|
+
const trackRef = (0, import_react19.useRef)(null);
|
|
3929
|
+
const [drag, setDrag] = (0, import_react19.useState)(null);
|
|
3930
|
+
const canvasRef = (0, import_react19.useRef)(null);
|
|
3931
|
+
const geoRef = (0, import_react19.useRef)(null);
|
|
3772
3932
|
const clampX = (x) => {
|
|
3773
3933
|
if (x < 0) return 0;
|
|
3774
3934
|
if (x > INNER_W) return INNER_W;
|
|
@@ -3816,7 +3976,7 @@ var __defProp = Object.defineProperty;
|
|
|
3816
3976
|
// 与填充显隐同源
|
|
3817
3977
|
dragging: drag !== null
|
|
3818
3978
|
};
|
|
3819
|
-
(0,
|
|
3979
|
+
(0, import_react19.useEffect)(() => {
|
|
3820
3980
|
const canvas = canvasRef.current;
|
|
3821
3981
|
if (!canvas) return void 0;
|
|
3822
3982
|
const ctx = canvas.getContext && canvas.getContext("2d");
|
|
@@ -3922,10 +4082,10 @@ var __defProp = Object.defineProperty;
|
|
|
3922
4082
|
themeObs.disconnect();
|
|
3923
4083
|
};
|
|
3924
4084
|
}, []);
|
|
3925
|
-
const popRef = (0,
|
|
3926
|
-
const shiftRef = (0,
|
|
3927
|
-
const [shiftX, setShiftX] = (0,
|
|
3928
|
-
(0,
|
|
4085
|
+
const popRef = (0, import_react19.useRef)(null);
|
|
4086
|
+
const shiftRef = (0, import_react19.useRef)(0);
|
|
4087
|
+
const [shiftX, setShiftX] = (0, import_react19.useState)(0);
|
|
4088
|
+
(0, import_react19.useLayoutEffect)(() => {
|
|
3929
4089
|
const clamp = () => {
|
|
3930
4090
|
const el = popRef.current;
|
|
3931
4091
|
if (!el) return;
|
|
@@ -3955,7 +4115,7 @@ var __defProp = Object.defineProperty;
|
|
|
3955
4115
|
for (let i = 0; i < MODES.length; i++) {
|
|
3956
4116
|
const stopLeft = i / (MODES.length - 1) * INNER_W + THUMB / 2;
|
|
3957
4117
|
stops.push(
|
|
3958
|
-
/* @__PURE__ */ (0,
|
|
4118
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3959
4119
|
"div",
|
|
3960
4120
|
{
|
|
3961
4121
|
style: {
|
|
@@ -3974,7 +4134,7 @@ var __defProp = Object.defineProperty;
|
|
|
3974
4134
|
)
|
|
3975
4135
|
);
|
|
3976
4136
|
}
|
|
3977
|
-
return /* @__PURE__ */ (0,
|
|
4137
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3978
4138
|
"div",
|
|
3979
4139
|
{
|
|
3980
4140
|
ref: popRef,
|
|
@@ -3985,13 +4145,13 @@ var __defProp = Object.defineProperty;
|
|
|
3985
4145
|
transform: "translateX(calc(-50% + " + shiftX + "px))",
|
|
3986
4146
|
zIndex: 1e3
|
|
3987
4147
|
},
|
|
3988
|
-
children: /* @__PURE__ */ (0,
|
|
4148
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3989
4149
|
"div",
|
|
3990
4150
|
{
|
|
3991
4151
|
className: "dsh-mem-popover",
|
|
3992
4152
|
style: { position: "relative", padding: "14px 16px" },
|
|
3993
4153
|
children: [
|
|
3994
|
-
/* @__PURE__ */ (0,
|
|
4154
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3995
4155
|
"div",
|
|
3996
4156
|
{
|
|
3997
4157
|
ref: trackRef,
|
|
@@ -4011,7 +4171,7 @@ var __defProp = Object.defineProperty;
|
|
|
4011
4171
|
onPointerUp,
|
|
4012
4172
|
onPointerCancel: onPointerUp,
|
|
4013
4173
|
children: [
|
|
4014
|
-
activeIdx > 0 || drag !== null ? /* @__PURE__ */ (0,
|
|
4174
|
+
activeIdx > 0 || drag !== null ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4015
4175
|
"div",
|
|
4016
4176
|
{
|
|
4017
4177
|
style: {
|
|
@@ -4029,7 +4189,7 @@ var __defProp = Object.defineProperty;
|
|
|
4029
4189
|
}
|
|
4030
4190
|
) : null,
|
|
4031
4191
|
stops,
|
|
4032
|
-
/* @__PURE__ */ (0,
|
|
4192
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4033
4193
|
"canvas",
|
|
4034
4194
|
{
|
|
4035
4195
|
ref: canvasRef,
|
|
@@ -4046,7 +4206,7 @@ var __defProp = Object.defineProperty;
|
|
|
4046
4206
|
}
|
|
4047
4207
|
}
|
|
4048
4208
|
),
|
|
4049
|
-
/* @__PURE__ */ (0,
|
|
4209
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4050
4210
|
"div",
|
|
4051
4211
|
{
|
|
4052
4212
|
style: {
|
|
@@ -4065,12 +4225,12 @@ var __defProp = Object.defineProperty;
|
|
|
4065
4225
|
}
|
|
4066
4226
|
}
|
|
4067
4227
|
),
|
|
4068
|
-
drag !== null ? /* @__PURE__ */ (0,
|
|
4228
|
+
drag !== null ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "dsh-mem-bubble", style: { left: thumbLeft + THUMB / 2, zIndex: 4 }, children: info.label }) : null
|
|
4069
4229
|
]
|
|
4070
4230
|
}
|
|
4071
4231
|
),
|
|
4072
|
-
props.error ? /* @__PURE__ */ (0,
|
|
4073
|
-
props.recall !== void 0 && props.onCommitRecall ? /* @__PURE__ */ (0,
|
|
4232
|
+
props.error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-danger)", marginTop: 10, whiteSpace: "nowrap" }, children: props.error }) : null,
|
|
4233
|
+
props.recall !== void 0 && props.onCommitRecall ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4074
4234
|
"div",
|
|
4075
4235
|
{
|
|
4076
4236
|
style: {
|
|
@@ -4083,8 +4243,8 @@ var __defProp = Object.defineProperty;
|
|
|
4083
4243
|
gap: 8
|
|
4084
4244
|
},
|
|
4085
4245
|
children: [
|
|
4086
|
-
/* @__PURE__ */ (0,
|
|
4087
|
-
/* @__PURE__ */ (0,
|
|
4246
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)" }, children: "注入" }),
|
|
4247
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4088
4248
|
Segmented,
|
|
4089
4249
|
{
|
|
4090
4250
|
value: props.recall === null ? "follow" : props.recall ? "on" : "off",
|
|
@@ -4100,7 +4260,7 @@ var __defProp = Object.defineProperty;
|
|
|
4100
4260
|
]
|
|
4101
4261
|
}
|
|
4102
4262
|
) : null,
|
|
4103
|
-
props.rpc && props.sessionId ? /* @__PURE__ */ (0,
|
|
4263
|
+
props.rpc && props.sessionId ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SessionInfoArea, { rpc: props.rpc, sessionId: props.sessionId }) : null
|
|
4104
4264
|
]
|
|
4105
4265
|
}
|
|
4106
4266
|
)
|
|
@@ -4109,18 +4269,18 @@ var __defProp = Object.defineProperty;
|
|
|
4109
4269
|
}
|
|
4110
4270
|
|
|
4111
4271
|
// client/src/pill/MemoryModePill.tsx
|
|
4112
|
-
var
|
|
4272
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4113
4273
|
function MemoryModePill(props) {
|
|
4114
4274
|
const rpc = props.rpc;
|
|
4115
4275
|
const sessionId = props.sessionId || props.session && props.session.sessionId;
|
|
4116
|
-
const [mode, setMode] = (0,
|
|
4117
|
-
const [recall, setRecall] = (0,
|
|
4118
|
-
const [recallResolved, setRecallResolved] = (0,
|
|
4119
|
-
const [error, setError] = (0,
|
|
4120
|
-
const [open, setOpen] = (0,
|
|
4121
|
-
const wrapRef = (0,
|
|
4122
|
-
const seqRef = (0,
|
|
4123
|
-
const load = (0,
|
|
4276
|
+
const [mode, setMode] = (0, import_react20.useState)(null);
|
|
4277
|
+
const [recall, setRecall] = (0, import_react20.useState)(null);
|
|
4278
|
+
const [recallResolved, setRecallResolved] = (0, import_react20.useState)(true);
|
|
4279
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
4280
|
+
const [open, setOpen] = (0, import_react20.useState)(false);
|
|
4281
|
+
const wrapRef = (0, import_react20.useRef)(null);
|
|
4282
|
+
const seqRef = (0, import_react20.useRef)(0);
|
|
4283
|
+
const load = (0, import_react20.useCallback)(() => {
|
|
4124
4284
|
if (!sessionId || !rpc) return;
|
|
4125
4285
|
const token = ++seqRef.current;
|
|
4126
4286
|
setError(null);
|
|
@@ -4136,13 +4296,13 @@ var __defProp = Object.defineProperty;
|
|
|
4136
4296
|
setError(String(e && e.message || e));
|
|
4137
4297
|
});
|
|
4138
4298
|
}, [sessionId, rpc]);
|
|
4139
|
-
(0,
|
|
4299
|
+
(0, import_react20.useEffect)(() => {
|
|
4140
4300
|
load();
|
|
4141
4301
|
}, [load]);
|
|
4142
|
-
(0,
|
|
4302
|
+
(0, import_react20.useEffect)(() => {
|
|
4143
4303
|
watchSidebarIcon();
|
|
4144
4304
|
}, []);
|
|
4145
|
-
(0,
|
|
4305
|
+
(0, import_react20.useEffect)(() => {
|
|
4146
4306
|
initOccupancyIndicator(
|
|
4147
4307
|
(endpoint, payload) => rpc(endpoint, payload)
|
|
4148
4308
|
);
|
|
@@ -4150,7 +4310,7 @@ var __defProp = Object.defineProperty;
|
|
|
4150
4310
|
watchContextMeter();
|
|
4151
4311
|
noteOccupancySession(sessionId ?? null);
|
|
4152
4312
|
}, [sessionId, rpc]);
|
|
4153
|
-
(0,
|
|
4313
|
+
(0, import_react20.useEffect)(() => {
|
|
4154
4314
|
if (!open) return;
|
|
4155
4315
|
const onDown = (e) => {
|
|
4156
4316
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -4236,8 +4396,8 @@ var __defProp = Object.defineProperty;
|
|
|
4236
4396
|
pillStyle.boxShadow = "0 0 12px color-mix(in srgb, " + info.color + " 30%, transparent)";
|
|
4237
4397
|
pillStyle["--dsh-mem-pill-tint"] = info.color;
|
|
4238
4398
|
}
|
|
4239
|
-
return /* @__PURE__ */ (0,
|
|
4240
|
-
/* @__PURE__ */ (0,
|
|
4399
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { ref: wrapRef, style: { position: "relative", display: "inline-flex" }, children: [
|
|
4400
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
4241
4401
|
"button",
|
|
4242
4402
|
{
|
|
4243
4403
|
type: "button",
|
|
@@ -4250,11 +4410,11 @@ var __defProp = Object.defineProperty;
|
|
|
4250
4410
|
style: pillStyle,
|
|
4251
4411
|
children: [
|
|
4252
4412
|
"记忆 · ",
|
|
4253
|
-
/* @__PURE__ */ (0,
|
|
4413
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: faceLabel })
|
|
4254
4414
|
]
|
|
4255
4415
|
}
|
|
4256
4416
|
),
|
|
4257
|
-
open ? /* @__PURE__ */ (0,
|
|
4417
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4258
4418
|
ModeSlider,
|
|
4259
4419
|
{
|
|
4260
4420
|
mode: mode || "auto",
|
|
@@ -4271,25 +4431,36 @@ var __defProp = Object.defineProperty;
|
|
|
4271
4431
|
|
|
4272
4432
|
// client/src/entry.tsx
|
|
4273
4433
|
var inject = ["slots"];
|
|
4434
|
+
var SETTINGS_SEAT = "settings.section";
|
|
4435
|
+
var SEAT_PROBE_MS = 3e3;
|
|
4274
4436
|
function apply(ctx) {
|
|
4275
4437
|
const rpc = makeRpc(ctx);
|
|
4276
4438
|
console.info("[dsh-prime-memory] client apply: slots 注入就绪,注册 UI 槽位");
|
|
4439
|
+
const SETTINGS_SEAT2 = "settings.section";
|
|
4440
|
+
let cardSeatLive = false;
|
|
4277
4441
|
try {
|
|
4278
|
-
ctx.slots.inject(
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
id: "dsh-memory",
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
}
|
|
4287
|
-
|
|
4288
|
-
|
|
4442
|
+
ctx.slots.inject(SETTINGS_SEAT2, () => {
|
|
4443
|
+
cardSeatLive = true;
|
|
4444
|
+
try {
|
|
4445
|
+
return ctx.slots.register(
|
|
4446
|
+
{ name: SETTINGS_SEAT2, id: "dsh-memory", order: 200, label: "记忆", inject: () => ({ rpc }) },
|
|
4447
|
+
MemoryPanel
|
|
4448
|
+
);
|
|
4449
|
+
} catch (err) {
|
|
4450
|
+
console.warn(`[dsh-prime-memory] ${SETTINGS_SEAT2} 注册失败:`, err);
|
|
4451
|
+
return () => {
|
|
4452
|
+
};
|
|
4453
|
+
}
|
|
4289
4454
|
});
|
|
4290
4455
|
} catch (err) {
|
|
4291
|
-
console.warn(
|
|
4456
|
+
console.warn(`[dsh-prime-memory] ${SETTINGS_SEAT2} 槽位未声明:`, err);
|
|
4292
4457
|
}
|
|
4458
|
+
setTimeout(() => {
|
|
4459
|
+
if (cardSeatLive) return;
|
|
4460
|
+
console.warn(
|
|
4461
|
+
`[dsh-prime-memory] 宿主未声明 ${SETTINGS_SEAT2}:设置里的「记忆」面板不会出现。(0.1.5 的座位集合本机未验证,请在真机上确认。)`
|
|
4462
|
+
);
|
|
4463
|
+
}, SEAT_PROBE_MS);
|
|
4293
4464
|
try {
|
|
4294
4465
|
ctx.slots.inject("conversation.input.left", () => {
|
|
4295
4466
|
return ctx.slots.register(
|