feat(summary): update prompt display, metrics lexical gate, and edge sanitization

This commit is contained in:
2026-02-11 22:01:02 +08:00
parent ca117b334f
commit 9f279d902f
4 changed files with 275 additions and 306 deletions

View File

@@ -1,5 +1,5 @@
// ═══════════════════════════════════════════════════════════════════════════
// Story Summary - Prompt Injection (v6 - EvidenceGroup: per-floor L0 + shared L1)
// Story Summary - Prompt Injection (v7 - L0 scene-based display)
//
// 命名规范:
// - 存储层用 L0/L1/L2/L3StateAtom/Chunk/Event/Fact
@@ -7,11 +7,7 @@
//
// 架构变更v5 → v6
// - 同楼层多个 L0 共享一对 L1EvidenceGroup per-floor
// - L0 展示文本 semantic 字段改为从结构字段type/subject/object/value/location拼接
// - 移除 <type> 标签和 [tags] theme 标签,输出自然语言短句
// - 短行分号拼接长行换行120字阈值
//
// 职责:
// - L0 展示文本直接使用 semantic 字段v7: 场景摘要,纯自然语言)
// - 仅负责"构建注入文本",不负责写入 extension_prompts
// - 注入发生在 story-summary.jsGENERATION_STARTED 时写入 extension_prompts
// ═══════════════════════════════════════════════════════════════════════════
@@ -297,84 +293,16 @@ function formatArcLine(arc) {
}
/**
* 从 atom 结构字段生成可读短句(不依赖 semantic 字段)
* 从 L0 获取展示文本
*
* 规则:
* - act: 主体+谓词+客体
* - emo: 主体+谓词+(对客体)
* - rev: 揭示:谓词+(关于客体)
* - dec: 主体+谓词+(对客体)
* - ten: 主体与客体之间:谓词
* - loc: 场景:地点或谓词
* - 地点非空且非 loc 类型时后缀 "在{location}"
* v7: L0 的 semantic 字段已是纯自然语言场景摘要60-100字直接使用。
*
* @param {object} l0 - L0 对象(含 l0.atom
* @returns {string} 可读短句
* @param {object} l0 - L0 对象
* @returns {string} 场景描述文本
*/
function buildL0DisplayText(l0) {
const atom = l0.atom || l0._atom || {};
const type = atom.type || 'act';
const subject = String(atom.subject || '').trim();
const object = String(atom.object || '').trim();
const value = String(atom.value || '').trim();
const location = String(atom.location || '').trim();
if (!value && !subject) {
// 兜底:如果结构字段缺失,回退到 semantic 并剥离标签
const semantic = String(atom.semantic || l0.text || '').trim();
return semantic
.replace(/^<\w+>\s*/, '')
.replace(/\s*\[[\w/]+\]\s*$/, '')
.trim() || '(未知锚点)';
}
let result = '';
switch (type) {
case 'emo':
result = `${subject}${value}`;
if (object) result += `(对${object})`;
break;
case 'act':
result = `${subject}${value}`;
if (object) result += `${object}`;
break;
case 'rev':
result = `揭示:${value}`;
if (object) result += `(关于${object})`;
break;
case 'dec':
result = `${subject}${value}`;
if (object) result += `(对${object})`;
break;
case 'ten':
if (object) {
result = `${subject}${object}之间:${value}`;
} else {
result = `${subject}${value}`;
}
break;
case 'loc':
result = `场景:${location || value}`;
break;
default:
result = `${subject}${value}`;
if (object) result += `${object}`;
break;
}
// 地点后缀loc 类型已包含地点,不重复)
if (location && type !== 'loc') {
result += `${location}`;
}
return result.trim();
const atom = l0.atom || {};
return String(atom.scene || atom.semantic || l0.text || '').trim() || '(未知锚点)';
}
/**