预设可以带一段手写的假历史,按真多轮发出去。
它进对话历史区、占真实轮次,跟酒馆示例对话(只做示范、不占轮次)不是一回事,所以要分开存:有它时排在真实历史之前,宏照样展开。
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
Reference in New Issue
Block a user