预设可以带一段手写的假历史,按真多轮发出去。

它进对话历史区、占真实轮次,跟酒馆示例对话(只做示范、不占轮次)不是一回事,所以要分开存:有它时排在真实历史之前,宏照样展开。
This commit is contained in:
2026-10-26 01:09:29 +08:00
parent 7e7b9c5083
commit 860eff59b2
4 changed files with 251 additions and 2 deletions
+10 -2
View File
@@ -23,6 +23,7 @@ import {
SCENARIO_MARKER,
} from "./markers.js";
import { parseExampleDialogue } from "./examples.js";
import { mergePseudoHistory, readPseudoHistory } from "./pseudo-history.js";
import {
applyRegexScripts,
readRegexScripts,
@@ -144,8 +145,15 @@ export function assemblePlayWorkerMessages(params: {
]
: [];
const scripts = readRegexScripts(params.preset.raw);
const history = regexHistoryMessages(pack.history, scripts, (text) =>
expandPresetDirectives(text, dirCtx).text,
// 假历史:作者手写的前情 → 真多轮,排在真实历史之前(一样要展开宏)。
const pseudo: ChatMessage[] = readPseudoHistory(params.preset).map((turn) => ({
role: turn.role,
content: expandPresetDirectives(turn.content, dirCtx).text,
}));
const history = regexHistoryMessages(
mergePseudoHistory(pseudo, pack.history),
scripts,
(text) => expandPresetDirectives(text, dirCtx).text,
);
const all = head.length > 0 ? [...head, ...history] : history;
return all.length > 0 ? all : null;
+41
View File
@@ -0,0 +1,41 @@
import type { ChatMessage } from "../llm/client.js";
import type { PresetChatTurn, PresetPackage } from "../types/preset.js";
/**
* 假历史:预设作者手写的前情,按真多轮(user / assistant)进「对话.历史」区。
* 属于历史,不属于示例对话(`mes_example` → system + example_user/example_assistant)。
*
* 只认 user / assistant:这里没有 system 的语义,作者想加系统提示就写一条普通模块。
* 脏数据(角色不认、内容非字符串或空白)一律丢掉,不抛。
*/
export function normalizePseudoHistory(value: unknown): PresetChatTurn[] {
if (!Array.isArray(value)) return [];
const out: PresetChatTurn[] = [];
for (const item of value) {
if (!item || typeof item !== "object") continue;
const { role, content } = item as Partial<PresetChatTurn>;
if (role !== "user" && role !== "assistant") continue;
if (typeof content !== "string" || !content.trim()) continue;
out.push({ role, content });
}
return out;
}
/** 读预设上的假历史。 */
export function readPseudoHistory(
preset: PresetPackage | null | undefined,
): PresetChatTurn[] {
return normalizePseudoHistory(preset?.pseudoHistory);
}
/**
* 假历史在前(作者写的前情),真实轮次在后。
* 返回的都是普通 message,交给「对话.历史」洞展开时再打历史区记号。
*/
export function mergePseudoHistory(
pseudo: ReadonlyArray<ChatMessage>,
history: ChatMessage[],
): ChatMessage[] {
if (pseudo.length === 0) return history;
return [...pseudo, ...history];
}