mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 13:00:44 +00:00
perf(plugins): reuse compatible metadata snapshots
Reuse compatible workspace-scoped plugin metadata snapshots for unscoped model catalog and manifest-contract readers while preserving env/config/workspace compatibility checks. Also updates the stale kitchen-sink prerelease canary assertion to the current script default. Fixes #77519. Related #77532.
This commit is contained in:
committed by
GitHub
parent
b38e674c9f
commit
48ff390953
@@ -662,6 +662,38 @@ describe("loadModelCatalog", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("lets read-only manifest catalog reuse the current workspace-scoped snapshot", () => {
|
||||
loadManifestModelCatalog({
|
||||
config: {} as OpenClawConfig,
|
||||
fallbackToMetadataScan: false,
|
||||
});
|
||||
|
||||
expect(currentPluginMetadataSnapshotMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
allowWorkspaceScopedSnapshot: true,
|
||||
}),
|
||||
);
|
||||
expect(loadPluginMetadataSnapshotMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("passes explicit env when checking current manifest catalog snapshot compatibility", () => {
|
||||
const env = { HOME: "/tmp/openclaw-model-catalog-env" } as NodeJS.ProcessEnv;
|
||||
|
||||
loadManifestModelCatalog({
|
||||
config: {} as OpenClawConfig,
|
||||
env,
|
||||
fallbackToMetadataScan: false,
|
||||
});
|
||||
|
||||
expect(currentPluginMetadataSnapshotMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
env,
|
||||
allowWorkspaceScopedSnapshot: true,
|
||||
}),
|
||||
);
|
||||
expect(loadPluginMetadataSnapshotMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("dedupes supplemental models against registry entries", async () => {
|
||||
mockSingleOpenAiCatalogModel();
|
||||
augmentCatalogMock.mockResolvedValueOnce([
|
||||
|
||||
@@ -123,7 +123,9 @@ export function loadManifestModelCatalog(params: {
|
||||
}): ModelCatalogEntry[] {
|
||||
const snapshot = getCurrentPluginMetadataSnapshot({
|
||||
config: params.config,
|
||||
env: params.env,
|
||||
...(params.workspaceDir !== undefined ? { workspaceDir: params.workspaceDir } : {}),
|
||||
...(params.workspaceDir === undefined ? { allowWorkspaceScopedSnapshot: true } : {}),
|
||||
});
|
||||
const resolvedSnapshot =
|
||||
snapshot ??
|
||||
|
||||
@@ -87,6 +87,19 @@ describe("current plugin metadata snapshot", () => {
|
||||
expect(getCurrentPluginMetadataSnapshot({ config })).toBeUndefined();
|
||||
});
|
||||
|
||||
it("can opt into reusing the stored workspace scope for unscoped control-plane readers", () => {
|
||||
const config = { plugins: { allow: ["demo"] } };
|
||||
const snapshot = createSnapshot({ config, workspaceDir: "/workspace/a" });
|
||||
setCurrentPluginMetadataSnapshot(snapshot, { config });
|
||||
|
||||
expect(
|
||||
getCurrentPluginMetadataSnapshot({
|
||||
config,
|
||||
allowWorkspaceScopedSnapshot: true,
|
||||
}),
|
||||
).toBe(snapshot);
|
||||
});
|
||||
|
||||
it("rejects a current snapshot when plugin load paths change", () => {
|
||||
const config = { plugins: { load: { paths: ["/plugins/one"] } } };
|
||||
const snapshot = createSnapshot({ config });
|
||||
|
||||
@@ -49,6 +49,7 @@ export function getCurrentPluginMetadataSnapshot(
|
||||
config?: OpenClawConfig;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
workspaceDir?: string;
|
||||
allowWorkspaceScopedSnapshot?: boolean;
|
||||
} = {},
|
||||
): PluginMetadataSnapshot | undefined {
|
||||
const { snapshot: rawSnapshot, configFingerprint } = getCurrentPluginMetadataSnapshotState();
|
||||
@@ -62,12 +63,15 @@ export function getCurrentPluginMetadataSnapshot(
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
const requestedWorkspaceDir =
|
||||
params.workspaceDir ??
|
||||
(params.allowWorkspaceScopedSnapshot === true ? snapshot.workspaceDir : undefined);
|
||||
if (params.config) {
|
||||
const requestedConfigFingerprint = resolvePluginMetadataControlPlaneFingerprint(params.config, {
|
||||
env: params.env,
|
||||
index: snapshot.index,
|
||||
policyHash: snapshot.policyHash,
|
||||
workspaceDir: params.workspaceDir,
|
||||
workspaceDir: requestedWorkspaceDir,
|
||||
});
|
||||
if (configFingerprint && configFingerprint !== requestedConfigFingerprint) {
|
||||
return undefined;
|
||||
@@ -76,12 +80,12 @@ export function getCurrentPluginMetadataSnapshot(
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
if (snapshot.workspaceDir !== undefined && params.workspaceDir === undefined) {
|
||||
if (snapshot.workspaceDir !== undefined && requestedWorkspaceDir === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (
|
||||
params.workspaceDir !== undefined &&
|
||||
(snapshot.workspaceDir ?? "") !== (params.workspaceDir ?? "")
|
||||
requestedWorkspaceDir !== undefined &&
|
||||
(snapshot.workspaceDir ?? "") !== (requestedWorkspaceDir ?? "")
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,51 @@ describe("loadManifestContractSnapshot", () => {
|
||||
expect(mocks.loadPluginMetadataSnapshot).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("opts unscoped callers into the stored workspace-scoped snapshot", () => {
|
||||
const env = { HOME: "/home/snapshot" } as NodeJS.ProcessEnv;
|
||||
const current = {
|
||||
index: { plugins: [] },
|
||||
plugins: [],
|
||||
};
|
||||
mocks.getCurrentPluginMetadataSnapshot.mockReturnValue(current);
|
||||
|
||||
expect(loadManifestContractSnapshot({ config: {}, env })).toEqual({
|
||||
index: current.index,
|
||||
plugins: current.plugins,
|
||||
});
|
||||
|
||||
expect(mocks.getCurrentPluginMetadataSnapshot).toHaveBeenCalledWith({
|
||||
config: {},
|
||||
env,
|
||||
allowWorkspaceScopedSnapshot: true,
|
||||
});
|
||||
expect(mocks.loadPluginMetadataSnapshot).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("normalizes omitted config before checking unscoped snapshot compatibility", () => {
|
||||
const env = { HOME: "/home/default-config" } as NodeJS.ProcessEnv;
|
||||
const snapshot = {
|
||||
index: { plugins: [{ pluginId: "demo" }] },
|
||||
plugins: [{ id: "demo" }],
|
||||
};
|
||||
mocks.loadPluginMetadataSnapshot.mockReturnValue(snapshot);
|
||||
|
||||
expect(loadManifestContractSnapshot({ env })).toEqual({
|
||||
index: snapshot.index,
|
||||
plugins: snapshot.plugins,
|
||||
});
|
||||
|
||||
expect(mocks.getCurrentPluginMetadataSnapshot).toHaveBeenCalledWith({
|
||||
config: {},
|
||||
env,
|
||||
allowWorkspaceScopedSnapshot: true,
|
||||
});
|
||||
expect(mocks.loadPluginMetadataSnapshot).toHaveBeenCalledWith({
|
||||
config: {},
|
||||
env,
|
||||
});
|
||||
});
|
||||
|
||||
it("falls back to the shared metadata snapshot loader", () => {
|
||||
const env = { HOME: "/home/fallback" } as NodeJS.ProcessEnv;
|
||||
const snapshot = {
|
||||
|
||||
@@ -96,17 +96,19 @@ export function loadManifestMetadataSnapshot(params: {
|
||||
workspaceDir?: string;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}): PluginMetadataSnapshot {
|
||||
const config = params.config ?? {};
|
||||
const env = params.env ?? process.env;
|
||||
const current = getCurrentPluginMetadataSnapshot({
|
||||
config: params.config,
|
||||
config,
|
||||
env,
|
||||
...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}),
|
||||
...(params.workspaceDir === undefined ? { allowWorkspaceScopedSnapshot: true } : {}),
|
||||
});
|
||||
if (current) {
|
||||
return current;
|
||||
}
|
||||
return loadPluginMetadataSnapshot({
|
||||
config: params.config ?? {},
|
||||
config,
|
||||
env,
|
||||
...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user