perf(agents): reuse current model catalog metadata (#105552)

This commit is contained in:
Peter Steinberger
2026-07-12 18:34:53 +01:00
committed by GitHub
parent 2d86d07f73
commit ec6c4e8e78
2 changed files with 100 additions and 5 deletions

View File

@@ -2,6 +2,7 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
const manifestMocks = vi.hoisted(() => ({
getCurrentPluginMetadataSnapshot: vi.fn(),
listOpenClawPluginManifestMetadata: vi.fn(),
loadPluginManifest: vi.fn(),
loadPluginManifestRegistry: vi.fn(),
@@ -19,6 +20,10 @@ vi.mock("../../plugins/manifest-metadata-scan.js", () => ({
listOpenClawPluginManifestMetadata: manifestMocks.listOpenClawPluginManifestMetadata,
}));
vi.mock("../../plugins/current-plugin-metadata-snapshot.js", () => ({
getCurrentPluginMetadataSnapshot: manifestMocks.getCurrentPluginMetadataSnapshot,
}));
vi.mock("../../plugins/manifest.js", async (importOriginal) => ({
...(await importOriginal<typeof import("../../plugins/manifest.js")>()),
loadPluginManifest: manifestMocks.loadPluginManifest,
@@ -117,6 +122,7 @@ function createMistralManifestPlugin(overrides?: {
}
beforeEach(() => {
manifestMocks.getCurrentPluginMetadataSnapshot.mockReset();
manifestMocks.listOpenClawPluginManifestMetadata.mockReset();
manifestMocks.loadPluginManifest.mockReset();
manifestMocks.loadPluginManifestRegistry.mockReset();
@@ -127,6 +133,7 @@ beforeEach(() => {
providerMocks.resolveRuntimePluginDiscoveryProviders.mockReset();
providerMocks.runProviderStaticCatalog.mockReset();
setManifestPlugins([]);
manifestMocks.getCurrentPluginMetadataSnapshot.mockReturnValue(undefined);
manifestMocks.loadPluginManifestRegistry.mockReturnValue({ plugins: [] });
providerMocks.resolveActivatableProviderOwnerPluginIds.mockImplementation(
({ pluginIds }: { pluginIds: string[] }) => pluginIds,
@@ -158,6 +165,78 @@ describe("canonicalizeManifestModelCatalogProviderAlias", () => {
expect(canonicalizeManifestModelCatalogProviderAlias({ provider })).toBe("moonshot");
}
});
it("reuses the current plugin metadata snapshot for repeated alias lookups", () => {
const plugins = [
{
providers: ["moonshot"],
modelCatalog: {
aliases: {
"moonshot-ai": { provider: "moonshot" },
},
},
},
];
manifestMocks.getCurrentPluginMetadataSnapshot.mockReturnValue({ plugins });
expect(canonicalizeManifestModelCatalogProviderAlias({ provider: "moonshot-ai" })).toBe(
"moonshot",
);
expect(canonicalizeManifestModelCatalogProviderAlias({ provider: "moonshot-ai" })).toBe(
"moonshot",
);
expect(manifestMocks.loadPluginManifestRegistry).not.toHaveBeenCalled();
expect(manifestMocks.getCurrentPluginMetadataSnapshot).toHaveBeenLastCalledWith({
config: undefined,
env: process.env,
requireDefaultDiscoveryContext: true,
workspaceDir: undefined,
});
});
it("requests an exact configured workspace snapshot", () => {
const cfg = { plugins: { allow: ["openai"] } };
manifestMocks.getCurrentPluginMetadataSnapshot.mockReturnValue({ plugins: [] });
canonicalizeManifestModelCatalogProviderAlias({
provider: "openai",
cfg,
workspaceDir: "/workspace",
});
expect(manifestMocks.getCurrentPluginMetadataSnapshot).toHaveBeenCalledWith({
config: cfg,
env: process.env,
workspaceDir: "/workspace",
});
});
it("keeps custom environments on their own manifest registry context", () => {
const env = { HOME: "/custom-home" };
manifestMocks.getCurrentPluginMetadataSnapshot.mockReturnValue({ plugins: [] });
manifestMocks.loadPluginManifestRegistry.mockReturnValue({
plugins: [
{
providers: ["moonshot"],
modelCatalog: {
aliases: {
"moonshot-ai": { provider: "moonshot" },
},
},
},
],
});
expect(canonicalizeManifestModelCatalogProviderAlias({ provider: "moonshot-ai", env })).toBe(
"moonshot",
);
expect(manifestMocks.getCurrentPluginMetadataSnapshot).not.toHaveBeenCalled();
expect(manifestMocks.loadPluginManifestRegistry).toHaveBeenCalledWith({
config: undefined,
env,
workspaceDir: undefined,
});
});
});
describe("resolveBundledStaticCatalogModel", () => {

View File

@@ -7,6 +7,7 @@ import type { ModelProviderConfig } from "../../config/types.models.js";
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import { planManifestModelCatalogRows } from "../../model-catalog/manifest-planner.js";
import { normalizePluginsConfig } from "../../plugins/config-state.js";
import { getCurrentPluginMetadataSnapshot } from "../../plugins/current-plugin-metadata-snapshot.js";
import { listOpenClawPluginManifestMetadata } from "../../plugins/manifest-metadata-scan.js";
import { passesManifestOwnerBasePolicy } from "../../plugins/manifest-owner-policy.js";
import { loadPluginManifestRegistry } from "../../plugins/manifest-registry.js";
@@ -207,14 +208,29 @@ export function canonicalizeManifestModelCatalogProviderAlias(params: {
if (!provider) {
return params.provider;
}
const env = params.env ?? process.env;
// Gateway plugin metadata is process-stable. Reuse its lifecycle-owned snapshot
// so every model turn does not rediscover the same manifest alias table.
const currentPlugins =
env === process.env
? getCurrentPluginMetadataSnapshot({
config: params.cfg,
workspaceDir: params.workspaceDir,
env,
...(params.cfg === undefined ? { requireDefaultDiscoveryContext: true } : {}),
})?.plugins
: undefined;
const plugins =
currentPlugins ??
loadPluginManifestRegistry({
config: params.cfg,
workspaceDir: params.workspaceDir,
env,
}).plugins;
return (
resolveManifestModelCatalogProviderAlias({
provider,
plugins: loadPluginManifestRegistry({
config: params.cfg,
workspaceDir: params.workspaceDir,
env: params.env ?? process.env,
}).plugins,
plugins,
}) ?? params.provider
);
}