Update story summary recall and prompt injection
This commit is contained in:
@@ -8,6 +8,7 @@ import { generateSummary, parseSummaryJson } from "./llm.js";
|
||||
|
||||
const MODULE_ID = 'summaryGenerator';
|
||||
const SUMMARY_SESSION_ID = 'xb9';
|
||||
const MAX_CAUSED_BY = 2;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// worldUpdate 清洗
|
||||
@@ -45,6 +46,57 @@ function sanitizeWorldUpdate(parsed) {
|
||||
parsed.worldUpdate = ok;
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// causedBy 清洗(事件因果边)
|
||||
// - 允许引用:已存在事件 + 本次新输出事件
|
||||
// - 限制长度:0-2
|
||||
// - 去重、剔除非法ID、剔除自引用
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
function sanitizeEventsCausality(parsed, existingEventIds) {
|
||||
if (!parsed) return;
|
||||
|
||||
const events = Array.isArray(parsed.events) ? parsed.events : [];
|
||||
if (!events.length) return;
|
||||
|
||||
const idRe = /^evt-\d+$/;
|
||||
|
||||
// 本次新输出事件ID集合(允许引用)
|
||||
const newIds = new Set(
|
||||
events
|
||||
.map(e => String(e?.id || '').trim())
|
||||
.filter(id => idRe.test(id))
|
||||
);
|
||||
|
||||
const allowed = new Set([...(existingEventIds || []), ...newIds]);
|
||||
|
||||
for (const e of events) {
|
||||
const selfId = String(e?.id || '').trim();
|
||||
if (!idRe.test(selfId)) {
|
||||
// id 不合格的话,causedBy 直接清空,避免污染
|
||||
e.causedBy = [];
|
||||
continue;
|
||||
}
|
||||
|
||||
const raw = Array.isArray(e.causedBy) ? e.causedBy : [];
|
||||
const out = [];
|
||||
const seen = new Set();
|
||||
|
||||
for (const x of raw) {
|
||||
const cid = String(x || '').trim();
|
||||
if (!idRe.test(cid)) continue;
|
||||
if (cid === selfId) continue;
|
||||
if (!allowed.has(cid)) continue;
|
||||
if (seen.has(cid)) continue;
|
||||
seen.add(cid);
|
||||
out.push(cid);
|
||||
if (out.length >= MAX_CAUSED_BY) break;
|
||||
}
|
||||
|
||||
e.causedBy = out;
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// 辅助函数
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
@@ -180,6 +232,8 @@ export async function runSummaryGeneration(mesId, config, callbacks = {}) {
|
||||
}
|
||||
|
||||
sanitizeWorldUpdate(parsed);
|
||||
const existingEventIds = new Set((store?.json?.events || []).map(e => e?.id).filter(Boolean));
|
||||
sanitizeEventsCausality(parsed, existingEventIds);
|
||||
|
||||
const merged = mergeNewData(store?.json || {}, parsed, slice.endMesId);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// LLM Service
|
||||
|
||||
const PROVIDER_MAP = {
|
||||
// ...
|
||||
openai: "openai",
|
||||
google: "gemini",
|
||||
gemini: "gemini",
|
||||
@@ -35,6 +36,7 @@ Incremental_Summary_Requirements:
|
||||
- 转折: 改变某条线走向
|
||||
- 点睛: 有细节不影响主线
|
||||
- 氛围: 纯粹氛围片段
|
||||
- Causal_Chain: 为每个新事件标注直接前因事件ID(causedBy),0-2个。只填 evt-数字 形式,必须指向“已存在事件”或“本次新输出事件”。不要写解释文字。
|
||||
- Character_Dynamics: 识别新角色,追踪关系趋势(破裂/厌恶/反感/陌生/投缘/亲密/交融)
|
||||
- Arc_Tracking: 更新角色弧光轨迹与成长进度(0.0-1.0)
|
||||
- World_State_Tracking: 维护当前世界的硬性约束。解决"什么不能违反"。采用 KV 覆盖模型,追踪生死、物品归属、秘密知情、关系状态、环境规则等不可违背的事实。(覆盖式更新)
|
||||
@@ -171,7 +173,8 @@ Before generating, observe the USER and analyze carefully:
|
||||
"summary": "1-2句话描述,涵盖丰富信息素,末尾标注楼层(#X-Y)",
|
||||
"participants": ["参与角色名"],
|
||||
"type": "相遇|冲突|揭示|抉择|羁绊|转变|收束|日常",
|
||||
"weight": "核心|主线|转折|点睛|氛围"
|
||||
"weight": "核心|主线|转折|点睛|氛围",
|
||||
"causedBy": ["evt-12", "evt-14"]
|
||||
}
|
||||
],
|
||||
"newCharacters": ["仅本次首次出现的角色名"],
|
||||
@@ -211,6 +214,10 @@ Before generating, observe the USER and analyze carefully:
|
||||
- events.id 从 evt-{nextEventId} 开始编号
|
||||
- 仅输出【增量】内容,已有事件绝不重复
|
||||
- keywords 是全局关键词,综合已有+新增
|
||||
- causedBy 规则:
|
||||
- 数组,最多2个;无前因则 []
|
||||
- 只能填 evt-数字(例如 evt-12)
|
||||
- 必须引用“已存在事件”或“本次新输出事件”(允许引用本次 JSON 内较早出现的事件)
|
||||
- worldUpdate 可为空数组
|
||||
- 合法JSON,字符串值内部避免英文双引号
|
||||
- 用小说家的细腻笔触记录,带烟火气
|
||||
@@ -441,4 +448,4 @@ export async function generateSummary(options) {
|
||||
console.groupEnd();
|
||||
|
||||
return rawOutput;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user