mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-31 03:41:51 +00:00
119 lines
3.5 KiB
TypeScript
119 lines
3.5 KiB
TypeScript
import { beforeEach, describe, expect, it } from "vitest";
|
|
import { createHookRunner } from "./hooks.js";
|
|
import { addStaticTestHooks } from "./hooks.test-helpers.js";
|
|
import { createEmptyPluginRegistry, type PluginRegistry } from "./registry.js";
|
|
import type {
|
|
PluginHookBeforeModelResolveResult,
|
|
PluginHookBeforePromptBuildResult,
|
|
} from "./types.js";
|
|
|
|
describe("phase hooks merger", () => {
|
|
let registry: PluginRegistry;
|
|
|
|
beforeEach(() => {
|
|
registry = createEmptyPluginRegistry();
|
|
});
|
|
|
|
async function runPhaseHook(params: {
|
|
hookName: "before_model_resolve" | "before_prompt_build";
|
|
hooks: ReadonlyArray<{
|
|
pluginId: string;
|
|
result: PluginHookBeforeModelResolveResult | PluginHookBeforePromptBuildResult;
|
|
priority?: number;
|
|
}>;
|
|
}) {
|
|
addStaticTestHooks(registry, {
|
|
hookName: params.hookName,
|
|
hooks: [...params.hooks],
|
|
});
|
|
const runner = createHookRunner(registry);
|
|
if (params.hookName === "before_model_resolve") {
|
|
return await runner.runBeforeModelResolve({ prompt: "test" }, {});
|
|
}
|
|
return await runner.runBeforePromptBuild({ prompt: "test", messages: [] }, {});
|
|
}
|
|
|
|
async function expectPhaseHookMerge(params: {
|
|
hookName: "before_model_resolve" | "before_prompt_build";
|
|
hooks: ReadonlyArray<{
|
|
pluginId: string;
|
|
result: PluginHookBeforeModelResolveResult | PluginHookBeforePromptBuildResult;
|
|
priority?: number;
|
|
}>;
|
|
expected: Record<string, unknown>;
|
|
}) {
|
|
const result = await runPhaseHook(params);
|
|
expect(result).toEqual(expect.objectContaining(params.expected));
|
|
}
|
|
|
|
it.each([
|
|
{
|
|
name: "before_model_resolve keeps higher-priority override values",
|
|
hookName: "before_model_resolve" as const,
|
|
hooks: [
|
|
{ pluginId: "low", result: { modelOverride: "demo-low-priority-model" }, priority: 1 },
|
|
{
|
|
pluginId: "high",
|
|
result: {
|
|
modelOverride: "demo-high-priority-model",
|
|
providerOverride: "demo-provider",
|
|
},
|
|
priority: 10,
|
|
},
|
|
],
|
|
expected: {
|
|
modelOverride: "demo-high-priority-model",
|
|
providerOverride: "demo-provider",
|
|
},
|
|
},
|
|
{
|
|
name: "before_prompt_build concatenates prependContext and preserves systemPrompt precedence",
|
|
hookName: "before_prompt_build" as const,
|
|
hooks: [
|
|
{
|
|
pluginId: "high",
|
|
result: { prependContext: "context A", systemPrompt: "system A" },
|
|
priority: 10,
|
|
},
|
|
{
|
|
pluginId: "low",
|
|
result: { prependContext: "context B" },
|
|
priority: 1,
|
|
},
|
|
],
|
|
expected: {
|
|
prependContext: "context A\n\ncontext B",
|
|
systemPrompt: "system A",
|
|
},
|
|
},
|
|
{
|
|
name: "before_prompt_build concatenates prependSystemContext and appendSystemContext",
|
|
hookName: "before_prompt_build" as const,
|
|
hooks: [
|
|
{
|
|
pluginId: "first",
|
|
result: {
|
|
prependSystemContext: "prepend A",
|
|
appendSystemContext: "append A",
|
|
},
|
|
priority: 10,
|
|
},
|
|
{
|
|
pluginId: "second",
|
|
result: {
|
|
prependSystemContext: "prepend B",
|
|
appendSystemContext: "append B",
|
|
},
|
|
priority: 1,
|
|
},
|
|
],
|
|
expected: {
|
|
prependSystemContext: "prepend A\n\nprepend B",
|
|
appendSystemContext: "append A\n\nappend B",
|
|
},
|
|
},
|
|
] as const)("$name", async ({ hookName, hooks, expected }) => {
|
|
await expectPhaseHookMerge({ hookName, hooks, expected });
|
|
});
|
|
});
|