dsh-prime-memory 0.24.1 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.en.md +22 -0
- package/CHANGELOG.ja.md +22 -0
- package/CHANGELOG.ko.md +22 -0
- package/CHANGELOG.md +22 -0
- package/dist/client.js +189 -172
- package/dist/config.d.ts +12 -0
- package/dist/config.js +4 -0
- package/dist/contract.d.ts +36 -0
- package/dist/keyword-backfill.d.ts +46 -0
- package/dist/keyword-backfill.js +143 -0
- package/dist/metadata-validators.d.ts +9 -0
- package/dist/metadata-validators.js +31 -0
- package/dist/stats.d.ts +6 -0
- package/dist/stats.js +25 -0
- package/dist/store/l1.d.ts +6 -0
- package/dist/store/l1.js +8 -0
- package/dist/store/memory-backend-worker.d.ts +1 -0
- package/dist/store/memory-backend-worker.js +3 -0
- package/dist/store/memory-backend.d.ts +3 -0
- package/dist/store/memory-backend.js +3 -0
- package/dist/store/memory-md-disable.js +1 -1
- package/dist/store/memory-md-sync.js +1 -1
- package/dist/store/memory-worker.js +3 -0
- package/dist/store/sqlite.d.ts +11 -0
- package/dist/store/sqlite.js +57 -6
- package/dsh.plugin.json +1 -1
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -2078,7 +2078,7 @@ var __defProp = Object.defineProperty;
|
|
|
2078
2078
|
const showInput = scope === "all" || scope === "input";
|
|
2079
2079
|
const effNote = layers.map((l) => eff[l[0]] || "?").join(" / ");
|
|
2080
2080
|
const rowLabel = (key) => key === "extract" ? "抽取输出" : key === "dedup" ? "去重输出" : key === "l2" ? "L2 输出" : "L3 输出";
|
|
2081
|
-
const
|
|
2081
|
+
const rowStyle = { display: "flex", alignItems: "center", gap: 8 };
|
|
2082
2082
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
|
|
2083
2083
|
showOutputs ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginTop: 12 }, children: [
|
|
2084
2084
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
@@ -2089,7 +2089,7 @@ var __defProp = Object.defineProperty;
|
|
|
2089
2089
|
children: "输出预算"
|
|
2090
2090
|
}
|
|
2091
2091
|
),
|
|
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:
|
|
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: rowStyle, children: [
|
|
2093
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]) }),
|
|
2094
2094
|
inputBox(
|
|
2095
2095
|
l[0],
|
|
@@ -2111,7 +2111,7 @@ var __defProp = Object.defineProperty;
|
|
|
2111
2111
|
children: "输入预算"
|
|
2112
2112
|
}
|
|
2113
2113
|
),
|
|
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:
|
|
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: rowStyle, children: [
|
|
2115
2115
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { width: 68, flexShrink: 0, fontSize: 12, color: "var(--dsh-mem-text-2)" }, children: "单次输入" }),
|
|
2116
2116
|
inputBox(
|
|
2117
2117
|
"input",
|
|
@@ -4495,6 +4495,39 @@ var __defProp = Object.defineProperty;
|
|
|
4495
4495
|
children: "用 " + m.usage.used + "/" + m.usage.attempts
|
|
4496
4496
|
}
|
|
4497
4497
|
) : null,
|
|
4498
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4499
|
+
"span",
|
|
4500
|
+
{
|
|
4501
|
+
title: m.name && m.name.length > 0 ? "名称(名称蒸馏产物;投射文件的命名取它):" + m.name : "尚未命名(名称蒸馏未产出);投射回落 mem-" + m.id.slice(-8),
|
|
4502
|
+
style: {
|
|
4503
|
+
fontSize: 11,
|
|
4504
|
+
padding: "1px 6px",
|
|
4505
|
+
borderRadius: 999,
|
|
4506
|
+
whiteSpace: "nowrap",
|
|
4507
|
+
maxWidth: 220,
|
|
4508
|
+
overflow: "hidden",
|
|
4509
|
+
textOverflow: "ellipsis",
|
|
4510
|
+
border: "1px solid " + (m.name && m.name.length > 0 ? "var(--dsh-mem-border)" : "var(--dsh-mem-danger)"),
|
|
4511
|
+
color: m.name && m.name.length > 0 ? "var(--dsh-mem-text-2)" : "var(--dsh-mem-danger)"
|
|
4512
|
+
},
|
|
4513
|
+
children: "名称 " + (m.name && m.name.length > 0 ? m.name : "未命名")
|
|
4514
|
+
}
|
|
4515
|
+
),
|
|
4516
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4517
|
+
"span",
|
|
4518
|
+
{
|
|
4519
|
+
title: m.scope === "workspace" ? "作用范围:指定工作区(仅归属工作区可见)" + (m.workspaceId ? ":" + m.workspaceId : "") : "作用范围:用户默认(global,任何工作区可见)",
|
|
4520
|
+
style: {
|
|
4521
|
+
fontSize: 11,
|
|
4522
|
+
padding: "1px 6px",
|
|
4523
|
+
borderRadius: 999,
|
|
4524
|
+
whiteSpace: "nowrap",
|
|
4525
|
+
border: "1px solid var(--dsh-mem-border)",
|
|
4526
|
+
color: "var(--dsh-mem-text-2)"
|
|
4527
|
+
},
|
|
4528
|
+
children: m.scope === "workspace" ? "工作区" : "用户默认"
|
|
4529
|
+
}
|
|
4530
|
+
),
|
|
4498
4531
|
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
4532
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
|
|
4500
4533
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: fmtTime(m.updatedAt) }),
|
|
@@ -4523,7 +4556,7 @@ var __defProp = Object.defineProperty;
|
|
|
4523
4556
|
) : null
|
|
4524
4557
|
] }),
|
|
4525
4558
|
/* @__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
|
|
4559
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.detail, children: "id: " + m.id + "\n名称: " + (m.name && m.name.length > 0 ? m.name : "(未命名,投射回落 mem-" + m.id.slice(-8) + ")") + "\n情境: " + (m.scene || "-") + "\n关键词: " + (m.keywords && m.keywords.length > 0 ? m.keywords.join(",") : "(暂无 · 预留检索轴)") + "\n作用范围: " + (m.scope === "workspace" ? "指定工作区" + (m.workspaceId ? ":" + m.workspaceId : "(未记录路径)") : "用户默认(global,任何工作区可见)") + "\n版本: v" + m.version + "(去重合并次数 " + m.version + ")\n创建: " + fmtTime(m.createdAt) + "\n活跃时间: " + (m.timestamps && m.timestamps.length > 0 ? m.timestamps.map(fmtTime).join(" → ") : "-") + "\n" + (m.sourceAnchors && m.sourceAnchors.length > 0 ? "来源锚点: " + m.sourceAnchors.join(", ") : "来源锚点: -") }) : null
|
|
4527
4560
|
]
|
|
4528
4561
|
},
|
|
4529
4562
|
m.id
|
|
@@ -5836,7 +5869,7 @@ var __defProp = Object.defineProperty;
|
|
|
5836
5869
|
}
|
|
5837
5870
|
|
|
5838
5871
|
// client/src/pill/MemoryModePill.tsx
|
|
5839
|
-
var
|
|
5872
|
+
var import_react25 = require("react");
|
|
5840
5873
|
|
|
5841
5874
|
// src/util/context-occupancy.ts
|
|
5842
5875
|
var CONTEXT_METER_CIRCUMFERENCE = 34.55751918948772;
|
|
@@ -6152,7 +6185,7 @@ var __defProp = Object.defineProperty;
|
|
|
6152
6185
|
}
|
|
6153
6186
|
|
|
6154
6187
|
// client/src/pill/WingWheel.tsx
|
|
6155
|
-
var
|
|
6188
|
+
var import_react24 = require("react");
|
|
6156
6189
|
|
|
6157
6190
|
// client/src/pill/SessionInfoArea.tsx
|
|
6158
6191
|
var import_react23 = require("react");
|
|
@@ -6263,101 +6296,8 @@ var __defProp = Object.defineProperty;
|
|
|
6263
6296
|
] });
|
|
6264
6297
|
}
|
|
6265
6298
|
|
|
6266
|
-
// client/src/pill/SessionRecalledArea.tsx
|
|
6267
|
-
var import_react24 = require("react");
|
|
6268
|
-
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
6269
|
-
var SHOW_CAP = 6;
|
|
6270
|
-
var POLL_MS2 = 4e3;
|
|
6271
|
-
var MATURITY_LABEL = { high: "成熟·高", mid: "成熟·中", low: "成熟·低" };
|
|
6272
|
-
function SessionRecalledArea(props) {
|
|
6273
|
-
const rpc = props.rpc;
|
|
6274
|
-
const sessionId = props.sessionId;
|
|
6275
|
-
const [records, setRecords] = (0, import_react24.useState)(void 0);
|
|
6276
|
-
(0, import_react24.useEffect)(() => {
|
|
6277
|
-
if (!rpc || !sessionId) return void 0;
|
|
6278
|
-
let alive = true;
|
|
6279
|
-
let timer = null;
|
|
6280
|
-
let seq = 0;
|
|
6281
|
-
const tick = () => {
|
|
6282
|
-
const token = ++seq;
|
|
6283
|
-
rpc("dsh-memory/session-recalled", { sessionId }).then((r) => {
|
|
6284
|
-
if (!alive || token !== seq) return;
|
|
6285
|
-
if (r && r.ok && r.value) {
|
|
6286
|
-
registerTypeCatalog(r.value.typeCatalog);
|
|
6287
|
-
setRecords(r.value.records);
|
|
6288
|
-
}
|
|
6289
|
-
}).catch(() => {
|
|
6290
|
-
}).then(() => {
|
|
6291
|
-
if (alive) timer = setTimeout(tick, POLL_MS2);
|
|
6292
|
-
});
|
|
6293
|
-
};
|
|
6294
|
-
tick();
|
|
6295
|
-
return () => {
|
|
6296
|
-
alive = false;
|
|
6297
|
-
if (timer) clearTimeout(timer);
|
|
6298
|
-
};
|
|
6299
|
-
}, [rpc, sessionId]);
|
|
6300
|
-
if (records === void 0) return null;
|
|
6301
|
-
const rows = records.filter((r) => r.superseded !== true || r.retired === true);
|
|
6302
|
-
const recentFirst = [...rows].reverse();
|
|
6303
|
-
const shown = recentFirst.slice(0, SHOW_CAP);
|
|
6304
|
-
const hidden = recentFirst.length - shown.length;
|
|
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)(
|
|
6308
|
-
"div",
|
|
6309
|
-
{
|
|
6310
|
-
style: { fontSize: 11, color: "var(--dsh-mem-text-3)", marginBottom: 6 },
|
|
6311
|
-
title: "本会话召回、且正文仍在上下文里的记忆(正文被摘要顶掉的已折叠不显示;清空会话才清除;不是常驻注入)",
|
|
6312
|
-
children: "本会话召回 " + rows.length + " 条"
|
|
6313
|
-
}
|
|
6314
|
-
),
|
|
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)(
|
|
6321
|
-
"span",
|
|
6322
|
-
{
|
|
6323
|
-
className: tagClass(r.type),
|
|
6324
|
-
style: { flexShrink: 0, whiteSpace: "nowrap" },
|
|
6325
|
-
children: typeLabel(r.type)
|
|
6326
|
-
}
|
|
6327
|
-
),
|
|
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
|
|
6331
|
-
] }, r.id)),
|
|
6332
|
-
hidden > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: "+ " + hidden + " 条更早召回(详见面板「记忆」页)" }) : null
|
|
6333
|
-
] })
|
|
6334
|
-
] });
|
|
6335
|
-
}
|
|
6336
|
-
var rowStyle = {
|
|
6337
|
-
display: "flex",
|
|
6338
|
-
alignItems: "flex-start",
|
|
6339
|
-
gap: 6,
|
|
6340
|
-
lineHeight: "16px"
|
|
6341
|
-
};
|
|
6342
|
-
var textStyle = {
|
|
6343
|
-
fontSize: 12,
|
|
6344
|
-
lineHeight: "16px",
|
|
6345
|
-
fontWeight: 400,
|
|
6346
|
-
minWidth: 0,
|
|
6347
|
-
display: "-webkit-box",
|
|
6348
|
-
WebkitLineClamp: 2,
|
|
6349
|
-
WebkitBoxOrient: "vertical",
|
|
6350
|
-
overflow: "hidden"
|
|
6351
|
-
};
|
|
6352
|
-
var STALE_TEXT_STYLE = { ...textStyle, textDecoration: "line-through" };
|
|
6353
|
-
function rowTitle(r) {
|
|
6354
|
-
const head = "[" + typeLabel(r.type) + "] " + r.content;
|
|
6355
|
-
const sc = r.usageScenario && r.usageScenario.length > 0 ? "\n使用场景:" + r.usageScenario.join(";") : "";
|
|
6356
|
-
return head + sc;
|
|
6357
|
-
}
|
|
6358
|
-
|
|
6359
6299
|
// client/src/pill/WingWheel.tsx
|
|
6360
|
-
var
|
|
6300
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
6361
6301
|
var SIZE = 196;
|
|
6362
6302
|
var CENTER = SIZE / 2;
|
|
6363
6303
|
var R = 64;
|
|
@@ -6400,17 +6340,19 @@ var __defProp = Object.defineProperty;
|
|
|
6400
6340
|
function WingWheel(props) {
|
|
6401
6341
|
ensureThemeStyle();
|
|
6402
6342
|
const isOff = props.mode === "off";
|
|
6403
|
-
const [overview, setOverview] = (0,
|
|
6404
|
-
const [backfillBusy, setBackfillBusy] = (0,
|
|
6405
|
-
const [
|
|
6406
|
-
const
|
|
6407
|
-
(0,
|
|
6343
|
+
const [overview, setOverview] = (0, import_react24.useState)(null);
|
|
6344
|
+
const [backfillBusy, setBackfillBusy] = (0, import_react24.useState)(false);
|
|
6345
|
+
const [kwBusy, setKwBusy] = (0, import_react24.useState)(false);
|
|
6346
|
+
const [kwSummary, setKwSummary] = (0, import_react24.useState)(null);
|
|
6347
|
+
const [localError, setLocalError] = (0, import_react24.useState)(null);
|
|
6348
|
+
const timersRef = (0, import_react24.useRef)([]);
|
|
6349
|
+
(0, import_react24.useEffect)(
|
|
6408
6350
|
() => () => {
|
|
6409
6351
|
for (const t of timersRef.current) window.clearTimeout(t);
|
|
6410
6352
|
},
|
|
6411
6353
|
[]
|
|
6412
6354
|
);
|
|
6413
|
-
(0,
|
|
6355
|
+
(0, import_react24.useEffect)(() => {
|
|
6414
6356
|
let alive = true;
|
|
6415
6357
|
props.rpc("dsh-memory/wing-overview", {}).then((r) => {
|
|
6416
6358
|
if (!alive) return;
|
|
@@ -6456,28 +6398,80 @@ var __defProp = Object.defineProperty;
|
|
|
6456
6398
|
finish();
|
|
6457
6399
|
});
|
|
6458
6400
|
};
|
|
6459
|
-
const
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6401
|
+
const keywordBackfill = () => {
|
|
6402
|
+
if (kwBusy) return;
|
|
6403
|
+
setKwBusy(true);
|
|
6404
|
+
setKwSummary(null);
|
|
6405
|
+
setLocalError(null);
|
|
6406
|
+
let polls = 0;
|
|
6407
|
+
const finish = () => setKwBusy(false);
|
|
6408
|
+
const showResult = (v) => {
|
|
6409
|
+
const fail = v.failed ?? 0;
|
|
6410
|
+
setKwSummary(`关键词回填完成:成功 ${v.updated ?? 0} 条${fail > 0 ? `,失败 ${fail} 条` : ""}`);
|
|
6411
|
+
};
|
|
6412
|
+
const failMsg = (m) => {
|
|
6413
|
+
setLocalError(m);
|
|
6414
|
+
finish();
|
|
6415
|
+
};
|
|
6416
|
+
const tick = () => {
|
|
6417
|
+
polls++;
|
|
6418
|
+
props.rpc("dsh-memory/keyword-backfill", {}).then((r) => {
|
|
6419
|
+
const v = r && r.ok ? r.value : null;
|
|
6420
|
+
if (!v) {
|
|
6421
|
+
failMsg("关键词回填失败");
|
|
6422
|
+
return;
|
|
6423
|
+
}
|
|
6424
|
+
if (!v.enabled) {
|
|
6425
|
+
failMsg("关键词回填未开启:请先在设置里打开 keyword.enabled");
|
|
6426
|
+
return;
|
|
6427
|
+
}
|
|
6428
|
+
if (!v.running) {
|
|
6429
|
+
showResult(v);
|
|
6430
|
+
finish();
|
|
6431
|
+
return;
|
|
6432
|
+
}
|
|
6433
|
+
if (polls >= 20) {
|
|
6434
|
+
showResult(v);
|
|
6435
|
+
finish();
|
|
6436
|
+
return;
|
|
6437
|
+
}
|
|
6438
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
6439
|
+
}).catch(() => failMsg("关键词回填失败"));
|
|
6440
|
+
};
|
|
6441
|
+
props.rpc("dsh-memory/keyword-backfill", {}).then((r) => {
|
|
6442
|
+
if (!r || !r.ok) {
|
|
6443
|
+
failMsg(r && r.error ? "关键词回填失败:" + r.error.message : "关键词回填失败");
|
|
6444
|
+
return;
|
|
6445
|
+
}
|
|
6446
|
+
if (!r.value || !r.value.enabled) {
|
|
6447
|
+
failMsg("关键词回填未开启:请先在设置里打开 keyword.enabled");
|
|
6448
|
+
return;
|
|
6449
|
+
}
|
|
6450
|
+
timersRef.current.push(window.setTimeout(tick, 3e3));
|
|
6451
|
+
}).catch((e) => failMsg("关键词回填失败:" + String(e && e.message || e)));
|
|
6452
|
+
};
|
|
6453
|
+
const boxRef = (0, import_react24.useRef)(null);
|
|
6454
|
+
const startRef = (0, import_react24.useRef)(null);
|
|
6455
|
+
const movedRef = (0, import_react24.useRef)(false);
|
|
6456
|
+
const downIndexRef = (0, import_react24.useRef)(null);
|
|
6457
|
+
const dragTargetRef = (0, import_react24.useRef)(null);
|
|
6458
|
+
const [drag, setDrag] = (0, import_react24.useState)(null);
|
|
6465
6459
|
const lockedIndex = (() => {
|
|
6466
6460
|
if (props.halls.length !== 1 || !overview) return null;
|
|
6467
6461
|
const i = overview.corners.findIndex((c) => c.id === props.halls[0]);
|
|
6468
6462
|
return i >= 0 ? i : null;
|
|
6469
6463
|
})();
|
|
6470
6464
|
const activeCorner = drag ? drag.index : lockedIndex;
|
|
6471
|
-
const blockPosRef = (0,
|
|
6465
|
+
const blockPosRef = (0, import_react24.useRef)(
|
|
6472
6466
|
activeCorner != null ? cornerXY(activeCorner) : { x: CENTER, y: CENTER }
|
|
6473
6467
|
);
|
|
6474
|
-
const blockTargetRef = (0,
|
|
6475
|
-
const [blockPos, setBlockPos] = (0,
|
|
6476
|
-
(0,
|
|
6468
|
+
const blockTargetRef = (0, import_react24.useRef)(blockPosRef.current);
|
|
6469
|
+
const [blockPos, setBlockPos] = (0, import_react24.useState)(blockPosRef.current);
|
|
6470
|
+
(0, import_react24.useEffect)(() => {
|
|
6477
6471
|
blockTargetRef.current = activeCorner != null ? cornerXY(activeCorner) : { x: CENTER, y: CENTER };
|
|
6478
6472
|
}, [activeCorner]);
|
|
6479
|
-
const reducedMotionRef = (0,
|
|
6480
|
-
(0,
|
|
6473
|
+
const reducedMotionRef = (0, import_react24.useRef)(false);
|
|
6474
|
+
(0, import_react24.useEffect)(() => {
|
|
6481
6475
|
const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
6482
6476
|
const apply2 = () => {
|
|
6483
6477
|
reducedMotionRef.current = mq.matches;
|
|
@@ -6486,7 +6480,7 @@ var __defProp = Object.defineProperty;
|
|
|
6486
6480
|
mq.addEventListener("change", apply2);
|
|
6487
6481
|
return () => mq.removeEventListener("change", apply2);
|
|
6488
6482
|
}, []);
|
|
6489
|
-
(0,
|
|
6483
|
+
(0, import_react24.useEffect)(() => {
|
|
6490
6484
|
let raf = 0;
|
|
6491
6485
|
const loop = () => {
|
|
6492
6486
|
const cur = blockPosRef.current;
|
|
@@ -6575,8 +6569,8 @@ var __defProp = Object.defineProperty;
|
|
|
6575
6569
|
}).join(" ");
|
|
6576
6570
|
const grayStyle = isOff ? { opacity: 0.45, pointerEvents: "none" } : {};
|
|
6577
6571
|
const boundariesDisabled = props.halls.length === 0 || isOff;
|
|
6578
|
-
return /* @__PURE__ */ (0,
|
|
6579
|
-
/* @__PURE__ */ (0,
|
|
6572
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { width: SIZE }, children: [
|
|
6573
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
6580
6574
|
"div",
|
|
6581
6575
|
{
|
|
6582
6576
|
ref: boxRef,
|
|
@@ -6586,7 +6580,7 @@ var __defProp = Object.defineProperty;
|
|
|
6586
6580
|
onPointerUp: onBoxUp,
|
|
6587
6581
|
onPointerCancel: onBoxUp,
|
|
6588
6582
|
children: [
|
|
6589
|
-
/* @__PURE__ */ (0,
|
|
6583
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
6590
6584
|
"svg",
|
|
6591
6585
|
{
|
|
6592
6586
|
width: SIZE,
|
|
@@ -6594,7 +6588,7 @@ var __defProp = Object.defineProperty;
|
|
|
6594
6588
|
style: { position: "absolute", inset: 0, pointerEvents: "none" },
|
|
6595
6589
|
"aria-hidden": "true",
|
|
6596
6590
|
children: [
|
|
6597
|
-
/* @__PURE__ */ (0,
|
|
6591
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6598
6592
|
"polygon",
|
|
6599
6593
|
{
|
|
6600
6594
|
points: polyPoints,
|
|
@@ -6605,7 +6599,7 @@ var __defProp = Object.defineProperty;
|
|
|
6605
6599
|
opacity: 0.45
|
|
6606
6600
|
}
|
|
6607
6601
|
),
|
|
6608
|
-
/* @__PURE__ */ (0,
|
|
6602
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6609
6603
|
"polygon",
|
|
6610
6604
|
{
|
|
6611
6605
|
points: polyPoints,
|
|
@@ -6616,7 +6610,7 @@ var __defProp = Object.defineProperty;
|
|
|
6616
6610
|
),
|
|
6617
6611
|
[0, 1, 2, 3, 4, 5, 6, 7].map((i) => {
|
|
6618
6612
|
const p = cornerPos(i);
|
|
6619
|
-
return /* @__PURE__ */ (0,
|
|
6613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6620
6614
|
"line",
|
|
6621
6615
|
{
|
|
6622
6616
|
x1: CENTER,
|
|
@@ -6632,7 +6626,7 @@ var __defProp = Object.defineProperty;
|
|
|
6632
6626
|
]
|
|
6633
6627
|
}
|
|
6634
6628
|
),
|
|
6635
|
-
/* @__PURE__ */ (0,
|
|
6629
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6636
6630
|
"div",
|
|
6637
6631
|
{
|
|
6638
6632
|
"aria-hidden": "true",
|
|
@@ -6651,7 +6645,7 @@ var __defProp = Object.defineProperty;
|
|
|
6651
6645
|
}
|
|
6652
6646
|
}
|
|
6653
6647
|
),
|
|
6654
|
-
/* @__PURE__ */ (0,
|
|
6648
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6655
6649
|
"button",
|
|
6656
6650
|
{
|
|
6657
6651
|
type: "button",
|
|
@@ -6685,7 +6679,7 @@ var __defProp = Object.defineProperty;
|
|
|
6685
6679
|
const dim = activeCorner != null && !active;
|
|
6686
6680
|
const empty = count === 0;
|
|
6687
6681
|
const p = cornerPos(i);
|
|
6688
|
-
return /* @__PURE__ */ (0,
|
|
6682
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
6689
6683
|
"div",
|
|
6690
6684
|
{
|
|
6691
6685
|
title: id ? `「${label}」${count ?? 0} 条
|
|
@@ -6714,8 +6708,8 @@ var __defProp = Object.defineProperty;
|
|
|
6714
6708
|
zIndex: 2
|
|
6715
6709
|
},
|
|
6716
6710
|
children: [
|
|
6717
|
-
/* @__PURE__ */ (0,
|
|
6718
|
-
/* @__PURE__ */ (0,
|
|
6711
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: label }),
|
|
6712
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 8, opacity: 0.75, fontVariantNumeric: "tabular-nums" }, children: count === null ? " " : empty ? "空角" : `${count} 条` })
|
|
6719
6713
|
]
|
|
6720
6714
|
},
|
|
6721
6715
|
id ?? i
|
|
@@ -6724,7 +6718,7 @@ var __defProp = Object.defineProperty;
|
|
|
6724
6718
|
]
|
|
6725
6719
|
}
|
|
6726
6720
|
),
|
|
6727
|
-
/* @__PURE__ */ (0,
|
|
6721
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
6728
6722
|
"div",
|
|
6729
6723
|
{
|
|
6730
6724
|
title: props.halls.length === 0 ? "选定某个角(单 Wing)后,这两项才生效" : "锁定 Wing 时两类无角记忆是否参与召回",
|
|
@@ -6738,9 +6732,9 @@ var __defProp = Object.defineProperty;
|
|
|
6738
6732
|
pointerEvents: boundariesDisabled ? "none" : void 0
|
|
6739
6733
|
},
|
|
6740
6734
|
children: [
|
|
6741
|
-
/* @__PURE__ */ (0,
|
|
6742
|
-
/* @__PURE__ */ (0,
|
|
6743
|
-
/* @__PURE__ */ (0,
|
|
6735
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: overview ? `另有 ${overview.unlabeled} 条未打标` : "未打标" }),
|
|
6736
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
6737
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6744
6738
|
Segmented,
|
|
6745
6739
|
{
|
|
6746
6740
|
value: props.hallIncludeUnlabeled ? "in" : "ex",
|
|
@@ -6751,7 +6745,7 @@ var __defProp = Object.defineProperty;
|
|
|
6751
6745
|
onChange: (key) => props.onCommitWingBoundaries({ includeUnlabeled: key === "in" })
|
|
6752
6746
|
}
|
|
6753
6747
|
),
|
|
6754
|
-
/* @__PURE__ */ (0,
|
|
6748
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6755
6749
|
Segmented,
|
|
6756
6750
|
{
|
|
6757
6751
|
value: props.hallIncludeGeneral ? "in" : "ex",
|
|
@@ -6766,7 +6760,7 @@ var __defProp = Object.defineProperty;
|
|
|
6766
6760
|
]
|
|
6767
6761
|
}
|
|
6768
6762
|
),
|
|
6769
|
-
/* @__PURE__ */ (0,
|
|
6763
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Row, { label: "会话", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6770
6764
|
Segmented,
|
|
6771
6765
|
{
|
|
6772
6766
|
value: isOff ? "off" : "on",
|
|
@@ -6781,7 +6775,7 @@ var __defProp = Object.defineProperty;
|
|
|
6781
6775
|
onChange: (key) => props.onCommit(key === "off" ? "off" : "auto")
|
|
6782
6776
|
}
|
|
6783
6777
|
) }),
|
|
6784
|
-
props.recall !== void 0 && props.onCommitRecall ? /* @__PURE__ */ (0,
|
|
6778
|
+
props.recall !== void 0 && props.onCommitRecall ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Row, { label: "注入", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6785
6779
|
Segmented,
|
|
6786
6780
|
{
|
|
6787
6781
|
value: props.recall === null ? "follow" : props.recall ? "on" : "off",
|
|
@@ -6794,7 +6788,7 @@ var __defProp = Object.defineProperty;
|
|
|
6794
6788
|
onChange: (key) => props.onCommitRecall(key === "on" ? true : key === "off" ? false : null)
|
|
6795
6789
|
}
|
|
6796
6790
|
) }) : null,
|
|
6797
|
-
/* @__PURE__ */ (0,
|
|
6791
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
6798
6792
|
"div",
|
|
6799
6793
|
{
|
|
6800
6794
|
style: {
|
|
@@ -6805,8 +6799,8 @@ var __defProp = Object.defineProperty;
|
|
|
6805
6799
|
marginTop: 10
|
|
6806
6800
|
},
|
|
6807
6801
|
children: [
|
|
6808
|
-
/* @__PURE__ */ (0,
|
|
6809
|
-
/* @__PURE__ */ (0,
|
|
6802
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: overview ? `未打标 ${overview.unlabeled} 条` : "未打标计数加载中" }),
|
|
6803
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6810
6804
|
ActionButton,
|
|
6811
6805
|
{
|
|
6812
6806
|
label: backfillBusy ? "回填中…" : "回填",
|
|
@@ -6818,13 +6812,36 @@ var __defProp = Object.defineProperty;
|
|
|
6818
6812
|
]
|
|
6819
6813
|
}
|
|
6820
6814
|
),
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6815
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
6816
|
+
"div",
|
|
6817
|
+
{
|
|
6818
|
+
style: {
|
|
6819
|
+
display: "flex",
|
|
6820
|
+
justifyContent: "space-between",
|
|
6821
|
+
alignItems: "center",
|
|
6822
|
+
gap: 8,
|
|
6823
|
+
marginTop: 10
|
|
6824
|
+
},
|
|
6825
|
+
children: [
|
|
6826
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 11, color: "var(--dsh-mem-text-3)" }, children: kwSummary || "为存量记忆补检索关键词" }),
|
|
6827
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6828
|
+
ActionButton,
|
|
6829
|
+
{
|
|
6830
|
+
label: kwBusy ? "回填中…" : "关键词回填",
|
|
6831
|
+
title: "对缺 dsh_keywords 的存量记忆批量补关键词,喂 FTS 关键词检索轴(需先开 keyword.enabled)",
|
|
6832
|
+
disabled: kwBusy,
|
|
6833
|
+
onClick: () => keywordBackfill()
|
|
6834
|
+
}
|
|
6835
|
+
)
|
|
6836
|
+
]
|
|
6837
|
+
}
|
|
6838
|
+
),
|
|
6839
|
+
props.error || localError ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { fontSize: 11, color: "var(--dsh-mem-danger)", marginTop: 8 }, children: props.error || localError }) : null,
|
|
6840
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SessionInfoArea, { rpc: props.rpc, sessionId: props.sessionId })
|
|
6824
6841
|
] });
|
|
6825
6842
|
}
|
|
6826
6843
|
function Row(props) {
|
|
6827
|
-
return /* @__PURE__ */ (0,
|
|
6844
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
6828
6845
|
"div",
|
|
6829
6846
|
{
|
|
6830
6847
|
style: {
|
|
@@ -6834,7 +6851,7 @@ var __defProp = Object.defineProperty;
|
|
|
6834
6851
|
marginTop: 10
|
|
6835
6852
|
},
|
|
6836
6853
|
children: [
|
|
6837
|
-
/* @__PURE__ */ (0,
|
|
6854
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: 12, color: "var(--dsh-mem-text-3)" }, children: props.label }),
|
|
6838
6855
|
props.children
|
|
6839
6856
|
]
|
|
6840
6857
|
}
|
|
@@ -6842,9 +6859,9 @@ var __defProp = Object.defineProperty;
|
|
|
6842
6859
|
}
|
|
6843
6860
|
var LABEL_FALLBACK = ["工作", "人际", "学习", "创作娱乐", "居家", "健康", "财务", "出行"];
|
|
6844
6861
|
function useViewportClamp(popRef) {
|
|
6845
|
-
const shiftRef = (0,
|
|
6846
|
-
const [shiftX, setShiftX] = (0,
|
|
6847
|
-
(0,
|
|
6862
|
+
const shiftRef = (0, import_react24.useRef)(0);
|
|
6863
|
+
const [shiftX, setShiftX] = (0, import_react24.useState)(0);
|
|
6864
|
+
(0, import_react24.useEffect)(() => {
|
|
6848
6865
|
const clamp = () => {
|
|
6849
6866
|
const el = popRef.current;
|
|
6850
6867
|
if (!el) return;
|
|
@@ -6874,24 +6891,24 @@ var __defProp = Object.defineProperty;
|
|
|
6874
6891
|
}
|
|
6875
6892
|
|
|
6876
6893
|
// client/src/pill/MemoryModePill.tsx
|
|
6877
|
-
var
|
|
6894
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
6878
6895
|
function MemoryModePill(props) {
|
|
6879
6896
|
const rpc = props.rpc;
|
|
6880
6897
|
const sessionId = props.sessionId || props.session && props.session.sessionId;
|
|
6881
|
-
const [mode, setMode] = (0,
|
|
6882
|
-
const [recall, setRecall] = (0,
|
|
6883
|
-
const [recallResolved, setRecallResolved] = (0,
|
|
6884
|
-
const [halls, setWings] = (0,
|
|
6885
|
-
const [hallIncludeUnlabeled, setWingIncludeUnlabeled] = (0,
|
|
6886
|
-
const [hallIncludeGeneral, setWingIncludeGeneral] = (0,
|
|
6887
|
-
const [wingLabels, setHallLabels] = (0,
|
|
6888
|
-
const [error, setError] = (0,
|
|
6889
|
-
const [open, setOpen] = (0,
|
|
6890
|
-
const wrapRef = (0,
|
|
6891
|
-
const popRef = (0,
|
|
6898
|
+
const [mode, setMode] = (0, import_react25.useState)(null);
|
|
6899
|
+
const [recall, setRecall] = (0, import_react25.useState)(null);
|
|
6900
|
+
const [recallResolved, setRecallResolved] = (0, import_react25.useState)(true);
|
|
6901
|
+
const [halls, setWings] = (0, import_react25.useState)([]);
|
|
6902
|
+
const [hallIncludeUnlabeled, setWingIncludeUnlabeled] = (0, import_react25.useState)(true);
|
|
6903
|
+
const [hallIncludeGeneral, setWingIncludeGeneral] = (0, import_react25.useState)(false);
|
|
6904
|
+
const [wingLabels, setHallLabels] = (0, import_react25.useState)({});
|
|
6905
|
+
const [error, setError] = (0, import_react25.useState)(null);
|
|
6906
|
+
const [open, setOpen] = (0, import_react25.useState)(false);
|
|
6907
|
+
const wrapRef = (0, import_react25.useRef)(null);
|
|
6908
|
+
const popRef = (0, import_react25.useRef)(null);
|
|
6892
6909
|
const shiftX = useViewportClamp(popRef);
|
|
6893
|
-
const seqRef = (0,
|
|
6894
|
-
const load = (0,
|
|
6910
|
+
const seqRef = (0, import_react25.useRef)(0);
|
|
6911
|
+
const load = (0, import_react25.useCallback)(() => {
|
|
6895
6912
|
if (!sessionId || !rpc) return;
|
|
6896
6913
|
const token = ++seqRef.current;
|
|
6897
6914
|
setError(null);
|
|
@@ -6916,13 +6933,13 @@ var __defProp = Object.defineProperty;
|
|
|
6916
6933
|
}).catch(() => {
|
|
6917
6934
|
});
|
|
6918
6935
|
}, [sessionId, rpc]);
|
|
6919
|
-
(0,
|
|
6936
|
+
(0, import_react25.useEffect)(() => {
|
|
6920
6937
|
load();
|
|
6921
6938
|
}, [load]);
|
|
6922
|
-
(0,
|
|
6939
|
+
(0, import_react25.useEffect)(() => {
|
|
6923
6940
|
watchSidebarIcon();
|
|
6924
6941
|
}, []);
|
|
6925
|
-
(0,
|
|
6942
|
+
(0, import_react25.useEffect)(() => {
|
|
6926
6943
|
initOccupancyIndicator(
|
|
6927
6944
|
(endpoint, payload) => rpc(endpoint, payload)
|
|
6928
6945
|
);
|
|
@@ -6930,7 +6947,7 @@ var __defProp = Object.defineProperty;
|
|
|
6930
6947
|
watchContextMeter();
|
|
6931
6948
|
noteOccupancySession(sessionId ?? null);
|
|
6932
6949
|
}, [sessionId, rpc]);
|
|
6933
|
-
(0,
|
|
6950
|
+
(0, import_react25.useEffect)(() => {
|
|
6934
6951
|
if (!open) return;
|
|
6935
6952
|
const onDown = (e) => {
|
|
6936
6953
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -7070,8 +7087,8 @@ var __defProp = Object.defineProperty;
|
|
|
7070
7087
|
pillStyle.boxShadow = "0 0 12px color-mix(in srgb, " + info.color + " 30%, transparent)";
|
|
7071
7088
|
pillStyle["--dsh-mem-pill-tint"] = info.color;
|
|
7072
7089
|
}
|
|
7073
|
-
return /* @__PURE__ */ (0,
|
|
7074
|
-
/* @__PURE__ */ (0,
|
|
7090
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { ref: wrapRef, style: { position: "relative", display: "inline-flex" }, children: [
|
|
7091
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
7075
7092
|
"button",
|
|
7076
7093
|
{
|
|
7077
7094
|
type: "button",
|
|
@@ -7084,11 +7101,11 @@ var __defProp = Object.defineProperty;
|
|
|
7084
7101
|
style: pillStyle,
|
|
7085
7102
|
children: [
|
|
7086
7103
|
"记忆 · ",
|
|
7087
|
-
/* @__PURE__ */ (0,
|
|
7104
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: faceLabel })
|
|
7088
7105
|
]
|
|
7089
7106
|
}
|
|
7090
7107
|
),
|
|
7091
|
-
open ? /* @__PURE__ */ (0,
|
|
7108
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7092
7109
|
"div",
|
|
7093
7110
|
{
|
|
7094
7111
|
ref: popRef,
|
|
@@ -7099,12 +7116,12 @@ var __defProp = Object.defineProperty;
|
|
|
7099
7116
|
transform: "translateX(calc(-50% + " + shiftX + "px))",
|
|
7100
7117
|
zIndex: 1e3
|
|
7101
7118
|
},
|
|
7102
|
-
children: /* @__PURE__ */ (0,
|
|
7119
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7103
7120
|
"div",
|
|
7104
7121
|
{
|
|
7105
7122
|
className: "dsh-mem-popover",
|
|
7106
7123
|
style: { position: "relative", padding: "10px 12px" },
|
|
7107
|
-
children: /* @__PURE__ */ (0,
|
|
7124
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7108
7125
|
WingWheel,
|
|
7109
7126
|
{
|
|
7110
7127
|
mode: mode || "auto",
|
package/dist/config.d.ts
CHANGED
|
@@ -193,6 +193,18 @@ export interface MemoryConfig {
|
|
|
193
193
|
usageScenario: {
|
|
194
194
|
enabled: boolean;
|
|
195
195
|
};
|
|
196
|
+
/**
|
|
197
|
+
* 关键词蒸馏回填(keyword 检索轴的产出方):**独立回填批扫**,为缺 `metadata.dsh_keywords` 的
|
|
198
|
+
* L1 记录批量补关键词,喂 `l1_fts` 的关键词轴(`ftsKeywordText` 读该键)。由
|
|
199
|
+
* `dsh-memory/keyword-backfill` 端点触发,镜像 wing 回填(单飞/后台/有界)。
|
|
200
|
+
*
|
|
201
|
+
* **默认关**:关时不回填、不产该键、`l1_fts.keywords` 列逐字不变(零漂移)。护栏复用 `backfill`。
|
|
202
|
+
* 注:写回走 `patchMetadata` 只改主表,回填会**额外重索引该记录的 fts 行**(见 keyword-backfill),
|
|
203
|
+
* 否则关键词轴对存量记录不生效。
|
|
204
|
+
*/
|
|
205
|
+
keyword: {
|
|
206
|
+
enabled: boolean;
|
|
207
|
+
};
|
|
196
208
|
/**
|
|
197
209
|
* 类型叙述模板(G2):抽取时按 7 类型各自的“前因后果”骨架写 content。
|
|
198
210
|
*
|