dsh-prime-memory 0.22.2 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.en.md +421 -0
- package/CHANGELOG.ja.md +416 -0
- package/CHANGELOG.ko.md +416 -0
- package/CHANGELOG.md +120 -0
- package/dist/client.js +1266 -845
- package/dist/config.d.ts +131 -1341
- package/dist/config.js +89 -4
- package/dist/conflict-service.d.ts +7 -1
- package/dist/conflict-service.js +7 -1
- package/dist/contract.d.ts +211 -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 +52 -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 +46 -1
- package/dist/pipeline/ruminate.js +109 -0
- package/dist/pipeline/runner.d.ts +10 -0
- package/dist/pipeline/runner.js +13 -2
- 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 +16 -1
- package/dist/stats.d.ts +12 -0
- package/dist/stats.js +352 -17
- 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 +94 -3
- package/dist/store/l1.js +169 -4
- 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 +74 -0
- package/dist/store/memory-md-disable.js +302 -0
- package/dist/store/memory-md-export.d.ts +50 -0
- package/dist/store/memory-md-export.js +227 -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-run.d.ts +48 -0
- package/dist/store/memory-md-run.js +151 -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-sync.d.ts +59 -0
- package/dist/store/memory-md-sync.js +152 -0
- package/dist/store/memory-md-types.d.ts +243 -0
- package/dist/store/memory-md-types.js +10 -0
- package/dist/store/memory-md.d.ts +117 -0
- package/dist/store/memory-md.js +230 -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 +26 -7
- package/dist/tools/slots.d.ts +2 -1
- package/dist/tools/slots.js +2 -1
- 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,281 @@ 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 s = rep.suffix;
|
|
1679
|
+
const suffix = s && s.renamed + s.revived + s.both + s.edited > 0 ? ` · 后缀对齐 改名 ${s.renamed}${s.edited > 0 ? `(人改过 ${s.edited})` : ""} 改回 ${s.revived}${s.both > 0 ? ` · 冲突 ${s.both}` : ""}` : "";
|
|
1680
|
+
const suffixMore = s && s.capped && s.remaining > 0 ? ` · 后缀还有 ${s.remaining} 个文件待对齐,再点一次继续` : "";
|
|
1681
|
+
const tail = rep.remaining > 0 ? ` · 剩余 ${rep.remaining} 个文件,再点一次继续` : "";
|
|
1682
|
+
const budget = typeof rep.appliedMaxRecords === "number" && rep.appliedMaxRecords > 0 ? ` · 本次预算 ${rep.appliedMaxRecords} 个文件` : "";
|
|
1683
|
+
const passes = typeof rep.passes === "number" && rep.passes > 1 ? ` · 共滚 ${rep.passes} 轮` : "";
|
|
1684
|
+
return head + named + nameBad + suffix + suffixMore + budget + passes + tail;
|
|
1685
|
+
}
|
|
1686
|
+
function lineOfReconcile(rep) {
|
|
1687
|
+
const parts = [
|
|
1688
|
+
`首次 ${rep.firstTime}`,
|
|
1689
|
+
`一致 ${rep.same}`,
|
|
1690
|
+
`仅库变 ${rep.dbOnly}`,
|
|
1691
|
+
`仅文件变 ${rep.fileOnly}`,
|
|
1692
|
+
`两边都变 ${rep.both}`,
|
|
1693
|
+
`文件缺失 ${rep.missingFile}`
|
|
1694
|
+
];
|
|
1695
|
+
return parts.join(" · ") + (rep.capped ? `(本次只扫了 ${rep.scanned} 条,未扫全)` : "");
|
|
1696
|
+
}
|
|
1697
|
+
function lineOfSync(rep) {
|
|
1698
|
+
const head = `回灌 ${rep.imported} · 重写文件 ${rep.rendered} · 退场 ${rep.retired} · 一致 ${rep.same}`;
|
|
1699
|
+
const tail = rep.pending > 0 ? ` · 两边都变 ${rep.pending} 条已挂账(两侧都没动)` : "";
|
|
1700
|
+
const extra = rep.newFiles > 0 ? ` · 新文件 ${rep.newFiles} 个未入库(导入须走写入内核)` : "";
|
|
1701
|
+
const links = rep.skippedLinks > 0 ? ` · 防护拦下 ${rep.skippedLinks} 个链接/越界条目(未读)` : "";
|
|
1702
|
+
const stale = rep.staleRootFiles > 0 ? ` · 陈旧根 ${rep.staleRootFiles} 个文件未参与同步(交给孤儿归档)` : "";
|
|
1703
|
+
const multi = rep.multiPath > 0 ? ` · 同记录多路径 ${rep.multiPath} 份未动(先跑孤儿归档再同步)` : "";
|
|
1704
|
+
const hashBad = rep.hashMismatch > 0 ? ` · 自校验不符 ${rep.hashMismatch} 个(文件被外部改动,已按文件侧处理)` : "";
|
|
1705
|
+
const unsigned = rep.unsigned > 0 ? ` · 未签名 ${rep.unsigned} 个(老投射文件无 hash,下轮导出补盖)` : "";
|
|
1706
|
+
return head + tail + extra + links + stale + multi + hashBad + unsigned + (rep.remaining > 0 ? ` · 剩余 ${rep.remaining} 个文件,再点一次继续` : "");
|
|
1707
|
+
}
|
|
1708
|
+
function lineOfOrphans(rep) {
|
|
1709
|
+
const head = rep.dryRun ? `账本共 ${rep.scanned} 条 · 仍被认领 ${rep.claimed} · 无人认领 ${rep.orphans}(未搬任何东西)` : `已搬 ${rep.moved} · 失败 ${rep.failed} · 仍被认领 ${rep.claimed}`;
|
|
1710
|
+
const tail = rep.remaining > 0 ? ` · 剩余 ${rep.remaining} 条,再点一次继续` : "";
|
|
1711
|
+
return head + tail + (rep.dir.length > 0 ? ` · 归档到 ${rep.dir}` : "");
|
|
1712
|
+
}
|
|
1713
|
+
function lineOfCleanup(rep) {
|
|
1714
|
+
if (rep.aborted) return `清理已中止(未删任何记录):${rep.diffs.join(";") || "门禁未通过"}`;
|
|
1715
|
+
if (rep.dryRun) return `待删 ${rep.targets} 条(预览了前 ${rep.items?.length ?? 0} 条)——未删除任何东西`;
|
|
1716
|
+
const f = rep.files ?? { moved: 0, failed: 0, absent: 0 };
|
|
1717
|
+
const head = `已删 ${rep.purged} 条 · 归档正文 ${rep.archiveMd === void 0 || rep.archiveMd === "" ? "未写" : "已写"} · 文件搬家 ${f.moved}(失败 ${f.failed}) · 图索引 ${rep.graphForgotten ?? 0}`;
|
|
1718
|
+
return rep.otherChanged && rep.otherChanged > 0 ? `${head} · 本批之外 ${rep.otherChanged} 条处于漂移(不影响本批)` : head;
|
|
1719
|
+
}
|
|
1720
|
+
function ArchiveSection(props) {
|
|
1721
|
+
const rpc = props.rpc;
|
|
1722
|
+
const [busy, setBusy] = (0, import_react7.useState)(false);
|
|
1723
|
+
const [exported, setExported] = (0, import_react7.useState)(void 0);
|
|
1724
|
+
const [recon, setRecon] = (0, import_react7.useState)(void 0);
|
|
1725
|
+
const [synced, setSynced] = (0, import_react7.useState)(void 0);
|
|
1726
|
+
const [orphans, setOrphans] = (0, import_react7.useState)(void 0);
|
|
1727
|
+
const [cleanup, setCleanup] = (0, import_react7.useState)(void 0);
|
|
1728
|
+
const [orphanArmed, setOrphanArmed] = (0, import_react7.useState)(false);
|
|
1729
|
+
const [armed, setArmed] = (0, import_react7.useState)(false);
|
|
1730
|
+
const [error, setError] = (0, import_react7.useState)(void 0);
|
|
1731
|
+
const [budgetDraft, setBudgetDraft] = (0, import_react7.useState)("");
|
|
1732
|
+
const [budgetNote, setBudgetNote] = (0, import_react7.useState)("");
|
|
1733
|
+
const [prog, setProg] = (0, import_react7.useState)(void 0);
|
|
1734
|
+
const pullProgress = () => {
|
|
1735
|
+
void rpc("dsh-memory/mem-run-status", {}).then((r) => {
|
|
1736
|
+
const v = r && r.ok ? r.value : void 0;
|
|
1737
|
+
if (v !== void 0) setProg(v);
|
|
1738
|
+
}).catch(() => {
|
|
1739
|
+
});
|
|
1740
|
+
};
|
|
1741
|
+
const runExport = () => {
|
|
1742
|
+
if (busy) return;
|
|
1743
|
+
setBusy(true);
|
|
1744
|
+
setError(void 0);
|
|
1745
|
+
const timer = setInterval(pullProgress, 500);
|
|
1746
|
+
pullProgress();
|
|
1747
|
+
void call(rpc, "dsh-memory/mem-export", {}).then((out) => {
|
|
1748
|
+
clearInterval(timer);
|
|
1749
|
+
setBusy(false);
|
|
1750
|
+
if (out.report !== void 0) {
|
|
1751
|
+
setExported(out.report);
|
|
1752
|
+
pullProgress();
|
|
1753
|
+
}
|
|
1754
|
+
if (out.error !== void 0) setError(out.error);
|
|
1755
|
+
});
|
|
1756
|
+
};
|
|
1757
|
+
(0, import_react7.useEffect)(() => {
|
|
1758
|
+
void rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
1759
|
+
const v = r && r.ok ? r.value : void 0;
|
|
1760
|
+
const n = v?.settings?.mdExportMaxRecords;
|
|
1761
|
+
if (typeof n === "number") setBudgetDraft(String(n));
|
|
1762
|
+
}).catch(() => {
|
|
1763
|
+
});
|
|
1764
|
+
}, [rpc]);
|
|
1765
|
+
const commitBudget = () => {
|
|
1766
|
+
const raw = budgetDraft.trim();
|
|
1767
|
+
if (raw === "") return;
|
|
1768
|
+
const n = Math.floor(Number(raw));
|
|
1769
|
+
if (!Number.isFinite(n) || n < 0 || n > 1e4) {
|
|
1770
|
+
setBudgetNote("预算要 0~10000 的整数(0 = 跟随部署默认)");
|
|
1771
|
+
return;
|
|
1772
|
+
}
|
|
1773
|
+
void rpc("dsh-memory/settings-set", { mdExportMaxRecords: n }).then((r) => {
|
|
1774
|
+
setBudgetNote(r && r.ok ? n === 0 ? "已改为跟随部署默认" : `已设为每次最多 ${n} 个文件,下一次点击生效` : "写入失败:预算未改");
|
|
1775
|
+
}).catch(() => {
|
|
1776
|
+
setBudgetNote("写入失败:预算未改");
|
|
1777
|
+
});
|
|
1778
|
+
};
|
|
1779
|
+
const run = (method, sink, payload) => {
|
|
1780
|
+
if (busy) return;
|
|
1781
|
+
setBusy(true);
|
|
1782
|
+
setError(void 0);
|
|
1783
|
+
void call(rpc, method, payload).then((out) => {
|
|
1784
|
+
if (out.report !== void 0) sink(out.report);
|
|
1785
|
+
if (out.error !== void 0) setError(out.error);
|
|
1786
|
+
setBusy(false);
|
|
1787
|
+
});
|
|
1788
|
+
};
|
|
1789
|
+
const root = exported?.root ?? recon?.root;
|
|
1790
|
+
const pct = prog !== void 0 && prog.total > 0 ? Math.min(100, Math.round(prog.done / (prog.total * 2) * 100)) : 0;
|
|
1791
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { marginTop: 12, paddingTop: 10, borderTop: "1px solid var(--dsh-mem-border)" }, children: [
|
|
1792
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontSize: 12, fontWeight: 600, color: "var(--dsh-mem-text-2)", marginBottom: 6 }, children: "外部存档(markdown 投射)" }),
|
|
1793
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: S.flexRow, children: [
|
|
1794
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1795
|
+
NButton,
|
|
1796
|
+
{
|
|
1797
|
+
disabled: busy,
|
|
1798
|
+
title: "把当前全部记忆渲染为 <根>/<类型>/<名称>.memory.md,并记下内容指纹(只写文件,不改库)。一次点完:一轮预算不够时服务端自己续跑下几轮,进度看下方进度条",
|
|
1799
|
+
onClick: runExport,
|
|
1800
|
+
children: "导出为可携存档"
|
|
1801
|
+
}
|
|
1802
|
+
),
|
|
1803
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1804
|
+
NButton,
|
|
1805
|
+
{
|
|
1806
|
+
disabled: busy,
|
|
1807
|
+
title: "按账本基线比对库与磁盘,只出报告:什么都不写,因此不需要高权限",
|
|
1808
|
+
onClick: () => {
|
|
1809
|
+
run("dsh-memory/mem-reconcile", setRecon, {});
|
|
1810
|
+
},
|
|
1811
|
+
children: "与存档对账"
|
|
1812
|
+
}
|
|
1813
|
+
),
|
|
1814
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1815
|
+
NButton,
|
|
1816
|
+
{
|
|
1817
|
+
disabled: busy,
|
|
1818
|
+
title: "文件 → 库:只有文件变过的回灌入库,`.disable` 后缀的退场;两边都变的那些两侧都不动,只挂账。会写库,因此需要高权限模式",
|
|
1819
|
+
onClick: () => {
|
|
1820
|
+
run("dsh-memory/mem-sync", setSynced, {});
|
|
1821
|
+
},
|
|
1822
|
+
children: "从存档同步回库"
|
|
1823
|
+
}
|
|
1824
|
+
),
|
|
1825
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1826
|
+
NButton,
|
|
1827
|
+
{
|
|
1828
|
+
disabled: busy,
|
|
1829
|
+
title: "只读预览:扫账本,找出“我们写过但现在没记录认领它”的投射文件(改名/消歧留下的残片)。来路不明的文件一律不动,也不搬任何东西",
|
|
1830
|
+
onClick: () => {
|
|
1831
|
+
setOrphanArmed(false);
|
|
1832
|
+
run("dsh-memory/mem-orphans", setOrphans, { dryRun: true });
|
|
1833
|
+
},
|
|
1834
|
+
children: "孤儿文件预览"
|
|
1835
|
+
}
|
|
1836
|
+
),
|
|
1837
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1838
|
+
NButton,
|
|
1839
|
+
{
|
|
1840
|
+
disabled: busy || orphans === void 0 || !orphans.dryRun || orphans.orphans === 0,
|
|
1841
|
+
title: orphanArmed ? "再点一次就真的搬——文件会被移出投射目录(不删,进归档目录,可手动搬回)" : "不删只搬:进 <数据目录>/memories-orphans/<批次时间戳>/;需要先跑预览,再点两次确认;服务端还要高权限模式",
|
|
1842
|
+
onClick: () => {
|
|
1843
|
+
if (!orphanArmed) {
|
|
1844
|
+
setOrphanArmed(true);
|
|
1845
|
+
return;
|
|
1846
|
+
}
|
|
1847
|
+
setOrphanArmed(false);
|
|
1848
|
+
run("dsh-memory/mem-orphans", setOrphans, { dryRun: false });
|
|
1849
|
+
},
|
|
1850
|
+
children: orphanArmed ? "确认搬走孤儿文件" : "孤儿文件归档"
|
|
1851
|
+
}
|
|
1852
|
+
),
|
|
1853
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1854
|
+
NButton,
|
|
1855
|
+
{
|
|
1856
|
+
disabled: busy,
|
|
1857
|
+
title: "只读预览:列出将被物理删除的退场记忆(前 50 条)与总数,不删任何东西",
|
|
1858
|
+
onClick: () => {
|
|
1859
|
+
setArmed(false);
|
|
1860
|
+
run("dsh-memory/cleanup-retired", setCleanup, { dryRun: true });
|
|
1861
|
+
},
|
|
1862
|
+
children: "清理预览(干跑)"
|
|
1863
|
+
}
|
|
1864
|
+
),
|
|
1865
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1866
|
+
NButton,
|
|
1867
|
+
{
|
|
1868
|
+
disabled: busy || cleanup === void 0 || !cleanup.dryRun || cleanup.targets === 0,
|
|
1869
|
+
title: armed ? "再点一次就真的删——物理删除不可逆(但会先落快照与归档正文)" : "不可逆动作:需要先跑预览,再点两次确认;服务端那边还要高权限模式",
|
|
1870
|
+
onClick: () => {
|
|
1871
|
+
if (!armed) {
|
|
1872
|
+
setArmed(true);
|
|
1873
|
+
return;
|
|
1874
|
+
}
|
|
1875
|
+
setArmed(false);
|
|
1876
|
+
run("dsh-memory/cleanup-retired", setCleanup, { dryRun: false });
|
|
1877
|
+
},
|
|
1878
|
+
children: armed ? "确认物理删除" : "清理并归档"
|
|
1879
|
+
}
|
|
1880
|
+
)
|
|
1881
|
+
] }),
|
|
1882
|
+
prog !== void 0 && prog.total > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { marginTop: 8 }, children: [
|
|
1883
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-mem-rb-bar", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-mem-rb-fill", style: { width: pct + "%" } }) }),
|
|
1884
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { ...HINT_STYLE, marginTop: 3 }, children: [
|
|
1885
|
+
prog.detail,
|
|
1886
|
+
prog.notice !== void 0 && prog.notice !== "" ? ` · ${prog.notice}` : ""
|
|
1887
|
+
] })
|
|
1888
|
+
] }) : null,
|
|
1889
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { ...S.flexRow, marginTop: 8, alignItems: "center" }, children: [
|
|
1890
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)" }, children: "单次文件更新预算" }),
|
|
1891
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1892
|
+
NInput,
|
|
1893
|
+
{
|
|
1894
|
+
type: "number",
|
|
1895
|
+
min: 0,
|
|
1896
|
+
max: 1e4,
|
|
1897
|
+
style: { width: 96 },
|
|
1898
|
+
title: "一次点击最多更新多少个投射文件(导出写入 + 后缀改名都占额度)。“没变过”的不占额度。0 = 跟随部署默认(2000);上限 10000。",
|
|
1899
|
+
placeholder: "0",
|
|
1900
|
+
value: budgetDraft,
|
|
1901
|
+
onChange: (e) => {
|
|
1902
|
+
setBudgetDraft(e.target.value);
|
|
1903
|
+
setBudgetNote("");
|
|
1904
|
+
},
|
|
1905
|
+
onBlur: () => {
|
|
1906
|
+
commitBudget();
|
|
1907
|
+
},
|
|
1908
|
+
onKeyDown: (e) => {
|
|
1909
|
+
if (e.key === "Enter") commitBudget();
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
),
|
|
1913
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)" }, children: "个文件/次(0 = 默认 2000)" }),
|
|
1914
|
+
budgetNote !== "" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)" }, children: budgetNote }) : null
|
|
1915
|
+
] }),
|
|
1916
|
+
/* @__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) : "导出=库→文件;对账=只读比较;同步=文件→库;孤儿=搬走没人认领的残片;清理=物理删除(不可逆,需高权限模式)。" }),
|
|
1917
|
+
recon !== void 0 && error === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: HINT_STYLE, children: [
|
|
1918
|
+
"最近差异样本:",
|
|
1919
|
+
recon.samples.map((s) => `${s.state}:${s.relPath}`).join(",") || "(无)"
|
|
1920
|
+
] }) : null,
|
|
1921
|
+
root !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: ROOT_STYLE, children: [
|
|
1922
|
+
"投射根:",
|
|
1923
|
+
root
|
|
1924
|
+
] }) : null
|
|
1925
|
+
] });
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1536
1928
|
// client/src/tabs/DistillSettings.tsx
|
|
1537
|
-
var
|
|
1929
|
+
var import_react12 = require("react");
|
|
1538
1930
|
|
|
1539
1931
|
// client/src/tabs/BudgetInputs.tsx
|
|
1540
|
-
var
|
|
1541
|
-
var
|
|
1932
|
+
var import_react8 = require("react");
|
|
1933
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1542
1934
|
var LAYERS = [
|
|
1543
1935
|
["extract", "抽取"],
|
|
1544
1936
|
["dedup", "去重"],
|
|
@@ -1559,7 +1951,7 @@ var __defProp = Object.defineProperty;
|
|
|
1559
1951
|
const onError = props.onError;
|
|
1560
1952
|
const scope = props.scope ?? "all";
|
|
1561
1953
|
const layers = scope === "all" || scope === "input" ? LAYERS : LAYERS.filter((l) => SCOPE_KEYS[scope].includes(l[0]));
|
|
1562
|
-
const [draft, setDraft] = (0,
|
|
1954
|
+
const [draft, setDraft] = (0, import_react8.useState)(null);
|
|
1563
1955
|
if (!data || !data.budgets) return null;
|
|
1564
1956
|
const cur = data.budgets.current || {};
|
|
1565
1957
|
const def = data.budgets.defaults || {};
|
|
@@ -1655,7 +2047,7 @@ var __defProp = Object.defineProperty;
|
|
|
1655
2047
|
return false;
|
|
1656
2048
|
};
|
|
1657
2049
|
const inputBox = (key, _label, title, width, placeholder, onCommit) => {
|
|
1658
|
-
return /* @__PURE__ */ (0,
|
|
2050
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1659
2051
|
NInput,
|
|
1660
2052
|
{
|
|
1661
2053
|
type: "number",
|
|
@@ -1687,9 +2079,9 @@ var __defProp = Object.defineProperty;
|
|
|
1687
2079
|
const effNote = layers.map((l) => eff[l[0]] || "?").join(" / ");
|
|
1688
2080
|
const rowLabel = (key) => key === "extract" ? "抽取输出" : key === "dedup" ? "去重输出" : key === "l2" ? "L2 输出" : "L3 输出";
|
|
1689
2081
|
const rowStyle2 = { display: "flex", alignItems: "center", gap: 8 };
|
|
1690
|
-
return /* @__PURE__ */ (0,
|
|
1691
|
-
showOutputs ? /* @__PURE__ */ (0,
|
|
1692
|
-
/* @__PURE__ */ (0,
|
|
2082
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
|
|
2083
|
+
showOutputs ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginTop: 12 }, children: [
|
|
2084
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1693
2085
|
"div",
|
|
1694
2086
|
{
|
|
1695
2087
|
style: S.switchLabel,
|
|
@@ -1697,8 +2089,8 @@ var __defProp = Object.defineProperty;
|
|
|
1697
2089
|
children: "输出预算"
|
|
1698
2090
|
}
|
|
1699
2091
|
),
|
|
1700
|
-
/* @__PURE__ */ (0,
|
|
1701
|
-
/* @__PURE__ */ (0,
|
|
2092
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 4 }, children: layers.map((l) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: rowStyle2, children: [
|
|
2093
|
+
/* @__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
2094
|
inputBox(
|
|
1703
2095
|
l[0],
|
|
1704
2096
|
l[1],
|
|
@@ -1707,11 +2099,11 @@ var __defProp = Object.defineProperty;
|
|
|
1707
2099
|
def[l[0]],
|
|
1708
2100
|
commitOutputs
|
|
1709
2101
|
),
|
|
1710
|
-
/* @__PURE__ */ (0,
|
|
2102
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: "token" })
|
|
1711
2103
|
] }, l[0])) })
|
|
1712
2104
|
] }) : null,
|
|
1713
|
-
showInput ? /* @__PURE__ */ (0,
|
|
1714
|
-
/* @__PURE__ */ (0,
|
|
2105
|
+
showInput ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginTop: 12 }, children: [
|
|
2106
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1715
2107
|
"div",
|
|
1716
2108
|
{
|
|
1717
2109
|
style: S.switchLabel,
|
|
@@ -1719,8 +2111,8 @@ var __defProp = Object.defineProperty;
|
|
|
1719
2111
|
children: "输入预算"
|
|
1720
2112
|
}
|
|
1721
2113
|
),
|
|
1722
|
-
/* @__PURE__ */ (0,
|
|
1723
|
-
/* @__PURE__ */ (0,
|
|
2114
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: rowStyle2, children: [
|
|
2115
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { width: 68, flexShrink: 0, fontSize: 12, color: "var(--dsh-mem-text-2)" }, children: "单次输入" }),
|
|
1724
2116
|
inputBox(
|
|
1725
2117
|
"input",
|
|
1726
2118
|
"输入",
|
|
@@ -1729,15 +2121,15 @@ var __defProp = Object.defineProperty;
|
|
|
1729
2121
|
ib.fallback,
|
|
1730
2122
|
commitInput
|
|
1731
2123
|
),
|
|
1732
|
-
/* @__PURE__ */ (0,
|
|
2124
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: "字符" })
|
|
1733
2125
|
] }) })
|
|
1734
2126
|
] }) : null
|
|
1735
2127
|
] });
|
|
1736
2128
|
}
|
|
1737
2129
|
|
|
1738
2130
|
// client/src/tabs/ChannelEditor.tsx
|
|
1739
|
-
var
|
|
1740
|
-
var
|
|
2131
|
+
var import_react9 = require("react");
|
|
2132
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1741
2133
|
var STY = {
|
|
1742
2134
|
block: { marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--dsh-mem-border)" },
|
|
1743
2135
|
head: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", marginBottom: 6 },
|
|
@@ -1768,14 +2160,14 @@ var __defProp = Object.defineProperty;
|
|
|
1768
2160
|
];
|
|
1769
2161
|
function ChannelEditor(props) {
|
|
1770
2162
|
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,
|
|
2163
|
+
const [baseText, setBaseText] = (0, import_react9.useState)(channel.runtimeBaseURL);
|
|
2164
|
+
const [keyText, setKeyText] = (0, import_react9.useState)("");
|
|
2165
|
+
const baseTimer = (0, import_react9.useRef)(void 0);
|
|
2166
|
+
const dirty = (0, import_react9.useRef)(false);
|
|
2167
|
+
(0, import_react9.useEffect)(() => {
|
|
1776
2168
|
if (!dirty.current) setBaseText(channel.runtimeBaseURL);
|
|
1777
2169
|
}, [channel.runtimeBaseURL]);
|
|
1778
|
-
(0,
|
|
2170
|
+
(0, import_react9.useEffect)(() => () => clearTimeout(baseTimer.current), []);
|
|
1779
2171
|
const commit2 = (patch) => {
|
|
1780
2172
|
rpc("dsh-memory/settings-set", patch).catch(() => {
|
|
1781
2173
|
});
|
|
@@ -1804,17 +2196,17 @@ var __defProp = Object.defineProperty;
|
|
|
1804
2196
|
const deployedDirect = channel.deployed === "direct";
|
|
1805
2197
|
const apiKeySet = channel.runtimeApiKeySet || channel.deployedApiKeySet;
|
|
1806
2198
|
const showWarn = isDirect && !channel.directReady;
|
|
1807
|
-
return /* @__PURE__ */ (0,
|
|
1808
|
-
/* @__PURE__ */ (0,
|
|
1809
|
-
/* @__PURE__ */ (0,
|
|
1810
|
-
/* @__PURE__ */ (0,
|
|
1811
|
-
/* @__PURE__ */ (0,
|
|
2199
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: STY.block, children: [
|
|
2200
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: STY.head, children: [
|
|
2201
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY.title, children: "蒸馏通道" }),
|
|
2202
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: isDirect ? STY.chipAccent : STY.chipMuted, children: isDirect ? "直连端点" : "复用宿主" }),
|
|
2203
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { title: "direct = 插件原生直连 OpenAI 兼容端点,与付费 API 解耦;失败自动回退宿主路由链。", style: { marginLeft: "auto", fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: [
|
|
1812
2204
|
"生效:",
|
|
1813
2205
|
runtime ? runtime === "direct" ? "运行时直连" : "运行时宿主" : "跟随部署配置"
|
|
1814
2206
|
] })
|
|
1815
2207
|
] }),
|
|
1816
|
-
/* @__PURE__ */ (0,
|
|
1817
|
-
/* @__PURE__ */ (0,
|
|
2208
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: STY.desc, children: "direct 通道走插件原生 HTTP,不依赖宿主 provider 注册表;direct 失败自动回退宿主路由链作兜底安全网。" }),
|
|
2209
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1818
2210
|
Segmented,
|
|
1819
2211
|
{
|
|
1820
2212
|
value: runtime,
|
|
@@ -1823,10 +2215,10 @@ var __defProp = Object.defineProperty;
|
|
|
1823
2215
|
onChange: (k) => commit2({ distillMode: k })
|
|
1824
2216
|
}
|
|
1825
2217
|
),
|
|
1826
|
-
editing ? /* @__PURE__ */ (0,
|
|
1827
|
-
/* @__PURE__ */ (0,
|
|
1828
|
-
/* @__PURE__ */ (0,
|
|
1829
|
-
/* @__PURE__ */ (0,
|
|
2218
|
+
editing ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
2219
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: STY.fieldRow, children: [
|
|
2220
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY.fieldLabel, children: "端点 URL" }),
|
|
2221
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1830
2222
|
NInput,
|
|
1831
2223
|
{
|
|
1832
2224
|
style: STY.input,
|
|
@@ -1843,14 +2235,14 @@ var __defProp = Object.defineProperty;
|
|
|
1843
2235
|
}
|
|
1844
2236
|
}
|
|
1845
2237
|
),
|
|
1846
|
-
deployedDirect && !channel.runtimeBaseURL ? /* @__PURE__ */ (0,
|
|
2238
|
+
deployedDirect && !channel.runtimeBaseURL ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: [
|
|
1847
2239
|
"部署基线:",
|
|
1848
2240
|
channel.deployedBaseURL || "(空)"
|
|
1849
2241
|
] }) : null
|
|
1850
2242
|
] }),
|
|
1851
|
-
/* @__PURE__ */ (0,
|
|
1852
|
-
/* @__PURE__ */ (0,
|
|
1853
|
-
/* @__PURE__ */ (0,
|
|
2243
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: STY.fieldRow, children: [
|
|
2244
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY.fieldLabel, children: "API Key" }),
|
|
2245
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1854
2246
|
NInput,
|
|
1855
2247
|
{
|
|
1856
2248
|
style: STY.input,
|
|
@@ -1866,8 +2258,8 @@ var __defProp = Object.defineProperty;
|
|
|
1866
2258
|
onBlur: commitKey
|
|
1867
2259
|
}
|
|
1868
2260
|
),
|
|
1869
|
-
apiKeySet ? /* @__PURE__ */ (0,
|
|
1870
|
-
/* @__PURE__ */ (0,
|
|
2261
|
+
apiKeySet ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY.chipAccent, children: "已配置" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: STY.chipMuted, children: "未配置" }),
|
|
2262
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1871
2263
|
NButton,
|
|
1872
2264
|
{
|
|
1873
2265
|
disabled,
|
|
@@ -1877,30 +2269,30 @@ var __defProp = Object.defineProperty;
|
|
|
1877
2269
|
}
|
|
1878
2270
|
)
|
|
1879
2271
|
] }),
|
|
1880
|
-
showWarn ? /* @__PURE__ */ (0,
|
|
1881
|
-
] }) : /* @__PURE__ */ (0,
|
|
2272
|
+
showWarn ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: STY.warn, children: "⚠ direct 未配置完整:需同时有端点 URL 与模型(llm.model / 全局链主路由),否则会回退宿主路由。" }) : null
|
|
2273
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: STY.preview, children: isDirect ? "当前将直连端点:" + (channel.runtimeBaseURL || channel.deployedBaseURL || "(未配置端点)") + (apiKeySet ? " · 密钥已配置" : " · 未配置密钥") : "当前复用宿主 ctx.llm(" + (runtime === "host" ? "运行时锁定" : "跟随部署配置") + ")" })
|
|
1882
2274
|
] });
|
|
1883
2275
|
}
|
|
1884
2276
|
|
|
1885
2277
|
// client/src/tabs/RouteChainEditor.tsx
|
|
1886
|
-
var
|
|
2278
|
+
var import_react11 = require("react");
|
|
1887
2279
|
|
|
1888
2280
|
// client/src/ui/NSel.tsx
|
|
1889
|
-
var
|
|
1890
|
-
var
|
|
2281
|
+
var import_react10 = require("react");
|
|
2282
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1891
2283
|
function NSel(props) {
|
|
1892
2284
|
const options = props.options || [];
|
|
1893
2285
|
const value = props.value || "";
|
|
1894
2286
|
const disabled = !!props.disabled;
|
|
1895
|
-
const [open, setOpen] = (0,
|
|
1896
|
-
const [idx, setIdx] = (0,
|
|
1897
|
-
const wrapRef = (0,
|
|
1898
|
-
const listRef = (0,
|
|
2287
|
+
const [open, setOpen] = (0, import_react10.useState)(false);
|
|
2288
|
+
const [idx, setIdx] = (0, import_react10.useState)(-1);
|
|
2289
|
+
const wrapRef = (0, import_react10.useRef)(null);
|
|
2290
|
+
const listRef = (0, import_react10.useRef)(null);
|
|
1899
2291
|
let selectedLabel = "";
|
|
1900
2292
|
for (let si = 0; si < options.length; si++) {
|
|
1901
2293
|
if (options[si].id === value) selectedLabel = options[si].label;
|
|
1902
2294
|
}
|
|
1903
|
-
(0,
|
|
2295
|
+
(0, import_react10.useEffect)(() => {
|
|
1904
2296
|
if (!open) return void 0;
|
|
1905
2297
|
const onDown = (e) => {
|
|
1906
2298
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -1910,7 +2302,7 @@ var __defProp = Object.defineProperty;
|
|
|
1910
2302
|
document.removeEventListener("mousedown", onDown);
|
|
1911
2303
|
};
|
|
1912
2304
|
}, [open]);
|
|
1913
|
-
(0,
|
|
2305
|
+
(0, import_react10.useEffect)(() => {
|
|
1914
2306
|
if (!open || !listRef.current) return;
|
|
1915
2307
|
const el = listRef.current.querySelector('[data-active="1"]');
|
|
1916
2308
|
if (el && el.scrollIntoView) el.scrollIntoView({ block: "nearest" });
|
|
@@ -1973,8 +2365,8 @@ var __defProp = Object.defineProperty;
|
|
|
1973
2365
|
const to = e.relatedTarget;
|
|
1974
2366
|
if (!to || wrapRef.current && !wrapRef.current.contains(to)) setOpen(false);
|
|
1975
2367
|
};
|
|
1976
|
-
return /* @__PURE__ */ (0,
|
|
1977
|
-
/* @__PURE__ */ (0,
|
|
2368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-mem-sel", style: props.style, ref: wrapRef, onKeyDown: onKey, onBlur, children: [
|
|
2369
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1978
2370
|
"button",
|
|
1979
2371
|
{
|
|
1980
2372
|
type: "button",
|
|
@@ -1990,13 +2382,13 @@ var __defProp = Object.defineProperty;
|
|
|
1990
2382
|
}
|
|
1991
2383
|
},
|
|
1992
2384
|
children: [
|
|
1993
|
-
/* @__PURE__ */ (0,
|
|
1994
|
-
/* @__PURE__ */ (0,
|
|
2385
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-select-label", children: selectedLabel || props.placeholder || "(请选择)" }),
|
|
2386
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-sel-chev" + (open ? " dsh-mem-sel-chev-open" : ""), "aria-hidden": true })
|
|
1995
2387
|
]
|
|
1996
2388
|
}
|
|
1997
2389
|
),
|
|
1998
|
-
open && !disabled ? /* @__PURE__ */ (0,
|
|
1999
|
-
return /* @__PURE__ */ (0,
|
|
2390
|
+
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) => {
|
|
2391
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2000
2392
|
"button",
|
|
2001
2393
|
{
|
|
2002
2394
|
type: "button",
|
|
@@ -2014,8 +2406,8 @@ var __defProp = Object.defineProperty;
|
|
|
2014
2406
|
if (idx !== i) setIdx(i);
|
|
2015
2407
|
},
|
|
2016
2408
|
children: [
|
|
2017
|
-
/* @__PURE__ */ (0,
|
|
2018
|
-
o.id === value ? /* @__PURE__ */ (0,
|
|
2409
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-pop-opt-label", children: o.label }),
|
|
2410
|
+
o.id === value ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-mem-pop-check", children: "✓" }) : null
|
|
2019
2411
|
]
|
|
2020
2412
|
},
|
|
2021
2413
|
o.id
|
|
@@ -2025,7 +2417,7 @@ var __defProp = Object.defineProperty;
|
|
|
2025
2417
|
}
|
|
2026
2418
|
|
|
2027
2419
|
// client/src/tabs/RouteChainEditor.tsx
|
|
2028
|
-
var
|
|
2420
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2029
2421
|
var modelsCache = {};
|
|
2030
2422
|
var EFFORT_VOCAB = ["", "off", "none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
2031
2423
|
var STY2 = {
|
|
@@ -2054,26 +2446,26 @@ var __defProp = Object.defineProperty;
|
|
|
2054
2446
|
const disabled = !!props.disabled;
|
|
2055
2447
|
const scope = props.scope ?? "global";
|
|
2056
2448
|
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,
|
|
2449
|
+
const [info, setInfo] = (0, import_react11.useState)(null);
|
|
2450
|
+
const [rows, setRows] = (0, import_react11.useState)(null);
|
|
2451
|
+
const [rowErrs, setRowErrs] = (0, import_react11.useState)({});
|
|
2452
|
+
const [err, setErr] = (0, import_react11.useState)(null);
|
|
2453
|
+
const [manual, setManual] = (0, import_react11.useState)({ idx: -1, text: "" });
|
|
2454
|
+
const pendingWrites = (0, import_react11.useRef)(0);
|
|
2063
2455
|
function refreshInfo() {
|
|
2064
2456
|
rpc("dsh-memory/llm-providers", {}).then((r) => {
|
|
2065
2457
|
if (r && r.ok && pendingWrites.current === 0) setInfo(r.value);
|
|
2066
2458
|
}).catch(() => {
|
|
2067
2459
|
});
|
|
2068
2460
|
}
|
|
2069
|
-
(0,
|
|
2461
|
+
(0, import_react11.useEffect)(() => {
|
|
2070
2462
|
refreshInfo();
|
|
2071
2463
|
const timer = setInterval(refreshInfo, 5e3);
|
|
2072
2464
|
return () => {
|
|
2073
2465
|
clearInterval(timer);
|
|
2074
2466
|
};
|
|
2075
2467
|
}, [rpc]);
|
|
2076
|
-
(0,
|
|
2468
|
+
(0, import_react11.useEffect)(() => {
|
|
2077
2469
|
if (!info || !info.providers) return;
|
|
2078
2470
|
info.providers.forEach((p) => {
|
|
2079
2471
|
if (!p.id || modelsCache[p.id]) return;
|
|
@@ -2085,7 +2477,7 @@ var __defProp = Object.defineProperty;
|
|
|
2085
2477
|
}, [rpc, info]);
|
|
2086
2478
|
const layerView = isLayer && info && info.layerChains ? info.layerChains[scope] : null;
|
|
2087
2479
|
const savedRows = isLayer ? layerView?.runtime ?? [] : info && info.chain ? info.chain.current : [];
|
|
2088
|
-
(0,
|
|
2480
|
+
(0, import_react11.useEffect)(() => {
|
|
2089
2481
|
if (rows === null && info && savedRows.length) {
|
|
2090
2482
|
setRows(savedRows.map(copyRow));
|
|
2091
2483
|
}
|
|
@@ -2233,17 +2625,17 @@ var __defProp = Object.defineProperty;
|
|
|
2233
2625
|
providersById[p.id] = p;
|
|
2234
2626
|
});
|
|
2235
2627
|
function roRow(e, i) {
|
|
2236
|
-
return /* @__PURE__ */ (0,
|
|
2237
|
-
/* @__PURE__ */ (0,
|
|
2238
|
-
/* @__PURE__ */ (0,
|
|
2239
|
-
/* @__PURE__ */ (0,
|
|
2628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.roRow, children: [
|
|
2629
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: STY2.badge, children: i === 0 ? "主" : String(i + 1) }),
|
|
2630
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { ...STY2.mono, color: "var(--dsh-mem-text-2)" }, children: e.provider + " / " + e.model }),
|
|
2631
|
+
/* @__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
2632
|
] }, "ro" + i);
|
|
2241
2633
|
}
|
|
2242
2634
|
if (info.pinned) {
|
|
2243
2635
|
const effPin = isLayer ? layerView?.effectiveChain ?? [] : info.chain && info.chain.effectiveChain || [];
|
|
2244
|
-
return /* @__PURE__ */ (0,
|
|
2636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.wrap, children: [
|
|
2245
2637
|
effPin.map(roRow),
|
|
2246
|
-
/* @__PURE__ */ (0,
|
|
2638
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: STY2.note, children: "部署已锁定路由(pin),调整请修改 cordis.patch.yml 中 llm 的配置。" })
|
|
2247
2639
|
] });
|
|
2248
2640
|
}
|
|
2249
2641
|
if (rows === null) {
|
|
@@ -2251,21 +2643,21 @@ var __defProp = Object.defineProperty;
|
|
|
2251
2643
|
const lv = layerView;
|
|
2252
2644
|
const src = lv?.source ?? "global";
|
|
2253
2645
|
if (src === "static" && lv) {
|
|
2254
|
-
return /* @__PURE__ */ (0,
|
|
2646
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.wrap, children: [
|
|
2255
2647
|
lv.static.map((e, i) => roRow({ provider: e.provider, model: e.model, effort: e.reasoningEffort || "" }, i)),
|
|
2256
|
-
/* @__PURE__ */ (0,
|
|
2648
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { onClick: forkStatic, disabled, children: "自定义本层链" }) })
|
|
2257
2649
|
] });
|
|
2258
2650
|
}
|
|
2259
2651
|
const previewRows = lv?.effectiveChain ?? [];
|
|
2260
|
-
return /* @__PURE__ */ (0,
|
|
2261
|
-
previewRows.length === 0 ? /* @__PURE__ */ (0,
|
|
2262
|
-
/* @__PURE__ */ (0,
|
|
2652
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.wrap, children: [
|
|
2653
|
+
previewRows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: S.switchDesc, children: "本层跟随全局链,暂无可用路由。" }) : previewRows.map(roRow),
|
|
2654
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { onClick: forkStatic, disabled, children: "自定义本层链" }) })
|
|
2263
2655
|
] });
|
|
2264
2656
|
}
|
|
2265
2657
|
const effFollow = info.chain && info.chain.effectiveChain || [];
|
|
2266
|
-
return /* @__PURE__ */ (0,
|
|
2267
|
-
effFollow.length === 0 ? /* @__PURE__ */ (0,
|
|
2268
|
-
/* @__PURE__ */ (0,
|
|
2658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.wrap, children: [
|
|
2659
|
+
effFollow.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: S.switchDesc, children: "蒸馏跟随默认模型,未配置回退链。" }) : effFollow.map(roRow),
|
|
2660
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { onClick: forkStatic, disabled, children: "编辑为运行时链" }) })
|
|
2269
2661
|
] });
|
|
2270
2662
|
}
|
|
2271
2663
|
const capped = rows.length >= 8;
|
|
@@ -2306,10 +2698,10 @@ var __defProp = Object.defineProperty;
|
|
|
2306
2698
|
const effortOptions = [{ id: "", label: "跟随部署配置" }].concat(
|
|
2307
2699
|
curEfforts.filter((k) => EFFORT_VOCAB.indexOf(k) >= 0).map((k) => ({ id: k, label: k }))
|
|
2308
2700
|
);
|
|
2309
|
-
return /* @__PURE__ */ (0,
|
|
2310
|
-
/* @__PURE__ */ (0,
|
|
2311
|
-
/* @__PURE__ */ (0,
|
|
2312
|
-
/* @__PURE__ */ (0,
|
|
2701
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { ...STY2.row, ...rowErrs[i] ? STY2.rowErr : null }, children: [
|
|
2702
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.line, children: [
|
|
2703
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: STY2.badge, children: isPrimary ? "主" : String(i + 1) }),
|
|
2704
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2313
2705
|
NSel,
|
|
2314
2706
|
{
|
|
2315
2707
|
style: { flex: 1, minWidth: 150 },
|
|
@@ -2322,7 +2714,7 @@ var __defProp = Object.defineProperty;
|
|
|
2322
2714
|
}
|
|
2323
2715
|
}
|
|
2324
2716
|
),
|
|
2325
|
-
!row2.provider ? null : manualInput ? /* @__PURE__ */ (0,
|
|
2717
|
+
!row2.provider ? null : manualInput ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2326
2718
|
NInput,
|
|
2327
2719
|
{
|
|
2328
2720
|
style: { flex: 1, minWidth: 150 },
|
|
@@ -2341,7 +2733,7 @@ var __defProp = Object.defineProperty;
|
|
|
2341
2733
|
}
|
|
2342
2734
|
}
|
|
2343
2735
|
}
|
|
2344
|
-
) : /* @__PURE__ */ (0,
|
|
2736
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2345
2737
|
NSel,
|
|
2346
2738
|
{
|
|
2347
2739
|
style: { flex: 1, minWidth: 150 },
|
|
@@ -2354,7 +2746,7 @@ var __defProp = Object.defineProperty;
|
|
|
2354
2746
|
}
|
|
2355
2747
|
}
|
|
2356
2748
|
),
|
|
2357
|
-
/* @__PURE__ */ (0,
|
|
2749
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2358
2750
|
NSel,
|
|
2359
2751
|
{
|
|
2360
2752
|
style: { flexShrink: 0, width: 118 },
|
|
@@ -2368,8 +2760,8 @@ var __defProp = Object.defineProperty;
|
|
|
2368
2760
|
}
|
|
2369
2761
|
)
|
|
2370
2762
|
] }),
|
|
2371
|
-
/* @__PURE__ */ (0,
|
|
2372
|
-
/* @__PURE__ */ (0,
|
|
2763
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.actions, children: [
|
|
2764
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2373
2765
|
NButton,
|
|
2374
2766
|
{
|
|
2375
2767
|
style: STY2.ico,
|
|
@@ -2381,7 +2773,7 @@ var __defProp = Object.defineProperty;
|
|
|
2381
2773
|
children: "↑"
|
|
2382
2774
|
}
|
|
2383
2775
|
),
|
|
2384
|
-
/* @__PURE__ */ (0,
|
|
2776
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2385
2777
|
NButton,
|
|
2386
2778
|
{
|
|
2387
2779
|
style: STY2.ico,
|
|
@@ -2393,7 +2785,7 @@ var __defProp = Object.defineProperty;
|
|
|
2393
2785
|
children: "↓"
|
|
2394
2786
|
}
|
|
2395
2787
|
),
|
|
2396
|
-
/* @__PURE__ */ (0,
|
|
2788
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2397
2789
|
NButton,
|
|
2398
2790
|
{
|
|
2399
2791
|
style: STY2.ico,
|
|
@@ -2406,14 +2798,14 @@ var __defProp = Object.defineProperty;
|
|
|
2406
2798
|
}
|
|
2407
2799
|
)
|
|
2408
2800
|
] }),
|
|
2409
|
-
isPrimary && !row2.provider ? /* @__PURE__ */ (0,
|
|
2410
|
-
!known ? /* @__PURE__ */ (0,
|
|
2411
|
-
rowErrs[i] ? /* @__PURE__ */ (0,
|
|
2801
|
+
isPrimary && !row2.provider ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: STY2.note, children: "跟随默认模型" + (info.default ? ":" + info.default.provider + " / " + info.default.model : "") + "(档位跟随部署配置,选定模型后可单独设置)" }) : null,
|
|
2802
|
+
!known ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: STY2.warn, children: "⚠ 供应商 " + row2.provider + " 已不在已注册路由中:该路由调用会失败并被链跳过(不阻止保存)。" }) : null,
|
|
2803
|
+
rowErrs[i] ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: STY2.warn, children: "✕ " + rowErrs[i] }) : null
|
|
2412
2804
|
] }, "row" + i);
|
|
2413
2805
|
});
|
|
2414
2806
|
const effChain = isLayer ? layerView?.effectiveChain ?? [] : info.chain && info.chain.effectiveChain || [];
|
|
2415
|
-
return /* @__PURE__ */ (0,
|
|
2416
|
-
/* @__PURE__ */ (0,
|
|
2807
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: STY2.wrap, children: [
|
|
2808
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2417
2809
|
"div",
|
|
2418
2810
|
{
|
|
2419
2811
|
style: { ...S.switchDesc, marginBottom: 8 },
|
|
@@ -2422,9 +2814,9 @@ var __defProp = Object.defineProperty;
|
|
|
2422
2814
|
}
|
|
2423
2815
|
),
|
|
2424
2816
|
rowEls,
|
|
2425
|
-
/* @__PURE__ */ (0,
|
|
2426
|
-
/* @__PURE__ */ (0,
|
|
2427
|
-
/* @__PURE__ */ (0,
|
|
2817
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { style: STY2.add, disabled: disabled || capped, onClick: addRow, children: capped ? "已达上限(8 条)" : "+ 添加回退路由" }),
|
|
2818
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 10 }, children: [
|
|
2819
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2428
2820
|
NButton,
|
|
2429
2821
|
{
|
|
2430
2822
|
style: isLayer ? { ...STY2.ghost, color: "var(--dsh-mem-danger)", border: "1px solid var(--dsh-mem-danger)" } : STY2.ghost,
|
|
@@ -2433,13 +2825,13 @@ var __defProp = Object.defineProperty;
|
|
|
2433
2825
|
children: isLayer ? "清除自定义 · 跟随全局" : "清空并跟随部署配置"
|
|
2434
2826
|
}
|
|
2435
2827
|
),
|
|
2436
|
-
/* @__PURE__ */ (0,
|
|
2437
|
-
/* @__PURE__ */ (0,
|
|
2828
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: S.grow }),
|
|
2829
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NButton, { variant: "primary", disabled, onClick: save, children: "保存" })
|
|
2438
2830
|
] }),
|
|
2439
|
-
err ? /* @__PURE__ */ (0,
|
|
2440
|
-
/* @__PURE__ */ (0,
|
|
2441
|
-
/* @__PURE__ */ (0,
|
|
2442
|
-
/* @__PURE__ */ (0,
|
|
2831
|
+
err ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { ...STY2.warn, marginTop: 8 }, children: "✕ " + err }) : null,
|
|
2832
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--dsh-mem-border)" }, children: [
|
|
2833
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)", marginBottom: 4 }, children: "实际链" + (dirty ? "(保存后更新;当前显示已保存值)" : "") }),
|
|
2834
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2443
2835
|
"div",
|
|
2444
2836
|
{
|
|
2445
2837
|
style: { fontSize: 12, color: "var(--dsh-mem-text-2)", wordBreak: "break-all", fontFamily: "ui-monospace, SFMono-Regular, Consolas, monospace" },
|
|
@@ -2451,7 +2843,7 @@ var __defProp = Object.defineProperty;
|
|
|
2451
2843
|
}
|
|
2452
2844
|
|
|
2453
2845
|
// client/src/tabs/DistillSettings.tsx
|
|
2454
|
-
var
|
|
2846
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2455
2847
|
var STY3 = {
|
|
2456
2848
|
hint: { fontSize: 11, color: "var(--dsh-mem-text-3)", margin: "0 0 8px" },
|
|
2457
2849
|
panelHead: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", marginBottom: 8 },
|
|
@@ -2480,9 +2872,9 @@ var __defProp = Object.defineProperty;
|
|
|
2480
2872
|
verticalAlign: "middle",
|
|
2481
2873
|
flexShrink: 0
|
|
2482
2874
|
};
|
|
2483
|
-
if (props.kind === "runtime") return /* @__PURE__ */ (0,
|
|
2484
|
-
if (props.kind === "static") return /* @__PURE__ */ (0,
|
|
2485
|
-
return /* @__PURE__ */ (0,
|
|
2875
|
+
if (props.kind === "runtime") return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...base, background: "var(--dsh-mem-accent)" } });
|
|
2876
|
+
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)" } });
|
|
2877
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...base, background: "var(--dsh-mem-track)" } });
|
|
2486
2878
|
}
|
|
2487
2879
|
var LAYER_META = {
|
|
2488
2880
|
l1: { seg: "L1", title: "L1 · 抽取 / 去重" },
|
|
@@ -2492,9 +2884,9 @@ var __defProp = Object.defineProperty;
|
|
|
2492
2884
|
function DistillSettings(props) {
|
|
2493
2885
|
const rpc = props.rpc;
|
|
2494
2886
|
const disabled = !!props.disabled;
|
|
2495
|
-
const [info, setInfo] = (0,
|
|
2496
|
-
const [tab, setTab] = (0,
|
|
2497
|
-
(0,
|
|
2887
|
+
const [info, setInfo] = (0, import_react12.useState)(null);
|
|
2888
|
+
const [tab, setTab] = (0, import_react12.useState)("g");
|
|
2889
|
+
(0, import_react12.useEffect)(() => {
|
|
2498
2890
|
let alive = true;
|
|
2499
2891
|
const refresh = () => {
|
|
2500
2892
|
rpc("dsh-memory/llm-providers", {}).then((r) => {
|
|
@@ -2517,46 +2909,46 @@ var __defProp = Object.defineProperty;
|
|
|
2517
2909
|
...["l1", "l2", "l3"].map((k) => ({
|
|
2518
2910
|
key: k,
|
|
2519
2911
|
title: LAYER_META[k].title + " · " + (dotOf(k) === "runtime" ? "运行时自定义" : dotOf(k) === "static" ? "部署 YAML 层链(只读)" : "跟随全局"),
|
|
2520
|
-
label: /* @__PURE__ */ (0,
|
|
2521
|
-
/* @__PURE__ */ (0,
|
|
2912
|
+
label: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
|
|
2913
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Dot, { kind: dotOf(k) }),
|
|
2522
2914
|
LAYER_META[k].seg
|
|
2523
2915
|
] })
|
|
2524
2916
|
}))
|
|
2525
2917
|
];
|
|
2526
2918
|
const chipTitle = (k) => dotOf(k) === "runtime" ? "本层走设置页自定义链" : dotOf(k) === "static" ? "本层走部署 YAML 层链(UI 只读,自定义可覆盖)" : "本层未单独配置,走全局默认链";
|
|
2527
|
-
return /* @__PURE__ */ (0,
|
|
2528
|
-
/* @__PURE__ */ (0,
|
|
2529
|
-
/* @__PURE__ */ (0,
|
|
2530
|
-
/* @__PURE__ */ (0,
|
|
2919
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
2920
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Segmented, { value: tab, options: segOptions, onChange: (k) => setTab(k) }),
|
|
2921
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: STY3.hint, children: [
|
|
2922
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Dot, { kind: "runtime" }),
|
|
2531
2923
|
" 自定义 · ",
|
|
2532
|
-
/* @__PURE__ */ (0,
|
|
2924
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Dot, { kind: "static" }),
|
|
2533
2925
|
" 部署 YAML · ",
|
|
2534
|
-
/* @__PURE__ */ (0,
|
|
2926
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Dot, { kind: "global" }),
|
|
2535
2927
|
" 跟随全局",
|
|
2536
|
-
/* @__PURE__ */ (0,
|
|
2928
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { title: "每层实际链:运行时自定义 → 部署 YAML 层链 → 全局默认链,逐级兜底;部署 pin 时运行时编辑只读", children: "(层链优先于全局)" })
|
|
2537
2929
|
] }),
|
|
2538
|
-
tab === "g" ? /* @__PURE__ */ (0,
|
|
2539
|
-
/* @__PURE__ */ (0,
|
|
2540
|
-
/* @__PURE__ */ (0,
|
|
2541
|
-
/* @__PURE__ */ (0,
|
|
2542
|
-
/* @__PURE__ */ (0,
|
|
2930
|
+
tab === "g" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
2931
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: STY3.panelHead, children: [
|
|
2932
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: STY3.panelTitle, children: "全局默认链" }),
|
|
2933
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...STY3.chip, ...STY3.chipAccent }, children: "运行时 · 可编辑" }),
|
|
2934
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...STY3.inUse, marginLeft: "auto" }, children: users.length ? "在用:" + users.map((k) => LAYER_META[k].seg).join("、") : "当前无层使用" })
|
|
2543
2935
|
] }),
|
|
2544
|
-
/* @__PURE__ */ (0,
|
|
2545
|
-
/* @__PURE__ */ (0,
|
|
2546
|
-
info?.channel ? /* @__PURE__ */ (0,
|
|
2547
|
-
] }) : /* @__PURE__ */ (0,
|
|
2548
|
-
/* @__PURE__ */ (0,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2550
|
-
/* @__PURE__ */ (0,
|
|
2936
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RouteChainEditor, { rpc, disabled }, "g"),
|
|
2937
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(BudgetInputs, { rpc, disabled, data: props.data, setData: props.setData, onError: props.onError, scope: "input" }, "g-budget"),
|
|
2938
|
+
info?.channel ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChannelEditor, { channel: info.channel, rpc, disabled }) : null
|
|
2939
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
2940
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: STY3.panelHead, children: [
|
|
2941
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: STY3.panelTitle, children: LAYER_META[tab].title }),
|
|
2942
|
+
/* @__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
2943
|
] }),
|
|
2552
|
-
/* @__PURE__ */ (0,
|
|
2553
|
-
/* @__PURE__ */ (0,
|
|
2944
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RouteChainEditor, { rpc, disabled, scope: tab }, tab),
|
|
2945
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(BudgetInputs, { rpc, disabled, data: props.data, setData: props.setData, onError: props.onError, scope: tab }, tab + "-budget")
|
|
2554
2946
|
] })
|
|
2555
2947
|
] });
|
|
2556
2948
|
}
|
|
2557
2949
|
|
|
2558
2950
|
// client/src/tabs/EmbeddingSection.tsx
|
|
2559
|
-
var
|
|
2951
|
+
var import_react13 = require("react");
|
|
2560
2952
|
|
|
2561
2953
|
// client/src/dimensions.ts
|
|
2562
2954
|
var DIMS_MIN = 1;
|
|
@@ -2604,7 +2996,7 @@ var __defProp = Object.defineProperty;
|
|
|
2604
2996
|
}
|
|
2605
2997
|
|
|
2606
2998
|
// client/src/tabs/EmbeddingSection.tsx
|
|
2607
|
-
var
|
|
2999
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2608
3000
|
var RSTY = {
|
|
2609
3001
|
block: { marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--dsh-mem-border)" },
|
|
2610
3002
|
title: { fontSize: 12, fontWeight: 600, color: "var(--dsh-mem-text-3)", margin: "0 0 2px" },
|
|
@@ -2628,17 +3020,17 @@ var __defProp = Object.defineProperty;
|
|
|
2628
3020
|
function EmbeddingSection(props) {
|
|
2629
3021
|
const rpc = props.rpc;
|
|
2630
3022
|
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,
|
|
3023
|
+
const [st, setSt] = (0, import_react13.useState)(null);
|
|
3024
|
+
const [err, setErr] = (0, import_react13.useState)(null);
|
|
3025
|
+
const busyPollRef = (0, import_react13.useRef)(null);
|
|
3026
|
+
const [rBase, setRBase] = (0, import_react13.useState)("");
|
|
3027
|
+
const [rModel, setRModel] = (0, import_react13.useState)("");
|
|
3028
|
+
const [rDims, setRDims] = (0, import_react13.useState)("");
|
|
3029
|
+
const [rKey, setRKey] = (0, import_react13.useState)("");
|
|
3030
|
+
const remoteDirty = (0, import_react13.useRef)({ base: false, model: false, dims: false });
|
|
3031
|
+
const baseTimer = (0, import_react13.useRef)(void 0);
|
|
3032
|
+
const modelTimer = (0, import_react13.useRef)(void 0);
|
|
3033
|
+
const load = (0, import_react13.useCallback)(() => {
|
|
2642
3034
|
rpc("dsh-memory/embedding-state-get", {}).then((r) => {
|
|
2643
3035
|
if (r && r.ok && r.value && r.value.supported !== false) {
|
|
2644
3036
|
const v = r.value;
|
|
@@ -2657,10 +3049,10 @@ var __defProp = Object.defineProperty;
|
|
|
2657
3049
|
setErr(String(e && e.message || e));
|
|
2658
3050
|
});
|
|
2659
3051
|
}, [rpc]);
|
|
2660
|
-
(0,
|
|
3052
|
+
(0, import_react13.useEffect)(() => {
|
|
2661
3053
|
load();
|
|
2662
3054
|
}, [load]);
|
|
2663
|
-
(0,
|
|
3055
|
+
(0, import_react13.useEffect)(() => {
|
|
2664
3056
|
let stopped = false;
|
|
2665
3057
|
const busyFlag = { v: false };
|
|
2666
3058
|
busyPollRef.current = busyFlag;
|
|
@@ -2676,11 +3068,11 @@ var __defProp = Object.defineProperty;
|
|
|
2676
3068
|
busyPollRef.current = null;
|
|
2677
3069
|
};
|
|
2678
3070
|
}, [load]);
|
|
2679
|
-
(0,
|
|
3071
|
+
(0, import_react13.useEffect)(() => () => {
|
|
2680
3072
|
clearTimeout(baseTimer.current);
|
|
2681
3073
|
clearTimeout(modelTimer.current);
|
|
2682
3074
|
}, []);
|
|
2683
|
-
(0,
|
|
3075
|
+
(0, import_react13.useEffect)(() => {
|
|
2684
3076
|
if (!st || !st.remote) return;
|
|
2685
3077
|
if (!remoteDirty.current.base) setRBase(st.remote.baseURL || "");
|
|
2686
3078
|
if (!remoteDirty.current.model) setRModel(st.remote.model || "");
|
|
@@ -2728,7 +3120,7 @@ var __defProp = Object.defineProperty;
|
|
|
2728
3120
|
if (v) commitRemote({ embedRemoteApiKey: v });
|
|
2729
3121
|
setRKey("");
|
|
2730
3122
|
};
|
|
2731
|
-
const
|
|
3123
|
+
const call2 = (endpoint, payload, confirmText) => {
|
|
2732
3124
|
if (confirmText && !window.confirm(confirmText)) return;
|
|
2733
3125
|
loose(endpoint, payload).then((r) => {
|
|
2734
3126
|
if (!r || !r.ok) setErr(r && r.error ? r.error.message : "操作失败");
|
|
@@ -2741,15 +3133,15 @@ var __defProp = Object.defineProperty;
|
|
|
2741
3133
|
});
|
|
2742
3134
|
};
|
|
2743
3135
|
if (err === "__unsupported__") {
|
|
2744
|
-
return /* @__PURE__ */ (0,
|
|
2745
|
-
/* @__PURE__ */ (0,
|
|
2746
|
-
/* @__PURE__ */ (0,
|
|
3136
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
3137
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: "语义检索(嵌入)" }),
|
|
3138
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", children: "存储处于降级状态,嵌入管理不可用。" })
|
|
2747
3139
|
] });
|
|
2748
3140
|
}
|
|
2749
3141
|
if (!st) {
|
|
2750
|
-
return /* @__PURE__ */ (0,
|
|
2751
|
-
/* @__PURE__ */ (0,
|
|
2752
|
-
err ? /* @__PURE__ */ (0,
|
|
3142
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
3143
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", children: err ? "嵌入状态读取失败:" + err : "嵌入状态读取中…" }),
|
|
3144
|
+
err ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NButton, { style: { marginTop: 8 }, onClick: load, children: "重试" }) : null
|
|
2753
3145
|
] });
|
|
2754
3146
|
}
|
|
2755
3147
|
const switchConfirm = "切换嵌入源后将按新模型重建向量索引(期间语义检索暂退化为关键词匹配,不影响对话)。确定切换?";
|
|
@@ -2762,10 +3154,10 @@ var __defProp = Object.defineProperty;
|
|
|
2762
3154
|
return;
|
|
2763
3155
|
}
|
|
2764
3156
|
const current = st.activeModel && ready.indexOf(st.activeModel) >= 0 ? st.activeModel : ready[0];
|
|
2765
|
-
|
|
3157
|
+
call2("dsh-memory/embedding-source-set", { source: "local", activeModel: current }, switchConfirm);
|
|
2766
3158
|
return;
|
|
2767
3159
|
}
|
|
2768
|
-
|
|
3160
|
+
call2("dsh-memory/embedding-source-set", { source: key }, key === "remote" ? switchConfirm : null);
|
|
2769
3161
|
};
|
|
2770
3162
|
const dl = st.download;
|
|
2771
3163
|
const dlActive = dl && (dl.phase === "downloading" || dl.phase === "verifying");
|
|
@@ -2775,40 +3167,40 @@ var __defProp = Object.defineProperty;
|
|
|
2775
3167
|
const remote = st.remote;
|
|
2776
3168
|
let runtimeRow = null;
|
|
2777
3169
|
if (rt.phase === "installing") {
|
|
2778
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
2779
|
-
/* @__PURE__ */ (0,
|
|
2780
|
-
/* @__PURE__ */ (0,
|
|
2781
|
-
/* @__PURE__ */ (0,
|
|
2782
|
-
/* @__PURE__ */ (0,
|
|
3170
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { marginTop: 8, fontSize: 12 }, children: [
|
|
3171
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3172
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "安装推理运行时中… 已耗时 " + Math.round(rt.elapsedMs / 1e3) + "s(约 100~200MB,视网络)" }),
|
|
3173
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.grow }),
|
|
3174
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NButton, { onClick: () => call2("dsh-memory/embedding-runtime-cancel", {}), children: "取消" })
|
|
2783
3175
|
] }),
|
|
2784
|
-
/* @__PURE__ */ (0,
|
|
3176
|
+
/* @__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
3177
|
] });
|
|
2786
3178
|
} else if (rt.phase === "error") {
|
|
2787
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
3179
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: "运行时安装失败:" + (rt.error || "未知") + "(重新切换嵌入源可重试)" });
|
|
2788
3180
|
} else if (rt.phase === "ready") {
|
|
2789
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
3181
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "推理运行时就绪(transformers.js v" + rt.installedVersion + ")" });
|
|
2790
3182
|
} else if (st.source === "local") {
|
|
2791
|
-
runtimeRow = /* @__PURE__ */ (0,
|
|
3183
|
+
runtimeRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "首次启用本地嵌入时会自动安装推理运行时(约 100~200MB)。" });
|
|
2792
3184
|
}
|
|
2793
3185
|
let applyRow = null;
|
|
2794
3186
|
if (ap.phase === "warming") {
|
|
2795
|
-
applyRow = /* @__PURE__ */ (0,
|
|
3187
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "加载嵌入模型中…(首次需数秒)" });
|
|
2796
3188
|
} else if (ap.phase === "switching") {
|
|
2797
|
-
applyRow = /* @__PURE__ */ (0,
|
|
3189
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: "切换嵌入源中…" });
|
|
2798
3190
|
} else if (ap.phase === "error") {
|
|
2799
|
-
applyRow = /* @__PURE__ */ (0,
|
|
3191
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: "切换失败:" + ap.message + "(已保存的嵌入源不变,重启后仍按原源运行)" });
|
|
2800
3192
|
} else if (st.reindex && st.reindex.running) {
|
|
2801
3193
|
const rj = st.reindex;
|
|
2802
3194
|
const rDone = rj.l1Done + rj.l0Done;
|
|
2803
3195
|
const rTotal = rj.l1Total + rj.l0Total;
|
|
2804
3196
|
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,
|
|
3197
|
+
applyRow = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { marginTop: 8 }, children: [
|
|
3198
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3199
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dsh-mem-rb-muted", children: "重嵌入中 L1 " + rj.l1Done + "/" + rj.l1Total + " · L0 " + rj.l0Done + "/" + rj.l0Total + "(" + rPct + "%)" }),
|
|
3200
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.grow }),
|
|
3201
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NButton, { onClick: () => call2("dsh-memory/embedding-reindex-cancel", {}), children: "取消" })
|
|
2810
3202
|
] }),
|
|
2811
|
-
/* @__PURE__ */ (0,
|
|
3203
|
+
/* @__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
3204
|
] });
|
|
2813
3205
|
}
|
|
2814
3206
|
const modelCards = st.models.map((m) => {
|
|
@@ -2817,61 +3209,61 @@ var __defProp = Object.defineProperty;
|
|
|
2817
3209
|
const pct = mDl && dl.overallTotal > 0 ? Math.round(dl.overallReceived / dl.overallTotal * 100) : 0;
|
|
2818
3210
|
let action;
|
|
2819
3211
|
if (mDl) {
|
|
2820
|
-
action = /* @__PURE__ */ (0,
|
|
2821
|
-
/* @__PURE__ */ (0,
|
|
2822
|
-
/* @__PURE__ */ (0,
|
|
2823
|
-
/* @__PURE__ */ (0,
|
|
2824
|
-
/* @__PURE__ */ (0,
|
|
3212
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { flex: 1, minWidth: 200 }, children: [
|
|
3213
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3214
|
+
/* @__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" : "") + ")" }),
|
|
3215
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.grow }),
|
|
3216
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NButton, { onClick: () => call2("dsh-memory/embedding-download-cancel", {}), children: "取消" })
|
|
2825
3217
|
] }),
|
|
2826
|
-
/* @__PURE__ */ (0,
|
|
3218
|
+
/* @__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
3219
|
] });
|
|
2828
3220
|
} 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,
|
|
3221
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3222
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dsh-mem-tag dsh-mem-tag-work-task", children: "使用中" }),
|
|
3223
|
+
localInfo && localInfo.state === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dsh-mem-rb-muted", children: "模型加载中…" }) : null,
|
|
3224
|
+
localInfo && localInfo.state === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-danger)" }, children: "加载失败:" + (localInfo.error || "") }) : null,
|
|
3225
|
+
localInfo && localInfo.state === "ready" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dsh-mem-rb-muted", children: "已就绪" }) : null
|
|
2834
3226
|
] });
|
|
2835
3227
|
} else if (m.state === "downloaded") {
|
|
2836
|
-
action = /* @__PURE__ */ (0,
|
|
2837
|
-
/* @__PURE__ */ (0,
|
|
3228
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3229
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2838
3230
|
NButton,
|
|
2839
3231
|
{
|
|
2840
3232
|
disabled: ap.busy,
|
|
2841
|
-
onClick: () =>
|
|
3233
|
+
onClick: () => call2("dsh-memory/embedding-source-set", { source: "local", activeModel: m.id }, switchConfirm),
|
|
2842
3234
|
children: "启用"
|
|
2843
3235
|
}
|
|
2844
3236
|
),
|
|
2845
|
-
/* @__PURE__ */ (0,
|
|
3237
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2846
3238
|
NButton,
|
|
2847
3239
|
{
|
|
2848
3240
|
disabled: dlActive,
|
|
2849
|
-
onClick: () =>
|
|
3241
|
+
onClick: () => call2("dsh-memory/embedding-model-delete", { modelId: m.id }, "删除已下载的 " + m.name + "(" + fmtMB(m.totalBytes) + ")?"),
|
|
2850
3242
|
children: "删除"
|
|
2851
3243
|
}
|
|
2852
3244
|
)
|
|
2853
3245
|
] });
|
|
2854
3246
|
} else {
|
|
2855
|
-
action = /* @__PURE__ */ (0,
|
|
3247
|
+
action = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2856
3248
|
NButton,
|
|
2857
3249
|
{
|
|
2858
3250
|
disabled: dlActive || !st.ceilings.local,
|
|
2859
3251
|
title: !st.ceilings.local ? "部署已禁用本地嵌入模型" : "",
|
|
2860
|
-
onClick: () =>
|
|
3252
|
+
onClick: () => call2("dsh-memory/embedding-download-start", { modelId: m.id }),
|
|
2861
3253
|
children: (m.state === "partial" ? "继续下载 " : "下载 ") + fmtMB(m.totalBytes)
|
|
2862
3254
|
}
|
|
2863
3255
|
);
|
|
2864
3256
|
}
|
|
2865
|
-
return /* @__PURE__ */ (0,
|
|
3257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2866
3258
|
"div",
|
|
2867
3259
|
{
|
|
2868
3260
|
style: { ...S.flexRow, padding: "8px 0", borderBottom: "1px solid var(--dsh-mem-border)", flexWrap: "wrap" },
|
|
2869
3261
|
children: [
|
|
2870
|
-
/* @__PURE__ */ (0,
|
|
2871
|
-
/* @__PURE__ */ (0,
|
|
2872
|
-
/* @__PURE__ */ (0,
|
|
3262
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { minWidth: 150 }, children: [
|
|
3263
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontWeight: 600 }, children: m.name }),
|
|
3264
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "dsh-mem-rb-muted", children: m.tags.join(" · ") + " · " + m.dims + " 维 · 上下文 " + m.contextTokens })
|
|
2873
3265
|
] }),
|
|
2874
|
-
/* @__PURE__ */ (0,
|
|
3266
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { flex: 1, minWidth: 180, fontSize: 12, color: "var(--dsh-mem-text-2)" }, children: m.description }),
|
|
2875
3267
|
action
|
|
2876
3268
|
]
|
|
2877
3269
|
},
|
|
@@ -2880,15 +3272,17 @@ var __defProp = Object.defineProperty;
|
|
|
2880
3272
|
});
|
|
2881
3273
|
const vec = st.vectors;
|
|
2882
3274
|
const vecOk = !!vec && vec.l1.embedded >= 0 && vec.l0.embedded >= 0;
|
|
2883
|
-
const
|
|
3275
|
+
const lastRun = st.reindex ? st.reindex.last : void 0;
|
|
3276
|
+
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";
|
|
3277
|
+
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
3278
|
const reindexRunning = !!(st.reindex && st.reindex.running);
|
|
2885
3279
|
const canRebuild = vecOk && st.source !== "off" && !reindexRunning && !st.apply.busy;
|
|
2886
3280
|
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,
|
|
3281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
3282
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: S.flexRow, children: [
|
|
3283
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontWeight: 600, whiteSpace: "nowrap" }, children: "语义检索(嵌入源)" }),
|
|
3284
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.grow }),
|
|
3285
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2892
3286
|
Segmented,
|
|
2893
3287
|
{
|
|
2894
3288
|
value: st.source,
|
|
@@ -2901,18 +3295,18 @@ var __defProp = Object.defineProperty;
|
|
|
2901
3295
|
}
|
|
2902
3296
|
)
|
|
2903
3297
|
] }),
|
|
2904
|
-
/* @__PURE__ */ (0,
|
|
2905
|
-
st.activeNote ? /* @__PURE__ */ (0,
|
|
2906
|
-
err && err !== "__unsupported__" ? /* @__PURE__ */ (0,
|
|
2907
|
-
dl && dl.phase === "error" ? /* @__PURE__ */ (0,
|
|
3298
|
+
/* @__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 + ")" : "") }),
|
|
3299
|
+
st.activeNote ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginTop: 4, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: st.activeNote }) : null,
|
|
3300
|
+
err && err !== "__unsupported__" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginTop: 6, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: err }) : null,
|
|
3301
|
+
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
3302
|
runtimeRow,
|
|
2909
3303
|
applyRow,
|
|
2910
|
-
/* @__PURE__ */ (0,
|
|
2911
|
-
/* @__PURE__ */ (0,
|
|
2912
|
-
/* @__PURE__ */ (0,
|
|
2913
|
-
/* @__PURE__ */ (0,
|
|
2914
|
-
/* @__PURE__ */ (0,
|
|
2915
|
-
/* @__PURE__ */ (0,
|
|
3304
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: RSTY.block, children: [
|
|
3305
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: RSTY.title, children: "远程连接(生效值;运行时覆盖优先于部署 YAML)" }),
|
|
3306
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: RSTY.note, children: "生效端点 " + (remote.baseURL || "(未配置)") + " · 模型 " + (remote.model || "(未配置)") + " · " + (remote.dimensions > 0 ? remote.dimensions + " 维" : "维度跟随部署") + (remote.apiKeySet ? " · 密钥已设置" : " · 密钥未设置") }),
|
|
3307
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: RSTY.row, children: [
|
|
3308
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.label, children: "端点 URL" }),
|
|
3309
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2916
3310
|
NInput,
|
|
2917
3311
|
{
|
|
2918
3312
|
style: RSTY.input,
|
|
@@ -2929,9 +3323,9 @@ var __defProp = Object.defineProperty;
|
|
|
2929
3323
|
}
|
|
2930
3324
|
)
|
|
2931
3325
|
] }),
|
|
2932
|
-
/* @__PURE__ */ (0,
|
|
2933
|
-
/* @__PURE__ */ (0,
|
|
2934
|
-
/* @__PURE__ */ (0,
|
|
3326
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: RSTY.row, children: [
|
|
3327
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.label, children: "模型名" }),
|
|
3328
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2935
3329
|
NInput,
|
|
2936
3330
|
{
|
|
2937
3331
|
style: RSTY.input,
|
|
@@ -2947,8 +3341,8 @@ var __defProp = Object.defineProperty;
|
|
|
2947
3341
|
}
|
|
2948
3342
|
}
|
|
2949
3343
|
),
|
|
2950
|
-
/* @__PURE__ */ (0,
|
|
2951
|
-
/* @__PURE__ */ (0,
|
|
3344
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.label, children: "维度" }),
|
|
3345
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2952
3346
|
NInput,
|
|
2953
3347
|
{
|
|
2954
3348
|
style: { width: 90, minWidth: 0, flex: "0 1 90px" },
|
|
@@ -2968,9 +3362,9 @@ var __defProp = Object.defineProperty;
|
|
|
2968
3362
|
}
|
|
2969
3363
|
)
|
|
2970
3364
|
] }),
|
|
2971
|
-
/* @__PURE__ */ (0,
|
|
2972
|
-
/* @__PURE__ */ (0,
|
|
2973
|
-
/* @__PURE__ */ (0,
|
|
3365
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: RSTY.row, children: [
|
|
3366
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.label, children: "API Key" }),
|
|
3367
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2974
3368
|
NInput,
|
|
2975
3369
|
{
|
|
2976
3370
|
style: RSTY.input,
|
|
@@ -2985,8 +3379,8 @@ var __defProp = Object.defineProperty;
|
|
|
2985
3379
|
onBlur: commitRemoteKey
|
|
2986
3380
|
}
|
|
2987
3381
|
),
|
|
2988
|
-
remote.apiKeySet ? /* @__PURE__ */ (0,
|
|
2989
|
-
/* @__PURE__ */ (0,
|
|
3382
|
+
remote.apiKeySet ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.chipAccent, children: "已设置" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: RSTY.chipMuted, children: "未设置" }),
|
|
3383
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2990
3384
|
NButton,
|
|
2991
3385
|
{
|
|
2992
3386
|
title: "写入空串清除运行时密钥(部署 YAML 的密钥不受影响)",
|
|
@@ -2996,17 +3390,17 @@ var __defProp = Object.defineProperty;
|
|
|
2996
3390
|
)
|
|
2997
3391
|
] })
|
|
2998
3392
|
] }),
|
|
2999
|
-
/* @__PURE__ */ (0,
|
|
3393
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: S.panelLabel, children: "本地模型目录(下载后离线可用,不随插件分发)" }),
|
|
3000
3394
|
modelCards,
|
|
3001
|
-
/* @__PURE__ */ (0,
|
|
3002
|
-
/* @__PURE__ */ (0,
|
|
3003
|
-
/* @__PURE__ */ (0,
|
|
3004
|
-
/* @__PURE__ */ (0,
|
|
3395
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: RSTY.block, children: [
|
|
3396
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: RSTY.title, children: "向量索引" }),
|
|
3397
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: RSTY.note, children: vecNote }),
|
|
3398
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: RSTY.row, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3005
3399
|
NButton,
|
|
3006
3400
|
{
|
|
3007
3401
|
disabled: !canRebuild,
|
|
3008
3402
|
title: rebuildHint,
|
|
3009
|
-
onClick: () =>
|
|
3403
|
+
onClick: () => call2("dsh-memory/embedding-reindex", {}),
|
|
3010
3404
|
children: "重建索引"
|
|
3011
3405
|
}
|
|
3012
3406
|
) })
|
|
@@ -3015,8 +3409,8 @@ var __defProp = Object.defineProperty;
|
|
|
3015
3409
|
}
|
|
3016
3410
|
|
|
3017
3411
|
// client/src/tabs/RebuildPanel.tsx
|
|
3018
|
-
var
|
|
3019
|
-
var
|
|
3412
|
+
var import_react14 = require("react");
|
|
3413
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3020
3414
|
var RB_PHASE_LABEL = {
|
|
3021
3415
|
preparing: "准备中(归档旧数据 · 清空检索库)",
|
|
3022
3416
|
distilling: "分块蒸馏中",
|
|
@@ -3024,21 +3418,21 @@ var __defProp = Object.defineProperty;
|
|
|
3024
3418
|
};
|
|
3025
3419
|
function RebuildPanel(props) {
|
|
3026
3420
|
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,
|
|
3421
|
+
const [rbRaw, setRb] = (0, import_react14.useState)(null);
|
|
3422
|
+
const [confirmOpen, setConfirmOpen] = (0, import_react14.useState)(false);
|
|
3423
|
+
const [busy, setBusy] = (0, import_react14.useState)(false);
|
|
3424
|
+
const [rbError, setRbError] = (0, import_react14.useState)(null);
|
|
3425
|
+
const refresh = (0, import_react14.useCallback)(() => {
|
|
3032
3426
|
rpc("dsh-memory/rebuild-status", {}).then((r) => {
|
|
3033
3427
|
if (r && r.ok) setRb(r.value);
|
|
3034
3428
|
}).catch(() => {
|
|
3035
3429
|
});
|
|
3036
3430
|
}, [rpc]);
|
|
3037
|
-
(0,
|
|
3431
|
+
(0, import_react14.useEffect)(() => {
|
|
3038
3432
|
refresh();
|
|
3039
3433
|
}, [refresh]);
|
|
3040
3434
|
const running = !!(rbRaw && rbRaw.running);
|
|
3041
|
-
(0,
|
|
3435
|
+
(0, import_react14.useEffect)(() => {
|
|
3042
3436
|
if (!running) return;
|
|
3043
3437
|
const timer = setInterval(refresh, 1500);
|
|
3044
3438
|
return () => {
|
|
@@ -3083,11 +3477,11 @@ var __defProp = Object.defineProperty;
|
|
|
3083
3477
|
} else if (!running && rb.phase === "failed") {
|
|
3084
3478
|
lastNote = "上次重建:失败:" + (rb.error || "未知错误");
|
|
3085
3479
|
}
|
|
3086
|
-
return /* @__PURE__ */ (0,
|
|
3087
|
-
/* @__PURE__ */ (0,
|
|
3088
|
-
/* @__PURE__ */ (0,
|
|
3089
|
-
/* @__PURE__ */ (0,
|
|
3090
|
-
running ? /* @__PURE__ */ (0,
|
|
3480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
3481
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }, children: [
|
|
3482
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 600, whiteSpace: "nowrap" }, children: "重建记忆" }),
|
|
3483
|
+
/* @__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;旧数据先归档(不删除)" }),
|
|
3484
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NButton, { disabled: busy || rb.cancelRequested, onClick: cancel, children: rb.cancelRequested ? "取消中…" : "取消重建" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3091
3485
|
NButton,
|
|
3092
3486
|
{
|
|
3093
3487
|
disabled: busy || empty,
|
|
@@ -3100,13 +3494,13 @@ var __defProp = Object.defineProperty;
|
|
|
3100
3494
|
}
|
|
3101
3495
|
)
|
|
3102
3496
|
] }),
|
|
3103
|
-
running ? /* @__PURE__ */ (0,
|
|
3104
|
-
/* @__PURE__ */ (0,
|
|
3105
|
-
/* @__PURE__ */ (0,
|
|
3497
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, marginTop: 10 }, children: [
|
|
3498
|
+
/* @__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 + "%" } }) }),
|
|
3499
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "dsh-mem-rb-muted", style: { whiteSpace: "nowrap" }, children: "产出 " + rb.recordsBuilt + " 条" })
|
|
3106
3500
|
] }) : null,
|
|
3107
|
-
lastNote ? /* @__PURE__ */ (0,
|
|
3108
|
-
rbError ? /* @__PURE__ */ (0,
|
|
3109
|
-
confirmOpen ? /* @__PURE__ */ (0,
|
|
3501
|
+
lastNote ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: lastNote }) : null,
|
|
3502
|
+
rbError ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: rbError }) : null,
|
|
3503
|
+
confirmOpen ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3110
3504
|
NModal,
|
|
3111
3505
|
{
|
|
3112
3506
|
open: true,
|
|
@@ -3115,7 +3509,7 @@ var __defProp = Object.defineProperty;
|
|
|
3115
3509
|
},
|
|
3116
3510
|
title: "确认重建全部记忆?",
|
|
3117
3511
|
footer: [
|
|
3118
|
-
/* @__PURE__ */ (0,
|
|
3512
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3119
3513
|
NButton,
|
|
3120
3514
|
{
|
|
3121
3515
|
onClick: () => {
|
|
@@ -3125,15 +3519,15 @@ var __defProp = Object.defineProperty;
|
|
|
3125
3519
|
},
|
|
3126
3520
|
"cancel"
|
|
3127
3521
|
),
|
|
3128
|
-
/* @__PURE__ */ (0,
|
|
3522
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NButton, { variant: "primary", disabled: busy, onClick: start, children: busy ? "启动中…" : "开始重建" }, "confirm")
|
|
3129
3523
|
],
|
|
3130
3524
|
children: [
|
|
3131
|
-
/* @__PURE__ */ (0,
|
|
3525
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3132
3526
|
"将以 L0 原始对话为事实源重新蒸馏:",
|
|
3133
|
-
/* @__PURE__ */ (0,
|
|
3527
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("b", { children: rb.sessionCount + " 个会话 · " + rb.messageCount + " 条消息" }),
|
|
3134
3528
|
",预计 ≥" + rb.estCalls + " 次蒸馏调用。"
|
|
3135
3529
|
] }),
|
|
3136
|
-
/* @__PURE__ */ (0,
|
|
3530
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { marginTop: 8 }, children: "现有 L1 记忆 / L2 场景 / L3 画像会整体归档(*.bak.时间戳,可手工找回),随后清空重建;重建期间可正常对话,新对话的蒸馏优先进行;中途可取消,已重建部分保留。" })
|
|
3137
3531
|
]
|
|
3138
3532
|
}
|
|
3139
3533
|
) : null
|
|
@@ -3141,8 +3535,8 @@ var __defProp = Object.defineProperty;
|
|
|
3141
3535
|
}
|
|
3142
3536
|
|
|
3143
3537
|
// client/src/tabs/RuminatePanel.tsx
|
|
3144
|
-
var
|
|
3145
|
-
var
|
|
3538
|
+
var import_react15 = require("react");
|
|
3539
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3146
3540
|
var RM_PHASE_LABEL = {
|
|
3147
3541
|
refreshing: "轻量刷新中",
|
|
3148
3542
|
distilling: "L1 蒸馏中",
|
|
@@ -3163,11 +3557,11 @@ var __defProp = Object.defineProperty;
|
|
|
3163
3557
|
var RM_IDLE_INTERVAL = 3e4;
|
|
3164
3558
|
function RuminatePanel(props) {
|
|
3165
3559
|
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,
|
|
3560
|
+
const [rmRaw, setRm] = (0, import_react15.useState)(null);
|
|
3561
|
+
const [confirmOpen, setConfirmOpen] = (0, import_react15.useState)(false);
|
|
3562
|
+
const [busy, setBusy] = (0, import_react15.useState)(false);
|
|
3563
|
+
const [rmError, setRmError] = (0, import_react15.useState)(null);
|
|
3564
|
+
const refresh = (0, import_react15.useCallback)(() => {
|
|
3171
3565
|
return rpc("dsh-memory/ruminate-status", {}).then((r) => {
|
|
3172
3566
|
if (r && r.ok) {
|
|
3173
3567
|
const st = r.value;
|
|
@@ -3182,14 +3576,14 @@ var __defProp = Object.defineProperty;
|
|
|
3182
3576
|
}).catch(() => {
|
|
3183
3577
|
});
|
|
3184
3578
|
}, [rpc]);
|
|
3185
|
-
const pollRef = (0,
|
|
3186
|
-
const backoffRef = (0,
|
|
3187
|
-
const lastDetailRef = (0,
|
|
3188
|
-
(0,
|
|
3579
|
+
const pollRef = (0, import_react15.useRef)(1500);
|
|
3580
|
+
const backoffRef = (0, import_react15.useRef)(1);
|
|
3581
|
+
const lastDetailRef = (0, import_react15.useRef)(null);
|
|
3582
|
+
(0, import_react15.useEffect)(() => {
|
|
3189
3583
|
refresh();
|
|
3190
3584
|
}, [refresh]);
|
|
3191
3585
|
const running = !!(rmRaw && (rmRaw.running || RM_RUNNING_PHASES.indexOf(rmRaw.phase) >= 0));
|
|
3192
|
-
(0,
|
|
3586
|
+
(0, import_react15.useEffect)(() => {
|
|
3193
3587
|
if (!running) return;
|
|
3194
3588
|
let alive = true;
|
|
3195
3589
|
let timer;
|
|
@@ -3208,13 +3602,13 @@ var __defProp = Object.defineProperty;
|
|
|
3208
3602
|
lastDetailRef.current = null;
|
|
3209
3603
|
};
|
|
3210
3604
|
}, [running, refresh]);
|
|
3211
|
-
(0,
|
|
3605
|
+
(0, import_react15.useEffect)(() => {
|
|
3212
3606
|
if (running) return;
|
|
3213
3607
|
const timer = setInterval(refresh, RM_IDLE_INTERVAL);
|
|
3214
3608
|
return () => clearInterval(timer);
|
|
3215
3609
|
}, [running, refresh]);
|
|
3216
|
-
const [, setTick] = (0,
|
|
3217
|
-
(0,
|
|
3610
|
+
const [, setTick] = (0, import_react15.useState)(0);
|
|
3611
|
+
(0, import_react15.useEffect)(() => {
|
|
3218
3612
|
if (!running) return;
|
|
3219
3613
|
const timer = setInterval(() => setTick((n) => n + 1), 1e3);
|
|
3220
3614
|
return () => clearInterval(timer);
|
|
@@ -3265,11 +3659,11 @@ var __defProp = Object.defineProperty;
|
|
|
3265
3659
|
}
|
|
3266
3660
|
const unit = rm.phase === "refreshing" || rm.phase === "relabeling" ? "步" : "会话";
|
|
3267
3661
|
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,
|
|
3662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "dsh-mem-rb-card", children: [
|
|
3663
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }, children: [
|
|
3664
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { fontWeight: 600, whiteSpace: "nowrap" }, children: "反刍整理" }),
|
|
3665
|
+
/* @__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" }),
|
|
3666
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(NButton, { disabled: busy || rm.cancelRequested, onClick: cancel, children: rm.cancelRequested ? "取消中…" : "取消整理" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3273
3667
|
NButton,
|
|
3274
3668
|
{
|
|
3275
3669
|
disabled: busy,
|
|
@@ -3282,27 +3676,27 @@ var __defProp = Object.defineProperty;
|
|
|
3282
3676
|
}
|
|
3283
3677
|
)
|
|
3284
3678
|
] }),
|
|
3285
|
-
running ? /* @__PURE__ */ (0,
|
|
3286
|
-
/* @__PURE__ */ (0,
|
|
3679
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10, marginTop: 10 }, children: [
|
|
3680
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "dsh-mem-rb-bar", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3287
3681
|
"div",
|
|
3288
3682
|
{
|
|
3289
3683
|
className: "dsh-mem-rb-fill" + (indet ? " dsh-mem-rb-fill-indet" : ""),
|
|
3290
3684
|
style: { width: indet ? "100%" : barPct + "%" }
|
|
3291
3685
|
}
|
|
3292
3686
|
) }),
|
|
3293
|
-
/* @__PURE__ */ (0,
|
|
3687
|
+
/* @__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
3688
|
] }) : null,
|
|
3295
|
-
running && rm.detail ? /* @__PURE__ */ (0,
|
|
3296
|
-
lastNote ? /* @__PURE__ */ (0,
|
|
3297
|
-
rmError ? /* @__PURE__ */ (0,
|
|
3298
|
-
confirmOpen ? /* @__PURE__ */ (0,
|
|
3689
|
+
running && rm.detail ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 6, whiteSpace: "normal" }, children: "当前:" + rm.detail }) : null,
|
|
3690
|
+
lastNote ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "dsh-mem-rb-muted", style: { marginTop: 8 }, children: lastNote }) : null,
|
|
3691
|
+
rmError ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsh-mem-danger)" }, children: rmError }) : null,
|
|
3692
|
+
confirmOpen ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
3299
3693
|
NModal,
|
|
3300
3694
|
{
|
|
3301
3695
|
open: true,
|
|
3302
3696
|
onClose: () => setConfirmOpen(false),
|
|
3303
3697
|
title: "确认反刍整理?",
|
|
3304
3698
|
footer: [
|
|
3305
|
-
/* @__PURE__ */ (0,
|
|
3699
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3306
3700
|
NButton,
|
|
3307
3701
|
{
|
|
3308
3702
|
onClick: () => setConfirmOpen(false),
|
|
@@ -3310,11 +3704,11 @@ var __defProp = Object.defineProperty;
|
|
|
3310
3704
|
},
|
|
3311
3705
|
"cancel"
|
|
3312
3706
|
),
|
|
3313
|
-
/* @__PURE__ */ (0,
|
|
3707
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(NButton, { variant: "primary", disabled: busy, onClick: start, children: busy ? "启动中…" : "反刍整理" }, "confirm")
|
|
3314
3708
|
],
|
|
3315
3709
|
children: [
|
|
3316
|
-
/* @__PURE__ */ (0,
|
|
3317
|
-
/* @__PURE__ */ (0,
|
|
3710
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { children: "将扫描未蒸馏缓冲,按会话逐个跑蒸馏管线,完成后强制 L2 场景整合与 L3 画像更新。" }),
|
|
3711
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { marginTop: 8 }, children: "与重建不同:不清空 L1 检索库、不归档旧产物、不改 L0;仅消化攒而未蒸馏的切片,无缓冲时做轻量 L2/L3 刷新。" })
|
|
3318
3712
|
]
|
|
3319
3713
|
}
|
|
3320
3714
|
) : null
|
|
@@ -3322,13 +3716,13 @@ var __defProp = Object.defineProperty;
|
|
|
3322
3716
|
}
|
|
3323
3717
|
|
|
3324
3718
|
// client/src/tabs/OverviewTab.tsx
|
|
3325
|
-
var
|
|
3719
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3326
3720
|
function OverviewTab(props) {
|
|
3327
3721
|
const rpc = props.rpc;
|
|
3328
|
-
const [stats, setStats] = (0,
|
|
3329
|
-
const [settingsData, setSettingsData] = (0,
|
|
3330
|
-
const [error, setError] = (0,
|
|
3331
|
-
const load = (0,
|
|
3722
|
+
const [stats, setStats] = (0, import_react16.useState)(null);
|
|
3723
|
+
const [settingsData, setSettingsData] = (0, import_react16.useState)(null);
|
|
3724
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
3725
|
+
const load = (0, import_react16.useCallback)(() => {
|
|
3332
3726
|
rpc("dsh-memory/stats", {}).then((r) => {
|
|
3333
3727
|
if (r && r.ok) setStats(r.value);
|
|
3334
3728
|
else setError(r && r.error ? r.error.message : "RPC error");
|
|
@@ -3340,7 +3734,7 @@ var __defProp = Object.defineProperty;
|
|
|
3340
3734
|
}).catch(() => {
|
|
3341
3735
|
});
|
|
3342
3736
|
}, [rpc]);
|
|
3343
|
-
(0,
|
|
3737
|
+
(0, import_react16.useEffect)(() => {
|
|
3344
3738
|
load();
|
|
3345
3739
|
const timer = setInterval(load, 5e3);
|
|
3346
3740
|
return () => {
|
|
@@ -3402,10 +3796,10 @@ var __defProp = Object.defineProperty;
|
|
|
3402
3796
|
const toolConflict = settingsData && settingsData.settings ? settingsData.settings.toolConflict !== false : true;
|
|
3403
3797
|
const toolMutate = settingsData && settingsData.settings ? settingsData.settings.toolMutate !== false : true;
|
|
3404
3798
|
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,
|
|
3799
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
3800
|
+
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: [
|
|
3801
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "记忆模式" }),
|
|
3802
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3409
3803
|
SwitchRow,
|
|
3410
3804
|
{
|
|
3411
3805
|
label: "记忆模式",
|
|
@@ -3416,7 +3810,7 @@ var __defProp = Object.defineProperty;
|
|
|
3416
3810
|
}
|
|
3417
3811
|
}
|
|
3418
3812
|
),
|
|
3419
|
-
/* @__PURE__ */ (0,
|
|
3813
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3420
3814
|
SwitchRow,
|
|
3421
3815
|
{
|
|
3422
3816
|
label: "捕获",
|
|
@@ -3428,7 +3822,7 @@ var __defProp = Object.defineProperty;
|
|
|
3428
3822
|
}
|
|
3429
3823
|
}
|
|
3430
3824
|
),
|
|
3431
|
-
/* @__PURE__ */ (0,
|
|
3825
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3432
3826
|
SwitchRow,
|
|
3433
3827
|
{
|
|
3434
3828
|
label: "蒸馏",
|
|
@@ -3440,7 +3834,7 @@ var __defProp = Object.defineProperty;
|
|
|
3440
3834
|
}
|
|
3441
3835
|
}
|
|
3442
3836
|
),
|
|
3443
|
-
/* @__PURE__ */ (0,
|
|
3837
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3444
3838
|
SwitchRow,
|
|
3445
3839
|
{
|
|
3446
3840
|
label: "召回",
|
|
@@ -3452,8 +3846,8 @@ var __defProp = Object.defineProperty;
|
|
|
3452
3846
|
}
|
|
3453
3847
|
}
|
|
3454
3848
|
),
|
|
3455
|
-
/* @__PURE__ */ (0,
|
|
3456
|
-
/* @__PURE__ */ (0,
|
|
3849
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "高权限模式" }),
|
|
3850
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3457
3851
|
SwitchRow,
|
|
3458
3852
|
{
|
|
3459
3853
|
label: "高权限模式",
|
|
@@ -3464,8 +3858,8 @@ var __defProp = Object.defineProperty;
|
|
|
3464
3858
|
}
|
|
3465
3859
|
}
|
|
3466
3860
|
),
|
|
3467
|
-
/* @__PURE__ */ (0,
|
|
3468
|
-
/* @__PURE__ */ (0,
|
|
3861
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "技能结晶" }),
|
|
3862
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3469
3863
|
SwitchRow,
|
|
3470
3864
|
{
|
|
3471
3865
|
label: "技能(程序性记忆)",
|
|
@@ -3476,8 +3870,8 @@ var __defProp = Object.defineProperty;
|
|
|
3476
3870
|
}
|
|
3477
3871
|
}
|
|
3478
3872
|
),
|
|
3479
|
-
/* @__PURE__ */ (0,
|
|
3480
|
-
/* @__PURE__ */ (0,
|
|
3873
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "工具封印" }),
|
|
3874
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3481
3875
|
SwitchRow,
|
|
3482
3876
|
{
|
|
3483
3877
|
label: "Room 管理工具",
|
|
@@ -3488,7 +3882,7 @@ var __defProp = Object.defineProperty;
|
|
|
3488
3882
|
}
|
|
3489
3883
|
}
|
|
3490
3884
|
),
|
|
3491
|
-
/* @__PURE__ */ (0,
|
|
3885
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3492
3886
|
SwitchRow,
|
|
3493
3887
|
{
|
|
3494
3888
|
label: "图谱工具",
|
|
@@ -3499,7 +3893,7 @@ var __defProp = Object.defineProperty;
|
|
|
3499
3893
|
}
|
|
3500
3894
|
}
|
|
3501
3895
|
),
|
|
3502
|
-
/* @__PURE__ */ (0,
|
|
3896
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3503
3897
|
SwitchRow,
|
|
3504
3898
|
{
|
|
3505
3899
|
label: "反刍工具",
|
|
@@ -3510,7 +3904,7 @@ var __defProp = Object.defineProperty;
|
|
|
3510
3904
|
}
|
|
3511
3905
|
}
|
|
3512
3906
|
),
|
|
3513
|
-
/* @__PURE__ */ (0,
|
|
3907
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3514
3908
|
SwitchRow,
|
|
3515
3909
|
{
|
|
3516
3910
|
label: "冲突工具",
|
|
@@ -3521,7 +3915,7 @@ var __defProp = Object.defineProperty;
|
|
|
3521
3915
|
}
|
|
3522
3916
|
}
|
|
3523
3917
|
),
|
|
3524
|
-
/* @__PURE__ */ (0,
|
|
3918
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3525
3919
|
SwitchRow,
|
|
3526
3920
|
{
|
|
3527
3921
|
label: "写删工具",
|
|
@@ -3532,8 +3926,8 @@ var __defProp = Object.defineProperty;
|
|
|
3532
3926
|
}
|
|
3533
3927
|
}
|
|
3534
3928
|
),
|
|
3535
|
-
/* @__PURE__ */ (0,
|
|
3536
|
-
/* @__PURE__ */ (0,
|
|
3929
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "人工冲突裁决" }),
|
|
3930
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3537
3931
|
SwitchRow,
|
|
3538
3932
|
{
|
|
3539
3933
|
label: "人工冲突裁决",
|
|
@@ -3544,42 +3938,43 @@ var __defProp = Object.defineProperty;
|
|
|
3544
3938
|
}
|
|
3545
3939
|
}
|
|
3546
3940
|
),
|
|
3547
|
-
/* @__PURE__ */ (0,
|
|
3548
|
-
/* @__PURE__ */ (0,
|
|
3549
|
-
ceilingNote ? /* @__PURE__ */ (0,
|
|
3941
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "蒸馏参数" }),
|
|
3942
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DistillSettings, { rpc, disabled: !master, data: settingsData, setData: setSettingsData, onError: setError }),
|
|
3943
|
+
ceilingNote ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { style: S.hint, children: ceilingNote }) : null
|
|
3550
3944
|
] }) : 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,
|
|
3945
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(EmbeddingSection, { rpc }),
|
|
3946
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RebuildPanel, { rpc }),
|
|
3947
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RuminatePanel, { rpc }),
|
|
3948
|
+
degraded ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { ...S.error, marginBottom: 10 }, children: "⚠ " + stats.message + "。上方数据为最后一次成功读取的值,记忆功能当前未工作。" }) : null,
|
|
3949
|
+
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: [
|
|
3950
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "记忆概况" }),
|
|
3951
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.statGrid, children: tiles.map((t) => {
|
|
3952
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "dsh-mem-card", style: S.statTile, children: [
|
|
3953
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.statNum, children: t.num }),
|
|
3954
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.statLabel, children: t.label })
|
|
3561
3955
|
] }, t.label);
|
|
3562
3956
|
}) }),
|
|
3563
|
-
/* @__PURE__ */ (0,
|
|
3957
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.panelLabel, children: "运行状态" }),
|
|
3564
3958
|
infos.map((row2) => {
|
|
3565
|
-
return /* @__PURE__ */ (0,
|
|
3566
|
-
/* @__PURE__ */ (0,
|
|
3567
|
-
/* @__PURE__ */ (0,
|
|
3959
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: S.infoRow, children: [
|
|
3960
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.infoKey, children: row2[0] }),
|
|
3961
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.infoVal, children: row2[1] })
|
|
3568
3962
|
] }, row2[0]);
|
|
3569
3963
|
})
|
|
3570
3964
|
] }),
|
|
3571
|
-
/* @__PURE__ */ (0,
|
|
3965
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ArchiveSection, { rpc }),
|
|
3966
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { style: S.hint, children: "浏览各层记忆内容请切换上方 Tab;原始对话(L0)不入浏览器,可由模型侧 conversation_search 工具查询。" })
|
|
3572
3967
|
] });
|
|
3573
3968
|
}
|
|
3574
3969
|
|
|
3575
3970
|
// client/src/tabs/PersonaTab.tsx
|
|
3576
|
-
var
|
|
3577
|
-
var
|
|
3971
|
+
var import_react17 = require("react");
|
|
3972
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3578
3973
|
function PersonaTab(props) {
|
|
3579
3974
|
const rpc = props.rpc;
|
|
3580
|
-
const [content, setContent] = (0,
|
|
3581
|
-
const [error, setError] = (0,
|
|
3582
|
-
const load = (0,
|
|
3975
|
+
const [content, setContent] = (0, import_react17.useState)(null);
|
|
3976
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
3977
|
+
const load = (0, import_react17.useCallback)(() => {
|
|
3583
3978
|
setError(null);
|
|
3584
3979
|
rpc("dsh-memory/persona", {}).then((r) => {
|
|
3585
3980
|
if (r && r.ok) setContent(r.value.content);
|
|
@@ -3588,64 +3983,55 @@ var __defProp = Object.defineProperty;
|
|
|
3588
3983
|
setError(String(e && e.message || e));
|
|
3589
3984
|
});
|
|
3590
3985
|
}, [rpc]);
|
|
3591
|
-
(0,
|
|
3986
|
+
(0, import_react17.useEffect)(() => {
|
|
3592
3987
|
load();
|
|
3593
3988
|
}, [load]);
|
|
3594
|
-
return /* @__PURE__ */ (0,
|
|
3595
|
-
/* @__PURE__ */ (0,
|
|
3596
|
-
/* @__PURE__ */ (0,
|
|
3597
|
-
/* @__PURE__ */ (0,
|
|
3598
|
-
/* @__PURE__ */ (0,
|
|
3989
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
|
|
3990
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
3991
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: S.muted, children: error ? "加载失败" : content === null ? "加载中…" : content ? content.length + " 字符" : "未生成画像" }),
|
|
3992
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.grow }),
|
|
3993
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
3599
3994
|
] }),
|
|
3600
|
-
error ? /* @__PURE__ */ (0,
|
|
3601
|
-
content ? /* @__PURE__ */ (0,
|
|
3995
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { ...S.error, marginBottom: 10 }, children: "画像读取失败:" + error + "(点右上“刷新”重试)" }) : null,
|
|
3996
|
+
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
3997
|
] });
|
|
3603
3998
|
}
|
|
3604
3999
|
|
|
3605
4000
|
// client/src/tabs/RecordsTab.tsx
|
|
3606
|
-
var
|
|
3607
|
-
var
|
|
4001
|
+
var import_react18 = require("react");
|
|
4002
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3608
4003
|
function retiredSelOf(r) {
|
|
3609
4004
|
if (r === "active") return false;
|
|
3610
4005
|
if (r === "retired") return true;
|
|
3611
4006
|
return void 0;
|
|
3612
4007
|
}
|
|
3613
|
-
var TYPE_CHOICES = [
|
|
3614
|
-
"persona",
|
|
3615
|
-
"episodic",
|
|
3616
|
-
"instruction",
|
|
3617
|
-
"work_fact",
|
|
3618
|
-
"work_task",
|
|
3619
|
-
"work_method",
|
|
3620
|
-
"work_artifact"
|
|
3621
|
-
];
|
|
3622
4008
|
var DELETE_LIMIT = 200;
|
|
3623
4009
|
function RecordsTab(props) {
|
|
3624
4010
|
const rpc = props.rpc;
|
|
3625
4011
|
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,
|
|
4012
|
+
const [items, setItems] = (0, import_react18.useState)([]);
|
|
4013
|
+
const [hasMore, setHasMore] = (0, import_react18.useState)(false);
|
|
4014
|
+
const [total, setTotal] = (0, import_react18.useState)(null);
|
|
4015
|
+
const [sceneOptions, setSceneOptions] = (0, import_react18.useState)([]);
|
|
4016
|
+
const [loading, setLoading] = (0, import_react18.useState)(false);
|
|
4017
|
+
const [truncated, setTruncated] = (0, import_react18.useState)(false);
|
|
4018
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
4019
|
+
const [expandedId, setExpandedId] = (0, import_react18.useState)(null);
|
|
4020
|
+
const [sel, setSel] = (0, import_react18.useState)(/* @__PURE__ */ new Set());
|
|
4021
|
+
const [hiPriv, setHiPriv] = (0, import_react18.useState)(false);
|
|
4022
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react18.useState)(false);
|
|
4023
|
+
const [query, setQuery] = (0, import_react18.useState)("");
|
|
4024
|
+
const [typeFilter, setTypeFilter] = (0, import_react18.useState)("");
|
|
4025
|
+
const [sceneFilter, setSceneFilter] = (0, import_react18.useState)("");
|
|
4026
|
+
const [hallFilter, setHallFilter] = (0, import_react18.useState)([]);
|
|
4027
|
+
const [tagFilter, setTagFilter] = (0, import_react18.useState)("");
|
|
4028
|
+
const [untaggedOnly, setUntaggedOnly] = (0, import_react18.useState)(false);
|
|
4029
|
+
const [orphanCount, setOrphanCount] = (0, import_react18.useState)(0);
|
|
4030
|
+
const [retiredFilter, setRetiredFilter] = (0, import_react18.useState)("");
|
|
4031
|
+
const [wingCatalog, setHallCatalog] = (0, import_react18.useState)(null);
|
|
4032
|
+
const [last, setLast] = (0, import_react18.useState)({ query: "", type: "", scene: "", halls: [], tag: "", untagged: false, retired: "" });
|
|
4033
|
+
const seqRef = (0, import_react18.useRef)(0);
|
|
4034
|
+
const fetchPage = (0, import_react18.useCallback)(
|
|
3649
4035
|
(conds, offset, append) => {
|
|
3650
4036
|
setLoading(true);
|
|
3651
4037
|
setError(null);
|
|
@@ -3675,6 +4061,7 @@ var __defProp = Object.defineProperty;
|
|
|
3675
4061
|
setTruncated(!!v.truncated);
|
|
3676
4062
|
if (v.scenes) setSceneOptions(v.scenes);
|
|
3677
4063
|
if (v.wingCatalog) setHallCatalog(v.wingCatalog);
|
|
4064
|
+
if (v.typeCatalog) registerTypeCatalog(v.typeCatalog);
|
|
3678
4065
|
}).catch((e) => {
|
|
3679
4066
|
if (token !== seqRef.current) return;
|
|
3680
4067
|
setLoading(false);
|
|
@@ -3694,23 +4081,23 @@ var __defProp = Object.defineProperty;
|
|
|
3694
4081
|
setLast(conds);
|
|
3695
4082
|
fetchPage(conds, 0, false);
|
|
3696
4083
|
};
|
|
3697
|
-
const loadRooms = (0,
|
|
4084
|
+
const loadRooms = (0, import_react18.useCallback)(() => {
|
|
3698
4085
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
3699
4086
|
if (r && r.ok) setOrphanCount(r.value.orphanCount ?? 0);
|
|
3700
4087
|
}).catch(() => {
|
|
3701
4088
|
});
|
|
3702
4089
|
}, [rpc]);
|
|
3703
|
-
(0,
|
|
4090
|
+
(0, import_react18.useEffect)(() => {
|
|
3704
4091
|
fetchPage({ query: "", type: "", scene: "", halls: [], tag: "", untagged: false, retired: "" }, 0, false);
|
|
3705
4092
|
loadRooms();
|
|
3706
4093
|
}, [fetchPage, loadRooms]);
|
|
3707
|
-
const loadHiPriv = (0,
|
|
4094
|
+
const loadHiPriv = (0, import_react18.useCallback)(() => {
|
|
3708
4095
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
3709
4096
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
3710
4097
|
}).catch(() => {
|
|
3711
4098
|
});
|
|
3712
4099
|
}, [rpc]);
|
|
3713
|
-
(0,
|
|
4100
|
+
(0, import_react18.useEffect)(() => {
|
|
3714
4101
|
loadHiPriv();
|
|
3715
4102
|
}, [loadHiPriv]);
|
|
3716
4103
|
const toggleHiPriv = () => {
|
|
@@ -3751,7 +4138,9 @@ var __defProp = Object.defineProperty;
|
|
|
3751
4138
|
if (r && r.ok) {
|
|
3752
4139
|
setSel(/* @__PURE__ */ new Set());
|
|
3753
4140
|
if (expandedId && ids.indexOf(expandedId) >= 0) setExpandedId(null);
|
|
3754
|
-
|
|
4141
|
+
const removed = r.value?.deleted ?? ids.length;
|
|
4142
|
+
setItems((prev) => prev.filter((m) => !ids.includes(m.id)));
|
|
4143
|
+
setTotal((t) => t === null ? null : Math.max(0, t - removed));
|
|
3755
4144
|
if (showRetired) loadRetired();
|
|
3756
4145
|
} else if (r) setError(r.error ? r.error.message : "退场失败");
|
|
3757
4146
|
}).catch((e) => setError(String(e && e.message || e)));
|
|
@@ -3766,16 +4155,17 @@ var __defProp = Object.defineProperty;
|
|
|
3766
4155
|
return next;
|
|
3767
4156
|
});
|
|
3768
4157
|
if (expandedId === id) setExpandedId(null);
|
|
3769
|
-
|
|
4158
|
+
setItems((prev) => prev.filter((m) => m.id !== id));
|
|
4159
|
+
setTotal((t) => t === null ? null : Math.max(0, t - 1));
|
|
3770
4160
|
if (showRetired) loadRetired();
|
|
3771
4161
|
} else if (r) setError(r.error ? r.error.message : "退场失败");
|
|
3772
4162
|
}).catch((e) => setError(String(e && e.message || e)));
|
|
3773
4163
|
};
|
|
3774
|
-
const [retired, setRetired] = (0,
|
|
3775
|
-
const [retiredTotal, setRetiredTotal] = (0,
|
|
3776
|
-
const [showRetired, setShowRetired] = (0,
|
|
3777
|
-
const [retiredBusy, setRetiredBusy] = (0,
|
|
3778
|
-
const loadRetired = (0,
|
|
4164
|
+
const [retired, setRetired] = (0, import_react18.useState)([]);
|
|
4165
|
+
const [retiredTotal, setRetiredTotal] = (0, import_react18.useState)(0);
|
|
4166
|
+
const [showRetired, setShowRetired] = (0, import_react18.useState)(false);
|
|
4167
|
+
const [retiredBusy, setRetiredBusy] = (0, import_react18.useState)(false);
|
|
4168
|
+
const loadRetired = (0, import_react18.useCallback)(() => {
|
|
3779
4169
|
setRetiredBusy(true);
|
|
3780
4170
|
rpc("dsh-memory/records-retired", { limit: 100, offset: 0 }).then((r) => {
|
|
3781
4171
|
if (r && r.ok) {
|
|
@@ -3784,7 +4174,7 @@ var __defProp = Object.defineProperty;
|
|
|
3784
4174
|
} else if (r) setError(r.error ? r.error.message : "已退场列表加载失败");
|
|
3785
4175
|
}).catch((e) => setError(String(e && e.message || e))).finally(() => setRetiredBusy(false));
|
|
3786
4176
|
}, [rpc]);
|
|
3787
|
-
(0,
|
|
4177
|
+
(0, import_react18.useEffect)(() => {
|
|
3788
4178
|
if (showRetired) loadRetired();
|
|
3789
4179
|
}, [showRetired, loadRetired]);
|
|
3790
4180
|
const restoreRecords = (ids) => {
|
|
@@ -3793,7 +4183,10 @@ var __defProp = Object.defineProperty;
|
|
|
3793
4183
|
rpc("dsh-memory/records-restore", { ids }).then((r) => {
|
|
3794
4184
|
if (r && r.ok) {
|
|
3795
4185
|
loadRetired();
|
|
3796
|
-
|
|
4186
|
+
const restored = new Set(ids);
|
|
4187
|
+
setItems(
|
|
4188
|
+
(prev) => prev.map((m) => restored.has(m.id) ? { ...m, retired: false, retiredReason: void 0 } : m)
|
|
4189
|
+
);
|
|
3797
4190
|
} else if (r) setError(r.error ? r.error.message : "恢复失败");
|
|
3798
4191
|
}).catch((e) => setError(String(e && e.message || e))).finally(() => setRetiredBusy(false));
|
|
3799
4192
|
};
|
|
@@ -3801,14 +4194,15 @@ var __defProp = Object.defineProperty;
|
|
|
3801
4194
|
conflict: "裁决退场",
|
|
3802
4195
|
superseded: "被取代",
|
|
3803
4196
|
manual: "人工退场",
|
|
4197
|
+
obsolete: "声明过时",
|
|
3804
4198
|
unknown: "已退场"
|
|
3805
4199
|
};
|
|
3806
4200
|
const countText = total !== null ? "共 " + total + " 条" : items.length + " 条" + (hasMore ? "+" : "");
|
|
3807
|
-
const [usageSummary, setUsageSummary] = (0,
|
|
4201
|
+
const [usageSummary, setUsageSummary] = (0, import_react18.useState)(null);
|
|
3808
4202
|
const selCount = sel.size;
|
|
3809
|
-
return /* @__PURE__ */ (0,
|
|
3810
|
-
/* @__PURE__ */ (0,
|
|
3811
|
-
/* @__PURE__ */ (0,
|
|
4203
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
|
|
4204
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: S.toolbar, children: [
|
|
4205
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3812
4206
|
NInput,
|
|
3813
4207
|
{
|
|
3814
4208
|
style: { flex: 1, minWidth: 160 },
|
|
@@ -3819,23 +4213,32 @@ var __defProp = Object.defineProperty;
|
|
|
3819
4213
|
},
|
|
3820
4214
|
onKeyDown: (e) => {
|
|
3821
4215
|
if (e.key === "Enter") search();
|
|
4216
|
+
else if (e.key === "Escape" || e.key === "Backspace" && (e.ctrlKey || e.metaKey)) {
|
|
4217
|
+
if (query.length > 0) {
|
|
4218
|
+
e.preventDefault();
|
|
4219
|
+
setQuery("");
|
|
4220
|
+
const conds = { query: "", type: typeFilter, scene: sceneFilter, halls: hallFilter, tag: tagFilter, untagged: untaggedOnly, retired: retiredFilter };
|
|
4221
|
+
setLast(conds);
|
|
4222
|
+
fetchPage(conds, 0, false);
|
|
4223
|
+
}
|
|
4224
|
+
}
|
|
3822
4225
|
}
|
|
3823
4226
|
}
|
|
3824
4227
|
),
|
|
3825
|
-
/* @__PURE__ */ (0,
|
|
4228
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3826
4229
|
NSel,
|
|
3827
4230
|
{
|
|
3828
4231
|
style: { maxWidth: 200 },
|
|
3829
4232
|
options: [{ id: "", label: "全部类型" }].concat(
|
|
3830
|
-
|
|
3831
|
-
return { id: t, label:
|
|
4233
|
+
(typeCatalogIds().length > 0 ? typeCatalogIds() : [...new Set(items.map((m) => m.type))]).map((t) => {
|
|
4234
|
+
return { id: t, label: typeLabel(t) };
|
|
3832
4235
|
})
|
|
3833
4236
|
),
|
|
3834
4237
|
value: typeFilter,
|
|
3835
4238
|
onChange: setTypeFilter
|
|
3836
4239
|
}
|
|
3837
4240
|
),
|
|
3838
|
-
/* @__PURE__ */ (0,
|
|
4241
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3839
4242
|
NSel,
|
|
3840
4243
|
{
|
|
3841
4244
|
style: { maxWidth: 220 },
|
|
@@ -3848,7 +4251,7 @@ var __defProp = Object.defineProperty;
|
|
|
3848
4251
|
onChange: setSceneFilter
|
|
3849
4252
|
}
|
|
3850
4253
|
),
|
|
3851
|
-
/* @__PURE__ */ (0,
|
|
4254
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3852
4255
|
WingMultiSelect,
|
|
3853
4256
|
{
|
|
3854
4257
|
options: wingCatalog ?? Array.from(new Set(items.map((m) => m.hall).filter((h) => !!h))).map((id) => ({ id, label: id })),
|
|
@@ -3856,8 +4259,8 @@ var __defProp = Object.defineProperty;
|
|
|
3856
4259
|
onChange: setHallFilter
|
|
3857
4260
|
}
|
|
3858
4261
|
),
|
|
3859
|
-
/* @__PURE__ */ (0,
|
|
3860
|
-
/* @__PURE__ */ (0,
|
|
4262
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(NButton, { onClick: search, children: "搜索" }),
|
|
4263
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3861
4264
|
NButton,
|
|
3862
4265
|
{
|
|
3863
4266
|
style: {
|
|
@@ -3871,8 +4274,8 @@ var __defProp = Object.defineProperty;
|
|
|
3871
4274
|
}
|
|
3872
4275
|
)
|
|
3873
4276
|
] }),
|
|
3874
|
-
/* @__PURE__ */ (0,
|
|
3875
|
-
/* @__PURE__ */ (0,
|
|
4277
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { marginBottom: 10, display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: [
|
|
4278
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3876
4279
|
"button",
|
|
3877
4280
|
{
|
|
3878
4281
|
type: "button",
|
|
@@ -3897,10 +4300,10 @@ var __defProp = Object.defineProperty;
|
|
|
3897
4300
|
children: "无绑定 · " + orphanCount
|
|
3898
4301
|
}
|
|
3899
4302
|
),
|
|
3900
|
-
(tagFilter || untaggedOnly) && /* @__PURE__ */ (0,
|
|
4303
|
+
(tagFilter || untaggedOnly) && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { style: S.muted, children: [
|
|
3901
4304
|
"筛选中:",
|
|
3902
4305
|
untaggedOnly ? "无绑定" : tagFilter,
|
|
3903
|
-
/* @__PURE__ */ (0,
|
|
4306
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3904
4307
|
"button",
|
|
3905
4308
|
{
|
|
3906
4309
|
type: "button",
|
|
@@ -3917,7 +4320,7 @@ var __defProp = Object.defineProperty;
|
|
|
3917
4320
|
}
|
|
3918
4321
|
)
|
|
3919
4322
|
] }),
|
|
3920
|
-
/* @__PURE__ */ (0,
|
|
4323
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3921
4324
|
"button",
|
|
3922
4325
|
{
|
|
3923
4326
|
type: "button",
|
|
@@ -3946,15 +4349,15 @@ var __defProp = Object.defineProperty;
|
|
|
3946
4349
|
children: "导出孤儿"
|
|
3947
4350
|
}
|
|
3948
4351
|
),
|
|
3949
|
-
/* @__PURE__ */ (0,
|
|
4352
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "Room 标签/分类管理:见「Hall」「Room」标签页。" })
|
|
3950
4353
|
] }),
|
|
3951
|
-
/* @__PURE__ */ (0,
|
|
3952
|
-
/* @__PURE__ */ (0,
|
|
3953
|
-
usageSummary ? /* @__PURE__ */ (0,
|
|
3954
|
-
/* @__PURE__ */ (0,
|
|
4354
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
4355
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: loading ? "加载中…" : countText }),
|
|
4356
|
+
usageSummary ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, title: "老化权重效果口径:参与召回尝试的记忆中,进 topN(被注入上下文)的比例", children: "召回使用 " + usageSummary.used + "/" + usageSummary.attempted + "(" + usageSummary.rate + "%)" }) : null,
|
|
4357
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "退场筛查" }),
|
|
3955
4358
|
[["", "全部"], ["active", "仅活跃"], ["retired", "仅退场"]].map(([val, label]) => {
|
|
3956
4359
|
const on = retiredFilter === val;
|
|
3957
|
-
return /* @__PURE__ */ (0,
|
|
4360
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3958
4361
|
"button",
|
|
3959
4362
|
{
|
|
3960
4363
|
type: "button",
|
|
@@ -3974,7 +4377,7 @@ var __defProp = Object.defineProperty;
|
|
|
3974
4377
|
val
|
|
3975
4378
|
);
|
|
3976
4379
|
}),
|
|
3977
|
-
/* @__PURE__ */ (0,
|
|
4380
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3978
4381
|
NButton,
|
|
3979
4382
|
{
|
|
3980
4383
|
style: selCount > 0 ? { color: "var(--dsh-mem-danger)" } : void 0,
|
|
@@ -3984,7 +4387,7 @@ var __defProp = Object.defineProperty;
|
|
|
3984
4387
|
children: "删除选中" + (selCount > 0 ? "(" + selCount + ")" : "")
|
|
3985
4388
|
}
|
|
3986
4389
|
),
|
|
3987
|
-
selCount > 0 ? /* @__PURE__ */ (0,
|
|
4390
|
+
selCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3988
4391
|
NButton,
|
|
3989
4392
|
{
|
|
3990
4393
|
onClick: () => {
|
|
@@ -3993,8 +4396,8 @@ var __defProp = Object.defineProperty;
|
|
|
3993
4396
|
children: "清空选择"
|
|
3994
4397
|
}
|
|
3995
4398
|
) : null,
|
|
3996
|
-
/* @__PURE__ */ (0,
|
|
3997
|
-
/* @__PURE__ */ (0,
|
|
4399
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
|
|
4400
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3998
4401
|
NButton,
|
|
3999
4402
|
{
|
|
4000
4403
|
onClick: () => {
|
|
@@ -4005,13 +4408,13 @@ var __defProp = Object.defineProperty;
|
|
|
4005
4408
|
}
|
|
4006
4409
|
)
|
|
4007
4410
|
] }),
|
|
4008
|
-
!hiPriv ? /* @__PURE__ */ (0,
|
|
4009
|
-
error ? /* @__PURE__ */ (0,
|
|
4010
|
-
truncated ? /* @__PURE__ */ (0,
|
|
4011
|
-
items.length === 0 && !loading && !error ? /* @__PURE__ */ (0,
|
|
4411
|
+
!hiPriv ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.hint, children: "提示:删除记忆需先开启高权限模式(右上开关或概览页「高权限模式」),关闭时删除按钮不可用。" }) : null,
|
|
4412
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.error, children: error }) : null,
|
|
4413
|
+
truncated ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.hint, children: "搜索分页已达检索上限(200 条),更早的结果未显示。请用更精确的关键词或类型/情境过滤。" }) : null,
|
|
4414
|
+
items.length === 0 && !loading && !error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: S.intro, children: "暂无记忆。对话几轮后,蒸馏管线会自动抽取记忆。" }) : items.map((m) => {
|
|
4012
4415
|
const open = expandedId === m.id;
|
|
4013
4416
|
const checked = sel.has(m.id);
|
|
4014
|
-
return /* @__PURE__ */ (0,
|
|
4417
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4015
4418
|
"div",
|
|
4016
4419
|
{
|
|
4017
4420
|
className: "dsh-mem-card dsh-mem-card-hover",
|
|
@@ -4020,8 +4423,8 @@ var __defProp = Object.defineProperty;
|
|
|
4020
4423
|
setExpandedId(open ? null : m.id);
|
|
4021
4424
|
},
|
|
4022
4425
|
children: [
|
|
4023
|
-
/* @__PURE__ */ (0,
|
|
4024
|
-
/* @__PURE__ */ (0,
|
|
4426
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: S.cardHead, children: [
|
|
4427
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4025
4428
|
"input",
|
|
4026
4429
|
{
|
|
4027
4430
|
type: "checkbox",
|
|
@@ -4036,9 +4439,9 @@ var __defProp = Object.defineProperty;
|
|
|
4036
4439
|
}
|
|
4037
4440
|
}
|
|
4038
4441
|
),
|
|
4039
|
-
/* @__PURE__ */ (0,
|
|
4040
|
-
m.hall ? /* @__PURE__ */ (0,
|
|
4041
|
-
m.retired ? /* @__PURE__ */ (0,
|
|
4442
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: tagClass(m.type), children: typeLabel(m.type) }),
|
|
4443
|
+
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,
|
|
4444
|
+
m.retired ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4042
4445
|
"span",
|
|
4043
4446
|
{
|
|
4044
4447
|
title: "该记忆已退场(软删):移出检索面但仍可恢复,并未真正删除",
|
|
@@ -4053,8 +4456,8 @@ var __defProp = Object.defineProperty;
|
|
|
4053
4456
|
children: "已退场" + (m.retiredReason ? " · " + (RETIRE_REASON_LABEL[m.retiredReason] || m.retiredReason) : "")
|
|
4054
4457
|
}
|
|
4055
4458
|
) : null,
|
|
4056
|
-
/* @__PURE__ */ (0,
|
|
4057
|
-
m.maturity ? /* @__PURE__ */ (0,
|
|
4459
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "优先级 " + m.priority }),
|
|
4460
|
+
m.maturity ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4058
4461
|
"span",
|
|
4059
4462
|
{
|
|
4060
4463
|
title: "成熟度(优先级 + 被用次数 + 新鲜度合成):" + m.maturity,
|
|
@@ -4069,7 +4472,7 @@ var __defProp = Object.defineProperty;
|
|
|
4069
4472
|
children: m.maturity === "high" ? "成熟·高" : m.maturity === "mid" ? "成熟·中" : "成熟·低"
|
|
4070
4473
|
}
|
|
4071
4474
|
) : null,
|
|
4072
|
-
m.agingWeight != null ? /* @__PURE__ */ (0,
|
|
4475
|
+
m.agingWeight != null ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4073
4476
|
"span",
|
|
4074
4477
|
{
|
|
4075
4478
|
style: {
|
|
@@ -4084,7 +4487,7 @@ var __defProp = Object.defineProperty;
|
|
|
4084
4487
|
children: "老化 " + Math.round(m.agingWeight * 100) + "%"
|
|
4085
4488
|
}
|
|
4086
4489
|
) : null,
|
|
4087
|
-
m.usage ? /* @__PURE__ */ (0,
|
|
4490
|
+
m.usage ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4088
4491
|
"span",
|
|
4089
4492
|
{
|
|
4090
4493
|
style: S.muted,
|
|
@@ -4092,10 +4495,10 @@ var __defProp = Object.defineProperty;
|
|
|
4092
4495
|
children: "用 " + m.usage.used + "/" + m.usage.attempts
|
|
4093
4496
|
}
|
|
4094
4497
|
) : null,
|
|
4095
|
-
m.score !== null && m.score !== void 0 ? /* @__PURE__ */ (0,
|
|
4096
|
-
/* @__PURE__ */ (0,
|
|
4097
|
-
/* @__PURE__ */ (0,
|
|
4098
|
-
m.retired ? /* @__PURE__ */ (0,
|
|
4498
|
+
m.score !== null && m.score !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "相关度 " + Number(m.score).toFixed(2) }) : null,
|
|
4499
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
|
|
4500
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: fmtTime(m.updatedAt) }),
|
|
4501
|
+
m.retired ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4099
4502
|
NButton,
|
|
4100
4503
|
{
|
|
4101
4504
|
style: { padding: "0 7px", minWidth: 26, height: 26, fontSize: 12, color: "var(--dsh-mem-accent)" },
|
|
@@ -4106,7 +4509,7 @@ var __defProp = Object.defineProperty;
|
|
|
4106
4509
|
},
|
|
4107
4510
|
children: "恢复"
|
|
4108
4511
|
}
|
|
4109
|
-
) : hiPriv ? /* @__PURE__ */ (0,
|
|
4512
|
+
) : hiPriv ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4110
4513
|
NButton,
|
|
4111
4514
|
{
|
|
4112
4515
|
style: { padding: "0 7px", minWidth: 26, height: 26, fontSize: 12, color: "var(--dsh-mem-danger)" },
|
|
@@ -4119,34 +4522,34 @@ var __defProp = Object.defineProperty;
|
|
|
4119
4522
|
}
|
|
4120
4523
|
) : null
|
|
4121
4524
|
] }),
|
|
4122
|
-
/* @__PURE__ */ (0,
|
|
4123
|
-
open ? /* @__PURE__ */ (0,
|
|
4525
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.content, children: m.content }),
|
|
4526
|
+
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
4527
|
]
|
|
4125
4528
|
},
|
|
4126
4529
|
m.id
|
|
4127
4530
|
);
|
|
4128
4531
|
}),
|
|
4129
|
-
/* @__PURE__ */ (0,
|
|
4130
|
-
/* @__PURE__ */ (0,
|
|
4131
|
-
showRetired && retiredBusy ? /* @__PURE__ */ (0,
|
|
4132
|
-
showRetired && !retiredBusy && retiredTotal > 0 ? /* @__PURE__ */ (0,
|
|
4532
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { ...S.flexRow, marginTop: 12 }, children: [
|
|
4533
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(NButton, { onClick: () => setShowRetired((v) => !v), children: (showRetired ? "收起" : "展开") + "「已退场」(可恢复)" }),
|
|
4534
|
+
showRetired && retiredBusy ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "加载中…" }) : null,
|
|
4535
|
+
showRetired && !retiredBusy && retiredTotal > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "共 " + retiredTotal + " 条可恢复" }) : null
|
|
4133
4536
|
] }),
|
|
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,
|
|
4537
|
+
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: [
|
|
4538
|
+
retired.map((m) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "dsh-mem-card", style: S.card, children: [
|
|
4539
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: S.cardHead, children: [
|
|
4540
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: RETIRE_REASON_LABEL[m.retiredReason] || m.retiredReason }),
|
|
4541
|
+
m.verdict ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "结论 " + m.verdict }) : null,
|
|
4542
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
|
|
4543
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: fmtTime(m.retiredAt) }),
|
|
4544
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(NButton, { disabled: retiredBusy, title: "恢复到检索面", onClick: () => restoreRecords([m.id]), children: "恢复" })
|
|
4142
4545
|
] }),
|
|
4143
|
-
/* @__PURE__ */ (0,
|
|
4546
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.content, children: m.content })
|
|
4144
4547
|
] }, m.id)),
|
|
4145
|
-
retiredTotal > retired.length ? /* @__PURE__ */ (0,
|
|
4548
|
+
retiredTotal > retired.length ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: S.hint, children: "共 " + retiredTotal + " 条,此处显示 " + retired.length + " 条" }) : null
|
|
4146
4549
|
] }) }) : null,
|
|
4147
|
-
hasMore ? /* @__PURE__ */ (0,
|
|
4148
|
-
/* @__PURE__ */ (0,
|
|
4149
|
-
/* @__PURE__ */ (0,
|
|
4550
|
+
hasMore ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: S.flexRow, children: [
|
|
4551
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
|
|
4552
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4150
4553
|
NButton,
|
|
4151
4554
|
{
|
|
4152
4555
|
disabled: loading,
|
|
@@ -4160,9 +4563,9 @@ var __defProp = Object.defineProperty;
|
|
|
4160
4563
|
] });
|
|
4161
4564
|
}
|
|
4162
4565
|
function WingMultiSelect(props) {
|
|
4163
|
-
const [open, setOpen] = (0,
|
|
4164
|
-
const wrapRef = (0,
|
|
4165
|
-
(0,
|
|
4566
|
+
const [open, setOpen] = (0, import_react18.useState)(false);
|
|
4567
|
+
const wrapRef = (0, import_react18.useRef)(null);
|
|
4568
|
+
(0, import_react18.useEffect)(() => {
|
|
4166
4569
|
if (!open) return;
|
|
4167
4570
|
const onDown = (e) => {
|
|
4168
4571
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -4182,8 +4585,8 @@ var __defProp = Object.defineProperty;
|
|
|
4182
4585
|
const toggle = (id) => {
|
|
4183
4586
|
props.onChange(props.selected.includes(id) ? props.selected.filter((x) => x !== id) : [...props.selected, id]);
|
|
4184
4587
|
};
|
|
4185
|
-
return /* @__PURE__ */ (0,
|
|
4186
|
-
/* @__PURE__ */ (0,
|
|
4588
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { ref: wrapRef, style: { position: "relative", maxWidth: 150 }, children: [
|
|
4589
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4187
4590
|
"button",
|
|
4188
4591
|
{
|
|
4189
4592
|
type: "button",
|
|
@@ -4192,31 +4595,31 @@ var __defProp = Object.defineProperty;
|
|
|
4192
4595
|
"aria-expanded": open,
|
|
4193
4596
|
onClick: () => setOpen(!open),
|
|
4194
4597
|
children: [
|
|
4195
|
-
/* @__PURE__ */ (0,
|
|
4196
|
-
/* @__PURE__ */ (0,
|
|
4598
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-select-label", title: summary, children: summary }),
|
|
4599
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-sel-chev" + (open ? " dsh-mem-sel-chev-open" : "") })
|
|
4197
4600
|
]
|
|
4198
4601
|
}
|
|
4199
4602
|
),
|
|
4200
|
-
open ? /* @__PURE__ */ (0,
|
|
4201
|
-
props.options.length === 0 ? /* @__PURE__ */ (0,
|
|
4603
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "dsh-mem-pop", role: "listbox", style: { left: 0, right: "auto", minWidth: 150 }, children: [
|
|
4604
|
+
props.options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "dsh-mem-pop-empty", children: "暂无可筛 Hall" }) : null,
|
|
4202
4605
|
props.options.map((o) => {
|
|
4203
4606
|
const active = props.selected.includes(o.id);
|
|
4204
|
-
return /* @__PURE__ */ (0,
|
|
4205
|
-
/* @__PURE__ */ (0,
|
|
4206
|
-
/* @__PURE__ */ (0,
|
|
4607
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("button", { type: "button", className: "dsh-mem-pop-opt", onClick: () => toggle(o.id), "aria-selected": active, children: [
|
|
4608
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-pop-check", children: active ? "✓" : "" }),
|
|
4609
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-pop-label", children: o.label })
|
|
4207
4610
|
] }, o.id);
|
|
4208
4611
|
}),
|
|
4209
|
-
props.selected.length > 0 ? /* @__PURE__ */ (0,
|
|
4210
|
-
/* @__PURE__ */ (0,
|
|
4211
|
-
/* @__PURE__ */ (0,
|
|
4612
|
+
props.selected.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("button", { type: "button", className: "dsh-mem-pop-opt", onClick: () => props.onChange([]), children: [
|
|
4613
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-pop-check" }),
|
|
4614
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "dsh-mem-pop-label", children: "清除筛选" })
|
|
4212
4615
|
] }) : null
|
|
4213
4616
|
] }) : null
|
|
4214
4617
|
] });
|
|
4215
4618
|
}
|
|
4216
4619
|
|
|
4217
4620
|
// client/src/tabs/RoomsTab.tsx
|
|
4218
|
-
var
|
|
4219
|
-
var
|
|
4621
|
+
var import_react19 = require("react");
|
|
4622
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4220
4623
|
function majorOf(slug) {
|
|
4221
4624
|
const i = slug.indexOf("/");
|
|
4222
4625
|
return i === -1 ? slug : slug.slice(0, i);
|
|
@@ -4245,26 +4648,26 @@ var __defProp = Object.defineProperty;
|
|
|
4245
4648
|
};
|
|
4246
4649
|
function RoomsTab(props) {
|
|
4247
4650
|
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,
|
|
4651
|
+
const [registry, setRegistry] = (0, import_react19.useState)([]);
|
|
4652
|
+
const [rooms, setRooms] = (0, import_react19.useState)([]);
|
|
4653
|
+
const [orphanCount, setOrphanCount] = (0, import_react19.useState)(0);
|
|
4654
|
+
const [busy, setBusy] = (0, import_react19.useState)(false);
|
|
4655
|
+
const [msg, setMsg] = (0, import_react19.useState)(null);
|
|
4656
|
+
const [error, setError] = (0, import_react19.useState)(null);
|
|
4657
|
+
const [hiPriv, setHiPriv] = (0, import_react19.useState)(false);
|
|
4658
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react19.useState)(false);
|
|
4659
|
+
const [regSlug, setRegSlug] = (0, import_react19.useState)("");
|
|
4660
|
+
const [regLabel, setRegLabel] = (0, import_react19.useState)("");
|
|
4661
|
+
const [regDesc, setRegDesc] = (0, import_react19.useState)("");
|
|
4662
|
+
const [form, setForm] = (0, import_react19.useState)(null);
|
|
4663
|
+
const [preview, setPreview] = (0, import_react19.useState)(null);
|
|
4664
|
+
const [grownOpen, setGrownOpen] = (0, import_react19.useState)(false);
|
|
4665
|
+
const [dragOverHall, setDragOverHall] = (0, import_react19.useState)(null);
|
|
4666
|
+
const [picking, setPicking] = (0, import_react19.useState)(null);
|
|
4667
|
+
const [editing, setEditing] = (0, import_react19.useState)(null);
|
|
4668
|
+
const [expandedRooms, setExpandedRooms] = (0, import_react19.useState)(/* @__PURE__ */ new Set());
|
|
4669
|
+
const [roomRecords, setRoomRecords] = (0, import_react19.useState)({});
|
|
4670
|
+
const [expandedHalls, setExpandedHalls] = (0, import_react19.useState)(() => {
|
|
4268
4671
|
try {
|
|
4269
4672
|
const v = window.localStorage.getItem("dsh.memory.halls.open");
|
|
4270
4673
|
return v ? new Set(JSON.parse(v)) : /* @__PURE__ */ new Set();
|
|
@@ -4272,9 +4675,9 @@ var __defProp = Object.defineProperty;
|
|
|
4272
4675
|
return /* @__PURE__ */ new Set();
|
|
4273
4676
|
}
|
|
4274
4677
|
});
|
|
4275
|
-
const [filter, setFilter] = (0,
|
|
4276
|
-
const dragRef = (0,
|
|
4277
|
-
const [ghost, setGhost] = (0,
|
|
4678
|
+
const [filter, setFilter] = (0, import_react19.useState)("");
|
|
4679
|
+
const dragRef = (0, import_react19.useRef)(null);
|
|
4680
|
+
const [ghost, setGhost] = (0, import_react19.useState)(null);
|
|
4278
4681
|
const onDragLabelDown = (ev, slug) => {
|
|
4279
4682
|
if (!hiPriv || busy || ev.button !== 0) return;
|
|
4280
4683
|
ev.currentTarget.setPointerCapture(ev.pointerId);
|
|
@@ -4299,7 +4702,7 @@ var __defProp = Object.defineProperty;
|
|
|
4299
4702
|
setDragOverHall(null);
|
|
4300
4703
|
if (hall) beginReclass(d.from, hall);
|
|
4301
4704
|
};
|
|
4302
|
-
const loadAll = (0,
|
|
4705
|
+
const loadAll = (0, import_react19.useCallback)(() => {
|
|
4303
4706
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
4304
4707
|
if (r && r.ok) {
|
|
4305
4708
|
setRooms(r.value.rooms ?? []);
|
|
@@ -4308,13 +4711,13 @@ var __defProp = Object.defineProperty;
|
|
|
4308
4711
|
}
|
|
4309
4712
|
}).catch(() => void 0);
|
|
4310
4713
|
}, [rpc]);
|
|
4311
|
-
const loadHiPriv = (0,
|
|
4714
|
+
const loadHiPriv = (0, import_react19.useCallback)(() => {
|
|
4312
4715
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
4313
4716
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
4314
4717
|
}).catch(() => {
|
|
4315
4718
|
});
|
|
4316
4719
|
}, [rpc]);
|
|
4317
|
-
(0,
|
|
4720
|
+
(0, import_react19.useEffect)(() => {
|
|
4318
4721
|
loadAll();
|
|
4319
4722
|
loadHiPriv();
|
|
4320
4723
|
}, [loadAll, loadHiPriv]);
|
|
@@ -4428,7 +4831,10 @@ var __defProp = Object.defineProperty;
|
|
|
4428
4831
|
loadAll();
|
|
4429
4832
|
if (expandedRooms.has(slug)) {
|
|
4430
4833
|
const rr = await rpc("dsh-memory/list-records", { tag: slug, limit: 10, retired: false });
|
|
4431
|
-
if (rr && rr.ok)
|
|
4834
|
+
if (rr && rr.ok) {
|
|
4835
|
+
registerTypeCatalog(rr.value.typeCatalog);
|
|
4836
|
+
setRoomRecords((m) => ({ ...m, [slug]: { items: rr.value.items, total: rr.value.total ?? null } }));
|
|
4837
|
+
}
|
|
4432
4838
|
}
|
|
4433
4839
|
} else setError(r && r.error ? r.error.message : "操作失败");
|
|
4434
4840
|
});
|
|
@@ -4450,6 +4856,7 @@ var __defProp = Object.defineProperty;
|
|
|
4450
4856
|
}
|
|
4451
4857
|
const r = await rpc("dsh-memory/list-records", { tag: slug, limit: 10, retired: false });
|
|
4452
4858
|
if (r && r.ok) {
|
|
4859
|
+
registerTypeCatalog(r.value.typeCatalog);
|
|
4453
4860
|
const next = new Set(expandedRooms);
|
|
4454
4861
|
next.add(slug);
|
|
4455
4862
|
setExpandedRooms(next);
|
|
@@ -4465,7 +4872,7 @@ var __defProp = Object.defineProperty;
|
|
|
4465
4872
|
if (r.value.csv) downloadCsv(r.value.csv, `dsh-memory-room-${slug.replace(/\//g, "-")}-records.csv`);
|
|
4466
4873
|
else setError("导出为空");
|
|
4467
4874
|
});
|
|
4468
|
-
const groups = (0,
|
|
4875
|
+
const groups = (0, import_react19.useMemo)(() => {
|
|
4469
4876
|
const countOf = new Map(rooms.map((r) => [r.room, r.count]));
|
|
4470
4877
|
const byHall = /* @__PURE__ */ new Map();
|
|
4471
4878
|
for (const e of registry) {
|
|
@@ -4482,7 +4889,7 @@ var __defProp = Object.defineProperty;
|
|
|
4482
4889
|
total: entries.reduce((s2, e) => s2 + (countOf.get(e.slug) ?? 0), 0)
|
|
4483
4890
|
})).sort((a, b) => a.hall.localeCompare(b.hall));
|
|
4484
4891
|
}, [registry, rooms]);
|
|
4485
|
-
const grownOnly = (0,
|
|
4892
|
+
const grownOnly = (0, import_react19.useMemo)(() => rooms.filter((r) => !registry.some((e) => e.slug === r.room)), [rooms, registry]);
|
|
4486
4893
|
const persistHalls = (next) => {
|
|
4487
4894
|
try {
|
|
4488
4895
|
window.localStorage.setItem("dsh.memory.halls.open", JSON.stringify([...next]));
|
|
@@ -4502,7 +4909,7 @@ var __defProp = Object.defineProperty;
|
|
|
4502
4909
|
persistHalls(next);
|
|
4503
4910
|
};
|
|
4504
4911
|
const normFilter = filter.trim().toLowerCase();
|
|
4505
|
-
const visibleGroups = (0,
|
|
4912
|
+
const visibleGroups = (0, import_react19.useMemo)(() => {
|
|
4506
4913
|
if (!normFilter) return groups;
|
|
4507
4914
|
return groups.map((g) => {
|
|
4508
4915
|
const hallHit = g.hall.toLowerCase().includes(normFilter) || (g.label ?? "").toLowerCase().includes(normFilter);
|
|
@@ -4512,15 +4919,15 @@ var __defProp = Object.defineProperty;
|
|
|
4512
4919
|
return { ...g, entries };
|
|
4513
4920
|
}).filter((g) => g.entries.length > 0);
|
|
4514
4921
|
}, [groups, normFilter]);
|
|
4515
|
-
const visibleGrown = (0,
|
|
4922
|
+
const visibleGrown = (0, import_react19.useMemo)(
|
|
4516
4923
|
() => normFilter ? grownOnly.filter((r) => r.room.toLowerCase().includes(normFilter)) : grownOnly,
|
|
4517
4924
|
[grownOnly, normFilter]
|
|
4518
4925
|
);
|
|
4519
|
-
return /* @__PURE__ */ (0,
|
|
4520
|
-
/* @__PURE__ */ (0,
|
|
4521
|
-
/* @__PURE__ */ (0,
|
|
4522
|
-
/* @__PURE__ */ (0,
|
|
4523
|
-
/* @__PURE__ */ (0,
|
|
4926
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
|
|
4927
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { ...S.flexRow, marginBottom: 8 }, children: [
|
|
4928
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "Hall = Room 大类 · 大类上限 200,小类「大类/小类」细分不占额度 · 与 Wing(域)筛选无关" }),
|
|
4929
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
4930
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4524
4931
|
"button",
|
|
4525
4932
|
{
|
|
4526
4933
|
type: "button",
|
|
@@ -4537,7 +4944,7 @@ var __defProp = Object.defineProperty;
|
|
|
4537
4944
|
children: "导出词表"
|
|
4538
4945
|
}
|
|
4539
4946
|
),
|
|
4540
|
-
/* @__PURE__ */ (0,
|
|
4947
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4541
4948
|
"button",
|
|
4542
4949
|
{
|
|
4543
4950
|
type: "button",
|
|
@@ -4557,7 +4964,7 @@ var __defProp = Object.defineProperty;
|
|
|
4557
4964
|
]
|
|
4558
4965
|
}
|
|
4559
4966
|
),
|
|
4560
|
-
/* @__PURE__ */ (0,
|
|
4967
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4561
4968
|
"button",
|
|
4562
4969
|
{
|
|
4563
4970
|
type: "button",
|
|
@@ -4572,10 +4979,10 @@ var __defProp = Object.defineProperty;
|
|
|
4572
4979
|
children: hiPriv ? "高权限:开" : "高权限:关"
|
|
4573
4980
|
}
|
|
4574
4981
|
),
|
|
4575
|
-
/* @__PURE__ */ (0,
|
|
4982
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", style: btn, onClick: loadAll, title: "重拉注册表与计数", children: "刷新" })
|
|
4576
4983
|
] }),
|
|
4577
|
-
/* @__PURE__ */ (0,
|
|
4578
|
-
/* @__PURE__ */ (0,
|
|
4984
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center", marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
4985
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4579
4986
|
"input",
|
|
4580
4987
|
{
|
|
4581
4988
|
value: filter,
|
|
@@ -4584,14 +4991,14 @@ var __defProp = Object.defineProperty;
|
|
|
4584
4991
|
style: { ...S.input, width: 250, fontSize: 12 }
|
|
4585
4992
|
}
|
|
4586
4993
|
),
|
|
4587
|
-
filter ? /* @__PURE__ */ (0,
|
|
4588
|
-
/* @__PURE__ */ (0,
|
|
4589
|
-
/* @__PURE__ */ (0,
|
|
4590
|
-
/* @__PURE__ */ (0,
|
|
4591
|
-
/* @__PURE__ */ (0,
|
|
4994
|
+
filter ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", style: btn, onClick: () => setFilter(""), children: "清除" }) : null,
|
|
4995
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: `匹配 ${visibleGroups.reduce((s2, g) => s2 + g.entries.length, 0)} room / ${visibleGroups.length} hall` }),
|
|
4996
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
4997
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", style: btn, title: "展开全部 hall 的子 room", onClick: () => setAllHalls(true), children: "展开全部" }),
|
|
4998
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", style: btn, title: "收起全部 hall(只留 hall 头)", onClick: () => setAllHalls(false), children: "收起全部" })
|
|
4592
4999
|
] }),
|
|
4593
|
-
/* @__PURE__ */ (0,
|
|
4594
|
-
/* @__PURE__ */ (0,
|
|
5000
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginBottom: 10 }, children: [
|
|
5001
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4595
5002
|
"input",
|
|
4596
5003
|
{
|
|
4597
5004
|
value: regSlug,
|
|
@@ -4601,7 +5008,7 @@ var __defProp = Object.defineProperty;
|
|
|
4601
5008
|
style: { ...S.input, width: 210, fontSize: 12 }
|
|
4602
5009
|
}
|
|
4603
5010
|
),
|
|
4604
|
-
/* @__PURE__ */ (0,
|
|
5011
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4605
5012
|
"input",
|
|
4606
5013
|
{
|
|
4607
5014
|
value: regLabel,
|
|
@@ -4611,7 +5018,7 @@ var __defProp = Object.defineProperty;
|
|
|
4611
5018
|
style: { ...S.input, width: 110, fontSize: 12 }
|
|
4612
5019
|
}
|
|
4613
5020
|
),
|
|
4614
|
-
/* @__PURE__ */ (0,
|
|
5021
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4615
5022
|
"input",
|
|
4616
5023
|
{
|
|
4617
5024
|
value: regDesc,
|
|
@@ -4621,7 +5028,7 @@ var __defProp = Object.defineProperty;
|
|
|
4621
5028
|
style: { ...S.input, width: 170, fontSize: 12 }
|
|
4622
5029
|
}
|
|
4623
5030
|
),
|
|
4624
|
-
/* @__PURE__ */ (0,
|
|
5031
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4625
5032
|
"button",
|
|
4626
5033
|
{
|
|
4627
5034
|
type: "button",
|
|
@@ -4631,26 +5038,26 @@ var __defProp = Object.defineProperty;
|
|
|
4631
5038
|
children: "注册"
|
|
4632
5039
|
}
|
|
4633
5040
|
),
|
|
4634
|
-
!hiPriv && /* @__PURE__ */ (0,
|
|
5041
|
+
!hiPriv && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "管理操作需先开启高权限模式" })
|
|
4635
5042
|
] }),
|
|
4636
|
-
editing ? /* @__PURE__ */ (0,
|
|
4637
|
-
/* @__PURE__ */ (0,
|
|
5043
|
+
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: [
|
|
5044
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { style: S.muted, children: [
|
|
4638
5045
|
"编辑 ",
|
|
4639
5046
|
editing.slug
|
|
4640
5047
|
] }),
|
|
4641
|
-
/* @__PURE__ */ (0,
|
|
4642
|
-
/* @__PURE__ */ (0,
|
|
4643
|
-
/* @__PURE__ */ (0,
|
|
4644
|
-
/* @__PURE__ */ (0,
|
|
5048
|
+
/* @__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 } }),
|
|
5049
|
+
/* @__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 } }),
|
|
5050
|
+
/* @__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: "保存" }),
|
|
5051
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, onClick: () => setEditing(null), style: btn, children: "取消" })
|
|
4645
5052
|
] }) : null,
|
|
4646
|
-
form ? /* @__PURE__ */ (0,
|
|
4647
|
-
/* @__PURE__ */ (0,
|
|
5053
|
+
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: [
|
|
5054
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { style: S.muted, children: [
|
|
4648
5055
|
form.action === "merge" ? "合并" : "归类/改名",
|
|
4649
5056
|
" ",
|
|
4650
5057
|
form.from,
|
|
4651
5058
|
" →"
|
|
4652
5059
|
] }),
|
|
4653
|
-
/* @__PURE__ */ (0,
|
|
5060
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4654
5061
|
"input",
|
|
4655
5062
|
{
|
|
4656
5063
|
value: form.to,
|
|
@@ -4660,7 +5067,7 @@ var __defProp = Object.defineProperty;
|
|
|
4660
5067
|
style: { ...S.input, width: 190, fontSize: 12 }
|
|
4661
5068
|
}
|
|
4662
5069
|
),
|
|
4663
|
-
form.action === "rename" ? /* @__PURE__ */ (0,
|
|
5070
|
+
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
5071
|
"button",
|
|
4665
5072
|
{
|
|
4666
5073
|
type: "button",
|
|
@@ -4671,32 +5078,32 @@ var __defProp = Object.defineProperty;
|
|
|
4671
5078
|
},
|
|
4672
5079
|
gg.hall
|
|
4673
5080
|
)) }) : null,
|
|
4674
|
-
/* @__PURE__ */ (0,
|
|
4675
|
-
/* @__PURE__ */ (0,
|
|
5081
|
+
/* @__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: "预览" }),
|
|
5082
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, onClick: () => {
|
|
4676
5083
|
setForm(null);
|
|
4677
5084
|
setPreview(null);
|
|
4678
5085
|
setPicking(null);
|
|
4679
5086
|
}, style: btn, children: "取消" }),
|
|
4680
|
-
picking ? /* @__PURE__ */ (0,
|
|
4681
|
-
/* @__PURE__ */ (0,
|
|
5087
|
+
picking ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "挑选中:点击目标 hall 头完成归类" }) : null,
|
|
5088
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "与反刍并发会互相覆盖,请在反刍空闲时执行。" })
|
|
4682
5089
|
] }) : null,
|
|
4683
|
-
preview ? /* @__PURE__ */ (0,
|
|
4684
|
-
/* @__PURE__ */ (0,
|
|
4685
|
-
/* @__PURE__ */ (0,
|
|
4686
|
-
/* @__PURE__ */ (0,
|
|
5090
|
+
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: [
|
|
5091
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { children: preview.notice }),
|
|
5092
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: 6, marginTop: 4 }, children: [
|
|
5093
|
+
/* @__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
5094
|
"确认执行",
|
|
4688
5095
|
preview.action === "merge" ? "合并" : "归类/改名"
|
|
4689
5096
|
] }),
|
|
4690
|
-
/* @__PURE__ */ (0,
|
|
5097
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, onClick: () => setPreview(null), style: btn, children: "再改改" })
|
|
4691
5098
|
] })
|
|
4692
5099
|
] }) : null,
|
|
4693
|
-
msg ? /* @__PURE__ */ (0,
|
|
4694
|
-
error ? /* @__PURE__ */ (0,
|
|
4695
|
-
ghost ? /* @__PURE__ */ (0,
|
|
4696
|
-
visibleGroups.length === 0 ? /* @__PURE__ */ (0,
|
|
5100
|
+
msg ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.hint, children: msg }) : null,
|
|
5101
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.error, children: error }) : null,
|
|
5102
|
+
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,
|
|
5103
|
+
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
5104
|
const hallOpen = !!normFilter || expandedHalls.has(g.hall);
|
|
4698
|
-
return /* @__PURE__ */ (0,
|
|
4699
|
-
/* @__PURE__ */ (0,
|
|
5105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { marginBottom: 10, border: "1px solid var(--dsh-mem-border)", borderRadius: 8, overflow: "hidden" }, children: [
|
|
5106
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4700
5107
|
"div",
|
|
4701
5108
|
{
|
|
4702
5109
|
"data-hall": g.hall,
|
|
@@ -4737,7 +5144,7 @@ var __defProp = Object.defineProperty;
|
|
|
4737
5144
|
},
|
|
4738
5145
|
title: picking ? "点击此 hall:把「" + picking + "」归入 " + g.hall + " 下(major/minor,预览后确认)" : hiPriv ? "拖入 room 归类到该 hall 下(major/minor;记录随迁,旧名进别名,预览后确认)" : void 0,
|
|
4739
5146
|
children: [
|
|
4740
|
-
/* @__PURE__ */ (0,
|
|
5147
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4741
5148
|
"button",
|
|
4742
5149
|
{
|
|
4743
5150
|
type: "button",
|
|
@@ -4750,13 +5157,13 @@ var __defProp = Object.defineProperty;
|
|
|
4750
5157
|
children: hallOpen ? "▾" : "▸"
|
|
4751
5158
|
}
|
|
4752
5159
|
),
|
|
4753
|
-
/* @__PURE__ */ (0,
|
|
5160
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { style: { fontSize: 12, fontWeight: 600 }, children: [
|
|
4754
5161
|
g.hall,
|
|
4755
|
-
g.label ? /* @__PURE__ */ (0,
|
|
5162
|
+
g.label ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: " (" + g.label + ")" }) : null
|
|
4756
5163
|
] }),
|
|
4757
|
-
/* @__PURE__ */ (0,
|
|
4758
|
-
/* @__PURE__ */ (0,
|
|
4759
|
-
/* @__PURE__ */ (0,
|
|
5164
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: `合计 ${g.total} 条 · ${g.entries.length} 个 room` }),
|
|
5165
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.grow }),
|
|
5166
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4760
5167
|
"button",
|
|
4761
5168
|
{
|
|
4762
5169
|
type: "button",
|
|
@@ -4777,10 +5184,10 @@ var __defProp = Object.defineProperty;
|
|
|
4777
5184
|
const standalone = e.slug === g.hall;
|
|
4778
5185
|
const count = rooms.find((r) => r.room === e.slug)?.count ?? 0;
|
|
4779
5186
|
const retired = e.status === "retired";
|
|
4780
|
-
return /* @__PURE__ */ (0,
|
|
4781
|
-
/* @__PURE__ */ (0,
|
|
4782
|
-
/* @__PURE__ */ (0,
|
|
4783
|
-
/* @__PURE__ */ (0,
|
|
5187
|
+
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: [
|
|
5188
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
5189
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { flex: 1, minWidth: 0, display: "flex", flexWrap: "wrap", gap: "2px 8px", alignItems: "baseline" }, children: [
|
|
5190
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4784
5191
|
"button",
|
|
4785
5192
|
{
|
|
4786
5193
|
type: "button",
|
|
@@ -4790,7 +5197,7 @@ var __defProp = Object.defineProperty;
|
|
|
4790
5197
|
children: expandedRooms.has(e.slug) ? "▾" : "▸"
|
|
4791
5198
|
}
|
|
4792
5199
|
),
|
|
4793
|
-
/* @__PURE__ */ (0,
|
|
5200
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4794
5201
|
"span",
|
|
4795
5202
|
{
|
|
4796
5203
|
style: { fontSize: 12, cursor: hiPriv && !busy ? "grab" : "default", touchAction: "none" },
|
|
@@ -4804,20 +5211,20 @@ var __defProp = Object.defineProperty;
|
|
|
4804
5211
|
]
|
|
4805
5212
|
}
|
|
4806
5213
|
),
|
|
4807
|
-
e.label ? /* @__PURE__ */ (0,
|
|
4808
|
-
/* @__PURE__ */ (0,
|
|
4809
|
-
retired ? /* @__PURE__ */ (0,
|
|
4810
|
-
(e.aliases ?? []).length > 0 ? /* @__PURE__ */ (0,
|
|
5214
|
+
e.label ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: e.label }) : null,
|
|
5215
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: count + " 条" }),
|
|
5216
|
+
retired ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "已退役" }) : null,
|
|
5217
|
+
(e.aliases ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: { ...S.muted, wordBreak: "break-all" }, children: "别名: " + (e.aliases ?? []).join(", ") }) : null
|
|
4811
5218
|
] }),
|
|
4812
|
-
/* @__PURE__ */ (0,
|
|
4813
|
-
!hiPriv ? null : /* @__PURE__ */ (0,
|
|
4814
|
-
/* @__PURE__ */ (0,
|
|
5219
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: 6, flexShrink: 0, alignItems: "center" }, children: [
|
|
5220
|
+
!hiPriv ? null : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
5221
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, title: "编辑显示名/归类说明", onClick: () => {
|
|
4815
5222
|
setEditing({ slug: e.slug, label: e.label ?? "", description: e.description ?? "" });
|
|
4816
5223
|
setForm(null);
|
|
4817
5224
|
setPreview(null);
|
|
4818
5225
|
setPicking(null);
|
|
4819
5226
|
}, style: btn, children: "编辑" }),
|
|
4820
|
-
/* @__PURE__ */ (0,
|
|
5227
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4821
5228
|
"button",
|
|
4822
5229
|
{
|
|
4823
5230
|
type: "button",
|
|
@@ -4838,43 +5245,43 @@ var __defProp = Object.defineProperty;
|
|
|
4838
5245
|
children: picking === e.slug ? "选 hall…" : "归类"
|
|
4839
5246
|
}
|
|
4840
5247
|
),
|
|
4841
|
-
/* @__PURE__ */ (0,
|
|
5248
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, title: `改名(= merge 1:1 + 注册表改名)`, onClick: () => {
|
|
4842
5249
|
setForm({ action: "rename", from: e.slug, to: "" });
|
|
4843
5250
|
setPreview(null);
|
|
4844
5251
|
}, style: btn, children: "改名" }),
|
|
4845
|
-
/* @__PURE__ */ (0,
|
|
5252
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, title: "合并到另一个 Room(dryRun 预览→确认实跑)", onClick: () => {
|
|
4846
5253
|
setForm({ action: "merge", from: e.slug, to: "" });
|
|
4847
5254
|
setPreview(null);
|
|
4848
5255
|
}, style: btn, children: "合并" }),
|
|
4849
|
-
/* @__PURE__ */ (0,
|
|
4850
|
-
!retired ? /* @__PURE__ */ (0,
|
|
5256
|
+
/* @__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 ? "恢复" : "退役" }),
|
|
5257
|
+
!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
5258
|
] }),
|
|
4852
|
-
/* @__PURE__ */ (0,
|
|
5259
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", disabled: busy, title: "导出该 Room 的记录清单 CSV", onClick: () => exportRecords(e.slug), style: btn, children: "导出" })
|
|
4853
5260
|
] })
|
|
4854
5261
|
] }),
|
|
4855
|
-
expandedRooms.has(e.slug) ? /* @__PURE__ */ (0,
|
|
4856
|
-
(roomRecords[e.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0,
|
|
4857
|
-
/* @__PURE__ */ (0,
|
|
5262
|
+
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: [
|
|
5263
|
+
(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: [
|
|
5264
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: tagClass(it.type), children: typeLabel(it.type) }),
|
|
4858
5265
|
" ",
|
|
4859
|
-
/* @__PURE__ */ (0,
|
|
4860
|
-
/* @__PURE__ */ (0,
|
|
5266
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: it.updatedAt ? fmtTime(it.updatedAt) : "" }),
|
|
5267
|
+
/* @__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
5268
|
] }, 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,
|
|
5269
|
+
(roomRecords[e.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: S.muted, children: "该 Room 暂无记录。" }) : null,
|
|
5270
|
+
(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
5271
|
] }) : null
|
|
4865
5272
|
] }, e.slug);
|
|
4866
5273
|
}) : null
|
|
4867
5274
|
] }, g.hall);
|
|
4868
5275
|
}),
|
|
4869
|
-
visibleGrown.length > 0 ? /* @__PURE__ */ (0,
|
|
4870
|
-
/* @__PURE__ */ (0,
|
|
5276
|
+
visibleGrown.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { marginTop: 4 }, children: [
|
|
5277
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { type: "button", onClick: () => setGrownOpen(!grownOpen), style: btn, title: grownOpen ? "收起未注册自生长 Room" : "展开未注册自生长 Room", children: [
|
|
4871
5278
|
grownOpen ? "▾" : "▸",
|
|
4872
5279
|
" 自生长未注册 · 共 ",
|
|
4873
5280
|
visibleGrown.length
|
|
4874
5281
|
] }),
|
|
4875
|
-
/* @__PURE__ */ (0,
|
|
4876
|
-
grownOpen ? /* @__PURE__ */ (0,
|
|
4877
|
-
/* @__PURE__ */ (0,
|
|
5282
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: S.muted, children: "(只在 tags 里涌现,不在词表 —— 收编后标注器才会优先挂靠)" }),
|
|
5283
|
+
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: [
|
|
5284
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4878
5285
|
"span",
|
|
4879
5286
|
{
|
|
4880
5287
|
style: { ...btn, cursor: hiPriv && !busy ? "grab" : "default", borderRadius: 999, padding: "2px 8px", touchAction: "none" },
|
|
@@ -4885,8 +5292,8 @@ var __defProp = Object.defineProperty;
|
|
|
4885
5292
|
children: r.room + " · " + r.count
|
|
4886
5293
|
}
|
|
4887
5294
|
),
|
|
4888
|
-
/* @__PURE__ */ (0,
|
|
4889
|
-
/* @__PURE__ */ (0,
|
|
5295
|
+
/* @__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: "收编" }),
|
|
5296
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4890
5297
|
"button",
|
|
4891
5298
|
{
|
|
4892
5299
|
type: "button",
|
|
@@ -4913,8 +5320,8 @@ var __defProp = Object.defineProperty;
|
|
|
4913
5320
|
}
|
|
4914
5321
|
|
|
4915
5322
|
// client/src/tabs/RoomTab.tsx
|
|
4916
|
-
var
|
|
4917
|
-
var
|
|
5323
|
+
var import_react20 = require("react");
|
|
5324
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4918
5325
|
var btn2 = {
|
|
4919
5326
|
cursor: "pointer",
|
|
4920
5327
|
fontSize: 12,
|
|
@@ -4935,22 +5342,22 @@ var __defProp = Object.defineProperty;
|
|
|
4935
5342
|
}
|
|
4936
5343
|
function RoomTab(props) {
|
|
4937
5344
|
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,
|
|
5345
|
+
const [registry, setRegistry] = (0, import_react20.useState)([]);
|
|
5346
|
+
const [counts, setCounts] = (0, import_react20.useState)([]);
|
|
5347
|
+
const [orphanCount, setOrphanCount] = (0, import_react20.useState)(0);
|
|
5348
|
+
const [busy, setBusy] = (0, import_react20.useState)(false);
|
|
5349
|
+
const [msg, setMsg] = (0, import_react20.useState)(null);
|
|
5350
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
5351
|
+
const [hiPriv, setHiPriv] = (0, import_react20.useState)(false);
|
|
5352
|
+
const [hiPrivBusy, setHiPrivBusy] = (0, import_react20.useState)(false);
|
|
5353
|
+
const [reg, setReg] = (0, import_react20.useState)({ slug: "", label: "", description: "" });
|
|
5354
|
+
const [editing, setEditing] = (0, import_react20.useState)(null);
|
|
5355
|
+
const [renaming, setRenaming] = (0, import_react20.useState)(null);
|
|
5356
|
+
const [expanded, setExpanded] = (0, import_react20.useState)(/* @__PURE__ */ new Set());
|
|
5357
|
+
const [retiredFilter, setRetiredFilter] = (0, import_react20.useState)("");
|
|
5358
|
+
const [filter, setFilter] = (0, import_react20.useState)("");
|
|
5359
|
+
const [records, setRecords] = (0, import_react20.useState)({});
|
|
5360
|
+
const loadAll = (0, import_react20.useCallback)(() => {
|
|
4954
5361
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
4955
5362
|
if (r && r.ok) {
|
|
4956
5363
|
setCounts(r.value.rooms ?? []);
|
|
@@ -4959,13 +5366,13 @@ var __defProp = Object.defineProperty;
|
|
|
4959
5366
|
}
|
|
4960
5367
|
}).catch(() => void 0);
|
|
4961
5368
|
}, [rpc]);
|
|
4962
|
-
const loadHiPriv = (0,
|
|
5369
|
+
const loadHiPriv = (0, import_react20.useCallback)(() => {
|
|
4963
5370
|
rpc("dsh-memory/settings-get", {}).then((r) => {
|
|
4964
5371
|
if (r && r.ok && r.value) setHiPriv(!!r.value.settings.memoryMutate);
|
|
4965
5372
|
}).catch(() => {
|
|
4966
5373
|
});
|
|
4967
5374
|
}, [rpc]);
|
|
4968
|
-
(0,
|
|
5375
|
+
(0, import_react20.useEffect)(() => {
|
|
4969
5376
|
loadAll();
|
|
4970
5377
|
loadHiPriv();
|
|
4971
5378
|
}, [loadAll, loadHiPriv]);
|
|
@@ -5055,7 +5462,10 @@ var __defProp = Object.defineProperty;
|
|
|
5055
5462
|
loadAll();
|
|
5056
5463
|
if (expanded.has(slug)) {
|
|
5057
5464
|
const rr = await rpc("dsh-memory/list-records", { tag: slug, limit: 10, retired: false });
|
|
5058
|
-
if (rr && rr.ok)
|
|
5465
|
+
if (rr && rr.ok) {
|
|
5466
|
+
registerTypeCatalog(rr.value.typeCatalog);
|
|
5467
|
+
setRecords((m) => ({ ...m, [slug]: { items: rr.value.items, total: rr.value.total ?? null } }));
|
|
5468
|
+
}
|
|
5059
5469
|
}
|
|
5060
5470
|
} else setError(r && r.error ? r.error.message : "操作失败");
|
|
5061
5471
|
});
|
|
@@ -5084,6 +5494,7 @@ var __defProp = Object.defineProperty;
|
|
|
5084
5494
|
}
|
|
5085
5495
|
const r = await rpc("dsh-memory/list-records", { tag: slug, limit: 10, retired: false });
|
|
5086
5496
|
if (r && r.ok) {
|
|
5497
|
+
registerTypeCatalog(r.value.typeCatalog);
|
|
5087
5498
|
const next = new Set(expanded);
|
|
5088
5499
|
next.add(slug);
|
|
5089
5500
|
setExpanded(next);
|
|
@@ -5103,11 +5514,11 @@ var __defProp = Object.defineProperty;
|
|
|
5103
5514
|
const visibleRows = normFilter ? rows.filter(
|
|
5104
5515
|
(row2) => row2.slug.toLowerCase().includes(normFilter) || (row2.entry?.label ?? "").toLowerCase().includes(normFilter) || (row2.entry?.aliases ?? []).some((a) => a.toLowerCase().includes(normFilter))
|
|
5105
5516
|
) : rows;
|
|
5106
|
-
return /* @__PURE__ */ (0,
|
|
5107
|
-
/* @__PURE__ */ (0,
|
|
5108
|
-
/* @__PURE__ */ (0,
|
|
5109
|
-
/* @__PURE__ */ (0,
|
|
5110
|
-
/* @__PURE__ */ (0,
|
|
5517
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
|
|
5518
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { ...S.flexRow, marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
5519
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "Room 级管理:存在(注册/收编/退役)· 名称(显示名/说明/改名)· 条目(展开浏览) · 归类到 hall 请到「Hall」页" }),
|
|
5520
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.grow }),
|
|
5521
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { type: "button", style: btn2, title: "导出无 Room 绑定的孤儿清单(含候选)", onClick: () => run(async () => {
|
|
5111
5522
|
const r = await rpc("dsh-memory/rooms-export", { kind: "orphans" });
|
|
5112
5523
|
if (!r.ok) {
|
|
5113
5524
|
setError(r.error.message);
|
|
@@ -5118,7 +5529,7 @@ var __defProp = Object.defineProperty;
|
|
|
5118
5529
|
"导出孤儿 · ",
|
|
5119
5530
|
orphanCount
|
|
5120
5531
|
] }),
|
|
5121
|
-
/* @__PURE__ */ (0,
|
|
5532
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5122
5533
|
"button",
|
|
5123
5534
|
{
|
|
5124
5535
|
type: "button",
|
|
@@ -5129,35 +5540,35 @@ var __defProp = Object.defineProperty;
|
|
|
5129
5540
|
children: hiPriv ? "高权限:开" : "高权限:关"
|
|
5130
5541
|
}
|
|
5131
5542
|
),
|
|
5132
|
-
/* @__PURE__ */ (0,
|
|
5543
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn2, onClick: loadAll, children: "刷新" })
|
|
5133
5544
|
] }),
|
|
5134
|
-
editing ? /* @__PURE__ */ (0,
|
|
5135
|
-
/* @__PURE__ */ (0,
|
|
5545
|
+
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: [
|
|
5546
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: S.muted, children: [
|
|
5136
5547
|
"编辑 ",
|
|
5137
5548
|
editing.slug
|
|
5138
5549
|
] }),
|
|
5139
|
-
/* @__PURE__ */ (0,
|
|
5140
|
-
/* @__PURE__ */ (0,
|
|
5141
|
-
/* @__PURE__ */ (0,
|
|
5142
|
-
/* @__PURE__ */ (0,
|
|
5550
|
+
/* @__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 } }),
|
|
5551
|
+
/* @__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 } }),
|
|
5552
|
+
/* @__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: "保存" }),
|
|
5553
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: () => setEditing(null), style: btn2, children: "取消" })
|
|
5143
5554
|
] }) : null,
|
|
5144
|
-
renaming ? /* @__PURE__ */ (0,
|
|
5145
|
-
/* @__PURE__ */ (0,
|
|
5555
|
+
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: [
|
|
5556
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: S.muted, children: [
|
|
5146
5557
|
"改名 ",
|
|
5147
5558
|
renaming.slug,
|
|
5148
5559
|
" →"
|
|
5149
5560
|
] }),
|
|
5150
|
-
/* @__PURE__ */ (0,
|
|
5151
|
-
/* @__PURE__ */ (0,
|
|
5152
|
-
/* @__PURE__ */ (0,
|
|
5153
|
-
/* @__PURE__ */ (0,
|
|
5154
|
-
/* @__PURE__ */ (0,
|
|
5561
|
+
/* @__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 } }),
|
|
5562
|
+
/* @__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: "预览" }),
|
|
5563
|
+
/* @__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: "确认执行" }),
|
|
5564
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, onClick: () => setRenaming(null), style: btn2, children: "取消" }),
|
|
5565
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "记录随迁;与反刍并发会互相覆盖,请在反刍空闲时执行。" })
|
|
5155
5566
|
] }) : null,
|
|
5156
|
-
/* @__PURE__ */ (0,
|
|
5157
|
-
/* @__PURE__ */ (0,
|
|
5567
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
5568
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "退场筛选" }),
|
|
5158
5569
|
[["", "全部"], ["active", "活跃"], ["retired", "已退役"]].map(([val, label]) => {
|
|
5159
5570
|
const on = retiredFilter === val;
|
|
5160
|
-
return /* @__PURE__ */ (0,
|
|
5571
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5161
5572
|
"button",
|
|
5162
5573
|
{
|
|
5163
5574
|
type: "button",
|
|
@@ -5177,8 +5588,8 @@ var __defProp = Object.defineProperty;
|
|
|
5177
5588
|
val
|
|
5178
5589
|
);
|
|
5179
5590
|
}),
|
|
5180
|
-
/* @__PURE__ */ (0,
|
|
5181
|
-
/* @__PURE__ */ (0,
|
|
5591
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.grow }),
|
|
5592
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5182
5593
|
"input",
|
|
5183
5594
|
{
|
|
5184
5595
|
value: filter,
|
|
@@ -5187,24 +5598,24 @@ var __defProp = Object.defineProperty;
|
|
|
5187
5598
|
style: { ...S.input, width: 230, fontSize: 12 }
|
|
5188
5599
|
}
|
|
5189
5600
|
),
|
|
5190
|
-
filter ? /* @__PURE__ */ (0,
|
|
5601
|
+
filter ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", style: btn2, onClick: () => setFilter(""), children: "清除" }) : null
|
|
5191
5602
|
] }),
|
|
5192
|
-
/* @__PURE__ */ (0,
|
|
5193
|
-
/* @__PURE__ */ (0,
|
|
5194
|
-
/* @__PURE__ */ (0,
|
|
5195
|
-
/* @__PURE__ */ (0,
|
|
5196
|
-
/* @__PURE__ */ (0,
|
|
5197
|
-
!hiPriv && /* @__PURE__ */ (0,
|
|
5603
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginBottom: 10 }, children: [
|
|
5604
|
+
/* @__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 } }),
|
|
5605
|
+
/* @__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 } }),
|
|
5606
|
+
/* @__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 } }),
|
|
5607
|
+
/* @__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: "注册" }),
|
|
5608
|
+
!hiPriv && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "管理操作需先开启高权限模式" })
|
|
5198
5609
|
] }),
|
|
5199
|
-
msg ? /* @__PURE__ */ (0,
|
|
5200
|
-
error ? /* @__PURE__ */ (0,
|
|
5201
|
-
visibleRows.length === 0 ? normFilter ? /* @__PURE__ */ (0,
|
|
5610
|
+
msg ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.hint, children: msg }) : null,
|
|
5611
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.error, children: error }) : null,
|
|
5612
|
+
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
5613
|
const e = row2.entry;
|
|
5203
5614
|
const retired = e?.status === "retired";
|
|
5204
5615
|
const grownOnly = !e;
|
|
5205
|
-
return /* @__PURE__ */ (0,
|
|
5206
|
-
/* @__PURE__ */ (0,
|
|
5207
|
-
/* @__PURE__ */ (0,
|
|
5616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 6, border: "1px solid var(--dsh-mem-border)", borderRadius: 8 }, children: [
|
|
5617
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "4px 10px" }, children: [
|
|
5618
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5208
5619
|
"button",
|
|
5209
5620
|
{
|
|
5210
5621
|
type: "button",
|
|
@@ -5214,28 +5625,28 @@ var __defProp = Object.defineProperty;
|
|
|
5214
5625
|
children: expanded.has(row2.slug) ? "▾" : "▸"
|
|
5215
5626
|
}
|
|
5216
5627
|
),
|
|
5217
|
-
/* @__PURE__ */ (0,
|
|
5218
|
-
/* @__PURE__ */ (0,
|
|
5628
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { flex: 1, minWidth: 0, display: "flex", flexWrap: "wrap", gap: "2px 8px", alignItems: "baseline" }, children: [
|
|
5629
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 12, opacity: retired ? 0.6 : 1 }, children: [
|
|
5219
5630
|
row2.slug,
|
|
5220
5631
|
e?.source === "pre-registered" ? " ⭐" : ""
|
|
5221
5632
|
] }),
|
|
5222
|
-
e?.label ? /* @__PURE__ */ (0,
|
|
5223
|
-
/* @__PURE__ */ (0,
|
|
5224
|
-
grownOnly ? /* @__PURE__ */ (0,
|
|
5225
|
-
retired ? /* @__PURE__ */ (0,
|
|
5226
|
-
(e?.aliases ?? []).length > 0 ? /* @__PURE__ */ (0,
|
|
5633
|
+
e?.label ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: e.label }) : null,
|
|
5634
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: row2.count + " 条" }),
|
|
5635
|
+
grownOnly ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: "(自生长未注册)" }) : null,
|
|
5636
|
+
retired ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "已退役" }) : null,
|
|
5637
|
+
(e?.aliases ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { ...S.muted, wordBreak: "break-all" }, children: "别名: " + (e?.aliases ?? []).join(", ") }) : null
|
|
5227
5638
|
] }),
|
|
5228
|
-
/* @__PURE__ */ (0,
|
|
5229
|
-
!hiPriv || grownOnly ? null : /* @__PURE__ */ (0,
|
|
5230
|
-
/* @__PURE__ */ (0,
|
|
5639
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, flexShrink: 0, alignItems: "center" }, children: [
|
|
5640
|
+
!hiPriv || grownOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
5641
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "编辑显示名/归类说明", onClick: () => {
|
|
5231
5642
|
setEditing({ slug: row2.slug, label: e?.label ?? "", description: e?.description ?? "" });
|
|
5232
5643
|
setRenaming(null);
|
|
5233
5644
|
}, style: btn2, children: "编辑" }),
|
|
5234
|
-
/* @__PURE__ */ (0,
|
|
5645
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "改名(可两级 slug;记录随迁,旧名进别名)", onClick: () => {
|
|
5235
5646
|
setRenaming({ slug: row2.slug, to: "" });
|
|
5236
5647
|
setEditing(null);
|
|
5237
5648
|
}, style: btn2, children: "改名" }),
|
|
5238
|
-
/* @__PURE__ */ (0,
|
|
5649
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5239
5650
|
"button",
|
|
5240
5651
|
{
|
|
5241
5652
|
type: "button",
|
|
@@ -5246,29 +5657,29 @@ var __defProp = Object.defineProperty;
|
|
|
5246
5657
|
children: retired ? "恢复" : "退役"
|
|
5247
5658
|
}
|
|
5248
5659
|
),
|
|
5249
|
-
!retired ? /* @__PURE__ */ (0,
|
|
5660
|
+
!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
5661
|
] }),
|
|
5251
|
-
grownOnly ? /* @__PURE__ */ (0,
|
|
5252
|
-
/* @__PURE__ */ (0,
|
|
5253
|
-
/* @__PURE__ */ (0,
|
|
5662
|
+
grownOnly ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
5663
|
+
/* @__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: "收编" }),
|
|
5664
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: !hiPriv || busy, title: "退场该 Room 下全部记忆(软删,可在「已退场」区恢复)", onClick: () => {
|
|
5254
5665
|
setRenaming(null);
|
|
5255
5666
|
retire(row2.slug, false, true);
|
|
5256
5667
|
}, style: { ...btn2, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)", opacity: !hiPriv || busy ? 0.5 : 1 }, children: "退场" })
|
|
5257
5668
|
] }) : null,
|
|
5258
|
-
/* @__PURE__ */ (0,
|
|
5669
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", disabled: busy, title: "导出该 Room 的记录清单 CSV", onClick: () => exportRecords(row2.slug), style: btn2, children: "导出" })
|
|
5259
5670
|
] })
|
|
5260
5671
|
] }),
|
|
5261
|
-
expanded.has(row2.slug) ? /* @__PURE__ */ (0,
|
|
5262
|
-
(records[row2.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0,
|
|
5263
|
-
/* @__PURE__ */ (0,
|
|
5672
|
+
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: [
|
|
5673
|
+
(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: [
|
|
5674
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: tagClass(it.type), children: typeLabel(it.type) }),
|
|
5264
5675
|
" ",
|
|
5265
|
-
it.retired ? /* @__PURE__ */ (0,
|
|
5676
|
+
it.retired ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "[已退场]" }) : null,
|
|
5266
5677
|
" ",
|
|
5267
|
-
/* @__PURE__ */ (0,
|
|
5268
|
-
/* @__PURE__ */ (0,
|
|
5678
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: S.muted, children: it.updatedAt ? fmtTime(it.updatedAt) : "" }),
|
|
5679
|
+
/* @__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
5680
|
] }, 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,
|
|
5681
|
+
(records[row2.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: S.muted, children: "该 Room 暂无记忆条目。" }) : null,
|
|
5682
|
+
(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
5683
|
] }) : null
|
|
5273
5684
|
] }, row2.slug);
|
|
5274
5685
|
})
|
|
@@ -5276,13 +5687,13 @@ var __defProp = Object.defineProperty;
|
|
|
5276
5687
|
}
|
|
5277
5688
|
|
|
5278
5689
|
// client/src/tabs/ScenesTab.tsx
|
|
5279
|
-
var
|
|
5280
|
-
var
|
|
5690
|
+
var import_react21 = require("react");
|
|
5691
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
5281
5692
|
function SceneCard(props) {
|
|
5282
5693
|
const s = props.s;
|
|
5283
|
-
const [open, setOpen] = (0,
|
|
5284
|
-
return /* @__PURE__ */ (0,
|
|
5285
|
-
/* @__PURE__ */ (0,
|
|
5694
|
+
const [open, setOpen] = (0, import_react21.useState)(false);
|
|
5695
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "dsh-mem-card dsh-mem-card-hover", style: S.card, children: [
|
|
5696
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
5286
5697
|
"div",
|
|
5287
5698
|
{
|
|
5288
5699
|
style: { ...S.sceneHead, cursor: "pointer", userSelect: "none" },
|
|
@@ -5290,23 +5701,23 @@ var __defProp = Object.defineProperty;
|
|
|
5290
5701
|
setOpen(!open);
|
|
5291
5702
|
},
|
|
5292
5703
|
children: [
|
|
5293
|
-
/* @__PURE__ */ (0,
|
|
5294
|
-
/* @__PURE__ */ (0,
|
|
5295
|
-
s.heat ? /* @__PURE__ */ (0,
|
|
5296
|
-
/* @__PURE__ */ (0,
|
|
5297
|
-
/* @__PURE__ */ (0,
|
|
5704
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "dsh-mem-scene-chev", style: { transform: open ? "rotate(90deg)" : "none" }, children: "▸" }),
|
|
5705
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.sceneTitle, children: s.path }),
|
|
5706
|
+
s.heat ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "热度 " + s.heat }) : null,
|
|
5707
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.grow }),
|
|
5708
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: "更新 " + fmtTime(s.updated) })
|
|
5298
5709
|
]
|
|
5299
5710
|
}
|
|
5300
5711
|
),
|
|
5301
|
-
s.summary ? /* @__PURE__ */ (0,
|
|
5302
|
-
open ? /* @__PURE__ */ (0,
|
|
5712
|
+
s.summary ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { ...S.muted, marginBottom: 6 }, children: s.summary }) : null,
|
|
5713
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { style: S.pre, children: s.content || "(空)" }) : null
|
|
5303
5714
|
] });
|
|
5304
5715
|
}
|
|
5305
5716
|
function ScenesTab(props) {
|
|
5306
5717
|
const rpc = props.rpc;
|
|
5307
|
-
const [items, setItems] = (0,
|
|
5308
|
-
const [error, setError] = (0,
|
|
5309
|
-
const load = (0,
|
|
5718
|
+
const [items, setItems] = (0, import_react21.useState)(null);
|
|
5719
|
+
const [error, setError] = (0, import_react21.useState)(null);
|
|
5720
|
+
const load = (0, import_react21.useCallback)(() => {
|
|
5310
5721
|
rpc("dsh-memory/scenes", {}).then((r) => {
|
|
5311
5722
|
if (r && r.ok) {
|
|
5312
5723
|
setItems(r.value.items);
|
|
@@ -5316,25 +5727,25 @@ var __defProp = Object.defineProperty;
|
|
|
5316
5727
|
setError(String(e && e.message || e));
|
|
5317
5728
|
});
|
|
5318
5729
|
}, [rpc]);
|
|
5319
|
-
(0,
|
|
5730
|
+
(0, import_react21.useEffect)(() => {
|
|
5320
5731
|
load();
|
|
5321
5732
|
}, [load]);
|
|
5322
|
-
return /* @__PURE__ */ (0,
|
|
5323
|
-
/* @__PURE__ */ (0,
|
|
5324
|
-
/* @__PURE__ */ (0,
|
|
5325
|
-
/* @__PURE__ */ (0,
|
|
5326
|
-
/* @__PURE__ */ (0,
|
|
5733
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
5734
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { ...S.flexRow, marginBottom: 10 }, children: [
|
|
5735
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: S.muted, children: items ? items.length + " 个场景块" : "加载中…" }),
|
|
5736
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.grow }),
|
|
5737
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(NButton, { onClick: load, children: "刷新" })
|
|
5327
5738
|
] }),
|
|
5328
|
-
error ? /* @__PURE__ */ (0,
|
|
5329
|
-
items && items.length === 0 ? /* @__PURE__ */ (0,
|
|
5739
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: S.error, children: error }) : null,
|
|
5740
|
+
items && items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: S.intro, children: "暂无场景块。累计 5 条新记忆后 L2 会自动整合出第一个场景。" }) : null,
|
|
5330
5741
|
(items || []).map((s) => {
|
|
5331
|
-
return /* @__PURE__ */ (0,
|
|
5742
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SceneCard, { s }, s.path);
|
|
5332
5743
|
})
|
|
5333
5744
|
] });
|
|
5334
5745
|
}
|
|
5335
5746
|
|
|
5336
5747
|
// client/src/panel.tsx
|
|
5337
|
-
var
|
|
5748
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
5338
5749
|
var TABS = [
|
|
5339
5750
|
["overview", "概览"],
|
|
5340
5751
|
["records", "记忆"],
|
|
@@ -5355,10 +5766,10 @@ var __defProp = Object.defineProperty;
|
|
|
5355
5766
|
];
|
|
5356
5767
|
function MemoryPanel(props) {
|
|
5357
5768
|
const rpc = props.rpc;
|
|
5358
|
-
const [tab, setTab] = (0,
|
|
5359
|
-
const [skin, setSkinState] = (0,
|
|
5769
|
+
const [tab, setTab] = (0, import_react22.useState)("overview");
|
|
5770
|
+
const [skin, setSkinState] = (0, import_react22.useState)(() => getSkin());
|
|
5360
5771
|
ensureThemeStyle(skin);
|
|
5361
|
-
(0,
|
|
5772
|
+
(0, import_react22.useEffect)(() => {
|
|
5362
5773
|
applySkin(skin);
|
|
5363
5774
|
watchSidebarIcon();
|
|
5364
5775
|
}, [skin]);
|
|
@@ -5367,21 +5778,21 @@ var __defProp = Object.defineProperty;
|
|
|
5367
5778
|
setSkinState(next);
|
|
5368
5779
|
};
|
|
5369
5780
|
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,
|
|
5781
|
+
if (tab === "overview") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(OverviewTab, { rpc });
|
|
5782
|
+
else if (tab === "records") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(RecordsTab, { rpc });
|
|
5783
|
+
else if (tab === "conflicts") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ConflictsTab, { rpc });
|
|
5784
|
+
else if (tab === "scenes") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ScenesTab, { rpc });
|
|
5785
|
+
else if (tab === "rooms") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(RoomsTab, { rpc });
|
|
5786
|
+
else if (tab === "room") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(RoomTab, { rpc });
|
|
5787
|
+
else if (tab === "persona") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PersonaTab, { rpc });
|
|
5788
|
+
else if (tab === "cost") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CostTab, { rpc });
|
|
5789
|
+
else if (tab === "connect") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ConnectTab, { rpc });
|
|
5790
|
+
else if (tab === "skills") body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SkillsTab, { rpc });
|
|
5791
|
+
else body = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LogTab, { rpc });
|
|
5792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "dsh-mem-root", style: S.section, children: [
|
|
5793
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h2", { style: S.heading, children: "记忆 (Memory)" }),
|
|
5794
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { style: S.intro, children: "L0~L3 分层蒸馏记忆:浏览被记住的内容,控制记忆模式开关。" }),
|
|
5795
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
5385
5796
|
"div",
|
|
5386
5797
|
{
|
|
5387
5798
|
style: {
|
|
@@ -5393,8 +5804,8 @@ var __defProp = Object.defineProperty;
|
|
|
5393
5804
|
marginBottom: 10
|
|
5394
5805
|
},
|
|
5395
5806
|
children: [
|
|
5396
|
-
/* @__PURE__ */ (0,
|
|
5397
|
-
SKIN_OPTS.map((s) => /* @__PURE__ */ (0,
|
|
5807
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)", marginRight: 4 }, children: "皮肤" }),
|
|
5808
|
+
SKIN_OPTS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5398
5809
|
"button",
|
|
5399
5810
|
{
|
|
5400
5811
|
className: skin === s[0] ? "dsh-mem-tab dsh-mem-tab-on" : "dsh-mem-tab",
|
|
@@ -5407,8 +5818,8 @@ var __defProp = Object.defineProperty;
|
|
|
5407
5818
|
]
|
|
5408
5819
|
}
|
|
5409
5820
|
),
|
|
5410
|
-
/* @__PURE__ */ (0,
|
|
5411
|
-
return /* @__PURE__ */ (0,
|
|
5821
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: S.tabbar, children: TABS.map((t) => {
|
|
5822
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5412
5823
|
"button",
|
|
5413
5824
|
{
|
|
5414
5825
|
className: tab === t[0] ? "dsh-mem-tab dsh-mem-tab-on" : "dsh-mem-tab",
|
|
@@ -5425,7 +5836,7 @@ var __defProp = Object.defineProperty;
|
|
|
5425
5836
|
}
|
|
5426
5837
|
|
|
5427
5838
|
// client/src/pill/MemoryModePill.tsx
|
|
5428
|
-
var
|
|
5839
|
+
var import_react26 = require("react");
|
|
5429
5840
|
|
|
5430
5841
|
// src/util/context-occupancy.ts
|
|
5431
5842
|
var CONTEXT_METER_CIRCUMFERENCE = 34.55751918948772;
|
|
@@ -5450,8 +5861,8 @@ var __defProp = Object.defineProperty;
|
|
|
5450
5861
|
var panelListeners = /* @__PURE__ */ new Set();
|
|
5451
5862
|
var panelWasOpen = false;
|
|
5452
5863
|
var snapshotListeners = /* @__PURE__ */ new Set();
|
|
5453
|
-
function initOccupancyIndicator(
|
|
5454
|
-
statsCall =
|
|
5864
|
+
function initOccupancyIndicator(call2) {
|
|
5865
|
+
statsCall = call2;
|
|
5455
5866
|
}
|
|
5456
5867
|
function noteOccupancySession(sessionId) {
|
|
5457
5868
|
if (sessionId === activeSessionId) return;
|
|
@@ -5741,23 +6152,23 @@ var __defProp = Object.defineProperty;
|
|
|
5741
6152
|
}
|
|
5742
6153
|
|
|
5743
6154
|
// client/src/pill/WingWheel.tsx
|
|
5744
|
-
var
|
|
6155
|
+
var import_react25 = require("react");
|
|
5745
6156
|
|
|
5746
6157
|
// client/src/pill/SessionInfoArea.tsx
|
|
5747
|
-
var
|
|
5748
|
-
var
|
|
6158
|
+
var import_react23 = require("react");
|
|
6159
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
5749
6160
|
function sinfoCell(val, label, title) {
|
|
5750
|
-
return /* @__PURE__ */ (0,
|
|
5751
|
-
/* @__PURE__ */ (0,
|
|
5752
|
-
/* @__PURE__ */ (0,
|
|
6161
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { title: title || void 0, children: [
|
|
6162
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "dsh-mem-sinfo-val", children: val }),
|
|
6163
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "dsh-mem-sinfo-label", children: label })
|
|
5753
6164
|
] });
|
|
5754
6165
|
}
|
|
5755
6166
|
function SessionInfoArea(props) {
|
|
5756
6167
|
const rpc = props.rpc;
|
|
5757
6168
|
const sessionId = props.sessionId;
|
|
5758
|
-
const [stats, setStats] = (0,
|
|
5759
|
-
const busyRef = (0,
|
|
5760
|
-
(0,
|
|
6169
|
+
const [stats, setStats] = (0, import_react23.useState)(void 0);
|
|
6170
|
+
const busyRef = (0, import_react23.useRef)(false);
|
|
6171
|
+
(0, import_react23.useEffect)(() => {
|
|
5761
6172
|
if (!rpc || !sessionId) return void 0;
|
|
5762
6173
|
let alive = true;
|
|
5763
6174
|
let timer = null;
|
|
@@ -5790,7 +6201,7 @@ var __defProp = Object.defineProperty;
|
|
|
5790
6201
|
}, [rpc, sessionId]);
|
|
5791
6202
|
if (stats === null) return null;
|
|
5792
6203
|
if (stats === void 0) {
|
|
5793
|
-
return /* @__PURE__ */ (0,
|
|
6204
|
+
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
6205
|
sinfoCell("…", "召回命中"),
|
|
5795
6206
|
sinfoCell("…", "攒批进度"),
|
|
5796
6207
|
sinfoCell("…", "本会话记忆"),
|
|
@@ -5839,30 +6250,30 @@ var __defProp = Object.defineProperty;
|
|
|
5839
6250
|
else if (stats.retrieval === "none") note = "检索不可用(FTS 与向量均失效)";
|
|
5840
6251
|
}
|
|
5841
6252
|
const ago = fmtAgo(gl.lastExtractAt);
|
|
5842
|
-
return /* @__PURE__ */ (0,
|
|
5843
|
-
warn ? /* @__PURE__ */ (0,
|
|
5844
|
-
/* @__PURE__ */ (0,
|
|
6253
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "dsh-mem-sinfo", children: [
|
|
6254
|
+
warn ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "dsh-mem-sinfo-warn", children: warn }) : null,
|
|
6255
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "dsh-mem-sinfo-grid", children: [
|
|
5845
6256
|
sinfoCell(rcVal, rcLabel, rcTitle),
|
|
5846
6257
|
sinfoCell(dVal, dLabel, dTitle),
|
|
5847
6258
|
sinfoCell(String(di.producedRecords || 0), "本会话记忆", pTitle),
|
|
5848
6259
|
sinfoCell(stats.l0Count != null ? String(stats.l0Count) : "…", "会话消息")
|
|
5849
6260
|
] }),
|
|
5850
|
-
note ? /* @__PURE__ */ (0,
|
|
5851
|
-
/* @__PURE__ */ (0,
|
|
6261
|
+
note ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "dsh-mem-sinfo-note", children: note }) : null,
|
|
6262
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "dsh-mem-sinfo-sum", children: "待蒸馏 " + (gl.pendingTotal || 0) + " · 上次蒸馏 " + (ago || "尚未蒸馏") })
|
|
5852
6263
|
] });
|
|
5853
6264
|
}
|
|
5854
6265
|
|
|
5855
6266
|
// client/src/pill/SessionRecalledArea.tsx
|
|
5856
|
-
var
|
|
5857
|
-
var
|
|
6267
|
+
var import_react24 = require("react");
|
|
6268
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
5858
6269
|
var SHOW_CAP = 6;
|
|
5859
6270
|
var POLL_MS2 = 4e3;
|
|
5860
6271
|
var MATURITY_LABEL = { high: "成熟·高", mid: "成熟·中", low: "成熟·低" };
|
|
5861
6272
|
function SessionRecalledArea(props) {
|
|
5862
6273
|
const rpc = props.rpc;
|
|
5863
6274
|
const sessionId = props.sessionId;
|
|
5864
|
-
const [records, setRecords] = (0,
|
|
5865
|
-
(0,
|
|
6275
|
+
const [records, setRecords] = (0, import_react24.useState)(void 0);
|
|
6276
|
+
(0, import_react24.useEffect)(() => {
|
|
5866
6277
|
if (!rpc || !sessionId) return void 0;
|
|
5867
6278
|
let alive = true;
|
|
5868
6279
|
let timer = null;
|
|
@@ -5871,7 +6282,10 @@ var __defProp = Object.defineProperty;
|
|
|
5871
6282
|
const token = ++seq;
|
|
5872
6283
|
rpc("dsh-memory/session-recalled", { sessionId }).then((r) => {
|
|
5873
6284
|
if (!alive || token !== seq) return;
|
|
5874
|
-
if (r && r.ok && r.value)
|
|
6285
|
+
if (r && r.ok && r.value) {
|
|
6286
|
+
registerTypeCatalog(r.value.typeCatalog);
|
|
6287
|
+
setRecords(r.value.records);
|
|
6288
|
+
}
|
|
5875
6289
|
}).catch(() => {
|
|
5876
6290
|
}).then(() => {
|
|
5877
6291
|
if (alive) timer = setTimeout(tick, POLL_MS2);
|
|
@@ -5884,32 +6298,38 @@ var __defProp = Object.defineProperty;
|
|
|
5884
6298
|
};
|
|
5885
6299
|
}, [rpc, sessionId]);
|
|
5886
6300
|
if (records === void 0) return null;
|
|
5887
|
-
const
|
|
6301
|
+
const rows = records.filter((r) => r.superseded !== true || r.retired === true);
|
|
6302
|
+
const recentFirst = [...rows].reverse();
|
|
5888
6303
|
const shown = recentFirst.slice(0, SHOW_CAP);
|
|
5889
6304
|
const hidden = recentFirst.length - shown.length;
|
|
5890
|
-
|
|
5891
|
-
|
|
6305
|
+
const allSuperseded = rows.length === 0 && records.length > 0;
|
|
6306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "dsh-mem-sinfo", children: [
|
|
6307
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
5892
6308
|
"div",
|
|
5893
6309
|
{
|
|
5894
6310
|
style: { fontSize: 11, color: "var(--dsh-mem-text-3)", marginBottom: 6 },
|
|
5895
|
-
title: "
|
|
5896
|
-
children: "本会话召回 " +
|
|
6311
|
+
title: "本会话召回、且正文仍在上下文里的记忆(正文被摘要顶掉的已折叠不显示;清空会话才清除;不是常驻注入)",
|
|
6312
|
+
children: "本会话召回 " + rows.length + " 条"
|
|
5897
6313
|
}
|
|
5898
6314
|
),
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
6315
|
+
allSuperseded ? (
|
|
6316
|
+
// 不是“还没召回到”——那批确实注入过,只是正文已被摘要顶掉。说谎的空态比不显示更糟。
|
|
6317
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)", lineHeight: "16px" }, children: "本会话注入过的 " + records.length + " 条记忆正文已被摘要取代" })
|
|
6318
|
+
) : 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: [
|
|
6319
|
+
shown.map((r) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: rowStyle, title: rowTitle(r), children: [
|
|
6320
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
5902
6321
|
"span",
|
|
5903
6322
|
{
|
|
5904
|
-
className:
|
|
6323
|
+
className: tagClass(r.type),
|
|
5905
6324
|
style: { flexShrink: 0, whiteSpace: "nowrap" },
|
|
5906
|
-
children:
|
|
6325
|
+
children: typeLabel(r.type)
|
|
5907
6326
|
}
|
|
5908
6327
|
),
|
|
5909
|
-
/* @__PURE__ */ (0,
|
|
5910
|
-
r.
|
|
6328
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "dsh-mem-sinfo-val", style: r.retired === true ? STALE_TEXT_STYLE : textStyle, children: r.content }),
|
|
6329
|
+
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,
|
|
6330
|
+
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
6331
|
] }, r.id)),
|
|
5912
|
-
hidden > 0 ? /* @__PURE__ */ (0,
|
|
6332
|
+
hidden > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: "+ " + hidden + " 条更早召回(详见面板「记忆」页)" }) : null
|
|
5913
6333
|
] })
|
|
5914
6334
|
] });
|
|
5915
6335
|
}
|
|
@@ -5929,14 +6349,15 @@ var __defProp = Object.defineProperty;
|
|
|
5929
6349
|
WebkitBoxOrient: "vertical",
|
|
5930
6350
|
overflow: "hidden"
|
|
5931
6351
|
};
|
|
6352
|
+
var STALE_TEXT_STYLE = { ...textStyle, textDecoration: "line-through" };
|
|
5932
6353
|
function rowTitle(r) {
|
|
5933
|
-
const head = "[" + (
|
|
6354
|
+
const head = "[" + typeLabel(r.type) + "] " + r.content;
|
|
5934
6355
|
const sc = r.usageScenario && r.usageScenario.length > 0 ? "\n使用场景:" + r.usageScenario.join(";") : "";
|
|
5935
6356
|
return head + sc;
|
|
5936
6357
|
}
|
|
5937
6358
|
|
|
5938
6359
|
// client/src/pill/WingWheel.tsx
|
|
5939
|
-
var
|
|
6360
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
5940
6361
|
var SIZE = 196;
|
|
5941
6362
|
var CENTER = SIZE / 2;
|
|
5942
6363
|
var R = 64;
|
|
@@ -5979,17 +6400,17 @@ var __defProp = Object.defineProperty;
|
|
|
5979
6400
|
function WingWheel(props) {
|
|
5980
6401
|
ensureThemeStyle();
|
|
5981
6402
|
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,
|
|
6403
|
+
const [overview, setOverview] = (0, import_react25.useState)(null);
|
|
6404
|
+
const [backfillBusy, setBackfillBusy] = (0, import_react25.useState)(false);
|
|
6405
|
+
const [localError, setLocalError] = (0, import_react25.useState)(null);
|
|
6406
|
+
const timersRef = (0, import_react25.useRef)([]);
|
|
6407
|
+
(0, import_react25.useEffect)(
|
|
5987
6408
|
() => () => {
|
|
5988
6409
|
for (const t of timersRef.current) window.clearTimeout(t);
|
|
5989
6410
|
},
|
|
5990
6411
|
[]
|
|
5991
6412
|
);
|
|
5992
|
-
(0,
|
|
6413
|
+
(0, import_react25.useEffect)(() => {
|
|
5993
6414
|
let alive = true;
|
|
5994
6415
|
props.rpc("dsh-memory/wing-overview", {}).then((r) => {
|
|
5995
6416
|
if (!alive) return;
|
|
@@ -6035,28 +6456,28 @@ var __defProp = Object.defineProperty;
|
|
|
6035
6456
|
finish();
|
|
6036
6457
|
});
|
|
6037
6458
|
};
|
|
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,
|
|
6459
|
+
const boxRef = (0, import_react25.useRef)(null);
|
|
6460
|
+
const startRef = (0, import_react25.useRef)(null);
|
|
6461
|
+
const movedRef = (0, import_react25.useRef)(false);
|
|
6462
|
+
const downIndexRef = (0, import_react25.useRef)(null);
|
|
6463
|
+
const dragTargetRef = (0, import_react25.useRef)(null);
|
|
6464
|
+
const [drag, setDrag] = (0, import_react25.useState)(null);
|
|
6044
6465
|
const lockedIndex = (() => {
|
|
6045
6466
|
if (props.halls.length !== 1 || !overview) return null;
|
|
6046
6467
|
const i = overview.corners.findIndex((c) => c.id === props.halls[0]);
|
|
6047
6468
|
return i >= 0 ? i : null;
|
|
6048
6469
|
})();
|
|
6049
6470
|
const activeCorner = drag ? drag.index : lockedIndex;
|
|
6050
|
-
const blockPosRef = (0,
|
|
6471
|
+
const blockPosRef = (0, import_react25.useRef)(
|
|
6051
6472
|
activeCorner != null ? cornerXY(activeCorner) : { x: CENTER, y: CENTER }
|
|
6052
6473
|
);
|
|
6053
|
-
const blockTargetRef = (0,
|
|
6054
|
-
const [blockPos, setBlockPos] = (0,
|
|
6055
|
-
(0,
|
|
6474
|
+
const blockTargetRef = (0, import_react25.useRef)(blockPosRef.current);
|
|
6475
|
+
const [blockPos, setBlockPos] = (0, import_react25.useState)(blockPosRef.current);
|
|
6476
|
+
(0, import_react25.useEffect)(() => {
|
|
6056
6477
|
blockTargetRef.current = activeCorner != null ? cornerXY(activeCorner) : { x: CENTER, y: CENTER };
|
|
6057
6478
|
}, [activeCorner]);
|
|
6058
|
-
const reducedMotionRef = (0,
|
|
6059
|
-
(0,
|
|
6479
|
+
const reducedMotionRef = (0, import_react25.useRef)(false);
|
|
6480
|
+
(0, import_react25.useEffect)(() => {
|
|
6060
6481
|
const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
6061
6482
|
const apply2 = () => {
|
|
6062
6483
|
reducedMotionRef.current = mq.matches;
|
|
@@ -6065,7 +6486,7 @@ var __defProp = Object.defineProperty;
|
|
|
6065
6486
|
mq.addEventListener("change", apply2);
|
|
6066
6487
|
return () => mq.removeEventListener("change", apply2);
|
|
6067
6488
|
}, []);
|
|
6068
|
-
(0,
|
|
6489
|
+
(0, import_react25.useEffect)(() => {
|
|
6069
6490
|
let raf = 0;
|
|
6070
6491
|
const loop = () => {
|
|
6071
6492
|
const cur = blockPosRef.current;
|
|
@@ -6154,8 +6575,8 @@ var __defProp = Object.defineProperty;
|
|
|
6154
6575
|
}).join(" ");
|
|
6155
6576
|
const grayStyle = isOff ? { opacity: 0.45, pointerEvents: "none" } : {};
|
|
6156
6577
|
const boundariesDisabled = props.halls.length === 0 || isOff;
|
|
6157
|
-
return /* @__PURE__ */ (0,
|
|
6158
|
-
/* @__PURE__ */ (0,
|
|
6578
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { style: { width: SIZE }, children: [
|
|
6579
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6159
6580
|
"div",
|
|
6160
6581
|
{
|
|
6161
6582
|
ref: boxRef,
|
|
@@ -6165,7 +6586,7 @@ var __defProp = Object.defineProperty;
|
|
|
6165
6586
|
onPointerUp: onBoxUp,
|
|
6166
6587
|
onPointerCancel: onBoxUp,
|
|
6167
6588
|
children: [
|
|
6168
|
-
/* @__PURE__ */ (0,
|
|
6589
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6169
6590
|
"svg",
|
|
6170
6591
|
{
|
|
6171
6592
|
width: SIZE,
|
|
@@ -6173,7 +6594,7 @@ var __defProp = Object.defineProperty;
|
|
|
6173
6594
|
style: { position: "absolute", inset: 0, pointerEvents: "none" },
|
|
6174
6595
|
"aria-hidden": "true",
|
|
6175
6596
|
children: [
|
|
6176
|
-
/* @__PURE__ */ (0,
|
|
6597
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6177
6598
|
"polygon",
|
|
6178
6599
|
{
|
|
6179
6600
|
points: polyPoints,
|
|
@@ -6184,7 +6605,7 @@ var __defProp = Object.defineProperty;
|
|
|
6184
6605
|
opacity: 0.45
|
|
6185
6606
|
}
|
|
6186
6607
|
),
|
|
6187
|
-
/* @__PURE__ */ (0,
|
|
6608
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6188
6609
|
"polygon",
|
|
6189
6610
|
{
|
|
6190
6611
|
points: polyPoints,
|
|
@@ -6195,7 +6616,7 @@ var __defProp = Object.defineProperty;
|
|
|
6195
6616
|
),
|
|
6196
6617
|
[0, 1, 2, 3, 4, 5, 6, 7].map((i) => {
|
|
6197
6618
|
const p = cornerPos(i);
|
|
6198
|
-
return /* @__PURE__ */ (0,
|
|
6619
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6199
6620
|
"line",
|
|
6200
6621
|
{
|
|
6201
6622
|
x1: CENTER,
|
|
@@ -6211,7 +6632,7 @@ var __defProp = Object.defineProperty;
|
|
|
6211
6632
|
]
|
|
6212
6633
|
}
|
|
6213
6634
|
),
|
|
6214
|
-
/* @__PURE__ */ (0,
|
|
6635
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6215
6636
|
"div",
|
|
6216
6637
|
{
|
|
6217
6638
|
"aria-hidden": "true",
|
|
@@ -6230,7 +6651,7 @@ var __defProp = Object.defineProperty;
|
|
|
6230
6651
|
}
|
|
6231
6652
|
}
|
|
6232
6653
|
),
|
|
6233
|
-
/* @__PURE__ */ (0,
|
|
6654
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6234
6655
|
"button",
|
|
6235
6656
|
{
|
|
6236
6657
|
type: "button",
|
|
@@ -6264,7 +6685,7 @@ var __defProp = Object.defineProperty;
|
|
|
6264
6685
|
const dim = activeCorner != null && !active;
|
|
6265
6686
|
const empty = count === 0;
|
|
6266
6687
|
const p = cornerPos(i);
|
|
6267
|
-
return /* @__PURE__ */ (0,
|
|
6688
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6268
6689
|
"div",
|
|
6269
6690
|
{
|
|
6270
6691
|
title: id ? `「${label}」${count ?? 0} 条
|
|
@@ -6293,8 +6714,8 @@ var __defProp = Object.defineProperty;
|
|
|
6293
6714
|
zIndex: 2
|
|
6294
6715
|
},
|
|
6295
6716
|
children: [
|
|
6296
|
-
/* @__PURE__ */ (0,
|
|
6297
|
-
/* @__PURE__ */ (0,
|
|
6717
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: label }),
|
|
6718
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 8, opacity: 0.75, fontVariantNumeric: "tabular-nums" }, children: count === null ? " " : empty ? "空角" : `${count} 条` })
|
|
6298
6719
|
]
|
|
6299
6720
|
},
|
|
6300
6721
|
id ?? i
|
|
@@ -6303,7 +6724,7 @@ var __defProp = Object.defineProperty;
|
|
|
6303
6724
|
]
|
|
6304
6725
|
}
|
|
6305
6726
|
),
|
|
6306
|
-
/* @__PURE__ */ (0,
|
|
6727
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6307
6728
|
"div",
|
|
6308
6729
|
{
|
|
6309
6730
|
title: props.halls.length === 0 ? "选定某个角(单 Wing)后,这两项才生效" : "锁定 Wing 时两类无角记忆是否参与召回",
|
|
@@ -6317,9 +6738,9 @@ var __defProp = Object.defineProperty;
|
|
|
6317
6738
|
pointerEvents: boundariesDisabled ? "none" : void 0
|
|
6318
6739
|
},
|
|
6319
6740
|
children: [
|
|
6320
|
-
/* @__PURE__ */ (0,
|
|
6321
|
-
/* @__PURE__ */ (0,
|
|
6322
|
-
/* @__PURE__ */ (0,
|
|
6741
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: overview ? `另有 ${overview.unlabeled} 条未打标` : "未打标" }),
|
|
6742
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
6743
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6323
6744
|
Segmented,
|
|
6324
6745
|
{
|
|
6325
6746
|
value: props.hallIncludeUnlabeled ? "in" : "ex",
|
|
@@ -6330,7 +6751,7 @@ var __defProp = Object.defineProperty;
|
|
|
6330
6751
|
onChange: (key) => props.onCommitWingBoundaries({ includeUnlabeled: key === "in" })
|
|
6331
6752
|
}
|
|
6332
6753
|
),
|
|
6333
|
-
/* @__PURE__ */ (0,
|
|
6754
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6334
6755
|
Segmented,
|
|
6335
6756
|
{
|
|
6336
6757
|
value: props.hallIncludeGeneral ? "in" : "ex",
|
|
@@ -6345,7 +6766,7 @@ var __defProp = Object.defineProperty;
|
|
|
6345
6766
|
]
|
|
6346
6767
|
}
|
|
6347
6768
|
),
|
|
6348
|
-
/* @__PURE__ */ (0,
|
|
6769
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Row, { label: "会话", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6349
6770
|
Segmented,
|
|
6350
6771
|
{
|
|
6351
6772
|
value: isOff ? "off" : "on",
|
|
@@ -6360,7 +6781,7 @@ var __defProp = Object.defineProperty;
|
|
|
6360
6781
|
onChange: (key) => props.onCommit(key === "off" ? "off" : "auto")
|
|
6361
6782
|
}
|
|
6362
6783
|
) }),
|
|
6363
|
-
props.recall !== void 0 && props.onCommitRecall ? /* @__PURE__ */ (0,
|
|
6784
|
+
props.recall !== void 0 && props.onCommitRecall ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Row, { label: "注入", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6364
6785
|
Segmented,
|
|
6365
6786
|
{
|
|
6366
6787
|
value: props.recall === null ? "follow" : props.recall ? "on" : "off",
|
|
@@ -6373,7 +6794,7 @@ var __defProp = Object.defineProperty;
|
|
|
6373
6794
|
onChange: (key) => props.onCommitRecall(key === "on" ? true : key === "off" ? false : null)
|
|
6374
6795
|
}
|
|
6375
6796
|
) }) : null,
|
|
6376
|
-
/* @__PURE__ */ (0,
|
|
6797
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6377
6798
|
"div",
|
|
6378
6799
|
{
|
|
6379
6800
|
style: {
|
|
@@ -6384,8 +6805,8 @@ var __defProp = Object.defineProperty;
|
|
|
6384
6805
|
marginTop: 10
|
|
6385
6806
|
},
|
|
6386
6807
|
children: [
|
|
6387
|
-
/* @__PURE__ */ (0,
|
|
6388
|
-
/* @__PURE__ */ (0,
|
|
6808
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: overview ? `未打标 ${overview.unlabeled} 条` : "未打标计数加载中" }),
|
|
6809
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6389
6810
|
ActionButton,
|
|
6390
6811
|
{
|
|
6391
6812
|
label: backfillBusy ? "回填中…" : "回填",
|
|
@@ -6397,13 +6818,13 @@ var __defProp = Object.defineProperty;
|
|
|
6397
6818
|
]
|
|
6398
6819
|
}
|
|
6399
6820
|
),
|
|
6400
|
-
props.error || localError ? /* @__PURE__ */ (0,
|
|
6401
|
-
/* @__PURE__ */ (0,
|
|
6402
|
-
/* @__PURE__ */ (0,
|
|
6821
|
+
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,
|
|
6822
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SessionRecalledArea, { rpc: props.rpc, sessionId: props.sessionId }),
|
|
6823
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SessionInfoArea, { rpc: props.rpc, sessionId: props.sessionId })
|
|
6403
6824
|
] });
|
|
6404
6825
|
}
|
|
6405
6826
|
function Row(props) {
|
|
6406
|
-
return /* @__PURE__ */ (0,
|
|
6827
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
6407
6828
|
"div",
|
|
6408
6829
|
{
|
|
6409
6830
|
style: {
|
|
@@ -6413,7 +6834,7 @@ var __defProp = Object.defineProperty;
|
|
|
6413
6834
|
marginTop: 10
|
|
6414
6835
|
},
|
|
6415
6836
|
children: [
|
|
6416
|
-
/* @__PURE__ */ (0,
|
|
6837
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)" }, children: props.label }),
|
|
6417
6838
|
props.children
|
|
6418
6839
|
]
|
|
6419
6840
|
}
|
|
@@ -6421,9 +6842,9 @@ var __defProp = Object.defineProperty;
|
|
|
6421
6842
|
}
|
|
6422
6843
|
var LABEL_FALLBACK = ["工作", "人际", "学习", "创作娱乐", "居家", "健康", "财务", "出行"];
|
|
6423
6844
|
function useViewportClamp(popRef) {
|
|
6424
|
-
const shiftRef = (0,
|
|
6425
|
-
const [shiftX, setShiftX] = (0,
|
|
6426
|
-
(0,
|
|
6845
|
+
const shiftRef = (0, import_react25.useRef)(0);
|
|
6846
|
+
const [shiftX, setShiftX] = (0, import_react25.useState)(0);
|
|
6847
|
+
(0, import_react25.useEffect)(() => {
|
|
6427
6848
|
const clamp = () => {
|
|
6428
6849
|
const el = popRef.current;
|
|
6429
6850
|
if (!el) return;
|
|
@@ -6453,24 +6874,24 @@ var __defProp = Object.defineProperty;
|
|
|
6453
6874
|
}
|
|
6454
6875
|
|
|
6455
6876
|
// client/src/pill/MemoryModePill.tsx
|
|
6456
|
-
var
|
|
6877
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
6457
6878
|
function MemoryModePill(props) {
|
|
6458
6879
|
const rpc = props.rpc;
|
|
6459
6880
|
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,
|
|
6881
|
+
const [mode, setMode] = (0, import_react26.useState)(null);
|
|
6882
|
+
const [recall, setRecall] = (0, import_react26.useState)(null);
|
|
6883
|
+
const [recallResolved, setRecallResolved] = (0, import_react26.useState)(true);
|
|
6884
|
+
const [halls, setWings] = (0, import_react26.useState)([]);
|
|
6885
|
+
const [hallIncludeUnlabeled, setWingIncludeUnlabeled] = (0, import_react26.useState)(true);
|
|
6886
|
+
const [hallIncludeGeneral, setWingIncludeGeneral] = (0, import_react26.useState)(false);
|
|
6887
|
+
const [wingLabels, setHallLabels] = (0, import_react26.useState)({});
|
|
6888
|
+
const [error, setError] = (0, import_react26.useState)(null);
|
|
6889
|
+
const [open, setOpen] = (0, import_react26.useState)(false);
|
|
6890
|
+
const wrapRef = (0, import_react26.useRef)(null);
|
|
6891
|
+
const popRef = (0, import_react26.useRef)(null);
|
|
6471
6892
|
const shiftX = useViewportClamp(popRef);
|
|
6472
|
-
const seqRef = (0,
|
|
6473
|
-
const load = (0,
|
|
6893
|
+
const seqRef = (0, import_react26.useRef)(0);
|
|
6894
|
+
const load = (0, import_react26.useCallback)(() => {
|
|
6474
6895
|
if (!sessionId || !rpc) return;
|
|
6475
6896
|
const token = ++seqRef.current;
|
|
6476
6897
|
setError(null);
|
|
@@ -6495,13 +6916,13 @@ var __defProp = Object.defineProperty;
|
|
|
6495
6916
|
}).catch(() => {
|
|
6496
6917
|
});
|
|
6497
6918
|
}, [sessionId, rpc]);
|
|
6498
|
-
(0,
|
|
6919
|
+
(0, import_react26.useEffect)(() => {
|
|
6499
6920
|
load();
|
|
6500
6921
|
}, [load]);
|
|
6501
|
-
(0,
|
|
6922
|
+
(0, import_react26.useEffect)(() => {
|
|
6502
6923
|
watchSidebarIcon();
|
|
6503
6924
|
}, []);
|
|
6504
|
-
(0,
|
|
6925
|
+
(0, import_react26.useEffect)(() => {
|
|
6505
6926
|
initOccupancyIndicator(
|
|
6506
6927
|
(endpoint, payload) => rpc(endpoint, payload)
|
|
6507
6928
|
);
|
|
@@ -6509,7 +6930,7 @@ var __defProp = Object.defineProperty;
|
|
|
6509
6930
|
watchContextMeter();
|
|
6510
6931
|
noteOccupancySession(sessionId ?? null);
|
|
6511
6932
|
}, [sessionId, rpc]);
|
|
6512
|
-
(0,
|
|
6933
|
+
(0, import_react26.useEffect)(() => {
|
|
6513
6934
|
if (!open) return;
|
|
6514
6935
|
const onDown = (e) => {
|
|
6515
6936
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -6649,8 +7070,8 @@ var __defProp = Object.defineProperty;
|
|
|
6649
7070
|
pillStyle.boxShadow = "0 0 12px color-mix(in srgb, " + info.color + " 30%, transparent)";
|
|
6650
7071
|
pillStyle["--dsh-mem-pill-tint"] = info.color;
|
|
6651
7072
|
}
|
|
6652
|
-
return /* @__PURE__ */ (0,
|
|
6653
|
-
/* @__PURE__ */ (0,
|
|
7073
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { ref: wrapRef, style: { position: "relative", display: "inline-flex" }, children: [
|
|
7074
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
6654
7075
|
"button",
|
|
6655
7076
|
{
|
|
6656
7077
|
type: "button",
|
|
@@ -6663,11 +7084,11 @@ var __defProp = Object.defineProperty;
|
|
|
6663
7084
|
style: pillStyle,
|
|
6664
7085
|
children: [
|
|
6665
7086
|
"记忆 · ",
|
|
6666
|
-
/* @__PURE__ */ (0,
|
|
7087
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: faceLabel })
|
|
6667
7088
|
]
|
|
6668
7089
|
}
|
|
6669
7090
|
),
|
|
6670
|
-
open ? /* @__PURE__ */ (0,
|
|
7091
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6671
7092
|
"div",
|
|
6672
7093
|
{
|
|
6673
7094
|
ref: popRef,
|
|
@@ -6678,12 +7099,12 @@ var __defProp = Object.defineProperty;
|
|
|
6678
7099
|
transform: "translateX(calc(-50% + " + shiftX + "px))",
|
|
6679
7100
|
zIndex: 1e3
|
|
6680
7101
|
},
|
|
6681
|
-
children: /* @__PURE__ */ (0,
|
|
7102
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6682
7103
|
"div",
|
|
6683
7104
|
{
|
|
6684
7105
|
className: "dsh-mem-popover",
|
|
6685
7106
|
style: { position: "relative", padding: "10px 12px" },
|
|
6686
|
-
children: /* @__PURE__ */ (0,
|
|
7107
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6687
7108
|
WingWheel,
|
|
6688
7109
|
{
|
|
6689
7110
|
mode: mode || "auto",
|