phase2-4 recall prompt-flow hardening

This commit is contained in:
Youzini-afk
2026-04-11 18:51:50 +08:00
parent 3a10dbb9ba
commit 0cb95c4f2b
14 changed files with 1069 additions and 143 deletions

View File

@@ -12,6 +12,16 @@ const extensionsShimSource = [
const extensionsShimUrl = `data:text/javascript,${encodeURIComponent(
extensionsShimSource,
)}`;
const regexEngineShimSource = [
"export const regex_placement = { USER_INPUT: 1, AI_OUTPUT: 2, SLASH_COMMAND: 3, WORLD_INFO: 5, REASONING: 6 };",
"export function getRegexedString(...args) {",
" const fn = globalThis.__taskRegexTestCoreGetRegexedString;",
" return typeof fn === 'function' ? fn(...args) : String(args?.[0] ?? '');",
"}",
].join("\n");
const regexEngineShimUrl = `data:text/javascript,${encodeURIComponent(
regexEngineShimSource,
)}`;
installResolveHooks([
{
@@ -22,6 +32,10 @@ installResolveHooks([
],
url: extensionsShimUrl,
},
{
specifiers: ["../../../../regex/engine.js"],
url: regexEngineShimUrl,
},
]);
const originalSillyTavern = globalThis.SillyTavern;
@@ -29,6 +43,7 @@ const originalGetTavernRegexes = globalThis.getTavernRegexes;
const originalIsCharacterTavernRegexesEnabled =
globalThis.isCharacterTavernRegexesEnabled;
const originalExtensionSettings = globalThis.__taskRegexTestExtensionSettings;
const originalCoreGetRegexedString = globalThis.__taskRegexTestCoreGetRegexedString;
const PLACEMENT = Object.freeze({
USER_INPUT: 1,
@@ -146,6 +161,14 @@ function setTestContext({
};
}
function setCoreRegexedStringHandler(handler = null) {
if (typeof handler === "function") {
globalThis.__taskRegexTestCoreGetRegexedString = handler;
return;
}
delete globalThis.__taskRegexTestCoreGetRegexedString;
}
try {
const { initializeHostAdapter } = await import("../host/adapter/index.js");
const { applyHostRegexReuse, applyTaskRegex, inspectTaskRegexReuse } = await import(
@@ -157,6 +180,8 @@ try {
normalizeTaskProfile,
normalizeTaskRegexStages,
} = await import("../prompting/prompt-profiles.js");
const initializeFallbackHostAdapter = () =>
initializeHostAdapter({ disableCoreRegexBridge: true });
const normalizedLegacyStages = normalizeTaskRegexStages({
finalPrompt: true,
@@ -245,6 +270,48 @@ try {
true,
);
setTestContext({
extensionSettings: {
regex: [],
preset_allowed_regex: {},
character_allowed_regex: [],
},
});
const coreFormatterCalls = [];
setCoreRegexedStringHandler((text, placement, options) => {
coreFormatterCalls.push({ text, placement, options });
return String(text || "").replace(/Alpha/g, "CORE");
});
initializeHostAdapter({});
const coreBridgeDebug = { entries: [] };
const coreBridgeOutput = applyHostRegexReuse(
buildSettings(),
"extract",
"Alpha Beta",
{
sourceType: "user_input",
role: "user",
debugCollector: coreBridgeDebug,
},
);
assert.equal(coreBridgeOutput.text, "CORE Beta");
assert.deepEqual(coreFormatterCalls, [
{
text: "Alpha Beta",
placement: 1,
options: {
isPrompt: true,
isMarkdown: false,
},
},
]);
assert.equal(coreBridgeDebug.entries[0].executionMode, "host-real");
assert.equal(
inspectTaskRegexReuse(buildSettings(), "extract").host.bridgeTier,
"core-real",
);
setCoreRegexedStringHandler(null);
globalThis.getTavernRegexes = () => {
throw new Error("legacy global getter should not be used in regex tests");
};
@@ -333,11 +400,15 @@ try {
},
},
]);
assert.equal(fullBridgeDebug.entries[0].executionMode, "host-real");
assert.equal(fullBridgeDebug.entries[0].executionMode, "host-helper");
assert.deepEqual(
fullBridgeDebug.entries[0].appliedRules.map((item) => item.id),
["__host_formatter__"],
);
assert.equal(
inspectTaskRegexReuse(fullBridgeSettings, "extract").host.bridgeTier,
"helper-bridge",
);
assert.equal(
applyTaskRegex(
fullBridgeSettings,
@@ -383,7 +454,7 @@ try {
},
],
});
initializeHostAdapter({});
initializeFallbackHostAdapter();
const fallbackDebug = { entries: [] };
const fallbackOutput = applyHostRegexReuse(
@@ -412,7 +483,7 @@ try {
character_allowed_regex: [],
},
});
initializeHostAdapter({});
initializeFallbackHostAdapter();
const depthMissResult = applyHostRegexReuse(
buildSettings({
sources: {
@@ -476,7 +547,7 @@ try {
},
],
});
initializeHostAdapter({});
initializeFallbackHostAdapter();
const fallbackInspect = inspectTaskRegexReuse(buildSettings(), "extract");
assert.equal(fallbackInspect.activeRuleCount, 3);
assert.deepEqual(
@@ -525,7 +596,7 @@ try {
},
],
});
initializeHostAdapter({});
initializeFallbackHostAdapter();
const disallowedOutput = applyHostRegexReuse(
buildSettings(),
@@ -587,7 +658,7 @@ try {
character_allowed_regex: [],
},
});
initializeHostAdapter({});
initializeFallbackHostAdapter();
const userReuseResult = applyHostRegexReuse(
tavernSemanticsSettings,
@@ -641,7 +712,7 @@ try {
character_allowed_regex: [],
},
});
initializeHostAdapter({});
initializeFallbackHostAdapter();
const markdownFinalDebug = { entries: [] };
const markdownFallbackResult = applyHostRegexReuse(
markdownOnlyFinalPromptSettings,
@@ -675,7 +746,7 @@ try {
character_allowed_regex: [],
},
});
initializeHostAdapter({});
initializeFallbackHostAdapter();
const beautifyFinalInspect = inspectTaskRegexReuse(
beautifyFinalPromptSettings,
"extract",
@@ -759,7 +830,7 @@ try {
character_allowed_regex: [],
},
});
initializeHostAdapter({});
initializeFallbackHostAdapter();
const destinationDebug = { entries: [] };
const destinationReuseResult = applyHostRegexReuse(
destinationBeautifySettings,
@@ -817,7 +888,7 @@ try {
character_allowed_regex: [],
},
});
initializeHostAdapter({});
initializeFallbackHostAdapter();
const mixedReuseResult = applyHostRegexReuse(
tavernSemanticsSettings,
"extract",
@@ -889,6 +960,12 @@ try {
globalThis.__taskRegexTestExtensionSettings = originalExtensionSettings;
}
if (originalCoreGetRegexedString === undefined) {
delete globalThis.__taskRegexTestCoreGetRegexedString;
} else {
globalThis.__taskRegexTestCoreGetRegexedString = originalCoreGetRegexedString;
}
try {
const { initializeHostAdapter } = await import("../host/adapter/index.js");
initializeHostAdapter({});