Files
openclaw/src/agents/model-selection.plugin-runtime.test.ts
Edward Abrams ef3e5f5e31 perf(plugins): thread prepared manifest plugins through runtime normalization (#85254)
Carry prepared manifest model-id normalization records through the runtime bridge so hot callers reuse existing metadata instead of consulting the snapshot fallback.

The final change preserves the existing no-prepared-record behavior, adds focused forwarding coverage, and removes the one-off proof script before landing.

Thanks @zeroaltitude.

Verification:
- 224 focused tests
- full CI run 27594070734
- real behavior proof run 27594081022
- final whole-branch autoreview clean

Co-authored-by: zeroaltitude <zeroaltitude@gmail.com>
2026-06-16 06:31:36 +02:00

266 lines
8.5 KiB
TypeScript

// Covers plugin-owned model id normalization through selection surfaces.
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const normalizeProviderModelIdWithPluginMock = vi.fn();
const emptyPluginMetadataSnapshot = vi.hoisted(() => ({
configFingerprint: "model-selection-plugin-runtime-test-empty-plugin-metadata",
plugins: [
{
modelIdNormalization: {
providers: {
google: {
aliases: {
"gemini-3.1-pro": "gemini-3.1-pro-preview",
},
},
},
},
},
],
}));
vi.mock("./provider-model-normalization.runtime.js", () => ({
normalizeProviderModelIdWithRuntime: (params: unknown) =>
normalizeProviderModelIdWithPluginMock(params),
}));
vi.mock("../plugins/current-plugin-metadata-snapshot.js", () => ({
getCurrentPluginMetadataSnapshot: () => emptyPluginMetadataSnapshot,
}));
let createModelSelectionStateForTest: typeof import("../auto-reply/reply/model-selection.js").createModelSelectionState;
describe("model-selection plugin runtime normalization", () => {
beforeAll(async () => {
({ createModelSelectionState: createModelSelectionStateForTest } =
await import("../auto-reply/reply/model-selection.js"));
});
beforeEach(() => {
normalizeProviderModelIdWithPluginMock.mockReset();
});
it("delegates provider-owned model id normalization to plugin runtime hooks", async () => {
normalizeProviderModelIdWithPluginMock.mockImplementation(({ provider, context }) => {
if (
provider === "custom-provider" &&
(context as { modelId?: string }).modelId === "custom-legacy-model"
) {
return "custom-modern-model";
}
return undefined;
});
const { parseModelRef } = await import("./model-selection.js");
expect(parseModelRef("custom-legacy-model", "custom-provider")).toEqual({
provider: "custom-provider",
model: "custom-modern-model",
});
expect(normalizeProviderModelIdWithPluginMock).toHaveBeenCalledWith({
provider: "custom-provider",
context: {
provider: "custom-provider",
modelId: "custom-legacy-model",
},
});
});
it("keeps static normalization while skipping plugin runtime hooks when disabled", async () => {
const { parseModelRef } = await import("./model-selection.js");
expect(
parseModelRef("gemini-3.1-pro", "google", {
allowPluginNormalization: false,
}),
).toEqual({
provider: "google",
model: "gemini-3.1-pro-preview",
});
expect(normalizeProviderModelIdWithPluginMock).not.toHaveBeenCalled();
});
it("keeps provider plugin normalization when inferring provider for bare defaults", async () => {
normalizeProviderModelIdWithPluginMock.mockImplementation(({ provider, context }) => {
if (
provider === "custom-provider" &&
(context as { modelId?: string }).modelId === "custom-legacy-model"
) {
return "custom-modern-model";
}
return undefined;
});
const { resolveConfiguredModelRef } = await import("./model-selection.js");
expect(
resolveConfiguredModelRef({
cfg: {
agents: {
defaults: {
model: { primary: "custom-legacy-model" },
models: {
"custom-provider/custom-legacy-model": {},
},
},
},
},
defaultProvider: "openai",
defaultModel: "gpt-5.5",
}),
).toEqual({
provider: "custom-provider",
model: "custom-modern-model",
});
});
it("keeps model visibility policy construction off plugin runtime hooks by default", async () => {
// Visibility policy is a hot/static path. It preserves configured keys
// unless callers explicitly opt into runtime plugin normalization.
normalizeProviderModelIdWithPluginMock.mockImplementation(({ provider, context }) => {
if (
provider === "custom-provider" &&
(context as { modelId?: string }).modelId === "custom-legacy-model"
) {
return "custom-modern-model";
}
return undefined;
});
const { createModelVisibilityPolicy } = await import("./model-visibility-policy.js");
const policy = createModelVisibilityPolicy({
cfg: {
agents: {
defaults: {
models: {
"custom-provider/custom-legacy-model": {},
},
},
},
},
catalog: [],
defaultProvider: "custom-provider",
defaultModel: "custom-legacy-model",
});
expect(policy.allowedKeys.has("custom-provider/custom-legacy-model")).toBe(true);
expect(policy.allowedKeys.has("custom-provider/custom-modern-model")).toBe(false);
expect(normalizeProviderModelIdWithPluginMock).not.toHaveBeenCalled();
});
it("propagates explicit plugin runtime normalization opt-in through model visibility policy", async () => {
normalizeProviderModelIdWithPluginMock.mockImplementation(({ provider, context }) => {
if (
provider === "custom-provider" &&
(context as { modelId?: string }).modelId === "custom-legacy-model"
) {
return "custom-modern-model";
}
return undefined;
});
const { createModelVisibilityPolicy } = await import("./model-visibility-policy.js");
const policy = createModelVisibilityPolicy({
cfg: {
agents: {
defaults: {
models: {
"custom-provider/custom-legacy-model": {},
},
},
},
},
catalog: [],
defaultProvider: "custom-provider",
defaultModel: "custom-legacy-model",
allowPluginNormalization: true,
});
expect(policy.allowedKeys.has("custom-provider/custom-modern-model")).toBe(true);
expect(normalizeProviderModelIdWithPluginMock).toHaveBeenCalled();
});
it("keeps plugin-normalized stored overrides allowed in auto-reply runtime selection", async () => {
// Stored session overrides are runtime inputs, so provider-owned
// normalization keeps old persisted ids usable without resetting them.
normalizeProviderModelIdWithPluginMock.mockImplementation(({ provider, context }) => {
if (
provider === "custom-provider" &&
(context as { modelId?: string }).modelId === "custom-legacy-model"
) {
return "custom-modern-model";
}
return undefined;
});
const cfg = {
agents: {
defaults: {
models: {
"custom-provider/custom-legacy-model": {},
},
},
},
};
const sessionKey = "agent:main:discord:channel:c1";
const sessionEntry = {
sessionId: sessionKey,
updatedAt: 1,
providerOverride: "custom-provider",
modelOverride: "custom-legacy-model",
};
const sessionStore = { [sessionKey]: sessionEntry };
const state = await createModelSelectionStateForTest({
cfg,
agentCfg: cfg.agents.defaults,
sessionEntry,
sessionStore,
sessionKey,
defaultProvider: "custom-provider",
defaultModel: "custom-legacy-model",
provider: "custom-provider",
model: "custom-legacy-model",
hasModelDirective: false,
});
expect(state.provider).toBe("custom-provider");
expect(state.model).toBe("custom-modern-model");
expect(state.resetModelOverride).toBe(false);
});
it("forwards manifestPlugins to the runtime normalization call so it can skip the slot-or-load disk walk", async () => {
normalizeProviderModelIdWithPluginMock.mockReturnValue(undefined);
const preparedPlugins = [
{
modelIdNormalization: {
providers: {
custom: { prefixWhenBare: "prepared" },
},
},
},
];
const { normalizeModelRef } = await import("./model-selection-normalize.js");
normalizeModelRef("custom", "my-model", { manifestPlugins: preparedPlugins });
expect(normalizeProviderModelIdWithPluginMock).toHaveBeenCalledWith(
expect.objectContaining({
provider: "custom",
plugins: preparedPlugins,
}),
);
});
it("omits plugins from the runtime call when no manifestPlugins are prepared (preserves current behavior)", async () => {
normalizeProviderModelIdWithPluginMock.mockReturnValue(undefined);
const { normalizeModelRef } = await import("./model-selection-normalize.js");
normalizeModelRef("custom", "my-model");
const callArgs = normalizeProviderModelIdWithPluginMock.mock.calls[0]?.[0] as
| { plugins?: unknown }
| undefined;
expect(callArgs).toBeDefined();
expect(callArgs?.plugins).toBeUndefined();
});
});