mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
feat: integrate host bridge prompt pipeline
This commit is contained in:
296
tests/task-regex.mjs
Normal file
296
tests/task-regex.mjs
Normal file
@@ -0,0 +1,296 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { registerHooks } from "node:module";
|
||||
|
||||
const extensionsShimSource = [
|
||||
"export const extension_settings = globalThis.__taskRegexTestExtensionSettings || {};",
|
||||
"export function getContext(...args) {",
|
||||
" return globalThis.SillyTavern?.getContext?.(...args) || null;",
|
||||
"}",
|
||||
].join("\n");
|
||||
const extensionsShimUrl = `data:text/javascript,${encodeURIComponent(
|
||||
extensionsShimSource,
|
||||
)}`;
|
||||
|
||||
registerHooks({
|
||||
resolve(specifier, context, nextResolve) {
|
||||
if (specifier === "../../../extensions.js") {
|
||||
return {
|
||||
shortCircuit: true,
|
||||
url: extensionsShimUrl,
|
||||
};
|
||||
}
|
||||
return nextResolve(specifier, context);
|
||||
},
|
||||
});
|
||||
|
||||
const originalSillyTavern = globalThis.SillyTavern;
|
||||
const originalGetTavernRegexes = globalThis.getTavernRegexes;
|
||||
const originalIsCharacterTavernRegexesEnabled =
|
||||
globalThis.isCharacterTavernRegexesEnabled;
|
||||
const originalExtensionSettings = globalThis.__taskRegexTestExtensionSettings;
|
||||
|
||||
function createRule(id, find, replace, overrides = {}) {
|
||||
return {
|
||||
id,
|
||||
script_name: id,
|
||||
enabled: true,
|
||||
find_regex: find,
|
||||
replace_string: replace,
|
||||
source: {
|
||||
user_input: true,
|
||||
ai_output: true,
|
||||
...(overrides.source || {}),
|
||||
},
|
||||
destination: {
|
||||
prompt: true,
|
||||
display: false,
|
||||
...(overrides.destination || {}),
|
||||
},
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
globalThis.__taskRegexTestExtensionSettings = {
|
||||
regex: {
|
||||
regex_scripts: [createRule("legacy-global", "/Gamma/g", "G")],
|
||||
},
|
||||
};
|
||||
|
||||
globalThis.SillyTavern = {
|
||||
getContext() {
|
||||
return {
|
||||
extensionSettings: globalThis.__taskRegexTestExtensionSettings,
|
||||
chatCompletionSettings: {
|
||||
regex_scripts: [createRule("legacy-preset", "/Delta/g", "D")],
|
||||
},
|
||||
characterId: 0,
|
||||
characters: [
|
||||
{
|
||||
extensions: {
|
||||
regex_scripts: [
|
||||
createRule("legacy-character", "/Epsilon/g", "E"),
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
globalThis.getTavernRegexes = () => {
|
||||
throw new Error(
|
||||
"legacy global getter should not be used when bridge exists",
|
||||
);
|
||||
};
|
||||
globalThis.isCharacterTavernRegexesEnabled = () => {
|
||||
throw new Error(
|
||||
"legacy character toggle should not be used when bridge full capability exists",
|
||||
);
|
||||
};
|
||||
|
||||
const { initializeHostAdapter } = await import("../host-adapter/index.js");
|
||||
const { applyTaskRegex } = await import("../task-regex.js");
|
||||
|
||||
const settings = {
|
||||
taskProfiles: {
|
||||
extract: {
|
||||
activeProfileId: "bridge-profile",
|
||||
profiles: [
|
||||
{
|
||||
id: "bridge-profile",
|
||||
name: "Regex Bridge Test",
|
||||
taskType: "extract",
|
||||
builtin: false,
|
||||
blocks: [],
|
||||
regex: {
|
||||
enabled: true,
|
||||
inheritStRegex: true,
|
||||
sources: {
|
||||
global: true,
|
||||
preset: true,
|
||||
character: true,
|
||||
},
|
||||
stages: {
|
||||
input: true,
|
||||
output: true,
|
||||
},
|
||||
localRules: [createRule("local-tail", "/Beta/g", "B")],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const bridgeCalls = [];
|
||||
initializeHostAdapter({
|
||||
regexProvider: {
|
||||
getTavernRegexes(request) {
|
||||
bridgeCalls.push(request);
|
||||
if (request?.type === "global") {
|
||||
return [createRule("bridge-global", "/Alpha/g", "A")];
|
||||
}
|
||||
if (request?.type === "preset") {
|
||||
return [createRule("bridge-preset", "/A/g", "P")];
|
||||
}
|
||||
if (request?.type === "character") {
|
||||
return [createRule("bridge-character", "/P/g", "C")];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
isCharacterTavernRegexesEnabled() {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const fullBridgeDebug = { entries: [] };
|
||||
const fullBridgeOutput = applyTaskRegex(
|
||||
settings,
|
||||
"extract",
|
||||
"finalPrompt",
|
||||
"Alpha Beta",
|
||||
fullBridgeDebug,
|
||||
"system",
|
||||
);
|
||||
|
||||
assert.equal(fullBridgeOutput, "C B");
|
||||
assert.deepEqual(bridgeCalls, [
|
||||
{ type: "global" },
|
||||
{ type: "preset", name: "in_use" },
|
||||
{ type: "character", name: "current" },
|
||||
]);
|
||||
assert.deepEqual(
|
||||
fullBridgeDebug.entries[0].appliedRules.map((item) => item.id),
|
||||
["bridge-global", "bridge-preset", "bridge-character", "local-tail"],
|
||||
);
|
||||
assert.deepEqual(fullBridgeDebug.entries[0].sourceCount, {
|
||||
tavern: 3,
|
||||
local: 1,
|
||||
});
|
||||
|
||||
const partialBridgeCalls = [];
|
||||
initializeHostAdapter({
|
||||
regexProvider: {
|
||||
getTavernRegexes(request) {
|
||||
partialBridgeCalls.push(request);
|
||||
if (request?.type === "global") {
|
||||
return [createRule("partial-global", "/Gamma/g", "G1")];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const partialBridgeDebug = { entries: [] };
|
||||
const partialBridgeOutput = applyTaskRegex(
|
||||
settings,
|
||||
"extract",
|
||||
"finalPrompt",
|
||||
"Gamma Delta Epsilon",
|
||||
partialBridgeDebug,
|
||||
"system",
|
||||
);
|
||||
|
||||
assert.equal(partialBridgeOutput, "G1 Delta E");
|
||||
assert.deepEqual(partialBridgeCalls, [
|
||||
{ type: "global" },
|
||||
{ type: "preset", name: "in_use" },
|
||||
]);
|
||||
assert.deepEqual(
|
||||
partialBridgeDebug.entries[0].appliedRules.map((item) => item.id),
|
||||
["partial-global", "legacy-character"],
|
||||
);
|
||||
assert.deepEqual(partialBridgeDebug.entries[0].sourceCount, {
|
||||
tavern: 2,
|
||||
local: 1,
|
||||
});
|
||||
|
||||
const emptyBridgeCalls = [];
|
||||
initializeHostAdapter({
|
||||
regexProvider: {
|
||||
getTavernRegexes(request) {
|
||||
emptyBridgeCalls.push(request);
|
||||
if (request?.type === "global") {
|
||||
return [];
|
||||
}
|
||||
if (request?.type === "preset") {
|
||||
return [createRule("bridge-preset-empty-guard", "/Theta/g", "T")];
|
||||
}
|
||||
if (request?.type === "character") {
|
||||
return [createRule("bridge-character-empty-guard", "/T/g", "C2")];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
isCharacterTavernRegexesEnabled() {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const emptyBridgeDebug = { entries: [] };
|
||||
const emptyBridgeOutput = applyTaskRegex(
|
||||
settings,
|
||||
"extract",
|
||||
"finalPrompt",
|
||||
"Gamma Theta",
|
||||
emptyBridgeDebug,
|
||||
"system",
|
||||
);
|
||||
|
||||
assert.equal(emptyBridgeOutput, "Gamma C2");
|
||||
assert.deepEqual(emptyBridgeCalls, [
|
||||
{ type: "global" },
|
||||
{ type: "preset", name: "in_use" },
|
||||
{ type: "character", name: "current" },
|
||||
]);
|
||||
assert.deepEqual(
|
||||
emptyBridgeDebug.entries[0].appliedRules.map((item) => item.id),
|
||||
["bridge-preset-empty-guard", "bridge-character-empty-guard"],
|
||||
);
|
||||
assert.equal(
|
||||
emptyBridgeDebug.entries[0].appliedRules.some(
|
||||
(item) => item.id === "legacy-global",
|
||||
),
|
||||
false,
|
||||
);
|
||||
assert.deepEqual(emptyBridgeDebug.entries[0].sourceCount, {
|
||||
tavern: 2,
|
||||
local: 1,
|
||||
});
|
||||
|
||||
console.log("task-regex tests passed");
|
||||
} finally {
|
||||
if (originalSillyTavern === undefined) {
|
||||
delete globalThis.SillyTavern;
|
||||
} else {
|
||||
globalThis.SillyTavern = originalSillyTavern;
|
||||
}
|
||||
|
||||
if (originalGetTavernRegexes === undefined) {
|
||||
delete globalThis.getTavernRegexes;
|
||||
} else {
|
||||
globalThis.getTavernRegexes = originalGetTavernRegexes;
|
||||
}
|
||||
|
||||
if (originalIsCharacterTavernRegexesEnabled === undefined) {
|
||||
delete globalThis.isCharacterTavernRegexesEnabled;
|
||||
} else {
|
||||
globalThis.isCharacterTavernRegexesEnabled =
|
||||
originalIsCharacterTavernRegexesEnabled;
|
||||
}
|
||||
|
||||
if (originalExtensionSettings === undefined) {
|
||||
delete globalThis.__taskRegexTestExtensionSettings;
|
||||
} else {
|
||||
globalThis.__taskRegexTestExtensionSettings = originalExtensionSettings;
|
||||
}
|
||||
|
||||
try {
|
||||
const { initializeHostAdapter } = await import("../host-adapter/index.js");
|
||||
initializeHostAdapter({});
|
||||
} catch {
|
||||
// ignore reset failures in test cleanup
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user