dsh-prime-memory 0.22.2 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.en.md +401 -0
- package/CHANGELOG.ja.md +401 -0
- package/CHANGELOG.ko.md +401 -0
- package/CHANGELOG.md +100 -0
- package/dist/client.js +1180 -845
- package/dist/config.d.ts +128 -1341
- package/dist/config.js +80 -4
- package/dist/conflict-service.d.ts +4 -0
- package/dist/conflict-service.js +6 -1
- package/dist/contract.d.ts +196 -0
- package/dist/domain-gate.d.ts +11 -0
- package/dist/domain-gate.js +15 -0
- package/dist/hooks/obsolete-notice.d.ts +26 -0
- package/dist/hooks/obsolete-notice.js +64 -0
- package/dist/hooks/recall.d.ts +39 -0
- package/dist/hooks/recall.js +110 -30
- package/dist/index.d.ts +1 -1127
- package/dist/index.js +30 -2
- package/dist/memory-types.d.ts +69 -0
- package/dist/memory-types.js +165 -0
- package/dist/memport/format.d.ts +6 -1
- package/dist/memport/format.js +42 -2
- package/dist/pipeline/l1.d.ts +44 -2
- package/dist/pipeline/l1.js +163 -9
- package/dist/pipeline/md-sync.d.ts +65 -0
- package/dist/pipeline/md-sync.js +456 -0
- package/dist/pipeline/ruminate.d.ts +43 -1
- package/dist/pipeline/ruminate.js +100 -0
- package/dist/pipeline/runner.d.ts +10 -0
- package/dist/pipeline/runner.js +7 -1
- package/dist/pipeline/workspace-relink.d.ts +60 -0
- package/dist/pipeline/workspace-relink.js +73 -0
- package/dist/projection/recall.d.ts +51 -13
- package/dist/projection/recall.js +47 -12
- package/dist/prompts/examples.d.ts +73 -0
- package/dist/prompts/examples.js +178 -0
- package/dist/prompts/l1-dedup.d.ts +9 -3
- package/dist/prompts/l1-dedup.js +34 -13
- package/dist/prompts/l1-extraction.d.ts +5 -3
- package/dist/prompts/l1-extraction.js +49 -4
- package/dist/settings.d.ts +8 -0
- package/dist/settings.js +12 -1
- package/dist/stats.d.ts +12 -0
- package/dist/stats.js +327 -15
- package/dist/store/embedding-source.d.ts +8 -0
- package/dist/store/embedding-source.js +39 -2
- package/dist/store/file-versions.d.ts +2 -0
- package/dist/store/file-versions.js +2 -0
- package/dist/store/graph-store.d.ts +14 -0
- package/dist/store/graph-store.js +35 -0
- package/dist/store/l1-snapshot.d.ts +26 -1
- package/dist/store/l1-snapshot.js +53 -8
- package/dist/store/l1.d.ts +75 -3
- package/dist/store/l1.js +124 -3
- package/dist/store/memory-md-archive.d.ts +84 -0
- package/dist/store/memory-md-archive.js +155 -0
- package/dist/store/memory-md-disable.d.ts +23 -0
- package/dist/store/memory-md-disable.js +106 -0
- package/dist/store/memory-md-export.d.ts +50 -0
- package/dist/store/memory-md-export.js +200 -0
- package/dist/store/memory-md-ledger.d.ts +94 -0
- package/dist/store/memory-md-ledger.js +243 -0
- package/dist/store/memory-md-orphan.d.ts +27 -0
- package/dist/store/memory-md-orphan.js +153 -0
- package/dist/store/memory-md-parse.d.ts +35 -0
- package/dist/store/memory-md-parse.js +85 -0
- package/dist/store/memory-md-skeleton.d.ts +18 -0
- package/dist/store/memory-md-skeleton.js +61 -0
- package/dist/store/memory-md-types.d.ts +174 -0
- package/dist/store/memory-md-types.js +10 -0
- package/dist/store/memory-md.d.ts +108 -0
- package/dist/store/memory-md.js +219 -0
- package/dist/store/obsolete-notices.d.ts +39 -0
- package/dist/store/obsolete-notices.js +153 -0
- package/dist/store/recall-feedback.d.ts +75 -0
- package/dist/store/recall-feedback.js +213 -0
- package/dist/store/recall-usage.d.ts +11 -0
- package/dist/store/recall-usage.js +29 -0
- package/dist/store/session-recalled.d.ts +38 -3
- package/dist/store/session-recalled.js +156 -9
- package/dist/store/sqlite.d.ts +66 -0
- package/dist/store/sqlite.js +233 -15
- package/dist/store/supersede.d.ts +1 -1
- package/dist/store/supersede.js +1 -1
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.js +23 -6
- package/dist/types.d.ts +24 -7
- package/dist/types.js +10 -2
- package/dist/util/maturity.d.ts +20 -3
- package/dist/util/maturity.js +18 -1
- package/dist/util/md-name.d.ts +129 -0
- package/dist/util/md-name.js +366 -0
- package/dist/util/md-normalize.d.ts +23 -0
- package/dist/util/md-normalize.js +131 -0
- package/dist/workspace-route.d.ts +22 -0
- package/dist/workspace-route.js +66 -0
- package/dsh.plugin.json +1 -1
- package/package.json +6 -5
package/dist/client.js
CHANGED
|
@@ -32,7 +32,7 @@ var __defProp = Object.defineProperty;
|
|
|
32
32
|
module.exports = __toCommonJS(entry_exports);
|
|
33
33
|
|
|
34
34
|
// client/src/panel.tsx
|
|
35
|
-
var
|
|
35
|
+
var import_react22 = require("react");
|
|
36
36
|
|
|
37
37
|
// client/src/sidebar-icon.ts
|
|
38
38
|
var BOOK_ICON_SVG = '<svg data-mem-icon="1" viewBox="0 0 16 16" width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" style="flex-shrink:0"><path d="M8 3.4C6.6 2.5 4.6 2.4 2.9 3.1v9.3c1.7-.7 3.7-.6 5.1.3 1.4-.9 3.4-1 5.1-.3V3.1C11.4 2.4 9.4 2.5 8 3.4Z" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/><path d="M8 3.4v9.3" stroke="currentColor" stroke-width="1.2"/></svg>';
|
|
@@ -264,6 +264,108 @@ var __defProp = Object.defineProperty;
|
|
|
264
264
|
sceneTitle: { fontSize: 13, fontWeight: 600, fontFamily: "ui-monospace, Consolas, monospace", color: "var(--dsh-mem-text-1)" }
|
|
265
265
|
};
|
|
266
266
|
|
|
267
|
+
// src/memory-types.ts
|
|
268
|
+
var HOST_MEMORY_TYPES = [
|
|
269
|
+
// —— 个人可见(chat 族):用户画像的四类 ——
|
|
270
|
+
"user_info",
|
|
271
|
+
"user_hobby",
|
|
272
|
+
"user_communication",
|
|
273
|
+
"user_behavior",
|
|
274
|
+
// —— 项目轴(work 族)——
|
|
275
|
+
"project_introduction",
|
|
276
|
+
"project_tech_stack",
|
|
277
|
+
"project_architecture",
|
|
278
|
+
"project_build_configuration",
|
|
279
|
+
"project_dependency_configuration",
|
|
280
|
+
"project_ide_configuration",
|
|
281
|
+
"project_scm_configuration",
|
|
282
|
+
"project_environment_configuration",
|
|
283
|
+
"project_rule",
|
|
284
|
+
// —— 开发规范轴(work 族)——
|
|
285
|
+
"development_code_specification",
|
|
286
|
+
"development_practice_specification",
|
|
287
|
+
"development_test_specification",
|
|
288
|
+
"development_comment_specification",
|
|
289
|
+
// —— 经验轴(work 族)——
|
|
290
|
+
"task_summary_experience",
|
|
291
|
+
"task_breakdown_experience",
|
|
292
|
+
"task_flow_experience",
|
|
293
|
+
"task_experience",
|
|
294
|
+
"tool_experience",
|
|
295
|
+
"mcp_experience",
|
|
296
|
+
"skill_experience",
|
|
297
|
+
"learned_skill_experience",
|
|
298
|
+
"expert_experience",
|
|
299
|
+
"important_decision_experience",
|
|
300
|
+
"common_pitfalls_experience",
|
|
301
|
+
"history_task_reference_files"
|
|
302
|
+
];
|
|
303
|
+
var LEGACY_MEMORY_TYPES = [
|
|
304
|
+
"persona",
|
|
305
|
+
"episodic",
|
|
306
|
+
"instruction",
|
|
307
|
+
"work_fact",
|
|
308
|
+
"work_task",
|
|
309
|
+
"work_method",
|
|
310
|
+
"work_artifact"
|
|
311
|
+
];
|
|
312
|
+
var UNCLASSIFIED_DIR = "unclassified";
|
|
313
|
+
var MEMORY_TYPE_VOCABULARY = /* @__PURE__ */ new Set([
|
|
314
|
+
...LEGACY_MEMORY_TYPES,
|
|
315
|
+
...HOST_MEMORY_TYPES
|
|
316
|
+
]);
|
|
317
|
+
var TYPE_FAMILY_MAP = Object.freeze(
|
|
318
|
+
(() => {
|
|
319
|
+
const map = {};
|
|
320
|
+
for (const t of LEGACY_MEMORY_TYPES) map[t] = t.startsWith("work") ? "work" : "chat";
|
|
321
|
+
for (const t of HOST_MEMORY_TYPES) map[t] = t.startsWith("user_") ? "chat" : "work";
|
|
322
|
+
map[UNCLASSIFIED_DIR] = "chat";
|
|
323
|
+
return map;
|
|
324
|
+
})()
|
|
325
|
+
);
|
|
326
|
+
var MEMORY_TYPE_LABELS = Object.freeze({
|
|
327
|
+
persona: "画像偏好",
|
|
328
|
+
episodic: "客观事件",
|
|
329
|
+
instruction: "全局指令",
|
|
330
|
+
work_fact: "工作事实",
|
|
331
|
+
work_task: "工作任务",
|
|
332
|
+
work_method: "工作方法",
|
|
333
|
+
work_artifact: "工作资产",
|
|
334
|
+
user_info: "用户信息",
|
|
335
|
+
user_hobby: "用户爱好",
|
|
336
|
+
user_communication: "沟通风格",
|
|
337
|
+
user_behavior: "行为规范",
|
|
338
|
+
project_introduction: "项目介绍",
|
|
339
|
+
project_tech_stack: "技术栈",
|
|
340
|
+
project_architecture: "架构设计",
|
|
341
|
+
project_build_configuration: "构建配置",
|
|
342
|
+
project_dependency_configuration: "依赖配置",
|
|
343
|
+
project_ide_configuration: "IDE 配置",
|
|
344
|
+
project_scm_configuration: "版本控制配置",
|
|
345
|
+
project_environment_configuration: "环境配置",
|
|
346
|
+
project_rule: "项目规则",
|
|
347
|
+
development_code_specification: "代码规范",
|
|
348
|
+
development_practice_specification: "实践规范",
|
|
349
|
+
development_test_specification: "测试规范",
|
|
350
|
+
development_comment_specification: "注释规范",
|
|
351
|
+
task_summary_experience: "任务总结",
|
|
352
|
+
task_breakdown_experience: "任务拆解",
|
|
353
|
+
task_flow_experience: "任务流程",
|
|
354
|
+
task_experience: "任务经验",
|
|
355
|
+
tool_experience: "工具经验",
|
|
356
|
+
mcp_experience: "MCP 经验",
|
|
357
|
+
skill_experience: "技能经验",
|
|
358
|
+
learned_skill_experience: "习得技能",
|
|
359
|
+
expert_experience: "专家经验",
|
|
360
|
+
important_decision_experience: "重要决策",
|
|
361
|
+
common_pitfalls_experience: "常见陷阱",
|
|
362
|
+
history_task_reference_files: "历史参考文件",
|
|
363
|
+
[UNCLASSIFIED_DIR]: "未分类"
|
|
364
|
+
});
|
|
365
|
+
function slugOf(type) {
|
|
366
|
+
return type.replace(/_/g, "-");
|
|
367
|
+
}
|
|
368
|
+
|
|
267
369
|
// client/src/theme.ts
|
|
268
370
|
var THEME_STYLE_ID = "dsh-mem-theme-style";
|
|
269
371
|
var LIGHT_TOK = [
|
|
@@ -346,6 +448,18 @@ var __defProp = Object.defineProperty;
|
|
|
346
448
|
" --dsh-mem-shadow-card: var(--dsw-shadow-lv1, 0 2px 4px 0 rgba(0,0,0,0.3));",
|
|
347
449
|
" --dsh-mem-shadow-pop: var(--dsw-shadow-lv3, 0 0 1px 0 rgba(0,0,0,.2), 0 0 4px 0 rgba(0,0,0,.02), 0 12px 32px 0 rgba(0,0,0,0.08));"
|
|
348
450
|
];
|
|
451
|
+
var EXT_LIGHT = ["#8a5a00", "#0757b4", "#116629", "#6f42c1", "#b43a6f", "#076f6b", "#7a5c00", "#4a6fa5"];
|
|
452
|
+
var EXT_DARK = ["#e3b341", "#6cb2ff", "#6fca74", "#c297ff", "#f077b6", "#56d4c8", "#d9b64a", "#9db8e8"];
|
|
453
|
+
var EXT_TAG_RULES = HOST_MEMORY_TYPES.map(
|
|
454
|
+
(t, i) => `.dsh-mem-tag-${slugOf(t)} { --dsh-mem-tag-c: ${EXT_LIGHT[i % EXT_LIGHT.length]}; }`
|
|
455
|
+
).concat(
|
|
456
|
+
HOST_MEMORY_TYPES.map(
|
|
457
|
+
(t, i) => `body[data-ds-dark-theme] .dsh-mem-tag-${slugOf(t)} { --dsh-mem-tag-c: ${EXT_DARK[i % EXT_DARK.length]}; }`
|
|
458
|
+
),
|
|
459
|
+
// 兜底桶固定中性灰:它代表“没归类”,不该带族色暗示。
|
|
460
|
+
`.dsh-mem-tag-${UNCLASSIFIED_DIR} { --dsh-mem-tag-c: #8a93a1; }`,
|
|
461
|
+
`body[data-ds-dark-theme] .dsh-mem-tag-${UNCLASSIFIED_DIR} { --dsh-mem-tag-c: #9aa4b2; }`
|
|
462
|
+
);
|
|
349
463
|
var COMPONENT_CSS = [
|
|
350
464
|
// conic 角度要 @property 注册才能插值动画;不支持 @property 的浏览器里
|
|
351
465
|
// var(--dsh-mem-angle) 无定义 → conic 层失效 → background 整条退化为无背景
|
|
@@ -452,6 +566,8 @@ var __defProp = Object.defineProperty;
|
|
|
452
566
|
"body[data-ds-dark-theme] .dsh-mem-tag-work-fact { --dsh-mem-tag-c: #6cb2ff; }",
|
|
453
567
|
"body[data-ds-dark-theme] .dsh-mem-tag-work-task { --dsh-mem-tag-c: #6fca74; }",
|
|
454
568
|
"body[data-ds-dark-theme] .dsh-mem-tag-work-method { --dsh-mem-tag-c: #c297ff; }",
|
|
569
|
+
// —— 扩展类别(宿主 29 类 + 兜底桶):类名从真源派生,缺一个类就是“标签无色” ——
|
|
570
|
+
...EXT_TAG_RULES,
|
|
455
571
|
// ── pill 边缘流光(品牌蓝族,chat/work/auto 三档共用;off 无):border 区画旋转
|
|
456
572
|
// conic 光带;内部必须用【不透明】底色盖住光带——半透明内层会让 conic 透进按钮
|
|
457
573
|
// 内部干扰文字(实测事故)。不透明底 = 主题底混 3% 档位色(--dsh-mem-pill-tint
|
|
@@ -561,15 +677,22 @@ var __defProp = Object.defineProperty;
|
|
|
561
677
|
var import_react2 = require("react");
|
|
562
678
|
|
|
563
679
|
// client/src/format.ts
|
|
564
|
-
var
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
680
|
+
var typeLabels = {};
|
|
681
|
+
function registerTypeCatalog(entries) {
|
|
682
|
+
if (!entries || entries.length === 0) return;
|
|
683
|
+
const next = { ...typeLabels };
|
|
684
|
+
for (const e of entries) next[e.id] = e.label;
|
|
685
|
+
typeLabels = next;
|
|
686
|
+
}
|
|
687
|
+
function typeLabel(type) {
|
|
688
|
+
return typeLabels[type] || type;
|
|
689
|
+
}
|
|
690
|
+
function typeCatalogIds() {
|
|
691
|
+
return Object.keys(typeLabels);
|
|
692
|
+
}
|
|
693
|
+
function tagClass(type) {
|
|
694
|
+
return "dsh-mem-tag dsh-mem-tag-" + type.replace(/_/g, "-");
|
|
695
|
+
}
|
|
573
696
|
function fmtTime(iso) {
|
|
574
697
|
if (!iso) return "-";
|
|
575
698
|
try {
|
|
@@ -1514,7 +1637,7 @@ var __defProp = Object.defineProperty;
|
|
|
1514
1637
|
}
|
|
1515
1638
|
|
|
1516
1639
|
// client/src/tabs/OverviewTab.tsx
|
|
1517
|
-
var
|
|
1640
|
+
var import_react16 = require("react");
|
|
1518
1641
|
|
|
1519
1642
|
// client/src/pill/modes.ts
|
|
1520
1643
|
var MODES = [
|
|
@@ -1533,12 +1656,195 @@ var __defProp = Object.defineProperty;
|
|
|
1533
1656
|
return "关闭";
|
|
1534
1657
|
}
|
|
1535
1658
|
|
|
1659
|
+
// client/src/tabs/ArchiveSection.tsx
|
|
1660
|
+
var import_react7 = require("react");
|
|
1661
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1662
|
+
var HINT_STYLE = { fontSize: 12, color: "var(--dsh-mem-text-3)", lineHeight: "18px" };
|
|
1663
|
+
var ROOT_STYLE = { fontSize: 11, color: "var(--dsh-mem-text-3)", wordBreak: "break-all" };
|
|
1664
|
+
async function call(rpc, method, payload) {
|
|
1665
|
+
try {
|
|
1666
|
+
const r = await rpc(method, payload);
|
|
1667
|
+
if (r && r.ok && r.value !== void 0) return { report: r.value };
|
|
1668
|
+
const msg = r && !r.ok ? r.error?.message : void 0;
|
|
1669
|
+
return { error: typeof msg === "string" && msg.length > 0 ? msg : "端点无响应" };
|
|
1670
|
+
} catch (err) {
|
|
1671
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
function lineOf(rep) {
|
|
1675
|
+
const head = `已写 ${rep.written} · 未变 ${rep.unchanged} · 跳过 ${rep.skipped}`;
|
|
1676
|
+
const named = rep.named > 0 ? ` · 新起名 ${rep.named} 条` : "";
|
|
1677
|
+
const nameBad = rep.nameFailed > 0 ? ` · 起名失败 ${rep.nameFailed} 条(下轮重试)` : "";
|
|
1678
|
+
const tail = rep.remaining > 0 ? ` · 剩余 ${rep.remaining} 条,再点一次继续` : "";
|
|
1679
|
+
return head + named + nameBad + tail;
|
|
1680
|
+
}
|
|
1681
|
+
function lineOfReconcile(rep) {
|
|
1682
|
+
const parts = [
|
|
1683
|
+
`首次 ${rep.firstTime}`,
|
|
1684
|
+
`一致 ${rep.same}`,
|
|
1685
|
+
`仅库变 ${rep.dbOnly}`,
|
|
1686
|
+
`仅文件变 ${rep.fileOnly}`,
|
|
1687
|
+
`两边都变 ${rep.both}`,
|
|
1688
|
+
`文件缺失 ${rep.missingFile}`
|
|
1689
|
+
];
|
|
1690
|
+
return parts.join(" · ") + (rep.capped ? `(本次只扫了 ${rep.scanned} 条,未扫全)` : "");
|
|
1691
|
+
}
|
|
1692
|
+
function lineOfSync(rep) {
|
|
1693
|
+
const head = `回灌 ${rep.imported} · 重写文件 ${rep.rendered} · 退场 ${rep.retired} · 一致 ${rep.same}`;
|
|
1694
|
+
const tail = rep.pending > 0 ? ` · 两边都变 ${rep.pending} 条已挂账(两侧都没动)` : "";
|
|
1695
|
+
const extra = rep.newFiles > 0 ? ` · 新文件 ${rep.newFiles} 个未入库(导入须走写入内核)` : "";
|
|
1696
|
+
const links = rep.skippedLinks > 0 ? ` · 防护拦下 ${rep.skippedLinks} 个链接/越界条目(未读)` : "";
|
|
1697
|
+
const stale = rep.staleRootFiles > 0 ? ` · 陈旧根 ${rep.staleRootFiles} 个文件未参与同步(交给孤儿归档)` : "";
|
|
1698
|
+
const multi = rep.multiPath > 0 ? ` · 同记录多路径 ${rep.multiPath} 份未动(先跑孤儿归档再同步)` : "";
|
|
1699
|
+
const hashBad = rep.hashMismatch > 0 ? ` · 自校验不符 ${rep.hashMismatch} 个(文件被外部改动,已按文件侧处理)` : "";
|
|
1700
|
+
const unsigned = rep.unsigned > 0 ? ` · 未签名 ${rep.unsigned} 个(老投射文件无 hash,下轮导出补盖)` : "";
|
|
1701
|
+
return head + tail + extra + links + stale + multi + hashBad + unsigned + (rep.remaining > 0 ? ` · 剩余 ${rep.remaining} 个文件,再点一次继续` : "");
|
|
1702
|
+
}
|
|
1703
|
+
function lineOfOrphans(rep) {
|
|
1704
|
+
const head = rep.dryRun ? `账本共 ${rep.scanned} 条 · 仍被认领 ${rep.claimed} · 无人认领 ${rep.orphans}(未搬任何东西)` : `已搬 ${rep.moved} · 失败 ${rep.failed} · 仍被认领 ${rep.claimed}`;
|
|
1705
|
+
const tail = rep.remaining > 0 ? ` · 剩余 ${rep.remaining} 条,再点一次继续` : "";
|
|
1706
|
+
return head + tail + (rep.dir.length > 0 ? ` · 归档到 ${rep.dir}` : "");
|
|
1707
|
+
}
|
|
1708
|
+
function lineOfCleanup(rep) {
|
|
1709
|
+
if (rep.aborted) return `清理已中止(未删任何记录):${rep.diffs.join(";") || "门禁未通过"}`;
|
|
1710
|
+
if (rep.dryRun) return `待删 ${rep.targets} 条(预览了前 ${rep.items?.length ?? 0} 条)——未删除任何东西`;
|
|
1711
|
+
const f = rep.files ?? { moved: 0, failed: 0, absent: 0 };
|
|
1712
|
+
const head = `已删 ${rep.purged} 条 · 归档正文 ${rep.archiveMd === void 0 || rep.archiveMd === "" ? "未写" : "已写"} · 文件搬家 ${f.moved}(失败 ${f.failed}) · 图索引 ${rep.graphForgotten ?? 0}`;
|
|
1713
|
+
return rep.otherChanged && rep.otherChanged > 0 ? `${head} · 本批之外 ${rep.otherChanged} 条处于漂移(不影响本批)` : head;
|
|
1714
|
+
}
|
|
1715
|
+
function ArchiveSection(props) {
|
|
1716
|
+
const rpc = props.rpc;
|
|
1717
|
+
const [busy, setBusy] = (0, import_react7.useState)(false);
|
|
1718
|
+
const [exported, setExported] = (0, import_react7.useState)(void 0);
|
|
1719
|
+
const [recon, setRecon] = (0, import_react7.useState)(void 0);
|
|
1720
|
+
const [synced, setSynced] = (0, import_react7.useState)(void 0);
|
|
1721
|
+
const [orphans, setOrphans] = (0, import_react7.useState)(void 0);
|
|
1722
|
+
const [cleanup, setCleanup] = (0, import_react7.useState)(void 0);
|
|
1723
|
+
const [orphanArmed, setOrphanArmed] = (0, import_react7.useState)(false);
|
|
1724
|
+
const [armed, setArmed] = (0, import_react7.useState)(false);
|
|
1725
|
+
const [error, setError] = (0, import_react7.useState)(void 0);
|
|
1726
|
+
const run = (method, sink, payload) => {
|
|
1727
|
+
if (busy) return;
|
|
1728
|
+
setBusy(true);
|
|
1729
|
+
setError(void 0);
|
|
1730
|
+
void call(rpc, method, payload).then((out) => {
|
|
1731
|
+
if (out.report !== void 0) sink(out.report);
|
|
1732
|
+
if (out.error !== void 0) setError(out.error);
|
|
1733
|
+
setBusy(false);
|
|
1734
|
+
});
|
|
1735
|
+
};
|
|
1736
|
+
const root = exported?.root ?? recon?.root;
|
|
1737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { marginTop: 12, paddingTop: 10, borderTop: "1px solid var(--dsh-mem-border)" }, children: [
|
|
1738
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontSize: 12, fontWeight: 600, color: "var(--dsh-mem-text-2)", marginBottom: 6 }, children: "外部存档(markdown 投射)" }),
|
|
1739
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: S.flexRow, children: [
|
|
1740
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1741
|
+
NButton,
|
|
1742
|
+
{
|
|
1743
|
+
disabled: busy,
|
|
1744
|
+
title: "把当前全部记忆渲染为 <根>/<类型>/<名称>.memory.md,并记下内容指纹(只写文件,不改库)",
|
|
1745
|
+
onClick: () => {
|
|
1746
|
+
run("dsh-memory/mem-export", setExported, {});
|
|
1747
|
+
},
|
|
1748
|
+
children: "导出为可携存档"
|
|
1749
|
+
}
|
|
1750
|
+
),
|
|
1751
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1752
|
+
NButton,
|
|
1753
|
+
{
|
|
1754
|
+
disabled: busy,
|
|
1755
|
+
title: "按账本基线比对库与磁盘,只出报告:什么都不写,因此不需要高权限",
|
|
1756
|
+
onClick: () => {
|
|
1757
|
+
run("dsh-memory/mem-reconcile", setRecon, {});
|
|
1758
|
+
},
|
|
1759
|
+
children: "与存档对账"
|
|
1760
|
+
}
|
|
1761
|
+
),
|
|
1762
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1763
|
+
NButton,
|
|
1764
|
+
{
|
|
1765
|
+
disabled: busy,
|
|
1766
|
+
title: "文件 → 库:只有文件变过的回灌入库,`.disable` 后缀的退场;两边都变的那些两侧都不动,只挂账。会写库,因此需要高权限模式",
|
|
1767
|
+
onClick: () => {
|
|
1768
|
+
run("dsh-memory/mem-sync", setSynced, {});
|
|
1769
|
+
},
|
|
1770
|
+
children: "从存档同步回库"
|
|
1771
|
+
}
|
|
1772
|
+
),
|
|
1773
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1774
|
+
NButton,
|
|
1775
|
+
{
|
|
1776
|
+
disabled: busy,
|
|
1777
|
+
title: "只读预览:扫账本,找出“我们写过但现在没记录认领它”的投射文件(改名/消歧留下的残片)。来路不明的文件一律不动,也不搬任何东西",
|
|
1778
|
+
onClick: () => {
|
|
1779
|
+
setOrphanArmed(false);
|
|
1780
|
+
run("dsh-memory/mem-orphans", setOrphans, { dryRun: true });
|
|
1781
|
+
},
|
|
1782
|
+
children: "孤儿文件预览"
|
|
1783
|
+
}
|
|
1784
|
+
),
|
|
1785
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1786
|
+
NButton,
|
|
1787
|
+
{
|
|
1788
|
+
disabled: busy || orphans === void 0 || !orphans.dryRun || orphans.orphans === 0,
|
|
1789
|
+
title: orphanArmed ? "再点一次就真的搬——文件会被移出投射目录(不删,进归档目录,可手动搬回)" : "不删只搬:进 <数据目录>/memories-orphans/<批次时间戳>/;需要先跑预览,再点两次确认;服务端还要高权限模式",
|
|
1790
|
+
onClick: () => {
|
|
1791
|
+
if (!orphanArmed) {
|
|
1792
|
+
setOrphanArmed(true);
|
|
1793
|
+
return;
|
|
1794
|
+
}
|
|
1795
|
+
setOrphanArmed(false);
|
|
1796
|
+
run("dsh-memory/mem-orphans", setOrphans, { dryRun: false });
|
|
1797
|
+
},
|
|
1798
|
+
children: orphanArmed ? "确认搬走孤儿文件" : "孤儿文件归档"
|
|
1799
|
+
}
|
|
1800
|
+
),
|
|
1801
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1802
|
+
NButton,
|
|
1803
|
+
{
|
|
1804
|
+
disabled: busy,
|
|
1805
|
+
title: "只读预览:列出将被物理删除的退场记忆(前 50 条)与总数,不删任何东西",
|
|
1806
|
+
onClick: () => {
|
|
1807
|
+
setArmed(false);
|
|
1808
|
+
run("dsh-memory/cleanup-retired", setCleanup, { dryRun: true });
|
|
1809
|
+
},
|
|
1810
|
+
children: "清理预览(干跑)"
|
|
1811
|
+
}
|
|
1812
|
+
),
|
|
1813
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1814
|
+
NButton,
|
|
1815
|
+
{
|
|
1816
|
+
disabled: busy || cleanup === void 0 || !cleanup.dryRun || cleanup.targets === 0,
|
|
1817
|
+
title: armed ? "再点一次就真的删——物理删除不可逆(但会先落快照与归档正文)" : "不可逆动作:需要先跑预览,再点两次确认;服务端那边还要高权限模式",
|
|
1818
|
+
onClick: () => {
|
|
1819
|
+
if (!armed) {
|
|
1820
|
+
setArmed(true);
|
|
1821
|
+
return;
|
|
1822
|
+
}
|
|
1823
|
+
setArmed(false);
|
|
1824
|
+
run("dsh-memory/cleanup-retired", setCleanup, { dryRun: false });
|
|
1825
|
+
},
|
|
1826
|
+
children: armed ? "确认物理删除" : "清理并归档"
|
|
1827
|
+
}
|
|
1828
|
+
)
|
|
1829
|
+
] }),
|
|
1830
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { ...HINT_STYLE, marginTop: 6 }, children: error !== void 0 ? `失败:${error}` : cleanup !== void 0 ? lineOfCleanup(cleanup) : orphans !== void 0 ? lineOfOrphans(orphans) : synced !== void 0 ? lineOfSync(synced) : exported !== void 0 ? lineOf(exported) : recon !== void 0 ? lineOfReconcile(recon) : "导出=库→文件;对账=只读比较;同步=文件→库;孤儿=搬走没人认领的残片;清理=物理删除(不可逆,需高权限模式)。" }),
|
|
1831
|
+
recon !== void 0 && error === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: HINT_STYLE, children: [
|
|
1832
|
+
"最近差异样本:",
|
|
1833
|
+
recon.samples.map((s) => `${s.state}:${s.relPath}`).join(",") || "(无)"
|
|
1834
|
+
] }) : null,
|
|
1835
|
+
root !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: ROOT_STYLE, children: [
|
|
1836
|
+
"投射根:",
|
|
1837
|
+
root
|
|
1838
|
+
] }) : null
|
|
1839
|
+
] });
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1536
1842
|
// client/src/tabs/DistillSettings.tsx
|
|
1537
|
-
var
|
|
1843
|
+
var import_react12 = require("react");
|
|
1538
1844
|
|
|
1539
1845
|
// client/src/tabs/BudgetInputs.tsx
|
|
1540
|
-
var
|
|
1541
|
-
var
|
|
1846
|
+
var import_react8 = require("react");
|
|
1847
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1542
1848
|
var LAYERS = [
|
|
1543
1849
|
["extract", "抽取"],
|
|
1544
1850
|
["dedup", "去重"],
|
|
@@ -1559,7 +1865,7 @@ var __defProp = Object.defineProperty;
|
|
|
1559
1865
|
const onError = props.onError;
|
|
1560
1866
|
const scope = props.scope ?? "all";
|
|
1561
1867
|
const layers = scope === "all" || scope === "input" ? LAYERS : LAYERS.filter((l) => SCOPE_KEYS[scope].includes(l[0]));
|
|
1562
|
-
const [draft, setDraft] = (0,
|
|
1868
|
+
const [draft, setDraft] = (0, import_react8.useState)(null);
|
|
1563
1869
|
if (!data || !data.budgets) return null;
|
|
1564
1870
|
const cur = data.budgets.current || {};
|
|
1565
1871
|
const def = data.budgets.defaults || {};
|
|
@@ -1655,7 +1961,7 @@ var __defProp = Object.defineProperty;
|
|
|
1655
1961
|
return false;
|
|
1656
1962
|
};
|
|
1657
1963
|
const inputBox = (key, _label, title, width, placeholder, onCommit) => {
|
|
1658
|
-
return /* @__PURE__ */ (0,
|
|
1964
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1659
1965
|
NInput,
|
|
1660
1966
|
{
|
|
1661
1967
|
type: "number",
|
|
@@ -1687,9 +1993,9 @@ var __defProp = Object.defineProperty;
|
|
|
1687
1993
|
const effNote = layers.map((l) => eff[l[0]] || "?").join(" / ");
|
|
1688
1994
|
const rowLabel = (key) => key === "extract" ? "抽取输出" : key === "dedup" ? "去重输出" : key === "l2" ? "L2 输出" : "L3 输出";
|
|
1689
1995
|
const rowStyle2 = { display: "flex", alignItems: "center", gap: 8 };
|
|
1690
|
-
return /* @__PURE__ */ (0,
|
|
1691
|
-
showOutputs ? /* @__PURE__ */ (0,
|
|
1692
|
-
/* @__PURE__ */ (0,
|
|
1996
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
|
|
1997
|
+
showOutputs ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginTop: 12 }, children: [
|
|
1998
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1693
1999
|
"div",
|
|
1694
2000
|
{
|
|
1695
2001
|
style: S.switchLabel,
|
|
@@ -1697,8 +2003,8 @@ var __defProp = Object.defineProperty;
|
|
|
1697
2003
|
children: "输出预算"
|
|
1698
2004
|
}
|
|
1699
2005
|
),
|
|
1700
|
-
/* @__PURE__ */ (0,
|
|
1701
|
-
/* @__PURE__ */ (0,
|
|
2006
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 4 }, children: layers.map((l) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: rowStyle2, children: [
|
|
2007
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { width: 68, flexShrink: 0, fontSize: 12, color: "var(--dsh-mem-text-2)" }, children: rowLabel(l[0]) }),
|
|
1702
2008
|
inputBox(
|
|
1703
2009
|
l[0],
|
|
1704
2010
|
l[1],
|
|
@@ -1707,11 +2013,11 @@ var __defProp = Object.defineProperty;
|
|
|
1707
2013
|
def[l[0]],
|
|
1708
2014
|
commitOutputs
|
|
1709
2015
|
),
|
|
1710
|
-
/* @__PURE__ */ (0,
|
|
2016
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: "token" })
|
|
1711
2017
|
] }, l[0])) })
|
|
1712
2018
|
] }) : null,
|
|
1713
|
-
showInput ? /* @__PURE__ */ (0,
|
|
1714
|
-
/* @__PURE__ */ (0,
|
|
2019
|
+
showInput ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginTop: 12 }, children: [
|
|
2020
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1715
2021
|
"div",
|
|
1716
2022
|
{
|
|
1717
2023
|
style: S.switchLabel,
|
|
@@ -1719,8 +2025,8 @@ var __defProp = Object.defineProperty;
|
|
|
1719
2025
|
children: "输入预算"
|
|
1720
2026
|
}
|
|
1721
2027
|
),
|
|
1722
|
-
/* @__PURE__ */ (0,
|
|
1723
|
-
/* @__PURE__ */ (0,
|
|
2028
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: rowStyle2, children: [
|
|
2029
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { width: 68, flexShrink: 0, fontSize: 12, color: "var(--dsh-mem-text-2)" }, children: "单次输入" }),
|
|
1724
2030
|
inputBox(
|
|
1725
2031
|
"input",
|
|
1726
2032
|
"输入",
|
|
@@ -1729,15 +2035,15 @@ var __defProp = Object.defineProperty;
|
|
|
1729
2035
|
ib.fallback,
|
|
1730
2036
|
commitInput
|
|
1731
2037
|
),
|
|
1732
|
-
/* @__PURE__ */ (0,
|
|
2038
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: "字符" })
|
|
1733
2039
|
] }) })
|
|
1734
2040
|
] }) : null
|
|
1735
2041
|
] });
|
|
1736
2042
|
}
|
|
1737
2043
|
|
|
1738
2044
|
// client/src/tabs/ChannelEditor.tsx
|
|
1739
|
-
var
|
|
1740
|
-
var
|
|
2045
|
+
var import_react9 = require("react");
|
|
2046
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1741
2047
|
var STY = {
|
|
1742
2048
|
block: { marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--dsh-mem-border)" },
|
|
1743
2049
|
head: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", marginBottom: 6 },
|
|
@@ -1768,14 +2074,14 @@ var __defProp = Object.defineProperty;
|
|
|
1768
2074
|
];
|
|
1769
2075
|
function ChannelEditor(props) {
|
|
1770
2076
|
const { channel, rpc, disabled } = props;
|
|
1771
|
-
const [baseText, setBaseText] = (0,
|
|
1772
|
-
const [keyText, setKeyText] = (0,
|
|
1773
|
-
const baseTimer = (0,
|
|
1774
|
-
const dirty = (0,
|
|
1775
|
-
(0,
|
|
2077
|
+
const [baseText, setBaseText] = (0, import_react9.useState)(channel.runtimeBaseURL);
|
|
2078
|
+
const [keyText, setKeyText] = (0, import_react9.useState)("");
|
|
2079
|
+
const baseTimer = (0, import_react9.useRef)(void 0);
|
|
2080
|
+
const dirty = (0, import_react9.useRef)(false);
|
|
2081
|
+
(0, import_react9.useEffect)(() => {
|
|
1776
2082
|
if (!dirty.current) setBaseText(channel.runtimeBaseURL);
|
|
1777
2083
|
}, [channel.runtimeBaseURL]);
|
|
1778
|
-
(0,
|
|
2084
|
+
(0, import_react9.useEffect)(() => () => clearTimeout(baseTimer.current), []);
|
|
1779
2085
|
const commit2 = (patch) => {
|
|
1780
2086
|
rpc("dsh-memory/settings-set", patch).catch(() => {
|
|
1781
2087
|
});
|
|
@@ -1804,17 +2110,17 @@ var __defProp = Object.defineProperty;
|
|
|
1804
2110
|
const deployedDirect = channel.deployed === "direct";
|
|
1805
2111
|
const apiKeySet = channel.runtimeApiKeySet || channel.deployedApiKeySet;
|
|
1806
2112
|
const showWarn = isDirect && !channel.directReady;
|
|
1807
|
-
return /* @__PURE__ */ (0,
|
|
1808
|
-
/* @__PURE__ */ (0,
|
|
1809
|
-
/* @__PURE__ */ (0,
|
|
1810
|
-
/* @__PURE__ */ (0,
|
|
1811
|
-
/* @__PURE__ */ (0,
|
|
2113
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: STY.block, children: [
|
|
2114
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: STY.head, children: [
|
|
2115
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY.title, children: "蒸馏通道" }),
|
|
2116
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: isDirect ? STY.chipAccent : STY.chipMuted, children: isDirect ? "直连端点" : "复用宿主" }),
|
|
2117
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { title: "direct = 插件原生直连 OpenAI 兼容端点,与付费 API 解耦;失败自动回退宿主路由链。", style: { marginLeft: "auto", fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: [
|
|
1812
2118
|
"生效:",
|
|
1813
2119
|
runtime ? runtime === "direct" ? "运行时直连" : "运行时宿主" : "跟随部署配置"
|
|
1814
2120
|
] })
|
|
1815
2121
|
] }),
|
|
1816
|
-
/* @__PURE__ */ (0,
|
|
1817
|
-
/* @__PURE__ */ (0,
|
|
2122
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: STY.desc, children: "direct 通道走插件原生 HTTP,不依赖宿主 provider 注册表;direct 失败自动回退宿主路由链作兜底安全网。" }),
|
|
2123
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1818
2124
|
Segmented,
|
|
1819
2125
|
{
|
|
1820
2126
|
value: runtime,
|
|
@@ -1823,10 +2129,10 @@ var __defProp = Object.defineProperty;
|
|
|
1823
2129
|
onChange: (k) => commit2({ distillMode: k })
|
|
1824
2130
|
}
|
|
1825
2131
|
),
|
|
1826
|
-
editing ? /* @__PURE__ */ (0,
|
|
1827
|
-
/* @__PURE__ */ (0,
|
|
1828
|
-
/* @__PURE__ */ (0,
|
|
1829
|
-
/* @__PURE__ */ (0,
|
|
2132
|
+
editing ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
2133
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: STY.fieldRow, children: [
|
|
2134
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY.fieldLabel, children: "端点 URL" }),
|
|
2135
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1830
2136
|
NInput,
|
|
1831
2137
|
{
|
|
1832
2138
|
style: STY.input,
|
|
@@ -1843,14 +2149,14 @@ var __defProp = Object.defineProperty;
|
|
|
1843
2149
|
}
|
|
1844
2150
|
}
|
|
1845
2151
|
),
|
|
1846
|
-
deployedDirect && !channel.runtimeBaseURL ? /* @__PURE__ */ (0,
|
|
2152
|
+
deployedDirect && !channel.runtimeBaseURL ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: [
|
|
1847
2153
|
"部署基线:",
|
|
1848
2154
|
channel.deployedBaseURL || "(空)"
|
|
1849
2155
|
] }) : null
|
|
1850
2156
|
] }),
|
|
1851
|
-
/* @__PURE__ */ (0,
|
|
1852
|
-
/* @__PURE__ */ (0,
|
|
1853
|
-
/* @__PURE__ */ (0,
|
|
2157
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: STY.fieldRow, children: [
|
|
2158
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY.fieldLabel, children: "API Key" }),
|
|
2159
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1854
2160
|
NInput,
|
|
1855
2161
|
{
|
|
1856
2162
|
style: STY.input,
|
|
@@ -1866,8 +2172,8 @@ var __defProp = Object.defineProperty;
|
|
|
1866
2172
|
onBlur: commitKey
|
|
1867
2173
|
}
|
|
1868
2174
|
),
|
|
1869
|
-
apiKeySet ? /* @__PURE__ */ (0,
|
|
1870
|
-
/* @__PURE__ */ (0,
|
|
2175
|
+
apiKeySet ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY.chipAccent, children: "已配置" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY.chipMuted, children: "未配置" }),
|
|
2176
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1871
2177
|
NButton,
|
|
1872
2178
|
{
|
|
1873
2179
|
disabled,
|
|
@@ -1877,30 +2183,30 @@ var __defProp = Object.defineProperty;
|
|
|
1877
2183
|
}
|
|
1878
2184
|
)
|
|
1879
2185
|
] }),
|
|
1880
|
-
showWarn ? /* @__PURE__ */ (0,
|
|
1881
|
-
] }) : /* @__PURE__ */ (0,
|
|
2186
|
+
showWarn ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: STY.warn, children: "⚠ direct 未配置完整:需同时有端点 URL 与模型(llm.model / 全局链主路由),否则会回退宿主路由。" }) : null
|
|
2187
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: STY.preview, children: isDirect ? "当前将直连端点:" + (channel.runtimeBaseURL || channel.deployedBaseURL || "(未配置端点)") + (apiKeySet ? " · 密钥已配置" : " · 未配置密钥") : "当前复用宿主 ctx.llm(" + (runtime === "host" ? "运行时锁定" : "跟随部署配置") + ")" })
|
|
1882
2188
|
] });
|
|
1883
2189
|
}
|
|
1884
2190
|
|
|
1885
2191
|
// client/src/tabs/RouteChainEditor.tsx
|
|
1886
|
-
var
|
|
2192
|
+
var import_react11 = require("react");
|
|
1887
2193
|
|
|
1888
2194
|
// client/src/ui/NSel.tsx
|
|
1889
|
-
var
|
|
1890
|
-
var
|
|
2195
|
+
var import_react10 = require("react");
|
|
2196
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1891
2197
|
function NSel(props) {
|
|
1892
2198
|
const options = props.options || [];
|
|
1893
2199
|
const value = props.value || "";
|
|
1894
2200
|
const disabled = !!props.disabled;
|
|
1895
|
-
const [open, setOpen] = (0,
|
|
1896
|
-
const [idx, setIdx] = (0,
|
|
1897
|
-
const wrapRef = (0,
|
|
1898
|
-
const listRef = (0,
|
|
2201
|
+
const [open, setOpen] = (0, import_react10.useState)(false);
|
|
2202
|
+
const [idx, setIdx] = (0, import_react10.useState)(-1);
|
|
2203
|
+
const wrapRef = (0, import_react10.useRef)(null);
|
|
2204
|
+
const listRef = (0, import_react10.useRef)(null);
|
|
1899
2205
|
let selectedLabel = "";
|
|
1900
2206
|
for (let si = 0; si < options.length; si++) {
|
|
1901
2207
|
if (options[si].id === value) selectedLabel = options[si].label;
|
|
1902
2208
|
}
|
|
1903
|
-
(0,
|
|
2209
|
+
(0, import_react10.useEffect)(() => {
|
|
1904
2210
|
if (!open) return void 0;
|
|
1905
2211
|
const onDown = (e) => {
|
|
1906
2212
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -1910,7 +2216,7 @@ var __defProp = Object.defineProperty;
|
|
|
1910
2216
|
document.removeEventListener("mousedown", onDown);
|
|
1911
2217
|
};
|
|
1912
2218
|
}, [open]);
|
|
1913
|
-
(0,
|
|
2219
|
+
(0, import_react10.useEffect)(() => {
|
|
1914
2220
|
if (!open || !listRef.current) return;
|
|
1915
2221
|
const el = listRef.current.querySelector('[data-active="1"]');
|
|
1916
2222
|
if (el && el.scrollIntoView) el.scrollIntoView({ block: "nearest" });
|
|
@@ -1973,8 +2279,8 @@ var __defProp = Object.defineProperty;
|
|
|
1973
2279
|
const to = e.relatedTarget;
|
|
1974
2280
|
if (!to || wrapRef.current && !wrapRef.current.contains(to)) setOpen(false);
|
|
1975
2281
|
};
|
|
1976
|
-
return /* @__PURE__ */ (0,
|
|
1977
|
-
/* @__PURE__ */ (0,
|
|
2282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-mem-sel", style: props.style, ref: wrapRef, onKeyDown: onKey, onBlur, children: [
|
|
2283
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1978
2284
|
"button",
|
|
1979
2285
|
{
|
|
1980
2286
|
type: "button",
|
|
@@ -1990,13 +2296,13 @@ var __defProp = Object.defineProperty;
|
|
|
1990
2296
|
}
|
|
1991
2297
|
},
|
|
1992
2298
|
children: [
|
|
1993
|
-
/* @__PURE__ */ (0,
|
|
1994
|
-
/* @__PURE__ */ (0,
|
|
2299
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-select-label", children: selectedLabel || props.placeholder || "(请选择)" }),
|
|
2300
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-sel-chev" + (open ? " dsh-mem-sel-chev-open" : ""), "aria-hidden": true })
|
|
1995
2301
|
]
|
|
1996
2302
|
}
|
|
1997
2303
|
),
|
|
1998
|
-
open && !disabled ? /* @__PURE__ */ (0,
|
|
1999
|
-
return /* @__PURE__ */ (0,
|
|
2304
|
+
open && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-pop", ref: listRef, role: "listbox", children: options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-mem-pop-empty", children: "无选项" }) : options.map((o, i) => {
|
|
2305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2000
2306
|
"button",
|
|
2001
2307
|
{
|
|
2002
2308
|
type: "button",
|
|
@@ -2014,8 +2320,8 @@ var __defProp = Object.defineProperty;
|
|
|
2014
2320
|
if (idx !== i) setIdx(i);
|
|
2015
2321
|
},
|
|
2016
2322
|
children: [
|
|
2017
|
-
/* @__PURE__ */ (0,
|
|
2018
|
-
o.id === value ? /* @__PURE__ */ (0,
|
|
2323
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-pop-opt-label", children: o.label }),
|
|
2324
|
+
o.id === value ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-pop-check", children: "✓" }) : null
|
|
2019
2325
|
]
|
|
2020
2326
|
},
|
|
2021
2327
|
o.id
|
|
@@ -2025,7 +2331,7 @@ var __defProp = Object.defineProperty;
|
|
|
2025
2331
|
}
|
|
2026
2332
|
|
|
2027
2333
|
// client/src/tabs/RouteChainEditor.tsx
|
|
2028
|
-
var
|
|
2334
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2029
2335
|
var modelsCache = {};
|
|
2030
2336
|
var EFFORT_VOCAB = ["", "off", "none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
2031
2337
|
var STY2 = {
|
|
@@ -2054,26 +2360,26 @@ var __defProp = Object.defineProperty;
|
|
|
2054
2360
|
const disabled = !!props.disabled;
|
|
2055
2361
|
const scope = props.scope ?? "global";
|
|
2056
2362
|
const isLayer = scope !== "global";
|
|
2057
|
-
const [info, setInfo] = (0,
|
|
2058
|
-
const [rows, setRows] = (0,
|
|
2059
|
-
const [rowErrs, setRowErrs] = (0,
|
|
2060
|
-
const [err, setErr] = (0,
|
|
2061
|
-
const [manual, setManual] = (0,
|
|
2062
|
-
const pendingWrites = (0,
|
|
2363
|
+
const [info, setInfo] = (0, import_react11.useState)(null);
|
|
2364
|
+
const [rows, setRows] = (0, import_react11.useState)(null);
|
|
2365
|
+
const [rowErrs, setRowErrs] = (0, import_react11.useState)({});
|
|
2366
|
+
const [err, setErr] = (0, import_react11.useState)(null);
|
|
2367
|
+
const [manual, setManual] = (0, import_react11.useState)({ idx: -1, text: "" });
|
|
2368
|
+
const pendingWrites = (0, import_react11.useRef)(0);
|
|
2063
2369
|
function refreshInfo() {
|
|
2064
2370
|
rpc("dsh-memory/llm-providers", {}).then((r) => {
|
|
2065
2371
|
if (r && r.ok && pendingWrites.current === 0) setInfo(r.value);
|
|
2066
2372
|
}).catch(() => {
|
|
2067
2373
|
});
|
|
2068
2374
|
}
|
|
2069
|
-
(0,
|
|
2375
|
+
(0, import_react11.useEffect)(() => {
|
|
2070
2376
|
refreshInfo();
|
|
2071
2377
|
const timer = setInterval(refreshInfo, 5e3);
|
|
2072
2378
|
return () => {
|
|
2073
2379
|
clearInterval(timer);
|
|
2074
2380
|
};
|
|
2075
2381
|
}, [rpc]);
|
|
2076
|
-
(0,
|
|
2382
|
+
(0, import_react11.useEffect)(() => {
|
|
2077
2383
|
if (!info || !info.providers) return;
|
|
2078
2384
|
info.providers.forEach((p) => {
|
|
2079
2385
|
if (!p.id || modelsCache[p.id]) return;
|
|
@@ -2085,7 +2391,7 @@ var __defProp = Object.defineProperty;
|
|
|
2085
2391
|
}, [rpc, info]);
|
|
2086
2392
|
const layerView = isLayer && info && info.layerChains ? info.layerChains[scope] : null;
|
|
2087
2393
|
const savedRows = isLayer ? layerView?.runtime ?? [] : info && info.chain ? info.chain.current : [];
|
|
2088
|
-
(0,
|
|
2394
|
+
(0, import_react11.useEffect)(() => {
|
|
2089
2395
|
if (rows === null && info && savedRows.length) {
|
|
2090
2396
|
setRows(savedRows.map(copyRow));
|
|
2091
2397
|
}
|
|
@@ -2233,17 +2539,17 @@ var __defProp = Object.defineProperty;
|
|
|
2233
2539
|
providersById[p.id] = p;
|
|
2234
2540
|
});
|
|
2235
2541
|
function roRow(e, i) {
|
|
2236
|
-
return /* @__PURE__ */ (0,
|
|
2237
|
-
/* @__PURE__ */ (0,
|
|
2238
|
-
/* @__PURE__ */ (0,
|
|
2239
|
-
/* @__PURE__ */ (0,
|
|
2542
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.roRow, children: [
|
|
2543
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: STY2.badge, children: i === 0 ? "主" : String(i + 1) }),
|
|
2544
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { ...STY2.mono, color: "var(--dsh-mem-text-2)" }, children: e.provider + " / " + e.model }),
|
|
2545
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { marginLeft: "auto", flexShrink: 0, fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: e.effort ? "档位 " + e.effort : "跟随部署配置" })
|
|
2240
2546
|
] }, "ro" + i);
|
|
2241
2547
|
}
|
|
2242
2548
|
if (info.pinned) {
|
|
2243
2549
|
const effPin = isLayer ? layerView?.effectiveChain ?? [] : info.chain && info.chain.effectiveChain || [];
|
|
2244
|
-
return /* @__PURE__ */ (0,
|
|
2550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.wrap, children: [
|
|
2245
2551
|
effPin.map(roRow),
|
|
2246
|
-
/* @__PURE__ */ (0,
|
|
2552
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: STY2.note, children: "部署已锁定路由(pin),调整请修改 cordis.patch.yml 中 llm 的配置。" })
|
|
2247
2553
|
] });
|
|
2248
2554
|
}
|
|
2249
2555
|
if (rows === null) {
|
|
@@ -2251,21 +2557,21 @@ var __defProp = Object.defineProperty;
|
|
|
2251
2557
|
const lv = layerView;
|
|
2252
2558
|
const src = lv?.source ?? "global";
|
|
2253
2559
|
if (src === "static" && lv) {
|
|
2254
|
-
return /* @__PURE__ */ (0,
|
|
2560
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.wrap, children: [
|
|
2255
2561
|
lv.static.map((e, i) => roRow({ provider: e.provider, model: e.model, effort: e.reasoningEffort || "" }, i)),
|
|
2256
|
-
/* @__PURE__ */ (0,
|
|
2562
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { onClick: forkStatic, disabled, children: "自定义本层链" }) })
|
|
2257
2563
|
] });
|
|
2258
2564
|
}
|
|
2259
2565
|
const previewRows = lv?.effectiveChain ?? [];
|
|
2260
|
-
return /* @__PURE__ */ (0,
|
|
2261
|
-
previewRows.length === 0 ? /* @__PURE__ */ (0,
|
|
2262
|
-
/* @__PURE__ */ (0,
|
|
2566
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.wrap, children: [
|
|
2567
|
+
previewRows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: S.switchDesc, children: "本层跟随全局链,暂无可用路由。" }) : previewRows.map(roRow),
|
|
2568
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { onClick: forkStatic, disabled, children: "自定义本层链" }) })
|
|
2263
2569
|
] });
|
|
2264
2570
|
}
|
|
2265
2571
|
const effFollow = info.chain && info.chain.effectiveChain || [];
|
|
2266
|
-
return /* @__PURE__ */ (0,
|
|
2267
|
-
effFollow.length === 0 ? /* @__PURE__ */ (0,
|
|
2268
|
-
/* @__PURE__ */ (0,
|
|
2572
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.wrap, children: [
|
|
2573
|
+
effFollow.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: S.switchDesc, children: "蒸馏跟随默认模型,未配置回退链。" }) : effFollow.map(roRow),
|
|
2574
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { onClick: forkStatic, disabled, children: "编辑为运行时链" }) })
|
|
2269
2575
|
] });
|
|
2270
2576
|
}
|
|
2271
2577
|
const capped = rows.length >= 8;
|
|
@@ -2306,10 +2612,10 @@ var __defProp = Object.defineProperty;
|
|
|
2306
2612
|
const effortOptions = [{ id: "", label: "跟随部署配置" }].concat(
|
|
2307
2613
|
curEfforts.filter((k) => EFFORT_VOCAB.indexOf(k) >= 0).map((k) => ({ id: k, label: k }))
|
|
2308
2614
|
);
|
|
2309
|
-
return /* @__PURE__ */ (0,
|
|
2310
|
-
/* @__PURE__ */ (0,
|
|
2311
|
-
/* @__PURE__ */ (0,
|
|
2312
|
-
/* @__PURE__ */ (0,
|
|
2615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { ...STY2.row, ...rowErrs[i] ? STY2.rowErr : null }, children: [
|
|
2616
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.line, children: [
|
|
2617
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: STY2.badge, children: isPrimary ? "主" : String(i + 1) }),
|
|
2618
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2313
2619
|
NSel,
|
|
2314
2620
|
{
|
|
2315
2621
|
style: { flex: 1, minWidth: 150 },
|
|
@@ -2322,7 +2628,7 @@ var __defProp = Object.defineProperty;
|
|
|
2322
2628
|
}
|
|
2323
2629
|
}
|
|
2324
2630
|
),
|
|
2325
|
-
!row2.provider ? null : manualInput ? /* @__PURE__ */ (0,
|
|
2631
|
+
!row2.provider ? null : manualInput ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2326
2632
|
NInput,
|
|
2327
2633
|
{
|
|
2328
2634
|
style: { flex: 1, minWidth: 150 },
|
|
@@ -2341,7 +2647,7 @@ var __defProp = Object.defineProperty;
|
|
|
2341
2647
|
}
|
|
2342
2648
|
}
|
|
2343
2649
|
}
|
|
2344
|
-
) : /* @__PURE__ */ (0,
|
|
2650
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2345
2651
|
NSel,
|
|
2346
2652
|
{
|
|
2347
2653
|
style: { flex: 1, minWidth: 150 },
|
|
@@ -2354,7 +2660,7 @@ var __defProp = Object.defineProperty;
|
|
|
2354
2660
|
}
|
|
2355
2661
|
}
|
|
2356
2662
|
),
|
|
2357
|
-
/* @__PURE__ */ (0,
|
|
2663
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2358
2664
|
NSel,
|
|
2359
2665
|
{
|
|
2360
2666
|
style: { flexShrink: 0, width: 118 },
|
|
@@ -2368,8 +2674,8 @@ var __defProp = Object.defineProperty;
|
|
|
2368
2674
|
}
|
|
2369
2675
|
)
|
|
2370
2676
|
] }),
|
|
2371
|
-
/* @__PURE__ */ (0,
|
|
2372
|
-
/* @__PURE__ */ (0,
|
|
2677
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.actions, children: [
|
|
2678
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2373
2679
|
NButton,
|
|
2374
2680
|
{
|
|
2375
2681
|
style: STY2.ico,
|
|
@@ -2381,7 +2687,7 @@ var __defProp = Object.defineProperty;
|
|
|
2381
2687
|
children: "↑"
|
|
2382
2688
|
}
|
|
2383
2689
|
),
|
|
2384
|
-
/* @__PURE__ */ (0,
|
|
2690
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2385
2691
|
NButton,
|
|
2386
2692
|
{
|
|
2387
2693
|
style: STY2.ico,
|
|
@@ -2393,7 +2699,7 @@ var __defProp = Object.defineProperty;
|
|
|
2393
2699
|
children: "↓"
|
|
2394
2700
|
}
|
|
2395
2701
|
),
|
|
2396
|
-
/* @__PURE__ */ (0,
|
|
2702
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2397
2703
|
NButton,
|
|
2398
2704
|
{
|
|
2399
2705
|
style: STY2.ico,
|
|
@@ -2406,14 +2712,14 @@ var __defProp = Object.defineProperty;
|
|
|
2406
2712
|
}
|
|
2407
2713
|
)
|
|
2408
2714
|
] }),
|
|
2409
|
-
isPrimary && !row2.provider ? /* @__PURE__ */ (0,
|
|
2410
|
-
!known ? /* @__PURE__ */ (0,
|
|
2411
|
-
rowErrs[i] ? /* @__PURE__ */ (0,
|
|
2715
|
+
isPrimary && !row2.provider ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: STY2.note, children: "跟随默认模型" + (info.default ? ":" + info.default.provider + " / " + info.default.model : "") + "(档位跟随部署配置,选定模型后可单独设置)" }) : null,
|
|
2716
|
+
!known ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: STY2.warn, children: "⚠ 供应商 " + row2.provider + " 已不在已注册路由中:该路由调用会失败并被链跳过(不阻止保存)。" }) : null,
|
|
2717
|
+
rowErrs[i] ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: STY2.warn, children: "✕ " + rowErrs[i] }) : null
|
|
2412
2718
|
] }, "row" + i);
|
|
2413
2719
|
});
|
|
2414
2720
|
const effChain = isLayer ? layerView?.effectiveChain ?? [] : info.chain && info.chain.effectiveChain || [];
|
|
2415
|
-
return /* @__PURE__ */ (0,
|
|
2416
|
-
/* @__PURE__ */ (0,
|
|
2721
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.wrap, children: [
|
|
2722
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2417
2723
|
"div",
|
|
2418
2724
|
{
|
|
2419
2725
|
style: { ...S.switchDesc, marginBottom: 8 },
|
|
@@ -2422,9 +2728,9 @@ var __defProp = Object.defineProperty;
|
|
|
2422
2728
|
}
|
|
2423
2729
|
),
|
|
2424
2730
|
rowEls,
|
|
2425
|
-
/* @__PURE__ */ (0,
|
|
2426
|
-
/* @__PURE__ */ (0,
|
|
2427
|
-
/* @__PURE__ */ (0,
|
|
2731
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { style: STY2.add, disabled: disabled || capped, onClick: addRow, children: capped ? "已达上限(8 条)" : "+ 添加回退路由" }),
|
|
2732
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 10 }, children: [
|
|
2733
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2428
2734
|
NButton,
|
|
2429
2735
|
{
|
|
2430
2736
|
style: isLayer ? { ...STY2.ghost, color: "var(--dsh-mem-danger)", border: "1px solid var(--dsh-mem-danger)" } : STY2.ghost,
|
|
@@ -2433,13 +2739,13 @@ var __defProp = Object.defineProperty;
|
|
|
2433
2739
|
children: isLayer ? "清除自定义 · 跟随全局" : "清空并跟随部署配置"
|
|
2434
2740
|
}
|
|
2435
2741
|
),
|
|
2436
|
-
/* @__PURE__ */ (0,
|
|
2437
|
-
/* @__PURE__ */ (0,
|
|
2742
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: S.grow }),
|
|
2743
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { variant: "primary", disabled, onClick: save, children: "保存" })
|
|
2438
2744
|
] }),
|
|
2439
|
-
err ? /* @__PURE__ */ (0,
|
|
2440
|
-
/* @__PURE__ */ (0,
|
|
2441
|
-
/* @__PURE__ */ (0,
|
|
2442
|
-
/* @__PURE__ */ (0,
|
|
2745
|
+
err ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { ...STY2.warn, marginTop: 8 }, children: "✕ " + err }) : null,
|
|
2746
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--dsh-mem-border)" }, children: [
|
|
2747
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)", marginBottom: 4 }, children: "实际链" + (dirty ? "(保存后更新;当前显示已保存值)" : "") }),
|
|
2748
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2443
2749
|
"div",
|
|
2444
2750
|
{
|
|
2445
2751
|
style: { fontSize: 12, color: "var(--dsh-mem-text-2)", wordBreak: "break-all", fontFamily: "ui-monospace, SFMono-Regular, Consolas, monospace" },
|
|
@@ -2451,7 +2757,7 @@ var __defProp = Object.defineProperty;
|
|
|
2451
2757
|
}
|
|
2452
2758
|
|
|
2453
2759
|
// client/src/tabs/DistillSettings.tsx
|
|
2454
|
-
var
|
|
2760
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2455
2761
|
var STY3 = {
|
|
2456
2762
|
hint: { fontSize: 11, color: "var(--dsh-mem-text-3)", margin: "0 0 8px" },
|
|
2457
2763
|
panelHead: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", marginBottom: 8 },
|
|
@@ -2480,9 +2786,9 @@ var __defProp = Object.defineProperty;
|
|
|
2480
2786
|
verticalAlign: "middle",
|
|
2481
2787
|
flexShrink: 0
|
|
2482
2788
|
};
|
|
2483
|
-
if (props.kind === "runtime") return /* @__PURE__ */ (0,
|
|
2484
|
-
if (props.kind === "static") return /* @__PURE__ */ (0,
|
|
2485
|
-
return /* @__PURE__ */ (0,
|
|
2789
|
+
if (props.kind === "runtime") return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...base, background: "var(--dsh-mem-accent)" } });
|
|
2790
|
+
if (props.kind === "static") return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...base, background: "transparent", border: "1.5px solid var(--dsh-mem-text-3)" } });
|
|
2791
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...base, background: "var(--dsh-mem-track)" } });
|
|
2486
2792
|
}
|
|
2487
2793
|
var LAYER_META = {
|
|
2488
2794
|
l1: { seg: "L1", title: "L1 · 抽取 / 去重" },
|
|
@@ -2492,9 +2798,9 @@ var __defProp = Object.defineProperty;
|
|
|
2492
2798
|
function DistillSettings(props) {
|
|
2493
2799
|
const rpc = props.rpc;
|
|
2494
2800
|
const disabled = !!props.disabled;
|
|
2495
|
-
const [info, setInfo] = (0,
|
|
2496
|
-
const [tab, setTab] = (0,
|
|
2497
|
-
(0,
|
|
2801
|
+
const [info, setInfo] = (0, import_react12.useState)(null);
|
|
2802
|
+
const [tab, setTab] = (0, import_react12.useState)("g");
|
|
2803
|
+
(0, import_react12.useEffect)(() => {
|
|
2498
2804
|
let alive = true;
|
|
2499
2805
|
const refresh = () => {
|
|
2500
2806
|
rpc("dsh-memory/llm-providers", {}).then((r) => {
|
|
@@ -2517,46 +2823,46 @@ var __defProp = Object.defineProperty;
|
|
|
2517
2823
|
...["l1", "l2", "l3"].map((k) => ({
|
|
2518
2824
|
key: k,
|
|
2519
2825
|
title: LAYER_META[k].title + " · " + (dotOf(k) === "runtime" ? "运行时自定义" : dotOf(k) === "static" ? "部署 YAML 层链(只读)" : "跟随全局"),
|
|
2520
|
-
label: /* @__PURE__ */ (0,
|
|
2521
|
-
/* @__PURE__ */ (0,
|
|
2826
|
+
label: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
|
|
2827
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Dot, { kind: dotOf(k) }),
|
|
2522
2828
|
LAYER_META[k].seg
|
|
2523
2829
|
] })
|
|
2524
2830
|
}))
|
|
2525
2831
|
];
|
|
2526
2832
|
const chipTitle = (k) => dotOf(k) === "runtime" ? "本层走设置页自定义链" : dotOf(k) === "static" ? "本层走部署 YAML 层链(UI 只读,自定义可覆盖)" : "本层未单独配置,走全局默认链";
|
|
2527
|
-
return /* @__PURE__ */ (0,
|
|
2528
|
-
/* @__PURE__ */ (0,
|
|
2529
|
-
/* @__PURE__ */ (0,
|
|
2530
|
-
/* @__PURE__ */ (0,
|
|
2833
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
2834
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Segmented, { value: tab, options: segOptions, onChange: (k) => setTab(k) }),
|
|
2835
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: STY3.hint, children: [
|
|
2836
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Dot, { kind: "runtime" }),
|
|
2531
2837
|
" 自定义 · ",
|
|
2532
|
-
/* @__PURE__ */ (0,
|
|
2838
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Dot, { kind: "static" }),
|
|
2533
2839
|
" 部署 YAML · ",
|
|
2534
|
-
/* @__PURE__ */ (0,
|
|
2840
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Dot, { kind: "global" }),
|
|
2535
2841
|
" 跟随全局",
|
|
2536
|
-
/* @__PURE__ */ (0,
|
|
2842
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { title: "每层实际链:运行时自定义 → 部署 YAML 层链 → 全局默认链,逐级兜底;部署 pin 时运行时编辑只读", children: "(层链优先于全局)" })
|
|
2537
2843
|
] }),
|
|
2538
|
-
tab === "g" ? /* @__PURE__ */ (0,
|
|
2539
|
-
/* @__PURE__ */ (0,
|
|
2540
|
-
/* @__PURE__ */ (0,
|
|
2541
|
-
/* @__PURE__ */ (0,
|
|
2542
|
-
/* @__PURE__ */ (0,
|
|
2844
|
+
tab === "g" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
2845
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: STY3.panelHead, children: [
|
|
2846
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: STY3.panelTitle, children: "全局默认链" }),
|
|
2847
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...STY3.chip, ...STY3.chipAccent }, children: "运行时 · 可编辑" }),
|
|
2848
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...STY3.inUse, marginLeft: "auto" }, children: users.length ? "在用:" + users.map((k) => LAYER_META[k].seg).join("、") : "当前无层使用" })
|
|
2543
2849
|
] }),
|
|
2544
|
-
/* @__PURE__ */ (0,
|
|
2545
|
-
/* @__PURE__ */ (0,
|
|
2546
|
-
info?.channel ? /* @__PURE__ */ (0,
|
|
2547
|
-
] }) : /* @__PURE__ */ (0,
|
|
2548
|
-
/* @__PURE__ */ (0,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2550
|
-
/* @__PURE__ */ (0,
|
|
2850
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RouteChainEditor, { rpc, disabled }, "g"),
|
|
2851
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(BudgetInputs, { rpc, disabled, data: props.data, setData: props.setData, onError: props.onError, scope: "input" }, "g-budget"),
|
|
2852
|
+
info?.channel ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChannelEditor, { channel: info.channel, rpc, disabled }) : null
|
|
2853
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
2854
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: STY3.panelHead, children: [
|
|
2855
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: STY3.panelTitle, children: LAYER_META[tab].title }),
|
|
2856
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...STY3.chip, ...dotOf(tab) === "runtime" ? STY3.chipAccent : STY3.chipMuted }, title: chipTitle(tab), children: dotOf(tab) === "runtime" ? "运行时自定义" : dotOf(tab) === "static" ? "静态 · YAML" : "跟随全局" })
|
|
2551
2857
|
] }),
|
|
2552
|
-
/* @__PURE__ */ (0,
|
|
2553
|
-
/* @__PURE__ */ (0,
|
|
2858
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RouteChainEditor, { rpc, disabled, scope: tab }, tab),
|
|
2859
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(BudgetInputs, { rpc, disabled, data: props.data, setData: props.setData, onError: props.onError, scope: tab }, tab + "-budget")
|
|
2554
2860
|
] })
|
|
2555
2861
|
] });
|
|
2556
2862
|
}
|
|
2557
2863
|
|
|
2558
2864
|
// client/src/tabs/EmbeddingSection.tsx
|
|
2559
|
-
var
|
|
2865
|
+
var import_react13 = require("react");
|
|
2560
2866
|
|
|
2561
2867
|
// client/src/dimensions.ts
|
|
2562
2868
|
var DIMS_MIN = 1;
|
|
@@ -2604,7 +2910,7 @@ var __defProp = Object.defineProperty;
|
|
|
2604
2910
|
}
|
|
2605
2911
|
|
|
2606
2912
|
// client/src/tabs/EmbeddingSection.tsx
|
|
2607
|
-
var
|
|
2913
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2608
2914
|
var RSTY = {
|
|
2609
2915
|
block: { marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--dsh-mem-border)" },
|
|
2610
2916
|
title: { fontSize: 12, fontWeight: 600, color: "var(--dsh-mem-text-3)", margin: "0 0 2px" },
|
|
@@ -2628,17 +2934,17 @@ var __defProp = Object.defineProperty;
|
|
|
2628
2934
|
function EmbeddingSection(props) {
|
|
2629
2935
|
const rpc = props.rpc;
|
|
2630
2936
|
const loose = asLoose(rpc);
|
|
2631
|
-
const [st, setSt] = (0,
|
|
2632
|
-
const [err, setErr] = (0,
|
|
2633
|
-
const busyPollRef = (0,
|
|
2634
|
-
const [rBase, setRBase] = (0,
|
|
2635
|
-
const [rModel, setRModel] = (0,
|
|
2636
|
-
const [rDims, setRDims] = (0,
|
|
2637
|
-
const [rKey, setRKey] = (0,
|
|
2638
|
-
const remoteDirty = (0,
|
|
2639
|
-
const baseTimer = (0,
|
|
2640
|
-
const modelTimer = (0,
|
|
2641
|
-
const load = (0,
|
|
2937
|
+
const [st, setSt] = (0, import_react13.useState)(null);
|
|
2938
|
+
const [err, setErr] = (0, import_react13.useState)(null);
|
|
2939
|
+
const busyPollRef = (0, import_react13.useRef)(null);
|
|
2940
|
+
const [rBase, setRBase] = (0, import_react13.useState)("");
|
|
2941
|
+
const [rModel, setRModel] = (0, import_react13.useState)("");
|
|
2942
|
+
const [rDims, setRDims] = (0, import_react13.useState)("");
|
|
2943
|
+
const [rKey, setRKey] = (0, import_react13.useState)("");
|
|
2944
|
+
const remoteDirty = (0, import_react13.useRef)({ base: false, model: false, dims: false });
|
|
2945
|
+
const baseTimer = (0, import_react13.useRef)(void 0);
|
|
2946
|
+
const modelTimer = (0, import_react13.useRef)(void 0);
|
|
2947
|
+
const load = (0, import_react13.useCallback)(() => {
|
|
2642
2948
|
rpc("dsh-memory/embedding-state-get", {}).then((r) => {
|
|
2643
2949
|
if (r && r.ok && r.value && r.value.supported !== false) {
|
|
2644
2950
|
const v = r.value;
|
|
@@ -2657,10 +2963,10 @@ var __defProp = Object.defineProperty;
|
|
|
2657
2963
|
setErr(String(e && e.message || e));
|
|
2658
2964
|
});
|
|
2659
2965
|
}, [rpc]);
|
|
2660
|
-
(0,
|
|
2966
|
+
(0, import_react13.useEffect)(() => {
|
|
2661
2967
|
load();
|
|
2662
2968
|
}, [load]);
|
|
2663
|
-
(0,
|
|
2969
|
+
(0, import_react13.useEffect)(() => {
|
|
2664
2970
|
let stopped = false;
|
|
2665
2971
|
const busyFlag = { v: false };
|
|
2666
2972
|
busyPollRef.current = busyFlag;
|
|
@@ -2676,11 +2982,11 @@ var __defProp = Object.defineProperty;
|
|
|
2676
2982
|
busyPollRef.current = null;
|
|
2677
2983
|
};
|
|
2678
2984
|
}, [load]);
|
|
2679
|
-
(0,
|
|
2985
|
+
(0, import_react13.useEffect)(() => () => {
|
|
2680
2986
|
clearTimeout(baseTimer.current);
|
|
2681
2987
|
clearTimeout(modelTimer.current);
|
|
2682
2988
|
}, []);
|
|
2683
|
-
(0,
|
|
2989
|
+
(0, import_react13.useEffect)(() => {
|
|
2684
2990
|
if (!st || !st.remote) return;
|
|
2685
2991
|
if (!remoteDirty.current.base) setRBase(st.remote.baseURL || "");
|
|
2686
2992
|
if (!remoteDirty.current.model) setRModel(st.remote.model || "");
|
|
@@ -2728,7 +3034,7 @@ var __defProp = Object.defineProperty;
|
|
|
2728
3034
|
if (v) commitRemote({ embedRemoteApiKey: v });
|
|
2729
3035
|
setRKey("");
|
|
2730
3036
|
};
|
|
2731
|
-
const
|
|
3037
|
+
const call2 = (endpoint, payload, confirmText) => {
|
|
2732
3038
|
if (confirmText && !window.confirm(confirmText)) return;
|
|
2733
3039
|
loose(endpoint, payload).then((r) => {
|
|
2734
3040
|
if (!r || !r.ok) setErr(r && r.error ? r.error.message : "操作失败");
|
|
@@ -2741,15 +3047,15 @@ var __defProp = Object.defineProperty;
|
|
|
2741
3047
|
});
|
|
2742
3048
|
};
|
|
2743
3049
|
if (err === "__unsupported__") {
|
|
2744
|
-
return /* @__PURE__ */ (0,
|
|
2745
|
-
/* @__PURE__ */ (0,
|
|
2746
|
-
/* @__PURE__ */ (0,
|
|
3050
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
3051
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: "语义检索(嵌入)" }),
|
|
3052
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", children: "存储处于降级状态,嵌入管理不可用。" })
|
|
2747
3053
|
] });
|
|
2748
3054
|
}
|
|
2749
3055
|
if (!st) {
|
|
2750
|
-
return /* @__PURE__ */ (0,
|
|
2751
|
-
/* @__PURE__ */ (0,
|
|
2752
|
-
err ? /* @__PURE__ */ (0,
|
|
3056
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
3057
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", children: err ? "嵌入状态读取失败:" + err : "嵌入状态读取中…" }),
|
|
3058
|
+
err ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NButton, { style: { marginTop: 8 }, onClick: load, children: "重试" }) : null
|
|
2753
3059
|
] });
|
|
2754
3060
|
}
|
|
2755
3061
|
const switchConfirm = "切换嵌入源后将按新模型重建向量索引(期间语义检索暂退化为关键词匹配,不影响对话)。确定切换?";
|
|
@@ -2762,10 +3068,10 @@ var __defProp = Object.defineProperty;
|
|
|
2762
3068
|
return;
|
|
2763
3069
|
}
|
|
2764
3070
|
const current = st.activeModel && ready.indexOf(st.activeModel) >= 0 ? st.activeModel : ready[0];
|
|
2765
|
-
|
|
3071
|
+
call2("dsh-memory/embedding-source-set", { source: "local", activeModel: current }, switchConfirm);
|
|
2766
3072
|
return;
|
|
2767
3073
|
}
|
|
2768
|
-
|
|
3074
|
+
call2("dsh-memory/embedding-source-set", { source: key }, key === "remote" ? switchConfirm : null);
|
|
2769
3075
|
};
|
|
2770
3076
|
const dl = st.download;
|
|
2771
3077
|
const dlActive = dl && (dl.phase === "downloading" || dl.phase === "verifying");
|
|
@@ -2775,40 +3081,40 @@ var __defProp = Object.defineProperty;
|
|
|
2775
3081
|
const remote = st.remote;
|
|
2776
3082
|
let runtimeRow = null;
|
|
2777
3083
|
if (rt.phase === "installing") {
|
|
2778
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
2779
|
-
/* @__PURE__ */ (0,
|
|
2780
|
-
/* @__PURE__ */ (0,
|
|
2781
|
-
/* @__PURE__ */ (0,
|
|
2782
|
-
/* @__PURE__ */ (0,
|
|
3084
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { marginTop: 8, fontSize: 12 }, children: [
|
|
3085
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3086
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "安装推理运行时中… 已耗时 " + Math.round(rt.elapsedMs / 1e3) + "s(约 100~200MB,视网络)" }),
|
|
3087
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.grow }),
|
|
3088
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NButton, { onClick: () => call2("dsh-memory/embedding-runtime-cancel", {}), children: "取消" })
|
|
2783
3089
|
] }),
|
|
2784
|
-
/* @__PURE__ */ (0,
|
|
3090
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("pre", { style: { ...S.pre, maxHeight: 68, marginTop: 6, fontSize: 11, opacity: 0.85 }, children: (rt.lastLines || []).join("\n") || "等待 npm 输出…" })
|
|
2785
3091
|
] });
|
|
2786
3092
|
} else if (rt.phase === "error") {
|
|
2787
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
3093
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: "运行时安装失败:" + (rt.error || "未知") + "(重新切换嵌入源可重试)" });
|
|
2788
3094
|
} else if (rt.phase === "ready") {
|
|
2789
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
3095
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "推理运行时就绪(transformers.js v" + rt.installedVersion + ")" });
|
|
2790
3096
|
} else if (st.source === "local") {
|
|
2791
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
3097
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "首次启用本地嵌入时会自动安装推理运行时(约 100~200MB)。" });
|
|
2792
3098
|
}
|
|
2793
3099
|
let applyRow = null;
|
|
2794
3100
|
if (ap.phase === "warming") {
|
|
2795
|
-
applyRow = /* @__PURE__ */ (0,
|
|
3101
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "加载嵌入模型中…(首次需数秒)" });
|
|
2796
3102
|
} else if (ap.phase === "switching") {
|
|
2797
|
-
applyRow = /* @__PURE__ */ (0,
|
|
3103
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "切换嵌入源中…" });
|
|
2798
3104
|
} else if (ap.phase === "error") {
|
|
2799
|
-
applyRow = /* @__PURE__ */ (0,
|
|
3105
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: "切换失败:" + ap.message + "(已保存的嵌入源不变,重启后仍按原源运行)" });
|
|
2800
3106
|
} else if (st.reindex && st.reindex.running) {
|
|
2801
3107
|
const rj = st.reindex;
|
|
2802
3108
|
const rDone = rj.l1Done + rj.l0Done;
|
|
2803
3109
|
const rTotal = rj.l1Total + rj.l0Total;
|
|
2804
3110
|
const rPct = rTotal > 0 ? Math.round(rDone / rTotal * 100) : 0;
|
|
2805
|
-
applyRow = /* @__PURE__ */ (0,
|
|
2806
|
-
/* @__PURE__ */ (0,
|
|
2807
|
-
/* @__PURE__ */ (0,
|
|
2808
|
-
/* @__PURE__ */ (0,
|
|
2809
|
-
/* @__PURE__ */ (0,
|
|
3111
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { marginTop: 8 }, children: [
|
|
3112
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3113
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dsh-mem-rb-muted", children: "重嵌入中 L1 " + rj.l1Done + "/" + rj.l1Total + " · L0 " + rj.l0Done + "/" + rj.l0Total + "(" + rPct + "%)" }),
|
|
3114
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.grow }),
|
|
3115
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NButton, { onClick: () => call2("dsh-memory/embedding-reindex-cancel", {}), children: "取消" })
|
|
2810
3116
|
] }),
|
|
2811
|
-
/* @__PURE__ */ (0,
|
|
3117
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { ...S.flexRow, marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-bar", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-fill", style: { width: rPct + "%" } }) }) })
|
|
2812
3118
|
] });
|
|
2813
3119
|
}
|
|
2814
3120
|
const modelCards = st.models.map((m) => {
|
|
@@ -2817,61 +3123,61 @@ var __defProp = Object.defineProperty;
|
|
|
2817
3123
|
const pct = mDl && dl.overallTotal > 0 ? Math.round(dl.overallReceived / dl.overallTotal * 100) : 0;
|
|
2818
3124
|
let action;
|
|
2819
3125
|
if (mDl) {
|
|
2820
|
-
action = /* @__PURE__ */ (0,
|
|
2821
|
-
/* @__PURE__ */ (0,
|
|
2822
|
-
/* @__PURE__ */ (0,
|
|
2823
|
-
/* @__PURE__ */ (0,
|
|
2824
|
-
/* @__PURE__ */ (0,
|
|
3126
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { flex: 1, minWidth: 200 }, children: [
|
|
3127
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3128
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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" : "") + ")" }),
|
|
3129
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.grow }),
|
|
3130
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NButton, { onClick: () => call2("dsh-memory/embedding-download-cancel", {}), children: "取消" })
|
|
2825
3131
|
] }),
|
|
2826
|
-
/* @__PURE__ */ (0,
|
|
3132
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { ...S.flexRow, marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-bar", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-fill", style: { width: pct + "%" } }) }) })
|
|
2827
3133
|
] });
|
|
2828
3134
|
} else if (isActive) {
|
|
2829
|
-
action = /* @__PURE__ */ (0,
|
|
2830
|
-
/* @__PURE__ */ (0,
|
|
2831
|
-
localInfo && localInfo.state === "loading" ? /* @__PURE__ */ (0,
|
|
2832
|
-
localInfo && localInfo.state === "failed" ? /* @__PURE__ */ (0,
|
|
2833
|
-
localInfo && localInfo.state === "ready" ? /* @__PURE__ */ (0,
|
|
3135
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3136
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dsh-mem-tag dsh-mem-tag-work-task", children: "使用中" }),
|
|
3137
|
+
localInfo && localInfo.state === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dsh-mem-rb-muted", children: "模型加载中…" }) : null,
|
|
3138
|
+
localInfo && localInfo.state === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-danger)" }, children: "加载失败:" + (localInfo.error || "") }) : null,
|
|
3139
|
+
localInfo && localInfo.state === "ready" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dsh-mem-rb-muted", children: "已就绪" }) : null
|
|
2834
3140
|
] });
|
|
2835
3141
|
} else if (m.state === "downloaded") {
|
|
2836
|
-
action = /* @__PURE__ */ (0,
|
|
2837
|
-
/* @__PURE__ */ (0,
|
|
3142
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3143
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2838
3144
|
NButton,
|
|
2839
3145
|
{
|
|
2840
3146
|
disabled: ap.busy,
|
|
2841
|
-
onClick: () =>
|
|
3147
|
+
onClick: () => call2("dsh-memory/embedding-source-set", { source: "local", activeModel: m.id }, switchConfirm),
|
|
2842
3148
|
children: "启用"
|
|
2843
3149
|
}
|
|
2844
3150
|
),
|
|
2845
|
-
/* @__PURE__ */ (0,
|
|
3151
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2846
3152
|
NButton,
|
|
2847
3153
|
{
|
|
2848
3154
|
disabled: dlActive,
|
|
2849
|
-
onClick: () =>
|
|
3155
|
+
onClick: () => call2("dsh-memory/embedding-model-delete", { modelId: m.id }, "删除已下载的 " + m.name + "(" + fmtMB(m.totalBytes) + ")?"),
|
|
2850
3156
|
children: "删除"
|
|
2851
3157
|
}
|
|
2852
3158
|
)
|
|
2853
3159
|
] });
|
|
2854
3160
|
} else {
|
|
2855
|
-
action = /* @__PURE__ */ (0,
|
|
3161
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2856
3162
|
NButton,
|
|
2857
3163
|
{
|
|
2858
3164
|
disabled: dlActive || !st.ceilings.local,
|
|
2859
3165
|
title: !st.ceilings.local ? "部署已禁用本地嵌入模型" : "",
|
|
2860
|
-
onClick: () =>
|
|
3166
|
+
onClick: () => call2("dsh-memory/embedding-download-start", { modelId: m.id }),
|
|
2861
3167
|
children: (m.state === "partial" ? "继续下载 " : "下载 ") + fmtMB(m.totalBytes)
|
|
2862
3168
|
}
|
|
2863
3169
|
);
|
|
2864
3170
|
}
|
|
2865
|
-
return /* @__PURE__ */ (0,
|
|
3171
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2866
3172
|
"div",
|
|
2867
3173
|
{
|
|
2868
3174
|
style: { ...S.flexRow, padding: "8px 0", borderBottom: "1px solid var(--dsh-mem-border)", flexWrap: "wrap" },
|
|
2869
3175
|
children: [
|
|
2870
|
-
/* @__PURE__ */ (0,
|
|
2871
|
-
/* @__PURE__ */ (0,
|
|
2872
|
-
/* @__PURE__ */ (0,
|
|
3176
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { minWidth: 150 }, children: [
|
|
3177
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontWeight: 600 }, children: m.name }),
|
|
3178
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", children: m.tags.join(" · ") + " · " + m.dims + " 维 · 上下文 " + m.contextTokens })
|
|
2873
3179
|
] }),
|
|
2874
|
-
/* @__PURE__ */ (0,
|
|
3180
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { flex: 1, minWidth: 180, fontSize: 12, color: "var(--dsh-mem-text-2)" }, children: m.description }),
|
|
2875
3181
|
action
|
|
2876
3182
|
]
|
|
2877
3183
|
},
|
|
@@ -2880,15 +3186,17 @@ var __defProp = Object.defineProperty;
|
|
|
2880
3186
|
});
|
|
2881
3187
|
const vec = st.vectors;
|
|
2882
3188
|
const vecOk = !!vec && vec.l1.embedded >= 0 && vec.l0.embedded >= 0;
|
|
2883
|
-
const
|
|
3189
|
+
const lastRun = st.reindex ? st.reindex.last : void 0;
|
|
3190
|
+
const lastNote = !lastRun ? "" : " · 上次重建:处理 " + lastRun.processed + "/" + lastRun.planned + " 条" + (lastRun.failed > 0 ? "、失败 " + lastRun.failed : "") + (lastRun.cancelled ? "(被取消)" : "") + ",待补 " + (lastRun.missingBefore.l1 + lastRun.missingBefore.l0) + " → " + (lastRun.missingAfter.l1 + lastRun.missingAfter.l0) + ",用时 " + (lastRun.durationMs / 1e3).toFixed(1) + "s";
|
|
3191
|
+
const vecNote = !vec ? "向量索引:宿主版本较旧,未上报计数" : !vecOk ? "向量索引不可用(sqlite-vec 扩展缺失或检索库降级),重建无从谈起" : "已嵌入 L1 " + vec.l1.embedded + "/" + vec.l1.total + " · L0 " + vec.l0.embedded + "/" + vec.l0.total + (vec.l1.missing + vec.l0.missing > 0 ? "(待补 " + (vec.l1.missing + vec.l0.missing) + " 条)" : "") + (vec.l1.skipped + vec.l0.skipped > 0 ? "(" + (vec.l1.skipped + vec.l0.skipped) + " 条内容不可嵌入,已跳过)" : "") + lastNote;
|
|
2884
3192
|
const reindexRunning = !!(st.reindex && st.reindex.running);
|
|
2885
3193
|
const canRebuild = vecOk && st.source !== "off" && !reindexRunning && !st.apply.busy;
|
|
2886
3194
|
const rebuildHint = !vecOk ? "向量能力不可用" : st.source === "off" ? "嵌入源已关闭,请先启用" : reindexRunning ? "重建已在进行中" : st.apply.busy ? "嵌入源切换进行中" : "只补缺失向量;已有向量不动。零向量内容会被跳过(重试无意义)";
|
|
2887
|
-
return /* @__PURE__ */ (0,
|
|
2888
|
-
/* @__PURE__ */ (0,
|
|
2889
|
-
/* @__PURE__ */ (0,
|
|
2890
|
-
/* @__PURE__ */ (0,
|
|
2891
|
-
/* @__PURE__ */ (0,
|
|
3195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
3196
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3197
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontWeight: 600, whiteSpace: "nowrap" }, children: "语义检索(嵌入源)" }),
|
|
3198
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.grow }),
|
|
3199
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2892
3200
|
Segmented,
|
|
2893
3201
|
{
|
|
2894
3202
|
value: st.source,
|
|
@@ -2901,18 +3209,18 @@ var __defProp = Object.defineProperty;
|
|
|
2901
3209
|
}
|
|
2902
3210
|
)
|
|
2903
3211
|
] }),
|
|
2904
|
-
/* @__PURE__ */ (0,
|
|
2905
|
-
st.activeNote ? /* @__PURE__ */ (0,
|
|
2906
|
-
err && err !== "__unsupported__" ? /* @__PURE__ */ (0,
|
|
2907
|
-
dl && dl.phase === "error" ? /* @__PURE__ */ (0,
|
|
3212
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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 + ")" : "") }),
|
|
3213
|
+
st.activeNote ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginTop: 4, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: st.activeNote }) : null,
|
|
3214
|
+
err && err !== "__unsupported__" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginTop: 6, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: err }) : null,
|
|
3215
|
+
dl && dl.phase === "error" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginTop: 6, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: "下载失败:" + (dl.error || "") }) : null,
|
|
2908
3216
|
runtimeRow,
|
|
2909
3217
|
applyRow,
|
|
2910
|
-
/* @__PURE__ */ (0,
|
|
2911
|
-
/* @__PURE__ */ (0,
|
|
2912
|
-
/* @__PURE__ */ (0,
|
|
2913
|
-
/* @__PURE__ */ (0,
|
|
2914
|
-
/* @__PURE__ */ (0,
|
|
2915
|
-
/* @__PURE__ */ (0,
|
|
3218
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: RSTY.block, children: [
|
|
3219
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: RSTY.title, children: "远程连接(生效值;运行时覆盖优先于部署 YAML)" }),
|
|
3220
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: RSTY.note, children: "生效端点 " + (remote.baseURL || "(未配置)") + " · 模型 " + (remote.model || "(未配置)") + " · " + (remote.dimensions > 0 ? remote.dimensions + " 维" : "维度跟随部署") + (remote.apiKeySet ? " · 密钥已设置" : " · 密钥未设置") }),
|
|
3221
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: RSTY.row, children: [
|
|
3222
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.label, children: "端点 URL" }),
|
|
3223
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2916
3224
|
NInput,
|
|
2917
3225
|
{
|
|
2918
3226
|
style: RSTY.input,
|
|
@@ -2929,9 +3237,9 @@ var __defProp = Object.defineProperty;
|
|
|
2929
3237
|
}
|
|
2930
3238
|
)
|
|
2931
3239
|
] }),
|
|
2932
|
-
/* @__PURE__ */ (0,
|
|
2933
|
-
/* @__PURE__ */ (0,
|
|
2934
|
-
/* @__PURE__ */ (0,
|
|
3240
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: RSTY.row, children: [
|
|
3241
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.label, children: "模型名" }),
|
|
3242
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2935
3243
|
NInput,
|
|
2936
3244
|
{
|
|
2937
3245
|
style: RSTY.input,
|
|
@@ -2947,8 +3255,8 @@ var __defProp = Object.defineProperty;
|
|
|
2947
3255
|
}
|
|
2948
3256
|
}
|
|
2949
3257
|
),
|
|
2950
|
-
/* @__PURE__ */ (0,
|
|
2951
|
-
/* @__PURE__ */ (0,
|
|
3258
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.label, children: "维度" }),
|
|
3259
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2952
3260
|
NInput,
|
|
2953
3261
|
{
|
|
2954
3262
|
style: { width: 90, minWidth: 0, flex: "0 1 90px" },
|
|
@@ -2968,9 +3276,9 @@ var __defProp = Object.defineProperty;
|
|
|
2968
3276
|
}
|
|
2969
3277
|
)
|
|
2970
3278
|
] }),
|
|
2971
|
-
/* @__PURE__ */ (0,
|
|
2972
|
-
/* @__PURE__ */ (0,
|
|
2973
|
-
/* @__PURE__ */ (0,
|
|
3279
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: RSTY.row, children: [
|
|
3280
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.label, children: "API Key" }),
|
|
3281
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2974
3282
|
NInput,
|
|
2975
3283
|
{
|
|
2976
3284
|
style: RSTY.input,
|
|
@@ -2985,8 +3293,8 @@ var __defProp = Object.defineProperty;
|
|
|
2985
3293
|
onBlur: commitRemoteKey
|
|
2986
3294
|
}
|
|
2987
3295
|
),
|
|
2988
|
-
remote.apiKeySet ? /* @__PURE__ */ (0,
|
|
2989
|
-
/* @__PURE__ */ (0,
|
|
3296
|
+
remote.apiKeySet ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.chipAccent, children: "已设置" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.chipMuted, children: "未设置" }),
|
|
3297
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2990
3298
|
NButton,
|
|
2991
3299
|
{
|
|
2992
3300
|
title: "写入空串清除运行时密钥(部署 YAML 的密钥不受影响)",
|
|
@@ -2996,17 +3304,17 @@ var __defProp = Object.defineProperty;
|
|
|
2996
3304
|
)
|
|
2997
3305
|
] })
|
|
2998
3306
|
] }),
|
|
2999
|
-
/* @__PURE__ */ (0,
|
|
3307
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.panelLabel, children: "本地模型目录(下载后离线可用,不随插件分发)" }),
|
|
3000
3308
|
modelCards,
|
|
3001
|
-
/* @__PURE__ */ (0,
|
|
3002
|
-
/* @__PURE__ */ (0,
|
|
3003
|
-
/* @__PURE__ */ (0,
|
|
3004
|
-
/* @__PURE__ */ (0,
|
|
3309
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: RSTY.block, children: [
|
|
3310
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: RSTY.title, children: "向量索引" }),
|
|
3311
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: RSTY.note, children: vecNote }),
|
|
3312
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: RSTY.row, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3005
3313
|
NButton,
|
|
3006
3314
|
{
|
|
3007
3315
|
disabled: !canRebuild,
|
|
3008
3316
|
title: rebuildHint,
|
|
3009
|
-
onClick: () =>
|
|
3317
|
+
onClick: () => call2("dsh-memory/embedding-reindex", {}),
|
|
3010
3318
|
children: "重建索引"
|
|
3011
3319
|
}
|
|
3012
3320
|
) })
|
|
@@ -3015,8 +3323,8 @@ var __defProp = Object.defineProperty;
|
|
|
3015
3323
|
}
|
|
3016
3324
|
|
|
3017
3325
|
// client/src/tabs/RebuildPanel.tsx
|
|
3018
|
-
var
|
|
3019
|
-
var
|
|
3326
|
+
var import_react14 = require("react");
|
|
3327
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3020
3328
|
var RB_PHASE_LABEL = {
|
|
3021
3329
|
preparing: "准备中(归档旧数据 · 清空检索库)",
|
|
3022
3330
|
distilling: "分块蒸馏中",
|
|
@@ -3024,21 +3332,21 @@ var __defProp = Object.defineProperty;
|
|
|
3024
3332
|
};
|
|
3025
3333
|
function RebuildPanel(props) {
|
|
3026
3334
|
const rpc = props.rpc;
|
|
3027
|
-
const [rbRaw, setRb] = (0,
|
|
3028
|
-
const [confirmOpen, setConfirmOpen] = (0,
|
|
3029
|
-
const [busy, setBusy] = (0,
|
|
3030
|
-
const [rbError, setRbError] = (0,
|
|
3031
|
-
const refresh = (0,
|
|
3335
|
+
const [rbRaw, setRb] = (0, import_react14.useState)(null);
|
|
3336
|
+
const [confirmOpen, setConfirmOpen] = (0, import_react14.useState)(false);
|
|
3337
|
+
const [busy, setBusy] = (0, import_react14.useState)(false);
|
|
3338
|
+
const [rbError, setRbError] = (0, import_react14.useState)(null);
|
|
3339
|
+
const refresh = (0, import_react14.useCallback)(() => {
|
|
3032
3340
|
rpc("dsh-memory/rebuild-status", {}).then((r) => {
|
|
3033
3341
|
if (r && r.ok) setRb(r.value);
|
|
3034
3342
|
}).catch(() => {
|
|
3035
3343
|
});
|
|
3036
3344
|
}, [rpc]);
|
|
3037
|
-
(0,
|
|
3345
|
+
(0, import_react14.useEffect)(() => {
|
|
3038
3346
|
refresh();
|
|
3039
3347
|
}, [refresh]);
|
|
3040
3348
|
const running = !!(rbRaw && rbRaw.running);
|
|
3041
|
-
(0,
|
|
3349
|
+
(0, import_react14.useEffect)(() => {
|
|
3042
3350
|
if (!running) return;
|
|
3043
3351
|
const timer = setInterval(refresh, 1500);
|
|
3044
3352
|
return () => {
|
|
@@ -3083,11 +3391,11 @@ var __defProp = Object.defineProperty;
|
|
|
3083
3391
|
} else if (!running && rb.phase === "failed") {
|
|
3084
3392
|
lastNote = "上次重建:失败:" + (rb.error || "未知错误");
|
|
3085
3393
|
}
|
|
3086
|
-
return /* @__PURE__ */ (0,
|
|
3087
|
-
/* @__PURE__ */ (0,
|
|
3088
|
-
/* @__PURE__ */ (0,
|
|
3089
|
-
/* @__PURE__ */ (0,
|
|
3090
|
-
running ? /* @__PURE__ */ (0,
|
|
3394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
3395
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }, children: [
|
|
3396
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 600, whiteSpace: "nowrap" }, children: "重建记忆" }),
|
|
3397
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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;旧数据先归档(不删除)" }),
|
|
3398
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NButton, { disabled: busy || rb.cancelRequested, onClick: cancel, children: rb.cancelRequested ? "取消中…" : "取消重建" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3091
3399
|
NButton,
|
|
3092
3400
|
{
|
|
3093
3401
|
disabled: busy || empty,
|
|
@@ -3100,13 +3408,13 @@ var __defProp = Object.defineProperty;
|
|
|
3100
3408
|
}
|
|
3101
3409
|
)
|
|
3102
3410
|
] }),
|
|
3103
|
-
running ? /* @__PURE__ */ (0,
|
|
3104
|
-
/* @__PURE__ */ (0,
|
|
3105
|
-
/* @__PURE__ */ (0,
|
|
3411
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, marginTop: 10 }, children: [
|
|
3412
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "dsh-mem-rb-bar", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "dsh-mem-rb-fill", style: { width: pct + "%" } }) }),
|
|
3413
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "dsh-mem-rb-muted", style: { whiteSpace: "nowrap" }, children: "产出 " + rb.recordsBuilt + " 条" })
|
|
3106
3414
|
] }) : null,
|
|
3107
|
-
lastNote ? /* @__PURE__ */ (0,
|
|
3108
|
-
rbError ? /* @__PURE__ */ (0,
|
|
3109
|
-
confirmOpen ? /* @__PURE__ */ (0,
|
|
3415
|
+
lastNote ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: lastNote }) : null,
|
|
3416
|
+
rbError ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: rbError }) : null,
|
|
3417
|
+
confirmOpen ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3110
3418
|
NModal,
|
|
3111
3419
|
{
|
|
3112
3420
|
open: true,
|
|
@@ -3115,7 +3423,7 @@ var __defProp = Object.defineProperty;
|
|
|
3115
3423
|
},
|
|
3116
3424
|
title: "确认重建全部记忆?",
|
|
3117
3425
|
footer: [
|
|
3118
|
-
/* @__PURE__ */ (0,
|
|
3426
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3119
3427
|
NButton,
|
|
3120
3428
|
{
|
|
3121
3429
|
onClick: () => {
|
|
@@ -3125,15 +3433,15 @@ var __defProp = Object.defineProperty;
|
|
|
3125
3433
|
},
|
|
3126
3434
|
"cancel"
|
|
3127
3435
|
),
|
|
3128
|
-
/* @__PURE__ */ (0,
|
|
3436
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NButton, { variant: "primary", disabled: busy, onClick: start, children: busy ? "启动中…" : "开始重建" }, "confirm")
|
|
3129
3437
|
],
|
|
3130
3438
|
children: [
|
|
3131
|
-
/* @__PURE__ */ (0,
|
|
3439
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3132
3440
|
"将以 L0 原始对话为事实源重新蒸馏:",
|
|
3133
|
-
/* @__PURE__ */ (0,
|
|
3441
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("b", { children: rb.sessionCount + " 个会话 · " + rb.messageCount + " 条消息" }),
|
|
3134
3442
|
",预计 ≥" + rb.estCalls + " 次蒸馏调用。"
|
|
3135
3443
|
] }),
|
|
3136
|
-
/* @__PURE__ */ (0,
|
|
3444
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { marginTop: 8 }, children: "现有 L1 记忆 / L2 场景 / L3 画像会整体归档(*.bak.时间戳,可手工找回),随后清空重建;重建期间可正常对话,新对话的蒸馏优先进行;中途可取消,已重建部分保留。" })
|
|
3137
3445
|
]
|
|
3138
3446
|
}
|
|
3139
3447
|
) : null
|
|
@@ -3141,8 +3449,8 @@ var __defProp = Object.defineProperty;
|
|
|
3141
3449
|
}
|
|
3142
3450
|
|
|
3143
3451
|
// client/src/tabs/RuminatePanel.tsx
|
|
3144
|
-
var
|
|
3145
|
-
var
|
|
3452
|
+
var import_react15 = require("react");
|
|
3453
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3146
3454
|
var RM_PHASE_LABEL = {
|
|
3147
3455
|
refreshing: "轻量刷新中",
|
|
3148
3456
|
distilling: "L1 蒸馏中",
|
|
@@ -3163,11 +3471,11 @@ var __defProp = Object.defineProperty;
|
|
|
3163
3471
|
var RM_IDLE_INTERVAL = 3e4;
|
|
3164
3472
|
function RuminatePanel(props) {
|
|
3165
3473
|
const rpc = props.rpc;
|
|
3166
|
-
const [rmRaw, setRm] = (0,
|
|
3167
|
-
const [confirmOpen, setConfirmOpen] = (0,
|
|
3168
|
-
const [busy, setBusy] = (0,
|
|
3169
|
-
const [rmError, setRmError] = (0,
|
|
3170
|
-
const refresh = (0,
|
|
3474
|
+
const [rmRaw, setRm] = (0, import_react15.useState)(null);
|
|
3475
|
+
const [confirmOpen, setConfirmOpen] = (0, import_react15.useState)(false);
|
|
3476
|
+
const [busy, setBusy] = (0, import_react15.useState)(false);
|
|
3477
|
+
const [rmError, setRmError] = (0, import_react15.useState)(null);
|
|
3478
|
+
const refresh = (0, import_react15.useCallback)(() => {
|
|
3171
3479
|
return rpc("dsh-memory/ruminate-status", {}).then((r) => {
|
|
3172
3480
|
if (r && r.ok) {
|
|
3173
3481
|
const st = r.value;
|
|
@@ -3182,14 +3490,14 @@ var __defProp = Object.defineProperty;
|
|
|
3182
3490
|
}).catch(() => {
|
|
3183
3491
|
});
|
|
3184
3492
|
}, [rpc]);
|
|
3185
|
-
const pollRef = (0,
|
|
3186
|
-
const backoffRef = (0,
|
|
3187
|
-
const lastDetailRef = (0,
|
|
3188
|
-
(0,
|
|
3493
|
+
const pollRef = (0, import_react15.useRef)(1500);
|
|
3494
|
+
const backoffRef = (0, import_react15.useRef)(1);
|
|
3495
|
+
const lastDetailRef = (0, import_react15.useRef)(null);
|
|
3496
|
+
(0, import_react15.useEffect)(() => {
|
|
3189
3497
|
refresh();
|
|
3190
3498
|
}, [refresh]);
|
|
3191
3499
|
const running = !!(rmRaw && (rmRaw.running || RM_RUNNING_PHASES.indexOf(rmRaw.phase) >= 0));
|
|
3192
|
-
(0,
|
|
3500
|
+
(0, import_react15.useEffect)(() => {
|
|
3193
3501
|
if (!running) return;
|
|
3194
3502
|
let alive = true;
|
|
3195
3503
|
let timer;
|
|
@@ -3208,13 +3516,13 @@ var __defProp = Object.defineProperty;
|
|
|
3208
3516
|
lastDetailRef.current = null;
|
|
3209
3517
|
};
|
|
3210
3518
|
}, [running, refresh]);
|
|
3211
|
-
(0,
|
|
3519
|
+
(0, import_react15.useEffect)(() => {
|
|
3212
3520
|
if (running) return;
|
|
3213
3521
|
const timer = setInterval(refresh, RM_IDLE_INTERVAL);
|
|
3214
3522
|
return () => clearInterval(timer);
|
|
3215
3523
|
}, [running, refresh]);
|
|
3216
|
-
const [, setTick] = (0,
|
|
3217
|
-
(0,
|
|
3524
|
+
const [, setTick] = (0, import_react15.useState)(0);
|
|
3525
|
+
(0, import_react15.useEffect)(() => {
|
|
3218
3526
|
if (!running) return;
|
|
3219
3527
|
const timer = setInterval(() => setTick((n) => n + 1), 1e3);
|
|
3220
3528
|
return () => clearInterval(timer);
|
|
@@ -3265,11 +3573,11 @@ var __defProp = Object.defineProperty;
|
|
|
3265
3573
|
}
|
|
3266
3574
|
const unit = rm.phase === "refreshing" || rm.phase === "relabeling" ? "步" : "会话";
|
|
3267
3575
|
const progressText = sub ? sub.label + " " + sub.done + "/" + sub.total + "(" + Math.round(sub.done / sub.total * 100) + "%)" : rm.total > 0 ? rm.done + "/" + rm.total + " " + unit + "(" + pct + "%)" : "进行中…";
|
|
3268
|
-
return /* @__PURE__ */ (0,
|
|
3269
|
-
/* @__PURE__ */ (0,
|
|
3270
|
-
/* @__PURE__ */ (0,
|
|
3271
|
-
/* @__PURE__ */ (0,
|
|
3272
|
-
running ? /* @__PURE__ */ (0,
|
|
3576
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
3577
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }, children: [
|
|
3578
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { fontWeight: 600, whiteSpace: "nowrap" }, children: "反刍整理" }),
|
|
3579
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.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" }),
|
|
3580
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(NButton, { disabled: busy || rm.cancelRequested, onClick: cancel, children: rm.cancelRequested ? "取消中…" : "取消整理" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3273
3581
|
NButton,
|
|
3274
3582
|
{
|
|
3275
3583
|
disabled: busy,
|
|
@@ -3282,27 +3590,27 @@ var __defProp = Object.defineProperty;
|
|
|
3282
3590
|
}
|
|
3283
3591
|
)
|
|
3284
3592
|
] }),
|
|
3285
|
-
running ? /* @__PURE__ */ (0,
|
|
3286
|
-
/* @__PURE__ */ (0,
|
|
3593
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, marginTop: 10 }, children: [
|
|
3594
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "dsh-mem-rb-bar", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3287
3595
|
"div",
|
|
3288
3596
|
{
|
|
3289
3597
|
className: "dsh-mem-rb-fill" + (indet ? " dsh-mem-rb-fill-indet" : ""),
|
|
3290
3598
|
style: { width: indet ? "100%" : barPct + "%" }
|
|
3291
3599
|
}
|
|
3292
3600
|
) }),
|
|
3293
|
-
/* @__PURE__ */ (0,
|
|
3601
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "dsh-mem-rb-muted", style: { whiteSpace: "nowrap" }, children: sub ? sub.label + " " + sub.done + "/" + sub.total : "产出 " + rm.recordsBuilt + " 条" })
|
|
3294
3602
|
] }) : null,
|
|
3295
|
-
running && rm.detail ? /* @__PURE__ */ (0,
|
|
3296
|
-
lastNote ? /* @__PURE__ */ (0,
|
|
3297
|
-
rmError ? /* @__PURE__ */ (0,
|
|
3298
|
-
confirmOpen ? /* @__PURE__ */ (0,
|
|
3603
|
+
running && rm.detail ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 6, whiteSpace: "normal" }, children: "当前:" + rm.detail }) : null,
|
|
3604
|
+
lastNote ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: lastNote }) : null,
|
|
3605
|
+
rmError ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: rmError }) : null,
|
|
3606
|
+
confirmOpen ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
3299
3607
|
NModal,
|
|
3300
3608
|
{
|
|
3301
3609
|
open: true,
|
|
3302
3610
|
onClose: () => setConfirmOpen(false),
|
|
3303
3611
|
title: "确认反刍整理?",
|
|
3304
3612
|
footer: [
|
|
3305
|
-
/* @__PURE__ */ (0,
|
|
3613
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3306
3614
|
NButton,
|
|
3307
3615
|
{
|
|
3308
3616
|
onClick: () => setConfirmOpen(false),
|
|
@@ -3310,11 +3618,11 @@ var __defProp = Object.defineProperty;
|
|
|
3310
3618
|
},
|
|
3311
3619
|
"cancel"
|
|
3312
3620
|
),
|
|
3313
|
-
/* @__PURE__ */ (0,
|
|
3621
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(NButton, { variant: "primary", disabled: busy, onClick: start, children: busy ? "启动中…" : "反刍整理" }, "confirm")
|
|
3314
3622
|
],
|
|
3315
3623
|
children: [
|
|
3316
|
-
/* @__PURE__ */ (0,
|
|
3317
|
-
/* @__PURE__ */ (0,
|
|
3624
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { children: "将扫描未蒸馏缓冲,按会话逐个跑蒸馏管线,完成后强制 L2 场景整合与 L3 画像更新。" }),
|
|
3625
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { marginTop: 8 }, children: "与重建不同:不清空 L1 检索库、不归档旧产物、不改 L0;仅消化攒而未蒸馏的切片,无缓冲时做轻量 L2/L3 刷新。" })
|
|
3318
3626
|
]
|
|
3319
3627
|
}
|
|
3320
3628
|
) : null
|
|
@@ -3322,13 +3630,13 @@ var __defProp = Object.defineProperty;
|
|
|
3322
3630
|
}
|
|
3323
3631
|
|
|
3324
3632
|
// client/src/tabs/OverviewTab.tsx
|
|
3325
|
-
var
|
|
3633
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3326
3634
|
function OverviewTab(props) {
|
|
3327
3635
|
const rpc = props.rpc;
|
|
3328
|
-
const [stats, setStats] = (0,
|
|
3329
|
-
const [settingsData, setSettingsData] = (0,
|
|
3330
|
-
const [error, setError] = (0,
|
|
3331
|
-
const load = (0,
|
|
3636
|
+
const [stats, setStats] = (0, import_react16.useState)(null);
|
|
3637
|
+
const [settingsData, setSettingsData] = (0, import_react16.useState)(null);
|
|
3638
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
3639
|
+
const load = (0, import_react16.useCallback)(() => {
|
|
3332
3640
|
rpc("dsh-memory/stats", {}).then((r) => {
|
|
3333
3641
|
if (r && r.ok) setStats(r.value);
|
|
3334
3642
|
else setError(r && r.error ? r.error.message : "RPC error");
|
|
@@ -3340,7 +3648,7 @@ var __defProp = Object.defineProperty;
|
|
|
3340
3648
|
}).catch(() => {
|
|
3341
3649
|
});
|
|
3342
3650
|
}, [rpc]);
|
|
3343
|
-
(0,
|
|
3651
|
+
(0, import_react16.useEffect)(() => {
|
|
3344
3652
|
load();
|
|
3345
3653
|
const timer = setInterval(load, 5e3);
|
|
3346
3654
|
return () => {
|
|
@@ -3402,10 +3710,10 @@ var __defProp = Object.defineProperty;
|
|
|
3402
3710
|
const toolConflict = settingsData && settingsData.settings ? settingsData.settings.toolConflict !== false : true;
|
|
3403
3711
|
const toolMutate = settingsData && settingsData.settings ? settingsData.settings.toolMutate !== false : true;
|
|
3404
3712
|
const skillsEnabled = settingsData && settingsData.settings ? settingsData.settings.skillsEnabled === true : false;
|
|
3405
|
-
return /* @__PURE__ */ (0,
|
|
3406
|
-
settingsData && settingsData.supported === false ? /* @__PURE__ */ (0,
|
|
3407
|
-
/* @__PURE__ */ (0,
|
|
3408
|
-
/* @__PURE__ */ (0,
|
|
3713
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
3714
|
+
settingsData && settingsData.supported === false ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { style: S.hint, children: "settings 服务不可用,记忆模式开关未启用(记忆保持全开)。" }) : settingsData ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: S.switchPanel, children: [
|
|
3715
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "记忆模式" }),
|
|
3716
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3409
3717
|
SwitchRow,
|
|
3410
3718
|
{
|
|
3411
3719
|
label: "记忆模式",
|
|
@@ -3416,7 +3724,7 @@ var __defProp = Object.defineProperty;
|
|
|
3416
3724
|
}
|
|
3417
3725
|
}
|
|
3418
3726
|
),
|
|
3419
|
-
/* @__PURE__ */ (0,
|
|
3727
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3420
3728
|
SwitchRow,
|
|
3421
3729
|
{
|
|
3422
3730
|
label: "捕获",
|
|
@@ -3428,7 +3736,7 @@ var __defProp = Object.defineProperty;
|
|
|
3428
3736
|
}
|
|
3429
3737
|
}
|
|
3430
3738
|
),
|
|
3431
|
-
/* @__PURE__ */ (0,
|
|
3739
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3432
3740
|
SwitchRow,
|
|
3433
3741
|
{
|
|
3434
3742
|
label: "蒸馏",
|
|
@@ -3440,7 +3748,7 @@ var __defProp = Object.defineProperty;
|
|
|
3440
3748
|
}
|
|
3441
3749
|
}
|
|
3442
3750
|
),
|
|
3443
|
-
/* @__PURE__ */ (0,
|
|
3751
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3444
3752
|
SwitchRow,
|
|
3445
3753
|
{
|
|
3446
3754
|
label: "召回",
|
|
@@ -3452,8 +3760,8 @@ var __defProp = Object.defineProperty;
|
|
|
3452
3760
|
}
|
|
3453
3761
|
}
|
|
3454
3762
|
),
|
|
3455
|
-
/* @__PURE__ */ (0,
|
|
3456
|
-
/* @__PURE__ */ (0,
|
|
3763
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "高权限模式" }),
|
|
3764
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3457
3765
|
SwitchRow,
|
|
3458
3766
|
{
|
|
3459
3767
|
label: "高权限模式",
|
|
@@ -3464,8 +3772,8 @@ var __defProp = Object.defineProperty;
|
|
|
3464
3772
|
}
|
|
3465
3773
|
}
|
|
3466
3774
|
),
|
|
3467
|
-
/* @__PURE__ */ (0,
|
|
3468
|
-
/* @__PURE__ */ (0,
|
|
3775
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "技能结晶" }),
|
|
3776
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3469
3777
|
SwitchRow,
|
|
3470
3778
|
{
|
|
3471
3779
|
label: "技能(程序性记忆)",
|
|
@@ -3476,8 +3784,8 @@ var __defProp = Object.defineProperty;
|
|
|
3476
3784
|
}
|
|
3477
3785
|
}
|
|
3478
3786
|
),
|
|
3479
|
-
/* @__PURE__ */ (0,
|
|
3480
|
-
/* @__PURE__ */ (0,
|
|
3787
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "工具封印" }),
|
|
3788
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3481
3789
|
SwitchRow,
|
|
3482
3790
|
{
|
|
3483
3791
|
label: "Room 管理工具",
|
|
@@ -3488,7 +3796,7 @@ var __defProp = Object.defineProperty;
|
|
|
3488
3796
|
}
|
|
3489
3797
|
}
|
|
3490
3798
|
),
|
|
3491
|
-
/* @__PURE__ */ (0,
|
|
3799
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3492
3800
|
SwitchRow,
|
|
3493
3801
|
{
|
|
3494
3802
|
label: "图谱工具",
|
|
@@ -3499,7 +3807,7 @@ var __defProp = Object.defineProperty;
|
|
|
3499
3807
|
}
|
|
3500
3808
|
}
|
|
3501
3809
|
),
|
|
3502
|
-
/* @__PURE__ */ (0,
|
|
3810
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3503
3811
|
SwitchRow,
|
|
3504
3812
|
{
|
|
3505
3813
|
label: "反刍工具",
|
|
@@ -3510,7 +3818,7 @@ var __defProp = Object.defineProperty;
|
|
|
3510
3818
|
}
|
|
3511
3819
|
}
|
|
3512
3820
|
),
|
|
3513
|
-
/* @__PURE__ */ (0,
|
|
3821
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3514
3822
|
SwitchRow,
|
|
3515
3823
|
{
|
|
3516
3824
|
label: "冲突工具",
|
|
@@ -3521,7 +3829,7 @@ var __defProp = Object.defineProperty;
|
|
|
3521
3829
|
}
|
|
3522
3830
|
}
|
|
3523
3831
|
),
|
|
3524
|
-
/* @__PURE__ */ (0,
|
|
3832
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3525
3833
|
SwitchRow,
|
|
3526
3834
|
{
|
|
3527
3835
|
label: "写删工具",
|
|
@@ -3532,8 +3840,8 @@ var __defProp = Object.defineProperty;
|
|
|
3532
3840
|
}
|
|
3533
3841
|
}
|
|
3534
3842
|
),
|
|
3535
|
-
/* @__PURE__ */ (0,
|
|
3536
|
-
/* @__PURE__ */ (0,
|
|
3843
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "人工冲突裁决" }),
|
|
3844
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3537
3845
|
SwitchRow,
|
|
3538
3846
|
{
|
|
3539
3847
|
label: "人工冲突裁决",
|
|
@@ -3544,42 +3852,43 @@ var __defProp = Object.defineProperty;
|
|
|
3544
3852
|
}
|
|
3545
3853
|
}
|
|
3546
3854
|
),
|
|
3547
|
-
/* @__PURE__ */ (0,
|
|
3548
|
-
/* @__PURE__ */ (0,
|
|
3549
|
-
ceilingNote ? /* @__PURE__ */ (0,
|
|
3855
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "蒸馏参数" }),
|
|
3856
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DistillSettings, { rpc, disabled: !master, data: settingsData, setData: setSettingsData, onError: setError }),
|
|
3857
|
+
ceilingNote ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { style: S.hint, children: ceilingNote }) : null
|
|
3550
3858
|
] }) : null,
|
|
3551
|
-
/* @__PURE__ */ (0,
|
|
3552
|
-
/* @__PURE__ */ (0,
|
|
3553
|
-
/* @__PURE__ */ (0,
|
|
3554
|
-
degraded ? /* @__PURE__ */ (0,
|
|
3555
|
-
error ? /* @__PURE__ */ (0,
|
|
3556
|
-
/* @__PURE__ */ (0,
|
|
3557
|
-
/* @__PURE__ */ (0,
|
|
3558
|
-
return /* @__PURE__ */ (0,
|
|
3559
|
-
/* @__PURE__ */ (0,
|
|
3560
|
-
/* @__PURE__ */ (0,
|
|
3859
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(EmbeddingSection, { rpc }),
|
|
3860
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RebuildPanel, { rpc }),
|
|
3861
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RuminatePanel, { rpc }),
|
|
3862
|
+
degraded ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { ...S.error, marginBottom: 10 }, children: "⚠ " + stats.message + "。上方数据为最后一次成功读取的值,记忆功能当前未工作。" }) : null,
|
|
3863
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.error, children: "获取状态失败:" + error }) : !stats ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { style: S.intro, children: "正在读取记忆状态…" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
3864
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "记忆概况" }),
|
|
3865
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.statGrid, children: tiles.map((t) => {
|
|
3866
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "dsh-mem-card", style: S.statTile, children: [
|
|
3867
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.statNum, children: t.num }),
|
|
3868
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.statLabel, children: t.label })
|
|
3561
3869
|
] }, t.label);
|
|
3562
3870
|
}) }),
|
|
3563
|
-
/* @__PURE__ */ (0,
|
|
3871
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "运行状态" }),
|
|
3564
3872
|
infos.map((row2) => {
|
|
3565
|
-
return /* @__PURE__ */ (0,
|
|
3566
|
-
/* @__PURE__ */ (0,
|
|
3567
|
-
/* @__PURE__ */ (0,
|
|
3873
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: S.infoRow, children: [
|
|
3874
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.infoKey, children: row2[0] }),
|
|
3875
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.infoVal, children: row2[1] })
|
|
3568
3876
|
] }, row2[0]);
|
|
3569
3877
|
})
|
|
3570
3878
|
] }),
|
|
3571
|
-
/* @__PURE__ */ (0,
|
|
3879
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ArchiveSection, { rpc }),
|
|
3880
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { style: S.hint, children: "浏览各层记忆内容请切换上方 Tab;原始对话(L0)不入浏览器,可由模型侧 conversation_search 工具查询。" })
|
|
3572
3881
|
] });
|
|
3573
3882
|
}
|
|
3574
3883
|
|
|
3575
3884
|
// client/src/tabs/PersonaTab.tsx
|
|
3576
|
-
var
|
|
3577
|
-
var
|
|
3885
|
+
var import_react17 = require("react");
|
|
3886
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3578
3887
|
function PersonaTab(props) {
|
|
3579
3888
|
const rpc = props.rpc;
|
|
3580
|
-
const [content, setContent] = (0,
|
|
3581
|
-
const [error, setError] = (0,
|
|
3582
|
-
const load = (0,
|
|
3889
|
+
const [content, setContent] = (0, import_react17.useState)(null);
|
|
3890
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
3891
|
+
const load = (0, import_react17.useCallback)(() => {
|
|
3583
3892
|
setError(null);
|
|
3584
3893
|
rpc("dsh-memory/persona", {}).then((r) => {
|
|
3585
3894
|
if (r && r.ok) setContent(r.value.content);
|
|
@@ -3588,64 +3897,55 @@ var __defProp = Object.defineProperty;
|
|
|
3588
3897
|
setError(String(e && e.message || e));
|
|
3589
3898
|
});
|
|
3590
3899
|
}, [rpc]);
|
|
3591
|
-
(0,
|
|
3900
|
+
(0, import_react17.useEffect)(() => {
|
|
3592
3901
|
load();
|
|
3593
3902
|
}, [load]);
|
|
3594
|
-
return /* @__PURE__ */ (0,
|
|
3595
|
-
/* @__PURE__ */ (0,
|
|
3596
|
-
/* @__PURE__ */ (0,
|
|
3597
|
-
/* @__PURE__ */ (0,
|
|
3598
|
-
/* @__PURE__ */ (0,
|
|
3903
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
|
|
3904
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
3905
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: S.muted, children: error ? "加载失败" : content === null ? "加载中…" : content ? content.length + " 字符" : "未生成画像" }),
|
|
3906
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.grow }),
|
|
3907
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
3599
3908
|
] }),
|
|
3600
|
-
error ? /* @__PURE__ */ (0,
|
|
3601
|
-
content ? /* @__PURE__ */ (0,
|
|
3909
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { ...S.error, marginBottom: 10 }, children: "画像读取失败:" + error + "(点右上“刷新”重试)" }) : null,
|
|
3910
|
+
content ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("pre", { style: S.pre, children: content }) : content === null ? null : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: S.intro, children: "画像尚未生成;蒸馏若干记忆后 L3 会自动产出。" })
|
|
3602
3911
|
] });
|
|
3603
3912
|
}
|
|
3604
3913
|
|
|
3605
3914
|
// client/src/tabs/RecordsTab.tsx
|
|
3606
|
-
var
|
|
3607
|
-
var
|
|
3915
|
+
var import_react18 = require("react");
|
|
3916
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3608
3917
|
function retiredSelOf(r) {
|
|
3609
3918
|
if (r === "active") return false;
|
|
3610
3919
|
if (r === "retired") return true;
|
|
3611
3920
|
return void 0;
|
|
3612
3921
|
}
|
|
3613
|
-
var TYPE_CHOICES = [
|
|
3614
|
-
"persona",
|
|
3615
|
-
"episodic",
|
|
3616
|
-
"instruction",
|
|
3617
|
-
"work_fact",
|
|
3618
|
-
"work_task",
|
|
3619
|
-
"work_method",
|
|
3620
|
-
"work_artifact"
|
|
3621
|
-
];
|
|
3622
3922
|
var DELETE_LIMIT = 200;
|
|
3623
3923
|
function RecordsTab(props) {
|
|
3624
3924
|
const rpc = props.rpc;
|
|
3625
3925
|
const limit = 50;
|
|
3626
|
-
const [items, setItems] = (0,
|
|
3627
|
-
const [hasMore, setHasMore] = (0,
|
|
3628
|
-
const [total, setTotal] = (0,
|
|
3629
|
-
const [sceneOptions, setSceneOptions] = (0,
|
|
3630
|
-
const [loading, setLoading] = (0,
|
|
3631
|
-
const [truncated, setTruncated] = (0,
|
|
3632
|
-
const [error, setError] = (0,
|
|
3633
|
-
const [expandedId, setExpandedId] = (0,
|
|
3634
|
-
const [sel, setSel] = (0,
|
|
3635
|
-
const [hiPriv, setHiPriv] = (0,
|
|
3636
|
-
const [hiPrivBusy, setHiPrivBusy] = (0,
|
|
3637
|
-
const [query, setQuery] = (0,
|
|
3638
|
-
const [typeFilter, setTypeFilter] = (0,
|
|
3639
|
-
const [sceneFilter, setSceneFilter] = (0,
|
|
3640
|
-
const [hallFilter, setHallFilter] = (0,
|
|
3641
|
-
const [tagFilter, setTagFilter] = (0,
|
|
3642
|
-
const [untaggedOnly, setUntaggedOnly] = (0,
|
|
3643
|
-
const [orphanCount, setOrphanCount] = (0,
|
|
3644
|
-
const [retiredFilter, setRetiredFilter] = (0,
|
|
3645
|
-
const [wingCatalog, setHallCatalog] = (0,
|
|
3646
|
-
const [last, setLast] = (0,
|
|
3647
|
-
const seqRef = (0,
|
|
3648
|
-
const fetchPage = (0,
|
|
3926
|
+
const [items, setItems] = (0, import_react18.useState)([]);
|
|
3927
|
+
const [hasMore, setHasMore] = (0, import_react18.useState)(false);
|
|
3928
|
+
const [total, setTotal] = (0, import_react18.useState)(null);
|
|
3929
|
+
const [sceneOptions, setSceneOptions] = (0, import_react18.useState)([]);
|
|
3930
|
+
const [loading, setLoading] = (0, import_react18.useState)(false);
|
|
3931
|
+
const [truncated, setTruncated] = (0, import_react18.useState)(false);
|
|
3932
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
3933
|
+
const [expandedId, setExpandedId] = (0, import_react18.useState)(null);
|
|
3934
|
+
const [sel, setSel] = (0, import_react18.useState)(/* @__PURE__ */ new Set());
|
|
3935
|
+
const [hiPriv, setHiPriv] = (0, import_react18.useState)(false);
|
|
3936
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react18.useState)(false);
|
|
3937
|
+
const [query, setQuery] = (0, import_react18.useState)("");
|
|
3938
|
+
const [typeFilter, setTypeFilter] = (0, import_react18.useState)("");
|
|
3939
|
+
const [sceneFilter, setSceneFilter] = (0, import_react18.useState)("");
|
|
3940
|
+
const [hallFilter, setHallFilter] = (0, import_react18.useState)([]);
|
|
3941
|
+
const [tagFilter, setTagFilter] = (0, import_react18.useState)("");
|
|
3942
|
+
const [untaggedOnly, setUntaggedOnly] = (0, import_react18.useState)(false);
|
|
3943
|
+
const [orphanCount, setOrphanCount] = (0, import_react18.useState)(0);
|
|
3944
|
+
const [retiredFilter, setRetiredFilter] = (0, import_react18.useState)("");
|
|
3945
|
+
const [wingCatalog, setHallCatalog] = (0, import_react18.useState)(null);
|
|
3946
|
+
const [last, setLast] = (0, import_react18.useState)({ query: "", type: "", scene: "", halls: [], tag: "", untagged: false, retired: "" });
|
|
3947
|
+
const seqRef = (0, import_react18.useRef)(0);
|
|
3948
|
+
const fetchPage = (0, import_react18.useCallback)(
|
|
3649
3949
|
(conds, offset, append) => {
|
|
3650
3950
|
setLoading(true);
|
|
3651
3951
|
setError(null);
|
|
@@ -3675,6 +3975,7 @@ var __defProp = Object.defineProperty;
|
|
|
3675
3975
|
setTruncated(!!v.truncated);
|
|
3676
3976
|
if (v.scenes) setSceneOptions(v.scenes);
|
|
3677
3977
|
if (v.wingCatalog) setHallCatalog(v.wingCatalog);
|
|
3978
|
+
if (v.typeCatalog) registerTypeCatalog(v.typeCatalog);
|
|
3678
3979
|
}).catch((e) => {
|
|
3679
3980
|
if (token !== seqRef.current) return;
|
|
3680
3981
|
setLoading(false);
|
|
@@ -3694,23 +3995,23 @@ var __defProp = Object.defineProperty;
|
|
|
3694
3995
|
setLast(conds);
|
|
3695
3996
|
fetchPage(conds, 0, false);
|
|
3696
3997
|
};
|
|
3697
|
-
const loadRooms = (0,
|
|
3998
|
+
const loadRooms = (0, import_react18.useCallback)(() => {
|
|
3698
3999
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
3699
4000
|
if (r && r.ok) setOrphanCount(r.value.orphanCount ?? 0);
|
|
3700
4001
|
}).catch(() => {
|
|
3701
4002
|
});
|
|
3702
4003
|
}, [rpc]);
|
|
3703
|
-
(0,
|
|
4004
|
+
(0, import_react18.useEffect)(() => {
|
|
3704
4005
|
fetchPage({ query: "", type: "", scene: "", halls: [], tag: "", untagged: false, retired: "" }, 0, false);
|
|
3705
4006
|
loadRooms();
|
|
3706
4007
|
}, [fetchPage, loadRooms]);
|
|
3707
|
-
const loadHiPriv = (0,
|
|
4008
|
+
const loadHiPriv = (0, import_react18.useCallback)(() => {
|
|
3708
4009
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
3709
4010
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
3710
4011
|
}).catch(() => {
|
|
3711
4012
|
});
|
|
3712
4013
|
}, [rpc]);
|
|
3713
|
-
(0,
|
|
4014
|
+
(0, import_react18.useEffect)(() => {
|
|
3714
4015
|
loadHiPriv();
|
|
3715
4016
|
}, [loadHiPriv]);
|
|
3716
4017
|
const toggleHiPriv = () => {
|
|
@@ -3751,7 +4052,9 @@ var __defProp = Object.defineProperty;
|
|
|
3751
4052
|
if (r && r.ok) {
|
|
3752
4053
|
setSel(/* @__PURE__ */ new Set());
|
|
3753
4054
|
if (expandedId && ids.indexOf(expandedId) >= 0) setExpandedId(null);
|
|
3754
|
-
|
|
4055
|
+
const removed = r.value?.deleted ?? ids.length;
|
|
4056
|
+
setItems((prev) => prev.filter((m) => !ids.includes(m.id)));
|
|
4057
|
+
setTotal((t) => t === null ? null : Math.max(0, t - removed));
|
|
3755
4058
|
if (showRetired) loadRetired();
|
|
3756
4059
|
} else if (r) setError(r.error ? r.error.message : "退场失败");
|
|
3757
4060
|
}).catch((e) => setError(String(e && e.message || e)));
|
|
@@ -3766,16 +4069,17 @@ var __defProp = Object.defineProperty;
|
|
|
3766
4069
|
return next;
|
|
3767
4070
|
});
|
|
3768
4071
|
if (expandedId === id) setExpandedId(null);
|
|
3769
|
-
|
|
4072
|
+
setItems((prev) => prev.filter((m) => m.id !== id));
|
|
4073
|
+
setTotal((t) => t === null ? null : Math.max(0, t - 1));
|
|
3770
4074
|
if (showRetired) loadRetired();
|
|
3771
4075
|
} else if (r) setError(r.error ? r.error.message : "退场失败");
|
|
3772
4076
|
}).catch((e) => setError(String(e && e.message || e)));
|
|
3773
4077
|
};
|
|
3774
|
-
const [retired, setRetired] = (0,
|
|
3775
|
-
const [retiredTotal, setRetiredTotal] = (0,
|
|
3776
|
-
const [showRetired, setShowRetired] = (0,
|
|
3777
|
-
const [retiredBusy, setRetiredBusy] = (0,
|
|
3778
|
-
const loadRetired = (0,
|
|
4078
|
+
const [retired, setRetired] = (0, import_react18.useState)([]);
|
|
4079
|
+
const [retiredTotal, setRetiredTotal] = (0, import_react18.useState)(0);
|
|
4080
|
+
const [showRetired, setShowRetired] = (0, import_react18.useState)(false);
|
|
4081
|
+
const [retiredBusy, setRetiredBusy] = (0, import_react18.useState)(false);
|
|
4082
|
+
const loadRetired = (0, import_react18.useCallback)(() => {
|
|
3779
4083
|
setRetiredBusy(true);
|
|
3780
4084
|
rpc("dsh-memory/records-retired", { limit: 100, offset: 0 }).then((r) => {
|
|
3781
4085
|
if (r && r.ok) {
|
|
@@ -3784,7 +4088,7 @@ var __defProp = Object.defineProperty;
|
|
|
3784
4088
|
} else if (r) setError(r.error ? r.error.message : "已退场列表加载失败");
|
|
3785
4089
|
}).catch((e) => setError(String(e && e.message || e))).finally(() => setRetiredBusy(false));
|
|
3786
4090
|
}, [rpc]);
|
|
3787
|
-
(0,
|
|
4091
|
+
(0, import_react18.useEffect)(() => {
|
|
3788
4092
|
if (showRetired) loadRetired();
|
|
3789
4093
|
}, [showRetired, loadRetired]);
|
|
3790
4094
|
const restoreRecords = (ids) => {
|
|
@@ -3793,7 +4097,10 @@ var __defProp = Object.defineProperty;
|
|
|
3793
4097
|
rpc("dsh-memory/records-restore", { ids }).then((r) => {
|
|
3794
4098
|
if (r && r.ok) {
|
|
3795
4099
|
loadRetired();
|
|
3796
|
-
|
|
4100
|
+
const restored = new Set(ids);
|
|
4101
|
+
setItems(
|
|
4102
|
+
(prev) => prev.map((m) => restored.has(m.id) ? { ...m, retired: false, retiredReason: void 0 } : m)
|
|
4103
|
+
);
|
|
3797
4104
|
} else if (r) setError(r.error ? r.error.message : "恢复失败");
|
|
3798
4105
|
}).catch((e) => setError(String(e && e.message || e))).finally(() => setRetiredBusy(false));
|
|
3799
4106
|
};
|
|
@@ -3801,14 +4108,15 @@ var __defProp = Object.defineProperty;
|
|
|
3801
4108
|
conflict: "裁决退场",
|
|
3802
4109
|
superseded: "被取代",
|
|
3803
4110
|
manual: "人工退场",
|
|
4111
|
+
obsolete: "声明过时",
|
|
3804
4112
|
unknown: "已退场"
|
|
3805
4113
|
};
|
|
3806
4114
|
const countText = total !== null ? "共 " + total + " 条" : items.length + " 条" + (hasMore ? "+" : "");
|
|
3807
|
-
const [usageSummary, setUsageSummary] = (0,
|
|
4115
|
+
const [usageSummary, setUsageSummary] = (0, import_react18.useState)(null);
|
|
3808
4116
|
const selCount = sel.size;
|
|
3809
|
-
return /* @__PURE__ */ (0,
|
|
3810
|
-
/* @__PURE__ */ (0,
|
|
3811
|
-
/* @__PURE__ */ (0,
|
|
4117
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
|
|
4118
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: S.toolbar, children: [
|
|
4119
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3812
4120
|
NInput,
|
|
3813
4121
|
{
|
|
3814
4122
|
style: { flex: 1, minWidth: 160 },
|
|
@@ -3819,23 +4127,32 @@ var __defProp = Object.defineProperty;
|
|
|
3819
4127
|
},
|
|
3820
4128
|
onKeyDown: (e) => {
|
|
3821
4129
|
if (e.key === "Enter") search();
|
|
4130
|
+
else if (e.key === "Escape" || e.key === "Backspace" && (e.ctrlKey || e.metaKey)) {
|
|
4131
|
+
if (query.length > 0) {
|
|
4132
|
+
e.preventDefault();
|
|
4133
|
+
setQuery("");
|
|
4134
|
+
const conds = { query: "", type: typeFilter, scene: sceneFilter, halls: hallFilter, tag: tagFilter, untagged: untaggedOnly, retired: retiredFilter };
|
|
4135
|
+
setLast(conds);
|
|
4136
|
+
fetchPage(conds, 0, false);
|
|
4137
|
+
}
|
|
4138
|
+
}
|
|
3822
4139
|
}
|
|
3823
4140
|
}
|
|
3824
4141
|
),
|
|
3825
|
-
/* @__PURE__ */ (0,
|
|
4142
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3826
4143
|
NSel,
|
|
3827
4144
|
{
|
|
3828
4145
|
style: { maxWidth: 200 },
|
|
3829
4146
|
options: [{ id: "", label: "全部类型" }].concat(
|
|
3830
|
-
|
|
3831
|
-
return { id: t, label:
|
|
4147
|
+
(typeCatalogIds().length > 0 ? typeCatalogIds() : [...new Set(items.map((m) => m.type))]).map((t) => {
|
|
4148
|
+
return { id: t, label: typeLabel(t) };
|
|
3832
4149
|
})
|
|
3833
4150
|
),
|
|
3834
4151
|
value: typeFilter,
|
|
3835
4152
|
onChange: setTypeFilter
|
|
3836
4153
|
}
|
|
3837
4154
|
),
|
|
3838
|
-
/* @__PURE__ */ (0,
|
|
4155
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3839
4156
|
NSel,
|
|
3840
4157
|
{
|
|
3841
4158
|
style: { maxWidth: 220 },
|
|
@@ -3848,7 +4165,7 @@ var __defProp = Object.defineProperty;
|
|
|
3848
4165
|
onChange: setSceneFilter
|
|
3849
4166
|
}
|
|
3850
4167
|
),
|
|
3851
|
-
/* @__PURE__ */ (0,
|
|
4168
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3852
4169
|
WingMultiSelect,
|
|
3853
4170
|
{
|
|
3854
4171
|
options: wingCatalog ?? Array.from(new Set(items.map((m) => m.hall).filter((h) => !!h))).map((id) => ({ id, label: id })),
|
|
@@ -3856,8 +4173,8 @@ var __defProp = Object.defineProperty;
|
|
|
3856
4173
|
onChange: setHallFilter
|
|
3857
4174
|
}
|
|
3858
4175
|
),
|
|
3859
|
-
/* @__PURE__ */ (0,
|
|
3860
|
-
/* @__PURE__ */ (0,
|
|
4176
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(NButton, { onClick: search, children: "搜索" }),
|
|
4177
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3861
4178
|
NButton,
|
|
3862
4179
|
{
|
|
3863
4180
|
style: {
|
|
@@ -3871,8 +4188,8 @@ var __defProp = Object.defineProperty;
|
|
|
3871
4188
|
}
|
|
3872
4189
|
)
|
|
3873
4190
|
] }),
|
|
3874
|
-
/* @__PURE__ */ (0,
|
|
3875
|
-
/* @__PURE__ */ (0,
|
|
4191
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { marginBottom: 10, display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: [
|
|
4192
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3876
4193
|
"button",
|
|
3877
4194
|
{
|
|
3878
4195
|
type: "button",
|
|
@@ -3897,10 +4214,10 @@ var __defProp = Object.defineProperty;
|
|
|
3897
4214
|
children: "无绑定 · " + orphanCount
|
|
3898
4215
|
}
|
|
3899
4216
|
),
|
|
3900
|
-
(tagFilter || untaggedOnly) && /* @__PURE__ */ (0,
|
|
4217
|
+
(tagFilter || untaggedOnly) && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { style: S.muted, children: [
|
|
3901
4218
|
"筛选中:",
|
|
3902
4219
|
untaggedOnly ? "无绑定" : tagFilter,
|
|
3903
|
-
/* @__PURE__ */ (0,
|
|
4220
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3904
4221
|
"button",
|
|
3905
4222
|
{
|
|
3906
4223
|
type: "button",
|
|
@@ -3917,7 +4234,7 @@ var __defProp = Object.defineProperty;
|
|
|
3917
4234
|
}
|
|
3918
4235
|
)
|
|
3919
4236
|
] }),
|
|
3920
|
-
/* @__PURE__ */ (0,
|
|
4237
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3921
4238
|
"button",
|
|
3922
4239
|
{
|
|
3923
4240
|
type: "button",
|
|
@@ -3946,15 +4263,15 @@ var __defProp = Object.defineProperty;
|
|
|
3946
4263
|
children: "导出孤儿"
|
|
3947
4264
|
}
|
|
3948
4265
|
),
|
|
3949
|
-
/* @__PURE__ */ (0,
|
|
4266
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "Room 标签/分类管理:见「Hall」「Room」标签页。" })
|
|
3950
4267
|
] }),
|
|
3951
|
-
/* @__PURE__ */ (0,
|
|
3952
|
-
/* @__PURE__ */ (0,
|
|
3953
|
-
usageSummary ? /* @__PURE__ */ (0,
|
|
3954
|
-
/* @__PURE__ */ (0,
|
|
4268
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
4269
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: loading ? "加载中…" : countText }),
|
|
4270
|
+
usageSummary ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, title: "老化权重效果口径:参与召回尝试的记忆中,进 topN(被注入上下文)的比例", children: "召回使用 " + usageSummary.used + "/" + usageSummary.attempted + "(" + usageSummary.rate + "%)" }) : null,
|
|
4271
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "退场筛查" }),
|
|
3955
4272
|
[["", "全部"], ["active", "仅活跃"], ["retired", "仅退场"]].map(([val, label]) => {
|
|
3956
4273
|
const on = retiredFilter === val;
|
|
3957
|
-
return /* @__PURE__ */ (0,
|
|
4274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3958
4275
|
"button",
|
|
3959
4276
|
{
|
|
3960
4277
|
type: "button",
|
|
@@ -3974,7 +4291,7 @@ var __defProp = Object.defineProperty;
|
|
|
3974
4291
|
val
|
|
3975
4292
|
);
|
|
3976
4293
|
}),
|
|
3977
|
-
/* @__PURE__ */ (0,
|
|
4294
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3978
4295
|
NButton,
|
|
3979
4296
|
{
|
|
3980
4297
|
style: selCount > 0 ? { color: "var(--dsh-mem-danger)" } : void 0,
|
|
@@ -3984,7 +4301,7 @@ var __defProp = Object.defineProperty;
|
|
|
3984
4301
|
children: "删除选中" + (selCount > 0 ? "(" + selCount + ")" : "")
|
|
3985
4302
|
}
|
|
3986
4303
|
),
|
|
3987
|
-
selCount > 0 ? /* @__PURE__ */ (0,
|
|
4304
|
+
selCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3988
4305
|
NButton,
|
|
3989
4306
|
{
|
|
3990
4307
|
onClick: () => {
|
|
@@ -3993,8 +4310,8 @@ var __defProp = Object.defineProperty;
|
|
|
3993
4310
|
children: "清空选择"
|
|
3994
4311
|
}
|
|
3995
4312
|
) : null,
|
|
3996
|
-
/* @__PURE__ */ (0,
|
|
3997
|
-
/* @__PURE__ */ (0,
|
|
4313
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
|
|
4314
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3998
4315
|
NButton,
|
|
3999
4316
|
{
|
|
4000
4317
|
onClick: () => {
|
|
@@ -4005,13 +4322,13 @@ var __defProp = Object.defineProperty;
|
|
|
4005
4322
|
}
|
|
4006
4323
|
)
|
|
4007
4324
|
] }),
|
|
4008
|
-
!hiPriv ? /* @__PURE__ */ (0,
|
|
4009
|
-
error ? /* @__PURE__ */ (0,
|
|
4010
|
-
truncated ? /* @__PURE__ */ (0,
|
|
4011
|
-
items.length === 0 && !loading && !error ? /* @__PURE__ */ (0,
|
|
4325
|
+
!hiPriv ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.hint, children: "提示:删除记忆需先开启高权限模式(右上开关或概览页「高权限模式」),关闭时删除按钮不可用。" }) : null,
|
|
4326
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.error, children: error }) : null,
|
|
4327
|
+
truncated ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.hint, children: "搜索分页已达检索上限(200 条),更早的结果未显示。请用更精确的关键词或类型/情境过滤。" }) : null,
|
|
4328
|
+
items.length === 0 && !loading && !error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: S.intro, children: "暂无记忆。对话几轮后,蒸馏管线会自动抽取记忆。" }) : items.map((m) => {
|
|
4012
4329
|
const open = expandedId === m.id;
|
|
4013
4330
|
const checked = sel.has(m.id);
|
|
4014
|
-
return /* @__PURE__ */ (0,
|
|
4331
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4015
4332
|
"div",
|
|
4016
4333
|
{
|
|
4017
4334
|
className: "dsh-mem-card dsh-mem-card-hover",
|
|
@@ -4020,8 +4337,8 @@ var __defProp = Object.defineProperty;
|
|
|
4020
4337
|
setExpandedId(open ? null : m.id);
|
|
4021
4338
|
},
|
|
4022
4339
|
children: [
|
|
4023
|
-
/* @__PURE__ */ (0,
|
|
4024
|
-
/* @__PURE__ */ (0,
|
|
4340
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: S.cardHead, children: [
|
|
4341
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4025
4342
|
"input",
|
|
4026
4343
|
{
|
|
4027
4344
|
type: "checkbox",
|
|
@@ -4036,9 +4353,9 @@ var __defProp = Object.defineProperty;
|
|
|
4036
4353
|
}
|
|
4037
4354
|
}
|
|
4038
4355
|
),
|
|
4039
|
-
/* @__PURE__ */ (0,
|
|
4040
|
-
m.hall ? /* @__PURE__ */ (0,
|
|
4041
|
-
m.retired ? /* @__PURE__ */ (0,
|
|
4356
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: tagClass(m.type), children: typeLabel(m.type) }),
|
|
4357
|
+
m.hall ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-tag dsh-mem-tag-work-fact", children: "Wing · " + (wingCatalog?.find((h) => h.id === m.hall)?.label || m.hall) }) : null,
|
|
4358
|
+
m.retired ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4042
4359
|
"span",
|
|
4043
4360
|
{
|
|
4044
4361
|
title: "该记忆已退场(软删):移出检索面但仍可恢复,并未真正删除",
|
|
@@ -4053,8 +4370,8 @@ var __defProp = Object.defineProperty;
|
|
|
4053
4370
|
children: "已退场" + (m.retiredReason ? " · " + (RETIRE_REASON_LABEL[m.retiredReason] || m.retiredReason) : "")
|
|
4054
4371
|
}
|
|
4055
4372
|
) : null,
|
|
4056
|
-
/* @__PURE__ */ (0,
|
|
4057
|
-
m.maturity ? /* @__PURE__ */ (0,
|
|
4373
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "优先级 " + m.priority }),
|
|
4374
|
+
m.maturity ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4058
4375
|
"span",
|
|
4059
4376
|
{
|
|
4060
4377
|
title: "成熟度(优先级 + 被用次数 + 新鲜度合成):" + m.maturity,
|
|
@@ -4069,7 +4386,7 @@ var __defProp = Object.defineProperty;
|
|
|
4069
4386
|
children: m.maturity === "high" ? "成熟·高" : m.maturity === "mid" ? "成熟·中" : "成熟·低"
|
|
4070
4387
|
}
|
|
4071
4388
|
) : null,
|
|
4072
|
-
m.agingWeight != null ? /* @__PURE__ */ (0,
|
|
4389
|
+
m.agingWeight != null ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4073
4390
|
"span",
|
|
4074
4391
|
{
|
|
4075
4392
|
style: {
|
|
@@ -4084,7 +4401,7 @@ var __defProp = Object.defineProperty;
|
|
|
4084
4401
|
children: "老化 " + Math.round(m.agingWeight * 100) + "%"
|
|
4085
4402
|
}
|
|
4086
4403
|
) : null,
|
|
4087
|
-
m.usage ? /* @__PURE__ */ (0,
|
|
4404
|
+
m.usage ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4088
4405
|
"span",
|
|
4089
4406
|
{
|
|
4090
4407
|
style: S.muted,
|
|
@@ -4092,10 +4409,10 @@ var __defProp = Object.defineProperty;
|
|
|
4092
4409
|
children: "用 " + m.usage.used + "/" + m.usage.attempts
|
|
4093
4410
|
}
|
|
4094
4411
|
) : null,
|
|
4095
|
-
m.score !== null && m.score !== void 0 ? /* @__PURE__ */ (0,
|
|
4096
|
-
/* @__PURE__ */ (0,
|
|
4097
|
-
/* @__PURE__ */ (0,
|
|
4098
|
-
m.retired ? /* @__PURE__ */ (0,
|
|
4412
|
+
m.score !== null && m.score !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "相关度 " + Number(m.score).toFixed(2) }) : null,
|
|
4413
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
|
|
4414
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: fmtTime(m.updatedAt) }),
|
|
4415
|
+
m.retired ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4099
4416
|
NButton,
|
|
4100
4417
|
{
|
|
4101
4418
|
style: { padding: "0 7px", minWidth: 26, height: 26, fontSize: 12, color: "var(--dsh-mem-accent)" },
|
|
@@ -4106,7 +4423,7 @@ var __defProp = Object.defineProperty;
|
|
|
4106
4423
|
},
|
|
4107
4424
|
children: "恢复"
|
|
4108
4425
|
}
|
|
4109
|
-
) : hiPriv ? /* @__PURE__ */ (0,
|
|
4426
|
+
) : hiPriv ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4110
4427
|
NButton,
|
|
4111
4428
|
{
|
|
4112
4429
|
style: { padding: "0 7px", minWidth: 26, height: 26, fontSize: 12, color: "var(--dsh-mem-danger)" },
|
|
@@ -4119,34 +4436,34 @@ var __defProp = Object.defineProperty;
|
|
|
4119
4436
|
}
|
|
4120
4437
|
) : null
|
|
4121
4438
|
] }),
|
|
4122
|
-
/* @__PURE__ */ (0,
|
|
4123
|
-
open ? /* @__PURE__ */ (0,
|
|
4439
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.content, children: m.content }),
|
|
4440
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime18.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.sourceAnchors && m.sourceAnchors.length > 0 ? "来源锚点: " + m.sourceAnchors.join(", ") : "来源锚点: -") }) : null
|
|
4124
4441
|
]
|
|
4125
4442
|
},
|
|
4126
4443
|
m.id
|
|
4127
4444
|
);
|
|
4128
4445
|
}),
|
|
4129
|
-
/* @__PURE__ */ (0,
|
|
4130
|
-
/* @__PURE__ */ (0,
|
|
4131
|
-
showRetired && retiredBusy ? /* @__PURE__ */ (0,
|
|
4132
|
-
showRetired && !retiredBusy && retiredTotal > 0 ? /* @__PURE__ */ (0,
|
|
4446
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { ...S.flexRow, marginTop: 12 }, children: [
|
|
4447
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(NButton, { onClick: () => setShowRetired((v) => !v), children: (showRetired ? "收起" : "展开") + "「已退场」(可恢复)" }),
|
|
4448
|
+
showRetired && retiredBusy ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "加载中…" }) : null,
|
|
4449
|
+
showRetired && !retiredBusy && retiredTotal > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "共 " + retiredTotal + " 条可恢复" }) : null
|
|
4133
4450
|
] }),
|
|
4134
|
-
showRetired ? /* @__PURE__ */ (0,
|
|
4135
|
-
retired.map((m) => /* @__PURE__ */ (0,
|
|
4136
|
-
/* @__PURE__ */ (0,
|
|
4137
|
-
/* @__PURE__ */ (0,
|
|
4138
|
-
m.verdict ? /* @__PURE__ */ (0,
|
|
4139
|
-
/* @__PURE__ */ (0,
|
|
4140
|
-
/* @__PURE__ */ (0,
|
|
4141
|
-
/* @__PURE__ */ (0,
|
|
4451
|
+
showRetired ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { marginTop: 8 }, children: retired.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: S.hint, children: retiredBusy ? " " : "没有已退场的记忆。" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
|
|
4452
|
+
retired.map((m) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "dsh-mem-card", style: S.card, children: [
|
|
4453
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: S.cardHead, children: [
|
|
4454
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: RETIRE_REASON_LABEL[m.retiredReason] || m.retiredReason }),
|
|
4455
|
+
m.verdict ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "结论 " + m.verdict }) : null,
|
|
4456
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
|
|
4457
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: fmtTime(m.retiredAt) }),
|
|
4458
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(NButton, { disabled: retiredBusy, title: "恢复到检索面", onClick: () => restoreRecords([m.id]), children: "恢复" })
|
|
4142
4459
|
] }),
|
|
4143
|
-
/* @__PURE__ */ (0,
|
|
4460
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.content, children: m.content })
|
|
4144
4461
|
] }, m.id)),
|
|
4145
|
-
retiredTotal > retired.length ? /* @__PURE__ */ (0,
|
|
4462
|
+
retiredTotal > retired.length ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: S.hint, children: "共 " + retiredTotal + " 条,此处显示 " + retired.length + " 条" }) : null
|
|
4146
4463
|
] }) }) : null,
|
|
4147
|
-
hasMore ? /* @__PURE__ */ (0,
|
|
4148
|
-
/* @__PURE__ */ (0,
|
|
4149
|
-
/* @__PURE__ */ (0,
|
|
4464
|
+
hasMore ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: S.flexRow, children: [
|
|
4465
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
|
|
4466
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4150
4467
|
NButton,
|
|
4151
4468
|
{
|
|
4152
4469
|
disabled: loading,
|
|
@@ -4160,9 +4477,9 @@ var __defProp = Object.defineProperty;
|
|
|
4160
4477
|
] });
|
|
4161
4478
|
}
|
|
4162
4479
|
function WingMultiSelect(props) {
|
|
4163
|
-
const [open, setOpen] = (0,
|
|
4164
|
-
const wrapRef = (0,
|
|
4165
|
-
(0,
|
|
4480
|
+
const [open, setOpen] = (0, import_react18.useState)(false);
|
|
4481
|
+
const wrapRef = (0, import_react18.useRef)(null);
|
|
4482
|
+
(0, import_react18.useEffect)(() => {
|
|
4166
4483
|
if (!open) return;
|
|
4167
4484
|
const onDown = (e) => {
|
|
4168
4485
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -4182,8 +4499,8 @@ var __defProp = Object.defineProperty;
|
|
|
4182
4499
|
const toggle = (id) => {
|
|
4183
4500
|
props.onChange(props.selected.includes(id) ? props.selected.filter((x) => x !== id) : [...props.selected, id]);
|
|
4184
4501
|
};
|
|
4185
|
-
return /* @__PURE__ */ (0,
|
|
4186
|
-
/* @__PURE__ */ (0,
|
|
4502
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { ref: wrapRef, style: { position: "relative", maxWidth: 150 }, children: [
|
|
4503
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4187
4504
|
"button",
|
|
4188
4505
|
{
|
|
4189
4506
|
type: "button",
|
|
@@ -4192,31 +4509,31 @@ var __defProp = Object.defineProperty;
|
|
|
4192
4509
|
"aria-expanded": open,
|
|
4193
4510
|
onClick: () => setOpen(!open),
|
|
4194
4511
|
children: [
|
|
4195
|
-
/* @__PURE__ */ (0,
|
|
4196
|
-
/* @__PURE__ */ (0,
|
|
4512
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-select-label", title: summary, children: summary }),
|
|
4513
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-sel-chev" + (open ? " dsh-mem-sel-chev-open" : "") })
|
|
4197
4514
|
]
|
|
4198
4515
|
}
|
|
4199
4516
|
),
|
|
4200
|
-
open ? /* @__PURE__ */ (0,
|
|
4201
|
-
props.options.length === 0 ? /* @__PURE__ */ (0,
|
|
4517
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "dsh-mem-pop", role: "listbox", style: { left: 0, right: "auto", minWidth: 150 }, children: [
|
|
4518
|
+
props.options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "dsh-mem-pop-empty", children: "暂无可筛 Hall" }) : null,
|
|
4202
4519
|
props.options.map((o) => {
|
|
4203
4520
|
const active = props.selected.includes(o.id);
|
|
4204
|
-
return /* @__PURE__ */ (0,
|
|
4205
|
-
/* @__PURE__ */ (0,
|
|
4206
|
-
/* @__PURE__ */ (0,
|
|
4521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("button", { type: "button", className: "dsh-mem-pop-opt", onClick: () => toggle(o.id), "aria-selected": active, children: [
|
|
4522
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-pop-check", children: active ? "✓" : "" }),
|
|
4523
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-pop-label", children: o.label })
|
|
4207
4524
|
] }, o.id);
|
|
4208
4525
|
}),
|
|
4209
|
-
props.selected.length > 0 ? /* @__PURE__ */ (0,
|
|
4210
|
-
/* @__PURE__ */ (0,
|
|
4211
|
-
/* @__PURE__ */ (0,
|
|
4526
|
+
props.selected.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("button", { type: "button", className: "dsh-mem-pop-opt", onClick: () => props.onChange([]), children: [
|
|
4527
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-pop-check" }),
|
|
4528
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-pop-label", children: "清除筛选" })
|
|
4212
4529
|
] }) : null
|
|
4213
4530
|
] }) : null
|
|
4214
4531
|
] });
|
|
4215
4532
|
}
|
|
4216
4533
|
|
|
4217
4534
|
// client/src/tabs/RoomsTab.tsx
|
|
4218
|
-
var
|
|
4219
|
-
var
|
|
4535
|
+
var import_react19 = require("react");
|
|
4536
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4220
4537
|
function majorOf(slug) {
|
|
4221
4538
|
const i = slug.indexOf("/");
|
|
4222
4539
|
return i === -1 ? slug : slug.slice(0, i);
|
|
@@ -4245,26 +4562,26 @@ var __defProp = Object.defineProperty;
|
|
|
4245
4562
|
};
|
|
4246
4563
|
function RoomsTab(props) {
|
|
4247
4564
|
const rpc = props.rpc;
|
|
4248
|
-
const [registry, setRegistry] = (0,
|
|
4249
|
-
const [rooms, setRooms] = (0,
|
|
4250
|
-
const [orphanCount, setOrphanCount] = (0,
|
|
4251
|
-
const [busy, setBusy] = (0,
|
|
4252
|
-
const [msg, setMsg] = (0,
|
|
4253
|
-
const [error, setError] = (0,
|
|
4254
|
-
const [hiPriv, setHiPriv] = (0,
|
|
4255
|
-
const [hiPrivBusy, setHiPrivBusy] = (0,
|
|
4256
|
-
const [regSlug, setRegSlug] = (0,
|
|
4257
|
-
const [regLabel, setRegLabel] = (0,
|
|
4258
|
-
const [regDesc, setRegDesc] = (0,
|
|
4259
|
-
const [form, setForm] = (0,
|
|
4260
|
-
const [preview, setPreview] = (0,
|
|
4261
|
-
const [grownOpen, setGrownOpen] = (0,
|
|
4262
|
-
const [dragOverHall, setDragOverHall] = (0,
|
|
4263
|
-
const [picking, setPicking] = (0,
|
|
4264
|
-
const [editing, setEditing] = (0,
|
|
4265
|
-
const [expandedRooms, setExpandedRooms] = (0,
|
|
4266
|
-
const [roomRecords, setRoomRecords] = (0,
|
|
4267
|
-
const [expandedHalls, setExpandedHalls] = (0,
|
|
4565
|
+
const [registry, setRegistry] = (0, import_react19.useState)([]);
|
|
4566
|
+
const [rooms, setRooms] = (0, import_react19.useState)([]);
|
|
4567
|
+
const [orphanCount, setOrphanCount] = (0, import_react19.useState)(0);
|
|
4568
|
+
const [busy, setBusy] = (0, import_react19.useState)(false);
|
|
4569
|
+
const [msg, setMsg] = (0, import_react19.useState)(null);
|
|
4570
|
+
const [error, setError] = (0, import_react19.useState)(null);
|
|
4571
|
+
const [hiPriv, setHiPriv] = (0, import_react19.useState)(false);
|
|
4572
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react19.useState)(false);
|
|
4573
|
+
const [regSlug, setRegSlug] = (0, import_react19.useState)("");
|
|
4574
|
+
const [regLabel, setRegLabel] = (0, import_react19.useState)("");
|
|
4575
|
+
const [regDesc, setRegDesc] = (0, import_react19.useState)("");
|
|
4576
|
+
const [form, setForm] = (0, import_react19.useState)(null);
|
|
4577
|
+
const [preview, setPreview] = (0, import_react19.useState)(null);
|
|
4578
|
+
const [grownOpen, setGrownOpen] = (0, import_react19.useState)(false);
|
|
4579
|
+
const [dragOverHall, setDragOverHall] = (0, import_react19.useState)(null);
|
|
4580
|
+
const [picking, setPicking] = (0, import_react19.useState)(null);
|
|
4581
|
+
const [editing, setEditing] = (0, import_react19.useState)(null);
|
|
4582
|
+
const [expandedRooms, setExpandedRooms] = (0, import_react19.useState)(/* @__PURE__ */ new Set());
|
|
4583
|
+
const [roomRecords, setRoomRecords] = (0, import_react19.useState)({});
|
|
4584
|
+
const [expandedHalls, setExpandedHalls] = (0, import_react19.useState)(() => {
|
|
4268
4585
|
try {
|
|
4269
4586
|
const v = window.localStorage.getItem("dsh.memory.halls.open");
|
|
4270
4587
|
return v ? new Set(JSON.parse(v)) : /* @__PURE__ */ new Set();
|
|
@@ -4272,9 +4589,9 @@ var __defProp = Object.defineProperty;
|
|
|
4272
4589
|
return /* @__PURE__ */ new Set();
|
|
4273
4590
|
}
|
|
4274
4591
|
});
|
|
4275
|
-
const [filter, setFilter] = (0,
|
|
4276
|
-
const dragRef = (0,
|
|
4277
|
-
const [ghost, setGhost] = (0,
|
|
4592
|
+
const [filter, setFilter] = (0, import_react19.useState)("");
|
|
4593
|
+
const dragRef = (0, import_react19.useRef)(null);
|
|
4594
|
+
const [ghost, setGhost] = (0, import_react19.useState)(null);
|
|
4278
4595
|
const onDragLabelDown = (ev, slug) => {
|
|
4279
4596
|
if (!hiPriv || busy || ev.button !== 0) return;
|
|
4280
4597
|
ev.currentTarget.setPointerCapture(ev.pointerId);
|
|
@@ -4299,7 +4616,7 @@ var __defProp = Object.defineProperty;
|
|
|
4299
4616
|
setDragOverHall(null);
|
|
4300
4617
|
if (hall) beginReclass(d.from, hall);
|
|
4301
4618
|
};
|
|
4302
|
-
const loadAll = (0,
|
|
4619
|
+
const loadAll = (0, import_react19.useCallback)(() => {
|
|
4303
4620
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
4304
4621
|
if (r && r.ok) {
|
|
4305
4622
|
setRooms(r.value.rooms ?? []);
|
|
@@ -4308,13 +4625,13 @@ var __defProp = Object.defineProperty;
|
|
|
4308
4625
|
}
|
|
4309
4626
|
}).catch(() => void 0);
|
|
4310
4627
|
}, [rpc]);
|
|
4311
|
-
const loadHiPriv = (0,
|
|
4628
|
+
const loadHiPriv = (0, import_react19.useCallback)(() => {
|
|
4312
4629
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
4313
4630
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
4314
4631
|
}).catch(() => {
|
|
4315
4632
|
});
|
|
4316
4633
|
}, [rpc]);
|
|
4317
|
-
(0,
|
|
4634
|
+
(0, import_react19.useEffect)(() => {
|
|
4318
4635
|
loadAll();
|
|
4319
4636
|
loadHiPriv();
|
|
4320
4637
|
}, [loadAll, loadHiPriv]);
|
|
@@ -4428,7 +4745,10 @@ var __defProp = Object.defineProperty;
|
|
|
4428
4745
|
loadAll();
|
|
4429
4746
|
if (expandedRooms.has(slug)) {
|
|
4430
4747
|
const rr = await rpc("dsh-memory/list-records", { tag: slug, limit: 10, retired: false });
|
|
4431
|
-
if (rr && rr.ok)
|
|
4748
|
+
if (rr && rr.ok) {
|
|
4749
|
+
registerTypeCatalog(rr.value.typeCatalog);
|
|
4750
|
+
setRoomRecords((m) => ({ ...m, [slug]: { items: rr.value.items, total: rr.value.total ?? null } }));
|
|
4751
|
+
}
|
|
4432
4752
|
}
|
|
4433
4753
|
} else setError(r && r.error ? r.error.message : "操作失败");
|
|
4434
4754
|
});
|
|
@@ -4450,6 +4770,7 @@ var __defProp = Object.defineProperty;
|
|
|
4450
4770
|
}
|
|
4451
4771
|
const r = await rpc("dsh-memory/list-records", { tag: slug, limit: 10, retired: false });
|
|
4452
4772
|
if (r && r.ok) {
|
|
4773
|
+
registerTypeCatalog(r.value.typeCatalog);
|
|
4453
4774
|
const next = new Set(expandedRooms);
|
|
4454
4775
|
next.add(slug);
|
|
4455
4776
|
setExpandedRooms(next);
|
|
@@ -4465,7 +4786,7 @@ var __defProp = Object.defineProperty;
|
|
|
4465
4786
|
if (r.value.csv) downloadCsv(r.value.csv, `dsh-memory-room-${slug.replace(/\//g, "-")}-records.csv`);
|
|
4466
4787
|
else setError("导出为空");
|
|
4467
4788
|
});
|
|
4468
|
-
const groups = (0,
|
|
4789
|
+
const groups = (0, import_react19.useMemo)(() => {
|
|
4469
4790
|
const countOf = new Map(rooms.map((r) => [r.room, r.count]));
|
|
4470
4791
|
const byHall = /* @__PURE__ */ new Map();
|
|
4471
4792
|
for (const e of registry) {
|
|
@@ -4482,7 +4803,7 @@ var __defProp = Object.defineProperty;
|
|
|
4482
4803
|
total: entries.reduce((s2, e) => s2 + (countOf.get(e.slug) ?? 0), 0)
|
|
4483
4804
|
})).sort((a, b) => a.hall.localeCompare(b.hall));
|
|
4484
4805
|
}, [registry, rooms]);
|
|
4485
|
-
const grownOnly = (0,
|
|
4806
|
+
const grownOnly = (0, import_react19.useMemo)(() => rooms.filter((r) => !registry.some((e) => e.slug === r.room)), [rooms, registry]);
|
|
4486
4807
|
const persistHalls = (next) => {
|
|
4487
4808
|
try {
|
|
4488
4809
|
window.localStorage.setItem("dsh.memory.halls.open", JSON.stringify([...next]));
|
|
@@ -4502,7 +4823,7 @@ var __defProp = Object.defineProperty;
|
|
|
4502
4823
|
persistHalls(next);
|
|
4503
4824
|
};
|
|
4504
4825
|
const normFilter = filter.trim().toLowerCase();
|
|
4505
|
-
const visibleGroups = (0,
|
|
4826
|
+
const visibleGroups = (0, import_react19.useMemo)(() => {
|
|
4506
4827
|
if (!normFilter) return groups;
|
|
4507
4828
|
return groups.map((g) => {
|
|
4508
4829
|
const hallHit = g.hall.toLowerCase().includes(normFilter) || (g.label ?? "").toLowerCase().includes(normFilter);
|
|
@@ -4512,15 +4833,15 @@ var __defProp = Object.defineProperty;
|
|
|
4512
4833
|
return { ...g, entries };
|
|
4513
4834
|
}).filter((g) => g.entries.length > 0);
|
|
4514
4835
|
}, [groups, normFilter]);
|
|
4515
|
-
const visibleGrown = (0,
|
|
4836
|
+
const visibleGrown = (0, import_react19.useMemo)(
|
|
4516
4837
|
() => normFilter ? grownOnly.filter((r) => r.room.toLowerCase().includes(normFilter)) : grownOnly,
|
|
4517
4838
|
[grownOnly, normFilter]
|
|
4518
4839
|
);
|
|
4519
|
-
return /* @__PURE__ */ (0,
|
|
4520
|
-
/* @__PURE__ */ (0,
|
|
4521
|
-
/* @__PURE__ */ (0,
|
|
4522
|
-
/* @__PURE__ */ (0,
|
|
4523
|
-
/* @__PURE__ */ (0,
|
|
4840
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
|
|
4841
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { ...S.flexRow, marginBottom: 8 }, children: [
|
|
4842
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "Hall = Room 大类 · 大类上限 200,小类「大类/小类」细分不占额度 · 与 Wing(域)筛选无关" }),
|
|
4843
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
4844
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4524
4845
|
"button",
|
|
4525
4846
|
{
|
|
4526
4847
|
type: "button",
|
|
@@ -4537,7 +4858,7 @@ var __defProp = Object.defineProperty;
|
|
|
4537
4858
|
children: "导出词表"
|
|
4538
4859
|
}
|
|
4539
4860
|
),
|
|
4540
|
-
/* @__PURE__ */ (0,
|
|
4861
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4541
4862
|
"button",
|
|
4542
4863
|
{
|
|
4543
4864
|
type: "button",
|
|
@@ -4557,7 +4878,7 @@ var __defProp = Object.defineProperty;
|
|
|
4557
4878
|
]
|
|
4558
4879
|
}
|
|
4559
4880
|
),
|
|
4560
|
-
/* @__PURE__ */ (0,
|
|
4881
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4561
4882
|
"button",
|
|
4562
4883
|
{
|
|
4563
4884
|
type: "button",
|
|
@@ -4572,10 +4893,10 @@ var __defProp = Object.defineProperty;
|
|
|
4572
4893
|
children: hiPriv ? "高权限:开" : "高权限:关"
|
|
4573
4894
|
}
|
|
4574
4895
|
),
|
|
4575
|
-
/* @__PURE__ */ (0,
|
|
4896
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", style: btn, onClick: loadAll, title: "重拉注册表与计数", children: "刷新" })
|
|
4576
4897
|
] }),
|
|
4577
|
-
/* @__PURE__ */ (0,
|
|
4578
|
-
/* @__PURE__ */ (0,
|
|
4898
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center", marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
4899
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4579
4900
|
"input",
|
|
4580
4901
|
{
|
|
4581
4902
|
value: filter,
|
|
@@ -4584,14 +4905,14 @@ var __defProp = Object.defineProperty;
|
|
|
4584
4905
|
style: { ...S.input, width: 250, fontSize: 12 }
|
|
4585
4906
|
}
|
|
4586
4907
|
),
|
|
4587
|
-
filter ? /* @__PURE__ */ (0,
|
|
4588
|
-
/* @__PURE__ */ (0,
|
|
4589
|
-
/* @__PURE__ */ (0,
|
|
4590
|
-
/* @__PURE__ */ (0,
|
|
4591
|
-
/* @__PURE__ */ (0,
|
|
4908
|
+
filter ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", style: btn, onClick: () => setFilter(""), children: "清除" }) : null,
|
|
4909
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: `匹配 ${visibleGroups.reduce((s2, g) => s2 + g.entries.length, 0)} room / ${visibleGroups.length} hall` }),
|
|
4910
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
4911
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", style: btn, title: "展开全部 hall 的子 room", onClick: () => setAllHalls(true), children: "展开全部" }),
|
|
4912
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", style: btn, title: "收起全部 hall(只留 hall 头)", onClick: () => setAllHalls(false), children: "收起全部" })
|
|
4592
4913
|
] }),
|
|
4593
|
-
/* @__PURE__ */ (0,
|
|
4594
|
-
/* @__PURE__ */ (0,
|
|
4914
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginBottom: 10 }, children: [
|
|
4915
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4595
4916
|
"input",
|
|
4596
4917
|
{
|
|
4597
4918
|
value: regSlug,
|
|
@@ -4601,7 +4922,7 @@ var __defProp = Object.defineProperty;
|
|
|
4601
4922
|
style: { ...S.input, width: 210, fontSize: 12 }
|
|
4602
4923
|
}
|
|
4603
4924
|
),
|
|
4604
|
-
/* @__PURE__ */ (0,
|
|
4925
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4605
4926
|
"input",
|
|
4606
4927
|
{
|
|
4607
4928
|
value: regLabel,
|
|
@@ -4611,7 +4932,7 @@ var __defProp = Object.defineProperty;
|
|
|
4611
4932
|
style: { ...S.input, width: 110, fontSize: 12 }
|
|
4612
4933
|
}
|
|
4613
4934
|
),
|
|
4614
|
-
/* @__PURE__ */ (0,
|
|
4935
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4615
4936
|
"input",
|
|
4616
4937
|
{
|
|
4617
4938
|
value: regDesc,
|
|
@@ -4621,7 +4942,7 @@ var __defProp = Object.defineProperty;
|
|
|
4621
4942
|
style: { ...S.input, width: 170, fontSize: 12 }
|
|
4622
4943
|
}
|
|
4623
4944
|
),
|
|
4624
|
-
/* @__PURE__ */ (0,
|
|
4945
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4625
4946
|
"button",
|
|
4626
4947
|
{
|
|
4627
4948
|
type: "button",
|
|
@@ -4631,26 +4952,26 @@ var __defProp = Object.defineProperty;
|
|
|
4631
4952
|
children: "注册"
|
|
4632
4953
|
}
|
|
4633
4954
|
),
|
|
4634
|
-
!hiPriv && /* @__PURE__ */ (0,
|
|
4955
|
+
!hiPriv && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "管理操作需先开启高权限模式" })
|
|
4635
4956
|
] }),
|
|
4636
|
-
editing ? /* @__PURE__ */ (0,
|
|
4637
|
-
/* @__PURE__ */ (0,
|
|
4957
|
+
editing ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { position: "sticky", top: 0, zIndex: 5, background: "var(--dsh-mem-bg-inset)", display: "flex", alignItems: "center", gap: 6, marginBottom: 8, flexWrap: "wrap", padding: "6px 8px", border: "1px solid var(--dsh-mem-accent)", borderRadius: 8 }, children: [
|
|
4958
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { style: S.muted, children: [
|
|
4638
4959
|
"编辑 ",
|
|
4639
4960
|
editing.slug
|
|
4640
4961
|
] }),
|
|
4641
|
-
/* @__PURE__ */ (0,
|
|
4642
|
-
/* @__PURE__ */ (0,
|
|
4643
|
-
/* @__PURE__ */ (0,
|
|
4644
|
-
/* @__PURE__ */ (0,
|
|
4962
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("input", { value: editing.label, onChange: (ev) => setEditing({ ...editing, label: ev.target.value }), placeholder: "显示名(可中文)", disabled: busy, style: { ...S.input, width: 140, fontSize: 12 } }),
|
|
4963
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("input", { value: editing.description, onChange: (ev) => setEditing({ ...editing, description: ev.target.value }), placeholder: "归类说明(喂标注器)", disabled: busy, style: { ...S.input, width: 200, fontSize: 12 } }),
|
|
4964
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, onClick: saveEditing, style: { ...btn, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" }, children: "保存" }),
|
|
4965
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, onClick: () => setEditing(null), style: btn, children: "取消" })
|
|
4645
4966
|
] }) : null,
|
|
4646
|
-
form ? /* @__PURE__ */ (0,
|
|
4647
|
-
/* @__PURE__ */ (0,
|
|
4967
|
+
form ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { position: "sticky", top: 0, zIndex: 5, background: "var(--dsh-mem-bg-inset)", display: "flex", alignItems: "center", gap: 6, marginBottom: 8, flexWrap: "wrap", padding: "6px 8px", border: "1px solid var(--dsh-mem-accent)", borderRadius: 8 }, children: [
|
|
4968
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { style: S.muted, children: [
|
|
4648
4969
|
form.action === "merge" ? "合并" : "归类/改名",
|
|
4649
4970
|
" ",
|
|
4650
4971
|
form.from,
|
|
4651
4972
|
" →"
|
|
4652
4973
|
] }),
|
|
4653
|
-
/* @__PURE__ */ (0,
|
|
4974
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4654
4975
|
"input",
|
|
4655
4976
|
{
|
|
4656
4977
|
value: form.to,
|
|
@@ -4660,7 +4981,7 @@ var __defProp = Object.defineProperty;
|
|
|
4660
4981
|
style: { ...S.input, width: 190, fontSize: 12 }
|
|
4661
4982
|
}
|
|
4662
4983
|
),
|
|
4663
|
-
form.action === "rename" ? /* @__PURE__ */ (0,
|
|
4984
|
+
form.action === "rename" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: { display: "inline-flex", gap: 4, flexWrap: "wrap" }, children: groups.filter((gg) => gg.hall !== majorOf(form.from)).map((gg) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4664
4985
|
"button",
|
|
4665
4986
|
{
|
|
4666
4987
|
type: "button",
|
|
@@ -4671,32 +4992,32 @@ var __defProp = Object.defineProperty;
|
|
|
4671
4992
|
},
|
|
4672
4993
|
gg.hall
|
|
4673
4994
|
)) }) : null,
|
|
4674
|
-
/* @__PURE__ */ (0,
|
|
4675
|
-
/* @__PURE__ */ (0,
|
|
4995
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, onClick: () => previewMerge(), style: { ...btn, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" }, children: "预览" }),
|
|
4996
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, onClick: () => {
|
|
4676
4997
|
setForm(null);
|
|
4677
4998
|
setPreview(null);
|
|
4678
4999
|
setPicking(null);
|
|
4679
5000
|
}, style: btn, children: "取消" }),
|
|
4680
|
-
picking ? /* @__PURE__ */ (0,
|
|
4681
|
-
/* @__PURE__ */ (0,
|
|
5001
|
+
picking ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "挑选中:点击目标 hall 头完成归类" }) : null,
|
|
5002
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "与反刍并发会互相覆盖,请在反刍空闲时执行。" })
|
|
4682
5003
|
] }) : null,
|
|
4683
|
-
preview ? /* @__PURE__ */ (0,
|
|
4684
|
-
/* @__PURE__ */ (0,
|
|
4685
|
-
/* @__PURE__ */ (0,
|
|
4686
|
-
/* @__PURE__ */ (0,
|
|
5004
|
+
preview ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { position: "sticky", top: 0, zIndex: 5, background: "var(--dsh-mem-bg-inset)", marginBottom: 8, padding: "6px 8px", border: "1px solid var(--dsh-mem-danger)", borderRadius: 8, fontSize: 12 }, children: [
|
|
5005
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { children: preview.notice }),
|
|
5006
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: 6, marginTop: 4 }, children: [
|
|
5007
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { type: "button", disabled: busy, onClick: execMerge, style: { ...btn, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" }, children: [
|
|
4687
5008
|
"确认执行",
|
|
4688
5009
|
preview.action === "merge" ? "合并" : "归类/改名"
|
|
4689
5010
|
] }),
|
|
4690
|
-
/* @__PURE__ */ (0,
|
|
5011
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, onClick: () => setPreview(null), style: btn, children: "再改改" })
|
|
4691
5012
|
] })
|
|
4692
5013
|
] }) : null,
|
|
4693
|
-
msg ? /* @__PURE__ */ (0,
|
|
4694
|
-
error ? /* @__PURE__ */ (0,
|
|
4695
|
-
ghost ? /* @__PURE__ */ (0,
|
|
4696
|
-
visibleGroups.length === 0 ? /* @__PURE__ */ (0,
|
|
5014
|
+
msg ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.hint, children: msg }) : null,
|
|
5015
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.error, children: error }) : null,
|
|
5016
|
+
ghost ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { position: "fixed", left: ghost.x + 12, top: ghost.y + 12, zIndex: 9999, pointerEvents: "none", fontSize: 12, padding: "2px 10px", borderRadius: 999, border: "1px solid var(--dsh-mem-accent)", background: "var(--dsh-mem-bg-inset)", color: "var(--dsh-mem-accent)" }, children: ghost.text }) : null,
|
|
5017
|
+
visibleGroups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: S.intro, children: normFilter ? "无匹配的 hall/room。" : "注册表为空。在上方注册 Hall/Room(如 dsh-plugin),或把自生长 slug「收编」进词表 —— 之后候选标注器会优先把相关记忆挂到这些 slug 上。" }) : visibleGroups.map((g) => {
|
|
4697
5018
|
const hallOpen = !!normFilter || expandedHalls.has(g.hall);
|
|
4698
|
-
return /* @__PURE__ */ (0,
|
|
4699
|
-
/* @__PURE__ */ (0,
|
|
5019
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { marginBottom: 10, border: "1px solid var(--dsh-mem-border)", borderRadius: 8, overflow: "hidden" }, children: [
|
|
5020
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4700
5021
|
"div",
|
|
4701
5022
|
{
|
|
4702
5023
|
"data-hall": g.hall,
|
|
@@ -4737,7 +5058,7 @@ var __defProp = Object.defineProperty;
|
|
|
4737
5058
|
},
|
|
4738
5059
|
title: picking ? "点击此 hall:把「" + picking + "」归入 " + g.hall + " 下(major/minor,预览后确认)" : hiPriv ? "拖入 room 归类到该 hall 下(major/minor;记录随迁,旧名进别名,预览后确认)" : void 0,
|
|
4739
5060
|
children: [
|
|
4740
|
-
/* @__PURE__ */ (0,
|
|
5061
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4741
5062
|
"button",
|
|
4742
5063
|
{
|
|
4743
5064
|
type: "button",
|
|
@@ -4750,13 +5071,13 @@ var __defProp = Object.defineProperty;
|
|
|
4750
5071
|
children: hallOpen ? "▾" : "▸"
|
|
4751
5072
|
}
|
|
4752
5073
|
),
|
|
4753
|
-
/* @__PURE__ */ (0,
|
|
5074
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { style: { fontSize: 12, fontWeight: 600 }, children: [
|
|
4754
5075
|
g.hall,
|
|
4755
|
-
g.label ? /* @__PURE__ */ (0,
|
|
5076
|
+
g.label ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: " (" + g.label + ")" }) : null
|
|
4756
5077
|
] }),
|
|
4757
|
-
/* @__PURE__ */ (0,
|
|
4758
|
-
/* @__PURE__ */ (0,
|
|
4759
|
-
/* @__PURE__ */ (0,
|
|
5078
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: `合计 ${g.total} 条 · ${g.entries.length} 个 room` }),
|
|
5079
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
5080
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4760
5081
|
"button",
|
|
4761
5082
|
{
|
|
4762
5083
|
type: "button",
|
|
@@ -4777,10 +5098,10 @@ var __defProp = Object.defineProperty;
|
|
|
4777
5098
|
const standalone = e.slug === g.hall;
|
|
4778
5099
|
const count = rooms.find((r) => r.room === e.slug)?.count ?? 0;
|
|
4779
5100
|
const retired = e.status === "retired";
|
|
4780
|
-
return /* @__PURE__ */ (0,
|
|
4781
|
-
/* @__PURE__ */ (0,
|
|
4782
|
-
/* @__PURE__ */ (0,
|
|
4783
|
-
/* @__PURE__ */ (0,
|
|
5101
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { padding: "4px 10px", borderTop: "1px solid var(--dsh-mem-border)", opacity: retired ? 0.55 : 1 }, children: [
|
|
5102
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
5103
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { flex: 1, minWidth: 0, display: "flex", flexWrap: "wrap", gap: "2px 8px", alignItems: "baseline" }, children: [
|
|
5104
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4784
5105
|
"button",
|
|
4785
5106
|
{
|
|
4786
5107
|
type: "button",
|
|
@@ -4790,7 +5111,7 @@ var __defProp = Object.defineProperty;
|
|
|
4790
5111
|
children: expandedRooms.has(e.slug) ? "▾" : "▸"
|
|
4791
5112
|
}
|
|
4792
5113
|
),
|
|
4793
|
-
/* @__PURE__ */ (0,
|
|
5114
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4794
5115
|
"span",
|
|
4795
5116
|
{
|
|
4796
5117
|
style: { fontSize: 12, cursor: hiPriv && !busy ? "grab" : "default", touchAction: "none" },
|
|
@@ -4804,20 +5125,20 @@ var __defProp = Object.defineProperty;
|
|
|
4804
5125
|
]
|
|
4805
5126
|
}
|
|
4806
5127
|
),
|
|
4807
|
-
e.label ? /* @__PURE__ */ (0,
|
|
4808
|
-
/* @__PURE__ */ (0,
|
|
4809
|
-
retired ? /* @__PURE__ */ (0,
|
|
4810
|
-
(e.aliases ?? []).length > 0 ? /* @__PURE__ */ (0,
|
|
5128
|
+
e.label ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: e.label }) : null,
|
|
5129
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: count + " 条" }),
|
|
5130
|
+
retired ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "已退役" }) : null,
|
|
5131
|
+
(e.aliases ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: { ...S.muted, wordBreak: "break-all" }, children: "别名: " + (e.aliases ?? []).join(", ") }) : null
|
|
4811
5132
|
] }),
|
|
4812
|
-
/* @__PURE__ */ (0,
|
|
4813
|
-
!hiPriv ? null : /* @__PURE__ */ (0,
|
|
4814
|
-
/* @__PURE__ */ (0,
|
|
5133
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: 6, flexShrink: 0, alignItems: "center" }, children: [
|
|
5134
|
+
!hiPriv ? null : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
5135
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, title: "编辑显示名/归类说明", onClick: () => {
|
|
4815
5136
|
setEditing({ slug: e.slug, label: e.label ?? "", description: e.description ?? "" });
|
|
4816
5137
|
setForm(null);
|
|
4817
5138
|
setPreview(null);
|
|
4818
5139
|
setPicking(null);
|
|
4819
5140
|
}, style: btn, children: "编辑" }),
|
|
4820
|
-
/* @__PURE__ */ (0,
|
|
5141
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4821
5142
|
"button",
|
|
4822
5143
|
{
|
|
4823
5144
|
type: "button",
|
|
@@ -4838,43 +5159,43 @@ var __defProp = Object.defineProperty;
|
|
|
4838
5159
|
children: picking === e.slug ? "选 hall…" : "归类"
|
|
4839
5160
|
}
|
|
4840
5161
|
),
|
|
4841
|
-
/* @__PURE__ */ (0,
|
|
5162
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, title: `改名(= merge 1:1 + 注册表改名)`, onClick: () => {
|
|
4842
5163
|
setForm({ action: "rename", from: e.slug, to: "" });
|
|
4843
5164
|
setPreview(null);
|
|
4844
5165
|
}, style: btn, children: "改名" }),
|
|
4845
|
-
/* @__PURE__ */ (0,
|
|
5166
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, title: "合并到另一个 Room(dryRun 预览→确认实跑)", onClick: () => {
|
|
4846
5167
|
setForm({ action: "merge", from: e.slug, to: "" });
|
|
4847
5168
|
setPreview(null);
|
|
4848
5169
|
}, style: btn, children: "合并" }),
|
|
4849
|
-
/* @__PURE__ */ (0,
|
|
4850
|
-
!retired ? /* @__PURE__ */ (0,
|
|
5170
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, title: retired ? "恢复该 Room 到词表" : "退役该 Room(存量 tags 不动)", onClick: () => retire(e.slug, retired), style: { ...btn, ...retired ? { color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" } : { color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" } }, children: retired ? "恢复" : "退役" }),
|
|
5171
|
+
!retired ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, title: "退役并退场该 Room 下全部记忆(软删,可在「已退场」区恢复)", onClick: () => retire(e.slug, false, true), style: { ...btn, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" }, children: "退场" }) : null
|
|
4851
5172
|
] }),
|
|
4852
|
-
/* @__PURE__ */ (0,
|
|
5173
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, title: "导出该 Room 的记录清单 CSV", onClick: () => exportRecords(e.slug), style: btn, children: "导出" })
|
|
4853
5174
|
] })
|
|
4854
5175
|
] }),
|
|
4855
|
-
expandedRooms.has(e.slug) ? /* @__PURE__ */ (0,
|
|
4856
|
-
(roomRecords[e.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0,
|
|
4857
|
-
/* @__PURE__ */ (0,
|
|
5176
|
+
expandedRooms.has(e.slug) ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { margin: "4px 0 2px", padding: "4px 8px", border: "1px dashed var(--dsh-mem-border)", borderRadius: 6 }, children: [
|
|
5177
|
+
(roomRecords[e.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { fontSize: 11, padding: "3px 0", borderBottom: "1px solid var(--dsh-mem-border)" }, children: [
|
|
5178
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: tagClass(it.type), children: typeLabel(it.type) }),
|
|
4858
5179
|
" ",
|
|
4859
|
-
/* @__PURE__ */ (0,
|
|
4860
|
-
/* @__PURE__ */ (0,
|
|
5180
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: it.updatedAt ? fmtTime(it.updatedAt) : "" }),
|
|
5181
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { marginTop: 2, wordBreak: "break-all", color: "var(--dsh-mem-text-2)" }, children: it.content.length > 120 ? it.content.slice(0, 120) + "…" : it.content })
|
|
4861
5182
|
] }, it.id)),
|
|
4862
|
-
(roomRecords[e.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0,
|
|
4863
|
-
(roomRecords[e.slug]?.total ?? 0) > (roomRecords[e.slug]?.items.length ?? 0) ? /* @__PURE__ */ (0,
|
|
5183
|
+
(roomRecords[e.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.muted, children: "该 Room 暂无记录。" }) : null,
|
|
5184
|
+
(roomRecords[e.slug]?.total ?? 0) > (roomRecords[e.slug]?.items.length ?? 0) ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { ...S.muted, fontSize: 11 }, children: "共 " + roomRecords[e.slug].total + " 条,仅显示前 " + roomRecords[e.slug].items.length + " 条" }) : null
|
|
4864
5185
|
] }) : null
|
|
4865
5186
|
] }, e.slug);
|
|
4866
5187
|
}) : null
|
|
4867
5188
|
] }, g.hall);
|
|
4868
5189
|
}),
|
|
4869
|
-
visibleGrown.length > 0 ? /* @__PURE__ */ (0,
|
|
4870
|
-
/* @__PURE__ */ (0,
|
|
5190
|
+
visibleGrown.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { marginTop: 4 }, children: [
|
|
5191
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { type: "button", onClick: () => setGrownOpen(!grownOpen), style: btn, title: grownOpen ? "收起未注册自生长 Room" : "展开未注册自生长 Room", children: [
|
|
4871
5192
|
grownOpen ? "▾" : "▸",
|
|
4872
5193
|
" 自生长未注册 · 共 ",
|
|
4873
5194
|
visibleGrown.length
|
|
4874
5195
|
] }),
|
|
4875
|
-
/* @__PURE__ */ (0,
|
|
4876
|
-
grownOpen ? /* @__PURE__ */ (0,
|
|
4877
|
-
/* @__PURE__ */ (0,
|
|
5196
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "(只在 tags 里涌现,不在词表 —— 收编后标注器才会优先挂靠)" }),
|
|
5197
|
+
grownOpen ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginTop: 6 }, children: visibleGrown.map((r) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { style: { display: "inline-flex", alignItems: "center", gap: 4 }, children: [
|
|
5198
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4878
5199
|
"span",
|
|
4879
5200
|
{
|
|
4880
5201
|
style: { ...btn, cursor: hiPriv && !busy ? "grab" : "default", borderRadius: 999, padding: "2px 8px", touchAction: "none" },
|
|
@@ -4885,8 +5206,8 @@ var __defProp = Object.defineProperty;
|
|
|
4885
5206
|
children: r.room + " · " + r.count
|
|
4886
5207
|
}
|
|
4887
5208
|
),
|
|
4888
|
-
/* @__PURE__ */ (0,
|
|
4889
|
-
/* @__PURE__ */ (0,
|
|
5209
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: !hiPriv || busy, title: "收编进注册表(source=grown,原地)", onClick: () => adopt(r.room), style: { ...btn, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)", opacity: !hiPriv || busy ? 0.5 : 1 }, children: "收编" }),
|
|
5210
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4890
5211
|
"button",
|
|
4891
5212
|
{
|
|
4892
5213
|
type: "button",
|
|
@@ -4913,8 +5234,8 @@ var __defProp = Object.defineProperty;
|
|
|
4913
5234
|
}
|
|
4914
5235
|
|
|
4915
5236
|
// client/src/tabs/RoomTab.tsx
|
|
4916
|
-
var
|
|
4917
|
-
var
|
|
5237
|
+
var import_react20 = require("react");
|
|
5238
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4918
5239
|
var btn2 = {
|
|
4919
5240
|
cursor: "pointer",
|
|
4920
5241
|
fontSize: 12,
|
|
@@ -4935,22 +5256,22 @@ var __defProp = Object.defineProperty;
|
|
|
4935
5256
|
}
|
|
4936
5257
|
function RoomTab(props) {
|
|
4937
5258
|
const rpc = props.rpc;
|
|
4938
|
-
const [registry, setRegistry] = (0,
|
|
4939
|
-
const [counts, setCounts] = (0,
|
|
4940
|
-
const [orphanCount, setOrphanCount] = (0,
|
|
4941
|
-
const [busy, setBusy] = (0,
|
|
4942
|
-
const [msg, setMsg] = (0,
|
|
4943
|
-
const [error, setError] = (0,
|
|
4944
|
-
const [hiPriv, setHiPriv] = (0,
|
|
4945
|
-
const [hiPrivBusy, setHiPrivBusy] = (0,
|
|
4946
|
-
const [reg, setReg] = (0,
|
|
4947
|
-
const [editing, setEditing] = (0,
|
|
4948
|
-
const [renaming, setRenaming] = (0,
|
|
4949
|
-
const [expanded, setExpanded] = (0,
|
|
4950
|
-
const [retiredFilter, setRetiredFilter] = (0,
|
|
4951
|
-
const [filter, setFilter] = (0,
|
|
4952
|
-
const [records, setRecords] = (0,
|
|
4953
|
-
const loadAll = (0,
|
|
5259
|
+
const [registry, setRegistry] = (0, import_react20.useState)([]);
|
|
5260
|
+
const [counts, setCounts] = (0, import_react20.useState)([]);
|
|
5261
|
+
const [orphanCount, setOrphanCount] = (0, import_react20.useState)(0);
|
|
5262
|
+
const [busy, setBusy] = (0, import_react20.useState)(false);
|
|
5263
|
+
const [msg, setMsg] = (0, import_react20.useState)(null);
|
|
5264
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
5265
|
+
const [hiPriv, setHiPriv] = (0, import_react20.useState)(false);
|
|
5266
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react20.useState)(false);
|
|
5267
|
+
const [reg, setReg] = (0, import_react20.useState)({ slug: "", label: "", description: "" });
|
|
5268
|
+
const [editing, setEditing] = (0, import_react20.useState)(null);
|
|
5269
|
+
const [renaming, setRenaming] = (0, import_react20.useState)(null);
|
|
5270
|
+
const [expanded, setExpanded] = (0, import_react20.useState)(/* @__PURE__ */ new Set());
|
|
5271
|
+
const [retiredFilter, setRetiredFilter] = (0, import_react20.useState)("");
|
|
5272
|
+
const [filter, setFilter] = (0, import_react20.useState)("");
|
|
5273
|
+
const [records, setRecords] = (0, import_react20.useState)({});
|
|
5274
|
+
const loadAll = (0, import_react20.useCallback)(() => {
|
|
4954
5275
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
4955
5276
|
if (r && r.ok) {
|
|
4956
5277
|
setCounts(r.value.rooms ?? []);
|
|
@@ -4959,13 +5280,13 @@ var __defProp = Object.defineProperty;
|
|
|
4959
5280
|
}
|
|
4960
5281
|
}).catch(() => void 0);
|
|
4961
5282
|
}, [rpc]);
|
|
4962
|
-
const loadHiPriv = (0,
|
|
5283
|
+
const loadHiPriv = (0, import_react20.useCallback)(() => {
|
|
4963
5284
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
4964
5285
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
4965
5286
|
}).catch(() => {
|
|
4966
5287
|
});
|
|
4967
5288
|
}, [rpc]);
|
|
4968
|
-
(0,
|
|
5289
|
+
(0, import_react20.useEffect)(() => {
|
|
4969
5290
|
loadAll();
|
|
4970
5291
|
loadHiPriv();
|
|
4971
5292
|
}, [loadAll, loadHiPriv]);
|
|
@@ -5055,7 +5376,10 @@ var __defProp = Object.defineProperty;
|
|
|
5055
5376
|
loadAll();
|
|
5056
5377
|
if (expanded.has(slug)) {
|
|
5057
5378
|
const rr = await rpc("dsh-memory/list-records", { tag: slug, limit: 10, retired: false });
|
|
5058
|
-
if (rr && rr.ok)
|
|
5379
|
+
if (rr && rr.ok) {
|
|
5380
|
+
registerTypeCatalog(rr.value.typeCatalog);
|
|
5381
|
+
setRecords((m) => ({ ...m, [slug]: { items: rr.value.items, total: rr.value.total ?? null } }));
|
|
5382
|
+
}
|
|
5059
5383
|
}
|
|
5060
5384
|
} else setError(r && r.error ? r.error.message : "操作失败");
|
|
5061
5385
|
});
|
|
@@ -5084,6 +5408,7 @@ var __defProp = Object.defineProperty;
|
|
|
5084
5408
|
}
|
|
5085
5409
|
const r = await rpc("dsh-memory/list-records", { tag: slug, limit: 10, retired: false });
|
|
5086
5410
|
if (r && r.ok) {
|
|
5411
|
+
registerTypeCatalog(r.value.typeCatalog);
|
|
5087
5412
|
const next = new Set(expanded);
|
|
5088
5413
|
next.add(slug);
|
|
5089
5414
|
setExpanded(next);
|
|
@@ -5103,11 +5428,11 @@ var __defProp = Object.defineProperty;
|
|
|
5103
5428
|
const visibleRows = normFilter ? rows.filter(
|
|
5104
5429
|
(row2) => row2.slug.toLowerCase().includes(normFilter) || (row2.entry?.label ?? "").toLowerCase().includes(normFilter) || (row2.entry?.aliases ?? []).some((a) => a.toLowerCase().includes(normFilter))
|
|
5105
5430
|
) : rows;
|
|
5106
|
-
return /* @__PURE__ */ (0,
|
|
5107
|
-
/* @__PURE__ */ (0,
|
|
5108
|
-
/* @__PURE__ */ (0,
|
|
5109
|
-
/* @__PURE__ */ (0,
|
|
5110
|
-
/* @__PURE__ */ (0,
|
|
5431
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
|
|
5432
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { ...S.flexRow, marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
5433
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "Room 级管理:存在(注册/收编/退役)· 名称(显示名/说明/改名)· 条目(展开浏览) · 归类到 hall 请到「Hall」页" }),
|
|
5434
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.grow }),
|
|
5435
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { type: "button", style: btn2, title: "导出无 Room 绑定的孤儿清单(含候选)", onClick: () => run(async () => {
|
|
5111
5436
|
const r = await rpc("dsh-memory/rooms-export", { kind: "orphans" });
|
|
5112
5437
|
if (!r.ok) {
|
|
5113
5438
|
setError(r.error.message);
|
|
@@ -5118,7 +5443,7 @@ var __defProp = Object.defineProperty;
|
|
|
5118
5443
|
"导出孤儿 · ",
|
|
5119
5444
|
orphanCount
|
|
5120
5445
|
] }),
|
|
5121
|
-
/* @__PURE__ */ (0,
|
|
5446
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5122
5447
|
"button",
|
|
5123
5448
|
{
|
|
5124
5449
|
type: "button",
|
|
@@ -5129,35 +5454,35 @@ var __defProp = Object.defineProperty;
|
|
|
5129
5454
|
children: hiPriv ? "高权限:开" : "高权限:关"
|
|
5130
5455
|
}
|
|
5131
5456
|
),
|
|
5132
|
-
/* @__PURE__ */ (0,
|
|
5457
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn2, onClick: loadAll, children: "刷新" })
|
|
5133
5458
|
] }),
|
|
5134
|
-
editing ? /* @__PURE__ */ (0,
|
|
5135
|
-
/* @__PURE__ */ (0,
|
|
5459
|
+
editing ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { position: "sticky", top: 0, zIndex: 5, background: "var(--dsh-mem-bg-inset)", display: "flex", alignItems: "center", gap: 6, marginBottom: 8, flexWrap: "wrap", padding: "6px 8px", border: "1px solid var(--dsh-mem-accent)", borderRadius: 8 }, children: [
|
|
5460
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: S.muted, children: [
|
|
5136
5461
|
"编辑 ",
|
|
5137
5462
|
editing.slug
|
|
5138
5463
|
] }),
|
|
5139
|
-
/* @__PURE__ */ (0,
|
|
5140
|
-
/* @__PURE__ */ (0,
|
|
5141
|
-
/* @__PURE__ */ (0,
|
|
5142
|
-
/* @__PURE__ */ (0,
|
|
5464
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { value: editing.label, onChange: (e) => setEditing({ ...editing, label: e.target.value }), placeholder: "显示名(可中文)", disabled: busy, style: { ...S.input, width: 140, fontSize: 12 } }),
|
|
5465
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { value: editing.description, onChange: (e) => setEditing({ ...editing, description: e.target.value }), placeholder: "归类说明(喂标注器)", disabled: busy, style: { ...S.input, width: 200, fontSize: 12 } }),
|
|
5466
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: saveEditing, style: { ...btn2, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" }, children: "保存" }),
|
|
5467
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: () => setEditing(null), style: btn2, children: "取消" })
|
|
5143
5468
|
] }) : null,
|
|
5144
|
-
renaming ? /* @__PURE__ */ (0,
|
|
5145
|
-
/* @__PURE__ */ (0,
|
|
5469
|
+
renaming ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { position: "sticky", top: 0, zIndex: 5, background: "var(--dsh-mem-bg-inset)", display: "flex", alignItems: "center", gap: 6, marginBottom: 8, flexWrap: "wrap", padding: "6px 8px", border: "1px solid var(--dsh-mem-accent)", borderRadius: 8 }, children: [
|
|
5470
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: S.muted, children: [
|
|
5146
5471
|
"改名 ",
|
|
5147
5472
|
renaming.slug,
|
|
5148
5473
|
" →"
|
|
5149
5474
|
] }),
|
|
5150
|
-
/* @__PURE__ */ (0,
|
|
5151
|
-
/* @__PURE__ */ (0,
|
|
5152
|
-
/* @__PURE__ */ (0,
|
|
5153
|
-
/* @__PURE__ */ (0,
|
|
5154
|
-
/* @__PURE__ */ (0,
|
|
5475
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { value: renaming.to, onChange: (e) => setRenaming({ ...renaming, to: e.target.value }), placeholder: "新 slug(可两级:hall/子类)", disabled: busy, style: { ...S.input, width: 200, fontSize: 12 } }),
|
|
5476
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: previewRename, style: { ...btn2, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" }, children: "预览" }),
|
|
5477
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: execRename, style: { ...btn2, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" }, children: "确认执行" }),
|
|
5478
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: () => setRenaming(null), style: btn2, children: "取消" }),
|
|
5479
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "记录随迁;与反刍并发会互相覆盖,请在反刍空闲时执行。" })
|
|
5155
5480
|
] }) : null,
|
|
5156
|
-
/* @__PURE__ */ (0,
|
|
5157
|
-
/* @__PURE__ */ (0,
|
|
5481
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
5482
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "退场筛选" }),
|
|
5158
5483
|
[["", "全部"], ["active", "活跃"], ["retired", "已退役"]].map(([val, label]) => {
|
|
5159
5484
|
const on = retiredFilter === val;
|
|
5160
|
-
return /* @__PURE__ */ (0,
|
|
5485
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5161
5486
|
"button",
|
|
5162
5487
|
{
|
|
5163
5488
|
type: "button",
|
|
@@ -5177,8 +5502,8 @@ var __defProp = Object.defineProperty;
|
|
|
5177
5502
|
val
|
|
5178
5503
|
);
|
|
5179
5504
|
}),
|
|
5180
|
-
/* @__PURE__ */ (0,
|
|
5181
|
-
/* @__PURE__ */ (0,
|
|
5505
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.grow }),
|
|
5506
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5182
5507
|
"input",
|
|
5183
5508
|
{
|
|
5184
5509
|
value: filter,
|
|
@@ -5187,24 +5512,24 @@ var __defProp = Object.defineProperty;
|
|
|
5187
5512
|
style: { ...S.input, width: 230, fontSize: 12 }
|
|
5188
5513
|
}
|
|
5189
5514
|
),
|
|
5190
|
-
filter ? /* @__PURE__ */ (0,
|
|
5515
|
+
filter ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn2, onClick: () => setFilter(""), children: "清除" }) : null
|
|
5191
5516
|
] }),
|
|
5192
|
-
/* @__PURE__ */ (0,
|
|
5193
|
-
/* @__PURE__ */ (0,
|
|
5194
|
-
/* @__PURE__ */ (0,
|
|
5195
|
-
/* @__PURE__ */ (0,
|
|
5196
|
-
/* @__PURE__ */ (0,
|
|
5197
|
-
!hiPriv && /* @__PURE__ */ (0,
|
|
5517
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginBottom: 10 }, children: [
|
|
5518
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { value: reg.slug, onChange: (e) => setReg({ ...reg, slug: e.target.value }), placeholder: "slug(如 dsh-plugin 或 dsh-plugin/merge)", disabled: !hiPriv || busy, style: { ...S.input, width: 210, fontSize: 12 } }),
|
|
5519
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { value: reg.label, onChange: (e) => setReg({ ...reg, label: e.target.value }), placeholder: "名称(可中文)", disabled: !hiPriv || busy, style: { ...S.input, width: 110, fontSize: 12 } }),
|
|
5520
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { value: reg.description, onChange: (e) => setReg({ ...reg, description: e.target.value }), placeholder: "归类说明(喂标注器)", disabled: !hiPriv || busy, style: { ...S.input, width: 170, fontSize: 12 } }),
|
|
5521
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: !hiPriv || busy || !reg.slug.trim(), onClick: register, style: { ...btn2, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)", opacity: !hiPriv || busy || !reg.slug.trim() ? 0.5 : 1 }, children: "注册" }),
|
|
5522
|
+
!hiPriv && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "管理操作需先开启高权限模式" })
|
|
5198
5523
|
] }),
|
|
5199
|
-
msg ? /* @__PURE__ */ (0,
|
|
5200
|
-
error ? /* @__PURE__ */ (0,
|
|
5201
|
-
visibleRows.length === 0 ? normFilter ? /* @__PURE__ */ (0,
|
|
5524
|
+
msg ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.hint, children: msg }) : null,
|
|
5525
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.error, children: error }) : null,
|
|
5526
|
+
visibleRows.length === 0 ? normFilter ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { style: S.intro, children: "无匹配的 Room。" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { style: S.intro, children: "暂无 Room:对话/反刍会从标签涌现,或在上方注册。" }) : visibleRows.map((row2) => {
|
|
5202
5527
|
const e = row2.entry;
|
|
5203
5528
|
const retired = e?.status === "retired";
|
|
5204
5529
|
const grownOnly = !e;
|
|
5205
|
-
return /* @__PURE__ */ (0,
|
|
5206
|
-
/* @__PURE__ */ (0,
|
|
5207
|
-
/* @__PURE__ */ (0,
|
|
5530
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 6, border: "1px solid var(--dsh-mem-border)", borderRadius: 8 }, children: [
|
|
5531
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "4px 10px" }, children: [
|
|
5532
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5208
5533
|
"button",
|
|
5209
5534
|
{
|
|
5210
5535
|
type: "button",
|
|
@@ -5214,28 +5539,28 @@ var __defProp = Object.defineProperty;
|
|
|
5214
5539
|
children: expanded.has(row2.slug) ? "▾" : "▸"
|
|
5215
5540
|
}
|
|
5216
5541
|
),
|
|
5217
|
-
/* @__PURE__ */ (0,
|
|
5218
|
-
/* @__PURE__ */ (0,
|
|
5542
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { flex: 1, minWidth: 0, display: "flex", flexWrap: "wrap", gap: "2px 8px", alignItems: "baseline" }, children: [
|
|
5543
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 12, opacity: retired ? 0.6 : 1 }, children: [
|
|
5219
5544
|
row2.slug,
|
|
5220
5545
|
e?.source === "pre-registered" ? " ⭐" : ""
|
|
5221
5546
|
] }),
|
|
5222
|
-
e?.label ? /* @__PURE__ */ (0,
|
|
5223
|
-
/* @__PURE__ */ (0,
|
|
5224
|
-
grownOnly ? /* @__PURE__ */ (0,
|
|
5225
|
-
retired ? /* @__PURE__ */ (0,
|
|
5226
|
-
(e?.aliases ?? []).length > 0 ? /* @__PURE__ */ (0,
|
|
5547
|
+
e?.label ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: e.label }) : null,
|
|
5548
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: row2.count + " 条" }),
|
|
5549
|
+
grownOnly ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "(自生长未注册)" }) : null,
|
|
5550
|
+
retired ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "已退役" }) : null,
|
|
5551
|
+
(e?.aliases ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { ...S.muted, wordBreak: "break-all" }, children: "别名: " + (e?.aliases ?? []).join(", ") }) : null
|
|
5227
5552
|
] }),
|
|
5228
|
-
/* @__PURE__ */ (0,
|
|
5229
|
-
!hiPriv || grownOnly ? null : /* @__PURE__ */ (0,
|
|
5230
|
-
/* @__PURE__ */ (0,
|
|
5553
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, flexShrink: 0, alignItems: "center" }, children: [
|
|
5554
|
+
!hiPriv || grownOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
5555
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "编辑显示名/归类说明", onClick: () => {
|
|
5231
5556
|
setEditing({ slug: row2.slug, label: e?.label ?? "", description: e?.description ?? "" });
|
|
5232
5557
|
setRenaming(null);
|
|
5233
5558
|
}, style: btn2, children: "编辑" }),
|
|
5234
|
-
/* @__PURE__ */ (0,
|
|
5559
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "改名(可两级 slug;记录随迁,旧名进别名)", onClick: () => {
|
|
5235
5560
|
setRenaming({ slug: row2.slug, to: "" });
|
|
5236
5561
|
setEditing(null);
|
|
5237
5562
|
}, style: btn2, children: "改名" }),
|
|
5238
|
-
/* @__PURE__ */ (0,
|
|
5563
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5239
5564
|
"button",
|
|
5240
5565
|
{
|
|
5241
5566
|
type: "button",
|
|
@@ -5246,29 +5571,29 @@ var __defProp = Object.defineProperty;
|
|
|
5246
5571
|
children: retired ? "恢复" : "退役"
|
|
5247
5572
|
}
|
|
5248
5573
|
),
|
|
5249
|
-
!retired ? /* @__PURE__ */ (0,
|
|
5574
|
+
!retired ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "退役并退场该 Room 下全部记忆(软删,可在「已退场」区恢复)", onClick: () => retire(row2.slug, false, true), style: { ...btn2, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" }, children: "退场" }) : null
|
|
5250
5575
|
] }),
|
|
5251
|
-
grownOnly ? /* @__PURE__ */ (0,
|
|
5252
|
-
/* @__PURE__ */ (0,
|
|
5253
|
-
/* @__PURE__ */ (0,
|
|
5576
|
+
grownOnly ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
5577
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: !hiPriv || busy, title: "收编进注册表(source=grown)", onClick: () => adopt(row2.slug), style: { ...btn2, color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)", opacity: !hiPriv || busy ? 0.5 : 1 }, children: "收编" }),
|
|
5578
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: !hiPriv || busy, title: "退场该 Room 下全部记忆(软删,可在「已退场」区恢复)", onClick: () => {
|
|
5254
5579
|
setRenaming(null);
|
|
5255
5580
|
retire(row2.slug, false, true);
|
|
5256
5581
|
}, style: { ...btn2, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)", opacity: !hiPriv || busy ? 0.5 : 1 }, children: "退场" })
|
|
5257
5582
|
] }) : null,
|
|
5258
|
-
/* @__PURE__ */ (0,
|
|
5583
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "导出该 Room 的记录清单 CSV", onClick: () => exportRecords(row2.slug), style: btn2, children: "导出" })
|
|
5259
5584
|
] })
|
|
5260
5585
|
] }),
|
|
5261
|
-
expanded.has(row2.slug) ? /* @__PURE__ */ (0,
|
|
5262
|
-
(records[row2.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0,
|
|
5263
|
-
/* @__PURE__ */ (0,
|
|
5586
|
+
expanded.has(row2.slug) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { margin: "0 10px 6px", padding: "4px 8px", border: "1px dashed var(--dsh-mem-border)", borderRadius: 6 }, children: [
|
|
5587
|
+
(records[row2.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 11, padding: "3px 0", borderBottom: "1px solid var(--dsh-mem-border)" }, children: [
|
|
5588
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: tagClass(it.type), children: typeLabel(it.type) }),
|
|
5264
5589
|
" ",
|
|
5265
|
-
it.retired ? /* @__PURE__ */ (0,
|
|
5590
|
+
it.retired ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "[已退场]" }) : null,
|
|
5266
5591
|
" ",
|
|
5267
|
-
/* @__PURE__ */ (0,
|
|
5268
|
-
/* @__PURE__ */ (0,
|
|
5592
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: it.updatedAt ? fmtTime(it.updatedAt) : "" }),
|
|
5593
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginTop: 2, wordBreak: "break-all", color: "var(--dsh-mem-text-2)", opacity: it.retired ? 0.55 : 1 }, children: it.content.length > 140 ? it.content.slice(0, 140) + "…" : it.content })
|
|
5269
5594
|
] }, it.id)),
|
|
5270
|
-
(records[row2.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0,
|
|
5271
|
-
(records[row2.slug]?.total ?? 0) > (records[row2.slug]?.items.length ?? 0) ? /* @__PURE__ */ (0,
|
|
5595
|
+
(records[row2.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.muted, children: "该 Room 暂无记忆条目。" }) : null,
|
|
5596
|
+
(records[row2.slug]?.total ?? 0) > (records[row2.slug]?.items.length ?? 0) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { ...S.muted, fontSize: 11 }, children: "共 " + records[row2.slug].total + " 条,仅显示前 " + records[row2.slug].items.length + " 条" }) : null
|
|
5272
5597
|
] }) : null
|
|
5273
5598
|
] }, row2.slug);
|
|
5274
5599
|
})
|
|
@@ -5276,13 +5601,13 @@ var __defProp = Object.defineProperty;
|
|
|
5276
5601
|
}
|
|
5277
5602
|
|
|
5278
5603
|
// client/src/tabs/ScenesTab.tsx
|
|
5279
|
-
var
|
|
5280
|
-
var
|
|
5604
|
+
var import_react21 = require("react");
|
|
5605
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
5281
5606
|
function SceneCard(props) {
|
|
5282
5607
|
const s = props.s;
|
|
5283
|
-
const [open, setOpen] = (0,
|
|
5284
|
-
return /* @__PURE__ */ (0,
|
|
5285
|
-
/* @__PURE__ */ (0,
|
|
5608
|
+
const [open, setOpen] = (0, import_react21.useState)(false);
|
|
5609
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "dsh-mem-card dsh-mem-card-hover", style: S.card, children: [
|
|
5610
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
5286
5611
|
"div",
|
|
5287
5612
|
{
|
|
5288
5613
|
style: { ...S.sceneHead, cursor: "pointer", userSelect: "none" },
|
|
@@ -5290,23 +5615,23 @@ var __defProp = Object.defineProperty;
|
|
|
5290
5615
|
setOpen(!open);
|
|
5291
5616
|
},
|
|
5292
5617
|
children: [
|
|
5293
|
-
/* @__PURE__ */ (0,
|
|
5294
|
-
/* @__PURE__ */ (0,
|
|
5295
|
-
s.heat ? /* @__PURE__ */ (0,
|
|
5296
|
-
/* @__PURE__ */ (0,
|
|
5297
|
-
/* @__PURE__ */ (0,
|
|
5618
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "dsh-mem-scene-chev", style: { transform: open ? "rotate(90deg)" : "none" }, children: "▸" }),
|
|
5619
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.sceneTitle, children: s.path }),
|
|
5620
|
+
s.heat ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "热度 " + s.heat }) : null,
|
|
5621
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.grow }),
|
|
5622
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "更新 " + fmtTime(s.updated) })
|
|
5298
5623
|
]
|
|
5299
5624
|
}
|
|
5300
5625
|
),
|
|
5301
|
-
s.summary ? /* @__PURE__ */ (0,
|
|
5302
|
-
open ? /* @__PURE__ */ (0,
|
|
5626
|
+
s.summary ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { ...S.muted, marginBottom: 6 }, children: s.summary }) : null,
|
|
5627
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { style: S.pre, children: s.content || "(空)" }) : null
|
|
5303
5628
|
] });
|
|
5304
5629
|
}
|
|
5305
5630
|
function ScenesTab(props) {
|
|
5306
5631
|
const rpc = props.rpc;
|
|
5307
|
-
const [items, setItems] = (0,
|
|
5308
|
-
const [error, setError] = (0,
|
|
5309
|
-
const load = (0,
|
|
5632
|
+
const [items, setItems] = (0, import_react21.useState)(null);
|
|
5633
|
+
const [error, setError] = (0, import_react21.useState)(null);
|
|
5634
|
+
const load = (0, import_react21.useCallback)(() => {
|
|
5310
5635
|
rpc("dsh-memory/scenes", {}).then((r) => {
|
|
5311
5636
|
if (r && r.ok) {
|
|
5312
5637
|
setItems(r.value.items);
|
|
@@ -5316,25 +5641,25 @@ var __defProp = Object.defineProperty;
|
|
|
5316
5641
|
setError(String(e && e.message || e));
|
|
5317
5642
|
});
|
|
5318
5643
|
}, [rpc]);
|
|
5319
|
-
(0,
|
|
5644
|
+
(0, import_react21.useEffect)(() => {
|
|
5320
5645
|
load();
|
|
5321
5646
|
}, [load]);
|
|
5322
|
-
return /* @__PURE__ */ (0,
|
|
5323
|
-
/* @__PURE__ */ (0,
|
|
5324
|
-
/* @__PURE__ */ (0,
|
|
5325
|
-
/* @__PURE__ */ (0,
|
|
5326
|
-
/* @__PURE__ */ (0,
|
|
5647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
5648
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
5649
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: items ? items.length + " 个场景块" : "加载中…" }),
|
|
5650
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.grow }),
|
|
5651
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
5327
5652
|
] }),
|
|
5328
|
-
error ? /* @__PURE__ */ (0,
|
|
5329
|
-
items && items.length === 0 ? /* @__PURE__ */ (0,
|
|
5653
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.error, children: error }) : null,
|
|
5654
|
+
items && items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: S.intro, children: "暂无场景块。累计 5 条新记忆后 L2 会自动整合出第一个场景。" }) : null,
|
|
5330
5655
|
(items || []).map((s) => {
|
|
5331
|
-
return /* @__PURE__ */ (0,
|
|
5656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SceneCard, { s }, s.path);
|
|
5332
5657
|
})
|
|
5333
5658
|
] });
|
|
5334
5659
|
}
|
|
5335
5660
|
|
|
5336
5661
|
// client/src/panel.tsx
|
|
5337
|
-
var
|
|
5662
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
5338
5663
|
var TABS = [
|
|
5339
5664
|
["overview", "概览"],
|
|
5340
5665
|
["records", "记忆"],
|
|
@@ -5355,10 +5680,10 @@ var __defProp = Object.defineProperty;
|
|
|
5355
5680
|
];
|
|
5356
5681
|
function MemoryPanel(props) {
|
|
5357
5682
|
const rpc = props.rpc;
|
|
5358
|
-
const [tab, setTab] = (0,
|
|
5359
|
-
const [skin, setSkinState] = (0,
|
|
5683
|
+
const [tab, setTab] = (0, import_react22.useState)("overview");
|
|
5684
|
+
const [skin, setSkinState] = (0, import_react22.useState)(() => getSkin());
|
|
5360
5685
|
ensureThemeStyle(skin);
|
|
5361
|
-
(0,
|
|
5686
|
+
(0, import_react22.useEffect)(() => {
|
|
5362
5687
|
applySkin(skin);
|
|
5363
5688
|
watchSidebarIcon();
|
|
5364
5689
|
}, [skin]);
|
|
@@ -5367,21 +5692,21 @@ var __defProp = Object.defineProperty;
|
|
|
5367
5692
|
setSkinState(next);
|
|
5368
5693
|
};
|
|
5369
5694
|
let body;
|
|
5370
|
-
if (tab === "overview") body = /* @__PURE__ */ (0,
|
|
5371
|
-
else if (tab === "records") body = /* @__PURE__ */ (0,
|
|
5372
|
-
else if (tab === "conflicts") body = /* @__PURE__ */ (0,
|
|
5373
|
-
else if (tab === "scenes") body = /* @__PURE__ */ (0,
|
|
5374
|
-
else if (tab === "rooms") body = /* @__PURE__ */ (0,
|
|
5375
|
-
else if (tab === "room") body = /* @__PURE__ */ (0,
|
|
5376
|
-
else if (tab === "persona") body = /* @__PURE__ */ (0,
|
|
5377
|
-
else if (tab === "cost") body = /* @__PURE__ */ (0,
|
|
5378
|
-
else if (tab === "connect") body = /* @__PURE__ */ (0,
|
|
5379
|
-
else if (tab === "skills") body = /* @__PURE__ */ (0,
|
|
5380
|
-
else body = /* @__PURE__ */ (0,
|
|
5381
|
-
return /* @__PURE__ */ (0,
|
|
5382
|
-
/* @__PURE__ */ (0,
|
|
5383
|
-
/* @__PURE__ */ (0,
|
|
5384
|
-
/* @__PURE__ */ (0,
|
|
5695
|
+
if (tab === "overview") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(OverviewTab, { rpc });
|
|
5696
|
+
else if (tab === "records") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(RecordsTab, { rpc });
|
|
5697
|
+
else if (tab === "conflicts") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ConflictsTab, { rpc });
|
|
5698
|
+
else if (tab === "scenes") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ScenesTab, { rpc });
|
|
5699
|
+
else if (tab === "rooms") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(RoomsTab, { rpc });
|
|
5700
|
+
else if (tab === "room") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(RoomTab, { rpc });
|
|
5701
|
+
else if (tab === "persona") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PersonaTab, { rpc });
|
|
5702
|
+
else if (tab === "cost") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CostTab, { rpc });
|
|
5703
|
+
else if (tab === "connect") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ConnectTab, { rpc });
|
|
5704
|
+
else if (tab === "skills") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SkillsTab, { rpc });
|
|
5705
|
+
else body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LogTab, { rpc });
|
|
5706
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "dsh-mem-root", style: S.section, children: [
|
|
5707
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h2", { style: S.heading, children: "记忆 (Memory)" }),
|
|
5708
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { style: S.intro, children: "L0~L3 分层蒸馏记忆:浏览被记住的内容,控制记忆模式开关。" }),
|
|
5709
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
5385
5710
|
"div",
|
|
5386
5711
|
{
|
|
5387
5712
|
style: {
|
|
@@ -5393,8 +5718,8 @@ var __defProp = Object.defineProperty;
|
|
|
5393
5718
|
marginBottom: 10
|
|
5394
5719
|
},
|
|
5395
5720
|
children: [
|
|
5396
|
-
/* @__PURE__ */ (0,
|
|
5397
|
-
SKIN_OPTS.map((s) => /* @__PURE__ */ (0,
|
|
5721
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)", marginRight: 4 }, children: "皮肤" }),
|
|
5722
|
+
SKIN_OPTS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5398
5723
|
"button",
|
|
5399
5724
|
{
|
|
5400
5725
|
className: skin === s[0] ? "dsh-mem-tab dsh-mem-tab-on" : "dsh-mem-tab",
|
|
@@ -5407,8 +5732,8 @@ var __defProp = Object.defineProperty;
|
|
|
5407
5732
|
]
|
|
5408
5733
|
}
|
|
5409
5734
|
),
|
|
5410
|
-
/* @__PURE__ */ (0,
|
|
5411
|
-
return /* @__PURE__ */ (0,
|
|
5735
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: S.tabbar, children: TABS.map((t) => {
|
|
5736
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5412
5737
|
"button",
|
|
5413
5738
|
{
|
|
5414
5739
|
className: tab === t[0] ? "dsh-mem-tab dsh-mem-tab-on" : "dsh-mem-tab",
|
|
@@ -5425,7 +5750,7 @@ var __defProp = Object.defineProperty;
|
|
|
5425
5750
|
}
|
|
5426
5751
|
|
|
5427
5752
|
// client/src/pill/MemoryModePill.tsx
|
|
5428
|
-
var
|
|
5753
|
+
var import_react26 = require("react");
|
|
5429
5754
|
|
|
5430
5755
|
// src/util/context-occupancy.ts
|
|
5431
5756
|
var CONTEXT_METER_CIRCUMFERENCE = 34.55751918948772;
|
|
@@ -5450,8 +5775,8 @@ var __defProp = Object.defineProperty;
|
|
|
5450
5775
|
var panelListeners = /* @__PURE__ */ new Set();
|
|
5451
5776
|
var panelWasOpen = false;
|
|
5452
5777
|
var snapshotListeners = /* @__PURE__ */ new Set();
|
|
5453
|
-
function initOccupancyIndicator(
|
|
5454
|
-
statsCall =
|
|
5778
|
+
function initOccupancyIndicator(call2) {
|
|
5779
|
+
statsCall = call2;
|
|
5455
5780
|
}
|
|
5456
5781
|
function noteOccupancySession(sessionId) {
|
|
5457
5782
|
if (sessionId === activeSessionId) return;
|
|
@@ -5741,23 +6066,23 @@ var __defProp = Object.defineProperty;
|
|
|
5741
6066
|
}
|
|
5742
6067
|
|
|
5743
6068
|
// client/src/pill/WingWheel.tsx
|
|
5744
|
-
var
|
|
6069
|
+
var import_react25 = require("react");
|
|
5745
6070
|
|
|
5746
6071
|
// client/src/pill/SessionInfoArea.tsx
|
|
5747
|
-
var
|
|
5748
|
-
var
|
|
6072
|
+
var import_react23 = require("react");
|
|
6073
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
5749
6074
|
function sinfoCell(val, label, title) {
|
|
5750
|
-
return /* @__PURE__ */ (0,
|
|
5751
|
-
/* @__PURE__ */ (0,
|
|
5752
|
-
/* @__PURE__ */ (0,
|
|
6075
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { title: title || void 0, children: [
|
|
6076
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "dsh-mem-sinfo-val", children: val }),
|
|
6077
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "dsh-mem-sinfo-label", children: label })
|
|
5753
6078
|
] });
|
|
5754
6079
|
}
|
|
5755
6080
|
function SessionInfoArea(props) {
|
|
5756
6081
|
const rpc = props.rpc;
|
|
5757
6082
|
const sessionId = props.sessionId;
|
|
5758
|
-
const [stats, setStats] = (0,
|
|
5759
|
-
const busyRef = (0,
|
|
5760
|
-
(0,
|
|
6083
|
+
const [stats, setStats] = (0, import_react23.useState)(void 0);
|
|
6084
|
+
const busyRef = (0, import_react23.useRef)(false);
|
|
6085
|
+
(0, import_react23.useEffect)(() => {
|
|
5761
6086
|
if (!rpc || !sessionId) return void 0;
|
|
5762
6087
|
let alive = true;
|
|
5763
6088
|
let timer = null;
|
|
@@ -5790,7 +6115,7 @@ var __defProp = Object.defineProperty;
|
|
|
5790
6115
|
}, [rpc, sessionId]);
|
|
5791
6116
|
if (stats === null) return null;
|
|
5792
6117
|
if (stats === void 0) {
|
|
5793
|
-
return /* @__PURE__ */ (0,
|
|
6118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "dsh-mem-sinfo", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "dsh-mem-sinfo-grid", children: [
|
|
5794
6119
|
sinfoCell("…", "召回命中"),
|
|
5795
6120
|
sinfoCell("…", "攒批进度"),
|
|
5796
6121
|
sinfoCell("…", "本会话记忆"),
|
|
@@ -5839,30 +6164,30 @@ var __defProp = Object.defineProperty;
|
|
|
5839
6164
|
else if (stats.retrieval === "none") note = "检索不可用(FTS 与向量均失效)";
|
|
5840
6165
|
}
|
|
5841
6166
|
const ago = fmtAgo(gl.lastExtractAt);
|
|
5842
|
-
return /* @__PURE__ */ (0,
|
|
5843
|
-
warn ? /* @__PURE__ */ (0,
|
|
5844
|
-
/* @__PURE__ */ (0,
|
|
6167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "dsh-mem-sinfo", children: [
|
|
6168
|
+
warn ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "dsh-mem-sinfo-warn", children: warn }) : null,
|
|
6169
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "dsh-mem-sinfo-grid", children: [
|
|
5845
6170
|
sinfoCell(rcVal, rcLabel, rcTitle),
|
|
5846
6171
|
sinfoCell(dVal, dLabel, dTitle),
|
|
5847
6172
|
sinfoCell(String(di.producedRecords || 0), "本会话记忆", pTitle),
|
|
5848
6173
|
sinfoCell(stats.l0Count != null ? String(stats.l0Count) : "…", "会话消息")
|
|
5849
6174
|
] }),
|
|
5850
|
-
note ? /* @__PURE__ */ (0,
|
|
5851
|
-
/* @__PURE__ */ (0,
|
|
6175
|
+
note ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "dsh-mem-sinfo-note", children: note }) : null,
|
|
6176
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "dsh-mem-sinfo-sum", children: "待蒸馏 " + (gl.pendingTotal || 0) + " · 上次蒸馏 " + (ago || "尚未蒸馏") })
|
|
5852
6177
|
] });
|
|
5853
6178
|
}
|
|
5854
6179
|
|
|
5855
6180
|
// client/src/pill/SessionRecalledArea.tsx
|
|
5856
|
-
var
|
|
5857
|
-
var
|
|
6181
|
+
var import_react24 = require("react");
|
|
6182
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
5858
6183
|
var SHOW_CAP = 6;
|
|
5859
6184
|
var POLL_MS2 = 4e3;
|
|
5860
6185
|
var MATURITY_LABEL = { high: "成熟·高", mid: "成熟·中", low: "成熟·低" };
|
|
5861
6186
|
function SessionRecalledArea(props) {
|
|
5862
6187
|
const rpc = props.rpc;
|
|
5863
6188
|
const sessionId = props.sessionId;
|
|
5864
|
-
const [records, setRecords] = (0,
|
|
5865
|
-
(0,
|
|
6189
|
+
const [records, setRecords] = (0, import_react24.useState)(void 0);
|
|
6190
|
+
(0, import_react24.useEffect)(() => {
|
|
5866
6191
|
if (!rpc || !sessionId) return void 0;
|
|
5867
6192
|
let alive = true;
|
|
5868
6193
|
let timer = null;
|
|
@@ -5871,7 +6196,10 @@ var __defProp = Object.defineProperty;
|
|
|
5871
6196
|
const token = ++seq;
|
|
5872
6197
|
rpc("dsh-memory/session-recalled", { sessionId }).then((r) => {
|
|
5873
6198
|
if (!alive || token !== seq) return;
|
|
5874
|
-
if (r && r.ok && r.value)
|
|
6199
|
+
if (r && r.ok && r.value) {
|
|
6200
|
+
registerTypeCatalog(r.value.typeCatalog);
|
|
6201
|
+
setRecords(r.value.records);
|
|
6202
|
+
}
|
|
5875
6203
|
}).catch(() => {
|
|
5876
6204
|
}).then(() => {
|
|
5877
6205
|
if (alive) timer = setTimeout(tick, POLL_MS2);
|
|
@@ -5884,32 +6212,38 @@ var __defProp = Object.defineProperty;
|
|
|
5884
6212
|
};
|
|
5885
6213
|
}, [rpc, sessionId]);
|
|
5886
6214
|
if (records === void 0) return null;
|
|
5887
|
-
const
|
|
6215
|
+
const rows = records.filter((r) => r.superseded !== true || r.retired === true);
|
|
6216
|
+
const recentFirst = [...rows].reverse();
|
|
5888
6217
|
const shown = recentFirst.slice(0, SHOW_CAP);
|
|
5889
6218
|
const hidden = recentFirst.length - shown.length;
|
|
5890
|
-
|
|
5891
|
-
|
|
6219
|
+
const allSuperseded = rows.length === 0 && records.length > 0;
|
|
6220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "dsh-mem-sinfo", children: [
|
|
6221
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
5892
6222
|
"div",
|
|
5893
6223
|
{
|
|
5894
6224
|
style: { fontSize: 11, color: "var(--dsh-mem-text-3)", marginBottom: 6 },
|
|
5895
|
-
title: "
|
|
5896
|
-
children: "本会话召回 " +
|
|
6225
|
+
title: "本会话召回、且正文仍在上下文里的记忆(正文被摘要顶掉的已折叠不显示;清空会话才清除;不是常驻注入)",
|
|
6226
|
+
children: "本会话召回 " + rows.length + " 条"
|
|
5897
6227
|
}
|
|
5898
6228
|
),
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
6229
|
+
allSuperseded ? (
|
|
6230
|
+
// 不是“还没召回到”——那批确实注入过,只是正文已被摘要顶掉。说谎的空态比不显示更糟。
|
|
6231
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)", lineHeight: "16px" }, children: "本会话注入过的 " + records.length + " 条记忆正文已被摘要取代" })
|
|
6232
|
+
) : records.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)", lineHeight: "16px" }, children: "还没召回到记忆(聊几轮后按相关性自动浮现)" }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
6233
|
+
shown.map((r) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: rowStyle, title: rowTitle(r), children: [
|
|
6234
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
5902
6235
|
"span",
|
|
5903
6236
|
{
|
|
5904
|
-
className:
|
|
6237
|
+
className: tagClass(r.type),
|
|
5905
6238
|
style: { flexShrink: 0, whiteSpace: "nowrap" },
|
|
5906
|
-
children:
|
|
6239
|
+
children: typeLabel(r.type)
|
|
5907
6240
|
}
|
|
5908
6241
|
),
|
|
5909
|
-
/* @__PURE__ */ (0,
|
|
5910
|
-
r.
|
|
6242
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "dsh-mem-sinfo-val", style: r.retired === true ? STALE_TEXT_STYLE : textStyle, children: r.content }),
|
|
6243
|
+
r.retired === true ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 10, color: "var(--dsh-mem-text-3)", whiteSpace: "nowrap", flexShrink: 0 }, children: "已判过时" }) : null,
|
|
6244
|
+
r.maturity ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 10, color: "var(--dsh-mem-text-3)", whiteSpace: "nowrap", flexShrink: 0 }, children: MATURITY_LABEL[r.maturity] }) : null
|
|
5911
6245
|
] }, r.id)),
|
|
5912
|
-
hidden > 0 ? /* @__PURE__ */ (0,
|
|
6246
|
+
hidden > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: "+ " + hidden + " 条更早召回(详见面板「记忆」页)" }) : null
|
|
5913
6247
|
] })
|
|
5914
6248
|
] });
|
|
5915
6249
|
}
|
|
@@ -5929,14 +6263,15 @@ var __defProp = Object.defineProperty;
|
|
|
5929
6263
|
WebkitBoxOrient: "vertical",
|
|
5930
6264
|
overflow: "hidden"
|
|
5931
6265
|
};
|
|
6266
|
+
var STALE_TEXT_STYLE = { ...textStyle, textDecoration: "line-through" };
|
|
5932
6267
|
function rowTitle(r) {
|
|
5933
|
-
const head = "[" + (
|
|
6268
|
+
const head = "[" + typeLabel(r.type) + "] " + r.content;
|
|
5934
6269
|
const sc = r.usageScenario && r.usageScenario.length > 0 ? "\n使用场景:" + r.usageScenario.join(";") : "";
|
|
5935
6270
|
return head + sc;
|
|
5936
6271
|
}
|
|
5937
6272
|
|
|
5938
6273
|
// client/src/pill/WingWheel.tsx
|
|
5939
|
-
var
|
|
6274
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
5940
6275
|
var SIZE = 196;
|
|
5941
6276
|
var CENTER = SIZE / 2;
|
|
5942
6277
|
var R = 64;
|
|
@@ -5979,17 +6314,17 @@ var __defProp = Object.defineProperty;
|
|
|
5979
6314
|
function WingWheel(props) {
|
|
5980
6315
|
ensureThemeStyle();
|
|
5981
6316
|
const isOff = props.mode === "off";
|
|
5982
|
-
const [overview, setOverview] = (0,
|
|
5983
|
-
const [backfillBusy, setBackfillBusy] = (0,
|
|
5984
|
-
const [localError, setLocalError] = (0,
|
|
5985
|
-
const timersRef = (0,
|
|
5986
|
-
(0,
|
|
6317
|
+
const [overview, setOverview] = (0, import_react25.useState)(null);
|
|
6318
|
+
const [backfillBusy, setBackfillBusy] = (0, import_react25.useState)(false);
|
|
6319
|
+
const [localError, setLocalError] = (0, import_react25.useState)(null);
|
|
6320
|
+
const timersRef = (0, import_react25.useRef)([]);
|
|
6321
|
+
(0, import_react25.useEffect)(
|
|
5987
6322
|
() => () => {
|
|
5988
6323
|
for (const t of timersRef.current) window.clearTimeout(t);
|
|
5989
6324
|
},
|
|
5990
6325
|
[]
|
|
5991
6326
|
);
|
|
5992
|
-
(0,
|
|
6327
|
+
(0, import_react25.useEffect)(() => {
|
|
5993
6328
|
let alive = true;
|
|
5994
6329
|
props.rpc("dsh-memory/wing-overview", {}).then((r) => {
|
|
5995
6330
|
if (!alive) return;
|
|
@@ -6035,28 +6370,28 @@ var __defProp = Object.defineProperty;
|
|
|
6035
6370
|
finish();
|
|
6036
6371
|
});
|
|
6037
6372
|
};
|
|
6038
|
-
const boxRef = (0,
|
|
6039
|
-
const startRef = (0,
|
|
6040
|
-
const movedRef = (0,
|
|
6041
|
-
const downIndexRef = (0,
|
|
6042
|
-
const dragTargetRef = (0,
|
|
6043
|
-
const [drag, setDrag] = (0,
|
|
6373
|
+
const boxRef = (0, import_react25.useRef)(null);
|
|
6374
|
+
const startRef = (0, import_react25.useRef)(null);
|
|
6375
|
+
const movedRef = (0, import_react25.useRef)(false);
|
|
6376
|
+
const downIndexRef = (0, import_react25.useRef)(null);
|
|
6377
|
+
const dragTargetRef = (0, import_react25.useRef)(null);
|
|
6378
|
+
const [drag, setDrag] = (0, import_react25.useState)(null);
|
|
6044
6379
|
const lockedIndex = (() => {
|
|
6045
6380
|
if (props.halls.length !== 1 || !overview) return null;
|
|
6046
6381
|
const i = overview.corners.findIndex((c) => c.id === props.halls[0]);
|
|
6047
6382
|
return i >= 0 ? i : null;
|
|
6048
6383
|
})();
|
|
6049
6384
|
const activeCorner = drag ? drag.index : lockedIndex;
|
|
6050
|
-
const blockPosRef = (0,
|
|
6385
|
+
const blockPosRef = (0, import_react25.useRef)(
|
|
6051
6386
|
activeCorner != null ? cornerXY(activeCorner) : { x: CENTER, y: CENTER }
|
|
6052
6387
|
);
|
|
6053
|
-
const blockTargetRef = (0,
|
|
6054
|
-
const [blockPos, setBlockPos] = (0,
|
|
6055
|
-
(0,
|
|
6388
|
+
const blockTargetRef = (0, import_react25.useRef)(blockPosRef.current);
|
|
6389
|
+
const [blockPos, setBlockPos] = (0, import_react25.useState)(blockPosRef.current);
|
|
6390
|
+
(0, import_react25.useEffect)(() => {
|
|
6056
6391
|
blockTargetRef.current = activeCorner != null ? cornerXY(activeCorner) : { x: CENTER, y: CENTER };
|
|
6057
6392
|
}, [activeCorner]);
|
|
6058
|
-
const reducedMotionRef = (0,
|
|
6059
|
-
(0,
|
|
6393
|
+
const reducedMotionRef = (0, import_react25.useRef)(false);
|
|
6394
|
+
(0, import_react25.useEffect)(() => {
|
|
6060
6395
|
const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
6061
6396
|
const apply2 = () => {
|
|
6062
6397
|
reducedMotionRef.current = mq.matches;
|
|
@@ -6065,7 +6400,7 @@ var __defProp = Object.defineProperty;
|
|
|
6065
6400
|
mq.addEventListener("change", apply2);
|
|
6066
6401
|
return () => mq.removeEventListener("change", apply2);
|
|
6067
6402
|
}, []);
|
|
6068
|
-
(0,
|
|
6403
|
+
(0, import_react25.useEffect)(() => {
|
|
6069
6404
|
let raf = 0;
|
|
6070
6405
|
const loop = () => {
|
|
6071
6406
|
const cur = blockPosRef.current;
|
|
@@ -6154,8 +6489,8 @@ var __defProp = Object.defineProperty;
|
|
|
6154
6489
|
}).join(" ");
|
|
6155
6490
|
const grayStyle = isOff ? { opacity: 0.45, pointerEvents: "none" } : {};
|
|
6156
6491
|
const boundariesDisabled = props.halls.length === 0 || isOff;
|
|
6157
|
-
return /* @__PURE__ */ (0,
|
|
6158
|
-
/* @__PURE__ */ (0,
|
|
6492
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { style: { width: SIZE }, children: [
|
|
6493
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6159
6494
|
"div",
|
|
6160
6495
|
{
|
|
6161
6496
|
ref: boxRef,
|
|
@@ -6165,7 +6500,7 @@ var __defProp = Object.defineProperty;
|
|
|
6165
6500
|
onPointerUp: onBoxUp,
|
|
6166
6501
|
onPointerCancel: onBoxUp,
|
|
6167
6502
|
children: [
|
|
6168
|
-
/* @__PURE__ */ (0,
|
|
6503
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6169
6504
|
"svg",
|
|
6170
6505
|
{
|
|
6171
6506
|
width: SIZE,
|
|
@@ -6173,7 +6508,7 @@ var __defProp = Object.defineProperty;
|
|
|
6173
6508
|
style: { position: "absolute", inset: 0, pointerEvents: "none" },
|
|
6174
6509
|
"aria-hidden": "true",
|
|
6175
6510
|
children: [
|
|
6176
|
-
/* @__PURE__ */ (0,
|
|
6511
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6177
6512
|
"polygon",
|
|
6178
6513
|
{
|
|
6179
6514
|
points: polyPoints,
|
|
@@ -6184,7 +6519,7 @@ var __defProp = Object.defineProperty;
|
|
|
6184
6519
|
opacity: 0.45
|
|
6185
6520
|
}
|
|
6186
6521
|
),
|
|
6187
|
-
/* @__PURE__ */ (0,
|
|
6522
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6188
6523
|
"polygon",
|
|
6189
6524
|
{
|
|
6190
6525
|
points: polyPoints,
|
|
@@ -6195,7 +6530,7 @@ var __defProp = Object.defineProperty;
|
|
|
6195
6530
|
),
|
|
6196
6531
|
[0, 1, 2, 3, 4, 5, 6, 7].map((i) => {
|
|
6197
6532
|
const p = cornerPos(i);
|
|
6198
|
-
return /* @__PURE__ */ (0,
|
|
6533
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6199
6534
|
"line",
|
|
6200
6535
|
{
|
|
6201
6536
|
x1: CENTER,
|
|
@@ -6211,7 +6546,7 @@ var __defProp = Object.defineProperty;
|
|
|
6211
6546
|
]
|
|
6212
6547
|
}
|
|
6213
6548
|
),
|
|
6214
|
-
/* @__PURE__ */ (0,
|
|
6549
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6215
6550
|
"div",
|
|
6216
6551
|
{
|
|
6217
6552
|
"aria-hidden": "true",
|
|
@@ -6230,7 +6565,7 @@ var __defProp = Object.defineProperty;
|
|
|
6230
6565
|
}
|
|
6231
6566
|
}
|
|
6232
6567
|
),
|
|
6233
|
-
/* @__PURE__ */ (0,
|
|
6568
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6234
6569
|
"button",
|
|
6235
6570
|
{
|
|
6236
6571
|
type: "button",
|
|
@@ -6264,7 +6599,7 @@ var __defProp = Object.defineProperty;
|
|
|
6264
6599
|
const dim = activeCorner != null && !active;
|
|
6265
6600
|
const empty = count === 0;
|
|
6266
6601
|
const p = cornerPos(i);
|
|
6267
|
-
return /* @__PURE__ */ (0,
|
|
6602
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6268
6603
|
"div",
|
|
6269
6604
|
{
|
|
6270
6605
|
title: id ? `「${label}」${count ?? 0} 条
|
|
@@ -6293,8 +6628,8 @@ var __defProp = Object.defineProperty;
|
|
|
6293
6628
|
zIndex: 2
|
|
6294
6629
|
},
|
|
6295
6630
|
children: [
|
|
6296
|
-
/* @__PURE__ */ (0,
|
|
6297
|
-
/* @__PURE__ */ (0,
|
|
6631
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: label }),
|
|
6632
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 8, opacity: 0.75, fontVariantNumeric: "tabular-nums" }, children: count === null ? " " : empty ? "空角" : `${count} 条` })
|
|
6298
6633
|
]
|
|
6299
6634
|
},
|
|
6300
6635
|
id ?? i
|
|
@@ -6303,7 +6638,7 @@ var __defProp = Object.defineProperty;
|
|
|
6303
6638
|
]
|
|
6304
6639
|
}
|
|
6305
6640
|
),
|
|
6306
|
-
/* @__PURE__ */ (0,
|
|
6641
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6307
6642
|
"div",
|
|
6308
6643
|
{
|
|
6309
6644
|
title: props.halls.length === 0 ? "选定某个角(单 Wing)后,这两项才生效" : "锁定 Wing 时两类无角记忆是否参与召回",
|
|
@@ -6317,9 +6652,9 @@ var __defProp = Object.defineProperty;
|
|
|
6317
6652
|
pointerEvents: boundariesDisabled ? "none" : void 0
|
|
6318
6653
|
},
|
|
6319
6654
|
children: [
|
|
6320
|
-
/* @__PURE__ */ (0,
|
|
6321
|
-
/* @__PURE__ */ (0,
|
|
6322
|
-
/* @__PURE__ */ (0,
|
|
6655
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: overview ? `另有 ${overview.unlabeled} 条未打标` : "未打标" }),
|
|
6656
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
6657
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6323
6658
|
Segmented,
|
|
6324
6659
|
{
|
|
6325
6660
|
value: props.hallIncludeUnlabeled ? "in" : "ex",
|
|
@@ -6330,7 +6665,7 @@ var __defProp = Object.defineProperty;
|
|
|
6330
6665
|
onChange: (key) => props.onCommitWingBoundaries({ includeUnlabeled: key === "in" })
|
|
6331
6666
|
}
|
|
6332
6667
|
),
|
|
6333
|
-
/* @__PURE__ */ (0,
|
|
6668
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6334
6669
|
Segmented,
|
|
6335
6670
|
{
|
|
6336
6671
|
value: props.hallIncludeGeneral ? "in" : "ex",
|
|
@@ -6345,7 +6680,7 @@ var __defProp = Object.defineProperty;
|
|
|
6345
6680
|
]
|
|
6346
6681
|
}
|
|
6347
6682
|
),
|
|
6348
|
-
/* @__PURE__ */ (0,
|
|
6683
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Row, { label: "会话", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6349
6684
|
Segmented,
|
|
6350
6685
|
{
|
|
6351
6686
|
value: isOff ? "off" : "on",
|
|
@@ -6360,7 +6695,7 @@ var __defProp = Object.defineProperty;
|
|
|
6360
6695
|
onChange: (key) => props.onCommit(key === "off" ? "off" : "auto")
|
|
6361
6696
|
}
|
|
6362
6697
|
) }),
|
|
6363
|
-
props.recall !== void 0 && props.onCommitRecall ? /* @__PURE__ */ (0,
|
|
6698
|
+
props.recall !== void 0 && props.onCommitRecall ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Row, { label: "注入", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6364
6699
|
Segmented,
|
|
6365
6700
|
{
|
|
6366
6701
|
value: props.recall === null ? "follow" : props.recall ? "on" : "off",
|
|
@@ -6373,7 +6708,7 @@ var __defProp = Object.defineProperty;
|
|
|
6373
6708
|
onChange: (key) => props.onCommitRecall(key === "on" ? true : key === "off" ? false : null)
|
|
6374
6709
|
}
|
|
6375
6710
|
) }) : null,
|
|
6376
|
-
/* @__PURE__ */ (0,
|
|
6711
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6377
6712
|
"div",
|
|
6378
6713
|
{
|
|
6379
6714
|
style: {
|
|
@@ -6384,8 +6719,8 @@ var __defProp = Object.defineProperty;
|
|
|
6384
6719
|
marginTop: 10
|
|
6385
6720
|
},
|
|
6386
6721
|
children: [
|
|
6387
|
-
/* @__PURE__ */ (0,
|
|
6388
|
-
/* @__PURE__ */ (0,
|
|
6722
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: overview ? `未打标 ${overview.unlabeled} 条` : "未打标计数加载中" }),
|
|
6723
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6389
6724
|
ActionButton,
|
|
6390
6725
|
{
|
|
6391
6726
|
label: backfillBusy ? "回填中…" : "回填",
|
|
@@ -6397,13 +6732,13 @@ var __defProp = Object.defineProperty;
|
|
|
6397
6732
|
]
|
|
6398
6733
|
}
|
|
6399
6734
|
),
|
|
6400
|
-
props.error || localError ? /* @__PURE__ */ (0,
|
|
6401
|
-
/* @__PURE__ */ (0,
|
|
6402
|
-
/* @__PURE__ */ (0,
|
|
6735
|
+
props.error || localError ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-danger)", marginTop: 8 }, children: props.error || localError }) : null,
|
|
6736
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SessionRecalledArea, { rpc: props.rpc, sessionId: props.sessionId }),
|
|
6737
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SessionInfoArea, { rpc: props.rpc, sessionId: props.sessionId })
|
|
6403
6738
|
] });
|
|
6404
6739
|
}
|
|
6405
6740
|
function Row(props) {
|
|
6406
|
-
return /* @__PURE__ */ (0,
|
|
6741
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6407
6742
|
"div",
|
|
6408
6743
|
{
|
|
6409
6744
|
style: {
|
|
@@ -6413,7 +6748,7 @@ var __defProp = Object.defineProperty;
|
|
|
6413
6748
|
marginTop: 10
|
|
6414
6749
|
},
|
|
6415
6750
|
children: [
|
|
6416
|
-
/* @__PURE__ */ (0,
|
|
6751
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)" }, children: props.label }),
|
|
6417
6752
|
props.children
|
|
6418
6753
|
]
|
|
6419
6754
|
}
|
|
@@ -6421,9 +6756,9 @@ var __defProp = Object.defineProperty;
|
|
|
6421
6756
|
}
|
|
6422
6757
|
var LABEL_FALLBACK = ["工作", "人际", "学习", "创作娱乐", "居家", "健康", "财务", "出行"];
|
|
6423
6758
|
function useViewportClamp(popRef) {
|
|
6424
|
-
const shiftRef = (0,
|
|
6425
|
-
const [shiftX, setShiftX] = (0,
|
|
6426
|
-
(0,
|
|
6759
|
+
const shiftRef = (0, import_react25.useRef)(0);
|
|
6760
|
+
const [shiftX, setShiftX] = (0, import_react25.useState)(0);
|
|
6761
|
+
(0, import_react25.useEffect)(() => {
|
|
6427
6762
|
const clamp = () => {
|
|
6428
6763
|
const el = popRef.current;
|
|
6429
6764
|
if (!el) return;
|
|
@@ -6453,24 +6788,24 @@ var __defProp = Object.defineProperty;
|
|
|
6453
6788
|
}
|
|
6454
6789
|
|
|
6455
6790
|
// client/src/pill/MemoryModePill.tsx
|
|
6456
|
-
var
|
|
6791
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
6457
6792
|
function MemoryModePill(props) {
|
|
6458
6793
|
const rpc = props.rpc;
|
|
6459
6794
|
const sessionId = props.sessionId || props.session && props.session.sessionId;
|
|
6460
|
-
const [mode, setMode] = (0,
|
|
6461
|
-
const [recall, setRecall] = (0,
|
|
6462
|
-
const [recallResolved, setRecallResolved] = (0,
|
|
6463
|
-
const [halls, setWings] = (0,
|
|
6464
|
-
const [hallIncludeUnlabeled, setWingIncludeUnlabeled] = (0,
|
|
6465
|
-
const [hallIncludeGeneral, setWingIncludeGeneral] = (0,
|
|
6466
|
-
const [wingLabels, setHallLabels] = (0,
|
|
6467
|
-
const [error, setError] = (0,
|
|
6468
|
-
const [open, setOpen] = (0,
|
|
6469
|
-
const wrapRef = (0,
|
|
6470
|
-
const popRef = (0,
|
|
6795
|
+
const [mode, setMode] = (0, import_react26.useState)(null);
|
|
6796
|
+
const [recall, setRecall] = (0, import_react26.useState)(null);
|
|
6797
|
+
const [recallResolved, setRecallResolved] = (0, import_react26.useState)(true);
|
|
6798
|
+
const [halls, setWings] = (0, import_react26.useState)([]);
|
|
6799
|
+
const [hallIncludeUnlabeled, setWingIncludeUnlabeled] = (0, import_react26.useState)(true);
|
|
6800
|
+
const [hallIncludeGeneral, setWingIncludeGeneral] = (0, import_react26.useState)(false);
|
|
6801
|
+
const [wingLabels, setHallLabels] = (0, import_react26.useState)({});
|
|
6802
|
+
const [error, setError] = (0, import_react26.useState)(null);
|
|
6803
|
+
const [open, setOpen] = (0, import_react26.useState)(false);
|
|
6804
|
+
const wrapRef = (0, import_react26.useRef)(null);
|
|
6805
|
+
const popRef = (0, import_react26.useRef)(null);
|
|
6471
6806
|
const shiftX = useViewportClamp(popRef);
|
|
6472
|
-
const seqRef = (0,
|
|
6473
|
-
const load = (0,
|
|
6807
|
+
const seqRef = (0, import_react26.useRef)(0);
|
|
6808
|
+
const load = (0, import_react26.useCallback)(() => {
|
|
6474
6809
|
if (!sessionId || !rpc) return;
|
|
6475
6810
|
const token = ++seqRef.current;
|
|
6476
6811
|
setError(null);
|
|
@@ -6495,13 +6830,13 @@ var __defProp = Object.defineProperty;
|
|
|
6495
6830
|
}).catch(() => {
|
|
6496
6831
|
});
|
|
6497
6832
|
}, [sessionId, rpc]);
|
|
6498
|
-
(0,
|
|
6833
|
+
(0, import_react26.useEffect)(() => {
|
|
6499
6834
|
load();
|
|
6500
6835
|
}, [load]);
|
|
6501
|
-
(0,
|
|
6836
|
+
(0, import_react26.useEffect)(() => {
|
|
6502
6837
|
watchSidebarIcon();
|
|
6503
6838
|
}, []);
|
|
6504
|
-
(0,
|
|
6839
|
+
(0, import_react26.useEffect)(() => {
|
|
6505
6840
|
initOccupancyIndicator(
|
|
6506
6841
|
(endpoint, payload) => rpc(endpoint, payload)
|
|
6507
6842
|
);
|
|
@@ -6509,7 +6844,7 @@ var __defProp = Object.defineProperty;
|
|
|
6509
6844
|
watchContextMeter();
|
|
6510
6845
|
noteOccupancySession(sessionId ?? null);
|
|
6511
6846
|
}, [sessionId, rpc]);
|
|
6512
|
-
(0,
|
|
6847
|
+
(0, import_react26.useEffect)(() => {
|
|
6513
6848
|
if (!open) return;
|
|
6514
6849
|
const onDown = (e) => {
|
|
6515
6850
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -6649,8 +6984,8 @@ var __defProp = Object.defineProperty;
|
|
|
6649
6984
|
pillStyle.boxShadow = "0 0 12px color-mix(in srgb, " + info.color + " 30%, transparent)";
|
|
6650
6985
|
pillStyle["--dsh-mem-pill-tint"] = info.color;
|
|
6651
6986
|
}
|
|
6652
|
-
return /* @__PURE__ */ (0,
|
|
6653
|
-
/* @__PURE__ */ (0,
|
|
6987
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { ref: wrapRef, style: { position: "relative", display: "inline-flex" }, children: [
|
|
6988
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
6654
6989
|
"button",
|
|
6655
6990
|
{
|
|
6656
6991
|
type: "button",
|
|
@@ -6663,11 +6998,11 @@ var __defProp = Object.defineProperty;
|
|
|
6663
6998
|
style: pillStyle,
|
|
6664
6999
|
children: [
|
|
6665
7000
|
"记忆 · ",
|
|
6666
|
-
/* @__PURE__ */ (0,
|
|
7001
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: faceLabel })
|
|
6667
7002
|
]
|
|
6668
7003
|
}
|
|
6669
7004
|
),
|
|
6670
|
-
open ? /* @__PURE__ */ (0,
|
|
7005
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6671
7006
|
"div",
|
|
6672
7007
|
{
|
|
6673
7008
|
ref: popRef,
|
|
@@ -6678,12 +7013,12 @@ var __defProp = Object.defineProperty;
|
|
|
6678
7013
|
transform: "translateX(calc(-50% + " + shiftX + "px))",
|
|
6679
7014
|
zIndex: 1e3
|
|
6680
7015
|
},
|
|
6681
|
-
children: /* @__PURE__ */ (0,
|
|
7016
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6682
7017
|
"div",
|
|
6683
7018
|
{
|
|
6684
7019
|
className: "dsh-mem-popover",
|
|
6685
7020
|
style: { position: "relative", padding: "10px 12px" },
|
|
6686
|
-
children: /* @__PURE__ */ (0,
|
|
7021
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6687
7022
|
WingWheel,
|
|
6688
7023
|
{
|
|
6689
7024
|
mode: mode || "auto",
|